@becrafter/prompt-manager 0.1.22 → 0.2.2

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.
Files changed (114) hide show
  1. package/package.json +31 -24
  2. package/packages/resources/tools/agent-browser/README.md +640 -0
  3. package/packages/resources/tools/agent-browser/agent-browser.tool.js +1389 -0
  4. package/packages/resources/tools/thinking/README.md +324 -0
  5. package/packages/resources/tools/thinking/thinking.tool.js +911 -0
  6. package/packages/server/README.md +3 -4
  7. package/packages/server/api/admin.routes.js +668 -664
  8. package/packages/server/api/open.routes.js +68 -67
  9. package/packages/server/api/surge.routes.js +5 -6
  10. package/packages/server/api/tool.routes.js +70 -71
  11. package/packages/server/app.js +70 -73
  12. package/packages/server/configs/authors.json +40 -0
  13. package/packages/server/configs/models/built-in/bigmodel.yaml +6 -6
  14. package/packages/server/configs/models/providers.yaml +4 -4
  15. package/packages/server/configs/templates/built-in/general-iteration.yaml +1 -1
  16. package/packages/server/configs/templates/built-in/general-optimize.yaml +1 -1
  17. package/packages/server/configs/templates/built-in/output-format-optimize.yaml +1 -1
  18. package/packages/server/index.js +3 -9
  19. package/packages/server/mcp/heartbeat-patch.js +1 -3
  20. package/packages/server/mcp/mcp.server.js +64 -134
  21. package/packages/server/mcp/prompt.handler.js +101 -95
  22. package/packages/server/middlewares/auth.middleware.js +31 -31
  23. package/packages/server/server.js +60 -45
  24. package/packages/server/services/TerminalService.js +156 -70
  25. package/packages/server/services/WebSocketService.js +35 -34
  26. package/packages/server/services/author-config.service.js +199 -0
  27. package/packages/server/services/manager.js +66 -60
  28. package/packages/server/services/model.service.js +5 -9
  29. package/packages/server/services/optimization.service.js +25 -22
  30. package/packages/server/services/template.service.js +3 -8
  31. package/packages/server/toolm/author-sync.service.js +97 -0
  32. package/packages/server/toolm/index.js +1 -2
  33. package/packages/server/toolm/package-installer.service.js +47 -50
  34. package/packages/server/toolm/tool-context.service.js +64 -62
  35. package/packages/server/toolm/tool-dependency.service.js +28 -30
  36. package/packages/server/toolm/tool-description-generator-optimized.service.js +55 -55
  37. package/packages/server/toolm/tool-description-generator.service.js +20 -23
  38. package/packages/server/toolm/tool-environment.service.js +45 -44
  39. package/packages/server/toolm/tool-execution.service.js +49 -48
  40. package/packages/server/toolm/tool-loader.service.js +13 -18
  41. package/packages/server/toolm/tool-logger.service.js +33 -39
  42. package/packages/server/toolm/tool-manager.handler.js +17 -15
  43. package/packages/server/toolm/tool-manual-generator.service.js +107 -87
  44. package/packages/server/toolm/tool-mode-handlers.service.js +52 -59
  45. package/packages/server/toolm/tool-storage.service.js +11 -12
  46. package/packages/server/toolm/tool-sync.service.js +36 -39
  47. package/packages/server/toolm/tool-utils.js +0 -1
  48. package/packages/server/toolm/tool-yaml-parser.service.js +12 -11
  49. package/packages/server/toolm/validate-system.js +56 -84
  50. package/packages/server/utils/config.js +97 -12
  51. package/packages/server/utils/logger.js +1 -1
  52. package/packages/server/utils/port-checker.js +8 -8
  53. package/packages/server/utils/util.js +470 -467
  54. package/packages/resources/tools/cognitive-thinking/README.md +0 -284
  55. package/packages/resources/tools/cognitive-thinking/cognitive-thinking.tool.js +0 -837
  56. package/packages/server/mcp/sequential-thinking.handler.js +0 -318
  57. package/packages/server/mcp/think-plan.handler.js +0 -274
  58. package/packages/server/mcp/thinking-toolkit.handler.js +0 -380
  59. package/packages/web/0.d1c5a72339dfc32ad86a.js +0 -1
  60. package/packages/web/112.8807b976372b2b0541a8.js +0 -1
  61. package/packages/web/130.584c7e365da413f5d9be.js +0 -1
  62. package/packages/web/142.72c985bc29720f975cca.js +0 -1
  63. package/packages/web/165.a05fc53bf84d18db36b8.js +0 -2
  64. package/packages/web/165.a05fc53bf84d18db36b8.js.LICENSE.txt +0 -9
  65. package/packages/web/203.724ab9f717b80554c397.js +0 -1
  66. package/packages/web/241.bf941d4f02866795f64a.js +0 -1
  67. package/packages/web/249.54cfb224af63f5f5ec55.js +0 -1
  68. package/packages/web/291.6df35042f8f296fca7cd.js +0 -1
  69. package/packages/web/319.2fab900a31b29873f666.js +0 -1
  70. package/packages/web/32.c78d866281995ec33a7b.js +0 -1
  71. package/packages/web/325.9ca297d0f73f38468ce9.js +0 -1
  72. package/packages/web/366.2f9b48fdbf8eee039e57.js +0 -1
  73. package/packages/web/378.6be08c612cd5a3ef97dc.js +0 -1
  74. package/packages/web/393.7a2f817515c5e90623d7.js +0 -1
  75. package/packages/web/412.062df5f732d5ba203415.js +0 -1
  76. package/packages/web/426.08656fef4918b3fb19ad.js +0 -1
  77. package/packages/web/465.2be8018327130a3bd798.js +0 -1
  78. package/packages/web/48.8ca96fc93667a715e67a.js +0 -1
  79. package/packages/web/480.44c1f1a2927486ac3d4f.js +0 -1
  80. package/packages/web/489.e041a8d0db15dc96d607.js +0 -1
  81. package/packages/web/490.9ffb26c907de020d671b.js +0 -1
  82. package/packages/web/492.58781369e348d91fc06a.js +0 -1
  83. package/packages/web/495.ed63e99791a87167c6b3.js +0 -1
  84. package/packages/web/510.4cc07ab7d30d5c1cd17f.js +0 -1
  85. package/packages/web/543.3af155ed4fa237664308.js +0 -1
  86. package/packages/web/567.f04ab60f8e2c2fb0745a.js +0 -1
  87. package/packages/web/592.f3ad085fa9c1849daa06.js +0 -1
  88. package/packages/web/616.b03fb801b3433b17750f.js +0 -1
  89. package/packages/web/617.d88def54921d2c4dc44c.js +0 -1
  90. package/packages/web/641.d30787d674f548928261.js +0 -1
  91. package/packages/web/672.5269c8399fa42a5af95d.js +0 -1
  92. package/packages/web/731.97cab92b71811c502bda.js +0 -1
  93. package/packages/web/746.3947c6f0235407e420fb.js +0 -1
  94. package/packages/web/756.a53233b3f3913900d5ac.js +0 -1
  95. package/packages/web/77.68801af593a28a631fbf.js +0 -1
  96. package/packages/web/802.53b2bff3cf2a69f7b80c.js +0 -1
  97. package/packages/web/815.b6dfab82265f56c7e046.js +0 -1
  98. package/packages/web/821.f5a13e5c735aac244eb9.js +0 -1
  99. package/packages/web/846.b9bf97d5f559270675ce.js +0 -1
  100. package/packages/web/869.7c10403f500e6201407f.js +0 -1
  101. package/packages/web/885.135050364f99e6924fb5.js +0 -1
  102. package/packages/web/901.fd5aeb9df630609a2b43.js +0 -1
  103. package/packages/web/928.f67e590de3caa4daa3ae.js +0 -1
  104. package/packages/web/955.d833403521ba4dd567ee.js +0 -1
  105. package/packages/web/981.a45cb745cf424044c8c8.js +0 -1
  106. package/packages/web/992.645320b60c74c8787482.js +0 -1
  107. package/packages/web/996.ed9a963dc9e7439eca9a.js +0 -1
  108. package/packages/web/css/codemirror-theme_xq-light.css +0 -43
  109. package/packages/web/css/codemirror.css +0 -344
  110. package/packages/web/css/main.196f434e6a88cd448158.css +0 -7278
  111. package/packages/web/css/terminal-fix.css +0 -571
  112. package/packages/web/index.html +0 -3
  113. package/packages/web/main.dceff50c7307dda04873.js +0 -2
  114. package/packages/web/main.dceff50c7307dda04873.js.LICENSE.txt +0 -3
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * 工具执行服务
3
- *
3
+ *
4
4
  * 职责:
5
5
  * 1. 处理工具执行模式
6
6
  * 2. 创建执行上下文
@@ -21,7 +21,7 @@ import { generateHelpInfo } from './tool-manual-generator.service.js';
21
21
  */
22
22
  export async function executeTool(toolName, parameters) {
23
23
  logger.info(`执行工具: ${toolName}`, { parameters });
24
-
24
+
25
25
  try {
26
26
  const tool = toolLoaderService.getTool(toolName);
27
27
  const toolModule = tool.module;
@@ -31,9 +31,9 @@ export async function executeTool(toolName, parameters) {
31
31
 
32
32
  // 2. 创建工具执行上下文
33
33
  const toolContext = await createToolContext(toolName, toolModule);
34
-
34
+
35
35
  // 3. 记录执行开始
36
- toolContext.api.logger.info('执行开始', {
36
+ toolContext.api.logger.info('执行开始', {
37
37
  tool: toolName,
38
38
  parameters: Object.keys(parameters)
39
39
  });
@@ -42,35 +42,33 @@ export async function executeTool(toolName, parameters) {
42
42
  let result;
43
43
  try {
44
44
  result = await toolContext.execute(parameters);
45
-
45
+
46
46
  // 5. 记录执行完成
47
- toolContext.api.logger.info('执行完成', {
47
+ toolContext.api.logger.info('执行完成', {
48
48
  tool: toolName,
49
49
  success: true
50
50
  });
51
-
52
51
  } catch (error) {
53
52
  // 记录执行错误
54
- toolContext.api.logger.error('执行失败', {
53
+ toolContext.api.logger.error('执行失败', {
55
54
  tool: toolName,
56
55
  error: error.message,
57
56
  stack: error.stack
58
57
  });
59
58
  throw error;
60
59
  }
61
-
60
+
62
61
  logger.info(`工具执行成功: ${toolName}`);
63
-
62
+
64
63
  // 6. 格式化并返回结果
65
64
  const content = formatToolResult(result, toolName);
66
65
  return { content };
67
-
68
66
  } catch (error) {
69
67
  logger.error(`工具执行失败: ${toolName}`, { error: error.message });
70
-
68
+
71
69
  const tool = toolLoaderService.getTool(toolName);
72
70
  const helpInfo = generateErrorHelpInfo(toolName, error, tool, parameters);
73
-
71
+
74
72
  return createTextResponse(helpInfo);
75
73
  }
76
74
  }
@@ -82,40 +80,40 @@ export async function executeTool(toolName, parameters) {
82
80
  /**
83
81
  * 格式化工具执行结果
84
82
  * 根据结果类型自动识别并转换为 MCP 格式的内容
85
- *
83
+ *
86
84
  * @param {any} result - 工具执行结果
87
85
  * @param {string} toolName - 工具名称
88
86
  * @returns {Array} MCP 格式的内容数组
89
87
  */
90
88
  function formatToolResult(result, toolName) {
91
89
  const content = [];
92
-
90
+
93
91
  // 尝试提取图片数据
94
92
  const imageContent = extractImageContent(result);
95
93
  if (imageContent.length > 0) {
96
94
  content.push(...imageContent);
97
-
95
+
98
96
  // 对于截图操作,只返回图片
99
97
  if (result?.method === 'takeScreenshot') {
100
98
  logger.info('截图成功,返回图片数据');
101
99
  return content;
102
100
  }
103
-
101
+
104
102
  // 其他操作有图片时,添加文本信息
105
103
  if (result?.text) {
106
104
  content.push(createTextContent(result.text));
107
105
  } else if (result?.method) {
108
106
  content.push(createTextContent(`操作成功:${result.method}`));
109
107
  }
110
-
108
+
111
109
  return content;
112
110
  }
113
-
111
+
114
112
  // 处理 file-reader 工具的其他格式(二进制、媒体元信息等)
115
113
  if (result?.format && result?.content) {
116
114
  return [createJsonTextContent(result, toolName)];
117
115
  }
118
-
116
+
119
117
  // 默认情况:返回 JSON 格式
120
118
  return [createJsonTextContent(result, toolName)];
121
119
  }
@@ -126,17 +124,17 @@ function formatToolResult(result, toolName) {
126
124
  * 1. chrome-devtools: result.images 数组
127
125
  * 2. filesystem: result.base64 + result.mimeType (图片类型)
128
126
  * 3. file-reader: result.format === 'image' + result.content.base64
129
- *
127
+ *
130
128
  * @param {any} result - 工具执行结果
131
129
  * @returns {Array} 图片内容数组
132
130
  */
133
131
  function extractImageContent(result) {
134
132
  const images = [];
135
-
133
+
136
134
  if (!result) {
137
135
  return images;
138
136
  }
139
-
137
+
140
138
  // 情况1: chrome-devtools 工具返回的图片数组
141
139
  if (Array.isArray(result.images) && result.images.length > 0) {
142
140
  for (const image of result.images) {
@@ -146,18 +144,18 @@ function extractImageContent(result) {
146
144
  }
147
145
  return images;
148
146
  }
149
-
147
+
150
148
  // 情况2: filesystem 工具的 read_media_file 返回的 base64 + mimeType
151
149
  if (result.base64 && result.mimeType && result.mimeType.startsWith('image/')) {
152
150
  images.push(createImageContent(result.base64, result.mimeType));
153
151
  logger.info('读取图片文件成功,返回图片数据');
154
152
  return images;
155
153
  }
156
-
154
+
157
155
  // 情况3: file-reader 工具返回的图片格式
158
156
  if (result.format === 'image' && result.content?.base64 && result.content?.mimeType) {
159
157
  images.push(createImageContent(result.content.base64, result.content.mimeType));
160
-
158
+
161
159
  // 如果有描述信息,也一并返回
162
160
  if (result.content.description) {
163
161
  images.push(createTextContent(result.content.description));
@@ -165,59 +163,63 @@ function extractImageContent(result) {
165
163
  logger.info('读取图片文件成功,返回图片数据');
166
164
  return images;
167
165
  }
168
-
166
+
169
167
  return images;
170
168
  }
171
169
 
172
170
  /**
173
171
  * 创建图片类型的内容
174
- *
172
+ *
175
173
  * @param {string} data - base64 编码的图片数据
176
174
  * @param {string} mimeType - 图片 MIME 类型
177
175
  * @returns {object} MCP 图片内容对象
178
176
  */
179
177
  function createImageContent(data, mimeType) {
180
178
  return {
181
- type: "image",
182
- data: data,
183
- mimeType: mimeType
179
+ type: 'image',
180
+ data,
181
+ mimeType
184
182
  };
185
183
  }
186
184
 
187
185
  /**
188
186
  * 创建文本类型的内容
189
- *
187
+ *
190
188
  * @param {string} text - 文本内容
191
189
  * @returns {object} MCP 文本内容对象
192
190
  */
193
191
  function createTextContent(text) {
194
192
  return {
195
- type: "text",
196
- text: text
193
+ type: 'text',
194
+ text
197
195
  };
198
196
  }
199
197
 
200
198
  /**
201
199
  * 创建 JSON 格式的文本内容
202
- *
200
+ *
203
201
  * @param {any} result - 工具执行结果
204
202
  * @param {string} toolName - 工具名称
205
203
  * @returns {object} MCP 文本内容对象
206
204
  */
207
205
  function createJsonTextContent(result, toolName) {
208
206
  return createTextContent(
209
- JSON.stringify({
210
- success: true,
211
- tool: toolName,
212
- mode: 'execute',
213
- result: result
214
- }, null, 2)
207
+ JSON.stringify(
208
+ {
209
+ success: true,
210
+ tool: toolName,
211
+ mode: 'execute',
212
+ result
213
+ },
214
+ null,
215
+ 2
216
+ )
215
217
  );
216
218
  }
217
219
 
218
220
  /**
219
221
  * 创建文本类型的响应
220
- *
222
+ *
221
223
  * @param {string} text - 文本内容
222
224
  * @returns {object} MCP 格式的响应对象
223
225
  */
@@ -229,7 +231,7 @@ function createTextResponse(text) {
229
231
 
230
232
  /**
231
233
  * 生成错误帮助信息
232
- *
234
+ *
233
235
  * @param {string} toolName - 工具名称
234
236
  * @param {Error} error - 错误对象
235
237
  * @param {object} tool - 工具对象
@@ -241,7 +243,7 @@ function generateErrorHelpInfo(toolName, error, tool, parameters) {
241
243
  if (isValidationErrorType(error.message)) {
242
244
  return generateHelpInfo(toolName, error, tool, parameters);
243
245
  }
244
-
246
+
245
247
  // 检查是否是业务错误
246
248
  const businessErrors = tool?.businessErrors || [];
247
249
  for (const businessError of businessErrors) {
@@ -249,14 +251,14 @@ function generateErrorHelpInfo(toolName, error, tool, parameters) {
249
251
  return generateHelpInfo(toolName, error, tool, parameters, businessError);
250
252
  }
251
253
  }
252
-
254
+
253
255
  // 其他错误也返回帮助信息
254
256
  return generateHelpInfo(toolName, error, tool, parameters);
255
257
  }
256
258
 
257
259
  /**
258
260
  * 判断是否是参数验证错误
259
- *
261
+ *
260
262
  * @param {string} errorMessage - 错误消息
261
263
  * @returns {boolean} 是否是参数验证错误
262
264
  */
@@ -271,7 +273,6 @@ function isValidationErrorType(errorMessage) {
271
273
  /参数.*类型错误/i,
272
274
  /参数.*格式错误/i
273
275
  ];
274
-
276
+
275
277
  return validationPatterns.some(pattern => pattern.test(errorMessage));
276
278
  }
277
-
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * 工具加载服务
3
- *
3
+ *
4
4
  * 职责:
5
5
  * 1. 扫描并加载 ~/.prompt-manager/tools 和 packages/resources/tools 目录下的所有工具
6
6
  * 2. 验证工具是否符合标准接口规范
@@ -11,26 +11,22 @@
11
11
 
12
12
  import fs from 'fs-extra';
13
13
  import path from 'path';
14
- import os from 'os';
15
- import { fileURLToPath } from 'url';
16
14
  import { logger } from '../utils/logger.js';
17
15
  import { pathExists } from './tool-utils.js';
18
16
  import { generateManual as generateManualFromService } from './tool-manual-generator.service.js';
19
-
20
- const __filename = fileURLToPath(import.meta.url);
21
- const __dirname = path.dirname(__filename);
17
+ import { config } from '../utils/config.js';
22
18
 
23
19
  class ToolLoaderService {
24
20
  constructor() {
25
21
  // 工具缓存:toolName -> toolModule
26
22
  this.toolCache = new Map();
27
-
23
+
28
24
  // 工具目录列表(所有工具都在沙箱环境中)
29
25
  this.toolDirectories = [
30
26
  // 沙箱工具目录(系统工具和用户工具都在这里)
31
- path.join(os.homedir(), '.prompt-manager', 'toolbox')
27
+ config.getToolboxDir()
32
28
  ];
33
-
29
+
34
30
  // 已初始化标志
35
31
  this.initialized = false;
36
32
  }
@@ -45,14 +41,14 @@ class ToolLoaderService {
45
41
  }
46
42
 
47
43
  logger.info('初始化工具加载器...');
48
-
44
+
49
45
  // 确保工具箱目录存在
50
- const toolboxDir = path.join(os.homedir(), '.prompt-manager', 'toolbox');
46
+ const toolboxDir = config.getToolboxDir();
51
47
  await fs.ensureDir(toolboxDir);
52
-
48
+
53
49
  // 扫描并加载所有工具
54
50
  await this.scanAndLoadTools();
55
-
51
+
56
52
  this.initialized = true;
57
53
  logger.info(`工具加载器初始化完成,共加载 ${this.toolCache.size} 个工具`);
58
54
  }
@@ -62,14 +58,14 @@ class ToolLoaderService {
62
58
  */
63
59
  async scanAndLoadTools() {
64
60
  for (const toolsDir of this.toolDirectories) {
65
- if (!await pathExists(toolsDir)) {
61
+ if (!(await pathExists(toolsDir))) {
66
62
  logger.debug(`工具目录不存在,跳过: ${toolsDir}`);
67
63
  continue;
68
64
  }
69
65
 
70
66
  try {
71
67
  const entries = await fs.readdir(toolsDir, { withFileTypes: true });
72
-
68
+
73
69
  for (const entry of entries) {
74
70
  if (!entry.isDirectory()) {
75
71
  continue;
@@ -78,7 +74,7 @@ class ToolLoaderService {
78
74
  const toolName = entry.name;
79
75
  const toolDir = path.join(toolsDir, toolName);
80
76
  const toolFile = path.join(toolDir, `${toolName}.tool.js`);
81
-
77
+
82
78
  if (await pathExists(toolFile)) {
83
79
  try {
84
80
  await this.loadTool(toolName, toolFile);
@@ -129,7 +125,7 @@ class ToolLoaderService {
129
125
  validateToolInterface(toolName, tool) {
130
126
  // 必需的方法
131
127
  const requiredMethods = ['execute'];
132
-
128
+
133
129
  // 推荐的方法
134
130
  const recommendedMethods = ['getMetadata', 'getSchema', 'getDependencies', 'getBusinessErrors'];
135
131
 
@@ -216,4 +212,3 @@ class ToolLoaderService {
216
212
 
217
213
  // 导出单例实例
218
214
  export const toolLoaderService = new ToolLoaderService();
219
-
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * 工具日志记录服务
3
- *
3
+ *
4
4
  * 职责:
5
5
  * 1. 为每个工具提供独立的日志记录器
6
6
  * 2. 日志自动写入到工具的 run.log 文件
@@ -10,9 +10,9 @@
10
10
 
11
11
  import fs from 'fs-extra';
12
12
  import path from 'path';
13
- import os from 'os';
14
13
  import { logger } from '../utils/logger.js';
15
14
  import { pathExists } from './tool-utils.js';
15
+ import { config } from '../utils/config.js';
16
16
 
17
17
  // 日志队列,用于批量写入
18
18
  const logQueues = new Map();
@@ -38,27 +38,25 @@ export function getLogger(toolName) {
38
38
  if (!logQueues.has(toolName)) {
39
39
  logQueues.set(toolName, []);
40
40
  }
41
-
41
+
42
42
  const logQueue = logQueues.get(toolName);
43
-
43
+
44
44
  return {
45
45
  info: (message, meta) => log(toolName, 'INFO', message, meta),
46
46
  warn: (message, meta) => log(toolName, 'WARN', message, meta),
47
47
  error: (message, meta) => log(toolName, 'ERROR', message, meta),
48
48
  debug: (message, meta) => log(toolName, 'DEBUG', message, meta)
49
49
  };
50
-
50
+
51
51
  function log(toolName, level, message, meta = {}) {
52
52
  const timestamp = new Date().toISOString();
53
- const metaStr = meta && Object.keys(meta).length > 0
54
- ? ' ' + JSON.stringify(meta)
55
- : '';
56
-
53
+ const metaStr = meta && Object.keys(meta).length > 0 ? ` ${JSON.stringify(meta)}` : '';
54
+
57
55
  const logEntry = `[${timestamp}] [${level}] ${message}${metaStr}\n`;
58
-
56
+
59
57
  // 添加到队列
60
58
  logQueue.push(logEntry);
61
-
59
+
62
60
  // 如果队列达到一定大小,立即刷新
63
61
  if (logQueue.length >= 10) {
64
62
  flushLogQueue(toolName).catch(error => {
@@ -84,38 +82,35 @@ async function flushLogQueue(toolName) {
84
82
  if (!logQueue || logQueue.length === 0) {
85
83
  return;
86
84
  }
87
-
88
- const toolDir = path.join(os.homedir(), '.prompt-manager', 'toolbox', toolName);
85
+
86
+ const toolDir = config.getToolDir(toolName);
89
87
  const logFilePath = path.join(toolDir, 'run.log');
90
-
88
+
91
89
  try {
92
90
  // 确保目录存在
93
91
  await fs.ensureDir(toolDir);
94
-
92
+
95
93
  // 读取现有日志(如果存在)
96
94
  let existingLogs = '';
97
95
  if (await pathExists(logFilePath)) {
98
96
  existingLogs = await fs.readFile(logFilePath, 'utf-8');
99
97
  }
100
-
98
+
101
99
  // 清理过期日志
102
100
  const cleanedLogs = cleanOldLogs(existingLogs);
103
-
101
+
104
102
  // 合并新日志
105
103
  const newLogs = logQueue.join('');
106
104
  const allLogs = cleanedLogs + newLogs;
107
-
105
+
108
106
  // 检查日志文件大小
109
- const logsToWrite = allLogs.length > MAX_LOG_SIZE
110
- ? keepRecentLogs(allLogs)
111
- : allLogs;
112
-
107
+ const logsToWrite = allLogs.length > MAX_LOG_SIZE ? keepRecentLogs(allLogs) : allLogs;
108
+
113
109
  // 写入日志文件
114
110
  await fs.writeFile(logFilePath, logsToWrite, 'utf-8');
115
-
111
+
116
112
  // 清空队列
117
113
  logQueue.length = 0;
118
-
119
114
  } catch (error) {
120
115
  logger.error(`写入工具日志失败: ${toolName}`, { error: error.message });
121
116
  }
@@ -130,15 +125,15 @@ function cleanOldLogs(logs) {
130
125
  const lines = logs.split('\n');
131
126
  const now = Date.now();
132
127
  const retentionMs = LOG_RETENTION_HOURS * 60 * 60 * 1000;
133
-
128
+
134
129
  const validLines = [];
135
-
130
+
136
131
  for (const line of lines) {
137
132
  if (!line.trim()) {
138
133
  validLines.push(line);
139
134
  continue;
140
135
  }
141
-
136
+
142
137
  // 提取时间戳
143
138
  const timestampMatch = line.match(/^\[([^\]]+)\]/);
144
139
  if (timestampMatch) {
@@ -156,7 +151,7 @@ function cleanOldLogs(logs) {
156
151
  validLines.push(line);
157
152
  }
158
153
  }
159
-
154
+
160
155
  return validLines.join('\n');
161
156
  }
162
157
 
@@ -168,7 +163,7 @@ function cleanOldLogs(logs) {
168
163
  function keepRecentLogs(logs) {
169
164
  const lines = logs.split('\n');
170
165
  const recentLines = lines.slice(-MAX_LOG_LINES);
171
- return recentLines.join('\n') + '\n';
166
+ return `${recentLines.join('\n')}\n`;
172
167
  }
173
168
 
174
169
  /**
@@ -176,27 +171,27 @@ function keepRecentLogs(logs) {
176
171
  */
177
172
  export function startLogCleanupTask() {
178
173
  setInterval(async () => {
179
- const toolboxDir = path.join(os.homedir(), '.prompt-manager', 'toolbox');
180
-
181
- if (!await pathExists(toolboxDir)) {
174
+ const toolboxDir = config.getToolboxDir();
175
+
176
+ if (!(await pathExists(toolboxDir))) {
182
177
  return;
183
178
  }
184
-
179
+
185
180
  try {
186
181
  const entries = await fs.readdir(toolboxDir, { withFileTypes: true });
187
-
182
+
188
183
  for (const entry of entries) {
189
184
  if (!entry.isDirectory()) {
190
185
  continue;
191
186
  }
192
-
187
+
193
188
  const toolName = entry.name;
194
189
  const logFilePath = path.join(toolboxDir, toolName, 'run.log');
195
-
190
+
196
191
  if (await pathExists(logFilePath)) {
197
192
  const logs = await fs.readFile(logFilePath, 'utf-8');
198
193
  const cleanedLogs = cleanOldLogs(logs);
199
-
194
+
200
195
  if (cleanedLogs.length < logs.length) {
201
196
  await fs.writeFile(logFilePath, cleanedLogs, 'utf-8');
202
197
  logger.debug(`清理工具日志: ${toolName}`);
@@ -207,7 +202,7 @@ export function startLogCleanupTask() {
207
202
  logger.error('定期清理日志失败', { error: error.message });
208
203
  }
209
204
  }, CLEANUP_INTERVAL);
210
-
205
+
211
206
  logger.info('工具日志清理任务已启动');
212
207
  }
213
208
 
@@ -220,4 +215,3 @@ export async function flushAllLogQueues() {
220
215
  await flushLogQueue(toolName);
221
216
  }
222
217
  }
223
-
@@ -1,20 +1,19 @@
1
1
  /**
2
2
  * 统一工具管理处理器
3
- *
3
+ *
4
4
  * 职责:
5
5
  * 1. 实现 mcp__promptmanager__toolm 工具的处理逻辑
6
6
  * 2. 路由到不同的模式处理器
7
7
  * 3. 统一错误处理
8
8
  */
9
9
 
10
- import { logger } from '../utils/logger.js';
11
10
  import { toolLoaderService } from './tool-loader.service.js';
12
11
  import { parseToolYaml } from './tool-yaml-parser.service.js';
13
- import {
14
- handleManualMode,
15
- handleExecuteMode,
16
- handleConfigureMode,
17
- handleLogMode
12
+ import {
13
+ handleManualMode,
14
+ handleExecuteMode,
15
+ handleConfigureMode,
16
+ handleLogMode
18
17
  } from './tool-mode-handlers.service.js';
19
18
 
20
19
  /**
@@ -24,7 +23,8 @@ import {
24
23
  */
25
24
  export async function handleToolM(args) {
26
25
  const { yaml: yamlInput } = args;
27
-
26
+
27
+ /* eslint-disable no-useless-catch */
28
28
  try {
29
29
  // 初始化工具加载器(如果尚未初始化)
30
30
  if (!toolLoaderService.initialized) {
@@ -33,10 +33,13 @@ export async function handleToolM(args) {
33
33
 
34
34
  // 解析 YAML 配置
35
35
  const { toolName, mode, parameters } = parseToolYaml(yamlInput);
36
-
36
+
37
37
  // 检查工具是否存在
38
38
  if (!toolLoaderService.hasTool(toolName)) {
39
- const availableTools = toolLoaderService.getAllTools().map(t => t.name).join(', ');
39
+ const availableTools = toolLoaderService
40
+ .getAllTools()
41
+ .map(t => t.name)
42
+ .join(', ');
40
43
  throw new Error(`工具 '${toolName}' 不存在\n可用工具: ${availableTools}`);
41
44
  }
42
45
 
@@ -44,20 +47,19 @@ export async function handleToolM(args) {
44
47
  switch (mode) {
45
48
  case 'manual':
46
49
  return handleManualMode(toolName);
47
-
50
+
48
51
  case 'execute':
49
52
  return await handleExecuteMode(toolName, parameters);
50
-
53
+
51
54
  case 'configure':
52
55
  return await handleConfigureMode(toolName, parameters);
53
-
56
+
54
57
  case 'log':
55
58
  return await handleLogMode(toolName, parameters);
56
-
59
+
57
60
  default:
58
61
  throw new Error(`不支持的模式: ${mode}\n支持的模式: manual, execute, configure, log`);
59
62
  }
60
-
61
63
  } catch (error) {
62
64
  // 错误已经在 parseToolYaml 中处理,直接抛出
63
65
  throw error;