tui: render PTY scroll-up from the structured message log#328
Closed
edwin-zvs wants to merge 2 commits into
Closed
tui: render PTY scroll-up from the structured message log#328edwin-zvs wants to merge 2 commits into
edwin-zvs wants to merge 2 commits into
Conversation
Scrolling up an interactive harness session showed a broken history. Codex pins its input box with a DECSTBM scroll region, and vt100 0.16 only saves scrolled-off lines to scrollback when no region is active, so codex's conversation was dropped entirely. Claude sets no region but rewrites lines with cursor-up + a bordered input box, so the viewport-snapshot fallback duplicated answer lines and spliced chrome (spinner, borders) into them. For PTY sessions that emit structured Message/Reasoning events and have no tool blocks, render scroll-up from the message log instead, rebuilt and reflowed to width. The live view stays the faithful PTY; a raw shell (no messages) keeps the snapshot path; tool-block sessions keep replay_full. Fed into both the hydration/replay and live event paths. See specs/0017-pty-scrollback-from-messages.md.
Message text carries bare \n line feeds (codex/claude emit multi-line prose). vt100 treats \n as line-feed only -- down a row, no carriage return -- so each line started where the previous one ended and the whole message staircased to the right. Normalize \n to \r\n in rebuild_shadow_from_messages, matching synth_message on the headless render path. Adds a multi-line regression test.
Contributor
Author
|
Closing — this approach (rendering scroll-up from the structured message log) is a net regression in practice: it shows only the prose messages and drops the tool calls / command output / diffs that make up most of a coding session. The current Pivoting to fixing the scrollback itself: patching the |
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.
Problem
Scrolling up an interactive harness session in the TUI showed a broken history:
vt1000.16 only saves a scrolled-off line to scrollback when no region is active (grid.rs::scroll_up→!scroll_region_active()), so codex's conversation lines are dropped — scrollback is empty, and the viewport-snapshot fallback fragments it (duplicated banner, spliced status, only a few lines recoverable).The web client doesn't have this — xterm.js keeps a real native scrollback for the same byte stream.
Fix
For PTY sessions that emit structured
Message/Reasoningevents and have no tool blocks, render scroll-up from the structured message log — rebuilt and reflowed to the current width. The live view stays the faithful PTY; a raw shell (no messages) keeps the snapshot path; tool-block sessions keepreplay_full. Messages are fed into the shadow on both the hydration/replay and live event paths.Rather than vendor/patch
vt100to match xterm.js's scrollback semantics, this uses the clean, complete, reflowable source the harness already provides.Design rationale:
specs/0017-pty-scrollback-from-messages.md.Evidence
Reproduced claude's break by feeding a real interactive-claude capture through the shadow path:
Tests (224 green):
app::tests::pty_session_scrollback_uses_message_log— full hydration path → scroll-up renders the clean message log (❯prompt, no PTY chrome), and the live view stays the PTY.pty_render::tests::codex_scrollback_renders_clean_message_log— codex scroll-region case.pty_render::tests::claude_style_redraw_scrollback_uses_messages— claude cursor-up redraw case: no chrome, no run-together, all answers scrollable.pty_render::tests::shell_session_without_messages_keeps_natural_scrollback— message-less sessions keep the snapshot path.Binary
Code is entirely in
crates/cli→ the relevant binary isagent(the TUI).agentd/agentd-mcp/agentd-adapter-*build but are unchanged frommain.No live screenshot: interactive sessions in a fresh isolated daemon stall on first-run folder-trust / sandbox prompts that one-shot input can't fully drive. Engagement was confirmed via temporary debug instrumentation (
render_shadow … msg_mode=true) on an interactive codex session, then removed.🤖 Generated with Claude Code