Overview
Add a PtyBackend as a new ExecutionBackend implementation alongside TmuxBackend and DockerBackend, using the portable-pty crate. This removes the tmux dependency for environments that lack it, enables web terminal (xterm.js) functionality in the UI, and provides direct programmatic process management.
Parent research issue: #659
Motivation
The current tmux-based approach has several limitations identified in #659:
- No way to use tmux's built-in tools/commands from the orchestrator
- Attaching to a tmux session running Claude in SDK mode shows raw NDJSON, not useful for humans
- tmux is an external binary dependency that may not be available in all environments
- No web terminal capability for the UI
Architecture
The ExecutionBackend trait in crates/wrap/src/backend.rs already abstracts session management. A PtyBackend implements this trait with:
portable-pty for cross-platform PTY spawning
- Async adaptation via
tokio::task::spawn_blocking (same pattern as TmuxBackend)
- I/O stream capture for web terminal relay
- Session lifecycle management (spawn, health check, kill)
Feature Scope
Core Backend
Web Terminal (UI)
CLI Integration
Cross-cutting
Dependency Graph
#659 (research consensus)
└─► #672 (spike: validate portable-pty)
└─► #673 (PtyBackend implementation)
├─► #674 (I/O capture & streaming)
│ └─► #675 (orchestrator relay endpoint)
│ └─► #676 (xterm.js web terminal)
└─► #677 (CLI integration)
└─────────────────────────────► #678 (configuration & docs)
▲
#676 ────────────────────────┘
#677 ────────────────────────┘
Key Decisions
- Supplement, don't replace: tmux remains the default backend; PTY is opt-in via
AGENTD_BACKEND=pty
- Library choice:
portable-pty (0.9.0) — most mature, cross-platform, actively maintained (wezterm project)
- Web terminal supplements logs: The existing
AgentLogView (structured, timestamped, searchable) stays; xterm.js is offered as an additional "Terminal" tab
- Cost/usage tracking unchanged: Already flows through WebSocket protocol, not terminal output
Dependencies
portable-pty crate (0.9.0)
@xterm/xterm npm package (for UI)
crossterm crate (for CLI attach)
- Existing
ExecutionBackend trait (no changes needed to trait definition)
Acceptance Criteria
Overview
Add a
PtyBackendas a newExecutionBackendimplementation alongsideTmuxBackendandDockerBackend, using theportable-ptycrate. This removes the tmux dependency for environments that lack it, enables web terminal (xterm.js) functionality in the UI, and provides direct programmatic process management.Parent research issue: #659
Motivation
The current tmux-based approach has several limitations identified in #659:
Architecture
The
ExecutionBackendtrait incrates/wrap/src/backend.rsalready abstracts session management. APtyBackendimplements this trait with:portable-ptyfor cross-platform PTY spawningtokio::task::spawn_blocking(same pattern asTmuxBackend)Feature Scope
Core Backend
Web Terminal (UI)
CLI Integration
Cross-cutting
Dependency Graph
Key Decisions
AGENTD_BACKEND=ptyportable-pty(0.9.0) — most mature, cross-platform, actively maintained (wezterm project)AgentLogView(structured, timestamped, searchable) stays; xterm.js is offered as an additional "Terminal" tabDependencies
portable-ptycrate (0.9.0)@xterm/xtermnpm package (for UI)crosstermcrate (for CLI attach)ExecutionBackendtrait (no changes needed to trait definition)Acceptance Criteria
PtyBackendpasses all existingExecutionBackendcontract tests