Contributing: use a branch + pull request into main — see CONTRIBUTING.md.
A Spec Kit extension for default-on git worktree isolation — work on multiple features (or run parallel agents) without checkout switching.
The community spec-kit-worktree extension is a good starting point. This extension differs in three ways:
- Default-on — worktrees are created automatically after
/speckit.specify. Opt out with--in-place, rather than opting in. - Nested layout by default — worktrees live at
.worktrees/<branch>/inside the repo (gitignored, self-contained). Sibling-dir layout (../<repo>--<branch>) is available as an option for IDE-per-feature workflows. - Deterministic bash script — a real script (
create-worktree.sh) with--jsonoutput,--dry-run,--base-ref, andSPECIFY_WORKTREE_PATHoverride, suitable for CI and scripted workflows.
This extension does not change another extension’s configuration on install (for example it does not disable the Git extension’s hooks). You opt into hook changes explicitly in .specify/extensions.yml when you need them (see below).
specify extension add worktrees --from https://github.com/dango85/spec-kit-worktree-parallel/archive/refs/tags/v1.3.2.zipCursor implements editor-native isolation: /worktree keeps the rest of that chat in a separate checkout, with optional .cursor/worktrees.json to run setup (deps, env files) using $ROOT_WORKTREE_PATH. See the official Cursor worktrees documentation and the Cursor CLI --worktree flag for the same behavior outside the UI.
- Start the feature with
/worktree …(or/best-of-nwhen comparing models). That aligns agent tools and cwd with Cursor’s isolated checkout. - Add
.cursor/worktrees.jsonat your main project root so each new checkout gets a working dev environment (copy.env, install packages, migrations, etc.). Copy and editexamples/cursor-worktrees.spec-kit.example.jsonfrom this repo as a starting point for Spec Kit repos. - Run
/speckit.specify, then plan / tasks / implement in the same chat so spec artifacts and edits stay in that checkout.
| Mechanism | Who creates it | Typical use |
|---|---|---|
Cursor /worktree |
Cursor (~/.cursor/worktrees, cleanup, setup hooks) |
Best default for Cursor users — session root matches isolation. |
This extension (after_specify) |
git worktree add under .worktrees/ or sibling dirs |
In-repo worktrees, CLI/CI, non-Cursor editors, list/clean helpers. |
Using both at once for the same feature usually adds confusion (two different worktree locations and mental models). For Cursor-heavy teams:
- Prefer
/worktree+.cursor/worktrees.jsonfor isolation, and setauto_create: falseinworktree-config.ymlso this extension does not also spawn an in-repo worktree after every specify — invoke/speckit.worktrees.createmanually when you still want a git worktree inside the repo (e.g. sibling layout for a second IDE window).
If you keep auto_create: true, you still get in-repo worktrees after specify; treat that as the non-Cursor or second checkout path and understand specs may land on the primary tree first (see Parallel agents and the Git extension below).
- Cursor: isolation + agent focus →
/worktree+worktrees.json. - This extension:
git worktreeautomation, dashboards, cleanup — complements Cursor; it does not replace Cursor’s chat root behavior.
Worktrees live inside the repo under .worktrees/ (auto-gitignored):
my-project/
├── .worktrees/
│ ├── 005-user-auth/ ← worktree
│ ├── 006-chat/ ← worktree
├── specs/
├── src/
Self-contained — everything stays in one directory. .worktrees/ is added to .gitignore at install time so worktree directories are never accidentally committed to the main repo. Work inside each worktree is committed on its own feature branch.
Each worktree is a sibling directory of the primary clone:
parent/
├── my-project/ ← primary checkout (main)
├── my-project--005-user-auth/ ← worktree (005-user-auth branch)
├── my-project--006-chat/ ← worktree (006-chat branch)
Open each directory in its own IDE window. Switch with layout: "sibling" in worktree-config.yml.
Git extension vs git on your PATH: This extension requires the git CLI only. It does not require the Spec Kit Git extension (speckit.git.*). That distinction matters because the Git extension registers before_specify → speckit.git.feature, which runs git checkout / git checkout -b on whatever directory the agent is using as the repo root. On a shared primary clone, that moves HEAD for everyone and fights parallel worktrees.
What this extension does instead: create-worktree.sh uses git worktree add (and git worktree add -b for a new branch). That creates the feature branch inside the new worktree and leaves the primary checkout’s HEAD alone.
If the Git extension is installed and you want a stable primary checkout: edit .specify/extensions.yml and set enabled: false on the before_specify entry whose extension is git and command is speckit.git.feature. Your file may include extra keys (optional, prompt, …); only enabled needs to change.
hooks:
before_specify:
- extension: git
command: speckit.git.feature
enabled: false
optional: false
# …other keys from your install stay as-is…After disabling that hook, feature branch naming is no longer applied by speckit.git.feature before specify. Use create-new-feature.sh --dry-run --json from the Git extension if you still want the same numbering without a checkout, or agree on branch names in the specify step. Branch from current HEAD when creating a worktree: pass --base-ref HEAD to create-worktree.sh (default base is main / origin/main when present).
after_specify ordering: This extension’s hook runs after /speckit.specify. Spec files are written to the current working tree first, then the worktree is created. For full isolation, run specify from the worktree root (worktree-first workflow). A Spec Kit preset that overrides only the commands you need is the maintainers’ recommended way to encode that workflow explicitly; this repo does not ship that preset yet.
Spec Kit 1.0.0: The Git extension is expected to become opt-in. Do not assume before_specify / speckit.git.feature is always present; keep the worktree flow valid with Git extension off.
Create .specify/extensions/worktrees/worktree-config.yml to override defaults:
layout: "nested" # nested | sibling
auto_create: true # Cursor + /worktree users: set false to avoid in-repo worktrees after every specify
sibling_pattern: "{{repo}}--{{branch}}"
dotworktrees_dir: ".worktrees"
# Optional VS Code handoff for /speckit.worktrees.specify
vscode_open_after_create: false
vscode_open_mode: "new-window" # new-window | reuse-window | print-command
vscode_command: "code"- On install (
specify extension add):.worktrees/is added to.gitignoreso the directory is ignored before any worktree exists - On create (
/speckit.worktrees.create): the script double-checks.gitignoreas a safety net - Commits stay on the right branch: each worktree has its own working tree and index —
git addandgit commitinside a worktree only affect that worktree's branch, not the main repo - Cleanup:
/speckit.worktrees.cleanremoves worktree directories; it never deletes the git branch itself
| Command | Description | Modifies files? |
|---|---|---|
/speckit.worktrees.specify |
Worktree-first specify flow: create/reuse a worktree, then write the spec inside it | Yes |
/speckit.worktrees.create |
Spawn a worktree for a feature branch | Yes |
/speckit.worktrees.list |
Dashboard: status, artifacts, tasks | No |
/speckit.worktrees.clean |
Remove merged/stale worktrees | Yes |
If you want the spec itself isolated from the start, use /speckit.worktrees.specify instead of /speckit.specify from the primary checkout:
/speckit.worktrees.specify 005-user-auth Build sign-in with email and passkeys
That command creates or reuses the feature worktree first, then treats the returned worktree path as the project root for the normal specify flow. The spec should be written under <worktree>/specs/<branch>/, and all follow-up /speckit.plan, /speckit.tasks, implementation, commit, push, and PR work should run from that worktree.
This is the recommended answer to the "pre-hook for specify" workflow: creating the worktree as an explicit command is predictable because it can pin the branch and path before any spec artifacts are written. A before_specify hook alone is not enough unless the surrounding product also changes the active project root for the rest of the specify command.
For VS Code, the most reliable variant remains one window per active worktree:
- Run
/speckit.worktrees.specify <branch> <feature description>from the primary checkout. - Open the returned worktree path in a new VS Code window.
- Continue
/speckit.planand later steps in that worktree window. - Commit, push, and open the PR from the worktree.
- Close the worktree window and run
/speckit.worktrees.cleanfrom the primary checkout when done.
/speckit.worktrees.specify can hand the created worktree to VS Code via the code CLI:
/speckit.worktrees.specify 005-user-auth Build sign-in --open-vscode
By default this uses a new window:
code -n <worktree-path>You can make that the project default in .specify/extensions/worktrees/worktree-config.yml:
vscode_open_after_create: true
vscode_open_mode: "new-window"
vscode_command: "code"Use vscode_open_mode: "reuse-window" only when you explicitly want VS Code to replace the current window with the worktree. If the code CLI is unavailable, or if vscode_open_mode: "print-command" is set, the command reports the exact code -n <worktree-path> command to run manually.
after_specify — automatically creates a worktree after a new feature is specified. Controlled by the auto_create config value.
The bash script can be called directly for automation:
# Create a nested worktree for branch 005-user-auth (default)
bash scripts/bash/create-worktree.sh --json 005-user-auth
# Sibling layout instead
bash scripts/bash/create-worktree.sh --json --layout sibling 005-user-auth
# Explicit path
bash scripts/bash/create-worktree.sh --json --path /tmp/my-worktree 005-user-auth
# Dry run (compute path without creating)
bash scripts/bash/create-worktree.sh --json --dry-run 005-user-auth
# Skip worktree (single-agent mode)
bash scripts/bash/create-worktree.sh --in-place 005-user-auth| Variable | Description |
|---|---|
SPECIFY_WORKTREE_PATH |
Override computed worktree path entirely |
SPECIFY_FEATURE |
Current feature name (set by spec-kit) |
- #61 — Spawn worktree when creating new branch (36+ upvotes)
- #1476 — Native worktree support for parallel agents
- #1940 — Git operations extracted to extension (closed)
- Spec Kit >= 0.4.0
- Git >= 2.15.0 (worktree support)
MIT