Agent chat: an opened tool run fades its top under the summary line while scrolled
Leo: "in that top section fade would be good"
Leo-ask: ask-cbdc0a8879 (sticky header fade, via claude-sr2)
What changed
An opened run of tool calls ("Read files, ran commands ⌄") lists its calls in a box that scrolls once it passes nine rows (.cv-tool-run). The summary line stays put above that box while the calls scroll under it. Before this change, a row scrolled halfway out was cut flat against the summary line: its top half was clipped, right under the header text.
Now the box's top edge fades out while there are rows above it:
ToolRun.tsxattaches the existinguseScrollEdgescallback ref (summary/scrollEdges.ts) to the list. It setsdata-fade-toponly while the list is scrolled down from its start.conversation.css.cv-tool-run[data-fade-top]uses the same technique as the transcript's own top edge (.acpmux-scroll[data-fade-top], also 18px): an alpha mask on the scroller, transparent at the top and solid 18px below. Since nothing is painted over the rows, the fade can't cover the summary line's text or chevron, and it can't catch clicks. Because it is a mask and not a gradient, it works the same in light, dark and glass/translucent themes. The scrollbar lane on the right stays fully drawn. With Reduce Transparency the edge stays plain, as the transcript's does.- No behaviour changes: same markup, same fold, same scrolling.
Builds on this lane's #24050 (useAnchoredCollapse). That PR changes how ToolRun opens and closes but not the list element, so the two merge cleanly in either order.
Before / after
Gallery state agent-pane.transcript / tool-run-scrolled-fade (synthetic fixtures): an 18-call run, opened and scrolled 3.5 rows so the fourth row sits half under the summary line.
- Before/after side by side (merge-base vs this branch): https://cmux-lawrences-mac-mini.tail137216.ts.net:18796/compare/tp-sticky-header-fade/?entry=agent-pane.transcript
- The state with only the gallery entry (no fade), for reference: https://cmux-lawrences-mac-mini.tail137216.ts.net:18796/compare/tp-sticky-header-fade-before/?entry=agent-pane.transcript
Test
webviews/test/tool-run-scroll-fade.test.tsx:
- When a run is opened, its list has no
data-fade-topat the start. Scrolled 3.5 rows it has the mark, and scrolled back to the top the mark is gone. - The fade rule is a mask (
mask-imageand-webkit-mask-image, transparent to#000over 18px). It has no background and no pseudo-element over the rows, so it paints nothing and has nothing to catch the pointer. Reduce Transparency clears the mask.
Observed / Not run
- Observed: the web lint and pre-push gates passed on push. The gallery compare is requested on the fleet gallery host.
- Not run locally:
bun test. cosmic-gray's hook refuses test runs, so the new test runs in CI (cmux-next-web).
No capture: webview-only change; the before/after is the Linux gallery above.
Changelog
- Fixed: In agent chat, an opened tool run's list now fades out under its summary line while scrolled, instead of cutting a row in half against it.
Agent session: cosmic-gray
🤖 Generated with Claude Code
![View with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v3-3x.png)
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Fades the top of an opened tool run's call list while it's scrolled, so a row half scrolled away dissolves under the summary line instead of sitting cut against it.
- The list marks its top edge via the existing
useScrollEdgeshook only while rows lie above it, and an 18px alpha mask (the transcript's own top-fade technique) fades that edge. - Nothing is painted, so the fade covers no text and catches no clicks; it works in light, dark, and glass themes, while Reduce Transparency keeps the edge plain.
- A unit test covers the mark being set and cleared and the mask rule itself; a gallery fixture shows the run scrolled 3.5 rows.