@@ -31,10 +31,11 @@ const FILE_SUBAGENT_ID = 'file'
3131/** Quiet period before the shimmer takes the slot back from streamed output. */
3232const STREAM_IDLE_DELAY_MS = 1_500
3333/**
34- * The one vertical extent (10px gap + 36px row) every tail-region occupant —
35- * shimmer slot, actions row, stopped row — must share. The settle swap is only
36- * jump-free because these are equal; changing one side without the others
37- * reintroduces a scroll clamp at end of turn.
34+ * The vertical extent (10px gap + 36px row) shared by the shimmer slot and the
35+ * actions row that replaces it at settle. The swap is only jump-free because
36+ * these are equal; changing one side without the other reintroduces a scroll
37+ * clamp at end of turn. (A stopped turn's stacked rows are exempt — their
38+ * extra height is glided-in growth, not a swap.)
3839 */
3940const TAIL_REGION_CLASSES = 'mt-[10px] flex h-[36px] items-center'
4041
@@ -982,22 +983,22 @@ function MessageContentInner({
982983 < PendingTagIndicator label = { thinkingLabel ?? 'Thinking…' } />
983984 </ div >
984985 </ div >
985- ) : (
986- // The settled tail takes the slot's place in the SAME render and at the
987- // SAME extent (TAIL_REGION_CLASSES), so the swap is height-neutral by
988- // construction — no reflow for the pinned scroller to absorb. A stopped
989- // turn stacks a second region (status row above the actions); that +46px
990- // is deliberate — the teardown's eased follow glides it into view, and
991- // the stacked layout beats a combined status/actions row visually.
986+ ) : // The settled tail takes the slot's place in the SAME render and at the
987+ // SAME extent (TAIL_REGION_CLASSES), so the swap is height-neutral by
988+ // construction — no reflow for the pinned scroller to absorb. A stopped
989+ // turn instead stacks compact natural rows (10px gaps, no 36px boxes):
990+ // its extra height is glided-in growth either way, so only the
991+ // shimmer-swap occupant needs the fixed extent.
992+ lastSegment ?. type === 'stopped' ? (
992993 < >
993- { lastSegment ?. type === 'stopped' && (
994- < div className = { cn ( TAIL_REGION_CLASSES , 'gap-[8px]' ) } >
995- < CircleStop className = 'size-[16px] flex-shrink-0 text-[var(--text-icon)]' />
996- < span className = 'text-[14px] text-[var(--text-body)]' > Stopped by user</ span >
997- </ div >
998- ) }
999- { actions && < div className = { TAIL_REGION_CLASSES } > { actions } </ div > }
994+ < div className = 'mt-[10px] flex items-center gap-[8px]' >
995+ < CircleStop className = 'size-[16px] flex-shrink-0 text-[var(--text-icon)]' />
996+ < span className = 'text-[14px] text-[var(--text-body)]' > Stopped by user</ span >
997+ </ div >
998+ { actions && < div className = 'mt-[10px]' > { actions } </ div > }
1000999 </ >
1000+ ) : (
1001+ actions && < div className = { TAIL_REGION_CLASSES } > { actions } </ div >
10011002 ) }
10021003 </ div >
10031004 )
0 commit comments