1---2name: codenomad-architecture-guide3description: Architecture and native OpenCode V2 navigation guide for CodeNomad. Use for cross-package changes, OpenCode client calls, server routes, events, workspaces, Git, Yolo, UI, or desktop integration.4---56# CodeNomad Architecture Guide78## Start Here910- UI: read `references/ui-conventions.md`; use i18n for visible text.11- Server: read `references/server-conventions.md` and `references/feature-traces.md`.12- OpenCode: read the three `sdk-*.md` references before changing client calls or service lifecycle.13- Desktop: read `references/desktop-conventions.md`.14- Developer Mode: read `../../../dev-docs/DEVELOPER_MODE.md`.1516## Native OpenCode V2 Baseline1718- The only OpenCode client dependency is the experimental `@opencode-ai/client@beta` protocol. Server and UI follow that dependency together; refresh the client lock before API audits or release validation. The runtime CLI is managed independently and startup has no exact version gate. The public `@opencode-ai/sdk` describes an alternative embedded host.19- Do not use `@opencode-ai/sdk`, `@opencode-ai/sdk/v2/client`, or `createOpencodeClient()`; follow installed `@opencode-ai/client` declarations.20- There is no legacy `packages/opencode-plugin/`. Do not restore the V1 compatibility runtime or add general plugin extension points. The reviewed project-local Developer Mode adapter is the sole narrow exception; see `dev-docs/DEVELOPER_MODE.md`.21- The server uses the selected host or WSL CLI's official `service status`, `service start`, and `service get password` lifecycle to connect to one externally owned global OpenCode daemon. It owns no private port/database/registration/PID and never stops the daemon on backend shutdown. WSL requires Windows localhost forwarding and uses no cross-namespace PID operations.22- The UI uses generated Promise clients from `OpenCode.make()` through the CodeNomad proxy.23- OpenCode owns session APIs, native Forms, session Shell (`client.session.shell`), session instructions (`client.session.instructions.entry`), location-scoped background Shells, and interactive PTYs. Question request/reply/reject routes are compatibility-only; new interruption flows use `client.form.*`. The Status panel lists `client.shell.*` records, refreshes on Shell events/reconnect, displays native metadata, and supports ownership-checked removal. Interactive `client.pty.*` terminals remain separate.24- CodeNomad owns explicit Stop Workspace eviction, directory authorization, Git status/diff/stage/unstage/commit, Yolo persistence/auto-replies, and `/api/events`. Tab/window close only detaches local UI and never evicts.25- OpenCode owns the global daemon's standard state and database. Allowed configured environment variables apply only to `service start` for a missing daemon; an existing daemon is unchanged, and `OPENCODE_DB`/`XDG_STATE_HOME` ownership settings are ignored.26- Native desktop identity is channel plus config profile: one singleton process/backend per profile and multiple UUID windows. A second launch opens another window by default; Advanced settings can restore MRU focus, while `--new-window` always requests another window. Stable/dev/non-default profiles isolate native state; OpenCode sessions/messages are shared while tabs/drafts/views are per-window.27- Client-state V3 is a per-window envelope over the V2 content-addressed partition graph with atomic publication/migration, ownership-fenced writes, and conservative post-commit GC. Native SideCar/browser previews are sandboxed without same-origin access; DOM comment inspection is web-only.2829## Package Map3031- `packages/server/`: Fastify control API, shared OpenCode service, locations, auth, filesystem, Git, Yolo, speech.32- `packages/ui/`: SolidJS application, generated client adapters, stores, components, i18n.33- `packages/electron-app/`: Electron host.34- `packages/tauri-app/`: Tauri host.35- `packages/cloudflare/`: edge deployment.3637## Integration Paths3839- Shared service: `packages/server/src/workspaces/opencode-service.ts`40- Location ownership: `packages/server/src/workspaces/manager.ts`41- OpenCode proxy: `packages/server/src/server/http-server.ts`42- CodeNomad API client/events: `packages/ui/src/lib/api-client.ts`43- OpenCode client cache: `packages/ui/src/lib/sdk-manager.ts`44- Root client authority: `packages/ui/src/stores/opencode-client.ts`45- Native session calls: `packages/ui/src/stores/session-api.ts`, `session-actions.ts`46- Git mutations: `packages/server/src/workspaces/git-mutations.ts`47- Yolo: `packages/server/src/permissions/`, `packages/server/src/server/routes/yolo.ts`48- Desktop hosts: `packages/electron-app/electron/main/`, `packages/electron-app/electron/preload/index.cjs`, `packages/tauri-app/src-tauri/src/`49- Developer Mode: `.opencode/plugins/codenomad-automation.ts`, `packages/server/src/opencode/automation-plugin.ts`, `packages/server/src/developer-cdp.ts`5051## Rules5253- Inspect installed declarations under `node_modules/@opencode-ai/client/dist/promise/`; generated names are the source of truth.54- Preserve `LocationRef` and explicit directory routing. Never infer workspace ownership from a client-provided path.55- Send CodeNomad operations through `/api/*`; send OpenCode operations through `/workspaces/:id/instance/api/*`.56- Consume the multiplexed CodeNomad SSE stream at `/api/events`; do not create one OpenCode process or event stream per workspace. Native events are volatile, so reconnect must reconcile authoritative state.57- Treat the instance proxy allowlist as an integration boundary. Upstream routes are not exposed automatically.58- Keep Git mutations and Yolo in CodeNomad. They are policy/security boundaries, not upstream client features.59- Check `packages/server/src/api-types.ts` and UI consumers together when changing CodeNomad events or responses.60- Desktop behavior must remain at strict Electron/Tauri parity in the same change; use the shared native abstraction and test both hosts.6162## Anti-Patterns6364| Avoid | Use |65|---|---|66| Public `@opencode-ai/sdk` examples | Installed experimental `@opencode-ai/client` declarations |67| One `opencode serve` per workspace | One externally owned global daemon through the official CLI lifecycle |68| Per-worktree clients/processes | Root proxy client plus native location/directory inputs |69| Reintroducing the V1 `packages/opencode-plugin` or general server plugin/background-process paths | Native OpenCode APIs; the reviewed project-local Developer Mode adapter only for desktop feedback |70| OpenCode APIs for stage/commit/Yolo policy | CodeNomad routes and managers |71| Hardcoded UI strings | `t()` / `tGlobal()` and every locale |7273## References7475- `references/architecture-overview.md`76- `references/server-conventions.md`77- `references/sdk-api-reference.md`78- `references/sdk-integration-patterns.md`79- `references/sdk-critical-behaviors.md`80- `references/feature-traces.md`81- `references/ui-conventions.md`82- `references/desktop-conventions.md`