pi-remote-control/docs/PHASE-0.5-spike-tmux-contro...

136 lines
5.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Phase 0.5 — Spike: tmux Control Mode
> **Status:** ready to start.
> **Owner:** single agent, end-to-end.
> **Branch:** `feat/spike-tmux-cc`.
> **Estimated effort:** ~2 hours.
> **Trigger:** Phase 0 found that `tmux pipe-pane` is not reliable across
> alternate-screen transitions. This phase evaluates the alternative.
## Background
Phase 0 (`PHASE-0-spike-stream.md`, report at
`docs/reference/PHASE-0-report.md`) validated the high-level design:
pi-in-tmux works, ANSI streaming over WebSocket works, latency is
excellent, SSH and WS stay in sync.
**But:** `tmux pipe-pane` is fragile. After alternate-screen usage
(`/settings`, full-screen menus) the pipe can detach silently; the
client sees a frozen stream. This is a Phase-1-blocker for the
`tmux/pipe.ts` task.
Two known alternatives:
- **(A)** Keep pipe-pane, add a watchdog that polls `#{pane_pipe}` and
re-arms when it falls to `0`. Simple but races: bytes produced
between detach and detection are lost.
- **(B)** Use **tmux control mode** (`tmux -CC`). tmux exposes a
structured event stream to a control client; pane output arrives as
framed events. This is the protocol iTerm2 uses for its tmux
integration. Multi-client attach still works for normal SSH users.
This spike decides between A and B with evidence.
## Goal
Verify that tmux control mode can reliably deliver pane bytes to a Node
client across the conditions where pipe-pane fails. Produce a short
report and a Go decision for one of the two paths.
## Acceptance Criteria
- A new branch `feat/spike-tmux-cc` with throwaway PoC code.
- A Node script that:
- Spawns a tmux session running `pi`.
- Connects to that session as a control client (`tmux -CC`).
- Parses the control-mode protocol enough to extract `%output`
events from the pi pane.
- Streams those bytes to stdout (no WebSocket needed for the spike —
raw stdout is fine).
- A test session that triggers the Phase-0 failure mode:
1. Pi running normally → bytes flow.
2. User runs `/settings` (alternate-screen) → bytes still flow.
3. User exits settings → bytes still flow.
4. Run for ≥5 minutes with mixed interactions.
- Report `docs/reference/PHASE-0.5-report.md` answering:
- **R-CC-1.** Does control mode deliver pane output reliably across
alternate-screen transitions?
- **R-CC-2.** Latency compared to pipe-pane (rough — same order of
magnitude is enough)?
- **R-CC-3.** Does a parallel `tmux attach` SSH client still work
while a control-mode client is connected? (P-2 critical.)
- **R-CC-4.** Is the control-mode protocol parser non-trivial? Order
of complexity estimate.
- **R-CC-5.** Verdict: **Path B (control mode)** or **Path A
(pipe-pane + watchdog)** for Phase 1, with reasoning.
## Out of Scope
- No WebSocket layer (raw stdout suffices to prove the streaming).
- No reconnect, sequence, snapshot, buffer.
- No send-keys.
- No reuse of Phase-0 spike code — start clean.
- No production-quality parser — minimal viable parser for `%output`
events is enough.
## Implementation Notes
- tmux control mode launch:
```bash
tmux -CC new-session -s pi-cc 'pi'
```
or attach to an existing detached session:
```bash
tmux new-session -d -s pi-cc 'pi'
tmux -CC attach -t pi-cc
```
- Control-mode protocol overview (consult `man tmux`, search
"CONTROL MODE"):
- Server emits lines like `%output %1 <octal-escaped-bytes>` for
pane output.
- Other events: `%session-changed`, `%window-add`, `%begin`/`%end`,
`%layout-change`, etc. — most can be ignored for the spike.
- Client sends regular tmux commands as plain text; replies are
framed by `%begin <ts> <num> <flags>``%end <ts> <num> <flags>`.
- Parse just `%output` lines, decode the octal escapes (`\NNN` in tmux's
output → bytes), write bytes to stdout.
- Spawn tmux as a child process from Node, talk via stdin/stdout pipes.
## File Plan
- New: `extensions/remote-control/spike-cc.ts` (or `.js`, whichever is
faster). ~100200 lines.
- New: `docs/reference/PHASE-0.5-report.md`.
- No changes to Phase-0 spike files.
## Test Protocol (the spike's own QA)
Run for ≥ 5 minutes, in parallel:
1. Terminal A: `npm run spike-cc` (your spike runner).
2. Terminal B: `tmux attach -t pi-cc` — verify normal SSH-style attach
still works alongside the control client.
3. Terminal A side: confirm bytes keep flowing through these events:
- Type a prompt and let pi respond.
- Run `/settings`, navigate around, exit.
- Run a longer pi tool call.
- Resize Terminal B and observe whether the stream stays clean.
If at any point bytes stop flowing without an obvious tmux process
exit: the spike failed for Path B and the verdict is Path A.
## Exit / Handover
- Push branch, push report.
- Update `docs/SYNC.md`:
- Remove your active claim.
- History entry.
- Phase Gate Table: Phase 0.5 → `done`, with verdict noted.
- Based on verdict:
- **If Path B:** open follow-up note in SYNC about updating
`PHASE-1-sidecar.md` T-1.1 to specify tmux control mode in
`tmux/pipe.ts`.
- **If Path A:** same, but specifying pipe-pane + watchdog.
In either case, do **not** modify `PHASE-1-sidecar.md` yourself —
that's an orchestrator-level edit and triggers a contract change
review.