# System Design

Zonegaze Flow is a local-first orchestration system with a browser control surface, a stateful Node runtime, task worktrees, PTY-backed CLI agents, and a native Cline SDK path.

## Context

The primary user is a developer running many coding agents against one or more local repositories. The product must isolate work, keep runtime state live in the browser, and make review/shipping workflows explicit.

External systems include git remotes, CLI agent binaries, Cline SDK/provider services, MCP servers, desktop shell integrations, Android storage/runtime surfaces, Sentry, PostHog, and package update endpoints.

## Containers

- Web app: React, Tailwind, Radix, Lucide, xterm, TRPC client, websocket consumers.
- Runtime: Node CLI/server, TRPC router, workspace registry, state hub, terminal manager, Cline SDK services, workspace/git utilities.
- Contracts: shared Zod schemas and runtime types.
- Product adapter: Zonegaze board behavior layered outside upstream-compatible Kanban core.
- Plugins: sibling product source boundaries such as `plugins/whispr/`, discovered through the shared catalog and launched/downloaded through Flow surfaces.
- Platforms: Electron desktop, Android, and server-manager packages. User-facing app installation is documented in [platform application guides](../platforms/README.md).

## Main Runtime Flows

Task start:

1. Web app sends `startTaskSession`.
2. Runtime resolves workspace, task worktree, agent, dimensions, context, and mode.
3. PTY agents launch through `TerminalSessionManager`; Cline launches through `ClineTaskSessionService`.
4. Runtime summaries flow through `RuntimeStateHub`.
5. Browser updates board cards, detail panels, and notifications.

Review flow:

1. Runtime captures worktree changes.
2. Web app requests all changes or last-turn changes.
3. Diff renderer presents files and hunks.
4. User comments are sent back to the agent, or commit/PR prompts are issued.

State stream:

1. Client connects to runtime state websocket.
2. Runtime sends a snapshot before deltas.
3. Workspace state, metadata, sessions, projects, chat messages, MCP auth, and review notifications stream as typed messages.

## Ownership Rules

- Browser owns presentation and transient UI state.
- Runtime owns session lifecycle, workspace state, worktrees, git, and streaming.
- Contracts own the browser-runtime wire shape.
- Cline SDK owns provider secrets, OAuth, and SDK session persistence.
- Product adapter owns Zonegaze-specific hierarchy and task behavior.
- `flow/kanban-core` remains upstream-compatible and must not receive Zonegaze product docs.

## Quality Attributes

- Isolation: each task runs in its own worktree when possible.
- Recoverability: terminal mirrors, Cline persisted history, task patches, and turn checkpoints reduce lost work.
- Safety: passcodes, origin checks, path sandboxing, and explicit destructive actions protect local state.
- Responsiveness: state streams avoid polling for long-running work.
- Maintainability: SDK and platform imports stay behind boundary modules.

## Security Model

Local mode (default, bound to `127.0.0.1`):

- The runtime API has no authentication by design: any process running as the same user can reach it, including the shell-adjacent surfaces (script shortcuts, terminal sessions, directory browsing).
- Browser-based attacks are mitigated at the HTTP layer: every request and websocket upgrade passes a Host-header allowlist (blocks DNS rebinding) and an Origin gate (blocks cross-origin calls) in `flow/runtime/src/server/middleware.ts`.
- Do not bind to a non-loopback host unless you intend to enable remote mode.

Remote mode (`--host` set to a non-loopback address):

- A cryptographically random passcode is generated at startup and printed once to the console. Browsers exchange it for an in-memory session cookie (`HttpOnly`, `SameSite=Strict`, 24h TTL); CLI subprocesses authenticate with a separate internal bearer token. Failed attempts are rate limited per IP. See `flow/runtime/src/security/passcode-manager.ts`.
- Static assets and `index.html` are served without authentication so the passcode gate UI can render; all `/api/*` routes are hard-blocked until authenticated.
- The MCP OAuth callback (`/kanban-mcp/mcp-oauth-callback`) is deliberately reachable without a session: it is the target of a cross-site redirect from the OAuth provider, and `SameSite=Strict` cookies are not sent on cross-site navigation. It is protected instead by single-use, crypto-random request IDs with a bounded lifetime, so an unauthenticated caller cannot inject an authorization code without guessing an in-flight UUID.
- `--no-passcode` disables all of this and must only be used behind an external auth layer (for example a reverse proxy). Use `--https` with `--cert`/`--key` to serve TLS directly.

## Component Guides

- Runtime control plane: `flow/runtime/src/trpc/`, `flow/runtime/src/server/`.
- PTY runtime: `flow/runtime/src/terminal/`.
- Cline integration: `flow/runtime/src/cline-sdk/`.
- Workspace/git: `flow/runtime/src/workspace/`.
- Web composition and hooks: `flow/web/src/App.tsx`, `flow/web/src/hooks/`, `flow/web/src/runtime/`.
- Platform packages: `platforms/desktop/`, `platforms/server-manager/`, `platforms/android/`.
- Plugin catalog and source: `flow/contracts/src/zonegaze-products.ts`, `plugins/`.

## Architecture References

- [Existing architecture overview](../architecture.md)
- [ADR index](../adr/README.md)
- [Generated source reference](../reference/generated/source/README.md)
