Skip to content

feat(renderer): show two worktrees side by side in one window - #31016

Open
pointmina wants to merge 5 commits into
stablyai:mainfrom
pointmina:feat/worktree-split-view
Open

pointmina wants to merge 5 commits into
stablyai:mainfrom
pointmina:feat/worktree-split-view

Conversation

@pointmina

@pointmina pointmina commented Oct 20, 2026 •

Copy link
Copy Markdown

ELI5

You can now put two worktrees side by side in one Orca window, the way you'd put two documents next to each other. Both stay live; whichever side you click is the one you type into. If you quit Orca with the split open, it comes back that way.

What Changed

Before: only one worktree is on screen. Watching an agent in one worktree while working in another means flipping back and forth in the sidebar.

After:

  • Right-click a worktree in the sidebar → Open in Split View. The current worktree stays on the left, the chosen one opens on the right. Works across two different repositories.
  • Both halves render live. Clicking a half moves keyboard input (and the "active worktree") to it. A divider between them drags to resize and has a close button; Close Split View is also in the context menu.
  • Activating any worktree outside the pair ends the split. Removing, purging or renaming a worktree in the pair updates or ends the split.
  • After quit and relaunch, the split and the focused side come back on the first frame (no flash of a single worktree). Width resets to 50:50. If a side no longer exists, Orca silently shows just the remaining worktree.

Mechanism:

  • A new store slice holds the pair (worktreeSplitViewPair: left/right worktree id + execution host id). Input ownership is unchanged: it still belongs to activeWorktreeId, which is always one side of the pair.
  • The places that assumed "only the active worktree is visible" now ask isWorktreeSurfaceShown, which also counts the split partner: terminal parking, the parked-watcher sync, browser retention, the on-screen attention scan and agent auto-ack. Without this the partner's terminals would be parked and its agents' notifications treated as unseen.
  • The pair is persisted as an optional field of the workspace session (worktreeSplitViewPair), validated on restore with restorableWorktreeSplitViewPair, and set in the same store update as activeWorktreeId. It is classified in every session field table (host ownership global, not transferred between profiles, not moved by the WSL mover, view for layout-beside).
  • A scoped re-hydration (the SSH pull merge) keeps the live pair unless it moves focus out of it, and a tabless side of a not-yet-listed SSH repo still counts as valid on restore.

Why

Users run agents in parallel worktrees and want to keep an eye on more than one at a time.

Alternatives considered:

  • Reuse the existing in-worktree tab-group split. Tab groups, layouts and tabs are all keyed by worktree, so hosting another worktree's tabs there would mean re-keying a lot of state. Rendering two existing worktree surfaces next to each other reuses them as-is.
  • A second window per worktree. Heavier, and loses the shared sidebar and a single focus model.
  • Persisting the split ratio too. Left out to keep the persisted shape minimal; 50:50 on restore is predictable.

The new session field is optional, so sessions written by older builds load unchanged and older peers ignore it.

Linked Issue

Fixes #31015

Visual Proof

Same seeded repo, captured from the Electron E2E harness (prompt shortened, first-run onboarding hints hidden).

Before: one worktree on screen After: two worktrees side by side
before after

Testing

Verified on macOS through the Electron E2E runs below (local worktrees, and two worktrees from different repositories), including a screenshot of the restored split after relaunch. Not run on Linux, Windows or a live SSH host; the SSH restore paths are covered by unit tests.

  • I manually tested these changes locally
  • Automated tests added/updated, or explained why not below

Automated:

  • Unit: worktree-split-view.test.ts (slice), worktree-split-view-pair.test.ts (restore validation), worktree-split-view-session-restore.test.ts (restore in the same update, missing side, old sessions, SSH repo not yet listed, scoped merge in/out of the pair, persistence, trip to settings), plus the session field-coverage tests.
  • E2E (--project electron-headless): worktree-split-view.spec.ts (side by side + input follows the click; two repositories) and worktree-split-view-restart.spec.ts (quit and relaunch restores both sides and the focused side).
  • Locally on macOS: pnpm lint, pnpm tc, the affected unit tests (1,268 files) and the desktop build (build:desktop, including the mobile web bundle) pass.
  • Not green locally, both unrelated to this change and left to CI: a handful of shell/PTY/packaging unit tests that fail on this machine's environment, and build:native, where the macOS Swift helpers fail because the local Xcode Command Line Tools install is broken (swift-package aborts with a missing symbol). This PR touches no native or Swift code.

AI Disclosure

Implemented with Claude Code (Claude Opus 5.5), including the tests. An independent agent review was run on the branch; its two medium findings are fixed in the last commit.

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

Ensure no issues in: Security, Cross-platoform support (Linux, Windows, Mac), Remote SSH, Mobile, general backwards compatibility, performance

  • Cross-platform: no platform-specific code or shortcuts were added.
  • SSH: each side carries its own execution host id; restore does not wait for the SSH host to connect.
  • Backwards compatibility: optional session field, salvaged on parse; no wire or opcode changes.
  • Mobile: unaffected (desktop renderer only).

Checklist

  • 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)
  • This PR is small and focused
  • pnpm lint, pnpm typecheck, pnpm test, and pnpm build pass (or CI will cover; local preferred)

🤖 Generated with Claude Code

pointmina and others added 5 commits October 20, 2026 13:52
Right-click a worktree in the sidebar and choose "Open in Split View" to
show it beside the active one. Whichever side was clicked last becomes the
active worktree, so the sidebar, shortcuts and Cmd+S follow it; the other
side stays painted and live but does not own focus or shortcuts.

- New worktree-split-view slice stores the left/right pair (with each
  side's execution host) and the divider ratio. Not persisted yet.
- Surfaces stay siblings ordered with CSS `order` and a container CSS
  variable, so switching sides or dragging never remounts a workspace.
- The partner is exempt from terminal parking, browser guest eviction,
  agent auto-ack and on-screen attention scans like the active one.
- Removing, renaming or host-twin purging a paired worktree clears or
  re-points the pair.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Activating a worktree outside the pair now ends the split, so a stale pair
no longer keeps two panes or hides "Open in Split View". Adds a close button
on the divider and shows "Close Split View" only while the split is on screen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The side-by-side pair is now saved in the workspace session and restored
in the same hydration update as the active worktree, so the first frame
already shows both halves. A pair whose side no longer exists, or that no
longer holds the active worktree, is dropped silently. The divider ratio
is not saved; a restored split starts at 50:50.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A scoped session merge could move focus outside the pair while leaving
the pair set, and a tabless side of a not-yet-listed SSH repo failed
restore validation, dropping the split before the host connected.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@pointmina
pointmina marked this pull request as ready for review October 20, 2026 07:11
@coderabbitai

coderabbitai Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

📝 Walkthrough

The change adds side-by-side display for two worktrees in one window. Users can open or close the split from the worktree context menu and resize it with a divider. The active worktree controls workspace input, while both surfaces can remain visible. The split pair is stored in workspace sessions and restored when its worktrees are valid. Worktree lifecycle, terminal visibility, retention, and on-screen target tracking now account for the split partner.

Priority: ➖ Normal

Severity of issue fixed: Medium

Merge Risk: 🔵 Low · up to ac726

A tabless SSH split may reopen with only one side visible, and the cross-repository test may fail during cleanup on Windows. Fix these paths before merging if support for those cases is required in this release.

Pre-merge checks: Passed 4 · Inconclusive 1

Failed Failed checks: 1 inconclusive

Check name Status Explanation Resolution
Docstring Coverage Inconclusive Docstring coverage is 47.06% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 51 functions across 50 files. (14 skipped… 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 primary change: displaying two worktrees side by side in one window.
Description check Passed The description includes all required sections, explains the user-visible behavior and implementation, links issue #31015, provides visual proof, documents testing and known environment failures, and …
Linked Issues check Passed Issue #31015 requires split rendering, input focus by side, divider and close controls, lifecycle cleanup, persistence, restore validation, 50:50 reset, cross-repository support, and SSH support. The …
Out of Scope Changes check Passed The changed files support issue #31015. Store, renderer, persistence, schema, session-field classification, localization, terminal visibility, and agent attention changes implement split-view behavior…
Full details: Description check

Explanation

The description includes all required sections, explains the user-visible behavior and implementation, links issue #31015, provides visual proof, documents testing and known environment failures, and addresses compatibility concerns. The unchecked manual-testing and small-focused checkboxes do not prevent the description from being mostly complete.

Full details: Linked Issues check

Explanation

Issue #31015 requires split rendering, input focus by side, divider and close controls, lifecycle cleanup, persistence, restore validation, 50:50 reset, cross-repository support, and SSH support. The PR adds the split-view store and UI, updates surface visibility and terminal retention, handles activation, removal, purge, and rename, and persists the pair with execution-host IDs. restorableWorktreeSplitViewPair validates both sides and the active side. Hydration includes tabless SSH worktree IDs and restores the pair in the same update as activeWorktreeId. Unit and Electron E2E tests cover the stated behavior.

Full details: Out of Scope Changes check

Explanation

The changed files support issue #31015. Store, renderer, persistence, schema, session-field classification, localization, terminal visibility, and agent attention changes implement split-view behavior or preserve existing behavior for the second visible worktree. The added unit and E2E tests verify these objectives. No unrelated change is demonstrated by the reviewed summary or focused source inspection.

Full details: Docstring Coverage

Explanation

Docstring coverage is 47.06% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 51 functions across 50 files. (14 skipped: 6 unsupported, 8 over the file limit.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

  • 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: 2


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 51242b0f-93c9-4b5b-b2e5-08c91327ca6f
📥 Commits

Reviewing files that changed from the base of the PR and between d6707ff and ac726e5.

📒 Files selected for processing: 64
  • src/main/orca-profiles/profile-project-session-field-disposition.ts
  • src/main/persistence/restoring-sessions/session-worktree-ownership.ts
  • src/renderer/src/components/TerminalSplitWorkspaceSurfaces.tsx
  • src/renderer/src/components/TerminalWorktreeSplitSurface.tsx
  • src/renderer/src/components/WorkspacePaneOverlayLayers.tsx
  • src/renderer/src/components/browser-pane/assemble-chrome/BrowserPaneOverlayLayer.tsx
  • src/renderer/src/components/native-chat/StructuredAgentSessionPaneOverlayLayer.tsx
  • src/renderer/src/components/sidebar/WorktreeContextMenuView.tsx
  • src/renderer/src/components/sidebar/WorktreeSplitViewMenuItems.tsx
  • src/renderer/src/components/tab-group/TabGroupSplitLayout.tsx
  • src/renderer/src/components/tab-group/TabGroupSplitNodeTree.tsx
  • src/renderer/src/components/terminal-cold-activation.ts
  • src/renderer/src/components/terminal-pane/TerminalPaneOverlayLayer.tsx
  • src/renderer/src/components/terminal-pane/use-manual-terminal-worktree-parking.ts
  • src/renderer/src/components/terminal-parked-watcher-sync-entries.test.tsx
  • src/renderer/src/components/terminal-parking-pass-candidates.ts
  • src/renderer/src/components/terminal/initial-terminal-admission-wait.test.tsx
  • src/renderer/src/components/terminal/initial-terminal-structured-launch.test.tsx
  • src/renderer/src/components/use-terminal-browser-retention.ts
  • src/renderer/src/components/use-terminal-parking-foundation.ts
  • src/renderer/src/components/use-terminal-parking-pass.ts
  • src/renderer/src/components/use-terminal-watcher-effects.ts
  • src/renderer/src/components/use-terminal-workspace-foundation.ts
  • src/renderer/src/components/worktree-split-view-divider.tsx
  • src/renderer/src/hooks/agent-auto-ack-targets.test.ts
  • src/renderer/src/hooks/agent-auto-ack-targets.ts
  • src/renderer/src/hooks/on-screen-attention-scan.ts
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/i18n/locales/es.json
  • src/renderer/src/i18n/locales/fr.json
  • src/renderer/src/i18n/locales/ja.json
  • src/renderer/src/i18n/locales/ko.json
  • src/renderer/src/i18n/locales/zh.json
  • src/renderer/src/lib/workspace-session-patch.ts
  • src/renderer/src/lib/workspace-session-relevant-fields.test.ts
  • src/renderer/src/lib/workspace-session-sanitized-tabs.ts
  • src/renderer/src/lib/workspace-session.test.ts
  • src/renderer/src/lib/workspace-session.ts
  • src/renderer/src/store/index.ts
  • src/renderer/src/store/slices/store-test-helpers.ts
  • src/renderer/src/store/slices/workspace-attention/workspace-unread-flag.ts
  • src/renderer/src/store/slices/worktree-split-view-session-restore.test.ts
  • src/renderer/src/store/slices/worktree-split-view.test.ts
  • src/renderer/src/store/slices/worktree-split-view.ts
  • src/renderer/src/store/slices/worktrees/session/set-active-worktree.ts
  • src/renderer/src/store/slices/worktrees/session/worktree-identity-rename-state.ts
  • src/renderer/src/store/slices/worktrees/teardown/host-twin-worktree-purge.ts
  • src/renderer/src/store/slices/worktrees/teardown/remove-worktree-store-cleanup.ts
  • src/renderer/src/store/slices/worktrees/teardown/worktree-purge-state.ts
  • src/renderer/src/store/terminals/workspace-terminal-hydration-patch.ts
  • src/renderer/src/store/terminals/workspace-terminal-hydration.ts
  • src/renderer/src/store/types.ts
  • src/shared/execution-host-id-schema.ts
  • src/shared/workspace-layout/workspace-layout-beside.ts
  • src/shared/workspace-layout/workspace-layout-profile.test-fixture.ts
  • src/shared/workspace-session-host-field-ownership.ts
  • src/shared/workspace-session-schema-field-coverage.test.ts
  • src/shared/workspace-session-schema.ts
  • src/shared/workspace-session-state-types.ts
  • src/shared/worktree-split-view-pair.test.ts
  • src/shared/worktree-split-view-pair.ts
  • src/shared/wsl-move/wsl-move-dispositions.ts
  • tests/e2e/worktree-split-view-restart.spec.ts
  • tests/e2e/worktree-split-view.spec.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.

Comment on lines +57 to +66
// Why the pair too: a tabless side of a not-yet-listed SSH repo must still restore.
[
...collectPersistedWorktreeIdsForSessionHydration(session),
...(session.worktreeSplitViewPair
? [
session.worktreeSplitViewPair.leftWorktreeId,
session.worktreeSplitViewPair.rightWorktreeId
]
: [])
]

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🔎 Supported by static analysis

🏁 Script executed:

sed -n '1,180p' src/renderer/src/store/terminals/workspace-terminal-ssh-placeholders.ts
sed -n '32,95p' src/shared/worktree/degraded-repo-worktree-validity.ts
sed -n '45,100p' src/renderer/src/store/terminals/workspace-terminal-hydration.ts
sed -n '40,82p' src/renderer/src/components/use-terminal-workspace-foundation.ts
sed -n '62,88p' src/renderer/src/store/slices/worktree-split-view-session-restore.test.ts

Repository: stablyai/orca

Length of output: 11626


🏁 Script executed:

set -o pipefail
printf '%s\n' '--- PR diff for hydration and placeholder paths ---'
git diff --no-ext-diff --unified=35 23d68112df3d8dd1c7bc3707a793dac1d31d3072 ac726e5e18d72dcc4337284f4ad5efb38d23c90d -- \
  src/renderer/src/store/terminals/workspace-terminal-hydration.ts \
  src/renderer/src/store/terminals/workspace-terminal-ssh-placeholders.ts \
  src/shared/worktree/degraded-repo-worktree-validity.ts \
  src/shared/worktree-split-view-pair.ts
printf '%s\n' '--- bound symbols and call sites ---'
rg -n -F --glob '*.ts' -e 'addHydratedSshWorktreePlaceholders' -e 'buildValidWorktreeIdsForSessionHydration' -e 'restorableWorktreeSplitViewPair' -e 'detectedWorktreesByRepo' src || test "$?" -eq 1
printf '%s\n' '--- hydration owner and relevant tests ---'
sed -n '1,220p' src/renderer/src/store/terminals/workspace-terminal-hydration.ts
sed -n '1,180p' src/shared/worktree/degraded-repo-worktree-validity.ts
sed -n '1,140p' src/shared/worktree-split-view-pair.ts
sed -n '1,260p' src/renderer/src/store/slices/worktree-split-view-session-restore.test.ts

Repository: stablyai/orca

Length of output: 41871


🏁 Script executed:

set -o pipefail
printf '%s\n' '--- split-pair lifecycle bindings ---'
rg -n -F --glob '*.ts' -e 'worktreeSplitViewPair' -e 'closeWorktreeSplitView' -e 'splitPartnerWorktreeId' src/renderer/src/store src/renderer/src/components src/shared | head -240
printf '%s\n' '--- detected-listing type and merge paths ---'
rg -n -F --glob '*.ts' -e 'export type DetectedWorktreeListResult' -e 'interface DetectedWorktreeListResult' -e 'authoritative:' -e 'worktreesByRepo:' src/shared src/renderer/src/store/slices/worktrees src/renderer/src/store/repos | head -240
sed -n '1,280p' src/renderer/src/store/slices/worktrees/listing/fetched-worktree-merge.ts
sed -n '1,180p' src/renderer/src/store/slices/worktrees/session/worktree-slice-initial-state.ts

Repository: stablyai/orca

Length of output: 32276


🏁 Script executed:

set -o pipefail
printf '%s\n' '--- authoritative removal and split cleanup ---'
rg -n -F --glob '*.ts' -e 'splitViewPairAfterRemoval' -e 'buildWorktreePurgeState' -e 'getRemovedWorktreeIdsAfterAuthoritativeScan' -e 'hasIndexedDetectedWorktree' src/renderer/src/store/slices src/renderer/src/lib
printf '%s\n' '--- purge state and split-removal callers ---'
sed -n '1,220p' src/renderer/src/store/slices/worktrees/teardown/worktree-purge-state.ts
sed -n '1,190p' src/renderer/src/store/slices/worktree-split-view.ts
printf '%s\n' '--- remainder of fetched merge ---'
sed -n '230,340p' src/renderer/src/store/slices/worktrees/listing/fetched-worktree-merge.ts
printf '%s\n' '--- detected result contract ---'
sed -n '250,300p' src/shared/worktree/types.ts

Repository: stablyai/orca

Length of output: 26616


Materialize tabless SSH pair sides as provisional placeholders.

buildValidWorktreeIdsForSessionHydration admits the pair IDs while the SSH listing is unavailable, but addHydratedSshWorktreePlaceholders only examines tabsByWorktree. A tabless side therefore remains in worktreeSplitViewPair but has no worktree surface, so the restored split does not render both sides.

Pass only pair IDs that survived validWorktreeIds into the placeholder helper. Do not pass every raw pair ID, because an authoritative listing can already prove that a side was deleted. Later authoritative removal already purges the placeholder and clears the pair.

Suggested fix
diff --git a/src/renderer/src/store/terminals/workspace-terminal-ssh-placeholders.ts b/src/renderer/src/store/terminals/workspace-terminal-ssh-placeholders.ts
--- a/src/renderer/src/store/terminals/workspace-terminal-ssh-placeholders.ts
+++ b/src/renderer/src/store/terminals/workspace-terminal-ssh-placeholders.ts
@@ -45,10 +45,15 @@ export function addHydratedSshWorktreePlaceholders(
   repos: readonly Repo[],
   sourceWorktreesByRepo: Record<string, Worktree[]>,
-  tabsByWorktree: Record<string, TerminalTab[]>
+  tabsByWorktree: Record<string, TerminalTab[]>,
+  additionalWorktreeIds: Iterable<string> = []
 ): Record<string, Worktree[]> {
   const sshRepoIds = new Set(repos.filter((repo) => repo.connectionId).map((repo) => repo.id))
   // Why copy-on-write: hydration writes this map straight to the store; an unconditional copy
   // rerendered every whole-map selector on every hydration with no data change.
   let worktreesByRepo = sourceWorktreesByRepo
-  for (const worktreeId of Object.keys(tabsByWorktree)) {
+  const hydratedWorktreeIds = new Set([
+    ...Object.keys(tabsByWorktree),
+    ...additionalWorktreeIds
+  ])
+  for (const worktreeId of hydratedWorktreeIds) {
diff --git a/src/renderer/src/store/terminals/workspace-terminal-hydration.ts b/src/renderer/src/store/terminals/workspace-terminal-hydration.ts
--- a/src/renderer/src/store/terminals/workspace-terminal-hydration.ts
+++ b/src/renderer/src/store/terminals/workspace-terminal-hydration.ts
@@ -128,10 +128,19 @@ export function createWorkspaceTerminalHydrationActions(
           tabsByWorktree,
           activeWorktreeId,
           activeTabId
         })
+        const splitPairWorktreeIds = session.worktreeSplitViewPair
+          ? [
+              session.worktreeSplitViewPair.leftWorktreeId,
+              session.worktreeSplitViewPair.rightWorktreeId
+            ].filter((worktreeId) => validWorktreeIds.has(worktreeId))
+          : []
         const worktreesByRepo = addHydratedSshWorktreePlaceholders(
           runtimeSessionPlaceholders.repos,
           runtimeSessionPlaceholders.worktreesByRepo,
-          tabsByWorktree
+          tabsByWorktree,
+          splitPairWorktreeIds
         )

Comment on lines +142 to +147
} finally {
await orcaPage
.evaluate(() => window.__store?.getState().closeWorktreeSplitView())
.catch(() => undefined)
rmSync(tempRoot, { recursive: true, force: true })
}

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.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Move the temporary-repository removal to after Electron shuts down.

The test adds secondRepositoryPath to the running app through addRepoPath, so Orca watches that folder. The finally block then calls rmSync(tempRoot, ...) while the electronApp fixture is still alive. On Windows, watched worktrees stay locked until Electron and its daemons exit. In that state, rmSync throws EBUSY or EPERM, and force: true does not suppress that error. The test then fails in cleanup even when every split-view assertion passed.

The orca-app fixture provides registerPostElectronShutdownCleanup for this case. Request that fixture and register the removal through it.

Proposed fix
-test('splits worktrees from two different repositories', async ({ orcaPage }) => {
+test('splits worktrees from two different repositories', async ({
+  orcaPage,
+  registerPostElectronShutdownCleanup
+}) => {
   test.setTimeout(180_000)
 ...
   const tempRoot = mkdtempSync(path.join(os.tmpdir(), 'orca-e2e-split-view-'))
+  registerPostElectronShutdownCleanup(async () => {
+    rmSync(tempRoot, { recursive: true, force: true })
+  })
 ...
   } finally {
     await orcaPage
       .evaluate(() => window.__store?.getState().closeWorktreeSplitView())
       .catch(() => undefined)
-    rmSync(tempRoot, { recursive: true, force: true })
   }

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.

Show two worktrees side by side in one window (split view)

1 participant