Skip to content

refactor: cut the Electron desktop app — remote always-on server is canonical (ADR-051) - #273

Merged
aterrylu merged 1 commit into
mainfrom
terry/electron-cleanup
Jun 29, 2026
Merged

refactor: cut the Electron desktop app — remote always-on server is canonical (ADR-051)#273
aterrylu merged 1 commit into
mainfrom
terry/electron-cleanup

Conversation

@aterrylu

Copy link
Copy Markdown
Owner

Summary

Cut the Electron desktop app entirely (ADR-051). The real user need behind "desktop app" was always "agents stay alive when my laptop is closed" — which is a remote always-on server, not a local GUI shell. The PWA (#71) already covers the installable-app / desktop-notifications / thin-client value at zero Electron cost, and the always-on server lifecycle (launchd/systemd-user, #271 / ADR-050) is the actual delivery mechanism.

Electron had become the single most expensive maintenance surface in the repo — signing/notary 85min+ stalls, electron-updater, universal2 lipo, the bun-compile/node-pty ABI wall — for a layer that wasn't getting used. This removes ~9,500 LOC of app source plus two CI jobs and five signing secrets.

+335 / −10,453 across 96 files. The biggest destructive PR in autonomOS history — reviewers should focus on the +335 (the surgical edits) and the careful tracking of what was kept and why.

The architectural shift

graph TB
    subgraph OLD["❌ OLD — Electron-bundle path (cut)"]
        direction TB
        U1[User] --> DMG[Download signed/notarized<br/>universal2 .dmg]
        DMG --> APP[autonomOS.app<br/>Electron shell]
        APP -->|spawns as child<br/>--embedded| SRV1[autonomos-server<br/>Built-in mode]
        APP -.electron-updater.-> DMG
        SRV1 --> AG1[agents die when<br/>laptop sleeps]
    end

    subgraph NEW["✅ NEW — always-on remote path"]
        direction TB
        U2[User] --> BROWSER[Browser / PWA #71]
        BROWSER -->|HTTP + token| SRV2[autonomos-server]
        SRV2 -.supervised by.-> LD[launchd / systemd-user<br/>ADR-050]
        LD --> SRV2
        SRV2 --> AG2[agents stay alive<br/>across laptop sleep]
        INSTALL[curl install.sh] -->|fetches per-platform<br/>server tarball| SRV2
    end

    OLD -.replaced by.-> NEW
Loading

The two "embedded"s — a naming-collision footgun, handled

The codebase has two unrelated things called "embedded". This PR removes one and leaves the other completely untouched:

Term What it is Fate
--embedded flag / embedded-mode.ts the Electron app spawning autonomos-server as an in-process child ("Built-in mode") DELETED
_embedded_dashboard / build:embed-dashboard (ADR-043) the dashboard compiled into the server binary so the hosted server can serve its own UI UNTOUCHED — stays

Future readers grepping for "embedded": we deleted Electron embedded-mode; we kept dashboard-embedded-in-server-bundle.

What's retained (the cores of the partially-superseded ADRs)

  • launchd/systemd-user lifecycle (ADR-028 core) — finished separately in ADR-050.
  • pid-file mutual-exclusion lock (ADR-029 core) — still prevents two daemons racing on ~/.autonomos/.
  • auth.ts CONFIG_DIR token isolation (ADR-030 server-side) — serves worktree-dev + future profiles.

ADR-051 adds append-only Update notes to ADR-005, 028, 029, 029-follow-up, and 030.

Changes

Deleted

  • packages/app/ — entire Electron source tree (main/renderer/preload, electron-builder config, DMG/sign/notary/lipo scripts, build resources, 8 test files)
  • packages/server/src/embedded-mode.ts + the --embedded flag (cli-args.ts, run.ts, CLI help)
  • .github/workflows/pr-artifact.yml; reusable-dmg-build.yml gutted → reusable-server-build.yml (server tarballs only)
  • 4 desktop research docs (desktop-as-thin-client.md, desktop-embedded-server.md, desktop-app-design-notes.md, phase-1b-sketch.md); desktop-shells/ retained as ADR-005's foundational research

Repointed / rewired

  • Release version source packages/app/package.jsonpackages/server/package.json (release-notes.ts, sync-changelog.ts, version.yml)
  • @autonomos/app removed from the changeset fixed group; bun.lock regenerated
  • release.yml keeps the server-tarball assembly; drops DMG/zip/blockmap/latest-mac.yml/signing/attestation
  • root package.json, tsconfig.json, Makefile, .gitignore, .changeset/README.md, release skill — de-app'd

Mid-execution refinement (flagged + approved during the cut)

  • helpers/embedded-server.ts turned out to be a shared real-spawn harness used by 4 integration suites (not Electron-specific). Rather than delete it, it was rewritten to parse the server's always-emitted listening on …:<port> startup log (instead of the going-away --embedded + AUTONOMOS_READY signal) and renamed helpers/test-server.ts (bootEmbeddedbootServer), preserving the 3 non-Electron suites (agent-spawn-prompt, usage-queue-integration, usage-queue-sim-integration).

⚠️ Manual follow-up for @aterrylu after merge

Five now-unused GitHub Actions secrets should be deleted (Settings → Secrets → Actions). Not deleted by this PR (flagging is safer than scripting secret deletion):
CSC_LINK, CSC_KEY_PASSWORD, APPLE_API_KEY, APPLE_API_KEY_ID, APPLE_API_ISSUER

Coordination

Testing

  • make check (biome + tsc --build + node:test + vitest) green
  • Real-spawn smoke in an isolated home on an alt port (never :3100): Claude + Codex agents both alive
  • Release-pipeline dry-check: a patch release builds no DMG/sign/notary step
  • install.sh: fetches only the server tarball + SHA256SUMS — no .dmg/.AppImage

🤖 Generated with Claude Code

@aterrylu
aterrylu enabled auto-merge (squash) June 29, 2026 08:40
…anonical (ADR-051)

Delete packages/app/ (~9.5k LOC Electron tree), the server's --embedded flag +
embedded-mode.ts, and the DMG/sign/notary/electron-updater half of the release
pipeline. The canonical client is now the browser + PWA (#71) against an
always-on server (launchd/systemd-user, ADR-050).

Retains the pid-file mutual-exclusion lock (ADR-029 core), the launchd/systemd
lifecycle (ADR-028 core), and auth.ts CONFIG_DIR token isolation (ADR-030
server-side). The dashboard-embedded-in-server-binary bundle (_embedded_dashboard,
ADR-043) is unrelated to Electron's --embedded and is untouched.

Mid-execution: helpers/embedded-server.ts was a shared real-spawn harness used by
4 integ suites (not Electron-specific); rewritten to parse the always-emitted
"listening on" startup log instead of the removed --embedded/AUTONOMOS_READY
signal, and renamed helpers/test-server.ts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZvsJYsGE8rAfD42TrX86i
@aterrylu
aterrylu force-pushed the terry/electron-cleanup branch from 2e16cb9 to ee217d5 Compare June 29, 2026 08:45

@nox-0x nox-0x left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving — the surgical edits hold up: --embedded is gone everywhere it was checked, embedded-mode.ts and its consumers are cleanly removed from run.ts, the renamed helpers/test-server.ts reliably picks up the new "listening on" banner (newline-anchored regex, defensive (r.stdout ?? "") guard), the changeset fixed group is correctly trimmed, and version-source repointing (scripts/release-notes.ts, scripts/sync-changelog.ts, version.yml) lines up with packages/server/package.json. The retained cores (pid-file mutual-exclusion, launchd/systemd lifecycle, auth.ts CONFIG_DIR isolation) are all preserved as ADR-051 promises.

One follow-up (non-blocking) — scripts/test-1a1-isolated.sh (still wired into package.json as test:1a1) passes --embedded and waits for AUTONOMOS_READY; with this PR, parseCliArgs will throw Unknown argument: --embedded at spawn. It's a manual smoke script (not run by make check or CI), so the bleed is contained, but bun run test:1a1 is now broken. Either drop --embedded + switch the grep to match the new autonomOS server listening on http://…:<port> banner, or delete the script and its test:1a1 package.json entry alongside the desktop cut.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants