Issue #6385: when a streaming turn settles, the two-render sequence
(keep-open expanded worklog → collapsed worklog) could displace the
reader's viewport because the second render captured its scroll snapshot
from the intermediate expanded state, not from the original live DOM.
Root cause
----------
The STREAM_DONE handler in messages.js:
1. Arms keep-settled-worklog-open token → renderMessages({preserveScroll:true})
→ worklog rendered EXPANDED (height-stable swap preventing shrink jump)
2. Disarms token → _renderMessagesWithScrollSnapshot()
→ This function called _captureMessageScrollSnapshot() which captured
the scroll anchor from the expanded-worklog DOM (step 1 output),
then called renderMessages with the worklog COLLAPSED (keep-open gone),
then tried to restore from the expanded-state snapshot.
The snapshot's semantic anchor (row key, session idx, top offset) was
captured from a DOM where the worklog was expanded. After the collapse
render the worklog is no longer at that position — anchor keys don't
match, the semantic restore fails, and the viewport jumps to a
unrelated scrollTop.
Fix
---
- Capture the scroll snapshot from the LIVE DOM (before any settlement
renders) and pass it as to the second render.
- Modify _renderMessagesWithScrollSnapshot() to accept a pre-captured
snapshot via options._prescrollSnapshot, using it instead of capturing
a fresh one from the current DOM state.
This ensures the collapse render anchors to the content the reader was
actually viewing, not to a stale intermediate expanded-worklog position.
Co-authored-by: webtecnica <webtecnica@users.noreply.github.com>