feat: replay scrollback history on attach#69
Merged
Conversation
Attaching to a session only rebuilt the visible screen via STATE_SYNC, so after a Neovim restart the terminal buffer had no scrollback and normal-mode scrolling/search found nothing above the viewport. Add a HELLO/HELLO_ACK protocol version handshake (proposal 0001) and a HISTORY frame (proposal 0002): clients that set REQUEST_HISTORY in HELLO receive the daemon's vt100 scrollback as a raw escape-sequence stream once, just before the initial STATE_SYNC. Wrapped rows are re-joined so search works across wrap points, and viewport padding keeps the STATE_SYNC redraw from overwriting the history tail. REDRAW and later RESIZE re-snapshots never resend history, so auto_redraw cannot duplicate it. Clients and daemons without HELLO keep the legacy behavior, so mixed-version setups stay compatible. The replay length is capped by PTERM_HISTORY_REPLAY_LINES (default: unlimited). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
0001 (protocol handshake) and 0002 (scrollback replay) are implemented; 0003 (daemon handoff) and 0004 (reboot persistence) are withdrawn as not worth their complexity. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ttak0422
added a commit
that referenced
this pull request
Jul 5, 2026
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.
Summary
Fixes the "cannot scroll" bug: attaching to a session only rebuilt the visible screen via
STATE_SYNC, so after a Neovim restart the terminal buffer had no scrollback — normal-mode scrolling, search, and markers found nothing above the viewport.Implements proposals 0001 and 0002 (included under
docs/proposals/):PROTO_VERSION = 1, clientHELLO(version + flags), serverHELLO_ACK, serverHISTORY, plus encode/parse helpers.history_formatted()pages through the vt100 scrollback withset_scrollbackand emits history lines oldest-first as a raw escape-sequence stream. Wrapped rows are emitted without\r\nso long lines re-join in the terminal buffer and search works across wrap points. Ends with one viewport of padding so the followingSTATE_SYNCredraw does not overwrite the history tail. Empty while the alternate screen is active.proto/wants_historyfromHELLO; queuesHISTORYonce, just before the initialSTATE_SYNC.REDRAWand laterRESIZEre-snapshots never resend history, soauto_redraw(which fires on everyBufEnter) cannot duplicate it.HELLO_ACKis (re)queued ahead of the firstSTATE_SYNCeven whenreplace_send_bufdrops queued frames; duplicate ACKs are idempotent. Replay length capped byPTERM_HISTORY_REPLAY_LINES(default: unlimited).HELLO+RESIZEin a single write, writesHISTORYpayloads to stdout likeOUTPUT, and prints a one-line notice on protocol mismatch (a daemon that never sendsHELLO_ACKbefore the firstSTATE_SYNCis treated as v0).Backward compatible in both directions: clients or daemons without
HELLOkeep the legacy behavior.Proposals 0003 (daemon handoff) and 0004 (reboot persistence) are recorded as withdrawn.
Test plan
cargo test: 37 + 9 proto tests pass, including new coverage for history content/no-duplication/max_lines/wrapped re-join/altscreen (session), frame orderingHELLO_ACK→HISTORY→STATE_SYNC, once-only history, and legacy-client behavior (server), and hello/hello_ack roundtrips (proto).STATE_SYNCredraw, with no protocol notice and clean detach.🤖 Generated with Claude Code