Skip to content

fix(sidebar): activate the chosen host when a grouped workspace switches hosts - #21

Merged
nplez1 merged 1 commit into
nplez1/mainfrom
nplez1/Stacked-Workspace-Switch
Sep 22, 2026
Merged

nplez1 merged 1 commit into
nplez1/mainfrom
nplez1/Stacked-Workspace-Switch

Conversation

@nplez1

@nplez1 nplez1 commented Sep 22, 2026 •

Copy link
Copy Markdown
Owner
Files Added Deleted Net
Test 1 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​114 0 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​114
Prod 2 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​67 $\color{#cf222e}{\Huge{\mathbf{−}}}$​7 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​60

ELI5

When the same branch is checked out on two machines, the sidebar shows them as one card with a small dropdown to pick the machine. Picking a different machine changed what the card showed, but the app stayed "on" the old machine, so nothing in the list looked selected anymore. Now picking a machine also switches the app to that machine's copy.

What Changed

Before: with Workspaces grouped by Project and "Group by branch" on, selecting a consolidated card and then changing the host dropdown swapped the card to the new host's workspace, but the card appeared unselected. The previously active workspace — whose row is merged into that same card — had no visible selection anywhere in the list.

After: changing the dropdown makes the chosen host's workspace the active workspace, so the card stays selected and its status, branch, PR, tabs and agents follow it.

Mechanism: the dropdown only wrote the ephemeral branchGroupHostByKey slice field that decides which member a consolidated card renders. The host-switch path now also runs the same activation a card click uses (activateWorktreeFromSidebar(worktree.id, hostId)) plus the click-path immediate marking. The member is resolved by branch group key + host from the row's branchGroup, not by row.worktree, because a merged row always stores its local-first member while the card can be displaying any host.

Why

The alternative was to make the store's setBranchGroupHost setter activate the workspace itself. That setter is a pure state mutation shared with the tab strip, so putting activation side effects inside it is a layering problem and would also fire while state is being rehydrated. Activating on the interaction path keeps the setter pure and reuses the existing activation flow.

Linked Issue

Issues are disabled in this fork, so there is no issue to link. Follow-up to the Group by branch host dropdown introduced in #14.

Related: #14

Visual Proof

N/A — reproducing needs two workspaces on the same branch on two different hosts, and the change alters selection/activation behavior rather than adding or moving any visual element. Covered by the new unit tests.

Testing

  • pnpm test src/renderer/src/components/sidebar/worktree-list/viewport/use-branch-group-host-selection.test.ts — 4 passed (non-primary member resolves and activates with the correct hostId; host choice still recorded when the row is gone).

  • pnpm test src/renderer/src/components/sidebar — 315 files / 2661 tests passed.

  • pnpm tc, oxfmt --check, and pnpm run check:code-quality:changed are clean.

  • Platforms: renderer logic only, no platform-specific code. Host switching passes the member's execution host id through the same path as a card click, so remote/SSH hosts are covered by construction.

  • I manually tested these changes locally

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

AI Disclosure

N/A — internal contributor.

Review

Agent skill upstream boundary

  • Not applicable, or this change follows docs/reference/agent-skill-sharing-upstream-boundary.md and copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.

Notes

Security: no new inputs or data flows; the handler is a lookup over already-rendered rows. Performance: O(rows) only on dropdown click, and the returned handler stays referentially stable so memoized cards do not re-render. Cross-platform / SSH: activation goes through activateWorktreeFromSidebar with the member's hostId, matching the card-click path used for remote hosts.

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)

…osts

Changing the host dropdown on a Group by branch card only updated which host
the merged card rendered; the active workspace stayed on the previous host.
That sibling's row is merged into the same card, so the list then showed
nothing active and the card rendered unselected.

Selecting a host now also activates that member's workspace, using the same
path as a card click. The member is resolved by branch group key + host,
because a merged row always stores its local-first member while the card can
be showing any host.
@nplez1
nplez1 merged commit c65b0e1 into nplez1/main Sep 22, 2026
30 checks passed
nplez1 added a commit that referenced this pull request Sep 22, 2026
…osts (#21)

Changing the host dropdown on a Group by branch card only updated which host
the merged card rendered; the active workspace stayed on the previous host.
That sibling's row is merged into the same card, so the list then showed
nothing active and the card rendered unselected.

Selecting a host now also activates that member's workspace, using the same
path as a card click. The member is resolved by branch group key + host,
because a merged row always stores its local-first member while the card can
be showing any host.
nplez1 added a commit that referenced this pull request Sep 25, 2026
…osts (#21)

Changing the host dropdown on a Group by branch card only updated which host
the merged card rendered; the active workspace stayed on the previous host.
That sibling's row is merged into the same card, so the list then showed
nothing active and the card rendered unselected.

Selecting a host now also activates that member's workspace, using the same
path as a card click. The member is resolved by branch group key + host,
because a merged row always stores its local-first member while the card can
be showing any host.
nplez1 added a commit that referenced this pull request Sep 27, 2026
…osts (#21)

Changing the host dropdown on a Group by branch card only updated which host
the merged card rendered; the active workspace stayed on the previous host.
That sibling's row is merged into the same card, so the list then showed
nothing active and the card rendered unselected.

Selecting a host now also activates that member's workspace, using the same
path as a card click. The member is resolved by branch group key + host,
because a merged row always stores its local-first member while the card can
be showing any host.
nplez1 added a commit that referenced this pull request Sep 29, 2026
…osts (#21)

Changing the host dropdown on a Group by branch card only updated which host
the merged card rendered; the active workspace stayed on the previous host.
That sibling's row is merged into the same card, so the list then showed
nothing active and the card rendered unselected.

Selecting a host now also activates that member's workspace, using the same
path as a card click. The member is resolved by branch group key + host,
because a merged row always stores its local-first member while the card can
be showing any host.
nplez1 added a commit that referenced this pull request Oct 1, 2026
…osts (#21)

Changing the host dropdown on a Group by branch card only updated which host
the merged card rendered; the active workspace stayed on the previous host.
That sibling's row is merged into the same card, so the list then showed
nothing active and the card rendered unselected.

Selecting a host now also activates that member's workspace, using the same
path as a card click. The member is resolved by branch group key + host,
because a merged row always stores its local-first member while the card can
be showing any host.
nplez1 added a commit that referenced this pull request Oct 6, 2026
…osts (#21)

Changing the host dropdown on a Group by branch card only updated which host
the merged card rendered; the active workspace stayed on the previous host.
That sibling's row is merged into the same card, so the list then showed
nothing active and the card rendered unselected.

Selecting a host now also activates that member's workspace, using the same
path as a card click. The member is resolved by branch group key + host,
because a merged row always stores its local-first member while the card can
be showing any host.
nplez1 pushed a commit that referenced this pull request Oct 19, 2026
…iew off the deprecated owner resolver (stablyai#30562)

* refactor(renderer): fold browser creation, file actions and doc-preview callers off the deprecated owner resolver

The creation-action policy and browser creation (#3, #48) fold together, so the provider the
policy offers is the one creation uses. Browser panes, page lifecycle and conversion, tab
duplication, the explorer tree pane, doc-preview actions and editor path moves (#21, #43, #45-#47,
#49, #50) read runtimeEnvironmentIdWithLegacyFallbackUnlessTwin. File-explorer writes on a folder
(#51) take the owner from the rows alone, never from the focused server. Deprecated importers
16 -> 6.

* refactor(renderer): fold file preview off the deprecated owner resolver; Open in Orca Browser refuses a twin

A project two hosts publish reads as no server for the doc-preview plan, but the file:// path now
refuses it with its own message instead of opening this machine's copy (#7). Deprecated importers
6 -> 5.

* fix(renderer): a twin's file preview and open-externally refuse instead of opening this machine's copy

Codex P2 on the F7 folds: a folder twin read as no server, so the preview plan built a local
file:// tab and open-externally handed the path to this machine's OS. Both now check the owner
for ambiguity first. Also fix two test fixtures that broke the renderer typecheck.

* refactor(renderer): move the file:// open target out of file-preview.ts

file-preview.ts crossed its line limit after main grew it; the file:// target, its type and its two
refusal messages move to workspace-file-browser-open-target.ts, which they never depended on
file-preview for.

* test: mock the replacement resolver in the quick-action availability suite (Codex P2)
@nplez1
nplez1 deleted the nplez1/Stacked-Workspace-Switch branch October 24, 2026 03:23
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.

1 participant