内容
<p align="center">
<img src="docs/assets/codebase-memory-logo.png" alt="Codebase Memory project logo" width="240">
</p>
# 代码库内存 V2
> **混合代码智能** — 原生 WASM 索引器(112 种语言)+ 人类记忆图 + Obsidian 保险库同步。
> V1(C 引擎,158 种语言)仍然是一个可选的、单独运行的数据库生产者和参考;V2 永远不会自动启动它。
[](https://github.com/Cheurteenyt/codebase-mirror/actions/workflows/ci.yml)
[](LICENSE)
## 这是什么?
代码库内存 V2 是一个 **混合** 代码智能系统:
1. **原生 WASM 索引器** (V2)— 通过 tree-sitter WASM 语法实现 112 种语言。 在 TypeScript/JavaScript 上具有最先进的语义精度:跨文件调用解析、模块有效性锁定、类型/值默认分离、内置真实性锁定。 语义版本 8。
2. **人类记忆图** (V2)— ADRs、bug 注释、重构计划、约定、遗留区域标记、风险评估、活动日志 — 同步到与 Obsidian 兼容的 Markdown 保险库。
3. **V1 C 引擎** (单独的生产者/参考)— 通过 tree-sitter C 实现 158 种语言。 如果操作员单独运行 V1,则 V2 可以通过 `CodeGraphReader` 读取生成的兼容 SQLite 数据库。
V2 在不调用 V1 的情况下执行原生索引。 它不会自动回退到 V1、合并 V1 和 V2 输出或按需创建 V1 数据库。
## 当前版本
参见 `v2/package.json` 和 `v2/CHANGELOG.md` 获取权威版本、测试计数和错误/优化历史。
## 快速开始
需要 Node.js >= 22.12.0。 仓库的 `.nvmrc` 和 `.node-version` 选择 Node 24 LTS 进行开发。
```bash
cd v2
npm ci
# 后端 CLI + MCP 服务器
npm run build
npm test # 参见 v2/CHANGELOG.md 获取当前测试计数
# 原生索引项目(不需要 V1 进行 TS/JS)
node dist/cli/index.js index --project my-app --root /path/to/repo
node dist/cli/index.js index --project my-app --root /path/to/repo --incremental
# 尝试演示
node dist/cli/index.js demo
# 初始化项目
node dist/cli/index.js init --project my-app
# 运行诊断
node dist/cli/index.js doctor --project my-app
# 构建完整的包,包括 Graph UI,然后启动它
npm run build:package
node dist/cli/index.js ui --project my-app
# 允许 Control 浏览/索引家目录外的存储库
node dist/cli/index.js ui --project my-app --allowed-root /srv/repos
```
`npm ci` 安装依赖项但不将此包的 `cbm-v2` 二进制文件放在您的 `PATH` 上。 从源代码检出使用 `node dist/cli/index.js`,如上所示,或在您更喜欢较短的 `cbm-v2` 命令时运行 `npm link` 一次。
## CLI 参考
### 核心命令
| 命令 | 描述 |
|---|---|
| `cbm-v2 index --project <p> --root <r>` | 原生索引项目(WASM,112 种语言) |
| `cbm-v2 index --project <p> --root <r> --incremental` | 快速增量索引(跳过未更改的文件) |
| `cbm-v2 index --project <p> --root <r> --discovery-mode fast` | 显式减少覆盖范围的完整重建,用于基准测试/速度敏感的运行;与 `--incremental` 不兼容 |
| `cbm-v2 index --project <p> --root <r> --dry-run` | 预览而不写入数据库 |
| `cbm-v2 init` | 初始化 `.codebase-memory.json` 配置 |
| `cbm-v2 doctor` | 运行诊断(Node 版本、数据库、保险库路径) |
| `cbm-v2 stats` | 显示漂亮的统计仪表板 |
| `cbm-v2 demo` | 创建具有示例注释 + 保险库的演示项目 |
| `cbm-v2 mcp` | 作为 MCP 服务器运行(JSON-RPC via stdio) |
| `cbm-v2 ui [--allowed-root <paths...>]` | 启动图 UI Web 服务器(端口 9749);可选地允许其他本地浏览/索引根目录 |
| `cbm-v2 watch` | 监视保险库中的更改并自动同步(守护进程) |
### 人类记忆命令
| 命令 | 描述 |
|---|---|
| `cbm-v2 human create --type ADR --title "ADR-001: ..."` | 创建注释 |
| `cbm-v2 human list [--type ADR] [--status active]` | 列出注释 |
| `cbm-v2 human show <id>` | 显示注释(JSON,包括边) |
| `cbm-v2 human link <noteId> --to-cbm-node <id> --edge DECIDES` | 将注释链接到代码节点 |
### Obsidian 命令
| 命令 | 描述 |
|---|---|
| `cbm-v2 obsidian init` | 创建保险库目录结构 |
| `cbm-v2 obsidian sync` | 双向同步(数据库 ↔ 保险库) |
| `cbm-v2 obsidian sync --dry-run` | 预览而不写入 |
| `cbm-v2 obsidian sync --direction export` | 仅导出(数据库 → 保险库) |
| `cbm-v2 obsidian sync --direction import` | 仅导入(保险库 → 数据库) |
| `cbm-v2 obsidian export` | 一次性导出(数据库 → 保险库) |
| `cbm-v2 obsidian import` | 一次性导入(保险库 → 数据库) |
| `cbm-v2 obsidian report` | 保险库文件报告(按目录) |
| `cbm-v2 obsidian create-adr --title "ADR-003: ..."` | 创建 ADR + 数据库记录 |
| `cbm-v2 obsidian create-module-note --module auth` | 创建 ModuleNote |
| `cbm-v2 obsidian create-route-note --method POST --path /api/login` | 创建 RouteNote |
### 报告命令
| 命令 | 描述 |
|---|---|
| `cbm-v2 report hotspots` | 关键模块(高度和复杂性) |
| `cbm-v2 report undocumented` | 没有人类注释的代码节点 |
| `cbm-v2 report risk` | 高耦合、死代码、脆弱接口 |
### 备份命令
| 命令 | 描述 |
|---|---|
| `cbm-v2 backup export --output backup.json` | 将所有注释 + 边导出到 JSON |
| `cbm-v2 backup import backup.json` | 从 JSON 备份导入 |
| `cbm-v2 backup import backup.json --dry-run` | 预览导入 |
## MCP 工具(8)
`cbm-v2 mcp` 命令通过 stdio 上的 JSON-RPC 2.0 公开 8 种工具:
| 工具 | 类型 | 描述 |
|---|---|---|
| `get_project_overview` | 读取 | 高级项目统计(节点、注释、覆盖率、新鲜度) |
| `get_module_context` | 读取 | 完整模块上下文:代码 + 人类注释 + ADRs + 错误 + 重构 |
| `get_undocumented_hotspots` | 读取 | 没有文档的关键代码节点 |
| `create_human_note` | 写入 | 创建 ADR/BugNote 等 + 链接到代码节点 |
| `link_note_to_code_node` | 写入 | 将现有注释链接到代码节点 |
| `search_code_and_memory` | 读取 | 跨代码图 + 人类记忆的统一搜索 |
| `lookup_source_text` | 读取 | 有界精确字面量、身份感知直接/多跳调用者、调用链和跟踪顶级库存,带有显式完整性 |
| `prepare_edit_context` | 读取 | 编辑需要结构上下文时的依赖关系、爆炸半径、风险、新鲜度和链接记忆证据 |
### 连接 AI 代理
将以下内容添加到您的 MCP 客户端配置(Claude Desktop、Cursor、Zed 等):
```json
{
"mcpServers": {
"codebase-memory-v2": {
"command": "node",
"args": ["/absolute/path/to/codebase-mirror/v2/dist/cli/index.js", "mcp", "--project", "my-app"]
}
}
}
```
对于 Codex,请在运行 `npm run build` 后将本地 STDIO 服务器添加到 `~/.codex/config.toml` 或受信任项目的 `.codex/config.toml` 中:
```toml
[mcp_servers.codebase_memory_v2]
command = "node"
args = ["/absolute/path/to/codebase-mirror/v2/dist/cli/index.js", "mcp", "--project", "my-app"]
```
在 Windows 上,全局文件为 `%USERPROFILE%\.codex\config.toml`。 使用正斜杠的绝对路径,例如 `D:/Mycodex/codebase-mirror/v2/dist/cli/index.js`,或在 TOML 字符串中转义每个反斜杠。 编辑配置后重启 Codex,然后使用 `codex mcp list` 或 `/mcp` 验证连接。
## 工作原理
```
┌──────────────────────────────────────────────────────────────┐
│ 代码库内存 V2(混合) │
├──────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────┐ ┌──────────────────────────┐ │
│ │ V2 原生索引器 │ │ V1 C 引擎(单独) │ │
│ │ tree-sitter WASM │ │ tree-sitter C │ │
│ │ 112 种语言 │ │ 158 种语言 │ │
│ │ 跨文件解析器 │ │ 数据库生产者/参考 │ │
│ │ 语义版本 8 │ │ │ │
│ └───────────┬─────────────┘ └──────────┬───────────────┘ │
│ │ │ │
│ v v │
│ ┌─────────────────────────────────────────────────────────┐│
│ │ SQLite 代码图(每个运行由一个索引器生成) ││
│ └─────────────────────────────────────────────────────────┘│
│ │ │
│ v │
│ ┌─────────────────────────────────────────────────────────┐│
│ │ V2 人类记忆层 ││
│ │ 人类记忆数据库 • Obsidian 保险库同步 • 图形 UI ││
│ │ 8 种 MCP 工具 • 报告 • 智能层 ││
│ └─────────────────────────────────────────────────────────┘│
│ │
│ 存储: │
│ ~/.cache/codebase-memory-mcp/ │
│ <project>.db ← 代码图(V2 或单独的 V1) │
│ <project>.human.db ← 人类记忆(V2,TS) │
│ <repo>/.codebase-memory-vault/ ← Obsidian 保险库(MD) │
│ <repo>/.codebase-memory.json ← 项目配置 │
└──────────────────────────────────────────────────────────────┘
```
## 原生索引器(V2 WASM)
V2 包含一个 **原生代码索引器**,无需 V1 C 二进制文件:
- **112 种语言** 通过预构建的 tree-sitter WASM 语法(`tree-sitter-wasm`)
- **跨文件调用解析** — 持久的 `call_sites`、`imports`、`exports` 表;解析器将调用站点与文件间的定义相匹配
- **模块有效性锁定** — 检测重复导出、默认标记冲突、未解析的星源、无效内置函数
- **类型/值默认分离** — 接口/类型别名默认值不包含在运行时计数中
- **内置真实性锁定** — `isBuiltin()` 来自 `node:module`;`node:fake` 被拒绝,`node:test` 被接受
- **增量索引** — 内容哈希 + mtime_ns 快速跳过;仅删除的快速路径
- **并行工作线程** — 大型项目的多线程 WASM 解析
- **语义版本控制** — `CURRENT_EXTRACTOR_SEMANTICS_VERSION = 8`;增量模式在提取器输出更改时强制完整重新索引
- **发现完整性锁定** — 具有结构化错误的 `DiscoveryResult`;部分发现保留现有图(无静默清除)
- **规范根传播** — 符号链接根生成不带 `..` 的 `file_path`
- **文件身份契约** — `dev:ino` 具有 `0:0` 回落的重复数据删除;确定性硬链接选择
### 限制
- V2 原生索引器在 **TypeScript/JavaScript** 上最为精确。 其他语言(Python、Go、Rust 等)通过结构解析但不具备跨文件解析。
- 对于 V1 的 158 种语言覆盖率和精度,请单独运行 V1 C 二进制文件以生成项目数据库,然后从 V2 打开它。
- 图形 UI 概览限制为 1,000 个代表节点,以确保可预测的传输和模拟成本。 精确的域、社区和目录范围在修订绑定页面中加载; 完整的项目永远不会被传输,仅用于检查一个范围。 选择一个社区会立即打开其精确的符号,而文件系统树请求一个不同的目录子树,因此同名布局社区无法替换它。
## 人类记忆节点类型
| 标签 | Obsidian 目录 | 描述 |
|---|---|---|
| `ArchitectureNote` | `Architecture/` | 横向架构笔记 |
| `ADR` | `ADR/` | 架构决策记录 |
| `BugNote` | `Bugs/` | 已知错误 |
| `RefactorPlan` | `Refactor/` | 计划的重构 |
| `LegacyNote` | `Legacy/` | 遗留区域标记 |
| `Convention` | `Conventions/` | 编码/架构约定 |
| `Prompt` | `Prompts/` | AI 代理的有用提示 |
| `JournalEntry` | `Journal/` | 活动日志 |
| `ModuleNote` | `Modules/` | 附加到模块的注释 |
| `RouteNote` | `Routes/` | 附加到 HTTP 路由的注释 |
| `RiskNote` | `Architecture/` | 风险评估 |
## 保险库格式
每个笔记都有两个部分:
```markdown
---
type: adr
status: active
cbm_node_ids: [1234]
tags: [auth, security]
---
# ADR-001: 使用 JWT 进行身份验证
## 自动生成
> ⚠️ 此部分由 Codebase Memory V2 控制,可能会重新生成。
> 请勿编辑 — 您的更改将在下一次同步时丢失。
### 元数据
- **类型**:ADR
- **状态**:active
- **Slug**:adr-001-use-jwt-for-authentication
### 代码链接
- [[1234]] — 模块:auth (`src/auth/index.ts:1`)
---
## 人类笔记
> ✏️ 此部分属于用户。 它将 **永远不会** 被覆盖。
### 上下文
我们需要一个无状态的身份验证机制。
### 决定
使用具有 HS256 签名的 JWT 令牌。
```
`## 人类笔记` 部分 **永远不会** 被 V2 覆盖。 在 Obsidian 中自由编辑它 — 下一次同步将保留您的编辑。
## 图形界面
V2图形界面取代了V1的独立3D Three.js场景,使用一个有界的2D d3-force画布和两个任务视图来显示同一个图:
- **仪表盘选项卡**(默认):关键绩效指标,图表新鲜度,智能推荐
- **图表选项卡**:2D 力导向画布,带有过滤器,平移/缩放,节点详细信息面板
- **结构**(默认):域名包含有界的信息丰富的社区标题,在缩放揭示单个符号之前。悬停或使用键盘聚焦于域名,激活一个渐进式洞察镜头:其确切的容量汇总和相关捆绑仍然可见,而社区标题仅限于该域名;闲置概览不会获得永久注释
- **依赖关系**(可选,本地持久化):精确度中心形成一个确定性星座。在选择之前,指针悬停或键盘节点聚焦会在已结算的框架中绘制一个瞬态可见的第一跳镜头:每个语义关系组最多两条事件边缘,带有真实的颜色/虚线语法和方向标记。它仅使用已加载的拓扑结构,不执行请求或模拟突变,并在布局,精确聚焦,过滤器移除和服务器修订转换时消失。选择一个符号,然后展开最多四个可见的传入/传出关系层,围绕一个固定在语义原点的焦点,具有无关节点作为淡色外层上下文。编号轨道暴露跳跃深度,重复目录车道暴露模块上下文,焦点画布标签列表显示与所选符号相关的可见关系组。传入标签向左打开,传出标签向右打开,通过三个确定性冲突候选。选定的框架在由保真度HUD,动作轨道,面包屑和详细信息面板留下的画布区域内重新组合;面板/视口调整大小会更新该摄像机,而不会重新加热d3。远距离深度使用单调压缩间距,中等扇出扩展垂直,因此受限画布可以扩大有向框架而不会合并轨道。符号标签共享自适应屏幕区域预算,确定性外部优先冲突回退和视口保护,防止文本被裁剪或隐藏在持久图表控件下。冲突优先级标签从最多四个预算窗口中回填,限制为每次绘制96个候选,而不是完整图表
- **精确范围**(按需):选择社区或文件系统目录,用修订绑定精确页面替换代表性框架,在同一画布内。后台添加一个确定性目录->文件->符号计划,从完整精确成员资格计算,因此第一页已经显示整个有界架构,同时仅绘制已加载的符号。原始内部拓扑立即可用,密集范围公开一个明确的“加载更多”操作。选择已加载的符号,保持精确范围安装,打开其详细信息,并仅强调可见事件关系;键盘社区浏览跳过文件表面,其符号尚未加载
- **解释耦合路径**(按需):将选定符号设为路径起点,然后使用现有的项目搜索或地图选择任何其他符号。详细信息面板显示确切的最短源到目标链,每个中间文件和每个关系的存储方向/类型。这使用完整的项目数据库,而不是代表性框架;有界搜索结果永远不会声称两个符号是断开的
- **项目选项卡**:项目列表,带有节点/边计数和健康状态
- **控制选项卡**:系统信息
两个图表视图共享一个拓扑结构,画布,d3模拟对象,采样/精确度标签,过滤器,选择,键盘模型和详细信息API。`结构`遵循服务器编写的域名/社区锚点。文件系统树路径保持一个单独的精确`目录`范围,即使社区具有相同的键;其面包屑返回父域名,而不重新标记采样数据为精确。`依赖关系`重新配置相同的模拟,带有任务特定目标和一个有界的重新加热,当视图或聚焦符号更改时;已知过滤器子集不会重新加热,没有渲染器,画布或节点对象被重建。直接关系导致聚焦框架,而真实深度2-4保留其语义线语法,权重较低;不推进或远离焦点的交叉链接不会被提升为流程。聚焦标签排名在语义框架更改时预计算,而不是在每次画布绘制期间排序。
未选定的依赖关系概览是一个精确的,有界的**依赖关系地图**,而不是1,000个符号的粒子环。布局响应排名最多12个顶级域名,将其精确的节点总数打包成稳定的圆圈,并聚合触摸这些域内的每个有向关系。省略域的流量仍包含在选定域的精确传入/传出总数中;它不会作为误导性的合成节点渲染。覆盖范围标记为完整或部分,关系类型过滤器重用返回的精确组而不进行另一个请求。
域名选择打开其采样结构,并公开现有的修订绑定精确范围操作,而缩放渐进式揭示代表性符号星座。在宏观规模上,画布跳过所有采样节点填充和命中测试;它仅绘制有界域名表面,流量层,标签和最多28个有向捆绑。相同的节点对象,d3模拟,过滤器,键盘模型,精确邻域和聚焦传入/传出流程被保留。因此,返回`结构`或聚焦符号会更改任务框架,而不会创建第二个渲染器或下载另一个图表。
```bash
# 从源码的 v2/ 目录开始
npm run build:package
node dist/cli/index.js ui --project my-app
# 或,在 npm link 或全局安装后
cbm-v2 ui --project my-app --port 8080
# 将用户主目录外的仓库添加到控制允许列表
cbm-v2 ui --project my-app --allowed-root /srv/repos /mnt/work
```
打开 `http://127.0.0.1:9749/` 以访问项目选择器,或直接访问 `http://127.0.0.1:9749/?tab=graph&project=my-app` 以访问交互式图表。默认情况下,允许主目录和选定项目的索引根。必须使用 `--allowed-root` 显式授予其他控制选项卡浏览/索引根;路径在包含检查之前规范化。
## Docker
```bash
# 构建
docker build -t cbm-v2 .
# 运行 CLI
docker run --rm cbm-v2 --help
docker run --rm cbm-v2 demo
# 运行 MCP 服务器(挂载缓存卷)
docker run --rm -i -v cbm-cache:/home/node/.cache/codebase-memory-mcp cbm-v2 mcp --project my-app
```
## 文档
使用[文档门户](docs/README.md)选择架构,参考,操作,性能证据或历史的规范来源。主要入口点是:
- [当前产品状态](docs/reference/V2_CURRENT_STATE.md)
- [CLI 参考](docs/reference/CLI_REFERENCE.md)
- [MCP 工具参考](docs/reference/MCP_TOOLS.md)
- [图形界面开发](graph-ui/README.md)
- [贡献](CONTRIBUTING.md)和[维护](MAINTAINERS_GUIDE.md)
## 安全
- **本地优先**:无网络调用,无遥测
- **保留人类注释**:`## 人类注释`部分永远不会被覆盖(回归测试)
- **路径遍历保护**:`obsidian_path`针对`..`和反斜杠进行验证;`assertPathInsideRoot`使用`path.relative`进行跨平台包含
- **发现完整性锁定**:部分发现(子树 EACCES,致命符号链接错误)保留现有图表 — 无静默清除。损坏的符号链接(ENOENT)被视为警告,而不是致命。
- **别名历史记录**(R153):当符号链接别名以前有效且现在损坏时,通过`alias_history`表保留旧规范目标的数据。防止静默历史目标删除。
- **警告传播**(R152+R153):所有发现警告(损坏的符号链接,ELOOP,TOCTOU 竞争)都在`IndexResult.warnings`中显示,带有根相对路径。CLI 打印它们,即使在成功时(`SUCCESS_WITH_WARNINGS`结果)。
- **类型结果**(R153):`IndexResult.outcome`是`SUCCESS` | `SUCCESS_WITH_WARNINGS` | `STALE` | `PARTIAL` | `FAILED`。退出代码:0(成功),1(错误),2(陈旧无错误)。
- **根发现验证**:`assertDiscoveryRoot`在任何 DB 突变之前验证 stat + isDirectory + realpath + readdir
- **备份轮换**:每个注释最多 5 个`.bak`文件
- **干燥运行**:在`obsidian sync`,`obsidian export`,`obsidian import`,`backup import`上可用
- **一致的同步哈希**:`markSynced`为导出和导入方向计算相同的基于 DB 的哈希,使冲突检测可靠(R14 修复)
## 性能
- **消除 N+1 查询**:所有热点路径都使用批量获取(`getBulkNotesByCbmNodeIds`,`getBulkNodeDegrees`,`getBulkEdges`)
- **SQL 级别限制**:`getBulkNotesByCbmNodeIds`使用`ROW_NUMBER() OVER (PARTITION BY ...)`在数据库级别限制每个节点
- **增量索引**:内容哈希 + mtime_ns 快速跳过;仅删除路径避免重新解析未更改的文件
- **并行工作线程**:多线程 WASM 解析,适用于具有 >20 个更改文件的项目
- **稳定的 UI 监听器**:`GraphCanvas`使用 refs 获取回调 — 无监听器在筛选器切换时重新绑定
## 许可证
MIT — 请参阅 [LICENSE](LICENSE)。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器