feat(web): cite assistant responses with inline citations - #9146
UI Consistency: 2 open findings, no new issues
No new consistency issues were introduced by the latest commits on this branch. The selection action was migrated to the shared Button primitive (size="xs", variant="glass", pill radius), which matches the existing floating glass pill in ChatView.tsx, so that earlier finding is resolved.
Two previously reported findings are still open and were not re-posted to avoid duplicate comments:
apps/web/src/components/chat/AssistantCitationChip.tsx— the chip label usesCOMPOSER_INLINE_CHIP_LABEL_CLASS_NAME(which includesselect-none) for both the composer and the read-only chat variant, so quoted text drops out of a selection dragged across a sent message. Other chat chips (FileTagChipContent,SkillInlineText) switch toCHAT_INLINE_CHIP_LABEL_CLASS_NAMEin that case.apps/web/src/components/chat/AssistantCitationCommentEditor.tsx— the raw<textarea>reconstructs the sharedTextareaprimitive's geometry and typography without itsaria-invalid, focus, and disabled treatment;DiffCommentAnnotationshows the borderless-inline pattern built on the primitive.
Details
Note
Your check run agent prompt is: .macroscope/check-run-agents/ui-consistency.md
More information about how Check Run Agents work can be found in our Help Center.
Scope reviewed: apps/web/src/**/*.ts, apps/web/src/**/*.tsx, apps/web/src/**/*.css.
Files examined for this run:
components/chat/AssistantSelectionToolbar.tsx(now usesButtonvariant="glass" size="xs", consistent with the jump-to-bottom pill inChatView.tsx;disabledand focus handling preserved)components/chat/AssistantCitationChip.tsx(link restructure into composer/chat variants; label class issue unchanged)components/chat/AssistantCitationCommentEditor.tsx(unchanged since the prior run)components/chat/AssistantCitationSource.tsxandindex.css(@property --assistant-citation-highlight-opacityplus::highlight(...)rules in@layer base; global highlight pseudo-elements are the correct owner, and the JS peak constant now matches the CSS comment highlight)components/chat/MessagesTimeline.tsx(AssistantCitationSourcewrapperdivsits inside a non-flexrelative min-w-0 px-1 py-0.5container, so it is layout-neutral)components/ComposerCitationNode.tsx,components/ChatMarkdown.tsx(chip reuse andt3-citationprotocol allowance; navigation uses the citation's ownenvironmentId/threadId, so no active-environment fallback)
Method: diffed 22c1ce8..393a909 restricted to the citation-related web files to isolate this branch's own changes from the unrelated main merges present in the range, then read the head versions of the new components and the shared primitives they reconstruct (ui/button.tsx, ui/popover.tsx, composerInlineChip.ts).
🔍 Agent activity — 14 tool calls
💭 I want to check the current state of the files at the PR head, especially the ones I flagged earlier, to see if the changes since commit 22c1ce8 (referenced in the maria-rcks comment about refined citation controls) introduced any new issues. I'll look at AssistantCitationChip.tsx, AssistantCitationCommentEditor.tsx, and AssistantSelectionToolbar.tsx as they currently stand, keeping in mind the diff I have is merge-base to head. The toolbar now uses a Button with glass variant instead of MenuItem, so that earlier finding is resolved. The citation chip still applies its label class unconditionally, and the comment editor still uses a raw textarea -- both threads I already flagged with unknown resolution status, so I shouldn't repeat them but should verify if the chip's tooltip behavior changed in response.
1. browse_code — apps/web/src/components/chat/AssistantCitationChip.tsx
2. browse_code — apps/web/src/components/chat/AssistantCitationCommentEditor.tsx
💭 Since the two earlier findings are still unresolved, I won't repost them. I want to check whether new commits since 22c1ce8 introduced fresh UI issues, so I'm comparing the diff against head 393a909 for apps/web—and I notice it already reflects the resolved MenuItem finding with the glass variant Button in AssistantSelectionToolbar, meaning changes have happened since.
3. git_tools — 22c1ce8..393a909
💭 That full diff is picking up unrelated main-branch changes since the branch got rebased or merged. I should narrow this down and diff only the specific web citation files between the two commits to isolate what the PR itself changed.
4. git_tools — apps/web/src/components/chat/AssistantSelectionToolbar.tsx 22c1ce8..393a909
5. git_tools — apps/web/src/components/chat/AssistantCitationChip.tsx 22c1ce8..393a909
💭 I'm noticing AssistantSelectionToolbar now uses a Button with a glass variant at xs size, so I need to verify that variant and size actually exist in the Button primitive. I also want to check how CITATION_ACTION_BUTTON_CLASS_NAME is used now, since it seems limited to the pencil trigger, and whether PopoverTrigger renders its own button styling by default.
6. browse_code — apps/web/src/components/composerInlineChip.ts
7. git_tools — glass
💭 Good, the toolbar now uses the primitive component, confirming my earlier finding. Now I'm scanning the new files in this PR under apps/web/src to check for additional UI issues, focusing on the citation-related components and hooks that were added. I already flagged two findings that remain unaddressed, so I won't repost those. I'm now checking whether the toolbar's className override of rounded-full and padding on the Button primitive is problematic, or whether it's a reasonable one-off pattern for a floating pill-style selection toolbar—I want to see if other glass-variant usages in the repo follow a similar rounded-full pattern to judge consistency.
8. git_tools — variant="glass"
9. browse_code — apps/web/src/components/ui/button.tsx
💭 The toolbar styling lines up with the ChatView jump-to-bottom pill pattern, which is a good sign of consistency. Now I'm scanning the remaining new web UI files for other consistency issues, starting with the citation source component and the CSS highlight additions in index.css around the new
@propertyand::highlight()rules. The highlight opacity value matches the corresponding JS constant with a documented comment, so that's consistent. I'm also checking the citation editor's decorator class usage, whether the PopoverTrigger component applies its own default styling versus relying on the passed className, and confirming other chip components follow the established pattern of plain buttons with the dismiss class name -- I need to check popover.tsx to verify.
10. git_tools — function Popover(Trigger|Popup)
💭 I'm checking the ChatMarkdown changes now — the new citation protocol handling in the sanitize schema and how it renders citation chips, confirming the navigation uses the explicit environmentId scope for routing. Now I'm considering whether wrapping ChatMarkdown in a plain div inside AssistantCitationSource could disrupt layout — if the parent container relies on flex/gap or space-y spacing, that extra wrapper might interfere, so I want to check the surrounding markup in AssistantTimelineRow.
11. git_tools — AssistantCitationSource
💭 Let me check the AssistantTimelineRow region to see how the wrapper div affects its layout.
12. git_tools — function AssistantTimelineRow
💭 I'm checking whether wrapping the content in an extra div breaks any layout assumptions—since the parent uses
min-w-0for truncation, I want to make sure the new wrapper doesn't need that same class to preserve overflow behavior for ChatMarkdown's children. Now I'm scanning other files: the citation rendering logic in ChatMarkdown looks fine, and the anchor sanitization allowing the custom citation protocol is correct. I want to double-check theAssistantCitationChipread-only rendering inside markdown paragraphs, then review the new CSS additions around the citation highlight property and highlight pseudo-selector rules to make sure they're correctly scoped within the layer.
13. browse_code — apps/web/src/index.css
💭 The CSS looks conventional for this repo, and using highlight pseudo-elements without text color seems fine. I'm now checking whether the animated opacity custom property set on the source root element via WAAPI actually gets inherited by the global
::highlight()selector, since highlight styling doesn't follow normal inheritance rules. Per CSS Pseudo-4, highlight pseudo-elements inherit custom properties through a chain of corresponding highlight pseudos rather than from the originating element directly, meaning setting the opacity variable on a mid-tree element likely wouldn't propagate correctly into::highlight()under the standard model. This is a subtle browser semantics question that's risky to flag without verifying actual behavior, and it's more of a functional correctness issue than a UI consistency one. That animation needs@propertyregistration to interpolate the custom property, which they've handled. Checking the remaining web files, I notice the toolbar sets position via inline style while a separate layout effect clamps it imperatively—re-renders could briefly override the clamp, but that's acceptable. I'm also verifying the coarse-pointer hit-target expansion on the toolbar button behaves correctly. The disabled state on the toolbar button when text is too long correctly disables pointer events, matching prior behavior. I want to compare chip removal patterns between citation nodes and file tag chips to confirm consistency—I already flagged the select-none label issue there. The pencil trigger uses Base UI's Popover.Trigger, which defaults to a proper button type, so no issue there. I'm confirming my two previously flagged issues are still unresolved but weren't the target of the recent restructuring, so re-flagging them would be duplicative and should be skipped. Now I want to check whether the more recent commits in scope introduced any new issues by diffing the citation-related and other relevant web files between the earlier commit and head, filtering out unrelated merges.
14. git_tools — apps/web/src/** 22c1ce8..393a909
💭 Most of the rebase changes are unrelated main-branch merges; the citation-relevant edits are the chip link restructure, toolbar Button, and highlight peak adjustment to 0.45, none of which introduce new issues beyond my two existing findings. I'm double-checking the toolbar's role attribute to see if anything new needs flagging there. Checking the AssistantSelectionToolbar's positioning and disabled-state logic confirms nothing new — the style merging through Button's props and the disabled/aria-label behavior both match prior patterns. So I have no new findings, just my two previously-posted ones that remain unresolved since I can't repost them, which raises the question of whether the check should still be marked as failing given those open issues. Since findings do exist, even if already surfaced, I'll mark the check as failure with a summary referencing the two outstanding items rather than duplicating comments — the "All clear" shortcut doesn't apply here since the JSON schema governs the response format. I confirm both prior findings are still valid: the chip label class is still used in both places including the chat variant, and the comment editor textarea is unchanged. My plan is to output a failure state titled around "2 open findings" summarizing both without adding anything new, though I'm still weighing whether "failure" is the right call here.
Agent Credits: 426 credits
Token usage: 22 uncached input · 1,840,289 cache-read input · 462,338 cache-write input · 9,652 output
Agent Credits may also include non-token charges from external tools such as web research.