Claude Media
Claude CodeでJustfileを入口にする — just --listで発見させ権限を絞る

Claude CodeでJustfileを入口にする — just --listで発見させ権限を絞る

Justfileのレシピをタスクの入口にし、just --listでClaude Codeに見つけさせる手順。docコメントとグループの付け方、Bash(just *)の権限ルール、confirmと--yesの抜け道まで。

Justfileをタスクの入口にするなら、決めることは3つです。検証コマンドを justfile のレシピとして名前付きで並べること、CLAUDE.mdには「まず just --list を見る」とだけ書くこと、承認ルールを just <レシピ名> の単位で作ることです。

just はMakeに似たコマンドランナーで、レシピに引数を渡せ、just --list で一覧を出せます。この2点が、Claude Codeに「何が実行できるか」を発見させる用途に向いています。ただし権限ルールが見るのはClaudeが書いたコマンドの文字列だけで、レシピの中身は審査されません。以下はその前提で、justfile の書き方と権限の置き方を順に扱います。

Justfileを入口にすると何が変わるか

Claudeに検証を任せると、npm test npx jest npm run test -- --watch のように、同じ目的でもコマンドの書き方が揺れます。揺れを許そうとして Bash(npm *) のような広い許可を置きがちです。

justfile にまとめれば、検証は just check の1語になります。順序や並列は justfile 側が持つので、会話に頼らずに済みます。

効果

Justfileを入口にして変わること

  • コマンドが固定される

    Claudeが打つのは just test のような短い形だけです。

  • 一覧が自己記述になる

    レシピ直前のコメントが just --list の出力に載ります。CLAUDE.mdに説明を重ねて書く必要が減ります。

  • 許可の単位が揃う

    Bash(just test) のようにレシピ単位で書け、広い Bash(npm *) を避けられます。

同じ考え方でMakefileを使う手順はMakefileの検証ループに、Taskfile(go-task)を使う手順はTaskfileを入口にする記事にあります。

インストールと動作確認

just はHomebrewのほか、npmの rust-just や cargo install just で入れられます。パッケージマネージャごとの一覧もあります。

brew install just
just --version

justfile はプロジェクトのルートに置きます。just はサブディレクトリからも呼べます。Claudeがディレクトリを移動していても、同じレシピが動きます。

Claudeが読みやすいjustfileの形

Claudeが最初に打つのは just --list です。この出力を設計の中心に置きます。

docコメントとグループを付ける

レシピの直前にあるコメントが just --list に表示されます。[group('名前')] を付けると、一覧がグループごとに分かれます。_ で始まる名前か [private] を付けたレシピは、一覧と just --summary から外れます。

set quiet
 
# 検証用のレシピをまとめて実行する
[group('verify')]
check: lint typecheck test
 
# ESLintを実行する
[group('verify')]
lint:
  npm run lint
 
# 型検査を実行する
[group('verify')]
typecheck:
  npx tsc --noEmit
 
# テストを実行する。引数でパターンを絞れる
[group('verify')]
test *args:
  npm test {{args}}
 
# 本番へデプロイする(確認が入る)
[confirm("本番へデプロイします。よろしいですか?")]
[group('release')]
deploy:
  ./scripts/deploy.sh
 
[private]
_build-assets:
  npm run build:assets

上の justfile で just --list を打つと、次のような形で出ます(形式に沿った例です)。

Available recipes:
    [release]
    deploy # 本番へデプロイする(確認が入る)
 
    [verify]
    check     # 検証用のレシピをまとめて実行する
    lint      # ESLintを実行する
    test *args # テストを実行する。引数でパターンを絞れる
    typecheck # 型検査を実行する

出力の細かな桁そろえは、バージョンによって異なるかもしれません。重要なのは、レシピ名・引数・説明が1行で並ぶことです。Claudeは [verify] のグループを見て、検証系だけを選べます。

引数を取れるレシピにする

just ではレシピに引数を書けます。build target: のように宣言し、just build my-awesome-project と呼びます。上の test *args は可変個の引数を受けるレシピです。

絞り込みが要るテストは、just test src/foo.test.ts と書けます。ここが権限の設計に効きます(後述)。

引数なしの just で一覧を出す

just をレシピ名なしで呼ぶと、[default] 属性のレシピ、なければ最初のレシピが動きます。最初のレシピが deploy だと、うっかり動かす事故になります。

次のように一覧を既定にしておくと安全です。

set default-list := true

default-list は1.52.0で追加された設定です。古い just では動かないので、その場合は先頭に次のレシピを置きます。

default:
  @just --list

@just --choose を既定にする書き方もあります。対話選択は、Claudeのようなコマンド実行の用途には向きません。

出力を絞る

set quiet を置くと、レシピの各行をエコーしません。行頭の @ でも、その行のエコーを切り替えられます。[no-quiet] で個別に戻せます。

Claudeに返る出力が減るので、長いログで失敗箇所が埋もれにくくなります。ただし quiet はコマンド行の表示を消すだけです。テストランナー自身の出力は残ります。

CLAUDE.mdには入口だけを書く

Claude Codeでは、CLAUDE.mdは強制ではなく、読んで従う文脈として扱われます。タスク名を全部書かず、入口と運用ルールだけを書きます。

## コマンド
- 作業の最初に `just --list` を実行し、使えるレシピを確認する
- 変更後の検証は `just check` を実行する
- テストの絞り込みは `just test <パターン>` で渡す
- `just deploy` は実行しない

レシピを足しても、CLAUDE.mdは直さずに済みます。一覧の正本が justfile になるからです。CLAUDE.mdが長くなりすぎる場合の警告は、CLAUDE.md is too long警告の解説で扱っています。

権限ルールをレシピ単位で作る

Claude Codeの権限ルールは、Claudeが書いたコマンドの文字列に対して照合されます。評価順はdeny、ask、allowで、最初に一致したものが結果を決めます。複合コマンドは、&& や ; などの区切りで分割され、各部分が個別に照合されます。

よく見かける書き方は Bash(just:*) です。権限のドキュメントによると、:* は末尾の * と等価で、Bash(just:*) は Bash(just *) と同じ意味です。つまり just のあらゆる呼び出しを通します。これは入口を絞る目的には広すぎます。

レシピ単位で書くと、次のようになります。

{
  "permissions": {
    "allow": [
      "Bash(just --list)",
      "Bash(just --summary)",
      "Bash(just check)",
      "Bash(just lint)",
      "Bash(just typecheck)",
      "Bash(just test)",
      "Bash(just test *)"
    ],
    "ask": [
      "Edit(justfile)"
    ],
    "deny": [
      "Bash(just deploy *)"
    ]
  }
}

* を伴わないルールは、完全に一致する1つのコマンドだけを通します。Bash(just test) は引数なしの just test だけです。引数付きを通したいときは、Bash(just test *) を別に書きます。ドキュメントの例どおり、Bash(npm run build) は npm run build --watch を通しません。

プロジェクトの .claude/settings.json に置いた allow は、そのフォルダのワークスペース信頼ダイアログを承認した後でのみ適用されます。ルールの全体像は/permissionsコマンドの解説も参考になります。

文字列で見る限り残る抜け道

ルールが見るのは文字列なので、レシピの中身は審査されません。設計時に押さえたい点を挙げます。

落とし穴

allowしたレシピの中身は承認なしで動く

Bash(just check) を許可すると、check が呼ぶコマンドはすべて承認なしで動きます。justfile にデプロイ用の行を足せば、そのまま通ってしまいます。justfile 自体をClaudeが勝手に書き換えられる状態にしないことが前提です。上の設定で Edit(justfile) を ask に置いたのはこのためです。import や mod で読み込むファイルも、同じ扱いにします。

落とし穴

confirmは--yesで外れる

[confirm] は端末での確認を求める属性です。一方、just に --yes を渡すと、確認は自動的に承認されます。Bash(just *) のような広い許可を置くと、just --yes deploy も通る可能性があります。

deploy のようなレシピは、[confirm] だけに頼らず、deny で Bash(just deploy *) と Bash(just --yes *) を並べます。ただし、deny はあくまで文字列の一致です。後の「別名とモジュールのパス」の項目で述べる、別名やモジュール経由の呼び出しは止まりません。

落とし穴

引数を受けるレシピは広く開く

Bash(just test *) は、test に何を渡しても通します。レシピ内で {{args}} をそのままシェルに渡していれば、引数が事実上の入力経路になります。受ける引数が決まっているレシピは、Bash(just test) のように完全一致で許可します。パターンを渡す用途だけは * 付きにして、レシピ側でテストランナー以外を呼ばない形にします。

落とし穴

別名とモジュールのパスは別の文字列

alias b := build を書くと just b が使えます。mod foo で読み込んだモジュールのレシピは just foo::bar の形でも呼べます。Bash(just deploy *) の deny は、just d や just ops::deploy を止めません。

権限ドキュメントも、git push を止めるルールで git -C . push が通る例を挙げ、denyは「普通に書かれる形」を止めるもので、セキュリティの境界ではないと説明しています。止めたい操作のレシピには別名を付けず、強く止めるならサンドボックスか、PreToolUse フックで全文を調べる構成を併用します。

他の入口との使い分け

Makefileも、Taskfileも、役割は同じ「名前付きの検証入口」です。Justfileの特徴は、レシピが引数を宣言でき、just --list で説明と引数が一覧に並ぶ点です。

既に Makefile が育っているプロジェクトでは、置き換えずに残す選択もあります。just を足すなら、まず検証系の3レシピだけ移して試す順序が安全です。

手順

Justfileへの移行の流れ

  1. 1

    検証コマンドを3つ選ぶ

    lint、型検査、テストなど、Claudeに繰り返し打たせているコマンドを選びます。

  2. 2

    docコメントを付けたレシピにする

    本体には既存のコマンドをそのまま書きます。コメントは一覧に出る文なので、1行で目的が伝わる形にします。

  3. 3

    checkでまとめる

    依存に3つを並べ、just check の1語にします。

  4. 4

    権限とCLAUDE.mdを揃える

    Bash(just check) を許可し、CLAUDE.mdに「検証は just check」と書きます。

MCPアダプターという選択肢

READMEのModel Context Protocolの節には、justfile の内容をLLMが問い合わせ、レシピを実行できるようにするアダプター(just-mcp)が紹介されています。これは just 本体とは別のサードパーティ製です。

Claude Codeには、Bashで just --list を打たせる方法でも十分に目的を果たせます。MCPを足すと、サーバーの信頼や権限という別の論点が増えます。まずはBash経由で足りるかを見て、不足が出てから検討する順序が無理のない形です。

まとめ

Justfileの価値は、検証手順に名前が付き、一覧が just --list で自己記述され、名前の単位で承認ルールを書けることです。入口は just --list、検証は just check、既定は default-list で一覧にする、という3点で構成が決まります。

一方で、承認ルールはレシピの中身までは守りません。justfile の編集、引数を転送するレシピ、--yes と別名の3つは、設計時に手当てしておく箇所です。Bash(just:*) は Bash(just *) と同じで広すぎる点も、見落としやすい落とし穴です。デプロイのような重い操作は、deny と [confirm]、サンドボックスを重ねておくと、片方の漏れを補えます。

この記事を共有:XはてブLinkedIn