bmall-mcp 1.7.0 → 1.8.1

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 CHANGED
@@ -204,6 +204,21 @@ src/
204
204
 
205
205
  ## Changelog
206
206
 
207
+ ### v1.8.1 (2026-03-16)
208
+ - ✅ 新增 generate_requirements 工具详细调试日志
209
+ - ✅ 添加环境信息输出(工作目录、平台、主目录)
210
+ - ✅ 添加文件路径解析日志(绝对路径/相对路径)
211
+ - ✅ 添加文件操作日志(读取、目录创建、写入)
212
+ - ✅ 添加完整错误堆栈信息
213
+ - ✅ 优化错误诊断能力
214
+
215
+ ### v1.8.0 (2026-03-16)
216
+ - ✅ 完善后端文档处理逻辑:添加智能缓存机制
217
+ - ✅ 新增后端文档缓存函数:saveBackendDocument、tryReadSavedBackend
218
+ - ✅ 优化后端文档处理流程:支持文件和网页两种形式的缓存
219
+ - ✅ 统一文档管理:所有输入材料(PRD、设计稿、后端文档)都支持智能缓存
220
+ - ✅ 更新使用文档:明确后端文档缓存机制和处理流程
221
+
207
222
  ### v1.7.0 (2026-03-16)
208
223
  - ✅ 优化设计稿处理逻辑:统一保存设计稿内容到 design-doc.md
209
224
  - ✅ 添加设计稿智能缓存:自动检测已保存的设计稿,避免重复读取
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/requirements/index.ts"],"names":[],"mappings":"AAQA,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,CAwHD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/requirements/index.ts"],"names":[],"mappings":"AAsBA,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,CAuJD"}
@@ -1,5 +1,14 @@
1
1
  import { McpError } from "@modelcontextprotocol/sdk/types.js";
2
- import { processRequirementDocument, tryReadSavedRequirement, tryReadSavedDesign } from "./requirement-processor.js";
2
+ import * as os from "os";
3
+ import { processRequirementDocument, tryReadSavedRequirement, tryReadSavedDesign, tryReadSavedBackend } from "./requirement-processor.js";
4
+ /**
5
+ * 调试日志输出
6
+ */
7
+ function debugLog(message, data) {
8
+ const timestamp = new Date().toISOString();
9
+ const logMessage = `[DEBUG ${timestamp}] ${message}${data ? '\n' + JSON.stringify(data, null, 2) : ''}`;
10
+ console.error(logMessage);
11
+ }
3
12
  /**
4
13
  * 验证必填参数
5
14
  */
@@ -20,6 +29,12 @@ function validateRequiredParams(params) {
20
29
  return { valid: true };
21
30
  }
22
31
  export async function generateRequirements(params) {
32
+ debugLog(`generateRequirements 开始`, {
33
+ params,
34
+ cwd: process.cwd(),
35
+ platform: os.platform(),
36
+ homedir: os.homedir()
37
+ });
23
38
  try {
24
39
  // 1. 验证必填参数
25
40
  const validation = validateRequiredParams(params);
@@ -28,12 +43,15 @@ export async function generateRequirements(params) {
28
43
  }
29
44
  // 2. 处理需求文档输入
30
45
  // 2.1 优先尝试读取已保存的 origin-requirement.md(智能缓存)
46
+ debugLog(`尝试读取已保存的需求文档`, { featureName: params.featureName });
31
47
  const savedContent = await tryReadSavedRequirement(params.featureName);
32
48
  if (!savedContent) {
49
+ debugLog(`未找到缓存,处理需求文档输入`);
33
50
  // 2.2 没有缓存,处理需求文档输入
34
51
  const requirementResult = await processRequirementDocument(params.requirementSource, params.featureName);
35
52
  // 2.2.1 如果需要执行操作(读取 PDF/网页),直接返回
36
53
  if (!requirementResult.success) {
54
+ debugLog(`需求文档处理失败`, { requirementResult });
37
55
  return {
38
56
  success: false,
39
57
  message: requirementResult.message,
@@ -42,6 +60,9 @@ export async function generateRequirements(params) {
42
60
  }
43
61
  // 2.2.2 需求文档已读取并保存(Markdown 文件)
44
62
  }
63
+ else {
64
+ debugLog(`找到缓存文档`, { contentLength: savedContent.length });
65
+ }
45
66
  // 3. 检查设计稿
46
67
  let designSourceInfo = "";
47
68
  if (params.designSource) {
@@ -72,24 +93,35 @@ export async function generateRequirements(params) {
72
93
  // 4. 处理后端文档
73
94
  let backendSourceInfo = "";
74
95
  if (params.backendSource) {
75
- const backendResult = await processRequirementDocument(params.backendSource, params.featureName, "backend-doc.md");
76
- if (!backendResult.success) {
77
- return {
78
- success: false,
79
- message: backendResult.message,
80
- needsAction: backendResult.needsAction,
81
- };
82
- }
83
- if (params.backendSource.type === "file") {
84
- backendSourceInfo = `**后端文档位置**:.specs/requirements/${params.featureName}/backend-doc.md\n`;
96
+ // 4.1 优先尝试读取已保存的后端文档
97
+ const savedBackend = await tryReadSavedBackend(params.featureName);
98
+ if (!savedBackend) {
99
+ // 4.2 没有缓存,处理后端文档
100
+ const backendResult = await processRequirementDocument(params.backendSource, params.featureName, "backend-doc.md");
101
+ if (!backendResult.success) {
102
+ return {
103
+ success: false,
104
+ message: backendResult.message,
105
+ needsAction: backendResult.needsAction,
106
+ };
107
+ }
108
+ // 4.2.1 文件类型已保存,返回信息
109
+ if (params.backendSource.type === "file") {
110
+ backendSourceInfo = `**后端文档位置**:.specs/requirements/${params.featureName}/backend-doc.md\n`;
111
+ }
112
+ else if (params.backendSource.type === "url") {
113
+ backendSourceInfo = `**后端文档网页**:${params.backendSource.url || "后端文档网页 URL 未提供"}(请使用 Chrome DevTools MCP 读取并保存到 .specs/requirements/${params.featureName}/backend-doc.md)\n`;
114
+ }
85
115
  }
86
- else if (params.backendSource.type === "url") {
116
+ else {
117
+ // 4.3 使用已保存的后端文档
87
118
  backendSourceInfo = `**后端文档位置**:.specs/requirements/${params.featureName}/backend-doc.md\n`;
88
119
  }
89
120
  }
90
121
  // 5. 生成分析提示词
91
122
  const outputPath = `.specs/requirements/${params.featureName}/requirements.md`;
92
123
  const originDocPath = `.specs/requirements/${params.featureName}/origin-requirement.md`;
124
+ debugLog(`生成输出路径`, { outputPath, originDocPath });
93
125
  let message = "📝 需求文档已准备完毕\n\n";
94
126
  message += `**原始文档位置**:${originDocPath}\n`;
95
127
  if (designSourceInfo) {
@@ -100,6 +132,7 @@ export async function generateRequirements(params) {
100
132
  }
101
133
  message += `**目标输出位置**:${outputPath}\n\n`;
102
134
  message += buildAnalysisPrompt(originDocPath, outputPath, params.designSource, params.backendSource);
135
+ debugLog(`返回分析提示词`);
103
136
  return {
104
137
  success: false,
105
138
  message,
@@ -110,6 +143,13 @@ export async function generateRequirements(params) {
110
143
  };
111
144
  }
112
145
  catch (error) {
146
+ debugLog(`发生错误`, {
147
+ error: error instanceof Error ? {
148
+ message: error.message,
149
+ stack: error.stack,
150
+ name: error.name
151
+ } : String(error)
152
+ });
113
153
  if (error instanceof McpError) {
114
154
  throw error;
115
155
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/requirements/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/requirements/index.ts"],"names":[],"mappings":"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"}
@@ -36,5 +36,14 @@ export declare function saveDesignDocument(featureName: string, designContent: s
36
36
  * 尝试读取已保存的设计稿文档
37
37
  */
38
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>;
39
48
  export {};
40
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;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"}
1
+ {"version":3,"file":"requirement-processor.d.ts","sourceRoot":"","sources":["../../../src/tools/requirements/requirement-processor.ts"],"names":[],"mappings":"AAcA,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,CAkHxB;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,CAUf;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,CAUf;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAYxB"}
@@ -1,10 +1,28 @@
1
1
  import { McpError } from "@modelcontextprotocol/sdk/types.js";
2
2
  import * as fs from "fs/promises";
3
+ import * as path from "path";
4
+ import * as os from "os";
5
+ /**
6
+ * 调试日志输出
7
+ */
8
+ function debugLog(message, data) {
9
+ const timestamp = new Date().toISOString();
10
+ const logMessage = `[DEBUG ${timestamp}] ${message}${data ? '\n' + JSON.stringify(data, null, 2) : ''}`;
11
+ console.error(logMessage);
12
+ }
3
13
  /**
4
14
  * 步骤 2:处理需求文档输入
5
15
  * 这是整体流程的第二步,专门处理需求文档
6
16
  */
7
17
  export async function processRequirementDocument(requirementSource, featureName, outputFileName = "origin-requirement.md") {
18
+ debugLog(`processRequirementDocument 开始`, {
19
+ requirementSource,
20
+ featureName,
21
+ outputFileName,
22
+ cwd: process.cwd(),
23
+ platform: os.platform(),
24
+ homedir: os.homedir()
25
+ });
8
26
  // 2.1 校验是否提供了需求文档
9
27
  if (!requirementSource) {
10
28
  return {
@@ -26,10 +44,12 @@ export async function processRequirementDocument(requirementSource, featureName,
26
44
  // 2.2 处理文件类型
27
45
  if (requirementSource.type === "file") {
28
46
  const filePath = requirementSource.path;
47
+ debugLog(`处理文件类型`, { filePath });
29
48
  if (!filePath) {
30
49
  throw new McpError(-32602, "文件路径不能为空");
31
50
  }
32
51
  const ext = filePath.split(".").pop()?.toLowerCase();
52
+ debugLog(`文件扩展名`, { ext });
33
53
  // 2.2.1 PDF 文件 - 返回读取指令
34
54
  if (ext === "pdf") {
35
55
  const outputMdPath = `.specs/requirements/${featureName}/${outputFileName}`;
@@ -49,12 +69,23 @@ export async function processRequirementDocument(requirementSource, featureName,
49
69
  // 2.2.2 Markdown 文件 - 保存到固定位置
50
70
  if (ext === "md" || ext === "markdown") {
51
71
  const outputMdPath = `.specs/requirements/${featureName}/${outputFileName}`;
72
+ debugLog(`准备保存 Markdown 文件`, {
73
+ inputPath: filePath,
74
+ outputPath: outputMdPath,
75
+ isAbsolute: path.isAbsolute(filePath),
76
+ resolvedPath: path.resolve(filePath)
77
+ });
52
78
  // 读取 Markdown 内容
53
79
  const content = await fs.readFile(filePath, "utf-8");
80
+ debugLog(`成功读取文件内容`, { contentLength: content.length });
54
81
  // 保存到固定位置
55
82
  const outputDir = outputMdPath.substring(0, outputMdPath.lastIndexOf("/"));
83
+ debugLog(`准备创建目录`, { outputDir });
56
84
  await fs.mkdir(outputDir, { recursive: true });
85
+ debugLog(`目录创建成功`, { outputDir });
86
+ debugLog(`准备写入文件`, { outputPath: outputMdPath });
57
87
  await fs.writeFile(outputMdPath, content, "utf-8");
88
+ debugLog(`文件写入成功`, { outputPath: outputMdPath });
58
89
  return {
59
90
  success: true,
60
91
  content,
@@ -109,11 +140,15 @@ export async function tryReadSavedRequirement(featureName) {
109
140
  * 用于保存从 Figma MCP 读取的设计稿内容
110
141
  */
111
142
  export async function saveDesignDocument(featureName, designContent) {
143
+ debugLog(`saveDesignDocument 开始`, { featureName });
112
144
  const designDocPath = `.specs/requirements/${featureName}/design-doc.md`;
113
145
  const outputDir = designDocPath.substring(0, designDocPath.lastIndexOf("/"));
146
+ debugLog(`设计稿准备创建目录`, { outputDir });
114
147
  await fs.mkdir(outputDir, { recursive: true });
148
+ debugLog(`设计稿目录创建成功`);
115
149
  await fs.writeFile(designDocPath, designContent, "utf-8");
116
150
  console.log(`✅ 设计稿已保存到: ${designDocPath}`);
151
+ debugLog(`设计稿文件写入成功`, { outputPath: designDocPath });
117
152
  }
118
153
  /**
119
154
  * 尝试读取已保存的设计稿文档
@@ -132,4 +167,36 @@ export async function tryReadSavedDesign(featureName) {
132
167
  }
133
168
  return null;
134
169
  }
170
+ /**
171
+ * 保存后端文档内容到文件
172
+ * 用于保存从 PDF/网页读取的后端文档内容
173
+ */
174
+ export async function saveBackendDocument(featureName, backendContent) {
175
+ debugLog(`saveBackendDocument 开始`, { featureName });
176
+ const backendDocPath = `.specs/requirements/${featureName}/backend-doc.md`;
177
+ const outputDir = backendDocPath.substring(0, backendDocPath.lastIndexOf("/"));
178
+ debugLog(`后端文档准备创建目录`, { outputDir });
179
+ await fs.mkdir(outputDir, { recursive: true });
180
+ debugLog(`后端文档目录创建成功`);
181
+ await fs.writeFile(backendDocPath, backendContent, "utf-8");
182
+ console.log(`✅ 后端文档已保存到: ${backendDocPath}`);
183
+ debugLog(`后端文档文件写入成功`, { outputPath: backendDocPath });
184
+ }
185
+ /**
186
+ * 尝试读取已保存的后端文档
187
+ */
188
+ export async function tryReadSavedBackend(featureName) {
189
+ const savedBackendPath = `.specs/requirements/${featureName}/backend-doc.md`;
190
+ try {
191
+ const savedContent = await fs.readFile(savedBackendPath, "utf-8");
192
+ if (savedContent) {
193
+ console.log(`✅ 使用已保存的后端文档: ${savedBackendPath}`);
194
+ return savedContent;
195
+ }
196
+ }
197
+ catch (error) {
198
+ // 文件不存在
199
+ }
200
+ return null;
201
+ }
135
202
  //# 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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"}
@@ -152,7 +152,7 @@ AI 负责:
152
152
  }
153
153
  ```
154
154
 
155
- **返回**:同流程 1(无设计稿信息)
155
+ **返回**:同流程 1(无设计稿信息,后端文档已缓存)
156
156
 
157
157
  **AI 执行**:
158
158
  1. 读取 `.specs/requirements/voice-recording/origin-requirement.md`
@@ -338,9 +338,9 @@ AI 负责:
338
338
  **AI 执行**:
339
339
  1. 使用 Figma MCP 工具读取设计稿,保存到 `.specs/requirements/voice-recording/design-doc.md`
340
340
  2. 使用 Chrome DevTools MCP 读取后端文档网页,保存到 `.specs/requirements/voice-recording/backend-doc.md`
341
- 3. 重新调用工具
341
+ 3. 重新调用工具(工具会使用已保存的设计稿和后端文档)
342
342
 
343
- **第 3 次调用**:同流程 1(使用已保存的文档)
343
+ **第 3 次调用**:同流程 1(所有文档已缓存)
344
344
 
345
345
  ---
346
346
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bmall-mcp",
3
- "version": "1.7.0",
3
+ "version": "1.8.1",
4
4
  "description": "MCP Server for bmall development rules and tools",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,11 +1,25 @@
1
1
  import { McpError } from "@modelcontextprotocol/sdk/types.js";
2
+ import * as fs from "fs/promises";
3
+ import * as path from "path";
4
+ import * as os from "os";
2
5
  import {
3
6
  processRequirementDocument,
4
7
  tryReadSavedRequirement,
5
8
  saveDesignDocument,
6
- tryReadSavedDesign
9
+ tryReadSavedDesign,
10
+ saveBackendDocument,
11
+ tryReadSavedBackend
7
12
  } from "./requirement-processor.js";
8
13
 
14
+ /**
15
+ * 调试日志输出
16
+ */
17
+ function debugLog(message: string, data?: any) {
18
+ const timestamp = new Date().toISOString();
19
+ const logMessage = `[DEBUG ${timestamp}] ${message}${data ? '\n' + JSON.stringify(data, null, 2) : ''}`;
20
+ console.error(logMessage);
21
+ }
22
+
9
23
  interface RequirementSource {
10
24
  type: "file" | "url";
11
25
  path?: string;
@@ -70,6 +84,13 @@ export async function generateRequirements(
70
84
  instruction: string;
71
85
  };
72
86
  }> {
87
+ debugLog(`generateRequirements 开始`, {
88
+ params,
89
+ cwd: process.cwd(),
90
+ platform: os.platform(),
91
+ homedir: os.homedir()
92
+ });
93
+
73
94
  try {
74
95
  // 1. 验证必填参数
75
96
  const validation = validateRequiredParams(params);
@@ -80,8 +101,10 @@ export async function generateRequirements(
80
101
  // 2. 处理需求文档输入
81
102
 
82
103
  // 2.1 优先尝试读取已保存的 origin-requirement.md(智能缓存)
104
+ debugLog(`尝试读取已保存的需求文档`, { featureName: params.featureName });
83
105
  const savedContent = await tryReadSavedRequirement(params.featureName);
84
106
  if (!savedContent) {
107
+ debugLog(`未找到缓存,处理需求文档输入`);
85
108
  // 2.2 没有缓存,处理需求文档输入
86
109
  const requirementResult = await processRequirementDocument(
87
110
  params.requirementSource,
@@ -90,6 +113,7 @@ export async function generateRequirements(
90
113
 
91
114
  // 2.2.1 如果需要执行操作(读取 PDF/网页),直接返回
92
115
  if (!requirementResult.success) {
116
+ debugLog(`需求文档处理失败`, { requirementResult });
93
117
  return {
94
118
  success: false,
95
119
  message: requirementResult.message!,
@@ -98,6 +122,8 @@ export async function generateRequirements(
98
122
  }
99
123
 
100
124
  // 2.2.2 需求文档已读取并保存(Markdown 文件)
125
+ } else {
126
+ debugLog(`找到缓存文档`, { contentLength: savedContent.length });
101
127
  }
102
128
 
103
129
  // 3. 检查设计稿
@@ -136,23 +162,33 @@ export async function generateRequirements(
136
162
  // 4. 处理后端文档
137
163
  let backendSourceInfo = "";
138
164
  if (params.backendSource) {
139
- const backendResult = await processRequirementDocument(
140
- params.backendSource,
141
- params.featureName,
142
- "backend-doc.md"
143
- );
165
+ // 4.1 优先尝试读取已保存的后端文档
166
+ const savedBackend = await tryReadSavedBackend(params.featureName);
144
167
 
145
- if (!backendResult.success) {
146
- return {
147
- success: false,
148
- message: backendResult.message!,
149
- needsAction: backendResult.needsAction,
150
- };
151
- }
152
-
153
- if (params.backendSource.type === "file") {
154
- backendSourceInfo = `**后端文档位置**:.specs/requirements/${params.featureName}/backend-doc.md\n`;
155
- } else if (params.backendSource.type === "url") {
168
+ if (!savedBackend) {
169
+ // 4.2 没有缓存,处理后端文档
170
+ const backendResult = await processRequirementDocument(
171
+ params.backendSource,
172
+ params.featureName,
173
+ "backend-doc.md"
174
+ );
175
+
176
+ if (!backendResult.success) {
177
+ return {
178
+ success: false,
179
+ message: backendResult.message!,
180
+ needsAction: backendResult.needsAction,
181
+ };
182
+ }
183
+
184
+ // 4.2.1 文件类型已保存,返回信息
185
+ if (params.backendSource.type === "file") {
186
+ backendSourceInfo = `**后端文档位置**:.specs/requirements/${params.featureName}/backend-doc.md\n`;
187
+ } else if (params.backendSource.type === "url") {
188
+ backendSourceInfo = `**后端文档网页**:${params.backendSource.url || "后端文档网页 URL 未提供"}(请使用 Chrome DevTools MCP 读取并保存到 .specs/requirements/${params.featureName}/backend-doc.md)\n`;
189
+ }
190
+ } else {
191
+ // 4.3 使用已保存的后端文档
156
192
  backendSourceInfo = `**后端文档位置**:.specs/requirements/${params.featureName}/backend-doc.md\n`;
157
193
  }
158
194
  }
@@ -160,6 +196,7 @@ export async function generateRequirements(
160
196
  // 5. 生成分析提示词
161
197
  const outputPath = `.specs/requirements/${params.featureName}/requirements.md`;
162
198
  const originDocPath = `.specs/requirements/${params.featureName}/origin-requirement.md`;
199
+ debugLog(`生成输出路径`, { outputPath, originDocPath });
163
200
 
164
201
  let message = "📝 需求文档已准备完毕\n\n";
165
202
  message += `**原始文档位置**:${originDocPath}\n`;
@@ -172,6 +209,7 @@ export async function generateRequirements(
172
209
  message += `**目标输出位置**:${outputPath}\n\n`;
173
210
  message += buildAnalysisPrompt(originDocPath, outputPath, params.designSource, params.backendSource);
174
211
 
212
+ debugLog(`返回分析提示词`);
175
213
  return {
176
214
  success: false,
177
215
  message,
@@ -181,6 +219,13 @@ export async function generateRequirements(
181
219
  },
182
220
  };
183
221
  } catch (error) {
222
+ debugLog(`发生错误`, {
223
+ error: error instanceof Error ? {
224
+ message: error.message,
225
+ stack: error.stack,
226
+ name: error.name
227
+ } : String(error)
228
+ });
184
229
  if (error instanceof McpError) {
185
230
  throw error;
186
231
  }
@@ -1,5 +1,16 @@
1
1
  import { McpError } from "@modelcontextprotocol/sdk/types.js";
2
2
  import * as fs from "fs/promises";
3
+ import * as path from "path";
4
+ import * as os from "os";
5
+
6
+ /**
7
+ * 调试日志输出
8
+ */
9
+ function debugLog(message: string, data?: any) {
10
+ const timestamp = new Date().toISOString();
11
+ const logMessage = `[DEBUG ${timestamp}] ${message}${data ? '\n' + JSON.stringify(data, null, 2) : ''}`;
12
+ console.error(logMessage);
13
+ }
3
14
 
4
15
  interface RequirementSource {
5
16
  type: "file" | "url";
@@ -32,6 +43,14 @@ export async function processRequirementDocument(
32
43
  featureName: string,
33
44
  outputFileName: string = "origin-requirement.md"
34
45
  ): Promise<ProcessResult> {
46
+ debugLog(`processRequirementDocument 开始`, {
47
+ requirementSource,
48
+ featureName,
49
+ outputFileName,
50
+ cwd: process.cwd(),
51
+ platform: os.platform(),
52
+ homedir: os.homedir()
53
+ });
35
54
  // 2.1 校验是否提供了需求文档
36
55
  if (!requirementSource) {
37
56
  return {
@@ -54,11 +73,13 @@ export async function processRequirementDocument(
54
73
  // 2.2 处理文件类型
55
74
  if (requirementSource.type === "file") {
56
75
  const filePath = requirementSource.path;
76
+ debugLog(`处理文件类型`, { filePath });
57
77
  if (!filePath) {
58
78
  throw new McpError(-32602, "文件路径不能为空");
59
79
  }
60
80
 
61
81
  const ext = filePath.split(".").pop()?.toLowerCase();
82
+ debugLog(`文件扩展名`, { ext });
62
83
 
63
84
  // 2.2.1 PDF 文件 - 返回读取指令
64
85
  if (ext === "pdf") {
@@ -80,14 +101,26 @@ export async function processRequirementDocument(
80
101
  // 2.2.2 Markdown 文件 - 保存到固定位置
81
102
  if (ext === "md" || ext === "markdown") {
82
103
  const outputMdPath = `.specs/requirements/${featureName}/${outputFileName}`;
104
+ debugLog(`准备保存 Markdown 文件`, {
105
+ inputPath: filePath,
106
+ outputPath: outputMdPath,
107
+ isAbsolute: path.isAbsolute(filePath),
108
+ resolvedPath: path.resolve(filePath)
109
+ });
83
110
 
84
111
  // 读取 Markdown 内容
85
112
  const content = await fs.readFile(filePath, "utf-8");
113
+ debugLog(`成功读取文件内容`, { contentLength: content.length });
86
114
 
87
115
  // 保存到固定位置
88
116
  const outputDir = outputMdPath.substring(0, outputMdPath.lastIndexOf("/"));
117
+ debugLog(`准备创建目录`, { outputDir });
89
118
  await fs.mkdir(outputDir, { recursive: true });
119
+ debugLog(`目录创建成功`, { outputDir });
120
+
121
+ debugLog(`准备写入文件`, { outputPath: outputMdPath });
90
122
  await fs.writeFile(outputMdPath, content, "utf-8");
123
+ debugLog(`文件写入成功`, { outputPath: outputMdPath });
91
124
 
92
125
  return {
93
126
  success: true,
@@ -153,11 +186,15 @@ export async function saveDesignDocument(
153
186
  featureName: string,
154
187
  designContent: string
155
188
  ): Promise<void> {
189
+ debugLog(`saveDesignDocument 开始`, { featureName });
156
190
  const designDocPath = `.specs/requirements/${featureName}/design-doc.md`;
157
191
  const outputDir = designDocPath.substring(0, designDocPath.lastIndexOf("/"));
192
+ debugLog(`设计稿准备创建目录`, { outputDir });
158
193
  await fs.mkdir(outputDir, { recursive: true });
194
+ debugLog(`设计稿目录创建成功`);
159
195
  await fs.writeFile(designDocPath, designContent, "utf-8");
160
196
  console.log(`✅ 设计稿已保存到: ${designDocPath}`);
197
+ debugLog(`设计稿文件写入成功`, { outputPath: designDocPath });
161
198
  }
162
199
 
163
200
  /**
@@ -178,3 +215,41 @@ export async function tryReadSavedDesign(
178
215
  }
179
216
  return null;
180
217
  }
218
+
219
+ /**
220
+ * 保存后端文档内容到文件
221
+ * 用于保存从 PDF/网页读取的后端文档内容
222
+ */
223
+ export async function saveBackendDocument(
224
+ featureName: string,
225
+ backendContent: string
226
+ ): Promise<void> {
227
+ debugLog(`saveBackendDocument 开始`, { featureName });
228
+ const backendDocPath = `.specs/requirements/${featureName}/backend-doc.md`;
229
+ const outputDir = backendDocPath.substring(0, backendDocPath.lastIndexOf("/"));
230
+ debugLog(`后端文档准备创建目录`, { outputDir });
231
+ await fs.mkdir(outputDir, { recursive: true });
232
+ debugLog(`后端文档目录创建成功`);
233
+ await fs.writeFile(backendDocPath, backendContent, "utf-8");
234
+ console.log(`✅ 后端文档已保存到: ${backendDocPath}`);
235
+ debugLog(`后端文档文件写入成功`, { outputPath: backendDocPath });
236
+ }
237
+
238
+ /**
239
+ * 尝试读取已保存的后端文档
240
+ */
241
+ export async function tryReadSavedBackend(
242
+ featureName: string
243
+ ): Promise<string | null> {
244
+ const savedBackendPath = `.specs/requirements/${featureName}/backend-doc.md`;
245
+ try {
246
+ const savedContent = await fs.readFile(savedBackendPath, "utf-8");
247
+ if (savedContent) {
248
+ console.log(`✅ 使用已保存的后端文档: ${savedBackendPath}`);
249
+ return savedContent;
250
+ }
251
+ } catch (error) {
252
+ // 文件不存在
253
+ }
254
+ return null;
255
+ }