Motivation
A standalone Amicode app — one that runs outside VS Code — addresses three converging needs:
-
Non-VS-Code users. Many quantum-control researchers work in PyCharm, Jupyter, tmux+vim, or have no IDE at all. The VS Code extension is a gate: they can't install Amicode without adopting an editor they don't use. A web app or thin desktop launcher removes that gate entirely.
-
Product independence. Amicode currently ships as a VS Code extension host with a server inside; its surface design, distribution, upgrade cadence, and even its brand presence are constrained by the extension's contribution points and lifecycle. A standalone app means Amicode owns its own window, its own update path, and its own UX — no more acquireVsCodeApi() bridge dance.
-
Remote / cloud deployment. A lab's compute runs on a headless server cluster; researchers connect from laptops, tablets, or thin clients. The extension's local-first workspace model doesn't map to that posture. A self-hosted web app (or a desktop app whose server is on a remote machine) is the natural architecture for "the solver is on the cluster, the UI is wherever I am."
Current architecture (today)
Amicode is already ~80% standalone — its spine carries no VS Code dependency:
| Layer |
What runs it |
VS Code dependency |
| Agent harness |
opencode serve (Bun, launchd supervised on 127.0.0.1:4096) |
None (server is independent) |
| Solve gate / CLI |
amico-run / amico (Node bundles) |
None |
| Run contract |
Filesystem — run.toml → logs → result.toml → FINISHED |
None |
| Entity stores |
~/.amico/problems/, runs/, vaults/ — JSON/TOML/JSONL |
None |
| Widget contract |
dashboard.json + ~/.amico/widgets/<id>/widget.js — mount(el, amico) |
None (no shipped renderer yet) |
| Chat UI |
<iframe> pointed at the opencode server's web app |
Thin (iframe host only) |
| Inspector UI |
Dependency-free TS webviews speaking postMessage |
Webview bridge + transport |
| Tree views (catalog, vault) |
VS Code TreeView API |
Full replacement needed |
| Server lifecycle |
Extension spawns/probes opencode serve |
Supervisor needed |
| Install root |
Pieces resolve from dev repo or newest VSIX via ls -dt | head -1 |
Pin needed |
| Project root |
Globs workspaceStorage/*/harmoniqs.amicode |
Define own project concept |
| Settings |
VS Code amicode.* settings schema |
New settings UI + config file |
| Commands (16) |
VS Code commands.registerCommand |
App menus / shortcuts |
Three approaches
A — Desktop shell (Electron / Tauri)
A native window that supervises opencode serve, embeds the served chat app, re-hosts the inspector/catalog/vault UIs, and renders the Home dashboard from the existing widget contract.
- Pros: Fastest path to a real app; single UI codebase shared with the extension; passwordless-localhost posture remains valid.
- Cons: Shipping a browser to render a browser. Electron ~170 MB, Tauri ~25 MB with a node sidecar for the run-dir watcher.
- Shell tech (deferred to team): Electron keeps the stack homogeneous (everything TS/Node); Tauri is lighter but adds Rust.
B — Browser-first PWA
The product is a web app served by opencode serve. The "app" is a thin launcher that boots the server and opens the browser, or an installable PWA. Desktop shell is optional.
- Pros: Least engineering; remote access is free (SSH-forward already works); same deployment model as the chat surface today.
- Cons: The passwordless-localhost posture becomes a real auth layer if the service is reachable off-localhost; no native affordances (notifications, file associations, menubar presence).
C — Native-first rewrite
Treat the extension's webviews as reference implementations and rebuild the shell as a proper SPA or native app.
- Pros: Best long-term UX; full ownership of every pixel.
- Cons: Most work by an order of magnitude; forks UI maintenance with the extension; premature unless the standalone app becomes the product.
The QM analogue
YC open-sourced QM (github.com/yc-software/qm) on July 31, 2026 — a multiplayer agent harness running entirely on Node + TypeScript + Fastify + Postgres, with Slack and web as equal surfaces. No native shell, no Rust, no Electron. The entire product is a headless core + plugin architecture, deployed via qm init → Fly.io/AWS.
QM proves a pure-Node, web-first, no-native-shell architecture works for exactly this class of product. Its patterns are instructive: plugin-separated surfaces, a deployment directory that separates core from customization, agent-driven infrastructure provisioning, and a SECURITY.md threat model worth borrowing from.
For Amicode, QM's model reframes the question: instead of "what native framework do we write the shell in?", the productive question may be how many of our extension surfaces should become web UI plugins served by opencode serve?
Recommended direction for discussion
Headless core + web-first surfaces + optional thin launcher.
- Keep
opencode serve as the headless agent core (already works, launchd supervised).
- Keep
amico-run / amico as the solve gate (already works).
- Build a web UI to replace the extension's surfaces, served by the opencode server:
- Chat (already served — promote from iframe to first-class route).
- Run Inspector (shim the existing dependency-free TS bundles behind a WebSocket transport).
- Catalog / Vault browsers (re-host tree views as web pages).
- Home dashboard (the greenfield widget renderer —
mount(el, amico) contract already exists).
- Settings (replaces
amicode.* VS Code settings schema).
- Build a thin desktop launcher (Electron, keeping the stack TS/Node) that supervises the server, provides system-tray notifications ("solve finished"), and optionally embeds the web UI for users who want an app icon. The launcher is not the architecture — the web app is.
- Offer a headless deploy mode for remote labs / cloud instances (already works via SSH-forward; the Harmoniqs Cloud executor proves the remote path).
The architectural decision the team needs to make is not Tauri vs Electron; it's what fraction of the extension's surfaces we route through the served web UI vs rebuild natively, and what the thin launcher's surface contract is (menu bar only? embedded window? file associations?).
Open questions for the team
- v1 scope. What's the cut line? "Chat + Inspector + solve loop" (the minimum viable standalone)? Or must Home, Catalog, Vault, and Device Inspector ship in v1 too?
- Install root. Do we bundle the opencode binary, CLI dist, plugin pack, templates, skills, and Julia project inside the app bundle, or keep them at
~/.amico/ and let the app resolve them?
- Project root. Replace
workspaceStorage globbing with what — a project picker that points at ~/.amico/problems/<slug>/?
- Auth posture. Keep passwordless localhost for the desktop launcher, but what about the headless deploy mode that serves the web UI on a remote machine? Tokens? SSH-forward only?
- Timeline. Is this a months-from-now build, or should it be planned for the next cycle alongside the existing solve workflow?
Next steps
- Team reviews open questions → resolves direction.
- Direction lands as a decision record (new ADR under
docs/adr/).
- Issue decomposed into vertical-slice sub-issues per the
break-into-subissues workflow.
Motivation
A standalone Amicode app — one that runs outside VS Code — addresses three converging needs:
Non-VS-Code users. Many quantum-control researchers work in PyCharm, Jupyter, tmux+vim, or have no IDE at all. The VS Code extension is a gate: they can't install Amicode without adopting an editor they don't use. A web app or thin desktop launcher removes that gate entirely.
Product independence. Amicode currently ships as a VS Code extension host with a server inside; its surface design, distribution, upgrade cadence, and even its brand presence are constrained by the extension's contribution points and lifecycle. A standalone app means Amicode owns its own window, its own update path, and its own UX — no more
acquireVsCodeApi()bridge dance.Remote / cloud deployment. A lab's compute runs on a headless server cluster; researchers connect from laptops, tablets, or thin clients. The extension's local-first workspace model doesn't map to that posture. A self-hosted web app (or a desktop app whose server is on a remote machine) is the natural architecture for "the solver is on the cluster, the UI is wherever I am."
Current architecture (today)
Amicode is already ~80% standalone — its spine carries no VS Code dependency:
opencode serve(Bun, launchd supervised on127.0.0.1:4096)amico-run/amico(Node bundles)run.toml→ logs →result.toml→FINISHED~/.amico/problems/,runs/,vaults/— JSON/TOML/JSONLdashboard.json+~/.amico/widgets/<id>/widget.js—mount(el, amico)<iframe>pointed at the opencode server's web apppostMessageopencode servels -dt | head -1workspaceStorage/*/harmoniqs.amicodeamicode.*settings schemacommands.registerCommandThree approaches
A — Desktop shell (Electron / Tauri)
A native window that supervises
opencode serve, embeds the served chat app, re-hosts the inspector/catalog/vault UIs, and renders the Home dashboard from the existing widget contract.B — Browser-first PWA
The product is a web app served by
opencode serve. The "app" is a thin launcher that boots the server and opens the browser, or an installable PWA. Desktop shell is optional.C — Native-first rewrite
Treat the extension's webviews as reference implementations and rebuild the shell as a proper SPA or native app.
The QM analogue
YC open-sourced QM (github.com/yc-software/qm) on July 31, 2026 — a multiplayer agent harness running entirely on Node + TypeScript + Fastify + Postgres, with Slack and web as equal surfaces. No native shell, no Rust, no Electron. The entire product is a headless core + plugin architecture, deployed via
qm init→ Fly.io/AWS.QM proves a pure-Node, web-first, no-native-shell architecture works for exactly this class of product. Its patterns are instructive: plugin-separated surfaces, a deployment directory that separates core from customization, agent-driven infrastructure provisioning, and a SECURITY.md threat model worth borrowing from.
For Amicode, QM's model reframes the question: instead of "what native framework do we write the shell in?", the productive question may be how many of our extension surfaces should become web UI plugins served by opencode serve?
Recommended direction for discussion
Headless core + web-first surfaces + optional thin launcher.
opencode serveas the headless agent core (already works, launchd supervised).amico-run/amicoas the solve gate (already works).mount(el, amico)contract already exists).amicode.*VS Code settings schema).The architectural decision the team needs to make is not Tauri vs Electron; it's what fraction of the extension's surfaces we route through the served web UI vs rebuild natively, and what the thin launcher's surface contract is (menu bar only? embedded window? file associations?).
Open questions for the team
~/.amico/and let the app resolve them?workspaceStorageglobbing with what — a project picker that points at~/.amico/problems/<slug>/?Next steps
docs/adr/).break-into-subissuesworkflow.