@becrafter/prompt-manager 0.1.21 → 0.1.31

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 +23 -23
  2. package/packages/resources/tools/agent-browser/README.md +640 -0
  3. package/packages/resources/tools/agent-browser/agent-browser.tool.js +1388 -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 +98 -13
  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
@@ -30,18 +30,18 @@ function serveAsarStatic(root) {
30
30
  try {
31
31
  // 动态导入 asar 模块(在 ES 模块环境中)
32
32
  const { default: asar } = await import('@electron/asar');
33
-
33
+
34
34
  // 从 root 中提取 asar 文件路径和相对路径
35
35
  const asarPathMatch = root.match(/^(.*?\.asar)(\/.*)?$/);
36
36
  const asarFilePath = asarPathMatch ? asarPathMatch[1] : root.replace(/\/.*$/, '.asar');
37
37
  const relativePathInAsar = asarPathMatch && asarPathMatch[2] ? asarPathMatch[2].substring(1) : 'web';
38
-
38
+
39
39
  const filePath = path.posix.join(relativePathInAsar, req.path).replace(/^\//, '');
40
40
  const stat = asar.statFile(asarFilePath, filePath);
41
-
41
+
42
42
  if (stat) {
43
43
  const fileContent = asar.extractFile(asarFilePath, filePath);
44
-
44
+
45
45
  // 设置适当的 Content-Type
46
46
  const ext = path.extname(filePath).toLowerCase();
47
47
  const mimeTypes = {
@@ -55,11 +55,11 @@ function serveAsarStatic(root) {
55
55
  '.svg': 'image/svg+xml',
56
56
  '.ico': 'image/x-icon'
57
57
  };
58
-
58
+
59
59
  if (mimeTypes[ext]) {
60
60
  res.setHeader('Content-Type', mimeTypes[ext]);
61
61
  }
62
-
62
+
63
63
  res.send(fileContent);
64
64
  } else {
65
65
  next();
@@ -80,7 +80,6 @@ app.use(cors());
80
80
  app.use(express.json({ limit: '8mb' }));
81
81
  app.use(express.urlencoded({ extended: true }));
82
82
 
83
-
84
83
  // 为管理员界面提供静态文件服务 - 根路径
85
84
  // 检查是否需要使用 ASAR 处理(需要验证 .asar 文件实际上存在)
86
85
  const isAsarPath = adminUiRoot.includes('.asar') && fs.existsSync(adminUiRoot.replace(/\/.*$/, '.asar'));
@@ -100,13 +99,13 @@ async function sendIndexHtml(req, res) {
100
99
  try {
101
100
  // 动态导入 asar 模块(在 ES 模块环境中)
102
101
  const { default: asar } = await import('@electron/asar');
103
-
102
+
104
103
  // 从 adminUiRoot 中提取 asar 文件路径和相对路径
105
104
  const asarPathMatch = adminUiRoot.match(/^(.*?\.asar)(\/.*)?$/);
106
105
  const asarFilePath = asarPathMatch ? asarPathMatch[1] : adminUiRoot.replace(/\/.*$/, '.asar');
107
106
  const relativePathInAsar = asarPathMatch && asarPathMatch[2] ? asarPathMatch[2].substring(1) : 'web';
108
107
  const indexPath = path.posix.join(relativePathInAsar, 'index.html');
109
-
108
+
110
109
  // 检查文件是否存在
111
110
  const stat = asar.statFile(asarFilePath, indexPath);
112
111
  if (stat) {
@@ -129,13 +128,12 @@ async function sendIndexHtml(req, res) {
129
128
  app.get(config.adminPath, sendIndexHtml);
130
129
 
131
130
  // 为管理员界面提供根路径访问(当用户访问 /admin/ 时显示 index.html)
132
- app.get(config.adminPath + '/', sendIndexHtml);
133
-
131
+ app.get(`${config.adminPath}/`, sendIndexHtml);
134
132
 
135
133
  // 健康检查端点
136
134
  app.get('/health', (req, res) => {
137
- res.status(200).json({
138
- status: 'ok',
135
+ res.status(200).json({
136
+ status: 'ok',
139
137
  timestamp: new Date().toISOString(),
140
138
  uptime: process.uptime(),
141
139
  port: config.getPort(),
@@ -155,7 +153,6 @@ app.use('/surge', surgeRouter);
155
153
  // 注册工具API
156
154
  app.use('/tool', toolRouter);
157
155
 
158
-
159
156
  const transports = {};
160
157
  const mcpServers = {}; // 存储每个会话的MCP服务器实例
161
158
  const eventStores = {}; // 存储每个会话的事件存储,以支持会话恢复
@@ -198,7 +195,7 @@ function attachTransportLifecycle(transport) {
198
195
  scheduleSessionCleanup(sid);
199
196
  };
200
197
 
201
- transport.onerror = (error) => {
198
+ transport.onerror = error => {
202
199
  console.error('MCP Transport error:', error);
203
200
  };
204
201
  }
@@ -208,7 +205,7 @@ app.all('/mcp', (req, res) => {
208
205
  try {
209
206
  let transport;
210
207
  const sessionId = req.headers['mcp-session-id'] || '';
211
-
208
+
212
209
  if (sessionId && transports[sessionId]) {
213
210
  const existingTransport = transports[sessionId];
214
211
  // Check if the transport is of the correct type
@@ -218,12 +215,12 @@ app.all('/mcp', (req, res) => {
218
215
  } else {
219
216
  // Transport exists but is not a StreamableHTTPServerTransport (could be SSEServerTransport)
220
217
  res.status(400).json({
221
- jsonrpc: '2.0',
222
- error: {
223
- code: -32000,
224
- message: 'Bad Request: Session exists but uses a different transport protocol'
225
- },
226
- id: null
218
+ jsonrpc: '2.0',
219
+ error: {
220
+ code: -32000,
221
+ message: 'Bad Request: Session exists but uses a different transport protocol'
222
+ },
223
+ id: null
227
224
  });
228
225
  return;
229
226
  }
@@ -231,51 +228,51 @@ app.all('/mcp', (req, res) => {
231
228
  // 断线后尝试恢复会话:为已有会话重新创建 transport
232
229
  const eventStore = eventStores[sessionId];
233
230
  transport = new StreamableHTTPServerTransport({
234
- sessionIdGenerator: () => sessionId,
235
- eventStore,
236
- onsessioninitialized: async () => {
237
- // 已有会话,不需要重新初始化
238
- transports[sessionId] = transport;
239
- // 重新连接已有的 MCP server
240
- try {
241
- const server = mcpServers[sessionId];
242
- server.connect(transport);
243
- console.log(`MCP server reconnected for session ${sessionId}`);
244
- } catch (error) {
245
- console.error('会话恢复失败:', error);
246
- }
231
+ sessionIdGenerator: () => sessionId,
232
+ eventStore,
233
+ onsessioninitialized: async () => {
234
+ // 已有会话,不需要重新初始化
235
+ transports[sessionId] = transport;
236
+ // 重新连接已有的 MCP server
237
+ try {
238
+ const server = mcpServers[sessionId];
239
+ server.connect(transport);
240
+ console.log(`MCP server reconnected for session ${sessionId}`);
241
+ } catch (error) {
242
+ console.error('会话恢复失败:', error);
247
243
  }
244
+ }
248
245
  });
249
246
  // 确保立即记录 transport
250
247
  transports[sessionId] = transport;
251
248
  attachTransportLifecycle(transport);
252
249
  // 若存在延迟清理计时器,先取消
253
250
  if (sessionCleanupTimers[sessionId]) {
254
- clearTimeout(sessionCleanupTimers[sessionId]);
255
- delete sessionCleanupTimers[sessionId];
251
+ clearTimeout(sessionCleanupTimers[sessionId]);
252
+ delete sessionCleanupTimers[sessionId];
256
253
  }
257
254
  } else if (!sessionId && req.method === 'POST' && isInitializeRequest(req.body)) {
258
255
  const eventStore = new InMemoryEventStore();
259
256
 
260
257
  transport = new StreamableHTTPServerTransport({
261
- sessionIdGenerator: () => randomUUID(),
262
- eventStore, // Enable resumability
263
- onsessioninitialized: async sessionId => {
264
- // Store the transport by session ID when session is initialized
265
- console.log(`StreamableHTTP session initialized with ID: ${sessionId}`);
266
- transports[sessionId] = transport;
267
- eventStores[sessionId] = eventStore;
268
-
269
- try {
270
- // 为新会话创建MCP服务器实例(同步等待完成)
271
- const server = await getMcpServer();
272
- mcpServers[sessionId] = server;
273
- server.connect(transport);
274
- console.log(`MCP server connected for session ${sessionId}`);
275
- } catch (error) {
276
- console.error('创建MCP服务器失败:', error);
277
- }
258
+ sessionIdGenerator: () => randomUUID(),
259
+ eventStore, // Enable resumability
260
+ onsessioninitialized: async sessionId => {
261
+ // Store the transport by session ID when session is initialized
262
+ console.log(`StreamableHTTP session initialized with ID: ${sessionId}`);
263
+ transports[sessionId] = transport;
264
+ eventStores[sessionId] = eventStore;
265
+
266
+ try {
267
+ // 为新会话创建MCP服务器实例(同步等待完成)
268
+ const server = await getMcpServer();
269
+ mcpServers[sessionId] = server;
270
+ server.connect(transport);
271
+ console.log(`MCP server connected for session ${sessionId}`);
272
+ } catch (error) {
273
+ console.error('创建MCP服务器失败:', error);
278
274
  }
275
+ }
279
276
  });
280
277
 
281
278
  // 统一注册关闭/错误处理(含延迟清理)
@@ -283,40 +280,40 @@ app.all('/mcp', (req, res) => {
283
280
  } else {
284
281
  // Invalid request - no session ID or not initialization request
285
282
  res.status(400).json({
286
- jsonrpc: '2.0',
287
- error: {
288
- code: -32000,
289
- message: 'Bad Request: No valid session ID provided'
290
- },
291
- id: null
283
+ jsonrpc: '2.0',
284
+ error: {
285
+ code: -32000,
286
+ message: 'Bad Request: No valid session ID provided'
287
+ },
288
+ id: null
292
289
  });
293
290
  return;
294
291
  }
295
-
292
+
296
293
  // Handle the request with the transport
297
294
  transport.handleRequest(req, res, req.body);
298
295
  } catch (error) {
299
- logger.error('Error handling MCP request: ' + error.message);
296
+ logger.error(`Error handling MCP request: ${error.message}`);
300
297
  return res.status(500).json({
301
- jsonrpc: '2.0',
302
- error: {
303
- code: -32603,
304
- message: 'Internal server error'
305
- },
306
- id: null
298
+ jsonrpc: '2.0',
299
+ error: {
300
+ code: -32603,
301
+ message: 'Internal server error'
302
+ },
303
+ id: null
307
304
  });
308
305
  }
309
306
  });
310
307
 
311
308
  // 错误处理中间件
312
- app.use((err, req, res, next) => {
309
+ app.use((err, req, res, _next) => {
313
310
  console.error(`[服务器错误]: ${err.message}`);
314
- res.status(500).send('Internal Server Error')
311
+ res.status(500).send('Internal Server Error');
315
312
  });
316
313
 
317
314
  // 404处理
318
315
  app.use((req, res) => {
319
- res.status(404).send('Not Found')
316
+ res.status(404).send('Not Found');
320
317
  });
321
318
 
322
319
  // 导出清理函数
@@ -333,8 +330,8 @@ export function cleanupMcpSessions() {
333
330
  }
334
331
  delete transports[sessionId];
335
332
  }
336
-
333
+
337
334
  // 注意:mcpServers 对象在 app.js 中不可访问,需要在 server.js 中处理
338
335
  }
339
336
 
340
- export default app;
337
+ export default app;
@@ -0,0 +1,40 @@
1
+ {
2
+ "version": "1.0.0",
3
+ "last_updated": "2026-01-11",
4
+
5
+ "authors": {
6
+ "becrafter": {
7
+ "name": "BeCrafter",
8
+ "github": "https://github.com/BeCrafter",
9
+ "homepage": "https://github.com/BeCrafter",
10
+ "bio": "让AI提示词管理变得简单而强大",
11
+ "featured": true,
12
+ "sort_order": 1,
13
+ "aliases": ["默认", "空", "Prompt Manager", "prompt-manager", "system", "promptmanager"]
14
+ },
15
+
16
+ "luban": {
17
+ "name": "鲁班",
18
+ "github": "https://github.com/Deepractice",
19
+ "homepage": "https://github.com/Deepractice",
20
+ "bio": "Prompt Manager 工具开发大师 | AI Agent 工具集创造者",
21
+ "featured": true,
22
+ "sort_order": 2
23
+ },
24
+
25
+ "nuwa": {
26
+ "name": "女娲",
27
+ "github": "https://github.com/Deepractice",
28
+ "homepage": "https://github.com/Deepractice",
29
+ "bio": "AI角色创造专家 | Prompt Manager 角色系统设计者",
30
+ "featured": true,
31
+ "sort_order": 3
32
+ }
33
+ },
34
+
35
+ "settings": {
36
+ "default_author": "becrafter",
37
+ "cache_avatar_hours": 24,
38
+ "default_avatar_emoji": "👤"
39
+ }
40
+ }
@@ -1,6 +1,6 @@
1
- name: "BigModel"
2
- provider: "BigModel"
3
- model: "glm-4.5-air"
4
- apiEndpoint: "https://open.bigmodel.cn/api/paas/v4/chat/completions"
5
- apiKey: "ba6397b3478a47c79938c98b822a3ced.fGPlm03ACPDDsbmL"
6
- enabled: true
1
+ name: 'BigModel'
2
+ provider: 'BigModel'
3
+ model: 'glm-4.5-air'
4
+ apiEndpoint: 'https://open.bigmodel.cn/api/paas/v4/chat/completions'
5
+ apiKey: 'ba6397b3478a47c79938c98b822a3ced.fGPlm03ACPDDsbmL'
6
+ enabled: true
@@ -44,7 +44,7 @@ providers:
44
44
  custom:
45
45
  name: 自定义
46
46
  description: 自定义 API 端点
47
- defaultModel: ""
48
- defaultEndpoint: ""
49
- website: ""
50
- models: []
47
+ defaultModel: ''
48
+ defaultEndpoint: ''
49
+ website: ''
50
+ models: []
@@ -57,4 +57,4 @@ content:
57
57
 
58
58
  请基于优化需求修改原始提示词(参考上述示例理解,将需求融入提示词中):
59
59
  type: iterate
60
- format: advanced
60
+ format: advanced
@@ -60,4 +60,4 @@ content: |
60
60
  作为[角色名称],你必须遵守上述Rules,按照Workflows执行任务。
61
61
 
62
62
 
63
- 请基于以上模板,优化并扩展以下prompt,确保内容专业、完整且结构清晰,注意不要携带任何引导词或解释,不要使用代码块包围:
63
+ 请基于以上模板,优化并扩展以下prompt,确保内容专业、完整且结构清晰,注意不要携带任何引导词或解释,不要使用代码块包围:
@@ -92,4 +92,4 @@ content: |
92
92
  作为[角色名称],你必须遵守上述Rules,按照Workflows执行任务,并按照[输出格式]输出。
93
93
 
94
94
 
95
- 请基于以上模板,优化并扩展以下prompt,确保内容专业、完整且结构清晰,注意不要携带任何引导词或解释,不要使用代码块包围:
95
+ 请基于以上模板,优化并扩展以下prompt,确保内容专业、完整且结构清晰,注意不要携带任何引导词或解释,不要使用代码块包围:
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Prompt Manager Core Library
3
- *
3
+ *
4
4
  * This is the main entry point for the Prompt Manager core library.
5
5
  * It exports the main server functionality and utility functions.
6
6
  */
@@ -21,13 +21,7 @@ export { promptManager } from './services/manager.js';
21
21
 
22
22
  // Export MCP functionality
23
23
  export { getMcpServer } from './mcp/mcp.server.js';
24
- export {
25
- handleGetPrompt,
26
- handleSearchPrompts,
27
- handleReloadPrompts
28
- } from './mcp/prompt.handler.js';
29
- export { handleSequentialThinking } from './mcp/sequential-thinking.handler.js';
30
- export { handleThinkPlan } from './mcp/think-plan.handler.js';
24
+ export { handleGetPrompt, handleSearchPrompts, handleReloadPrompts } from './mcp/prompt.handler.js';
31
25
  export { handleToolM } from './toolm/index.js';
32
26
 
33
27
  // Export API routes
@@ -36,4 +30,4 @@ export { openRouter } from './api/open.routes.js';
36
30
  export { surgeRouter } from './api/surge.routes.js';
37
31
 
38
32
  // Export middlewares
39
- export { adminAuthMiddleware } from './middlewares/auth.middleware.js';
33
+ export { adminAuthMiddleware } from './middlewares/auth.middleware.js';
@@ -44,7 +44,7 @@ export function patchStreamableHTTPHeartbeat() {
44
44
 
45
45
  const proto = StreamableHTTPServerTransport.prototype;
46
46
 
47
- const wrap = (original) => {
47
+ const wrap = original => {
48
48
  return async function wrapped(...args) {
49
49
  const res = args[1];
50
50
  try {
@@ -69,5 +69,3 @@ export function patchStreamableHTTPHeartbeat() {
69
69
  proto.handlePostRequest = wrap(proto.handlePostRequest);
70
70
  proto.replayEvents = wrap(proto.replayEvents);
71
71
  }
72
-
73
-
@@ -1,149 +1,79 @@
1
1
  import { config } from '../utils/config.js';
2
2
  import { z } from 'zod';
3
3
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
4
- import {
5
- handleGetPrompt,
6
- handleSearchPrompts,
7
- handleReloadPrompts,
8
- handlePrompts
9
- } from './prompt.handler.js';
4
+ import { handlePrompts } from './prompt.handler.js';
10
5
  import { handleToolM } from '../toolm/index.js';
11
- import { handleThinkingToolkit, THINKING_SCENARIOS } from './thinking-toolkit.handler.js';
12
- // import { generateToolmDescription } from '../toolm/tool-description-generator.service.js';
13
6
  import { generateToolmDescription } from '../toolm/tool-description-generator-optimized.service.js';
14
7
  import { toolLoaderService } from '../toolm/tool-loader.service.js';
15
8
 
16
- const sequentialThinkingPayloadSchema = z.object({
17
- thought: z.string().describe('当前思考内容,是顺序思考步骤的主体'),
18
- nextThoughtNeeded: z.boolean().optional().describe('是否继续向下一个思考步骤推进'),
19
- thoughtNumber: z.number().int().min(1).optional().describe('显式指定此次思考的编号'),
20
- totalThoughts: z.number().int().min(1).optional().describe('预计需要的总思考步数'),
21
- isRevision: z.boolean().optional().describe('该思考是否用于修订之前的结果'),
22
- revisesThought: z.number().int().min(1).optional().describe('若为修订,指向被修订的思考编号'),
23
- branchFromThought: z.number().int().min(1).optional().describe('创建分支时,来源的思考编号'),
24
- branchId: z.string().optional().describe('为新的思考分支设置的标识'),
25
- needsMoreThoughts: z.boolean().optional().describe('终点后发现仍需更多思考时标记为 true')
26
- });
27
-
28
- const thinkPlanPayloadSchema = z.object({
29
- thought: z.string().describe('对当前任务的分析、假设或洞见'),
30
- plan: z.string().describe('将任务拆分为可执行步骤的计划文本'),
31
- action: z.string().describe('下一步需要执行的具体行动'),
32
- thoughtNumber: z.string().describe('思考步骤编号,用于追踪整个规划过程'),
33
- sessionId: z.string().optional().describe('可选的会话标识,区分并行任务')
34
- });
35
-
36
- const metaSchema = z.object({
37
- scenario: z.string().describe('思考场景:exploratory(顺序思考)或 execution(思考规划)').optional(),
38
- progressToken: z.any().optional()
39
- }).catchall(z.any());
40
-
41
- const thinkingToolkitPayloadSchema = z.object({
42
- thought: z.string().optional().describe('思考内容(两种场景都依赖)'),
43
- thoughtNumber: z.union([z.string(), z.number()]).optional().describe('思考编号;execution 场景必填,可使用字符串或数字'),
44
- plan: z.string().optional().describe('execution 场景:将任务拆分成可执行步骤'),
45
- action: z.string().optional().describe('execution 场景:下一步可验证的行动'),
46
- sessionId: z.string().optional().describe('execution 场景:可选会话标识'),
47
- nextThoughtNeeded: z.boolean().optional().describe('exploratory 场景:是否继续下一步'),
48
- totalThoughts: z.number().int().min(1).optional().describe('exploratory 场景:预计总步数'),
49
- isRevision: z.boolean().optional().describe('exploratory 场景:是否为修订'),
50
- revisesThought: z.number().int().min(1).optional().describe('exploratory 场景:被修订的编号'),
51
- branchFromThought: z.number().int().min(1).optional().describe('exploratory 场景:分支起点编号'),
52
- branchId: z.string().optional().describe('exploratory 场景:分支 ID'),
53
- needsMoreThoughts: z.boolean().optional().describe('exploratory 场景:终点后仍需继续时标记')
54
- });
55
-
56
- const thinkingToolkitInputSchema = {
57
- scenario: z.enum(
58
- [THINKING_SCENARIOS.EXPLORATORY, THINKING_SCENARIOS.EXECUTION],
59
- {
60
- description: '思考场景:exploratory(顺序思考)或 execution(思考规划)'
61
- }
62
- ).optional(),
63
- payload: thinkingToolkitPayloadSchema.optional().describe('根据场景填写对应字段;缺省或 null 时仅返回说明'),
64
- _meta: metaSchema.optional()
65
- };
66
-
67
9
  class Server {
68
- constructor() {
69
- this.server = new McpServer(
70
- {
71
- name: 'Prompt Management Server',
72
- version: config.getServerVersion()
73
- },
74
- { capabilities: { logging: {} } }
75
- );
76
- }
10
+ constructor() {
11
+ this.server = new McpServer(
12
+ {
13
+ name: 'Prompt Management Server',
14
+ version: config.getServerVersion()
15
+ },
16
+ { capabilities: { logging: {} } }
17
+ );
18
+ }
77
19
 
78
- registerTools(tools) {
79
- for (const tool of tools) {
80
- this.server.registerTool(tool.name,
81
- {
82
- description: tool.description,
83
- inputSchema: tool.inputSchema,
84
- },
85
- tool.handler
86
- );
87
- }
20
+ registerTools(tools) {
21
+ for (const tool of tools) {
22
+ this.server.registerTool(
23
+ tool.name,
24
+ {
25
+ description: tool.description,
26
+ inputSchema: tool.inputSchema
27
+ },
28
+ tool.handler
29
+ );
88
30
  }
31
+ }
89
32
 
90
- getServer() {
91
- return this.server;
92
- }
33
+ getServer() {
34
+ return this.server;
35
+ }
93
36
  }
94
37
 
95
38
  export const getMcpServer = async () => {
96
- const mcpServer = new Server();
97
-
98
- // 确保工具加载器已初始化(用于生成动态描述)
99
- if (!toolLoaderService.initialized) {
100
- try {
101
- await toolLoaderService.initialize();
102
- } catch (error) {
103
- // 如果初始化失败,继续使用默认描述
104
- console.warn('工具加载器初始化失败,使用默认描述:', error.message);
105
- }
39
+ const mcpServer = new Server();
40
+
41
+ // 确保工具加载器已初始化(用于生成动态描述)
42
+ if (!toolLoaderService.initialized) {
43
+ try {
44
+ await toolLoaderService.initialize();
45
+ } catch (error) {
46
+ // 如果初始化失败,继续使用默认描述
47
+ console.warn('工具加载器初始化失败,使用默认描述:', error.message);
106
48
  }
107
-
108
- // 动态生成 toolm 工具的描述
109
- const toolmDescription = generateToolmDescription();
110
-
111
- mcpServer.registerTools([
112
- {
113
- name: 'prompts',
114
- description: `🤖 **提示词助手** - 你的AI提示词管家\n\n【规范名称】promptmanager_prompts\n【调用说明】在提示词中使用 promptmanager_prompts,实际调用时自动映射到 mcp__[server]__action\n\n我可以帮你找到并使用各种专业的提示词,让AI变得更聪明、更专业。\n\n## 我能做什么\n- 🔍 **找提示词** - 告诉我你想要什么功能,我帮你搜索匹配的提示词\n- 📋 **用提示词** - 帮你加载并应用专业的提示词到对话中\n- 📚 **逛提示词库** - 带你浏览所有可用的提示词,了解有什么可以用的\n\n## 在对话中怎么和我说\n\n**想找提示词时可以说:**\n- "帮我找找代码审查相关的提示词"\n- "有什么标题生成的提示词可以用吗?"\n- "我想看看所有可用的提示词"\n\n**想用某个提示词时可以说:**\n- "用代码审查的提示词帮我看看这段代码"\n- "加载标题生成器,我要写文章标题"\n- "用文档生成提示词帮我写API文档"\n\n## 实际使用示例\n\n\`\`\`json\n// 对话中的自然表达:\n// "我想找个代码审查的提示词"\n{"action": "search", "query": "代码审查"}\n\n// "帮我用标题生成器"\n{"action": "get", "query": "examples-prompts-generator-gen_title"}\n\n// "看看有什么提示词可以用"\n{"action": "search"}\n\`\`\`\n\n**提示:** 先搜索找到合适的提示词ID,然后用"get"加载它,就能直接在对话中使用啦!`,
115
- inputSchema: {
116
- action: z.enum(['search', 'get']).describe('操作类型:search(搜索提示词) get(获取提示词详情)'),
117
- query: z.string().optional().describe('搜索关键词(用于search) 或 提示词ID/名称(用于get)'),
118
- },
119
- handler: async (args) => {
120
- return handlePrompts(args);
121
- }
122
- },
123
- {
124
- name: 'toolm',
125
- description: toolmDescription,
126
- inputSchema: {
127
- yaml: z.string().describe('YAML 格式的工具调用配置')
128
- },
129
- handler: async (args) => {
130
- return handleToolM(args);
131
- }
132
- },
133
- // {
134
- // name: 'thinking',
135
- // description: `🧭 **智能思考工具箱**\n\n【规范名称】promptmanager_thinking\n【调用说明】在提示词中使用 promptmanager_thinking,实际调用时自动映射到 mcp__[server]__action\n\n⚠️ **务必先读说明**:每次首次使用某个 scenario 时,先发送仅包含 \`{"scenario":"..."}\` 的请求获取完整描述,确认理解适用场景与参数要求后,再携带 payload 调用。跳过此步骤易导致字段缺失或流程误用。\n\n## 核心特性\n\n- **双模式思考** - 提供顺序思考(exploratory)和思考规划(execution)两种模式\n- **智能引导** - 通过场景参数自动匹配合适的思考策略\n- **结构化流程** - 支持多轮思考追踪和分支管理\n- **错误预防** - 强制预读说明,避免参数配置错误\n- **灵活扩展** - 支持修订、分支和会话管理\n\n## 何时使用 Thinking Toolkit\n\n### 快速决策(IF-THEN 规则):\n- IF 需要探索性思考、诊断问题、发散推理 → 使用 scenario: "exploratory"\n- IF 需要结构化规划、制定执行步骤 → 使用 scenario: "execution"\n- IF 看到 scenario 参数 → 使用 thinking_toolkit 调用\n- IF 不确定场景用法 → 先用仅包含 scenario 的请求查看说明\n\n### 首次使用任何场景\n⚠️ **必须先发送仅包含 scenario 的请求** 阅读场景完整描述\n⚠️ 示例:thinking_toolkit with scenario: "exploratory" (无payload)\n\n## 如何使用 Thinking Toolkit\n\n### 模式 1:查看场景说明(首次使用)\n\n\`\`\`javascript\nmcp_mcp-router_thinking_toolkit({\n scenario: "exploratory"\n})\n\`\`\`\n\n**重要**:每次使用新场景前必须先执行此步骤,了解场景的具体参数要求和使用方法。\n\n### 模式 2:执行顺序思考\n\n\`\`\`javascript\nmcp_mcp-router_thinking_toolkit({\n scenario: "exploratory",\n payload: {\n thought: "分析性能下降的可能原因",\n totalThoughts: 5,\n nextThoughtNeeded: true\n }\n})\n\`\`\`\n\n### 模式 3:执行思考规划\n\n\`\`\`javascript\nmcp_mcp-router_thinking_toolkit({\n scenario: "execution",\n payload: {\n thought: "需要上线新版本",\n plan: "1. 备份 2. 部署 3. 验证",\n action: "先执行备份脚本",\n thoughtNumber: "TP-001"\n }\n})\n\`\`\`\n\n## 关键规则\n\n### ✅ 正确格式\n- 先发送 \`{"scenario": "..."}\` 获取场景说明\n- 根据说明确认参数要求后,再携带 payload 调用\n- scenario 必填:exploratory(顺序思考)或 execution(思考规划)\n- payload 根据场景填写对应字段\n\n### ❌ 常见错误\n- 不要跳过场景说明,直接携带 payload 调用(易导致参数错误)\n- 不要混用不同场景的参数字段\n- 不要在首次使用场景时直接执行 payload\n\n## 支持的思考场景\n\n### Exploratory(顺序思考)\n适合探索、诊断、发散推理场景,支持多轮思考追踪和分支管理。\n\n### Execution(思考规划)\n适合结构化计划制定和行动追踪,按步骤执行任务规划。\n\n更多场景正在开发中...`,
136
- // inputSchema: thinkingToolkitInputSchema,
137
- // handler: async (args) => handleThinkingToolkit(args)
138
- // }
139
- // {
140
- // name: 'reload_prompts',
141
- // description: 'Force a reload of all preset prompts to overwrite the cache.',
142
- // inputSchema: {},
143
- // handler: async (args) => {
144
- // return handleReloadPrompts(args);
145
- // }
146
- // }
147
- ]);
148
- return mcpServer.getServer();
149
- };
49
+ }
50
+
51
+ // 动态生成 toolm 工具的描述
52
+ const toolmDescription = generateToolmDescription();
53
+
54
+ mcpServer.registerTools([
55
+ {
56
+ name: 'prompts',
57
+ description:
58
+ '🤖 **提示词助手** - 你的AI提示词管家\n\n【规范名称】promptmanager_prompts\n【调用说明】在提示词中使用 promptmanager_prompts,实际调用时自动映射到 mcp__[server]__action\n\n我可以帮你找到并使用各种专业的提示词,让AI变得更聪明、更专业。\n\n## 我能做什么\n- 🔍 **找提示词** - 告诉我你想要什么功能,我帮你搜索匹配的提示词\n- 📋 **用提示词** - 帮你加载并应用专业的提示词到对话中\n- 📚 **逛提示词库** - 带你浏览所有可用的提示词,了解有什么可以用的\n\n## 在对话中怎么和我说\n\n**想找提示词时可以说:**\n- "帮我找找代码审查相关的提示词"\n- "有什么标题生成的提示词可以用吗?"\n- "我想看看所有可用的提示词"\n\n**想用某个提示词时可以说:**\n- "用代码审查的提示词帮我看看这段代码"\n- "加载标题生成器,我要写文章标题"\n- "用文档生成提示词帮我写API文档"\n\n## 实际使用示例\n\n```json\n// 对话中的自然表达:\n// "我想找个代码审查的提示词"\n{"action": "search", "query": "代码审查"}\n\n// "帮我用标题生成器"\n{"action": "get", "query": "examples-prompts-generator-gen_title"}\n\n// "看看有什么提示词可以用"\n{"action": "search"}\n```\n\n**提示:** 先搜索找到合适的提示词ID,然后用"get"加载它,就能直接在对话中使用啦!',
59
+ inputSchema: {
60
+ action: z.enum(['search', 'get']).describe('操作类型:search(搜索提示词) 或 get(获取提示词详情)'),
61
+ query: z.string().optional().describe('搜索关键词(用于search) 提示词ID/名称(用于get)')
62
+ },
63
+ handler: async args => {
64
+ return handlePrompts(args);
65
+ }
66
+ },
67
+ {
68
+ name: 'toolm',
69
+ description: toolmDescription,
70
+ inputSchema: {
71
+ yaml: z.string().describe('YAML 格式的工具调用配置')
72
+ },
73
+ handler: async args => {
74
+ return handleToolM(args);
75
+ }
76
+ }
77
+ ]);
78
+ return mcpServer.getServer();
79
+ };