ccman 3.3.13 → 3.3.14-beta.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,9 +15,9 @@ var init_package = __esm({
15
15
  "../core/package.json"() {
16
16
  package_default = {
17
17
  name: "@ccman/core",
18
- version: "3.3.13",
18
+ version: "3.3.14-beta.1",
19
19
  type: "module",
20
- description: "Core business logic for ccman - Manage Codex, Claude Code, Gemini CLI, and MCP configurations",
20
+ description: "Core business logic for ccman - Manage Codex, Claude Code, Gemini CLI, OpenCode, OpenClaw, and MCP configurations",
21
21
  main: "./dist/index.js",
22
22
  types: "./dist/index.d.ts",
23
23
  files: [
@@ -36,6 +36,8 @@ var init_package = __esm({
36
36
  "claude-code",
37
37
  "gemini",
38
38
  "gemini-cli",
39
+ "opencode",
40
+ "openclaw",
39
41
  "mcp",
40
42
  "model-context-protocol",
41
43
  "ai",
@@ -80,12 +82,14 @@ var init_dist = __esm({
80
82
  CLAUDE: "claude",
81
83
  MCP: "mcp",
82
84
  GEMINI: "gemini",
83
- OPENCODE: "opencode"
85
+ OPENCODE: "opencode",
86
+ OPENCLAW: "openclaw"
84
87
  };
85
88
  MAIN_TOOL_TYPES = {
86
89
  CODEX: TOOL_TYPES.CODEX,
87
90
  CLAUDE: TOOL_TYPES.CLAUDE,
88
- GEMINI: TOOL_TYPES.GEMINI
91
+ GEMINI: TOOL_TYPES.GEMINI,
92
+ OPENCLAW: TOOL_TYPES.OPENCLAW
89
93
  };
90
94
  TOOL_CONFIG = {
91
95
  [TOOL_TYPES.CODEX]: {
@@ -127,6 +131,14 @@ var init_dist = __esm({
127
131
  bgColorClass: "bg-amber-50",
128
132
  hoverBgColorClass: "hover:bg-amber-100",
129
133
  description: "OpenCode \u914D\u7F6E"
134
+ },
135
+ [TOOL_TYPES.OPENCLAW]: {
136
+ displayName: "OpenClaw",
137
+ color: "teal",
138
+ textColorClass: "text-teal-600",
139
+ bgColorClass: "bg-teal-50",
140
+ hoverBgColorClass: "hover:bg-teal-100",
141
+ description: "OpenClaw \u914D\u7F6E"
130
142
  }
131
143
  };
132
144
  }
@@ -159,6 +171,9 @@ function getGeminiDir() {
159
171
  function getOpenCodeDir() {
160
172
  return opencodeDir;
161
173
  }
174
+ function getOpenClawDir() {
175
+ return openclawDir;
176
+ }
162
177
  function getConfigPath() {
163
178
  return path.join(ccmanDir, "config.json");
164
179
  }
@@ -183,7 +198,13 @@ function getGeminiEnvPath() {
183
198
  function getOpenCodeConfigPath() {
184
199
  return path.join(opencodeDir, "opencode.json");
185
200
  }
186
- var isDev, isTest, rootDir, ccmanDir, codexDir, claudeDir, geminiDir, opencodeDir;
201
+ function getOpenClawConfigPath() {
202
+ return path.join(openclawDir, "openclaw.json");
203
+ }
204
+ function getOpenClawModelsPath() {
205
+ return path.join(openclawDir, "agents", "main", "agent", "models.json");
206
+ }
207
+ var isDev, isTest, rootDir, ccmanDir, codexDir, claudeDir, geminiDir, opencodeDir, openclawDir;
187
208
  var init_paths = __esm({
188
209
  "../core/dist/paths.js"() {
189
210
  "use strict";
@@ -201,6 +222,7 @@ var init_paths = __esm({
201
222
  claudeDir = path.join(rootDir, ".claude");
202
223
  geminiDir = path.join(rootDir, ".gemini");
203
224
  opencodeDir = path.join(rootDir, ".config", "opencode");
225
+ openclawDir = path.join(rootDir, ".openclaw");
204
226
  }
205
227
  });
206
228
 
@@ -785,6 +807,21 @@ var init_opencode = __esm({
785
807
  }
786
808
  });
787
809
 
810
+ // ../core/dist/presets/openclaw.js
811
+ var OPENCLAW_PRESETS;
812
+ var init_openclaw = __esm({
813
+ "../core/dist/presets/openclaw.js"() {
814
+ "use strict";
815
+ OPENCLAW_PRESETS = [
816
+ {
817
+ name: "GMN",
818
+ baseUrl: "https://gmn.chuangzuoli.com/v1",
819
+ description: "GMN \u670D\u52A1 (OpenClaw \u517C\u5BB9)"
820
+ }
821
+ ];
822
+ }
823
+ });
824
+
788
825
  // ../core/dist/writers/gemini.js
789
826
  import * as fs5 from "fs";
790
827
  import * as path6 from "path";
@@ -1134,6 +1171,170 @@ var init_opencode2 = __esm({
1134
1171
  }
1135
1172
  });
1136
1173
 
1174
+ // ../core/dist/writers/openclaw.js
1175
+ import * as fs7 from "fs";
1176
+ import * as path8 from "path";
1177
+ import { fileURLToPath as fileURLToPath5 } from "url";
1178
+ function resolveTemplatePath5(relativePath) {
1179
+ const candidates = [
1180
+ // @ccman/core runtime (dist/writers -> templates)
1181
+ path8.resolve(__dirname5, "../../templates", relativePath),
1182
+ // Bundled CLI runtime (dist -> dist/templates)
1183
+ path8.resolve(__dirname5, "templates", relativePath),
1184
+ // Fallback (some bundlers/layouts)
1185
+ path8.resolve(__dirname5, "../templates", relativePath)
1186
+ ];
1187
+ for (const candidate of candidates) {
1188
+ if (fs7.existsSync(candidate))
1189
+ return candidate;
1190
+ }
1191
+ return null;
1192
+ }
1193
+ function loadTemplate(relativePath, fallback) {
1194
+ try {
1195
+ const templatePath = resolveTemplatePath5(relativePath);
1196
+ if (templatePath) {
1197
+ const content = fs7.readFileSync(templatePath, "utf-8");
1198
+ const parsed = JSON.parse(content);
1199
+ if (parsed && typeof parsed === "object") {
1200
+ return parsed;
1201
+ }
1202
+ }
1203
+ } catch {
1204
+ }
1205
+ return fallback;
1206
+ }
1207
+ function resolveProviderName(provider) {
1208
+ const name = provider.name?.trim();
1209
+ if (name)
1210
+ return name;
1211
+ return DEFAULT_PROVIDER_NAME;
1212
+ }
1213
+ function writeOpenClawConfig(provider) {
1214
+ const configPath = getOpenClawConfigPath();
1215
+ const modelsPath = getOpenClawModelsPath();
1216
+ const homeDir = path8.dirname(getOpenClawDir());
1217
+ const providerName = resolveProviderName(provider);
1218
+ ensureDir(getOpenClawDir());
1219
+ ensureDir(path8.dirname(modelsPath));
1220
+ const rawConfigTemplate = loadTemplate("openclaw/openclaw.base.template.json", OPENCLAW_CONFIG_TEMPLATE);
1221
+ const rawModelsTemplate = loadTemplate("openclaw/models.base.template.json", OPENCLAW_MODELS_TEMPLATE);
1222
+ const variables = {
1223
+ providerName,
1224
+ baseUrl: provider.baseUrl || "",
1225
+ apiKey: provider.apiKey || ""
1226
+ };
1227
+ const nextOpenClawConfig = replaceVariables(rawConfigTemplate, variables);
1228
+ const nextModelsConfig = replaceVariables(rawModelsTemplate, variables);
1229
+ const currentAgents = nextOpenClawConfig.agents || {};
1230
+ const defaults = currentAgents.defaults || {};
1231
+ nextOpenClawConfig.agents = {
1232
+ ...currentAgents,
1233
+ defaults: {
1234
+ ...defaults,
1235
+ workspace: homeDir
1236
+ }
1237
+ };
1238
+ writeJSON(configPath, nextOpenClawConfig);
1239
+ writeJSON(modelsPath, nextModelsConfig);
1240
+ }
1241
+ var DEFAULT_PROVIDER_NAME, __filename5, __dirname5, OPENCLAW_CONFIG_TEMPLATE, OPENCLAW_MODELS_TEMPLATE;
1242
+ var init_openclaw2 = __esm({
1243
+ "../core/dist/writers/openclaw.js"() {
1244
+ "use strict";
1245
+ init_paths();
1246
+ init_file();
1247
+ init_template();
1248
+ DEFAULT_PROVIDER_NAME = "gmn";
1249
+ __filename5 = fileURLToPath5(import.meta.url);
1250
+ __dirname5 = path8.dirname(__filename5);
1251
+ OPENCLAW_CONFIG_TEMPLATE = {
1252
+ models: {
1253
+ mode: "merge",
1254
+ providers: {
1255
+ "{{providerName}}": {
1256
+ baseUrl: "{{baseUrl}}",
1257
+ apiKey: "{{apiKey}}",
1258
+ api: "openai-responses",
1259
+ headers: {
1260
+ "User-Agent": "curl/8.0",
1261
+ "OpenAI-Beta": "responses=v1"
1262
+ },
1263
+ authHeader: true,
1264
+ models: [
1265
+ {
1266
+ id: "gpt-5.3-codex",
1267
+ name: "gpt-5.3-codex",
1268
+ api: "openai-responses",
1269
+ reasoning: false,
1270
+ input: ["text"],
1271
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
1272
+ contextWindow: 2e5,
1273
+ maxTokens: 8192
1274
+ },
1275
+ {
1276
+ id: "gpt-5.2-codex",
1277
+ name: "gpt-5.2-codex",
1278
+ api: "openai-responses",
1279
+ reasoning: false,
1280
+ input: ["text"],
1281
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
1282
+ contextWindow: 2e5,
1283
+ maxTokens: 8192
1284
+ }
1285
+ ]
1286
+ }
1287
+ }
1288
+ },
1289
+ agents: {
1290
+ defaults: {
1291
+ workspace: "",
1292
+ model: {
1293
+ primary: "{{providerName}}/gpt-5.3-codex"
1294
+ },
1295
+ thinkingDefault: "xhigh"
1296
+ }
1297
+ }
1298
+ };
1299
+ OPENCLAW_MODELS_TEMPLATE = {
1300
+ providers: {
1301
+ "{{providerName}}": {
1302
+ baseUrl: "{{baseUrl}}",
1303
+ apiKey: "{{apiKey}}",
1304
+ api: "openai-responses",
1305
+ authHeader: true,
1306
+ headers: {
1307
+ "User-Agent": "curl/8.0",
1308
+ "OpenAI-Beta": "responses=v1"
1309
+ },
1310
+ models: [
1311
+ {
1312
+ id: "gpt-5.3-codex",
1313
+ name: "gpt-5.3-codex",
1314
+ api: "openai-responses",
1315
+ reasoning: false,
1316
+ input: ["text"],
1317
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
1318
+ contextWindow: 2e5,
1319
+ maxTokens: 8192
1320
+ },
1321
+ {
1322
+ id: "gpt-5.2-codex",
1323
+ name: "gpt-5.2-codex",
1324
+ api: "openai-responses",
1325
+ reasoning: false,
1326
+ input: ["text"],
1327
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
1328
+ contextWindow: 2e5,
1329
+ maxTokens: 8192
1330
+ }
1331
+ ]
1332
+ }
1333
+ }
1334
+ };
1335
+ }
1336
+ });
1337
+
1137
1338
  // ../core/dist/tool-manager.types.js
1138
1339
  var ProviderNotFoundError, ProviderNameConflictError, PresetNameConflictError;
1139
1340
  var init_tool_manager_types = __esm({
@@ -1161,7 +1362,7 @@ var init_tool_manager_types = __esm({
1161
1362
  });
1162
1363
 
1163
1364
  // ../core/dist/tool-manager.js
1164
- import * as path8 from "path";
1365
+ import * as path9 from "path";
1165
1366
  function createToolManager(tool) {
1166
1367
  const toolConfig = TOOL_CONFIGS[tool];
1167
1368
  const configPath = toolConfig.configPath;
@@ -1475,6 +1676,9 @@ function createGeminiManager() {
1475
1676
  function createOpenCodeManager() {
1476
1677
  return createToolManager("opencode");
1477
1678
  }
1679
+ function createOpenClawManager() {
1680
+ return createToolManager("openclaw");
1681
+ }
1478
1682
  var TOOL_CONFIGS;
1479
1683
  var init_tool_manager = __esm({
1480
1684
  "../core/dist/tool-manager.js"() {
@@ -1489,22 +1693,24 @@ var init_tool_manager = __esm({
1489
1693
  init_mcp2();
1490
1694
  init_gemini();
1491
1695
  init_opencode();
1696
+ init_openclaw();
1492
1697
  init_gemini2();
1493
1698
  init_opencode2();
1699
+ init_openclaw2();
1494
1700
  init_tool_manager_types();
1495
1701
  TOOL_CONFIGS = {
1496
1702
  codex: {
1497
- configPath: path8.join(getCcmanDir(), "codex.json"),
1703
+ configPath: path9.join(getCcmanDir(), "codex.json"),
1498
1704
  builtinPresets: CODEX_PRESETS,
1499
1705
  writer: writeCodexConfig
1500
1706
  },
1501
1707
  claude: {
1502
- configPath: path8.join(getCcmanDir(), "claude.json"),
1708
+ configPath: path9.join(getCcmanDir(), "claude.json"),
1503
1709
  builtinPresets: CC_PRESETS,
1504
1710
  writer: writeClaudeConfig
1505
1711
  },
1506
1712
  mcp: {
1507
- configPath: path8.join(getCcmanDir(), "mcp.json"),
1713
+ configPath: path9.join(getCcmanDir(), "mcp.json"),
1508
1714
  builtinPresets: MCP_PRESETS,
1509
1715
  writer: writeMCPConfig,
1510
1716
  autoSync: true,
@@ -1534,14 +1740,19 @@ var init_tool_manager = __esm({
1534
1740
  }
1535
1741
  },
1536
1742
  gemini: {
1537
- configPath: path8.join(getCcmanDir(), "gemini.json"),
1743
+ configPath: path9.join(getCcmanDir(), "gemini.json"),
1538
1744
  builtinPresets: GEMINI_PRESETS,
1539
1745
  writer: writeGeminiConfig
1540
1746
  },
1541
1747
  opencode: {
1542
- configPath: path8.join(getCcmanDir(), "opencode.json"),
1748
+ configPath: path9.join(getCcmanDir(), "opencode.json"),
1543
1749
  builtinPresets: OPENCODE_PRESETS,
1544
1750
  writer: writeOpenCodeConfig
1751
+ },
1752
+ openclaw: {
1753
+ configPath: path9.join(getCcmanDir(), "openclaw.json"),
1754
+ builtinPresets: OPENCLAW_PRESETS,
1755
+ writer: writeOpenClawConfig
1545
1756
  }
1546
1757
  };
1547
1758
  }
@@ -1556,20 +1767,20 @@ var init_migrate = __esm({
1556
1767
  });
1557
1768
 
1558
1769
  // ../core/dist/config.js
1559
- import * as fs7 from "fs";
1770
+ import * as fs8 from "fs";
1560
1771
  function ensureConfigDir() {
1561
1772
  const dir = getCcmanDir();
1562
- if (!fs7.existsSync(dir)) {
1563
- fs7.mkdirSync(dir, { recursive: true, mode: 448 });
1773
+ if (!fs8.existsSync(dir)) {
1774
+ fs8.mkdirSync(dir, { recursive: true, mode: 448 });
1564
1775
  }
1565
1776
  }
1566
1777
  function loadConfig() {
1567
1778
  const configPath = getConfigPath();
1568
- if (!fs7.existsSync(configPath)) {
1779
+ if (!fs8.existsSync(configPath)) {
1569
1780
  return {};
1570
1781
  }
1571
1782
  try {
1572
- const content = fs7.readFileSync(configPath, "utf-8");
1783
+ const content = fs8.readFileSync(configPath, "utf-8");
1573
1784
  return JSON.parse(content);
1574
1785
  } catch (error) {
1575
1786
  throw new Error(`Failed to load config: ${error.message}`);
@@ -1580,10 +1791,10 @@ function saveConfig(config) {
1580
1791
  const configPath = getConfigPath();
1581
1792
  try {
1582
1793
  const tempPath = `${configPath}.tmp`;
1583
- fs7.writeFileSync(tempPath, JSON.stringify(config, null, 2), {
1794
+ fs8.writeFileSync(tempPath, JSON.stringify(config, null, 2), {
1584
1795
  mode: 384
1585
1796
  });
1586
- fs7.renameSync(tempPath, configPath);
1797
+ fs8.renameSync(tempPath, configPath);
1587
1798
  } catch (error) {
1588
1799
  throw new Error(`Failed to save config: ${error.message}`);
1589
1800
  }
@@ -1915,24 +2126,24 @@ var init_merge_advanced = __esm({
1915
2126
  });
1916
2127
 
1917
2128
  // ../core/dist/sync/merge.js
1918
- import fs8 from "fs";
1919
- import path9 from "path";
2129
+ import fs9 from "fs";
2130
+ import path10 from "path";
1920
2131
  function backupConfig(configPath, keepCount = 3) {
1921
- if (!fs8.existsSync(configPath)) {
2132
+ if (!fs9.existsSync(configPath)) {
1922
2133
  throw new Error(`\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728: ${configPath}`);
1923
2134
  }
1924
2135
  const timestamp = Date.now();
1925
2136
  const backupPath = `${configPath}.backup.${timestamp}`;
1926
- fs8.copyFileSync(configPath, backupPath);
2137
+ fs9.copyFileSync(configPath, backupPath);
1927
2138
  cleanupOldBackups(configPath, keepCount);
1928
2139
  return backupPath;
1929
2140
  }
1930
2141
  function cleanupOldBackups(configPath, keepCount) {
1931
- const dir = path9.dirname(configPath);
1932
- const basename = path9.basename(configPath);
2142
+ const dir = path10.dirname(configPath);
2143
+ const basename = path10.basename(configPath);
1933
2144
  const backupPrefix = `${basename}.backup.`;
1934
2145
  try {
1935
- const files = fs8.readdirSync(dir);
2146
+ const files = fs9.readdirSync(dir);
1936
2147
  const backups = files.filter((f) => f.startsWith(backupPrefix)).map((f) => {
1937
2148
  const timestampStr = f.substring(backupPrefix.length);
1938
2149
  const timestamp = parseInt(timestampStr, 10);
@@ -1941,14 +2152,14 @@ function cleanupOldBackups(configPath, keepCount) {
1941
2152
  }
1942
2153
  return {
1943
2154
  name: f,
1944
- path: path9.join(dir, f),
2155
+ path: path10.join(dir, f),
1945
2156
  timestamp
1946
2157
  };
1947
2158
  }).filter((backup) => backup !== null).sort((a, b) => b.timestamp - a.timestamp);
1948
2159
  const toDelete = backups.slice(keepCount);
1949
2160
  for (const backup of toDelete) {
1950
2161
  try {
1951
- fs8.unlinkSync(backup.path);
2162
+ fs9.unlinkSync(backup.path);
1952
2163
  } catch (error) {
1953
2164
  console.warn(`\u65E0\u6CD5\u5220\u9664\u65E7\u5907\u4EFD\u6587\u4EF6 ${backup.name}: ${error.message}`);
1954
2165
  }
@@ -1964,15 +2175,31 @@ var init_merge = __esm({
1964
2175
  });
1965
2176
 
1966
2177
  // ../core/dist/sync/sync-v2.js
1967
- import fs9 from "fs";
1968
- import path10 from "path";
2178
+ import fs10 from "fs";
2179
+ import path11 from "path";
2180
+ function createEmptyToolConfig() {
2181
+ return {
2182
+ providers: [],
2183
+ presets: []
2184
+ };
2185
+ }
2186
+ function readLocalConfigOrEmpty(configPath) {
2187
+ if (!fileExists(configPath)) {
2188
+ return createEmptyToolConfig();
2189
+ }
2190
+ return readJSON(configPath);
2191
+ }
1969
2192
  async function uploadToCloud(config, password) {
1970
2193
  const ccmanDir2 = getCcmanDir();
1971
2194
  const toolKeys = Object.keys(TOOL_SYNC_CONFIG);
2195
+ let uploadedCount = 0;
1972
2196
  for (const tool of toolKeys) {
1973
2197
  const { remotePath, configFilename } = TOOL_SYNC_CONFIG[tool];
1974
- const configPath = path10.join(ccmanDir2, configFilename);
1975
- const localConfig = readJSON(configPath);
2198
+ const configPath = path11.join(ccmanDir2, configFilename);
2199
+ if (!fileExists(configPath)) {
2200
+ continue;
2201
+ }
2202
+ const localConfig = readLocalConfigOrEmpty(configPath);
1976
2203
  const encryptedProviders = encryptProviders(localConfig.providers, password);
1977
2204
  const encryptedConfig = {
1978
2205
  ...localConfig,
@@ -1982,6 +2209,10 @@ async function uploadToCloud(config, password) {
1982
2209
  };
1983
2210
  const jsonContent = JSON.stringify(encryptedConfig, null, 2);
1984
2211
  await uploadToWebDAV(config, remotePath, jsonContent);
2212
+ uploadedCount += 1;
2213
+ }
2214
+ if (uploadedCount === 0) {
2215
+ throw new Error("\u672C\u5730\u672A\u627E\u5230\u53EF\u4E0A\u4F20\u7684\u914D\u7F6E\u6587\u4EF6");
1985
2216
  }
1986
2217
  updateLastSyncTime();
1987
2218
  console.log("\u2705 \u914D\u7F6E\u5DF2\u4E0A\u4F20\u5230\u4E91\u7AEF");
@@ -2017,8 +2248,8 @@ async function downloadFromCloud(config, password) {
2017
2248
  try {
2018
2249
  for (const tool of toolKeys) {
2019
2250
  const { configFilename } = TOOL_SYNC_CONFIG[tool];
2020
- const configPath = path10.join(ccmanDir2, configFilename);
2021
- if (fs9.existsSync(configPath)) {
2251
+ const configPath = path11.join(ccmanDir2, configFilename);
2252
+ if (fs10.existsSync(configPath)) {
2022
2253
  backupPaths.push(backupConfig(configPath));
2023
2254
  }
2024
2255
  }
@@ -2030,7 +2261,7 @@ async function downloadFromCloud(config, password) {
2030
2261
  if (!remoteConfig || !decryptedProviders)
2031
2262
  continue;
2032
2263
  const { configFilename } = TOOL_SYNC_CONFIG[tool];
2033
- const configPath = path10.join(ccmanDir2, configFilename);
2264
+ const configPath = path11.join(ccmanDir2, configFilename);
2034
2265
  const newConfig = {
2035
2266
  ...remoteConfig,
2036
2267
  // 使用云端配置的所有字段
@@ -2046,8 +2277,8 @@ async function downloadFromCloud(config, password) {
2046
2277
  } catch (error) {
2047
2278
  for (const backupPath of backupPaths) {
2048
2279
  const originalPath = backupPath.replace(/\.backup\.\d+$/, "");
2049
- if (fs9.existsSync(backupPath)) {
2050
- fs9.copyFileSync(backupPath, originalPath);
2280
+ if (fs10.existsSync(backupPath)) {
2281
+ fs10.copyFileSync(backupPath, originalPath);
2051
2282
  }
2052
2283
  }
2053
2284
  throw new Error(`\u8986\u76D6\u914D\u7F6E\u5931\u8D25\uFF0C\u5DF2\u6062\u590D\u5907\u4EFD: ${error.message}`);
@@ -2072,8 +2303,8 @@ async function mergeSync(config, password) {
2072
2303
  for (let i = 0; i < toolKeys.length; i++) {
2073
2304
  const tool = toolKeys[i];
2074
2305
  const { remotePath, configFilename } = TOOL_SYNC_CONFIG[tool];
2075
- const configPath = path10.join(ccmanDir2, configFilename);
2076
- const localConfig = readJSON(configPath);
2306
+ const configPath = path11.join(ccmanDir2, configFilename);
2307
+ const localConfig = readLocalConfigOrEmpty(configPath);
2077
2308
  let remoteProviders = [];
2078
2309
  if (existsChecks[i]) {
2079
2310
  try {
@@ -2104,8 +2335,8 @@ async function mergeSync(config, password) {
2104
2335
  try {
2105
2336
  for (const tool of toolKeys) {
2106
2337
  const { configFilename } = TOOL_SYNC_CONFIG[tool];
2107
- const configPath = path10.join(ccmanDir2, configFilename);
2108
- if (fs9.existsSync(configPath)) {
2338
+ const configPath = path11.join(ccmanDir2, configFilename);
2339
+ if (fs10.existsSync(configPath)) {
2109
2340
  backupPaths.push(backupConfig(configPath));
2110
2341
  }
2111
2342
  }
@@ -2116,7 +2347,7 @@ async function mergeSync(config, password) {
2116
2347
  for (let i = 0; i < mergeDataList.length; i++) {
2117
2348
  const { tool, localConfig, mergeResult } = mergeDataList[i];
2118
2349
  const { remotePath, configFilename } = TOOL_SYNC_CONFIG[tool];
2119
- const configPath = path10.join(ccmanDir2, configFilename);
2350
+ const configPath = path11.join(ccmanDir2, configFilename);
2120
2351
  let remoteConfig = null;
2121
2352
  if (existsChecks[i]) {
2122
2353
  const jsonContent2 = await downloadFromWebDAV(config, remotePath);
@@ -2131,6 +2362,10 @@ async function mergeSync(config, password) {
2131
2362
  presets: mergedPresets
2132
2363
  // 替换为合并后的 presets
2133
2364
  };
2365
+ const shouldPersist = fileExists(configPath) || existsChecks[i] || mergeResult.merged.length > 0 || mergedPresets && mergedPresets.length > 0;
2366
+ if (!shouldPersist) {
2367
+ continue;
2368
+ }
2134
2369
  writeJSON(configPath, mergedConfig);
2135
2370
  applyCurrentProvider(tool, mergedConfig);
2136
2371
  const encryptedProviders = encryptProviders(mergeResult.merged, password);
@@ -2152,8 +2387,8 @@ async function mergeSync(config, password) {
2152
2387
  } catch (error) {
2153
2388
  for (const backupPath of backupPaths) {
2154
2389
  const originalPath = backupPath.replace(/\.backup\.\d+$/, "");
2155
- if (fs9.existsSync(backupPath)) {
2156
- fs9.copyFileSync(backupPath, originalPath);
2390
+ if (fs10.existsSync(backupPath)) {
2391
+ fs10.copyFileSync(backupPath, originalPath);
2157
2392
  }
2158
2393
  }
2159
2394
  throw new Error(`\u5408\u5E76\u914D\u7F6E\u5931\u8D25\uFF0C\u5DF2\u6062\u590D\u5907\u4EFD: ${error.message}`);
@@ -2184,6 +2419,7 @@ var init_sync_v2 = __esm({
2184
2419
  init_codex();
2185
2420
  init_claude();
2186
2421
  init_gemini2();
2422
+ init_openclaw2();
2187
2423
  init_constants();
2188
2424
  TOOL_SYNC_CONFIG = {
2189
2425
  [MAIN_TOOL_TYPES.CODEX]: {
@@ -2200,33 +2436,35 @@ var init_sync_v2 = __esm({
2200
2436
  remotePath: ".ccman/gemini.json",
2201
2437
  configFilename: "gemini.json",
2202
2438
  writerFunc: writeGeminiConfig
2439
+ },
2440
+ [MAIN_TOOL_TYPES.OPENCLAW]: {
2441
+ remotePath: ".ccman/openclaw.json",
2442
+ configFilename: "openclaw.json",
2443
+ writerFunc: writeOpenClawConfig
2203
2444
  }
2204
2445
  };
2205
2446
  }
2206
2447
  });
2207
2448
 
2208
2449
  // ../core/dist/export.js
2209
- import * as fs10 from "fs";
2210
- import * as path11 from "path";
2450
+ import * as fs11 from "fs";
2451
+ import * as path12 from "path";
2211
2452
  function validateExport() {
2212
2453
  const ccmanDir2 = getCcmanDir();
2213
- const codexPath = path11.join(ccmanDir2, CODEX_CONFIG_FILE);
2214
- const claudePath = path11.join(ccmanDir2, CLAUDE_CONFIG_FILE);
2215
- const missingFiles = [];
2216
- if (!fileExists(codexPath)) {
2217
- missingFiles.push(CODEX_CONFIG_FILE);
2218
- }
2219
- if (!fileExists(claudePath)) {
2220
- missingFiles.push(CLAUDE_CONFIG_FILE);
2221
- }
2222
- if (missingFiles.length > 0) {
2454
+ const foundFiles = SUPPORTED_CONFIG_FILES.filter((filename) => fileExists(path12.join(ccmanDir2, filename)));
2455
+ if (foundFiles.length === 0) {
2223
2456
  return {
2224
2457
  valid: false,
2225
- message: `\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728: ${missingFiles.join(", ")}`,
2226
- missingFiles
2458
+ message: `\u672A\u627E\u5230\u53EF\u5BFC\u51FA\u7684\u914D\u7F6E\u6587\u4EF6 (${SUPPORTED_CONFIG_FILES.join(" / ")})`,
2459
+ missingFiles: [...SUPPORTED_CONFIG_FILES],
2460
+ foundFiles: []
2227
2461
  };
2228
2462
  }
2229
- return { valid: true };
2463
+ return {
2464
+ valid: true,
2465
+ foundFiles,
2466
+ missingFiles: SUPPORTED_CONFIG_FILES.filter((file) => !foundFiles.includes(file))
2467
+ };
2230
2468
  }
2231
2469
  function validateImportDir(sourceDir) {
2232
2470
  if (!fileExists(sourceDir)) {
@@ -2236,7 +2474,7 @@ function validateImportDir(sourceDir) {
2236
2474
  foundFiles: []
2237
2475
  };
2238
2476
  }
2239
- const stats = fs10.statSync(sourceDir);
2477
+ const stats = fs11.statSync(sourceDir);
2240
2478
  if (!stats.isDirectory()) {
2241
2479
  return {
2242
2480
  valid: false,
@@ -2244,19 +2482,11 @@ function validateImportDir(sourceDir) {
2244
2482
  foundFiles: []
2245
2483
  };
2246
2484
  }
2247
- const codexPath = path11.join(sourceDir, CODEX_CONFIG_FILE);
2248
- const claudePath = path11.join(sourceDir, CLAUDE_CONFIG_FILE);
2249
- const foundFiles = [];
2250
- if (fileExists(codexPath)) {
2251
- foundFiles.push(CODEX_CONFIG_FILE);
2252
- }
2253
- if (fileExists(claudePath)) {
2254
- foundFiles.push(CLAUDE_CONFIG_FILE);
2255
- }
2485
+ const foundFiles = SUPPORTED_CONFIG_FILES.filter((filename) => fileExists(path12.join(sourceDir, filename)));
2256
2486
  if (foundFiles.length === 0) {
2257
2487
  return {
2258
2488
  valid: false,
2259
- message: `\u672A\u627E\u5230\u914D\u7F6E\u6587\u4EF6 (${CODEX_CONFIG_FILE} \u6216 ${CLAUDE_CONFIG_FILE})`,
2489
+ message: `\u672A\u627E\u5230\u914D\u7F6E\u6587\u4EF6 (${SUPPORTED_CONFIG_FILES.join(" / ")})`,
2260
2490
  foundFiles: []
2261
2491
  };
2262
2492
  }
@@ -2273,17 +2503,14 @@ function exportConfig(targetDir) {
2273
2503
  ensureDir(targetDir);
2274
2504
  const ccmanDir2 = getCcmanDir();
2275
2505
  const exportedFiles = [];
2276
- const codexSrc = path11.join(ccmanDir2, CODEX_CONFIG_FILE);
2277
- const codexDst = path11.join(targetDir, CODEX_CONFIG_FILE);
2278
- if (fileExists(codexSrc)) {
2279
- fs10.copyFileSync(codexSrc, codexDst);
2280
- exportedFiles.push(CODEX_CONFIG_FILE);
2281
- }
2282
- const claudeSrc = path11.join(ccmanDir2, CLAUDE_CONFIG_FILE);
2283
- const claudeDst = path11.join(targetDir, CLAUDE_CONFIG_FILE);
2284
- if (fileExists(claudeSrc)) {
2285
- fs10.copyFileSync(claudeSrc, claudeDst);
2286
- exportedFiles.push(CLAUDE_CONFIG_FILE);
2506
+ const filesToExport = validation.foundFiles || [];
2507
+ for (const file of filesToExport) {
2508
+ const src = path12.join(ccmanDir2, file);
2509
+ const dst = path12.join(targetDir, file);
2510
+ if (fileExists(src)) {
2511
+ fs11.copyFileSync(src, dst);
2512
+ exportedFiles.push(file);
2513
+ }
2287
2514
  }
2288
2515
  return {
2289
2516
  success: true,
@@ -2301,25 +2528,15 @@ function importConfig(sourceDir) {
2301
2528
  const importedFiles = [];
2302
2529
  ensureDir(ccmanDir2);
2303
2530
  try {
2304
- if (validation.foundFiles.includes(CODEX_CONFIG_FILE)) {
2305
- const codexDst = path11.join(ccmanDir2, CODEX_CONFIG_FILE);
2306
- if (fileExists(codexDst)) {
2307
- const backupPath = backupConfig(codexDst);
2531
+ for (const file of validation.foundFiles) {
2532
+ const targetPath = path12.join(ccmanDir2, file);
2533
+ const sourcePath = path12.join(sourceDir, file);
2534
+ if (fileExists(targetPath)) {
2535
+ const backupPath = backupConfig(targetPath);
2308
2536
  backupPaths.push(backupPath);
2309
2537
  }
2310
- const codexSrc = path11.join(sourceDir, CODEX_CONFIG_FILE);
2311
- fs10.copyFileSync(codexSrc, codexDst);
2312
- importedFiles.push(CODEX_CONFIG_FILE);
2313
- }
2314
- if (validation.foundFiles.includes(CLAUDE_CONFIG_FILE)) {
2315
- const claudeDst = path11.join(ccmanDir2, CLAUDE_CONFIG_FILE);
2316
- if (fileExists(claudeDst)) {
2317
- const backupPath = backupConfig(claudeDst);
2318
- backupPaths.push(backupPath);
2319
- }
2320
- const claudeSrc = path11.join(sourceDir, CLAUDE_CONFIG_FILE);
2321
- fs10.copyFileSync(claudeSrc, claudeDst);
2322
- importedFiles.push(CLAUDE_CONFIG_FILE);
2538
+ fs11.copyFileSync(sourcePath, targetPath);
2539
+ importedFiles.push(file);
2323
2540
  }
2324
2541
  return {
2325
2542
  success: true,
@@ -2330,26 +2547,25 @@ function importConfig(sourceDir) {
2330
2547
  for (const backupPath of backupPaths) {
2331
2548
  const originalPath = backupPath.replace(/\.backup\.\d+$/, "");
2332
2549
  if (fileExists(backupPath)) {
2333
- fs10.copyFileSync(backupPath, originalPath);
2550
+ fs11.copyFileSync(backupPath, originalPath);
2334
2551
  }
2335
2552
  }
2336
2553
  throw new Error(`\u5BFC\u5165\u5931\u8D25\uFF0C\u5DF2\u6062\u590D\u5907\u4EFD: ${error.message}`);
2337
2554
  }
2338
2555
  }
2339
- var CODEX_CONFIG_FILE, CLAUDE_CONFIG_FILE;
2556
+ var SUPPORTED_CONFIG_FILES;
2340
2557
  var init_export = __esm({
2341
2558
  "../core/dist/export.js"() {
2342
2559
  "use strict";
2343
2560
  init_paths();
2344
2561
  init_file();
2345
2562
  init_merge();
2346
- CODEX_CONFIG_FILE = "codex.json";
2347
- CLAUDE_CONFIG_FILE = "claude.json";
2563
+ SUPPORTED_CONFIG_FILES = ["codex.json", "claude.json", "openclaw.json"];
2348
2564
  }
2349
2565
  });
2350
2566
 
2351
2567
  // ../core/dist/claude-clean.js
2352
- import * as fs11 from "fs";
2568
+ import * as fs12 from "fs";
2353
2569
  function formatBytes(bytes) {
2354
2570
  if (bytes < 1024)
2355
2571
  return `${bytes} B`;
@@ -2359,7 +2575,7 @@ function formatBytes(bytes) {
2359
2575
  }
2360
2576
  function getFileSize(filePath) {
2361
2577
  try {
2362
- const stats = fs11.statSync(filePath);
2578
+ const stats = fs12.statSync(filePath);
2363
2579
  return stats.size;
2364
2580
  } catch {
2365
2581
  return 0;
@@ -2368,18 +2584,18 @@ function getFileSize(filePath) {
2368
2584
  function backupFile2(filePath) {
2369
2585
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/:/g, "-").split(".")[0];
2370
2586
  const backupPath = `${filePath}.backup-${timestamp}`;
2371
- fs11.copyFileSync(filePath, backupPath);
2587
+ fs12.copyFileSync(filePath, backupPath);
2372
2588
  return backupPath;
2373
2589
  }
2374
2590
  function saveJsonAtomic(filePath, data) {
2375
2591
  const tempPath = `${filePath}.tmp`;
2376
2592
  const content = JSON.stringify(data, null, 2);
2377
- fs11.writeFileSync(tempPath, content, { mode: 384 });
2378
- fs11.renameSync(tempPath, filePath);
2593
+ fs12.writeFileSync(tempPath, content, { mode: 384 });
2594
+ fs12.renameSync(tempPath, filePath);
2379
2595
  }
2380
2596
  function analyzeClaudeJson() {
2381
2597
  const filePath = getClaudeJsonPath();
2382
- if (!fs11.existsSync(filePath)) {
2598
+ if (!fs12.existsSync(filePath)) {
2383
2599
  return {
2384
2600
  fileSize: 0,
2385
2601
  fileSizeFormatted: "0 B",
@@ -2395,7 +2611,7 @@ function analyzeClaudeJson() {
2395
2611
  };
2396
2612
  }
2397
2613
  const fileSize = getFileSize(filePath);
2398
- const content = fs11.readFileSync(filePath, "utf-8");
2614
+ const content = fs12.readFileSync(filePath, "utf-8");
2399
2615
  const config = JSON.parse(content);
2400
2616
  const projects = config.projects || {};
2401
2617
  const projectHistory = [];
@@ -2429,12 +2645,12 @@ function analyzeClaudeJson() {
2429
2645
  }
2430
2646
  function cleanClaudeJson(options = {}) {
2431
2647
  const filePath = getClaudeJsonPath();
2432
- if (!fs11.existsSync(filePath)) {
2648
+ if (!fs12.existsSync(filePath)) {
2433
2649
  throw new Error(`${filePath} \u6587\u4EF6\u4E0D\u5B58\u5728`);
2434
2650
  }
2435
2651
  const backupPath = backupFile2(filePath);
2436
2652
  const sizeBefore = getFileSize(filePath);
2437
- const content = fs11.readFileSync(filePath, "utf-8");
2653
+ const content = fs12.readFileSync(filePath, "utf-8");
2438
2654
  const config = JSON.parse(content);
2439
2655
  const cleanedItems = applyCleanOptions(config, options);
2440
2656
  saveJsonAtomic(filePath, config);
@@ -2522,6 +2738,7 @@ var init_dist2 = __esm({
2522
2738
  init_mcp2();
2523
2739
  init_gemini();
2524
2740
  init_opencode();
2741
+ init_openclaw();
2525
2742
  init_mcp();
2526
2743
  init_migrate();
2527
2744
  init_paths();
@@ -2889,12 +3106,18 @@ function uploadCommand(program2) {
2889
3106
  }
2890
3107
  const codexManager = createCodexManager();
2891
3108
  const claudeManager = createClaudeManager();
3109
+ const geminiManager = createGeminiManager();
3110
+ const openclawManager = createOpenClawManager();
2892
3111
  const codexProviders = codexManager.list();
2893
3112
  const claudeProviders = claudeManager.list();
3113
+ const geminiProviders = geminiManager.list();
3114
+ const openclawProviders = openclawManager.list();
2894
3115
  console.log(chalk6.bold("\n\u{1F4E4} \u4E0A\u4F20\u914D\u7F6E\u5230\u4E91\u7AEF\n"));
2895
3116
  console.log("\u914D\u7F6E\u4FE1\u606F:");
2896
3117
  console.log(` Codex \u670D\u52A1\u5546: ${chalk6.cyan(codexProviders.length)} \u4E2A`);
2897
3118
  console.log(` Claude \u670D\u52A1\u5546: ${chalk6.cyan(claudeProviders.length)} \u4E2A`);
3119
+ console.log(` Gemini \u670D\u52A1\u5546: ${chalk6.cyan(geminiProviders.length)} \u4E2A`);
3120
+ console.log(` OpenClaw \u670D\u52A1\u5546: ${chalk6.cyan(openclawProviders.length)} \u4E2A`);
2898
3121
  console.log();
2899
3122
  console.log(chalk6.yellow("\u26A0\uFE0F \u4E91\u7AEF\u73B0\u6709\u914D\u7F6E\u5C06\u88AB\u8986\u76D6"));
2900
3123
  console.log();
@@ -2920,6 +3143,8 @@ function uploadCommand(program2) {
2920
3143
  console.log(chalk6.gray("\u8FDC\u7A0B\u6587\u4EF6:"));
2921
3144
  console.log(chalk6.gray(` ${config.webdavUrl}${config.remoteDir}/.ccman/codex.json`));
2922
3145
  console.log(chalk6.gray(` ${config.webdavUrl}${config.remoteDir}/.ccman/claude.json`));
3146
+ console.log(chalk6.gray(` ${config.webdavUrl}${config.remoteDir}/.ccman/gemini.json`));
3147
+ console.log(chalk6.gray(` ${config.webdavUrl}${config.remoteDir}/.ccman/openclaw.json`));
2923
3148
  console.log();
2924
3149
  console.log(chalk6.blue("\u{1F4A1} \u5176\u4ED6\u8BBE\u5907\u53EF\u901A\u8FC7 'ccman sync download' \u83B7\u53D6\u914D\u7F6E\n"));
2925
3150
  } catch (error) {
@@ -2990,8 +3215,8 @@ function downloadCommand(program2) {
2990
3215
  console.log();
2991
3216
  if (backupPaths.length > 0) {
2992
3217
  console.log(chalk7.gray("\u672C\u5730\u5907\u4EFD:"));
2993
- backupPaths.forEach((path14) => {
2994
- console.log(chalk7.gray(` ${path14}`));
3218
+ backupPaths.forEach((path15) => {
3219
+ console.log(chalk7.gray(` ${path15}`));
2995
3220
  });
2996
3221
  console.log();
2997
3222
  }
@@ -3052,8 +3277,8 @@ function mergeCommand(program2) {
3052
3277
  console.log();
3053
3278
  if (result.backupPaths.length > 0) {
3054
3279
  console.log(chalk8.gray("\u5907\u4EFD:"));
3055
- result.backupPaths.forEach((path14) => {
3056
- console.log(chalk8.gray(` ${path14}`));
3280
+ result.backupPaths.forEach((path15) => {
3281
+ console.log(chalk8.gray(` ${path15}`));
3057
3282
  });
3058
3283
  console.log();
3059
3284
  }
@@ -3098,16 +3323,26 @@ function statusCommand(program2) {
3098
3323
  console.log(` URL: ${chalk9.gray(config.webdavUrl)}`);
3099
3324
  console.log(` \u7528\u6237: ${chalk9.gray(config.username)}`);
3100
3325
  console.log(` \u8FDC\u7A0B\u76EE\u5F55: ${chalk9.gray(config.remoteDir)}`);
3101
- console.log(` \u8BA4\u8BC1: ${chalk9.gray(config.authType === "password" ? "Basic Auth" : "Digest Auth")}`);
3102
- console.log(` \u540C\u6B65\u5BC6\u7801: ${config.syncPassword ? chalk9.green("\u2713 \u5DF2\u4FDD\u5B58") : chalk9.yellow("\u2717 \u672A\u4FDD\u5B58")}`);
3326
+ console.log(
3327
+ ` \u8BA4\u8BC1: ${chalk9.gray(config.authType === "password" ? "Basic Auth" : "Digest Auth")}`
3328
+ );
3329
+ console.log(
3330
+ ` \u540C\u6B65\u5BC6\u7801: ${config.syncPassword ? chalk9.green("\u2713 \u5DF2\u4FDD\u5B58") : chalk9.yellow("\u2717 \u672A\u4FDD\u5B58")}`
3331
+ );
3103
3332
  console.log();
3104
3333
  const codexManager = createCodexManager();
3105
3334
  const claudeManager = createClaudeManager();
3335
+ const geminiManager = createGeminiManager();
3336
+ const openclawManager = createOpenClawManager();
3106
3337
  const codexProviders = codexManager.list();
3107
3338
  const claudeProviders = claudeManager.list();
3339
+ const geminiProviders = geminiManager.list();
3340
+ const openclawProviders = openclawManager.list();
3108
3341
  console.log(chalk9.bold("\u672C\u5730\u914D\u7F6E:"));
3109
3342
  console.log(` Codex: ${chalk9.cyan(codexProviders.length)} \u4E2A\u670D\u52A1\u5546`);
3110
3343
  console.log(` Claude: ${chalk9.cyan(claudeProviders.length)} \u4E2A\u670D\u52A1\u5546`);
3344
+ console.log(` Gemini: ${chalk9.cyan(geminiProviders.length)} \u4E2A\u670D\u52A1\u5546`);
3345
+ console.log(` OpenClaw: ${chalk9.cyan(openclawProviders.length)} \u4E2A\u670D\u52A1\u5546`);
3111
3346
  if (config.lastSync) {
3112
3347
  const date = new Date(config.lastSync).toLocaleString("zh-CN");
3113
3348
  console.log(` \u6700\u540E\u540C\u6B65: ${chalk9.gray(date)}`);
@@ -3245,7 +3480,7 @@ var init_sync = __esm({
3245
3480
 
3246
3481
  // src/index.ts
3247
3482
  import { Command as Command3 } from "commander";
3248
- import chalk48 from "chalk";
3483
+ import chalk55 from "chalk";
3249
3484
 
3250
3485
  // src/utils/logo.ts
3251
3486
  init_dist2();
@@ -3308,7 +3543,8 @@ var CLI_TOOL_CONFIG = {
3308
3543
  [TOOL_TYPES.CODEX]: { name: "Codex", emoji: "\u{1F536}", cmd: "cx" },
3309
3544
  [TOOL_TYPES.CLAUDE]: { name: "Claude", emoji: "\u{1F537}", cmd: "cc" },
3310
3545
  [TOOL_TYPES.GEMINI]: { name: "Gemini", emoji: "\u{1F48E}", cmd: "gm" },
3311
- [TOOL_TYPES.OPENCODE]: { name: "OpenCode", emoji: "\u{1F9E9}", cmd: "oc" }
3546
+ [TOOL_TYPES.OPENCODE]: { name: "OpenCode", emoji: "\u{1F9E9}", cmd: "oc" },
3547
+ [TOOL_TYPES.OPENCLAW]: { name: "OpenClaw", emoji: "\u{1F980}", cmd: "ow" }
3312
3548
  };
3313
3549
  function getManager(tool) {
3314
3550
  switch (tool) {
@@ -3320,6 +3556,8 @@ function getManager(tool) {
3320
3556
  return createGeminiManager();
3321
3557
  case TOOL_TYPES.OPENCODE:
3322
3558
  return createOpenCodeManager();
3559
+ case TOOL_TYPES.OPENCLAW:
3560
+ return createOpenClawManager();
3323
3561
  }
3324
3562
  }
3325
3563
  async function promptProviderForm(defaults) {
@@ -3386,6 +3624,7 @@ async function startMainMenu() {
3386
3624
  { name: "\u{1F536} Codex \u7BA1\u7406", value: "codex" },
3387
3625
  { name: "\u{1F48E} Gemini \u7BA1\u7406", value: "gemini" },
3388
3626
  { name: "\u{1F9E9} OpenCode \u7BA1\u7406", value: "opencode" },
3627
+ { name: "\u{1F980} OpenClaw \u7BA1\u7406", value: "openclaw" },
3389
3628
  { name: "\u{1F504} WebDAV \u540C\u6B65", value: "sync" },
3390
3629
  { name: "\u{1F4E6} \u9884\u7F6E\u670D\u52A1\u5546\u7BA1\u7406", value: "presets" },
3391
3630
  { name: "\u274C \u9000\u51FA", value: "exit" }
@@ -3404,6 +3643,8 @@ async function startMainMenu() {
3404
3643
  await startGeminiMenu();
3405
3644
  } else if (choice === "opencode") {
3406
3645
  await startOpenCodeMenu();
3646
+ } else if (choice === "openclaw") {
3647
+ await startOpenClawMenu();
3407
3648
  } else if (choice === "sync") {
3408
3649
  const { startSyncMenu: startSyncMenu2 } = await Promise.resolve().then(() => (init_sync(), sync_exports));
3409
3650
  await startSyncMenu2();
@@ -3424,6 +3665,9 @@ async function startGeminiMenu() {
3424
3665
  async function startOpenCodeMenu() {
3425
3666
  await showToolMenu(TOOL_TYPES.OPENCODE);
3426
3667
  }
3668
+ async function startOpenClawMenu() {
3669
+ await showToolMenu(TOOL_TYPES.OPENCLAW);
3670
+ }
3427
3671
  async function showToolMenu(tool) {
3428
3672
  const { name: toolName, emoji: toolEmoji } = CLI_TOOL_CONFIG[tool];
3429
3673
  while (true) {
@@ -5275,7 +5519,7 @@ function editCommand3(program2) {
5275
5519
  targetId = selectedId;
5276
5520
  }
5277
5521
  const provider = manager.get(targetId);
5278
- const currentCommand5 = provider.baseUrl;
5522
+ const currentCommand6 = provider.baseUrl;
5279
5523
  const currentArgs = provider.apiKey;
5280
5524
  const currentEnv = provider.model;
5281
5525
  console.log(chalk30.bold("\n\u270F\uFE0F \u7F16\u8F91 MCP \u670D\u52A1\u5668\n"));
@@ -5291,7 +5535,7 @@ function editCommand3(program2) {
5291
5535
  type: "input",
5292
5536
  name: "command",
5293
5537
  message: "\u542F\u52A8\u547D\u4EE4:",
5294
- default: currentCommand5
5538
+ default: currentCommand6
5295
5539
  },
5296
5540
  {
5297
5541
  type: "input",
@@ -5310,7 +5554,7 @@ function editCommand3(program2) {
5310
5554
  if (answers.name && answers.name !== provider.name) {
5311
5555
  updates.name = answers.name;
5312
5556
  }
5313
- if (answers.command && answers.command !== currentCommand5) {
5557
+ if (answers.command && answers.command !== currentCommand6) {
5314
5558
  updates.baseUrl = answers.command;
5315
5559
  }
5316
5560
  if (answers.args && answers.args !== currentArgs) {
@@ -6241,44 +6485,495 @@ function createOpenCodeCommands(program2) {
6241
6485
  cloneCommand4(program2);
6242
6486
  }
6243
6487
 
6488
+ // src/commands/openclaw/add.ts
6489
+ init_dist2();
6490
+ import chalk45 from "chalk";
6491
+ import inquirer32 from "inquirer";
6492
+ function addCommand6(program2) {
6493
+ program2.command("add").description("\u6DFB\u52A0\u65B0\u7684 OpenClaw \u670D\u52A1\u5546(\u4EA4\u4E92\u5F0F)").action(async () => {
6494
+ try {
6495
+ const manager = createOpenClawManager();
6496
+ console.log(chalk45.bold("\n\u{1F4DD} \u6DFB\u52A0 OpenClaw \u670D\u52A1\u5546\n"));
6497
+ const { usePreset } = await inquirer32.prompt([
6498
+ {
6499
+ type: "list",
6500
+ name: "usePreset",
6501
+ message: "\u9009\u62E9\u914D\u7F6E\u6765\u6E90:",
6502
+ choices: [
6503
+ { name: "\u{1F4E6} \u4F7F\u7528\u9884\u7F6E\u670D\u52A1\u5546", value: true },
6504
+ { name: "\u270F\uFE0F \u81EA\u5B9A\u4E49\u914D\u7F6E", value: false }
6505
+ ]
6506
+ }
6507
+ ]);
6508
+ let name;
6509
+ let desc;
6510
+ let baseUrl;
6511
+ let apiKey;
6512
+ if (usePreset) {
6513
+ const { presetName } = await inquirer32.prompt([
6514
+ {
6515
+ type: "list",
6516
+ name: "presetName",
6517
+ message: "\u9009\u62E9\u9884\u7F6E\u670D\u52A1\u5546:",
6518
+ choices: OPENCLAW_PRESETS.map((p) => ({
6519
+ name: `${p.name} - ${p.description}`,
6520
+ value: p.name
6521
+ }))
6522
+ }
6523
+ ]);
6524
+ const preset = OPENCLAW_PRESETS.find((p) => p.name === presetName);
6525
+ console.log(chalk45.blue(`
6526
+ \u4F7F\u7528\u9884\u8BBE: ${preset.name} - ${preset.description}
6527
+ `));
6528
+ const input = await promptProviderForm({
6529
+ name: preset.name,
6530
+ desc: "",
6531
+ baseUrl: preset.baseUrl,
6532
+ apiKey: ""
6533
+ });
6534
+ name = input.name;
6535
+ desc = input.desc;
6536
+ baseUrl = input.baseUrl;
6537
+ apiKey = input.apiKey;
6538
+ } else {
6539
+ const answers = await inquirer32.prompt([
6540
+ {
6541
+ type: "input",
6542
+ name: "name",
6543
+ message: "\u670D\u52A1\u5546\u540D\u79F0:",
6544
+ validate: (value) => value ? true : "\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A"
6545
+ },
6546
+ {
6547
+ type: "input",
6548
+ name: "baseUrl",
6549
+ message: "API \u5730\u5740:",
6550
+ validate: (value) => {
6551
+ if (!value) return "API \u5730\u5740\u4E0D\u80FD\u4E3A\u7A7A";
6552
+ if (!value.startsWith("http://") && !value.startsWith("https://")) {
6553
+ return "API \u5730\u5740\u5FC5\u987B\u4EE5 http:// \u6216 https:// \u5F00\u5934";
6554
+ }
6555
+ return true;
6556
+ }
6557
+ },
6558
+ {
6559
+ type: "password",
6560
+ name: "apiKey",
6561
+ message: "API \u5BC6\u94A5:",
6562
+ mask: "*",
6563
+ validate: (value) => value ? true : "API \u5BC6\u94A5\u4E0D\u80FD\u4E3A\u7A7A"
6564
+ }
6565
+ ]);
6566
+ name = answers.name;
6567
+ desc = void 0;
6568
+ baseUrl = answers.baseUrl;
6569
+ apiKey = answers.apiKey;
6570
+ }
6571
+ const provider = manager.add({
6572
+ name,
6573
+ desc,
6574
+ baseUrl,
6575
+ apiKey
6576
+ });
6577
+ console.log();
6578
+ console.log(chalk45.green("\u2705 \u6DFB\u52A0\u6210\u529F"));
6579
+ console.log();
6580
+ console.log(` ${chalk45.bold(provider.name)} ${chalk45.blue("[OpenClaw]")}`);
6581
+ console.log(` ${chalk45.gray(provider.baseUrl)}`);
6582
+ console.log();
6583
+ const { switchNow } = await inquirer32.prompt([
6584
+ {
6585
+ type: "confirm",
6586
+ name: "switchNow",
6587
+ message: "\u662F\u5426\u7ACB\u5373\u5207\u6362\u5230\u6B64\u670D\u52A1\u5546?",
6588
+ default: true
6589
+ }
6590
+ ]);
6591
+ if (switchNow) {
6592
+ manager.switch(provider.id);
6593
+ console.log(chalk45.green("\u2705 \u5DF2\u5207\u6362\u5230\u65B0\u670D\u52A1\u5546"));
6594
+ console.log();
6595
+ console.log(chalk45.gray("\u914D\u7F6E\u5DF2\u66F4\u65B0:"));
6596
+ console.log(chalk45.gray(` - ${getOpenClawConfigPath()}`));
6597
+ console.log(chalk45.gray(` - ${getOpenClawModelsPath()}`));
6598
+ } else {
6599
+ console.log(
6600
+ chalk45.blue("\u{1F4A1} \u7A0D\u540E\u5207\u6362:") + chalk45.white(` ccman openclaw use "${provider.name}"`)
6601
+ );
6602
+ }
6603
+ } catch (error) {
6604
+ console.error(chalk45.red(`
6605
+ \u274C ${error.message}
6606
+ `));
6607
+ process.exit(1);
6608
+ }
6609
+ });
6610
+ }
6611
+
6612
+ // src/commands/openclaw/list.ts
6613
+ init_dist2();
6614
+ import chalk46 from "chalk";
6615
+ function listCommand6(program2) {
6616
+ program2.command("list").alias("ls").description("\u5217\u51FA\u6240\u6709 OpenClaw \u670D\u52A1\u5546").action(async () => {
6617
+ try {
6618
+ const manager = createOpenClawManager();
6619
+ const providers = manager.list();
6620
+ const current = manager.getCurrent();
6621
+ if (providers.length === 0) {
6622
+ console.log(chalk46.yellow("\n\u26A0\uFE0F \u6682\u65E0 OpenClaw \u670D\u52A1\u5546\n"));
6623
+ console.log(chalk46.blue("\u{1F4A1} \u6DFB\u52A0\u670D\u52A1\u5546:") + chalk46.white(" ccman openclaw add\n"));
6624
+ return;
6625
+ }
6626
+ console.log(chalk46.bold(`
6627
+ \u{1F4CB} OpenClaw \u670D\u52A1\u5546 (${providers.length} \u4E2A)`));
6628
+ console.log(formatProviderTable(providers, current?.id));
6629
+ } catch (error) {
6630
+ console.error(chalk46.red(`
6631
+ \u274C ${error.message}
6632
+ `));
6633
+ process.exit(1);
6634
+ }
6635
+ });
6636
+ }
6637
+
6638
+ // src/commands/openclaw/use.ts
6639
+ init_dist2();
6640
+ import chalk47 from "chalk";
6641
+ import inquirer33 from "inquirer";
6642
+ function useCommand5(program2) {
6643
+ program2.command("use [name]").description("\u5207\u6362 OpenClaw \u670D\u52A1\u5546").action(async (name) => {
6644
+ try {
6645
+ const manager = createOpenClawManager();
6646
+ const providers = manager.list();
6647
+ if (providers.length === 0) {
6648
+ console.log(chalk47.yellow("\n\u26A0\uFE0F \u6682\u65E0 OpenClaw \u670D\u52A1\u5546\n"));
6649
+ console.log(chalk47.blue("\u{1F4A1} \u6DFB\u52A0\u670D\u52A1\u5546:") + chalk47.white(" ccman openclaw add\n"));
6650
+ return;
6651
+ }
6652
+ let targetId;
6653
+ if (name) {
6654
+ const provider2 = manager.findByName(name);
6655
+ if (!provider2) {
6656
+ throw new ProviderNotFoundError(name);
6657
+ }
6658
+ targetId = provider2.id;
6659
+ } else {
6660
+ const { selectedId } = await inquirer33.prompt([
6661
+ {
6662
+ type: "list",
6663
+ name: "selectedId",
6664
+ message: "\u9009\u62E9\u8981\u5207\u6362\u7684\u670D\u52A1\u5546:",
6665
+ choices: providers.map((p) => ({
6666
+ name: `${p.name} - ${p.baseUrl}`,
6667
+ value: p.id
6668
+ }))
6669
+ }
6670
+ ]);
6671
+ targetId = selectedId;
6672
+ }
6673
+ manager.switch(targetId);
6674
+ const provider = manager.get(targetId);
6675
+ console.log(chalk47.green("\n\u2705 \u5207\u6362\u6210\u529F\n"));
6676
+ console.log(` ${chalk47.bold(provider.name)} ${chalk47.blue("[OpenClaw]")}`);
6677
+ console.log(` ${chalk47.gray(`URL: ${provider.baseUrl}`)}`);
6678
+ console.log();
6679
+ console.log(chalk47.gray("\u914D\u7F6E\u5DF2\u66F4\u65B0:"));
6680
+ console.log(chalk47.gray(` - ${getOpenClawConfigPath()}`));
6681
+ console.log(chalk47.gray(` - ${getOpenClawModelsPath()}`));
6682
+ } catch (error) {
6683
+ if (error instanceof ProviderNotFoundError) {
6684
+ console.error(chalk47.red(`
6685
+ \u274C \u670D\u52A1\u5546\u4E0D\u5B58\u5728: ${name}
6686
+ `));
6687
+ } else {
6688
+ console.error(chalk47.red(`
6689
+ \u274C ${error.message}
6690
+ `));
6691
+ }
6692
+ process.exit(1);
6693
+ }
6694
+ });
6695
+ }
6696
+
6697
+ // src/commands/openclaw/current.ts
6698
+ init_dist2();
6699
+ import chalk48 from "chalk";
6700
+ function currentCommand5(program2) {
6701
+ program2.command("current").description("\u663E\u793A\u5F53\u524D OpenClaw \u670D\u52A1\u5546").action(async () => {
6702
+ try {
6703
+ const manager = createOpenClawManager();
6704
+ const current = manager.getCurrent();
6705
+ if (!current) {
6706
+ console.log(chalk48.yellow("\n\u26A0\uFE0F \u5F53\u524D\u6CA1\u6709\u6FC0\u6D3B\u7684 OpenClaw \u670D\u52A1\u5546\n"));
6707
+ console.log(chalk48.blue("\u{1F4A1} \u5217\u51FA\u670D\u52A1\u5546:") + chalk48.white(" ccman openclaw list\n"));
6708
+ return;
6709
+ }
6710
+ console.log(chalk48.bold("\n\u{1F3AF} \u5F53\u524D OpenClaw \u670D\u52A1\u5546\n"));
6711
+ console.log(` \u540D\u79F0: ${chalk48.bold(current.name)}`);
6712
+ console.log(` \u5730\u5740: ${chalk48.gray(current.baseUrl)}`);
6713
+ console.log();
6714
+ } catch (error) {
6715
+ console.error(chalk48.red(`
6716
+ \u274C ${error.message}
6717
+ `));
6718
+ process.exit(1);
6719
+ }
6720
+ });
6721
+ }
6722
+
6723
+ // src/commands/openclaw/edit.ts
6724
+ init_dist2();
6725
+ import chalk49 from "chalk";
6726
+ import inquirer34 from "inquirer";
6727
+ function editCommand6(program2) {
6728
+ program2.command("edit [name]").description("\u7F16\u8F91 OpenClaw \u670D\u52A1\u5546").action(async (name) => {
6729
+ try {
6730
+ const manager = createOpenClawManager();
6731
+ const providers = manager.list();
6732
+ if (providers.length === 0) {
6733
+ console.log(chalk49.yellow("\n\u26A0\uFE0F \u6682\u65E0 OpenClaw \u670D\u52A1\u5546\n"));
6734
+ console.log(chalk49.blue("\u{1F4A1} \u6DFB\u52A0\u670D\u52A1\u5546:") + chalk49.white(" ccman openclaw add\n"));
6735
+ return;
6736
+ }
6737
+ let targetId;
6738
+ if (name) {
6739
+ const provider2 = manager.findByName(name);
6740
+ if (!provider2) {
6741
+ throw new ProviderNotFoundError(name);
6742
+ }
6743
+ targetId = provider2.id;
6744
+ } else {
6745
+ const { selectedId } = await inquirer34.prompt([
6746
+ {
6747
+ type: "list",
6748
+ name: "selectedId",
6749
+ message: "\u9009\u62E9\u8981\u7F16\u8F91\u7684\u670D\u52A1\u5546:",
6750
+ choices: providers.map((p) => ({
6751
+ name: `${p.name} - ${p.baseUrl}`,
6752
+ value: p.id
6753
+ }))
6754
+ }
6755
+ ]);
6756
+ targetId = selectedId;
6757
+ }
6758
+ const provider = manager.get(targetId);
6759
+ const input = await promptProviderForm({
6760
+ name: provider.name,
6761
+ desc: provider.desc ?? "",
6762
+ baseUrl: provider.baseUrl,
6763
+ apiKey: provider.apiKey
6764
+ });
6765
+ manager.edit(targetId, {
6766
+ name: input.name,
6767
+ desc: input.desc,
6768
+ baseUrl: input.baseUrl,
6769
+ apiKey: input.apiKey
6770
+ });
6771
+ console.log(chalk49.green("\n\u2705 \u7F16\u8F91\u6210\u529F\n"));
6772
+ } catch (error) {
6773
+ if (error instanceof ProviderNotFoundError) {
6774
+ console.error(chalk49.red(`
6775
+ \u274C \u670D\u52A1\u5546\u4E0D\u5B58\u5728: ${name}
6776
+ `));
6777
+ } else {
6778
+ console.error(chalk49.red(`
6779
+ \u274C ${error.message}
6780
+ `));
6781
+ }
6782
+ process.exit(1);
6783
+ }
6784
+ });
6785
+ }
6786
+
6787
+ // src/commands/openclaw/remove.ts
6788
+ init_dist2();
6789
+ import chalk50 from "chalk";
6790
+ import inquirer35 from "inquirer";
6791
+ function removeCommand6(program2) {
6792
+ program2.command("remove [name]").alias("rm").description("\u5220\u9664 OpenClaw \u670D\u52A1\u5546").action(async (name) => {
6793
+ try {
6794
+ const manager = createOpenClawManager();
6795
+ const providers = manager.list();
6796
+ if (providers.length === 0) {
6797
+ console.log(chalk50.yellow("\n\u26A0\uFE0F \u6682\u65E0 OpenClaw \u670D\u52A1\u5546\n"));
6798
+ return;
6799
+ }
6800
+ let targetId;
6801
+ let targetName;
6802
+ if (name) {
6803
+ const provider = manager.findByName(name);
6804
+ if (!provider) {
6805
+ throw new ProviderNotFoundError(name);
6806
+ }
6807
+ targetId = provider.id;
6808
+ targetName = provider.name;
6809
+ } else {
6810
+ const { selectedId } = await inquirer35.prompt([
6811
+ {
6812
+ type: "list",
6813
+ name: "selectedId",
6814
+ message: "\u9009\u62E9\u8981\u5220\u9664\u7684\u670D\u52A1\u5546:",
6815
+ choices: providers.map((p) => ({
6816
+ name: `${p.name} - ${p.baseUrl}`,
6817
+ value: p.id
6818
+ }))
6819
+ }
6820
+ ]);
6821
+ const provider = manager.get(selectedId);
6822
+ targetId = selectedId;
6823
+ targetName = provider.name;
6824
+ }
6825
+ const { confirmed } = await inquirer35.prompt([
6826
+ {
6827
+ type: "confirm",
6828
+ name: "confirmed",
6829
+ message: `\u786E\u5B9A\u5220\u9664 "${targetName}"?`,
6830
+ default: false
6831
+ }
6832
+ ]);
6833
+ if (!confirmed) {
6834
+ console.log(chalk50.gray("\n\u5DF2\u53D6\u6D88\n"));
6835
+ return;
6836
+ }
6837
+ manager.remove(targetId);
6838
+ console.log(chalk50.green(`
6839
+ \u2705 \u5DF2\u5220\u9664: ${targetName}
6840
+ `));
6841
+ } catch (error) {
6842
+ if (error instanceof ProviderNotFoundError) {
6843
+ console.error(chalk50.red(`
6844
+ \u274C \u670D\u52A1\u5546\u4E0D\u5B58\u5728: ${name}
6845
+ `));
6846
+ } else {
6847
+ console.error(chalk50.red(`
6848
+ \u274C ${error.message}
6849
+ `));
6850
+ }
6851
+ process.exit(1);
6852
+ }
6853
+ });
6854
+ }
6855
+
6856
+ // src/commands/openclaw/clone.ts
6857
+ init_dist2();
6858
+ import chalk51 from "chalk";
6859
+ import inquirer36 from "inquirer";
6860
+ function cloneCommand5(program2) {
6861
+ program2.command("clone [source-name] [new-name]").description("\u514B\u9686 OpenClaw \u670D\u52A1\u5546").action(async (sourceName, newName) => {
6862
+ try {
6863
+ const manager = createOpenClawManager();
6864
+ const providers = manager.list();
6865
+ if (providers.length === 0) {
6866
+ console.log(chalk51.yellow("\n\u26A0\uFE0F \u6682\u65E0 OpenClaw \u670D\u52A1\u5546\n"));
6867
+ return;
6868
+ }
6869
+ let sourceId;
6870
+ if (sourceName) {
6871
+ const provider = manager.findByName(sourceName);
6872
+ if (!provider) {
6873
+ throw new ProviderNotFoundError(sourceName);
6874
+ }
6875
+ sourceId = provider.id;
6876
+ } else {
6877
+ const { selectedId } = await inquirer36.prompt([
6878
+ {
6879
+ type: "list",
6880
+ name: "selectedId",
6881
+ message: "\u9009\u62E9\u8981\u514B\u9686\u7684\u670D\u52A1\u5546:",
6882
+ choices: providers.map((p) => ({
6883
+ name: `${p.name} - ${p.baseUrl}`,
6884
+ value: p.id
6885
+ }))
6886
+ }
6887
+ ]);
6888
+ sourceId = selectedId;
6889
+ }
6890
+ const source = manager.get(sourceId);
6891
+ let cloned;
6892
+ if (newName) {
6893
+ cloned = manager.clone(sourceId, newName);
6894
+ } else {
6895
+ console.log(chalk51.blue(`
6896
+ \u514B\u9686\u81EA: ${source.name}
6897
+ `));
6898
+ const input = await promptProviderForm({
6899
+ name: `${source.name}\uFF08\u526F\u672C\uFF09`,
6900
+ desc: "",
6901
+ baseUrl: source.baseUrl,
6902
+ apiKey: source.apiKey
6903
+ });
6904
+ cloned = manager.add({
6905
+ name: input.name,
6906
+ desc: input.desc,
6907
+ baseUrl: input.baseUrl,
6908
+ apiKey: input.apiKey
6909
+ });
6910
+ }
6911
+ console.log();
6912
+ console.log(chalk51.green("\u2705 \u514B\u9686\u6210\u529F"));
6913
+ console.log();
6914
+ console.log(` ${chalk51.bold(cloned.name)} ${chalk51.blue("[OpenClaw]")}`);
6915
+ console.log(` ${chalk51.gray(`ID: ${cloned.id}`)}`);
6916
+ console.log(` ${chalk51.gray(`URL: ${cloned.baseUrl}`)}`);
6917
+ console.log();
6918
+ } catch (error) {
6919
+ console.error(chalk51.red(`
6920
+ \u274C ${error.message}
6921
+ `));
6922
+ process.exit(1);
6923
+ }
6924
+ });
6925
+ }
6926
+
6927
+ // src/commands/openclaw/index.ts
6928
+ function createOpenClawCommands(program2) {
6929
+ addCommand6(program2);
6930
+ listCommand6(program2);
6931
+ useCommand5(program2);
6932
+ currentCommand5(program2);
6933
+ editCommand6(program2);
6934
+ removeCommand6(program2);
6935
+ cloneCommand5(program2);
6936
+ }
6937
+
6244
6938
  // src/index.ts
6245
6939
  init_sync();
6246
6940
 
6247
6941
  // src/commands/export.ts
6248
6942
  init_dist2();
6249
- import chalk45 from "chalk";
6250
- import path12 from "path";
6943
+ import chalk52 from "chalk";
6944
+ import path13 from "path";
6251
6945
  function exportCommand(program2) {
6252
6946
  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) => {
6253
6947
  try {
6254
- console.log(chalk45.bold("\n\u{1F4E6} \u5BFC\u51FA\u914D\u7F6E\n"));
6948
+ console.log(chalk52.bold("\n\u{1F4E6} \u5BFC\u51FA\u914D\u7F6E\n"));
6255
6949
  const validation = validateExport();
6256
6950
  if (!validation.valid) {
6257
- console.log(chalk45.red(`\u274C ${validation.message}
6951
+ console.log(chalk52.red(`\u274C ${validation.message}
6258
6952
  `));
6259
6953
  process.exit(1);
6260
6954
  }
6261
- const resolvedPath = targetDir.startsWith("~") ? path12.join(process.env.HOME || "", targetDir.slice(1)) : path12.resolve(targetDir);
6262
- console.log("\u5BFC\u51FA\u6587\u4EF6:");
6263
- console.log(` ${chalk45.cyan("codex.json")} - Codex \u914D\u7F6E`);
6264
- console.log(` ${chalk45.cyan("claude.json")} - Claude \u914D\u7F6E`);
6955
+ const resolvedPath = targetDir.startsWith("~") ? path13.join(process.env.HOME || "", targetDir.slice(1)) : path13.resolve(targetDir);
6956
+ console.log("\u5BFC\u51FA\u6587\u4EF6\uFF08\u5B58\u5728\u5219\u5BFC\u51FA\uFF0C\u4E0D\u5B58\u5728\u5219\u8DF3\u8FC7\uFF09:");
6957
+ console.log(` ${chalk52.cyan("codex.json")} - Codex \u914D\u7F6E`);
6958
+ console.log(` ${chalk52.cyan("claude.json")} - Claude \u914D\u7F6E`);
6959
+ console.log(` ${chalk52.cyan("openclaw.json")} - OpenClaw \u914D\u7F6E`);
6265
6960
  console.log();
6266
- console.log(`\u76EE\u6807\u76EE\u5F55: ${chalk45.cyan(resolvedPath)}`);
6961
+ console.log(`\u76EE\u6807\u76EE\u5F55: ${chalk52.cyan(resolvedPath)}`);
6267
6962
  console.log();
6268
- console.log(chalk45.yellow("\u26A0\uFE0F \u5BFC\u51FA\u6587\u4EF6\u5305\u542B API Key\uFF0C\u8BF7\u59A5\u5584\u4FDD\u7BA1"));
6963
+ console.log(chalk52.yellow("\u26A0\uFE0F \u5BFC\u51FA\u6587\u4EF6\u5305\u542B API Key\uFF0C\u8BF7\u59A5\u5584\u4FDD\u7BA1"));
6269
6964
  console.log();
6270
6965
  const result = exportConfig(resolvedPath);
6271
- console.log(chalk45.green("\u2705 \u5BFC\u51FA\u6210\u529F"));
6966
+ console.log(chalk52.green("\u2705 \u5BFC\u51FA\u6210\u529F"));
6272
6967
  console.log();
6273
6968
  console.log("\u5DF2\u5BFC\u51FA\u6587\u4EF6:");
6274
6969
  for (const file of result.exportedFiles) {
6275
- console.log(` ${chalk45.cyan("\u2713")} ${file}`);
6970
+ console.log(` ${chalk52.cyan("\u2713")} ${file}`);
6276
6971
  }
6277
6972
  console.log();
6278
- console.log(chalk45.blue(`\u{1F4A1} \u5BFC\u5165\u547D\u4EE4: ccman import ${resolvedPath}
6973
+ console.log(chalk52.blue(`\u{1F4A1} \u5BFC\u5165\u547D\u4EE4: ccman import ${resolvedPath}
6279
6974
  `));
6280
6975
  } catch (error) {
6281
- console.error(chalk45.red(`
6976
+ console.error(chalk52.red(`
6282
6977
  \u274C ${error.message}
6283
6978
  `));
6284
6979
  process.exit(1);
@@ -6288,31 +6983,33 @@ function exportCommand(program2) {
6288
6983
 
6289
6984
  // src/commands/import.ts
6290
6985
  init_dist2();
6291
- import chalk46 from "chalk";
6292
- import inquirer32 from "inquirer";
6293
- import path13 from "path";
6986
+ import chalk53 from "chalk";
6987
+ import inquirer37 from "inquirer";
6988
+ import path14 from "path";
6294
6989
  function importCommand(program2) {
6295
6990
  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) => {
6296
6991
  try {
6297
- const resolvedPath = sourceDir.startsWith("~") ? path13.join(process.env.HOME || "", sourceDir.slice(1)) : path13.resolve(sourceDir);
6298
- console.log(chalk46.bold("\n\u{1F4E5} \u5BFC\u5165\u914D\u7F6E\n"));
6992
+ const resolvedPath = sourceDir.startsWith("~") ? path14.join(process.env.HOME || "", sourceDir.slice(1)) : path14.resolve(sourceDir);
6993
+ console.log(chalk53.bold("\n\u{1F4E5} \u5BFC\u5165\u914D\u7F6E\n"));
6299
6994
  const validation = validateImportDir(resolvedPath);
6300
6995
  if (!validation.valid) {
6301
- console.log(chalk46.red(`\u274C ${validation.message}
6996
+ console.log(chalk53.red(`\u274C ${validation.message}
6302
6997
  `));
6303
6998
  process.exit(1);
6304
6999
  }
6305
- console.log(chalk46.yellow("\u26A0\uFE0F \u8B66\u544A\uFF1A\u5BFC\u5165\u5C06\u8986\u76D6\u5F53\u524D\u914D\u7F6E\n"));
6306
- console.log(`\u6E90\u76EE\u5F55: ${chalk46.cyan(resolvedPath)}`);
7000
+ console.log(chalk53.yellow("\u26A0\uFE0F \u8B66\u544A\uFF1A\u5BFC\u5165\u5C06\u8986\u76D6\u5F53\u524D\u914D\u7F6E\n"));
7001
+ console.log(`\u6E90\u76EE\u5F55: ${chalk53.cyan(resolvedPath)}`);
6307
7002
  console.log();
6308
7003
  console.log("\u627E\u5230\u914D\u7F6E\u6587\u4EF6:");
6309
7004
  for (const file of validation.foundFiles) {
6310
- console.log(` ${chalk46.cyan("\u2713")} ${file}`);
7005
+ console.log(` ${chalk53.cyan("\u2713")} ${file}`);
6311
7006
  }
6312
7007
  console.log();
6313
- console.log(chalk46.gray("\u5F53\u524D\u914D\u7F6E\u5C06\u88AB\u8986\u76D6\uFF08\u81EA\u52A8\u5907\u4EFD\uFF09"));
7008
+ console.log(chalk53.gray("\u672A\u627E\u5230\u7684\u53D7\u652F\u6301\u6587\u4EF6\u5C06\u81EA\u52A8\u8DF3\u8FC7\uFF0C\u4E0D\u4F1A\u4E2D\u65AD\u5BFC\u5165"));
7009
+ console.log();
7010
+ console.log(chalk53.gray("\u5F53\u524D\u914D\u7F6E\u5C06\u88AB\u8986\u76D6\uFF08\u81EA\u52A8\u5907\u4EFD\uFF09"));
6314
7011
  console.log();
6315
- const { confirmFirst } = await inquirer32.prompt([
7012
+ const { confirmFirst } = await inquirer37.prompt([
6316
7013
  {
6317
7014
  type: "confirm",
6318
7015
  name: "confirmFirst",
@@ -6321,13 +7018,13 @@ function importCommand(program2) {
6321
7018
  }
6322
7019
  ]);
6323
7020
  if (!confirmFirst) {
6324
- console.log(chalk46.gray("\n\u274C \u5DF2\u53D6\u6D88\n"));
7021
+ console.log(chalk53.gray("\n\u274C \u5DF2\u53D6\u6D88\n"));
6325
7022
  return;
6326
7023
  }
6327
7024
  console.log();
6328
- 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"));
7025
+ console.log(chalk53.red.bold("\u26A0\uFE0F \u6700\u540E\u786E\u8BA4\uFF1A\u6B64\u64CD\u4F5C\u5C06\u8986\u76D6\u6240\u6709\u5F53\u524D\u914D\u7F6E\uFF01"));
6329
7026
  console.log();
6330
- const { confirmSecond } = await inquirer32.prompt([
7027
+ const { confirmSecond } = await inquirer37.prompt([
6331
7028
  {
6332
7029
  type: "confirm",
6333
7030
  name: "confirmSecond",
@@ -6336,31 +7033,31 @@ function importCommand(program2) {
6336
7033
  }
6337
7034
  ]);
6338
7035
  if (!confirmSecond) {
6339
- console.log(chalk46.gray("\n\u274C \u5DF2\u53D6\u6D88\n"));
7036
+ console.log(chalk53.gray("\n\u274C \u5DF2\u53D6\u6D88\n"));
6340
7037
  return;
6341
7038
  }
6342
7039
  console.log();
6343
- console.log(chalk46.gray("\u{1F4BE} \u5907\u4EFD\u5F53\u524D\u914D\u7F6E..."));
6344
- console.log(chalk46.gray("\u{1F4E5} \u5BFC\u5165\u65B0\u914D\u7F6E..."));
7040
+ console.log(chalk53.gray("\u{1F4BE} \u5907\u4EFD\u5F53\u524D\u914D\u7F6E..."));
7041
+ console.log(chalk53.gray("\u{1F4E5} \u5BFC\u5165\u65B0\u914D\u7F6E..."));
6345
7042
  const result = importConfig(resolvedPath);
6346
7043
  console.log();
6347
- console.log(chalk46.green("\u2705 \u5BFC\u5165\u6210\u529F"));
7044
+ console.log(chalk53.green("\u2705 \u5BFC\u5165\u6210\u529F"));
6348
7045
  console.log();
6349
7046
  if (result.backupPaths.length > 0) {
6350
7047
  console.log("\u5907\u4EFD\u6587\u4EF6:");
6351
7048
  for (const backupPath of result.backupPaths) {
6352
- console.log(` ${chalk46.gray(backupPath)}`);
7049
+ console.log(` ${chalk53.gray(backupPath)}`);
6353
7050
  }
6354
7051
  console.log();
6355
7052
  }
6356
7053
  console.log("\u5DF2\u5BFC\u5165\u6587\u4EF6:");
6357
7054
  for (const file of result.importedFiles) {
6358
- console.log(` ${chalk46.cyan("\u2713")} ${file}`);
7055
+ console.log(` ${chalk53.cyan("\u2713")} ${file}`);
6359
7056
  }
6360
7057
  console.log();
6361
- console.log(chalk46.blue("\u{1F4A1} \u8BF7\u4F7F\u7528 'ccman cx use' \u6216 'ccman cc use' \u5207\u6362\u670D\u52A1\u5546\n"));
7058
+ console.log(chalk53.blue("\u{1F4A1} \u8BF7\u4F7F\u7528 'ccman cx use' \u6216 'ccman cc use' \u5207\u6362\u670D\u52A1\u5546\n"));
6362
7059
  } catch (error) {
6363
- console.error(chalk46.red(`
7060
+ console.error(chalk53.red(`
6364
7061
  \u274C ${error.message}
6365
7062
  `));
6366
7063
  process.exit(1);
@@ -6370,12 +7067,13 @@ function importCommand(program2) {
6370
7067
 
6371
7068
  // src/commands/gmn.ts
6372
7069
  init_dist2();
6373
- import chalk47 from "chalk";
6374
- import inquirer33 from "inquirer";
7070
+ import chalk54 from "chalk";
7071
+ import inquirer38 from "inquirer";
6375
7072
  var PROVIDER_NAME = "GMN";
6376
- var VALID_PLATFORMS = ["codex", "opencode"];
7073
+ var VALID_PLATFORMS = ["codex", "opencode", "openclaw"];
6377
7074
  var DEFAULT_PLATFORMS = ["codex", "opencode"];
6378
7075
  var GMN_OPENAI_BASE_URL = "https://gmn.chuangzuoli.com";
7076
+ var GMN_OPENCLAW_BASE_URL = "https://gmn.chuangzuoli.com/v1";
6379
7077
  var TOTAL_STEPS = 3;
6380
7078
  function renderStep(current, total, title) {
6381
7079
  const barLength = total;
@@ -6386,7 +7084,7 @@ function renderStep(current, total, title) {
6386
7084
  function printBanner() {
6387
7085
  printLogo();
6388
7086
  console.log(
6389
- chalk47.cyanBright(
7087
+ chalk54.cyanBright(
6390
7088
  [
6391
7089
  " \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2557",
6392
7090
  " \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551",
@@ -6398,31 +7096,36 @@ function printBanner() {
6398
7096
  ].join("\n")
6399
7097
  )
6400
7098
  );
6401
- console.log(chalk47.gray("\u81EA\u52A8\u5199\u5165\u9009\u4E2D\u5DE5\u5177\u914D\u7F6E\uFF0C\u652F\u6301\u591A\u9009\u3002\n"));
7099
+ console.log(chalk54.gray("\u81EA\u52A8\u5199\u5165\u9009\u4E2D\u5DE5\u5177\u914D\u7F6E\uFF0C\u652F\u6301\u591A\u9009\u3002\n"));
6402
7100
  }
6403
7101
  function printKeyNotice() {
6404
7102
  console.log(
6405
- chalk47.yellow(
7103
+ chalk54.yellow(
6406
7104
  [
6407
- "\u63D0\u793A\uFF1A\u672C\u547D\u4EE4\u4EC5\u914D\u7F6E Codex \u4E0E OpenCode\uFF0C\u4E24\u8005\u5171\u4EAB OpenAI \u5957\u9910/\u7AEF\u70B9\u3002",
7105
+ "\u63D0\u793A\uFF1A\u672C\u547D\u4EE4\u652F\u6301 Codex\u3001OpenCode\u3001OpenClaw \u4E09\u4E2A\u5E73\u53F0\u3002",
7106
+ "Codex \u4E0E OpenCode \u5171\u4EAB OpenAI \u7AEF\u70B9\uFF1BOpenClaw \u4F7F\u7528 /v1 \u7AEF\u70B9\u3002",
6408
7107
  "VS Code \u7684 Codex \u63D2\u4EF6\u82E5\u4F7F\u7528\u672C\u673A\u9ED8\u8BA4\u914D\u7F6E\uFF0C\u4E5F\u4F1A\u8DDF\u968F\u672C\u6B21\u5199\u5165\u751F\u6548\u3002"
6409
7108
  ].join("\n")
6410
7109
  )
6411
7110
  );
6412
7111
  }
6413
7112
  function printWriteTargets(platforms) {
6414
- console.log(chalk47.gray(`\u5199\u5165\u76EE\u5F55: ${getCcmanDir()}`));
7113
+ console.log(chalk54.gray(`\u5199\u5165\u76EE\u5F55: ${getCcmanDir()}`));
6415
7114
  if (platforms.includes("codex")) {
6416
- console.log(chalk47.gray(` - Codex: ${getCodexConfigPath()}`));
6417
- console.log(chalk47.gray(` - Codex: ${getCodexAuthPath()}`));
7115
+ console.log(chalk54.gray(` - Codex: ${getCodexConfigPath()}`));
7116
+ console.log(chalk54.gray(` - Codex: ${getCodexAuthPath()}`));
6418
7117
  }
6419
7118
  if (platforms.includes("opencode")) {
6420
- console.log(chalk47.gray(` - OpenCode: ${getOpenCodeConfigPath()}`));
7119
+ console.log(chalk54.gray(` - OpenCode: ${getOpenCodeConfigPath()}`));
7120
+ }
7121
+ if (platforms.includes("openclaw")) {
7122
+ console.log(chalk54.gray(` - OpenClaw: ${getOpenClawConfigPath()}`));
7123
+ console.log(chalk54.gray(` - OpenClaw: ${getOpenClawModelsPath()}`));
6421
7124
  }
6422
7125
  const env = process.env.NODE_ENV;
6423
7126
  if (env === "development" || env === "test") {
6424
7127
  console.log(
6425
- chalk47.yellow(
7128
+ chalk54.yellow(
6426
7129
  `\u26A0\uFE0F \u5F53\u524D NODE_ENV=${env}\uFF0C\u5C06\u5199\u5165\u5F00\u53D1/\u6D4B\u8BD5\u76EE\u5F55\uFF1B\u5982\u9700\u5199\u5165\u771F\u5B9E HOME\uFF0C\u8BF7\u5728\u751F\u4EA7\u73AF\u5883\u8FD0\u884C\uFF08unset NODE_ENV\uFF09\u3002`
6427
7130
  )
6428
7131
  );
@@ -6441,7 +7144,7 @@ function parsePlatforms(platformArg) {
6441
7144
  return platforms;
6442
7145
  }
6443
7146
  async function promptApiKey() {
6444
- const answers = await inquirer33.prompt([
7147
+ const answers = await inquirer38.prompt([
6445
7148
  {
6446
7149
  type: "password",
6447
7150
  name: "apiKey",
@@ -6456,7 +7159,7 @@ async function promptApiKey() {
6456
7159
  return answers.apiKey.trim();
6457
7160
  }
6458
7161
  async function promptPlatforms() {
6459
- const answers = await inquirer33.prompt([
7162
+ const answers = await inquirer38.prompt([
6460
7163
  {
6461
7164
  type: "checkbox",
6462
7165
  name: "platforms",
@@ -6465,7 +7168,8 @@ async function promptPlatforms() {
6465
7168
  choices: [
6466
7169
  { name: "Codex\uFF08\u9700\u5355\u72EC\u8BA2\u9605 OpenAI \u5957\u9910\uFF09", value: "codex" },
6467
7170
  { name: "OpenCode\uFF08\u4E0E Codex \u5171\u4EAB OpenAI \u5957\u9910\uFF09", value: "opencode" },
6468
- { name: "\u5168\u90E8\uFF08\u5C06\u4F9D\u6B21\u914D\u7F6E Codex \u548C OpenCode\uFF09", value: "all" }
7171
+ { name: "OpenClaw\uFF08GMN /v1 \u7AEF\u70B9\uFF0C\u9ED8\u8BA4\u4E0D\u9009\u4E2D\uFF09", value: "openclaw" },
7172
+ { name: "\u5168\u90E8\uFF08\u5C06\u4F9D\u6B21\u914D\u7F6E Codex\u3001OpenCode\u3001OpenClaw\uFF09", value: "all" }
6469
7173
  ],
6470
7174
  default: DEFAULT_PLATFORMS,
6471
7175
  validate: (value) => {
@@ -6490,43 +7194,48 @@ async function gmnCommand(apiKey, platformArg) {
6490
7194
  printBanner();
6491
7195
  let platforms;
6492
7196
  try {
6493
- console.log(chalk47.cyan(`
7197
+ console.log(chalk54.cyan(`
6494
7198
  ${renderStep(1, TOTAL_STEPS, "\u9009\u62E9\u8981\u914D\u7F6E\u7684\u5DE5\u5177")}`));
6495
7199
  platforms = await resolvePlatforms(platformArg);
6496
7200
  } catch (error) {
6497
- console.error(chalk47.red(`\u274C ${error.message}`));
7201
+ console.error(chalk54.red(`\u274C ${error.message}`));
6498
7202
  process.exit(1);
6499
7203
  }
6500
- console.log(chalk47.gray(`\u5DF2\u9009\u62E9: ${platforms.join(", ")}`));
7204
+ console.log(chalk54.gray(`\u5DF2\u9009\u62E9: ${platforms.join(", ")}`));
6501
7205
  printKeyNotice();
6502
7206
  let resolvedApiKey = apiKey?.trim();
6503
- console.log(chalk47.cyan(`
7207
+ console.log(chalk54.cyan(`
6504
7208
  ${renderStep(2, TOTAL_STEPS, "\u8F93\u5165 API Key")}`));
6505
7209
  if (!resolvedApiKey) {
6506
7210
  resolvedApiKey = await promptApiKey();
6507
7211
  } else {
6508
- console.log(chalk47.gray("\u5DF2\u901A\u8FC7\u53C2\u6570\u63D0\u4F9B API Key\uFF08\u5DF2\u9690\u85CF\uFF09"));
7212
+ console.log(chalk54.gray("\u5DF2\u901A\u8FC7\u53C2\u6570\u63D0\u4F9B API Key\uFF08\u5DF2\u9690\u85CF\uFF09"));
6509
7213
  }
6510
7214
  if (!resolvedApiKey?.trim()) {
6511
- console.error(chalk47.red("\u274C \u9519\u8BEF: API Key \u4E0D\u80FD\u4E3A\u7A7A"));
7215
+ console.error(chalk54.red("\u274C \u9519\u8BEF: API Key \u4E0D\u80FD\u4E3A\u7A7A"));
6512
7216
  process.exit(1);
6513
7217
  }
6514
7218
  const openaiBaseUrl = GMN_OPENAI_BASE_URL;
6515
7219
  const platformBaseUrls = {
6516
7220
  codex: openaiBaseUrl,
6517
- opencode: openaiBaseUrl
7221
+ opencode: openaiBaseUrl,
7222
+ openclaw: GMN_OPENCLAW_BASE_URL
6518
7223
  };
6519
- console.log(chalk47.cyan(`
7224
+ console.log(chalk54.cyan(`
6520
7225
  ${renderStep(3, TOTAL_STEPS, "\u5F00\u59CB\u5199\u5165\u914D\u7F6E")}`));
6521
- console.log(chalk47.gray(`\u5DF2\u9009\u62E9\u5E73\u53F0: ${platforms.join(", ")}`));
7226
+ console.log(chalk54.gray(`\u5DF2\u9009\u62E9\u5E73\u53F0: ${platforms.join(", ")}`));
6522
7227
  if (platforms.includes("codex") || platforms.includes("opencode")) {
6523
- console.log(chalk47.gray(`OpenAI Base URL: ${openaiBaseUrl}`));
7228
+ console.log(chalk54.gray(`OpenAI Base URL: ${openaiBaseUrl}`));
7229
+ }
7230
+ if (platforms.includes("openclaw")) {
7231
+ console.log(chalk54.gray(`OpenClaw Base URL: ${GMN_OPENCLAW_BASE_URL}`));
6524
7232
  }
6525
7233
  printWriteTargets(platforms);
6526
7234
  console.log();
6527
7235
  const ALL_TOOLS = {
6528
7236
  codex: { name: "Codex", manager: createCodexManager() },
6529
- opencode: { name: "OpenCode", manager: createOpenCodeManager() }
7237
+ opencode: { name: "OpenCode", manager: createOpenCodeManager() },
7238
+ openclaw: { name: "OpenClaw", manager: createOpenClawManager() }
6530
7239
  };
6531
7240
  const tools = platforms.map((platform) => ({
6532
7241
  platform,
@@ -6535,34 +7244,35 @@ ${renderStep(3, TOTAL_STEPS, "\u5F00\u59CB\u5199\u5165\u914D\u7F6E")}`));
6535
7244
  let completed = 0;
6536
7245
  for (const { platform, name, manager } of tools) {
6537
7246
  try {
6538
- console.log(chalk47.gray(`\u2192 \u914D\u7F6E ${name}...`));
7247
+ console.log(chalk54.gray(`\u2192 \u914D\u7F6E ${name}...`));
6539
7248
  const baseUrl = platformBaseUrls[platform];
6540
7249
  const existing = manager.findByName(PROVIDER_NAME);
6541
7250
  const provider = existing ? manager.edit(existing.id, { baseUrl, apiKey: resolvedApiKey }) : manager.add({ name: PROVIDER_NAME, baseUrl, apiKey: resolvedApiKey });
6542
7251
  manager.switch(provider.id);
6543
7252
  completed += 1;
6544
- console.log(chalk47.green(`\u2705 ${name}`));
7253
+ console.log(chalk54.green(`\u2705 ${name}`));
6545
7254
  } catch (error) {
6546
- console.error(chalk47.red(`\u274C ${name}: ${error.message}`));
7255
+ console.error(chalk54.red(`\u274C ${name}: ${error.message}`));
6547
7256
  }
6548
7257
  }
6549
- console.log(chalk47.green(`
7258
+ console.log(chalk54.green(`
6550
7259
  \u{1F389} GMN \u914D\u7F6E\u5B8C\u6210\uFF01(${completed}/${tools.length})`));
6551
- console.log(chalk47.gray("\u63D0\u793A\uFF1A\u8BF7\u91CD\u542F\u5BF9\u5E94\u5DE5\u5177/\u63D2\u4EF6\u4EE5\u4F7F\u914D\u7F6E\u751F\u6548\u3002"));
7260
+ console.log(chalk54.gray("\u63D0\u793A\uFF1A\u8BF7\u91CD\u542F\u5BF9\u5E94\u5DE5\u5177/\u63D2\u4EF6\u4EE5\u4F7F\u914D\u7F6E\u751F\u6548\u3002"));
6552
7261
  }
6553
7262
 
6554
7263
  // src/index.ts
6555
7264
  init_dist2();
6556
7265
  if (process.env.NODE_ENV === "development") {
6557
- console.log(chalk48.gray("\n[\u5F00\u53D1\u6A21\u5F0F] \u914D\u7F6E\u76EE\u5F55:"));
6558
- console.log(chalk48.gray(` ccman: ${getCcmanDir()}`));
6559
- console.log(chalk48.gray(` codex: ${getCodexDir()}`));
6560
- console.log(chalk48.gray(` claude: ${getClaudeDir()}`));
6561
- console.log(chalk48.gray(` opencode: ${getOpenCodeDir()}`));
7266
+ console.log(chalk55.gray("\n[\u5F00\u53D1\u6A21\u5F0F] \u914D\u7F6E\u76EE\u5F55:"));
7267
+ console.log(chalk55.gray(` ccman: ${getCcmanDir()}`));
7268
+ console.log(chalk55.gray(` codex: ${getCodexDir()}`));
7269
+ console.log(chalk55.gray(` claude: ${getClaudeDir()}`));
7270
+ console.log(chalk55.gray(` opencode: ${getOpenCodeDir()}`));
7271
+ console.log(chalk55.gray(` openclaw: ${getOpenClawDir()}`));
6562
7272
  console.log();
6563
7273
  }
6564
7274
  var program = new Command3();
6565
- 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) => {
7275
+ program.name("ccman").description("Codex/Claude Code/Gemini/OpenCode/OpenClaw API \u670D\u52A1\u5546\u914D\u7F6E\u7BA1\u7406\u5DE5\u5177").version(VERSION).showHelpAfterError(false).exitOverride((err) => {
6566
7276
  if (err.code === "commander.helpDisplayed" || err.code === "commander.version") {
6567
7277
  process.exit(0);
6568
7278
  }
@@ -6570,21 +7280,33 @@ program.name("ccman").description("Codex/Claude Code/Gemini/OpenCode API \u670D\
6570
7280
  });
6571
7281
  program.on("command:*", (operands) => {
6572
7282
  const unknownCommand = operands[0];
6573
- console.error(chalk48.red(`
7283
+ console.error(chalk55.red(`
6574
7284
  \u274C \u672A\u77E5\u547D\u4EE4: ${unknownCommand}
6575
7285
  `));
6576
- const availableCommands = ["cx", "cc", "gm", "oc", "mcp", "sync", "export", "import", "gmn"];
7286
+ const availableCommands = [
7287
+ "cx",
7288
+ "cc",
7289
+ "gm",
7290
+ "oc",
7291
+ "openclaw",
7292
+ "ow",
7293
+ "mcp",
7294
+ "sync",
7295
+ "export",
7296
+ "import",
7297
+ "gmn"
7298
+ ];
6577
7299
  const suggestions = availableCommands.filter(
6578
7300
  (cmd) => cmd.includes(unknownCommand) || unknownCommand.includes(cmd)
6579
7301
  );
6580
7302
  if (suggestions.length > 0) {
6581
- console.log(chalk48.yellow("\u{1F4A1} \u4F60\u662F\u4E0D\u662F\u60F3\u8F93\u5165:"));
7303
+ console.log(chalk55.yellow("\u{1F4A1} \u4F60\u662F\u4E0D\u662F\u60F3\u8F93\u5165:"));
6582
7304
  suggestions.forEach((cmd) => {
6583
- console.log(chalk48.cyan(` ccman ${cmd}`));
7305
+ console.log(chalk55.cyan(` ccman ${cmd}`));
6584
7306
  });
6585
7307
  console.log();
6586
7308
  }
6587
- console.log(chalk48.gray("\u67E5\u770B\u6240\u6709\u53EF\u7528\u547D\u4EE4: ") + chalk48.cyan("ccman --help"));
7309
+ console.log(chalk55.gray("\u67E5\u770B\u6240\u6709\u53EF\u7528\u547D\u4EE4: ") + chalk55.cyan("ccman --help"));
6588
7310
  console.log();
6589
7311
  process.exit(1);
6590
7312
  });
@@ -6612,6 +7334,12 @@ oc.action(async () => {
6612
7334
  printLogo();
6613
7335
  await startOpenCodeMenu();
6614
7336
  });
7337
+ var openclaw = program.command("openclaw").alias("ow").description("\u7BA1\u7406 OpenClaw \u670D\u52A1\u5546");
7338
+ createOpenClawCommands(openclaw);
7339
+ openclaw.action(async () => {
7340
+ printLogo();
7341
+ await startOpenClawMenu();
7342
+ });
6615
7343
  var mcp = program.command("mcp").description("\u7BA1\u7406 MCP \u670D\u52A1\u5668");
6616
7344
  createMCPCommands(mcp);
6617
7345
  mcp.action(() => {
@@ -6625,7 +7353,7 @@ sync.action(async () => {
6625
7353
  });
6626
7354
  exportCommand(program);
6627
7355
  importCommand(program);
6628
- program.command("gmn [apiKey]").description("\u914D\u7F6E GMN \u5230 Codex \u548C OpenCode").option("-p, --platform <platforms>", "\u6307\u5B9A\u5E73\u53F0 (codex,opencode,all)").action(async (apiKey, options) => {
7356
+ program.command("gmn [apiKey]").description("\u914D\u7F6E GMN \u5230 Codex\u3001OpenCode\u3001OpenClaw").option("-p, --platform <platforms>", "\u6307\u5B9A\u5E73\u53F0 (codex,opencode,openclaw,all)").action(async (apiKey, options) => {
6629
7357
  await gmnCommand(apiKey, options.platform);
6630
7358
  });
6631
7359
  (async () => {