关于 setup-solid
setup-solid 是面向代码仓库的技能,用于在项目指引中加入 SOLID 架构规则。它先检查代码结构、现有规范和架构决策,再起草或更新单个章节供用户确认。
主要功能
- 01检查仓库结构与约定
- 02识别策略层和实现层
- 03核对现有规范与 ADR
- 04起草或更新一个 SOLID 章节
- 05写入前确认内容
适用场景
- 01为仓库记录架构规则
- 02使 SOLID 指引符合现有代码分层
- 03更新已有 SOLID 章节并避免重复
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ c0nant/ skills --skill setup-solid安装后在 Claude Code 中输入/setup-solid确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
RESUMO.mdTRADUCAO.pt-BR.mdagents/openai.yaml详细介绍
设置 SOLID
在仓库中安装一条持久的指引:通过童子军规则,在架构层面应用 SOLID。
童子军规则是这项设置的核心。SOLID 应用于当前正在编写的代码,以及当前流程已经经过的代码,而不是整个仓库。代码库每次变更一点,逐步趋于完善。
本节与语言无关:讨论的是模块、接缝和依赖方向,而不是框架的 DI 容器或某种语言的 interface 关键字。值得编写本节的原因,在于第 1 步的探索;本节会明确列出这个仓库的实际分层和路径。
无论仓库的文档使用什么语言,本节始终以英语撰写,与其他代码标准保持一致。
流程
1. 探索
起草前先阅读仓库。不要想当然:
- 使用了哪些语言,以及代码如何分组:包、文件夹、服务。哪些文件夹包含策略(领域 / 业务规则),哪些包含细节(数据库、HTTP、SDK、文件系统)?
- 根目录下的
CLAUDE.md和AGENTS.md:是否存在其中任一文件?一个是否是指向另一个的符号链接?是否已有 SOLID 部分(任何标题级别或大小写均算),或者与之重叠的架构 / 编码标准部分? - 单体仓库的迹象:
pnpm-workspace.yaml、package.json中的workspaces字段、包含各包自身CLAUDE.md文件的非空packages/*。只有当这些包的分层布局确实不同时才需要考虑;否则根目录文件就足以覆盖。 GLOSSARY.md:本节应使用的、描述仓库概念的领域词汇。- ADR(
.agents/adr/、docs/adr/):本节不得与之矛盾的架构决策。 - 依赖目前如何注入(构造函数参数、函数参数、容器、模块导入),以及测试目前如何替换依赖:本节应描述现有惯例,而不是引入新的做法。
完成标准:能够用这个仓库自身的路径,指出策略所在位置、细节所在位置、两者目前如何连接,以及测试如何替换某项细节。
如果不存在策略 / 细节分层,就停止。 文档仓库、精简的脚本仓库、提示词文件仓库:这些仓库没有可供本节塑造的 IO 边界。告知用户仓库没有可供本节列出的分层,不要编写本节。如果存在分层但较简单(只有一个小型领域文件夹,尚无接口),则提供精简版内容:仅包含 SRP 和 OCP,不包含 ### 在本仓库中 部分,并说明删去了哪些内容。
2. 起草并确认
向用户展示准备编写的完整部分,并填入第 1 步中获得的信息。只询问确实会导致不同处理方式的问题:
- 只有在
CLAUDE.md和AGENTS.md均不存在时,才询问要写入哪个文件。 - 探索后仍不明确的事项,例如有两个可能的策略文件夹。
如实指出以下情况,不要默默自行决定:
- 标准部分重叠。 如果某个架构或编码标准部分已规定依赖方向或抽象规则,应说明这一点,并提议将 SOLID 合并进去,或让 SOLID 遵循该部分。同一个文件中针对同一问题出现两套规则,甚至不如没有规则:
/review-axes会将它们都视为已记录的标准。 - 与 ADR 冲突。 如果某条 ADR 与某项原则矛盾,应指出 ADR 名称和对应条目。不要默默删掉该原则;缺少 DIP 条目会留下无法解释的空缺。
写入前,允许用户修改草稿。
3. 编写
选择文件:如果 CLAUDE.md 存在,就编辑它;否则编辑 AGENTS.md;否则编辑用户选择的文件。如果已经存在 SOLID 章节(无论标题级别或大小写),就在原处更新,不要再追加第二个。保留周围的章节不变。
该章节:
## SOLID
Apply SOLID at the **architecture** level: module boundaries, dependency direction, and the interfaces between them. It is a way to shape seams, not a naming ritual. "Module" means whatever this codebase groups behaviour into: a class, a package, a file of functions, a service.
### Scope: boy scout rule
SOLID applies to:
- code written new in the current change, and
- the existing code the current flow already passes through, when a small local edit clears friction that change is hitting.
The rest of the codebase stays as it is. Keep a change's blast radius on the flow being built or fixed: a repo-wide SOLID refactor is its own piece of work, and happens only when explicitly asked for. The codebase converges one change at a time.
When applying a principle would require reshaping modules outside the current flow, leave them alone and say so in the summary of the change.
### In this repo
- **Policy**: [POLICY PATHS]
- **Details**: [DETAILS PATHS]
- **Wiring**: [INJECTION CONVENTION]
- **Test substitution**: [TEST SUBSTITUTION CONVENTION]
### The principles, as architecture rules
- **SRP**: a module has one reason to change. When one flow forces edits in a module that other flows also own for unrelated reasons, that module is holding two responsibilities.
- **OCP**: new behaviour arrives as a new implementation behind an existing interface, rather than another branch in a growing conditional over kinds of thing.
- **LSP**: every implementation of an interface is substitutable through that interface: same contract, same error behaviour, no "this one also needs X called first".
- **ISP**: a consumer depends on the narrow interface it actually uses. Interfaces are shaped by the caller's need, not by everything the implementation can do.
- **DIP**: policy does not depend on details (see *In this repo* above for both). The interface belongs to the policy side; the detail implements it and is passed in.
### Applying it
- When a new flow crosses an IO boundary, define the interface from the policy side and inject the implementation.
- One production implementation is enough **when a test substitutes it**: the test double is the second implementation, and the interface is the test surface. An adapter behind an interface with a single caller and no substitution is a hypothetical seam: drop the interface until something real needs it.
- Use this repo's domain vocabulary (`GLOSSARY.md`) when naming modules and interfaces.
根据第 1 步中本仓库的实际路径和约定,填写 [POLICY PATHS]、[DETAILS PATHS]、[INJECTION CONVENTION] 和 [TEST SUBSTITUTION CONVENTION]:使用具体的 glob(如 src/domain/**),不要写类别。如果仓库中没有 GLOSSARY.md,就删除这一行。如果 ADR 覆盖了某项原则,保留该条要点,并在其中注明例外,同时引用 ADR。
然后重新阅读你写的内容并检查:没有遗留任何 [PLACEHOLDER],且文件中恰好只有一个 SOLID 章节。遗留的占位符会成为永久噪音,之后每个读取此文件的技能都会看到它。
4. 完成
告知用户:
- 你编辑了哪个文件。
- SOLID 现在适用于新代码,也适用于每次变更已经涉及的代码:不会再单独进行重构。
- 这改变了其他技能的行为。
/review-axes会优先遵循文档记录的仓库标准,而不是自身的基准,因此从现在起,它会标记违反这些要点的差异,并引用本节;/implement会在编写代码时读取这些要点。如果这些要求比用户期望的更严格,现在正是放宽某条要点的时候。
只有需要调整该章节本身时,才需要重新运行此技能;也可以直接编辑该章节。