ccman 3.0.33 → 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.
- package/README.md +6 -6
- package/dist/index.js +701 -110
- 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/
|
|
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/
|
|
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/
|
|
294
|
-
- [问题反馈](https://github.com/2ue/
|
|
295
|
-
- [更新日志](https://github.com/2ue/
|
|
296
|
-
- [Desktop 版本](https://github.com/2ue/
|
|
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
|
|
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/
|
|
46
|
+
url: "https://github.com/2ue/ccman.git",
|
|
47
47
|
directory: "packages/core"
|
|
48
48
|
},
|
|
49
|
-
homepage: "https://github.com/2ue/
|
|
49
|
+
homepage: "https://github.com/2ue/ccman#readme",
|
|
50
50
|
bugs: {
|
|
51
|
-
url: "https://github.com/2ue/
|
|
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
|
-
|
|
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
|
-
|
|
348
|
-
windsurf: []
|
|
357
|
+
gemini: []
|
|
349
358
|
};
|
|
350
359
|
} else if (!config.managedServerNames) {
|
|
351
360
|
config.managedServerNames = {
|
|
352
361
|
claude: [],
|
|
353
362
|
codex: [],
|
|
354
|
-
|
|
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
|
-
|
|
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 "
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
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", "
|
|
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
|
|
1109
|
+
import * as fs6 from "fs";
|
|
972
1110
|
function ensureConfigDir() {
|
|
973
1111
|
const dir = getCcmanDir();
|
|
974
|
-
if (!
|
|
975
|
-
|
|
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 (!
|
|
1118
|
+
if (!fs6.existsSync(configPath)) {
|
|
981
1119
|
return {};
|
|
982
1120
|
}
|
|
983
1121
|
try {
|
|
984
|
-
const content =
|
|
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
|
-
|
|
1133
|
+
fs6.writeFileSync(tempPath, JSON.stringify(config, null, 2), {
|
|
996
1134
|
mode: 384
|
|
997
1135
|
});
|
|
998
|
-
|
|
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
|
|
1460
|
+
import fs7 from "fs";
|
|
1323
1461
|
import path7 from "path";
|
|
1324
1462
|
function backupConfig(configPath, keepCount = 3) {
|
|
1325
|
-
if (!
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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 (
|
|
1565
|
+
if (fs8.existsSync(codexConfigPath)) {
|
|
1428
1566
|
backupPaths.push(backupConfig(codexConfigPath));
|
|
1429
1567
|
}
|
|
1430
|
-
if (
|
|
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 (
|
|
1464
|
-
|
|
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 (
|
|
1652
|
+
if (fs8.existsSync(codexConfigPath)) {
|
|
1515
1653
|
backupPaths.push(backupConfig(codexConfigPath));
|
|
1516
1654
|
}
|
|
1517
|
-
if (
|
|
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 (
|
|
1574
|
-
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 =
|
|
1904
|
+
const stats = fs10.statSync(filePath);
|
|
1767
1905
|
return stats.size;
|
|
1768
1906
|
} catch {
|
|
1769
1907
|
return 0;
|
|
@@ -1772,18 +1910,18 @@ 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
|
-
|
|
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
|
-
|
|
1782
|
-
|
|
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 (!
|
|
1924
|
+
if (!fs10.existsSync(filePath)) {
|
|
1787
1925
|
return {
|
|
1788
1926
|
fileSize: 0,
|
|
1789
1927
|
fileSizeFormatted: "0 B",
|
|
@@ -1799,7 +1937,7 @@ function analyzeClaudeJson() {
|
|
|
1799
1937
|
};
|
|
1800
1938
|
}
|
|
1801
1939
|
const fileSize = getFileSize(filePath);
|
|
1802
|
-
const content =
|
|
1940
|
+
const content = fs10.readFileSync(filePath, "utf-8");
|
|
1803
1941
|
const config = JSON.parse(content);
|
|
1804
1942
|
const projects = config.projects || {};
|
|
1805
1943
|
const projectHistory = [];
|
|
@@ -1833,12 +1971,12 @@ function analyzeClaudeJson() {
|
|
|
1833
1971
|
}
|
|
1834
1972
|
function cleanClaudeJson(options = {}) {
|
|
1835
1973
|
const filePath = getClaudeJsonPath();
|
|
1836
|
-
if (!
|
|
1974
|
+
if (!fs10.existsSync(filePath)) {
|
|
1837
1975
|
throw new Error(`${filePath} \u6587\u4EF6\u4E0D\u5B58\u5728`);
|
|
1838
1976
|
}
|
|
1839
1977
|
const backupPath = backupFile(filePath);
|
|
1840
1978
|
const sizeBefore = getFileSize(filePath);
|
|
1841
|
-
const content =
|
|
1979
|
+
const content = fs10.readFileSync(filePath, "utf-8");
|
|
1842
1980
|
const config = JSON.parse(content);
|
|
1843
1981
|
const cleanedItems = applyCleanOptions(config, options);
|
|
1844
1982
|
saveJsonAtomic(filePath, config);
|
|
@@ -1923,6 +2061,7 @@ var init_dist = __esm({
|
|
|
1923
2061
|
init_codex2();
|
|
1924
2062
|
init_claude2();
|
|
1925
2063
|
init_mcp2();
|
|
2064
|
+
init_gemini();
|
|
1926
2065
|
init_mcp();
|
|
1927
2066
|
init_migrate();
|
|
1928
2067
|
init_paths();
|
|
@@ -2646,7 +2785,7 @@ var init_sync = __esm({
|
|
|
2646
2785
|
|
|
2647
2786
|
// src/index.ts
|
|
2648
2787
|
import { Command as Command3 } from "commander";
|
|
2649
|
-
import
|
|
2788
|
+
import chalk40 from "chalk";
|
|
2650
2789
|
|
|
2651
2790
|
// src/utils/logo.ts
|
|
2652
2791
|
init_dist();
|
|
@@ -2705,6 +2844,11 @@ function formatProviderTable(providers, currentId) {
|
|
|
2705
2844
|
}
|
|
2706
2845
|
|
|
2707
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
|
+
};
|
|
2708
2852
|
async function promptProviderForm(defaults) {
|
|
2709
2853
|
const answers = await inquirer7.prompt([
|
|
2710
2854
|
{
|
|
@@ -2766,6 +2910,7 @@ async function startMainMenu() {
|
|
|
2766
2910
|
choices: [
|
|
2767
2911
|
{ name: "\u{1F537} Claude \u7BA1\u7406", value: "claude" },
|
|
2768
2912
|
{ name: "\u{1F536} Codex \u7BA1\u7406", value: "codex" },
|
|
2913
|
+
{ name: "\u{1F48E} Gemini \u7BA1\u7406", value: "gemini" },
|
|
2769
2914
|
{ name: "\u{1F504} WebDAV \u540C\u6B65", value: "sync" },
|
|
2770
2915
|
{ name: "\u{1F4E6} \u9884\u7F6E\u670D\u52A1\u5546\u7BA1\u7406", value: "presets" },
|
|
2771
2916
|
{ name: "\u274C \u9000\u51FA", value: "exit" }
|
|
@@ -2780,6 +2925,8 @@ async function startMainMenu() {
|
|
|
2780
2925
|
await startClaudeMenu();
|
|
2781
2926
|
} else if (choice === "codex") {
|
|
2782
2927
|
await startCodexMenu();
|
|
2928
|
+
} else if (choice === "gemini") {
|
|
2929
|
+
await startGeminiMenu();
|
|
2783
2930
|
} else if (choice === "sync") {
|
|
2784
2931
|
const { startSyncMenu: startSyncMenu2 } = await Promise.resolve().then(() => (init_sync(), sync_exports));
|
|
2785
2932
|
await startSyncMenu2();
|
|
@@ -2794,9 +2941,11 @@ async function startClaudeMenu() {
|
|
|
2794
2941
|
async function startCodexMenu() {
|
|
2795
2942
|
await showToolMenu("codex");
|
|
2796
2943
|
}
|
|
2944
|
+
async function startGeminiMenu() {
|
|
2945
|
+
await showToolMenu("gemini");
|
|
2946
|
+
}
|
|
2797
2947
|
async function showToolMenu(tool) {
|
|
2798
|
-
const
|
|
2799
|
-
const toolEmoji = tool === "claude" ? "\u{1F537}" : "\u{1F536}";
|
|
2948
|
+
const { name: toolName, emoji: toolEmoji } = TOOL_CONFIG[tool];
|
|
2800
2949
|
while (true) {
|
|
2801
2950
|
console.log();
|
|
2802
2951
|
const { action } = await inquirer7.prompt([
|
|
@@ -2861,8 +3010,8 @@ async function showPresetsMenu() {
|
|
|
2861
3010
|
console.log(chalk11.yellow("\n\u26A0\uFE0F \u9884\u7F6E\u670D\u52A1\u5546\u7BA1\u7406\u529F\u80FD\u5373\u5C06\u63A8\u51FA\n"));
|
|
2862
3011
|
}
|
|
2863
3012
|
async function handleAdd(tool) {
|
|
2864
|
-
const manager = tool === "codex" ? createCodexManager() : createClaudeManager();
|
|
2865
|
-
const
|
|
3013
|
+
const manager = tool === "codex" ? createCodexManager() : tool === "claude" ? createClaudeManager() : createGeminiManager();
|
|
3014
|
+
const { name: toolName, cmd } = TOOL_CONFIG[tool];
|
|
2866
3015
|
const presets = manager.listPresets();
|
|
2867
3016
|
console.log(chalk11.bold(`
|
|
2868
3017
|
\u{1F4DD} \u6DFB\u52A0 ${toolName} \u670D\u52A1\u5546
|
|
@@ -2961,13 +3110,13 @@ async function handleAdd(tool) {
|
|
|
2961
3110
|
console.log(chalk11.green("\u2705 \u5DF2\u5207\u6362\u5230\u65B0\u670D\u52A1\u5546\n"));
|
|
2962
3111
|
} else {
|
|
2963
3112
|
console.log(
|
|
2964
|
-
chalk11.blue("\u{1F4A1} \u7A0D\u540E\u5207\u6362:") + chalk11.white(` ccman ${
|
|
3113
|
+
chalk11.blue("\u{1F4A1} \u7A0D\u540E\u5207\u6362:") + chalk11.white(` ccman ${cmd} use "${provider.name}"
|
|
2965
3114
|
`)
|
|
2966
3115
|
);
|
|
2967
3116
|
}
|
|
2968
3117
|
}
|
|
2969
3118
|
async function handleSwitch(tool) {
|
|
2970
|
-
const manager = tool === "codex" ? createCodexManager() : createClaudeManager();
|
|
3119
|
+
const manager = tool === "codex" ? createCodexManager() : tool === "claude" ? createClaudeManager() : createGeminiManager();
|
|
2971
3120
|
const providers = manager.list();
|
|
2972
3121
|
const current = manager.getCurrent();
|
|
2973
3122
|
if (providers.length === 0) {
|
|
@@ -2992,10 +3141,10 @@ async function handleSwitch(tool) {
|
|
|
2992
3141
|
`));
|
|
2993
3142
|
}
|
|
2994
3143
|
async function handleList(tool) {
|
|
2995
|
-
const manager = tool === "codex" ? createCodexManager() : createClaudeManager();
|
|
3144
|
+
const manager = tool === "codex" ? createCodexManager() : tool === "claude" ? createClaudeManager() : createGeminiManager();
|
|
2996
3145
|
const providers = manager.list();
|
|
2997
3146
|
const current = manager.getCurrent();
|
|
2998
|
-
const toolName = tool
|
|
3147
|
+
const { name: toolName } = TOOL_CONFIG[tool];
|
|
2999
3148
|
if (providers.length === 0) {
|
|
3000
3149
|
console.log(chalk11.yellow(`
|
|
3001
3150
|
\u26A0\uFE0F \u6682\u65E0 ${toolName} \u670D\u52A1\u5546
|
|
@@ -3007,9 +3156,9 @@ async function handleList(tool) {
|
|
|
3007
3156
|
console.log(formatProviderTable(providers, current?.id));
|
|
3008
3157
|
}
|
|
3009
3158
|
async function handleCurrent(tool) {
|
|
3010
|
-
const manager = tool === "codex" ? createCodexManager() : createClaudeManager();
|
|
3159
|
+
const manager = tool === "codex" ? createCodexManager() : tool === "claude" ? createClaudeManager() : createGeminiManager();
|
|
3011
3160
|
const current = manager.getCurrent();
|
|
3012
|
-
const toolName = tool
|
|
3161
|
+
const { name: toolName } = TOOL_CONFIG[tool];
|
|
3013
3162
|
if (!current) {
|
|
3014
3163
|
console.log(chalk11.yellow(`
|
|
3015
3164
|
\u26A0\uFE0F \u672A\u9009\u62E9\u4EFB\u4F55 ${toolName} \u670D\u52A1\u5546
|
|
@@ -3028,7 +3177,7 @@ async function handleCurrent(tool) {
|
|
|
3028
3177
|
console.log();
|
|
3029
3178
|
}
|
|
3030
3179
|
async function handleEdit(tool) {
|
|
3031
|
-
const manager = tool === "codex" ? createCodexManager() : createClaudeManager();
|
|
3180
|
+
const manager = tool === "codex" ? createCodexManager() : tool === "claude" ? createClaudeManager() : createGeminiManager();
|
|
3032
3181
|
const providers = manager.list();
|
|
3033
3182
|
if (providers.length === 0) {
|
|
3034
3183
|
console.log(chalk11.yellow("\n\u26A0\uFE0F \u6682\u65E0\u670D\u52A1\u5546\n"));
|
|
@@ -3089,7 +3238,7 @@ async function handleEdit(tool) {
|
|
|
3089
3238
|
console.log(chalk11.green("\n\u2705 \u7F16\u8F91\u6210\u529F\n"));
|
|
3090
3239
|
}
|
|
3091
3240
|
async function handleClone(tool) {
|
|
3092
|
-
const manager = tool === "codex" ? createCodexManager() : createClaudeManager();
|
|
3241
|
+
const manager = tool === "codex" ? createCodexManager() : tool === "claude" ? createClaudeManager() : createGeminiManager();
|
|
3093
3242
|
const providers = manager.list();
|
|
3094
3243
|
if (providers.length === 0) {
|
|
3095
3244
|
console.log(chalk11.yellow("\n\u26A0\uFE0F \u6682\u65E0\u670D\u52A1\u5546\n"));
|
|
@@ -3136,7 +3285,7 @@ async function handleClone(tool) {
|
|
|
3136
3285
|
console.log();
|
|
3137
3286
|
}
|
|
3138
3287
|
async function handleRemove(tool) {
|
|
3139
|
-
const manager = tool === "codex" ? createCodexManager() : createClaudeManager();
|
|
3288
|
+
const manager = tool === "codex" ? createCodexManager() : tool === "claude" ? createClaudeManager() : createGeminiManager();
|
|
3140
3289
|
const providers = manager.list();
|
|
3141
3290
|
if (providers.length === 0) {
|
|
3142
3291
|
console.log(chalk11.yellow("\n\u26A0\uFE0F \u6682\u65E0\u670D\u52A1\u5546\n"));
|
|
@@ -4648,7 +4797,7 @@ function editCommand3(program2) {
|
|
|
4648
4797
|
targetId = selectedId;
|
|
4649
4798
|
}
|
|
4650
4799
|
const provider = manager.get(targetId);
|
|
4651
|
-
const
|
|
4800
|
+
const currentCommand4 = provider.baseUrl;
|
|
4652
4801
|
const currentArgs = provider.apiKey;
|
|
4653
4802
|
const currentEnv = provider.model;
|
|
4654
4803
|
console.log(chalk30.bold("\n\u270F\uFE0F \u7F16\u8F91 MCP \u670D\u52A1\u5668\n"));
|
|
@@ -4664,7 +4813,7 @@ function editCommand3(program2) {
|
|
|
4664
4813
|
type: "input",
|
|
4665
4814
|
name: "command",
|
|
4666
4815
|
message: "\u542F\u52A8\u547D\u4EE4:",
|
|
4667
|
-
default:
|
|
4816
|
+
default: currentCommand4
|
|
4668
4817
|
},
|
|
4669
4818
|
{
|
|
4670
4819
|
type: "input",
|
|
@@ -4683,7 +4832,7 @@ function editCommand3(program2) {
|
|
|
4683
4832
|
if (answers.name && answers.name !== provider.name) {
|
|
4684
4833
|
updates.name = answers.name;
|
|
4685
4834
|
}
|
|
4686
|
-
if (answers.command && answers.command !==
|
|
4835
|
+
if (answers.command && answers.command !== currentCommand4) {
|
|
4687
4836
|
updates.baseUrl = answers.command;
|
|
4688
4837
|
}
|
|
4689
4838
|
if (answers.args && answers.args !== currentArgs) {
|
|
@@ -4732,44 +4881,480 @@ function createMCPCommands(program2) {
|
|
|
4732
4881
|
editCommand3(program2);
|
|
4733
4882
|
}
|
|
4734
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
|
+
|
|
4735
5320
|
// src/index.ts
|
|
4736
5321
|
init_sync();
|
|
4737
5322
|
|
|
4738
5323
|
// src/commands/export.ts
|
|
4739
5324
|
init_dist();
|
|
4740
|
-
import
|
|
5325
|
+
import chalk38 from "chalk";
|
|
4741
5326
|
import path10 from "path";
|
|
4742
5327
|
function exportCommand(program2) {
|
|
4743
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) => {
|
|
4744
5329
|
try {
|
|
4745
|
-
console.log(
|
|
5330
|
+
console.log(chalk38.bold("\n\u{1F4E6} \u5BFC\u51FA\u914D\u7F6E\n"));
|
|
4746
5331
|
const validation = validateExport();
|
|
4747
5332
|
if (!validation.valid) {
|
|
4748
|
-
console.log(
|
|
5333
|
+
console.log(chalk38.red(`\u274C ${validation.message}
|
|
4749
5334
|
`));
|
|
4750
5335
|
process.exit(1);
|
|
4751
5336
|
}
|
|
4752
5337
|
const resolvedPath = targetDir.startsWith("~") ? path10.join(process.env.HOME || "", targetDir.slice(1)) : path10.resolve(targetDir);
|
|
4753
5338
|
console.log("\u5BFC\u51FA\u6587\u4EF6:");
|
|
4754
|
-
console.log(` ${
|
|
4755
|
-
console.log(` ${
|
|
5339
|
+
console.log(` ${chalk38.cyan("codex.json")} - Codex \u914D\u7F6E`);
|
|
5340
|
+
console.log(` ${chalk38.cyan("claude.json")} - Claude \u914D\u7F6E`);
|
|
4756
5341
|
console.log();
|
|
4757
|
-
console.log(`\u76EE\u6807\u76EE\u5F55: ${
|
|
5342
|
+
console.log(`\u76EE\u6807\u76EE\u5F55: ${chalk38.cyan(resolvedPath)}`);
|
|
4758
5343
|
console.log();
|
|
4759
|
-
console.log(
|
|
5344
|
+
console.log(chalk38.yellow("\u26A0\uFE0F \u5BFC\u51FA\u6587\u4EF6\u5305\u542B API Key\uFF0C\u8BF7\u59A5\u5584\u4FDD\u7BA1"));
|
|
4760
5345
|
console.log();
|
|
4761
5346
|
const result = exportConfig(resolvedPath);
|
|
4762
|
-
console.log(
|
|
5347
|
+
console.log(chalk38.green("\u2705 \u5BFC\u51FA\u6210\u529F"));
|
|
4763
5348
|
console.log();
|
|
4764
5349
|
console.log("\u5DF2\u5BFC\u51FA\u6587\u4EF6:");
|
|
4765
5350
|
for (const file of result.exportedFiles) {
|
|
4766
|
-
console.log(` ${
|
|
5351
|
+
console.log(` ${chalk38.cyan("\u2713")} ${file}`);
|
|
4767
5352
|
}
|
|
4768
5353
|
console.log();
|
|
4769
|
-
console.log(
|
|
5354
|
+
console.log(chalk38.blue(`\u{1F4A1} \u5BFC\u5165\u547D\u4EE4: ccman import ${resolvedPath}
|
|
4770
5355
|
`));
|
|
4771
5356
|
} catch (error) {
|
|
4772
|
-
console.error(
|
|
5357
|
+
console.error(chalk38.red(`
|
|
4773
5358
|
\u274C ${error.message}
|
|
4774
5359
|
`));
|
|
4775
5360
|
process.exit(1);
|
|
@@ -4779,31 +5364,31 @@ function exportCommand(program2) {
|
|
|
4779
5364
|
|
|
4780
5365
|
// src/commands/import.ts
|
|
4781
5366
|
init_dist();
|
|
4782
|
-
import
|
|
4783
|
-
import
|
|
5367
|
+
import chalk39 from "chalk";
|
|
5368
|
+
import inquirer27 from "inquirer";
|
|
4784
5369
|
import path11 from "path";
|
|
4785
5370
|
function importCommand(program2) {
|
|
4786
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) => {
|
|
4787
5372
|
try {
|
|
4788
5373
|
const resolvedPath = sourceDir.startsWith("~") ? path11.join(process.env.HOME || "", sourceDir.slice(1)) : path11.resolve(sourceDir);
|
|
4789
|
-
console.log(
|
|
5374
|
+
console.log(chalk39.bold("\n\u{1F4E5} \u5BFC\u5165\u914D\u7F6E\n"));
|
|
4790
5375
|
const validation = validateImportDir(resolvedPath);
|
|
4791
5376
|
if (!validation.valid) {
|
|
4792
|
-
console.log(
|
|
5377
|
+
console.log(chalk39.red(`\u274C ${validation.message}
|
|
4793
5378
|
`));
|
|
4794
5379
|
process.exit(1);
|
|
4795
5380
|
}
|
|
4796
|
-
console.log(
|
|
4797
|
-
console.log(`\u6E90\u76EE\u5F55: ${
|
|
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)}`);
|
|
4798
5383
|
console.log();
|
|
4799
5384
|
console.log("\u627E\u5230\u914D\u7F6E\u6587\u4EF6:");
|
|
4800
5385
|
for (const file of validation.foundFiles) {
|
|
4801
|
-
console.log(` ${
|
|
5386
|
+
console.log(` ${chalk39.cyan("\u2713")} ${file}`);
|
|
4802
5387
|
}
|
|
4803
5388
|
console.log();
|
|
4804
|
-
console.log(
|
|
5389
|
+
console.log(chalk39.gray("\u5F53\u524D\u914D\u7F6E\u5C06\u88AB\u8986\u76D6\uFF08\u81EA\u52A8\u5907\u4EFD\uFF09"));
|
|
4805
5390
|
console.log();
|
|
4806
|
-
const { confirmFirst } = await
|
|
5391
|
+
const { confirmFirst } = await inquirer27.prompt([
|
|
4807
5392
|
{
|
|
4808
5393
|
type: "confirm",
|
|
4809
5394
|
name: "confirmFirst",
|
|
@@ -4812,13 +5397,13 @@ function importCommand(program2) {
|
|
|
4812
5397
|
}
|
|
4813
5398
|
]);
|
|
4814
5399
|
if (!confirmFirst) {
|
|
4815
|
-
console.log(
|
|
5400
|
+
console.log(chalk39.gray("\n\u274C \u5DF2\u53D6\u6D88\n"));
|
|
4816
5401
|
return;
|
|
4817
5402
|
}
|
|
4818
5403
|
console.log();
|
|
4819
|
-
console.log(
|
|
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"));
|
|
4820
5405
|
console.log();
|
|
4821
|
-
const { confirmSecond } = await
|
|
5406
|
+
const { confirmSecond } = await inquirer27.prompt([
|
|
4822
5407
|
{
|
|
4823
5408
|
type: "confirm",
|
|
4824
5409
|
name: "confirmSecond",
|
|
@@ -4827,31 +5412,31 @@ function importCommand(program2) {
|
|
|
4827
5412
|
}
|
|
4828
5413
|
]);
|
|
4829
5414
|
if (!confirmSecond) {
|
|
4830
|
-
console.log(
|
|
5415
|
+
console.log(chalk39.gray("\n\u274C \u5DF2\u53D6\u6D88\n"));
|
|
4831
5416
|
return;
|
|
4832
5417
|
}
|
|
4833
5418
|
console.log();
|
|
4834
|
-
console.log(
|
|
4835
|
-
console.log(
|
|
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..."));
|
|
4836
5421
|
const result = importConfig(resolvedPath);
|
|
4837
5422
|
console.log();
|
|
4838
|
-
console.log(
|
|
5423
|
+
console.log(chalk39.green("\u2705 \u5BFC\u5165\u6210\u529F"));
|
|
4839
5424
|
console.log();
|
|
4840
5425
|
if (result.backupPaths.length > 0) {
|
|
4841
5426
|
console.log("\u5907\u4EFD\u6587\u4EF6:");
|
|
4842
5427
|
for (const backupPath of result.backupPaths) {
|
|
4843
|
-
console.log(` ${
|
|
5428
|
+
console.log(` ${chalk39.gray(backupPath)}`);
|
|
4844
5429
|
}
|
|
4845
5430
|
console.log();
|
|
4846
5431
|
}
|
|
4847
5432
|
console.log("\u5DF2\u5BFC\u5165\u6587\u4EF6:");
|
|
4848
5433
|
for (const file of result.importedFiles) {
|
|
4849
|
-
console.log(` ${
|
|
5434
|
+
console.log(` ${chalk39.cyan("\u2713")} ${file}`);
|
|
4850
5435
|
}
|
|
4851
5436
|
console.log();
|
|
4852
|
-
console.log(
|
|
5437
|
+
console.log(chalk39.blue("\u{1F4A1} \u8BF7\u4F7F\u7528 'ccman cx use' \u6216 'ccman cc use' \u5207\u6362\u670D\u52A1\u5546\n"));
|
|
4853
5438
|
} catch (error) {
|
|
4854
|
-
console.error(
|
|
5439
|
+
console.error(chalk39.red(`
|
|
4855
5440
|
\u274C ${error.message}
|
|
4856
5441
|
`));
|
|
4857
5442
|
process.exit(1);
|
|
@@ -4862,10 +5447,10 @@ function importCommand(program2) {
|
|
|
4862
5447
|
// src/index.ts
|
|
4863
5448
|
init_dist();
|
|
4864
5449
|
if (process.env.NODE_ENV === "development") {
|
|
4865
|
-
console.log(
|
|
4866
|
-
console.log(
|
|
4867
|
-
console.log(
|
|
4868
|
-
console.log(
|
|
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()}`));
|
|
4869
5454
|
console.log();
|
|
4870
5455
|
}
|
|
4871
5456
|
var program = new Command3();
|
|
@@ -4877,21 +5462,21 @@ program.name("ccman").description("Codex/Claude Code API \u670D\u52A1\u5546\u914
|
|
|
4877
5462
|
});
|
|
4878
5463
|
program.on("command:*", (operands) => {
|
|
4879
5464
|
const unknownCommand = operands[0];
|
|
4880
|
-
console.error(
|
|
5465
|
+
console.error(chalk40.red(`
|
|
4881
5466
|
\u274C \u672A\u77E5\u547D\u4EE4: ${unknownCommand}
|
|
4882
5467
|
`));
|
|
4883
|
-
const availableCommands = ["cx", "cc", "mcp", "sync", "export", "import"];
|
|
5468
|
+
const availableCommands = ["cx", "cc", "gm", "mcp", "sync", "export", "import"];
|
|
4884
5469
|
const suggestions = availableCommands.filter(
|
|
4885
5470
|
(cmd) => cmd.includes(unknownCommand) || unknownCommand.includes(cmd)
|
|
4886
5471
|
);
|
|
4887
5472
|
if (suggestions.length > 0) {
|
|
4888
|
-
console.log(
|
|
5473
|
+
console.log(chalk40.yellow("\u{1F4A1} \u4F60\u662F\u4E0D\u662F\u60F3\u8F93\u5165:"));
|
|
4889
5474
|
suggestions.forEach((cmd) => {
|
|
4890
|
-
console.log(
|
|
5475
|
+
console.log(chalk40.cyan(` ccman ${cmd}`));
|
|
4891
5476
|
});
|
|
4892
5477
|
console.log();
|
|
4893
5478
|
}
|
|
4894
|
-
console.log(
|
|
5479
|
+
console.log(chalk40.gray("\u67E5\u770B\u6240\u6709\u53EF\u7528\u547D\u4EE4: ") + chalk40.cyan("ccman --help"));
|
|
4895
5480
|
console.log();
|
|
4896
5481
|
process.exit(1);
|
|
4897
5482
|
});
|
|
@@ -4907,6 +5492,12 @@ cc.action(async () => {
|
|
|
4907
5492
|
printLogo();
|
|
4908
5493
|
await startClaudeMenu();
|
|
4909
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
|
+
});
|
|
4910
5501
|
var mcp = program.command("mcp").description("\u7BA1\u7406 MCP \u670D\u52A1\u5668");
|
|
4911
5502
|
createMCPCommands(mcp);
|
|
4912
5503
|
mcp.action(() => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ccman",
|
|
3
|
-
"version": "3.0
|
|
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/
|
|
28
|
+
"url": "https://github.com/2ue/ccman.git",
|
|
29
29
|
"directory": "packages/cli"
|
|
30
30
|
},
|
|
31
|
-
"homepage": "https://github.com/2ue/
|
|
31
|
+
"homepage": "https://github.com/2ue/ccman#readme",
|
|
32
32
|
"bugs": {
|
|
33
|
-
"url": "https://github.com/2ue/
|
|
33
|
+
"url": "https://github.com/2ue/ccman/issues"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@iarna/toml": "^2.2.5",
|