feat(terminal): add bounded snapshot and history streaming - #189
Conversation
Ark0N
commented
Aug 5, 2026
Hi Lior, closing this one as part of a cleanup of the seventeen PRs currently open from you. The full explanation is in #173, and I would rather you read that one than this note, because it is the honest version and it is not a dismissal of your work. The short form: sixteen PRs opened in a single day, roughly 42,000 added lines in total, landing mostly on the same few files (nine touch Going forward, please keep no more than three open PRs at a time, each one a single behavior change that stands on its own, with a test that fails on master and passes with the fix. #214 and #215, merged today, are good models. If this particular change fixes something that genuinely annoys you in daily use, it is a good candidate to be the first one you reopen on its own, rebased on current master. I will review it properly. Thanks for the effort you put in, and sorry to close it this way. |
Summary
Adds the server-side contracts for lossless, bounded terminal restoration and live delivery without loading an entire conversation into the browser.
Commit Structure
fix(stream): distinguish empty terminal subscriptionsfeat(terminal): add bounded snapshot and history streamingfix(terminal): preserve cursor boundaries across websocket framesDesign Notes
GET /api/sessions/:id/terminal?format=streamreturns terminal text outside the JSON envelope and places stream, generation, range, source, truncation, and status metadata in headers.historyPage=1captures one physical-row page from tmux. Capture uses asynchronousexecFilecalls, 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 buildnpm run typechecknpm run lintThe 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.