Agent chat: keep the running line with the resized transcript

Merged
TE
9d ago
+191-5

Leo: "it doesnt shift and resize the same as the other elements on the agent chat area there's not really tha t much to say".

When Session Info is open and a native pane or window changes width, the existing resize observer now puts the transcript, its running line and the composer at their final position before paint. Previously, a second CSS translation moved them for another 180 ms after native geometry had already changed. The observer freezes its resize decision before React can defer the state updater, and the resize-only override targets the actual translated spacer/find and dock children.

The one-frame marker clears on the next animation frame. Resize replacement, shell changes and unmount cancel its pending frame; leaving Session Info or changing shells disconnects the observer. This adds no row scan, work per token, follow-scroll correction, timer, or looping animation.

Reference: cmux design references apps/cmux/live/status-working-timer-and-token-count.png and composer-transcript-bottom-spacing.png. The running line keeps the existing typography and glass; this change only removes a second geometry animation.

Validation

Hosted red→green run, source 1aade6ed0893d72b72155a3c6b2d6e8740722234, snapshot 4717681218a5dee85c7354725d94199fe91e4f5d, tree a855d4b6e9fb7e03d0743c3d3b58cc23ecac328f: SUCCESS. The same browser harness and dependencies run against base 8982de94e7c9b8f31f81550ad339d48d088460a1 and then the head, swapping only the two production inspector files.

MeasurementBaseHead
Chromium / WebKit regressionBoth failBoth pass
Extra motion after resize, 900 px pane111 px0 px
Finite translations on spacer/composer20
First→last painted x, 900 px−21→90 px90→90 px
First→last painted x, 1200 px—114→114 px

The regression samples the real running row and composer for 20 painted frames after each resize, checks the real ResizeObserver marker, and reads transition/animation state from the moved elements. Full hosted typecheck passes (2,859 files). Scoped formatting, lint, browser-lane, fixed-wait and prepush checks pass. Existing web-lint debt is in untouched files (SendScrollSetting gallery type scale, settings formatting, App hook dependencies, generated ACPMUX methods).

Review (Codex gpt-6-astra, xhigh): SHIP at 1aade6ed0893d72b72155a3c6b2d6e8740722234. Independent static review resolved both prior blockers: the deferred functional-updater closure and the formerly vacuous transition selector. Browser results above are separate hosted evidence.

Before / after captures

These are real Playwright recordings from the hosted run, not generated UI. The neutral fixture uses a historical turn timestamp, so its elapsed-time label is intentionally outside this layout fix's scope.

BeforeAfter
Before resize recordingAfter resize recording
Before at 900 pxAfter at 900 px

Changelog

Fixed the running status line and composer taking an extra layout transition after a pane resize.

Agent session: agent session