Repository navigation
UI Consistency: 1 issue found
apps/web/src/components/chat/ComposerTasksBadge.tsx — the new bounded task-list scroll region (max-h-[min(24rem,40dvh)] overflow-y-auto overscroll-contain) is not focusable, so tasks below the cap are reachable only by pointer/wheel. Before this change the full list was laid out; now keyboard-only users lose access to the clipped items. The sibling composer scroller (ComposerPendingApprovalPanel: max-h-20 overflow-auto with tabIndex={0} plus a focus-visible ring) is the established contract in this surface; matching it restores keyboard scrollability. Inline comment posted with a suggested fix.
No other findings: the header ChevronDownIcon (down while the body is open below the header) matches the ComposerPendingUserInputPanel convention, native overflow-y-auto with a max-h cap is the local pattern in chat (no ScrollArea consumers there) and inherits the global scrollbar styling, and the added aria-label on the collapse control is an improvement.
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.
Checks performed:
- Read the full
ComposerTasksBadge.tsxand its test at head; verified new assertions match rendered markup. - Traced the call site in
ChatComposer.tsx: the drawer is a direct child of the composer<form>with no overflow/max-height/flex constraint, so the inner cap is the only height owner and cannot break the drawer surface geometry. - Verified
.chat-composer-top-drawerinapps/web/src/index.css(masked::beforeglass,padding-bottom: var(--chat-composer-attachment-overlap), 16px top radius, theme bridges): the new inner scroll container does not clip or reposition that surface, and the drawer's bottom overlap seam stays intact. - Compared against existing scroll ownership:
apps/web/src/components/ui/scroll-area.tsx(Base UI viewport +virtualized-scroll-fadecontract) is not used anywhere undercomponents/chat; nativemax-h+overflow-autoregions (ComposerPendingApprovalPanel,ComposerCommandMenu,ComposerStashMenu,ModelPickerSidebar) are the local convention, so a native scroller here is not a primitive-ownership violation. No always-on static mask was introduced, and global::-webkit-scrollbarstyling keeps the lane visible. - Checked chevron conventions across
components/chat(ComposerPendingUserInputPanel,MessagesTimeline,ComposerControl) anddvhusage acrossapps/web/srcfor precedent.
Not flagged (aesthetic/optional): absence of an overflow fade on the new scroll region, and the collapsed tab still having no chevron affordance.
🔍 Agent activity — 16 tool calls
1. browse_code — apps/web/src/components/chat/ComposerTasksBadge.tsx
2. browse_code — apps/web/src/components/chat/ComposerTasksBadge.test.tsx
💭 I'm noting that a new scroll region uses raw overflow-y-auto rather than a shared ScrollArea primitive, and I want to check how other drawers in the repo handle scrolling to see if there's a preferred pattern to follow instead.
3. git_tools — chat-composer-top-drawer
💭 I'm noticing the drawer's surface comes from a
::beforepseudo-element withinset: 0and a mask hiding the bottom overlap, plus a matching padding-bottom on the drawer itself. Since the new scrollable region is nested as a child, the drawer's overall height stays bounded and the painted surface should still track correctly. Checking whether scrolled content gets cut off abruptly without a fade — the scroll container's bottom edge sits above the masked overlap area, so that should be fine visually. But I want to verify against the project's rule that repeated overflow fades should reuse the shared virtualized-scroll-fade contract, and whether there's an existing ScrollArea primitive this new scroll region should be using instead of a plain native overflow container. I'm also weighing the arbitrarymax-h-[min(24rem,40dvh)]value against existing tokens, checking if scrollbar-lane opacity and overscroll-contain conventions are respected elsewhere, and confirming the new aria-label is a genuine improvement rather than a regression. Let me look at how ScrollArea and similar scroll regions are implemented elsewhere to compare.
4. git_tools — overflow-y-auto
5. browse_code — apps/web/src/components/ui/*.tsx
💭 I'm noting that native overflow-y-auto is used elsewhere too, so it isn't inherently a violation of the ScrollArea rule. I'm now checking whether the drawer's scroll container conflicts with the painted
::beforesurface that covers the full inset. Rounded corners and scrollbar placement look fine given the pseudo-element handles the visual radius while the content scrolls normally. What stands out more is the chevron: the expanded drawer shows a down-pointing chevron for collapsing, while the collapsed badge tab shows none — I want to check other composer drawers in the repo to confirm this direction convention is consistent.
6. git_tools — Chevron(Up|Down)Icon
7. browse_code — apps/web/src/components/ui/scroll-area.tsx
💭 I notice an inconsistency: the collapsed tab lacks a chevron, whereas the sibling ComposerPendingUserInputPanel uses a rotating chevron to indicate open/collapsed state, with a comment explaining the direction points toward the body. Checking that convention against the tasks drawer confirms ChevronDown is used correctly since the body sits below the header, so this asymmetry (no chevron on the tab) is intentional and already covered by an existing test — not a real issue. Now I'm looking at how the drawer's glass surface handles its overlay styling with
::before,inset: 0, and mask/padding to blend with the composer. The bounded max-height keeps things from breaking, but I want to flag whether the scroll region should be using the shared ScrollArea primitive with its fade treatment instead of a rawoverflow-y-auto, since that would produce a hard-clipped edge without the usual scroll fade or scrollbar styling seen elsewhere. I should check how ScrollArea is used in other composer-attached drawers to see if this is a real inconsistency.
8. git_tools — ScrollArea
💭 Since chat components don't use ScrollArea, native overflow seems to be the convention here. I want to check other composer drawers for existing max-height patterns to see if there's an established token like a fixed dvh value or CSS variable I should follow.
9. git_tools — max-h-
💭 I notice the sibling composer panel scroll region uses tabIndex 0 plus a focus-visible ring, giving keyboard users a way to scroll it — but the new tasks list scroll region lacks that same keyboard accessibility. Another candidate finding is the missing overflow fade, since the repo has a shared virtualized-scroll-fade contract for native overflow fades that this new region doesn't use. I'm also checking whether padding and mask overlap interact badly when the list overflows, but that seems fine on closer inspection. Now I want to check whether other CSS selectors targeting the drawer assume it's non-scrollable, and whether the drawer's parent container imposes any height constraints that could conflict.
10. git_tools — ComposerTasksDrawer
11. git_tools — composer-tasks|composer-task-
💭 I should check where ChatComposer calls this to understand whether the drawer sits inside a container with overflow-hidden or has its own scroll behavior.
12. browse_code — In apps/web/src/components/chat/ChatComposer.tsx, show the JSX where ComposerTasksDrawer is rendered, including the surrounding container elements and their className/style (the drawer slot / stack above the composer). Also describe whether that container has overflow, max-height, or flex constraints, and whether it hosts other drawers like ComposerPendingUserInputPanel or ComposerPendingApprovalPanel.
💭 I'm checking for a visual regression where the drawer's glass overlay masks the bottom edge so the composer surface can overlap it, and tracing whether scrolled content might peek out under the drawer's padding near the bottom of the scroll region. Actually, since
pb-4is padding on the scroll container itself, content correctly scrolls within that padded area with no clipping issue there. The bigger concern is the 40dvh cap on the drawer — since dvh is relative to the full viewport, it could overflow in constrained contexts like a narrow side panel or inline-preview pane where the composer's container is much shorter than the viewport, potentially pushing the composer out of view. But the chat pane usually spans nearly the full viewport height minus the titlebar, so 40dvh combined with the 24rem cap should stay reasonable on desktop. I want to check ifdvhis already used elsewhere in the codebase to confirm this is an established convention rather than a new risk.
13. git_tools — dvh
💭 The dvh usage seems fine as an app-level pattern, and the inline path isn't relevant here. I want to check whether the drawer's scrollable list might show a native scrollbar clashing with its rounded corners, so I should look for shared scrollbar styling like a global
app-scrollbarclass in index.css.
14. git_tools — scrollbar
💭 The global scrollbar styling means native scroll behaves fine visually, but I'm noticing rows will cut off abruptly at the scroll boundary without any fade effect, since the drawer's glass overlay spans the full height while the content clips sharply beneath the header. More importantly, the sibling ComposerPendingApprovalPanel gives its scroll region tabIndex, a focus ring, and an aria-label, while this new tasks region has none of that — meaning keyboard users in this Electron app can't scroll to reach items beyond the visible 24rem, which is a real accessibility gap rather than just an aesthetic nitpick. The chevron's color inheritance seems roughly consistent with other composer panels even without an exact match, so that's not a real issue. I'm also checking the
ml-autoplacement on the chevron relative to the header's flex layout, and it seems to fit fine alongside the dismiss button without conflict. The bigger question is whether the keyboard scrollability concern is severe enough to flag as a failure, so I want to check if there's an established convention elsewhere in the repo—liketabIndex={0}paired with overflow containers—to see how this pattern is normally handled before deciding.
15. git_tools — tabIndex={0}
💭 The sibling ComposerPendingApprovalPanel component sets a good precedent, using scrollable styling with a focus ring and tabIndex plus aria-label. I'll suggest adding tabIndex and a focus-visible ring to the new className on line 206 to preserve keyboard scrollability, matching that approval panel pattern, and provide an inline suggestion covering lines 205-209. Tab focus should still work fine here since the drawer only intercepts pointerdown. I'm confirming this targets the added lines 205-209 in the diff so the suggestion applies cleanly. Given this is a genuine accessibility regression—a scrollable list that's not keyboard reachable—I'll mark the check as failure rather than neutral, then post the review.
16. modify_pr — One finding on the new bounded task list: the clipped region is not keyboard-scrollable. See the inline comment.
Agent Credits: 266 credits