#17330

feat(cli): persist tray preferences and expose autostart controls

Openphoriahopened 2d ago

There is currently no supported way to disable the system tray icon — and no way to make autostart boot without it — from the GUI or from any persisted configuration. I checked before filing:

  • Dashboard (src/**): zero tray references. No setting, page, or management-API route can see or change the tray.
  • omniroute serve: --tray / --no-tray exist, but they are per-invocation flags; nothing is remembered.
  • omniroute tray hide|show|quit (bin/cli/commands/tray.mjs): all three are stubs that only process.stderr.write an advice line. hide says "Send SIGUSR1 to the serve process to toggle the tray" — but SIGUSR1 has no handler anywhere in the repo (it occurs only inside that message).
  • omniroute autostart enable: accepts no options and hardcodes the tray into the startup entry:
    • Windows VBS: buildWinVbsContent → buildServeExecLine(cliPath, { tray: true }) (bin/cli/tray/autostart.mjs:378)
    • macOS LaunchAgent plist: <string>--tray</string> (:303, :378)
    • Linux is inconsistent between its own two paths: systemd passes { tray: false } ("Foreground serve only", :139) while the XDG desktop entry passes { tray: true } (:158)
  • docs/reference/ENVIRONMENT.md: no tray-related variable exists.
  • Electron desktop app: the tray is always created (electron/main.js::createTray); the only related persisted preference is the "When Dashboard Closes" behavior.

Why this matters beyond cosmetics

  1. The tray chain is what pulls in the --tray launcher machinery: a hidden VBS → detached worker spawned stdio: "ignore" → a systray2 lazy npm install → the readiness deadline. That's the whole silent-failure surface from #15464, and on 3.8.52 the worker can still be taskkilled at the deadline when the tray never becomes ready (#17315 — follow-up filed, with two concrete loader bugs). With tray in a user's hands, that entire path is on by design wherever autostart is used.
  2. The tray menu is also where autostart is "toggled" from (traySystray.mjs:84), but the same enable() always regenerates the entry with tray — so a CLI user who doesn't want the icon has no supported path to an autostart that serves headless-with-dashboard instead of with a tray. The report in #15464 ("Dropping --tray from the generated VBS makes autostart work reliably") is exactly that unsupported path today.

Proposed shape

A single persisted preference, consulted by both serve and every autostart generator:

  • CLI
    • omniroute autostart enable --no-tray / --tray (explicit per-run override of the stored preference)
    • a documented env var (e.g. OMNIROUTE_TRAY=0) in ENVIRONMENT.md
  • Dashboard
    • a Settings card with two toggles: system tray icon and start at login — reading/writing the same preference via /api/*, so CLI and GUI stay in sync
    • (optional, nice: show the actual runtime state — whether a server/tray process is actually running — instead of only "the startup file exists", which is all autostart status checks today)
  • Consistency
    • one mechanism for VBS, plist, systemd and XDG (systemd's "Foreground serve only" choice vs XDG's --tray looks like an accident rather than intent)
  • tray hide
    • either implement the SIGUSR1 toggle it documents (or have hide call the management API) or remove the subcommand — right now all three subcommands mislead

The no-tray autostart variant is already fully supported by the code (plain omniroute serve --no-open boots the same server, and it is exactly the Linux systemd mode); only the wiring to choose it is missing, so this should be a small PR once the preference plumbing exists.

Reference: #15464 (the original autostart bug) and #17315 (loader bugs that keep tray-era autostart broken in 3.8.52 — a persisted no-tray preference also sidesteps that failure mode entirely).

Activity

1
diegosouzapw2d ago

Confirmed on the current development branch: serve accepts per-invocation tray flags, but autostart enable does not accept or persist that choice. The Windows, macOS and XDG generators enable the tray, while the systemd service remains headless. The tray hide message also recommends a SIGUSR1 toggle that is not implemented; Node reserves that signal for the debugger, so that guidance needs correcting.

This request is broader than the loader fixes in #17328. We are tracking it in separate increments: persisted CLI/autostart preferences, dashboard controls backed by the same settings, and explicit control of an already-running tray. Headless service operation must remain supported. The current macOS/systemd status checks already inspect OS state in addition to files, so those should be preserved. This issue remains open; no implementation of the full requested scope is claimed.