@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
@@ -7,82 +7,88 @@ import { util } from '../utils/util.js';
7
7
  export async function handleGetPrompt(args) {
8
8
  // 注意:这里为了兼容性,我们同时支持prompt_id和name参数
9
9
  const promptId = args.prompt_id || args.name;
10
-
10
+
11
11
  if (!promptId) {
12
- throw new Error("缺少必需参数: prompt_id");
12
+ throw new Error('缺少必需参数: prompt_id');
13
13
  }
14
-
14
+
15
15
  const promptManager = await util.getPromptManager();
16
16
  const prompt = promptManager.getPrompt(promptId);
17
17
  if (!prompt) {
18
18
  throw new Error(`未找到ID为 "${promptId}" 的prompt`);
19
19
  }
20
-
20
+
21
21
  // 返回完整的prompt信息
22
22
  const promptInfo = {
23
- id: prompt.uniqueId, // 使用基于文件路径的唯一ID
23
+ id: prompt.uniqueId, // 使用基于文件路径的唯一ID
24
24
  name: prompt.name,
25
25
  description: prompt.description || `Prompt: ${prompt.name}`,
26
26
  messages: prompt.messages || [],
27
27
  arguments: prompt.arguments || [],
28
- filePath: prompt.relativePath, // 添加文件路径信息
28
+ filePath: prompt.relativePath // 添加文件路径信息
29
29
  };
30
30
 
31
31
  if (config.getLogLevel() === 'debug') {
32
32
  promptInfo.metadata = {
33
33
  uniqueId: prompt.uniqueId,
34
34
  fileName: prompt.fileName,
35
- fullPath: prompt.filePath,
35
+ fullPath: prompt.filePath
36
36
  };
37
37
  }
38
38
 
39
- return convertToText({
40
- success: true,
41
- prompt: promptInfo
42
- }, 'detail');
39
+ return convertToText(
40
+ {
41
+ success: true,
42
+ prompt: promptInfo
43
+ },
44
+ 'detail'
45
+ );
43
46
  }
44
47
 
45
48
  // 处理 search_prompts 工具调用
46
49
  export async function handleSearchPrompts(args) {
47
50
  // 注意:这里为了兼容性,我们同时支持title和name参数
48
51
  const searchTerm = args.title || args.name;
49
-
52
+
50
53
  const logLevel = config.getLogLevel();
51
54
  const promptManager = await util.getPromptManager();
52
- let allPrompts = (await promptManager.loadPrompts()).prompts || [];
55
+ const allPrompts = (await promptManager.loadPrompts()).prompts || [];
53
56
 
54
57
  // 如果搜索词为空,则返回所有提示词
55
58
  if (!searchTerm) {
56
- let simplifiedPrompts = formatResults(allPrompts);
59
+ const simplifiedPrompts = formatResults(allPrompts);
57
60
 
58
- return convertToText({
59
- success: true,
60
- query: searchTerm || '',
61
- count: simplifiedPrompts.length,
62
- results: simplifiedPrompts
63
- }, 'list');
61
+ return convertToText(
62
+ {
63
+ success: true,
64
+ query: searchTerm || '',
65
+ count: simplifiedPrompts.length,
66
+ results: simplifiedPrompts
67
+ },
68
+ 'list'
69
+ );
64
70
  }
65
-
71
+
66
72
  // 实现相似度匹配算法
67
- const searchResults = allPrompts.map(prompt => {
68
- prompt.description = prompt.description || `Prompt: ${prompt.name}`;
69
- prompt.arguments = prompt.arguments || [];
70
- prompt.hasArguments = prompt.arguments && prompt.arguments.length > 0;
71
- return {
72
- prompt: prompt,
73
- score: util.calculateSimilarityScore(searchTerm, prompt),
74
- };
75
- })
76
- .filter(result => result.score > 0) // 只返回有匹配的结果
77
- .sort((a, b) => b.score - a.score); // 按相似度得分降序排列
78
-
73
+ const searchResults = allPrompts
74
+ .map(prompt => {
75
+ prompt.description = prompt.description || `Prompt: ${prompt.name}`;
76
+ prompt.arguments = prompt.arguments || [];
77
+ prompt.hasArguments = prompt.arguments && prompt.arguments.length > 0;
78
+ return {
79
+ prompt,
80
+ score: util.calculateSimilarityScore(searchTerm, prompt)
81
+ };
82
+ })
83
+ .filter(result => result.score > 0) // 只返回有匹配的结果
84
+ .sort((a, b) => b.score - a.score); // 按相似度得分降序排列
79
85
 
80
- let result = {
86
+ const result = {
81
87
  success: true,
82
88
  query: searchTerm || '',
83
89
  count: searchResults.length,
84
- results: formatResults(searchResults),
85
- }
90
+ results: formatResults(searchResults)
91
+ };
86
92
 
87
93
  if (logLevel === 'debug') {
88
94
  result.debug = {
@@ -90,9 +96,9 @@ export async function handleSearchPrompts(args) {
90
96
  id: result.prompt.id,
91
97
  name: result.prompt.name,
92
98
  score: result.score,
93
- fullPath: result.prompt.filePath,
99
+ fullPath: result.prompt.filePath
94
100
  }))
95
- }
101
+ };
96
102
  }
97
103
 
98
104
  return convertToText(result, 'list');
@@ -101,21 +107,25 @@ export async function handleSearchPrompts(args) {
101
107
  /**
102
108
  * 处理 reload_prompts 工具调用
103
109
  */
104
- export async function handleReloadPrompts(args) {
110
+ export async function handleReloadPrompts(_args) {
105
111
  logger.info('重新加载prompts...');
106
-
112
+
107
113
  const promptManager = await util.getPromptManager();
108
114
  const result = await promptManager.reloadPrompts();
109
-
115
+
110
116
  return {
111
117
  content: [
112
118
  {
113
- type: "text",
114
- text: JSON.stringify({
115
- success: true,
116
- message: `重新加载完成: 成功 ${result.success} 个, 失败 ${result.errorCount} 个`,
117
- result: formatResults(result.prompts)
118
- }, null, 2)
119
+ type: 'text',
120
+ text: JSON.stringify(
121
+ {
122
+ success: true,
123
+ message: `重新加载完成: 成功 ${result.success} 个, 失败 ${result.errorCount} 个`,
124
+ result: formatResults(result.prompts)
125
+ },
126
+ null,
127
+ 2
128
+ )
119
129
  }
120
130
  ]
121
131
  };
@@ -123,8 +133,8 @@ export async function handleReloadPrompts(args) {
123
133
 
124
134
  /**
125
135
  * 格式化搜索结果
126
- * @param {*} results
127
- * @returns
136
+ * @param {*} results
137
+ * @returns
128
138
  */
129
139
  function formatResults(results = []) {
130
140
  if (!Array.isArray(results)) return [];
@@ -151,23 +161,23 @@ function formatResults(results = []) {
151
161
 
152
162
  /**
153
163
  * 处理列表格式输出
154
- * @param {*} result
155
- * @returns
164
+ * @param {*} result
165
+ * @returns
156
166
  */
157
167
  function formatListOutput(result) {
158
168
  // 生成当前时间戳
159
169
  const now = new Date();
160
170
  const formattedDate = `${now.getFullYear()}/${(now.getMonth() + 1).toString().padStart(2, '0')}/${now.getDate().toString().padStart(2, '0')} ${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}`;
161
-
171
+
162
172
  // 构建新的输出格式
163
- let output = "";
164
- output += "[PROMPT_HEADER_AREA]\n";
165
- output += "🎭 **PromptManager 提示词清单**\n";
173
+ let output = '';
174
+ output += '[PROMPT_HEADER_AREA]\n';
175
+ output += '🎭 **PromptManager 提示词清单**\n';
166
176
  output += `📅 ${formattedDate}\n\n`;
167
- output += "--------------------------------------------------\n";
168
- output += "[PROMPT_LIST_AREA]\n\n";
177
+ output += '--------------------------------------------------\n';
178
+ output += '[PROMPT_LIST_AREA]\n\n';
169
179
  output += `📦 **提示词列表** (${result.count}个)\n`;
170
-
180
+
171
181
  // 添加提示词列表
172
182
  if (result.results && Array.isArray(result.results) && result.results.length > 0) {
173
183
  result.results.forEach(prompt => {
@@ -175,75 +185,71 @@ function formatListOutput(result) {
175
185
  output += ` - ${prompt.description}\n`;
176
186
  });
177
187
  } else {
178
- output += "(无提示词)\n";
188
+ output += '(无提示词)\n';
179
189
  }
180
-
181
- output += "\n--------------------------------------------------\n";
182
- output += "[STATE_AREA]\n";
183
- output += "📍 **当前状态**:prompts_completed\n";
184
-
190
+
191
+ output += '\n--------------------------------------------------\n';
192
+ output += '[STATE_AREA]\n';
193
+ output += '📍 **当前状态**:prompts_completed\n';
194
+
185
195
  // 返回格式化文本
186
196
  return output;
187
197
  }
188
198
 
189
199
  /**
190
200
  * 处理详情格式输出
191
- * @param {*} result
201
+ * @param {*} result
192
202
  * @returns string
193
203
  */
194
204
  function formatDetailOutput(result) {
195
205
  const prompt = result.prompt;
196
-
197
- // 生成当前时间戳
198
- const now = new Date();
199
- const formattedDate = `${now.getFullYear()}/${(now.getMonth() + 1).toString().padStart(2, '0')}/${now.getDate().toString().padStart(2, '0')} ${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}`;
200
-
206
+
201
207
  // 构建新的输出格式
202
- let output = "";
203
- output += "--------------------------------------------------\n";
204
- output += "[PROMPT_HEADER_AREA]\n";
208
+ let output = '';
209
+ output += '--------------------------------------------------\n';
210
+ output += '[PROMPT_HEADER_AREA]\n';
205
211
  output += `- id: ${prompt.id}\n`;
206
212
  output += `- name: ${prompt.name}\n`;
207
213
  output += `- description: ${prompt.description}\n`;
208
214
  output += `- filepath: ${prompt.filePath}\n\n`;
209
- output += "--------------------------------------------------\n";
210
- output += "[PROMPT_PARAMS_AREA]\n";
211
-
215
+ output += '--------------------------------------------------\n';
216
+ output += '[PROMPT_PARAMS_AREA]\n';
217
+
212
218
  // 添加参数信息
213
219
  if (prompt.arguments && Array.isArray(prompt.arguments) && prompt.arguments.length > 0) {
214
220
  prompt.arguments.forEach(param => {
215
- const requiredText = param.required ? "必填" : "非必填";
221
+ const requiredText = param.required ? '必填' : '非必填';
216
222
  output += `- ${param.name}: ${param.type}; ${requiredText}; ${param.description}\n`;
217
223
  });
218
224
  } else {
219
- output += "(无参数)\n";
225
+ output += '(无参数)\n';
220
226
  }
221
-
222
- output += "\n--------------------------------------------------\n";
223
- output += "[PROMPT_CONTENT_AREA]\n";
224
-
227
+
228
+ output += '\n--------------------------------------------------\n';
229
+ output += '[PROMPT_CONTENT_AREA]\n';
230
+
225
231
  // 添加消息内容
226
232
  if (prompt.messages && Array.isArray(prompt.messages)) {
227
- const userMessages = prompt.messages.filter(msg => msg.role !== "");
233
+ const userMessages = prompt.messages.filter(msg => msg.role !== '');
228
234
  if (userMessages.length > 0 && userMessages[0].content && userMessages[0].content.text) {
229
- output += userMessages[0].content.text + "\n";
235
+ output += `${userMessages[0].content.text}\n`;
230
236
  }
231
237
  }
232
-
233
- output += "\n[STATE_AREA]\n";
234
- output += "📍 **当前状态**:prompt_loaded\n";
235
-
238
+
239
+ output += '\n[STATE_AREA]\n';
240
+ output += '📍 **当前状态**:prompt_loaded\n';
241
+
236
242
  return output;
237
243
  }
238
244
 
239
245
  /**
240
246
  * 将对象转换为格式化的text类型输出
241
- * @param {*} result
247
+ * @param {*} result
242
248
  * @param {string} format - 输出格式类型: 'list' 或 'detail'
243
- * @returns
249
+ * @returns
244
250
  */
245
251
  function convertToText(result, format) {
246
- let ret = ""
252
+ let ret = '';
247
253
  switch (format) {
248
254
  case 'list':
249
255
  ret = formatListOutput(result);
@@ -252,12 +258,12 @@ function convertToText(result, format) {
252
258
  ret = formatDetailOutput(result);
253
259
  break;
254
260
  default:
255
- ret =JSON.stringify(result, null, 2);
261
+ ret = JSON.stringify(result, null, 2);
256
262
  }
257
263
  return {
258
264
  content: [
259
265
  {
260
- type: "text",
266
+ type: 'text',
261
267
  text: ret
262
268
  }
263
269
  ]
@@ -272,7 +278,7 @@ export async function handlePrompts(args) {
272
278
  const { action, query } = args;
273
279
 
274
280
  if (!action) {
275
- throw new Error("缺少必需参数: action (search 或 get)");
281
+ throw new Error('缺少必需参数: action (search 或 get)');
276
282
  }
277
283
 
278
284
  switch (action) {
@@ -281,7 +287,7 @@ export async function handlePrompts(args) {
281
287
 
282
288
  case 'get':
283
289
  if (!query) {
284
- throw new Error("get操作需要提供query参数指定提示词ID或名称");
290
+ throw new Error('get操作需要提供query参数指定提示词ID或名称');
285
291
  }
286
292
  return handleGetPrompt({ prompt_id: query });
287
293
 
@@ -1,40 +1,40 @@
1
1
  import { config } from '../utils/config.js';
2
2
 
3
3
  /**
4
- * 管理员API中间件
5
- * @param {*} req
6
- * @param {*} res
7
- * @param {*} next
8
- * @returns
9
- */
4
+ * 管理员API中间件
5
+ * @param {*} req
6
+ * @param {*} res
7
+ * @param {*} next
8
+ * @returns
9
+ */
10
10
  export function adminAuthMiddleware(req, res, next) {
11
- // 检查是否启用了管理员功能
12
- if (!config.adminEnable) {
13
- return res.status(404).json({ error: 'Admin功能未启用' });
14
- }
11
+ // 检查是否启用了管理员功能
12
+ if (!config.adminEnable) {
13
+ return res.status(404).json({ error: 'Admin功能未启用' });
14
+ }
15
15
 
16
- // 如果不需要认证,直接通过
17
- if (!config.adminRequireAuth) {
18
- next();
19
- return;
20
- }
16
+ // 如果不需要认证,直接通过
17
+ if (!config.adminRequireAuth) {
18
+ next();
19
+ return;
20
+ }
21
21
 
22
- // 检查Authorization请求头是否存在且格式正确
23
- const authHeader = req.headers.authorization;
24
- if (!authHeader || !authHeader.startsWith('Bearer ')) {
25
- return res.status(401).json({ error: '未提供认证令牌' });
26
- }
22
+ // 检查Authorization请求头是否存在且格式正确
23
+ const authHeader = req.headers.authorization;
24
+ if (!authHeader || !authHeader.startsWith('Bearer ')) {
25
+ return res.status(401).json({ error: '未提供认证令牌' });
26
+ }
27
27
 
28
- // 提取Bearer token
29
- const token = authHeader.substring(7);
28
+ // 提取Bearer token
29
+ const token = authHeader.substring(7);
30
30
 
31
- // 验证令牌是否在配置的管理员列表中
32
- const admin = config.admins.find(a => a.token === token);
33
- if (!admin) {
34
- return res.status(401).json({ error: '无效的认证令牌' });
35
- }
31
+ // 验证令牌是否在配置的管理员列表中
32
+ const admin = config.admins.find(a => a.token === token);
33
+ if (!admin) {
34
+ return res.status(401).json({ error: '无效的认证令牌' });
35
+ }
36
36
 
37
- // 将管理员信息附加到请求对象,供后续中间件使用
38
- req.admin = admin;
39
- next();
40
- }
37
+ // 将管理员信息附加到请求对象,供后续中间件使用
38
+ req.admin = admin;
39
+ next();
40
+ }
@@ -4,9 +4,10 @@ import { config } from './utils/config.js';
4
4
  import { logger } from './utils/logger.js';
5
5
  import { util } from './utils/util.js';
6
6
  import { syncSystemTools } from './toolm/tool-sync.service.js';
7
+ import { syncAuthorConfig } from './toolm/author-sync.service.js';
7
8
  import { startLogCleanupTask } from './toolm/tool-logger.service.js';
8
9
  import { webSocketService } from './services/WebSocketService.js';
9
- import { checkPortAvailable, findAvailablePort } from './utils/port-checker.js';
10
+ import { checkPortAvailable } from './utils/port-checker.js';
10
11
 
11
12
  // 动态导入 promptManager,以处理 Electron 打包后的路径问题
12
13
  let promptManager;
@@ -33,34 +34,39 @@ export async function isServerRunning() {
33
34
  if (!serverInstance) {
34
35
  return false;
35
36
  }
36
-
37
+
37
38
  // 实际验证服务器是否在监听
38
- return new Promise((resolve) => {
39
- import('http').then(http => {
40
- // 设置超时以避免长时间等待
41
- const req = http.request({
42
- hostname: 'localhost',
43
- port: config.getPort(),
44
- path: '/health',
45
- method: 'GET',
46
- timeout: 2000
47
- }, (res) => {
48
- resolve(true);
49
- });
50
-
51
- req.on('error', () => {
52
- resolve(false);
53
- });
54
-
55
- req.on('timeout', () => {
56
- req.destroy();
39
+ return new Promise(resolve => {
40
+ import('http')
41
+ .then(http => {
42
+ // 设置超时以避免长时间等待
43
+ const req = http.request(
44
+ {
45
+ hostname: 'localhost',
46
+ port: config.getPort(),
47
+ path: '/health',
48
+ method: 'GET',
49
+ timeout: 2000
50
+ },
51
+ _res => {
52
+ resolve(true);
53
+ }
54
+ );
55
+
56
+ req.on('error', () => {
57
+ resolve(false);
58
+ });
59
+
60
+ req.on('timeout', () => {
61
+ req.destroy();
62
+ resolve(false);
63
+ });
64
+
65
+ req.end();
66
+ })
67
+ .catch(() => {
57
68
  resolve(false);
58
69
  });
59
-
60
- req.end();
61
- }).catch(() => {
62
- resolve(false);
63
- });
64
70
  });
65
71
  }
66
72
 
@@ -86,19 +92,19 @@ export async function startServer(options = {}) {
86
92
  serverStartingPromise = (async () => {
87
93
  try {
88
94
  await _handleConfig(options);
89
-
95
+
90
96
  // 检查端口可用性
91
97
  const port = config.getPort();
92
98
  const isPortAvailable = await checkPortAvailable(port);
93
-
99
+
94
100
  if (!isPortAvailable) {
95
101
  const errorMsg = `端口 ${port} 已被占用,请检查是否有其他服务在使用该端口,或手动指定其他端口`;
96
102
  logger.error(errorMsg);
97
103
  throw new Error(errorMsg);
98
104
  }
99
-
105
+
100
106
  await promptManager.loadPrompts();
101
-
107
+
102
108
  // 加载优化模板和模型
103
109
  try {
104
110
  const { templateManager } = await import('./services/template.service.js');
@@ -115,17 +121,24 @@ export async function startServer(options = {}) {
115
121
  } catch (error) {
116
122
  logger.warn('加载优化模型失败,继续启动服务', { error: error.message });
117
123
  }
118
-
124
+
119
125
  // 同步系统工具到沙箱环境
120
126
  try {
121
127
  await syncSystemTools();
122
128
  } catch (error) {
123
129
  logger.error('同步系统工具失败,继续启动服务', { error: error.message });
124
130
  }
125
-
126
- // MCP 长连接可能长时间空闲(IDE 侧保持会话),若沿用 Node 默认超时(requestTimeout 5 分钟、keepAliveTimeout 5 秒、headersTimeout 60 秒)
127
- // 会导致连接被动关闭。这里将相关超时调高/关闭以避免 IDE 定期断开。
128
- const MCP_LONG_TIMEOUT = 24 * 60 * 60 * 1000; // 24h
131
+
132
+ // 同步作者配置到沙箱环境
133
+ try {
134
+ await syncAuthorConfig();
135
+ } catch (error) {
136
+ logger.error('同步作者配置失败,继续启动服务', { error: error.message });
137
+ }
138
+
139
+ // MCP 长连接可能长时间空闲(IDE 侧保持会话),若沿用 Node 默认超时(requestTimeout 5 分钟、keepAliveTimeout 5 秒、headersTimeout 60 秒)
140
+ // 会导致连接被动关闭。这里将相关超时调高/关闭以避免 IDE 定期断开。
141
+ const MCP_LONG_TIMEOUT = 24 * 60 * 60 * 1000; // 24h
129
142
 
130
143
  // 启动日志清理任务
131
144
  startLogCleanupTask();
@@ -137,7 +150,9 @@ export async function startServer(options = {}) {
137
150
  logger.info(`MCP服务启动成功 http://localhost:${port}/mcp`);
138
151
  if (config.adminEnable) {
139
152
  logger.info(`管理员界面可通过 http://localhost:${port}${config.adminPath} 访问`);
140
- process.stderr.write('\n======================================================================================\n');
153
+ process.stderr.write(
154
+ '\n======================================================================================\n'
155
+ );
141
156
  }
142
157
 
143
158
  // 放宽 HTTP 服务器超时,防止 MCP 流式会话被意外回收
@@ -149,17 +164,17 @@ export async function startServer(options = {}) {
149
164
 
150
165
  // 设置服务器实例
151
166
  serverInstance = server;
152
-
153
- // 启动WebSocket服务,传入 HTTP 服务器端口
167
+
154
168
  try {
155
- await webSocketService.start({ port: config.getPort() });
156
- const wsPort = webSocketService.getPort();
157
- logger.info(`WebSocket服务启动成功,端口: ${wsPort}`);
169
+ // WebSocket服务使用动态端口(端口0,由系统自动分配)
170
+ await webSocketService.start();
171
+ const wsPort = webSocketService.getPort();
172
+ logger.info(`WebSocket服务启动成功,端口: ${wsPort}`);
158
173
  } catch (wsError) {
159
174
  logger.error('WebSocket服务启动失败:', wsError.message);
160
175
  // WebSocket服务失败不影响主服务器运行
161
176
  }
162
-
177
+
163
178
  resolve(server);
164
179
  } catch (error) {
165
180
  logger.error('服务器启动后处理失败:', error.message);
@@ -168,7 +183,7 @@ export async function startServer(options = {}) {
168
183
  }
169
184
  });
170
185
 
171
- server.on('error', (err) => {
186
+ server.on('error', err => {
172
187
  logger.error('服务器启动失败:', err.message);
173
188
  if (err.code === 'EADDRINUSE') {
174
189
  logger.error(`端口 ${port} 已被占用,请检查是否有其他服务在使用该端口`);
@@ -220,7 +235,7 @@ export async function stopServer() {
220
235
  }
221
236
 
222
237
  await new Promise((resolve, reject) => {
223
- serverInstance.close((err) => {
238
+ serverInstance.close(err => {
224
239
  if (err) {
225
240
  logger.error('停止服务器失败:', err.message);
226
241
  reject(err);
@@ -255,7 +270,7 @@ const isDirectRun = (() => {
255
270
  })();
256
271
 
257
272
  if (isDirectRun) {
258
- startServer().catch((error) => {
273
+ startServer().catch(error => {
259
274
  logger.error('服务器启动失败:', error.message);
260
275
  process.exit(1);
261
276
  });