作者分享了用 Agent 分析 Dependabot PR 的流程,检查上游差异、所有权变化、安装脚本、依赖关系及安全公告,再提出合并、暂缓或拒绝建议。人工决定后执行操作,并将调查文档转为 ADR,补丁版本也接受完整审查。
karasu 是一种用于系统架构的文本建模语言,灵感来自 C4 model。你在 .krs 文件中描述系统,karasu 负责绘制系统、部署和团队结构等视图。我没有手写过它的代码,所有代码都通过 Claude Code 完成。
这是第二篇每周更新,涵盖 10 月 10 日至 17 日合并的变更。这次先聊聊我在使用 Agent 开发过程中学到的东西,再逐一介绍交付了哪些功能,以及每项变更带来的经验。
先看本周数字:合并了 88 个 PR,其中 16 个来自 Dependabot;以 ADR(架构决策记录)的形式记录了 12 项决策。10 月 15 日,我发布了四个包:karasu 0.9.0、@karasu-tools/core 0.4.0、karasu-vscode 0.4.0 和 karasu-skills 0.2.0。上周文章介绍的 .krs 语言 v2.0,也随这次发布登陆了 npm 和 Visual Studio Code Marketplace。
Dependabot 分诊通过 hane 的一个 skill 运行。 karasu 不会在 Dependabot PR 提交后直接合并。分诊使用的是 hane 中的 dependabot skill;hane 是我单独开发的一个 skill 集合。它是一个 Claude Code plugin,打包了从 karasu 开发过程中逐渐积累起来的 skills。
运行 /hane:dependabot 后,Agent 会依次执行以下步骤:
收集所有尚未关闭的 Dependabot PR。
追溯每个 PR 的上游信息:release notes、两个 tag 之间的代码 diff、发布者或仓库所有权的变化、安装时执行的脚本、lockfile 中的依赖关系、已知安全通告,以及该版本发布至今的时间。
将调查结果写入设计文档,为每个 PR 给出建议:合并、暂缓或拒绝。
等我作出决定后,合并或关闭这些 PR,再将设计文档转为 ADR。
这个 skill 不会因为是补丁版本就跳过调查。把被篡改的版本包装成补丁,是供应链攻击最容易蒙混过关的方式。它也绝不会自动合并;每次都由人作出决定。由于设计文档和 ADR 都保留在仓库中,我可以追溯任何一个版本是在什么时候、出于什么原因被引入的。
skill 本身只保留适用于所有仓库的步骤。karasu 专属的规则放在 karasu 仓库自己的规则文件中,即 .claude/rules/dependabot.md。例如,7 天冷静期,以及当 Dependabot 自己的 diff 无法保证正确时,什么情况下应通过替代 PR 引入更新。本周我用这套组合进行了三轮分诊。
这三轮操作让我学到了两件事。
第一件事与开放 PR 数量上限有关。本周有 24 项 npm 更新过了冷静期,但上限是 8,因此它们分成三批提交。每一批都需要单独分诊,所以我把上限提高到了 25。PR 总数没有变化,改变的只是同时开放的数量。
第二件事是,重新生成 lockfile 可能会让依赖偏离你已经审查过的版本。一个替代 PR 重新生成 lockfile 时,knip 被解析为刚过冷静期的 6.41.0,而不是已经审查过的 6.40.0。我将它重新固定在 6.40.0,并把这次经验记录进 ADR。
我对 CodeRabbit 提出的 261 条审查意见进行了分类。 karasu 的 PR 由 CodeRabbit 审查。我把它在 8 月 20 日至 10 月 10 日期间,针对 Markdown 文件留下的全部 261 条讨论都做了分类。结果发现,大约一半确实是缺陷。因此,文档仍然需要接受审查。
在其余意见中,有两类误报反复出现。它们都源于 CodeRabbit 所读取的规则文本的措辞。例如,一条规则写着“不要在设计文档中放入里程碑列表”,结果它被应用到了设计文档模板明确要求填写的实施步骤上。这条规则原本只针对 slice-plan 表格。因此,我修改了规则文本,明确其适用范围,而没有修改 CodeRabbit 配置。这样一来,即使人脱离上下文读到这句话,也更不容易误解。
从 npm 安装的 karasu serve 无法工作,却没有任何测试发现。
在 0.8.0 的 npm 包中,karasu serve 对所有请求都返回 "App not built"。tarball 中只有 5 个文件,没有预览应用。serve 按相对于 monorepo 的路径查找应用,所以在仓库内部能用,从 npm 安装后就失效了。换句话说,README 里的 npx --yes karasu@latest serve . 在 monorepo 之外从来就没正常工作过。我是在一个外部仓库中尝试 reverse-architecture skill 时发现这个问题的。
修复方式是将仅供 serve 使用的应用构建产物放入 dist/app/,随包一起发布。新增的 CI 步骤会用 pnpm pack 打包 CLI,解开 tarball,再从解包后的产物启动 serve。我确认过:只要从包的文件列表中移除 dist/app/,这项测试就会失败。只有实际运行打包产物的测试,才能发现这类 bug。
打包进去的应用有 16MB,共 97 个文件,其中大部分来自 Monaco editor。serve 只显示预览,从来不会打开编辑器。因此,现在 serve 构建有了独立入口,而且只要 bundle 中出现任何 Monaco 模块,构建就会失败。我故意把 Monaco import 加了回来,以验证这道检查:构建确实失败,并列出了 1,233 个模块。现在 serve 应用只有 1.7MB,共 4 个文件。发布的 0.9.0 包解压后为 3.3MB,共 12 个文件。
0.9.0 到第三次运行发布流程时才成功发布。npm Trusted Publisher 的两个坑阻止了 karasu-skills 发布。Trusted Publisher 是 npm 的一项设置,允许 GitHub Actions 无需 token 即可发布。karasu 0.9.0 依赖 karasu-skills 0.2.0,因此也被卡住了。
E404: 新注册的配置处于 "not yet validated" 状态,如果 2 天内没有通过该配置成功发布一次,就会过期。我在手动发布 0.1.0 后,立即注册了 karasu-skills 的配置。发布流程使用 changeset publish,它会跳过 npm 上已经存在的版本,因此 0.1.0 永远无法用来验证这份配置。等到发布 0.2.0 时,配置已经过期了。
E403: 2026 年 9 月 3 日之后创建的配置,默认只允许 npm stage publish。发布工作流运行的是 npm publish,因此必须勾选 "Allow npm publish"。
现在,发布文档要求在合并提升包版本号的 release PR 之前,再注册这份配置。
本周继续改进了连线路由,目标是解决连线直接穿过卡片、没有绕行的问题。
同一行卡片之间的连线。 过去,这些连线会直接穿过中间的所有卡片。现在,它们会通过该行上方或下方的通道绕行。系统会选择与现有连线交叉次数更少的一侧。
连接侧列的连线。 在 Dify 模型的两个视图中,Gateway 的三条出入连线在每个视图里都穿过了 7 张卡片。现在,它们沿着侧列旁的空隙向下走线。
此外,还合并了三项较小的修复。通道内的走线现在会根据各条连线向上还是向下转弯来排序。原本在同一通道内折返的路径会合并成一段。在下钻视图中,走线和标签会保持在当前聚焦的边框内。
每项修复都在从开源项目逆向建模得到的真实模型上进行衡量。主要测试集包括 Umami、Dify、Twenty 和 WordPress,总计 1,542 个视图。每项修复都会跟踪两个数字:消除了多少处问题,以及作为副作用改变了多少个视图。
对于侧列连线的修复,还有一种方案会清出更宽的通道。但它会改变 13 个视图,所以我选择了改动较小的方案。
交叉标记现在会随连线一起变暗。 鼠标悬停在卡片或连线上时,无关连线会变暗。但过去,连线交叉处绘制的小弧线(“hops”)和计数标记仍然保持明亮,依旧勾勒出那些已经变暗的连线形状。现在,这些标记会随所属连线一起变暗。为此,上周合并成一个 <path> 的 hops 又被拆开了,每条连线对应一个 <path>。在 Dify 模型中,输出体积增加了 4.29%,hop 的 <path> 元素从 757 个增加到了 2,585 个。最大视图的渲染时间基本不变:修改前为 33.3 ms,修改后为 33.5 ms。过去不响应鼠标的连线,例如部署视图中的连线,现在也会响应悬停了。
同名节点不再混淆。 Shop 内部的 Api(Shop.Api)与一个名为 "Shop.Api" 的顶层服务,过去会共用同一个内部 key。现在,所有节点和连线的标识 key 都由同一个不会产生冲突的辅助函数生成。当两个系统声明了相同 ID 的节点时,过去不同的内部 map 会各自选中不同的节点;现在它们遵循统一规则。
karasu diff 现在可以正确比较多个系统。 比较模式过去只会对第一个系统执行 diff。添加或删除第一个系统后,它就会拿两个不同的系统进行比较,导致没有变化的卡片也被显示为删除和新增。现在,系统按 ID 配对,不再按位置配对。
小修复。 样式表中的 label-offset: -20px 过去会丢失负号,表现得像 20px。karasu render <directory> 过去会报 "File not found";现在会读取该目录下的 index.krs。
e2e 测试发现了两个真实 bug。 本周新增了大量 Playwright 端到端测试,所有测试都已启用,没有任何测试仍被 test.skip 跳过。在这个过程中,它们发现了两个 jsdom 单元测试无法察觉的 bug。目前都还没有修复。第一个:在编辑器中输入时,Ctrl/Cmd+B 等快捷键仍会触发。Monaco 的输入目标变成了一个既不是 contenteditable、也不是 textarea 的元素,因此“用户是否正在输入”的检查没能识别它。第二个:在部署视图或矩阵打开时重新加载页面,会退回系统视图。
将 Visual Studio Code 扩展作为每周预发布版本交付的设计已经合并,接下来开始实现。
已有一个 Issue,用于将 npm 发布迁移到 Trusted Publisher 下的 staged publishing。
已有一个 epic,计划让公共图库也能供运营者之外的人使用。目前运营者只有我。
网站:karasu.kompiro.dev
如需采取进一步措施,可以考虑屏蔽此人和/或举报滥用行为。