feat(sidebar): group threads by worktree#2708
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 Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
ApprovabilityVerdict: Needs human review This PR introduces a new user-facing feature (grouping sidebar threads by worktree) with new settings, UI components, and state management. New features of this scope warrant human review to ensure the implementation meets design expectations and UX requirements. You can customize Macroscope's approvability policy. Learn more. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes 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 20b9a1f. Configure here.
| const projectOverflowControlsWorktrees = threadGroupingMode === "worktree" && showWorktreeGroups; | ||
| const showProjectOverflowControl = projectOverflowControlsWorktrees | ||
| ? hasOverflowingWorktrees || hasHiddenWorktrees | ||
| : hasOverflowingThreads; |
There was a problem hiding this comment.
Overflow button label inconsistently switches between states
Low Severity
projectOverflowControlsWorktrees derives from showWorktreeGroups, which depends on the currently rendered groups. When collapsed with worktreePreviewCount=1 and the current checkout is the first group, showWorktreeGroups is false, so the button says "Show more threads". After clicking (expanding reveals other worktrees), showWorktreeGroups flips to true, and the collapse button says "Show fewer worktrees". The user clicks one label but sees a different label to undo the action, creating a confusing asymmetry.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 20b9a1f. Configure here.
| } | ||
|
|
||
| function parsePrimaryWorktreePath(worktreeListPorcelain: string): string | null { | ||
| for (const line of worktreeListPorcelain.split("\n")) { |
There was a problem hiding this comment.
🟢 Low git/GitManager.ts:108
On Windows, Git outputs CRLF line endings (\r\n), so split("\n") leaves a trailing \r on each line. This causes parsePrimaryWorktreePath to return paths like "/path\r", which breaks fileSystem.realPath() and canonicalizeExistingPath. Consider trimming whitespace or using a regex split that handles both line ending types.
- for (const line of worktreeListPorcelain.split("\n")) {
+ for (const line of worktreeListPorcelain.split(/\r?\n/)) {🤖 Copy this AI Prompt to have your agent fix this:
In file apps/server/src/git/GitManager.ts around line 108:
On Windows, Git outputs CRLF line endings (`\r\n`), so `split("\n")` leaves a trailing `\r` on each line. This causes `parsePrimaryWorktreePath` to return paths like `"/path\r"`, which breaks `fileSystem.realPath()` and `canonicalizeExistingPath`. Consider trimming whitespace or using a regex split that handles both line ending types.
Evidence trail:
apps/server/src/git/GitManager.ts lines 107-118 (parsePrimaryWorktreePath with split("\n") and no \r handling), apps/server/src/git/GitManager.ts lines 732-735 (caller passes stdout directly, result goes to canonicalizeExistingPath), apps/server/src/vcs/GitVcsDriverCore.ts lines 534-605 (collectOutput: text field accumulates raw decoded output with no CRLF normalization; only the onLine callback strips \r at line 550)


What Changed
Why
TLDR I wanna stop using conductor but T3's worktree's absolutely suck to use
T3's worktree support is capable but requires a lot of mental load. It's easy to run all your chats in the main worktree, and its easy to run all your chats in separate worktrees, but as soon as you want to do any amount of mixing and matching in different worktrees it gets absolutely impossible to manage.
This is one of the most obvious UX improvements here, and makes it much more clear when threads are operating in the same worktree. Better display of worktrees also paves the way for other improvements, like clearer UX around creating new threads in specific worktrees. Those improvements are beyond the scope of this PR.
UI Changes
Sort & group settings before and after:


Sidebar before

Sidebar still looks like this when threads are not grouped by worktree
Sidebar after


indicators


Checklist
(not very small, but focused at least. my b)
n/a
Note
Medium Risk
Changes sidebar thread rendering/ordering and adds new persisted UI state and client settings defaults, which could affect navigation shortcuts/selection and user-configured sidebar behavior. Risk is moderated by extensive new unit test coverage for grouping/overflow/pinning edge cases.
Overview
Adds worktree-grouped thread lists in the sidebar (default behavior). Threads can now render under expandable worktree headers (with a special “Current checkout” group), while preserving a flat
separatemode.Introduces new sidebar render modeling in
Sidebar.logic.ts(group building, overflow/preview limits per worktree, and “pin active thread” behavior) and updatesSidebar.tsxto use the grouped model for visible ordering (jump shortcuts, prewarming, range selection) plus new per-worktree and per-project “show more/less” controls.Adds two new client settings in
contracts/settings.ts—sidebarThreadGroupingModeandsidebarWorktreePreviewCount—wires them into the sort/group menu and “Restore defaults”, and persists collapsed worktree UI state viauiStateStore(collapsedWorktreeIds) with associated tests.Reviewed by Cursor Bugbot for commit 20b9a1f. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Group sidebar threads by worktree with per-worktree expand/collapse controls
buildSidebarWorktreeThreadGroups,buildSidebarThreadRenderModel, andbuildSidebarProjectThreadRenderStatein Sidebar.logic.ts to compute grouped render state with pinned active thread, preview limits, and hidden/overflow accounting.sidebarThreadGroupingMode(default'worktree') andsidebarWorktreePreviewCount(default 4, range 1–15) as persisted client settings, configurable fromProjectSortMenu.uiStateStore, restoring expansion state on reload.📊 Macroscope summarized e915a02. 1 file reviewed, 1 issue evaluated, 0 issues filtered, 1 comment posted
🗂️ Filtered Issues