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 +7 -0
- package/dist/chunks/claude-code-config-manager.mjs +7 -7
- package/dist/chunks/claude-code-incremental-manager.mjs +1 -1
- package/dist/chunks/codex-config-switch.mjs +4 -4
- package/dist/chunks/codex-provider-manager.mjs +28 -41
- package/dist/chunks/codex-uninstaller.mjs +1 -1
- package/dist/chunks/commands.mjs +1 -1
- package/dist/chunks/features.mjs +20 -28
- package/dist/chunks/simple-config.mjs +312 -230
- package/dist/cli.mjs +3 -3
- package/dist/i18n/locales/en/codex.json +1 -1
- package/dist/i18n/locales/en/configuration.json +3 -2
- package/dist/i18n/locales/en/menu.json +1 -1
- package/dist/i18n/locales/zh-CN/codex.json +1 -1
- package/dist/i18n/locales/zh-CN/configuration.json +3 -2
- package/dist/i18n/locales/zh-CN/menu.json +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +2 -2
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 '
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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 '
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 '
|
|
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
|
-
|
|
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
|
|
116
|
-
|
|
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
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
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,
|
package/dist/chunks/commands.mjs
CHANGED
package/dist/chunks/features.mjs
CHANGED
|
@@ -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,
|
|
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 '
|
|
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.
|
|
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.
|
|
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.
|
|
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) :
|
|
424
|
-
// Default to gpt-5
|
|
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.
|
|
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 {
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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 '
|
|
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.
|
|
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 =
|
|
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
|
-
|
|
2879
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
4503
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
4747
|
-
|
|
4829
|
+
const { updateCodexApiFields, upsertCodexProvider } = await Promise.resolve().then(function () { return codexTomlUpdater; });
|
|
4830
|
+
updateCodexApiFields({
|
|
4831
|
+
model: existingConfig?.model,
|
|
4748
4832
|
modelProvider: defaultProvider,
|
|
4749
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
|
4977
|
-
|
|
5061
|
+
const { updateCodexApiFields } = await Promise.resolve().then(function () { return codexTomlUpdater; });
|
|
5062
|
+
updateCodexApiFields({
|
|
4978
5063
|
modelProvider: shouldCommentModelProvider ? preservedModelProvider : existingConfig.modelProvider,
|
|
4979
|
-
modelProviderCommented: shouldCommentModelProvider
|
|
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
|
-
|
|
5015
|
-
|
|
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
|
|
5019
|
-
|
|
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
|
|
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,
|
|
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,
|
|
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 '
|
|
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.
|
|
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
|
|
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.
|
|
74
|
-
"codexModelOptions.
|
|
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
|
|
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.
|
|
74
|
-
"codexModelOptions.
|
|
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
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zcf",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "3.5.
|
|
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
|
},
|