refactor(desktop): couple host-service to Electron, drop adoption
Merged
KI
6mo ago+163+163+012345678901234567890123456789-588-588-012345678901234567890123456789
Summary
Host-service no longer survives Electron. The detach + manifest-adoption machinery was load-bearing back when host-service owned PTYs directly; now that pty-daemon (separate detached lifecycle, supervised by host-service) owns PTY survival, host-service itself has no reason to outlive the app.
- Coordinator — spawn with `detached: false`. Remove `tryAdopt`, `discoverAll`, `teardownKnownManifests`, `releaseAll`, adopted-liveness timer, and the version-mismatch healing branch. `stop` / `stopAll` / `restart` / `reset` kept; `reset` is still the SIGKILL escape hatch for wedged manifests.
- Quit path — `before-quit` always SIGTERMs host-services. `runFullQuitCleanup` collapses into `teardownTerminalHost` (v1 only).
- Parent watchdog — host-service polls `process.ppid` against `HOST_PARENT_PID`. If Electron crashes / force-quits without sending SIGTERM, the child reaps itself within ~2s. CLI-spawned standalone host-services don't set the env var and skip the watchdog.
- Graceful shutdown — SIGTERM gets a 3s drain, then `closeAllConnections` forces SSE/WS streams (chat completions, file watchers) closed so we don't hang.
- Manifest — still written by the child so the CLI (`packages/cli`) can find a running service. Desktop coordinator no longer reads it for adoption, only for the `reset` recovery path.
- Docs and tests updated; `HOST_SERVICE_LIFECYCLE.md` rewritten.
Net: ~390 lines deleted, simpler lifecycle, no orphan host-services.
Test plan
- `bun run lint` clean
- `bun run typecheck` clean in apps/desktop
- All 1959 desktop tests pass
- Manual: open a chat completion, Cmd+R the window, verify the renderer reconnects to a fresh host-service cleanly
- Manual: `kill -9` the Electron process while a host-service is running, then `ps aux | grep host-service` ~10s later — should be empty (watchdog reaped it)
- Manual: run auto-update install, verify new version's host-service starts fresh (no stale-adoption)
- Manual: CLI `superset status` while desktop running — should still find host-service via manifest
Summary by cubic
Coupled the desktop host-service to Electron so it starts and stops with the app; removed manifest adoption and simplified quit paths. PTY survival is handled by a detached pty-daemon, keeping terminals intact across restarts.
-
Refactors
- Spawn host-service attached (
detached: false);before-quitcallscoordinator.stopAll(). - Removed adoption code:
tryAdopt,discoverAll,teardownKnownManifests,releaseAll, adopted-liveness timer, version-mismatch branch. - Deleted unused APIs:
hasActiveInstances,listManifests; droppedspawnedByAppVersionfrom manifest andSUPERSET_APP_VERSIONenv. - Replaced
runFullQuitCleanupwithteardownTerminalHost(v1 only); dev SIGTERM/SIGINT also stops services. - Manifests still written by the child; desktop reads them only for
reset. CLI inpackages/clistill reads them.
- Spawn host-service attached (
-
Bug Fixes
- Parent-pid watchdog starts at process boot so the child self-exits even if Electron crashes during startup.
- Graceful SIGTERM with a 3s drain;
closeAllConnectionsends SSE/WS so shutdown doesn’t hang. - Removes the “wedged adopted service” path and prevents orphan host-service processes.
Summary by CodeRabbit
-
Improvements
- Host services perform graceful shutdown with connection draining and forced-exit fallback for more reliable quits.
- Host services monitor parent app health and self-exit if the app crashes, preventing orphaned processes.
-
Changes
- Host-service lifecycle is now owned by the app—services stop on quit and are not re-adopted on restart.
- Terminal PTYs survive via a separate daemon so open terminals persist after quitting.
- CLI now consumes service manifests for status/control; manifests are removed on stop.