| name | improve-codebase-architecture |
| description | 扫描代码库寻找可深化的机会,以可视化 HTML 报告呈现,然后针对你选定的那个进行拷问。 |
| disable-model-invocation | true |
Improve Codebase Architecture
浮现出架构上的摩擦点,并提出可深化的机会——把浅模块变成深模块的重构。目标是可测试性与 AI 可导航性。
本命令受项目领域模型的启发,并建立在一套共享的设计词汇之上:
- 运行
/codebase-design 技能以获取架构词汇(模块、接口、深度、接缝、适配器、杠杆、局部性)及其原则(删除测试、"接口即测试面"、"一个适配器 = 假想接缝,两个 = 真实接缝")。在每一条建议中都精确使用这些术语——不要漂移到"组件"、"服务"、"API"或"边界"。
CONTEXT.md 中的领域语言为好的接缝命名;docs/adr/ 中的 ADR 记录了本命令不应重新翻案的决策。
流程
1. 探索
先界定范围再扫描——YAGNI。 深化一个模块的回报在于让它未来的改动更容易,所以要对代码库中近期发生变化的部分给予额外的权重。在动手看之前先决定看哪里:
- 如果用户指定了方向——某个模块、某个子系统、某个痛点——就采纳它,并跳过下面的推断。
- 否则,回溯足够长的一段提交历史(
git log --oneline)来找出代码库的热点——那些反复出现的文件和区域——让这些路径首先吸引你的注意力。如果改动分散、没有明显热点,就把网撒得更大。
先阅读项目的领域术语表(CONTEXT.md)以及你所触及区域内的任何 ADR。
然后使用 Agent 工具(subagent_type=Explore)来遍历代码库。不要遵循僵硬的启发式规则——有机地探索,并记下你在哪里感到摩擦:
- 在哪里,理解一个概念需要在许多小模块之间来回跳转?
- 在哪里,模块是浅的——接口几乎和实现一样复杂?
- 在哪里,纯函数仅仅为了可测试性而被抽取出来,但真正的 bug 藏在它们被调用的方式里(没有局部性)?
- 在哪里,紧耦合的模块跨接缝泄漏?
- 代码库的哪些部分未经测试,或难以通过其当前接口进行测试?
对任何你怀疑是浅的东西施加删除测试:删掉它会集中复杂度,还是只是把复杂度挪个地方?"是,会集中"就是你想要的信号。
2. 以 HTML 报告呈现候选项
写一个自包含的 HTML 文件到操作系统临时目录,这样什么都不会落进仓库。从 $TMPDIR 解析临时目录,回退到 /tmp(Windows 上为 %TEMP%),并写入 <tmpdir>/architecture-review-<timestamp>.html,让每次运行都得到一个全新文件。为用户打开它——Linux 上用 xdg-open <path>,macOS 上用 open <path>,Windows 上用 start <path>——并告诉他们绝对路径。
报告使用 Tailwind(经 CDN) 做布局与样式,在图/流程/时序能可靠传达结构的地方使用 Mermaid(经 CDN) 画图。把 Mermaid 与手工打造的 CSS/SVG 视觉元素混用——当关系呈图状(调用图、依赖、时序)时用 Mermaid,当你想要更具编辑感的东西(质量图、剖面图、坍缩动画)时用手工构建的 div/SVG。每个候选项都配一张前后对比可视化。要有视觉表现力。
为每个候选项渲染一张卡片,包含:
- 文件(Files)——涉及哪些文件/模块
- 问题(Problem)——为什么当前架构造成摩擦
- 方案(Solution)——用平实的语言描述会改变什么
- 收益(Benefits)——以局部性和杠杆的角度解释,以及测试将如何改善
- 前 / 后示意图——并排、定制绘制,展现浅薄之处与深化之处
- 推荐强度——
Strong、Worth exploring、Speculative 之一,渲染为一个徽章
在报告结尾以一个 Top recommendation(首要推荐) 小节收束:你会先着手哪个候选项,以及为什么。
领域方面使用 CONTEXT.md 的词汇,架构方面使用 /codebase-design 的词汇。 如果 CONTEXT.md 定义了"Order",就谈"Order 接收模块"——而不是"FooBarHandler",也不是"Order 服务"。
ADR 冲突:如果某个候选项与既有 ADR 相矛盾,只有当摩擦真实到足以值得重新审视该 ADR 时才把它浮现出来。在卡片中明确标注(例如一个警告标注框:"与 ADR-0007 相矛盾——但值得重启,因为……")。不要罗列某条 ADR 所禁止的每一个理论上的重构。
关于完整的 HTML 脚手架、图表模式和样式指南,见 HTML-REPORT.md。
现在还不要提出接口。文件写好后,问用户:"你想探索这些当中的哪一个?"
3. 拷问循环
一旦用户选定一个候选项,运行 /grilling 技能与他们一起走过决策树——约束、依赖、深化后模块的形态、接缝之后是什么、哪些测试得以存活。
副作用在决策逐渐结晶时就地发生——一边推进一边运行 /domain-modeling 技能让领域模型保持最新:
- 要用一个不在
CONTEXT.md 中的概念来命名深化后的模块? 把该术语加进 CONTEXT.md。如果文件不存在就惰性创建它。
- 在对话中打磨了一个模糊的术语? 就地更新
CONTEXT.md。
- 用户以一个起支撑作用的理由否决了候选项? 提议记一条 ADR,措辞如:"要我把这个记为一条 ADR,好让未来的架构评审不再重新建议它吗?" 只有当这个理由确实会被未来的探索者用来避免重复建议同一件事时才提议——跳过一时性的理由("现在不值得")和不言自明的理由。
- 想为深化后的模块探索备选接口? 运行
/codebase-design 技能,使用它的"设计两遍"并行子 agent 模式。