ccman 3.2.2 → 3.3.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 +62 -43
- package/dist/index.js +761 -93
- package/dist/templates/codex/config.toml +5 -6
- package/package.json +3 -2
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.3.0",
|
|
19
19
|
type: "module",
|
|
20
20
|
description: "Core business logic for ccman - Manage Codex, Claude Code, Gemini CLI, and MCP configurations",
|
|
21
21
|
main: "./dist/index.js",
|
|
@@ -79,7 +79,8 @@ var init_dist = __esm({
|
|
|
79
79
|
CODEX: "codex",
|
|
80
80
|
CLAUDE: "claude",
|
|
81
81
|
MCP: "mcp",
|
|
82
|
-
GEMINI: "gemini"
|
|
82
|
+
GEMINI: "gemini",
|
|
83
|
+
OPENCODE: "opencode"
|
|
83
84
|
};
|
|
84
85
|
MAIN_TOOL_TYPES = {
|
|
85
86
|
CODEX: TOOL_TYPES.CODEX,
|
|
@@ -118,6 +119,14 @@ var init_dist = __esm({
|
|
|
118
119
|
bgColorClass: "bg-green-50",
|
|
119
120
|
hoverBgColorClass: "hover:bg-green-100",
|
|
120
121
|
description: "Gemini CLI AI \u52A9\u624B"
|
|
122
|
+
},
|
|
123
|
+
[TOOL_TYPES.OPENCODE]: {
|
|
124
|
+
displayName: "OpenCode",
|
|
125
|
+
color: "amber",
|
|
126
|
+
textColorClass: "text-amber-600",
|
|
127
|
+
bgColorClass: "bg-amber-50",
|
|
128
|
+
hoverBgColorClass: "hover:bg-amber-100",
|
|
129
|
+
description: "OpenCode \u914D\u7F6E"
|
|
121
130
|
}
|
|
122
131
|
};
|
|
123
132
|
}
|
|
@@ -147,6 +156,9 @@ function getClaudeDir() {
|
|
|
147
156
|
function getGeminiDir() {
|
|
148
157
|
return geminiDir;
|
|
149
158
|
}
|
|
159
|
+
function getOpenCodeDir() {
|
|
160
|
+
return opencodeDir;
|
|
161
|
+
}
|
|
150
162
|
function getConfigPath() {
|
|
151
163
|
return path.join(ccmanDir, "config.json");
|
|
152
164
|
}
|
|
@@ -168,14 +180,17 @@ function getGeminiSettingsPath() {
|
|
|
168
180
|
function getGeminiEnvPath() {
|
|
169
181
|
return path.join(geminiDir, ".env");
|
|
170
182
|
}
|
|
171
|
-
|
|
183
|
+
function getOpenCodeConfigPath() {
|
|
184
|
+
return path.join(opencodeDir, "opencode.json");
|
|
185
|
+
}
|
|
186
|
+
var isDev, isTest, rootDir, ccmanDir, codexDir, claudeDir, geminiDir, opencodeDir;
|
|
172
187
|
var init_paths = __esm({
|
|
173
188
|
"../core/dist/paths.js"() {
|
|
174
189
|
"use strict";
|
|
175
190
|
isDev = process.env.NODE_ENV === "development";
|
|
176
191
|
isTest = process.env.NODE_ENV === "test";
|
|
177
192
|
if (isTest) {
|
|
178
|
-
rootDir = path.join(
|
|
193
|
+
rootDir = path.join("/tmp", "ccman-test");
|
|
179
194
|
} else if (isDev) {
|
|
180
195
|
rootDir = path.join(os.tmpdir(), "ccman-dev");
|
|
181
196
|
} else {
|
|
@@ -185,6 +200,7 @@ var init_paths = __esm({
|
|
|
185
200
|
codexDir = path.join(rootDir, ".codex");
|
|
186
201
|
claudeDir = path.join(rootDir, ".claude");
|
|
187
202
|
geminiDir = path.join(rootDir, ".gemini");
|
|
203
|
+
opencodeDir = path.join(rootDir, ".config", "opencode");
|
|
188
204
|
}
|
|
189
205
|
});
|
|
190
206
|
|
|
@@ -576,9 +592,14 @@ var init_codex2 = __esm({
|
|
|
576
592
|
"use strict";
|
|
577
593
|
CODEX_PRESETS = [
|
|
578
594
|
{
|
|
579
|
-
name: "
|
|
580
|
-
baseUrl: "https://
|
|
581
|
-
description: "
|
|
595
|
+
name: "OpenAI Official",
|
|
596
|
+
baseUrl: "https://api.openai.com/v1",
|
|
597
|
+
description: "OpenAI \u5B98\u65B9 API"
|
|
598
|
+
},
|
|
599
|
+
{
|
|
600
|
+
name: "GMN",
|
|
601
|
+
baseUrl: "https://gmn.chuangzuoli.cn/openai",
|
|
602
|
+
description: "GMN \u670D\u52A1 (Codex/Gemini \u517C\u5BB9)"
|
|
582
603
|
}
|
|
583
604
|
];
|
|
584
605
|
}
|
|
@@ -594,36 +615,6 @@ var init_claude2 = __esm({
|
|
|
594
615
|
name: "Anthropic Official",
|
|
595
616
|
baseUrl: "https://api.anthropic.com",
|
|
596
617
|
description: "Anthropic \u5B98\u65B9 API"
|
|
597
|
-
},
|
|
598
|
-
{
|
|
599
|
-
name: "AnyRouter",
|
|
600
|
-
baseUrl: "https://anyrouter.top",
|
|
601
|
-
description: "AnyRouter API \u670D\u52A1"
|
|
602
|
-
},
|
|
603
|
-
{
|
|
604
|
-
name: "PackyCode",
|
|
605
|
-
baseUrl: "https://api.packycode.com",
|
|
606
|
-
description: "PackyCode API \u670D\u52A1"
|
|
607
|
-
},
|
|
608
|
-
{
|
|
609
|
-
name: "88Code",
|
|
610
|
-
baseUrl: "https://www.88code.org/api",
|
|
611
|
-
description: "88Code API \u670D\u52A1"
|
|
612
|
-
},
|
|
613
|
-
{
|
|
614
|
-
name: "KKYYXX",
|
|
615
|
-
baseUrl: "https://api.kkyyxx.xyz",
|
|
616
|
-
description: "KKYYXX API \u670D\u52A1"
|
|
617
|
-
},
|
|
618
|
-
{
|
|
619
|
-
name: "BigModel",
|
|
620
|
-
baseUrl: "https://open.bigmodel.cn/api/anthropic",
|
|
621
|
-
description: "\u667A\u8C31 BigModel API"
|
|
622
|
-
},
|
|
623
|
-
{
|
|
624
|
-
name: "ModelScope",
|
|
625
|
-
baseUrl: "https://api-inference.modelscope.cn/v1/chat/completions",
|
|
626
|
-
description: "\u963F\u91CC\u4E91 ModelScope API"
|
|
627
618
|
}
|
|
628
619
|
];
|
|
629
620
|
}
|
|
@@ -711,14 +702,24 @@ var init_gemini = __esm({
|
|
|
711
702
|
description: "\u4F7F\u7528\u5B98\u65B9 Gemini API\uFF08\u901A\u8FC7 GEMINI_API_KEY \u6216 GOOGLE_API_KEY \u8BA4\u8BC1\uFF09"
|
|
712
703
|
},
|
|
713
704
|
{
|
|
714
|
-
name: "
|
|
715
|
-
baseUrl: "https://
|
|
716
|
-
description: "
|
|
717
|
-
}
|
|
705
|
+
name: "GMN",
|
|
706
|
+
baseUrl: "https://gmn.chuangzuoli.cn/openai",
|
|
707
|
+
description: "GMN \u670D\u52A1 (Codex/Gemini \u517C\u5BB9)"
|
|
708
|
+
}
|
|
709
|
+
];
|
|
710
|
+
}
|
|
711
|
+
});
|
|
712
|
+
|
|
713
|
+
// ../core/dist/presets/opencode.js
|
|
714
|
+
var OPENCODE_PRESETS;
|
|
715
|
+
var init_opencode = __esm({
|
|
716
|
+
"../core/dist/presets/opencode.js"() {
|
|
717
|
+
"use strict";
|
|
718
|
+
OPENCODE_PRESETS = [
|
|
718
719
|
{
|
|
719
|
-
name: "
|
|
720
|
-
baseUrl: "
|
|
721
|
-
description: "
|
|
720
|
+
name: "GMN",
|
|
721
|
+
baseUrl: "https://gmn.chuangzuoli.cn/openai",
|
|
722
|
+
description: "GMN \u670D\u52A1 (OpenCode \u517C\u5BB9)"
|
|
722
723
|
}
|
|
723
724
|
];
|
|
724
725
|
}
|
|
@@ -840,6 +841,94 @@ var init_gemini2 = __esm({
|
|
|
840
841
|
}
|
|
841
842
|
});
|
|
842
843
|
|
|
844
|
+
// ../core/dist/writers/opencode.js
|
|
845
|
+
function parseProviderMeta(raw) {
|
|
846
|
+
if (!raw || !raw.trim())
|
|
847
|
+
return null;
|
|
848
|
+
try {
|
|
849
|
+
const parsed = JSON.parse(raw);
|
|
850
|
+
if (parsed && typeof parsed === "object") {
|
|
851
|
+
return parsed;
|
|
852
|
+
}
|
|
853
|
+
} catch {
|
|
854
|
+
return { npm: raw };
|
|
855
|
+
}
|
|
856
|
+
return null;
|
|
857
|
+
}
|
|
858
|
+
function toProviderKey(name) {
|
|
859
|
+
const normalized = name.trim().toLowerCase();
|
|
860
|
+
const collapsed = normalized.replace(/\s+/g, "-");
|
|
861
|
+
const cleaned = collapsed.replace(/[^a-z0-9-_]/g, "");
|
|
862
|
+
return cleaned || "provider";
|
|
863
|
+
}
|
|
864
|
+
function writeOpenCodeConfig(provider) {
|
|
865
|
+
ensureDir(getOpenCodeDir());
|
|
866
|
+
const configPath = getOpenCodeConfigPath();
|
|
867
|
+
const existingConfig = fileExists(configPath) ? readJSON(configPath) : {};
|
|
868
|
+
const meta = parseProviderMeta(provider.model);
|
|
869
|
+
const npmPackage = meta?.npm || DEFAULT_NPM_PACKAGE;
|
|
870
|
+
const providerKey = toProviderKey(provider.name);
|
|
871
|
+
const existingProvider = existingConfig.provider?.[providerKey];
|
|
872
|
+
const models = meta?.models || existingProvider?.models || DEFAULT_MODELS;
|
|
873
|
+
const providerConfig = {
|
|
874
|
+
...existingProvider,
|
|
875
|
+
npm: npmPackage,
|
|
876
|
+
name: provider.name,
|
|
877
|
+
options: {
|
|
878
|
+
...existingProvider?.options || {},
|
|
879
|
+
baseURL: provider.baseUrl,
|
|
880
|
+
apiKey: provider.apiKey
|
|
881
|
+
},
|
|
882
|
+
models
|
|
883
|
+
};
|
|
884
|
+
const existingProviders = existingConfig.provider && typeof existingConfig.provider === "object" ? { ...existingConfig.provider } : {};
|
|
885
|
+
const nextConfig = {
|
|
886
|
+
...existingConfig,
|
|
887
|
+
$schema: OPENCODE_SCHEMA,
|
|
888
|
+
provider: {
|
|
889
|
+
...existingProviders,
|
|
890
|
+
[providerKey]: providerConfig
|
|
891
|
+
}
|
|
892
|
+
};
|
|
893
|
+
writeJSON(configPath, nextConfig);
|
|
894
|
+
}
|
|
895
|
+
var OPENCODE_SCHEMA, DEFAULT_NPM_PACKAGE, DEFAULT_MODELS;
|
|
896
|
+
var init_opencode2 = __esm({
|
|
897
|
+
"../core/dist/writers/opencode.js"() {
|
|
898
|
+
"use strict";
|
|
899
|
+
init_paths();
|
|
900
|
+
init_file();
|
|
901
|
+
OPENCODE_SCHEMA = "https://opencode.ai/config.json";
|
|
902
|
+
DEFAULT_NPM_PACKAGE = "@ai-sdk/openai";
|
|
903
|
+
DEFAULT_MODELS = {
|
|
904
|
+
"gpt-5.2-codex": {
|
|
905
|
+
variants: {
|
|
906
|
+
xhigh: {
|
|
907
|
+
reasoningEffort: "xhigh",
|
|
908
|
+
textVerbosity: "low",
|
|
909
|
+
reasoningSummary: "auto"
|
|
910
|
+
},
|
|
911
|
+
high: {
|
|
912
|
+
reasoningEffort: "high",
|
|
913
|
+
textVerbosity: "low",
|
|
914
|
+
reasoningSummary: "auto"
|
|
915
|
+
},
|
|
916
|
+
medium: {
|
|
917
|
+
reasoningEffort: "medium",
|
|
918
|
+
textVerbosity: "low",
|
|
919
|
+
reasoningSummary: "auto"
|
|
920
|
+
},
|
|
921
|
+
low: {
|
|
922
|
+
reasoningEffort: "low",
|
|
923
|
+
textVerbosity: "low",
|
|
924
|
+
reasoningSummary: "auto"
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
};
|
|
929
|
+
}
|
|
930
|
+
});
|
|
931
|
+
|
|
843
932
|
// ../core/dist/tool-manager.types.js
|
|
844
933
|
var ProviderNotFoundError, ProviderNameConflictError, PresetNameConflictError;
|
|
845
934
|
var init_tool_manager_types = __esm({
|
|
@@ -1119,6 +1208,9 @@ function createMCPManager() {
|
|
|
1119
1208
|
function createGeminiManager() {
|
|
1120
1209
|
return createToolManager("gemini");
|
|
1121
1210
|
}
|
|
1211
|
+
function createOpenCodeManager() {
|
|
1212
|
+
return createToolManager("opencode");
|
|
1213
|
+
}
|
|
1122
1214
|
var TOOL_CONFIGS;
|
|
1123
1215
|
var init_tool_manager = __esm({
|
|
1124
1216
|
"../core/dist/tool-manager.js"() {
|
|
@@ -1132,7 +1224,9 @@ var init_tool_manager = __esm({
|
|
|
1132
1224
|
init_claude2();
|
|
1133
1225
|
init_mcp2();
|
|
1134
1226
|
init_gemini();
|
|
1227
|
+
init_opencode();
|
|
1135
1228
|
init_gemini2();
|
|
1229
|
+
init_opencode2();
|
|
1136
1230
|
init_tool_manager_types();
|
|
1137
1231
|
TOOL_CONFIGS = {
|
|
1138
1232
|
codex: {
|
|
@@ -1179,6 +1273,11 @@ var init_tool_manager = __esm({
|
|
|
1179
1273
|
configPath: path6.join(getCcmanDir(), "gemini.json"),
|
|
1180
1274
|
builtinPresets: GEMINI_PRESETS,
|
|
1181
1275
|
writer: writeGeminiConfig
|
|
1276
|
+
},
|
|
1277
|
+
opencode: {
|
|
1278
|
+
configPath: path6.join(getCcmanDir(), "opencode.json"),
|
|
1279
|
+
builtinPresets: OPENCODE_PRESETS,
|
|
1280
|
+
writer: writeOpenCodeConfig
|
|
1182
1281
|
}
|
|
1183
1282
|
};
|
|
1184
1283
|
}
|
|
@@ -2150,6 +2249,7 @@ var init_dist2 = __esm({
|
|
|
2150
2249
|
init_claude2();
|
|
2151
2250
|
init_mcp2();
|
|
2152
2251
|
init_gemini();
|
|
2252
|
+
init_opencode();
|
|
2153
2253
|
init_mcp();
|
|
2154
2254
|
init_migrate();
|
|
2155
2255
|
init_paths();
|
|
@@ -2873,7 +2973,7 @@ var init_sync = __esm({
|
|
|
2873
2973
|
|
|
2874
2974
|
// src/index.ts
|
|
2875
2975
|
import { Command as Command3 } from "commander";
|
|
2876
|
-
import
|
|
2976
|
+
import chalk47 from "chalk";
|
|
2877
2977
|
|
|
2878
2978
|
// src/utils/logo.ts
|
|
2879
2979
|
init_dist2();
|
|
@@ -2931,11 +3031,33 @@ function formatProviderTable(providers, currentId) {
|
|
|
2931
3031
|
return lines.join("\n");
|
|
2932
3032
|
}
|
|
2933
3033
|
|
|
3034
|
+
// src/utils/opencode.ts
|
|
3035
|
+
var DEFAULT_OPENCODE_NPM = "@ai-sdk/openai";
|
|
3036
|
+
function parseOpenCodeMeta(raw) {
|
|
3037
|
+
if (!raw || !raw.trim()) return null;
|
|
3038
|
+
try {
|
|
3039
|
+
const parsed = JSON.parse(raw);
|
|
3040
|
+
if (parsed && typeof parsed === "object") {
|
|
3041
|
+
return parsed;
|
|
3042
|
+
}
|
|
3043
|
+
} catch {
|
|
3044
|
+
return { npm: raw };
|
|
3045
|
+
}
|
|
3046
|
+
return null;
|
|
3047
|
+
}
|
|
3048
|
+
function buildOpenCodeModel(meta) {
|
|
3049
|
+
const payload = {};
|
|
3050
|
+
if (meta.npm) payload.npm = meta.npm;
|
|
3051
|
+
if (meta.models) payload.models = meta.models;
|
|
3052
|
+
return JSON.stringify(payload);
|
|
3053
|
+
}
|
|
3054
|
+
|
|
2934
3055
|
// src/interactive.ts
|
|
2935
3056
|
var CLI_TOOL_CONFIG = {
|
|
2936
3057
|
[TOOL_TYPES.CODEX]: { name: "Codex", emoji: "\u{1F536}", cmd: "cx" },
|
|
2937
3058
|
[TOOL_TYPES.CLAUDE]: { name: "Claude", emoji: "\u{1F537}", cmd: "cc" },
|
|
2938
|
-
[TOOL_TYPES.GEMINI]: { name: "Gemini", emoji: "\u{1F48E}", cmd: "gm" }
|
|
3059
|
+
[TOOL_TYPES.GEMINI]: { name: "Gemini", emoji: "\u{1F48E}", cmd: "gm" },
|
|
3060
|
+
[TOOL_TYPES.OPENCODE]: { name: "OpenCode", emoji: "\u{1F9E9}", cmd: "oc" }
|
|
2939
3061
|
};
|
|
2940
3062
|
function getManager(tool) {
|
|
2941
3063
|
switch (tool) {
|
|
@@ -2945,6 +3067,8 @@ function getManager(tool) {
|
|
|
2945
3067
|
return createClaudeManager();
|
|
2946
3068
|
case TOOL_TYPES.GEMINI:
|
|
2947
3069
|
return createGeminiManager();
|
|
3070
|
+
case TOOL_TYPES.OPENCODE:
|
|
3071
|
+
return createOpenCodeManager();
|
|
2948
3072
|
}
|
|
2949
3073
|
}
|
|
2950
3074
|
async function promptProviderForm(defaults) {
|
|
@@ -3009,6 +3133,7 @@ async function startMainMenu() {
|
|
|
3009
3133
|
{ name: "\u{1F537} Claude \u7BA1\u7406", value: "claude" },
|
|
3010
3134
|
{ name: "\u{1F536} Codex \u7BA1\u7406", value: "codex" },
|
|
3011
3135
|
{ name: "\u{1F48E} Gemini \u7BA1\u7406", value: "gemini" },
|
|
3136
|
+
{ name: "\u{1F9E9} OpenCode \u7BA1\u7406", value: "opencode" },
|
|
3012
3137
|
{ name: "\u{1F504} WebDAV \u540C\u6B65", value: "sync" },
|
|
3013
3138
|
{ name: "\u{1F4E6} \u9884\u7F6E\u670D\u52A1\u5546\u7BA1\u7406", value: "presets" },
|
|
3014
3139
|
{ name: "\u274C \u9000\u51FA", value: "exit" }
|
|
@@ -3025,6 +3150,8 @@ async function startMainMenu() {
|
|
|
3025
3150
|
await startCodexMenu();
|
|
3026
3151
|
} else if (choice === "gemini") {
|
|
3027
3152
|
await startGeminiMenu();
|
|
3153
|
+
} else if (choice === "opencode") {
|
|
3154
|
+
await startOpenCodeMenu();
|
|
3028
3155
|
} else if (choice === "sync") {
|
|
3029
3156
|
const { startSyncMenu: startSyncMenu2 } = await Promise.resolve().then(() => (init_sync(), sync_exports));
|
|
3030
3157
|
await startSyncMenu2();
|
|
@@ -3042,6 +3169,9 @@ async function startCodexMenu() {
|
|
|
3042
3169
|
async function startGeminiMenu() {
|
|
3043
3170
|
await showToolMenu(TOOL_TYPES.GEMINI);
|
|
3044
3171
|
}
|
|
3172
|
+
async function startOpenCodeMenu() {
|
|
3173
|
+
await showToolMenu(TOOL_TYPES.OPENCODE);
|
|
3174
|
+
}
|
|
3045
3175
|
async function showToolMenu(tool) {
|
|
3046
3176
|
const { name: toolName, emoji: toolEmoji } = CLI_TOOL_CONFIG[tool];
|
|
3047
3177
|
while (true) {
|
|
@@ -3188,7 +3318,20 @@ async function handleAdd(tool) {
|
|
|
3188
3318
|
baseUrl = answers.baseUrl;
|
|
3189
3319
|
apiKey = answers.apiKey;
|
|
3190
3320
|
}
|
|
3191
|
-
|
|
3321
|
+
let model;
|
|
3322
|
+
if (tool === TOOL_TYPES.OPENCODE) {
|
|
3323
|
+
const { npmPackage } = await inquirer7.prompt([
|
|
3324
|
+
{
|
|
3325
|
+
type: "input",
|
|
3326
|
+
name: "npmPackage",
|
|
3327
|
+
message: "\u517C\u5BB9\u5305 (npm):",
|
|
3328
|
+
default: DEFAULT_OPENCODE_NPM,
|
|
3329
|
+
validate: (value) => value ? true : "npm \u5305\u4E0D\u80FD\u4E3A\u7A7A"
|
|
3330
|
+
}
|
|
3331
|
+
]);
|
|
3332
|
+
model = buildOpenCodeModel({ npm: npmPackage });
|
|
3333
|
+
}
|
|
3334
|
+
const provider = manager.add({ name, desc, baseUrl, apiKey, model });
|
|
3192
3335
|
console.log();
|
|
3193
3336
|
console.log(chalk11.green("\u2705 \u6DFB\u52A0\u6210\u529F"));
|
|
3194
3337
|
console.log();
|
|
@@ -3291,6 +3434,8 @@ async function handleEdit(tool) {
|
|
|
3291
3434
|
}
|
|
3292
3435
|
]);
|
|
3293
3436
|
const provider = providers.find((p) => p.id === providerId);
|
|
3437
|
+
const meta = tool === TOOL_TYPES.OPENCODE ? parseOpenCodeMeta(provider.model) : null;
|
|
3438
|
+
const currentNpm = meta?.npm || DEFAULT_OPENCODE_NPM;
|
|
3294
3439
|
const answers = await inquirer7.prompt([
|
|
3295
3440
|
{
|
|
3296
3441
|
type: "input",
|
|
@@ -3325,11 +3470,25 @@ async function handleEdit(tool) {
|
|
|
3325
3470
|
mask: "*"
|
|
3326
3471
|
}
|
|
3327
3472
|
]);
|
|
3473
|
+
let model;
|
|
3474
|
+
if (tool === TOOL_TYPES.OPENCODE) {
|
|
3475
|
+
const { npmPackage } = await inquirer7.prompt([
|
|
3476
|
+
{
|
|
3477
|
+
type: "input",
|
|
3478
|
+
name: "npmPackage",
|
|
3479
|
+
message: "\u517C\u5BB9\u5305 (npm):",
|
|
3480
|
+
default: currentNpm,
|
|
3481
|
+
validate: (value) => value ? true : "npm \u5305\u4E0D\u80FD\u4E3A\u7A7A"
|
|
3482
|
+
}
|
|
3483
|
+
]);
|
|
3484
|
+
model = buildOpenCodeModel({ npm: npmPackage, models: meta?.models });
|
|
3485
|
+
}
|
|
3328
3486
|
manager.edit(providerId, {
|
|
3329
3487
|
name: answers.name,
|
|
3330
3488
|
desc: answers.desc || void 0,
|
|
3331
3489
|
baseUrl: answers.baseUrl,
|
|
3332
|
-
apiKey: answers.apiKey || void 0
|
|
3490
|
+
apiKey: answers.apiKey || void 0,
|
|
3491
|
+
model
|
|
3333
3492
|
});
|
|
3334
3493
|
console.log(chalk11.green("\n\u2705 \u7F16\u8F91\u6210\u529F\n"));
|
|
3335
3494
|
}
|
|
@@ -3352,6 +3511,8 @@ async function handleClone(tool) {
|
|
|
3352
3511
|
}
|
|
3353
3512
|
]);
|
|
3354
3513
|
const provider = providers.find((p) => p.id === providerId);
|
|
3514
|
+
const meta = tool === TOOL_TYPES.OPENCODE ? parseOpenCodeMeta(provider.model) : null;
|
|
3515
|
+
const currentNpm = meta?.npm || DEFAULT_OPENCODE_NPM;
|
|
3355
3516
|
const answers = await inquirer7.prompt([
|
|
3356
3517
|
{
|
|
3357
3518
|
type: "input",
|
|
@@ -3368,12 +3529,26 @@ async function handleClone(tool) {
|
|
|
3368
3529
|
validate: (value) => value ? true : "API \u5BC6\u94A5\u4E0D\u80FD\u4E3A\u7A7A"
|
|
3369
3530
|
}
|
|
3370
3531
|
]);
|
|
3532
|
+
let model;
|
|
3533
|
+
if (tool === TOOL_TYPES.OPENCODE) {
|
|
3534
|
+
const { npmPackage } = await inquirer7.prompt([
|
|
3535
|
+
{
|
|
3536
|
+
type: "input",
|
|
3537
|
+
name: "npmPackage",
|
|
3538
|
+
message: "\u517C\u5BB9\u5305 (npm):",
|
|
3539
|
+
default: currentNpm,
|
|
3540
|
+
validate: (value) => value ? true : "npm \u5305\u4E0D\u80FD\u4E3A\u7A7A"
|
|
3541
|
+
}
|
|
3542
|
+
]);
|
|
3543
|
+
model = buildOpenCodeModel({ npm: npmPackage, models: meta?.models });
|
|
3544
|
+
}
|
|
3371
3545
|
const newProvider = manager.add({
|
|
3372
3546
|
name: answers.name,
|
|
3373
3547
|
// 克隆时不继承描述,留空让用户后续编辑
|
|
3374
3548
|
desc: void 0,
|
|
3375
3549
|
baseUrl: provider.baseUrl,
|
|
3376
|
-
apiKey: answers.apiKey
|
|
3550
|
+
apiKey: answers.apiKey,
|
|
3551
|
+
model
|
|
3377
3552
|
});
|
|
3378
3553
|
console.log(chalk11.green("\n\u2705 \u514B\u9686\u6210\u529F\n"));
|
|
3379
3554
|
console.log(` ${chalk11.bold(newProvider.name)}`);
|
|
@@ -4893,7 +5068,7 @@ function editCommand3(program2) {
|
|
|
4893
5068
|
targetId = selectedId;
|
|
4894
5069
|
}
|
|
4895
5070
|
const provider = manager.get(targetId);
|
|
4896
|
-
const
|
|
5071
|
+
const currentCommand5 = provider.baseUrl;
|
|
4897
5072
|
const currentArgs = provider.apiKey;
|
|
4898
5073
|
const currentEnv = provider.model;
|
|
4899
5074
|
console.log(chalk30.bold("\n\u270F\uFE0F \u7F16\u8F91 MCP \u670D\u52A1\u5668\n"));
|
|
@@ -4909,7 +5084,7 @@ function editCommand3(program2) {
|
|
|
4909
5084
|
type: "input",
|
|
4910
5085
|
name: "command",
|
|
4911
5086
|
message: "\u542F\u52A8\u547D\u4EE4:",
|
|
4912
|
-
default:
|
|
5087
|
+
default: currentCommand5
|
|
4913
5088
|
},
|
|
4914
5089
|
{
|
|
4915
5090
|
type: "input",
|
|
@@ -4928,7 +5103,7 @@ function editCommand3(program2) {
|
|
|
4928
5103
|
if (answers.name && answers.name !== provider.name) {
|
|
4929
5104
|
updates.name = answers.name;
|
|
4930
5105
|
}
|
|
4931
|
-
if (answers.command && answers.command !==
|
|
5106
|
+
if (answers.command && answers.command !== currentCommand5) {
|
|
4932
5107
|
updates.baseUrl = answers.command;
|
|
4933
5108
|
}
|
|
4934
5109
|
if (answers.args && answers.args !== currentArgs) {
|
|
@@ -5413,44 +5588,530 @@ function createGeminiCommands(program2) {
|
|
|
5413
5588
|
cloneCommand3(program2);
|
|
5414
5589
|
}
|
|
5415
5590
|
|
|
5591
|
+
// src/commands/opencode/add.ts
|
|
5592
|
+
init_dist2();
|
|
5593
|
+
import chalk38 from "chalk";
|
|
5594
|
+
import inquirer27 from "inquirer";
|
|
5595
|
+
function addCommand5(program2) {
|
|
5596
|
+
program2.command("add").description("\u6DFB\u52A0\u65B0\u7684 OpenCode \u670D\u52A1\u5546(\u4EA4\u4E92\u5F0F)").action(async () => {
|
|
5597
|
+
try {
|
|
5598
|
+
const manager = createOpenCodeManager();
|
|
5599
|
+
console.log(chalk38.bold("\n\u{1F4DD} \u6DFB\u52A0 OpenCode \u670D\u52A1\u5546\n"));
|
|
5600
|
+
const { usePreset } = await inquirer27.prompt([
|
|
5601
|
+
{
|
|
5602
|
+
type: "list",
|
|
5603
|
+
name: "usePreset",
|
|
5604
|
+
message: "\u9009\u62E9\u914D\u7F6E\u6765\u6E90:",
|
|
5605
|
+
choices: [
|
|
5606
|
+
{ name: "\u{1F4E6} \u4F7F\u7528\u9884\u7F6E\u670D\u52A1\u5546", value: true },
|
|
5607
|
+
{ name: "\u270F\uFE0F \u81EA\u5B9A\u4E49\u914D\u7F6E", value: false }
|
|
5608
|
+
]
|
|
5609
|
+
}
|
|
5610
|
+
]);
|
|
5611
|
+
let name;
|
|
5612
|
+
let desc;
|
|
5613
|
+
let baseUrl;
|
|
5614
|
+
let apiKey;
|
|
5615
|
+
if (usePreset) {
|
|
5616
|
+
const { presetName } = await inquirer27.prompt([
|
|
5617
|
+
{
|
|
5618
|
+
type: "list",
|
|
5619
|
+
name: "presetName",
|
|
5620
|
+
message: "\u9009\u62E9\u9884\u7F6E\u670D\u52A1\u5546:",
|
|
5621
|
+
choices: OPENCODE_PRESETS.map((p) => ({
|
|
5622
|
+
name: `${p.name} - ${p.description}`,
|
|
5623
|
+
value: p.name
|
|
5624
|
+
}))
|
|
5625
|
+
}
|
|
5626
|
+
]);
|
|
5627
|
+
const preset = OPENCODE_PRESETS.find((p) => p.name === presetName);
|
|
5628
|
+
console.log(chalk38.blue(`
|
|
5629
|
+
\u4F7F\u7528\u9884\u8BBE: ${preset.name} - ${preset.description}
|
|
5630
|
+
`));
|
|
5631
|
+
const input = await promptProviderForm({
|
|
5632
|
+
name: preset.name,
|
|
5633
|
+
desc: "",
|
|
5634
|
+
baseUrl: preset.baseUrl,
|
|
5635
|
+
apiKey: ""
|
|
5636
|
+
});
|
|
5637
|
+
name = input.name;
|
|
5638
|
+
desc = input.desc;
|
|
5639
|
+
baseUrl = input.baseUrl;
|
|
5640
|
+
apiKey = input.apiKey;
|
|
5641
|
+
} else {
|
|
5642
|
+
const answers = await inquirer27.prompt([
|
|
5643
|
+
{
|
|
5644
|
+
type: "input",
|
|
5645
|
+
name: "name",
|
|
5646
|
+
message: "\u670D\u52A1\u5546\u540D\u79F0:",
|
|
5647
|
+
validate: (value) => value ? true : "\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A"
|
|
5648
|
+
},
|
|
5649
|
+
{
|
|
5650
|
+
type: "input",
|
|
5651
|
+
name: "baseUrl",
|
|
5652
|
+
message: "API \u5730\u5740:",
|
|
5653
|
+
validate: (value) => {
|
|
5654
|
+
if (!value) return "API \u5730\u5740\u4E0D\u80FD\u4E3A\u7A7A";
|
|
5655
|
+
if (!value.startsWith("http://") && !value.startsWith("https://")) {
|
|
5656
|
+
return "API \u5730\u5740\u5FC5\u987B\u4EE5 http:// \u6216 https:// \u5F00\u5934";
|
|
5657
|
+
}
|
|
5658
|
+
return true;
|
|
5659
|
+
}
|
|
5660
|
+
},
|
|
5661
|
+
{
|
|
5662
|
+
type: "password",
|
|
5663
|
+
name: "apiKey",
|
|
5664
|
+
message: "API \u5BC6\u94A5:",
|
|
5665
|
+
mask: "*",
|
|
5666
|
+
validate: (value) => value ? true : "API \u5BC6\u94A5\u4E0D\u80FD\u4E3A\u7A7A"
|
|
5667
|
+
}
|
|
5668
|
+
]);
|
|
5669
|
+
name = answers.name;
|
|
5670
|
+
desc = void 0;
|
|
5671
|
+
baseUrl = answers.baseUrl;
|
|
5672
|
+
apiKey = answers.apiKey;
|
|
5673
|
+
}
|
|
5674
|
+
const { npmPackage } = await inquirer27.prompt([
|
|
5675
|
+
{
|
|
5676
|
+
type: "input",
|
|
5677
|
+
name: "npmPackage",
|
|
5678
|
+
message: "\u517C\u5BB9\u5305 (npm):",
|
|
5679
|
+
default: DEFAULT_OPENCODE_NPM,
|
|
5680
|
+
validate: (value) => value ? true : "npm \u5305\u4E0D\u80FD\u4E3A\u7A7A"
|
|
5681
|
+
}
|
|
5682
|
+
]);
|
|
5683
|
+
const provider = manager.add({
|
|
5684
|
+
name,
|
|
5685
|
+
desc,
|
|
5686
|
+
baseUrl,
|
|
5687
|
+
apiKey,
|
|
5688
|
+
model: buildOpenCodeModel({ npm: npmPackage })
|
|
5689
|
+
});
|
|
5690
|
+
console.log();
|
|
5691
|
+
console.log(chalk38.green("\u2705 \u6DFB\u52A0\u6210\u529F"));
|
|
5692
|
+
console.log();
|
|
5693
|
+
console.log(` ${chalk38.bold(provider.name)} ${chalk38.blue("[OpenCode]")}`);
|
|
5694
|
+
console.log(` ${chalk38.gray(provider.baseUrl)}`);
|
|
5695
|
+
console.log();
|
|
5696
|
+
const { switchNow } = await inquirer27.prompt([
|
|
5697
|
+
{
|
|
5698
|
+
type: "confirm",
|
|
5699
|
+
name: "switchNow",
|
|
5700
|
+
message: "\u662F\u5426\u7ACB\u5373\u5207\u6362\u5230\u6B64\u670D\u52A1\u5546?",
|
|
5701
|
+
default: true
|
|
5702
|
+
}
|
|
5703
|
+
]);
|
|
5704
|
+
if (switchNow) {
|
|
5705
|
+
manager.switch(provider.id);
|
|
5706
|
+
console.log(chalk38.green("\u2705 \u5DF2\u5207\u6362\u5230\u65B0\u670D\u52A1\u5546"));
|
|
5707
|
+
console.log();
|
|
5708
|
+
console.log(chalk38.gray("\u914D\u7F6E\u5DF2\u66F4\u65B0:"));
|
|
5709
|
+
console.log(chalk38.gray(` - ${getOpenCodeConfigPath()}`));
|
|
5710
|
+
} else {
|
|
5711
|
+
console.log(chalk38.blue("\u{1F4A1} \u7A0D\u540E\u5207\u6362:") + chalk38.white(` ccman oc use "${provider.name}"`));
|
|
5712
|
+
}
|
|
5713
|
+
} catch (error) {
|
|
5714
|
+
console.error(chalk38.red(`
|
|
5715
|
+
\u274C ${error.message}
|
|
5716
|
+
`));
|
|
5717
|
+
process.exit(1);
|
|
5718
|
+
}
|
|
5719
|
+
});
|
|
5720
|
+
}
|
|
5721
|
+
|
|
5722
|
+
// src/commands/opencode/list.ts
|
|
5723
|
+
init_dist2();
|
|
5724
|
+
import chalk39 from "chalk";
|
|
5725
|
+
function listCommand5(program2) {
|
|
5726
|
+
program2.command("list").alias("ls").description("\u5217\u51FA\u6240\u6709 OpenCode \u670D\u52A1\u5546").action(async () => {
|
|
5727
|
+
try {
|
|
5728
|
+
const manager = createOpenCodeManager();
|
|
5729
|
+
const providers = manager.list();
|
|
5730
|
+
const current = manager.getCurrent();
|
|
5731
|
+
if (providers.length === 0) {
|
|
5732
|
+
console.log(chalk39.yellow("\n\u26A0\uFE0F \u6682\u65E0 OpenCode \u670D\u52A1\u5546\n"));
|
|
5733
|
+
console.log(chalk39.blue("\u{1F4A1} \u6DFB\u52A0\u670D\u52A1\u5546:") + chalk39.white(" ccman oc add\n"));
|
|
5734
|
+
return;
|
|
5735
|
+
}
|
|
5736
|
+
console.log(chalk39.bold(`
|
|
5737
|
+
\u{1F4CB} OpenCode \u670D\u52A1\u5546 (${providers.length} \u4E2A)`));
|
|
5738
|
+
console.log(formatProviderTable(providers, current?.id));
|
|
5739
|
+
} catch (error) {
|
|
5740
|
+
console.error(chalk39.red(`
|
|
5741
|
+
\u274C ${error.message}
|
|
5742
|
+
`));
|
|
5743
|
+
process.exit(1);
|
|
5744
|
+
}
|
|
5745
|
+
});
|
|
5746
|
+
}
|
|
5747
|
+
|
|
5748
|
+
// src/commands/opencode/use.ts
|
|
5749
|
+
init_dist2();
|
|
5750
|
+
import chalk40 from "chalk";
|
|
5751
|
+
import inquirer28 from "inquirer";
|
|
5752
|
+
function useCommand4(program2) {
|
|
5753
|
+
program2.command("use [name]").description("\u5207\u6362 OpenCode \u670D\u52A1\u5546").action(async (name) => {
|
|
5754
|
+
try {
|
|
5755
|
+
const manager = createOpenCodeManager();
|
|
5756
|
+
const providers = manager.list();
|
|
5757
|
+
if (providers.length === 0) {
|
|
5758
|
+
console.log(chalk40.yellow("\n\u26A0\uFE0F \u6682\u65E0 OpenCode \u670D\u52A1\u5546\n"));
|
|
5759
|
+
console.log(chalk40.blue("\u{1F4A1} \u6DFB\u52A0\u670D\u52A1\u5546:") + chalk40.white(" ccman oc add\n"));
|
|
5760
|
+
return;
|
|
5761
|
+
}
|
|
5762
|
+
let targetId;
|
|
5763
|
+
if (name) {
|
|
5764
|
+
const provider2 = manager.findByName(name);
|
|
5765
|
+
if (!provider2) {
|
|
5766
|
+
throw new ProviderNotFoundError(name);
|
|
5767
|
+
}
|
|
5768
|
+
targetId = provider2.id;
|
|
5769
|
+
} else {
|
|
5770
|
+
const { selectedId } = await inquirer28.prompt([
|
|
5771
|
+
{
|
|
5772
|
+
type: "list",
|
|
5773
|
+
name: "selectedId",
|
|
5774
|
+
message: "\u9009\u62E9\u8981\u5207\u6362\u7684\u670D\u52A1\u5546:",
|
|
5775
|
+
choices: providers.map((p) => ({
|
|
5776
|
+
name: `${p.name} - ${p.baseUrl}`,
|
|
5777
|
+
value: p.id
|
|
5778
|
+
}))
|
|
5779
|
+
}
|
|
5780
|
+
]);
|
|
5781
|
+
targetId = selectedId;
|
|
5782
|
+
}
|
|
5783
|
+
manager.switch(targetId);
|
|
5784
|
+
const provider = manager.get(targetId);
|
|
5785
|
+
console.log(chalk40.green("\n\u2705 \u5207\u6362\u6210\u529F\n"));
|
|
5786
|
+
console.log(` ${chalk40.bold(provider.name)} ${chalk40.blue("[OpenCode]")}`);
|
|
5787
|
+
console.log(` ${chalk40.gray(`URL: ${provider.baseUrl}`)}`);
|
|
5788
|
+
console.log();
|
|
5789
|
+
console.log(chalk40.gray("\u914D\u7F6E\u5DF2\u66F4\u65B0:"));
|
|
5790
|
+
console.log(chalk40.gray(` - ${getOpenCodeConfigPath()}`));
|
|
5791
|
+
} catch (error) {
|
|
5792
|
+
if (error instanceof ProviderNotFoundError) {
|
|
5793
|
+
console.error(chalk40.red(`
|
|
5794
|
+
\u274C \u670D\u52A1\u5546\u4E0D\u5B58\u5728: ${name}
|
|
5795
|
+
`));
|
|
5796
|
+
} else {
|
|
5797
|
+
console.error(chalk40.red(`
|
|
5798
|
+
\u274C ${error.message}
|
|
5799
|
+
`));
|
|
5800
|
+
}
|
|
5801
|
+
process.exit(1);
|
|
5802
|
+
}
|
|
5803
|
+
});
|
|
5804
|
+
}
|
|
5805
|
+
|
|
5806
|
+
// src/commands/opencode/current.ts
|
|
5807
|
+
init_dist2();
|
|
5808
|
+
import chalk41 from "chalk";
|
|
5809
|
+
function currentCommand4(program2) {
|
|
5810
|
+
program2.command("current").description("\u663E\u793A\u5F53\u524D OpenCode \u670D\u52A1\u5546").action(async () => {
|
|
5811
|
+
try {
|
|
5812
|
+
const manager = createOpenCodeManager();
|
|
5813
|
+
const current = manager.getCurrent();
|
|
5814
|
+
if (!current) {
|
|
5815
|
+
console.log(chalk41.yellow("\n\u26A0\uFE0F \u5F53\u524D\u6CA1\u6709\u6FC0\u6D3B\u7684 OpenCode \u670D\u52A1\u5546\n"));
|
|
5816
|
+
console.log(chalk41.blue("\u{1F4A1} \u5217\u51FA\u670D\u52A1\u5546:") + chalk41.white(" ccman oc list\n"));
|
|
5817
|
+
return;
|
|
5818
|
+
}
|
|
5819
|
+
console.log(chalk41.bold("\n\u{1F3AF} \u5F53\u524D OpenCode \u670D\u52A1\u5546\n"));
|
|
5820
|
+
console.log(` \u540D\u79F0: ${chalk41.bold(current.name)}`);
|
|
5821
|
+
console.log(` \u5730\u5740: ${chalk41.gray(current.baseUrl)}`);
|
|
5822
|
+
console.log();
|
|
5823
|
+
} catch (error) {
|
|
5824
|
+
console.error(chalk41.red(`
|
|
5825
|
+
\u274C ${error.message}
|
|
5826
|
+
`));
|
|
5827
|
+
process.exit(1);
|
|
5828
|
+
}
|
|
5829
|
+
});
|
|
5830
|
+
}
|
|
5831
|
+
|
|
5832
|
+
// src/commands/opencode/edit.ts
|
|
5833
|
+
init_dist2();
|
|
5834
|
+
import chalk42 from "chalk";
|
|
5835
|
+
import inquirer29 from "inquirer";
|
|
5836
|
+
function editCommand5(program2) {
|
|
5837
|
+
program2.command("edit [name]").description("\u7F16\u8F91 OpenCode \u670D\u52A1\u5546").action(async (name) => {
|
|
5838
|
+
try {
|
|
5839
|
+
const manager = createOpenCodeManager();
|
|
5840
|
+
const providers = manager.list();
|
|
5841
|
+
if (providers.length === 0) {
|
|
5842
|
+
console.log(chalk42.yellow("\n\u26A0\uFE0F \u6682\u65E0 OpenCode \u670D\u52A1\u5546\n"));
|
|
5843
|
+
console.log(chalk42.blue("\u{1F4A1} \u6DFB\u52A0\u670D\u52A1\u5546:") + chalk42.white(" ccman oc add\n"));
|
|
5844
|
+
return;
|
|
5845
|
+
}
|
|
5846
|
+
let targetId;
|
|
5847
|
+
if (name) {
|
|
5848
|
+
const provider2 = manager.findByName(name);
|
|
5849
|
+
if (!provider2) {
|
|
5850
|
+
throw new ProviderNotFoundError(name);
|
|
5851
|
+
}
|
|
5852
|
+
targetId = provider2.id;
|
|
5853
|
+
} else {
|
|
5854
|
+
const { selectedId } = await inquirer29.prompt([
|
|
5855
|
+
{
|
|
5856
|
+
type: "list",
|
|
5857
|
+
name: "selectedId",
|
|
5858
|
+
message: "\u9009\u62E9\u8981\u7F16\u8F91\u7684\u670D\u52A1\u5546:",
|
|
5859
|
+
choices: providers.map((p) => ({
|
|
5860
|
+
name: `${p.name} - ${p.baseUrl}`,
|
|
5861
|
+
value: p.id
|
|
5862
|
+
}))
|
|
5863
|
+
}
|
|
5864
|
+
]);
|
|
5865
|
+
targetId = selectedId;
|
|
5866
|
+
}
|
|
5867
|
+
const provider = manager.get(targetId);
|
|
5868
|
+
const meta = parseOpenCodeMeta(provider.model);
|
|
5869
|
+
const currentNpm = meta?.npm || DEFAULT_OPENCODE_NPM;
|
|
5870
|
+
const input = await promptProviderForm({
|
|
5871
|
+
name: provider.name,
|
|
5872
|
+
desc: provider.desc ?? "",
|
|
5873
|
+
baseUrl: provider.baseUrl,
|
|
5874
|
+
apiKey: provider.apiKey
|
|
5875
|
+
});
|
|
5876
|
+
const { npmPackage } = await inquirer29.prompt([
|
|
5877
|
+
{
|
|
5878
|
+
type: "input",
|
|
5879
|
+
name: "npmPackage",
|
|
5880
|
+
message: "\u517C\u5BB9\u5305 (npm):",
|
|
5881
|
+
default: currentNpm,
|
|
5882
|
+
validate: (value) => value ? true : "npm \u5305\u4E0D\u80FD\u4E3A\u7A7A"
|
|
5883
|
+
}
|
|
5884
|
+
]);
|
|
5885
|
+
manager.edit(targetId, {
|
|
5886
|
+
name: input.name,
|
|
5887
|
+
desc: input.desc,
|
|
5888
|
+
baseUrl: input.baseUrl,
|
|
5889
|
+
apiKey: input.apiKey,
|
|
5890
|
+
model: buildOpenCodeModel({
|
|
5891
|
+
npm: npmPackage,
|
|
5892
|
+
models: meta?.models
|
|
5893
|
+
})
|
|
5894
|
+
});
|
|
5895
|
+
console.log(chalk42.green("\n\u2705 \u7F16\u8F91\u6210\u529F\n"));
|
|
5896
|
+
} catch (error) {
|
|
5897
|
+
if (error instanceof ProviderNotFoundError) {
|
|
5898
|
+
console.error(chalk42.red(`
|
|
5899
|
+
\u274C \u670D\u52A1\u5546\u4E0D\u5B58\u5728: ${name}
|
|
5900
|
+
`));
|
|
5901
|
+
} else {
|
|
5902
|
+
console.error(chalk42.red(`
|
|
5903
|
+
\u274C ${error.message}
|
|
5904
|
+
`));
|
|
5905
|
+
}
|
|
5906
|
+
process.exit(1);
|
|
5907
|
+
}
|
|
5908
|
+
});
|
|
5909
|
+
}
|
|
5910
|
+
|
|
5911
|
+
// src/commands/opencode/remove.ts
|
|
5912
|
+
init_dist2();
|
|
5913
|
+
import chalk43 from "chalk";
|
|
5914
|
+
import inquirer30 from "inquirer";
|
|
5915
|
+
function removeCommand5(program2) {
|
|
5916
|
+
program2.command("remove [name]").alias("rm").description("\u5220\u9664 OpenCode \u670D\u52A1\u5546").action(async (name) => {
|
|
5917
|
+
try {
|
|
5918
|
+
const manager = createOpenCodeManager();
|
|
5919
|
+
const providers = manager.list();
|
|
5920
|
+
if (providers.length === 0) {
|
|
5921
|
+
console.log(chalk43.yellow("\n\u26A0\uFE0F \u6682\u65E0 OpenCode \u670D\u52A1\u5546\n"));
|
|
5922
|
+
return;
|
|
5923
|
+
}
|
|
5924
|
+
let targetId;
|
|
5925
|
+
let targetName;
|
|
5926
|
+
if (name) {
|
|
5927
|
+
const provider = manager.findByName(name);
|
|
5928
|
+
if (!provider) {
|
|
5929
|
+
throw new ProviderNotFoundError(name);
|
|
5930
|
+
}
|
|
5931
|
+
targetId = provider.id;
|
|
5932
|
+
targetName = provider.name;
|
|
5933
|
+
} else {
|
|
5934
|
+
const { selectedId } = await inquirer30.prompt([
|
|
5935
|
+
{
|
|
5936
|
+
type: "list",
|
|
5937
|
+
name: "selectedId",
|
|
5938
|
+
message: "\u9009\u62E9\u8981\u5220\u9664\u7684\u670D\u52A1\u5546:",
|
|
5939
|
+
choices: providers.map((p) => ({
|
|
5940
|
+
name: `${p.name} - ${p.baseUrl}`,
|
|
5941
|
+
value: p.id
|
|
5942
|
+
}))
|
|
5943
|
+
}
|
|
5944
|
+
]);
|
|
5945
|
+
const provider = manager.get(selectedId);
|
|
5946
|
+
targetId = selectedId;
|
|
5947
|
+
targetName = provider.name;
|
|
5948
|
+
}
|
|
5949
|
+
const { confirmed } = await inquirer30.prompt([
|
|
5950
|
+
{
|
|
5951
|
+
type: "confirm",
|
|
5952
|
+
name: "confirmed",
|
|
5953
|
+
message: `\u786E\u5B9A\u5220\u9664 "${targetName}"?`,
|
|
5954
|
+
default: false
|
|
5955
|
+
}
|
|
5956
|
+
]);
|
|
5957
|
+
if (!confirmed) {
|
|
5958
|
+
console.log(chalk43.gray("\n\u5DF2\u53D6\u6D88\n"));
|
|
5959
|
+
return;
|
|
5960
|
+
}
|
|
5961
|
+
manager.remove(targetId);
|
|
5962
|
+
console.log(chalk43.green(`
|
|
5963
|
+
\u2705 \u5DF2\u5220\u9664: ${targetName}
|
|
5964
|
+
`));
|
|
5965
|
+
} catch (error) {
|
|
5966
|
+
if (error instanceof ProviderNotFoundError) {
|
|
5967
|
+
console.error(chalk43.red(`
|
|
5968
|
+
\u274C \u670D\u52A1\u5546\u4E0D\u5B58\u5728: ${name}
|
|
5969
|
+
`));
|
|
5970
|
+
} else {
|
|
5971
|
+
console.error(chalk43.red(`
|
|
5972
|
+
\u274C ${error.message}
|
|
5973
|
+
`));
|
|
5974
|
+
}
|
|
5975
|
+
process.exit(1);
|
|
5976
|
+
}
|
|
5977
|
+
});
|
|
5978
|
+
}
|
|
5979
|
+
|
|
5980
|
+
// src/commands/opencode/clone.ts
|
|
5981
|
+
init_dist2();
|
|
5982
|
+
import chalk44 from "chalk";
|
|
5983
|
+
import inquirer31 from "inquirer";
|
|
5984
|
+
function cloneCommand4(program2) {
|
|
5985
|
+
program2.command("clone [source-name] [new-name]").description("\u514B\u9686 OpenCode \u670D\u52A1\u5546").action(async (sourceName, newName) => {
|
|
5986
|
+
try {
|
|
5987
|
+
const manager = createOpenCodeManager();
|
|
5988
|
+
const providers = manager.list();
|
|
5989
|
+
if (providers.length === 0) {
|
|
5990
|
+
console.log(chalk44.yellow("\n\u26A0\uFE0F \u6682\u65E0 OpenCode \u670D\u52A1\u5546\n"));
|
|
5991
|
+
return;
|
|
5992
|
+
}
|
|
5993
|
+
let sourceId;
|
|
5994
|
+
if (sourceName) {
|
|
5995
|
+
const provider = manager.findByName(sourceName);
|
|
5996
|
+
if (!provider) {
|
|
5997
|
+
throw new ProviderNotFoundError(sourceName);
|
|
5998
|
+
}
|
|
5999
|
+
sourceId = provider.id;
|
|
6000
|
+
} else {
|
|
6001
|
+
const { selectedId } = await inquirer31.prompt([
|
|
6002
|
+
{
|
|
6003
|
+
type: "list",
|
|
6004
|
+
name: "selectedId",
|
|
6005
|
+
message: "\u9009\u62E9\u8981\u514B\u9686\u7684\u670D\u52A1\u5546:",
|
|
6006
|
+
choices: providers.map((p) => ({
|
|
6007
|
+
name: `${p.name} - ${p.baseUrl}`,
|
|
6008
|
+
value: p.id
|
|
6009
|
+
}))
|
|
6010
|
+
}
|
|
6011
|
+
]);
|
|
6012
|
+
sourceId = selectedId;
|
|
6013
|
+
}
|
|
6014
|
+
const source = manager.get(sourceId);
|
|
6015
|
+
const meta = parseOpenCodeMeta(source.model);
|
|
6016
|
+
const currentNpm = meta?.npm || DEFAULT_OPENCODE_NPM;
|
|
6017
|
+
let cloned;
|
|
6018
|
+
if (newName) {
|
|
6019
|
+
cloned = manager.clone(sourceId, newName);
|
|
6020
|
+
} else {
|
|
6021
|
+
console.log(chalk44.blue(`
|
|
6022
|
+
\u514B\u9686\u81EA: ${source.name}
|
|
6023
|
+
`));
|
|
6024
|
+
const input = await promptProviderForm({
|
|
6025
|
+
name: `${source.name}\uFF08\u526F\u672C\uFF09`,
|
|
6026
|
+
desc: "",
|
|
6027
|
+
baseUrl: source.baseUrl,
|
|
6028
|
+
apiKey: source.apiKey
|
|
6029
|
+
});
|
|
6030
|
+
const { npmPackage } = await inquirer31.prompt([
|
|
6031
|
+
{
|
|
6032
|
+
type: "input",
|
|
6033
|
+
name: "npmPackage",
|
|
6034
|
+
message: "\u517C\u5BB9\u5305 (npm):",
|
|
6035
|
+
default: currentNpm,
|
|
6036
|
+
validate: (value) => value ? true : "npm \u5305\u4E0D\u80FD\u4E3A\u7A7A"
|
|
6037
|
+
}
|
|
6038
|
+
]);
|
|
6039
|
+
cloned = manager.add({
|
|
6040
|
+
name: input.name,
|
|
6041
|
+
desc: input.desc,
|
|
6042
|
+
baseUrl: input.baseUrl,
|
|
6043
|
+
apiKey: input.apiKey,
|
|
6044
|
+
model: buildOpenCodeModel({
|
|
6045
|
+
npm: npmPackage,
|
|
6046
|
+
models: meta?.models
|
|
6047
|
+
})
|
|
6048
|
+
});
|
|
6049
|
+
}
|
|
6050
|
+
console.log();
|
|
6051
|
+
console.log(chalk44.green("\u2705 \u514B\u9686\u6210\u529F"));
|
|
6052
|
+
console.log();
|
|
6053
|
+
console.log(` ${chalk44.bold(cloned.name)} ${chalk44.blue("[OpenCode]")}`);
|
|
6054
|
+
console.log(` ${chalk44.gray(`ID: ${cloned.id}`)}`);
|
|
6055
|
+
console.log(` ${chalk44.gray(`URL: ${cloned.baseUrl}`)}`);
|
|
6056
|
+
console.log();
|
|
6057
|
+
} catch (error) {
|
|
6058
|
+
console.error(chalk44.red(`
|
|
6059
|
+
\u274C ${error.message}
|
|
6060
|
+
`));
|
|
6061
|
+
process.exit(1);
|
|
6062
|
+
}
|
|
6063
|
+
});
|
|
6064
|
+
}
|
|
6065
|
+
|
|
6066
|
+
// src/commands/opencode/index.ts
|
|
6067
|
+
function createOpenCodeCommands(program2) {
|
|
6068
|
+
addCommand5(program2);
|
|
6069
|
+
listCommand5(program2);
|
|
6070
|
+
useCommand4(program2);
|
|
6071
|
+
currentCommand4(program2);
|
|
6072
|
+
editCommand5(program2);
|
|
6073
|
+
removeCommand5(program2);
|
|
6074
|
+
cloneCommand4(program2);
|
|
6075
|
+
}
|
|
6076
|
+
|
|
5416
6077
|
// src/index.ts
|
|
5417
6078
|
init_sync();
|
|
5418
6079
|
|
|
5419
6080
|
// src/commands/export.ts
|
|
5420
6081
|
init_dist2();
|
|
5421
|
-
import
|
|
6082
|
+
import chalk45 from "chalk";
|
|
5422
6083
|
import path10 from "path";
|
|
5423
6084
|
function exportCommand(program2) {
|
|
5424
6085
|
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) => {
|
|
5425
6086
|
try {
|
|
5426
|
-
console.log(
|
|
6087
|
+
console.log(chalk45.bold("\n\u{1F4E6} \u5BFC\u51FA\u914D\u7F6E\n"));
|
|
5427
6088
|
const validation = validateExport();
|
|
5428
6089
|
if (!validation.valid) {
|
|
5429
|
-
console.log(
|
|
6090
|
+
console.log(chalk45.red(`\u274C ${validation.message}
|
|
5430
6091
|
`));
|
|
5431
6092
|
process.exit(1);
|
|
5432
6093
|
}
|
|
5433
6094
|
const resolvedPath = targetDir.startsWith("~") ? path10.join(process.env.HOME || "", targetDir.slice(1)) : path10.resolve(targetDir);
|
|
5434
6095
|
console.log("\u5BFC\u51FA\u6587\u4EF6:");
|
|
5435
|
-
console.log(` ${
|
|
5436
|
-
console.log(` ${
|
|
6096
|
+
console.log(` ${chalk45.cyan("codex.json")} - Codex \u914D\u7F6E`);
|
|
6097
|
+
console.log(` ${chalk45.cyan("claude.json")} - Claude \u914D\u7F6E`);
|
|
5437
6098
|
console.log();
|
|
5438
|
-
console.log(`\u76EE\u6807\u76EE\u5F55: ${
|
|
6099
|
+
console.log(`\u76EE\u6807\u76EE\u5F55: ${chalk45.cyan(resolvedPath)}`);
|
|
5439
6100
|
console.log();
|
|
5440
|
-
console.log(
|
|
6101
|
+
console.log(chalk45.yellow("\u26A0\uFE0F \u5BFC\u51FA\u6587\u4EF6\u5305\u542B API Key\uFF0C\u8BF7\u59A5\u5584\u4FDD\u7BA1"));
|
|
5441
6102
|
console.log();
|
|
5442
6103
|
const result = exportConfig(resolvedPath);
|
|
5443
|
-
console.log(
|
|
6104
|
+
console.log(chalk45.green("\u2705 \u5BFC\u51FA\u6210\u529F"));
|
|
5444
6105
|
console.log();
|
|
5445
6106
|
console.log("\u5DF2\u5BFC\u51FA\u6587\u4EF6:");
|
|
5446
6107
|
for (const file of result.exportedFiles) {
|
|
5447
|
-
console.log(` ${
|
|
6108
|
+
console.log(` ${chalk45.cyan("\u2713")} ${file}`);
|
|
5448
6109
|
}
|
|
5449
6110
|
console.log();
|
|
5450
|
-
console.log(
|
|
6111
|
+
console.log(chalk45.blue(`\u{1F4A1} \u5BFC\u5165\u547D\u4EE4: ccman import ${resolvedPath}
|
|
5451
6112
|
`));
|
|
5452
6113
|
} catch (error) {
|
|
5453
|
-
console.error(
|
|
6114
|
+
console.error(chalk45.red(`
|
|
5454
6115
|
\u274C ${error.message}
|
|
5455
6116
|
`));
|
|
5456
6117
|
process.exit(1);
|
|
@@ -5460,31 +6121,31 @@ function exportCommand(program2) {
|
|
|
5460
6121
|
|
|
5461
6122
|
// src/commands/import.ts
|
|
5462
6123
|
init_dist2();
|
|
5463
|
-
import
|
|
5464
|
-
import
|
|
6124
|
+
import chalk46 from "chalk";
|
|
6125
|
+
import inquirer32 from "inquirer";
|
|
5465
6126
|
import path11 from "path";
|
|
5466
6127
|
function importCommand(program2) {
|
|
5467
6128
|
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) => {
|
|
5468
6129
|
try {
|
|
5469
6130
|
const resolvedPath = sourceDir.startsWith("~") ? path11.join(process.env.HOME || "", sourceDir.slice(1)) : path11.resolve(sourceDir);
|
|
5470
|
-
console.log(
|
|
6131
|
+
console.log(chalk46.bold("\n\u{1F4E5} \u5BFC\u5165\u914D\u7F6E\n"));
|
|
5471
6132
|
const validation = validateImportDir(resolvedPath);
|
|
5472
6133
|
if (!validation.valid) {
|
|
5473
|
-
console.log(
|
|
6134
|
+
console.log(chalk46.red(`\u274C ${validation.message}
|
|
5474
6135
|
`));
|
|
5475
6136
|
process.exit(1);
|
|
5476
6137
|
}
|
|
5477
|
-
console.log(
|
|
5478
|
-
console.log(`\u6E90\u76EE\u5F55: ${
|
|
6138
|
+
console.log(chalk46.yellow("\u26A0\uFE0F \u8B66\u544A\uFF1A\u5BFC\u5165\u5C06\u8986\u76D6\u5F53\u524D\u914D\u7F6E\n"));
|
|
6139
|
+
console.log(`\u6E90\u76EE\u5F55: ${chalk46.cyan(resolvedPath)}`);
|
|
5479
6140
|
console.log();
|
|
5480
6141
|
console.log("\u627E\u5230\u914D\u7F6E\u6587\u4EF6:");
|
|
5481
6142
|
for (const file of validation.foundFiles) {
|
|
5482
|
-
console.log(` ${
|
|
6143
|
+
console.log(` ${chalk46.cyan("\u2713")} ${file}`);
|
|
5483
6144
|
}
|
|
5484
6145
|
console.log();
|
|
5485
|
-
console.log(
|
|
6146
|
+
console.log(chalk46.gray("\u5F53\u524D\u914D\u7F6E\u5C06\u88AB\u8986\u76D6\uFF08\u81EA\u52A8\u5907\u4EFD\uFF09"));
|
|
5486
6147
|
console.log();
|
|
5487
|
-
const { confirmFirst } = await
|
|
6148
|
+
const { confirmFirst } = await inquirer32.prompt([
|
|
5488
6149
|
{
|
|
5489
6150
|
type: "confirm",
|
|
5490
6151
|
name: "confirmFirst",
|
|
@@ -5493,13 +6154,13 @@ function importCommand(program2) {
|
|
|
5493
6154
|
}
|
|
5494
6155
|
]);
|
|
5495
6156
|
if (!confirmFirst) {
|
|
5496
|
-
console.log(
|
|
6157
|
+
console.log(chalk46.gray("\n\u274C \u5DF2\u53D6\u6D88\n"));
|
|
5497
6158
|
return;
|
|
5498
6159
|
}
|
|
5499
6160
|
console.log();
|
|
5500
|
-
console.log(
|
|
6161
|
+
console.log(chalk46.red.bold("\u26A0\uFE0F \u6700\u540E\u786E\u8BA4\uFF1A\u6B64\u64CD\u4F5C\u5C06\u8986\u76D6\u6240\u6709\u5F53\u524D\u914D\u7F6E\uFF01"));
|
|
5501
6162
|
console.log();
|
|
5502
|
-
const { confirmSecond } = await
|
|
6163
|
+
const { confirmSecond } = await inquirer32.prompt([
|
|
5503
6164
|
{
|
|
5504
6165
|
type: "confirm",
|
|
5505
6166
|
name: "confirmSecond",
|
|
@@ -5508,31 +6169,31 @@ function importCommand(program2) {
|
|
|
5508
6169
|
}
|
|
5509
6170
|
]);
|
|
5510
6171
|
if (!confirmSecond) {
|
|
5511
|
-
console.log(
|
|
6172
|
+
console.log(chalk46.gray("\n\u274C \u5DF2\u53D6\u6D88\n"));
|
|
5512
6173
|
return;
|
|
5513
6174
|
}
|
|
5514
6175
|
console.log();
|
|
5515
|
-
console.log(
|
|
5516
|
-
console.log(
|
|
6176
|
+
console.log(chalk46.gray("\u{1F4BE} \u5907\u4EFD\u5F53\u524D\u914D\u7F6E..."));
|
|
6177
|
+
console.log(chalk46.gray("\u{1F4E5} \u5BFC\u5165\u65B0\u914D\u7F6E..."));
|
|
5517
6178
|
const result = importConfig(resolvedPath);
|
|
5518
6179
|
console.log();
|
|
5519
|
-
console.log(
|
|
6180
|
+
console.log(chalk46.green("\u2705 \u5BFC\u5165\u6210\u529F"));
|
|
5520
6181
|
console.log();
|
|
5521
6182
|
if (result.backupPaths.length > 0) {
|
|
5522
6183
|
console.log("\u5907\u4EFD\u6587\u4EF6:");
|
|
5523
6184
|
for (const backupPath of result.backupPaths) {
|
|
5524
|
-
console.log(` ${
|
|
6185
|
+
console.log(` ${chalk46.gray(backupPath)}`);
|
|
5525
6186
|
}
|
|
5526
6187
|
console.log();
|
|
5527
6188
|
}
|
|
5528
6189
|
console.log("\u5DF2\u5BFC\u5165\u6587\u4EF6:");
|
|
5529
6190
|
for (const file of result.importedFiles) {
|
|
5530
|
-
console.log(` ${
|
|
6191
|
+
console.log(` ${chalk46.cyan("\u2713")} ${file}`);
|
|
5531
6192
|
}
|
|
5532
6193
|
console.log();
|
|
5533
|
-
console.log(
|
|
6194
|
+
console.log(chalk46.blue("\u{1F4A1} \u8BF7\u4F7F\u7528 'ccman cx use' \u6216 'ccman cc use' \u5207\u6362\u670D\u52A1\u5546\n"));
|
|
5534
6195
|
} catch (error) {
|
|
5535
|
-
console.error(
|
|
6196
|
+
console.error(chalk46.red(`
|
|
5536
6197
|
\u274C ${error.message}
|
|
5537
6198
|
`));
|
|
5538
6199
|
process.exit(1);
|
|
@@ -5543,14 +6204,15 @@ function importCommand(program2) {
|
|
|
5543
6204
|
// src/index.ts
|
|
5544
6205
|
init_dist2();
|
|
5545
6206
|
if (process.env.NODE_ENV === "development") {
|
|
5546
|
-
console.log(
|
|
5547
|
-
console.log(
|
|
5548
|
-
console.log(
|
|
5549
|
-
console.log(
|
|
6207
|
+
console.log(chalk47.gray("\n[\u5F00\u53D1\u6A21\u5F0F] \u914D\u7F6E\u76EE\u5F55:"));
|
|
6208
|
+
console.log(chalk47.gray(` ccman: ${getCcmanDir()}`));
|
|
6209
|
+
console.log(chalk47.gray(` codex: ${getCodexDir()}`));
|
|
6210
|
+
console.log(chalk47.gray(` claude: ${getClaudeDir()}`));
|
|
6211
|
+
console.log(chalk47.gray(` opencode: ${getOpenCodeDir()}`));
|
|
5550
6212
|
console.log();
|
|
5551
6213
|
}
|
|
5552
6214
|
var program = new Command3();
|
|
5553
|
-
program.name("ccman").description("Codex/Claude Code API \u670D\u52A1\u5546\u914D\u7F6E\u7BA1\u7406\u5DE5\u5177").version(VERSION).showHelpAfterError(false).exitOverride((err) => {
|
|
6215
|
+
program.name("ccman").description("Codex/Claude Code/Gemini/OpenCode API \u670D\u52A1\u5546\u914D\u7F6E\u7BA1\u7406\u5DE5\u5177").version(VERSION).showHelpAfterError(false).exitOverride((err) => {
|
|
5554
6216
|
if (err.code === "commander.helpDisplayed" || err.code === "commander.version") {
|
|
5555
6217
|
process.exit(0);
|
|
5556
6218
|
}
|
|
@@ -5558,21 +6220,21 @@ program.name("ccman").description("Codex/Claude Code API \u670D\u52A1\u5546\u914
|
|
|
5558
6220
|
});
|
|
5559
6221
|
program.on("command:*", (operands) => {
|
|
5560
6222
|
const unknownCommand = operands[0];
|
|
5561
|
-
console.error(
|
|
6223
|
+
console.error(chalk47.red(`
|
|
5562
6224
|
\u274C \u672A\u77E5\u547D\u4EE4: ${unknownCommand}
|
|
5563
6225
|
`));
|
|
5564
|
-
const availableCommands = ["cx", "cc", "gm", "mcp", "sync", "export", "import"];
|
|
6226
|
+
const availableCommands = ["cx", "cc", "gm", "oc", "mcp", "sync", "export", "import"];
|
|
5565
6227
|
const suggestions = availableCommands.filter(
|
|
5566
6228
|
(cmd) => cmd.includes(unknownCommand) || unknownCommand.includes(cmd)
|
|
5567
6229
|
);
|
|
5568
6230
|
if (suggestions.length > 0) {
|
|
5569
|
-
console.log(
|
|
6231
|
+
console.log(chalk47.yellow("\u{1F4A1} \u4F60\u662F\u4E0D\u662F\u60F3\u8F93\u5165:"));
|
|
5570
6232
|
suggestions.forEach((cmd) => {
|
|
5571
|
-
console.log(
|
|
6233
|
+
console.log(chalk47.cyan(` ccman ${cmd}`));
|
|
5572
6234
|
});
|
|
5573
6235
|
console.log();
|
|
5574
6236
|
}
|
|
5575
|
-
console.log(
|
|
6237
|
+
console.log(chalk47.gray("\u67E5\u770B\u6240\u6709\u53EF\u7528\u547D\u4EE4: ") + chalk47.cyan("ccman --help"));
|
|
5576
6238
|
console.log();
|
|
5577
6239
|
process.exit(1);
|
|
5578
6240
|
});
|
|
@@ -5594,6 +6256,12 @@ gm.action(async () => {
|
|
|
5594
6256
|
printLogo();
|
|
5595
6257
|
await startGeminiMenu();
|
|
5596
6258
|
});
|
|
6259
|
+
var oc = program.command("oc").description("\u7BA1\u7406 OpenCode \u670D\u52A1\u5546");
|
|
6260
|
+
createOpenCodeCommands(oc);
|
|
6261
|
+
oc.action(async () => {
|
|
6262
|
+
printLogo();
|
|
6263
|
+
await startOpenCodeMenu();
|
|
6264
|
+
});
|
|
5597
6265
|
var mcp = program.command("mcp").description("\u7BA1\u7406 MCP \u670D\u52A1\u5668");
|
|
5598
6266
|
createMCPCommands(mcp);
|
|
5599
6267
|
mcp.action(() => {
|