pi-remote-control/docs/PHASE-0-spike-stream.md

4.7 KiB

Phase 0 — Spike: tmux Stream PoC

Status: ready to start. Owner: single agent, end-to-end (too small to parallelise). Branch: feat/spike-stream. Estimated effort: ~1 day.

Goal

Verify the foundational assumption of the entire spec: that we can run pi inside tmux, tee the pane output via pipe-pane, push it as a binary WebSocket stream, and consume it from a client without rendering artefacts or unacceptable latency.

Output is a decision: green light for Phase 1, or list of blockers that need spec revision.

Acceptance Criteria

  • A new branch feat/spike-stream in pi-remote-control.
  • A CLI invocation (e.g. pi-remote spike) that:
    • Spawns a tmux session pi-spike running pi.
    • Pipes the pane via pipe-pane to a WS endpoint on ws://127.0.0.1:7799/spike.
    • Attaches the local terminal to the same tmux session.
  • A test client (raw wscat script or a tiny throwaway HTML page) that connects, dumps incoming binary frames to stdout (or a hex viewer) and optionally re-renders them via xterm.js.
  • A written PoC report docs/reference/PHASE-0-report.md answering:
    • R-1. Does pi run cleanly inside tmux? (Ink redraws OK, no escape sequence loss, no crashes during 10min uptime.)
    • R-2. Does alternate-screen-buffer (\e[?1049h) work? Is the stream parseable on the other side?
    • R-3. Is per-chunk latency acceptable (< 50ms localhost, < 200ms WAN)?
    • R-4. Does the SSH session attached to the same tmux pane stay in sync with the WS stream byte-for-byte?
    • R-5. Edge cases observed (mouse mode, title sequences, very wide output, etc.).

Out of Scope for Spike-0

  • No authentication, no TLS — bind to 127.0.0.1 only.
  • No reconnect, sequence numbers, snapshot or buffer.
  • No send-keys direction (read-only stream is enough to verify rendering).
  • No multi-session — one fixed pi-spike session.
  • No iOS code.

Task Breakdown

T-0.1 — Branch + skeleton

Create feat/spike-stream. Add a new file extensions/remote-control/spike.ts and a CLI entry (a new flag --spike on the existing extension or a separate npm-script — whichever is faster).

T-0.2 — tmux helper

Spawn tmux session, attach pipe-pane to a Unix FIFO or a pseudo-stream we can read from Node. Reference command:

tmux new-session -d -s pi-spike 'pi'
mkfifo /tmp/pi-spike.fifo
tmux pipe-pane -t pi-spike -o "cat > /tmp/pi-spike.fifo"

Node opens the FIFO read-side (fs.createReadStream) and exposes the byte stream.

T-0.3 — WS server

Stand up a minimal ws server on port 7799, route /spike, send the FIFO bytes as binary frames. No backpressure handling, no permessage-deflate yet.

T-0.4 — Test client

Two options, pick whichever is faster:

  • (a) wscat -b ws://127.0.0.1:7799/spike and pipe through od -c for raw inspection.
  • (b) A 50-line HTML page with xterm.js, plain WebSocket, no styling.

T-0.5 — Attach + dual-render test

Open a second terminal, run tmux attach -t pi-spike. Type into pi. Verify that what you see in the SSH attach is identical to what arrives on the WS client.

T-0.6 — Stress / edge cases

Briefly try:

  • Resize the SSH terminal — see how tmux/pi react.
  • Run a slash command that opens a full-screen menu (alternate screen).
  • Paste a multi-line block.
  • Let pi do a long tool call.

T-0.7 — Report

Write docs/reference/PHASE-0-report.md. One paragraph per R-question, plus a "go / no-go for Phase 1" verdict.

File Plan

  • New: extensions/remote-control/spike.ts
  • New: docs/reference/PHASE-0-report.md
  • Modified: extensions/remote-control/index.ts (add --spike flag or separate entry).
  • No changes to existing server.ts / html.ts / messages.ts.

Dependencies

  • tmux installed on the dev host. macOS: already present or brew install tmux.
  • ws library: already in package.json.
  • mkfifo shell command (POSIX): already present on macOS/Linux.

Risks

  • R-A. Ink may refuse to run inside tmux due to TTY detection. If so, set FORCE_COLOR=1, TERM=xterm-256color, pass -tt to tmux. Fall back to spawning pi via unbuffer if necessary.
  • R-B. FIFO can have buffering issues. If line buffering causes visible lag, switch to a Unix domain socket and have Node read directly from the socket.
  • R-C. tmux's pipe-pane reproduces ANSI but may drop sequences during bursts. If lossy, the alternative is to run pi inside our own node-pty (a much larger change, but a fallback option).

Exit / Handover

When Phase 0 closes:

  • Merge feat/spike-stream into main only if PoC code is reusable for Phase 1; otherwise close the branch and keep the report.
  • Update SYNC.md with the verdict and any spec revisions needed.
  • Trigger Phase 1.