Skip to content

fix(sidebar): keep pinned worktrees in grouped lists#4745

Open
tmchow wants to merge 1 commit into
stablyai:mainfrom
tmchow:tmchow/repo-worktree-organization
Open

fix(sidebar): keep pinned worktrees in grouped lists#4745
tmchow wants to merge 1 commit into
stablyai:mainfrom
tmchow:tmchow/repo-worktree-organization

Conversation

@tmchow
Copy link
Copy Markdown
Contributor

@tmchow tmchow commented Jun 6, 2026

Summary

Pinned worktrees now stay visible in the groups that claim to contain them. Before this change, pinning a worktree removed it from its repo, status, or All grouping, which made those sections read as partial lists even when their labels promised otherwise. The pinned section now behaves as a shortcut overlay instead of a relocation target: the same worktree can appear in Pinned and in its natural repo/status/all section.

That creates an intentional duplicate-row situation, so the sidebar now distinguishes which copy the user actually selected. Both rows remain semantically current because they represent the same active worktree, but the clicked row gets the primary active surface while the other copy gets a secondary active surface. Sidebar clicks also stop re-revealing the first mounted copy, so selecting the natural repo/status row no longer jumps the scroll position back to the pinned row at the top.

Behavior

Before After
Pinning moved a worktree out of its repo/status/all section. Pinning adds a shortcut while preserving the natural grouped entry.
All, In progress, and repo groups could silently omit pinned worktrees. Group labels match their contents; pinned worktrees still count and render there.
Duplicate active rows would either both look primary or the pinned copy would win after reveal. The clicked row is primary, the other active copy is secondary.
Clicking the lower grouped copy could scroll back to the pinned shortcut. Sidebar-originated activation does not enqueue an unnecessary reveal.

Demo

CleanShot.2026-06-06.at.00.29.45.mp4

Test Plan

  • pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/lib/sidebar-worktree-activation.test.ts src/renderer/src/components/sidebar/WorktreeCard.test.ts src/renderer/src/components/sidebar/WorktreeCard.quick-actions.test.tsx src/renderer/src/components/sidebar/WorktreeList.lineage-child-card.test.ts src/renderer/src/components/sidebar/sleep-worktree-flow.test.ts src/renderer/src/components/sidebar/worktree-list-groups.test.ts src/renderer/src/components/sidebar/worktree-section-activity.test.ts src/renderer/src/components/sidebar/worktree-drag-units.test.ts src/renderer/src/components/sidebar/worktree-manual-order.test.ts src/renderer/src/components/sidebar/worktree-list-imported-rows.test.ts src/renderer/src/components/sidebar/worktree-list-sticky-headers.test.ts src/renderer/src/store/slices/worktrees.test.ts
  • pnpm run typecheck:web
  • pnpm exec oxlint src/renderer/src/assets/main.css src/renderer/src/components/sidebar/WorktreeCard.tsx src/renderer/src/components/sidebar/WorktreeList.tsx src/renderer/src/components/sidebar/WorktreeCard.test.ts src/renderer/src/components/sidebar/WorktreeCard.quick-actions.test.tsx src/renderer/src/components/sidebar/WorktreeList.lineage-child-card.test.ts src/renderer/src/components/sidebar/sleep-worktree-flow.ts src/renderer/src/components/sidebar/sleep-worktree-flow.test.ts src/renderer/src/components/sidebar/worktree-drag-units.ts src/renderer/src/components/sidebar/worktree-drag-units.test.ts src/renderer/src/components/sidebar/worktree-list-groups.ts src/renderer/src/components/sidebar/worktree-list-groups.test.ts src/renderer/src/components/sidebar/worktree-list-imported-rows.test.ts src/renderer/src/components/sidebar/worktree-list-sticky-headers.test.ts src/renderer/src/components/sidebar/worktree-section-activity.ts src/renderer/src/components/sidebar/worktree-section-activity.test.ts src/renderer/src/lib/sidebar-worktree-activation.ts src/renderer/src/lib/sidebar-worktree-activation.test.ts src/renderer/src/lib/worktree-activation.ts src/renderer/src/store/slices/worktree-helpers.ts src/renderer/src/store/slices/worktrees.ts src/renderer/src/store/slices/worktrees.test.ts

Compound Engineering
GPT-5

Copy link
Copy Markdown
Contributor

@pullfrog pullfrog Bot left a comment

Choose a reason for hiding this comment

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

✅ No new issues found.

Reviewed changes — makes pinned worktrees visible in their natural sidebar groups (All, repo, status) while keeping the Pinned section as a shortcut overlay, and distinguishes which copy the user clicked via primary/secondary active surface styling.

  • Pinned overlay modelemitPinnedGroup no longer returns a pinned-ID exclusion set; buildRows and all group-by modes iterate the full worktree list so group labels remain literal.
  • Dual-row active surfacemarkSidebarWorktreeActiveImmediately handles multiple DOM rows for the same worktree ID; the clicked copy gets primary styling (filled border) and the other copy gets secondary (ring accent).
  • Suppressed sidebar reveal on sidebar clickactivateAndRevealWorktree accepts revealInSidebar: false, preventing scroll jumps back to the first mounted copy when clicking the natural-group row.
  • Row-scoped renamerenamingWorktreeId becomes { worktreeId, rowKey? }, so rename opens on the specific row that was clicked rather than both copies.
  • Drag safety — pinned overlay rows are excluded from getWorktreeDragGroups and getWorktreeDragUnitGroups, and keyboard-navigation deduplication guards duplicated worktree IDs in renderedWorktreeIds and selectedWorktrees.
  • Section activity — pinned worktrees contribute activity to both Pinned and natural section headers.
  • Sleep flowfindSidebarWorktreeRow now locates rows via data-worktree-id instead of the old virtual-row key, matching the scoped-row model.

Pullfrog  | View workflow run | Using DeepSeek Pro (free via Pullfrog for OSS) | 𝕏

@tmchow
Copy link
Copy Markdown
Contributor Author

tmchow commented Jun 6, 2026

@nwparker @AmethystLiang potentially controversial change 🙈

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.

2 participants