Skip to content

feat(terminal): add bounded snapshot and history streaming - #189

Draft
Lint111 wants to merge 3 commits into
Ark0N:masterfrom
Lint111:agent/split-terminal-streaming
Draft

feat(terminal): add bounded snapshot and history streaming#189
Lint111 wants to merge 3 commits into
Ark0N:masterfrom
Lint111:agent/split-terminal-streaming

Conversation

@Lint111

@Lint111 Lint111 commented Jul 29, 2026

Copy link
Copy Markdown

Summary

Adds the server-side contracts for lossless, bounded terminal restoration and live delivery without loading an entire conversation into the browser.

  • adds per-session stream/generation cursors to terminal output
  • exposes raw compressed terminal snapshots with cursor metadata in response headers
  • captures bounded tmux history pages asynchronously with stable row coordinates
  • distinguishes an explicit empty SSE subscription from legacy unfiltered delivery
  • coordinates SSE/WebSocket ownership for a per-tab terminal stream
  • batches mobile output without splitting UTF-8, ANSI control strings, or synchronized updates
  • carries cursor ranges across bounded WebSocket frames
  • discards incomplete ANSI tails at clear, generation, and handoff boundaries

Commit Structure

  1. fix(stream): distinguish empty terminal subscriptions
  2. feat(terminal): add bounded snapshot and history streaming
  3. fix(terminal): preserve cursor boundaries across websocket frames

Design Notes

GET /api/sessions/:id/terminal?format=stream returns terminal text outside the JSON envelope and places stream, generation, range, source, truncation, and status metadata in headers.

historyPage=1 captures one physical-row page from tmux. Capture uses asynchronous execFile calls, bounded output buffers, and argument arrays rather than a shell, so a history request does not block other sessions or accept shell interpolation.

Live SSE and WebSocket batches use the same UTF-16 cursor units as JavaScript string slicing. Clients can queue output during a snapshot and deterministically discard overlap instead of relying on empty-buffer heuristics.

This PR is server/transport infrastructure. It intentionally excludes browser frame covers, lazy history rendering, session restoration metadata, repository browsing, Codex animation settings, and mobile controls; those are reviewed separately.

Validation

  • npm run build
  • npm run typecheck
  • npm run lint
  • Prettier check for every changed source/test/document
  • 162 focused tests across session routes, SSE filtering/batching, WebSocket transport, cursor handling, and tmux history paging

The repository-wide integration suite was not run in this active clone: its current cleanup path can delete the checkout itself. That isolation issue is tracked separately in #175; focused tests here use mocks/injected runners and cannot access the user's tmux server.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant