Repository navigation
Prompt rail: a hover sweep forces fewer layouts; the card's blur follows a move in one measure - #34711
Conversation
…over sweep (red) jsdom has no layout, so the test models it: a write dirties the page and the first rail or card layout read after it is one forced layout. On base each row a sweep reaches forces 4 layouts, and a row it comes back to as many. The test asks for at most 3 on a new row and 1 on a row seen before. Leo-ask: ask-0eea9d95e5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-6db3c1673d18051baad7
…ach row's fit Leo (2026-11-04): "hovering across the session rail gets a bit laggy ... it needs to get faster". Each row a sweep reaches placed the card after the commit (a layout), then fitted it: a computed style and the prompt's rect after the place's write, the reply's rect after lifting its clamp, and the place again after the budget, four forced layouts per row. Now a content change fits once and the fit places the card (no place before it), the place's own reads join the fit's last pass, and the fit remembers its budget by the reply's blocks and the prompt: a row seen before at the same card width writes that budget and reads once. A resize the card's observer sees measures again and replaces what the row remembers. thread-rail-hover-reads: 4 -> 3 forced layouts on a new row, 4 -> 1 on a row seen before. Leo-ask: ask-0eea9d95e5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-6db3c1673d18051baad7
…move costs (red) The rail's preview card moves to the next row by its inline transform. On base each move restarts the follow loop: 4 measures (the move and 3 unchanged frames) per row, so a sweep at a row every 40 ms never lets the loop stop. The test asks for one measure per move, with the hole moved. Leo-ask: ask-0eea9d95e5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-6db3c1673d18051baad7
… follow loop
Leo (2026-11-04): "hover previews kinda lag across me hovering over the
sidebar stuff :(". The rail's card moving to the next row by its inline
transform restarted the loop that follows fades and resizes until three
unchanged frames; a sweep crosses a row every 40 ms, so through it every
frame re-read the card's rect and style and the transcript's rect. A
style change alone now measures on the next frame, once: a transition is
still followed through transitionrun and a resize through the
ResizeObserver, which keep the loop. see-through-blur-follow: 4 -> 1
measures per move.
Leo-ask: ask-0eea9d95e5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-6db3c1673d18051baad7
Every row the pointer crosses renders the tick list, and each drawn row (about 115 on a tall rail) built its aria label again through t(), for the few rows the hover changes. A row whose place, count and mark are unchanged now keeps its label; a language change starts over. The rail test checks the label follows a bookmark on and off. Leo-ask: ask-0eea9d95e5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-6db3c1673d18051baad7
|
Review (subagent claude-opus-5-5 medium): SHIP at 586ef38 Visual verdict: unchanged by this diff (no rendering change; work per row only). Follow-ups:
|
|
cmux status (one comment, edited in place; each line is updated by the job that owns it) Review App of this head (app.zip, kept 1 day)
Gallery before/after for
States
Pick other states with a Passes: CI passes on CI passes on Written by web and size checks: green Shipped in:
|
…over-lag # Conflicts: # webviews/src/agent-session/acpmux/threadMinimap/PreviewCard.tsx
…ommit in a row's turn The scroll pacer runs on the page's clock and its frame sometimes lands inside a row's turn, rendering the card again with the same props and one more place() read. The assertion now takes the median per sweep (1 on a revisited row; base: 4 on every row) and allows one extra read per row, so it no longer flakes on a loaded host. Leo-ask: ask-0eea9d95e5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-6db3c1673d18051baad7
|
Review (subagent claude-opus-5-5 medium): SHIP at 449d336 Visual verdict: unchanged by this diff. Follow-ups:
|
|
Found 2 test failures on Blacksmith runners: Failures
|
…ange Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-6db3c1673d18051baad7
The fit cache was keyed by content and width. A text size or density change while the card showed another row kept the old line budget. The reuse path now reads the prompt's and reply's line heights in its single read pass. Closes #34718. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-6db3c1673d18051baad7
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-6db3c1673d18051baad7
|
Review (subagent claude-opus-5-5 medium): SHIP at 5908868 Delta since the SHIP at 449d336: a remembered card fit is reused only at the same prompt and reply line heights (closes #34718), and feat-cmux-next is merged in. The reuse path still does one read pass after its budget write. Follow-ups:
|
|
Finding outcome: comment-6627112810/F1 filed-follow-up #35239 |
![Fix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/fix-with-codesmith-light-3x.png)
Leo, 2026-11-04:
Leo-ask: ask-0eea9d95e5
The rail's height and the wave's gaps are fixed in #34666. This PR cuts the work done each time the hovered row changes during a sweep, when the row changes about every 40 ms:
PreviewCard.tsx): it reads before it writes, and it remembers each row's fit. Placing and fitting the card used to alternate reads and writes, which forced 4 layouts per row. Now there is one read pass and then one write. A row seen before writes its remembered lines and line height and reads once. That fit is reused only at the same card width and the same type (the prompt's and the reply's computed line heights). So a text size or density change, even while the card showed another row, measures fresh, as do a resize the card's observer catches (a font, an image) and a width change.seeThroughBlur.ts): the card moves through its inline transform. Each move used to restart the blur's follow loop, which ran at least 4 frames of re-measuring every covered element and rewriting the SVG hole filter on the whole transcript. A change to the surface's own style now measures once on the next frame. Transitions, animations and resizes still run the full loop. The Summary card and Session Info share this path.ThreadMinimap.tsxTickList): each drawn row keeps its spoken label while its position, row count and bookmark state don't change. A hover no longer rebuilds about 115 labels to change about 8.Performance
test/thread-rail-hover-reads.test.tsx(jsdom dirty/read model)test/see-through-blur-follow.test.tsbench/thread-rail-hover.bench.ts(#34658);cmux-ciis down until #34673 lands, numbers follow thenNo new timers or observers run on their own. The blur's new style observer is the existing one, split out: it disconnects in the same cleanup, and its single measure is one rAF that is cancelled on teardown. The card's fit cache is a module-level
WeakMapkeyed by each turn's reply blocks, then by the prompt text: an entry goes when its turn's blocks do, and it is shared by every card that shows that turn.Tests
Red first, each before its fix:
bun test test/thread-rail-hover-reads.test.tsx: fails on base (4 forced layouts per row), passes on head (3 new, 1 revisited).bun test test/see-through-blur-follow.test.ts: fails on base ([4,4,4,4]measures per move), passes on head ([1,1,1,1]). The hole still follows the card, and a transition still follows for 3 frames.bun test test/thread-rail-hover-reads.test.tsx("measures again once the text size changed"): fails at 449d336 (the old 20px budget kept), passes on head (31px).test/thread-minimap-rail.test.tsx: the label follows a bookmark on and off.thread-minimap*,thread-rail*,minimap*,chat-minimap*,thread-scroll-map*, glass, Summary andhover-cards-glasspasses.Observed / Not run
vp fmt,vp lintandtscare clean on the changed files.minimap-card-layout,see-through-blur,thread-minimap-motion,session-info-glass); this PR's webview CI runs them. The frame bench is pending as above.Follow-ups
Review follow-ups: #35239.
Changelog
risk:normal
🤖 Generated with Claude Code
Agent session: agent session