@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.
- package/package.json +31 -24
- package/packages/resources/tools/agent-browser/README.md +640 -0
- package/packages/resources/tools/agent-browser/agent-browser.tool.js +1389 -0
- package/packages/resources/tools/thinking/README.md +324 -0
- package/packages/resources/tools/thinking/thinking.tool.js +911 -0
- package/packages/server/README.md +3 -4
- package/packages/server/api/admin.routes.js +668 -664
- package/packages/server/api/open.routes.js +68 -67
- package/packages/server/api/surge.routes.js +5 -6
- package/packages/server/api/tool.routes.js +70 -71
- package/packages/server/app.js +70 -73
- package/packages/server/configs/authors.json +40 -0
- package/packages/server/configs/models/built-in/bigmodel.yaml +6 -6
- package/packages/server/configs/models/providers.yaml +4 -4
- package/packages/server/configs/templates/built-in/general-iteration.yaml +1 -1
- package/packages/server/configs/templates/built-in/general-optimize.yaml +1 -1
- package/packages/server/configs/templates/built-in/output-format-optimize.yaml +1 -1
- package/packages/server/index.js +3 -9
- package/packages/server/mcp/heartbeat-patch.js +1 -3
- package/packages/server/mcp/mcp.server.js +64 -134
- package/packages/server/mcp/prompt.handler.js +101 -95
- package/packages/server/middlewares/auth.middleware.js +31 -31
- package/packages/server/server.js +60 -45
- package/packages/server/services/TerminalService.js +156 -70
- package/packages/server/services/WebSocketService.js +35 -34
- package/packages/server/services/author-config.service.js +199 -0
- package/packages/server/services/manager.js +66 -60
- package/packages/server/services/model.service.js +5 -9
- package/packages/server/services/optimization.service.js +25 -22
- package/packages/server/services/template.service.js +3 -8
- package/packages/server/toolm/author-sync.service.js +97 -0
- package/packages/server/toolm/index.js +1 -2
- package/packages/server/toolm/package-installer.service.js +47 -50
- package/packages/server/toolm/tool-context.service.js +64 -62
- package/packages/server/toolm/tool-dependency.service.js +28 -30
- package/packages/server/toolm/tool-description-generator-optimized.service.js +55 -55
- package/packages/server/toolm/tool-description-generator.service.js +20 -23
- package/packages/server/toolm/tool-environment.service.js +45 -44
- package/packages/server/toolm/tool-execution.service.js +49 -48
- package/packages/server/toolm/tool-loader.service.js +13 -18
- package/packages/server/toolm/tool-logger.service.js +33 -39
- package/packages/server/toolm/tool-manager.handler.js +17 -15
- package/packages/server/toolm/tool-manual-generator.service.js +107 -87
- package/packages/server/toolm/tool-mode-handlers.service.js +52 -59
- package/packages/server/toolm/tool-storage.service.js +11 -12
- package/packages/server/toolm/tool-sync.service.js +36 -39
- package/packages/server/toolm/tool-utils.js +0 -1
- package/packages/server/toolm/tool-yaml-parser.service.js +12 -11
- package/packages/server/toolm/validate-system.js +56 -84
- package/packages/server/utils/config.js +97 -12
- package/packages/server/utils/logger.js +1 -1
- package/packages/server/utils/port-checker.js +8 -8
- package/packages/server/utils/util.js +470 -467
- package/packages/resources/tools/cognitive-thinking/README.md +0 -284
- package/packages/resources/tools/cognitive-thinking/cognitive-thinking.tool.js +0 -837
- package/packages/server/mcp/sequential-thinking.handler.js +0 -318
- package/packages/server/mcp/think-plan.handler.js +0 -274
- package/packages/server/mcp/thinking-toolkit.handler.js +0 -380
- package/packages/web/0.d1c5a72339dfc32ad86a.js +0 -1
- package/packages/web/112.8807b976372b2b0541a8.js +0 -1
- package/packages/web/130.584c7e365da413f5d9be.js +0 -1
- package/packages/web/142.72c985bc29720f975cca.js +0 -1
- package/packages/web/165.a05fc53bf84d18db36b8.js +0 -2
- package/packages/web/165.a05fc53bf84d18db36b8.js.LICENSE.txt +0 -9
- package/packages/web/203.724ab9f717b80554c397.js +0 -1
- package/packages/web/241.bf941d4f02866795f64a.js +0 -1
- package/packages/web/249.54cfb224af63f5f5ec55.js +0 -1
- package/packages/web/291.6df35042f8f296fca7cd.js +0 -1
- package/packages/web/319.2fab900a31b29873f666.js +0 -1
- package/packages/web/32.c78d866281995ec33a7b.js +0 -1
- package/packages/web/325.9ca297d0f73f38468ce9.js +0 -1
- package/packages/web/366.2f9b48fdbf8eee039e57.js +0 -1
- package/packages/web/378.6be08c612cd5a3ef97dc.js +0 -1
- package/packages/web/393.7a2f817515c5e90623d7.js +0 -1
- package/packages/web/412.062df5f732d5ba203415.js +0 -1
- package/packages/web/426.08656fef4918b3fb19ad.js +0 -1
- package/packages/web/465.2be8018327130a3bd798.js +0 -1
- package/packages/web/48.8ca96fc93667a715e67a.js +0 -1
- package/packages/web/480.44c1f1a2927486ac3d4f.js +0 -1
- package/packages/web/489.e041a8d0db15dc96d607.js +0 -1
- package/packages/web/490.9ffb26c907de020d671b.js +0 -1
- package/packages/web/492.58781369e348d91fc06a.js +0 -1
- package/packages/web/495.ed63e99791a87167c6b3.js +0 -1
- package/packages/web/510.4cc07ab7d30d5c1cd17f.js +0 -1
- package/packages/web/543.3af155ed4fa237664308.js +0 -1
- package/packages/web/567.f04ab60f8e2c2fb0745a.js +0 -1
- package/packages/web/592.f3ad085fa9c1849daa06.js +0 -1
- package/packages/web/616.b03fb801b3433b17750f.js +0 -1
- package/packages/web/617.d88def54921d2c4dc44c.js +0 -1
- package/packages/web/641.d30787d674f548928261.js +0 -1
- package/packages/web/672.5269c8399fa42a5af95d.js +0 -1
- package/packages/web/731.97cab92b71811c502bda.js +0 -1
- package/packages/web/746.3947c6f0235407e420fb.js +0 -1
- package/packages/web/756.a53233b3f3913900d5ac.js +0 -1
- package/packages/web/77.68801af593a28a631fbf.js +0 -1
- package/packages/web/802.53b2bff3cf2a69f7b80c.js +0 -1
- package/packages/web/815.b6dfab82265f56c7e046.js +0 -1
- package/packages/web/821.f5a13e5c735aac244eb9.js +0 -1
- package/packages/web/846.b9bf97d5f559270675ce.js +0 -1
- package/packages/web/869.7c10403f500e6201407f.js +0 -1
- package/packages/web/885.135050364f99e6924fb5.js +0 -1
- package/packages/web/901.fd5aeb9df630609a2b43.js +0 -1
- package/packages/web/928.f67e590de3caa4daa3ae.js +0 -1
- package/packages/web/955.d833403521ba4dd567ee.js +0 -1
- package/packages/web/981.a45cb745cf424044c8c8.js +0 -1
- package/packages/web/992.645320b60c74c8787482.js +0 -1
- package/packages/web/996.ed9a963dc9e7439eca9a.js +0 -1
- package/packages/web/css/codemirror-theme_xq-light.css +0 -43
- package/packages/web/css/codemirror.css +0 -344
- package/packages/web/css/main.196f434e6a88cd448158.css +0 -7278
- package/packages/web/css/terminal-fix.css +0 -571
- package/packages/web/index.html +0 -3
- package/packages/web/main.dceff50c7307dda04873.js +0 -2
- package/packages/web/main.dceff50c7307dda04873.js.LICENSE.txt +0 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
3
|
* 工具系统全面验证脚本
|
|
4
|
-
*
|
|
4
|
+
*
|
|
5
5
|
* 验证内容:
|
|
6
6
|
* 1. 目录结构是否完整
|
|
7
7
|
* 2. 文件是否存在且可读
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
|
|
13
13
|
import fs from 'fs-extra';
|
|
14
14
|
import path from 'path';
|
|
15
|
-
import os from 'os';
|
|
16
15
|
import { fileURLToPath } from 'url';
|
|
17
16
|
import { pathExists } from './tool-utils.js';
|
|
17
|
+
import { config } from '../utils/config.js';
|
|
18
18
|
|
|
19
19
|
const __filename = fileURLToPath(import.meta.url);
|
|
20
20
|
const __dirname = path.dirname(__filename);
|
|
@@ -53,7 +53,6 @@ function section(title) {
|
|
|
53
53
|
log(`\n${'='.repeat(60)}`, 'blue');
|
|
54
54
|
log(` ${title}`, 'bright');
|
|
55
55
|
log('='.repeat(60), 'blue');
|
|
56
|
-
console.log();
|
|
57
56
|
}
|
|
58
57
|
|
|
59
58
|
// 验证结果收集
|
|
@@ -65,32 +64,6 @@ const results = {
|
|
|
65
64
|
errors: []
|
|
66
65
|
};
|
|
67
66
|
|
|
68
|
-
function check(description, test) {
|
|
69
|
-
results.total++;
|
|
70
|
-
try {
|
|
71
|
-
const result = test();
|
|
72
|
-
if (result === true || result === undefined) {
|
|
73
|
-
success(description);
|
|
74
|
-
results.passed++;
|
|
75
|
-
return true;
|
|
76
|
-
} else if (result === 'warning') {
|
|
77
|
-
warning(description);
|
|
78
|
-
results.warnings++;
|
|
79
|
-
return 'warning';
|
|
80
|
-
} else {
|
|
81
|
-
error(description);
|
|
82
|
-
results.failed++;
|
|
83
|
-
results.errors.push(description);
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
86
|
-
} catch (err) {
|
|
87
|
-
error(`${description}: ${err.message}`);
|
|
88
|
-
results.failed++;
|
|
89
|
-
results.errors.push(`${description}: ${err.message}`);
|
|
90
|
-
return false;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
67
|
async function asyncCheck(description, test) {
|
|
95
68
|
results.total++;
|
|
96
69
|
try {
|
|
@@ -120,14 +93,14 @@ async function asyncCheck(description, test) {
|
|
|
120
93
|
// 1. 验证目录结构
|
|
121
94
|
async function validateDirectoryStructure() {
|
|
122
95
|
section('1. 验证目录结构');
|
|
123
|
-
|
|
96
|
+
|
|
124
97
|
const rootDir = path.join(__dirname, '..', '..', '..', '..');
|
|
125
98
|
const paths = {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
99
|
+
tools目录: path.join(__dirname),
|
|
100
|
+
系统工具目录: path.join(rootDir, 'packages', 'resources', 'tools'),
|
|
101
|
+
用户工具目录: config.getToolboxDir()
|
|
129
102
|
};
|
|
130
|
-
|
|
103
|
+
|
|
131
104
|
for (const [name, dirPath] of Object.entries(paths)) {
|
|
132
105
|
await asyncCheck(`${name} 存在: ${dirPath}`, async () => {
|
|
133
106
|
const exists = await pathExists(dirPath);
|
|
@@ -145,19 +118,19 @@ async function validateDirectoryStructure() {
|
|
|
145
118
|
// 2. 验证核心文件
|
|
146
119
|
async function validateCoreFiles() {
|
|
147
120
|
section('2. 验证核心文件');
|
|
148
|
-
|
|
121
|
+
|
|
149
122
|
const coreFiles = [
|
|
150
123
|
{ name: '工具加载服务', path: path.join(__dirname, 'tool-loader.service.js') },
|
|
151
124
|
{ name: '工具管理处理器', path: path.join(__dirname, 'tool-manager.handler.js') },
|
|
152
125
|
{ name: '工具系统入口', path: path.join(__dirname, 'index.js') },
|
|
153
|
-
{ name: 'MCP服务器', path: path.join(__dirname, '..', 'mcp.server.js') }
|
|
126
|
+
{ name: 'MCP服务器', path: path.join(__dirname, '..', 'mcp.server.js') }
|
|
154
127
|
];
|
|
155
|
-
|
|
128
|
+
|
|
156
129
|
for (const file of coreFiles) {
|
|
157
130
|
await asyncCheck(`${file.name} 文件存在`, async () => {
|
|
158
131
|
return await pathExists(file.path);
|
|
159
132
|
});
|
|
160
|
-
|
|
133
|
+
|
|
161
134
|
await asyncCheck(`${file.name} 可读`, async () => {
|
|
162
135
|
try {
|
|
163
136
|
await fs.access(file.path, fs.constants.R_OK);
|
|
@@ -172,24 +145,24 @@ async function validateCoreFiles() {
|
|
|
172
145
|
// 3. 验证工具文件
|
|
173
146
|
async function validateToolFiles() {
|
|
174
147
|
section('3. 验证工具文件');
|
|
175
|
-
|
|
148
|
+
|
|
176
149
|
const rootDir = path.join(__dirname, '..', '..', '..', '..');
|
|
177
150
|
const toolsDir = path.join(rootDir, 'packages', 'resources', 'tools');
|
|
178
|
-
|
|
179
|
-
if (!await pathExists(toolsDir)) {
|
|
151
|
+
|
|
152
|
+
if (!(await pathExists(toolsDir))) {
|
|
180
153
|
error(`工具目录不存在: ${toolsDir}`);
|
|
181
154
|
return;
|
|
182
155
|
}
|
|
183
|
-
|
|
156
|
+
|
|
184
157
|
const toolDirs = await fs.readdir(toolsDir);
|
|
185
158
|
info(`找到 ${toolDirs.length} 个工具目录`);
|
|
186
|
-
|
|
159
|
+
|
|
187
160
|
for (const toolDir of toolDirs) {
|
|
188
161
|
const toolPath = path.join(toolsDir, toolDir);
|
|
189
162
|
const stat = await fs.stat(toolPath);
|
|
190
|
-
|
|
163
|
+
|
|
191
164
|
if (!stat.isDirectory()) continue;
|
|
192
|
-
|
|
165
|
+
|
|
193
166
|
const toolFile = path.join(toolPath, `${toolDir}.tool.js`);
|
|
194
167
|
await asyncCheck(`工具 '${toolDir}' 文件存在`, async () => {
|
|
195
168
|
return await pathExists(toolFile);
|
|
@@ -200,19 +173,19 @@ async function validateToolFiles() {
|
|
|
200
173
|
// 4. 验证模块导入
|
|
201
174
|
async function validateModuleImports() {
|
|
202
175
|
section('4. 验证模块导入');
|
|
203
|
-
|
|
176
|
+
|
|
204
177
|
// 验证工具加载服务
|
|
205
178
|
await asyncCheck('导入工具加载服务', async () => {
|
|
206
179
|
const module = await import('./tool-loader.service.js');
|
|
207
180
|
return module.toolLoaderService !== undefined;
|
|
208
181
|
});
|
|
209
|
-
|
|
182
|
+
|
|
210
183
|
// 验证工具管理处理器
|
|
211
184
|
await asyncCheck('导入工具管理处理器', async () => {
|
|
212
185
|
const module = await import('./tool-manager.handler.js');
|
|
213
186
|
return typeof module.handleToolM === 'function';
|
|
214
187
|
});
|
|
215
|
-
|
|
188
|
+
|
|
216
189
|
// 验证工具系统入口
|
|
217
190
|
await asyncCheck('导入工具系统入口', async () => {
|
|
218
191
|
const module = await import('./index.js');
|
|
@@ -223,44 +196,44 @@ async function validateModuleImports() {
|
|
|
223
196
|
// 5. 验证工具接口规范
|
|
224
197
|
async function validateToolInterfaces() {
|
|
225
198
|
section('5. 验证工具接口规范');
|
|
226
|
-
|
|
199
|
+
|
|
227
200
|
const rootDir = path.join(__dirname, '..', '..', '..', '..');
|
|
228
201
|
const toolsDir = path.join(rootDir, 'packages', 'resources', 'tools');
|
|
229
|
-
|
|
230
|
-
if (!await pathExists(toolsDir)) {
|
|
202
|
+
|
|
203
|
+
if (!(await pathExists(toolsDir))) {
|
|
231
204
|
warning('工具目录不存在,跳过接口验证');
|
|
232
205
|
return;
|
|
233
206
|
}
|
|
234
|
-
|
|
207
|
+
|
|
235
208
|
const toolDirs = await fs.readdir(toolsDir);
|
|
236
|
-
|
|
209
|
+
|
|
237
210
|
for (const toolDir of toolDirs) {
|
|
238
211
|
const toolPath = path.join(toolsDir, toolDir);
|
|
239
212
|
const stat = await fs.stat(toolPath);
|
|
240
|
-
|
|
213
|
+
|
|
241
214
|
if (!stat.isDirectory()) continue;
|
|
242
|
-
|
|
215
|
+
|
|
243
216
|
const toolFile = path.join(toolPath, `${toolDir}.tool.js`);
|
|
244
|
-
|
|
245
|
-
if (!await pathExists(toolFile)) continue;
|
|
246
|
-
|
|
217
|
+
|
|
218
|
+
if (!(await pathExists(toolFile))) continue;
|
|
219
|
+
|
|
247
220
|
await asyncCheck(`工具 '${toolDir}' 符合接口规范`, async () => {
|
|
248
221
|
const toolModule = await import(toolFile);
|
|
249
222
|
const tool = toolModule.default || toolModule;
|
|
250
|
-
|
|
223
|
+
|
|
251
224
|
// 必需方法
|
|
252
225
|
if (typeof tool.execute !== 'function') {
|
|
253
226
|
throw new Error('缺少 execute 方法');
|
|
254
227
|
}
|
|
255
|
-
|
|
228
|
+
|
|
256
229
|
// 推荐方法
|
|
257
230
|
const recommendedMethods = ['getMetadata', 'getSchema', 'getDependencies', 'getBusinessErrors'];
|
|
258
231
|
const missing = recommendedMethods.filter(method => typeof tool[method] !== 'function');
|
|
259
|
-
|
|
232
|
+
|
|
260
233
|
if (missing.length > 0) {
|
|
261
234
|
info(` 缺少推荐方法: ${missing.join(', ')}`);
|
|
262
235
|
}
|
|
263
|
-
|
|
236
|
+
|
|
264
237
|
return true;
|
|
265
238
|
});
|
|
266
239
|
}
|
|
@@ -269,25 +242,25 @@ async function validateToolInterfaces() {
|
|
|
269
242
|
// 6. 验证工具加载器功能
|
|
270
243
|
async function validateToolLoaderFunctionality() {
|
|
271
244
|
section('6. 验证工具加载器功能');
|
|
272
|
-
|
|
245
|
+
|
|
273
246
|
const { toolLoaderService } = await import('./tool-loader.service.js');
|
|
274
|
-
|
|
247
|
+
|
|
275
248
|
await asyncCheck('初始化工具加载器', async () => {
|
|
276
249
|
await toolLoaderService.initialize();
|
|
277
250
|
return toolLoaderService.initialized === true;
|
|
278
251
|
});
|
|
279
|
-
|
|
252
|
+
|
|
280
253
|
await asyncCheck('获取工具列表', async () => {
|
|
281
254
|
const tools = toolLoaderService.getAllTools();
|
|
282
255
|
info(` 加载了 ${tools.length} 个工具`);
|
|
283
256
|
return Array.isArray(tools);
|
|
284
257
|
});
|
|
285
|
-
|
|
258
|
+
|
|
286
259
|
// 检查 filesystem 工具
|
|
287
260
|
await asyncCheck('filesystem 工具已加载', async () => {
|
|
288
261
|
return toolLoaderService.hasTool('filesystem');
|
|
289
262
|
});
|
|
290
|
-
|
|
263
|
+
|
|
291
264
|
if (toolLoaderService.hasTool('filesystem')) {
|
|
292
265
|
await asyncCheck('获取 filesystem 工具详情', async () => {
|
|
293
266
|
const tool = toolLoaderService.getTool('filesystem');
|
|
@@ -295,7 +268,7 @@ async function validateToolLoaderFunctionality() {
|
|
|
295
268
|
info(` 工具描述: ${tool.metadata.description}`);
|
|
296
269
|
return tool !== undefined;
|
|
297
270
|
});
|
|
298
|
-
|
|
271
|
+
|
|
299
272
|
await asyncCheck('生成 filesystem 工具手册', async () => {
|
|
300
273
|
const manual = toolLoaderService.generateManual('filesystem');
|
|
301
274
|
return typeof manual === 'string' && manual.length > 0;
|
|
@@ -306,29 +279,29 @@ async function validateToolLoaderFunctionality() {
|
|
|
306
279
|
// 7. 验证工具管理处理器功能
|
|
307
280
|
async function validateToolManagerFunctionality() {
|
|
308
281
|
section('7. 验证工具管理处理器功能');
|
|
309
|
-
|
|
282
|
+
|
|
310
283
|
const { handleToolM } = await import('./tool-manager.handler.js');
|
|
311
|
-
|
|
284
|
+
|
|
312
285
|
// 测试 manual 模式
|
|
313
286
|
await asyncCheck('手册模式正常工作', async () => {
|
|
314
287
|
const yamlInput = `tool: tool://filesystem
|
|
315
288
|
mode: manual`;
|
|
316
|
-
|
|
289
|
+
|
|
317
290
|
const result = await handleToolM({ yaml: yamlInput });
|
|
318
291
|
return result.content && result.content[0].type === 'text';
|
|
319
292
|
});
|
|
320
|
-
|
|
293
|
+
|
|
321
294
|
// 测试 execute 模式
|
|
322
295
|
await asyncCheck('执行模式正常工作', async () => {
|
|
323
296
|
const yamlInput = `tool: tool://filesystem
|
|
324
297
|
mode: execute
|
|
325
298
|
parameters:
|
|
326
299
|
method: list_allowed_directories`;
|
|
327
|
-
|
|
300
|
+
|
|
328
301
|
const result = await handleToolM({ yaml: yamlInput });
|
|
329
302
|
return result.content && result.content[0].type === 'text';
|
|
330
303
|
});
|
|
331
|
-
|
|
304
|
+
|
|
332
305
|
// 测试错误处理
|
|
333
306
|
await asyncCheck('错误处理正常工作', async () => {
|
|
334
307
|
try {
|
|
@@ -345,12 +318,12 @@ mode: execute`;
|
|
|
345
318
|
// 8. 验证 MCP 服务器集成
|
|
346
319
|
async function validateMCPServerIntegration() {
|
|
347
320
|
section('8. 验证 MCP 服务器集成');
|
|
348
|
-
|
|
321
|
+
|
|
349
322
|
await asyncCheck('MCP 服务器模块可导入', async () => {
|
|
350
323
|
const module = await import('../mcp.server.js');
|
|
351
324
|
return typeof module.getMcpServer === 'function';
|
|
352
325
|
});
|
|
353
|
-
|
|
326
|
+
|
|
354
327
|
await asyncCheck('MCP 服务器包含 toolm 工具', async () => {
|
|
355
328
|
// 这需要实际启动服务器才能验证,这里只检查导入
|
|
356
329
|
info(' 需要启动服务器才能完全验证,当前仅检查模块导入');
|
|
@@ -361,7 +334,7 @@ async function validateMCPServerIntegration() {
|
|
|
361
334
|
// 9. 生成报告
|
|
362
335
|
function generateReport() {
|
|
363
336
|
section('验证结果汇总');
|
|
364
|
-
|
|
337
|
+
|
|
365
338
|
console.log(`总计测试: ${results.total}`);
|
|
366
339
|
log(`通过: ${results.passed}`, 'green');
|
|
367
340
|
if (results.warnings > 0) {
|
|
@@ -370,17 +343,17 @@ function generateReport() {
|
|
|
370
343
|
if (results.failed > 0) {
|
|
371
344
|
log(`失败: ${results.failed}`, 'red');
|
|
372
345
|
}
|
|
373
|
-
|
|
374
|
-
const percentage = (results.passed / results.total * 100).toFixed(1);
|
|
346
|
+
|
|
347
|
+
const percentage = ((results.passed / results.total) * 100).toFixed(1);
|
|
375
348
|
console.log(`\n通过率: ${percentage}%`);
|
|
376
|
-
|
|
349
|
+
|
|
377
350
|
if (results.errors.length > 0) {
|
|
378
351
|
section('失败的测试');
|
|
379
352
|
results.errors.forEach((err, index) => {
|
|
380
353
|
error(`${index + 1}. ${err}`);
|
|
381
354
|
});
|
|
382
355
|
}
|
|
383
|
-
|
|
356
|
+
|
|
384
357
|
console.log();
|
|
385
358
|
if (results.failed === 0) {
|
|
386
359
|
log('🎉 所有验证通过!工具系统已准备就绪。', 'green');
|
|
@@ -396,7 +369,7 @@ async function main() {
|
|
|
396
369
|
log('\n╔════════════════════════════════════════════════════════╗', 'cyan');
|
|
397
370
|
log('║ Prompt Manager 工具系统全面验证 ║', 'cyan');
|
|
398
371
|
log('╚════════════════════════════════════════════════════════╝', 'cyan');
|
|
399
|
-
|
|
372
|
+
|
|
400
373
|
try {
|
|
401
374
|
await validateDirectoryStructure();
|
|
402
375
|
await validateCoreFiles();
|
|
@@ -406,7 +379,7 @@ async function main() {
|
|
|
406
379
|
await validateToolLoaderFunctionality();
|
|
407
380
|
await validateToolManagerFunctionality();
|
|
408
381
|
await validateMCPServerIntegration();
|
|
409
|
-
|
|
382
|
+
|
|
410
383
|
const success = generateReport();
|
|
411
384
|
process.exit(success ? 0 : 1);
|
|
412
385
|
} catch (error) {
|
|
@@ -418,4 +391,3 @@ async function main() {
|
|
|
418
391
|
|
|
419
392
|
// 运行验证
|
|
420
393
|
main();
|
|
421
|
-
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import fs from 'fs-extra';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import os from 'os';
|
|
4
|
-
import { fileURLToPath } from 'url';
|
|
5
4
|
import crypto from 'crypto';
|
|
6
5
|
import dotenv from 'dotenv';
|
|
7
6
|
|
|
@@ -25,8 +24,6 @@ function expandPath(inputPath) {
|
|
|
25
24
|
const configHome = path.join(os.homedir(), '.prompt-manager');
|
|
26
25
|
dotenv.config({ path: path.join(configHome, '.env') });
|
|
27
26
|
|
|
28
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
29
|
-
const __dirname = path.dirname(__filename);
|
|
30
27
|
const DEFAULT_HOME_DIR = path.join(os.homedir(), '.prompt-manager');
|
|
31
28
|
const DEFAULT_PROMPTS_DIR = path.join(DEFAULT_HOME_DIR, 'prompts');
|
|
32
29
|
|
|
@@ -109,10 +106,8 @@ export class Config {
|
|
|
109
106
|
}
|
|
110
107
|
|
|
111
108
|
// 确定prompts目录
|
|
112
|
-
this.promptsDir = expandPath(cliArgs.promptsDir) ||
|
|
113
|
-
|
|
114
|
-
DEFAULT_PROMPTS_DIR;
|
|
115
|
-
this.configHome = path.dirname(this.promptsDir);
|
|
109
|
+
this.promptsDir = expandPath(cliArgs.promptsDir) || expandPath(process.env.PROMPTS_DIR) || DEFAULT_PROMPTS_DIR;
|
|
110
|
+
this.configHome = DEFAULT_HOME_DIR;
|
|
116
111
|
|
|
117
112
|
// 服务器端口
|
|
118
113
|
this.port = cliArgs.port || process.env.SERVER_PORT || 5621;
|
|
@@ -147,7 +142,7 @@ export class Config {
|
|
|
147
142
|
];
|
|
148
143
|
|
|
149
144
|
if (cliArgs.version) {
|
|
150
|
-
process.stderr.write(this.serverVersion
|
|
145
|
+
process.stderr.write(`${this.serverVersion}\n`);
|
|
151
146
|
process.exit(0);
|
|
152
147
|
}
|
|
153
148
|
|
|
@@ -181,7 +176,6 @@ export class Config {
|
|
|
181
176
|
|
|
182
177
|
if (promptsDir) {
|
|
183
178
|
this.promptsDir = expandPath(promptsDir);
|
|
184
|
-
this.configHome = path.dirname(this.promptsDir);
|
|
185
179
|
}
|
|
186
180
|
if (port) {
|
|
187
181
|
this.port = port;
|
|
@@ -221,7 +215,6 @@ export class Config {
|
|
|
221
215
|
}
|
|
222
216
|
}
|
|
223
217
|
|
|
224
|
-
|
|
225
218
|
/**
|
|
226
219
|
* 确保prompts目录存在
|
|
227
220
|
*/
|
|
@@ -230,7 +223,7 @@ export class Config {
|
|
|
230
223
|
await fs.ensureDir(this.promptsDir);
|
|
231
224
|
return true;
|
|
232
225
|
} catch (error) {
|
|
233
|
-
process.stderr.write(
|
|
226
|
+
process.stderr.write(`Failed to create prompts directory: ${error.message}\n`);
|
|
234
227
|
return false;
|
|
235
228
|
}
|
|
236
229
|
}
|
|
@@ -260,6 +253,67 @@ export class Config {
|
|
|
260
253
|
this.port = port;
|
|
261
254
|
}
|
|
262
255
|
|
|
256
|
+
/**
|
|
257
|
+
* 获取临时文件目录
|
|
258
|
+
* @returns {string} 临时文件目录路径
|
|
259
|
+
*/
|
|
260
|
+
getTempDir() {
|
|
261
|
+
return path.join(this.getConfigHome(), 'temp');
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* 获取工具箱目录
|
|
266
|
+
* @returns {string} 工具箱目录路径
|
|
267
|
+
*/
|
|
268
|
+
getToolboxDir() {
|
|
269
|
+
return path.join(this.getConfigHome(), 'toolbox');
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* 获取指定工具的目录
|
|
274
|
+
* @param {string} toolName - 工具名称
|
|
275
|
+
* @returns {string} 工具目录路径
|
|
276
|
+
* @throws {Error} 如果 toolName 未提供
|
|
277
|
+
*/
|
|
278
|
+
getToolDir(toolName) {
|
|
279
|
+
if (!toolName) {
|
|
280
|
+
throw new Error('toolName is required for getToolDir()');
|
|
281
|
+
}
|
|
282
|
+
return path.join(this.getToolboxDir(), toolName);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* 获取模型配置目录
|
|
287
|
+
* @returns {string} 模型配置目录路径
|
|
288
|
+
*/
|
|
289
|
+
getModelsDir() {
|
|
290
|
+
return path.join(this.getConfigHome(), 'configs', 'models');
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* 获取模板配置目录
|
|
295
|
+
* @returns {string} 模板配置目录路径
|
|
296
|
+
*/
|
|
297
|
+
getTemplatesDir() {
|
|
298
|
+
return path.join(this.getConfigHome(), 'configs', 'templates');
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* 获取用户配置目录
|
|
303
|
+
* @returns {string} 用户配置目录路径
|
|
304
|
+
*/
|
|
305
|
+
getConfigsDir() {
|
|
306
|
+
return path.join(this.getConfigHome(), 'configs');
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* 获取环境变量文件路径
|
|
311
|
+
* @returns {string} .env 文件路径
|
|
312
|
+
*/
|
|
313
|
+
getEnvFilePath() {
|
|
314
|
+
return path.join(this.getConfigHome(), '.env');
|
|
315
|
+
}
|
|
316
|
+
|
|
263
317
|
/**
|
|
264
318
|
* 获取服务器名称
|
|
265
319
|
*/
|
|
@@ -308,6 +362,36 @@ export class Config {
|
|
|
308
362
|
}
|
|
309
363
|
}
|
|
310
364
|
|
|
365
|
+
/**
|
|
366
|
+
* 验证配置路径一致性
|
|
367
|
+
* @throws {Error} 如果路径配置不一致
|
|
368
|
+
*/
|
|
369
|
+
validatePaths() {
|
|
370
|
+
const configHome = this.getConfigHome();
|
|
371
|
+
const expectedHome = DEFAULT_HOME_DIR;
|
|
372
|
+
|
|
373
|
+
if (configHome !== expectedHome) {
|
|
374
|
+
throw new Error(`ConfigHome不一致: 期望 ${expectedHome}, 实际 ${configHome}`);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// 仅验证路径格式,不实际创建目录
|
|
378
|
+
const dirsToCheck = [
|
|
379
|
+
this.getPromptsDir(),
|
|
380
|
+
this.getTempDir(),
|
|
381
|
+
this.getToolboxDir(),
|
|
382
|
+
this.getModelsDir(),
|
|
383
|
+
this.getTemplatesDir()
|
|
384
|
+
];
|
|
385
|
+
|
|
386
|
+
for (const dir of dirsToCheck) {
|
|
387
|
+
if (!dir || typeof dir !== 'string') {
|
|
388
|
+
throw new Error(`无效的目录路径: ${dir}`);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
return true;
|
|
393
|
+
}
|
|
394
|
+
|
|
311
395
|
/**
|
|
312
396
|
* 获取公开配置(前端可访问的配置信息)
|
|
313
397
|
*/
|
|
@@ -318,7 +402,8 @@ export class Config {
|
|
|
318
402
|
port: this.port,
|
|
319
403
|
adminEnable: this.adminEnable,
|
|
320
404
|
adminPath: this.adminPath,
|
|
321
|
-
|
|
405
|
+
// WebSocket端口由WebSocketService动态分配,通过admin.routes.js暴露给前端
|
|
406
|
+
websocketPort: null,
|
|
322
407
|
features: {
|
|
323
408
|
terminal: true,
|
|
324
409
|
optimization: true,
|
|
@@ -6,16 +6,16 @@ import net from 'net';
|
|
|
6
6
|
* @returns {Promise<boolean>} - 端口是否可用
|
|
7
7
|
*/
|
|
8
8
|
export async function checkPortAvailable(port) {
|
|
9
|
-
return new Promise(
|
|
9
|
+
return new Promise(resolve => {
|
|
10
10
|
const server = net.createServer();
|
|
11
|
-
|
|
11
|
+
|
|
12
12
|
server.listen(port, () => {
|
|
13
13
|
server.once('close', () => {
|
|
14
14
|
resolve(true);
|
|
15
15
|
});
|
|
16
16
|
server.close();
|
|
17
17
|
});
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
server.on('error', () => {
|
|
20
20
|
resolve(false);
|
|
21
21
|
});
|
|
@@ -44,15 +44,15 @@ export async function findAvailablePort(startPort, maxAttempts = 10) {
|
|
|
44
44
|
* @returns {Promise<Object>} - 端口占用信息
|
|
45
45
|
*/
|
|
46
46
|
export async function getPortInfo(port) {
|
|
47
|
-
return new Promise(
|
|
47
|
+
return new Promise(resolve => {
|
|
48
48
|
const server = net.createServer();
|
|
49
|
-
|
|
49
|
+
|
|
50
50
|
server.listen(port, () => {
|
|
51
51
|
server.close();
|
|
52
52
|
resolve({ available: true, process: null });
|
|
53
53
|
});
|
|
54
|
-
|
|
55
|
-
server.on('error',
|
|
54
|
+
|
|
55
|
+
server.on('error', error => {
|
|
56
56
|
if (error.code === 'EADDRINUSE') {
|
|
57
57
|
resolve({ available: false, error: '端口已被占用' });
|
|
58
58
|
} else {
|
|
@@ -60,4 +60,4 @@ export async function getPortInfo(port) {
|
|
|
60
60
|
}
|
|
61
61
|
});
|
|
62
62
|
});
|
|
63
|
-
}
|
|
63
|
+
}
|