Skip to content

fix(web): preserve pull request filter interactions

MacroscopeApp / Macroscope - UI Consistency failed Aug 30, 2026 in 3m 31s

UI Consistency: 1 issue found

apps/web/src/components/pullRequest/PullRequestListFilters.tsx — the new submenu triggers (PullRequestFilterRadioSubmenu, PullRequestAuthorFilter, PullRequestLabelFilter) put ml-auto on the trailing value span while MenuSubTrigger already renders its chevron with ms-auto. Two auto main-axis margins split the free space equally, so the current-value text floats mid-row rather than right-aligning next to the chevron, and its position varies row to row. Suggested fix: give the label span flex-1 and drop ml-auto from the value span (posted inline, with the two sibling triggers named).

Previously flagged items that are now resolved: the project label truncation inside the shared radio group, and the Sort trigger's aria-label overriding its visible name.

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.

Files examined: PullRequestListFilters.tsx, PullRequestListFilters.test.tsx, PullRequestRow.tsx, pullRequestList.logic.ts, _chat.pull-requests.tsx, plus ui/menu.tsx, ui/button.tsx, ui/badge.tsx, and pullRequestPresentation.tsx for primitive contracts.

Checked and found acceptable:

  • Filters and Sort triggers now both render through Button variant="outline", so height, radius, focus ring, coarse hit target and --control-icon-color come from the primitive.
  • MenuSubPopup widths (w-80, w-72, min-w-56) satisfy MenuPopup's width-defaulting contract, so min-w-32 is correctly suppressed.
  • PullRequestRowLabels is guarded at the call site, keeping PullRequestMetaLine's separator contract intact; changedLines > 0 matches PullRequestDiffStat's own zero-suppression.
  • Author search input uses InputGroupInput size="compact" rather than overriding the group's height, and keyboard propagation now lets ArrowDown/Escape through to the menu.
  • No environment-scoped action was added to a shared renderer; no CSS/theme or scroll-mask ownership changed.

🔍 Agent activity — 17 tool calls

💭 I'm checking the diff between the merge-base and the current head at fcf21d4, comparing against prior review runs to see if earlier findings were fixed or if new issues appeared.

1. browse_code — apps/web/src/components/pullRequest/PullRequestListFilters.tsx

2. git_tools — 86c9a92..fcf21d4

💭 Let me check the diff from commit fcf21d4 to see exactly what was fixed there.

3. git_tools — fcf21d4

💭 The two prior findings at c7a9a02 look addressed, and the label filter's clear option seems to have been removed intentionally. Now I'm scanning the current head for any new issues, starting with the author filter's onKeyDown handler which now stops propagation for all key events. Digging deeper, ArrowUp/Home/End from the input field still get blocked while only ArrowDown and Escape pass through, though this seems like a minor gap rather than a real regression since focus moves once you enter the list - I'll skip re-flagging this. Next I want to check the MenuSubPopup width classes against MenuPopup's implementation to see if there's a contract mismatch. For the remaining pieces, the Filters trigger button, submenu trigger, avatar sizing, and the count badge all look fine as written. The "Unavailable" text marker replaced an earlier amber pill I'd flagged, so that thread seems resolved. Now I want to check the menu primitives and other files for any new issues, starting with the pull requests view file. I'm looking at the outlined filter menu variant, which conditionally renders a Button when outlined mode is active and leaves className undefined otherwise—this seems to address the earlier finding, but I need to verify whether the icon still renders correctly in that path, so I'll pull up that function directly.

4. browse_code — apps/web/src/components/ui/menu.tsx

5. browse_code — apps/web/src/routes/_chat.pull-requests.tsx

💭 Looking at the PullRequestFilterRadioSubmenu component, I notice a potential layout issue: both the label span and the chevron icon have auto-margin classes (ml-auto and ms-auto respectively), which could cause conflicting spacing behavior in the submenu trigger. I want to check how other MenuSubTrigger usages in the repo handle this pattern to see if it's consistent, and also verify the avatar sizing inside MenuRadioItem for PullRequestActorAvatar and the corresponding setup in PullRequestAuthorFilter. The value comparison in PullRequestAuthorFilter uses exact string matching on actor.login against filters.author, which could have case mismatches but seems like a minor logic issue rather than a UI concern. I'm also noting the disabled empty-state menu items look fine, and the count badge and Button styling seem okay too. I want to zero in on the ml-auto/ms-auto conflict since it's a genuine new visual issue appearing in three places — the radio submenu, author filter, and label filter — so I should verify how other places in the codebase handle this same trigger pattern.

6. git_tools — MenuSubTrigger

💭 I'm noticing there's no existing pattern for trailing value text in MenuSubTrigger, and the double auto-margin between the value and chevron creates a gap so the value doesn't sit flush against the chevron. With MenuPopup's min-width of 18rem and typically short content, that free space becomes a real layout inconsistency worth flagging. The cleanest fix is giving the label span flex-1 so it absorbs all free space, leaving zero for the auto margins and pulling the value right up against the chevron — a self-contained fix applicable to each trigger row. Confirming this is a genuine bug introduced by the PR: with two auto margins and any leftover free space (even after gap-2), the value text floats mid-row with inconsistent spacing to the chevron across rows, which is worth flagging as new. I'm also checking truncate with max-w-32 works fine since a fixed max-width satisfies truncate's requirements. Now I want to look at other potential issues nearby: whether PullRequestActorAvatar in the author submenu gets a default size since the SVG-sizing selector wouldn't apply to an img element, and how the checkbox item's grid layout with col-start-2 and nested flex wrapper handles alignment for PullRequestLabelFilter. I'm now tracing whether the label text can actually truncate given the grid structure — since a 1fr track defaults to minmax(auto, 1fr) and the grid item has no explicit min-w-0, the track's minimum content size could force the popup to overflow rather than truncate, unlike the author's MenuRadioItem row where an explicit min-w-0 flex-1 wrapper handles it correctly. I'm weighing whether this potential label-overflow issue is significant enough to flag. Checking whether the grid's 1fr track would actually truncate — min-content sizing would fall back to the longest word, and label names are typically short single words anyway, so this seems too speculative to flag. Moving on, the labels chip duplication issue in PullRequestRow was already flagged at 7589c7. Looking at PullRequestRowLabels now, I see it no longer renders a dot at all, so the labelDotColor concern is moot. Next I want to check whether the filterCount badge styling duplicates an existing Badge primitive in the components/ui folder, since that could indicate a locally reconstructed pattern worth flagging. I'm also noting that ActFilterMenu's outline button trigger overrides the chevron's color via a muted-foreground class rather than the control-icon-color token, though it's a minor stylistic inconsistency, and the aria-label conditional logic there looks correctly handled. Now I want to check the Badge primitive and PullRequestActorAvatar next.

7. browse_code — apps/web/src/components/ui/*.tsx

8. git_tools — export function PullRequestActorAvatar

💭 I notice the filter count pill in the Filters trigger button is hand-rolled with its own styling rather than using the Badge primitive—worth flagging as a reconstructed component if that pattern isn't used consistently elsewhere.

9. browse_code — apps/web/src/components/ui/badge.tsx

10. git_tools — rounded-full bg-primary/1[05]

💭 I'm weighing whether the count pill's custom rounded-full styling counts as a local reconstruction of Badge, since it deviates from Badge's default rounded-sm treatment—this feels like a borderline case rather than a clear-cut finding. I'll check whether other count indicators in the app use Badge already, but since I already have a solid auto-margin finding, I'll move on to reviewing PullRequestRow and the route file for stronger issues instead of chasing this weaker one.

11. browse_code — apps/web/src/components/pullRequest/PullRequestRow.tsx

💭 I'm checking whether the diff stat gating on changedLines > 0 duplicates logic that PullRequestDiffStat already handles internally—if it already returns null for zero changes, the extra check might be redundant but harmless.

12. git_tools — export function PullRequestDiffStat

💭 I'm looking at the row layout with the line count and diff stat right-aligned in the same span, deciding that duplication there is just aesthetic and not worth fixing. Now I want to check the route file changes near the displayGroups logic and sort menu header placement, so I'll look at those sections of the code again.

13. browse_code — apps/web/src/routes/_chat.pull-requests.tsx

14. browse_code — apps/web/src/routes/_chat.pull-requests.tsx

💭 I'm checking whether the sort and filters buttons have shrink-0 or whitespace-nowrap so they don't get squeezed or wrap awkwardly next to the flexible search input in that row.

15. browse_code — apps/web/src/components/ui/button.tsx

💭 I'm checking that the sort and filter buttons stay consistent, confirming the icon color routing works correctly since the chevron already has its own text class, so it won't inherit the control icon color override. The size difference between the chevron and filter icon feels like a minor aesthetic mismatch rather than a real bug, so I'll set that aside and focus on the stronger finding around the double auto-margin in the menu sub-trigger value labels — verifying the flexbox spec's behavior around auto margins consuming free space to make sure my reasoning about that bug holds up. Confirming the spec detail, free space gets split equally between two auto margins on the same axis. That means in the sub-trigger row, the value span and the chevron each grab half the leftover space, so the value text lands at some midpoint rather than being right-aligned against the chevron — and since label/value lengths differ across the eight menu rows (State, Involvement, Author, Labels, Draft, Review, Checks, Project), the values end up jagged instead of forming a clean right-aligned column. I'm now checking whether there's actually enough free space in the popup's fixed width to produce this visible effect. Estimating box widths: subtracting icon, gaps, text, and chevron sizes from the ~280px content area leaves roughly 155px of free space, split into ~77px auto margins — plenty to visibly float the value text away from the chevron rather than sitting snug against it. That confirms this is a real, noticeable bug rather than a rounding error. The fix is to make the label span absorb the free space with flex-1 instead of relying on ml-auto, so the value stays anchored next to the chevron; I'm drafting the concrete JSX patch for the affected component now. Writing JSX patch... The same pattern applies to two other spots in the file, so I'm deciding whether to post one comment covering all three occurrences with inline suggestions or split them into separate comments — leaning toward a single consolidated comment referencing all three line ranges. I'm also reconsidering the author submenu keyboard handler, which blocks most keys except ArrowDown and Escape from propagating — that seems too aggressive since it would also block Home/End/Enter from reaching the menu, and I need to check whether that's actually the intended behavior. The nested flex spans there resolve fine since the inner container fills its wrapper. I'm now checking whether other consumers of MenuCheckboxItem handle truncation consistently, particularly around the col-start-2 grid area and whether a min-w-0 is needed there too.

16. git_tools — MenuCheckboxItem

💭 This is the only consumer of MenuCheckboxItem so truncation risk is low, and I'll go with the single auto-margin finding as the failure state. I need to anchor the review comment on the added lines around 219-223 in the diff's right side. For the fix, I'm simplifying the label span to just flex-1 and removing ml-auto from the value span while keeping the truncate and max-width styling. Rather than posting three separate comments for the shared submenu and the two other triggers at lines 264 and 327, I'll post one comment with the suggestion and note that the same change applies to those other lines too.

17. modify_pr — One layout finding on the new filter submenu triggers.


Agent Credits: 120 credits

Token usage: 26 uncached input · 873,218 cache-read input · 63,357 cache-write input · 12,355 output
Agent Credits may also include non-token charges from external tools such as web research.