web: Group tool-result resource_links in a scrollable "Resource Links" box with Protocol colors#1686
Conversation
…" box with Protocol colors Closes #1685 - ToolResultPanel: coalesce consecutive `resource_link` blocks into a single bordered, internally-scrollable "Resource Links" box (mirroring the "Messages" box in the Protocol monitoring sidebar). Non-link blocks and non-adjacent runs are preserved in order via `segmentContent`. - ResourceLink: render each link card on the recessed `inset` surface (`Card variant="inset"`), matching ProtocolEntry's colors in light and dark modes; nested read-result Code blocks read as raised on the grey card via the inset cascade variable. - Drop redundant metadata: the resource `description` line (ResourceLinkInfo, and thus ContentViewer/ResourceLink) and the green "Resource:" label above the expanded read result. - Update tests + stories for the removed props/label and the new grouping box; add multi-link and split-run coverage. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RwZGbocZ64yN9bgb2mj1qE
Reverts the description removal from the previous commit per review — the `description` line is retained on ResourceLinkInfo (and its ContentViewer / ResourceLink callers). Only the redundant green "Resource:" label above the expanded read result stays removed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RwZGbocZ64yN9bgb2mj1qE
The `description` is generated by the server and can be misleading — e.g. a blob resource served with a `text/plain` mimeType gets described as a "plaintext resource" even though the payload is a blob. Rather than surface that nonsense text, drop the description line from ResourceLinkInfo (and its ContentViewer / ResourceLink callers) entirely. Reverts the description-retention from the prior commit; the grouped "Resource Links" box and the "Resource:" label removal are unaffected. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RwZGbocZ64yN9bgb2mj1qE
…y toggle, full-height box Follow-up refinements to the Resource Links display: - ResourceLinkInfo: move the URI below the name and add a CopyButton beside it so the URI can be copied. The name + MIME badge (and the optional expand control) sit on the header row; the URI + copy sit on the row below. - ResourceLink: replace the bespoke chevron with the same tooltip'd ExpandToggle used by ProtocolEntry, and animate the read-result panel with Mantine's Collapse (same as ProtocolEntry). The toggle is a sibling of the URI copy button (no card-wide wrapping button) so the two real buttons never nest (axe `nested-interactive`). - ToolResultPanel: when a result contains a Resource Links box, fill the card's height so the box grows into the available space and scrolls internally (pinned "Resource Links" heading), instead of capping at a fixed content height. Plain text/image results keep the scroll-within-card body. - ToolsScreen: give the result card `flex: 1` so it fills the pane, providing the definite height the Resource Links box grows into. - Tests/stories updated for the new layout, the Expand/Collapse toggle labels, the mounted-through-collapse read result, and the full-height box (with a height-bounded decorator on the ResourceLinks story). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RwZGbocZ64yN9bgb2mj1qE
… URI style Bring ResourceLinkInfo closer to the ProtocolEntry message card: - Move the expand/collapse toggle to the second (URI) row, opposite the copy button — mirroring ProtocolEntry, whose toggle sits on the row below the badges. The MIME badge stays on the header row's right, beside the name. - MIME badge: bump to `size="md"` so the lowercase MIME text matches the point size of ProtocolEntry's uppercase method/status badges, and make it a solid dark-blue fill with white text in dark mode (keeping the blue-light tint in light mode) instead of a washed-out translucent chip. - Render the URI like ProtocolEntry/NetworkEntry render URLs — `sm` / `fw: 500` in the default sans-serif face and text color — rather than a blue monospace "link". `monoBreak` is kept only for long-URI wrapping. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RwZGbocZ64yN9bgb2mj1qE
Code-review finding: ToolsScreen gave the result card `flex={1}`
unconditionally, so plain text/image/error results also filled the full pane
height — leaving a tall empty card and a height jump versus the input-form
state. Fill is only needed so a "Resource Links" box can grow and scroll.
Gate the fill on a new `resultHasResourceLinks(result)` helper (extracted to
`toolResultUtils.ts` so the component module keeps exporting only components,
per react-refresh/only-export-components). Non-link results keep their
content-sized card; link results still fill and scroll internally.
Tests: unit tests for the helper (link / text-only / empty / error) and a
ToolsScreen test that a resource-link result renders the Resource Links box
(covering the `flex={1}` branch).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RwZGbocZ64yN9bgb2mj1qE
The error-case fixture in ToolResultPanel.test.tsx wasn't re-formatted after adding the required `name` field, failing CI's `format:check`. No logic change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RwZGbocZ64yN9bgb2mj1qE
Addresses the mixed-content case from the review: a long text block preceding the links would take its full natural height and push the Resource Links box almost entirely off-screen (only the first card peeking at the bottom). In the links-containing result, wrap each non-link block in a ScrollArea.Autosize capped at `mah: 50%` (flex "0 1 auto"), so it scrolls within at most half the card and the links box keeps the rest. A short block still takes only its content height; a result with no links renders non-link blocks uncapped in the outer scroll body as before. Adds a `ResourceLinksWithLongText` story (full-height decorator) exercising the cap. Verified visually: the text scrolls within ~50% and the links box fills the remainder. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RwZGbocZ64yN9bgb2mj1qE
|
@claude review |
|
Claude finished @cliffhall's task in 2m 22s —— View job Review — PR #1686 · Resource Links box
Overall this is a clean, well-commented change. The 1. Stale JSDoc: URI is no longer "monospace, link-styled" (minor, doc)
But the code (and the accurate inline comment at line 52) now renders the URI as 2. Loss of the URI from the expand control's accessible name (a11y consideration)The old control had 3. Dropping
|
…test Review follow-ups on PR #1686: - ExpandToggle: add an optional `ariaLabel` (defaults to the tooltip verb, so ProtocolEntry/NetworkEntry/Task are unchanged) and expose `aria-expanded`. ResourceLink passes a per-resource label ("Expand/Collapse resource <uri>") so multiple link toggles are distinguishable to assistive tech and announce their state — restoring the a11y the card-wide button previously provided, while keeping the visible tooltip a plain "Expand"/"Collapse". - ResourceLinkInfo: fix the stale JSDoc that still described the URI as "monospace, link-styled" — it now renders sans-serif sm/fw:500 default color. - ToolsScreen test: assert the result card actually gets `flex: 1` for a links result and NOT for a plain text result, so the test verifies the fill branch it names rather than only that the heading renders. Tests: ExpandToggle gains ariaLabel + aria-expanded cases; ResourceLink / ToolResultPanel / stories updated for the per-resource toggle name. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RwZGbocZ64yN9bgb2mj1qE
These lock files were touched by a local install in the worktree (dropping the `version` field and adding optional @emnapi platform deps); they are unrelated to this PR. Restore them to their v2/main state. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RwZGbocZ64yN9bgb2mj1qE
|
Thanks for the review — addressed in 1. Stale JSDoc (fixed). Updated the 2. Expand-toggle accessible name / 3. Dropping 4. Per-block 50% cap (accepted edge case). Correct that 5. Weak
|
|
@claude review |
|
Claude finished @cliffhall's task in 1m 56s —— View job Re-review — PR #1686 · Resource Links box
All follow-ups from the earlier review landed cleanly, and I don't see any new issues. Confirming each fix against the current tree: 1. Stale JSDoc (fixed). 2. ExpandToggle accessible name + 3. 4. Per-block 50% cap (accepted edge case). Left as-is; the single-preamble case is satisfied and the comment at 5. I also re-checked the surrounding logic for regressions from the a11y change:
Nothing blocking — this is good to go from my side. Nice, thorough follow-up. |
Closes #1685
What
Tool-result
resource_linkblocks now render inside a labeled, full-height, internally-scrollable "Resource Links" box that closely matches the Protocol message cards (ProtocolEntry) in both light and dark modes.Changes
Grouping & layout (
ToolResultPanel,ToolsScreen)resource_linkblocks are coalesced (viasegmentContent) into one bordered Resource Links box with a pinned heading, mirroring the Messages box (ProtocolListPanel). Non-link blocks and non-adjacent runs are preserved in order.resultHasResourceLinks) and the box grows into the available height and scrolls internally. Plain text/image/error results keep their content-sized card (no tall empty card, no height jump vs the input form).Link card (
ResourceLink,ResourceLinkInfo)Card variant="inset"(--inspector-surface-inset), matchingProtocolEntryin light/dark; nested read-resultCodeblocks read as raised via the inset cascade variable.ProtocolEntry).ExpandToggleasProtocolEntry, with the read-result panel animated by Mantine'sCollapse. The toggle and copy button are sibling real buttons (no card-wide wrapping button) so they never nest (axenested-interactive).ProtocolEntry/NetworkEntryURLs (sm/fw: 500, sans-serif, default color) instead of a blue monospace link.description(e.g. a blob served astext/plaindescribed as a "plaintext resource") and the redundant green "Resource:" label are removed.Review
Ran a
/code-reviewpass and addressed the substantive findings:resultHasResourceLinks.Remaining note: the shared
ExpandToggle's generic "Expand"/"Collapse" label (noaria-expanded) matchesProtocolEntryby request.Screenshots
Tests & stories
ResourceLinkInfo,ResourceLink,ContentViewer,ToolResultPanel, andToolsScreentests/stories for the new layout, the Expand/Collapse toggle, the mounted-through-collapse read result, the grouped full-height box, and the 50%-capped text (ResourceLinksWithLongTextstory).resultHasResourceLinks(link/text/empty/error), the grouped box (single / consecutive / split runs), and theToolsScreenfill branch.test:coverage(unit + integration) passes the per-file ≥90 gate; Storybook play + axe a11y checks pass in headless chromium. Verified visually in light and dark againstProtocolEntry.🤖 Generated with Claude Code