ASTro-sight
AI エージェント向けの AST 情報生成 CLI。tree-sitter で 16 言語のコードを解析し、シンボルの定義と参照、diff の影響範囲、API の差分、デッドコードを JSON か TOON で返す
対応プラットフォーム
English |
日本語
---
astro-sight は、AI エージェントがコードを編集しながら確かめたい構造の情報を返します。シンボルがどこで定義されどこで使われているか、diff が何を壊すか、公開 API のどこが変わったか、どこからも呼ばれなくなった export はどれか、に答えます。
tree-sitter の構文木の識別子ノードだけを照合するので、`refs --name new` は `grep new` のようにコメントや文字列の中の同じ綴りを拾いません。出力の既定は compact JSON で、トークンを減らしたいときは TOON か自動選択に切り替えられます。同じ問い合わせを CLI、NDJSON の session、MCP サーバーのどれからでも実行できます。
Bash / zsh の解析失敗は結果に明示する。エラー領域で識別できた宣言候補は `refs.kind: "unknown"` として返し、`review` は削除未確認の候補を確定した削除と分ける。[シェルの解析エラー](docs/diff-analysis.ja.md#シェルの解析エラー)を参照。
Rust の cfg 条件判定は走査中の祖先列を再利用し、深い `use` パスで親ノードを繰り返し探索する処理を避けます。参照の位置・順序と cfg キーの除外規則は維持します。再現可能な比較方法は[性能確認](docs/development.ja.md#参照走査の性能)を参照してください。
## 機能
- **識別子単位の参照検索**: `refs` はディレクトリ全体からシンボルの定義と参照を探し、`refs --names` は複数の名前を 1 回の走査で調べます
- **diff の影響分析**: `context` は unified diff から、変わったシンボル、シグネチャの変更、呼び出し元を洗い出します。`impact` は diff の外に未解決の呼び出し元が残っていれば exit 1 を返します (Stop hook 向け)
- **Rust の型エイリアス**: 同じファイルに追加した公開型エイリアスへの置き換えが、旧・新ソースの構文木から同じ型と証明できる場合、関数シグネチャの変更と呼び出し元への影響を情報提供として扱います
- **Rust の引数パターン**: 通常引数の名前・分解パターンだけの変更は、呼び出し契約が同じと証明できれば除外します。型や receiver は引き続き比べます。[証明の範囲と容器の制約](docs/diff-analysis.ja.md#rust-の引数パターン)を参照してください。
- **構造化レビュー**: `review` は影響範囲、git blame から見て一緒に変わりやすいファイル (`cochange`)、公開 API の差分、死蔵シンボルを 1 回でまとめて返します
- **ファイルの構造**: `symbols`・`calls`・`imports`・`ast` がファイルの輪郭、コールグラフ、依存、構文ノードを返し、`sequence` は呼び出しの流れを Mermaid のシーケンス図にします
- **デッドコードとルール**: `dead-code` はどこからも参照されない export を報告し、テストランナーやフレームワークが実行時に呼ぶものは除きます。`lint` は YAML で書いた AST パターンのルールで検査します
- **トークンを意識した出力**: compact JSON・TOON・`--format auto` から選べます。頻出する名前の結果は既定で 100 件か約 3,000 トークンで打ち切り、省いた分の内訳を `result_summary` に出します
- **AI エージェントとの連携**: Claude Code と Codex のスキル、MCP サーバー、問い合わせをまとめて流せる NDJSON の `session` があります
対応言語 (拡張子とパーサの版は [docs/languages.ja.md](docs/languages.ja.md) にあります):
## インストール
### Homebrew (macOS/Linux)
```bash
brew install owayo/astro-sight/astro-sight
```
### winget (Windows)
```powershell
winget install owayo.astro-sight
```
### Cargo
Rust 1.99 以上が必要です。
```bash
cargo install --git https://github.com/owayo/astro-sight --locked
```
### GitHub Releases から
[Releases](https://github.com/owayo/astro-sight/releases/latest) から自分の環境のアーカイブを取得して展開し、`astro-sight` を `PATH` の通った場所に置きます。各リリースには、取得したファイルを確かめるための `SHA256SUMS` も添付しています。
| プラットフォーム | ファイル |
|---|---|
| Linux (x86_64) | `astro-sight-x86_64-unknown-linux-gnu.tar.gz` |
| Linux (x86_64, musl) | `astro-sight-x86_64-unknown-linux-musl.tar.gz` |
| Linux (ARM64) | `astro-sight-aarch64-unknown-linux-gnu.tar.gz` |
| macOS (Intel) | `astro-sight-x86_64-apple-darwin.tar.gz` |
| macOS (Apple Silicon) | `astro-sight-aarch64-apple-darwin.tar.gz` |
| Windows (x86_64) | `astro-sight-x86_64-pc-windows-msvc.zip` |
macOS でブラウザから取得した場合は、実行の前に隔離属性を外します: `xattr -d com.apple.quarantine astro-sight`。
### ソースから
[mise](https://mise.jdx.dev/) が必要です (Rust のツールチェーンは `mise.toml` で固定しています)。
```bash
git clone https://github.com/owayo/astro-sight.git
cd astro-sight
make install
```
`make install` は `/usr/local/bin` に入れます。場所を変えるときは `INSTALL_PATH` を指定します (例: `make install INSTALL_PATH="$HOME/.local/bin"`)。
インストール後は `astro-sight --version` を確認します。`command -v astro-sight` が mise の shim を指す場合は、`mise which astro-sight` で更新対象の実体を確認できます。詳しくは [インストール後の確認](docs/development.ja.md#ci-と同じ検査) を参照してください。
`winget install` の後は新しいターミナルを開いてください。portable パッケージは PATH を書き換えて `astro-sight` を通すので、開いていたターミナルには反映されません。musl 版は glibc を使わない静的リンクのバイナリで、Alpine のように glibc が無い環境や、glibc が古い Docker イメージで使えます。
ソースからビルドするには、tree-sitter のパーサをビルドする C コンパイラ (macOS なら Xcode Command Line Tools) も要ります。`make install` はバイナリを置いた後に、[AI エージェントとの連携](#ai-エージェントとの連携) で説明する Claude Code と Codex のスキルも書き込みます。
## 使い方
結果の既定は 1 行の compact JSON です (バッチ処理ではファイルごとに 1 行)。`--pretty` を付けると JSON を字下げし、`--format toon` か `--format auto` を付けると TOON か、推定トークン数が少ない方の形式に切り替わります。TOON 出力は [v4.1 仕様](https://github.com/toon-format/spec/blob/main/SPEC.md) に従い、空配列は `[]` です。
### エージェント向けの手順
```bash
# 1. diff 全体は review から入る
astro-sight review --dir . --git
# 2. 編集前後は context / impact を対にする
astro-sight context --dir . --git
astro-sight impact --dir . --git
# 3. 構造把握は symbols、識別子参照は refs
astro-sight symbols --path src/main.rs
astro-sight refs --name "AppService" --dir src/
# 4. 構文ノードを正確に特定したいときだけ ast を使う
astro-sight ast --path src/main.rs --line 10 --col 0
# 5. 繰り返し確かめる構造ルールは lint、呼び出し順序が重要な場合や 3 段以上の呼び出しは sequence で確認する
astro-sight lint --path src/main.rs --rules rules.yaml
astro-sight sequence --path src/main.rs --function main
# 6. 種類の違う問い合わせが 2 個以上続くなら session にまとめる
printf '%s\n' \
'{"command":"symbols","path":"src/main.rs"}' \
'{"command":"refs","name":"AppService","dir":"src"}' \
| astro-sight session
```
### 参照を探す
```bash
astro-sight refs --name extract_symbols --dir .
```
```json
{
"symbol": "extract_symbols",
"refs": [
{ "path": "src/engine/symbols/mod.rs", "ln": 107, "col": 7, "ctx": "pub fn extract_symbols(...)", "kind": "def" },
{ "path": "src/commands/api_changes/exported.rs", "ln": 45, "col": 39, "ctx": "let syms = crate::engine::symbols::extract_symbols(root, source, lang_id).ok()?;", "kind": "ref" }
]
}
```
`path` は `--dir` からの相対パスで、`ln` と `col` は 0 始まりです。参照が 100 件を超えるか、出力が約 3,000 トークンを超える名前では、そこで出力を打ち切り、省いた参照の内訳を `result_summary` に出します。上限は `--max-results` と `--token-budget` で変えられます (`unlimited` で上限なし)。
解析できない言語のソース (`.vue`、`.applescript` など) は黙って飛ばさず `truncations` に並べます。どのファイルも解析できない範囲では、空の結果ではなく `UNSUPPORTED_LANGUAGE` を返します。詳しくは [解析できない言語のファイル](docs/usage.ja.md#解析できない言語のファイル) を参照してください。
### 未解決の影響を確かめる
```bash
astro-sight impact --dir . --git
```
```text
Unresolved impacts found:
src/engine/symbols/mod.rs changed [extract_symbols]:
→ src/service.rs:284 [extract_symbols]
→ src/commands/api_changes/exported.rs:45 [extract_symbols]
```
呼び出し元をすべて直してあれば、`impact` は何も出力せずに exit 0 で終わります。未解決の影響が残っていれば、上の一覧を stderr に出して exit 1 を返します。このテキストの行番号は、エディタでそのまま開けるよう 1 始まりです。
TS/TSX では、固定インターフェース型を受け取ってそのまま返すローカル関数に、単一メソッドのオブジェクトを直接登録して default export する形を限定的に証明します。契約に既存の引数をメソッド実装が受け取り始めても、契約・登録経路が不変で、直接呼び出しの引数数を確認できれば、`mod_compat` の理由 `fixed_callback_contract` として残します。`impact` とレビュー用 hook は停止せず、`context` の参照情報は保持します。
対象は単純な必須引数と `void` 戻り値で、対象の default import に結び付く直接呼び出しを要求します。オブジェクトの受け渡し・別名・再 export・動的アクセス・解析失敗がある場合や、ソースが 512 ファイル・8 MiB・100,000 ノードの上限を超える場合は、従来の判定を維持します。現状の証明範囲は JS/TS のみで、リポジトリ全体に外部 import・計算アクセス・エスケープ付き文字列が無い場合に限られます。実装の引数と本体以外は旧新の byte 一致を要求し、動作の同値性や外部の利用者まで保証するものではありません。
TypeScript の interface か object 型の type alias へ必須プロパティを足した変更は、`api.mod_closed` に分かれることがあります。条件は、その型を返す関数、`const x: T` と `satisfies T` の値、その型を引数に取るファイル直下の関数の呼び出し元を、同じ差分ですべて直していることです。足したプロパティには、新しいメンバーの型に合う値が要ります。generic や `extends` のある宣言、必須メソッドの追加、対応していない位置 (`T[]` など) の参照は、参照の行が変わっていても blocking に残ります。詳しくは [TypeScript の型への必須プロパティ追加](docs/diff-analysis.ja.md#typescript-の型への必須プロパティ追加) を参照してください。
詳しい説明は話題ごとに分けています。
- 全コマンドのオプション、バッチ処理、`session`、MCP サーバー: [docs/usage.ja.md](docs/usage.ja.md)
- `context`・`impact`・`review`・`dead-code`・`cochange` の詳細: [docs/diff-analysis.ja.md](docs/diff-analysis.ja.md)
- 短縮キー、TOON、`--format auto`: [docs/output-format.ja.md](docs/output-format.ja.md)
## 設定
`astro-sight init` は設定ファイルを `~/.config/astro-sight/config.toml` に書き出します (`--path` で別の場所に書けます。同じパスにファイルがあると確認なしで上書きします)。`--config ` を付けると、その実行だけ別の設定ファイルを読みます。
```toml
debug = false # デバッグログをファイルに出力する
format = "json" # 既定の出力形式: "json" | "toon" | "auto"
skip_generated = true # ディレクトリの走査から生成ファイルを外す
```
コマンドラインの `--format` は、設定の `format` より優先されます。ログの置き場所、`~/.cache/astro-sight/` のキャッシュと `--no-cache` は [docs/configuration.ja.md](docs/configuration.ja.md) で説明しています。
## AI エージェントとの連携
スキルとして登録すると、Claude Code や Codex が「この関数の呼び出し元は?」「この diff の影響範囲は?」のような質問で astro-sight を使うようになります。
```bash
astro-sight skill-install claude # ~/.claude/skills/astro-sight/SKILL.md
astro-sight skill-install codex # ~/.codex/skills/astro-sight/SKILL.md
```
MCP サーバーとして stdio で動かすときは、解析したいリポジトリをカレントディレクトリにして `astro-sight mcp` を起動します。そのディレクトリの外のファイルは拒否します。
```json
{
"mcpServers": {
"astro-sight": {
"command": "astro-sight",
"args": ["mcp"]
}
}
}
```
スキルを入れただけでは、エージェントが grep に戻ることがあります。astro-sight を優先させる `CLAUDE.md` / `AGENTS.md` の規則は [docs/integrations.ja.md](docs/integrations.ja.md) にあります。`impact` が未解決の呼び出し元を報告している間は作業を終えさせない Stop hook の設定も、同じ文書で説明しています。
## 開発
[mise](https://mise.jdx.dev/) が必要です。ツールの版は `mise.toml` で固定しています。
```bash
make setup # ツールチェーン (mise) と依存を取得する
make ci # CI と同じ検査 (書き換えない)
```
| コマンド | 説明 |
|---|---|
| `make setup` | ツールチェーン (mise) と依存を取得する |
| `make build` | デバッグ版をビルドする |
| `make release` | リリース版をビルドする |
| `make run` | デバッグ版を実行する (引数は ARGS="...") |
| `make test` | テストを実行する |
| `make lint` | clippy を警告ゼロで通す |
| `make fmt` | コードを整形する (書き換える) |
| `make fmt-check` | 整形済みかを確かめる (書き換えない) |
| `make check` | 整形と静的検査 (書き換えない) |
| `make ci` | CI と同じ検査 (書き換えない) |
| `make install` | リリース版を INSTALL_PATH (既定 /usr/local/bin) に入れる |
| `make uninstall` | INSTALL_PATH から取り除く |
| `make clean` | ビルド成果物を消す |
`make` でターゲットの一覧を表示します。リリースは GitHub Actions で行います (**Actions → Release → Run workflow**)。
mise のほかに、tree-sitter のパーサをビルドする C コンパイラと、テストが呼ぶ `git` が要ります。mise を使わないときは `SYSTEM_TOOLS=1` を付けると、PATH 上のツールで動きます。`.cargo/config.toml` の `[patch]` でローカルの tree-sitter 系を差し込むと `Cargo.lock` が手元でだけ変わり、`--locked` で止まります。そのときは `make ci CARGO_FLAGS=` で外してください。
`make install` で入れるスキルの選び方、ヒーププロファイル、利用状況の集計ツール、リリースの流れは [docs/development.ja.md](docs/development.ja.md) で説明しています。
## ライセンス
[MIT](LICENSE)