ccman 3.3.11 → 3.3.12
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/dist/index.js +126 -58
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -15,7 +15,7 @@ var init_package = __esm({
|
|
|
15
15
|
"../core/package.json"() {
|
|
16
16
|
package_default = {
|
|
17
17
|
name: "@ccman/core",
|
|
18
|
-
version: "3.3.
|
|
18
|
+
version: "3.3.12",
|
|
19
19
|
type: "module",
|
|
20
20
|
description: "Core business logic for ccman - Manage Codex, Claude Code, Gemini CLI, and MCP configurations",
|
|
21
21
|
main: "./dist/index.js",
|
|
@@ -1192,21 +1192,50 @@ function createToolManager(tool) {
|
|
|
1192
1192
|
}
|
|
1193
1193
|
writeJSON(configPath, config);
|
|
1194
1194
|
}
|
|
1195
|
+
function trimInput(value) {
|
|
1196
|
+
if (value === void 0)
|
|
1197
|
+
return void 0;
|
|
1198
|
+
return value.trim();
|
|
1199
|
+
}
|
|
1200
|
+
function trimProvider(input) {
|
|
1201
|
+
return {
|
|
1202
|
+
...input,
|
|
1203
|
+
name: input.name.trim(),
|
|
1204
|
+
desc: trimInput(input.desc),
|
|
1205
|
+
baseUrl: input.baseUrl.trim(),
|
|
1206
|
+
apiKey: input.apiKey.trim(),
|
|
1207
|
+
model: trimInput(input.model)
|
|
1208
|
+
};
|
|
1209
|
+
}
|
|
1210
|
+
function trimProviderUpdates(updates) {
|
|
1211
|
+
return {
|
|
1212
|
+
...updates,
|
|
1213
|
+
name: trimInput(updates.name),
|
|
1214
|
+
desc: trimInput(updates.desc),
|
|
1215
|
+
baseUrl: trimInput(updates.baseUrl),
|
|
1216
|
+
apiKey: trimInput(updates.apiKey),
|
|
1217
|
+
model: trimInput(updates.model)
|
|
1218
|
+
};
|
|
1219
|
+
}
|
|
1195
1220
|
return {
|
|
1196
1221
|
add(input) {
|
|
1197
1222
|
const config = loadConfig2();
|
|
1198
|
-
const
|
|
1223
|
+
const normalizedInput = trimProvider(input);
|
|
1224
|
+
if (!normalizedInput.name) {
|
|
1225
|
+
throw new Error("\u670D\u52A1\u5546\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A");
|
|
1226
|
+
}
|
|
1227
|
+
const nameExists = config.providers.some((p) => p.name.trim() === normalizedInput.name);
|
|
1199
1228
|
if (nameExists) {
|
|
1200
|
-
throw new ProviderNameConflictError(
|
|
1229
|
+
throw new ProviderNameConflictError(normalizedInput.name);
|
|
1201
1230
|
}
|
|
1202
1231
|
const timestamp = Date.now();
|
|
1203
1232
|
const provider = {
|
|
1204
1233
|
id: generateId(),
|
|
1205
|
-
name:
|
|
1206
|
-
desc:
|
|
1207
|
-
baseUrl:
|
|
1208
|
-
apiKey:
|
|
1209
|
-
model:
|
|
1234
|
+
name: normalizedInput.name,
|
|
1235
|
+
desc: normalizedInput.desc,
|
|
1236
|
+
baseUrl: normalizedInput.baseUrl,
|
|
1237
|
+
apiKey: normalizedInput.apiKey,
|
|
1238
|
+
model: normalizedInput.model,
|
|
1210
1239
|
createdAt: timestamp,
|
|
1211
1240
|
lastModified: timestamp
|
|
1212
1241
|
};
|
|
@@ -1231,8 +1260,10 @@ function createToolManager(tool) {
|
|
|
1231
1260
|
},
|
|
1232
1261
|
findByName(name) {
|
|
1233
1262
|
const config = loadConfig2();
|
|
1234
|
-
const lowerName = name.toLowerCase();
|
|
1235
|
-
|
|
1263
|
+
const lowerName = name.trim().toLowerCase();
|
|
1264
|
+
if (!lowerName)
|
|
1265
|
+
return void 0;
|
|
1266
|
+
return config.providers.find((p) => p.name.trim().toLowerCase() === lowerName);
|
|
1236
1267
|
},
|
|
1237
1268
|
switch(id) {
|
|
1238
1269
|
const config = loadConfig2();
|
|
@@ -1259,25 +1290,29 @@ function createToolManager(tool) {
|
|
|
1259
1290
|
edit(id, updates) {
|
|
1260
1291
|
const config = loadConfig2();
|
|
1261
1292
|
const provider = config.providers.find((p) => p.id === id);
|
|
1293
|
+
const normalizedUpdates = trimProviderUpdates(updates);
|
|
1262
1294
|
if (!provider) {
|
|
1263
1295
|
throw new ProviderNotFoundError(id);
|
|
1264
1296
|
}
|
|
1265
|
-
if (
|
|
1266
|
-
|
|
1297
|
+
if (normalizedUpdates.name !== void 0 && !normalizedUpdates.name) {
|
|
1298
|
+
throw new Error("\u670D\u52A1\u5546\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A");
|
|
1299
|
+
}
|
|
1300
|
+
if (normalizedUpdates.name !== void 0 && normalizedUpdates.name !== provider.name.trim()) {
|
|
1301
|
+
const nameConflict = config.providers.some((p) => p.id !== id && p.name.trim() === normalizedUpdates.name);
|
|
1267
1302
|
if (nameConflict) {
|
|
1268
|
-
throw new ProviderNameConflictError(
|
|
1303
|
+
throw new ProviderNameConflictError(normalizedUpdates.name);
|
|
1269
1304
|
}
|
|
1270
1305
|
}
|
|
1271
|
-
if (
|
|
1272
|
-
provider.name =
|
|
1273
|
-
if (
|
|
1274
|
-
provider.desc =
|
|
1275
|
-
if (
|
|
1276
|
-
provider.baseUrl =
|
|
1277
|
-
if (
|
|
1278
|
-
provider.apiKey =
|
|
1279
|
-
if (
|
|
1280
|
-
provider.model =
|
|
1306
|
+
if (normalizedUpdates.name !== void 0)
|
|
1307
|
+
provider.name = normalizedUpdates.name;
|
|
1308
|
+
if (normalizedUpdates.desc !== void 0)
|
|
1309
|
+
provider.desc = normalizedUpdates.desc;
|
|
1310
|
+
if (normalizedUpdates.baseUrl !== void 0)
|
|
1311
|
+
provider.baseUrl = normalizedUpdates.baseUrl;
|
|
1312
|
+
if (normalizedUpdates.apiKey !== void 0)
|
|
1313
|
+
provider.apiKey = normalizedUpdates.apiKey;
|
|
1314
|
+
if (normalizedUpdates.model !== void 0)
|
|
1315
|
+
provider.model = normalizedUpdates.model;
|
|
1281
1316
|
provider.lastModified = Date.now();
|
|
1282
1317
|
saveConfig2(config);
|
|
1283
1318
|
if (config.currentProviderId === id) {
|
|
@@ -1306,15 +1341,19 @@ function createToolManager(tool) {
|
|
|
1306
1341
|
clone(sourceId, newName) {
|
|
1307
1342
|
const source = this.get(sourceId);
|
|
1308
1343
|
const config = loadConfig2();
|
|
1309
|
-
const
|
|
1344
|
+
const normalizedName = newName.trim();
|
|
1345
|
+
if (!normalizedName) {
|
|
1346
|
+
throw new Error("\u670D\u52A1\u5546\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A");
|
|
1347
|
+
}
|
|
1348
|
+
const nameExists = config.providers.some((p) => p.name.trim() === normalizedName);
|
|
1310
1349
|
if (nameExists) {
|
|
1311
|
-
throw new ProviderNameConflictError(
|
|
1350
|
+
throw new ProviderNameConflictError(normalizedName);
|
|
1312
1351
|
}
|
|
1313
1352
|
const timestamp = Date.now();
|
|
1314
1353
|
const newProvider = {
|
|
1315
1354
|
...source,
|
|
1316
1355
|
id: generateId(),
|
|
1317
|
-
name:
|
|
1356
|
+
name: normalizedName,
|
|
1318
1357
|
desc: void 0,
|
|
1319
1358
|
createdAt: timestamp,
|
|
1320
1359
|
lastModified: timestamp,
|
|
@@ -1326,18 +1365,27 @@ function createToolManager(tool) {
|
|
|
1326
1365
|
},
|
|
1327
1366
|
addPreset(input) {
|
|
1328
1367
|
const config = loadConfig2();
|
|
1368
|
+
const normalizedInput = {
|
|
1369
|
+
...input,
|
|
1370
|
+
name: input.name.trim(),
|
|
1371
|
+
baseUrl: input.baseUrl.trim(),
|
|
1372
|
+
description: input.description.trim()
|
|
1373
|
+
};
|
|
1374
|
+
if (!normalizedInput.name) {
|
|
1375
|
+
throw new Error("\u9884\u7F6E\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A");
|
|
1376
|
+
}
|
|
1329
1377
|
if (!config.presets) {
|
|
1330
1378
|
config.presets = [];
|
|
1331
1379
|
}
|
|
1332
1380
|
const allPresets = [...toolConfig.builtinPresets, ...config.presets];
|
|
1333
|
-
const nameExists = allPresets.some((p) => p.name ===
|
|
1381
|
+
const nameExists = allPresets.some((p) => p.name.trim() === normalizedInput.name);
|
|
1334
1382
|
if (nameExists) {
|
|
1335
|
-
throw new PresetNameConflictError(
|
|
1383
|
+
throw new PresetNameConflictError(normalizedInput.name);
|
|
1336
1384
|
}
|
|
1337
1385
|
const preset = {
|
|
1338
|
-
name:
|
|
1339
|
-
baseUrl:
|
|
1340
|
-
description:
|
|
1386
|
+
name: normalizedInput.name,
|
|
1387
|
+
baseUrl: normalizedInput.baseUrl,
|
|
1388
|
+
description: normalizedInput.description
|
|
1341
1389
|
};
|
|
1342
1390
|
config.presets.push(preset);
|
|
1343
1391
|
saveConfig2(config);
|
|
@@ -1361,26 +1409,36 @@ function createToolManager(tool) {
|
|
|
1361
1409
|
},
|
|
1362
1410
|
editPreset(name, updates) {
|
|
1363
1411
|
const config = loadConfig2();
|
|
1412
|
+
const normalizedName = name.trim();
|
|
1413
|
+
const normalizedUpdates = {
|
|
1414
|
+
...updates,
|
|
1415
|
+
name: trimInput(updates.name),
|
|
1416
|
+
baseUrl: trimInput(updates.baseUrl),
|
|
1417
|
+
description: trimInput(updates.description)
|
|
1418
|
+
};
|
|
1364
1419
|
if (!config.presets) {
|
|
1365
1420
|
config.presets = [];
|
|
1366
1421
|
}
|
|
1367
|
-
const preset = config.presets.find((p) => p.name ===
|
|
1422
|
+
const preset = config.presets.find((p) => p.name.trim() === normalizedName);
|
|
1368
1423
|
if (!preset) {
|
|
1369
|
-
throw new Error(`\u9884\u7F6E\u4E0D\u5B58\u5728: ${
|
|
1424
|
+
throw new Error(`\u9884\u7F6E\u4E0D\u5B58\u5728: ${normalizedName}`);
|
|
1425
|
+
}
|
|
1426
|
+
if (normalizedUpdates.name !== void 0 && !normalizedUpdates.name) {
|
|
1427
|
+
throw new Error("\u9884\u7F6E\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A");
|
|
1370
1428
|
}
|
|
1371
|
-
if (
|
|
1429
|
+
if (normalizedUpdates.name !== void 0 && normalizedUpdates.name !== preset.name.trim()) {
|
|
1372
1430
|
const allPresets = [...toolConfig.builtinPresets, ...config.presets];
|
|
1373
|
-
const nameConflict = allPresets.some((p) => p.name !==
|
|
1431
|
+
const nameConflict = allPresets.some((p) => p.name.trim() !== normalizedName && p.name.trim() === normalizedUpdates.name);
|
|
1374
1432
|
if (nameConflict) {
|
|
1375
|
-
throw new PresetNameConflictError(
|
|
1433
|
+
throw new PresetNameConflictError(normalizedUpdates.name);
|
|
1376
1434
|
}
|
|
1377
1435
|
}
|
|
1378
|
-
if (
|
|
1379
|
-
preset.name =
|
|
1380
|
-
if (
|
|
1381
|
-
preset.baseUrl =
|
|
1382
|
-
if (
|
|
1383
|
-
preset.description =
|
|
1436
|
+
if (normalizedUpdates.name !== void 0)
|
|
1437
|
+
preset.name = normalizedUpdates.name;
|
|
1438
|
+
if (normalizedUpdates.baseUrl !== void 0)
|
|
1439
|
+
preset.baseUrl = normalizedUpdates.baseUrl;
|
|
1440
|
+
if (normalizedUpdates.description !== void 0)
|
|
1441
|
+
preset.description = normalizedUpdates.description;
|
|
1384
1442
|
saveConfig2(config);
|
|
1385
1443
|
return {
|
|
1386
1444
|
...preset,
|
|
@@ -1389,12 +1447,13 @@ function createToolManager(tool) {
|
|
|
1389
1447
|
},
|
|
1390
1448
|
removePreset(name) {
|
|
1391
1449
|
const config = loadConfig2();
|
|
1450
|
+
const normalizedName = name.trim();
|
|
1392
1451
|
if (!config.presets) {
|
|
1393
1452
|
return;
|
|
1394
1453
|
}
|
|
1395
|
-
const index = config.presets.findIndex((p) => p.name ===
|
|
1454
|
+
const index = config.presets.findIndex((p) => p.name.trim() === normalizedName);
|
|
1396
1455
|
if (index === -1) {
|
|
1397
|
-
throw new Error(`Preset not found: ${
|
|
1456
|
+
throw new Error(`Preset not found: ${normalizedName}`);
|
|
1398
1457
|
}
|
|
1399
1458
|
config.presets.splice(index, 1);
|
|
1400
1459
|
saveConfig2(config);
|
|
@@ -1534,8 +1593,16 @@ function getSyncConfig() {
|
|
|
1534
1593
|
return config.sync || null;
|
|
1535
1594
|
}
|
|
1536
1595
|
function saveSyncConfig(syncConfig) {
|
|
1596
|
+
const normalizedSyncConfig = {
|
|
1597
|
+
...syncConfig,
|
|
1598
|
+
webdavUrl: syncConfig.webdavUrl.trim(),
|
|
1599
|
+
username: syncConfig.username.trim(),
|
|
1600
|
+
password: syncConfig.password.trim(),
|
|
1601
|
+
remoteDir: syncConfig.remoteDir?.trim(),
|
|
1602
|
+
syncPassword: syncConfig.syncPassword?.trim()
|
|
1603
|
+
};
|
|
1537
1604
|
const config = loadConfig();
|
|
1538
|
-
config.sync =
|
|
1605
|
+
config.sync = normalizedSyncConfig;
|
|
1539
1606
|
saveConfig(config);
|
|
1540
1607
|
}
|
|
1541
1608
|
function updateLastSyncTime() {
|
|
@@ -1570,9 +1637,9 @@ function joinPath(baseDir, filename) {
|
|
|
1570
1637
|
return `${normalizedBase}/${normalizedFile}`;
|
|
1571
1638
|
}
|
|
1572
1639
|
function createWebDAVClient(config) {
|
|
1573
|
-
const client = createClient(config.webdavUrl, {
|
|
1574
|
-
username: config.username,
|
|
1575
|
-
password: config.password,
|
|
1640
|
+
const client = createClient(config.webdavUrl.trim(), {
|
|
1641
|
+
username: config.username.trim(),
|
|
1642
|
+
password: config.password.trim(),
|
|
1576
1643
|
authType: config.authType || "password",
|
|
1577
1644
|
// 默认使用 Basic Auth
|
|
1578
1645
|
maxBodyLength: 100 * 1024 * 1024,
|
|
@@ -3263,7 +3330,7 @@ async function promptProviderForm(defaults) {
|
|
|
3263
3330
|
message: "\u670D\u52A1\u5546\u540D\u79F0:",
|
|
3264
3331
|
default: defaults?.name || void 0,
|
|
3265
3332
|
validate: (value) => {
|
|
3266
|
-
if (!value) return "\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A";
|
|
3333
|
+
if (!value?.trim()) return "\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A";
|
|
3267
3334
|
return true;
|
|
3268
3335
|
}
|
|
3269
3336
|
},
|
|
@@ -3279,8 +3346,9 @@ async function promptProviderForm(defaults) {
|
|
|
3279
3346
|
message: "API \u5730\u5740:",
|
|
3280
3347
|
default: defaults?.baseUrl || void 0,
|
|
3281
3348
|
validate: (value) => {
|
|
3282
|
-
|
|
3283
|
-
if (!
|
|
3349
|
+
const trimmed = value?.trim();
|
|
3350
|
+
if (!trimmed) return "API \u5730\u5740\u4E0D\u80FD\u4E3A\u7A7A";
|
|
3351
|
+
if (!trimmed.startsWith("http://") && !trimmed.startsWith("https://")) {
|
|
3284
3352
|
return "API \u5730\u5740\u5FC5\u987B\u4EE5 http:// \u6216 https:// \u5F00\u5934";
|
|
3285
3353
|
}
|
|
3286
3354
|
return true;
|
|
@@ -3293,16 +3361,16 @@ async function promptProviderForm(defaults) {
|
|
|
3293
3361
|
default: defaults?.apiKey || void 0,
|
|
3294
3362
|
mask: "*",
|
|
3295
3363
|
validate: (value) => {
|
|
3296
|
-
if (!value) return "API \u5BC6\u94A5\u4E0D\u80FD\u4E3A\u7A7A";
|
|
3364
|
+
if (!value?.trim()) return "API \u5BC6\u94A5\u4E0D\u80FD\u4E3A\u7A7A";
|
|
3297
3365
|
return true;
|
|
3298
3366
|
}
|
|
3299
3367
|
}
|
|
3300
3368
|
]);
|
|
3301
3369
|
return {
|
|
3302
|
-
name: answers.name,
|
|
3303
|
-
desc: answers.desc || void 0,
|
|
3304
|
-
baseUrl: answers.baseUrl,
|
|
3305
|
-
apiKey: answers.apiKey
|
|
3370
|
+
name: answers.name.trim(),
|
|
3371
|
+
desc: answers.desc?.trim() || void 0,
|
|
3372
|
+
baseUrl: answers.baseUrl.trim(),
|
|
3373
|
+
apiKey: answers.apiKey.trim()
|
|
3306
3374
|
};
|
|
3307
3375
|
}
|
|
3308
3376
|
async function startMainMenu() {
|
|
@@ -6392,12 +6460,12 @@ async function promptApiKey() {
|
|
|
6392
6460
|
message: "\u8BF7\u8F93\u5165 GMN API Key:",
|
|
6393
6461
|
mask: "*",
|
|
6394
6462
|
validate: (value) => {
|
|
6395
|
-
if (!value) return "API Key \u4E0D\u80FD\u4E3A\u7A7A";
|
|
6463
|
+
if (!value?.trim()) return "API Key \u4E0D\u80FD\u4E3A\u7A7A";
|
|
6396
6464
|
return true;
|
|
6397
6465
|
}
|
|
6398
6466
|
}
|
|
6399
6467
|
]);
|
|
6400
|
-
return answers.apiKey;
|
|
6468
|
+
return answers.apiKey.trim();
|
|
6401
6469
|
}
|
|
6402
6470
|
async function promptPlatforms() {
|
|
6403
6471
|
const answers = await inquirer33.prompt([
|