关于 coverctl
coverctl 是面向编码 Agent 的覆盖率策略命令行工具和 MCP 服务,支持 15 种语言。它按代码域执行覆盖率门槛,并在编辑过程中返回结构化结果,帮助在提交前发现问题。
主要功能
- 01支持 15 种语言的覆盖率检查
- 02按代码域执行覆盖率门槛
- 03提供覆盖缺口和门槛建议
- 04覆盖率配置文件、趋势与对比
- 05输入和输出净化
适用场景
- 01在提交前发现覆盖率回退
- 02查找未覆盖文件并安排修复优先级
- 03跟踪多次记录之间的覆盖率变化
MCP 相关
MCP 服务在 Agent 模式下提供 `check`、`suggest` 和 `debt` 工具,CI 模式另提供六种工具。它还提供覆盖债务、趋势、建议和检测到的配置等只读资源。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
coverctl
适用于各种语言的 Agent 循环覆盖率治理——在提交前由 AI 编码 Agent 调用的覆盖率工具,而不是 CI 结束后才查看的仪表板。
支持 Python、TypeScript/JavaScript、Java、Rust、Go、C#、C/C++、PHP、Ruby、Swift、Dart、Scala、Elixir 和 Shell——一个 .coverctl.yaml,一个 MCP 接口。它不是 Go 覆盖率工具。
开始使用 ↓ · 语言 ↓ · 使用效果 ↓ · MCP 工具 ↓ · CLI 参考 ↓ · 存在的意义 ↓ · 社区 ↓
“我们的 AI Agent 能快速交付代码,但在编辑时看不到覆盖率策略。我们只能等到 CI 中断后才发现问题,那时上下文已经丢失,同一个 Agent 又只能猜着修复。”
所有语言使用相同的策略模型:自动检测运行器,将路径归入各个域,并在提交前执行最低要求。模拟(mock)密集或特殊的目录布局可能需要在 .coverctl.yaml 中显式配置 domains: 区块。
coverctl 不是 Go 覆盖率 CLI:它通过各语言的原生覆盖率运行器提供策略和 MCP(与 go test -cover / pytest --cov 的比较)。
开始使用
brew install klarlabs-studio/tap/coverctl
接入 Claude Code(~/.config/claude-code/mcp.json):
{
"mcpServers": {
"coverctl": {
"command": "coverctl",
"args": ["mcp", "serve"]
}
}
}
向 Agent 提问:“运行 coverctl check,告诉我哪些域的覆盖率下降了。”
关于 Cursor / Cline / Claude Desktop / Aider / Continue / OpenCode 及其他 MCP 客户端,请参阅 docs/src/content/docs/mcp.mdx。所有支持 MCP 的客户端都能使用;coverctl mcp serve 默认以 Agent 模式运行(3 个工具:check、suggest、debt)。使用 --mode=ci 可启用完整的九工具接口。
端到端验证安装:
coverctl mcp doctor # PASS/FAIL per step with remediation
Agent 循环中的使用效果
为便于阅读而渲染——你的客户端可能会以不同方式显示工具调用。
You: Add the email-validation feature to the api domain.
Claude: I'll add EmailValidator + tests under src/api/.
[edits: src/api/email.ts, src/api/email.test.ts]
Tool call → coverctl check
Result → passed: false; failing: api (78.2%, required 80%)
uncovered: src/api/email.ts:42-58 (error paths)
Tool call → coverctl suggest api
Result → uncovered files: email.ts (16 lines), retry.ts (4 lines)
Two error branches in EmailValidator.validate are uncovered.
I'll add cases for empty-input and malformed-domain so api meets
the 80% threshold before we commit.
过去要等 8 分钟后才会在 CI 中出现的回归,现在能在同一轮 Agent 调用中修复。
Agent 擅长的事: 原样读取 check 输出,调用 suggest 查找未覆盖的文件,调用 debt 找出成本最低的修复项,再次运行 check 进行确认。
需要留意: Agent 可能会降低 .coverctl.yaml 中的阈值来“修复”失败(这并非真正的修复)。Agent 可能会在没有再次调用 check 的情况下声称覆盖率有所提升(这是幻觉)。Agent 可能会忽略拒绝响应中的 error_code,并使用相同的输入重试。
coverctl 会返回确定性的结构化信号;Agent 的修复仍需人工审阅。完整契约请参阅 docs/src/content/docs/mcp.mdx。
为何要构建
AI 编码 Agent 编写代码时看不到覆盖率。它们修改代码,你提交,然后几分钟或几小时后回归问题才在 CI 中暴露——届时已来不及在同一会话中调整方向。仪表板(Codecov、Coveralls)和原始语言测试运行器(go test -cover、pytest --cov、nyc)面向的是事后查看数据的人类,而不是在编辑过程中执行策略的 Agent。
coverctl 专为 Agent 工作循环打造(并非 Go 覆盖率工具的替代品):
- 在提交前捕获回归问题。 在 Agent 编辑的当前轮次中提供覆盖率反馈,而不是等到 CI 失败几分钟后。核心指标是在提交前捕获的回归问题。
- 可通过 MCP 调用。 支持 MCP——这一多厂商 Agent 工具标准目前由 Anthropic、OpenAI、Google、Microsoft 和 AWS 共同治理。可与所有现有的 MCP 兼容客户端配合使用;未来推出的兼容产品也无需修改即可使用。
- 多语言治理,统一配置。 一份
.coverctl.yaml即可在 15 种语言中强制执行各领域的阈值。在 Go 仓库中,它可以像在其他场景调用pytest一样调用go test,然后应用相同的领域策略。Agent 会接触任何语言;覆盖率治理也必须如此。 - 本地优先。 源代码永远不会离开你的机器。Agent 通过标准输入/输出调用 coverctl,而不是通过 SaaS API。无需账户、无需上传,Agent 可触及的范围内也没有第三方依赖。
- 经过加固的 MCP 接口。 输入和输出净化机制可防御通过测试运行器标志和覆盖率配置文件中的恶意文件名实施的提示词注入(Lethal Trifecta)。
CLI 和 MCP 服务采用 Apache-2.0 许可证,并始终免费。路线图中包含一个用于跨仓库覆盖率历史记录的托管层(见 docs/strategy/monetization-decision.md)——这是附加功能,而非付费墙。
MCP 工具
Agent 模式会公布三种工具(check、suggest、debt),以便 Agent 可靠地选择工具。CI 模式(--mode=ci)则会增加其余工具。
| 工具 | 模式 | 用途 |
|---|---|---|
check | agent + ci | 运行带覆盖率的测试并执行策略。返回各领域的通过/失败状态、文件和警告。 |
suggest | agent + ci | 推荐阈值(current / aggressive / conservative)。 |
debt | agent + ci | 按领域统计覆盖率缺口,列出投入精力的方向并排序。 |
init | ci | 自动检测项目结构,并创建包含领域策略的 .coverctl.yaml。 |
report | ci | 分析现有覆盖率配置文件,无需运行测试。 |
record | ci | 将当前覆盖率记录到历史数据中,以跟踪趋势。 |
compare | ci | 对比两个覆盖率配置文件。返回差异、覆盖率改善或退步的文件,以及领域变化。 |
badge | ci | 生成 SVG 覆盖率徽章。 |
pr-comment | ci | 将覆盖率报告发布到 GitHub / GitLab / Bitbucket PR。 |
MCP 资源(只读上下文)
| URI | 内容 |
|---|---|
coverctl://debt | JSON 格式的覆盖率债务。 |
coverctl://trend | 已记录历史数据的趋势。 |
coverctl://suggest | 阈值建议。 |
coverctl://config | 检测到的项目配置。 |
安全边界
根据 Lethal Trifecta 威胁模型,coverctl 将两个方向的 MCP 流量都视为不可信。
- 输入边界。 Agent 模式接受类型化能力(
packages、tags、race、short、run、timeout),并拒绝任意 runnertestArgs,以防 coverctl 被用作通用命令执行 MCP 服务。危险标志(--rootdir、--cov-config、-D、-I、--require、--init-script、--node-options,……)也会被拒绝,作为纵深防御。Agent 模式无法选择其他策略文件、将检查筛选为部分域、缩小coverageScope(缩小测量范围可能会隐藏未测试的域)、通过fromProfile跳过测试运行,或使用增量检查(空差异会自动通过);仓库的.coverctl.yaml是权威配置,验证必须针对完整策略执行测试。拒绝响应使用包含error_code和便于 Agent 采取行动的remediation的稳定架构。从人工终端发起的 CLI 调用不会经过清理;此时人类就是信任边界。 - 输出边界。 返回给 Agent 的用户可控标识符(覆盖率配置文件中的文件名、域名、包路径)会进行百分比编码,而非破坏性替换,因此不同名称仍保持区分(
src/über.go不会与另一个文件混为一谈)。控制字符、反引号和 Markdown 元字符无法被渲染成指令。这样可以防止恶意 PR 或攻击者命名的测试文件通过往返流程进行提示词注入。
coverctl 以本地优先为设计原则。默认安装不会传输任何内容——无遥测、无分析数据,也无源代码数据。选择启用的 --mcp-telemetry 标志会将结构化工具调用事件输出到 stderr,供希望为自己的流水线添加监测的用户使用(格式详见 docs/design/mcp-metrics-spec.md)。对抗性和正常路径评估(internal/eval/scenarios/ 下的 85 个以上场景)会以拒绝架构完整性和提示词注入防护作为每次发布的门槛。
规范性意图:docs/strategy/system-intent.md。 完整威胁模型与剩余风险:docs/security/mcp-threat-model.md。
CLI 参考
CLI 是 MCP 服务背后的基础层;人类也可以直接使用。
| 命令 | 用途 |
|---|---|
init / i | 交互式向导,自动检测语言和域。CI 中可使用 --no-interactive。 |
check / c | 运行覆盖率检查并强制执行策略。使用 -o json 输出机器可读内容,或使用 --fail-under N、--ratchet、--from-profile。 |
run / r | 生成覆盖率产物,不评估策略。 |
watch / w | 开发期间在文件变更时重新运行覆盖率检查。 |
report | 评估现有配置文件。可使用 -o html、--uncovered、--diff <ref>、--merge <profile>。 |
detect | 自动检测域并写入配置。使用 --dry-run 预览。 |
badge | SVG 覆盖率徽章。可使用 --style flat-square。 |
compare | 比较两个配置文件的差异。 |
debt | 覆盖率债务报告。 |
trend | 根据记录的历史数据生成覆盖率趋势。 |
record | 将当前覆盖率追加到历史记录。CI 中可使用 --commit、--branch。 |
suggest | 提供阈值建议。使用 --write-config 应用。 |
pr-comment | 将覆盖率发布到 GitHub/GitLab/Bitbucket PR。 |
ignore | 显示已配置的排除项和已跟踪的域。 |
mcp serve | 启动 MCP 服务(stdio)。可使用 --mode=agent|ci|auto。 |
mcp doctor | 首次运行验证:逐步显示 PASS/FAIL,并提供补救措施。 |
survey | Sean Ellis 的 40% PMF 提示词;追加到 ~/.coverctl/survey.jsonl。 |
全局标志:-q/--quiet、--no-color、--ci(组合 quiet 与 GitHub Actions 注释)。
测试执行标志
check、run、record 接受转发给底层测试运行器的工具链标志:
| 标志 | 示例 |
|---|---|
--tags | --tags integration,e2e |
--race | (Go 竞态检测器) |
--short | 跳过耗时较长的测试 |
-v | 详细的测试输出 |
--run | --run TestFoo |
--timeout | --timeout 30m |
--test-arg | 可重复使用:--test-arg=-count=1 --test-arg=-parallel=4 |
--language / -l | 覆盖自动检测结果:python、javascript、typescript、java、rust、go、csharp、cpp、php、ruby、swift、dart、scala、elixir、shell |
终端流程(不使用 Agent)
如果你更愿意直接运行 coverctl:
coverctl init # auto-detect language + domains, write .coverctl.yaml
coverctl check # enforce policy; exit 1 on violation
coverctl suggest --strategy current
coverctl record
如果某一步失败:coverctl detect --dry-run 可预览 init 输出;coverctl check -o json 可显示结构化的失败详情;在 CI 中,coverctl record --commit "$(git rev-parse HEAD)" --branch "$(git rev-parse --abbrev-ref HEAD)" 可显式提供元数据。
配置
.coverctl.yaml(架构:schemas/coverctl.schema.json):
域是命名的路径组,而不是语言包。对于大多数语言,match 使用路径 glob(src/auth/**);如果项目使用 Go,则使用 Go 包路径(./internal/auth/...):
version: 1
policy:
default:
min: 75
domains:
- name: auth
match: ["src/auth/**"] # Go equivalent: ["./internal/auth/..."]
min: 90 # critical path — stricter
- name: api
match: ["src/api/**"]
min: 80
- name: utils
match: ["src/utils/**"]
# falls back to default min: 75
exclude:
- "**/generated/**"
按域执行策略才是关键:整体覆盖率会掩盖关键路径上的回归。coverctl 会根据每个域各自的最低要求进行评估,若任何域未达标,就会使构建失败。各语言的入门示例:文档快速入门。与原生运行器的区别:与原生覆盖率的比较。
仅适用于 Go 的注释:为什么数字可能与直接运行 go test ./... 得出的不同
在 Go 项目中,coverctl 可能会传入覆盖已配置域的 -coverpkg,因此某个包也可以因其他包的测试对其进行测试而获得覆盖率。直接运行 go test ./... 只会将包自身的测试计入覆盖率——两种数字都合理;coverctl 得出的数字通常更高。这是 Go 运行器的行为,并非产品模型。比较历史数据时,建议使用 coverctl check 配置文件。--from-profile 会报告所提供配置文件测得的数据。
高级用法
files:
- match: ["internal/core/*.go"]
min: 90 # per-file overrides
diff:
enabled: true
base: origin/main # only enforce on changed files
integration:
enabled: true # Go 1.20+ GOCOVERDIR integration tests
packages: ["./internal/integration/..."]
cover_dir: ".cover/integration"
profile: ".cover/integration.out"
merge:
profiles: [".cover/unit.out", ".cover/integration.out"]
annotations:
enabled: true # // coverctl:ignore, // coverctl:domain=NAME
多包单体仓库?使用 extends: 继承策略。可从以下内容开始:复制 templates/coverctl.yaml。
支持的语言
一款产品支持 15 种语言。coverctl 会自动检测要调用的运行器;路径域只需定义一次。
| 语言 | 格式 | 检测标记 |
|---|---|---|
| Python | Cobertura、LCOV | pyproject.toml、setup.py、requirements.txt |
| TypeScript / JavaScript | LCOV | tsconfig.json、package.json |
| Java / Kotlin | JaCoCo、Cobertura | pom.xml、build.gradle |
| Rust | LCOV(cargo-llvm-cov) | Cargo.toml |
| Go | 原生覆盖率配置文件 | go.mod、go.sum |
| C# / .NET | Cobertura(coverlet) | *.csproj、*.sln |
| C / C++ | LCOV(gcov/lcov) | CMakeLists.txt、meson.build |
| PHP | Cobertura(PHPUnit) | composer.json、phpunit.xml |
| Ruby | LCOV(SimpleCov) | Gemfile、Rakefile |
| Swift | LCOV(llvm-cov) | Package.swift |
| Dart | LCOV(dart test) | pubspec.yaml |
| Scala | Cobertura(scoverage) | build.sbt |
| Elixir | LCOV(mix test) | mix.exs |
| Shell | Cobertura(kcov) | *.bats |
各语言的配置示例:文档快速入门。
GitHub Action
jobs:
coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version: "1.25"
- uses: ./.github/actions/coverctl
with:
command: check
config: .coverctl.yaml
output: text
面向平台和开发者体验团队
需要在许多多语言代码仓库中统一覆盖率策略?coverctl 附带安全和采购审查所需的文档:
- MCP 威胁模型 — 输入和输出边界控制、提示词注入防御、残余风险。
- 拒绝响应架构参考 — 稳定的
error_code+remediation契约,助力 Agent 恢复。 - GTM 漏斗指标规范 — 埋点内容以及遥测如何保持为可选项。
考虑在整个组织范围内采用 coverctl?请创建一个带有 platform-evaluation 标签的 GitHub issue — 我们很乐意介绍架构和信任边界。
社区
- Claude Code 插件市场 — 通过
/plugin install直接安装coverctl。 - MCP Registry — 已在 registry.modelcontextprotocol.io 上列出。
- GitHub 讨论区 — go.klarlabs.de/coverctl/discussions。
- 赞助 coverctl 开发 — github.com/sponsors/felixgeelhaar。
使用 coverctl 几周了吗?运行 coverctl survey 分享 PMF 反馈(默认仅在本地运行;除非你选择加入,否则不会传输任何内容)。
由 Felix Geelhaar 与多语言 AI 编码社区的贡献者共同开发。
贡献
- TDD:行为变更前先编写测试。
- 满足
.coverctl.yaml中每个领域的min(未设置时默认为 80%)。本仓库使用 Go,因此请运行go run ./cmd/coverctl check进行内部试用(它只负责执行策略,并不能替代阅读go test的失败信息)。 - 使用 Conventional Commits(
feat:、fix:、chore:等),以支持 Relicta 的版本递增逻辑。 main受保护;CI 通过(.github/workflows/go.yml+.github/workflows/eval.yml)后,通过 PR 合并。- 推送前运行
gofmt -w和golangci-lint v2。
贡献者可查阅架构详情:ARCHITECTURE.md。
发布
由 Relicta 管理。请勿手动推送 v* 标签。
安全
披露政策请参阅 SECURITY.md。MCP 输入清理(internal/mcp/sanitize.go)和输出规范化(internal/mcp/sanitize_output.go)是防御提示词注入引发的参数和内容攻击的主要措施;如发现可绕过之处,请私下报告。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。