Configure permissions
概要
Claude Code が何にアクセスし何をできるかを、ルール・モード・managed policy で細かく制御する仕組み。permission 設定はバージョン管理にチェックインして組織で共有でき、開発者ごとに個別調整もできる。
仕様
権限の階層
| ツール種別 | 承認の要否 | 「Yes, don't ask again」の効果 |
|---|---|---|
| Read-only(ファイル読み取り、Grep) | 作業ディレクトリと追加ディレクトリ内では不要 | 該当なし |
| Bash コマンド | 組み込みの read-only コマンド集合を除き必要 | リポジトリとコマンドごとに恒久保存 |
| ファイル変更(Edit / Write) | 必要 | セッション終了まで |
- 恒久保存される承認(Bash コマンドなど)は、git リポジトリルートの
.claude/settings.local.jsonに保存される。worktree はメインの checkout に解決される。そのリポジトリ内のどこで始めたセッション(サブディレクトリや worktree を含む)にも適用される - git リポジトリ外、およびリポジトリルートがホームディレクトリの場合は、起動したディレクトリに保存される
- v2.1.211 より前は常に起動ディレクトリに保存されていた
- Bash / PowerShell の permission prompt で
Ctrl+Eを押すと、コマンドの説明(何をするか、なぜ実行するか、何が起こりうるか)が Low risk / Med risk / High risk のラベル付きで表示される。押したときにだけモデルへ送られる。表示しても実行はされない。もう一度押すと隠れる - このショートカットを切るには
~/.claude.jsonのpermissionExplainerEnabledをfalseにする
ルールの種類と評価順
-
Allow: 手動承認なしでツールを使える
-
Ask: 使おうとするたびに確認を求める
-
Deny: 使用を禁止する
-
評価順は deny → ask → allow。この順で最初に一致したものが結果を決め、ルールの具体度は順序を変えない
-
Bash(aws *)のような広い deny ルールは、より狭い allow ルールBash(aws s3 ls)に一致する呼び出しもブロックする。ask と allow の間も同様 -
素のツール名(
Bash)の deny ルールはツール自体を Claude のコンテキストから取り除く。ただしEndConversationは例外で、他のツールが残っている限り deny で取り除けず、ask でもプロンプトを出さない -
Bash(rm *)のようなスコープ付きルールはツールを残し、一致する呼び出しをブロックする -
permission ルールは Claude Code が強制するものであり、モデルが強制するものではない。プロンプトや
CLAUDE.mdの指示は Claude が何を試みるかを形作るが、Claude Code が何を許すかは変えない -
/permissionsで全ルールと、それぞれの出所となるsettings.jsonを確認・管理できる
ルール構文
- 形式は
ToolまたはTool(specifier) - 括弧なしのツール名はそのツールのすべての使用に一致する。
Bash(*)はBashと等価
入力パラメータによる一致
- deny と ask ルールは
Tool(param:value)で任意のツールのトップレベル入力パラメータに一致できる(例:Agent(model:opus)、Agent(isolation:worktree)、Bash(run_in_background:true)) - allow ルールはこの形式を使わず、各ツール固有の specifier 構文を使う
- パラメータ名はツール入力の直接のフィールドでなければならない。オブジェクトや配列の中にネストしたフィールドは対象外
- 1 ルールにつき 1 パラメータ。2 つを条件にするならルールを 2 つ書く
- 値では
*が任意の文字列にマッチする。*が無ければ完全一致 - モデルが省略したパラメータには決して一致しない(
Agent(model:*)はmodel未設定の呼び出しに一致しない) - 値は正規化前の Claude が送るリテラル入力と比較される。
Agent(model:opus)はエイリアスopusに一致するが完全なモデル ID には一致しない - コロン前後の空白は無視される
- ツールの主要コンテンツフィールドはこの方法で指定できない(Bash / PowerShell の
command、Read / Edit / Write のfile_path、Grep / Glob のpath、NotebookEdit のnotebook_path、WebFetch のurl)。Bash(command:rm *)のようなルールは無視され起動時に警告が出る
ツール名のワイルドカード
- deny と ask ルールはツール名の位置に glob を受け付ける。パターンはツール名全体に一致する必要がある。
"*"は全ツール、"mcp__*"は全サーバーの全 MCP ツールに一致する - allow ルールは、リテラルの
mcp__<server>__接頭辞の後にのみ glob を受け付ける。サーバー部分に glob は使えない。mcp__puppeteer__*、mcp__github__get_*は有効。"*"/"B*"/"mcp__*"のような anchor されない allow glob は警告付きでスキップされ何も自動承認しない - 既知のツールに一致しない deny / ask ルールは起動時に警告が出る。
_や*を含むツール名はこのチェックの対象外 - トランスクリプトや permission ダイアログのラベルは正規名と異なることがある(例:
Stop Taskの正規名はTaskStop)。permission ルールと hook matcher は正規名にのみ一致する
Bash ルール
*によるワイルドカードは先頭・中間・末尾のどこでも使える- 単一の
*はスペースを含む任意の文字列に一致するため、1 つのワイルドカードが複数の引数にまたがる - 末尾のスペース付き
*(Bash(ls *))は語境界を強制し、接頭辞の後にスペースか文字列終端が必要。Bash(ls *)はls -laに一致するがlsofには一致しない。Bash(ls*)は両方に一致する :*接尾辞は末尾ワイルドカードと等価。Bash(ls:*)はBash(ls *)と同じ。:*はパターン末尾でのみ認識され、Bash(git:* push)のコロンはリテラル扱い- permission ダイアログで「Yes, don't ask again」を選ぶとスペース区切り形式が書かれる
複合コマンド
- 認識される区切りは
&&、||、;、|、|&、&、改行。ルールは各サブコマンドに独立して一致する必要がある - 複合コマンドを「Yes, don't ask again」で承認すると、承認が必要な各サブコマンドごとに別々のルールが保存される。サブディレクトリへの
cdはそのパスの Read ルールを生成する。1 つの複合コマンドで最大 5 つのルールが保存される
ラッパー
- Bash ルールの照合前に固定のラッパー集合が取り除かれる:
timeout、time、nice、nohup、stdbuf、シェル組み込みのcommandとbuiltin、zsh のnoglob。クエリ形式のcommand -vと zsh のnocorrectは取り除かれない - 既知の安全な環境変数の先頭代入も取り除かれる(
Bash(npm test *)はNODE_ENV=test npm testに一致する)。それ以外の変数代入を越えて allow ルールは一致しない。deny / ask ルールは任意の先頭代入を越えて一致する - フラグ無しの
xargsも取り除かれる。xargs -n1 grep patternのようにフラグがある場合はxargsコマンドとして照合される - このラッパー一覧は組み込みで設定できない。
direnv exec、devbox run、mise exec、npx、docker execなどの環境ランナーは含まれない。Bash(devbox run *)はrunの後に来るもの(devbox run rm -rf .を含む)に一致してしまうため、Bash(devbox run npm test)のようにランナーと内側のコマンドを両方含む具体的なルールを書く watch、setsid、ionice、flockのような exec ラッパーは常にプロンプトを出し、Bash(watch *)のような接頭辞ルールで自動承認できない。-execや-delete付きのfindも同様
read-only コマンド
- 組み込みで read-only と認識され、すべてのモードでプロンプトなしに実行されるコマンド:
ls、cat、echo、pwd、head、tail、grep、find、wc、which、diff、stat、du、cd、およびgitの read-only 形式など - この集合は設定できない。プロンプトを要求するには
askまたはdenyルールを追加する - すべてのフラグが read-only のコマンドでは引用符なしの glob が許される(
ls *.ts、wc -l src/*.py)
それでもプロンプトが出る場合:
- 書き込み可能フラグを持つコマンドでの引用符なし glob:
find、sort、sed、gitなど。glob が-deleteのようなフラグに展開されうるため - 別 daemon を指す
docker:-H、--context、Podman の--url/--connectionなどのフラグがある場合 - パスを開くフラグ付きの
file:-m/--magic-file、-f/--files-from - Windows のネットワークパス:
\\server\share\fileのような UNC パスを引数に含むコマンド。PowerShell ツールにも同じチェックが適用される - 解析できないコマンド: 完全に解析できない場合は承認を求める。10,000 文字を超えるコマンドは常にプロンプトを出す
- 作業ディレクトリまたは追加ディレクトリ内への
cdも read-only。cd packages/api && lsのような複合コマンドも各部分が単独で条件を満たせばプロンプトなしで動くcdとgitの組み合わせ:cdが別ディレクトリへ移動する場合はプロンプトを出す(新しいディレクトリでgitを実行するとそのディレクトリの hook が動きうるため)。現在の作業ディレクトリに解決されるcdは no-op でプロンプトを出さないcdと出力リダイレクトの組み合わせ:cd後にリダイレクト先がどのディレクトリに解決されるか判定できない場合はプロンプトを出す。リダイレクト先が/dev/nullのみの場合は出さない
PowerShell ルール
- Bash ルールと同じ形。
*は任意位置、:*接尾辞は末尾*と等価、素のPowerShell/PowerShell(*)は全コマンドに一致 - 一般的なエイリアスは照合前に正規化される。
PowerShell(Get-ChildItem *)はgci、ls、dirにも一致する。照合は大小文字を区別しない - PowerShell の AST を解析し、複合コマンドの各コマンドを独立に確認する。
|、;、PowerShell 7+ では&&と||がサブコマンドに分割する
Read と Edit ルール
Editルールはファイルを編集するすべての組み込みツールに適用されるReadルールは Grep や Glob などファイルを読む組み込みツール、プロンプト内の@fileメンション、接続した IDE が共有する選択範囲・開いているファイルのコンテキストにも best-effort で適用されるReadの deny ルールは同じパスに対する Edit ツール(新規ファイル作成を含む)もブロックする。Write と NotebookEdit は対象外なので、どのツールも変更してはならないパスにはEditの deny ルールを追加する。v2.1.208 以降- ファイル権限は
Edit(path)とRead(path)ルールに対してのみ照合される。Write/NotebookEdit/Glob/ 旧MultiEditにパスルールを書いても参照されず、起動時に警告が出る(--allowedToolsで渡したGlobルールを除く)。v2.1.210 以降 - Read と Edit の deny ルールは Claude の組み込みファイルツールと、Claude Code が認識する Bash のファイルコマンド(
cat、head、tail、sedなど)に適用される。ファイルを自分で開く Python や Node のスクリプトのような任意のサブプロセスには適用されない。OS レベルで全プロセスをブロックするには sandbox を有効にする
パターンの種類(gitignore 構文):
| パターン | 意味 | 例 |
|---|---|---|
//path | ファイルシステムルートからの絶対パス | Read(//Users/alice/secrets/**) |
~/path | ホームディレクトリからのパス | Read(~/Documents/*.pdf) |
/path | settings のソースからの相対パス | Edit(/src/**/*.ts) |
path または ./path | 現在のディレクトリからの相対パス | Read(*.env) |
/Users/alice/fileは絶対パスではない。先頭の 1 つのスラッシュは settings のソースに anchor する
/path の解決先:
| ルールの定義場所 | /path の解決先 |
|---|---|
Project settings .claude/settings.json | <project root>/path |
Local settings .claude/settings.local.json | <original cwd>/path |
User settings ~/.claude/settings.json | ~/.claude/path |
--settings <file> で渡したファイル | <directory of file>/path |
CLI フラグ、/permissions、セッションルール | <original cwd>/path |
- Windows ではパスは照合前に POSIX 形式に正規化される。
C:\Users\aliceは/c/Users/aliceになるため、そのドライブ上の.envを対象にするには//c/**/.env、全ドライブなら//**/.env - 素のファイル名は gitignore のセマンティクスに従い任意の深さに一致する。
Read(.env)とRead(**/.env)は等価 - 単一ディレクトリセグメントの相対パターンは、ルール種別で一致する深さが変わる
- allow ルール:
Edit(src/**)は<cwd>/srcとその配下のみに一致する。任意の深さを許可するにはEdit(**/src/**) - deny / ask ルール:
Read(secrets/**)は現在のディレクトリ配下の任意の深さのsecretsディレクトリに一致する
- allow ルール:
- それ以外のパターン形状はどのルール種別でも同じ深さに一致する
- 「Yes, don't ask again」でファイルパスを承認すると、そのパス内の gitignore パターン文字(
[、]、*)がエスケープされ、承認したリテラルパスにのみ一致するルールが生成される。自分で書いたルールはエスケープされない。v2.1.202 より前は未エスケープで保存されていた
symlink の扱い:
- allow ルール: symlink のパスとその解決先の両方が一致するときのみ適用される。許可されたディレクトリ内の、外を指す symlink はプロンプトを出す
- deny ルール: symlink のパスまたは解決先のいずれかが一致すれば適用される
WebFetch ルール
domain:接頭辞を使い、リクエスト URL のホスト名に照合する。大小文字を区別せず、*ワイルドカードに対応し、ルールとホスト名の末尾の.を取り除くWebFetch(domain:example.com)はexample.comに一致するWebFetch(domain:*.example.com)は任意の深さのサブドメイン(api.example.com、a.b.example.com)に一致するがexample.com自体には一致しないWebFetch(domain:*)は全ドメインに一致し、素のWebFetchルールと等価- 先頭の
*.と素の*以外の位置では、ワイルドカードは 2 つのドットの間のテキストにのみ一致する。WebFetch(domain:example.*)はexample.orgに一致するがexample.evil.comには一致しない
MCP ルール
mcp__puppeteerはpuppeteerサーバーの任意のツールに一致するmcp__puppeteer__*も同サーバーの全ツールに一致するmcp__puppeteer__puppeteer_navigateは特定ツールに一致する- 組織が claude.ai connector のツールを
askに設定している場合、そのツールの allow ルールは効かず、autoとbypassPermissionsモードでも毎回プロンプトが出る。dontAskモードでは拒否される。connector ツールはmcp__claude_ai_<server>__<tool>として現れる
Agent(subagent)ルール
Agent(Explore)、Agent(Plan)、Agent(my-custom-agent)の形で、Claude が使える subagent を制御する- 無効化するには settings の
deny配列に追加するか--disallowedToolsを使う
Cd ルール
/cdコマンドがセッションを移動できるディレクトリを制御する。Cdはモデルが呼べるツールではなく、ユーザーが/cdを実行したときにのみ適用される- 素の
Cddeny ルールは/cdを完全に無効化する。Cd(<path-pattern>)deny ルールは一致する移動先をブロックする。deny ルールは symlink の各ホップを含め、移動先のあらゆる綴りを確認する Cdの allow ルールを 1 つでも追加すると/cdは allowlist モードになり、解決後の移動先が allow ルールのいずれかに一致しなければ拒否されるCdルールが無い場合、/cdは既定の挙動(未知のディレクトリの trust を尋ねる)を保つ- パスパターンは Read / Edit の
//、~/、/の anchor を共有するが、照合は gitignore 形式ではなくディレクトリパス全体に anchor される。*はちょうど 1 セグメント、**は複数セグメントに一致する。末尾の/**は名前付きルート自体にも一致する
| ルール | 一致する | 一致しない |
|---|---|---|
Cd(~/code/*) | ~/code/app | ~/code/app/src, ~/code |
Cd(~/code/**) | ~/code とその配下の任意のディレクトリ | ~/code の外 |
Cd(**/node_modules) | 任意の深さの node_modules | node_modules/pkg |
hook による拡張
PreToolUsehook は permission prompt の前に走る(EndConversationを除く全ツール)。hook 出力はツール呼び出しを拒否する、プロンプトを強制する、プロンプトを飛ばして進める、のいずれかができる- hook の判断は permission ルールを迂回しない。deny と ask ルールは hook の戻り値に関わらず評価される。組織が
askに設定した connector ツールとrequiresUserInteractionの MCP ツールも、hook が"allow"を返してもプロンプトを出す - 終了コード 2 で終わるブロッキング hook は permission ルールの評価前にツール呼び出しを止めるため、allow ルールがあってもブロックが優先される
作業ディレクトリ
- 既定では起動したディレクトリのファイルにアクセスできる
- 拡張方法: 起動時の
--add-dir <path>、セッション中の/add-dir、settings のadditionalDirectories - 追加ディレクトリのファイルは元の作業ディレクトリと同じ permission ルールに従う
- セッションの主作業ディレクトリ自体を変えるには
/cdを使う(v2.1.169 以降)
追加ディレクトリは設定のルートにはならない
--add-dir フラグまたは /add-dir で追加したディレクトリからのみ、次の例外が読み込まれる。settings の permissions.additionalDirectories に列挙したディレクトリはファイルアクセスのみを与え、以下の設定は読み込まない。
| 設定 | --add-dir から読み込まれるか |
|---|---|
.claude/skills/ の Skills | 読み込む(ライブリロードあり) |
.claude/agents/ の Subagents | 読み込む |
.claude/settings.json / .claude/settings.local.json | enabledPlugins と extraKnownMarketplaces キーのみ |
CLAUDE.md、.claude/rules/、CLAUDE.local.md | CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 のときのみ。CLAUDE.local.md はさらに local の setting source が必要(既定で有効) |
- コマンドと output style は、現在の作業ディレクトリとその親、
~/.claude/、managed settings から発見される - hooks とその他の
.claude/settings.jsonのキーは、現在の作業ディレクトリの.claude/から読み込まれ、親ディレクトリへのフォールバックは無い(加えて user の~/.claude/settings.jsonと managed settings) .claude/settings.local.jsonは git リポジトリルートから読み込まれる(サブディレクトリで起動しても同じ)。v2.1.211 より前は現在の作業ディレクトリのみだった。Agent SDK セッションは全バージョンで作業ディレクトリから読む
sandboxing との関係
- Permissions: どのツールを使えるか、どのファイル・ドメインにアクセスできるかを制御する。全ツールに適用される
- Sandboxing: OS レベルで Bash ツールのファイルシステム・ネットワークアクセスを制限する。Bash コマンドとその子プロセスにのみ適用される
- sandbox のファイルシステム制限は
sandbox.filesystem設定と Read / Edit の deny ルールを統合して最終的な境界にする - ネットワーク制限は WebFetch の permission ルールと sandbox の
allowedDomains/deniedDomainsを統合する - sandboxing を有効にし
autoAllowBashIfSandboxedを既定のtrueのままにすると、素のBashask ルール(およびBash(*))があってもサンドボックス化された Bash コマンドはプロンプトなしで動く - plan mode ではこの置き換えは行われない。v2.1.212 より前は plan mode でも置き換えが適用されていた
- なお次のチェックは引き続き適用される:
Bash(git push *)のような content-scoped な ask ルール、明示的な deny ルール、/・ホームディレクトリ・その他の重要システムパスを対象とするrm/rmdir(auto mode では classifier チェック。classifier への routing は v2.1.218 以降)
managed settings
管理者が配布する設定で、settings reference の precedence の例外を除き user / project settings で上書きできない。
managed settings からのみ読まれる設定:
| 設定 | 説明 |
|---|---|
allowAllClaudeAiMcps | true のとき、配布した managed-mcp.json の排他制御で抑止せず claude.ai connector も読み込む |
allowedChannelPlugins | メッセージを push できる channel plugin の allowlist。設定すると既定の Anthropic allowlist を置き換える。channelsEnabled: true が必要 |
allowManagedHooksOnly | true のとき、managed hooks、SDK hooks、managed settings の enabledPlugins で強制有効化した plugin の hooks のみを読み込む |
allowManagedMcpServersOnly | true のとき、managed settings の allowedMcpServers のみを尊重する。deniedMcpServers は全ソースからマージされる |
allowManagedPermissionRulesOnly | true のとき、user / project settings が allow / ask / deny ルールを定義できなくなる |
blockedMarketplaces | marketplace ソースの blocklist。ダウンロード前に確認されるためファイルシステムに触れない |
channelsEnabled | 組織で channels を許可する |
disableSideloadFlags | 起動時に --plugin-dir / --plugin-url / --agents / --mcp-config を拒否する。v2.1.193 以降 |
forceRemoteSettingsRefresh | true のとき、リモートの managed settings を取得し終えるまで CLI 起動をブロックし、取得失敗時は終了する |
pluginTrustMessage | インストール前の plugin trust 警告に追記するカスタムメッセージ |
sandbox.filesystem.allowManagedReadPathsOnly | true のとき、managed settings の filesystem.allowRead のみを尊重する。denyRead は全ソースからマージされる |
sandbox.network.allowManagedDomainsOnly | true のとき、managed settings の allowedDomains と WebFetch(domain:...) allow ルールのみを尊重する。許可されないドメインはプロンプトなしで自動ブロックされる |
strictKnownMarketplaces | ユーザーが追加・インストールできる plugin marketplace ソースを制御する |
strictPluginOnlyCustomization | skills / agents / hooks / MCP サーバーを user・project ソースから禁止し、plugin か managed settings 由来のみにする。true で 4 つすべて、["skills", "hooks"] のような配列で指定分のみ |
wslInheritsWindowsSettings | Windows の HKLM レジストリキーまたは C:\Program Files\ClaudeCode\managed-settings.json で true のとき、WSL が /etc/claude-code に加えて Windows のポリシーチェーンから managed settings を読む |
disableBypassPermissionsModeは通常 managed settings に置くが、どのスコープでも機能するbypassPermissionsやautoの使用を防ぐには、いずれかの settings ファイルでpermissions.disableBypassPermissionsMode/permissions.disableAutoModeを"disable"にする
precedence
- permission ルールは他の設定と同じ settings precedence に従い、managed settings が最上位。コマンドライン引数を含め他のレベルは managed の permission ルールを上書きできない
- どのレベルであれ deny されたツールは、他のレベルで allow できない
- user settings が allow、project settings が deny の場合は deny が勝つ。逆も同様(deny はどのスコープからでも allow より先に評価されるため)
project の allow ルールと workspace trust
- project の
.claude/settings.jsonのpermissions.allowとpermissions.additionalDirectoriesは capability を与えるため、そのワークスペースの workspace trust ダイアログを承認した後にのみ適用される。それまでルールは読まれるが適用されない - trust ダイアログは、そのフォルダが与える allow ルールと追加ディレクトリを一覧表示する
denyとaskルールは制限のみなので影響を受けない- trust はワークスペース単位で保存され、キーは git リポジトリルート(リポジトリ外では起動ディレクトリ)。ホームディレクトリで起動した場合は現在のセッション限りでディスクに書かれない。親ディレクトリを信頼してもネストしたプロジェクトの allow ルールは適用されない
.claude/settings.local.jsonは自分のファイルなので通常 trust チェックの対象外。ただしリポジトリが供給しえた場合(git にコミットされている、.claudeが symlink など)は project settings と同様に trust チェックを通る- 次の 2 つの場合は workspace trust なしでも
.claude/settings.local.jsonの allow ルールと追加ディレクトリが適用される- 起動したディレクトリが git リポジトリの中でない
- セッションが自分の設定ホーム(ホームディレクトリ、または
CLAUDE_CONFIG_DIRで.claudeサブディレクトリを設定したディレクトリ)で動いている
- v2.1.200 以降、親ディレクトリが既に信頼済みで trust ダイアログを一度も表示していないワークスペースでは、次に対話起動したときにダイアログが表示される。選択肢は Yes, I trust this folder(trust を保存し同一セッションでルールを適用)と No, continue without these permissions(ルールを無視して継続、次セッションで再表示)
-pの非対話モードではダイアログは出ず、ルールは無視されたままになる
設定
{
"permissions": {
"allow": [
"Bash(npm run *)",
"Bash(git commit *)",
"Bash(git * main)",
"Bash(* --version)",
"Bash(* --help *)"
],
"deny": [
"Bash(git push *)"
]
}
}
{
"permissions": {
"allow": [
"PowerShell(Get-ChildItem *)",
"PowerShell(git commit *)"
],
"deny": [
"PowerShell(Remove-Item *)"
]
}
}
{
"permissions": {
"deny": ["mcp__*", "Agent(Explore)"]
}
}
制約・注意点
- コマンド引数を制約しようとする Bash の permission パターンは壊れやすい。
Bash(curl http://github.com/ *)は、URL 前のオプション、別プロトコル、リダイレクト、変数展開、余分な空白などの変種に一致しない- より確実な URL フィルタリング: deny ルールで
curl/wgetなどをブロックし、許可ドメインにはWebFetch(domain:github.com)を使う /PreToolUsehook で URL を検証する /CLAUDE.mdに記述する(強制力は無いので他と併用する) - WebFetch を使うだけではネットワークアクセスを防げない。Bash が許可されていれば
curlなどで任意の URL に到達できる
- より確実な URL フィルタリング: deny ルールで
関連
facts/claude-code/permission-modes.mdfacts/claude-code/settings.mdfacts/claude-code/sandboxing.mdfacts/claude-code/hooks.mdfacts/claude-code/mcp.mdfacts/claude-code/sub-agents.mdfacts/claude-code/tools-reference.mdfacts/claude-code/security.mdfacts/claude-code/commands.mdfacts/claude-code/worktrees.md