feat(web): add scroll-to-bottom button - #1694
Conversation
There was a problem hiding this comment.
Findings
-
[Major] Retarget the smooth tail jump when content grows —
scrollToBottomdisables auto-follow before issuing a one-time smooth scroll to the content's current bottom. If an assistant message streams or a tool card expands during that animation, the destination becomes stale. The scroll handler ignores the intermediate events whiletailScrollInProgressRefis set, the resize observer cannot follow becauseautoScrollEnabledRefis false, and the view has already switched to tail mode, so the unread control disappears. The viewport can therefore remain permanently behind the live tail. Evidence:web/src/components/AssistantChat/HappyThread.tsx:1130.Suggested fix:
const observer = new ResizeObserver(() => { if (tailScrollInProgressRef.current && !pendingScrollRef.current) { content.scrollIntoView({ block: 'end', behavior: 'smooth' }) } else if ( autoScrollEnabledRef.current && atBottomRef.current && !pendingScrollRef.current ) { scrollToBottomInstant() } // existing coverage handling... })
Summary
Review mode: initial
One Major finding: the smooth jump needs to track layout growth until the real bottom is reached.
Testing
Not run (automation). Add a browser-level regression that starts the jump, grows scrollHeight during the animation without manually moving to the new bottom, and verifies the viewport eventually reaches/follows the new tail.
HAPI Bot
| // instant tail-following disabled until the smooth animation | ||
| // reaches the bottom, otherwise a resize/state update can snap | ||
| // the viewport there before the animation is visible. | ||
| autoScrollEnabledRef.current = false |
There was a problem hiding this comment.
[MAJOR] Retarget the smooth tail jump when content grows
This disables auto-follow before a one-time smooth scroll to the content's current bottom. If streaming text or an expanding tool card increases scrollHeight during the animation, that destination becomes stale. While tailScrollInProgressRef is true, intermediate scroll events are ignored; the resize observer also cannot follow because auto-scroll is false. Since this handler already switches view mode to tail, the unread control disappears and the viewport can remain permanently behind.
Suggested fix:
const observer = new ResizeObserver(() => {
if (tailScrollInProgressRef.current && !pendingScrollRef.current) {
content.scrollIntoView({ block: 'end', behavior: 'smooth' })
} else if (
autoScrollEnabledRef.current
&& atBottomRef.current
&& !pendingScrollRef.current
) {
scrollToBottomInstant()
}
// existing coverage handling...
})Please also cover content growth without manually advancing scrollTop to the new bottom; the current test does that manually, so it cannot catch a stale native smooth-scroll target.
There was a problem hiding this comment.
Findings
- None.
Summary
Review mode: follow-up after new commits
No issues found in the latest full diff. The prior smooth-scroll finding is no longer present: content growth now retargets the active tail jump from the content ResizeObserver (web/src/components/AssistantChat/HappyThread.tsx:1543). Residual risk remains around browser-native smooth-scroll timing under continuous streaming.
Testing
Not run (automation). The added tests cover visibility decisions and verify that resize dispatches a second smooth-scroll request; they do not browser-test that the viewport ultimately reaches the final tail while real content grows.
HAPI Bot
Summary
Validation
bun typecheck— passed for CLI, Web, Hub, and Relay after the review fix.bun run test:web -- src/components/AssistantChat/HappyThread.test.tsx src/components/AssistantChat/HappyThread.mobile-scroll.test.tsx— 40/40 passed after the review fix.pwsh -NoProfile -File .\scripts\Invoke-HapiTaskPlaywright.ps1 -Name scroll-to-bottom-button -Suite Root terminal-wrap-fidelity.spec.ts— 2/2 passed before the review-only smooth-scroll fix; the fix is covered by the focused Web regression test above.bun run build— passed for the Web bundle, embedded Web assets, and Hub bundle after the review fix.bun run test— 2,440/2,467 tests passed before the review-only Web fix. The remaining 27 failures are limited to unrelated Windows path, permission, shell-quoting, and ACP timing suites; the focused Web suite passed after the fix.testpassed. The unrelatedintegrationjob currently fails 4 runner session-management tests incli/src/runner/runner.integration.test.ts; no changed files overlap that failure.ok, the Runner machine was active, and the demo session contained 63 messages including 3 live messages.Related Issues
None.
AI Disclosure
Code and tests were prepared with Codex (GPT-5.6).