Skip to content

fix(sidebar): move pinned folder workspaces into the Pinned section - #34007

Open
aesthetic wants to merge 1 commit into
stablyai:mainfrom
aesthetic:fix/pinned-folder-workspaces
Open

aesthetic wants to merge 1 commit into
stablyai:mainfrom
aesthetic:fix/pinned-folder-workspaces

Conversation

@aesthetic

@aesthetic aesthetic commented Oct 26, 2026 •

Copy link
Copy Markdown

ELI5

When you pin a git worktree, it moves to the Pinned section at the top of the sidebar. When you pin a folder workspace (a workspace in a folder project that is not a git repo), Orca saves the pin, but the row stays in its project group. This change moves pinned folder workspaces into Pinned too.

What Changed

Before: Select Pin on a folder workspace. The menu then shows Unpin and Orca saves isPinned: true, but the row stays in its project group lane. If no git worktree is pinned, the sidebar shows no Pinned header.

After: A pinned folder workspace shows once, under Pinned, in each Group by mode (repo, workspace-status, pr-status, none). Unpin moves it back to its lane.

Mechanism:

  • src/shared/sidebar-list/sidebar-row-plan.ts: planSidebarRows divides the renderable folder workspaces into pinned and unpinned. The lanes (buildOrderedGroups, flat mode, appendProjectGroupSections) get only the unpinned ones. The pinned ones go to emitPinnedGroup, sorted with compareFolderWorkspacesForDisplay.
  • src/shared/sidebar-list/pinned-group-rows.ts: emitPinnedGroup accepts the pinned folder workspaces. The header count includes them. Per-host counts and IDs come from getLaneHostWorktreeCounts / getLaneHostWorktreeIds, which the status and flat lanes already use for folder workspaces. The section now shows when only folder workspaces are pinned. Folder rows come after the git rows, like in the status lanes.
  • src/renderer/.../navigation/folder-reveal.ts: the reveal of a pinned folder workspace expands Pinned (host-scoped when hosts are shown) and its host, not the project group.

Folder rows have one placement under each pinned display policy. With "show pinned workspaces in their groups" on, a pinned folder workspace shows in Pinned only. Folder rows have one host-identity row key and option ID (render-row.ts, active-descendant-option.ts). A second copy needs separate work on those keys, so this PR does not include it.

Why

All other layers already treat a folder-workspace pin as real: the context menu shows Pin for folder rows, setWorktreesPinnedAndReveal has a folder branch, persistence saves isPinned for folder workspaces, and desktop-sidebar-facts.ts puts folder:<id> in pinnedWorkspaceIds. Only the row planner ignored the flag, because the Pinned section comes from buildWorktreeOccurrencePlan, which gets only git worktrees. #15362 fixed the same kind of gap for the Group by lanes.

This change reuses the existing folder-row and lane host-count functions. I did not add folder workspaces to the worktree occurrence plan, because that plan handles lineage and duplicate occurrences that folder rows do not use.

Prior art: #16799

@lafraia found this bug first and opened #16799 on 2026-08-27. @nwparker agreed it is a bug on 2026-09-06. That PR is still open, and it now conflicts with main: the row builder moved from src/renderer/.../grouping/build-rows.ts to src/shared/sidebar-list/ (planSidebarRows, emitPinnedGroup) after it was opened. This PR uses the same approach as #16799: divide the renderable folder workspaces into pinned and unpinned, and give the Pinned header the lane host-count helpers. This PR applies that approach to the current shared planner.

Differences:

#16799 This PR
Base Renderer buildRows (before the move to src/shared) Current planSidebarRows in src/shared/sidebar-list/
"Show pinned workspaces in their groups" Shows a pinned folder workspace in Pinned and in its group. Adds a required sectionKey to FolderWorkspaceRow, with distinct DOM IDs and one primary active surface Pinned only, with no second copy
Reveal of a pinned folder workspace Expands Pinned or the group, depending on the policy Expands Pinned
Size Larger: row key, option ID, active surface, range selection and keyboard cycle changes 5 files, +37 prod LOC

If the maintainers prefer the full duplicate-copy support, rebasing #16799 onto src/shared/sidebar-list/ is the more complete fix, and I will close this PR. If not, this PR fixes the default policy now, and the duplicate-copy work from #16799 can follow on top of it.

Linked Issue

Fixes #34006

Visual Proof

Same e2e profile and state in both images: one pinned git worktree, a Research folder project with Pinned notes (pinned through setWorktreesPinnedAndReveal, which the context menu calls) and Loose notes. Group by: Project.

Before After
Before: Pinned notes stays under Research After: Pinned notes is under Pinned

Testing

  • New cases in build-rows.folder-workspace-lanes.test.ts: the pinned folder row is under Pinned in all four Group by modes and shows only once; Pinned shows when a folder workspace is the only pinned row; a collapsed Pinned hides the row; an SSH project group's pinned folder is counted under its host, with an empty ID array.

  • New case in folder-reveal.test.ts: the reveal keys for a pinned folder workspace are the host-scoped Pinned key and the host key.

  • All 8 new cases fail on origin/main and pass with this change.

  • pnpm check:changed --maxWorkers=2: 25 of 25 checks pass (format, lint, typecheck, affected tests, ratchets).

  • Toolchain for the results below: Node 24.22.1 and Bun 1.4.4, as package.json and config/.bun-version require.

  • pnpm lint: 35 of 35 steps pass. pnpm typecheck:ci: no type errors.

  • pnpm build: passes, including the mobile web bundle.

  • Tests related to the changed modules (vitest related on the 3 changed source files): 100 files, 746 passed, 0 failed.

  • pnpm test (full): 68 tests in 21 files fail on my machine, and they fail the same way on unchanged origin/main. None of these files is in the related set above. The causes are local to macOS and this machine: macOS bash 3.2 (mapfile: command not found), the /tmp → /private/tmp symlink, a local username (will) that the transcript secret scanner reports in its fixtures, a blocked registry.npmjs.org, uninstalled cloud/ dependencies (pg), and zsh startup tests that read my shell profile. I expect CI on Linux to cover these.

  • Visual proof: a temporary Playwright spec (not committed) ran against the e2e Electron build (ORCA_BACKGROUND_LAUNCH=1, electron-headless). I captured the sidebar once without the fix and once with it.

  • Platforms: macOS (arm64). The change is in platform-independent row planning.

  • I manually tested these changes locally

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

AI Disclosure

Written with Claude (Anthropic) in the omp coding agent. I reviewed the diff and the before/after output.

Review

AI review summary (Claude, path-correctness lens, trace from producer to consumer): no findings. It checked the renderer sidebar consumers and the mobile feed (sidebar-feed-rows.ts → mobile/src/host-screen/host-sidebar-feed-sections.ts), which shows folder-workspace rows under the current section and so gets the same placement.

  • Cross-platform: no platform, path, shell or shortcut code changes. The row planner is platform-independent.
  • SSH/remote/local: folder rows keep their host-qualified keys. The Pinned header's host counts and IDs include folder workspaces, so each host section gets its own Pinned header (tested for an SSH project group). Mixed client and server versions are not affected: no wire format or persisted data changes.
  • Agents and integrations: no agent, provider or git-provider code changes.
  • Performance: one filter and one sort over the folder workspaces each time the planner runs. Lanes already sorted the same list.
  • UI quality: no new components or styles. Pinned folder rows use the existing folder-workspace row and the existing Pinned header. I captured light theme only. The change moves a row and does not change how it looks.
  • Security: no new input, IPC, network, file or persistence paths.

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

  • Cross-platform: no platform-specific code.
  • SSH/remote: folder rows keep their host-qualified keys. Pinned header host counts and IDs include folder workspaces, so each host section gets its own Pinned header.
  • Mobile: the feed uses the same planner. Pinned folder workspaces show under Pinned on mobile too.
  • Backwards compatibility: no persisted data changes. isPinned on folder workspaces already exists.
  • Performance: one filter and sort over the folder workspaces each time the planner runs.

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). Lint, typecheck and build pass locally. The full test suite needs CI; see Testing.

@coderabbitai

coderabbitai Bot commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 922d70bd-696b-4990-9eb3-2ffb7ba7b758
Commits

Reviewing files that changed from the base of the PR and between 0afedab and ff2e601.

Files selected for processing: 5
  • src/renderer/src/components/sidebar/worktree-list/grouping/build-rows.folder-workspace-lanes.test.ts
  • src/renderer/src/components/sidebar/worktree-list/navigation/folder-reveal.test.ts
  • src/renderer/src/components/sidebar/worktree-list/navigation/folder-reveal.ts
  • src/shared/sidebar-list/pinned-group-rows.ts
  • src/shared/sidebar-list/sidebar-row-plan.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

Row planning now sends pinned folder workspaces to the Pinned section and keeps unpinned folders in their regular lanes. The Pinned header includes folder workspaces in its count and host metadata, and the section emits their rows. Folder reveal logic returns the pinned and host-specific group keys. Tests cover grouping modes, collapsed sections, host metadata, and reveal keys.

Priority: Normal

Severity of issue fixed: Medium

Merge Risk: Minimal · up to ff2e6

Pinned folder placement and reveal behavior appear consistent across the inspected paths. No blocking issue remains.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 5 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: moving pinned folder workspaces into the Pinned section.
Linked Issues check Passed Issue #34006 requires pinned folder workspaces to appear in Pinned instead of their project-group lane. planSidebarRows separates pinned folder workspaces from lane folder workspaces, passes only un…
Out of Scope Changes check Passed The changed planner, pinned-section, and folder-reveal code directly supports issue #34006. The added tests verify the required placement, counts, collapse behavior, host scoping, and reveal behavior.…
Description check Passed The pull request description follows the required template and clearly explains the user impact, implementation, rationale, linked issue, visual proof, testing, AI disclosure, compatibility considerat…
Full details: Linked Issues check

Explanation

Issue #34006 requires pinned folder workspaces to appear in Pinned instead of their project-group lane. planSidebarRows separates pinned folder workspaces from lane folder workspaces, passes only unpinned folders to lane builders, and passes pinned folders to emitPinnedGroup. emitPinnedGroup renders the folder rows, includes them in the header count and host metadata, and shows the section when folder pins are the only pinned items. The supplied test summary covers all four grouping modes, single placement, folder-only Pinned, collapse behavior, SSH host metadata, and reveal keys.

Full details: Out of Scope Changes check

Explanation

The changed planner, pinned-section, and folder-reveal code directly supports issue #34006. The added tests verify the required placement, counts, collapse behavior, host scoping, and reveal behavior. No unrelated change is demonstrated. The PR explicitly excludes duplicate pinned copies when the display policy requests group placement.

Full details: Description check

Explanation

The pull request description follows the required template and clearly explains the user impact, implementation, rationale, linked issue, visual proof, testing, AI disclosure, compatibility considerations, and checklist status. The manual-testing checkbox is unchecked, but the description documents automated, visual, platform, SSH, mobile, and CI-related validation in sufficient detail.

  • 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.

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.

[Bug]: Pinned folder workspaces stay in their project group instead of moving to Pinned

1 participant