Claude Media
Claude Codeで依存ライブラリのソースを読む — add-dirで足しdenyで書込を止める

Claude Codeで依存ライブラリのソースを読む — add-dirで足しdenyで書込を止める

依存ライブラリの実装を読ませて挙動を確かめるとき、--add-dirで実体ディレクトリを足し、Edit denyで書き込みだけ止める設定と、答えにファイル:行を付けさせる検証を示します。

ライブラリのドキュメントに書かれていない挙動は、ソースを読めば分かります。Claude Codeにその実装を読ませるなら、--add-dirで実体のディレクトリを足すのが近道です。ただし--add-dirが与えるのは読み取りだけではありません。

Claude Codeの--add-dirは「ファイルを読んで編集するための作業ディレクトリを足す」フラグです。足した先は編集も許可の対象になります。site-packagesやnode_modulesを足したまま作業を任せると、ライブラリ本体を書き換えられる状態になります。

この記事では、足す手順、permissions.denyのEditルールで書き込みだけを止める設定、答えに「ファイル:行」を付けさせて検証する流れを順に示します。

ライブラリを読むのに --add-dirが要る場面

プロジェクト直下のnode_modulesは、すでに作業ディレクトリの中にあります。追加の指定なしで読めるので、--add-dirは要りません。

足す必要があるのは、作業ディレクトリの外にあるソースです。

  • 仮想環境が別の場所にあり、site-packagesが作業ディレクトリの外にある
  • グローバルにインストールしたパッケージの実体を読みたい
  • ライブラリのリポジトリを隣のディレクトリにgit cloneしてある
  • モノレポの別パッケージを、別セッションで開かずに参照したい

足す書式は、フラグに複数のパスを並べるだけです。存在するディレクトリでなければ、追加は検証で止まります。

claude --add-dir ~/work/.venv/lib/python3.12/site-packages \
  ../some-library

セッション中に足すなら/add-dir、毎回足すなら設定ファイルのpermissions.additionalDirectoriesです。実体のパスを解決できない場合の対処は、add-dirで「couldn't be resolved」と出る原因にまとめています。UNCパスのようなネットワークパスが足せない制約は別の記事の領分です。

足した先は書き込みも許可の対象になる

追加ディレクトリのファイルには、元の作業ディレクトリと同じ権限規則が適用されます。読み取りはプロンプトなしで通り、編集は現在の権限モードに従います。

この「現在の権限モードに従う」が落とし穴です。

権限モード追加ディレクトリへの編集
default追加ディレクトリへの編集確認が出る
acceptEdits追加ディレクトリへの編集作業ディレクトリとadditionalDirectoriesのパスは自動で通る
bypassPermissions追加ディレクトリへの編集確認なしで通る

acceptEditsは、作業ディレクトリとadditionalDirectoriesのパスについて、ファイル編集とmkdir・touch・mv・cpのような基本的なファイル操作を自動承認します。ライブラリを読むだけのつもりで足したディレクトリが、承認なしで書き換えられる対象に入ります。

だから、足すときは書き込みを止めるルールをセットで置きます。

Editのdenyで書き込みだけを止める

止めるのはEditのdenyルールです。Editルールは、ファイルを編集する組み込みツール全般に効きます。読み取りはReadルールの担当なので、Editを止めても読み取りには影響しません。

パスの書き方は、アンカーで決まります。

書き出し意味
//path意味ファイルシステムのルートからの絶対パス
~/path意味ホームからのパス
/path意味設定ファイルの置き場所を基準にしたパス
path・./path意味カレントディレクトリからのパス

作業ディレクトリの外を指すので、//の絶対パスか~/を使います。設定にはこう書きます。

{
  "permissions": {
    "additionalDirectories": [
      "/Users/alice/work/.venv/lib/python3.12/site-packages"
    ],
    "deny": [
      "Edit(//Users/alice/work/.venv/lib/python3.12/site-packages/**)"
    ]
  }
}

additionalDirectoriesの方は通常の絶対パス、denyの方は//で始まる点が違います。/Users/...と一本スラッシュで書くと、設定ファイルの置き場所を基準にしたパスとして読まれます。

置く場所は、個人用の.claude/settings.local.jsonが向いています。プロジェクトの.claude/settings.jsonに書いたadditionalDirectoriesは、フォルダーを信頼するダイアログを承認するまで有効になりません。denyは制限を足すだけなので、この待ちの対象外です。

denyルールが警告で空振りしていないかは、matches no toolの警告の読み方で確かめられます。設定ファイル全体の構造はsettings.jsonの解説にあります。

denyが止めるものと止めないもの

Editのdenyは、Claude Codeが組み込みで扱う編集に効きます。Bashで書き込む場合も、sedやteeのようにClaude Codeが認識するファイルコマンドと、> fileのようなリダイレクト先には適用されます。

一方、ファイル名を明示しない操作は対象外です。たとえばPythonやNodeのスクリプトが自分でファイルを開いて書き込む場合は、denyルールをすり抜けます。

読み取り専用を確実にしたいなら、OSレベルで強制するサンドボックスを併用します。選び方はサンドボックスの早見表で比べられます。

シンボリックリンクについては、denyルールは要求されたパスと、その解決先のどちらかが一致すれば適用されます。仮想環境やpnpmのようにリンクで実体へ飛ぶ構成でも、実体側のパスで書いておけば守れます。

編集ツール自体を外す方法との違い

--disallowedTools "Edit"のように、ツール名だけを指定する方法もあります。この場合はEditツールそのものがClaudeのコンテキストから消えます。ライブラリを読むだけのセッションなら成立しますが、手元のコードも直せなくなります。

パス付きのEdit(...)ルールなら、ツールは残ったままライブラリ側だけを止められます。読み取りと自分のコードの修正を同じセッションで回すなら、こちらを使います。

読ませて、答えに「ファイル:行」を付けさせる

足して守ったら、読ませる番です。ここで大事なのは、推測で答えさせないことです。ライブラリの挙動を訊くと、モデルは訓練時に見た別バージョンの記憶で答えることがあります。ソースを読ませたことを、答えの形で確かめられるようにします。

プロンプトの例です。

requests のリトライの挙動を知りたい。
site-packages の実装を読んで答えて。
根拠は「ファイル:行」の形で全部付けて。
読んでいない推測は「推測」と明記して。

もう一つ、CLAUDE.mdに常設しておく方法もあります。

## ライブラリの挙動を答えるとき
- 追加ディレクトリのソースを先に読む
- 結論ごとに「パス:行番号」を付ける
- 該当箇所が見つからなければ、見つからなかったと答える

返ってきた答えは、そのまま信じずに数行だけ開いて突き合わせます。

sed -n '120,140p' \
  ~/work/.venv/lib/python3.12/site-packages/requests/adapters.py

引用された行が実在し、主張と一致していれば、その答えはソース由来だと言えます。行番号がずれていたり、そのファイルが存在しなかったりした場合は、記憶で答えた可能性があります。読み直させる合図になります。

「ファイル:行」を付けさせる運用には、副次的な効果もあります。バージョンの食い違いに気づきやすくなります。付いたパスの中にあるバージョン番号や、.dist-infoの名前から、今のプロジェクトが使っている版を読んだのか確かめられます。

質問の立て方で、読む範囲が決まる

追加したディレクトリは広大です。site-packagesには何十ものパッケージが入っているので、「このライブラリの挙動は?」と漠然と訊くと、関係のないファイルまで開きにいきます。入口を指定して絞ります。

  1. 対象のパッケージ名を明示する(例: requests、urllib3)
  2. 挙動を確かめたい関数かオプションの名前を挙げる
  3. 呼び出しの入口から、実際に分岐する箇所まで辿るよう頼む
  4. 辿ったファイルと行を、順番に並べさせる

たとえば「Retryのbackoff_factorが待ち時間にどう効くか、urllib3の実装を呼び出しの入口から順に辿って」と頼めば、答えは辿った経路の形で返ります。経路が長いほど、途中の1行を自分で開いて確かめやすくなります。

Node.jsの場合は、手元のnode_modulesをそのまま読ませれば足ります。グローバルにインストールしたツールの実体を読みたいときだけ、そのnode_modulesを足します。pnpmのようにリンクで実体へ飛ぶ構成では、リンクの先にあるストア側のパスでdenyを書いておきます。

同じ設定を複数のライブラリに使い回す

読みたいライブラリが増えると、additionalDirectoriesとdenyの組が増えます。ディレクトリを1つ決めて、そこに読みたいリポジトリをgit cloneでまとめる運用にすると、additionalDirectoriesとEdit(//.../**)が1組で済みます。denyの**は配下全部に及ぶので、クローンを足しても設定を書き足す必要がありません。

ライブラリのバージョンを揃えたいなら、読む前にgit checkoutでプロジェクトが使っているタグへ切り替えておきます。これも編集ではなく読み取りの準備なので、Claudeに頼まず自分で行うのが確実です。

書き込みが止まっているかを先に試す

設定したら、本番の質問の前に一度だけ試します。

  1. 足したディレクトリ内の適当なファイルに、コメント行を1行足すよう頼む
  2. 編集が拒否されることを確認する
  3. 同じファイルを読んで要約するよう頼み、読み取りは通ることを確認する

拒否されたのに、後からsed -iやスクリプトで回避しようとする動きが出たら、サンドボックスの出番です。読むだけのセッションはacceptEditsにせず、defaultかplanで回す手もあります。planは--permission-mode planで始められます。

追加ディレクトリ側の .claudeは何が読み込まれるか

ライブラリのリポジトリを丸ごと足すと、そこに.claude/があることがあります。--add-dirで足した場合は、.claude/skills/のスキル、.claude/commands/のコマンド、.claude/agents/のサブエージェントが読み込まれます。設定ファイルからはenabledPluginsとextraKnownMarketplacesだけが対象です。

CLAUDE.mdは、環境変数CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1を設定したときだけ読まれます。

permissions.additionalDirectoriesで足したディレクトリは、ファイルアクセスだけを与え、上の設定類は読み込みません。他人のリポジトリのソースを読むだけなら、設定ファイル経由の追加の方が余計なものを取り込みません。

読めない・止まらないときの切り分け

足したのに読めない場合は、まずパスの綴りと、そのディレクトリが実在するかを見ます。--add-dirは存在するディレクトリかどうかを検証するため、存在しない場所は足せません。

denyが効かない場合は、書き出しのスラッシュの数を疑います。//が絶対パス、/が設定ファイルの置き場所基準です。ここを取り違えると、ルールは別の場所を指します。読み取り専用のつもりが編集できてしまうのは、たいていこの取り違えか、additionalDirectoriesとdenyで別のパスを書いたときです。パスはコピーして揃えます。

使い分けの早見表

状況足し方守り方
一度だけ読む足し方claude --add-dir <path>守り方Edit(//...)のdeny
同じライブラリを繰り返し読む足し方permissions.additionalDirectories守り方同じ設定ファイルにdenyを併記
他人のリポジトリを丸ごと参照足し方設定ファイル経由守り方deny + サンドボックス
書き込みを絶対に許したくない足し方どちらでも守り方サンドボックスで強制

まとめ

--add-dirは読み取り専用の機能ではないので、ライブラリの実体を足すならEditのdenyを同じ設定に置きます。denyはClaude Codeが認識する編集に効く一方、スクリプト経由の書き込みは止められません。確実に止めたいときはサンドボックスが担当です。

答えの信頼性は、「ファイル:行」を付けさせ、数行だけ自分で開いて突き合わせることで担保できます。

参照した一次ソース

この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。

  1. code.claude.com/docs/en/cli-reference
  2. code.claude.com/docs/en/permissions
  3. code.claude.com/docs/en/settings
この記事を共有:XはてブLinkedIn