Desktop: attach to the supervised daemon instead of a private sidecar#1005
Conversation
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
executor-marketing | 50c18a9 | Commit Preview URL Branch Preview URL |
Jun 14 2026, 07:07 AM |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
executor-cloud | 50c18a9 | Jun 14 2026, 07:08 AM |
Cloudflare previewTorn down — the PR is closed. |
@executor-js/cli
@executor-js/config
@executor-js/execution
@executor-js/sdk
@executor-js/codemode-core
@executor-js/runtime-quickjs
@executor-js/plugin-file-secrets
@executor-js/plugin-graphql
@executor-js/plugin-keychain
@executor-js/plugin-mcp
@executor-js/plugin-onepassword
@executor-js/plugin-openapi
executor
commit: |
3f5d776 to
6b0d8d1
Compare
19316c1 to
3e1a78b
Compare
Greptile SummaryThis PR replaces the desktop app's owned sidecar with a thin-client pattern: on packaged macOS, the app attaches to an OS-supervised launchd daemon (reusing the bundled
Confidence Score: 3/5The core supervised-attach and install flows are structurally sound, but the token-rotation path for a supervised daemon can permanently install a stale credential into the Electron session if the daemon restart takes longer than 15 seconds. The rotate-token handler falls back to the old SidecarConnection with the pre-rotation authToken when waitForSupervisedAttach times out. installBearerAuthHeader then embeds this stale token in the Electron session. Because a quick restart means supervisedDaemonDown is never set to true, the crash monitor never triggers a reload, so the bad token persists until the user manually restarts. apps/desktop/src/main/index.ts — specifically the executor:server:rotate-token IPC handler's supervised-daemon branch. Important Files Changed
Sequence DiagramsequenceDiagram
participant App as Desktop App
participant ens as ensureSupervisedConnection
participant launchd as launchd / OS
participant daemon as executor-sidecar (supervised)
participant fs as server.json
App->>ens: boot (app.isPackaged)
ens->>fs: attachToSupervisedDaemon read server.json
alt manifest exists and reachable
fs-->>ens: "SidecarConnection supervisedDaemon=true"
ens-->>App: attach OK armSupervisedMonitor
else plist registered not running
ens->>launchd: launchctl kickstart -k
launchd->>daemon: start
daemon->>fs: writeSupervisedManifest port newToken
ens->>fs: waitForSupervisedAttach polls
fs-->>ens: SidecarConnection
ens-->>App: attach OK armSupervisedMonitor
else first run
App->>App: confirmEnableBackgroundService dialog
App->>launchd: launchctl bootstrap installSupervisedService
launchd->>daemon: start
daemon->>fs: writeSupervisedManifest
ens->>fs: waitForSupervisedAttach polls
fs-->>ens: SidecarConnection
ens-->>App: attach OK armSupervisedMonitor
else not supported or declined
ens-->>App: null fallback managed-spawn
end
note over App,daemon: On quit supervisedDaemon=true connection=null no stop
note over App,daemon: rotate-token restartSupervisedService + waitForSupervisedAttach 15s
Reviews (6): Last reviewed commit: "Desktop: attach to the supervised daemon..." | Re-trigger Greptile |
| const writeSupervisedManifest = (port: number) => { | ||
| const connection = normalizeExecutorServerConnection({ | ||
| origin: `http://${hostname}:${port}`, | ||
| displayName: "Supervised daemon", | ||
| ...(authPassword | ||
| ? { auth: { kind: "basic" as const, username: "executor", password: authPassword } } | ||
| : {}), |
There was a problem hiding this comment.
Hardcoded
"executor" username instead of the shared constant
writeSupervisedManifest writes username: "executor" directly. The rest of the codebase (managed sidecar manifest, attachToSupervisedDaemon) uses SERVER_SETTINGS_USERNAME from ../shared/server-settings. If the username ever changes, this site will drift. Since server.ts already imports from @executor-js/sdk/shared, the constant should be accessible or re-exported there.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
61480bc to
6aad883
Compare
3e1a78b to
cf387fd
Compare
cf387fd to
04595d7
Compare
dd6ae85 to
3f98ede
Compare
04595d7 to
3203153
Compare
3f98ede to
2126859
Compare
The Electron app becomes a thin client of the OS-supervised gateway: - On packaged macOS launch it attaches to a running supervised daemon, or (with a one-time consent prompt) registers one by pointing a launchd LaunchAgent at the bundled sidecar binary in supervised mode. Falls back to the existing managed sidecar everywhere else. - Quitting the app, restarting the window, updating, or resetting state no longer stops a supervised daemon -- it keeps serving MCP. The old 'another server owns the data dir -> fatal dialog' path becomes a clean attach. - The sidecar entry, when supervised, self-writes the discovery manifest and reads its password from service.key. - A crash monitor shows a reconnecting overlay while launchd restarts the daemon; regenerating the password reinstalls + re-points the window.
3203153 to
50c18a9
Compare
Builds on the
executor servicestack to make the desktop app a thin client of the OS-supervised gateway, so quitting the app leaves MCP serving.Behavior
executor-sidecarbinary running in supervised mode. Every other case (dev, macOS < 13 path, install declined/failed, Linux/Windows) falls back to the existing managed sidecar unchanged.service.key.status/set-enabled) backs a Settings toggle.No second binary is bundled — the supervised daemon reuses the sidecar that already ships. The launchd plist generator mirrors the canonical copy in the CLI (
apps/cli/src/service.ts).Verification & coverage
The launchd mechanics are exercised live via the CLI path in the parent PR. The desktop-specific flow (attach, consent install, quit-leaves-serving) needs a code-signed packaged build to verify end-to-end — that part is reviewed as source here and should be smoke-tested on a signed build before release. Typecheck and lint pass.
Stack
executor serviceto supervise the local gateway daemon #1004