frizz 0.8.1 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/dist/claude-agent-broker.js +156 -13
- package/dist/dev-child.js +4603 -1769
- package/dist/frizz.js +684 -263
- package/package.json +1 -1
- package/runtime/board/config.mjs +12 -1
- package/runtime/board/index.mjs +5 -0
- package/runtime/board/thread-update.mjs +4 -0
- package/runtime/cc-worker/.claude-plugin/plugin.json +1 -1
- package/runtime/cc-worker/DECISIONS.md +18 -0
- package/runtime/cc-worker/bin/frizz-mcp.mjs +604 -55
- package/runtime/cc-worker/hooks/scratchpad.mjs +20 -24
- package/runtime/cc-worker/hooks/session-seed.mjs +2 -2
- package/runtime/cc-worker/skills/gh/scripts/github-watch.mjs +1 -1
- package/web-dist/assets/{TerminalPane-BM_laA_I.js → TerminalPane-XNji7D_c.js} +1 -1
- package/web-dist/assets/{abnfDiagram-VRR7QNED-C5FCLi1n.js → abnfDiagram-VRR7QNED-gPeb-B7g.js} +1 -1
- package/web-dist/assets/architecture-TIHT7OUA-BsgSgexh.js +1 -0
- package/web-dist/assets/{architectureDiagram-ZJ3FMSHR-Dm7tUnwt.js → architectureDiagram-ZJ3FMSHR-DV69ktbl.js} +1 -1
- package/web-dist/assets/{blockDiagram-677ZJIJ3-3EhpmwKM.js → blockDiagram-677ZJIJ3-D8vw5eim.js} +1 -1
- package/web-dist/assets/{c4Diagram-LMCZKHZV-Ca-BjDxw.js → c4Diagram-LMCZKHZV--9PLGn-L.js} +1 -1
- package/web-dist/assets/channel-ClLnncxh.js +1 -0
- package/web-dist/assets/{chunk-32BRIVSS-xGbaUlTN.js → chunk-32BRIVSS-D4BSk0FZ.js} +1 -1
- package/web-dist/assets/{chunk-52WLFC77-YYhE3F1a.js → chunk-52WLFC77-WNcmTkcR.js} +1 -1
- package/web-dist/assets/{chunk-C7G6YPKG-SYKXFtUg.js → chunk-C7G6YPKG-BDlcLa5W.js} +1 -1
- package/web-dist/assets/{chunk-EX3LRPZG-cqjtdM_c.js → chunk-EX3LRPZG-CFnqFt7s.js} +1 -1
- package/web-dist/assets/{chunk-FWX5IMBZ-qyaTngKT.js → chunk-FWX5IMBZ-Ci9LgOOg.js} +2 -2
- package/web-dist/assets/{chunk-HOUHSVGY-DBFt1HnE.js → chunk-HOUHSVGY-BTD_X5OP.js} +1 -1
- package/web-dist/assets/{chunk-ICXQ74PX-Bme_2_gm.js → chunk-ICXQ74PX-D2Y3Ys5K.js} +1 -1
- package/web-dist/assets/{chunk-MOJQB5TN-DupTmWhN.js → chunk-MOJQB5TN-C-GDt7vC.js} +1 -1
- package/web-dist/assets/{chunk-OGEWGWER-DSqmbKCq.js → chunk-OGEWGWER-DvnPoUnz.js} +1 -1
- package/web-dist/assets/{chunk-PUDLZKDR-DVnHUoFN.js → chunk-PUDLZKDR-C3AymM-j.js} +1 -1
- package/web-dist/assets/{chunk-Q4XR5HBZ-BIZh_Yuh.js → chunk-Q4XR5HBZ-DmyBNAl6.js} +1 -1
- package/web-dist/assets/{chunk-V7JOEXUC-e2G7UgOg.js → chunk-V7JOEXUC-DTuPUeRa.js} +1 -1
- package/web-dist/assets/{chunk-VAUOI2AC-uYgyYWPh.js → chunk-VAUOI2AC-CcW8PviB.js} +1 -1
- package/web-dist/assets/{chunk-VR4S4FIN-BjGjcexQ.js → chunk-VR4S4FIN-0tm6n83G.js} +1 -1
- package/web-dist/assets/{chunk-WYO6CB5R-BKKd_W3B.js → chunk-WYO6CB5R-CH3ADqeI.js} +1 -1
- package/web-dist/assets/{chunk-ZGVPDNZ5-D5_hsjnF.js → chunk-ZGVPDNZ5-BHFnlpXH.js} +1 -1
- package/web-dist/assets/classDiagram-OUVF2IWQ-CwLnPgud.js +1 -0
- package/web-dist/assets/classDiagram-v2-EOCWNBFH-CwLnPgud.js +1 -0
- package/web-dist/assets/{cynefin-VYW2F7L2-bkFv7EpV.js → cynefin-VYW2F7L2-DtFCLOIN.js} +1 -1
- package/web-dist/assets/{cynefinDiagram-TSTJHNR4-Du2-dyuZ.js → cynefinDiagram-TSTJHNR4-llFTHp2q.js} +1 -1
- package/web-dist/assets/{dagre-VKFMJZFB-CU7w00Ul.js → dagre-VKFMJZFB-CvBRVl_k.js} +1 -1
- package/web-dist/assets/{diagram-FQU43EPY-BxvVgxWb.js → diagram-FQU43EPY-D1QXo6ri.js} +1 -1
- package/web-dist/assets/{diagram-G47NLZAW-D8VvetwQ.js → diagram-G47NLZAW-2pZew-Bk.js} +1 -1
- package/web-dist/assets/{diagram-NH7WQ7WH-CwsChkED.js → diagram-NH7WQ7WH-Ch9JRwGN.js} +1 -1
- package/web-dist/assets/{diagram-OA4YK3LP-BIPYbe6L.js → diagram-OA4YK3LP-BIbrLf02.js} +1 -1
- package/web-dist/assets/{diagram-WEI45ONY-BoyH4dKl.js → diagram-WEI45ONY-D3KtL2s-.js} +1 -1
- package/web-dist/assets/{ebnfDiagram-CCIWWBDH-9A3WRDfU.js → ebnfDiagram-CCIWWBDH-D829sKG_.js} +1 -1
- package/web-dist/assets/{erDiagram-Q63AITRT-D3Y9WA4H.js → erDiagram-Q63AITRT-Cj3Grovg.js} +1 -1
- package/web-dist/assets/eventmodeling-45OFAUF4-CzZyv3HA.js +1 -0
- package/web-dist/assets/flowDiagram-23GEKE2U-rQ7PRoGL.js +1 -0
- package/web-dist/assets/{ganttDiagram-NO4QXBWP-Bk2-LClm.js → ganttDiagram-NO4QXBWP-CGHaXF-g.js} +1 -1
- package/web-dist/assets/{gitGraph-TEB2WS4Q-CXvPrsio.js → gitGraph-TEB2WS4Q-BbxeaotX.js} +1 -1
- package/web-dist/assets/{gitGraphDiagram-IHSO6WYX-BC9D72kT.js → gitGraphDiagram-IHSO6WYX-C4WHE0cI.js} +1 -1
- package/web-dist/assets/index-BpCFdr7Z.css +1 -0
- package/web-dist/assets/index-CiaKj-0V.js +506 -0
- package/web-dist/assets/{info-DKCQHKI2-Beag76kE.js → info-DKCQHKI2-3fKpn7Qr.js} +1 -1
- package/web-dist/assets/{infoDiagram-FWYZ7A6U-DaqYXHYB.js → infoDiagram-FWYZ7A6U-CDQl4JMv.js} +1 -1
- package/web-dist/assets/{ishikawaDiagram-FXEZZL3T-D-d4tmLU.js → ishikawaDiagram-FXEZZL3T-CDKjMW-u.js} +1 -1
- package/web-dist/assets/{journeyDiagram-5HDEW3XC-kkFYzNg1.js → journeyDiagram-5HDEW3XC-BOsabu1Z.js} +1 -1
- package/web-dist/assets/{kanban-definition-HUTT4EX6-BYRPjbfv.js → kanban-definition-HUTT4EX6-KTuh-6eN.js} +1 -1
- package/web-dist/assets/{line-C8l7y6rG.js → line-KaxbYSN3.js} +1 -1
- package/web-dist/assets/{mermaid-parser.core-BG3fgy77.js → mermaid-parser.core-B53huyyd.js} +3 -3
- package/web-dist/assets/{mermaid.core-BCDzcbhr.js → mermaid.core-Bz6B5ouC.js} +3 -3
- package/web-dist/assets/{mindmap-definition-LN4V7U3C-CP_bgQm8.js → mindmap-definition-LN4V7U3C-Bb7T7B3a.js} +1 -1
- package/web-dist/assets/{packet-7NZHBO7P-Dgd69pFS.js → packet-7NZHBO7P-w3lynC8r.js} +1 -1
- package/web-dist/assets/{pegDiagram-2B236MQR-BJUb_DOD.js → pegDiagram-2B236MQR-nQ7c2Z03.js} +1 -1
- package/web-dist/assets/{pie-RZYD4A2V-DPbVRAuL.js → pie-RZYD4A2V-B3Yko5Wb.js} +1 -1
- package/web-dist/assets/{pieDiagram-ENE6RG2P-DavUeOqM.js → pieDiagram-ENE6RG2P-CN4Lp5HG.js} +1 -1
- package/web-dist/assets/{quadrantDiagram-ABIIQ3AL-BdvoSedu.js → quadrantDiagram-ABIIQ3AL-3QTB92dH.js} +1 -1
- package/web-dist/assets/{radar-I7S5WNFK-C2TAta9K.js → radar-I7S5WNFK-8ZsXt0FI.js} +1 -1
- package/web-dist/assets/{railroad-3IZDKUUU-DEMjzYqC.js → railroad-3IZDKUUU-C4IKxzEZ.js} +1 -1
- package/web-dist/assets/railroad-abnf-AHOZXSZD-g2si5iUv.js +1 -0
- package/web-dist/assets/railroad-ebnf-EBAXGLYW-BikkLG6y.js +1 -0
- package/web-dist/assets/railroad-peg-LSFZ7HO6-Dv4rDehz.js +1 -0
- package/web-dist/assets/{railroadDiagram-RFXS5EU6-C4rERo6H.js → railroadDiagram-RFXS5EU6-DrGnmjpD.js} +1 -1
- package/web-dist/assets/{requirementDiagram-TGXJPOKE-DlIG9D0n.js → requirementDiagram-TGXJPOKE-Bh9XNuxa.js} +1 -1
- package/web-dist/assets/{sankeyDiagram-HTMAVEWB-DVMrG-qY.js → sankeyDiagram-HTMAVEWB-CXy3ra5-.js} +1 -1
- package/web-dist/assets/{sequenceDiagram-DBY2YBRQ-DDcDM_-e.js → sequenceDiagram-DBY2YBRQ-B7ESCT52.js} +1 -1
- package/web-dist/assets/{stateDiagram-2N3HPSRC-DuCRKU5t.js → stateDiagram-2N3HPSRC-DFr9k5Xv.js} +1 -1
- package/web-dist/assets/stateDiagram-v2-6OUMAXLB-BQUd0MEa.js +1 -0
- package/web-dist/assets/{swimlanes-5IMT3BWC-CY0fdvUm.js → swimlanes-5IMT3BWC-B2RKoz1q.js} +1 -1
- package/web-dist/assets/swimlanesDiagram-G3AALYLV-GWn4zXxj.js +8 -0
- package/web-dist/assets/{timeline-definition-FHXFAJF6-De0fDNdU.js → timeline-definition-FHXFAJF6-KpTqaG5g.js} +1 -1
- package/web-dist/assets/{treeView-QDETBFTQ-AIoMhcen.js → treeView-QDETBFTQ-oB1a6ikv.js} +1 -1
- package/web-dist/assets/{treemap-6X3UGDF4-CPZ1Ln05.js → treemap-6X3UGDF4-DO8OvvZg.js} +1 -1
- package/web-dist/assets/{vennDiagram-L72KCM5P-FrSO6pmh.js → vennDiagram-L72KCM5P-BgTjK4_q.js} +1 -1
- package/web-dist/assets/{wardley-OPB4EBWU-BbET6cjs.js → wardley-OPB4EBWU-CGyjn939.js} +1 -1
- package/web-dist/assets/{wardleyDiagram-EHGQE667-DqvcCBjr.js → wardleyDiagram-EHGQE667-CM_HxruS.js} +1 -1
- package/web-dist/assets/{xychartDiagram-FW5EYKEG-91xKEO07.js → xychartDiagram-FW5EYKEG-vamHu0jN.js} +1 -1
- package/web-dist/index.html +2 -2
- package/web-dist/assets/architecture-TIHT7OUA-ngY1F0r2.js +0 -1
- package/web-dist/assets/channel-BpyNaJoi.js +0 -1
- package/web-dist/assets/classDiagram-OUVF2IWQ-DTEWwxt7.js +0 -1
- package/web-dist/assets/classDiagram-v2-EOCWNBFH-DTEWwxt7.js +0 -1
- package/web-dist/assets/eventmodeling-45OFAUF4-D7g9kDF0.js +0 -1
- package/web-dist/assets/flowDiagram-23GEKE2U-BqKnxVr3.js +0 -1
- package/web-dist/assets/index-CCtNIGi6.js +0 -491
- package/web-dist/assets/index-Cq79m8AR.css +0 -1
- package/web-dist/assets/railroad-abnf-AHOZXSZD-_4FByoRI.js +0 -1
- package/web-dist/assets/railroad-ebnf-EBAXGLYW-DKAvMIMu.js +0 -1
- package/web-dist/assets/railroad-peg-LSFZ7HO6-CkJl3c69.js +0 -1
- package/web-dist/assets/stateDiagram-v2-6OUMAXLB-90dqEQum.js +0 -1
- package/web-dist/assets/swimlanesDiagram-G3AALYLV-BETWueIt.js +0 -8
package/dist/frizz.js
CHANGED
|
@@ -4175,10 +4175,10 @@ var require_resolve_block_map = __commonJS({
|
|
|
4175
4175
|
let offset = bm.offset;
|
|
4176
4176
|
let commentEnd = null;
|
|
4177
4177
|
for (const collItem of bm.items) {
|
|
4178
|
-
const { start, key, sep:
|
|
4178
|
+
const { start, key, sep: sep4, value } = collItem;
|
|
4179
4179
|
const keyProps = resolveProps.resolveProps(start, {
|
|
4180
4180
|
indicator: "explicit-key-ind",
|
|
4181
|
-
next: key ??
|
|
4181
|
+
next: key ?? sep4?.[0],
|
|
4182
4182
|
offset,
|
|
4183
4183
|
onError,
|
|
4184
4184
|
parentIndent: bm.indent,
|
|
@@ -4192,7 +4192,7 @@ var require_resolve_block_map = __commonJS({
|
|
|
4192
4192
|
else if ("indent" in key && key.indent !== bm.indent)
|
|
4193
4193
|
onError(offset, "BAD_INDENT", startColMsg);
|
|
4194
4194
|
}
|
|
4195
|
-
if (!keyProps.anchor && !keyProps.tag && !
|
|
4195
|
+
if (!keyProps.anchor && !keyProps.tag && !sep4) {
|
|
4196
4196
|
commentEnd = keyProps.end;
|
|
4197
4197
|
if (keyProps.comment) {
|
|
4198
4198
|
if (map.comment)
|
|
@@ -4216,7 +4216,7 @@ var require_resolve_block_map = __commonJS({
|
|
|
4216
4216
|
ctx.atKey = false;
|
|
4217
4217
|
if (utilMapIncludes.mapIncludes(ctx, map.items, keyNode))
|
|
4218
4218
|
onError(keyStart, "DUPLICATE_KEY", "Map keys must be unique");
|
|
4219
|
-
const valueProps = resolveProps.resolveProps(
|
|
4219
|
+
const valueProps = resolveProps.resolveProps(sep4 ?? [], {
|
|
4220
4220
|
indicator: "map-value-ind",
|
|
4221
4221
|
next: value,
|
|
4222
4222
|
offset: keyNode.range[2],
|
|
@@ -4232,7 +4232,7 @@ var require_resolve_block_map = __commonJS({
|
|
|
4232
4232
|
if (ctx.options.strict && keyProps.start < valueProps.found.offset - 1024)
|
|
4233
4233
|
onError(keyNode.range, "KEY_OVER_1024_CHARS", "The : indicator must be at most 1024 chars after the start of an implicit block mapping key");
|
|
4234
4234
|
}
|
|
4235
|
-
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset,
|
|
4235
|
+
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset, sep4, null, valueProps, onError);
|
|
4236
4236
|
if (ctx.schema.compat)
|
|
4237
4237
|
utilFlowIndentCheck.flowIndentCheck(bm.indent, value, onError);
|
|
4238
4238
|
offset = valueNode.range[2];
|
|
@@ -4323,7 +4323,7 @@ var require_resolve_end = __commonJS({
|
|
|
4323
4323
|
let comment = "";
|
|
4324
4324
|
if (end) {
|
|
4325
4325
|
let hasSpace = false;
|
|
4326
|
-
let
|
|
4326
|
+
let sep4 = "";
|
|
4327
4327
|
for (const token of end) {
|
|
4328
4328
|
const { source, type } = token;
|
|
4329
4329
|
switch (type) {
|
|
@@ -4337,13 +4337,13 @@ var require_resolve_end = __commonJS({
|
|
|
4337
4337
|
if (!comment)
|
|
4338
4338
|
comment = cb;
|
|
4339
4339
|
else
|
|
4340
|
-
comment +=
|
|
4341
|
-
|
|
4340
|
+
comment += sep4 + cb;
|
|
4341
|
+
sep4 = "";
|
|
4342
4342
|
break;
|
|
4343
4343
|
}
|
|
4344
4344
|
case "newline":
|
|
4345
4345
|
if (comment)
|
|
4346
|
-
|
|
4346
|
+
sep4 += source;
|
|
4347
4347
|
hasSpace = true;
|
|
4348
4348
|
break;
|
|
4349
4349
|
default:
|
|
@@ -4386,18 +4386,18 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
4386
4386
|
let offset = fc.offset + fc.start.source.length;
|
|
4387
4387
|
for (let i = 0; i < fc.items.length; ++i) {
|
|
4388
4388
|
const collItem = fc.items[i];
|
|
4389
|
-
const { start, key, sep:
|
|
4389
|
+
const { start, key, sep: sep4, value } = collItem;
|
|
4390
4390
|
const props = resolveProps.resolveProps(start, {
|
|
4391
4391
|
flow: fcName,
|
|
4392
4392
|
indicator: "explicit-key-ind",
|
|
4393
|
-
next: key ??
|
|
4393
|
+
next: key ?? sep4?.[0],
|
|
4394
4394
|
offset,
|
|
4395
4395
|
onError,
|
|
4396
4396
|
parentIndent: fc.indent,
|
|
4397
4397
|
startOnNewline: false
|
|
4398
4398
|
});
|
|
4399
4399
|
if (!props.found) {
|
|
4400
|
-
if (!props.anchor && !props.tag && !
|
|
4400
|
+
if (!props.anchor && !props.tag && !sep4 && !value) {
|
|
4401
4401
|
if (i === 0 && props.comma)
|
|
4402
4402
|
onError(props.comma, "UNEXPECTED_TOKEN", `Unexpected , in ${fcName}`);
|
|
4403
4403
|
else if (i < fc.items.length - 1)
|
|
@@ -4451,8 +4451,8 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
4451
4451
|
}
|
|
4452
4452
|
}
|
|
4453
4453
|
}
|
|
4454
|
-
if (!isMap && !
|
|
4455
|
-
const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end,
|
|
4454
|
+
if (!isMap && !sep4 && !props.found) {
|
|
4455
|
+
const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, sep4, null, props, onError);
|
|
4456
4456
|
coll.items.push(valueNode);
|
|
4457
4457
|
offset = valueNode.range[2];
|
|
4458
4458
|
if (isBlock(value))
|
|
@@ -4464,7 +4464,7 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
4464
4464
|
if (isBlock(key))
|
|
4465
4465
|
onError(keyNode.range, "BLOCK_IN_FLOW", blockMsg);
|
|
4466
4466
|
ctx.atKey = false;
|
|
4467
|
-
const valueProps = resolveProps.resolveProps(
|
|
4467
|
+
const valueProps = resolveProps.resolveProps(sep4 ?? [], {
|
|
4468
4468
|
flow: fcName,
|
|
4469
4469
|
indicator: "map-value-ind",
|
|
4470
4470
|
next: value,
|
|
@@ -4475,8 +4475,8 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
4475
4475
|
});
|
|
4476
4476
|
if (valueProps.found) {
|
|
4477
4477
|
if (!isMap && !props.found && ctx.options.strict) {
|
|
4478
|
-
if (
|
|
4479
|
-
for (const st of
|
|
4478
|
+
if (sep4)
|
|
4479
|
+
for (const st of sep4) {
|
|
4480
4480
|
if (st === valueProps.found)
|
|
4481
4481
|
break;
|
|
4482
4482
|
if (st.type === "newline") {
|
|
@@ -4493,7 +4493,7 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
4493
4493
|
else
|
|
4494
4494
|
onError(valueProps.start, "MISSING_CHAR", `Missing , or : between ${fcName} items`);
|
|
4495
4495
|
}
|
|
4496
|
-
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end,
|
|
4496
|
+
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep4, null, valueProps, onError) : null;
|
|
4497
4497
|
if (valueNode) {
|
|
4498
4498
|
if (isBlock(value))
|
|
4499
4499
|
onError(valueNode.range, "BLOCK_IN_FLOW", blockMsg);
|
|
@@ -4673,7 +4673,7 @@ var require_resolve_block_scalar = __commonJS({
|
|
|
4673
4673
|
chompStart = i + 1;
|
|
4674
4674
|
}
|
|
4675
4675
|
let value = "";
|
|
4676
|
-
let
|
|
4676
|
+
let sep4 = "";
|
|
4677
4677
|
let prevMoreIndented = false;
|
|
4678
4678
|
for (let i = 0; i < contentStart; ++i)
|
|
4679
4679
|
value += lines[i][0].slice(trimIndent) + "\n";
|
|
@@ -4690,24 +4690,24 @@ var require_resolve_block_scalar = __commonJS({
|
|
|
4690
4690
|
indent = "";
|
|
4691
4691
|
}
|
|
4692
4692
|
if (type === Scalar.Scalar.BLOCK_LITERAL) {
|
|
4693
|
-
value +=
|
|
4694
|
-
|
|
4693
|
+
value += sep4 + indent.slice(trimIndent) + content;
|
|
4694
|
+
sep4 = "\n";
|
|
4695
4695
|
} else if (indent.length > trimIndent || content[0] === " ") {
|
|
4696
|
-
if (
|
|
4697
|
-
|
|
4698
|
-
else if (!prevMoreIndented &&
|
|
4699
|
-
|
|
4700
|
-
value +=
|
|
4701
|
-
|
|
4696
|
+
if (sep4 === " ")
|
|
4697
|
+
sep4 = "\n";
|
|
4698
|
+
else if (!prevMoreIndented && sep4 === "\n")
|
|
4699
|
+
sep4 = "\n\n";
|
|
4700
|
+
value += sep4 + indent.slice(trimIndent) + content;
|
|
4701
|
+
sep4 = "\n";
|
|
4702
4702
|
prevMoreIndented = true;
|
|
4703
4703
|
} else if (content === "") {
|
|
4704
|
-
if (
|
|
4704
|
+
if (sep4 === "\n")
|
|
4705
4705
|
value += "\n";
|
|
4706
4706
|
else
|
|
4707
|
-
|
|
4707
|
+
sep4 = "\n";
|
|
4708
4708
|
} else {
|
|
4709
|
-
value +=
|
|
4710
|
-
|
|
4709
|
+
value += sep4 + content;
|
|
4710
|
+
sep4 = " ";
|
|
4711
4711
|
prevMoreIndented = false;
|
|
4712
4712
|
}
|
|
4713
4713
|
}
|
|
@@ -4889,25 +4889,25 @@ var require_resolve_flow_scalar = __commonJS({
|
|
|
4889
4889
|
if (!match)
|
|
4890
4890
|
return source;
|
|
4891
4891
|
let res = match[1];
|
|
4892
|
-
let
|
|
4892
|
+
let sep4 = " ";
|
|
4893
4893
|
let pos = first.lastIndex;
|
|
4894
4894
|
line.lastIndex = pos;
|
|
4895
4895
|
while (match = line.exec(source)) {
|
|
4896
4896
|
if (match[1] === "") {
|
|
4897
|
-
if (
|
|
4898
|
-
res +=
|
|
4897
|
+
if (sep4 === "\n")
|
|
4898
|
+
res += sep4;
|
|
4899
4899
|
else
|
|
4900
|
-
|
|
4900
|
+
sep4 = "\n";
|
|
4901
4901
|
} else {
|
|
4902
|
-
res +=
|
|
4903
|
-
|
|
4902
|
+
res += sep4 + match[1];
|
|
4903
|
+
sep4 = " ";
|
|
4904
4904
|
}
|
|
4905
4905
|
pos = line.lastIndex;
|
|
4906
4906
|
}
|
|
4907
4907
|
const last = /[ \t]*(.*)/sy;
|
|
4908
4908
|
last.lastIndex = pos;
|
|
4909
4909
|
match = last.exec(source);
|
|
4910
|
-
return res +
|
|
4910
|
+
return res + sep4 + (match?.[1] ?? "");
|
|
4911
4911
|
}
|
|
4912
4912
|
function doubleQuotedValue(source, onError) {
|
|
4913
4913
|
let res = "";
|
|
@@ -5717,14 +5717,14 @@ var require_cst_stringify = __commonJS({
|
|
|
5717
5717
|
}
|
|
5718
5718
|
}
|
|
5719
5719
|
}
|
|
5720
|
-
function stringifyItem({ start, key, sep:
|
|
5720
|
+
function stringifyItem({ start, key, sep: sep4, value }) {
|
|
5721
5721
|
let res = "";
|
|
5722
5722
|
for (const st of start)
|
|
5723
5723
|
res += st.source;
|
|
5724
5724
|
if (key)
|
|
5725
5725
|
res += stringifyToken(key);
|
|
5726
|
-
if (
|
|
5727
|
-
for (const st of
|
|
5726
|
+
if (sep4)
|
|
5727
|
+
for (const st of sep4)
|
|
5728
5728
|
res += st.source;
|
|
5729
5729
|
if (value)
|
|
5730
5730
|
res += stringifyToken(value);
|
|
@@ -6891,18 +6891,18 @@ var require_parser = __commonJS({
|
|
|
6891
6891
|
if (this.type === "map-value-ind") {
|
|
6892
6892
|
const prev = getPrevProps(this.peek(2));
|
|
6893
6893
|
const start = getFirstKeyStartProps(prev);
|
|
6894
|
-
let
|
|
6894
|
+
let sep4;
|
|
6895
6895
|
if (scalar.end) {
|
|
6896
|
-
|
|
6897
|
-
|
|
6896
|
+
sep4 = scalar.end;
|
|
6897
|
+
sep4.push(this.sourceToken);
|
|
6898
6898
|
delete scalar.end;
|
|
6899
6899
|
} else
|
|
6900
|
-
|
|
6900
|
+
sep4 = [this.sourceToken];
|
|
6901
6901
|
const map = {
|
|
6902
6902
|
type: "block-map",
|
|
6903
6903
|
offset: scalar.offset,
|
|
6904
6904
|
indent: scalar.indent,
|
|
6905
|
-
items: [{ start, key: scalar, sep:
|
|
6905
|
+
items: [{ start, key: scalar, sep: sep4 }]
|
|
6906
6906
|
};
|
|
6907
6907
|
this.onKeyLine = true;
|
|
6908
6908
|
this.stack[this.stack.length - 1] = map;
|
|
@@ -7055,15 +7055,15 @@ var require_parser = __commonJS({
|
|
|
7055
7055
|
} else if (isFlowToken(it.key) && !includesToken(it.sep, "newline")) {
|
|
7056
7056
|
const start2 = getFirstKeyStartProps(it.start);
|
|
7057
7057
|
const key = it.key;
|
|
7058
|
-
const
|
|
7059
|
-
|
|
7058
|
+
const sep4 = it.sep;
|
|
7059
|
+
sep4.push(this.sourceToken);
|
|
7060
7060
|
delete it.key;
|
|
7061
7061
|
delete it.sep;
|
|
7062
7062
|
this.stack.push({
|
|
7063
7063
|
type: "block-map",
|
|
7064
7064
|
offset: this.offset,
|
|
7065
7065
|
indent: this.indent,
|
|
7066
|
-
items: [{ start: start2, key, sep:
|
|
7066
|
+
items: [{ start: start2, key, sep: sep4 }]
|
|
7067
7067
|
});
|
|
7068
7068
|
} else if (start.length > 0) {
|
|
7069
7069
|
it.sep = it.sep.concat(start, this.sourceToken);
|
|
@@ -7257,13 +7257,13 @@ var require_parser = __commonJS({
|
|
|
7257
7257
|
const prev = getPrevProps(parent);
|
|
7258
7258
|
const start = getFirstKeyStartProps(prev);
|
|
7259
7259
|
fixFlowSeqItems(fc);
|
|
7260
|
-
const
|
|
7261
|
-
|
|
7260
|
+
const sep4 = fc.end.splice(1, fc.end.length);
|
|
7261
|
+
sep4.push(this.sourceToken);
|
|
7262
7262
|
const map = {
|
|
7263
7263
|
type: "block-map",
|
|
7264
7264
|
offset: fc.offset,
|
|
7265
7265
|
indent: fc.indent,
|
|
7266
|
-
items: [{ start, key: fc, sep:
|
|
7266
|
+
items: [{ start, key: fc, sep: sep4 }]
|
|
7267
7267
|
};
|
|
7268
7268
|
this.onKeyLine = true;
|
|
7269
7269
|
this.stack[this.stack.length - 1] = map;
|
|
@@ -12184,6 +12184,16 @@ var init_interactions = __esm({
|
|
|
12184
12184
|
});
|
|
12185
12185
|
|
|
12186
12186
|
// packages/shared/src/claim.ts
|
|
12187
|
+
function isAnonymousClaimName(name) {
|
|
12188
|
+
return ANONYMOUS_CLAIM_PATTERN.test(name);
|
|
12189
|
+
}
|
|
12190
|
+
function generateAnonymousClaimName() {
|
|
12191
|
+
const bytes = new Uint8Array(ANONYMOUS_CLAIM_NAME_LENGTH);
|
|
12192
|
+
crypto.getRandomValues(bytes);
|
|
12193
|
+
let name = "";
|
|
12194
|
+
for (const byte of bytes) name += ANONYMOUS_CLAIM_ALPHABET[byte & 31];
|
|
12195
|
+
return name;
|
|
12196
|
+
}
|
|
12187
12197
|
function toBase64Url(bytes) {
|
|
12188
12198
|
const view = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);
|
|
12189
12199
|
let binary = "";
|
|
@@ -12267,7 +12277,7 @@ async function claimIdentityFromPrivateKey(pkcs8) {
|
|
|
12267
12277
|
return null;
|
|
12268
12278
|
}
|
|
12269
12279
|
}
|
|
12270
|
-
var CLAIM_PROTOCOL_VERSION, CLAIM_MAX_AGE_MS, CLAIM_LEASE_MS, RESERVED_CLAIM_NAMES, CLAIM_NAME_MIN_LENGTH, CLAIM_NAME_MAX_LENGTH;
|
|
12280
|
+
var CLAIM_PROTOCOL_VERSION, CLAIM_MAX_AGE_MS, CLAIM_LEASE_MS, RESERVED_CLAIM_NAMES, CLAIM_NAME_MIN_LENGTH, CLAIM_NAME_MAX_LENGTH, ANONYMOUS_CLAIM_NAME_LENGTH, ANONYMOUS_CLAIM_ALPHABET, ANONYMOUS_CLAIM_PATTERN;
|
|
12271
12281
|
var init_claim = __esm({
|
|
12272
12282
|
"packages/shared/src/claim.ts"() {
|
|
12273
12283
|
"use strict";
|
|
@@ -12306,6 +12316,9 @@ var init_claim = __esm({
|
|
|
12306
12316
|
]);
|
|
12307
12317
|
CLAIM_NAME_MIN_LENGTH = 3;
|
|
12308
12318
|
CLAIM_NAME_MAX_LENGTH = 63;
|
|
12319
|
+
ANONYMOUS_CLAIM_NAME_LENGTH = 20;
|
|
12320
|
+
ANONYMOUS_CLAIM_ALPHABET = "abcdefghijklmnopqrstuvwxyz234567";
|
|
12321
|
+
ANONYMOUS_CLAIM_PATTERN = new RegExp(`^[a-z2-7]{${ANONYMOUS_CLAIM_NAME_LENGTH}}$`);
|
|
12309
12322
|
}
|
|
12310
12323
|
});
|
|
12311
12324
|
|
|
@@ -12374,7 +12387,7 @@ function relayHandshakeInput(name, pubkey, issuedAt) {
|
|
|
12374
12387
|
["frizz-relay", `v${RELAY_PROTOCOL_VERSION}`, name, pubkey, String(issuedAt)].join(":")
|
|
12375
12388
|
);
|
|
12376
12389
|
}
|
|
12377
|
-
var RELAY_PROTOCOL_VERSION, RELAY_STRIPPED_HEADERS, RELAY_MAX_FRAME_BODY, RELAY_MAX_WS_CHUNK, WsMessageAssembler, serializeFrame;
|
|
12390
|
+
var RELAY_PROTOCOL_VERSION, RELAY_STRIPPED_HEADERS, RELAY_MAX_FRAME_BODY, RELAY_MAX_WS_CHUNK, WsMessageAssembler, serializeFrame, RELAY_KEEPALIVE_PING, RELAY_KEEPALIVE_PONG;
|
|
12378
12391
|
var init_relay_protocol = __esm({
|
|
12379
12392
|
"packages/shared/src/relay-protocol.ts"() {
|
|
12380
12393
|
"use strict";
|
|
@@ -12440,6 +12453,8 @@ var init_relay_protocol = __esm({
|
|
|
12440
12453
|
}
|
|
12441
12454
|
};
|
|
12442
12455
|
serializeFrame = (frame) => JSON.stringify(frame);
|
|
12456
|
+
RELAY_KEEPALIVE_PING = serializeFrame({ t: "ping", id: "keepalive" });
|
|
12457
|
+
RELAY_KEEPALIVE_PONG = serializeFrame({ t: "pong", id: "keepalive" });
|
|
12443
12458
|
}
|
|
12444
12459
|
});
|
|
12445
12460
|
|
|
@@ -12447,7 +12462,7 @@ var init_relay_protocol = __esm({
|
|
|
12447
12462
|
function fallbackPort(base) {
|
|
12448
12463
|
return base + 1e4;
|
|
12449
12464
|
}
|
|
12450
|
-
var import_yaml, ATTACHMENT_IMAGE_EXTENSIONS, ATTACHMENT_DOC_EXTENSIONS, ATTACHMENT_EXTENSIONS, ATTACHMENT_MAX_BASE64_CHARS, ATTACHMENT_MAX_BYTES, ATTACHMENT_EXT_SET, ATTACHMENT_ACCEPT, FrizzStatus, BlockMechanism, RuntimeState, Backend, CodexModel, ThreadProfileOption, ThreadAgent, SubAgentView, BgShellView, CompletionHoldOp, CompletionHold, AskOption, AskQuestion, PendingAsk, AwaitingHint, RETIRED_AWAITING_KINDS, RETIRED_LINE_RE, AWAITING_FOR_MAX_MS, SnoozeUntil, SNOOZE_PROMPT_MAX, SnoozePrompt, RECURRING_PROMPT_MAX, RECURRING_MIN_INTERVAL_SECONDS, RECURRING_MAX_INTERVAL_SECONDS, RecurringPromptText, RecurringIntervalSeconds, ThreadRecurringPrompt, TIMER_PROMPT_MAX, TIMER_MAX_DELAY_SECONDS, TimerPromptText, SIGNOFF_NUDGE_MARKER, SIGNOFF_NUDGE_MESSAGE, ThreadWatchKind, GithubChecksState, GithubMergeState, GithubWatchStatus, ThreadWatchView, PR_WATCH_DEFAULT_FOR_MS, PrWatchView, AddOwnPrWatchInput, AddOwnPrWatchResult, DropOwnPrWatchInput, DropOwnPrWatchResult, ListOwnPrWatchesInput, OwnPrWatchesResult, ThreadTimerView, ThreadFence, LimitWindow, LimitPause, ThreadView, BoardErrorItem, BoardSnapshot, QuotaWindow, ProviderQuota, QuotaSnapshot, ProviderAuth, AccountEmails, AuthSnapshot, AccountLogoutInput, AccountLogoutResult, AccountLoginStartInput, AccountLoginStartResult, AccountLoginStatusInput, AccountLoginStatusResult, PermissionMode, LocalFileOpener, Settings, DispatchProviderPreferences, DispatchPreferences, DispatchProfileSnapshot, SetDispatchPreferenceInput, DispatchInput, ADOPT_THREAD_MESSAGE_MAX_CHARS, AdoptThreadInput, AdoptThreadResult, AdoptSessionInput, FollowUpInput, UnqueueFollowUpInput, UnqueueFollowUpResult, DeliverQueuedNowInput, DeliverQueuedNowResult, SetThreadSnoozeInput, SetThreadRecurringPromptInput, SetOwnThreadRecurringPromptInput, SetOwnThreadRecurringPromptResult, GetOwnThreadRecurringPromptInput, OwnThreadRecurringPromptResult, SetOwnThreadTimerInput, CancelOwnThreadTimerInput, ListOwnThreadTimersInput, OwnThreadTimersResult, ThreadActivityItem, ListOwnThreadActivityInput, OwnThreadActivityResult, SetOwnThreadTimerResult, CancelOwnThreadTimerResult, SetOwnThreadStopHookInput, SetOwnThreadHeartbeatInput, ThreadPluginReloadResult, RenameThreadInput, AiRenameThreadInput, AiRenameThreadResult, SetThreadPermissionInput, SetThreadPermissionResult, ThreadProfileOptionsInput, ThreadProfileOptionsResult, ThreadSkillSource, ThreadSkill, ThreadSkillsInput, ThreadSkillsResult, SetThreadProfileInput, SetThreadProfileResult, DISPATCH_TASK_BANNER, DISPATCH_TASK_BANNER_MARKER, HUMAN_GAP_FLOOR_MS, GithubWakeItem, GithubWakeSteer, WAKE_SCOPE, WAKE_REF, WAKE_SINGLE, WAKE_MULTI_HEAD, PR_WATCH_FINISHED, PR_WATCH_CI_PASSED, PR_WATCH_CI_FAILED, GithubStatus, GithubRefCard, GithubRefPreviewInput, GithubRefPreviewResult, GithubItem, GithubListInput, GithubListResult, GithubBatchInput, GithubBatchResult, BoardMeta, ServerEvent, TranscriptEdit, TranscriptTodo, TranscriptToolCall, TranscriptPart, TranscriptMessage, TranscriptPageCursor, TranscriptPage, TranscriptEarlierInput, SocketTranscriptSlug, SocketClientMsg, ProjectCard, PROJECT_ICON_MAX_BASE64_CHARS, DirectoryPickResult, ThreadLocation, FRIZZ_ROUTE_PREFIX, DEFAULT_PORT;
|
|
12465
|
+
var import_yaml, ATTACHMENT_IMAGE_EXTENSIONS, ATTACHMENT_TEXT_EXTENSIONS, ATTACHMENT_OFFICE_EXTENSIONS, ATTACHMENT_DATA_EXTENSIONS, ATTACHMENT_ARCHIVE_EXTENSIONS, ATTACHMENT_DOC_EXTENSIONS, ATTACHMENT_EXTENSIONS, ATTACHMENT_MAX_BASE64_CHARS, ATTACHMENT_MAX_BYTES, ATTACHMENT_EXT_SET, ATTACHMENT_ACCEPT, FrizzStatus, BlockMechanism, RuntimeState, Backend, CodexModel, ThreadProfileOption, ThreadAgent, SubAgentView, BgShellView, CompletionHoldOp, CompletionHold, AskOption, AskQuestion, PendingAsk, AwaitingHint, RETIRED_AWAITING_KINDS, RETIRED_LINE_RE, AWAITING_FOR_MAX_MS, SnoozeUntil, SNOOZE_PROMPT_MAX, SnoozePrompt, RECURRING_PROMPT_MAX, RECURRING_MIN_INTERVAL_SECONDS, RECURRING_MAX_INTERVAL_SECONDS, RecurringPromptText, RecurringIntervalSeconds, ThreadRecurringPrompt, TIMER_PROMPT_MAX, TIMER_MAX_DELAY_SECONDS, TimerPromptText, SIGNOFF_NUDGE_MARKER, SIGNOFF_NUDGE_MESSAGE, ThreadWatchKind, GithubChecksState, GithubMergeState, GithubWatchStatus, ThreadWatchView, PR_WATCH_FOR_MAX_MS, PR_WATCH_DEFAULT_FOR_MS, PrWatchView, AddOwnPrWatchInput, AddOwnPrWatchResult, DropOwnPrWatchInput, DropOwnPrWatchResult, OwnWatchKind, AddOwnWatchInput, OwnWatchView, AddOwnWatchResult, DropOwnWatchInput, DropOwnWatchResult, AskQuestionKind, AskedOptionSchema, AskedQuestionSchema, AskInput, RegisteredQuestionView, AskResult, UnaskInput, UnaskResult, QuestionAnswerSchema, AnswerQuestionsInput, AnswerQuestionsResult, DismissQuestionsInput, DismissQuestionsResult, MarkOwnDoneInput, MarkOwnDoneResult, ListOwnPrWatchesInput, OwnPrWatchesResult, ThreadTimerView, ThreadFence, LimitWindow, LimitPause, ThreadView, BoardErrorItem, BoardSnapshot, QuotaWindow, ProviderQuota, QuotaSnapshot, ProviderAuth, AccountEmails, AuthSnapshot, AccountLogoutInput, AccountLogoutResult, AccountLoginStartInput, AccountLoginStartResult, AccountLoginStatusInput, AccountLoginStatusResult, PermissionMode, LocalFileOpener, Settings, DispatchProviderPreferences, DispatchPreferences, DispatchProfileSnapshot, SetDispatchPreferenceInput, DispatchInput, ADOPT_THREAD_MESSAGE_MAX_CHARS, AdoptThreadInput, AdoptThreadResult, AdoptSessionInput, FollowUpInput, UnqueueFollowUpInput, UnqueueFollowUpResult, DeliverQueuedNowInput, DeliverQueuedNowResult, SetThreadSnoozeInput, SetThreadPinnedInput, SetThreadRecurringPromptInput, SetOwnThreadRecurringPromptInput, SetOwnThreadRecurringPromptResult, GetOwnThreadRecurringPromptInput, OwnThreadRecurringPromptResult, SetOwnThreadTimerInput, CancelOwnThreadTimerInput, ListOwnThreadTimersInput, OwnThreadTimersResult, ThreadActivityItem, ListOwnThreadActivityInput, OwnThreadActivityResult, SetOwnThreadTimerResult, CancelOwnThreadTimerResult, SetOwnThreadStopHookInput, SetOwnThreadHeartbeatInput, ThreadPluginReloadResult, RenameThreadInput, AiRenameThreadInput, AiRenameThreadResult, SetOwnThreadTitleInput, SetOwnThreadTitleResult, SetThreadPermissionInput, SetThreadPermissionResult, ThreadProfileOptionsInput, ThreadProfileOptionsResult, ThreadSkillSource, ThreadSkill, ThreadSkillsInput, ThreadSkillsResult, SetThreadProfileInput, SetThreadProfileResult, DISPATCH_TASK_BANNER, DISPATCH_TASK_BANNER_MARKER, HUMAN_GAP_FLOOR_MS, GithubWakeItem, GithubWakeSteer, WAKE_SCOPE, WAKE_REF, WAKE_SINGLE, WAKE_MULTI_HEAD, PR_WATCH_FINISHED, PR_WATCH_CI_PASSED, PR_WATCH_CI_FAILED, GithubStatus, GithubRefCard, GithubRefPreviewInput, GithubRefPreviewResult, GithubItem, GithubListInput, GithubListResult, GithubBatchInput, GithubBatchResult, BoardMeta, ServerEvent, TranscriptEdit, TranscriptTodo, TranscriptToolCall, TranscriptPart, TranscriptMessage, TranscriptPageCursor, EditedFile, TranscriptPage, TranscriptEarlierInput, SocketTranscriptSlug, SocketFilePath, SocketTranscriptClientMsg, SocketFileClientMsg, SocketClientMsg, ProjectCard, PROJECT_ICON_MAX_BASE64_CHARS, DirectoryPickResult, ThreadLocation, FRIZZ_ROUTE_PREFIX, DEFAULT_PORT;
|
|
12451
12466
|
var init_src = __esm({
|
|
12452
12467
|
"packages/shared/src/index.ts"() {
|
|
12453
12468
|
"use strict";
|
|
@@ -12464,7 +12479,7 @@ var init_src = __esm({
|
|
|
12464
12479
|
init_relay_protocol();
|
|
12465
12480
|
init_thread_slug();
|
|
12466
12481
|
ATTACHMENT_IMAGE_EXTENSIONS = ["png", "jpg", "jpeg", "gif", "webp"];
|
|
12467
|
-
|
|
12482
|
+
ATTACHMENT_TEXT_EXTENSIONS = [
|
|
12468
12483
|
"pdf",
|
|
12469
12484
|
"svg",
|
|
12470
12485
|
"txt",
|
|
@@ -12476,6 +12491,7 @@ var init_src = __esm({
|
|
|
12476
12491
|
"tsv",
|
|
12477
12492
|
"json",
|
|
12478
12493
|
"jsonl",
|
|
12494
|
+
"ndjson",
|
|
12479
12495
|
"yaml",
|
|
12480
12496
|
"yml",
|
|
12481
12497
|
"toml",
|
|
@@ -12512,6 +12528,38 @@ var init_src = __esm({
|
|
|
12512
12528
|
"lua",
|
|
12513
12529
|
"r"
|
|
12514
12530
|
];
|
|
12531
|
+
ATTACHMENT_OFFICE_EXTENSIONS = [
|
|
12532
|
+
"xlsx",
|
|
12533
|
+
"xlsm",
|
|
12534
|
+
"xls",
|
|
12535
|
+
"docx",
|
|
12536
|
+
"doc",
|
|
12537
|
+
"pptx",
|
|
12538
|
+
"ppt",
|
|
12539
|
+
"odt",
|
|
12540
|
+
"ods",
|
|
12541
|
+
"odp",
|
|
12542
|
+
"rtf",
|
|
12543
|
+
"epub"
|
|
12544
|
+
];
|
|
12545
|
+
ATTACHMENT_DATA_EXTENSIONS = [
|
|
12546
|
+
"parquet",
|
|
12547
|
+
"avro",
|
|
12548
|
+
"orc",
|
|
12549
|
+
"arrow",
|
|
12550
|
+
"feather",
|
|
12551
|
+
"ipynb",
|
|
12552
|
+
"db",
|
|
12553
|
+
"sqlite",
|
|
12554
|
+
"sqlite3"
|
|
12555
|
+
];
|
|
12556
|
+
ATTACHMENT_ARCHIVE_EXTENSIONS = ["zip", "tar", "gz", "tgz", "bz2", "xz", "zst", "7z"];
|
|
12557
|
+
ATTACHMENT_DOC_EXTENSIONS = [
|
|
12558
|
+
...ATTACHMENT_TEXT_EXTENSIONS,
|
|
12559
|
+
...ATTACHMENT_OFFICE_EXTENSIONS,
|
|
12560
|
+
...ATTACHMENT_DATA_EXTENSIONS,
|
|
12561
|
+
...ATTACHMENT_ARCHIVE_EXTENSIONS
|
|
12562
|
+
];
|
|
12515
12563
|
ATTACHMENT_EXTENSIONS = [...ATTACHMENT_IMAGE_EXTENSIONS, ...ATTACHMENT_DOC_EXTENSIONS];
|
|
12516
12564
|
ATTACHMENT_MAX_BASE64_CHARS = 25e6;
|
|
12517
12565
|
ATTACHMENT_MAX_BYTES = Math.floor(ATTACHMENT_MAX_BASE64_CHARS / 4) * 3;
|
|
@@ -12564,17 +12612,25 @@ var init_src = __esm({
|
|
|
12564
12612
|
// clears itself when that work does. Every liveness reading keys on "running", so a rested row holds
|
|
12565
12613
|
// nothing back: it does not block a rest, hold the queue, or gate Mark-as-done.
|
|
12566
12614
|
state: external_exports.enum(["running", "stale", "rested"]),
|
|
12567
|
-
// The worker-profile cell (model+effort)
|
|
12568
|
-
//
|
|
12569
|
-
//
|
|
12570
|
-
//
|
|
12571
|
-
//
|
|
12615
|
+
// The worker-profile cell (model+effort) for the dispatch — RESOLVED, not the raw `subagent_type`:
|
|
12616
|
+
// an effort-only profile carries no model, so the server composes it from the call's own `model` or
|
|
12617
|
+
// the dispatching turn's (server/subagent-profile.ts). It is NO LONGER drawn as a tag on the child
|
|
12618
|
+
// rows under the prompt box (maintainer 2026-07-27: the profile belongs to the prompt box's own
|
|
12619
|
+
// control one line up, not repeated on every child line); the transcript's dispatch card shows it,
|
|
12620
|
+
// the sidebar rail carries it in the row tooltip, and the drill-in passes it to the drawer.
|
|
12621
|
+
// Optional — absent when nothing about the child's runtime is known.
|
|
12572
12622
|
subagentType: external_exports.string().optional(),
|
|
12573
12623
|
// The dispatch tool_use id (the stable correlation key: same id on the Agent tool_use block, the
|
|
12574
12624
|
// completion <task-notification>, and the transcript AgentBlock). Optional — absent on a pre-restart
|
|
12575
12625
|
// server that doesn't emit it yet → the drill-in drawer's entry point is simply not offered. Present
|
|
12576
12626
|
// → the banner row / AgentBlock is clickable and resolves this exact child's transcript.
|
|
12577
12627
|
id: external_exports.string().optional(),
|
|
12628
|
+
// The RUNTIME agent id — the `agentId: a01b2d20b32feab11` line of the Agent tool's launch ack, which
|
|
12629
|
+
// is the only id the MODEL is ever shown for its child (the tool_use id above is invisible to it). So
|
|
12630
|
+
// it is the string a worker writes in an `agents:` fence line or registers a `watch` against, exactly
|
|
12631
|
+
// as BgShellView.taskId is for a shell. Every liveness reading accepts both. Absent for a codex row
|
|
12632
|
+
// and for a Claude row between its tool_use and its launch ack.
|
|
12633
|
+
taskId: external_exports.string().optional(),
|
|
12578
12634
|
// Can frizz actually END this child's work right now? Computed SERVER-side (board.ts, the one place
|
|
12579
12635
|
// holding both the session row and the tailer's telemetry) and never re-derived by a client — the
|
|
12580
12636
|
// same discipline as `steerable`, and for the same reason: the policy depends on the thread's
|
|
@@ -12686,8 +12742,13 @@ var init_src = __esm({
|
|
|
12686
12742
|
subAgentCount: external_exports.number().default(0),
|
|
12687
12743
|
// total live sub-agents (≥ subAgents.length)
|
|
12688
12744
|
bgShells: external_exports.array(CompletionHoldOp).default([]),
|
|
12689
|
-
bgShellCount: external_exports.number().default(0)
|
|
12745
|
+
bgShellCount: external_exports.number().default(0),
|
|
12690
12746
|
// total live background shells (≥ bgShells.length)
|
|
12747
|
+
// The worker is DEAD and its recorded turn never ended — cut off by a reboot, a signal or a crash
|
|
12748
|
+
// mid-tool-call (router.cutOffHold). Nothing is running, so nothing will be killed; the hold exists
|
|
12749
|
+
// because the thread is not finished and Done would say it was. Optional rather than defaulted so it
|
|
12750
|
+
// is absent (⇒ false) on every hold that is not this one, and a pre-change client reads them unchanged.
|
|
12751
|
+
cutOff: external_exports.boolean().optional()
|
|
12691
12752
|
});
|
|
12692
12753
|
AskOption = external_exports.object({
|
|
12693
12754
|
label: external_exports.string(),
|
|
@@ -12852,7 +12913,8 @@ var init_src = __esm({
|
|
|
12852
12913
|
* known, so a timer row always carries this. */
|
|
12853
12914
|
timer: external_exports.object({ fireAt: external_exports.string(), prompt: external_exports.string() }).strict().optional()
|
|
12854
12915
|
}).strict();
|
|
12855
|
-
|
|
12916
|
+
PR_WATCH_FOR_MAX_MS = 365 * 24 * 60 * 60 * 1e3;
|
|
12917
|
+
PR_WATCH_DEFAULT_FOR_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
12856
12918
|
PrWatchView = external_exports.object({
|
|
12857
12919
|
id: external_exports.string(),
|
|
12858
12920
|
/** `owner/repo#N`, normalized — the same string the board's row and the status book are keyed by. */
|
|
@@ -12867,13 +12929,18 @@ var init_src = __esm({
|
|
|
12867
12929
|
/** `owner/repo#123` or a PR URL. Parsed server-side; an unparseable ref is refused rather than stored,
|
|
12868
12930
|
* because a watcher that can never fire is worse than none — the worker rests believing it is covered. */
|
|
12869
12931
|
target: external_exports.string().trim().min(1).max(200),
|
|
12870
|
-
/** How long to watch, as a DURATION (`
|
|
12932
|
+
/** How long to watch, as a DURATION (`2h`, `3d`, `180d` — parseAwaitingDurationRaw, capped at
|
|
12933
|
+
* PR_WATCH_FOR_MAX_MS).
|
|
12871
12934
|
*
|
|
12872
12935
|
* A PR nobody ever reviews would otherwise be polled forever, and a thread parked on it would wait
|
|
12873
12936
|
* forever with it — the same unbounded wait the awaiting fence's `for:` closes, one level down. A
|
|
12874
12937
|
* duration rather than an instant for the same reason it is one there: it cannot be written in the
|
|
12875
12938
|
* past (maintainer 2026-08-15, asking for it explicitly).
|
|
12876
12939
|
*
|
|
12940
|
+
* BOUNDED IS NOT THE SAME AS SHORT, and conflating them is what made this field a noise source. The
|
|
12941
|
+
* bound exists so a forgotten watcher stops polling eventually, which a year satisfies exactly as
|
|
12942
|
+
* well as a day — and a day spent it against every external PR, which does not move on that clock.
|
|
12943
|
+
*
|
|
12877
12944
|
* REQUIRED BY THE TOOL, OPTIONAL ON THE WIRE, and the asymmetry is deliberate. A worker's MCP server
|
|
12878
12945
|
* outlives every frizz restart, so a session dispatched before this existed still holds a binary that
|
|
12879
12946
|
* cannot send it — and making the RPC reject that would break `watch_pr` outright for every thread
|
|
@@ -12888,6 +12955,12 @@ var init_src = __esm({
|
|
|
12888
12955
|
/** True when this exact PR was ALREADY watched by this thread, so the call registered nothing new.
|
|
12889
12956
|
* Re-registering after a compaction is the common case, and a duplicate would double every wake. */
|
|
12890
12957
|
alreadyArmed: external_exports.boolean(),
|
|
12958
|
+
/** When this watcher runs out. Read back so the worker sees the duration it ACTUALLY got rather than
|
|
12959
|
+
* the one it asked for — on a re-registration that is the original expiry, which the call left alone. */
|
|
12960
|
+
expiresAt: external_exports.string(),
|
|
12961
|
+
/** The `for:` the worker wrote, present ONLY when it exceeded the ceiling and was capped. A clamp
|
|
12962
|
+
* nobody is told about is a worker resting on a year of coverage it does not have. */
|
|
12963
|
+
clampedFrom: external_exports.string().optional(),
|
|
12891
12964
|
watches: external_exports.array(PrWatchView)
|
|
12892
12965
|
}).strict();
|
|
12893
12966
|
DropOwnPrWatchInput = external_exports.object({
|
|
@@ -12898,6 +12971,160 @@ var init_src = __esm({
|
|
|
12898
12971
|
dropped: external_exports.boolean(),
|
|
12899
12972
|
watches: external_exports.array(PrWatchView)
|
|
12900
12973
|
}).strict();
|
|
12974
|
+
OwnWatchKind = external_exports.enum(["shell", "agent"]);
|
|
12975
|
+
AddOwnWatchInput = external_exports.object({
|
|
12976
|
+
slug: ThreadSlug,
|
|
12977
|
+
/** What KIND of thing the target is. Stored, and checked against the thread's live telemetry before the
|
|
12978
|
+
* row is written — see the note on `target`. */
|
|
12979
|
+
kind: OwnWatchKind,
|
|
12980
|
+
/** The handle the worker was shown: a runtime task id ("Command running in background with ID: …"), a
|
|
12981
|
+
* launch tool_use id, or the op's own label.
|
|
12982
|
+
*
|
|
12983
|
+
* VALIDATED AGAINST LIVE TELEMETRY, NOT AGAINST ITS SHAPE. A PR ref is checkable by shape because
|
|
12984
|
+
* `owner/repo#123` looks like nothing else; a shell handle and a sub-agent handle are both opaque
|
|
12985
|
+
* runtime strings and overlap completely, so shape can only ever be a guess. What frizz CAN answer
|
|
12986
|
+
* exactly is whether this thread has a live shell — or a live sub-agent — answering to this handle, and
|
|
12987
|
+
* that is both the stronger check and the one that catches the real mistake: naming a sub-agent under
|
|
12988
|
+
* `kind: "shell"`, which is what put two sub-agents under a "Background shells" heading on 2026-08-26. */
|
|
12989
|
+
target: external_exports.string().trim().min(1).max(200),
|
|
12990
|
+
/** REQUIRED, and a DURATION (`30m`, `2h`, `3d` — parseAwaitingDurationRaw, capped at 24h).
|
|
12991
|
+
*
|
|
12992
|
+
* STILL A DAY, where a PR watcher now gets a year: this names a shell or a sub-agent, which lives
|
|
12993
|
+
* inside the session that launched it, so a wait standing longer than a day is one whose target is
|
|
12994
|
+
* almost certainly already gone.
|
|
12995
|
+
*
|
|
12996
|
+
* No default and no wire-level optionality, unlike `AddOwnPrWatchInput.for`: that field is optional
|
|
12997
|
+
* only to keep working for sessions dispatched before it existed, and this RPC has no such sessions.
|
|
12998
|
+
* On elapse the row is CANCELLED and the thread woken to re-decide, which is what stops a registration
|
|
12999
|
+
* outliving its own relevance — the one thing an un-restated fence could never do wrong. */
|
|
13000
|
+
for: external_exports.string().trim().min(1).max(16)
|
|
13001
|
+
}).strict();
|
|
13002
|
+
OwnWatchView = external_exports.object({
|
|
13003
|
+
id: external_exports.string(),
|
|
13004
|
+
kind: OwnWatchKind,
|
|
13005
|
+
target: external_exports.string(),
|
|
13006
|
+
/** The op's own label where the target resolved to one, so a read-back names the work rather than an
|
|
13007
|
+
* opaque handle. Absent when the target no longer resolves — the row still stands and names itself. */
|
|
13008
|
+
label: external_exports.string().optional(),
|
|
13009
|
+
createdAt: external_exports.string(),
|
|
13010
|
+
expiresAt: external_exports.string()
|
|
13011
|
+
}).strict();
|
|
13012
|
+
AddOwnWatchResult = external_exports.object({
|
|
13013
|
+
id: external_exports.string(),
|
|
13014
|
+
kind: OwnWatchKind,
|
|
13015
|
+
target: external_exports.string(),
|
|
13016
|
+
/** True when this exact (kind, target) was already watched, so the call registered nothing new and the
|
|
13017
|
+
* existing expiry stands. Re-registering after a wake or a compaction is the common, correct case. */
|
|
13018
|
+
alreadyArmed: external_exports.boolean(),
|
|
13019
|
+
/** The `for:` the worker wrote, present ONLY when it exceeded the ceiling and was capped — the twin of
|
|
13020
|
+
* `AddOwnPrWatchResult.clampedFrom`, for the same reason: a silent clamp is a worker resting on
|
|
13021
|
+
* coverage it does not have. */
|
|
13022
|
+
clampedFrom: external_exports.string().optional(),
|
|
13023
|
+
watches: external_exports.array(OwnWatchView)
|
|
13024
|
+
}).strict();
|
|
13025
|
+
DropOwnWatchInput = external_exports.object({
|
|
13026
|
+
slug: ThreadSlug,
|
|
13027
|
+
id: external_exports.string().min(1).max(64)
|
|
13028
|
+
}).strict();
|
|
13029
|
+
DropOwnWatchResult = external_exports.object({
|
|
13030
|
+
dropped: external_exports.boolean(),
|
|
13031
|
+
watches: external_exports.array(OwnWatchView)
|
|
13032
|
+
}).strict();
|
|
13033
|
+
AskQuestionKind = external_exports.enum(["question", "multi"]);
|
|
13034
|
+
AskedOptionSchema = external_exports.lazy(() => external_exports.object({
|
|
13035
|
+
// 400, not the 120 it launched with (2026-09-03): a label is a chip line, but "Post the drafted
|
|
13036
|
+
// comment as written" plus its qualifier runs long, and the fence has no cap at all. The answer's
|
|
13037
|
+
// `chosen` carries labels, so its per-item cap matches this one.
|
|
13038
|
+
label: external_exports.string().trim().min(1).max(400),
|
|
13039
|
+
// 20000, not the 4000 the retired `preview` had (2026-09-03): a description is allowed to BE the rich
|
|
13040
|
+
// body — a diff, a drafted comment, a table — and a real diff exceeds 4000.
|
|
13041
|
+
description: external_exports.string().trim().max(2e4).optional(),
|
|
13042
|
+
recommended: external_exports.boolean().optional(),
|
|
13043
|
+
preview: external_exports.string().max(4e3).optional(),
|
|
13044
|
+
// No count cap, like `options` (2026-09-03); the tree is bounded by ASK_MAX_DEPTH instead.
|
|
13045
|
+
followUps: external_exports.array(AskedQuestionSchema).optional()
|
|
13046
|
+
}).strict());
|
|
13047
|
+
AskedQuestionSchema = external_exports.lazy(() => external_exports.object({
|
|
13048
|
+
// 4000, not the 600 it launched with (2026-09-03): this field is the whole card context — everything
|
|
13049
|
+
// the human needs to answer cold — and a question that carries its own evidence needs the room. The
|
|
13050
|
+
// answer restates it, so QuestionAnswerSchema's cap matches.
|
|
13051
|
+
question: external_exports.string().trim().min(1).max(4e3),
|
|
13052
|
+
header: external_exports.string().trim().max(24).optional(),
|
|
13053
|
+
kind: AskQuestionKind,
|
|
13054
|
+
danger: external_exports.boolean().optional(),
|
|
13055
|
+
// UNBOUNDED, deliberately. This carried `.max(8)` from launch until 2026-09-03, when the maintainer
|
|
13056
|
+
// asked for the cap to go ("allow arbitrary numbers of options"): a `multi` over a long list — which
|
|
13057
|
+
// gates to run, which of twenty findings to act on — is a real shape, and the card letters past 26
|
|
13058
|
+
// (`AA.`) already. The count is the worker's to choose; the answer's `chosen` is unbounded to match.
|
|
13059
|
+
options: external_exports.array(AskedOptionSchema).optional()
|
|
13060
|
+
}).strict());
|
|
13061
|
+
AskInput = external_exports.object({
|
|
13062
|
+
slug: ThreadSlug,
|
|
13063
|
+
// No cap on the count (four until 2026-09-03): the tool's own text says "several at once is one
|
|
13064
|
+
// call — register them together", and a cap here told a worker with six to batch and then refused it.
|
|
13065
|
+
questions: external_exports.array(AskedQuestionSchema).min(1)
|
|
13066
|
+
}).strict();
|
|
13067
|
+
RegisteredQuestionView = external_exports.object({
|
|
13068
|
+
/** Minted by frizz. The worker never chose it, which is why an answer RESTATES the question text —
|
|
13069
|
+
* an id alone cannot be correlated back to what was asked. */
|
|
13070
|
+
id: external_exports.string(),
|
|
13071
|
+
spec: AskedQuestionSchema,
|
|
13072
|
+
askedAt: external_exports.string()
|
|
13073
|
+
}).strict();
|
|
13074
|
+
AskResult = external_exports.object({
|
|
13075
|
+
registered: external_exports.array(RegisteredQuestionView),
|
|
13076
|
+
/** Everything still open on this thread afterwards, so a worker never needs a second call. */
|
|
13077
|
+
open: external_exports.array(RegisteredQuestionView)
|
|
13078
|
+
}).strict();
|
|
13079
|
+
UnaskInput = external_exports.object({
|
|
13080
|
+
slug: ThreadSlug,
|
|
13081
|
+
id: external_exports.string().min(1).max(64)
|
|
13082
|
+
}).strict();
|
|
13083
|
+
UnaskResult = external_exports.object({
|
|
13084
|
+
withdrawn: external_exports.boolean(),
|
|
13085
|
+
open: external_exports.array(RegisteredQuestionView)
|
|
13086
|
+
}).strict();
|
|
13087
|
+
QuestionAnswerSchema = external_exports.lazy(() => external_exports.object({
|
|
13088
|
+
questionId: external_exports.string().min(1).max(64),
|
|
13089
|
+
question: external_exports.string().min(1).max(4e3),
|
|
13090
|
+
// No count cap: a `multi` may carry any number of options (see AskedQuestionSchema), and the human
|
|
13091
|
+
// may pick every one of them. The per-item cap is the option label's.
|
|
13092
|
+
chosen: external_exports.array(external_exports.string().max(400)),
|
|
13093
|
+
text: external_exports.string().max(8e3).optional(),
|
|
13094
|
+
followUps: external_exports.array(QuestionAnswerSchema).optional()
|
|
13095
|
+
}).strict());
|
|
13096
|
+
AnswerQuestionsInput = external_exports.object({
|
|
13097
|
+
slug: ThreadSlug,
|
|
13098
|
+
/** SUBMITTED AS A UNIT. The card sends whatever was answered in one call, because a per-question send
|
|
13099
|
+
* would half-wake a turn: the worker would come back to a payload it cannot act on and would have to
|
|
13100
|
+
* ask again for the rest. */
|
|
13101
|
+
answers: external_exports.array(QuestionAnswerSchema).min(1)
|
|
13102
|
+
}).strict();
|
|
13103
|
+
AnswerQuestionsResult = external_exports.object({
|
|
13104
|
+
/** The ids that were open and are now answered. An id that was already settled is silently absent
|
|
13105
|
+
* rather than an error: two browser tabs answering the same card is a race nobody should see. */
|
|
13106
|
+
answered: external_exports.array(external_exports.string()),
|
|
13107
|
+
open: external_exports.array(RegisteredQuestionView)
|
|
13108
|
+
}).strict();
|
|
13109
|
+
DismissQuestionsInput = external_exports.object({
|
|
13110
|
+
slug: ThreadSlug,
|
|
13111
|
+
ids: external_exports.array(external_exports.string().min(1).max(64)).min(1)
|
|
13112
|
+
}).strict();
|
|
13113
|
+
DismissQuestionsResult = external_exports.object({
|
|
13114
|
+
dismissed: external_exports.array(external_exports.string()),
|
|
13115
|
+
open: external_exports.array(RegisteredQuestionView)
|
|
13116
|
+
}).strict();
|
|
13117
|
+
MarkOwnDoneInput = external_exports.object({
|
|
13118
|
+
slug: ThreadSlug,
|
|
13119
|
+
body: external_exports.string().trim().min(1).max(2e4)
|
|
13120
|
+
}).strict();
|
|
13121
|
+
MarkOwnDoneResult = external_exports.object({
|
|
13122
|
+
done: external_exports.boolean(),
|
|
13123
|
+
/** Open questions, by id and question text. */
|
|
13124
|
+
blockingQuestions: external_exports.array(external_exports.object({ id: external_exports.string(), question: external_exports.string() }).strict()),
|
|
13125
|
+
/** Armed registrations, by id and what each names. Watches, PR watchers and timers alike. */
|
|
13126
|
+
blockingWatches: external_exports.array(external_exports.object({ id: external_exports.string(), what: external_exports.string() }).strict())
|
|
13127
|
+
}).strict();
|
|
12901
13128
|
ListOwnPrWatchesInput = external_exports.object({ slug: ThreadSlug }).strict();
|
|
12902
13129
|
OwnPrWatchesResult = external_exports.object({ watches: external_exports.array(PrWatchView) }).strict();
|
|
12903
13130
|
ThreadTimerView = external_exports.object({
|
|
@@ -12912,9 +13139,15 @@ var init_src = __esm({
|
|
|
12912
13139
|
kind: external_exports.enum(["done", "awaiting"]),
|
|
12913
13140
|
body: external_exports.string(),
|
|
12914
13141
|
// fence body minus hint lines, capped server-side; may be ""
|
|
12915
|
-
hints: external_exports.array(AwaitingHint).default([])
|
|
13142
|
+
hints: external_exports.array(AwaitingHint).default([]),
|
|
13143
|
+
// Present only on a completion the worker REGISTERED (`mcp__frizz__done`, board.registeredDoneFence)
|
|
13144
|
+
// rather than wrote as a ```done fence in its final message. The two are one fence to every predicate,
|
|
13145
|
+
// but the TRANSCRIPT draws a fence card from the message text it parses — so a registered done, which
|
|
13146
|
+
// is in no message, needs the client to know it must draw the card itself at the bottom of the thread
|
|
13147
|
+
// (maintainer 2026-08-27: a thread that signed off by tool rested with no card at all).
|
|
13148
|
+
registered: external_exports.literal(true).optional()
|
|
12916
13149
|
});
|
|
12917
|
-
LimitWindow = external_exports.enum(["session", "weekly", "unknown"]);
|
|
13150
|
+
LimitWindow = external_exports.enum(["session", "weekly", "model", "unknown"]);
|
|
12918
13151
|
LimitPause = external_exports.object({
|
|
12919
13152
|
backend: Backend,
|
|
12920
13153
|
window: LimitWindow,
|
|
@@ -13008,6 +13241,18 @@ var init_src = __esm({
|
|
|
13008
13241
|
// Derived safety net (tailer): at rest with an unanswered ```question the worker asked in chat but
|
|
13009
13242
|
// never encoded as blocked. Defaults false so old snapshots/rows parse. Feeds needsAction.
|
|
13010
13243
|
pendingQuestion: external_exports.boolean().default(false),
|
|
13244
|
+
// The worker's REGISTERED questions, still open (thread_question). Distinct from `pendingQuestion`
|
|
13245
|
+
// beside it, and the difference is the whole point of the registry: that boolean is recomputed from
|
|
13246
|
+
// the LATEST assistant text on every assistant record and cleared by any human turn, so it cannot
|
|
13247
|
+
// outlive the message that carried it. These rows can, and they carry the question itself rather than
|
|
13248
|
+
// merely asserting one exists — the card renders from this instead of re-parsing prose.
|
|
13249
|
+
questions: external_exports.array(RegisteredQuestionView).default([]),
|
|
13250
|
+
/** The answer the human has already SENT that the worker has not received yet, as the exact message
|
|
13251
|
+
* the delivery will carry (board.answersInFlight → questionAnswerMessage). The chat parses it with
|
|
13252
|
+
* the same reader it uses on the delivered turn, so the in-flight card and the landed one are the
|
|
13253
|
+
* same card and the swap is invisible. Absent whenever there is nothing in flight, which is almost
|
|
13254
|
+
* always — it exists for the seconds between the human sending and the worker being handed it. */
|
|
13255
|
+
answersInFlight: external_exports.string().optional(),
|
|
13011
13256
|
// ISO8601 of the newest REAL user interaction (answer/steer/dispatch) — the chronological listing
|
|
13012
13257
|
// sort key. Optional; the listing falls back to spawnedAt when absent (a dispatch IS an interaction).
|
|
13013
13258
|
lastUserAt: external_exports.string().optional(),
|
|
@@ -13043,6 +13288,11 @@ var init_src = __esm({
|
|
|
13043
13288
|
// AUTO-bump (the scheduler resumes the agent with exactly this text) rather than a reminder, which is
|
|
13044
13289
|
// the distinction the held row's tooltip renders. Absent ⇒ the card merely re-surfaces.
|
|
13045
13290
|
snoozePrompt: external_exports.string().optional(),
|
|
13291
|
+
// The instant the human PINNED this thread (absent = not pinned). A pinned thread leaves the rail's
|
|
13292
|
+
// band system entirely — Rested/Active/Snoozed/Done — and holds the pinned band at the very top, in
|
|
13293
|
+
// this instant's order. Lifecycle metadata like the snooze: written only by the pin/unpin verb, and
|
|
13294
|
+
// it outranks every derived state (a pinned thread that finishes stays pinned).
|
|
13295
|
+
pinnedAt: external_exports.string().optional(),
|
|
13046
13296
|
/** The EVENT snooze on the resting card is armed for this exact rest — the human has said "hide this
|
|
13047
13297
|
* until something reports". Distinct from `snoozedUntil`, which is a wall-clock park on the whole
|
|
13048
13298
|
* thread: this one has no deadline and clears itself when the thread comes to a NEW rest.
|
|
@@ -13193,7 +13443,7 @@ var init_src = __esm({
|
|
|
13193
13443
|
key: external_exports.string(),
|
|
13194
13444
|
// stable id: "5h" | "weekly" (provider-neutral)
|
|
13195
13445
|
label: external_exports.string(),
|
|
13196
|
-
// short human label for the chip ("5h", "Weekly")
|
|
13446
|
+
// short human label for the chip ("5h", "Weekly") — house duration grammar
|
|
13197
13447
|
usedPercent: external_exports.number(),
|
|
13198
13448
|
// 0..100
|
|
13199
13449
|
resetsAt: external_exports.number().optional()
|
|
@@ -13288,6 +13538,12 @@ var init_src = __esm({
|
|
|
13288
13538
|
// Code caps to the model's real window. Optional so an old blob parses; defaultSettings pins 500_000
|
|
13289
13539
|
// (maintainer 2026-08-26: "a default compaction window of 500k by default").
|
|
13290
13540
|
autoCompactWindow: external_exports.number().int().positive().optional(),
|
|
13541
|
+
// The prompt-cache tier a NEW Claude worker writes to. "auto" leaves the CLI's own choice (1h on a
|
|
13542
|
+
// subscription); "5m" and "1h" reach the worker as CLAUDE_CODE_PROMPT_CACHE_TTL (and the sub-agent
|
|
13543
|
+
// twin). The 1h tier bills a cache write at 2x input against 1.25x for 5m; on 2026-09-03 cache
|
|
13544
|
+
// writes were 51% of a day's spend while the entries were invalidated every 15–30 minutes anyway
|
|
13545
|
+
// (see claudePromptCacheEnv). Optional so an old blob parses; defaultSettings pins "auto".
|
|
13546
|
+
promptCacheTtl: external_exports.enum(["auto", "5m", "1h"]).optional(),
|
|
13291
13547
|
// The GitHub batch-dispatch prompt template (the picker's per-item worker prompt). Optional: when
|
|
13292
13548
|
// unset OR blank the server falls back to its exported DEFAULT_GITHUB_PROMPT. Substitution tokens
|
|
13293
13549
|
// the server fills: {repo} {n} {title} {url} {labels} {body}. The leading `THREAD: <slug>` tag is
|
|
@@ -13426,6 +13682,11 @@ var init_src = __esm({
|
|
|
13426
13682
|
// can never leave an armed prompt behind.
|
|
13427
13683
|
prompt: SnoozePrompt.nullable().optional()
|
|
13428
13684
|
}).strict();
|
|
13685
|
+
SetThreadPinnedInput = external_exports.object({
|
|
13686
|
+
slug: ThreadSlug,
|
|
13687
|
+
sessionId: external_exports.string().min(1),
|
|
13688
|
+
pinned: external_exports.boolean()
|
|
13689
|
+
}).strict();
|
|
13429
13690
|
SetThreadRecurringPromptInput = external_exports.object({
|
|
13430
13691
|
slug: ThreadSlug,
|
|
13431
13692
|
sessionId: external_exports.string().min(1),
|
|
@@ -13490,13 +13751,25 @@ var init_src = __esm({
|
|
|
13490
13751
|
/** ISO8601 of when it started or was armed — absent when frizz has no instant for it. */
|
|
13491
13752
|
since: external_exports.string().optional(),
|
|
13492
13753
|
/** A timer's fire instant, or a PR's expiry. Absent for shells and sub-agents. */
|
|
13493
|
-
until: external_exports.string().optional()
|
|
13754
|
+
until: external_exports.string().optional(),
|
|
13755
|
+
/** The `wch_…` id of the REGISTERED WATCH holding this item, when the worker armed one — so a readout
|
|
13756
|
+
* that exists to hand ids back also hands back the one `unwatch` takes. A separate ROW per watch was
|
|
13757
|
+
* the alternative and it would list the same shell twice, which is exactly the duplication that put
|
|
13758
|
+
* two sub-agents under a "Background shells" heading. */
|
|
13759
|
+
watchId: external_exports.string().optional()
|
|
13494
13760
|
}).strict();
|
|
13495
13761
|
ListOwnThreadActivityInput = external_exports.object({
|
|
13496
13762
|
slug: ThreadSlug
|
|
13497
13763
|
}).strict();
|
|
13498
13764
|
OwnThreadActivityResult = external_exports.object({
|
|
13499
|
-
activity: external_exports.array(ThreadActivityItem)
|
|
13765
|
+
activity: external_exports.array(ThreadActivityItem),
|
|
13766
|
+
/** Every question still owed an answer. NOT a `ThreadActivityItem` and deliberately its own list: a
|
|
13767
|
+
* question is not running work, it waits on a PERSON, and there is no `questions:` key in the awaiting
|
|
13768
|
+
* fence for it to be written into. Until 2026-08-28 a worker could read its open questions back only
|
|
13769
|
+
* as a side effect of `ask` (which registers another) or `unask` (which withdraws one) — so the ids
|
|
13770
|
+
* that block `done` were readable only by mutating something (maintainer: "Is there a way for the
|
|
13771
|
+
* agent to read out the current set of watchers and questions?"). */
|
|
13772
|
+
questions: external_exports.array(RegisteredQuestionView).default([])
|
|
13500
13773
|
}).strict();
|
|
13501
13774
|
SetOwnThreadTimerResult = external_exports.object({
|
|
13502
13775
|
id: external_exports.string(),
|
|
@@ -13531,6 +13804,15 @@ var init_src = __esm({
|
|
|
13531
13804
|
});
|
|
13532
13805
|
AiRenameThreadInput = external_exports.object({ slug: ThreadSlug });
|
|
13533
13806
|
AiRenameThreadResult = external_exports.object({ title: external_exports.string().min(1).max(200) });
|
|
13807
|
+
SetOwnThreadTitleInput = external_exports.object({
|
|
13808
|
+
slug: ThreadSlug,
|
|
13809
|
+
title: external_exports.string().trim().min(1).max(200)
|
|
13810
|
+
}).strict();
|
|
13811
|
+
SetOwnThreadTitleResult = external_exports.object({
|
|
13812
|
+
accepted: external_exports.boolean(),
|
|
13813
|
+
title: external_exports.string(),
|
|
13814
|
+
lockedByHuman: external_exports.boolean()
|
|
13815
|
+
}).strict();
|
|
13534
13816
|
SetThreadPermissionInput = external_exports.object({
|
|
13535
13817
|
slug: ThreadSlug,
|
|
13536
13818
|
permissionMode: PermissionMode
|
|
@@ -13757,7 +14039,11 @@ ${DISPATCH_TASK_BANNER}
|
|
|
13757
14039
|
TranscriptEdit = external_exports.object({
|
|
13758
14040
|
file: external_exports.string(),
|
|
13759
14041
|
old: external_exports.string(),
|
|
13760
|
-
new: external_exports.string()
|
|
14042
|
+
new: external_exports.string(),
|
|
14043
|
+
// Line counts of the UNCAPPED sides, taken at projection time — `old`/`new` above are capped for
|
|
14044
|
+
// transport, so a diffstat recomputed from them undercounts any large edit.
|
|
14045
|
+
added: external_exports.number().int().nonnegative().optional(),
|
|
14046
|
+
removed: external_exports.number().int().nonnegative().optional()
|
|
13761
14047
|
});
|
|
13762
14048
|
TranscriptTodo = external_exports.object({
|
|
13763
14049
|
text: external_exports.string(),
|
|
@@ -13829,8 +14115,10 @@ ${DISPATCH_TASK_BANNER}
|
|
|
13829
14115
|
// optional so a pre-restart server / older transcript falls back to the plain `Agent(detail)` line.
|
|
13830
14116
|
prompt: external_exports.string().optional(),
|
|
13831
14117
|
// the capped dispatch prompt (the AgentBlock's expanded body)
|
|
14118
|
+
// The RESOLVED model+effort cell (e.g. "frizz:opus-high"), not `subagent_type` verbatim: a modern
|
|
14119
|
+
// profile is effort-only, so the server folds the call's `model` — or, when omitted, the model the
|
|
14120
|
+
// dispatching turn itself ran at — back into the cell. See server/subagent-profile.ts.
|
|
13832
14121
|
subagentType: external_exports.string().optional(),
|
|
13833
|
-
// the dispatch's subagent_type verbatim (e.g. "frizz:frizz-opus-high")
|
|
13834
14122
|
agentId: external_exports.string().optional(),
|
|
13835
14123
|
// the Agent tool_use id — the correlation key to the live tracked sub-agent
|
|
13836
14124
|
// Terminal outcome of the dispatched sub-agent, back-filled when a matching completion
|
|
@@ -13892,7 +14180,19 @@ ${DISPATCH_TASK_BANNER}
|
|
|
13892
14180
|
// The whole to-do list, for the calls that carry it (see TranscriptTodo). The client promotes such a
|
|
13893
14181
|
// call into a TodoBlock — a checklist card, one row per task with its status. Optional, so a
|
|
13894
14182
|
// pre-restart server / older transcript falls back to the generic card.
|
|
13895
|
-
todos: external_exports.array(TranscriptTodo).optional()
|
|
14183
|
+
todos: external_exports.array(TranscriptTodo).optional(),
|
|
14184
|
+
// ---- Native question (AskUserQuestion) block ----
|
|
14185
|
+
// The structured questions an `AskUserQuestion` tool_use asked, so a SETTLED call renders as a
|
|
14186
|
+
// read-only question card at its place in the transcript instead of a generic tool line buried in a
|
|
14187
|
+
// disclosure. This is what keeps a question the human saw from vanishing: a follow-up sent instead
|
|
14188
|
+
// of an answer retires the pending interaction card (the broker denies the parked call), and without
|
|
14189
|
+
// this field nothing in the transcript ever said what was asked. Optional, so a pre-restart server /
|
|
14190
|
+
// older transcript falls back to the generic card.
|
|
14191
|
+
ask: external_exports.array(AskQuestion).optional(),
|
|
14192
|
+
// The human's answers, parallel to `ask` (null = that question got no answer), parsed from the
|
|
14193
|
+
// call's structured tool result. Absent entirely when the call settled unanswered — the withdrawn /
|
|
14194
|
+
// denied case — which the client renders as "Not answered".
|
|
14195
|
+
askAnswers: external_exports.array(external_exports.string().nullable()).optional()
|
|
13896
14196
|
});
|
|
13897
14197
|
TranscriptPart = external_exports.discriminatedUnion("kind", [
|
|
13898
14198
|
external_exports.object({ kind: external_exports.literal("text"), text: external_exports.string() }),
|
|
@@ -14044,22 +14344,39 @@ ${DISPATCH_TASK_BANNER}
|
|
|
14044
14344
|
fenceRefused: external_exports.literal(true).optional()
|
|
14045
14345
|
});
|
|
14046
14346
|
TranscriptPageCursor = external_exports.string().min(1).max(2048).regex(/^[A-Za-z0-9_-]+$/);
|
|
14347
|
+
EditedFile = external_exports.object({
|
|
14348
|
+
path: external_exports.string().min(1),
|
|
14349
|
+
edits: external_exports.number().int().positive(),
|
|
14350
|
+
lastEditedAt: external_exports.string().optional(),
|
|
14351
|
+
// The file's diffstat, summed over its write calls (each call's counts are the line counts of its
|
|
14352
|
+
// raw old/new sides). A Write counts as all additions — what it replaced is unknowable here.
|
|
14353
|
+
added: external_exports.number().int().nonnegative().optional(),
|
|
14354
|
+
removed: external_exports.number().int().nonnegative().optional()
|
|
14355
|
+
}).strict();
|
|
14047
14356
|
TranscriptPage = external_exports.object({
|
|
14048
14357
|
messages: external_exports.array(TranscriptMessage),
|
|
14049
14358
|
beforeCursor: TranscriptPageCursor.nullable(),
|
|
14050
14359
|
hasEarlier: external_exports.boolean(),
|
|
14051
14360
|
reachedTurnBoundary: external_exports.boolean(),
|
|
14052
|
-
transcriptKey: external_exports.string().min(1).max(256)
|
|
14361
|
+
transcriptKey: external_exports.string().min(1).max(256),
|
|
14362
|
+
// The LATEST page only (see EditedFile); an earlier page is settled history and carries none.
|
|
14363
|
+
editedFiles: external_exports.array(EditedFile).optional()
|
|
14053
14364
|
}).strict();
|
|
14054
14365
|
TranscriptEarlierInput = external_exports.object({
|
|
14055
14366
|
slug: ThreadSlug,
|
|
14056
14367
|
cursor: TranscriptPageCursor
|
|
14057
14368
|
}).strict();
|
|
14058
14369
|
SocketTranscriptSlug = ThreadSlug;
|
|
14059
|
-
|
|
14370
|
+
SocketFilePath = external_exports.string().min(1).max(4096);
|
|
14371
|
+
SocketTranscriptClientMsg = external_exports.discriminatedUnion("t", [
|
|
14060
14372
|
external_exports.object({ t: external_exports.literal("sub"), topic: external_exports.literal("transcript"), slug: SocketTranscriptSlug }).strict(),
|
|
14061
14373
|
external_exports.object({ t: external_exports.literal("unsub"), topic: external_exports.literal("transcript"), slug: SocketTranscriptSlug }).strict()
|
|
14062
14374
|
]);
|
|
14375
|
+
SocketFileClientMsg = external_exports.discriminatedUnion("t", [
|
|
14376
|
+
external_exports.object({ t: external_exports.literal("sub"), topic: external_exports.literal("file"), path: SocketFilePath }).strict(),
|
|
14377
|
+
external_exports.object({ t: external_exports.literal("unsub"), topic: external_exports.literal("file"), path: SocketFilePath }).strict()
|
|
14378
|
+
]);
|
|
14379
|
+
SocketClientMsg = external_exports.union([SocketTranscriptClientMsg, SocketFileClientMsg]);
|
|
14063
14380
|
ProjectCard = external_exports.object({
|
|
14064
14381
|
id: external_exports.string(),
|
|
14065
14382
|
slug: external_exports.string(),
|
|
@@ -14112,6 +14429,85 @@ ${DISPATCH_TASK_BANNER}
|
|
|
14112
14429
|
}
|
|
14113
14430
|
});
|
|
14114
14431
|
|
|
14432
|
+
// packages/server/src/frizz-paths.ts
|
|
14433
|
+
import { existsSync } from "node:fs";
|
|
14434
|
+
import { homedir as homedir2, tmpdir } from "node:os";
|
|
14435
|
+
import { dirname as dirname2, isAbsolute as isAbsolute2, join as join3, relative, resolve, sep as sep2 } from "node:path";
|
|
14436
|
+
function legacyFrizzRoot(home = homedir2()) {
|
|
14437
|
+
return join3(home, LEGACY_DIR_NAME);
|
|
14438
|
+
}
|
|
14439
|
+
function xdg(env, name) {
|
|
14440
|
+
const value = env[name];
|
|
14441
|
+
return value && (value.startsWith("/") || /^[A-Za-z]:[\\/]/u.test(value)) ? value : void 0;
|
|
14442
|
+
}
|
|
14443
|
+
function insideHome(child, home) {
|
|
14444
|
+
const norm = (value) => value.replace(/[\\/]+$/u, "").replaceAll("\\", "/").toLowerCase();
|
|
14445
|
+
const parent = norm(home);
|
|
14446
|
+
const inner = norm(child);
|
|
14447
|
+
return inner === parent || inner.startsWith(`${parent}/`);
|
|
14448
|
+
}
|
|
14449
|
+
function windowsRoots(env, home) {
|
|
14450
|
+
const local = env.LOCALAPPDATA && insideHome(env.LOCALAPPDATA, home) ? env.LOCALAPPDATA : join3(home, "AppData", "Local");
|
|
14451
|
+
const base = join3(local, "Frizz");
|
|
14452
|
+
return {
|
|
14453
|
+
data: join3(base, "Data"),
|
|
14454
|
+
state: join3(base, "State"),
|
|
14455
|
+
cache: join3(base, "Cache")
|
|
14456
|
+
};
|
|
14457
|
+
}
|
|
14458
|
+
function darwinRoots(home) {
|
|
14459
|
+
const support = join3(home, "Library", "Application Support", "Frizz");
|
|
14460
|
+
return {
|
|
14461
|
+
data: support,
|
|
14462
|
+
// macOS has no state directory concept; Application Support is where this belongs, and the log
|
|
14463
|
+
// files themselves already live under each project's own directory.
|
|
14464
|
+
state: support,
|
|
14465
|
+
cache: join3(home, "Library", "Caches", "Frizz")
|
|
14466
|
+
};
|
|
14467
|
+
}
|
|
14468
|
+
function xdgRoots(env, home) {
|
|
14469
|
+
return {
|
|
14470
|
+
data: join3(xdg(env, "XDG_DATA_HOME") ?? join3(home, ".local", "share"), "frizz"),
|
|
14471
|
+
state: join3(xdg(env, "XDG_STATE_HOME") ?? join3(home, ".local", "state"), "frizz"),
|
|
14472
|
+
cache: join3(xdg(env, "XDG_CACHE_HOME") ?? join3(home, ".cache"), "frizz")
|
|
14473
|
+
};
|
|
14474
|
+
}
|
|
14475
|
+
function frizzPaths(options2 = {}) {
|
|
14476
|
+
const env = options2.env ?? process.env;
|
|
14477
|
+
const platform = options2.platform ?? process.platform;
|
|
14478
|
+
const home = options2.home ?? homedir2();
|
|
14479
|
+
const exists = options2.exists ?? existsSync;
|
|
14480
|
+
const legacyRoot = legacyFrizzRoot(home);
|
|
14481
|
+
if (exists(legacyRoot)) {
|
|
14482
|
+
return { data: legacyRoot, state: legacyRoot, cache: legacyRoot, legacy: true };
|
|
14483
|
+
}
|
|
14484
|
+
const explicit = {
|
|
14485
|
+
data: xdg(env, "XDG_DATA_HOME"),
|
|
14486
|
+
state: xdg(env, "XDG_STATE_HOME"),
|
|
14487
|
+
cache: xdg(env, "XDG_CACHE_HOME")
|
|
14488
|
+
};
|
|
14489
|
+
const platformRoots = platform === "win32" ? windowsRoots(env, home) : platform === "darwin" ? darwinRoots(home) : xdgRoots(env, home);
|
|
14490
|
+
return {
|
|
14491
|
+
data: explicit.data ? join3(explicit.data, "frizz") : platformRoots.data,
|
|
14492
|
+
state: explicit.state ? join3(explicit.state, "frizz") : platformRoots.state,
|
|
14493
|
+
cache: explicit.cache ? join3(explicit.cache, "frizz") : platformRoots.cache,
|
|
14494
|
+
legacy: false
|
|
14495
|
+
};
|
|
14496
|
+
}
|
|
14497
|
+
function frizzRoots() {
|
|
14498
|
+
return cached ??= frizzPaths();
|
|
14499
|
+
}
|
|
14500
|
+
function projectStateDir(projectId, home) {
|
|
14501
|
+
return join3(home ? frizzPaths({ home }).data : frizzRoots().data, "projects", projectId);
|
|
14502
|
+
}
|
|
14503
|
+
var LEGACY_DIR_NAME, cached;
|
|
14504
|
+
var init_frizz_paths = __esm({
|
|
14505
|
+
"packages/server/src/frizz-paths.ts"() {
|
|
14506
|
+
"use strict";
|
|
14507
|
+
LEGACY_DIR_NAME = ".frizz";
|
|
14508
|
+
}
|
|
14509
|
+
});
|
|
14510
|
+
|
|
14115
14511
|
// node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/constants.js
|
|
14116
14512
|
var require_constants = __commonJS({
|
|
14117
14513
|
"node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/constants.js"(exports, module) {
|
|
@@ -17806,85 +18202,6 @@ var init_wrapper = __esm({
|
|
|
17806
18202
|
}
|
|
17807
18203
|
});
|
|
17808
18204
|
|
|
17809
|
-
// packages/server/src/frizz-paths.ts
|
|
17810
|
-
import { existsSync as existsSync2 } from "node:fs";
|
|
17811
|
-
import { homedir as homedir5, tmpdir } from "node:os";
|
|
17812
|
-
import { dirname as dirname4, join as join5 } from "node:path";
|
|
17813
|
-
function legacyFrizzRoot(home = homedir5()) {
|
|
17814
|
-
return join5(home, LEGACY_DIR_NAME);
|
|
17815
|
-
}
|
|
17816
|
-
function xdg(env, name) {
|
|
17817
|
-
const value = env[name];
|
|
17818
|
-
return value && (value.startsWith("/") || /^[A-Za-z]:[\\/]/u.test(value)) ? value : void 0;
|
|
17819
|
-
}
|
|
17820
|
-
function insideHome(child, home) {
|
|
17821
|
-
const norm = (value) => value.replace(/[\\/]+$/u, "").replaceAll("\\", "/").toLowerCase();
|
|
17822
|
-
const parent = norm(home);
|
|
17823
|
-
const inner = norm(child);
|
|
17824
|
-
return inner === parent || inner.startsWith(`${parent}/`);
|
|
17825
|
-
}
|
|
17826
|
-
function windowsRoots(env, home) {
|
|
17827
|
-
const local = env.LOCALAPPDATA && insideHome(env.LOCALAPPDATA, home) ? env.LOCALAPPDATA : join5(home, "AppData", "Local");
|
|
17828
|
-
const base = join5(local, "Frizz");
|
|
17829
|
-
return {
|
|
17830
|
-
data: join5(base, "Data"),
|
|
17831
|
-
state: join5(base, "State"),
|
|
17832
|
-
cache: join5(base, "Cache")
|
|
17833
|
-
};
|
|
17834
|
-
}
|
|
17835
|
-
function darwinRoots(home) {
|
|
17836
|
-
const support = join5(home, "Library", "Application Support", "Frizz");
|
|
17837
|
-
return {
|
|
17838
|
-
data: support,
|
|
17839
|
-
// macOS has no state directory concept; Application Support is where this belongs, and the log
|
|
17840
|
-
// files themselves already live under each project's own directory.
|
|
17841
|
-
state: support,
|
|
17842
|
-
cache: join5(home, "Library", "Caches", "Frizz")
|
|
17843
|
-
};
|
|
17844
|
-
}
|
|
17845
|
-
function xdgRoots(env, home) {
|
|
17846
|
-
return {
|
|
17847
|
-
data: join5(xdg(env, "XDG_DATA_HOME") ?? join5(home, ".local", "share"), "frizz"),
|
|
17848
|
-
state: join5(xdg(env, "XDG_STATE_HOME") ?? join5(home, ".local", "state"), "frizz"),
|
|
17849
|
-
cache: join5(xdg(env, "XDG_CACHE_HOME") ?? join5(home, ".cache"), "frizz")
|
|
17850
|
-
};
|
|
17851
|
-
}
|
|
17852
|
-
function frizzPaths(options2 = {}) {
|
|
17853
|
-
const env = options2.env ?? process.env;
|
|
17854
|
-
const platform = options2.platform ?? process.platform;
|
|
17855
|
-
const home = options2.home ?? homedir5();
|
|
17856
|
-
const exists = options2.exists ?? existsSync2;
|
|
17857
|
-
const legacyRoot = legacyFrizzRoot(home);
|
|
17858
|
-
if (exists(legacyRoot)) {
|
|
17859
|
-
return { data: legacyRoot, state: legacyRoot, cache: legacyRoot, legacy: true };
|
|
17860
|
-
}
|
|
17861
|
-
const explicit = {
|
|
17862
|
-
data: xdg(env, "XDG_DATA_HOME"),
|
|
17863
|
-
state: xdg(env, "XDG_STATE_HOME"),
|
|
17864
|
-
cache: xdg(env, "XDG_CACHE_HOME")
|
|
17865
|
-
};
|
|
17866
|
-
const platformRoots = platform === "win32" ? windowsRoots(env, home) : platform === "darwin" ? darwinRoots(home) : xdgRoots(env, home);
|
|
17867
|
-
return {
|
|
17868
|
-
data: explicit.data ? join5(explicit.data, "frizz") : platformRoots.data,
|
|
17869
|
-
state: explicit.state ? join5(explicit.state, "frizz") : platformRoots.state,
|
|
17870
|
-
cache: explicit.cache ? join5(explicit.cache, "frizz") : platformRoots.cache,
|
|
17871
|
-
legacy: false
|
|
17872
|
-
};
|
|
17873
|
-
}
|
|
17874
|
-
function frizzRoots() {
|
|
17875
|
-
return cached ??= frizzPaths();
|
|
17876
|
-
}
|
|
17877
|
-
function projectStateDir(projectId, home) {
|
|
17878
|
-
return join5(home ? frizzPaths({ home }).data : frizzRoots().data, "projects", projectId);
|
|
17879
|
-
}
|
|
17880
|
-
var LEGACY_DIR_NAME, cached;
|
|
17881
|
-
var init_frizz_paths = __esm({
|
|
17882
|
-
"packages/server/src/frizz-paths.ts"() {
|
|
17883
|
-
"use strict";
|
|
17884
|
-
LEGACY_DIR_NAME = ".frizz";
|
|
17885
|
-
}
|
|
17886
|
-
});
|
|
17887
|
-
|
|
17888
18205
|
// packages/server/src/logging.ts
|
|
17889
18206
|
import {
|
|
17890
18207
|
appendFileSync,
|
|
@@ -18223,7 +18540,7 @@ import {
|
|
|
18223
18540
|
writeFileSync as writeFileSync5
|
|
18224
18541
|
} from "node:fs";
|
|
18225
18542
|
import { homedir as homedir7 } from "node:os";
|
|
18226
|
-
import { dirname as dirname5, join as join8, resolve } from "node:path";
|
|
18543
|
+
import { dirname as dirname5, join as join8, resolve as resolve2 } from "node:path";
|
|
18227
18544
|
import { setTimeout as delay } from "node:timers/promises";
|
|
18228
18545
|
function errorCode2(error) {
|
|
18229
18546
|
return error && typeof error === "object" && "code" in error && typeof error.code === "string" ? error.code : void 0;
|
|
@@ -18235,7 +18552,7 @@ function canonicalHome(home) {
|
|
|
18235
18552
|
try {
|
|
18236
18553
|
return realpathSync2(home);
|
|
18237
18554
|
} catch {
|
|
18238
|
-
return
|
|
18555
|
+
return resolve2(home);
|
|
18239
18556
|
}
|
|
18240
18557
|
}
|
|
18241
18558
|
function globalLaunchLockPath(home = homedir7()) {
|
|
@@ -18440,7 +18757,7 @@ function revParsePath(dir, flag) {
|
|
|
18440
18757
|
throw new Error("unable to inspect Git worktree identity");
|
|
18441
18758
|
}
|
|
18442
18759
|
try {
|
|
18443
|
-
return realpathSync2(
|
|
18760
|
+
return realpathSync2(resolve2(dir, raw));
|
|
18444
18761
|
} catch {
|
|
18445
18762
|
throw new Error("unable to canonicalize Git worktree identity");
|
|
18446
18763
|
}
|
|
@@ -18512,7 +18829,7 @@ function syncGitConfig(dir) {
|
|
|
18512
18829
|
} catch {
|
|
18513
18830
|
throw new Error("unable to locate git config after writing frizz.id");
|
|
18514
18831
|
}
|
|
18515
|
-
const path =
|
|
18832
|
+
const path = resolve2(dir, raw);
|
|
18516
18833
|
syncGitConfigPath(path);
|
|
18517
18834
|
}
|
|
18518
18835
|
function createGitProjectId(dir) {
|
|
@@ -18638,7 +18955,7 @@ import {
|
|
|
18638
18955
|
statSync as statSync4,
|
|
18639
18956
|
writeFileSync as writeFileSync6
|
|
18640
18957
|
} from "node:fs";
|
|
18641
|
-
import { basename as basename2, dirname as dirname6, isAbsolute as
|
|
18958
|
+
import { basename as basename2, dirname as dirname6, isAbsolute as isAbsolute3, join as join9 } from "node:path";
|
|
18642
18959
|
function errorCode3(error) {
|
|
18643
18960
|
return error && typeof error === "object" && "code" in error && typeof error.code === "string" ? error.code : void 0;
|
|
18644
18961
|
}
|
|
@@ -18794,7 +19111,7 @@ function parseOwner(path) {
|
|
|
18794
19111
|
try {
|
|
18795
19112
|
const value = JSON.parse(readFileSync7(path, "utf8"));
|
|
18796
19113
|
const generation = parseGeneration(value);
|
|
18797
|
-
if (value.version !== 1 && value.version !== OWNER_VERSION || !generation || typeof value.token !== "string" || !UUID_RE.test(value.token) || typeof value.projectId !== "string" || !UUID_RE.test(value.projectId) || !validText(value.projectDir) || !
|
|
19114
|
+
if (value.version !== 1 && value.version !== OWNER_VERSION || !generation || typeof value.token !== "string" || !UUID_RE.test(value.token) || typeof value.projectId !== "string" || !UUID_RE.test(value.projectId) || !validText(value.projectDir) || !isAbsolute3(value.projectDir) || !validRole(value.role) || !validText(value.acquiredAt, 128) || !validText(value.updatedAt, 128)) return null;
|
|
18798
19115
|
const delegates = value.version === 1 ? [] : parseDelegates(value.delegates);
|
|
18799
19116
|
const state = value.version === 1 ? "active" : value.state;
|
|
18800
19117
|
if (!delegates || state !== "active" && state !== "draining") return null;
|
|
@@ -19031,7 +19348,7 @@ function projectLaunchTargetFromEnvironment(env) {
|
|
|
19031
19348
|
const projectDir = env[FRIZZ_LAUNCH_PROJECT_DIR];
|
|
19032
19349
|
const stateDir = env[FRIZZ_LAUNCH_STATE_DIR];
|
|
19033
19350
|
const scope = env[FRIZZ_LAUNCH_IDENTITY_SCOPE];
|
|
19034
|
-
if (!projectId || !UUID_RE.test(projectId) || !projectDir || !
|
|
19351
|
+
if (!projectId || !UUID_RE.test(projectId) || !projectDir || !isAbsolute3(projectDir) || !stateDir || !isAbsolute3(stateDir) || scope !== "repository" && scope !== "worktree") return null;
|
|
19035
19352
|
return {
|
|
19036
19353
|
projectId,
|
|
19037
19354
|
projectDir,
|
|
@@ -19108,7 +19425,7 @@ var init_boot_progress = __esm({
|
|
|
19108
19425
|
import { createHash as createHash3, randomUUID as randomUUID4 } from "node:crypto";
|
|
19109
19426
|
import { closeSync as closeSync3, existsSync as existsSync3, fsyncSync as fsyncSync3, mkdirSync as mkdirSync8, openSync as openSync4, readFileSync as readFileSync9, realpathSync as realpathSync3, renameSync as renameSync4, rmSync as rmSync6, writeFileSync as writeFileSync8 } from "node:fs";
|
|
19110
19427
|
import { homedir as homedir8 } from "node:os";
|
|
19111
|
-
import { dirname as dirname8, join as join11, parse, resolve as
|
|
19428
|
+
import { dirname as dirname8, join as join11, parse, resolve as resolve3 } from "node:path";
|
|
19112
19429
|
function projectIdPath(root) {
|
|
19113
19430
|
return join11(root, FRIZZ_DIR, ID_FILE);
|
|
19114
19431
|
}
|
|
@@ -19189,9 +19506,9 @@ function hasAny(dir, names) {
|
|
|
19189
19506
|
function isHomeDirectory(dir, home = homedir8()) {
|
|
19190
19507
|
const canonical = (value) => {
|
|
19191
19508
|
try {
|
|
19192
|
-
return realpathSync3(
|
|
19509
|
+
return realpathSync3(resolve3(value));
|
|
19193
19510
|
} catch {
|
|
19194
|
-
return
|
|
19511
|
+
return resolve3(value);
|
|
19195
19512
|
}
|
|
19196
19513
|
};
|
|
19197
19514
|
try {
|
|
@@ -19218,11 +19535,11 @@ function hasProjectMarker(dir) {
|
|
|
19218
19535
|
function discoverProjectRoot(cwd = process.cwd(), home = homedir8()) {
|
|
19219
19536
|
let dir;
|
|
19220
19537
|
try {
|
|
19221
|
-
dir =
|
|
19538
|
+
dir = resolve3(cwd);
|
|
19222
19539
|
} catch {
|
|
19223
|
-
return
|
|
19540
|
+
return resolve3(cwd);
|
|
19224
19541
|
}
|
|
19225
|
-
const stop =
|
|
19542
|
+
const stop = resolve3(home);
|
|
19226
19543
|
const filesystemRoot = parse(dir).root;
|
|
19227
19544
|
for (let at = dir; ; at = dirname8(at)) {
|
|
19228
19545
|
if (at === stop || at === filesystemRoot) break;
|
|
@@ -19605,12 +19922,12 @@ function manifestIdFor(url) {
|
|
|
19605
19922
|
return url.endsWith("/") ? url : `${url}/`;
|
|
19606
19923
|
}
|
|
19607
19924
|
function execFileP(cmd, args2) {
|
|
19608
|
-
return new Promise((
|
|
19925
|
+
return new Promise((resolve6, reject) => {
|
|
19609
19926
|
execFile(
|
|
19610
19927
|
cmd,
|
|
19611
19928
|
args2,
|
|
19612
19929
|
{ encoding: "utf8", timeout: 1e4 },
|
|
19613
|
-
(err, stdout) => err ? reject(err) :
|
|
19930
|
+
(err, stdout) => err ? reject(err) : resolve6(stdout)
|
|
19614
19931
|
);
|
|
19615
19932
|
});
|
|
19616
19933
|
}
|
|
@@ -19689,9 +20006,9 @@ function openCdpSession(browserPath, dataPath) {
|
|
|
19689
20006
|
cmdPipe.on("error", failAll);
|
|
19690
20007
|
resPipe.on("error", failAll);
|
|
19691
20008
|
child.on("exit", () => failAll(new Error("chrome exited before the CDP handshake completed")));
|
|
19692
|
-
const call2 = (method, params = {}, timeoutMs = 2e4) => new Promise((
|
|
20009
|
+
const call2 = (method, params = {}, timeoutMs = 2e4) => new Promise((resolve6, reject) => {
|
|
19693
20010
|
const id = ++seq;
|
|
19694
|
-
pending.set(id, { resolve:
|
|
20011
|
+
pending.set(id, { resolve: resolve6, reject });
|
|
19695
20012
|
cmdPipe.write(JSON.stringify({ id, method, params }) + "\0");
|
|
19696
20013
|
setTimeout(() => {
|
|
19697
20014
|
if (pending.has(id)) {
|
|
@@ -19704,15 +20021,15 @@ function openCdpSession(browserPath, dataPath) {
|
|
|
19704
20021
|
await call2("Browser.close").catch(() => {
|
|
19705
20022
|
});
|
|
19706
20023
|
if (child.exitCode !== null || child.signalCode !== null) return;
|
|
19707
|
-
await new Promise((
|
|
20024
|
+
await new Promise((resolve6) => {
|
|
19708
20025
|
const t = setTimeout(() => {
|
|
19709
20026
|
child.kill();
|
|
19710
|
-
|
|
20027
|
+
resolve6();
|
|
19711
20028
|
}, 1e4);
|
|
19712
20029
|
t.unref();
|
|
19713
20030
|
child.once("exit", () => {
|
|
19714
20031
|
clearTimeout(t);
|
|
19715
|
-
|
|
20032
|
+
resolve6();
|
|
19716
20033
|
});
|
|
19717
20034
|
});
|
|
19718
20035
|
};
|
|
@@ -22451,7 +22768,15 @@ function createAccessPane(options2) {
|
|
|
22451
22768
|
ticker.unref?.();
|
|
22452
22769
|
return true;
|
|
22453
22770
|
},
|
|
22454
|
-
key() {
|
|
22771
|
+
key(key) {
|
|
22772
|
+
if (key === "l" || key === "L") {
|
|
22773
|
+
const link = options2.issue();
|
|
22774
|
+
if (!link) return "close";
|
|
22775
|
+
shown = link;
|
|
22776
|
+
consumed = false;
|
|
22777
|
+
paint();
|
|
22778
|
+
return "keep";
|
|
22779
|
+
}
|
|
22455
22780
|
return "close";
|
|
22456
22781
|
},
|
|
22457
22782
|
close() {
|
|
@@ -22473,25 +22798,26 @@ function createAccessPane(options2) {
|
|
|
22473
22798
|
}
|
|
22474
22799
|
|
|
22475
22800
|
// src/remote-controller.ts
|
|
22476
|
-
import { homedir as
|
|
22801
|
+
import { homedir as homedir5 } from "node:os";
|
|
22477
22802
|
|
|
22478
22803
|
// src/cloud.ts
|
|
22479
22804
|
init_src();
|
|
22480
22805
|
import { spawn as spawn2 } from "node:child_process";
|
|
22481
|
-
import { existsSync, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3, rmSync } from "node:fs";
|
|
22806
|
+
import { existsSync as existsSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3, rmSync } from "node:fs";
|
|
22482
22807
|
import { createInterface } from "node:readline/promises";
|
|
22483
|
-
import { homedir as
|
|
22484
|
-
import { dirname as
|
|
22808
|
+
import { homedir as homedir4 } from "node:os";
|
|
22809
|
+
import { dirname as dirname4, join as join5 } from "node:path";
|
|
22485
22810
|
|
|
22486
22811
|
// src/identity.ts
|
|
22812
|
+
init_frizz_paths();
|
|
22487
22813
|
init_src();
|
|
22488
22814
|
import { mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "node:fs";
|
|
22489
|
-
import { homedir as
|
|
22490
|
-
import { dirname as
|
|
22491
|
-
function claimIdentityPath(home =
|
|
22492
|
-
return
|
|
22815
|
+
import { homedir as homedir3 } from "node:os";
|
|
22816
|
+
import { dirname as dirname3, join as join4 } from "node:path";
|
|
22817
|
+
function claimIdentityPath(home = homedir3()) {
|
|
22818
|
+
return join4(frizzPaths({ home }).state, "identity.key");
|
|
22493
22819
|
}
|
|
22494
|
-
async function loadOrCreateClaimIdentity(home =
|
|
22820
|
+
async function loadOrCreateClaimIdentity(home = homedir3()) {
|
|
22495
22821
|
const path = claimIdentityPath(home);
|
|
22496
22822
|
let stored;
|
|
22497
22823
|
try {
|
|
@@ -22507,7 +22833,7 @@ async function loadOrCreateClaimIdentity(home = homedir2()) {
|
|
|
22507
22833
|
);
|
|
22508
22834
|
}
|
|
22509
22835
|
const identity = await generateClaimIdentity();
|
|
22510
|
-
mkdirSync2(
|
|
22836
|
+
mkdirSync2(dirname3(path), { recursive: true });
|
|
22511
22837
|
writeFileSync2(path, await exportClaimPrivateKey(identity.privateKey), { mode: 384 });
|
|
22512
22838
|
return identity;
|
|
22513
22839
|
}
|
|
@@ -22645,7 +22971,12 @@ function serveRelayRequest(frame, options2) {
|
|
|
22645
22971
|
const target2 = new URL(frame.url);
|
|
22646
22972
|
const local = new URL(options2.origin);
|
|
22647
22973
|
const publicUrl = new URL(options2.publicOrigin);
|
|
22648
|
-
|
|
22974
|
+
let cancelled = false;
|
|
22975
|
+
let abort;
|
|
22976
|
+
const done = new Promise((resolve6) => {
|
|
22977
|
+
const send = (upFrame) => {
|
|
22978
|
+
if (!cancelled) options2.send(upFrame);
|
|
22979
|
+
};
|
|
22649
22980
|
const headers = {};
|
|
22650
22981
|
for (const [name, value] of stripHopByHop(frame.headers)) headers[name] = value;
|
|
22651
22982
|
headers.host = publicUrl.host;
|
|
@@ -22664,10 +22995,10 @@ function serveRelayRequest(frame, options2) {
|
|
|
22664
22995
|
);
|
|
22665
22996
|
const streaming = shouldStream(outHeaders);
|
|
22666
22997
|
if (streaming) {
|
|
22667
|
-
|
|
22998
|
+
send({ t: "res", id: frame.id, status: res.statusCode ?? 502, headers: outHeaders, end: false });
|
|
22668
22999
|
res.on("data", (chunk) => {
|
|
22669
23000
|
for (let at = 0; at < chunk.length; at += RELAY_MAX_FRAME_BODY) {
|
|
22670
|
-
|
|
23001
|
+
send({
|
|
22671
23002
|
t: "res-chunk",
|
|
22672
23003
|
id: frame.id,
|
|
22673
23004
|
data: encodeBody(new Uint8Array(chunk.subarray(at, at + RELAY_MAX_FRAME_BODY)))
|
|
@@ -22675,12 +23006,12 @@ function serveRelayRequest(frame, options2) {
|
|
|
22675
23006
|
}
|
|
22676
23007
|
});
|
|
22677
23008
|
res.on("end", () => {
|
|
22678
|
-
|
|
22679
|
-
|
|
23009
|
+
send({ t: "res-end", id: frame.id });
|
|
23010
|
+
resolve6();
|
|
22680
23011
|
});
|
|
22681
23012
|
res.on("error", () => {
|
|
22682
|
-
|
|
22683
|
-
|
|
23013
|
+
send({ t: "res-end", id: frame.id });
|
|
23014
|
+
resolve6();
|
|
22684
23015
|
});
|
|
22685
23016
|
return;
|
|
22686
23017
|
}
|
|
@@ -22689,7 +23020,7 @@ function serveRelayRequest(frame, options2) {
|
|
|
22689
23020
|
res.on("end", () => {
|
|
22690
23021
|
const body = Buffer.concat(chunks);
|
|
22691
23022
|
if (body.byteLength <= RELAY_MAX_FRAME_BODY) {
|
|
22692
|
-
|
|
23023
|
+
send({
|
|
22693
23024
|
t: "res",
|
|
22694
23025
|
id: frame.id,
|
|
22695
23026
|
status: res.statusCode ?? 502,
|
|
@@ -22697,28 +23028,28 @@ function serveRelayRequest(frame, options2) {
|
|
|
22697
23028
|
...body.byteLength > 0 ? { body: encodeBody(new Uint8Array(body)) } : {},
|
|
22698
23029
|
end: true
|
|
22699
23030
|
});
|
|
22700
|
-
|
|
23031
|
+
resolve6();
|
|
22701
23032
|
return;
|
|
22702
23033
|
}
|
|
22703
|
-
|
|
23034
|
+
send({ t: "res", id: frame.id, status: res.statusCode ?? 502, headers: outHeaders, end: false });
|
|
22704
23035
|
for (let at = 0; at < body.byteLength; at += RELAY_MAX_FRAME_BODY) {
|
|
22705
|
-
|
|
23036
|
+
send({
|
|
22706
23037
|
t: "res-chunk",
|
|
22707
23038
|
id: frame.id,
|
|
22708
23039
|
data: encodeBody(new Uint8Array(body.subarray(at, at + RELAY_MAX_FRAME_BODY)))
|
|
22709
23040
|
});
|
|
22710
23041
|
}
|
|
22711
|
-
|
|
22712
|
-
|
|
23042
|
+
send({ t: "res-end", id: frame.id });
|
|
23043
|
+
resolve6();
|
|
22713
23044
|
});
|
|
22714
23045
|
res.on("error", () => {
|
|
22715
|
-
|
|
22716
|
-
|
|
23046
|
+
send({ t: "res", id: frame.id, status: 502, headers: [], end: true });
|
|
23047
|
+
resolve6();
|
|
22717
23048
|
});
|
|
22718
23049
|
}
|
|
22719
23050
|
);
|
|
22720
23051
|
req.on("error", (error) => {
|
|
22721
|
-
|
|
23052
|
+
send({
|
|
22722
23053
|
t: "res",
|
|
22723
23054
|
id: frame.id,
|
|
22724
23055
|
status: 502,
|
|
@@ -22726,11 +23057,23 @@ function serveRelayRequest(frame, options2) {
|
|
|
22726
23057
|
body: encodeBody(new TextEncoder().encode(`Frizz is not answering on this machine: ${error.message}`)),
|
|
22727
23058
|
end: true
|
|
22728
23059
|
});
|
|
22729
|
-
|
|
23060
|
+
resolve6();
|
|
22730
23061
|
});
|
|
22731
23062
|
if (frame.body) req.write(Buffer.from(decodeBody(frame.body)));
|
|
22732
23063
|
req.end();
|
|
23064
|
+
abort = () => {
|
|
23065
|
+
req.destroy();
|
|
23066
|
+
resolve6();
|
|
23067
|
+
};
|
|
22733
23068
|
});
|
|
23069
|
+
return {
|
|
23070
|
+
done,
|
|
23071
|
+
cancel: () => {
|
|
23072
|
+
if (cancelled) return;
|
|
23073
|
+
cancelled = true;
|
|
23074
|
+
abort?.();
|
|
23075
|
+
}
|
|
23076
|
+
};
|
|
22734
23077
|
}
|
|
22735
23078
|
var HANDSHAKE_HEADERS = /* @__PURE__ */ new Set([
|
|
22736
23079
|
"sec-websocket-key",
|
|
@@ -22812,6 +23155,7 @@ function defaultBackoff(attempt, random = Math.random) {
|
|
|
22812
23155
|
const base = Math.min(3e4, 500 * 2 ** Math.min(attempt, 6));
|
|
22813
23156
|
return Math.round(base / 2 + random() * (base / 2));
|
|
22814
23157
|
}
|
|
23158
|
+
var RELAY_KEEPALIVE_INTERVAL_MS = 45e3;
|
|
22815
23159
|
async function signRelayHandshake(name, identity, issuedAt) {
|
|
22816
23160
|
const pubkey = await exportClaimPublicKey(identity.publicKey);
|
|
22817
23161
|
const signature = await crypto.subtle.sign(
|
|
@@ -22829,9 +23173,22 @@ function connectRelay(options2) {
|
|
|
22829
23173
|
const makeSocket = options2.socketFactory ?? ((url) => new WebSocket(url));
|
|
22830
23174
|
let socket = null;
|
|
22831
23175
|
const nested = /* @__PURE__ */ new Map();
|
|
23176
|
+
const requests = /* @__PURE__ */ new Map();
|
|
22832
23177
|
let attempt = 0;
|
|
22833
23178
|
let stopped = false;
|
|
22834
23179
|
let retryHandle;
|
|
23180
|
+
let keepaliveHandle;
|
|
23181
|
+
let awaitingPong = false;
|
|
23182
|
+
const clearKeepalive = () => {
|
|
23183
|
+
if (keepaliveHandle !== void 0) {
|
|
23184
|
+
clearTimer(keepaliveHandle);
|
|
23185
|
+
keepaliveHandle = void 0;
|
|
23186
|
+
}
|
|
23187
|
+
};
|
|
23188
|
+
const cancelRequests = () => {
|
|
23189
|
+
for (const request of requests.values()) request.cancel();
|
|
23190
|
+
requests.clear();
|
|
23191
|
+
};
|
|
22835
23192
|
const send = (frame) => {
|
|
22836
23193
|
try {
|
|
22837
23194
|
socket?.send(serializeFrame(frame));
|
|
@@ -22858,7 +23215,26 @@ function connectRelay(options2) {
|
|
|
22858
23215
|
const next = makeSocket(url);
|
|
22859
23216
|
socket = next;
|
|
22860
23217
|
let settled;
|
|
23218
|
+
const beat = () => {
|
|
23219
|
+
if (stopped || socket !== next) return;
|
|
23220
|
+
if (awaitingPong) {
|
|
23221
|
+
dropped();
|
|
23222
|
+
try {
|
|
23223
|
+
next.close();
|
|
23224
|
+
} catch {
|
|
23225
|
+
}
|
|
23226
|
+
return;
|
|
23227
|
+
}
|
|
23228
|
+
awaitingPong = true;
|
|
23229
|
+
try {
|
|
23230
|
+
next.send(RELAY_KEEPALIVE_PING);
|
|
23231
|
+
} catch {
|
|
23232
|
+
}
|
|
23233
|
+
keepaliveHandle = setTimer(beat, RELAY_KEEPALIVE_INTERVAL_MS);
|
|
23234
|
+
};
|
|
22861
23235
|
next.addEventListener("open", () => {
|
|
23236
|
+
awaitingPong = false;
|
|
23237
|
+
keepaliveHandle = setTimer(beat, RELAY_KEEPALIVE_INTERVAL_MS);
|
|
22862
23238
|
settled = setTimer(() => {
|
|
22863
23239
|
attempt = 0;
|
|
22864
23240
|
}, SETTLED_MS);
|
|
@@ -22872,12 +23248,25 @@ function connectRelay(options2) {
|
|
|
22872
23248
|
send({ t: "pong", id: frame.id });
|
|
22873
23249
|
return;
|
|
22874
23250
|
}
|
|
23251
|
+
if (frame.t === "pong") {
|
|
23252
|
+
awaitingPong = false;
|
|
23253
|
+
return;
|
|
23254
|
+
}
|
|
22875
23255
|
if (frame.t === "req") {
|
|
22876
|
-
|
|
23256
|
+
const handle = serveRelayRequest(frame, {
|
|
22877
23257
|
origin: options2.boardOrigin,
|
|
22878
23258
|
publicOrigin: options2.publicOrigin,
|
|
22879
23259
|
send
|
|
22880
23260
|
});
|
|
23261
|
+
requests.set(frame.id, handle);
|
|
23262
|
+
void handle.done.then(() => {
|
|
23263
|
+
if (requests.get(frame.id) === handle) requests.delete(frame.id);
|
|
23264
|
+
});
|
|
23265
|
+
return;
|
|
23266
|
+
}
|
|
23267
|
+
if (frame.t === "req-cancel") {
|
|
23268
|
+
requests.get(frame.id)?.cancel();
|
|
23269
|
+
requests.delete(frame.id);
|
|
22881
23270
|
return;
|
|
22882
23271
|
}
|
|
22883
23272
|
if (frame.t === "ws-open") {
|
|
@@ -22906,9 +23295,11 @@ function connectRelay(options2) {
|
|
|
22906
23295
|
clearTimer(settled);
|
|
22907
23296
|
settled = void 0;
|
|
22908
23297
|
}
|
|
23298
|
+
clearKeepalive();
|
|
22909
23299
|
socket = null;
|
|
22910
23300
|
for (const session of nested.values()) session.close();
|
|
22911
23301
|
nested.clear();
|
|
23302
|
+
cancelRequests();
|
|
22912
23303
|
options2.onStatus?.("disconnected");
|
|
22913
23304
|
scheduleRetry("the relay connection closed");
|
|
22914
23305
|
};
|
|
@@ -22920,12 +23311,14 @@ function connectRelay(options2) {
|
|
|
22920
23311
|
stop() {
|
|
22921
23312
|
stopped = true;
|
|
22922
23313
|
if (retryHandle !== void 0) clearTimer(retryHandle);
|
|
23314
|
+
clearKeepalive();
|
|
22923
23315
|
try {
|
|
22924
23316
|
socket?.close();
|
|
22925
23317
|
} catch {
|
|
22926
23318
|
}
|
|
22927
23319
|
for (const session of nested.values()) session.close();
|
|
22928
23320
|
nested.clear();
|
|
23321
|
+
cancelRequests();
|
|
22929
23322
|
socket = null;
|
|
22930
23323
|
},
|
|
22931
23324
|
get connected() {
|
|
@@ -22957,7 +23350,7 @@ function zoneClaimLabel(hostname) {
|
|
|
22957
23350
|
const label = hostname.slice(0, -suffix.length);
|
|
22958
23351
|
return label.length > 0 && !label.includes(".") ? label : null;
|
|
22959
23352
|
}
|
|
22960
|
-
async function reconcileCloudConfig(config, port, home =
|
|
23353
|
+
async function reconcileCloudConfig(config, port, home = homedir4(), onNotice, origin, github = githubCli) {
|
|
22961
23354
|
if (isRelayConfig(config)) return config;
|
|
22962
23355
|
const label = config.claim ?? zoneClaimLabel(config.hostname);
|
|
22963
23356
|
if (!label) return config;
|
|
@@ -22966,10 +23359,10 @@ async function reconcileCloudConfig(config, port, home = homedir3(), onNotice, o
|
|
|
22966
23359
|
);
|
|
22967
23360
|
return establishCloudConfig(label, port, home, origin, github);
|
|
22968
23361
|
}
|
|
22969
|
-
function cloudConfigPath(home =
|
|
22970
|
-
return
|
|
23362
|
+
function cloudConfigPath(home = homedir4()) {
|
|
23363
|
+
return join5(home, ".frizz", "cloud.json");
|
|
22971
23364
|
}
|
|
22972
|
-
function readCloudConfig(home =
|
|
23365
|
+
function readCloudConfig(home = homedir4()) {
|
|
22973
23366
|
try {
|
|
22974
23367
|
const parsed = JSON.parse(readFileSync4(cloudConfigPath(home), "utf8"));
|
|
22975
23368
|
if (typeof parsed.hostname !== "string" || !parsed.hostname) return null;
|
|
@@ -22989,10 +23382,10 @@ function readCloudConfig(home = homedir3()) {
|
|
|
22989
23382
|
return null;
|
|
22990
23383
|
}
|
|
22991
23384
|
}
|
|
22992
|
-
function tunnelTokenPath(home =
|
|
22993
|
-
return
|
|
23385
|
+
function tunnelTokenPath(home = homedir4()) {
|
|
23386
|
+
return join5(home, ".frizz", "tunnel-token");
|
|
22994
23387
|
}
|
|
22995
|
-
function readTunnelToken(home =
|
|
23388
|
+
function readTunnelToken(home = homedir4()) {
|
|
22996
23389
|
try {
|
|
22997
23390
|
const token = readFileSync4(tunnelTokenPath(home), "utf8").trim();
|
|
22998
23391
|
return token.length > 0 ? token : null;
|
|
@@ -23000,18 +23393,18 @@ function readTunnelToken(home = homedir3()) {
|
|
|
23000
23393
|
return null;
|
|
23001
23394
|
}
|
|
23002
23395
|
}
|
|
23003
|
-
function writeTunnelToken(token, home =
|
|
23396
|
+
function writeTunnelToken(token, home = homedir4()) {
|
|
23004
23397
|
const path = tunnelTokenPath(home);
|
|
23005
|
-
mkdirSync3(
|
|
23398
|
+
mkdirSync3(dirname4(path), { recursive: true });
|
|
23006
23399
|
writeFileSync3(path, `${token}
|
|
23007
23400
|
`, { mode: 384 });
|
|
23008
23401
|
}
|
|
23009
|
-
function deleteCloudConfig(home =
|
|
23402
|
+
function deleteCloudConfig(home = homedir4()) {
|
|
23010
23403
|
rmSync(cloudConfigPath(home), { force: true });
|
|
23011
23404
|
}
|
|
23012
|
-
function writeCloudConfig(config, home =
|
|
23405
|
+
function writeCloudConfig(config, home = homedir4()) {
|
|
23013
23406
|
const path = cloudConfigPath(home);
|
|
23014
|
-
mkdirSync3(
|
|
23407
|
+
mkdirSync3(dirname4(path), { recursive: true });
|
|
23015
23408
|
writeFileSync3(path, `${JSON.stringify(config, null, 2)}
|
|
23016
23409
|
`);
|
|
23017
23410
|
}
|
|
@@ -23032,7 +23425,7 @@ async function promptForTunnelName(hostname, fallback) {
|
|
|
23032
23425
|
rl.close();
|
|
23033
23426
|
}
|
|
23034
23427
|
}
|
|
23035
|
-
async function establishCloudConfig(answer, port, home =
|
|
23428
|
+
async function establishCloudConfig(answer, port, home = homedir4(), origin, github = githubCli) {
|
|
23036
23429
|
if (answer.includes(".")) {
|
|
23037
23430
|
const hostname = normalizeHostname(answer);
|
|
23038
23431
|
const tunnel = await promptForTunnelName(hostname, hostname.split(".")[0]);
|
|
@@ -23043,17 +23436,23 @@ async function establishCloudConfig(answer, port, home = homedir3(), origin, git
|
|
|
23043
23436
|
"claiming a name on frizz.sh is not available yet.\n Reach this board through a tunnel of your own instead \u2014 see docs/remote-access.md \u2014 and\n answer with its hostname rather than a bare name."
|
|
23044
23437
|
);
|
|
23045
23438
|
}
|
|
23046
|
-
|
|
23439
|
+
const anonymous = answer === "" || isAnonymousClaimName(answer);
|
|
23440
|
+
if (!anonymous && !claimNameIsValid(answer)) {
|
|
23047
23441
|
normalizeClaimName(answer);
|
|
23048
23442
|
}
|
|
23049
|
-
const name = normalizeClaimName(answer);
|
|
23443
|
+
const name = answer === "" ? generateAnonymousClaimName() : normalizeClaimName(answer);
|
|
23050
23444
|
const identity = await loadOrCreateClaimIdentity(home);
|
|
23051
|
-
|
|
23052
|
-
|
|
23053
|
-
|
|
23445
|
+
let token;
|
|
23446
|
+
if (!anonymous) {
|
|
23447
|
+
token = await github.accessToken();
|
|
23448
|
+
const login = await github.login();
|
|
23449
|
+
if (login) console.log(` claiming ${name}.frizz.sh for GitHub user ${login}`);
|
|
23450
|
+
} else {
|
|
23451
|
+
console.log(" claiming a private name on frizz.sh \u2014 no account needed");
|
|
23452
|
+
}
|
|
23054
23453
|
let result;
|
|
23055
23454
|
try {
|
|
23056
|
-
result = await claimName({ name, port, identity, github: token, ...origin ? { origin } : {} });
|
|
23455
|
+
result = await claimName({ name, port, identity, ...token ? { github: token } : {}, ...origin ? { origin } : {} });
|
|
23057
23456
|
} catch (error) {
|
|
23058
23457
|
if (error instanceof ClaimError && error.code === "unreachable") {
|
|
23059
23458
|
throw new ClaimError(
|
|
@@ -23070,7 +23469,7 @@ async function establishCloudConfig(answer, port, home = homedir3(), origin, git
|
|
|
23070
23469
|
}
|
|
23071
23470
|
return { hostname: result.hostname, claim: name, serve: "relay" };
|
|
23072
23471
|
}
|
|
23073
|
-
async function resolveRunToken(config, port, home =
|
|
23472
|
+
async function resolveRunToken(config, port, home = homedir4(), onWarning, origin) {
|
|
23074
23473
|
if (!isClaimedConfig(config)) return null;
|
|
23075
23474
|
const cached2 = readTunnelToken(home);
|
|
23076
23475
|
try {
|
|
@@ -23087,12 +23486,12 @@ async function resolveRunToken(config, port, home = homedir3(), onWarning, origi
|
|
|
23087
23486
|
throw error;
|
|
23088
23487
|
}
|
|
23089
23488
|
}
|
|
23090
|
-
function resolveTunnelConfigPath(config, home =
|
|
23489
|
+
function resolveTunnelConfigPath(config, home = homedir4()) {
|
|
23091
23490
|
if (config.config) return config.config;
|
|
23092
|
-
const candidate =
|
|
23093
|
-
return
|
|
23491
|
+
const candidate = join5(home, ".cloudflared", "frizz.yml");
|
|
23492
|
+
return existsSync2(candidate) ? candidate : null;
|
|
23094
23493
|
}
|
|
23095
|
-
async function startRelay(config, port, home =
|
|
23494
|
+
async function startRelay(config, port, home = homedir4(), onStatus) {
|
|
23096
23495
|
const identity = await loadOrCreateClaimIdentity(home);
|
|
23097
23496
|
const origin = `https://${config.hostname}`;
|
|
23098
23497
|
return connectRelay({
|
|
@@ -23110,7 +23509,7 @@ async function startRelay(config, port, home = homedir3(), onStatus) {
|
|
|
23110
23509
|
} : {}
|
|
23111
23510
|
});
|
|
23112
23511
|
}
|
|
23113
|
-
function startTunnel(config, onExit, onError, home =
|
|
23512
|
+
function startTunnel(config, onExit, onError, home = homedir4(), runToken) {
|
|
23114
23513
|
const configPath = runToken ? null : resolveTunnelConfigPath(config, home);
|
|
23115
23514
|
const args2 = runToken ? ["tunnel", "--no-autoupdate", "run", "--token", runToken] : [
|
|
23116
23515
|
"tunnel",
|
|
@@ -23141,7 +23540,7 @@ function startTunnel(config, onExit, onError, home = homedir3(), runToken) {
|
|
|
23141
23540
|
|
|
23142
23541
|
// src/remote-controller.ts
|
|
23143
23542
|
function createRemoteController(options2) {
|
|
23144
|
-
const home = options2.home ??
|
|
23543
|
+
const home = options2.home ?? homedir5();
|
|
23145
23544
|
let config = null;
|
|
23146
23545
|
let transport = null;
|
|
23147
23546
|
const stopTransport = () => {
|
|
@@ -23223,9 +23622,9 @@ function createRemoteController(options2) {
|
|
|
23223
23622
|
import { execFile as execFile3 } from "node:child_process";
|
|
23224
23623
|
var PROBE_TIMEOUT_MS = 4e3;
|
|
23225
23624
|
function run2(command, args2) {
|
|
23226
|
-
return new Promise((
|
|
23625
|
+
return new Promise((resolve6) => {
|
|
23227
23626
|
execFile3(command, args2, { encoding: "utf8", timeout: PROBE_TIMEOUT_MS }, (error, stdout) => {
|
|
23228
|
-
|
|
23627
|
+
resolve6(error ? null : stdout);
|
|
23229
23628
|
});
|
|
23230
23629
|
});
|
|
23231
23630
|
}
|
|
@@ -23253,8 +23652,10 @@ async function probeTailscale() {
|
|
|
23253
23652
|
}
|
|
23254
23653
|
|
|
23255
23654
|
// src/remote-pane.ts
|
|
23655
|
+
init_src();
|
|
23256
23656
|
var CHOICES = [
|
|
23257
|
-
{ kind: "
|
|
23657
|
+
{ kind: "private", title: "Private name", blurb: "an unguessable name on frizz.sh \u2014 no account, nothing to install" },
|
|
23658
|
+
{ kind: "frizz", title: "Custom name", blurb: "<name>.frizz.sh of your choosing; needs the GitHub CLI" },
|
|
23258
23659
|
{ kind: "cloudflare", title: "Cloudflare Tunnel", blurb: "a domain you own on Cloudflare; cloudflared on this machine" },
|
|
23259
23660
|
{ kind: "tailscale", title: "Tailscale", blurb: "your tailnet; tailscale serve does the TLS" },
|
|
23260
23661
|
{ kind: "other", title: "Something else", blurb: "any proxy or tunnel you run \u2014 tell Frizz its address" },
|
|
@@ -23269,7 +23670,7 @@ var TAB = " ";
|
|
|
23269
23670
|
var SHIFT_TAB = "\x1B[Z";
|
|
23270
23671
|
function kindOf(config) {
|
|
23271
23672
|
if (!config) return "off";
|
|
23272
|
-
if (isClaimedConfig(config)) return "frizz";
|
|
23673
|
+
if (isClaimedConfig(config)) return isAnonymousClaimName(config.claim) ? "private" : "frizz";
|
|
23273
23674
|
if (isExternalConfig(config)) return config.provider === "tailscale" ? "tailscale" : "other";
|
|
23274
23675
|
return "cloudflare";
|
|
23275
23676
|
}
|
|
@@ -23356,10 +23757,10 @@ function createRemotePane(options2) {
|
|
|
23356
23757
|
if (kind === "frizz") {
|
|
23357
23758
|
const gh = github === "pending" || github === null ? `${DIM}GitHub CLI checking\u2026${RESET2}` : !github.installed ? "GitHub CLI not installed \u2014 see https://cli.github.com, then `gh auth login`" : github.login ? check(true, `GitHub CLI signed in as ${github.login}`) : "GitHub CLI not signed in \u2014 run `gh auth login` in another terminal";
|
|
23358
23759
|
return [
|
|
23359
|
-
"frizz.sh name",
|
|
23760
|
+
"Custom frizz.sh name",
|
|
23360
23761
|
"",
|
|
23361
23762
|
...wrap(
|
|
23362
|
-
"Claims <name>.frizz.sh
|
|
23763
|
+
"Claims <name>.frizz.sh of your choosing, tied to your GitHub account so names cannot be squatted. The board dials out to frizz.sh \u2014 no port, no DNS record, no tunnel binary. One name per account; a name nobody runs for 30 days is released. (A private name needs none of this.)"
|
|
23363
23764
|
),
|
|
23364
23765
|
...options2.sandbox ? ["", ...wrap("This is a sandbox, but a claim is real: it binds this machine's one name to your account, and your real board keeps it. Only the setup saved here is thrown away.")] : [],
|
|
23365
23766
|
"",
|
|
@@ -23480,6 +23881,22 @@ function createRemotePane(options2) {
|
|
|
23480
23881
|
}
|
|
23481
23882
|
paint();
|
|
23482
23883
|
};
|
|
23884
|
+
const claimPrivate = async () => {
|
|
23885
|
+
const back = { name: "menu", index: 0 };
|
|
23886
|
+
screen = { name: "busy", message: "claiming a private name on frizz.sh\u2026" };
|
|
23887
|
+
paint();
|
|
23888
|
+
try {
|
|
23889
|
+
const next = await options2.claim("");
|
|
23890
|
+
screen = { name: "busy", message: `serving ${next.hostname}\u2026` };
|
|
23891
|
+
paint();
|
|
23892
|
+
await options2.apply(next, { justClaimed: true });
|
|
23893
|
+
options2.onChanged?.(next);
|
|
23894
|
+
screen = { name: "done", message: `Serving https://${next.hostname} (${describeCloudConfig(next)}).`, link: options2.issueLink(), config: next };
|
|
23895
|
+
} catch (error) {
|
|
23896
|
+
screen = { name: "error", message: error instanceof Error ? error.message : String(error), back };
|
|
23897
|
+
}
|
|
23898
|
+
paint();
|
|
23899
|
+
};
|
|
23483
23900
|
const turnOff = async () => {
|
|
23484
23901
|
screen = { name: "busy", message: "back to loopback only\u2026" };
|
|
23485
23902
|
paint();
|
|
@@ -23515,10 +23932,11 @@ function createRemotePane(options2) {
|
|
|
23515
23932
|
if (key === ESC || key === "q") return "close";
|
|
23516
23933
|
if (key === UP || key === "k") s.index = (s.index + CHOICES.length - 1) % CHOICES.length;
|
|
23517
23934
|
else if (key === DOWN || key === "j") s.index = (s.index + 1) % CHOICES.length;
|
|
23518
|
-
else if (/^[1-
|
|
23935
|
+
else if (/^[1-6]$/.test(key)) s.index = Number(key) - 1;
|
|
23519
23936
|
else if (ENTER.has(key)) {
|
|
23520
23937
|
const choice = CHOICES[s.index];
|
|
23521
23938
|
if (choice.kind === "off") void turnOff();
|
|
23939
|
+
else if (choice.kind === "private") void claimPrivate();
|
|
23522
23940
|
else openForm(choice.kind);
|
|
23523
23941
|
return "keep";
|
|
23524
23942
|
}
|
|
@@ -23894,22 +24312,22 @@ init_project_launch();
|
|
|
23894
24312
|
init_local_origin();
|
|
23895
24313
|
init_boot_progress();
|
|
23896
24314
|
init_frizz_paths();
|
|
23897
|
-
init_project_root();
|
|
23898
|
-
init_logging();
|
|
23899
|
-
init_src();
|
|
23900
|
-
init_project_registry();
|
|
23901
24315
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
23902
24316
|
import { createServer as createServer2 } from "node:net";
|
|
23903
24317
|
import { existsSync as existsSync5, mkdirSync as mkdirSync10, mkdtempSync, readdirSync as readdirSync3, readFileSync as readFileSync11, realpathSync as realpathSync5, rmSync as rmSync8, symlinkSync as symlinkSync2, writeFileSync as writeFileSync10 } from "node:fs";
|
|
23904
24318
|
import { homedir as homedir10, tmpdir as tmpdir2 } from "node:os";
|
|
23905
|
-
import { basename as basename5, join as join13, resolve as
|
|
24319
|
+
import { basename as basename5, dirname as dirname10, join as join13, resolve as resolve4 } from "node:path";
|
|
23906
24320
|
import { setTimeout as delay2 } from "node:timers/promises";
|
|
24321
|
+
init_project_root();
|
|
24322
|
+
init_logging();
|
|
24323
|
+
init_src();
|
|
24324
|
+
init_project_registry();
|
|
23907
24325
|
var PORT_SCAN_COUNT = 100;
|
|
23908
24326
|
var LAUNCH_TIMEOUT_MS = 3e4;
|
|
23909
24327
|
var LAUNCH_HARD_TIMEOUT_MS = 10 * 6e4;
|
|
23910
24328
|
var RETIRED_NETWORK_FLAGS = ["--host", "--allowed-host", "--public-origin", "--cloud"];
|
|
23911
24329
|
function retiredFlagMessage(flag) {
|
|
23912
|
-
return `${flag} was retired \u2014 how a board is reached is set up from the running board now: press R in its terminal to pick a frizz.sh name, a Cloudflare Tunnel, Tailscale or a proxy of your own. The choice is remembered, so a plain launch serves it.`;
|
|
24330
|
+
return `${flag} was retired \u2014 how a board is reached is set up from the running board now: press R in its terminal to pick a private or custom frizz.sh name, a Cloudflare Tunnel, Tailscale or a proxy of your own. The choice is remembered, so a plain launch serves it.`;
|
|
23913
24331
|
}
|
|
23914
24332
|
function parseCliArgs(argv) {
|
|
23915
24333
|
const args2 = new Set(argv);
|
|
@@ -24042,9 +24460,11 @@ function shareCredentials(realHome, home) {
|
|
|
24042
24460
|
} catch {
|
|
24043
24461
|
}
|
|
24044
24462
|
};
|
|
24045
|
-
|
|
24046
|
-
|
|
24047
|
-
|
|
24463
|
+
const realKey = claimIdentityPath(realHome);
|
|
24464
|
+
const sandboxKey = claimIdentityPath(home);
|
|
24465
|
+
mkdirSync10(dirname10(realKey), { recursive: true });
|
|
24466
|
+
mkdirSync10(dirname10(sandboxKey), { recursive: true });
|
|
24467
|
+
link(realKey, sandboxKey);
|
|
24048
24468
|
if (existsSync5(join13(realHome, ".config", "gh"))) {
|
|
24049
24469
|
mkdirSync10(join13(home, ".config"), { recursive: true });
|
|
24050
24470
|
link(join13(realHome, ".config", "gh"), join13(home, ".config", "gh"));
|
|
@@ -24326,7 +24746,7 @@ import { fork } from "node:child_process";
|
|
|
24326
24746
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
24327
24747
|
import { existsSync as existsSync6, mkdirSync as mkdirSync11, readFileSync as readFileSync12 } from "node:fs";
|
|
24328
24748
|
import { createServer as createNetServer } from "node:net";
|
|
24329
|
-
import { basename as basename6, dirname as
|
|
24749
|
+
import { basename as basename6, dirname as dirname11, extname as extname2, isAbsolute as isAbsolute4, relative as relative2, resolve as resolve5, sep as sep3 } from "node:path";
|
|
24330
24750
|
import { fileURLToPath } from "node:url";
|
|
24331
24751
|
import watcher from "@parcel/watcher";
|
|
24332
24752
|
init_logging();
|
|
@@ -24417,29 +24837,29 @@ function createSupervisorShutdownHandler(options2) {
|
|
|
24417
24837
|
);
|
|
24418
24838
|
};
|
|
24419
24839
|
}
|
|
24420
|
-
var packagesDir =
|
|
24421
|
-
var workspaceDir =
|
|
24840
|
+
var packagesDir = resolve5(import.meta.dirname, "..", "..");
|
|
24841
|
+
var workspaceDir = resolve5(packagesDir, "..");
|
|
24422
24842
|
var INITIAL_BOOT_REASON = "initial boot";
|
|
24423
24843
|
function defaultDevWatchRoots() {
|
|
24424
24844
|
return [workspaceDir];
|
|
24425
24845
|
}
|
|
24426
24846
|
function isWithin(path, root) {
|
|
24427
|
-
const rel =
|
|
24428
|
-
return rel === "" || rel !== ".." && !rel.startsWith(`..${
|
|
24847
|
+
const rel = relative2(root, path);
|
|
24848
|
+
return rel === "" || rel !== ".." && !rel.startsWith(`..${sep3}`) && !isAbsolute4(rel);
|
|
24429
24849
|
}
|
|
24430
24850
|
function ignoredDevPath(path) {
|
|
24431
|
-
const parts =
|
|
24851
|
+
const parts = resolve5(path).split(sep3);
|
|
24432
24852
|
const name = parts.at(-1) ?? "";
|
|
24433
24853
|
return parts.some((part) => GENERATED_DIRS.has(part) || part === "fixtures" || part.endsWith(".fixtures")) || /\.(?:test|spec)\.[^.]+$/.test(name) || name.includes(".golden.");
|
|
24434
24854
|
}
|
|
24435
24855
|
function classifyDevChange(path, roots = defaultDevWatchRoots()) {
|
|
24436
|
-
const absolute =
|
|
24437
|
-
const root = roots.find((candidate) => isWithin(absolute,
|
|
24856
|
+
const absolute = resolve5(path);
|
|
24857
|
+
const root = roots.find((candidate) => isWithin(absolute, resolve5(candidate)));
|
|
24438
24858
|
if (!root) return null;
|
|
24439
24859
|
if (ignoredDevPath(absolute)) return null;
|
|
24440
24860
|
const name = basename6(absolute);
|
|
24441
|
-
const relToWorkspace =
|
|
24442
|
-
const parts = relToWorkspace.split(
|
|
24861
|
+
const relToWorkspace = relative2(resolve5(root), absolute);
|
|
24862
|
+
const parts = relToWorkspace.split(sep3);
|
|
24443
24863
|
const packageName = parts[0] === "packages" ? parts[1] : void 0;
|
|
24444
24864
|
if (name === "package.json" && parts.length === 3 && packageName && CHILD_PACKAGE_METADATA.has(packageName)) {
|
|
24445
24865
|
return "child";
|
|
@@ -24586,10 +25006,10 @@ var Supervisor = class {
|
|
|
24586
25006
|
if (launchOwner.pid !== callerGeneration.pid || launchOwner.processStart !== callerGeneration.processStart) throw new Error("dev supervisor caller is not the exact project launch owner");
|
|
24587
25007
|
this.port = opts.port;
|
|
24588
25008
|
this.launchTarget = opts.launchTarget;
|
|
24589
|
-
this.cwd =
|
|
25009
|
+
this.cwd = resolve5(opts.cwd ?? opts.launchTarget.projectDir);
|
|
24590
25010
|
if (this.cwd !== opts.launchTarget.projectDir) throw new Error("dev supervisor cwd does not match its owned project");
|
|
24591
25011
|
this.parentEnv = projectLaunchEnvironment(opts.env ?? process.env, opts.launchTarget, opts.launchOwnerToken);
|
|
24592
|
-
this.roots = (opts.watchRoots ?? defaultDevWatchRoots()).map((root) =>
|
|
25012
|
+
this.roots = (opts.watchRoots ?? defaultDevWatchRoots()).map((root) => resolve5(root));
|
|
24593
25013
|
this.watchEnabled = opts.watch !== false;
|
|
24594
25014
|
this.childEnvironment = opts.childEnvironment ?? (() => ({}));
|
|
24595
25015
|
this.debounceMs = opts.debounceMs ?? DEV_RESTART_DEBOUNCE_MS;
|
|
@@ -24599,10 +25019,10 @@ var Supervisor = class {
|
|
|
24599
25019
|
this.childArgs = opts.childArgs ?? [];
|
|
24600
25020
|
this.watchSubscribe = opts.watchSubscribe ?? ((root, callback, options2) => watcher.subscribe(root, callback, options2));
|
|
24601
25021
|
this.reexec = opts.reexec ?? (typeof process.execve === "function" ? (request) => process.execve(request.executable, request.argv, request.env) : void 0);
|
|
24602
|
-
if (opts.stateDir &&
|
|
25022
|
+
if (opts.stateDir && resolve5(opts.stateDir) !== opts.launchTarget.stateDir) {
|
|
24603
25023
|
throw new Error("dev supervisor state directory does not match its owned project");
|
|
24604
25024
|
}
|
|
24605
|
-
this.supervisorLock =
|
|
25025
|
+
this.supervisorLock = resolve5(opts.launchTarget.stateDir, "dev-supervisor.lock");
|
|
24606
25026
|
this.ownerToken = opts.launchOwnerToken;
|
|
24607
25027
|
this.logLine = opts.log ?? ((line) => log.info("supervisor", stripPrefix(line)));
|
|
24608
25028
|
this.errorLine = opts.error ?? ((line) => log.error("supervisor", stripPrefix(line)));
|
|
@@ -24654,7 +25074,7 @@ var Supervisor = class {
|
|
|
24654
25074
|
}
|
|
24655
25075
|
async start() {
|
|
24656
25076
|
if (this.supervisorLock) {
|
|
24657
|
-
mkdirSync11(
|
|
25077
|
+
mkdirSync11(dirname11(this.supervisorLock), { recursive: true });
|
|
24658
25078
|
this.writeStatus("starting", "watcher initializing");
|
|
24659
25079
|
}
|
|
24660
25080
|
try {
|
|
@@ -24709,7 +25129,7 @@ var Supervisor = class {
|
|
|
24709
25129
|
return;
|
|
24710
25130
|
}
|
|
24711
25131
|
this.crashAttempts = 0;
|
|
24712
|
-
this.requestRestart(
|
|
25132
|
+
this.requestRestart(relative2(workspaceDir, relevant.path), false, kind === "launcher");
|
|
24713
25133
|
}
|
|
24714
25134
|
}
|
|
24715
25135
|
requestRestart(reason, immediate = false, reloadLauncher = false, delayMs = this.debounceMs) {
|
|
@@ -25187,7 +25607,7 @@ var npmRegistryReleaseAdapter = {
|
|
|
25187
25607
|
import { spawnSync } from "node:child_process";
|
|
25188
25608
|
import { chmodSync as chmodSync2, statSync as statSync5 } from "node:fs";
|
|
25189
25609
|
import { createRequire } from "node:module";
|
|
25190
|
-
import { dirname as
|
|
25610
|
+
import { dirname as dirname12, join as join14 } from "node:path";
|
|
25191
25611
|
var SUPPORTED_NODE_LINES = [
|
|
25192
25612
|
{ major: 22, minor: 13 },
|
|
25193
25613
|
{ major: 23, minor: 4 }
|
|
@@ -25239,7 +25659,7 @@ function ensureNativeHelperPermissions(options2 = {}) {
|
|
|
25239
25659
|
const resolvePty = options2.resolvePty ?? (() => createRequire(import.meta.url).resolve("node-pty/package.json"));
|
|
25240
25660
|
try {
|
|
25241
25661
|
const helper = join14(
|
|
25242
|
-
|
|
25662
|
+
dirname12(resolvePty()),
|
|
25243
25663
|
"prebuilds",
|
|
25244
25664
|
`${platform}-${options2.arch ?? process.arch}`,
|
|
25245
25665
|
"spawn-helper"
|
|
@@ -25304,7 +25724,8 @@ Options:
|
|
|
25304
25724
|
|
|
25305
25725
|
|
|
25306
25726
|
To reach the board from a phone or another machine, press R in the terminal running it: a short
|
|
25307
|
-
walkthrough sets up a frizz.sh name
|
|
25727
|
+
walkthrough sets up a private frizz.sh name (no account needed), a custom one, a Cloudflare
|
|
25728
|
+
Tunnel, Tailscale, or a proxy of your own, and
|
|
25308
25729
|
remembers the choice, so a plain launch serves it from then on. The board stays on loopback and
|
|
25309
25730
|
shows a single-use sign-in link as a QR; press L for a fresh one, or run --link from another shell.`
|
|
25310
25731
|
);
|