Transcript: opening a line at the very bottom moves only the text above, with no room opening under it

Merged
TE
3d ago
+187-2

Leo, 2026-11-03:

plus like the chatgpt thing / you guys adding fake space or whatever / it grows and shrinks right / i have said / when you expand tool calls at the very bottom / you push the text above upwards / you don't expand down IN THAT CASE

What was wrong

With the transcript at its very bottom, opening a line (a tool group, "Worked for", Show more) pins the scroller to the new end in one layout pass, then slides the whole thread from delta px low back to 0 (beginBottomStackFold, from #29686 and #29857). The slide carried everything: on the first frame the rows under the opened line (the reply, the end of the chat) dropped delta px below their place, while the body showed under the line. Then everything rose back up. It read as expanding down into room that then closed, which is the "fake space" that grows and shrinks.

Fix

The thread slide stays: one compositor animation, same clock and easing, and a late measure still updates it in place. Against it:

  • The rows under the opened line hold their pixels. Each gets a counter-slide (translate, composite: "add") on the same timing, so its net movement is 0 on every frame. The held set is found by geometry: rows whose top did not rise with the stack since the click.
  • What rises is cut at the line those rows hold. A clip-path on the opened row, and on any other rising row that would cross the line, is keyed on the slide's own eased progress (pushUpCut). What opened is revealed from the top while the text above moves up, and nothing of it is ever drawn over the rows under it.

A late measure updates every one of these effects in place. stopBottomStackFold cancels them all. Reduce Motion still applies at once with no animation. Every other case (away from the bottom, closing) is unchanged.

Tests

webviews/test/transcript-expand-at-bottom.test.ts gets a frame-by-frame test for both gallery variants of agent-pane.expand-at-bottom (a tool group, and a long prompt's Show more). It reads every painted frame after the click and checks:

  • the row under the opened line and the last row stay within 1 px;
  • the view stays at its end;
  • the opened row is never drawn past the row under it;
  • the line only moves up.

The pushUpCut keyframes have unit tests in foldAnchor.test.ts.

  • Red at c44586e3 (test only, base App.tsx): filled in below.
  • Green at the head: filled in below.

Observed / Not run

Filled in after the runs.

Spec: leo-workspace design/chat-transcript.md, "Bottom expansion".

Changelog

  • Fixed: Opening a tool call or Show more at the very bottom of a chat now only pushes the text above up; the reply under it no longer drops down and slides back.

Agent session: agent session

🤖 Generated with Claude Code


Autofix with [code]smith
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Fixes opening a tool group or Show more at the very bottom of a transcript: only the text above moves up, instead of the rows under the opened line dropping down and sliding back during the fold.

  • Rows under the opened line now hold their pixels with a counter-slide on the thread's own timing; rows rising with the stack are clipped at the line they hold (pushUpCut).
  • Adds a frame-by-frame test asserting, for both gallery variants, that the rows under the opened line hold within 1 px, the view stays pinned to the end, and nothing of the opened row is drawn over them.