
我开源了 Canary一条命令检查项目把 CI 错误搬进可交互的架构地图CI 红了真正耗时间的往往是红灯之后。你打开日志翻过几十屏输出找到一条报错再去源码里确认位置。修复后重新跑测试还得判断这次通过的检查和刚才失败的检查是不是同一批报告对应的代码有没有变哪些分支根本没有被执行检查工具越来越多但这些信息经常散落在终端、测试报告、覆盖率页面和 GitHub Actions 之间。于是我开源了Canary一个把项目检查、架构地图、覆盖率和错误证据连接起来的项目验证工作台。一条命令开始检查从失败进入代码让每一次修复有据可查。项目地址https://github.com/EVEDensity/Canary01一条命令让已有检查进入同一个工作台不少开发者都有这样一套命令构建、类型检查、lint、格式检查、测试。换一个项目脚本名称和包管理器又可能不同。Canary 可以自动发现项目已有的检查入口并统一执行、记录和输出结果。canary run--ci默认自动发现模式无需创建 Canary 配置文件。安装后在项目目录或其子目录运行即可也可以直接指定项目canary run--ci--project/path/to/project目前支持的自动发现包括Node.js 项目构建、类型检查、lint、格式检查和测试脚本并识别项目声明的包管理器Python 项目标准 pytest / unittest 测试入口Go 项目go vet与go testRust 项目cargo check与cargo test项目自身的依赖、语言运行时和测试服务准备好后Canary 就能组织已有检查。对于复杂检查、超时、覆盖采集或自定义执行环境也提供显式配置入口。这类常规检查通过自动化执行不需要调用模型也不消耗模型 Token。02让失败拥有“空间位置”二维地图 三维分层一个错误文件名和一张能逐层探索的项目地图带来的理解体验完全不同。启动报告页面canary run--port4318--no-open打开http://127.0.0.1:4318就能在检查结果之外进入项目结构工作区。Canary 提供二维结构视图和可切换的三维分层视图支持逐层浏览、节点搜索、依赖过滤、上下游聚焦和源码片段查看。TypeScript / JavaScript 可以深入到函数和类其他语言先展示可用的目录、文件等结构层级。你可以从项目全局进入模块再进入目录、文件和具体符号。用户定义的架构分层也可以用来组织地图例如界面层、业务层、数据层。三维视图让层级关系更容易看懂二维视图适合精确查看依赖和定位代码。地图展示的是项目结构与有依据的关系静态依赖不会被包装成真实运行时调用。它可以成为理解陌生项目的入口也可以成为失败排查的导航工具。03覆盖率终于可以“点进去”了一个覆盖率百分比能说明测量范围里的代码执行情况却很难直接告诉你下一步该看哪里。Canary 把实际采集到的行、函数和分支覆盖关联到结构节点。你可以从覆盖率指标进入地图找到薄弱文件再下钻到未覆盖分支和对应源码位置。地图提供覆盖、失败和变更三种颜色模式并保留固定图例。不同含义不会混在一起未覆盖区域当前测量范围里的验证缺口失败节点本次运行已有错误证据变更节点相对 Git 基线发生变化的位置文件和分支保留各自的测量分母未采集或无法可靠映射的部分显示为未知。支持的采集路径包括 V8 和 Istanbul具体精度由采集与映射方式决定。这里有一个我很看重的设计原则未覆盖表示验证缺口失败表示已有错误证据。代码被执行过也不等于业务行为已经被充分验证。这个区分让可视化有了实际意义用户知道哪些地方已经发现问题哪些地方还需要补充验证。04历史结果要和历史代码一起看一个容易被忽视的问题是源码已经修改了昨天的报告还能用今天的代码来解释吗Canary 为运行产物保留 manifest、内容哈希和运行谱系把代码版本、检查计划、结果和历史记录关联起来。架构地图读取该次运行封存的结构快照。展示源码时会核对内容哈希必要时尝试读取记录的 Git 提交并再次确认匹配。无法确认时页面会明确提示而不是拿当前代码补上旧报告。这带来一个很实用的能力你看到的不只是“曾经失败”还能追溯“在哪个版本、哪次运行、哪份证据中失败”。内容哈希用于检测产物内容是否变化它与运行身份、版本关联共同构成可核查的记录并不等同于第三方签名认证。05把验证结果直接带进 GitHub PR如果结果只存在一个额外页面里开发者还需要主动打开它。因此Canary 已提供可复用的 GitHub Action把验证结果带到现有 PR 工作流中简洁的检查摘要展示通过、失败、阻塞或证据不足结果绑定实际执行的提交版本对可靠的源码位置生成 annotations链接到诊断报告和可下载的证据产物只需contents: read不创建重复 PR 评论对常规 npm 项目可以这样接入其他项目将依赖准备步骤换成自己的命令即可name:Canaryon:[push,pull_request]permissions:contents:readjobs:verify:runs-on:ubuntu-latesttimeout-minutes:20steps:-uses:actions/checkoutv4with:ref:${{github.event.pull_request.head.sha||github.sha}}persist-credentials:false-uses:actions/setup-nodev4with:node-version:24-run:npm ci-uses:EVEDensity/Canary/.github/actions/verifymainwith:project:.生产工作流建议把 Action 固定到审核过的 commit。Fork PR 采用只读检查流程不注入发布凭据验证与部署保持独立。准确的位置才标注未知的位置就保留未知。报告中的堆栈位置是排查入口不能直接等同于已经证明的根因。这部分已经有真实 CI 证据集成 fixture 执行一个故意失败的断言验证失败退出码、封存证据和源码标注报告准确指向failure.mjs第 3 行。详情可查看 R17 集成验证运行 与 对应修正 PR。06Canary 的前瞻性体现在哪里我认为它最值得关注的地方是把开发者排查问题时需要的信息连接成了同一条路径检查结果 → 项目结构 → 源码位置 → 错误证据 → 关联重跑与比较从“报表展示”走向“问题导航”架构地图、覆盖率和日志共享同一份运行上下文。看见问题之后可以继续进入对应模块和证据减少在多个工具之间反复找线索。从“测试全绿”走向“知道验证了什么”它保留测量分母、未知状态和版本绑定让通过的结果有明确范围。这为后续的变更验证打下了基础不仅关注检查是否通过也关注这次修改到底得到了哪些验证。从“孤立记录”走向“可追溯验证”manifest、哈希、结构快照和运行谱系让历史报告能够与历史代码对应。对需要复盘错误、审查修复和协作维护的项目这是一项实实在在的工程能力。让人和自动化工具读到同一套证据开发者通过页面下钻CI 通过稳定退出码和标准报告集成自动化工具可以消费结构化数据。JSON、JUnit、Markdown 报告以及已有的 MCP 接口为进一步集成保留了入口。这是一条有前瞻性的产品路线让 CI 的结果成为可探索、可解释、可追溯的开发资产。这些判断有已实现的功能作为依据至于排查时间能降低多少还需要在更多真实项目中持续测量。07快速体验准备Node.js 24 和 Git执行对应系统的安装命令。Windows / PowerShelliwr-useb https://raw.githubusercontent.com/EVEDensity/Canary/main/scripts/install/install.ps1|iexmacOS / Linuxcurl-fsSLhttps://raw.githubusercontent.com/EVEDensity/Canary/main/scripts/install/install.sh|bash安装完成后新开一个终端在已经准备好依赖的项目中执行canary run--ci需要交互式报告时canary run--port4318--no-open检查和报告产物保存在目标项目的.canary/目录请将它加入.gitignore。自动发现适合快速接入有自定义流程时再按需添加配置。08为什么叫 CanaryCanary 是金丝雀。这个名字源于矿井中的早期预警信号在危险扩大之前先发现异常。软件开发也需要这样的信号。一次失败检查、一个没有走到的分支、一条不符合预期的依赖都可能是值得提前关注的线索。早发现早检测让问题更容易定位让修复更值得信任。09接下来把修复验证做得更深入现有版本已经具备项目检查、交互式地图、覆盖联动、错误证据和 PR 集成。后续路线会继续围绕实际开发流程展开更完整的版本化复现与隔离执行修复前后的回归验证识别测试删除、跳过或验证条件削弱将变更与执行覆盖、断言和项目显式契约关联这些是接下来的建设方向。目标很清楚让开发者更快看懂失败也更有依据地判断修复是否成立。最后欢迎拿你的真实项目试一试如果你维护一个需要反复构建、测试和排查失败的项目或者接手了一个结构复杂、缺少清晰导航的代码库欢迎体验 Canary。项目采用Apache-2.0开源许可证提供中英文界面与文档。欢迎提交使用反馈、功能建议和代码贡献。GitHubEVEDensity / Canary中文介绍README.cn.md使用文档Canary Docs如果这个方向对你有帮助欢迎给项目一个Star也欢迎通过 Issue 告诉我你最希望从哪一次 CI 失败开始少走几步弯路。