Repository navigation
UI Consistency: 1 issue found
apps/web/src/components/settings/settingsSearch.ts — the new wsl-backend catalog entry can still produce a search result whose anchor never renders. windowsOnly only suppresses the entry on non-Windows desktop; on Windows desktop without WSL installed, renderWslRow returns null (!desktopWslState.available && !enabled && !wslOnly), so the jump navigates to Connections with nothing to scroll to, focus, or pulse, and #wsl-backend stays in the URL because onTargetHandled never fires. Suggested fix: gate the entry on the same runtime WSL state the row uses (thread desktopWslStateAtom's available || enabled || wslOnly into searchSettings, as items already is) instead of the client platform; passing the platform in explicitly would also make the new filter branch testable.
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 reviewed (in scope): apps/web/src/components/settings/settingsSearch.ts, apps/web/src/components/settings/settingsSearch.test.ts, apps/web/src/components/settings/ConnectionsSettings.tsx.
Checks performed and found clean:
- The three
{...searchableSetting("wsl-backend")}spreads sit in mutually exclusive branches ofrenderWslRow, so no duplicate DOMidis emitted;SettingsRowacceptsidand wires it throughuseSettingsSearchTargetplustabIndex={-1}, matching every other searchable row. - No primitive was reconstructed or restyled; no Tailwind/CSS ownership, theme variant, mask/scroll, or layout behavior changed.
- Platform detection reuses the shared
isWindowsPlatformhelper from~/lib/utils, consistent with the existingisWindowsPlatform(navigator.platform)gate for the Windows tray rows in the same file. - The WSL row targets the local desktop bridge (
desktopWslStateAtom→window.desktopBridge.getWslState), so deriving the gate from the renderer's own platform is the correct scope here; no cross-environment RPC/label mismatch. - Late mounting of the row after the SWR load is handled by the ref-callback target contract, so async loading alone is not a dead-anchor case.
Remaining risk is limited to the reported case (Windows desktop with WSL absent), where the entry is offered but the row is intentionally not rendered.
🔍 Agent activity — 22 tool calls
💭 I want to check how the codebase normally does platform detection, comparing against the new
windowsOnlyfilter's use ofnavigator.platform. I also want to check whether the three call sites usingsearchableSetting("wsl-backend")in ConnectionsSettings would create duplicate DOM ids. I'm also noticing there's a weird test insertion that appears appended into an existing test, and I want to verify the WSL backend row actually depends on the environment's server platform rather than the local renderer's navigator.platform — that distinction matters a lot for remote contexts.
1. git_tools — isWindowsPlatform
2. browse_code — apps/web/src/components/settings/settingsSearch.ts
💭 I'm noticing that
searchableSettingreturns an object spread across three call sites in ConnectionsSettings, all using the same id "wsl-backend" — that would create duplicate DOM ids unless these are conditional variants that only render one at a time. I need to check the three call sites around lines 2760-2860 to confirm.
3. browse_code — apps/web/src/components/settings/ConnectionsSettings.tsx
💭 Since the branches are mutually exclusive returns, there's no risk of duplicate ids. Now I'm checking whether the
windowsOnlyfilter's use ofnavigator.platforminside the search function is consistent with howisElectronis handled elsewhere, and looking at how this interacts with the existing test for "wsl" search results. More importantly, I need to trace what actually gates rendering of the WSL row — whether it depends onnavigator.platformat all, or on the desktop bridge and server-side platform state instead. If gating relies ondesktopBridgeavailability rather than the browser's platform string, filtering search results bynavigator.platformcould mismatch the actual render condition, similar to concerns withdesktopOnly.
4. git_tools — renderWslRow|canManageLocalBackend|desktopWslState
5. browse_code — apps/web/src/components/settings/settingsSearch.test.ts
💭 I'm checking whether SettingsRow actually accepts and forwards an
idprop to its underlying element, since previously rows only hadtitlewithoutid, and now the spread introducesid="wsl-backend"that needs to reach the DOM for the search functionality to work. I should also verify how the search scroll mechanism resolves the target anchor, and whether the WSL row is nested inside a collapsed disclosure or card at that point in the file, which could prevent scrolling from revealing it even if the id is correctly set.
6. git_tools — function SettingsRow|interface SettingsRowProps|type SettingsRowProps
7. git_tools — searchSettings(|SettingsSearchItem
8. browse_code — apps/web/src/components/settings/settingsLayout.tsx
9. browse_code — apps/web/src/components/settings/SettingsSidebarNav.tsx
💭 The SettingsRow with an id gets tabIndex -1 and the search ref, matching the pattern of other rows. The three call sites all reference the same "wsl-backend" searchable setting as mutually exclusive branches, and there's a separate wsl-only toggle row in the same fragment with its own title. Now I want to double-check whether the windowsOnly gating is applied correctly. Checking, the row's visibility depends on
desktopWslStateexisting, which comes from the desktop bridge and presumably only exists on Windows. Using navigator.platform in the filter function matches existing usage elsewhere in the file for the tray, so that's consistent, though I should verify whether the WSL section sits inside a collapsed disclosure that might make the anchor unreachable, and whether the row only renders when the desktop bridge exists. The test asserting that "wsl" search returns empty in browser passes since isElectron is false there, and the search item catalog typing looks fine. Gating the WSL row on navigator.platform for the local desktop host seems appropriate since it's about the local backend rather than a remote environment. I want to double check whether the windowsOnly filter matches correctly on real Electron Windows — navigator.platform would be "Win32" so that lines up. I should also check whether other consumers of SETTINGS_SEARCH_ITEMS, like a full listing view when the query is empty, bypass the windowsOnly filter, and confirm the WSL row's aria-label and title wiring look correct. Now I'm wondering whether the WSL section could actually render on non-Windows desktop too, in which case hiding it via windowsOnly would incorrectly suppress a real anchor — I need to check how that section's visibility is conditioned.
10. browse_code — apps/web/src/components/settings/ConnectionsSettings.tsx
11. browse_code — apps/web/src/components/settings/ConnectionsSettings.tsx
💭 I'm checking whether the desktop bridge's WSL state returns unavailable on non-Windows platforms, which would make renderWslRow return null naturally—so the windowsOnly guard might be redundant, though I still want to verify the case where WSL isn't installed on an actual Windows machine. Actually, this is the same scenario the comment claims to prevent: on Windows without WSL, the row is hidden but a search result could still link to that missing anchor. I'm weighing whether this counts as a real violation, since navigating there would just silently do nothing, and similar precedent exists elsewhere in the catalog for other conditionally-hidden rows. I'm also wondering about the maintainability angle: reading navigator.platform directly inside a supposedly pure search function makes windowsOnly filtering untestable, unlike the module-level isElectron constant pattern used elsewhere for platform checks. The new "registers WSL backend as desktop-only" test doesn't actually exercise the windowsOnly filtering logic, so I'm trying to decide if that testability gap counts as a concrete finding worth flagging, and want to check the other searchableSetting call sites for wsl-backend to see if the same issue repeats. Checking the three branches of the WSL settings row rendering, they seem mutually exclusive based on desktopWslState and availability, so no duplicate-id risk there. I'm also scanning for other consumers of the settings search items besides the search function and the test itself, but it looks isolated -- so the missing test coverage on the windowsOnly filter still seems like the most concrete issue to raise. The row shows when desktopBridge exists and desktopWslState is loaded, and that state comes from the desktop bridge locally so it's consistent. I should check whether desktopWslStateAtom gates rendering to only Windows Electron, though.
12. git_tools — wsl
💭 I'm noticing a potential mismatch: on macOS, if getWslState throws an error, the error recovery row would still try to render a "couldn't load WSL backend state" message, but the windowsOnly guard would hide it anyway—so that edge case is probably harmless in practice. Checking the isWindowsPlatform regex against navigator.platform values like "Win32" confirms it matches correctly on Windows, and this same pattern is already used elsewhere in the file, so I'm fairly confident the approach is consistent with existing conventions. I want to check if there's a preferred alternative pattern in the codebase, like an isElectron flag or a dedicated platform detection utility, before settling on this.
13. browse_code — apps/web/src/env.ts
14. git_tools — apps/web/src/components/settings/settingsSearch.ts
💭 I want to check the first commit of the PR to make sure the diff covers the full change since it's a merge-base comparison. Now I'm digging deeper for a real UI-consistency issue, considering things like duplicated title props in the select component. Another possibility worth investigating: the WSL row's search anchor might target a row that only mounts after async WSL state finishes loading, meaning if the row hasn't rendered yet when navigating from search, the scroll target won't exist. I want to check whether
useSettingsSearchTargethandles late-mounting rows gracefully by scrolling once the hash matches, regardless of mount timing.
15. git_tools — export function useSettingsSearchTarget
💭 Since the ref callback fires on mount while the target id matches, the async/late-loading case for the WSL row is properly handled by the context/ref design, and swapping branches doesn't cause issues since the target was already cleared. I'm now checking the search filter's matching logic once more to see if there's a real bug hiding there. The filter checks Electron-only and Windows-only item flags, using
navigator.platformto detect Windows even inside Electron, which should still work correctly since Electron's renderer reports the host OS. I'm noting a minor inconsistency though:isElectronis a module-level constant evaluated once, while the Windows check runs per item per call, makingsearchSettingsslightly more environment-dependent than before — a nitpick rather than a bug. I also want to check if the WSL row might be duplicated in another settings panel, so I should search the repo for "WSL backend".
16. git_tools — WSL backend
17. git_tools — searchableSetting(
💭 I'm noticing a discrepancy in line numbers between my grep results, which suggests the search may have run against a different revision than HEAD—I need to verify which version I'm actually looking at for the searchableSetting definition and usages. Maybe the discrepancy is because the two greps ran against different refs despite both including the same sha in the URL. I also notice existing code carefully avoids assigning an anchor id when a row isn't the real target, like conditionally returning undefined for the id when a setting is still loading. Let me just directly verify whether "default-terminal-shell" exists in the catalog at HEAD.
18. git_tools — default-terminal-shell
19. git_tools — 9b2d043..9bb587f
💭 That setting doesn't exist at HEAD, so the earlier grep must've come from a different revision — not a real discrepancy. Now I want to check whether there's an actual correctness issue, starting with the ordering of the settings search items. Looking closer, the WSL entry sits after
remote-environmentsin the catalog, but WSL renders in the "This environment" section which appears earlier on the page than the Remote environments section. The catalog docstring explicitly promises "in result order" matching panel order, and there's a test enforcing that panel-order contract elsewhere, so this placement seems like a legitimate small inconsistency worth flagging — a query matching both entries would surface them out of the documented order. But it's a pretty marginal case since queries for "wsl" and "remote" rarely overlap. Meanwhile I'm noticing something potentially more significant: several desktop-bridge-gated Connections rows (network access, tailscale, WSL) aren't even represented in the catalog itself, except partially — that's worth digging into further before settling on which finding is strongest. I'm weighing whether this is actually worth flagging as a failure, since the resulting behavior — navigating to Connections with no scroll or error — is mildly bad but comparable to how other conditional entries likearchivebehave. I want to check whether non-Windows desktop can even trigger this path; if the WSL IPC handler returnsavailable:falseon macOS, the row stays null and stays consistent with thewindowsOnlyflag, which makes me question whether that flag is even necessary given the existing desktopOnly and state checks. Right — navigator.platform reflects the Electron host OS, not the server, so the WSL-served-renderer case still shows Win32 correctly. For a non-Electron web client hitting a Windows backend remotely, desktopOnly filtering excludes the row anyway since there's no desktopBridge, so that's consistent too. The platform gating logic holds up; I'm left weighing the weaker ordering concern against the more plausible missing-anchor issue on Windows without WSL, so let me verify the ordering claim against the actual Connections page layout. Confirming the panel order: "This environment" (with the WSL row) appears before the remote-backend-reachability section, which comes before the remote-environments section. The catalog lists wsl-backend after remote-environments, both pointing to the same connections route, but no realistic search query would surface both entries together, so the ordering mismatch is essentially invisible to users and doesn't warrant a strong flag — at most a minor note. Then I want to double-check the desktop-only hiding test: it expectssearchSettings("wsl")to return empty since isElectron is false in the test environment, so I need to verify that's actually how the filtering behaves. But the bigger issue is that the newwindowsOnlylogic has no test coverage at all, since it depends on reading the globalnavigatorand module-levelisElectron. Following the rule that new filtering behavior needs focused tests, the cleanest fix is to make the platform check an explicit parameter ofsearchSettings, defaulting tonavigator.platform, so it can actually be tested. I'm weighing whether this rises to a real violation versus just a design preference, and scanning the rest of the diff for anything more concrete—there's a minor stylistic inconsistency between!item.windowsOnlyanditem.desktopOnly !== true, but that's trivial. Let me double-check the platform detection logic in the Electron renderer path for an actual bug. I'm considering whether SSR handling ofsearchSettingscauses a mismatch: sinceisElectronand the windowsOnly check both resolve to false during SSR whennavigator/windoware undefined, hydration on Windows Electron could differ from server-rendered output—but this mirrors an existing pattern fordesktopOnlyitems and Electron content loads client-side anyway, so it's not a new issue. Reconsidering the PR's stated goal—preventing search results from pointing to missing anchors—I realize the main scenario, WSL not installed causing the row to be hidden, isn't actually addressed by this fix. A thorough reviewer would likely flag that the search entry should be gated on the row's actual presence rather than just the windowsOnly flag, though the minimal fix path for this isn't obvious given there's no runtime-availability signal exposed to the search index. Other entries in this catalog always render on their platform, so the implicit contract is that a search entry only exists for rows guaranteed to appear. The WSL entry breaks that: on Windows without WSL installed, the row is absent, so searching "WSL" surfaces a result that silently does nothing when clicked — a genuine dead-end in the UI. I'm weighing whether to flag this as a hard failure versus a softer note, since before this PR there was no WSL entry at all, so this dead-result scenario is newly introduced by the changed lines. I'll report it inline with a clear explanation, leaning toward treating it as a real consistency risk rather than dismissing it as speculative. I trace through the WSL state logic once more: on Windows without WSL installed, the availability check returns false with no distros, so the picker row gets hidden — confirming that's exactly the config where the search result would be dead, whereas WSL installed-but-disabled still renders the row correctly. So the finding crystallizes: adding this catalog entry creates a search result that never resolves to a visible anchor on Windows machines without WSL, undermining the same protection the windowsOnly flag exists for. I'm weighing whether the fix should thread the actual runtime availability state into the search filter (mirroring the condition the row renderer already uses) versus just removing the catalog entry — though injecting live state into what's meant to be a static catalog raises its own complications. I'm also second-guessing whether this concern falls within the scope of the check I'm running, since the stated rules focus on environment routing, primitives, and CSS consistency rather than search catalog completeness. A dead search anchor is arguably a behavioral consistency issue, but the change itself is small and follows existing patterns, so I want to avoid over-flagging something that isn't a genuine violation. Still, the added platform-based filtering only partially addresses the underlying issue since the row's availability still depends on runtime state that isn't being checked. I'm also weighing whether to flag catalog ordering—wsl-backend should probably precede remote-environments to match panel order—but that feels low value and possibly noisy, especially since it's unclear whether result ordering is meant to match panel order within a section or overall sidebar order across sections. Confirming the WSL row does appear before Remote environments in the actual page, so the catalog entry order is misplaced relative to render order. Still, since it only affects keyboard navigation ordering for queries that would realistically never overlap, I'll treat it as optional/aesthetic and skip it, keeping just the one solid finding. Now checking another angle: the first branch renders even whendesktopWslStateis null and there's an error, meaning it could also trigger on macOS or Linux ifgetWslStaterejects there — I want to verify whether that call can actually reject on non-Windows platforms, since that would create a visible row without a matching search entry.
20. browse_code — apps/desktop/src/ipc/methods/wsl.ts
💭 Since getWslState never throws, the error branch only fires on rare IPC transport failures, not real platform gaps. So the actual issue is Windows without WSL producing a dead search result, while on macOS the row is already hidden by the runtime state itself, making the windowsOnly flag redundant complexity in the shared catalog logic. Actually wait — desktopOnly only checks Electron, not OS, so without windowsOnly a "wsl" search would still surface on macOS Electron and be dead. So the flag isn't redundant after all; it's needed to prevent that macOS dead-result case. That leaves my one real finding: a residual dead anchor when searching "wsl" on Windows without WSL installed. I'm weighing whether that's enough to flag, since it's a partial fix to a problem the same PR introduces. A reasonable reviewer comment would note that the row isn't rendered when WSL isn't available/enabled, so the search result still points at a missing anchor, and suggest gating the entry on the loaded WSL state rather than platform. I should still check whether the settings layout's hash-scroll logic handles an unresolved target gracefully before finalizing this.
21. git_tools — useSettingsSearchTargetId|SettingsSearchTargetProvider
💭 This confirms the codebase's care around ensuring search targets actually mount, auto-expanding collapsed sections so the anchor exists to scroll to. The new WSL entry breaks that invariant on Windows desktop without WSL installed, since the row stays hidden and
onTargetHandlednever fires, leaving#wsl-backendstuck in the URL unresolved. I'll post a single inline comment on the settingsSearch.ts catalog entry, lines 266-272 on the diff's right side. Given the review guidance that findings default to a failure state, I'll mark this check as failure while keeping the comment focused and constructive. I decide the finding is solid enough to flag: the code documents an invariant about not exposing results pointing to missing anchors, but on Windows without WSL that invariant breaks in a common configuration. For the fix, since a proper solution would require reading the WSL state atom in SettingsSidebarNav and isn't a clean single-hunk change, I'll skip providing a diff suggestion and just describe the issue and recommended direction in the comment text, noting that renderWslRow returns null under that condition so the entry still surfaces a result whose anchor never mounts. I also want to flag that gating on platform rather than the actual loaded WSL state makes this hard to test — the added test only covers the desktopOnly path, not this new branch — and suggest threading the WSL availability through the same wayitemsis passed, so it's testable and correct. I'll post this as an inline comment on lines 266-272 using the RIGHT side line numbers via github_pr_review.
22. modify_pr — One finding: the new wsl-backend search entry can still resolve to a row that never mounts on Windows desktop. Details inline.
Agent Credits: 158 credits
Token usage: 30 uncached input · 795,099 cache-read input · 95,960 cache-write input · 20,041 output
Agent Credits may also include non-token charges from external tools such as web research.