aicodeswitch 3.0.7 → 3.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/bin/cli.js +3 -3
- package/bin/{update.js → upgrade.js} +17 -17
- package/bin/version.js +1 -1
- package/dist/server/fs-database.js +244 -3
- package/dist/server/main.js +234 -10
- package/dist/server/mcp-image-handler.js +232 -0
- package/dist/server/proxy-server.js +123 -0
- package/dist/ui/assets/index-BUGoZPd5.js +486 -0
- package/dist/ui/assets/index-Bbt481dy.css +1 -0
- package/dist/ui/index.html +2 -2
- package/package.json +1 -1
- package/dist/ui/assets/index-BFZeqM0H.css +0 -1
- package/dist/ui/assets/index-BnQkDg3R.js +0 -481
package/README.md
CHANGED
|
@@ -153,6 +153,11 @@ aicodeswitch内部,会根据“源类型”来转换数据。例如,你的
|
|
|
153
153
|
你可以在 aicodeswitch 中集中统一管理 skills,把skills分发给claude code和codex,随时启用和停用skills。
|
|
154
154
|
另外,你可以基于自然语言搜索skills,找到skill之后,支持一键安装。
|
|
155
155
|
|
|
156
|
+
## MCP管理
|
|
157
|
+
|
|
158
|
+
你可以在 aicodeswitch 中集中统一管理 MCP,把MCP分发给claude code和codex,随时启用和停用MCP。
|
|
159
|
+
并且,你还可以通过MCP来实现图像理解。
|
|
160
|
+
|
|
156
161
|
## 日志
|
|
157
162
|
|
|
158
163
|
在**日志**页面,您可以查看:
|
package/bin/cli.js
CHANGED
|
@@ -7,7 +7,7 @@ const commands = {
|
|
|
7
7
|
start: require('./start'),
|
|
8
8
|
stop: require('./stop'),
|
|
9
9
|
restart: require('./restart'),
|
|
10
|
-
|
|
10
|
+
upgrade: require('./upgrade'),
|
|
11
11
|
restore: require('./restore'),
|
|
12
12
|
version: require('./version'),
|
|
13
13
|
ui: require('./ui'),
|
|
@@ -22,7 +22,7 @@ Commands:
|
|
|
22
22
|
stop Stop the AI Code Switch server
|
|
23
23
|
restart Restart the AI Code Switch server
|
|
24
24
|
ui Open the web UI in browser (starts server if needed)
|
|
25
|
-
|
|
25
|
+
upgrade Upgrade to the latest version and restart
|
|
26
26
|
restore Restore original configuration files
|
|
27
27
|
version Show current version information
|
|
28
28
|
|
|
@@ -31,7 +31,7 @@ Example:
|
|
|
31
31
|
aicos stop
|
|
32
32
|
aicos restart
|
|
33
33
|
aicos ui
|
|
34
|
-
aicos
|
|
34
|
+
aicos upgrade
|
|
35
35
|
aicos restore
|
|
36
36
|
aicos restore claude-code
|
|
37
37
|
aicos restore codex
|
|
@@ -29,7 +29,7 @@ const getLatestVersion = () => {
|
|
|
29
29
|
path: `/${PACKAGE_NAME}`,
|
|
30
30
|
method: 'GET',
|
|
31
31
|
headers: {
|
|
32
|
-
'User-Agent': 'aicodeswitch-
|
|
32
|
+
'User-Agent': 'aicodeswitch-upgrade'
|
|
33
33
|
}
|
|
34
34
|
};
|
|
35
35
|
|
|
@@ -142,8 +142,8 @@ const compareVersions = (v1, v2) => {
|
|
|
142
142
|
return 0;
|
|
143
143
|
};
|
|
144
144
|
|
|
145
|
-
//
|
|
146
|
-
const
|
|
145
|
+
// 主升级逻辑
|
|
146
|
+
const upgrade = async () => {
|
|
147
147
|
console.log('\n');
|
|
148
148
|
|
|
149
149
|
const currentVersion = getCurrentVersion();
|
|
@@ -180,8 +180,8 @@ const update = async () => {
|
|
|
180
180
|
} catch (err) {
|
|
181
181
|
checkSpinner.fail(chalk.red('Failed to check for updates'));
|
|
182
182
|
console.log(chalk.yellow(`\nError: ${err.message}\n`));
|
|
183
|
-
console.log(chalk.white('You can manually
|
|
184
|
-
console.log(chalk.cyan(' npm
|
|
183
|
+
console.log(chalk.white('You can manually upgrade by running:\n'));
|
|
184
|
+
console.log(chalk.cyan(' npm install -g aicodeswitch\n'));
|
|
185
185
|
process.exit(1);
|
|
186
186
|
}
|
|
187
187
|
|
|
@@ -212,7 +212,7 @@ const update = async () => {
|
|
|
212
212
|
chalk.yellow.bold('⬆️ New version available!\n\n') +
|
|
213
213
|
chalk.white('Current: ') + chalk.gray(currentVersion) + '\n' +
|
|
214
214
|
chalk.white('Latest: ') + chalk.green.bold(latestVersion) + '\n\n' +
|
|
215
|
-
chalk.gray('Preparing to
|
|
215
|
+
chalk.gray('Preparing to upgrade...'),
|
|
216
216
|
{
|
|
217
217
|
padding: 1,
|
|
218
218
|
margin: 1,
|
|
@@ -230,9 +230,9 @@ const update = async () => {
|
|
|
230
230
|
console.log(boxen(
|
|
231
231
|
chalk.yellow.bold('⚠️ Sudo privileges required\n\n') +
|
|
232
232
|
chalk.white('This operation requires ') + chalk.yellow.bold('sudo') + chalk.white(' privileges.\n\n') +
|
|
233
|
-
chalk.white('Please run the following command to
|
|
233
|
+
chalk.white('Please run the following command to upgrade:\n\n') +
|
|
234
234
|
chalk.cyan.bold(' sudo npm install -g ' + PACKAGE_NAME + '@latest\n\n') +
|
|
235
|
-
chalk.gray('After
|
|
235
|
+
chalk.gray('After upgrading, run ') + chalk.cyan('aicos restart') + chalk.gray(' to restart the server.'),
|
|
236
236
|
{
|
|
237
237
|
padding: 1,
|
|
238
238
|
margin: 1,
|
|
@@ -244,26 +244,26 @@ const update = async () => {
|
|
|
244
244
|
process.exit(0);
|
|
245
245
|
}
|
|
246
246
|
|
|
247
|
-
//
|
|
248
|
-
const
|
|
249
|
-
text: chalk.cyan('
|
|
247
|
+
// 执行升级
|
|
248
|
+
const upgradeSpinner = ora({
|
|
249
|
+
text: chalk.cyan('Upgrading to latest version...'),
|
|
250
250
|
color: 'cyan'
|
|
251
251
|
}).start();
|
|
252
252
|
|
|
253
253
|
try {
|
|
254
254
|
await execCommand('npm', ['install', '-g', `${PACKAGE_NAME}@latest`]);
|
|
255
|
-
|
|
255
|
+
upgradeSpinner.succeed(chalk.green('Upgrade successful!'));
|
|
256
256
|
} catch (err) {
|
|
257
|
-
|
|
258
|
-
console.log(chalk.yellow(`\
|
|
259
|
-
console.log(chalk.white('You can try manually
|
|
257
|
+
upgradeSpinner.fail(chalk.red('Upgrade failed'));
|
|
258
|
+
console.log(chalk.yellow(`\nUpgrade failed with error code ${err.code || 'unknown'}\n`));
|
|
259
|
+
console.log(chalk.white('You can try manually upgrading:\n'));
|
|
260
260
|
console.log(chalk.cyan(` npm install -g ${PACKAGE_NAME}@latest\n`));
|
|
261
261
|
process.exit(1);
|
|
262
262
|
}
|
|
263
263
|
|
|
264
264
|
console.log('');
|
|
265
265
|
console.log(boxen(
|
|
266
|
-
chalk.green.bold('✓ Successfully
|
|
266
|
+
chalk.green.bold('✓ Successfully upgraded!\n\n') +
|
|
267
267
|
chalk.white('Previous version: ') + chalk.gray(currentVersion) + '\n' +
|
|
268
268
|
chalk.white('New version: ') + chalk.green.bold(latestVersion),
|
|
269
269
|
{
|
|
@@ -280,4 +280,4 @@ const update = async () => {
|
|
|
280
280
|
console.log('\n');
|
|
281
281
|
};
|
|
282
282
|
|
|
283
|
-
module.exports =
|
|
283
|
+
module.exports = upgrade;
|
package/bin/version.js
CHANGED
|
@@ -38,7 +38,7 @@ const version = () => {
|
|
|
38
38
|
));
|
|
39
39
|
|
|
40
40
|
console.log(chalk.cyan('💡 Tips:\n'));
|
|
41
|
-
console.log(chalk.white(' • Check for updates: ') + chalk.yellow('aicos
|
|
41
|
+
console.log(chalk.white(' • Check for updates: ') + chalk.yellow('aicos upgrade'));
|
|
42
42
|
console.log(chalk.white(' • Restart server: ') + chalk.yellow('aicos restart\n'));
|
|
43
43
|
|
|
44
44
|
process.exit(0);
|
|
@@ -45,6 +45,7 @@ class FileSystemDatabaseManager {
|
|
|
45
45
|
get errorLogsFile() { return path_1.default.join(this.dataPath, 'error-logs.json'); }
|
|
46
46
|
get blacklistFile() { return path_1.default.join(this.dataPath, 'blacklist.json'); }
|
|
47
47
|
get statisticsFile() { return path_1.default.join(this.dataPath, 'statistics.json'); }
|
|
48
|
+
get mcpFile() { return path_1.default.join(this.dataPath, 'mcps.json'); }
|
|
48
49
|
// 创建空的统计数据结构
|
|
49
50
|
createEmptyStatistics() {
|
|
50
51
|
return {
|
|
@@ -130,6 +131,12 @@ class FileSystemDatabaseManager {
|
|
|
130
131
|
writable: true,
|
|
131
132
|
value: new Map()
|
|
132
133
|
});
|
|
134
|
+
Object.defineProperty(this, "mcps", {
|
|
135
|
+
enumerable: true,
|
|
136
|
+
configurable: true,
|
|
137
|
+
writable: true,
|
|
138
|
+
value: []
|
|
139
|
+
});
|
|
133
140
|
// 持久化统计数据
|
|
134
141
|
Object.defineProperty(this, "statistics", {
|
|
135
142
|
enumerable: true,
|
|
@@ -215,6 +222,7 @@ class FileSystemDatabaseManager {
|
|
|
215
222
|
this.loadErrorLogs(),
|
|
216
223
|
this.loadBlacklist(),
|
|
217
224
|
this.loadStatistics(),
|
|
225
|
+
this.loadMCPs(),
|
|
218
226
|
]);
|
|
219
227
|
});
|
|
220
228
|
}
|
|
@@ -684,6 +692,22 @@ class FileSystemDatabaseManager {
|
|
|
684
692
|
yield promises_1.default.writeFile(this.statisticsFile, JSON.stringify(this.statistics, null, 2));
|
|
685
693
|
});
|
|
686
694
|
}
|
|
695
|
+
loadMCPs() {
|
|
696
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
697
|
+
try {
|
|
698
|
+
const data = yield promises_1.default.readFile(this.mcpFile, 'utf-8');
|
|
699
|
+
this.mcps = JSON.parse(data);
|
|
700
|
+
}
|
|
701
|
+
catch (_a) {
|
|
702
|
+
this.mcps = [];
|
|
703
|
+
}
|
|
704
|
+
});
|
|
705
|
+
}
|
|
706
|
+
saveMCPs() {
|
|
707
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
708
|
+
yield promises_1.default.writeFile(this.mcpFile, JSON.stringify(this.mcps, null, 2));
|
|
709
|
+
});
|
|
710
|
+
}
|
|
687
711
|
ensureDefaultConfig() {
|
|
688
712
|
return __awaiter(this, void 0, void 0, function* () {
|
|
689
713
|
if (!this.config) {
|
|
@@ -1263,6 +1287,101 @@ class FileSystemDatabaseManager {
|
|
|
1263
1287
|
return count;
|
|
1264
1288
|
});
|
|
1265
1289
|
}
|
|
1290
|
+
/**
|
|
1291
|
+
* 搜索请求日志内容
|
|
1292
|
+
* @param query 搜索关键词
|
|
1293
|
+
* @param limit 返回��量限制
|
|
1294
|
+
* @param offset 偏移量
|
|
1295
|
+
* @returns 匹配的日志列表
|
|
1296
|
+
*/
|
|
1297
|
+
searchLogs(query_1) {
|
|
1298
|
+
return __awaiter(this, arguments, void 0, function* (query, limit = 100, offset = 0) {
|
|
1299
|
+
const searchQuery = query.toLowerCase().trim();
|
|
1300
|
+
if (!searchQuery) {
|
|
1301
|
+
return this.getLogs(limit, offset);
|
|
1302
|
+
}
|
|
1303
|
+
const allMatches = [];
|
|
1304
|
+
const sortedShards = [...this.logShardsIndex].sort((a, b) => b.endTime - a.endTime);
|
|
1305
|
+
// 遍历所有分片进行搜索
|
|
1306
|
+
for (const shard of sortedShards) {
|
|
1307
|
+
const shardLogs = yield this.loadLogShard(shard.filename);
|
|
1308
|
+
for (const log of shardLogs) {
|
|
1309
|
+
if (this.logMatchesQuery(log, searchQuery)) {
|
|
1310
|
+
allMatches.push(log);
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
// 按时间倒序排列并分页
|
|
1315
|
+
return allMatches
|
|
1316
|
+
.sort((a, b) => b.timestamp - a.timestamp)
|
|
1317
|
+
.slice(offset, offset + limit);
|
|
1318
|
+
});
|
|
1319
|
+
}
|
|
1320
|
+
/**
|
|
1321
|
+
* 搜索请求日志内容数量
|
|
1322
|
+
* @param query 搜索关键词
|
|
1323
|
+
* @returns 匹配的日志数量
|
|
1324
|
+
*/
|
|
1325
|
+
searchLogsCount(query) {
|
|
1326
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1327
|
+
const searchQuery = query.toLowerCase().trim();
|
|
1328
|
+
if (!searchQuery) {
|
|
1329
|
+
return this.getLogsCount();
|
|
1330
|
+
}
|
|
1331
|
+
let count = 0;
|
|
1332
|
+
for (const shard of this.logShardsIndex) {
|
|
1333
|
+
const shardLogs = yield this.loadLogShard(shard.filename);
|
|
1334
|
+
for (const log of shardLogs) {
|
|
1335
|
+
if (this.logMatchesQuery(log, searchQuery)) {
|
|
1336
|
+
count++;
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
return count;
|
|
1341
|
+
});
|
|
1342
|
+
}
|
|
1343
|
+
/**
|
|
1344
|
+
* 检查日志是否匹配搜索查询
|
|
1345
|
+
*/
|
|
1346
|
+
logMatchesQuery(log, query) {
|
|
1347
|
+
// 搜索请求体
|
|
1348
|
+
if (log.body) {
|
|
1349
|
+
const bodyStr = typeof log.body === 'string' ? log.body : JSON.stringify(log.body);
|
|
1350
|
+
if (bodyStr.toLowerCase().includes(query)) {
|
|
1351
|
+
return true;
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
// 搜索响应体
|
|
1355
|
+
if (log.responseBody && typeof log.responseBody === 'string') {
|
|
1356
|
+
if (log.responseBody.toLowerCase().includes(query)) {
|
|
1357
|
+
return true;
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
// 搜索流式响应块
|
|
1361
|
+
if (log.streamChunks && log.streamChunks.length > 0) {
|
|
1362
|
+
for (const chunk of log.streamChunks) {
|
|
1363
|
+
if (chunk.toLowerCase().includes(query)) {
|
|
1364
|
+
return true;
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1368
|
+
// 搜索错误信息
|
|
1369
|
+
if (log.error && log.error.toLowerCase().includes(query)) {
|
|
1370
|
+
return true;
|
|
1371
|
+
}
|
|
1372
|
+
// 搜索路径
|
|
1373
|
+
if (log.path && log.path.toLowerCase().includes(query)) {
|
|
1374
|
+
return true;
|
|
1375
|
+
}
|
|
1376
|
+
// 搜索模型名称
|
|
1377
|
+
if (log.requestModel && log.requestModel.toLowerCase().includes(query)) {
|
|
1378
|
+
return true;
|
|
1379
|
+
}
|
|
1380
|
+
if (log.targetModel && log.targetModel.toLowerCase().includes(query)) {
|
|
1381
|
+
return true;
|
|
1382
|
+
}
|
|
1383
|
+
return false;
|
|
1384
|
+
}
|
|
1266
1385
|
// Error log operations
|
|
1267
1386
|
addErrorLog(log) {
|
|
1268
1387
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -1294,6 +1413,78 @@ class FileSystemDatabaseManager {
|
|
|
1294
1413
|
return count;
|
|
1295
1414
|
});
|
|
1296
1415
|
}
|
|
1416
|
+
/**
|
|
1417
|
+
* 搜索错误日志内容
|
|
1418
|
+
* @param query 搜索关键词
|
|
1419
|
+
* @param limit 返回数量限制
|
|
1420
|
+
* @param offset 偏移量
|
|
1421
|
+
* @returns 匹配的错误日志列表
|
|
1422
|
+
*/
|
|
1423
|
+
searchErrorLogs(query_1) {
|
|
1424
|
+
return __awaiter(this, arguments, void 0, function* (query, limit = 100, offset = 0) {
|
|
1425
|
+
const searchQuery = query.toLowerCase().trim();
|
|
1426
|
+
if (!searchQuery) {
|
|
1427
|
+
return this.getErrorLogs(limit, offset);
|
|
1428
|
+
}
|
|
1429
|
+
const matches = this.errorLogs.filter(log => this.errorLogMatchesQuery(log, searchQuery));
|
|
1430
|
+
return matches
|
|
1431
|
+
.sort((a, b) => b.timestamp - a.timestamp)
|
|
1432
|
+
.slice(offset, offset + limit);
|
|
1433
|
+
});
|
|
1434
|
+
}
|
|
1435
|
+
/**
|
|
1436
|
+
* 搜索错误日志内容数量
|
|
1437
|
+
* @param query 搜索关键词
|
|
1438
|
+
* @returns 匹配的错误日志数量
|
|
1439
|
+
*/
|
|
1440
|
+
searchErrorLogsCount(query) {
|
|
1441
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1442
|
+
const searchQuery = query.toLowerCase().trim();
|
|
1443
|
+
if (!searchQuery) {
|
|
1444
|
+
return this.getErrorLogsCount();
|
|
1445
|
+
}
|
|
1446
|
+
return this.errorLogs.filter(log => this.errorLogMatchesQuery(log, searchQuery)).length;
|
|
1447
|
+
});
|
|
1448
|
+
}
|
|
1449
|
+
/**
|
|
1450
|
+
* 检查错误日志是否匹配搜索查询
|
|
1451
|
+
*/
|
|
1452
|
+
errorLogMatchesQuery(log, query) {
|
|
1453
|
+
// 搜索错误信息
|
|
1454
|
+
if (log.errorMessage && log.errorMessage.toLowerCase().includes(query)) {
|
|
1455
|
+
return true;
|
|
1456
|
+
}
|
|
1457
|
+
// 搜索错误堆栈
|
|
1458
|
+
if (log.errorStack && log.errorStack.toLowerCase().includes(query)) {
|
|
1459
|
+
return true;
|
|
1460
|
+
}
|
|
1461
|
+
// 搜索请求体
|
|
1462
|
+
if (log.requestBody) {
|
|
1463
|
+
const bodyStr = typeof log.requestBody === 'string' ? log.requestBody : JSON.stringify(log.requestBody);
|
|
1464
|
+
if (bodyStr.toLowerCase().includes(query)) {
|
|
1465
|
+
return true;
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
// 搜索响应体
|
|
1469
|
+
if (log.responseBody) {
|
|
1470
|
+
const bodyStr = typeof log.responseBody === 'string' ? log.responseBody : JSON.stringify(log.responseBody);
|
|
1471
|
+
if (bodyStr.toLowerCase().includes(query)) {
|
|
1472
|
+
return true;
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
// 搜索路径
|
|
1476
|
+
if (log.path && log.path.toLowerCase().includes(query)) {
|
|
1477
|
+
return true;
|
|
1478
|
+
}
|
|
1479
|
+
// 搜索模型名称
|
|
1480
|
+
if (log.requestModel && log.requestModel.toLowerCase().includes(query)) {
|
|
1481
|
+
return true;
|
|
1482
|
+
}
|
|
1483
|
+
if (log.targetModel && log.targetModel.toLowerCase().includes(query)) {
|
|
1484
|
+
return true;
|
|
1485
|
+
}
|
|
1486
|
+
return false;
|
|
1487
|
+
}
|
|
1297
1488
|
// Service blacklist operations
|
|
1298
1489
|
isServiceBlacklisted(serviceId, routeId, contentType) {
|
|
1299
1490
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -1442,13 +1633,22 @@ class FileSystemDatabaseManager {
|
|
|
1442
1633
|
if (!rule.routeId || typeof rule.routeId !== 'string') {
|
|
1443
1634
|
return { valid: false, error: `规则[${index}](${rule.id}) 缺少有效的 routeId 字段` };
|
|
1444
1635
|
}
|
|
1445
|
-
if (!rule.targetServiceId || typeof rule.targetServiceId !== 'string') {
|
|
1446
|
-
return { valid: false, error: `规则[${index}](${rule.id}) 缺少有效的 targetServiceId 字段` };
|
|
1447
|
-
}
|
|
1448
1636
|
const validContentTypes = ['default', 'background', 'thinking', 'long-context', 'image-understanding', 'model-mapping'];
|
|
1449
1637
|
if (!rule.contentType || !validContentTypes.includes(rule.contentType)) {
|
|
1450
1638
|
return { valid: false, error: `规则[${index}](${rule.id}) 的 contentType 无效` };
|
|
1451
1639
|
}
|
|
1640
|
+
// 如果使用MCP(仅对图像理解类型有效),则不需要验证targetServiceId
|
|
1641
|
+
if (rule.useMCP === true && rule.contentType === 'image-understanding') {
|
|
1642
|
+
if (!rule.mcpId || typeof rule.mcpId !== 'string') {
|
|
1643
|
+
return { valid: false, error: `规则[${index}](${rule.id}) 使用MCP时缺少有效的 mcpId 字段` };
|
|
1644
|
+
}
|
|
1645
|
+
}
|
|
1646
|
+
else {
|
|
1647
|
+
// 不使用MCP时,必须验证targetServiceId
|
|
1648
|
+
if (!rule.targetServiceId || typeof rule.targetServiceId !== 'string') {
|
|
1649
|
+
return { valid: false, error: `规则[${index}](${rule.id}) 缺少有效的 targetServiceId 字段` };
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1452
1652
|
return { valid: true };
|
|
1453
1653
|
}
|
|
1454
1654
|
/**
|
|
@@ -2027,6 +2227,47 @@ class FileSystemDatabaseManager {
|
|
|
2027
2227
|
return entry;
|
|
2028
2228
|
});
|
|
2029
2229
|
}
|
|
2230
|
+
// MCP 工具相关操作
|
|
2231
|
+
getMCPs() {
|
|
2232
|
+
return this.mcps.sort((a, b) => b.createdAt - a.createdAt);
|
|
2233
|
+
}
|
|
2234
|
+
getMCP(id) {
|
|
2235
|
+
return this.mcps.find(m => m.id === id);
|
|
2236
|
+
}
|
|
2237
|
+
getMCPsByTarget(targetType) {
|
|
2238
|
+
return this.mcps.filter(m => { var _a; return (_a = m.targets) === null || _a === void 0 ? void 0 : _a.includes(targetType); });
|
|
2239
|
+
}
|
|
2240
|
+
createMCP(mcp) {
|
|
2241
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2242
|
+
const id = crypto_1.default.randomUUID();
|
|
2243
|
+
const now = Date.now();
|
|
2244
|
+
const newMCP = Object.assign(Object.assign({}, mcp), { id, createdAt: now, updatedAt: now });
|
|
2245
|
+
this.mcps.push(newMCP);
|
|
2246
|
+
yield this.saveMCPs();
|
|
2247
|
+
return newMCP;
|
|
2248
|
+
});
|
|
2249
|
+
}
|
|
2250
|
+
updateMCP(id, mcp) {
|
|
2251
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2252
|
+
const index = this.mcps.findIndex(m => m.id === id);
|
|
2253
|
+
if (index === -1)
|
|
2254
|
+
return false;
|
|
2255
|
+
const now = Date.now();
|
|
2256
|
+
this.mcps[index] = Object.assign(Object.assign(Object.assign({}, this.mcps[index]), mcp), { id, updatedAt: now });
|
|
2257
|
+
yield this.saveMCPs();
|
|
2258
|
+
return true;
|
|
2259
|
+
});
|
|
2260
|
+
}
|
|
2261
|
+
deleteMCP(id) {
|
|
2262
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2263
|
+
const index = this.mcps.findIndex(m => m.id === id);
|
|
2264
|
+
if (index === -1)
|
|
2265
|
+
return false;
|
|
2266
|
+
this.mcps.splice(index, 1);
|
|
2267
|
+
yield this.saveMCPs();
|
|
2268
|
+
return true;
|
|
2269
|
+
});
|
|
2270
|
+
}
|
|
2030
2271
|
// Close method for compatibility (no-op for filesystem database)
|
|
2031
2272
|
close() {
|
|
2032
2273
|
// 文件系统数据库不需要关闭连接
|