claude-sdlc 1.0.7 → 1.3.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 +134 -42
- package/lib/installer.js +113 -11
- package/package.json +3 -2
- package/plugin.json +17 -0
- package/template/.claude/agents/sdlc-coder.md +27 -0
- package/template/.claude/agents/sdlc-reviewer.md +27 -0
- package/template/.claude/agents/sdlc-tester.md +28 -0
- package/template/.claude/hooks/check-phase-test.sh +4 -7
- package/template/.claude/hooks/check-phase-write.sh +4 -8
- package/template/.claude/hooks/file-suggestion.sh +26 -0
- package/template/.claude/hooks/permission-request.sh +83 -0
- package/template/.claude/hooks/post-tool-failure.sh +21 -0
- package/template/.claude/hooks/pre-compact.sh +40 -0
- package/template/.claude/hooks/session-end.sh +27 -0
- package/template/.claude/hooks/session-start.sh +30 -0
- package/template/.claude/hooks/statusline.sh +45 -0
- package/template/.claude/hooks/stop-check.sh +56 -0
- package/template/.claude/hooks/subagent-start.sh +31 -0
- package/template/.claude/hooks/subagent-stop.sh +27 -0
- package/template/.claude/hooks/task-completed.sh +22 -0
- package/template/.claude/hooks/user-prompt-submit.sh +18 -0
- package/template/.claude/rules/01-lifecycle-phases.md +2 -0
- package/template/.claude/rules/02-coding-standards.md +23 -0
- package/template/.claude/rules/03-testing-standards.md +10 -0
- package/template/.claude/rules/05-anti-amnesia.md +87 -31
- package/template/.claude/rules/07-parallel-agents.md +26 -4
- package/template/.claude/rules/08-chrome-integration.md +32 -0
- package/template/.claude/settings.json +165 -10
- package/template/.claude/skills/checkpoint/SKILL.md +73 -0
- package/template/.claude/skills/phase/SKILL.md +165 -0
- package/template/.claude/skills/review/SKILL.md +472 -0
- package/template/.claude/skills/status/SKILL.md +97 -0
- package/template/CLAUDE.md +17 -3
package/README.md
CHANGED
|
@@ -42,9 +42,10 @@ npx claude-sdlc uninstall
|
|
|
42
42
|
|------|---------|
|
|
43
43
|
| Claude 不走流程,直接写代码 | 六阶段强制流程:需求 → 设计 → 编码 → 测试 → 审查 → 交付 |
|
|
44
44
|
| 需要反复输入指令推进 | **自动驱动**:确认需求和设计后,编码到交付全自动 |
|
|
45
|
-
| 规范需要每次手动提醒 | CLAUDE.md + rules/ 自动加载,Hooks 运行时拦截 |
|
|
45
|
+
| 规范需要每次手动提醒 | CLAUDE.md + rules/ 自动加载,12 个 Hooks 运行时拦截 |
|
|
46
46
|
| Claude 自行加减功能 | **PRD 驱动**:严格按需求清单,每行代码对应 PRD |
|
|
47
|
-
| 长对话后遗忘规范 |
|
|
47
|
+
| 长对话后遗忘规范 | **十六层防御** + 抗压缩机制,compaction 后自动恢复 |
|
|
48
|
+
| 单线程开发效率低 | **3 个自定义 Agent** 并行编码/测试/审查 |
|
|
48
49
|
| CLAUDE.md 过长导致遵循率下降 | 精简到 ~100 行,详细规则拆到 rules/ 自动加载 |
|
|
49
50
|
|
|
50
51
|
---
|
|
@@ -67,13 +68,81 @@ P3 编码 → P4 测试 → P5 集成审查 → P6 交付 → 完成报告
|
|
|
67
68
|
|
|
68
69
|
## 核心特性
|
|
69
70
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
71
|
+
### 12 个 Hooks — 全生命周期拦截
|
|
72
|
+
|
|
73
|
+
| Hook | 类型 | 作用 |
|
|
74
|
+
|------|------|------|
|
|
75
|
+
| SessionStart | command | 会话启动/恢复时注入 SDLC 上下文 |
|
|
76
|
+
| SessionEnd | command | 会话结束时归档状态摘要 |
|
|
77
|
+
| UserPromptSubmit | command | 每次用户输入时注入阶段提醒 |
|
|
78
|
+
| PreToolUse (Write/Edit) | command | P3 前拦截代码写入 |
|
|
79
|
+
| PreToolUse (Bash) | command | P4 前拦截测试、P6 前拦截 git |
|
|
80
|
+
| PostToolUse | command | 文件修改后提醒更新状态(async) |
|
|
81
|
+
| PostToolUseFailure | command | 工具失败时注入恢复建议 |
|
|
82
|
+
| Stop | agent | 回复后自检阶段合规性 |
|
|
83
|
+
| PreCompact | agent | 压缩前自动保存状态 |
|
|
84
|
+
| SubagentStart | command | 子 Agent 注入 SDLC + PRD 上下文 |
|
|
85
|
+
| SubagentStop | command | 子 Agent 完成时验证输出质量 |
|
|
86
|
+
| TaskCompleted | command | 子任务完成时提醒验证合规 |
|
|
87
|
+
| PermissionRequest | command | 按 SDLC 阶段自动决策权限 |
|
|
88
|
+
|
|
89
|
+
### 3 个自定义 Agent — 并行开发
|
|
90
|
+
|
|
91
|
+
| Agent | 阶段 | 核心能力 |
|
|
92
|
+
|-------|------|---------|
|
|
93
|
+
| sdlc-coder | P3 | 严格按 PRD 编码,禁止 PRD 外功能 |
|
|
94
|
+
| sdlc-tester | P4 | 每条 PRD 需求至少一个测试,AAA 模式 |
|
|
95
|
+
| sdlc-reviewer | P5 | PRD 四环追溯(需求→设计→代码→测试) |
|
|
96
|
+
|
|
97
|
+
### 4 个 Skills — 斜杠命令
|
|
98
|
+
|
|
99
|
+
| 命令 | 作用 | 增强特性 |
|
|
100
|
+
|------|------|---------|
|
|
101
|
+
| `/review` | 执行当前阶段审查 | `context: fork` 隔离上下文 + 技能级 hooks |
|
|
102
|
+
| `/status` | 查看完整项目状态 | `!`command`` 动态注入实时状态 |
|
|
103
|
+
| `/phase` | 阶段管理 | `!`command`` 动态读取当前阶段 |
|
|
104
|
+
| `/checkpoint` | 手动保存状态快照 | — |
|
|
105
|
+
|
|
106
|
+
### 声明式权限控制
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
deny → .env 文件绝对禁止读写(平台层面强制)
|
|
110
|
+
allow → Read/Glob/Grep/git只读/lint 自动放行(减少弹窗)
|
|
111
|
+
ask → rm -rf / git push --force 等危险命令强制弹框确认
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### 更多特性
|
|
115
|
+
|
|
116
|
+
- **statusLine** — 终端底部实时显示 `[SDLC P3] 编码实现 ●●●○○○ 任务描述`
|
|
117
|
+
- **sandbox** — 限制网络访问域名白名单
|
|
118
|
+
- **env** — 声明式注入 `SDLC_PROJECT`/`SDLC_VERSION` 环境变量
|
|
119
|
+
- **attribution** — Git commit 自动署名
|
|
120
|
+
- **fileSuggestion** — `@` 文件补全优先显示 SDLC 文件
|
|
121
|
+
- **spinnerVerbs** — 自定义中文加载动词(审查中、编码中、测试中...)
|
|
122
|
+
- **language** — 界面语言设为中文
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## 十六层防御机制
|
|
127
|
+
|
|
128
|
+
| 层 | 机制 | 类型 | 作用 |
|
|
129
|
+
|----|------|------|------|
|
|
130
|
+
| 1 | SessionStart Hook | 主动 | 确定性注入阶段上下文,最关键防线 |
|
|
131
|
+
| 2 | CLAUDE.md + rules/ | 主动 | 规范自动加载,compaction 后重新加载 |
|
|
132
|
+
| 3 | UserPromptSubmit Hook | 主动 | 每次用户输入注入阶段提醒 |
|
|
133
|
+
| 4 | PreToolUse Hooks | 被动 | 硬拦截违规操作(exit 2) |
|
|
134
|
+
| 5 | PostToolUse Hook | 主动 | 文件修改后同步状态 |
|
|
135
|
+
| 6 | Stop Hook (agent) | 主动 | 回复后自检,可读写文件 |
|
|
136
|
+
| 7 | PreCompact Hook (agent) | 主动 | 压缩前保存状态 |
|
|
137
|
+
| 8 | SubagentStart Hook | 主动 | 子 Agent 注入 SDLC + PRD 上下文 |
|
|
138
|
+
| 9 | TaskCompleted Hook | 主动 | 子任务完成验证合规 |
|
|
139
|
+
| 10 | Permissions (deny/allow/ask) | 被动 | 声明式权限,平台层面强制 |
|
|
140
|
+
| 11 | statusLine | 被动 | 终端实时状态显示 |
|
|
141
|
+
| 12 | Skills (/status /review) | 按需 | 深度自检和审查 |
|
|
142
|
+
| 13 | SubagentStop Hook | 主动 | 子 Agent 输出质量门控 |
|
|
143
|
+
| 14 | PostToolUseFailure Hook | 主动 | 工具失败恢复指导 |
|
|
144
|
+
| 15 | PermissionRequest Hook | 被动 | 阶段感知自动权限决策 |
|
|
145
|
+
| 16 | SessionEnd Hook | 主动 | 会话结束状态归档 |
|
|
77
146
|
|
|
78
147
|
---
|
|
79
148
|
|
|
@@ -81,41 +150,59 @@ P3 编码 → P4 测试 → P5 集成审查 → P6 交付 → 完成报告
|
|
|
81
150
|
|
|
82
151
|
```
|
|
83
152
|
your-project/
|
|
84
|
-
├── CLAUDE.md
|
|
153
|
+
├── CLAUDE.md # 核心控制文件(~100行)
|
|
85
154
|
└── .claude/
|
|
86
|
-
├── settings.json
|
|
87
|
-
├──
|
|
88
|
-
|
|
89
|
-
│ ├──
|
|
90
|
-
│ ├──
|
|
91
|
-
│ ├──
|
|
92
|
-
│ ├──
|
|
93
|
-
│ ├──
|
|
94
|
-
│
|
|
95
|
-
├──
|
|
96
|
-
│
|
|
97
|
-
|
|
98
|
-
├──
|
|
99
|
-
│ ├──
|
|
100
|
-
│ ├──
|
|
101
|
-
│ ├──
|
|
102
|
-
│
|
|
103
|
-
|
|
155
|
+
├── settings.json # 12 Hooks + Permissions + Settings
|
|
156
|
+
├── project-state.md # SDLC 状态存储(活文档)
|
|
157
|
+
├── rules/ # 8 个规则文件(自动加载)
|
|
158
|
+
│ ├── 01-lifecycle-phases.md # 六阶段详细定义
|
|
159
|
+
│ ├── 02-coding-standards.md # 编码规范
|
|
160
|
+
│ ├── 03-testing-standards.md # 测试规范
|
|
161
|
+
│ ├── 04-git-workflow.md # Git 工作流
|
|
162
|
+
│ ├── 05-anti-amnesia.md # 十六层防御机制
|
|
163
|
+
│ ├── 06-review-tools.md # 审查工具链
|
|
164
|
+
│ ├── 07-parallel-agents.md # 多 Agent 并行
|
|
165
|
+
│ └── 08-chrome-integration.md # Chrome 浏览器集成
|
|
166
|
+
├── hooks/ # 12 个 Hook 脚本
|
|
167
|
+
│ ├── session-start.sh # SessionStart
|
|
168
|
+
│ ├── session-end.sh # SessionEnd
|
|
169
|
+
│ ├── user-prompt-submit.sh # UserPromptSubmit
|
|
170
|
+
│ ├── check-phase-write.sh # PreToolUse Write/Edit
|
|
171
|
+
│ ├── check-phase-test.sh # PreToolUse Bash
|
|
172
|
+
│ ├── post-tool-failure.sh # PostToolUseFailure
|
|
173
|
+
│ ├── subagent-start.sh # SubagentStart
|
|
174
|
+
│ ├── subagent-stop.sh # SubagentStop
|
|
175
|
+
│ ├── task-completed.sh # TaskCompleted
|
|
176
|
+
│ ├── permission-request.sh # PermissionRequest
|
|
177
|
+
│ ├── statusline.sh # statusLine
|
|
178
|
+
│ └── file-suggestion.sh # fileSuggestion
|
|
179
|
+
├── agents/ # 3 个自定义 Agent
|
|
180
|
+
│ ├── sdlc-coder.md # P3 编码 Agent
|
|
181
|
+
│ ├── sdlc-tester.md # P4 测试 Agent
|
|
182
|
+
│ └── sdlc-reviewer.md # P5 审查 Agent
|
|
183
|
+
├── skills/ # 4 个技能命令
|
|
184
|
+
│ ├── phase/SKILL.md # /phase
|
|
185
|
+
│ ├── status/SKILL.md # /status
|
|
186
|
+
│ ├── checkpoint/SKILL.md # /checkpoint
|
|
187
|
+
│ └── review/SKILL.md # /review
|
|
188
|
+
└── reviews/ # 审查报告持久化
|
|
104
189
|
```
|
|
105
190
|
|
|
106
191
|
---
|
|
107
192
|
|
|
108
|
-
##
|
|
193
|
+
## PermissionRequest 权限决策矩阵
|
|
109
194
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
|
113
|
-
|
|
114
|
-
|
|
|
115
|
-
|
|
|
116
|
-
|
|
|
117
|
-
|
|
|
118
|
-
|
|
|
195
|
+
PermissionRequest Hook 根据当前 SDLC 阶段自动决策工具权限:
|
|
196
|
+
|
|
197
|
+
| 工具 | P0-P2 | P3 | P4 | P5 | P6 |
|
|
198
|
+
|------|-------|----|----|----|----|
|
|
199
|
+
| Write/Edit (代码) | deny | allow | allow | allow(修复) | allow(文档) |
|
|
200
|
+
| Write/Edit (文档) | allow | allow | allow | allow | allow |
|
|
201
|
+
| Bash (git 只读) | allow | allow | allow | allow | allow |
|
|
202
|
+
| Bash (测试) | deny | deny | allow | allow | allow |
|
|
203
|
+
| Bash (git 写入) | deny | deny | deny | deny | allow |
|
|
204
|
+
| Chrome | P2 allow | deny | allow | deny | deny |
|
|
205
|
+
| Read/Glob/Grep | allow | allow | allow | allow | allow |
|
|
119
206
|
|
|
120
207
|
---
|
|
121
208
|
|
|
@@ -131,7 +218,7 @@ claude-sdlc
|
|
|
131
218
|
### Shell 脚本安装(无需 Node.js)
|
|
132
219
|
|
|
133
220
|
```bash
|
|
134
|
-
git clone https://github.com/
|
|
221
|
+
git clone https://github.com/Muqian-Sun/claude-sdlc.git
|
|
135
222
|
cd claude-sdlc
|
|
136
223
|
./install.sh /path/to/your-project
|
|
137
224
|
```
|
|
@@ -151,7 +238,9 @@ cd claude-sdlc
|
|
|
151
238
|
| 修改编码规范 | `.claude/rules/02-coding-standards.md` |
|
|
152
239
|
| 添加新规则 | `.claude/rules/` 下新增 `.md` 文件 |
|
|
153
240
|
| 调整拦截规则 | `.claude/hooks/` 下的脚本 |
|
|
154
|
-
|
|
|
241
|
+
| 修改权限矩阵 | `.claude/hooks/permission-request.sh` |
|
|
242
|
+
| 自定义 Agent | `.claude/agents/` 下修改 `.md` 文件 |
|
|
243
|
+
| 添加技能命令 | `.claude/skills/` 下新增目录和 `SKILL.md` |
|
|
155
244
|
|
|
156
245
|
---
|
|
157
246
|
|
|
@@ -161,17 +250,20 @@ cd claude-sdlc
|
|
|
161
250
|
会直接覆盖为最新版本。
|
|
162
251
|
|
|
163
252
|
**已有 settings.json 怎么办?**
|
|
164
|
-
自动智能合并 hooks
|
|
253
|
+
自动智能合并 — hooks 按 matcher 去重升级,permissions 合并不丢失,新增字段仅在用户未设置时写入。
|
|
165
254
|
|
|
166
255
|
**可以跳过阶段吗?**
|
|
167
256
|
可以,Claude 会先说明风险,确认后记录跳过原因并推进。
|
|
168
257
|
|
|
258
|
+
**从旧版本升级?**
|
|
259
|
+
直接重新运行 `npx claude-sdlc`,安装器自动合并新旧配置,不丢失用户自定义。
|
|
260
|
+
|
|
169
261
|
**如何卸载?**
|
|
170
262
|
```bash
|
|
171
263
|
npx claude-sdlc uninstall # 卸载当前目录
|
|
172
264
|
npx claude-sdlc uninstall ./my-project # 卸载指定目录
|
|
173
265
|
```
|
|
174
|
-
|
|
266
|
+
自动清除全部 SDLC 文件(CLAUDE.md、rules/、hooks/、agents/、skills/、reviews/、settings.json 中的 SDLC 配置)。用户自定义的 settings.json 字段保留。
|
|
175
267
|
|
|
176
268
|
---
|
|
177
269
|
|
package/lib/installer.js
CHANGED
|
@@ -82,7 +82,11 @@ function hookMatcherKey(group) {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
function mergeSettings(existing, template) {
|
|
85
|
-
const hookTypes = ['PreToolUse', 'PostToolUse', '
|
|
85
|
+
const hookTypes = ['PreToolUse', 'PostToolUse', 'PostToolUseFailure',
|
|
86
|
+
'Stop', 'PreCompact',
|
|
87
|
+
'SessionStart', 'SessionEnd', 'UserPromptSubmit',
|
|
88
|
+
'SubagentStart', 'SubagentStop', 'TaskCompleted',
|
|
89
|
+
'PermissionRequest'];
|
|
86
90
|
const result = JSON.parse(JSON.stringify(existing));
|
|
87
91
|
|
|
88
92
|
// 合并 $schema
|
|
@@ -129,6 +133,36 @@ function mergeSettings(existing, template) {
|
|
|
129
133
|
result.hooks[type] = merged;
|
|
130
134
|
}
|
|
131
135
|
|
|
136
|
+
// 合并 statusLine:模板有 statusLine 且用户没有 → 添加
|
|
137
|
+
if (template.statusLine && !result.statusLine) {
|
|
138
|
+
result.statusLine = JSON.parse(JSON.stringify(template.statusLine));
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// 合并 permissions:模板的 allow/deny/ask 规则追加到用户已有列表(去重)
|
|
142
|
+
if (template.permissions) {
|
|
143
|
+
if (!result.permissions) result.permissions = {};
|
|
144
|
+
for (const key of ['allow', 'deny', 'ask']) {
|
|
145
|
+
const templateRules = template.permissions[key] || [];
|
|
146
|
+
const existingRules = result.permissions[key] || [];
|
|
147
|
+
const merged = [...new Set([...existingRules, ...templateRules])];
|
|
148
|
+
if (merged.length > 0) {
|
|
149
|
+
result.permissions[key] = merged;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// 合并 permissions.defaultMode
|
|
153
|
+
if (template.permissions.defaultMode && !result.permissions.defaultMode) {
|
|
154
|
+
result.permissions.defaultMode = template.permissions.defaultMode;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// 合并新增标量字段(模板有、用户没有 → 复制)
|
|
159
|
+
const newFields = ['sandbox', 'env', 'attribution', 'fileSuggestion', 'spinnerVerbs', 'language'];
|
|
160
|
+
for (const field of newFields) {
|
|
161
|
+
if (template[field] !== undefined && result[field] === undefined) {
|
|
162
|
+
result[field] = JSON.parse(JSON.stringify(template[field]));
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
132
166
|
return result;
|
|
133
167
|
}
|
|
134
168
|
|
|
@@ -145,7 +179,7 @@ function copyFilesQuiet(srcDir, destDir, ext) {
|
|
|
145
179
|
|
|
146
180
|
function install(targetDir) {
|
|
147
181
|
const templateDir = path.join(__dirname, '..', 'template');
|
|
148
|
-
const STEPS =
|
|
182
|
+
const STEPS = 9;
|
|
149
183
|
|
|
150
184
|
// 验证
|
|
151
185
|
if (!fs.existsSync(targetDir)) {
|
|
@@ -177,6 +211,25 @@ function install(targetDir) {
|
|
|
177
211
|
const templateClaudeMd = path.join(templateDir, 'CLAUDE.md');
|
|
178
212
|
const templateContent = fs.readFileSync(templateClaudeMd, 'utf-8');
|
|
179
213
|
const isUpgrade = fs.existsSync(targetClaudeMd);
|
|
214
|
+
|
|
215
|
+
// v1.0.6→v1.0.7 迁移:旧版状态内嵌在 CLAUDE.md 中,需要提取出来
|
|
216
|
+
let migratedState = null;
|
|
217
|
+
if (isUpgrade) {
|
|
218
|
+
const oldContent = fs.readFileSync(targetClaudeMd, 'utf-8');
|
|
219
|
+
const yamlMatch = oldContent.match(/```yaml\n# === SDLC 项目状态 ===\n([\s\S]*?)```/);
|
|
220
|
+
if (yamlMatch) {
|
|
221
|
+
// 检查是否有实际数据(非空白模板)
|
|
222
|
+
const yamlBlock = yamlMatch[0];
|
|
223
|
+
const hasData = /current_phase:\s*P[1-6]/.test(yamlBlock)
|
|
224
|
+
|| /task_description:\s*"[^"]+"/.test(yamlBlock)
|
|
225
|
+
|| /modified_files:\s*\n\s*-/.test(yamlBlock)
|
|
226
|
+
|| /prd:\s*\n\s*-\s*id:/.test(yamlBlock);
|
|
227
|
+
if (hasData) {
|
|
228
|
+
migratedState = yamlBlock;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
180
233
|
fs.writeFileSync(targetClaudeMd, templateContent, 'utf-8');
|
|
181
234
|
fileLog(SYM.check, isUpgrade
|
|
182
235
|
? `CLAUDE.md ${DIM}(已更新至最新版本)${RESET}`
|
|
@@ -184,7 +237,7 @@ function install(targetDir) {
|
|
|
184
237
|
|
|
185
238
|
// Step 2: 目录结构
|
|
186
239
|
step(2, STEPS, '创建目录结构');
|
|
187
|
-
const dirs = ['rules', 'hooks', 'commands', 'reviews'];
|
|
240
|
+
const dirs = ['rules', 'hooks', 'commands', 'skills', 'reviews', 'agents'];
|
|
188
241
|
for (const dir of dirs) {
|
|
189
242
|
fs.mkdirSync(path.join(targetDir, '.claude', dir), { recursive: true });
|
|
190
243
|
fileLog(SYM.check, `.claude/${dir}/`);
|
|
@@ -196,6 +249,17 @@ function install(targetDir) {
|
|
|
196
249
|
const templateState = path.join(templateDir, '.claude', 'project-state.md');
|
|
197
250
|
if (fs.existsSync(targetState)) {
|
|
198
251
|
fileLog(SYM.check, `.claude/project-state.md ${DIM}(已有状态,跳过保护)${RESET}`);
|
|
252
|
+
} else if (migratedState) {
|
|
253
|
+
// v1.0.6→v1.0.7 迁移:将旧 CLAUDE.md 中的状态写入新的 project-state.md
|
|
254
|
+
const stateTemplate = fs.readFileSync(templateState, 'utf-8');
|
|
255
|
+
const emptyYaml = stateTemplate.match(/```yaml\n# === SDLC 项目状态 ===\n[\s\S]*?```/);
|
|
256
|
+
if (emptyYaml) {
|
|
257
|
+
const migrated = stateTemplate.replace(emptyYaml[0], migratedState);
|
|
258
|
+
fs.writeFileSync(targetState, migrated, 'utf-8');
|
|
259
|
+
} else {
|
|
260
|
+
fs.writeFileSync(targetState, stateTemplate, 'utf-8');
|
|
261
|
+
}
|
|
262
|
+
fileLog(SYM.warn, `.claude/project-state.md ${DIM}(从旧版 CLAUDE.md 迁移状态)${RESET}`);
|
|
199
263
|
} else {
|
|
200
264
|
fs.copyFileSync(templateState, targetState);
|
|
201
265
|
fileLog(SYM.check, '.claude/project-state.md');
|
|
@@ -235,8 +299,43 @@ function install(targetDir) {
|
|
|
235
299
|
);
|
|
236
300
|
fileLog(SYM.check, `${cmds.length} 个命令 — ${DIM}/phase /status /checkpoint /review${RESET}`);
|
|
237
301
|
|
|
238
|
-
// Step 7:
|
|
239
|
-
step(7, STEPS, '
|
|
302
|
+
// Step 7: Skills
|
|
303
|
+
step(7, STEPS, '安装 Skills');
|
|
304
|
+
const skillsSrcDir = path.join(templateDir, '.claude', 'skills');
|
|
305
|
+
const skillsDestDir = path.join(targetDir, '.claude', 'skills');
|
|
306
|
+
let skillCount = 0;
|
|
307
|
+
if (fs.existsSync(skillsSrcDir)) {
|
|
308
|
+
const skillDirs = fs.readdirSync(skillsSrcDir).filter(d =>
|
|
309
|
+
fs.statSync(path.join(skillsSrcDir, d)).isDirectory()
|
|
310
|
+
);
|
|
311
|
+
for (const dir of skillDirs) {
|
|
312
|
+
const destDir = path.join(skillsDestDir, dir);
|
|
313
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
314
|
+
const skillFile = path.join(skillsSrcDir, dir, 'SKILL.md');
|
|
315
|
+
if (fs.existsSync(skillFile)) {
|
|
316
|
+
fs.copyFileSync(skillFile, path.join(destDir, 'SKILL.md'));
|
|
317
|
+
skillCount++;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
fileLog(SYM.check, `${skillCount} 个 Skills — ${DIM}/phase /status /checkpoint /review${RESET}`);
|
|
322
|
+
|
|
323
|
+
// Step 8: 自定义 Agents
|
|
324
|
+
step(8, STEPS, '安装自定义 Agents');
|
|
325
|
+
const agentsSrcDir = path.join(templateDir, '.claude', 'agents');
|
|
326
|
+
const agentsDestDir = path.join(targetDir, '.claude', 'agents');
|
|
327
|
+
let agentCount = 0;
|
|
328
|
+
if (fs.existsSync(agentsSrcDir)) {
|
|
329
|
+
const agentFiles = fs.readdirSync(agentsSrcDir).filter(f => f.endsWith('.md'));
|
|
330
|
+
for (const file of agentFiles) {
|
|
331
|
+
fs.copyFileSync(path.join(agentsSrcDir, file), path.join(agentsDestDir, file));
|
|
332
|
+
agentCount++;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
fileLog(SYM.check, `${agentCount} 个 Agents — ${DIM}sdlc-coder, sdlc-tester, sdlc-reviewer${RESET}`);
|
|
336
|
+
|
|
337
|
+
// Step 9: settings.json
|
|
338
|
+
step(9, STEPS, '配置 Hooks + Permissions + Settings');
|
|
240
339
|
const targetSettings = path.join(targetDir, '.claude', 'settings.json');
|
|
241
340
|
const sourceSettings = path.join(templateDir, '.claude', 'settings.json');
|
|
242
341
|
|
|
@@ -260,16 +359,18 @@ function install(targetDir) {
|
|
|
260
359
|
resultBanner('安装完成');
|
|
261
360
|
|
|
262
361
|
// 文件树
|
|
263
|
-
console.log(` ${DIM}已安装 ${rules.length + hookCount + cmds.length + 3} 个文件:${RESET}`);
|
|
362
|
+
console.log(` ${DIM}已安装 ${rules.length + hookCount + cmds.length + skillCount + agentCount + 3} 个文件:${RESET}`);
|
|
264
363
|
blank();
|
|
265
364
|
console.log(` ${BOLD}${path.basename(targetDir)}/${RESET}`);
|
|
266
365
|
console.log(` ${SYM.tee} CLAUDE.md ${DIM}核心控制文件(升级时自动更新)${RESET}`);
|
|
267
366
|
console.log(` ${SYM.corner} ${BOLD}.claude/${RESET}`);
|
|
268
367
|
console.log(` ${SYM.tee} project-state.md ${DIM}项目状态(升级时保留)${RESET}`);
|
|
269
|
-
console.log(` ${SYM.tee} settings.json ${DIM}Hooks 配置${RESET}`);
|
|
368
|
+
console.log(` ${SYM.tee} settings.json ${DIM}Hooks + Permissions 配置${RESET}`);
|
|
270
369
|
console.log(` ${SYM.tee} ${BOLD}rules/${RESET} ${DIM}${rules.length} 个规则 (自动加载)${RESET}`);
|
|
271
370
|
console.log(` ${SYM.tee} ${BOLD}hooks/${RESET} ${DIM}${hookCount} 个拦截脚本${RESET}`);
|
|
272
|
-
console.log(` ${SYM.tee} ${BOLD}
|
|
371
|
+
console.log(` ${SYM.tee} ${BOLD}skills/${RESET} ${DIM}${skillCount} 个 Skills${RESET}`);
|
|
372
|
+
console.log(` ${SYM.tee} ${BOLD}commands/${RESET} ${DIM}${cmds.length} 个斜杠命令 (fallback)${RESET}`);
|
|
373
|
+
console.log(` ${SYM.tee} ${BOLD}agents/${RESET} ${DIM}${agentCount} 个自定义 Agents${RESET}`);
|
|
273
374
|
console.log(` ${SYM.corner} ${BOLD}reviews/${RESET} ${DIM}审查报告${RESET}`);
|
|
274
375
|
blank();
|
|
275
376
|
|
|
@@ -325,7 +426,7 @@ function uninstall(targetDir) {
|
|
|
325
426
|
}
|
|
326
427
|
|
|
327
428
|
// .claude 子目录(全部删除)
|
|
328
|
-
const removeDirs = ['rules', 'hooks', 'commands', 'reviews'];
|
|
429
|
+
const removeDirs = ['rules', 'hooks', 'commands', 'skills', 'reviews', 'agents'];
|
|
329
430
|
for (const dir of removeDirs) {
|
|
330
431
|
const dirPath = path.join(targetDir, '.claude', dir);
|
|
331
432
|
if (fs.existsSync(dirPath)) {
|
|
@@ -341,8 +442,9 @@ function uninstall(targetDir) {
|
|
|
341
442
|
if (fs.existsSync(settingsPath)) {
|
|
342
443
|
try {
|
|
343
444
|
const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
|
|
344
|
-
|
|
345
|
-
|
|
445
|
+
for (const key of ['hooks', 'statusLine', 'permissions', 'sandbox', 'env',
|
|
446
|
+
'attribution', 'fileSuggestion', 'spinnerVerbs', 'language']) {
|
|
447
|
+
if (settings[key]) delete settings[key];
|
|
346
448
|
}
|
|
347
449
|
if (settings.$schema === 'https://json.schemastore.org/claude-code-settings.json') {
|
|
348
450
|
delete settings.$schema;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-sdlc",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "让 Claude Code 严格按 SDLC 规范开发 — 一条命令安装",
|
|
5
5
|
"bin": {
|
|
6
6
|
"claude-sdlc": "./bin/cli.js"
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
"files": [
|
|
9
9
|
"bin/",
|
|
10
10
|
"lib/",
|
|
11
|
-
"template/"
|
|
11
|
+
"template/",
|
|
12
|
+
"plugin.json"
|
|
12
13
|
],
|
|
13
14
|
"keywords": [
|
|
14
15
|
"claude-code",
|
package/plugin.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "claude-sdlc",
|
|
3
|
+
"version": "1.3.0",
|
|
4
|
+
"description": "SDLC Enforcer — 让 Claude Code 严格按 SDLC 规范开发",
|
|
5
|
+
"author": "沐谦",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"provides": {
|
|
8
|
+
"hooks": 12,
|
|
9
|
+
"skills": 4,
|
|
10
|
+
"agents": 3,
|
|
11
|
+
"rules": 8
|
|
12
|
+
},
|
|
13
|
+
"install": {
|
|
14
|
+
"method": "npx",
|
|
15
|
+
"command": "npx claude-sdlc"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sdlc-coder
|
|
3
|
+
description: "SDLC P3 编码实现专用 Agent。严格按 PRD 和设计方案编写代码,遵守编码规范。用于并行编码独立模块。"
|
|
4
|
+
tools:
|
|
5
|
+
- Read
|
|
6
|
+
- Write
|
|
7
|
+
- Edit
|
|
8
|
+
- Glob
|
|
9
|
+
- Grep
|
|
10
|
+
- Bash
|
|
11
|
+
disallowedTools:
|
|
12
|
+
- Task
|
|
13
|
+
permissionMode: acceptEdits
|
|
14
|
+
maxTurns: 15
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
你是 SDLC 编码实现专用 Agent(P3 阶段)。
|
|
18
|
+
|
|
19
|
+
## 核心约束
|
|
20
|
+
- **严格按 PRD 编码**:每写一行代码自问"对应 PRD 哪条需求?"答不上来就不写
|
|
21
|
+
- **禁止添加 PRD 外功能**
|
|
22
|
+
- 编码规范:函数 ≤50 行、嵌套 ≤3 层、命名遵循语言约定
|
|
23
|
+
- Bash 仅用于 lint/build,禁止执行测试和 git 提交
|
|
24
|
+
- **控制范围**:每次只实现 1-2 个 PRD 需求对应的模块,不要贪多
|
|
25
|
+
|
|
26
|
+
## 输出要求
|
|
27
|
+
完成后报告:(1) 已创建/修改的文件列表 (2) 对应的 PRD 需求编号 (3) 关键实现决策
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sdlc-reviewer
|
|
3
|
+
description: "SDLC P5 集成审查专用 Agent。执行跨模块全局审查和 PRD 四环追溯。用于并行审查不同维度。"
|
|
4
|
+
tools:
|
|
5
|
+
- Read
|
|
6
|
+
- Glob
|
|
7
|
+
- Grep
|
|
8
|
+
- Edit
|
|
9
|
+
disallowedTools:
|
|
10
|
+
- Bash
|
|
11
|
+
- Write
|
|
12
|
+
- Task
|
|
13
|
+
permissionMode: default
|
|
14
|
+
maxTurns: 10
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
你是 SDLC 集成审查专用 Agent(P5 阶段)。
|
|
18
|
+
|
|
19
|
+
## 核心约束
|
|
20
|
+
- PRD 四环追溯:需求 → 设计 → 代码:行号 → 测试,无断链
|
|
21
|
+
- 检查无 PRD 外变更
|
|
22
|
+
- Edit 仅用于修复审查问题
|
|
23
|
+
- 禁止 Bash/Write
|
|
24
|
+
- **高效审查**:聚焦分配的审查维度,不要展开无关分析
|
|
25
|
+
|
|
26
|
+
## 输出要求
|
|
27
|
+
审查报告:(1) 每条 PRD 四环追溯 (2) 全局一致性 (3) 安全性 (4) 问题及严重程度
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sdlc-tester
|
|
3
|
+
description: "SDLC P4 测试验证专用 Agent。按 PRD 需求编写和执行测试,确保覆盖率达标。用于并行测试独立模块。"
|
|
4
|
+
tools:
|
|
5
|
+
- Read
|
|
6
|
+
- Write
|
|
7
|
+
- Edit
|
|
8
|
+
- Glob
|
|
9
|
+
- Grep
|
|
10
|
+
- Bash
|
|
11
|
+
disallowedTools:
|
|
12
|
+
- Task
|
|
13
|
+
permissionMode: acceptEdits
|
|
14
|
+
maxTurns: 15
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
你是 SDLC 测试验证专用 Agent(P4 阶段)。
|
|
18
|
+
|
|
19
|
+
## 核心约束
|
|
20
|
+
- 每条 PRD 需求至少一个测试用例
|
|
21
|
+
- 遵循 AAA 模式(Arrange-Act-Assert)
|
|
22
|
+
- 命名格式:"should X when Y"
|
|
23
|
+
- 覆盖率目标:行 ≥80%,关键逻辑 ≥90%,分支 ≥70%
|
|
24
|
+
- 禁止 git 提交
|
|
25
|
+
- **控制范围**:每次只为 1-2 个模块编写测试,不要贪多
|
|
26
|
+
|
|
27
|
+
## 输出要求
|
|
28
|
+
完成后报告:(1) 测试文件路径 (2) PRD → 测试映射表 (3) 测试执行结果
|
|
@@ -25,15 +25,12 @@ fi
|
|
|
25
25
|
# 读取项目状态
|
|
26
26
|
# ==============================
|
|
27
27
|
|
|
28
|
+
# 读取当前阶段(文件优先,环境变量兜底)
|
|
28
29
|
STATE_FILE="${CLAUDE_PROJECT_DIR:-.}/.claude/project-state.md"
|
|
29
|
-
|
|
30
|
-
#
|
|
31
|
-
if [ ! -f "$STATE_FILE" ]; then
|
|
32
|
-
exit 0
|
|
30
|
+
if [ -f "$STATE_FILE" ]; then
|
|
31
|
+
CURRENT_PHASE=$(sed -n 's/^current_phase:[[:space:]]*\([^[:space:]#]*\).*/\1/p' "$STATE_FILE" 2>/dev/null | head -1)
|
|
33
32
|
fi
|
|
34
|
-
|
|
35
|
-
# 读取当前阶段 — 兼容 macOS(不使用 grep -oP)
|
|
36
|
-
CURRENT_PHASE=$(sed -n 's/^current_phase:[[:space:]]*\([^[:space:]#]*\).*/\1/p' "$STATE_FILE" 2>/dev/null | head -1)
|
|
33
|
+
CURRENT_PHASE="${CURRENT_PHASE:-$SDLC_PHASE}"
|
|
37
34
|
|
|
38
35
|
if [ -z "$CURRENT_PHASE" ]; then
|
|
39
36
|
exit 0
|
|
@@ -29,16 +29,12 @@ if echo "$FILE_PATH" | grep -qiE "$DOC_EXTENSIONS"; then
|
|
|
29
29
|
exit 0
|
|
30
30
|
fi
|
|
31
31
|
|
|
32
|
-
#
|
|
32
|
+
# 读取当前阶段(文件优先,环境变量兜底)
|
|
33
33
|
STATE_FILE="${CLAUDE_PROJECT_DIR:-.}/.claude/project-state.md"
|
|
34
|
-
|
|
35
|
-
#
|
|
36
|
-
if [ ! -f "$STATE_FILE" ]; then
|
|
37
|
-
exit 0
|
|
34
|
+
if [ -f "$STATE_FILE" ]; then
|
|
35
|
+
CURRENT_PHASE=$(sed -n 's/^current_phase:[[:space:]]*\([^[:space:]#]*\).*/\1/p' "$STATE_FILE" 2>/dev/null | head -1)
|
|
38
36
|
fi
|
|
39
|
-
|
|
40
|
-
# 读取当前阶段 — 兼容 macOS (BSD sed)
|
|
41
|
-
CURRENT_PHASE=$(sed -n 's/^current_phase:[[:space:]]*\([^[:space:]#]*\).*/\1/p' "$STATE_FILE" 2>/dev/null | head -1)
|
|
37
|
+
CURRENT_PHASE="${CURRENT_PHASE:-$SDLC_PHASE}"
|
|
42
38
|
|
|
43
39
|
# 如果无法确定阶段,默认放行(容错)
|
|
44
40
|
if [ -z "$CURRENT_PHASE" ]; then
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# fileSuggestion — @ 文件补全,优先 SDLC 文件
|
|
3
|
+
# 接收 stdin JSON: {"query": "..."}
|
|
4
|
+
# 输出:每行一个文件路径(最多 15 行)
|
|
5
|
+
|
|
6
|
+
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-.}"
|
|
7
|
+
|
|
8
|
+
# SDLC 核心文件(始终优先显示)
|
|
9
|
+
SDLC_FILES=(
|
|
10
|
+
".claude/project-state.md"
|
|
11
|
+
"CLAUDE.md"
|
|
12
|
+
".claude/settings.json"
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
for f in "${SDLC_FILES[@]}"; do
|
|
16
|
+
[ -f "$PROJECT_DIR/$f" ] && echo "$f"
|
|
17
|
+
done
|
|
18
|
+
|
|
19
|
+
# SDLC 规则和审查文件
|
|
20
|
+
for f in "$PROJECT_DIR"/.claude/rules/*.md; do
|
|
21
|
+
[ -f "$f" ] && echo ".claude/rules/$(basename "$f")"
|
|
22
|
+
done
|
|
23
|
+
|
|
24
|
+
for f in "$PROJECT_DIR"/.claude/reviews/*.md; do
|
|
25
|
+
[ -f "$f" ] && echo ".claude/reviews/$(basename "$f")"
|
|
26
|
+
done | tail -5
|