maxgfr/codeindex
GitHub: maxgfr/codeindex
一个零依赖、确定性输出的仓库索引引擎,通过 tree-sitter AST 与 regex 双通道提取符号和 import,构建跨文件依赖图并支持 CLI、库和 MCP server 三种使用方式。
Stars: 0 | Forks: 0
# codeindex
独立、确定性的 **repo-indexing engine**:文件遍历、语言检测、符号/import 提取(tree-sitter AST 并带有 regex 后备)、import 解析、类型化的跨文件 link-graph 以及图分析——作为一个单一的零依赖 `engine.mjs` 提供,供消费工具直接 **vendor**(复制到其 repo 中)而不是通过安装使用。
提取自 [ultraindex](https://github.com/maxgfr/ultraindex) 5.1.0 的核心,并被 ultra* 技能系列(ultraindex, ultradoc, ultrasec, ultraeval, reconstruct, construct, ultra11y)所使用。
## 功能说明
- **遍历** repo 并确保确定性:ignore 列表、跳过 binary/lockfile、大小和数量上限(`capped` 标志,从不静默截断)、symlink-cycle 防护。
- **扫描** 每个文件并生成 `FileRecord`:分类、语言、symbols、imports、headings、hashes — 带有增量缓存快速路径。
- **提取 symbols** 通过 tree-sitter(10 种语言,当存在 wasm sidecar 时)或基于语言的 regex 规则(15 种语言,始终可用)。
- **解析 imports** 跨多种语言:tsconfig 路径、package `exports`、go.mod、Cargo、Java 包、PSR-4、C# namespace。
- **构建类型化的 link-graph**:在文件和模块级别提供 `import` / `call` / `use` / `doc-link` / `mention` 边,以及 Louvain 社区、PageRank/介数中心性、tests→code 映射和意外边检测。
- **渲染** 字节稳定的 `graph.json` / `symbols.json`(对于未更改的 repo,两次构建是字节完全相同的),外加一个 **SCIP** 代码智能索引(`index.scip`),通过手动编写的零依赖 protobuf 编码器实现 — 由官方 `scip` CLI(`stats`/`lint`)验证。
## 作为库使用(vendoring 模式)
使用者将 `scripts/engine.mjs` + `scripts/engine.d.mts`(在固定的 release tag 处获取)提交到 `src/vendor/` 并从中导入;他们的 bundler 会内联该 engine,因此他们仍然会发布单个文件:
```
import { buildIndexArtifacts, renderGraphJson } from "./vendor/engine.mjs";
const { scan, graph, symbols } = buildIndexArtifacts("/path/to/repo");
```
AST 层是可选的:如果 bundle 旁边没有 `grammars/` 目录,engine 会静默使用其 regex 层。只有想要 AST 精度的工具(例如 ultraindex)才会额外 vendor `scripts/grammars/`(约 17 MiB 的 wasm)。
## 通过 npm 使用
对于不想 vendor 该 bundle 的使用者,`@maxgfr/codeindex` 也可以作为常规 package 解析:
```
npm i @maxgfr/codeindex
```
```
import { scanRepo, ENGINE_VERSION } from "@maxgfr/codeindex";
const scan = scanRepo("/path/to/repo");
```
CLI 也包含在同一个 package 中 — 有关全局安装命令,请参阅下方的 **作为 CLI 使用**。Skills 仍然应该优先选择 vendoring:这能保持它们自己的 bundle 为单文件,并固定到特定的 commit,而无需 npm 依赖。
## 作为 CLI 使用
```
brew install maxgfr/tap/codeindex # or: npm i -g @maxgfr/codeindex
codeindex index --repo . --out .codeindex # graph + symbols + incremental cache
codeindex graph --repo . > graph.json
codeindex scip --repo . --out index.scip # SCIP index (--out - for stdout)
codeindex callers --repo . # per-symbol caller index
codeindex grep 'pattern' --repo .
```
## 搜索
`codeindex search "" --repo .` 使用无 key 的 BM25 对 symbol 名称、路径片段、markdown headings 和摘要进行文件排名。如果查询 term 在语料库中没有任何匹配项(零文档频率),则会触发确定性的 **trigram fuzzy fallback** — 无需 embedding 即可实现容错:该 term 会通过字符 trigram 的 Dice 相似度与语料库词汇表进行比较(阈值为 0.6,前 3 个候选项,贡献度按 Dice 分数缩放,因此近似匹配的排名始终低于精确命中)。已经匹配到内容的 term 绝不会被修改,因此现有的查询将保持字节完全一致。默认启用;可通过 `--no-fuzzy`(CLI)或 `fuzzy: false`(库/MCP `SearchOptions.fuzzy`)禁用;当后备机制产生贡献时,结果中会附带一个相加性质的 `fuzzyTerms` 字段。
## 作为 MCP server 使用
`codeindex mcp`(或 `node scripts/cli.mjs mcp`)通过 stdio 提供 engine 服务 — 工具包括:`scan_summary`、`graph`、`symbols`、`callers`、`workspaces`、`churn`、`grep`。在 Claude Code 中通过以下方式注册它:
```
claude mcp add codeindex -- codeindex mcp
```
`engine.mjs` 是一个纯粹的、无副作用的库(使用者可以安全地将其内联到自己的 CLI 中);`cli.mjs` 是一个轻量级的独立 CLI/MCP wrapper。
## 版本控制
- `ENGINE_VERSION` — release tag,以可 grep 的方式嵌入在 bundle 中。
- `SCHEMA_VERSION` — `graph.json`/`symbols.json` 的结构(延续了 ultraindex 的谱系;目前为 4)。使用者会拒绝不匹配的 artifact。
- `EXTRACTOR_VERSION` — 提取输出的结构;当它更新时,基于它生成的增量缓存将被完全丢弃。
`buildGraph`/`buildIndexArtifacts` 接受 `meta: { version, schemaVersion }` 参数,以便使用者可以将其自身的身份信息标记到其持久化的 artifact 中。
## 基准测试
使用可重现的测试工具(`scripts/bench/`)针对 01x-in/codeindex、universal-ctags 和 scip-typescript 进行了测量;完整的方法论、公平性说明及所有场景请参阅 [BENCHMARKS.md](./BENCHMARKS.md)。
| 指标 | codeindex | 上下文 |
| --- | --- | --- |
| `socialgouv/code-du-travail-numerique` — 冷索引 | 1,746 毫秒 | 对比 ctags 371 毫秒,01x 初始化 13,409 毫秒 |
| `socialgouv/code-du-travail-numerique` — 热重跑 | 339 毫秒 | |
| `vercel/next.js` — 冷索引 | 9,398 毫秒 | 对比 ctags 3,431 毫秒 |
| `socialgouv/code-du-travail-numerique` — token 比率(实测) | 32.9× | 结构化索引对比原始 grep,单 symbol 查找 |
## 开发
```
pnpm install
pnpm test # unit + fixtures + compat + no-wasm gates
pnpm typecheck
pnpm build # tsup → scripts/engine.mjs + scripts/engine.d.mts
pnpm check:build # proves the committed bundle is byte-reproducible
pnpm test:e2e # opt-in: pinned real-repo builds with ratchets
```
兼容性测试套件固定了 ultraindex 5.1.0 为 `mini-repo` fixture 生成的确切字节 — 这是提取无损的证明。
## 许可证
MIT
标签:MITM代理, 数据可视化, 自动化攻击