zcf 3.5.0 → 3.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -102,9 +102,16 @@ If you find this project helpful, please consider sponsoring its development. Yo
102
102
  ### Our Sponsors
103
103
 
104
104
  A huge thank you to all our sponsors for their generous support!
105
+
106
+ 【Corporate Sponsors】
107
+
105
108
  - [302.AI](https://share.302.ai/gAT9VG) (first corporate sponsorship 🤠)
106
109
  - [GLM](https://z.ai/subscribe?ic=8JVLJQFSKB) (first AI model sponsorship 🤖)
107
110
  - [PackyCode](https://www.packyapi.com/register?aff=zcf) (first API proxy service sponsor 🧝🏻‍♀️)
111
+ - [UUCode](https://www.uucode.org/auth?ref=JQ2DJ1T8) (sponsored $100 proxy credits 💰)
112
+
113
+ 【Individual Sponsors】
114
+
108
115
  - Tc (first sponsor)
109
116
  - Argolinhas (first ko-fi sponsor ٩(•̤̀ᵕ•̤́๑))
110
117
  - r\*r (first anonymous sponsor 🤣)
@@ -13,7 +13,7 @@ import 'inquirer-toggle';
13
13
  import 'ora';
14
14
  import 'tinyexec';
15
15
  import 'semver';
16
- import 'smol-toml';
16
+ import '@rainbowatcher/toml-edit-js';
17
17
  import 'node:fs/promises';
18
18
  import 'i18next';
19
19
  import 'i18next-fs-backend';
@@ -183,15 +183,15 @@ class ClaudeCodeConfigManager {
183
183
  * Apply profile settings to Claude Code runtime
184
184
  */
185
185
  static async applyProfileSettings(profile) {
186
- const { ensureI18nInitialized, i18n } = await import('./simple-config.mjs').then(function (n) { return n.bg; });
186
+ const { ensureI18nInitialized, i18n } = await import('./simple-config.mjs').then(function (n) { return n.bf; });
187
187
  ensureI18nInitialized();
188
188
  try {
189
189
  if (!profile) {
190
- const { switchToOfficialLogin } = await import('./simple-config.mjs').then(function (n) { return n.bk; });
190
+ const { switchToOfficialLogin } = await import('./simple-config.mjs').then(function (n) { return n.bj; });
191
191
  switchToOfficialLogin();
192
192
  return;
193
193
  }
194
- const { readJsonConfig: readJsonConfig2, writeJsonConfig } = await import('./simple-config.mjs').then(function (n) { return n.bi; });
194
+ const { readJsonConfig: readJsonConfig2, writeJsonConfig } = await import('./simple-config.mjs').then(function (n) { return n.bh; });
195
195
  const settings = readJsonConfig2(SETTINGS_FILE) || {};
196
196
  if (!settings.env)
197
197
  settings.env = {};
@@ -204,7 +204,7 @@ class ClaudeCodeConfigManager {
204
204
  settings.env.ANTHROPIC_AUTH_TOKEN = profile.apiKey;
205
205
  delete settings.env.ANTHROPIC_API_KEY;
206
206
  } else if (profile.authType === "ccr_proxy") {
207
- const { readCcrConfig } = await import('./simple-config.mjs').then(function (n) { return n.bl; });
207
+ const { readCcrConfig } = await import('./simple-config.mjs').then(function (n) { return n.bk; });
208
208
  const ccrConfig = readCcrConfig();
209
209
  if (!ccrConfig) {
210
210
  throw new Error(i18n.t("ccr:ccrNotConfigured") || "CCR proxy configuration not found");
@@ -239,7 +239,7 @@ class ClaudeCodeConfigManager {
239
239
  clearModelEnv(settings.env);
240
240
  }
241
241
  writeJsonConfig(SETTINGS_FILE, settings);
242
- const { setPrimaryApiKey, addCompletedOnboarding } = await import('./simple-config.mjs').then(function (n) { return n.bj; });
242
+ const { setPrimaryApiKey, addCompletedOnboarding } = await import('./simple-config.mjs').then(function (n) { return n.bi; });
243
243
  setPrimaryApiKey();
244
244
  addCompletedOnboarding();
245
245
  if (shouldRestartCcr) {
@@ -600,7 +600,7 @@ class ClaudeCodeConfigManager {
600
600
  */
601
601
  static async syncCcrProfile() {
602
602
  try {
603
- const { readCcrConfig } = await import('./simple-config.mjs').then(function (n) { return n.bl; });
603
+ const { readCcrConfig } = await import('./simple-config.mjs').then(function (n) { return n.bk; });
604
604
  const ccrConfig = readCcrConfig();
605
605
  if (!ccrConfig) {
606
606
  await this.ensureCcrProfileExists(ccrConfig);
@@ -14,7 +14,7 @@ import 'inquirer-toggle';
14
14
  import 'ora';
15
15
  import 'tinyexec';
16
16
  import 'semver';
17
- import 'smol-toml';
17
+ import '@rainbowatcher/toml-edit-js';
18
18
  import 'node:fs/promises';
19
19
  import 'i18next';
20
20
  import 'i18next-fs-backend';
@@ -14,7 +14,7 @@ import 'inquirer-toggle';
14
14
  import 'ora';
15
15
  import 'tinyexec';
16
16
  import 'semver';
17
- import 'smol-toml';
17
+ import '@rainbowatcher/toml-edit-js';
18
18
  import 'node:fs/promises';
19
19
  import 'i18next';
20
20
  import 'i18next-fs-backend';
@@ -152,7 +152,7 @@ async function handleAddProvider() {
152
152
  wireApi: selectedProvider === "custom" ? answers.wireApi : prefilledWireApi,
153
153
  tempEnvKey: `${providerId.toUpperCase().replace(/-/g, "_")}_API_KEY`,
154
154
  requiresOpenaiAuth: true,
155
- model: prefilledModel || "gpt-5-codex"
155
+ model: prefilledModel || "gpt-5.2"
156
156
  // Use provider's default model or fallback
157
157
  };
158
158
  const result = await addProviderToExisting(provider, answers.apiKey.trim(), true);
@@ -244,7 +244,7 @@ async function handleEditProvider(providers) {
244
244
  type: "input",
245
245
  name: "model",
246
246
  message: i18n.t("codex:providerModelPrompt"),
247
- default: provider.model || "gpt-5-codex",
247
+ default: provider.model || "gpt-5.2",
248
248
  validate: (input) => !!input.trim() || i18n.t("codex:providerModelRequired")
249
249
  }
250
250
  ]);
@@ -336,7 +336,7 @@ ${i18n.t("codex:copyingProvider", { name: provider.name })}`));
336
336
  type: "input",
337
337
  name: "model",
338
338
  message: i18n.t("codex:providerModelPrompt"),
339
- default: provider.model || "gpt-5-codex",
339
+ default: provider.model || "gpt-5.2",
340
340
  validate: (input) => !!input.trim() || i18n.t("codex:providerModelRequired")
341
341
  }
342
342
  ]);
@@ -1,4 +1,4 @@
1
- import { ak as ensureI18nInitialized, ay as readCodexConfig, al as i18n, az as backupCodexComplete, aA as writeCodexConfig, aB as writeAuthFile } from './simple-config.mjs';
1
+ import { ak as ensureI18nInitialized, ay as readCodexConfig, al as i18n, az as backupCodexComplete, aA as writeAuthFile } from './simple-config.mjs';
2
2
  import 'node:fs';
3
3
  import 'node:process';
4
4
  import 'ansis';
@@ -13,7 +13,7 @@ import 'inquirer-toggle';
13
13
  import 'ora';
14
14
  import 'tinyexec';
15
15
  import 'semver';
16
- import 'smol-toml';
16
+ import '@rainbowatcher/toml-edit-js';
17
17
  import 'node:fs/promises';
18
18
  import 'i18next';
19
19
  import 'i18next-fs-backend';
@@ -29,31 +29,6 @@ async function addProviderToExisting(provider, apiKey, allowOverwrite = false) {
29
29
  error: i18n.t("codex:providerManager.providerExists", { id: provider.id })
30
30
  };
31
31
  }
32
- let updatedConfig;
33
- if (!existingConfig) {
34
- updatedConfig = {
35
- model: provider.model || null,
36
- modelProvider: provider.id,
37
- providers: [provider],
38
- mcpServices: [],
39
- managed: true,
40
- otherConfig: []
41
- };
42
- } else if (existingProviderIndex !== -1) {
43
- const updatedProviders = [...existingConfig.providers];
44
- updatedProviders[existingProviderIndex] = provider;
45
- updatedConfig = {
46
- ...existingConfig,
47
- providers: updatedProviders,
48
- modelProvider: existingConfig.modelProvider || provider.id
49
- };
50
- } else {
51
- updatedConfig = {
52
- ...existingConfig,
53
- providers: [...existingConfig.providers, provider],
54
- modelProvider: existingConfig.modelProvider || provider.id
55
- };
56
- }
57
32
  let backupPath;
58
33
  if (existingConfig) {
59
34
  const backup = backupCodexComplete();
@@ -65,7 +40,20 @@ async function addProviderToExisting(provider, apiKey, allowOverwrite = false) {
65
40
  }
66
41
  backupPath = backup || void 0;
67
42
  }
68
- writeCodexConfig(updatedConfig);
43
+ const { updateCodexApiFields, upsertCodexProvider } = await import('./simple-config.mjs').then(function (n) { return n.bm; });
44
+ if (!existingConfig) {
45
+ updateCodexApiFields({
46
+ model: provider.model,
47
+ modelProvider: provider.id,
48
+ modelProviderCommented: false
49
+ });
50
+ } else if (!existingConfig.modelProvider) {
51
+ updateCodexApiFields({
52
+ modelProvider: provider.id,
53
+ modelProviderCommented: false
54
+ });
55
+ }
56
+ upsertCodexProvider(provider.id, provider);
69
57
  const authEntries = {};
70
58
  authEntries[provider.tempEnvKey] = apiKey;
71
59
  writeAuthFile(authEntries);
@@ -112,13 +100,8 @@ async function editExistingProvider(providerId, updates) {
112
100
  ...updates.wireApi && { wireApi: updates.wireApi },
113
101
  ...updates.model && { model: updates.model }
114
102
  };
115
- const updatedProviders = [...existingConfig.providers];
116
- updatedProviders[providerIndex] = updatedProvider;
117
- const updatedConfig = {
118
- ...existingConfig,
119
- providers: updatedProviders
120
- };
121
- writeCodexConfig(updatedConfig);
103
+ const { upsertCodexProvider } = await import('./simple-config.mjs').then(function (n) { return n.bm; });
104
+ upsertCodexProvider(providerId, updatedProvider);
122
105
  if (updates.apiKey) {
123
106
  const authEntries = {};
124
107
  authEntries[updatedProvider.tempEnvKey] = updates.apiKey;
@@ -183,12 +166,16 @@ async function deleteProviders(providerIds) {
183
166
  if (providerIds.includes(existingConfig.modelProvider || "")) {
184
167
  newDefaultProvider = remainingProviders[0].id;
185
168
  }
186
- const updatedConfig = {
187
- ...existingConfig,
188
- modelProvider: newDefaultProvider,
189
- providers: remainingProviders
190
- };
191
- writeCodexConfig(updatedConfig);
169
+ const { deleteCodexProvider, updateCodexApiFields } = await import('./simple-config.mjs').then(function (n) { return n.bm; });
170
+ if (newDefaultProvider !== existingConfig.modelProvider) {
171
+ updateCodexApiFields({
172
+ modelProvider: newDefaultProvider,
173
+ modelProviderCommented: false
174
+ });
175
+ }
176
+ for (const providerId of providerIds) {
177
+ deleteCodexProvider(providerId);
178
+ }
192
179
  const result = {
193
180
  success: true,
194
181
  backupPath,
@@ -15,7 +15,7 @@ import 'inquirer-toggle';
15
15
  import 'ora';
16
16
  import 'tinyexec';
17
17
  import 'semver';
18
- import 'smol-toml';
18
+ import '@rainbowatcher/toml-edit-js';
19
19
  import 'node:fs/promises';
20
20
  import 'i18next';
21
21
  import 'i18next-fs-backend';
@@ -13,7 +13,7 @@ import 'inquirer-toggle';
13
13
  import 'ora';
14
14
  import 'tinyexec';
15
15
  import 'semver';
16
- import 'smol-toml';
16
+ import '@rainbowatcher/toml-edit-js';
17
17
  import 'node:fs/promises';
18
18
  import 'i18next';
19
19
  import 'i18next-fs-backend';
@@ -1,6 +1,6 @@
1
1
  import ansis from 'ansis';
2
2
  import inquirer from 'inquirer';
3
- import { al as i18n, ak as ensureI18nInitialized, x as SUPPORTED_LANGS, am as addNumbersToChoices, y as LANG_LABELS, aC as updateZcfConfig, aD as changeLanguage, aE as readZcfConfig, ao as promptBoolean, o as openSettingsJson, d as importRecommendedPermissions, b as importRecommendedEnv, a1 as applyAiLanguageDirective, aF as configureOutputStyle, $ as getExistingModelConfig, X as updateCustomModel, Y as updateDefaultModel, aG as isWindows, F as readMcpConfig, K as fixWindowsMcpConfig, G as writeMcpConfig, aH as selectMcpServices, H as backupMcpConfig, aI as getMcpServices, J as buildMcpServerConfig, I as mergeMcpServers, aJ as isCcrInstalled, aK as installCcr, aL as setupCcrConfiguration, a0 as getExistingApiConfig, a3 as promptApiConfigurationAction, aM as modifyApiConfigPartially, an as validateApiKey, V as configureApi, aN as formatApiKeyDisplay, a2 as switchToOfficialLogin } from './simple-config.mjs';
3
+ import { al as i18n, ak as ensureI18nInitialized, x as SUPPORTED_LANGS, am as addNumbersToChoices, y as LANG_LABELS, aB as updateZcfConfig, aC as changeLanguage, aD as readZcfConfig, ao as promptBoolean, o as openSettingsJson, d as importRecommendedPermissions, b as importRecommendedEnv, a1 as applyAiLanguageDirective, aE as configureOutputStyle, $ as getExistingModelConfig, X as updateCustomModel, Y as updateDefaultModel, aF as isWindows, F as readMcpConfig, K as fixWindowsMcpConfig, G as writeMcpConfig, aG as selectMcpServices, H as backupMcpConfig, aH as getMcpServices, J as buildMcpServerConfig, I as mergeMcpServers, aI as isCcrInstalled, aJ as installCcr, aK as setupCcrConfiguration, a0 as getExistingApiConfig, a3 as promptApiConfigurationAction, aL as modifyApiConfigPartially, an as validateApiKey, V as configureApi, aM as formatApiKeyDisplay, a2 as switchToOfficialLogin } from './simple-config.mjs';
4
4
  import 'node:fs';
5
5
  import 'node:process';
6
6
  import 'node:child_process';
@@ -13,7 +13,7 @@ import 'inquirer-toggle';
13
13
  import 'ora';
14
14
  import 'tinyexec';
15
15
  import 'semver';
16
- import 'smol-toml';
16
+ import '@rainbowatcher/toml-edit-js';
17
17
  import 'node:fs/promises';
18
18
  import 'i18next';
19
19
  import 'i18next-fs-backend';
@@ -351,7 +351,7 @@ ${ansis.blue(`\u2139 ${i18n.t("configuration:existingLanguageConfig") || "Existi
351
351
  return;
352
352
  }
353
353
  }
354
- const { selectAiOutputLanguage } = await import('./simple-config.mjs').then(function (n) { return n.bm; });
354
+ const { selectAiOutputLanguage } = await import('./simple-config.mjs').then(function (n) { return n.bl; });
355
355
  const aiOutputLang = await selectAiOutputLanguage();
356
356
  applyAiLanguageDirective(aiOutputLang);
357
357
  updateZcfConfig({ aiOutputLang });
@@ -390,7 +390,7 @@ async function configureCodexDefaultModelFeature() {
390
390
  if (currentModel) {
391
391
  console.log(`
392
392
  ${ansis.blue(`\u2139 ${i18n.t("configuration:existingModelConfig") || "Existing model configuration"}`)}`);
393
- const modelDisplay = currentModel === "gpt-5-codex" ? "GPT-5-Codex" : currentModel === "gpt-5" ? "GPT-5" : currentModel.charAt(0).toUpperCase() + currentModel.slice(1);
393
+ const modelDisplay = currentModel === "gpt-5.2" ? "GPT-5.2" : currentModel === "gpt-5.1-codex-max" ? "GPT-5.1-Codex-Max" : currentModel === "gpt-5.1-codex-mini" ? "GPT-5.1-Codex-Mini" : currentModel.charAt(0).toUpperCase() + currentModel.slice(1);
394
394
  console.log(ansis.gray(` ${i18n.t("configuration:currentModel") || "Current model"}: ${modelDisplay}
395
395
  `));
396
396
  const modify = await promptBoolean({
@@ -408,20 +408,24 @@ ${ansis.blue(`\u2139 ${i18n.t("configuration:existingModelConfig") || "Existing
408
408
  message: i18n.t("configuration:selectDefaultModel") || "Select default model",
409
409
  choices: addNumbersToChoices([
410
410
  {
411
- name: i18n.t("configuration:codexModelOptions.gpt5"),
412
- value: "gpt-5"
411
+ name: i18n.t("configuration:codexModelOptions.gpt51CodexMax"),
412
+ value: "gpt-5.1-codex-max"
413
413
  },
414
414
  {
415
- name: i18n.t("configuration:codexModelOptions.gpt5Codex"),
416
- value: "gpt-5-codex"
415
+ name: i18n.t("configuration:codexModelOptions.gpt51CodexMini"),
416
+ value: "gpt-5.1-codex-mini"
417
+ },
418
+ {
419
+ name: i18n.t("configuration:codexModelOptions.gpt52"),
420
+ value: "gpt-5.2"
417
421
  },
418
422
  {
419
423
  name: i18n.t("configuration:codexModelOptions.custom"),
420
424
  value: "custom"
421
425
  }
422
426
  ]),
423
- default: currentModel ? ["gpt-5", "gpt-5-codex", "custom"].indexOf(currentModel) : 1
424
- // Default to gpt-5-codex
427
+ default: currentModel ? ["gpt-5.1-codex-max", "gpt-5.1-codex-mini", "gpt-5.2", "custom"].indexOf(currentModel) : 2
428
+ // Default to gpt-5.2
425
429
  });
426
430
  if (!model) {
427
431
  await handleCancellation();
@@ -485,7 +489,7 @@ ${ansis.blue(`\u2139 ${i18n.t("configuration:existingLanguageConfig") || "Existi
485
489
  return;
486
490
  }
487
491
  }
488
- const { selectAiOutputLanguage } = await import('./simple-config.mjs').then(function (n) { return n.bm; });
492
+ const { selectAiOutputLanguage } = await import('./simple-config.mjs').then(function (n) { return n.bl; });
489
493
  const aiOutputLang = await selectAiOutputLanguage();
490
494
  await updateCodexLanguageDirective(aiOutputLang);
491
495
  updateZcfConfig({ aiOutputLang });
@@ -500,28 +504,16 @@ ${ansis.blue(`\u2139 ${i18n.t("configuration:existingLanguageConfig") || "Existi
500
504
  }
501
505
  }
502
506
  async function updateCodexModelProvider(modelProvider) {
503
- const { readCodexConfig, writeCodexConfig, backupCodexConfig, getBackupMessage } = await import('./simple-config.mjs').then(function (n) { return n.bn; });
507
+ const { backupCodexConfig, getBackupMessage } = await import('./simple-config.mjs').then(function (n) { return n.bn; });
508
+ const { updateCodexApiFields } = await import('./simple-config.mjs').then(function (n) { return n.bm; });
504
509
  const backupPath = backupCodexConfig();
505
510
  if (backupPath) {
506
511
  console.log(ansis.gray(getBackupMessage(backupPath)));
507
512
  }
508
- const existingConfig = readCodexConfig();
509
- const updatedConfig = {
510
- ...existingConfig,
511
- model: modelProvider,
512
- // Set the model field
513
- modelProvider: existingConfig?.modelProvider || null,
514
- // Preserve existing API provider
515
- providers: existingConfig?.providers || [],
516
- mcpServices: existingConfig?.mcpServices || [],
517
- managed: true,
518
- otherConfig: existingConfig?.otherConfig || [],
519
- modelProviderCommented: existingConfig?.modelProviderCommented
520
- };
521
- writeCodexConfig(updatedConfig);
513
+ updateCodexApiFields({ model: modelProvider });
522
514
  }
523
515
  async function ensureLanguageDirectiveInAgents(aiOutputLang) {
524
- const { readFile, writeFile, exists } = await import('./simple-config.mjs').then(function (n) { return n.bh; });
516
+ const { readFile, writeFile, exists } = await import('./simple-config.mjs').then(function (n) { return n.bg; });
525
517
  const { homedir } = await import('node:os');
526
518
  const { join } = await import('pathe');
527
519
  const CODEX_AGENTS_FILE = join(homedir(), ".codex", "AGENTS.md");
@@ -556,7 +548,7 @@ async function ensureLanguageDirectiveInAgents(aiOutputLang) {
556
548
  }
557
549
  }
558
550
  async function updateCodexLanguageDirective(aiOutputLang) {
559
- const { readFile, writeFile, exists } = await import('./simple-config.mjs').then(function (n) { return n.bh; });
551
+ const { readFile, writeFile, exists } = await import('./simple-config.mjs').then(function (n) { return n.bg; });
560
552
  const { backupCodexAgents, getBackupMessage } = await import('./simple-config.mjs').then(function (n) { return n.bn; });
561
553
  const { homedir } = await import('node:os');
562
554
  const { join } = await import('pathe');
@@ -13,12 +13,12 @@ import toggleModule from 'inquirer-toggle';
13
13
  import ora from 'ora';
14
14
  import { exec, x } from 'tinyexec';
15
15
  import semver from 'semver';
16
- import { stringify, parse } from 'smol-toml';
16
+ import { edit, stringify, parse, initSync } from '@rainbowatcher/toml-edit-js';
17
17
  import { rm, mkdir, copyFile as copyFile$1 } from 'node:fs/promises';
18
18
  import i18next from 'i18next';
19
19
  import Backend from 'i18next-fs-backend';
20
20
 
21
- const version = "3.5.0";
21
+ const version = "3.5.1";
22
22
  const homepage = "https://github.com/UfoMiao/zcf";
23
23
 
24
24
  const i18n = i18next.createInstance();
@@ -2850,6 +2850,34 @@ function addNumbersToChoices(choices, startFrom = 1, format = (n) => `${n}. `) {
2850
2850
  });
2851
2851
  }
2852
2852
 
2853
+ let initialized = false;
2854
+ function ensureTomlInitSync() {
2855
+ if (!initialized) {
2856
+ initSync();
2857
+ initialized = true;
2858
+ }
2859
+ }
2860
+ function parseToml(content) {
2861
+ ensureTomlInitSync();
2862
+ return parse(content);
2863
+ }
2864
+ function stringifyToml(data) {
2865
+ ensureTomlInitSync();
2866
+ return stringify(data);
2867
+ }
2868
+ function editToml(content, path, value) {
2869
+ ensureTomlInitSync();
2870
+ return edit(content, path, value);
2871
+ }
2872
+ function batchEditToml(content, edits) {
2873
+ ensureTomlInitSync();
2874
+ let result = content;
2875
+ for (const [path, value] of edits) {
2876
+ result = edit(result, path, value);
2877
+ }
2878
+ return result;
2879
+ }
2880
+
2853
2881
  function isSupportedLang(value) {
2854
2882
  return SUPPORTED_LANGS.includes(value);
2855
2883
  }
@@ -2865,18 +2893,117 @@ function readTomlConfig(configPath) {
2865
2893
  return null;
2866
2894
  }
2867
2895
  const content = readFile(configPath);
2868
- const parsed = parse(content);
2896
+ const parsed = parseToml(content);
2869
2897
  return parsed;
2870
2898
  } catch {
2871
2899
  return null;
2872
2900
  }
2873
2901
  }
2902
+ function insertAtTopLevelStart(topLevel, content) {
2903
+ const lines = topLevel.split("\n");
2904
+ let insertLineIndex = 0;
2905
+ for (let i = 0; i < lines.length; i++) {
2906
+ const trimmed = lines[i].trim();
2907
+ if (trimmed === "" || trimmed.startsWith("#")) {
2908
+ insertLineIndex = i + 1;
2909
+ } else {
2910
+ insertLineIndex = i;
2911
+ break;
2912
+ }
2913
+ }
2914
+ lines.splice(insertLineIndex, 0, content.replace(/\n$/, ""));
2915
+ return lines.join("\n");
2916
+ }
2917
+ function insertAfterVersionField(topLevel, content) {
2918
+ const versionRegex = /^version\s*=\s*["'][^"']*["'][ \t]*(?:#.*)?$/m;
2919
+ const match = topLevel.match(versionRegex);
2920
+ if (match && match.index !== void 0) {
2921
+ const versionEnd = match.index + match[0].length;
2922
+ const before = topLevel.slice(0, versionEnd);
2923
+ const after = topLevel.slice(versionEnd);
2924
+ return `${before}
2925
+ ${content.replace(/\n$/, "")}${after}`;
2926
+ }
2927
+ return insertAtTopLevelStart(topLevel, content);
2928
+ }
2929
+ function updateTopLevelTomlFields(content, version, lastUpdated) {
2930
+ const firstSectionMatch = content.match(/^\[/m);
2931
+ const topLevelEnd = firstSectionMatch?.index ?? content.length;
2932
+ let topLevel = content.slice(0, topLevelEnd);
2933
+ const rest = content.slice(topLevelEnd);
2934
+ const versionRegex = /^version\s*=\s*["'][^"']*["'][ \t]*(?:#.*)?$/m;
2935
+ const versionMatch = topLevel.match(versionRegex);
2936
+ if (versionMatch) {
2937
+ topLevel = topLevel.replace(versionRegex, `version = "${version}"`);
2938
+ } else {
2939
+ topLevel = insertAtTopLevelStart(topLevel, `version = "${version}"`);
2940
+ }
2941
+ const lastUpdatedRegex = /^lastUpdated\s*=\s*["'][^"']*["'][ \t]*(?:#.*)?$/m;
2942
+ const lastUpdatedMatch = topLevel.match(lastUpdatedRegex);
2943
+ if (lastUpdatedMatch) {
2944
+ topLevel = topLevel.replace(lastUpdatedRegex, `lastUpdated = "${lastUpdated}"`);
2945
+ } else {
2946
+ topLevel = insertAfterVersionField(topLevel, `lastUpdated = "${lastUpdated}"`);
2947
+ }
2948
+ if (rest.length > 0 && !topLevel.endsWith("\n\n") && !topLevel.endsWith("\n")) {
2949
+ topLevel += "\n";
2950
+ }
2951
+ return topLevel + rest;
2952
+ }
2874
2953
  function writeTomlConfig(configPath, config) {
2875
2954
  try {
2876
2955
  const configDir = dirname(configPath);
2877
2956
  ensureDir(configDir);
2878
- const tomlContent = stringify(config);
2879
- writeFile(configPath, tomlContent);
2957
+ if (exists(configPath)) {
2958
+ const existingContent = readFile(configPath);
2959
+ const edits = [
2960
+ // General section
2961
+ ["general.preferredLang", config.general.preferredLang],
2962
+ ["general.currentTool", config.general.currentTool]
2963
+ ];
2964
+ if (config.general.templateLang !== void 0) {
2965
+ edits.push(["general.templateLang", config.general.templateLang]);
2966
+ }
2967
+ if (config.general.aiOutputLang !== void 0) {
2968
+ edits.push(["general.aiOutputLang", config.general.aiOutputLang]);
2969
+ }
2970
+ edits.push(
2971
+ ["claudeCode.enabled", config.claudeCode.enabled],
2972
+ ["claudeCode.outputStyles", config.claudeCode.outputStyles],
2973
+ ["claudeCode.installType", config.claudeCode.installType]
2974
+ );
2975
+ if (config.claudeCode.defaultOutputStyle !== void 0) {
2976
+ edits.push(["claudeCode.defaultOutputStyle", config.claudeCode.defaultOutputStyle]);
2977
+ }
2978
+ if (config.claudeCode.currentProfile !== void 0) {
2979
+ edits.push(["claudeCode.currentProfile", config.claudeCode.currentProfile]);
2980
+ }
2981
+ if (config.claudeCode.profiles !== void 0) {
2982
+ edits.push(["claudeCode.profiles", config.claudeCode.profiles]);
2983
+ }
2984
+ if (config.claudeCode.version !== void 0) {
2985
+ edits.push(["claudeCode.version", config.claudeCode.version]);
2986
+ }
2987
+ edits.push(
2988
+ ["codex.enabled", config.codex.enabled],
2989
+ ["codex.systemPromptStyle", config.codex.systemPromptStyle]
2990
+ );
2991
+ try {
2992
+ let updatedContent = batchEditToml(existingContent, edits);
2993
+ updatedContent = updateTopLevelTomlFields(
2994
+ updatedContent,
2995
+ config.version,
2996
+ config.lastUpdated
2997
+ );
2998
+ writeFile(configPath, updatedContent);
2999
+ } catch {
3000
+ const tomlContent = stringifyToml(config);
3001
+ writeFile(configPath, tomlContent);
3002
+ }
3003
+ } else {
3004
+ const tomlContent = stringifyToml(config);
3005
+ writeFile(configPath, tomlContent);
3006
+ }
2880
3007
  } catch {
2881
3008
  }
2882
3009
  }
@@ -3380,6 +3507,147 @@ function applyCodexPlatformCommand(config) {
3380
3507
  }
3381
3508
  }
3382
3509
 
3510
+ function updateTopLevelTomlField(content, field, value, options = {}) {
3511
+ if (!content) {
3512
+ if (value === null) {
3513
+ return "";
3514
+ }
3515
+ const commentPrefix = options.commented ? "# " : "";
3516
+ return `${commentPrefix}${field} = "${value}"
3517
+ `;
3518
+ }
3519
+ const firstSectionMatch = content.match(/^\[/m);
3520
+ const topLevelEnd = firstSectionMatch?.index ?? content.length;
3521
+ let topLevel = content.slice(0, topLevelEnd);
3522
+ const rest = content.slice(topLevelEnd);
3523
+ const fieldRegex = new RegExp(`^(#\\s*)?${field}\\s*=\\s*["'][^"']*["'][ \\t]*(?:#.*)?$`, "m");
3524
+ const existingMatch = topLevel.match(fieldRegex);
3525
+ if (value === null) {
3526
+ if (existingMatch) {
3527
+ topLevel = topLevel.replace(fieldRegex, "").replace(/\n{2,}/g, "\n\n");
3528
+ }
3529
+ } else {
3530
+ const commentPrefix = options.commented ? "# " : "";
3531
+ const newLine = `${commentPrefix}${field} = "${value}"`;
3532
+ if (existingMatch) {
3533
+ topLevel = topLevel.replace(fieldRegex, newLine);
3534
+ } else {
3535
+ topLevel = `${topLevel.trimEnd()}
3536
+ ${newLine}
3537
+ `;
3538
+ }
3539
+ }
3540
+ if (rest.length > 0 && !topLevel.endsWith("\n\n")) {
3541
+ topLevel = `${topLevel.trimEnd()}
3542
+
3543
+ `;
3544
+ }
3545
+ return topLevel + rest;
3546
+ }
3547
+ function updateCodexApiFields(fields) {
3548
+ if (!exists(CODEX_CONFIG_FILE)) {
3549
+ ensureDir(CODEX_DIR);
3550
+ writeFile(CODEX_CONFIG_FILE, "");
3551
+ }
3552
+ let content = readFile(CODEX_CONFIG_FILE) || "";
3553
+ if (fields.model !== void 0) {
3554
+ content = updateTopLevelTomlField(content, "model", fields.model);
3555
+ }
3556
+ if (fields.modelProvider !== void 0) {
3557
+ content = updateTopLevelTomlField(
3558
+ content,
3559
+ "model_provider",
3560
+ fields.modelProvider,
3561
+ { commented: fields.modelProviderCommented }
3562
+ );
3563
+ }
3564
+ writeFile(CODEX_CONFIG_FILE, content);
3565
+ }
3566
+ function upsertCodexProvider(providerId, provider) {
3567
+ if (!exists(CODEX_CONFIG_FILE)) {
3568
+ ensureDir(CODEX_DIR);
3569
+ writeFile(CODEX_CONFIG_FILE, "");
3570
+ }
3571
+ let content = readFile(CODEX_CONFIG_FILE) || "";
3572
+ const basePath = `model_providers.${providerId}`;
3573
+ content = editToml(content, `${basePath}.name`, provider.name);
3574
+ content = editToml(content, `${basePath}.base_url`, provider.baseUrl);
3575
+ content = editToml(content, `${basePath}.wire_api`, provider.wireApi);
3576
+ content = editToml(content, `${basePath}.temp_env_key`, provider.tempEnvKey);
3577
+ content = editToml(content, `${basePath}.requires_openai_auth`, provider.requiresOpenaiAuth);
3578
+ if (provider.model) {
3579
+ content = editToml(content, `${basePath}.model`, provider.model);
3580
+ }
3581
+ writeFile(CODEX_CONFIG_FILE, content);
3582
+ }
3583
+ function deleteCodexProvider(providerId) {
3584
+ if (!exists(CODEX_CONFIG_FILE)) {
3585
+ return;
3586
+ }
3587
+ const content = readFile(CODEX_CONFIG_FILE) || "";
3588
+ const sectionRegex = new RegExp(
3589
+ `\\n?\\[model_providers\\.${escapeRegex(providerId)}\\][\\s\\S]*?(?=\\n\\[|$)`,
3590
+ "g"
3591
+ );
3592
+ const updatedContent = content.replace(sectionRegex, "");
3593
+ writeFile(CODEX_CONFIG_FILE, updatedContent);
3594
+ }
3595
+ function upsertCodexMcpService(serviceId, service) {
3596
+ if (!exists(CODEX_CONFIG_FILE)) {
3597
+ ensureDir(CODEX_DIR);
3598
+ writeFile(CODEX_CONFIG_FILE, "");
3599
+ }
3600
+ let content = readFile(CODEX_CONFIG_FILE) || "";
3601
+ const basePath = `mcp_servers.${serviceId}`;
3602
+ const parsed = content ? parseToml(content) : {};
3603
+ const existingService = parsed.mcp_servers?.[serviceId];
3604
+ if (existingService?.url && !existingService?.command) {
3605
+ if (service.env && Object.keys(service.env).length > 0) {
3606
+ content = editToml(content, `${basePath}.env`, service.env);
3607
+ }
3608
+ if (service.startup_timeout_sec) {
3609
+ content = editToml(content, `${basePath}.startup_timeout_sec`, service.startup_timeout_sec);
3610
+ }
3611
+ } else {
3612
+ const normalizedCommand = normalizeTomlPath(service.command);
3613
+ content = editToml(content, `${basePath}.command`, normalizedCommand);
3614
+ content = editToml(content, `${basePath}.args`, service.args || []);
3615
+ if (service.env && Object.keys(service.env).length > 0) {
3616
+ content = editToml(content, `${basePath}.env`, service.env);
3617
+ }
3618
+ if (service.startup_timeout_sec) {
3619
+ content = editToml(content, `${basePath}.startup_timeout_sec`, service.startup_timeout_sec);
3620
+ }
3621
+ }
3622
+ writeFile(CODEX_CONFIG_FILE, content);
3623
+ }
3624
+ function batchUpdateCodexMcpServices(services, options = {}) {
3625
+ if (options.replaceAll) {
3626
+ if (exists(CODEX_CONFIG_FILE)) {
3627
+ let content = readFile(CODEX_CONFIG_FILE) || "";
3628
+ content = content.replace(/\n?\[mcp_servers\.[^\]]+\][\s\S]*?(?=\n\[|$)/g, "");
3629
+ content = content.replace(/\n?#\s*---\s*MCP servers added by ZCF\s*---\s*/gi, "");
3630
+ writeFile(CODEX_CONFIG_FILE, content);
3631
+ }
3632
+ }
3633
+ for (const service of services) {
3634
+ upsertCodexMcpService(service.id, service);
3635
+ }
3636
+ }
3637
+ function escapeRegex(str) {
3638
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3639
+ }
3640
+
3641
+ const codexTomlUpdater = {
3642
+ __proto__: null,
3643
+ batchUpdateCodexMcpServices: batchUpdateCodexMcpServices,
3644
+ deleteCodexProvider: deleteCodexProvider,
3645
+ updateCodexApiFields: updateCodexApiFields,
3646
+ updateTopLevelTomlField: updateTopLevelTomlField,
3647
+ upsertCodexMcpService: upsertCodexMcpService,
3648
+ upsertCodexProvider: upsertCodexProvider
3649
+ };
3650
+
3383
3651
  async function configureCodexMcp(options) {
3384
3652
  ensureI18nInitialized();
3385
3653
  const { skipPrompt = false } = options ?? {};
@@ -3396,7 +3664,6 @@ async function configureCodexMcp(options) {
3396
3664
  return;
3397
3665
  }
3398
3666
  const defaultServiceIds = Array.isArray(options?.mcpServices) ? options.mcpServices : MCP_SERVICE_CONFIGS.filter((service) => !service.requiresApiKey).map((service) => service.id);
3399
- const baseProviders2 = existingConfig?.providers || [];
3400
3667
  const existingServices2 = existingConfig?.mcpServices || [];
3401
3668
  const selection2 = [];
3402
3669
  for (const id of defaultServiceIds) {
@@ -3450,13 +3717,7 @@ async function configureCodexMcp(options) {
3450
3717
  }
3451
3718
  return svc;
3452
3719
  });
3453
- writeCodexConfig({
3454
- model: existingConfig?.model || null,
3455
- modelProvider: existingConfig?.modelProvider || null,
3456
- providers: baseProviders2,
3457
- mcpServices: finalServices2,
3458
- otherConfig: existingConfig?.otherConfig || []
3459
- });
3720
+ batchUpdateCodexMcpServices(finalServices2);
3460
3721
  updateZcfConfig({ codeToolType: "codex" });
3461
3722
  console.log(ansis.green(i18n.t("codex:mcpConfigured")));
3462
3723
  return;
@@ -3465,7 +3726,6 @@ async function configureCodexMcp(options) {
3465
3726
  if (!selectedIds)
3466
3727
  return;
3467
3728
  const servicesMeta = await getMcpServices();
3468
- const baseProviders = existingConfig?.providers || [];
3469
3729
  const selection = [];
3470
3730
  const existingServices = existingConfig?.mcpServices || [];
3471
3731
  if (selectedIds.length === 0) {
@@ -3485,13 +3745,7 @@ async function configureCodexMcp(options) {
3485
3745
  }
3486
3746
  return svc;
3487
3747
  });
3488
- writeCodexConfig({
3489
- model: existingConfig?.model || null,
3490
- modelProvider: existingConfig?.modelProvider || null,
3491
- providers: baseProviders,
3492
- mcpServices: preserved,
3493
- otherConfig: existingConfig?.otherConfig || []
3494
- });
3748
+ batchUpdateCodexMcpServices(preserved);
3495
3749
  updateZcfConfig({ codeToolType: "codex" });
3496
3750
  return;
3497
3751
  }
@@ -3560,13 +3814,7 @@ async function configureCodexMcp(options) {
3560
3814
  }
3561
3815
  return svc;
3562
3816
  });
3563
- writeCodexConfig({
3564
- model: existingConfig?.model || null,
3565
- modelProvider: existingConfig?.modelProvider || null,
3566
- providers: baseProviders,
3567
- mcpServices: finalServices,
3568
- otherConfig: existingConfig?.otherConfig || []
3569
- });
3817
+ batchUpdateCodexMcpServices(finalServices);
3570
3818
  updateZcfConfig({ codeToolType: "codex" });
3571
3819
  console.log(ansis.green(i18n.t("codex:mcpConfigured")));
3572
3820
  }
@@ -3828,7 +4076,7 @@ function parseCodexConfig(content) {
3828
4076
  const normalizedContent = content.replace(/(SYSTEMROOT\s*=\s*")[^"\n]+("?)/g, (match) => {
3829
4077
  return match.replace(/\\\\/g, "/").replace(/\\/g, "/").replace('C:/Windows"?', 'C:/Windows"');
3830
4078
  });
3831
- const tomlData = parse(normalizedContent);
4079
+ const tomlData = parseToml(normalizedContent);
3832
4080
  const providers = [];
3833
4081
  if (tomlData.model_providers) {
3834
4082
  for (const [id, providerData] of Object.entries(tomlData.model_providers)) {
@@ -3962,70 +4210,6 @@ function parseCodexConfig(content) {
3962
4210
  };
3963
4211
  }
3964
4212
  }
3965
- function formatInlineTableValue(value) {
3966
- if (value === null || value === void 0) {
3967
- return "";
3968
- }
3969
- if (typeof value === "string") {
3970
- const normalized = normalizeTomlPath(value);
3971
- return `'${normalized}'`;
3972
- }
3973
- if (typeof value === "number" || typeof value === "boolean") {
3974
- return String(value);
3975
- }
3976
- if (Array.isArray(value)) {
3977
- const items = value.map((item) => {
3978
- if (typeof item === "string") {
3979
- const normalized = normalizeTomlPath(item);
3980
- return `'${normalized}'`;
3981
- }
3982
- if (typeof item === "object" && item !== null && !Array.isArray(item)) {
3983
- return formatInlineTable(item);
3984
- }
3985
- return String(item);
3986
- }).join(", ");
3987
- return `[${items}]`;
3988
- }
3989
- if (typeof value === "object") {
3990
- return formatInlineTable(value);
3991
- }
3992
- return String(value);
3993
- }
3994
- function formatInlineTable(obj) {
3995
- const entries = Object.entries(obj).filter(([_, v]) => v !== null && v !== void 0).map(([k, v]) => `${k} = ${formatInlineTableValue(v)}`).join(", ");
3996
- return `{${entries}}`;
3997
- }
3998
- function formatTomlField(key, value) {
3999
- if (value === null || value === void 0) {
4000
- return "";
4001
- }
4002
- if (typeof value === "string") {
4003
- const normalized = normalizeTomlPath(value);
4004
- const escaped = normalized.replace(/"/g, '\\"');
4005
- return `${key} = "${escaped}"`;
4006
- }
4007
- if (typeof value === "number" || typeof value === "boolean") {
4008
- return `${key} = ${value}`;
4009
- }
4010
- if (Array.isArray(value)) {
4011
- const items = value.map((item) => {
4012
- if (typeof item === "string") {
4013
- const normalized = normalizeTomlPath(item);
4014
- const escaped = normalized.replace(/"/g, '\\"');
4015
- return `"${escaped}"`;
4016
- }
4017
- if (typeof item === "object" && item !== null && !Array.isArray(item)) {
4018
- return formatInlineTable(item);
4019
- }
4020
- return String(item);
4021
- }).join(", ");
4022
- return `${key} = [${items}]`;
4023
- }
4024
- if (typeof value === "object") {
4025
- return `${key} = ${formatInlineTable(value)}`;
4026
- }
4027
- return "";
4028
- }
4029
4213
  function readCodexConfig() {
4030
4214
  if (!exists(CODEX_CONFIG_FILE))
4031
4215
  return null;
@@ -4037,100 +4221,6 @@ function readCodexConfig() {
4037
4221
  return null;
4038
4222
  }
4039
4223
  }
4040
- function renderCodexConfig(data) {
4041
- const lines = [];
4042
- if (data.model || data.modelProvider || data.providers.length > 0 || data.modelProviderCommented) {
4043
- lines.push("# --- model provider added by ZCF ---");
4044
- if (data.model) {
4045
- lines.push(`model = "${data.model}"`);
4046
- }
4047
- if (data.modelProvider) {
4048
- const commentPrefix = data.modelProviderCommented ? "# " : "";
4049
- lines.push(`${commentPrefix}model_provider = "${data.modelProvider}"`);
4050
- }
4051
- lines.push("");
4052
- }
4053
- if (data.otherConfig && data.otherConfig.length > 0) {
4054
- const preserved = data.otherConfig.filter((raw) => {
4055
- const l = String(raw).trim();
4056
- if (!l)
4057
- return false;
4058
- if (/^#\s*---\s*model provider added by ZCF\s*---\s*$/i.test(l))
4059
- return false;
4060
- if (/^#\s*---\s*MCP servers added by ZCF\s*---\s*$/i.test(l))
4061
- return false;
4062
- if (/^\[\s*mcp_servers\./i.test(l))
4063
- return false;
4064
- if (/^\[\s*model_providers\./i.test(l))
4065
- return false;
4066
- if (/^#?\s*model_provider\s*=/.test(l))
4067
- return false;
4068
- if (/^\s*model\s*=/.test(l) && !l.includes("["))
4069
- return false;
4070
- return true;
4071
- });
4072
- if (preserved.length > 0) {
4073
- lines.push(...preserved);
4074
- if (data.providers.length > 0 || data.mcpServices.length > 0) {
4075
- lines.push("");
4076
- }
4077
- }
4078
- }
4079
- if (data.providers.length > 0) {
4080
- for (const provider of data.providers) {
4081
- lines.push("");
4082
- lines.push(`[model_providers.${provider.id}]`);
4083
- lines.push(`name = "${provider.name}"`);
4084
- lines.push(`base_url = "${provider.baseUrl}"`);
4085
- lines.push(`wire_api = "${provider.wireApi}"`);
4086
- lines.push(`temp_env_key = "${provider.tempEnvKey}"`);
4087
- lines.push(`requires_openai_auth = ${provider.requiresOpenaiAuth}`);
4088
- if (provider.model) {
4089
- lines.push(`model = "${provider.model}"`);
4090
- }
4091
- }
4092
- }
4093
- if (data.mcpServices.length > 0) {
4094
- lines.push("");
4095
- lines.push("# --- MCP servers added by ZCF ---");
4096
- for (const service of data.mcpServices) {
4097
- lines.push(`[mcp_servers.${service.id}]`);
4098
- const normalizedCommand = normalizeTomlPath(service.command);
4099
- lines.push(`command = "${normalizedCommand}"`);
4100
- const argsString = service.args.length > 0 ? service.args.map((arg) => `"${arg}"`).join(", ") : "";
4101
- lines.push(`args = [${argsString}]`);
4102
- if (service.env && Object.keys(service.env).length > 0) {
4103
- const envEntries = Object.entries(service.env).map(([key, value]) => `${key} = '${value}'`).join(", ");
4104
- lines.push(`env = {${envEntries}}`);
4105
- }
4106
- if (service.startup_timeout_sec) {
4107
- lines.push(`startup_timeout_sec = ${service.startup_timeout_sec}`);
4108
- }
4109
- if (service.extraFields) {
4110
- for (const [key, value] of Object.entries(service.extraFields)) {
4111
- const formatted = formatTomlField(key, value);
4112
- if (formatted) {
4113
- lines.push(formatted);
4114
- }
4115
- }
4116
- }
4117
- lines.push("");
4118
- }
4119
- if (lines[lines.length - 1] === "") {
4120
- lines.pop();
4121
- }
4122
- }
4123
- let result = lines.join("\n");
4124
- if (result && !result.endsWith("\n")) {
4125
- result += "\n";
4126
- }
4127
- return result;
4128
- }
4129
- function writeCodexConfig(data) {
4130
- ensureEnvKeyMigration();
4131
- ensureDir(CODEX_DIR);
4132
- writeFile(CODEX_CONFIG_FILE, renderCodexConfig(data));
4133
- }
4134
4224
  function writeAuthFile(newEntries) {
4135
4225
  ensureDir(CODEX_DIR);
4136
4226
  const existing = readJsonConfig(CODEX_AUTH_FILE, { defaultValue: {} }) || {};
@@ -4473,12 +4563,11 @@ async function applyCustomApiConfig(customApiConfig) {
4473
4563
  }
4474
4564
  const existingConfig = readCodexConfig();
4475
4565
  const existingAuth = readJsonConfig(CODEX_AUTH_FILE, { defaultValue: {} }) || {};
4476
- const providers = [];
4477
4566
  const authEntries = { ...existingAuth };
4478
4567
  const providerId = type === "auth_token" ? "official-auth-token" : "custom-api-key";
4479
4568
  const providerName = type === "auth_token" ? "Official Auth Token" : "Custom API Key";
4480
4569
  const existingProvider = existingConfig?.providers.find((p) => p.id === providerId);
4481
- providers.push({
4570
+ const newProvider = {
4482
4571
  id: providerId,
4483
4572
  name: providerName,
4484
4573
  baseUrl: baseUrl || existingProvider?.baseUrl || "https://api.anthropic.com",
@@ -4486,24 +4575,18 @@ async function applyCustomApiConfig(customApiConfig) {
4486
4575
  tempEnvKey: existingProvider?.tempEnvKey || `${providerId.toUpperCase()}_API_KEY`,
4487
4576
  requiresOpenaiAuth: existingProvider?.requiresOpenaiAuth ?? false,
4488
4577
  model: model || existingProvider?.model
4489
- });
4490
- if (existingConfig?.providers) {
4491
- providers.push(...existingConfig.providers.filter((p) => p.id !== providerId));
4492
- }
4578
+ };
4493
4579
  if (token) {
4494
4580
  authEntries[providerId] = token;
4495
4581
  authEntries.OPENAI_API_KEY = token;
4496
4582
  }
4497
- const configData = {
4583
+ const { updateCodexApiFields, upsertCodexProvider } = await Promise.resolve().then(function () { return codexTomlUpdater; });
4584
+ updateCodexApiFields({
4498
4585
  model: model || existingConfig?.model || "claude-3-5-sonnet-20241022",
4499
- // Prefer provided model, then existing, fallback default
4500
4586
  modelProvider: providerId,
4501
- modelProviderCommented: false,
4502
- providers,
4503
- mcpServices: existingConfig?.mcpServices || [],
4504
- otherConfig: existingConfig?.otherConfig || []
4505
- };
4506
- writeCodexConfig(configData);
4587
+ modelProviderCommented: false
4588
+ });
4589
+ upsertCodexProvider(providerId, newProvider);
4507
4590
  writeJsonConfig(CODEX_AUTH_FILE, authEntries);
4508
4591
  updateZcfConfig({ codeToolType: "codex" });
4509
4592
  console.log(ansis.green(`\u2714 ${i18n.t("codex:apiConfigured")}`));
@@ -4674,7 +4757,7 @@ async function configureCodexApi(options) {
4674
4757
  type: "input",
4675
4758
  name: "model",
4676
4759
  message: `${i18n.t("configuration:enterCustomModel")}${i18n.t("common:emptyToSkip")}`,
4677
- default: "gpt-5-codex"
4760
+ default: "gpt-5.2"
4678
4761
  }]);
4679
4762
  if (model.trim()) {
4680
4763
  customModel = model.trim();
@@ -4713,7 +4796,7 @@ async function configureCodexApi(options) {
4713
4796
  wireApi: selectedProvider2 === "custom" ? answers.wireApi || "responses" : prefilledWireApi,
4714
4797
  tempEnvKey,
4715
4798
  requiresOpenaiAuth: true,
4716
- model: customModel || prefilledModel || "gpt-5-codex"
4799
+ model: customModel || prefilledModel || "gpt-5.2"
4717
4800
  // Use custom model, provider's default model, or fallback
4718
4801
  };
4719
4802
  providers.push(newProvider);
@@ -4743,13 +4826,15 @@ async function configureCodexApi(options) {
4743
4826
  if (defaultApiKey)
4744
4827
  authEntries.OPENAI_API_KEY = defaultApiKey;
4745
4828
  }
4746
- writeCodexConfig({
4747
- model: existingConfig?.model || null,
4829
+ const { updateCodexApiFields, upsertCodexProvider } = await Promise.resolve().then(function () { return codexTomlUpdater; });
4830
+ updateCodexApiFields({
4831
+ model: existingConfig?.model,
4748
4832
  modelProvider: defaultProvider,
4749
- providers,
4750
- mcpServices: existingConfig?.mcpServices || [],
4751
- otherConfig: existingConfig?.otherConfig || []
4833
+ modelProviderCommented: false
4752
4834
  });
4835
+ for (const provider of providers) {
4836
+ upsertCodexProvider(provider.id, provider);
4837
+ }
4753
4838
  writeAuthFile(authEntries);
4754
4839
  updateZcfConfig({ codeToolType: "codex" });
4755
4840
  console.log(ansis.green(i18n.t("codex:apiConfigured")));
@@ -4937,12 +5022,12 @@ async function switchCodexProvider(providerId) {
4937
5022
  if (backupPath) {
4938
5023
  console.log(ansis.gray(getBackupMessage(backupPath)));
4939
5024
  }
4940
- const updatedConfig = {
4941
- ...existingConfig,
4942
- modelProvider: providerId
4943
- };
4944
5025
  try {
4945
- writeCodexConfig(updatedConfig);
5026
+ const { updateCodexApiFields } = await Promise.resolve().then(function () { return codexTomlUpdater; });
5027
+ updateCodexApiFields({
5028
+ modelProvider: providerId,
5029
+ modelProviderCommented: false
5030
+ });
4946
5031
  console.log(ansis.green(i18n.t("codex:providerSwitchSuccess", { provider: providerId })));
4947
5032
  return true;
4948
5033
  } catch (error) {
@@ -4966,19 +5051,18 @@ async function switchToOfficialLogin() {
4966
5051
  if (!preservedModelProvider) {
4967
5052
  try {
4968
5053
  const rawContent = readFile(CODEX_CONFIG_FILE);
4969
- const parsedToml = parse(rawContent);
5054
+ const parsedToml = parseToml(rawContent);
4970
5055
  if (typeof parsedToml.model_provider === "string" && parsedToml.model_provider.trim().length > 0)
4971
5056
  preservedModelProvider = parsedToml.model_provider.trim();
4972
5057
  } catch {
4973
5058
  }
4974
5059
  }
4975
5060
  const shouldCommentModelProvider = typeof preservedModelProvider === "string" && preservedModelProvider.length > 0;
4976
- const updatedConfig = {
4977
- ...existingConfig,
5061
+ const { updateCodexApiFields } = await Promise.resolve().then(function () { return codexTomlUpdater; });
5062
+ updateCodexApiFields({
4978
5063
  modelProvider: shouldCommentModelProvider ? preservedModelProvider : existingConfig.modelProvider,
4979
- modelProviderCommented: shouldCommentModelProvider ? true : existingConfig.modelProviderCommented
4980
- };
4981
- writeCodexConfig(updatedConfig);
5064
+ modelProviderCommented: shouldCommentModelProvider || existingConfig.modelProviderCommented
5065
+ });
4982
5066
  const auth = readJsonConfig(CODEX_AUTH_FILE, { defaultValue: {} }) || {};
4983
5067
  auth.OPENAI_API_KEY = null;
4984
5068
  writeJsonConfig(CODEX_AUTH_FILE, auth, { pretty: true });
@@ -5011,18 +5095,18 @@ async function switchToProvider(providerId) {
5011
5095
  targetModel = provider.model;
5012
5096
  } else {
5013
5097
  const currentModel = existingConfig.model;
5014
- if (currentModel !== "gpt-5" && currentModel !== "gpt-5-codex") {
5015
- targetModel = "gpt-5-codex";
5098
+ const knownModels = ["gpt-5.1-codex-max", "gpt-5.1-codex-mini", "gpt-5.2"];
5099
+ if (!currentModel || !knownModels.includes(currentModel)) {
5100
+ targetModel = "gpt-5.2";
5016
5101
  }
5017
5102
  }
5018
- const updatedConfig = {
5019
- ...existingConfig,
5103
+ const { updateCodexApiFields } = await Promise.resolve().then(function () { return codexTomlUpdater; });
5104
+ updateCodexApiFields({
5020
5105
  model: targetModel,
5021
5106
  modelProvider: providerId,
5022
5107
  modelProviderCommented: false
5023
5108
  // Ensure it's not commented
5024
- };
5025
- writeCodexConfig(updatedConfig);
5109
+ });
5026
5110
  const auth = readJsonConfig(CODEX_AUTH_FILE, { defaultValue: {} }) || {};
5027
5111
  const envValue = auth[provider.tempEnvKey] || null;
5028
5112
  auth.OPENAI_API_KEY = envValue;
@@ -5059,7 +5143,6 @@ const codex = {
5059
5143
  needsEnvKeyMigration: needsEnvKeyMigration,
5060
5144
  parseCodexConfig: parseCodexConfig,
5061
5145
  readCodexConfig: readCodexConfig,
5062
- renderCodexConfig: renderCodexConfig,
5063
5146
  runCodexFullInit: runCodexFullInit,
5064
5147
  runCodexSystemPromptSelection: runCodexSystemPromptSelection,
5065
5148
  runCodexUninstall: runCodexUninstall,
@@ -5069,8 +5152,7 @@ const codex = {
5069
5152
  switchCodexProvider: switchCodexProvider,
5070
5153
  switchToOfficialLogin: switchToOfficialLogin,
5071
5154
  switchToProvider: switchToProvider,
5072
- writeAuthFile: writeAuthFile,
5073
- writeCodexConfig: writeCodexConfig
5155
+ writeAuthFile: writeAuthFile
5074
5156
  };
5075
5157
 
5076
5158
  const CODE_TYPE_ABBREVIATIONS = {
@@ -7488,7 +7570,7 @@ async function convertToCodexProvider(config) {
7488
7570
  const displayName = config.name || config.provider || "custom";
7489
7571
  const providerId = displayName.toLowerCase().replace(/[^a-z0-9]/g, "-");
7490
7572
  let baseUrl = config.url || API_DEFAULT_URL;
7491
- let model = config.primaryModel || "gpt-5-codex";
7573
+ let model = config.primaryModel || "gpt-5.2";
7492
7574
  let wireApi = "responses";
7493
7575
  if (config.provider && config.provider !== "custom") {
7494
7576
  const { getProviderPreset } = await import('./api-providers.mjs');
@@ -7588,4 +7670,4 @@ async function openSettingsJson() {
7588
7670
  }
7589
7671
  }
7590
7672
 
7591
- export { getExistingModelConfig as $, API_DEFAULT_URL as A, getAiOutputLanguageLabel as B, CLAUDE_DIR as C, DEFAULT_CODE_TOOL_TYPE as D, getMcpConfigPath as E, readMcpConfig as F, writeMcpConfig as G, backupMcpConfig as H, mergeMcpServers as I, buildMcpServerConfig as J, fixWindowsMcpConfig as K, LEGACY_ZCF_CONFIG_FILES as L, addCompletedOnboarding as M, ensureApiKeyApproved as N, removeApiKeyFromRejected as O, manageApiKeyApproval as P, setPrimaryApiKey as Q, ensureClaudeDir as R, SETTINGS_FILE as S, backupExistingConfig as T, copyConfigFiles as U, configureApi as V, mergeConfigs as W, updateCustomModel as X, updateDefaultModel as Y, ZCF_CONFIG_DIR as Z, mergeSettingsFile as _, commandExists as a, resolveAiOutputLanguage as a$, getExistingApiConfig as a0, applyAiLanguageDirective as a1, switchToOfficialLogin$1 as a2, promptApiConfigurationAction as a3, isClaudeCodeInstalled as a4, installClaudeCode as a5, isCodexInstalled as a6, installCodex as a7, isLocalClaudeCodeInstalled as a8, getInstallationStatus as a9, writeCodexConfig as aA, writeAuthFile as aB, updateZcfConfig as aC, changeLanguage as aD, readZcfConfig as aE, configureOutputStyle as aF, isWindows as aG, selectMcpServices as aH, getMcpServices as aI, isCcrInstalled as aJ, installCcr as aK, setupCcrConfiguration as aL, modifyApiConfigPartially as aM, formatApiKeyDisplay as aN, readCcrConfig as aO, configureCcrFeature as aP, handleExitPromptError as aQ, handleGeneralError as aR, COMETIX_COMMAND_NAME as aS, COMETIX_COMMANDS as aT, installCometixLine as aU, checkAndUpdateTools as aV, runCodexUpdate as aW, resolveCodeType as aX, writeJsonConfig as aY, displayBanner as aZ, version as a_, removeLocalClaudeCode as aa, uninstallCodeTool as ab, setInstallMethod as ac, detectInstalledVersion as ad, selectInstallMethod as ae, executeInstallMethod as af, handleInstallFailure as ag, verifyInstallation as ah, createHomebrewSymlink as ai, displayVerificationResult as aj, ensureI18nInitialized as ak, i18n as al, addNumbersToChoices as am, validateApiKey as an, promptBoolean as ao, ensureDir as ap, readDefaultTomlConfig as aq, createDefaultTomlConfig as ar, exists as as, readJsonConfig as at, writeTomlConfig as au, clearModelEnv as av, copyFile as aw, detectConfigManagementMode as ax, readCodexConfig as ay, backupCodexComplete as az, importRecommendedEnv as b, updatePromptOnly as b0, selectAndInstallWorkflows as b1, checkClaudeCodeVersionAndPrompt as b2, displayBannerWithInfo as b3, runCodexUninstall as b4, configureCodexMcp as b5, configureCodexApi as b6, runCodexWorkflowImportWithLanguageSelection as b7, runCodexFullInit as b8, switchCodexProvider as b9, listCodexProviders as ba, switchToOfficialLogin as bb, switchToProvider as bc, readZcfConfigAsync as bd, initI18n as be, selectScriptLanguage as bf, index as bg, fsOperations as bh, jsonConfig as bi, claudeConfig as bj, config$1 as bk, config as bl, prompts as bm, codex as bn, installer as bo, cleanupPermissions as c, importRecommendedPermissions as d, CLAUDE_MD_FILE as e, ClAUDE_CONFIG_FILE as f, getPlatform as g, CLAUDE_VSC_CONFIG_FILE as h, init as i, CODEX_DIR as j, CODEX_CONFIG_FILE as k, CODEX_AUTH_FILE as l, mergeAndCleanPermissions as m, CODEX_AGENTS_FILE as n, openSettingsJson as o, CODEX_PROMPTS_DIR as p, ZCF_CONFIG_FILE as q, CODE_TOOL_TYPES as r, CODE_TOOL_BANNERS as s, CODE_TOOL_ALIASES as t, isCodeToolType as u, API_ENV_KEY as v, resolveCodeToolType as w, SUPPORTED_LANGS as x, LANG_LABELS as y, AI_OUTPUT_LANGUAGES as z };
7673
+ export { getExistingModelConfig as $, API_DEFAULT_URL as A, getAiOutputLanguageLabel as B, CLAUDE_DIR as C, DEFAULT_CODE_TOOL_TYPE as D, getMcpConfigPath as E, readMcpConfig as F, writeMcpConfig as G, backupMcpConfig as H, mergeMcpServers as I, buildMcpServerConfig as J, fixWindowsMcpConfig as K, LEGACY_ZCF_CONFIG_FILES as L, addCompletedOnboarding as M, ensureApiKeyApproved as N, removeApiKeyFromRejected as O, manageApiKeyApproval as P, setPrimaryApiKey as Q, ensureClaudeDir as R, SETTINGS_FILE as S, backupExistingConfig as T, copyConfigFiles as U, configureApi as V, mergeConfigs as W, updateCustomModel as X, updateDefaultModel as Y, ZCF_CONFIG_DIR as Z, mergeSettingsFile as _, commandExists as a, updatePromptOnly as a$, getExistingApiConfig as a0, applyAiLanguageDirective as a1, switchToOfficialLogin$1 as a2, promptApiConfigurationAction as a3, isClaudeCodeInstalled as a4, installClaudeCode as a5, isCodexInstalled as a6, installCodex as a7, isLocalClaudeCodeInstalled as a8, getInstallationStatus as a9, writeAuthFile as aA, updateZcfConfig as aB, changeLanguage as aC, readZcfConfig as aD, configureOutputStyle as aE, isWindows as aF, selectMcpServices as aG, getMcpServices as aH, isCcrInstalled as aI, installCcr as aJ, setupCcrConfiguration as aK, modifyApiConfigPartially as aL, formatApiKeyDisplay as aM, readCcrConfig as aN, configureCcrFeature as aO, handleExitPromptError as aP, handleGeneralError as aQ, COMETIX_COMMAND_NAME as aR, COMETIX_COMMANDS as aS, installCometixLine as aT, checkAndUpdateTools as aU, runCodexUpdate as aV, resolveCodeType as aW, writeJsonConfig as aX, displayBanner as aY, version as aZ, resolveAiOutputLanguage as a_, removeLocalClaudeCode as aa, uninstallCodeTool as ab, setInstallMethod as ac, detectInstalledVersion as ad, selectInstallMethod as ae, executeInstallMethod as af, handleInstallFailure as ag, verifyInstallation as ah, createHomebrewSymlink as ai, displayVerificationResult as aj, ensureI18nInitialized as ak, i18n as al, addNumbersToChoices as am, validateApiKey as an, promptBoolean as ao, ensureDir as ap, readDefaultTomlConfig as aq, createDefaultTomlConfig as ar, exists as as, readJsonConfig as at, writeTomlConfig as au, clearModelEnv as av, copyFile as aw, detectConfigManagementMode as ax, readCodexConfig as ay, backupCodexComplete as az, importRecommendedEnv as b, selectAndInstallWorkflows as b0, checkClaudeCodeVersionAndPrompt as b1, displayBannerWithInfo as b2, runCodexUninstall as b3, configureCodexMcp as b4, configureCodexApi as b5, runCodexWorkflowImportWithLanguageSelection as b6, runCodexFullInit as b7, switchCodexProvider as b8, listCodexProviders as b9, switchToOfficialLogin as ba, switchToProvider as bb, readZcfConfigAsync as bc, initI18n as bd, selectScriptLanguage as be, index as bf, fsOperations as bg, jsonConfig as bh, claudeConfig as bi, config$1 as bj, config as bk, prompts as bl, codexTomlUpdater as bm, codex as bn, installer as bo, cleanupPermissions as c, importRecommendedPermissions as d, CLAUDE_MD_FILE as e, ClAUDE_CONFIG_FILE as f, getPlatform as g, CLAUDE_VSC_CONFIG_FILE as h, init as i, CODEX_DIR as j, CODEX_CONFIG_FILE as k, CODEX_AUTH_FILE as l, mergeAndCleanPermissions as m, CODEX_AGENTS_FILE as n, openSettingsJson as o, CODEX_PROMPTS_DIR as p, ZCF_CONFIG_FILE as q, CODE_TOOL_TYPES as r, CODE_TOOL_BANNERS as s, CODE_TOOL_ALIASES as t, isCodeToolType as u, API_ENV_KEY as v, resolveCodeToolType as w, SUPPORTED_LANGS as x, LANG_LABELS as y, AI_OUTPUT_LANGUAGES as z };
package/dist/cli.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import cac from 'cac';
3
3
  import ansis from 'ansis';
4
- import { ak as ensureI18nInitialized, al as i18n, aO as readCcrConfig, aJ as isCcrInstalled, aK as installCcr, aP as configureCcrFeature, ao as promptBoolean, aQ as handleExitPromptError, aR as handleGeneralError, aS as COMETIX_COMMAND_NAME, aT as COMETIX_COMMANDS, aU as installCometixLine, am as addNumbersToChoices, aV as checkAndUpdateTools, aW as runCodexUpdate, aX as resolveCodeType$1, at as readJsonConfig, aY as writeJsonConfig, q as ZCF_CONFIG_FILE, aE as readZcfConfig, D as DEFAULT_CODE_TOOL_TYPE, u as isCodeToolType, aZ as displayBanner, aC as updateZcfConfig, a_ as version, a$ as resolveAiOutputLanguage, b0 as updatePromptOnly, b1 as selectAndInstallWorkflows, b2 as checkClaudeCodeVersionAndPrompt, w as resolveCodeToolType$1, b3 as displayBannerWithInfo, s as CODE_TOOL_BANNERS, b4 as runCodexUninstall, b5 as configureCodexMcp, b6 as configureCodexApi, b7 as runCodexWorkflowImportWithLanguageSelection, b8 as runCodexFullInit, i as init, b9 as switchCodexProvider, ba as listCodexProviders, ay as readCodexConfig, bb as switchToOfficialLogin, bc as switchToProvider, bd as readZcfConfigAsync, be as initI18n, bf as selectScriptLanguage, aD as changeLanguage } from './chunks/simple-config.mjs';
4
+ import { ak as ensureI18nInitialized, al as i18n, aN as readCcrConfig, aI as isCcrInstalled, aJ as installCcr, aO as configureCcrFeature, ao as promptBoolean, aP as handleExitPromptError, aQ as handleGeneralError, aR as COMETIX_COMMAND_NAME, aS as COMETIX_COMMANDS, aT as installCometixLine, am as addNumbersToChoices, aU as checkAndUpdateTools, aV as runCodexUpdate, aW as resolveCodeType$1, at as readJsonConfig, aX as writeJsonConfig, q as ZCF_CONFIG_FILE, aD as readZcfConfig, D as DEFAULT_CODE_TOOL_TYPE, u as isCodeToolType, aY as displayBanner, aB as updateZcfConfig, aZ as version, a_ as resolveAiOutputLanguage, a$ as updatePromptOnly, b0 as selectAndInstallWorkflows, b1 as checkClaudeCodeVersionAndPrompt, w as resolveCodeToolType$1, b2 as displayBannerWithInfo, s as CODE_TOOL_BANNERS, b3 as runCodexUninstall, b4 as configureCodexMcp, b5 as configureCodexApi, b6 as runCodexWorkflowImportWithLanguageSelection, b7 as runCodexFullInit, i as init, b8 as switchCodexProvider, b9 as listCodexProviders, ay as readCodexConfig, ba as switchToOfficialLogin, bb as switchToProvider, bc as readZcfConfigAsync, bd as initI18n, be as selectScriptLanguage, aC as changeLanguage } from './chunks/simple-config.mjs';
5
5
  import { existsSync } from 'node:fs';
6
6
  import { homedir } from 'node:os';
7
7
  import inquirer from 'inquirer';
@@ -20,7 +20,7 @@ import 'node:url';
20
20
  import 'inquirer-toggle';
21
21
  import 'ora';
22
22
  import 'semver';
23
- import 'smol-toml';
23
+ import '@rainbowatcher/toml-edit-js';
24
24
  import 'node:fs/promises';
25
25
  import 'i18next';
26
26
  import 'i18next-fs-backend';
@@ -1193,7 +1193,7 @@ async function update(options = {}) {
1193
1193
  }
1194
1194
  return;
1195
1195
  }
1196
- const { resolveTemplateLanguage } = await import('./chunks/simple-config.mjs').then(function (n) { return n.bm; });
1196
+ const { resolveTemplateLanguage } = await import('./chunks/simple-config.mjs').then(function (n) { return n.bl; });
1197
1197
  const configLang = await resolveTemplateLanguage(
1198
1198
  options.configLang,
1199
1199
  // Command line option
@@ -80,7 +80,7 @@
80
80
  "copyingProvider": "Copying provider: {{name}}",
81
81
  "providerCopied": "✔ Successfully copied provider: {{name}}",
82
82
  "providerCopyFailed": "❌ Failed to copy provider: {{error}}",
83
- "providerModelPrompt": "Model name (e.g. gpt-5-codex)",
83
+ "providerModelPrompt": "Model name (e.g. gpt-5.2)",
84
84
  "providerModelRequired": "Model name is required",
85
85
  "selectProvidersToDelete": "Select providers to delete (multiple)",
86
86
  "selectAtLeastOne": "Please select at least one provider",
@@ -70,8 +70,9 @@
70
70
  "updatingPrompts": "Updating Claude Code memory documents...",
71
71
  "enterCustomModel": "Enter custom model name",
72
72
  "systemPromptConfigured": "System prompt style configured",
73
- "codexModelOptions.gpt5": "GPT-5 - General powerful model, suitable for complex tasks",
74
- "codexModelOptions.gpt5Codex": "GPT-5-Codex - Code-optimized model, recommended for programming tasks",
73
+ "codexModelOptions.gpt51CodexMax": "GPT-5.1-Codex-Max - Codex-optimized flagship for deep and fast reasoning",
74
+ "codexModelOptions.gpt51CodexMini": "GPT-5.1-Codex-Mini - Optimized for codex. Cheaper, faster, but less capable",
75
+ "codexModelOptions.gpt52": "GPT-5.2 - Latest frontier model with improvements across knowledge, reasoning and coding (Recommended)",
75
76
  "codexModelOptions.custom": "Custom - Specify custom model names",
76
77
  "windowsMcpConfigFixed": "Windows MCP configuration fixed"
77
78
  }
@@ -41,7 +41,7 @@
41
41
  "menuDescriptions.codexImportWorkflow": "Import/update Codex workflow-related files",
42
42
  "menuDescriptions.codexConfigureApi": "Configure Codex API providers",
43
43
  "menuDescriptions.codexConfigureMcp": "Configure Codex MCP services",
44
- "menuDescriptions.codexConfigureModel": "Set default model (gpt-5/gpt-5-codex/custom)",
44
+ "menuDescriptions.codexConfigureModel": "Set default model (gpt-5.2/gpt-5.1-codex-max/gpt-5.1-codex-mini/custom)",
45
45
  "menuDescriptions.codexConfigureAiMemory": "Configure AI output language and system prompt style",
46
46
  "menuDescriptions.codexUninstall": "Remove Codex configuration and files",
47
47
  "menuDescriptions.codexCheckUpdates": "Check and update Codex",
@@ -80,7 +80,7 @@
80
80
  "copyingProvider": "正在复制供应商:{{name}}",
81
81
  "providerCopied": "✔ 已成功复制供应商:{{name}}",
82
82
  "providerCopyFailed": "❌ 复制供应商失败:{{error}}",
83
- "providerModelPrompt": "模型名称(如 gpt-5-codex)",
83
+ "providerModelPrompt": "模型名称(如 gpt-5.2)",
84
84
  "providerModelRequired": "必须填写模型名称",
85
85
  "selectProvidersToDelete": "选择要删除的供应商(多选)",
86
86
  "selectAtLeastOne": "请至少选择一个供应商",
@@ -70,8 +70,9 @@
70
70
  "updatingPrompts": "正在更新 Claude Code 记忆文档...",
71
71
  "enterCustomModel": "请输入自定义模型名称",
72
72
  "systemPromptConfigured": "系统提示词风格已配置",
73
- "codexModelOptions.gpt5": "GPT-5 - 通用强力模型,适合复杂任务",
74
- "codexModelOptions.gpt5Codex": "GPT-5-Codex - 专为代码优化的模型,推荐用于编程任务",
73
+ "codexModelOptions.gpt51CodexMax": "GPT-5.1-Codex-Max - Codex 优化旗舰模型,支持深度快速推理",
74
+ "codexModelOptions.gpt51CodexMini": "GPT-5.1-Codex-Mini - Codex 优化版,更便宜快速但能力稍弱",
75
+ "codexModelOptions.gpt52": "GPT-5.2 - 最新前沿模型,知识、推理和编码全面提升(推荐)",
75
76
  "codexModelOptions.custom": "自定义 - 指定自定义模型名称",
76
77
  "windowsMcpConfigFixed": "Windows MCP 配置已修复"
77
78
  }
@@ -41,7 +41,7 @@
41
41
  "menuDescriptions.codexImportWorkflow": "仅导入/更新 Codex 工作流相关文件",
42
42
  "menuDescriptions.codexConfigureApi": "配置 Codex 的 API 提供商",
43
43
  "menuDescriptions.codexConfigureMcp": "配置 Codex 的 MCP 服务",
44
- "menuDescriptions.codexConfigureModel": "设置默认模型(gpt-5/gpt-5-codex/自定义)",
44
+ "menuDescriptions.codexConfigureModel": "设置默认模型(gpt-5.2/gpt-5.1-codex-max/gpt-5.1-codex-mini/自定义)",
45
45
  "menuDescriptions.codexConfigureAiMemory": "配置 AI 输出语言和系统提示词风格",
46
46
  "menuDescriptions.codexUninstall": "删除 Codex 配置和相关文件",
47
47
  "menuDescriptions.codexCheckUpdates": "检查并更新 Codex",
package/dist/index.mjs CHANGED
@@ -13,7 +13,7 @@ import 'inquirer-toggle';
13
13
  import 'ora';
14
14
  import 'tinyexec';
15
15
  import 'semver';
16
- import 'smol-toml';
16
+ import '@rainbowatcher/toml-edit-js';
17
17
  import 'node:fs/promises';
18
18
  import 'i18next';
19
19
  import 'i18next-fs-backend';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "zcf",
3
3
  "type": "module",
4
- "version": "3.5.0",
4
+ "version": "3.5.1",
5
5
  "description": "Zero-Config Code Flow - One-click configuration tool for Code Cli",
6
6
  "author": {
7
7
  "name": "Miao Da",
@@ -43,6 +43,7 @@
43
43
  "templates"
44
44
  ],
45
45
  "dependencies": {
46
+ "@rainbowatcher/toml-edit-js": "^0.6.4",
46
47
  "@types/semver": "^7.7.1",
47
48
  "ansis": "^4.1.0",
48
49
  "cac": "^6.7.14",
@@ -56,7 +57,6 @@
56
57
  "ora": "^9.0.0",
57
58
  "pathe": "^2.0.3",
58
59
  "semver": "^7.7.2",
59
- "smol-toml": "^1.4.2",
60
60
  "tinyexec": "^1.0.1",
61
61
  "trash": "^10.0.0"
62
62
  },