Repository navigation
Conversation
The sync store keeps at most 100 messages per session and drops the oldest one whenever a new message arrives (context/sync.tsx). Each drop removes rows from the top of the transcript scrollbox while scrollTop stays put, so a reader scrolled up into history sees the text slide upward on every new assistant message, and once it reaches the bottom sticky scroll re-engages and follows the stream again. Short sessions never hit the cap, which is why the bug only shows up in long agentic runs. keepScrollAnchor() listens for the root's "layout-changed" event, which fires after the new layout is computed but before any renderable reads it. While the scrollbox is not at the bottom it takes the first child that was visible under the old layout and scrolls by the distance that child moved, so the view stays put before the frame is drawn. At the bottom it does nothing and sticky scroll keeps following as before.
Contributor
|
The following comment was made by an LLM, it may be inaccurate: |
Nowaker
added a commit
to Nowaker/opencode
that referenced
this pull request
Oct 4, 2026
…session New feature and session records for 6ff168d, which re-anchors the session transcript after every layout so the 100-message prune no longer slides a scrolled-up view. Upstream PR anomalyco#53219 closes the existing issue anomalyco#41243. The stream-throttle feature gets a re-verified timeline entry. AI-Tool: opencode 1.18.33-vt-60-2fa3363c92 AI-Model: anthropic/claude-opus-5-5 AI-Variant: high AI-Platform: linux AI-Harness: Vibeterm 3ae7f02 AI-Session-ID: ses_ef81ca107ffet5DwnFLaGWlUap
Nowaker
force-pushed
the
fix-scroll-follow
branch
from
October 7, 2026 11:13
ecfa7cb to
556b9e0
Compare
Member
|
This branch has been upgraded to V2. We're no longer taking PRs for V1. If you think this is still relevant, please port it over and open it for V2. — from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊 |
Nowaker
added a commit
to Nowaker/opencode
that referenced
this pull request
Oct 11, 2026
…session New feature and session records for 6ff168d, which re-anchors the session transcript after every layout so the 100-message prune no longer slides a scrolled-up view. Upstream PR anomalyco#53219 closes the existing issue anomalyco#41243. The stream-throttle feature gets a re-verified timeline entry. AI-Tool: opencode 1.18.33-vt-60-2fa3363c92 AI-Model: anthropic/claude-opus-5-5 AI-Variant: high AI-Platform: linux AI-Harness: Vibeterm 3ae7f02 AI-Session-ID: ses_ef81ca107ffet5DwnFLaGWlUap
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.
Note: I'm aware v1 is now the maintenance branch and new features go to v2 only. This fix is here for others who want it on v1. I will submit a v2 version once I've migrated my plugin setup to v2.
Issue for this PR
Closes #41243 (root cause analysis of #29094 / #4196). The earlier fix for it, #41247, was closed by the automated PR cleanup without a review.
Type of change
What does this PR do?
The sync store keeps at most 100 messages per session and drops the oldest one on every new message (
context/sync.tsx). Each drop removes rows above the viewport whilescrollTopstays fixed, so a reader scrolled up in a long session sees the text slide up with every new assistant message. Once it reaches the bottom, sticky scroll re-engages and follows the stream again. Short sessions never hit the cap. That is why the scrollbox looks correct in isolation: sticky scroll itself is fine, as #41243 found.keepScrollAnchor()(inutil/scroll.ts) listens to the root'slayout-changedevent. That event fires after the new layout is computed and before any renderable reads it. When the scrollbox is not at the bottom, it takes the first child that was visible under the old layout and scrolls by the distance that child moved, so the frame is drawn with the view in place. At the bottom it does nothing, and following the stream is unchanged.Compared with #41247, this measures the layout change itself instead of predicting the pruned height from the message list. It needs no
idwrapper on assistant messages, and it covers any other height change above the viewport too.How did you verify your code works?
packages/tui/test/util/scroll.test.tsxrenders a sticky-bottom scrollbox and rotates items the way the transcript does. Scrolled up, the first visible line stays put (item 25). Without the fix it drifts toitem 28after three rotations. At the bottom, new items are still followed.bun typecheckpasses, and the TUI suite passes apart fromDiffViewerFileTree > does not render text markers for highlighted rows, which is flaky under full-suite load and passes alone.Before (
dev), the view slides down the transcript:After, the view holds for 40s while the stream keeps going, and
Endresumes following:In sessions under 100 messages, scrolled-up reading already holds on
devfor wheel, PageUp and line-up. This change leaves that path alone.Screenshots / recordings
Text frames above (tmux
capture-pane).Checklist
This PR is AI generated, but under direct supervision and on request of @Nowaker.