--- name: improve-codebase-architecture description: 扫描代码库中接口复杂、职责分散或边界不清的位置,生成可视化 HTML 审查报告,再与用户深入讨论选中的改进项。 disable-model-invocation: true --- # 架构审查 找出架构上的问题点,提出**加深模块的机会**:把浅模块重构为深模块。目标是提高可测性,并让 AI 更容易理解和定位代码。 本命令以项目的领域模型为依据,并使用一套共享的设计术语: - 使用 `codebase-design` skill 获取架构术语(**模块**、**接口**、**深度**、**接缝**、**适配器**、**杠杆**、**局部性**)及其原则(删除测试、“接口就是测试面”、“有两个适配器时接缝才真实存在”)。描述模块设计时一致地使用这些术语;组件、服务、API、边界等词只在符合其原义时使用,不用来替代这些术语。 - `CONTEXT.md` 中的领域语言用于为接缝命名;`docs/adr/` 中的 ADR 记录了本命令不应重新争论的决定。 ## 过程 ### 1. 探索 **先确定范围,再扫描(YAGNI)。** 加深模块的回报在于以后修改它更容易,所以优先关注代码库中最近经常变化的部分。开始查看之前,先决定*看哪里*: - 用户指定了方向(某个模块、子系统或痛点)时,按用户的方向进行,跳过下面的推断。 - 否则,查看较长一段提交历史(`git log --oneline`),找出代码库的热点:反复被修改的文件和区域,优先关注这些路径。改动分散、没有明显热点时,扩大范围。 先阅读项目的术语表(`CONTEXT.md`)和涉及区域的 ADR。 然后派一个子代理遍历代码库。不必套用固定的启发式规则,根据实际情况探索,记录哪里让理解或修改变得困难: - 理解一个概念时,是否需要在很多小模块之间来回跳转? - 哪些模块是**浅**的,接口几乎和实现一样复杂? - 哪里为了可测性抽出了纯函数,但真正的 bug 出在它们的调用方式上(缺少**局部性**)? - 哪些紧耦合的模块跨过接缝泄漏了实现细节? - 代码库中哪些部分没有测试,或者很难通过当前接口测试? - 最近的 bug 修复中,是否有因为找不到合适的接缝而没能编写回归测试的情况? - 是否有业务模块 import 其他业务模块的内部代码,或直接读写其他业务模块的数据? - 哪些业务本身很简单,却套上了仓储、服务、DTO 映射等多层抽象?判断标准见 `codebase-design` skill 的 [BUSINESS-MODULES.md](../codebase-design/BUSINESS-MODULES.md)。 对怀疑是浅模块的代码做**删除测试**:设想删除它,复杂性是集中到一处,还是只是换了个位置?“集中到一处”就是你要找的信号。 ### 2. 用 HTML 报告展示候选项 在操作系统临时目录中写一个自包含的 HTML 文件,不在仓库中留下任何内容。临时目录优先使用 `$TMPDIR`,否则使用 `/tmp`(Windows 使用 `%TEMP%`)。文件路径为 `<临时目录>/architecture-review-<时间戳>.html`,每次运行生成新文件。替用户打开它(Linux 用 `xdg-open <路径>`,macOS 用 `open <路径>`,Windows 用 `start <路径>`),并告诉用户绝对路径。 报告使用 **CDN 引入的 Tailwind** 实现布局和样式。在流程图、时序图能准确表达结构的地方,使用 **CDN 引入的 Mermaid** 绘图。Mermaid 与手写 CSS 或 SVG 图示结合使用:图状关系(调用图、依赖关系、时序)用 Mermaid;需要更强表现力的示意(体量图、剖面图、调用折叠图)用手写 div 或 SVG。每个候选项都有一张**改造前后对比图**。以图示为主。 每个候选项渲染成一张卡片: - **文件**:涉及哪些文件或模块 - **问题**:当前架构为什么让理解或修改变得困难 - **方案**:用平实的语言描述会改变什么 - **收益**:用局部性和杠杆解释收益,并说明测试会如何改善 - **改造前后对比图**:并排展示、针对该候选项绘制,说明浅在哪里、如何加深 - **推荐强度**:`强烈推荐`、`值得探索`、`推测性` 之一,渲染为徽章 报告有一节**已排除项**:列出探索阶段发现过、但没有做成候选卡片的 2-5 处(例如某个浅模块、某段紧耦合),每条写清是被哪条标准挡下的——杠杆太低、属于已有 ADR 排除的范围、影响面太局部不值得开专门候选等。这一节不是可选的:它是报告说服力的来源,证明候选项是筛过一圈之后留下的,而不是探索时看到什么就报什么。找不到值得一提的排除项时,说明探索范围本身较窄,而不是省略这一节。 报告最后是**首要推荐**一节:说明你会先处理哪个候选项,以及原因。 **领域概念使用 `CONTEXT.md` 的词汇,架构概念使用 `codebase-design` 的术语。** 如果 `CONTEXT.md` 定义了“订单”,就写“订单录入模块”,而不是“FooBarHandler”;只有它确实是一个独立部署的服务时,才写“订单服务”。 **与 ADR 冲突**:只有当问题真实到值得重新审视某条 ADR 时,才提出与之矛盾的候选项。在卡片中清楚标注(例如用一个警告框:_“与 ADR-0007 矛盾,但值得重新讨论,因为……”_)。不需要逐一列出被 ADR 排除的理论性重构。 完整的 HTML 骨架、图示方式和样式说明见 [HTML-REPORT.md](HTML-REPORT.md)。 这一步只展示候选项,接口设计留到第 3 步。文件写好后询问用户:“你想深入讨论哪一个?” ### 3. 追问循环 用户选中一个候选项后,使用 `grilling` skill 与用户逐项确认相关决策:约束、依赖、加深后模块的结构、接缝后面隐藏什么、哪些测试可以保留。 决策确定时,就地更新相关文档;使用 `domain-modeling` skill 保持领域模型为最新: - **为加深后的模块取了一个 `CONTEXT.md` 中没有的概念名?** 把术语加入 `CONTEXT.md`。文件不存在时按需创建。 - **对话中澄清了一个模糊的术语?** 立即更新 `CONTEXT.md`。 - **用户基于关键理由否决了候选项?** 提议写 ADR,例如:_“要不要把这个理由记录成 ADR,避免以后的架构审查再次提出同样的建议?”_ 只有未来的审查确实需要这个理由来避免重复建议时才提议;暂时性的理由(“现在不值得做”)和不言自明的理由不需要记录。 - **想为加深后的模块探索备选接口?** 使用 `codebase-design` skill 中的“设计两次”并行子代理模式。 追问达成共识后,告诉用户:要实现这项改进,运行 `/to-spec` 进入主流程。