frizz 0.9.0 → 0.10.0

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.
Files changed (96) hide show
  1. package/dist/claude-agent-broker.js +141 -12
  2. package/dist/dev-child.js +869 -333
  3. package/dist/frizz.js +81 -19
  4. package/package.json +1 -1
  5. package/runtime/cc-worker/DECISIONS.md +11 -0
  6. package/runtime/cc-worker/bin/frizz-mcp.mjs +58 -24
  7. package/web-dist/assets/{TerminalPane-CNFymHXK.js → TerminalPane-XNji7D_c.js} +1 -1
  8. package/web-dist/assets/{abnfDiagram-VRR7QNED-DNBrcJfV.js → abnfDiagram-VRR7QNED-gPeb-B7g.js} +1 -1
  9. package/web-dist/assets/architecture-TIHT7OUA-BsgSgexh.js +1 -0
  10. package/web-dist/assets/{architectureDiagram-ZJ3FMSHR-SXVydqly.js → architectureDiagram-ZJ3FMSHR-DV69ktbl.js} +1 -1
  11. package/web-dist/assets/{blockDiagram-677ZJIJ3-CgI1GSdx.js → blockDiagram-677ZJIJ3-D8vw5eim.js} +1 -1
  12. package/web-dist/assets/{c4Diagram-LMCZKHZV-KDmJm2tG.js → c4Diagram-LMCZKHZV--9PLGn-L.js} +1 -1
  13. package/web-dist/assets/channel-ClLnncxh.js +1 -0
  14. package/web-dist/assets/{chunk-32BRIVSS-j3eOjq4Z.js → chunk-32BRIVSS-D4BSk0FZ.js} +1 -1
  15. package/web-dist/assets/{chunk-52WLFC77-DZHfa78H.js → chunk-52WLFC77-WNcmTkcR.js} +1 -1
  16. package/web-dist/assets/{chunk-C7G6YPKG-CiB5uo24.js → chunk-C7G6YPKG-BDlcLa5W.js} +1 -1
  17. package/web-dist/assets/{chunk-EX3LRPZG-B35Inyjz.js → chunk-EX3LRPZG-CFnqFt7s.js} +1 -1
  18. package/web-dist/assets/{chunk-FWX5IMBZ-D2sRvM5U.js → chunk-FWX5IMBZ-Ci9LgOOg.js} +2 -2
  19. package/web-dist/assets/{chunk-HOUHSVGY-D247PDv6.js → chunk-HOUHSVGY-BTD_X5OP.js} +1 -1
  20. package/web-dist/assets/{chunk-ICXQ74PX-Bu3Tb6Ec.js → chunk-ICXQ74PX-D2Y3Ys5K.js} +1 -1
  21. package/web-dist/assets/{chunk-MOJQB5TN-C_lQy4on.js → chunk-MOJQB5TN-C-GDt7vC.js} +1 -1
  22. package/web-dist/assets/{chunk-OGEWGWER-DU5ZBedR.js → chunk-OGEWGWER-DvnPoUnz.js} +1 -1
  23. package/web-dist/assets/{chunk-PUDLZKDR-DWRT7ztS.js → chunk-PUDLZKDR-C3AymM-j.js} +1 -1
  24. package/web-dist/assets/{chunk-Q4XR5HBZ-CCX4AK_n.js → chunk-Q4XR5HBZ-DmyBNAl6.js} +1 -1
  25. package/web-dist/assets/{chunk-V7JOEXUC-VbixbkDG.js → chunk-V7JOEXUC-DTuPUeRa.js} +1 -1
  26. package/web-dist/assets/{chunk-VAUOI2AC-PJvChxMA.js → chunk-VAUOI2AC-CcW8PviB.js} +1 -1
  27. package/web-dist/assets/{chunk-VR4S4FIN-BjsMfxj8.js → chunk-VR4S4FIN-0tm6n83G.js} +1 -1
  28. package/web-dist/assets/{chunk-WYO6CB5R-Bcb97r3w.js → chunk-WYO6CB5R-CH3ADqeI.js} +1 -1
  29. package/web-dist/assets/{chunk-ZGVPDNZ5-CT2sZlhT.js → chunk-ZGVPDNZ5-BHFnlpXH.js} +1 -1
  30. package/web-dist/assets/classDiagram-OUVF2IWQ-CwLnPgud.js +1 -0
  31. package/web-dist/assets/classDiagram-v2-EOCWNBFH-CwLnPgud.js +1 -0
  32. package/web-dist/assets/{cynefin-VYW2F7L2-dUpO4u0w.js → cynefin-VYW2F7L2-DtFCLOIN.js} +1 -1
  33. package/web-dist/assets/{cynefinDiagram-TSTJHNR4-BQZ3UIsx.js → cynefinDiagram-TSTJHNR4-llFTHp2q.js} +1 -1
  34. package/web-dist/assets/{dagre-VKFMJZFB-K-oO8w51.js → dagre-VKFMJZFB-CvBRVl_k.js} +1 -1
  35. package/web-dist/assets/{diagram-FQU43EPY-Cr47GJ_S.js → diagram-FQU43EPY-D1QXo6ri.js} +1 -1
  36. package/web-dist/assets/{diagram-G47NLZAW-BbWzSkoZ.js → diagram-G47NLZAW-2pZew-Bk.js} +1 -1
  37. package/web-dist/assets/{diagram-NH7WQ7WH-BGJJBgGM.js → diagram-NH7WQ7WH-Ch9JRwGN.js} +1 -1
  38. package/web-dist/assets/{diagram-OA4YK3LP-2W7aunEN.js → diagram-OA4YK3LP-BIbrLf02.js} +1 -1
  39. package/web-dist/assets/{diagram-WEI45ONY-D-4ITFI6.js → diagram-WEI45ONY-D3KtL2s-.js} +1 -1
  40. package/web-dist/assets/{ebnfDiagram-CCIWWBDH-CxUcx103.js → ebnfDiagram-CCIWWBDH-D829sKG_.js} +1 -1
  41. package/web-dist/assets/{erDiagram-Q63AITRT-Cf_5SWAE.js → erDiagram-Q63AITRT-Cj3Grovg.js} +1 -1
  42. package/web-dist/assets/eventmodeling-45OFAUF4-CzZyv3HA.js +1 -0
  43. package/web-dist/assets/flowDiagram-23GEKE2U-rQ7PRoGL.js +1 -0
  44. package/web-dist/assets/{ganttDiagram-NO4QXBWP-CVZI8Ywa.js → ganttDiagram-NO4QXBWP-CGHaXF-g.js} +1 -1
  45. package/web-dist/assets/{gitGraph-TEB2WS4Q-BsiGpR9l.js → gitGraph-TEB2WS4Q-BbxeaotX.js} +1 -1
  46. package/web-dist/assets/{gitGraphDiagram-IHSO6WYX-DVym_4l1.js → gitGraphDiagram-IHSO6WYX-C4WHE0cI.js} +1 -1
  47. package/web-dist/assets/index-BpCFdr7Z.css +1 -0
  48. package/web-dist/assets/index-CiaKj-0V.js +506 -0
  49. package/web-dist/assets/{info-DKCQHKI2-DYcsKFv-.js → info-DKCQHKI2-3fKpn7Qr.js} +1 -1
  50. package/web-dist/assets/{infoDiagram-FWYZ7A6U-hjVxlrTT.js → infoDiagram-FWYZ7A6U-CDQl4JMv.js} +1 -1
  51. package/web-dist/assets/{ishikawaDiagram-FXEZZL3T-B0DKOPSS.js → ishikawaDiagram-FXEZZL3T-CDKjMW-u.js} +1 -1
  52. package/web-dist/assets/{journeyDiagram-5HDEW3XC-Cohibc5O.js → journeyDiagram-5HDEW3XC-BOsabu1Z.js} +1 -1
  53. package/web-dist/assets/{kanban-definition-HUTT4EX6-_6Zr31vM.js → kanban-definition-HUTT4EX6-KTuh-6eN.js} +1 -1
  54. package/web-dist/assets/{line-B14EZI6M.js → line-KaxbYSN3.js} +1 -1
  55. package/web-dist/assets/{mermaid-parser.core-DHkc6cqw.js → mermaid-parser.core-B53huyyd.js} +3 -3
  56. package/web-dist/assets/{mermaid.core-DuTvdsKf.js → mermaid.core-Bz6B5ouC.js} +3 -3
  57. package/web-dist/assets/{mindmap-definition-LN4V7U3C-DPRF9pW2.js → mindmap-definition-LN4V7U3C-Bb7T7B3a.js} +1 -1
  58. package/web-dist/assets/{packet-7NZHBO7P-Ci8oCcGM.js → packet-7NZHBO7P-w3lynC8r.js} +1 -1
  59. package/web-dist/assets/{pegDiagram-2B236MQR-Cr3ctC6e.js → pegDiagram-2B236MQR-nQ7c2Z03.js} +1 -1
  60. package/web-dist/assets/{pie-RZYD4A2V-EHgA307y.js → pie-RZYD4A2V-B3Yko5Wb.js} +1 -1
  61. package/web-dist/assets/{pieDiagram-ENE6RG2P-UW6Bmu6F.js → pieDiagram-ENE6RG2P-CN4Lp5HG.js} +1 -1
  62. package/web-dist/assets/{quadrantDiagram-ABIIQ3AL-D6tAsRj9.js → quadrantDiagram-ABIIQ3AL-3QTB92dH.js} +1 -1
  63. package/web-dist/assets/{radar-I7S5WNFK-CAQqojcd.js → radar-I7S5WNFK-8ZsXt0FI.js} +1 -1
  64. package/web-dist/assets/{railroad-3IZDKUUU-BZsAOTrm.js → railroad-3IZDKUUU-C4IKxzEZ.js} +1 -1
  65. package/web-dist/assets/railroad-abnf-AHOZXSZD-g2si5iUv.js +1 -0
  66. package/web-dist/assets/railroad-ebnf-EBAXGLYW-BikkLG6y.js +1 -0
  67. package/web-dist/assets/railroad-peg-LSFZ7HO6-Dv4rDehz.js +1 -0
  68. package/web-dist/assets/{railroadDiagram-RFXS5EU6-bSpff55H.js → railroadDiagram-RFXS5EU6-DrGnmjpD.js} +1 -1
  69. package/web-dist/assets/{requirementDiagram-TGXJPOKE-DIAYvXoB.js → requirementDiagram-TGXJPOKE-Bh9XNuxa.js} +1 -1
  70. package/web-dist/assets/{sankeyDiagram-HTMAVEWB-DEnsSz3F.js → sankeyDiagram-HTMAVEWB-CXy3ra5-.js} +1 -1
  71. package/web-dist/assets/{sequenceDiagram-DBY2YBRQ-DsG7eb9R.js → sequenceDiagram-DBY2YBRQ-B7ESCT52.js} +1 -1
  72. package/web-dist/assets/{stateDiagram-2N3HPSRC-DT3XNwjo.js → stateDiagram-2N3HPSRC-DFr9k5Xv.js} +1 -1
  73. package/web-dist/assets/stateDiagram-v2-6OUMAXLB-BQUd0MEa.js +1 -0
  74. package/web-dist/assets/{swimlanes-5IMT3BWC-B5hZwgRo.js → swimlanes-5IMT3BWC-B2RKoz1q.js} +1 -1
  75. package/web-dist/assets/swimlanesDiagram-G3AALYLV-GWn4zXxj.js +8 -0
  76. package/web-dist/assets/{timeline-definition-FHXFAJF6-BVTsjkfu.js → timeline-definition-FHXFAJF6-KpTqaG5g.js} +1 -1
  77. package/web-dist/assets/{treeView-QDETBFTQ-M6HmP4bB.js → treeView-QDETBFTQ-oB1a6ikv.js} +1 -1
  78. package/web-dist/assets/{treemap-6X3UGDF4-C60TppfC.js → treemap-6X3UGDF4-DO8OvvZg.js} +1 -1
  79. package/web-dist/assets/{vennDiagram-L72KCM5P-Dv1y3g4S.js → vennDiagram-L72KCM5P-BgTjK4_q.js} +1 -1
  80. package/web-dist/assets/{wardley-OPB4EBWU-D0lMJMWt.js → wardley-OPB4EBWU-CGyjn939.js} +1 -1
  81. package/web-dist/assets/{wardleyDiagram-EHGQE667-B1E5NtZY.js → wardleyDiagram-EHGQE667-CM_HxruS.js} +1 -1
  82. package/web-dist/assets/{xychartDiagram-FW5EYKEG-oA91YOvh.js → xychartDiagram-FW5EYKEG-vamHu0jN.js} +1 -1
  83. package/web-dist/index.html +2 -2
  84. package/web-dist/assets/architecture-TIHT7OUA-BSUDKbro.js +0 -1
  85. package/web-dist/assets/channel-DaCOnTxr.js +0 -1
  86. package/web-dist/assets/classDiagram-OUVF2IWQ-BlylbZXV.js +0 -1
  87. package/web-dist/assets/classDiagram-v2-EOCWNBFH-BlylbZXV.js +0 -1
  88. package/web-dist/assets/eventmodeling-45OFAUF4-DxKQnZNV.js +0 -1
  89. package/web-dist/assets/flowDiagram-23GEKE2U-Cdz9YM2Z.js +0 -1
  90. package/web-dist/assets/index-CYzJK7u0.js +0 -497
  91. package/web-dist/assets/index-CovJDCWc.css +0 -1
  92. package/web-dist/assets/railroad-abnf-AHOZXSZD-_2rSHfPz.js +0 -1
  93. package/web-dist/assets/railroad-ebnf-EBAXGLYW-xM3eAMFz.js +0 -1
  94. package/web-dist/assets/railroad-peg-LSFZ7HO6-cZlBUsED.js +0 -1
  95. package/web-dist/assets/stateDiagram-v2-6OUMAXLB-C06v0Ltu.js +0 -1
  96. package/web-dist/assets/swimlanesDiagram-G3AALYLV-CXyN7ZyO.js +0 -8
@@ -2,7 +2,7 @@ import { createRequire as __frizzCreateRequire } from "node:module"; const requi
2
2
 
3
3
  // packages/server/src/backend/claude-agent-broker.ts
4
4
  import net from "node:net";
5
- import { readFileSync as readFileSync3, realpathSync as realpathSync2, unlinkSync as unlinkSync2, writeFileSync } from "node:fs";
5
+ import { readFileSync as readFileSync4, realpathSync as realpathSync2, unlinkSync as unlinkSync2, writeFileSync } from "node:fs";
6
6
  import { randomUUID } from "node:crypto";
7
7
  import { fileURLToPath } from "node:url";
8
8
 
@@ -20714,10 +20714,12 @@ function startClaudeQuery(executablePath, options) {
20714
20714
  // broker session gets the frizz sub-agent profiles + hooks, mount the frizz MCP server, and
20715
20715
  // pre-approve it. EMPTY is skipped, not passed: since frizz stopped mounting a browser (2026-08-26)
20716
20716
  // a resolved-nothing worker env is a real state, and `{}`/`[]` are truthy — handing the SDK an
20717
- // empty allowlist is not the same as handing it none. The project's own `.mcp.json` servers are
20718
- // loaded by settingSources, independently of this.
20717
+ // empty allowlist is not the same as handing it none. The project's own `.mcp.json` servers arrive
20718
+ // INSIDE `mcpServers` the broker daemon merges them (project-mcp-servers.ts) — because
20719
+ // `strictMcpConfig` stops the CLI discovering any MCP scope by itself.
20719
20720
  ...options.pluginDir ? { plugins: [{ type: "local", path: options.pluginDir }] } : {},
20720
20721
  ...options.mcpServers && Object.keys(options.mcpServers).length > 0 ? { mcpServers: options.mcpServers } : {},
20722
+ ...options.strictMcpConfig ? { strictMcpConfig: true } : {},
20721
20723
  ...options.allowedTools?.length ? { allowedTools: options.allowedTools } : {},
20722
20724
  ...options.disallowedTools?.length ? { disallowedTools: [...options.disallowedTools] } : {},
20723
20725
  persistSession: options.persistSession ?? false,
@@ -21502,6 +21504,130 @@ function objectValue(value, label) {
21502
21504
  return value;
21503
21505
  }
21504
21506
 
21507
+ // packages/server/src/backend/project-mcp-servers.ts
21508
+ import { readFileSync as readFileSync2 } from "node:fs";
21509
+ import { homedir } from "node:os";
21510
+ import { join } from "node:path";
21511
+ function readJsonObject(path) {
21512
+ try {
21513
+ const parsed = JSON.parse(readFileSync2(path, "utf8"));
21514
+ return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
21515
+ } catch {
21516
+ return void 0;
21517
+ }
21518
+ }
21519
+ function objectField(source, key) {
21520
+ const value = source?.[key];
21521
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
21522
+ }
21523
+ function stringList(source, key) {
21524
+ const value = source?.[key];
21525
+ return Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : [];
21526
+ }
21527
+ function stringMap(value) {
21528
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return void 0;
21529
+ const out = {};
21530
+ for (const [key, entry] of Object.entries(value)) {
21531
+ if (typeof entry === "string") out[key] = entry;
21532
+ }
21533
+ return out;
21534
+ }
21535
+ var ENV_REF = /\$\{([A-Za-z_][A-Za-z0-9_]*)(?::-([^}]*))?\}/g;
21536
+ function expandMcpEnvRefs(value, env) {
21537
+ let unresolved = false;
21538
+ const out = value.replace(ENV_REF, (_match, name, fallback) => {
21539
+ const resolved = env[name];
21540
+ if (resolved !== void 0) return resolved;
21541
+ if (fallback !== void 0) return fallback;
21542
+ unresolved = true;
21543
+ return "";
21544
+ });
21545
+ return unresolved ? void 0 : out;
21546
+ }
21547
+ function expandMap(map, env) {
21548
+ if (!map) return void 0;
21549
+ const out = {};
21550
+ for (const [key, value] of Object.entries(map)) {
21551
+ const expanded = expandMcpEnvRefs(value, env);
21552
+ if (expanded === void 0) return null;
21553
+ out[key] = expanded;
21554
+ }
21555
+ return out;
21556
+ }
21557
+ function normalizeMcpServer(raw, env) {
21558
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return void 0;
21559
+ const record = raw;
21560
+ const type = typeof record.type === "string" ? record.type : void 0;
21561
+ if (type === "http" || type === "sse") {
21562
+ if (typeof record.url !== "string") return void 0;
21563
+ const url = expandMcpEnvRefs(record.url, env);
21564
+ const headers = expandMap(stringMap(record.headers), env);
21565
+ if (url === void 0 || headers === null) return void 0;
21566
+ return { type, url, ...headers ? { headers } : {} };
21567
+ }
21568
+ if (type !== void 0 && type !== "stdio") return void 0;
21569
+ if (typeof record.command !== "string") return void 0;
21570
+ const command = expandMcpEnvRefs(record.command, env);
21571
+ if (command === void 0) return void 0;
21572
+ const args = [];
21573
+ for (const entry of Array.isArray(record.args) ? record.args : []) {
21574
+ if (typeof entry !== "string") return void 0;
21575
+ const expanded = expandMcpEnvRefs(entry, env);
21576
+ if (expanded === void 0) return void 0;
21577
+ args.push(expanded);
21578
+ }
21579
+ const serverEnv = expandMap(stringMap(record.env), env);
21580
+ if (serverEnv === null) return void 0;
21581
+ return { command, ...args.length ? { args } : {}, ...serverEnv ? { env: serverEnv } : {} };
21582
+ }
21583
+ function collectApproval(layers) {
21584
+ const approval = { all: false, enabled: /* @__PURE__ */ new Set(), disabled: /* @__PURE__ */ new Set() };
21585
+ for (const layer of layers) {
21586
+ if (layer?.enableAllProjectMcpServers === true) approval.all = true;
21587
+ for (const name of stringList(layer, "enabledMcpjsonServers")) approval.enabled.add(name);
21588
+ for (const name of stringList(layer, "disabledMcpjsonServers")) approval.disabled.add(name);
21589
+ }
21590
+ return approval;
21591
+ }
21592
+ function userScopeRemoteServers(account, cwd, env) {
21593
+ const out = {};
21594
+ const maps = [objectField(account, "mcpServers"), objectField(objectField(objectField(account, "projects"), cwd), "mcpServers")];
21595
+ for (const map of maps) {
21596
+ for (const [name, raw] of Object.entries(map ?? {})) {
21597
+ const server = normalizeMcpServer(raw, env);
21598
+ if (server && server.type !== void 0 && server.type !== "stdio") out[name] = server;
21599
+ }
21600
+ }
21601
+ return out;
21602
+ }
21603
+ function projectMcpServers(cwd, options = {}) {
21604
+ const env = options.env ?? process.env;
21605
+ const home = options.home ?? homedir();
21606
+ const configOverride = options.claudeConfigDir ?? (env.CLAUDE_CONFIG_DIR?.trim() ? env.CLAUDE_CONFIG_DIR.trim() : void 0);
21607
+ const accountFile = configOverride ? join(configOverride, ".claude.json") : join(home, ".claude.json");
21608
+ const userSettingsFile = join(configOverride ?? join(home, ".claude"), "settings.json");
21609
+ const account = readJsonObject(accountFile);
21610
+ const out = userScopeRemoteServers(account, cwd, env);
21611
+ const declared = objectField(readJsonObject(join(cwd, ".mcp.json")), "mcpServers");
21612
+ if (!declared) return out;
21613
+ const approval = collectApproval([
21614
+ readJsonObject(join(cwd, ".claude", "settings.json")),
21615
+ readJsonObject(join(cwd, ".claude", "settings.local.json")),
21616
+ readJsonObject(userSettingsFile),
21617
+ objectField(objectField(account, "projects"), cwd)
21618
+ ]);
21619
+ for (const [name, raw] of Object.entries(declared)) {
21620
+ if (approval.disabled.has(name)) continue;
21621
+ if (!approval.all && !approval.enabled.has(name)) continue;
21622
+ const server = normalizeMcpServer(raw, env);
21623
+ if (server) out[name] = server;
21624
+ }
21625
+ return out;
21626
+ }
21627
+ function workerMcpServers(project, frizz) {
21628
+ return { ...project ?? {}, ...frizz ?? {} };
21629
+ }
21630
+
21505
21631
  // packages/server/src/backend/types.ts
21506
21632
  var CLAUDE_WORKER_ENV = {
21507
21633
  CLAUDE_CODE_TOTAL_TOKENS_REMINDER: "infinite",
@@ -21517,12 +21643,12 @@ function claudeCompactionWindowOf(env) {
21517
21643
  }
21518
21644
 
21519
21645
  // packages/server/src/backend/claude-broker-diagnostics.ts
21520
- import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, renameSync as renameSync2, statSync as statSync2 } from "node:fs";
21521
- import { join } from "node:path";
21646
+ import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync3, renameSync as renameSync2, statSync as statSync2 } from "node:fs";
21647
+ import { join as join2 } from "node:path";
21522
21648
  var MAX_BYTES = 4 * 1024 * 1024;
21523
21649
  function appendRecord(path, record) {
21524
21650
  try {
21525
- mkdirSync2(join(path, ".."), { recursive: true });
21651
+ mkdirSync2(join2(path, ".."), { recursive: true });
21526
21652
  try {
21527
21653
  if (statSync2(path).size > MAX_BYTES) renameSync2(path, `${path}.1`);
21528
21654
  } catch {
@@ -21584,21 +21710,24 @@ function runClaudeBroker(config) {
21584
21710
  const writeDiagnostic = config.diagnosticLogPath ? createClaudeBrokerDiagnosticWriter(config.diagnosticLogPath, { daemonPid: process.pid, generation }) : void 0;
21585
21711
  const writeExit = config.diagnosticLogPath ? createClaudeBrokerExitWriter(config.diagnosticLogPath, { daemonPid: process.pid, generation }) : void 0;
21586
21712
  const factory = createClaudeQueryFactory({ enabled: true, executablePath: config.executablePath });
21713
+ const env = { ...inheritWorkerEnvironment(config.env), ...config.workerEnv ?? {} };
21587
21714
  const handle = factory.start({
21588
21715
  cwd: config.cwd,
21589
21716
  session: config.resume ? { kind: "resume", sessionId: config.sessionId } : { kind: "new", sessionId: config.sessionId },
21590
21717
  permissionMode: config.permissionMode ?? "default",
21591
- // The worker inherits frizz's environment minus frizz's own control plane (see worker-env.ts). The
21592
- // frizz worker vars it DOES need (FRIZZ_THREAD, FRIZZ_PERM_DIR) ride workerEnv and are merged on
21593
- // top — which is also what gives them THIS thread's values instead of the server's.
21594
- env: { ...inheritWorkerEnvironment(config.env), ...config.workerEnv ?? {} },
21718
+ env,
21595
21719
  persistSession: true,
21596
21720
  // write the tailer-readable transcript JSONL
21597
21721
  appendSystemPrompt: config.appendSystemPrompt,
21598
21722
  model: config.model,
21599
21723
  effort: config.effort,
21600
21724
  pluginDir: config.pluginDir,
21601
- mcpServers: config.mcpServers,
21725
+ // The WHOLE MCP surface of this thread, and STRICT so the CLI discovers nothing else: the project's
21726
+ // approved `.mcp.json` (and the operator's remote user-scope servers) under the frizz mount, which
21727
+ // wins a name collision. Read at every fork, not once per project, so a `.mcp.json` edit reaches the
21728
+ // next dispatch the way it reaches the next plain `claude`. project-mcp-servers.ts has the reasons.
21729
+ mcpServers: workerMcpServers(projectMcpServers(config.cwd, { env }), config.mcpServers),
21730
+ strictMcpConfig: true,
21602
21731
  allowedTools: config.allowedTools,
21603
21732
  // NO `disallowedTools` here, and the asymmetry with the argv path (WORKER_DISALLOWED_TOOLS →
21604
21733
  // `--disallowedTools=AskUserQuestion`) is DELIBERATE. That flag exists because a worker launched as
@@ -21760,7 +21889,7 @@ function runClaudeBroker(config) {
21760
21889
  const recordOwner = () => {
21761
21890
  if (!config.recordPath) return null;
21762
21891
  try {
21763
- return JSON.parse(readFileSync3(config.recordPath, "utf8")).daemonPid;
21892
+ return JSON.parse(readFileSync4(config.recordPath, "utf8")).daemonPid;
21764
21893
  } catch {
21765
21894
  return null;
21766
21895
  }