ctreeで取得する情報

Rust で AST ベースの解析器 ctree を作りました。ローカル LLM にコード構造を要約して渡し、必要なシンボルだけを詳しく読むためのツールです。

よく使う言語を対象に、ハッシュ付きスナップショットで実装と依存の変更を追います。ファイルごとに解析の詳しさを変えられます。

ctree の要約から対象を選び、Serena の find_symbol で定義を読みます。pathfinder はファイルパスを解決します。

LLM導入の開発支援で、入力する context を減らすための構成です。

Zed Editor の MCP Servers 画面: ctree (5 tools), pathfinder, serena (22 tools) が並んでいる
Zed Editor の MCP Servers 画面 — ctree, pathfinder, serena が独立した MCP ツールとして動作する

Serenaの前に構造を読む

Serena で全シンボルを先に読むと context が増えます。必要な定義を読む前に、構造の要約が必要でした。

ctree を Serena の前段に置きます。

層ツール役割
ファイル操作の精度向上pathfinderパス解決の失敗をリカバリし、コンテキスト膨張を防ぐ
コードベースの浅い俯瞰ctree実装と依存の変化をハッシュベースでコンパクトに提供
シンボルの精密な解析Serenafind_symbol で特定シンボルの定義・参照を取得

pathfinder がパス、ctree が構造、Serena が定義を扱います。独立した3つの MCP ツールです。


CLI

  $ ctree --help
Generate annotated tree + symbols + compact ctx

Usage: ctree [OPTIONS] [COMMAND]

Commands:
  init
  reset
  check
  clean
  help   Print this message or the help of the given subcommand(s)

Options:
      --mcp                    Run as MCP stdio server
      --config <CONFIG>        Config file path (default: .ctree.toml if exists)
      --root <ROOT>            Scan root path [default: .]
      --syntax <SYNTAX>        [possible values: go, rust, python, typescript,
                                csharp, dart, lua, awk, shell, kotlin, swift,
                                markdown, html]
      --include <INCLUDE>      Include globs
      --exclude <EXCLUDE>      Exclude globs [default: **/tmp/**,**/testdata/**,
                                **/.git/**,**/vendor/**]
      --strong <STRONG>        Strong scope globs
      --weak <WEAK>            Weak scope globs
      --sw <SW>                Max annotation words per strong file line [default: 12]
      --ww <WW>                Max annotation words per weak/symbol-only file line [default: 3]
      --reasoning <REASONING>  Reasoning level [possible values: high, medium, low]
      --template <TEMPLATE>    Output template [possible values: plain, hugo, jinja]
  -h, --help                   Print help
  

ASTで解析する範囲

対応言語

tree-sitter の AST parser を、よく使う言語に絞って実装しました。

Go, Rust, Python, TypeScript/JavaScript, Dart, Kotlin, Lua, Shell, Awk, C#, Swift, Markdown, HTML

アプリ本体に加え、shell script と文書も同じ仕組みで扱います。

strong / weak スコープ

ファイルを strong(詳細)と weak(概要)に分けます。

  [ctree]
watch = "rust"
root = "."
include = ["src/**/*.rs", "tests/**/*.rs"]
exclude = ["**/tmp/**", "**/testdata/**", "**/.git/**", "**/vendor/**", "**/target/**"]
strong = ["src/**"]
weak = ["tests/**"]
sw = 24
ww = 5
reasoning = "medium"
  

strong は詳細な symbol 要約、weak は短い概要です。設定で確認する範囲を切り替えます。

全ファイルの情報量を揃えず、詳しく見る対象を指定するためです。

reasoning プリセット

reasoning = "high" | "medium" | "low" で要約の詳しさを変えます。

reasoning用途
high小規模プロジェクト、詳細な解析が必要な場面
medium通常の開発作業(デフォルト)
low大規模モノレポ、トークンを最小限に抑えたい場面

ハッシュベースのスナップショット

strong / weak の pattern と reasoning から決定論的にハッシュを作り、snapshot ディレクトリを分けます。

  .ctree/
  rust/
    e83adb52/          ← スコープ設定のハッシュ
      snapshots/
        .baseline.txt
        rev/
          0001.txt
          0002.txt
  

範囲を切り替えても過去の snapshot は残ります。元の設定に戻すと再生成せずに利用できます。


MCP ツール

5つの MCP ツールを公開します。

ツール役割
checkスナップショットの生成・更新。最新の差分を返す
get_baselineコードベース全体のアノテーション付きツリー + シンボル要約を返す
get_revsリビジョン履歴(何が変わったか)を返す
get_textハッシュからシンボルや依存のテキストを取得する
get_dependsシンボル間の依存関係を探索する

実際の出力

ctree check — スナップショット生成と差分検出

  $ ctree check --syntax rust
frequency=always
action=generate
latest_before=0001
latest_after=0001
(no new rev)
  

変更がなければ (no new rev)、変更があれば新しい revision と symbol のハッシュを返します。

初回生成の出力です。

  $ ctree check --syntax rust
frequency=always
action=generate
latest_before=
latest_after=0001
rev_file=.ctree/rust/{scope_hash}/snapshots/rev/0001.txt
hashes={hash1},{hash2},{hash3},...

{hash1}
source=symbol kind=module name=... scope=strong path=src/.../main.rs line=2
mod ...;
--{hash1}
{hash2}
source=symbol kind=function name=... scope=strong path=src/.../mcp.rs line=164
fn ...(args: ...) -> Result<...> {
--{hash2}
  

ハッシュを get_text に渡すと symbol の本文を読めます。

get_baseline — コードベースの浅い俯瞰

get_baseline はファイルツリー、symbol 要約、token 推定値を返します。ソース全文を送らず、ここから選んだ定義を Serena の find_symbol で読みます。

自社の LLM pipeline で使っており、出力形式の詳細は公開していません。

get_revs — リビジョン差分

symbol と依存の追加・削除を revision 差分で返します。get_text にハッシュを渡すと本文と依存の詳細を取得できます。

この出力形式の詳細も非公開です。


3つのツールの使い分け

pathfinder — パス解決の失敗をリカバリする

pathfinder は、誤ったディレクトリ名から実在するパスの候補を返します。

  path_resolve:
  check_path: "content/ja/docs/tech/infrastrcture/podman-quadlet-systemd-ubuntu.md"
                                      ^^^^^^^^^^^ typo
  →  resolved: "content/ja/docs/tech/infrastructure/podman-quadlet-systemd-ubuntu.md"
  
  $ pathfinder --help
pathfinder — semantic path finder & MCP resolution server

USAGE
    pathfinder [OPTIONS]          Interactive semantic directory finder (default).
    pathfinder --mcp [OPTIONS]    Start as an MCP server.

FINDER OPTIONS
    --include-builds    Include build/artifact dirs (target, dist, …).

MCP OPTIONS
    --root <PATH>       Add a project root directory to watch and index.

GENERAL OPTIONS
    -h, --help          Print this help message and exit.
    -V, --version       Print version, model, and PCA config.

MCP TOOLS
  1. path_resolve        Resolve a failed file path to the best match.
  2. tool_retry_with_resolve  Resolve + retry the operation in one call.
  3. roots_list          Return configured root directories.
  4. reindex_paths       Force a full index rebuild.

ENVIRONMENT VARIABLES
    PF_MCP_INFERENCE    Inference mode: "general" (default) or "code".
    Models (both INT8 quantized):
      general → mxbai-edge-colbert (17M, 48-dim)
      code    → lateon-code-edge (17M, 48-dim)
  
pathfinder CLI: pf コマンドでセマンティック検索し、ディレクトリを選択して cd する
pathfinder CLI — セマンティック検索でプロジェクトを横断的に俯瞰し、選択結果のディレクトリに cd する

想定ワークフロー

  1. pathfinder  → LLM のパス typo を解決(ENOENT → tool_retry_with_resolve)
2. ctree check → スナップショット更新、変更されたシンボルのハッシュを取得
3. get_baseline → コードベースの浅い俯瞰を得る
4. 関心のあるシンボルを特定 → Serena の find_symbol で定義・参照を深掘り
5. get_revs + get_text → 変更されたシンボルの詳細を取得
  

独立したツールから、要約、対象の選択、定義の順に情報を取得します。

8K〜32Kのローカル LLM でも、使う情報を選んで context の消費を抑える狙いです。


注意事項

  • 対象は対応する言語で、汎用の静的解析器ではありません
  • get_baseline / get_revs の形式は、自社 LLM pipeline の一部として非公開です
  • ONNX / ColBERT などの ML 推論は見送りました。strong / weak で範囲を管理し、決定論的な設計を保っています
  • MCP 2024-11-05に対応し、Claude Code / Zed Editor などから使えます