# Desktop Shell (electron) Owns the desktop runtime: the Electron main process, the preload bridge that exposes `window.api` to the renderer, IPC handlers, the local TypeORM + sql.js database, the plugin loader, OS-integration adapters (window controls, idle detection, game detection, audio), update flow, and the Local API server that hosts the Docusaurus bundle inside the app. > **Format reference:** > - **Vocabulary** — bold term, one-sentence definition, aliases to avoid. > - **Relationships** — bullets with bold terms and cardinality. > - **Boundaries / IO** — what this subdomain exposes and consumes. > - **Invariants** — rules that always hold. > - **Flagged ambiguities** — terms in dispute with proposed resolutions. > > See `agents-docs/AGENTS_CONTEXT.md` for the contract. Update in the same turn a trigger fires (see `agents-docs/AGENT_WORKFLOW.md` § CONTEXT.md upkeep). ## Vocabulary | Term | Definition | Aliases to avoid | |------|------------|------------------| | **Preload bridge** | `electron/preload.ts` — the only surface that the renderer can call into Node through; exposes `window.api.*` after `contextBridge.exposeInMainWorld`. | "preloader" | | **IPC handler** | A `main`-process function registered against an IPC channel name; lives under `electron/ipc/` (system, window-controls) and `electron/cqrs.ts`. | "rpc handler" | | **CQRS handler** | Command or query handler dispatched through `electron/ipc/cqrs.ts`; pattern shared with `server/src/cqrs/`. | "command processor" | | **Local API server** | An in-process HTTP server (`electron/api/local-api-server.ts`) that serves the prebuilt Docusaurus docs and OpenAPI views to the renderer over `http://localhost:/`. | "internal API" | | **Plugin library** | The plugin loader (`electron/plugin-library.ts`) — resolves manifests, validates entry points, and prepares the sandbox the renderer mounts plugins into. | "plugin manager" | | **Data archive** | The export/import format implemented in `electron/data-archive.ts` for moving a user's local database between installs. | "backup" | ## Relationships - The **Preload bridge** is the only path between the **Renderer** (toju-app) and **Main**; the renderer cannot import Electron, Node, or TypeORM directly. - An **IPC channel** maps 1:1 to a method on `window.api.*`. Adding a method on the preload requires registering its handler in `electron/ipc/` or `electron/cqrs.ts`. - The **Plugin library** loads manifests at startup and on user action; it owns the contract the renderer's *plugins* domain consumes (defined in `toju-app/src/app/shared-kernel/plugin-system.contracts.ts`). - TypeORM **migrations** in `electron/migrations/` are applied on startup against the per-user SQLite file resolved by `electron/runtime-paths.ts`. - The **Local API server** serves the Docusaurus bundle built into `docs-site/build/` and the OpenAPI artifacts under `electron/api/openapi.ts`. ## Boundaries / IO - **Exposes:** - `window.api.*` surface (preload bridge) — the canonical IPC contract for the renderer. - IPC channel names registered in `electron/ipc/index.ts`, `electron/ipc/cqrs.ts`, `electron/ipc/system.ts`, `electron/ipc/window-controls.ts`. - Local API HTTP endpoints (`electron/api/router.ts`) under `http://localhost:/`. - Plugin host contract (`electron/plugin-library.ts`) — defines what plugin manifests must declare and what the plugin runtime can call back into. - **Consumes:** - The renderer (toju-app) via IPC `invoke`/`handle` and event emitters. - The local SQLite database via `electron/data-source.ts` and entities under `electron/entities/`. - OS APIs: window controls, idle detection (`electron/idle/`), game detection (`electron/game-detection/`), process list (`electron/process-list.ts`). - The audio worklet bundle (`toju-app/public/rnnoise-worklet.js` built from `@timephy/rnnoise-wasm`). ## Invariants - The **Renderer** never has direct access to Node, the filesystem, or the database — every privileged operation goes through an IPC handler. - Every schema change is accompanied by a **TypeORM migration**; the database is never mutated outside the migration system. - IPC handler errors are translated to typed error envelopes before crossing back into the renderer — the renderer never sees a raw `Error` from main. - The **Preload bridge** exposes a frozen, allow-listed set of methods; adding a method requires touching both `preload.ts` and the matching handler. ## Flagged ambiguities - _None recorded yet — add entries when an IPC channel name or plugin contract term resists clean definition._ --- *Agent-procedural rules (TDD, lint, build) live in `/AGENTS.md`. Cross-context contract details (IPC envelope shapes, plugin manifest schema) belong in `agents-docs/features/`. This file is the bounded-context domain artefact for the desktop shell.*