Skip to content

Move terminal VT state into the daemon (per design 01) #158

Description

@MasonRhodesDev

Tracking issue for docs/designs/01-daemon-canonical-terminal.md (Accepted).

Problem

When a single agent harness emits sustained PTY output, the desktop GPUI thread becomes unresponsive until the harness calms down. The render thread is on the parse path: LiveTerminalRuntime::apply_output (app/src/terminal_runtime.rs:283) runs alacritty_terminal::vte::ansi::Processor::advance synchronously inside drain_terminal_launch_replies (app/src/app.rs:6059) and drain_session_events (app/src/app.rs:5910). Existing mitigations (DRAIN_OUTPUT_BYTE_CAP, watchdog from #125) limp under typical load.

Decision

Per the design doc:

  • One alacritty_terminal::Term per PTY, owned by a per-tab tokio task in the daemon.
  • New wire: SessionEvent::TerminalFrame { Full | Diff } with monotonic seq, pull-paced via Control::TerminalSubscribe { max_fps, since_seq }.
  • Scrollback + search become RPCs (Control::TerminalReadScrollback, Control::TerminalSearch).
  • Bell/title via dedicated WorkerReply::Push variants.
  • PTY spawn moves to the daemon; GPUI-side fulfillment (pending_tab_launches, TabResizeRequest) goes away.
  • Inactive tabs still parse daemon-side; no frames emitted for unsubscribed (viewer, tab) pairs.
  • terminal-wrapping-principle refined: ANSI/VT parsing may live daemon-side; per-agent semantic parsing still forbidden.

Phases (see design doc for sub-phase breakdown)

  • Phase 1 — Wire types + principle clarification (1 PR; 4 commits)
  • Phase 2 — Daemon-side Term task (1 PR; 5 commits)
  • Phase 3 — Per-viewer pacer + dispatch wiring (1 PR; 3 commits)
  • Phase 4 — PTY spawn moves to daemon, flag-gated (1 PR; 3 commits)
  • Phase 5 — Desktop cutover (6 PRs: 5a–5f)
  • Phase 6 — Warm launches + Claude session restore migration (1 PR)
  • Phase 7 — Mobile viewer cutover (separate; possibly own repo)
  • Phase 8 — Diff frame emission (deferred; own issue when triggered)
  • Phase 9 — Per-viewer max_fps honoring (deferred; own issue when triggered)

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions