ccman 3.3.12 → 3.3.14-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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.12",
18
+ version: "3.3.14-beta.0",
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,216 @@ 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 parseModelMeta(raw) {
1208
+ const defaults = {
1209
+ providerKey: DEFAULT_PROVIDER_KEY,
1210
+ primaryModelId: DEFAULT_PRIMARY_MODEL_ID,
1211
+ secondaryModelId: DEFAULT_SECONDARY_MODEL_ID,
1212
+ includeSecondaryModel: true
1213
+ };
1214
+ if (!raw || !raw.trim()) {
1215
+ return defaults;
1216
+ }
1217
+ try {
1218
+ const parsed = JSON.parse(raw);
1219
+ if (!parsed || typeof parsed !== "object") {
1220
+ return defaults;
1221
+ }
1222
+ const obj = parsed;
1223
+ return {
1224
+ providerKey: (obj.providerKey || defaults.providerKey).trim(),
1225
+ primaryModelId: (obj.primaryModelId || defaults.primaryModelId).trim(),
1226
+ secondaryModelId: (obj.secondaryModelId || defaults.secondaryModelId).trim(),
1227
+ includeSecondaryModel: obj.includeSecondaryModel === void 0 ? defaults.includeSecondaryModel : Boolean(obj.includeSecondaryModel)
1228
+ };
1229
+ } catch {
1230
+ return {
1231
+ ...defaults,
1232
+ primaryModelId: raw.trim()
1233
+ };
1234
+ }
1235
+ }
1236
+ function createModel(id) {
1237
+ return {
1238
+ id,
1239
+ name: id,
1240
+ api: OPENAI_RESPONSES_API,
1241
+ reasoning: false,
1242
+ input: ["text"],
1243
+ cost: {
1244
+ input: 0,
1245
+ output: 0,
1246
+ cacheRead: 0,
1247
+ cacheWrite: 0
1248
+ },
1249
+ contextWindow: 2e5,
1250
+ maxTokens: 8192
1251
+ };
1252
+ }
1253
+ function writeOpenClawConfig(provider) {
1254
+ const configPath = getOpenClawConfigPath();
1255
+ const modelsPath = getOpenClawModelsPath();
1256
+ const homeDir = path8.dirname(getOpenClawDir());
1257
+ ensureDir(getOpenClawDir());
1258
+ ensureDir(path8.dirname(modelsPath));
1259
+ const meta = parseModelMeta(provider.model);
1260
+ const providerKey = meta.providerKey || DEFAULT_PROVIDER_KEY;
1261
+ const primaryModelId = meta.primaryModelId || DEFAULT_PRIMARY_MODEL_ID;
1262
+ const secondaryModelId = meta.secondaryModelId || DEFAULT_SECONDARY_MODEL_ID;
1263
+ const includeSecondaryModel = meta.includeSecondaryModel && secondaryModelId && secondaryModelId !== primaryModelId;
1264
+ const rawConfigTemplate = loadTemplate("openclaw/openclaw.base.template.json", OPENCLAW_CONFIG_TEMPLATE);
1265
+ const rawModelsTemplate = loadTemplate("openclaw/models.base.template.json", OPENCLAW_MODELS_TEMPLATE);
1266
+ const variables = {
1267
+ homeDir,
1268
+ providerKey,
1269
+ baseUrl: provider.baseUrl || "",
1270
+ apiKey: provider.apiKey || "",
1271
+ primaryModelId,
1272
+ secondaryModelId
1273
+ };
1274
+ const configTemplate = replaceVariables(rawConfigTemplate, variables);
1275
+ const modelsTemplate = replaceVariables(rawModelsTemplate, variables);
1276
+ const nextModelsConfig = {
1277
+ ...modelsTemplate,
1278
+ providers: {
1279
+ [providerKey]: {
1280
+ ...(modelsTemplate.providers || {})[providerKey] || {},
1281
+ baseUrl: provider.baseUrl,
1282
+ apiKey: provider.apiKey,
1283
+ api: OPENAI_RESPONSES_API,
1284
+ authHeader: true,
1285
+ headers: {
1286
+ "User-Agent": "curl/8.0",
1287
+ "OpenAI-Beta": "responses=v1"
1288
+ },
1289
+ models: includeSecondaryModel ? [createModel(primaryModelId), createModel(secondaryModelId)] : [createModel(primaryModelId)]
1290
+ }
1291
+ }
1292
+ };
1293
+ const defaults = configTemplate.agents?.defaults || {};
1294
+ const nextOpenClawConfig = {
1295
+ ...configTemplate,
1296
+ models: {
1297
+ ...configTemplate.models || {},
1298
+ mode: configTemplate.models?.mode || "merge",
1299
+ providers: configTemplate.models?.providers || {}
1300
+ },
1301
+ agents: {
1302
+ ...configTemplate.agents || {},
1303
+ defaults: {
1304
+ ...defaults,
1305
+ workspace: homeDir,
1306
+ model: {
1307
+ ...defaults.model || {},
1308
+ primary: `${providerKey}/${primaryModelId}`
1309
+ },
1310
+ thinkingDefault: defaults.thinkingDefault || "xhigh"
1311
+ }
1312
+ }
1313
+ };
1314
+ writeJSON(configPath, nextOpenClawConfig);
1315
+ writeJSON(modelsPath, nextModelsConfig);
1316
+ }
1317
+ var DEFAULT_PROVIDER_KEY, DEFAULT_PRIMARY_MODEL_ID, DEFAULT_SECONDARY_MODEL_ID, OPENAI_RESPONSES_API, __filename5, __dirname5, OPENCLAW_CONFIG_TEMPLATE, OPENCLAW_MODELS_TEMPLATE;
1318
+ var init_openclaw2 = __esm({
1319
+ "../core/dist/writers/openclaw.js"() {
1320
+ "use strict";
1321
+ init_paths();
1322
+ init_file();
1323
+ init_template();
1324
+ DEFAULT_PROVIDER_KEY = "sub2api";
1325
+ DEFAULT_PRIMARY_MODEL_ID = "gpt-5.3-codex";
1326
+ DEFAULT_SECONDARY_MODEL_ID = "gpt-5.2-codex";
1327
+ OPENAI_RESPONSES_API = "openai-responses";
1328
+ __filename5 = fileURLToPath5(import.meta.url);
1329
+ __dirname5 = path8.dirname(__filename5);
1330
+ OPENCLAW_CONFIG_TEMPLATE = {
1331
+ models: {
1332
+ mode: "merge",
1333
+ providers: {}
1334
+ },
1335
+ agents: {
1336
+ defaults: {
1337
+ workspace: "",
1338
+ model: {
1339
+ primary: `${DEFAULT_PROVIDER_KEY}/${DEFAULT_PRIMARY_MODEL_ID}`
1340
+ },
1341
+ thinkingDefault: "xhigh"
1342
+ }
1343
+ }
1344
+ };
1345
+ OPENCLAW_MODELS_TEMPLATE = {
1346
+ providers: {
1347
+ [DEFAULT_PROVIDER_KEY]: {
1348
+ baseUrl: "https://gmn.chuangzuoli.com/v1",
1349
+ apiKey: "",
1350
+ api: OPENAI_RESPONSES_API,
1351
+ authHeader: true,
1352
+ headers: {
1353
+ "User-Agent": "curl/8.0",
1354
+ "OpenAI-Beta": "responses=v1"
1355
+ },
1356
+ models: [
1357
+ {
1358
+ id: DEFAULT_PRIMARY_MODEL_ID,
1359
+ name: DEFAULT_PRIMARY_MODEL_ID,
1360
+ api: OPENAI_RESPONSES_API,
1361
+ reasoning: false,
1362
+ input: ["text"],
1363
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
1364
+ contextWindow: 2e5,
1365
+ maxTokens: 8192
1366
+ },
1367
+ {
1368
+ id: DEFAULT_SECONDARY_MODEL_ID,
1369
+ name: DEFAULT_SECONDARY_MODEL_ID,
1370
+ api: OPENAI_RESPONSES_API,
1371
+ reasoning: false,
1372
+ input: ["text"],
1373
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
1374
+ contextWindow: 2e5,
1375
+ maxTokens: 8192
1376
+ }
1377
+ ]
1378
+ }
1379
+ }
1380
+ };
1381
+ }
1382
+ });
1383
+
1137
1384
  // ../core/dist/tool-manager.types.js
1138
1385
  var ProviderNotFoundError, ProviderNameConflictError, PresetNameConflictError;
1139
1386
  var init_tool_manager_types = __esm({
@@ -1161,7 +1408,7 @@ var init_tool_manager_types = __esm({
1161
1408
  });
1162
1409
 
1163
1410
  // ../core/dist/tool-manager.js
1164
- import * as path8 from "path";
1411
+ import * as path9 from "path";
1165
1412
  function createToolManager(tool) {
1166
1413
  const toolConfig = TOOL_CONFIGS[tool];
1167
1414
  const configPath = toolConfig.configPath;
@@ -1475,6 +1722,9 @@ function createGeminiManager() {
1475
1722
  function createOpenCodeManager() {
1476
1723
  return createToolManager("opencode");
1477
1724
  }
1725
+ function createOpenClawManager() {
1726
+ return createToolManager("openclaw");
1727
+ }
1478
1728
  var TOOL_CONFIGS;
1479
1729
  var init_tool_manager = __esm({
1480
1730
  "../core/dist/tool-manager.js"() {
@@ -1489,22 +1739,24 @@ var init_tool_manager = __esm({
1489
1739
  init_mcp2();
1490
1740
  init_gemini();
1491
1741
  init_opencode();
1742
+ init_openclaw();
1492
1743
  init_gemini2();
1493
1744
  init_opencode2();
1745
+ init_openclaw2();
1494
1746
  init_tool_manager_types();
1495
1747
  TOOL_CONFIGS = {
1496
1748
  codex: {
1497
- configPath: path8.join(getCcmanDir(), "codex.json"),
1749
+ configPath: path9.join(getCcmanDir(), "codex.json"),
1498
1750
  builtinPresets: CODEX_PRESETS,
1499
1751
  writer: writeCodexConfig
1500
1752
  },
1501
1753
  claude: {
1502
- configPath: path8.join(getCcmanDir(), "claude.json"),
1754
+ configPath: path9.join(getCcmanDir(), "claude.json"),
1503
1755
  builtinPresets: CC_PRESETS,
1504
1756
  writer: writeClaudeConfig
1505
1757
  },
1506
1758
  mcp: {
1507
- configPath: path8.join(getCcmanDir(), "mcp.json"),
1759
+ configPath: path9.join(getCcmanDir(), "mcp.json"),
1508
1760
  builtinPresets: MCP_PRESETS,
1509
1761
  writer: writeMCPConfig,
1510
1762
  autoSync: true,
@@ -1534,14 +1786,19 @@ var init_tool_manager = __esm({
1534
1786
  }
1535
1787
  },
1536
1788
  gemini: {
1537
- configPath: path8.join(getCcmanDir(), "gemini.json"),
1789
+ configPath: path9.join(getCcmanDir(), "gemini.json"),
1538
1790
  builtinPresets: GEMINI_PRESETS,
1539
1791
  writer: writeGeminiConfig
1540
1792
  },
1541
1793
  opencode: {
1542
- configPath: path8.join(getCcmanDir(), "opencode.json"),
1794
+ configPath: path9.join(getCcmanDir(), "opencode.json"),
1543
1795
  builtinPresets: OPENCODE_PRESETS,
1544
1796
  writer: writeOpenCodeConfig
1797
+ },
1798
+ openclaw: {
1799
+ configPath: path9.join(getCcmanDir(), "openclaw.json"),
1800
+ builtinPresets: OPENCLAW_PRESETS,
1801
+ writer: writeOpenClawConfig
1545
1802
  }
1546
1803
  };
1547
1804
  }
@@ -1556,20 +1813,20 @@ var init_migrate = __esm({
1556
1813
  });
1557
1814
 
1558
1815
  // ../core/dist/config.js
1559
- import * as fs7 from "fs";
1816
+ import * as fs8 from "fs";
1560
1817
  function ensureConfigDir() {
1561
1818
  const dir = getCcmanDir();
1562
- if (!fs7.existsSync(dir)) {
1563
- fs7.mkdirSync(dir, { recursive: true, mode: 448 });
1819
+ if (!fs8.existsSync(dir)) {
1820
+ fs8.mkdirSync(dir, { recursive: true, mode: 448 });
1564
1821
  }
1565
1822
  }
1566
1823
  function loadConfig() {
1567
1824
  const configPath = getConfigPath();
1568
- if (!fs7.existsSync(configPath)) {
1825
+ if (!fs8.existsSync(configPath)) {
1569
1826
  return {};
1570
1827
  }
1571
1828
  try {
1572
- const content = fs7.readFileSync(configPath, "utf-8");
1829
+ const content = fs8.readFileSync(configPath, "utf-8");
1573
1830
  return JSON.parse(content);
1574
1831
  } catch (error) {
1575
1832
  throw new Error(`Failed to load config: ${error.message}`);
@@ -1580,10 +1837,10 @@ function saveConfig(config) {
1580
1837
  const configPath = getConfigPath();
1581
1838
  try {
1582
1839
  const tempPath = `${configPath}.tmp`;
1583
- fs7.writeFileSync(tempPath, JSON.stringify(config, null, 2), {
1840
+ fs8.writeFileSync(tempPath, JSON.stringify(config, null, 2), {
1584
1841
  mode: 384
1585
1842
  });
1586
- fs7.renameSync(tempPath, configPath);
1843
+ fs8.renameSync(tempPath, configPath);
1587
1844
  } catch (error) {
1588
1845
  throw new Error(`Failed to save config: ${error.message}`);
1589
1846
  }
@@ -1915,24 +2172,24 @@ var init_merge_advanced = __esm({
1915
2172
  });
1916
2173
 
1917
2174
  // ../core/dist/sync/merge.js
1918
- import fs8 from "fs";
1919
- import path9 from "path";
2175
+ import fs9 from "fs";
2176
+ import path10 from "path";
1920
2177
  function backupConfig(configPath, keepCount = 3) {
1921
- if (!fs8.existsSync(configPath)) {
2178
+ if (!fs9.existsSync(configPath)) {
1922
2179
  throw new Error(`\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728: ${configPath}`);
1923
2180
  }
1924
2181
  const timestamp = Date.now();
1925
2182
  const backupPath = `${configPath}.backup.${timestamp}`;
1926
- fs8.copyFileSync(configPath, backupPath);
2183
+ fs9.copyFileSync(configPath, backupPath);
1927
2184
  cleanupOldBackups(configPath, keepCount);
1928
2185
  return backupPath;
1929
2186
  }
1930
2187
  function cleanupOldBackups(configPath, keepCount) {
1931
- const dir = path9.dirname(configPath);
1932
- const basename = path9.basename(configPath);
2188
+ const dir = path10.dirname(configPath);
2189
+ const basename = path10.basename(configPath);
1933
2190
  const backupPrefix = `${basename}.backup.`;
1934
2191
  try {
1935
- const files = fs8.readdirSync(dir);
2192
+ const files = fs9.readdirSync(dir);
1936
2193
  const backups = files.filter((f) => f.startsWith(backupPrefix)).map((f) => {
1937
2194
  const timestampStr = f.substring(backupPrefix.length);
1938
2195
  const timestamp = parseInt(timestampStr, 10);
@@ -1941,14 +2198,14 @@ function cleanupOldBackups(configPath, keepCount) {
1941
2198
  }
1942
2199
  return {
1943
2200
  name: f,
1944
- path: path9.join(dir, f),
2201
+ path: path10.join(dir, f),
1945
2202
  timestamp
1946
2203
  };
1947
2204
  }).filter((backup) => backup !== null).sort((a, b) => b.timestamp - a.timestamp);
1948
2205
  const toDelete = backups.slice(keepCount);
1949
2206
  for (const backup of toDelete) {
1950
2207
  try {
1951
- fs8.unlinkSync(backup.path);
2208
+ fs9.unlinkSync(backup.path);
1952
2209
  } catch (error) {
1953
2210
  console.warn(`\u65E0\u6CD5\u5220\u9664\u65E7\u5907\u4EFD\u6587\u4EF6 ${backup.name}: ${error.message}`);
1954
2211
  }
@@ -1964,15 +2221,31 @@ var init_merge = __esm({
1964
2221
  });
1965
2222
 
1966
2223
  // ../core/dist/sync/sync-v2.js
1967
- import fs9 from "fs";
1968
- import path10 from "path";
2224
+ import fs10 from "fs";
2225
+ import path11 from "path";
2226
+ function createEmptyToolConfig() {
2227
+ return {
2228
+ providers: [],
2229
+ presets: []
2230
+ };
2231
+ }
2232
+ function readLocalConfigOrEmpty(configPath) {
2233
+ if (!fileExists(configPath)) {
2234
+ return createEmptyToolConfig();
2235
+ }
2236
+ return readJSON(configPath);
2237
+ }
1969
2238
  async function uploadToCloud(config, password) {
1970
2239
  const ccmanDir2 = getCcmanDir();
1971
2240
  const toolKeys = Object.keys(TOOL_SYNC_CONFIG);
2241
+ let uploadedCount = 0;
1972
2242
  for (const tool of toolKeys) {
1973
2243
  const { remotePath, configFilename } = TOOL_SYNC_CONFIG[tool];
1974
- const configPath = path10.join(ccmanDir2, configFilename);
1975
- const localConfig = readJSON(configPath);
2244
+ const configPath = path11.join(ccmanDir2, configFilename);
2245
+ if (!fileExists(configPath)) {
2246
+ continue;
2247
+ }
2248
+ const localConfig = readLocalConfigOrEmpty(configPath);
1976
2249
  const encryptedProviders = encryptProviders(localConfig.providers, password);
1977
2250
  const encryptedConfig = {
1978
2251
  ...localConfig,
@@ -1982,6 +2255,10 @@ async function uploadToCloud(config, password) {
1982
2255
  };
1983
2256
  const jsonContent = JSON.stringify(encryptedConfig, null, 2);
1984
2257
  await uploadToWebDAV(config, remotePath, jsonContent);
2258
+ uploadedCount += 1;
2259
+ }
2260
+ if (uploadedCount === 0) {
2261
+ throw new Error("\u672C\u5730\u672A\u627E\u5230\u53EF\u4E0A\u4F20\u7684\u914D\u7F6E\u6587\u4EF6");
1985
2262
  }
1986
2263
  updateLastSyncTime();
1987
2264
  console.log("\u2705 \u914D\u7F6E\u5DF2\u4E0A\u4F20\u5230\u4E91\u7AEF");
@@ -2017,8 +2294,8 @@ async function downloadFromCloud(config, password) {
2017
2294
  try {
2018
2295
  for (const tool of toolKeys) {
2019
2296
  const { configFilename } = TOOL_SYNC_CONFIG[tool];
2020
- const configPath = path10.join(ccmanDir2, configFilename);
2021
- if (fs9.existsSync(configPath)) {
2297
+ const configPath = path11.join(ccmanDir2, configFilename);
2298
+ if (fs10.existsSync(configPath)) {
2022
2299
  backupPaths.push(backupConfig(configPath));
2023
2300
  }
2024
2301
  }
@@ -2030,7 +2307,7 @@ async function downloadFromCloud(config, password) {
2030
2307
  if (!remoteConfig || !decryptedProviders)
2031
2308
  continue;
2032
2309
  const { configFilename } = TOOL_SYNC_CONFIG[tool];
2033
- const configPath = path10.join(ccmanDir2, configFilename);
2310
+ const configPath = path11.join(ccmanDir2, configFilename);
2034
2311
  const newConfig = {
2035
2312
  ...remoteConfig,
2036
2313
  // 使用云端配置的所有字段
@@ -2046,8 +2323,8 @@ async function downloadFromCloud(config, password) {
2046
2323
  } catch (error) {
2047
2324
  for (const backupPath of backupPaths) {
2048
2325
  const originalPath = backupPath.replace(/\.backup\.\d+$/, "");
2049
- if (fs9.existsSync(backupPath)) {
2050
- fs9.copyFileSync(backupPath, originalPath);
2326
+ if (fs10.existsSync(backupPath)) {
2327
+ fs10.copyFileSync(backupPath, originalPath);
2051
2328
  }
2052
2329
  }
2053
2330
  throw new Error(`\u8986\u76D6\u914D\u7F6E\u5931\u8D25\uFF0C\u5DF2\u6062\u590D\u5907\u4EFD: ${error.message}`);
@@ -2072,8 +2349,8 @@ async function mergeSync(config, password) {
2072
2349
  for (let i = 0; i < toolKeys.length; i++) {
2073
2350
  const tool = toolKeys[i];
2074
2351
  const { remotePath, configFilename } = TOOL_SYNC_CONFIG[tool];
2075
- const configPath = path10.join(ccmanDir2, configFilename);
2076
- const localConfig = readJSON(configPath);
2352
+ const configPath = path11.join(ccmanDir2, configFilename);
2353
+ const localConfig = readLocalConfigOrEmpty(configPath);
2077
2354
  let remoteProviders = [];
2078
2355
  if (existsChecks[i]) {
2079
2356
  try {
@@ -2104,8 +2381,8 @@ async function mergeSync(config, password) {
2104
2381
  try {
2105
2382
  for (const tool of toolKeys) {
2106
2383
  const { configFilename } = TOOL_SYNC_CONFIG[tool];
2107
- const configPath = path10.join(ccmanDir2, configFilename);
2108
- if (fs9.existsSync(configPath)) {
2384
+ const configPath = path11.join(ccmanDir2, configFilename);
2385
+ if (fs10.existsSync(configPath)) {
2109
2386
  backupPaths.push(backupConfig(configPath));
2110
2387
  }
2111
2388
  }
@@ -2116,7 +2393,7 @@ async function mergeSync(config, password) {
2116
2393
  for (let i = 0; i < mergeDataList.length; i++) {
2117
2394
  const { tool, localConfig, mergeResult } = mergeDataList[i];
2118
2395
  const { remotePath, configFilename } = TOOL_SYNC_CONFIG[tool];
2119
- const configPath = path10.join(ccmanDir2, configFilename);
2396
+ const configPath = path11.join(ccmanDir2, configFilename);
2120
2397
  let remoteConfig = null;
2121
2398
  if (existsChecks[i]) {
2122
2399
  const jsonContent2 = await downloadFromWebDAV(config, remotePath);
@@ -2131,6 +2408,10 @@ async function mergeSync(config, password) {
2131
2408
  presets: mergedPresets
2132
2409
  // 替换为合并后的 presets
2133
2410
  };
2411
+ const shouldPersist = fileExists(configPath) || existsChecks[i] || mergeResult.merged.length > 0 || mergedPresets && mergedPresets.length > 0;
2412
+ if (!shouldPersist) {
2413
+ continue;
2414
+ }
2134
2415
  writeJSON(configPath, mergedConfig);
2135
2416
  applyCurrentProvider(tool, mergedConfig);
2136
2417
  const encryptedProviders = encryptProviders(mergeResult.merged, password);
@@ -2152,8 +2433,8 @@ async function mergeSync(config, password) {
2152
2433
  } catch (error) {
2153
2434
  for (const backupPath of backupPaths) {
2154
2435
  const originalPath = backupPath.replace(/\.backup\.\d+$/, "");
2155
- if (fs9.existsSync(backupPath)) {
2156
- fs9.copyFileSync(backupPath, originalPath);
2436
+ if (fs10.existsSync(backupPath)) {
2437
+ fs10.copyFileSync(backupPath, originalPath);
2157
2438
  }
2158
2439
  }
2159
2440
  throw new Error(`\u5408\u5E76\u914D\u7F6E\u5931\u8D25\uFF0C\u5DF2\u6062\u590D\u5907\u4EFD: ${error.message}`);
@@ -2184,6 +2465,7 @@ var init_sync_v2 = __esm({
2184
2465
  init_codex();
2185
2466
  init_claude();
2186
2467
  init_gemini2();
2468
+ init_openclaw2();
2187
2469
  init_constants();
2188
2470
  TOOL_SYNC_CONFIG = {
2189
2471
  [MAIN_TOOL_TYPES.CODEX]: {
@@ -2200,33 +2482,35 @@ var init_sync_v2 = __esm({
2200
2482
  remotePath: ".ccman/gemini.json",
2201
2483
  configFilename: "gemini.json",
2202
2484
  writerFunc: writeGeminiConfig
2485
+ },
2486
+ [MAIN_TOOL_TYPES.OPENCLAW]: {
2487
+ remotePath: ".ccman/openclaw.json",
2488
+ configFilename: "openclaw.json",
2489
+ writerFunc: writeOpenClawConfig
2203
2490
  }
2204
2491
  };
2205
2492
  }
2206
2493
  });
2207
2494
 
2208
2495
  // ../core/dist/export.js
2209
- import * as fs10 from "fs";
2210
- import * as path11 from "path";
2496
+ import * as fs11 from "fs";
2497
+ import * as path12 from "path";
2211
2498
  function validateExport() {
2212
2499
  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) {
2500
+ const foundFiles = SUPPORTED_CONFIG_FILES.filter((filename) => fileExists(path12.join(ccmanDir2, filename)));
2501
+ if (foundFiles.length === 0) {
2223
2502
  return {
2224
2503
  valid: false,
2225
- message: `\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728: ${missingFiles.join(", ")}`,
2226
- missingFiles
2504
+ message: `\u672A\u627E\u5230\u53EF\u5BFC\u51FA\u7684\u914D\u7F6E\u6587\u4EF6 (${SUPPORTED_CONFIG_FILES.join(" / ")})`,
2505
+ missingFiles: [...SUPPORTED_CONFIG_FILES],
2506
+ foundFiles: []
2227
2507
  };
2228
2508
  }
2229
- return { valid: true };
2509
+ return {
2510
+ valid: true,
2511
+ foundFiles,
2512
+ missingFiles: SUPPORTED_CONFIG_FILES.filter((file) => !foundFiles.includes(file))
2513
+ };
2230
2514
  }
2231
2515
  function validateImportDir(sourceDir) {
2232
2516
  if (!fileExists(sourceDir)) {
@@ -2236,7 +2520,7 @@ function validateImportDir(sourceDir) {
2236
2520
  foundFiles: []
2237
2521
  };
2238
2522
  }
2239
- const stats = fs10.statSync(sourceDir);
2523
+ const stats = fs11.statSync(sourceDir);
2240
2524
  if (!stats.isDirectory()) {
2241
2525
  return {
2242
2526
  valid: false,
@@ -2244,19 +2528,11 @@ function validateImportDir(sourceDir) {
2244
2528
  foundFiles: []
2245
2529
  };
2246
2530
  }
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
- }
2531
+ const foundFiles = SUPPORTED_CONFIG_FILES.filter((filename) => fileExists(path12.join(sourceDir, filename)));
2256
2532
  if (foundFiles.length === 0) {
2257
2533
  return {
2258
2534
  valid: false,
2259
- message: `\u672A\u627E\u5230\u914D\u7F6E\u6587\u4EF6 (${CODEX_CONFIG_FILE} \u6216 ${CLAUDE_CONFIG_FILE})`,
2535
+ message: `\u672A\u627E\u5230\u914D\u7F6E\u6587\u4EF6 (${SUPPORTED_CONFIG_FILES.join(" / ")})`,
2260
2536
  foundFiles: []
2261
2537
  };
2262
2538
  }
@@ -2273,17 +2549,14 @@ function exportConfig(targetDir) {
2273
2549
  ensureDir(targetDir);
2274
2550
  const ccmanDir2 = getCcmanDir();
2275
2551
  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);
2552
+ const filesToExport = validation.foundFiles || [];
2553
+ for (const file of filesToExport) {
2554
+ const src = path12.join(ccmanDir2, file);
2555
+ const dst = path12.join(targetDir, file);
2556
+ if (fileExists(src)) {
2557
+ fs11.copyFileSync(src, dst);
2558
+ exportedFiles.push(file);
2559
+ }
2287
2560
  }
2288
2561
  return {
2289
2562
  success: true,
@@ -2301,25 +2574,15 @@ function importConfig(sourceDir) {
2301
2574
  const importedFiles = [];
2302
2575
  ensureDir(ccmanDir2);
2303
2576
  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);
2308
- backupPaths.push(backupPath);
2309
- }
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);
2577
+ for (const file of validation.foundFiles) {
2578
+ const targetPath = path12.join(ccmanDir2, file);
2579
+ const sourcePath = path12.join(sourceDir, file);
2580
+ if (fileExists(targetPath)) {
2581
+ const backupPath = backupConfig(targetPath);
2318
2582
  backupPaths.push(backupPath);
2319
2583
  }
2320
- const claudeSrc = path11.join(sourceDir, CLAUDE_CONFIG_FILE);
2321
- fs10.copyFileSync(claudeSrc, claudeDst);
2322
- importedFiles.push(CLAUDE_CONFIG_FILE);
2584
+ fs11.copyFileSync(sourcePath, targetPath);
2585
+ importedFiles.push(file);
2323
2586
  }
2324
2587
  return {
2325
2588
  success: true,
@@ -2330,26 +2593,25 @@ function importConfig(sourceDir) {
2330
2593
  for (const backupPath of backupPaths) {
2331
2594
  const originalPath = backupPath.replace(/\.backup\.\d+$/, "");
2332
2595
  if (fileExists(backupPath)) {
2333
- fs10.copyFileSync(backupPath, originalPath);
2596
+ fs11.copyFileSync(backupPath, originalPath);
2334
2597
  }
2335
2598
  }
2336
2599
  throw new Error(`\u5BFC\u5165\u5931\u8D25\uFF0C\u5DF2\u6062\u590D\u5907\u4EFD: ${error.message}`);
2337
2600
  }
2338
2601
  }
2339
- var CODEX_CONFIG_FILE, CLAUDE_CONFIG_FILE;
2602
+ var SUPPORTED_CONFIG_FILES;
2340
2603
  var init_export = __esm({
2341
2604
  "../core/dist/export.js"() {
2342
2605
  "use strict";
2343
2606
  init_paths();
2344
2607
  init_file();
2345
2608
  init_merge();
2346
- CODEX_CONFIG_FILE = "codex.json";
2347
- CLAUDE_CONFIG_FILE = "claude.json";
2609
+ SUPPORTED_CONFIG_FILES = ["codex.json", "claude.json", "openclaw.json"];
2348
2610
  }
2349
2611
  });
2350
2612
 
2351
2613
  // ../core/dist/claude-clean.js
2352
- import * as fs11 from "fs";
2614
+ import * as fs12 from "fs";
2353
2615
  function formatBytes(bytes) {
2354
2616
  if (bytes < 1024)
2355
2617
  return `${bytes} B`;
@@ -2359,7 +2621,7 @@ function formatBytes(bytes) {
2359
2621
  }
2360
2622
  function getFileSize(filePath) {
2361
2623
  try {
2362
- const stats = fs11.statSync(filePath);
2624
+ const stats = fs12.statSync(filePath);
2363
2625
  return stats.size;
2364
2626
  } catch {
2365
2627
  return 0;
@@ -2368,18 +2630,18 @@ function getFileSize(filePath) {
2368
2630
  function backupFile2(filePath) {
2369
2631
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/:/g, "-").split(".")[0];
2370
2632
  const backupPath = `${filePath}.backup-${timestamp}`;
2371
- fs11.copyFileSync(filePath, backupPath);
2633
+ fs12.copyFileSync(filePath, backupPath);
2372
2634
  return backupPath;
2373
2635
  }
2374
2636
  function saveJsonAtomic(filePath, data) {
2375
2637
  const tempPath = `${filePath}.tmp`;
2376
2638
  const content = JSON.stringify(data, null, 2);
2377
- fs11.writeFileSync(tempPath, content, { mode: 384 });
2378
- fs11.renameSync(tempPath, filePath);
2639
+ fs12.writeFileSync(tempPath, content, { mode: 384 });
2640
+ fs12.renameSync(tempPath, filePath);
2379
2641
  }
2380
2642
  function analyzeClaudeJson() {
2381
2643
  const filePath = getClaudeJsonPath();
2382
- if (!fs11.existsSync(filePath)) {
2644
+ if (!fs12.existsSync(filePath)) {
2383
2645
  return {
2384
2646
  fileSize: 0,
2385
2647
  fileSizeFormatted: "0 B",
@@ -2395,7 +2657,7 @@ function analyzeClaudeJson() {
2395
2657
  };
2396
2658
  }
2397
2659
  const fileSize = getFileSize(filePath);
2398
- const content = fs11.readFileSync(filePath, "utf-8");
2660
+ const content = fs12.readFileSync(filePath, "utf-8");
2399
2661
  const config = JSON.parse(content);
2400
2662
  const projects = config.projects || {};
2401
2663
  const projectHistory = [];
@@ -2429,12 +2691,12 @@ function analyzeClaudeJson() {
2429
2691
  }
2430
2692
  function cleanClaudeJson(options = {}) {
2431
2693
  const filePath = getClaudeJsonPath();
2432
- if (!fs11.existsSync(filePath)) {
2694
+ if (!fs12.existsSync(filePath)) {
2433
2695
  throw new Error(`${filePath} \u6587\u4EF6\u4E0D\u5B58\u5728`);
2434
2696
  }
2435
2697
  const backupPath = backupFile2(filePath);
2436
2698
  const sizeBefore = getFileSize(filePath);
2437
- const content = fs11.readFileSync(filePath, "utf-8");
2699
+ const content = fs12.readFileSync(filePath, "utf-8");
2438
2700
  const config = JSON.parse(content);
2439
2701
  const cleanedItems = applyCleanOptions(config, options);
2440
2702
  saveJsonAtomic(filePath, config);
@@ -2522,6 +2784,7 @@ var init_dist2 = __esm({
2522
2784
  init_mcp2();
2523
2785
  init_gemini();
2524
2786
  init_opencode();
2787
+ init_openclaw();
2525
2788
  init_mcp();
2526
2789
  init_migrate();
2527
2790
  init_paths();
@@ -2889,12 +3152,18 @@ function uploadCommand(program2) {
2889
3152
  }
2890
3153
  const codexManager = createCodexManager();
2891
3154
  const claudeManager = createClaudeManager();
3155
+ const geminiManager = createGeminiManager();
3156
+ const openclawManager = createOpenClawManager();
2892
3157
  const codexProviders = codexManager.list();
2893
3158
  const claudeProviders = claudeManager.list();
3159
+ const geminiProviders = geminiManager.list();
3160
+ const openclawProviders = openclawManager.list();
2894
3161
  console.log(chalk6.bold("\n\u{1F4E4} \u4E0A\u4F20\u914D\u7F6E\u5230\u4E91\u7AEF\n"));
2895
3162
  console.log("\u914D\u7F6E\u4FE1\u606F:");
2896
3163
  console.log(` Codex \u670D\u52A1\u5546: ${chalk6.cyan(codexProviders.length)} \u4E2A`);
2897
3164
  console.log(` Claude \u670D\u52A1\u5546: ${chalk6.cyan(claudeProviders.length)} \u4E2A`);
3165
+ console.log(` Gemini \u670D\u52A1\u5546: ${chalk6.cyan(geminiProviders.length)} \u4E2A`);
3166
+ console.log(` OpenClaw \u670D\u52A1\u5546: ${chalk6.cyan(openclawProviders.length)} \u4E2A`);
2898
3167
  console.log();
2899
3168
  console.log(chalk6.yellow("\u26A0\uFE0F \u4E91\u7AEF\u73B0\u6709\u914D\u7F6E\u5C06\u88AB\u8986\u76D6"));
2900
3169
  console.log();
@@ -2920,6 +3189,8 @@ function uploadCommand(program2) {
2920
3189
  console.log(chalk6.gray("\u8FDC\u7A0B\u6587\u4EF6:"));
2921
3190
  console.log(chalk6.gray(` ${config.webdavUrl}${config.remoteDir}/.ccman/codex.json`));
2922
3191
  console.log(chalk6.gray(` ${config.webdavUrl}${config.remoteDir}/.ccman/claude.json`));
3192
+ console.log(chalk6.gray(` ${config.webdavUrl}${config.remoteDir}/.ccman/gemini.json`));
3193
+ console.log(chalk6.gray(` ${config.webdavUrl}${config.remoteDir}/.ccman/openclaw.json`));
2923
3194
  console.log();
2924
3195
  console.log(chalk6.blue("\u{1F4A1} \u5176\u4ED6\u8BBE\u5907\u53EF\u901A\u8FC7 'ccman sync download' \u83B7\u53D6\u914D\u7F6E\n"));
2925
3196
  } catch (error) {
@@ -2990,8 +3261,8 @@ function downloadCommand(program2) {
2990
3261
  console.log();
2991
3262
  if (backupPaths.length > 0) {
2992
3263
  console.log(chalk7.gray("\u672C\u5730\u5907\u4EFD:"));
2993
- backupPaths.forEach((path14) => {
2994
- console.log(chalk7.gray(` ${path14}`));
3264
+ backupPaths.forEach((path15) => {
3265
+ console.log(chalk7.gray(` ${path15}`));
2995
3266
  });
2996
3267
  console.log();
2997
3268
  }
@@ -3052,8 +3323,8 @@ function mergeCommand(program2) {
3052
3323
  console.log();
3053
3324
  if (result.backupPaths.length > 0) {
3054
3325
  console.log(chalk8.gray("\u5907\u4EFD:"));
3055
- result.backupPaths.forEach((path14) => {
3056
- console.log(chalk8.gray(` ${path14}`));
3326
+ result.backupPaths.forEach((path15) => {
3327
+ console.log(chalk8.gray(` ${path15}`));
3057
3328
  });
3058
3329
  console.log();
3059
3330
  }
@@ -3098,16 +3369,26 @@ function statusCommand(program2) {
3098
3369
  console.log(` URL: ${chalk9.gray(config.webdavUrl)}`);
3099
3370
  console.log(` \u7528\u6237: ${chalk9.gray(config.username)}`);
3100
3371
  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")}`);
3372
+ console.log(
3373
+ ` \u8BA4\u8BC1: ${chalk9.gray(config.authType === "password" ? "Basic Auth" : "Digest Auth")}`
3374
+ );
3375
+ console.log(
3376
+ ` \u540C\u6B65\u5BC6\u7801: ${config.syncPassword ? chalk9.green("\u2713 \u5DF2\u4FDD\u5B58") : chalk9.yellow("\u2717 \u672A\u4FDD\u5B58")}`
3377
+ );
3103
3378
  console.log();
3104
3379
  const codexManager = createCodexManager();
3105
3380
  const claudeManager = createClaudeManager();
3381
+ const geminiManager = createGeminiManager();
3382
+ const openclawManager = createOpenClawManager();
3106
3383
  const codexProviders = codexManager.list();
3107
3384
  const claudeProviders = claudeManager.list();
3385
+ const geminiProviders = geminiManager.list();
3386
+ const openclawProviders = openclawManager.list();
3108
3387
  console.log(chalk9.bold("\u672C\u5730\u914D\u7F6E:"));
3109
3388
  console.log(` Codex: ${chalk9.cyan(codexProviders.length)} \u4E2A\u670D\u52A1\u5546`);
3110
3389
  console.log(` Claude: ${chalk9.cyan(claudeProviders.length)} \u4E2A\u670D\u52A1\u5546`);
3390
+ console.log(` Gemini: ${chalk9.cyan(geminiProviders.length)} \u4E2A\u670D\u52A1\u5546`);
3391
+ console.log(` OpenClaw: ${chalk9.cyan(openclawProviders.length)} \u4E2A\u670D\u52A1\u5546`);
3111
3392
  if (config.lastSync) {
3112
3393
  const date = new Date(config.lastSync).toLocaleString("zh-CN");
3113
3394
  console.log(` \u6700\u540E\u540C\u6B65: ${chalk9.gray(date)}`);
@@ -3245,7 +3526,7 @@ var init_sync = __esm({
3245
3526
 
3246
3527
  // src/index.ts
3247
3528
  import { Command as Command3 } from "commander";
3248
- import chalk48 from "chalk";
3529
+ import chalk55 from "chalk";
3249
3530
 
3250
3531
  // src/utils/logo.ts
3251
3532
  init_dist2();
@@ -3308,7 +3589,8 @@ var CLI_TOOL_CONFIG = {
3308
3589
  [TOOL_TYPES.CODEX]: { name: "Codex", emoji: "\u{1F536}", cmd: "cx" },
3309
3590
  [TOOL_TYPES.CLAUDE]: { name: "Claude", emoji: "\u{1F537}", cmd: "cc" },
3310
3591
  [TOOL_TYPES.GEMINI]: { name: "Gemini", emoji: "\u{1F48E}", cmd: "gm" },
3311
- [TOOL_TYPES.OPENCODE]: { name: "OpenCode", emoji: "\u{1F9E9}", cmd: "oc" }
3592
+ [TOOL_TYPES.OPENCODE]: { name: "OpenCode", emoji: "\u{1F9E9}", cmd: "oc" },
3593
+ [TOOL_TYPES.OPENCLAW]: { name: "OpenClaw", emoji: "\u{1F980}", cmd: "ow" }
3312
3594
  };
3313
3595
  function getManager(tool) {
3314
3596
  switch (tool) {
@@ -3320,6 +3602,8 @@ function getManager(tool) {
3320
3602
  return createGeminiManager();
3321
3603
  case TOOL_TYPES.OPENCODE:
3322
3604
  return createOpenCodeManager();
3605
+ case TOOL_TYPES.OPENCLAW:
3606
+ return createOpenClawManager();
3323
3607
  }
3324
3608
  }
3325
3609
  async function promptProviderForm(defaults) {
@@ -3386,6 +3670,7 @@ async function startMainMenu() {
3386
3670
  { name: "\u{1F536} Codex \u7BA1\u7406", value: "codex" },
3387
3671
  { name: "\u{1F48E} Gemini \u7BA1\u7406", value: "gemini" },
3388
3672
  { name: "\u{1F9E9} OpenCode \u7BA1\u7406", value: "opencode" },
3673
+ { name: "\u{1F980} OpenClaw \u7BA1\u7406", value: "openclaw" },
3389
3674
  { name: "\u{1F504} WebDAV \u540C\u6B65", value: "sync" },
3390
3675
  { name: "\u{1F4E6} \u9884\u7F6E\u670D\u52A1\u5546\u7BA1\u7406", value: "presets" },
3391
3676
  { name: "\u274C \u9000\u51FA", value: "exit" }
@@ -3404,6 +3689,8 @@ async function startMainMenu() {
3404
3689
  await startGeminiMenu();
3405
3690
  } else if (choice === "opencode") {
3406
3691
  await startOpenCodeMenu();
3692
+ } else if (choice === "openclaw") {
3693
+ await startOpenClawMenu();
3407
3694
  } else if (choice === "sync") {
3408
3695
  const { startSyncMenu: startSyncMenu2 } = await Promise.resolve().then(() => (init_sync(), sync_exports));
3409
3696
  await startSyncMenu2();
@@ -3424,6 +3711,9 @@ async function startGeminiMenu() {
3424
3711
  async function startOpenCodeMenu() {
3425
3712
  await showToolMenu(TOOL_TYPES.OPENCODE);
3426
3713
  }
3714
+ async function startOpenClawMenu() {
3715
+ await showToolMenu(TOOL_TYPES.OPENCLAW);
3716
+ }
3427
3717
  async function showToolMenu(tool) {
3428
3718
  const { name: toolName, emoji: toolEmoji } = CLI_TOOL_CONFIG[tool];
3429
3719
  while (true) {
@@ -5275,7 +5565,7 @@ function editCommand3(program2) {
5275
5565
  targetId = selectedId;
5276
5566
  }
5277
5567
  const provider = manager.get(targetId);
5278
- const currentCommand5 = provider.baseUrl;
5568
+ const currentCommand6 = provider.baseUrl;
5279
5569
  const currentArgs = provider.apiKey;
5280
5570
  const currentEnv = provider.model;
5281
5571
  console.log(chalk30.bold("\n\u270F\uFE0F \u7F16\u8F91 MCP \u670D\u52A1\u5668\n"));
@@ -5291,7 +5581,7 @@ function editCommand3(program2) {
5291
5581
  type: "input",
5292
5582
  name: "command",
5293
5583
  message: "\u542F\u52A8\u547D\u4EE4:",
5294
- default: currentCommand5
5584
+ default: currentCommand6
5295
5585
  },
5296
5586
  {
5297
5587
  type: "input",
@@ -5310,7 +5600,7 @@ function editCommand3(program2) {
5310
5600
  if (answers.name && answers.name !== provider.name) {
5311
5601
  updates.name = answers.name;
5312
5602
  }
5313
- if (answers.command && answers.command !== currentCommand5) {
5603
+ if (answers.command && answers.command !== currentCommand6) {
5314
5604
  updates.baseUrl = answers.command;
5315
5605
  }
5316
5606
  if (answers.args && answers.args !== currentArgs) {
@@ -6241,44 +6531,495 @@ function createOpenCodeCommands(program2) {
6241
6531
  cloneCommand4(program2);
6242
6532
  }
6243
6533
 
6534
+ // src/commands/openclaw/add.ts
6535
+ init_dist2();
6536
+ import chalk45 from "chalk";
6537
+ import inquirer32 from "inquirer";
6538
+ function addCommand6(program2) {
6539
+ program2.command("add").description("\u6DFB\u52A0\u65B0\u7684 OpenClaw \u670D\u52A1\u5546(\u4EA4\u4E92\u5F0F)").action(async () => {
6540
+ try {
6541
+ const manager = createOpenClawManager();
6542
+ console.log(chalk45.bold("\n\u{1F4DD} \u6DFB\u52A0 OpenClaw \u670D\u52A1\u5546\n"));
6543
+ const { usePreset } = await inquirer32.prompt([
6544
+ {
6545
+ type: "list",
6546
+ name: "usePreset",
6547
+ message: "\u9009\u62E9\u914D\u7F6E\u6765\u6E90:",
6548
+ choices: [
6549
+ { name: "\u{1F4E6} \u4F7F\u7528\u9884\u7F6E\u670D\u52A1\u5546", value: true },
6550
+ { name: "\u270F\uFE0F \u81EA\u5B9A\u4E49\u914D\u7F6E", value: false }
6551
+ ]
6552
+ }
6553
+ ]);
6554
+ let name;
6555
+ let desc;
6556
+ let baseUrl;
6557
+ let apiKey;
6558
+ if (usePreset) {
6559
+ const { presetName } = await inquirer32.prompt([
6560
+ {
6561
+ type: "list",
6562
+ name: "presetName",
6563
+ message: "\u9009\u62E9\u9884\u7F6E\u670D\u52A1\u5546:",
6564
+ choices: OPENCLAW_PRESETS.map((p) => ({
6565
+ name: `${p.name} - ${p.description}`,
6566
+ value: p.name
6567
+ }))
6568
+ }
6569
+ ]);
6570
+ const preset = OPENCLAW_PRESETS.find((p) => p.name === presetName);
6571
+ console.log(chalk45.blue(`
6572
+ \u4F7F\u7528\u9884\u8BBE: ${preset.name} - ${preset.description}
6573
+ `));
6574
+ const input = await promptProviderForm({
6575
+ name: preset.name,
6576
+ desc: "",
6577
+ baseUrl: preset.baseUrl,
6578
+ apiKey: ""
6579
+ });
6580
+ name = input.name;
6581
+ desc = input.desc;
6582
+ baseUrl = input.baseUrl;
6583
+ apiKey = input.apiKey;
6584
+ } else {
6585
+ const answers = await inquirer32.prompt([
6586
+ {
6587
+ type: "input",
6588
+ name: "name",
6589
+ message: "\u670D\u52A1\u5546\u540D\u79F0:",
6590
+ validate: (value) => value ? true : "\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A"
6591
+ },
6592
+ {
6593
+ type: "input",
6594
+ name: "baseUrl",
6595
+ message: "API \u5730\u5740:",
6596
+ validate: (value) => {
6597
+ if (!value) return "API \u5730\u5740\u4E0D\u80FD\u4E3A\u7A7A";
6598
+ if (!value.startsWith("http://") && !value.startsWith("https://")) {
6599
+ return "API \u5730\u5740\u5FC5\u987B\u4EE5 http:// \u6216 https:// \u5F00\u5934";
6600
+ }
6601
+ return true;
6602
+ }
6603
+ },
6604
+ {
6605
+ type: "password",
6606
+ name: "apiKey",
6607
+ message: "API \u5BC6\u94A5:",
6608
+ mask: "*",
6609
+ validate: (value) => value ? true : "API \u5BC6\u94A5\u4E0D\u80FD\u4E3A\u7A7A"
6610
+ }
6611
+ ]);
6612
+ name = answers.name;
6613
+ desc = void 0;
6614
+ baseUrl = answers.baseUrl;
6615
+ apiKey = answers.apiKey;
6616
+ }
6617
+ const provider = manager.add({
6618
+ name,
6619
+ desc,
6620
+ baseUrl,
6621
+ apiKey
6622
+ });
6623
+ console.log();
6624
+ console.log(chalk45.green("\u2705 \u6DFB\u52A0\u6210\u529F"));
6625
+ console.log();
6626
+ console.log(` ${chalk45.bold(provider.name)} ${chalk45.blue("[OpenClaw]")}`);
6627
+ console.log(` ${chalk45.gray(provider.baseUrl)}`);
6628
+ console.log();
6629
+ const { switchNow } = await inquirer32.prompt([
6630
+ {
6631
+ type: "confirm",
6632
+ name: "switchNow",
6633
+ message: "\u662F\u5426\u7ACB\u5373\u5207\u6362\u5230\u6B64\u670D\u52A1\u5546?",
6634
+ default: true
6635
+ }
6636
+ ]);
6637
+ if (switchNow) {
6638
+ manager.switch(provider.id);
6639
+ console.log(chalk45.green("\u2705 \u5DF2\u5207\u6362\u5230\u65B0\u670D\u52A1\u5546"));
6640
+ console.log();
6641
+ console.log(chalk45.gray("\u914D\u7F6E\u5DF2\u66F4\u65B0:"));
6642
+ console.log(chalk45.gray(` - ${getOpenClawConfigPath()}`));
6643
+ console.log(chalk45.gray(` - ${getOpenClawModelsPath()}`));
6644
+ } else {
6645
+ console.log(
6646
+ chalk45.blue("\u{1F4A1} \u7A0D\u540E\u5207\u6362:") + chalk45.white(` ccman openclaw use "${provider.name}"`)
6647
+ );
6648
+ }
6649
+ } catch (error) {
6650
+ console.error(chalk45.red(`
6651
+ \u274C ${error.message}
6652
+ `));
6653
+ process.exit(1);
6654
+ }
6655
+ });
6656
+ }
6657
+
6658
+ // src/commands/openclaw/list.ts
6659
+ init_dist2();
6660
+ import chalk46 from "chalk";
6661
+ function listCommand6(program2) {
6662
+ program2.command("list").alias("ls").description("\u5217\u51FA\u6240\u6709 OpenClaw \u670D\u52A1\u5546").action(async () => {
6663
+ try {
6664
+ const manager = createOpenClawManager();
6665
+ const providers = manager.list();
6666
+ const current = manager.getCurrent();
6667
+ if (providers.length === 0) {
6668
+ console.log(chalk46.yellow("\n\u26A0\uFE0F \u6682\u65E0 OpenClaw \u670D\u52A1\u5546\n"));
6669
+ console.log(chalk46.blue("\u{1F4A1} \u6DFB\u52A0\u670D\u52A1\u5546:") + chalk46.white(" ccman openclaw add\n"));
6670
+ return;
6671
+ }
6672
+ console.log(chalk46.bold(`
6673
+ \u{1F4CB} OpenClaw \u670D\u52A1\u5546 (${providers.length} \u4E2A)`));
6674
+ console.log(formatProviderTable(providers, current?.id));
6675
+ } catch (error) {
6676
+ console.error(chalk46.red(`
6677
+ \u274C ${error.message}
6678
+ `));
6679
+ process.exit(1);
6680
+ }
6681
+ });
6682
+ }
6683
+
6684
+ // src/commands/openclaw/use.ts
6685
+ init_dist2();
6686
+ import chalk47 from "chalk";
6687
+ import inquirer33 from "inquirer";
6688
+ function useCommand5(program2) {
6689
+ program2.command("use [name]").description("\u5207\u6362 OpenClaw \u670D\u52A1\u5546").action(async (name) => {
6690
+ try {
6691
+ const manager = createOpenClawManager();
6692
+ const providers = manager.list();
6693
+ if (providers.length === 0) {
6694
+ console.log(chalk47.yellow("\n\u26A0\uFE0F \u6682\u65E0 OpenClaw \u670D\u52A1\u5546\n"));
6695
+ console.log(chalk47.blue("\u{1F4A1} \u6DFB\u52A0\u670D\u52A1\u5546:") + chalk47.white(" ccman openclaw add\n"));
6696
+ return;
6697
+ }
6698
+ let targetId;
6699
+ if (name) {
6700
+ const provider2 = manager.findByName(name);
6701
+ if (!provider2) {
6702
+ throw new ProviderNotFoundError(name);
6703
+ }
6704
+ targetId = provider2.id;
6705
+ } else {
6706
+ const { selectedId } = await inquirer33.prompt([
6707
+ {
6708
+ type: "list",
6709
+ name: "selectedId",
6710
+ message: "\u9009\u62E9\u8981\u5207\u6362\u7684\u670D\u52A1\u5546:",
6711
+ choices: providers.map((p) => ({
6712
+ name: `${p.name} - ${p.baseUrl}`,
6713
+ value: p.id
6714
+ }))
6715
+ }
6716
+ ]);
6717
+ targetId = selectedId;
6718
+ }
6719
+ manager.switch(targetId);
6720
+ const provider = manager.get(targetId);
6721
+ console.log(chalk47.green("\n\u2705 \u5207\u6362\u6210\u529F\n"));
6722
+ console.log(` ${chalk47.bold(provider.name)} ${chalk47.blue("[OpenClaw]")}`);
6723
+ console.log(` ${chalk47.gray(`URL: ${provider.baseUrl}`)}`);
6724
+ console.log();
6725
+ console.log(chalk47.gray("\u914D\u7F6E\u5DF2\u66F4\u65B0:"));
6726
+ console.log(chalk47.gray(` - ${getOpenClawConfigPath()}`));
6727
+ console.log(chalk47.gray(` - ${getOpenClawModelsPath()}`));
6728
+ } catch (error) {
6729
+ if (error instanceof ProviderNotFoundError) {
6730
+ console.error(chalk47.red(`
6731
+ \u274C \u670D\u52A1\u5546\u4E0D\u5B58\u5728: ${name}
6732
+ `));
6733
+ } else {
6734
+ console.error(chalk47.red(`
6735
+ \u274C ${error.message}
6736
+ `));
6737
+ }
6738
+ process.exit(1);
6739
+ }
6740
+ });
6741
+ }
6742
+
6743
+ // src/commands/openclaw/current.ts
6744
+ init_dist2();
6745
+ import chalk48 from "chalk";
6746
+ function currentCommand5(program2) {
6747
+ program2.command("current").description("\u663E\u793A\u5F53\u524D OpenClaw \u670D\u52A1\u5546").action(async () => {
6748
+ try {
6749
+ const manager = createOpenClawManager();
6750
+ const current = manager.getCurrent();
6751
+ if (!current) {
6752
+ console.log(chalk48.yellow("\n\u26A0\uFE0F \u5F53\u524D\u6CA1\u6709\u6FC0\u6D3B\u7684 OpenClaw \u670D\u52A1\u5546\n"));
6753
+ console.log(chalk48.blue("\u{1F4A1} \u5217\u51FA\u670D\u52A1\u5546:") + chalk48.white(" ccman openclaw list\n"));
6754
+ return;
6755
+ }
6756
+ console.log(chalk48.bold("\n\u{1F3AF} \u5F53\u524D OpenClaw \u670D\u52A1\u5546\n"));
6757
+ console.log(` \u540D\u79F0: ${chalk48.bold(current.name)}`);
6758
+ console.log(` \u5730\u5740: ${chalk48.gray(current.baseUrl)}`);
6759
+ console.log();
6760
+ } catch (error) {
6761
+ console.error(chalk48.red(`
6762
+ \u274C ${error.message}
6763
+ `));
6764
+ process.exit(1);
6765
+ }
6766
+ });
6767
+ }
6768
+
6769
+ // src/commands/openclaw/edit.ts
6770
+ init_dist2();
6771
+ import chalk49 from "chalk";
6772
+ import inquirer34 from "inquirer";
6773
+ function editCommand6(program2) {
6774
+ program2.command("edit [name]").description("\u7F16\u8F91 OpenClaw \u670D\u52A1\u5546").action(async (name) => {
6775
+ try {
6776
+ const manager = createOpenClawManager();
6777
+ const providers = manager.list();
6778
+ if (providers.length === 0) {
6779
+ console.log(chalk49.yellow("\n\u26A0\uFE0F \u6682\u65E0 OpenClaw \u670D\u52A1\u5546\n"));
6780
+ console.log(chalk49.blue("\u{1F4A1} \u6DFB\u52A0\u670D\u52A1\u5546:") + chalk49.white(" ccman openclaw add\n"));
6781
+ return;
6782
+ }
6783
+ let targetId;
6784
+ if (name) {
6785
+ const provider2 = manager.findByName(name);
6786
+ if (!provider2) {
6787
+ throw new ProviderNotFoundError(name);
6788
+ }
6789
+ targetId = provider2.id;
6790
+ } else {
6791
+ const { selectedId } = await inquirer34.prompt([
6792
+ {
6793
+ type: "list",
6794
+ name: "selectedId",
6795
+ message: "\u9009\u62E9\u8981\u7F16\u8F91\u7684\u670D\u52A1\u5546:",
6796
+ choices: providers.map((p) => ({
6797
+ name: `${p.name} - ${p.baseUrl}`,
6798
+ value: p.id
6799
+ }))
6800
+ }
6801
+ ]);
6802
+ targetId = selectedId;
6803
+ }
6804
+ const provider = manager.get(targetId);
6805
+ const input = await promptProviderForm({
6806
+ name: provider.name,
6807
+ desc: provider.desc ?? "",
6808
+ baseUrl: provider.baseUrl,
6809
+ apiKey: provider.apiKey
6810
+ });
6811
+ manager.edit(targetId, {
6812
+ name: input.name,
6813
+ desc: input.desc,
6814
+ baseUrl: input.baseUrl,
6815
+ apiKey: input.apiKey
6816
+ });
6817
+ console.log(chalk49.green("\n\u2705 \u7F16\u8F91\u6210\u529F\n"));
6818
+ } catch (error) {
6819
+ if (error instanceof ProviderNotFoundError) {
6820
+ console.error(chalk49.red(`
6821
+ \u274C \u670D\u52A1\u5546\u4E0D\u5B58\u5728: ${name}
6822
+ `));
6823
+ } else {
6824
+ console.error(chalk49.red(`
6825
+ \u274C ${error.message}
6826
+ `));
6827
+ }
6828
+ process.exit(1);
6829
+ }
6830
+ });
6831
+ }
6832
+
6833
+ // src/commands/openclaw/remove.ts
6834
+ init_dist2();
6835
+ import chalk50 from "chalk";
6836
+ import inquirer35 from "inquirer";
6837
+ function removeCommand6(program2) {
6838
+ program2.command("remove [name]").alias("rm").description("\u5220\u9664 OpenClaw \u670D\u52A1\u5546").action(async (name) => {
6839
+ try {
6840
+ const manager = createOpenClawManager();
6841
+ const providers = manager.list();
6842
+ if (providers.length === 0) {
6843
+ console.log(chalk50.yellow("\n\u26A0\uFE0F \u6682\u65E0 OpenClaw \u670D\u52A1\u5546\n"));
6844
+ return;
6845
+ }
6846
+ let targetId;
6847
+ let targetName;
6848
+ if (name) {
6849
+ const provider = manager.findByName(name);
6850
+ if (!provider) {
6851
+ throw new ProviderNotFoundError(name);
6852
+ }
6853
+ targetId = provider.id;
6854
+ targetName = provider.name;
6855
+ } else {
6856
+ const { selectedId } = await inquirer35.prompt([
6857
+ {
6858
+ type: "list",
6859
+ name: "selectedId",
6860
+ message: "\u9009\u62E9\u8981\u5220\u9664\u7684\u670D\u52A1\u5546:",
6861
+ choices: providers.map((p) => ({
6862
+ name: `${p.name} - ${p.baseUrl}`,
6863
+ value: p.id
6864
+ }))
6865
+ }
6866
+ ]);
6867
+ const provider = manager.get(selectedId);
6868
+ targetId = selectedId;
6869
+ targetName = provider.name;
6870
+ }
6871
+ const { confirmed } = await inquirer35.prompt([
6872
+ {
6873
+ type: "confirm",
6874
+ name: "confirmed",
6875
+ message: `\u786E\u5B9A\u5220\u9664 "${targetName}"?`,
6876
+ default: false
6877
+ }
6878
+ ]);
6879
+ if (!confirmed) {
6880
+ console.log(chalk50.gray("\n\u5DF2\u53D6\u6D88\n"));
6881
+ return;
6882
+ }
6883
+ manager.remove(targetId);
6884
+ console.log(chalk50.green(`
6885
+ \u2705 \u5DF2\u5220\u9664: ${targetName}
6886
+ `));
6887
+ } catch (error) {
6888
+ if (error instanceof ProviderNotFoundError) {
6889
+ console.error(chalk50.red(`
6890
+ \u274C \u670D\u52A1\u5546\u4E0D\u5B58\u5728: ${name}
6891
+ `));
6892
+ } else {
6893
+ console.error(chalk50.red(`
6894
+ \u274C ${error.message}
6895
+ `));
6896
+ }
6897
+ process.exit(1);
6898
+ }
6899
+ });
6900
+ }
6901
+
6902
+ // src/commands/openclaw/clone.ts
6903
+ init_dist2();
6904
+ import chalk51 from "chalk";
6905
+ import inquirer36 from "inquirer";
6906
+ function cloneCommand5(program2) {
6907
+ program2.command("clone [source-name] [new-name]").description("\u514B\u9686 OpenClaw \u670D\u52A1\u5546").action(async (sourceName, newName) => {
6908
+ try {
6909
+ const manager = createOpenClawManager();
6910
+ const providers = manager.list();
6911
+ if (providers.length === 0) {
6912
+ console.log(chalk51.yellow("\n\u26A0\uFE0F \u6682\u65E0 OpenClaw \u670D\u52A1\u5546\n"));
6913
+ return;
6914
+ }
6915
+ let sourceId;
6916
+ if (sourceName) {
6917
+ const provider = manager.findByName(sourceName);
6918
+ if (!provider) {
6919
+ throw new ProviderNotFoundError(sourceName);
6920
+ }
6921
+ sourceId = provider.id;
6922
+ } else {
6923
+ const { selectedId } = await inquirer36.prompt([
6924
+ {
6925
+ type: "list",
6926
+ name: "selectedId",
6927
+ message: "\u9009\u62E9\u8981\u514B\u9686\u7684\u670D\u52A1\u5546:",
6928
+ choices: providers.map((p) => ({
6929
+ name: `${p.name} - ${p.baseUrl}`,
6930
+ value: p.id
6931
+ }))
6932
+ }
6933
+ ]);
6934
+ sourceId = selectedId;
6935
+ }
6936
+ const source = manager.get(sourceId);
6937
+ let cloned;
6938
+ if (newName) {
6939
+ cloned = manager.clone(sourceId, newName);
6940
+ } else {
6941
+ console.log(chalk51.blue(`
6942
+ \u514B\u9686\u81EA: ${source.name}
6943
+ `));
6944
+ const input = await promptProviderForm({
6945
+ name: `${source.name}\uFF08\u526F\u672C\uFF09`,
6946
+ desc: "",
6947
+ baseUrl: source.baseUrl,
6948
+ apiKey: source.apiKey
6949
+ });
6950
+ cloned = manager.add({
6951
+ name: input.name,
6952
+ desc: input.desc,
6953
+ baseUrl: input.baseUrl,
6954
+ apiKey: input.apiKey
6955
+ });
6956
+ }
6957
+ console.log();
6958
+ console.log(chalk51.green("\u2705 \u514B\u9686\u6210\u529F"));
6959
+ console.log();
6960
+ console.log(` ${chalk51.bold(cloned.name)} ${chalk51.blue("[OpenClaw]")}`);
6961
+ console.log(` ${chalk51.gray(`ID: ${cloned.id}`)}`);
6962
+ console.log(` ${chalk51.gray(`URL: ${cloned.baseUrl}`)}`);
6963
+ console.log();
6964
+ } catch (error) {
6965
+ console.error(chalk51.red(`
6966
+ \u274C ${error.message}
6967
+ `));
6968
+ process.exit(1);
6969
+ }
6970
+ });
6971
+ }
6972
+
6973
+ // src/commands/openclaw/index.ts
6974
+ function createOpenClawCommands(program2) {
6975
+ addCommand6(program2);
6976
+ listCommand6(program2);
6977
+ useCommand5(program2);
6978
+ currentCommand5(program2);
6979
+ editCommand6(program2);
6980
+ removeCommand6(program2);
6981
+ cloneCommand5(program2);
6982
+ }
6983
+
6244
6984
  // src/index.ts
6245
6985
  init_sync();
6246
6986
 
6247
6987
  // src/commands/export.ts
6248
6988
  init_dist2();
6249
- import chalk45 from "chalk";
6250
- import path12 from "path";
6989
+ import chalk52 from "chalk";
6990
+ import path13 from "path";
6251
6991
  function exportCommand(program2) {
6252
6992
  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
6993
  try {
6254
- console.log(chalk45.bold("\n\u{1F4E6} \u5BFC\u51FA\u914D\u7F6E\n"));
6994
+ console.log(chalk52.bold("\n\u{1F4E6} \u5BFC\u51FA\u914D\u7F6E\n"));
6255
6995
  const validation = validateExport();
6256
6996
  if (!validation.valid) {
6257
- console.log(chalk45.red(`\u274C ${validation.message}
6997
+ console.log(chalk52.red(`\u274C ${validation.message}
6258
6998
  `));
6259
6999
  process.exit(1);
6260
7000
  }
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`);
7001
+ const resolvedPath = targetDir.startsWith("~") ? path13.join(process.env.HOME || "", targetDir.slice(1)) : path13.resolve(targetDir);
7002
+ console.log("\u5BFC\u51FA\u6587\u4EF6\uFF08\u5B58\u5728\u5219\u5BFC\u51FA\uFF0C\u4E0D\u5B58\u5728\u5219\u8DF3\u8FC7\uFF09:");
7003
+ console.log(` ${chalk52.cyan("codex.json")} - Codex \u914D\u7F6E`);
7004
+ console.log(` ${chalk52.cyan("claude.json")} - Claude \u914D\u7F6E`);
7005
+ console.log(` ${chalk52.cyan("openclaw.json")} - OpenClaw \u914D\u7F6E`);
6265
7006
  console.log();
6266
- console.log(`\u76EE\u6807\u76EE\u5F55: ${chalk45.cyan(resolvedPath)}`);
7007
+ console.log(`\u76EE\u6807\u76EE\u5F55: ${chalk52.cyan(resolvedPath)}`);
6267
7008
  console.log();
6268
- console.log(chalk45.yellow("\u26A0\uFE0F \u5BFC\u51FA\u6587\u4EF6\u5305\u542B API Key\uFF0C\u8BF7\u59A5\u5584\u4FDD\u7BA1"));
7009
+ console.log(chalk52.yellow("\u26A0\uFE0F \u5BFC\u51FA\u6587\u4EF6\u5305\u542B API Key\uFF0C\u8BF7\u59A5\u5584\u4FDD\u7BA1"));
6269
7010
  console.log();
6270
7011
  const result = exportConfig(resolvedPath);
6271
- console.log(chalk45.green("\u2705 \u5BFC\u51FA\u6210\u529F"));
7012
+ console.log(chalk52.green("\u2705 \u5BFC\u51FA\u6210\u529F"));
6272
7013
  console.log();
6273
7014
  console.log("\u5DF2\u5BFC\u51FA\u6587\u4EF6:");
6274
7015
  for (const file of result.exportedFiles) {
6275
- console.log(` ${chalk45.cyan("\u2713")} ${file}`);
7016
+ console.log(` ${chalk52.cyan("\u2713")} ${file}`);
6276
7017
  }
6277
7018
  console.log();
6278
- console.log(chalk45.blue(`\u{1F4A1} \u5BFC\u5165\u547D\u4EE4: ccman import ${resolvedPath}
7019
+ console.log(chalk52.blue(`\u{1F4A1} \u5BFC\u5165\u547D\u4EE4: ccman import ${resolvedPath}
6279
7020
  `));
6280
7021
  } catch (error) {
6281
- console.error(chalk45.red(`
7022
+ console.error(chalk52.red(`
6282
7023
  \u274C ${error.message}
6283
7024
  `));
6284
7025
  process.exit(1);
@@ -6288,31 +7029,33 @@ function exportCommand(program2) {
6288
7029
 
6289
7030
  // src/commands/import.ts
6290
7031
  init_dist2();
6291
- import chalk46 from "chalk";
6292
- import inquirer32 from "inquirer";
6293
- import path13 from "path";
7032
+ import chalk53 from "chalk";
7033
+ import inquirer37 from "inquirer";
7034
+ import path14 from "path";
6294
7035
  function importCommand(program2) {
6295
7036
  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
7037
  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"));
7038
+ const resolvedPath = sourceDir.startsWith("~") ? path14.join(process.env.HOME || "", sourceDir.slice(1)) : path14.resolve(sourceDir);
7039
+ console.log(chalk53.bold("\n\u{1F4E5} \u5BFC\u5165\u914D\u7F6E\n"));
6299
7040
  const validation = validateImportDir(resolvedPath);
6300
7041
  if (!validation.valid) {
6301
- console.log(chalk46.red(`\u274C ${validation.message}
7042
+ console.log(chalk53.red(`\u274C ${validation.message}
6302
7043
  `));
6303
7044
  process.exit(1);
6304
7045
  }
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)}`);
7046
+ console.log(chalk53.yellow("\u26A0\uFE0F \u8B66\u544A\uFF1A\u5BFC\u5165\u5C06\u8986\u76D6\u5F53\u524D\u914D\u7F6E\n"));
7047
+ console.log(`\u6E90\u76EE\u5F55: ${chalk53.cyan(resolvedPath)}`);
6307
7048
  console.log();
6308
7049
  console.log("\u627E\u5230\u914D\u7F6E\u6587\u4EF6:");
6309
7050
  for (const file of validation.foundFiles) {
6310
- console.log(` ${chalk46.cyan("\u2713")} ${file}`);
7051
+ console.log(` ${chalk53.cyan("\u2713")} ${file}`);
6311
7052
  }
6312
7053
  console.log();
6313
- console.log(chalk46.gray("\u5F53\u524D\u914D\u7F6E\u5C06\u88AB\u8986\u76D6\uFF08\u81EA\u52A8\u5907\u4EFD\uFF09"));
7054
+ 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"));
7055
+ console.log();
7056
+ console.log(chalk53.gray("\u5F53\u524D\u914D\u7F6E\u5C06\u88AB\u8986\u76D6\uFF08\u81EA\u52A8\u5907\u4EFD\uFF09"));
6314
7057
  console.log();
6315
- const { confirmFirst } = await inquirer32.prompt([
7058
+ const { confirmFirst } = await inquirer37.prompt([
6316
7059
  {
6317
7060
  type: "confirm",
6318
7061
  name: "confirmFirst",
@@ -6321,13 +7064,13 @@ function importCommand(program2) {
6321
7064
  }
6322
7065
  ]);
6323
7066
  if (!confirmFirst) {
6324
- console.log(chalk46.gray("\n\u274C \u5DF2\u53D6\u6D88\n"));
7067
+ console.log(chalk53.gray("\n\u274C \u5DF2\u53D6\u6D88\n"));
6325
7068
  return;
6326
7069
  }
6327
7070
  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"));
7071
+ 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
7072
  console.log();
6330
- const { confirmSecond } = await inquirer32.prompt([
7073
+ const { confirmSecond } = await inquirer37.prompt([
6331
7074
  {
6332
7075
  type: "confirm",
6333
7076
  name: "confirmSecond",
@@ -6336,31 +7079,31 @@ function importCommand(program2) {
6336
7079
  }
6337
7080
  ]);
6338
7081
  if (!confirmSecond) {
6339
- console.log(chalk46.gray("\n\u274C \u5DF2\u53D6\u6D88\n"));
7082
+ console.log(chalk53.gray("\n\u274C \u5DF2\u53D6\u6D88\n"));
6340
7083
  return;
6341
7084
  }
6342
7085
  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..."));
7086
+ console.log(chalk53.gray("\u{1F4BE} \u5907\u4EFD\u5F53\u524D\u914D\u7F6E..."));
7087
+ console.log(chalk53.gray("\u{1F4E5} \u5BFC\u5165\u65B0\u914D\u7F6E..."));
6345
7088
  const result = importConfig(resolvedPath);
6346
7089
  console.log();
6347
- console.log(chalk46.green("\u2705 \u5BFC\u5165\u6210\u529F"));
7090
+ console.log(chalk53.green("\u2705 \u5BFC\u5165\u6210\u529F"));
6348
7091
  console.log();
6349
7092
  if (result.backupPaths.length > 0) {
6350
7093
  console.log("\u5907\u4EFD\u6587\u4EF6:");
6351
7094
  for (const backupPath of result.backupPaths) {
6352
- console.log(` ${chalk46.gray(backupPath)}`);
7095
+ console.log(` ${chalk53.gray(backupPath)}`);
6353
7096
  }
6354
7097
  console.log();
6355
7098
  }
6356
7099
  console.log("\u5DF2\u5BFC\u5165\u6587\u4EF6:");
6357
7100
  for (const file of result.importedFiles) {
6358
- console.log(` ${chalk46.cyan("\u2713")} ${file}`);
7101
+ console.log(` ${chalk53.cyan("\u2713")} ${file}`);
6359
7102
  }
6360
7103
  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"));
7104
+ console.log(chalk53.blue("\u{1F4A1} \u8BF7\u4F7F\u7528 'ccman cx use' \u6216 'ccman cc use' \u5207\u6362\u670D\u52A1\u5546\n"));
6362
7105
  } catch (error) {
6363
- console.error(chalk46.red(`
7106
+ console.error(chalk53.red(`
6364
7107
  \u274C ${error.message}
6365
7108
  `));
6366
7109
  process.exit(1);
@@ -6370,16 +7113,13 @@ function importCommand(program2) {
6370
7113
 
6371
7114
  // src/commands/gmn.ts
6372
7115
  init_dist2();
6373
- import chalk47 from "chalk";
6374
- import inquirer33 from "inquirer";
7116
+ import chalk54 from "chalk";
7117
+ import inquirer38 from "inquirer";
6375
7118
  var PROVIDER_NAME = "GMN";
6376
- var VALID_PLATFORMS = ["claude", "codex", "gemini", "opencode"];
7119
+ var VALID_PLATFORMS = ["codex", "opencode", "openclaw"];
6377
7120
  var DEFAULT_PLATFORMS = ["codex", "opencode"];
6378
- var GMN_BASE_URLS = {
6379
- claude: "https://gmn.chuangzuoli.com/api",
6380
- gemini: "https://gmn.chuangzuoli.com"
6381
- };
6382
7121
  var GMN_OPENAI_BASE_URL = "https://gmn.chuangzuoli.com";
7122
+ var GMN_OPENCLAW_BASE_URL = "https://gmn.chuangzuoli.com/v1";
6383
7123
  var TOTAL_STEPS = 3;
6384
7124
  function renderStep(current, total, title) {
6385
7125
  const barLength = total;
@@ -6390,7 +7130,7 @@ function renderStep(current, total, title) {
6390
7130
  function printBanner() {
6391
7131
  printLogo();
6392
7132
  console.log(
6393
- chalk47.cyanBright(
7133
+ chalk54.cyanBright(
6394
7134
  [
6395
7135
  " \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2557",
6396
7136
  " \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",
@@ -6402,39 +7142,36 @@ function printBanner() {
6402
7142
  ].join("\n")
6403
7143
  )
6404
7144
  );
6405
- console.log(chalk47.gray("\u81EA\u52A8\u5199\u5165\u9009\u4E2D\u5DE5\u5177\u914D\u7F6E\uFF0C\u652F\u6301\u591A\u9009\u3002\n"));
7145
+ console.log(chalk54.gray("\u81EA\u52A8\u5199\u5165\u9009\u4E2D\u5DE5\u5177\u914D\u7F6E\uFF0C\u652F\u6301\u591A\u9009\u3002\n"));
6406
7146
  }
6407
7147
  function printKeyNotice() {
6408
7148
  console.log(
6409
- chalk47.yellow(
7149
+ chalk54.yellow(
6410
7150
  [
6411
- "\u63D0\u793A\uFF1ACodex \u4E0E OpenCode \u5171\u4EAB OpenAI \u5957\u9910/\u7AEF\u70B9\uFF1BGemini \u4E0E Claude \u9700\u5355\u72EC\u8BA2\u9605\u3002",
6412
- "\u4F8B\u5982\uFF1AGemini \u5957\u9910\u4E0D\u80FD\u7528\u4E8E Codex/OpenCode\uFF0CClaude \u5957\u9910\u4E5F\u4E0D\u80FD\u901A\u7528\u3002",
7151
+ "\u63D0\u793A\uFF1A\u672C\u547D\u4EE4\u652F\u6301 Codex\u3001OpenCode\u3001OpenClaw \u4E09\u4E2A\u5E73\u53F0\u3002",
7152
+ "Codex \u4E0E OpenCode \u5171\u4EAB OpenAI \u7AEF\u70B9\uFF1BOpenClaw \u4F7F\u7528 /v1 \u7AEF\u70B9\u3002",
6413
7153
  "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"
6414
7154
  ].join("\n")
6415
7155
  )
6416
7156
  );
6417
7157
  }
6418
7158
  function printWriteTargets(platforms) {
6419
- console.log(chalk47.gray(`\u5199\u5165\u76EE\u5F55: ${getCcmanDir()}`));
7159
+ console.log(chalk54.gray(`\u5199\u5165\u76EE\u5F55: ${getCcmanDir()}`));
6420
7160
  if (platforms.includes("codex")) {
6421
- console.log(chalk47.gray(` - Codex: ${getCodexConfigPath()}`));
6422
- console.log(chalk47.gray(` - Codex: ${getCodexAuthPath()}`));
6423
- }
6424
- if (platforms.includes("claude")) {
6425
- console.log(chalk47.gray(` - Claude Code: ${getClaudeConfigPath()}`));
6426
- }
6427
- if (platforms.includes("gemini")) {
6428
- console.log(chalk47.gray(` - Gemini CLI: ${getGeminiSettingsPath()}`));
6429
- console.log(chalk47.gray(` - Gemini CLI: ${getGeminiEnvPath()}`));
7161
+ console.log(chalk54.gray(` - Codex: ${getCodexConfigPath()}`));
7162
+ console.log(chalk54.gray(` - Codex: ${getCodexAuthPath()}`));
6430
7163
  }
6431
7164
  if (platforms.includes("opencode")) {
6432
- console.log(chalk47.gray(` - OpenCode: ${getOpenCodeConfigPath()}`));
7165
+ console.log(chalk54.gray(` - OpenCode: ${getOpenCodeConfigPath()}`));
7166
+ }
7167
+ if (platforms.includes("openclaw")) {
7168
+ console.log(chalk54.gray(` - OpenClaw: ${getOpenClawConfigPath()}`));
7169
+ console.log(chalk54.gray(` - OpenClaw: ${getOpenClawModelsPath()}`));
6433
7170
  }
6434
7171
  const env = process.env.NODE_ENV;
6435
7172
  if (env === "development" || env === "test") {
6436
7173
  console.log(
6437
- chalk47.yellow(
7174
+ chalk54.yellow(
6438
7175
  `\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`
6439
7176
  )
6440
7177
  );
@@ -6453,7 +7190,7 @@ function parsePlatforms(platformArg) {
6453
7190
  return platforms;
6454
7191
  }
6455
7192
  async function promptApiKey() {
6456
- const answers = await inquirer33.prompt([
7193
+ const answers = await inquirer38.prompt([
6457
7194
  {
6458
7195
  type: "password",
6459
7196
  name: "apiKey",
@@ -6468,18 +7205,17 @@ async function promptApiKey() {
6468
7205
  return answers.apiKey.trim();
6469
7206
  }
6470
7207
  async function promptPlatforms() {
6471
- const answers = await inquirer33.prompt([
7208
+ const answers = await inquirer38.prompt([
6472
7209
  {
6473
7210
  type: "checkbox",
6474
7211
  name: "platforms",
6475
7212
  message: "\u9009\u62E9\u8981\u914D\u7F6E\u7684\u5DE5\u5177\uFF08\u53EF\u591A\u9009\uFF0C\u7A7A\u683C\u9009\u62E9 / a\u5168\u9009 / i\u53CD\u9009 / \u56DE\u8F66\u786E\u8BA4\uFF09:",
6476
7213
  dontShowHints: true,
6477
7214
  choices: [
6478
- { name: "Claude Code\uFF08\u9700\u5355\u72EC\u8BA2\u9605 Claude \u5957\u9910\uFF09", value: "claude" },
6479
7215
  { name: "Codex\uFF08\u9700\u5355\u72EC\u8BA2\u9605 OpenAI \u5957\u9910\uFF09", value: "codex" },
6480
- { name: "Gemini CLI\uFF08\u9700\u5355\u72EC\u8BA2\u9605 Gemini \u5957\u9910\uFF09", value: "gemini" },
6481
7216
  { name: "OpenCode\uFF08\u4E0E Codex \u5171\u4EAB OpenAI \u5957\u9910\uFF09", value: "opencode" },
6482
- { name: "\u5168\u90E8\uFF08\u5C06\u4F9D\u6B21\u914D\u7F6E\u6240\u6709\u5DE5\u5177\uFF09", value: "all" }
7217
+ { name: "OpenClaw\uFF08GMN /v1 \u7AEF\u70B9\uFF0C\u9ED8\u8BA4\u4E0D\u9009\u4E2D\uFF09", value: "openclaw" },
7218
+ { name: "\u5168\u90E8\uFF08\u5C06\u4F9D\u6B21\u914D\u7F6E Codex\u3001OpenCode\u3001OpenClaw\uFF09", value: "all" }
6483
7219
  ],
6484
7220
  default: DEFAULT_PLATFORMS,
6485
7221
  validate: (value) => {
@@ -6504,47 +7240,48 @@ async function gmnCommand(apiKey, platformArg) {
6504
7240
  printBanner();
6505
7241
  let platforms;
6506
7242
  try {
6507
- console.log(chalk47.cyan(`
7243
+ console.log(chalk54.cyan(`
6508
7244
  ${renderStep(1, TOTAL_STEPS, "\u9009\u62E9\u8981\u914D\u7F6E\u7684\u5DE5\u5177")}`));
6509
7245
  platforms = await resolvePlatforms(platformArg);
6510
7246
  } catch (error) {
6511
- console.error(chalk47.red(`\u274C ${error.message}`));
7247
+ console.error(chalk54.red(`\u274C ${error.message}`));
6512
7248
  process.exit(1);
6513
7249
  }
6514
- console.log(chalk47.gray(`\u5DF2\u9009\u62E9: ${platforms.join(", ")}`));
7250
+ console.log(chalk54.gray(`\u5DF2\u9009\u62E9: ${platforms.join(", ")}`));
6515
7251
  printKeyNotice();
6516
7252
  let resolvedApiKey = apiKey?.trim();
6517
- console.log(chalk47.cyan(`
7253
+ console.log(chalk54.cyan(`
6518
7254
  ${renderStep(2, TOTAL_STEPS, "\u8F93\u5165 API Key")}`));
6519
7255
  if (!resolvedApiKey) {
6520
7256
  resolvedApiKey = await promptApiKey();
6521
7257
  } else {
6522
- console.log(chalk47.gray("\u5DF2\u901A\u8FC7\u53C2\u6570\u63D0\u4F9B API Key\uFF08\u5DF2\u9690\u85CF\uFF09"));
7258
+ console.log(chalk54.gray("\u5DF2\u901A\u8FC7\u53C2\u6570\u63D0\u4F9B API Key\uFF08\u5DF2\u9690\u85CF\uFF09"));
6523
7259
  }
6524
7260
  if (!resolvedApiKey?.trim()) {
6525
- console.error(chalk47.red("\u274C \u9519\u8BEF: API Key \u4E0D\u80FD\u4E3A\u7A7A"));
7261
+ console.error(chalk54.red("\u274C \u9519\u8BEF: API Key \u4E0D\u80FD\u4E3A\u7A7A"));
6526
7262
  process.exit(1);
6527
7263
  }
6528
7264
  const openaiBaseUrl = GMN_OPENAI_BASE_URL;
6529
7265
  const platformBaseUrls = {
6530
- claude: GMN_BASE_URLS.claude,
6531
7266
  codex: openaiBaseUrl,
6532
- gemini: GMN_BASE_URLS.gemini,
6533
- opencode: openaiBaseUrl
7267
+ opencode: openaiBaseUrl,
7268
+ openclaw: GMN_OPENCLAW_BASE_URL
6534
7269
  };
6535
- console.log(chalk47.cyan(`
7270
+ console.log(chalk54.cyan(`
6536
7271
  ${renderStep(3, TOTAL_STEPS, "\u5F00\u59CB\u5199\u5165\u914D\u7F6E")}`));
6537
- console.log(chalk47.gray(`\u5DF2\u9009\u62E9\u5E73\u53F0: ${platforms.join(", ")}`));
7272
+ console.log(chalk54.gray(`\u5DF2\u9009\u62E9\u5E73\u53F0: ${platforms.join(", ")}`));
6538
7273
  if (platforms.includes("codex") || platforms.includes("opencode")) {
6539
- console.log(chalk47.gray(`OpenAI Base URL: ${openaiBaseUrl}`));
7274
+ console.log(chalk54.gray(`OpenAI Base URL: ${openaiBaseUrl}`));
7275
+ }
7276
+ if (platforms.includes("openclaw")) {
7277
+ console.log(chalk54.gray(`OpenClaw Base URL: ${GMN_OPENCLAW_BASE_URL}`));
6540
7278
  }
6541
7279
  printWriteTargets(platforms);
6542
7280
  console.log();
6543
7281
  const ALL_TOOLS = {
6544
- claude: { name: "Claude Code", manager: createClaudeManager() },
6545
7282
  codex: { name: "Codex", manager: createCodexManager() },
6546
- gemini: { name: "Gemini CLI", manager: createGeminiManager() },
6547
- opencode: { name: "OpenCode", manager: createOpenCodeManager() }
7283
+ opencode: { name: "OpenCode", manager: createOpenCodeManager() },
7284
+ openclaw: { name: "OpenClaw", manager: createOpenClawManager() }
6548
7285
  };
6549
7286
  const tools = platforms.map((platform) => ({
6550
7287
  platform,
@@ -6553,34 +7290,35 @@ ${renderStep(3, TOTAL_STEPS, "\u5F00\u59CB\u5199\u5165\u914D\u7F6E")}`));
6553
7290
  let completed = 0;
6554
7291
  for (const { platform, name, manager } of tools) {
6555
7292
  try {
6556
- console.log(chalk47.gray(`\u2192 \u914D\u7F6E ${name}...`));
7293
+ console.log(chalk54.gray(`\u2192 \u914D\u7F6E ${name}...`));
6557
7294
  const baseUrl = platformBaseUrls[platform];
6558
7295
  const existing = manager.findByName(PROVIDER_NAME);
6559
7296
  const provider = existing ? manager.edit(existing.id, { baseUrl, apiKey: resolvedApiKey }) : manager.add({ name: PROVIDER_NAME, baseUrl, apiKey: resolvedApiKey });
6560
7297
  manager.switch(provider.id);
6561
7298
  completed += 1;
6562
- console.log(chalk47.green(`\u2705 ${name}`));
7299
+ console.log(chalk54.green(`\u2705 ${name}`));
6563
7300
  } catch (error) {
6564
- console.error(chalk47.red(`\u274C ${name}: ${error.message}`));
7301
+ console.error(chalk54.red(`\u274C ${name}: ${error.message}`));
6565
7302
  }
6566
7303
  }
6567
- console.log(chalk47.green(`
7304
+ console.log(chalk54.green(`
6568
7305
  \u{1F389} GMN \u914D\u7F6E\u5B8C\u6210\uFF01(${completed}/${tools.length})`));
6569
- console.log(chalk47.gray("\u63D0\u793A\uFF1A\u8BF7\u91CD\u542F\u5BF9\u5E94\u5DE5\u5177/\u63D2\u4EF6\u4EE5\u4F7F\u914D\u7F6E\u751F\u6548\u3002"));
7306
+ console.log(chalk54.gray("\u63D0\u793A\uFF1A\u8BF7\u91CD\u542F\u5BF9\u5E94\u5DE5\u5177/\u63D2\u4EF6\u4EE5\u4F7F\u914D\u7F6E\u751F\u6548\u3002"));
6570
7307
  }
6571
7308
 
6572
7309
  // src/index.ts
6573
7310
  init_dist2();
6574
7311
  if (process.env.NODE_ENV === "development") {
6575
- console.log(chalk48.gray("\n[\u5F00\u53D1\u6A21\u5F0F] \u914D\u7F6E\u76EE\u5F55:"));
6576
- console.log(chalk48.gray(` ccman: ${getCcmanDir()}`));
6577
- console.log(chalk48.gray(` codex: ${getCodexDir()}`));
6578
- console.log(chalk48.gray(` claude: ${getClaudeDir()}`));
6579
- console.log(chalk48.gray(` opencode: ${getOpenCodeDir()}`));
7312
+ console.log(chalk55.gray("\n[\u5F00\u53D1\u6A21\u5F0F] \u914D\u7F6E\u76EE\u5F55:"));
7313
+ console.log(chalk55.gray(` ccman: ${getCcmanDir()}`));
7314
+ console.log(chalk55.gray(` codex: ${getCodexDir()}`));
7315
+ console.log(chalk55.gray(` claude: ${getClaudeDir()}`));
7316
+ console.log(chalk55.gray(` opencode: ${getOpenCodeDir()}`));
7317
+ console.log(chalk55.gray(` openclaw: ${getOpenClawDir()}`));
6580
7318
  console.log();
6581
7319
  }
6582
7320
  var program = new Command3();
6583
- 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) => {
7321
+ 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) => {
6584
7322
  if (err.code === "commander.helpDisplayed" || err.code === "commander.version") {
6585
7323
  process.exit(0);
6586
7324
  }
@@ -6588,21 +7326,33 @@ program.name("ccman").description("Codex/Claude Code/Gemini/OpenCode API \u670D\
6588
7326
  });
6589
7327
  program.on("command:*", (operands) => {
6590
7328
  const unknownCommand = operands[0];
6591
- console.error(chalk48.red(`
7329
+ console.error(chalk55.red(`
6592
7330
  \u274C \u672A\u77E5\u547D\u4EE4: ${unknownCommand}
6593
7331
  `));
6594
- const availableCommands = ["cx", "cc", "gm", "oc", "mcp", "sync", "export", "import", "gmn"];
7332
+ const availableCommands = [
7333
+ "cx",
7334
+ "cc",
7335
+ "gm",
7336
+ "oc",
7337
+ "openclaw",
7338
+ "ow",
7339
+ "mcp",
7340
+ "sync",
7341
+ "export",
7342
+ "import",
7343
+ "gmn"
7344
+ ];
6595
7345
  const suggestions = availableCommands.filter(
6596
7346
  (cmd) => cmd.includes(unknownCommand) || unknownCommand.includes(cmd)
6597
7347
  );
6598
7348
  if (suggestions.length > 0) {
6599
- console.log(chalk48.yellow("\u{1F4A1} \u4F60\u662F\u4E0D\u662F\u60F3\u8F93\u5165:"));
7349
+ console.log(chalk55.yellow("\u{1F4A1} \u4F60\u662F\u4E0D\u662F\u60F3\u8F93\u5165:"));
6600
7350
  suggestions.forEach((cmd) => {
6601
- console.log(chalk48.cyan(` ccman ${cmd}`));
7351
+ console.log(chalk55.cyan(` ccman ${cmd}`));
6602
7352
  });
6603
7353
  console.log();
6604
7354
  }
6605
- console.log(chalk48.gray("\u67E5\u770B\u6240\u6709\u53EF\u7528\u547D\u4EE4: ") + chalk48.cyan("ccman --help"));
7355
+ console.log(chalk55.gray("\u67E5\u770B\u6240\u6709\u53EF\u7528\u547D\u4EE4: ") + chalk55.cyan("ccman --help"));
6606
7356
  console.log();
6607
7357
  process.exit(1);
6608
7358
  });
@@ -6630,6 +7380,12 @@ oc.action(async () => {
6630
7380
  printLogo();
6631
7381
  await startOpenCodeMenu();
6632
7382
  });
7383
+ var openclaw = program.command("openclaw").alias("ow").description("\u7BA1\u7406 OpenClaw \u670D\u52A1\u5546");
7384
+ createOpenClawCommands(openclaw);
7385
+ openclaw.action(async () => {
7386
+ printLogo();
7387
+ await startOpenClawMenu();
7388
+ });
6633
7389
  var mcp = program.command("mcp").description("\u7BA1\u7406 MCP \u670D\u52A1\u5668");
6634
7390
  createMCPCommands(mcp);
6635
7391
  mcp.action(() => {
@@ -6643,7 +7399,7 @@ sync.action(async () => {
6643
7399
  });
6644
7400
  exportCommand(program);
6645
7401
  importCommand(program);
6646
- program.command("gmn [apiKey]").description("\u914D\u7F6E GMN \u5230\u6240\u6709\u5DE5\u5177").option("-p, --platform <platforms>", "\u6307\u5B9A\u5E73\u53F0 (claude,codex,gemini,opencode,all)").action(async (apiKey, options) => {
7402
+ 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) => {
6647
7403
  await gmnCommand(apiKey, options.platform);
6648
7404
  });
6649
7405
  (async () => {