Three Hard Boundaries
Rig runs across three decoupled layers: a static React SPA (the presentation shell), a Node.js
Fastify server (the state-holding proxy), and pi child processes (the agent execution
engine). The server never imports pi as a library — it discovers it via
which pi and spawns it with spawn() from node:child_process.
This means Rig is structurally immune to internal changes within the agent, so long as the RPC
protocol contract is upheld.
graph LR
subgraph Frontend [" React 19 SPA (:5173) "]
APP["App.tsx — Router + State"]
BOARD["Board.tsx — Session List"]
LOG["SessionLog.tsx — Work Log"]
HOOK["useSessionBridge — WS Hook"]
end
subgraph Server [" Fastify Proxy (:3100) "]
ROUTES["routes.ts — REST + WS"]
BRIDGE["pi-bridge.ts — Process Manager"]
STORE["session-store.ts — JSONL Reader"]
FTRACK["file-tracker.ts — Edit Tracker"]
end
subgraph PiLayer [" Pi Subprocess "]
PI["pi --mode rpc"]
SESS[("~/.pi/agent/sessions/")]
CONF[("settings.json")]
end
APP -->|"REST /api/*"| ROUTES
HOOK <-->|"WebSocket /api/ws/:id"| ROUTES
ROUTES -->|"spawn + stdin"| BRIDGE
BRIDGE -->|"spawn()"| PI
PI -->|"stdout JSONL"| BRIDGE
STORE -->|"readFile"| SESS
ROUTES -->|"readPiSettings()"| CONF
PI -->|"write"| SESS