Repository navigation
Conversation
…s screen After a session's first load per page, a tab switch fetched a 1 MiB tail of the server's byte stream. For a fullscreen claude pane (alternate screen, tmux `history_size` 0) that tail is old repaints of one frame, and an idle tab parsed it twice (the cached copy, then the fresh one). Every terminal response now records `paneHistoryLines` per session, and `selectSession` takes `full=1` whenever the last report was 0. For such a pane that capture is the visible frame, a few KB, which is also what a page load already shows. A response without the field forgets the entry, so unknown never counts as empty; a pane that starts keeping history goes back to the tail on the next switch. Shells and the refresh path are unchanged. Measured with real prod payloads through the real client in chromium: median switch 1.26-1.66 s -> 0.10-0.19 s, parse ~1.1-1.5 s -> 2-3 ms. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When you switch back to a terminal tab, the web UI reloads that session's terminal from the server. For a fullscreen Claude tab, every switch after the first downloaded and replayed a 1 MB tail of old screen redraws, which cost about 1.3 to 1.7 s in the browser plus 136 to 1,070 ms on the server. This PR makes those switches load only the current screen, a few KB, which is what a page load already does. It builds on #583, which adds the
paneHistoryLinesfield this relies on. No server or API changes beyond that field.Why the tail was wasted work
#{history_size}is 0), because Claude keeps the conversation itself and the wheel scrolls it there.selectSessionfetched?tail=1048576: the last 1 MiB of the server's raw output stream plus the current frame. For these panes that stream is earlier redraws of the same screen. One measured pane gave 450 non-blank scrollback rows, only 44 of them distinct.What this PR changes
paneHistoryLinesper session (_notePaneHistory).selectSessionrequestsfull=1instead of the tail. For such a pane that capture is the visible frame. That is the same request and the same rendering a page load already uses for every TUI session.Evidence
All 11 live sessions on the measured instance were fullscreen Claude panes with 0 tmux scrollback. Real tail and full payloads from two of them, replayed through the real
selectSessionin Chromium, alternating the two tabs 12 times, old logic vs new:full=1)The geometry fields were stripped for this run, so the old path was not penalised by a resize retry it would not take on the user's own screen.
Unstubbed, on an isolated instance with two real fullscreen Claude sessions:
full=1.tmux capture-pane).Side effect worth knowing
After a switch, the local scrollback of such a tab is empty instead of holding repeated frames. That matches what a page load already shows. It is also what lets
_maybePageCliTranscriptturn a gesture into PageUp/PageDown for the CLI's own transcript when wheel forwarding is off: that fallback only engages when there is no local scrollback.Shift+Wheelon such a tab now scrolls nothing locally rather than through repeats.Reviewing the diff
The logic is about 50 lines in
src/web/public/app.js:_paneHistoryLines(constructor) and_notePaneHistory(new method).useFullHistorycondition inselectSession._clearHistoryTruncation.The rest is tests and docs:
test/pane-history-memory.test.ts(CI gate) runs the real methods in avm.test/fullscreen-tab-switch-capture.browser.test.ts(browser suite, registered inconfig/test-suites.ts) drives the real client with a stubbed terminal route: hollow vs inline panes, a pane gaining history, and an unknown report. Disabling the new condition fails it.test/history-truncation-notice.test.ts: the static pin on theuseFullHistoryexpression is updated.Risk
mux-visible) does not run for these switches. This is unchanged from how page loads already behave.Testing
npm test(the CI gate): 10,381 passed.format:check,check:frontend-syntaxandcheck:browser-excludesclean.capture-geometry-retryandcapture-load-windowpass (11 tests).