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.
- package/README.md +6 -6
- package/dist/index.js +715 -112
- 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,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
|
-
|
|
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 (!
|
|
1787
|
-
|
|
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 =
|
|
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 (!
|
|
1825
|
-
throw new Error(
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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 ${
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
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 !==
|
|
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
|
|
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(
|
|
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(
|
|
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(` ${
|
|
4743
|
-
console.log(` ${
|
|
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: ${
|
|
5342
|
+
console.log(`\u76EE\u6807\u76EE\u5F55: ${chalk38.cyan(resolvedPath)}`);
|
|
4746
5343
|
console.log();
|
|
4747
|
-
console.log(
|
|
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(
|
|
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(` ${
|
|
5351
|
+
console.log(` ${chalk38.cyan("\u2713")} ${file}`);
|
|
4755
5352
|
}
|
|
4756
5353
|
console.log();
|
|
4757
|
-
console.log(
|
|
5354
|
+
console.log(chalk38.blue(`\u{1F4A1} \u5BFC\u5165\u547D\u4EE4: ccman import ${resolvedPath}
|
|
4758
5355
|
`));
|
|
4759
5356
|
} catch (error) {
|
|
4760
|
-
console.error(
|
|
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
|
|
4771
|
-
import
|
|
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(
|
|
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(
|
|
5377
|
+
console.log(chalk39.red(`\u274C ${validation.message}
|
|
4781
5378
|
`));
|
|
4782
5379
|
process.exit(1);
|
|
4783
5380
|
}
|
|
4784
|
-
console.log(
|
|
4785
|
-
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)}`);
|
|
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(` ${
|
|
5386
|
+
console.log(` ${chalk39.cyan("\u2713")} ${file}`);
|
|
4790
5387
|
}
|
|
4791
5388
|
console.log();
|
|
4792
|
-
console.log(
|
|
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
|
|
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(
|
|
5400
|
+
console.log(chalk39.gray("\n\u274C \u5DF2\u53D6\u6D88\n"));
|
|
4804
5401
|
return;
|
|
4805
5402
|
}
|
|
4806
5403
|
console.log();
|
|
4807
|
-
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"));
|
|
4808
5405
|
console.log();
|
|
4809
|
-
const { confirmSecond } = await
|
|
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(
|
|
5415
|
+
console.log(chalk39.gray("\n\u274C \u5DF2\u53D6\u6D88\n"));
|
|
4819
5416
|
return;
|
|
4820
5417
|
}
|
|
4821
5418
|
console.log();
|
|
4822
|
-
console.log(
|
|
4823
|
-
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..."));
|
|
4824
5421
|
const result = importConfig(resolvedPath);
|
|
4825
5422
|
console.log();
|
|
4826
|
-
console.log(
|
|
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(` ${
|
|
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(` ${
|
|
5434
|
+
console.log(` ${chalk39.cyan("\u2713")} ${file}`);
|
|
4838
5435
|
}
|
|
4839
5436
|
console.log();
|
|
4840
|
-
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"));
|
|
4841
5438
|
} catch (error) {
|
|
4842
|
-
console.error(
|
|
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(
|
|
4854
|
-
console.log(
|
|
4855
|
-
console.log(
|
|
4856
|
-
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()}`));
|
|
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(
|
|
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(
|
|
5473
|
+
console.log(chalk40.yellow("\u{1F4A1} \u4F60\u662F\u4E0D\u662F\u60F3\u8F93\u5165:"));
|
|
4877
5474
|
suggestions.forEach((cmd) => {
|
|
4878
|
-
console.log(
|
|
5475
|
+
console.log(chalk40.cyan(` ccman ${cmd}`));
|
|
4879
5476
|
});
|
|
4880
5477
|
console.log();
|
|
4881
5478
|
}
|
|
4882
|
-
console.log(
|
|
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
|
|
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",
|