bmall-mcp 1.8.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 +8 -0
- package/dist/tools/requirements/index.d.ts.map +1 -1
- package/dist/tools/requirements/index.js +30 -0
- package/dist/tools/requirements/index.js.map +1 -1
- package/dist/tools/requirements/requirement-processor.d.ts.map +1 -1
- package/dist/tools/requirements/requirement-processor.js +39 -0
- package/dist/tools/requirements/requirement-processor.js.map +1 -1
- package/package.json +1 -1
- package/src/tools/requirements/index.ts +33 -0
- package/src/tools/requirements/requirement-processor.ts +41 -0
package/README.md
CHANGED
|
@@ -204,6 +204,14 @@ src/
|
|
|
204
204
|
|
|
205
205
|
## Changelog
|
|
206
206
|
|
|
207
|
+
### v1.8.1 (2026-03-16)
|
|
208
|
+
- ✅ 新增 generate_requirements 工具详细调试日志
|
|
209
|
+
- ✅ 添加环境信息输出(工作目录、平台、主目录)
|
|
210
|
+
- ✅ 添加文件路径解析日志(绝对路径/相对路径)
|
|
211
|
+
- ✅ 添加文件操作日志(读取、目录创建、写入)
|
|
212
|
+
- ✅ 添加完整错误堆栈信息
|
|
213
|
+
- ✅ 优化错误诊断能力
|
|
214
|
+
|
|
207
215
|
### v1.8.0 (2026-03-16)
|
|
208
216
|
- ✅ 完善后端文档处理逻辑:添加智能缓存机制
|
|
209
217
|
- ✅ 新增后端文档缓存函数:saveBackendDocument、tryReadSavedBackend
|
|
@@ -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":"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 * as os from "os";
|
|
2
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) {
|
|
@@ -100,6 +121,7 @@ export async function generateRequirements(params) {
|
|
|
100
121
|
// 5. 生成分析提示词
|
|
101
122
|
const outputPath = `.specs/requirements/${params.featureName}/requirements.md`;
|
|
102
123
|
const originDocPath = `.specs/requirements/${params.featureName}/origin-requirement.md`;
|
|
124
|
+
debugLog(`生成输出路径`, { outputPath, originDocPath });
|
|
103
125
|
let message = "📝 需求文档已准备完毕\n\n";
|
|
104
126
|
message += `**原始文档位置**:${originDocPath}\n`;
|
|
105
127
|
if (designSourceInfo) {
|
|
@@ -110,6 +132,7 @@ export async function generateRequirements(params) {
|
|
|
110
132
|
}
|
|
111
133
|
message += `**目标输出位置**:${outputPath}\n\n`;
|
|
112
134
|
message += buildAnalysisPrompt(originDocPath, outputPath, params.designSource, params.backendSource);
|
|
135
|
+
debugLog(`返回分析提示词`);
|
|
113
136
|
return {
|
|
114
137
|
success: false,
|
|
115
138
|
message,
|
|
@@ -120,6 +143,13 @@ export async function generateRequirements(params) {
|
|
|
120
143
|
};
|
|
121
144
|
}
|
|
122
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
|
+
});
|
|
123
153
|
if (error instanceof McpError) {
|
|
124
154
|
throw error;
|
|
125
155
|
}
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/requirements/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requirement-processor.d.ts","sourceRoot":"","sources":["../../../src/tools/requirements/requirement-processor.ts"],"names":[],"mappings":"
|
|
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
|
* 尝试读取已保存的设计稿文档
|
|
@@ -137,11 +172,15 @@ export async function tryReadSavedDesign(featureName) {
|
|
|
137
172
|
* 用于保存从 PDF/网页读取的后端文档内容
|
|
138
173
|
*/
|
|
139
174
|
export async function saveBackendDocument(featureName, backendContent) {
|
|
175
|
+
debugLog(`saveBackendDocument 开始`, { featureName });
|
|
140
176
|
const backendDocPath = `.specs/requirements/${featureName}/backend-doc.md`;
|
|
141
177
|
const outputDir = backendDocPath.substring(0, backendDocPath.lastIndexOf("/"));
|
|
178
|
+
debugLog(`后端文档准备创建目录`, { outputDir });
|
|
142
179
|
await fs.mkdir(outputDir, { recursive: true });
|
|
180
|
+
debugLog(`后端文档目录创建成功`);
|
|
143
181
|
await fs.writeFile(backendDocPath, backendContent, "utf-8");
|
|
144
182
|
console.log(`✅ 后端文档已保存到: ${backendDocPath}`);
|
|
183
|
+
debugLog(`后端文档文件写入成功`, { outputPath: backendDocPath });
|
|
145
184
|
}
|
|
146
185
|
/**
|
|
147
186
|
* 尝试读取已保存的后端文档
|
|
@@ -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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"}
|
package/package.json
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
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,
|
|
@@ -8,6 +11,15 @@ import {
|
|
|
8
11
|
tryReadSavedBackend
|
|
9
12
|
} from "./requirement-processor.js";
|
|
10
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
|
+
|
|
11
23
|
interface RequirementSource {
|
|
12
24
|
type: "file" | "url";
|
|
13
25
|
path?: string;
|
|
@@ -72,6 +84,13 @@ export async function generateRequirements(
|
|
|
72
84
|
instruction: string;
|
|
73
85
|
};
|
|
74
86
|
}> {
|
|
87
|
+
debugLog(`generateRequirements 开始`, {
|
|
88
|
+
params,
|
|
89
|
+
cwd: process.cwd(),
|
|
90
|
+
platform: os.platform(),
|
|
91
|
+
homedir: os.homedir()
|
|
92
|
+
});
|
|
93
|
+
|
|
75
94
|
try {
|
|
76
95
|
// 1. 验证必填参数
|
|
77
96
|
const validation = validateRequiredParams(params);
|
|
@@ -82,8 +101,10 @@ export async function generateRequirements(
|
|
|
82
101
|
// 2. 处理需求文档输入
|
|
83
102
|
|
|
84
103
|
// 2.1 优先尝试读取已保存的 origin-requirement.md(智能缓存)
|
|
104
|
+
debugLog(`尝试读取已保存的需求文档`, { featureName: params.featureName });
|
|
85
105
|
const savedContent = await tryReadSavedRequirement(params.featureName);
|
|
86
106
|
if (!savedContent) {
|
|
107
|
+
debugLog(`未找到缓存,处理需求文档输入`);
|
|
87
108
|
// 2.2 没有缓存,处理需求文档输入
|
|
88
109
|
const requirementResult = await processRequirementDocument(
|
|
89
110
|
params.requirementSource,
|
|
@@ -92,6 +113,7 @@ export async function generateRequirements(
|
|
|
92
113
|
|
|
93
114
|
// 2.2.1 如果需要执行操作(读取 PDF/网页),直接返回
|
|
94
115
|
if (!requirementResult.success) {
|
|
116
|
+
debugLog(`需求文档处理失败`, { requirementResult });
|
|
95
117
|
return {
|
|
96
118
|
success: false,
|
|
97
119
|
message: requirementResult.message!,
|
|
@@ -100,6 +122,8 @@ export async function generateRequirements(
|
|
|
100
122
|
}
|
|
101
123
|
|
|
102
124
|
// 2.2.2 需求文档已读取并保存(Markdown 文件)
|
|
125
|
+
} else {
|
|
126
|
+
debugLog(`找到缓存文档`, { contentLength: savedContent.length });
|
|
103
127
|
}
|
|
104
128
|
|
|
105
129
|
// 3. 检查设计稿
|
|
@@ -172,6 +196,7 @@ export async function generateRequirements(
|
|
|
172
196
|
// 5. 生成分析提示词
|
|
173
197
|
const outputPath = `.specs/requirements/${params.featureName}/requirements.md`;
|
|
174
198
|
const originDocPath = `.specs/requirements/${params.featureName}/origin-requirement.md`;
|
|
199
|
+
debugLog(`生成输出路径`, { outputPath, originDocPath });
|
|
175
200
|
|
|
176
201
|
let message = "📝 需求文档已准备完毕\n\n";
|
|
177
202
|
message += `**原始文档位置**:${originDocPath}\n`;
|
|
@@ -184,6 +209,7 @@ export async function generateRequirements(
|
|
|
184
209
|
message += `**目标输出位置**:${outputPath}\n\n`;
|
|
185
210
|
message += buildAnalysisPrompt(originDocPath, outputPath, params.designSource, params.backendSource);
|
|
186
211
|
|
|
212
|
+
debugLog(`返回分析提示词`);
|
|
187
213
|
return {
|
|
188
214
|
success: false,
|
|
189
215
|
message,
|
|
@@ -193,6 +219,13 @@ export async function generateRequirements(
|
|
|
193
219
|
},
|
|
194
220
|
};
|
|
195
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
|
+
});
|
|
196
229
|
if (error instanceof McpError) {
|
|
197
230
|
throw error;
|
|
198
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
|
/**
|
|
@@ -187,11 +224,15 @@ export async function saveBackendDocument(
|
|
|
187
224
|
featureName: string,
|
|
188
225
|
backendContent: string
|
|
189
226
|
): Promise<void> {
|
|
227
|
+
debugLog(`saveBackendDocument 开始`, { featureName });
|
|
190
228
|
const backendDocPath = `.specs/requirements/${featureName}/backend-doc.md`;
|
|
191
229
|
const outputDir = backendDocPath.substring(0, backendDocPath.lastIndexOf("/"));
|
|
230
|
+
debugLog(`后端文档准备创建目录`, { outputDir });
|
|
192
231
|
await fs.mkdir(outputDir, { recursive: true });
|
|
232
|
+
debugLog(`后端文档目录创建成功`);
|
|
193
233
|
await fs.writeFile(backendDocPath, backendContent, "utf-8");
|
|
194
234
|
console.log(`✅ 后端文档已保存到: ${backendDocPath}`);
|
|
235
|
+
debugLog(`后端文档文件写入成功`, { outputPath: backendDocPath });
|
|
195
236
|
}
|
|
196
237
|
|
|
197
238
|
/**
|