Sessions model
How the dashboard and CLI represent a running harness.
Two sources, one UI#
Every session in /sessions carries a source tag:
- cu — spawned by dashboard + New session or Resume in cu. The daemon owns the PTY through
pty.Broker: full read+write. - external — discovered: the daemon spots a running
claude/codexby walking/proc(orps/WMI) and tails its on-disk transcript via fsnotify.
Both flavours surface the same way in the dashboard — single list, same xterm view. The only behavioural difference is whether the Interactive tab accepts keystrokes (cu) or is observe-only (external).
Where the transcript lives#
claude_code ~/.claude/projects/<dash-encoded-cwd>/<session-uuid>.jsonl
codex ~/.codex/sessions/<YYYY>/<MM>/<DD>/rollout-...-<uuid>.jsonlThe discovery scanner walks recent date shards (codex) or matches by encoded cwd (claude), opens the most-recently-modified .jsonl, and confirms via payload.cwd (codex) or path naming (claude). When the process exits the daemon waits 3s before marking the session ended — covers final flushes.
Resume in cu#
External sessions can't accept dashboard keystrokes — we don't own the PTY. Click Resume in cu in the session header: the daemon launches a new cu <kind> --resume <harness-id> in the same cwd. Same conversation, PTY now owned by the broker, fully writable.
Multi-attach#
cu attach <session-id> joins a daemon-owned PTY from any terminal on the same machine. The dashboard's Interactive tab does the same thing over WebSocket. Both paths converge on pty.Broker:
- Stdout fan-out — every subscriber sees every byte.
- 64 KB scrollback ring per session — new attachers get recent context.
- Controller semantics — first attacher types, others observe until
--take-control. Ctrl-\\detaches without killing the session.
Permission modes#
--cu-mode is the controlum abstraction; each harness maps it to its own approval / sandbox flags. Both cu claude and cu codextranslate uniformly:
claude codex
ask (default — claude prompts) (default — --ask-for-approval untrusted)
auto_safe --permission-mode acceptEdits --full-auto
dangerous --dangerously-skip-permissions --dangerously-bypass-approvals-and-sandboxClaude additionally runs the policy engine via PreToolUse hooks — independent of the cu-mode setting. Codex doesn't have an analogous hook surface yet, so for codex sessions the cu-mode + harness flags are the only enforcement layer. The dashboard's Permissions tab is also claude-only for the same reason.