agent transcript: toggle holds last a fixed minimum, a sideways wheel keeps them, and a stale press is never reused (follow-up to #28780)
Leo's words:
why the f*** did you guys ff***ing ellipsis EVERYTHING WITH NO WAY TO EXPAND WHAT WAS SAID TO SEE
AND IT'S SO F***ING AWKWARD TO SEE THEM THERE AT THE BOTTOM SINCE WHEN I EXPAND THEM IT JUMPS ME DOWN AND WHEN I COLLAPSE IT JUMPS ME UP
#28780 carried this PR's earlier head (5e59e449) to feat-cmux-next: every cut row opens to its whole text, every toggle holds its place, and the collapse room. This PR is now the remainder. It holds the toggle-hold fixes made after that head, merged with the current base. Its diff against base is about 60 lines.
What this changes
- A fixed minimum hold, not one that keeps extending (
foldAnchor.ts). Base extends a hold by 150 ms every time its line moves, up to 1.5 s. While the view was scrolled to a tall prompt, that kept re-placing the prompt under the pointer, and its Show less missed the click (transcript-fold-anchor-browser: "Show less on a prompt several screens tall, with motion off" failed with it). Every hold now lastsmax(foldMs + FOLD_SETTLE_MS, FOLD_HOLD_MIN_MS = 400 ms). A toggle with no fold under Reduce Motion, which used to get 150 ms, is still held while what it opened is measured and placed. - A sideways wheel keeps the hold in both release paths (
App.tsxcancelProgrammatic). Base exempted a horizontal wheel only inrelease. The user-scroll intent listener cleared the hold first, so scrolling a code block sideways still let go. - The press place is never stale (
App.tsx). A keyboard click (detail === 0) does not reuse an earlier, abandoned press, andpointercanceldrops it. The row's own anchored-collapse event (holdAsked) keeps the click's pressed place instead of replacing it with where the line is now. - A file link inside a tool line is not a toggle (
NESTED_CONTROLgains[role="link"], the roleWriteLabel's file name uses). - No dangling
aria-controls(ToolRow.tsx). Since every call opens, an opened call with no output names a body only when one is drawn. DiagramBlock's toggle carriesdata-fold-toggletoo, like Wrap lines and Raw.
Stop and cleanup
Nothing new animates. A hold is a timestamp checked on each placement pass, with no timer. It ends at max(foldMs + FOLD_SETTLE_MS, FOLD_HOLD_MIN_MS) after the click, or at once on a vertical wheel, a key, a touch or a drag. The pointercancel listener is added and removed with the pointerdown and click listeners. Nothing runs per streamed token.
Tests
conversation/foldAnchor.test.ts:- a toggle with no fold is held at least
FOLD_HOLD_MIN_MS - a hold that puts its line back does not outlast its time
- press, click, then the row's anchored-collapse event keeps the pressed place
- a file link inside a tool line is not held
- a toggle with no fold is held at least
conversation/TruncatedRowsReachable.test.tsx: an opened call'saria-controlsnames a body that exists, and a call with no output names none.- Verified with
cmux-cion Linux Chromium:- typecheck,
check:browser-lanes,check:fixed-waits,vp fmt - the acpmux conversation unit suites
- 13 transcript browser suites: fold-keeps-place, fold-anchor-browser, follow-live, reading-place, queue-scroll-bottom, find-position, tool-group scroll, alignment and overlap, no-blank-space, incoming and received message disclosure, transcript-follow
- typecheck,
Media
Linux Chromium gallery, agent-pane.tool-row-column (variant column), with the tool group opened. Captured through cmux-ci using a public gallery fixture. It shows what #28780 shipped and this PR keeps: every call row opens. This PR changes no layout.


Risk
Low. Hold timing only:
- Holds no longer extend while their line moves; they last at least 400 ms instead.
- A sideways wheel no longer releases a hold.
- A file link inside a toggle no longer starts one.
Performance
| metric | before | after | delta | harness |
|---|---|---|---|---|
| work per streamed token in the transcript path | 0 new | 0 new | 0 | code read: the changes run only on clicks, presses, wheel events and placement passes, O(1) each |
Follow-ups from review (not in this PR)
- Fold-room follow release when the transcript is shorter than the view: a no-output toggle can leave room above
rowsEndand stop following. outputSummaryno longer caps text forbriefs,steeranddispatch, not only reports.
Agent session: agent session
š¤ Generated with Claude Code