ccman 3.0.32 → 3.1.0

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 (3) hide show
  1. package/README.md +6 -6
  2. package/dist/index.js +715 -112
  3. package/package.json +4 -4
package/README.md CHANGED
@@ -29,7 +29,7 @@ ccman 的核心功能是自动化配置文件的切换:
29
29
 
30
30
  如果你更喜欢手动编辑配置文件,或者只使用一个服务商从不切换,可能不需要这个工具。
31
31
 
32
- 📖 更多信息:[GitHub 仓库](https://github.com/2ue/ccm) - 包含手动配置方式和详细对比分析
32
+ 📖 更多信息:[GitHub 仓库](https://github.com/2ue/ccman) - 包含手动配置方式和详细对比分析
33
33
 
34
34
  ---
35
35
 
@@ -41,7 +41,7 @@ npm install -g ccman
41
41
 
42
42
  **要求**:Node.js >= 18.0.0
43
43
 
44
- **Desktop 版本**:如果你更喜欢图形界面,可以从 [GitHub Releases](https://github.com/2ue/ccm/releases) 下载 Desktop 应用(macOS/Windows/Linux)。
44
+ **Desktop 版本**:如果你更喜欢图形界面,可以从 [GitHub Releases](https://github.com/2ue/ccman/releases) 下载 Desktop 应用(macOS/Windows/Linux)。
45
45
 
46
46
  ---
47
47
 
@@ -290,7 +290,7 @@ MIT
290
290
 
291
291
  ## 相关链接
292
292
 
293
- - [GitHub 仓库](https://github.com/2ue/ccm)
294
- - [问题反馈](https://github.com/2ue/ccm/issues)
295
- - [更新日志](https://github.com/2ue/ccm/blob/main/CHANGELOG.md)
296
- - [Desktop 版本](https://github.com/2ue/ccm/releases)(图形界面)
293
+ - [GitHub 仓库](https://github.com/2ue/ccman)
294
+ - [问题反馈](https://github.com/2ue/ccman/issues)
295
+ - [更新日志](https://github.com/2ue/ccman/blob/main/CHANGELOG.md)
296
+ - [Desktop 版本](https://github.com/2ue/ccman/releases)(图形界面)
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.0.32",
18
+ version: "3.1.0",
19
19
  type: "module",
20
20
  description: "Core business logic for ccman",
21
21
  main: "./dist/index.js",
@@ -43,12 +43,12 @@ var init_package = __esm({
43
43
  license: "MIT",
44
44
  repository: {
45
45
  type: "git",
46
- url: "https://github.com/2ue/ccm.git",
46
+ url: "https://github.com/2ue/ccman.git",
47
47
  directory: "packages/core"
48
48
  },
49
- homepage: "https://github.com/2ue/ccm#readme",
49
+ homepage: "https://github.com/2ue/ccman#readme",
50
50
  bugs: {
51
- url: "https://github.com/2ue/ccm/issues"
51
+ url: "https://github.com/2ue/ccman/issues"
52
52
  },
53
53
  dependencies: {
54
54
  "@iarna/toml": "^2.2.5",
@@ -77,6 +77,9 @@ function getCodexDir() {
77
77
  function getClaudeDir() {
78
78
  return claudeDir;
79
79
  }
80
+ function getGeminiDir() {
81
+ return geminiDir;
82
+ }
80
83
  function getConfigPath() {
81
84
  return path.join(ccmanDir, "config.json");
82
85
  }
@@ -92,7 +95,13 @@ function getClaudeConfigPath() {
92
95
  function getClaudeJsonPath() {
93
96
  return path.join(rootDir, ".claude.json");
94
97
  }
95
- var isDev, isTest, rootDir, ccmanDir, codexDir, claudeDir;
98
+ function getGeminiSettingsPath() {
99
+ return path.join(geminiDir, "settings.json");
100
+ }
101
+ function getGeminiEnvPath() {
102
+ return path.join(geminiDir, ".env");
103
+ }
104
+ var isDev, isTest, rootDir, ccmanDir, codexDir, claudeDir, geminiDir;
96
105
  var init_paths = __esm({
97
106
  "../core/dist/paths.js"() {
98
107
  "use strict";
@@ -108,6 +117,7 @@ var init_paths = __esm({
108
117
  ccmanDir = path.join(rootDir, ".ccman");
109
118
  codexDir = path.join(rootDir, ".codex");
110
119
  claudeDir = path.join(rootDir, ".claude");
120
+ geminiDir = path.join(rootDir, ".gemini");
111
121
  }
112
122
  });
113
123
 
@@ -344,15 +354,13 @@ function migrateMCPConfig(config) {
344
354
  config.managedServerNames = {
345
355
  claude: config.managedServerNames,
346
356
  codex: [],
347
- cursor: [],
348
- windsurf: []
357
+ gemini: []
349
358
  };
350
359
  } else if (!config.managedServerNames) {
351
360
  config.managedServerNames = {
352
361
  claude: [],
353
362
  codex: [],
354
- cursor: [],
355
- windsurf: []
363
+ gemini: []
356
364
  };
357
365
  }
358
366
  if (config.servers) {
@@ -374,8 +382,7 @@ function loadMCPConfig() {
374
382
  managedServerNames: {
375
383
  claude: [],
376
384
  codex: [],
377
- cursor: [],
378
- windsurf: []
385
+ gemini: []
379
386
  }
380
387
  };
381
388
  }
@@ -441,10 +448,10 @@ function writeMCPConfigForApp(app, _provider) {
441
448
  break;
442
449
  case "codex":
443
450
  return;
444
- case "cursor":
445
- return;
446
- case "windsurf":
447
- return;
451
+ case "gemini":
452
+ configPath = getGeminiSettingsPath();
453
+ configDir = getGeminiDir();
454
+ break;
448
455
  }
449
456
  ensureDir(configDir);
450
457
  let appConfig = {};
@@ -625,6 +632,127 @@ var init_mcp2 = __esm({
625
632
  }
626
633
  });
627
634
 
635
+ // ../core/dist/presets/gemini.js
636
+ var GEMINI_PRESETS;
637
+ var init_gemini = __esm({
638
+ "../core/dist/presets/gemini.js"() {
639
+ "use strict";
640
+ GEMINI_PRESETS = [
641
+ {
642
+ name: "Google Gemini (API Key)",
643
+ baseUrl: "",
644
+ description: "\u4F7F\u7528\u5B98\u65B9 Gemini API\uFF08\u901A\u8FC7 GEMINI_API_KEY \u6216 GOOGLE_API_KEY \u8BA4\u8BC1\uFF09"
645
+ },
646
+ {
647
+ name: "PackyAPI",
648
+ baseUrl: "https://www.packyapi.com",
649
+ description: "PackyAPI Gemini \u517C\u5BB9\u670D\u52A1"
650
+ },
651
+ {
652
+ name: "LiteLLM Proxy",
653
+ baseUrl: "http://localhost:4000",
654
+ description: "\u4F7F\u7528\u672C\u5730 LiteLLM Proxy \u4F5C\u4E3A Gemini \u517C\u5BB9\u4EE3\u7406"
655
+ }
656
+ ];
657
+ }
658
+ });
659
+
660
+ // ../core/dist/writers/gemini.js
661
+ import * as fs5 from "fs";
662
+ function loadEnvFile(envPath) {
663
+ if (!fileExists(envPath))
664
+ return {};
665
+ const content = fs5.readFileSync(envPath, "utf-8");
666
+ const result = {};
667
+ for (const line of content.split("\n")) {
668
+ const trimmed = line.trim();
669
+ if (!trimmed || trimmed.startsWith("#"))
670
+ continue;
671
+ const eqIndex = trimmed.indexOf("=");
672
+ if (eqIndex === -1)
673
+ continue;
674
+ const key = trimmed.slice(0, eqIndex).trim();
675
+ const value = trimmed.slice(eqIndex + 1).trim();
676
+ if (!key)
677
+ continue;
678
+ result[key] = value;
679
+ }
680
+ return result;
681
+ }
682
+ function saveEnvFile(envPath, env) {
683
+ const lines = [];
684
+ const keys = Object.keys(env).sort();
685
+ for (const key of keys) {
686
+ lines.push(`${key}=${String(env[key])}`);
687
+ }
688
+ const content = lines.join("\n") + (lines.length ? "\n" : "");
689
+ fs5.writeFileSync(envPath, content, { mode: 384 });
690
+ }
691
+ function writeGeminiConfig(provider) {
692
+ const settingsPath = getGeminiSettingsPath();
693
+ const envPath = getGeminiEnvPath();
694
+ const dir = getGeminiDir();
695
+ ensureDir(dir);
696
+ let settings = {};
697
+ if (fileExists(settingsPath)) {
698
+ try {
699
+ const content = fs5.readFileSync(settingsPath, "utf-8");
700
+ const parsed = JSON.parse(content);
701
+ if (parsed && typeof parsed === "object") {
702
+ settings = parsed;
703
+ }
704
+ } catch (error) {
705
+ throw new Error(`\u65E0\u6CD5\u8BFB\u53D6 Gemini settings.json: ${error.message}`);
706
+ }
707
+ }
708
+ if (!settings.ide || typeof settings.ide !== "object") {
709
+ settings.ide = {};
710
+ }
711
+ if (settings.ide.enabled === void 0) {
712
+ settings.ide.enabled = true;
713
+ }
714
+ if (!settings.security || typeof settings.security !== "object") {
715
+ settings.security = {};
716
+ }
717
+ if (!settings.security.auth || typeof settings.security.auth !== "object") {
718
+ settings.security.auth = {};
719
+ }
720
+ if (settings.security.auth.selectedType === void 0) {
721
+ settings.security.auth.selectedType = "gemini-api-key";
722
+ }
723
+ try {
724
+ const tempPath = `${settingsPath}.tmp`;
725
+ fs5.writeFileSync(tempPath, JSON.stringify(settings, null, 2), {
726
+ mode: 384
727
+ });
728
+ fs5.renameSync(tempPath, settingsPath);
729
+ } catch (error) {
730
+ throw new Error(`\u5199\u5165 Gemini settings.json \u5931\u8D25: ${error.message}`);
731
+ }
732
+ const env = loadEnvFile(envPath);
733
+ if (provider.baseUrl && provider.baseUrl.trim().length > 0) {
734
+ env.GOOGLE_GEMINI_BASE_URL = provider.baseUrl;
735
+ } else {
736
+ delete env.GOOGLE_GEMINI_BASE_URL;
737
+ }
738
+ if (provider.apiKey && provider.apiKey.trim().length > 0) {
739
+ env.GEMINI_API_KEY = provider.apiKey;
740
+ } else {
741
+ delete env.GEMINI_API_KEY;
742
+ }
743
+ if (provider.model && provider.model.trim().length > 0) {
744
+ env.GEMINI_MODEL = provider.model;
745
+ }
746
+ saveEnvFile(envPath, env);
747
+ }
748
+ var init_gemini2 = __esm({
749
+ "../core/dist/writers/gemini.js"() {
750
+ "use strict";
751
+ init_paths();
752
+ init_file();
753
+ }
754
+ });
755
+
628
756
  // ../core/dist/tool-manager.types.js
629
757
  var ProviderNotFoundError, ProviderNameConflictError, PresetNameConflictError;
630
758
  var init_tool_manager_types = __esm({
@@ -901,6 +1029,9 @@ function createClaudeManager() {
901
1029
  function createMCPManager() {
902
1030
  return createToolManager("mcp");
903
1031
  }
1032
+ function createGeminiManager() {
1033
+ return createToolManager("gemini");
1034
+ }
904
1035
  var TOOL_CONFIGS;
905
1036
  var init_tool_manager = __esm({
906
1037
  "../core/dist/tool-manager.js"() {
@@ -913,6 +1044,8 @@ var init_tool_manager = __esm({
913
1044
  init_codex2();
914
1045
  init_claude2();
915
1046
  init_mcp2();
1047
+ init_gemini();
1048
+ init_gemini2();
916
1049
  init_tool_manager_types();
917
1050
  TOOL_CONFIGS = {
918
1051
  codex: {
@@ -949,11 +1082,16 @@ var init_tool_manager = __esm({
949
1082
  }
950
1083
  return mcpServer;
951
1084
  });
952
- for (const app of ["claude", "codex", "cursor", "windsurf"]) {
1085
+ for (const app of ["claude", "codex", "gemini"]) {
953
1086
  mcpConfig.managedServerNames[app] = mcpConfig.servers.filter((s) => s.enabledApps.includes(app)).map((s) => s.name);
954
1087
  }
955
1088
  saveMCPConfig(mcpConfig);
956
1089
  }
1090
+ },
1091
+ gemini: {
1092
+ configPath: path6.join(getCcmanDir(), "gemini.json"),
1093
+ builtinPresets: GEMINI_PRESETS,
1094
+ writer: writeGeminiConfig
957
1095
  }
958
1096
  };
959
1097
  }
@@ -968,20 +1106,20 @@ var init_migrate = __esm({
968
1106
  });
969
1107
 
970
1108
  // ../core/dist/config.js
971
- import * as fs5 from "fs";
1109
+ import * as fs6 from "fs";
972
1110
  function ensureConfigDir() {
973
1111
  const dir = getCcmanDir();
974
- if (!fs5.existsSync(dir)) {
975
- fs5.mkdirSync(dir, { recursive: true, mode: 448 });
1112
+ if (!fs6.existsSync(dir)) {
1113
+ fs6.mkdirSync(dir, { recursive: true, mode: 448 });
976
1114
  }
977
1115
  }
978
1116
  function loadConfig() {
979
1117
  const configPath = getConfigPath();
980
- if (!fs5.existsSync(configPath)) {
1118
+ if (!fs6.existsSync(configPath)) {
981
1119
  return {};
982
1120
  }
983
1121
  try {
984
- const content = fs5.readFileSync(configPath, "utf-8");
1122
+ const content = fs6.readFileSync(configPath, "utf-8");
985
1123
  return JSON.parse(content);
986
1124
  } catch (error) {
987
1125
  throw new Error(`Failed to load config: ${error.message}`);
@@ -992,10 +1130,10 @@ function saveConfig(config) {
992
1130
  const configPath = getConfigPath();
993
1131
  try {
994
1132
  const tempPath = `${configPath}.tmp`;
995
- fs5.writeFileSync(tempPath, JSON.stringify(config, null, 2), {
1133
+ fs6.writeFileSync(tempPath, JSON.stringify(config, null, 2), {
996
1134
  mode: 384
997
1135
  });
998
- fs5.renameSync(tempPath, configPath);
1136
+ fs6.renameSync(tempPath, configPath);
999
1137
  } catch (error) {
1000
1138
  throw new Error(`Failed to save config: ${error.message}`);
1001
1139
  }
@@ -1319,15 +1457,15 @@ var init_merge_advanced = __esm({
1319
1457
  });
1320
1458
 
1321
1459
  // ../core/dist/sync/merge.js
1322
- import fs6 from "fs";
1460
+ import fs7 from "fs";
1323
1461
  import path7 from "path";
1324
1462
  function backupConfig(configPath, keepCount = 3) {
1325
- if (!fs6.existsSync(configPath)) {
1463
+ if (!fs7.existsSync(configPath)) {
1326
1464
  throw new Error(`\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728: ${configPath}`);
1327
1465
  }
1328
1466
  const timestamp = Date.now();
1329
1467
  const backupPath = `${configPath}.backup.${timestamp}`;
1330
- fs6.copyFileSync(configPath, backupPath);
1468
+ fs7.copyFileSync(configPath, backupPath);
1331
1469
  cleanupOldBackups(configPath, keepCount);
1332
1470
  return backupPath;
1333
1471
  }
@@ -1336,7 +1474,7 @@ function cleanupOldBackups(configPath, keepCount) {
1336
1474
  const basename = path7.basename(configPath);
1337
1475
  const backupPrefix = `${basename}.backup.`;
1338
1476
  try {
1339
- const files = fs6.readdirSync(dir);
1477
+ const files = fs7.readdirSync(dir);
1340
1478
  const backups = files.filter((f) => f.startsWith(backupPrefix)).map((f) => {
1341
1479
  const timestampStr = f.substring(backupPrefix.length);
1342
1480
  const timestamp = parseInt(timestampStr, 10);
@@ -1352,7 +1490,7 @@ function cleanupOldBackups(configPath, keepCount) {
1352
1490
  const toDelete = backups.slice(keepCount);
1353
1491
  for (const backup of toDelete) {
1354
1492
  try {
1355
- fs6.unlinkSync(backup.path);
1493
+ fs7.unlinkSync(backup.path);
1356
1494
  } catch (error) {
1357
1495
  console.warn(`\u65E0\u6CD5\u5220\u9664\u65E7\u5907\u4EFD\u6587\u4EF6 ${backup.name}: ${error.message}`);
1358
1496
  }
@@ -1368,7 +1506,7 @@ var init_merge = __esm({
1368
1506
  });
1369
1507
 
1370
1508
  // ../core/dist/sync/sync-v2.js
1371
- import fs7 from "fs";
1509
+ import fs8 from "fs";
1372
1510
  import path8 from "path";
1373
1511
  async function uploadToCloud(config, password) {
1374
1512
  const ccmanDir2 = getCcmanDir();
@@ -1424,10 +1562,10 @@ async function downloadFromCloud(config, password) {
1424
1562
  const codexConfigPath = path8.join(ccmanDir2, "codex.json");
1425
1563
  const claudeConfigPath = path8.join(ccmanDir2, "claude.json");
1426
1564
  try {
1427
- if (fs7.existsSync(codexConfigPath)) {
1565
+ if (fs8.existsSync(codexConfigPath)) {
1428
1566
  backupPaths.push(backupConfig(codexConfigPath));
1429
1567
  }
1430
- if (fs7.existsSync(claudeConfigPath)) {
1568
+ if (fs8.existsSync(claudeConfigPath)) {
1431
1569
  backupPaths.push(backupConfig(claudeConfigPath));
1432
1570
  }
1433
1571
  } catch (error) {
@@ -1460,8 +1598,8 @@ async function downloadFromCloud(config, password) {
1460
1598
  } catch (error) {
1461
1599
  for (const backupPath of backupPaths) {
1462
1600
  const originalPath = backupPath.replace(/\.backup\.\d+$/, "");
1463
- if (fs7.existsSync(backupPath)) {
1464
- fs7.copyFileSync(backupPath, originalPath);
1601
+ if (fs8.existsSync(backupPath)) {
1602
+ fs8.copyFileSync(backupPath, originalPath);
1465
1603
  }
1466
1604
  }
1467
1605
  throw new Error(`\u8986\u76D6\u914D\u7F6E\u5931\u8D25\uFF0C\u5DF2\u6062\u590D\u5907\u4EFD: ${error.message}`);
@@ -1511,10 +1649,10 @@ async function mergeSync(config, password) {
1511
1649
  }
1512
1650
  const backupPaths = [];
1513
1651
  try {
1514
- if (fs7.existsSync(codexConfigPath)) {
1652
+ if (fs8.existsSync(codexConfigPath)) {
1515
1653
  backupPaths.push(backupConfig(codexConfigPath));
1516
1654
  }
1517
- if (fs7.existsSync(claudeConfigPath)) {
1655
+ if (fs8.existsSync(claudeConfigPath)) {
1518
1656
  backupPaths.push(backupConfig(claudeConfigPath));
1519
1657
  }
1520
1658
  } catch (error) {
@@ -1570,8 +1708,8 @@ async function mergeSync(config, password) {
1570
1708
  } catch (error) {
1571
1709
  for (const backupPath of backupPaths) {
1572
1710
  const originalPath = backupPath.replace(/\.backup\.\d+$/, "");
1573
- if (fs7.existsSync(backupPath)) {
1574
- fs7.copyFileSync(backupPath, originalPath);
1711
+ if (fs8.existsSync(backupPath)) {
1712
+ fs8.copyFileSync(backupPath, originalPath);
1575
1713
  }
1576
1714
  }
1577
1715
  throw new Error(`\u5408\u5E76\u914D\u7F6E\u5931\u8D25\uFF0C\u5DF2\u6062\u590D\u5907\u4EFD: ${error.message}`);
@@ -1610,7 +1748,7 @@ var init_sync_v2 = __esm({
1610
1748
  });
1611
1749
 
1612
1750
  // ../core/dist/export.js
1613
- import * as fs8 from "fs";
1751
+ import * as fs9 from "fs";
1614
1752
  import * as path9 from "path";
1615
1753
  function validateExport() {
1616
1754
  const ccmanDir2 = getCcmanDir();
@@ -1640,7 +1778,7 @@ function validateImportDir(sourceDir) {
1640
1778
  foundFiles: []
1641
1779
  };
1642
1780
  }
1643
- const stats = fs8.statSync(sourceDir);
1781
+ const stats = fs9.statSync(sourceDir);
1644
1782
  if (!stats.isDirectory()) {
1645
1783
  return {
1646
1784
  valid: false,
@@ -1680,13 +1818,13 @@ function exportConfig(targetDir) {
1680
1818
  const codexSrc = path9.join(ccmanDir2, CODEX_CONFIG_FILE);
1681
1819
  const codexDst = path9.join(targetDir, CODEX_CONFIG_FILE);
1682
1820
  if (fileExists(codexSrc)) {
1683
- fs8.copyFileSync(codexSrc, codexDst);
1821
+ fs9.copyFileSync(codexSrc, codexDst);
1684
1822
  exportedFiles.push(CODEX_CONFIG_FILE);
1685
1823
  }
1686
1824
  const claudeSrc = path9.join(ccmanDir2, CLAUDE_CONFIG_FILE);
1687
1825
  const claudeDst = path9.join(targetDir, CLAUDE_CONFIG_FILE);
1688
1826
  if (fileExists(claudeSrc)) {
1689
- fs8.copyFileSync(claudeSrc, claudeDst);
1827
+ fs9.copyFileSync(claudeSrc, claudeDst);
1690
1828
  exportedFiles.push(CLAUDE_CONFIG_FILE);
1691
1829
  }
1692
1830
  return {
@@ -1712,7 +1850,7 @@ function importConfig(sourceDir) {
1712
1850
  backupPaths.push(backupPath);
1713
1851
  }
1714
1852
  const codexSrc = path9.join(sourceDir, CODEX_CONFIG_FILE);
1715
- fs8.copyFileSync(codexSrc, codexDst);
1853
+ fs9.copyFileSync(codexSrc, codexDst);
1716
1854
  importedFiles.push(CODEX_CONFIG_FILE);
1717
1855
  }
1718
1856
  if (validation.foundFiles.includes(CLAUDE_CONFIG_FILE)) {
@@ -1722,7 +1860,7 @@ function importConfig(sourceDir) {
1722
1860
  backupPaths.push(backupPath);
1723
1861
  }
1724
1862
  const claudeSrc = path9.join(sourceDir, CLAUDE_CONFIG_FILE);
1725
- fs8.copyFileSync(claudeSrc, claudeDst);
1863
+ fs9.copyFileSync(claudeSrc, claudeDst);
1726
1864
  importedFiles.push(CLAUDE_CONFIG_FILE);
1727
1865
  }
1728
1866
  return {
@@ -1734,7 +1872,7 @@ function importConfig(sourceDir) {
1734
1872
  for (const backupPath of backupPaths) {
1735
1873
  const originalPath = backupPath.replace(/\.backup\.\d+$/, "");
1736
1874
  if (fileExists(backupPath)) {
1737
- fs8.copyFileSync(backupPath, originalPath);
1875
+ fs9.copyFileSync(backupPath, originalPath);
1738
1876
  }
1739
1877
  }
1740
1878
  throw new Error(`\u5BFC\u5165\u5931\u8D25\uFF0C\u5DF2\u6062\u590D\u5907\u4EFD: ${error.message}`);
@@ -1753,7 +1891,7 @@ var init_export = __esm({
1753
1891
  });
1754
1892
 
1755
1893
  // ../core/dist/claude-clean.js
1756
- import * as fs9 from "fs";
1894
+ import * as fs10 from "fs";
1757
1895
  function formatBytes(bytes) {
1758
1896
  if (bytes < 1024)
1759
1897
  return `${bytes} B`;
@@ -1763,7 +1901,7 @@ function formatBytes(bytes) {
1763
1901
  }
1764
1902
  function getFileSize(filePath) {
1765
1903
  try {
1766
- const stats = fs9.statSync(filePath);
1904
+ const stats = fs10.statSync(filePath);
1767
1905
  return stats.size;
1768
1906
  } catch {
1769
1907
  return 0;
@@ -1772,22 +1910,34 @@ function getFileSize(filePath) {
1772
1910
  function backupFile(filePath) {
1773
1911
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/:/g, "-").split(".")[0];
1774
1912
  const backupPath = `${filePath}.backup-${timestamp}`;
1775
- fs9.copyFileSync(filePath, backupPath);
1913
+ fs10.copyFileSync(filePath, backupPath);
1776
1914
  return backupPath;
1777
1915
  }
1778
1916
  function saveJsonAtomic(filePath, data) {
1779
1917
  const tempPath = `${filePath}.tmp`;
1780
1918
  const content = JSON.stringify(data, null, 2);
1781
- fs9.writeFileSync(tempPath, content, { mode: 384 });
1782
- fs9.renameSync(tempPath, filePath);
1919
+ fs10.writeFileSync(tempPath, content, { mode: 384 });
1920
+ fs10.renameSync(tempPath, filePath);
1783
1921
  }
1784
1922
  function analyzeClaudeJson() {
1785
1923
  const filePath = getClaudeJsonPath();
1786
- if (!fs9.existsSync(filePath)) {
1787
- throw new Error("~/.claude.json \u6587\u4EF6\u4E0D\u5B58\u5728");
1924
+ if (!fs10.existsSync(filePath)) {
1925
+ return {
1926
+ fileSize: 0,
1927
+ fileSizeFormatted: "0 B",
1928
+ projectCount: 0,
1929
+ totalHistoryCount: 0,
1930
+ projectHistory: [],
1931
+ cacheSize: 0,
1932
+ estimatedSavings: {
1933
+ conservative: 0,
1934
+ moderate: 0,
1935
+ aggressive: 0
1936
+ }
1937
+ };
1788
1938
  }
1789
1939
  const fileSize = getFileSize(filePath);
1790
- const content = fs9.readFileSync(filePath, "utf-8");
1940
+ const content = fs10.readFileSync(filePath, "utf-8");
1791
1941
  const config = JSON.parse(content);
1792
1942
  const projects = config.projects || {};
1793
1943
  const projectHistory = [];
@@ -1821,12 +1971,12 @@ function analyzeClaudeJson() {
1821
1971
  }
1822
1972
  function cleanClaudeJson(options = {}) {
1823
1973
  const filePath = getClaudeJsonPath();
1824
- if (!fs9.existsSync(filePath)) {
1825
- throw new Error("~/.claude.json \u6587\u4EF6\u4E0D\u5B58\u5728");
1974
+ if (!fs10.existsSync(filePath)) {
1975
+ throw new Error(`${filePath} \u6587\u4EF6\u4E0D\u5B58\u5728`);
1826
1976
  }
1827
1977
  const backupPath = backupFile(filePath);
1828
1978
  const sizeBefore = getFileSize(filePath);
1829
- const content = fs9.readFileSync(filePath, "utf-8");
1979
+ const content = fs10.readFileSync(filePath, "utf-8");
1830
1980
  const config = JSON.parse(content);
1831
1981
  const cleanedItems = applyCleanOptions(config, options);
1832
1982
  saveJsonAtomic(filePath, config);
@@ -1911,6 +2061,7 @@ var init_dist = __esm({
1911
2061
  init_codex2();
1912
2062
  init_claude2();
1913
2063
  init_mcp2();
2064
+ init_gemini();
1914
2065
  init_mcp();
1915
2066
  init_migrate();
1916
2067
  init_paths();
@@ -2634,7 +2785,7 @@ var init_sync = __esm({
2634
2785
 
2635
2786
  // src/index.ts
2636
2787
  import { Command as Command3 } from "commander";
2637
- import chalk33 from "chalk";
2788
+ import chalk40 from "chalk";
2638
2789
 
2639
2790
  // src/utils/logo.ts
2640
2791
  init_dist();
@@ -2693,6 +2844,11 @@ function formatProviderTable(providers, currentId) {
2693
2844
  }
2694
2845
 
2695
2846
  // src/interactive.ts
2847
+ var TOOL_CONFIG = {
2848
+ codex: { name: "Codex", emoji: "\u{1F536}", cmd: "cx" },
2849
+ claude: { name: "Claude", emoji: "\u{1F537}", cmd: "cc" },
2850
+ gemini: { name: "Gemini", emoji: "\u{1F48E}", cmd: "gm" }
2851
+ };
2696
2852
  async function promptProviderForm(defaults) {
2697
2853
  const answers = await inquirer7.prompt([
2698
2854
  {
@@ -2754,6 +2910,7 @@ async function startMainMenu() {
2754
2910
  choices: [
2755
2911
  { name: "\u{1F537} Claude \u7BA1\u7406", value: "claude" },
2756
2912
  { name: "\u{1F536} Codex \u7BA1\u7406", value: "codex" },
2913
+ { name: "\u{1F48E} Gemini \u7BA1\u7406", value: "gemini" },
2757
2914
  { name: "\u{1F504} WebDAV \u540C\u6B65", value: "sync" },
2758
2915
  { name: "\u{1F4E6} \u9884\u7F6E\u670D\u52A1\u5546\u7BA1\u7406", value: "presets" },
2759
2916
  { name: "\u274C \u9000\u51FA", value: "exit" }
@@ -2768,6 +2925,8 @@ async function startMainMenu() {
2768
2925
  await startClaudeMenu();
2769
2926
  } else if (choice === "codex") {
2770
2927
  await startCodexMenu();
2928
+ } else if (choice === "gemini") {
2929
+ await startGeminiMenu();
2771
2930
  } else if (choice === "sync") {
2772
2931
  const { startSyncMenu: startSyncMenu2 } = await Promise.resolve().then(() => (init_sync(), sync_exports));
2773
2932
  await startSyncMenu2();
@@ -2782,9 +2941,11 @@ async function startClaudeMenu() {
2782
2941
  async function startCodexMenu() {
2783
2942
  await showToolMenu("codex");
2784
2943
  }
2944
+ async function startGeminiMenu() {
2945
+ await showToolMenu("gemini");
2946
+ }
2785
2947
  async function showToolMenu(tool) {
2786
- const toolName = tool === "claude" ? "Claude" : "Codex";
2787
- const toolEmoji = tool === "claude" ? "\u{1F537}" : "\u{1F536}";
2948
+ const { name: toolName, emoji: toolEmoji } = TOOL_CONFIG[tool];
2788
2949
  while (true) {
2789
2950
  console.log();
2790
2951
  const { action } = await inquirer7.prompt([
@@ -2849,8 +3010,8 @@ async function showPresetsMenu() {
2849
3010
  console.log(chalk11.yellow("\n\u26A0\uFE0F \u9884\u7F6E\u670D\u52A1\u5546\u7BA1\u7406\u529F\u80FD\u5373\u5C06\u63A8\u51FA\n"));
2850
3011
  }
2851
3012
  async function handleAdd(tool) {
2852
- const manager = tool === "codex" ? createCodexManager() : createClaudeManager();
2853
- const toolName = tool === "claude" ? "Claude" : "Codex";
3013
+ const manager = tool === "codex" ? createCodexManager() : tool === "claude" ? createClaudeManager() : createGeminiManager();
3014
+ const { name: toolName, cmd } = TOOL_CONFIG[tool];
2854
3015
  const presets = manager.listPresets();
2855
3016
  console.log(chalk11.bold(`
2856
3017
  \u{1F4DD} \u6DFB\u52A0 ${toolName} \u670D\u52A1\u5546
@@ -2949,13 +3110,13 @@ async function handleAdd(tool) {
2949
3110
  console.log(chalk11.green("\u2705 \u5DF2\u5207\u6362\u5230\u65B0\u670D\u52A1\u5546\n"));
2950
3111
  } else {
2951
3112
  console.log(
2952
- chalk11.blue("\u{1F4A1} \u7A0D\u540E\u5207\u6362:") + chalk11.white(` ccman ${tool === "codex" ? "cx" : "cc"} use "${provider.name}"
3113
+ chalk11.blue("\u{1F4A1} \u7A0D\u540E\u5207\u6362:") + chalk11.white(` ccman ${cmd} use "${provider.name}"
2953
3114
  `)
2954
3115
  );
2955
3116
  }
2956
3117
  }
2957
3118
  async function handleSwitch(tool) {
2958
- const manager = tool === "codex" ? createCodexManager() : createClaudeManager();
3119
+ const manager = tool === "codex" ? createCodexManager() : tool === "claude" ? createClaudeManager() : createGeminiManager();
2959
3120
  const providers = manager.list();
2960
3121
  const current = manager.getCurrent();
2961
3122
  if (providers.length === 0) {
@@ -2980,10 +3141,10 @@ async function handleSwitch(tool) {
2980
3141
  `));
2981
3142
  }
2982
3143
  async function handleList(tool) {
2983
- const manager = tool === "codex" ? createCodexManager() : createClaudeManager();
3144
+ const manager = tool === "codex" ? createCodexManager() : tool === "claude" ? createClaudeManager() : createGeminiManager();
2984
3145
  const providers = manager.list();
2985
3146
  const current = manager.getCurrent();
2986
- const toolName = tool === "claude" ? "Claude" : "Codex";
3147
+ const { name: toolName } = TOOL_CONFIG[tool];
2987
3148
  if (providers.length === 0) {
2988
3149
  console.log(chalk11.yellow(`
2989
3150
  \u26A0\uFE0F \u6682\u65E0 ${toolName} \u670D\u52A1\u5546
@@ -2995,9 +3156,9 @@ async function handleList(tool) {
2995
3156
  console.log(formatProviderTable(providers, current?.id));
2996
3157
  }
2997
3158
  async function handleCurrent(tool) {
2998
- const manager = tool === "codex" ? createCodexManager() : createClaudeManager();
3159
+ const manager = tool === "codex" ? createCodexManager() : tool === "claude" ? createClaudeManager() : createGeminiManager();
2999
3160
  const current = manager.getCurrent();
3000
- const toolName = tool === "claude" ? "Claude" : "Codex";
3161
+ const { name: toolName } = TOOL_CONFIG[tool];
3001
3162
  if (!current) {
3002
3163
  console.log(chalk11.yellow(`
3003
3164
  \u26A0\uFE0F \u672A\u9009\u62E9\u4EFB\u4F55 ${toolName} \u670D\u52A1\u5546
@@ -3016,7 +3177,7 @@ async function handleCurrent(tool) {
3016
3177
  console.log();
3017
3178
  }
3018
3179
  async function handleEdit(tool) {
3019
- const manager = tool === "codex" ? createCodexManager() : createClaudeManager();
3180
+ const manager = tool === "codex" ? createCodexManager() : tool === "claude" ? createClaudeManager() : createGeminiManager();
3020
3181
  const providers = manager.list();
3021
3182
  if (providers.length === 0) {
3022
3183
  console.log(chalk11.yellow("\n\u26A0\uFE0F \u6682\u65E0\u670D\u52A1\u5546\n"));
@@ -3077,7 +3238,7 @@ async function handleEdit(tool) {
3077
3238
  console.log(chalk11.green("\n\u2705 \u7F16\u8F91\u6210\u529F\n"));
3078
3239
  }
3079
3240
  async function handleClone(tool) {
3080
- const manager = tool === "codex" ? createCodexManager() : createClaudeManager();
3241
+ const manager = tool === "codex" ? createCodexManager() : tool === "claude" ? createClaudeManager() : createGeminiManager();
3081
3242
  const providers = manager.list();
3082
3243
  if (providers.length === 0) {
3083
3244
  console.log(chalk11.yellow("\n\u26A0\uFE0F \u6682\u65E0\u670D\u52A1\u5546\n"));
@@ -3124,7 +3285,7 @@ async function handleClone(tool) {
3124
3285
  console.log();
3125
3286
  }
3126
3287
  async function handleRemove(tool) {
3127
- const manager = tool === "codex" ? createCodexManager() : createClaudeManager();
3288
+ const manager = tool === "codex" ? createCodexManager() : tool === "claude" ? createClaudeManager() : createGeminiManager();
3128
3289
  const providers = manager.list();
3129
3290
  if (providers.length === 0) {
3130
3291
  console.log(chalk11.yellow("\n\u26A0\uFE0F \u6682\u65E0\u670D\u52A1\u5546\n"));
@@ -4636,7 +4797,7 @@ function editCommand3(program2) {
4636
4797
  targetId = selectedId;
4637
4798
  }
4638
4799
  const provider = manager.get(targetId);
4639
- const currentCommand3 = provider.baseUrl;
4800
+ const currentCommand4 = provider.baseUrl;
4640
4801
  const currentArgs = provider.apiKey;
4641
4802
  const currentEnv = provider.model;
4642
4803
  console.log(chalk30.bold("\n\u270F\uFE0F \u7F16\u8F91 MCP \u670D\u52A1\u5668\n"));
@@ -4652,7 +4813,7 @@ function editCommand3(program2) {
4652
4813
  type: "input",
4653
4814
  name: "command",
4654
4815
  message: "\u542F\u52A8\u547D\u4EE4:",
4655
- default: currentCommand3
4816
+ default: currentCommand4
4656
4817
  },
4657
4818
  {
4658
4819
  type: "input",
@@ -4671,7 +4832,7 @@ function editCommand3(program2) {
4671
4832
  if (answers.name && answers.name !== provider.name) {
4672
4833
  updates.name = answers.name;
4673
4834
  }
4674
- if (answers.command && answers.command !== currentCommand3) {
4835
+ if (answers.command && answers.command !== currentCommand4) {
4675
4836
  updates.baseUrl = answers.command;
4676
4837
  }
4677
4838
  if (answers.args && answers.args !== currentArgs) {
@@ -4720,44 +4881,480 @@ function createMCPCommands(program2) {
4720
4881
  editCommand3(program2);
4721
4882
  }
4722
4883
 
4884
+ // src/commands/gemini/add.ts
4885
+ init_dist();
4886
+ import chalk31 from "chalk";
4887
+ import inquirer22 from "inquirer";
4888
+ function addCommand4(program2) {
4889
+ program2.command("add").description("\u6DFB\u52A0\u65B0\u7684 Gemini CLI \u670D\u52A1\u5546(\u4EA4\u4E92\u5F0F)").action(async () => {
4890
+ try {
4891
+ const manager = createGeminiManager();
4892
+ console.log(chalk31.bold("\n\u{1F4DD} \u6DFB\u52A0 Gemini CLI \u670D\u52A1\u5546\n"));
4893
+ const { usePreset } = await inquirer22.prompt([
4894
+ {
4895
+ type: "list",
4896
+ name: "usePreset",
4897
+ message: "\u9009\u62E9\u914D\u7F6E\u6765\u6E90:",
4898
+ choices: [
4899
+ { name: "\u{1F4E6} \u4F7F\u7528\u9884\u7F6E\u670D\u52A1\u5546", value: true },
4900
+ { name: "\u270F\uFE0F \u81EA\u5B9A\u4E49\u914D\u7F6E", value: false }
4901
+ ]
4902
+ }
4903
+ ]);
4904
+ let name;
4905
+ let desc;
4906
+ let baseUrl;
4907
+ let apiKey;
4908
+ if (usePreset) {
4909
+ const { presetName } = await inquirer22.prompt([
4910
+ {
4911
+ type: "list",
4912
+ name: "presetName",
4913
+ message: "\u9009\u62E9\u9884\u7F6E\u670D\u52A1\u5546:",
4914
+ choices: GEMINI_PRESETS.map((p) => ({
4915
+ name: `${p.name} - ${p.description}`,
4916
+ value: p.name
4917
+ }))
4918
+ }
4919
+ ]);
4920
+ const preset = GEMINI_PRESETS.find((p) => p.name === presetName);
4921
+ console.log(chalk31.blue(`
4922
+ \u4F7F\u7528\u9884\u8BBE: ${preset.name} - ${preset.description}
4923
+ `));
4924
+ const input = await promptProviderForm({
4925
+ name: preset.name,
4926
+ desc: "",
4927
+ baseUrl: preset.baseUrl,
4928
+ apiKey: ""
4929
+ });
4930
+ name = input.name;
4931
+ desc = input.desc;
4932
+ baseUrl = input.baseUrl;
4933
+ apiKey = input.apiKey;
4934
+ } else {
4935
+ const answers = await inquirer22.prompt([
4936
+ {
4937
+ type: "input",
4938
+ name: "name",
4939
+ message: "\u670D\u52A1\u5546\u540D\u79F0:",
4940
+ validate: (value) => {
4941
+ if (!value) return "\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A";
4942
+ return true;
4943
+ }
4944
+ },
4945
+ {
4946
+ type: "input",
4947
+ name: "baseUrl",
4948
+ message: "API \u5730\u5740 (\u53EF\u4E3A\u7A7A\uFF0C\u4F7F\u7528\u5B98\u65B9\u9ED8\u8BA4):",
4949
+ validate: (value) => {
4950
+ if (!value) return true;
4951
+ if (!value.startsWith("http://") && !value.startsWith("https://")) {
4952
+ return "API \u5730\u5740\u5FC5\u987B\u4EE5 http:// \u6216 https:// \u5F00\u5934";
4953
+ }
4954
+ return true;
4955
+ }
4956
+ },
4957
+ {
4958
+ type: "password",
4959
+ name: "apiKey",
4960
+ message: "API \u5BC6\u94A5 (\u53EF\u4E3A\u7A7A\uFF0C\u4F7F\u7528\u73AF\u5883\u5DF2\u914D\u7F6E\u7684 Key):",
4961
+ mask: "*"
4962
+ }
4963
+ ]);
4964
+ name = answers.name;
4965
+ desc = void 0;
4966
+ baseUrl = answers.baseUrl || "";
4967
+ apiKey = answers.apiKey || "";
4968
+ }
4969
+ const provider = manager.add({ name, desc, baseUrl, apiKey });
4970
+ console.log();
4971
+ console.log(chalk31.green("\u2705 \u6DFB\u52A0\u6210\u529F"));
4972
+ console.log();
4973
+ console.log(` ${chalk31.bold(provider.name)} ${chalk31.blue("[Gemini CLI]")}`);
4974
+ console.log(` ${chalk31.gray(provider.baseUrl || "(\u4F7F\u7528\u9ED8\u8BA4\u7AEF\u70B9)")}`);
4975
+ console.log();
4976
+ const { switchNow } = await inquirer22.prompt([
4977
+ {
4978
+ type: "confirm",
4979
+ name: "switchNow",
4980
+ message: "\u662F\u5426\u7ACB\u5373\u5207\u6362\u5230\u6B64\u670D\u52A1\u5546?",
4981
+ default: true
4982
+ }
4983
+ ]);
4984
+ if (switchNow) {
4985
+ manager.switch(provider.id);
4986
+ console.log(chalk31.green("\u2705 \u5DF2\u5207\u6362\u5230\u65B0\u670D\u52A1\u5546"));
4987
+ console.log();
4988
+ console.log(chalk31.gray("\u914D\u7F6E\u5DF2\u66F4\u65B0:"));
4989
+ console.log(chalk31.gray(` - ${getGeminiSettingsPath()}`));
4990
+ console.log(chalk31.gray(` - ${getGeminiEnvPath()}`));
4991
+ } else {
4992
+ console.log(chalk31.blue("\u{1F4A1} \u7A0D\u540E\u5207\u6362:") + chalk31.white(` ccman gm use "${provider.name}"`));
4993
+ }
4994
+ } catch (error) {
4995
+ console.error(chalk31.red(`
4996
+ \u274C ${error.message}
4997
+ `));
4998
+ process.exit(1);
4999
+ }
5000
+ });
5001
+ }
5002
+
5003
+ // src/commands/gemini/list.ts
5004
+ init_dist();
5005
+ import chalk32 from "chalk";
5006
+ function listCommand4(program2) {
5007
+ program2.command("list").alias("ls").description("\u5217\u51FA\u6240\u6709 Gemini CLI \u670D\u52A1\u5546").action(async () => {
5008
+ try {
5009
+ const manager = createGeminiManager();
5010
+ const providers = manager.list();
5011
+ const current = manager.getCurrent();
5012
+ if (providers.length === 0) {
5013
+ console.log(chalk32.yellow("\n\u26A0\uFE0F \u6682\u65E0 Gemini CLI \u670D\u52A1\u5546\n"));
5014
+ console.log(chalk32.blue("\u{1F4A1} \u6DFB\u52A0\u670D\u52A1\u5546:") + chalk32.white(" ccman gm add\n"));
5015
+ return;
5016
+ }
5017
+ console.log(chalk32.bold(`
5018
+ \u{1F4CB} Gemini CLI \u670D\u52A1\u5546 (${providers.length} \u4E2A)`));
5019
+ console.log(formatProviderTable(providers, current?.id));
5020
+ } catch (error) {
5021
+ console.error(chalk32.red(`
5022
+ \u274C ${error.message}
5023
+ `));
5024
+ process.exit(1);
5025
+ }
5026
+ });
5027
+ }
5028
+
5029
+ // src/commands/gemini/use.ts
5030
+ init_dist();
5031
+ import chalk33 from "chalk";
5032
+ import inquirer23 from "inquirer";
5033
+ function useCommand3(program2) {
5034
+ program2.command("use [name]").description("\u5207\u6362 Gemini CLI \u670D\u52A1\u5546").action(async (name) => {
5035
+ try {
5036
+ const manager = createGeminiManager();
5037
+ const providers = manager.list();
5038
+ if (providers.length === 0) {
5039
+ console.log(chalk33.yellow("\n\u26A0\uFE0F \u6682\u65E0 Gemini CLI \u670D\u52A1\u5546\n"));
5040
+ console.log(chalk33.blue("\u{1F4A1} \u6DFB\u52A0\u670D\u52A1\u5546:") + chalk33.white(" ccman gm add\n"));
5041
+ return;
5042
+ }
5043
+ let targetId;
5044
+ if (name) {
5045
+ const provider2 = manager.findByName(name);
5046
+ if (!provider2) {
5047
+ throw new ProviderNotFoundError(name);
5048
+ }
5049
+ targetId = provider2.id;
5050
+ } else {
5051
+ const { selectedId } = await inquirer23.prompt([
5052
+ {
5053
+ type: "list",
5054
+ name: "selectedId",
5055
+ message: "\u9009\u62E9\u8981\u5207\u6362\u7684\u670D\u52A1\u5546:",
5056
+ choices: providers.map((p) => ({
5057
+ name: `${p.name} - ${p.baseUrl || "(\u9ED8\u8BA4\u7AEF\u70B9)"}`,
5058
+ value: p.id
5059
+ }))
5060
+ }
5061
+ ]);
5062
+ targetId = selectedId;
5063
+ }
5064
+ manager.switch(targetId);
5065
+ const provider = manager.get(targetId);
5066
+ console.log();
5067
+ console.log(chalk33.green("\u2705 \u5207\u6362\u6210\u529F"));
5068
+ console.log();
5069
+ console.log(` ${chalk33.bold(provider.name)} ${chalk33.blue("[Gemini CLI]")}`);
5070
+ console.log(` ${chalk33.gray(`URL: ${provider.baseUrl || "(\u9ED8\u8BA4\u7AEF\u70B9)"}`)}`);
5071
+ console.log();
5072
+ console.log(chalk33.gray("\u914D\u7F6E\u5DF2\u66F4\u65B0:"));
5073
+ console.log(chalk33.gray(` - ${getGeminiSettingsPath()}`));
5074
+ console.log(chalk33.gray(` - ${getGeminiEnvPath()}`));
5075
+ console.log();
5076
+ } catch (error) {
5077
+ if (error instanceof ProviderNotFoundError) {
5078
+ console.error(chalk33.red(`
5079
+ \u274C \u670D\u52A1\u5546\u4E0D\u5B58\u5728: ${error.message}
5080
+ `));
5081
+ console.log(chalk33.blue("\u{1F4A1} \u67E5\u770B\u6240\u6709\u670D\u52A1\u5546:") + chalk33.white(" ccman gm list\n"));
5082
+ } else {
5083
+ console.error(chalk33.red(`
5084
+ \u274C ${error.message}
5085
+ `));
5086
+ }
5087
+ process.exit(1);
5088
+ }
5089
+ });
5090
+ }
5091
+
5092
+ // src/commands/gemini/current.ts
5093
+ init_dist();
5094
+ import chalk34 from "chalk";
5095
+ function currentCommand3(program2) {
5096
+ program2.command("current").description("\u663E\u793A\u5F53\u524D Gemini CLI \u670D\u52A1\u5546").action(async () => {
5097
+ try {
5098
+ const manager = createGeminiManager();
5099
+ const current = manager.getCurrent();
5100
+ if (!current) {
5101
+ console.log(chalk34.yellow("\n\u26A0\uFE0F \u5F53\u524D\u6CA1\u6709\u6FC0\u6D3B\u7684 Gemini CLI \u670D\u52A1\u5546\n"));
5102
+ console.log(chalk34.blue("\u{1F4A1} \u5217\u51FA\u670D\u52A1\u5546:") + chalk34.white(" ccman gm list\n"));
5103
+ return;
5104
+ }
5105
+ console.log(chalk34.bold("\n\u{1F3AF} \u5F53\u524D Gemini CLI \u670D\u52A1\u5546\n"));
5106
+ console.log(` \u540D\u79F0: ${chalk34.bold(current.name)}`);
5107
+ console.log(` \u5730\u5740: ${chalk34.gray(current.baseUrl || "(\u9ED8\u8BA4\u7AEF\u70B9)")}`);
5108
+ console.log();
5109
+ } catch (error) {
5110
+ console.error(chalk34.red(`
5111
+ \u274C ${error.message}
5112
+ `));
5113
+ process.exit(1);
5114
+ }
5115
+ });
5116
+ }
5117
+
5118
+ // src/commands/gemini/remove.ts
5119
+ init_dist();
5120
+ import chalk35 from "chalk";
5121
+ import inquirer24 from "inquirer";
5122
+ function removeCommand4(program2) {
5123
+ program2.command("remove [name]").alias("rm").description("\u5220\u9664 Gemini CLI \u670D\u52A1\u5546").action(async (name) => {
5124
+ try {
5125
+ const manager = createGeminiManager();
5126
+ const providers = manager.list();
5127
+ if (providers.length === 0) {
5128
+ console.log(chalk35.yellow("\n\u26A0\uFE0F \u6682\u65E0 Gemini CLI \u670D\u52A1\u5546\n"));
5129
+ console.log(chalk35.blue("\u{1F4A1} \u6DFB\u52A0\u670D\u52A1\u5546:") + chalk35.white(" ccman gm add\n"));
5130
+ return;
5131
+ }
5132
+ let targetId;
5133
+ let targetName;
5134
+ if (name) {
5135
+ const provider = manager.findByName(name);
5136
+ if (!provider) {
5137
+ console.log(chalk35.red(`
5138
+ \u274C \u670D\u52A1\u5546\u4E0D\u5B58\u5728: ${name}
5139
+ `));
5140
+ process.exit(1);
5141
+ }
5142
+ targetId = provider.id;
5143
+ targetName = provider.name;
5144
+ } else {
5145
+ const { selectedId } = await inquirer24.prompt([
5146
+ {
5147
+ type: "list",
5148
+ name: "selectedId",
5149
+ message: "\u9009\u62E9\u8981\u5220\u9664\u7684\u670D\u52A1\u5546:",
5150
+ choices: providers.map((p) => ({
5151
+ name: `${p.name} - ${p.baseUrl || "(\u9ED8\u8BA4\u7AEF\u70B9)"}`,
5152
+ value: p.id
5153
+ }))
5154
+ }
5155
+ ]);
5156
+ const provider = manager.get(selectedId);
5157
+ targetId = provider.id;
5158
+ targetName = provider.name;
5159
+ }
5160
+ const { confirm } = await inquirer24.prompt([
5161
+ {
5162
+ type: "confirm",
5163
+ name: "confirm",
5164
+ message: `\u786E\u5B9A\u8981\u5220\u9664\u670D\u52A1\u5546 "${targetName}" \u5417\uFF1F`,
5165
+ default: false
5166
+ }
5167
+ ]);
5168
+ if (!confirm) {
5169
+ console.log(chalk35.gray("\n\u5DF2\u53D6\u6D88\u5220\u9664\n"));
5170
+ return;
5171
+ }
5172
+ manager.remove(targetId);
5173
+ console.log(chalk35.green("\n\u2705 \u5DF2\u5220\u9664\u670D\u52A1\u5546\n"));
5174
+ } catch (error) {
5175
+ console.error(chalk35.red(`
5176
+ \u274C ${error.message}
5177
+ `));
5178
+ process.exit(1);
5179
+ }
5180
+ });
5181
+ }
5182
+
5183
+ // src/commands/gemini/edit.ts
5184
+ init_dist();
5185
+ import chalk36 from "chalk";
5186
+ import inquirer25 from "inquirer";
5187
+ function editCommand4(program2) {
5188
+ program2.command("edit [name]").description("\u7F16\u8F91 Gemini CLI \u670D\u52A1\u5546").action(async (name) => {
5189
+ try {
5190
+ const manager = createGeminiManager();
5191
+ const providers = manager.list();
5192
+ if (providers.length === 0) {
5193
+ console.log(chalk36.yellow("\n\u26A0\uFE0F \u6682\u65E0 Gemini CLI \u670D\u52A1\u5546\n"));
5194
+ console.log(chalk36.blue("\u{1F4A1} \u6DFB\u52A0\u670D\u52A1\u5546:") + chalk36.white(" ccman gm add\n"));
5195
+ return;
5196
+ }
5197
+ let targetId;
5198
+ if (name) {
5199
+ const provider2 = manager.findByName(name);
5200
+ if (!provider2) {
5201
+ console.log(chalk36.red(`
5202
+ \u274C \u670D\u52A1\u5546\u4E0D\u5B58\u5728: ${name}
5203
+ `));
5204
+ process.exit(1);
5205
+ }
5206
+ targetId = provider2.id;
5207
+ } else {
5208
+ const { selectedId } = await inquirer25.prompt([
5209
+ {
5210
+ type: "list",
5211
+ name: "selectedId",
5212
+ message: "\u9009\u62E9\u8981\u7F16\u8F91\u7684\u670D\u52A1\u5546:",
5213
+ choices: providers.map((p) => ({
5214
+ name: `${p.name} - ${p.baseUrl || "(\u9ED8\u8BA4\u7AEF\u70B9)"}`,
5215
+ value: p.id
5216
+ }))
5217
+ }
5218
+ ]);
5219
+ targetId = selectedId;
5220
+ }
5221
+ const provider = manager.get(targetId);
5222
+ const input = await promptProviderForm({
5223
+ name: provider.name,
5224
+ desc: provider.desc ?? "",
5225
+ baseUrl: provider.baseUrl,
5226
+ apiKey: provider.apiKey
5227
+ });
5228
+ manager.edit(targetId, {
5229
+ name: input.name,
5230
+ desc: input.desc,
5231
+ baseUrl: input.baseUrl,
5232
+ apiKey: input.apiKey
5233
+ });
5234
+ console.log(chalk36.green("\n\u2705 \u7F16\u8F91\u6210\u529F\n"));
5235
+ } catch (error) {
5236
+ console.error(chalk36.red(`
5237
+ \u274C ${error.message}
5238
+ `));
5239
+ process.exit(1);
5240
+ }
5241
+ });
5242
+ }
5243
+
5244
+ // src/commands/gemini/clone.ts
5245
+ init_dist();
5246
+ import chalk37 from "chalk";
5247
+ import inquirer26 from "inquirer";
5248
+ function cloneCommand3(program2) {
5249
+ program2.command("clone [name]").description("\u514B\u9686 Gemini CLI \u670D\u52A1\u5546").action(async (name) => {
5250
+ try {
5251
+ const manager = createGeminiManager();
5252
+ const providers = manager.list();
5253
+ if (providers.length === 0) {
5254
+ console.log(chalk37.yellow("\n\u26A0\uFE0F \u6682\u65E0 Gemini CLI \u670D\u52A1\u5546\n"));
5255
+ console.log(chalk37.blue("\u{1F4A1} \u6DFB\u52A0\u670D\u52A1\u5546:") + chalk37.white(" ccman gm add\n"));
5256
+ return;
5257
+ }
5258
+ let sourceId;
5259
+ if (name) {
5260
+ const provider = manager.findByName(name);
5261
+ if (!provider) {
5262
+ console.log(chalk37.red(`
5263
+ \u274C \u670D\u52A1\u5546\u4E0D\u5B58\u5728: ${name}
5264
+ `));
5265
+ process.exit(1);
5266
+ }
5267
+ sourceId = provider.id;
5268
+ } else {
5269
+ const { selectedId } = await inquirer26.prompt([
5270
+ {
5271
+ type: "list",
5272
+ name: "selectedId",
5273
+ message: "\u9009\u62E9\u8981\u514B\u9686\u7684\u670D\u52A1\u5546:",
5274
+ choices: providers.map((p) => ({
5275
+ name: `${p.name} - ${p.baseUrl || "(\u9ED8\u8BA4\u7AEF\u70B9)"}`,
5276
+ value: p.id
5277
+ }))
5278
+ }
5279
+ ]);
5280
+ sourceId = selectedId;
5281
+ }
5282
+ const { newName } = await inquirer26.prompt([
5283
+ {
5284
+ type: "input",
5285
+ name: "newName",
5286
+ message: "\u8F93\u5165\u65B0\u670D\u52A1\u5546\u540D\u79F0:",
5287
+ validate: (value) => {
5288
+ if (!value) return "\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A";
5289
+ return true;
5290
+ }
5291
+ }
5292
+ ]);
5293
+ const newProvider = manager.clone(sourceId, newName);
5294
+ console.log();
5295
+ console.log(chalk37.green("\u2705 \u514B\u9686\u6210\u529F"));
5296
+ console.log();
5297
+ console.log(` ${chalk37.bold(newProvider.name)} ${chalk37.blue("[Gemini CLI]")}`);
5298
+ console.log(` ${chalk37.gray(newProvider.baseUrl || "(\u9ED8\u8BA4\u7AEF\u70B9)")}`);
5299
+ console.log();
5300
+ } catch (error) {
5301
+ console.error(chalk37.red(`
5302
+ \u274C ${error.message}
5303
+ `));
5304
+ process.exit(1);
5305
+ }
5306
+ });
5307
+ }
5308
+
5309
+ // src/commands/gemini/index.ts
5310
+ function createGeminiCommands(program2) {
5311
+ addCommand4(program2);
5312
+ listCommand4(program2);
5313
+ useCommand3(program2);
5314
+ currentCommand3(program2);
5315
+ removeCommand4(program2);
5316
+ editCommand4(program2);
5317
+ cloneCommand3(program2);
5318
+ }
5319
+
4723
5320
  // src/index.ts
4724
5321
  init_sync();
4725
5322
 
4726
5323
  // src/commands/export.ts
4727
5324
  init_dist();
4728
- import chalk31 from "chalk";
5325
+ import chalk38 from "chalk";
4729
5326
  import path10 from "path";
4730
5327
  function exportCommand(program2) {
4731
5328
  program2.command("export <\u76EE\u6807\u76EE\u5F55>").description("\u5BFC\u51FA\u914D\u7F6E\u5230\u672C\u5730\u76EE\u5F55\uFF08\u5305\u542B API Key\uFF09").action(async (targetDir) => {
4732
5329
  try {
4733
- console.log(chalk31.bold("\n\u{1F4E6} \u5BFC\u51FA\u914D\u7F6E\n"));
5330
+ console.log(chalk38.bold("\n\u{1F4E6} \u5BFC\u51FA\u914D\u7F6E\n"));
4734
5331
  const validation = validateExport();
4735
5332
  if (!validation.valid) {
4736
- console.log(chalk31.red(`\u274C ${validation.message}
5333
+ console.log(chalk38.red(`\u274C ${validation.message}
4737
5334
  `));
4738
5335
  process.exit(1);
4739
5336
  }
4740
5337
  const resolvedPath = targetDir.startsWith("~") ? path10.join(process.env.HOME || "", targetDir.slice(1)) : path10.resolve(targetDir);
4741
5338
  console.log("\u5BFC\u51FA\u6587\u4EF6:");
4742
- console.log(` ${chalk31.cyan("codex.json")} - Codex \u914D\u7F6E`);
4743
- console.log(` ${chalk31.cyan("claude.json")} - Claude \u914D\u7F6E`);
5339
+ console.log(` ${chalk38.cyan("codex.json")} - Codex \u914D\u7F6E`);
5340
+ console.log(` ${chalk38.cyan("claude.json")} - Claude \u914D\u7F6E`);
4744
5341
  console.log();
4745
- console.log(`\u76EE\u6807\u76EE\u5F55: ${chalk31.cyan(resolvedPath)}`);
5342
+ console.log(`\u76EE\u6807\u76EE\u5F55: ${chalk38.cyan(resolvedPath)}`);
4746
5343
  console.log();
4747
- console.log(chalk31.yellow("\u26A0\uFE0F \u5BFC\u51FA\u6587\u4EF6\u5305\u542B API Key\uFF0C\u8BF7\u59A5\u5584\u4FDD\u7BA1"));
5344
+ console.log(chalk38.yellow("\u26A0\uFE0F \u5BFC\u51FA\u6587\u4EF6\u5305\u542B API Key\uFF0C\u8BF7\u59A5\u5584\u4FDD\u7BA1"));
4748
5345
  console.log();
4749
5346
  const result = exportConfig(resolvedPath);
4750
- console.log(chalk31.green("\u2705 \u5BFC\u51FA\u6210\u529F"));
5347
+ console.log(chalk38.green("\u2705 \u5BFC\u51FA\u6210\u529F"));
4751
5348
  console.log();
4752
5349
  console.log("\u5DF2\u5BFC\u51FA\u6587\u4EF6:");
4753
5350
  for (const file of result.exportedFiles) {
4754
- console.log(` ${chalk31.cyan("\u2713")} ${file}`);
5351
+ console.log(` ${chalk38.cyan("\u2713")} ${file}`);
4755
5352
  }
4756
5353
  console.log();
4757
- console.log(chalk31.blue(`\u{1F4A1} \u5BFC\u5165\u547D\u4EE4: ccman import ${resolvedPath}
5354
+ console.log(chalk38.blue(`\u{1F4A1} \u5BFC\u5165\u547D\u4EE4: ccman import ${resolvedPath}
4758
5355
  `));
4759
5356
  } catch (error) {
4760
- console.error(chalk31.red(`
5357
+ console.error(chalk38.red(`
4761
5358
  \u274C ${error.message}
4762
5359
  `));
4763
5360
  process.exit(1);
@@ -4767,31 +5364,31 @@ function exportCommand(program2) {
4767
5364
 
4768
5365
  // src/commands/import.ts
4769
5366
  init_dist();
4770
- import chalk32 from "chalk";
4771
- import inquirer22 from "inquirer";
5367
+ import chalk39 from "chalk";
5368
+ import inquirer27 from "inquirer";
4772
5369
  import path11 from "path";
4773
5370
  function importCommand(program2) {
4774
5371
  program2.command("import <\u6E90\u76EE\u5F55>").description("\u4ECE\u672C\u5730\u76EE\u5F55\u5BFC\u5165\u914D\u7F6E\uFF08\u4F1A\u8986\u76D6\u5F53\u524D\u914D\u7F6E\uFF09").action(async (sourceDir) => {
4775
5372
  try {
4776
5373
  const resolvedPath = sourceDir.startsWith("~") ? path11.join(process.env.HOME || "", sourceDir.slice(1)) : path11.resolve(sourceDir);
4777
- console.log(chalk32.bold("\n\u{1F4E5} \u5BFC\u5165\u914D\u7F6E\n"));
5374
+ console.log(chalk39.bold("\n\u{1F4E5} \u5BFC\u5165\u914D\u7F6E\n"));
4778
5375
  const validation = validateImportDir(resolvedPath);
4779
5376
  if (!validation.valid) {
4780
- console.log(chalk32.red(`\u274C ${validation.message}
5377
+ console.log(chalk39.red(`\u274C ${validation.message}
4781
5378
  `));
4782
5379
  process.exit(1);
4783
5380
  }
4784
- console.log(chalk32.yellow("\u26A0\uFE0F \u8B66\u544A\uFF1A\u5BFC\u5165\u5C06\u8986\u76D6\u5F53\u524D\u914D\u7F6E\n"));
4785
- console.log(`\u6E90\u76EE\u5F55: ${chalk32.cyan(resolvedPath)}`);
5381
+ console.log(chalk39.yellow("\u26A0\uFE0F \u8B66\u544A\uFF1A\u5BFC\u5165\u5C06\u8986\u76D6\u5F53\u524D\u914D\u7F6E\n"));
5382
+ console.log(`\u6E90\u76EE\u5F55: ${chalk39.cyan(resolvedPath)}`);
4786
5383
  console.log();
4787
5384
  console.log("\u627E\u5230\u914D\u7F6E\u6587\u4EF6:");
4788
5385
  for (const file of validation.foundFiles) {
4789
- console.log(` ${chalk32.cyan("\u2713")} ${file}`);
5386
+ console.log(` ${chalk39.cyan("\u2713")} ${file}`);
4790
5387
  }
4791
5388
  console.log();
4792
- console.log(chalk32.gray("\u5F53\u524D\u914D\u7F6E\u5C06\u88AB\u8986\u76D6\uFF08\u81EA\u52A8\u5907\u4EFD\uFF09"));
5389
+ console.log(chalk39.gray("\u5F53\u524D\u914D\u7F6E\u5C06\u88AB\u8986\u76D6\uFF08\u81EA\u52A8\u5907\u4EFD\uFF09"));
4793
5390
  console.log();
4794
- const { confirmFirst } = await inquirer22.prompt([
5391
+ const { confirmFirst } = await inquirer27.prompt([
4795
5392
  {
4796
5393
  type: "confirm",
4797
5394
  name: "confirmFirst",
@@ -4800,13 +5397,13 @@ function importCommand(program2) {
4800
5397
  }
4801
5398
  ]);
4802
5399
  if (!confirmFirst) {
4803
- console.log(chalk32.gray("\n\u274C \u5DF2\u53D6\u6D88\n"));
5400
+ console.log(chalk39.gray("\n\u274C \u5DF2\u53D6\u6D88\n"));
4804
5401
  return;
4805
5402
  }
4806
5403
  console.log();
4807
- console.log(chalk32.red.bold("\u26A0\uFE0F \u6700\u540E\u786E\u8BA4\uFF1A\u6B64\u64CD\u4F5C\u5C06\u8986\u76D6\u6240\u6709\u5F53\u524D\u914D\u7F6E\uFF01"));
5404
+ console.log(chalk39.red.bold("\u26A0\uFE0F \u6700\u540E\u786E\u8BA4\uFF1A\u6B64\u64CD\u4F5C\u5C06\u8986\u76D6\u6240\u6709\u5F53\u524D\u914D\u7F6E\uFF01"));
4808
5405
  console.log();
4809
- const { confirmSecond } = await inquirer22.prompt([
5406
+ const { confirmSecond } = await inquirer27.prompt([
4810
5407
  {
4811
5408
  type: "confirm",
4812
5409
  name: "confirmSecond",
@@ -4815,31 +5412,31 @@ function importCommand(program2) {
4815
5412
  }
4816
5413
  ]);
4817
5414
  if (!confirmSecond) {
4818
- console.log(chalk32.gray("\n\u274C \u5DF2\u53D6\u6D88\n"));
5415
+ console.log(chalk39.gray("\n\u274C \u5DF2\u53D6\u6D88\n"));
4819
5416
  return;
4820
5417
  }
4821
5418
  console.log();
4822
- console.log(chalk32.gray("\u{1F4BE} \u5907\u4EFD\u5F53\u524D\u914D\u7F6E..."));
4823
- console.log(chalk32.gray("\u{1F4E5} \u5BFC\u5165\u65B0\u914D\u7F6E..."));
5419
+ console.log(chalk39.gray("\u{1F4BE} \u5907\u4EFD\u5F53\u524D\u914D\u7F6E..."));
5420
+ console.log(chalk39.gray("\u{1F4E5} \u5BFC\u5165\u65B0\u914D\u7F6E..."));
4824
5421
  const result = importConfig(resolvedPath);
4825
5422
  console.log();
4826
- console.log(chalk32.green("\u2705 \u5BFC\u5165\u6210\u529F"));
5423
+ console.log(chalk39.green("\u2705 \u5BFC\u5165\u6210\u529F"));
4827
5424
  console.log();
4828
5425
  if (result.backupPaths.length > 0) {
4829
5426
  console.log("\u5907\u4EFD\u6587\u4EF6:");
4830
5427
  for (const backupPath of result.backupPaths) {
4831
- console.log(` ${chalk32.gray(backupPath)}`);
5428
+ console.log(` ${chalk39.gray(backupPath)}`);
4832
5429
  }
4833
5430
  console.log();
4834
5431
  }
4835
5432
  console.log("\u5DF2\u5BFC\u5165\u6587\u4EF6:");
4836
5433
  for (const file of result.importedFiles) {
4837
- console.log(` ${chalk32.cyan("\u2713")} ${file}`);
5434
+ console.log(` ${chalk39.cyan("\u2713")} ${file}`);
4838
5435
  }
4839
5436
  console.log();
4840
- console.log(chalk32.blue("\u{1F4A1} \u8BF7\u4F7F\u7528 'ccman cx use' \u6216 'ccman cc use' \u5207\u6362\u670D\u52A1\u5546\n"));
5437
+ console.log(chalk39.blue("\u{1F4A1} \u8BF7\u4F7F\u7528 'ccman cx use' \u6216 'ccman cc use' \u5207\u6362\u670D\u52A1\u5546\n"));
4841
5438
  } catch (error) {
4842
- console.error(chalk32.red(`
5439
+ console.error(chalk39.red(`
4843
5440
  \u274C ${error.message}
4844
5441
  `));
4845
5442
  process.exit(1);
@@ -4850,10 +5447,10 @@ function importCommand(program2) {
4850
5447
  // src/index.ts
4851
5448
  init_dist();
4852
5449
  if (process.env.NODE_ENV === "development") {
4853
- console.log(chalk33.gray("\n[\u5F00\u53D1\u6A21\u5F0F] \u914D\u7F6E\u76EE\u5F55:"));
4854
- console.log(chalk33.gray(` ccman: ${getCcmanDir()}`));
4855
- console.log(chalk33.gray(` codex: ${getCodexDir()}`));
4856
- console.log(chalk33.gray(` claude: ${getClaudeDir()}`));
5450
+ console.log(chalk40.gray("\n[\u5F00\u53D1\u6A21\u5F0F] \u914D\u7F6E\u76EE\u5F55:"));
5451
+ console.log(chalk40.gray(` ccman: ${getCcmanDir()}`));
5452
+ console.log(chalk40.gray(` codex: ${getCodexDir()}`));
5453
+ console.log(chalk40.gray(` claude: ${getClaudeDir()}`));
4857
5454
  console.log();
4858
5455
  }
4859
5456
  var program = new Command3();
@@ -4865,21 +5462,21 @@ program.name("ccman").description("Codex/Claude Code API \u670D\u52A1\u5546\u914
4865
5462
  });
4866
5463
  program.on("command:*", (operands) => {
4867
5464
  const unknownCommand = operands[0];
4868
- console.error(chalk33.red(`
5465
+ console.error(chalk40.red(`
4869
5466
  \u274C \u672A\u77E5\u547D\u4EE4: ${unknownCommand}
4870
5467
  `));
4871
- const availableCommands = ["cx", "cc", "mcp", "sync", "export", "import"];
5468
+ const availableCommands = ["cx", "cc", "gm", "mcp", "sync", "export", "import"];
4872
5469
  const suggestions = availableCommands.filter(
4873
5470
  (cmd) => cmd.includes(unknownCommand) || unknownCommand.includes(cmd)
4874
5471
  );
4875
5472
  if (suggestions.length > 0) {
4876
- console.log(chalk33.yellow("\u{1F4A1} \u4F60\u662F\u4E0D\u662F\u60F3\u8F93\u5165:"));
5473
+ console.log(chalk40.yellow("\u{1F4A1} \u4F60\u662F\u4E0D\u662F\u60F3\u8F93\u5165:"));
4877
5474
  suggestions.forEach((cmd) => {
4878
- console.log(chalk33.cyan(` ccman ${cmd}`));
5475
+ console.log(chalk40.cyan(` ccman ${cmd}`));
4879
5476
  });
4880
5477
  console.log();
4881
5478
  }
4882
- console.log(chalk33.gray("\u67E5\u770B\u6240\u6709\u53EF\u7528\u547D\u4EE4: ") + chalk33.cyan("ccman --help"));
5479
+ console.log(chalk40.gray("\u67E5\u770B\u6240\u6709\u53EF\u7528\u547D\u4EE4: ") + chalk40.cyan("ccman --help"));
4883
5480
  console.log();
4884
5481
  process.exit(1);
4885
5482
  });
@@ -4895,6 +5492,12 @@ cc.action(async () => {
4895
5492
  printLogo();
4896
5493
  await startClaudeMenu();
4897
5494
  });
5495
+ var gm = program.command("gm").description("\u7BA1\u7406 Gemini CLI \u670D\u52A1\u5546");
5496
+ createGeminiCommands(gm);
5497
+ gm.action(async () => {
5498
+ printLogo();
5499
+ await startGeminiMenu();
5500
+ });
4898
5501
  var mcp = program.command("mcp").description("\u7BA1\u7406 MCP \u670D\u52A1\u5668");
4899
5502
  createMCPCommands(mcp);
4900
5503
  mcp.action(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccman",
3
- "version": "3.0.32",
3
+ "version": "3.1.0",
4
4
  "type": "module",
5
5
  "description": "Manage Codex and Claude Code API service provider configurations",
6
6
  "main": "./dist/index.js",
@@ -25,12 +25,12 @@
25
25
  "license": "MIT",
26
26
  "repository": {
27
27
  "type": "git",
28
- "url": "https://github.com/2ue/ccm.git",
28
+ "url": "https://github.com/2ue/ccman.git",
29
29
  "directory": "packages/cli"
30
30
  },
31
- "homepage": "https://github.com/2ue/ccm#readme",
31
+ "homepage": "https://github.com/2ue/ccman#readme",
32
32
  "bugs": {
33
- "url": "https://github.com/2ue/ccm/issues"
33
+ "url": "https://github.com/2ue/ccman/issues"
34
34
  },
35
35
  "dependencies": {
36
36
  "@iarna/toml": "^2.2.5",