From wt-manager
git worktree を扱う際は必ず `wt` 系コマンドを使う (内包化済みで Claude の Bash からも直接実行できる)。「worktree切って」「並列で別タスク」「PR検証用にworktree」「実験用に別ブランチで」などの依頼で必ず発動する。`git worktree add` を直接叩かず `wt new -d "<目的>"` で作成する、PR作成後は `wt set <name> "<内容>"` で description を更新する、並列実行は `wt claude <name>` で Agent View に乗せる、worktree への移動は `EnterWorktree({path})` を使う (name モードでの新規作成と ExitWorktree remove は hook が deny)、というルールを Claude に守らせるためのスキル。
How this skill is triggered — by the user, by Claude, or both
Slash command
/wt-manager:wt-managerThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
`wt` 系コマンドは `.zshrc` から source された **zsh 関数** で、各worktreeの「何用か」をメタデータとして `git config --worktree wt.description` に保存しつつ運用する仕組み。直接 `git worktree add` を叩くと description が抜け落ち、後で何用のworktreeか分からなくなるので、**worktree操作はすべて `wt` 経由で行う**。
wt 系コマンドは .zshrc から source された zsh 関数 で、各worktreeの「何用か」をメタデータとして git config --worktree wt.description に保存しつつ運用する仕組み。直接 git worktree add を叩くと description が抜け落ち、後で何用のworktreeか分からなくなるので、worktree操作はすべて wt 経由で行う。
以下の依頼パターンを検知したら、このスキルのルールに従って動く:
明示的に「git worktree add を使って」と指定された場合のみ、直接叩いてよい。
wt new -d で作るgit worktree add を直接叩かない。代わりに:
wt new -b <new-branch> <dir> [base-ref] -d "<目的を自然文で>"
<dir> はディレクトリ名のみ (絶対パス・相対パス禁止)。配置先は自動検出される-d の description は必須扱い。後で「何用か分からない」を防ぐため、PR番号 / 検証対象 / 目的 を含める[base-ref] 省略時は git config wt.baseRef → 現在のHEAD の順でフォールバックcd / claude --bg 起動は連動しない。次の操作は wt cd / wt claude で別途呼ぶ例:
wt new -b feature/PROJ_foo_pr-1234-verify task-pr-1234 origin/develop \
-d "PR#1234 検証用 / Agent Viewで並列レビュー"
PRを作ったら、そのworktreeの description に PR 番号・状態を反映する:
wt set <worktree名> "PR#5678 レビュー待ち / レビュアー: @xxx"
git config --worktree wt.description "<内容>" でも同じ (名前解決が不要なだけで、書き込まれるキーは同一)更新タイミング:
gh pr create で作成した直後wt claude で Agent View に乗せるユーザーが「別タスクを並列で進めて」「同時に走らせて」と言ったら、wt claude を使う:
wt claude # fzf選択 → claude --bg (idle、プロンプト無しで起動だけ)
wt claude <name> # name指定でfzfスキップ (Claude起点の非対話用)
wt claude <name> -n "<表示名>" # 表示名を明示指定
-n): claude --bg -n "<label>" でセッションに表示名を付ける (Agent View / 端末タイトルで識別)。既定は wt.description、無ければディレクトリ名。-n "<表示名>" で上書きClaudeが過去に git worktree add で作ってしまったものや、~/myApplication/<task>/ のような既存資産にも description を付ける運用にする。
wt set # fzfで対象選択 → $EDITOR or インラインでdescription入力
wt set <name> "<desc>" # 非対話で直接設定 ("" でクリア)
「このworktree何用?」と分からなくなったら wt ls で一覧確認 → 不明なものに wt set で後付け。
ここまでの Rule 1〜4 は 人間が対話 zsh シェルから wt を使う前提の動線。Claude 起点では以下を加える。
前提: wt は internal ヘルパ (_wt_*) を wt() 内に内包しており、Claude の Bash(zsh) からも動作する。fzf 対話を避けるため引数指定の非対話形を使うこと:
wt new -b <branch> <dir> [base] -d "<目的>" # 新規作成
wt ls -p # 一覧 (-p で絶対PATH列付き)
wt set <name> "<desc>" # description設定 ("" でクリア)
wt rm <name> -y [-b] # 削除 (-y必須。-bでブランチも)
wt claude <name> # 並列セッション投入 (idle)
wt cd だけは効かない(後述「wt cd の制約」)。worktree モデルの二重化(harness の .claude/worktrees/ と wt 規約 <repo親>/<dir>)を避けるため、worktree の「移動」「削除」は Rule 5/6 に従う。これらは wt-manager の PreToolUse hook で機械的に強制される(EnterWorktree の name モードと ExitWorktree の remove を deny)。
EnterWorktree({ path }) を使うwt cd は呼び出し元シェルの cwd を変える関数で、Claude の Bash(毎回独立シェル)には効かない。Claude がセッションを別 worktree へ移すときは harness の EnterWorktree を使う:
EnterWorktree({ path: "<絶対パス>" }) (パスは wt ls -p / git worktree list で取得)ExitWorktree({ action: "keep" }) のみ。"remove" は使わない (削除は wt rm が担当)EnterWorktree の name モード (新規作成) は使わない — .claude/worktrees/ 配下に origin/<default> から切る挙動で、wt の description も配置規約 (parent パターン) も無視するためhook が
EnterWorktree(name あり) とExitWorktree(action:"remove") を deny し、deny 理由で正しいフローへ誘導する。
wt new を使う内包化により wt new は Claude の Bash から動くので、新規作成も人間と同じく wt 経由にする (引数をフル指定すれば fzf を介さず非対話で完結):
wt new -b <branch> <dir> [base-ref] -d "<目的>"
# 作成された絶対パス (出力 "wt new: created <path>" / wt ls で確認) に対して
EnterWorktree({ path: "<作成された絶対パス>" })
wt new は作成のみで cd は連動しない。入るのは EnterWorktree({ path }) (Rule 5)git worktree add の直叩きは従来どおり禁止 (description が抜けるため)。Claude 起点でも例外なし人間は
wt new -d "<目的>"→wt cd、Claude はwt new -d "<目的>"→EnterWorktree({ path })。作成コマンドは共通、入り方だけが違う。
| コマンド | 用途 | 補足 |
|---|---|---|
wt | (引数なし) fzfでworktree選択 → エディタ(code/zed)選択 → 起動 | vcw 後継。code選択時はディレクトリを直接開く |
wt new -b <branch> <dir> [base] [-d desc] | 新規作成 + description記録 | 作成のみ、cd/claude起動は連動しない |
wt ls [-p] | メタデータ付き一覧 | DIR / BRANCH / AGE / DESC。-p で絶対PATH列を追加 |
wt set [<name>] ["<desc>"] | description編集/設定 | 無引数→fzf+$EDITOR。<name> "<desc>" で非対話 ("" でクリア) |
wt rm [<name>...] [-y] [-b] | worktree削除 | 無引数→fzf複数選択+対話確認。-y 確認スキップ、-b ブランチも削除 |
wt claude [<name>] [-n <label>] | Agent View に背景セッション投入 (idle) | name指定でfzfスキップ。表示名は既定で wt.description、無ければディレクトリ名。-n で上書き |
wt cd <name> | worktreeに移動 | cwd伝播のため ClaudeのBash/CIでは無意味 (→ EnterWorktree({path})) |
wt new の <dir> の解決ルール)repo_root = git rev-parse --show-toplevelparent = dirname $repo_rootparent == $HOME かつ basename($repo_root) != "main"): ~/<repo>-worktrees/<dir>/<parent>/<dir>/例:
~/m-tojo-marketplace/ で wt new ... task-foo → ~/m-tojo-marketplace-worktrees/task-foo/~/myApplication/main/ で wt new ... task-foo → ~/myApplication/task-foo/wt cd の制約内包化により他のサブコマンド (wt new/ls/set/rm/claude) は Claude の Bash(zsh) からも動くが、wt cd だけは別。wt cd は呼び出し元シェルの cwd を変える関数だが、Claude の Bash ツールは各呼び出しが独立シェルなので cd が次の呼び出しに残らない。
Bash ツールで wt cd を呼んでも、次のコマンドは元のディレクトリで実行されるClaude がセッションごと別 worktree へ移るなら EnterWorktree({ path }) (Rule 5)。単発で別 worktree のコマンドを叩くだけなら git -C <path> ...、または cd <絶対パス> && <コマンド> を1コマンドに連結する。
| キー | スコープ | 内容 |
|---|---|---|
wt.description | per-worktree (git config --worktree) | 「何用か」を自然文で |
wt.baseRef | per-repository (git config) | wt new の base 省略時のデフォルト (例: origin/develop) |
description は自然文。status / PR番号 / レビュアー / 期限などはすべて description 内に書き込む (フィールド分割しない方針)。
wt.zsh はトップレベルに公開関数 wt 1つだけを定義し、各サブコマンド (wt new/ls/set/rm/claude/cd) の実体 _wt_* は wt() の中に内包する (理由は「内包設計」節)。配置は以下の二重構成:
| 役割 | パス | 用途 |
|---|---|---|
| 正本 | ~/dotfiles/dotfiles/wt.zsh | .zshrc から相対パスで source される実体。ユーザの対話シェルで wt が使えるのはこれが load されているため |
| 配布用スナップショット | ${CLAUDE_PLUGIN_ROOT}/skills/wt-manager/scripts/wt.zsh | プラグイン同梱の参照用コピー。dotfiles を持たない環境でも実装を確認できる |
.zshrc 側のロード規約 (相対パス)wt.zsh は .zshrc と同一ディレクトリに配置し、相対パスで source する:
# ~/dotfiles/dotfiles/.zshrc の末尾
source "${${(%):-%x}:A:h}/wt.zsh"
${${(%):-%x}:A:h} は zsh のイディオムで「現在 source 中のファイル (= .zshrc 本体) の解決済み絶対ディレクトリ」を返す。:A で symlink (~/.zshrc → ~/dotfiles/dotfiles/.zshrc 等) も解決されるため、~/.zshrc がどこに置かれていても同居している wt.zsh を拾える。
~/dotfiles/dotfiles/wt.zsh が存在) → 正本 を優先で Read${CLAUDE_PLUGIN_ROOT}/skills/wt-manager/scripts/wt.zsh) を Read同梱版は正本のスナップショット (現状は手動同期)。正本を更新したらスナップショットにも反映する運用。乖離が疑われる場合は両方の git log / diff を確認する。
wt() に内包するか)internal ヘルパ _wt_* は wt() 実行時に関数内で定義し、終了時に unfunction -m '_wt_*' で破棄する。狙いは2つ:
_wt_* がグローバル名前空間や補完候補に常駐しない (公開ゼロ)Bash で動く: Claude Code のシェルスナップショットは「先頭 _ のトップレベル関数」を除外する。_wt_* をトップレベルに置くと Claude から wt new が _wt_new not found で落ちるが、wt() 内包なら snapshot に載るのは wt だけで、wt 経由で全サブコマンドが動くテスト (wt.test.zsh) は _wt_* を直接呼ぶため、環境変数 WT_KEEP_INTERNAL=1 で破棄を抑止し、一度 wt を呼んでヘルパをグローバル展開してからテストする。
hooks/hooks.json + scripts/guard-worktree.sh)worktree モデルの二重化を防ぐガード。EnterWorktree / ExitWorktree を matcher にとり、deny 理由で正しいフローへ誘導する:
EnterWorktree に name あり (新規作成) → deny (→ wt new → EnterWorktree({ path }))ExitWorktree の action:"remove" → deny (→ ExitWorktree({ action:"keep" }) + wt rm)EnterWorktree({ path }) / ExitWorktree({ action:"keep" }) は許可git worktree add を直接叩く (ルール違反、descriptionが抜ける。Claude 起点も wt new を使う=例外なし)wt new を実行するwt rm での手動削除のみ)wt cd を非対話シェル / CI / Claude の Bash から使う (Claude は Rule 5 の EnterWorktree({ path }))EnterWorktree の name モード (新規作成) / ExitWorktree({ action: "remove" }) を使う (配置規約・descriptionを無視 / 削除は wt rm)gwta (= git worktree add エイリアス, ~/dotfiles/dotfiles/.zshrc) は維持。wt new とは別物として共存vcw / delete-vcw zsh関数 (dotfiles) と VSCodeColorizer プラグインは、wt への統合完了に伴い 1.4.0 で削除済みCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub kuu13580/dotfiles --plugin wt-manager