bmall-mcp 1.5.0 → 1.6.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 +42 -0
- package/dist/server/tools.d.ts +52 -0
- package/dist/server/tools.d.ts.map +1 -1
- package/dist/server/tools.js +39 -1
- package/dist/server/tools.js.map +1 -1
- package/dist/tools/requirements/index.d.ts +10 -0
- package/dist/tools/requirements/index.d.ts.map +1 -1
- package/dist/tools/requirements/index.js +172 -25
- package/dist/tools/requirements/index.js.map +1 -1
- package/dist/tools/requirements/requirement-processor.d.ts +6 -1
- package/dist/tools/requirements/requirement-processor.d.ts.map +1 -1
- package/dist/tools/requirements/requirement-processor.js +4 -4
- package/dist/tools/requirements/requirement-processor.js.map +1 -1
- package/docs/generate-requirements-usage.md +204 -28
- package/package.json +2 -2
- package/src/server/tools.ts +39 -1
- package/src/tools/requirements/index.ts +195 -29
- package/src/tools/requirements/requirement-processor.ts +11 -4
package/README.md
CHANGED
|
@@ -51,6 +51,7 @@ npx -y bmall-mcp
|
|
|
51
51
|
| `mta_implementation` | 生成埋点管理类代码 | `生成埋点代码 34747` |
|
|
52
52
|
| `mta_integration` | 埋点业务集成指导 | `集成埋点 34747` |
|
|
53
53
|
| `analyze_appfreeze` | 鸿蒙AppFreeze分析 | `分析AppFreeze日志 /path/to/freeze.log` |
|
|
54
|
+
| `generate_requirements` | 需求文档生成 | `生成需求文档` |
|
|
54
55
|
|
|
55
56
|
### 工具详情
|
|
56
57
|
|
|
@@ -139,6 +140,38 @@ npx -y bmall-mcp
|
|
|
139
140
|
- 项目根目录下的 `harmonyos-appfreeze-guide.md` 包含完整的分析规则和典型案例
|
|
140
141
|
</details>
|
|
141
142
|
|
|
143
|
+
<details>
|
|
144
|
+
<summary><b>generate_requirements</b> - 需求文档生成</summary>
|
|
145
|
+
|
|
146
|
+
从产品 PRD 文档(支持 Markdown/PDF/网页)、可选的设计稿(Figma/文件)和后端文档(文件/网页)生成结构化的前端需求文档。
|
|
147
|
+
|
|
148
|
+
**参数:**
|
|
149
|
+
- `requirementSource`: 需求文档来源(必填)
|
|
150
|
+
- `type`: "file" | "url"
|
|
151
|
+
- `path`: 文件路径(.md/.pdf),type=file 时必填
|
|
152
|
+
- `url`: 网页 URL,type=url 时必填
|
|
153
|
+
- `featureName`: 功能名称(必填),用于生成输出路径
|
|
154
|
+
- `designSource`: 设计稿来源(可选)
|
|
155
|
+
- `type`: "figma" | "file"
|
|
156
|
+
- `url`: Figma 链接,type=figma 时必填
|
|
157
|
+
- `path`: 设计稿文件路径,type=file 时必填
|
|
158
|
+
- `backendSource`: 后端文档来源(可选)
|
|
159
|
+
- `type`: "file" | "url"
|
|
160
|
+
- `path`: 后端文档路径(.md/.pdf),type=file 时必填
|
|
161
|
+
- `url`: 后端文档网页 URL,type=url 时必填
|
|
162
|
+
|
|
163
|
+
**输出文档结构:**
|
|
164
|
+
1. 介绍:功能概述、核心价值、涉及范围、核心指标、术语表
|
|
165
|
+
2. 功能需求:用户故事 + 验收标准(3-6 条)
|
|
166
|
+
3. 交互细节:视觉反馈、动画效果、错误处理、确认弹窗
|
|
167
|
+
4. 技术要求与限制:性能需求、可用性需求、兼容性需求、限制说明
|
|
168
|
+
|
|
169
|
+
**核心约束:**
|
|
170
|
+
- 从用户视角描述功能,避免技术细节
|
|
171
|
+
- 必须覆盖 10 个前端开发重点
|
|
172
|
+
- 验收标准必须可测试、具体明确
|
|
173
|
+
</details>
|
|
174
|
+
|
|
142
175
|
## 项目架构
|
|
143
176
|
|
|
144
177
|
```
|
|
@@ -171,6 +204,15 @@ src/
|
|
|
171
204
|
|
|
172
205
|
## Changelog
|
|
173
206
|
|
|
207
|
+
### v1.6.0 (2026-03-16)
|
|
208
|
+
- ✅ 优化 `generate_requirements` 工具 Prompt 模板
|
|
209
|
+
- ✅ 新增设计稿支持(Figma 链接和本地文件)
|
|
210
|
+
- ✅ 新增后端文档支持(文件和网页 URL)
|
|
211
|
+
- ✅ 完善输出文档结构(4 个章节:介绍、功能需求、交互细节、技术要求与限制)
|
|
212
|
+
- ✅ 强化核心约束:用户视角、10 个前端开发重点、可测试的验收标准
|
|
213
|
+
- ✅ 支持多输入源:PRD + 设计稿 + 后端文档组合生成
|
|
214
|
+
- ✅ 更新使用文档:新增完整流程示例和最佳实践
|
|
215
|
+
|
|
174
216
|
### v1.5.0 (2026-02-12)
|
|
175
217
|
- ✅ 新增 `generate_requirements` 工具:从需求文档生成结构化的 requirements.md
|
|
176
218
|
- ✅ 支持 Markdown、PDF、网页 URL 三种输入格式
|
package/dist/server/tools.d.ts
CHANGED
|
@@ -28,6 +28,8 @@ export declare const toolDefinitions: ({
|
|
|
28
28
|
outputPath?: undefined;
|
|
29
29
|
requirementSource?: undefined;
|
|
30
30
|
featureName?: undefined;
|
|
31
|
+
designSource?: undefined;
|
|
32
|
+
backendSource?: undefined;
|
|
31
33
|
};
|
|
32
34
|
required?: undefined;
|
|
33
35
|
};
|
|
@@ -61,6 +63,8 @@ export declare const toolDefinitions: ({
|
|
|
61
63
|
outputPath?: undefined;
|
|
62
64
|
requirementSource?: undefined;
|
|
63
65
|
featureName?: undefined;
|
|
66
|
+
designSource?: undefined;
|
|
67
|
+
backendSource?: undefined;
|
|
64
68
|
};
|
|
65
69
|
required?: undefined;
|
|
66
70
|
};
|
|
@@ -86,6 +90,8 @@ export declare const toolDefinitions: ({
|
|
|
86
90
|
outputPath?: undefined;
|
|
87
91
|
requirementSource?: undefined;
|
|
88
92
|
featureName?: undefined;
|
|
93
|
+
designSource?: undefined;
|
|
94
|
+
backendSource?: undefined;
|
|
89
95
|
};
|
|
90
96
|
required?: undefined;
|
|
91
97
|
};
|
|
@@ -115,6 +121,8 @@ export declare const toolDefinitions: ({
|
|
|
115
121
|
outputPath?: undefined;
|
|
116
122
|
requirementSource?: undefined;
|
|
117
123
|
featureName?: undefined;
|
|
124
|
+
designSource?: undefined;
|
|
125
|
+
backendSource?: undefined;
|
|
118
126
|
};
|
|
119
127
|
required: string[];
|
|
120
128
|
};
|
|
@@ -143,6 +151,8 @@ export declare const toolDefinitions: ({
|
|
|
143
151
|
outputPath?: undefined;
|
|
144
152
|
requirementSource?: undefined;
|
|
145
153
|
featureName?: undefined;
|
|
154
|
+
designSource?: undefined;
|
|
155
|
+
backendSource?: undefined;
|
|
146
156
|
};
|
|
147
157
|
required: string[];
|
|
148
158
|
};
|
|
@@ -171,6 +181,8 @@ export declare const toolDefinitions: ({
|
|
|
171
181
|
outputPath?: undefined;
|
|
172
182
|
requirementSource?: undefined;
|
|
173
183
|
featureName?: undefined;
|
|
184
|
+
designSource?: undefined;
|
|
185
|
+
backendSource?: undefined;
|
|
174
186
|
};
|
|
175
187
|
required: string[];
|
|
176
188
|
};
|
|
@@ -199,6 +211,8 @@ export declare const toolDefinitions: ({
|
|
|
199
211
|
businessCodePath?: undefined;
|
|
200
212
|
requirementSource?: undefined;
|
|
201
213
|
featureName?: undefined;
|
|
214
|
+
designSource?: undefined;
|
|
215
|
+
backendSource?: undefined;
|
|
202
216
|
};
|
|
203
217
|
required: string[];
|
|
204
218
|
};
|
|
@@ -232,6 +246,44 @@ export declare const toolDefinitions: ({
|
|
|
232
246
|
type: string;
|
|
233
247
|
description: string;
|
|
234
248
|
};
|
|
249
|
+
designSource: {
|
|
250
|
+
type: string;
|
|
251
|
+
description: string;
|
|
252
|
+
properties: {
|
|
253
|
+
type: {
|
|
254
|
+
type: string;
|
|
255
|
+
enum: string[];
|
|
256
|
+
description: string;
|
|
257
|
+
};
|
|
258
|
+
url: {
|
|
259
|
+
type: string;
|
|
260
|
+
description: string;
|
|
261
|
+
};
|
|
262
|
+
path: {
|
|
263
|
+
type: string;
|
|
264
|
+
description: string;
|
|
265
|
+
};
|
|
266
|
+
};
|
|
267
|
+
};
|
|
268
|
+
backendSource: {
|
|
269
|
+
type: string;
|
|
270
|
+
description: string;
|
|
271
|
+
properties: {
|
|
272
|
+
type: {
|
|
273
|
+
type: string;
|
|
274
|
+
enum: string[];
|
|
275
|
+
description: string;
|
|
276
|
+
};
|
|
277
|
+
path: {
|
|
278
|
+
type: string;
|
|
279
|
+
description: string;
|
|
280
|
+
};
|
|
281
|
+
url: {
|
|
282
|
+
type: string;
|
|
283
|
+
description: string;
|
|
284
|
+
};
|
|
285
|
+
};
|
|
286
|
+
};
|
|
235
287
|
ide?: undefined;
|
|
236
288
|
rulesType?: undefined;
|
|
237
289
|
message?: undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/server/tools.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,eAAe
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/server/tools.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAyM3B,CAAC"}
|
package/dist/server/tools.js
CHANGED
|
@@ -132,7 +132,7 @@ export const toolDefinitions = [
|
|
|
132
132
|
},
|
|
133
133
|
{
|
|
134
134
|
name: "generate_requirements",
|
|
135
|
-
description: "需求文档生成:从需求文档(PRD
|
|
135
|
+
description: "需求文档生成:从需求文档(PRD/文件/网页)和可选的设计稿、后端文档生成结构化的 requirements.md。输出路径固定为 .specs/requirements/{featureName}/requirements.md。触发词:生成需求文档、需求分析、requirements",
|
|
136
136
|
inputSchema: {
|
|
137
137
|
type: "object",
|
|
138
138
|
properties: {
|
|
@@ -160,6 +160,44 @@ export const toolDefinitions = [
|
|
|
160
160
|
type: "string",
|
|
161
161
|
description: "功能名称(必填),用于生成输出路径 .specs/requirements/{featureName}/requirements.md",
|
|
162
162
|
},
|
|
163
|
+
designSource: {
|
|
164
|
+
type: "object",
|
|
165
|
+
description: "设计稿来源(可选,支持 Figma 或文件)",
|
|
166
|
+
properties: {
|
|
167
|
+
type: {
|
|
168
|
+
type: "string",
|
|
169
|
+
enum: ["figma", "file"],
|
|
170
|
+
description: "设计稿类型",
|
|
171
|
+
},
|
|
172
|
+
url: {
|
|
173
|
+
type: "string",
|
|
174
|
+
description: "Figma 链接,当 type 为 figma 时必填",
|
|
175
|
+
},
|
|
176
|
+
path: {
|
|
177
|
+
type: "string",
|
|
178
|
+
description: "设计稿文件路径,当 type 为 file 时必填",
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
backendSource: {
|
|
183
|
+
type: "object",
|
|
184
|
+
description: "后端文档来源(可选,支持文件或网页)",
|
|
185
|
+
properties: {
|
|
186
|
+
type: {
|
|
187
|
+
type: "string",
|
|
188
|
+
enum: ["file", "url"],
|
|
189
|
+
description: "文件或网页",
|
|
190
|
+
},
|
|
191
|
+
path: {
|
|
192
|
+
type: "string",
|
|
193
|
+
description: "文件路径(.md/.pdf),当 type 为 file 时必填",
|
|
194
|
+
},
|
|
195
|
+
url: {
|
|
196
|
+
type: "string",
|
|
197
|
+
description: "网页 URL,当 type 为 url 时必填",
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
},
|
|
163
201
|
},
|
|
164
202
|
required: ["requirementSource", "featureName"],
|
|
165
203
|
},
|
package/dist/server/tools.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/server/tools.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/server/tools.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B;QACE,IAAI,EAAE,YAAY;QAClB,WAAW,EAAE,kCAAkC;QAC/C,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,GAAG,EAAE;oBACH,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,CAAC;oBAC/C,WAAW,EAAE,mCAAmC;iBACjD;gBACD,SAAS,EAAE;oBACT,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC;oBAC7C,WAAW,EAAE,sBAAsB;iBACpC;aACF;SACF;KACF;IACD;QACE,IAAI,EAAE,YAAY;QAClB,WAAW,EAAE,2BAA2B;QACxC,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,GAAG,EAAE;oBACH,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,CAAC;oBAC/C,WAAW,EAAE,mCAAmC;iBACjD;gBACD,OAAO,EAAE;oBACP,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,WAAW;iBACzB;gBACD,SAAS,EAAE;oBACT,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC;oBAC7C,WAAW,EAAE,sBAAsB;iBACpC;aACF;SACF;KACF;IACD;QACE,IAAI,EAAE,qBAAqB;QAC3B,WAAW,EAAE,8EAA8E;QAC3F,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,yBAAyB;iBACvC;aACF;SACF;KACF;IACD;QACE,IAAI,EAAE,UAAU;QAChB,WAAW,EAAE,0EAA0E;QACvF,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,cAAc,EAAE;oBACd,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,4DAA4D;iBAC1E;gBACD,QAAQ,EAAE;oBACR,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC;oBAC3C,WAAW,EAAE,uBAAuB;iBACrC;aACF;YACD,QAAQ,EAAE,CAAC,gBAAgB,CAAC;SAC7B;KACF;IACD;QACE,IAAI,EAAE,oBAAoB;QAC1B,WAAW,EAAE,mEAAmE;QAChF,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,aAAa,EAAE;oBACb,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,gBAAgB;iBAC9B;gBACD,UAAU,EAAE;oBACV,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,sBAAsB;iBACpC;aACF;YACD,QAAQ,EAAE,CAAC,eAAe,CAAC;SAC5B;KACF;IACD;QACE,IAAI,EAAE,iBAAiB;QACvB,WAAW,EAAE,wCAAwC;QACrD,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,aAAa,EAAE;oBACb,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,gBAAgB;iBAC9B;gBACD,gBAAgB,EAAE;oBAChB,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,oCAAoC;iBAClD;aACF;YACD,QAAQ,EAAE,CAAC,eAAe,CAAC;SAC5B;KACF;IACD;QACE,IAAI,EAAE,mBAAmB;QACzB,WAAW,EAAE,0DAA0D;QACvE,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,WAAW,EAAE;oBACX,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,0CAA0C;iBACxD;gBACD,UAAU,EAAE;oBACV,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,sBAAsB;iBACpC;aACF;YACD,QAAQ,EAAE,CAAC,aAAa,CAAC;SAC1B;KACF;IACD;QACE,IAAI,EAAE,uBAAuB;QAC7B,WAAW,EAAE,kJAAkJ;QAC/J,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,iBAAiB,EAAE;oBACjB,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,YAAY;oBACzB,UAAU,EAAE;wBACV,IAAI,EAAE;4BACJ,IAAI,EAAE,QAAQ;4BACd,IAAI,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC;4BACrB,WAAW,EAAE,OAAO;yBACrB;wBACD,IAAI,EAAE;4BACJ,IAAI,EAAE,QAAQ;4BACd,WAAW,EAAE,kCAAkC;yBAChD;wBACD,GAAG,EAAE;4BACH,IAAI,EAAE,QAAQ;4BACd,WAAW,EAAE,yBAAyB;yBACvC;qBACF;oBACD,QAAQ,EAAE,CAAC,MAAM,CAAC;iBACnB;gBACD,WAAW,EAAE;oBACX,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,qEAAqE;iBACnF;gBACD,YAAY,EAAE;oBACZ,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,wBAAwB;oBACrC,UAAU,EAAE;wBACV,IAAI,EAAE;4BACJ,IAAI,EAAE,QAAQ;4BACd,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;4BACvB,WAAW,EAAE,OAAO;yBACrB;wBACD,GAAG,EAAE;4BACH,IAAI,EAAE,QAAQ;4BACd,WAAW,EAAE,6BAA6B;yBAC3C;wBACD,IAAI,EAAE;4BACJ,IAAI,EAAE,QAAQ;4BACd,WAAW,EAAE,2BAA2B;yBACzC;qBACF;iBACF;gBACD,aAAa,EAAE;oBACb,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,oBAAoB;oBACjC,UAAU,EAAE;wBACV,IAAI,EAAE;4BACJ,IAAI,EAAE,QAAQ;4BACd,IAAI,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC;4BACrB,WAAW,EAAE,OAAO;yBACrB;wBACD,IAAI,EAAE;4BACJ,IAAI,EAAE,QAAQ;4BACd,WAAW,EAAE,kCAAkC;yBAChD;wBACD,GAAG,EAAE;4BACH,IAAI,EAAE,QAAQ;4BACd,WAAW,EAAE,yBAAyB;yBACvC;qBACF;iBACF;aACF;YACD,QAAQ,EAAE,CAAC,mBAAmB,EAAE,aAAa,CAAC;SAC/C;KACF;CACF,CAAC"}
|
|
@@ -6,6 +6,16 @@ interface RequirementSource {
|
|
|
6
6
|
interface GenerateRequirementsParams {
|
|
7
7
|
requirementSource: RequirementSource;
|
|
8
8
|
featureName: string;
|
|
9
|
+
designSource?: {
|
|
10
|
+
type: "figma" | "file";
|
|
11
|
+
url?: string;
|
|
12
|
+
path?: string;
|
|
13
|
+
};
|
|
14
|
+
backendSource?: {
|
|
15
|
+
type: "file" | "url";
|
|
16
|
+
path?: string;
|
|
17
|
+
url?: string;
|
|
18
|
+
};
|
|
9
19
|
}
|
|
10
20
|
export declare function generateRequirements(params: GenerateRequirementsParams): Promise<{
|
|
11
21
|
success: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/requirements/index.ts"],"names":[],"mappings":"AAMA,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,UAAU,0BAA0B;IAClC,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,WAAW,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/requirements/index.ts"],"names":[],"mappings":"AAMA,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,UAAU,0BAA0B;IAClC,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE;QACb,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;QACvB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,aAAa,CAAC,EAAE;QACd,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;QACrB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAmCD,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,0BAA0B,GACjC,OAAO,CAAC;IACT,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE;QACZ,IAAI,EAAE,UAAU,GAAG,UAAU,GAAG,iBAAiB,CAAC;QAClD,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH,CAAC,CAiGD"}
|
|
@@ -42,19 +42,53 @@ export async function generateRequirements(params) {
|
|
|
42
42
|
}
|
|
43
43
|
// 2.2.2 需求文档已读取并保存(Markdown 文件)
|
|
44
44
|
}
|
|
45
|
-
// 3.
|
|
45
|
+
// 3. 检查设计稿
|
|
46
|
+
let designSourceInfo = "";
|
|
47
|
+
if (params.designSource) {
|
|
48
|
+
if (params.designSource.type === "figma") {
|
|
49
|
+
designSourceInfo = `**设计稿链接**:${params.designSource.url || "Figma 链接未提供"}\n`;
|
|
50
|
+
}
|
|
51
|
+
else if (params.designSource.type === "file") {
|
|
52
|
+
designSourceInfo = `**设计稿文件**:${params.designSource.path || "设计稿路径未提供"}\n`;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// 4. 处理后端文档
|
|
56
|
+
let backendSourceInfo = "";
|
|
57
|
+
if (params.backendSource) {
|
|
58
|
+
const backendResult = await processRequirementDocument(params.backendSource, params.featureName, "backend-doc.md");
|
|
59
|
+
if (!backendResult.success) {
|
|
60
|
+
return {
|
|
61
|
+
success: false,
|
|
62
|
+
message: backendResult.message,
|
|
63
|
+
needsAction: backendResult.needsAction,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
if (params.backendSource.type === "file") {
|
|
67
|
+
backendSourceInfo = `**后端文档位置**:.specs/requirements/${params.featureName}/backend-doc.md\n`;
|
|
68
|
+
}
|
|
69
|
+
else if (params.backendSource.type === "url") {
|
|
70
|
+
backendSourceInfo = `**后端文档位置**:.specs/requirements/${params.featureName}/backend-doc.md\n`;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// 5. 生成分析提示词
|
|
46
74
|
const outputPath = `.specs/requirements/${params.featureName}/requirements.md`;
|
|
47
75
|
const originDocPath = `.specs/requirements/${params.featureName}/origin-requirement.md`;
|
|
48
76
|
let message = "📝 需求文档已准备完毕\n\n";
|
|
49
77
|
message += `**原始文档位置**:${originDocPath}\n`;
|
|
78
|
+
if (designSourceInfo) {
|
|
79
|
+
message += designSourceInfo;
|
|
80
|
+
}
|
|
81
|
+
if (backendSourceInfo) {
|
|
82
|
+
message += backendSourceInfo;
|
|
83
|
+
}
|
|
50
84
|
message += `**目标输出位置**:${outputPath}\n\n`;
|
|
51
|
-
message += buildAnalysisPrompt(originDocPath, outputPath);
|
|
85
|
+
message += buildAnalysisPrompt(originDocPath, outputPath, params.designSource, params.backendSource);
|
|
52
86
|
return {
|
|
53
87
|
success: false,
|
|
54
88
|
message,
|
|
55
89
|
needsAction: {
|
|
56
90
|
type: "analyze_content",
|
|
57
|
-
instruction: `分析 ${originDocPath},生成 ${outputPath}`,
|
|
91
|
+
instruction: `分析 ${originDocPath}${params.designSource ? "、设计稿" : ""}${params.backendSource ? "、后端文档" : ""},生成 ${outputPath}`,
|
|
58
92
|
},
|
|
59
93
|
};
|
|
60
94
|
}
|
|
@@ -65,42 +99,155 @@ export async function generateRequirements(params) {
|
|
|
65
99
|
throw new McpError(-32603, `生成需求文档失败: ${error instanceof Error ? error.message : String(error)}`);
|
|
66
100
|
}
|
|
67
101
|
}
|
|
68
|
-
function buildAnalysisPrompt(originDocPath, outputPath) {
|
|
69
|
-
|
|
102
|
+
function buildAnalysisPrompt(originDocPath, outputPath, designSource, backendSource) {
|
|
103
|
+
const featureName = outputPath.split('/')[2];
|
|
104
|
+
let prompt = `# 产品 PRD 转需求文档
|
|
105
|
+
|
|
106
|
+
## 角色定义
|
|
107
|
+
|
|
108
|
+
你是一位资深的前端需求分析专家,擅长从产品 PRD 中提取并转化为前端开发可执行的需求文档。
|
|
109
|
+
|
|
110
|
+
## 任务目标
|
|
70
111
|
|
|
71
|
-
|
|
112
|
+
根据产品 PRD 文档${designSource ? "、设计稿" : ""}${backendSource ? "和后端文档" : ""},生成一份高质量的需求文档,确保前端开发人员能够清晰理解用户需求,准确实现功能。
|
|
72
113
|
|
|
73
|
-
|
|
114
|
+
## 输入材料
|
|
74
115
|
|
|
75
|
-
|
|
116
|
+
1. **产品 PRD 文档**:\`${originDocPath}\`(包含项目背景、功能列表、系统流程、详细说明等)
|
|
117
|
+
2. **设计稿**:${designSource ? `已提供${designSource.type === "figma" ? "Figma 链接,使用 MCP 工具读取" : "设计稿文件"}:${designSource.url || designSource.path}` : "未提供(如有设计稿,请使用 Figma MCP 工具读取)"}
|
|
118
|
+
3. **后端文档**:${backendSource ? `已提供${backendSource.type === "url" ? "网页 URL" : "文件"}:.specs/requirements/${featureName}/backend-doc.md(包含接口定义、数据结构、后端逻辑等,可作为生成验收标准的参考)` : "未提供(如有后端文档,可作为生成验收标准的参考)"}
|
|
76
119
|
|
|
77
|
-
|
|
120
|
+
## 输出要求
|
|
78
121
|
|
|
79
122
|
### 文档结构
|
|
80
123
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
124
|
+
必须包含以下章节:
|
|
125
|
+
|
|
126
|
+
#### 1. 介绍
|
|
127
|
+
- **功能概述**:一句话说明功能是什么、解决什么问题
|
|
128
|
+
- **核心价值**:为什么要做这个功能(用户体验、转化率、营销能力等)
|
|
129
|
+
- **涉及范围**:
|
|
130
|
+
- 业务场景范围
|
|
131
|
+
- 平台支持范围
|
|
132
|
+
- 排除范围
|
|
133
|
+
- **核心指标**:衡量成功的关键指标
|
|
134
|
+
- **术语表**:关键术语定义,避免歧义
|
|
135
|
+
|
|
136
|
+
#### 2. 功能需求
|
|
137
|
+
每个需求必须包含:
|
|
138
|
+
- **用户故事**:作为角色,我希望功能,以便价值
|
|
139
|
+
- **验收标准**:WHEN 触发条件 THEN 预期行为(至少 3-6 条)
|
|
140
|
+
- **说明**:补充必要的细节(不涉及技术实现)
|
|
141
|
+
|
|
142
|
+
#### 3. 交互细节
|
|
143
|
+
- **视觉反馈**:选中、不可用、加载、错误的视觉表现
|
|
144
|
+
- **动画效果**:展开/收起、弹出、跳转的动画时长和方式
|
|
145
|
+
- **错误处理**:各种错误场景的用户提示和处理方式
|
|
146
|
+
- **确认弹窗**:需要用户确认的场景和确认内容
|
|
147
|
+
|
|
148
|
+
#### 4. 技术要求与限制
|
|
149
|
+
- **性能需求**:响应时间、加载速度、动画流畅度
|
|
150
|
+
- **可用性需求**:状态清晰性、错误提示友好性、操作便捷性
|
|
151
|
+
- **兼容性需求**:支持的系统版本、设备类型、浏览器要求
|
|
152
|
+
- **限制说明**:不支持的场景、已知的兼容性问题、特殊边界情况
|
|
153
|
+
|
|
154
|
+
### 内容要求
|
|
155
|
+
|
|
156
|
+
#### 必须包含的关键内容
|
|
157
|
+
|
|
158
|
+
**1. 功能范围**
|
|
159
|
+
- 业务场景、平台范围、排除范围
|
|
160
|
+
|
|
161
|
+
**2. 页面结构**
|
|
162
|
+
- 页面/模块布局、组件层级关系
|
|
163
|
+
|
|
164
|
+
**3. 数据展示**
|
|
165
|
+
- 数据来源(用"由系统返回"替代接口名)
|
|
166
|
+
- 数据展示规则
|
|
167
|
+
- 空数据/加载/错误状态的表现
|
|
168
|
+
|
|
169
|
+
**4. 交互逻辑**
|
|
170
|
+
- 操作入口、触发条件、即时反馈、结果处理
|
|
171
|
+
|
|
172
|
+
**5. 状态管理**
|
|
173
|
+
- 状态触发条件、转换逻辑、数据保持/重置
|
|
174
|
+
|
|
175
|
+
**6. 页面跳转**
|
|
176
|
+
- 跳转触发、目标页面、参数传递(只说明内容,不涉及字段)、返回逻辑
|
|
177
|
+
|
|
178
|
+
**7. 跨系统交互**
|
|
179
|
+
- 交互触发、返回处理、结果查询和展示
|
|
180
|
+
|
|
181
|
+
**8. 异常处理**
|
|
182
|
+
- 异常场景、提示方式、恢复机制
|
|
183
|
+
|
|
184
|
+
**9. 交互细节**
|
|
185
|
+
- 视觉反馈(选中/不可用等)
|
|
186
|
+
- 动画效果(展开/收起/弹出等)
|
|
187
|
+
- 确认弹窗
|
|
188
|
+
|
|
189
|
+
**10. 性能要求**
|
|
190
|
+
- 加载速度、响应时间、动画流畅度
|
|
191
|
+
|
|
192
|
+
#### 视角要求
|
|
193
|
+
|
|
194
|
+
**从用户视角描述**
|
|
195
|
+
- ✅ 描述"用户能看到什么"、"用户能做什么"、"操作后有什么反馈"
|
|
196
|
+
|
|
197
|
+
**避免技术细节**
|
|
198
|
+
- ❌ 不要描述"轮询 5 次"、"骨架屏 vs 局部加载"、"调用 XXX 接口"、"使用 XXX SDK"
|
|
199
|
+
- ✅ 用"查询超时"、"加载状态"、"由系统返回"替代
|
|
200
|
+
|
|
201
|
+
#### 格式化要求
|
|
202
|
+
- 用户故事:作为[角色],我希望[功能],以便[价值]
|
|
203
|
+
- 验收标准:WHEN [触发条件] THEN THE System SHALL [预期行为]
|
|
204
|
+
- 验收标准必须可测试:使用具体的时间、数量、状态,避免"快速响应"等模糊描述
|
|
205
|
+
|
|
206
|
+
### 格式要求
|
|
207
|
+
|
|
208
|
+
#### 用户故事格式
|
|
209
|
+
\`\`\`
|
|
210
|
+
**用户故事**:作为[角色],我希望[功能],以便[价值]。
|
|
211
|
+
\`\`\`
|
|
212
|
+
|
|
213
|
+
#### 验收标准格式
|
|
214
|
+
\`\`\`
|
|
215
|
+
#### 验收标准
|
|
216
|
+
|
|
217
|
+
1. WHEN [触发条件] THEN THE System SHALL [预期行为]
|
|
218
|
+
2. WHEN [触发条件] THEN THE System SHALL [预期行为]
|
|
219
|
+
3. WHEN [触发条件] THEN THE System SHALL [预期行为]
|
|
220
|
+
...
|
|
221
|
+
\`\`\`
|
|
222
|
+
|
|
223
|
+
#### 可测试性要求
|
|
224
|
+
- 每个验收标准必须可测试、可验证
|
|
225
|
+
- 避免模糊的描述(如"快速响应")
|
|
226
|
+
- 使用具体的时间、数量、状态描述
|
|
84
227
|
|
|
85
|
-
|
|
228
|
+
## 核心约束
|
|
86
229
|
|
|
87
|
-
|
|
230
|
+
### 1. 内容完整性
|
|
231
|
+
- 必须包含所有 4 个章节(介绍、功能需求、交互细节、技术要求与限制)
|
|
232
|
+
- 每个功能需求必须有用户故事和 3-6 条验收标准
|
|
233
|
+
- 必须覆盖 10 个前端开发重点
|
|
88
234
|
|
|
89
|
-
|
|
235
|
+
### 2. 视角正确性
|
|
236
|
+
- 从用户视角描述功能
|
|
237
|
+
- 不涉及技术实现细节(接口、SDK、轮询机制等)
|
|
238
|
+
- 用"由系统返回"、"加载状态"、"查询超时"替代技术术语
|
|
90
239
|
|
|
91
|
-
###
|
|
240
|
+
### 3. 内容独立性
|
|
241
|
+
- 不要生成接口文档(放在设计文档)
|
|
242
|
+
- 不要生成数据模型(放在设计文档)
|
|
243
|
+
- 不要生成技术架构(放在设计文档)
|
|
244
|
+
- 不要生成代码示例(放在开发阶段)
|
|
92
245
|
|
|
93
|
-
|
|
94
|
-
- System 代表整个系统(前后端整体)
|
|
95
|
-
- 覆盖所有功能点、用户场景、异常情况
|
|
96
|
-
- Acceptance Criteria 必须可测试、具体明确
|
|
97
|
-
- 每个需求 3-6 条验收标准
|
|
246
|
+
## 开始执行
|
|
98
247
|
|
|
99
|
-
|
|
248
|
+
请按照以上要求,从输入的 PRD ${designSource ? "和设计稿" : ""} 中提取信息,生成完整的需求文档到:\`${outputPath}\`
|
|
100
249
|
|
|
101
|
-
|
|
102
|
-
- 不要凭空猜测或假设需求
|
|
103
|
-
- 列出具体的疑问点,等待用户确认后再生成文档
|
|
250
|
+
生成过程中,如果遇到不明确的内容,必须向用户确认,不要假设答案。
|
|
104
251
|
`;
|
|
105
252
|
return prompt;
|
|
106
253
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/requirements/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAC;AAC9D,OAAO,EACL,0BAA0B,EAC1B,uBAAuB,EACxB,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/requirements/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,11 +12,16 @@ interface ProcessResult {
|
|
|
12
12
|
instruction: string;
|
|
13
13
|
};
|
|
14
14
|
}
|
|
15
|
+
interface RequirementSource {
|
|
16
|
+
type: "file" | "url";
|
|
17
|
+
path?: string;
|
|
18
|
+
url?: string;
|
|
19
|
+
}
|
|
15
20
|
/**
|
|
16
21
|
* 步骤 2:处理需求文档输入
|
|
17
22
|
* 这是整体流程的第二步,专门处理需求文档
|
|
18
23
|
*/
|
|
19
|
-
export declare function processRequirementDocument(requirementSource: RequirementSource | undefined, featureName: string): Promise<ProcessResult>;
|
|
24
|
+
export declare function processRequirementDocument(requirementSource: RequirementSource | undefined, featureName: string, outputFileName?: string): Promise<ProcessResult>;
|
|
20
25
|
/**
|
|
21
26
|
* 尝试读取已保存的需求文档
|
|
22
27
|
* 如果用户之前已经按照指令保存了文件,优先使用已保存的内容
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requirement-processor.d.ts","sourceRoot":"","sources":["../../../src/tools/requirements/requirement-processor.ts"],"names":[],"mappings":"AAGA,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,UAAU,aAAa;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE;QACZ,IAAI,EAAE,UAAU,GAAG,UAAU,GAAG,iBAAiB,CAAC;QAClD,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED;;;GAGG;AACH,wBAAsB,0BAA0B,CAC9C,iBAAiB,EAAE,iBAAiB,GAAG,SAAS,EAChD,WAAW,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"requirement-processor.d.ts","sourceRoot":"","sources":["../../../src/tools/requirements/requirement-processor.ts"],"names":[],"mappings":"AAGA,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,UAAU,aAAa;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE;QACZ,IAAI,EAAE,UAAU,GAAG,UAAU,GAAG,iBAAiB,CAAC;QAClD,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,wBAAsB,0BAA0B,CAC9C,iBAAiB,EAAE,iBAAiB,GAAG,SAAS,EAChD,WAAW,EAAE,MAAM,EACnB,cAAc,GAAE,MAAgC,GAC/C,OAAO,CAAC,aAAa,CAAC,CA4FxB;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAYxB"}
|
|
@@ -4,7 +4,7 @@ import * as fs from "fs/promises";
|
|
|
4
4
|
* 步骤 2:处理需求文档输入
|
|
5
5
|
* 这是整体流程的第二步,专门处理需求文档
|
|
6
6
|
*/
|
|
7
|
-
export async function processRequirementDocument(requirementSource, featureName) {
|
|
7
|
+
export async function processRequirementDocument(requirementSource, featureName, outputFileName = "origin-requirement.md") {
|
|
8
8
|
// 2.1 校验是否提供了需求文档
|
|
9
9
|
if (!requirementSource) {
|
|
10
10
|
return {
|
|
@@ -32,7 +32,7 @@ export async function processRequirementDocument(requirementSource, featureName)
|
|
|
32
32
|
const ext = filePath.split(".").pop()?.toLowerCase();
|
|
33
33
|
// 2.2.1 PDF 文件 - 返回读取指令
|
|
34
34
|
if (ext === "pdf") {
|
|
35
|
-
const outputMdPath = `.specs/requirements/${featureName}
|
|
35
|
+
const outputMdPath = `.specs/requirements/${featureName}/${outputFileName}`;
|
|
36
36
|
return {
|
|
37
37
|
success: false,
|
|
38
38
|
message: `📄 检测到 PDF 文件
|
|
@@ -48,7 +48,7 @@ export async function processRequirementDocument(requirementSource, featureName)
|
|
|
48
48
|
}
|
|
49
49
|
// 2.2.2 Markdown 文件 - 保存到固定位置
|
|
50
50
|
if (ext === "md" || ext === "markdown") {
|
|
51
|
-
const outputMdPath = `.specs/requirements/${featureName}
|
|
51
|
+
const outputMdPath = `.specs/requirements/${featureName}/${outputFileName}`;
|
|
52
52
|
// 读取 Markdown 内容
|
|
53
53
|
const content = await fs.readFile(filePath, "utf-8");
|
|
54
54
|
// 保存到固定位置
|
|
@@ -70,7 +70,7 @@ export async function processRequirementDocument(requirementSource, featureName)
|
|
|
70
70
|
if (!url) {
|
|
71
71
|
throw new McpError(-32602, "网页 URL 不能为空");
|
|
72
72
|
}
|
|
73
|
-
const outputMdPath = `.specs/requirements/${featureName}
|
|
73
|
+
const outputMdPath = `.specs/requirements/${featureName}/${outputFileName}`;
|
|
74
74
|
return {
|
|
75
75
|
success: false,
|
|
76
76
|
message: `🌐 检测到网页 URL
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requirement-processor.js","sourceRoot":"","sources":["../../../src/tools/requirements/requirement-processor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAC;AAC9D,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"requirement-processor.js","sourceRoot":"","sources":["../../../src/tools/requirements/requirement-processor.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
## 功能说明
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
从产品 PRD 文档(支持 Markdown/PDF/网页)、可选的设计稿(Figma/文件)和后端文档(文件/网页)生成结构化的前端需求文档。
|
|
10
10
|
|
|
11
11
|
输出路径固定为:`.specs/requirements/{featureName}/requirements.md`
|
|
12
12
|
|
|
@@ -16,16 +16,26 @@
|
|
|
16
16
|
|
|
17
17
|
工具负责:
|
|
18
18
|
1. 统一保存原始文档到固定位置(origin-requirement.md)
|
|
19
|
-
2.
|
|
19
|
+
2. 提供专业的前端需求分析提示词(指导 AI 如何生成 requirements.md)
|
|
20
20
|
|
|
21
21
|
AI 负责:
|
|
22
22
|
1. 读取原始文档
|
|
23
|
-
2.
|
|
24
|
-
3.
|
|
23
|
+
2. 如有设计稿,使用 Figma MCP 读取设计稿内容
|
|
24
|
+
3. 如有后端文档,读取后端文档作为生成验收标准的参考
|
|
25
|
+
4. 按照前端需求分析标准,生成高质量的需求文档
|
|
26
|
+
|
|
27
|
+
## 输出文档结构
|
|
28
|
+
|
|
29
|
+
生成的 `requirements.md` 包含以下 4 个章节:
|
|
30
|
+
|
|
31
|
+
1. **介绍**:功能概述、核心价值、涉及范围、核心指标、术语表
|
|
32
|
+
2. **功能需求**:用户故事 + 验收标准(每个需求 3-6 条)
|
|
33
|
+
3. **交互细节**:视觉反馈、动画效果、错误处理、确认弹窗
|
|
34
|
+
4. **技术要求与限制**:性能需求、可用性需求、兼容性需求、限制说明
|
|
25
35
|
|
|
26
36
|
## 使用流程
|
|
27
37
|
|
|
28
|
-
### 流程 1:Markdown
|
|
38
|
+
### 流程 1:Markdown 文件 + Figma 设计稿 + 后端文档(完整流程)
|
|
29
39
|
|
|
30
40
|
**调用**:
|
|
31
41
|
```json
|
|
@@ -34,7 +44,15 @@ AI 负责:
|
|
|
34
44
|
"type": "file",
|
|
35
45
|
"path": "prd.md"
|
|
36
46
|
},
|
|
37
|
-
"featureName": "voice-recording"
|
|
47
|
+
"featureName": "voice-recording",
|
|
48
|
+
"designSource": {
|
|
49
|
+
"type": "figma",
|
|
50
|
+
"url": "https://figma.com/design/xxx/xxx?node-id=1-2"
|
|
51
|
+
},
|
|
52
|
+
"backendSource": {
|
|
53
|
+
"type": "file",
|
|
54
|
+
"path": "backend-api.md"
|
|
55
|
+
}
|
|
38
56
|
}
|
|
39
57
|
```
|
|
40
58
|
|
|
@@ -43,20 +61,102 @@ AI 负责:
|
|
|
43
61
|
📝 需求文档已准备完毕
|
|
44
62
|
|
|
45
63
|
**原始文档位置**:.specs/requirements/voice-recording/origin-requirement.md
|
|
64
|
+
**设计稿链接**:https://figma.com/design/xxx/xxx?node-id=1-2
|
|
65
|
+
**后端文档位置**:.specs/requirements/voice-recording/backend-doc.md
|
|
46
66
|
**目标输出位置**:.specs/requirements/voice-recording/requirements.md
|
|
47
67
|
|
|
48
|
-
#
|
|
49
|
-
|
|
68
|
+
# 产品 PRD 转需求文档
|
|
69
|
+
...(前端需求分析提示词)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**AI 执行**:
|
|
73
|
+
1. 读取 `.specs/requirements/voice-recording/origin-requirement.md`
|
|
74
|
+
2. 使用 Figma MCP 工具读取设计稿
|
|
75
|
+
3. 读取 `.specs/requirements/voice-recording/backend-doc.md` 作为生成验收标准的参考
|
|
76
|
+
4. 按照 4 章节结构分析内容
|
|
77
|
+
5. 生成 `.specs/requirements/voice-recording/requirements.md`
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
### 流程 2:Markdown 文件 + Figma 设计稿(推荐)
|
|
84
|
+
|
|
85
|
+
**调用**:
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"requirementSource": {
|
|
89
|
+
"type": "file",
|
|
90
|
+
"path": "prd.md"
|
|
91
|
+
},
|
|
92
|
+
"featureName": "voice-recording",
|
|
93
|
+
"designSource": {
|
|
94
|
+
"type": "figma",
|
|
95
|
+
"url": "https://figma.com/design/xxx/xxx?node-id=1-2"
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**返回**:同流程 1(无后端文档信息)
|
|
101
|
+
|
|
102
|
+
**AI 执行**:
|
|
103
|
+
1. 读取 `.specs/requirements/voice-recording/origin-requirement.md`
|
|
104
|
+
2. 使用 Figma MCP 工具读取设计稿
|
|
105
|
+
3. 按照 4 章节结构分析内容
|
|
106
|
+
4. 生成 `.specs/requirements/voice-recording/requirements.md`
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
### 流程 3:Markdown 文件(无设计稿和后端文档)
|
|
111
|
+
|
|
112
|
+
**调用**:
|
|
113
|
+
```json
|
|
114
|
+
{
|
|
115
|
+
"requirementSource": {
|
|
116
|
+
"type": "file",
|
|
117
|
+
"path": "prd.md"
|
|
118
|
+
},
|
|
119
|
+
"featureName": "voice-recording"
|
|
120
|
+
}
|
|
50
121
|
```
|
|
51
122
|
|
|
123
|
+
**返回**:同流程 1(无设计稿和后端文档信息)
|
|
124
|
+
|
|
52
125
|
**AI 执行**:
|
|
53
126
|
1. 读取 `.specs/requirements/voice-recording/origin-requirement.md`
|
|
54
|
-
2.
|
|
127
|
+
2. 仅基于 PRD 生成需求文档
|
|
55
128
|
3. 生成 `.specs/requirements/voice-recording/requirements.md`
|
|
56
129
|
|
|
57
130
|
---
|
|
58
131
|
|
|
59
|
-
### 流程
|
|
132
|
+
### 流程 4:Markdown 文件 + 后端文档(无设计稿)
|
|
133
|
+
|
|
134
|
+
**调用**:
|
|
135
|
+
```json
|
|
136
|
+
{
|
|
137
|
+
"requirementSource": {
|
|
138
|
+
"type": "file",
|
|
139
|
+
"path": "prd.md"
|
|
140
|
+
},
|
|
141
|
+
"featureName": "voice-recording",
|
|
142
|
+
"backendSource": {
|
|
143
|
+
"type": "file",
|
|
144
|
+
"path": "backend-api.md"
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**返回**:同流程 1(无设计稿信息)
|
|
150
|
+
|
|
151
|
+
**AI 执行**:
|
|
152
|
+
1. 读取 `.specs/requirements/voice-recording/origin-requirement.md`
|
|
153
|
+
2. 读取 `.specs/requirements/voice-recording/backend-doc.md` 作为生成验收标准的参考
|
|
154
|
+
3. 按照 4 章节结构分析内容
|
|
155
|
+
4. 生成 `.specs/requirements/voice-recording/requirements.md`
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
### 流程 5:PDF 文件 + Figma 设计稿 + 后端文档
|
|
60
160
|
|
|
61
161
|
**第 1 次调用**:
|
|
62
162
|
```json
|
|
@@ -65,7 +165,15 @@ AI 负责:
|
|
|
65
165
|
"type": "file",
|
|
66
166
|
"path": "prd.pdf"
|
|
67
167
|
},
|
|
68
|
-
"featureName": "voice-recording"
|
|
168
|
+
"featureName": "voice-recording",
|
|
169
|
+
"designSource": {
|
|
170
|
+
"type": "figma",
|
|
171
|
+
"url": "https://figma.com/design/xxx/xxx?node-id=1-2"
|
|
172
|
+
},
|
|
173
|
+
"backendSource": {
|
|
174
|
+
"type": "file",
|
|
175
|
+
"path": "backend-api.md"
|
|
176
|
+
}
|
|
69
177
|
}
|
|
70
178
|
```
|
|
71
179
|
|
|
@@ -90,7 +198,15 @@ AI 负责:
|
|
|
90
198
|
"type": "file",
|
|
91
199
|
"path": "prd.pdf"
|
|
92
200
|
},
|
|
93
|
-
"featureName": "voice-recording"
|
|
201
|
+
"featureName": "voice-recording",
|
|
202
|
+
"designSource": {
|
|
203
|
+
"type": "figma",
|
|
204
|
+
"url": "https://figma.com/design/xxx/xxx?node-id=1-2"
|
|
205
|
+
},
|
|
206
|
+
"backendSource": {
|
|
207
|
+
"type": "file",
|
|
208
|
+
"path": "backend-api.md"
|
|
209
|
+
}
|
|
94
210
|
}
|
|
95
211
|
```
|
|
96
212
|
|
|
@@ -98,7 +214,7 @@ AI 负责:
|
|
|
98
214
|
|
|
99
215
|
---
|
|
100
216
|
|
|
101
|
-
### 流程
|
|
217
|
+
### 流程 6:网页 URL + Figma 设计稿 + 后端文档
|
|
102
218
|
|
|
103
219
|
**第 1 次调用**:
|
|
104
220
|
```json
|
|
@@ -107,7 +223,15 @@ AI 负责:
|
|
|
107
223
|
"type": "url",
|
|
108
224
|
"url": "https://wiki.jd.com/pages/viewpage.action?pageId=123456"
|
|
109
225
|
},
|
|
110
|
-
"featureName": "voice-recording"
|
|
226
|
+
"featureName": "voice-recording",
|
|
227
|
+
"designSource": {
|
|
228
|
+
"type": "figma",
|
|
229
|
+
"url": "https://figma.com/design/xxx/xxx?node-id=1-2"
|
|
230
|
+
},
|
|
231
|
+
"backendSource": {
|
|
232
|
+
"type": "url",
|
|
233
|
+
"url": "https://wiki.jd.com/pages/viewpage.action?pageId=789012"
|
|
234
|
+
}
|
|
111
235
|
}
|
|
112
236
|
```
|
|
113
237
|
|
|
@@ -121,11 +245,13 @@ AI 负责:
|
|
|
121
245
|
```
|
|
122
246
|
|
|
123
247
|
**AI 执行**:
|
|
124
|
-
1. 使用 Chrome DevTools MCP
|
|
248
|
+
1. 使用 Chrome DevTools MCP 读取 PRD 网页
|
|
125
249
|
2. 保存到 `.specs/requirements/voice-recording/origin-requirement.md`
|
|
126
|
-
3.
|
|
250
|
+
3. 使用 Chrome DevTools MCP 读取后端文档网页
|
|
251
|
+
4. 保存到 `.specs/requirements/voice-recording/backend-doc.md`
|
|
252
|
+
5. 重新调用工具
|
|
127
253
|
|
|
128
|
-
**第 2 次调用**:同流程
|
|
254
|
+
**第 2 次调用**:同流程 5
|
|
129
255
|
|
|
130
256
|
---
|
|
131
257
|
|
|
@@ -138,22 +264,61 @@ AI 负责:
|
|
|
138
264
|
| `requirementSource.path` | string | - | 文件路径(type=file 时必填) |
|
|
139
265
|
| `requirementSource.url` | string | - | 网页 URL(type=url 时必填) |
|
|
140
266
|
| `featureName` | string | ✅ | 功能名称,用于生成输出路径 |
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
-
|
|
147
|
-
-
|
|
148
|
-
-
|
|
149
|
-
|
|
150
|
-
|
|
267
|
+
| `designSource` | object | - | 设计稿来源(可选) |
|
|
268
|
+
| `designSource.type` | string | - | "figma" 或 "file" |
|
|
269
|
+
| `designSource.url` | string | - | Figma 链接(type=figma 时必填) |
|
|
270
|
+
| `designSource.path` | string | - | 设计稿文件路径(type=file 时必填) |
|
|
271
|
+
| `backendSource` | object | - | 后端文档来源(可选) |
|
|
272
|
+
| `backendSource.type` | string | - | "file" 或 "url" |
|
|
273
|
+
| `backendSource.path` | string | - | 后端文档路径(type=file 时必填) |
|
|
274
|
+
| `backendSource.url` | string | - | 后端文档网页 URL(type=url 时必填) |
|
|
275
|
+
|
|
276
|
+
## 输出文档要求
|
|
277
|
+
|
|
278
|
+
### 文档结构(4 个章节)
|
|
279
|
+
|
|
280
|
+
1. **介绍**
|
|
281
|
+
- 功能概述:一句话说明功能是什么、解决什么问题
|
|
282
|
+
- 核心价值:为什么要做这个功能
|
|
283
|
+
- 涉及范围:业务场景、平台支持、排除范围
|
|
284
|
+
- 核心指标:衡量成功的关键指标
|
|
285
|
+
- 术语表:关键术语定义
|
|
286
|
+
|
|
287
|
+
2. **功能需求**
|
|
288
|
+
- 用户故事:作为[角色],我希望[功能],以便[价值]
|
|
289
|
+
- 验收标准:WHEN [触发条件] THEN THE System SHALL [预期行为](3-6 条)
|
|
290
|
+
- 说明:补充必要的细节(不涉及技术实现)
|
|
291
|
+
|
|
292
|
+
3. **交互细节**
|
|
293
|
+
- 视觉反馈:选中、不可用、加载、错误的视觉表现
|
|
294
|
+
- 动画效果:展开/收起、弹出、跳转的动画时长和方式
|
|
295
|
+
- 错误处理:各种错误场景的用户提示和处理方式
|
|
296
|
+
- 确认弹窗:需要用户确认的场景和确认内容
|
|
297
|
+
|
|
298
|
+
4. **技术要求与限制**
|
|
299
|
+
- 性能需求:响应时间、加载速度、动画流畅度
|
|
300
|
+
- 可用性需求:状态清晰性、错误提示友好性、操作便捷性
|
|
301
|
+
- 兼容性需求:支持的系统版本、设备类型、浏览器要求
|
|
302
|
+
- 限制说明:不支持的场景、已知的兼容性问题、特殊边界情况
|
|
303
|
+
|
|
304
|
+
### 核心约束
|
|
305
|
+
|
|
306
|
+
#### 视角要求
|
|
307
|
+
- ✅ 从用户视角描述:"用户能看到什么"、"用户能做什么"
|
|
308
|
+
- ❌ 不涉及技术实现细节(接口、SDK、轮询机制等)
|
|
309
|
+
- ✅ 用"由系统返回"、"加载状态"、"查询超时"替代技术术语
|
|
310
|
+
|
|
311
|
+
#### 内容要求
|
|
312
|
+
- 必须覆盖 10 个前端开发重点:功能范围、页面结构、数据展示、交互逻辑、状态管理、页面跳转、跨系统交互、异常处理、交互细节、性能要求
|
|
313
|
+
- 每个需求 3-6 条验收标准
|
|
314
|
+
- 验收标准必须可测试、具体明确
|
|
151
315
|
|
|
152
316
|
## 文件路径
|
|
153
317
|
|
|
154
318
|
所有文件统一保存在 `.specs/requirements/{featureName}/` 目录下:
|
|
155
319
|
|
|
156
320
|
- `origin-requirement.md` - 原始需求文档(统一保存位置)
|
|
321
|
+
- `backend-doc.md` - 后端文档(如提供,统一保存位置)
|
|
157
322
|
- `requirements.md` - 最终生成的需求文档
|
|
158
323
|
|
|
159
324
|
## 智能缓存
|
|
@@ -169,7 +334,18 @@ AI 负责:
|
|
|
169
334
|
1. **featureName 必填**:用于生成文件路径
|
|
170
335
|
2. **智能缓存**:重新调用时会自动读取已保存的文件
|
|
171
336
|
3. **分步执行**:PDF/URL 需要先读取内容,再分析生成
|
|
172
|
-
4.
|
|
337
|
+
4. **设计稿集成**:提供 Figma 设计稿可生成更准确的需求文档
|
|
338
|
+
5. **后端文档参考**:提供后端文档可以作为生成验收标准的参考,让需求更贴合实际接口
|
|
339
|
+
6. **AI 自主生成**:工具只提供专业的前端需求分析提示词,AI 自己完成分析和生成
|
|
340
|
+
|
|
341
|
+
## 最佳实践
|
|
342
|
+
|
|
343
|
+
1. **推荐提供设计稿**:Figma 设计稿可以提供更准确的交互细节和视觉反馈信息
|
|
344
|
+
2. **提供后端文档**:后端文档包含接口定义、数据结构等,可帮助生成更准确的验收标准
|
|
345
|
+
3. **确保 PRD 完整性**:PRD 应包含项目背景、功能列表、系统流程、详细说明
|
|
346
|
+
4. **明确功能范围**:在生成需求文档时,明确业务场景、平台支持、排除范围
|
|
347
|
+
5. **验收标准可测试**:每条验收标准都应该能够被明确验证
|
|
348
|
+
6. **及时澄清疑问**:如果 PRD 中有不清晰、模糊、矛盾的地方,必须先向用户确认
|
|
173
349
|
|
|
174
350
|
## 触发词
|
|
175
351
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bmall-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "MCP Server for bmall development rules and tools",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -28,4 +28,4 @@
|
|
|
28
28
|
"typescript": "^5.0.0",
|
|
29
29
|
"ts-node": "^10.9.0"
|
|
30
30
|
}
|
|
31
|
-
}
|
|
31
|
+
}
|
package/src/server/tools.ts
CHANGED
|
@@ -133,7 +133,7 @@ export const toolDefinitions = [
|
|
|
133
133
|
},
|
|
134
134
|
{
|
|
135
135
|
name: "generate_requirements",
|
|
136
|
-
description: "需求文档生成:从需求文档(PRD
|
|
136
|
+
description: "需求文档生成:从需求文档(PRD/文件/网页)和可选的设计稿、后端文档生成结构化的 requirements.md。输出路径固定为 .specs/requirements/{featureName}/requirements.md。触发词:生成需求文档、需求分析、requirements",
|
|
137
137
|
inputSchema: {
|
|
138
138
|
type: "object",
|
|
139
139
|
properties: {
|
|
@@ -161,6 +161,44 @@ export const toolDefinitions = [
|
|
|
161
161
|
type: "string",
|
|
162
162
|
description: "功能名称(必填),用于生成输出路径 .specs/requirements/{featureName}/requirements.md",
|
|
163
163
|
},
|
|
164
|
+
designSource: {
|
|
165
|
+
type: "object",
|
|
166
|
+
description: "设计稿来源(可选,支持 Figma 或文件)",
|
|
167
|
+
properties: {
|
|
168
|
+
type: {
|
|
169
|
+
type: "string",
|
|
170
|
+
enum: ["figma", "file"],
|
|
171
|
+
description: "设计稿类型",
|
|
172
|
+
},
|
|
173
|
+
url: {
|
|
174
|
+
type: "string",
|
|
175
|
+
description: "Figma 链接,当 type 为 figma 时必填",
|
|
176
|
+
},
|
|
177
|
+
path: {
|
|
178
|
+
type: "string",
|
|
179
|
+
description: "设计稿文件路径,当 type 为 file 时必填",
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
backendSource: {
|
|
184
|
+
type: "object",
|
|
185
|
+
description: "后端文档来源(可选,支持文件或网页)",
|
|
186
|
+
properties: {
|
|
187
|
+
type: {
|
|
188
|
+
type: "string",
|
|
189
|
+
enum: ["file", "url"],
|
|
190
|
+
description: "文件或网页",
|
|
191
|
+
},
|
|
192
|
+
path: {
|
|
193
|
+
type: "string",
|
|
194
|
+
description: "文件路径(.md/.pdf),当 type 为 file 时必填",
|
|
195
|
+
},
|
|
196
|
+
url: {
|
|
197
|
+
type: "string",
|
|
198
|
+
description: "网页 URL,当 type 为 url 时必填",
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
},
|
|
164
202
|
},
|
|
165
203
|
required: ["requirementSource", "featureName"],
|
|
166
204
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { McpError } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
-
import {
|
|
3
|
-
processRequirementDocument,
|
|
4
|
-
tryReadSavedRequirement
|
|
2
|
+
import {
|
|
3
|
+
processRequirementDocument,
|
|
4
|
+
tryReadSavedRequirement
|
|
5
5
|
} from "./requirement-processor.js";
|
|
6
6
|
|
|
7
7
|
interface RequirementSource {
|
|
@@ -13,6 +13,16 @@ interface RequirementSource {
|
|
|
13
13
|
interface GenerateRequirementsParams {
|
|
14
14
|
requirementSource: RequirementSource;
|
|
15
15
|
featureName: string;
|
|
16
|
+
designSource?: {
|
|
17
|
+
type: "figma" | "file";
|
|
18
|
+
url?: string;
|
|
19
|
+
path?: string;
|
|
20
|
+
};
|
|
21
|
+
backendSource?: {
|
|
22
|
+
type: "file" | "url";
|
|
23
|
+
path?: string;
|
|
24
|
+
url?: string;
|
|
25
|
+
};
|
|
16
26
|
}
|
|
17
27
|
|
|
18
28
|
/**
|
|
@@ -88,21 +98,61 @@ export async function generateRequirements(
|
|
|
88
98
|
// 2.2.2 需求文档已读取并保存(Markdown 文件)
|
|
89
99
|
}
|
|
90
100
|
|
|
91
|
-
// 3.
|
|
101
|
+
// 3. 检查设计稿
|
|
102
|
+
let designSourceInfo = "";
|
|
103
|
+
if (params.designSource) {
|
|
104
|
+
if (params.designSource.type === "figma") {
|
|
105
|
+
designSourceInfo = `**设计稿链接**:${params.designSource.url || "Figma 链接未提供"}\n`;
|
|
106
|
+
} else if (params.designSource.type === "file") {
|
|
107
|
+
designSourceInfo = `**设计稿文件**:${params.designSource.path || "设计稿路径未提供"}\n`;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// 4. 处理后端文档
|
|
112
|
+
let backendSourceInfo = "";
|
|
113
|
+
if (params.backendSource) {
|
|
114
|
+
const backendResult = await processRequirementDocument(
|
|
115
|
+
params.backendSource,
|
|
116
|
+
params.featureName,
|
|
117
|
+
"backend-doc.md"
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
if (!backendResult.success) {
|
|
121
|
+
return {
|
|
122
|
+
success: false,
|
|
123
|
+
message: backendResult.message!,
|
|
124
|
+
needsAction: backendResult.needsAction,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (params.backendSource.type === "file") {
|
|
129
|
+
backendSourceInfo = `**后端文档位置**:.specs/requirements/${params.featureName}/backend-doc.md\n`;
|
|
130
|
+
} else if (params.backendSource.type === "url") {
|
|
131
|
+
backendSourceInfo = `**后端文档位置**:.specs/requirements/${params.featureName}/backend-doc.md\n`;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// 5. 生成分析提示词
|
|
92
136
|
const outputPath = `.specs/requirements/${params.featureName}/requirements.md`;
|
|
93
137
|
const originDocPath = `.specs/requirements/${params.featureName}/origin-requirement.md`;
|
|
94
|
-
|
|
138
|
+
|
|
95
139
|
let message = "📝 需求文档已准备完毕\n\n";
|
|
96
140
|
message += `**原始文档位置**:${originDocPath}\n`;
|
|
141
|
+
if (designSourceInfo) {
|
|
142
|
+
message += designSourceInfo;
|
|
143
|
+
}
|
|
144
|
+
if (backendSourceInfo) {
|
|
145
|
+
message += backendSourceInfo;
|
|
146
|
+
}
|
|
97
147
|
message += `**目标输出位置**:${outputPath}\n\n`;
|
|
98
|
-
message += buildAnalysisPrompt(originDocPath, outputPath);
|
|
148
|
+
message += buildAnalysisPrompt(originDocPath, outputPath, params.designSource, params.backendSource);
|
|
99
149
|
|
|
100
150
|
return {
|
|
101
151
|
success: false,
|
|
102
152
|
message,
|
|
103
153
|
needsAction: {
|
|
104
154
|
type: "analyze_content",
|
|
105
|
-
instruction: `分析 ${originDocPath},生成 ${outputPath}`,
|
|
155
|
+
instruction: `分析 ${originDocPath}${params.designSource ? "、设计稿" : ""}${params.backendSource ? "、后端文档" : ""},生成 ${outputPath}`,
|
|
106
156
|
},
|
|
107
157
|
};
|
|
108
158
|
} catch (error) {
|
|
@@ -118,43 +168,159 @@ export async function generateRequirements(
|
|
|
118
168
|
|
|
119
169
|
function buildAnalysisPrompt(
|
|
120
170
|
originDocPath: string,
|
|
121
|
-
outputPath: string
|
|
171
|
+
outputPath: string,
|
|
172
|
+
designSource?: { type: "figma" | "file"; url?: string; path?: string },
|
|
173
|
+
backendSource?: { type: "file" | "url"; path?: string; url?: string }
|
|
122
174
|
): string {
|
|
123
|
-
|
|
175
|
+
const featureName = outputPath.split('/')[2];
|
|
176
|
+
|
|
177
|
+
let prompt = `# 产品 PRD 转需求文档
|
|
178
|
+
|
|
179
|
+
## 角色定义
|
|
124
180
|
|
|
125
|
-
|
|
181
|
+
你是一位资深的前端需求分析专家,擅长从产品 PRD 中提取并转化为前端开发可执行的需求文档。
|
|
126
182
|
|
|
127
|
-
|
|
183
|
+
## 任务目标
|
|
128
184
|
|
|
129
|
-
|
|
185
|
+
根据产品 PRD 文档${designSource ? "、设计稿" : ""}${backendSource ? "和后端文档" : ""},生成一份高质量的需求文档,确保前端开发人员能够清晰理解用户需求,准确实现功能。
|
|
130
186
|
|
|
131
|
-
|
|
187
|
+
## 输入材料
|
|
188
|
+
|
|
189
|
+
1. **产品 PRD 文档**:\`${originDocPath}\`(包含项目背景、功能列表、系统流程、详细说明等)
|
|
190
|
+
2. **设计稿**:${designSource ? `已提供${designSource.type === "figma" ? "Figma 链接,使用 MCP 工具读取" : "设计稿文件"}:${designSource.url || designSource.path}` : "未提供(如有设计稿,请使用 Figma MCP 工具读取)" }
|
|
191
|
+
3. **后端文档**:${backendSource ? `已提供${backendSource.type === "url" ? "网页 URL" : "文件"}:.specs/requirements/${featureName}/backend-doc.md(包含接口定义、数据结构、后端逻辑等,可作为生成验收标准的参考)` : "未提供(如有后端文档,可作为生成验收标准的参考)" }
|
|
192
|
+
|
|
193
|
+
## 输出要求
|
|
132
194
|
|
|
133
195
|
### 文档结构
|
|
134
196
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
197
|
+
必须包含以下章节:
|
|
198
|
+
|
|
199
|
+
#### 1. 介绍
|
|
200
|
+
- **功能概述**:一句话说明功能是什么、解决什么问题
|
|
201
|
+
- **核心价值**:为什么要做这个功能(用户体验、转化率、营销能力等)
|
|
202
|
+
- **涉及范围**:
|
|
203
|
+
- 业务场景范围
|
|
204
|
+
- 平台支持范围
|
|
205
|
+
- 排除范围
|
|
206
|
+
- **核心指标**:衡量成功的关键指标
|
|
207
|
+
- **术语表**:关键术语定义,避免歧义
|
|
208
|
+
|
|
209
|
+
#### 2. 功能需求
|
|
210
|
+
每个需求必须包含:
|
|
211
|
+
- **用户故事**:作为角色,我希望功能,以便价值
|
|
212
|
+
- **验收标准**:WHEN 触发条件 THEN 预期行为(至少 3-6 条)
|
|
213
|
+
- **说明**:补充必要的细节(不涉及技术实现)
|
|
214
|
+
|
|
215
|
+
#### 3. 交互细节
|
|
216
|
+
- **视觉反馈**:选中、不可用、加载、错误的视觉表现
|
|
217
|
+
- **动画效果**:展开/收起、弹出、跳转的动画时长和方式
|
|
218
|
+
- **错误处理**:各种错误场景的用户提示和处理方式
|
|
219
|
+
- **确认弹窗**:需要用户确认的场景和确认内容
|
|
220
|
+
|
|
221
|
+
#### 4. 技术要求与限制
|
|
222
|
+
- **性能需求**:响应时间、加载速度、动画流畅度
|
|
223
|
+
- **可用性需求**:状态清晰性、错误提示友好性、操作便捷性
|
|
224
|
+
- **兼容性需求**:支持的系统版本、设备类型、浏览器要求
|
|
225
|
+
- **限制说明**:不支持的场景、已知的兼容性问题、特殊边界情况
|
|
226
|
+
|
|
227
|
+
### 内容要求
|
|
228
|
+
|
|
229
|
+
#### 必须包含的关键内容
|
|
230
|
+
|
|
231
|
+
**1. 功能范围**
|
|
232
|
+
- 业务场景、平台范围、排除范围
|
|
233
|
+
|
|
234
|
+
**2. 页面结构**
|
|
235
|
+
- 页面/模块布局、组件层级关系
|
|
236
|
+
|
|
237
|
+
**3. 数据展示**
|
|
238
|
+
- 数据来源(用"由系统返回"替代接口名)
|
|
239
|
+
- 数据展示规则
|
|
240
|
+
- 空数据/加载/错误状态的表现
|
|
241
|
+
|
|
242
|
+
**4. 交互逻辑**
|
|
243
|
+
- 操作入口、触发条件、即时反馈、结果处理
|
|
244
|
+
|
|
245
|
+
**5. 状态管理**
|
|
246
|
+
- 状态触发条件、转换逻辑、数据保持/重置
|
|
247
|
+
|
|
248
|
+
**6. 页面跳转**
|
|
249
|
+
- 跳转触发、目标页面、参数传递(只说明内容,不涉及字段)、返回逻辑
|
|
250
|
+
|
|
251
|
+
**7. 跨系统交互**
|
|
252
|
+
- 交互触发、返回处理、结果查询和展示
|
|
253
|
+
|
|
254
|
+
**8. 异常处理**
|
|
255
|
+
- 异常场景、提示方式、恢复机制
|
|
256
|
+
|
|
257
|
+
**9. 交互细节**
|
|
258
|
+
- 视觉反馈(选中/不可用等)
|
|
259
|
+
- 动画效果(展开/收起/弹出等)
|
|
260
|
+
- 确认弹窗
|
|
261
|
+
|
|
262
|
+
**10. 性能要求**
|
|
263
|
+
- 加载速度、响应时间、动画流畅度
|
|
264
|
+
|
|
265
|
+
#### 视角要求
|
|
266
|
+
|
|
267
|
+
**从用户视角描述**
|
|
268
|
+
- ✅ 描述"用户能看到什么"、"用户能做什么"、"操作后有什么反馈"
|
|
269
|
+
|
|
270
|
+
**避免技术细节**
|
|
271
|
+
- ❌ 不要描述"轮询 5 次"、"骨架屏 vs 局部加载"、"调用 XXX 接口"、"使用 XXX SDK"
|
|
272
|
+
- ✅ 用"查询超时"、"加载状态"、"由系统返回"替代
|
|
273
|
+
|
|
274
|
+
#### 格式化要求
|
|
275
|
+
- 用户故事:作为[角色],我希望[功能],以便[价值]
|
|
276
|
+
- 验收标准:WHEN [触发条件] THEN THE System SHALL [预期行为]
|
|
277
|
+
- 验收标准必须可测试:使用具体的时间、数量、状态,避免"快速响应"等模糊描述
|
|
278
|
+
|
|
279
|
+
### 格式要求
|
|
280
|
+
|
|
281
|
+
#### 用户故事格式
|
|
282
|
+
\`\`\`
|
|
283
|
+
**用户故事**:作为[角色],我希望[功能],以便[价值]。
|
|
284
|
+
\`\`\`
|
|
285
|
+
|
|
286
|
+
#### 验收标准格式
|
|
287
|
+
\`\`\`
|
|
288
|
+
#### 验收标准
|
|
289
|
+
|
|
290
|
+
1. WHEN [触发条件] THEN THE System SHALL [预期行为]
|
|
291
|
+
2. WHEN [触发条件] THEN THE System SHALL [预期行为]
|
|
292
|
+
3. WHEN [触发条件] THEN THE System SHALL [预期行为]
|
|
293
|
+
...
|
|
294
|
+
\`\`\`
|
|
295
|
+
|
|
296
|
+
#### 可测试性要求
|
|
297
|
+
- 每个验收标准必须可测试、可验证
|
|
298
|
+
- 避免模糊的描述(如"快速响应")
|
|
299
|
+
- 使用具体的时间、数量、状态描述
|
|
138
300
|
|
|
139
|
-
|
|
301
|
+
## 核心约束
|
|
140
302
|
|
|
141
|
-
|
|
303
|
+
### 1. 内容完整性
|
|
304
|
+
- 必须包含所有 4 个章节(介绍、功能需求、交互细节、技术要求与限制)
|
|
305
|
+
- 每个功能需求必须有用户故事和 3-6 条验收标准
|
|
306
|
+
- 必须覆盖 10 个前端开发重点
|
|
142
307
|
|
|
143
|
-
|
|
308
|
+
### 2. 视角正确性
|
|
309
|
+
- 从用户视角描述功能
|
|
310
|
+
- 不涉及技术实现细节(接口、SDK、轮询机制等)
|
|
311
|
+
- 用"由系统返回"、"加载状态"、"查询超时"替代技术术语
|
|
144
312
|
|
|
145
|
-
###
|
|
313
|
+
### 3. 内容独立性
|
|
314
|
+
- 不要生成接口文档(放在设计文档)
|
|
315
|
+
- 不要生成数据模型(放在设计文档)
|
|
316
|
+
- 不要生成技术架构(放在设计文档)
|
|
317
|
+
- 不要生成代码示例(放在开发阶段)
|
|
146
318
|
|
|
147
|
-
|
|
148
|
-
- System 代表整个系统(前后端整体)
|
|
149
|
-
- 覆盖所有功能点、用户场景、异常情况
|
|
150
|
-
- Acceptance Criteria 必须可测试、具体明确
|
|
151
|
-
- 每个需求 3-6 条验收标准
|
|
319
|
+
## 开始执行
|
|
152
320
|
|
|
153
|
-
|
|
321
|
+
请按照以上要求,从输入的 PRD ${designSource ? "和设计稿" : ""} 中提取信息,生成完整的需求文档到:\`${outputPath}\`
|
|
154
322
|
|
|
155
|
-
|
|
156
|
-
- 不要凭空猜测或假设需求
|
|
157
|
-
- 列出具体的疑问点,等待用户确认后再生成文档
|
|
323
|
+
生成过程中,如果遇到不明确的内容,必须向用户确认,不要假设答案。
|
|
158
324
|
`;
|
|
159
325
|
|
|
160
326
|
return prompt;
|
|
@@ -17,13 +17,20 @@ interface ProcessResult {
|
|
|
17
17
|
};
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
interface RequirementSource {
|
|
21
|
+
type: "file" | "url";
|
|
22
|
+
path?: string;
|
|
23
|
+
url?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
20
26
|
/**
|
|
21
27
|
* 步骤 2:处理需求文档输入
|
|
22
28
|
* 这是整体流程的第二步,专门处理需求文档
|
|
23
29
|
*/
|
|
24
30
|
export async function processRequirementDocument(
|
|
25
31
|
requirementSource: RequirementSource | undefined,
|
|
26
|
-
featureName: string
|
|
32
|
+
featureName: string,
|
|
33
|
+
outputFileName: string = "origin-requirement.md"
|
|
27
34
|
): Promise<ProcessResult> {
|
|
28
35
|
// 2.1 校验是否提供了需求文档
|
|
29
36
|
if (!requirementSource) {
|
|
@@ -55,7 +62,7 @@ export async function processRequirementDocument(
|
|
|
55
62
|
|
|
56
63
|
// 2.2.1 PDF 文件 - 返回读取指令
|
|
57
64
|
if (ext === "pdf") {
|
|
58
|
-
const outputMdPath = `.specs/requirements/${featureName}
|
|
65
|
+
const outputMdPath = `.specs/requirements/${featureName}/${outputFileName}`;
|
|
59
66
|
return {
|
|
60
67
|
success: false,
|
|
61
68
|
message: `📄 检测到 PDF 文件
|
|
@@ -72,7 +79,7 @@ export async function processRequirementDocument(
|
|
|
72
79
|
|
|
73
80
|
// 2.2.2 Markdown 文件 - 保存到固定位置
|
|
74
81
|
if (ext === "md" || ext === "markdown") {
|
|
75
|
-
const outputMdPath = `.specs/requirements/${featureName}
|
|
82
|
+
const outputMdPath = `.specs/requirements/${featureName}/${outputFileName}`;
|
|
76
83
|
|
|
77
84
|
// 读取 Markdown 内容
|
|
78
85
|
const content = await fs.readFile(filePath, "utf-8");
|
|
@@ -100,7 +107,7 @@ export async function processRequirementDocument(
|
|
|
100
107
|
throw new McpError(-32602, "网页 URL 不能为空");
|
|
101
108
|
}
|
|
102
109
|
|
|
103
|
-
const outputMdPath = `.specs/requirements/${featureName}
|
|
110
|
+
const outputMdPath = `.specs/requirements/${featureName}/${outputFileName}`;
|
|
104
111
|
return {
|
|
105
112
|
success: false,
|
|
106
113
|
message: `🌐 检测到网页 URL
|