Skip to content

fix(sidebar): fold same-named project groups from different hosts into one header - #29536

Open
Jerryx333 wants to merge 2 commits into
stablyai:mainfrom
Jerryx333:fix/sidebar-merge-cross-host-project-groups
Open

Jerryx333 wants to merge 2 commits into
stablyai:mainfrom
Jerryx333:fix/sidebar-merge-cross-host-project-groups

Conversation

@Jerryx333

Copy link
Copy Markdown

ELI5

When the same folder of projects is checked out on two machines (say ~/code/ai on this Mac and on a paired Orca server), the sidebar showed that folder twice: one "ai" group per machine. Now it shows one "ai" group with both machines' projects inside it.

What Changed

Before: every host keeps its own project groups, and the sidebar listed each host's groups side by side. With a paired server that mirrors the same folders, "Group by Project" showed ai (this computer) and ai (server) as two headers, and the projects that exist on both machines landed in whichever of the two groups happened to anchor them.

After: under "Group by Project", groups from different hosts that share a name (and the same parent group) fold into one header. The header holds every host's projects and folder workspaces, keeps one collapse state, and child groups fold the same way underneath it. The groups themselves are untouched on each host; only the sidebar draws them together.

Mechanism: the host-visible project groups now pass through a merge step (cross-host-project-group-merge.ts) that picks one representative per set of same-named groups (this computer's copy when it has one) and maps every member id to it. Row building, folder-workspace placement, collapse and reveal keys, Cmd+1–9 ordering, header drag and the group dialogs all read that map, so:

  • rows bucket by the merged header, and a remote folder workspace keeps its own group for host and path-status lookups;
  • dragging a project into a merged header moves it into the member group on the project's own host;
  • renaming or deleting a merged header applies to every member, so the fold does not split back apart after a rename;
  • reveal and collapse address the merged header's key, not a member id that was never drawn.

Groups on a single host are never merged with each other, and a name that exists on only one host renders exactly as before (the merge returns the input list untouched).

Why

Project groups are per-host data, and merging them server-side would mean inventing a cross-host identity for a folder. The sidebar already merges projects across hosts by their git identity, so the natural reading of "same-named group on another host" is "the same folder on another machine", and folding them in the view gives that without touching persistence or the wire format. Alternatives considered: merging by folder basename (surprising when two unrelated folders share a name on different hosts, and the name is what the user actually sees and edits), or an explicit "link groups" action (more UI for the common case where the user already named them the same).

Linked Issue

Fixes #29535

Visual Proof

Before / after of the row model replayed with the author's two real catalogs (49 local repos, 16 server repos):

Before: ai (server, 8 projects) and ai (local, 26 projects) as two headers; the 8 projects present on both machines sat under whichever group anchored them.

After: one ai header (34 entries) with both hosts' checkouts under each shared project, followed by tomoro.

(Screenshots to be attached from a local build.)

Testing

  • pnpm test for src/renderer/src/components/sidebar (new: cross-host-project-group-merge.test.ts, build-rows.cross-host-project-groups.test.ts, folder-reveal.cross-host.test.ts, use-project-group-dialogs-cross-host.test.tsx)

  • pnpm tc, pnpm run check:code-quality:changed

  • Replayed the sidebar row model with two real host catalogs (local + paired Orca server) through buildRows and addHostSectionRows.

  • Platforms: macOS (local) + macOS Orca server; the change is renderer-only and host-agnostic.

  • I manually tested these changes locally

  • Automated tests added/updated, or explained why not below

AI Disclosure

Drafted with Claude Code (Claude Fable 5.1); reviewed and tested by the author.

Review

Agent skill upstream boundary

  • Not applicable, or this change copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.

Notes

Renderer-only; no wire or persistence change, so older servers and clients are unaffected. Mobile does not render project groups. Group actions on a merged header fan out one request per host, each routed to the group's owner as before.

Checklist

  • This PR is small and focused
  • I explained what changed and why (ELI5, the user-facing before/after, the mechanism, and why over the alternatives)
  • Before/after screenshots or videos attached for UI changes, or N/A with reason
  • Self-reviewed for correctness, security, and performance
  • Cross-platform, SSH/remote, and path/shortcut impact considered (or N/A)
  • pnpm lint, pnpm typecheck, pnpm test, and pnpm build pass (or CI will cover; local preferred)

🤖 Generated with Claude Code

…o one header

A folder imported as a project group on this computer and again on a paired
Orca server showed up as two groups with the same name, and the projects that
exist on both machines landed in whichever copy anchored them. Under Group by
Project the sidebar now draws one header for same-named groups from different
hosts (same-host namesakes stay apart), with this computer's copy as the
representative. Rows, folder workspaces, collapse and reveal keys, Cmd+1-9
order, header drag and the group dialogs read the same mapping, so a drop
lands on the repo's own host and rename/delete reach every member. Persistence
and the wire format are untouched.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 11e6060f-0dc4-448b-b368-98c2a6cd77ef
📥 Commits

Reviewing files that changed from the base of the PR and between 8a6e80b and e414a29.

📒 Files selected for processing: 4
  • src/renderer/src/components/sidebar/WorktreeList.tsx
  • src/renderer/src/components/sidebar/worktree-list/rows/use-project-group-dialogs-cross-host.test.tsx
  • src/renderer/src/components/sidebar/worktree-list/rows/use-project-group-dialogs-owner-host.test.tsx
  • src/renderer/src/components/sidebar/worktree-list/rows/use-project-group-dialogs.ts
💤 Files with no reviewable changes: 2
  • src/renderer/src/components/sidebar/worktree-list/rows/use-project-group-dialogs-owner-host.test.tsx
  • src/renderer/src/components/sidebar/WorktreeList.tsx
🚧 Files skipped from review as they are similar to previous changes: 2
  • src/renderer/src/components/sidebar/worktree-list/rows/use-project-group-dialogs-cross-host.test.tsx
  • src/renderer/src/components/sidebar/worktree-list/rows/use-project-group-dialogs.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

📝 Walkthrough

The sidebar folds matching project groups from different execution hosts into one display group. Row construction, folder-workspace handling, and reveal and collapse calculations use the merged group mapping. Drag operations route repositories to the group member on their execution host. Rename and delete actions target the members of a merged group.

Priority: ➖ Normal

Merge Risk: ⚪ Minimal · up to e414a

The cross-host sidebar grouping is mergeable after normal checks; no actionable merge-blocking risk remains.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 35 functions across 23 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main change: merging same-named project groups across hosts into one sidebar header.
Description check Passed The description is complete and on-topic. It includes the user-facing behavior, implementation details, rationale, linked issue, testing information, AI disclosure, compatibility notes, and checklist.…
Linked Issues check Passed The PR meets the coding requirements in #29535. The merge model folds same-named groups across hosts while keeping same-host groups separate and preserving host-specific members. Row grouping and fold…
Out of Scope Changes check Passed The changes remain within #29535. They update renderer sidebar grouping, rows, folder workspaces, reveal and collapse behavior, drag routing, group dialogs, and focused tests. The merge model does not…
Full details: Description check

Explanation

The description is complete and on-topic. It includes the user-facing behavior, implementation details, rationale, linked issue, testing information, AI disclosure, compatibility notes, and checklist. Visual proof and full lint, typecheck, test, and build validation remain unchecked, but these gaps are explicitly documented rather than making the description incomplete.

Full details: Linked Issues check

Explanation

The PR meets the coding requirements in #29535. The merge model folds same-named groups across hosts while keeping same-host groups separate and preserving host-specific members. Row grouping and folder-workspace handling use the display mapping. Reveal and collapse paths use merged header keys. Drag resolves the target member on the repository host. Dialog actions fan rename and delete operations out to all merged members. Delete counts use host-qualified project identities. The supplied change summary reports tests for these behaviors.

Full details: Out of Scope Changes check

Explanation

The changes remain within #29535. They update renderer sidebar grouping, rows, folder workspaces, reveal and collapse behavior, drag routing, group dialogs, and focused tests. The merge model does not change persistence or the wire format. No unrelated change is established. The unavailable incremental diff does not provide additional evidence of out-of-scope changes.

  • Fix all pre-merge checks with AI
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 5b83e7c3-9358-4b68-b9ae-d91e10cd9b20
📥 Commits

Reviewing files that changed from the base of the PR and between 3963611 and 8a6e80b.

📒 Files selected for processing: 23
  • src/renderer/src/components/sidebar/WorktreeList.tsx
  • src/renderer/src/components/sidebar/rendered-sidebar-worktree-order.ts
  • src/renderer/src/components/sidebar/worktree-list/drag/use-header-drag.ts
  • src/renderer/src/components/sidebar/worktree-list/grouping/build-rows.cross-host-project-groups.test.ts
  • src/renderer/src/components/sidebar/worktree-list/grouping/build-rows.ts
  • src/renderer/src/components/sidebar/worktree-list/grouping/cross-host-project-group-merge.test.ts
  • src/renderer/src/components/sidebar/worktree-list/grouping/cross-host-project-group-merge.ts
  • src/renderer/src/components/sidebar/worktree-list/grouping/folder-workspace-lanes.ts
  • src/renderer/src/components/sidebar/worktree-list/grouping/project-group-sections.ts
  • src/renderer/src/components/sidebar/worktree-list/listing/rendered-sidebar-row-keys.ts
  • src/renderer/src/components/sidebar/worktree-list/listing/use-collapsed-groups.ts
  • src/renderer/src/components/sidebar/worktree-list/listing/use-host-visible-scope.ts
  • src/renderer/src/components/sidebar/worktree-list/listing/use-section-rows.ts
  • src/renderer/src/components/sidebar/worktree-list/navigation/folder-reveal.cross-host.test.ts
  • src/renderer/src/components/sidebar/worktree-list/navigation/folder-reveal.ts
  • src/renderer/src/components/sidebar/worktree-list/navigation/pending-reveal-inputs.ts
  • src/renderer/src/components/sidebar/worktree-list/navigation/reveal-ancestors.ts
  • src/renderer/src/components/sidebar/worktree-list/navigation/use-pending-reveal.ts
  • src/renderer/src/components/sidebar/worktree-list/navigation/worktree-reveal-group-keys.ts
  • src/renderer/src/components/sidebar/worktree-list/rows/use-project-group-dialogs-cross-host.test.tsx
  • src/renderer/src/components/sidebar/worktree-list/rows/use-project-group-dialogs.ts
  • src/renderer/src/components/sidebar/worktree-list/viewport/VirtualizedWorktreeViewport.tsx
  • src/renderer/src/components/sidebar/worktree-list/viewport/viewport-props.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

The delete confirmation for a header folded across hosts collected the
members' project ids into one set, so a repo id that both hosts carry showed
as one project although confirming removes it on each host. Keep every
(id, host) pair, and look names up by the same identity instead of the
host-blind repo map.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Sidebar shows one project group per host for the same folder; cross-host projects land in either copy

1 participant