Use when 使用者要開 worktree(隔離環境跑 task 不影響主 working tree),或並行做多條 task(/wt A: ... B: ...)。NOT for main-bound 操作(publish / propagate / spectra-archive),NOT for 只是要切 branch。
Scanned 9/5/2026
Install to Claude Code
npx -y skills add Charles5277/nuxt-supabase-starter --skill wt --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Wt?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/charles5277-nuxt-supabase-starter-79e7db1b)More formats (shields.io, HTML) on the badges page.
---
name: wt
description: "Use when 使用者要開 worktree(隔離環境跑 task 不影響主 working tree),或並行做多條 task(/wt A: ... B: ...)。NOT for main-bound 操作(publish / propagate / spectra-archive),NOT for 只是要切 branch。"
license: MIT
metadata:
author: clade
version: "4.0"
permission_tier: action
---
<!-- 🔒 LOCKED — managed by clade · auto-generated by sync-to-cursor; edit source in .claude/ then re-run sync -->
# /wt — orchestrate worktree task lifecycle
`/wt` is the single entry point for "do work in a worktree". It builds the worktree, auto-routes the executor (Pi astra/luna for non-UI coding/analysis/debug, Claude subagent only for the Form 3/4 cases — see Step 1.8; UI view implementation is never dispatched at all), and reports — without squashing or cleaning up. The worktree branch holds the committed work until the corresponding spectra change is archived; `/spectra-archive` Step 0 (per [[worktree-default]] §5.5) runs `wt-helper merge-back` to atomically absorb the worktree into main, then `/commit` lands the result.
This deferred-landing model guarantees main never carries half-done features between sessions: only fully-reviewed-and-archived changes touch main. The previous v2.0 behavior — `/wt` return time squash + cleanup — accumulated cross-session WIP in main and made `/commit` impossible whenever the 人工檢查 Gate triggered.
The user's only follow-up action is the actual 人工檢查 decision(GUI 的 OK / Issue / Skip)。After that decision, the coordinator invokes `/spectra-archive <change>` and `/commit` itself. If either main-bound step requires a separate clean session, use [[session-tasks.operations]] § Herdr session transport and return the dispatch receipt; **NEVER** ask the user to open main or type either invocation.
## When to invoke
Whenever a coding task (write, edit, refactor, migration prep) or investigation task (analysis, debugging, auditing) is about to start from the main worktree. `/wt` makes per-task worktree isolation cheap; the previous "type a slug, copy a oneliner, open a new session" choreography is gone.
Non-UI tasks are automatically routed to Pi (cheaper, doesn't consume Claude context); UI tasks stay with Claude subagent. Use `--claude` or `--pi` (the older `--codex` spelling is still accepted) to override.
**Do not invoke `/wt`** in these cases:
- The work is read-only AND trivial (quick grep, log inspection, code explanation that writes nothing and doesn't need structured evidence collection).
- The skill being run is main-bound by design (`/spectra-archive`).
- cwd is already inside a session worktree (`git rev-parse --git-dir` contains `/worktrees/`). The current worktree is the workspace; do not nest.
## Invocation forms
### Form 1 — single ad-hoc task
```
/wt <task description>
```
Examples:
```
/wt refactor the cache layer to use LRU eviction
/wt add unit tests for src/parsers/csv.ts covering empty / unicode / quoted rows
/wt update Node version pin to 24 and rerun pnpm install
```
The skill derives a short slug from the task description (lowercased, kebab-case, trimmed to roughly 40 chars). If the user prefers an explicit slug, they MAY prefix the description with `<slug>:` — e.g., `/wt lru-cache: refactor the cache layer to use LRU eviction`.
### Form 2 — parallel multi-task
```
/wt
A: <task A description>
B: <task B description>
C: <task C description>
```
Or single line: `/wt A: task A B: task B`.
Each labeled task becomes its own worktree + subagent. Subagents run concurrently and commit inside their worktrees. There is no squash or cleanup at return — completed worktrees stay parked until archive-time merge-back (see Step 4). A failure in one task does not block the others.
Labels are arbitrary identifiers (A/B/C/feat-x/test-y). The skill normalizes them into slugs.
### Form 3 — dispatch a named next-skill (internal, used by `/handoff` Mode B)
```
/wt <slug>: /<next-skill> <args>
```
Example:
```
/wt fix-auth: /spectra-apply fix-auth
/wt evlog-dpattern: /spectra-ingest evlog-dpattern
```
This form is invoked by `/handoff` Mode B (per [[worktree-default]] §1 and [[handoff]] §2B.5) when the user has selected a worktree-requiring change from the outstanding-work list. The subagent inside the worktree runs `<next-skill>` as its first action.
Direct user invocation of this form is allowed but uncommon — usually the user just types `/wt <task>` and lets the subagent figure out the work.
### Form 4 — Resume interrupted worktree
```
/wt resume <slug>
```
Dispatches a new subagent into an existing worktree whose previous session was interrupted. The subagent reads `WORKTREE-BRIEF.md` at the worktree root for full task context (description, thin brief, progress checklist) and continues from the next unchecked Progress item.
If no worktree exists at the expected path for `<slug>`, error with guidance: "No worktree found for slug `<slug>`. Use `/wt <task>` to create a new one."
To discover available worktrees for resume, run `node scripts/wt-helper.ts list` — the output shows task summary and status for worktrees that have a brief.
## Per-task lifecycle
For each task in the invocation, `/wt` SHALL execute the following sequence. With parallel tasks, steps 2–4 run concurrently across tasks; step 1 runs sequentially (one `wt-helper add` at a time). **There is no squash or cleanup at `/wt` return** — those happen at archive time via `wt-helper merge-back` (per [[worktree-default]] §5.5).
### Step 0 — Resume detection
Before creating a new worktree, check if one already exists at the expected path:
1. Derive the slug from the task description (or from the explicit `resume <slug>` form).
2. Compute the expected worktree path: `<consumer-parent>/<consumer-name>-wt/<slug>/`.
3. If the path exists AND contains `WORKTREE-BRIEF.md`:
- Read the brief file.
- Run `git -C <worktree-path> log main..HEAD --oneline` to see completed commits.
- Run `git -C <worktree-path> status --short` to see uncommitted work.
- **Skip Step 1 entirely** — do NOT call `wt-helper add`.
- Proceed to Step 1.5 (update the brief's `last_updated` timestamp) and Step 2 (dispatch a resume subagent with the brief content + git status as context).
4. If the path exists but has no brief, the worktree was created before this feature. Fall through to the existing "already exists" error from `wt-helper add`.
5. If the path does not exist and the invocation is Form 4 (`/wt resume <slug>`), error: "No worktree found for slug `<slug>`."
6. If the path does not exist, proceed to Step 1 normally.
### Step 1 — Build the worktree (with pre-fork baseline guard)
**MUST Read [baseline-guard.md](baseline-guard.md) before running `wt-helper add`** — 含 unmerged / clean / dirty 三路策略分流、`--baseline-scope-paths` 的對齊要求、stash strategy 的隱性風險與 `rescue` 救援、`--include-unrelated-dirty` 的 bulk-capture 語意與還原三步驟。四條契約(預設不 capture / 帶 WIP 要顯式 flag / 傳了 flag 不准宣稱 main 沒被動到 / 不准手寫 pathspec stash)在 [[worktree-default]] §1。
`/wt` ad-hoc invocation 沒有 spectra change context,所以**不能**做 scope-aware baseline commit(會撞 cross-session WIP)。預設走 **stash-apply** 策略 — 把 main 的 dirty(modified + untracked)一律 stash 起來、fork 後在新 worktree 內 `git stash apply` 把全部 baseline 帶過去,再 drop stash。Subagent 進 worktree 看 baseline 但收到 Step 2 的 warn 段落知道哪些檔不該動。
```bash
node scripts/wt-helper.ts add <slug> \
--task-summary "<一句話:這棵樹要做什麼>" \
--precheck-baseline \
--baseline-strategy stash
```
Run from the main worktree's cwd. The helper:
- Detects main dirty paths(modified / untracked / unmerged)via `git status --porcelain`:
- **Unmerged 非空** → STOP,refuse to fork. User must resolve conflicts first.
- **Clean** → fork directly(no stash needed).
- **Dirty 非空** → `git stash push -u -m wt-baseline/<slug>/<ISO>` on main.
- Normalizes the slug.
- Creates branch `session/<YYYY-MM-DD-HHMM>-<slug>` from `main`.
- Materializes the worktree at `<consumer-parent>/<consumer-name>-wt/<slug>/`.
- Merges `origin/main` if present.
- (stash strategy + has stashed)cd 進 worktree 跑 `git stash apply stash@{0}` + `git stash drop stash@{0}` → worktree 看到 baseline dirty、main 的 stash list 清掉。
- Stash apply 失敗 → warn user,保留 stash entry 供手動恢復(極罕見:worktree 起步是 main HEAD 副本,理論不該衝突)。
Capture the worktree absolute path (the helper prints `cd <path>` and `Branch: <branch>` — parse them, or derive them from the consumer-root + slug convention).
### Step 1.5 — Write WORKTREE-BRIEF.md
After the worktree is created (Step 1) and before dispatching the subagent (Step 2), write `WORKTREE-BRIEF.md` at the worktree root using the Write tool. This persists the full task context so interrupted sessions can seamlessly resume.
The file is already excluded from git tracking via `wt-helper`'s per-worktree `$GIT_DIR/info/exclude` setup.
Template:
```markdown
---
slug: <slug>
branch: <session-branch-name>
consumer: <consumer-name>
created: <current ISO date>
base_sha: <output of git -C <worktree-path> rev-parse HEAD>
status: in-progress
last_updated: <current ISO date>
---
# Task
<original task description verbatim from the /wt invocation>
# Context
<thin brief prepared by the parent session: file paths to touch, rules to
follow, acceptance criteria. This is the same context that goes into the
subagent prompt — duplicated here for persistence across session boundaries.>
# Progress
- [ ] <planned step 1>
- [ ] <planned step 2>
...
# Recovery
If you are a new session resuming this worktree:
1. Run `git log main..HEAD --oneline` to see completed commits
2. Run `git status` to see uncommitted work
3. Continue from the next unchecked Progress item above
4. Follow the subagent contract: selective `git add -- <files>`, no `git add -A`, no `git push`
```
**Progress section**: Decompose the task into concrete steps if possible. If the task is too vague to decompose upfront, write a single item `- [ ] Complete task` — the subagent will refine the checklist as it works.
**For resume (Step 0 detected existing worktree)**: Do NOT overwrite the existing brief. Instead, update only the `last_updated` frontmatter field via Edit tool.
### Step 1.8 — Executor routing
Classify the task to choose the executor. The default routing is automatic; users can override with `--claude` or `--pi` (the older `--codex` spelling is still accepted).
**Invocation override flags** (parsed from args before slug/task extraction):
- `/wt --claude <task>` → force Claude subagent (Step 2)
- `/wt --pi <task>` (or the older `--codex`) → force Pi (Step 2-pi)
- No flag → auto-classify below
**Auto-classification** (check in order, first match wins):
1. **UI view implementation** → **NOT dispatched. The Opus main line does it** (no Step 2 at all — build the worktree, then implement in it directly)
- Task description contains UI keywords: `vue`, `css`, `scss`, `component`, `page`, `layout`, `styling`, `design`, `template`, `responsive`, `animation`, `UI`, `UX`, `視覺`, `畫面`, `樣式`, `介面`
- OR thin brief lists files matching: `*.vue`, `*.tsx`, `*.jsx`, `*.css`, `*.scss`, `pages/`, `components/`, `layouts/`, `views/`
- **NEVER** hand this to Pi (any model) or to a Claude subagent. There is no legal tier for this row — implementation and visual judgement both stay on the main line.
- **NEVER** reroute because the task is large, the hour is late, or a Pi pipeline is already warm for the non-view phases — that pipeline is for non-view work only.
- SoT: [[agent-routing]] § 派不派 不外派清單. This step **NEVER** overrides it.
2. **Analysis/debug work** → **Pi via pi-dispatch.ts** (Step 2-pi-investigate)
- Task description contains investigation keywords: `analyze`, `analysis`, `debug`, `investigate`, `audit`, `scan`, `trace`, `why`, `root cause`, `分析`, `除錯`, `調查`, `掃描`, `追蹤`, `為什麼`
- Rationale: analysis/debug tasks benefit from Pi's structured evidence collection (pi-offload templates). These tasks typically don't need worktree commits — they produce JSON reports.
3. **Non-UI coding work** → **Pi via the Pi dispatcher** (Step 2-pi)
- Everything else: refactoring, adding tests, implementing features, fixing bugs, migrations, config changes, etc.
- Rationale: non-UI coding is the sweet spot for Pi — cheaper, doesn't consume Claude context, follows the same pi-watch-protocol already proven in `/commit` and `/spectra-apply`.
**Form-specific overrides**:
- Form 3 (`/wt <slug>: /<next-skill>`): always Claude subagent — the subagent needs Skill tool access to invoke the next skill
- Form 4 (`/wt resume <slug>`): always Claude subagent — resume requires judgment to pick up from WORKTREE-BRIEF.md
- Form 2 (parallel multi-task): each task independently classified; mixed executors in the same invocation is fine
After classification, report the routing decision to the user before dispatching:
```
Routing: <task> → [pi|claude|pi:analyze|pi:debug] (<reason>)
```
### Step 2 — Dispatch a Claude subagent into the worktree
**MUST Read [dispatch-claude.md](dispatch-claude.md) before dispatching** — 含 Agent tool 參數、subagent prompt template(fresh + resume + form 3 variants)、baseline notice、contract。
摘要:`Agent(name: "wt-<slug>", prompt: <template>)` 派 subagent 進 worktree,cwd 透過 prompt 指定。Parent cwd 不動。Thin brief MUST 由 parent 預消化。
**Same message as the dispatch**: 記下 Agent name/id 與 deadline(deadline 取值依 [[agent-routing]] § deadline 怎麼取),排 [[agent-routing]] § Async keepalive prompt 的 canonical `ASYNC_KEEPALIVE_CONTROL task=none owner=<owner> deadline=<ISO>...`。這條路徑沒有可查 harness task id,**NEVER** 放原 `/wt` input、偽造 task id 或用 `TaskOutput` 推斷狀態。deadline 到達走 `TaskStop(owner)` intervention,terminal notification 前保留 ownership。
### Step 2-pi — Pi dispatch into worktree (non-UI coding)
**MUST Read [dispatch-pi.md](dispatch-pi.md) § Step 2-pi before dispatching** — 含 brief template(Task/Context/Plan-first/Git Baseline/Scope guard/View-layer guard/Commit Authorization)、`Pi dispatcher` 指令、effort 分級表、Watch Protocol。
摘要:寫 brief 到 `/tmp/wt-pi-<slug>-prompt.md` → `Pi dispatcher` background dispatch → Watch Protocol(1500s safety net)。
### Step 2-pi-investigate — Pi analysis/debug into worktree
**MUST Read [dispatch-pi.md](dispatch-pi.md) § Step 2-pi-investigate before dispatching** — 含 investigation 分類(debug/analysis)、`pi-dispatch.ts` 參數、template 選擇、JSON evidence 解析。
摘要:`pi-dispatch.ts --template <template>` 走 pi-offload,產出 structured JSON evidence → 寫入 WORKTREE-BRIEF.md `# Findings`。
### Step 3 — Wait for completion
**All paths — keepalive first**: worktree tasks routinely run past an hour (2026-08-08: 1h43m). Before ending the dispatch turn,follow [[agent-routing]] § 主線靜默上限:Claude subagent 用 `ASYNC_KEEPALIVE_CONTROL task=none owner=<agent-name-or-id> deadline=<ISO>`;pi background Bash 用既有 1500s `ASYNC_KEEPALIVE_CONTROL task=<task-id> owner=<owner> deadline=<ISO>`,不另加第二條。兩者都只承載控制面,**NEVER** 重播原任務;完成時停止。
**Claude subagent path** (Step 2): The Agent tool call returns when the subagent finishes — that describes how the result arrives, **not** what the mainline does meanwhile. Parse its report to determine success vs. failure.
**Pi coding path** (Step 2-pi): Wait for `<task-notification>`. On completion, read stdout and verify:
1. **Phase boundary**: `git -C <worktree-path> log --oneline main..HEAD` — should have commits with `🧹 chore: wt <slug>` format
2. **View-layer drift double-check**:
```bash
git -C <worktree-path> diff main..HEAD --name-only \
-- '*.vue' '*.tsx' '*.jsx' '*.css' '*.scss' \
'app/pages/**' 'app/components/**' 'app/layouts/**' \
'pages/**' 'components/**' 'layouts/**' 'views/**'
```
Any hit → AskUserQuestion: [1] reset + redispatch / [2] accept + mainline fixes view parts / [3] abort
3. **Scope discipline**: `git -C <worktree-path> diff main..HEAD --name-only` vs. brief's scope declaration
**Pi investigation path** (Step 2-pi-investigate): Wait for `<task-notification>`. On completion, parse dispatcher's stdout JSON. Exit code 0 → read `result` field for structured evidence. Write findings into WORKTREE-BRIEF.md `# Findings` section.
For all paths, verify commits exist (if applicable):
```bash
git -C <worktree-path> log --oneline main..HEAD
```
### Step 4 — Report (no squash, no cleanup)
After all tasks in the invocation have either completed (subagent committed) or failed (worktree preserved with whatever WIP exists), emit one aggregated report:
```
✅ A (lru-cache) [pi]: committed — 5 files, 2 commits on branch session/<date>-lru-cache
<one-line summary from pi stdout>
pending: /spectra-archive <change> will absorb via wt-helper merge-back
✅ B (csv-tests) [claude]: subagent committed — 2 files added on branch session/<date>-csv-tests
✅ C (perf-audit) [pi:analyze]: JSON result — 8 findings, status: pass
findings written to WORKTREE-BRIEF.md # Findings
❌ D (node-upgrade) [pi]: pi fail — pnpm install exited 1
worktree preserved at ~/offline/<consumer>-wt/node-upgrade/
branch: session/<date>-node-upgrade
Pending worktrees: <N> (absorbed at /spectra-archive of matching change)
```
The `[pi]` / `[claude]` / `[pi:analyze]` / `[pi:debug]` tag indicates which executor was used. This helps the user understand the execution path and cost profile.
**Key shift from v2.0**: `/wt` no longer squashes or cleans up. Each worktree's branch carries committed work until its corresponding `/spectra-archive` run; archive Step 0 runs `wt-helper merge-back --auto-stash --noop-if-missing <change-name>` to atomically absorb + cleanup. This means main's working tree stays clean of in-progress work between sessions.
For non-spectra ad-hoc tasks (Form 1 with no corresponding change), the user runs `wt-helper merge-back <slug>` manually when ready to land.
## Failure handling
### Claude subagent task failure
Subagent reports failure or exits without commits. Preserve the worktree and branch; report the path. The user can inspect via `git -C <wt-path> log/diff/status` from the main session — no need to switch cwd.
When the user fixes the underlying issue, they can either:
- Re-run the subagent in the same worktree by passing the worktree path explicitly to a new Agent invocation, or
- `wt-helper cleanup <slug> --force --force-discard-unland` to discard the worktree and start fresh via `/wt`.
### Pi task failure
Pi exits with non-zero or `<task-notification status=failed>`. Preserve the worktree and branch; report the error tail from stdout/stderr.
Recovery options:
- **Retry with adjusted brief**: fix the issue in the brief (scope, paths, instructions), write a new prompt file, re-dispatch the `Pi dispatcher` into the same worktree (it already exists, no need for `wt-helper add`).
- **Switch to Claude**: re-dispatch as Claude subagent via `/wt --claude resume <slug>` (Claude picks up from WORKTREE-BRIEF.md).
- **Discard**: `wt-helper cleanup <slug> --force --force-discard-unland`.
For Pi investigation failures (Step 2-pi-investigate), exit code 2 (business fail) means the investigation ran but didn't meet acceptance criteria — read `result` JSON for details. Exit code 3 (mechanical failure) means Pi itself broke — check `/tmp/pi-<label>-stderr.log`. Exit code 4 (quota) means rate limited — wait or switch to Claude.
### Squash conflicts (no longer at `/wt` time)
Squash happens at archive time (Step 0 of `/spectra-archive`, calling `wt-helper merge-back`). Conflict handling lives there — see [[worktree-default]] §5.5 and `spectra-archive/SKILL.md` Step 0. `/wt` does not encounter squash conflicts because it never squashes.
## After `/wt` completes
Worktree(s) hold committed work on their session branches. Main's working tree is untouched.
The user's next moves:
1. (Spectra change worktree) When the change is ready to archive, run `/spectra-archive <change-name>`. Step 0 absorbs the worktree via `wt-helper merge-back --auto-stash --noop-if-missing`. Subsequent archive gates inspect the post-squash state.
2. (Ad-hoc Form-1 worktree) When ready to land, run `node scripts/wt-helper.ts merge-back <slug> --auto-stash`. The diff lands on main's working tree; main commit ceremony via `/commit`.
3. Once one or more worktrees have been absorbed and main has accumulated diff, run `/commit` on main.
`/wt` does NOT:
- Squash to main.
- Cleanup worktrees.
- Commit on main.
- Push anywhere.
These remain explicit later actions (archive + commit).
## Edge cases
### Degenerate form: `/wt <single-token>` with no description and no `:`
If the user types just `/wt fix-auth` (no description, no `:`-prefixed next-skill), prompt the user to clarify whether they want:
- An ad-hoc task in a new worktree (ask for the task description).
- A long-lived worktree session (deprecated via `/wt`; suggest `node scripts/wt-helper.ts add fix-auth --task-summary "<一句話>"` + opening a fresh session in the resulting path).
Do NOT silently build a worktree with no task — that's the deprecated v1 behavior and is gone.
### cwd already inside a session worktree
If `git rev-parse --git-dir` shows `/worktrees/`, refuse to invoke `/wt`. The current worktree IS the workspace. Tell the user: "Already inside worktree <name>; do the work here. Use `/wt` only from the main worktree."
### Subagent commits but you can't tell if the task fully succeeded
The subagent's reported status is the authority. If it says "done", proceed to squash. If the subagent's commits exist but it failed to report cleanly, treat as failure (preserve worktree, report ambiguity).
## Related rules
- [[worktree-default]] — full rule baseline (§1 invariant, §5 mechanic, §6 tools).
- [[agent-routing.pi-watch-protocol]] — Pi dispatch standard, Watch Protocol, Plan-first / Git baseline / Commit Authorization hard rules.
- [[handoff]] — Mode B dispatch path that invokes `/wt <slug>: /<next-skill>`.
- [[session-tasks]] — shared `<YYYY-MM-DD-HHMM>-<slug>` naming convention.
- [[scope-discipline]] — when a `/wt` task drifts beyond its slug's scope, open a separate `/wt` task or escalate to `/spectra-propose`.
- [[pi-offload]] — template registry for analysis/debug dispatch (`~/offline/clade/vendor/snippets/pi-offload/`).
## Maintenance commands
```bash
node scripts/wt-helper.ts list # list session worktrees
node scripts/wt-helper.ts merge-back <slug> # atomically land worktree → main
node scripts/wt-helper.ts merge-back <slug> --dry-run # preview blockers
node scripts/wt-helper.ts merge-back <slug> --auto-stash # stash main blockers
node scripts/wt-helper.ts land-pending <slug> # alias for grandfathered worktrees
node scripts/wt-helper.ts prune # remove merged ones interactively
node scripts/wt-helper.ts cleanup <slug> --force --force-discard-unland # discard worktree + commits
node scripts/stash-reconcile.ts # plan recovery for wt-merge-block/* stashes
```
`merge-back` is the primary post-`/wt` action for ad-hoc Form-1 worktrees and for early-landing when needed. `/spectra-archive` calls it automatically as Step 0; users invoke it manually for non-spectra work.
`cleanup --force --force-discard-unland` is for discarding unwanted worktrees (subagent fail, abandoned exploration). It permanently loses the branch's commits; use `merge-back` first to preserve the work.
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!