Rex is a terminal kanban for parallel AI coding-agent sessions. Two processes: rex (client) and rex-daemon (supervisor).
┌─────────────┐ JSONL/UDS ┌──────────────────┐
│ rex (TUI/ │ ◄──────────────► │ rex-daemon │
│ CLI) │ protocol. │ - server (UDS) │
└─────────────┘ Envelope │ - state.Store │
│ - N × pty. │
│ Supervisor │
└────────┬─────────┘
│ spawn
▼
┌──────────────────┐
│ agent CLIs │
│ (claude, codex, │
│ echo, …) │
└──────────────────┘
- Client (
internal/wire/client): dial socket,Hello, subscribe, send intents. - Server (
internal/daemon/server): accept connections, mutatestate.Store, spawnpty.Supervisorper session. - PTY (
internal/daemon/pty): one child process, adapter classification, transcript append. - Persistence (
internal/daemon/state):~/.local/share/rex/sessions/<id>/meta.json+transcript.log.
TUI boot (internal/surface/tui/splash_steps.go): if socket unreachable, daemonctl.Start execs rex-daemon beside rex binary.
- User presses
ior runsrex new→IntentNewSessionwith tool/model from registry + settings. - Server acquires concurrency slot, creates
state.Session, starts supervisor with resolvedregistry.Toolcommand line. - Adapter reads PTY output → updates
Session.State→ store broadcastsEventSessionUpdated. - Subscribed clients (TUI) render board columns by state.
- Optional: supervisor enqueues session id on
SummaryRequest→ summarizer patchesdescription.
rex attach <sel>or TUI attach: clientSubscribeReplay, receives transcript tail + liveSessionOutput.- Server forwards stdin via
SendInput/ dedicated input channel to supervisor. - Detach stops forwarding; daemon keeps child running.
cmd/rex → cli → {client, tui, daemonctl, settings, …}
cmd/rex-daemon → {server, state, registry, summarizer, lua, settings, rexlog}
cli → client, protocol, tui, daemonctl
tui → client, protocol, audio, settings, registry, daemonctl
server → {protocol, state, registry, pty, adapter, ids}
pty → {adapter, state, protocol}
adapter → {protocol, registry}
client → protocol
summarizer → {state, protocol}
state → protocol
daemonctl → (stdlib)
- Daemon:
Serveaccept loop; per-client handler goroutine; per-session supervisor goroutine; summarizer single worker goroutine; store broadcasts to subscriber callbacks (TUI event pump). - TUI: Bubble Tea model on main thread; daemon events via
DaemonEventMsgchannel. - Session cap:
server.TryAcquireSession/max_concurrent_sessionsflag and setting.
SIGHUP on daemon reloads tools.yaml into server.SetRegistry without restarting PTYs. rex reload sends SIGHUP via CLI.
| System | Package | Role |
|---|---|---|
| Agent CLIs | registry + pty |
Child processes |
| Ollama | summarizer |
Local HTTP descriptions |
| oto | audio |
UI sounds |
| Lua (optional) | lua |
Event hooks in daemon |
Human design notes: ../architecture.md, ../protocol.md. When they disagree with code, code wins — see AGENTS.md.