Skip to content

feat(sidebar,git): thread folders, worktree labels, git sync control, CI status#4207

Open
TheIcarusWings wants to merge 3 commits into
pingdotgg:mainfrom
TheIcarusWings:t3code/sidebar-folders-worktree-labels-git-sync
Open

feat(sidebar,git): thread folders, worktree labels, git sync control, CI status#4207
TheIcarusWings wants to merge 3 commits into
pingdotgg:mainfrom
TheIcarusWings:t3code/sidebar-folders-worktree-labels-git-sync

Conversation

@TheIcarusWings

@TheIcarusWings TheIcarusWings commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Re-submits four features that were closed during the backlog cleanup on 2026-07-20 (#3069, #3070, #3071, #3075, #3088). Per that request, this is a current diff rebuilt on top of today's main rather than a reopen: the old branches predated the sidebar refactor and no longer applied.

Grouped into one PR to keep it to a single review rather than five. Happy to split it back out if you'd prefer.

Thread folders + drag reorder

User-defined folders in the sidebar, with drag to reorder threads.

folders expanded
folder collapsed
move to folder
drag reorder

Custom worktree labels

Display-only label for a worktree, shared by every thread on it. Does not move the worktree on disk.

rename dialog
applied label

Git sync control

VS Code-style publish/pull/push/sync in the branch toolbar, driven by upstream state.

state control
up to date up to date
ahead ahead
behind behind
diverged diverged
no upstream publish

CI status next to the PR pill

Check status surfaced on the composer PR pill (server-side plumbing in GitHubCli / gitHubPullRequests).

Note on the multi-select context menu

The one real conflict with current main was in Sidebar.tsx, where this work and the upstream archive action both changed the multi-select menu. Both are kept, and buildMultiSelectThreadContextMenuItems now takes optional folder children so the menu composes rather than one replacing the other:

multi-select menu

Verification

  • pnpm typecheck: 0 errors
  • pnpm lint: 0 errors
  • pnpm test: green, except MessagesTimeline.test.tsx, which fails the same way on pristine main under full parallel load and is untouched here
  • Screenshots above captured from this branch against a scratch repo with a real remote

The desktop prod-staging dependency commits from my local branch are deliberately left out of this PR; they are unrelated and can go separately if wanted.


Note

Medium Risk
New git fetch/push/sync and rebase paths can mutate remotes and local history; sidebar folder state is persisted locally with GC tied to live snapshots, so bugs could affect ordering or membership until refresh.

Overview
Adds four user-facing capabilities: sidebar thread folders, cosmetic worktree labels, a branch-toolbar git sync control, and PR CI status in the composer.

Sidebar gains per-project thread folders with create/rename/delete, context-menu and bulk Move to folder, and drag-and-drop to reorder folders, move threads into folders, reorder ungrouped threads, or drop on “Remove from folder.” Folder membership, folder order, collapse state, and manual ungrouped order persist in uiStateStore (with snapshot GC so empty bootstrap does not wipe data). Keyboard traversal and multi-select menus follow the rendered folder layout.

Worktree labels are display-only names keyed by worktree path (worktreeLabelByPath), editable via double-click/right-click on the workspace selector and a global WorktreeRenameDialog; labels clear when a worktree is removed.

Git adds server fetchCurrentBranch / syncCurrentBranch (ff pull, push, publish without upstream, optional rebase on divergence → GitDivergedError) and wires vcs.fetch / vcs.push / vcs.sync through GitWorkflowService and ws. The web GitSyncControl drives fetch/pull/push/sync with toasts (including rebase on diverged sync) and blocks branch picker changes while sync ops run.

CI requests statusCheckRollup from gh pr JSON, derives ChangeRequestChecks in gitHubPullRequests, and surfaces checks on VCS/change-request payloads and the branch toolbar PR pill (chip + open checks URL).

Reviewed by Cursor Bugbot for commit 6f3cfd3. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add thread folders, worktree labels, and Git fetch/push/sync controls to the sidebar

  • Adds drag-and-drop thread folders to the sidebar: users can create, rename, delete, expand/collapse, and reorder folders, and move threads between them or back to ungrouped via a drop zone.
  • Adds a GitSyncControl component to the branch toolbar that exposes one-click fetch, pull, push/publish, and sync with toast notifications; ref switching is disabled while a sync is running.
  • Adds CI checks status to PRs: statusCheckRollup is fetched from GitHub, rolled up into a passing/pending/failing summary, and shown as a colored chip next to the PR in the branch toolbar.
  • Adds per-worktree custom labels stored in uiStateStore; users can set or clear labels by double-clicking or right-clicking the workspace selector, and labels appear in the branch toolbar and delete-confirmation dialogs.
  • Adds server-side RPC handlers and GitVcsDriver implementations for vcsFetch, vcsPush, and vcsSync, with GitDivergedError surfaced when sync cannot fast-forward.
  • Risk: manual thread order and folder membership are persisted; stale entries are garbage-collected on load, but schema changes may affect existing persisted state on upgrade.

Macroscope summarized 6f3cfd3.

… CI status

Re-submits four previously reviewed features, rebuilt on current main after
the sidebar refactor. Replaces pingdotgg#3069, pingdotgg#3070, pingdotgg#3071, pingdotgg#3075 and pingdotgg#3088, which
were closed during backlog cleanup while stale.

- sidebar: user-defined thread folders with drag reorder
- web: custom display labels for worktrees
- git-sync: VS Code-style publish/pull/push/sync control
- composer: CI status next to the PR pill

The multi-select thread context menu now composes both the folder move
submenu and the upstream archive action:
mark unread / move to folder / archive / delete.
@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 6eaca1b4-5689-4e6e-8420-e3bb0f96e673

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Jul 20, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 3 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit c20e433. Configure here.

Comment thread apps/web/src/components/Sidebar.tsx Outdated
Comment thread apps/web/src/components/Sidebar.tsx
Comment thread apps/web/src/components/Sidebar.tsx
@@ -74,9 +74,19 @@ export async function archiveSelectedThreadEntries<
export function buildMultiSelectThreadContextMenuItems(input: {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Medium components/Sidebar.logic.ts:74

When the global selection spans multiple projects, the "Move to folder" submenu applies the chosen folder to every selected thread, including threads whose projectKey differs from the clicked project. moveThreadsToGroup receives all selected keys, so cross-project threads are removed from their existing folders and assigned to a folder in the wrong project — they then silently disappear from that folder because its layout only renders threads for the target project. The submenu should either restrict the move to threads in the clicked project or disable the action when the selection is cross-project.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/components/Sidebar.logic.ts around line 74:

When the global selection spans multiple projects, the "Move to folder" submenu applies the chosen folder to every selected thread, including threads whose `projectKey` differs from the clicked project. `moveThreadsToGroup` receives all selected keys, so cross-project threads are removed from their existing folders and assigned to a folder in the wrong project — they then silently disappear from that folder because its layout only renders threads for the target project. The submenu should either restrict the move to threads in the clicked project or disable the action when the selection is cross-project.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 985513a. The move now applies only to selected threads in the clicked project, the label shows that count, and the entry is hidden when nothing in the selection belongs to the project.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I'm unable to act on this request because you do not have permissions within this repository.

Comment thread apps/web/src/components/GitSyncControl.tsx Outdated
event.stopPropagation();
return;
}
if (suppressThreadClickAfterDragRef.current) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Medium components/Sidebar.tsx:538

After a drag is cancelled (e.g. via Escape, window resize, or tab visibility change), the next thread click is silently ignored instead of navigating or selecting. handleRowClick bails out when suppressThreadClickAfterDragRef.current is set, but that flag is only reset on a completed drop — the drag-cancel path never clears it. @dnd-kit/core 6.3.1 can cancel an active pointer drag without producing the trailing click this guard expects, so the flag stays true indefinitely and the first post-cancel click is swallowed.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/components/Sidebar.tsx around line 538:

After a drag is cancelled (e.g. via Escape, window resize, or tab visibility change), the next thread click is silently ignored instead of navigating or selecting. `handleRowClick` bails out when `suppressThreadClickAfterDragRef.current` is set, but that flag is only reset on a completed drop — the drag-cancel path never clears it. `@dnd-kit/core` 6.3.1 can cancel an active pointer drag without producing the trailing click this guard expects, so the flag stays `true` indefinitely and the first post-cancel click is swallowed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 985513a (same root cause as Bugbot's finding on the cancel handler); both suppression flags are cleared on drag cancel.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I'm unable to act on this request because you do not have permissions within this repository.

Comment thread apps/web/src/uiStateStore.ts
Comment thread apps/server/src/sourceControl/gitHubPullRequests.ts
Comment thread packages/client-runtime/src/state/threadSort.ts
@macroscopeapp

macroscopeapp Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

2 blocking correctness issues found. Large feature PR introducing thread folders with drag-and-drop, worktree labels, git sync controls, and CI status display. Multiple new components, RPC endpoints, and complex state management warrant human review. Two unresolved comments also identify functional bugs in folder assignment and drag handling.

You can customize Macroscope's approvability policy. Learn more.

- clear click-suppression flags on drag cancel so the next click is not swallowed
- close the diverged toast before starting Rebase & sync to prevent stacked retries
- make digit-jump hints and ctrl+arrow traversal folder-aware so shortcuts match
  the rendered order (folders first, then the ungrouped list)
- scope multi-select folder moves to threads in the clicked project and hide the
  entry for cross-project-only selections
- persist ungrouped reorder against the full (uncapped) list and include newly
  ungrouped dragged threads so the drop position applies
- guard the folder GC against empty bootstrap/disconnect snapshots, both at the
  sidebar effect and inside syncThreadGroups, so a reload can no longer wipe
  persisted folders and manual order
- treat GitHub's STALE check conclusion as failing; a stale required check
  still blocks merging
- keep sortThreads deterministic in manual mode by sorting on recency; the
  sidebar still layers the user-defined order via orderItemsByPreferredIds,
  and latest-thread pickers no longer depend on input array order
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 1,000+ changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant