Repository navigation
fix(terminal): partial-history notice only when there is history to load - #583
Merged
Merged
Conversation
The "Showing the most recent 1.0 MB of this session. 4.8 MB more may still
be retained." bar covered the top of the terminal on nearly every tab switch,
and for fullscreen claude panes it could never be acted on: `truncated`
measures the server's byte stream, while Load full history asks tmux, which
holds no scrollback for a pane that lives in the alternate screen.
- The capture reads `#{history_size}` in the cursor query it already makes
and the terminal route returns it as `paneHistoryLines`.
- A reported 0 hides the notice; a positive count replaces the byte gap in
the message.
- The notice is lazy: it appears once a wheel/touch gesture reaches the top
of the browser buffer (after the pull that gesture starts), leaves when
the user scrolls back to live output or switches tabs, and its dismissal
sticks per session until reload.
- formatHistoryBytes no longer prints "1024 KB" just under 1 MiB.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Ark0N
pushed a commit
that referenced
this pull request
Oct 13, 2026
#583 merge-time fix) _smoothScrollBy and the touch paths call _maybeLoadMoreHistoryOnScroll on every frame. Once the viewport sat at row 0, the next frame hit the real pull's in-flight early return, so its reveal ran at once and the notice showed the pre-pull tail state for the whole pull. A later frame now leaves the reveal to the call that started the pull. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Ark0N
pushed a commit
that referenced
this pull request
Oct 13, 2026
…read (#583 merge-time fix) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Ark0N
pushed a commit
that referenced
this pull request
Oct 13, 2026
…ered history, not the byte recording Conflicts resolved against #583 and #588: - One history-depth field: #583's `historyLines` / `capturedHistoryLines` (reported as `paneHistoryLines`) is kept, and #601's lines cut now reads it instead of a second `capturedHistorySize`. #601's `alternateOn` / `capturedAlternateOn` joins it, and the one display-message format string ends `#{history_size} #{alternate_on}`. - selectSession keeps #588's full=1 switch for panes with no scrollback, gated off remote and Docker sessions, and #601's SHELL_LOAD_QUERY for shells. - computeHistoryTruncationNotice names a line count when paneHistoryLines is known (#583) and otherwise uses #601's remainder wording. - docs: api-reference lists both historyLinesCut and paneHistoryLines; the notice invariant keys on history_size while the shell's automatic load is the one place alternate_on decides. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Ark0N
pushed a commit
that referenced
this pull request
Oct 13, 2026
…tegration) A remote session's local pane hosts the remote tmux client in the alternate screen, so its history_size is always 0. #583 read that as "nothing to load" and hid the partial-history notice, but with #602 a full=1 load reads the real scrollback from the remote tmux. The route now leaves the field out for remote sessions, so their notice keeps the byte-based wording and its Load full history button. 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 a terminal replay is cut short, the web UI shows a bar over the top of the terminal: "Showing the most recent 1.0 MB of this session. 4.8 MB more may still be retained." with a Load full history button (#258). This PR makes that bar appear only when it means something and only when you are looking for history. Before, it showed on almost every tab switch and could not be acted on for fullscreen Claude sessions.
What was wrong
truncatedmeasures the server's raw byte stream. Load full history asks tmux for its scrollback instead. A fullscreen Claude pane lives in the alternate screen and tmux keeps 0 lines of scrollback for it (Claude keeps the conversation itself). So the "4.8 MB more" was old screen redraws, and the button could only end in the existing downgrade refusal ("Earlier output is no longer kept").What this PR changes
capturePaneBufferalready runs onedisplay-messagefor the cursor and pane size. That same call now also reads#{history_size}(no extra tmux call).GET /api/v1/sessions/:id/terminalreturns it aspaneHistoryLines, the rows tmux holds above the visible frame. The field is absent when the body is not a pane capture. This is an additive response field.paneHistoryLines === 0hides it in every state. A positive count replaces the misleading byte figure: "99,971 lines of scrollback are retained." Without the field (an older server, or a byte-history fallback) the old wording is kept.formatHistoryBytesno longer prints "1024 KB" for a tail cut just under 1 MiB.Not changed: what any load fetches or replays, the downgrade guard, the tile grid, and shell pull sizes.
Evidence
Measured on a live instance with 11 fullscreen Claude sessions:
alternate_on=1,history_size=0.full=1returned 0.9 to 5.6 KB, which is the visible frame only.End to end in Chromium on an isolated instance, with trusted wheel events:
full=1= 155 bytes): never shown, even at the top.Why
history_sizeand notalternate_onA shell running
lessis also in the alternate screen, but tmux still keeps its whole history (measured 99,972 rows), andfull=1returns all of it.history_sizeis exactly what the full pull can add, so the decision keys on that.Reviewing the diff
About 330 of the 561 added lines are tests and about 20 are docs. The logic is roughly 110 lines:
src/tmux-manager.ts:queryPaneCursorparses an optional fifth field, validated on its own so a bad value never voids the caret;capturePaneBuffercopies it toopts.capturedHistoryLines.src/web/routes/session-routes.ts: one response field.src/web/public/constants.js:computeHistoryTruncationNoticegating and wording.src/web/public/app.js: banner render gate, sticky ×,_setHistoryNoticeRevealed, and the reset inselectSession.src/web/public/terminal-ui.js:_maybeLoadMoreHistoryOnScrollreveals at the top and retires at the bottom.New test:
test/history-notice-reveal.test.tsruns the real app.js / terminal-ui.js / constants.js methods in avmagainst a stub DOM. Removing the reveal gate makes 5 of its tests fail.Risk
Testing
npm test(the CI gate): 10,376 passed.format:checkandcheck:frontend-syntaxclean.