ccman 3.2.3 → 3.3.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/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.2.3",
18
+ version: "3.3.1",
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
- var isDev, isTest, rootDir, ccmanDir, codexDir, claudeDir, geminiDir;
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(os.tmpdir(), `ccman-test-${process.pid}`);
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: "88Code",
580
- baseUrl: "https://www.88code.org/openai/v1",
581
- description: "88Code API \u670D\u52A1"
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: "PackyAPI",
715
- baseUrl: "https://www.packyapi.com",
716
- description: "PackyAPI Gemini \u517C\u5BB9\u670D\u52A1"
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: "LiteLLM Proxy",
720
- baseUrl: "http://localhost:4000",
721
- description: "\u4F7F\u7528\u672C\u5730 LiteLLM Proxy \u4F5C\u4E3A Gemini \u517C\u5BB9\u4EE3\u7406"
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 chalk40 from "chalk";
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
- const provider = manager.add({ name, desc, baseUrl, apiKey });
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 currentCommand4 = provider.baseUrl;
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: currentCommand4
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 !== currentCommand4) {
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 chalk38 from "chalk";
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(chalk38.bold("\n\u{1F4E6} \u5BFC\u51FA\u914D\u7F6E\n"));
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(chalk38.red(`\u274C ${validation.message}
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(` ${chalk38.cyan("codex.json")} - Codex \u914D\u7F6E`);
5436
- console.log(` ${chalk38.cyan("claude.json")} - Claude \u914D\u7F6E`);
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: ${chalk38.cyan(resolvedPath)}`);
6099
+ console.log(`\u76EE\u6807\u76EE\u5F55: ${chalk45.cyan(resolvedPath)}`);
5439
6100
  console.log();
5440
- console.log(chalk38.yellow("\u26A0\uFE0F \u5BFC\u51FA\u6587\u4EF6\u5305\u542B API Key\uFF0C\u8BF7\u59A5\u5584\u4FDD\u7BA1"));
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(chalk38.green("\u2705 \u5BFC\u51FA\u6210\u529F"));
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(` ${chalk38.cyan("\u2713")} ${file}`);
6108
+ console.log(` ${chalk45.cyan("\u2713")} ${file}`);
5448
6109
  }
5449
6110
  console.log();
5450
- console.log(chalk38.blue(`\u{1F4A1} \u5BFC\u5165\u547D\u4EE4: ccman import ${resolvedPath}
6111
+ console.log(chalk45.blue(`\u{1F4A1} \u5BFC\u5165\u547D\u4EE4: ccman import ${resolvedPath}
5451
6112
  `));
5452
6113
  } catch (error) {
5453
- console.error(chalk38.red(`
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 chalk39 from "chalk";
5464
- import inquirer27 from "inquirer";
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(chalk39.bold("\n\u{1F4E5} \u5BFC\u5165\u914D\u7F6E\n"));
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(chalk39.red(`\u274C ${validation.message}
6134
+ console.log(chalk46.red(`\u274C ${validation.message}
5474
6135
  `));
5475
6136
  process.exit(1);
5476
6137
  }
5477
- console.log(chalk39.yellow("\u26A0\uFE0F \u8B66\u544A\uFF1A\u5BFC\u5165\u5C06\u8986\u76D6\u5F53\u524D\u914D\u7F6E\n"));
5478
- console.log(`\u6E90\u76EE\u5F55: ${chalk39.cyan(resolvedPath)}`);
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(` ${chalk39.cyan("\u2713")} ${file}`);
6143
+ console.log(` ${chalk46.cyan("\u2713")} ${file}`);
5483
6144
  }
5484
6145
  console.log();
5485
- console.log(chalk39.gray("\u5F53\u524D\u914D\u7F6E\u5C06\u88AB\u8986\u76D6\uFF08\u81EA\u52A8\u5907\u4EFD\uFF09"));
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 inquirer27.prompt([
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(chalk39.gray("\n\u274C \u5DF2\u53D6\u6D88\n"));
6157
+ console.log(chalk46.gray("\n\u274C \u5DF2\u53D6\u6D88\n"));
5497
6158
  return;
5498
6159
  }
5499
6160
  console.log();
5500
- 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"));
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 inquirer27.prompt([
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(chalk39.gray("\n\u274C \u5DF2\u53D6\u6D88\n"));
6172
+ console.log(chalk46.gray("\n\u274C \u5DF2\u53D6\u6D88\n"));
5512
6173
  return;
5513
6174
  }
5514
6175
  console.log();
5515
- console.log(chalk39.gray("\u{1F4BE} \u5907\u4EFD\u5F53\u524D\u914D\u7F6E..."));
5516
- console.log(chalk39.gray("\u{1F4E5} \u5BFC\u5165\u65B0\u914D\u7F6E..."));
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(chalk39.green("\u2705 \u5BFC\u5165\u6210\u529F"));
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(` ${chalk39.gray(backupPath)}`);
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(` ${chalk39.cyan("\u2713")} ${file}`);
6191
+ console.log(` ${chalk46.cyan("\u2713")} ${file}`);
5531
6192
  }
5532
6193
  console.log();
5533
- console.log(chalk39.blue("\u{1F4A1} \u8BF7\u4F7F\u7528 'ccman cx use' \u6216 'ccman cc use' \u5207\u6362\u670D\u52A1\u5546\n"));
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(chalk39.red(`
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(chalk40.gray("\n[\u5F00\u53D1\u6A21\u5F0F] \u914D\u7F6E\u76EE\u5F55:"));
5547
- console.log(chalk40.gray(` ccman: ${getCcmanDir()}`));
5548
- console.log(chalk40.gray(` codex: ${getCodexDir()}`));
5549
- console.log(chalk40.gray(` claude: ${getClaudeDir()}`));
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(chalk40.red(`
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(chalk40.yellow("\u{1F4A1} \u4F60\u662F\u4E0D\u662F\u60F3\u8F93\u5165:"));
6231
+ console.log(chalk47.yellow("\u{1F4A1} \u4F60\u662F\u4E0D\u662F\u60F3\u8F93\u5165:"));
5570
6232
  suggestions.forEach((cmd) => {
5571
- console.log(chalk40.cyan(` ccman ${cmd}`));
6233
+ console.log(chalk47.cyan(` ccman ${cmd}`));
5572
6234
  });
5573
6235
  console.log();
5574
6236
  }
5575
- console.log(chalk40.gray("\u67E5\u770B\u6240\u6709\u53EF\u7528\u547D\u4EE4: ") + chalk40.cyan("ccman --help"));
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(() => {