zcf 3.1.2 → 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.2";
19
+ const version = "3.1.3";
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
- const systemRoot = process.env.SYSTEMROOT || process.env.SystemRoot || "C:Windows";
548
- return systemRoot.replace(/\\/g, "\\\\");
549
- }
550
- return null;
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 {
@@ -2807,7 +2811,10 @@ function parseCodexConfig(content) {
2807
2811
  };
2808
2812
  }
2809
2813
  try {
2810
- const tomlData = parse(content);
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);
2811
2818
  const providers = [];
2812
2819
  if (tomlData.model_providers) {
2813
2820
  for (const [id, providerData] of Object.entries(tomlData.model_providers)) {
@@ -2876,21 +2883,30 @@ function parseCodexConfig(content) {
2876
2883
  const otherConfig = [];
2877
2884
  const lines = content.split("\n");
2878
2885
  let skipCurrentSection = false;
2879
- let currentSection = "";
2880
2886
  for (const line of lines) {
2881
- const trimmedLine = line.trim();
2882
- if (trimmedLine.includes("--- model provider added by ZCF ---") || trimmedLine.includes("--- MCP servers added by ZCF ---") || trimmedLine.includes("Managed by ZCF")) {
2887
+ const trimmed = line.trim();
2888
+ if (!trimmed)
2883
2889
  continue;
2884
- }
2885
- const sectionMatch = trimmedLine.match(/^\[([^\]]+)\]/);
2886
- if (sectionMatch) {
2887
- currentSection = sectionMatch[1];
2888
- skipCurrentSection = currentSection.startsWith("model_providers.") || currentSection.startsWith("mcp_servers.");
2889
- }
2890
- if (!skipCurrentSection && (trimmedLine.startsWith("model_provider") || trimmedLine.startsWith("# model_provider") || /^model\s*=/.test(trimmedLine))) {
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);
2891
2903
  continue;
2892
2904
  }
2893
- if (!skipCurrentSection && trimmedLine) {
2905
+ if (/^#?\s*model_provider\s*=/.test(trimmed))
2906
+ continue;
2907
+ if (/^model\s*=/.test(trimmed))
2908
+ continue;
2909
+ if (!skipCurrentSection) {
2894
2910
  otherConfig.push(line);
2895
2911
  }
2896
2912
  }
@@ -2906,13 +2922,15 @@ function parseCodexConfig(content) {
2906
2922
  };
2907
2923
  } catch (error) {
2908
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);
2909
2927
  return {
2910
2928
  model: null,
2911
2929
  modelProvider: null,
2912
2930
  providers: [],
2913
2931
  mcpServices: [],
2914
2932
  managed: false,
2915
- otherConfig: content.split("\n"),
2933
+ otherConfig,
2916
2934
  modelProviderCommented: void 0
2917
2935
  };
2918
2936
  }
@@ -2941,9 +2959,29 @@ function renderCodexConfig(data) {
2941
2959
  lines.push("");
2942
2960
  }
2943
2961
  if (data.otherConfig && data.otherConfig.length > 0) {
2944
- lines.push(...data.otherConfig);
2945
- if (data.providers.length > 0 || data.mcpServices.length > 0) {
2946
- lines.push("");
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
+ }
2947
2985
  }
2948
2986
  }
2949
2987
  if (data.providers.length > 0) {
@@ -3452,14 +3490,29 @@ async function configureCodexMcp() {
3452
3490
  const servicesMeta = await getMcpServices();
3453
3491
  const baseProviders = existingConfig?.providers || [];
3454
3492
  const selection = [];
3455
- const existingMap = new Map((existingConfig?.mcpServices || []).map((service) => [service.id, service]));
3493
+ const existingServices = existingConfig?.mcpServices || [];
3456
3494
  if (selectedIds.length === 0) {
3457
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
+ });
3458
3511
  writeCodexConfig({
3459
3512
  model: existingConfig?.model || null,
3460
3513
  modelProvider: existingConfig?.modelProvider || null,
3461
3514
  providers: baseProviders,
3462
- mcpServices: Array.from(existingMap.values()),
3515
+ mcpServices: preserved,
3463
3516
  otherConfig: existingConfig?.otherConfig || []
3464
3517
  });
3465
3518
  updateZcfConfig({ codeToolType: "codex" });
@@ -3504,15 +3557,33 @@ async function configureCodexMcp() {
3504
3557
  startup_timeout_ms: configInfo.config.startup_timeout_ms
3505
3558
  });
3506
3559
  }
3507
- const selectionMap = new Map(selection.map((service) => [service.id, service]));
3508
- const mergedMap = new Map(existingMap);
3509
- for (const service of selectionMap.values())
3510
- mergedMap.set(service.id, service);
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
+ });
3511
3582
  writeCodexConfig({
3512
3583
  model: existingConfig?.model || null,
3513
3584
  modelProvider: existingConfig?.modelProvider || null,
3514
3585
  providers: baseProviders,
3515
- mcpServices: Array.from(mergedMap.values()),
3586
+ mcpServices: finalServices,
3516
3587
  otherConfig: existingConfig?.otherConfig || []
3517
3588
  });
3518
3589
  updateZcfConfig({ codeToolType: "codex" });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "zcf",
3
3
  "type": "module",
4
- "version": "3.1.2",
4
+ "version": "3.1.3",
5
5
  "description": "Zero-Config Code Flow - One-click configuration tool for Claude Code",
6
6
  "author": {
7
7
  "name": "Miao Da",
@@ -10,17 +10,19 @@
10
10
  "permissions": {
11
11
  "allow": [
12
12
  "Bash",
13
- "Read",
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
- "TodoWrite",
22
- "NotebookRead",
23
- "NotebookEdit",
25
+ "Write",
24
26
  "mcp__ide",
25
27
  "mcp__exa",
26
28
  "mcp__context7",