fix(pi-tui): keep transcript anchored and render scroll input immediately during streaming - #3162
Conversation
…tely during streaming Anchor the ScrollView viewport to the same content when it shrinks while the user is scrolled up (folding/trimming older transcript turns), instead of snapping to the top. Route wheel and keyboard scroll through the immediate render path so scrolling stays responsive during streaming.
🦋 Changeset detectedLatest commit: c9bd1de The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c9bd1ded2e
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| const shrink = previousContentHeight - this.contentHeight; | ||
| if (shrink > 0) this.currentScrollTop = Math.max(0, this.currentScrollTop - shrink); |
There was a problem hiding this comment.
Do not shift for shrinkage below the viewport
When a reader has scrolled into an older turn, mergeCurrentTurnSteps() can fold the active turn at the bottom, entirely below the viewport. updateLayout() receives only the total height, so subtracting every decrease from currentScrollTop treats that bottom-only shrink as rows removed above and jumps the reader upward by shrink; the same problem occurs whenever a component below the viewport reflows shorter. Preserve the offset unless removal is known to be above a tracked anchor, or pass positional anchor information into this update.
Useful? React with 👍 / 👎.
| if (remaining !== 0 && !seen.has(primary)) primary.scrollBy(remaining); | ||
| this.updateScrollbarHover(event.x, event.y); | ||
| this.requestRender(); | ||
| this.requestImmediateRender(); |
There was a problem hiding this comment.
Document and guard the new vendored divergence
This changes vendored scrolling behavior, but the package's exhaustive local-divergence list was not updated and the added test covers only height anchoring, not the immediate wheel-render path here. Existing alt-screen tests merely wait for an eventual render, so reverting these calls to throttled requestRender() would still pass; add the divergence entry and a timing/preemption test so the next re-vendor cannot silently drop the fix.
AGENTS.md reference: packages/pi-tui/AGENTS.md:L3-L7
Useful? React with 👍 / 👎.
Related Issue
Resolve #3116
Problem
See #3116. Scrolling the transcript with the mouse wheel during a streaming turn is janky — it lags before the view
moves, and sometimes snaps to the very top.
What changed
ScrollViewviewport to the same content when it shrinks mid-turn (older steps folded / oldturns trimmed), instead of clamping the scroll offset and snapping the view to the top.
responsive while output is streaming.
packages/pi-tui/test/layout.test.ts.Checklist
/approve).gen-changesetsskill, or this PR needs no changeset. (Added.changeset/tui-scroll-anchoring.md)gen-docsskill, or this PR needs no doc update.