Eilodon/CALM

GitHub: Eilodon/CALM

CALM 是一个为 AI 编程代理提供实时、编译器验证的代码库调用图谱的 MCP 服务,让代理在编辑前看到完整的依赖关系并强制执行写入安全策略。

Stars: 15 | Forks: 1

# CALM — Coding Agent Liveness Map [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/Eilodon/CALM/actions/workflows/ci.yml) [![npm](https://img.shields.io/npm/v/%40eilodon%2Fcalm-mcp?label=npm)](https://www.npmjs.com/package/@eilodon/calm-mcp) ![Languages](https://img.shields.io/badge/languages-24%20parsed%20%C2%B7%2013%20call--graph%20by%20default%20%C2%B7%2012%20formal--verified-informational) **一张实时且经过图谱验证的代码库地图——让 AI coding agent 可以睁开眼编辑,而不是在黑暗中盲目 grep。** 使用真实的 call graphs,而不是基于向量相似度的猜测。只要有可用的 compiler,就提供经过 compiler 验证的边。在写入路径本身设置了硬性安全闸门,而不仅仅是 agent 可以随意划过的警告。本 README 中的每一个数字都是测量出来的——使用 CALM 自身的工具,针对 CALM 自身的代码库,并由一套可复现的 benchmark 套件提供支持。 **初次接触?** [快速开始](#quick-start) 让你在不到一分钟内运行起来——无需 clone,无需 Rust toolchain,兼容 [Claude Code, VS Code, Cursor, Windsurf/Devin Desktop, Codex, Antigravity 和 JetBrains](#quick-start)。**正在比较此类工具?** 直接跳转到 [证明,而非承诺](#proof-not-promises)。**想了解内部原理?** [`docs/architecture.md`](docs/architecture.md) 全面涵盖了多层 indexing、SCIP/LSP overlay 系统、并发模型和 sanitization 层。 | | | |---|---| | **覆盖率** | 解析 24 种语言 · 13 种语言默认提供完整 call graphs(6 种零配置 + 7 种通过默认的 `tier0-5` bundle) · 12 种语言具备 formal/compiler-verified 的升级路径 | | **安全性** | 在进行 benchmark 的 5 个实时 MCP server 中,唯一*拒绝*对已验证的 hub symbol 进行未确认编辑的 server | | **效率** | 在多文件任务上,比直接读取文件的基线节省 29 倍到 241 倍的 token([benchmark](benchmarks/b4_token_efficiency/)) | ## 问题所在 一个 AI agent 如果在不知道谁调用了它将要修改的 function 的情况下就编辑代码,迟早会: - 删除了其他十几个文件仍在调用的“死代码”。 - 修改了 signature 却漏掉了一半的 call sites。 - 重构了它原以为无足轻重的 symbol——然后在破坏了构建之后才发现,那是整个 module 所依赖的 hub。 这些都不是推理失败,而是*可见性*失败:agent 从未拥有过地图。给它一张地图,猜测就会停止。 ## 为什么叫“CALM” 大多数 coding agent 的工作方式就像任何人初次进入一个陌生代码库且只有 `grep` 时那样:不知道什么和什么相连,不知道触碰这个 function 会不会波及其他十四个 function。这不是自信——这是快速猜测。 CALM 代表 **Coding Agent Liveness Map**。之所以叫 *Liveness*,是因为这张地图从来不是过时的快照——它监控文件系统,随着文件的修改进行增量 reindex,并在每次 response 中报告它当前的新鲜度(`scanning → parsing → building_edges → ready`)。之所以叫 *Map*,因为它是一个真正的图谱——call edges、import edges、hub/coreness 指标——而不是一个假装成图谱的扁平文本索引。交给 agent 一张实时、值得信赖的地形图,它就不会再瞎扑腾了。它变得从容了。 ## 你能得到什么 - **Agent 不再猜测谁依赖谁。** 在修改发布前,`callers`/`callees`/`edit_context` 会显示所有已知的 caller。完整的 tree-sitter call graphs **开箱即用覆盖 13 种语言**:Python、TypeScript、JavaScript、Java、Rust 和 Go 无需配置,另外通过默认的 `tier0-5` grammar bundle 支持 C、C++、C#、Ruby、PHP、Shell 和 R。还有另外 11 种语言(Kotlin、Swift、Scala、Dart、Lua、Elixir、Haskell、OCaml、Zig、PowerShell、Groovy)可以通过选择性的 `--features lang-X` 构建标志进行解析——总共解析 24 种语言(参见 [多层 indexing](docs/architecture.md#multi-tier-indexing))。 - **不会静默破坏事物的编辑。** 每次写入都会在接触磁盘之前,针对确切的行范围进行 hash 验证和语法检查。Hub 和高扇入 symbol 会硬拒绝写入,直到 agent 审查了 callers 并明确确认——这是一项只有拥有真正依赖图的工具才能执行的策略,也是 [CALM 的竞品 benchmark](#benchmarked-against-four-other-live-mcp-servers) 中没有其他 server 执行的策略。 - **每一条边都会告诉你它的可信度。** Call edges 都有 confidence 分级(`textual → inferred → resolved → formal`),并且当你的 compiler 可以复核图谱时,CALM 会要求它进行复核:SCIP overlay(`rust-analyzer`、`scip-go`——包括多模块的 `go.work` 工作区——`scip-python`、`scip-ruby` 等)和实时的 LSP overlay(`gopls`、`clangd`)会将最佳猜测的边升级为 compiler-verified 的真实情况,涵盖 12 种语言,且在未安装 toolchain 的机器上行为完全没有变化。 - **一个能给自己打分的代码库。** `fitness_report` 将 hub 集中度、死代码、复杂度和架构边界违规转化为可查询、可在 CI 中强制执行的信号,而不是一次性的审计——同时 `remember`/`recall` 让决策和陷阱在多个会话之间保持可用。 - **与他人良好协作,并始终留在你的机器上。** 跨进程的编辑锁和单写者 indexing 模型意味着同一个 repo 上的两个编辑器会话不会破坏彼此的写入或进行重复索引——在共享的 daemon 下,会话甚至能看到彼此的到来。没有任何代码会为了 indexing、搜索或编辑而离开你的机器;默认的 embedding 模型在构建时被内嵌到了二进制文件中(运行时零网络),只有在那个内嵌的副本无法使用时,才会进行一次罕见的、可选择退出的回退下载。MIT 许可证。*(另一个可选的例外:使用 `--features otel` 构建并设置 `OTEL_EXPORTER_OTLP_ENDPOINT` 会将 span 属性——文件路径、symbol 名称、工具名称、计时,绝不包含源代码主体——导出到你自己的 collector。默认关闭;参见 [docs/architecture.md](docs/architecture.md#observability-optional) 且仅使用 `https://` collector。)* ## CALM 的定位 “面向 AI agent 的代码智能”现在已经成为一个真正的类别,它是由开源先驱们——Aider、Serena、Sourcegraph/Cody 等——建立起来的,他们证明了 agent 在真正的代码结构下比在 grep 和良好意愿下工作得更好。CALM 建立在这个基础之上,但有着不同的重心:该类别中的大多数工具都在**改善读取路径**——更好的搜索、更好的导航、更好的上下文。CALM 还会**守护写入路径**。同一个图谱在回答“谁调用这个?”的同时,也强制执行“在你查看之前不许修改”:编辑前获取上下文是强制性的,对 hub 的编辑要求基于真实 caller 的明确确认,并且在写入之前都要经过 hash 和语法验证。 权衡说得很清楚:CALM 开箱即用的完整 call-graph 层支持 13 种语言,而不是一些纯 LSP 工具达到的 40 多种——尽管有 24 种语言被解析,且 12 种语言具备 compiler-verified 升级路径,差距比看起来要小。这种权衡换来的是最具 CALM 独特性的部分:confidence 分级的边、硬性的编辑前闸门,以及一个能给自己健康状况打分的代码库——每一项都有你可以自己重现的数字支持([证明,而非承诺](#proof-not-promises))。 ### CALM 适合你吗? **非常适合:** 直接编辑代码(而不仅仅是回答代码相关问题)的 agent · 使用 Tier-0/Tier-0.5 语言的单 repo 代码库 · 针对同一 repo 运行多个 MCP client 的项目(参见下方的[支持的 client](#quick-start))· 不想依赖 embedding API 的本地优先用户。 **目前不适合:** 多 repo/跨 repo 的企业级搜索——专门为这种规模构建的工具(包括 Sourcegraph/Cody)会更好地为你服务 · CALM 目前 24 种 tree-sitter 集合中完全没有的语言。 ## 快速开始 **支持的 client** — CALM 兼容任何使用 stdio 通信的 MCP client;以下是目前已接入或记录的 client: | Client | 模式 | 最快安装方式 | |---|---|---| | **Claude Code** | CLI · Web · IDE | `claude mcp add --transport stdio calm -- npx -y @eilodon/calm-mcp serve` | | **VS Code** | IDE(原生 MCP / Copilot Agent 模式) | `code --add-mcp '{"name":"calm","command":"npx","args":["-y","@eilodon/calm-mcp","serve"]}'` | | **Cursor** | IDE · 云端(Background Agent) | [添加到 Cursor →](cursor://anysphere.cursor-deeplink/mcp/install?name=calm&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBlaWxvZG9uL2NhbG0tbWNwIiwic2VydmUiXX0=) | | **Windsurf / Devin Desktop** | IDE · 云端 | 编辑 `~/.codeium/windsurf/mcp_config.json` | | **Codex** (OpenAI) | CLI · IDE | `codex mcp add calm -- npx -y @eilodon/calm-mcp serve` | | **Antigravity** (Google) | CLI · IDE | 编辑 `~/.gemini/config/mcp_config.json` | | **JetBrains AI Assistant** | IDE | 通过 UI 设置 | 以上每个 client 的完整操作指南,包括需要全局配置的 client 的确切代码片段——[`docs/mcp-client-setup.md`](docs/mcp-client-setup.md)。如果在 stdio 转发无法触达的 devcontainer/Codespace 中运行?请参阅 [`docs/http-transport.md`](docs/http-transport.md)(高级用法,仅限远程开发,可选启用,默认回环)。 **在你自己的项目中使用 CALM** — 无需 clone,无需 Rust toolchain: ``` { "mcpServers": { "calm": { "command": "npx", "args": ["-y", "@eilodon/calm-mcp", "serve"] } } } ``` 将其放入项目根目录下的 `.mcp.json`(Claude Code/Cursor)或 `.vscode/mcp.json`(VS Code 使用顶层的 `"servers"` 键而不是 `"mcpServers"`,其余格式相同)。如果是在 Claude Code 中使用插件:`/plugin marketplace add Eilodon/CALM` 然后 `/plugin install calm@CALM`。 更喜欢原生二进制文件而不是 npx?`curl -fsSL https://raw.githubusercontent.com/Eilodon/CALM/main/scripts/install.sh | sh`,然后从你的项目内部运行 `calm setup`——它会自动写入相同的 MCP 配置,并指向你刚安装的二进制文件。添加 `calm setup --npx` 则会写入可移植的 `npx` 条目(可共享/可提交——团队成员和 CI 不需要二进制文件,且它会跟踪已发布的 release)。 **开发 CALM 本身**(本仓库): ``` # 1. 构建 binary cargo build --release -p calm-cli # 2. 为你的项目初始化 config calm init --project-root . # 3. 构建 index(如果 config.json 中启用了 semantic search,也会 embed symbols) calm index --project-root . # 4. 通过 stdio 运行 MCP server — 如果 index 已经存在,incremental reindex 会自动启动 calm serve --project-root . ``` 本仓库附带了适用于 Claude Code (`.mcp.json`)、Cursor (`.cursor/mcp.json`) 和 VS Code (`.vscode/mcp.json`) 的现成配置——这三者都指向 `scripts/mcp-launcher.sh`,这是一个共享的启动器,它会寻找已经构建好的二进制文件,如果你处于匹配的 git tag 上则下载经过 checksum 验证的预编译 release,或者在什么都不可用时从源码构建。克隆仓库后即可直接使用——不需要首先进行手动构建步骤。 ## 示例:agent 的实际工作流 ``` agent: repo_overview() → 237 files, 3,583 symbols, indexing_phase=ready agent: "I need to change getUserByEmail" → locate("getUserByEmail") # find the file + symbol metadata → source("getUserByEmail") # read just the function body, not the whole file → edit_context("getUserByEmail") # MANDATORY before any edit → 12 callers, risk_assessment=high → agent reviews each caller before touching the signature → edit_symbol("getUserByEmail", expected_hash=..., new_text=...) → risk_assessment=high, is_hub=true, no confirm:true → refused, with an explanation → edit_symbol(..., confirm=true, reason="checked getUserByToken, still returns the same shape") # reason must cite a real caller edit_context returned — writes for real, reindexes immediately → diff_impact(staged=true) # verifies blast radius before commit ``` ## 证明,而非承诺 以下每个数字都是通过将 CALM 自身的 `fitness_report`/`repo_overview` 指向它自己的代码库来测量的——可以在刚克隆的代码库上用同样的两次工具调用复现: | 指标 | 测量值 | |---|---| | 已索引的代码库 | **237 个文件,3,583 个 symbol**——仅此 repo 中就存在 15 种语言 | | Hub 集中度 (`hub_pct`) | 7.6% — 174 个 hub symbol(闸门:≤ 20%) | | 死代码率 (`dead_code_pct`,感知覆盖率) | 5.6%(闸门:≤ 10%) | | Edge 覆盖率 (`edge_coverage_pct`) | 70.1% 的 symbol 至少有一条 call edge(闸门:≥ 60%) | | 高复杂度 function (`high_complexity_pct`) | 2.8%(闸门:≤ 15%) | | 架构契合度 (`avg_distance`, Martin/OOD) | 距离主序列的平均距离为 0.27(闸门:≤ 1.00) | | 不明确的 symbol 边界 (`boundaryambiguous_count`) | 0(闸门:≤ 0) | | 架构边界违规 (`boundary_violations`) | 0(闸门:≤ 0)——此处之前标记的 `watcher → tools` import 已通过将其所需的共享 `RwLockExt`/`LockExt` trait 从 `tools/common.rs` 迁移到它们自己的 `sync_ext` 模块中来修复 | | 相比直接读取文件基线的 Token 效率 | `source` **241 倍** · `edit_context` **193 倍** · `locate` **29 倍** · `callers` **1.0 倍** —— 四项 benchmark 任务中的中位数为 111 倍([方法论](benchmarks/b4_token_efficiency/)) | | 完整测试套件(默认 features) | 见下方的[测试](#testing) |
竞品 benchmark 方法论及各语言注意事项 ### 与另外四个实时 MCP server 进行了 benchmark `benchmarks/b11_extended_competitor_ab/` 安装并调用了四个成熟的开源代码智能 MCP server——CodeGraph、Semble、grepai 和 Serena——针对本 repo 的一个独立 git worktree,每个任务重复 5 次,并为每个任务配备了正确性验证机制。目标不是为了排名;而是为了用真实的、运行中的现有技术来检验 CALM 的声明,而不是看营销页面。 运行结果显示:CALM 在 caller 召回率和爆炸半径任务上取得了最佳结果,并且是这五个 server 中唯一一个其编辑前安全闸门真正*拒绝*了高风险、未确认编辑的 server,而不仅仅是事后能够描述风险。并不是所有的数字都很讨喜:在一项 token 效率任务中,CALM 的压缩比是五个中最低的——那里的正确性也保持在顶峰,该数字按实测结果发布。这就是本项目一贯的 benchmark 策略:不讨喜的结果与好结果一同发布([benchmarks/README.md](benchmarks/README.md))。完整的方法论、每一项任务以及原始的各工具数据都在 benchmark 的专属 README 中。 ### 语言覆盖率,是测量出来的而不是断言的 `benchmarks/resolution/` 在 19 种新添加的或 Tier-0.5 语言中运行了层级分布的 baseline(resolved / inferred / textual / ambiguous 的划分——没有 oracle,每种语言一个真实的 OSS repo),按原样报告:Kotlin (89.6%) 和 OCaml (86.3%) 由于常见的方法短名冲突,大多落入 `ambiguous` 层级;Dart 生成了 symbol,但没有生成 call edges——这是该 tree-sitter grammar 的已知限制,而不是 bug;Tier-2 类型推断目前仅为最初的 Tier-0 语言接入了。完整的各语言表格见 benchmark 的专属 README。
## CALM 的工作原理 完整的技术细节位于 [`docs/architecture.md`](docs/architecture.md) 中——包括为什么每次 response 都包含 `suggested_next` 以及为什么高风险步骤是硬性拦截而不仅仅是建议背后的设计哲学。分节摘要: - **[多层 indexing](docs/architecture.md#multi-tier-indexing)** — 13 种语言默认提供完整的 call graphs,另有 11 种语言可通过选配的 grammar feature 进行解析,总计 24 种。 - **[你可以真正信任的 call graph](docs/architecture.md#a-call-graph-you-can-actually-trust)** — 每一条边都按置信度(`resolved`/`inferred`/`formal`/`textual`)进行标记;SCIP 和 LSP overlay 会将边升级为跨越 12 种语言的 compiler 级真实情况。 - **[能够真正找到东西的搜索](docs/architecture.md#search-that-actually-finds-things)** — 通过 Reciprocal Rank Fusion 融合的 FTS5 + 语义 embedding,外加直接从磁盘读取的真实 grep/glob,用于查找 indexer 从未解析的文件。 - **[具备实际安全网的编辑](docs/architecture.md#editing-with-an-actual-safety-net)** — 经过 hash 验证的写入、在任何操作触及磁盘前的语法验证,以及针对 hub/高风险 symbol 的三部分闸门(新鲜的 `edit_context`、`confirm:true`、有理有据的 `reason`)。 - **[并发与可靠性](docs/architecture.md#concurrency--reliability)** — 一个共享的 daemon、跨进程编辑锁和单实例 indexing 锁,意味着同一个 repo 上的多个编辑器会话不会破坏或重复工作。 - **[自我评分的代码库](docs/architecture.md#the-codebase-grading-itself)** — 10 项健康指标、感知覆盖率的死代码检测、声明的架构边界、文档漂移检测。 - **[具有记忆且知道何时陷入困境的 agent](docs/architecture.md#an-agent-that-remembers-and-knows-when-its-stuck)** — 持久的跨会话笔记、git 协同变更挖掘、陷入死循环的信号。 - **[默认安全](docs/architecture.md#safe-by-default)** — 对每次工具 response 都进行凭据/prompt injection 脱敏,默认仅限本地。 ## Crate 布局 - `crates/calm-core/` — index 引擎:`tree-sitter` 解析、SQLite schema、多层 resolver(保守推断 → inferred → formal/Stack-Graphs、SCIP 或 LSP)、图算法(coreness、hub 检测)、FTS5/语义搜索、分析(hotspots、覆盖率、代码所有者、diff-impact、死代码)、健康指标、gitignore 管理。 - `crates/calm-server/` — MCP server(基于 stdio 或 unix-socket daemon 的 `rmcp`),公开 30 个工具以及增量文件监控器。 - `crates/calm-cli/` — CLI:`calm init`、`calm index`、`calm serve`、`calm connect`、`calm setup`、`calm fitness-check`、`calm doctor`。 ## CLI 参考 ``` calm init --project-root . # writes .calm/config.json with defaults calm index --project-root . # one-shot full index (Scanning → Parsing → BuildingEdges → Ready) # also embeds symbols+chunks if semantic_search.enabled=true calm serve --project-root . # MCP server over stdio + incremental reindex + file watcher calm serve --project-root . --listen unix:/path/to/daemon.sock # run as a shared daemon (opt-in) calm connect --project-root . # lightweight forwarder to an already-running daemon (opt-in, Unix) calm serve --project-root /project --db-path /data/index.db # separate DB path (container deployment) calm serve --project-root . --preset orient # register only the "orient" phase's tools calm doctor --project-root . # validates config, DB (symbols/files/metrics history), git calm setup --project-root . # writes/merges MCP config (.mcp.json/.cursor/.vscode) pointing at this binary calm fitness-check --project-root . # CI gate, exits 1 on failure calm fitness-check --project-root . --json # JSON output calm fitness-check --project-root . --config thresholds.toml # custom thresholds calm scip-run --project-root . --lang go # force one SCIP provider to run now, bypassing refresh policy calm scip-run --project-root . # --lang omitted = run every provider ("rust,go,python,javascript,java,csharp,php,ruby,c") calm index --project-root . --scip-file build/index.scip --sub-root services/api # ingest a pre-built SCIP index (CI/sandboxed, no external indexer install needed) ``` ## 面向 AI agent 的 30 个 MCP 工具 CLI preset 通过工作流阶段过滤工具:`orient`、`trace`、`edit`、`compound`、`full`(默认),可以通过 `calm serve --preset` 或 `config.json` 中的 `preset` 字段配置——或者从工具集(模块)名称中组合自定义集合,例如 `--preset "trace,security"` 或 `--preset "full,-edit"`(完整的工具集列表见 AGENTS.md)。每个 response 都包含 `suggested_next` 指向下一步——关于每个工具的详细信息和完整工作流位于 [AGENTS.md](AGENTS.md)。 | 分组 | 工具 | |---|---| | Orient | `repo_overview`、`hotspots`、`fitness_report`(健康快照——与 `calm fitness-check` 指标相同,可在会话期间查询)、`indexing_status`、`test_gap_hotspots`(按 coreness × 死代码/测试覆盖率置信度对 symbol 进行排名——即编写测试投资回报率最高的地方) | | Locate | `locate`、`search`、`file_overview` | | Inspect | `source`、`symbol_info`、`understand`、`symbols_batch`(一次往返获取多个确切 `qualified_name` 的源代码及 callers/callees) | | Trace | `callers`、`callees`(有序、有上限、在 hub symbol 上可被 etag 缓存)、`path`、`dependencies` | | Edit | `edit_context`(在任何编辑之前是强制性的)、`edit_lines`/`edit_symbol`(用于任意内容的唯一写入工具——经过 hash 验证;除非本次会话针对该确切 symbol 运行过 `edit_context`,传递了 `confirm:true`,并且 `reason` 引用了 `edit_context` 返回的真实 caller,否则对 hub/高风险的触碰将被拒绝)、`format_files`(仅通过 stdin 执行 rustfmt——绝不使用位置文件参数,因此它无法触发 rustfmt 自身的 crate 级别 `mod`-tree 发现并重新格式化其自身 `paths` 列表之外的文件;因为没有语义改变所以不需要 confirm/edit_context 闸门)、`pattern_debt_register`/`pattern_debt_status`(通过 `search(kind="similar")` 按 qualified_name 锚定重复的 bug 模式,稍后重新检查 `open`/`resolved`/`anchor_lost`)、`diff_impact`(提交前强制执行)—— `edit_context` 和 `diff_impact` 在 Claude Code 下是 hook 强制执行的(参见 `.claude/hooks/calm-nudge.sh`);`session_context` 中的 `pending_diff_impact` 是任何其他 MCP client 上的等效信号 | | Recover | `session_context`、`remember`、`recall` | | Advanced | `scip_refresh`、`lsp_refresh` —— 强制一个或所有 SCIP/LSP provider 立即运行,绕过自动刷新策略。`scan_text` —— 对*你提供的任何文本*(WebFetch/WebSearch 结果、子 agent 的报告、粘贴的内容)运行 `source`/`understand` 所使用的相同 prompt 注入/凭据启发式算法——完全本地离线,独立于任何托管的 LLM 安全分类器。`set_toolset` —— 在运行时缩小或重置*当前会话*公开的工具,无需重启 server(安全底线——orient+guardrails+recover+edit——将始终保留)。以上四项:仅限 `full` preset,不包含在上述四个工作流阶段 preset 中——这是刻意的、供手动/罕见使用的逃生舱,而不是默认流程中的步骤 | ### MCP Prompts — 封装为 slash-command 的工作流 不同于上面的 `tools` —— MCP Prompts (`prompts/list`、`prompts/get`) 为你经常重复的工作流返回一条现成的指令信息;MCP client 会将它们显示为 slash-command: | Prompt | 参数 | 封装的工作流 | |---|---|---| | `review_symbol` | `symbol` | `locate` → `source` → `edit_context`(强制) → 在修改任何内容之前进行风险总结 | | `debug_symbol` | `symbol` | `understand` → `callers(max_depth=3)` → 检查 `test_files`/`dead_code_confidence` | | `onboard_area` | `path` | `repo_overview` → 限定于该路径的 `file_overview`/`dependencies` → `hotspots` | | `review_pr` | `range` | `diff_impact(commits=range)` → `hotspots`(重叠检查) → `fitness_report` → 合并前的总体风险总结 | | `calm_workflow` | *(无)* | 面向完整 Stage 1-8 工具流的无参数导航——适用于从不自动加载 AGENTS.md 的 client,或会话中途的复习 | ## 健康检查 — CI 闸门 在每次 push/PR 时,都会在 `.github/workflows/ci.yml` 的 `fitness-check` 作业中实际运行——首先运行 `calm index`(新检出还没有 `.calm/index.db`),然后运行 `calm fitness-check --project-root . --config thresholds.toml`。这里的 `--config` 标志不是可选的:如果没有它,`[[boundaries]]` 和 `[config_drift]` 将被静默视为“未声明任何规则”而不是抛出错误——只有数字阈值才具有真正的默认值。 `calm fitness-check` 根据在 `thresholds.toml` 中声明的阈值测量 11 项指标: | 指标 | 测量内容 | 默认阈值 | |---|---|---| | `hub_count` | 被归类为 hub 的 symbol 计数 | ≤ 1000 | | `hub_pct` | hub symbol 占 symbol 总数的百分比(尺度不变) | ≤ 20.0% | | `avg_coreness` | 整个图的平均 k-core coreness | ≤ 15.0 | | `dead_code_pct` | 具有“高”死代码置信度的 symbol 百分比 | ≤ 10% | | `hotspot_risk` | 代码库中最高的 hotspot 得分 | ≤ 0.75 | | `edge_coverage_pct` | 至少有一条 call edge 的 symbol 百分比 | ≥ 60% | | `high_complexity_pct` | McCabe 圈复杂度 > 10 的 function/method 百分比(基于 AST;Tier-0.5 语言始终报告为 1) | ≤ 15.0% | | `avg_distance` | Martin/OOD 距离主序列的平均距离——每个文件的抽象程度与其不稳定性(Ca/Ce)所暗示的理想状态之间的差距 | ≤ 1.00 | | `boundary_violations` | 违反声明的 `[[boundaries]]` 规则的 `import_edges` 计数 | ≤ 0 | | `boundary_ambiguous_count` | 具有不明确行边界(与邻居共享)的 symbol 计数——在解决之前,对这些 symbol 的 `edit_symbol` 替换将被拒绝 | ≤ 0 | | `config_drift_count` | 指向不存在的实际路径的文档文件路径引用(通过 `[config_drift].doc_paths` 声明)计数 | ≤ 0 | 每次 `calm fitness-check` 运行也都会将指标快照保存到 DB 中, `edit_context` 显示趋势(与前一天的差值)。 ### 架构边界 — `[[boundaries]]` 直接在 `thresholds.toml`(与 `[thresholds]` 相同的文件)中声明“module A 不得 import module B”,通过路径前缀匹配(不是 glob/regex)。请注意,这适用于 Rust 自身的 crate/module 边界*尚未*强制执行的情况——声明“calm-core 不得 import calm-server”将是一个空操作,因为 Cargo 的依赖图在结构上已经使其成为不可能: ``` [[boundaries]] from = "crates/calm-core/src/indexer/" to = "crates/calm-core/src/analysis/" reason = "indexer (extraction) must stay upstream of analysis (dead-code, hotspots, fitness) — not the other way around" ``` `calm fitness-check` 会在 `--json` 模式之外具体报告每一次违规(真实的起始/目标路径、规则和原因);默认的 `max_boundary_violations = 0` 意味着你特意声明的规则是你真正遵守的规则。 本仓库自身的 `thresholds.toml` 目前声明了两个:上面那个,以及 `crates/calm-server/src/watcher.rs` → `crates/calm-server/src/tools/`(“后台重新索引/监控循环不得依赖于独立于其运行的 MCP 工具处理层”)——两者均保持为 0 违规。 ## 部署 - `cargo build --release` → 通过 `.github/workflows/release.yml` 构建静态(Linux 上为 musl)二进制文件,具有 5 个目标的矩阵,带有 `SHA256SUMS` + 为每个 asset 提供构建来源证明:`x86_64-unknown-linux-musl`、`aarch64-unknown-linux-musl`、`aarch64-apple-darwin`、`x86_64-apple-darwin`、`x86_64-pc-windows-msvc`。当检出处于(或你正在安装)匹配的 git tag 时,`scripts/mcp-launcher.sh`/`scripts/install.sh` 会自动下载并 checksum 验证正确平台的构建。 - `Containerfile`,多阶段构建(`rust:alpine` → `scratch`)——一个单一的静态二进制文件,不需要运行时镜像,在每次 git tag 推送时发布到 `ghcr.io/eilodon/calm-mcp`(按版本 + `latest` 标记)。 - `compose.yaml` 提供了一个经过强化的示例(`read_only`、`cap_drop: ALL`、`no-new-privileges`、`pids_limit: 64`、`mem_limit: 256m`)。 - 默认 embedding 模型的权重通过 `include_bytes!` 内嵌到二进制文件中——`build.rs::ensure_embedding_weights` 从 Hugging Face Hub 获取 `crates/calm-core/assets/potion-code-16m/*.safetensors` 并在*编译*时校验一次,因此正常的 `cargo build`/release 二进制文件在运行时加载它时实现零网络 I/O。不涉及 Git LFS(repo 不包含任何 LFS 内容)。
如果构建时获取失败(离线构建等)会怎样 `cargo build` 仍然能够**成功编译**——`build.rs` 会写入一个小的占位符 stub 来代替真实的权重,而不是使构建失败。在**运行时**加载该 stub 会失败(“failed to parse safetensors”),因此 `Embedder::load` 会自动回退到从 Hugging Face Hub 一次性下载相同的模型(之后缓存在本地,受 `semantic_search.allow_network_fallback` 控制)。如果该回退被禁用或同样不可用,`indexing_status` 将报告 `embeddings_status: "failed"`,并且 `search(kind="semantic"/"hybrid")` 将降级为仅限 FTS——不会崩溃,只是直到模型可用并且你重新构建或重新运行之前没有语义搜索。
## 测试 ``` cargo test --workspace # unit + integration (embeddings is a default feature, included) cargo test --test parity_test test_formal_edges # Stack Graphs regression corpus ``` 每个 PR 都会运行八个 CI 作业:`verify`(fmt/clippy/test/audit)、`stack-graphs-corpus`(formal-resolver 一致性)、`embeddings`(包含 `embeddings` feature 的 clippy + 测试)、`no-stack-graphs-formal`(关闭 `stack-graphs-formal` 的 clippy + 测试——这是该 feature gate 编译成的 `resolver::formal` stub 的唯一 CI 覆盖)、`all-languages`(涵盖所有 24 种已解析语言的 fixture-repo indexing,外加 `lsp-overlay`)、`js-client-interop`(与真实的 JS MCP SDK client 交叉检查工具 schema,而不仅仅是 Rust 自身的)、`otel-http-features`(包含 `otel`/`http` feature 的 clippy + 测试,外加防止 `opentelemetry` 核心版本偏移的守卫)、`fitness-check`(针对此 repo 自身的 index 运行 `calm fitness-check`——见下方的[健康检查](#fitness-check--the-ci-gate))。 完整的工作区套件——1,000 多项测试——通过检查,只有少数 `#[ignore]` 标记的实时二进制集成测试(如 `rust-analyzer`/`scip-go`/`scip-java`)需要未在所有环境中安装的外部工具。 ## 延伸阅读 - [`docs/architecture.md`](docs/architecture.md) — 完整的技术深入剖析:多层 indexing、SCIP/LSP overlay、搜索内部机制、编辑安全网、并发、自我评分、记忆、sanitization,以及这一切背后的设计哲学。 - [`docs/comparison.md`](docs/comparison.md) — 基于方法论的定位文章,与其他此类工具的对比。 - [`docs/what-external-users-get.md`](docs/what-external-users-get.md) — `npx`/npm/MCP-Registry 安装给你的确切内容,与本 repo 自身的开发检出有何不同:安装/分发机制、完整的工具和工具集分解、编辑安全层、语言覆盖率,以及永远不会在外部发布的内容。 - [`docs/`](docs/) — resolver 内部机制、迁移计划,以及上面 `docs/architecture.md` 未涵盖的其他设计说明。 - [`docs/adr/`](docs/adr/) — 单独的架构决策记录(Stack Graphs 范围、formal-resolver 方法、LSP 可选的置信度升级、daemon+forwarder 并发模型)。 - [`docs/mcp-client-setup.md`](docs/mcp-client-setup.md) — 每个 MCP client 安装路径的详细信息,包括 Windsurf/Devin Desktop 和 Codex 全局配置。 - [`docs/http-transport.md`](docs/http-transport.md) — 可选的远程/HTTP transport(`calm serve --http`):默认回环、故障关闭的 `--allow-remote` + token 要求、为什么远程暴露会强制使用只读 preset,以及对 TLS/反向代理的期望。 - [`AGENTS.md`](AGENTS.md) — 本项目自身 agent 所遵循的逐工具工作流指南。 - [`benchmarks/`](benchmarks/) — 本 README 中每一个数字背后的测量套件,以及更多内容:`b2_call_graph_quality/`(与 SCIP oracle 的精确度/召回率)、`b3_search_quality/`(混合 RRF vs. 纯 FTS vs. 原始 grep,NDCG@10)、`b4_token_efficiency/`(对比直接 baseline 的 token 成本,按任务划分)、`b6_tool_call_efficiency/`(往返:原始多次调用 vs. 一次 MCP 调用)、`b7_task_correctness/`(跨 6 种语言语料库 fd/Rust、flask/Python、express/JS、zod/TS、gin/Go、spring-petclinic/Java 的真实重命名重构——由独立的通过/失败 oracle 检查,而非 LLM 裁判)、`b11_extended_competitor_ab/`(对 4 个其他活跃 MCP server 的真实调用,而非自我报告的数字)、`b12_tier1_tier2_tool_correctness/`(通过 JSON-RPC 在 6 个外部 OSS repo 上实时驱动 9 个工具,以 regex/`git grep` 作为真实依据)、`resolution/`(跨 19 个真实 OSS repo 的层级分布 baseline,每种语言一个)。不讨喜的结果有意与好结果一同发布——`benchmarks/README.md` 陈述了该策略。 ## 许可证 [MIT](LICENSE)
标签:AI编程助手, SOC Prime, 云安全监控, 代码图谱, 可视化界面, 开发工具, 暗色界面, 模型上下文协议, 通知系统, 静态分析