claude-sdlc 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +317 -0
- package/bin/cli.js +39 -0
- package/lib/installer.js +224 -0
- package/package.json +20 -0
- package/template/.claude/commands/checkpoint.md +65 -0
- package/template/.claude/commands/phase.md +152 -0
- package/template/.claude/commands/review.md +456 -0
- package/template/.claude/commands/status.md +86 -0
- package/template/.claude/hooks/check-phase-test.sh +154 -0
- package/template/.claude/hooks/check-phase-write.sh +86 -0
- package/template/.claude/reviews/.gitkeep +0 -0
- package/template/.claude/rules/01-lifecycle-phases.md +343 -0
- package/template/.claude/rules/02-coding-standards.md +125 -0
- package/template/.claude/rules/03-testing-standards.md +120 -0
- package/template/.claude/rules/04-git-workflow.md +126 -0
- package/template/.claude/rules/05-anti-amnesia.md +219 -0
- package/template/.claude/rules/06-review-tools.md +85 -0
- package/template/.claude/rules/07-parallel-agents.md +163 -0
- package/template/.claude/settings.json +35 -0
- package/template/CLAUDE.md +117 -0
package/README.md
ADDED
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
# SDLC Enforcer for Claude Code
|
|
2
|
+
|
|
3
|
+
**让 Claude Code 严格按照软件开发生命周期(SDLC)规范进行开发。**
|
|
4
|
+
|
|
5
|
+
自动加载、自动识别任务、自动驱动全流程、运行时拦截、抗上下文压缩——零配置,开箱即用。
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 解决什么问题
|
|
10
|
+
|
|
11
|
+
| 问题 | 解决方案 |
|
|
12
|
+
|------|---------|
|
|
13
|
+
| Claude Code 不遵循开发流程,直接写代码 | SDLC 六阶段强制流程(需求→设计→编码→测试→审查→交付) |
|
|
14
|
+
| 需要用户反复输入指令推进流程 | **自动驱动模式**:确认 PRD 和设计后,P3→P6 全自动完成 |
|
|
15
|
+
| 规范需要手动每次提醒 | CLAUDE.md + rules/ 自动加载,Hooks 运行时拦截 |
|
|
16
|
+
| Claude Code 无法自动识别规范 | CLAUDE.md 启动指令自动初始化 + 任务自动识别 |
|
|
17
|
+
| Claude 自行添加/减少功能 | **PRD 驱动开发**:严格按需求清单执行,每行代码对应 PRD |
|
|
18
|
+
| 长对话后 Claude 忘记规范(context compaction) | 七层防御机制 + `# Compact Instructions` + CLAUDE.md 活文档 |
|
|
19
|
+
| CLAUDE.md 太长导致指令遵循率下降 | **精简到 ~100 行**,详细规则拆分到 rules/(自动加载) |
|
|
20
|
+
|
|
21
|
+
## 核心特性
|
|
22
|
+
|
|
23
|
+
- **自动驱动模式**:用户只需确认 PRD 和设计方案,P3 编码→P4 测试→P5 集成审查→P6 交付全自动完成
|
|
24
|
+
- **PRD 驱动开发**:P1 产出编号化需求清单,全流程以 PRD 为唯一依据,禁止自行添加/减少
|
|
25
|
+
- **六阶段 SDLC 流程**:P1 需求分析 → P2 系统设计 → P3 编码实现 → P4 测试验证 → P5 集成审查 → P6 部署交付
|
|
26
|
+
- **每阶段独立审查**:每个阶段都有专项 Review,审查通过才推进(自动驱动模式下自动执行)
|
|
27
|
+
- **自动修复重试**:审查未通过时自动修复并重试(最多 3 次),超过才请求用户帮助
|
|
28
|
+
- **运行时拦截**:Hooks 自动拦截当前阶段不允许的操作(写代码、测试、git 提交)
|
|
29
|
+
- **抗压缩**:`# Compact Instructions` + PreCompact hook,compaction 后自动恢复并继续自动驱动
|
|
30
|
+
- **精简 CLAUDE.md**:核心控制文件仅 ~100 行,指令遵循率最优;详细规则通过 rules/ 自动加载
|
|
31
|
+
- **斜杠命令**:`/phase`、`/status`、`/checkpoint`、`/review`(自动驱动时通常不需要手动使用)
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 快速安装
|
|
36
|
+
|
|
37
|
+
### 方式 1:npx 一条命令(推荐)
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npx claude-sdlc # 安装到当前项目
|
|
41
|
+
npx claude-sdlc ./my-project # 安装到指定目录
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 方式 2:全局安装
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npm install -g claude-sdlc
|
|
48
|
+
claude-sdlc
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 方式 3:clone 后安装(备选)
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
git clone https://github.com/<your-username>/sdlc-enforcer.git
|
|
55
|
+
cd sdlc-enforcer
|
|
56
|
+
./install.sh /path/to/your-project
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### 前置依赖
|
|
60
|
+
|
|
61
|
+
- **Node.js >= 16**(npx / npm 方式需要)
|
|
62
|
+
- **jq**(可选):Hook 脚本优先使用 jq 解析 JSON,未安装时自动降级为 sed 解析(仍然可用)
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## 安装后的文件结构
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
your-project/
|
|
70
|
+
├── CLAUDE.md # 核心控制文件(~100行,自动加载)
|
|
71
|
+
└── .claude/
|
|
72
|
+
├── settings.json # Hooks 配置
|
|
73
|
+
├── rules/ # 详细规则(自动加载)
|
|
74
|
+
│ ├── 01-lifecycle-phases.md # SDLC 阶段定义
|
|
75
|
+
│ ├── 02-coding-standards.md # 编码规范
|
|
76
|
+
│ ├── 03-testing-standards.md # 测试标准
|
|
77
|
+
│ ├── 04-git-workflow.md # Git 工作流
|
|
78
|
+
│ ├── 05-anti-amnesia.md # 反遗忘机制
|
|
79
|
+
│ ├── 06-review-tools.md # 审查工具链配置
|
|
80
|
+
│ └── 07-parallel-agents.md # 多 Agent 并行开发
|
|
81
|
+
├── hooks/ # 运行时拦截脚本
|
|
82
|
+
│ ├── check-phase-write.sh # 拦截非法代码写入
|
|
83
|
+
│ └── check-phase-test.sh # 拦截非法测试/git 执行
|
|
84
|
+
├── reviews/ # 审查报告持久化
|
|
85
|
+
└── commands/ # 斜杠命令
|
|
86
|
+
├── phase.md # /phase 命令
|
|
87
|
+
├── checkpoint.md # /checkpoint 命令
|
|
88
|
+
├── status.md # /status 命令
|
|
89
|
+
└── review.md # /review 命令
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### 架构设计原则
|
|
93
|
+
|
|
94
|
+
| 层 | 文件 | 加载方式 | 职责 |
|
|
95
|
+
|----|------|---------|------|
|
|
96
|
+
| 控制层 | `CLAUDE.md` (~100行) | 自动加载 | 启动指令、核心规则摘要、项目状态 YAML、Compact Instructions |
|
|
97
|
+
| 规则层 | `.claude/rules/*.md` | 自动加载 | 详细阶段定义、编码/测试/Git 规范、反遗忘机制 |
|
|
98
|
+
| 拦截层 | `.claude/hooks/*.sh` | 自动触发 | PreToolUse 运行时拦截违规操作 |
|
|
99
|
+
| 审查层 | `.claude/settings.json` | 自动注册 | Stop/PostToolUse/PreCompact prompt hooks |
|
|
100
|
+
| 交互层 | `.claude/commands/*.md` | 用户调用 | /phase, /status, /checkpoint, /review |
|
|
101
|
+
|
|
102
|
+
**精简 CLAUDE.md 的原因**:官方文档指出,CLAUDE.md 越短指令遵循率越高。详细规则通过 rules/ 自动加载,无需在 CLAUDE.md 中重复。
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## 使用指南
|
|
107
|
+
|
|
108
|
+
### 开始开发
|
|
109
|
+
|
|
110
|
+
在目标项目目录启动 Claude Code:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
cd your-project
|
|
114
|
+
claude
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Claude 会自动加载 SDLC 规范。**当你提出开发任务时(如"帮我实现..."),Claude 会自动进入 P1(需求分析),无需手动操作。**
|
|
118
|
+
|
|
119
|
+
### 自动驱动模式(核心特性)
|
|
120
|
+
|
|
121
|
+
**用户只需两次确认,其余全自动:**
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
你说"帮我实现XX"
|
|
125
|
+
↓ 自动
|
|
126
|
+
P1 需求分析 → Claude 整理 PRD → 【你确认 PRD】
|
|
127
|
+
↓ 自动
|
|
128
|
+
P2 系统设计 → Claude 设计方案 → 【你确认设计】
|
|
129
|
+
↓ 自动(以下全自动,你不需要操作)
|
|
130
|
+
P3 编码 → 自动审查 → P4 测试 → 自动审查 → P5 集成 → 自动审查 → P6 交付 → 完成报告
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
- P1/P2:Claude 做分析,你确认方案,仅此而已
|
|
134
|
+
- P3→P6:Claude 自动编码、测试、审查、交付,你坐等结果
|
|
135
|
+
- 审查失败时 Claude 自动修复重试(最多 3 次),超过才请求你帮助
|
|
136
|
+
- 你随时可以介入(输入任何消息即可)
|
|
137
|
+
|
|
138
|
+
### 可用命令(通常不需要手动使用)
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
/phase # 查看当前阶段进度
|
|
142
|
+
/phase next # 手动推进阶段(自动驱动模式下不需要)
|
|
143
|
+
/phase back # 回退到上一阶段
|
|
144
|
+
/status # 查看全面的项目状态报告
|
|
145
|
+
/checkpoint # 保存状态快照(建议长对话时定期使用)
|
|
146
|
+
/review # 手动触发当前阶段审查
|
|
147
|
+
/review src/auth/login.ts # 审查指定文件(P3+ 阶段)
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### SDLC 六阶段说明
|
|
151
|
+
|
|
152
|
+
| 阶段 | 名称 | 核心活动 | 阶段审查 | 推进方式 |
|
|
153
|
+
|------|------|---------|---------|---------|
|
|
154
|
+
| **P1** | 需求分析 | 理解需求、整理 PRD | 需求审查 | 用户确认 PRD |
|
|
155
|
+
| **P2** | 系统设计 | 架构设计、实现规划 | 设计审查 | 用户确认设计 |
|
|
156
|
+
| **P3** | 编码实现 | 按 PRD 编写代码 | 代码审查(含工具链) | **自动驱动** |
|
|
157
|
+
| **P4** | 测试验证 | 按 PRD 编写/执行测试 | 测试审查(含覆盖率) | **自动驱动** |
|
|
158
|
+
| **P5** | 集成审查 | 全局审查、四环追溯 | 集成审查 | **自动驱动** |
|
|
159
|
+
| **P6** | 部署交付 | Git 提交、交付报告 | 交付审查 | **自动完成** |
|
|
160
|
+
|
|
161
|
+
### 工具辅助审查(生产级特性)
|
|
162
|
+
|
|
163
|
+
`/review` 不仅依赖 LLM 判断,还会**自动运行真实工具链**,用客观数据辅助审查:
|
|
164
|
+
|
|
165
|
+
- **自动检测项目类型** — 根据 `package.json`、`pyproject.toml`、`go.mod`、`Cargo.toml` 等文件自动识别项目类型,运行对应的 Lint/Typecheck/Build/Audit 工具
|
|
166
|
+
- **工具未安装时自动安装** — 检测到所需工具未安装时,自动安装为 devDependency(如 `npm install --save-dev eslint`);安装失败时降级跳过,不阻塞审查
|
|
167
|
+
- **真实数据驱动** — Lint 错误数、Typecheck 错误数、构建结果、依赖漏洞数、测试通过率、代码覆盖率均来自工具实际输出,非 LLM 估算
|
|
168
|
+
- **审查报告持久化** — 每次 `/review` 的完整报告(含工具输出原文)写入 `.claude/reviews/P{n}-review-{时间}.md`,可追溯
|
|
169
|
+
|
|
170
|
+
详细配置见 `.claude/rules/06-review-tools.md`。
|
|
171
|
+
|
|
172
|
+
### 多 Agent 并行开发
|
|
173
|
+
|
|
174
|
+
P3/P4/P5 阶段支持多 Agent 并行工作,利用 Claude Code 的 Task 工具提高开发效率:
|
|
175
|
+
|
|
176
|
+
- **P3 并行编码** — 独立模块由不同子 Agent 同时编写,主 Agent 协调接口一致性
|
|
177
|
+
- **P4 并行测试** — 不同模块的测试由不同子 Agent 同时编写,主 Agent 统一执行验证
|
|
178
|
+
- **P5 并行审查** — 全局一致性、性能、PRD 追溯三个维度由不同子 Agent 同时审查
|
|
179
|
+
|
|
180
|
+
并行开发不适用于:P1/P2(需用户交互)、P6(git 串行)、模块间有依赖时。
|
|
181
|
+
|
|
182
|
+
详细规则见 `.claude/rules/07-parallel-agents.md`。
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## 自动执行 — 无需人为干预
|
|
187
|
+
|
|
188
|
+
本系统的设计目标:**Claude 在任何情况下都能自己读取规范、按规范执行**,用户不需要提醒。
|
|
189
|
+
|
|
190
|
+
### 七层防御机制
|
|
191
|
+
|
|
192
|
+
| 层 | 机制 | 类型 | 作用 |
|
|
193
|
+
|----|------|------|------|
|
|
194
|
+
| 1 | CLAUDE.md 启动指令 | 主动 | 每次加载时自动执行状态检查和初始化 |
|
|
195
|
+
| 2 | rules/ 规则文件 | 主动 | 详细规范自动加载,compaction 后重新加载 |
|
|
196
|
+
| 3 | PreToolUse Hooks | 被动 | 硬拦截违规操作(写代码/测试/git),不依赖 Claude 自觉 |
|
|
197
|
+
| 4 | PostToolUse Hook | 主动 | 每次文件修改后提醒更新 CLAUDE.md 状态 |
|
|
198
|
+
| 5 | Stop Hook | 主动 | 每次回复后强制自检合规性 + 自动驱动推进 |
|
|
199
|
+
| 6 | PreCompact Hook | 主动 | 压缩前强制保存所有状态到 CLAUDE.md |
|
|
200
|
+
| 7 | 用户命令 | 按需 | /status、/checkpoint、/phase、/review |
|
|
201
|
+
|
|
202
|
+
### 端到端自动化流程
|
|
203
|
+
|
|
204
|
+
```
|
|
205
|
+
用户说"帮我实现X"
|
|
206
|
+
↓
|
|
207
|
+
CLAUDE.md 启动指令自动识别 → 进入 P1
|
|
208
|
+
↓
|
|
209
|
+
P1 需求分析 → 整理 PRD → 用户确认 → 自动审查 → 进入 P2
|
|
210
|
+
↓
|
|
211
|
+
P2 系统设计 → 设计方案 → 用户确认 → 自动审查 → 进入 P3
|
|
212
|
+
↓
|
|
213
|
+
══════════ 自动驱动模式启动 ══════════
|
|
214
|
+
↓
|
|
215
|
+
P3 编码 → 代码审查 → 通过 → P4 测试 → 测试审查 → 通过 → P5 集成审查 → 通过 → P6 交付 → 完成
|
|
216
|
+
│ │ │
|
|
217
|
+
└── 审查失败:自动修复 └── 审查失败:自动修复 └── 审查失败:自动修复
|
|
218
|
+
重试(最多3次) 重试(最多3次) 重试(最多3次)
|
|
219
|
+
↓
|
|
220
|
+
输出交付摘要(PRD 完成率、修改文件、测试结果、Git 提交)
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
全程每次回复 → Stop Hook 强制自检 + 自动驱动推进
|
|
224
|
+
全程每次工具调用 → PreToolUse Hook 拦截违规
|
|
225
|
+
全程每次文件修改 → PostToolUse Hook 同步状态
|
|
226
|
+
Context Compaction 时 → PreCompact Hook 保存状态 → 自动恢复后继续
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## 自定义配置
|
|
231
|
+
|
|
232
|
+
### 修改阶段定义
|
|
233
|
+
|
|
234
|
+
编辑 `.claude/rules/01-lifecycle-phases.md`,可以修改每个阶段的入口/退出条件。
|
|
235
|
+
|
|
236
|
+
### 修改编码规范
|
|
237
|
+
|
|
238
|
+
编辑 `.claude/rules/02-coding-standards.md`,根据团队习惯调整命名、格式等规范。
|
|
239
|
+
|
|
240
|
+
### 添加新的规则文件
|
|
241
|
+
|
|
242
|
+
在 `.claude/rules/` 目录下添加新的 `.md` 文件,会自动被 Claude Code 加载。
|
|
243
|
+
|
|
244
|
+
### 调整 Hook 拦截规则
|
|
245
|
+
|
|
246
|
+
编辑 `.claude/hooks/` 下的脚本,修改文件类型白名单或命令模式匹配。
|
|
247
|
+
|
|
248
|
+
### 添加新的斜杠命令
|
|
249
|
+
|
|
250
|
+
在 `.claude/commands/` 下添加新的 `.md` 文件即可注册新命令。
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## 工作原理
|
|
255
|
+
|
|
256
|
+
```
|
|
257
|
+
Claude Code 启动
|
|
258
|
+
↓
|
|
259
|
+
自动加载 CLAUDE.md (~100行) → 启动指令 + 核心规则 + 项目状态
|
|
260
|
+
↓
|
|
261
|
+
自动加载 .claude/rules/*.md → 详细阶段定义 + 编码/测试/Git 规范 + 反遗忘机制
|
|
262
|
+
↓
|
|
263
|
+
自动注册 .claude/settings.json 中的 Hooks
|
|
264
|
+
↓
|
|
265
|
+
自动注册 .claude/commands/*.md 为斜杠命令
|
|
266
|
+
↓
|
|
267
|
+
开始工作(受规范约束)
|
|
268
|
+
│
|
|
269
|
+
├── 每次工具调用 → PreToolUse Hook 检查阶段合规性
|
|
270
|
+
├── 每次文件修改 → PostToolUse Hook 同步状态到 CLAUDE.md
|
|
271
|
+
├── 每次回复后 → Stop Hook 自检 + 自动驱动推进
|
|
272
|
+
└── Context Compaction 前 → PreCompact Hook 保存状态
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### 为什么精简 CLAUDE.md?
|
|
276
|
+
|
|
277
|
+
| 对比 | 旧版 (~285行) | 新版 (~100行) |
|
|
278
|
+
|------|-------------|-------------|
|
|
279
|
+
| 详细规则 | 全部写在 CLAUDE.md 中 | 拆分到 rules/ 自动加载 |
|
|
280
|
+
| 指令遵循率 | 随长度增加而下降 | 精简核心,遵循率更高 |
|
|
281
|
+
| Compaction 影响 | 信息过多可能被压缩遗漏 | 关键信息集中,不易遗漏 |
|
|
282
|
+
| 维护性 | 单文件维护困难 | 模块化,各规则独立维护 |
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## 常见问题
|
|
287
|
+
|
|
288
|
+
### Hook 报错"jq: command not found"
|
|
289
|
+
|
|
290
|
+
安装 jq:`brew install jq`(macOS)或 `sudo apt-get install jq`(Ubuntu)。无 jq 时 hooks 自动降级为 sed 解析。
|
|
291
|
+
|
|
292
|
+
### 已有 CLAUDE.md 会被覆盖吗?
|
|
293
|
+
|
|
294
|
+
不会。安装脚本会先将已有的 CLAUDE.md 备份为 `CLAUDE.md.bak.<时间戳>`。
|
|
295
|
+
|
|
296
|
+
### 已有 settings.json 会被覆盖吗?
|
|
297
|
+
|
|
298
|
+
如果安装了 jq,脚本会智能合并 hooks 配置。否则会备份原文件后覆盖。
|
|
299
|
+
|
|
300
|
+
### 可以跳过某个阶段吗?
|
|
301
|
+
|
|
302
|
+
可以,但 Claude 会先说明跳过的风险。用户坚持则记录跳过原因后强制推进。
|
|
303
|
+
|
|
304
|
+
### 如何卸载?
|
|
305
|
+
|
|
306
|
+
删除以下文件即可:
|
|
307
|
+
```bash
|
|
308
|
+
rm CLAUDE.md
|
|
309
|
+
rm -rf .claude/rules/ .claude/hooks/ .claude/commands/
|
|
310
|
+
# 如需要,手动从 .claude/settings.json 中移除 SDLC 相关的 hooks
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
## License
|
|
316
|
+
|
|
317
|
+
MIT
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const { install } = require('../lib/installer');
|
|
6
|
+
|
|
7
|
+
const pkg = require('../package.json');
|
|
8
|
+
|
|
9
|
+
const HELP = `
|
|
10
|
+
SDLC Enforcer v${pkg.version}
|
|
11
|
+
|
|
12
|
+
让 Claude Code 严格按照 SDLC 规范开发 — 一条命令安装
|
|
13
|
+
|
|
14
|
+
用法:
|
|
15
|
+
claude-sdlc [目标路径] 安装 SDLC 规范到目标项目(默认当前目录)
|
|
16
|
+
claude-sdlc --help 显示帮助
|
|
17
|
+
claude-sdlc --version 显示版本
|
|
18
|
+
|
|
19
|
+
示例:
|
|
20
|
+
npx claude-sdlc # 安装到当前目录
|
|
21
|
+
npx claude-sdlc ./myapp # 安装到指定目录
|
|
22
|
+
`.trim();
|
|
23
|
+
|
|
24
|
+
const args = process.argv.slice(2);
|
|
25
|
+
|
|
26
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
27
|
+
console.log(HELP);
|
|
28
|
+
process.exit(0);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (args.includes('--version') || args.includes('-v')) {
|
|
32
|
+
console.log(pkg.version);
|
|
33
|
+
process.exit(0);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const targetArg = args[0] || '.';
|
|
37
|
+
const targetDir = path.resolve(targetArg);
|
|
38
|
+
|
|
39
|
+
install(targetDir);
|
package/lib/installer.js
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
// 颜色码
|
|
7
|
+
const RED = '\x1b[0;31m';
|
|
8
|
+
const GREEN = '\x1b[0;32m';
|
|
9
|
+
const YELLOW = '\x1b[1;33m';
|
|
10
|
+
const BLUE = '\x1b[0;34m';
|
|
11
|
+
const NC = '\x1b[0m';
|
|
12
|
+
|
|
13
|
+
function info(msg) { console.log(`${BLUE}[INFO]${NC} ${msg}`); }
|
|
14
|
+
function success(msg) { console.log(`${GREEN}[OK]${NC} ${msg}`); }
|
|
15
|
+
function warn(msg) { console.log(`${YELLOW}[WARN]${NC} ${msg}`); }
|
|
16
|
+
function error(msg) { console.error(`${RED}[ERROR]${NC} ${msg}`); }
|
|
17
|
+
|
|
18
|
+
function timestamp() {
|
|
19
|
+
const d = new Date();
|
|
20
|
+
return d.getFullYear().toString()
|
|
21
|
+
+ String(d.getMonth() + 1).padStart(2, '0')
|
|
22
|
+
+ String(d.getDate()).padStart(2, '0')
|
|
23
|
+
+ String(d.getHours()).padStart(2, '0')
|
|
24
|
+
+ String(d.getMinutes()).padStart(2, '0')
|
|
25
|
+
+ String(d.getSeconds()).padStart(2, '0');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* 复制目录中所有匹配指定扩展名的文件
|
|
30
|
+
*/
|
|
31
|
+
function copyFiles(srcDir, destDir, ext, label) {
|
|
32
|
+
if (!fs.existsSync(srcDir)) return [];
|
|
33
|
+
const files = fs.readdirSync(srcDir).filter(f => f.endsWith(ext));
|
|
34
|
+
const copied = [];
|
|
35
|
+
for (const file of files) {
|
|
36
|
+
fs.copyFileSync(path.join(srcDir, file), path.join(destDir, file));
|
|
37
|
+
success(`已安装${label}:${file}`);
|
|
38
|
+
copied.push(file);
|
|
39
|
+
}
|
|
40
|
+
return copied;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* 智能合并 settings.json — 合并 hooks 数组(去重)
|
|
45
|
+
*/
|
|
46
|
+
function mergeSettings(existing, template) {
|
|
47
|
+
const hookTypes = ['PreToolUse', 'PostToolUse', 'Stop', 'PreCompact'];
|
|
48
|
+
const result = JSON.parse(JSON.stringify(existing));
|
|
49
|
+
|
|
50
|
+
for (const type of hookTypes) {
|
|
51
|
+
const existingHooks = result.hooks?.[type] || [];
|
|
52
|
+
const newHooks = template.hooks?.[type] || [];
|
|
53
|
+
|
|
54
|
+
const merged = [...existingHooks];
|
|
55
|
+
for (const hook of newHooks) {
|
|
56
|
+
const key = hook.command || hook.prompt;
|
|
57
|
+
if (!merged.some(h => (h.command || h.prompt) === key)) {
|
|
58
|
+
merged.push(hook);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (!result.hooks) result.hooks = {};
|
|
63
|
+
result.hooks[type] = merged;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* 主安装逻辑
|
|
71
|
+
*/
|
|
72
|
+
function install(targetDir) {
|
|
73
|
+
// 模板目录位于包的 template/ 下
|
|
74
|
+
const templateDir = path.join(__dirname, '..', 'template');
|
|
75
|
+
|
|
76
|
+
// 验证目标目录
|
|
77
|
+
if (!fs.existsSync(targetDir)) {
|
|
78
|
+
error(`目标目录不存在:${targetDir}`);
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (!fs.statSync(targetDir).isDirectory()) {
|
|
83
|
+
error(`目标路径不是目录:${targetDir}`);
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// 验证模板目录
|
|
88
|
+
if (!fs.existsSync(templateDir)) {
|
|
89
|
+
error(`找不到 template 目录:${templateDir}`);
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
console.log('');
|
|
94
|
+
console.log('========================================');
|
|
95
|
+
console.log(' SDLC Enforcer 安装程序');
|
|
96
|
+
console.log('========================================');
|
|
97
|
+
console.log('');
|
|
98
|
+
info(`模板目录:${templateDir}`);
|
|
99
|
+
info(`目标项目:${targetDir}`);
|
|
100
|
+
console.log('');
|
|
101
|
+
|
|
102
|
+
// === Step 1: 备份已有的 CLAUDE.md ===
|
|
103
|
+
const claudeMdPath = path.join(targetDir, 'CLAUDE.md');
|
|
104
|
+
if (fs.existsSync(claudeMdPath)) {
|
|
105
|
+
const backupName = `CLAUDE.md.bak.${timestamp()}`;
|
|
106
|
+
const backupPath = path.join(targetDir, backupName);
|
|
107
|
+
warn(`目标项目已有 CLAUDE.md,备份为:${backupName}`);
|
|
108
|
+
fs.copyFileSync(claudeMdPath, backupPath);
|
|
109
|
+
success('已备份 CLAUDE.md');
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// === Step 2: 复制 CLAUDE.md ===
|
|
113
|
+
fs.copyFileSync(path.join(templateDir, 'CLAUDE.md'), claudeMdPath);
|
|
114
|
+
success('已安装 CLAUDE.md');
|
|
115
|
+
|
|
116
|
+
// === Step 3: 创建 .claude 目录结构 ===
|
|
117
|
+
const dirs = ['rules', 'hooks', 'commands', 'reviews'];
|
|
118
|
+
for (const dir of dirs) {
|
|
119
|
+
fs.mkdirSync(path.join(targetDir, '.claude', dir), { recursive: true });
|
|
120
|
+
}
|
|
121
|
+
success('已创建 .claude/ 目录结构');
|
|
122
|
+
|
|
123
|
+
// === Step 4: 复制 rules 文件 ===
|
|
124
|
+
copyFiles(
|
|
125
|
+
path.join(templateDir, '.claude', 'rules'),
|
|
126
|
+
path.join(targetDir, '.claude', 'rules'),
|
|
127
|
+
'.md',
|
|
128
|
+
'规则'
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
// === Step 5: 复制 hooks 脚本 + 设置执行权限 ===
|
|
132
|
+
const hooksSrcDir = path.join(templateDir, '.claude', 'hooks');
|
|
133
|
+
const hooksDestDir = path.join(targetDir, '.claude', 'hooks');
|
|
134
|
+
if (fs.existsSync(hooksSrcDir)) {
|
|
135
|
+
const hookFiles = fs.readdirSync(hooksSrcDir).filter(f => f.endsWith('.sh'));
|
|
136
|
+
for (const file of hookFiles) {
|
|
137
|
+
const destPath = path.join(hooksDestDir, file);
|
|
138
|
+
fs.copyFileSync(path.join(hooksSrcDir, file), destPath);
|
|
139
|
+
try {
|
|
140
|
+
fs.chmodSync(destPath, 0o755);
|
|
141
|
+
} catch (_) {
|
|
142
|
+
// Windows 下 chmod 可能不支持,忽略
|
|
143
|
+
}
|
|
144
|
+
success(`已安装 Hook:${file}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// === Step 6: 复制 commands ===
|
|
149
|
+
copyFiles(
|
|
150
|
+
path.join(templateDir, '.claude', 'commands'),
|
|
151
|
+
path.join(targetDir, '.claude', 'commands'),
|
|
152
|
+
'.md',
|
|
153
|
+
'命令'
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
// === Step 7: 智能合并 settings.json ===
|
|
157
|
+
const targetSettings = path.join(targetDir, '.claude', 'settings.json');
|
|
158
|
+
const sourceSettings = path.join(templateDir, '.claude', 'settings.json');
|
|
159
|
+
|
|
160
|
+
if (fs.existsSync(targetSettings)) {
|
|
161
|
+
warn('目标项目已有 .claude/settings.json');
|
|
162
|
+
|
|
163
|
+
try {
|
|
164
|
+
const existing = JSON.parse(fs.readFileSync(targetSettings, 'utf-8'));
|
|
165
|
+
const template = JSON.parse(fs.readFileSync(sourceSettings, 'utf-8'));
|
|
166
|
+
|
|
167
|
+
// 备份原文件
|
|
168
|
+
const backupName = `settings.json.bak.${timestamp()}`;
|
|
169
|
+
const backupPath = path.join(targetDir, '.claude', backupName);
|
|
170
|
+
fs.copyFileSync(targetSettings, backupPath);
|
|
171
|
+
warn(`已备份原 settings.json 为:${backupName}`);
|
|
172
|
+
|
|
173
|
+
// 智能合并
|
|
174
|
+
const merged = mergeSettings(existing, template);
|
|
175
|
+
fs.writeFileSync(targetSettings, JSON.stringify(merged, null, 2) + '\n', 'utf-8');
|
|
176
|
+
success('已智能合并 settings.json(保留原有配置)');
|
|
177
|
+
} catch (e) {
|
|
178
|
+
warn(`合并失败(${e.message}),将覆盖安装 settings.json`);
|
|
179
|
+
fs.copyFileSync(sourceSettings, targetSettings);
|
|
180
|
+
success('已安装 settings.json(覆盖)');
|
|
181
|
+
}
|
|
182
|
+
} else {
|
|
183
|
+
fs.copyFileSync(sourceSettings, targetSettings);
|
|
184
|
+
success('已安装 settings.json');
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// === Step 8: 安装完成 ===
|
|
188
|
+
console.log('');
|
|
189
|
+
console.log('========================================');
|
|
190
|
+
console.log(` ${GREEN}安装完成!${NC}`);
|
|
191
|
+
console.log('========================================');
|
|
192
|
+
console.log('');
|
|
193
|
+
console.log('已安装的文件:');
|
|
194
|
+
console.log(` ${targetDir}/`);
|
|
195
|
+
console.log(' ├── CLAUDE.md (核心控制文件 ~100行,自动加载)');
|
|
196
|
+
console.log(' └── .claude/');
|
|
197
|
+
console.log(' ├── settings.json (Hooks 配置)');
|
|
198
|
+
console.log(' ├── reviews/ (审查报告持久化)');
|
|
199
|
+
console.log(' ├── rules/ (详细规则,自动加载)');
|
|
200
|
+
console.log(' │ ├── 01-lifecycle-phases.md');
|
|
201
|
+
console.log(' │ ├── 02-coding-standards.md');
|
|
202
|
+
console.log(' │ ├── 03-testing-standards.md');
|
|
203
|
+
console.log(' │ ├── 04-git-workflow.md');
|
|
204
|
+
console.log(' │ ├── 05-anti-amnesia.md');
|
|
205
|
+
console.log(' │ ├── 06-review-tools.md');
|
|
206
|
+
console.log(' │ └── 07-parallel-agents.md');
|
|
207
|
+
console.log(' ├── hooks/ (运行时拦截)');
|
|
208
|
+
console.log(' │ ├── check-phase-write.sh');
|
|
209
|
+
console.log(' │ └── check-phase-test.sh');
|
|
210
|
+
console.log(' └── commands/ (斜杠命令)');
|
|
211
|
+
console.log(' ├── phase.md (/phase)');
|
|
212
|
+
console.log(' ├── checkpoint.md (/checkpoint)');
|
|
213
|
+
console.log(' ├── status.md (/status)');
|
|
214
|
+
console.log(' └── review.md (/review)');
|
|
215
|
+
console.log('');
|
|
216
|
+
console.log('使用方法:');
|
|
217
|
+
console.log(` 1. cd ${targetDir}`);
|
|
218
|
+
console.log(' 2. 启动 claude 即可自动加载 SDLC 规范');
|
|
219
|
+
console.log(' 3. 使用 /phase 查看当前阶段');
|
|
220
|
+
console.log(' 4. 使用 /status 查看项目状态');
|
|
221
|
+
console.log('');
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
module.exports = { install, mergeSettings };
|
package/package.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "claude-sdlc",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "让 Claude Code 严格按 SDLC 规范开发 — 一条命令安装",
|
|
5
|
+
"bin": {
|
|
6
|
+
"claude-sdlc": "./bin/cli.js"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"bin/",
|
|
10
|
+
"lib/",
|
|
11
|
+
"template/"
|
|
12
|
+
],
|
|
13
|
+
"keywords": [
|
|
14
|
+
"claude-code",
|
|
15
|
+
"sdlc",
|
|
16
|
+
"development-workflow",
|
|
17
|
+
"ai-coding"
|
|
18
|
+
],
|
|
19
|
+
"license": "MIT"
|
|
20
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# /checkpoint — 保存状态快照
|
|
2
|
+
|
|
3
|
+
用法:`/checkpoint [描述]`
|
|
4
|
+
|
|
5
|
+
参数:$ARGUMENTS
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 执行逻辑
|
|
10
|
+
|
|
11
|
+
1. **收集当前状态信息**:
|
|
12
|
+
- 读取 CLAUDE.md 中的 `current_phase`
|
|
13
|
+
- 读取 CLAUDE.md 中的 `task_description`
|
|
14
|
+
- 执行 `git status`(如果是 git 仓库)获取文件变更状态
|
|
15
|
+
- 执行 `git diff --stat`(如果是 git 仓库)获取变更统计
|
|
16
|
+
|
|
17
|
+
2. **生成快照摘要**:
|
|
18
|
+
```
|
|
19
|
+
=== SDLC Checkpoint ===
|
|
20
|
+
时间:{当前时间}
|
|
21
|
+
描述:{用户提供的描述 或 "手动检查点"}
|
|
22
|
+
当前阶段:{阶段编号} — {阶段名称}
|
|
23
|
+
任务:{task_description}
|
|
24
|
+
|
|
25
|
+
已修改文件:
|
|
26
|
+
- {文件列表}
|
|
27
|
+
|
|
28
|
+
架构决策:
|
|
29
|
+
- {决策列表}
|
|
30
|
+
|
|
31
|
+
待办事项:
|
|
32
|
+
- {待办列表}
|
|
33
|
+
|
|
34
|
+
Git 状态:
|
|
35
|
+
{git status 输出摘要}
|
|
36
|
+
========================
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
3. **更新 CLAUDE.md**:
|
|
40
|
+
- 确保 `modified_files` 列表是最新的
|
|
41
|
+
- 确保 `todo_items` 列表是最新的
|
|
42
|
+
- 更新 `last_updated` 时间戳
|
|
43
|
+
- 更新 `key_context` 为当前关键上下文的摘要
|
|
44
|
+
|
|
45
|
+
4. **输出确认信息**:
|
|
46
|
+
```
|
|
47
|
+
✅ 检查点已保存。
|
|
48
|
+
|
|
49
|
+
如果后续发生上下文压缩(compaction),可以从 CLAUDE.md 恢复以下状态:
|
|
50
|
+
- 阶段:{阶段}
|
|
51
|
+
- 任务:{任务描述}
|
|
52
|
+
- 已修改 {n} 个文件
|
|
53
|
+
- {n} 项待办事项
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## 使用建议
|
|
59
|
+
|
|
60
|
+
建议在以下时机使用 `/checkpoint`:
|
|
61
|
+
- 完成一个重要步骤后
|
|
62
|
+
- 进行长对话之前(预防 compaction)
|
|
63
|
+
- 做出重要架构决策后
|
|
64
|
+
- 切换工作方向之前
|
|
65
|
+
- 任何你觉得"这些信息不能丢"的时候
|