Git worktree per task — <worktree_path>/<context>/<title>, in .worktrees.
Scanned 9/6/2026
Install to Claude Code
npx -y skills add Dev-Toolbelt/dev-team-agents --skill worktree --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Worktree?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/dev-toolbelt-worktree)More formats (shields.io, HTML) on the badges page.
---
name: worktree
description: Git worktree per task — <worktree_path>/<context>/<title>, in .worktrees.
---
# Worktree — Task Isolation Protocol
Invoke this skill at the **very start** of every task. No code, no file edits, no planning until the worktree decision is resolved.
---
## Decision Cascade (load first)
Resolve the worktree decision top-down; stop at the first that applies:
| # | Source | Action |
|---|--------|--------|
| 1 | `.dev-team-agents/.worktree-session` present | Follow the stored per-session decision silently |
| 2 | `worktree_active` in `preferences.json` | Use it **without asking**; write the session file so the rest of the session is consistent |
| 3 | key absent (legacy install) | Ask the user once — see below |
```bash
cat .dev-team-agents/.worktree-session 2>/dev/null # source 1
```
| Session-file content | Action |
|---|---|
| `worktree=no branch=<b>` | Operate on branch `<b>`; skip worktree setup |
| `worktree=yes branch=<b>` | Load `references/branch-flow.md` using `<b>` as base |
**If the session file is absent**, read `worktree_active` from `preferences.json`:
`true` → set up a worktree without the yes/no prompt; `false` → skip the yes/no prompt and ask only for a new branch name;
key absent → use the `AskUserQuestion` tool with options [Yes, No]:
"Should this task use a git worktree (isolated working directory)?"
- **Yes** → resolve the base branch (auto-detect default branch), write `worktree=yes branch=<base>`, follow `references/branch-flow.md`
- **No** → ask for a new branch name (suggest `<context>/<brief-title>`), run `git checkout -b <branch-name>`, write `worktree=no branch=<branch-name>`
For the full cascade, base-branch resolution, format rules, and cleanup: load `references/session-protocol.md`.
---
## Worktree Setup (when worktree=yes)
`<wt-path>` = `worktree_path` from `preferences.json` (default `.worktrees`).
Load `references/branch-flow.md` for the complete step-by-step flow:
1. Load project context (project-config → preferences.json → skill defaults)
2. Derive name: `<context>/<brief-title>` — lowercase, hyphenated, ≤ 5 words
3. Resolve base branch: `worktree_base_branch` → project config → auto-detect default branch → ask
4. Check for existing worktree → reuse if present
5. Create: `git worktree add <wt-path>/<ctx>/<title> -b <ctx>/<title> <base>`
6. Work exclusively inside `<wt-path>/<ctx>/<title>/` — when `worktree_docker_isolate` and the project uses Docker, load `references/docker-isolation.md`
7. Commit with `git -C <wt-path>/<ctx>/<title> ...` (intermediate commits are normal)
8. Finalize on merge: rebase onto base → resolve → commit → merge → **dirty-worktree guard** (`git status --porcelain`; abort teardown and ask the user if not clean) → teardown worktree + isolated Docker stack only
---
## Name Format
```
<context>/<brief-title>
```
Examples: `auth/add-oauth-provider`, `payments/fix-refund-calculation`, `api/add-rate-limiting`
Both parts must be real, spelled-out words describing the task — never an invented acronym or letter code (e.g. `bsi`, `dkey`). A human unfamiliar with the task must be able to tell what it's about from the name alone.
For the full naming table, see `references/branch-flow.md` → Naming quick-reference.
---
## Task Completion Summary
When work is declared done (before finalization/teardown), the agent **must** output a summary block showing the current state:
```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
WORKTREE SUMMARY
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Worktree: <wt-path>/<context>/<brief-title>
Branch: <context>/<brief-title>
Base: <base-branch>
Docker: <compose-project-name> (<n> containers: <svc1>, <svc2>, ...)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```
To gather the info:
```bash
# Worktree path and branch
WT=<wt-path>/<context>/<brief-title>
BRANCH=<context>/<brief-title>
BASE=<base-branch>
# Docker containers (if worktree_docker_isolate and compose is up)
docker compose -p "$COMPOSE_PROJECT_NAME" ps --format "table {{.Name}}\t{{.Status}}" 2>/dev/null
```
- If there is no Docker isolation (`worktree_docker_isolate` is `false` or compose is down), show `Docker: none`.
- The summary goes in a text block — present it directly, no quiz, no markdown tables.
---
## Key Rules
- **Unified naming**: worktree directory, branch, and (when Docker isolation applies) the Docker Compose project name and its containers must all derive from the **same** `<context>/<brief-title>` slug — worktree path `<wt-path>/<context>/<brief-title>`, branch `<context>/<brief-title>`, Docker project `<base-project>-wt-<context>-<brief-title>` (see `references/docker-isolation.md` → Step 2). Never let one of these drift to a different name than the others — that is what keeps a task's worktree, branch, and containers instantly identifiable as belonging together.
- **Never** use `git checkout -b` in the main tree — always `git worktree add`
- **Never** hardcode `main`, `master`, or `beta` as base — resolve from `worktree_base_branch`, project config, or the auto-detected default branch
- **Finalization is mandatory**: on merge, rebase onto the base first, then merge, then tear down **only** the worktree and its isolated Docker stack — never the main infra
- **Never remove a dirty worktree**: before `git worktree remove`, run `git status --porcelain` inside it — non-empty output means uncommitted/untracked content would be destroyed. Abort and ask the user (commit / discard / keep) instead of proceeding
- The session file is ephemeral — remove it on cleanup, keep it gitignored
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!