Repository navigation
UI Consistency: 3 issues found
Reviewed the changed web UI surfaces (ComputerHistorySettings.tsx, ComputerUseSettings.tsx, ComputerUseMoreBrowsers.tsx, browserBrandIcons.tsx, settingsLayout.tsx, settingsSearch.ts, ComposerPendingApprovalPanel.tsx, MessagesTimeline.tsx). Three consistency issues found, all in apps/web/src/components/settings/ComputerHistorySettings.tsx:
- L433-L453 (and L487-L499) — The
Clear 10 min / hour / day / allactions and the per-itemDeletepermanently remove events and derived memories but use the neutraloutline/ghostvariants with no confirmation. Settings elsewhere usedestructive-outlinefor irreversible removals and confirm through the sharedAlertDialog(ConnectionsSettings,ProjectSettingsPanel,ThemeSettings). - L389-L417 — The exclusions reset is rendered in an ad-hoc right-aligned
divbelow the row instead ofSettingsRow'sresetActionslot, which every other reset in settings uses; this relocates the affordance and re-implements the row padding. - L384 (and L420) —
{...searchableSetting(...)}is spread intoSettingsSectionand itstitleis then overridden, so the catalog title is discarded and the search label drifts from the visible heading. The existing pattern for an intentionally different heading isid={searchableSetting("...").id}(seeSourceControlSettings).
Inline comments with suggested fixes were posted.
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.
Previously flagged issues that are resolved in this revision and were not re-reported:
- Escape in the inline exclusion editor now calls
preventDefault()+stopPropagation()so it no longer dismisses the surrounding privacy dialog (L96-L103). - The
Mirror to Codex skysightswitch now carriesdisabled={!onDesktop}, matching its sibling switches and the PrivacyManagebutton (L360). - The removable exclusion entry is now a plain list row instead of a
Badgeoverridden withh-auto px-2 py-1 font-normal text-left(L129-L139). - The duplicated local
RowTitledefinitions were consolidated into the exportedSettingRowTitleinsettingsLayout.tsx, alongside the new sharedSettingIconAction(which correctly replaces the repeatedsize="icon-micro" variant="ghost-muted"call sites).
Other areas checked and found acceptable:
browserBrandIcons.tsxrenders brand artwork as<img>image targets, not a reconstruction of a core primitive.ExtensionStatusis a local inline status label; it is not a duplicate ofConnectionStatusDot(different geometry and no ping/tooltip contract) and uses the sharedbg-success/bg-warningtokens.ComputerUseMoreBrowserscomposesCollapsible+SettingsRowchildren correctly;aria-controlsmatches the panel id.PrivacyExclusionListuses the coreInputandButtonprimitives with preserved disabled/focus behavior.- No CSS/Tailwind ownership, theme-variant, scroll-mask, or virtualized-list changes are present in this PR; class-ordering differences in the new files are cosmetic and were not reported.
🔍 Agent activity — 1 tool call
💭 I'm examining the PR diff to understand what changes were made. This PR is massive, so I'm narrowing my focus to the apps/web/src directory. I need to check if previous comments on ComputerHistorySettings.tsx around lines 101 and 354 were actually resolved, and whether the new changes introduce any additional issues. Let me pull up the list of modified web files to see what I'm working with. The earlier fixes are in place—preventDefault and stopPropagation are now on line 101, the mirrorToCodex switch has the disabled condition, the badge is simplified to a plain row, and RowTitle got consolidated into SettingRowTitle. Now I'm checking the current state of the changed web files for any remaining issues, starting with ComputerHistorySettings.tsx to verify the rem values. I also need to verify that ComputerUseSettings.tsx is using SettingsRow props correctly (status and children), check if ExtensionStatus is duplicated, and confirm those bg-success and bg-warning classes exist. ComputerUseMoreBrowsers.tsx uses SettingsRow with children, so I need to confirm SettingsRow actually accepts children as a prop. The browserBrandIcons.tsx file looks fine with its img elements. Let me pull up settingsLayout.tsx to review SettingIconAction and SettingRowTitle. Looking at the ComputerHistorySettings and ComputerUseSettings files to understand how they're structured, and checking how the
searchableSettinghelper works—it spreads the id and title, though title can be overridden in specific sections. I'm starting to identify potential consistency issues in how these settings are organized. Now examining the button states and disabled conditions across both files—the timeline and clear buttons usevariant="ghost" size="sm"but aren't gated by!onDesktopeven though they only appear on desktop anyway. The "Recorder status" refresh button hasdisabled={busy}but not the desktop check since the status itself is desktop-only. The History section uses a custom flex layout instead of SettingsRow for the clear buttons, which is acceptable but worth noting. The PrivacyExclusionList uses the core Input primitive with SettingIconAction for removal, which looks good. I need to verify whether the design tokens likebg-success,bg-warning, andtext-destructiveactually exist in the system, and check what Button variants are available. I'm noticing thatExtensionStatusin ComputerUseSettings is creating a status dot with the same styling pattern as the existingConnectionStatusDotcomponent—using a small rounded circle with success or warning background colors. Let me check if this is duplicating an existing primitive that should be reused instead. ExtensionStatus looks like a minor duplicate—it's just a small inline status label with slightly different sizing than what's already in the codebase. The settings pages already handle status dots in various ways through providerStatus.ts, so I should check if there's an existing settings component that ExtensionStatus is redundantly recreating. Looking at ComputerHistorySettings and ComputerUseSettings, I'm noticing that the "Reveal" and "Delete" buttons in the History section use a ghost variant but aren't being disabled when!onDesktop || busy, whereas the clear buttons in the same section properly handle this condition — that's an inconsistency worth flagging. I'm also checking whether the Input component actually supports theonValueChangeprop that's being used, and examining the ComputerUseMoreBrowsers collapsible setup where there's a potential issue with aria-controls — the trigger is manually setting aria-controls to a custom panel id, but Base UI's Collapsible already manages this internally, so passing an explicit id to the panel could cause the trigger's aria-controls to point to the wrong element. Looking at how Base UI's Collapsible.Panel handles IDs — it usesuseBaseUiIdto generate or register the panel ID, and the Trigger automatically setsaria-controlsto that ID. So if I pass an explicit id prop, the aria-controls attribute ends up pointing to the same value anyway, making an explicit aria-controls declaration redundant but harmless. The CollapsibleTrigger's className merges with the Button render prop through Base UI's className merging, so that works fine. I should check if other settings components use Collapsible the same way for consistency, though it's not critical. Now I need to look at how the Input primitive handles onValueChange. Let me pull up the actual ComputerHistorySettings.tsx and ComputerUseSettings.tsx files to see what's really there, since the diff output seems truncated even though it claims to show 521 lines. I'm spotting a couple more issues here. The Delete button in the history list is usingvariant="ghost"for a destructive action, but the repo convention seems to call forvariant="ghost-destructive"or something similar for those kinds of actions. I should verify what button variants are actually available. There's also a prop spreading issue whereSettingsSectionspreads thetitlefromsearchableSettingand then immediately overrides it. I see thatsearchableSettingreturns the item's own id rather than the targetId, and search navigation usestargetId ?? idas the fallback. For "computer-history-enabled", the targetId points to the "computer-history" section, so the pulse focuses the entire section rather than just the row itself—similar to how "color-scheme" works, though here the row has its own matching id that would be the more natural target. Looking at the other items: "computer-history-privacy" and "computer-history-timeline" both use targetIds that match their section ids, which is fine. The Computer Use items mostly work correctly—"computer-use-enabled" and the browser/agent-cursor variants all have matching ids. But there's a potential issue with "computer-use-accessibility" and "computer-use-screen-recording": these rows only render when permissions exist and the user is on desktop, yet the search items exist regardless, so jumping to them fails silently when off-desktop. The entire Permissions section itself is also desktop-only, creating an inconsistency where search can reference items that don't exist in the UI. Now I'm checking whether this is actually a violation by looking at how other settings pages handle section-level ids and shared description components. I want to see if there's a pattern likeSettingsSectionDescriptionthat ComputerHistorySettings should be using instead of inline styled paragraphs. I'm noticing the class ordering is inconsistent across the codebase — some components follow a sorted convention while ComputerHistorySettings uses a different order, though this appears to be a harmless inconsistency that shouldn't cause failures. Now I'm wondering if there's a shared component pattern for description text in settings pages, so I'm checking how other settings files like ConnectionsSettings or GeneralSettings structure their descriptive paragraphs to see if there's a reusable pattern I should follow. Now I'm checking the Button primitive to see what variants and sizes are available, particularly looking at whether the "ghost" Delete styling is consistent across the design system and if there's a destructive ghost variant already being used elsewhere for delete actions in settings. Looking at the ComputerUseSettings.tsx file to understand its structure and implementation. I'm noticing an inconsistency in how the master toggles are handled across these settings components. The Computer Use settings allow the main switch to remain enabled even when not on desktop, despite showing a message about remote environments, while the Computer History settings actually disable that same toggle when!onDesktop. Since desktop control settings are persisted server-side and might apply on the host machine, there could be a deliberate reason for keeping the Computer Use toggle editable remotely, but it's creating an odd asymmetry between the two components. Looking at the browsing icons now, I see slight size inconsistencies — the agent cursor icon usessize-6while the browser icons usesize-5. Also checking accessibility: the decorative images inbrowserBrandIconshave empty alt text which is correct, and the icon placement inSettingRowTitlewithin the heading looks fine. For theComputerUseMoreBrowserssection, I'm examining how theSettingsRowsits inside theCollapsibleand whether the aria-controls attribute is being set correctly — theCollapsibleTriggerexplicitly setsaria-controls="computer-use-more-browsers", but I need to verify if the base UI's Collapsible.Panel is generating its own id properly or if there's a mismatch. I'm noticing a discrepancy between what the diff showed and what's actually at HEAD — the diff indicated ComputerUseSettings was importing and rendering a separate ComputerUseMoreBrowsers component, but the grep at the same commit shows the "more browsers" Collapsible is actually inlined directly in ComputerUseSettings around lines 299-341, so either the diff I'm looking at is stale or there's something off with the comparison. I'm realizing the git_diff and git_grep might be pulling from different revisions or there's a caching issue. Both commands should be using the same commit (7507596), but the imports don't match up — the diff shows a ComputerUseMoreBrowsers import while grep shows a Collapsible import at line 32. Let me view the full file from lines 1-40 and 280-360 to see what's actually there. The git_grep results were pulling from an older revision since the grep tool defaulted to the clone commit rather than the URL ref I passed. My earlier grep searches for things like bg-success might be affected by the same issue, though the ComputerUseSettings.tsx match at lines 60-62 appears consistent with the current head. The inline collapsible component in ComputerUseSettings was extracted to ComputerUseMoreBrowsers.tsx at head, which explains the discrepancy. I need to be more careful about which revision the grep is actually searching — the workspace clone should be at the PR head (7507596), but the grep output showing line 32 for the collapsible import contradicts what I'm seeing in the current view. Let me re-run git_grep for ComputerUseMoreBrowsers to verify whether the file exists in grep's view. Passing the revision explicitly fixes the issue since earlier greps were defaulting to an older commit. Now I'm checking the rest of ComputerUseSettings from lines 198 to 380 at the current head. Looking at the ComputerUseMoreBrowsers component at the current version to see how it's structured with SettingsRow and the CollapsiblePanel children, and checking if there are any issues with the implementation. I'm checking whether theMore browsersrow's collapsible needs to be gated ondesktop.enabled, but since it's just instructions, it should be fine. For thearia-controlsattribute pointing tocomputer-use-more-browsers, I need to verify how Base UI's Collapsible.Trigger and Panel work together — specifically whether the Panel accepts anidprop that gets passed through context so the trigger's aria-controls matches automatically. Either way the manual attribute resolves correctly: if Base UI uses the passed id, it's redundant but harmless; if Base UI generates its own id, the spread props ensure the manual aria-controls points to the actual DOM element. When the panel is closed and unmounted, aria-controls pointing to a nonexistent element is standard Base UI behavior, so that's not a concern. ThebrowserBrandIconsusing<img>elements for brand icons is reasonable and doesn't violate the rule against flagging raw elements for image targets. Looking back at the prior findings — the Badge misuse is fixed, the RowTitle duplication is resolved through SettingRowTitle in settingsLayout — so I should check what's changed since the last review to identify any new issues introduced. Since the branch was force-pushed, I need to review the current head from scratch. Looking at the diff, I'm checking for any web-related changes I might have missed across the various files that were modified—assets, component files like ComposerPendingApprovalPanel and MessagesTimeline, settings-related components, and browser configuration files. The path-filtered diff appears complete and accurate based on the commit range, so I can trust what it showed. For MessagesTimeline, the change adds a ShieldIcon and maps "shield" as an icon name, with "wrench" returned for tool work entries. Now I need to examine ComposerPendingApprovalPanel more closely to see if the label additions interact with any color or tone handling based on requestKind that might be inconsistent elsewhere in the component. Checking whether that uppercase pending approval span is new to this change—looking at the merge base, it was already there, so not in scope. The overflow-auto class is also pre-existing. Now I'm comparing the new settings pages against existing ones to spot any UI consistency issues. Looking at how other settings pages handle list rows and actions, I notice ComputerHistorySettings uses custom<li>elements with truncate and ghost buttons instead of the standardSettingsRowcomponent, though that's acceptable since it's displaying data rather than settings. I'm also checking what button variant is typically used for destructive actions in settings lists—I seedestructive-outlineexists in the repo, so I need to verify whether theDeletebuttons withvariant="ghost"match the pattern used elsewhere like in ConnectionsSettings. I'm noticing a consistency issue with destructive actions across the settings. The ComputerHistorySettings component uses plain outline or ghost variants for "Delete" and "Clear all" actions, but if the codebase convention is to use adestructive-outlinevariant for irreversible delete operations, then these buttons should follow that same pattern to maintain consistency. I'm noticing the Computer History page introduces a pattern inconsistency—it uses neutraloutline/ghostbuttons for destructive actions like "Clear all" and "Delete," while the rest of the codebase consistently appliesdestructive-outlinefor similar operations like revoke and delete. This creates a real divergence in how destructive controls are styled, and I'm wondering if this falls under the scope of the variant consistency check. I'd flag this as a single comment on the Clear buttons block, mentioning the Delete action too, with moderate confidence since the destructive variant already exists and serves a purpose. There's also a secondary UX pattern worth noting—destructive settings actions elsewhere typically trigger a confirmation dialog, but "Clear all" and "Delete" here fire immediately. That's more of a UX concern than a UI consistency issue, though I should check if the repo has an established AlertDialog pattern for destructive settings to see if that's worth mentioning alongside the variant inconsistency. I'm noticing the codebase follows a consistent pattern where destructive actions like removing themes or environments trigger anAlertDialogwith a destructive-styled confirm button. Let me check how ThemeSettings implements this confirmation flow around lines 992-1003. I've identified a key inconsistency: the ComputerHistorySettings component uses neutral button variants for destructive actions like clearing history and deleting individual items, but these operations lack confirmation dialogs and don't follow the established pattern of usingvariant="destructive"with AlertDialog for irreversible data removal. The minimal fix is to applyvariant="destructive-outline"to the trigger buttons for clarity, then route the irreversible "Clear all" and "Delete" actions through the shared AlertDialog component like ThemeSettings and ConnectionsSettings do. I'll suggest the variant change inline and note the confirmation dialog as the follow-up for truly irreversible operations. I'm also checking other potential issues: the PrivacyExclusionList uses a plain div row which is intentional and acceptable, the panel styling is fine, and I'm examining how SettingResetButton is positioned in the Privacy reset section. There's a real ownership divergence here — the SettingsRow component has a dedicatedresetActionslot that reserves space next to the title, and every other settings page uses it, but this PR places the exclusions reset in a custom flex div below the row instead, which misaligns the affordance and duplicates padding. The fix is straightforward: pass the reset as theresetActionprop on the "Excluded apps & websites" row where it belongs. Let me verify whether any other settings pages bypass this slot to confirm this is actually a deviation from the established pattern. I'm noticing that mostSettingResetButtoncomponents are placed in eitherresetActionslots within rows orheaderActionslots in sections, but the ComputerHistorySettings exclusions reset is an outlier—it's positioned in a standalone right-aligned div instead of following this pattern, which suggests it should be refactored to use the row'sresetActionslot like the others. That's the second concrete finding. For the first one, I identified that the destructive variant for Clear/Delete actions needs attention. Looking at a third potential issue: the SettingsSection is spreadingsearchableSetting("computer-history-privacy")and then overriding its title withtitle="Privacy", which creates a mismatch—the search catalog shows "Computer History privacy" but the rendered heading displays just "Privacy". The same problem occurs with "computer-history-timeline" showing as "History" in the UI while appearing as "Computer History timeline" in search results. This inconsistency undermines the catalog's purpose as the single source of truth for both anchor IDs and visible titles. The cleanest fix would be to explicitly useid={searchableSetting("computer-history-privacy").id}withtitle="Privacy"to make the override intentional, though the catalog title would still diverge from what users see. Spreading the object and then overriding a property is dead code that masks this drift—worth flagging as a documentation or design issue. I'm weighing whether to include this as a lower-severity consistency note on lines 384 and 420, but I already have two solid findings that will fail the check. The first one is strong: the Clear buttons are genuinely destructive (they delete events and memories) yet lack the destructive-outline styling and confirmation dialog that the repo convention requires. The per-item Delete buttons also usevariant="ghost"inconsistently with that pattern. I'm deciding between posting separate inline comments for the Clear buttons and Delete button, or combining them. To keep noise down while staying precise, I'll post one comment on the Clear button block around line 437 that references the Delete button issue at 487-499, then maybe add the search-title consistency note as a third comment if it seems worth flagging. Now I'm looking at two specific issues: the Clear and Delete buttons useoutlineandghostrespectively instead of following the destructive pattern seen elsewhere (like in ConnectionsSettings or ThemeSettings withdestructive-outlineplus AlertDialog), and the reset button is placed in an ad-hoc div rather than using the SettingsRow'sresetActionslot. For the second issue, a suggestion would need to span lines 389-417 to restructure how the reset button is positioned. Writing the refactored component... Verifying the indentation for the suggestion on line 435... Writing the replacement code... I'm noticing the PR uses a spread-then-override pattern with{...searchableSetting(...)} title="Privacy"that diverges from the established convention in the codebase, which explicitly usesid={searchableSetting("x").id}alongside the title. This approach silently discards the catalog title, which is worth flagging as a minor consistency issue. I'll add a third comment suggesting the explicit.idpattern for line 384, keeping it brief since the first two comments cover the main concerns. Before finalizing, I'm double-checking that spreading the title prop into SettingsSection and overriding it doesn't cause TypeScript errors—it shouldn't—and verifying that the "computer-history-enabled" spread at line 321 is actually fine since the catalog title matches the intended visible title there. For the first finding about the Clear buttons, I'm reconsidering whether the neutral styling was intentional given the four buttons in a row, but "Clear all" is definitely an irreversible action that warrants destructive styling. I'll suggest at minimum thedestructive-outlinevariant and an AlertDialog confirmation, consistent with how ThemeSettings and ConnectionsSettings handle deletions. The inline suggestion for the variant will apply to all four buttons in the map, which is the desired effect. Now I'm drafting the review comments. The first one addresses the destructive actions needing better visual signaling and confirmation dialogs. The second comment covers the reset button placement in the exclusions row, and the third is about spread/override behavior. I'm preparing the exact suggestion text with proper indentation for the multi-line comment spanning lines 389-417.
1. modify_pr — UI consistency review of the new Computer Use / Computer History settings surfaces. The earlier findings (Escape handling in the inline exclusion editor, disabled={!onDesktop} on the mirror switch, the Badge-as-list-row, and the duplicated RowTitle) are all resolved in this revision. Three remaining consistency issues, all in ComputerHistorySettings.tsx.