prd-workflow-cli 1.4.0 → 2.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/.agent/workflows/prd-a1-scan.md +133 -0
- package/.agent/workflows/prd-a2ui-guide.md +6 -6
- package/.agent/workflows/prd-b-planning.md +135 -0
- package/.agent/workflows/prd-it-biz.md +56 -0
- package/.agent/workflows/prd-it-dev.md +163 -0
- package/.agent/workflows/prd-r2-review.md +104 -409
- package/.antigravity/rules.md +50 -265
- package/.cursorrules +57 -371
- package/GUIDE.md +147 -240
- package/README.md +170 -337
- package/bin/prd-cli.js +19 -12
- package/commands/baseline.js +174 -293
- package/commands/freeze-checks.js +424 -0
- package/commands/init.js +97 -162
- package/commands/it.js +286 -0
- package/commands/iteration.js +7 -91
- package/commands/planning.js +149 -517
- package/commands/review.js +78 -50
- package/commands/status.js +29 -38
- package/commands/upgrade.js +20 -0
- package/commands/version.js +222 -200
- package/package.json +2 -2
- package/rules/index.json +26 -27
- package/rules/schemas/rules.schema.json +1 -2
- package/templates/it-biz.md +141 -0
- package/templates/it-dev.md +237 -0
- package/templates//344/270/232/345/212/241/351/234/200/346/261/202.md +141 -0
- package/templates//346/212/200/346/234/257/350/247/204/346/240/274.md +237 -0
- package/.agent/workflows/prd-b1-planning-draft.md +0 -614
- package/.agent/workflows/prd-b2-planning-breakdown.md +0 -828
- package/.agent/workflows/prd-c1-requirement-list.md +0 -286
- package/.agent/workflows/prd-r1-review.md +0 -503
package/commands/version.js
CHANGED
|
@@ -3,6 +3,7 @@ const path = require('path');
|
|
|
3
3
|
const chalk = require('chalk');
|
|
4
4
|
const confirm = require('./confirm');
|
|
5
5
|
const dialog = require('./dialog');
|
|
6
|
+
const { runVersionFreezeChecks } = require('./freeze-checks');
|
|
6
7
|
|
|
7
8
|
module.exports = async function (action, type, options = {}) {
|
|
8
9
|
const configPath = path.join(process.cwd(), '.prd-config.json');
|
|
@@ -36,6 +37,17 @@ async function createVersionDoc(type, config, configPath) {
|
|
|
36
37
|
`第${String(config.currentIteration).padStart(2, '0')}轮迭代`
|
|
37
38
|
);
|
|
38
39
|
|
|
40
|
+
// 拦截废弃的文档类型
|
|
41
|
+
if (type === 'C0') {
|
|
42
|
+
console.log(chalk.red('❌ C0 已废弃。请直接创建 IT 用户故事。'));
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (type === 'C1') {
|
|
46
|
+
console.log(chalk.red('❌ C1 已废弃。请使用 "prd it create" 替代。'));
|
|
47
|
+
console.log(chalk.cyan('运行: prd it create "需求名称"'));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
39
51
|
// C 类文档必须先有 B3
|
|
40
52
|
const b3Path = path.join(iterationDir, 'B3_规划冻结归档.md');
|
|
41
53
|
if (!await fs.pathExists(b3Path)) {
|
|
@@ -64,13 +76,13 @@ async function createVersionDoc(type, config, configPath) {
|
|
|
64
76
|
return;
|
|
65
77
|
}
|
|
66
78
|
|
|
67
|
-
// C1
|
|
79
|
+
// C1 现在已包含版本范围声明(原 C0 内容),不再强制要求先创建 C0
|
|
80
|
+
// 但检查 C0 是否存在,如果存在则提示已有
|
|
68
81
|
if (type === 'C1') {
|
|
69
82
|
const c0Path = path.join(iterationDir, 'C0_版本范围声明.md');
|
|
70
|
-
if (
|
|
71
|
-
console.log(chalk.
|
|
72
|
-
console.log('
|
|
73
|
-
return;
|
|
83
|
+
if (await fs.pathExists(c0Path)) {
|
|
84
|
+
console.log(chalk.cyan('ℹ️ 检测到 C0 已存在,C1 已包含版本范围声明部分'));
|
|
85
|
+
console.log(chalk.gray(' 提示:新版 C1 已合并 C0 内容,你可以直接在 C1 中填写版本范围\n'));
|
|
74
86
|
}
|
|
75
87
|
}
|
|
76
88
|
|
|
@@ -101,35 +113,31 @@ async function createVersionDoc(type, config, configPath) {
|
|
|
101
113
|
console.log('2. 创建 C1: prd version create C1');
|
|
102
114
|
} else if (type === 'C1') {
|
|
103
115
|
console.log(chalk.bold('⚠️ 重要提醒:\n'));
|
|
116
|
+
console.log(chalk.green('📋 新版 C1 已包含版本范围声明(原 C0 内容)'));
|
|
117
|
+
console.log(chalk.gray(' 无需单独创建 C0,直接在 C1 中填写版本范围和详细需求\n'));
|
|
118
|
+
|
|
104
119
|
console.log(chalk.yellow('【PM 职责】'));
|
|
105
|
-
console.log('-
|
|
106
|
-
console.log('-
|
|
120
|
+
console.log('- 填写版本范围声明(第 1 章节)');
|
|
121
|
+
console.log('- 确认需求是否准确完整');
|
|
122
|
+
console.log('- 定义验收标准\n');
|
|
107
123
|
|
|
108
124
|
console.log(chalk.cyan('【AI 职责】'));
|
|
109
|
-
console.log('-
|
|
110
|
-
console.log('-
|
|
125
|
+
console.log('- 基于 B2 拆分需求清单');
|
|
126
|
+
console.log('- 校验需求可验证性');
|
|
111
127
|
console.log('- 标注来源关系\n');
|
|
112
128
|
|
|
113
129
|
console.log(chalk.red('【AI 禁止】'));
|
|
114
|
-
console.log('- ❌
|
|
130
|
+
console.log('- ❌ 引入 B3 规划外需求\n');
|
|
115
131
|
|
|
116
132
|
console.log(chalk.bold('下一步:'));
|
|
117
|
-
console.log('1. PM 填写 C1_版本需求清单.md');
|
|
118
|
-
console.log('2.
|
|
133
|
+
console.log('1. PM 填写 C1_版本需求清单.md(包含版本范围 + 详细需求)');
|
|
134
|
+
console.log('2. 完成后执行冻结: prd version freeze');
|
|
119
135
|
console.log('');
|
|
120
|
-
console.log(chalk.bold.
|
|
121
|
-
console.log(chalk.bold.
|
|
122
|
-
console.log(chalk.bold.
|
|
136
|
+
console.log(chalk.bold.green('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
|
|
137
|
+
console.log(chalk.bold.green('✨ 简化流程:C1 填写完成后直接运行 prd version freeze'));
|
|
138
|
+
console.log(chalk.bold.green(' 程序会自动执行 R2 审视,通过后完成冻结'));
|
|
139
|
+
console.log(chalk.bold.green('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
|
|
123
140
|
console.log('');
|
|
124
|
-
console.log(chalk.yellow(' R2 审视将检查:'));
|
|
125
|
-
console.log(' 1. ✅ 一致性检查:C1 是否忠实于 B3/B2/C0');
|
|
126
|
-
console.log(' 2. ✅ 范围检查:是否有超出当前版本的需求');
|
|
127
|
-
console.log(' 3. ✅ 用户视角审查:站在用户角度评估需求');
|
|
128
|
-
console.log(' - 用户感知是否良好?');
|
|
129
|
-
console.log(' - 是否解决了用户真正的问题?');
|
|
130
|
-
console.log(' - 用户使用时会满意吗?');
|
|
131
|
-
console.log('');
|
|
132
|
-
console.log(chalk.gray('提示:没有 R2 审视报告,无法执行 prd version freeze'));
|
|
133
141
|
} else if (type === 'C2') {
|
|
134
142
|
console.log(chalk.bold('⚠️ 重要提醒:\n'));
|
|
135
143
|
console.log(chalk.yellow('【C2 用途】'));
|
|
@@ -159,40 +167,44 @@ async function freezeVersion(config, configPath, options = {}) {
|
|
|
159
167
|
`第${String(config.currentIteration).padStart(2, '0')}轮迭代`
|
|
160
168
|
);
|
|
161
169
|
|
|
162
|
-
//
|
|
163
|
-
const b3Path = path.join(iterationDir, 'B3_规划冻结归档.md');
|
|
164
|
-
const c0Path = path.join(iterationDir, 'C0_版本范围声明.md');
|
|
165
|
-
const c1Path = path.join(iterationDir, 'C1_版本需求清单.md');
|
|
170
|
+
// ===== 新流程:自动执行前置检查 =====
|
|
166
171
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
172
|
+
// 支持 --force 跳过检查
|
|
173
|
+
if (options.force) {
|
|
174
|
+
console.log(chalk.yellow('\n⚠️ 使用 --force 跳过前置检查\n'));
|
|
175
|
+
} else {
|
|
176
|
+
// 执行自动检查(包含 R2 审视)
|
|
177
|
+
const checkResult = await runVersionFreezeChecks(iterationDir);
|
|
178
|
+
|
|
179
|
+
if (!checkResult.pass) {
|
|
180
|
+
console.log(chalk.yellow('💡 提示:解决以上问题后重新运行 prd version freeze'));
|
|
181
|
+
console.log(chalk.gray(' 或使用 prd version freeze --force 强制跳过检查(不推荐)\n'));
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
170
184
|
}
|
|
171
185
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
186
|
+
// ===== 检查通过,继续冻结流程 =====
|
|
187
|
+
|
|
188
|
+
// 检查规划冻结是否存在(支持新旧文件名)
|
|
189
|
+
let freezePath = path.join(iterationDir, '规划冻结.md');
|
|
190
|
+
if (!await fs.pathExists(freezePath)) {
|
|
191
|
+
freezePath = path.join(iterationDir, 'B3_规划冻结归档.md');
|
|
175
192
|
}
|
|
176
193
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
console.log(chalk.red('✗ 请先完成 R2 版本审视'));
|
|
181
|
-
console.log('运行: prd review r2');
|
|
194
|
+
if (!await fs.pathExists(freezePath)) {
|
|
195
|
+
console.log(chalk.red('✗ 请先完成规划冻结'));
|
|
196
|
+
console.log('运行: prd plan freeze');
|
|
182
197
|
return;
|
|
183
198
|
}
|
|
184
199
|
|
|
185
|
-
//
|
|
186
|
-
const
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
if (!hasPassed) {
|
|
190
|
-
console.log(chalk.red('✗ R2 审视未通过,不能冻结版本'));
|
|
191
|
-
console.log(chalk.yellow('请修改 C0/C1 后重新执行 R2 审视'));
|
|
200
|
+
// 检查 IT 是否存在
|
|
201
|
+
const itDirCheck = path.join(iterationDir, 'IT');
|
|
202
|
+
if (!await fs.pathExists(itDirCheck)) {
|
|
203
|
+
console.log(chalk.red('✗ 请先创建 IT 用户故事'));
|
|
192
204
|
return;
|
|
193
205
|
}
|
|
194
206
|
|
|
195
|
-
//
|
|
207
|
+
// PM 确认冻结
|
|
196
208
|
let pmSignature = null;
|
|
197
209
|
if (options.pmConfirmed && options.pmSignature) {
|
|
198
210
|
console.log(chalk.green(`✓ PM 已在对话中确认版本冻结,签名: ${options.pmSignature}`));
|
|
@@ -207,65 +219,82 @@ async function freezeVersion(config, configPath, options = {}) {
|
|
|
207
219
|
return;
|
|
208
220
|
}
|
|
209
221
|
|
|
210
|
-
// ⭐ 读取
|
|
211
|
-
console.log(chalk.gray('正在从
|
|
212
|
-
|
|
213
|
-
const
|
|
214
|
-
const
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
let
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
// 提取 R2 审视摘要
|
|
233
|
-
let r2Summary = '';
|
|
234
|
-
const r2Sections = ['版本目标一致性', '版本范围偏移检查', '规划覆盖完整性', '需求粒度成熟度', '进入执行准备度'];
|
|
235
|
-
for (const section of r2Sections) {
|
|
236
|
-
const sectionContent = extractSection(r2Content, section);
|
|
237
|
-
if (sectionContent && sectionContent.length > 10) {
|
|
238
|
-
r2Summary += `- ${section}: ${sectionContent.substring(0, 80)}...\n`;
|
|
222
|
+
// ⭐ 读取 IT 内容,提取关键信息
|
|
223
|
+
console.log(chalk.gray('正在从 IT 文档提取关键信息...'));
|
|
224
|
+
|
|
225
|
+
const itDir = path.join(iterationDir, 'IT');
|
|
226
|
+
const itFolders = (await fs.readdir(itDir)).filter(name => name.startsWith('IT-'));
|
|
227
|
+
|
|
228
|
+
let itSummaries = '';
|
|
229
|
+
let totalReqCount = itFolders.length;
|
|
230
|
+
let p0Count = 0;
|
|
231
|
+
let p1Count = 0;
|
|
232
|
+
let p2Count = 0;
|
|
233
|
+
let versionGoal = '';
|
|
234
|
+
|
|
235
|
+
for (const folder of itFolders) {
|
|
236
|
+
const itPath = path.join(itDir, folder);
|
|
237
|
+
const itId = folder.split('-').slice(0, 2).join('-');
|
|
238
|
+
|
|
239
|
+
// 读取业务需求文档(支持新旧文件名)
|
|
240
|
+
let bizPath = path.join(itPath, '业务需求.md');
|
|
241
|
+
if (!await fs.pathExists(bizPath)) {
|
|
242
|
+
bizPath = path.join(itPath, `${itId}-BIZ.md`);
|
|
239
243
|
}
|
|
244
|
+
let bizContent = '';
|
|
245
|
+
if (await fs.pathExists(bizPath)) {
|
|
246
|
+
bizContent = await fs.readFile(bizPath, 'utf-8');
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// 提取 IT 标题
|
|
250
|
+
const titleMatch = bizContent.match(/^# (IT-\d+ .*?) -/);
|
|
251
|
+
const title = titleMatch ? titleMatch[1] : folder;
|
|
252
|
+
|
|
253
|
+
// 提取优先级
|
|
254
|
+
if (/P0/i.test(bizContent)) p0Count++;
|
|
255
|
+
else if (/P1/i.test(bizContent)) p1Count++;
|
|
256
|
+
else p2Count++; // 默认为 P2
|
|
257
|
+
|
|
258
|
+
// 提取用户故事摘要
|
|
259
|
+
const storyMatch = bizContent.match(/### 1. 用户故事\s*\n([\s\S]*?)(?=\n##|$)/);
|
|
260
|
+
const story = storyMatch ? storyMatch[1].trim().split('\n')[0] : '(无在 BIZ 中找到用户故事)';
|
|
261
|
+
|
|
262
|
+
itSummaries += `### ${title}\n\n`;
|
|
263
|
+
itSummaries += `**用户故事**: ${story}\n\n`;
|
|
264
|
+
itSummaries += `**文档位置**: IT/${folder}/\n\n`;
|
|
240
265
|
}
|
|
241
|
-
if (!r2Summary) {
|
|
242
|
-
r2Summary = '(请参考 R2_版本审视报告.md)';
|
|
243
|
-
}
|
|
244
266
|
|
|
245
|
-
//
|
|
246
|
-
const
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
267
|
+
// 从规划冻结提取版本目标
|
|
268
|
+
const freezeContent = await fs.readFile(freezePath, 'utf-8');
|
|
269
|
+
versionGoal = extractSection(freezeContent, '核心问题') || '请参考规划冻结文档';
|
|
270
|
+
|
|
271
|
+
// 审视归档说明
|
|
272
|
+
const reviewSummary = '本次冻结执行了自动化版本审视,检查了所有 IT 文档的完整性与一致性。';
|
|
273
|
+
|
|
274
|
+
// 生成版本发布文档
|
|
275
|
+
const releaseTemplate = getReleaseTemplate(pmSignature, {
|
|
276
|
+
versionGoal,
|
|
277
|
+
totalReqCount,
|
|
250
278
|
p0Count,
|
|
251
279
|
p1Count,
|
|
252
280
|
p2Count,
|
|
253
|
-
|
|
281
|
+
itSummaries,
|
|
282
|
+
reviewSummary
|
|
254
283
|
});
|
|
255
|
-
const
|
|
256
|
-
await fs.writeFile(
|
|
284
|
+
const releasePath = path.join(iterationDir, '版本发布.md');
|
|
285
|
+
await fs.writeFile(releasePath, releaseTemplate);
|
|
257
286
|
|
|
258
287
|
// 记录 PM 决策和文档创建
|
|
259
|
-
await dialog.logPMConfirmation('version', '
|
|
288
|
+
await dialog.logPMConfirmation('version', 'freeze', 'approved',
|
|
260
289
|
`PM签名: ${pmSignature}, 版本冻结`
|
|
261
290
|
);
|
|
262
|
-
await dialog.logDocumentCreation('version', '
|
|
291
|
+
await dialog.logDocumentCreation('version', '版本发布', releasePath);
|
|
263
292
|
|
|
264
|
-
console.log(chalk.green('\n✓
|
|
265
|
-
console.log(chalk.cyan(`文件位置: ${
|
|
293
|
+
console.log(chalk.green('\n✓ 版本发布.md 创建成功!'));
|
|
294
|
+
console.log(chalk.cyan(`文件位置: ${releasePath}\n`));
|
|
266
295
|
|
|
267
|
-
console.log(chalk.bold.green('🎉
|
|
268
|
-
console.log(chalk.bold('✅
|
|
296
|
+
console.log(chalk.bold.green('🎉 版本已冻结!产品需求阶段完成!\n'));
|
|
297
|
+
console.log(chalk.bold('✅ 本轮迭代已完成,可以:'));
|
|
269
298
|
console.log('1. 将冻结的需求交付给研发团队');
|
|
270
299
|
console.log('2. 开始下一轮迭代: prd iteration new');
|
|
271
300
|
console.log('3. 查看项目状态: prd status');
|
|
@@ -419,31 +448,66 @@ function getC1Template() {
|
|
|
419
448
|
## 文档说明
|
|
420
449
|
|
|
421
450
|
**目的**:
|
|
451
|
+
- 声明本版本的范围边界
|
|
422
452
|
- 详细列出所有版本需求
|
|
423
453
|
- 定义验收标准
|
|
424
454
|
- 作为研发的输入
|
|
425
455
|
|
|
426
456
|
**填写要求**:
|
|
427
|
-
-
|
|
457
|
+
- 版本范围必须基于 B3 冻结的规划
|
|
458
|
+
- 每个需求必须可在 B2 中找到来源
|
|
428
459
|
- 必须有明确的验收条件
|
|
429
460
|
- 禁止引入规划外的需求
|
|
430
461
|
|
|
431
462
|
---
|
|
432
463
|
|
|
433
|
-
## 1.
|
|
464
|
+
## 1. 版本范围声明
|
|
465
|
+
|
|
466
|
+
### 1.1 版本定位
|
|
467
|
+
|
|
468
|
+
**版本编号**: v______
|
|
469
|
+
**计划发布时间**: ______
|
|
470
|
+
|
|
471
|
+
**本版本解决的核心问题**:
|
|
472
|
+
<!-- 引用 B1/B3 中的规划目标 -->
|
|
473
|
+
|
|
474
|
+
### 1.2 版本范围
|
|
475
|
+
|
|
476
|
+
**本版本包含的功能**:
|
|
477
|
+
1.
|
|
478
|
+
2.
|
|
479
|
+
3.
|
|
480
|
+
|
|
481
|
+
**对应 B2 中的需求项**:
|
|
482
|
+
- 需求项 #__: ______
|
|
483
|
+
- 需求项 #__: ______
|
|
484
|
+
|
|
485
|
+
**本版本明确不包含**:
|
|
486
|
+
1.
|
|
487
|
+
2.
|
|
488
|
+
3.
|
|
489
|
+
|
|
490
|
+
**不包含的原因**:
|
|
491
|
+
- 延后到后续版本
|
|
492
|
+
- 不在 B3 规划范围
|
|
493
|
+
- 资源/时间限制
|
|
494
|
+
|
|
495
|
+
---
|
|
496
|
+
|
|
497
|
+
## 2. 详细需求清单
|
|
434
498
|
|
|
435
|
-
###
|
|
499
|
+
### REQ-001 需求标题
|
|
436
500
|
|
|
437
|
-
**需求标题**:
|
|
438
501
|
**需求编号**: REQ-001
|
|
439
|
-
**来源**: B2 需求项 #__
|
|
502
|
+
**来源**: B2 需求项 #__
|
|
503
|
+
**优先级**: P0 / P1 / P2
|
|
504
|
+
|
|
505
|
+
**需求背景**:
|
|
506
|
+
<!-- 用户痛点/业务目标 -->
|
|
440
507
|
|
|
441
508
|
**需求描述**:
|
|
442
509
|
<!-- 详细描述需求 -->
|
|
443
510
|
|
|
444
|
-
**业务目标**:
|
|
445
|
-
<!-- 该需求解决什么业务问题 -->
|
|
446
|
-
|
|
447
511
|
**核心规则**:
|
|
448
512
|
1.
|
|
449
513
|
2.
|
|
@@ -454,76 +518,65 @@ function getC1Template() {
|
|
|
454
518
|
- [ ] 标准2
|
|
455
519
|
- [ ] 标准3
|
|
456
520
|
|
|
457
|
-
|
|
521
|
+
**边界情况**:
|
|
522
|
+
<!-- 异常处理、特殊情况 -->
|
|
458
523
|
|
|
459
524
|
---
|
|
460
525
|
|
|
461
|
-
###
|
|
526
|
+
### REQ-002 需求标题
|
|
462
527
|
|
|
463
|
-
<!--
|
|
528
|
+
<!-- 继续列举其他需求,使用相同格式 -->
|
|
464
529
|
|
|
465
530
|
---
|
|
466
531
|
|
|
467
|
-
##
|
|
532
|
+
## 3. 需求关系
|
|
468
533
|
|
|
469
|
-
###
|
|
534
|
+
### 3.1 依赖关系
|
|
470
535
|
|
|
471
|
-
**需求
|
|
536
|
+
**需求 REQ-001 依赖**:
|
|
472
537
|
- 依赖需求: REQ-___
|
|
473
|
-
-
|
|
538
|
+
- 依赖现有功能: (引用 A1)
|
|
474
539
|
|
|
475
|
-
###
|
|
540
|
+
### 3.2 互斥关系
|
|
476
541
|
|
|
477
542
|
**互斥需求**:
|
|
478
543
|
<!-- 如果某些需求不能同时满足,说明原因 -->
|
|
479
544
|
|
|
480
545
|
---
|
|
481
546
|
|
|
482
|
-
##
|
|
547
|
+
## 4. 非功能需求
|
|
483
548
|
|
|
484
|
-
###
|
|
549
|
+
### 4.1 性能要求
|
|
485
550
|
|
|
486
551
|
**响应时间**:
|
|
487
552
|
**并发量**:
|
|
488
553
|
|
|
489
|
-
###
|
|
554
|
+
### 4.2 安全要求
|
|
490
555
|
|
|
491
556
|
**权限控制**:
|
|
492
557
|
**数据安全**:
|
|
493
558
|
|
|
494
559
|
---
|
|
495
560
|
|
|
496
|
-
## 4. 边界情况
|
|
497
|
-
|
|
498
|
-
### 4.1 异常处理
|
|
499
|
-
|
|
500
|
-
**异常场景1**:
|
|
501
|
-
- 触发条件:
|
|
502
|
-
- 期望行为:
|
|
503
|
-
|
|
504
|
-
### 4.2 边界值
|
|
505
|
-
|
|
506
|
-
**边界条件**:
|
|
507
|
-
<!-- 列出关键的边界值和处理方式 -->
|
|
508
|
-
|
|
509
|
-
---
|
|
510
|
-
|
|
511
561
|
## 5. 验收总览
|
|
512
562
|
|
|
513
|
-
### 5.1
|
|
563
|
+
### 5.1 需求完整性检查
|
|
514
564
|
|
|
515
|
-
- [ ]
|
|
565
|
+
- [ ] 版本范围已明确,不超出 B3
|
|
566
|
+
- [ ] 所有需求均来自 B2
|
|
516
567
|
- [ ] 每个需求都有验收标准
|
|
517
568
|
- [ ] 依赖关系已标注
|
|
518
569
|
- [ ] 边界情况已说明
|
|
519
570
|
|
|
520
|
-
### 5.2
|
|
571
|
+
### 5.2 版本统计
|
|
521
572
|
|
|
522
573
|
**总需求数**: ______
|
|
523
574
|
**P0 需求数**: ______
|
|
524
575
|
**P1 需求数**: ______
|
|
525
576
|
**P2 需求数**: ______
|
|
526
577
|
|
|
578
|
+
### 5.3 PM 确认
|
|
579
|
+
|
|
527
580
|
**PM 签字**: _____________
|
|
528
581
|
**日期**: _____________
|
|
529
582
|
|
|
@@ -639,28 +692,28 @@ function extractSection(content, sectionTitle) {
|
|
|
639
692
|
return null;
|
|
640
693
|
}
|
|
641
694
|
|
|
642
|
-
function
|
|
695
|
+
function getReleaseTemplate(pmSignature, extractedContent = {}) {
|
|
643
696
|
const {
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
reqCount = 0,
|
|
697
|
+
versionGoal = '(未提供)',
|
|
698
|
+
totalReqCount = 0,
|
|
647
699
|
p0Count = 0,
|
|
648
700
|
p1Count = 0,
|
|
649
701
|
p2Count = 0,
|
|
650
|
-
|
|
702
|
+
itSummaries = '(无用户故事)',
|
|
703
|
+
reviewSummary = '(未提供)'
|
|
651
704
|
} = extractedContent;
|
|
652
705
|
|
|
653
|
-
return `#
|
|
706
|
+
return `# 版本发布
|
|
654
707
|
|
|
655
708
|
**冻结时间**: ${new Date().toLocaleString('zh-CN')}
|
|
656
709
|
**PM 签名**: ${pmSignature}
|
|
657
|
-
|
|
710
|
+
**状态**: 已冻结 ✅
|
|
658
711
|
|
|
659
712
|
---
|
|
660
713
|
|
|
661
714
|
## 冻结声明
|
|
662
715
|
|
|
663
|
-
|
|
716
|
+
本版本需求已通过自动化审视,正式冻结。
|
|
664
717
|
|
|
665
718
|
**冻结承诺**:
|
|
666
719
|
- 产品需求阶段完成
|
|
@@ -673,79 +726,52 @@ function getC3Template(pmSignature, extractedContent = {}) {
|
|
|
673
726
|
|
|
674
727
|
### 1.1 版本目标
|
|
675
728
|
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
${c0VersionGoal}
|
|
729
|
+
${versionGoal}
|
|
679
730
|
|
|
680
|
-
### 1.2
|
|
731
|
+
### 1.2 需求概览
|
|
681
732
|
|
|
682
|
-
|
|
733
|
+
**IT 用户故事统计**:
|
|
734
|
+
- 总故事数: ${totalReqCount}
|
|
735
|
+
- P0 故事: ${p0Count}
|
|
736
|
+
- P1 故事: ${p1Count}
|
|
737
|
+
- P2 故事: ${p2Count}
|
|
683
738
|
|
|
684
|
-
|
|
739
|
+
---
|
|
685
740
|
|
|
686
|
-
|
|
741
|
+
## 2. 需求清单
|
|
687
742
|
|
|
688
|
-
|
|
689
|
-
- 总需求数: ${reqCount || '(请手动统计)'}
|
|
690
|
-
- P0 需求: ${p0Count}
|
|
691
|
-
- P1 需求: ${p1Count}
|
|
692
|
-
- P2 需求: ${p2Count}
|
|
743
|
+
${itSummaries}
|
|
693
744
|
|
|
694
745
|
---
|
|
695
746
|
|
|
696
|
-
##
|
|
697
|
-
|
|
698
|
-
### 2.1 审视结果
|
|
699
|
-
|
|
700
|
-
**R2 审视状态**: ✅ 通过
|
|
747
|
+
## 3. 审视结论
|
|
701
748
|
|
|
749
|
+
**审视状态**: ✅ 通过
|
|
702
750
|
**通过时间**: ${new Date().toLocaleString('zh-CN')}
|
|
703
751
|
|
|
704
752
|
**审视摘要**:
|
|
753
|
+
${reviewSummary}
|
|
705
754
|
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
### 2.2 一致性确认
|
|
709
|
-
|
|
710
|
-
**与 B3 规划的一致性**:
|
|
755
|
+
**与规划的一致性**:
|
|
711
756
|
- ✅ 未背叛规划
|
|
712
|
-
- ✅
|
|
713
|
-
- ✅
|
|
757
|
+
- ✅ 未超出规划范围
|
|
758
|
+
- ✅ 需求可追溯
|
|
714
759
|
|
|
715
760
|
---
|
|
716
761
|
|
|
717
|
-
##
|
|
762
|
+
## 4. 交付清单
|
|
718
763
|
|
|
719
|
-
|
|
764
|
+
**用户故事文档**:
|
|
765
|
+
- 包含 ${totalReqCount} 个独立的用户故事文档(业务需求.md)
|
|
720
766
|
|
|
721
|
-
|
|
722
|
-
-
|
|
723
|
-
- A1: 已上线功能清单
|
|
724
|
-
- A2: 存量反馈汇总
|
|
725
|
-
|
|
726
|
-
**规划文档**:
|
|
727
|
-
- B1: 需求规划草案
|
|
728
|
-
- B2: 规划拆解与范围界定
|
|
729
|
-
- B3: 规划冻结归档
|
|
730
|
-
- R1: 规划审视报告
|
|
731
|
-
|
|
732
|
-
**版本文档**:
|
|
733
|
-
- C0: 版本范围声明
|
|
734
|
-
- C1: 版本需求清单
|
|
735
|
-
- R2: 版本审视报告
|
|
736
|
-
|
|
737
|
-
### 3.2 交付物
|
|
738
|
-
|
|
739
|
-
**可交付给研发的文档**:
|
|
740
|
-
- ✅ C1_版本需求清单.md (主要依据)
|
|
741
|
-
- ✅ C0_版本范围声明.md (边界参考)
|
|
742
|
-
- ✅ B3_规划冻结归档.md (背景理解)
|
|
767
|
+
**技术规格文档**:
|
|
768
|
+
- 包含 ${totalReqCount} 个对应的技术规格文档(技术规格.md)
|
|
743
769
|
|
|
744
770
|
---
|
|
745
771
|
|
|
746
|
-
##
|
|
772
|
+
## 5. 冻结管理
|
|
747
773
|
|
|
748
|
-
###
|
|
774
|
+
### 5.1 修改规则
|
|
749
775
|
|
|
750
776
|
**冻结后禁止**:
|
|
751
777
|
- ❌ 修改需求内容
|
|
@@ -757,38 +783,34 @@ ${r2Summary}
|
|
|
757
783
|
- ✅ UI/UX 设计细节
|
|
758
784
|
- ✅ 测试用例
|
|
759
785
|
|
|
760
|
-
###
|
|
786
|
+
### 5.2 变更流程
|
|
761
787
|
|
|
762
788
|
**如需变更需求**:
|
|
763
|
-
1.
|
|
764
|
-
2.
|
|
765
|
-
3.
|
|
766
|
-
4. PM 重新签字确认
|
|
789
|
+
1. 评估变更影响
|
|
790
|
+
2. PM 重新签字确认
|
|
791
|
+
3. 更新版本发布文档
|
|
767
792
|
|
|
768
793
|
---
|
|
769
794
|
|
|
770
|
-
##
|
|
795
|
+
## 6. 下一步
|
|
771
796
|
|
|
772
|
-
###
|
|
797
|
+
### 6.1 研发阶段
|
|
773
798
|
|
|
774
799
|
**可以启动**:
|
|
775
800
|
- 技术方案设计
|
|
776
801
|
- 架构评审
|
|
777
802
|
- 开发排期
|
|
778
803
|
|
|
779
|
-
###
|
|
804
|
+
### 6.2 后续迭代
|
|
780
805
|
|
|
781
806
|
**如需新的迭代**:
|
|
782
807
|
1. 运行: prd iteration new
|
|
783
|
-
2. 重新执行
|
|
784
|
-
3. 基于本次迭代的经验优化
|
|
808
|
+
2. 重新执行 基线 → 规划 → IT → 版本 流程
|
|
785
809
|
|
|
786
810
|
---
|
|
787
811
|
|
|
788
812
|
**PM 最终确认**: ${pmSignature}
|
|
789
813
|
**冻结日期**: ${new Date().toLocaleDateString('zh-CN')}
|
|
790
|
-
**状态**: 🔒 已冻结
|
|
791
814
|
**产品需求阶段**: ✅ 完成
|
|
792
815
|
`;
|
|
793
816
|
}
|
|
794
|
-
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prd-workflow-cli",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "产品需求管理规范 CLI 工具 - 基于
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "产品需求管理规范 CLI 工具 - 基于 基线→规划→IT→版本 流程的需求管理命令行工具",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"prd": "./bin/prd-cli.js"
|