feat(web): filter sidebar threads by environment - #8530
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This PR introduces a substantial session-only environment-filter workflow that changes how sidebar threads, drafts, search results, project choices, selection, and pagination are presented. The unresolved disabled-state affordance issue also merits review before relying on the new interaction. You can add or adjust custom eligibility rules. Learn more. |
258c853 to
8983e13
Compare
Dismissing prior approval to re-evaluate 8983e13
There was a problem hiding this comment.
One consistency finding on the new environment-filter trigger: it is the only icon SidebarMenuButton in this header row without the coarse-pointer hit-target overlay its neighbors use. Everything else (Menu/MenuPopup/MenuCheckboxItem composition, width-class contract on MenuPopup, active-filter dot matching PullRequestListFilters) matches the shared component system.
Posted via Macroscope — UI Consistency
8983e13 to
14ed67b
Compare
Add an icon button next to the sidebar's project scope menu (visible only when more than one environment is connected) that opens a checklist to enable and disable which environments' threads the list shows. The filter composes with the project scope, draft rows, search, and the settled-tail pagination reset; the project menu narrows to projects with a presence in an enabled environment. State is the disabled set, so newly connected environments are visible by default. The last enabled environment cannot be unchecked, and a catalog change that would leave nothing enabled resets the filter instead of hiding every thread behind a control that no longer renders. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
14ed67b to
72c948d
Compare
There was a problem hiding this comment.
Two consistency findings on the new environment filter control in apps/web/src/components/Sidebar.tsx. Everything else (dot indicator matching PullRequestListFilters, MenuPopup width contract, SidebarMenuButton icon-color indirection) lines up with the existing system.
Posted via Macroscope — UI Consistency
| className={cn( | ||
| "[&>span:last-child]:min-w-0", | ||
| isEnabled | ||
| ? "text-foreground data-disabled:opacity-100" |
There was a problem hiding this comment.
data-disabled:opacity-100 cancels the only visible disabled affordance MenuCheckboxItem has. The primitive's disabled state is pointer-events-none + cursor-not-allowed + opacity-64; with pointer events off there is no hover highlight and no not-allowed cursor either, so the last enabled environment renders identically to an interactive checked item that silently does nothing on click — the outcome the adjacent comment says the disabled prop is there to avoid.
Consider keeping the primitive's dimming so the at-least-one constraint is actually visible:
| className={cn( | |
| "[&>span:last-child]:min-w-0", | |
| isEnabled | |
| ? "text-foreground data-disabled:opacity-100" | |
| ? "text-foreground" |
Posted via Macroscope — UI Consistency
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit d80e30b. Configure here.
There was a problem hiding this comment.
One finding on the new commit: the locked environment row explains its constraint with a native title attribute instead of the shared Tooltip primitive. Details inline.
Posted via Macroscope — UI Consistency
There was a problem hiding this comment.
One finding on the newest commit: the environment checkbox rows now pin data-highlighted text colors, which overrides MenuCheckboxItem's accent-surface foreground contract.
Posted via Macroscope — UI Consistency

Observed problem and reproduction
Connect T3 Code to more than one environment and open the web or desktop sidebar. Threads from every machine are interleaved. The project filter cannot express “show only this environment” because one logical project may span environments.
Cause
The sidebar had project scope but no environment scope. Thread rows, drafts, search results, project options, selection, and settled pagination always used the full connected-environment catalog.
Change and boundary
The sidebar now shows an icon-only environment checklist beside the project combobox only when more than one environment is connected. Selected environments use the normal high-contrast foreground; unchecked environments are slightly faded at rest and retain a theme-safe 70% accent foreground while highlighted. The last selected environment stays high contrast but has a distinct locked background, not-allowed cursor, and repository-standard tooltip explaining the at-least-one constraint. The trigger also has the same themed tooltip pattern as the adjacent icon buttons.
Disabling an environment hides its threads, drafts, and search results, narrows project options, clears multi-select, and resets settled-tail pagination. A dot marks an active filter. Project choices retain upstream’s logical group label, so selecting one environment never replaces a grouped repository with one physical clone name and never appends a redundant environment name.
State is the disabled environment set. An empty set means all environments are enabled, newly connected environments are visible by default, and the last enabled environment cannot be unchecked. Catalog pruning is derived during render, so disconnecting the last enabled environment cannot produce a transient empty sidebar before the synchronization effect runs.
This is session-only and uses the shared web sidebar, so it applies to web and desktop. React Native mobile, SwiftUI mobile, providers, server events, and wire contracts are unchanged. Settings, the command palette, and keybindings do not own this list filter. Local, direct remote, relay, and tunnel catalogs use the same client-side path.
Validation
On remote head
248f6158842b9adce725a88efd6c3b846d93eb0a, against fetched livemaintarget1f8ed54add4133ac39effceded8fc1fff12d8e03:CI=true pnpm vp test run src/components/Sidebar.logic.test.tsfromapps/web: 1 file and 124 tests passed; exit 0.CI=true pnpm vp lint apps/web/src/components/Sidebar.tsx apps/web/src/components/Sidebar.logic.ts apps/web/src/components/Sidebar.logic.test.ts: exit 0.CI=true pnpm vp format --check apps/web/src/components/Sidebar.tsx apps/web/src/components/Sidebar.logic.ts apps/web/src/components/Sidebar.logic.test.ts: exit 0.CI=true pnpm --filter @t3tools/web typecheck: exit 0.git diff --check: exit 0.text-accent-foreground/70, the selected locked row remained full contrast with a distinct background and not-allowed cursor, and the project menu retained the logical project label without an environment suffix.MERGEABLE/CLEANand all current-head checks complete: 18 successful, 8 expected skips, 1 neutral, 0 failures, 0 pending. Cursor Bugbot and Macroscope Correctness, UI Consistency, Effect Service Conventions, and Approvability completed without a current-head finding.main, with merge base053affbed2659f90cd1b1efaaa7a75865c4131c7. Per owner instruction, this correction used normal owned-head pushes only: no merge, rebase, force-push, or merge action.Cross-provider review was not run because the owner explicitly required no re-delegation. GPT-5.6 Sol reviewed the frozen three-file diff against the repository policy and the primary-worktree
CODING_STANDARDS.mdhash144fbf46af335d8d18a95c8d4b4f2e9e0207fa2e; no actionable issue remained after the current review feedback was applied.Evidence
Known gaps: Current-head static screenshots, GIFs, and MP4 capture are pending. The attached T3 preview’s snapshot endpoint failed, and its recording start timed out after 15 seconds. A Chrome fallback was abandoned because that browser was actively in use. The media below is historical reference from head
163236dacand is not claimed as current-head proof.Historical visual reference — head 163236d
Before, dark
After, dark
Before and after, dark
Interaction
Play or download the MP4 interaction recording.
Light mode evidence
Full-window source captures and animations
Risks and limitations
Owning issue and stack
No owning issue, discussion, or stacked PR exists. This is a direct web contribution, and maintainer edits are enabled.
Implemented and reviewed by GPT-5.6 Sol in the Codex/T3 harness.
Note
Low Risk
Client-only sidebar list filtering with guarded edge cases and unit tests; no server, auth, or persistence changes.
Overview
Adds a session-only environment filter to the web sidebar when more than one environment is connected: a server icon menu with per-environment checkboxes (and an active-filter dot) beside the existing project scope combobox.
Filter state is stored as the disabled environment set (empty = all visible; new connections stay on by default).
toggleDisabledEnvironmentIdandpruneDisabledEnvironmentIdsinSidebar.logic.tshandle toggles, no-op set identity for React, blocking the last enabled environment, and resetting when disconnects would hide every thread. The sidebar applies the enabled set to thread partitioning, draft rows, project picker options, multi-select clearing, settled-tail pagination reset, and empty-state copy; project scope widens to “all projects” if the scoped project would have no enabled environments.Reviewed by Cursor Bugbot for commit 248f615. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Add environment filter menu to sidebar for filtering threads and drafts
toggleDisabledEnvironmentIdandpruneDisabledEnvironmentIdsutilities in Sidebar.logic.ts that store disabled environment IDs as aSet, preserve reference identity for no-ops, and prevent disabling the last enabled environmentMacroscope summarized 248f615.