prd-workflow-cli 1.1.25
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-b1-planning-draft.md +501 -0
- package/.agent/workflows/prd-b2-planning-breakdown.md +731 -0
- package/.agent/workflows/prd-c1-requirement-list.md +907 -0
- package/.agent/workflows/prd-c2-change-tracking.md +320 -0
- package/.agent/workflows/prd-dialog-archive.md +215 -0
- package/.agent/workflows/prd-p0-project-info.md +379 -0
- package/.agent/workflows/prd-r0-baseline-review.md +925 -0
- package/.agent/workflows/prd-r1-review.md +458 -0
- package/.agent/workflows/prd-r2-review.md +483 -0
- package/.antigravity/rules.md +238 -0
- package/.cursorrules +284 -0
- package/GUIDE.md +341 -0
- package/README.md +416 -0
- package/bin/prd-cli.js +134 -0
- package/commands/baseline.js +470 -0
- package/commands/change.js +151 -0
- package/commands/confirm.js +364 -0
- package/commands/dialog.js +227 -0
- package/commands/index.js +365 -0
- package/commands/init.js +357 -0
- package/commands/iteration.js +192 -0
- package/commands/planning.js +710 -0
- package/commands/review.js +444 -0
- package/commands/status.js +142 -0
- package/commands/upgrade.js +228 -0
- package/commands/version.js +794 -0
- package/package.json +74 -0
- package/scripts/postinstall.js +241 -0
- package/templates/README-FOR-NEW-USER.md +105 -0
- package/templates/dialog-template.md +109 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const chalk = require('chalk');
|
|
4
|
+
|
|
5
|
+
module.exports = async function (action) {
|
|
6
|
+
const configPath = path.join(process.cwd(), '.prd-config.json');
|
|
7
|
+
|
|
8
|
+
if (!await fs.pathExists(configPath)) {
|
|
9
|
+
console.log(chalk.red('✗ 当前目录不是一个 PRD 项目'));
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const config = await fs.readJSON(configPath);
|
|
14
|
+
|
|
15
|
+
if (action === 'new') {
|
|
16
|
+
await createNewIteration(config, configPath);
|
|
17
|
+
} else if (action === 'list') {
|
|
18
|
+
await listIterations();
|
|
19
|
+
} else if (action === 'current') {
|
|
20
|
+
console.log(chalk.cyan(`当前迭代: 第 ${config.currentIteration} 轮`));
|
|
21
|
+
} else {
|
|
22
|
+
console.log(chalk.red('✗ 未知操作'));
|
|
23
|
+
console.log('可用操作: new, list, current');
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
async function createNewIteration(config, configPath) {
|
|
28
|
+
const newIteration = config.currentIteration + 1;
|
|
29
|
+
const iterationName = `第${String(newIteration).padStart(2, '0')}轮迭代`;
|
|
30
|
+
const iterationDir = path.join(process.cwd(), '02_迭代记录', iterationName);
|
|
31
|
+
|
|
32
|
+
if (await fs.pathExists(iterationDir)) {
|
|
33
|
+
console.log(chalk.yellow(`⚠ 迭代目录已存在: ${iterationName}`));
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
console.log(chalk.blue(`\n正在创建 ${iterationName}...\n`));
|
|
38
|
+
|
|
39
|
+
// 创建迭代目录
|
|
40
|
+
await fs.ensureDir(iterationDir);
|
|
41
|
+
|
|
42
|
+
// 创建 R1 启动条件检查文档
|
|
43
|
+
const r1StartTemplate = `# R1_规划启动条件检查
|
|
44
|
+
|
|
45
|
+
**检查时间**: ${new Date().toLocaleString('zh-CN')}
|
|
46
|
+
**迭代轮次**: ${iterationName}
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## R1 启动条件检查
|
|
51
|
+
|
|
52
|
+
在开始 B1/B2 规划之前,必须确认以下三个条件全部满足。
|
|
53
|
+
|
|
54
|
+
### 启动条件一:问题是否被确认真实存在
|
|
55
|
+
|
|
56
|
+
**检查标准**:
|
|
57
|
+
该问题可以在以下至少一类中被指认:
|
|
58
|
+
- [ ] A1: 已上线功能/用户路径中的明确断点
|
|
59
|
+
- [ ] A2: 真实用户反馈/数据异常/业务投诉
|
|
60
|
+
- [ ] 明确的业务约束或合规要求变化
|
|
61
|
+
|
|
62
|
+
**检查结果**:
|
|
63
|
+
<!-- 填写检查结果 -->
|
|
64
|
+
|
|
65
|
+
**问题描述**:
|
|
66
|
+
<!-- 描述具体问题,并指向 A 类文档中的具体章节 -->
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
### 启动条件二:问题是否需要"单独一轮规划"来解决
|
|
71
|
+
|
|
72
|
+
**检查标准**:
|
|
73
|
+
该问题:
|
|
74
|
+
- [ ] 无法通过微调、修补、参数修改解决
|
|
75
|
+
- [ ] 会显著影响核心用户路径/核心目标
|
|
76
|
+
|
|
77
|
+
**检查结果**:
|
|
78
|
+
<!-- 说明为什么不能作为"顺带改一下" -->
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
### 启动条件三:问题是否已经被理解到"可规划"的程度
|
|
83
|
+
|
|
84
|
+
**检查标准**:
|
|
85
|
+
问题的边界已基本清楚:
|
|
86
|
+
- [ ] 是哪个用户
|
|
87
|
+
- [ ] 发生在哪个场景
|
|
88
|
+
- [ ] 影响到哪一段流程
|
|
89
|
+
|
|
90
|
+
不存在以下情况:
|
|
91
|
+
- [ ] 核心概念尚未统一
|
|
92
|
+
- [ ] 关键前提仍在争论
|
|
93
|
+
|
|
94
|
+
**检查结果**:
|
|
95
|
+
<!-- 描述问题的边界和范围 -->
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## 最终判定
|
|
100
|
+
|
|
101
|
+
**三条条件检查结果**:
|
|
102
|
+
- [ ] 条件一: 通过 / 不通过
|
|
103
|
+
- [ ] 条件二: 通过 / 不通过
|
|
104
|
+
- [ ] 条件三: 通过 / 不通过
|
|
105
|
+
|
|
106
|
+
**结论**:
|
|
107
|
+
- [ ] ✅ 全部通过 - 允许启动 B1/B2
|
|
108
|
+
- [ ] ❌ 存在不满足 - 禁止创建 B1 文档
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
⚠️ **重要提醒**:
|
|
113
|
+
- 只有三条条件全部满足,才允许启动 B1/B2
|
|
114
|
+
- 任意一条不满足,禁止创建 B1 文档
|
|
115
|
+
- 没有"勉强通过",没有"先写着看"
|
|
116
|
+
`;
|
|
117
|
+
|
|
118
|
+
await fs.writeFile(
|
|
119
|
+
path.join(iterationDir, 'R1_规划启动条件检查.md'),
|
|
120
|
+
r1StartTemplate
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
// 更新配置
|
|
124
|
+
config.currentIteration = newIteration;
|
|
125
|
+
await fs.writeJSON(configPath, config, { spaces: 2 });
|
|
126
|
+
|
|
127
|
+
console.log(chalk.green(`✓ ${iterationName} 创建成功!`));
|
|
128
|
+
console.log(chalk.cyan(`\n目录位置: ${iterationDir}\n`));
|
|
129
|
+
|
|
130
|
+
// 检查 A2 是否有待下版事项
|
|
131
|
+
const a2Path = path.join(process.cwd(), '01_产品基线', 'A2_存量反馈与数据汇总.md');
|
|
132
|
+
if (await fs.pathExists(a2Path)) {
|
|
133
|
+
const a2Content = await fs.readFile(a2Path, 'utf-8');
|
|
134
|
+
if (a2Content.includes('待下版事项') && !a2Content.includes('待下版事项 #1: [需求标题]')) {
|
|
135
|
+
console.log(chalk.yellow.bold('📌 提醒:A2 中有待下版事项!\n'));
|
|
136
|
+
console.log(chalk.yellow(' 请检查 01_产品基线/A2_存量反馈与数据汇总.md'));
|
|
137
|
+
console.log(chalk.yellow(' 的"五、待下版事项"章节,'));
|
|
138
|
+
console.log(chalk.yellow(' 将需要处理的事项纳入本轮 B1 规划。\n'));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
console.log(chalk.bold('下一步:'));
|
|
143
|
+
console.log('1. 检查 A2 的"待下版事项"(如有)');
|
|
144
|
+
console.log('2. 填写 R1_规划启动条件检查.md');
|
|
145
|
+
console.log('3. 确认三个条件全部满足');
|
|
146
|
+
console.log('4. 创建 B1: prd plan create B1');
|
|
147
|
+
console.log('');
|
|
148
|
+
|
|
149
|
+
console.log(chalk.yellow('📌 R1 启动条件快速参考:'));
|
|
150
|
+
console.log(' 条件一: 问题是否真实存在(基于 A 类文档)');
|
|
151
|
+
console.log(' 条件二: 是否值得单独一轮规划');
|
|
152
|
+
console.log(' 条件三: 问题是否已理解清楚');
|
|
153
|
+
console.log('');
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async function listIterations() {
|
|
157
|
+
const iterationsDir = path.join(process.cwd(), '02_迭代记录');
|
|
158
|
+
|
|
159
|
+
if (!await fs.pathExists(iterationsDir)) {
|
|
160
|
+
console.log(chalk.yellow('还没有任何迭代'));
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const iterations = await fs.readdir(iterationsDir);
|
|
165
|
+
const validIterations = iterations.filter(name => name.startsWith('第') && name.includes('轮迭代'));
|
|
166
|
+
|
|
167
|
+
if (validIterations.length === 0) {
|
|
168
|
+
console.log(chalk.yellow('还没有任何迭代'));
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
console.log(chalk.bold('\n迭代列表:\n'));
|
|
173
|
+
for (const iteration of validIterations.sort()) {
|
|
174
|
+
const iterPath = path.join(iterationsDir, iteration);
|
|
175
|
+
const files = await fs.readdir(iterPath);
|
|
176
|
+
console.log(chalk.cyan(`📁 ${iteration}`));
|
|
177
|
+
console.log(` 文档数: ${files.length}`);
|
|
178
|
+
|
|
179
|
+
// 检查阶段完成情况
|
|
180
|
+
const hasB3 = files.includes('B3_规划冻结归档.md');
|
|
181
|
+
const hasC3 = files.includes('C3_版本冻结归档.md');
|
|
182
|
+
|
|
183
|
+
if (hasC3) {
|
|
184
|
+
console.log(chalk.green(' 状态: ✓ 已完成'));
|
|
185
|
+
} else if (hasB3) {
|
|
186
|
+
console.log(chalk.yellow(' 状态: · 规划已冻结,进行中'));
|
|
187
|
+
} else {
|
|
188
|
+
console.log(chalk.gray(' 状态: · 规划中'));
|
|
189
|
+
}
|
|
190
|
+
console.log('');
|
|
191
|
+
}
|
|
192
|
+
}
|