Summary
Replace the current PTY + tmux + xterm.js communication layer with a separate Rust daemon that spawns Claude Code (and Codex) using --output-format stream-json --input-format stream-json. The Tauri app talks to the daemon over a Unix domain socket using a JSON-lines protocol.
Design doc: docs/plans/2026-04-13-daemon-revamp-design.md (branch: daemon-revamp-design).
Reference implementation: slock-daemon — annotated source showing how a daemon can drive Claude Code with structured I/O, inbox queuing, and an agent state machine.
Motivation
Three limitations of the current architecture compound:
- No structured data. Output is ANSI bytes. The UI can't reason about thinking blocks, tool calls, or message boundaries.
- Fragile process control. Message delivery is typing into a PTY. No inbox, no mid-work notifications, no first-class busy/idle state beyond hook signals.
- tmux-coupled lifecycle. Session persistence, reattach artifacts, and hook-based status signals are all tangled into one layer.
Key decisions
- Separate daemon process, written in Rust, in a new Cargo workspace alongside
src-tauri.
- JSON-lines over Unix domain socket for UI ↔ daemon IPC.
- Incremental replace: gate behind a per-session
communication_mode flag. Terminal/tmux path stays until the daemon path proves out.
Proposed rollout
- Phase 1 — Workspace refactor, daemon skeleton,
DaemonClient in Tauri. No UI change.
- Phase 2 — Per-session flag +
StructuredTerminal.svelte. Both modes coexist.
- Phase 3 — Default new sessions to daemon mode. Migrate auto-worker, staging, secure-env, summary pane.
- Phase 4 — Retire
pty_manager, tmux, Terminal.svelte, hook-based status detection.
Open questions captured in the design
- Daemon lifecycle: Tauri sidecar on launch (leaning here), launchd, or lazy spawn?
- Daemon upgrade path when the Tauri app updates.
- stream-json format stability — need a compatibility layer + tests.
- Raw key input (CSI-u modifier sequences) has no direct analogue in structured mode; features relying on it need redesign.
- Staging under the daemon model: likely a second UI subscriber, needs phase 2 design.
Scope note
This issue tracks the overall effort. Each phase will get its own implementation plan and likely its own PR(s). Too large for single-shot auto-worker execution.
Summary
Replace the current PTY + tmux + xterm.js communication layer with a separate Rust daemon that spawns Claude Code (and Codex) using
--output-format stream-json --input-format stream-json. The Tauri app talks to the daemon over a Unix domain socket using a JSON-lines protocol.Design doc:
docs/plans/2026-04-13-daemon-revamp-design.md(branch:daemon-revamp-design).Reference implementation: slock-daemon — annotated source showing how a daemon can drive Claude Code with structured I/O, inbox queuing, and an agent state machine.
Motivation
Three limitations of the current architecture compound:
Key decisions
src-tauri.communication_modeflag. Terminal/tmux path stays until the daemon path proves out.Proposed rollout
DaemonClientin Tauri. No UI change.StructuredTerminal.svelte. Both modes coexist.pty_manager,tmux,Terminal.svelte, hook-based status detection.Open questions captured in the design
Scope note
This issue tracks the overall effort. Each phase will get its own implementation plan and likely its own PR(s). Too large for single-shot auto-worker execution.