
Wt Switch Create
- 877 installs
- 6.3k repo stars
- Updated August 5, 2026
- max-sixty/worktrunk
wt-switch-create is an agent skill that creates a worktrunk git worktree and switches the active coding session into it for developers who need isolated branch directories for parallel fixes and feature builds.
About
wt-switch-create is a Worktrunk agent skill from max-sixty/worktrunk that wraps the wt CLI to create a new git worktree and immediately move the active Claude Code session into that directory. The command accepts an optional branch name, optional cross-repo path, and a -- task delimiter so agents can launch /wt-switch-create my-fix -- patch the parser or switch mid-session without nesting worktrees inside existing ones. Worktrunk computes sibling paths from configurable templates, applies project hooks on create, and keeps exploratory or risky changes out of the main checkout while another build keeps running elsewhere. Developers reach for wt-switch-create when hotfix branches, feature spikes, or parallel agent runs need separate directories with the same repo history. Cleanup stays outside this skill—merge or remove finished worktrees with wt merge and wt remove after the isolated task completes.
- Create isolated git worktrees for parallel branches
- Switch active worktree context without stashing
- Keep long-running builds alive in separate directories
- Reduce branch context-switching during agent sessions
- Standardize repo sandbox setup across teammates
Wt Switch Create by the numbers
- 877 all-time installs (skills.sh)
- +147 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #79 of 733 Git & Pull Requests skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/max-sixty/worktrunk --skill wt-switch-createAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 877 |
|---|---|
| repo stars | ★ 6.3k |
| Last updated | August 5, 2026 |
| Repository | max-sixty/worktrunk ↗ |
How do you switch Claude Code into a new git worktree?
Create or switch git worktrees with worktrunk so you can run a hotfix branch in isolation while a feature build keeps compiling in another directory.
Who is it for?
Developers using Worktrunk and Claude Code who run parallel branches or agent tasks that must not share the same working directory as an active compile or feature build.
Skip if: Developers on Codex, OpenCode, or Gemini CLI without Claude Code session switching who should invoke wt switch --create directly from the terminal.
When should I use this skill?
The user wants to create a git worktree, switch an agent session into an isolated branch directory, or run /wt-switch-create with an optional repo path and task after --.
What you get
A new worktrunk worktree on a named branch with the agent session rooted in that directory and hooks applied from Worktrunk config.
- isolated git worktree directory
- switched agent session cwd
- named feature or hotfix branch
By the numbers
- Accepts up to 3 argument parts: branch name, optional repo path, and -- task text
Files
Arguments: $ARGUMENTS. Grammar: [<branch>] [<repo>] [-- <task>].
- branch — optional; the branch name for the new worktree. When omitted,
pick one (step 1 below).
- repo — optional path; create the worktree in this repo instead of the
session's current one.
- task — optional; what to do inside the new worktree. No task means enter
the worktree and wait.
Tokens before the -- are the branch and/or repo: a path-shaped token (starting with /, ~, ./, or ../) is the repo; any other token is the branch (docs is a branch name, never the docs/ directory). More than one branch-shaped token before a -- doesn't fit the grammar — ask. Without a --, judge where the task starts: leading tokens that read as a branch name (fix-auth) or a repo path are consumed as such, and the rest is the task; otherwise the whole input is the task (fix the parser bug has no branch-shaped lead — all task).
/wt-switch-create my-feature -- fix the parser bug
/wt-switch-create -- fix the parser bug
/wt-switch-create my-feature ~/workspace/other-repo -- fix the parser bug
/wt-switch-create my-featureWhat to do
Steps 1–3 come before any other work.
<!-- Maintainers: rationale.md (same directory) covers the harness rules and design choices behind this — read it before re-adding guards or routes. -->
1. Pick the branch name if none was given: short, from the task and consistent with existing worktree names, or, mid-session, from the work being moved; with nothing to derive from, ask.
2. Create the worktree with a Bash call (omit -C <repo> for this repo):
wt -C <repo> switch --create <branch> --no-cd --format=jsonStdout is JSON whose path field is the worktree's absolute path (status lines go to stderr). On Branch <branch> already exists: if the user named the branch, rerun without --create (it enters the branch, creating its worktree if missing); if step 1 picked the name, pick another and rerun. Any other failure (not a git repo, invalid name): report it and stop.
Mid-session, carry uncommitted work across: git stash push -u before creating the worktree, then git -C <path> stash pop after (the stash is shared across worktrees).
3. Enter the worktree, then do the task. Call EnterWorktree({path: "<path from the JSON>"}).
- Accepted → the session is re-rooted in the worktree. Do the task (or,
with no task text, confirm it's ready and wait).
- Rejected → graceful, and nothing is created. Two cases land here: the
worktree is in another repo (EnterWorktree re-roots only within the repo your cwd is in), or this session is already rooted in a worktree (or is a pinned agent), which limits entry to that repo's .claude/worktrees/ and refuses even a same-repo wt sibling. Both reduce to the same test: whether you can cd into the worktree, which works when it's inside an allowed directory (a permissions.additionalDirectories entry such as ~/workspace). So cd <path> and read the result:
- no
Shell cwd was resetnotice → it stuck; the worktree is reachable.
Work there, but a bare cd is not a tracked re-root, so the cwd can revert to the session's launch worktree across turns (and in spawned subagents); pin commands with git -C <path> / wt -C <path> rather than trusting the cd to persist.
Shell cwd was reset→ not reachable. Stop and ask the user to make it
reachable: add the repo, or a parent like ~/workspace, to permissions.additionalDirectories (durable, every session), or run /add-dir <path> (this session). Then continue. Don't grind through absolute paths with cd resetting on every command.
Cleanup
The worktree is a normal worktrunk worktree: it persists after the session ends, shows up in wt list, and is merged or removed with wt merge / wt remove <branch> like any other. Don't remove it unprompted. If the user asks to leave mid-session, ExitWorktree({action: "keep"}) returns the session to its original directory; ExitWorktree cannot remove a worktree entered by path, so removal is always wt remove <branch>.
Scope
This command authorizes creating/entering ONE worktree (in the named repo, if one was given) and doing the requested task. Commits, pushes, and merges still each require explicit user permission.
wt-switch-create design rationale
Why the skill is create-then-reach: create the worktree with wt, enter it with EnterWorktree, and when entry is rejected, work in it if it's reachable or escalate to the user to make it reachable. Not the guard-heavy multi-route flow it replaced, and not the silent absolute-paths fallback that read as a failure.
Every claim here was verified against primary sources (2026-06-11 to 2026-06-17): Claude Code 2.1.173, with the path-entry and working-directory logic re-confirmed live and against the 2.1.177 binary, plus official docs at code.claude.com/docs; and wt v0.57.0-16-g371d28662 (live runs in a scratch repo). Re-verify against current versions before relying on a specific behavior; the shape of the argument should outlive the details. Binary symbol names are deliberately omitted — they re-minify every build.
The design
1. Create the worktree with wt -C <repo> switch --create <branch> --no-cd --format=json in Bash (omit -C for this repo). wt solves repo targeting (-C works from anywhere), existing-branch handling (rerun without --create), and machine-readable output (.path on stdout, status on stderr). Creating in another repo is fine; only entering the result is constrained. 2. Enter it with EnterWorktree({path}) — the only way to re-root a Claude Code session, and it accepts only a worktree of the session's own repo. 3. On rejection, the session can still work there iff the path sits inside a directory it's allowed in (an additionalDirectories entry). A single cd <path> discovers which: it sticks when reachable, resets when not. Reachable → work in place. Unreachable → escalate, because the agent can't enlarge that set itself: ask the user to add the repo or a parent (e.g. ~/workspace) to additionalDirectories, or /add-dir <path>. A one-line, set-once handback, not a silent degrade.
Two independent harness facts underlie this — re-root is repo-scoped, and cd persistence is working-directory-membership-scoped — detailed below.
wt CLI and git behavior (all live-tested)
wt switch --create <branch>exits 1 with `✗ Branch <branch> already
exists whenever the branch exists, with or without a worktree. Its own hint names the fix: rerun without --create`.
wt switch <branch>(no--create) exits 0 for an existing branch: it
creates the worktree if missing ("action":"created","created_branch":false) or re-enters it ("action":"existing"). Per wt switch --help: "Without --create, the branch must already exist."
- Every
--format=jsonvariant carriespath(absolute). Only the JSON goes
to stdout; all human-readable status, including hook output, goes to stderr — which is what makes .path extraction safe.
wt remove: dirty worktree → refuses (exit 1, hints--force); clean but
unmerged commits → removes the worktree, keeps the branch, hints wt remove -D; clean and merged → removes worktree and branch.
- The git stash is per-repo, shared across worktrees:
git stash push -uin
one worktree pops cleanly in another via git -C <path> stash pop, untracked files included — the mid-session carry-across in step 2.
Claude Code behavior
A session works wherever its cwd is. Two mechanisms move it, and they compose: cd moves the cwd (and so which repo EnterWorktree sees); EnterWorktree re-roots within the repo the cwd is in. All verified live and against the 2.1.177 binary.
M1 — cd (shell cwd)
Moves the shell cwd; the statusline and tool-path relativization (Write(foo/bar.py)) follow it.
- Gate: the path must sit inside a configured working directory — the
session's base cwd plus every entry in permissions.additionalDirectories (settings.json), --add-dir (launch), or /add-dir (mid-session).
- Inside →
cdpersists across Bash calls. Outside → the harness snaps it back
and appends Shell cwd was reset to <original> to the result.
- Repo-blind: it checks only the path's location against that set, never
which git repo owns the path. A different repo's worktree under /tmp is reachable when /tmp is configured.
- Within a single Bash call,
cd X && cmdalways works; the reset happens
only between calls. (Subagent threads reset between every call.)
M2 — EnterWorktree({path}) (re-root)
Formally re-roots: sets the session's worktree home (tracked for exit) and its cwd.
- Gate: a worktree of the repo the current cwd resolves to, by session
state:
- Plain / first-entry session → any worktree registered to that repo
(git worktree list), anywhere on disk.
- Already in a worktree-session, or a pinned agent → only under that
repo's .claude/worktrees/; rejects even same-repo siblings.
- cwd outside any git repo → refuses entirely.
- Rejections are graceful and side-effect-free (nothing is created), verbatim:
- registered-check: `Cannot enter worktree: <path> is not a registered
worktree of <repo>. Run 'git -C <repo> worktree list' …`
- managed-location: `Cannot enter worktree: <path> is not under
<repo>/.claude/worktrees. Switching from this session is limited to worktrees managed by Claude Code …`
- no repo: `Cannot enter an existing worktree: the current directory is not in
a git repository.`
The repo is read from the cwd, so EnterWorktree never moves you to a different repo on its own — it re-roots within whatever repo you're already standing in. To re-root into another repo, cd into it first, then EnterWorktree. Verified: from a worktrunk session, cd into a prql worktree under /tmp, then EnterWorktree re-rooted within prql.
How they compose
Whether you can work in — or re-root into — a repo reduces to whether your cwd can be there, which is cd's gate:
| Target | cwd reachable? | Result |
|---|---|---|
| Same repo (incl. its sibling worktrees) | always | EnterWorktree re-roots directly |
Another repo under a configured dir (~/workspace, /tmp) | yes | cd in → working there; from a plain session, EnterWorktree re-roots within it too |
| Another repo outside every configured dir | no | unreachable — add it (or a parent) to additionalDirectories, or /add-dir |
| Outside any repo | n/a | no re-root possible |
additionalDirectories is the one master gate: once a repo, or a parent like ~/workspace, is in it, the session can cd into that repo's worktrees and both work there and re-root within them. This is load-bearing for the same-repo path too: a sibling worktree is registered to the repo, so EnterWorktree from a plain session re-roots into the sibling wt creates. The agent cannot enlarge that set itself (/add-dir is user-typed; the only automatic add is a narrow symlink-resolving-to-the-same-cwd fixup), so a repo reachable by neither the cwd nor config is a genuine handback to the user.
Why --no-cd
The Bash tool is not a bare shell: Claude Code replays the user's shell startup from a snapshot, so a user who installed wt shell integration runs the wt wrapper function inside the tool. wt then runs with integration active, and a plain wt switch hands the wrapper a cd directive that moves the tool's cwd — a second, untracked re-root racing EnterWorktree. --no-cd skips the directive, so EnterWorktree stays the single re-root. Verified: without --no-cd, wt switch <branch> moved the session and the new cwd persisted to the next Bash call. Where the user never installed integration (a fresh shell, CI) the wrapper is absent and wt cannot cd regardless, so --no-cd is load-bearing on an integrated machine and a no-op elsewhere. Don't drop it.
Why not EnterWorktree({name}) + the WorktreeCreate hook
A worktree could also be created by EnterWorktree({name}), which the worktrunk plugin routes through its WorktreeCreate hook. Rejected for the skill — the hook itself stays; it is how isolation: "worktree" agents get worktrunk worktrees:
1. Hard-fails on existing branches. The hook runs wt switch --create, and a nonzero hook exit fails worktree creation outright — there is no git fallback (binary: "Other exit codes - worktree creation failed"; docs: "the hook replaces the default git behavior"). That forced a second route for existing branches; path entry needs no second route. 2. No repo targeting. EnterWorktree({name}) creates the worktree wherever the session is rooted; it can't make one in another repo, which wt -C does trivially in step 1. 3. Wrong exit-time semantics for durable worktrees. Worktrees created by name are tracked for session-exit cleanup: when the session has no user-set title, a clean worktree (no changed files, no new commits) is silently auto-removed at exit (binary: auto-remove iff zero changes, zero commits, and no session title; message "Worktree removed (no changes)"). A worktrunk worktree the user asked for should outlive the session (wt list, later wt merge). Path-entered worktrees get exactly that: left in place, no prompt ("worktree at <path> left in place"). 4. Hook contract details leak into the skill. stdout's last non-empty line must be an existing directory, etc. — irrelevant when the skill reads .path from wt --format=json directly.
Why escalate instead of grinding through absolute paths
The original incident worked a cross-repo task via absolute paths from a session rooted elsewhere: every cd into the worktree reset, so each command needed an absolute prefix, and the session never gained the worktree cwd. It produced correct output but read as a failure. File tools (absolute paths) and git -C are cwd-independent, so the work is possible that way — but it is friction the user shouldn't absorb when the fix is one line of config.
So when the worktree is unreachable, the skill escalates with the concrete fix rather than degrading silently. This is not a predictive guard: the skill doesn't refuse to create cross-repo and doesn't guess reachability. It creates, attempts entry, and lets a single cd reveal reachability — the escalation fires only on an actual reset. Cheap to attempt, and the handback is actionable and durable (a ~/workspace entry, set once, covers every future cross-repo task).
The hooks.json pipefail wrapper (agent-isolation path, not this skill)
WorktreeCreate pipes jq | xargs wt | jq; without pipefail the trailing jq exits 0 on empty input and swallows a wt failure, so Claude Code saw a "successful" hook with no path. Hook commands are spawned with an empty args array and shell: true (binary), i.e. /bin/sh -c on Unix — bash 3.2 on macOS but dash on many Linuxes. dash rejects set -o pipefail fatally (set is a POSIX special builtin; no dash release through 0.5.12 supports pipefail — only post-0.5.12 upstream git and distro backports such as Debian's 0.5.12-7). And /bin/sh -c is evidently not universal: one user's hooks ran under fish (worktrunk PR #2962), which has no shell options at all. Hence the explicit bash -c 'set -o pipefail; …' wrapper. Verified end-to-end: success prints the path and exits 0; an existing-branch failure exits 1 with empty stdout.
Known limits (deliberate)
EnterWorktreere-roots only within the repo the cwd is in, and the cwd can't
cd outside the session's additionalDirectories (Claude Code restrictions, not skill gaps). So another repo is reachable only when it, or a parent like ~/workspace, is in additionalDirectories — then the session cds in and works there (and, from a plain session, can re-root within it). Otherwise the skill escalates for a one-line config add rather than degrading to absolute-paths mode. The agent can't enlarge the set itself (/add-dir is user-typed), so this handback is irreducible — but set once, it is permanent.
- A pinned or already-in-worktree session can't even re-enter a same-repo
sibling worktree (the stricter .claude/worktrees/ check); it lands in the same reachability test and the same escalation.
wt switch --createis not idempotent. If that ever changes upstream
(enter-if-exists), step 2's existing-branch retry collapses to nothing.
Related skills
How it compares
Use wt-switch-create when the agent session itself must relocate into a fresh worktree; use plain wt switch for manual terminal branch changes without session re-rooting.
FAQ
What does wt-switch-create require installed?
wt-switch-create needs the Worktrunk wt CLI on PATH and the Claude Code WorktreeCreate hook configured so agent-created worktrees route through wt switch --create instead of plain git worktree add.
Can wt-switch-create target another repository?
wt-switch-create accepts an optional repo path as the second argument before a -- task delimiter. The skill creates the worktree in that repository and switches the session working directory according to Worktrunk cross-repo rules.
How is wt-switch-create different from wt merge or wt remove?
wt-switch-create only creates a worktree and enters it for active development. wt merge and wt remove are separate Worktrunk commands used afterward to integrate or delete finished worktrees with uncommitted-change safeguards.