From Z Skills
Create a git worktree for agent work. Thin wrapper around create-worktree.sh — owns prefix-derived path, optional --branch-name override, optional pre-flight prune+fetch+ff-merge, safe worktree-add, and sanitised .zskills/tracked / .zskills/worktreepurpose writes. Prints the worktree path on stdout.
How this skill is triggered — by the user, by Claude, or both
Slash command
/zs:create-worktree <slug> [--prefix P] [--branch-name REF] [--from B] [--root R] [--purpose TEXT] [--pipeline-id ID] [--allow-resume] [--no-preflight]<slug> [--prefix P] [--branch-name REF] [--from B] [--root R] [--purpose TEXT] [--pipeline-id ID] [--allow-resume] [--no-preflight]The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Thin skill wrapper around `.claude/skills/create-worktree/scripts/create-worktree.sh`. The script is the spec; this file exists for discoverability and to document the invocation contract. Do not duplicate the script's logic here.
Thin skill wrapper around .claude/skills/create-worktree/scripts/create-worktree.sh. The script is the spec; this file exists for discoverability and to document the invocation contract. Do not duplicate the script's logic here.
This skill has two kinds of callers. Both ultimately run the same script; they differ only in whether --pipeline-id is specified upfront.
Tier 1 — bash callers inside other skills (e.g. /run-plan, /fix-issues, /do). These know their canonical pipeline ID (run-plan.<tracking-id>, fix-issues.<sprint-id>, do.<task-slug>, etc.) and must pass it verbatim via --pipeline-id. The script rejects invocations without the flag (rc 5). There is no env-var fallback and no silent default — the flag is required so mis-wired call sites fail loudly instead of producing a wrong .zskills/tracked.
Tier 2 — user / Claude invoking /create-worktree as a slash command. Users say "make a worktree called foo-task" and don't know or care what a pipeline ID is. When the user omits --pipeline-id, Claude (reading this skill) synthesises create-worktree.<slug> and passes it to the script. A power user who wants a specific pipeline ID can still pass --pipeline-id explicitly; Claude passes it through unchanged.
This is why the script is strict but the skill is ergonomic.
Invoke via $CLAUDE_PROJECT_DIR (works from any CWD, including nested worktrees):
if [ -f "${CLAUDE_PLUGIN_ROOT}/skills/update-zskills/scripts/zskills-resolve-config.sh" ]; then
export CLAUDE_PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT}"
. "${CLAUDE_PLUGIN_ROOT}/skills/update-zskills/scripts/zskills-resolve-config.sh"
else
. "$CLAUDE_PROJECT_DIR/.claude/skills/update-zskills/scripts/zskills-resolve-config.sh"
fi
WT_PATH=$(bash "$ZSKILLS_SKILLS_ROOT/create-worktree/scripts/create-worktree.sh" \
--pipeline-id "<id>" \
[--prefix P] [--branch-name REF] [--from B] [--root R] \
[--purpose TEXT] [--allow-resume] [--no-preflight] \
<slug>)
For tier-1 callers: --pipeline-id is the skill's canonical ID (e.g. run-plan.${TRACKING_ID}).
For tier-2 user invocations without an explicit flag: Claude synthesises --pipeline-id "create-worktree.<slug>" (or create-worktree.<prefix>.<slug> when --prefix is given) and passes it to the script. This default is owned at the skill layer and never happens inside the script.
<slug> (required, positional) — last non-flag token. Must match [A-Za-z0-9._-]+.--pipeline-id ID (required) — the value written (after sanitisation) to .zskills/tracked. Tier-1 callers pass their canonical pipeline ID. Tier-2 standalone invocations synthesise create-worktree[.${PREFIX}].${SLUG} at the skill layer if the user omitted a flag.--prefix P — adds P- to branch name and path leaf. Slashes rejected (rc 5).--branch-name REF — overrides branch verbatim; path leaf is unchanged. Slashes in the ref are legal (refs under refs/heads/).--from B — base branch for pre-flight and worktree-add-safe.sh. Default main.--root R — override ${WORKTREE_ROOT}/${PROJECT_NAME} stem. Path becomes ${R}/[${PREFIX}-]${SLUG}.--purpose TEXT — write .zskills/worktreepurpose with this text. Without this flag, the script does NOT write .zskills/worktreepurpose; caller/agent retains responsibility.--allow-resume — export ZSKILLS_ALLOW_BRANCH_RESUME=1 to worktree-add-safe.sh (permits attach-to-existing-branch that is ahead of base).--no-preflight — skip git worktree prune, git fetch origin <BASE>, git merge --ff-only origin/<BASE>. Preserves pre-migration semantics for /do worktree mode.PROJECT_NAME=$(basename "$MAIN_ROOT"). Final path is realpath -m:
| Invocation | Path | Branch |
|---|---|---|
... <slug> | ${WORKTREE_ROOT}/${PROJECT_NAME}-${SLUG} | wt-${SLUG} |
... --prefix P <slug> | ${WORKTREE_ROOT}/${PROJECT_NAME}-${P}-${SLUG} | ${P}-${SLUG} |
... --root R <slug> | ${R}/${SLUG} | wt-${SLUG} |
... --root R --prefix P <slug> | ${R}/${P}-${SLUG} | ${P}-${SLUG} |
WORKTREE_ROOT comes from execution.worktree_root in .claude/zskills-config.json; default /tmp.
On success (rc=0), stdout is exactly one line: the absolute worktree path. All progress and error messages go to stderr. Callers may safely WT_PATH=$(bash … <slug>) and cd "$WT_PATH".
| Code | Meaning | Retryable |
|---|---|---|
| 0 | Worktree created (fresh, recreated, or resumed) | — |
| 2 | Path exists (incl. TOCTOU remap) | No (operator decides) |
| 3 | Poisoned branch (behind base, 0 ahead) | No |
| 4 | Branch ahead of base without --allow-resume | No |
| 5 | Input validation — missing --pipeline-id, bad slug, slash in --prefix, unknown flag, not in git, install-integrity | No |
| 6 | Pre-flight fetch failed | Yes |
| 7 | Pre-flight ff-merge not possible (divergent base) | No |
| 8 | Post-create write failed (worktree rolled back) | Maybe |
Codes 2/3/4 propagate from .claude/skills/create-worktree/scripts/worktree-add-safe.sh. Code 2 also covers the TOCTOU remap when the path materialises mid-flight.
.zskills/tracked is always written with the sanitised --pipeline-id value.
The script requires the flag — there is no env-var path and no fallback.
The value is passed through .claude/skills/create-worktree/scripts/sanitize-pipeline-id.sh before being written..zskills/worktreepurpose is written iff --purpose was given..claude/skills/commit/scripts/land-phase.sh
refuses to clean up a worktree that has git-tracked copies of either.scripts/post-create-worktree.sh stub runs LAST (the worktree
path is $1). This is THE place for per-project worktree bootstrap —
dependency install and git-hook setup (e.g. npm i && npm run prepare) so a
fresh worktree is commit-ready. A fresh worktree has no installed deps and no
installed hooks, so do the bootstrap in the stub rather than baking install
commands into agent dispatch prompts. Never symlink node_modules from the
main repo — a shared node_modules shares build-tool caches (vite / webpack
/ esbuild) across worktrees and serves stale output; do a real install into
the worktree. See the stub's inline comments for the template.scripts/move-to-worktree.sh is a sibling helper for the "I have dirty
changes on main and want them moved into a worktree" flow (#1165). It
creates a worktree off the CURRENT LOCAL HEAD (via create-worktree.sh --no-preflight, so the carry is same-base by construction), carries the
dirty + untracked files into it (a TWO-patch carry that preserves the
staged/unstaged split, plus per-file untracked copy), byte+index-verifies
the carry, and then performs a SANCTIONED, stash-free restore of main
back to HEAD. No git stash (hard-denied), no git clean, no
tree-overwriting verbs — only git restore --staged --worktree --source=HEAD, run by the helper itself so the agent never types a denied
command.
bash "$ZSKILLS_SKILLS_ROOT/create-worktree/scripts/move-to-worktree.sh" <branch-name|--auto> [--keep-main-dirty]
Exit codes (distinct from create-worktree.sh's table above):
| Code | Meaning |
|---|---|
| 0 | Success — worktree created, dirt carried, main restored (unless --keep-main-dirty) |
| 2 | Usage error (bad/missing args, not in a git repo, unknown flag) |
| 6 | create-worktree.sh failed (its rc reported in the message) |
| 7 | Base mismatch OR patch-apply failure — main left FULLY untouched (UNMERGED paths land here: resolve the merge first) |
| 8 | Byte/index verification mismatch — step-6 leaves main fully untouched; a step-7 per-file TOCTOU mismatch leaves main PARTIALLY restored, with the preserved files listed |
--keep-main-dirty skips the restore (main stays dirty, the worktree also
has the dirt). Gitignored files and .zskills/ (plus the legacy root
markers) are structurally excluded from the carry. The worktree branches
off LOCAL HEAD — if local main is ahead of/behind origin, the branch
rebases later through the normal PR flow.
Authoritative spec: scripts/create-worktree.sh and scripts/move-to-worktree.sh. Edit there; this wrapper should stay thin.
Provides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.
Fetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.
npx claudepluginhub zeveck/zskills-dev --plugin zs