指南

Code Intelligence

REAP 内置代码索引。无需安装、无需启动、没有后台进程。Tree-sitter 解析器遍历每个受版本控制的文件,记录其中定义的符号以及它们之间的调用与 import,并将结果以 gzip 压缩的 JSON 存放在 .reap/.index/。随附 15 种语言,且没有原生构建 —— 语法是 WebAssembly。

命令

每个子命令都与 REAP 的其他命令一样在 stdout 输出 JSON,智能体可以解析,人可以读 message 字段。

bash
reap index                     # update —— 默认行为
reap index update [--full]     # 让索引与 HEAD 对齐
reap index status              # 统计、import 解析率、已索引的 commit
reap index impact <file>...    # 修改这个文件会影响什么
reap index search <query>      # 查找定义,返回 file:line
reap index callers <symbolId>  # 谁调用了它
reap index callees <symbolId>  # 它调用了什么

symbolId 的形式是 <file>::<name> —— 例如 src/core/lifecycle.ts::nextStage。reap index search 会输出它们。

变更的单位是 commit

索引记录它所描述的 SHA。判断需要重新解析什么只是一次 git diff,判断是否值得重新解析只是一次字符串比较。一旦 HEAD 移动 —— 提交、切换分支、rebase 或 pull 之后 —— 查询本身会更新索引。REAP 只在自己刚提交的地方主动刷新:completion 末尾,以及 early-close。

bash
reap index update    # Indexed 412 file(s) — full, 1530 symbols at 1a2b3c4 (612ms)
reap index update    # Index is current at 1a2b3c4 (1530 symbols, 3688 edges)

代价是:未提交的工作不在索引中。刚写完还没提交的符号 search 找不到,新建的文件也不会出现在 impact 里 —— 那部分请用 Grep。此外需要一个 git 仓库,否则没有可供索引绑定的 commit。

相信 impact 之前先看 status

impact 所知的一切都来自已解析的 import 边。imports 比率偏低意味着图不完整,此时空的 blast radius 表示未知而非没有。status 还会在语法加载失败时发出警告 —— 这是某种语言被悄悄漏掉索引的另一条路径。

text
files:   412
symbols: 1530  (function 902, method 341, class 187, type 100)
edges:   3688  (CALLS 3145, IMPORTS 543)
imports: 543/543 resolved (100%)
commit:  1a2b3c4

(示例数值。)关键是 imports 这一行。impact 所知的一切都来自已解析的 import 边,因此解析率偏低意味着图不完整 —— 此时空的 blast radius 表示「未知」,而不是「没有」。无法把 ./x.js 这样的 specifier 对应到生成它的 x.ts 的解析器,在这里会报告零 —— 所以我们把解析率显示出来,而不是从「索引跑了吗」去推断。

索引存放在哪里

位于 .reap/.index/ —— 一个 manifest.json 加一个 gzip 压缩的图 —— 并由 reap init 和 reap update 写入 .gitignore。删除项目时索引随之消失,主目录里不会累积任何东西。忽略它与体积无关:把索引提交进去意味着包含它的那次提交又需要被索引,这个过程不会终止。删除 .reap/.index/ 永远是安全的 —— 下一条命令会重建。

何时使用

两者互补 —— 索引以 file:line 作答,你据此去读代码。

使用当问题是
reap index这在哪里定义、谁调用它、什么依赖这个文件、这次改动的 blast radius 有多大
Grep / Glob字面字符串、注释、配置文件、没有语法支持的语言,以及一切尚未提交的内容