Experiment Persistence dakka

A monorepo architecture with 4 packages (shared, gork, mork, shell) connected by WebSocket protocol will enable parallel Claude Code orchestration with full terminal fidelity

monorepoarchitectureai-agents
Hypothesis

A monorepo architecture with 4 packages (shared, gork, mork, shell) connected by WebSocket protocol will enable parallel Claude Code orchestration with full terminal fidelity

Result: confirmed
Key Findings

Full terminal fidelity achieved via PTY-based execution. XState v5 state machines manage agent lifecycle. WebSocket binary framing protocol operational for inter-process communication.

Changelog

DateSummary
2026-04-06Audited: added Changelog, domain tag, stamped last_audited
2026-03-29Initial creation

Hypothesis

A monorepo architecture with 4 dedicated packages, connected by a WebSocket binary framing protocol, will enable parallel Claude Code orchestration with full terminal fidelity. The key bet is that splitting concerns into shared types, backend orchestration, frontend rendering, and desktop shell will allow each layer to evolve independently while maintaining a single coherent protocol.

Method

Built the monorepo from scratch across 29 sessions using Turborepo for build orchestration. The 4 packages:

  1. shared: TypeScript types and WebSocket protocol definitions. All message schemas, agent role enums, and state machine event types live here. Both gork and mork import from shared, ensuring type safety across the process boundary.

  2. gork (backend): PTY management via node-pty, XState v5 state machines for agent lifecycle (spawning, running, killing, errored), and a WebSocket server that broadcasts PTY output as binary frames. Each agent gets its own PTY instance with isolated environment variables.

  3. mork (frontend): React application with xterm.js terminal emulators. Each agent renders in its own terminal pane. WebSocket client receives binary frames and writes directly to xterm instances, preserving full ANSI escape sequences, colors, and cursor positioning.

  4. shell: Electron wrapper providing native desktop experience. Manages window lifecycle, tray integration, and IPC bridge between the renderer (mork) and main process (gork).

The WebSocket protocol uses binary framing for terminal data (high throughput, low overhead) and JSON for control messages (spawn, kill, status updates).

Results

Confirmed. All 4 packages operational after 29 sessions of development. Full terminal fidelity achieved: ANSI escape sequences, 256-color output, cursor positioning, and alternate screen buffer all work correctly through the PTY-to-xterm pipeline. XState v5 state machines provide predictable agent lifecycle management with clear state transitions and error recovery. The WebSocket binary framing protocol handles sustained terminal output without frame dropping or backpressure issues.

Findings

  1. Turborepo monorepo enables shared types across frontend and backend. The shared package eliminates type drift between gork and mork. Protocol changes are caught at compile time rather than at runtime.

  2. PTY-based execution preserves full terminal fidelity. Unlike approaches that parse terminal output as text, raw PTY output piped through binary WebSocket frames to xterm.js preserves every escape sequence. Claude Code’s rich terminal output (spinners, progress bars, colored diffs) renders identically to a native terminal.

  3. XState v5 state machines are well-suited for agent lifecycle. The finite state machine model maps naturally to agent states (idle, spawning, running, killing, errored). Guard conditions prevent invalid transitions (e.g., killing an agent that is still spawning).

  4. Binary framing is essential for performance. Early prototypes using JSON-encoded terminal data introduced noticeable latency on high-output commands. Switching to binary WebSocket frames eliminated this bottleneck.

Next Steps

Add spawn/kill UI with +/- buttons for dynamic warband management. The current system requires manual WebSocket commands to spawn and kill agents. A visual UI with fixed spawn order will make the system usable for daily development workflows. See experiments/dakka/2026-03-29-v020-spawn-kill-ui.