zcf 3.1.1 → 3.1.3
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.
|
@@ -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.3";
|
|
20
20
|
const homepage = "https://github.com/UfoMiao/zcf";
|
|
21
21
|
|
|
22
22
|
const i18n = i18next.createInstance();
|
|
@@ -542,6 +542,17 @@ function getMcpCommand() {
|
|
|
542
542
|
}
|
|
543
543
|
return ["npx"];
|
|
544
544
|
}
|
|
545
|
+
function getSystemRoot() {
|
|
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, "/");
|
|
555
|
+
}
|
|
545
556
|
async function commandExists(command) {
|
|
546
557
|
try {
|
|
547
558
|
const cmd = getPlatform() === "windows" ? "where" : "which";
|
|
@@ -2661,6 +2672,13 @@ function detectConfigManagementMode() {
|
|
|
2661
2672
|
}
|
|
2662
2673
|
}
|
|
2663
2674
|
|
|
2675
|
+
function applyCodexPlatformCommand(config) {
|
|
2676
|
+
if (config.command === "npx" && isWindows()) {
|
|
2677
|
+
const mcpCmd = getMcpCommand();
|
|
2678
|
+
config.command = mcpCmd[0];
|
|
2679
|
+
config.args = [...mcpCmd.slice(1), ...config.args || []];
|
|
2680
|
+
}
|
|
2681
|
+
}
|
|
2664
2682
|
const CODEX_DIR = join(homedir(), ".codex");
|
|
2665
2683
|
const CODEX_CONFIG_FILE = join(CODEX_DIR, "config.toml");
|
|
2666
2684
|
const CODEX_AUTH_FILE = join(CODEX_DIR, "auth.json");
|
|
@@ -2793,7 +2811,10 @@ function parseCodexConfig(content) {
|
|
|
2793
2811
|
};
|
|
2794
2812
|
}
|
|
2795
2813
|
try {
|
|
2796
|
-
const
|
|
2814
|
+
const normalizedContent = content.replace(/(SYSTEMROOT\s*=\s*")[^"\n]+("?)/g, (match) => {
|
|
2815
|
+
return match.replace(/\\\\/g, "/").replace(/\\/g, "/").replace('C:/Windows"?', 'C:/Windows"');
|
|
2816
|
+
});
|
|
2817
|
+
const tomlData = parse(normalizedContent);
|
|
2797
2818
|
const providers = [];
|
|
2798
2819
|
if (tomlData.model_providers) {
|
|
2799
2820
|
for (const [id, providerData] of Object.entries(tomlData.model_providers)) {
|
|
@@ -2862,21 +2883,30 @@ function parseCodexConfig(content) {
|
|
|
2862
2883
|
const otherConfig = [];
|
|
2863
2884
|
const lines = content.split("\n");
|
|
2864
2885
|
let skipCurrentSection = false;
|
|
2865
|
-
let currentSection = "";
|
|
2866
2886
|
for (const line of lines) {
|
|
2867
|
-
const
|
|
2868
|
-
if (
|
|
2887
|
+
const trimmed = line.trim();
|
|
2888
|
+
if (!trimmed)
|
|
2869
2889
|
continue;
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
if (
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2890
|
+
if (/^#\s*---\s*model provider added by ZCF\s*---\s*$/i.test(trimmed))
|
|
2891
|
+
continue;
|
|
2892
|
+
if (/^#\s*---\s*MCP servers added by ZCF\s*---\s*$/i.test(trimmed))
|
|
2893
|
+
continue;
|
|
2894
|
+
if (/Managed by ZCF/i.test(trimmed))
|
|
2895
|
+
continue;
|
|
2896
|
+
const sec = trimmed.match(/^\[([^\]]+)\]/);
|
|
2897
|
+
if (sec) {
|
|
2898
|
+
const name = sec[1];
|
|
2899
|
+
skipCurrentSection = name.startsWith("model_providers.") || name.startsWith("mcp_servers.");
|
|
2900
|
+
if (skipCurrentSection)
|
|
2901
|
+
continue;
|
|
2902
|
+
otherConfig.push(line);
|
|
2877
2903
|
continue;
|
|
2878
2904
|
}
|
|
2879
|
-
if (
|
|
2905
|
+
if (/^#?\s*model_provider\s*=/.test(trimmed))
|
|
2906
|
+
continue;
|
|
2907
|
+
if (/^model\s*=/.test(trimmed))
|
|
2908
|
+
continue;
|
|
2909
|
+
if (!skipCurrentSection) {
|
|
2880
2910
|
otherConfig.push(line);
|
|
2881
2911
|
}
|
|
2882
2912
|
}
|
|
@@ -2892,13 +2922,15 @@ function parseCodexConfig(content) {
|
|
|
2892
2922
|
};
|
|
2893
2923
|
} catch (error) {
|
|
2894
2924
|
console.warn("TOML parsing failed, falling back to basic parsing:", error);
|
|
2925
|
+
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");
|
|
2926
|
+
const otherConfig = cleaned.split("\n").map((l) => l.replace(/\s+$/g, "")).filter((l) => l.trim().length > 0);
|
|
2895
2927
|
return {
|
|
2896
2928
|
model: null,
|
|
2897
2929
|
modelProvider: null,
|
|
2898
2930
|
providers: [],
|
|
2899
2931
|
mcpServices: [],
|
|
2900
2932
|
managed: false,
|
|
2901
|
-
otherConfig
|
|
2933
|
+
otherConfig,
|
|
2902
2934
|
modelProviderCommented: void 0
|
|
2903
2935
|
};
|
|
2904
2936
|
}
|
|
@@ -2927,9 +2959,29 @@ function renderCodexConfig(data) {
|
|
|
2927
2959
|
lines.push("");
|
|
2928
2960
|
}
|
|
2929
2961
|
if (data.otherConfig && data.otherConfig.length > 0) {
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2962
|
+
const preserved = data.otherConfig.filter((raw) => {
|
|
2963
|
+
const l = String(raw).trim();
|
|
2964
|
+
if (!l)
|
|
2965
|
+
return false;
|
|
2966
|
+
if (/^#\s*---\s*model provider added by ZCF\s*---\s*$/i.test(l))
|
|
2967
|
+
return false;
|
|
2968
|
+
if (/^#\s*---\s*MCP servers added by ZCF\s*---\s*$/i.test(l))
|
|
2969
|
+
return false;
|
|
2970
|
+
if (/^\[\s*mcp_servers\./i.test(l))
|
|
2971
|
+
return false;
|
|
2972
|
+
if (/^\[\s*model_providers\./i.test(l))
|
|
2973
|
+
return false;
|
|
2974
|
+
if (/^#?\s*model_provider\s*=/.test(l))
|
|
2975
|
+
return false;
|
|
2976
|
+
if (/^\s*model\s*=/.test(l))
|
|
2977
|
+
return false;
|
|
2978
|
+
return true;
|
|
2979
|
+
});
|
|
2980
|
+
if (preserved.length > 0) {
|
|
2981
|
+
lines.push(...preserved);
|
|
2982
|
+
if (data.providers.length > 0 || data.mcpServices.length > 0) {
|
|
2983
|
+
lines.push("");
|
|
2984
|
+
}
|
|
2933
2985
|
}
|
|
2934
2986
|
}
|
|
2935
2987
|
if (data.providers.length > 0) {
|
|
@@ -3438,14 +3490,29 @@ async function configureCodexMcp() {
|
|
|
3438
3490
|
const servicesMeta = await getMcpServices();
|
|
3439
3491
|
const baseProviders = existingConfig?.providers || [];
|
|
3440
3492
|
const selection = [];
|
|
3441
|
-
const
|
|
3493
|
+
const existingServices = existingConfig?.mcpServices || [];
|
|
3442
3494
|
if (selectedIds.length === 0) {
|
|
3443
3495
|
console.log(ansis.yellow(i18n.t("codex:noMcpConfigured")));
|
|
3496
|
+
const preserved = (existingServices || []).map((svc) => {
|
|
3497
|
+
if (isWindows()) {
|
|
3498
|
+
const systemRoot = getSystemRoot();
|
|
3499
|
+
if (systemRoot) {
|
|
3500
|
+
return {
|
|
3501
|
+
...svc,
|
|
3502
|
+
env: {
|
|
3503
|
+
...svc.env || {},
|
|
3504
|
+
SYSTEMROOT: systemRoot
|
|
3505
|
+
}
|
|
3506
|
+
};
|
|
3507
|
+
}
|
|
3508
|
+
}
|
|
3509
|
+
return svc;
|
|
3510
|
+
});
|
|
3444
3511
|
writeCodexConfig({
|
|
3445
3512
|
model: existingConfig?.model || null,
|
|
3446
3513
|
modelProvider: existingConfig?.modelProvider || null,
|
|
3447
3514
|
providers: baseProviders,
|
|
3448
|
-
mcpServices:
|
|
3515
|
+
mcpServices: preserved,
|
|
3449
3516
|
otherConfig: existingConfig?.otherConfig || []
|
|
3450
3517
|
});
|
|
3451
3518
|
updateZcfConfig({ codeToolType: "codex" });
|
|
@@ -3457,10 +3524,18 @@ async function configureCodexMcp() {
|
|
|
3457
3524
|
continue;
|
|
3458
3525
|
const serviceMeta = servicesMeta.find((service) => service.id === id);
|
|
3459
3526
|
let command = configInfo.config.command || id;
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3527
|
+
let args = (configInfo.config.args || []).map((arg) => String(arg));
|
|
3528
|
+
const serviceConfig = { id: id.toLowerCase(), command, args };
|
|
3529
|
+
applyCodexPlatformCommand(serviceConfig);
|
|
3530
|
+
command = serviceConfig.command;
|
|
3531
|
+
args = serviceConfig.args || [];
|
|
3463
3532
|
const env = { ...configInfo.config.env || {} };
|
|
3533
|
+
if (isWindows()) {
|
|
3534
|
+
const systemRoot = getSystemRoot();
|
|
3535
|
+
if (systemRoot) {
|
|
3536
|
+
env.SYSTEMROOT = systemRoot;
|
|
3537
|
+
}
|
|
3538
|
+
}
|
|
3464
3539
|
if (configInfo.requiresApiKey && configInfo.apiKeyEnvVar) {
|
|
3465
3540
|
const promptMessage = serviceMeta?.apiKeyPrompt || i18n.t("mcp:apiKeyPrompt");
|
|
3466
3541
|
const { apiKey } = await inquirer.prompt([{
|
|
@@ -3476,21 +3551,39 @@ async function configureCodexMcp() {
|
|
|
3476
3551
|
selection.push({
|
|
3477
3552
|
id: id.toLowerCase(),
|
|
3478
3553
|
// Convert to lowercase for Codex compatibility
|
|
3479
|
-
command,
|
|
3480
|
-
args,
|
|
3554
|
+
command: serviceConfig.command,
|
|
3555
|
+
args: serviceConfig.args,
|
|
3481
3556
|
env: Object.keys(env).length > 0 ? env : void 0,
|
|
3482
3557
|
startup_timeout_ms: configInfo.config.startup_timeout_ms
|
|
3483
3558
|
});
|
|
3484
3559
|
}
|
|
3485
|
-
const
|
|
3486
|
-
const
|
|
3487
|
-
|
|
3488
|
-
|
|
3560
|
+
const mergedMap = /* @__PURE__ */ new Map();
|
|
3561
|
+
for (const svc of existingServices) {
|
|
3562
|
+
mergedMap.set(svc.id.toLowerCase(), { ...svc });
|
|
3563
|
+
}
|
|
3564
|
+
for (const svc of selection) {
|
|
3565
|
+
mergedMap.set(svc.id.toLowerCase(), { ...svc });
|
|
3566
|
+
}
|
|
3567
|
+
const finalServices = Array.from(mergedMap.values()).map((svc) => {
|
|
3568
|
+
if (isWindows()) {
|
|
3569
|
+
const systemRoot = getSystemRoot();
|
|
3570
|
+
if (systemRoot) {
|
|
3571
|
+
return {
|
|
3572
|
+
...svc,
|
|
3573
|
+
env: {
|
|
3574
|
+
...svc.env || {},
|
|
3575
|
+
SYSTEMROOT: systemRoot
|
|
3576
|
+
}
|
|
3577
|
+
};
|
|
3578
|
+
}
|
|
3579
|
+
}
|
|
3580
|
+
return svc;
|
|
3581
|
+
});
|
|
3489
3582
|
writeCodexConfig({
|
|
3490
3583
|
model: existingConfig?.model || null,
|
|
3491
3584
|
modelProvider: existingConfig?.modelProvider || null,
|
|
3492
3585
|
providers: baseProviders,
|
|
3493
|
-
mcpServices:
|
|
3586
|
+
mcpServices: finalServices,
|
|
3494
3587
|
otherConfig: existingConfig?.otherConfig || []
|
|
3495
3588
|
});
|
|
3496
3589
|
updateZcfConfig({ codeToolType: "codex" });
|
package/package.json
CHANGED
|
@@ -10,17 +10,19 @@
|
|
|
10
10
|
"permissions": {
|
|
11
11
|
"allow": [
|
|
12
12
|
"Bash",
|
|
13
|
-
"
|
|
14
|
-
"Write",
|
|
13
|
+
"BashOutput",
|
|
15
14
|
"Edit",
|
|
16
|
-
"MultiEdit",
|
|
17
15
|
"Glob",
|
|
18
16
|
"Grep",
|
|
17
|
+
"KillShell",
|
|
18
|
+
"NotebookEdit",
|
|
19
|
+
"Read",
|
|
20
|
+
"SlashCommand",
|
|
21
|
+
"Task",
|
|
22
|
+
"TodoWrite",
|
|
19
23
|
"WebFetch",
|
|
20
24
|
"WebSearch",
|
|
21
|
-
"
|
|
22
|
-
"NotebookRead",
|
|
23
|
-
"NotebookEdit",
|
|
25
|
+
"Write",
|
|
24
26
|
"mcp__ide",
|
|
25
27
|
"mcp__exa",
|
|
26
28
|
"mcp__context7",
|