ccman 3.3.15 → 3.3.17

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 +189 -40
  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.15",
18
+ version: "3.3.17",
19
19
  type: "module",
20
20
  description: "Core business logic for ccman - Manage Codex, Claude Code, Gemini CLI, OpenCode, OpenClaw, and MCP configurations",
21
21
  main: "./dist/index.js",
@@ -260,6 +260,13 @@ function backupFile(filePath) {
260
260
  fs.chmodSync(backupPath, 384);
261
261
  return backupPath;
262
262
  }
263
+ function backupFileOrThrow(filePath, operation) {
264
+ try {
265
+ return backupFile(filePath);
266
+ } catch (error) {
267
+ throw new Error(`\u5907\u4EFD\u5931\u8D25\uFF0C\u5DF2\u4E2D\u6B62\u540E\u7EED\u5199\u5165\uFF08${operation}\uFF09: ${error.message}`);
268
+ }
269
+ }
263
270
  var init_file = __esm({
264
271
  "../core/dist/utils/file.js"() {
265
272
  "use strict";
@@ -306,12 +313,6 @@ function loadCodexTemplateConfig() {
306
313
  function writeCodexConfig(provider) {
307
314
  ensureDir(getCodexDir());
308
315
  const configPath = getCodexConfigPath();
309
- if (fileExists(configPath)) {
310
- try {
311
- backupFile(configPath);
312
- } catch {
313
- }
314
- }
315
316
  const templateConfig = loadCodexTemplateConfig();
316
317
  const nextConfig = { ...templateConfig };
317
318
  if (nextConfig.features && typeof nextConfig.features === "object" && !Array.isArray(nextConfig.features) && "web_search_request" in nextConfig.features) {
@@ -333,12 +334,6 @@ function writeCodexConfig(provider) {
333
334
  };
334
335
  fs2.writeFileSync(configPath, stringifyToml(nextConfig), { mode: 384 });
335
336
  const authPath = getCodexAuthPath();
336
- if (fileExists(authPath)) {
337
- try {
338
- backupFile(authPath);
339
- } catch {
340
- }
341
- }
342
337
  const auth = { OPENAI_API_KEY: provider.apiKey };
343
338
  writeJSON(authPath, auth);
344
339
  }
@@ -894,7 +889,9 @@ function saveEnvFile(envPath, env) {
894
889
  lines.push(`${key}=${String(env[key])}`);
895
890
  }
896
891
  const content = lines.join("\n") + (lines.length ? "\n" : "");
897
- fs5.writeFileSync(envPath, content, { mode: 384 });
892
+ const tempPath = `${envPath}.tmp`;
893
+ fs5.writeFileSync(tempPath, content, { mode: 384 });
894
+ fs5.renameSync(tempPath, envPath);
898
895
  }
899
896
  function writeGeminiConfig(provider) {
900
897
  const settingsPath = getGeminiSettingsPath();
@@ -2209,6 +2206,7 @@ function backupConfig(configPath, keepCount = 3) {
2209
2206
  const timestamp = Date.now();
2210
2207
  const backupPath = `${configPath}.backup.${timestamp}`;
2211
2208
  fs9.copyFileSync(configPath, backupPath);
2209
+ fs9.chmodSync(backupPath, 384);
2212
2210
  cleanupOldBackups(configPath, keepCount);
2213
2211
  return backupPath;
2214
2212
  }
@@ -2582,6 +2580,9 @@ function exportConfig(targetDir) {
2582
2580
  const src = path12.join(ccmanDir2, file);
2583
2581
  const dst = path12.join(targetDir, file);
2584
2582
  if (fileExists(src)) {
2583
+ if (fileExists(dst)) {
2584
+ backupFileOrThrow(dst, `export.${file}`);
2585
+ }
2585
2586
  fs11.copyFileSync(src, dst);
2586
2587
  exportedFiles.push(file);
2587
2588
  }
@@ -2658,8 +2659,13 @@ function getFileSize(filePath) {
2658
2659
  function backupFile2(filePath) {
2659
2660
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/:/g, "-").split(".")[0];
2660
2661
  const backupPath = `${filePath}.backup-${timestamp}`;
2661
- fs12.copyFileSync(filePath, backupPath);
2662
- return backupPath;
2662
+ try {
2663
+ fs12.copyFileSync(filePath, backupPath);
2664
+ fs12.chmodSync(backupPath, 384);
2665
+ return backupPath;
2666
+ } catch (error) {
2667
+ throw new Error(`\u5907\u4EFD\u5931\u8D25\uFF0C\u5DF2\u4E2D\u6B62\u540E\u7EED\u5199\u5165\uFF08claude-clean\uFF09: ${error.message}`);
2668
+ }
2663
2669
  }
2664
2670
  function saveJsonAtomic(filePath, data) {
2665
2671
  const tempPath = `${filePath}.tmp`;
@@ -3289,8 +3295,8 @@ function downloadCommand(program2) {
3289
3295
  console.log();
3290
3296
  if (backupPaths.length > 0) {
3291
3297
  console.log(chalk7.gray("\u672C\u5730\u5907\u4EFD:"));
3292
- backupPaths.forEach((path15) => {
3293
- console.log(chalk7.gray(` ${path15}`));
3298
+ backupPaths.forEach((path16) => {
3299
+ console.log(chalk7.gray(` ${path16}`));
3294
3300
  });
3295
3301
  console.log();
3296
3302
  }
@@ -3351,8 +3357,8 @@ function mergeCommand(program2) {
3351
3357
  console.log();
3352
3358
  if (result.backupPaths.length > 0) {
3353
3359
  console.log(chalk8.gray("\u5907\u4EFD:"));
3354
- result.backupPaths.forEach((path15) => {
3355
- console.log(chalk8.gray(` ${path15}`));
3360
+ result.backupPaths.forEach((path16) => {
3361
+ console.log(chalk8.gray(` ${path16}`));
3356
3362
  });
3357
3363
  console.log();
3358
3364
  }
@@ -7141,13 +7147,23 @@ function importCommand(program2) {
7141
7147
 
7142
7148
  // src/commands/gmn.ts
7143
7149
  init_dist2();
7150
+ import fs13 from "fs";
7151
+ import path15 from "path";
7144
7152
  import chalk54 from "chalk";
7145
7153
  import inquirer38 from "inquirer";
7146
7154
  var DEFAULT_PROVIDER_NAME2 = "gmn";
7147
7155
  var VALID_PLATFORMS = ["codex", "opencode", "openclaw"];
7148
7156
  var DEFAULT_PLATFORMS = ["codex", "opencode"];
7149
- var GMN_OPENAI_BASE_URL = "https://gmn.chuangzuoli.com";
7150
- var GMN_OPENCLAW_BASE_URL = "https://gmn.chuangzuoli.com/v1";
7157
+ var GMN_PROFILE = {
7158
+ commandName: "gmn",
7159
+ title: "GMN",
7160
+ openaiBaseUrl: "https://gmn.chuangzuoli.com"
7161
+ };
7162
+ var GMN1_PROFILE = {
7163
+ commandName: "gmn1",
7164
+ title: "GMN1",
7165
+ openaiBaseUrl: "https://gmncode.cn"
7166
+ };
7151
7167
  var TOTAL_STEPS = 3;
7152
7168
  function renderStep(current, total, title) {
7153
7169
  const barLength = total;
@@ -7155,7 +7171,7 @@ function renderStep(current, total, title) {
7155
7171
  const bar = `${"\u25A0".repeat(filledLength)}${"\u25A1".repeat(barLength - filledLength)}`;
7156
7172
  return `\u6B65\u9AA4 ${current}/${total} [${bar}] ${title}`;
7157
7173
  }
7158
- function printBanner() {
7174
+ function printBanner(title) {
7159
7175
  printLogo();
7160
7176
  console.log(
7161
7177
  chalk54.cyanBright(
@@ -7166,7 +7182,7 @@ function printBanner() {
7166
7182
  " \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2588\u2588\u2554\u255D\u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551",
7167
7183
  " \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551 \u255A\u2550\u255D \u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551",
7168
7184
  " \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D",
7169
- " CCMAN GMN \u4E00\u952E\u914D\u7F6E\u5411\u5BFC"
7185
+ ` CCMAN ${title} \u4E00\u952E\u914D\u7F6E\u5411\u5BFC`
7170
7186
  ].join("\n")
7171
7187
  )
7172
7188
  );
@@ -7217,12 +7233,12 @@ function parsePlatforms(platformArg) {
7217
7233
  }
7218
7234
  return platforms;
7219
7235
  }
7220
- async function promptApiKey() {
7236
+ async function promptApiKey(title) {
7221
7237
  const answers = await inquirer38.prompt([
7222
7238
  {
7223
7239
  type: "password",
7224
7240
  name: "apiKey",
7225
- message: "\u8BF7\u8F93\u5165 GMN API Key:",
7241
+ message: `\u8BF7\u8F93\u5165 ${title} API Key:`,
7226
7242
  mask: "*",
7227
7243
  validate: (value) => {
7228
7244
  if (!value?.trim()) return "API Key \u4E0D\u80FD\u4E3A\u7A7A";
@@ -7232,7 +7248,7 @@ async function promptApiKey() {
7232
7248
  ]);
7233
7249
  return answers.apiKey.trim();
7234
7250
  }
7235
- async function promptPlatforms() {
7251
+ async function promptPlatforms(title) {
7236
7252
  const answers = await inquirer38.prompt([
7237
7253
  {
7238
7254
  type: "checkbox",
@@ -7242,7 +7258,7 @@ async function promptPlatforms() {
7242
7258
  choices: [
7243
7259
  { name: "Codex\uFF08\u9700\u5355\u72EC\u8BA2\u9605 OpenAI \u5957\u9910\uFF09", value: "codex" },
7244
7260
  { name: "OpenCode\uFF08\u4E0E Codex \u5171\u4EAB OpenAI \u5957\u9910\uFF09", value: "opencode" },
7245
- { name: "OpenClaw\uFF08GMN /v1 \u7AEF\u70B9\uFF0C\u9ED8\u8BA4\u4E0D\u9009\u4E2D\uFF09", value: "openclaw" },
7261
+ { name: `OpenClaw\uFF08${title} /v1 \u7AEF\u70B9\uFF0C\u9ED8\u8BA4\u4E0D\u9009\u4E2D\uFF09`, value: "openclaw" },
7246
7262
  { name: "\u5168\u90E8\uFF08\u5C06\u4F9D\u6B21\u914D\u7F6E Codex\u3001OpenCode\u3001OpenClaw\uFF09", value: "all" }
7247
7263
  ],
7248
7264
  default: DEFAULT_PLATFORMS,
@@ -7258,11 +7274,11 @@ async function promptPlatforms() {
7258
7274
  }
7259
7275
  return selected;
7260
7276
  }
7261
- async function resolvePlatforms(platformArg) {
7277
+ async function resolvePlatforms(platformArg, title = "GMN") {
7262
7278
  if (platformArg && platformArg.trim().length > 0) {
7263
7279
  return parsePlatforms(platformArg);
7264
7280
  }
7265
- return promptPlatforms();
7281
+ return promptPlatforms(title);
7266
7282
  }
7267
7283
  function resolveProviderName2(providerNameArg) {
7268
7284
  if (providerNameArg === void 0) {
@@ -7283,14 +7299,84 @@ function findPreferredProvider(providers, targetName) {
7283
7299
  const lowerTarget = targetName.toLowerCase();
7284
7300
  return providers.find((p) => p.name.trim().toLowerCase() === lowerTarget);
7285
7301
  }
7286
- async function gmnCommand(apiKey, platformArg, providerNameArg) {
7287
- printBanner();
7302
+ function getPlatformTargetFiles(platform) {
7303
+ const ccmanDir2 = getCcmanDir();
7304
+ switch (platform) {
7305
+ case "codex":
7306
+ return [path15.join(ccmanDir2, "codex.json"), getCodexConfigPath(), getCodexAuthPath()];
7307
+ case "opencode":
7308
+ return [path15.join(ccmanDir2, "opencode.json"), getOpenCodeConfigPath()];
7309
+ case "openclaw":
7310
+ return [
7311
+ path15.join(ccmanDir2, "openclaw.json"),
7312
+ getOpenClawConfigPath(),
7313
+ getOpenClawModelsPath()
7314
+ ];
7315
+ }
7316
+ }
7317
+ function createPlatformBackupOrThrow(platform, backupRootDir) {
7318
+ const backupDir = path15.join(backupRootDir, platform);
7319
+ const entries = [];
7320
+ const targetFiles = getPlatformTargetFiles(platform);
7321
+ fs13.mkdirSync(backupDir, { recursive: true, mode: 448 });
7322
+ for (const [index, originalPath] of targetFiles.entries()) {
7323
+ const existed = fs13.existsSync(originalPath);
7324
+ if (!existed) {
7325
+ entries.push({ originalPath, backupPath: null, existed: false });
7326
+ continue;
7327
+ }
7328
+ const fileName = path15.basename(originalPath).replace(/[^\w.-]/g, "_");
7329
+ const backupPath = path15.join(backupDir, `${String(index).padStart(2, "0")}-${fileName}.bak`);
7330
+ try {
7331
+ fs13.copyFileSync(originalPath, backupPath);
7332
+ fs13.chmodSync(backupPath, 384);
7333
+ entries.push({ originalPath, backupPath, existed: true });
7334
+ } catch (error) {
7335
+ throw new Error(`\u5907\u4EFD\u5931\u8D25\uFF0C\u5DF2\u4E2D\u6B62\u540E\u7EED\u5199\u5165\uFF08${platform}\uFF09: ${error.message}`);
7336
+ }
7337
+ }
7338
+ const manifestPath = path15.join(backupDir, "manifest.json");
7339
+ const manifest = {
7340
+ platform,
7341
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
7342
+ entries
7343
+ };
7344
+ fs13.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2), { mode: 384 });
7345
+ return { backupDir, entries };
7346
+ }
7347
+ function rollbackFromBackupOrThrow(result) {
7348
+ const errors = [];
7349
+ for (const entry of result.entries) {
7350
+ try {
7351
+ if (entry.existed) {
7352
+ if (!entry.backupPath || !fs13.existsSync(entry.backupPath)) {
7353
+ throw new Error(`\u5907\u4EFD\u6587\u4EF6\u7F3A\u5931: ${entry.backupPath || entry.originalPath}`);
7354
+ }
7355
+ fs13.mkdirSync(path15.dirname(entry.originalPath), { recursive: true });
7356
+ fs13.copyFileSync(entry.backupPath, entry.originalPath);
7357
+ } else if (fs13.existsSync(entry.originalPath)) {
7358
+ fs13.rmSync(entry.originalPath, { force: true });
7359
+ }
7360
+ } catch (error) {
7361
+ errors.push(`${entry.originalPath}: ${error.message}`);
7362
+ }
7363
+ }
7364
+ if (errors.length > 0) {
7365
+ throw new Error(`\u56DE\u6EDA\u5931\u8D25: ${errors.join("; ")}`);
7366
+ }
7367
+ }
7368
+ function buildOpenClawBaseUrl(openaiBaseUrl) {
7369
+ const normalized = openaiBaseUrl.replace(/\/+$/, "");
7370
+ return `${normalized}/v1`;
7371
+ }
7372
+ async function runGmnCommand(profile, apiKey, platformArg, providerNameArg) {
7373
+ printBanner(profile.title);
7288
7374
  let platforms;
7289
7375
  let providerName;
7290
7376
  try {
7291
7377
  console.log(chalk54.cyan(`
7292
7378
  ${renderStep(1, TOTAL_STEPS, "\u9009\u62E9\u8981\u914D\u7F6E\u7684\u5DE5\u5177")}`));
7293
- platforms = await resolvePlatforms(platformArg);
7379
+ platforms = await resolvePlatforms(platformArg, profile.title);
7294
7380
  providerName = resolveProviderName2(providerNameArg);
7295
7381
  } catch (error) {
7296
7382
  console.error(chalk54.red(`\u274C ${error.message}`));
@@ -7303,7 +7389,7 @@ ${renderStep(1, TOTAL_STEPS, "\u9009\u62E9\u8981\u914D\u7F6E\u7684\u5DE5\u5177")
7303
7389
  console.log(chalk54.cyan(`
7304
7390
  ${renderStep(2, TOTAL_STEPS, "\u8F93\u5165 API Key")}`));
7305
7391
  if (!resolvedApiKey) {
7306
- resolvedApiKey = await promptApiKey();
7392
+ resolvedApiKey = await promptApiKey(profile.title);
7307
7393
  } else {
7308
7394
  console.log(chalk54.gray("\u5DF2\u901A\u8FC7\u53C2\u6570\u63D0\u4F9B API Key\uFF08\u5DF2\u9690\u85CF\uFF09"));
7309
7395
  }
@@ -7311,11 +7397,12 @@ ${renderStep(2, TOTAL_STEPS, "\u8F93\u5165 API Key")}`));
7311
7397
  console.error(chalk54.red("\u274C \u9519\u8BEF: API Key \u4E0D\u80FD\u4E3A\u7A7A"));
7312
7398
  process.exit(1);
7313
7399
  }
7314
- const openaiBaseUrl = GMN_OPENAI_BASE_URL;
7400
+ const openaiBaseUrl = profile.openaiBaseUrl;
7401
+ const openclawBaseUrl = buildOpenClawBaseUrl(openaiBaseUrl);
7315
7402
  const platformBaseUrls = {
7316
7403
  codex: openaiBaseUrl,
7317
7404
  opencode: openaiBaseUrl,
7318
- openclaw: GMN_OPENCLAW_BASE_URL
7405
+ openclaw: openclawBaseUrl
7319
7406
  };
7320
7407
  console.log(chalk54.cyan(`
7321
7408
  ${renderStep(3, TOTAL_STEPS, "\u5F00\u59CB\u5199\u5165\u914D\u7F6E")}`));
@@ -7324,10 +7411,18 @@ ${renderStep(3, TOTAL_STEPS, "\u5F00\u59CB\u5199\u5165\u914D\u7F6E")}`));
7324
7411
  console.log(chalk54.gray(`OpenAI Base URL: ${openaiBaseUrl}`));
7325
7412
  }
7326
7413
  if (platforms.includes("openclaw")) {
7327
- console.log(chalk54.gray(`OpenClaw Base URL: ${GMN_OPENCLAW_BASE_URL}`));
7414
+ console.log(chalk54.gray(`OpenClaw Base URL: ${openclawBaseUrl}`));
7328
7415
  }
7329
7416
  printWriteTargets(platforms);
7330
7417
  console.log();
7418
+ const backupRootDir = path15.join(
7419
+ getCcmanDir(),
7420
+ "backups",
7421
+ `${profile.commandName}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`
7422
+ );
7423
+ fs13.mkdirSync(backupRootDir, { recursive: true, mode: 448 });
7424
+ console.log(chalk54.gray(`\u5907\u4EFD\u6839\u76EE\u5F55: ${backupRootDir}`));
7425
+ console.log();
7331
7426
  const ALL_TOOLS = {
7332
7427
  codex: { name: "Codex", manager: createCodexManager() },
7333
7428
  opencode: { name: "OpenCode", manager: createOpenCodeManager() },
@@ -7337,24 +7432,74 @@ ${renderStep(3, TOTAL_STEPS, "\u5F00\u59CB\u5199\u5165\u914D\u7F6E")}`));
7337
7432
  platform,
7338
7433
  ...ALL_TOOLS[platform]
7339
7434
  }));
7435
+ const successBackups = [];
7340
7436
  let completed = 0;
7341
7437
  for (const { platform, name, manager } of tools) {
7438
+ let backupResult = null;
7342
7439
  try {
7343
7440
  console.log(chalk54.gray(`\u2192 \u914D\u7F6E ${name}...`));
7441
+ backupResult = createPlatformBackupOrThrow(platform, backupRootDir);
7442
+ const backupFiles = backupResult.entries.map((entry) => entry.backupPath).filter((p) => p !== null);
7443
+ if (backupFiles.length > 0) {
7444
+ console.log(chalk54.gray(` \u5DF2\u5907\u4EFD ${backupFiles.length} \u4E2A\u6587\u4EF6`));
7445
+ } else {
7446
+ console.log(chalk54.gray(" \u65E0\u5386\u53F2\u6587\u4EF6\u53EF\u5907\u4EFD"));
7447
+ }
7344
7448
  const baseUrl = platformBaseUrls[platform];
7345
7449
  const existing = findPreferredProvider(manager.list(), providerName);
7346
7450
  const provider = existing ? manager.edit(existing.id, { name: providerName, baseUrl, apiKey: resolvedApiKey }) : manager.add({ name: providerName, baseUrl, apiKey: resolvedApiKey });
7347
7451
  manager.switch(provider.id);
7348
7452
  completed += 1;
7349
7453
  console.log(chalk54.green(`\u2705 ${name}`));
7454
+ successBackups.push({
7455
+ name,
7456
+ backupDir: backupResult.backupDir,
7457
+ backupFiles
7458
+ });
7350
7459
  } catch (error) {
7351
- console.error(chalk54.red(`\u274C ${name}: ${error.message}`));
7460
+ const operationError = error;
7461
+ if (backupResult !== null) {
7462
+ try {
7463
+ rollbackFromBackupOrThrow(backupResult);
7464
+ console.error(chalk54.red(`\u274C ${name}: ${operationError.message}\uFF08\u5DF2\u56DE\u6EDA\u5386\u53F2\u6587\u4EF6\uFF09`));
7465
+ } catch (rollbackError) {
7466
+ console.error(
7467
+ chalk54.red(
7468
+ `\u274C ${name}: ${operationError.message}\uFF1B\u56DE\u6EDA\u4E5F\u5931\u8D25: ${rollbackError.message}`
7469
+ )
7470
+ );
7471
+ }
7472
+ } else {
7473
+ console.error(chalk54.red(`\u274C ${name}: ${operationError.message}`));
7474
+ }
7352
7475
  }
7353
7476
  }
7354
7477
  console.log(chalk54.green(`
7355
- \u{1F389} GMN \u914D\u7F6E\u5B8C\u6210\uFF01(${completed}/${tools.length})`));
7478
+ \u{1F389} ${profile.title} \u914D\u7F6E\u5B8C\u6210\uFF01(${completed}/${tools.length})`));
7479
+ console.log();
7480
+ console.log(chalk54.bold("\u5907\u4EFD\u4FE1\u606F:"));
7481
+ if (successBackups.length === 0) {
7482
+ console.log(chalk54.gray(" \u65E0\u6210\u529F\u914D\u7F6E\u9879\uFF0C\u672A\u751F\u6210\u53EF\u7528\u5907\u4EFD\u76EE\u5F55\u3002"));
7483
+ } else {
7484
+ for (const item of successBackups) {
7485
+ console.log(chalk54.gray(` ${item.name}: ${item.backupDir}`));
7486
+ if (item.backupFiles.length === 0) {
7487
+ console.log(chalk54.gray(" - \u65E0\u5386\u53F2\u6587\u4EF6\u53EF\u5907\u4EFD"));
7488
+ } else {
7489
+ for (const file of item.backupFiles) {
7490
+ console.log(chalk54.gray(` - ${file}`));
7491
+ }
7492
+ }
7493
+ }
7494
+ }
7356
7495
  console.log(chalk54.gray("\u63D0\u793A\uFF1A\u8BF7\u91CD\u542F\u5BF9\u5E94\u5DE5\u5177/\u63D2\u4EF6\u4EE5\u4F7F\u914D\u7F6E\u751F\u6548\u3002"));
7357
7496
  }
7497
+ async function gmnCommand(apiKey, platformArg, providerNameArg) {
7498
+ await runGmnCommand(GMN_PROFILE, apiKey, platformArg, providerNameArg);
7499
+ }
7500
+ async function gmn1Command(apiKey, platformArg, providerNameArg) {
7501
+ await runGmnCommand(GMN1_PROFILE, apiKey, platformArg, providerNameArg);
7502
+ }
7358
7503
 
7359
7504
  // src/index.ts
7360
7505
  init_dist2();
@@ -7390,7 +7535,8 @@ program.on("command:*", (operands) => {
7390
7535
  "sync",
7391
7536
  "export",
7392
7537
  "import",
7393
- "gmn"
7538
+ "gmn",
7539
+ "gmn1"
7394
7540
  ];
7395
7541
  const suggestions = availableCommands.filter(
7396
7542
  (cmd) => cmd.includes(unknownCommand) || unknownCommand.includes(cmd)
@@ -7452,6 +7598,9 @@ importCommand(program);
7452
7598
  program.command("gmn [apiKey]").description("\u914D\u7F6E GMN \u5230 Codex\u3001OpenCode\u3001OpenClaw").option("-p, --platform <platforms>", "\u6307\u5B9A\u5E73\u53F0 (codex,opencode,openclaw,all)").option("-n, --name <providerName>", "\u6307\u5B9A\u670D\u52A1\u5546\u540D\u79F0\uFF08\u9ED8\u8BA4: gmn\uFF09").action(async (apiKey, options) => {
7453
7599
  await gmnCommand(apiKey, options.platform, options.name);
7454
7600
  });
7601
+ program.command("gmn1 [apiKey]").description("\u914D\u7F6E GMN1 \u5230 Codex\u3001OpenCode\u3001OpenClaw\uFF08\u9ED8\u8BA4 URL: https://gmncode.cn\uFF09").option("-p, --platform <platforms>", "\u6307\u5B9A\u5E73\u53F0 (codex,opencode,openclaw,all)").option("-n, --name <providerName>", "\u6307\u5B9A\u670D\u52A1\u5546\u540D\u79F0\uFF08\u9ED8\u8BA4: gmn\uFF09").action(async (apiKey, options) => {
7602
+ await gmn1Command(apiKey, options.platform, options.name);
7603
+ });
7455
7604
  (async () => {
7456
7605
  if (!process.argv.slice(2).length) {
7457
7606
  printLogo();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccman",
3
- "version": "3.3.15",
3
+ "version": "3.3.17",
4
4
  "type": "module",
5
5
  "description": "Manage Codex, Claude Code, Gemini CLI, OpenCode, OpenClaw, and MCP API service provider configurations",
6
6
  "main": "./dist/index.js",