frizz 0.10.1 → 0.11.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 (91) hide show
  1. package/dist/dev-child.js +392 -177
  2. package/dist/frizz.js +243 -13
  3. package/package.json +2 -2
  4. package/web-dist/assets/{TerminalPane-VbmxsjxK.js → TerminalPane-DzTdpZim.js} +1 -1
  5. package/web-dist/assets/{abnfDiagram-VRR7QNED-CBCkSzJg.js → abnfDiagram-VRR7QNED-BpxlBYqa.js} +1 -1
  6. package/web-dist/assets/architecture-TIHT7OUA-Cyj72dua.js +1 -0
  7. package/web-dist/assets/{architectureDiagram-ZJ3FMSHR-Rd44A8-r.js → architectureDiagram-ZJ3FMSHR-yyvTAq0j.js} +1 -1
  8. package/web-dist/assets/{blockDiagram-677ZJIJ3-C8vX06UX.js → blockDiagram-677ZJIJ3-BLqVDdZ-.js} +1 -1
  9. package/web-dist/assets/{c4Diagram-LMCZKHZV-CMMjtui-.js → c4Diagram-LMCZKHZV-BrKEPLUT.js} +1 -1
  10. package/web-dist/assets/channel-DgpcWDXI.js +1 -0
  11. package/web-dist/assets/{chunk-32BRIVSS-DtsFPb8y.js → chunk-32BRIVSS-S-tSRtT-.js} +1 -1
  12. package/web-dist/assets/{chunk-52WLFC77-35RvKhG9.js → chunk-52WLFC77-DE9X7l52.js} +1 -1
  13. package/web-dist/assets/{chunk-C7G6YPKG-Dusr0gOw.js → chunk-C7G6YPKG-BdNBZMEZ.js} +1 -1
  14. package/web-dist/assets/{chunk-EX3LRPZG-BadaF-x2.js → chunk-EX3LRPZG-D1TPCp23.js} +1 -1
  15. package/web-dist/assets/{chunk-FWX5IMBZ-CpQ7yEDx.js → chunk-FWX5IMBZ-Bi7A_VUf.js} +2 -2
  16. package/web-dist/assets/{chunk-HOUHSVGY-CxygFxWC.js → chunk-HOUHSVGY-cdZH3cLd.js} +1 -1
  17. package/web-dist/assets/{chunk-ICXQ74PX-YC4-v0mV.js → chunk-ICXQ74PX-C4V2E3yL.js} +1 -1
  18. package/web-dist/assets/{chunk-MOJQB5TN-CTgO9Z8o.js → chunk-MOJQB5TN-C-zmX9mY.js} +1 -1
  19. package/web-dist/assets/{chunk-OGEWGWER-D87J1JIz.js → chunk-OGEWGWER-CwGTe6tT.js} +1 -1
  20. package/web-dist/assets/{chunk-PUDLZKDR-CVB9kmxS.js → chunk-PUDLZKDR-D7GuPy2U.js} +1 -1
  21. package/web-dist/assets/{chunk-Q4XR5HBZ-B2a88YVr.js → chunk-Q4XR5HBZ-4DNJYqvP.js} +1 -1
  22. package/web-dist/assets/{chunk-V7JOEXUC-DoFngcpl.js → chunk-V7JOEXUC-CdOmZJqy.js} +1 -1
  23. package/web-dist/assets/{chunk-VAUOI2AC-X71d5AYZ.js → chunk-VAUOI2AC-D0qOoeHa.js} +1 -1
  24. package/web-dist/assets/{chunk-VR4S4FIN-39jPx_ES.js → chunk-VR4S4FIN-D13PW9Ld.js} +1 -1
  25. package/web-dist/assets/{chunk-WYO6CB5R-CnCFbrQ7.js → chunk-WYO6CB5R-DPd8fNip.js} +1 -1
  26. package/web-dist/assets/{chunk-ZGVPDNZ5-B7wPa-pc.js → chunk-ZGVPDNZ5-DEoZANj0.js} +1 -1
  27. package/web-dist/assets/classDiagram-OUVF2IWQ-22nxxqBO.js +1 -0
  28. package/web-dist/assets/classDiagram-v2-EOCWNBFH-22nxxqBO.js +1 -0
  29. package/web-dist/assets/{cynefin-VYW2F7L2-C4GE-6ZJ.js → cynefin-VYW2F7L2-CQfP_SH_.js} +1 -1
  30. package/web-dist/assets/{cynefinDiagram-TSTJHNR4-DM7vNSjQ.js → cynefinDiagram-TSTJHNR4-B_q23LrX.js} +1 -1
  31. package/web-dist/assets/{dagre-VKFMJZFB-CBRFVbWb.js → dagre-VKFMJZFB-Drf-81Vi.js} +1 -1
  32. package/web-dist/assets/{diagram-FQU43EPY-D3t9pHH6.js → diagram-FQU43EPY-CreTIGTP.js} +1 -1
  33. package/web-dist/assets/{diagram-G47NLZAW-CBjFvnAL.js → diagram-G47NLZAW-BBNZRSgW.js} +1 -1
  34. package/web-dist/assets/{diagram-NH7WQ7WH-DAI3KCBU.js → diagram-NH7WQ7WH-DITd_c_z.js} +1 -1
  35. package/web-dist/assets/{diagram-OA4YK3LP-C82PfYbV.js → diagram-OA4YK3LP-HMl5mDli.js} +1 -1
  36. package/web-dist/assets/{diagram-WEI45ONY-fOJDDfoI.js → diagram-WEI45ONY-CxkP1cxL.js} +1 -1
  37. package/web-dist/assets/{ebnfDiagram-CCIWWBDH-B5h_VbLA.js → ebnfDiagram-CCIWWBDH-cOqwSqSu.js} +1 -1
  38. package/web-dist/assets/{erDiagram-Q63AITRT-BPje_yvH.js → erDiagram-Q63AITRT-CEaFJZJ5.js} +1 -1
  39. package/web-dist/assets/eventmodeling-45OFAUF4-OZo7EY27.js +1 -0
  40. package/web-dist/assets/flowDiagram-23GEKE2U-BTrtNMK0.js +1 -0
  41. package/web-dist/assets/{ganttDiagram-NO4QXBWP-sBrAv0Zq.js → ganttDiagram-NO4QXBWP-B83_pEFL.js} +1 -1
  42. package/web-dist/assets/{gitGraph-TEB2WS4Q-DRA1mvOm.js → gitGraph-TEB2WS4Q-CcZy9vvP.js} +1 -1
  43. package/web-dist/assets/{gitGraphDiagram-IHSO6WYX-DBMOi0IS.js → gitGraphDiagram-IHSO6WYX-dHJwoE1p.js} +1 -1
  44. package/web-dist/assets/index-DRUjlRIw.js +318 -0
  45. package/web-dist/assets/{info-DKCQHKI2-faVLVx1A.js → info-DKCQHKI2-DqY5he2n.js} +1 -1
  46. package/web-dist/assets/{infoDiagram-FWYZ7A6U-BST26f54.js → infoDiagram-FWYZ7A6U-COKKCbGB.js} +1 -1
  47. package/web-dist/assets/{ishikawaDiagram-FXEZZL3T-AQe4w48R.js → ishikawaDiagram-FXEZZL3T-C8yanhbC.js} +1 -1
  48. package/web-dist/assets/{journeyDiagram-5HDEW3XC-DHYMyWnH.js → journeyDiagram-5HDEW3XC-xOm9kUhr.js} +1 -1
  49. package/web-dist/assets/{kanban-definition-HUTT4EX6-DRjdUC1w.js → kanban-definition-HUTT4EX6-Cs_nVoSG.js} +1 -1
  50. package/web-dist/assets/{line-DsDFTOBE.js → line-BRWDTY95.js} +1 -1
  51. package/web-dist/assets/{mermaid-parser.core-BQmWWHcM.js → mermaid-parser.core-_snubxnm.js} +3 -3
  52. package/web-dist/assets/{mermaid.core-DyyZgnTM.js → mermaid.core-B_sHF_kX.js} +3 -3
  53. package/web-dist/assets/{mindmap-definition-LN4V7U3C-DKFwErMl.js → mindmap-definition-LN4V7U3C-CROqMxsQ.js} +1 -1
  54. package/web-dist/assets/{packet-7NZHBO7P-Dc2mNrwB.js → packet-7NZHBO7P-Cy6k0ePg.js} +1 -1
  55. package/web-dist/assets/{pegDiagram-2B236MQR-CApGxts7.js → pegDiagram-2B236MQR-CiPu5Dg4.js} +1 -1
  56. package/web-dist/assets/{pie-RZYD4A2V-420IM2Cy.js → pie-RZYD4A2V-BGbuoQNT.js} +1 -1
  57. package/web-dist/assets/{pieDiagram-ENE6RG2P-B9AabvqO.js → pieDiagram-ENE6RG2P-DXkmXblw.js} +1 -1
  58. package/web-dist/assets/{quadrantDiagram-ABIIQ3AL-KDtGo5xp.js → quadrantDiagram-ABIIQ3AL-BanFSlsg.js} +1 -1
  59. package/web-dist/assets/{radar-I7S5WNFK-r00cL8de.js → radar-I7S5WNFK-CGQFn8j-.js} +1 -1
  60. package/web-dist/assets/{railroad-3IZDKUUU-u3-ja2m8.js → railroad-3IZDKUUU-B5ADtgsA.js} +1 -1
  61. package/web-dist/assets/railroad-abnf-AHOZXSZD-C5nN5q7B.js +1 -0
  62. package/web-dist/assets/railroad-ebnf-EBAXGLYW-Bmr9Qqwv.js +1 -0
  63. package/web-dist/assets/railroad-peg-LSFZ7HO6-CEoELuaR.js +1 -0
  64. package/web-dist/assets/{railroadDiagram-RFXS5EU6-PXQXCI8m.js → railroadDiagram-RFXS5EU6-CItx2rmJ.js} +1 -1
  65. package/web-dist/assets/{requirementDiagram-TGXJPOKE-CsigfYcM.js → requirementDiagram-TGXJPOKE-xR5EF8t9.js} +1 -1
  66. package/web-dist/assets/{sankeyDiagram-HTMAVEWB-CZTeOkfq.js → sankeyDiagram-HTMAVEWB-5Xc3Jm9J.js} +1 -1
  67. package/web-dist/assets/{sequenceDiagram-DBY2YBRQ-BVnCAk_N.js → sequenceDiagram-DBY2YBRQ-vKameWMa.js} +1 -1
  68. package/web-dist/assets/{stateDiagram-2N3HPSRC-ChCJipZW.js → stateDiagram-2N3HPSRC-cd0jZZvF.js} +1 -1
  69. package/web-dist/assets/stateDiagram-v2-6OUMAXLB-CxXmUa7L.js +1 -0
  70. package/web-dist/assets/{swimlanes-5IMT3BWC-DHR9HD5O.js → swimlanes-5IMT3BWC-9iMSvVuR.js} +1 -1
  71. package/web-dist/assets/swimlanesDiagram-G3AALYLV-VlGeDigP.js +8 -0
  72. package/web-dist/assets/{timeline-definition-FHXFAJF6-BZl68jCj.js → timeline-definition-FHXFAJF6-C6_2LRwZ.js} +1 -1
  73. package/web-dist/assets/{treeView-QDETBFTQ-CcWDnN_I.js → treeView-QDETBFTQ-CX8-eA8C.js} +1 -1
  74. package/web-dist/assets/{treemap-6X3UGDF4-CoPTx3oa.js → treemap-6X3UGDF4-DaUY20IG.js} +1 -1
  75. package/web-dist/assets/{vennDiagram-L72KCM5P-lrsO-4o9.js → vennDiagram-L72KCM5P-CZLt-iPN.js} +1 -1
  76. package/web-dist/assets/{wardley-OPB4EBWU-hA_IMYdR.js → wardley-OPB4EBWU-Cjp9-zMo.js} +1 -1
  77. package/web-dist/assets/{wardleyDiagram-EHGQE667-6T7WmjKn.js → wardleyDiagram-EHGQE667-BF_U8_o5.js} +1 -1
  78. package/web-dist/assets/{xychartDiagram-FW5EYKEG-BPYtf6cM.js → xychartDiagram-FW5EYKEG-CJEIPPRH.js} +1 -1
  79. package/web-dist/index.html +1 -1
  80. package/web-dist/assets/architecture-TIHT7OUA-DGkzyd6b.js +0 -1
  81. package/web-dist/assets/channel-BvYE_fQ0.js +0 -1
  82. package/web-dist/assets/classDiagram-OUVF2IWQ-BmoT0Xoa.js +0 -1
  83. package/web-dist/assets/classDiagram-v2-EOCWNBFH-BmoT0Xoa.js +0 -1
  84. package/web-dist/assets/eventmodeling-45OFAUF4-Bqo9jfNt.js +0 -1
  85. package/web-dist/assets/flowDiagram-23GEKE2U-BwssDy7H.js +0 -1
  86. package/web-dist/assets/index-YBqvcp8M.js +0 -506
  87. package/web-dist/assets/railroad-abnf-AHOZXSZD-BIa3zJb3.js +0 -1
  88. package/web-dist/assets/railroad-ebnf-EBAXGLYW-Dhv_ZRtc.js +0 -1
  89. package/web-dist/assets/railroad-peg-LSFZ7HO6-BSnPbaOy.js +0 -1
  90. package/web-dist/assets/stateDiagram-v2-6OUMAXLB-BopBzYGR.js +0 -1
  91. package/web-dist/assets/swimlanesDiagram-G3AALYLV-B3z_1cGb.js +0 -8
package/dist/dev-child.js CHANGED
@@ -4762,10 +4762,10 @@ var require_resolve_block_map = __commonJS({
4762
4762
  let offset = bm.offset;
4763
4763
  let commentEnd = null;
4764
4764
  for (const collItem of bm.items) {
4765
- const { start, key, sep: sep5, value } = collItem;
4765
+ const { start, key, sep: sep6, value } = collItem;
4766
4766
  const keyProps = resolveProps.resolveProps(start, {
4767
4767
  indicator: "explicit-key-ind",
4768
- next: key ?? sep5?.[0],
4768
+ next: key ?? sep6?.[0],
4769
4769
  offset,
4770
4770
  onError,
4771
4771
  parentIndent: bm.indent,
@@ -4779,7 +4779,7 @@ var require_resolve_block_map = __commonJS({
4779
4779
  else if ("indent" in key && key.indent !== bm.indent)
4780
4780
  onError(offset, "BAD_INDENT", startColMsg);
4781
4781
  }
4782
- if (!keyProps.anchor && !keyProps.tag && !sep5) {
4782
+ if (!keyProps.anchor && !keyProps.tag && !sep6) {
4783
4783
  commentEnd = keyProps.end;
4784
4784
  if (keyProps.comment) {
4785
4785
  if (map.comment)
@@ -4803,7 +4803,7 @@ var require_resolve_block_map = __commonJS({
4803
4803
  ctx.atKey = false;
4804
4804
  if (utilMapIncludes.mapIncludes(ctx, map.items, keyNode))
4805
4805
  onError(keyStart, "DUPLICATE_KEY", "Map keys must be unique");
4806
- const valueProps = resolveProps.resolveProps(sep5 ?? [], {
4806
+ const valueProps = resolveProps.resolveProps(sep6 ?? [], {
4807
4807
  indicator: "map-value-ind",
4808
4808
  next: value,
4809
4809
  offset: keyNode.range[2],
@@ -4819,7 +4819,7 @@ var require_resolve_block_map = __commonJS({
4819
4819
  if (ctx.options.strict && keyProps.start < valueProps.found.offset - 1024)
4820
4820
  onError(keyNode.range, "KEY_OVER_1024_CHARS", "The : indicator must be at most 1024 chars after the start of an implicit block mapping key");
4821
4821
  }
4822
- const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset, sep5, null, valueProps, onError);
4822
+ const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset, sep6, null, valueProps, onError);
4823
4823
  if (ctx.schema.compat)
4824
4824
  utilFlowIndentCheck.flowIndentCheck(bm.indent, value, onError);
4825
4825
  offset = valueNode.range[2];
@@ -4910,7 +4910,7 @@ var require_resolve_end = __commonJS({
4910
4910
  let comment = "";
4911
4911
  if (end) {
4912
4912
  let hasSpace = false;
4913
- let sep5 = "";
4913
+ let sep6 = "";
4914
4914
  for (const token of end) {
4915
4915
  const { source, type } = token;
4916
4916
  switch (type) {
@@ -4924,13 +4924,13 @@ var require_resolve_end = __commonJS({
4924
4924
  if (!comment)
4925
4925
  comment = cb;
4926
4926
  else
4927
- comment += sep5 + cb;
4928
- sep5 = "";
4927
+ comment += sep6 + cb;
4928
+ sep6 = "";
4929
4929
  break;
4930
4930
  }
4931
4931
  case "newline":
4932
4932
  if (comment)
4933
- sep5 += source;
4933
+ sep6 += source;
4934
4934
  hasSpace = true;
4935
4935
  break;
4936
4936
  default:
@@ -4973,18 +4973,18 @@ var require_resolve_flow_collection = __commonJS({
4973
4973
  let offset = fc.offset + fc.start.source.length;
4974
4974
  for (let i = 0; i < fc.items.length; ++i) {
4975
4975
  const collItem = fc.items[i];
4976
- const { start, key, sep: sep5, value } = collItem;
4976
+ const { start, key, sep: sep6, value } = collItem;
4977
4977
  const props = resolveProps.resolveProps(start, {
4978
4978
  flow: fcName,
4979
4979
  indicator: "explicit-key-ind",
4980
- next: key ?? sep5?.[0],
4980
+ next: key ?? sep6?.[0],
4981
4981
  offset,
4982
4982
  onError,
4983
4983
  parentIndent: fc.indent,
4984
4984
  startOnNewline: false
4985
4985
  });
4986
4986
  if (!props.found) {
4987
- if (!props.anchor && !props.tag && !sep5 && !value) {
4987
+ if (!props.anchor && !props.tag && !sep6 && !value) {
4988
4988
  if (i === 0 && props.comma)
4989
4989
  onError(props.comma, "UNEXPECTED_TOKEN", `Unexpected , in ${fcName}`);
4990
4990
  else if (i < fc.items.length - 1)
@@ -5038,8 +5038,8 @@ var require_resolve_flow_collection = __commonJS({
5038
5038
  }
5039
5039
  }
5040
5040
  }
5041
- if (!isMap && !sep5 && !props.found) {
5042
- const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, sep5, null, props, onError);
5041
+ if (!isMap && !sep6 && !props.found) {
5042
+ const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, sep6, null, props, onError);
5043
5043
  coll.items.push(valueNode);
5044
5044
  offset = valueNode.range[2];
5045
5045
  if (isBlock(value))
@@ -5051,7 +5051,7 @@ var require_resolve_flow_collection = __commonJS({
5051
5051
  if (isBlock(key))
5052
5052
  onError(keyNode.range, "BLOCK_IN_FLOW", blockMsg);
5053
5053
  ctx.atKey = false;
5054
- const valueProps = resolveProps.resolveProps(sep5 ?? [], {
5054
+ const valueProps = resolveProps.resolveProps(sep6 ?? [], {
5055
5055
  flow: fcName,
5056
5056
  indicator: "map-value-ind",
5057
5057
  next: value,
@@ -5062,8 +5062,8 @@ var require_resolve_flow_collection = __commonJS({
5062
5062
  });
5063
5063
  if (valueProps.found) {
5064
5064
  if (!isMap && !props.found && ctx.options.strict) {
5065
- if (sep5)
5066
- for (const st of sep5) {
5065
+ if (sep6)
5066
+ for (const st of sep6) {
5067
5067
  if (st === valueProps.found)
5068
5068
  break;
5069
5069
  if (st.type === "newline") {
@@ -5080,7 +5080,7 @@ var require_resolve_flow_collection = __commonJS({
5080
5080
  else
5081
5081
  onError(valueProps.start, "MISSING_CHAR", `Missing , or : between ${fcName} items`);
5082
5082
  }
5083
- const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep5, null, valueProps, onError) : null;
5083
+ const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep6, null, valueProps, onError) : null;
5084
5084
  if (valueNode) {
5085
5085
  if (isBlock(value))
5086
5086
  onError(valueNode.range, "BLOCK_IN_FLOW", blockMsg);
@@ -5260,7 +5260,7 @@ var require_resolve_block_scalar = __commonJS({
5260
5260
  chompStart = i + 1;
5261
5261
  }
5262
5262
  let value = "";
5263
- let sep5 = "";
5263
+ let sep6 = "";
5264
5264
  let prevMoreIndented = false;
5265
5265
  for (let i = 0; i < contentStart; ++i)
5266
5266
  value += lines[i][0].slice(trimIndent) + "\n";
@@ -5277,24 +5277,24 @@ var require_resolve_block_scalar = __commonJS({
5277
5277
  indent = "";
5278
5278
  }
5279
5279
  if (type === Scalar.Scalar.BLOCK_LITERAL) {
5280
- value += sep5 + indent.slice(trimIndent) + content;
5281
- sep5 = "\n";
5280
+ value += sep6 + indent.slice(trimIndent) + content;
5281
+ sep6 = "\n";
5282
5282
  } else if (indent.length > trimIndent || content[0] === " ") {
5283
- if (sep5 === " ")
5284
- sep5 = "\n";
5285
- else if (!prevMoreIndented && sep5 === "\n")
5286
- sep5 = "\n\n";
5287
- value += sep5 + indent.slice(trimIndent) + content;
5288
- sep5 = "\n";
5283
+ if (sep6 === " ")
5284
+ sep6 = "\n";
5285
+ else if (!prevMoreIndented && sep6 === "\n")
5286
+ sep6 = "\n\n";
5287
+ value += sep6 + indent.slice(trimIndent) + content;
5288
+ sep6 = "\n";
5289
5289
  prevMoreIndented = true;
5290
5290
  } else if (content === "") {
5291
- if (sep5 === "\n")
5291
+ if (sep6 === "\n")
5292
5292
  value += "\n";
5293
5293
  else
5294
- sep5 = "\n";
5294
+ sep6 = "\n";
5295
5295
  } else {
5296
- value += sep5 + content;
5297
- sep5 = " ";
5296
+ value += sep6 + content;
5297
+ sep6 = " ";
5298
5298
  prevMoreIndented = false;
5299
5299
  }
5300
5300
  }
@@ -5476,25 +5476,25 @@ var require_resolve_flow_scalar = __commonJS({
5476
5476
  if (!match2)
5477
5477
  return source;
5478
5478
  let res = match2[1];
5479
- let sep5 = " ";
5479
+ let sep6 = " ";
5480
5480
  let pos = first.lastIndex;
5481
5481
  line.lastIndex = pos;
5482
5482
  while (match2 = line.exec(source)) {
5483
5483
  if (match2[1] === "") {
5484
- if (sep5 === "\n")
5485
- res += sep5;
5484
+ if (sep6 === "\n")
5485
+ res += sep6;
5486
5486
  else
5487
- sep5 = "\n";
5487
+ sep6 = "\n";
5488
5488
  } else {
5489
- res += sep5 + match2[1];
5490
- sep5 = " ";
5489
+ res += sep6 + match2[1];
5490
+ sep6 = " ";
5491
5491
  }
5492
5492
  pos = line.lastIndex;
5493
5493
  }
5494
5494
  const last = /[ \t]*(.*)/sy;
5495
5495
  last.lastIndex = pos;
5496
5496
  match2 = last.exec(source);
5497
- return res + sep5 + (match2?.[1] ?? "");
5497
+ return res + sep6 + (match2?.[1] ?? "");
5498
5498
  }
5499
5499
  function doubleQuotedValue(source, onError) {
5500
5500
  let res = "";
@@ -6304,14 +6304,14 @@ var require_cst_stringify = __commonJS({
6304
6304
  }
6305
6305
  }
6306
6306
  }
6307
- function stringifyItem({ start, key, sep: sep5, value }) {
6307
+ function stringifyItem({ start, key, sep: sep6, value }) {
6308
6308
  let res = "";
6309
6309
  for (const st of start)
6310
6310
  res += st.source;
6311
6311
  if (key)
6312
6312
  res += stringifyToken(key);
6313
- if (sep5)
6314
- for (const st of sep5)
6313
+ if (sep6)
6314
+ for (const st of sep6)
6315
6315
  res += st.source;
6316
6316
  if (value)
6317
6317
  res += stringifyToken(value);
@@ -7478,18 +7478,18 @@ var require_parser = __commonJS({
7478
7478
  if (this.type === "map-value-ind") {
7479
7479
  const prev = getPrevProps(this.peek(2));
7480
7480
  const start = getFirstKeyStartProps(prev);
7481
- let sep5;
7481
+ let sep6;
7482
7482
  if (scalar.end) {
7483
- sep5 = scalar.end;
7484
- sep5.push(this.sourceToken);
7483
+ sep6 = scalar.end;
7484
+ sep6.push(this.sourceToken);
7485
7485
  delete scalar.end;
7486
7486
  } else
7487
- sep5 = [this.sourceToken];
7487
+ sep6 = [this.sourceToken];
7488
7488
  const map = {
7489
7489
  type: "block-map",
7490
7490
  offset: scalar.offset,
7491
7491
  indent: scalar.indent,
7492
- items: [{ start, key: scalar, sep: sep5 }]
7492
+ items: [{ start, key: scalar, sep: sep6 }]
7493
7493
  };
7494
7494
  this.onKeyLine = true;
7495
7495
  this.stack[this.stack.length - 1] = map;
@@ -7642,15 +7642,15 @@ var require_parser = __commonJS({
7642
7642
  } else if (isFlowToken(it.key) && !includesToken(it.sep, "newline")) {
7643
7643
  const start2 = getFirstKeyStartProps(it.start);
7644
7644
  const key = it.key;
7645
- const sep5 = it.sep;
7646
- sep5.push(this.sourceToken);
7645
+ const sep6 = it.sep;
7646
+ sep6.push(this.sourceToken);
7647
7647
  delete it.key;
7648
7648
  delete it.sep;
7649
7649
  this.stack.push({
7650
7650
  type: "block-map",
7651
7651
  offset: this.offset,
7652
7652
  indent: this.indent,
7653
- items: [{ start: start2, key, sep: sep5 }]
7653
+ items: [{ start: start2, key, sep: sep6 }]
7654
7654
  });
7655
7655
  } else if (start.length > 0) {
7656
7656
  it.sep = it.sep.concat(start, this.sourceToken);
@@ -7844,13 +7844,13 @@ var require_parser = __commonJS({
7844
7844
  const prev = getPrevProps(parent);
7845
7845
  const start = getFirstKeyStartProps(prev);
7846
7846
  fixFlowSeqItems(fc);
7847
- const sep5 = fc.end.splice(1, fc.end.length);
7848
- sep5.push(this.sourceToken);
7847
+ const sep6 = fc.end.splice(1, fc.end.length);
7848
+ sep6.push(this.sourceToken);
7849
7849
  const map = {
7850
7850
  type: "block-map",
7851
7851
  offset: fc.offset,
7852
7852
  indent: fc.indent,
7853
- items: [{ start, key: fc, sep: sep5 }]
7853
+ items: [{ start, key: fc, sep: sep6 }]
7854
7854
  };
7855
7855
  this.onKeyLine = true;
7856
7856
  this.stack[this.stack.length - 1] = map;
@@ -15746,11 +15746,25 @@ async function ghInstalled() {
15746
15746
  }
15747
15747
  }
15748
15748
  async function ghAuthed() {
15749
+ if (Date.now() < ghAuthedUntil) return true;
15750
+ if (ghAuthedInFlight) return await ghAuthedInFlight;
15751
+ const probe = (async () => {
15752
+ const authed = await (async () => {
15753
+ try {
15754
+ await gh(["auth", "status", "--active"]);
15755
+ return true;
15756
+ } catch {
15757
+ return await ghHasToken();
15758
+ }
15759
+ })();
15760
+ if (authed) ghAuthedUntil = Date.now() + GH_AUTHED_TTL_MS;
15761
+ return authed;
15762
+ })();
15763
+ ghAuthedInFlight = probe;
15749
15764
  try {
15750
- await gh(["auth", "status", "--active"]);
15751
- return true;
15752
- } catch {
15753
- return await ghHasToken();
15765
+ return await probe;
15766
+ } finally {
15767
+ ghAuthedInFlight = null;
15754
15768
  }
15755
15769
  }
15756
15770
  async function ghHasToken() {
@@ -16044,7 +16058,7 @@ function effectiveTemplate(custom2) {
16044
16058
  if (custom2 && custom2.trim().length > 0) return custom2;
16045
16059
  return DEFAULT_GITHUB_PROMPT;
16046
16060
  }
16047
- var pexec, GH_TIMEOUT, GH_MAXBUF, SEARCH_SORT, SEARCH_RESULT_WINDOW, LINKED_PR_CHUNK, GITHUB_PAGE_SIZE, BODY_CAP, DEFAULT_GITHUB_PROMPT;
16061
+ var pexec, GH_TIMEOUT, GH_MAXBUF, GH_AUTHED_TTL_MS, ghAuthedUntil, ghAuthedInFlight, SEARCH_SORT, SEARCH_RESULT_WINDOW, LINKED_PR_CHUNK, GITHUB_PAGE_SIZE, BODY_CAP, DEFAULT_GITHUB_PROMPT;
16048
16062
  var init_github = __esm({
16049
16063
  "packages/server/src/github.ts"() {
16050
16064
  "use strict";
@@ -16052,6 +16066,9 @@ var init_github = __esm({
16052
16066
  pexec = promisify(execFile);
16053
16067
  GH_TIMEOUT = 8e3;
16054
16068
  GH_MAXBUF = 16 * 1024 * 1024;
16069
+ GH_AUTHED_TTL_MS = 3e4;
16070
+ ghAuthedUntil = 0;
16071
+ ghAuthedInFlight = null;
16055
16072
  SEARCH_SORT = {
16056
16073
  reactions: "reactions",
16057
16074
  recent: "updated"
@@ -18631,6 +18648,15 @@ function slugMintedFromTitle(slug, title) {
18631
18648
  const derived = slugify(title);
18632
18649
  return derived === slug || derived === slug.replace(/-\d+$/, "");
18633
18650
  }
18651
+ function groupBySlug(rows) {
18652
+ const bySlug = /* @__PURE__ */ new Map();
18653
+ for (const row of rows) {
18654
+ const bucket = bySlug.get(row.thread_slug);
18655
+ if (bucket) bucket.push(row);
18656
+ else bySlug.set(row.thread_slug, [row]);
18657
+ }
18658
+ return bySlug;
18659
+ }
18634
18660
  function ensureStorageSchema(db) {
18635
18661
  db.exec(STORAGE_SCHEMA);
18636
18662
  for (const column of ["pinned_at TEXT"]) {
@@ -18982,6 +19008,9 @@ function createStorage(source, projectId) {
18982
19008
  const armedTimersBySlugStmt = scope.prepare(
18983
19009
  "SELECT * FROM thread_timer WHERE project_id = @project_id AND thread_slug = ? AND state = 'armed' ORDER BY fire_at, id"
18984
19010
  );
19011
+ const armedTimersStmt = scope.prepare(
19012
+ "SELECT * FROM thread_timer WHERE project_id = @project_id AND state = 'armed' ORDER BY fire_at, id"
19013
+ );
18985
19014
  const timerByIdStmt = scope.prepare("SELECT * FROM thread_timer WHERE project_id = @project_id AND id = ?");
18986
19015
  const dueTimersStmt = scope.prepare(
18987
19016
  "SELECT * FROM thread_timer WHERE project_id = @project_id AND state = 'armed' AND fire_at <= ? ORDER BY fire_at, id"
@@ -19081,6 +19110,9 @@ function createStorage(source, projectId) {
19081
19110
  const openThreadQuestionsStmt = scope.prepare(
19082
19111
  "SELECT * FROM thread_question WHERE project_id = @project_id AND state = 'open' ORDER BY asked_at, rowid"
19083
19112
  );
19113
+ const allThreadQuestionsStmt = scope.prepare(
19114
+ "SELECT * FROM thread_question WHERE project_id = @project_id ORDER BY asked_at, rowid"
19115
+ );
19084
19116
  const answerThreadQuestionStmt = scope.prepare(`
19085
19117
  UPDATE thread_question SET state = 'answered', answer = ?, settled_at = ?
19086
19118
  WHERE project_id = @project_id AND id = ? AND state = 'open'
@@ -19106,6 +19138,9 @@ function createStorage(source, projectId) {
19106
19138
  ON CONFLICT(project_id, thread_slug) DO UPDATE SET body = excluded.body, done_at = excluded.done_at
19107
19139
  `);
19108
19140
  const getThreadDoneStmt = scope.prepare("SELECT body, done_at FROM thread_done WHERE project_id = @project_id AND thread_slug = ?");
19141
+ const allThreadDoneStmt = scope.prepare(
19142
+ "SELECT thread_slug, body, done_at FROM thread_done WHERE project_id = @project_id"
19143
+ );
19109
19144
  const clearThreadDoneStmt = scope.prepare("DELETE FROM thread_done WHERE project_id = @project_id AND thread_slug = ?");
19110
19145
  const clearExpiredSnoozesStmt = scope.prepare(`
19111
19146
  UPDATE session SET snoozed_until = NULL
@@ -19600,6 +19635,9 @@ function createStorage(source, projectId) {
19600
19635
  resetParkBumps: (slug) => void resetParkBumpsStmt.run(slug),
19601
19636
  armPrWatch: (watch2) => void armPrWatchStmt.run(watch2),
19602
19637
  listPrWatches: (slug, opts) => (opts?.armedOnly ? armedPrWatchesBySlugStmt : prWatchesBySlugStmt).all(slug),
19638
+ // Grouped off `armedPrWatchesStmt` — the scheduler's own whole-project read, which already carries
19639
+ // the identical `state = 'armed'` predicate and `created_at, id` order the per-slug statement uses.
19640
+ armedPrWatchesBySlug: () => groupBySlug(armedPrWatchesStmt.all()),
19603
19641
  getPrWatch: (id) => prWatchByIdStmt.get(id),
19604
19642
  armedPrWatches: () => armedPrWatchesStmt.all(),
19605
19643
  expiredPrWatches: (nowMs) => expiredPrWatchesStmt.all(nowMs),
@@ -19617,6 +19655,9 @@ function createStorage(source, projectId) {
19617
19655
  return threadWatchByIdStmt.get(w.id);
19618
19656
  },
19619
19657
  listThreadWatches: (slug, opts) => (opts?.armedOnly ? armedThreadWatchesBySlugStmt : threadWatchesBySlugStmt).all(slug),
19658
+ // Grouped off `armedThreadWatchesStmt`, for the same reason as the PR watchers above: it is already
19659
+ // the identical predicate and order, asked of the whole project instead of one slug.
19660
+ armedThreadWatchesBySlug: () => groupBySlug(armedThreadWatchesStmt.all()),
19620
19661
  getThreadWatch: (id) => threadWatchByIdStmt.get(id),
19621
19662
  expiredThreadWatches: (nowMs) => expiredThreadWatchesStmt.all(nowMs),
19622
19663
  armedThreadWatches: () => armedThreadWatchesStmt.all(),
@@ -19625,6 +19666,7 @@ function createStorage(source, projectId) {
19625
19666
  return threadQuestionByIdStmt.get(q.id);
19626
19667
  },
19627
19668
  listThreadQuestions: (slug, opts) => (opts?.openOnly ? openThreadQuestionsBySlugStmt : threadQuestionsBySlugStmt).all(slug),
19669
+ threadQuestionsBySlug: () => groupBySlug(allThreadQuestionsStmt.all()),
19628
19670
  getThreadQuestion: (id) => threadQuestionByIdStmt.get(id),
19629
19671
  openThreadQuestions: () => openThreadQuestionsStmt.all(),
19630
19672
  answerThreadQuestion: (id, answer, atMs) => answerThreadQuestionStmt.run(answer, atMs, id).changes === 1,
@@ -19639,11 +19681,19 @@ function createStorage(source, projectId) {
19639
19681
  const row = getThreadDoneStmt.get(slug);
19640
19682
  return row ? { body: row.body, doneAt: row.done_at } : void 0;
19641
19683
  },
19684
+ // The same ms→`doneAt` mapping as `getThreadDone`, applied once per row instead of once per call,
19685
+ // so the board reads the identical shape out of the map that it read out of the single-row call.
19686
+ threadDoneBySlug: () => {
19687
+ const bySlug = /* @__PURE__ */ new Map();
19688
+ for (const row of allThreadDoneStmt.all()) bySlug.set(row.thread_slug, { body: row.body, doneAt: row.done_at });
19689
+ return bySlug;
19690
+ },
19642
19691
  clearThreadDone: (slug) => clearThreadDoneStmt.run(slug).changes > 0,
19643
19692
  dropThreadWatch: (slug, id, settledAtMs) => dropThreadWatchStmt.run(settledAtMs, id, slug).changes === 1,
19644
19693
  settleThreadWatch: (id, settledAtMs, state = "settled") => settleThreadWatchStmt.run(state, settledAtMs, id).changes === 1,
19645
19694
  armThreadTimer: (timer) => void armTimerStmt.run(timer),
19646
19695
  listThreadTimers: (slug, opts) => (opts?.armedOnly ? armedTimersBySlugStmt : timersBySlugStmt).all(slug),
19696
+ armedThreadTimersBySlug: () => groupBySlug(armedTimersStmt.all()),
19647
19697
  getThreadTimer: (id) => timerByIdStmt.get(id),
19648
19698
  dueThreadTimers: (nowMs) => dueTimersStmt.all(nowMs),
19649
19699
  cancelThreadTimer: (slug, id, settledAtMs) => cancelTimerStmt.run(settledAtMs, id, slug).changes === 1,
@@ -22696,20 +22746,41 @@ var init_tail_cache = __esm({
22696
22746
 
22697
22747
  // packages/server/src/tailer.ts
22698
22748
  import { statSync as statSync8, openSync as openSync10, readSync as readSync4, closeSync as closeSync9, readdirSync as readdirSync5, realpathSync as realpathSync5, mkdirSync as mkdirSync10, writeFileSync as writeFileSync8, readFileSync as readFileSync12, existsSync as existsSync5 } from "node:fs";
22699
- import { execFileSync as execFileSync4 } from "node:child_process";
22749
+ import { execFile as execFile2 } from "node:child_process";
22750
+ import { promisify as promisify2 } from "node:util";
22700
22751
  import { basename as basename4, join as join18 } from "node:path";
22701
22752
  import { homedir as homedir7 } from "node:os";
22702
- function probeShellAlive(outputFile) {
22703
- if (!existsSync5(outputFile)) return void 0;
22753
+ async function probeShellsAlive(outputFiles) {
22754
+ const verdicts = /* @__PURE__ */ new Map();
22755
+ const live = [];
22756
+ for (const file of outputFiles) {
22757
+ if (!existsSync5(file)) {
22758
+ verdicts.set(file, void 0);
22759
+ continue;
22760
+ }
22761
+ try {
22762
+ live.push({ requested: file, real: realpathSync5(file) });
22763
+ } catch {
22764
+ verdicts.set(file, void 0);
22765
+ }
22766
+ }
22767
+ if (live.length === 0) return verdicts;
22768
+ let stdout = "";
22704
22769
  try {
22705
- const out = execFileSync4("lsof", ["-t", "--", outputFile], { encoding: "utf8", timeout: 4e3, stdio: ["ignore", "pipe", "ignore"] });
22706
- return out.trim().length > 0;
22770
+ stdout = (await execFileAsync("lsof", ["-F", "pn", "--", ...live.map((f) => f.real)], { encoding: "utf8", timeout: 8e3 })).stdout;
22707
22771
  } catch (err) {
22708
22772
  const e = err;
22709
- if (e.code === "ENOENT") return void 0;
22710
- if (e.status === 1) return false;
22711
- return void 0;
22773
+ const ran = typeof e.code === "number" && !e.killed;
22774
+ if (!ran) {
22775
+ for (const f of live) verdicts.set(f.requested, void 0);
22776
+ return verdicts;
22777
+ }
22778
+ stdout = e.stdout ?? "";
22712
22779
  }
22780
+ const held = /* @__PURE__ */ new Set();
22781
+ for (const line of stdout.split("\n")) if (line.startsWith("n")) held.add(line.slice(1));
22782
+ for (const f of live) verdicts.set(f.requested, held.has(f.real));
22783
+ return verdicts;
22713
22784
  }
22714
22785
  function activityMinute(at) {
22715
22786
  if (!at) return "";
@@ -23906,16 +23977,48 @@ ${ask}`;
23906
23977
  return void 0;
23907
23978
  }
23908
23979
  const shellAliveCache = /* @__PURE__ */ new Map();
23980
+ const shellProbeWanted = /* @__PURE__ */ new Set();
23981
+ let shellProbeInFlight = false;
23982
+ let shellProbeArmed;
23983
+ function armShellProbeFlush() {
23984
+ if (shellProbeArmed) return;
23985
+ shellProbeArmed = setTimeout(() => {
23986
+ shellProbeArmed = void 0;
23987
+ flushShellProbes();
23988
+ }, 0);
23989
+ shellProbeArmed.unref?.();
23990
+ }
23991
+ function flushShellProbes() {
23992
+ if (shellProbeInFlight || shellProbeWanted.size === 0) return;
23993
+ const batch = [...shellProbeWanted];
23994
+ shellProbeWanted.clear();
23995
+ shellProbeInFlight = true;
23996
+ void probeShellsAlive(batch).then((verdicts) => {
23997
+ for (const [file, alive] of verdicts) {
23998
+ if (alive === void 0) continue;
23999
+ shellAliveCache.set(file, { at: now(), alive });
24000
+ }
24001
+ if (verdicts.size > 0) deps.onChange();
24002
+ }).catch(() => {
24003
+ }).finally(() => {
24004
+ shellProbeInFlight = false;
24005
+ });
24006
+ }
23909
24007
  function shellIsGone(e) {
23910
24008
  if (!e.outputFile) return false;
23911
24009
  const started = Date.parse(e.startedAt);
23912
24010
  if (!Number.isFinite(started) || now() - started < SHELL_PROBE_GRACE_MS) return false;
23913
24011
  const cached2 = shellAliveCache.get(e.outputFile);
23914
24012
  if (cached2 && (cached2.alive === false || now() - cached2.at < SHELL_PROBE_TTL_MS)) return !cached2.alive;
23915
- const alive = (deps.shellAlive ?? probeShellAlive)(e.outputFile);
23916
- if (alive === void 0) return false;
23917
- shellAliveCache.set(e.outputFile, { at: now(), alive });
23918
- return !alive;
24013
+ if (deps.shellAlive) {
24014
+ const alive = deps.shellAlive(e.outputFile);
24015
+ if (alive === void 0) return false;
24016
+ shellAliveCache.set(e.outputFile, { at: now(), alive });
24017
+ return !alive;
24018
+ }
24019
+ shellProbeWanted.add(e.outputFile);
24020
+ armShellProbeFlush();
24021
+ return false;
23919
24022
  }
23920
24023
  function backgroundShellLookup(slug, id) {
23921
24024
  const state = states.get(slug);
@@ -24396,14 +24499,27 @@ ${detail2}
24396
24499
  let primedRows = 0;
24397
24500
  const tickStartedMs = monotonicNow();
24398
24501
  primeIncomplete = false;
24502
+ const primeDeferred = (row) => (
24503
+ // Yield the slot to a still-cold visible row — but never at the cost of the forward-progress
24504
+ // guarantee above. `primedRows > 0` keeps the archive advancing by at least one row per tick
24505
+ // even if a visible row were somehow to stay cold indefinitely, so deferral can never become
24506
+ // starvation. The visible row still primes on this same tick; it just is not necessarily first.
24507
+ coldVisibleRow && primedRows > 0 && rowIsArchived(row) || primedRows >= MAX_PRIME_ROWS_PER_TICK || primedRows > 0 && monotonicNow() - tickStartedMs > PRIME_BUDGET_MS
24508
+ );
24399
24509
  for (const row of rows) {
24400
24510
  if (primeProgress && primed % PRIME_PROGRESS_EVERY === 0) primeProgress(primed, rows.length);
24401
24511
  primed++;
24402
24512
  const backend = resolveBackend(row.backend);
24403
24513
  const nativeId = row.agent_session_id ?? row.transcript_id ?? row.session_id;
24404
- let state = states.get(row.slug);
24514
+ const known = states.get(row.slug);
24405
24515
  const runtimeGeneration = row.runtime_generation ?? 0;
24406
- if (!state || state.sessionId !== row.session_id || state.nativeSessionId !== nativeId || state.runtimeGeneration !== runtimeGeneration) {
24516
+ const keepable = known !== void 0 && known.sessionId === row.session_id && known.nativeSessionId === nativeId && known.runtimeGeneration === runtimeGeneration;
24517
+ let state = keepable ? known : void 0;
24518
+ if (!state && primeDeferred(row)) {
24519
+ primeIncomplete = true;
24520
+ continue;
24521
+ }
24522
+ if (!state) {
24407
24523
  const path = backend.transcriptPath(nativeId) ?? join18(logDir, `${nativeId}.jsonl`);
24408
24524
  state = newTailState(row.slug, row.session_id, path, false, nativeId, runtimeGeneration);
24409
24525
  state.dismissedOps = deps.storage.retiredOps(row.slug, row.session_id);
@@ -24417,13 +24533,7 @@ ${detail2}
24417
24533
  const prevNoTranscript = state.noTranscript;
24418
24534
  if (row.backend !== "codex" && !resolveTranscript(state, row, nowMs)) continue;
24419
24535
  if (!state.primed) {
24420
- if (
24421
- // Yield the slot to a still-cold visible row — but never at the cost of the forward-progress
24422
- // guarantee below. `primedRows > 0` keeps the archive advancing by at least one row per tick
24423
- // even if a visible row were somehow to stay cold indefinitely, so deferral can never become
24424
- // starvation. The visible row still primes on this same tick; it just is not necessarily first.
24425
- coldVisibleRow && primedRows > 0 && rowIsArchived(row) || primedRows >= MAX_PRIME_ROWS_PER_TICK || primedRows > 0 && monotonicNow() - tickStartedMs > PRIME_BUDGET_MS
24426
- ) {
24536
+ if (primeDeferred(row)) {
24427
24537
  primeIncomplete = true;
24428
24538
  continue;
24429
24539
  }
@@ -24728,7 +24838,7 @@ ${detail2}
24728
24838
  stopped = false;
24729
24839
  primeProgress = onPrimeProgress;
24730
24840
  try {
24731
- tick();
24841
+ tickWithBudget();
24732
24842
  } finally {
24733
24843
  primeProgress = void 0;
24734
24844
  }
@@ -24753,7 +24863,7 @@ function landsAfterRead(eventAt, lastReadAt) {
24753
24863
  if (!Number.isFinite(e) || !Number.isFinite(r)) return true;
24754
24864
  return e > r;
24755
24865
  }
24756
- var IDLE_BACKSTOP_MS, RUNTIME_CHASE_MAX, POLL_MS2, MAX_PRIME_ROWS_PER_TICK, PRIME_BUDGET_MS, TRANSCRIPT_READ_WINDOW, EMPTY_BUFFER, MAX_POLL_MS, SUBAGENT_STALE_MS, SHELL_PROBE_TTL_MS, SHELL_PROBE_GRACE_MS, FOREIGN_FRESH_MS, FOREIGN_MAX, FOREIGN_SCAN_EVERY, CACHE_FLUSH_MS, PRIME_PROGRESS_EVERY, DISCOVER_RETRY_MS, DISCOVER_RETRY_MAX_MS, RETAINED_SUBAGENTS_MAX, RETAINED_SHELLS_MAX, DESCENDANT_TERMINALS_MAX, PENDING_RESUMES_MAX, PENDING_SHELLS_MAX, RESUME_REPLAY_SLACK_MS, FIRST_USER_TEXT_MAX, QUESTION_BLOCK_RE, SIGNAL_FENCE_RE, FENCE_BODY_MAX, LAUNCH_ACK_RE, AUTO_BACKGROUND_ACK_RE, DESCENDANT_SIDECAR_MAX, DESCENDANT_NOTIFY_GRACE_MS, MAX_OWNED_TOOL_USE_IDS, BROKER_LIVENESS_TTL_MS, UNRESTORED_TAIL_FIELDS;
24866
+ var IDLE_BACKSTOP_MS, RUNTIME_CHASE_MAX, POLL_MS2, MAX_PRIME_ROWS_PER_TICK, PRIME_BUDGET_MS, TRANSCRIPT_READ_WINDOW, EMPTY_BUFFER, MAX_POLL_MS, SUBAGENT_STALE_MS, SHELL_PROBE_TTL_MS, SHELL_PROBE_GRACE_MS, execFileAsync, FOREIGN_FRESH_MS, FOREIGN_MAX, FOREIGN_SCAN_EVERY, CACHE_FLUSH_MS, PRIME_PROGRESS_EVERY, DISCOVER_RETRY_MS, DISCOVER_RETRY_MAX_MS, RETAINED_SUBAGENTS_MAX, RETAINED_SHELLS_MAX, DESCENDANT_TERMINALS_MAX, PENDING_RESUMES_MAX, PENDING_SHELLS_MAX, RESUME_REPLAY_SLACK_MS, FIRST_USER_TEXT_MAX, QUESTION_BLOCK_RE, SIGNAL_FENCE_RE, FENCE_BODY_MAX, LAUNCH_ACK_RE, AUTO_BACKGROUND_ACK_RE, DESCENDANT_SIDECAR_MAX, DESCENDANT_NOTIFY_GRACE_MS, MAX_OWNED_TOOL_USE_IDS, BROKER_LIVENESS_TTL_MS, UNRESTORED_TAIL_FIELDS;
24757
24867
  var init_tailer = __esm({
24758
24868
  "packages/server/src/tailer.ts"() {
24759
24869
  "use strict";
@@ -24786,6 +24896,7 @@ var init_tailer = __esm({
24786
24896
  SUBAGENT_STALE_MS = 15 * 6e4;
24787
24897
  SHELL_PROBE_TTL_MS = 3e4;
24788
24898
  SHELL_PROBE_GRACE_MS = 6e4;
24899
+ execFileAsync = promisify2(execFile2);
24789
24900
  FOREIGN_FRESH_MS = 24 * 60 * 6e4;
24790
24901
  FOREIGN_MAX = 20;
24791
24902
  FOREIGN_SCAN_EVERY = 5;
@@ -30679,11 +30790,11 @@ var init_codex_app_server = __esm({
30679
30790
  init_logging();
30680
30791
  CODEX_APP_SERVER_PROVIDER = "codex-app-server";
30681
30792
  CODEX_NATIVE_LISTEN_FLAG = "FRIZZ_CODEX_NATIVE_LISTEN";
30682
- CODEX_APP_SERVER_SUPPORTED_VERSION = "0.146.0";
30793
+ CODEX_APP_SERVER_SUPPORTED_VERSION = "0.153.2";
30683
30794
  CODEX_APP_SERVER_PROTOCOL_REVISION = Object.freeze({
30684
30795
  packageVersion: CODEX_APP_SERVER_SUPPORTED_VERSION,
30685
- sourceTag: "rust-v0.146.0",
30686
- sourceCommit: "e363b08c9175ac1cbe5893615dd2cb9ddf95043b"
30796
+ sourceTag: "rust-v0.153.2",
30797
+ sourceCommit: "657a993cbee87acf52d14b758ce49dbd46d1b8eb"
30687
30798
  });
30688
30799
  PROTOCOL_FINGERPRINT = [
30689
30800
  CODEX_APP_SERVER_PROTOCOL_REVISION.sourceTag,
@@ -33163,8 +33274,8 @@ import { join as join23 } from "node:path";
33163
33274
  import { homedir as homedir9, platform } from "node:os";
33164
33275
  import { createHash as createHash10 } from "node:crypto";
33165
33276
  import { mkdir, readFile, rename, rm, stat, writeFile } from "node:fs/promises";
33166
- import { execFile as execFile2 } from "node:child_process";
33167
- import { promisify as promisify2 } from "node:util";
33277
+ import { execFile as execFile3 } from "node:child_process";
33278
+ import { promisify as promisify3 } from "node:util";
33168
33279
  function claudeConfigDir() {
33169
33280
  const override = process.env.CLAUDE_CONFIG_DIR;
33170
33281
  return override && override.trim() ? override : join23(homedir9(), ".claude");
@@ -33185,7 +33296,7 @@ function tokenFromCredentialsJson(raw2) {
33185
33296
  async function readKeychainToken() {
33186
33297
  if (platform() !== "darwin") return void 0;
33187
33298
  try {
33188
- const { stdout } = await execFileAsync("security", ["find-generic-password", "-s", "Claude Code-credentials", "-w"], {
33299
+ const { stdout } = await execFileAsync2("security", ["find-generic-password", "-s", "Claude Code-credentials", "-w"], {
33189
33300
  encoding: "utf8",
33190
33301
  timeout: 4e3
33191
33302
  });
@@ -33313,7 +33424,7 @@ async function acquireLock(path) {
33313
33424
  }
33314
33425
  }
33315
33426
  async function runClaudeUsage(claudeBin) {
33316
- const { stdout } = await execFileAsync(
33427
+ const { stdout } = await execFileAsync2(
33317
33428
  // Never a bare name: on Windows `execFile("claude")` is ENOENT and `execFile("claude.cmd")` is
33318
33429
  // EINVAL (node refuses .cmd/.bat without a shell since CVE-2024-27980), so this reader could
33319
33430
  // never reach the CLI there and every quota refresh threw. See auth-status.ts for the measurement.
@@ -33520,13 +33631,13 @@ async function readClaudeQuota(claudeBin = "claude", deps = {}, options = {}) {
33520
33631
  });
33521
33632
  }
33522
33633
  }
33523
- var execFileAsync, USAGE_URL, OAUTH_BETA, USER_AGENT, ENDPOINT_TIMEOUT_MS, OK_TTL_MS, FAIL_TTL_MS, STALE_MAX_AGE_MS, CLI_TIMEOUT_MS, LOCK_STALE_MS, LOCK_WAIT_MS, LOCK_POLL_MS2, LINE_WINDOWS, MONTH_INDEX, backgroundRefreshes;
33634
+ var execFileAsync2, USAGE_URL, OAUTH_BETA, USER_AGENT, ENDPOINT_TIMEOUT_MS, OK_TTL_MS, FAIL_TTL_MS, STALE_MAX_AGE_MS, CLI_TIMEOUT_MS, LOCK_STALE_MS, LOCK_WAIT_MS, LOCK_POLL_MS2, LINE_WINDOWS, MONTH_INDEX, backgroundRefreshes;
33524
33635
  var init_claude_quota = __esm({
33525
33636
  "packages/server/src/backend/claude-quota.ts"() {
33526
33637
  "use strict";
33527
33638
  init_frizz_paths();
33528
33639
  init_claude_broker_host();
33529
- execFileAsync = promisify2(execFile2);
33640
+ execFileAsync2 = promisify3(execFile3);
33530
33641
  USAGE_URL = "https://api.anthropic.com/api/oauth/usage";
33531
33642
  OAUTH_BETA = "oauth-2025-04-20";
33532
33643
  USER_AGENT = "claude-code/2.0.0";
@@ -33631,10 +33742,10 @@ var init_quota = __esm({
33631
33742
  });
33632
33743
 
33633
33744
  // packages/server/src/frizz.ts
33634
- import { execFile as execFile3 } from "node:child_process";
33745
+ import { execFile as execFile4 } from "node:child_process";
33635
33746
  import { lstatSync as lstatSync2, realpathSync as realpathSync6 } from "node:fs";
33636
33747
  import { basename as basename5, dirname as dirname9, join as join24, resolve as resolve5 } from "node:path";
33637
- import { promisify as promisify3 } from "node:util";
33748
+ import { promisify as promisify4 } from "node:util";
33638
33749
  function frizzScriptsDir() {
33639
33750
  if (process.env.FRIZZ_SCRIPTS_DIR) return process.env.FRIZZ_SCRIPTS_DIR;
33640
33751
  return resolve5(import.meta.dirname, "..", "..", "..", "board");
@@ -33691,7 +33802,7 @@ var init_frizz = __esm({
33691
33802
  "packages/server/src/frizz.ts"() {
33692
33803
  "use strict";
33693
33804
  init_src();
33694
- execFileP = promisify3(execFile3);
33805
+ execFileP = promisify4(execFile4);
33695
33806
  }
33696
33807
  });
33697
33808
 
@@ -34644,9 +34755,10 @@ When delegation is explicitly authorized:
34644
34755
  - \`gpt-5.6-luna\` + \`medium\` or \`gpt-5.6-terra\` + \`medium\` for fully specified mechanical QA,
34645
34756
  documentation, straightforward tests, and exact collection or edits.
34646
34757
  - \`gpt-5.6-terra\` + \`high\` only after observed cross-layer or concurrency ambiguity.
34647
- - \`gpt-5.6-sol\` + \`high\` or \`xhigh\` only for evidenced high-risk runtime, persistence,
34648
- process-control, provider-protocol, or complex-concurrency work. Before any Sol or xhigh spawn,
34649
- state the observed evidence, the specific risk/ambiguity, and why Terra + medium is inadequate.
34758
+ - \`gpt-6-astra\` + \`high\` or \`xhigh\` (or \`gpt-5.6-sol\` when Astra is absent from the live
34759
+ model catalog) only for evidenced high-risk runtime, persistence, process-control,
34760
+ provider-protocol, or complex-concurrency work. Before any Astra, Sol or xhigh spawn, state the
34761
+ observed evidence, the specific risk/ambiguity, and why Terra + medium is inadequate.
34650
34762
 
34651
34763
  ## Automated waits in Codex
34652
34764
 
@@ -35711,8 +35823,8 @@ var init_claude_agent_broker_bridge = __esm({
35711
35823
  import { join as join27 } from "node:path";
35712
35824
  import { homedir as homedir12, platform as platform2 } from "node:os";
35713
35825
  import { readFileSync as readFileSync17, statSync as statSync11 } from "node:fs";
35714
- import { execFile as execFile4 } from "node:child_process";
35715
- import { promisify as promisify4 } from "node:util";
35826
+ import { execFile as execFile5 } from "node:child_process";
35827
+ import { promisify as promisify5 } from "node:util";
35716
35828
  function claudeConfigDir2() {
35717
35829
  const override = process.env.CLAUDE_CONFIG_DIR;
35718
35830
  return override && override.trim() ? override : join27(homedir12(), ".claude");
@@ -35730,7 +35842,7 @@ async function claudeKeychainState() {
35730
35842
  if (process.env.FRIZZ_KEYCHAIN_DISABLED && process.env.NODE_ENV !== "production") return "absent";
35731
35843
  if (platform2() !== "darwin") return "absent";
35732
35844
  try {
35733
- const { stdout } = await execFileAsync2("security", ["find-generic-password", "-s", "Claude Code-credentials", "-w"], {
35845
+ const { stdout } = await execFileAsync3("security", ["find-generic-password", "-s", "Claude Code-credentials", "-w"], {
35734
35846
  encoding: "utf8",
35735
35847
  timeout: 4e3
35736
35848
  });
@@ -35770,7 +35882,7 @@ function readCodexAuthState(codexHome = defaultCodexHome()) {
35770
35882
  const accessToken = tokens && typeof tokens.access_token === "string" && tokens.access_token ? tokens.access_token : void 0;
35771
35883
  return apiKey || accessToken ? "authed" : "signed-out";
35772
35884
  }
35773
- async function readCodexBinaryState(codexBin = "codex", exec = execFileAsync2) {
35885
+ async function readCodexBinaryState(codexBin = "codex", exec = execFileAsync3) {
35774
35886
  try {
35775
35887
  await exec(codexBin, ["--version"], { timeout: 5e3 });
35776
35888
  return "present";
@@ -35792,7 +35904,7 @@ function parseClaudeAuthStatusJson(stdout) {
35792
35904
  async function readClaudeAuthStatusCli(opts) {
35793
35905
  try {
35794
35906
  const bin = resolveClaudeExecutableAbsolute(opts?.claudeBin);
35795
- const { stdout } = await execFileAsync2(bin, ["auth", "status", "--json"], {
35907
+ const { stdout } = await execFileAsync3(bin, ["auth", "status", "--json"], {
35796
35908
  encoding: "utf8",
35797
35909
  timeout: opts?.timeoutMs ?? 5e3,
35798
35910
  ...opts?.cwd ? { cwd: opts.cwd } : {}
@@ -35890,14 +36002,14 @@ async function readAuthSnapshot(opts) {
35890
36002
  }
35891
36003
  };
35892
36004
  }
35893
- var execFileAsync2, ProviderAuthRequiredError, claudeAccountMemo;
36005
+ var execFileAsync3, ProviderAuthRequiredError, claudeAccountMemo;
35894
36006
  var init_auth_status = __esm({
35895
36007
  "packages/server/src/backend/auth-status.ts"() {
35896
36008
  "use strict";
35897
36009
  init_claude_quota();
35898
36010
  init_codex();
35899
36011
  init_claude_broker_host();
35900
- execFileAsync2 = promisify4(execFile4);
36012
+ execFileAsync3 = promisify5(execFile5);
35901
36013
  ProviderAuthRequiredError = class extends Error {
35902
36014
  backend;
35903
36015
  constructor(backend) {
@@ -36648,10 +36760,11 @@ var init_dispatch = __esm({
36648
36760
 
36649
36761
  // packages/server/src/board.ts
36650
36762
  import {
36763
+ realpathSync as realpathSync8,
36651
36764
  watch as fsWatch
36652
36765
  } from "node:fs";
36653
36766
  import { homedir as homedir13 } from "node:os";
36654
- import { join as join29 } from "node:path";
36767
+ import { dirname as dirname12, join as join29 } from "node:path";
36655
36768
  import watcher from "@parcel/watcher";
36656
36769
  function appServerTurnStalled(liveness, lastActivityAt, nowMs) {
36657
36770
  if (!liveness) return false;
@@ -36699,6 +36812,9 @@ function registeredLegacyFileIsTerminal(projectDir, slug) {
36699
36812
  const status = raw2?.replace(/^(?:"(.*)"|'(.*)')$/, "$1$2").trim();
36700
36813
  return status === "done" || status === "dismissed";
36701
36814
  }
36815
+ function isBoardRelevantFrizzPath(roots, path) {
36816
+ return path.endsWith(".md") && roots.has(dirname12(path));
36817
+ }
36702
36818
  function futureSnooze(row, nowMs) {
36703
36819
  const parsed = SnoozeUntil.safeParse(row.snoozed_until);
36704
36820
  return parsed.success && Date.parse(parsed.data) > nowMs ? parsed.data : void 0;
@@ -37028,20 +37144,29 @@ function registeredDoneFence(done, lastUserAt) {
37028
37144
  if (Number.isFinite(userAt) && userAt > done.doneAt) return void 0;
37029
37145
  return { kind: "done", body: done.body, hints: [], registered: true };
37030
37146
  }
37031
- function sessionThreadView(projectDir, storage, row, rawTele, registeredLegacyTerminal, interactionPresence, nowMs, codexTurnLiveness, claudeBrokerDaemonAlive, github = {}) {
37032
- const armedPrWatches = storage.listPrWatches(row.slug, { armedOnly: true }).map((w) => ({
37147
+ function readThreadRegistries(storage) {
37148
+ return {
37149
+ prWatches: storage.armedPrWatchesBySlug(),
37150
+ timers: storage.armedThreadTimersBySlug(),
37151
+ questions: storage.threadQuestionsBySlug(),
37152
+ watches: storage.armedThreadWatchesBySlug(),
37153
+ done: storage.threadDoneBySlug()
37154
+ };
37155
+ }
37156
+ function sessionThreadView(projectDir, storage, row, rawTele, registeredLegacyTerminal, interactionPresence, nowMs, codexTurnLiveness, claudeBrokerDaemonAlive, registries, github = {}) {
37157
+ const armedPrWatches = (registries.prWatches.get(row.slug) ?? []).map((w) => ({
37033
37158
  target: `${w.owner}/${w.repo}#${w.number}`,
37034
37159
  createdAt: new Date(w.created_at).toISOString()
37035
37160
  }));
37036
37161
  const registeredPrWatches = new Set(armedPrWatches.map((w) => w.target));
37037
- const armedTimers = storage.listThreadTimers(row.slug, { armedOnly: true }).map((t) => ({
37162
+ const armedTimers = (registries.timers.get(row.slug) ?? []).map((t) => ({
37038
37163
  id: t.id,
37039
37164
  prompt: t.prompt,
37040
37165
  fireAt: new Date(t.fire_at).toISOString(),
37041
37166
  createdAt: new Date(t.created_at).toISOString()
37042
37167
  }));
37043
37168
  const armedTimerIds = new Set(armedTimers.map((t) => t.id));
37044
- const questionRows = storage.listThreadQuestions(row.slug);
37169
+ const questionRows = registries.questions.get(row.slug) ?? [];
37045
37170
  const questions = [];
37046
37171
  for (const q of questionRows) {
37047
37172
  if (q.state !== "open") continue;
@@ -37049,7 +37174,7 @@ function sessionThreadView(projectDir, storage, row, rawTele, registeredLegacyTe
37049
37174
  if (spec) questions.push({ id: q.id, spec, askedAt: new Date(q.asked_at).toISOString() });
37050
37175
  }
37051
37176
  const inFlightAnswers = answersInFlight(questionRows, rawTele?.lastUserAt, row.recurring_on_rest === 1 && Boolean(row.recurring_prompt?.trim()));
37052
- const armedWatches = storage.listThreadWatches(row.slug, { armedOnly: true }).map((w) => ({
37177
+ const armedWatches = (registries.watches.get(row.slug) ?? []).map((w) => ({
37053
37178
  id: w.id,
37054
37179
  kind: w.kind,
37055
37180
  target: w.target,
@@ -37057,7 +37182,7 @@ function sessionThreadView(projectDir, storage, row, rawTele, registeredLegacyTe
37057
37182
  expiresAt: new Date(w.expires_at).toISOString()
37058
37183
  }));
37059
37184
  const supersededDone = questions.length > 0 || armedWatches.length > 0 || armedPrWatches.length > 0 || armedTimers.length > 0;
37060
- const done = supersededDone ? void 0 : registeredDoneFence(storage.getThreadDone(row.slug), rawTele?.lastUserAt);
37185
+ const done = supersededDone ? void 0 : registeredDoneFence(registries.done.get(row.slug), rawTele?.lastUserAt);
37061
37186
  const tele = done && rawTele ? { ...rawTele, lastFence: done } : rawTele;
37062
37187
  const headlessStalled = row.codex_runtime === "app-server" ? appServerTurnStalled(codexTurnLiveness(row.slug, row.session_id), tele?.lastActivityAt, nowMs) : isBrokerClaudeRow(row) ? !claudeBrokerDaemonAlive(row.session_id) : false;
37063
37188
  const headlessLostWork = isBrokerClaudeRow(row) && headlessStalled && hasUnretiredOwnAgents(tele);
@@ -37287,6 +37412,7 @@ function createBoard(project, storage, bus, tailer, bootId, deps = {}) {
37287
37412
  function buildSessionThreads(nowMs) {
37288
37413
  const rows = storage.allSessions().filter((row) => ThreadSlug.safeParse(row.slug).success);
37289
37414
  const github = readGithubStatusBook(storage.getSetting(GITHUB_STATUS_SETTING));
37415
+ const registries = readThreadRegistries(storage);
37290
37416
  const currentInteractionKeys = /* @__PURE__ */ new Set();
37291
37417
  const out = [];
37292
37418
  for (const row of rows) {
@@ -37323,6 +37449,7 @@ function createBoard(project, storage, bus, tailer, bootId, deps = {}) {
37323
37449
  nowMs,
37324
37450
  codexTurnLiveness,
37325
37451
  claudeBrokerDaemonAlive,
37452
+ registries,
37326
37453
  github
37327
37454
  ));
37328
37455
  }
@@ -37452,7 +37579,23 @@ function createBoard(project, storage, bus, tailer, bootId, deps = {}) {
37452
37579
  if (parcelSub || stopped) return Promise.resolve();
37453
37580
  if (watchSetup) return watchSetup;
37454
37581
  const setup = (async () => {
37455
- const next = await subscribe(join29(project.dir, ".frizz"), () => scheduleRebuild());
37582
+ const dir = join29(project.dir, ".frizz");
37583
+ const roots = /* @__PURE__ */ new Set([dir]);
37584
+ try {
37585
+ roots.add(realpathSync8(dir));
37586
+ } catch {
37587
+ }
37588
+ const next = await subscribe(
37589
+ dir,
37590
+ (err, events) => {
37591
+ if (err || !events) {
37592
+ scheduleRebuild();
37593
+ return;
37594
+ }
37595
+ if (events.some((event) => isBoardRelevantFrizzPath(roots, event.path))) scheduleRebuild();
37596
+ },
37597
+ { ignore: FRIZZ_WATCH_IGNORED_DIRS.map((name) => join29(dir, name)) }
37598
+ );
37456
37599
  if (stopped) {
37457
37600
  await next.unsubscribe();
37458
37601
  return;
@@ -37527,7 +37670,7 @@ function createBoard(project, storage, bus, tailer, bootId, deps = {}) {
37527
37670
  }
37528
37671
  };
37529
37672
  }
37530
- var DEBOUNCE_MS, RECONCILE_MS, STALL_GRACE_MS, LINE_CAP, DECLARED_PARK_MAX_MS;
37673
+ var DEBOUNCE_MS, RECONCILE_MS, STALL_GRACE_MS, LINE_CAP, FRIZZ_WATCH_IGNORED_DIRS, DECLARED_PARK_MAX_MS;
37531
37674
  var init_board = __esm({
37532
37675
  "packages/server/src/board.ts"() {
37533
37676
  "use strict";
@@ -37547,6 +37690,7 @@ var init_board = __esm({
37547
37690
  RECONCILE_MS = 15e3;
37548
37691
  STALL_GRACE_MS = 3e4;
37549
37692
  LINE_CAP = 240;
37693
+ FRIZZ_WATCH_IGNORED_DIRS = ["threads", ".session-state"];
37550
37694
  DECLARED_PARK_MAX_MS = 24 * 60 * 60 * 1e3;
37551
37695
  }
37552
37696
  });
@@ -37767,8 +37911,8 @@ var init_wake_store = __esm({
37767
37911
  });
37768
37912
 
37769
37913
  // packages/server/src/github-review.ts
37770
- import { execFile as execFile5 } from "node:child_process";
37771
- import { promisify as promisify5 } from "node:util";
37914
+ import { execFile as execFile6 } from "node:child_process";
37915
+ import { promisify as promisify6 } from "node:util";
37772
37916
  function refKey(ref) {
37773
37917
  return `${ref.owner}/${ref.repo}#${ref.number}`;
37774
37918
  }
@@ -37778,7 +37922,7 @@ function conciseError(error) {
37778
37922
  }
37779
37923
  async function defaultGetToken() {
37780
37924
  try {
37781
- const { stdout } = await execFileAsync3(
37925
+ const { stdout } = await execFileAsync4(
37782
37926
  "gh",
37783
37927
  ["auth", "token", "--hostname", "github.com"],
37784
37928
  {
@@ -38084,11 +38228,11 @@ function createGithubReviewFetcher(deps = {}) {
38084
38228
  }
38085
38229
  });
38086
38230
  }
38087
- var execFileAsync3, GH_TIMEOUT_MS, GH_MAX_BUFFER, REQUEST_TIMEOUT_MS, MAX_REFS_PER_REQUEST, RATE_LIMIT_RESERVE;
38231
+ var execFileAsync4, GH_TIMEOUT_MS, GH_MAX_BUFFER, REQUEST_TIMEOUT_MS, MAX_REFS_PER_REQUEST, RATE_LIMIT_RESERVE;
38088
38232
  var init_github_review = __esm({
38089
38233
  "packages/server/src/github-review.ts"() {
38090
38234
  "use strict";
38091
- execFileAsync3 = promisify5(execFile5);
38235
+ execFileAsync4 = promisify6(execFile6);
38092
38236
  GH_TIMEOUT_MS = 3e4;
38093
38237
  GH_MAX_BUFFER = 1024 * 1024;
38094
38238
  REQUEST_TIMEOUT_MS = 3e4;
@@ -38215,8 +38359,8 @@ var init_pr_watch_noise = __esm({
38215
38359
  });
38216
38360
 
38217
38361
  // packages/server/src/scheduler.ts
38218
- import { execFile as execFile6 } from "node:child_process";
38219
- import { promisify as promisify6 } from "node:util";
38362
+ import { execFile as execFile7 } from "node:child_process";
38363
+ import { promisify as promisify7 } from "node:util";
38220
38364
  import { createHash as createHash12, randomUUID as randomUUID14 } from "node:crypto";
38221
38365
  function failureSignature(rollup) {
38222
38366
  const ids = [];
@@ -38460,7 +38604,7 @@ function conciseGhError(err) {
38460
38604
  }
38461
38605
  async function probePrReadable(ref) {
38462
38606
  try {
38463
- await execFileAsync4(
38607
+ await execFileAsync5(
38464
38608
  "gh",
38465
38609
  ["pr", "view", String(ref.number), "--repo", `${ref.owner}/${ref.repo}`, "--json", "state"],
38466
38610
  { timeout: 15e3, maxBuffer: 1e6, env: { ...process.env, GH_PAGER: "cat", GH_PROMPT_DISABLED: "1" } }
@@ -38472,7 +38616,7 @@ async function probePrReadable(ref) {
38472
38616
  }
38473
38617
  async function defaultFetchPr(ref) {
38474
38618
  try {
38475
- const { stdout } = await execFileAsync4(
38619
+ const { stdout } = await execFileAsync5(
38476
38620
  "gh",
38477
38621
  ghPrViewArgs(ref),
38478
38622
  { timeout: 15e3, maxBuffer: 8e6, env: { ...process.env, GH_PAGER: "cat", GH_PROMPT_DISABLED: "1" } }
@@ -38480,7 +38624,7 @@ async function defaultFetchPr(ref) {
38480
38624
  const j = JSON.parse(stdout);
38481
38625
  if (typeof j.state !== "string" || !j.state) return void 0;
38482
38626
  if (typeof j.headRefOid !== "string" || !j.headRefOid) return void 0;
38483
- const runs = await execFileAsync4(
38627
+ const runs = await execFileAsync5(
38484
38628
  "gh",
38485
38629
  ["run", "list", "--repo", `${ref.owner}/${ref.repo}`, "--commit", j.headRefOid, "--limit", "100", "--json", "name,workflowName,status,conclusion,databaseId,event,createdAt"],
38486
38630
  { timeout: 15e3, maxBuffer: 8e6, env: { ...process.env, GH_PAGER: "cat", GH_PROMPT_DISABLED: "1" } }
@@ -39796,7 +39940,7 @@ ${wakeTimeHeader(now(), spokeAt)}`;
39796
39940
  }
39797
39941
  };
39798
39942
  }
39799
- var execFileAsync4, LIMIT_FENCE_PREFIX, LIMIT_HINT_PREFIX, LIMIT_RESUME_GRACE_MS, LIMIT_RESUME_HEADROOM_PERCENT, LIMIT_HEADROOM_MIN_FAULT_AGE_MS, REPORT_FENCE_PREFIX, REPORT_HINT_PREFIX, SNOOZE_FENCE_PREFIX, SNOOZE_HINT_PREFIX, HEARTBEAT_FENCE_PREFIX, HEARTBEAT_HINT_PREFIX, STOP_HOOK_FENCE_PREFIX, STOP_HOOK_HINT_KEY, COMPACT_FENCE_PREFIX, COMPACT_HINT_KEY, TIMER_FENCE_PREFIX, TIMER_HINT_PREFIX, SHELL_FENCE_PREFIX, PR_WATCH_FENCE_PREFIX, PR_WATCH_EXPIRED_FENCE_PREFIX, OWN_WATCH_EXPIRED_FENCE_PREFIX, QUESTION_ANSWER_FENCE_PREFIX, PR_WATCH_POLL_MS, SIGNOFF_FENCE_PREFIX, SIGNOFF_HINT_KEY, SIGNOFF_NUDGE_MAX, PARK_BUMP_MAX, SIGNOFF_NUDGE_SETTING, PARK_FENCE_PREFIX, GITHUB_STATUS_CAP, REVIEW_SEEN_CAP, REVIEW_STEER_CAP, AWAITING_KEY_OF, MID_TURN_HOLD_MAX_MS, WAKE_HOLD_DEFERRAL;
39943
+ var execFileAsync5, LIMIT_FENCE_PREFIX, LIMIT_HINT_PREFIX, LIMIT_RESUME_GRACE_MS, LIMIT_RESUME_HEADROOM_PERCENT, LIMIT_HEADROOM_MIN_FAULT_AGE_MS, REPORT_FENCE_PREFIX, REPORT_HINT_PREFIX, SNOOZE_FENCE_PREFIX, SNOOZE_HINT_PREFIX, HEARTBEAT_FENCE_PREFIX, HEARTBEAT_HINT_PREFIX, STOP_HOOK_FENCE_PREFIX, STOP_HOOK_HINT_KEY, COMPACT_FENCE_PREFIX, COMPACT_HINT_KEY, TIMER_FENCE_PREFIX, TIMER_HINT_PREFIX, SHELL_FENCE_PREFIX, PR_WATCH_FENCE_PREFIX, PR_WATCH_EXPIRED_FENCE_PREFIX, OWN_WATCH_EXPIRED_FENCE_PREFIX, QUESTION_ANSWER_FENCE_PREFIX, PR_WATCH_POLL_MS, SIGNOFF_FENCE_PREFIX, SIGNOFF_HINT_KEY, SIGNOFF_NUDGE_MAX, PARK_BUMP_MAX, SIGNOFF_NUDGE_SETTING, PARK_FENCE_PREFIX, GITHUB_STATUS_CAP, REVIEW_SEEN_CAP, REVIEW_STEER_CAP, AWAITING_KEY_OF, MID_TURN_HOLD_MAX_MS, WAKE_HOLD_DEFERRAL;
39800
39944
  var init_scheduler = __esm({
39801
39945
  "packages/server/src/scheduler.ts"() {
39802
39946
  "use strict";
@@ -39812,7 +39956,7 @@ var init_scheduler = __esm({
39812
39956
  init_pr_watch_noise();
39813
39957
  init_github_review();
39814
39958
  init_logging();
39815
- execFileAsync4 = promisify6(execFile6);
39959
+ execFileAsync5 = promisify7(execFile7);
39816
39960
  LIMIT_FENCE_PREFIX = "limit";
39817
39961
  LIMIT_HINT_PREFIX = "limit:";
39818
39962
  LIMIT_RESUME_GRACE_MS = 6e4;
@@ -40228,7 +40372,7 @@ var init_codex_app_server_diagnostics = __esm({
40228
40372
  });
40229
40373
 
40230
40374
  // packages/server/src/backend/stale-socket-sweep.ts
40231
- import { execFile as execFile7 } from "node:child_process";
40375
+ import { execFile as execFile8 } from "node:child_process";
40232
40376
  import { readdirSync as readdirSync8, unlinkSync as unlinkSync4 } from "node:fs";
40233
40377
  import { connect as connectSocket } from "node:net";
40234
40378
  import { join as join32 } from "node:path";
@@ -40275,7 +40419,7 @@ var init_stale_socket_sweep = __esm({
40275
40419
  "packages/server/src/backend/stale-socket-sweep.ts"() {
40276
40420
  "use strict";
40277
40421
  defaultListReferenced = (prefix, done) => {
40278
- execFile7("lsof", ["-U", "-F", "n"], { timeout: 3e4, maxBuffer: 16 * 1024 * 1024 }, (error, stdout) => {
40422
+ execFile8("lsof", ["-U", "-F", "n"], { timeout: 3e4, maxBuffer: 16 * 1024 * 1024 }, (error, stdout) => {
40279
40423
  if (!stdout) return done(null);
40280
40424
  if (error && !stdout.includes(prefix)) return done(null);
40281
40425
  done(parseLsofSocketNames(stdout));
@@ -40297,9 +40441,9 @@ var init_stale_socket_sweep = __esm({
40297
40441
  });
40298
40442
 
40299
40443
  // packages/server/src/orphan-reaper.ts
40300
- import { execFileSync as execFileSync5 } from "node:child_process";
40444
+ import { execFileSync as execFileSync4 } from "node:child_process";
40301
40445
  import { readFileSync as readFileSync19 } from "node:fs";
40302
- import { dirname as dirname12 } from "node:path";
40446
+ import { dirname as dirname13 } from "node:path";
40303
40447
  function firstTokenBasename(command) {
40304
40448
  const first = command.trimStart().split(/\s+/, 1)[0] ?? "";
40305
40449
  const slash = first.lastIndexOf("/");
@@ -40526,7 +40670,7 @@ function sweepOrphansOnce(deps = {}) {
40526
40670
  }
40527
40671
  function sweepStaleBrokerSockets() {
40528
40672
  try {
40529
- sweepStaleSockets({ dir: dirname12(claudeBrokerSocketPath("", "")), prefix: CLAUDE_BROKER_SOCKET_PREFIX });
40673
+ sweepStaleSockets({ dir: dirname13(claudeBrokerSocketPath("", "")), prefix: CLAUDE_BROKER_SOCKET_PREFIX });
40530
40674
  } catch {
40531
40675
  }
40532
40676
  }
@@ -40562,7 +40706,7 @@ var init_orphan_reaper = __esm({
40562
40706
  ORPHAN_REAP_INTERVAL_MS = 6e4;
40563
40707
  ORPHAN_MIN_AGE_MS = 12e4;
40564
40708
  SLUG_RE = /FRIZZ_THREAD=([A-Za-z0-9._-]+)/;
40565
- defaultExec = (file, args) => execFileSync5(file, args, { encoding: "utf8", maxBuffer: 16 * 1024 * 1024, timeout: 1e4 });
40709
+ defaultExec = (file, args) => execFileSync4(file, args, { encoding: "utf8", maxBuffer: 16 * 1024 * 1024, timeout: 1e4 });
40566
40710
  defaultReadEnv = (pid) => {
40567
40711
  try {
40568
40712
  return readFileSync19(`/proc/${pid}/environ`, "utf8");
@@ -43916,7 +44060,7 @@ var init_server = __esm({
43916
44060
 
43917
44061
  // packages/server/src/repair.ts
43918
44062
  import { existsSync as existsSync11, readFileSync as readFileSync20, writeFileSync as writeFileSync11 } from "node:fs";
43919
- import { basename as basename7, dirname as dirname13, resolve as resolve7 } from "node:path";
44063
+ import { basename as basename7, dirname as dirname14, resolve as resolve7 } from "node:path";
43920
44064
  function quoteValue(v) {
43921
44065
  if (/^[\w./#:+-]+$/.test(v)) return v;
43922
44066
  return `"${v.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
@@ -43928,7 +44072,7 @@ function deriveTitle(body, slug) {
43928
44072
  function repairThreadFile(frizzDir, file) {
43929
44073
  const root = resolve7(frizzDir);
43930
44074
  const abs = resolve7(root, file);
43931
- if (dirname13(abs) !== root) throw new RepairError(`refusing to repair "${file}": not directly under .frizz/`);
44075
+ if (dirname14(abs) !== root) throw new RepairError(`refusing to repair "${file}": not directly under .frizz/`);
43932
44076
  if (!abs.endsWith(".md")) throw new RepairError(`refusing to repair "${file}": not a .md thread file`);
43933
44077
  if (!existsSync11(abs)) throw new RepairError(`no thread file to repair: ${basename7(abs)}`);
43934
44078
  const content = readFileSync20(abs, "utf8");
@@ -46663,13 +46807,13 @@ var init_open_external = __esm({
46663
46807
 
46664
46808
  // packages/server/src/local-file.ts
46665
46809
  import { spawn as spawn6 } from "node:child_process";
46666
- import { readFileSync as readFileSync23, realpathSync as realpathSync8, statSync as statSync15 } from "node:fs";
46810
+ import { readFileSync as readFileSync23, realpathSync as realpathSync9, statSync as statSync15 } from "node:fs";
46667
46811
  import { homedir as homedir16 } from "node:os";
46668
46812
  import { isAbsolute as isAbsolute4, join as join35, resolve as resolve8, sep as sep2 } from "node:path";
46669
46813
  function isUnder(real, root) {
46670
46814
  let rootReal;
46671
46815
  try {
46672
- rootReal = realpathSync8(root);
46816
+ rootReal = realpathSync9(root);
46673
46817
  } catch {
46674
46818
  return false;
46675
46819
  }
@@ -46679,7 +46823,7 @@ function resolveLocalFile(rawPath, roots) {
46679
46823
  if (!isAbsolute4(rawPath)) throw new Error("Local path must be absolute");
46680
46824
  let real;
46681
46825
  try {
46682
- real = realpathSync8(rawPath);
46826
+ real = realpathSync9(rawPath);
46683
46827
  } catch {
46684
46828
  throw new Error("Local file was not found");
46685
46829
  }
@@ -47029,8 +47173,8 @@ var init_github_hovercard = __esm({
47029
47173
  });
47030
47174
 
47031
47175
  // packages/server/src/backend/account-actions.ts
47032
- import { execFile as execFile8 } from "node:child_process";
47033
- import { promisify as promisify7 } from "node:util";
47176
+ import { execFile as execFile9 } from "node:child_process";
47177
+ import { promisify as promisify8 } from "node:util";
47034
47178
  function liveThreadsForBackend(threads, backend) {
47035
47179
  let count = 0;
47036
47180
  for (const thread of threads) {
@@ -47049,7 +47193,7 @@ async function runProviderLogout(opts) {
47049
47193
  const args = opts.backend === "codex" ? ["logout"] : ["auth", "logout"];
47050
47194
  let failure;
47051
47195
  try {
47052
- await execFileAsync5(bin, args, { encoding: "utf8", timeout: opts.timeoutMs ?? 15e3 });
47196
+ await execFileAsync6(bin, args, { encoding: "utf8", timeout: opts.timeoutMs ?? 15e3 });
47053
47197
  } catch (err) {
47054
47198
  const e = err;
47055
47199
  const stderr = typeof e.stderr === "string" ? e.stderr.trim() : "";
@@ -47059,12 +47203,12 @@ async function runProviderLogout(opts) {
47059
47203
  if (failure && auth !== "signed-out") return { status: "failed", detail: failure, auth };
47060
47204
  return { status: "done", auth };
47061
47205
  }
47062
- var execFileAsync5, LIVE_RUNTIMES;
47206
+ var execFileAsync6, LIVE_RUNTIMES;
47063
47207
  var init_account_actions = __esm({
47064
47208
  "packages/server/src/backend/account-actions.ts"() {
47065
47209
  "use strict";
47066
47210
  init_auth_status();
47067
- execFileAsync5 = promisify7(execFile8);
47211
+ execFileAsync6 = promisify8(execFile9);
47068
47212
  LIVE_RUNTIMES = /* @__PURE__ */ new Set(["spawning", "running", "perm-prompt"]);
47069
47213
  }
47070
47214
  });
@@ -47332,8 +47476,8 @@ var init_image_header = __esm({
47332
47476
  });
47333
47477
 
47334
47478
  // packages/server/src/directory-picker.ts
47335
- import { execFile as execFile9 } from "node:child_process";
47336
- import { promisify as promisify8 } from "node:util";
47479
+ import { execFile as execFile10 } from "node:child_process";
47480
+ import { promisify as promisify9 } from "node:util";
47337
47481
  async function pickImageFile(startIn, prompt = "Choose an image for this project", platform3 = process.platform) {
47338
47482
  if (platform3 === "darwin") {
47339
47483
  const location = startIn ? ` default location POSIX file ${JSON.stringify(startIn)}` : "";
@@ -47414,7 +47558,7 @@ var run2, PICKER_TIMEOUT_MS, OSASCRIPT;
47414
47558
  var init_directory_picker = __esm({
47415
47559
  "packages/server/src/directory-picker.ts"() {
47416
47560
  "use strict";
47417
- run2 = promisify8(execFile9);
47561
+ run2 = promisify9(execFile10);
47418
47562
  PICKER_TIMEOUT_MS = 5 * 6e4;
47419
47563
  OSASCRIPT = (prompt) => `POSIX path of (choose folder with prompt ${JSON.stringify(prompt)})`;
47420
47564
  }
@@ -47424,7 +47568,7 @@ var init_directory_picker = __esm({
47424
47568
  import { readFileSync as readFileSync24, statSync as statSync17 } from "node:fs";
47425
47569
  import { join as join36, resolve as resolve9 } from "node:path";
47426
47570
  import { randomUUID as randomUUID16 } from "node:crypto";
47427
- import { basename as basename9, dirname as dirname14 } from "node:path";
47571
+ import { basename as basename9, dirname as dirname15 } from "node:path";
47428
47572
  import { existsSync as existsSync13, mkdirSync as mkdirSync16, rmSync as rmSync10, writeFileSync as writeFileSync13 } from "node:fs";
47429
47573
  import { homedir as homedir17 } from "node:os";
47430
47574
  function validateGithubDispatchProfile(input) {
@@ -47618,7 +47762,7 @@ function storeProjectIcon(id, name, bytes) {
47618
47762
  if (!entry) throw new Error("No such project.");
47619
47763
  if (bytes.length === 0) throw new Error("That file is empty.");
47620
47764
  const path = customIconPath(id, `.${extension2}`);
47621
- mkdirSync16(dirname14(path), { recursive: true });
47765
+ mkdirSync16(dirname15(path), { recursive: true });
47622
47766
  writeFileSync13(path, bytes);
47623
47767
  if (!imageDimensions(path)) {
47624
47768
  rmSync10(path, { force: true });
@@ -49997,7 +50141,7 @@ var init_compression = __esm({
49997
50141
  });
49998
50142
 
49999
50143
  // packages/server/src/local-image.ts
50000
- import { readFileSync as readFileSync25, realpathSync as realpathSync9, statSync as statSync18 } from "node:fs";
50144
+ import { readFileSync as readFileSync25, realpathSync as realpathSync10, statSync as statSync18 } from "node:fs";
50001
50145
  import { extname as extname2, isAbsolute as isAbsolute5 } from "node:path";
50002
50146
  function resolveLocalImage(rawPath) {
50003
50147
  if (!rawPath || !isAbsolute5(rawPath)) return { status: 400 };
@@ -50005,7 +50149,7 @@ function resolveLocalImage(rawPath) {
50005
50149
  if (!contentType) return { status: 400 };
50006
50150
  let real;
50007
50151
  try {
50008
- real = realpathSync9(rawPath);
50152
+ real = realpathSync10(rawPath);
50009
50153
  } catch {
50010
50154
  return { status: 404 };
50011
50155
  }
@@ -50031,9 +50175,9 @@ var init_local_image = __esm({
50031
50175
  });
50032
50176
 
50033
50177
  // packages/server/src/project-icon.ts
50034
- import { readFileSync as readFileSync26, readdirSync as readdirSync10, realpathSync as realpathSync10, statSync as statSync19 } from "node:fs";
50178
+ import { readFileSync as readFileSync26, readdirSync as readdirSync10, realpathSync as realpathSync11, statSync as statSync19 } from "node:fs";
50035
50179
  import { homedir as homedir18 } from "node:os";
50036
- import { basename as basename10, dirname as dirname15, extname as extname3, join as join37, relative as relative2, sep as sep3 } from "node:path";
50180
+ import { basename as basename10, dirname as dirname16, extname as extname3, join as join37, relative as relative2, sep as sep3 } from "node:path";
50037
50181
  function normalizeStem(stem) {
50038
50182
  const sized = stem.toLowerCase().replace(/[@-]\d+(\.\d+)?x(\d+)?$/u, "").replace(/[-_]\d{2,4}$/u, "");
50039
50183
  const normalized = sized.replace(VARIANT_SUFFIX, "");
@@ -50098,7 +50242,7 @@ function manifestIcons(manifestPath) {
50098
50242
  return [];
50099
50243
  }
50100
50244
  if (!Array.isArray(parsed?.icons)) return [];
50101
- const directory = dirname15(manifestPath);
50245
+ const directory = dirname16(manifestPath);
50102
50246
  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) => join37(directory, src.replace(/[?#].*$/u, "").replace(/^\//u, "")));
50103
50247
  }
50104
50248
  function projectIconCandidates(root) {
@@ -50121,7 +50265,7 @@ function projectIconCandidates(root) {
50121
50265
  for (const icon of manifestIcons(join37(directory, name))) {
50122
50266
  if (MEASURABLE_IMAGE_EXTENSIONS.has(extname3(icon).toLowerCase())) {
50123
50267
  fromManifest.add(icon);
50124
- files.push({ path: icon, directory: dirname15(icon) });
50268
+ files.push({ path: icon, directory: dirname16(icon) });
50125
50269
  }
50126
50270
  }
50127
50271
  continue;
@@ -50180,14 +50324,14 @@ function resolveProjectIconResponse(id, options = {}) {
50180
50324
  if (!contentType) return { status: 404 };
50181
50325
  let real;
50182
50326
  try {
50183
- real = realpathSync10(path);
50327
+ real = realpathSync11(path);
50184
50328
  if (!statSync19(real).isFile()) return { status: 404 };
50185
50329
  } catch {
50186
50330
  return { status: 404 };
50187
50331
  }
50188
50332
  const roots = [entry.path, projectStateDir(id, home)].map((root) => {
50189
50333
  try {
50190
- return realpathSync10(root);
50334
+ return realpathSync11(root);
50191
50335
  } catch {
50192
50336
  return root;
50193
50337
  }
@@ -50306,7 +50450,7 @@ var init_project_icon = __esm({
50306
50450
  });
50307
50451
 
50308
50452
  // packages/server/src/local-visualization.ts
50309
- import { readdirSync as readdirSync11, readFileSync as readFileSync27, realpathSync as realpathSync11, statSync as statSync20 } from "node:fs";
50453
+ import { readdirSync as readdirSync11, readFileSync as readFileSync27, realpathSync as realpathSync12, statSync as statSync20 } from "node:fs";
50310
50454
  import { join as join38, sep as sep4 } from "node:path";
50311
50455
  function children(path, pattern) {
50312
50456
  try {
@@ -50323,8 +50467,8 @@ function resolveFragment(projectDir, sessionId, file) {
50323
50467
  let projectReal;
50324
50468
  let baseReal;
50325
50469
  try {
50326
- projectReal = realpathSync11(projectDir);
50327
- baseReal = realpathSync11(base);
50470
+ projectReal = realpathSync12(projectDir);
50471
+ baseReal = realpathSync12(base);
50328
50472
  } catch {
50329
50473
  return null;
50330
50474
  }
@@ -50337,7 +50481,7 @@ function resolveFragment(projectDir, sessionId, file) {
50337
50481
  const sessionRoot = join38(baseReal, year, month, day, sessionId);
50338
50482
  const candidate = join38(monthDir, day, sessionId, file);
50339
50483
  try {
50340
- const real = realpathSync11(candidate);
50484
+ const real = realpathSync12(candidate);
50341
50485
  if (isUnder2(real, sessionRoot) && statSync20(real).isFile()) return real;
50342
50486
  } catch {
50343
50487
  }
@@ -51044,7 +51188,11 @@ function makeTranscriptReader(project, storage, backendFor, lifecycleFor, peerNa
51044
51188
  };
51045
51189
  }
51046
51190
  function createAppSocketServer(deps) {
51047
- const wss = new import_websocket_server.default({ noServer: true, maxPayload: APP_SOCKET_MAX_MESSAGE_BYTES });
51191
+ const wss = new import_websocket_server.default({
51192
+ noServer: true,
51193
+ maxPayload: APP_SOCKET_MAX_MESSAGE_BYTES,
51194
+ perMessageDeflate: APP_SOCKET_DEFLATE
51195
+ });
51048
51196
  const registry = new SubscriptionRegistry();
51049
51197
  const boundedCount = (value, fallback) => {
51050
51198
  const candidate = value ?? fallback;
@@ -51774,7 +51922,7 @@ function createAppSocketServer(deps) {
51774
51922
  }
51775
51923
  };
51776
51924
  }
51777
- var WS_PATH, SubscriptionRegistry, HEARTBEAT_MS, APP_SOCKET_MAX_MESSAGE_BYTES, APP_SOCKET_MAX_LOGICAL_FRAME_BYTES, APP_SOCKET_MAX_OUTPUT_BUFFER_BYTES, APP_SOCKET_MAX_CONNECTIONS, APP_SOCKET_MAX_SUBSCRIPTIONS, APP_SOCKET_MAX_FILE_WATCHES, APP_SOCKET_MAX_MESSAGES_PER_WINDOW, APP_SOCKET_MESSAGE_WINDOW_MS, APP_SOCKET_MAX_BUFFERED_KEYFRAME_EVENTS, APP_SOCKET_MAX_TRANSCRIPT_READS_PER_ORIGIN, APP_SOCKET_MAX_TRANSCRIPT_READS_OVERALL, APP_SOCKET_TRANSCRIPT_READ_WINDOW_MS, APP_SOCKET_MAX_TRANSCRIPT_CACHE_ENTRIES, APP_SOCKET_MAX_TRANSCRIPT_CACHE_BYTES;
51925
+ var WS_PATH, SubscriptionRegistry, HEARTBEAT_MS, APP_SOCKET_MAX_MESSAGE_BYTES, APP_SOCKET_MAX_LOGICAL_FRAME_BYTES, APP_SOCKET_MAX_OUTPUT_BUFFER_BYTES, APP_SOCKET_MAX_CONNECTIONS, APP_SOCKET_MAX_SUBSCRIPTIONS, APP_SOCKET_MAX_FILE_WATCHES, APP_SOCKET_MAX_MESSAGES_PER_WINDOW, APP_SOCKET_MESSAGE_WINDOW_MS, APP_SOCKET_MAX_BUFFERED_KEYFRAME_EVENTS, APP_SOCKET_MAX_TRANSCRIPT_READS_PER_ORIGIN, APP_SOCKET_MAX_TRANSCRIPT_READS_OVERALL, APP_SOCKET_TRANSCRIPT_READ_WINDOW_MS, APP_SOCKET_MAX_TRANSCRIPT_CACHE_ENTRIES, APP_SOCKET_MAX_TRANSCRIPT_CACHE_BYTES, APP_SOCKET_DEFLATE;
51778
51926
  var init_app_socket = __esm({
51779
51927
  "packages/server/src/app-socket.ts"() {
51780
51928
  "use strict";
@@ -51866,12 +52014,21 @@ var init_app_socket = __esm({
51866
52014
  APP_SOCKET_TRANSCRIPT_READ_WINDOW_MS = 1e3;
51867
52015
  APP_SOCKET_MAX_TRANSCRIPT_CACHE_ENTRIES = 128;
51868
52016
  APP_SOCKET_MAX_TRANSCRIPT_CACHE_BYTES = 32 * 1024 * 1024;
52017
+ APP_SOCKET_DEFLATE = {
52018
+ threshold: 8 * 1024,
52019
+ concurrencyLimit: 10,
52020
+ zlibDeflateOptions: { level: 6, memLevel: 8 },
52021
+ // A sliding window is negotiated per connection and costs memory on both ends for the whole
52022
+ // connection's life; these frames are independently compressible, so decline the context takeover.
52023
+ serverNoContextTakeover: true,
52024
+ clientNoContextTakeover: true
52025
+ };
51869
52026
  }
51870
52027
  });
51871
52028
 
51872
52029
  // packages/server/src/local-file-watch.ts
51873
52030
  import { watch } from "node:fs";
51874
- import { basename as basename11, dirname as dirname16 } from "node:path";
52031
+ import { basename as basename11, dirname as dirname17 } from "node:path";
51875
52032
  function close(path) {
51876
52033
  const entry = entries.get(path);
51877
52034
  if (!entry) return;
@@ -51886,7 +52043,7 @@ function watchLocalFile(path, onChange) {
51886
52043
  let entry = entries.get(path);
51887
52044
  if (!entry) {
51888
52045
  const name = basename11(path);
51889
- const watcher2 = watch(dirname16(path), { persistent: false }, (_event, changed) => {
52046
+ const watcher2 = watch(dirname17(path), { persistent: false }, (_event, changed) => {
51890
52047
  if (changed !== null && changed !== void 0 && changed.toString() !== name) return;
51891
52048
  const current = entries.get(path);
51892
52049
  if (!current) return;
@@ -51920,7 +52077,7 @@ var init_local_file_watch = __esm({
51920
52077
 
51921
52078
  // packages/server/src/boot-progress.ts
51922
52079
  import { mkdirSync as mkdirSync18, readFileSync as readFileSync28, renameSync as renameSync10, rmSync as rmSync11, writeFileSync as writeFileSync15 } from "node:fs";
51923
- import { basename as basename12, dirname as dirname17, join as join40 } from "node:path";
52080
+ import { basename as basename12, dirname as dirname18, join as join40 } from "node:path";
51924
52081
  function bootProgressPath(stateDir) {
51925
52082
  return join40(stateDir, BOOT_PROGRESS_NAME);
51926
52083
  }
@@ -51942,8 +52099,8 @@ function createBootProgressPublisher(stateDir, minIntervalMs = 200) {
51942
52099
  lastAt = now;
51943
52100
  step++;
51944
52101
  try {
51945
- mkdirSync18(dirname17(path), { recursive: true, mode: 448 });
51946
- const temp = join40(dirname17(path), `.${basename12(path)}.${process.pid}.tmp`);
52102
+ mkdirSync18(dirname18(path), { recursive: true, mode: 448 });
52103
+ const temp = join40(dirname18(path), `.${basename12(path)}.${process.pid}.tmp`);
51947
52104
  writeFileSync15(temp, `${JSON.stringify({ pid: process.pid, step, phase, at: new Date(now).toISOString() })}
51948
52105
  `, "utf8");
51949
52106
  renameSync10(temp, path);
@@ -52496,12 +52653,12 @@ var init_legacy_project_db = __esm({
52496
52653
 
52497
52654
  // packages/server/src/frizz-db.ts
52498
52655
  import { existsSync as existsSync14, mkdirSync as mkdirSync19, readdirSync as readdirSync12, renameSync as renameSync11, statSync as statSync21 } from "node:fs";
52499
- import { basename as basename13, dirname as dirname18, join as join41 } from "node:path";
52656
+ import { basename as basename13, dirname as dirname19, join as join41 } from "node:path";
52500
52657
  function frizzDatabaseLocation(options) {
52501
52658
  if (options.stateDir !== void 0) {
52502
- const projectsDir = dirname18(options.stateDir);
52659
+ const projectsDir = dirname19(options.stateDir);
52503
52660
  if (basename13(projectsDir) === "projects") {
52504
- return { path: options.path ?? join41(dirname18(projectsDir), "ui.db"), projectsDir };
52661
+ return { path: options.path ?? join41(dirname19(projectsDir), "ui.db"), projectsDir };
52505
52662
  }
52506
52663
  return { path: options.path ?? join41(options.stateDir, "ui.db"), projectsDir: void 0 };
52507
52664
  }
@@ -52525,7 +52682,7 @@ function ensureFrizzSchema(db) {
52525
52682
  }
52526
52683
  function openFrizzDatabase(options = {}) {
52527
52684
  const { path, projectsDir } = frizzDatabaseLocation(options);
52528
- mkdirSync19(dirname18(path), { recursive: true });
52685
+ mkdirSync19(dirname19(path), { recursive: true });
52529
52686
  const db = new sqlite_default(path);
52530
52687
  db.pragma("busy_timeout = 5000");
52531
52688
  db.pragma("journal_mode = WAL");
@@ -52684,6 +52841,7 @@ function startTenantPrime(deps) {
52684
52841
  result.skipped.push(entry.id);
52685
52842
  continue;
52686
52843
  }
52844
+ const resolveStartedAt = deps.monotonicNow?.() ?? performance.now();
52687
52845
  let project;
52688
52846
  try {
52689
52847
  project = deps.toProject(entry);
@@ -52698,12 +52856,13 @@ function startTenantPrime(deps) {
52698
52856
  log3(`${project.name} is served by another Frizz (pid ${other}) \u2014 leaving it closed here`);
52699
52857
  continue;
52700
52858
  }
52859
+ const resolveMs = (deps.monotonicNow?.() ?? performance.now()) - resolveStartedAt;
52701
52860
  if (lastTookMs !== void 0) await delay2(deps.gapMs ?? gapAfter(lastTookMs));
52702
52861
  if (stopped) break;
52703
52862
  try {
52704
52863
  const startedAt = deps.monotonicNow?.() ?? performance.now();
52705
52864
  const opened = await deps.activate(project);
52706
- const tookMs = Math.round((deps.monotonicNow?.() ?? performance.now()) - startedAt);
52865
+ const tookMs = Math.round(resolveMs + ((deps.monotonicNow?.() ?? performance.now()) - startedAt));
52707
52866
  lastTookMs = tookMs;
52708
52867
  if (opened === void 0) result.failed.push(entry.id);
52709
52868
  else {
@@ -52740,14 +52899,14 @@ var init_tenant_prime = __esm({
52740
52899
  init_logging();
52741
52900
  PRIME_START_DELAY_MS = 250;
52742
52901
  PRIME_MIN_GAP_MS = 25;
52743
- PRIME_MAX_GAP_MS = 250;
52902
+ PRIME_MAX_GAP_MS = 1500;
52744
52903
  }
52745
52904
  });
52746
52905
 
52747
52906
  // packages/server/src/project-teardown.ts
52748
52907
  import { rmSync as rmSync12 } from "node:fs";
52749
52908
  import { homedir as homedir19 } from "node:os";
52750
- import { dirname as dirname19, resolve as resolve10 } from "node:path";
52909
+ import { dirname as dirname20, resolve as resolve10 } from "node:path";
52751
52910
  async function stopProjectWorkers(ctx) {
52752
52911
  let stopped = 0;
52753
52912
  for (const row of ctx.storage.allSessions()) {
@@ -52767,7 +52926,7 @@ function deleteProjectState(projectId, home = homedir19()) {
52767
52926
  if (!/^[\w.-]+$/u.test(projectId) || projectId === "." || projectId === "..") {
52768
52927
  throw new Error(`Refusing to delete state for a malformed project id: ${projectId}`);
52769
52928
  }
52770
- if (dirname19(resolve10(target)) !== resolve10(dirname19(projectStateDir("x", home)))) {
52929
+ if (dirname20(resolve10(target)) !== resolve10(dirname20(projectStateDir("x", home)))) {
52771
52930
  throw new Error(`Refusing to delete ${target} \u2014 it is not a project state directory`);
52772
52931
  }
52773
52932
  rmSync12(target, { recursive: true, force: true });
@@ -52790,13 +52949,14 @@ __export(index_exports, {
52790
52949
  createShutdownSignalHandler: () => createShutdownSignalHandler,
52791
52950
  pipeToApp: () => pipeToApp,
52792
52951
  registeredTenantHealth: () => registeredTenantHealth,
52952
+ serveStatic: () => serveStatic,
52793
52953
  splitTenantRequest: () => splitTenantRequest,
52794
52954
  startServer: () => startServer,
52795
52955
  unknownProjectPage: () => unknownProjectPage
52796
52956
  });
52797
52957
  import { createServer } from "node:http";
52798
- import { readFileSync as readFileSync29, existsSync as existsSync15 } from "node:fs";
52799
- import { dirname as dirname20, join as join42, resolve as resolve11, extname as extname4, normalize } from "node:path";
52958
+ import { readFileSync as readFileSync29, existsSync as existsSync15, statSync as statSync22 } from "node:fs";
52959
+ import { dirname as dirname21, join as join42, resolve as resolve11, extname as extname4, normalize, sep as sep5 } from "node:path";
52800
52960
  function readServerAddressHolder(path) {
52801
52961
  try {
52802
52962
  const value = JSON.parse(readFileSync29(path, "utf8"));
@@ -52897,14 +53057,63 @@ function createShutdownSignalHandler(options) {
52897
53057
  );
52898
53058
  };
52899
53059
  }
53060
+ function encodedStatic(key, encoding, raw2) {
53061
+ const hit = staticEncodedCache.get(key);
53062
+ if (hit) return hit;
53063
+ const out = compress(raw2, encoding);
53064
+ if (staticEncodedCacheBytes + out.byteLength > STATIC_ENCODED_CACHE_MAX_BYTES) {
53065
+ staticEncodedCache.clear();
53066
+ staticEncodedCacheBytes = 0;
53067
+ }
53068
+ staticEncodedCache.set(key, out);
53069
+ staticEncodedCacheBytes += out.byteLength;
53070
+ return out;
53071
+ }
53072
+ function staticIsFresh(req, etag, mtimeMs) {
53073
+ const ifNoneMatch = req.headers["if-none-match"];
53074
+ if (ifNoneMatch) {
53075
+ return ifNoneMatch.split(",").some((candidate) => {
53076
+ const tag = candidate.trim();
53077
+ return tag === "*" || tag.replace(/^W\//, "") === etag;
53078
+ });
53079
+ }
53080
+ const ifModifiedSince = req.headers["if-modified-since"];
53081
+ if (!ifModifiedSince) return false;
53082
+ const since = Date.parse(ifModifiedSince);
53083
+ return Number.isFinite(since) && Math.floor(mtimeMs / 1e3) <= Math.floor(since / 1e3);
53084
+ }
52900
53085
  function serveStatic(distDir, req, res) {
52901
53086
  const rel = normalize((req.url ?? "/").split("?")[0]).replace(/^(\.\.[/\\])+/, "");
52902
53087
  let file = join42(distDir, rel === "/" ? "index.html" : rel);
52903
53088
  if (!file.startsWith(distDir)) file = join42(distDir, "index.html");
52904
53089
  if (!existsSync15(file)) file = join42(distDir, "index.html");
52905
53090
  try {
52906
- const body = readFileSync29(file);
52907
- res.writeHead(200, { "content-type": MIME[extname4(file)] ?? "application/octet-stream" });
53091
+ const stats = statSync22(file);
53092
+ const cacheControl = file.startsWith(join42(distDir, "assets") + sep5) ? STATIC_CACHE_IMMUTABLE : STATIC_CACHE_REVALIDATE;
53093
+ const etag = `"${stats.size.toString(16)}-${Math.trunc(stats.mtimeMs).toString(16)}"`;
53094
+ const headers = {
53095
+ "content-type": MIME[extname4(file)] ?? "application/octet-stream",
53096
+ "cache-control": cacheControl,
53097
+ etag,
53098
+ "last-modified": stats.mtime.toUTCString(),
53099
+ // Sent on every static response, not just the compressed ones: a shared cache in front of a
53100
+ // tunnelled Frizz must not hand a brotli body to a client that asked for identity.
53101
+ vary: "Accept-Encoding"
53102
+ };
53103
+ if (staticIsFresh(req, etag, stats.mtimeMs)) {
53104
+ res.writeHead(304, headers);
53105
+ res.end();
53106
+ return;
53107
+ }
53108
+ let body = readFileSync29(file);
53109
+ const accept = req.headers["accept-encoding"];
53110
+ const encoding = negotiateEncoding(Array.isArray(accept) ? accept.join(",") : accept);
53111
+ if (encoding && shouldCompress(new Headers({ "content-type": headers["content-type"] }), body.byteLength)) {
53112
+ body = encodedStatic(`${encoding}:${file}:${etag}`, encoding, body);
53113
+ headers["content-encoding"] = encoding;
53114
+ }
53115
+ headers["content-length"] = String(body.byteLength);
53116
+ res.writeHead(200, headers);
52908
53117
  res.end(body);
52909
53118
  } catch {
52910
53119
  res.writeHead(404);
@@ -53153,7 +53362,7 @@ async function startServer(opts = {}) {
53153
53362
  if (statusPath && statusIdentity) runtime.removeStatus(statusPath, statusIdentity);
53154
53363
  if (statusPath && statusIdentity) {
53155
53364
  try {
53156
- runtime.removeStatus(serverAddressPathForStateDir(dirname20(statusPath)), statusIdentity);
53365
+ runtime.removeStatus(serverAddressPathForStateDir(dirname21(statusPath)), statusIdentity);
53157
53366
  } catch {
53158
53367
  }
53159
53368
  }
@@ -53501,13 +53710,14 @@ async function startServer(opts = {}) {
53501
53710
  });
53502
53711
  }
53503
53712
  }
53504
- var SERVER_SHUTDOWN_TIMEOUT_MS, SERVER_FORCE_EXIT_MS, defaultStartServerRuntime, ServerStartupError, isApiUrl, serverLockPathFor, MIME;
53713
+ var SERVER_SHUTDOWN_TIMEOUT_MS, SERVER_FORCE_EXIT_MS, defaultStartServerRuntime, ServerStartupError, isApiUrl, serverLockPathFor, MIME, STATIC_CACHE_IMMUTABLE, STATIC_CACHE_REVALIDATE, staticEncodedCache, STATIC_ENCODED_CACHE_MAX_BYTES, staticEncodedCacheBytes;
53505
53714
  var init_index = __esm({
53506
53715
  "packages/server/src/index.ts"() {
53507
53716
  "use strict";
53508
53717
  init_src();
53509
53718
  init_context();
53510
53719
  init_app();
53720
+ init_compression();
53511
53721
  init_terminal();
53512
53722
  init_app_socket();
53513
53723
  init_shutdown();
@@ -53575,6 +53785,11 @@ var init_index = __esm({
53575
53785
  ".ico": "image/x-icon",
53576
53786
  ".woff2": "font/woff2"
53577
53787
  };
53788
+ STATIC_CACHE_IMMUTABLE = "public, max-age=31536000, immutable";
53789
+ STATIC_CACHE_REVALIDATE = "no-cache";
53790
+ staticEncodedCache = /* @__PURE__ */ new Map();
53791
+ STATIC_ENCODED_CACHE_MAX_BYTES = 32 * 1024 * 1024;
53792
+ staticEncodedCacheBytes = 0;
53578
53793
  }
53579
53794
  });
53580
53795