ccman 3.0.33 → 3.1.1
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 +906 -253
- package/package.json +4 -4
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.
|
|
18
|
+
version: "3.1.1",
|
|
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",
|
|
@@ -65,6 +65,59 @@ var init_package = __esm({
|
|
|
65
65
|
}
|
|
66
66
|
});
|
|
67
67
|
|
|
68
|
+
// ../core/dist/constants.js
|
|
69
|
+
var TOOL_TYPES, MAIN_TOOL_TYPES, TOOL_CONFIG;
|
|
70
|
+
var init_constants = __esm({
|
|
71
|
+
"../core/dist/constants.js"() {
|
|
72
|
+
"use strict";
|
|
73
|
+
TOOL_TYPES = {
|
|
74
|
+
CODEX: "codex",
|
|
75
|
+
CLAUDE: "claude",
|
|
76
|
+
MCP: "mcp",
|
|
77
|
+
GEMINI: "gemini"
|
|
78
|
+
};
|
|
79
|
+
MAIN_TOOL_TYPES = {
|
|
80
|
+
CODEX: TOOL_TYPES.CODEX,
|
|
81
|
+
CLAUDE: TOOL_TYPES.CLAUDE,
|
|
82
|
+
GEMINI: TOOL_TYPES.GEMINI
|
|
83
|
+
};
|
|
84
|
+
TOOL_CONFIG = {
|
|
85
|
+
[TOOL_TYPES.CODEX]: {
|
|
86
|
+
displayName: "Codex",
|
|
87
|
+
color: "blue",
|
|
88
|
+
textColorClass: "text-blue-600",
|
|
89
|
+
bgColorClass: "bg-blue-50",
|
|
90
|
+
hoverBgColorClass: "hover:bg-blue-100",
|
|
91
|
+
description: "Codex AI \u52A9\u624B"
|
|
92
|
+
},
|
|
93
|
+
[TOOL_TYPES.CLAUDE]: {
|
|
94
|
+
displayName: "Claude Code",
|
|
95
|
+
color: "purple",
|
|
96
|
+
textColorClass: "text-purple-600",
|
|
97
|
+
bgColorClass: "bg-purple-50",
|
|
98
|
+
hoverBgColorClass: "hover:bg-purple-100",
|
|
99
|
+
description: "Claude Code AI \u52A9\u624B"
|
|
100
|
+
},
|
|
101
|
+
[TOOL_TYPES.MCP]: {
|
|
102
|
+
displayName: "MCP",
|
|
103
|
+
color: "gray",
|
|
104
|
+
textColorClass: "text-gray-600",
|
|
105
|
+
bgColorClass: "bg-gray-50",
|
|
106
|
+
hoverBgColorClass: "hover:bg-gray-100",
|
|
107
|
+
description: "MCP \u670D\u52A1"
|
|
108
|
+
},
|
|
109
|
+
[TOOL_TYPES.GEMINI]: {
|
|
110
|
+
displayName: "Gemini CLI",
|
|
111
|
+
color: "green",
|
|
112
|
+
textColorClass: "text-green-600",
|
|
113
|
+
bgColorClass: "bg-green-50",
|
|
114
|
+
hoverBgColorClass: "hover:bg-green-100",
|
|
115
|
+
description: "Gemini CLI AI \u52A9\u624B"
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
|
|
68
121
|
// ../core/dist/paths.js
|
|
69
122
|
import * as os from "os";
|
|
70
123
|
import * as path from "path";
|
|
@@ -77,6 +130,9 @@ function getCodexDir() {
|
|
|
77
130
|
function getClaudeDir() {
|
|
78
131
|
return claudeDir;
|
|
79
132
|
}
|
|
133
|
+
function getGeminiDir() {
|
|
134
|
+
return geminiDir;
|
|
135
|
+
}
|
|
80
136
|
function getConfigPath() {
|
|
81
137
|
return path.join(ccmanDir, "config.json");
|
|
82
138
|
}
|
|
@@ -92,7 +148,13 @@ function getClaudeConfigPath() {
|
|
|
92
148
|
function getClaudeJsonPath() {
|
|
93
149
|
return path.join(rootDir, ".claude.json");
|
|
94
150
|
}
|
|
95
|
-
|
|
151
|
+
function getGeminiSettingsPath() {
|
|
152
|
+
return path.join(geminiDir, "settings.json");
|
|
153
|
+
}
|
|
154
|
+
function getGeminiEnvPath() {
|
|
155
|
+
return path.join(geminiDir, ".env");
|
|
156
|
+
}
|
|
157
|
+
var isDev, isTest, rootDir, ccmanDir, codexDir, claudeDir, geminiDir;
|
|
96
158
|
var init_paths = __esm({
|
|
97
159
|
"../core/dist/paths.js"() {
|
|
98
160
|
"use strict";
|
|
@@ -108,6 +170,7 @@ var init_paths = __esm({
|
|
|
108
170
|
ccmanDir = path.join(rootDir, ".ccman");
|
|
109
171
|
codexDir = path.join(rootDir, ".codex");
|
|
110
172
|
claudeDir = path.join(rootDir, ".claude");
|
|
173
|
+
geminiDir = path.join(rootDir, ".gemini");
|
|
111
174
|
}
|
|
112
175
|
});
|
|
113
176
|
|
|
@@ -344,15 +407,13 @@ function migrateMCPConfig(config) {
|
|
|
344
407
|
config.managedServerNames = {
|
|
345
408
|
claude: config.managedServerNames,
|
|
346
409
|
codex: [],
|
|
347
|
-
|
|
348
|
-
windsurf: []
|
|
410
|
+
gemini: []
|
|
349
411
|
};
|
|
350
412
|
} else if (!config.managedServerNames) {
|
|
351
413
|
config.managedServerNames = {
|
|
352
414
|
claude: [],
|
|
353
415
|
codex: [],
|
|
354
|
-
|
|
355
|
-
windsurf: []
|
|
416
|
+
gemini: []
|
|
356
417
|
};
|
|
357
418
|
}
|
|
358
419
|
if (config.servers) {
|
|
@@ -374,8 +435,7 @@ function loadMCPConfig() {
|
|
|
374
435
|
managedServerNames: {
|
|
375
436
|
claude: [],
|
|
376
437
|
codex: [],
|
|
377
|
-
|
|
378
|
-
windsurf: []
|
|
438
|
+
gemini: []
|
|
379
439
|
}
|
|
380
440
|
};
|
|
381
441
|
}
|
|
@@ -441,10 +501,10 @@ function writeMCPConfigForApp(app, _provider) {
|
|
|
441
501
|
break;
|
|
442
502
|
case "codex":
|
|
443
503
|
return;
|
|
444
|
-
case "
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
504
|
+
case "gemini":
|
|
505
|
+
configPath = getGeminiSettingsPath();
|
|
506
|
+
configDir = getGeminiDir();
|
|
507
|
+
break;
|
|
448
508
|
}
|
|
449
509
|
ensureDir(configDir);
|
|
450
510
|
let appConfig = {};
|
|
@@ -625,6 +685,127 @@ var init_mcp2 = __esm({
|
|
|
625
685
|
}
|
|
626
686
|
});
|
|
627
687
|
|
|
688
|
+
// ../core/dist/presets/gemini.js
|
|
689
|
+
var GEMINI_PRESETS;
|
|
690
|
+
var init_gemini = __esm({
|
|
691
|
+
"../core/dist/presets/gemini.js"() {
|
|
692
|
+
"use strict";
|
|
693
|
+
GEMINI_PRESETS = [
|
|
694
|
+
{
|
|
695
|
+
name: "Google Gemini (API Key)",
|
|
696
|
+
baseUrl: "",
|
|
697
|
+
description: "\u4F7F\u7528\u5B98\u65B9 Gemini API\uFF08\u901A\u8FC7 GEMINI_API_KEY \u6216 GOOGLE_API_KEY \u8BA4\u8BC1\uFF09"
|
|
698
|
+
},
|
|
699
|
+
{
|
|
700
|
+
name: "PackyAPI",
|
|
701
|
+
baseUrl: "https://www.packyapi.com",
|
|
702
|
+
description: "PackyAPI Gemini \u517C\u5BB9\u670D\u52A1"
|
|
703
|
+
},
|
|
704
|
+
{
|
|
705
|
+
name: "LiteLLM Proxy",
|
|
706
|
+
baseUrl: "http://localhost:4000",
|
|
707
|
+
description: "\u4F7F\u7528\u672C\u5730 LiteLLM Proxy \u4F5C\u4E3A Gemini \u517C\u5BB9\u4EE3\u7406"
|
|
708
|
+
}
|
|
709
|
+
];
|
|
710
|
+
}
|
|
711
|
+
});
|
|
712
|
+
|
|
713
|
+
// ../core/dist/writers/gemini.js
|
|
714
|
+
import * as fs5 from "fs";
|
|
715
|
+
function loadEnvFile(envPath) {
|
|
716
|
+
if (!fileExists(envPath))
|
|
717
|
+
return {};
|
|
718
|
+
const content = fs5.readFileSync(envPath, "utf-8");
|
|
719
|
+
const result = {};
|
|
720
|
+
for (const line of content.split("\n")) {
|
|
721
|
+
const trimmed = line.trim();
|
|
722
|
+
if (!trimmed || trimmed.startsWith("#"))
|
|
723
|
+
continue;
|
|
724
|
+
const eqIndex = trimmed.indexOf("=");
|
|
725
|
+
if (eqIndex === -1)
|
|
726
|
+
continue;
|
|
727
|
+
const key = trimmed.slice(0, eqIndex).trim();
|
|
728
|
+
const value = trimmed.slice(eqIndex + 1).trim();
|
|
729
|
+
if (!key)
|
|
730
|
+
continue;
|
|
731
|
+
result[key] = value;
|
|
732
|
+
}
|
|
733
|
+
return result;
|
|
734
|
+
}
|
|
735
|
+
function saveEnvFile(envPath, env) {
|
|
736
|
+
const lines = [];
|
|
737
|
+
const keys = Object.keys(env).sort();
|
|
738
|
+
for (const key of keys) {
|
|
739
|
+
lines.push(`${key}=${String(env[key])}`);
|
|
740
|
+
}
|
|
741
|
+
const content = lines.join("\n") + (lines.length ? "\n" : "");
|
|
742
|
+
fs5.writeFileSync(envPath, content, { mode: 384 });
|
|
743
|
+
}
|
|
744
|
+
function writeGeminiConfig(provider) {
|
|
745
|
+
const settingsPath = getGeminiSettingsPath();
|
|
746
|
+
const envPath = getGeminiEnvPath();
|
|
747
|
+
const dir = getGeminiDir();
|
|
748
|
+
ensureDir(dir);
|
|
749
|
+
let settings = {};
|
|
750
|
+
if (fileExists(settingsPath)) {
|
|
751
|
+
try {
|
|
752
|
+
const content = fs5.readFileSync(settingsPath, "utf-8");
|
|
753
|
+
const parsed = JSON.parse(content);
|
|
754
|
+
if (parsed && typeof parsed === "object") {
|
|
755
|
+
settings = parsed;
|
|
756
|
+
}
|
|
757
|
+
} catch (error) {
|
|
758
|
+
throw new Error(`\u65E0\u6CD5\u8BFB\u53D6 Gemini settings.json: ${error.message}`);
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
if (!settings.ide || typeof settings.ide !== "object") {
|
|
762
|
+
settings.ide = {};
|
|
763
|
+
}
|
|
764
|
+
if (settings.ide.enabled === void 0) {
|
|
765
|
+
settings.ide.enabled = true;
|
|
766
|
+
}
|
|
767
|
+
if (!settings.security || typeof settings.security !== "object") {
|
|
768
|
+
settings.security = {};
|
|
769
|
+
}
|
|
770
|
+
if (!settings.security.auth || typeof settings.security.auth !== "object") {
|
|
771
|
+
settings.security.auth = {};
|
|
772
|
+
}
|
|
773
|
+
if (settings.security.auth.selectedType === void 0) {
|
|
774
|
+
settings.security.auth.selectedType = "gemini-api-key";
|
|
775
|
+
}
|
|
776
|
+
try {
|
|
777
|
+
const tempPath = `${settingsPath}.tmp`;
|
|
778
|
+
fs5.writeFileSync(tempPath, JSON.stringify(settings, null, 2), {
|
|
779
|
+
mode: 384
|
|
780
|
+
});
|
|
781
|
+
fs5.renameSync(tempPath, settingsPath);
|
|
782
|
+
} catch (error) {
|
|
783
|
+
throw new Error(`\u5199\u5165 Gemini settings.json \u5931\u8D25: ${error.message}`);
|
|
784
|
+
}
|
|
785
|
+
const env = loadEnvFile(envPath);
|
|
786
|
+
if (provider.baseUrl && provider.baseUrl.trim().length > 0) {
|
|
787
|
+
env.GOOGLE_GEMINI_BASE_URL = provider.baseUrl;
|
|
788
|
+
} else {
|
|
789
|
+
delete env.GOOGLE_GEMINI_BASE_URL;
|
|
790
|
+
}
|
|
791
|
+
if (provider.apiKey && provider.apiKey.trim().length > 0) {
|
|
792
|
+
env.GEMINI_API_KEY = provider.apiKey;
|
|
793
|
+
} else {
|
|
794
|
+
delete env.GEMINI_API_KEY;
|
|
795
|
+
}
|
|
796
|
+
if (provider.model && provider.model.trim().length > 0) {
|
|
797
|
+
env.GEMINI_MODEL = provider.model;
|
|
798
|
+
}
|
|
799
|
+
saveEnvFile(envPath, env);
|
|
800
|
+
}
|
|
801
|
+
var init_gemini2 = __esm({
|
|
802
|
+
"../core/dist/writers/gemini.js"() {
|
|
803
|
+
"use strict";
|
|
804
|
+
init_paths();
|
|
805
|
+
init_file();
|
|
806
|
+
}
|
|
807
|
+
});
|
|
808
|
+
|
|
628
809
|
// ../core/dist/tool-manager.types.js
|
|
629
810
|
var ProviderNotFoundError, ProviderNameConflictError, PresetNameConflictError;
|
|
630
811
|
var init_tool_manager_types = __esm({
|
|
@@ -901,6 +1082,9 @@ function createClaudeManager() {
|
|
|
901
1082
|
function createMCPManager() {
|
|
902
1083
|
return createToolManager("mcp");
|
|
903
1084
|
}
|
|
1085
|
+
function createGeminiManager() {
|
|
1086
|
+
return createToolManager("gemini");
|
|
1087
|
+
}
|
|
904
1088
|
var TOOL_CONFIGS;
|
|
905
1089
|
var init_tool_manager = __esm({
|
|
906
1090
|
"../core/dist/tool-manager.js"() {
|
|
@@ -913,6 +1097,8 @@ var init_tool_manager = __esm({
|
|
|
913
1097
|
init_codex2();
|
|
914
1098
|
init_claude2();
|
|
915
1099
|
init_mcp2();
|
|
1100
|
+
init_gemini();
|
|
1101
|
+
init_gemini2();
|
|
916
1102
|
init_tool_manager_types();
|
|
917
1103
|
TOOL_CONFIGS = {
|
|
918
1104
|
codex: {
|
|
@@ -949,11 +1135,16 @@ var init_tool_manager = __esm({
|
|
|
949
1135
|
}
|
|
950
1136
|
return mcpServer;
|
|
951
1137
|
});
|
|
952
|
-
for (const app of ["claude", "codex", "
|
|
1138
|
+
for (const app of ["claude", "codex", "gemini"]) {
|
|
953
1139
|
mcpConfig.managedServerNames[app] = mcpConfig.servers.filter((s) => s.enabledApps.includes(app)).map((s) => s.name);
|
|
954
1140
|
}
|
|
955
1141
|
saveMCPConfig(mcpConfig);
|
|
956
1142
|
}
|
|
1143
|
+
},
|
|
1144
|
+
gemini: {
|
|
1145
|
+
configPath: path6.join(getCcmanDir(), "gemini.json"),
|
|
1146
|
+
builtinPresets: GEMINI_PRESETS,
|
|
1147
|
+
writer: writeGeminiConfig
|
|
957
1148
|
}
|
|
958
1149
|
};
|
|
959
1150
|
}
|
|
@@ -968,20 +1159,20 @@ var init_migrate = __esm({
|
|
|
968
1159
|
});
|
|
969
1160
|
|
|
970
1161
|
// ../core/dist/config.js
|
|
971
|
-
import * as
|
|
1162
|
+
import * as fs6 from "fs";
|
|
972
1163
|
function ensureConfigDir() {
|
|
973
1164
|
const dir = getCcmanDir();
|
|
974
|
-
if (!
|
|
975
|
-
|
|
1165
|
+
if (!fs6.existsSync(dir)) {
|
|
1166
|
+
fs6.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
976
1167
|
}
|
|
977
1168
|
}
|
|
978
1169
|
function loadConfig() {
|
|
979
1170
|
const configPath = getConfigPath();
|
|
980
|
-
if (!
|
|
1171
|
+
if (!fs6.existsSync(configPath)) {
|
|
981
1172
|
return {};
|
|
982
1173
|
}
|
|
983
1174
|
try {
|
|
984
|
-
const content =
|
|
1175
|
+
const content = fs6.readFileSync(configPath, "utf-8");
|
|
985
1176
|
return JSON.parse(content);
|
|
986
1177
|
} catch (error) {
|
|
987
1178
|
throw new Error(`Failed to load config: ${error.message}`);
|
|
@@ -992,10 +1183,10 @@ function saveConfig(config) {
|
|
|
992
1183
|
const configPath = getConfigPath();
|
|
993
1184
|
try {
|
|
994
1185
|
const tempPath = `${configPath}.tmp`;
|
|
995
|
-
|
|
1186
|
+
fs6.writeFileSync(tempPath, JSON.stringify(config, null, 2), {
|
|
996
1187
|
mode: 384
|
|
997
1188
|
});
|
|
998
|
-
|
|
1189
|
+
fs6.renameSync(tempPath, configPath);
|
|
999
1190
|
} catch (error) {
|
|
1000
1191
|
throw new Error(`Failed to save config: ${error.message}`);
|
|
1001
1192
|
}
|
|
@@ -1319,15 +1510,15 @@ var init_merge_advanced = __esm({
|
|
|
1319
1510
|
});
|
|
1320
1511
|
|
|
1321
1512
|
// ../core/dist/sync/merge.js
|
|
1322
|
-
import
|
|
1513
|
+
import fs7 from "fs";
|
|
1323
1514
|
import path7 from "path";
|
|
1324
1515
|
function backupConfig(configPath, keepCount = 3) {
|
|
1325
|
-
if (!
|
|
1516
|
+
if (!fs7.existsSync(configPath)) {
|
|
1326
1517
|
throw new Error(`\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728: ${configPath}`);
|
|
1327
1518
|
}
|
|
1328
1519
|
const timestamp = Date.now();
|
|
1329
1520
|
const backupPath = `${configPath}.backup.${timestamp}`;
|
|
1330
|
-
|
|
1521
|
+
fs7.copyFileSync(configPath, backupPath);
|
|
1331
1522
|
cleanupOldBackups(configPath, keepCount);
|
|
1332
1523
|
return backupPath;
|
|
1333
1524
|
}
|
|
@@ -1336,7 +1527,7 @@ function cleanupOldBackups(configPath, keepCount) {
|
|
|
1336
1527
|
const basename = path7.basename(configPath);
|
|
1337
1528
|
const backupPrefix = `${basename}.backup.`;
|
|
1338
1529
|
try {
|
|
1339
|
-
const files =
|
|
1530
|
+
const files = fs7.readdirSync(dir);
|
|
1340
1531
|
const backups = files.filter((f) => f.startsWith(backupPrefix)).map((f) => {
|
|
1341
1532
|
const timestampStr = f.substring(backupPrefix.length);
|
|
1342
1533
|
const timestamp = parseInt(timestampStr, 10);
|
|
@@ -1352,7 +1543,7 @@ function cleanupOldBackups(configPath, keepCount) {
|
|
|
1352
1543
|
const toDelete = backups.slice(keepCount);
|
|
1353
1544
|
for (const backup of toDelete) {
|
|
1354
1545
|
try {
|
|
1355
|
-
|
|
1546
|
+
fs7.unlinkSync(backup.path);
|
|
1356
1547
|
} catch (error) {
|
|
1357
1548
|
console.warn(`\u65E0\u6CD5\u5220\u9664\u65E7\u5907\u4EFD\u6587\u4EF6 ${backup.name}: ${error.message}`);
|
|
1358
1549
|
}
|
|
@@ -1368,91 +1559,81 @@ var init_merge = __esm({
|
|
|
1368
1559
|
});
|
|
1369
1560
|
|
|
1370
1561
|
// ../core/dist/sync/sync-v2.js
|
|
1371
|
-
import
|
|
1562
|
+
import fs8 from "fs";
|
|
1372
1563
|
import path8 from "path";
|
|
1373
1564
|
async function uploadToCloud(config, password) {
|
|
1374
1565
|
const ccmanDir2 = getCcmanDir();
|
|
1375
|
-
const
|
|
1376
|
-
const
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
providers: encryptedClaudeProviders
|
|
1391
|
-
// 只替换 providers(加密后的)
|
|
1392
|
-
};
|
|
1393
|
-
const codexJson = JSON.stringify(encryptedCodexConfig, null, 2);
|
|
1394
|
-
const claudeJson = JSON.stringify(encryptedClaudeConfig, null, 2);
|
|
1395
|
-
await uploadToWebDAV(config, CODEX_REMOTE_PATH, codexJson);
|
|
1396
|
-
await uploadToWebDAV(config, CLAUDE_REMOTE_PATH, claudeJson);
|
|
1566
|
+
const toolKeys = Object.keys(TOOL_SYNC_CONFIG);
|
|
1567
|
+
for (const tool of toolKeys) {
|
|
1568
|
+
const { remotePath, configFilename } = TOOL_SYNC_CONFIG[tool];
|
|
1569
|
+
const configPath = path8.join(ccmanDir2, configFilename);
|
|
1570
|
+
const localConfig = readJSON(configPath);
|
|
1571
|
+
const encryptedProviders = encryptProviders(localConfig.providers, password);
|
|
1572
|
+
const encryptedConfig = {
|
|
1573
|
+
...localConfig,
|
|
1574
|
+
// 保留所有字段
|
|
1575
|
+
providers: encryptedProviders
|
|
1576
|
+
// 只替换 providers(加密后的)
|
|
1577
|
+
};
|
|
1578
|
+
const jsonContent = JSON.stringify(encryptedConfig, null, 2);
|
|
1579
|
+
await uploadToWebDAV(config, remotePath, jsonContent);
|
|
1580
|
+
}
|
|
1397
1581
|
updateLastSyncTime();
|
|
1398
1582
|
console.log("\u2705 \u914D\u7F6E\u5DF2\u4E0A\u4F20\u5230\u4E91\u7AEF");
|
|
1399
1583
|
}
|
|
1400
1584
|
async function downloadFromCloud(config, password) {
|
|
1401
|
-
const
|
|
1402
|
-
const
|
|
1403
|
-
|
|
1585
|
+
const ccmanDir2 = getCcmanDir();
|
|
1586
|
+
const toolKeys = Object.keys(TOOL_SYNC_CONFIG);
|
|
1587
|
+
const existsChecks = await Promise.all(toolKeys.map(async (tool) => {
|
|
1588
|
+
const { remotePath } = TOOL_SYNC_CONFIG[tool];
|
|
1589
|
+
return existsOnWebDAV(config, remotePath);
|
|
1590
|
+
}));
|
|
1591
|
+
if (!existsChecks.some((exists) => exists)) {
|
|
1404
1592
|
throw new Error("\u8FDC\u7A0B\u914D\u7F6E\u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u4E0A\u4F20\u914D\u7F6E");
|
|
1405
1593
|
}
|
|
1406
|
-
const
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1594
|
+
const remoteConfigs = [];
|
|
1595
|
+
for (let i = 0; i < toolKeys.length; i++) {
|
|
1596
|
+
const tool = toolKeys[i];
|
|
1597
|
+
const { remotePath } = TOOL_SYNC_CONFIG[tool];
|
|
1598
|
+
if (existsChecks[i]) {
|
|
1599
|
+
const jsonContent = await downloadFromWebDAV(config, remotePath);
|
|
1600
|
+
const remoteConfig = JSON.parse(jsonContent);
|
|
1601
|
+
try {
|
|
1602
|
+
const decryptedProviders = decryptProviders(remoteConfig.providers, password);
|
|
1603
|
+
remoteConfigs.push({ tool, config: remoteConfig, decryptedProviders });
|
|
1604
|
+
} catch (error) {
|
|
1605
|
+
throw new Error("\u89E3\u5BC6\u5931\u8D25\uFF1A\u5BC6\u7801\u9519\u8BEF\u6216\u6570\u636E\u635F\u574F");
|
|
1606
|
+
}
|
|
1607
|
+
} else {
|
|
1608
|
+
remoteConfigs.push({ tool, config: null, decryptedProviders: null });
|
|
1418
1609
|
}
|
|
1419
|
-
} catch (error) {
|
|
1420
|
-
throw new Error("\u89E3\u5BC6\u5931\u8D25\uFF1A\u5BC6\u7801\u9519\u8BEF\u6216\u6570\u636E\u635F\u574F");
|
|
1421
1610
|
}
|
|
1422
1611
|
const backupPaths = [];
|
|
1423
|
-
const ccmanDir2 = getCcmanDir();
|
|
1424
|
-
const codexConfigPath = path8.join(ccmanDir2, "codex.json");
|
|
1425
|
-
const claudeConfigPath = path8.join(ccmanDir2, "claude.json");
|
|
1426
1612
|
try {
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1613
|
+
for (const tool of toolKeys) {
|
|
1614
|
+
const { configFilename } = TOOL_SYNC_CONFIG[tool];
|
|
1615
|
+
const configPath = path8.join(ccmanDir2, configFilename);
|
|
1616
|
+
if (fs8.existsSync(configPath)) {
|
|
1617
|
+
backupPaths.push(backupConfig(configPath));
|
|
1618
|
+
}
|
|
1432
1619
|
}
|
|
1433
1620
|
} catch (error) {
|
|
1434
1621
|
throw new Error(`\u5907\u4EFD\u5931\u8D25: ${error.message}`);
|
|
1435
1622
|
}
|
|
1436
1623
|
try {
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
writeJSON(codexConfigPath, newCodexConfig);
|
|
1445
|
-
applyCurrentProvider("codex", newCodexConfig);
|
|
1446
|
-
}
|
|
1447
|
-
if (remoteClaudeConfig && decryptedClaudeProviders) {
|
|
1448
|
-
const newClaudeConfig = {
|
|
1449
|
-
...remoteClaudeConfig,
|
|
1624
|
+
for (const { tool, config: remoteConfig, decryptedProviders } of remoteConfigs) {
|
|
1625
|
+
if (!remoteConfig || !decryptedProviders)
|
|
1626
|
+
continue;
|
|
1627
|
+
const { configFilename } = TOOL_SYNC_CONFIG[tool];
|
|
1628
|
+
const configPath = path8.join(ccmanDir2, configFilename);
|
|
1629
|
+
const newConfig = {
|
|
1630
|
+
...remoteConfig,
|
|
1450
1631
|
// 使用云端配置的所有字段
|
|
1451
|
-
providers:
|
|
1632
|
+
providers: decryptedProviders
|
|
1452
1633
|
// 只替换 providers(解密后的)
|
|
1453
1634
|
};
|
|
1454
|
-
writeJSON(
|
|
1455
|
-
applyCurrentProvider(
|
|
1635
|
+
writeJSON(configPath, newConfig);
|
|
1636
|
+
applyCurrentProvider(tool, newConfig);
|
|
1456
1637
|
}
|
|
1457
1638
|
updateLastSyncTime();
|
|
1458
1639
|
console.log("\u2705 \u914D\u7F6E\u5DF2\u4ECE\u4E91\u7AEF\u4E0B\u8F7D\u5E76\u5E94\u7528");
|
|
@@ -1460,17 +1641,21 @@ async function downloadFromCloud(config, password) {
|
|
|
1460
1641
|
} catch (error) {
|
|
1461
1642
|
for (const backupPath of backupPaths) {
|
|
1462
1643
|
const originalPath = backupPath.replace(/\.backup\.\d+$/, "");
|
|
1463
|
-
if (
|
|
1464
|
-
|
|
1644
|
+
if (fs8.existsSync(backupPath)) {
|
|
1645
|
+
fs8.copyFileSync(backupPath, originalPath);
|
|
1465
1646
|
}
|
|
1466
1647
|
}
|
|
1467
1648
|
throw new Error(`\u8986\u76D6\u914D\u7F6E\u5931\u8D25\uFF0C\u5DF2\u6062\u590D\u5907\u4EFD: ${error.message}`);
|
|
1468
1649
|
}
|
|
1469
1650
|
}
|
|
1470
1651
|
async function mergeSync(config, password) {
|
|
1471
|
-
const
|
|
1472
|
-
const
|
|
1473
|
-
|
|
1652
|
+
const ccmanDir2 = getCcmanDir();
|
|
1653
|
+
const toolKeys = Object.keys(TOOL_SYNC_CONFIG);
|
|
1654
|
+
const existsChecks = await Promise.all(toolKeys.map(async (tool) => {
|
|
1655
|
+
const { remotePath } = TOOL_SYNC_CONFIG[tool];
|
|
1656
|
+
return existsOnWebDAV(config, remotePath);
|
|
1657
|
+
}));
|
|
1658
|
+
if (!existsChecks.some((exists) => exists)) {
|
|
1474
1659
|
console.log("\u8FDC\u7A0B\u914D\u7F6E\u4E0D\u5B58\u5728\uFF0C\u6267\u884C\u4E0A\u4F20\u64CD\u4F5C");
|
|
1475
1660
|
await uploadToCloud(config, password);
|
|
1476
1661
|
return {
|
|
@@ -1478,30 +1663,31 @@ async function mergeSync(config, password) {
|
|
|
1478
1663
|
backupPaths: []
|
|
1479
1664
|
};
|
|
1480
1665
|
}
|
|
1481
|
-
const
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
if (
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1666
|
+
const mergeDataList = [];
|
|
1667
|
+
for (let i = 0; i < toolKeys.length; i++) {
|
|
1668
|
+
const tool = toolKeys[i];
|
|
1669
|
+
const { remotePath, configFilename } = TOOL_SYNC_CONFIG[tool];
|
|
1670
|
+
const configPath = path8.join(ccmanDir2, configFilename);
|
|
1671
|
+
const localConfig = readJSON(configPath);
|
|
1672
|
+
let remoteProviders = [];
|
|
1673
|
+
if (existsChecks[i]) {
|
|
1674
|
+
try {
|
|
1675
|
+
const jsonContent = await downloadFromWebDAV(config, remotePath);
|
|
1676
|
+
const remoteConfig = JSON.parse(jsonContent);
|
|
1677
|
+
remoteProviders = decryptProviders(remoteConfig.providers, password);
|
|
1678
|
+
} catch (error) {
|
|
1679
|
+
throw new Error("\u89E3\u5BC6\u5931\u8D25\uFF1A\u5BC6\u7801\u9519\u8BEF\u6216\u6570\u636E\u635F\u574F");
|
|
1680
|
+
}
|
|
1493
1681
|
}
|
|
1494
|
-
|
|
1495
|
-
|
|
1682
|
+
const mergeResult = mergeProviders(localConfig.providers, remoteProviders);
|
|
1683
|
+
mergeDataList.push({
|
|
1684
|
+
tool,
|
|
1685
|
+
localConfig,
|
|
1686
|
+
remoteProviders,
|
|
1687
|
+
mergeResult
|
|
1688
|
+
});
|
|
1496
1689
|
}
|
|
1497
|
-
const
|
|
1498
|
-
const codexConfigPath = path8.join(ccmanDir2, "codex.json");
|
|
1499
|
-
const claudeConfigPath = path8.join(ccmanDir2, "claude.json");
|
|
1500
|
-
const localCodexConfig = readJSON(codexConfigPath);
|
|
1501
|
-
const localClaudeConfig = readJSON(claudeConfigPath);
|
|
1502
|
-
const codexMergeResult = mergeProviders(localCodexConfig.providers, remoteCodexProviders);
|
|
1503
|
-
const claudeMergeResult = mergeProviders(localClaudeConfig.providers, remoteClaudeProviders);
|
|
1504
|
-
const hasChanges = codexMergeResult.hasChanges || claudeMergeResult.hasChanges;
|
|
1690
|
+
const hasChanges = mergeDataList.some((data) => data.mergeResult.hasChanges);
|
|
1505
1691
|
if (!hasChanges) {
|
|
1506
1692
|
console.log("\u2139\uFE0F \u914D\u7F6E\u5DF2\u540C\u6B65\uFF0C\u65E0\u9700\u64CD\u4F5C");
|
|
1507
1693
|
return {
|
|
@@ -1511,56 +1697,47 @@ async function mergeSync(config, password) {
|
|
|
1511
1697
|
}
|
|
1512
1698
|
const backupPaths = [];
|
|
1513
1699
|
try {
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1700
|
+
for (const tool of toolKeys) {
|
|
1701
|
+
const { configFilename } = TOOL_SYNC_CONFIG[tool];
|
|
1702
|
+
const configPath = path8.join(ccmanDir2, configFilename);
|
|
1703
|
+
if (fs8.existsSync(configPath)) {
|
|
1704
|
+
backupPaths.push(backupConfig(configPath));
|
|
1705
|
+
}
|
|
1519
1706
|
}
|
|
1520
1707
|
} catch (error) {
|
|
1521
1708
|
throw new Error(`\u5907\u4EFD\u5931\u8D25: ${error.message}`);
|
|
1522
1709
|
}
|
|
1523
|
-
const mergedCodexPresets = mergePresets(localCodexConfig.presets, remoteCodexConfig?.presets);
|
|
1524
|
-
const mergedClaudePresets = mergePresets(localClaudeConfig.presets, remoteClaudeConfig?.presets);
|
|
1525
1710
|
try {
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
// 保留合并后配置的所有字段
|
|
1557
|
-
providers: encryptedClaudeProviders
|
|
1558
|
-
// 只替换 providers(加密后的)
|
|
1559
|
-
};
|
|
1560
|
-
const codexJson2 = JSON.stringify(encryptedCodexConfig, null, 2);
|
|
1561
|
-
const claudeJson2 = JSON.stringify(encryptedClaudeConfig, null, 2);
|
|
1562
|
-
await uploadToWebDAV(config, CODEX_REMOTE_PATH, codexJson2);
|
|
1563
|
-
await uploadToWebDAV(config, CLAUDE_REMOTE_PATH, claudeJson2);
|
|
1711
|
+
for (let i = 0; i < mergeDataList.length; i++) {
|
|
1712
|
+
const { tool, localConfig, mergeResult } = mergeDataList[i];
|
|
1713
|
+
const { remotePath, configFilename } = TOOL_SYNC_CONFIG[tool];
|
|
1714
|
+
const configPath = path8.join(ccmanDir2, configFilename);
|
|
1715
|
+
let remoteConfig = null;
|
|
1716
|
+
if (existsChecks[i]) {
|
|
1717
|
+
const jsonContent2 = await downloadFromWebDAV(config, remotePath);
|
|
1718
|
+
remoteConfig = JSON.parse(jsonContent2);
|
|
1719
|
+
}
|
|
1720
|
+
const mergedPresets = mergePresets(localConfig.presets, remoteConfig?.presets);
|
|
1721
|
+
const mergedConfig = {
|
|
1722
|
+
...localConfig,
|
|
1723
|
+
// 保留本地配置的所有字段
|
|
1724
|
+
providers: mergeResult.merged,
|
|
1725
|
+
// 替换为合并后的 providers
|
|
1726
|
+
presets: mergedPresets
|
|
1727
|
+
// 替换为合并后的 presets
|
|
1728
|
+
};
|
|
1729
|
+
writeJSON(configPath, mergedConfig);
|
|
1730
|
+
applyCurrentProvider(tool, mergedConfig);
|
|
1731
|
+
const encryptedProviders = encryptProviders(mergeResult.merged, password);
|
|
1732
|
+
const encryptedConfig = {
|
|
1733
|
+
...mergedConfig,
|
|
1734
|
+
// 保留合并后配置的所有字段
|
|
1735
|
+
providers: encryptedProviders
|
|
1736
|
+
// 只替换 providers(加密后的)
|
|
1737
|
+
};
|
|
1738
|
+
const jsonContent = JSON.stringify(encryptedConfig, null, 2);
|
|
1739
|
+
await uploadToWebDAV(config, remotePath, jsonContent);
|
|
1740
|
+
}
|
|
1564
1741
|
updateLastSyncTime();
|
|
1565
1742
|
console.log("\u2705 \u914D\u7F6E\u5DF2\u5408\u5E76\u5E76\u540C\u6B65\u5230\u4E91\u7AEF");
|
|
1566
1743
|
return {
|
|
@@ -1570,8 +1747,8 @@ async function mergeSync(config, password) {
|
|
|
1570
1747
|
} catch (error) {
|
|
1571
1748
|
for (const backupPath of backupPaths) {
|
|
1572
1749
|
const originalPath = backupPath.replace(/\.backup\.\d+$/, "");
|
|
1573
|
-
if (
|
|
1574
|
-
|
|
1750
|
+
if (fs8.existsSync(backupPath)) {
|
|
1751
|
+
fs8.copyFileSync(backupPath, originalPath);
|
|
1575
1752
|
}
|
|
1576
1753
|
}
|
|
1577
1754
|
throw new Error(`\u5408\u5E76\u914D\u7F6E\u5931\u8D25\uFF0C\u5DF2\u6062\u590D\u5907\u4EFD: ${error.message}`);
|
|
@@ -1585,13 +1762,10 @@ function applyCurrentProvider(tool, config) {
|
|
|
1585
1762
|
if (!provider) {
|
|
1586
1763
|
return;
|
|
1587
1764
|
}
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
} else {
|
|
1591
|
-
writeClaudeConfig(provider);
|
|
1592
|
-
}
|
|
1765
|
+
const { writerFunc } = TOOL_SYNC_CONFIG[tool];
|
|
1766
|
+
writerFunc(provider);
|
|
1593
1767
|
}
|
|
1594
|
-
var
|
|
1768
|
+
var TOOL_SYNC_CONFIG;
|
|
1595
1769
|
var init_sync_v2 = __esm({
|
|
1596
1770
|
"../core/dist/sync/sync-v2.js"() {
|
|
1597
1771
|
"use strict";
|
|
@@ -1604,13 +1778,30 @@ var init_sync_v2 = __esm({
|
|
|
1604
1778
|
init_file();
|
|
1605
1779
|
init_codex();
|
|
1606
1780
|
init_claude();
|
|
1607
|
-
|
|
1608
|
-
|
|
1781
|
+
init_gemini2();
|
|
1782
|
+
init_constants();
|
|
1783
|
+
TOOL_SYNC_CONFIG = {
|
|
1784
|
+
[MAIN_TOOL_TYPES.CODEX]: {
|
|
1785
|
+
remotePath: ".ccman/codex.json",
|
|
1786
|
+
configFilename: "codex.json",
|
|
1787
|
+
writerFunc: writeCodexConfig
|
|
1788
|
+
},
|
|
1789
|
+
[MAIN_TOOL_TYPES.CLAUDE]: {
|
|
1790
|
+
remotePath: ".ccman/claude.json",
|
|
1791
|
+
configFilename: "claude.json",
|
|
1792
|
+
writerFunc: writeClaudeConfig
|
|
1793
|
+
},
|
|
1794
|
+
[MAIN_TOOL_TYPES.GEMINI]: {
|
|
1795
|
+
remotePath: ".ccman/gemini.json",
|
|
1796
|
+
configFilename: "gemini.json",
|
|
1797
|
+
writerFunc: writeGeminiConfig
|
|
1798
|
+
}
|
|
1799
|
+
};
|
|
1609
1800
|
}
|
|
1610
1801
|
});
|
|
1611
1802
|
|
|
1612
1803
|
// ../core/dist/export.js
|
|
1613
|
-
import * as
|
|
1804
|
+
import * as fs9 from "fs";
|
|
1614
1805
|
import * as path9 from "path";
|
|
1615
1806
|
function validateExport() {
|
|
1616
1807
|
const ccmanDir2 = getCcmanDir();
|
|
@@ -1640,7 +1831,7 @@ function validateImportDir(sourceDir) {
|
|
|
1640
1831
|
foundFiles: []
|
|
1641
1832
|
};
|
|
1642
1833
|
}
|
|
1643
|
-
const stats =
|
|
1834
|
+
const stats = fs9.statSync(sourceDir);
|
|
1644
1835
|
if (!stats.isDirectory()) {
|
|
1645
1836
|
return {
|
|
1646
1837
|
valid: false,
|
|
@@ -1680,13 +1871,13 @@ function exportConfig(targetDir) {
|
|
|
1680
1871
|
const codexSrc = path9.join(ccmanDir2, CODEX_CONFIG_FILE);
|
|
1681
1872
|
const codexDst = path9.join(targetDir, CODEX_CONFIG_FILE);
|
|
1682
1873
|
if (fileExists(codexSrc)) {
|
|
1683
|
-
|
|
1874
|
+
fs9.copyFileSync(codexSrc, codexDst);
|
|
1684
1875
|
exportedFiles.push(CODEX_CONFIG_FILE);
|
|
1685
1876
|
}
|
|
1686
1877
|
const claudeSrc = path9.join(ccmanDir2, CLAUDE_CONFIG_FILE);
|
|
1687
1878
|
const claudeDst = path9.join(targetDir, CLAUDE_CONFIG_FILE);
|
|
1688
1879
|
if (fileExists(claudeSrc)) {
|
|
1689
|
-
|
|
1880
|
+
fs9.copyFileSync(claudeSrc, claudeDst);
|
|
1690
1881
|
exportedFiles.push(CLAUDE_CONFIG_FILE);
|
|
1691
1882
|
}
|
|
1692
1883
|
return {
|
|
@@ -1712,7 +1903,7 @@ function importConfig(sourceDir) {
|
|
|
1712
1903
|
backupPaths.push(backupPath);
|
|
1713
1904
|
}
|
|
1714
1905
|
const codexSrc = path9.join(sourceDir, CODEX_CONFIG_FILE);
|
|
1715
|
-
|
|
1906
|
+
fs9.copyFileSync(codexSrc, codexDst);
|
|
1716
1907
|
importedFiles.push(CODEX_CONFIG_FILE);
|
|
1717
1908
|
}
|
|
1718
1909
|
if (validation.foundFiles.includes(CLAUDE_CONFIG_FILE)) {
|
|
@@ -1722,7 +1913,7 @@ function importConfig(sourceDir) {
|
|
|
1722
1913
|
backupPaths.push(backupPath);
|
|
1723
1914
|
}
|
|
1724
1915
|
const claudeSrc = path9.join(sourceDir, CLAUDE_CONFIG_FILE);
|
|
1725
|
-
|
|
1916
|
+
fs9.copyFileSync(claudeSrc, claudeDst);
|
|
1726
1917
|
importedFiles.push(CLAUDE_CONFIG_FILE);
|
|
1727
1918
|
}
|
|
1728
1919
|
return {
|
|
@@ -1734,7 +1925,7 @@ function importConfig(sourceDir) {
|
|
|
1734
1925
|
for (const backupPath of backupPaths) {
|
|
1735
1926
|
const originalPath = backupPath.replace(/\.backup\.\d+$/, "");
|
|
1736
1927
|
if (fileExists(backupPath)) {
|
|
1737
|
-
|
|
1928
|
+
fs9.copyFileSync(backupPath, originalPath);
|
|
1738
1929
|
}
|
|
1739
1930
|
}
|
|
1740
1931
|
throw new Error(`\u5BFC\u5165\u5931\u8D25\uFF0C\u5DF2\u6062\u590D\u5907\u4EFD: ${error.message}`);
|
|
@@ -1753,7 +1944,7 @@ var init_export = __esm({
|
|
|
1753
1944
|
});
|
|
1754
1945
|
|
|
1755
1946
|
// ../core/dist/claude-clean.js
|
|
1756
|
-
import * as
|
|
1947
|
+
import * as fs10 from "fs";
|
|
1757
1948
|
function formatBytes(bytes) {
|
|
1758
1949
|
if (bytes < 1024)
|
|
1759
1950
|
return `${bytes} B`;
|
|
@@ -1763,7 +1954,7 @@ function formatBytes(bytes) {
|
|
|
1763
1954
|
}
|
|
1764
1955
|
function getFileSize(filePath) {
|
|
1765
1956
|
try {
|
|
1766
|
-
const stats =
|
|
1957
|
+
const stats = fs10.statSync(filePath);
|
|
1767
1958
|
return stats.size;
|
|
1768
1959
|
} catch {
|
|
1769
1960
|
return 0;
|
|
@@ -1772,18 +1963,18 @@ function getFileSize(filePath) {
|
|
|
1772
1963
|
function backupFile(filePath) {
|
|
1773
1964
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/:/g, "-").split(".")[0];
|
|
1774
1965
|
const backupPath = `${filePath}.backup-${timestamp}`;
|
|
1775
|
-
|
|
1966
|
+
fs10.copyFileSync(filePath, backupPath);
|
|
1776
1967
|
return backupPath;
|
|
1777
1968
|
}
|
|
1778
1969
|
function saveJsonAtomic(filePath, data) {
|
|
1779
1970
|
const tempPath = `${filePath}.tmp`;
|
|
1780
1971
|
const content = JSON.stringify(data, null, 2);
|
|
1781
|
-
|
|
1782
|
-
|
|
1972
|
+
fs10.writeFileSync(tempPath, content, { mode: 384 });
|
|
1973
|
+
fs10.renameSync(tempPath, filePath);
|
|
1783
1974
|
}
|
|
1784
1975
|
function analyzeClaudeJson() {
|
|
1785
1976
|
const filePath = getClaudeJsonPath();
|
|
1786
|
-
if (!
|
|
1977
|
+
if (!fs10.existsSync(filePath)) {
|
|
1787
1978
|
return {
|
|
1788
1979
|
fileSize: 0,
|
|
1789
1980
|
fileSizeFormatted: "0 B",
|
|
@@ -1799,7 +1990,7 @@ function analyzeClaudeJson() {
|
|
|
1799
1990
|
};
|
|
1800
1991
|
}
|
|
1801
1992
|
const fileSize = getFileSize(filePath);
|
|
1802
|
-
const content =
|
|
1993
|
+
const content = fs10.readFileSync(filePath, "utf-8");
|
|
1803
1994
|
const config = JSON.parse(content);
|
|
1804
1995
|
const projects = config.projects || {};
|
|
1805
1996
|
const projectHistory = [];
|
|
@@ -1833,12 +2024,12 @@ function analyzeClaudeJson() {
|
|
|
1833
2024
|
}
|
|
1834
2025
|
function cleanClaudeJson(options = {}) {
|
|
1835
2026
|
const filePath = getClaudeJsonPath();
|
|
1836
|
-
if (!
|
|
2027
|
+
if (!fs10.existsSync(filePath)) {
|
|
1837
2028
|
throw new Error(`${filePath} \u6587\u4EF6\u4E0D\u5B58\u5728`);
|
|
1838
2029
|
}
|
|
1839
2030
|
const backupPath = backupFile(filePath);
|
|
1840
2031
|
const sizeBefore = getFileSize(filePath);
|
|
1841
|
-
const content =
|
|
2032
|
+
const content = fs10.readFileSync(filePath, "utf-8");
|
|
1842
2033
|
const config = JSON.parse(content);
|
|
1843
2034
|
const cleanedItems = applyCleanOptions(config, options);
|
|
1844
2035
|
saveJsonAtomic(filePath, config);
|
|
@@ -1919,10 +2110,12 @@ var init_dist = __esm({
|
|
|
1919
2110
|
"../core/dist/index.js"() {
|
|
1920
2111
|
"use strict";
|
|
1921
2112
|
init_package();
|
|
2113
|
+
init_constants();
|
|
1922
2114
|
init_tool_manager();
|
|
1923
2115
|
init_codex2();
|
|
1924
2116
|
init_claude2();
|
|
1925
2117
|
init_mcp2();
|
|
2118
|
+
init_gemini();
|
|
1926
2119
|
init_mcp();
|
|
1927
2120
|
init_migrate();
|
|
1928
2121
|
init_paths();
|
|
@@ -2646,7 +2839,7 @@ var init_sync = __esm({
|
|
|
2646
2839
|
|
|
2647
2840
|
// src/index.ts
|
|
2648
2841
|
import { Command as Command3 } from "commander";
|
|
2649
|
-
import
|
|
2842
|
+
import chalk40 from "chalk";
|
|
2650
2843
|
|
|
2651
2844
|
// src/utils/logo.ts
|
|
2652
2845
|
init_dist();
|
|
@@ -2705,6 +2898,21 @@ function formatProviderTable(providers, currentId) {
|
|
|
2705
2898
|
}
|
|
2706
2899
|
|
|
2707
2900
|
// src/interactive.ts
|
|
2901
|
+
var CLI_TOOL_CONFIG = {
|
|
2902
|
+
[TOOL_TYPES.CODEX]: { name: "Codex", emoji: "\u{1F536}", cmd: "cx" },
|
|
2903
|
+
[TOOL_TYPES.CLAUDE]: { name: "Claude", emoji: "\u{1F537}", cmd: "cc" },
|
|
2904
|
+
[TOOL_TYPES.GEMINI]: { name: "Gemini", emoji: "\u{1F48E}", cmd: "gm" }
|
|
2905
|
+
};
|
|
2906
|
+
function getManager(tool) {
|
|
2907
|
+
switch (tool) {
|
|
2908
|
+
case TOOL_TYPES.CODEX:
|
|
2909
|
+
return createCodexManager();
|
|
2910
|
+
case TOOL_TYPES.CLAUDE:
|
|
2911
|
+
return createClaudeManager();
|
|
2912
|
+
case TOOL_TYPES.GEMINI:
|
|
2913
|
+
return createGeminiManager();
|
|
2914
|
+
}
|
|
2915
|
+
}
|
|
2708
2916
|
async function promptProviderForm(defaults) {
|
|
2709
2917
|
const answers = await inquirer7.prompt([
|
|
2710
2918
|
{
|
|
@@ -2766,6 +2974,7 @@ async function startMainMenu() {
|
|
|
2766
2974
|
choices: [
|
|
2767
2975
|
{ name: "\u{1F537} Claude \u7BA1\u7406", value: "claude" },
|
|
2768
2976
|
{ name: "\u{1F536} Codex \u7BA1\u7406", value: "codex" },
|
|
2977
|
+
{ name: "\u{1F48E} Gemini \u7BA1\u7406", value: "gemini" },
|
|
2769
2978
|
{ name: "\u{1F504} WebDAV \u540C\u6B65", value: "sync" },
|
|
2770
2979
|
{ name: "\u{1F4E6} \u9884\u7F6E\u670D\u52A1\u5546\u7BA1\u7406", value: "presets" },
|
|
2771
2980
|
{ name: "\u274C \u9000\u51FA", value: "exit" }
|
|
@@ -2780,6 +2989,8 @@ async function startMainMenu() {
|
|
|
2780
2989
|
await startClaudeMenu();
|
|
2781
2990
|
} else if (choice === "codex") {
|
|
2782
2991
|
await startCodexMenu();
|
|
2992
|
+
} else if (choice === "gemini") {
|
|
2993
|
+
await startGeminiMenu();
|
|
2783
2994
|
} else if (choice === "sync") {
|
|
2784
2995
|
const { startSyncMenu: startSyncMenu2 } = await Promise.resolve().then(() => (init_sync(), sync_exports));
|
|
2785
2996
|
await startSyncMenu2();
|
|
@@ -2789,14 +3000,16 @@ async function startMainMenu() {
|
|
|
2789
3000
|
}
|
|
2790
3001
|
}
|
|
2791
3002
|
async function startClaudeMenu() {
|
|
2792
|
-
await showToolMenu(
|
|
3003
|
+
await showToolMenu(TOOL_TYPES.CLAUDE);
|
|
2793
3004
|
}
|
|
2794
3005
|
async function startCodexMenu() {
|
|
2795
|
-
await showToolMenu(
|
|
3006
|
+
await showToolMenu(TOOL_TYPES.CODEX);
|
|
3007
|
+
}
|
|
3008
|
+
async function startGeminiMenu() {
|
|
3009
|
+
await showToolMenu(TOOL_TYPES.GEMINI);
|
|
2796
3010
|
}
|
|
2797
3011
|
async function showToolMenu(tool) {
|
|
2798
|
-
const
|
|
2799
|
-
const toolEmoji = tool === "claude" ? "\u{1F537}" : "\u{1F536}";
|
|
3012
|
+
const { name: toolName, emoji: toolEmoji } = CLI_TOOL_CONFIG[tool];
|
|
2800
3013
|
while (true) {
|
|
2801
3014
|
console.log();
|
|
2802
3015
|
const { action } = await inquirer7.prompt([
|
|
@@ -2810,7 +3023,7 @@ async function showToolMenu(tool) {
|
|
|
2810
3023
|
{ name: "\u{1F4CB} \u5217\u51FA\u6240\u6709\u670D\u52A1\u5546", value: "list" },
|
|
2811
3024
|
{ name: "\u{1F441}\uFE0F \u67E5\u770B\u5F53\u524D\u670D\u52A1\u5546", value: "current" },
|
|
2812
3025
|
{ name: "\u270F\uFE0F \u7F16\u8F91\u670D\u52A1\u5546", value: "edit" },
|
|
2813
|
-
{ name: "\u{
|
|
3026
|
+
{ name: "\u{1F501} \u514B\u9686\u670D\u52A1\u5546", value: "clone" },
|
|
2814
3027
|
{ name: "\u{1F5D1}\uFE0F \u5220\u9664\u670D\u52A1\u5546", value: "remove" },
|
|
2815
3028
|
{ name: "\u2B05\uFE0F \u8FD4\u56DE\u4E0A\u7EA7", value: "back" }
|
|
2816
3029
|
]
|
|
@@ -2861,8 +3074,8 @@ async function showPresetsMenu() {
|
|
|
2861
3074
|
console.log(chalk11.yellow("\n\u26A0\uFE0F \u9884\u7F6E\u670D\u52A1\u5546\u7BA1\u7406\u529F\u80FD\u5373\u5C06\u63A8\u51FA\n"));
|
|
2862
3075
|
}
|
|
2863
3076
|
async function handleAdd(tool) {
|
|
2864
|
-
const manager = tool
|
|
2865
|
-
const
|
|
3077
|
+
const manager = getManager(tool);
|
|
3078
|
+
const { name: toolName, cmd } = CLI_TOOL_CONFIG[tool];
|
|
2866
3079
|
const presets = manager.listPresets();
|
|
2867
3080
|
console.log(chalk11.bold(`
|
|
2868
3081
|
\u{1F4DD} \u6DFB\u52A0 ${toolName} \u670D\u52A1\u5546
|
|
@@ -2960,14 +3173,12 @@ async function handleAdd(tool) {
|
|
|
2960
3173
|
manager.switch(provider.id);
|
|
2961
3174
|
console.log(chalk11.green("\u2705 \u5DF2\u5207\u6362\u5230\u65B0\u670D\u52A1\u5546\n"));
|
|
2962
3175
|
} else {
|
|
2963
|
-
console.log(
|
|
2964
|
-
|
|
2965
|
-
`)
|
|
2966
|
-
);
|
|
3176
|
+
console.log(chalk11.blue("\u{1F4A1} \u7A0D\u540E\u5207\u6362:") + chalk11.white(` ccman ${cmd} use "${provider.name}"
|
|
3177
|
+
`));
|
|
2967
3178
|
}
|
|
2968
3179
|
}
|
|
2969
3180
|
async function handleSwitch(tool) {
|
|
2970
|
-
const manager = tool
|
|
3181
|
+
const manager = getManager(tool);
|
|
2971
3182
|
const providers = manager.list();
|
|
2972
3183
|
const current = manager.getCurrent();
|
|
2973
3184
|
if (providers.length === 0) {
|
|
@@ -2992,10 +3203,10 @@ async function handleSwitch(tool) {
|
|
|
2992
3203
|
`));
|
|
2993
3204
|
}
|
|
2994
3205
|
async function handleList(tool) {
|
|
2995
|
-
const manager = tool
|
|
3206
|
+
const manager = getManager(tool);
|
|
2996
3207
|
const providers = manager.list();
|
|
2997
3208
|
const current = manager.getCurrent();
|
|
2998
|
-
const toolName = tool
|
|
3209
|
+
const { name: toolName } = CLI_TOOL_CONFIG[tool];
|
|
2999
3210
|
if (providers.length === 0) {
|
|
3000
3211
|
console.log(chalk11.yellow(`
|
|
3001
3212
|
\u26A0\uFE0F \u6682\u65E0 ${toolName} \u670D\u52A1\u5546
|
|
@@ -3007,9 +3218,9 @@ async function handleList(tool) {
|
|
|
3007
3218
|
console.log(formatProviderTable(providers, current?.id));
|
|
3008
3219
|
}
|
|
3009
3220
|
async function handleCurrent(tool) {
|
|
3010
|
-
const manager = tool
|
|
3221
|
+
const manager = getManager(tool);
|
|
3011
3222
|
const current = manager.getCurrent();
|
|
3012
|
-
const toolName = tool
|
|
3223
|
+
const { name: toolName } = CLI_TOOL_CONFIG[tool];
|
|
3013
3224
|
if (!current) {
|
|
3014
3225
|
console.log(chalk11.yellow(`
|
|
3015
3226
|
\u26A0\uFE0F \u672A\u9009\u62E9\u4EFB\u4F55 ${toolName} \u670D\u52A1\u5546
|
|
@@ -3028,7 +3239,7 @@ async function handleCurrent(tool) {
|
|
|
3028
3239
|
console.log();
|
|
3029
3240
|
}
|
|
3030
3241
|
async function handleEdit(tool) {
|
|
3031
|
-
const manager = tool
|
|
3242
|
+
const manager = getManager(tool);
|
|
3032
3243
|
const providers = manager.list();
|
|
3033
3244
|
if (providers.length === 0) {
|
|
3034
3245
|
console.log(chalk11.yellow("\n\u26A0\uFE0F \u6682\u65E0\u670D\u52A1\u5546\n"));
|
|
@@ -3089,7 +3300,7 @@ async function handleEdit(tool) {
|
|
|
3089
3300
|
console.log(chalk11.green("\n\u2705 \u7F16\u8F91\u6210\u529F\n"));
|
|
3090
3301
|
}
|
|
3091
3302
|
async function handleClone(tool) {
|
|
3092
|
-
const manager = tool
|
|
3303
|
+
const manager = getManager(tool);
|
|
3093
3304
|
const providers = manager.list();
|
|
3094
3305
|
if (providers.length === 0) {
|
|
3095
3306
|
console.log(chalk11.yellow("\n\u26A0\uFE0F \u6682\u65E0\u670D\u52A1\u5546\n"));
|
|
@@ -3136,7 +3347,7 @@ async function handleClone(tool) {
|
|
|
3136
3347
|
console.log();
|
|
3137
3348
|
}
|
|
3138
3349
|
async function handleRemove(tool) {
|
|
3139
|
-
const manager = tool
|
|
3350
|
+
const manager = getManager(tool);
|
|
3140
3351
|
const providers = manager.list();
|
|
3141
3352
|
if (providers.length === 0) {
|
|
3142
3353
|
console.log(chalk11.yellow("\n\u26A0\uFE0F \u6682\u65E0\u670D\u52A1\u5546\n"));
|
|
@@ -4648,7 +4859,7 @@ function editCommand3(program2) {
|
|
|
4648
4859
|
targetId = selectedId;
|
|
4649
4860
|
}
|
|
4650
4861
|
const provider = manager.get(targetId);
|
|
4651
|
-
const
|
|
4862
|
+
const currentCommand4 = provider.baseUrl;
|
|
4652
4863
|
const currentArgs = provider.apiKey;
|
|
4653
4864
|
const currentEnv = provider.model;
|
|
4654
4865
|
console.log(chalk30.bold("\n\u270F\uFE0F \u7F16\u8F91 MCP \u670D\u52A1\u5668\n"));
|
|
@@ -4664,7 +4875,7 @@ function editCommand3(program2) {
|
|
|
4664
4875
|
type: "input",
|
|
4665
4876
|
name: "command",
|
|
4666
4877
|
message: "\u542F\u52A8\u547D\u4EE4:",
|
|
4667
|
-
default:
|
|
4878
|
+
default: currentCommand4
|
|
4668
4879
|
},
|
|
4669
4880
|
{
|
|
4670
4881
|
type: "input",
|
|
@@ -4683,7 +4894,7 @@ function editCommand3(program2) {
|
|
|
4683
4894
|
if (answers.name && answers.name !== provider.name) {
|
|
4684
4895
|
updates.name = answers.name;
|
|
4685
4896
|
}
|
|
4686
|
-
if (answers.command && answers.command !==
|
|
4897
|
+
if (answers.command && answers.command !== currentCommand4) {
|
|
4687
4898
|
updates.baseUrl = answers.command;
|
|
4688
4899
|
}
|
|
4689
4900
|
if (answers.args && answers.args !== currentArgs) {
|
|
@@ -4732,44 +4943,480 @@ function createMCPCommands(program2) {
|
|
|
4732
4943
|
editCommand3(program2);
|
|
4733
4944
|
}
|
|
4734
4945
|
|
|
4946
|
+
// src/commands/gemini/add.ts
|
|
4947
|
+
init_dist();
|
|
4948
|
+
import chalk31 from "chalk";
|
|
4949
|
+
import inquirer22 from "inquirer";
|
|
4950
|
+
function addCommand4(program2) {
|
|
4951
|
+
program2.command("add").description("\u6DFB\u52A0\u65B0\u7684 Gemini CLI \u670D\u52A1\u5546(\u4EA4\u4E92\u5F0F)").action(async () => {
|
|
4952
|
+
try {
|
|
4953
|
+
const manager = createGeminiManager();
|
|
4954
|
+
console.log(chalk31.bold("\n\u{1F4DD} \u6DFB\u52A0 Gemini CLI \u670D\u52A1\u5546\n"));
|
|
4955
|
+
const { usePreset } = await inquirer22.prompt([
|
|
4956
|
+
{
|
|
4957
|
+
type: "list",
|
|
4958
|
+
name: "usePreset",
|
|
4959
|
+
message: "\u9009\u62E9\u914D\u7F6E\u6765\u6E90:",
|
|
4960
|
+
choices: [
|
|
4961
|
+
{ name: "\u{1F4E6} \u4F7F\u7528\u9884\u7F6E\u670D\u52A1\u5546", value: true },
|
|
4962
|
+
{ name: "\u270F\uFE0F \u81EA\u5B9A\u4E49\u914D\u7F6E", value: false }
|
|
4963
|
+
]
|
|
4964
|
+
}
|
|
4965
|
+
]);
|
|
4966
|
+
let name;
|
|
4967
|
+
let desc;
|
|
4968
|
+
let baseUrl;
|
|
4969
|
+
let apiKey;
|
|
4970
|
+
if (usePreset) {
|
|
4971
|
+
const { presetName } = await inquirer22.prompt([
|
|
4972
|
+
{
|
|
4973
|
+
type: "list",
|
|
4974
|
+
name: "presetName",
|
|
4975
|
+
message: "\u9009\u62E9\u9884\u7F6E\u670D\u52A1\u5546:",
|
|
4976
|
+
choices: GEMINI_PRESETS.map((p) => ({
|
|
4977
|
+
name: `${p.name} - ${p.description}`,
|
|
4978
|
+
value: p.name
|
|
4979
|
+
}))
|
|
4980
|
+
}
|
|
4981
|
+
]);
|
|
4982
|
+
const preset = GEMINI_PRESETS.find((p) => p.name === presetName);
|
|
4983
|
+
console.log(chalk31.blue(`
|
|
4984
|
+
\u4F7F\u7528\u9884\u8BBE: ${preset.name} - ${preset.description}
|
|
4985
|
+
`));
|
|
4986
|
+
const input = await promptProviderForm({
|
|
4987
|
+
name: preset.name,
|
|
4988
|
+
desc: "",
|
|
4989
|
+
baseUrl: preset.baseUrl,
|
|
4990
|
+
apiKey: ""
|
|
4991
|
+
});
|
|
4992
|
+
name = input.name;
|
|
4993
|
+
desc = input.desc;
|
|
4994
|
+
baseUrl = input.baseUrl;
|
|
4995
|
+
apiKey = input.apiKey;
|
|
4996
|
+
} else {
|
|
4997
|
+
const answers = await inquirer22.prompt([
|
|
4998
|
+
{
|
|
4999
|
+
type: "input",
|
|
5000
|
+
name: "name",
|
|
5001
|
+
message: "\u670D\u52A1\u5546\u540D\u79F0:",
|
|
5002
|
+
validate: (value) => {
|
|
5003
|
+
if (!value) return "\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A";
|
|
5004
|
+
return true;
|
|
5005
|
+
}
|
|
5006
|
+
},
|
|
5007
|
+
{
|
|
5008
|
+
type: "input",
|
|
5009
|
+
name: "baseUrl",
|
|
5010
|
+
message: "API \u5730\u5740 (\u53EF\u4E3A\u7A7A\uFF0C\u4F7F\u7528\u5B98\u65B9\u9ED8\u8BA4):",
|
|
5011
|
+
validate: (value) => {
|
|
5012
|
+
if (!value) return true;
|
|
5013
|
+
if (!value.startsWith("http://") && !value.startsWith("https://")) {
|
|
5014
|
+
return "API \u5730\u5740\u5FC5\u987B\u4EE5 http:// \u6216 https:// \u5F00\u5934";
|
|
5015
|
+
}
|
|
5016
|
+
return true;
|
|
5017
|
+
}
|
|
5018
|
+
},
|
|
5019
|
+
{
|
|
5020
|
+
type: "password",
|
|
5021
|
+
name: "apiKey",
|
|
5022
|
+
message: "API \u5BC6\u94A5 (\u53EF\u4E3A\u7A7A\uFF0C\u4F7F\u7528\u73AF\u5883\u5DF2\u914D\u7F6E\u7684 Key):",
|
|
5023
|
+
mask: "*"
|
|
5024
|
+
}
|
|
5025
|
+
]);
|
|
5026
|
+
name = answers.name;
|
|
5027
|
+
desc = void 0;
|
|
5028
|
+
baseUrl = answers.baseUrl || "";
|
|
5029
|
+
apiKey = answers.apiKey || "";
|
|
5030
|
+
}
|
|
5031
|
+
const provider = manager.add({ name, desc, baseUrl, apiKey });
|
|
5032
|
+
console.log();
|
|
5033
|
+
console.log(chalk31.green("\u2705 \u6DFB\u52A0\u6210\u529F"));
|
|
5034
|
+
console.log();
|
|
5035
|
+
console.log(` ${chalk31.bold(provider.name)} ${chalk31.blue("[Gemini CLI]")}`);
|
|
5036
|
+
console.log(` ${chalk31.gray(provider.baseUrl || "(\u4F7F\u7528\u9ED8\u8BA4\u7AEF\u70B9)")}`);
|
|
5037
|
+
console.log();
|
|
5038
|
+
const { switchNow } = await inquirer22.prompt([
|
|
5039
|
+
{
|
|
5040
|
+
type: "confirm",
|
|
5041
|
+
name: "switchNow",
|
|
5042
|
+
message: "\u662F\u5426\u7ACB\u5373\u5207\u6362\u5230\u6B64\u670D\u52A1\u5546?",
|
|
5043
|
+
default: true
|
|
5044
|
+
}
|
|
5045
|
+
]);
|
|
5046
|
+
if (switchNow) {
|
|
5047
|
+
manager.switch(provider.id);
|
|
5048
|
+
console.log(chalk31.green("\u2705 \u5DF2\u5207\u6362\u5230\u65B0\u670D\u52A1\u5546"));
|
|
5049
|
+
console.log();
|
|
5050
|
+
console.log(chalk31.gray("\u914D\u7F6E\u5DF2\u66F4\u65B0:"));
|
|
5051
|
+
console.log(chalk31.gray(` - ${getGeminiSettingsPath()}`));
|
|
5052
|
+
console.log(chalk31.gray(` - ${getGeminiEnvPath()}`));
|
|
5053
|
+
} else {
|
|
5054
|
+
console.log(chalk31.blue("\u{1F4A1} \u7A0D\u540E\u5207\u6362:") + chalk31.white(` ccman gm use "${provider.name}"`));
|
|
5055
|
+
}
|
|
5056
|
+
} catch (error) {
|
|
5057
|
+
console.error(chalk31.red(`
|
|
5058
|
+
\u274C ${error.message}
|
|
5059
|
+
`));
|
|
5060
|
+
process.exit(1);
|
|
5061
|
+
}
|
|
5062
|
+
});
|
|
5063
|
+
}
|
|
5064
|
+
|
|
5065
|
+
// src/commands/gemini/list.ts
|
|
5066
|
+
init_dist();
|
|
5067
|
+
import chalk32 from "chalk";
|
|
5068
|
+
function listCommand4(program2) {
|
|
5069
|
+
program2.command("list").alias("ls").description("\u5217\u51FA\u6240\u6709 Gemini CLI \u670D\u52A1\u5546").action(async () => {
|
|
5070
|
+
try {
|
|
5071
|
+
const manager = createGeminiManager();
|
|
5072
|
+
const providers = manager.list();
|
|
5073
|
+
const current = manager.getCurrent();
|
|
5074
|
+
if (providers.length === 0) {
|
|
5075
|
+
console.log(chalk32.yellow("\n\u26A0\uFE0F \u6682\u65E0 Gemini CLI \u670D\u52A1\u5546\n"));
|
|
5076
|
+
console.log(chalk32.blue("\u{1F4A1} \u6DFB\u52A0\u670D\u52A1\u5546:") + chalk32.white(" ccman gm add\n"));
|
|
5077
|
+
return;
|
|
5078
|
+
}
|
|
5079
|
+
console.log(chalk32.bold(`
|
|
5080
|
+
\u{1F4CB} Gemini CLI \u670D\u52A1\u5546 (${providers.length} \u4E2A)`));
|
|
5081
|
+
console.log(formatProviderTable(providers, current?.id));
|
|
5082
|
+
} catch (error) {
|
|
5083
|
+
console.error(chalk32.red(`
|
|
5084
|
+
\u274C ${error.message}
|
|
5085
|
+
`));
|
|
5086
|
+
process.exit(1);
|
|
5087
|
+
}
|
|
5088
|
+
});
|
|
5089
|
+
}
|
|
5090
|
+
|
|
5091
|
+
// src/commands/gemini/use.ts
|
|
5092
|
+
init_dist();
|
|
5093
|
+
import chalk33 from "chalk";
|
|
5094
|
+
import inquirer23 from "inquirer";
|
|
5095
|
+
function useCommand3(program2) {
|
|
5096
|
+
program2.command("use [name]").description("\u5207\u6362 Gemini CLI \u670D\u52A1\u5546").action(async (name) => {
|
|
5097
|
+
try {
|
|
5098
|
+
const manager = createGeminiManager();
|
|
5099
|
+
const providers = manager.list();
|
|
5100
|
+
if (providers.length === 0) {
|
|
5101
|
+
console.log(chalk33.yellow("\n\u26A0\uFE0F \u6682\u65E0 Gemini CLI \u670D\u52A1\u5546\n"));
|
|
5102
|
+
console.log(chalk33.blue("\u{1F4A1} \u6DFB\u52A0\u670D\u52A1\u5546:") + chalk33.white(" ccman gm add\n"));
|
|
5103
|
+
return;
|
|
5104
|
+
}
|
|
5105
|
+
let targetId;
|
|
5106
|
+
if (name) {
|
|
5107
|
+
const provider2 = manager.findByName(name);
|
|
5108
|
+
if (!provider2) {
|
|
5109
|
+
throw new ProviderNotFoundError(name);
|
|
5110
|
+
}
|
|
5111
|
+
targetId = provider2.id;
|
|
5112
|
+
} else {
|
|
5113
|
+
const { selectedId } = await inquirer23.prompt([
|
|
5114
|
+
{
|
|
5115
|
+
type: "list",
|
|
5116
|
+
name: "selectedId",
|
|
5117
|
+
message: "\u9009\u62E9\u8981\u5207\u6362\u7684\u670D\u52A1\u5546:",
|
|
5118
|
+
choices: providers.map((p) => ({
|
|
5119
|
+
name: `${p.name} - ${p.baseUrl || "(\u9ED8\u8BA4\u7AEF\u70B9)"}`,
|
|
5120
|
+
value: p.id
|
|
5121
|
+
}))
|
|
5122
|
+
}
|
|
5123
|
+
]);
|
|
5124
|
+
targetId = selectedId;
|
|
5125
|
+
}
|
|
5126
|
+
manager.switch(targetId);
|
|
5127
|
+
const provider = manager.get(targetId);
|
|
5128
|
+
console.log();
|
|
5129
|
+
console.log(chalk33.green("\u2705 \u5207\u6362\u6210\u529F"));
|
|
5130
|
+
console.log();
|
|
5131
|
+
console.log(` ${chalk33.bold(provider.name)} ${chalk33.blue("[Gemini CLI]")}`);
|
|
5132
|
+
console.log(` ${chalk33.gray(`URL: ${provider.baseUrl || "(\u9ED8\u8BA4\u7AEF\u70B9)"}`)}`);
|
|
5133
|
+
console.log();
|
|
5134
|
+
console.log(chalk33.gray("\u914D\u7F6E\u5DF2\u66F4\u65B0:"));
|
|
5135
|
+
console.log(chalk33.gray(` - ${getGeminiSettingsPath()}`));
|
|
5136
|
+
console.log(chalk33.gray(` - ${getGeminiEnvPath()}`));
|
|
5137
|
+
console.log();
|
|
5138
|
+
} catch (error) {
|
|
5139
|
+
if (error instanceof ProviderNotFoundError) {
|
|
5140
|
+
console.error(chalk33.red(`
|
|
5141
|
+
\u274C \u670D\u52A1\u5546\u4E0D\u5B58\u5728: ${error.message}
|
|
5142
|
+
`));
|
|
5143
|
+
console.log(chalk33.blue("\u{1F4A1} \u67E5\u770B\u6240\u6709\u670D\u52A1\u5546:") + chalk33.white(" ccman gm list\n"));
|
|
5144
|
+
} else {
|
|
5145
|
+
console.error(chalk33.red(`
|
|
5146
|
+
\u274C ${error.message}
|
|
5147
|
+
`));
|
|
5148
|
+
}
|
|
5149
|
+
process.exit(1);
|
|
5150
|
+
}
|
|
5151
|
+
});
|
|
5152
|
+
}
|
|
5153
|
+
|
|
5154
|
+
// src/commands/gemini/current.ts
|
|
5155
|
+
init_dist();
|
|
5156
|
+
import chalk34 from "chalk";
|
|
5157
|
+
function currentCommand3(program2) {
|
|
5158
|
+
program2.command("current").description("\u663E\u793A\u5F53\u524D Gemini CLI \u670D\u52A1\u5546").action(async () => {
|
|
5159
|
+
try {
|
|
5160
|
+
const manager = createGeminiManager();
|
|
5161
|
+
const current = manager.getCurrent();
|
|
5162
|
+
if (!current) {
|
|
5163
|
+
console.log(chalk34.yellow("\n\u26A0\uFE0F \u5F53\u524D\u6CA1\u6709\u6FC0\u6D3B\u7684 Gemini CLI \u670D\u52A1\u5546\n"));
|
|
5164
|
+
console.log(chalk34.blue("\u{1F4A1} \u5217\u51FA\u670D\u52A1\u5546:") + chalk34.white(" ccman gm list\n"));
|
|
5165
|
+
return;
|
|
5166
|
+
}
|
|
5167
|
+
console.log(chalk34.bold("\n\u{1F3AF} \u5F53\u524D Gemini CLI \u670D\u52A1\u5546\n"));
|
|
5168
|
+
console.log(` \u540D\u79F0: ${chalk34.bold(current.name)}`);
|
|
5169
|
+
console.log(` \u5730\u5740: ${chalk34.gray(current.baseUrl || "(\u9ED8\u8BA4\u7AEF\u70B9)")}`);
|
|
5170
|
+
console.log();
|
|
5171
|
+
} catch (error) {
|
|
5172
|
+
console.error(chalk34.red(`
|
|
5173
|
+
\u274C ${error.message}
|
|
5174
|
+
`));
|
|
5175
|
+
process.exit(1);
|
|
5176
|
+
}
|
|
5177
|
+
});
|
|
5178
|
+
}
|
|
5179
|
+
|
|
5180
|
+
// src/commands/gemini/remove.ts
|
|
5181
|
+
init_dist();
|
|
5182
|
+
import chalk35 from "chalk";
|
|
5183
|
+
import inquirer24 from "inquirer";
|
|
5184
|
+
function removeCommand4(program2) {
|
|
5185
|
+
program2.command("remove [name]").alias("rm").description("\u5220\u9664 Gemini CLI \u670D\u52A1\u5546").action(async (name) => {
|
|
5186
|
+
try {
|
|
5187
|
+
const manager = createGeminiManager();
|
|
5188
|
+
const providers = manager.list();
|
|
5189
|
+
if (providers.length === 0) {
|
|
5190
|
+
console.log(chalk35.yellow("\n\u26A0\uFE0F \u6682\u65E0 Gemini CLI \u670D\u52A1\u5546\n"));
|
|
5191
|
+
console.log(chalk35.blue("\u{1F4A1} \u6DFB\u52A0\u670D\u52A1\u5546:") + chalk35.white(" ccman gm add\n"));
|
|
5192
|
+
return;
|
|
5193
|
+
}
|
|
5194
|
+
let targetId;
|
|
5195
|
+
let targetName;
|
|
5196
|
+
if (name) {
|
|
5197
|
+
const provider = manager.findByName(name);
|
|
5198
|
+
if (!provider) {
|
|
5199
|
+
console.log(chalk35.red(`
|
|
5200
|
+
\u274C \u670D\u52A1\u5546\u4E0D\u5B58\u5728: ${name}
|
|
5201
|
+
`));
|
|
5202
|
+
process.exit(1);
|
|
5203
|
+
}
|
|
5204
|
+
targetId = provider.id;
|
|
5205
|
+
targetName = provider.name;
|
|
5206
|
+
} else {
|
|
5207
|
+
const { selectedId } = await inquirer24.prompt([
|
|
5208
|
+
{
|
|
5209
|
+
type: "list",
|
|
5210
|
+
name: "selectedId",
|
|
5211
|
+
message: "\u9009\u62E9\u8981\u5220\u9664\u7684\u670D\u52A1\u5546:",
|
|
5212
|
+
choices: providers.map((p) => ({
|
|
5213
|
+
name: `${p.name} - ${p.baseUrl || "(\u9ED8\u8BA4\u7AEF\u70B9)"}`,
|
|
5214
|
+
value: p.id
|
|
5215
|
+
}))
|
|
5216
|
+
}
|
|
5217
|
+
]);
|
|
5218
|
+
const provider = manager.get(selectedId);
|
|
5219
|
+
targetId = provider.id;
|
|
5220
|
+
targetName = provider.name;
|
|
5221
|
+
}
|
|
5222
|
+
const { confirm } = await inquirer24.prompt([
|
|
5223
|
+
{
|
|
5224
|
+
type: "confirm",
|
|
5225
|
+
name: "confirm",
|
|
5226
|
+
message: `\u786E\u5B9A\u8981\u5220\u9664\u670D\u52A1\u5546 "${targetName}" \u5417\uFF1F`,
|
|
5227
|
+
default: false
|
|
5228
|
+
}
|
|
5229
|
+
]);
|
|
5230
|
+
if (!confirm) {
|
|
5231
|
+
console.log(chalk35.gray("\n\u5DF2\u53D6\u6D88\u5220\u9664\n"));
|
|
5232
|
+
return;
|
|
5233
|
+
}
|
|
5234
|
+
manager.remove(targetId);
|
|
5235
|
+
console.log(chalk35.green("\n\u2705 \u5DF2\u5220\u9664\u670D\u52A1\u5546\n"));
|
|
5236
|
+
} catch (error) {
|
|
5237
|
+
console.error(chalk35.red(`
|
|
5238
|
+
\u274C ${error.message}
|
|
5239
|
+
`));
|
|
5240
|
+
process.exit(1);
|
|
5241
|
+
}
|
|
5242
|
+
});
|
|
5243
|
+
}
|
|
5244
|
+
|
|
5245
|
+
// src/commands/gemini/edit.ts
|
|
5246
|
+
init_dist();
|
|
5247
|
+
import chalk36 from "chalk";
|
|
5248
|
+
import inquirer25 from "inquirer";
|
|
5249
|
+
function editCommand4(program2) {
|
|
5250
|
+
program2.command("edit [name]").description("\u7F16\u8F91 Gemini CLI \u670D\u52A1\u5546").action(async (name) => {
|
|
5251
|
+
try {
|
|
5252
|
+
const manager = createGeminiManager();
|
|
5253
|
+
const providers = manager.list();
|
|
5254
|
+
if (providers.length === 0) {
|
|
5255
|
+
console.log(chalk36.yellow("\n\u26A0\uFE0F \u6682\u65E0 Gemini CLI \u670D\u52A1\u5546\n"));
|
|
5256
|
+
console.log(chalk36.blue("\u{1F4A1} \u6DFB\u52A0\u670D\u52A1\u5546:") + chalk36.white(" ccman gm add\n"));
|
|
5257
|
+
return;
|
|
5258
|
+
}
|
|
5259
|
+
let targetId;
|
|
5260
|
+
if (name) {
|
|
5261
|
+
const provider2 = manager.findByName(name);
|
|
5262
|
+
if (!provider2) {
|
|
5263
|
+
console.log(chalk36.red(`
|
|
5264
|
+
\u274C \u670D\u52A1\u5546\u4E0D\u5B58\u5728: ${name}
|
|
5265
|
+
`));
|
|
5266
|
+
process.exit(1);
|
|
5267
|
+
}
|
|
5268
|
+
targetId = provider2.id;
|
|
5269
|
+
} else {
|
|
5270
|
+
const { selectedId } = await inquirer25.prompt([
|
|
5271
|
+
{
|
|
5272
|
+
type: "list",
|
|
5273
|
+
name: "selectedId",
|
|
5274
|
+
message: "\u9009\u62E9\u8981\u7F16\u8F91\u7684\u670D\u52A1\u5546:",
|
|
5275
|
+
choices: providers.map((p) => ({
|
|
5276
|
+
name: `${p.name} - ${p.baseUrl || "(\u9ED8\u8BA4\u7AEF\u70B9)"}`,
|
|
5277
|
+
value: p.id
|
|
5278
|
+
}))
|
|
5279
|
+
}
|
|
5280
|
+
]);
|
|
5281
|
+
targetId = selectedId;
|
|
5282
|
+
}
|
|
5283
|
+
const provider = manager.get(targetId);
|
|
5284
|
+
const input = await promptProviderForm({
|
|
5285
|
+
name: provider.name,
|
|
5286
|
+
desc: provider.desc ?? "",
|
|
5287
|
+
baseUrl: provider.baseUrl,
|
|
5288
|
+
apiKey: provider.apiKey
|
|
5289
|
+
});
|
|
5290
|
+
manager.edit(targetId, {
|
|
5291
|
+
name: input.name,
|
|
5292
|
+
desc: input.desc,
|
|
5293
|
+
baseUrl: input.baseUrl,
|
|
5294
|
+
apiKey: input.apiKey
|
|
5295
|
+
});
|
|
5296
|
+
console.log(chalk36.green("\n\u2705 \u7F16\u8F91\u6210\u529F\n"));
|
|
5297
|
+
} catch (error) {
|
|
5298
|
+
console.error(chalk36.red(`
|
|
5299
|
+
\u274C ${error.message}
|
|
5300
|
+
`));
|
|
5301
|
+
process.exit(1);
|
|
5302
|
+
}
|
|
5303
|
+
});
|
|
5304
|
+
}
|
|
5305
|
+
|
|
5306
|
+
// src/commands/gemini/clone.ts
|
|
5307
|
+
init_dist();
|
|
5308
|
+
import chalk37 from "chalk";
|
|
5309
|
+
import inquirer26 from "inquirer";
|
|
5310
|
+
function cloneCommand3(program2) {
|
|
5311
|
+
program2.command("clone [name]").description("\u514B\u9686 Gemini CLI \u670D\u52A1\u5546").action(async (name) => {
|
|
5312
|
+
try {
|
|
5313
|
+
const manager = createGeminiManager();
|
|
5314
|
+
const providers = manager.list();
|
|
5315
|
+
if (providers.length === 0) {
|
|
5316
|
+
console.log(chalk37.yellow("\n\u26A0\uFE0F \u6682\u65E0 Gemini CLI \u670D\u52A1\u5546\n"));
|
|
5317
|
+
console.log(chalk37.blue("\u{1F4A1} \u6DFB\u52A0\u670D\u52A1\u5546:") + chalk37.white(" ccman gm add\n"));
|
|
5318
|
+
return;
|
|
5319
|
+
}
|
|
5320
|
+
let sourceId;
|
|
5321
|
+
if (name) {
|
|
5322
|
+
const provider = manager.findByName(name);
|
|
5323
|
+
if (!provider) {
|
|
5324
|
+
console.log(chalk37.red(`
|
|
5325
|
+
\u274C \u670D\u52A1\u5546\u4E0D\u5B58\u5728: ${name}
|
|
5326
|
+
`));
|
|
5327
|
+
process.exit(1);
|
|
5328
|
+
}
|
|
5329
|
+
sourceId = provider.id;
|
|
5330
|
+
} else {
|
|
5331
|
+
const { selectedId } = await inquirer26.prompt([
|
|
5332
|
+
{
|
|
5333
|
+
type: "list",
|
|
5334
|
+
name: "selectedId",
|
|
5335
|
+
message: "\u9009\u62E9\u8981\u514B\u9686\u7684\u670D\u52A1\u5546:",
|
|
5336
|
+
choices: providers.map((p) => ({
|
|
5337
|
+
name: `${p.name} - ${p.baseUrl || "(\u9ED8\u8BA4\u7AEF\u70B9)"}`,
|
|
5338
|
+
value: p.id
|
|
5339
|
+
}))
|
|
5340
|
+
}
|
|
5341
|
+
]);
|
|
5342
|
+
sourceId = selectedId;
|
|
5343
|
+
}
|
|
5344
|
+
const { newName } = await inquirer26.prompt([
|
|
5345
|
+
{
|
|
5346
|
+
type: "input",
|
|
5347
|
+
name: "newName",
|
|
5348
|
+
message: "\u8F93\u5165\u65B0\u670D\u52A1\u5546\u540D\u79F0:",
|
|
5349
|
+
validate: (value) => {
|
|
5350
|
+
if (!value) return "\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A";
|
|
5351
|
+
return true;
|
|
5352
|
+
}
|
|
5353
|
+
}
|
|
5354
|
+
]);
|
|
5355
|
+
const newProvider = manager.clone(sourceId, newName);
|
|
5356
|
+
console.log();
|
|
5357
|
+
console.log(chalk37.green("\u2705 \u514B\u9686\u6210\u529F"));
|
|
5358
|
+
console.log();
|
|
5359
|
+
console.log(` ${chalk37.bold(newProvider.name)} ${chalk37.blue("[Gemini CLI]")}`);
|
|
5360
|
+
console.log(` ${chalk37.gray(newProvider.baseUrl || "(\u9ED8\u8BA4\u7AEF\u70B9)")}`);
|
|
5361
|
+
console.log();
|
|
5362
|
+
} catch (error) {
|
|
5363
|
+
console.error(chalk37.red(`
|
|
5364
|
+
\u274C ${error.message}
|
|
5365
|
+
`));
|
|
5366
|
+
process.exit(1);
|
|
5367
|
+
}
|
|
5368
|
+
});
|
|
5369
|
+
}
|
|
5370
|
+
|
|
5371
|
+
// src/commands/gemini/index.ts
|
|
5372
|
+
function createGeminiCommands(program2) {
|
|
5373
|
+
addCommand4(program2);
|
|
5374
|
+
listCommand4(program2);
|
|
5375
|
+
useCommand3(program2);
|
|
5376
|
+
currentCommand3(program2);
|
|
5377
|
+
removeCommand4(program2);
|
|
5378
|
+
editCommand4(program2);
|
|
5379
|
+
cloneCommand3(program2);
|
|
5380
|
+
}
|
|
5381
|
+
|
|
4735
5382
|
// src/index.ts
|
|
4736
5383
|
init_sync();
|
|
4737
5384
|
|
|
4738
5385
|
// src/commands/export.ts
|
|
4739
5386
|
init_dist();
|
|
4740
|
-
import
|
|
5387
|
+
import chalk38 from "chalk";
|
|
4741
5388
|
import path10 from "path";
|
|
4742
5389
|
function exportCommand(program2) {
|
|
4743
5390
|
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
5391
|
try {
|
|
4745
|
-
console.log(
|
|
5392
|
+
console.log(chalk38.bold("\n\u{1F4E6} \u5BFC\u51FA\u914D\u7F6E\n"));
|
|
4746
5393
|
const validation = validateExport();
|
|
4747
5394
|
if (!validation.valid) {
|
|
4748
|
-
console.log(
|
|
5395
|
+
console.log(chalk38.red(`\u274C ${validation.message}
|
|
4749
5396
|
`));
|
|
4750
5397
|
process.exit(1);
|
|
4751
5398
|
}
|
|
4752
5399
|
const resolvedPath = targetDir.startsWith("~") ? path10.join(process.env.HOME || "", targetDir.slice(1)) : path10.resolve(targetDir);
|
|
4753
5400
|
console.log("\u5BFC\u51FA\u6587\u4EF6:");
|
|
4754
|
-
console.log(` ${
|
|
4755
|
-
console.log(` ${
|
|
5401
|
+
console.log(` ${chalk38.cyan("codex.json")} - Codex \u914D\u7F6E`);
|
|
5402
|
+
console.log(` ${chalk38.cyan("claude.json")} - Claude \u914D\u7F6E`);
|
|
4756
5403
|
console.log();
|
|
4757
|
-
console.log(`\u76EE\u6807\u76EE\u5F55: ${
|
|
5404
|
+
console.log(`\u76EE\u6807\u76EE\u5F55: ${chalk38.cyan(resolvedPath)}`);
|
|
4758
5405
|
console.log();
|
|
4759
|
-
console.log(
|
|
5406
|
+
console.log(chalk38.yellow("\u26A0\uFE0F \u5BFC\u51FA\u6587\u4EF6\u5305\u542B API Key\uFF0C\u8BF7\u59A5\u5584\u4FDD\u7BA1"));
|
|
4760
5407
|
console.log();
|
|
4761
5408
|
const result = exportConfig(resolvedPath);
|
|
4762
|
-
console.log(
|
|
5409
|
+
console.log(chalk38.green("\u2705 \u5BFC\u51FA\u6210\u529F"));
|
|
4763
5410
|
console.log();
|
|
4764
5411
|
console.log("\u5DF2\u5BFC\u51FA\u6587\u4EF6:");
|
|
4765
5412
|
for (const file of result.exportedFiles) {
|
|
4766
|
-
console.log(` ${
|
|
5413
|
+
console.log(` ${chalk38.cyan("\u2713")} ${file}`);
|
|
4767
5414
|
}
|
|
4768
5415
|
console.log();
|
|
4769
|
-
console.log(
|
|
5416
|
+
console.log(chalk38.blue(`\u{1F4A1} \u5BFC\u5165\u547D\u4EE4: ccman import ${resolvedPath}
|
|
4770
5417
|
`));
|
|
4771
5418
|
} catch (error) {
|
|
4772
|
-
console.error(
|
|
5419
|
+
console.error(chalk38.red(`
|
|
4773
5420
|
\u274C ${error.message}
|
|
4774
5421
|
`));
|
|
4775
5422
|
process.exit(1);
|
|
@@ -4779,31 +5426,31 @@ function exportCommand(program2) {
|
|
|
4779
5426
|
|
|
4780
5427
|
// src/commands/import.ts
|
|
4781
5428
|
init_dist();
|
|
4782
|
-
import
|
|
4783
|
-
import
|
|
5429
|
+
import chalk39 from "chalk";
|
|
5430
|
+
import inquirer27 from "inquirer";
|
|
4784
5431
|
import path11 from "path";
|
|
4785
5432
|
function importCommand(program2) {
|
|
4786
5433
|
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
5434
|
try {
|
|
4788
5435
|
const resolvedPath = sourceDir.startsWith("~") ? path11.join(process.env.HOME || "", sourceDir.slice(1)) : path11.resolve(sourceDir);
|
|
4789
|
-
console.log(
|
|
5436
|
+
console.log(chalk39.bold("\n\u{1F4E5} \u5BFC\u5165\u914D\u7F6E\n"));
|
|
4790
5437
|
const validation = validateImportDir(resolvedPath);
|
|
4791
5438
|
if (!validation.valid) {
|
|
4792
|
-
console.log(
|
|
5439
|
+
console.log(chalk39.red(`\u274C ${validation.message}
|
|
4793
5440
|
`));
|
|
4794
5441
|
process.exit(1);
|
|
4795
5442
|
}
|
|
4796
|
-
console.log(
|
|
4797
|
-
console.log(`\u6E90\u76EE\u5F55: ${
|
|
5443
|
+
console.log(chalk39.yellow("\u26A0\uFE0F \u8B66\u544A\uFF1A\u5BFC\u5165\u5C06\u8986\u76D6\u5F53\u524D\u914D\u7F6E\n"));
|
|
5444
|
+
console.log(`\u6E90\u76EE\u5F55: ${chalk39.cyan(resolvedPath)}`);
|
|
4798
5445
|
console.log();
|
|
4799
5446
|
console.log("\u627E\u5230\u914D\u7F6E\u6587\u4EF6:");
|
|
4800
5447
|
for (const file of validation.foundFiles) {
|
|
4801
|
-
console.log(` ${
|
|
5448
|
+
console.log(` ${chalk39.cyan("\u2713")} ${file}`);
|
|
4802
5449
|
}
|
|
4803
5450
|
console.log();
|
|
4804
|
-
console.log(
|
|
5451
|
+
console.log(chalk39.gray("\u5F53\u524D\u914D\u7F6E\u5C06\u88AB\u8986\u76D6\uFF08\u81EA\u52A8\u5907\u4EFD\uFF09"));
|
|
4805
5452
|
console.log();
|
|
4806
|
-
const { confirmFirst } = await
|
|
5453
|
+
const { confirmFirst } = await inquirer27.prompt([
|
|
4807
5454
|
{
|
|
4808
5455
|
type: "confirm",
|
|
4809
5456
|
name: "confirmFirst",
|
|
@@ -4812,13 +5459,13 @@ function importCommand(program2) {
|
|
|
4812
5459
|
}
|
|
4813
5460
|
]);
|
|
4814
5461
|
if (!confirmFirst) {
|
|
4815
|
-
console.log(
|
|
5462
|
+
console.log(chalk39.gray("\n\u274C \u5DF2\u53D6\u6D88\n"));
|
|
4816
5463
|
return;
|
|
4817
5464
|
}
|
|
4818
5465
|
console.log();
|
|
4819
|
-
console.log(
|
|
5466
|
+
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
5467
|
console.log();
|
|
4821
|
-
const { confirmSecond } = await
|
|
5468
|
+
const { confirmSecond } = await inquirer27.prompt([
|
|
4822
5469
|
{
|
|
4823
5470
|
type: "confirm",
|
|
4824
5471
|
name: "confirmSecond",
|
|
@@ -4827,31 +5474,31 @@ function importCommand(program2) {
|
|
|
4827
5474
|
}
|
|
4828
5475
|
]);
|
|
4829
5476
|
if (!confirmSecond) {
|
|
4830
|
-
console.log(
|
|
5477
|
+
console.log(chalk39.gray("\n\u274C \u5DF2\u53D6\u6D88\n"));
|
|
4831
5478
|
return;
|
|
4832
5479
|
}
|
|
4833
5480
|
console.log();
|
|
4834
|
-
console.log(
|
|
4835
|
-
console.log(
|
|
5481
|
+
console.log(chalk39.gray("\u{1F4BE} \u5907\u4EFD\u5F53\u524D\u914D\u7F6E..."));
|
|
5482
|
+
console.log(chalk39.gray("\u{1F4E5} \u5BFC\u5165\u65B0\u914D\u7F6E..."));
|
|
4836
5483
|
const result = importConfig(resolvedPath);
|
|
4837
5484
|
console.log();
|
|
4838
|
-
console.log(
|
|
5485
|
+
console.log(chalk39.green("\u2705 \u5BFC\u5165\u6210\u529F"));
|
|
4839
5486
|
console.log();
|
|
4840
5487
|
if (result.backupPaths.length > 0) {
|
|
4841
5488
|
console.log("\u5907\u4EFD\u6587\u4EF6:");
|
|
4842
5489
|
for (const backupPath of result.backupPaths) {
|
|
4843
|
-
console.log(` ${
|
|
5490
|
+
console.log(` ${chalk39.gray(backupPath)}`);
|
|
4844
5491
|
}
|
|
4845
5492
|
console.log();
|
|
4846
5493
|
}
|
|
4847
5494
|
console.log("\u5DF2\u5BFC\u5165\u6587\u4EF6:");
|
|
4848
5495
|
for (const file of result.importedFiles) {
|
|
4849
|
-
console.log(` ${
|
|
5496
|
+
console.log(` ${chalk39.cyan("\u2713")} ${file}`);
|
|
4850
5497
|
}
|
|
4851
5498
|
console.log();
|
|
4852
|
-
console.log(
|
|
5499
|
+
console.log(chalk39.blue("\u{1F4A1} \u8BF7\u4F7F\u7528 'ccman cx use' \u6216 'ccman cc use' \u5207\u6362\u670D\u52A1\u5546\n"));
|
|
4853
5500
|
} catch (error) {
|
|
4854
|
-
console.error(
|
|
5501
|
+
console.error(chalk39.red(`
|
|
4855
5502
|
\u274C ${error.message}
|
|
4856
5503
|
`));
|
|
4857
5504
|
process.exit(1);
|
|
@@ -4862,10 +5509,10 @@ function importCommand(program2) {
|
|
|
4862
5509
|
// src/index.ts
|
|
4863
5510
|
init_dist();
|
|
4864
5511
|
if (process.env.NODE_ENV === "development") {
|
|
4865
|
-
console.log(
|
|
4866
|
-
console.log(
|
|
4867
|
-
console.log(
|
|
4868
|
-
console.log(
|
|
5512
|
+
console.log(chalk40.gray("\n[\u5F00\u53D1\u6A21\u5F0F] \u914D\u7F6E\u76EE\u5F55:"));
|
|
5513
|
+
console.log(chalk40.gray(` ccman: ${getCcmanDir()}`));
|
|
5514
|
+
console.log(chalk40.gray(` codex: ${getCodexDir()}`));
|
|
5515
|
+
console.log(chalk40.gray(` claude: ${getClaudeDir()}`));
|
|
4869
5516
|
console.log();
|
|
4870
5517
|
}
|
|
4871
5518
|
var program = new Command3();
|
|
@@ -4877,21 +5524,21 @@ program.name("ccman").description("Codex/Claude Code API \u670D\u52A1\u5546\u914
|
|
|
4877
5524
|
});
|
|
4878
5525
|
program.on("command:*", (operands) => {
|
|
4879
5526
|
const unknownCommand = operands[0];
|
|
4880
|
-
console.error(
|
|
5527
|
+
console.error(chalk40.red(`
|
|
4881
5528
|
\u274C \u672A\u77E5\u547D\u4EE4: ${unknownCommand}
|
|
4882
5529
|
`));
|
|
4883
|
-
const availableCommands = ["cx", "cc", "mcp", "sync", "export", "import"];
|
|
5530
|
+
const availableCommands = ["cx", "cc", "gm", "mcp", "sync", "export", "import"];
|
|
4884
5531
|
const suggestions = availableCommands.filter(
|
|
4885
5532
|
(cmd) => cmd.includes(unknownCommand) || unknownCommand.includes(cmd)
|
|
4886
5533
|
);
|
|
4887
5534
|
if (suggestions.length > 0) {
|
|
4888
|
-
console.log(
|
|
5535
|
+
console.log(chalk40.yellow("\u{1F4A1} \u4F60\u662F\u4E0D\u662F\u60F3\u8F93\u5165:"));
|
|
4889
5536
|
suggestions.forEach((cmd) => {
|
|
4890
|
-
console.log(
|
|
5537
|
+
console.log(chalk40.cyan(` ccman ${cmd}`));
|
|
4891
5538
|
});
|
|
4892
5539
|
console.log();
|
|
4893
5540
|
}
|
|
4894
|
-
console.log(
|
|
5541
|
+
console.log(chalk40.gray("\u67E5\u770B\u6240\u6709\u53EF\u7528\u547D\u4EE4: ") + chalk40.cyan("ccman --help"));
|
|
4895
5542
|
console.log();
|
|
4896
5543
|
process.exit(1);
|
|
4897
5544
|
});
|
|
@@ -4907,6 +5554,12 @@ cc.action(async () => {
|
|
|
4907
5554
|
printLogo();
|
|
4908
5555
|
await startClaudeMenu();
|
|
4909
5556
|
});
|
|
5557
|
+
var gm = program.command("gm").description("\u7BA1\u7406 Gemini CLI \u670D\u52A1\u5546");
|
|
5558
|
+
createGeminiCommands(gm);
|
|
5559
|
+
gm.action(async () => {
|
|
5560
|
+
printLogo();
|
|
5561
|
+
await startGeminiMenu();
|
|
5562
|
+
});
|
|
4910
5563
|
var mcp = program.command("mcp").description("\u7BA1\u7406 MCP \u670D\u52A1\u5668");
|
|
4911
5564
|
createMCPCommands(mcp);
|
|
4912
5565
|
mcp.action(() => {
|