mcpField
A
ast-index

ast-index

github.com/defendend開発58139 回インストール4 週間前に更新
リポジトリ

ast-index について

ast-index は、多言語・複数プラットフォームのプロジェクトを対象とする Rust 製コード検索 CLI で、コード構造やシンボル参照を調べる開発者向けです。SQLite と FTS5 を使い、関連度、シンボル関係、Git 履歴による順位付けを行います。

主な機能

  1. 01多言語プロジェクトのインデックス作成
  2. 02意図やシンボルによるコード検索
  3. 03定義、呼び出し元、継承関係の確認
  4. 04Git 履歴と依存関係による順位付け
  5. 05シンボルの使用箇所とファイルの特定

活用シーン

  1. 01コードベースで機能の実装方法を把握
  2. 02リファクタリング前にシンボルの使用箇所を追跡
  3. 03同名の実装候補を絞り込み
  4. 04プロジェクト内のクラス、関数、テストを検索

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/defendend/claude-ast-index-search --skill ast-index

インストール後、Claude Code で/ast-indexを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
android-commands.md
cpp-commands.md
csharp-commands.md
dart-commands.md
go-commands.md
ios-commands.md
matlab-commands.md
module-commands.md
perl-commands.md
proto-commands.md
python-commands.md
ruby-commands.md
rust-commands.md
typescript-commands.md
wsdl-commands.md

詳細

ast-index - マルチプラットフォームプロジェクト向けコード検索

SQLite + FTS5 インデックスを使用して、Android/Kotlin/Java、iOS/Swift/ObjC、Dart/Flutter、TypeScript/JavaScript、Rust、Ruby、C#、Scala、PHP、Perl、Python、Go、C++、Proto プロジェクトのコードを構造的に検索できる、高速なネイティブ Rust CLI です。

重要なルール

コード検索タスクでは、必ず最初に ast-index を使用してください。 次のルールは必須です。

  1. ast-index を主要な検索ツールとして使う — grep、ripgrep、または Search ツールより先に使用してください
  2. 分かっている内容に応じてコマンドを選ぶ:
    • 意図や説明(「認証はどのように処理されるか」「管理者更新の処理」など)が分かっている場合 → ast-index explore "<query>"。関連度順に表示し、ソースを出力します。
    • 正確な識別子(UserService、parseConfig など)が分かっている場合 → ast-index search / symbol / class。定義本体が必要な場合は symbol に --with-content を追加します。正確な修飾名や種類が不明な場合は search に追加します。
    • 複数語のクエリで一致する文字列がない場合、search 自体が explore による関連度順の検索にフォールバックするため、コマンドの選択を誤っても致命的ではありません。ただし、質問には explore を最初に使うのが適切です。
  3. 結果を重複して調べない — ast-index で使用箇所や実装が見つかった場合、それが完全な回答です
  4. ast-index が結果を返した後、「完全性を確保するため」に grep を実行しないでください
  5. --with-content が返した本体を再度読み込まない — 結果が正常に返された場合、通常の sed / awk / grep / rg やファイル読み込みの手順は不要です。本体が途中で切れている場合や利用できない場合、または返された定義の範囲外にあるテキストが必要な場合に限り、これらのツールを使用してください。
  6. grep/Search を使用できるのは次の場合のみです:
    • ast-index の結果が空の場合
    • 正規表現パターンを検索する場合(ast-index はリテラル一致を使用します)
    • コード内の文字列リテラル("some text")を検索する場合 — usages と refs は文字列やコメント内の名前を検索対象にしません
    • コメントの内容を検索する場合

理由: ast-index は grep より 17~69 倍高速(1~10ms 対 200ms~3s)で、構造化された正確な結果を返します。

前提条件

使用する前に CLI をインストールしてください。

brew tap defendend/ast-index
brew install ast-index

プロジェクトのルートでインデックスを初期化します。

cd /path/to/project
ast-index rebuild

インデックスは ~/Library/Caches/ast-index/<project-hash>/index.db(macOS)または ~/.cache/ast-index/<project-hash>/index.db(Linux)に保存されます。再構築すると新しいインデックスが作成され、既存のインデックスと入れ替わります。名前付きサブツリーと収集済みの Git 履歴(hotspots --collect)は引き継がれます。

対応プロジェクト

プラットフォーム言語モジュールシステム
Android/JavaKotlin、JavaGradle (build.gradle.kts)、Maven (pom.xml)
iOSSwift、Objective-CSPM (Package.swift)
WebTypeScript、JavaScript、React、Vue、Sveltepackage.json
RustRustCargo.toml
RubyRuby、Rails、RSpecGemfile
.NETC#、ASP.NET、Unity*.csproj
Dart/FlutterDartpubspec.yaml
ScalaScalaBazel (WORKSPACE、BUILD)
PHPPHPcomposer.json
PerlPerlMakefile.PL、Build.PL
PythonPythonなし (*.py files)
GoGoなし (*.go files)
ProtoProtocol Buffers (proto2/proto3)なし (*.proto files)
WSDLWSDL、XSDなし (.wsdl、.xsd files)
C/C++C、C++ (JNI、uservices)なし (.cpp、.h、*.hpp files)
GodotGDScriptproject.godot
混在上記すべてすべて

プロジェクトの種類はマーカーファイル(build.gradle.kts、Package.swift、Makefile.PL など)から自動検出されます。Python、Go、Proto、WSDL、C++ のファイルは、メインのプロジェクトの種類と併せてインデックス化されます。

ミニファイされた JavaScript/CSS はインデックス化も検索もされません。対象は、ファイル名が *.min.* または *-min.* の .js / .mjs / .cjs / .css ファイル、または先頭 64 KiB がミニファイ出力(コードの行の平均が 1000 バイト以上で、1 本の長い文字列ではないもの)であるファイルです。grep ベースのコマンドも対象をスキップします。また、そのようなファイルに対する outline / imports は解析せず、Skipped: minified file と表示します。AST_INDEX_SKIP_MINIFIED=0 にすると、このフィルターは無効になります。

主なコマンド

探索(ワンショットのコンテキスト)

explore - クエリに最も関連するシンボルを順位付けし、最適なファイルを表示します — 型またはモジュールのアウトライン(行範囲付き。内部の定義を示し、 選択されたものには → を付けます)、関数のソース(ディスクから最新の内容を読み込みます)、 グラフの近傍(呼び出し元/サブクラス)、パス規則によるテストの検索を 1 回の呼び出しで行います。領域を理解したい場合は、検索してから読み込むループより こちらを優先してください。次に、アウトラインの行が示す部分を読み込みます。 言語に依存せず、ベンダーにも対応しています(node_modules の .d.ts やスタックをまたぐ 一致は順位を下げますが、削除はしません)。

ast-index explore applicant merge MergeService   # bag of symbol/file names
ast-index explore "how does auth session work"   # natural-language question
ast-index explore PaymentService --rwr           # --rwr: re-rank via call/inheritance graph
ast-index explore Repository --max-files 8        # cap source files shown (default 6)
ast-index explore Session request --rwr --format json
  • デフォルト(Stage A)では、語彙の一致度と複数語による裏付けに基づいて順位付けします。 質問の単語は連結した状態でも照合され(pdf to html service で PdfToHtmlService が見つかります)、ファイルパスも対象になるため、 CamelCase のクラスを構成する単語からそのクラスを見つけられます。ファイル名の由来となった型は ヘルパーより上位になり、文(has_many :x、scope、include)や名前空間のみのモジュールは 定義より下位になります。質問の単語(how、does、work)は無視されます。
  • --rwr(Stage B)では、メモリ上に呼び出し/継承グラフを構築し、パーソナライズド PageRank によって順位を付け直して、 「Graph neighbours」セクションに呼び出し元/サブクラスを表示します。 やや遅くなりますが、何が何を呼び出すかを知りたい場合に最適です。
ユニバーサル検索

search - ファイル、シンボル、モジュールを横断して同時にユニバーサル検索を実行します。

ast-index search "Payment"           # Finds files, classes, functions matching "Payment"
ast-index search "Payment" --with-content  # Include matched symbol bodies
ast-index search "ViewModel"         # Returns files, symbols, modules in ranked order
ast-index search "Store" --fuzzy     # Fuzzy: exact → prefix → contains matching
ast-index search "Handler" --module "core/"  # Search within a module
ast-index search "Handler" --with-content  # Include matched symbol bodies
ast-index search "UserService"       # Find Java/Spring services
ast-index search "@RestController"   # Find Spring REST controllers (annotation search)
ast-index search "@GetMapping"       # Find GET endpoint mappings

シンボルには順位層があります。まず完全一致、次に名前の最後の :: または . のセグメントが クエリに一致するもの(Invoice で Billing::Invoice、email でスキーマ列の users.email が見つかります)、その後に部分一致です。各 順位層ではインポートより定義が先になり、node_modules よりプロジェクトコードが先になります。 部分一致の中では、テストシンボル(テストファイル、test_*、TestX)が最後になります。

search --rank <preset> - ファイルの Git 履歴とシンボルの依存関係グラフ上の位置に基づいて、 Files セクションと Symbols セクションの順位を付け直し、各結果の横にその順位の理由を示す 詳細情報を表示します。質問が「X はどこにあるか」ではなく「これらの X のうちどれか」である場合に使います。

ast-index search Service --fuzzy --module app/services/ --rank proven  # a settled example to copy
ast-index search Merge --rank risky                   # dangerous to touch: many dependents + unstable history
ast-index search Import --rank hotspots               # keeps being changed and fixed
ast-index search Import --rank hotspots --exclude-tests  # same, spec/test files left out
ast-index search Event --module app/models/ --rank central  # what the rest leans on (PageRank)
ast-index --format json search Merge --rank risky     # rank.applied / rank.missing + per-result dossier
プリセットスコア必要なもの
provenmean(1 − hotspot score, maturity, used 1/0) × substance (スタブの場合は 0.5) × lineage (基底クラスがもう拡張されていない場合は 0.5)hotspots --collect + graph build
hotspotsファイルのホットスポットスコア(コミット数、変更頻度、バグ修正率 pct)hotspots --collect
risky依存元の pct × ホットスポットスコア両方
centralPageRank pctgraph build
  • 関連性は引き続き優先されます。対象は通常の順序で上位 100 件のプロジェクトシンボルに限られ、完全一致は部分一致より上位になります。同じ順位層内では、 キーとして 0.9 × score + 0.1 × 1/(1 + position/20) を使います。ファイルパスの一致では、 一致箇所(stem、名前、ディレクトリ)を関連性の要素として使います。
  • 履歴はファイルごとです。ファイル内のすべてのシンボルが同じ履歴を共有します(出力では「file history」)。 グラフの数値はシンボルごとに算出され、ファイルの結果には最も強いシンボルの数値が適用されます。
  • データがない場合、ゼロとして順位付けされることはありません。プリセットは適用されず、結果は通常の順序のままとなり、 実行すべきコマンドが出力に示されます(JSON の rank.missing[].command)。古いグラフを使って順位付けする場合は警告が表示されます。
  • サードパーティコード(node_modules、.d.ts)はスコアの対象にならず、すべてのプロジェクト結果の後に表示されます。
  • 数式は、4 万ファイルのモノレポで翌年のバグ修正をバックテストして選定しました。proven は「どちらをコピーするか」という 人手で判断したクエリでも検証しています。数値は USER_GUIDE.md の「Ranking search results」に記載されています。 数値上安全でも、良い例とは限りません。proven では、現役の 2 つのスタイルのどちらをチームが好むかは判断できません。
ファイル検索

file - 名前パターンでファイルを検索します。

ast-index file "Fragment.kt"         # Find files ending with Fragment.kt
ast-index file "ViewController"      # Find iOS view controllers
シンボル検索

symbol - 名前でシンボル(クラス、インターフェース、関数、プロパティ)を検索します。

ast-index symbol "PaymentInteractor" # Find exact symbol
ast-index symbol "PaymentInteractor" --with-content  # Include its source body
ast-index symbol "Presenter"         # Find all presenters
ast-index symbol "Store" --fuzzy     # Fuzzy: exact → prefix → contains matching
ast-index symbol "Mapper" --in-file "payments/" --limit 10  # Scoped search
ast-index symbol "Mapper" --with-content  # Include bounded source bodies
ast-index symbol "@Service"          # Find all @Service annotations

名前空間付きクラスは、短い名前または完全な名前で見つかります。LedgerImporter と Billing::LedgerImporter はどちらも class Billing::LedgerImporter を見つけます(class、refs、hierarchy、implementations でも同様です)。名前空間のない短い名前が完全一致する場合は、名前空間付きの名前より優先されます。usages Billing::LedgerImporter は完全な名前が記述された行にある LedgerImporter への参照を一覧表示し、usages LedgerImporter はすべての参照を一覧表示します。

クラス検索

class - クラス、インターフェース、またはプロトコルの定義を検索します。

ast-index class "BaseFragment"       # Find Android base fragment
ast-index class "UIViewController"   # Find iOS view controller subclass
ast-index class "Store" --fuzzy      # Find all classes containing "Store"
ast-index class "Repository" --module "features/payments"  # Filter by module
ast-index class "UserController"     # Find Java/Spring controller class
使用箇所検索

usages - シンボルが使用されている箇所をすべて検索します。リファクタリングに不可欠です。

ast-index usages "PaymentRepository" # Find all usages of repository
ast-index usages "onClick"           # Find all click handler usages
ast-index usages "fetchData" --in-file "src/api/"  # Scoped to file path
ast-index usages "Repository" --module "features/auth" --limit 100
ast-index usages "parse_config"      # snake_case calls: Python, Rust, Go, C, PHP, ...

使用箇所(ここおよび refs)は、本番ファイルを先に、テストファイルを後に一覧表示します。各グループ内ではパスと行番号順です。JSON では、テストの参照に "test": true が付きます。

インデックス化される使用箇所は、大文字で始まる名前と name( の形式で記述された呼び出しです。snake_case 名と _private 名も含まれます。予約語(sizeof (x)、#if defined(X)、Go の func (r *T)、Python の None)は記録されません。

パフォーマンス:インデックス化されたシンボルで約 8ms です。

相互参照

refs - シンボルの定義、インポート、使用箇所の相互参照を一度に表示します。

ast-index refs "PaymentRepository"   # Definitions + imports + usages
ast-index refs "BaseFragment" --limit 10  # Limit results per section
実装検索

implementations - 指定したクラス/インターフェース/プロトコルを拡張または実装するクラスをすべて検索します。引数にはメソッド名や関数名ではなく、親の型を指定します。関連度順(完全一致 → サフィックス一致 → 部分一致)での部分的な名前一致に対応しています。

ast-index implementations "BasePresenter"  # Find all presenter implementations
ast-index implementations "Repository"     # Find repository implementations (exact match)
ast-index implementations "Service"        # Partial: finds UserService, PaymentService impls too
ast-index implementations "ViewModel" --module "features/"  # Scoped to module
ast-index implementations "Repository" --with-content  # Include bounded source bodies
クラス階層

hierarchy - クラス階層の完全なツリーを表示します。

ast-index hierarchy "BaseFragment"   # Show fragment inheritance tree
呼び出し元検索

callers - クエリ時に名前で照合し(name(、.name、…)、関数を呼び出す行を検索します。呼び出し箇所を出力します。各呼び出し箇所を含む関数は出力しません。その場合は call-tree を使用してください。

ast-index callers "onClick"          # Find all onClick calls
ast-index callers "fetchUser"        # Find API call sites

メソッド名を示す Ruby シンボルは、呼び出し箇所として扱われます(before_save :name、validate :name、delegate :name、map(&:name))。一方、:name?、:name!、:name= は別のメソッドを示すため該当せず、::name のパス(use super::name;、Billing::Name)も呼び出しがない限り該当しません(Mod::name(、Billing::Name.new)。

呼び出しツリー

call-tree - 呼び出し階層を上方向に表示します。各呼び出しを含む関数から、その呼び出し元へとたどります。インデックス化されたすべての言語で機能します。呼び出し元は、tree-sitter 対応言語(Ruby、TypeScript/JavaScript、Python、Go、Rust、Java、Kotlin、Swift、C#、C/C++、PHP、…)では、呼び出し箇所を含む範囲を持つ最も内側の定義です。範囲を持たない正規表現ベースのパーサー(Perl、WSDL/XSD)では、呼び出し箇所より上にある最も近い定義が使われます。

ast-index call-tree "processPayment" --depth 3 --limit 10
ast-index call-tree "getUsers"       # Java: finds callers of getUsers() method

同じ名前の定義が別のファイルにある場合も含め、各呼び出し元はファイルとともに出力されます(it "works" ブロックが 2 つあれば、呼び出し元も 2 つです)。呼び出し元は名前で検索されるため、各名前は一度だけ展開されます。後から現れる同名の呼び出し元には (expanded above) が付され、(recursive) は自身のパス上ですでに出現した定義にのみ付きます。これは実際の循環を示します。インポートやアノテーション(use、include Mod、Rails のコールバック)が呼び出し元になることはありません。それらを囲む定義が呼び出し元になります。また、関数を宣言する行は、その関数の呼び出しとして扱われません。

シンボル依存グラフ

graph - インデックスから構築された、シンボル間の有向グラフです。エッジは「参照を含む定義」→「その参照が示す定義」を意味します。callers/call-tree(クエリ時のテキスト検索)とは異なり、事前計算されたエッジをもとに回答し、各ターゲットの確度も示します。

ast-index graph build                                 # Build/refresh the graph (explicit, ~seconds)
ast-index graph status                                # Built? Stale? Edge counts per confidence
ast-index graph dependents ApplicationService         # Who depends on it (incoming edges)
ast-index graph dependents "Billing::Invoice#total"   # A member of one class
ast-index graph dependents MergeService --exclude-tests  # Production dependents only (also on impact)
ast-index graph dependencies CheckoutController --members  # What a class and its methods use
ast-index graph impact PaymentGateway --depth 3       # Blast radius: dependents per depth, files
ast-index graph path OrdersController Invoice         # Shortest dependency path(s) between two symbols
ast-index graph cycles --path app/models              # Strongly connected components
ast-index graph top --kind class --exclude-tests      # Most central symbols (PageRank)
ast-index graph metrics Invoice Payment               # fan-in/out, dependents, PageRank per symbol

各エッジには、ターゲットが解決されたレベルが付与されます。local(同じファイル)、scoped(明示的な名前空間 A::B::Name、字句的なネスト、定数レシーバー Type.method、または継承/ミックスイン)、import(ソースファイルがターゲットのモジュールをインポート)、unique(その言語でその名前を持つ定義が1つのみ)、ambiguous(候補が複数ある場合、または型が不明なレシーバーへの呼び出し。候補数は candidates で示されます)。ファンイン、ファンアウト、依存先、PageRank の集計対象は解決済みエッジのみです。曖昧なエッジは別途集計され、--include-ambiguous を指定すると一覧表示されます(impact では、解決済みのみの数値の横に上限値が表示されます)。

Rust のパスはコンパイラーの読み取り方に従って解決されます。ファイルはモジュール(src/db.rs は db)であり、crate::/super::/self:: はモジュールツリーをたどります。また、use 宣言(グループ化、別名、グロブ、pub use による再エクスポート)は名前を束縛します。そのため、db::open_db(...) は src/db.rs への scoped エッジとなり、use でインポートされた名前は import エッジとなります。別のワークスペースクレートには Cargo.toml のライブラリ名でアクセスします。std:: および依存関係のパスが、同名のプロジェクト内定義に解決されることはありません。

クラスシンボルが持つのは、クラスレベルの参照(スーパークラス、ミックスイン)のみです。クラス内の定義も対象にするには、dependents/dependencies/impact に --members を指定します。path は常にクラス自体とそのメンバーを対象とし、クラスからメンバーへ進むこともあります(contains と表示されます)。これは、Service.call → process のようなディスパッチを静的に判定できないためです。

単独の名前には複数の定義が一致する場合があります(call、またはモデル、TypeScript 型、spec スタブとしての Applicant など)。その場合、dependents/dependencies/impact は一致した定義のエッジを統合し、一致した定義数を示します。最大 --limit 件まで一覧表示し、Outer::Name、Class#member、--in-file、--kind の指定を提案します。

Rails アプリでは、db/schema.rb のテーブルがモデルに対応付けられます(self.table_name、単一テーブル継承、table_name_prefix/isolate_namespace、ネスト、複数形にしたクラス名)。また、モデル内で呼び出されるカラムリーダーや属性メソッド(status、self.status、status?、saved_change_to_status?)は、そのカラムへの scoped エッジとして解決されます。例:ast-index graph dependents applicants.first_name(または applicants#first_name)。別のレシーバーへの呼び出し(applicant.first_name)ではカラムを推測しないため、カラムの読み取りの大半はそのエッジに含まれません。その旨が回答に表示されます。すべての読み取りを一覧表示するには、ast-index usages first_name を実行します。graph build は、モデルのないテーブルとテーブルのないモデルを報告します。

グラフは rebuild/update では再構築されません。更新によってインデックスが変更された後にクエリを実行すると、古い状態であることを示す警告(JSON では "stale": true)が出力されます。再構築するには、graph build を再実行するか、クエリに --refresh を追加します。

ファイル解析

imports - 特定のファイル内のすべてのインポートを一覧表示します。

ast-index imports "path/to/File.kt"  # Show Kotlin file imports

outline - インデックスと同じ方法(ほとんどの言語では tree-sitter)で解析した、ファイル内で定義されているすべてのシンボルを表示します。

ast-index outline "PaymentFragment.kt"    # Show Kotlin fragment structure
ast-index outline "UserController.java"   # Show Java controller methods
ast-index outline "App.tsx"               # Show TypeScript/React components and functions
ast-index outline "handler.rs"            # Show Rust structs, impls, functions
ast-index outline --format json "app.rb"  # {schema_version: 1, file, symbols: [{name, kind, line, end_line}]}

行はソース内の順序で表示されます。複数行にわたる定義には範囲が表示され(:12-40 Invoice [class])、Read ではその範囲を正確に指定できます。1行の定義には :12 と表示されます。パーサーが範囲を報告しない場合、JSON の end_line は null になります。

スキーマダンプ(db/schema.rb)では、カラムはテーブルの行にまとめられ(:96-149 orders [table] 33 columns)、アウトラインが簡潔に保たれます。すべてのカラムを一覧表示するには --full を指定します。1つのテーブルのカラムを一覧表示するには、symbol --type column --pattern 'users.*' を実行します。

コード品質

todo - コード内の TODO/FIXME/HACK コメントを検索します。

ast-index todo                           # Find all TODO comments
ast-index todo --limit 10                # Limit results

deprecated - @Deprecated アノテーションを検索します。

ast-index deprecated                     # Find deprecated items

unused-symbols - 使用されていない可能性があるエクスポート済みシンボルを検索します。

ast-index unused-symbols --module path/to/module   # In specific module
ast-index unused-symbols --export-only             # Only exported (public) symbols
Git/Arc との統合

changed - 検出された Git/Arc リポジトリのブランチ単位のファイル概要をすばやく表示します。merge-base(base, HEAD) と HEAD を比較し、リポジトリ相対パスと、A(追加)、M(変更)、D(削除)、R(名前変更)のステータスを報告します。--base を指定しない場合、Git は origin/HEAD を解決し、続いて origin/main、origin/master、main、master、trunk の順に試します。Arc は trunk を使用します。名前変更の場合、JSON には old_path が含まれます。

ast-index changed                              # Auto-detect Git base; Arc uses trunk
ast-index changed --base main                  # Explicit base branch
ast-index --format json changed --base trunk   # Stable JSON schema v1
ast-index changed --timeout-ms 30000           # Bound VCS execution time
ast-index changed --verbose                    # Exact VCS argv and timing on stderr

テキスト出力の例:

Changed files against main (5):
  A  src/new.rs
  M  src/lib.rs
  D  src/obsolete.rs
  R  src/old.rs -> src/current.rs
  M  src/generated\nname.rs

テキストモードでは、制御文字とバックスラッシュがエスケープされるため、各結果が 1 行に収まります。スクリプトでは、テキスト概要を解析するのではなく、JSON を要求してください。

JSON 出力の例:

{
  "schema_version": 1,
  "vcs": "git",
  "base": "main",
  "head": "HEAD",
  "scope": null,
  "changes": [
    { "status": "M", "path": "src/lib.rs" },
    { "status": "R", "path": "src/current.rs", "old_path": "src/old.rs" }
  ]
}

リポジトリのルートでは scope は null です。入れ子になった作業ディレクトリでは、リポジトリ相対のディレクトリパスになります。

changed は VCS の状態を直接読み取るため、ast-index データベース/キャッシュに依存しません。対象範囲は現在の作業ディレクトリですが、出力パスはリポジトリルートからの相対パスのままです。レビュー前にブランチ内のファイルを一覧化するにはこれを使用し、パッチの差分を確認するには生の git diff/arc diff を使用してください。変更されたシンボルは報告せず、ステージ済み/未ステージの作業ツリーのみの編集も含みません。

hotspots - Git の履歴に基づいてファイルを順位付けします。対象となる指標は、コミット数、変更量(追加行数+削除行数、および 10 行以上のファイルでは現在のファイルサイズに対する変更量)、バグ修正の割合、異なる作成者の数、経過日数、最終変更からの経過時間です。 似たようなファイルが複数あるときにどのファイルのパターンを参考にするか決めたり、リファクタリングの範囲を定めたりする際に使用してください。28 回コミットされ、54%がバグ修正であるファイルは、1 回だけ書かれて 86 日間変更されていないファイルとは異なります。

しきい値は固定値ではなく、このリポジトリ内のパーセンタイルです。ライブラリでは 28 回のコミットは多くても、モノレポでは珍しくありません。数値は常にラベルの横に表示されます。

ast-index hotspots --collect                   # Read new Git history, then report
ast-index hotspots --limit 50 --sort fixes     # Report only; no Git subprocess
ast-index hotspots --path src/parsers          # Narrow output; percentiles stay global
ast-index hotspots --exclude-tests             # Hide spec/test files; percentiles stay global
ast-index hotspots --collect --full            # Discard the cursor, rescan everything
ast-index --format json hotspots --limit 10    # Paginated JSON schema v2

収集は暗黙には実行されません。rebuild と update は収集を実行しません。最初の --collect は全履歴をコミット単位のストアに読み込みます。以降の実行では、差分を使って現在の HEAD まで反映します。HEAD から到達できなくなったコミット(ブランチ切り替え、リベース、リセット、強制プッシュによるもの)は差し引き、新しいコミットを追加します。そのため、ブランチの切り替えにかかる時間は差分のあるコミット数に比例し、元のブランチに戻る際には何も再読み込みしません。数値は、その HEAD で全件を再収集した場合と一致します。行数は作業ツリーから取得されるため、未コミットの編集も、後続の --collect でファイルが再計算されたとき、または --full の実行時に一度カウントされます。ガベージコレクションでカーソルコミットが削除された場合、プロジェクトルートが変更された場合、または --full を指定した場合に限り、最初から再構築されます。rebuild は、収集済みの履歴を保持します(インデックスには依存しません)。ただし、古いバージョン、別の作業ツリー、または別のスコープから取得された場合は、次の --collect で再び読み込みます。

ラベル:churn:high/churn:elevated、rewritten-often(相対変更量。10 行以上のファイルのみ対象です。これより短い場合、1 行のバンドル、フィクスチャ、内容が削除されたビューなど、行数では内容を測れなくなるためです)、fixes:high/fixes:elevated(コミット数が 4 以上のファイルのみ対象)、authors:many、veteran。 --sort には score(デフォルト)、commits、churn、relative-churn、fixes、authors、recent を指定できます。score は四捨五入して表示されますが、並び順と JSON の score_exact には、パーセンタイルの丸め前の平均が使用されるため、大規模なリポジトリの上位で同順位ばかりになることはありません。fixes は履歴が少ない場合の影響を割り引いたバグ修正の割合で並べ替えます(95%ウィルソン信頼区間の下限を使用します。2 件中 2 件よりも 17 件中 11 件が上位になります)。コミット数が 4 未満のファイルは最後になります。バグ修正の検出には、コミットサブジェクトのヒューリスティックを使用します(英語とロシア語に対応し、先頭のトラッカーキーは最初に除去されます。[HOTFIX]/[FIX] などのタグは修正としてカウントされます)。マージコミットは除外され、名前変更の場合は履歴が新しいパスに引き継がれます。

パブリック API

api - モジュールのパブリック API を表示します。モジュールパスまたはモジュール名を受け付けます(ドットはスラッシュに変換されます)。

ast-index api "path/to/module"           # By path
ast-index api "module.name"              # By module name (dots → slashes)

プロジェクトの分析

プロジェクトマップ

map - プロジェクトの概要を簡潔に表示します。サイズ順の上位ディレクトリとシンボル種別ごとの件数を確認できます。特定の領域を詳しく調べるには、--module を使うと、クラスと継承の詳細が表示されます。

ast-index map                                # Summary: top 50 dirs with kind counts (~54 lines)
ast-index map --limit 20                     # Show only top 20 directories
ast-index map --module features/payments     # Detailed: classes with inheritance for a module
ast-index map --module src/core --per-dir 10 # More symbols per directory in detailed mode
ast-index map --format json                  # JSON output

サマリーモードの出力(デフォルト、--module なし):

Project: Android (Kotlin/Java) | 29144 files | 859 modules | top 50 of 728 dirs

  features/taxi_order/impl/          1626 files | 371 iface, 94 obj, 1834 cls
  features/masstransit/impl/          862 files | 165 obj, 1261 cls, 280 iface

詳細モードの出力(--module あり):

features/payments/impl/ (250 files)
  PaymentInteractor : class > BaseInteractor
  PaymentRepository : interface
  PaymentMapper : class
プロジェクトの規約

conventions - インデックス化されたコードベースから、アーキテクチャパターン、フレームワーク、命名規約を自動検出します。読み取り専用の SQL クエリを実行するため、ファイルのスキャンは不要です。

ast-index conventions                        # Text output (~30 lines)
ast-index conventions --format json          # JSON output

検出対象:

  • アーキテクチャ:Clean Architecture、Feature-sliced、BLoC、MVC、MVVM、MVP、Redux、Composition API、Hooks
  • フレームワーク:DI(Hilt、Dagger、Koin)、非同期処理(Coroutines、RxJava、Combine)、ネットワーク(Retrofit、OkHttp)、DB(Room、Realm、ActiveRecord、Sequel)、UI(Compose、SwiftUI、React、Flutter)、テスト(JUnit、Kotest、XCTest、pytest、Jest、RSpec)、Web(Rails、Django、Flask、FastAPI、Express)、ジョブ(Sidekiq、Celery) — import 名と require 名から検出し、名前全体のセグメントで照合します(sequel-combine は Combine ではありません)
  • 命名パターン:ViewModel、Repository、UseCase、Service、Controller、Fragment など(件数付き)

共通フラグ

多くの検索コマンド(search、symbol、class、usages、implementations、refs)で次のフラグを使用できます。

フラグ説明
--fuzzyあいまい検索:完全一致 → 前方一致 → 部分一致(search、symbol、class のみ)
--in-file <PATH>ファイルパスで結果を絞り込みます(部分一致。callers と call-tree でも使用可能)
--module <PATH>パスのプレフィックスで結果を絞り込みます
--limit <N>返す結果の最大数
--format json構造化処理向けの JSON 出力

--fuzzy の使いどころ: 正確な名前がわからない場合に使用します。ast-index class "Store" --fuzzy を実行すると、Store、StoreImpl、AppStore、DataStoreRepository などが見つかります。--fuzzy フラグは 3 段階で照合します。まず完全一致、次に前方一致、最後に部分一致を試します。

インデックス管理

ast-index rebuild                        # Full rebuild with dependencies
ast-index rebuild --no-deps              # Skip module dependency indexing
ast-index rebuild --no-ignore            # Include gitignored files (build/, etc.)
ast-index rebuild --sub-projects         # Index each sub-project separately (large monorepos)
ast-index rebuild -j 32                  # Use 32 threads (for network/FUSE filesystems)
ast-index rebuild -v                     # Verbose logging with timing per step
ast-index update                         # Incremental update (changed files only)
ast-index stats                          # Show index statistics
ast-index clear                          # Delete index for current project
ast-index restore /path/to/index.db      # Restore index from a .db file
ast-index watch                          # Watch for file changes and auto-update index
ディレクトリ単位の検索

サブディレクトリから検索を実行すると、結果は自動的にそのサブツリーに限定されます(キャッシュ内のインデックス DB を使ってプロジェクトのルートを検出します)。

cd /project/root
ast-index rebuild                        # Index entire project
ast-index search "Payment"              # Finds results across entire project

cd /project/root/services/payments
ast-index search "Payment"              # Only finds results within services/payments/
ast-index class "PaymentService"        # Only classes in services/payments/ subtree

これはすべての検索コマンド(search、symbol、class、implementations、usages)で機能します。

複数ルートのプロジェクト

兄弟関係にあるソースツリーを意図的にまたいで作業するワークスペースには、名前付きサブツリーを追加できます。これらはメインのプロジェクトと並行してインデックス化されます。メインのプロジェクトを先にインデックス化する必要があります。

ast-index subtree add shared ../shared-library   # Attach a named subtree
ast-index update                                 # Index its files
ast-index subtree list                           # List attached subtrees
ast-index subtree remove shared                  # Detach, then rebuild to drop its files
ast-index --subtree shared search "Payment"      # Query one subtree
ast-index --local search "Payment"               # Query the primary project only

add-root、remove-root、list-roots は、互換性エイリアスとして引き続き使用できます。ある git worktree を別の git worktree に追加しないでください。各 worktree にはそれぞれ独自のインデックスが作成されます。

ユーティリティコマンド

ast-index version                    # Show CLI version
ast-index help                       # Show help message
ast-index help <command>             # Show help for specific command
ast-index install-claude-plugin      # Install Claude Code plugin to ~/.claude/plugins/

プログラムからのアクセス(SQL と SDK)

複数のクエリの組み合わせ、フィルタリング、集計を必要とする複雑な分析には、複数のコマンドを連結するのではなく、SQL に直接アクセスしてください。

構造検索(ast-grep)

AST パターンを使った構造的なコード検索です。sg(ast-grep)のインストールが必要です。

# Simple pattern matching
ast-index agrep "router.launch($$$)" --lang kotlin
ast-index agrep "@Inject constructor($$$)" --lang kotlin
ast-index agrep "suspend fun $NAME($$$)" --lang kotlin

# Find classes extending a specific base
ast-index agrep "class $NAME : BasePresenter($$$)" --lang kotlin

# Find async functions (Swift)
ast-index agrep "func $NAME($$$) async" --lang swift

# Find React components
ast-index agrep "export default function $NAME($$$)" --lang typescript

# JSON output for programmatic use
ast-index agrep "@Composable fun $NAME($$$)" --lang kotlin --json

パターン構文(ast-grep):

  • $NAME — 単一の AST ノードに一致します(メタ変数としてキャプチャします)
  • $$$ — 0 個以上の AST ノードに一致します(可変長)
  • それ以外はすべて、AST に対するリテラルのパターン照合です

agrep と組み込みコマンドの使い分け:

  • composables、inject、suspend → 組み込みコマンドを使用します(より高速で、事前設定済みです)
  • カスタムの構造パターン、否定照合、コンテキストクエリ → agrep を使用します
生 SQL クエリ
# Execute any SELECT query against the index database (JSON output)
ast-index query "SELECT s.name, s.kind, f.path FROM symbols s JOIN files f ON s.file_id = f.id WHERE s.kind = 'class'"

# With limit
ast-index query "SELECT * FROM symbols WHERE name LIKE '%Service%'" --limit 50

# Complex joins — find classes that implement an interface but have no usages
ast-index query "SELECT s.name, f.path FROM symbols s JOIN files f ON s.file_id = f.id JOIN inheritance i ON s.id = i.child_id WHERE i.parent_name = 'Repository' AND s.name NOT IN (SELECT name FROM refs)"

# Find files with most symbols (complexity hotspots)
ast-index query "SELECT f.path, COUNT(*) as sym_count FROM symbols s JOIN files f ON s.file_id = f.id GROUP BY f.id ORDER BY sym_count DESC LIMIT 20"

# Find unused classes (defined but never referenced)
ast-index query "SELECT s.name, s.kind, f.path FROM symbols s JOIN files f ON s.file_id = f.id WHERE s.kind IN ('class', 'interface') AND s.name NOT IN (SELECT name FROM refs) AND s.name NOT IN (SELECT parent_name FROM inheritance)"

# Module dependency analysis — find modules with most dependencies
ast-index query "SELECT m.name, COUNT(*) as dep_count FROM module_deps md JOIN modules m ON md.module_id = m.id GROUP BY m.id ORDER BY dep_count DESC"

# CTE — transitive dependency chain
ast-index query "WITH RECURSIVE chain AS (SELECT md.dep_module_id, m.name, 1 as depth FROM module_deps md JOIN modules m ON md.dep_module_id = m.id WHERE md.module_id = (SELECT id FROM modules WHERE name LIKE '%payments%') UNION ALL SELECT md.dep_module_id, m.name, c.depth + 1 FROM chain c JOIN module_deps md ON md.module_id = c.dep_module_id JOIN modules m ON md.dep_module_id = m.id WHERE c.depth < 5) SELECT DISTINCT name, depth FROM chain ORDER BY depth, name"

セキュリティ: 許可されるクエリは SELECT、WITH、EXPLAIN のみです。変更操作(INSERT、UPDATE、DELETE、DROP)はブロックされます。

データベーススキーマ
# Show all tables with columns and row counts (JSON)
ast-index schema

主なテーブル:

テーブル説明主な列
filesインデックス済みのソースファイルpath、mtime、size
symbolsクラス、関数、プロパティなどname、kind、line、file_id、signature
symbols_ftsシンボルのFTS5全文検索name、signature
inheritance親子の型関係child_id、parent_name、kind
refsシンボルの参照/使用箇所name、line、file_id、context
modulesビルドモジュール(Gradle、Mavenなど)name、path、kind
module_depsモジュール間の依存関係module_id、dep_module_id
transitive_deps事前計算済みの推移的依存関係module_id、dependency_id、depth
xml_usagesAndroid XMLレイアウトでのクラス使用箇所class_name、file_path
resourcesAndroidリソース定義type、name、file_path
データベースへの直接アクセス(SDK/スクリプト)
# Get the SQLite database path for external tools
ast-index db-path
# Output: /Users/me/.cache/ast-index/abc123/index.db

SQLiteをサポートする任意の言語で、この方法を使用できます。

import sqlite3, json
db_path = subprocess.check_output(["ast-index", "db-path"]).decode().strip()
conn = sqlite3.connect(db_path)

# Example: find all classes implementing an interface with no references
unused_impls = conn.execute("""
    SELECT s.name, f.path, i.parent_name
    FROM symbols s
    JOIN files f ON s.file_id = f.id
    JOIN inheritance i ON s.id = i.child_id
    WHERE s.name NOT IN (SELECT name FROM refs)
    ORDER BY i.parent_name, s.name
""").fetchall()
for name, path, parent in unused_impls:
    print(f"  {name} implements {parent} — {path}")

queryと事前定義コマンドの使い分け:

  • 単純な検索 → search、class、usagesを使用します(高速で、整形済みの出力)
  • 複雑な結合、集計、否定条件 → queryを使用します(N回ではなく1回の呼び出し)
  • バッチ分析、スクリプト、CIパイプライン → db-pathとSQLiteへの直接アクセスを使用します

パフォーマンスの目安

1回の呼び出しの実時間(プロセスの起動時間を含む):小規模なプロジェクト、およびページキャッシュがウォーム状態の40kファイルのRails + Reactモノレポ(シンボル数300k)。

コマンド小規模40kファイル備考
class / symbol~10ms~20msインデックスを直接検索
usages / implementations~10ms~20-40msインデックスを使った参照検索
imports~10ms~20msファイルベースの検索
outline~10ms~50msファイルを解析
search~10ms~250-550msFTS5によるシンボル検索とファイル内容のスキャン
explore~15ms~100-150ms--rwrは~200ms
graph queries~10ms~100msgraph build(~1-2s)が必要
callers~20ms~200msクエリ時にテキストを照合
call-tree~20ms~500ms呼び出し元の呼び出し元
map / conventions~20ms~0.1-1sSQL集計
rebuild数秒数分プロジェクト全体のインデックス作成

プラットフォーム固有のコマンド

Android/Kotlin/Java/Spring

参照先:references/android-commands.md

Javaパーサーは、クラス、インターフェース、列挙型、メソッド、コンストラクター、フィールド、および重要なアノテーション(@RestController、@Service、@Repository、@Component、@Entity、@GetMapping、@PostMapping、@Autowired、@Override、@Transactional、@SpringBootApplication、@Test、@Inject、@Data、@Builderなど)をインデックス化します。

Mavenモジュール(pom.xml)は、Gradleモジュールと同様に完全にサポートされています。

  • DIコマンド:provides、inject(@Inject + @Autowired)、annotations
  • Composeコマンド:composables、previews
  • コルーチンコマンド:suspend、flows
  • XMLコマンド:xml-usages、resource-usages
  • コード品質:deprecated、suppress、todo
  • 拡張機能:extensions
  • ナビゲーション:deeplinks
iOS/Swift/ObjC

参照先:references/ios-commands.md

  • StoryboardとXIB:storyboard-usages
  • アセット:asset-usages
  • SwiftUI:swiftui
  • Swift並行処理:async-funcs、main-actor
  • Combine:publishers
TypeScript/JavaScript

参照先:references/typescript-commands.md

  • インデックス化対象:class、interface、type、function、const、デコレーター
  • 対応対象:React(フック、コンポーネント)、Vue SFC、Svelte、NestJS、Angular
  • outlineとimportsはTS/JSファイルで動作します
Rust

参照先:references/rust-commands.md

  • インデックス化対象:struct、enum、trait、impl、fn、macro_rules!、mod
  • 対応対象:derive、属性(#[test]、#[derive])
  • outlineとimportsはRustファイルで動作します
Ruby

参照:references/ruby-commands.md

  • インデックス対象:class、module、def、定数(A::B = ...)、Rails DSL
  • 対応:RSpec(describe、it、let)、Rails(関連付け、バリデーション)
  • db/schema.rb(gitignore 対象でもインデックス化):テーブルは table、カラムは column として、table.column という名前で登録されます — ast-index search first_name -t column
  • outline と imports は Ruby ファイルで動作します
C#/.NET

参照:references/csharp-commands.md

  • インデックス対象:class、interface、struct、record、enum、メソッド、プロパティ
  • 対応:ASP.NET 属性、Unity(MonoBehaviour、SerializeField)
  • outline と imports は C# ファイルで動作します
Dart/Flutter

参照:references/dart-commands.md

  • インデックス対象:class、mixin、extension、extension type、enum、typedef、関数、コンストラクター
  • 対応:Dart 3 の修飾子(sealed、final、base、interface、mixin class)
  • outline と imports は Dart ファイルで動作します
Python

参照:references/python-commands.md

  • インデックス対象:class、def、async def、デコレーター
  • outline と imports は Python ファイルで動作します
Go

参照:references/go-commands.md

  • インデックス対象:package、type struct、type interface、func
  • outline と imports は Go ファイルで動作します
Scala
  • インデックス対象:class、case class、object、trait、enum(Scala 3)、def、val、var、type、given
  • 対応:継承(extends/with)、コンパニオンオブジェクト
  • outline と imports は Scala ファイルで動作します
PHP
  • インデックス対象:namespace、class、interface、trait、enum、function、method、const、property、use
  • 対応:Laravel(モデル、トレイト、ファサード)、extends/implements、名前空間のインポート
  • outline と imports は PHP ファイルで動作します
Perl

参照:references/perl-commands.md

  • エクスポート:perl-exports
  • サブルーチン:perl-subs
  • POD:perl-pod
  • インポート:perl-imports
  • テスト:perl-tests
モジュール解析

参照:references/module-commands.md

  • モジュール検索:module
  • 依存関係:deps、dependents
  • 未使用の依存関係:unused-deps
  • 未使用のシンボル:unused-symbols
  • パブリック API:api

ワークフローの推奨事項

  1. プロジェクトのルートで ast-index rebuild を一度実行し、インデックスを作成します
  2. ast-index conventions と ast-index map を使ってセッションを開始し、プロジェクト構造を把握します(約80行、約500トークン)
  3. ast-index map --module <path> を使って、特定の領域を詳しく確認します
  4. 探索中の素早い汎用検索には ast-index search を使います
  5. 正確なクラス/インターフェースの検索には ast-index class を使います
  6. リファクタリング前にすべての参照を見つけるには ast-index usages を使います(1つの定義の依存先には graph dependents を使います)
  7. 継承を把握するには ast-index implementations を使います
  8. コードレビュー前にブランチ内のファイルを一覧にするには ast-index changed --base main を使います
  9. インデックスを最新の状態に保つため、定期的に ast-index update を実行します

JSON 出力(任意)

デフォルトの出力は人間が読みやすいプレーンテキストです — スクリプト用に構造化データが必要な場合を除き、そのまま使用してください。

次の場合にのみ --format json を追加します:

  • 出力をプログラムで解析する場合(パイプライン、スクリプト)
  • 正確なフィールド値(ファイルパス、ステータス、行番号、シンボルの種類)が必要な場合
  • 別のツールと連携する場合

JSON 出力に対応するコマンドは search、explore、file、symbol、class、usages、callers、implementations、refs、stats、changed、hotspots、graph …、unused-symbols、map、conventions です。それ以外(outline、call-tree、hierarchy、imports、todo)は、どちらの場合もテキストを出力します。

ast-index --format json search "Query" | jq '.symbols[].path'

追加リソース

プラットフォーム固有のコマンドの詳細については、以下を参照してください。

  • references/android-commands.md - DI、Compose、Coroutines、XML
  • references/ios-commands.md - Storyboard、SwiftUI、Combine
  • references/typescript-commands.md - React、Vue、Svelte、NestJS、Angular
  • references/rust-commands.md - 構造体、トレイト、impl ブロック、マクロ
  • references/ruby-commands.md - Rails、RSpec、クラス、モジュール
  • references/csharp-commands.md - ASP.NET、Unity、コントローラー、インターフェース
  • references/dart-commands.md - Dart/Flutter のクラス、ミックスイン、拡張
  • references/perl-commands.md - Perl のエクスポート、サブルーチン、POD
  • references/python-commands.md - Python のクラス、関数
  • references/go-commands.md - Go の構造体、インターフェース
  • references/cpp-commands.md - C/C++ のクラス、JNI 関数
  • references/proto-commands.md - Protocol Buffers のメッセージ、サービス
  • references/wsdl-commands.md - WSDL のサービス、XSD 型
  • references/module-commands.md - モジュールの依存関係

コメント