Skip to content

Open each worktree in its own Zed window#417

Closed
blacroix wants to merge 3 commits into
supabitapp:mainfrom
blacroix:zed-window-per-worktree
Closed

Open each worktree in its own Zed window#417
blacroix wants to merge 3 commits into
supabitapp:mainfrom
blacroix:zed-window-per-worktree

Conversation

@blacroix

@blacroix blacroix commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Fixes #399

What

Opening a worktree in Zed now gives one Zed window per worktree instead of collapsing every worktree into a single shared window — matching how VS Code already behaves.

  • Open a worktree → it gets its own Zed window.
  • Open a worktree that's already open → Zed focuses the existing window (no duplicate).
  • Open a different worktree → a separate new window.

⚠️ Requires a Zed setting

This relies on Zed's cli_default_open_behavior being set to new_window (Zed's own default is existing_window, which is what causes the collapse). Set it via:

  • zed://settings/cli_default_open_behavior, or
  • Zed → Settings (settings.json):
    "cli_default_open_behavior": "new_window"

With the default existing_window, worktrees keep collapsing into one window.

How (briefly)

Previously the worktree was opened with NSWorkspace.open(...), which sends macOS an "open document" event — Zed treats that as "add this folder to my most-recent window", hence the collapse.

This switches the Zed path to launch Zed's bundled CLI (Zed.app/Contents/MacOS/cli) with just the worktree path. With cli_default_open_behavior: new_window, the CLI opens a fresh window per worktree and focuses the existing one when the worktree is already open.

Note: the -n / --new flag is intentionally not used — it forces a brand-new window every time, so re-opening an already-open worktree would spawn duplicates. The bare-path + setting combination is the only one that gives "new window, or focus if already open". If the CLI helper is ever missing, it falls back to the previous NSWorkspace.open behavior.

Tests

Added ZedLaunchTests covering the launch decision: CLI path resolution, CLI invocation with the bare worktree path (guards against a -n regression), and the NSWorkspace.open fallback when the CLI is absent.

Screen recording

Screen.Recording.2026-06-19.at.09.42.27.mp4

NSWorkspace.open hands the worktree directory to Zed as an "open document"
event, so every worktree collapses into Zed's most-recent window. Launch the
bundled Zed CLI (Zed.app/Contents/MacOS/cli) with the bare worktree path
instead: with Zed's `cli_default_open_behavior` set to `new_window`, that opens
one window per worktree and focuses the existing window when the worktree is
already open. Falls back to NSWorkspace.open when the CLI helper is absent.

The `-n` flag is deliberately not used: it forces a brand-new window even for an
already-open worktree, producing duplicates.
@blacroix blacroix marked this pull request as ready for review June 19, 2026 07:45
@sbertix

sbertix commented Jun 19, 2026

Copy link
Copy Markdown
Collaborator

Nice 💪 only thing, could we have this a bit more "generic"? So it's not just "Zed" and we ideally can reuse this for any arbitrary app requiring/enhanced by a command line?

@blacroix

Copy link
Copy Markdown
Contributor Author

📚 Companion docs PR: supabitapp/docs.supacode.sh#1 — documents the required cli_default_open_behavior: new_window Zed setting.

@sbertix

sbertix commented Jun 19, 2026

Copy link
Copy Markdown
Collaborator

Could you check if the generalization in #423 still works for you? It worked fine on my devices, but I just wanted to double-check. Apologies for this, but together with #420, it made sense to just tackle them at once with a more coordinated effort.

Replace the Zed-specific launcher with a generic seam: an optional CLILauncher
descriptor on OpenWorktreeAction (relative path to the app's bundled CLI helper
plus any flags) and an AppLauncher that prefers a CLI launch when an app
advertises one, otherwise falls back to NSWorkspace.open. Adding another
CLI-capable app is now just returning a CLILauncher from `cliLauncher`.

Only Zed is wired up for now; enabling other apps (VS Code, Cursor, …) needs
per-app verification of their new-window semantics.
@blacroix

Copy link
Copy Markdown
Contributor Author

@sbertix good call — generalized it 👍

Opening now goes through a small generic seam instead of a Zed-specific path:

  • OpenWorktreeAction.cliLauncher — an optional descriptor (relative path to the app's bundled CLI helper + any flags).
  • AppLauncher prefers a CLI launch when an app advertises one, otherwise falls back to NSWorkspace.open.

Adding another CLI-capable app is now just returning a CLILauncher from cliLauncher — no new launch code. Only Zed is wired up for now (Contents/MacOS/cli), since enabling others (VS Code, Cursor, …) needs per-app verification of their new-window semantics. Pushed in the follow-up commit.

@sbertix

sbertix commented Jun 19, 2026

Copy link
Copy Markdown
Collaborator

I guess the previous comment slipped through 😅 this indeed ended up being a superset of #423, so I guess I'm merging that. Thanks and sorry for the back and forth

@sbertix sbertix closed this in #423 Jun 19, 2026
@blacroix

Copy link
Copy Markdown
Contributor Author

I guess the previous comment slipped through 😅 this indeed ended up being a superset of #423, so I guess I'm merging that. Thanks and sorry for the back and forth

Sorry for that, didn't see your comment on time! Got the PR ready after your comment 🥷

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.

Open Zed in a new window (per worktree)

2 participants