worktree 並列開発 (wt)
wt コマンドが、git worktree と herdr workspace を一体で管理する。対象リポジトリ内の任意の場所から実行する。
wt new <task> [--base <ref>] [--no-claude] [--prompt <text>|--prompt-file <path>]
# worktree + workspace + Claude Code 起動
wt bootstrap [<path>] # 既存 worktree に欠落ファイルを補完
wt open <task> # 既存 worktree を workspace として開き直す
wt list # worktree ↔ workspace の対応一覧
wt peers [--json] # この repo の Claude Code セッション一覧 (会話の宛先)
wt merge [<task>] # worktree ブランチを本体の現在ブランチへマージ
wt rm [<task>] [--force] # worktree / workspace / ブランチを削除
- worktree は native と同じ
<repo>/.claude/worktrees/<task名>に、ブランチworktree-<task名>で作られる (WT_HOMEを設定すると従来の集約置き場$WT_HOME/<repo名>/<task名>)。 --base省略時は本体 checkout の現在ブランチから分岐する。--prompt/--prompt-fileは worktree 側で起動する Claude Code への初期プロンプト。herdr サーバが無いとプロンプトを渡せないため die する。- worktree 側の claude は既定で
-n wt-<task> --model opus --permission-mode auto付きで起動する(WT_CLAUDE_ARGSで差し替え、空文字でフラグ無し。-nは常に付き、WT_CLAUDE_ARGS側の-nが後勝ちで上書きする)。 merge/rmは worktree 内から task 省略で実行でき、自分の worktree を対象にする(worktree 側セッションの/wt-merge/wt-cleanが使う)。- herdr サーバが起動していなければ git worktree の作成だけにフォールバックする。
native worktree との使い分け(統一方針)
Claude Code 自身も worktree を作る(claude --worktree、subagent の isolation: worktree、desktop の並列セッション)。wt と native は同じ置き場・同じブランチ命名(<repo>/.claude/worktrees/<name>/、ブランチ worktree-<name>)を共有し、同じ worktree を指す。違うのは作り方と補完方法で、native は fresh コピー中心・base 既定 origin/HEAD、wt は herdr workspace 起動と symlink 補完込み・base 既定は本体の現在ブランチ。同じ実体なので native で作った worktree を wt open / wt bootstrap / wt rm でそのまま扱える。単一の補完 hook が両方をまたげないため、**.worktreeinclude を「持ち込むファイル一覧の唯一の正」**として両方で共有する。
.worktreeinclude(repo root、要コミット): fresh checkout に要る gitignore 済みファイルを.gitignore構文で列挙。native はこれを読んで自動でコピーし、wt bootstrapもこれを読んで本体から実体コピーする(既存ファイルは上書きしない)。フックが worktreeinclude を読む必要はない。scripts/worktree-setup(repo フック、要コミット): コピーで表せない補完=依存インストール・環境 symlink 再生成・native rebuild。wtはこれに委譲する。native はこのフックを呼ばないので、依存が要る repo の native worktree は作成後にwt bootstrap <path>で仕上げる。- base の既定が違う(native=
origin/HEADfresh /wt=本体の現在ブランチ)。揃えたいときは settings に"worktree": { "baseRef": "head" }。 .worktreeinclude/ フックはコミット必須。native の fresh base は未コミットファイルを見ない。
使い分け: 軽量・使い捨て・subagent 分離は native(claude --worktree)、herdr workspace 起動や欠落補完込みで立ち上げたいときは wt。同じ場所を指すので、native で作ったものを後から wt open / wt bootstrap で仕上げてもよい。
bootstrap の分担
共通処理 (wt 本体):
.worktreeincludeに列挙されたファイルを本体から実体コピー (既存ファイルは上書きしない)- 本体の
.envを worktree へ symlink (実体ファイルが既にあれば触らない。.worktreeincludeに.envがあればコピーが優先される) .claude/settings.local.jsonをコピー (Claude Code の許可設定の引き継ぎ)- repo フックがあれば委譲、無ければ lockfile から検出した package manager で依存インストール
repo 固有処理 (repo の scripts/worktree-setup、実行可能ファイル):
- cwd = worktree で呼ばれ、
WT_MAIN_ROOT(本体 checkout) とWT_TARGET(worktree) が渡される - 依存インストールを含めてフック側の責任 (フックがあると wt は install しない)
- 推奨実装: 環境 symlink の再生成 → 依存インストール → native rebuild。worktreeinclude の補完は wt 本体が済ませているのでフックで読む必要はない。
WT_SKIP_DEPS=1で config 補完だけ回せると再補完が速い - 典型的な内容: gitignore された secrets/credentials の symlink 共有、ローカル DB のコピー独立、native addon の補完
- monorepo での参照実装イメージ: gitignore された config の symlink・環境固有ファイルの symlink 再生成・各パッケージ (
client/infra等) のnpm ci・Python パッケージのuv syncを 1 つのフックにまとめる
セッション間の会話 (dev ↔ worktree)
worktree 側セッションと dev 側セッションは、Claude Code のセッション間メッセージ (ListAgents / SendMessage) で直接会話できる。仕組みは Claude Code 側にあり (レジストリは <config>/sessions/<pid>.json、name が宛先)、wt が担うのは宛先の決定だけ。
wt newはclaude -n wt-<task>で起動するので、worktree 側セッションの宛先名はwt-<task>に固定される。dev 側は task 名から宛先を決められる。- dev 側セッションの名前は Claude Code の自動命名(
<ディレクトリ名>-<2 文字>)。wt peersのrole=dev行で引く。 wt peersはこの repo(本体 + 全 worktree)に属する生存中のセッションを role (dev/ task 名) 付きで一覧する。死んだセッションのレジストリファイルは残るので生存を確認し、cwd が worktree のサブディレクトリでも正しく分類する。--jsonで機械可読。- 送受信の作法(宛先解決、初回の
[ref]再送、返信はfromを使う、権限の回し合いをしない)は skill/wt-askに集約する。
peer レジストリに載らないセッション(古い Claude Code で起動したもの、既に終了したもの)とは会話できない。wt peers にも ListAgents にも出てこなければ宛先にできないので、レビューページやコミットメッセージ経由の受け渡しに切り替える。
既知の注意点
~/.npmrcにignore-scripts=trueがあると、npm ciだけでは native addon (better-sqlite3 等) がビルドされない。フックでnpm rebuild <pkg> --ignore-scripts=false --foreground-scriptsするか、本体のビルド済み.nodeをコピーする。- Claude Code が自分で作る worktree (
.claude/worktrees/*) も同じ欠落を持つ。テストや実行が必要ならwt bootstrap <path>で補完する。 - 本体 checkout の未コミット変更は worktree に入らない (worktree はコミット済み ref から分岐する)。
.worktreeincludeのコピー (wt / native) ではディレクトリパターンsecrets/がそのまま使える。フックで symlink する場合のみ末尾スラッシュ無し (secrets) で書く。.worktreeincludeの否定パターン!は、親ディレクトリごと除外した配下を再 include できない (gitignore の仕様)。secrets/+!secrets/xは効かず、secrets/*+!secrets/xと書く。- 空ディレクトリはコピーされない (git が列挙しないため)。
slash command skill
wt repo は 8 つのコマンド skill を同梱し、install.sh が ~/.claude/skills/ に配置する。
| skill | 実行する側 | 役割 |
|---|---|---|
/wt <作業内容> |
dev (本体) | worktree 名を生成し、初期プロンプト付きで worktree + Claude を起動 |
/wt-detail <作業内容> |
dev (本体) | コード調査 → 不明点をユーザーに確認 → 実装プランを初期プロンプトとして worktree に渡す |
/wt-split <親issue> |
dev (本体) | 親 issue を子 issue に分解して起票し、独立な子ごとに worktree + Claude を並列起動(依存の子は再実行で追加起動) |
/wt-ask <内容> |
両方 | wt peers で宛先を解決し、相手セッションに質問・報告を送る |
/wt-review |
worktree | 変更の diff からレビュー用 HTML を生成してブラウザで開き、マージ承認を待つ |
/wt-auto-review |
worktree | /wt-split の子タスク専用。新規 subagent の AI レビュー PASS で承認ゲートを満たし、マージまで自動で進める |
/wt-merge |
worktree | 自分のブランチを本体の現在ブランチへマージ(レビュー指示があれば承認後) |
/wt-clean |
worktree | 未コミット・未マージを検査し、クリーンなら自分の worktree を片付けて閉じる |
このほか契約 skill local-artifact を同梱する。Artifact と同一の設計規約で HTML を作り、claude.ai に publish せずローカル公開する(skeleton / テーマトグル / mermaid の再現込み)。/wt-review のレビューページ生成はこれに従う。