Install
$ agentstack add skill-yongwoon-ywc-agent-toolkit-ywc-worktrees ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
ywc-worktrees
Announce at start: "I'm using the ywc-worktrees skill to manage the git worktree lifecycle for an isolated workspace."
Single source of truth for git worktree priority resolution, creation, audit, and pruning. Extracted from ywc-parallel-executor so the same discipline is callable from any skill that needs worktree isolation (parallel-executor's per-task worktrees, finish-branch's post-merge cleanup, ad-hoc developer use). Pattern inspiration: superpowers using-git-worktrees skill, adapted to this project's self-contained runtime policy — referenced for design intent only, never dispatched at runtime.
Rationalization Defense
When tempted to skip a step, check this table first:
| Excuse | Reality | |---|---| | "Worktree location does not matter — drop it next to the repo" | Worktree path is a contract. Callers and audit tooling expect .worktrees/ or the project's documented worktree_root. Inventing a sibling path breaks every downstream cleanup that scans the documented location. | | "git worktree prune is enough — skip the audit step" | prune removes only stale metadata for worktrees whose directories are gone. It does not report worktrees whose directories still exist but were never claimed by any task. Audit catches both classes; prune alone hides drift. | | "If a worktree path already exists, just reuse it" | A pre-existing path means either a prior run did not clean up (drift) or another task is currently using it (collision). Reuse silently corrupts whichever party is touching the path. Always treat existing paths as an error, not a hint. | | "The caller passed --mode create so the resolution step is decided — skip the audit" | Pre-flight audit is mandatory before any new worktree creation. Stale metadata from a previous run causes the new git worktree add to fail with a confusing "already registered" error; the audit + prune catches this before the user-visible failure. | | "Worktree priority is overhead — the caller knows where it wants to go" | The priority chain (.worktrees/ > CLAUDE.md worktree_root > --root fallback) exists so that a project can pin a worktree location once (in its CLAUDE.md) and have every skill respect it. Callers that bypass the chain silently fragment worktree locations across the project. |
Violating the letter of these rules is violating the spirit. A stale worktree from yesterday's run is the most common cause of "the new run is broken for no reason" in parallel-executor.
Arguments
| Parameter | Format | Example | Description | |---|---|---|---| | --mode | ` | --mode create | One of create, audit, prune, resolve. See [Modes](#modes). | | --task-name | | --task-name 000001-010-db-create-users | The task this worktree belongs to. Required for create and prune; optional for audit. | | --branch | | --branch feature/000001-010-db-create-users | The branch to associate with the worktree. Required for create; optional for prune (defaults to feature/). | | --base-branch | | --base-branch develop | The starting point for the new branch. Required for create (no default). | | --root | | --root .worktrees | Fallback worktree root when the project has neither .worktrees/ nor CLAUDE.md worktree_root. Project-level configuration wins over this value. | | --expect | | --expect 000001-010,000001-020 | (Audit only) Comma-separated list of task names that should currently have a worktree. Any extra or missing worktree fails the audit. | | --force | flag | | (Prune only) Pass --force to git worktree remove even if the worktree is dirty. Use only when the caller has confirmed the worktree's contents are disposable. | | --keep-branch | flag | | (Prune only) Remove the worktree and prune stale metadata, but **skip** the local branch deletion (git branch -d) and its verification. Same semantics as ywc-finish-branch --keep-branch`: use when the branch must survive the worktree teardown (e.g. an integration branch a caller will later raise a trunk PR from). |
Modes
| Mode | Reads | Writes | Use case | |---|---|---|---| | resolve | .worktrees/ presence, CLAUDE.md worktree_root, --root | nothing | Caller wants to know where a worktree would land before committing to create. Returns the resolved path on stdout. | | create | resolved root + --task-name + --branch + --base-branch | git worktree add | Per-task worktree creation. Called by ywc-parallel-executor Step 4 for each in-wave task. | | audit | resolved root contents + --expect (optional) | nothing (read-only) | Pre-flight or wave-end audit. Reports stale, leaked, or unexpected worktrees. | | prune | resolved root + --task-name + optional --branch + optional --keep-branch | git worktree remove + local branch delete (skipped when --keep-branch) + git worktree prune | Post-merge cleanup. Called by ywc-finish-branch Step 5/8 and ywc-parallel-executor Step 4g. --keep-branch preserves the branch (e.g. ywc-sequential-executor --worktree non-aggregate teardown). |
Modes are mutually exclusive — --mode takes exactly one value. The caller chooses the mode based on the lifecycle stage; this skill does not infer.
Priority Resolution
The worktree root is resolved by walking the following chain in order; the first match wins:
.worktrees/directory present in repo root — if the directory exists (even empty), it is the worktree root. This is the recommended pattern: a project commits an empty.worktrees/.gitkeepto make the location explicit and discoverable.- CLAUDE.md
worktree_rootdirective — ifCLAUDE.mdcontains a line matchingworktree_root:, that path is the root. Allows projects to pin a location outside the repo (e.g., a sibling../-worktrees/) without requiring an in-repo directory. --rootfallback — used only when neither.worktrees/norCLAUDE.mddeclares a project-level root. This lets callers pass an explicit location without overriding project policy.- Project-relative
../fallback — if none of the above match, fall back to../worktree-(the legacy parallel-executor convention). A warning is logged: the project should adopt.worktrees/or the CLAUDE.md directive to make this explicit.
The resolved path is recorded in the caller's payload and re-derived (not stored) on every invocation, so a mid-run change to CLAUDE.md or .worktrees/ presence takes effect on the next call.
Execution
--mode resolve
- Walk the priority chain above.
- Print the resolved root path to stdout.
- Exit 0 on success; exit 1 if
--rootwas provided but is not a writable directory.
No side effects. Safe to call from --dry-run paths in upstream skills.
--mode create
- Run
--mode resolveinternally to get the worktree root. - Verify the target path
/does not already exist. If it does, exit 1 with a descriptive error — never overwrite. - Run
git worktree add -b. - Verify the worktree was registered:
git worktree list --porcelain | grepreturns a row. - Print the resolved worktree path on stdout for the caller to capture.
- Exit 0 on success.
Error handling: if git worktree add fails (locked, branch already exists elsewhere, etc.), surface the exact git error and exit 1. Never retry; the caller decides whether the failure is recoverable.
--mode audit
- Run
--mode resolveto get the worktree root. - Run the bundled
scripts/audit-worktrees.shagainst the resolved root. The script reports:
- Clean — no stale metadata, no unexpected worktrees, every
--expecttask has a worktree. - Drift —
git worktree listrows whose directories no longer exist (stale metadata) OR directories under the root whose paths are not ingit worktree list. Both cases fail the audit. - Missing — when
--expectis provided, tasks in the expect list that do not have a worktree. Fails the audit. - Leaked — when
--expectis provided, worktrees that exist but are not in the expect list. Fails the audit (a previous task was not cleaned up).
- Exit 0 if clean; exit 1 with the categorized findings on stdout if not.
--mode prune
- Run
--mode resolveto get the worktree root. - Run the bundled
scripts/cleanup-worktree.shagainst the resolved task worktree path. The script:
- Verifies the path is under the resolved root (refuses to operate on paths outside).
- Runs
git worktree remove(or--forceif--forcewas passed). - Deletes the local branch with
git branch -d(defaultfeature/) after the worktree is released — unless--keep-branchis set, in which case the branch deletion and its verification are skipped. The branch name is treated as a git ref (it may legitimately contain/, e.g.integration/run-orwork/); only--task-name, which forms a path component, is allowlisted to^[A-Za-z0-9_-]+$. - If the target branch does not exist (e.g. an
--aggregate-printegration branch already merged and deleted by its final PR), the deletion step is idempotent — it logs and continues rather than failing. - Runs
git worktree pruneto clear any stale metadata. - Verifies the path is gone, the metadata row is removed, and (when
--keep-branchis not set) the local branch no longer exists.
- Exit 0 if cleanup verified; exit 1 with details on stdout if any step failed.
The script refuses to operate on dirty worktrees unless --force is set — this is the discipline that catches accidental deletion of work in progress.
Integration
- upstream —
ywc-parallel-executor(Pre-flight--mode audit, Step 4 per-task--mode create, Step 4g--mode prune);ywc-finish-branch(Step 5/8 cleanup--mode prunewhen called from a parallel-executor context). - downstream — none; this skill is a leaf operation. Callers consume its exit code and stdout.
- bundled scripts —
scripts/audit-worktrees.sh(audit),scripts/cleanup-worktree.sh(prune + local branch deletion). Both moved here fromywc-parallel-executor/scripts/viagit mv, preserving history.
Design Source
Adapted from the superpowers using-git-worktrees skill. The priority resolution chain (.worktrees/ > CLAUDE.md > --root > fallback) and the four-mode interface (create / audit / prune / resolve) follow that pattern. This project's self-contained runtime policy means the superpowers skill is not dispatched at runtime — it is a design reference for the pattern shape only, and this file is the project-owned implementation.
Notes
This skill is the single source for worktree lifecycle. Callers must not re-implement worktree creation or pruning inline; doing so fragments the priority resolution chain and the audit / prune discipline. If a caller needs a worktree operation not covered by the four modes, extend this skill rather than work around it.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: yongwoon
- Source: yongwoon/ywc-agent-toolkit
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.