frizz 0.10.0 → 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.
- package/dist/dev-child.js +408 -190
- package/dist/frizz.js +243 -13
- package/package.json +2 -2
- package/web-dist/assets/{TerminalPane-XNji7D_c.js → TerminalPane-DzTdpZim.js} +1 -1
- package/web-dist/assets/{abnfDiagram-VRR7QNED-gPeb-B7g.js → abnfDiagram-VRR7QNED-BpxlBYqa.js} +1 -1
- package/web-dist/assets/architecture-TIHT7OUA-Cyj72dua.js +1 -0
- package/web-dist/assets/{architectureDiagram-ZJ3FMSHR-DV69ktbl.js → architectureDiagram-ZJ3FMSHR-yyvTAq0j.js} +1 -1
- package/web-dist/assets/{blockDiagram-677ZJIJ3-D8vw5eim.js → blockDiagram-677ZJIJ3-BLqVDdZ-.js} +1 -1
- package/web-dist/assets/{c4Diagram-LMCZKHZV--9PLGn-L.js → c4Diagram-LMCZKHZV-BrKEPLUT.js} +1 -1
- package/web-dist/assets/channel-DgpcWDXI.js +1 -0
- package/web-dist/assets/{chunk-32BRIVSS-D4BSk0FZ.js → chunk-32BRIVSS-S-tSRtT-.js} +1 -1
- package/web-dist/assets/{chunk-52WLFC77-WNcmTkcR.js → chunk-52WLFC77-DE9X7l52.js} +1 -1
- package/web-dist/assets/{chunk-C7G6YPKG-BDlcLa5W.js → chunk-C7G6YPKG-BdNBZMEZ.js} +1 -1
- package/web-dist/assets/{chunk-EX3LRPZG-CFnqFt7s.js → chunk-EX3LRPZG-D1TPCp23.js} +1 -1
- package/web-dist/assets/{chunk-FWX5IMBZ-Ci9LgOOg.js → chunk-FWX5IMBZ-Bi7A_VUf.js} +2 -2
- package/web-dist/assets/{chunk-HOUHSVGY-BTD_X5OP.js → chunk-HOUHSVGY-cdZH3cLd.js} +1 -1
- package/web-dist/assets/{chunk-ICXQ74PX-D2Y3Ys5K.js → chunk-ICXQ74PX-C4V2E3yL.js} +1 -1
- package/web-dist/assets/{chunk-MOJQB5TN-C-GDt7vC.js → chunk-MOJQB5TN-C-zmX9mY.js} +1 -1
- package/web-dist/assets/{chunk-OGEWGWER-DvnPoUnz.js → chunk-OGEWGWER-CwGTe6tT.js} +1 -1
- package/web-dist/assets/{chunk-PUDLZKDR-C3AymM-j.js → chunk-PUDLZKDR-D7GuPy2U.js} +1 -1
- package/web-dist/assets/{chunk-Q4XR5HBZ-DmyBNAl6.js → chunk-Q4XR5HBZ-4DNJYqvP.js} +1 -1
- package/web-dist/assets/{chunk-V7JOEXUC-DTuPUeRa.js → chunk-V7JOEXUC-CdOmZJqy.js} +1 -1
- package/web-dist/assets/{chunk-VAUOI2AC-CcW8PviB.js → chunk-VAUOI2AC-D0qOoeHa.js} +1 -1
- package/web-dist/assets/{chunk-VR4S4FIN-0tm6n83G.js → chunk-VR4S4FIN-D13PW9Ld.js} +1 -1
- package/web-dist/assets/{chunk-WYO6CB5R-CH3ADqeI.js → chunk-WYO6CB5R-DPd8fNip.js} +1 -1
- package/web-dist/assets/{chunk-ZGVPDNZ5-BHFnlpXH.js → chunk-ZGVPDNZ5-DEoZANj0.js} +1 -1
- package/web-dist/assets/classDiagram-OUVF2IWQ-22nxxqBO.js +1 -0
- package/web-dist/assets/classDiagram-v2-EOCWNBFH-22nxxqBO.js +1 -0
- package/web-dist/assets/{cynefin-VYW2F7L2-DtFCLOIN.js → cynefin-VYW2F7L2-CQfP_SH_.js} +1 -1
- package/web-dist/assets/{cynefinDiagram-TSTJHNR4-llFTHp2q.js → cynefinDiagram-TSTJHNR4-B_q23LrX.js} +1 -1
- package/web-dist/assets/{dagre-VKFMJZFB-CvBRVl_k.js → dagre-VKFMJZFB-Drf-81Vi.js} +1 -1
- package/web-dist/assets/{diagram-FQU43EPY-D1QXo6ri.js → diagram-FQU43EPY-CreTIGTP.js} +1 -1
- package/web-dist/assets/{diagram-G47NLZAW-2pZew-Bk.js → diagram-G47NLZAW-BBNZRSgW.js} +1 -1
- package/web-dist/assets/{diagram-NH7WQ7WH-Ch9JRwGN.js → diagram-NH7WQ7WH-DITd_c_z.js} +1 -1
- package/web-dist/assets/{diagram-OA4YK3LP-BIbrLf02.js → diagram-OA4YK3LP-HMl5mDli.js} +1 -1
- package/web-dist/assets/{diagram-WEI45ONY-D3KtL2s-.js → diagram-WEI45ONY-CxkP1cxL.js} +1 -1
- package/web-dist/assets/{ebnfDiagram-CCIWWBDH-D829sKG_.js → ebnfDiagram-CCIWWBDH-cOqwSqSu.js} +1 -1
- package/web-dist/assets/{erDiagram-Q63AITRT-Cj3Grovg.js → erDiagram-Q63AITRT-CEaFJZJ5.js} +1 -1
- package/web-dist/assets/eventmodeling-45OFAUF4-OZo7EY27.js +1 -0
- package/web-dist/assets/flowDiagram-23GEKE2U-BTrtNMK0.js +1 -0
- package/web-dist/assets/{ganttDiagram-NO4QXBWP-CGHaXF-g.js → ganttDiagram-NO4QXBWP-B83_pEFL.js} +1 -1
- package/web-dist/assets/{gitGraph-TEB2WS4Q-BbxeaotX.js → gitGraph-TEB2WS4Q-CcZy9vvP.js} +1 -1
- package/web-dist/assets/{gitGraphDiagram-IHSO6WYX-C4WHE0cI.js → gitGraphDiagram-IHSO6WYX-dHJwoE1p.js} +1 -1
- package/web-dist/assets/{index-BpCFdr7Z.css → index-C_iC5T6e.css} +1 -1
- package/web-dist/assets/index-DRUjlRIw.js +318 -0
- package/web-dist/assets/{info-DKCQHKI2-3fKpn7Qr.js → info-DKCQHKI2-DqY5he2n.js} +1 -1
- package/web-dist/assets/{infoDiagram-FWYZ7A6U-CDQl4JMv.js → infoDiagram-FWYZ7A6U-COKKCbGB.js} +1 -1
- package/web-dist/assets/{ishikawaDiagram-FXEZZL3T-CDKjMW-u.js → ishikawaDiagram-FXEZZL3T-C8yanhbC.js} +1 -1
- package/web-dist/assets/{journeyDiagram-5HDEW3XC-BOsabu1Z.js → journeyDiagram-5HDEW3XC-xOm9kUhr.js} +1 -1
- package/web-dist/assets/{kanban-definition-HUTT4EX6-KTuh-6eN.js → kanban-definition-HUTT4EX6-Cs_nVoSG.js} +1 -1
- package/web-dist/assets/{line-KaxbYSN3.js → line-BRWDTY95.js} +1 -1
- package/web-dist/assets/{mermaid-parser.core-B53huyyd.js → mermaid-parser.core-_snubxnm.js} +3 -3
- package/web-dist/assets/{mermaid.core-Bz6B5ouC.js → mermaid.core-B_sHF_kX.js} +3 -3
- package/web-dist/assets/{mindmap-definition-LN4V7U3C-Bb7T7B3a.js → mindmap-definition-LN4V7U3C-CROqMxsQ.js} +1 -1
- package/web-dist/assets/{packet-7NZHBO7P-w3lynC8r.js → packet-7NZHBO7P-Cy6k0ePg.js} +1 -1
- package/web-dist/assets/{pegDiagram-2B236MQR-nQ7c2Z03.js → pegDiagram-2B236MQR-CiPu5Dg4.js} +1 -1
- package/web-dist/assets/{pie-RZYD4A2V-B3Yko5Wb.js → pie-RZYD4A2V-BGbuoQNT.js} +1 -1
- package/web-dist/assets/{pieDiagram-ENE6RG2P-CN4Lp5HG.js → pieDiagram-ENE6RG2P-DXkmXblw.js} +1 -1
- package/web-dist/assets/{quadrantDiagram-ABIIQ3AL-3QTB92dH.js → quadrantDiagram-ABIIQ3AL-BanFSlsg.js} +1 -1
- package/web-dist/assets/{radar-I7S5WNFK-8ZsXt0FI.js → radar-I7S5WNFK-CGQFn8j-.js} +1 -1
- package/web-dist/assets/{railroad-3IZDKUUU-C4IKxzEZ.js → railroad-3IZDKUUU-B5ADtgsA.js} +1 -1
- package/web-dist/assets/railroad-abnf-AHOZXSZD-C5nN5q7B.js +1 -0
- package/web-dist/assets/railroad-ebnf-EBAXGLYW-Bmr9Qqwv.js +1 -0
- package/web-dist/assets/railroad-peg-LSFZ7HO6-CEoELuaR.js +1 -0
- package/web-dist/assets/{railroadDiagram-RFXS5EU6-DrGnmjpD.js → railroadDiagram-RFXS5EU6-CItx2rmJ.js} +1 -1
- package/web-dist/assets/{requirementDiagram-TGXJPOKE-Bh9XNuxa.js → requirementDiagram-TGXJPOKE-xR5EF8t9.js} +1 -1
- package/web-dist/assets/{sankeyDiagram-HTMAVEWB-CXy3ra5-.js → sankeyDiagram-HTMAVEWB-5Xc3Jm9J.js} +1 -1
- package/web-dist/assets/{sequenceDiagram-DBY2YBRQ-B7ESCT52.js → sequenceDiagram-DBY2YBRQ-vKameWMa.js} +1 -1
- package/web-dist/assets/{stateDiagram-2N3HPSRC-DFr9k5Xv.js → stateDiagram-2N3HPSRC-cd0jZZvF.js} +1 -1
- package/web-dist/assets/stateDiagram-v2-6OUMAXLB-CxXmUa7L.js +1 -0
- package/web-dist/assets/{swimlanes-5IMT3BWC-B2RKoz1q.js → swimlanes-5IMT3BWC-9iMSvVuR.js} +1 -1
- package/web-dist/assets/swimlanesDiagram-G3AALYLV-VlGeDigP.js +8 -0
- package/web-dist/assets/{timeline-definition-FHXFAJF6-KpTqaG5g.js → timeline-definition-FHXFAJF6-C6_2LRwZ.js} +1 -1
- package/web-dist/assets/{treeView-QDETBFTQ-oB1a6ikv.js → treeView-QDETBFTQ-CX8-eA8C.js} +1 -1
- package/web-dist/assets/{treemap-6X3UGDF4-DO8OvvZg.js → treemap-6X3UGDF4-DaUY20IG.js} +1 -1
- package/web-dist/assets/{vennDiagram-L72KCM5P-BgTjK4_q.js → vennDiagram-L72KCM5P-CZLt-iPN.js} +1 -1
- package/web-dist/assets/{wardley-OPB4EBWU-CGyjn939.js → wardley-OPB4EBWU-Cjp9-zMo.js} +1 -1
- package/web-dist/assets/{wardleyDiagram-EHGQE667-CM_HxruS.js → wardleyDiagram-EHGQE667-BF_U8_o5.js} +1 -1
- package/web-dist/assets/{xychartDiagram-FW5EYKEG-vamHu0jN.js → xychartDiagram-FW5EYKEG-CJEIPPRH.js} +1 -1
- package/web-dist/index.html +2 -2
- package/web-dist/assets/architecture-TIHT7OUA-BsgSgexh.js +0 -1
- package/web-dist/assets/channel-ClLnncxh.js +0 -1
- package/web-dist/assets/classDiagram-OUVF2IWQ-CwLnPgud.js +0 -1
- package/web-dist/assets/classDiagram-v2-EOCWNBFH-CwLnPgud.js +0 -1
- package/web-dist/assets/eventmodeling-45OFAUF4-CzZyv3HA.js +0 -1
- package/web-dist/assets/flowDiagram-23GEKE2U-rQ7PRoGL.js +0 -1
- package/web-dist/assets/index-CiaKj-0V.js +0 -506
- package/web-dist/assets/railroad-abnf-AHOZXSZD-g2si5iUv.js +0 -1
- package/web-dist/assets/railroad-ebnf-EBAXGLYW-BikkLG6y.js +0 -1
- package/web-dist/assets/railroad-peg-LSFZ7HO6-Dv4rDehz.js +0 -1
- package/web-dist/assets/stateDiagram-v2-6OUMAXLB-BQUd0MEa.js +0 -1
- package/web-dist/assets/swimlanesDiagram-G3AALYLV-GWn4zXxj.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:
|
|
4765
|
+
const { start, key, sep: sep6, value } = collItem;
|
|
4766
4766
|
const keyProps = resolveProps.resolveProps(start, {
|
|
4767
4767
|
indicator: "explicit-key-ind",
|
|
4768
|
-
next: key ??
|
|
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 && !
|
|
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(
|
|
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,
|
|
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
|
|
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 +=
|
|
4928
|
-
|
|
4927
|
+
comment += sep6 + cb;
|
|
4928
|
+
sep6 = "";
|
|
4929
4929
|
break;
|
|
4930
4930
|
}
|
|
4931
4931
|
case "newline":
|
|
4932
4932
|
if (comment)
|
|
4933
|
-
|
|
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:
|
|
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 ??
|
|
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 && !
|
|
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 && !
|
|
5042
|
-
const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end,
|
|
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(
|
|
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 (
|
|
5066
|
-
for (const st of
|
|
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,
|
|
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
|
|
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 +=
|
|
5281
|
-
|
|
5280
|
+
value += sep6 + indent.slice(trimIndent) + content;
|
|
5281
|
+
sep6 = "\n";
|
|
5282
5282
|
} else if (indent.length > trimIndent || content[0] === " ") {
|
|
5283
|
-
if (
|
|
5284
|
-
|
|
5285
|
-
else if (!prevMoreIndented &&
|
|
5286
|
-
|
|
5287
|
-
value +=
|
|
5288
|
-
|
|
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 (
|
|
5291
|
+
if (sep6 === "\n")
|
|
5292
5292
|
value += "\n";
|
|
5293
5293
|
else
|
|
5294
|
-
|
|
5294
|
+
sep6 = "\n";
|
|
5295
5295
|
} else {
|
|
5296
|
-
value +=
|
|
5297
|
-
|
|
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
|
|
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 (
|
|
5485
|
-
res +=
|
|
5484
|
+
if (sep6 === "\n")
|
|
5485
|
+
res += sep6;
|
|
5486
5486
|
else
|
|
5487
|
-
|
|
5487
|
+
sep6 = "\n";
|
|
5488
5488
|
} else {
|
|
5489
|
-
res +=
|
|
5490
|
-
|
|
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 +
|
|
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:
|
|
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 (
|
|
6314
|
-
for (const st of
|
|
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
|
|
7481
|
+
let sep6;
|
|
7482
7482
|
if (scalar.end) {
|
|
7483
|
-
|
|
7484
|
-
|
|
7483
|
+
sep6 = scalar.end;
|
|
7484
|
+
sep6.push(this.sourceToken);
|
|
7485
7485
|
delete scalar.end;
|
|
7486
7486
|
} else
|
|
7487
|
-
|
|
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:
|
|
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
|
|
7646
|
-
|
|
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:
|
|
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
|
|
7848
|
-
|
|
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:
|
|
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
|
|
15751
|
-
|
|
15752
|
-
|
|
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
|
|
@@ -19259,6 +19294,7 @@ function createStorage(source, projectId) {
|
|
|
19259
19294
|
SET model = ?, effort = ?, profile_revision = profile_revision + 1
|
|
19260
19295
|
WHERE project_id = @project_id AND slug = ? AND session_id = ? AND runtime_generation = ?
|
|
19261
19296
|
AND runtime_control IS NULL AND profile_pending_model IS NULL AND profile_pending_effort IS NULL
|
|
19297
|
+
AND (profile_set_at IS NULL OR backend = 'codex')
|
|
19262
19298
|
AND (model IS NOT ? OR effort IS NOT ?)
|
|
19263
19299
|
`);
|
|
19264
19300
|
const beginRuntimeGenerationStmt = scope.prepare(`
|
|
@@ -19599,6 +19635,9 @@ function createStorage(source, projectId) {
|
|
|
19599
19635
|
resetParkBumps: (slug) => void resetParkBumpsStmt.run(slug),
|
|
19600
19636
|
armPrWatch: (watch2) => void armPrWatchStmt.run(watch2),
|
|
19601
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()),
|
|
19602
19641
|
getPrWatch: (id) => prWatchByIdStmt.get(id),
|
|
19603
19642
|
armedPrWatches: () => armedPrWatchesStmt.all(),
|
|
19604
19643
|
expiredPrWatches: (nowMs) => expiredPrWatchesStmt.all(nowMs),
|
|
@@ -19616,6 +19655,9 @@ function createStorage(source, projectId) {
|
|
|
19616
19655
|
return threadWatchByIdStmt.get(w.id);
|
|
19617
19656
|
},
|
|
19618
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()),
|
|
19619
19661
|
getThreadWatch: (id) => threadWatchByIdStmt.get(id),
|
|
19620
19662
|
expiredThreadWatches: (nowMs) => expiredThreadWatchesStmt.all(nowMs),
|
|
19621
19663
|
armedThreadWatches: () => armedThreadWatchesStmt.all(),
|
|
@@ -19624,6 +19666,7 @@ function createStorage(source, projectId) {
|
|
|
19624
19666
|
return threadQuestionByIdStmt.get(q.id);
|
|
19625
19667
|
},
|
|
19626
19668
|
listThreadQuestions: (slug, opts) => (opts?.openOnly ? openThreadQuestionsBySlugStmt : threadQuestionsBySlugStmt).all(slug),
|
|
19669
|
+
threadQuestionsBySlug: () => groupBySlug(allThreadQuestionsStmt.all()),
|
|
19627
19670
|
getThreadQuestion: (id) => threadQuestionByIdStmt.get(id),
|
|
19628
19671
|
openThreadQuestions: () => openThreadQuestionsStmt.all(),
|
|
19629
19672
|
answerThreadQuestion: (id, answer, atMs) => answerThreadQuestionStmt.run(answer, atMs, id).changes === 1,
|
|
@@ -19638,11 +19681,19 @@ function createStorage(source, projectId) {
|
|
|
19638
19681
|
const row = getThreadDoneStmt.get(slug);
|
|
19639
19682
|
return row ? { body: row.body, doneAt: row.done_at } : void 0;
|
|
19640
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
|
+
},
|
|
19641
19691
|
clearThreadDone: (slug) => clearThreadDoneStmt.run(slug).changes > 0,
|
|
19642
19692
|
dropThreadWatch: (slug, id, settledAtMs) => dropThreadWatchStmt.run(settledAtMs, id, slug).changes === 1,
|
|
19643
19693
|
settleThreadWatch: (id, settledAtMs, state = "settled") => settleThreadWatchStmt.run(state, settledAtMs, id).changes === 1,
|
|
19644
19694
|
armThreadTimer: (timer) => void armTimerStmt.run(timer),
|
|
19645
19695
|
listThreadTimers: (slug, opts) => (opts?.armedOnly ? armedTimersBySlugStmt : timersBySlugStmt).all(slug),
|
|
19696
|
+
armedThreadTimersBySlug: () => groupBySlug(armedTimersStmt.all()),
|
|
19646
19697
|
getThreadTimer: (id) => timerByIdStmt.get(id),
|
|
19647
19698
|
dueThreadTimers: (nowMs) => dueTimersStmt.all(nowMs),
|
|
19648
19699
|
cancelThreadTimer: (slug, id, settledAtMs) => cancelTimerStmt.run(settledAtMs, id, slug).changes === 1,
|
|
@@ -22695,20 +22746,41 @@ var init_tail_cache = __esm({
|
|
|
22695
22746
|
|
|
22696
22747
|
// packages/server/src/tailer.ts
|
|
22697
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";
|
|
22698
|
-
import {
|
|
22749
|
+
import { execFile as execFile2 } from "node:child_process";
|
|
22750
|
+
import { promisify as promisify2 } from "node:util";
|
|
22699
22751
|
import { basename as basename4, join as join18 } from "node:path";
|
|
22700
22752
|
import { homedir as homedir7 } from "node:os";
|
|
22701
|
-
function
|
|
22702
|
-
|
|
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 = "";
|
|
22703
22769
|
try {
|
|
22704
|
-
|
|
22705
|
-
return out.trim().length > 0;
|
|
22770
|
+
stdout = (await execFileAsync("lsof", ["-F", "pn", "--", ...live.map((f) => f.real)], { encoding: "utf8", timeout: 8e3 })).stdout;
|
|
22706
22771
|
} catch (err) {
|
|
22707
22772
|
const e = err;
|
|
22708
|
-
|
|
22709
|
-
if (
|
|
22710
|
-
|
|
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 ?? "";
|
|
22711
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;
|
|
22712
22784
|
}
|
|
22713
22785
|
function activityMinute(at) {
|
|
22714
22786
|
if (!at) return "";
|
|
@@ -23905,16 +23977,48 @@ ${ask}`;
|
|
|
23905
23977
|
return void 0;
|
|
23906
23978
|
}
|
|
23907
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
|
+
}
|
|
23908
24007
|
function shellIsGone(e) {
|
|
23909
24008
|
if (!e.outputFile) return false;
|
|
23910
24009
|
const started = Date.parse(e.startedAt);
|
|
23911
24010
|
if (!Number.isFinite(started) || now() - started < SHELL_PROBE_GRACE_MS) return false;
|
|
23912
24011
|
const cached2 = shellAliveCache.get(e.outputFile);
|
|
23913
24012
|
if (cached2 && (cached2.alive === false || now() - cached2.at < SHELL_PROBE_TTL_MS)) return !cached2.alive;
|
|
23914
|
-
|
|
23915
|
-
|
|
23916
|
-
|
|
23917
|
-
|
|
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;
|
|
23918
24022
|
}
|
|
23919
24023
|
function backgroundShellLookup(slug, id) {
|
|
23920
24024
|
const state = states.get(slug);
|
|
@@ -24395,14 +24499,27 @@ ${detail2}
|
|
|
24395
24499
|
let primedRows = 0;
|
|
24396
24500
|
const tickStartedMs = monotonicNow();
|
|
24397
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
|
+
);
|
|
24398
24509
|
for (const row of rows) {
|
|
24399
24510
|
if (primeProgress && primed % PRIME_PROGRESS_EVERY === 0) primeProgress(primed, rows.length);
|
|
24400
24511
|
primed++;
|
|
24401
24512
|
const backend = resolveBackend(row.backend);
|
|
24402
24513
|
const nativeId = row.agent_session_id ?? row.transcript_id ?? row.session_id;
|
|
24403
|
-
|
|
24514
|
+
const known = states.get(row.slug);
|
|
24404
24515
|
const runtimeGeneration = row.runtime_generation ?? 0;
|
|
24405
|
-
|
|
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) {
|
|
24406
24523
|
const path = backend.transcriptPath(nativeId) ?? join18(logDir, `${nativeId}.jsonl`);
|
|
24407
24524
|
state = newTailState(row.slug, row.session_id, path, false, nativeId, runtimeGeneration);
|
|
24408
24525
|
state.dismissedOps = deps.storage.retiredOps(row.slug, row.session_id);
|
|
@@ -24416,13 +24533,7 @@ ${detail2}
|
|
|
24416
24533
|
const prevNoTranscript = state.noTranscript;
|
|
24417
24534
|
if (row.backend !== "codex" && !resolveTranscript(state, row, nowMs)) continue;
|
|
24418
24535
|
if (!state.primed) {
|
|
24419
|
-
if (
|
|
24420
|
-
// Yield the slot to a still-cold visible row — but never at the cost of the forward-progress
|
|
24421
|
-
// guarantee below. `primedRows > 0` keeps the archive advancing by at least one row per tick
|
|
24422
|
-
// even if a visible row were somehow to stay cold indefinitely, so deferral can never become
|
|
24423
|
-
// starvation. The visible row still primes on this same tick; it just is not necessarily first.
|
|
24424
|
-
coldVisibleRow && primedRows > 0 && rowIsArchived(row) || primedRows >= MAX_PRIME_ROWS_PER_TICK || primedRows > 0 && monotonicNow() - tickStartedMs > PRIME_BUDGET_MS
|
|
24425
|
-
) {
|
|
24536
|
+
if (primeDeferred(row)) {
|
|
24426
24537
|
primeIncomplete = true;
|
|
24427
24538
|
continue;
|
|
24428
24539
|
}
|
|
@@ -24727,7 +24838,7 @@ ${detail2}
|
|
|
24727
24838
|
stopped = false;
|
|
24728
24839
|
primeProgress = onPrimeProgress;
|
|
24729
24840
|
try {
|
|
24730
|
-
|
|
24841
|
+
tickWithBudget();
|
|
24731
24842
|
} finally {
|
|
24732
24843
|
primeProgress = void 0;
|
|
24733
24844
|
}
|
|
@@ -24752,7 +24863,7 @@ function landsAfterRead(eventAt, lastReadAt) {
|
|
|
24752
24863
|
if (!Number.isFinite(e) || !Number.isFinite(r)) return true;
|
|
24753
24864
|
return e > r;
|
|
24754
24865
|
}
|
|
24755
|
-
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;
|
|
24756
24867
|
var init_tailer = __esm({
|
|
24757
24868
|
"packages/server/src/tailer.ts"() {
|
|
24758
24869
|
"use strict";
|
|
@@ -24785,6 +24896,7 @@ var init_tailer = __esm({
|
|
|
24785
24896
|
SUBAGENT_STALE_MS = 15 * 6e4;
|
|
24786
24897
|
SHELL_PROBE_TTL_MS = 3e4;
|
|
24787
24898
|
SHELL_PROBE_GRACE_MS = 6e4;
|
|
24899
|
+
execFileAsync = promisify2(execFile2);
|
|
24788
24900
|
FOREIGN_FRESH_MS = 24 * 60 * 6e4;
|
|
24789
24901
|
FOREIGN_MAX = 20;
|
|
24790
24902
|
FOREIGN_SCAN_EVERY = 5;
|
|
@@ -30678,11 +30790,11 @@ var init_codex_app_server = __esm({
|
|
|
30678
30790
|
init_logging();
|
|
30679
30791
|
CODEX_APP_SERVER_PROVIDER = "codex-app-server";
|
|
30680
30792
|
CODEX_NATIVE_LISTEN_FLAG = "FRIZZ_CODEX_NATIVE_LISTEN";
|
|
30681
|
-
CODEX_APP_SERVER_SUPPORTED_VERSION = "0.
|
|
30793
|
+
CODEX_APP_SERVER_SUPPORTED_VERSION = "0.153.2";
|
|
30682
30794
|
CODEX_APP_SERVER_PROTOCOL_REVISION = Object.freeze({
|
|
30683
30795
|
packageVersion: CODEX_APP_SERVER_SUPPORTED_VERSION,
|
|
30684
|
-
sourceTag: "rust-v0.
|
|
30685
|
-
sourceCommit: "
|
|
30796
|
+
sourceTag: "rust-v0.153.2",
|
|
30797
|
+
sourceCommit: "657a993cbee87acf52d14b758ce49dbd46d1b8eb"
|
|
30686
30798
|
});
|
|
30687
30799
|
PROTOCOL_FINGERPRINT = [
|
|
30688
30800
|
CODEX_APP_SERVER_PROTOCOL_REVISION.sourceTag,
|
|
@@ -33162,8 +33274,8 @@ import { join as join23 } from "node:path";
|
|
|
33162
33274
|
import { homedir as homedir9, platform } from "node:os";
|
|
33163
33275
|
import { createHash as createHash10 } from "node:crypto";
|
|
33164
33276
|
import { mkdir, readFile, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
33165
|
-
import { execFile as
|
|
33166
|
-
import { promisify as
|
|
33277
|
+
import { execFile as execFile3 } from "node:child_process";
|
|
33278
|
+
import { promisify as promisify3 } from "node:util";
|
|
33167
33279
|
function claudeConfigDir() {
|
|
33168
33280
|
const override = process.env.CLAUDE_CONFIG_DIR;
|
|
33169
33281
|
return override && override.trim() ? override : join23(homedir9(), ".claude");
|
|
@@ -33184,7 +33296,7 @@ function tokenFromCredentialsJson(raw2) {
|
|
|
33184
33296
|
async function readKeychainToken() {
|
|
33185
33297
|
if (platform() !== "darwin") return void 0;
|
|
33186
33298
|
try {
|
|
33187
|
-
const { stdout } = await
|
|
33299
|
+
const { stdout } = await execFileAsync2("security", ["find-generic-password", "-s", "Claude Code-credentials", "-w"], {
|
|
33188
33300
|
encoding: "utf8",
|
|
33189
33301
|
timeout: 4e3
|
|
33190
33302
|
});
|
|
@@ -33312,7 +33424,7 @@ async function acquireLock(path) {
|
|
|
33312
33424
|
}
|
|
33313
33425
|
}
|
|
33314
33426
|
async function runClaudeUsage(claudeBin) {
|
|
33315
|
-
const { stdout } = await
|
|
33427
|
+
const { stdout } = await execFileAsync2(
|
|
33316
33428
|
// Never a bare name: on Windows `execFile("claude")` is ENOENT and `execFile("claude.cmd")` is
|
|
33317
33429
|
// EINVAL (node refuses .cmd/.bat without a shell since CVE-2024-27980), so this reader could
|
|
33318
33430
|
// never reach the CLI there and every quota refresh threw. See auth-status.ts for the measurement.
|
|
@@ -33519,13 +33631,13 @@ async function readClaudeQuota(claudeBin = "claude", deps = {}, options = {}) {
|
|
|
33519
33631
|
});
|
|
33520
33632
|
}
|
|
33521
33633
|
}
|
|
33522
|
-
var
|
|
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;
|
|
33523
33635
|
var init_claude_quota = __esm({
|
|
33524
33636
|
"packages/server/src/backend/claude-quota.ts"() {
|
|
33525
33637
|
"use strict";
|
|
33526
33638
|
init_frizz_paths();
|
|
33527
33639
|
init_claude_broker_host();
|
|
33528
|
-
|
|
33640
|
+
execFileAsync2 = promisify3(execFile3);
|
|
33529
33641
|
USAGE_URL = "https://api.anthropic.com/api/oauth/usage";
|
|
33530
33642
|
OAUTH_BETA = "oauth-2025-04-20";
|
|
33531
33643
|
USER_AGENT = "claude-code/2.0.0";
|
|
@@ -33630,10 +33742,10 @@ var init_quota = __esm({
|
|
|
33630
33742
|
});
|
|
33631
33743
|
|
|
33632
33744
|
// packages/server/src/frizz.ts
|
|
33633
|
-
import { execFile as
|
|
33745
|
+
import { execFile as execFile4 } from "node:child_process";
|
|
33634
33746
|
import { lstatSync as lstatSync2, realpathSync as realpathSync6 } from "node:fs";
|
|
33635
33747
|
import { basename as basename5, dirname as dirname9, join as join24, resolve as resolve5 } from "node:path";
|
|
33636
|
-
import { promisify as
|
|
33748
|
+
import { promisify as promisify4 } from "node:util";
|
|
33637
33749
|
function frizzScriptsDir() {
|
|
33638
33750
|
if (process.env.FRIZZ_SCRIPTS_DIR) return process.env.FRIZZ_SCRIPTS_DIR;
|
|
33639
33751
|
return resolve5(import.meta.dirname, "..", "..", "..", "board");
|
|
@@ -33690,7 +33802,7 @@ var init_frizz = __esm({
|
|
|
33690
33802
|
"packages/server/src/frizz.ts"() {
|
|
33691
33803
|
"use strict";
|
|
33692
33804
|
init_src();
|
|
33693
|
-
execFileP =
|
|
33805
|
+
execFileP = promisify4(execFile4);
|
|
33694
33806
|
}
|
|
33695
33807
|
});
|
|
33696
33808
|
|
|
@@ -34643,9 +34755,10 @@ When delegation is explicitly authorized:
|
|
|
34643
34755
|
- \`gpt-5.6-luna\` + \`medium\` or \`gpt-5.6-terra\` + \`medium\` for fully specified mechanical QA,
|
|
34644
34756
|
documentation, straightforward tests, and exact collection or edits.
|
|
34645
34757
|
- \`gpt-5.6-terra\` + \`high\` only after observed cross-layer or concurrency ambiguity.
|
|
34646
|
-
- \`gpt-
|
|
34647
|
-
|
|
34648
|
-
|
|
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.
|
|
34649
34762
|
|
|
34650
34763
|
## Automated waits in Codex
|
|
34651
34764
|
|
|
@@ -35710,8 +35823,8 @@ var init_claude_agent_broker_bridge = __esm({
|
|
|
35710
35823
|
import { join as join27 } from "node:path";
|
|
35711
35824
|
import { homedir as homedir12, platform as platform2 } from "node:os";
|
|
35712
35825
|
import { readFileSync as readFileSync17, statSync as statSync11 } from "node:fs";
|
|
35713
|
-
import { execFile as
|
|
35714
|
-
import { promisify as
|
|
35826
|
+
import { execFile as execFile5 } from "node:child_process";
|
|
35827
|
+
import { promisify as promisify5 } from "node:util";
|
|
35715
35828
|
function claudeConfigDir2() {
|
|
35716
35829
|
const override = process.env.CLAUDE_CONFIG_DIR;
|
|
35717
35830
|
return override && override.trim() ? override : join27(homedir12(), ".claude");
|
|
@@ -35729,7 +35842,7 @@ async function claudeKeychainState() {
|
|
|
35729
35842
|
if (process.env.FRIZZ_KEYCHAIN_DISABLED && process.env.NODE_ENV !== "production") return "absent";
|
|
35730
35843
|
if (platform2() !== "darwin") return "absent";
|
|
35731
35844
|
try {
|
|
35732
|
-
const { stdout } = await
|
|
35845
|
+
const { stdout } = await execFileAsync3("security", ["find-generic-password", "-s", "Claude Code-credentials", "-w"], {
|
|
35733
35846
|
encoding: "utf8",
|
|
35734
35847
|
timeout: 4e3
|
|
35735
35848
|
});
|
|
@@ -35769,7 +35882,7 @@ function readCodexAuthState(codexHome = defaultCodexHome()) {
|
|
|
35769
35882
|
const accessToken = tokens && typeof tokens.access_token === "string" && tokens.access_token ? tokens.access_token : void 0;
|
|
35770
35883
|
return apiKey || accessToken ? "authed" : "signed-out";
|
|
35771
35884
|
}
|
|
35772
|
-
async function readCodexBinaryState(codexBin = "codex", exec =
|
|
35885
|
+
async function readCodexBinaryState(codexBin = "codex", exec = execFileAsync3) {
|
|
35773
35886
|
try {
|
|
35774
35887
|
await exec(codexBin, ["--version"], { timeout: 5e3 });
|
|
35775
35888
|
return "present";
|
|
@@ -35791,7 +35904,7 @@ function parseClaudeAuthStatusJson(stdout) {
|
|
|
35791
35904
|
async function readClaudeAuthStatusCli(opts) {
|
|
35792
35905
|
try {
|
|
35793
35906
|
const bin = resolveClaudeExecutableAbsolute(opts?.claudeBin);
|
|
35794
|
-
const { stdout } = await
|
|
35907
|
+
const { stdout } = await execFileAsync3(bin, ["auth", "status", "--json"], {
|
|
35795
35908
|
encoding: "utf8",
|
|
35796
35909
|
timeout: opts?.timeoutMs ?? 5e3,
|
|
35797
35910
|
...opts?.cwd ? { cwd: opts.cwd } : {}
|
|
@@ -35889,14 +36002,14 @@ async function readAuthSnapshot(opts) {
|
|
|
35889
36002
|
}
|
|
35890
36003
|
};
|
|
35891
36004
|
}
|
|
35892
|
-
var
|
|
36005
|
+
var execFileAsync3, ProviderAuthRequiredError, claudeAccountMemo;
|
|
35893
36006
|
var init_auth_status = __esm({
|
|
35894
36007
|
"packages/server/src/backend/auth-status.ts"() {
|
|
35895
36008
|
"use strict";
|
|
35896
36009
|
init_claude_quota();
|
|
35897
36010
|
init_codex();
|
|
35898
36011
|
init_claude_broker_host();
|
|
35899
|
-
|
|
36012
|
+
execFileAsync3 = promisify5(execFile5);
|
|
35900
36013
|
ProviderAuthRequiredError = class extends Error {
|
|
35901
36014
|
backend;
|
|
35902
36015
|
constructor(backend) {
|
|
@@ -36647,10 +36760,11 @@ var init_dispatch = __esm({
|
|
|
36647
36760
|
|
|
36648
36761
|
// packages/server/src/board.ts
|
|
36649
36762
|
import {
|
|
36763
|
+
realpathSync as realpathSync8,
|
|
36650
36764
|
watch as fsWatch
|
|
36651
36765
|
} from "node:fs";
|
|
36652
36766
|
import { homedir as homedir13 } from "node:os";
|
|
36653
|
-
import { join as join29 } from "node:path";
|
|
36767
|
+
import { dirname as dirname12, join as join29 } from "node:path";
|
|
36654
36768
|
import watcher from "@parcel/watcher";
|
|
36655
36769
|
function appServerTurnStalled(liveness, lastActivityAt, nowMs) {
|
|
36656
36770
|
if (!liveness) return false;
|
|
@@ -36698,6 +36812,9 @@ function registeredLegacyFileIsTerminal(projectDir, slug) {
|
|
|
36698
36812
|
const status = raw2?.replace(/^(?:"(.*)"|'(.*)')$/, "$1$2").trim();
|
|
36699
36813
|
return status === "done" || status === "dismissed";
|
|
36700
36814
|
}
|
|
36815
|
+
function isBoardRelevantFrizzPath(roots, path) {
|
|
36816
|
+
return path.endsWith(".md") && roots.has(dirname12(path));
|
|
36817
|
+
}
|
|
36701
36818
|
function futureSnooze(row, nowMs) {
|
|
36702
36819
|
const parsed = SnoozeUntil.safeParse(row.snoozed_until);
|
|
36703
36820
|
return parsed.success && Date.parse(parsed.data) > nowMs ? parsed.data : void 0;
|
|
@@ -36946,7 +37063,8 @@ function resolveSessionProfile(row, tele) {
|
|
|
36946
37063
|
const observedAt = tele?.profileAt ? Date.parse(tele.profileAt) : NaN;
|
|
36947
37064
|
const spawnedAt = Date.parse(row.spawned_at);
|
|
36948
37065
|
const setAt = row.profile_set_at ? Date.parse(row.profile_set_at) : NaN;
|
|
36949
|
-
const
|
|
37066
|
+
const operatorSetSticks = (row.backend ?? "claude") !== "codex";
|
|
37067
|
+
const supersededByOperatorSet = Number.isFinite(setAt) && (operatorSetSticks || setAt > observedAt);
|
|
36950
37068
|
const observedIsCurrent = Number.isFinite(observedAt) && Number.isFinite(spawnedAt) && observedAt >= spawnedAt && !supersededByOperatorSet;
|
|
36951
37069
|
const observedModel = tele?.model ? normalizeObservedThreadModel(row.backend ?? "claude", tele.model) ?? tele.model.trim() : void 0;
|
|
36952
37070
|
const model = (!persistedModel || observedIsCurrent ? observedModel : void 0) || persistedModel;
|
|
@@ -37026,20 +37144,29 @@ function registeredDoneFence(done, lastUserAt) {
|
|
|
37026
37144
|
if (Number.isFinite(userAt) && userAt > done.doneAt) return void 0;
|
|
37027
37145
|
return { kind: "done", body: done.body, hints: [], registered: true };
|
|
37028
37146
|
}
|
|
37029
|
-
function
|
|
37030
|
-
|
|
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) => ({
|
|
37031
37158
|
target: `${w.owner}/${w.repo}#${w.number}`,
|
|
37032
37159
|
createdAt: new Date(w.created_at).toISOString()
|
|
37033
37160
|
}));
|
|
37034
37161
|
const registeredPrWatches = new Set(armedPrWatches.map((w) => w.target));
|
|
37035
|
-
const armedTimers =
|
|
37162
|
+
const armedTimers = (registries.timers.get(row.slug) ?? []).map((t) => ({
|
|
37036
37163
|
id: t.id,
|
|
37037
37164
|
prompt: t.prompt,
|
|
37038
37165
|
fireAt: new Date(t.fire_at).toISOString(),
|
|
37039
37166
|
createdAt: new Date(t.created_at).toISOString()
|
|
37040
37167
|
}));
|
|
37041
37168
|
const armedTimerIds = new Set(armedTimers.map((t) => t.id));
|
|
37042
|
-
const questionRows =
|
|
37169
|
+
const questionRows = registries.questions.get(row.slug) ?? [];
|
|
37043
37170
|
const questions = [];
|
|
37044
37171
|
for (const q of questionRows) {
|
|
37045
37172
|
if (q.state !== "open") continue;
|
|
@@ -37047,7 +37174,7 @@ function sessionThreadView(projectDir, storage, row, rawTele, registeredLegacyTe
|
|
|
37047
37174
|
if (spec) questions.push({ id: q.id, spec, askedAt: new Date(q.asked_at).toISOString() });
|
|
37048
37175
|
}
|
|
37049
37176
|
const inFlightAnswers = answersInFlight(questionRows, rawTele?.lastUserAt, row.recurring_on_rest === 1 && Boolean(row.recurring_prompt?.trim()));
|
|
37050
|
-
const armedWatches =
|
|
37177
|
+
const armedWatches = (registries.watches.get(row.slug) ?? []).map((w) => ({
|
|
37051
37178
|
id: w.id,
|
|
37052
37179
|
kind: w.kind,
|
|
37053
37180
|
target: w.target,
|
|
@@ -37055,7 +37182,7 @@ function sessionThreadView(projectDir, storage, row, rawTele, registeredLegacyTe
|
|
|
37055
37182
|
expiresAt: new Date(w.expires_at).toISOString()
|
|
37056
37183
|
}));
|
|
37057
37184
|
const supersededDone = questions.length > 0 || armedWatches.length > 0 || armedPrWatches.length > 0 || armedTimers.length > 0;
|
|
37058
|
-
const done = supersededDone ? void 0 : registeredDoneFence(
|
|
37185
|
+
const done = supersededDone ? void 0 : registeredDoneFence(registries.done.get(row.slug), rawTele?.lastUserAt);
|
|
37059
37186
|
const tele = done && rawTele ? { ...rawTele, lastFence: done } : rawTele;
|
|
37060
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;
|
|
37061
37188
|
const headlessLostWork = isBrokerClaudeRow(row) && headlessStalled && hasUnretiredOwnAgents(tele);
|
|
@@ -37285,6 +37412,7 @@ function createBoard(project, storage, bus, tailer, bootId, deps = {}) {
|
|
|
37285
37412
|
function buildSessionThreads(nowMs) {
|
|
37286
37413
|
const rows = storage.allSessions().filter((row) => ThreadSlug.safeParse(row.slug).success);
|
|
37287
37414
|
const github = readGithubStatusBook(storage.getSetting(GITHUB_STATUS_SETTING));
|
|
37415
|
+
const registries = readThreadRegistries(storage);
|
|
37288
37416
|
const currentInteractionKeys = /* @__PURE__ */ new Set();
|
|
37289
37417
|
const out = [];
|
|
37290
37418
|
for (const row of rows) {
|
|
@@ -37321,6 +37449,7 @@ function createBoard(project, storage, bus, tailer, bootId, deps = {}) {
|
|
|
37321
37449
|
nowMs,
|
|
37322
37450
|
codexTurnLiveness,
|
|
37323
37451
|
claudeBrokerDaemonAlive,
|
|
37452
|
+
registries,
|
|
37324
37453
|
github
|
|
37325
37454
|
));
|
|
37326
37455
|
}
|
|
@@ -37450,7 +37579,23 @@ function createBoard(project, storage, bus, tailer, bootId, deps = {}) {
|
|
|
37450
37579
|
if (parcelSub || stopped) return Promise.resolve();
|
|
37451
37580
|
if (watchSetup) return watchSetup;
|
|
37452
37581
|
const setup = (async () => {
|
|
37453
|
-
const
|
|
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
|
+
);
|
|
37454
37599
|
if (stopped) {
|
|
37455
37600
|
await next.unsubscribe();
|
|
37456
37601
|
return;
|
|
@@ -37525,7 +37670,7 @@ function createBoard(project, storage, bus, tailer, bootId, deps = {}) {
|
|
|
37525
37670
|
}
|
|
37526
37671
|
};
|
|
37527
37672
|
}
|
|
37528
|
-
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;
|
|
37529
37674
|
var init_board = __esm({
|
|
37530
37675
|
"packages/server/src/board.ts"() {
|
|
37531
37676
|
"use strict";
|
|
@@ -37545,6 +37690,7 @@ var init_board = __esm({
|
|
|
37545
37690
|
RECONCILE_MS = 15e3;
|
|
37546
37691
|
STALL_GRACE_MS = 3e4;
|
|
37547
37692
|
LINE_CAP = 240;
|
|
37693
|
+
FRIZZ_WATCH_IGNORED_DIRS = ["threads", ".session-state"];
|
|
37548
37694
|
DECLARED_PARK_MAX_MS = 24 * 60 * 60 * 1e3;
|
|
37549
37695
|
}
|
|
37550
37696
|
});
|
|
@@ -37765,8 +37911,8 @@ var init_wake_store = __esm({
|
|
|
37765
37911
|
});
|
|
37766
37912
|
|
|
37767
37913
|
// packages/server/src/github-review.ts
|
|
37768
|
-
import { execFile as
|
|
37769
|
-
import { promisify as
|
|
37914
|
+
import { execFile as execFile6 } from "node:child_process";
|
|
37915
|
+
import { promisify as promisify6 } from "node:util";
|
|
37770
37916
|
function refKey(ref) {
|
|
37771
37917
|
return `${ref.owner}/${ref.repo}#${ref.number}`;
|
|
37772
37918
|
}
|
|
@@ -37776,7 +37922,7 @@ function conciseError(error) {
|
|
|
37776
37922
|
}
|
|
37777
37923
|
async function defaultGetToken() {
|
|
37778
37924
|
try {
|
|
37779
|
-
const { stdout } = await
|
|
37925
|
+
const { stdout } = await execFileAsync4(
|
|
37780
37926
|
"gh",
|
|
37781
37927
|
["auth", "token", "--hostname", "github.com"],
|
|
37782
37928
|
{
|
|
@@ -38082,11 +38228,11 @@ function createGithubReviewFetcher(deps = {}) {
|
|
|
38082
38228
|
}
|
|
38083
38229
|
});
|
|
38084
38230
|
}
|
|
38085
|
-
var
|
|
38231
|
+
var execFileAsync4, GH_TIMEOUT_MS, GH_MAX_BUFFER, REQUEST_TIMEOUT_MS, MAX_REFS_PER_REQUEST, RATE_LIMIT_RESERVE;
|
|
38086
38232
|
var init_github_review = __esm({
|
|
38087
38233
|
"packages/server/src/github-review.ts"() {
|
|
38088
38234
|
"use strict";
|
|
38089
|
-
|
|
38235
|
+
execFileAsync4 = promisify6(execFile6);
|
|
38090
38236
|
GH_TIMEOUT_MS = 3e4;
|
|
38091
38237
|
GH_MAX_BUFFER = 1024 * 1024;
|
|
38092
38238
|
REQUEST_TIMEOUT_MS = 3e4;
|
|
@@ -38213,8 +38359,8 @@ var init_pr_watch_noise = __esm({
|
|
|
38213
38359
|
});
|
|
38214
38360
|
|
|
38215
38361
|
// packages/server/src/scheduler.ts
|
|
38216
|
-
import { execFile as
|
|
38217
|
-
import { promisify as
|
|
38362
|
+
import { execFile as execFile7 } from "node:child_process";
|
|
38363
|
+
import { promisify as promisify7 } from "node:util";
|
|
38218
38364
|
import { createHash as createHash12, randomUUID as randomUUID14 } from "node:crypto";
|
|
38219
38365
|
function failureSignature(rollup) {
|
|
38220
38366
|
const ids = [];
|
|
@@ -38458,7 +38604,7 @@ function conciseGhError(err) {
|
|
|
38458
38604
|
}
|
|
38459
38605
|
async function probePrReadable(ref) {
|
|
38460
38606
|
try {
|
|
38461
|
-
await
|
|
38607
|
+
await execFileAsync5(
|
|
38462
38608
|
"gh",
|
|
38463
38609
|
["pr", "view", String(ref.number), "--repo", `${ref.owner}/${ref.repo}`, "--json", "state"],
|
|
38464
38610
|
{ timeout: 15e3, maxBuffer: 1e6, env: { ...process.env, GH_PAGER: "cat", GH_PROMPT_DISABLED: "1" } }
|
|
@@ -38470,7 +38616,7 @@ async function probePrReadable(ref) {
|
|
|
38470
38616
|
}
|
|
38471
38617
|
async function defaultFetchPr(ref) {
|
|
38472
38618
|
try {
|
|
38473
|
-
const { stdout } = await
|
|
38619
|
+
const { stdout } = await execFileAsync5(
|
|
38474
38620
|
"gh",
|
|
38475
38621
|
ghPrViewArgs(ref),
|
|
38476
38622
|
{ timeout: 15e3, maxBuffer: 8e6, env: { ...process.env, GH_PAGER: "cat", GH_PROMPT_DISABLED: "1" } }
|
|
@@ -38478,7 +38624,7 @@ async function defaultFetchPr(ref) {
|
|
|
38478
38624
|
const j = JSON.parse(stdout);
|
|
38479
38625
|
if (typeof j.state !== "string" || !j.state) return void 0;
|
|
38480
38626
|
if (typeof j.headRefOid !== "string" || !j.headRefOid) return void 0;
|
|
38481
|
-
const runs = await
|
|
38627
|
+
const runs = await execFileAsync5(
|
|
38482
38628
|
"gh",
|
|
38483
38629
|
["run", "list", "--repo", `${ref.owner}/${ref.repo}`, "--commit", j.headRefOid, "--limit", "100", "--json", "name,workflowName,status,conclusion,databaseId,event,createdAt"],
|
|
38484
38630
|
{ timeout: 15e3, maxBuffer: 8e6, env: { ...process.env, GH_PAGER: "cat", GH_PROMPT_DISABLED: "1" } }
|
|
@@ -39794,7 +39940,7 @@ ${wakeTimeHeader(now(), spokeAt)}`;
|
|
|
39794
39940
|
}
|
|
39795
39941
|
};
|
|
39796
39942
|
}
|
|
39797
|
-
var
|
|
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;
|
|
39798
39944
|
var init_scheduler = __esm({
|
|
39799
39945
|
"packages/server/src/scheduler.ts"() {
|
|
39800
39946
|
"use strict";
|
|
@@ -39810,7 +39956,7 @@ var init_scheduler = __esm({
|
|
|
39810
39956
|
init_pr_watch_noise();
|
|
39811
39957
|
init_github_review();
|
|
39812
39958
|
init_logging();
|
|
39813
|
-
|
|
39959
|
+
execFileAsync5 = promisify7(execFile7);
|
|
39814
39960
|
LIMIT_FENCE_PREFIX = "limit";
|
|
39815
39961
|
LIMIT_HINT_PREFIX = "limit:";
|
|
39816
39962
|
LIMIT_RESUME_GRACE_MS = 6e4;
|
|
@@ -40226,7 +40372,7 @@ var init_codex_app_server_diagnostics = __esm({
|
|
|
40226
40372
|
});
|
|
40227
40373
|
|
|
40228
40374
|
// packages/server/src/backend/stale-socket-sweep.ts
|
|
40229
|
-
import { execFile as
|
|
40375
|
+
import { execFile as execFile8 } from "node:child_process";
|
|
40230
40376
|
import { readdirSync as readdirSync8, unlinkSync as unlinkSync4 } from "node:fs";
|
|
40231
40377
|
import { connect as connectSocket } from "node:net";
|
|
40232
40378
|
import { join as join32 } from "node:path";
|
|
@@ -40273,7 +40419,7 @@ var init_stale_socket_sweep = __esm({
|
|
|
40273
40419
|
"packages/server/src/backend/stale-socket-sweep.ts"() {
|
|
40274
40420
|
"use strict";
|
|
40275
40421
|
defaultListReferenced = (prefix, done) => {
|
|
40276
|
-
|
|
40422
|
+
execFile8("lsof", ["-U", "-F", "n"], { timeout: 3e4, maxBuffer: 16 * 1024 * 1024 }, (error, stdout) => {
|
|
40277
40423
|
if (!stdout) return done(null);
|
|
40278
40424
|
if (error && !stdout.includes(prefix)) return done(null);
|
|
40279
40425
|
done(parseLsofSocketNames(stdout));
|
|
@@ -40295,9 +40441,9 @@ var init_stale_socket_sweep = __esm({
|
|
|
40295
40441
|
});
|
|
40296
40442
|
|
|
40297
40443
|
// packages/server/src/orphan-reaper.ts
|
|
40298
|
-
import { execFileSync as
|
|
40444
|
+
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
40299
40445
|
import { readFileSync as readFileSync19 } from "node:fs";
|
|
40300
|
-
import { dirname as
|
|
40446
|
+
import { dirname as dirname13 } from "node:path";
|
|
40301
40447
|
function firstTokenBasename(command) {
|
|
40302
40448
|
const first = command.trimStart().split(/\s+/, 1)[0] ?? "";
|
|
40303
40449
|
const slash = first.lastIndexOf("/");
|
|
@@ -40524,7 +40670,7 @@ function sweepOrphansOnce(deps = {}) {
|
|
|
40524
40670
|
}
|
|
40525
40671
|
function sweepStaleBrokerSockets() {
|
|
40526
40672
|
try {
|
|
40527
|
-
sweepStaleSockets({ dir:
|
|
40673
|
+
sweepStaleSockets({ dir: dirname13(claudeBrokerSocketPath("", "")), prefix: CLAUDE_BROKER_SOCKET_PREFIX });
|
|
40528
40674
|
} catch {
|
|
40529
40675
|
}
|
|
40530
40676
|
}
|
|
@@ -40560,7 +40706,7 @@ var init_orphan_reaper = __esm({
|
|
|
40560
40706
|
ORPHAN_REAP_INTERVAL_MS = 6e4;
|
|
40561
40707
|
ORPHAN_MIN_AGE_MS = 12e4;
|
|
40562
40708
|
SLUG_RE = /FRIZZ_THREAD=([A-Za-z0-9._-]+)/;
|
|
40563
|
-
defaultExec = (file, args) =>
|
|
40709
|
+
defaultExec = (file, args) => execFileSync4(file, args, { encoding: "utf8", maxBuffer: 16 * 1024 * 1024, timeout: 1e4 });
|
|
40564
40710
|
defaultReadEnv = (pid) => {
|
|
40565
40711
|
try {
|
|
40566
40712
|
return readFileSync19(`/proc/${pid}/environ`, "utf8");
|
|
@@ -43914,7 +44060,7 @@ var init_server = __esm({
|
|
|
43914
44060
|
|
|
43915
44061
|
// packages/server/src/repair.ts
|
|
43916
44062
|
import { existsSync as existsSync11, readFileSync as readFileSync20, writeFileSync as writeFileSync11 } from "node:fs";
|
|
43917
|
-
import { basename as basename7, dirname as
|
|
44063
|
+
import { basename as basename7, dirname as dirname14, resolve as resolve7 } from "node:path";
|
|
43918
44064
|
function quoteValue(v) {
|
|
43919
44065
|
if (/^[\w./#:+-]+$/.test(v)) return v;
|
|
43920
44066
|
return `"${v.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
@@ -43926,7 +44072,7 @@ function deriveTitle(body, slug) {
|
|
|
43926
44072
|
function repairThreadFile(frizzDir, file) {
|
|
43927
44073
|
const root = resolve7(frizzDir);
|
|
43928
44074
|
const abs = resolve7(root, file);
|
|
43929
|
-
if (
|
|
44075
|
+
if (dirname14(abs) !== root) throw new RepairError(`refusing to repair "${file}": not directly under .frizz/`);
|
|
43930
44076
|
if (!abs.endsWith(".md")) throw new RepairError(`refusing to repair "${file}": not a .md thread file`);
|
|
43931
44077
|
if (!existsSync11(abs)) throw new RepairError(`no thread file to repair: ${basename7(abs)}`);
|
|
43932
44078
|
const content = readFileSync20(abs, "utf8");
|
|
@@ -46661,13 +46807,13 @@ var init_open_external = __esm({
|
|
|
46661
46807
|
|
|
46662
46808
|
// packages/server/src/local-file.ts
|
|
46663
46809
|
import { spawn as spawn6 } from "node:child_process";
|
|
46664
|
-
import { readFileSync as readFileSync23, realpathSync as
|
|
46810
|
+
import { readFileSync as readFileSync23, realpathSync as realpathSync9, statSync as statSync15 } from "node:fs";
|
|
46665
46811
|
import { homedir as homedir16 } from "node:os";
|
|
46666
46812
|
import { isAbsolute as isAbsolute4, join as join35, resolve as resolve8, sep as sep2 } from "node:path";
|
|
46667
46813
|
function isUnder(real, root) {
|
|
46668
46814
|
let rootReal;
|
|
46669
46815
|
try {
|
|
46670
|
-
rootReal =
|
|
46816
|
+
rootReal = realpathSync9(root);
|
|
46671
46817
|
} catch {
|
|
46672
46818
|
return false;
|
|
46673
46819
|
}
|
|
@@ -46677,7 +46823,7 @@ function resolveLocalFile(rawPath, roots) {
|
|
|
46677
46823
|
if (!isAbsolute4(rawPath)) throw new Error("Local path must be absolute");
|
|
46678
46824
|
let real;
|
|
46679
46825
|
try {
|
|
46680
|
-
real =
|
|
46826
|
+
real = realpathSync9(rawPath);
|
|
46681
46827
|
} catch {
|
|
46682
46828
|
throw new Error("Local file was not found");
|
|
46683
46829
|
}
|
|
@@ -46719,12 +46865,12 @@ function readLocalMarkdown(rawPath, roots) {
|
|
|
46719
46865
|
const lastBreak = head.lastIndexOf(10);
|
|
46720
46866
|
return { path, markdown: head.subarray(0, lastBreak > 0 ? lastBreak : head.length).toString("utf8"), truncated: true };
|
|
46721
46867
|
}
|
|
46722
|
-
function resolveWatchableLocalFile(rawPath,
|
|
46723
|
-
|
|
46724
|
-
|
|
46725
|
-
|
|
46868
|
+
function resolveWatchableLocalFile(rawPath, roots) {
|
|
46869
|
+
const path = resolveLocalFile(rawPath, roots);
|
|
46870
|
+
if (MARKDOWN_FILE_EXT.test(rawPath.trim()) && !MARKDOWN_FILE_EXT.test(path)) {
|
|
46871
|
+
throw new Error("Local file is not a Markdown file");
|
|
46726
46872
|
}
|
|
46727
|
-
return
|
|
46873
|
+
return path;
|
|
46728
46874
|
}
|
|
46729
46875
|
function defaultSpawn(command, args, options) {
|
|
46730
46876
|
return spawn6(command, [...args], options);
|
|
@@ -47027,8 +47173,8 @@ var init_github_hovercard = __esm({
|
|
|
47027
47173
|
});
|
|
47028
47174
|
|
|
47029
47175
|
// packages/server/src/backend/account-actions.ts
|
|
47030
|
-
import { execFile as
|
|
47031
|
-
import { promisify as
|
|
47176
|
+
import { execFile as execFile9 } from "node:child_process";
|
|
47177
|
+
import { promisify as promisify8 } from "node:util";
|
|
47032
47178
|
function liveThreadsForBackend(threads, backend) {
|
|
47033
47179
|
let count = 0;
|
|
47034
47180
|
for (const thread of threads) {
|
|
@@ -47047,7 +47193,7 @@ async function runProviderLogout(opts) {
|
|
|
47047
47193
|
const args = opts.backend === "codex" ? ["logout"] : ["auth", "logout"];
|
|
47048
47194
|
let failure;
|
|
47049
47195
|
try {
|
|
47050
|
-
await
|
|
47196
|
+
await execFileAsync6(bin, args, { encoding: "utf8", timeout: opts.timeoutMs ?? 15e3 });
|
|
47051
47197
|
} catch (err) {
|
|
47052
47198
|
const e = err;
|
|
47053
47199
|
const stderr = typeof e.stderr === "string" ? e.stderr.trim() : "";
|
|
@@ -47057,12 +47203,12 @@ async function runProviderLogout(opts) {
|
|
|
47057
47203
|
if (failure && auth !== "signed-out") return { status: "failed", detail: failure, auth };
|
|
47058
47204
|
return { status: "done", auth };
|
|
47059
47205
|
}
|
|
47060
|
-
var
|
|
47206
|
+
var execFileAsync6, LIVE_RUNTIMES;
|
|
47061
47207
|
var init_account_actions = __esm({
|
|
47062
47208
|
"packages/server/src/backend/account-actions.ts"() {
|
|
47063
47209
|
"use strict";
|
|
47064
47210
|
init_auth_status();
|
|
47065
|
-
|
|
47211
|
+
execFileAsync6 = promisify8(execFile9);
|
|
47066
47212
|
LIVE_RUNTIMES = /* @__PURE__ */ new Set(["spawning", "running", "perm-prompt"]);
|
|
47067
47213
|
}
|
|
47068
47214
|
});
|
|
@@ -47330,8 +47476,8 @@ var init_image_header = __esm({
|
|
|
47330
47476
|
});
|
|
47331
47477
|
|
|
47332
47478
|
// packages/server/src/directory-picker.ts
|
|
47333
|
-
import { execFile as
|
|
47334
|
-
import { promisify as
|
|
47479
|
+
import { execFile as execFile10 } from "node:child_process";
|
|
47480
|
+
import { promisify as promisify9 } from "node:util";
|
|
47335
47481
|
async function pickImageFile(startIn, prompt = "Choose an image for this project", platform3 = process.platform) {
|
|
47336
47482
|
if (platform3 === "darwin") {
|
|
47337
47483
|
const location = startIn ? ` default location POSIX file ${JSON.stringify(startIn)}` : "";
|
|
@@ -47412,7 +47558,7 @@ var run2, PICKER_TIMEOUT_MS, OSASCRIPT;
|
|
|
47412
47558
|
var init_directory_picker = __esm({
|
|
47413
47559
|
"packages/server/src/directory-picker.ts"() {
|
|
47414
47560
|
"use strict";
|
|
47415
|
-
run2 =
|
|
47561
|
+
run2 = promisify9(execFile10);
|
|
47416
47562
|
PICKER_TIMEOUT_MS = 5 * 6e4;
|
|
47417
47563
|
OSASCRIPT = (prompt) => `POSIX path of (choose folder with prompt ${JSON.stringify(prompt)})`;
|
|
47418
47564
|
}
|
|
@@ -47422,7 +47568,7 @@ var init_directory_picker = __esm({
|
|
|
47422
47568
|
import { readFileSync as readFileSync24, statSync as statSync17 } from "node:fs";
|
|
47423
47569
|
import { join as join36, resolve as resolve9 } from "node:path";
|
|
47424
47570
|
import { randomUUID as randomUUID16 } from "node:crypto";
|
|
47425
|
-
import { basename as basename9, dirname as
|
|
47571
|
+
import { basename as basename9, dirname as dirname15 } from "node:path";
|
|
47426
47572
|
import { existsSync as existsSync13, mkdirSync as mkdirSync16, rmSync as rmSync10, writeFileSync as writeFileSync13 } from "node:fs";
|
|
47427
47573
|
import { homedir as homedir17 } from "node:os";
|
|
47428
47574
|
function validateGithubDispatchProfile(input) {
|
|
@@ -47616,7 +47762,7 @@ function storeProjectIcon(id, name, bytes) {
|
|
|
47616
47762
|
if (!entry) throw new Error("No such project.");
|
|
47617
47763
|
if (bytes.length === 0) throw new Error("That file is empty.");
|
|
47618
47764
|
const path = customIconPath(id, `.${extension2}`);
|
|
47619
|
-
mkdirSync16(
|
|
47765
|
+
mkdirSync16(dirname15(path), { recursive: true });
|
|
47620
47766
|
writeFileSync13(path, bytes);
|
|
47621
47767
|
if (!imageDimensions(path)) {
|
|
47622
47768
|
rmSync10(path, { force: true });
|
|
@@ -49208,12 +49354,13 @@ Say which way you went and why in your write-up, so the human can course-correct
|
|
|
49208
49354
|
output: external_exports.object({ path: external_exports.string(), markdown: external_exports.string(), truncated: external_exports.boolean() }),
|
|
49209
49355
|
handler: async ({ input }) => readLocalMarkdown(input.path, openRoots)
|
|
49210
49356
|
}),
|
|
49211
|
-
// A
|
|
49212
|
-
//
|
|
49357
|
+
// A file's SOURCE, for the fullscreen page's file viewer. The SAME openable roots as the Markdown
|
|
49358
|
+
// reader — see readLocalTextFile for why the project-directory-only gate this replaced refused 41%
|
|
49359
|
+
// of the rail's own rows (a worker's checkout is very often a worktree outside the project dir).
|
|
49213
49360
|
localFile: query({
|
|
49214
49361
|
input: external_exports.object({ path: external_exports.string().max(4096) }).strict(),
|
|
49215
49362
|
output: external_exports.object({ path: external_exports.string(), text: external_exports.string(), truncated: external_exports.boolean() }),
|
|
49216
|
-
handler: async ({ input }) => readLocalTextFile(input.path,
|
|
49363
|
+
handler: async ({ input }) => readLocalTextFile(input.path, openRoots)
|
|
49217
49364
|
}),
|
|
49218
49365
|
// Batch-classify path REFERENCES (as they appear in inline code) → their canonical openable path, or
|
|
49219
49366
|
// null when a candidate doesn't resolve to a real file under the openable roots. The client renders
|
|
@@ -49994,7 +50141,7 @@ var init_compression = __esm({
|
|
|
49994
50141
|
});
|
|
49995
50142
|
|
|
49996
50143
|
// packages/server/src/local-image.ts
|
|
49997
|
-
import { readFileSync as readFileSync25, realpathSync as
|
|
50144
|
+
import { readFileSync as readFileSync25, realpathSync as realpathSync10, statSync as statSync18 } from "node:fs";
|
|
49998
50145
|
import { extname as extname2, isAbsolute as isAbsolute5 } from "node:path";
|
|
49999
50146
|
function resolveLocalImage(rawPath) {
|
|
50000
50147
|
if (!rawPath || !isAbsolute5(rawPath)) return { status: 400 };
|
|
@@ -50002,7 +50149,7 @@ function resolveLocalImage(rawPath) {
|
|
|
50002
50149
|
if (!contentType) return { status: 400 };
|
|
50003
50150
|
let real;
|
|
50004
50151
|
try {
|
|
50005
|
-
real =
|
|
50152
|
+
real = realpathSync10(rawPath);
|
|
50006
50153
|
} catch {
|
|
50007
50154
|
return { status: 404 };
|
|
50008
50155
|
}
|
|
@@ -50028,9 +50175,9 @@ var init_local_image = __esm({
|
|
|
50028
50175
|
});
|
|
50029
50176
|
|
|
50030
50177
|
// packages/server/src/project-icon.ts
|
|
50031
|
-
import { readFileSync as readFileSync26, readdirSync as readdirSync10, realpathSync as
|
|
50178
|
+
import { readFileSync as readFileSync26, readdirSync as readdirSync10, realpathSync as realpathSync11, statSync as statSync19 } from "node:fs";
|
|
50032
50179
|
import { homedir as homedir18 } from "node:os";
|
|
50033
|
-
import { basename as basename10, dirname as
|
|
50180
|
+
import { basename as basename10, dirname as dirname16, extname as extname3, join as join37, relative as relative2, sep as sep3 } from "node:path";
|
|
50034
50181
|
function normalizeStem(stem) {
|
|
50035
50182
|
const sized = stem.toLowerCase().replace(/[@-]\d+(\.\d+)?x(\d+)?$/u, "").replace(/[-_]\d{2,4}$/u, "");
|
|
50036
50183
|
const normalized = sized.replace(VARIANT_SUFFIX, "");
|
|
@@ -50095,7 +50242,7 @@ function manifestIcons(manifestPath) {
|
|
|
50095
50242
|
return [];
|
|
50096
50243
|
}
|
|
50097
50244
|
if (!Array.isArray(parsed?.icons)) return [];
|
|
50098
|
-
const directory =
|
|
50245
|
+
const directory = dirname16(manifestPath);
|
|
50099
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, "")));
|
|
50100
50247
|
}
|
|
50101
50248
|
function projectIconCandidates(root) {
|
|
@@ -50118,7 +50265,7 @@ function projectIconCandidates(root) {
|
|
|
50118
50265
|
for (const icon of manifestIcons(join37(directory, name))) {
|
|
50119
50266
|
if (MEASURABLE_IMAGE_EXTENSIONS.has(extname3(icon).toLowerCase())) {
|
|
50120
50267
|
fromManifest.add(icon);
|
|
50121
|
-
files.push({ path: icon, directory:
|
|
50268
|
+
files.push({ path: icon, directory: dirname16(icon) });
|
|
50122
50269
|
}
|
|
50123
50270
|
}
|
|
50124
50271
|
continue;
|
|
@@ -50177,14 +50324,14 @@ function resolveProjectIconResponse(id, options = {}) {
|
|
|
50177
50324
|
if (!contentType) return { status: 404 };
|
|
50178
50325
|
let real;
|
|
50179
50326
|
try {
|
|
50180
|
-
real =
|
|
50327
|
+
real = realpathSync11(path);
|
|
50181
50328
|
if (!statSync19(real).isFile()) return { status: 404 };
|
|
50182
50329
|
} catch {
|
|
50183
50330
|
return { status: 404 };
|
|
50184
50331
|
}
|
|
50185
50332
|
const roots = [entry.path, projectStateDir(id, home)].map((root) => {
|
|
50186
50333
|
try {
|
|
50187
|
-
return
|
|
50334
|
+
return realpathSync11(root);
|
|
50188
50335
|
} catch {
|
|
50189
50336
|
return root;
|
|
50190
50337
|
}
|
|
@@ -50303,7 +50450,7 @@ var init_project_icon = __esm({
|
|
|
50303
50450
|
});
|
|
50304
50451
|
|
|
50305
50452
|
// packages/server/src/local-visualization.ts
|
|
50306
|
-
import { readdirSync as readdirSync11, readFileSync as readFileSync27, realpathSync as
|
|
50453
|
+
import { readdirSync as readdirSync11, readFileSync as readFileSync27, realpathSync as realpathSync12, statSync as statSync20 } from "node:fs";
|
|
50307
50454
|
import { join as join38, sep as sep4 } from "node:path";
|
|
50308
50455
|
function children(path, pattern) {
|
|
50309
50456
|
try {
|
|
@@ -50320,8 +50467,8 @@ function resolveFragment(projectDir, sessionId, file) {
|
|
|
50320
50467
|
let projectReal;
|
|
50321
50468
|
let baseReal;
|
|
50322
50469
|
try {
|
|
50323
|
-
projectReal =
|
|
50324
|
-
baseReal =
|
|
50470
|
+
projectReal = realpathSync12(projectDir);
|
|
50471
|
+
baseReal = realpathSync12(base);
|
|
50325
50472
|
} catch {
|
|
50326
50473
|
return null;
|
|
50327
50474
|
}
|
|
@@ -50334,7 +50481,7 @@ function resolveFragment(projectDir, sessionId, file) {
|
|
|
50334
50481
|
const sessionRoot = join38(baseReal, year, month, day, sessionId);
|
|
50335
50482
|
const candidate = join38(monthDir, day, sessionId, file);
|
|
50336
50483
|
try {
|
|
50337
|
-
const real =
|
|
50484
|
+
const real = realpathSync12(candidate);
|
|
50338
50485
|
if (isUnder2(real, sessionRoot) && statSync20(real).isFile()) return real;
|
|
50339
50486
|
} catch {
|
|
50340
50487
|
}
|
|
@@ -51041,7 +51188,11 @@ function makeTranscriptReader(project, storage, backendFor, lifecycleFor, peerNa
|
|
|
51041
51188
|
};
|
|
51042
51189
|
}
|
|
51043
51190
|
function createAppSocketServer(deps) {
|
|
51044
|
-
const wss = new import_websocket_server.default({
|
|
51191
|
+
const wss = new import_websocket_server.default({
|
|
51192
|
+
noServer: true,
|
|
51193
|
+
maxPayload: APP_SOCKET_MAX_MESSAGE_BYTES,
|
|
51194
|
+
perMessageDeflate: APP_SOCKET_DEFLATE
|
|
51195
|
+
});
|
|
51045
51196
|
const registry = new SubscriptionRegistry();
|
|
51046
51197
|
const boundedCount = (value, fallback) => {
|
|
51047
51198
|
const candidate = value ?? fallback;
|
|
@@ -51771,7 +51922,7 @@ function createAppSocketServer(deps) {
|
|
|
51771
51922
|
}
|
|
51772
51923
|
};
|
|
51773
51924
|
}
|
|
51774
|
-
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;
|
|
51775
51926
|
var init_app_socket = __esm({
|
|
51776
51927
|
"packages/server/src/app-socket.ts"() {
|
|
51777
51928
|
"use strict";
|
|
@@ -51863,12 +52014,21 @@ var init_app_socket = __esm({
|
|
|
51863
52014
|
APP_SOCKET_TRANSCRIPT_READ_WINDOW_MS = 1e3;
|
|
51864
52015
|
APP_SOCKET_MAX_TRANSCRIPT_CACHE_ENTRIES = 128;
|
|
51865
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
|
+
};
|
|
51866
52026
|
}
|
|
51867
52027
|
});
|
|
51868
52028
|
|
|
51869
52029
|
// packages/server/src/local-file-watch.ts
|
|
51870
52030
|
import { watch } from "node:fs";
|
|
51871
|
-
import { basename as basename11, dirname as
|
|
52031
|
+
import { basename as basename11, dirname as dirname17 } from "node:path";
|
|
51872
52032
|
function close(path) {
|
|
51873
52033
|
const entry = entries.get(path);
|
|
51874
52034
|
if (!entry) return;
|
|
@@ -51883,7 +52043,7 @@ function watchLocalFile(path, onChange) {
|
|
|
51883
52043
|
let entry = entries.get(path);
|
|
51884
52044
|
if (!entry) {
|
|
51885
52045
|
const name = basename11(path);
|
|
51886
|
-
const watcher2 = watch(
|
|
52046
|
+
const watcher2 = watch(dirname17(path), { persistent: false }, (_event, changed) => {
|
|
51887
52047
|
if (changed !== null && changed !== void 0 && changed.toString() !== name) return;
|
|
51888
52048
|
const current = entries.get(path);
|
|
51889
52049
|
if (!current) return;
|
|
@@ -51917,7 +52077,7 @@ var init_local_file_watch = __esm({
|
|
|
51917
52077
|
|
|
51918
52078
|
// packages/server/src/boot-progress.ts
|
|
51919
52079
|
import { mkdirSync as mkdirSync18, readFileSync as readFileSync28, renameSync as renameSync10, rmSync as rmSync11, writeFileSync as writeFileSync15 } from "node:fs";
|
|
51920
|
-
import { basename as basename12, dirname as
|
|
52080
|
+
import { basename as basename12, dirname as dirname18, join as join40 } from "node:path";
|
|
51921
52081
|
function bootProgressPath(stateDir) {
|
|
51922
52082
|
return join40(stateDir, BOOT_PROGRESS_NAME);
|
|
51923
52083
|
}
|
|
@@ -51939,8 +52099,8 @@ function createBootProgressPublisher(stateDir, minIntervalMs = 200) {
|
|
|
51939
52099
|
lastAt = now;
|
|
51940
52100
|
step++;
|
|
51941
52101
|
try {
|
|
51942
|
-
mkdirSync18(
|
|
51943
|
-
const temp = join40(
|
|
52102
|
+
mkdirSync18(dirname18(path), { recursive: true, mode: 448 });
|
|
52103
|
+
const temp = join40(dirname18(path), `.${basename12(path)}.${process.pid}.tmp`);
|
|
51944
52104
|
writeFileSync15(temp, `${JSON.stringify({ pid: process.pid, step, phase, at: new Date(now).toISOString() })}
|
|
51945
52105
|
`, "utf8");
|
|
51946
52106
|
renameSync10(temp, path);
|
|
@@ -52493,12 +52653,12 @@ var init_legacy_project_db = __esm({
|
|
|
52493
52653
|
|
|
52494
52654
|
// packages/server/src/frizz-db.ts
|
|
52495
52655
|
import { existsSync as existsSync14, mkdirSync as mkdirSync19, readdirSync as readdirSync12, renameSync as renameSync11, statSync as statSync21 } from "node:fs";
|
|
52496
|
-
import { basename as basename13, dirname as
|
|
52656
|
+
import { basename as basename13, dirname as dirname19, join as join41 } from "node:path";
|
|
52497
52657
|
function frizzDatabaseLocation(options) {
|
|
52498
52658
|
if (options.stateDir !== void 0) {
|
|
52499
|
-
const projectsDir =
|
|
52659
|
+
const projectsDir = dirname19(options.stateDir);
|
|
52500
52660
|
if (basename13(projectsDir) === "projects") {
|
|
52501
|
-
return { path: options.path ?? join41(
|
|
52661
|
+
return { path: options.path ?? join41(dirname19(projectsDir), "ui.db"), projectsDir };
|
|
52502
52662
|
}
|
|
52503
52663
|
return { path: options.path ?? join41(options.stateDir, "ui.db"), projectsDir: void 0 };
|
|
52504
52664
|
}
|
|
@@ -52522,7 +52682,7 @@ function ensureFrizzSchema(db) {
|
|
|
52522
52682
|
}
|
|
52523
52683
|
function openFrizzDatabase(options = {}) {
|
|
52524
52684
|
const { path, projectsDir } = frizzDatabaseLocation(options);
|
|
52525
|
-
mkdirSync19(
|
|
52685
|
+
mkdirSync19(dirname19(path), { recursive: true });
|
|
52526
52686
|
const db = new sqlite_default(path);
|
|
52527
52687
|
db.pragma("busy_timeout = 5000");
|
|
52528
52688
|
db.pragma("journal_mode = WAL");
|
|
@@ -52681,6 +52841,7 @@ function startTenantPrime(deps) {
|
|
|
52681
52841
|
result.skipped.push(entry.id);
|
|
52682
52842
|
continue;
|
|
52683
52843
|
}
|
|
52844
|
+
const resolveStartedAt = deps.monotonicNow?.() ?? performance.now();
|
|
52684
52845
|
let project;
|
|
52685
52846
|
try {
|
|
52686
52847
|
project = deps.toProject(entry);
|
|
@@ -52695,12 +52856,13 @@ function startTenantPrime(deps) {
|
|
|
52695
52856
|
log3(`${project.name} is served by another Frizz (pid ${other}) \u2014 leaving it closed here`);
|
|
52696
52857
|
continue;
|
|
52697
52858
|
}
|
|
52859
|
+
const resolveMs = (deps.monotonicNow?.() ?? performance.now()) - resolveStartedAt;
|
|
52698
52860
|
if (lastTookMs !== void 0) await delay2(deps.gapMs ?? gapAfter(lastTookMs));
|
|
52699
52861
|
if (stopped) break;
|
|
52700
52862
|
try {
|
|
52701
52863
|
const startedAt = deps.monotonicNow?.() ?? performance.now();
|
|
52702
52864
|
const opened = await deps.activate(project);
|
|
52703
|
-
const tookMs = Math.round((deps.monotonicNow?.() ?? performance.now()) - startedAt);
|
|
52865
|
+
const tookMs = Math.round(resolveMs + ((deps.monotonicNow?.() ?? performance.now()) - startedAt));
|
|
52704
52866
|
lastTookMs = tookMs;
|
|
52705
52867
|
if (opened === void 0) result.failed.push(entry.id);
|
|
52706
52868
|
else {
|
|
@@ -52737,14 +52899,14 @@ var init_tenant_prime = __esm({
|
|
|
52737
52899
|
init_logging();
|
|
52738
52900
|
PRIME_START_DELAY_MS = 250;
|
|
52739
52901
|
PRIME_MIN_GAP_MS = 25;
|
|
52740
|
-
PRIME_MAX_GAP_MS =
|
|
52902
|
+
PRIME_MAX_GAP_MS = 1500;
|
|
52741
52903
|
}
|
|
52742
52904
|
});
|
|
52743
52905
|
|
|
52744
52906
|
// packages/server/src/project-teardown.ts
|
|
52745
52907
|
import { rmSync as rmSync12 } from "node:fs";
|
|
52746
52908
|
import { homedir as homedir19 } from "node:os";
|
|
52747
|
-
import { dirname as
|
|
52909
|
+
import { dirname as dirname20, resolve as resolve10 } from "node:path";
|
|
52748
52910
|
async function stopProjectWorkers(ctx) {
|
|
52749
52911
|
let stopped = 0;
|
|
52750
52912
|
for (const row of ctx.storage.allSessions()) {
|
|
@@ -52764,7 +52926,7 @@ function deleteProjectState(projectId, home = homedir19()) {
|
|
|
52764
52926
|
if (!/^[\w.-]+$/u.test(projectId) || projectId === "." || projectId === "..") {
|
|
52765
52927
|
throw new Error(`Refusing to delete state for a malformed project id: ${projectId}`);
|
|
52766
52928
|
}
|
|
52767
|
-
if (
|
|
52929
|
+
if (dirname20(resolve10(target)) !== resolve10(dirname20(projectStateDir("x", home)))) {
|
|
52768
52930
|
throw new Error(`Refusing to delete ${target} \u2014 it is not a project state directory`);
|
|
52769
52931
|
}
|
|
52770
52932
|
rmSync12(target, { recursive: true, force: true });
|
|
@@ -52787,13 +52949,14 @@ __export(index_exports, {
|
|
|
52787
52949
|
createShutdownSignalHandler: () => createShutdownSignalHandler,
|
|
52788
52950
|
pipeToApp: () => pipeToApp,
|
|
52789
52951
|
registeredTenantHealth: () => registeredTenantHealth,
|
|
52952
|
+
serveStatic: () => serveStatic,
|
|
52790
52953
|
splitTenantRequest: () => splitTenantRequest,
|
|
52791
52954
|
startServer: () => startServer,
|
|
52792
52955
|
unknownProjectPage: () => unknownProjectPage
|
|
52793
52956
|
});
|
|
52794
52957
|
import { createServer } from "node:http";
|
|
52795
|
-
import { readFileSync as readFileSync29, existsSync as existsSync15 } from "node:fs";
|
|
52796
|
-
import { dirname as
|
|
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";
|
|
52797
52960
|
function readServerAddressHolder(path) {
|
|
52798
52961
|
try {
|
|
52799
52962
|
const value = JSON.parse(readFileSync29(path, "utf8"));
|
|
@@ -52894,14 +53057,63 @@ function createShutdownSignalHandler(options) {
|
|
|
52894
53057
|
);
|
|
52895
53058
|
};
|
|
52896
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
|
+
}
|
|
52897
53085
|
function serveStatic(distDir, req, res) {
|
|
52898
53086
|
const rel = normalize((req.url ?? "/").split("?")[0]).replace(/^(\.\.[/\\])+/, "");
|
|
52899
53087
|
let file = join42(distDir, rel === "/" ? "index.html" : rel);
|
|
52900
53088
|
if (!file.startsWith(distDir)) file = join42(distDir, "index.html");
|
|
52901
53089
|
if (!existsSync15(file)) file = join42(distDir, "index.html");
|
|
52902
53090
|
try {
|
|
52903
|
-
const
|
|
52904
|
-
|
|
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);
|
|
52905
53117
|
res.end(body);
|
|
52906
53118
|
} catch {
|
|
52907
53119
|
res.writeHead(404);
|
|
@@ -53003,10 +53215,10 @@ async function startServer(opts = {}) {
|
|
|
53003
53215
|
// too — projecting only the RPC is the exact half-fix the × already had to correct once.
|
|
53004
53216
|
(slug) => c.tailer.ownerGone?.(slug) ?? false
|
|
53005
53217
|
),
|
|
53006
|
-
// A reader's live watch on the file it shows. Gated as the read is (
|
|
53007
|
-
//
|
|
53008
|
-
// symlinked `.md` and its target are one watch.
|
|
53009
|
-
watchFile: (path, onChange) => watchLocalFile(resolveWatchableLocalFile(path,
|
|
53218
|
+
// A reader's live watch on the file it shows. Gated as the read is (one set of openable roots for
|
|
53219
|
+
// both readers, plus the Markdown reader's canonical-extension check) and watched by CANONICAL
|
|
53220
|
+
// path, so a symlinked `.md` and its target are one watch.
|
|
53221
|
+
watchFile: (path, onChange) => watchLocalFile(resolveWatchableLocalFile(path, openableFileRoots(c.project)), onChange)
|
|
53010
53222
|
});
|
|
53011
53223
|
let githubInit;
|
|
53012
53224
|
let terminal;
|
|
@@ -53150,7 +53362,7 @@ async function startServer(opts = {}) {
|
|
|
53150
53362
|
if (statusPath && statusIdentity) runtime.removeStatus(statusPath, statusIdentity);
|
|
53151
53363
|
if (statusPath && statusIdentity) {
|
|
53152
53364
|
try {
|
|
53153
|
-
runtime.removeStatus(serverAddressPathForStateDir(
|
|
53365
|
+
runtime.removeStatus(serverAddressPathForStateDir(dirname21(statusPath)), statusIdentity);
|
|
53154
53366
|
} catch {
|
|
53155
53367
|
}
|
|
53156
53368
|
}
|
|
@@ -53498,13 +53710,14 @@ async function startServer(opts = {}) {
|
|
|
53498
53710
|
});
|
|
53499
53711
|
}
|
|
53500
53712
|
}
|
|
53501
|
-
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;
|
|
53502
53714
|
var init_index = __esm({
|
|
53503
53715
|
"packages/server/src/index.ts"() {
|
|
53504
53716
|
"use strict";
|
|
53505
53717
|
init_src();
|
|
53506
53718
|
init_context();
|
|
53507
53719
|
init_app();
|
|
53720
|
+
init_compression();
|
|
53508
53721
|
init_terminal();
|
|
53509
53722
|
init_app_socket();
|
|
53510
53723
|
init_shutdown();
|
|
@@ -53572,6 +53785,11 @@ var init_index = __esm({
|
|
|
53572
53785
|
".ico": "image/x-icon",
|
|
53573
53786
|
".woff2": "font/woff2"
|
|
53574
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;
|
|
53575
53793
|
}
|
|
53576
53794
|
});
|
|
53577
53795
|
|