zcf 3.4.3 → 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 +8 -1
- package/dist/chunks/api-providers.mjs +1 -1
- 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 +351 -263
- 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/templates/CLAUDE.md +39 -11
- package/templates/{codex/en/workflow/sixStep/prompts → common/workflow/sixStep/en}/workflow.md +25 -4
- package/templates/{codex/zh-CN/workflow/sixStep/prompts → common/workflow/sixStep/zh-CN}/workflow.md +25 -4
- package/templates/claude-code/en/workflow/sixStep/commands/workflow.md +0 -230
- package/templates/claude-code/zh-CN/workflow/sixStep/commands/workflow.md +0 -194
- package/templates/codex/en/system-prompt/engineer-professional.md +0 -88
- package/templates/codex/en/system-prompt/laowang-engineer.md +0 -127
- package/templates/codex/en/system-prompt/nekomata-engineer.md +0 -120
- package/templates/codex/en/system-prompt/ojousama-engineer.md +0 -121
- package/templates/codex/en/workflow/git/prompts/git-cleanBranches.md +0 -102
- package/templates/codex/en/workflow/git/prompts/git-commit.md +0 -205
- package/templates/codex/en/workflow/git/prompts/git-rollback.md +0 -90
- package/templates/codex/en/workflow/git/prompts/git-worktree.md +0 -276
- package/templates/codex/zh-CN/system-prompt/engineer-professional.md +0 -89
- package/templates/codex/zh-CN/system-prompt/laowang-engineer.md +0 -127
- package/templates/codex/zh-CN/system-prompt/nekomata-engineer.md +0 -120
- package/templates/codex/zh-CN/system-prompt/ojousama-engineer.md +0 -121
- package/templates/codex/zh-CN/workflow/git/prompts/git-cleanBranches.md +0 -102
- package/templates/codex/zh-CN/workflow/git/prompts/git-commit.md +0 -205
- package/templates/codex/zh-CN/workflow/git/prompts/git-rollback.md +0 -90
- package/templates/codex/zh-CN/workflow/git/prompts/git-worktree.md +0 -276
- /package/templates/{claude-code/en/output-styles → common/output-styles/en}/engineer-professional.md +0 -0
- /package/templates/{claude-code/en/output-styles → common/output-styles/en}/laowang-engineer.md +0 -0
- /package/templates/{claude-code/en/output-styles → common/output-styles/en}/nekomata-engineer.md +0 -0
- /package/templates/{claude-code/en/output-styles → common/output-styles/en}/ojousama-engineer.md +0 -0
- /package/templates/{claude-code/zh-CN/output-styles → common/output-styles/zh-CN}/engineer-professional.md +0 -0
- /package/templates/{claude-code/zh-CN/output-styles → common/output-styles/zh-CN}/laowang-engineer.md +0 -0
- /package/templates/{claude-code/zh-CN/output-styles → common/output-styles/zh-CN}/nekomata-engineer.md +0 -0
- /package/templates/{claude-code/zh-CN/output-styles → common/output-styles/zh-CN}/ojousama-engineer.md +0 -0
- /package/templates/{claude-code/en/workflow/git/commands → common/workflow/git/en}/git-cleanBranches.md +0 -0
- /package/templates/{claude-code/en/workflow/git/commands → common/workflow/git/en}/git-commit.md +0 -0
- /package/templates/{claude-code/en/workflow/git/commands → common/workflow/git/en}/git-rollback.md +0 -0
- /package/templates/{claude-code/en/workflow/git/commands → common/workflow/git/en}/git-worktree.md +0 -0
- /package/templates/{claude-code/zh-CN/workflow/git/commands → common/workflow/git/zh-CN}/git-cleanBranches.md +0 -0
- /package/templates/{claude-code/zh-CN/workflow/git/commands → common/workflow/git/zh-CN}/git-commit.md +0 -0
- /package/templates/{claude-code/zh-CN/workflow/git/commands → common/workflow/git/zh-CN}/git-rollback.md +0 -0
- /package/templates/{claude-code/zh-CN/workflow/git/commands → common/workflow/git/zh-CN}/git-worktree.md +0 -0
|
@@ -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.
|
|
21
|
+
const version = "3.5.1";
|
|
22
22
|
const homepage = "https://github.com/UfoMiao/zcf";
|
|
23
23
|
|
|
24
24
|
const i18n = i18next.createInstance();
|
|
@@ -1852,6 +1852,7 @@ async function configureCcrProxy(ccrConfig) {
|
|
|
1852
1852
|
if (!settings.env) {
|
|
1853
1853
|
settings.env = {};
|
|
1854
1854
|
}
|
|
1855
|
+
delete settings.env.ANTHROPIC_AUTH_TOKEN;
|
|
1855
1856
|
settings.env.ANTHROPIC_BASE_URL = `http://${host}:${port}`;
|
|
1856
1857
|
settings.env.ANTHROPIC_API_KEY = apiKey;
|
|
1857
1858
|
writeJsonConfig(SETTINGS_FILE, settings);
|
|
@@ -2849,6 +2850,34 @@ function addNumbersToChoices(choices, startFrom = 1, format = (n) => `${n}. `) {
|
|
|
2849
2850
|
});
|
|
2850
2851
|
}
|
|
2851
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
|
+
|
|
2852
2881
|
function isSupportedLang(value) {
|
|
2853
2882
|
return SUPPORTED_LANGS.includes(value);
|
|
2854
2883
|
}
|
|
@@ -2864,18 +2893,117 @@ function readTomlConfig(configPath) {
|
|
|
2864
2893
|
return null;
|
|
2865
2894
|
}
|
|
2866
2895
|
const content = readFile(configPath);
|
|
2867
|
-
const parsed =
|
|
2896
|
+
const parsed = parseToml(content);
|
|
2868
2897
|
return parsed;
|
|
2869
2898
|
} catch {
|
|
2870
2899
|
return null;
|
|
2871
2900
|
}
|
|
2872
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
|
+
}
|
|
2873
2953
|
function writeTomlConfig(configPath, config) {
|
|
2874
2954
|
try {
|
|
2875
2955
|
const configDir = dirname(configPath);
|
|
2876
2956
|
ensureDir(configDir);
|
|
2877
|
-
|
|
2878
|
-
|
|
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
|
+
}
|
|
2879
3007
|
} catch {
|
|
2880
3008
|
}
|
|
2881
3009
|
}
|
|
@@ -3379,6 +3507,147 @@ function applyCodexPlatformCommand(config) {
|
|
|
3379
3507
|
}
|
|
3380
3508
|
}
|
|
3381
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
|
+
|
|
3382
3651
|
async function configureCodexMcp(options) {
|
|
3383
3652
|
ensureI18nInitialized();
|
|
3384
3653
|
const { skipPrompt = false } = options ?? {};
|
|
@@ -3395,7 +3664,6 @@ async function configureCodexMcp(options) {
|
|
|
3395
3664
|
return;
|
|
3396
3665
|
}
|
|
3397
3666
|
const defaultServiceIds = Array.isArray(options?.mcpServices) ? options.mcpServices : MCP_SERVICE_CONFIGS.filter((service) => !service.requiresApiKey).map((service) => service.id);
|
|
3398
|
-
const baseProviders2 = existingConfig?.providers || [];
|
|
3399
3667
|
const existingServices2 = existingConfig?.mcpServices || [];
|
|
3400
3668
|
const selection2 = [];
|
|
3401
3669
|
for (const id of defaultServiceIds) {
|
|
@@ -3449,13 +3717,7 @@ async function configureCodexMcp(options) {
|
|
|
3449
3717
|
}
|
|
3450
3718
|
return svc;
|
|
3451
3719
|
});
|
|
3452
|
-
|
|
3453
|
-
model: existingConfig?.model || null,
|
|
3454
|
-
modelProvider: existingConfig?.modelProvider || null,
|
|
3455
|
-
providers: baseProviders2,
|
|
3456
|
-
mcpServices: finalServices2,
|
|
3457
|
-
otherConfig: existingConfig?.otherConfig || []
|
|
3458
|
-
});
|
|
3720
|
+
batchUpdateCodexMcpServices(finalServices2);
|
|
3459
3721
|
updateZcfConfig({ codeToolType: "codex" });
|
|
3460
3722
|
console.log(ansis.green(i18n.t("codex:mcpConfigured")));
|
|
3461
3723
|
return;
|
|
@@ -3464,7 +3726,6 @@ async function configureCodexMcp(options) {
|
|
|
3464
3726
|
if (!selectedIds)
|
|
3465
3727
|
return;
|
|
3466
3728
|
const servicesMeta = await getMcpServices();
|
|
3467
|
-
const baseProviders = existingConfig?.providers || [];
|
|
3468
3729
|
const selection = [];
|
|
3469
3730
|
const existingServices = existingConfig?.mcpServices || [];
|
|
3470
3731
|
if (selectedIds.length === 0) {
|
|
@@ -3484,13 +3745,7 @@ async function configureCodexMcp(options) {
|
|
|
3484
3745
|
}
|
|
3485
3746
|
return svc;
|
|
3486
3747
|
});
|
|
3487
|
-
|
|
3488
|
-
model: existingConfig?.model || null,
|
|
3489
|
-
modelProvider: existingConfig?.modelProvider || null,
|
|
3490
|
-
providers: baseProviders,
|
|
3491
|
-
mcpServices: preserved,
|
|
3492
|
-
otherConfig: existingConfig?.otherConfig || []
|
|
3493
|
-
});
|
|
3748
|
+
batchUpdateCodexMcpServices(preserved);
|
|
3494
3749
|
updateZcfConfig({ codeToolType: "codex" });
|
|
3495
3750
|
return;
|
|
3496
3751
|
}
|
|
@@ -3559,13 +3814,7 @@ async function configureCodexMcp(options) {
|
|
|
3559
3814
|
}
|
|
3560
3815
|
return svc;
|
|
3561
3816
|
});
|
|
3562
|
-
|
|
3563
|
-
model: existingConfig?.model || null,
|
|
3564
|
-
modelProvider: existingConfig?.modelProvider || null,
|
|
3565
|
-
providers: baseProviders,
|
|
3566
|
-
mcpServices: finalServices,
|
|
3567
|
-
otherConfig: existingConfig?.otherConfig || []
|
|
3568
|
-
});
|
|
3817
|
+
batchUpdateCodexMcpServices(finalServices);
|
|
3569
3818
|
updateZcfConfig({ codeToolType: "codex" });
|
|
3570
3819
|
console.log(ansis.green(i18n.t("codex:mcpConfigured")));
|
|
3571
3820
|
}
|
|
@@ -3827,7 +4076,7 @@ function parseCodexConfig(content) {
|
|
|
3827
4076
|
const normalizedContent = content.replace(/(SYSTEMROOT\s*=\s*")[^"\n]+("?)/g, (match) => {
|
|
3828
4077
|
return match.replace(/\\\\/g, "/").replace(/\\/g, "/").replace('C:/Windows"?', 'C:/Windows"');
|
|
3829
4078
|
});
|
|
3830
|
-
const tomlData =
|
|
4079
|
+
const tomlData = parseToml(normalizedContent);
|
|
3831
4080
|
const providers = [];
|
|
3832
4081
|
if (tomlData.model_providers) {
|
|
3833
4082
|
for (const [id, providerData] of Object.entries(tomlData.model_providers)) {
|
|
@@ -3961,70 +4210,6 @@ function parseCodexConfig(content) {
|
|
|
3961
4210
|
};
|
|
3962
4211
|
}
|
|
3963
4212
|
}
|
|
3964
|
-
function formatInlineTableValue(value) {
|
|
3965
|
-
if (value === null || value === void 0) {
|
|
3966
|
-
return "";
|
|
3967
|
-
}
|
|
3968
|
-
if (typeof value === "string") {
|
|
3969
|
-
const normalized = normalizeTomlPath(value);
|
|
3970
|
-
return `'${normalized}'`;
|
|
3971
|
-
}
|
|
3972
|
-
if (typeof value === "number" || typeof value === "boolean") {
|
|
3973
|
-
return String(value);
|
|
3974
|
-
}
|
|
3975
|
-
if (Array.isArray(value)) {
|
|
3976
|
-
const items = value.map((item) => {
|
|
3977
|
-
if (typeof item === "string") {
|
|
3978
|
-
const normalized = normalizeTomlPath(item);
|
|
3979
|
-
return `'${normalized}'`;
|
|
3980
|
-
}
|
|
3981
|
-
if (typeof item === "object" && item !== null && !Array.isArray(item)) {
|
|
3982
|
-
return formatInlineTable(item);
|
|
3983
|
-
}
|
|
3984
|
-
return String(item);
|
|
3985
|
-
}).join(", ");
|
|
3986
|
-
return `[${items}]`;
|
|
3987
|
-
}
|
|
3988
|
-
if (typeof value === "object") {
|
|
3989
|
-
return formatInlineTable(value);
|
|
3990
|
-
}
|
|
3991
|
-
return String(value);
|
|
3992
|
-
}
|
|
3993
|
-
function formatInlineTable(obj) {
|
|
3994
|
-
const entries = Object.entries(obj).filter(([_, v]) => v !== null && v !== void 0).map(([k, v]) => `${k} = ${formatInlineTableValue(v)}`).join(", ");
|
|
3995
|
-
return `{${entries}}`;
|
|
3996
|
-
}
|
|
3997
|
-
function formatTomlField(key, value) {
|
|
3998
|
-
if (value === null || value === void 0) {
|
|
3999
|
-
return "";
|
|
4000
|
-
}
|
|
4001
|
-
if (typeof value === "string") {
|
|
4002
|
-
const normalized = normalizeTomlPath(value);
|
|
4003
|
-
const escaped = normalized.replace(/"/g, '\\"');
|
|
4004
|
-
return `${key} = "${escaped}"`;
|
|
4005
|
-
}
|
|
4006
|
-
if (typeof value === "number" || typeof value === "boolean") {
|
|
4007
|
-
return `${key} = ${value}`;
|
|
4008
|
-
}
|
|
4009
|
-
if (Array.isArray(value)) {
|
|
4010
|
-
const items = value.map((item) => {
|
|
4011
|
-
if (typeof item === "string") {
|
|
4012
|
-
const normalized = normalizeTomlPath(item);
|
|
4013
|
-
const escaped = normalized.replace(/"/g, '\\"');
|
|
4014
|
-
return `"${escaped}"`;
|
|
4015
|
-
}
|
|
4016
|
-
if (typeof item === "object" && item !== null && !Array.isArray(item)) {
|
|
4017
|
-
return formatInlineTable(item);
|
|
4018
|
-
}
|
|
4019
|
-
return String(item);
|
|
4020
|
-
}).join(", ");
|
|
4021
|
-
return `${key} = [${items}]`;
|
|
4022
|
-
}
|
|
4023
|
-
if (typeof value === "object") {
|
|
4024
|
-
return `${key} = ${formatInlineTable(value)}`;
|
|
4025
|
-
}
|
|
4026
|
-
return "";
|
|
4027
|
-
}
|
|
4028
4213
|
function readCodexConfig() {
|
|
4029
4214
|
if (!exists(CODEX_CONFIG_FILE))
|
|
4030
4215
|
return null;
|
|
@@ -4036,100 +4221,6 @@ function readCodexConfig() {
|
|
|
4036
4221
|
return null;
|
|
4037
4222
|
}
|
|
4038
4223
|
}
|
|
4039
|
-
function renderCodexConfig(data) {
|
|
4040
|
-
const lines = [];
|
|
4041
|
-
if (data.model || data.modelProvider || data.providers.length > 0 || data.modelProviderCommented) {
|
|
4042
|
-
lines.push("# --- model provider added by ZCF ---");
|
|
4043
|
-
if (data.model) {
|
|
4044
|
-
lines.push(`model = "${data.model}"`);
|
|
4045
|
-
}
|
|
4046
|
-
if (data.modelProvider) {
|
|
4047
|
-
const commentPrefix = data.modelProviderCommented ? "# " : "";
|
|
4048
|
-
lines.push(`${commentPrefix}model_provider = "${data.modelProvider}"`);
|
|
4049
|
-
}
|
|
4050
|
-
lines.push("");
|
|
4051
|
-
}
|
|
4052
|
-
if (data.otherConfig && data.otherConfig.length > 0) {
|
|
4053
|
-
const preserved = data.otherConfig.filter((raw) => {
|
|
4054
|
-
const l = String(raw).trim();
|
|
4055
|
-
if (!l)
|
|
4056
|
-
return false;
|
|
4057
|
-
if (/^#\s*---\s*model provider added by ZCF\s*---\s*$/i.test(l))
|
|
4058
|
-
return false;
|
|
4059
|
-
if (/^#\s*---\s*MCP servers added by ZCF\s*---\s*$/i.test(l))
|
|
4060
|
-
return false;
|
|
4061
|
-
if (/^\[\s*mcp_servers\./i.test(l))
|
|
4062
|
-
return false;
|
|
4063
|
-
if (/^\[\s*model_providers\./i.test(l))
|
|
4064
|
-
return false;
|
|
4065
|
-
if (/^#?\s*model_provider\s*=/.test(l))
|
|
4066
|
-
return false;
|
|
4067
|
-
if (/^\s*model\s*=/.test(l) && !l.includes("["))
|
|
4068
|
-
return false;
|
|
4069
|
-
return true;
|
|
4070
|
-
});
|
|
4071
|
-
if (preserved.length > 0) {
|
|
4072
|
-
lines.push(...preserved);
|
|
4073
|
-
if (data.providers.length > 0 || data.mcpServices.length > 0) {
|
|
4074
|
-
lines.push("");
|
|
4075
|
-
}
|
|
4076
|
-
}
|
|
4077
|
-
}
|
|
4078
|
-
if (data.providers.length > 0) {
|
|
4079
|
-
for (const provider of data.providers) {
|
|
4080
|
-
lines.push("");
|
|
4081
|
-
lines.push(`[model_providers.${provider.id}]`);
|
|
4082
|
-
lines.push(`name = "${provider.name}"`);
|
|
4083
|
-
lines.push(`base_url = "${provider.baseUrl}"`);
|
|
4084
|
-
lines.push(`wire_api = "${provider.wireApi}"`);
|
|
4085
|
-
lines.push(`temp_env_key = "${provider.tempEnvKey}"`);
|
|
4086
|
-
lines.push(`requires_openai_auth = ${provider.requiresOpenaiAuth}`);
|
|
4087
|
-
if (provider.model) {
|
|
4088
|
-
lines.push(`model = "${provider.model}"`);
|
|
4089
|
-
}
|
|
4090
|
-
}
|
|
4091
|
-
}
|
|
4092
|
-
if (data.mcpServices.length > 0) {
|
|
4093
|
-
lines.push("");
|
|
4094
|
-
lines.push("# --- MCP servers added by ZCF ---");
|
|
4095
|
-
for (const service of data.mcpServices) {
|
|
4096
|
-
lines.push(`[mcp_servers.${service.id}]`);
|
|
4097
|
-
const normalizedCommand = normalizeTomlPath(service.command);
|
|
4098
|
-
lines.push(`command = "${normalizedCommand}"`);
|
|
4099
|
-
const argsString = service.args.length > 0 ? service.args.map((arg) => `"${arg}"`).join(", ") : "";
|
|
4100
|
-
lines.push(`args = [${argsString}]`);
|
|
4101
|
-
if (service.env && Object.keys(service.env).length > 0) {
|
|
4102
|
-
const envEntries = Object.entries(service.env).map(([key, value]) => `${key} = '${value}'`).join(", ");
|
|
4103
|
-
lines.push(`env = {${envEntries}}`);
|
|
4104
|
-
}
|
|
4105
|
-
if (service.startup_timeout_sec) {
|
|
4106
|
-
lines.push(`startup_timeout_sec = ${service.startup_timeout_sec}`);
|
|
4107
|
-
}
|
|
4108
|
-
if (service.extraFields) {
|
|
4109
|
-
for (const [key, value] of Object.entries(service.extraFields)) {
|
|
4110
|
-
const formatted = formatTomlField(key, value);
|
|
4111
|
-
if (formatted) {
|
|
4112
|
-
lines.push(formatted);
|
|
4113
|
-
}
|
|
4114
|
-
}
|
|
4115
|
-
}
|
|
4116
|
-
lines.push("");
|
|
4117
|
-
}
|
|
4118
|
-
if (lines[lines.length - 1] === "") {
|
|
4119
|
-
lines.pop();
|
|
4120
|
-
}
|
|
4121
|
-
}
|
|
4122
|
-
let result = lines.join("\n");
|
|
4123
|
-
if (result && !result.endsWith("\n")) {
|
|
4124
|
-
result += "\n";
|
|
4125
|
-
}
|
|
4126
|
-
return result;
|
|
4127
|
-
}
|
|
4128
|
-
function writeCodexConfig(data) {
|
|
4129
|
-
ensureEnvKeyMigration();
|
|
4130
|
-
ensureDir(CODEX_DIR);
|
|
4131
|
-
writeFile(CODEX_CONFIG_FILE, renderCodexConfig(data));
|
|
4132
|
-
}
|
|
4133
4224
|
function writeAuthFile(newEntries) {
|
|
4134
4225
|
ensureDir(CODEX_DIR);
|
|
4135
4226
|
const existing = readJsonConfig(CODEX_AUTH_FILE, { defaultValue: {} }) || {};
|
|
@@ -4260,7 +4351,6 @@ async function runCodexWorkflowImportWithLanguageSelection(options) {
|
|
|
4260
4351
|
async function runCodexSystemPromptSelection(skipPrompt = false) {
|
|
4261
4352
|
ensureI18nInitialized();
|
|
4262
4353
|
const rootDir = getRootDir$1();
|
|
4263
|
-
const templateRoot = join(rootDir, "templates", "codex");
|
|
4264
4354
|
const zcfConfig$1 = readZcfConfig();
|
|
4265
4355
|
const { readDefaultTomlConfig: readDefaultTomlConfig2 } = await Promise.resolve().then(function () { return zcfConfig; });
|
|
4266
4356
|
const tomlConfig = readDefaultTomlConfig2();
|
|
@@ -4273,10 +4363,9 @@ async function runCodexSystemPromptSelection(skipPrompt = false) {
|
|
|
4273
4363
|
// Pass skipPrompt flag
|
|
4274
4364
|
);
|
|
4275
4365
|
updateZcfConfig({ templateLang: preferredLang });
|
|
4276
|
-
let
|
|
4277
|
-
if (!exists(
|
|
4278
|
-
|
|
4279
|
-
const systemPromptSrc = join(langDir, "system-prompt");
|
|
4366
|
+
let systemPromptSrc = join(rootDir, "templates", "common", "output-styles", preferredLang);
|
|
4367
|
+
if (!exists(systemPromptSrc))
|
|
4368
|
+
systemPromptSrc = join(rootDir, "templates", "common", "output-styles", "zh-CN");
|
|
4280
4369
|
if (!exists(systemPromptSrc))
|
|
4281
4370
|
return;
|
|
4282
4371
|
const availablePrompts = [
|
|
@@ -4338,17 +4427,17 @@ async function runCodexWorkflowSelection(options) {
|
|
|
4338
4427
|
ensureI18nInitialized();
|
|
4339
4428
|
const { skipPrompt = false, workflows: presetWorkflows = [] } = options ?? {};
|
|
4340
4429
|
const rootDir = getRootDir$1();
|
|
4341
|
-
const templateRoot = join(rootDir, "templates", "codex");
|
|
4342
4430
|
const zcfConfig = readZcfConfig();
|
|
4343
4431
|
const templateLang = zcfConfig?.templateLang || zcfConfig?.preferredLang || "en";
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
if (!exists(langDir))
|
|
4347
|
-
langDir = join(templateRoot, "zh-CN");
|
|
4348
|
-
const workflowSrc = join(langDir, "workflow");
|
|
4432
|
+
let preferredLang = templateLang === "en" ? "en" : "zh-CN";
|
|
4433
|
+
const workflowSrc = join(rootDir, "templates", "common", "workflow");
|
|
4349
4434
|
if (!exists(workflowSrc))
|
|
4350
4435
|
return;
|
|
4351
|
-
|
|
4436
|
+
let allWorkflows = getAllWorkflowFiles(workflowSrc, preferredLang);
|
|
4437
|
+
if (allWorkflows.length === 0 && preferredLang === "en") {
|
|
4438
|
+
preferredLang = "zh-CN";
|
|
4439
|
+
allWorkflows = getAllWorkflowFiles(workflowSrc, preferredLang);
|
|
4440
|
+
}
|
|
4352
4441
|
if (allWorkflows.length === 0)
|
|
4353
4442
|
return;
|
|
4354
4443
|
if (skipPrompt) {
|
|
@@ -4362,9 +4451,9 @@ async function runCodexWorkflowSelection(options) {
|
|
|
4362
4451
|
const selectedWorkflows = allWorkflows.filter(
|
|
4363
4452
|
(workflow) => presetWorkflows.includes(workflow.name)
|
|
4364
4453
|
);
|
|
4365
|
-
workflowsToInstall = expandSelectedWorkflowPaths(selectedWorkflows.map((w) => w.path), workflowSrc);
|
|
4454
|
+
workflowsToInstall = expandSelectedWorkflowPaths(selectedWorkflows.map((w) => w.path), workflowSrc, preferredLang);
|
|
4366
4455
|
} else {
|
|
4367
|
-
workflowsToInstall = expandSelectedWorkflowPaths(allWorkflows.map((w) => w.path), workflowSrc);
|
|
4456
|
+
workflowsToInstall = expandSelectedWorkflowPaths(allWorkflows.map((w) => w.path), workflowSrc, preferredLang);
|
|
4368
4457
|
}
|
|
4369
4458
|
for (const workflowPath of workflowsToInstall) {
|
|
4370
4459
|
const content = readFile(workflowPath);
|
|
@@ -4392,7 +4481,7 @@ async function runCodexWorkflowSelection(options) {
|
|
|
4392
4481
|
if (backupPath) {
|
|
4393
4482
|
console.log(ansis.gray(getBackupMessage(backupPath)));
|
|
4394
4483
|
}
|
|
4395
|
-
const finalWorkflowPaths = expandSelectedWorkflowPaths(workflows, workflowSrc);
|
|
4484
|
+
const finalWorkflowPaths = expandSelectedWorkflowPaths(workflows, workflowSrc, preferredLang);
|
|
4396
4485
|
for (const workflowPath of finalWorkflowPaths) {
|
|
4397
4486
|
const content = readFile(workflowPath);
|
|
4398
4487
|
const filename = workflowPath.split("/").pop() || "workflow.md";
|
|
@@ -4401,19 +4490,16 @@ async function runCodexWorkflowSelection(options) {
|
|
|
4401
4490
|
}
|
|
4402
4491
|
}
|
|
4403
4492
|
const GIT_GROUP_SENTINEL = "::gitGroup";
|
|
4404
|
-
function getAllWorkflowFiles(
|
|
4493
|
+
function getAllWorkflowFiles(workflowSrc, preferredLang) {
|
|
4405
4494
|
const workflows = [];
|
|
4406
|
-
const
|
|
4407
|
-
if (exists(
|
|
4408
|
-
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
path: workflowFile
|
|
4413
|
-
});
|
|
4414
|
-
}
|
|
4495
|
+
const sixStepFile = join(workflowSrc, "sixStep", preferredLang, "workflow.md");
|
|
4496
|
+
if (exists(sixStepFile)) {
|
|
4497
|
+
workflows.push({
|
|
4498
|
+
name: i18n.t("workflow:workflowOption.sixStepsWorkflow"),
|
|
4499
|
+
path: sixStepFile
|
|
4500
|
+
});
|
|
4415
4501
|
}
|
|
4416
|
-
const gitPromptsDir = join(
|
|
4502
|
+
const gitPromptsDir = join(workflowSrc, "git", preferredLang);
|
|
4417
4503
|
if (exists(gitPromptsDir)) {
|
|
4418
4504
|
workflows.push({
|
|
4419
4505
|
name: i18n.t("workflow:workflowOption.gitWorkflow"),
|
|
@@ -4423,19 +4509,19 @@ function getAllWorkflowFiles(dirPath) {
|
|
|
4423
4509
|
}
|
|
4424
4510
|
return workflows;
|
|
4425
4511
|
}
|
|
4426
|
-
function expandSelectedWorkflowPaths(paths, workflowSrc) {
|
|
4512
|
+
function expandSelectedWorkflowPaths(paths, workflowSrc, preferredLang) {
|
|
4427
4513
|
const expanded = [];
|
|
4428
4514
|
for (const p of paths) {
|
|
4429
4515
|
if (p === GIT_GROUP_SENTINEL) {
|
|
4430
|
-
expanded.push(...getGitPromptFiles(workflowSrc));
|
|
4516
|
+
expanded.push(...getGitPromptFiles(workflowSrc, preferredLang));
|
|
4431
4517
|
} else {
|
|
4432
4518
|
expanded.push(p);
|
|
4433
4519
|
}
|
|
4434
4520
|
}
|
|
4435
4521
|
return expanded;
|
|
4436
4522
|
}
|
|
4437
|
-
function getGitPromptFiles(workflowSrc) {
|
|
4438
|
-
const
|
|
4523
|
+
function getGitPromptFiles(workflowSrc, preferredLang) {
|
|
4524
|
+
const gitPromptsDir = join(workflowSrc, "git", preferredLang);
|
|
4439
4525
|
const files = [
|
|
4440
4526
|
"git-commit.md",
|
|
4441
4527
|
"git-rollback.md",
|
|
@@ -4444,7 +4530,7 @@ function getGitPromptFiles(workflowSrc) {
|
|
|
4444
4530
|
];
|
|
4445
4531
|
const resolved = [];
|
|
4446
4532
|
for (const f of files) {
|
|
4447
|
-
const full = join(
|
|
4533
|
+
const full = join(gitPromptsDir, f);
|
|
4448
4534
|
if (exists(full))
|
|
4449
4535
|
resolved.push(full);
|
|
4450
4536
|
}
|
|
@@ -4477,12 +4563,11 @@ async function applyCustomApiConfig(customApiConfig) {
|
|
|
4477
4563
|
}
|
|
4478
4564
|
const existingConfig = readCodexConfig();
|
|
4479
4565
|
const existingAuth = readJsonConfig(CODEX_AUTH_FILE, { defaultValue: {} }) || {};
|
|
4480
|
-
const providers = [];
|
|
4481
4566
|
const authEntries = { ...existingAuth };
|
|
4482
4567
|
const providerId = type === "auth_token" ? "official-auth-token" : "custom-api-key";
|
|
4483
4568
|
const providerName = type === "auth_token" ? "Official Auth Token" : "Custom API Key";
|
|
4484
4569
|
const existingProvider = existingConfig?.providers.find((p) => p.id === providerId);
|
|
4485
|
-
|
|
4570
|
+
const newProvider = {
|
|
4486
4571
|
id: providerId,
|
|
4487
4572
|
name: providerName,
|
|
4488
4573
|
baseUrl: baseUrl || existingProvider?.baseUrl || "https://api.anthropic.com",
|
|
@@ -4490,24 +4575,18 @@ async function applyCustomApiConfig(customApiConfig) {
|
|
|
4490
4575
|
tempEnvKey: existingProvider?.tempEnvKey || `${providerId.toUpperCase()}_API_KEY`,
|
|
4491
4576
|
requiresOpenaiAuth: existingProvider?.requiresOpenaiAuth ?? false,
|
|
4492
4577
|
model: model || existingProvider?.model
|
|
4493
|
-
}
|
|
4494
|
-
if (existingConfig?.providers) {
|
|
4495
|
-
providers.push(...existingConfig.providers.filter((p) => p.id !== providerId));
|
|
4496
|
-
}
|
|
4578
|
+
};
|
|
4497
4579
|
if (token) {
|
|
4498
4580
|
authEntries[providerId] = token;
|
|
4499
4581
|
authEntries.OPENAI_API_KEY = token;
|
|
4500
4582
|
}
|
|
4501
|
-
const
|
|
4583
|
+
const { updateCodexApiFields, upsertCodexProvider } = await Promise.resolve().then(function () { return codexTomlUpdater; });
|
|
4584
|
+
updateCodexApiFields({
|
|
4502
4585
|
model: model || existingConfig?.model || "claude-3-5-sonnet-20241022",
|
|
4503
|
-
// Prefer provided model, then existing, fallback default
|
|
4504
4586
|
modelProvider: providerId,
|
|
4505
|
-
modelProviderCommented: false
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
otherConfig: existingConfig?.otherConfig || []
|
|
4509
|
-
};
|
|
4510
|
-
writeCodexConfig(configData);
|
|
4587
|
+
modelProviderCommented: false
|
|
4588
|
+
});
|
|
4589
|
+
upsertCodexProvider(providerId, newProvider);
|
|
4511
4590
|
writeJsonConfig(CODEX_AUTH_FILE, authEntries);
|
|
4512
4591
|
updateZcfConfig({ codeToolType: "codex" });
|
|
4513
4592
|
console.log(ansis.green(`\u2714 ${i18n.t("codex:apiConfigured")}`));
|
|
@@ -4678,7 +4757,7 @@ async function configureCodexApi(options) {
|
|
|
4678
4757
|
type: "input",
|
|
4679
4758
|
name: "model",
|
|
4680
4759
|
message: `${i18n.t("configuration:enterCustomModel")}${i18n.t("common:emptyToSkip")}`,
|
|
4681
|
-
default: "gpt-5
|
|
4760
|
+
default: "gpt-5.2"
|
|
4682
4761
|
}]);
|
|
4683
4762
|
if (model.trim()) {
|
|
4684
4763
|
customModel = model.trim();
|
|
@@ -4717,7 +4796,7 @@ async function configureCodexApi(options) {
|
|
|
4717
4796
|
wireApi: selectedProvider2 === "custom" ? answers.wireApi || "responses" : prefilledWireApi,
|
|
4718
4797
|
tempEnvKey,
|
|
4719
4798
|
requiresOpenaiAuth: true,
|
|
4720
|
-
model: customModel || prefilledModel || "gpt-5
|
|
4799
|
+
model: customModel || prefilledModel || "gpt-5.2"
|
|
4721
4800
|
// Use custom model, provider's default model, or fallback
|
|
4722
4801
|
};
|
|
4723
4802
|
providers.push(newProvider);
|
|
@@ -4747,13 +4826,15 @@ async function configureCodexApi(options) {
|
|
|
4747
4826
|
if (defaultApiKey)
|
|
4748
4827
|
authEntries.OPENAI_API_KEY = defaultApiKey;
|
|
4749
4828
|
}
|
|
4750
|
-
|
|
4751
|
-
|
|
4829
|
+
const { updateCodexApiFields, upsertCodexProvider } = await Promise.resolve().then(function () { return codexTomlUpdater; });
|
|
4830
|
+
updateCodexApiFields({
|
|
4831
|
+
model: existingConfig?.model,
|
|
4752
4832
|
modelProvider: defaultProvider,
|
|
4753
|
-
|
|
4754
|
-
mcpServices: existingConfig?.mcpServices || [],
|
|
4755
|
-
otherConfig: existingConfig?.otherConfig || []
|
|
4833
|
+
modelProviderCommented: false
|
|
4756
4834
|
});
|
|
4835
|
+
for (const provider of providers) {
|
|
4836
|
+
upsertCodexProvider(provider.id, provider);
|
|
4837
|
+
}
|
|
4757
4838
|
writeAuthFile(authEntries);
|
|
4758
4839
|
updateZcfConfig({ codeToolType: "codex" });
|
|
4759
4840
|
console.log(ansis.green(i18n.t("codex:apiConfigured")));
|
|
@@ -4941,12 +5022,12 @@ async function switchCodexProvider(providerId) {
|
|
|
4941
5022
|
if (backupPath) {
|
|
4942
5023
|
console.log(ansis.gray(getBackupMessage(backupPath)));
|
|
4943
5024
|
}
|
|
4944
|
-
const updatedConfig = {
|
|
4945
|
-
...existingConfig,
|
|
4946
|
-
modelProvider: providerId
|
|
4947
|
-
};
|
|
4948
5025
|
try {
|
|
4949
|
-
|
|
5026
|
+
const { updateCodexApiFields } = await Promise.resolve().then(function () { return codexTomlUpdater; });
|
|
5027
|
+
updateCodexApiFields({
|
|
5028
|
+
modelProvider: providerId,
|
|
5029
|
+
modelProviderCommented: false
|
|
5030
|
+
});
|
|
4950
5031
|
console.log(ansis.green(i18n.t("codex:providerSwitchSuccess", { provider: providerId })));
|
|
4951
5032
|
return true;
|
|
4952
5033
|
} catch (error) {
|
|
@@ -4970,19 +5051,18 @@ async function switchToOfficialLogin() {
|
|
|
4970
5051
|
if (!preservedModelProvider) {
|
|
4971
5052
|
try {
|
|
4972
5053
|
const rawContent = readFile(CODEX_CONFIG_FILE);
|
|
4973
|
-
const parsedToml =
|
|
5054
|
+
const parsedToml = parseToml(rawContent);
|
|
4974
5055
|
if (typeof parsedToml.model_provider === "string" && parsedToml.model_provider.trim().length > 0)
|
|
4975
5056
|
preservedModelProvider = parsedToml.model_provider.trim();
|
|
4976
5057
|
} catch {
|
|
4977
5058
|
}
|
|
4978
5059
|
}
|
|
4979
5060
|
const shouldCommentModelProvider = typeof preservedModelProvider === "string" && preservedModelProvider.length > 0;
|
|
4980
|
-
const
|
|
4981
|
-
|
|
5061
|
+
const { updateCodexApiFields } = await Promise.resolve().then(function () { return codexTomlUpdater; });
|
|
5062
|
+
updateCodexApiFields({
|
|
4982
5063
|
modelProvider: shouldCommentModelProvider ? preservedModelProvider : existingConfig.modelProvider,
|
|
4983
|
-
modelProviderCommented: shouldCommentModelProvider
|
|
4984
|
-
};
|
|
4985
|
-
writeCodexConfig(updatedConfig);
|
|
5064
|
+
modelProviderCommented: shouldCommentModelProvider || existingConfig.modelProviderCommented
|
|
5065
|
+
});
|
|
4986
5066
|
const auth = readJsonConfig(CODEX_AUTH_FILE, { defaultValue: {} }) || {};
|
|
4987
5067
|
auth.OPENAI_API_KEY = null;
|
|
4988
5068
|
writeJsonConfig(CODEX_AUTH_FILE, auth, { pretty: true });
|
|
@@ -5015,18 +5095,18 @@ async function switchToProvider(providerId) {
|
|
|
5015
5095
|
targetModel = provider.model;
|
|
5016
5096
|
} else {
|
|
5017
5097
|
const currentModel = existingConfig.model;
|
|
5018
|
-
|
|
5019
|
-
|
|
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";
|
|
5020
5101
|
}
|
|
5021
5102
|
}
|
|
5022
|
-
const
|
|
5023
|
-
|
|
5103
|
+
const { updateCodexApiFields } = await Promise.resolve().then(function () { return codexTomlUpdater; });
|
|
5104
|
+
updateCodexApiFields({
|
|
5024
5105
|
model: targetModel,
|
|
5025
5106
|
modelProvider: providerId,
|
|
5026
5107
|
modelProviderCommented: false
|
|
5027
5108
|
// Ensure it's not commented
|
|
5028
|
-
};
|
|
5029
|
-
writeCodexConfig(updatedConfig);
|
|
5109
|
+
});
|
|
5030
5110
|
const auth = readJsonConfig(CODEX_AUTH_FILE, { defaultValue: {} }) || {};
|
|
5031
5111
|
const envValue = auth[provider.tempEnvKey] || null;
|
|
5032
5112
|
auth.OPENAI_API_KEY = envValue;
|
|
@@ -5063,7 +5143,6 @@ const codex = {
|
|
|
5063
5143
|
needsEnvKeyMigration: needsEnvKeyMigration,
|
|
5064
5144
|
parseCodexConfig: parseCodexConfig,
|
|
5065
5145
|
readCodexConfig: readCodexConfig,
|
|
5066
|
-
renderCodexConfig: renderCodexConfig,
|
|
5067
5146
|
runCodexFullInit: runCodexFullInit,
|
|
5068
5147
|
runCodexSystemPromptSelection: runCodexSystemPromptSelection,
|
|
5069
5148
|
runCodexUninstall: runCodexUninstall,
|
|
@@ -5073,8 +5152,7 @@ const codex = {
|
|
|
5073
5152
|
switchCodexProvider: switchCodexProvider,
|
|
5074
5153
|
switchToOfficialLogin: switchToOfficialLogin,
|
|
5075
5154
|
switchToProvider: switchToProvider,
|
|
5076
|
-
writeAuthFile: writeAuthFile
|
|
5077
|
-
writeCodexConfig: writeCodexConfig
|
|
5155
|
+
writeAuthFile: writeAuthFile
|
|
5078
5156
|
};
|
|
5079
5157
|
|
|
5080
5158
|
const CODE_TYPE_ABBREVIATIONS = {
|
|
@@ -5267,7 +5345,7 @@ async function copyOutputStyles(selectedStyles, lang) {
|
|
|
5267
5345
|
const currentFilePath = fileURLToPath(import.meta.url);
|
|
5268
5346
|
const distDir = dirname(dirname(currentFilePath));
|
|
5269
5347
|
const rootDir = dirname(distDir);
|
|
5270
|
-
const templateDir = join(rootDir, "templates", "
|
|
5348
|
+
const templateDir = join(rootDir, "templates", "common", "output-styles", lang);
|
|
5271
5349
|
for (const styleId of selectedStyles) {
|
|
5272
5350
|
const style = OUTPUT_STYLES.find((s) => s.id === styleId);
|
|
5273
5351
|
if (!style || !style.isCustom || !style.filePath) {
|
|
@@ -6415,6 +6493,7 @@ function getRootDir() {
|
|
|
6415
6493
|
return dirname(distDir);
|
|
6416
6494
|
}
|
|
6417
6495
|
const DEFAULT_CODE_TOOL_TEMPLATE = "claude-code";
|
|
6496
|
+
const COMMON_TEMPLATE_CATEGORIES = ["git", "sixStep"];
|
|
6418
6497
|
async function selectAndInstallWorkflows(configLang, preselectedWorkflows) {
|
|
6419
6498
|
ensureI18nInitialized();
|
|
6420
6499
|
const workflows = getOrderedWorkflows();
|
|
@@ -6474,7 +6553,16 @@ async function installWorkflowWithDependencies(config, configLang) {
|
|
|
6474
6553
|
await mkdir(commandsDir, { recursive: true });
|
|
6475
6554
|
}
|
|
6476
6555
|
for (const commandFile of config.commands) {
|
|
6477
|
-
const
|
|
6556
|
+
const isCommonTemplate = COMMON_TEMPLATE_CATEGORIES.includes(config.category);
|
|
6557
|
+
const commandSource = isCommonTemplate ? join(
|
|
6558
|
+
rootDir,
|
|
6559
|
+
"templates",
|
|
6560
|
+
"common",
|
|
6561
|
+
"workflow",
|
|
6562
|
+
config.category,
|
|
6563
|
+
configLang,
|
|
6564
|
+
commandFile
|
|
6565
|
+
) : join(
|
|
6478
6566
|
rootDir,
|
|
6479
6567
|
"templates",
|
|
6480
6568
|
DEFAULT_CODE_TOOL_TEMPLATE,
|
|
@@ -7482,7 +7570,7 @@ async function convertToCodexProvider(config) {
|
|
|
7482
7570
|
const displayName = config.name || config.provider || "custom";
|
|
7483
7571
|
const providerId = displayName.toLowerCase().replace(/[^a-z0-9]/g, "-");
|
|
7484
7572
|
let baseUrl = config.url || API_DEFAULT_URL;
|
|
7485
|
-
let model = config.primaryModel || "gpt-5
|
|
7573
|
+
let model = config.primaryModel || "gpt-5.2";
|
|
7486
7574
|
let wireApi = "responses";
|
|
7487
7575
|
if (config.provider && config.provider !== "custom") {
|
|
7488
7576
|
const { getProviderPreset } = await import('./api-providers.mjs');
|
|
@@ -7582,4 +7670,4 @@ async function openSettingsJson() {
|
|
|
7582
7670
|
}
|
|
7583
7671
|
}
|
|
7584
7672
|
|
|
7585
|
-
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 };
|