graft について
graftは、ソース位置付きのノートと呼び出し関係のグラフでコードベースを調べるコマンドラインスキルです。コーディングエージェントがコードの場所やファイルAPIを把握し、変更の影響を確認できます。
主な機能
- 01コードと概念の順位付き検索
- 02インデックス全体のテキスト検索
- 03ファイルAPIシグネチャの一覧
- 04呼び出しと参照の追跡
- 05コードベース構成の把握
- 06グラフの鮮度チェック
活用シーン
- 01機能の実装箇所の特定
- 02シンボルの全出現箇所の列挙
- 03関数変更前の呼び出し元確認
- 04不慣れなコードベースの把握
MCP 対応
graft MCP サーバーに接続すると、検索、ファイルAPI、呼び出し追跡、リポジトリマップ、鮮度チェックのツールを利用できます。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ trailhq/ trail-code --skill graftインストール後、Claude Code で/graftを入力して読み込まれたか確認します。
詳細
graft
graft/ には、このリポジトリのグラフが格納されています。各ノードは小さな Markdown ファイルで、1つの部分を文章で説明し、対象となる正確な file:line の範囲を示します。また、誰が何を呼び出すかを表す接続グラフもあります。ノードを検索するコストは数百トークンですが、ソースを読んで同じ理解を組み立てるには数千トークンかかり、呼び出し関係も見落とします。
以下のコマンドはすべて $0 で実行でき、API キーは不要で、1秒以内に結果が返ります。コマンドは6つあります。タスクに合ったものを1つ選んで実行し、結果に基づいて作業してください。さらに情報を得ようとツールを連続で実行しないでください。ほとんどのタスクは1回の呼び出しで済みます。
ツール
1 · graft ask "<question>" --source:場所の特定と理解(デフォルト)
グラフを対象に検索順位を付け、文章ノードと接続グラフを自動で切り替えて、正確な file:line とともに上位の結果を返します。
--sourceを指定すると、各ヒット箇所のコード、つまり各定義の8行以内の要点がインライン表示されるため、結果に必要なコードが含まれ、追加でファイルを読む必要はありません。要点だけでは作業に不十分な場合に限り、--fullを追加してください。--in <path>は順位付けの前にサブツリーを絞り込みます。-n Nは結果数の上限を指定します(デフォルトは8)。- 次の場合に使用します:概念や場所に関する質問。「認証はどのように機能するか」「レート制限はどこで処理されるか」「リクエストパイプラインを組み立てているのは何か」など。
- 通常は ask 1回で答えが得られます。複数の要素を含む質問では、異なる要素ごとに ask を1回実行してください。同じ質問を言い換えて繰り返さないでください。ヒットが少ない、または関連性が低い場合は、ツールを切り替えてください(grep / skeleton / callers)。再度 ask を実行しないでください。
2 · graft grep "<pattern>":漏れのない検索
インデックス化されたすべてのファイルを対象に、正規表現(リテラルの場合は --fixed)で検索します。ヒットは包含するシンボルごとにグループ化され、結合度で順位付けされます。読み取れなかったファイルも報告します。
- 次の場合に使用します:すべての出現箇所が必要な場合。すべての呼び出し箇所、定数のすべての使用箇所、すべてのプロバイダーなどです。
askは上位N件のみを返すため、インスタンスを見落とすことがありますが、grep なら見落としません。grep 1回で ask の連続実行を置き換えられます。 - 完全なシグネチャを推測して検索するのではなく、短いシンボル名またはリテラルを検索してください。過度に限定した正規表現(
func (s *Server) GenerateHandler)では、コードがインデックス化されていても何も返らないことがあります。grep で見つからない場合は、条件を緩めて(レシーバーとシグネチャを外し、名前だけを残して)graft grepを再実行してください。低速で順位付けもされない rawgrep -rnに切り替えてはいけません。 -iは大文字小文字を区別しません。--in <path>はサブツリーに対象を絞ります。rawgrep -rnを使うのは、graft がインデックス化していないファイル(ドキュメント、設定ファイル、新しく追加されたファイル)に限ります。
3 · graft skeleton <file>:ファイルの API をひと目で確認
1つのファイルに含まれる各関数/メソッド/型とその範囲を、シグネチャのみで表示します。約200トークンで済み、ファイルを読む場合より約10倍低コストです。
- 次の場合に使用します:ファイルを編集したり、そのファイルに処理を接続したりする前に、「このファイルには何があるか/ここで何を呼び出せるか」を把握する場合です。1回の skeleton でファイル全体の答えが得られます。同じファイルを再度 skeleton したり、
mapがすでに示したすべてのファイルを skeleton したりしないでください。
4 · graft callers <symbol>:正確な呼び出し関係
テキスト検索ではなく、事前に計算された呼び出し/参照関係です。シンボルには、単独名(Foo)、修飾名(Class.method)、パッケージ修飾名(pkg.Fn)を指定できます。
- デフォルトは
--direction inです。このシンボルを呼び出す/参照するものを調べます。名前の変更、削除、シグネチャの変更を行う前に実行してください。 --direction outは、このシンボル自体が呼び出す/依存するものを調べます(以前のcallees)。--depth Nは、変更による影響範囲全体を把握するため、N段階先まで再帰的にたどります(以前のimpact)。--depth 2は通常、「これに手を加えると何が壊れるか」を調べる際に使います。--depth allは、接続関係全体、つまりエッジをたどって到達できるすべてのソースを調べます。リファクタリング、名前変更、複数ファイルにわたる変更の前に実行してください。1ファイルだけの編集では見落とす、関連ファイルやその下流のファイル(プラットフォーム別の実装、切り出す必要があるモジュールなど)が見つかります。
5 · graft map:不慣れなリポジトリや領域の全体像を把握する
トークン予算を考慮した案内です。ディレクトリのまとまり、ディレクトリごとのハブ、全体の注目箇所を、配線グラフから直接示します。
- 次の場合に使います:リポジトリに初めて取り組むときや、「アーキテクチャ」を尋ねられたときです。
mapだけで十分です。名前が挙がったハブカードを読み、その後、リストされたすべてのサブシステムについてスケルトンを調べたり、順に質問したりする必要はありません。--max-dirs Nを指定すると対象を広げられます。
6 · ライフサイクル:graft build / graft check
上記の各ツールは回答の前にグラフ自体を更新するため、返される内容は常に現在のコードを反映しています。コミットしていない直近の編集も含まれます。編集後に build を実行する必要はありません。
ただし、graft/ 配下の Markdown を直接 grep する場合は注意が必要です。カードは各クエリのたびではなく、ターンの最後に再生成される投影なので、編集後は古い内容のままになっていることがあります。上記のツールは常に最新です。こちらを優先し、そのターンに編集したファイルについてはカード内の範囲を古いものとして扱ってください。
build は LLM レイヤー用です(--deep を指定すると概念マップが追加されます。依頼された場合を除き、省略してください)。check は graft/ が古い場合に失敗します。CI 用です。
シナリオ:コーディングタスクを最短で進める
| 状況 | 使うもの | 呼び出し回数 |
|---|---|---|
| オンボーディング/「このコードベースを説明して」 | graft map を実行し、名前が挙がったハブカードを読む | 1 |
| 処理の流れを理解する(「X はどう動くのか」) | graft ask "<flow>" --source | 1 |
| 変更箇所を特定する | graft ask "where is <behavior>" --source | 1 |
| すでに名前が分かっているシンボルを編集する | graft grep "<symbol>" を実行し、file:line の箇所を編集する(場所が分かっているので ask は不要です) | 1 |
| 名前変更/削除/シグネチャ変更 | まず graft callers <sym> --depth 2 を実行する | 1 |
| リファクタリング/複数ファイルの変更(編集前) | graft callers <sym> --depth all を実行し、つながっているファイルをすべて把握する。最初のファイルだけで終わらせない | 1 |
| 「これは何に依存しているか」 | graft callers <sym> --direction out | 1 |
| パターンの出現箇所をすべて見つける | graft grep "<literal>" | 1 |
| 「このファイルの API は何か」 | graft skeleton <file> | 1 |
| 領域 X の障害をデバッグする | graft ask "<symptom>" --source を実行し、続けて疑わしい箇所に対して callers を実行する | 1–2 |
| マージ前に差分のリスクを判断する | graft callers <changed sym> --depth 2 | 1 / シンボル |
| モノレポ内の単一リポジトリで作業する | ask / grep / callers に --in <scope>/ を追加する | 該当なし |
複数リポジトリのワークスペースでは、graft は特定の大きなリポジトリがほかを埋もれさせないよう公平に順位付けし、各ヒットにサブプロジェクト名を示す [scope/] ラベルを付けます。作業対象がすでに分かっている場合は、graft ask "<task>" --in <scope>/ で絞り込んでください。
呼び出し回数を最小限にする
- ノードの
covers:リストには、各シンボルの正確なfile:lineがすでに記載されています。そこから直接引用してください。範囲はソースから生成された信頼できる情報です。「念のため」の再確認としてファイルを開き直したり、再度grepしたりする必要はありません。 - タスクですでに変更対象のファイルやシンボルが指定されている場合は、すぐにそこへ進んでください。
graft grep "<symbol>"で正確なfile:lineを確認してから編集します。graft askはコードの場所がまだ分からない場合に使ってください。場所が分かっている対象に対するaskの往復は無駄です。 - 回答を信頼して作業に移ってください。最初のツールで本当に不十分だった場合に限り、2つ目のツールを使います。たとえば、ヒットが不確か、範囲が途中で切れている、または網羅的な確認が必要な場合です。
- graft が示したパスがディスク上に存在しない場合、インデックスがチェックアウトより先行しています(ブランチの切り替えや、まだ取り込まれていない移動など)。存在しないファイルを読もうとせず、
graft grepでシンボルの現在の場所を探すか、graft buildを実行して更新してください。
graft が保存したトークン数を毎ターン報告する
各検索ツールは、出力の冒頭に [graft] tokens saved ≈ N という行を表示します。これは、その呼び出しで対象となったファイル全体を読む場合と比べて、節約できたトークン数の推定値です。
そのターンで graft ツールを使った場合は毎回、実行したすべての graft 呼び出しの数値を合計し、返信の末尾に次のような1行を付けてください。
🌱 graft saved ~12,400 tokens this turn (3 calls). この行が表示されない呼び出し(ポインターとソースのトークン数が同程度になる小さなファイルなど)では何も節約されていないため、合計から除外してください。これはターンごとの数値です。ステータスラインにはセッション全体の累計が表示されます。
graft コマンドを head、tail、sed -n にパイプしないでください。 どのツールも出力上限が設定されており、省略した内容が明示されます。出力を切り詰めると、要求した情報を見逃すだけでなく、ステータスラインの累計を算出するために解析される節約量の行も、知らないうちに除外されてしまいます。
graft だけでは不十分な場合
- スパンが切り詰められている(「+N more lines」)場合:その正確な範囲を指定してファイルを開いてください。
- ノードに詳細が不足している場合:より具体的な質問をしてください。それでも不足する場合に限り、ソースを正確な
file:lineで読み込みます。graft で得られる理解を再構築するためだけに、ファイル全体を読むことは避けてください。 graft/内で直接 grep / ls / cat を使うこともできます(プレーンな Markdown です。ノードの索引はgraft/INDEX.mdにあります)。ただし、上記のツールのほうが高速で、重要な箇所を網羅できるため、まずはそちらを使ってください。
graft MCP サーバーに接続されている場合、次のツールも利用できます。
graft_find_code、graft_find_all、graft_file_api、graft_trace_calls(direction / depth を指定)、graft_repo_map、graft_check_freshness。利用可能なインターフェースを使ってください。ガイダンスはどちらも同じです。