How it works
The request lifecycle in spawn, from a task on the board to live events streaming back.
Every task in spawn follows the same path: you describe it on the board, the router classifies it and picks a harness, the orchestrator spins up an isolated session, and a coordination sidecar keeps that session in sync with its siblings. This page walks through the pieces and the lifecycle that ties them together.
Architecture
TUI (board + per-thread detail, @opentui/react)
↔ WebSocket
spawn server (orchestrator)
├─ CodingRouter (subprocess → local ONNX classifier)
├─ CoordinationService (file registry, change feeds, context injection)
├─ Orchestration (commands → decider → events → read model; threads/sessions)
└─ Provider Drivers (Claude, Codex, OpenCode, Cursor, Grok, ...)
└── spawn child CLIs (worktree per session) → stream events back- TUI — the primary surface, a React app on
@opentui/core. The board launches and monitors sessions; per-thread detail shows chat, diffs, and state. It talks to the server over a WebSocket. - spawn server (orchestrator) — an Effect-based service that owns supervision, persistence (SQLite), git worktree management, and the flow between every other box.
- CodingRouter — runs a local ONNX classifier in a subprocess to decide the harness and model tier for a task. Fast and local, so classification doesn't bottleneck dispatch.
- CoordinationService — the cross-cutting sidecar. It maintains the live file registry, fans out change feeds on commit, prevents conflicts at dispatch time, and injects diff summaries into context.
- Orchestration — event-sourced core: commands run through a decider to produce events, which fold into a read model. Sessions map to threads, each with its full event history.
- Provider Drivers — a clean
ProviderDriver<Config>interface with adapters per backend. spawn ships Codex, Claude, Cursor, and OpenCode today, with Grok planned. Each driver spawns a child CLI in its own worktree and streams events back.
The lifecycle of a task
You describe a task in the TUI board — a short description of what you want done.
The router classifies it once — task type, complexity, risk, and sub-dimensions — and maps the result through a policy to a harness and model tier.
The orchestrator creates a session/thread in an isolated git worktree and starts the chosen provider through its driver.
The coordination service tracks file ownership and feeds change summaries to sibling sessions, heading off collisions before they happen.
Events stream back to the board live, so you watch progress across every parallel session at a glance.
Event-sourced orchestration
Orchestration is event-sourced: commands flow through a decider that emits events, and those events fold into a read model the TUI renders. Sessions map to threads, and each thread keeps its full event history — so state is always reconstructable and every session has an auditable timeline.
The TUI is the primary surface, but it isn't the only one. The web (React + Vite) and desktop (Electron) UIs talk to the same spawn server, so the board, routing, and coordination behave identically across all three.