feat(desktop): AO_KEEP_DAEMON to keep the daemon alive after the app closes#2231
feat(desktop): AO_KEEP_DAEMON to keep the daemon alive after the app closes#2231axisrow wants to merge 1 commit into
Conversation
1b18854 to
405be36
Compare
Concrete motivating use-case: remote daemon in a containerWorth surfacing the strongest case for this flag — a headless / containerized daemon that must outlive any desktop client. The supervisor watchdog arms only after the first client connects, then self-stops ~5s after the last client disconnects. That's exactly right for a window-tied desktop daemon. But consider running
I'm tracking the container-hosting side separately (in my own Default behavior is unchanged (flag unset → byte-for-byte the same self-stop). Happy to add a short note to the README row pointing at the remote/headless use-case if that's useful. |
ab0a1a7 to
b7d178f
Compare
…closes
By default the desktop app's daemon is tied to the window via the OS-native
supervisor link and self-stops shortly after the app quits. That is right for
casual use, but long agent sessions are detached when the window closes.
Add an opt-in env var AO_KEEP_DAEMON: when set, the app spawns its daemon
without the supervisor link and skips the orphan-cleanup kill on exit, so the
daemon persists across app quit and stops only on an explicit `ao stop`.
- daemon-owner.ts: keepDaemonAlive(env) helper; shouldLinkOnAttach honors it so
reopening the app never re-arms the link on a persistent daemon.
- main.ts: gate establishSupervisorLink() on the spawn path and both attach
paths; skip the process.on("exit") fallback kill when the flag is set.
- Default behavior (flag unset) is byte-for-byte unchanged.
- Docs: AO_KEEP_DAEMON row in the README config table.
Closes AgentWrapper#2230
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
b7d178f to
596e506
Compare
What
Adds an opt-in env var
AO_KEEP_DAEMON: when set, the desktop app spawns its daemon without the OS-native supervisor link and skips the orphan-cleanup kill on exit, so the daemon persists across app quit and stops only on an explicitao stop.By default the app's daemon is tied to the window and self-stops shortly after the app quits — right for casual use, but long agent sessions get detached when the window closes. This gives power users a way to opt out.
Closes #2230.
Changes
daemon-owner.ts:keepDaemonAlive(env)helper;shouldLinkOnAttachhonors it, so reopening the app never re-arms the link on a persistent daemon.main.ts: gateestablishSupervisorLink()on the spawn path and both attach paths; skip theprocess.on("exit")orphan-cleanup kill when the flag is set (this last one is essential — without it the fallback kill defeats the flag on quit).AO_KEEP_DAEMONrow in the config table.Default behavior unchanged
With the flag unset, behavior is byte-for-byte the same: the daemon self-stops shortly after the app quits.
Intentional scope / omissions
ao startdaemons never self-stop), so persistence is achieved purely by the app not holding the link — no daemon-side change needed.AO_OWNER=appleft as-is. The persistent daemon is still tagged app-owned;shouldLinkOnAttachgates on the flag rather than the owner tag, so no owner-tag change is required.Testing
keepDaemonAlive(truthy / empty /0/false/ whitespace) andshouldLinkOnAttachpersist cases.npm run lint(backendgo test ./...+ golangci-lint) run for the touched repo — backend untouched, no new failures.AO_KEEP_DAEMON=1: open app → close window → daemon survives;ao stopstops it explicitly. ✓🤖 Generated with Claude Code