zcf 3.1.2 → 3.1.4
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 +2 -3
- package/dist/chunks/simple-config.mjs +329 -70
- package/dist/cli.mjs +74 -19
- package/dist/i18n/locales/en/cli.json +2 -0
- package/dist/i18n/locales/en/errors.json +1 -0
- package/dist/i18n/locales/zh-CN/cli.json +2 -0
- package/dist/i18n/locales/zh-CN/errors.json +1 -0
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/package.json +1 -1
- package/templates/claude-code/common/settings.json +8 -6
- package/templates/codex/en/workflow/git/prompts/git-cleanBranches.md +102 -0
- package/templates/codex/en/workflow/git/prompts/git-commit.md +157 -0
- package/templates/codex/en/workflow/git/prompts/git-rollback.md +90 -0
- package/templates/codex/en/workflow/git/prompts/git-worktree.md +276 -0
- package/templates/codex/en/workflow/sixStep/prompts/workflow.md +140 -121
- package/templates/codex/zh-CN/workflow/git/prompts/git-cleanBranches.md +102 -0
- package/templates/codex/zh-CN/workflow/git/prompts/git-commit.md +157 -0
- package/templates/codex/zh-CN/workflow/git/prompts/git-rollback.md +90 -0
- package/templates/codex/zh-CN/workflow/git/prompts/git-worktree.md +276 -0
- package/templates/codex/zh-CN/workflow/sixStep/prompts/workflow.md +16 -33
|
@@ -16,7 +16,7 @@ import { rm, mkdir, copyFile as copyFile$1 } from 'node:fs/promises';
|
|
|
16
16
|
import i18next from 'i18next';
|
|
17
17
|
import Backend from 'i18next-fs-backend';
|
|
18
18
|
|
|
19
|
-
const version = "3.1.
|
|
19
|
+
const version = "3.1.4";
|
|
20
20
|
const homepage = "https://github.com/UfoMiao/zcf";
|
|
21
21
|
|
|
22
22
|
const i18n = i18next.createInstance();
|
|
@@ -543,11 +543,15 @@ function getMcpCommand() {
|
|
|
543
543
|
return ["npx"];
|
|
544
544
|
}
|
|
545
545
|
function getSystemRoot() {
|
|
546
|
-
if (isWindows())
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
546
|
+
if (!isWindows())
|
|
547
|
+
return null;
|
|
548
|
+
const env = process.env;
|
|
549
|
+
let systemRoot = "C:\\Windows";
|
|
550
|
+
if (Object.prototype.hasOwnProperty.call(env, "SYSTEMROOT") && env.SYSTEMROOT)
|
|
551
|
+
systemRoot = env.SYSTEMROOT;
|
|
552
|
+
else if (Object.prototype.hasOwnProperty.call(env, "SystemRoot") && env.SystemRoot)
|
|
553
|
+
systemRoot = env.SystemRoot;
|
|
554
|
+
return systemRoot.replace(/\\+/g, "/").replace(/\/+/g, "/");
|
|
551
555
|
}
|
|
552
556
|
async function commandExists(command) {
|
|
553
557
|
try {
|
|
@@ -2494,12 +2498,15 @@ async function selectScriptLanguage(currentLang) {
|
|
|
2494
2498
|
});
|
|
2495
2499
|
return scriptLang;
|
|
2496
2500
|
}
|
|
2497
|
-
async function resolveAiOutputLanguage(scriptLang, commandLineOption, savedConfig) {
|
|
2501
|
+
async function resolveAiOutputLanguage(scriptLang, commandLineOption, savedConfig, skipPrompt) {
|
|
2498
2502
|
ensureI18nInitialized();
|
|
2499
2503
|
if (commandLineOption) {
|
|
2500
2504
|
return commandLineOption;
|
|
2501
2505
|
}
|
|
2502
2506
|
if (savedConfig?.aiOutputLang) {
|
|
2507
|
+
if (skipPrompt) {
|
|
2508
|
+
return savedConfig.aiOutputLang;
|
|
2509
|
+
}
|
|
2503
2510
|
const currentLanguageLabel = getAiOutputLanguageLabel(savedConfig.aiOutputLang) || savedConfig.aiOutputLang;
|
|
2504
2511
|
console.log(ansis.blue(`${i18n.t("language:currentConfigFound")}: ${currentLanguageLabel}`));
|
|
2505
2512
|
const { shouldModify } = await inquirer.prompt({
|
|
@@ -2518,6 +2525,9 @@ async function resolveAiOutputLanguage(scriptLang, commandLineOption, savedConfi
|
|
|
2518
2525
|
}
|
|
2519
2526
|
return await selectAiOutputLanguage(scriptLang);
|
|
2520
2527
|
}
|
|
2528
|
+
if (skipPrompt) {
|
|
2529
|
+
return scriptLang;
|
|
2530
|
+
}
|
|
2521
2531
|
return await selectAiOutputLanguage(scriptLang);
|
|
2522
2532
|
}
|
|
2523
2533
|
async function selectTemplateLanguage() {
|
|
@@ -2543,12 +2553,15 @@ async function selectTemplateLanguage() {
|
|
|
2543
2553
|
}
|
|
2544
2554
|
return lang;
|
|
2545
2555
|
}
|
|
2546
|
-
async function resolveTemplateLanguage(commandLineOption, savedConfig) {
|
|
2556
|
+
async function resolveTemplateLanguage(commandLineOption, savedConfig, skipPrompt) {
|
|
2547
2557
|
ensureI18nInitialized();
|
|
2548
2558
|
if (commandLineOption) {
|
|
2549
2559
|
return commandLineOption;
|
|
2550
2560
|
}
|
|
2551
2561
|
if (savedConfig?.templateLang) {
|
|
2562
|
+
if (skipPrompt) {
|
|
2563
|
+
return savedConfig.templateLang;
|
|
2564
|
+
}
|
|
2552
2565
|
const currentLanguageLabel = LANG_LABELS[savedConfig.templateLang];
|
|
2553
2566
|
console.log(ansis.blue(`${i18n.t("language:currentTemplateLanguageFound")}: ${currentLanguageLabel}`));
|
|
2554
2567
|
const { shouldModify } = await inquirer.prompt({
|
|
@@ -2568,6 +2581,9 @@ async function resolveTemplateLanguage(commandLineOption, savedConfig) {
|
|
|
2568
2581
|
return await selectTemplateLanguage();
|
|
2569
2582
|
}
|
|
2570
2583
|
if (savedConfig?.preferredLang && !savedConfig?.templateLang) {
|
|
2584
|
+
if (skipPrompt) {
|
|
2585
|
+
return savedConfig.preferredLang;
|
|
2586
|
+
}
|
|
2571
2587
|
console.log(ansis.yellow(`${i18n.t("language:usingFallbackTemplate")}: ${LANG_LABELS[savedConfig.preferredLang]}`));
|
|
2572
2588
|
const { shouldModify } = await inquirer.prompt({
|
|
2573
2589
|
type: "confirm",
|
|
@@ -2584,9 +2600,12 @@ async function resolveTemplateLanguage(commandLineOption, savedConfig) {
|
|
|
2584
2600
|
}
|
|
2585
2601
|
return await selectTemplateLanguage();
|
|
2586
2602
|
}
|
|
2603
|
+
if (skipPrompt) {
|
|
2604
|
+
return "en";
|
|
2605
|
+
}
|
|
2587
2606
|
return await selectTemplateLanguage();
|
|
2588
2607
|
}
|
|
2589
|
-
async function resolveSystemPromptStyle(availablePrompts, commandLineOption, savedConfig) {
|
|
2608
|
+
async function resolveSystemPromptStyle(availablePrompts, commandLineOption, savedConfig, skipPrompt) {
|
|
2590
2609
|
ensureI18nInitialized();
|
|
2591
2610
|
if (commandLineOption && availablePrompts.some((p) => p.id === commandLineOption)) {
|
|
2592
2611
|
return commandLineOption;
|
|
@@ -2595,6 +2614,9 @@ async function resolveSystemPromptStyle(availablePrompts, commandLineOption, sav
|
|
|
2595
2614
|
const currentStyleId = savedConfig.codex.systemPromptStyle;
|
|
2596
2615
|
const currentStyle = availablePrompts.find((p) => p.id === currentStyleId);
|
|
2597
2616
|
if (currentStyle) {
|
|
2617
|
+
if (skipPrompt) {
|
|
2618
|
+
return currentStyleId;
|
|
2619
|
+
}
|
|
2598
2620
|
console.log(ansis.blue(`${i18n.t("language:currentSystemPromptFound")}: ${currentStyle.name}`));
|
|
2599
2621
|
const { shouldModify } = await inquirer.prompt({
|
|
2600
2622
|
type: "confirm",
|
|
@@ -2612,6 +2634,9 @@ async function resolveSystemPromptStyle(availablePrompts, commandLineOption, sav
|
|
|
2612
2634
|
}
|
|
2613
2635
|
}
|
|
2614
2636
|
}
|
|
2637
|
+
if (skipPrompt) {
|
|
2638
|
+
return "engineer-professional";
|
|
2639
|
+
}
|
|
2615
2640
|
const { systemPrompt } = await inquirer.prompt([{
|
|
2616
2641
|
type: "list",
|
|
2617
2642
|
name: "systemPrompt",
|
|
@@ -2807,7 +2832,10 @@ function parseCodexConfig(content) {
|
|
|
2807
2832
|
};
|
|
2808
2833
|
}
|
|
2809
2834
|
try {
|
|
2810
|
-
const
|
|
2835
|
+
const normalizedContent = content.replace(/(SYSTEMROOT\s*=\s*")[^"\n]+("?)/g, (match) => {
|
|
2836
|
+
return match.replace(/\\\\/g, "/").replace(/\\/g, "/").replace('C:/Windows"?', 'C:/Windows"');
|
|
2837
|
+
});
|
|
2838
|
+
const tomlData = parse(normalizedContent);
|
|
2811
2839
|
const providers = [];
|
|
2812
2840
|
if (tomlData.model_providers) {
|
|
2813
2841
|
for (const [id, providerData] of Object.entries(tomlData.model_providers)) {
|
|
@@ -2876,21 +2904,30 @@ function parseCodexConfig(content) {
|
|
|
2876
2904
|
const otherConfig = [];
|
|
2877
2905
|
const lines = content.split("\n");
|
|
2878
2906
|
let skipCurrentSection = false;
|
|
2879
|
-
let currentSection = "";
|
|
2880
2907
|
for (const line of lines) {
|
|
2881
|
-
const
|
|
2882
|
-
if (
|
|
2908
|
+
const trimmed = line.trim();
|
|
2909
|
+
if (!trimmed)
|
|
2883
2910
|
continue;
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
if (
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2911
|
+
if (/^#\s*---\s*model provider added by ZCF\s*---\s*$/i.test(trimmed))
|
|
2912
|
+
continue;
|
|
2913
|
+
if (/^#\s*---\s*MCP servers added by ZCF\s*---\s*$/i.test(trimmed))
|
|
2914
|
+
continue;
|
|
2915
|
+
if (/Managed by ZCF/i.test(trimmed))
|
|
2916
|
+
continue;
|
|
2917
|
+
const sec = trimmed.match(/^\[([^\]]+)\]/);
|
|
2918
|
+
if (sec) {
|
|
2919
|
+
const name = sec[1];
|
|
2920
|
+
skipCurrentSection = name.startsWith("model_providers.") || name.startsWith("mcp_servers.");
|
|
2921
|
+
if (skipCurrentSection)
|
|
2922
|
+
continue;
|
|
2923
|
+
otherConfig.push(line);
|
|
2891
2924
|
continue;
|
|
2892
2925
|
}
|
|
2893
|
-
if (
|
|
2926
|
+
if (/^#?\s*model_provider\s*=/.test(trimmed))
|
|
2927
|
+
continue;
|
|
2928
|
+
if (/^model\s*=/.test(trimmed))
|
|
2929
|
+
continue;
|
|
2930
|
+
if (!skipCurrentSection) {
|
|
2894
2931
|
otherConfig.push(line);
|
|
2895
2932
|
}
|
|
2896
2933
|
}
|
|
@@ -2906,13 +2943,15 @@ function parseCodexConfig(content) {
|
|
|
2906
2943
|
};
|
|
2907
2944
|
} catch (error) {
|
|
2908
2945
|
console.warn("TOML parsing failed, falling back to basic parsing:", error);
|
|
2946
|
+
const cleaned = content.replace(/^\s*#\s*---\s*model provider added by ZCF\s*---\s*$/gim, "").replace(/^\s*#\s*---\s*MCP servers added by ZCF\s*---\s*$/gim, "").replace(/^\[model_providers\.[^\]]+\][\s\S]*?(?=^\[|$)/gim, "").replace(/^\[mcp_servers\.[^\]]+\][\s\S]*?(?=^\[|$)/gim, "").replace(/^\s*(?:#\s*)?model_provider\s*=.*$/gim, "").replace(/^\s*model\s*=.*$/gim, "").replace(/\n{3,}/g, "\n\n");
|
|
2947
|
+
const otherConfig = cleaned.split("\n").map((l) => l.replace(/\s+$/g, "")).filter((l) => l.trim().length > 0);
|
|
2909
2948
|
return {
|
|
2910
2949
|
model: null,
|
|
2911
2950
|
modelProvider: null,
|
|
2912
2951
|
providers: [],
|
|
2913
2952
|
mcpServices: [],
|
|
2914
2953
|
managed: false,
|
|
2915
|
-
otherConfig
|
|
2954
|
+
otherConfig,
|
|
2916
2955
|
modelProviderCommented: void 0
|
|
2917
2956
|
};
|
|
2918
2957
|
}
|
|
@@ -2941,9 +2980,29 @@ function renderCodexConfig(data) {
|
|
|
2941
2980
|
lines.push("");
|
|
2942
2981
|
}
|
|
2943
2982
|
if (data.otherConfig && data.otherConfig.length > 0) {
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2983
|
+
const preserved = data.otherConfig.filter((raw) => {
|
|
2984
|
+
const l = String(raw).trim();
|
|
2985
|
+
if (!l)
|
|
2986
|
+
return false;
|
|
2987
|
+
if (/^#\s*---\s*model provider added by ZCF\s*---\s*$/i.test(l))
|
|
2988
|
+
return false;
|
|
2989
|
+
if (/^#\s*---\s*MCP servers added by ZCF\s*---\s*$/i.test(l))
|
|
2990
|
+
return false;
|
|
2991
|
+
if (/^\[\s*mcp_servers\./i.test(l))
|
|
2992
|
+
return false;
|
|
2993
|
+
if (/^\[\s*model_providers\./i.test(l))
|
|
2994
|
+
return false;
|
|
2995
|
+
if (/^#?\s*model_provider\s*=/.test(l))
|
|
2996
|
+
return false;
|
|
2997
|
+
if (/^\s*model\s*=/.test(l))
|
|
2998
|
+
return false;
|
|
2999
|
+
return true;
|
|
3000
|
+
});
|
|
3001
|
+
if (preserved.length > 0) {
|
|
3002
|
+
lines.push(...preserved);
|
|
3003
|
+
if (data.providers.length > 0 || data.mcpServices.length > 0) {
|
|
3004
|
+
lines.push("");
|
|
3005
|
+
}
|
|
2947
3006
|
}
|
|
2948
3007
|
}
|
|
2949
3008
|
if (data.providers.length > 0) {
|
|
@@ -3086,21 +3145,22 @@ async function runCodexWorkflowImport() {
|
|
|
3086
3145
|
async function runCodexWorkflowImportWithLanguageSelection(options) {
|
|
3087
3146
|
ensureI18nInitialized();
|
|
3088
3147
|
const zcfConfig = readZcfConfig();
|
|
3089
|
-
const { aiOutputLang: commandLineOption, skipPrompt } = options ?? {};
|
|
3090
|
-
const aiOutputLang =
|
|
3148
|
+
const { aiOutputLang: commandLineOption, skipPrompt = false } = options ?? {};
|
|
3149
|
+
const aiOutputLang = await resolveAiOutputLanguage(
|
|
3091
3150
|
i18n.language,
|
|
3092
3151
|
commandLineOption,
|
|
3093
|
-
zcfConfig
|
|
3152
|
+
zcfConfig,
|
|
3153
|
+
skipPrompt
|
|
3094
3154
|
);
|
|
3095
3155
|
updateZcfConfig({ aiOutputLang });
|
|
3096
3156
|
applyAiLanguageDirective(aiOutputLang);
|
|
3097
|
-
await runCodexSystemPromptSelection();
|
|
3157
|
+
await runCodexSystemPromptSelection(skipPrompt);
|
|
3098
3158
|
ensureCodexAgentsLanguageDirective(aiOutputLang);
|
|
3099
|
-
await runCodexWorkflowSelection();
|
|
3159
|
+
await runCodexWorkflowSelection(options);
|
|
3100
3160
|
console.log(ansis.green(i18n.t("codex:workflowInstall")));
|
|
3101
3161
|
return aiOutputLang;
|
|
3102
3162
|
}
|
|
3103
|
-
async function runCodexSystemPromptSelection() {
|
|
3163
|
+
async function runCodexSystemPromptSelection(skipPrompt = false) {
|
|
3104
3164
|
ensureI18nInitialized();
|
|
3105
3165
|
const rootDir = getRootDir$1();
|
|
3106
3166
|
const templateRoot = join(rootDir, "templates", "codex");
|
|
@@ -3111,7 +3171,9 @@ async function runCodexSystemPromptSelection() {
|
|
|
3111
3171
|
const preferredLang = await resolveTemplateLanguage(
|
|
3112
3172
|
void 0,
|
|
3113
3173
|
// No command line option for this function
|
|
3114
|
-
zcfConfig$1
|
|
3174
|
+
zcfConfig$1,
|
|
3175
|
+
skipPrompt
|
|
3176
|
+
// Pass skipPrompt flag
|
|
3115
3177
|
);
|
|
3116
3178
|
updateZcfConfig({ templateLang: preferredLang });
|
|
3117
3179
|
let langDir = join(templateRoot, preferredLang);
|
|
@@ -3149,7 +3211,9 @@ async function runCodexSystemPromptSelection() {
|
|
|
3149
3211
|
availablePrompts,
|
|
3150
3212
|
void 0,
|
|
3151
3213
|
// No command line option for this function
|
|
3152
|
-
tomlConfig
|
|
3214
|
+
tomlConfig,
|
|
3215
|
+
skipPrompt
|
|
3216
|
+
// Pass skipPrompt flag
|
|
3153
3217
|
);
|
|
3154
3218
|
if (!systemPrompt)
|
|
3155
3219
|
return;
|
|
@@ -3173,8 +3237,9 @@ async function runCodexSystemPromptSelection() {
|
|
|
3173
3237
|
console.error("Failed to update ZCF config:", error);
|
|
3174
3238
|
}
|
|
3175
3239
|
}
|
|
3176
|
-
async function runCodexWorkflowSelection() {
|
|
3240
|
+
async function runCodexWorkflowSelection(options) {
|
|
3177
3241
|
ensureI18nInitialized();
|
|
3242
|
+
const { skipPrompt = false, workflows: presetWorkflows = [] } = options ?? {};
|
|
3178
3243
|
const rootDir = getRootDir$1();
|
|
3179
3244
|
const templateRoot = join(rootDir, "templates", "codex");
|
|
3180
3245
|
const zcfConfig = readZcfConfig();
|
|
@@ -3189,6 +3254,29 @@ async function runCodexWorkflowSelection() {
|
|
|
3189
3254
|
const allWorkflows = getAllWorkflowFiles(workflowSrc);
|
|
3190
3255
|
if (allWorkflows.length === 0)
|
|
3191
3256
|
return;
|
|
3257
|
+
if (skipPrompt) {
|
|
3258
|
+
ensureDir(CODEX_PROMPTS_DIR);
|
|
3259
|
+
const backupPath2 = backupCodexPrompts();
|
|
3260
|
+
if (backupPath2) {
|
|
3261
|
+
console.log(ansis.gray(getBackupMessage(backupPath2)));
|
|
3262
|
+
}
|
|
3263
|
+
let workflowsToInstall;
|
|
3264
|
+
if (presetWorkflows.length > 0) {
|
|
3265
|
+
const selectedWorkflows = allWorkflows.filter(
|
|
3266
|
+
(workflow) => presetWorkflows.includes(workflow.name)
|
|
3267
|
+
);
|
|
3268
|
+
workflowsToInstall = expandSelectedWorkflowPaths(selectedWorkflows.map((w) => w.path), workflowSrc);
|
|
3269
|
+
} else {
|
|
3270
|
+
workflowsToInstall = expandSelectedWorkflowPaths(allWorkflows.map((w) => w.path), workflowSrc);
|
|
3271
|
+
}
|
|
3272
|
+
for (const workflowPath of workflowsToInstall) {
|
|
3273
|
+
const content = readFile(workflowPath);
|
|
3274
|
+
const filename = workflowPath.split("/").pop() || "workflow.md";
|
|
3275
|
+
const targetPath = join(CODEX_PROMPTS_DIR, filename);
|
|
3276
|
+
writeFile(targetPath, content);
|
|
3277
|
+
}
|
|
3278
|
+
return;
|
|
3279
|
+
}
|
|
3192
3280
|
const { workflows } = await inquirer.prompt([{
|
|
3193
3281
|
type: "checkbox",
|
|
3194
3282
|
name: "workflows",
|
|
@@ -3207,13 +3295,15 @@ async function runCodexWorkflowSelection() {
|
|
|
3207
3295
|
if (backupPath) {
|
|
3208
3296
|
console.log(ansis.gray(getBackupMessage(backupPath)));
|
|
3209
3297
|
}
|
|
3210
|
-
|
|
3298
|
+
const finalWorkflowPaths = expandSelectedWorkflowPaths(workflows, workflowSrc);
|
|
3299
|
+
for (const workflowPath of finalWorkflowPaths) {
|
|
3211
3300
|
const content = readFile(workflowPath);
|
|
3212
3301
|
const filename = workflowPath.split("/").pop() || "workflow.md";
|
|
3213
3302
|
const targetPath = join(CODEX_PROMPTS_DIR, filename);
|
|
3214
3303
|
writeFile(targetPath, content);
|
|
3215
3304
|
}
|
|
3216
3305
|
}
|
|
3306
|
+
const GIT_GROUP_SENTINEL = "::gitGroup";
|
|
3217
3307
|
function getAllWorkflowFiles(dirPath) {
|
|
3218
3308
|
const workflows = [];
|
|
3219
3309
|
const sixStepDir = join(dirPath, "sixStep", "prompts");
|
|
@@ -3226,8 +3316,43 @@ function getAllWorkflowFiles(dirPath) {
|
|
|
3226
3316
|
});
|
|
3227
3317
|
}
|
|
3228
3318
|
}
|
|
3319
|
+
const gitPromptsDir = join(dirPath, "git", "prompts");
|
|
3320
|
+
if (exists(gitPromptsDir)) {
|
|
3321
|
+
workflows.push({
|
|
3322
|
+
name: i18n.t("workflow:workflowOption.gitWorkflow"),
|
|
3323
|
+
// Use sentinel path for grouped selection; expanded later
|
|
3324
|
+
path: GIT_GROUP_SENTINEL
|
|
3325
|
+
});
|
|
3326
|
+
}
|
|
3229
3327
|
return workflows;
|
|
3230
3328
|
}
|
|
3329
|
+
function expandSelectedWorkflowPaths(paths, workflowSrc) {
|
|
3330
|
+
const expanded = [];
|
|
3331
|
+
for (const p of paths) {
|
|
3332
|
+
if (p === GIT_GROUP_SENTINEL) {
|
|
3333
|
+
expanded.push(...getGitPromptFiles(workflowSrc));
|
|
3334
|
+
} else {
|
|
3335
|
+
expanded.push(p);
|
|
3336
|
+
}
|
|
3337
|
+
}
|
|
3338
|
+
return expanded;
|
|
3339
|
+
}
|
|
3340
|
+
function getGitPromptFiles(workflowSrc) {
|
|
3341
|
+
const gitDir = join(workflowSrc, "git", "prompts");
|
|
3342
|
+
const files = [
|
|
3343
|
+
"git-commit.md",
|
|
3344
|
+
"git-rollback.md",
|
|
3345
|
+
"git-cleanBranches.md",
|
|
3346
|
+
"git-worktree.md"
|
|
3347
|
+
];
|
|
3348
|
+
const resolved = [];
|
|
3349
|
+
for (const f of files) {
|
|
3350
|
+
const full = join(gitDir, f);
|
|
3351
|
+
if (exists(full))
|
|
3352
|
+
resolved.push(full);
|
|
3353
|
+
}
|
|
3354
|
+
return resolved;
|
|
3355
|
+
}
|
|
3231
3356
|
function toProvidersList(providers) {
|
|
3232
3357
|
return providers.map((provider) => ({ name: provider.name || provider.id, value: provider.id }));
|
|
3233
3358
|
}
|
|
@@ -3247,10 +3372,59 @@ function createApiConfigChoices(providers, currentProvider, isCommented) {
|
|
|
3247
3372
|
});
|
|
3248
3373
|
return choices;
|
|
3249
3374
|
}
|
|
3250
|
-
async function
|
|
3375
|
+
async function applyCustomApiConfig(customApiConfig) {
|
|
3376
|
+
const { type, token, baseUrl } = customApiConfig;
|
|
3377
|
+
const backupPath = backupCodexComplete();
|
|
3378
|
+
if (backupPath) {
|
|
3379
|
+
console.log(ansis.gray(getBackupMessage(backupPath)));
|
|
3380
|
+
}
|
|
3381
|
+
const providers = [];
|
|
3382
|
+
const authEntries = {};
|
|
3383
|
+
const providerId = type === "auth_token" ? "official-auth-token" : "custom-api-key";
|
|
3384
|
+
const providerName = type === "auth_token" ? "Official Auth Token" : "Custom API Key";
|
|
3385
|
+
providers.push({
|
|
3386
|
+
id: providerId,
|
|
3387
|
+
name: providerName,
|
|
3388
|
+
baseUrl: baseUrl || "https://api.anthropic.com",
|
|
3389
|
+
wireApi: "claude",
|
|
3390
|
+
envKey: `${providerId.toUpperCase()}_API_KEY`,
|
|
3391
|
+
requiresOpenaiAuth: false
|
|
3392
|
+
});
|
|
3393
|
+
if (token) {
|
|
3394
|
+
authEntries[providerId] = token;
|
|
3395
|
+
}
|
|
3396
|
+
const configData = {
|
|
3397
|
+
model: "claude-3-5-sonnet-20241022",
|
|
3398
|
+
modelProvider: providerId,
|
|
3399
|
+
modelProviderCommented: false,
|
|
3400
|
+
providers,
|
|
3401
|
+
mcpServices: []};
|
|
3402
|
+
writeFile(CODEX_CONFIG_FILE, renderCodexConfig(configData));
|
|
3403
|
+
writeJsonConfig(CODEX_AUTH_FILE, authEntries);
|
|
3404
|
+
updateZcfConfig({ codeToolType: "codex" });
|
|
3405
|
+
console.log(ansis.green(`\u2714 ${i18n.t("codex:apiConfigured")}`));
|
|
3406
|
+
}
|
|
3407
|
+
async function configureCodexApi(options) {
|
|
3251
3408
|
ensureI18nInitialized();
|
|
3409
|
+
const { skipPrompt = false, apiMode, customApiConfig } = options ?? {};
|
|
3252
3410
|
const existingConfig = readCodexConfig();
|
|
3253
3411
|
const existingAuth = readJsonConfig(CODEX_AUTH_FILE, { defaultValue: {} }) || {};
|
|
3412
|
+
if (skipPrompt) {
|
|
3413
|
+
if (apiMode === "skip") {
|
|
3414
|
+
return;
|
|
3415
|
+
}
|
|
3416
|
+
if (apiMode === "custom" && customApiConfig) {
|
|
3417
|
+
await applyCustomApiConfig(customApiConfig);
|
|
3418
|
+
return;
|
|
3419
|
+
}
|
|
3420
|
+
if (apiMode === "official") {
|
|
3421
|
+
const success = await switchToOfficialLogin();
|
|
3422
|
+
if (success) {
|
|
3423
|
+
updateZcfConfig({ codeToolType: "codex" });
|
|
3424
|
+
}
|
|
3425
|
+
return;
|
|
3426
|
+
}
|
|
3427
|
+
}
|
|
3254
3428
|
const hasProviders = existingConfig?.providers && existingConfig.providers.length > 0;
|
|
3255
3429
|
const modeChoices = [
|
|
3256
3430
|
{ name: i18n.t("codex:apiModeOfficial"), value: "official" },
|
|
@@ -3439,9 +3613,13 @@ async function configureCodexApi() {
|
|
|
3439
3613
|
updateZcfConfig({ codeToolType: "codex" });
|
|
3440
3614
|
console.log(ansis.green(i18n.t("codex:apiConfigured")));
|
|
3441
3615
|
}
|
|
3442
|
-
async function configureCodexMcp() {
|
|
3616
|
+
async function configureCodexMcp(options) {
|
|
3443
3617
|
ensureI18nInitialized();
|
|
3618
|
+
const { skipPrompt = false } = options ?? {};
|
|
3444
3619
|
const existingConfig = readCodexConfig();
|
|
3620
|
+
if (skipPrompt) {
|
|
3621
|
+
return;
|
|
3622
|
+
}
|
|
3445
3623
|
const backupPath = backupCodexComplete();
|
|
3446
3624
|
if (backupPath) {
|
|
3447
3625
|
console.log(ansis.gray(getBackupMessage(backupPath)));
|
|
@@ -3452,14 +3630,29 @@ async function configureCodexMcp() {
|
|
|
3452
3630
|
const servicesMeta = await getMcpServices();
|
|
3453
3631
|
const baseProviders = existingConfig?.providers || [];
|
|
3454
3632
|
const selection = [];
|
|
3455
|
-
const
|
|
3633
|
+
const existingServices = existingConfig?.mcpServices || [];
|
|
3456
3634
|
if (selectedIds.length === 0) {
|
|
3457
3635
|
console.log(ansis.yellow(i18n.t("codex:noMcpConfigured")));
|
|
3636
|
+
const preserved = (existingServices || []).map((svc) => {
|
|
3637
|
+
if (isWindows()) {
|
|
3638
|
+
const systemRoot = getSystemRoot();
|
|
3639
|
+
if (systemRoot) {
|
|
3640
|
+
return {
|
|
3641
|
+
...svc,
|
|
3642
|
+
env: {
|
|
3643
|
+
...svc.env || {},
|
|
3644
|
+
SYSTEMROOT: systemRoot
|
|
3645
|
+
}
|
|
3646
|
+
};
|
|
3647
|
+
}
|
|
3648
|
+
}
|
|
3649
|
+
return svc;
|
|
3650
|
+
});
|
|
3458
3651
|
writeCodexConfig({
|
|
3459
3652
|
model: existingConfig?.model || null,
|
|
3460
3653
|
modelProvider: existingConfig?.modelProvider || null,
|
|
3461
3654
|
providers: baseProviders,
|
|
3462
|
-
mcpServices:
|
|
3655
|
+
mcpServices: preserved,
|
|
3463
3656
|
otherConfig: existingConfig?.otherConfig || []
|
|
3464
3657
|
});
|
|
3465
3658
|
updateZcfConfig({ codeToolType: "codex" });
|
|
@@ -3504,15 +3697,33 @@ async function configureCodexMcp() {
|
|
|
3504
3697
|
startup_timeout_ms: configInfo.config.startup_timeout_ms
|
|
3505
3698
|
});
|
|
3506
3699
|
}
|
|
3507
|
-
const
|
|
3508
|
-
const
|
|
3509
|
-
|
|
3510
|
-
|
|
3700
|
+
const mergedMap = /* @__PURE__ */ new Map();
|
|
3701
|
+
for (const svc of existingServices) {
|
|
3702
|
+
mergedMap.set(svc.id.toLowerCase(), { ...svc });
|
|
3703
|
+
}
|
|
3704
|
+
for (const svc of selection) {
|
|
3705
|
+
mergedMap.set(svc.id.toLowerCase(), { ...svc });
|
|
3706
|
+
}
|
|
3707
|
+
const finalServices = Array.from(mergedMap.values()).map((svc) => {
|
|
3708
|
+
if (isWindows()) {
|
|
3709
|
+
const systemRoot = getSystemRoot();
|
|
3710
|
+
if (systemRoot) {
|
|
3711
|
+
return {
|
|
3712
|
+
...svc,
|
|
3713
|
+
env: {
|
|
3714
|
+
...svc.env || {},
|
|
3715
|
+
SYSTEMROOT: systemRoot
|
|
3716
|
+
}
|
|
3717
|
+
};
|
|
3718
|
+
}
|
|
3719
|
+
}
|
|
3720
|
+
return svc;
|
|
3721
|
+
});
|
|
3511
3722
|
writeCodexConfig({
|
|
3512
3723
|
model: existingConfig?.model || null,
|
|
3513
3724
|
modelProvider: existingConfig?.modelProvider || null,
|
|
3514
3725
|
providers: baseProviders,
|
|
3515
|
-
mcpServices:
|
|
3726
|
+
mcpServices: finalServices,
|
|
3516
3727
|
otherConfig: existingConfig?.otherConfig || []
|
|
3517
3728
|
});
|
|
3518
3729
|
updateZcfConfig({ codeToolType: "codex" });
|
|
@@ -3522,8 +3733,8 @@ async function runCodexFullInit(options) {
|
|
|
3522
3733
|
ensureI18nInitialized();
|
|
3523
3734
|
await installCodexCli();
|
|
3524
3735
|
const aiOutputLang = await runCodexWorkflowImportWithLanguageSelection(options);
|
|
3525
|
-
await configureCodexApi();
|
|
3526
|
-
await configureCodexMcp();
|
|
3736
|
+
await configureCodexApi(options);
|
|
3737
|
+
await configureCodexMcp(options);
|
|
3527
3738
|
return aiOutputLang;
|
|
3528
3739
|
}
|
|
3529
3740
|
function ensureCodexAgentsLanguageDirective(aiOutputLang) {
|
|
@@ -3563,7 +3774,10 @@ function normalizeLanguageLabel(label) {
|
|
|
3563
3774
|
}
|
|
3564
3775
|
async function runCodexUpdate(force = false, skipPrompt = false) {
|
|
3565
3776
|
ensureI18nInitialized();
|
|
3566
|
-
|
|
3777
|
+
console.log(ansis.bold.cyan(`
|
|
3778
|
+
\u{1F50D} ${i18n.t("updater:checkingTools")}
|
|
3779
|
+
`));
|
|
3780
|
+
const spinner = ora(i18n.t("updater:checkingVersion")).start();
|
|
3567
3781
|
try {
|
|
3568
3782
|
const { installed, currentVersion, latestVersion, needsUpdate } = await checkCodexUpdate();
|
|
3569
3783
|
spinner.stop();
|
|
@@ -3826,6 +4040,43 @@ const codex = {
|
|
|
3826
4040
|
writeCodexConfig: writeCodexConfig
|
|
3827
4041
|
};
|
|
3828
4042
|
|
|
4043
|
+
const CODE_TYPE_ABBREVIATIONS = {
|
|
4044
|
+
cc: "claude-code",
|
|
4045
|
+
cx: "codex"
|
|
4046
|
+
};
|
|
4047
|
+
async function resolveCodeType(codeTypeParam) {
|
|
4048
|
+
if (codeTypeParam) {
|
|
4049
|
+
const normalizedParam = codeTypeParam.toLowerCase().trim();
|
|
4050
|
+
if (normalizedParam in CODE_TYPE_ABBREVIATIONS) {
|
|
4051
|
+
return CODE_TYPE_ABBREVIATIONS[normalizedParam];
|
|
4052
|
+
}
|
|
4053
|
+
if (isValidCodeType(normalizedParam)) {
|
|
4054
|
+
return normalizedParam;
|
|
4055
|
+
}
|
|
4056
|
+
const validAbbreviations = Object.keys(CODE_TYPE_ABBREVIATIONS);
|
|
4057
|
+
const validFullTypes = Object.values(CODE_TYPE_ABBREVIATIONS);
|
|
4058
|
+
const validOptions = [...validAbbreviations, ...validFullTypes].join(", ");
|
|
4059
|
+
throw new Error(
|
|
4060
|
+
i18n.t(
|
|
4061
|
+
"errors:invalidCodeType",
|
|
4062
|
+
`Invalid code type: "${codeTypeParam}". Valid options are: ${validOptions}.`,
|
|
4063
|
+
{ value: codeTypeParam, validOptions }
|
|
4064
|
+
)
|
|
4065
|
+
);
|
|
4066
|
+
}
|
|
4067
|
+
try {
|
|
4068
|
+
const config = await readZcfConfigAsync();
|
|
4069
|
+
if (config?.codeToolType && isValidCodeType(config.codeToolType)) {
|
|
4070
|
+
return config.codeToolType;
|
|
4071
|
+
}
|
|
4072
|
+
} catch {
|
|
4073
|
+
}
|
|
4074
|
+
return DEFAULT_CODE_TOOL_TYPE;
|
|
4075
|
+
}
|
|
4076
|
+
function isValidCodeType(value) {
|
|
4077
|
+
return ["claude-code", "codex"].includes(value);
|
|
4078
|
+
}
|
|
4079
|
+
|
|
3829
4080
|
function getPlatformStatusLineConfig() {
|
|
3830
4081
|
return {
|
|
3831
4082
|
type: "command",
|
|
@@ -4722,12 +4973,6 @@ function validateSkipPromptOptions(options) {
|
|
|
4722
4973
|
if (!options.configAction) {
|
|
4723
4974
|
options.configAction = "backup";
|
|
4724
4975
|
}
|
|
4725
|
-
if (!options.configLang) {
|
|
4726
|
-
options.configLang = "en";
|
|
4727
|
-
}
|
|
4728
|
-
if (!options.aiOutputLang) {
|
|
4729
|
-
options.aiOutputLang = "en";
|
|
4730
|
-
}
|
|
4731
4976
|
if (typeof options.outputStyles === "string") {
|
|
4732
4977
|
if (options.outputStyles === "skip") {
|
|
4733
4978
|
options.outputStyles = false;
|
|
@@ -4822,22 +5067,20 @@ function validateSkipPromptOptions(options) {
|
|
|
4822
5067
|
options.workflows = WORKFLOW_CONFIG_BASE.map((w) => w.id);
|
|
4823
5068
|
}
|
|
4824
5069
|
}
|
|
4825
|
-
function resolveCodeToolType(optionValue, savedValue) {
|
|
4826
|
-
if (isCodeToolType(optionValue)) {
|
|
4827
|
-
return optionValue;
|
|
4828
|
-
}
|
|
4829
|
-
if (savedValue && isCodeToolType(savedValue)) {
|
|
4830
|
-
return savedValue;
|
|
4831
|
-
}
|
|
4832
|
-
return DEFAULT_CODE_TOOL_TYPE;
|
|
4833
|
-
}
|
|
4834
5070
|
async function init(options = {}) {
|
|
4835
5071
|
if (options.skipPrompt) {
|
|
4836
5072
|
validateSkipPromptOptions(options);
|
|
4837
5073
|
}
|
|
4838
5074
|
try {
|
|
4839
5075
|
const zcfConfig = readZcfConfig();
|
|
4840
|
-
|
|
5076
|
+
let codeToolType;
|
|
5077
|
+
try {
|
|
5078
|
+
codeToolType = await resolveCodeType(options.codeType);
|
|
5079
|
+
} catch (error) {
|
|
5080
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
5081
|
+
console.error(ansis.red(`${i18n.t("errors:generalError")} ${errorMessage}`));
|
|
5082
|
+
codeToolType = DEFAULT_CODE_TOOL_TYPE;
|
|
5083
|
+
}
|
|
4841
5084
|
options.codeType = codeToolType;
|
|
4842
5085
|
async function selectApiConfigurationMode() {
|
|
4843
5086
|
const { apiMode } = await inquirer.prompt({
|
|
@@ -4931,23 +5174,39 @@ async function init(options = {}) {
|
|
|
4931
5174
|
}
|
|
4932
5175
|
}
|
|
4933
5176
|
} else {
|
|
4934
|
-
if (!configLang
|
|
5177
|
+
if (!configLang) {
|
|
4935
5178
|
const { resolveTemplateLanguage } = await Promise.resolve().then(function () { return prompts; });
|
|
4936
5179
|
configLang = await resolveTemplateLanguage(
|
|
4937
5180
|
options.configLang,
|
|
4938
|
-
zcfConfig
|
|
5181
|
+
zcfConfig,
|
|
5182
|
+
options.skipPrompt
|
|
4939
5183
|
);
|
|
4940
|
-
} else if (!configLang && options.skipPrompt) {
|
|
4941
|
-
configLang = "en";
|
|
4942
5184
|
}
|
|
4943
5185
|
}
|
|
4944
5186
|
if (!configLang) {
|
|
4945
5187
|
configLang = "en";
|
|
4946
5188
|
}
|
|
4947
5189
|
if (codeToolType === "codex") {
|
|
5190
|
+
const apiMode = options.apiType === "auth_token" ? "official" : options.apiType === "api_key" ? "custom" : options.apiType === "skip" ? "skip" : options.skipPrompt ? "skip" : void 0;
|
|
5191
|
+
const customApiConfig = options.apiType === "api_key" && options.apiKey ? {
|
|
5192
|
+
type: "api_key",
|
|
5193
|
+
token: options.apiKey,
|
|
5194
|
+
baseUrl: options.apiUrl
|
|
5195
|
+
} : void 0;
|
|
5196
|
+
let selectedWorkflows;
|
|
5197
|
+
if (Array.isArray(options.workflows)) {
|
|
5198
|
+
selectedWorkflows = options.workflows;
|
|
5199
|
+
} else if (typeof options.workflows === "string") {
|
|
5200
|
+
selectedWorkflows = [options.workflows];
|
|
5201
|
+
} else if (options.workflows === true) {
|
|
5202
|
+
selectedWorkflows = [];
|
|
5203
|
+
}
|
|
4948
5204
|
const resolvedAiOutputLang = await runCodexFullInit({
|
|
4949
5205
|
aiOutputLang: options.aiOutputLang,
|
|
4950
|
-
skipPrompt: options.skipPrompt
|
|
5206
|
+
skipPrompt: options.skipPrompt,
|
|
5207
|
+
apiMode,
|
|
5208
|
+
customApiConfig,
|
|
5209
|
+
workflows: selectedWorkflows
|
|
4951
5210
|
});
|
|
4952
5211
|
updateZcfConfig({
|
|
4953
5212
|
version,
|
|
@@ -4961,7 +5220,7 @@ async function init(options = {}) {
|
|
|
4961
5220
|
console.log(ansis.green(i18n.t("codex:setupComplete")));
|
|
4962
5221
|
return;
|
|
4963
5222
|
}
|
|
4964
|
-
const aiOutputLang =
|
|
5223
|
+
const aiOutputLang = await resolveAiOutputLanguage(i18n.language, options.aiOutputLang, zcfConfig, options.skipPrompt);
|
|
4965
5224
|
const installationStatus = await getInstallationStatus();
|
|
4966
5225
|
if (installationStatus.hasGlobal || installationStatus.hasLocal) {
|
|
4967
5226
|
if (!options.skipPrompt) {
|
|
@@ -5363,4 +5622,4 @@ async function openSettingsJson() {
|
|
|
5363
5622
|
}
|
|
5364
5623
|
}
|
|
5365
5624
|
|
|
5366
|
-
export { removeLocalClaudeCode as $, AI_OUTPUT_LANGUAGES as A, ensureApiKeyApproved as B, CLAUDE_DIR as C, DEFAULT_CODE_TOOL_TYPE as D, removeApiKeyFromRejected as E, manageApiKeyApproval as F, setPrimaryApiKey as G, ensureClaudeDir as H, backupExistingConfig as I, copyConfigFiles as J, configureApi as K, LEGACY_ZCF_CONFIG_FILES as L, mergeConfigs as M, updateCustomModel as N, updateDefaultModel as O, mergeSettingsFile as P, getExistingModelConfig as Q, getExistingApiConfig as R, SETTINGS_FILE as S, applyAiLanguageDirective as T, switchToOfficialLogin$1 as U, promptApiConfigurationAction as V, isClaudeCodeInstalled as W, installClaudeCode as X, isLocalClaudeCodeInstalled as Y, ZCF_CONFIG_DIR as Z, getInstallationStatus as _, commandExists as a, i18n as a0, readCodexConfig as a1, backupCodexComplete as a2, writeCodexConfig as a3, writeAuthFile as a4, ensureI18nInitialized as a5, detectConfigManagementMode as a6, addNumbersToChoices as a7, readCcrConfig as a8, isCcrInstalled as a9,
|
|
5625
|
+
export { removeLocalClaudeCode as $, AI_OUTPUT_LANGUAGES as A, ensureApiKeyApproved as B, CLAUDE_DIR as C, DEFAULT_CODE_TOOL_TYPE as D, removeApiKeyFromRejected as E, manageApiKeyApproval as F, setPrimaryApiKey as G, ensureClaudeDir as H, backupExistingConfig as I, copyConfigFiles as J, configureApi as K, LEGACY_ZCF_CONFIG_FILES as L, mergeConfigs as M, updateCustomModel as N, updateDefaultModel as O, mergeSettingsFile as P, getExistingModelConfig as Q, getExistingApiConfig as R, SETTINGS_FILE as S, applyAiLanguageDirective as T, switchToOfficialLogin$1 as U, promptApiConfigurationAction as V, isClaudeCodeInstalled as W, installClaudeCode as X, isLocalClaudeCodeInstalled as Y, ZCF_CONFIG_DIR as Z, getInstallationStatus as _, commandExists as a, i18n as a0, readCodexConfig as a1, backupCodexComplete as a2, writeCodexConfig as a3, writeAuthFile as a4, ensureI18nInitialized as a5, detectConfigManagementMode as a6, addNumbersToChoices as a7, readCcrConfig as a8, isCcrInstalled as a9, updatePromptOnly as aA, selectAndInstallWorkflows as aB, checkClaudeCodeVersionAndPrompt as aC, displayBannerWithInfo as aD, runCodexUninstall as aE, configureCodexMcp as aF, configureCodexApi as aG, runCodexWorkflowImport as aH, runCodexFullInit as aI, listCodexProviders as aJ, getCurrentCodexProvider as aK, switchCodexProvider as aL, switchToOfficialLogin as aM, switchToProvider as aN, readZcfConfigAsync as aO, initI18n as aP, selectScriptLanguage as aQ, fsOperations as aR, prompts as aS, codex as aT, installCcr as aa, configureCcrFeature as ab, handleExitPromptError as ac, handleGeneralError as ad, updateZcfConfig as ae, changeLanguage as af, readZcfConfig as ag, configureOutputStyle as ah, isWindows as ai, selectMcpServices as aj, getMcpServices as ak, setupCcrConfiguration as al, modifyApiConfigPartially as am, validateApiKey as an, formatApiKeyDisplay as ao, COMETIX_COMMAND_NAME as ap, COMETIX_COMMANDS as aq, installCometixLine as ar, checkAndUpdateTools as as, runCodexUpdate as at, resolveCodeType as au, readJsonConfig as av, writeJsonConfig as aw, displayBanner as ax, version as ay, resolveAiOutputLanguage as az, importRecommendedEnv as b, 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, ZCF_CONFIG_FILE as j, CODE_TOOL_TYPES as k, CODE_TOOL_BANNERS as l, mergeAndCleanPermissions as m, isCodeToolType as n, openSettingsJson as o, SUPPORTED_LANGS as p, LANG_LABELS as q, getAiOutputLanguageLabel as r, getMcpConfigPath as s, readMcpConfig as t, backupMcpConfig as u, mergeMcpServers as v, writeMcpConfig as w, buildMcpServerConfig as x, fixWindowsMcpConfig as y, addCompletedOnboarding as z };
|