ccman 3.3.5 → 3.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -95,7 +95,7 @@ $ ccman cx list
95
95
  https://api.openai.com/v1
96
96
 
97
97
  ○ GMN
98
- https://gmn.chuangzuoli.cn/openai
98
+ https://gmn.chuangzuoli.com
99
99
  ```
100
100
 
101
101
  ```bash
@@ -231,29 +231,27 @@ ccman mcp remove # 删除 MCP 服务器
231
231
  | 预设名称 | Base URL |
232
232
  |---------|----------|
233
233
  | Anthropic Official | `https://api.anthropic.com` |
234
- | GMN | `https://gmn.chuangzuoli.cn/api` |
234
+ | GMN | `https://gmn.chuangzuoli.com/api` |
235
235
 
236
236
  ### Gemini CLI 预设(2 个)
237
237
 
238
238
  | 预设名称 | Base URL |
239
239
  |---------|----------|
240
240
  | Google Gemini (API Key) | 官方默认 |
241
- | GMN | `https://gmn.chuangzuoli.cn/gemini` |
241
+ | GMN | `https://gmn.chuangzuoli.com` |
242
242
 
243
- ### Codex 预设(3 个)
243
+ ### Codex 预设(2 个)
244
244
 
245
245
  | 预设名称 | Base URL |
246
246
  |---------|----------|
247
247
  | OpenAI Official | `https://api.openai.com/v1` |
248
- | GMN | `https://gmn.chuangzuoli.cn/openai` |
249
- | GMN (COM) | `https://gmn.chuangzuoli.com` |
248
+ | GMN | `https://gmn.chuangzuoli.com` |
250
249
 
251
- ### OpenCode 预设(2 个)
250
+ ### OpenCode 预设(1 个)
252
251
 
253
252
  | 预设名称 | Base URL |
254
253
  |---------|----------|
255
- | GMN | `https://gmn.chuangzuoli.cn/openai` |
256
- | GMN (COM) | `https://gmn.chuangzuoli.com` |
254
+ | GMN | `https://gmn.chuangzuoli.com` |
257
255
 
258
256
  ### MCP 预设(多个)
259
257
 
@@ -296,7 +294,7 @@ $ ccman cx current
296
294
 
297
295
  GMN
298
296
  ID: codex-1760178741529-abc123
299
- URL: https://gmn.chuangzuoli.cn/openai
297
+ URL: https://gmn.chuangzuoli.com
300
298
  最后使用: 2025/10/11 18:32:25
301
299
  ```
302
300
 
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ var init_package = __esm({
15
15
  "../core/package.json"() {
16
16
  package_default = {
17
17
  name: "@ccman/core",
18
- version: "3.3.5",
18
+ version: "3.3.6",
19
19
  type: "module",
20
20
  description: "Core business logic for ccman - Manage Codex, Claude Code, Gemini CLI, and MCP configurations",
21
21
  main: "./dist/index.js",
@@ -284,6 +284,12 @@ function resolveTemplatePath(relativePath) {
284
284
  }
285
285
  return null;
286
286
  }
287
+ function resolveCodexProviderKey(provider) {
288
+ const baseUrl = (provider.baseUrl || "").toLowerCase();
289
+ if (baseUrl.includes("gmn.chuangzuoli.com"))
290
+ return "gmn";
291
+ return provider.name;
292
+ }
287
293
  function loadCodexTemplateConfig() {
288
294
  try {
289
295
  const templatePath = resolveTemplatePath("codex/config.toml");
@@ -305,11 +311,31 @@ function writeCodexConfig(provider) {
305
311
  }
306
312
  const templateConfig = loadCodexTemplateConfig();
307
313
  const mergedConfig = deepMerge(templateConfig, userConfig);
308
- mergedConfig.model_provider = provider.name;
309
- mergedConfig.model = provider.model || mergedConfig.model || "gpt-5-codex";
314
+ if (mergedConfig.features && typeof mergedConfig.features === "object" && !Array.isArray(mergedConfig.features) && "web_search_request" in mergedConfig.features) {
315
+ delete mergedConfig.features.web_search_request;
316
+ }
317
+ if (mergedConfig.features && typeof mergedConfig.features === "object" && !Array.isArray(mergedConfig.features)) {
318
+ for (const key of ["plan_tool", "view_image_tool", "rmcp_client", "streamable_shell"]) {
319
+ if (key in mergedConfig.features) {
320
+ delete mergedConfig.features[key];
321
+ }
322
+ }
323
+ if (Object.keys(mergedConfig.features).length === 0) {
324
+ delete mergedConfig.features;
325
+ }
326
+ }
327
+ if (!mergedConfig.web_search) {
328
+ mergedConfig.web_search = "live";
329
+ }
330
+ const providerKey = resolveCodexProviderKey(provider);
331
+ mergedConfig.model_provider = providerKey;
332
+ mergedConfig.model = provider.model || mergedConfig.model || "gpt-5.2-codex";
310
333
  mergedConfig.model_providers = mergedConfig.model_providers || {};
311
- mergedConfig.model_providers[provider.name] = {
312
- name: provider.name,
334
+ if (providerKey !== provider.name) {
335
+ delete mergedConfig.model_providers[provider.name];
336
+ }
337
+ mergedConfig.model_providers[providerKey] = {
338
+ name: providerKey,
313
339
  base_url: provider.baseUrl,
314
340
  wire_api: "responses",
315
341
  requires_openai_auth: true
@@ -336,48 +362,15 @@ var init_codex = __esm({
336
362
  __filename = fileURLToPath(import.meta.url);
337
363
  __dirname = path3.dirname(__filename);
338
364
  CODEX_DEFAULT_CONFIG = {
339
- model: "gpt-5.1-code-max",
365
+ model: "gpt-5.2-codex",
340
366
  model_reasoning_effort: "high",
367
+ model_verbosity: "high",
368
+ web_search: "live",
341
369
  disable_response_storage: true,
342
- sandbox_mode: "danger-full-access",
343
370
  windows_wsl_setup_acknowledged: true,
344
- approval_policy: "never",
345
- profile: "auto-max",
346
- file_opener: "vscode",
347
- history: {
348
- persistence: "save-all"
349
- },
350
- tui: {
351
- notifications: true
352
- },
353
- shell_environment_policy: {
354
- inherit: "all",
355
- ignore_default_excludes: false
356
- },
357
- features: {
358
- plan_tool: true,
359
- apply_patch_freeform: true,
360
- view_image_tool: true,
361
- web_search_request: true,
362
- unified_exec: false,
363
- streamable_shell: false,
364
- rmcp_client: true
365
- },
371
+ sandbox_mode: "workspace-write",
366
372
  sandbox_workspace_write: {
367
373
  network_access: true
368
- },
369
- profiles: {
370
- "auto-max": {
371
- approval_policy: "never",
372
- sandbox_mode: "workspace-write"
373
- },
374
- review: {
375
- approval_policy: "on-request",
376
- sandbox_mode: "workspace-write"
377
- }
378
- },
379
- notice: {
380
- hide_gpt5_1_migration_prompt: true
381
374
  }
382
375
  };
383
376
  }
@@ -629,11 +622,6 @@ var init_codex2 = __esm({
629
622
  },
630
623
  {
631
624
  name: "GMN",
632
- baseUrl: "https://gmn.chuangzuoli.cn/openai",
633
- description: "GMN \u670D\u52A1 (OpenAI/Codex \u517C\u5BB9)"
634
- },
635
- {
636
- name: "GMN (COM)",
637
625
  baseUrl: "https://gmn.chuangzuoli.com",
638
626
  description: "GMN \u670D\u52A1 (OpenAI/Codex \u517C\u5BB9)"
639
627
  }
@@ -654,7 +642,7 @@ var init_claude2 = __esm({
654
642
  },
655
643
  {
656
644
  name: "GMN",
657
- baseUrl: "https://gmn.chuangzuoli.cn/api",
645
+ baseUrl: "https://gmn.chuangzuoli.com/api",
658
646
  description: "GMN \u670D\u52A1 (Claude \u517C\u5BB9)"
659
647
  }
660
648
  ];
@@ -744,7 +732,7 @@ var init_gemini = __esm({
744
732
  },
745
733
  {
746
734
  name: "GMN",
747
- baseUrl: "https://gmn.chuangzuoli.cn/gemini",
735
+ baseUrl: "https://gmn.chuangzuoli.com",
748
736
  description: "GMN \u670D\u52A1 (Gemini \u517C\u5BB9)"
749
737
  }
750
738
  ];
@@ -759,12 +747,7 @@ var init_opencode = __esm({
759
747
  OPENCODE_PRESETS = [
760
748
  {
761
749
  name: "GMN",
762
- baseUrl: "https://gmn.chuangzuoli.cn/openai",
763
- description: "GMN \u670D\u52A1 (OpenCode \u517C\u5BB9)"
764
- },
765
- {
766
- name: "GMN (COM)",
767
- baseUrl: "https://gmn.chuangzuoli.com/v1",
750
+ baseUrl: "https://gmn.chuangzuoli.com",
768
751
  description: "GMN \u670D\u52A1 (OpenCode \u517C\u5BB9)"
769
752
  }
770
753
  ];
@@ -6229,14 +6212,11 @@ var PROVIDER_NAME = "GMN";
6229
6212
  var VALID_PLATFORMS = ["claude", "codex", "gemini", "opencode"];
6230
6213
  var DEFAULT_PLATFORMS = ["codex", "opencode"];
6231
6214
  var GMN_BASE_URLS = {
6232
- claude: "https://gmn.chuangzuoli.cn/api",
6233
- gemini: "https://gmn.chuangzuoli.cn/gemini"
6215
+ claude: "https://gmn.chuangzuoli.com/api",
6216
+ gemini: "https://gmn.chuangzuoli.com"
6234
6217
  };
6235
- var GMN_OPENAI_BASE_URLS = {
6236
- cn: "https://gmn.chuangzuoli.cn/openai",
6237
- com: "https://gmn.chuangzuoli.com"
6238
- };
6239
- var TOTAL_STEPS = 4;
6218
+ var GMN_OPENAI_BASE_URL = "https://gmn.chuangzuoli.com";
6219
+ var TOTAL_STEPS = 3;
6240
6220
  function renderStep(current, total, title) {
6241
6221
  const barLength = total;
6242
6222
  const filledLength = Math.min(current, total);
@@ -6258,7 +6238,7 @@ function printBanner() {
6258
6238
  ].join("\n")
6259
6239
  )
6260
6240
  );
6261
- console.log(chalk47.gray("\u81EA\u52A8\u5199\u5165\u9009\u4E2D\u5DE5\u5177\u914D\u7F6E\uFF0C\u652F\u6301\u591A\u9009\u4E0E\u7AEF\u70B9\u9009\u62E9\u3002\n"));
6241
+ console.log(chalk47.gray("\u81EA\u52A8\u5199\u5165\u9009\u4E2D\u5DE5\u5177\u914D\u7F6E\uFF0C\u652F\u6301\u591A\u9009\u3002\n"));
6262
6242
  }
6263
6243
  function printKeyNotice() {
6264
6244
  console.log(
@@ -6356,33 +6336,7 @@ async function resolvePlatforms(platformArg) {
6356
6336
  }
6357
6337
  return promptPlatforms();
6358
6338
  }
6359
- async function resolveOpenAIDomain(domainArg, platforms) {
6360
- const needsOpenAI = platforms.includes("codex") || platforms.includes("opencode");
6361
- if (!needsOpenAI) {
6362
- return "cn";
6363
- }
6364
- if (domainArg && domainArg.trim().length > 0) {
6365
- const normalized = domainArg.trim().toLowerCase();
6366
- if (normalized === "cn" || normalized === "com") {
6367
- return normalized;
6368
- }
6369
- throw new Error(`\u65E0\u6548\u7684 domain: ${domainArg} (\u53EF\u9009: cn, com)`);
6370
- }
6371
- const answers = await inquirer33.prompt([
6372
- {
6373
- type: "list",
6374
- name: "domain",
6375
- message: "\u9009\u62E9 Codex/OpenCode \u7684 OpenAI Base URL\uFF08\u53EA\u5F71\u54CD\u8FD9\u4E24\u4E2A\u5DE5\u5177\uFF09:",
6376
- choices: [
6377
- { name: `CN\uFF08\u56FD\u5185\uFF09 ${GMN_OPENAI_BASE_URLS.cn}`, value: "cn" },
6378
- { name: `COM\uFF08\u56FD\u9645\uFF09 ${GMN_OPENAI_BASE_URLS.com}`, value: "com" }
6379
- ],
6380
- default: "cn"
6381
- }
6382
- ]);
6383
- return answers.domain;
6384
- }
6385
- async function gmnCommand(apiKey, platformArg, domainArg) {
6339
+ async function gmnCommand(apiKey, platformArg) {
6386
6340
  printBanner();
6387
6341
  let platforms;
6388
6342
  try {
@@ -6395,26 +6349,9 @@ ${renderStep(1, TOTAL_STEPS, "\u9009\u62E9\u8981\u914D\u7F6E\u7684\u5DE5\u5177")
6395
6349
  }
6396
6350
  console.log(chalk47.gray(`\u5DF2\u9009\u62E9: ${platforms.join(", ")}`));
6397
6351
  printKeyNotice();
6398
- let openaiDomain;
6399
- try {
6400
- if (platforms.includes("codex") || platforms.includes("opencode")) {
6401
- console.log(
6402
- chalk47.cyan(`
6403
- ${renderStep(2, TOTAL_STEPS, "\u9009\u62E9 OpenAI \u7AEF\u70B9 (\u4EC5 Codex/OpenCode)")}`)
6404
- );
6405
- } else {
6406
- console.log(chalk47.cyan(`
6407
- ${renderStep(2, TOTAL_STEPS, "\u9009\u62E9 OpenAI \u7AEF\u70B9 (\u5DF2\u8DF3\u8FC7)")}`));
6408
- console.log(chalk47.gray("\u672A\u9009\u62E9 Codex/OpenCode\uFF0C\u5C06\u8DF3\u8FC7\u6B64\u6B65\u9AA4\u3002"));
6409
- }
6410
- openaiDomain = await resolveOpenAIDomain(domainArg, platforms);
6411
- } catch (error) {
6412
- console.error(chalk47.red(`\u274C ${error.message}`));
6413
- process.exit(1);
6414
- }
6415
6352
  let resolvedApiKey = apiKey?.trim();
6416
6353
  console.log(chalk47.cyan(`
6417
- ${renderStep(3, TOTAL_STEPS, "\u8F93\u5165 API Key")}`));
6354
+ ${renderStep(2, TOTAL_STEPS, "\u8F93\u5165 API Key")}`));
6418
6355
  if (!resolvedApiKey) {
6419
6356
  resolvedApiKey = await promptApiKey();
6420
6357
  } else {
@@ -6424,7 +6361,7 @@ ${renderStep(3, TOTAL_STEPS, "\u8F93\u5165 API Key")}`));
6424
6361
  console.error(chalk47.red("\u274C \u9519\u8BEF: API Key \u4E0D\u80FD\u4E3A\u7A7A"));
6425
6362
  process.exit(1);
6426
6363
  }
6427
- const openaiBaseUrl = GMN_OPENAI_BASE_URLS[openaiDomain];
6364
+ const openaiBaseUrl = GMN_OPENAI_BASE_URL;
6428
6365
  const platformBaseUrls = {
6429
6366
  claude: GMN_BASE_URLS.claude,
6430
6367
  codex: openaiBaseUrl,
@@ -6432,10 +6369,10 @@ ${renderStep(3, TOTAL_STEPS, "\u8F93\u5165 API Key")}`));
6432
6369
  opencode: openaiBaseUrl
6433
6370
  };
6434
6371
  console.log(chalk47.cyan(`
6435
- ${renderStep(4, TOTAL_STEPS, "\u5F00\u59CB\u5199\u5165\u914D\u7F6E")}`));
6372
+ ${renderStep(3, TOTAL_STEPS, "\u5F00\u59CB\u5199\u5165\u914D\u7F6E")}`));
6436
6373
  console.log(chalk47.gray(`\u5DF2\u9009\u62E9\u5E73\u53F0: ${platforms.join(", ")}`));
6437
6374
  if (platforms.includes("codex") || platforms.includes("opencode")) {
6438
- console.log(chalk47.gray(`OpenAI \u7AEF\u70B9: ${openaiBaseUrl}`));
6375
+ console.log(chalk47.gray(`OpenAI Base URL: ${openaiBaseUrl}`));
6439
6376
  }
6440
6377
  printWriteTargets(platforms);
6441
6378
  console.log();
@@ -6542,8 +6479,8 @@ sync.action(async () => {
6542
6479
  });
6543
6480
  exportCommand(program);
6544
6481
  importCommand(program);
6545
- 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)").option("-d, --domain <domain>", "\u9009\u62E9 OpenAI \u7AEF\u70B9 (cn|com)").action(async (apiKey, options) => {
6546
- await gmnCommand(apiKey, options.platform, options.domain);
6482
+ 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) => {
6483
+ await gmnCommand(apiKey, options.platform);
6547
6484
  });
6548
6485
  (async () => {
6549
6486
  if (!process.argv.slice(2).length) {
@@ -1,109 +1,21 @@
1
1
  ########################################
2
- # 基础设置:通用 Codex 默认配置
2
+ # Codex 最小模板(ccman 默认)
3
+ #
4
+ # - model_provider 与 [model_providers.*] 由 ccman 根据当前服务商自动写入
5
+ # - 配置越少越稳定;需要扩展再手动加
3
6
  ########################################
4
7
 
5
- model = "gpt-5.1-code-max"
6
-
7
- # model_provider 与 model_providers 由 ccman 根据当前服务商自动写入
8
- # 如需手动指定可自行在此添加:
9
- # model_provider = "YourProviderName"
10
-
11
- # 理力度设置
8
+ model = "gpt-5.2-codex"
12
9
  model_reasoning_effort = "high"
13
-
14
- # 存储策略
10
+ model_verbosity = "high"
15
11
  disable_response_storage = true
16
-
17
- # 沙箱模式
18
- sandbox_mode = "danger-full-access" # 完全禁用沙箱
19
- # sandbox_mode = "workspace-write"
20
12
  windows_wsl_setup_acknowledged = true
21
13
 
22
- # 命令审批策略(只影响本地行为,不会影响上游服务商)
23
- # - "never":尽量自动执行命令(自动模式)
24
- approval_policy = "never"
25
-
26
- # 默认使用的 profile(下面定义,只改行为,不改 model)
27
- profile = "auto-max"
28
-
29
- # 打开文件用哪个编辑器
30
- file_opener = "vscode"
31
-
32
-
33
- ########################################
34
- # 历史记录 & 终端 UI(纯本地)
35
- ########################################
36
-
37
- [history]
38
- persistence = "save-all"
14
+ # Web 搜索策略(替代旧的 [features].web_search_request)
15
+ web_search = "live" # "live" | "cached" | "disabled"
39
16
 
40
- [tui]
41
- notifications = true
42
-
43
-
44
- ########################################
45
- # Shell 环境(纯本地)
46
- ########################################
47
-
48
- [shell_environment_policy]
49
- inherit = "all"
50
- ignore_default_excludes = false
51
- # 如有需要可以再加 exclude / include_only / set
52
-
53
-
54
- ########################################
55
- # workspace-write 沙箱设置(纯本地)
56
- ########################################
17
+ # 沙箱与网络访问:workspace-write + 允许联网
18
+ sandbox_mode = "workspace-write"
57
19
 
58
20
  [sandbox_workspace_write]
59
21
  network_access = true
60
- # 可按需再加 writable_roots / exclude_tmpdir_env_var / exclude_slash_tmp
61
-
62
-
63
- ########################################
64
- # Features(完全沿用你原来的 + 本地能力)
65
- ########################################
66
-
67
- [features]
68
- plan_tool = true
69
- apply_patch_freeform = true
70
- view_image_tool = true
71
- web_search_request = true
72
- unified_exec = false
73
- streamable_shell = false
74
- rmcp_client = true
75
- # 如以后确认其他服务完全兼容,可以考虑再打开 ghost_commit 等
76
-
77
-
78
- ########################################
79
- # Profiles:只改“行为”,不改模型/提供方
80
- ########################################
81
-
82
- [profiles.auto-max]
83
- # 使用顶层的 model / model_provider(即 gpt-5.1-codex + OpenAI/GMN)
84
- # 这里只覆盖“本地行为”,例如审批和沙箱
85
- approval_policy = "never"
86
- sandbox_mode = "workspace-write"
87
-
88
- [profiles.review]
89
- # 审核模式:命令前多问一句(适合公司仓库)
90
- approval_policy = "on-request"
91
- sandbox_mode = "workspace-write"
92
-
93
-
94
- ########################################
95
- # 其它提示 / 杂项
96
- ########################################
97
-
98
- [notice]
99
- hide_gpt5_1_migration_prompt = true
100
-
101
- ########################################
102
- # 模型提供方示例(仅注释示例,不会生效)
103
- ########################################
104
-
105
- # [model_providers.gmn]
106
- # name = "GMN"
107
- # base_url = "https://gmn.chuangzuoli.cn/openai"
108
- # wire_api = "responses"
109
- # requires_openai_auth = true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccman",
3
- "version": "3.3.5",
3
+ "version": "3.3.6",
4
4
  "type": "module",
5
5
  "description": "Manage Codex, Claude Code, Gemini CLI, OpenCode, and MCP API service provider configurations",
6
6
  "main": "./dist/index.js",