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.
Files changed (2) hide show
  1. package/dist/index.js +126 -58
  2. 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.11",
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 nameExists = config.providers.some((p) => p.name === input.name);
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(input.name);
1229
+ throw new ProviderNameConflictError(normalizedInput.name);
1201
1230
  }
1202
1231
  const timestamp = Date.now();
1203
1232
  const provider = {
1204
1233
  id: generateId(),
1205
- name: input.name,
1206
- desc: input.desc,
1207
- baseUrl: input.baseUrl,
1208
- apiKey: input.apiKey,
1209
- model: input.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
- return config.providers.find((p) => p.name.toLowerCase() === lowerName);
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 (updates.name !== void 0 && updates.name !== provider.name) {
1266
- const nameConflict = config.providers.some((p) => p.id !== id && p.name === updates.name);
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(updates.name);
1303
+ throw new ProviderNameConflictError(normalizedUpdates.name);
1269
1304
  }
1270
1305
  }
1271
- if (updates.name !== void 0)
1272
- provider.name = updates.name;
1273
- if (updates.desc !== void 0)
1274
- provider.desc = updates.desc;
1275
- if (updates.baseUrl !== void 0)
1276
- provider.baseUrl = updates.baseUrl;
1277
- if (updates.apiKey !== void 0)
1278
- provider.apiKey = updates.apiKey;
1279
- if (updates.model !== void 0)
1280
- provider.model = updates.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 nameExists = config.providers.some((p) => p.name === newName);
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(newName);
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: newName,
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 === input.name);
1381
+ const nameExists = allPresets.some((p) => p.name.trim() === normalizedInput.name);
1334
1382
  if (nameExists) {
1335
- throw new PresetNameConflictError(input.name);
1383
+ throw new PresetNameConflictError(normalizedInput.name);
1336
1384
  }
1337
1385
  const preset = {
1338
- name: input.name,
1339
- baseUrl: input.baseUrl,
1340
- description: input.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 === 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: ${name}`);
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 (updates.name !== void 0 && updates.name !== preset.name) {
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 !== name && p.name === updates.name);
1431
+ const nameConflict = allPresets.some((p) => p.name.trim() !== normalizedName && p.name.trim() === normalizedUpdates.name);
1374
1432
  if (nameConflict) {
1375
- throw new PresetNameConflictError(updates.name);
1433
+ throw new PresetNameConflictError(normalizedUpdates.name);
1376
1434
  }
1377
1435
  }
1378
- if (updates.name !== void 0)
1379
- preset.name = updates.name;
1380
- if (updates.baseUrl !== void 0)
1381
- preset.baseUrl = updates.baseUrl;
1382
- if (updates.description !== void 0)
1383
- preset.description = updates.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 === name);
1454
+ const index = config.presets.findIndex((p) => p.name.trim() === normalizedName);
1396
1455
  if (index === -1) {
1397
- throw new Error(`Preset not found: ${name}`);
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 = syncConfig;
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
- if (!value) return "API \u5730\u5740\u4E0D\u80FD\u4E3A\u7A7A";
3283
- if (!value.startsWith("http://") && !value.startsWith("https://")) {
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([
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccman",
3
- "version": "3.3.11",
3
+ "version": "3.3.12",
4
4
  "type": "module",
5
5
  "description": "Manage Codex, Claude Code, Gemini CLI, OpenCode, and MCP API service provider configurations",
6
6
  "main": "./dist/index.js",