bmall-mcp 1.6.0 → 1.8.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 +14 -0
- package/dist/tools/requirements/index.d.ts.map +1 -1
- package/dist/tools/requirements/index.js +46 -19
- package/dist/tools/requirements/index.js.map +1 -1
- package/dist/tools/requirements/requirement-processor.d.ts +18 -0
- package/dist/tools/requirements/requirement-processor.d.ts.map +1 -1
- package/dist/tools/requirements/requirement-processor.js +56 -0
- package/dist/tools/requirements/requirement-processor.js.map +1 -1
- package/docs/generate-requirements-usage.md +111 -22
- package/package.json +1 -1
- package/src/tools/requirements/index.ts +61 -24
- package/src/tools/requirements/requirement-processor.ts +68 -0
package/README.md
CHANGED
|
@@ -204,6 +204,20 @@ src/
|
|
|
204
204
|
|
|
205
205
|
## Changelog
|
|
206
206
|
|
|
207
|
+
### v1.8.0 (2026-03-16)
|
|
208
|
+
- ✅ 完善后端文档处理逻辑:添加智能缓存机制
|
|
209
|
+
- ✅ 新增后端文档缓存函数:saveBackendDocument、tryReadSavedBackend
|
|
210
|
+
- ✅ 优化后端文档处理流程:支持文件和网页两种形式的缓存
|
|
211
|
+
- ✅ 统一文档管理:所有输入材料(PRD、设计稿、后端文档)都支持智能缓存
|
|
212
|
+
- ✅ 更新使用文档:明确后端文档缓存机制和处理流程
|
|
213
|
+
|
|
214
|
+
### v1.7.0 (2026-03-16)
|
|
215
|
+
- ✅ 优化设计稿处理逻辑:统一保存设计稿内容到 design-doc.md
|
|
216
|
+
- ✅ 添加设计稿智能缓存:自动检测已保存的设计稿,避免重复读取
|
|
217
|
+
- ✅ 完善 Figma 设计稿处理流程:AI 先读取并保存,再重新调用工具使用缓存
|
|
218
|
+
- ✅ 更新使用文档:明确设计稿文档保存路径和缓存机制
|
|
219
|
+
- ✅ 统一文件管理:origin-requirement.md、design-doc.md、backend-doc.md、requirements.md
|
|
220
|
+
|
|
207
221
|
### v1.6.0 (2026-03-16)
|
|
208
222
|
- ✅ 优化 `generate_requirements` 工具 Prompt 模板
|
|
209
223
|
- ✅ 新增设计稿支持(Figma 链接和本地文件)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/requirements/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/requirements/index.ts"],"names":[],"mappings":"AAUA,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,CAkID"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { McpError } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
-
import { processRequirementDocument, tryReadSavedRequirement } from "./requirement-processor.js";
|
|
2
|
+
import { processRequirementDocument, tryReadSavedRequirement, tryReadSavedDesign, tryReadSavedBackend } from "./requirement-processor.js";
|
|
3
3
|
/**
|
|
4
4
|
* 验证必填参数
|
|
5
5
|
*/
|
|
@@ -45,28 +45,55 @@ export async function generateRequirements(params) {
|
|
|
45
45
|
// 3. 检查设计稿
|
|
46
46
|
let designSourceInfo = "";
|
|
47
47
|
if (params.designSource) {
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
// 3.1 优先尝试读取已保存的设计稿
|
|
49
|
+
const savedDesign = await tryReadSavedDesign(params.featureName);
|
|
50
|
+
if (!savedDesign) {
|
|
51
|
+
// 3.2 没有缓存,处理设计稿
|
|
52
|
+
if (params.designSource.type === "file") {
|
|
53
|
+
const designResult = await processRequirementDocument(params.designSource, params.featureName, "design-doc.md");
|
|
54
|
+
if (!designResult.success) {
|
|
55
|
+
return {
|
|
56
|
+
success: false,
|
|
57
|
+
message: designResult.message,
|
|
58
|
+
needsAction: designResult.needsAction,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
designSourceInfo = `**设计稿位置**:.specs/requirements/${params.featureName}/design-doc.md\n`;
|
|
62
|
+
}
|
|
63
|
+
else if (params.designSource.type === "figma") {
|
|
64
|
+
designSourceInfo = `**设计稿链接**:${params.designSource.url || "Figma 链接未提供"}(请使用 Figma MCP 读取并保存到 .specs/requirements/${params.featureName}/design-doc.md)\n`;
|
|
65
|
+
}
|
|
50
66
|
}
|
|
51
|
-
else
|
|
52
|
-
|
|
67
|
+
else {
|
|
68
|
+
// 3.3 使用已保存的设计稿
|
|
69
|
+
designSourceInfo = `**设计稿位置**:.specs/requirements/${params.featureName}/design-doc.md\n`;
|
|
53
70
|
}
|
|
54
71
|
}
|
|
55
72
|
// 4. 处理后端文档
|
|
56
73
|
let backendSourceInfo = "";
|
|
57
74
|
if (params.backendSource) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
75
|
+
// 4.1 优先尝试读取已保存的后端文档
|
|
76
|
+
const savedBackend = await tryReadSavedBackend(params.featureName);
|
|
77
|
+
if (!savedBackend) {
|
|
78
|
+
// 4.2 没有缓存,处理后端文档
|
|
79
|
+
const backendResult = await processRequirementDocument(params.backendSource, params.featureName, "backend-doc.md");
|
|
80
|
+
if (!backendResult.success) {
|
|
81
|
+
return {
|
|
82
|
+
success: false,
|
|
83
|
+
message: backendResult.message,
|
|
84
|
+
needsAction: backendResult.needsAction,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
// 4.2.1 文件类型已保存,返回信息
|
|
88
|
+
if (params.backendSource.type === "file") {
|
|
89
|
+
backendSourceInfo = `**后端文档位置**:.specs/requirements/${params.featureName}/backend-doc.md\n`;
|
|
90
|
+
}
|
|
91
|
+
else if (params.backendSource.type === "url") {
|
|
92
|
+
backendSourceInfo = `**后端文档网页**:${params.backendSource.url || "后端文档网页 URL 未提供"}(请使用 Chrome DevTools MCP 读取并保存到 .specs/requirements/${params.featureName}/backend-doc.md)\n`;
|
|
93
|
+
}
|
|
68
94
|
}
|
|
69
|
-
else
|
|
95
|
+
else {
|
|
96
|
+
// 4.3 使用已保存的后端文档
|
|
70
97
|
backendSourceInfo = `**后端文档位置**:.specs/requirements/${params.featureName}/backend-doc.md\n`;
|
|
71
98
|
}
|
|
72
99
|
}
|
|
@@ -88,7 +115,7 @@ export async function generateRequirements(params) {
|
|
|
88
115
|
message,
|
|
89
116
|
needsAction: {
|
|
90
117
|
type: "analyze_content",
|
|
91
|
-
instruction: `分析 ${originDocPath}${params.designSource ? "
|
|
118
|
+
instruction: `分析 ${originDocPath}${params.designSource ? "、design-doc.md" : ""}${params.backendSource ? "、backend-doc.md" : ""},生成 ${outputPath}`,
|
|
92
119
|
},
|
|
93
120
|
};
|
|
94
121
|
}
|
|
@@ -114,8 +141,8 @@ function buildAnalysisPrompt(originDocPath, outputPath, designSource, backendSou
|
|
|
114
141
|
## 输入材料
|
|
115
142
|
|
|
116
143
|
1. **产品 PRD 文档**:\`${originDocPath}\`(包含项目背景、功能列表、系统流程、详细说明等)
|
|
117
|
-
2. **设计稿**:${designSource ?
|
|
118
|
-
3. **后端文档**:${backendSource ?
|
|
144
|
+
2. **设计稿**:${designSource ? `已保存到 .specs/requirements/${featureName}/design-doc.md${designSource.type === "figma" ? "(使用 Figma MCP 读取)" : ""}` : "未提供(如有设计稿,请使用 Figma MCP 工具读取)"}
|
|
145
|
+
3. **后端文档**:${backendSource ? `已保存到 .specs/requirements/${featureName}/backend-doc.md(包含接口定义、数据结构、后端逻辑等,可作为生成验收标准的参考)` : "未提供(如有后端文档,可作为生成验收标准的参考)"}
|
|
119
146
|
|
|
120
147
|
## 输出要求
|
|
121
148
|
|
|
@@ -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,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/requirements/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -27,5 +27,23 @@ export declare function processRequirementDocument(requirementSource: Requiremen
|
|
|
27
27
|
* 如果用户之前已经按照指令保存了文件,优先使用已保存的内容
|
|
28
28
|
*/
|
|
29
29
|
export declare function tryReadSavedRequirement(featureName: string): Promise<string | null>;
|
|
30
|
+
/**
|
|
31
|
+
* 保存设计稿内容到文件
|
|
32
|
+
* 用于保存从 Figma MCP 读取的设计稿内容
|
|
33
|
+
*/
|
|
34
|
+
export declare function saveDesignDocument(featureName: string, designContent: string): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* 尝试读取已保存的设计稿文档
|
|
37
|
+
*/
|
|
38
|
+
export declare function tryReadSavedDesign(featureName: string): Promise<string | null>;
|
|
39
|
+
/**
|
|
40
|
+
* 保存后端文档内容到文件
|
|
41
|
+
* 用于保存从 PDF/网页读取的后端文档内容
|
|
42
|
+
*/
|
|
43
|
+
export declare function saveBackendDocument(featureName: string, backendContent: string): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* 尝试读取已保存的后端文档
|
|
46
|
+
*/
|
|
47
|
+
export declare function tryReadSavedBackend(featureName: string): Promise<string | null>;
|
|
30
48
|
export {};
|
|
31
49
|
//# sourceMappingURL=requirement-processor.d.ts.map
|
|
@@ -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,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"}
|
|
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;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CAMf;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAYxB;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,IAAI,CAAC,CAMf;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAYxB"}
|
|
@@ -104,4 +104,60 @@ export async function tryReadSavedRequirement(featureName) {
|
|
|
104
104
|
}
|
|
105
105
|
return null;
|
|
106
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* 保存设计稿内容到文件
|
|
109
|
+
* 用于保存从 Figma MCP 读取的设计稿内容
|
|
110
|
+
*/
|
|
111
|
+
export async function saveDesignDocument(featureName, designContent) {
|
|
112
|
+
const designDocPath = `.specs/requirements/${featureName}/design-doc.md`;
|
|
113
|
+
const outputDir = designDocPath.substring(0, designDocPath.lastIndexOf("/"));
|
|
114
|
+
await fs.mkdir(outputDir, { recursive: true });
|
|
115
|
+
await fs.writeFile(designDocPath, designContent, "utf-8");
|
|
116
|
+
console.log(`✅ 设计稿已保存到: ${designDocPath}`);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* 尝试读取已保存的设计稿文档
|
|
120
|
+
*/
|
|
121
|
+
export async function tryReadSavedDesign(featureName) {
|
|
122
|
+
const savedDesignPath = `.specs/requirements/${featureName}/design-doc.md`;
|
|
123
|
+
try {
|
|
124
|
+
const savedContent = await fs.readFile(savedDesignPath, "utf-8");
|
|
125
|
+
if (savedContent) {
|
|
126
|
+
console.log(`✅ 使用已保存的设计稿: ${savedDesignPath}`);
|
|
127
|
+
return savedContent;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
// 文件不存在
|
|
132
|
+
}
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* 保存后端文档内容到文件
|
|
137
|
+
* 用于保存从 PDF/网页读取的后端文档内容
|
|
138
|
+
*/
|
|
139
|
+
export async function saveBackendDocument(featureName, backendContent) {
|
|
140
|
+
const backendDocPath = `.specs/requirements/${featureName}/backend-doc.md`;
|
|
141
|
+
const outputDir = backendDocPath.substring(0, backendDocPath.lastIndexOf("/"));
|
|
142
|
+
await fs.mkdir(outputDir, { recursive: true });
|
|
143
|
+
await fs.writeFile(backendDocPath, backendContent, "utf-8");
|
|
144
|
+
console.log(`✅ 后端文档已保存到: ${backendDocPath}`);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* 尝试读取已保存的后端文档
|
|
148
|
+
*/
|
|
149
|
+
export async function tryReadSavedBackend(featureName) {
|
|
150
|
+
const savedBackendPath = `.specs/requirements/${featureName}/backend-doc.md`;
|
|
151
|
+
try {
|
|
152
|
+
const savedContent = await fs.readFile(savedBackendPath, "utf-8");
|
|
153
|
+
if (savedContent) {
|
|
154
|
+
console.log(`✅ 使用已保存的后端文档: ${savedBackendPath}`);
|
|
155
|
+
return savedContent;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
// 文件不存在
|
|
160
|
+
}
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
107
163
|
//# sourceMappingURL=requirement-processor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requirement-processor.js","sourceRoot":"","sources":["../../../src/tools/requirements/requirement-processor.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"requirement-processor.js","sourceRoot":"","sources":["../../../src/tools/requirements/requirement-processor.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,12 +16,14 @@
|
|
|
16
16
|
|
|
17
17
|
工具负责:
|
|
18
18
|
1. 统一保存原始文档到固定位置(origin-requirement.md)
|
|
19
|
-
2.
|
|
19
|
+
2. 如有设计稿,保存设计稿内容到固定位置(design-doc.md)
|
|
20
|
+
3. 如有后端文档,统一保存后端文档到固定位置(backend-doc.md)
|
|
21
|
+
4. 提供专业的前端需求分析提示词(指导 AI 如何生成 requirements.md)
|
|
20
22
|
|
|
21
23
|
AI 负责:
|
|
22
24
|
1. 读取原始文档
|
|
23
|
-
2.
|
|
24
|
-
3.
|
|
25
|
+
2. 如有设计稿,读取保存的设计稿内容
|
|
26
|
+
3. 如有后端文档,读取保存的后端文档作为生成验收标准的参考
|
|
25
27
|
4. 按照前端需求分析标准,生成高质量的需求文档
|
|
26
28
|
|
|
27
29
|
## 输出文档结构
|
|
@@ -61,7 +63,7 @@ AI 负责:
|
|
|
61
63
|
📝 需求文档已准备完毕
|
|
62
64
|
|
|
63
65
|
**原始文档位置**:.specs/requirements/voice-recording/origin-requirement.md
|
|
64
|
-
**设计稿链接**:https://figma.com/design/xxx/xxx?node-id=1-2
|
|
66
|
+
**设计稿链接**:https://figma.com/design/xxx/xxx?node-id=1-2(请使用 Figma MCP 读取并保存到 .specs/requirements/voice-recording/design-doc.md)
|
|
65
67
|
**后端文档位置**:.specs/requirements/voice-recording/backend-doc.md
|
|
66
68
|
**目标输出位置**:.specs/requirements/voice-recording/requirements.md
|
|
67
69
|
|
|
@@ -70,11 +72,13 @@ AI 负责:
|
|
|
70
72
|
```
|
|
71
73
|
|
|
72
74
|
**AI 执行**:
|
|
73
|
-
1.
|
|
74
|
-
2.
|
|
75
|
-
3. 读取 `.specs/requirements/voice-recording/
|
|
76
|
-
4.
|
|
77
|
-
5.
|
|
75
|
+
1. 使用 Figma MCP 工具读取设计稿,保存到 `.specs/requirements/voice-recording/design-doc.md`
|
|
76
|
+
2. 重新调用工具(工具会使用已保存的设计稿)
|
|
77
|
+
3. 读取 `.specs/requirements/voice-recording/origin-requirement.md`
|
|
78
|
+
4. 读取 `.specs/requirements/voice-recording/design-doc.md`
|
|
79
|
+
5. 读取 `.specs/requirements/voice-recording/backend-doc.md` 作为生成验收标准的参考
|
|
80
|
+
6. 按照 4 章节结构分析内容
|
|
81
|
+
7. 生成 `.specs/requirements/voice-recording/requirements.md`
|
|
78
82
|
|
|
79
83
|
---
|
|
80
84
|
|
|
@@ -100,10 +104,12 @@ AI 负责:
|
|
|
100
104
|
**返回**:同流程 1(无后端文档信息)
|
|
101
105
|
|
|
102
106
|
**AI 执行**:
|
|
103
|
-
1.
|
|
104
|
-
2.
|
|
105
|
-
3.
|
|
106
|
-
4.
|
|
107
|
+
1. 使用 Figma MCP 工具读取设计稿,保存到 `.specs/requirements/voice-recording/design-doc.md`
|
|
108
|
+
2. 重新调用工具(工具会使用已保存的设计稿)
|
|
109
|
+
3. 读取 `.specs/requirements/voice-recording/origin-requirement.md`
|
|
110
|
+
4. 读取 `.specs/requirements/voice-recording/design-doc.md`
|
|
111
|
+
5. 按照 4 章节结构分析内容
|
|
112
|
+
6. 生成 `.specs/requirements/voice-recording/requirements.md`
|
|
107
113
|
|
|
108
114
|
---
|
|
109
115
|
|
|
@@ -146,7 +152,7 @@ AI 负责:
|
|
|
146
152
|
}
|
|
147
153
|
```
|
|
148
154
|
|
|
149
|
-
**返回**:同流程 1
|
|
155
|
+
**返回**:同流程 1(无设计稿信息,后端文档已缓存)
|
|
150
156
|
|
|
151
157
|
**AI 执行**:
|
|
152
158
|
1. 读取 `.specs/requirements/voice-recording/origin-requirement.md`
|
|
@@ -214,7 +220,56 @@ AI 负责:
|
|
|
214
220
|
|
|
215
221
|
---
|
|
216
222
|
|
|
217
|
-
### 流程
|
|
223
|
+
### 流程 5:PDF 文件 + Figma 设计稿 + 后端文档(无设计稿缓存)
|
|
224
|
+
|
|
225
|
+
**第 1 次调用**:
|
|
226
|
+
```json
|
|
227
|
+
{
|
|
228
|
+
"requirementSource": {
|
|
229
|
+
"type": "file",
|
|
230
|
+
"path": "prd.pdf"
|
|
231
|
+
},
|
|
232
|
+
"featureName": "voice-recording",
|
|
233
|
+
"designSource": {
|
|
234
|
+
"type": "figma",
|
|
235
|
+
"url": "https://figma.com/design/xxx/xxx?node-id=1-2"
|
|
236
|
+
},
|
|
237
|
+
"backendSource": {
|
|
238
|
+
"type": "file",
|
|
239
|
+
"path": "backend-api.md"
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
**AI 执行**:
|
|
245
|
+
1. 使用 `mcp_pdf_reader_read_pdf_text` 读取 PRD PDF,保存到 `.specs/requirements/voice-recording/origin-requirement.md`
|
|
246
|
+
2. 使用 Figma MCP 工具读取设计稿,保存到 `.specs/requirements/voice-recording/design-doc.md`
|
|
247
|
+
3. 重新调用工具
|
|
248
|
+
|
|
249
|
+
**第 2 次调用**:
|
|
250
|
+
```json
|
|
251
|
+
{
|
|
252
|
+
"requirementSource": {
|
|
253
|
+
"type": "file",
|
|
254
|
+
"path": "prd.pdf"
|
|
255
|
+
},
|
|
256
|
+
"featureName": "voice-recording",
|
|
257
|
+
"designSource": {
|
|
258
|
+
"type": "figma",
|
|
259
|
+
"url": "https://figma.com/design/xxx/xxx?node-id=1-2"
|
|
260
|
+
},
|
|
261
|
+
"backendSource": {
|
|
262
|
+
"type": "file",
|
|
263
|
+
"path": "backend-api.md"
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
**返回**:分析提示词(同流程 1,包含设计稿位置)
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
### 流程 6:网页 URL + Figma 设计稿 + 后端文档(无设计稿缓存)
|
|
218
273
|
|
|
219
274
|
**第 1 次调用**:
|
|
220
275
|
```json
|
|
@@ -239,19 +294,53 @@ AI 负责:
|
|
|
239
294
|
```
|
|
240
295
|
🌐 检测到网页 URL
|
|
241
296
|
|
|
242
|
-
请使用 Chrome DevTools MCP
|
|
297
|
+
请使用 Chrome DevTools MCP 读取 PRD 网页内容
|
|
243
298
|
保存到:.specs/requirements/voice-recording/origin-requirement.md
|
|
244
299
|
完成后重新调用本工具
|
|
245
300
|
```
|
|
246
301
|
|
|
247
302
|
**AI 执行**:
|
|
248
|
-
1. 使用 Chrome DevTools MCP 读取 PRD
|
|
249
|
-
2.
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
303
|
+
1. 使用 Chrome DevTools MCP 读取 PRD 网页,保存到 `.specs/requirements/voice-recording/origin-requirement.md`
|
|
304
|
+
2. 重新调用工具
|
|
305
|
+
|
|
306
|
+
**第 2 次调用**:
|
|
307
|
+
```json
|
|
308
|
+
{
|
|
309
|
+
"requirementSource": {
|
|
310
|
+
"type": "url",
|
|
311
|
+
"url": "https://wiki.jd.com/pages/viewpage.action?pageId=123456"
|
|
312
|
+
},
|
|
313
|
+
"featureName": "voice-recording",
|
|
314
|
+
"designSource": {
|
|
315
|
+
"type": "figma",
|
|
316
|
+
"url": "https://figma.com/design/xxx/xxx?node-id=1-2"
|
|
317
|
+
},
|
|
318
|
+
"backendSource": {
|
|
319
|
+
"type": "url",
|
|
320
|
+
"url": "https://wiki.jd.com/pages/viewpage.action?pageId=789012"
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
**返回**:
|
|
326
|
+
```
|
|
327
|
+
📝 需求文档已准备完毕
|
|
328
|
+
|
|
329
|
+
**原始文档位置**:.specs/requirements/voice-recording/origin-requirement.md
|
|
330
|
+
**设计稿链接**:https://figma.com/design/xxx/xxx?node-id=1-2(请使用 Figma MCP 读取并保存到 .specs/requirements/voice-recording/design-doc.md)
|
|
331
|
+
**后端文档位置**:.specs/requirements/voice-recording/backend-doc.md
|
|
332
|
+
**目标输出位置**:.specs/requirements/voice-recording/requirements.md
|
|
333
|
+
|
|
334
|
+
# 产品 PRD 转需求文档
|
|
335
|
+
...(前端需求分析提示词)
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
**AI 执行**:
|
|
339
|
+
1. 使用 Figma MCP 工具读取设计稿,保存到 `.specs/requirements/voice-recording/design-doc.md`
|
|
340
|
+
2. 使用 Chrome DevTools MCP 读取后端文档网页,保存到 `.specs/requirements/voice-recording/backend-doc.md`
|
|
341
|
+
3. 重新调用工具(工具会使用已保存的设计稿和后端文档)
|
|
253
342
|
|
|
254
|
-
**第
|
|
343
|
+
**第 3 次调用**:同流程 1(所有文档已缓存)
|
|
255
344
|
|
|
256
345
|
---
|
|
257
346
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { McpError } from "@modelcontextprotocol/sdk/types.js";
|
|
2
2
|
import {
|
|
3
3
|
processRequirementDocument,
|
|
4
|
-
tryReadSavedRequirement
|
|
4
|
+
tryReadSavedRequirement,
|
|
5
|
+
saveDesignDocument,
|
|
6
|
+
tryReadSavedDesign,
|
|
7
|
+
saveBackendDocument,
|
|
8
|
+
tryReadSavedBackend
|
|
5
9
|
} from "./requirement-processor.js";
|
|
6
10
|
|
|
7
11
|
interface RequirementSource {
|
|
@@ -101,33 +105,66 @@ export async function generateRequirements(
|
|
|
101
105
|
// 3. 检查设计稿
|
|
102
106
|
let designSourceInfo = "";
|
|
103
107
|
if (params.designSource) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
+
// 3.1 优先尝试读取已保存的设计稿
|
|
109
|
+
const savedDesign = await tryReadSavedDesign(params.featureName);
|
|
110
|
+
|
|
111
|
+
if (!savedDesign) {
|
|
112
|
+
// 3.2 没有缓存,处理设计稿
|
|
113
|
+
if (params.designSource.type === "file") {
|
|
114
|
+
const designResult = await processRequirementDocument(
|
|
115
|
+
params.designSource as any,
|
|
116
|
+
params.featureName,
|
|
117
|
+
"design-doc.md"
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
if (!designResult.success) {
|
|
121
|
+
return {
|
|
122
|
+
success: false,
|
|
123
|
+
message: designResult.message!,
|
|
124
|
+
needsAction: designResult.needsAction,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
designSourceInfo = `**设计稿位置**:.specs/requirements/${params.featureName}/design-doc.md\n`;
|
|
129
|
+
} else if (params.designSource.type === "figma") {
|
|
130
|
+
designSourceInfo = `**设计稿链接**:${params.designSource.url || "Figma 链接未提供"}(请使用 Figma MCP 读取并保存到 .specs/requirements/${params.featureName}/design-doc.md)\n`;
|
|
131
|
+
}
|
|
132
|
+
} else {
|
|
133
|
+
// 3.3 使用已保存的设计稿
|
|
134
|
+
designSourceInfo = `**设计稿位置**:.specs/requirements/${params.featureName}/design-doc.md\n`;
|
|
108
135
|
}
|
|
109
136
|
}
|
|
110
137
|
|
|
111
138
|
// 4. 处理后端文档
|
|
112
139
|
let backendSourceInfo = "";
|
|
113
140
|
if (params.backendSource) {
|
|
114
|
-
|
|
115
|
-
|
|
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
|
-
}
|
|
141
|
+
// 4.1 优先尝试读取已保存的后端文档
|
|
142
|
+
const savedBackend = await tryReadSavedBackend(params.featureName);
|
|
127
143
|
|
|
128
|
-
if (
|
|
129
|
-
|
|
130
|
-
|
|
144
|
+
if (!savedBackend) {
|
|
145
|
+
// 4.2 没有缓存,处理后端文档
|
|
146
|
+
const backendResult = await processRequirementDocument(
|
|
147
|
+
params.backendSource,
|
|
148
|
+
params.featureName,
|
|
149
|
+
"backend-doc.md"
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
if (!backendResult.success) {
|
|
153
|
+
return {
|
|
154
|
+
success: false,
|
|
155
|
+
message: backendResult.message!,
|
|
156
|
+
needsAction: backendResult.needsAction,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// 4.2.1 文件类型已保存,返回信息
|
|
161
|
+
if (params.backendSource.type === "file") {
|
|
162
|
+
backendSourceInfo = `**后端文档位置**:.specs/requirements/${params.featureName}/backend-doc.md\n`;
|
|
163
|
+
} else if (params.backendSource.type === "url") {
|
|
164
|
+
backendSourceInfo = `**后端文档网页**:${params.backendSource.url || "后端文档网页 URL 未提供"}(请使用 Chrome DevTools MCP 读取并保存到 .specs/requirements/${params.featureName}/backend-doc.md)\n`;
|
|
165
|
+
}
|
|
166
|
+
} else {
|
|
167
|
+
// 4.3 使用已保存的后端文档
|
|
131
168
|
backendSourceInfo = `**后端文档位置**:.specs/requirements/${params.featureName}/backend-doc.md\n`;
|
|
132
169
|
}
|
|
133
170
|
}
|
|
@@ -152,7 +189,7 @@ export async function generateRequirements(
|
|
|
152
189
|
message,
|
|
153
190
|
needsAction: {
|
|
154
191
|
type: "analyze_content",
|
|
155
|
-
instruction: `分析 ${originDocPath}${params.designSource ? "
|
|
192
|
+
instruction: `分析 ${originDocPath}${params.designSource ? "、design-doc.md" : ""}${params.backendSource ? "、backend-doc.md" : ""},生成 ${outputPath}`,
|
|
156
193
|
},
|
|
157
194
|
};
|
|
158
195
|
} catch (error) {
|
|
@@ -187,8 +224,8 @@ function buildAnalysisPrompt(
|
|
|
187
224
|
## 输入材料
|
|
188
225
|
|
|
189
226
|
1. **产品 PRD 文档**:\`${originDocPath}\`(包含项目背景、功能列表、系统流程、详细说明等)
|
|
190
|
-
2. **设计稿**:${designSource ?
|
|
191
|
-
3. **后端文档**:${backendSource ?
|
|
227
|
+
2. **设计稿**:${designSource ? `已保存到 .specs/requirements/${featureName}/design-doc.md${designSource.type === "figma" ? "(使用 Figma MCP 读取)" : ""}` : "未提供(如有设计稿,请使用 Figma MCP 工具读取)" }
|
|
228
|
+
3. **后端文档**:${backendSource ? `已保存到 .specs/requirements/${featureName}/backend-doc.md(包含接口定义、数据结构、后端逻辑等,可作为生成验收标准的参考)` : "未提供(如有后端文档,可作为生成验收标准的参考)" }
|
|
192
229
|
|
|
193
230
|
## 输出要求
|
|
194
231
|
|
|
@@ -144,3 +144,71 @@ export async function tryReadSavedRequirement(
|
|
|
144
144
|
}
|
|
145
145
|
return null;
|
|
146
146
|
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* 保存设计稿内容到文件
|
|
150
|
+
* 用于保存从 Figma MCP 读取的设计稿内容
|
|
151
|
+
*/
|
|
152
|
+
export async function saveDesignDocument(
|
|
153
|
+
featureName: string,
|
|
154
|
+
designContent: string
|
|
155
|
+
): Promise<void> {
|
|
156
|
+
const designDocPath = `.specs/requirements/${featureName}/design-doc.md`;
|
|
157
|
+
const outputDir = designDocPath.substring(0, designDocPath.lastIndexOf("/"));
|
|
158
|
+
await fs.mkdir(outputDir, { recursive: true });
|
|
159
|
+
await fs.writeFile(designDocPath, designContent, "utf-8");
|
|
160
|
+
console.log(`✅ 设计稿已保存到: ${designDocPath}`);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* 尝试读取已保存的设计稿文档
|
|
165
|
+
*/
|
|
166
|
+
export async function tryReadSavedDesign(
|
|
167
|
+
featureName: string
|
|
168
|
+
): Promise<string | null> {
|
|
169
|
+
const savedDesignPath = `.specs/requirements/${featureName}/design-doc.md`;
|
|
170
|
+
try {
|
|
171
|
+
const savedContent = await fs.readFile(savedDesignPath, "utf-8");
|
|
172
|
+
if (savedContent) {
|
|
173
|
+
console.log(`✅ 使用已保存的设计稿: ${savedDesignPath}`);
|
|
174
|
+
return savedContent;
|
|
175
|
+
}
|
|
176
|
+
} catch (error) {
|
|
177
|
+
// 文件不存在
|
|
178
|
+
}
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* 保存后端文档内容到文件
|
|
184
|
+
* 用于保存从 PDF/网页读取的后端文档内容
|
|
185
|
+
*/
|
|
186
|
+
export async function saveBackendDocument(
|
|
187
|
+
featureName: string,
|
|
188
|
+
backendContent: string
|
|
189
|
+
): Promise<void> {
|
|
190
|
+
const backendDocPath = `.specs/requirements/${featureName}/backend-doc.md`;
|
|
191
|
+
const outputDir = backendDocPath.substring(0, backendDocPath.lastIndexOf("/"));
|
|
192
|
+
await fs.mkdir(outputDir, { recursive: true });
|
|
193
|
+
await fs.writeFile(backendDocPath, backendContent, "utf-8");
|
|
194
|
+
console.log(`✅ 后端文档已保存到: ${backendDocPath}`);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* 尝试读取已保存的后端文档
|
|
199
|
+
*/
|
|
200
|
+
export async function tryReadSavedBackend(
|
|
201
|
+
featureName: string
|
|
202
|
+
): Promise<string | null> {
|
|
203
|
+
const savedBackendPath = `.specs/requirements/${featureName}/backend-doc.md`;
|
|
204
|
+
try {
|
|
205
|
+
const savedContent = await fs.readFile(savedBackendPath, "utf-8");
|
|
206
|
+
if (savedContent) {
|
|
207
|
+
console.log(`✅ 使用已保存的后端文档: ${savedBackendPath}`);
|
|
208
|
+
return savedContent;
|
|
209
|
+
}
|
|
210
|
+
} catch (error) {
|
|
211
|
+
// 文件不存在
|
|
212
|
+
}
|
|
213
|
+
return null;
|
|
214
|
+
}
|