ccman 3.0.18 → 3.0.19

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.
Files changed (2) hide show
  1. package/dist/index.js +121 -55
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -39,7 +39,7 @@ var init_package = __esm({
39
39
  "../core/package.json"() {
40
40
  package_default = {
41
41
  name: "@ccman/core",
42
- version: "3.0.18",
42
+ version: "3.0.19",
43
43
  type: "module",
44
44
  description: "Core business logic for ccman",
45
45
  main: "./dist/index.js",
@@ -2163,37 +2163,55 @@ var require_toml = __commonJS({
2163
2163
  }
2164
2164
  });
2165
2165
 
2166
+ // ../core/dist/utils/template.js
2167
+ function replaceVariables(template, variables) {
2168
+ const jsonStr = JSON.stringify(template);
2169
+ let result = jsonStr;
2170
+ for (const [key, value] of Object.entries(variables)) {
2171
+ const escapedValue = value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
2172
+ result = result.replace(new RegExp(`{{${key}}}`, "g"), escapedValue);
2173
+ }
2174
+ return JSON.parse(result);
2175
+ }
2176
+ function deepMerge(target, source) {
2177
+ const result = { ...target };
2178
+ for (const key in source) {
2179
+ const sourceValue = source[key];
2180
+ const targetValue = result[key];
2181
+ if (sourceValue && typeof sourceValue === "object" && !Array.isArray(sourceValue) && targetValue && typeof targetValue === "object" && !Array.isArray(targetValue)) {
2182
+ result[key] = deepMerge(targetValue, sourceValue);
2183
+ } else {
2184
+ result[key] = sourceValue;
2185
+ }
2186
+ }
2187
+ return result;
2188
+ }
2189
+ var init_template = __esm({
2190
+ "../core/dist/utils/template.js"() {
2191
+ "use strict";
2192
+ }
2193
+ });
2194
+
2166
2195
  // ../core/dist/writers/codex.js
2167
2196
  function writeCodexConfig(provider) {
2168
2197
  ensureDir(getCodexDir());
2169
2198
  const configPath = getCodexConfigPath();
2170
- let config;
2199
+ let userConfig = {};
2171
2200
  if (fileExists(configPath)) {
2172
2201
  const content = fs2.readFileSync(configPath, "utf-8");
2173
- config = (0, import_toml.parse)(content);
2174
- } else {
2175
- config = {};
2202
+ userConfig = (0, import_toml.parse)(content);
2176
2203
  }
2177
- config.model_provider = provider.name;
2178
- config.model_providers = config.model_providers || {};
2179
- config.model_providers[provider.name] = {
2204
+ const mergedConfig = deepMerge(CODEX_DEFAULT_CONFIG, userConfig);
2205
+ mergedConfig.model_provider = provider.name;
2206
+ mergedConfig.model = provider.model || mergedConfig.model || "gpt-5-codex";
2207
+ mergedConfig.model_providers = mergedConfig.model_providers || {};
2208
+ mergedConfig.model_providers[provider.name] = {
2180
2209
  name: provider.name,
2181
2210
  base_url: provider.baseUrl,
2182
2211
  wire_api: "responses",
2183
- // 固定值
2184
2212
  requires_openai_auth: true
2185
- // 固定值
2186
2213
  };
2187
- if (!config.model) {
2188
- config.model = "gpt-5";
2189
- }
2190
- if (!config.model_reasoning_effort) {
2191
- config.model_reasoning_effort = "high";
2192
- }
2193
- if (!("disable_response_storage" in config)) {
2194
- config.disable_response_storage = true;
2195
- }
2196
- fs2.writeFileSync(configPath, (0, import_toml.stringify)(config), { mode: 384 });
2214
+ fs2.writeFileSync(configPath, (0, import_toml.stringify)(mergedConfig), { mode: 384 });
2197
2215
  const authPath = getCodexAuthPath();
2198
2216
  let auth;
2199
2217
  if (fileExists(authPath)) {
@@ -2205,7 +2223,7 @@ function writeCodexConfig(provider) {
2205
2223
  auth.OPENAI_API_KEY = provider.apiKey;
2206
2224
  fs2.writeFileSync(authPath, JSON.stringify(auth, null, 2), { mode: 384 });
2207
2225
  }
2208
- var fs2, import_toml;
2226
+ var fs2, import_toml, CODEX_DEFAULT_CONFIG;
2209
2227
  var init_codex = __esm({
2210
2228
  "../core/dist/writers/codex.js"() {
2211
2229
  "use strict";
@@ -2213,6 +2231,29 @@ var init_codex = __esm({
2213
2231
  import_toml = __toESM(require_toml(), 1);
2214
2232
  init_paths();
2215
2233
  init_file();
2234
+ init_template();
2235
+ CODEX_DEFAULT_CONFIG = {
2236
+ model_reasoning_effort: "high",
2237
+ disable_response_storage: true,
2238
+ sandbox_mode: "workspace-write",
2239
+ windows_wsl_setup_acknowledged: true,
2240
+ features: {
2241
+ plan_tool: true,
2242
+ apply_patch_freeform: true,
2243
+ view_image_tool: true,
2244
+ web_search_request: true,
2245
+ unified_exec: false,
2246
+ streamable_shell: false,
2247
+ rmcp_client: true
2248
+ },
2249
+ tools: {
2250
+ web_search: true,
2251
+ view_image: true
2252
+ },
2253
+ sandbox_workspace_write: {
2254
+ network_access: true
2255
+ }
2256
+ };
2216
2257
  }
2217
2258
  });
2218
2259
 
@@ -2220,42 +2261,38 @@ var init_codex = __esm({
2220
2261
  function writeClaudeConfig(provider) {
2221
2262
  ensureDir(getClaudeDir());
2222
2263
  const configPath = getClaudeConfigPath();
2223
- let settings;
2264
+ let userConfig = {};
2224
2265
  if (fileExists(configPath)) {
2225
2266
  const content = fs3.readFileSync(configPath, "utf-8");
2226
- settings = JSON.parse(content);
2227
- } else {
2228
- settings = {};
2229
- }
2230
- if (!settings.env) {
2231
- settings.env = {};
2232
- }
2233
- settings.env.ANTHROPIC_AUTH_TOKEN = provider.apiKey;
2234
- settings.env.ANTHROPIC_BASE_URL = provider.baseUrl;
2235
- if (!("CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC" in settings.env)) {
2236
- settings.env.CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC = 1;
2267
+ userConfig = JSON.parse(content);
2237
2268
  }
2238
- if (!("CLAUDE_CODE_MAX_OUTPUT_TOKENS" in settings.env)) {
2239
- settings.env.CLAUDE_CODE_MAX_OUTPUT_TOKENS = 32e3;
2240
- }
2241
- if (!settings.permissions) {
2242
- settings.permissions = { allow: [], deny: [] };
2243
- }
2244
- if (!settings.permissions.allow) {
2245
- settings.permissions.allow = [];
2246
- }
2247
- if (!settings.permissions.deny) {
2248
- settings.permissions.deny = [];
2249
- }
2250
- fs3.writeFileSync(configPath, JSON.stringify(settings, null, 2), { mode: 384 });
2269
+ const defaultConfig = replaceVariables(CLAUDE_CONFIG_TEMPLATE, {
2270
+ apiKey: provider.apiKey,
2271
+ baseUrl: provider.baseUrl
2272
+ });
2273
+ const mergedConfig = deepMerge(defaultConfig, userConfig);
2274
+ fs3.writeFileSync(configPath, JSON.stringify(mergedConfig, null, 2), { mode: 384 });
2251
2275
  }
2252
- var fs3;
2276
+ var fs3, CLAUDE_CONFIG_TEMPLATE;
2253
2277
  var init_claude = __esm({
2254
2278
  "../core/dist/writers/claude.js"() {
2255
2279
  "use strict";
2256
2280
  fs3 = __toESM(require("fs"), 1);
2257
2281
  init_paths();
2258
2282
  init_file();
2283
+ init_template();
2284
+ CLAUDE_CONFIG_TEMPLATE = {
2285
+ env: {
2286
+ ANTHROPIC_AUTH_TOKEN: "{{apiKey}}",
2287
+ ANTHROPIC_BASE_URL: "{{baseUrl}}",
2288
+ CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: 1,
2289
+ CLAUDE_CODE_MAX_OUTPUT_TOKENS: 32e3
2290
+ },
2291
+ permissions: {
2292
+ allow: [],
2293
+ deny: []
2294
+ }
2295
+ };
2259
2296
  }
2260
2297
  });
2261
2298
 
@@ -2342,8 +2379,8 @@ function createCodexManager() {
2342
2379
  ensureDir(getCcmanDir());
2343
2380
  const initialConfig = {
2344
2381
  providers: [],
2345
- presets: [...CODEX_PRESETS]
2346
- // 初始化内置预置到配置文件
2382
+ presets: []
2383
+ // 只存储用户自定义预置
2347
2384
  };
2348
2385
  writeJSON(configPath, initialConfig);
2349
2386
  return initialConfig;
@@ -2366,6 +2403,8 @@ function createCodexManager() {
2366
2403
  name: input.name,
2367
2404
  baseUrl: input.baseUrl,
2368
2405
  apiKey: input.apiKey,
2406
+ model: input.model,
2407
+ // 保存 model 字段
2369
2408
  createdAt: timestamp,
2370
2409
  lastModified: timestamp
2371
2410
  };
@@ -2387,7 +2426,8 @@ function createCodexManager() {
2387
2426
  },
2388
2427
  findByName(name) {
2389
2428
  const config = loadConfig2();
2390
- return config.providers.find((p) => p.name === name);
2429
+ const lowerName = name.toLowerCase();
2430
+ return config.providers.find((p) => p.name.toLowerCase() === lowerName);
2391
2431
  },
2392
2432
  switch(id) {
2393
2433
  const config = loadConfig2();
@@ -2426,6 +2466,8 @@ function createCodexManager() {
2426
2466
  provider.baseUrl = updates.baseUrl;
2427
2467
  if (updates.apiKey !== void 0)
2428
2468
  provider.apiKey = updates.apiKey;
2469
+ if (updates.model !== void 0)
2470
+ provider.model = updates.model;
2429
2471
  provider.lastModified = Date.now();
2430
2472
  saveConfig2(config);
2431
2473
  if (config.currentProviderId === id) {
@@ -2535,8 +2577,8 @@ function createClaudeManager() {
2535
2577
  ensureDir(getCcmanDir());
2536
2578
  const initialConfig = {
2537
2579
  providers: [],
2538
- presets: [...CC_PRESETS]
2539
- // 初始化内置预置到配置文件
2580
+ presets: []
2581
+ // 只存储用户自定义预置
2540
2582
  };
2541
2583
  writeJSON(configPath, initialConfig);
2542
2584
  return initialConfig;
@@ -2580,7 +2622,8 @@ function createClaudeManager() {
2580
2622
  },
2581
2623
  findByName(name) {
2582
2624
  const config = loadConfig2();
2583
- return config.providers.find((p) => p.name === name);
2625
+ const lowerName = name.toLowerCase();
2626
+ return config.providers.find((p) => p.name.toLowerCase() === lowerName);
2584
2627
  },
2585
2628
  switch(id) {
2586
2629
  const config = loadConfig2();
@@ -16471,6 +16514,7 @@ async function downloadFromCloud(config, password) {
16471
16514
  // 保留本地 presets
16472
16515
  };
16473
16516
  writeJSON(codexConfigPath, newCodexConfig);
16517
+ applyCurrentProvider("codex", newCodexConfig);
16474
16518
  }
16475
16519
  if (remoteClaudeConfig && decryptedClaudeProviders) {
16476
16520
  const newClaudeConfig = {
@@ -16480,8 +16524,9 @@ async function downloadFromCloud(config, password) {
16480
16524
  // 保留本地 presets
16481
16525
  };
16482
16526
  writeJSON(claudeConfigPath, newClaudeConfig);
16527
+ applyCurrentProvider("claude", newClaudeConfig);
16483
16528
  }
16484
- console.log("\u2705 \u914D\u7F6E\u5DF2\u4ECE\u4E91\u7AEF\u4E0B\u8F7D\u5E76\u8986\u76D6\u672C\u5730");
16529
+ console.log("\u2705 \u914D\u7F6E\u5DF2\u4ECE\u4E91\u7AEF\u4E0B\u8F7D\u5E76\u5E94\u7528");
16485
16530
  return backupPaths;
16486
16531
  } catch (error) {
16487
16532
  for (const backupPath of backupPaths) {
@@ -16559,6 +16604,8 @@ async function mergeSync(config, password) {
16559
16604
  };
16560
16605
  writeJSON(codexConfigPath, mergedCodexConfig);
16561
16606
  writeJSON(claudeConfigPath, mergedClaudeConfig);
16607
+ applyCurrentProvider("codex", mergedCodexConfig);
16608
+ applyCurrentProvider("claude", mergedClaudeConfig);
16562
16609
  const encryptedCodexProviders = encryptProviders(codexMergeResult.merged, password);
16563
16610
  const encryptedClaudeProviders = encryptProviders(claudeMergeResult.merged, password);
16564
16611
  const encryptedCodexConfig = {
@@ -16588,6 +16635,20 @@ async function mergeSync(config, password) {
16588
16635
  throw new Error(`\u5408\u5E76\u914D\u7F6E\u5931\u8D25\uFF0C\u5DF2\u6062\u590D\u5907\u4EFD: ${error.message}`);
16589
16636
  }
16590
16637
  }
16638
+ function applyCurrentProvider(tool, config) {
16639
+ if (!config.currentProviderId) {
16640
+ return;
16641
+ }
16642
+ const provider = config.providers.find((p) => p.id === config.currentProviderId);
16643
+ if (!provider) {
16644
+ return;
16645
+ }
16646
+ if (tool === "codex") {
16647
+ writeCodexConfig(provider);
16648
+ } else {
16649
+ writeClaudeConfig(provider);
16650
+ }
16651
+ }
16591
16652
  var import_fs2, import_path18, CODEX_REMOTE_PATH, CLAUDE_REMOTE_PATH;
16592
16653
  var init_sync_v2 = __esm({
16593
16654
  "../core/dist/sync/sync-v2.js"() {
@@ -16600,6 +16661,8 @@ var init_sync_v2 = __esm({
16600
16661
  init_merge2();
16601
16662
  init_paths();
16602
16663
  init_file();
16664
+ init_codex();
16665
+ init_claude();
16603
16666
  CODEX_REMOTE_PATH = ".ccman/codex.json";
16604
16667
  CLAUDE_REMOTE_PATH = ".ccman/claude.json";
16605
16668
  }
@@ -17486,6 +17549,7 @@ var import_chalk27 = __toESM(require("chalk"));
17486
17549
 
17487
17550
  // src/utils/logo.ts
17488
17551
  var import_chalk = __toESM(require("chalk"));
17552
+ init_dist4();
17489
17553
  function printLogo() {
17490
17554
  console.log(
17491
17555
  import_chalk.default.bold(
@@ -17499,7 +17563,9 @@ function printLogo() {
17499
17563
  `
17500
17564
  )
17501
17565
  );
17502
- console.log(import_chalk.default.gray(" Codex/Claude Code API \u670D\u52A1\u5546\u914D\u7F6E\u7BA1\u7406\u5DE5\u5177\n"));
17566
+ console.log(import_chalk.default.gray(" Codex/Claude Code API \u670D\u52A1\u5546\u914D\u7F6E\u7BA1\u7406\u5DE5\u5177"));
17567
+ console.log(import_chalk.default.gray(` \u7248\u672C ${VERSION}
17568
+ `));
17503
17569
  }
17504
17570
 
17505
17571
  // src/commands/codex/add.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccman",
3
- "version": "3.0.18",
3
+ "version": "3.0.19",
4
4
  "description": "Manage Codex and Claude Code API service provider configurations",
5
5
  "main": "./dist/index.js",
6
6
  "bin": {