Skip to content

fix(pi-tui): keep transcript anchored and render scroll input immediately during streaming - #3162

Open
neptune-constellation wants to merge 1 commit into
MoonshotAI:mainfrom
neptune-constellation:fix/tui-scroll-during-streaming
Open

fix(pi-tui): keep transcript anchored and render scroll input immediately during streaming#3162
neptune-constellation wants to merge 1 commit into
MoonshotAI:mainfrom
neptune-constellation:fix/tui-scroll-during-streaming

Conversation

@neptune-constellation

Copy link
Copy Markdown

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

  • Anchor the transcript ScrollView viewport to the same content when it shrinks mid-turn (older steps folded / old
    turns trimmed), instead of clamping the scroll offset and snapping the view to the top.
  • Route wheel and keyboard scroll through the immediate render path instead of the throttled path, so scrolling stays
    responsive while output is streaming.
  • Add a regression test in packages/pi-tui/test/layout.test.ts.

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue (external PRs: the issue must have a maintainer's /approve).
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset. (Added .changeset/tui-scroll-anchoring.md)
  • Ran gen-docs skill, or this PR needs no doc update.

…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-bot

changeset-bot Bot commented Aug 21, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: c9bd1de

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@moonshot-ai/pi-tui Patch

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

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment on lines +201 to +202
const shrink = previousContentHeight - this.contentHeight;
if (shrink > 0) this.currentScrollTop = Math.max(0, this.currentScrollTop - shrink);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

滚动位置问题

1 participant