frizz-server 0.15.15 → 0.15.16

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 (99) hide show
  1. package/dist/dev-child.js +237 -103
  2. package/package.json +1 -1
  3. package/runtime/cc-worker/bin/frizz-mcp.mjs +1 -1
  4. package/web-dist/assets/{abnfDiagram-VRR7QNED-DhfveBnK.js → abnfDiagram-VRR7QNED-DjpPWj1n.js} +1 -1
  5. package/web-dist/assets/{arc-CyAhw_PT.js → arc-GGQPeqIn.js} +1 -1
  6. package/web-dist/assets/architecture-TIHT7OUA-qF4uSd6w.js +1 -0
  7. package/web-dist/assets/{architectureDiagram-ZJ3FMSHR-DwWGlWWh.js → architectureDiagram-ZJ3FMSHR-i9N18wLs.js} +1 -1
  8. package/web-dist/assets/{blockDiagram-677ZJIJ3-DaZjGZtu.js → blockDiagram-677ZJIJ3-CIc5kmW3.js} +1 -1
  9. package/web-dist/assets/{c4Diagram-LMCZKHZV-BRMup1j9.js → c4Diagram-LMCZKHZV-DjUgY_rv.js} +1 -1
  10. package/web-dist/assets/channel-KKo0nJfj.js +1 -0
  11. package/web-dist/assets/{chunk-32BRIVSS-DQwcDwtE.js → chunk-32BRIVSS-DdVPbS2L.js} +1 -1
  12. package/web-dist/assets/{chunk-52WLFC77-CgGBFwno.js → chunk-52WLFC77-k-avutEL.js} +1 -1
  13. package/web-dist/assets/{chunk-C7G6YPKG-CuxheuT5.js → chunk-C7G6YPKG-jMdA6WRB.js} +1 -1
  14. package/web-dist/assets/{chunk-EX3LRPZG-BUJla0kp.js → chunk-EX3LRPZG-DPQFUeFc.js} +1 -1
  15. package/web-dist/assets/{chunk-FWX5IMBZ-B0zpcsgr.js → chunk-FWX5IMBZ-CnOUb3RH.js} +2 -2
  16. package/web-dist/assets/{chunk-HOUHSVGY-Rmt15rW3.js → chunk-HOUHSVGY-YdnK1w2S.js} +1 -1
  17. package/web-dist/assets/{chunk-ICXQ74PX-DhfK6S2X.js → chunk-ICXQ74PX-hdfmNc2d.js} +1 -1
  18. package/web-dist/assets/{chunk-MOJQB5TN-DPeso190.js → chunk-MOJQB5TN-CsGFUAEU.js} +1 -1
  19. package/web-dist/assets/{chunk-OGEWGWER-Dnxu3oeq.js → chunk-OGEWGWER-CzQY8gM0.js} +1 -1
  20. package/web-dist/assets/{chunk-PUDLZKDR-JzuUO3j2.js → chunk-PUDLZKDR-CquKZy9Z.js} +1 -1
  21. package/web-dist/assets/{chunk-Q4XR5HBZ-CM6ZXGkW.js → chunk-Q4XR5HBZ-C_1V073n.js} +1 -1
  22. package/web-dist/assets/{chunk-RYQCIY6F--6BdDOKZ.js → chunk-RYQCIY6F-B2Y6QBP5.js} +1 -1
  23. package/web-dist/assets/{chunk-V7JOEXUC-Dq3E-pJp.js → chunk-V7JOEXUC-_NMzZcnP.js} +1 -1
  24. package/web-dist/assets/{chunk-VAUOI2AC-Cd8PGNlH.js → chunk-VAUOI2AC-D8ojVgWd.js} +1 -1
  25. package/web-dist/assets/{chunk-VR4S4FIN-dwYLlPtI.js → chunk-VR4S4FIN-CgTzyBot.js} +1 -1
  26. package/web-dist/assets/{chunk-WYO6CB5R-CycRCrJb.js → chunk-WYO6CB5R-D0qL-eZe.js} +1 -1
  27. package/web-dist/assets/{chunk-XXDRQBXY-BHkd_B7T.js → chunk-XXDRQBXY-CqoZQ1Er.js} +1 -1
  28. package/web-dist/assets/{chunk-ZGVPDNZ5-w1E_2-n0.js → chunk-ZGVPDNZ5-CY3MtA1p.js} +1 -1
  29. package/web-dist/assets/classDiagram-OUVF2IWQ-B4WEPxqA.js +1 -0
  30. package/web-dist/assets/classDiagram-v2-EOCWNBFH-B4WEPxqA.js +1 -0
  31. package/web-dist/assets/{cose-bilkent-JH36ORCC-DT58QUJH.js → cose-bilkent-JH36ORCC-CdwbTfJj.js} +1 -1
  32. package/web-dist/assets/{cynefin-VYW2F7L2-DJBWvYfG.js → cynefin-VYW2F7L2-CpVXg7NY.js} +1 -1
  33. package/web-dist/assets/{cynefinDiagram-TSTJHNR4-BgZsBMC5.js → cynefinDiagram-TSTJHNR4-Bq8xdMaL.js} +1 -1
  34. package/web-dist/assets/{dagre-VKFMJZFB-BsUdprP7.js → dagre-VKFMJZFB-3LmR7haE.js} +1 -1
  35. package/web-dist/assets/{diagram-FQU43EPY-AYwXc4ap.js → diagram-FQU43EPY-Bl3VhSKJ.js} +1 -1
  36. package/web-dist/assets/{diagram-G47NLZAW--4o6VVV_.js → diagram-G47NLZAW-Dx8wicI9.js} +1 -1
  37. package/web-dist/assets/{diagram-NH7WQ7WH-B0_Gu4SY.js → diagram-NH7WQ7WH-D-ac7oKf.js} +1 -1
  38. package/web-dist/assets/{diagram-OA4YK3LP-DIdSWxbC.js → diagram-OA4YK3LP-C3n9muDh.js} +1 -1
  39. package/web-dist/assets/{diagram-WEI45ONY-ZggLbvMN.js → diagram-WEI45ONY-zhWZ_XKT.js} +1 -1
  40. package/web-dist/assets/{dist-Bx4dBZZj.js → dist-C2WuhXSR.js} +1 -1
  41. package/web-dist/assets/{ebnfDiagram-CCIWWBDH-D4mwPGRz.js → ebnfDiagram-CCIWWBDH-BYXQgDLw.js} +1 -1
  42. package/web-dist/assets/{erDiagram-Q63AITRT-BdVxVYVS.js → erDiagram-Q63AITRT-DSTBG9Mp.js} +1 -1
  43. package/web-dist/assets/eventmodeling-45OFAUF4-Dfi1SiqN.js +1 -0
  44. package/web-dist/assets/flowDiagram-23GEKE2U-DrZ_4EiE.js +1 -0
  45. package/web-dist/assets/{ganttDiagram-NO4QXBWP-1ch3s-Lp.js → ganttDiagram-NO4QXBWP-C9RStO67.js} +1 -1
  46. package/web-dist/assets/{gitGraph-TEB2WS4Q-OYci86fv.js → gitGraph-TEB2WS4Q-JFtHkb0B.js} +1 -1
  47. package/web-dist/assets/{gitGraphDiagram-IHSO6WYX-C0vyzUeM.js → gitGraphDiagram-IHSO6WYX-uVA8Zt2w.js} +1 -1
  48. package/web-dist/assets/index-DdA4AFB7.js +334 -0
  49. package/web-dist/assets/index-J1N8yjnp.css +2 -0
  50. package/web-dist/assets/{info-DKCQHKI2-Di5Jz1rS.js → info-DKCQHKI2-hrkiQZrg.js} +1 -1
  51. package/web-dist/assets/{infoDiagram-FWYZ7A6U-CFb6Kd3F.js → infoDiagram-FWYZ7A6U-BhdOdJlu.js} +1 -1
  52. package/web-dist/assets/{ishikawaDiagram-FXEZZL3T-DcfyEKeu.js → ishikawaDiagram-FXEZZL3T-zdLsCb3B.js} +1 -1
  53. package/web-dist/assets/{journeyDiagram-5HDEW3XC-DKXBMkLI.js → journeyDiagram-5HDEW3XC-C_2hQwBD.js} +1 -1
  54. package/web-dist/assets/{kanban-definition-HUTT4EX6-B369XB3j.js → kanban-definition-HUTT4EX6-o0jEXUku.js} +1 -1
  55. package/web-dist/assets/{line-CHcvip-O.js → line-BI9UTuIR.js} +1 -1
  56. package/web-dist/assets/{linear-DQNyozJe.js → linear-Rr0EbNoq.js} +1 -1
  57. package/web-dist/assets/{mermaid-parser.core-BjxGpEg5.js → mermaid-parser.core-yhmLALkv.js} +3 -3
  58. package/web-dist/assets/{mermaid.core-DrLahovt.js → mermaid.core-BRyxVBzn.js} +3 -3
  59. package/web-dist/assets/{mindmap-definition-LN4V7U3C-MZ52F91o.js → mindmap-definition-LN4V7U3C-BA9ji-1w.js} +1 -1
  60. package/web-dist/assets/{packet-7NZHBO7P-CjyAw65k.js → packet-7NZHBO7P-DBhL0KIK.js} +1 -1
  61. package/web-dist/assets/{pegDiagram-2B236MQR-DLWhOQnL.js → pegDiagram-2B236MQR-CPxXVeZH.js} +1 -1
  62. package/web-dist/assets/{pie-RZYD4A2V-Bo059ddI.js → pie-RZYD4A2V-ByCiaDbD.js} +1 -1
  63. package/web-dist/assets/{pieDiagram-ENE6RG2P-Bn4xh59c.js → pieDiagram-ENE6RG2P-Bw8GvNiv.js} +1 -1
  64. package/web-dist/assets/{quadrantDiagram-ABIIQ3AL-yL39XUy5.js → quadrantDiagram-ABIIQ3AL-CwL8u1x5.js} +1 -1
  65. package/web-dist/assets/{radar-I7S5WNFK-Ck7WdZik.js → radar-I7S5WNFK-Ds0-Pw3X.js} +1 -1
  66. package/web-dist/assets/{railroad-3IZDKUUU-iyRvRPSM.js → railroad-3IZDKUUU-xwnxXT5n.js} +1 -1
  67. package/web-dist/assets/railroad-abnf-AHOZXSZD-BMLoaNxy.js +1 -0
  68. package/web-dist/assets/railroad-ebnf-EBAXGLYW-BRk3kvdr.js +1 -0
  69. package/web-dist/assets/railroad-peg-LSFZ7HO6-h9Wo00HF.js +1 -0
  70. package/web-dist/assets/{railroadDiagram-RFXS5EU6-BxVsxOmr.js → railroadDiagram-RFXS5EU6-B1rEgDrn.js} +1 -1
  71. package/web-dist/assets/{requirementDiagram-TGXJPOKE-D66pmX1H.js → requirementDiagram-TGXJPOKE-CdLF-_L5.js} +1 -1
  72. package/web-dist/assets/{sankeyDiagram-HTMAVEWB-BvgsAMO2.js → sankeyDiagram-HTMAVEWB-DTmdqI7H.js} +1 -1
  73. package/web-dist/assets/{sequenceDiagram-DBY2YBRQ-BhNfNIv2.js → sequenceDiagram-DBY2YBRQ-CKtz0A1H.js} +1 -1
  74. package/web-dist/assets/{src-CjLI2OlU.js → src-BqbE4HyW.js} +1 -1
  75. package/web-dist/assets/{stateDiagram-2N3HPSRC-vnAKWHvS.js → stateDiagram-2N3HPSRC-GYGYAkK2.js} +1 -1
  76. package/web-dist/assets/stateDiagram-v2-6OUMAXLB-BmiBzOjo.js +1 -0
  77. package/web-dist/assets/{swimlanes-5IMT3BWC-CB-Yj_fF.js → swimlanes-5IMT3BWC-DAi3tBaQ.js} +1 -1
  78. package/web-dist/assets/swimlanesDiagram-G3AALYLV-BvIghLXt.js +8 -0
  79. package/web-dist/assets/{timeline-definition-FHXFAJF6-CvLWFhRF.js → timeline-definition-FHXFAJF6-O4KNojxn.js} +1 -1
  80. package/web-dist/assets/{treeView-QDETBFTQ-BDE_I1pO.js → treeView-QDETBFTQ-BbAhfX9e.js} +1 -1
  81. package/web-dist/assets/{treemap-6X3UGDF4-FQ6gU3Zd.js → treemap-6X3UGDF4-D3XVXTNg.js} +1 -1
  82. package/web-dist/assets/{vennDiagram-L72KCM5P-BVrnKEXl.js → vennDiagram-L72KCM5P-BjsVc4st.js} +1 -1
  83. package/web-dist/assets/{wardley-OPB4EBWU-BXDzR7qq.js → wardley-OPB4EBWU-CcWQmwG4.js} +1 -1
  84. package/web-dist/assets/{wardleyDiagram-EHGQE667-DbUiehJp.js → wardleyDiagram-EHGQE667-Cz-aojN7.js} +1 -1
  85. package/web-dist/assets/{xychartDiagram-FW5EYKEG-BTwgjd1B.js → xychartDiagram-FW5EYKEG-CASxN8z7.js} +1 -1
  86. package/web-dist/index.html +2 -2
  87. package/web-dist/assets/architecture-TIHT7OUA-C1SxnjA-.js +0 -1
  88. package/web-dist/assets/channel-BF49lwbq.js +0 -1
  89. package/web-dist/assets/classDiagram-OUVF2IWQ-CBnpuahb.js +0 -1
  90. package/web-dist/assets/classDiagram-v2-EOCWNBFH-CBnpuahb.js +0 -1
  91. package/web-dist/assets/eventmodeling-45OFAUF4-DmV5Ki1T.js +0 -1
  92. package/web-dist/assets/flowDiagram-23GEKE2U-BIo9OVTK.js +0 -1
  93. package/web-dist/assets/index-DDIB2iVX.js +0 -330
  94. package/web-dist/assets/index-DcU5Cvjj.css +0 -2
  95. package/web-dist/assets/railroad-abnf-AHOZXSZD-CbUyyZcZ.js +0 -1
  96. package/web-dist/assets/railroad-ebnf-EBAXGLYW-Cw1S-tc2.js +0 -1
  97. package/web-dist/assets/railroad-peg-LSFZ7HO6-BEpXiF80.js +0 -1
  98. package/web-dist/assets/stateDiagram-v2-6OUMAXLB-D-SWO5VU.js +0 -1
  99. package/web-dist/assets/swimlanesDiagram-G3AALYLV-PjEPG6SC.js +0 -8
package/dist/dev-child.js CHANGED
@@ -12957,6 +12957,68 @@ var init_drainable_worker = __esm({
12957
12957
  }
12958
12958
  });
12959
12959
 
12960
+ // packages/shared/src/frizz-md.ts
12961
+ function landingRule(landing, branch) {
12962
+ const b = `\`${branch}\``;
12963
+ switch (landing) {
12964
+ case "pull-request":
12965
+ return `Never commit directly to ${b}. Put each change on its own branch, push it, and open a pull request against ${b}. Never merge a pull request yourself: a human reviews and merges it. Your work is not finished until the pull request is open with its checks passing.`;
12966
+ case "main":
12967
+ return `Commit finished work directly to the local ${b} branch. Do not open pull requests, and do not push to the remote: a human pushes. Commit at each coherent checkpoint, and always commit completed work before you stop.`;
12968
+ case "main-push":
12969
+ return `Commit finished work directly to ${b} and push it to the remote. Do not open pull requests. Run the project's checks before every push, and never force-push.`;
12970
+ case "branch":
12971
+ return `Never commit directly to ${b}, and do not push to the remote. Commit each change to its own local branch and say which branch in your write-up: a human reviews and merges it.`;
12972
+ }
12973
+ }
12974
+ function autonomyRule(autonomy) {
12975
+ switch (autonomy) {
12976
+ case "decide":
12977
+ return "Decide and proceed. Make every reversible call yourself \u2014 names, defaults, error messages, which of two equivalent designs \u2014 and say in your write-up which way you went. Ask only before something destructive or irreversible, an external-facing action, or a product decision that is genuinely the human's to make.";
12978
+ case "balanced":
12979
+ return "Make routine implementation calls yourself and say which way you went. Ask before a significant design choice, a change of scope, or anything destructive or irreversible.";
12980
+ case "check-in":
12981
+ return "Check in before acting. Confirm your plan with the human before you write substantial code, and ask about any decision the task does not make obvious.";
12982
+ }
12983
+ }
12984
+ function composeFrizzMd(answers, defaultBranch2) {
12985
+ const sections = [
12986
+ "# Frizz worker norms",
12987
+ "Frizz adds this file to the system prompt of every agent it starts in this project. No other coding-agent session reads it: Claude Code, Codex or any other agent you start yourself is unaffected. Edit it freely; the next agent Frizz starts reads the new version.",
12988
+ "## Landing changes",
12989
+ landingRule(answers.landing, defaultBranch2),
12990
+ "## Working independently",
12991
+ autonomyRule(answers.autonomy)
12992
+ ];
12993
+ const notes = answers.notes.trim();
12994
+ if (notes) sections.push("## Project notes", notes);
12995
+ return `${sections.join("\n\n")}
12996
+ `;
12997
+ }
12998
+ var FrizzMdLanding, FrizzMdAutonomy, FRIZZ_MD_NOTES_MAX, FrizzMdAnswers, FrizzMdStatus;
12999
+ var init_frizz_md = __esm({
13000
+ "packages/shared/src/frizz-md.ts"() {
13001
+ "use strict";
13002
+ init_zod();
13003
+ FrizzMdLanding = external_exports.enum(["pull-request", "main", "main-push", "branch"]);
13004
+ FrizzMdAutonomy = external_exports.enum(["decide", "balanced", "check-in"]);
13005
+ FRIZZ_MD_NOTES_MAX = 8e3;
13006
+ FrizzMdAnswers = external_exports.object({
13007
+ landing: FrizzMdLanding,
13008
+ autonomy: FrizzMdAutonomy,
13009
+ notes: external_exports.string().max(FRIZZ_MD_NOTES_MAX)
13010
+ }).strict();
13011
+ FrizzMdStatus = external_exports.object({
13012
+ /** A FRIZZ.md is already at the project root: the project has its rules, so nothing is asked. */
13013
+ exists: external_exports.boolean(),
13014
+ /** The operator skipped the questionnaire for this project: it is not asked again. */
13015
+ skipped: external_exports.boolean(),
13016
+ /** The branch the landing rules name — the remote's default, else the checked-out one, else `main`. */
13017
+ defaultBranch: external_exports.string()
13018
+ });
13019
+ }
13020
+ });
13021
+
12960
13022
  // packages/shared/src/receipt-bus.ts
12961
13023
  var init_receipt_bus = __esm({
12962
13024
  "packages/shared/src/receipt-bus.ts"() {
@@ -13679,7 +13741,7 @@ function signoffNudgeText(needsInput) {
13679
13741
  "",
13680
13742
  "**STILL OWED counts things you are not going to do yourself.** A decision you are RECOMMENDING, a",
13681
13743
  "draft you wrote but did not send, follow-up work you discovered \u2014 all of it dies with the card, even",
13682
- "the part that is someone else's to do. Each ends on a question with your recommendation as option A,",
13744
+ "the part that is someone else's to do. Each ends on a question with your recommendation as option 1,",
13683
13745
  "or you DO it first \u2014 a sub-agent's result comes BACK to you, so it lands on your card; a new card via",
13684
13746
  "`mcp__frizz__spawn_thread` is the LAST resort, since nothing it learns returns to you or its siblings.",
13685
13747
  "None of them is a `done`. And what is not",
@@ -14069,6 +14131,7 @@ var init_src = __esm({
14069
14131
  init_code_fences();
14070
14132
  init_delta();
14071
14133
  init_drainable_worker();
14134
+ init_frizz_md();
14072
14135
  init_interactions();
14073
14136
  init_receipt_bus();
14074
14137
  init_relay_protocol();
@@ -14733,8 +14796,8 @@ var init_src = __esm({
14733
14796
  danger: external_exports.boolean().optional(),
14734
14797
  // UNBOUNDED, deliberately. This carried `.max(8)` from launch until 2026-09-03, when the maintainer
14735
14798
  // asked for the cap to go ("allow arbitrary numbers of options"): a `multi` over a long list — which
14736
- // gates to run, which of twenty findings to act on — is a real shape, and the card letters past 26
14737
- // (`AA.`) already. The count is the worker's to choose; the answer's `chosen` is unbounded to match.
14799
+ // gates to run, which of twenty findings to act on — is a real shape, and the card numbers past 9
14800
+ // (only 1–9 are keys) already. The count is the worker's to choose; the answer's `chosen` is unbounded to match.
14738
14801
  options: external_exports.array(AskedOptionSchema).optional()
14739
14802
  }).strict());
14740
14803
  AskInput = external_exports.object({
@@ -17032,9 +17095,9 @@ function resolveProjectIdentity(dir, home = homedir5()) {
17032
17095
  throw new Error("unable to inspect Git repository identity");
17033
17096
  }
17034
17097
  }
17035
- const git2 = insideWorktree ? resolveGitProjectIdentity(dir, home) : void 0;
17036
- const root = git2?.root ?? dir;
17037
- return { id: ensureProjectIdFile(root, home, git2?.id), scope: git2?.scope ?? "repository", root };
17098
+ const git3 = insideWorktree ? resolveGitProjectIdentity(dir, home) : void 0;
17099
+ const root = git3?.root ?? dir;
17100
+ return { id: ensureProjectIdFile(root, home, git3?.id), scope: git3?.scope ?? "repository", root };
17038
17101
  }
17039
17102
  function cwdSlug(absPath) {
17040
17103
  const slug = absPath.replace(/[^A-Za-z0-9]/g, "-");
@@ -27512,19 +27575,19 @@ function searchPath2(env) {
27512
27575
  function vendoredNativeBeside(launcherJs, arch, access) {
27513
27576
  const triple = WINDOWS_TRIPLE[arch];
27514
27577
  if (!triple) return void 0;
27515
- const { dirname: dirname27, join: join50 } = win322;
27578
+ const { dirname: dirname27, join: join51 } = win322;
27516
27579
  const pkgRoot = dirname27(dirname27(launcherJs));
27517
27580
  const platformPkg = `codex-win32-${arch}`;
27518
27581
  const vendorRoots = [
27519
- join50(pkgRoot, "node_modules", "@openai", platformPkg, "vendor"),
27582
+ join51(pkgRoot, "node_modules", "@openai", platformPkg, "vendor"),
27520
27583
  // nested under the package
27521
- join50(dirname27(pkgRoot), platformPkg, "vendor"),
27584
+ join51(dirname27(pkgRoot), platformPkg, "vendor"),
27522
27585
  // hoisted beside it: <prefix>\node_modules\@openai\<pkg>
27523
- join50(pkgRoot, "vendor")
27586
+ join51(pkgRoot, "vendor")
27524
27587
  // the pre-platform-package layout, binaries inside @openai/codex itself
27525
27588
  ];
27526
27589
  for (const root of vendorRoots) {
27527
- const exe2 = join50(root, triple, "bin", "codex.exe");
27590
+ const exe2 = join51(root, triple, "bin", "codex.exe");
27528
27591
  if (access(exe2, "exists")) return exe2;
27529
27592
  }
27530
27593
  return void 0;
@@ -37138,7 +37201,7 @@ exactly ONE of them.
37138
37201
  - **A RECOMMENDATION IS NOT A CONCLUSION, AND AN UNSENT DRAFT IS NOT A DELIVERABLE.** When the
37139
37202
  verdict is that SOMEONE SHOULD NOW DO SOMETHING \u2014 merge it, decline it, post this comment, pick
37140
37203
  one of these designs, press the button you are not allowed to press \u2014 that someone is the human,
37141
- so register the question with \`mcp__frizz__ask\`, your recommendation as option A, and rest on
37204
+ so register the question with \`mcp__frizz__ask\`, your recommendation as option 1, and rest on
37142
37205
  it. Once nothing is left to DECIDE and only the human's act remains, the steps go to them under
37143
37206
  \`steps:\` in an \` \`\`\`awaiting \` fence instead. Same for anything you WROTE
37144
37207
  but did not SEND (a drafted comment, reply, issue body or release note): \`done\` files that draft
@@ -37453,10 +37516,11 @@ so, which?" without asking it of somebody who said no. Written out, one registra
37453
37516
  description: zero deps, human-editable, racy under concurrent writes
37454
37517
 
37455
37518
  Each question must stand alone: the specific question on ONE line, options each with a one-line
37456
- trade-off, and enough context to answer cold. The card letters the options A, B, C in the order you
37457
- give them, so put the one you would take FIRST and mark it \`recommended\`; mark exactly one. Several
37458
- independent questions are several entries of ONE \`ask\` call, never one bundled question. A bare
37459
- "which approach?" with no options is a broken handoff.
37519
+ trade-off, and enough context to answer cold. The card numbers the options 1, 2, 3 in the order you
37520
+ give them \u2014 the human picks one by pressing its number \u2014 so put the one you would take FIRST and mark
37521
+ it \`recommended\`; mark exactly one. Several independent questions are several entries of ONE
37522
+ \`ask\` call, never one bundled question. A bare "which approach?" with no options is a broken
37523
+ handoff.
37460
37524
 
37461
37525
  NO "I" AND NO "you" ANYWHERE IN A QUESTION \u2014 the question, its options, or any interactive prompt.
37462
37526
  Clicking an option is the HUMAN speaking, so first and second person flip between writer and reader: in
@@ -37564,7 +37628,7 @@ and reported, not offered. Only the ACT behind a command can earn a card (destru
37564
37628
  outside your boundary), and then the question is whether the thing happens, never who types it.
37565
37629
 
37566
37630
  **That test inverts when knowing the answer and being ABLE TO ACT ON IT come apart** \u2014 a read-only
37567
- boundary, a comment that goes out under the human's name, a merge, a close, a publish, a spend. It becomes the QUESTION, with the recommendation as option A and the act spelled out concretely
37631
+ boundary, a comment that goes out under the human's name, a merge, a close, a publish, a spend. It becomes the QUESTION, with the recommendation as option 1 and the act spelled out concretely
37568
37632
  enough to approve in one word. Never resolve that fork by fencing \` \`\`\`done \` on the investigation.
37569
37633
 
37570
37634
  Stop only when a wrong guess would be BOTH costly AND hard to undo: destructive or irreversible actions
@@ -78957,6 +79021,55 @@ var init_background_shell_output = __esm({
78957
79021
  }
78958
79022
  });
78959
79023
 
79024
+ // packages/server/src/frizz-md.ts
79025
+ import { execFileSync as execFileSync5 } from "node:child_process";
79026
+ import { existsSync as existsSync18, writeFileSync as writeFileSync14 } from "node:fs";
79027
+ import { join as join40 } from "node:path";
79028
+ function frizzMdPath(projectDir) {
79029
+ return join40(projectDir, "FRIZZ.md");
79030
+ }
79031
+ function git2(args, cwd) {
79032
+ try {
79033
+ return execFileSync5("git", args, { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: 5e3 }).trim() || null;
79034
+ } catch {
79035
+ return null;
79036
+ }
79037
+ }
79038
+ function defaultBranch(projectDir) {
79039
+ const remote = git2(["symbolic-ref", "--quiet", "--short", "refs/remotes/origin/HEAD"], projectDir);
79040
+ if (remote?.startsWith("origin/")) return remote.slice("origin/".length);
79041
+ const current = git2(["symbolic-ref", "--quiet", "--short", "HEAD"], projectDir);
79042
+ return current ?? "main";
79043
+ }
79044
+ function frizzMdStatus(projectDir, storage) {
79045
+ return {
79046
+ exists: existsSync18(frizzMdPath(projectDir)),
79047
+ skipped: storage.getSetting(SKIP_SETTING) !== void 0,
79048
+ defaultBranch: defaultBranch(projectDir)
79049
+ };
79050
+ }
79051
+ function createFrizzMd(projectDir, answers) {
79052
+ const path3 = frizzMdPath(projectDir);
79053
+ try {
79054
+ writeFileSync14(path3, composeFrizzMd(answers, defaultBranch(projectDir)), { encoding: "utf8", flag: "wx" });
79055
+ } catch (error) {
79056
+ if (error.code === "EEXIST") throw new Error("This project already has a FRIZZ.md.");
79057
+ throw error;
79058
+ }
79059
+ return { path: path3 };
79060
+ }
79061
+ function skipFrizzMd(storage, now = /* @__PURE__ */ new Date()) {
79062
+ storage.setSetting(SKIP_SETTING, { at: now.toISOString() });
79063
+ }
79064
+ var SKIP_SETTING;
79065
+ var init_frizz_md2 = __esm({
79066
+ "packages/server/src/frizz-md.ts"() {
79067
+ "use strict";
79068
+ init_src();
79069
+ SKIP_SETTING = "frizzMd.onboarding.skipped.v1";
79070
+ }
79071
+ });
79072
+
78960
79073
  // packages/server/src/image-header.ts
78961
79074
  import { closeSync as closeSync16, openSync as openSync17, readSync as readSync10, statSync as statSync18 } from "node:fs";
78962
79075
  import { extname } from "node:path";
@@ -79342,10 +79455,10 @@ function run(argv) {
79342
79455
 
79343
79456
  // packages/server/src/router.ts
79344
79457
  import { readFileSync as readFileSync28, statSync as statSync19 } from "node:fs";
79345
- import { join as join40, resolve as resolve10 } from "node:path";
79458
+ import { join as join41, resolve as resolve10 } from "node:path";
79346
79459
  import { randomUUID as randomUUID17 } from "node:crypto";
79347
79460
  import { basename as basename9, dirname as dirname18 } from "node:path";
79348
- import { existsSync as existsSync18, mkdirSync as mkdirSync20, rmSync as rmSync11, writeFileSync as writeFileSync14 } from "node:fs";
79461
+ import { existsSync as existsSync19, mkdirSync as mkdirSync20, rmSync as rmSync11, writeFileSync as writeFileSync15 } from "node:fs";
79349
79462
  import { homedir as homedir17 } from "node:os";
79350
79463
  function validateGithubDispatchProfile(input, codexModels) {
79351
79464
  if (input.backend === "acp") return;
@@ -79519,7 +79632,7 @@ function projectCard(entry, stale) {
79519
79632
  function addProjectAtPath(input, home = homedir17()) {
79520
79633
  const typed = input.trim();
79521
79634
  if (!typed) throw new Error("Enter a folder path.");
79522
- const expanded = typed === "~" || typed.startsWith("~/") ? join40(home, typed.slice(1)) : typed;
79635
+ const expanded = typed === "~" || typed.startsWith("~/") ? join41(home, typed.slice(1)) : typed;
79523
79636
  const absolute = resolve10(expanded);
79524
79637
  let stats;
79525
79638
  try {
@@ -79549,7 +79662,7 @@ function storeProjectIcon(id2, name, bytes) {
79549
79662
  if (bytes.length === 0) throw new Error("That file is empty.");
79550
79663
  const path3 = customIconPath(id2, `.${extension2}`);
79551
79664
  mkdirSync20(dirname18(path3), { recursive: true });
79552
- writeFileSync14(path3, bytes);
79665
+ writeFileSync15(path3, bytes);
79553
79666
  if (!imageDimensions(path3)) {
79554
79667
  rmSync11(path3, { force: true });
79555
79668
  throw new Error("That file does not look like an image Frizz can draw.");
@@ -79603,7 +79716,7 @@ function mergeSubAgentSteers(messages, steers) {
79603
79716
  return merged;
79604
79717
  }
79605
79718
  function createRouter(ctx) {
79606
- const frizzDir = join40(ctx.project.dir, ".frizz");
79719
+ const frizzDir = join41(ctx.project.dir, ".frizz");
79607
79720
  const openRoots = openableFileRoots(ctx.project);
79608
79721
  function isAutoTitledSession(slug) {
79609
79722
  return ctx.storage.getSession(slug)?.title_auto === 1;
@@ -81821,7 +81934,7 @@ Say which way you went and why in your write-up, so the human can course-correct
81821
81934
  }
81822
81935
  const updated = clearProjectIcon(input.id);
81823
81936
  if (!updated) throw new Error("No such project.");
81824
- return projectCard(updated, !existsSync18(updated.path));
81937
+ return projectCard(updated, !existsSync19(updated.path));
81825
81938
  }
81826
81939
  }),
81827
81940
  /**
@@ -81862,7 +81975,7 @@ Say which way you went and why in your write-up, so the human can course-correct
81862
81975
  }
81863
81976
  const updated = renameProject(entry.id, { name: name === basename9(path3) ? null : name, slug: name });
81864
81977
  if (!updated) throw new Error("No such project.");
81865
- return projectCard(updated, !existsSync18(updated.path));
81978
+ return projectCard(updated, !existsSync19(updated.path));
81866
81979
  }
81867
81980
  }),
81868
81981
  /**
@@ -81948,6 +82061,26 @@ Say which way you went and why in your write-up, so the human can course-correct
81948
82061
  output: Settings,
81949
82062
  handler: async () => ctx.resetSettings()
81950
82063
  }),
82064
+ // The first-run questionnaire (shared/frizz-md.ts): a project with no threads and no FRIZZ.md asks
82065
+ // how its workers should land work and how independently they should act, and writes the answers
82066
+ // as FRIZZ.md — which only Frizz workers ever read. Skipping is remembered per project.
82067
+ frizzMdStatus: query({
82068
+ output: FrizzMdStatus,
82069
+ handler: async () => frizzMdStatus(ctx.project.dir, ctx.storage)
82070
+ }),
82071
+ frizzMdCreate: mutation({
82072
+ input: FrizzMdAnswers,
82073
+ output: external_exports.object({ path: external_exports.string() }),
82074
+ handler: async ({ input }) => createFrizzMd(ctx.project.dir, input)
82075
+ }),
82076
+ frizzMdSkip: mutation({
82077
+ input: external_exports.object({}).strict(),
82078
+ output: external_exports.object({ skipped: external_exports.literal(true) }),
82079
+ handler: async () => {
82080
+ skipFrizzMd(ctx.storage);
82081
+ return { skipped: true };
82082
+ }
82083
+ }),
81951
82084
  dispatchPreferencesGet: query({
81952
82085
  output: DispatchPreferences,
81953
82086
  handler: async () => ctx.getDispatchPreferences(readCodexModels(void 0, ctx.codexVersion))
@@ -82080,6 +82213,7 @@ var init_router5 = __esm({
82080
82213
  init_transcript();
82081
82214
  init_project_registry();
82082
82215
  init_src();
82216
+ init_frizz_md2();
82083
82217
  init_image_header();
82084
82218
  init_project_root();
82085
82219
  init_project_identity();
@@ -82363,7 +82497,7 @@ var init_local_image = __esm({
82363
82497
  // packages/server/src/project-icon.ts
82364
82498
  import { readFileSync as readFileSync29, readdirSync as readdirSync12, realpathSync as realpathSync13, statSync as statSync21 } from "node:fs";
82365
82499
  import { homedir as homedir18 } from "node:os";
82366
- import { basename as basename10, dirname as dirname19, extname as extname3, join as join41, relative as relative2, sep as sep4 } from "node:path";
82500
+ import { basename as basename10, dirname as dirname19, extname as extname3, join as join42, relative as relative2, sep as sep4 } from "node:path";
82367
82501
  function normalizeStem(stem) {
82368
82502
  const sized = stem.toLowerCase().replace(/[@-]\d+(\.\d+)?x(\d+)?$/u, "").replace(/[-_]\d{2,4}$/u, "");
82369
82503
  const normalized = sized.replace(VARIANT_SUFFIX, "");
@@ -82381,7 +82515,7 @@ function sizeScore(dimensions) {
82381
82515
  return Math.max(0, Math.min(40, Math.round(Math.log2(edge / 24) * 8)));
82382
82516
  }
82383
82517
  function under(root, relativeDirectory) {
82384
- return relativeDirectory ? join41(root, relativeDirectory) : root;
82518
+ return relativeDirectory ? join42(root, relativeDirectory) : root;
82385
82519
  }
82386
82520
  function listFiles(directory) {
82387
82521
  try {
@@ -82403,19 +82537,19 @@ function iconDirectories(root) {
82403
82537
  for (const asset of ASSET_DIRECTORIES) directories.push(under(root, asset));
82404
82538
  for (const host of HOST_DIRECTORIES) {
82405
82539
  if (!children2.has(host)) continue;
82406
- for (const asset of ASSET_DIRECTORIES) directories.push(under(join41(root, host), asset));
82540
+ for (const asset of ASSET_DIRECTORIES) directories.push(under(join42(root, host), asset));
82407
82541
  }
82408
82542
  for (const extra of EXTRA_DIRECTORIES) directories.push(under(root, extra));
82409
82543
  for (const container of WORKSPACE_CONTAINERS) {
82410
82544
  if (!children2.has(container)) continue;
82411
82545
  let members;
82412
82546
  try {
82413
- members = readdirSync12(join41(root, container), { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name);
82547
+ members = readdirSync12(join42(root, container), { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name);
82414
82548
  } catch {
82415
82549
  continue;
82416
82550
  }
82417
82551
  for (const member of members) {
82418
- for (const asset of ASSET_DIRECTORIES) directories.push(under(join41(root, container, member), asset));
82552
+ for (const asset of ASSET_DIRECTORIES) directories.push(under(join42(root, container, member), asset));
82419
82553
  }
82420
82554
  }
82421
82555
  return [...new Set(directories)];
@@ -82429,7 +82563,7 @@ function manifestIcons(manifestPath) {
82429
82563
  }
82430
82564
  if (!Array.isArray(parsed?.icons)) return [];
82431
82565
  const directory = dirname19(manifestPath);
82432
- return parsed.icons.map((icon) => typeof icon?.src === "string" ? icon.src : void 0).filter((src) => !!src && !/^(https?:)?\/\//u.test(src) && !src.startsWith("data:")).map((src) => join41(directory, src.replace(/[?#].*$/u, "").replace(/^\//u, "")));
82566
+ return parsed.icons.map((icon) => typeof icon?.src === "string" ? icon.src : void 0).filter((src) => !!src && !/^(https?:)?\/\//u.test(src) && !src.startsWith("data:")).map((src) => join42(directory, src.replace(/[?#].*$/u, "").replace(/^\//u, "")));
82433
82567
  }
82434
82568
  function projectIconCandidates(root) {
82435
82569
  const projectStem = normalizeStem(basename10(root)).normalized;
@@ -82448,7 +82582,7 @@ function projectIconCandidates(root) {
82448
82582
  for (const name of listFiles(directory)) {
82449
82583
  const extension2 = extname3(name).toLowerCase();
82450
82584
  if (MANIFEST_NAMES.includes(name.toLowerCase())) {
82451
- for (const icon of manifestIcons(join41(directory, name))) {
82585
+ for (const icon of manifestIcons(join42(directory, name))) {
82452
82586
  if (MEASURABLE_IMAGE_EXTENSIONS.has(extname3(icon).toLowerCase())) {
82453
82587
  fromManifest.add(icon);
82454
82588
  files.push({ path: icon, directory: dirname19(icon) });
@@ -82459,7 +82593,7 @@ function projectIconCandidates(root) {
82459
82593
  if (!MEASURABLE_IMAGE_EXTENSIONS.has(extension2)) continue;
82460
82594
  const stem = name.slice(0, name.length - extension2.length);
82461
82595
  if (normalizeStem(stem).normalized === "favicon") iconHomes.add(directory);
82462
- files.push({ path: join41(directory, name), directory });
82596
+ files.push({ path: join42(directory, name), directory });
82463
82597
  if (files.length >= MAX_CANDIDATES) break;
82464
82598
  }
82465
82599
  }
@@ -82637,7 +82771,7 @@ var init_project_icon = __esm({
82637
82771
 
82638
82772
  // packages/server/src/local-visualization.ts
82639
82773
  import { readdirSync as readdirSync13, readFileSync as readFileSync30, realpathSync as realpathSync14, statSync as statSync22 } from "node:fs";
82640
- import { join as join42, sep as sep5 } from "node:path";
82774
+ import { join as join43, sep as sep5 } from "node:path";
82641
82775
  function children(path3, pattern) {
82642
82776
  try {
82643
82777
  return readdirSync13(path3, { withFileTypes: true }).filter((entry) => entry.isDirectory() && pattern.test(entry.name)).map((entry) => entry.name).sort().reverse();
@@ -82649,7 +82783,7 @@ function isUnder2(path3, root) {
82649
82783
  return path3 === root || path3.startsWith(root.endsWith(sep5) ? root : root + sep5);
82650
82784
  }
82651
82785
  function resolveFragment(projectDir, sessionId, file) {
82652
- const base = join42(projectDir, ".codex", "visualizations");
82786
+ const base = join43(projectDir, ".codex", "visualizations");
82653
82787
  let projectReal;
82654
82788
  let baseReal;
82655
82789
  try {
@@ -82660,12 +82794,12 @@ function resolveFragment(projectDir, sessionId, file) {
82660
82794
  }
82661
82795
  if (!isUnder2(baseReal, projectReal)) return null;
82662
82796
  for (const year of children(base, YEAR_PART)) {
82663
- const yearDir = join42(base, year);
82797
+ const yearDir = join43(base, year);
82664
82798
  for (const month of children(yearDir, DATE_PART)) {
82665
- const monthDir = join42(yearDir, month);
82799
+ const monthDir = join43(yearDir, month);
82666
82800
  for (const day of children(monthDir, DATE_PART)) {
82667
- const sessionRoot = join42(baseReal, year, month, day, sessionId);
82668
- const candidate = join42(monthDir, day, sessionId, file);
82801
+ const sessionRoot = join43(baseReal, year, month, day, sessionId);
82802
+ const candidate = join43(monthDir, day, sessionId, file);
82669
82803
  try {
82670
82804
  const real = realpathSync14(candidate);
82671
82805
  if (isUnder2(real, sessionRoot) && statSync22(real).isFile()) return real;
@@ -82797,9 +82931,9 @@ var init_local_visualization = __esm({
82797
82931
  });
82798
82932
 
82799
82933
  // packages/server/src/app.ts
82800
- import { mkdirSync as mkdirSync21, writeFileSync as writeFileSync15 } from "node:fs";
82934
+ import { mkdirSync as mkdirSync21, writeFileSync as writeFileSync16 } from "node:fs";
82801
82935
  import { Readable } from "node:stream";
82802
- import { join as join43 } from "node:path";
82936
+ import { join as join44 } from "node:path";
82803
82937
  import { randomUUID as randomUUID18 } from "node:crypto";
82804
82938
  function createApp(ctx, options = {}) {
82805
82939
  const app = new Hono2();
@@ -82906,11 +83040,11 @@ function createApp(ctx, options = {}) {
82906
83040
  if (typeof body.data !== "string" || body.data.length > ATTACHMENT_MAX_BASE64_CHARS) return c.json({ error: "bad payload" }, 400);
82907
83041
  const ext = `.${attachmentExtension(name)}`;
82908
83042
  const buf = Buffer.from(body.data, "base64");
82909
- const dir = join43(ctx.project.stateDir, "attachments");
83043
+ const dir = join44(ctx.project.stateDir, "attachments");
82910
83044
  mkdirSync21(dir, { recursive: true });
82911
83045
  const base = name.replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9_-]+/g, "-").slice(0, 40) || "file";
82912
- const path3 = join43(dir, `${Date.now()}-${randomUUID18().slice(0, 8)}-${base}${ext}`);
82913
- writeFileSync15(path3, buf);
83046
+ const path3 = join44(dir, `${Date.now()}-${randomUUID18().slice(0, 8)}-${base}${ext}`);
83047
+ writeFileSync16(path3, buf);
82914
83048
  return c.json({ path: path3 });
82915
83049
  });
82916
83050
  app.get(
@@ -83889,10 +84023,10 @@ var init_local_file_watch = __esm({
83889
84023
  });
83890
84024
 
83891
84025
  // packages/server/src/boot-progress.ts
83892
- import { mkdirSync as mkdirSync22, readFileSync as readFileSync31, renameSync as renameSync11, rmSync as rmSync12, writeFileSync as writeFileSync16 } from "node:fs";
83893
- import { basename as basename12, dirname as dirname21, join as join44 } from "node:path";
84026
+ import { mkdirSync as mkdirSync22, readFileSync as readFileSync31, renameSync as renameSync11, rmSync as rmSync12, writeFileSync as writeFileSync17 } from "node:fs";
84027
+ import { basename as basename12, dirname as dirname21, join as join45 } from "node:path";
83894
84028
  function bootProgressPath(stateDir) {
83895
- return join44(stateDir, BOOT_PROGRESS_NAME);
84029
+ return join45(stateDir, BOOT_PROGRESS_NAME);
83896
84030
  }
83897
84031
  function createBootProgressPublisher(stateDir, minIntervalMs = 200) {
83898
84032
  if (!stateDir) {
@@ -83913,8 +84047,8 @@ function createBootProgressPublisher(stateDir, minIntervalMs = 200) {
83913
84047
  step++;
83914
84048
  try {
83915
84049
  mkdirSync22(dirname21(path3), { recursive: true, mode: 448 });
83916
- const temp = join44(dirname21(path3), `.${basename12(path3)}.${process.pid}.tmp`);
83917
- writeFileSync16(temp, `${JSON.stringify({ pid: process.pid, step, phase, at: new Date(now).toISOString() })}
84050
+ const temp = join45(dirname21(path3), `.${basename12(path3)}.${process.pid}.tmp`);
84051
+ writeFileSync17(temp, `${JSON.stringify({ pid: process.pid, step, phase, at: new Date(now).toISOString() })}
83918
84052
  `, "utf8");
83919
84053
  renameSync11(temp, path3);
83920
84054
  } catch {
@@ -83939,12 +84073,12 @@ var init_boot_progress = __esm({
83939
84073
  });
83940
84074
 
83941
84075
  // packages/server/src/runtime-lease.ts
83942
- import { existsSync as existsSync19, mkdirSync as mkdirSync23, readdirSync as readdirSync14, readFileSync as readFileSync32, unlinkSync as unlinkSync8, writeFileSync as writeFileSync17 } from "node:fs";
83943
- import { dirname as dirname22, join as join45 } from "node:path";
84076
+ import { existsSync as existsSync20, mkdirSync as mkdirSync23, readdirSync as readdirSync14, readFileSync as readFileSync32, unlinkSync as unlinkSync8, writeFileSync as writeFileSync18 } from "node:fs";
84077
+ import { dirname as dirname22, join as join46 } from "node:path";
83944
84078
  function runtimeVersionDir(bin) {
83945
84079
  let dir = dirname22(bin);
83946
84080
  for (let step = 0; step < MAX_ASCENT; step++) {
83947
- if (existsSync19(join45(dir, PROVISIONED_MARKER))) return dir;
84081
+ if (existsSync20(join46(dir, PROVISIONED_MARKER))) return dir;
83948
84082
  const parent = dirname22(dir);
83949
84083
  if (parent === dir) return void 0;
83950
84084
  dir = parent;
@@ -83963,11 +84097,11 @@ function leaseRuntime(bin, role) {
83963
84097
  const versionDir = runtimeVersionDir(bin);
83964
84098
  if (!versionDir) return () => {
83965
84099
  };
83966
- const path3 = join45(versionDir, LEASES_DIR, `${process.pid}.json`);
84100
+ const path3 = join46(versionDir, LEASES_DIR, `${process.pid}.json`);
83967
84101
  try {
83968
84102
  mkdirSync23(dirname22(path3), { recursive: true });
83969
84103
  const lease = { pid: process.pid, role, bin, at: (/* @__PURE__ */ new Date()).toISOString() };
83970
- writeFileSync17(path3, JSON.stringify(lease));
84104
+ writeFileSync18(path3, JSON.stringify(lease));
83971
84105
  } catch {
83972
84106
  return () => {
83973
84107
  };
@@ -83980,7 +84114,7 @@ function leaseRuntime(bin, role) {
83980
84114
  };
83981
84115
  }
83982
84116
  function liveRuntimeLeases(versionDir) {
83983
- const dir = join45(versionDir, LEASES_DIR);
84117
+ const dir = join46(versionDir, LEASES_DIR);
83984
84118
  let names;
83985
84119
  try {
83986
84120
  names = readdirSync14(dir);
@@ -83990,7 +84124,7 @@ function liveRuntimeLeases(versionDir) {
83990
84124
  const live = [];
83991
84125
  for (const name of names) {
83992
84126
  if (!name.endsWith(".json")) continue;
83993
- const path3 = join45(dir, name);
84127
+ const path3 = join46(dir, name);
83994
84128
  let lease;
83995
84129
  try {
83996
84130
  lease = JSON.parse(readFileSync32(path3, "utf8"));
@@ -84024,7 +84158,7 @@ import { createHash as createHash17 } from "node:crypto";
84024
84158
  import {
84025
84159
  chmodSync as chmodSync2,
84026
84160
  closeSync as closeSync17,
84027
- existsSync as existsSync20,
84161
+ existsSync as existsSync21,
84028
84162
  mkdirSync as mkdirSync24,
84029
84163
  openSync as openSync18,
84030
84164
  readFileSync as readFileSync33,
@@ -84032,17 +84166,17 @@ import {
84032
84166
  renameSync as renameSync12,
84033
84167
  rmSync as rmSync13,
84034
84168
  statSync as statSync24,
84035
- writeFileSync as writeFileSync18,
84169
+ writeFileSync as writeFileSync19,
84036
84170
  writeSync as writeSync2
84037
84171
  } from "node:fs";
84038
- import { dirname as dirname23, isAbsolute as isAbsolute10, join as join46, normalize, relative as relative3, sep as sep6 } from "node:path";
84172
+ import { dirname as dirname23, isAbsolute as isAbsolute10, join as join47, normalize, relative as relative3, sep as sep6 } from "node:path";
84039
84173
  import { Readable as Readable2, Transform, Writable as Writable4 } from "node:stream";
84040
84174
  import { pipeline } from "node:stream/promises";
84041
84175
  import { createGunzip } from "node:zlib";
84042
84176
  function runtimesRoot(env = process.env) {
84043
84177
  const override = env[RUNTIMES_DIR_ENV];
84044
84178
  if (override && isAbsolute10(override)) return override;
84045
- return join46(frizzRoots().cache, "runtimes");
84179
+ return join47(frizzRoots().cache, "runtimes");
84046
84180
  }
84047
84181
  function isMusl() {
84048
84182
  if (process.platform !== "linux") return false;
@@ -84059,16 +84193,16 @@ function runtimeCoordinates(backend, platform3 = process.platform, arch = proces
84059
84193
  return { pkg: "@openai/codex", packageVersion: `${CODEX_VERSION}-${platform3}-${arch}`, label: CODEX_VERSION, binary: `codex${exe2}` };
84060
84194
  }
84061
84195
  function provisionedBinary(backend, root, label) {
84062
- const dir = join46(root, backend, label);
84196
+ const dir = join47(root, backend, label);
84063
84197
  let marker;
84064
84198
  try {
84065
- marker = JSON.parse(readFileSync33(join46(dir, MARKER), "utf8"));
84199
+ marker = JSON.parse(readFileSync33(join47(dir, MARKER), "utf8"));
84066
84200
  } catch {
84067
84201
  return void 0;
84068
84202
  }
84069
84203
  if (typeof marker.binary !== "string" || marker.label !== label) return void 0;
84070
- const bin = join46(dir, marker.binary);
84071
- return existsSync20(bin) ? bin : void 0;
84204
+ const bin = join47(dir, marker.binary);
84205
+ return existsSync21(bin) ? bin : void 0;
84072
84206
  }
84073
84207
  function octal(buffer, offset, length) {
84074
84208
  const text2 = buffer.toString("latin1", offset, offset + length).replace(/\0.*$/su, "").trim();
@@ -84082,17 +84216,17 @@ function safeEntryPath(dest, name) {
84082
84216
  if (parts.length < 2) return void 0;
84083
84217
  const rel = normalize(parts.slice(1).join(sep6));
84084
84218
  if (isAbsolute10(rel) || rel === ".." || rel.startsWith(`..${sep6}`)) return void 0;
84085
- const full = join46(dest, rel);
84219
+ const full = join47(dest, rel);
84086
84220
  const back = relative3(dest, full);
84087
84221
  if (back.startsWith("..") || isAbsolute10(back)) return void 0;
84088
84222
  return full;
84089
84223
  }
84090
84224
  function locateBinary(dir, backend, binary) {
84091
84225
  if (backend === "claude") {
84092
- const direct = join46(dir, binary);
84093
- return existsSync20(direct) ? direct : void 0;
84226
+ const direct = join47(dir, binary);
84227
+ return existsSync21(direct) ? direct : void 0;
84094
84228
  }
84095
- const vendor = join46(dir, "vendor");
84229
+ const vendor = join47(dir, "vendor");
84096
84230
  let triples;
84097
84231
  try {
84098
84232
  triples = readdirSync15(vendor);
@@ -84100,8 +84234,8 @@ function locateBinary(dir, backend, binary) {
84100
84234
  return void 0;
84101
84235
  }
84102
84236
  for (const triple of triples) {
84103
- const candidate = join46(vendor, triple, "bin", binary);
84104
- if (existsSync20(candidate)) return candidate;
84237
+ const candidate = join47(vendor, triple, "bin", binary);
84238
+ if (existsSync21(candidate)) return candidate;
84105
84239
  }
84106
84240
  return void 0;
84107
84241
  }
@@ -84116,9 +84250,9 @@ async function provisionRuntime(backend, options) {
84116
84250
  const registry = options.registry ?? REGISTRY;
84117
84251
  const progress = options.onProgress ?? (() => {
84118
84252
  });
84119
- const backendDir = join46(root, backend);
84120
- const finalDir = join46(backendDir, coordinates.label);
84121
- const partial = join46(backendDir, `.partial-${coordinates.label}-${process.pid}`);
84253
+ const backendDir = join47(root, backend);
84254
+ const finalDir = join47(backendDir, coordinates.label);
84255
+ const partial = join47(backendDir, `.partial-${coordinates.label}-${process.pid}`);
84122
84256
  mkdirSync24(backendDir, { recursive: true });
84123
84257
  rmSync13(partial, { recursive: true, force: true });
84124
84258
  mkdirSync24(partial);
@@ -84165,7 +84299,7 @@ async function provisionRuntime(backend, options) {
84165
84299
  binary: relative3(partial, bin),
84166
84300
  at: (/* @__PURE__ */ new Date()).toISOString()
84167
84301
  };
84168
- writeFileSync18(join46(partial, MARKER), `${JSON.stringify(marker, null, 2)}
84302
+ writeFileSync19(join47(partial, MARKER), `${JSON.stringify(marker, null, 2)}
84169
84303
  `, "utf8");
84170
84304
  const rename2 = options.rename ?? renameSync12;
84171
84305
  try {
@@ -84174,7 +84308,7 @@ async function provisionRuntime(backend, options) {
84174
84308
  rename2(partial, finalDir);
84175
84309
  break;
84176
84310
  } catch (err) {
84177
- if (attempt >= RENAME_ATTEMPTS || !TRANSIENT_HANDLE_CODES.has(errorCode4(err) ?? "") || existsSync20(finalDir)) throw err;
84311
+ if (attempt >= RENAME_ATTEMPTS || !TRANSIENT_HANDLE_CODES.has(errorCode4(err) ?? "") || existsSync21(finalDir)) throw err;
84178
84312
  await new Promise((resolve13) => setTimeout(resolve13, options.retryDelayMs ?? RENAME_RETRY_DELAY_MS));
84179
84313
  }
84180
84314
  }
@@ -84185,7 +84319,7 @@ async function provisionRuntime(backend, options) {
84185
84319
  return { bin: theirs, label: coordinates.label, fetched: false };
84186
84320
  }
84187
84321
  progress("ready");
84188
- return { bin: join46(finalDir, marker.binary), label: coordinates.label, fetched: true };
84322
+ return { bin: join47(finalDir, marker.binary), label: coordinates.label, fetched: true };
84189
84323
  } catch (err) {
84190
84324
  rmSync13(partial, { recursive: true, force: true });
84191
84325
  throw err;
@@ -84193,7 +84327,7 @@ async function provisionRuntime(backend, options) {
84193
84327
  }
84194
84328
  function sweepRuntimes(backend, root, keepLabel, now = Date.now(), deps = {}) {
84195
84329
  const rm2 = deps.rm ?? defaultSweepRm;
84196
- const backendDir = join46(root, backend);
84330
+ const backendDir = join47(root, backend);
84197
84331
  let entries2;
84198
84332
  try {
84199
84333
  entries2 = readdirSync15(backendDir);
@@ -84203,7 +84337,7 @@ function sweepRuntimes(backend, root, keepLabel, now = Date.now(), deps = {}) {
84203
84337
  const sweep = { removed: [], kept: [] };
84204
84338
  for (const entry of entries2) {
84205
84339
  if (entry === keepLabel) continue;
84206
- const full = join46(backendDir, entry);
84340
+ const full = join47(backendDir, entry);
84207
84341
  if (entry.startsWith(".partial-")) {
84208
84342
  try {
84209
84343
  if (now - statSync24(full).mtimeMs < 24 * 60 * 60 * 1e3) continue;
@@ -84974,18 +85108,18 @@ var init_legacy_project_db = __esm({
84974
85108
  });
84975
85109
 
84976
85110
  // packages/server/src/frizz-db.ts
84977
- import { existsSync as existsSync21, mkdirSync as mkdirSync25, readdirSync as readdirSync16, renameSync as renameSync13, statSync as statSync25 } from "node:fs";
84978
- import { basename as basename13, dirname as dirname24, join as join47 } from "node:path";
85111
+ import { existsSync as existsSync22, mkdirSync as mkdirSync25, readdirSync as readdirSync16, renameSync as renameSync13, statSync as statSync25 } from "node:fs";
85112
+ import { basename as basename13, dirname as dirname24, join as join48 } from "node:path";
84979
85113
  function frizzDatabaseLocation(options) {
84980
85114
  if (options.stateDir !== void 0) {
84981
85115
  const projectsDir = dirname24(options.stateDir);
84982
85116
  if (basename13(projectsDir) === "projects") {
84983
- return { path: options.path ?? join47(dirname24(projectsDir), "ui.db"), projectsDir };
85117
+ return { path: options.path ?? join48(dirname24(projectsDir), "ui.db"), projectsDir };
84984
85118
  }
84985
- return { path: options.path ?? join47(options.stateDir, "ui.db"), projectsDir: void 0 };
85119
+ return { path: options.path ?? join48(options.stateDir, "ui.db"), projectsDir: void 0 };
84986
85120
  }
84987
85121
  const data = options.home ? frizzPaths({ home: options.home }).data : frizzRoots().data;
84988
- return { path: options.path ?? join47(data, "ui.db"), projectsDir: join47(data, "projects") };
85122
+ return { path: options.path ?? join48(data, "ui.db"), projectsDir: join48(data, "projects") };
84989
85123
  }
84990
85124
  function ensureFrizzSchema(db2) {
84991
85125
  db2.exec(`
@@ -85016,10 +85150,10 @@ function openFrizzDatabase(options = {}) {
85016
85150
  );
85017
85151
  for (const projectId of retiredLegacyProjectIds(projectsDir)) {
85018
85152
  if (alreadyImported.has(projectId)) continue;
85019
- const dir = join47(projectsDir, projectId);
85153
+ const dir = join48(projectsDir, projectId);
85020
85154
  try {
85021
- renameSync13(join47(dir, "ui.db.imported"), join47(dir, "ui.db"));
85022
- db2.prepare("INSERT INTO imported_project (project_id, source, rows, imported_at) VALUES (?, ?, 0, ?)").run(projectId, join47(dir, "ui.db"), (/* @__PURE__ */ new Date()).toISOString());
85155
+ renameSync13(join48(dir, "ui.db.imported"), join48(dir, "ui.db"));
85156
+ db2.prepare("INSERT INTO imported_project (project_id, source, rows, imported_at) VALUES (?, ?, 0, ?)").run(projectId, join48(dir, "ui.db"), (/* @__PURE__ */ new Date()).toISOString());
85023
85157
  alreadyImported.add(projectId);
85024
85158
  log.info("frizz-db", `${projectId}: restored ui.db.imported to ui.db and recorded it as imported`);
85025
85159
  } catch (error) {
@@ -85029,7 +85163,7 @@ function openFrizzDatabase(options = {}) {
85029
85163
  }
85030
85164
  for (const projectId of legacyProjectIds(projectsDir)) {
85031
85165
  if (alreadyImported.has(projectId)) continue;
85032
- const legacyPath = join47(projectsDir, projectId, "ui.db");
85166
+ const legacyPath = join48(projectsDir, projectId, "ui.db");
85033
85167
  try {
85034
85168
  const rows = importLegacyProject(db2, projectId, legacyPath);
85035
85169
  imported.push({ projectId, rows });
@@ -85059,10 +85193,10 @@ function openFrizzDatabase(options = {}) {
85059
85193
  };
85060
85194
  }
85061
85195
  function projectIdsWithFile(projectsDir, file) {
85062
- if (!existsSync21(projectsDir)) return [];
85196
+ if (!existsSync22(projectsDir)) return [];
85063
85197
  return readdirSync16(projectsDir).filter((name) => {
85064
85198
  try {
85065
- return statSync25(join47(projectsDir, name, file)).isFile();
85199
+ return statSync25(join48(projectsDir, name, file)).isFile();
85066
85200
  } catch {
85067
85201
  return false;
85068
85202
  }
@@ -85072,7 +85206,7 @@ function legacyProjectIds(projectsDir) {
85072
85206
  return projectIdsWithFile(projectsDir, "ui.db");
85073
85207
  }
85074
85208
  function retiredLegacyProjectIds(projectsDir) {
85075
- return projectIdsWithFile(projectsDir, "ui.db.imported").filter((id2) => !existsSync21(join47(projectsDir, id2, "ui.db")));
85209
+ return projectIdsWithFile(projectsDir, "ui.db.imported").filter((id2) => !existsSync22(join48(projectsDir, id2, "ui.db")));
85076
85210
  }
85077
85211
  function tableColumns(db2, schema, table) {
85078
85212
  return db2.prepare(`PRAGMA ${schema}.table_info(${table})`).all().map((c) => c.name);
@@ -85277,8 +85411,8 @@ __export(index_exports, {
85277
85411
  unknownProjectPage: () => unknownProjectPage
85278
85412
  });
85279
85413
  import { createServer } from "node:http";
85280
- import { readFileSync as readFileSync34, existsSync as existsSync22, statSync as statSync26 } from "node:fs";
85281
- import { dirname as dirname26, join as join48, resolve as resolve12, extname as extname4, posix as posix2, sep as sep7 } from "node:path";
85414
+ import { readFileSync as readFileSync34, existsSync as existsSync23, statSync as statSync26 } from "node:fs";
85415
+ import { dirname as dirname26, join as join49, resolve as resolve12, extname as extname4, posix as posix2, sep as sep7 } from "node:path";
85282
85416
  function readServerAddressHolder(path3) {
85283
85417
  try {
85284
85418
  const value = JSON.parse(readFileSync34(path3, "utf8"));
@@ -85406,12 +85540,12 @@ function staticIsFresh(req, etag, mtimeMs) {
85406
85540
  }
85407
85541
  function serveStatic(distDir, req, res) {
85408
85542
  const rel = posix2.normalize((req.url ?? "/").split("?")[0].replace(/\\/g, "/")).replace(/^(\.\.[/\\])+/, "");
85409
- let file = join48(distDir, rel === "/" ? "index.html" : rel);
85410
- if (!file.startsWith(distDir + sep7)) file = join48(distDir, "index.html");
85411
- if (!existsSync22(file)) file = join48(distDir, "index.html");
85543
+ let file = join49(distDir, rel === "/" ? "index.html" : rel);
85544
+ if (!file.startsWith(distDir + sep7)) file = join49(distDir, "index.html");
85545
+ if (!existsSync23(file)) file = join49(distDir, "index.html");
85412
85546
  try {
85413
85547
  const stats = statSync26(file);
85414
- const cacheControl = file.startsWith(join48(distDir, "assets") + sep7) ? STATIC_CACHE_IMMUTABLE : STATIC_CACHE_REVALIDATE;
85548
+ const cacheControl = file.startsWith(join49(distDir, "assets") + sep7) ? STATIC_CACHE_IMMUTABLE : STATIC_CACHE_REVALIDATE;
85415
85549
  const etag = `"${stats.size.toString(16)}-${Math.trunc(stats.mtimeMs).toString(16)}"`;
85416
85550
  const headers = {
85417
85551
  "content-type": MIME[extname4(file)] ?? "application/octet-stream",
@@ -85816,7 +85950,7 @@ async function startServer(opts = {}) {
85816
85950
  }
85817
85951
  statusPath = serverLockPathFor(ctx.project);
85818
85952
  const webRoot = resolve12(import.meta.dirname, "..", "..", "web");
85819
- const distDir = opts.webDistDir ? resolve12(opts.webDistDir) : join48(webRoot, "dist");
85953
+ const distDir = opts.webDistDir ? resolve12(opts.webDistDir) : join49(webRoot, "dist");
85820
85954
  startupPhase = "Vite";
85821
85955
  if (opts.dev) {
85822
85956
  try {
@@ -85894,7 +86028,7 @@ async function startServer(opts = {}) {
85894
86028
  if (vite) {
85895
86029
  vite.middlewares(req, res, () => {
85896
86030
  try {
85897
- const html = readFileSync34(join48(webRoot, "index.html"), "utf8");
86031
+ const html = readFileSync34(join49(webRoot, "index.html"), "utf8");
85898
86032
  void vite.transformIndexHtml(url, html).then((out) => {
85899
86033
  res.writeHead(200, { "content-type": "text/html" });
85900
86034
  res.end(out);
@@ -85906,7 +86040,7 @@ async function startServer(opts = {}) {
85906
86040
  });
85907
86041
  return;
85908
86042
  }
85909
- if (existsSync22(distDir)) {
86043
+ if (existsSync23(distDir)) {
85910
86044
  serveStatic(distDir, req, res);
85911
86045
  return;
85912
86046
  }
@@ -86100,7 +86234,7 @@ var init_index = __esm({
86100
86234
  }
86101
86235
  };
86102
86236
  isApiUrl = (url) => url === FRIZZ_ROUTE_PREFIX || url.startsWith(`${FRIZZ_ROUTE_PREFIX}/`);
86103
- serverLockPathFor = (project) => join48(project.stateDir, "server.lock");
86237
+ serverLockPathFor = (project) => join49(project.stateDir, "server.lock");
86104
86238
  MIME = {
86105
86239
  ".html": "text/html",
86106
86240
  ".js": "text/javascript",
@@ -86123,8 +86257,8 @@ init_project();
86123
86257
  init_project_launch();
86124
86258
  init_shutdown();
86125
86259
  init_logging();
86126
- import { existsSync as existsSync23 } from "node:fs";
86127
- import { join as join49 } from "node:path";
86260
+ import { existsSync as existsSync24 } from "node:fs";
86261
+ import { join as join50 } from "node:path";
86128
86262
  process.on("uncaughtException", (error) => {
86129
86263
  log.error("dev-child", `uncaught exception: ${error instanceof Error ? error.stack ?? error.message : error}`);
86130
86264
  process.exit(1);
@@ -86179,9 +86313,9 @@ try {
86179
86313
  ["FRIZZ_SCRIPTS_DIR", process.env.FRIZZ_SCRIPTS_DIR, "index.mjs"],
86180
86314
  ["FRIZZ_WORKER_PLUGIN_DIR", process.env.FRIZZ_WORKER_PLUGIN_DIR, ".claude-plugin/plugin.json"]
86181
86315
  ];
86182
- if (!existsSync23(stableWebDist)) throw new Error("stable artifact launch is missing its verified web directory");
86316
+ if (!existsSync24(stableWebDist)) throw new Error("stable artifact launch is missing its verified web directory");
86183
86317
  for (const [name, directory, requiredFile] of required) {
86184
- if (!directory || !existsSync23(join49(directory, requiredFile)))
86318
+ if (!directory || !existsSync24(join50(directory, requiredFile)))
86185
86319
  throw new Error(`stable artifact launch is missing verified ${name}`);
86186
86320
  }
86187
86321
  }