frizz 0.8.0 → 0.9.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 +73 -2
- package/dist/dev-child.js +4052 -1861
- package/dist/frizz.js +621 -260
- 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 +7 -0
- package/runtime/cc-worker/agents/high.md +1 -1
- package/runtime/cc-worker/agents/low.md +1 -1
- package/runtime/cc-worker/agents/max.md +1 -1
- package/runtime/cc-worker/agents/medium.md +1 -1
- package/runtime/cc-worker/agents/xhigh.md +1 -1
- package/runtime/cc-worker/bin/frizz-mcp.mjs +561 -46
- package/runtime/cc-worker/hooks/agent-dispatch.mjs +4 -4
- 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-BIBHC61j.js → TerminalPane-CNFymHXK.js} +1 -1
- package/web-dist/assets/{abnfDiagram-VRR7QNED-CcFQGFPf.js → abnfDiagram-VRR7QNED-DNBrcJfV.js} +1 -1
- package/web-dist/assets/architecture-TIHT7OUA-BSUDKbro.js +1 -0
- package/web-dist/assets/{architectureDiagram-ZJ3FMSHR-DErIQOIs.js → architectureDiagram-ZJ3FMSHR-SXVydqly.js} +1 -1
- package/web-dist/assets/{blockDiagram-677ZJIJ3-CpsUqur1.js → blockDiagram-677ZJIJ3-CgI1GSdx.js} +1 -1
- package/web-dist/assets/{c4Diagram-LMCZKHZV-D2dHmCEJ.js → c4Diagram-LMCZKHZV-KDmJm2tG.js} +1 -1
- package/web-dist/assets/channel-DaCOnTxr.js +1 -0
- package/web-dist/assets/{chunk-32BRIVSS-aOCEfxRW.js → chunk-32BRIVSS-j3eOjq4Z.js} +1 -1
- package/web-dist/assets/{chunk-52WLFC77-2iw4nJPC.js → chunk-52WLFC77-DZHfa78H.js} +1 -1
- package/web-dist/assets/{chunk-C7G6YPKG-BPD3iHVE.js → chunk-C7G6YPKG-CiB5uo24.js} +1 -1
- package/web-dist/assets/{chunk-EX3LRPZG-DrefHift.js → chunk-EX3LRPZG-B35Inyjz.js} +1 -1
- package/web-dist/assets/{chunk-FWX5IMBZ-By940EHT.js → chunk-FWX5IMBZ-D2sRvM5U.js} +2 -2
- package/web-dist/assets/{chunk-HOUHSVGY-B1Cqvz7e.js → chunk-HOUHSVGY-D247PDv6.js} +1 -1
- package/web-dist/assets/{chunk-ICXQ74PX-1LkVpWuI.js → chunk-ICXQ74PX-Bu3Tb6Ec.js} +1 -1
- package/web-dist/assets/{chunk-MOJQB5TN-Ip1cy64r.js → chunk-MOJQB5TN-C_lQy4on.js} +1 -1
- package/web-dist/assets/{chunk-OGEWGWER-CNjVyu8F.js → chunk-OGEWGWER-DU5ZBedR.js} +1 -1
- package/web-dist/assets/{chunk-PUDLZKDR-9HZR6DAU.js → chunk-PUDLZKDR-DWRT7ztS.js} +1 -1
- package/web-dist/assets/{chunk-Q4XR5HBZ-vtWwOCuQ.js → chunk-Q4XR5HBZ-CCX4AK_n.js} +1 -1
- package/web-dist/assets/{chunk-V7JOEXUC-DC6YaHG0.js → chunk-V7JOEXUC-VbixbkDG.js} +1 -1
- package/web-dist/assets/{chunk-VAUOI2AC-CP-xe7SD.js → chunk-VAUOI2AC-PJvChxMA.js} +1 -1
- package/web-dist/assets/{chunk-VR4S4FIN-wbxDFptH.js → chunk-VR4S4FIN-BjsMfxj8.js} +1 -1
- package/web-dist/assets/{chunk-WYO6CB5R-dibXmwpK.js → chunk-WYO6CB5R-Bcb97r3w.js} +1 -1
- package/web-dist/assets/{chunk-ZGVPDNZ5-_y_itJHG.js → chunk-ZGVPDNZ5-CT2sZlhT.js} +1 -1
- package/web-dist/assets/classDiagram-OUVF2IWQ-BlylbZXV.js +1 -0
- package/web-dist/assets/classDiagram-v2-EOCWNBFH-BlylbZXV.js +1 -0
- package/web-dist/assets/{cynefin-VYW2F7L2-D1RYokZP.js → cynefin-VYW2F7L2-dUpO4u0w.js} +1 -1
- package/web-dist/assets/{cynefinDiagram-TSTJHNR4-qofqoy3T.js → cynefinDiagram-TSTJHNR4-BQZ3UIsx.js} +1 -1
- package/web-dist/assets/{dagre-VKFMJZFB-CgHLoGFk.js → dagre-VKFMJZFB-K-oO8w51.js} +1 -1
- package/web-dist/assets/{diagram-FQU43EPY-JEAs4LOb.js → diagram-FQU43EPY-Cr47GJ_S.js} +1 -1
- package/web-dist/assets/{diagram-G47NLZAW--tLd4Lf7.js → diagram-G47NLZAW-BbWzSkoZ.js} +1 -1
- package/web-dist/assets/{diagram-NH7WQ7WH-DPbw9CJU.js → diagram-NH7WQ7WH-BGJJBgGM.js} +1 -1
- package/web-dist/assets/{diagram-OA4YK3LP-CDrb7nWs.js → diagram-OA4YK3LP-2W7aunEN.js} +1 -1
- package/web-dist/assets/{diagram-WEI45ONY-DJswZe3f.js → diagram-WEI45ONY-D-4ITFI6.js} +1 -1
- package/web-dist/assets/{ebnfDiagram-CCIWWBDH-BP8-PZMF.js → ebnfDiagram-CCIWWBDH-CxUcx103.js} +1 -1
- package/web-dist/assets/{erDiagram-Q63AITRT-BQXuebf5.js → erDiagram-Q63AITRT-Cf_5SWAE.js} +1 -1
- package/web-dist/assets/eventmodeling-45OFAUF4-DxKQnZNV.js +1 -0
- package/web-dist/assets/flowDiagram-23GEKE2U-Cdz9YM2Z.js +1 -0
- package/web-dist/assets/{ganttDiagram-NO4QXBWP-DotMb935.js → ganttDiagram-NO4QXBWP-CVZI8Ywa.js} +1 -1
- package/web-dist/assets/{gitGraph-TEB2WS4Q-B1vbYyKQ.js → gitGraph-TEB2WS4Q-BsiGpR9l.js} +1 -1
- package/web-dist/assets/{gitGraphDiagram-IHSO6WYX-BjDXKk4m.js → gitGraphDiagram-IHSO6WYX-DVym_4l1.js} +1 -1
- package/web-dist/assets/index-CYzJK7u0.js +497 -0
- package/web-dist/assets/index-CovJDCWc.css +1 -0
- package/web-dist/assets/{info-DKCQHKI2-xLTLqQju.js → info-DKCQHKI2-DYcsKFv-.js} +1 -1
- package/web-dist/assets/{infoDiagram-FWYZ7A6U-BFfYUsrC.js → infoDiagram-FWYZ7A6U-hjVxlrTT.js} +1 -1
- package/web-dist/assets/{ishikawaDiagram-FXEZZL3T-45a7VMwm.js → ishikawaDiagram-FXEZZL3T-B0DKOPSS.js} +1 -1
- package/web-dist/assets/{journeyDiagram-5HDEW3XC-CEBUpu59.js → journeyDiagram-5HDEW3XC-Cohibc5O.js} +1 -1
- package/web-dist/assets/{kanban-definition-HUTT4EX6-RwKtDFzG.js → kanban-definition-HUTT4EX6-_6Zr31vM.js} +1 -1
- package/web-dist/assets/{line-DStcMIry.js → line-B14EZI6M.js} +1 -1
- package/web-dist/assets/{mermaid-parser.core-B0ekgQMA.js → mermaid-parser.core-DHkc6cqw.js} +3 -3
- package/web-dist/assets/{mermaid.core-w1hcQaPy.js → mermaid.core-DuTvdsKf.js} +3 -3
- package/web-dist/assets/{mindmap-definition-LN4V7U3C-D_n38Imb.js → mindmap-definition-LN4V7U3C-DPRF9pW2.js} +1 -1
- package/web-dist/assets/{packet-7NZHBO7P-CstGeBOX.js → packet-7NZHBO7P-Ci8oCcGM.js} +1 -1
- package/web-dist/assets/{pegDiagram-2B236MQR-DvowVyTO.js → pegDiagram-2B236MQR-Cr3ctC6e.js} +1 -1
- package/web-dist/assets/{pie-RZYD4A2V-BOP2j_HH.js → pie-RZYD4A2V-EHgA307y.js} +1 -1
- package/web-dist/assets/{pieDiagram-ENE6RG2P-CKRqu_2f.js → pieDiagram-ENE6RG2P-UW6Bmu6F.js} +1 -1
- package/web-dist/assets/{quadrantDiagram-ABIIQ3AL-zSArSS8R.js → quadrantDiagram-ABIIQ3AL-D6tAsRj9.js} +1 -1
- package/web-dist/assets/{radar-I7S5WNFK-BqRdNIBw.js → radar-I7S5WNFK-CAQqojcd.js} +1 -1
- package/web-dist/assets/{railroad-3IZDKUUU-BaKcl_LU.js → railroad-3IZDKUUU-BZsAOTrm.js} +1 -1
- package/web-dist/assets/railroad-abnf-AHOZXSZD-_2rSHfPz.js +1 -0
- package/web-dist/assets/railroad-ebnf-EBAXGLYW-xM3eAMFz.js +1 -0
- package/web-dist/assets/railroad-peg-LSFZ7HO6-cZlBUsED.js +1 -0
- package/web-dist/assets/{railroadDiagram-RFXS5EU6-BrXTQge9.js → railroadDiagram-RFXS5EU6-bSpff55H.js} +1 -1
- package/web-dist/assets/{requirementDiagram-TGXJPOKE-DBBNi_SS.js → requirementDiagram-TGXJPOKE-DIAYvXoB.js} +1 -1
- package/web-dist/assets/{sankeyDiagram-HTMAVEWB-BwFi7xFy.js → sankeyDiagram-HTMAVEWB-DEnsSz3F.js} +1 -1
- package/web-dist/assets/{sequenceDiagram-DBY2YBRQ-CeivqMeT.js → sequenceDiagram-DBY2YBRQ-DsG7eb9R.js} +1 -1
- package/web-dist/assets/{stateDiagram-2N3HPSRC-C6NZsnFm.js → stateDiagram-2N3HPSRC-DT3XNwjo.js} +1 -1
- package/web-dist/assets/stateDiagram-v2-6OUMAXLB-C06v0Ltu.js +1 -0
- package/web-dist/assets/{swimlanes-5IMT3BWC-C0MubXTG.js → swimlanes-5IMT3BWC-B5hZwgRo.js} +1 -1
- package/web-dist/assets/swimlanesDiagram-G3AALYLV-CXyN7ZyO.js +8 -0
- package/web-dist/assets/{timeline-definition-FHXFAJF6-CtxwSvFu.js → timeline-definition-FHXFAJF6-BVTsjkfu.js} +1 -1
- package/web-dist/assets/{treeView-QDETBFTQ-CXcwSjey.js → treeView-QDETBFTQ-M6HmP4bB.js} +1 -1
- package/web-dist/assets/{treemap-6X3UGDF4-Uspgr-d1.js → treemap-6X3UGDF4-C60TppfC.js} +1 -1
- package/web-dist/assets/{vennDiagram-L72KCM5P-tZamQQAQ.js → vennDiagram-L72KCM5P-Dv1y3g4S.js} +1 -1
- package/web-dist/assets/{wardley-OPB4EBWU-0_79c19P.js → wardley-OPB4EBWU-D0lMJMWt.js} +1 -1
- package/web-dist/assets/{wardleyDiagram-EHGQE667-uYmUsP66.js → wardleyDiagram-EHGQE667-B1E5NtZY.js} +1 -1
- package/web-dist/assets/{xychartDiagram-FW5EYKEG-BsOU7Wf7.js → xychartDiagram-FW5EYKEG-oA91YOvh.js} +1 -1
- package/web-dist/index.html +2 -2
- package/web-dist/assets/architecture-TIHT7OUA-BZEZt7jZ.js +0 -1
- package/web-dist/assets/channel-DdFRPviT.js +0 -1
- package/web-dist/assets/classDiagram-OUVF2IWQ-Bf3duLb8.js +0 -1
- package/web-dist/assets/classDiagram-v2-EOCWNBFH-Bf3duLb8.js +0 -1
- package/web-dist/assets/eventmodeling-45OFAUF4-DOLxRQQ5.js +0 -1
- package/web-dist/assets/flowDiagram-23GEKE2U-DoK1yb0H.js +0 -1
- package/web-dist/assets/index-CmrDpsD8.css +0 -1
- package/web-dist/assets/index-Cs0TDGMu.js +0 -491
- package/web-dist/assets/railroad-abnf-AHOZXSZD-itqDLg1p.js +0 -1
- package/web-dist/assets/railroad-ebnf-EBAXGLYW-ze7rLVCi.js +0 -1
- package/web-dist/assets/railroad-peg-LSFZ7HO6-DKsYkEuG.js +0 -1
- package/web-dist/assets/stateDiagram-v2-6OUMAXLB-B3YRnI4W.js +0 -1
- package/web-dist/assets/swimlanesDiagram-G3AALYLV-CXva4Ic9.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, 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_DEFAULT_FOR_MS, PrWatchView, AddOwnPrWatchInput, AddOwnPrWatchResult, DropOwnPrWatchInput, DropOwnPrWatchResult, OwnWatchKind, AddOwnWatchInput, OwnWatchView, AddOwnWatchResult, DropOwnWatchInput, DropOwnWatchResult, AskQuestionKind, ASK_MAX_PER_CALL, ASK_MAX_OPEN, 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, 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, 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
|
|
@@ -12898,6 +12954,137 @@ var init_src = __esm({
|
|
|
12898
12954
|
dropped: external_exports.boolean(),
|
|
12899
12955
|
watches: external_exports.array(PrWatchView)
|
|
12900
12956
|
}).strict();
|
|
12957
|
+
OwnWatchKind = external_exports.enum(["shell", "agent"]);
|
|
12958
|
+
AddOwnWatchInput = external_exports.object({
|
|
12959
|
+
slug: ThreadSlug,
|
|
12960
|
+
/** What KIND of thing the target is. Stored, and checked against the thread's live telemetry before the
|
|
12961
|
+
* row is written — see the note on `target`. */
|
|
12962
|
+
kind: OwnWatchKind,
|
|
12963
|
+
/** The handle the worker was shown: a runtime task id ("Command running in background with ID: …"), a
|
|
12964
|
+
* launch tool_use id, or the op's own label.
|
|
12965
|
+
*
|
|
12966
|
+
* VALIDATED AGAINST LIVE TELEMETRY, NOT AGAINST ITS SHAPE. A PR ref is checkable by shape because
|
|
12967
|
+
* `owner/repo#123` looks like nothing else; a shell handle and a sub-agent handle are both opaque
|
|
12968
|
+
* runtime strings and overlap completely, so shape can only ever be a guess. What frizz CAN answer
|
|
12969
|
+
* exactly is whether this thread has a live shell — or a live sub-agent — answering to this handle, and
|
|
12970
|
+
* that is both the stronger check and the one that catches the real mistake: naming a sub-agent under
|
|
12971
|
+
* `kind: "shell"`, which is what put two sub-agents under a "Background shells" heading on 2026-08-26. */
|
|
12972
|
+
target: external_exports.string().trim().min(1).max(200),
|
|
12973
|
+
/** REQUIRED, and a DURATION (`30m`, `2h`, `3d` — parseAwaitingDuration, capped at 24h).
|
|
12974
|
+
*
|
|
12975
|
+
* No default and no wire-level optionality, unlike `AddOwnPrWatchInput.for`: that field is optional
|
|
12976
|
+
* only to keep working for sessions dispatched before it existed, and this RPC has no such sessions.
|
|
12977
|
+
* On elapse the row is CANCELLED and the thread woken to re-decide, which is what stops a registration
|
|
12978
|
+
* outliving its own relevance — the one thing an un-restated fence could never do wrong. */
|
|
12979
|
+
for: external_exports.string().trim().min(1).max(16)
|
|
12980
|
+
}).strict();
|
|
12981
|
+
OwnWatchView = external_exports.object({
|
|
12982
|
+
id: external_exports.string(),
|
|
12983
|
+
kind: OwnWatchKind,
|
|
12984
|
+
target: external_exports.string(),
|
|
12985
|
+
/** The op's own label where the target resolved to one, so a read-back names the work rather than an
|
|
12986
|
+
* opaque handle. Absent when the target no longer resolves — the row still stands and names itself. */
|
|
12987
|
+
label: external_exports.string().optional(),
|
|
12988
|
+
createdAt: external_exports.string(),
|
|
12989
|
+
expiresAt: external_exports.string()
|
|
12990
|
+
}).strict();
|
|
12991
|
+
AddOwnWatchResult = external_exports.object({
|
|
12992
|
+
id: external_exports.string(),
|
|
12993
|
+
kind: OwnWatchKind,
|
|
12994
|
+
target: external_exports.string(),
|
|
12995
|
+
/** True when this exact (kind, target) was already watched, so the call registered nothing new and the
|
|
12996
|
+
* existing expiry stands. Re-registering after a wake or a compaction is the common, correct case. */
|
|
12997
|
+
alreadyArmed: external_exports.boolean(),
|
|
12998
|
+
watches: external_exports.array(OwnWatchView)
|
|
12999
|
+
}).strict();
|
|
13000
|
+
DropOwnWatchInput = external_exports.object({
|
|
13001
|
+
slug: ThreadSlug,
|
|
13002
|
+
id: external_exports.string().min(1).max(64)
|
|
13003
|
+
}).strict();
|
|
13004
|
+
DropOwnWatchResult = external_exports.object({
|
|
13005
|
+
dropped: external_exports.boolean(),
|
|
13006
|
+
watches: external_exports.array(OwnWatchView)
|
|
13007
|
+
}).strict();
|
|
13008
|
+
AskQuestionKind = external_exports.enum(["question", "multi"]);
|
|
13009
|
+
ASK_MAX_PER_CALL = 4;
|
|
13010
|
+
ASK_MAX_OPEN = 12;
|
|
13011
|
+
AskedOptionSchema = external_exports.lazy(() => external_exports.object({
|
|
13012
|
+
label: external_exports.string().trim().min(1).max(120),
|
|
13013
|
+
description: external_exports.string().trim().max(400).optional(),
|
|
13014
|
+
recommended: external_exports.boolean().optional(),
|
|
13015
|
+
preview: external_exports.string().max(4e3).optional(),
|
|
13016
|
+
followUps: external_exports.array(AskedQuestionSchema).max(ASK_MAX_PER_CALL).optional()
|
|
13017
|
+
}).strict());
|
|
13018
|
+
AskedQuestionSchema = external_exports.lazy(() => external_exports.object({
|
|
13019
|
+
question: external_exports.string().trim().min(1).max(600),
|
|
13020
|
+
header: external_exports.string().trim().max(24).optional(),
|
|
13021
|
+
kind: AskQuestionKind,
|
|
13022
|
+
danger: external_exports.boolean().optional(),
|
|
13023
|
+
options: external_exports.array(AskedOptionSchema).max(8).optional()
|
|
13024
|
+
}).strict());
|
|
13025
|
+
AskInput = external_exports.object({
|
|
13026
|
+
slug: ThreadSlug,
|
|
13027
|
+
questions: external_exports.array(AskedQuestionSchema).min(1).max(ASK_MAX_PER_CALL)
|
|
13028
|
+
}).strict();
|
|
13029
|
+
RegisteredQuestionView = external_exports.object({
|
|
13030
|
+
/** Minted by frizz. The worker never chose it, which is why an answer RESTATES the question text —
|
|
13031
|
+
* an id alone cannot be correlated back to what was asked. */
|
|
13032
|
+
id: external_exports.string(),
|
|
13033
|
+
spec: AskedQuestionSchema,
|
|
13034
|
+
askedAt: external_exports.string()
|
|
13035
|
+
}).strict();
|
|
13036
|
+
AskResult = external_exports.object({
|
|
13037
|
+
registered: external_exports.array(RegisteredQuestionView),
|
|
13038
|
+
/** Everything still open on this thread afterwards, so a worker never needs a second call. */
|
|
13039
|
+
open: external_exports.array(RegisteredQuestionView)
|
|
13040
|
+
}).strict();
|
|
13041
|
+
UnaskInput = external_exports.object({
|
|
13042
|
+
slug: ThreadSlug,
|
|
13043
|
+
id: external_exports.string().min(1).max(64)
|
|
13044
|
+
}).strict();
|
|
13045
|
+
UnaskResult = external_exports.object({
|
|
13046
|
+
withdrawn: external_exports.boolean(),
|
|
13047
|
+
open: external_exports.array(RegisteredQuestionView)
|
|
13048
|
+
}).strict();
|
|
13049
|
+
QuestionAnswerSchema = external_exports.lazy(() => external_exports.object({
|
|
13050
|
+
questionId: external_exports.string().min(1).max(64),
|
|
13051
|
+
question: external_exports.string().min(1).max(600),
|
|
13052
|
+
chosen: external_exports.array(external_exports.string().max(200)).max(8),
|
|
13053
|
+
text: external_exports.string().max(8e3).optional(),
|
|
13054
|
+
followUps: external_exports.array(QuestionAnswerSchema).max(ASK_MAX_PER_CALL).optional()
|
|
13055
|
+
}).strict());
|
|
13056
|
+
AnswerQuestionsInput = external_exports.object({
|
|
13057
|
+
slug: ThreadSlug,
|
|
13058
|
+
/** SUBMITTED AS A UNIT. The card sends whatever was answered in one call, because a per-question send
|
|
13059
|
+
* would half-wake a turn: the worker would come back to a payload it cannot act on and would have to
|
|
13060
|
+
* ask again for the rest. */
|
|
13061
|
+
answers: external_exports.array(QuestionAnswerSchema).min(1).max(ASK_MAX_OPEN)
|
|
13062
|
+
}).strict();
|
|
13063
|
+
AnswerQuestionsResult = external_exports.object({
|
|
13064
|
+
/** The ids that were open and are now answered. An id that was already settled is silently absent
|
|
13065
|
+
* rather than an error: two browser tabs answering the same card is a race nobody should see. */
|
|
13066
|
+
answered: external_exports.array(external_exports.string()),
|
|
13067
|
+
open: external_exports.array(RegisteredQuestionView)
|
|
13068
|
+
}).strict();
|
|
13069
|
+
DismissQuestionsInput = external_exports.object({
|
|
13070
|
+
slug: ThreadSlug,
|
|
13071
|
+
ids: external_exports.array(external_exports.string().min(1).max(64)).min(1).max(ASK_MAX_OPEN)
|
|
13072
|
+
}).strict();
|
|
13073
|
+
DismissQuestionsResult = external_exports.object({
|
|
13074
|
+
dismissed: external_exports.array(external_exports.string()),
|
|
13075
|
+
open: external_exports.array(RegisteredQuestionView)
|
|
13076
|
+
}).strict();
|
|
13077
|
+
MarkOwnDoneInput = external_exports.object({
|
|
13078
|
+
slug: ThreadSlug,
|
|
13079
|
+
body: external_exports.string().trim().min(1).max(2e4)
|
|
13080
|
+
}).strict();
|
|
13081
|
+
MarkOwnDoneResult = external_exports.object({
|
|
13082
|
+
done: external_exports.boolean(),
|
|
13083
|
+
/** Open questions, by id and question text. */
|
|
13084
|
+
blockingQuestions: external_exports.array(external_exports.object({ id: external_exports.string(), question: external_exports.string() }).strict()),
|
|
13085
|
+
/** Armed registrations, by id and what each names. Watches, PR watchers and timers alike. */
|
|
13086
|
+
blockingWatches: external_exports.array(external_exports.object({ id: external_exports.string(), what: external_exports.string() }).strict())
|
|
13087
|
+
}).strict();
|
|
12901
13088
|
ListOwnPrWatchesInput = external_exports.object({ slug: ThreadSlug }).strict();
|
|
12902
13089
|
OwnPrWatchesResult = external_exports.object({ watches: external_exports.array(PrWatchView) }).strict();
|
|
12903
13090
|
ThreadTimerView = external_exports.object({
|
|
@@ -12912,9 +13099,15 @@ var init_src = __esm({
|
|
|
12912
13099
|
kind: external_exports.enum(["done", "awaiting"]),
|
|
12913
13100
|
body: external_exports.string(),
|
|
12914
13101
|
// fence body minus hint lines, capped server-side; may be ""
|
|
12915
|
-
hints: external_exports.array(AwaitingHint).default([])
|
|
13102
|
+
hints: external_exports.array(AwaitingHint).default([]),
|
|
13103
|
+
// Present only on a completion the worker REGISTERED (`mcp__frizz__done`, board.registeredDoneFence)
|
|
13104
|
+
// rather than wrote as a ```done fence in its final message. The two are one fence to every predicate,
|
|
13105
|
+
// but the TRANSCRIPT draws a fence card from the message text it parses — so a registered done, which
|
|
13106
|
+
// is in no message, needs the client to know it must draw the card itself at the bottom of the thread
|
|
13107
|
+
// (maintainer 2026-08-27: a thread that signed off by tool rested with no card at all).
|
|
13108
|
+
registered: external_exports.literal(true).optional()
|
|
12916
13109
|
});
|
|
12917
|
-
LimitWindow = external_exports.enum(["session", "weekly", "unknown"]);
|
|
13110
|
+
LimitWindow = external_exports.enum(["session", "weekly", "model", "unknown"]);
|
|
12918
13111
|
LimitPause = external_exports.object({
|
|
12919
13112
|
backend: Backend,
|
|
12920
13113
|
window: LimitWindow,
|
|
@@ -13008,6 +13201,18 @@ var init_src = __esm({
|
|
|
13008
13201
|
// Derived safety net (tailer): at rest with an unanswered ```question the worker asked in chat but
|
|
13009
13202
|
// never encoded as blocked. Defaults false so old snapshots/rows parse. Feeds needsAction.
|
|
13010
13203
|
pendingQuestion: external_exports.boolean().default(false),
|
|
13204
|
+
// The worker's REGISTERED questions, still open (thread_question). Distinct from `pendingQuestion`
|
|
13205
|
+
// beside it, and the difference is the whole point of the registry: that boolean is recomputed from
|
|
13206
|
+
// the LATEST assistant text on every assistant record and cleared by any human turn, so it cannot
|
|
13207
|
+
// outlive the message that carried it. These rows can, and they carry the question itself rather than
|
|
13208
|
+
// merely asserting one exists — the card renders from this instead of re-parsing prose.
|
|
13209
|
+
questions: external_exports.array(RegisteredQuestionView).default([]),
|
|
13210
|
+
/** The answer the human has already SENT that the worker has not received yet, as the exact message
|
|
13211
|
+
* the delivery will carry (board.answersInFlight → questionAnswerMessage). The chat parses it with
|
|
13212
|
+
* the same reader it uses on the delivered turn, so the in-flight card and the landed one are the
|
|
13213
|
+
* same card and the swap is invisible. Absent whenever there is nothing in flight, which is almost
|
|
13214
|
+
* always — it exists for the seconds between the human sending and the worker being handed it. */
|
|
13215
|
+
answersInFlight: external_exports.string().optional(),
|
|
13011
13216
|
// ISO8601 of the newest REAL user interaction (answer/steer/dispatch) — the chronological listing
|
|
13012
13217
|
// sort key. Optional; the listing falls back to spawnedAt when absent (a dispatch IS an interaction).
|
|
13013
13218
|
lastUserAt: external_exports.string().optional(),
|
|
@@ -13193,7 +13398,7 @@ var init_src = __esm({
|
|
|
13193
13398
|
key: external_exports.string(),
|
|
13194
13399
|
// stable id: "5h" | "weekly" (provider-neutral)
|
|
13195
13400
|
label: external_exports.string(),
|
|
13196
|
-
// short human label for the chip ("5h", "Weekly")
|
|
13401
|
+
// short human label for the chip ("5h", "Weekly") — house duration grammar
|
|
13197
13402
|
usedPercent: external_exports.number(),
|
|
13198
13403
|
// 0..100
|
|
13199
13404
|
resetsAt: external_exports.number().optional()
|
|
@@ -13490,13 +13695,25 @@ var init_src = __esm({
|
|
|
13490
13695
|
/** ISO8601 of when it started or was armed — absent when frizz has no instant for it. */
|
|
13491
13696
|
since: external_exports.string().optional(),
|
|
13492
13697
|
/** A timer's fire instant, or a PR's expiry. Absent for shells and sub-agents. */
|
|
13493
|
-
until: external_exports.string().optional()
|
|
13698
|
+
until: external_exports.string().optional(),
|
|
13699
|
+
/** The `wch_…` id of the REGISTERED WATCH holding this item, when the worker armed one — so a readout
|
|
13700
|
+
* that exists to hand ids back also hands back the one `unwatch` takes. A separate ROW per watch was
|
|
13701
|
+
* the alternative and it would list the same shell twice, which is exactly the duplication that put
|
|
13702
|
+
* two sub-agents under a "Background shells" heading. */
|
|
13703
|
+
watchId: external_exports.string().optional()
|
|
13494
13704
|
}).strict();
|
|
13495
13705
|
ListOwnThreadActivityInput = external_exports.object({
|
|
13496
13706
|
slug: ThreadSlug
|
|
13497
13707
|
}).strict();
|
|
13498
13708
|
OwnThreadActivityResult = external_exports.object({
|
|
13499
|
-
activity: external_exports.array(ThreadActivityItem)
|
|
13709
|
+
activity: external_exports.array(ThreadActivityItem),
|
|
13710
|
+
/** Every question still owed an answer. NOT a `ThreadActivityItem` and deliberately its own list: a
|
|
13711
|
+
* question is not running work, it waits on a PERSON, and there is no `questions:` key in the awaiting
|
|
13712
|
+
* fence for it to be written into. Until 2026-08-28 a worker could read its open questions back only
|
|
13713
|
+
* as a side effect of `ask` (which registers another) or `unask` (which withdraws one) — so the ids
|
|
13714
|
+
* that block `done` were readable only by mutating something (maintainer: "Is there a way for the
|
|
13715
|
+
* agent to read out the current set of watchers and questions?"). */
|
|
13716
|
+
questions: external_exports.array(RegisteredQuestionView).default([])
|
|
13500
13717
|
}).strict();
|
|
13501
13718
|
SetOwnThreadTimerResult = external_exports.object({
|
|
13502
13719
|
id: external_exports.string(),
|
|
@@ -13531,6 +13748,15 @@ var init_src = __esm({
|
|
|
13531
13748
|
});
|
|
13532
13749
|
AiRenameThreadInput = external_exports.object({ slug: ThreadSlug });
|
|
13533
13750
|
AiRenameThreadResult = external_exports.object({ title: external_exports.string().min(1).max(200) });
|
|
13751
|
+
SetOwnThreadTitleInput = external_exports.object({
|
|
13752
|
+
slug: ThreadSlug,
|
|
13753
|
+
title: external_exports.string().trim().min(1).max(200)
|
|
13754
|
+
}).strict();
|
|
13755
|
+
SetOwnThreadTitleResult = external_exports.object({
|
|
13756
|
+
accepted: external_exports.boolean(),
|
|
13757
|
+
title: external_exports.string(),
|
|
13758
|
+
lockedByHuman: external_exports.boolean()
|
|
13759
|
+
}).strict();
|
|
13534
13760
|
SetThreadPermissionInput = external_exports.object({
|
|
13535
13761
|
slug: ThreadSlug,
|
|
13536
13762
|
permissionMode: PermissionMode
|
|
@@ -13553,9 +13779,11 @@ var init_src = __esm({
|
|
|
13553
13779
|
backend: Backend,
|
|
13554
13780
|
options: external_exports.array(ThreadProfileOption)
|
|
13555
13781
|
});
|
|
13782
|
+
ThreadSkillSource = external_exports.enum(["project", "user", "builtin", "plugin"]);
|
|
13556
13783
|
ThreadSkill = external_exports.object({
|
|
13557
13784
|
name: external_exports.string().min(1).max(512),
|
|
13558
|
-
description: external_exports.string().max(1024)
|
|
13785
|
+
description: external_exports.string().max(1024),
|
|
13786
|
+
source: ThreadSkillSource.optional()
|
|
13559
13787
|
}).strict();
|
|
13560
13788
|
ThreadSkillsInput = external_exports.object({ slug: ThreadSlug }).strict();
|
|
13561
13789
|
ThreadSkillsResult = external_exports.object({ skills: external_exports.array(ThreadSkill).max(1024) }).strict();
|
|
@@ -13755,7 +13983,11 @@ ${DISPATCH_TASK_BANNER}
|
|
|
13755
13983
|
TranscriptEdit = external_exports.object({
|
|
13756
13984
|
file: external_exports.string(),
|
|
13757
13985
|
old: external_exports.string(),
|
|
13758
|
-
new: external_exports.string()
|
|
13986
|
+
new: external_exports.string(),
|
|
13987
|
+
// Line counts of the UNCAPPED sides, taken at projection time — `old`/`new` above are capped for
|
|
13988
|
+
// transport, so a diffstat recomputed from them undercounts any large edit.
|
|
13989
|
+
added: external_exports.number().int().nonnegative().optional(),
|
|
13990
|
+
removed: external_exports.number().int().nonnegative().optional()
|
|
13759
13991
|
});
|
|
13760
13992
|
TranscriptTodo = external_exports.object({
|
|
13761
13993
|
text: external_exports.string(),
|
|
@@ -13827,8 +14059,10 @@ ${DISPATCH_TASK_BANNER}
|
|
|
13827
14059
|
// optional so a pre-restart server / older transcript falls back to the plain `Agent(detail)` line.
|
|
13828
14060
|
prompt: external_exports.string().optional(),
|
|
13829
14061
|
// the capped dispatch prompt (the AgentBlock's expanded body)
|
|
14062
|
+
// The RESOLVED model+effort cell (e.g. "frizz:opus-high"), not `subagent_type` verbatim: a modern
|
|
14063
|
+
// profile is effort-only, so the server folds the call's `model` — or, when omitted, the model the
|
|
14064
|
+
// dispatching turn itself ran at — back into the cell. See server/subagent-profile.ts.
|
|
13830
14065
|
subagentType: external_exports.string().optional(),
|
|
13831
|
-
// the dispatch's subagent_type verbatim (e.g. "frizz:frizz-opus-high")
|
|
13832
14066
|
agentId: external_exports.string().optional(),
|
|
13833
14067
|
// the Agent tool_use id — the correlation key to the live tracked sub-agent
|
|
13834
14068
|
// Terminal outcome of the dispatched sub-agent, back-filled when a matching completion
|
|
@@ -13890,7 +14124,19 @@ ${DISPATCH_TASK_BANNER}
|
|
|
13890
14124
|
// The whole to-do list, for the calls that carry it (see TranscriptTodo). The client promotes such a
|
|
13891
14125
|
// call into a TodoBlock — a checklist card, one row per task with its status. Optional, so a
|
|
13892
14126
|
// pre-restart server / older transcript falls back to the generic card.
|
|
13893
|
-
todos: external_exports.array(TranscriptTodo).optional()
|
|
14127
|
+
todos: external_exports.array(TranscriptTodo).optional(),
|
|
14128
|
+
// ---- Native question (AskUserQuestion) block ----
|
|
14129
|
+
// The structured questions an `AskUserQuestion` tool_use asked, so a SETTLED call renders as a
|
|
14130
|
+
// read-only question card at its place in the transcript instead of a generic tool line buried in a
|
|
14131
|
+
// disclosure. This is what keeps a question the human saw from vanishing: a follow-up sent instead
|
|
14132
|
+
// of an answer retires the pending interaction card (the broker denies the parked call), and without
|
|
14133
|
+
// this field nothing in the transcript ever said what was asked. Optional, so a pre-restart server /
|
|
14134
|
+
// older transcript falls back to the generic card.
|
|
14135
|
+
ask: external_exports.array(AskQuestion).optional(),
|
|
14136
|
+
// The human's answers, parallel to `ask` (null = that question got no answer), parsed from the
|
|
14137
|
+
// call's structured tool result. Absent entirely when the call settled unanswered — the withdrawn /
|
|
14138
|
+
// denied case — which the client renders as "Not answered".
|
|
14139
|
+
askAnswers: external_exports.array(external_exports.string().nullable()).optional()
|
|
13894
14140
|
});
|
|
13895
14141
|
TranscriptPart = external_exports.discriminatedUnion("kind", [
|
|
13896
14142
|
external_exports.object({ kind: external_exports.literal("text"), text: external_exports.string() }),
|
|
@@ -14042,12 +14288,23 @@ ${DISPATCH_TASK_BANNER}
|
|
|
14042
14288
|
fenceRefused: external_exports.literal(true).optional()
|
|
14043
14289
|
});
|
|
14044
14290
|
TranscriptPageCursor = external_exports.string().min(1).max(2048).regex(/^[A-Za-z0-9_-]+$/);
|
|
14291
|
+
EditedFile = external_exports.object({
|
|
14292
|
+
path: external_exports.string().min(1),
|
|
14293
|
+
edits: external_exports.number().int().positive(),
|
|
14294
|
+
lastEditedAt: external_exports.string().optional(),
|
|
14295
|
+
// The file's diffstat, summed over its write calls (each call's counts are the line counts of its
|
|
14296
|
+
// raw old/new sides). A Write counts as all additions — what it replaced is unknowable here.
|
|
14297
|
+
added: external_exports.number().int().nonnegative().optional(),
|
|
14298
|
+
removed: external_exports.number().int().nonnegative().optional()
|
|
14299
|
+
}).strict();
|
|
14045
14300
|
TranscriptPage = external_exports.object({
|
|
14046
14301
|
messages: external_exports.array(TranscriptMessage),
|
|
14047
14302
|
beforeCursor: TranscriptPageCursor.nullable(),
|
|
14048
14303
|
hasEarlier: external_exports.boolean(),
|
|
14049
14304
|
reachedTurnBoundary: external_exports.boolean(),
|
|
14050
|
-
transcriptKey: external_exports.string().min(1).max(256)
|
|
14305
|
+
transcriptKey: external_exports.string().min(1).max(256),
|
|
14306
|
+
// The LATEST page only (see EditedFile); an earlier page is settled history and carries none.
|
|
14307
|
+
editedFiles: external_exports.array(EditedFile).optional()
|
|
14051
14308
|
}).strict();
|
|
14052
14309
|
TranscriptEarlierInput = external_exports.object({
|
|
14053
14310
|
slug: ThreadSlug,
|
|
@@ -14110,6 +14367,85 @@ ${DISPATCH_TASK_BANNER}
|
|
|
14110
14367
|
}
|
|
14111
14368
|
});
|
|
14112
14369
|
|
|
14370
|
+
// packages/server/src/frizz-paths.ts
|
|
14371
|
+
import { existsSync } from "node:fs";
|
|
14372
|
+
import { homedir as homedir2, tmpdir } from "node:os";
|
|
14373
|
+
import { dirname as dirname2, isAbsolute as isAbsolute2, join as join3, relative, resolve, sep as sep2 } from "node:path";
|
|
14374
|
+
function legacyFrizzRoot(home = homedir2()) {
|
|
14375
|
+
return join3(home, LEGACY_DIR_NAME);
|
|
14376
|
+
}
|
|
14377
|
+
function xdg(env, name) {
|
|
14378
|
+
const value = env[name];
|
|
14379
|
+
return value && (value.startsWith("/") || /^[A-Za-z]:[\\/]/u.test(value)) ? value : void 0;
|
|
14380
|
+
}
|
|
14381
|
+
function insideHome(child, home) {
|
|
14382
|
+
const norm = (value) => value.replace(/[\\/]+$/u, "").replaceAll("\\", "/").toLowerCase();
|
|
14383
|
+
const parent = norm(home);
|
|
14384
|
+
const inner = norm(child);
|
|
14385
|
+
return inner === parent || inner.startsWith(`${parent}/`);
|
|
14386
|
+
}
|
|
14387
|
+
function windowsRoots(env, home) {
|
|
14388
|
+
const local = env.LOCALAPPDATA && insideHome(env.LOCALAPPDATA, home) ? env.LOCALAPPDATA : join3(home, "AppData", "Local");
|
|
14389
|
+
const base = join3(local, "Frizz");
|
|
14390
|
+
return {
|
|
14391
|
+
data: join3(base, "Data"),
|
|
14392
|
+
state: join3(base, "State"),
|
|
14393
|
+
cache: join3(base, "Cache")
|
|
14394
|
+
};
|
|
14395
|
+
}
|
|
14396
|
+
function darwinRoots(home) {
|
|
14397
|
+
const support = join3(home, "Library", "Application Support", "Frizz");
|
|
14398
|
+
return {
|
|
14399
|
+
data: support,
|
|
14400
|
+
// macOS has no state directory concept; Application Support is where this belongs, and the log
|
|
14401
|
+
// files themselves already live under each project's own directory.
|
|
14402
|
+
state: support,
|
|
14403
|
+
cache: join3(home, "Library", "Caches", "Frizz")
|
|
14404
|
+
};
|
|
14405
|
+
}
|
|
14406
|
+
function xdgRoots(env, home) {
|
|
14407
|
+
return {
|
|
14408
|
+
data: join3(xdg(env, "XDG_DATA_HOME") ?? join3(home, ".local", "share"), "frizz"),
|
|
14409
|
+
state: join3(xdg(env, "XDG_STATE_HOME") ?? join3(home, ".local", "state"), "frizz"),
|
|
14410
|
+
cache: join3(xdg(env, "XDG_CACHE_HOME") ?? join3(home, ".cache"), "frizz")
|
|
14411
|
+
};
|
|
14412
|
+
}
|
|
14413
|
+
function frizzPaths(options2 = {}) {
|
|
14414
|
+
const env = options2.env ?? process.env;
|
|
14415
|
+
const platform = options2.platform ?? process.platform;
|
|
14416
|
+
const home = options2.home ?? homedir2();
|
|
14417
|
+
const exists = options2.exists ?? existsSync;
|
|
14418
|
+
const legacyRoot = legacyFrizzRoot(home);
|
|
14419
|
+
if (exists(legacyRoot)) {
|
|
14420
|
+
return { data: legacyRoot, state: legacyRoot, cache: legacyRoot, legacy: true };
|
|
14421
|
+
}
|
|
14422
|
+
const explicit = {
|
|
14423
|
+
data: xdg(env, "XDG_DATA_HOME"),
|
|
14424
|
+
state: xdg(env, "XDG_STATE_HOME"),
|
|
14425
|
+
cache: xdg(env, "XDG_CACHE_HOME")
|
|
14426
|
+
};
|
|
14427
|
+
const platformRoots = platform === "win32" ? windowsRoots(env, home) : platform === "darwin" ? darwinRoots(home) : xdgRoots(env, home);
|
|
14428
|
+
return {
|
|
14429
|
+
data: explicit.data ? join3(explicit.data, "frizz") : platformRoots.data,
|
|
14430
|
+
state: explicit.state ? join3(explicit.state, "frizz") : platformRoots.state,
|
|
14431
|
+
cache: explicit.cache ? join3(explicit.cache, "frizz") : platformRoots.cache,
|
|
14432
|
+
legacy: false
|
|
14433
|
+
};
|
|
14434
|
+
}
|
|
14435
|
+
function frizzRoots() {
|
|
14436
|
+
return cached ??= frizzPaths();
|
|
14437
|
+
}
|
|
14438
|
+
function projectStateDir(projectId, home) {
|
|
14439
|
+
return join3(home ? frizzPaths({ home }).data : frizzRoots().data, "projects", projectId);
|
|
14440
|
+
}
|
|
14441
|
+
var LEGACY_DIR_NAME, cached;
|
|
14442
|
+
var init_frizz_paths = __esm({
|
|
14443
|
+
"packages/server/src/frizz-paths.ts"() {
|
|
14444
|
+
"use strict";
|
|
14445
|
+
LEGACY_DIR_NAME = ".frizz";
|
|
14446
|
+
}
|
|
14447
|
+
});
|
|
14448
|
+
|
|
14113
14449
|
// node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/constants.js
|
|
14114
14450
|
var require_constants = __commonJS({
|
|
14115
14451
|
"node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/constants.js"(exports, module) {
|
|
@@ -17804,85 +18140,6 @@ var init_wrapper = __esm({
|
|
|
17804
18140
|
}
|
|
17805
18141
|
});
|
|
17806
18142
|
|
|
17807
|
-
// packages/server/src/frizz-paths.ts
|
|
17808
|
-
import { existsSync as existsSync2 } from "node:fs";
|
|
17809
|
-
import { homedir as homedir5, tmpdir } from "node:os";
|
|
17810
|
-
import { dirname as dirname4, join as join5 } from "node:path";
|
|
17811
|
-
function legacyFrizzRoot(home = homedir5()) {
|
|
17812
|
-
return join5(home, LEGACY_DIR_NAME);
|
|
17813
|
-
}
|
|
17814
|
-
function xdg(env, name) {
|
|
17815
|
-
const value = env[name];
|
|
17816
|
-
return value && (value.startsWith("/") || /^[A-Za-z]:[\\/]/u.test(value)) ? value : void 0;
|
|
17817
|
-
}
|
|
17818
|
-
function insideHome(child, home) {
|
|
17819
|
-
const norm = (value) => value.replace(/[\\/]+$/u, "").replaceAll("\\", "/").toLowerCase();
|
|
17820
|
-
const parent = norm(home);
|
|
17821
|
-
const inner = norm(child);
|
|
17822
|
-
return inner === parent || inner.startsWith(`${parent}/`);
|
|
17823
|
-
}
|
|
17824
|
-
function windowsRoots(env, home) {
|
|
17825
|
-
const local = env.LOCALAPPDATA && insideHome(env.LOCALAPPDATA, home) ? env.LOCALAPPDATA : join5(home, "AppData", "Local");
|
|
17826
|
-
const base = join5(local, "Frizz");
|
|
17827
|
-
return {
|
|
17828
|
-
data: join5(base, "Data"),
|
|
17829
|
-
state: join5(base, "State"),
|
|
17830
|
-
cache: join5(base, "Cache")
|
|
17831
|
-
};
|
|
17832
|
-
}
|
|
17833
|
-
function darwinRoots(home) {
|
|
17834
|
-
const support = join5(home, "Library", "Application Support", "Frizz");
|
|
17835
|
-
return {
|
|
17836
|
-
data: support,
|
|
17837
|
-
// macOS has no state directory concept; Application Support is where this belongs, and the log
|
|
17838
|
-
// files themselves already live under each project's own directory.
|
|
17839
|
-
state: support,
|
|
17840
|
-
cache: join5(home, "Library", "Caches", "Frizz")
|
|
17841
|
-
};
|
|
17842
|
-
}
|
|
17843
|
-
function xdgRoots(env, home) {
|
|
17844
|
-
return {
|
|
17845
|
-
data: join5(xdg(env, "XDG_DATA_HOME") ?? join5(home, ".local", "share"), "frizz"),
|
|
17846
|
-
state: join5(xdg(env, "XDG_STATE_HOME") ?? join5(home, ".local", "state"), "frizz"),
|
|
17847
|
-
cache: join5(xdg(env, "XDG_CACHE_HOME") ?? join5(home, ".cache"), "frizz")
|
|
17848
|
-
};
|
|
17849
|
-
}
|
|
17850
|
-
function frizzPaths(options2 = {}) {
|
|
17851
|
-
const env = options2.env ?? process.env;
|
|
17852
|
-
const platform = options2.platform ?? process.platform;
|
|
17853
|
-
const home = options2.home ?? homedir5();
|
|
17854
|
-
const exists = options2.exists ?? existsSync2;
|
|
17855
|
-
const legacyRoot = legacyFrizzRoot(home);
|
|
17856
|
-
if (exists(legacyRoot)) {
|
|
17857
|
-
return { data: legacyRoot, state: legacyRoot, cache: legacyRoot, legacy: true };
|
|
17858
|
-
}
|
|
17859
|
-
const explicit = {
|
|
17860
|
-
data: xdg(env, "XDG_DATA_HOME"),
|
|
17861
|
-
state: xdg(env, "XDG_STATE_HOME"),
|
|
17862
|
-
cache: xdg(env, "XDG_CACHE_HOME")
|
|
17863
|
-
};
|
|
17864
|
-
const platformRoots = platform === "win32" ? windowsRoots(env, home) : platform === "darwin" ? darwinRoots(home) : xdgRoots(env, home);
|
|
17865
|
-
return {
|
|
17866
|
-
data: explicit.data ? join5(explicit.data, "frizz") : platformRoots.data,
|
|
17867
|
-
state: explicit.state ? join5(explicit.state, "frizz") : platformRoots.state,
|
|
17868
|
-
cache: explicit.cache ? join5(explicit.cache, "frizz") : platformRoots.cache,
|
|
17869
|
-
legacy: false
|
|
17870
|
-
};
|
|
17871
|
-
}
|
|
17872
|
-
function frizzRoots() {
|
|
17873
|
-
return cached ??= frizzPaths();
|
|
17874
|
-
}
|
|
17875
|
-
function projectStateDir(projectId, home) {
|
|
17876
|
-
return join5(home ? frizzPaths({ home }).data : frizzRoots().data, "projects", projectId);
|
|
17877
|
-
}
|
|
17878
|
-
var LEGACY_DIR_NAME, cached;
|
|
17879
|
-
var init_frizz_paths = __esm({
|
|
17880
|
-
"packages/server/src/frizz-paths.ts"() {
|
|
17881
|
-
"use strict";
|
|
17882
|
-
LEGACY_DIR_NAME = ".frizz";
|
|
17883
|
-
}
|
|
17884
|
-
});
|
|
17885
|
-
|
|
17886
18143
|
// packages/server/src/logging.ts
|
|
17887
18144
|
import {
|
|
17888
18145
|
appendFileSync,
|
|
@@ -18221,7 +18478,7 @@ import {
|
|
|
18221
18478
|
writeFileSync as writeFileSync5
|
|
18222
18479
|
} from "node:fs";
|
|
18223
18480
|
import { homedir as homedir7 } from "node:os";
|
|
18224
|
-
import { dirname as dirname5, join as join8, resolve } from "node:path";
|
|
18481
|
+
import { dirname as dirname5, join as join8, resolve as resolve2 } from "node:path";
|
|
18225
18482
|
import { setTimeout as delay } from "node:timers/promises";
|
|
18226
18483
|
function errorCode2(error) {
|
|
18227
18484
|
return error && typeof error === "object" && "code" in error && typeof error.code === "string" ? error.code : void 0;
|
|
@@ -18233,7 +18490,7 @@ function canonicalHome(home) {
|
|
|
18233
18490
|
try {
|
|
18234
18491
|
return realpathSync2(home);
|
|
18235
18492
|
} catch {
|
|
18236
|
-
return
|
|
18493
|
+
return resolve2(home);
|
|
18237
18494
|
}
|
|
18238
18495
|
}
|
|
18239
18496
|
function globalLaunchLockPath(home = homedir7()) {
|
|
@@ -18438,7 +18695,7 @@ function revParsePath(dir, flag) {
|
|
|
18438
18695
|
throw new Error("unable to inspect Git worktree identity");
|
|
18439
18696
|
}
|
|
18440
18697
|
try {
|
|
18441
|
-
return realpathSync2(
|
|
18698
|
+
return realpathSync2(resolve2(dir, raw));
|
|
18442
18699
|
} catch {
|
|
18443
18700
|
throw new Error("unable to canonicalize Git worktree identity");
|
|
18444
18701
|
}
|
|
@@ -18510,7 +18767,7 @@ function syncGitConfig(dir) {
|
|
|
18510
18767
|
} catch {
|
|
18511
18768
|
throw new Error("unable to locate git config after writing frizz.id");
|
|
18512
18769
|
}
|
|
18513
|
-
const path =
|
|
18770
|
+
const path = resolve2(dir, raw);
|
|
18514
18771
|
syncGitConfigPath(path);
|
|
18515
18772
|
}
|
|
18516
18773
|
function createGitProjectId(dir) {
|
|
@@ -18636,7 +18893,7 @@ import {
|
|
|
18636
18893
|
statSync as statSync4,
|
|
18637
18894
|
writeFileSync as writeFileSync6
|
|
18638
18895
|
} from "node:fs";
|
|
18639
|
-
import { basename as basename2, dirname as dirname6, isAbsolute as
|
|
18896
|
+
import { basename as basename2, dirname as dirname6, isAbsolute as isAbsolute3, join as join9 } from "node:path";
|
|
18640
18897
|
function errorCode3(error) {
|
|
18641
18898
|
return error && typeof error === "object" && "code" in error && typeof error.code === "string" ? error.code : void 0;
|
|
18642
18899
|
}
|
|
@@ -18792,7 +19049,7 @@ function parseOwner(path) {
|
|
|
18792
19049
|
try {
|
|
18793
19050
|
const value = JSON.parse(readFileSync7(path, "utf8"));
|
|
18794
19051
|
const generation = parseGeneration(value);
|
|
18795
|
-
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) || !
|
|
19052
|
+
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;
|
|
18796
19053
|
const delegates = value.version === 1 ? [] : parseDelegates(value.delegates);
|
|
18797
19054
|
const state = value.version === 1 ? "active" : value.state;
|
|
18798
19055
|
if (!delegates || state !== "active" && state !== "draining") return null;
|
|
@@ -19029,7 +19286,7 @@ function projectLaunchTargetFromEnvironment(env) {
|
|
|
19029
19286
|
const projectDir = env[FRIZZ_LAUNCH_PROJECT_DIR];
|
|
19030
19287
|
const stateDir = env[FRIZZ_LAUNCH_STATE_DIR];
|
|
19031
19288
|
const scope = env[FRIZZ_LAUNCH_IDENTITY_SCOPE];
|
|
19032
|
-
if (!projectId || !UUID_RE.test(projectId) || !projectDir || !
|
|
19289
|
+
if (!projectId || !UUID_RE.test(projectId) || !projectDir || !isAbsolute3(projectDir) || !stateDir || !isAbsolute3(stateDir) || scope !== "repository" && scope !== "worktree") return null;
|
|
19033
19290
|
return {
|
|
19034
19291
|
projectId,
|
|
19035
19292
|
projectDir,
|
|
@@ -19106,7 +19363,7 @@ var init_boot_progress = __esm({
|
|
|
19106
19363
|
import { createHash as createHash3, randomUUID as randomUUID4 } from "node:crypto";
|
|
19107
19364
|
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";
|
|
19108
19365
|
import { homedir as homedir8 } from "node:os";
|
|
19109
|
-
import { dirname as dirname8, join as join11, parse, resolve as
|
|
19366
|
+
import { dirname as dirname8, join as join11, parse, resolve as resolve3 } from "node:path";
|
|
19110
19367
|
function projectIdPath(root) {
|
|
19111
19368
|
return join11(root, FRIZZ_DIR, ID_FILE);
|
|
19112
19369
|
}
|
|
@@ -19187,9 +19444,9 @@ function hasAny(dir, names) {
|
|
|
19187
19444
|
function isHomeDirectory(dir, home = homedir8()) {
|
|
19188
19445
|
const canonical = (value) => {
|
|
19189
19446
|
try {
|
|
19190
|
-
return realpathSync3(
|
|
19447
|
+
return realpathSync3(resolve3(value));
|
|
19191
19448
|
} catch {
|
|
19192
|
-
return
|
|
19449
|
+
return resolve3(value);
|
|
19193
19450
|
}
|
|
19194
19451
|
};
|
|
19195
19452
|
try {
|
|
@@ -19216,11 +19473,11 @@ function hasProjectMarker(dir) {
|
|
|
19216
19473
|
function discoverProjectRoot(cwd = process.cwd(), home = homedir8()) {
|
|
19217
19474
|
let dir;
|
|
19218
19475
|
try {
|
|
19219
|
-
dir =
|
|
19476
|
+
dir = resolve3(cwd);
|
|
19220
19477
|
} catch {
|
|
19221
|
-
return
|
|
19478
|
+
return resolve3(cwd);
|
|
19222
19479
|
}
|
|
19223
|
-
const stop =
|
|
19480
|
+
const stop = resolve3(home);
|
|
19224
19481
|
const filesystemRoot = parse(dir).root;
|
|
19225
19482
|
for (let at = dir; ; at = dirname8(at)) {
|
|
19226
19483
|
if (at === stop || at === filesystemRoot) break;
|
|
@@ -19603,12 +19860,12 @@ function manifestIdFor(url) {
|
|
|
19603
19860
|
return url.endsWith("/") ? url : `${url}/`;
|
|
19604
19861
|
}
|
|
19605
19862
|
function execFileP(cmd, args2) {
|
|
19606
|
-
return new Promise((
|
|
19863
|
+
return new Promise((resolve6, reject) => {
|
|
19607
19864
|
execFile(
|
|
19608
19865
|
cmd,
|
|
19609
19866
|
args2,
|
|
19610
19867
|
{ encoding: "utf8", timeout: 1e4 },
|
|
19611
|
-
(err, stdout) => err ? reject(err) :
|
|
19868
|
+
(err, stdout) => err ? reject(err) : resolve6(stdout)
|
|
19612
19869
|
);
|
|
19613
19870
|
});
|
|
19614
19871
|
}
|
|
@@ -19687,9 +19944,9 @@ function openCdpSession(browserPath, dataPath) {
|
|
|
19687
19944
|
cmdPipe.on("error", failAll);
|
|
19688
19945
|
resPipe.on("error", failAll);
|
|
19689
19946
|
child.on("exit", () => failAll(new Error("chrome exited before the CDP handshake completed")));
|
|
19690
|
-
const call2 = (method, params = {}, timeoutMs = 2e4) => new Promise((
|
|
19947
|
+
const call2 = (method, params = {}, timeoutMs = 2e4) => new Promise((resolve6, reject) => {
|
|
19691
19948
|
const id = ++seq;
|
|
19692
|
-
pending.set(id, { resolve:
|
|
19949
|
+
pending.set(id, { resolve: resolve6, reject });
|
|
19693
19950
|
cmdPipe.write(JSON.stringify({ id, method, params }) + "\0");
|
|
19694
19951
|
setTimeout(() => {
|
|
19695
19952
|
if (pending.has(id)) {
|
|
@@ -19702,15 +19959,15 @@ function openCdpSession(browserPath, dataPath) {
|
|
|
19702
19959
|
await call2("Browser.close").catch(() => {
|
|
19703
19960
|
});
|
|
19704
19961
|
if (child.exitCode !== null || child.signalCode !== null) return;
|
|
19705
|
-
await new Promise((
|
|
19962
|
+
await new Promise((resolve6) => {
|
|
19706
19963
|
const t = setTimeout(() => {
|
|
19707
19964
|
child.kill();
|
|
19708
|
-
|
|
19965
|
+
resolve6();
|
|
19709
19966
|
}, 1e4);
|
|
19710
19967
|
t.unref();
|
|
19711
19968
|
child.once("exit", () => {
|
|
19712
19969
|
clearTimeout(t);
|
|
19713
|
-
|
|
19970
|
+
resolve6();
|
|
19714
19971
|
});
|
|
19715
19972
|
});
|
|
19716
19973
|
};
|
|
@@ -22449,7 +22706,15 @@ function createAccessPane(options2) {
|
|
|
22449
22706
|
ticker.unref?.();
|
|
22450
22707
|
return true;
|
|
22451
22708
|
},
|
|
22452
|
-
key() {
|
|
22709
|
+
key(key) {
|
|
22710
|
+
if (key === "l" || key === "L") {
|
|
22711
|
+
const link = options2.issue();
|
|
22712
|
+
if (!link) return "close";
|
|
22713
|
+
shown = link;
|
|
22714
|
+
consumed = false;
|
|
22715
|
+
paint();
|
|
22716
|
+
return "keep";
|
|
22717
|
+
}
|
|
22453
22718
|
return "close";
|
|
22454
22719
|
},
|
|
22455
22720
|
close() {
|
|
@@ -22471,25 +22736,26 @@ function createAccessPane(options2) {
|
|
|
22471
22736
|
}
|
|
22472
22737
|
|
|
22473
22738
|
// src/remote-controller.ts
|
|
22474
|
-
import { homedir as
|
|
22739
|
+
import { homedir as homedir5 } from "node:os";
|
|
22475
22740
|
|
|
22476
22741
|
// src/cloud.ts
|
|
22477
22742
|
init_src();
|
|
22478
22743
|
import { spawn as spawn2 } from "node:child_process";
|
|
22479
|
-
import { existsSync, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3, rmSync } from "node:fs";
|
|
22744
|
+
import { existsSync as existsSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3, rmSync } from "node:fs";
|
|
22480
22745
|
import { createInterface } from "node:readline/promises";
|
|
22481
|
-
import { homedir as
|
|
22482
|
-
import { dirname as
|
|
22746
|
+
import { homedir as homedir4 } from "node:os";
|
|
22747
|
+
import { dirname as dirname4, join as join5 } from "node:path";
|
|
22483
22748
|
|
|
22484
22749
|
// src/identity.ts
|
|
22750
|
+
init_frizz_paths();
|
|
22485
22751
|
init_src();
|
|
22486
22752
|
import { mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "node:fs";
|
|
22487
|
-
import { homedir as
|
|
22488
|
-
import { dirname as
|
|
22489
|
-
function claimIdentityPath(home =
|
|
22490
|
-
return
|
|
22753
|
+
import { homedir as homedir3 } from "node:os";
|
|
22754
|
+
import { dirname as dirname3, join as join4 } from "node:path";
|
|
22755
|
+
function claimIdentityPath(home = homedir3()) {
|
|
22756
|
+
return join4(frizzPaths({ home }).state, "identity.key");
|
|
22491
22757
|
}
|
|
22492
|
-
async function loadOrCreateClaimIdentity(home =
|
|
22758
|
+
async function loadOrCreateClaimIdentity(home = homedir3()) {
|
|
22493
22759
|
const path = claimIdentityPath(home);
|
|
22494
22760
|
let stored;
|
|
22495
22761
|
try {
|
|
@@ -22505,7 +22771,7 @@ async function loadOrCreateClaimIdentity(home = homedir2()) {
|
|
|
22505
22771
|
);
|
|
22506
22772
|
}
|
|
22507
22773
|
const identity = await generateClaimIdentity();
|
|
22508
|
-
mkdirSync2(
|
|
22774
|
+
mkdirSync2(dirname3(path), { recursive: true });
|
|
22509
22775
|
writeFileSync2(path, await exportClaimPrivateKey(identity.privateKey), { mode: 384 });
|
|
22510
22776
|
return identity;
|
|
22511
22777
|
}
|
|
@@ -22643,7 +22909,12 @@ function serveRelayRequest(frame, options2) {
|
|
|
22643
22909
|
const target2 = new URL(frame.url);
|
|
22644
22910
|
const local = new URL(options2.origin);
|
|
22645
22911
|
const publicUrl = new URL(options2.publicOrigin);
|
|
22646
|
-
|
|
22912
|
+
let cancelled = false;
|
|
22913
|
+
let abort;
|
|
22914
|
+
const done = new Promise((resolve6) => {
|
|
22915
|
+
const send = (upFrame) => {
|
|
22916
|
+
if (!cancelled) options2.send(upFrame);
|
|
22917
|
+
};
|
|
22647
22918
|
const headers = {};
|
|
22648
22919
|
for (const [name, value] of stripHopByHop(frame.headers)) headers[name] = value;
|
|
22649
22920
|
headers.host = publicUrl.host;
|
|
@@ -22662,10 +22933,10 @@ function serveRelayRequest(frame, options2) {
|
|
|
22662
22933
|
);
|
|
22663
22934
|
const streaming = shouldStream(outHeaders);
|
|
22664
22935
|
if (streaming) {
|
|
22665
|
-
|
|
22936
|
+
send({ t: "res", id: frame.id, status: res.statusCode ?? 502, headers: outHeaders, end: false });
|
|
22666
22937
|
res.on("data", (chunk) => {
|
|
22667
22938
|
for (let at = 0; at < chunk.length; at += RELAY_MAX_FRAME_BODY) {
|
|
22668
|
-
|
|
22939
|
+
send({
|
|
22669
22940
|
t: "res-chunk",
|
|
22670
22941
|
id: frame.id,
|
|
22671
22942
|
data: encodeBody(new Uint8Array(chunk.subarray(at, at + RELAY_MAX_FRAME_BODY)))
|
|
@@ -22673,12 +22944,12 @@ function serveRelayRequest(frame, options2) {
|
|
|
22673
22944
|
}
|
|
22674
22945
|
});
|
|
22675
22946
|
res.on("end", () => {
|
|
22676
|
-
|
|
22677
|
-
|
|
22947
|
+
send({ t: "res-end", id: frame.id });
|
|
22948
|
+
resolve6();
|
|
22678
22949
|
});
|
|
22679
22950
|
res.on("error", () => {
|
|
22680
|
-
|
|
22681
|
-
|
|
22951
|
+
send({ t: "res-end", id: frame.id });
|
|
22952
|
+
resolve6();
|
|
22682
22953
|
});
|
|
22683
22954
|
return;
|
|
22684
22955
|
}
|
|
@@ -22687,7 +22958,7 @@ function serveRelayRequest(frame, options2) {
|
|
|
22687
22958
|
res.on("end", () => {
|
|
22688
22959
|
const body = Buffer.concat(chunks);
|
|
22689
22960
|
if (body.byteLength <= RELAY_MAX_FRAME_BODY) {
|
|
22690
|
-
|
|
22961
|
+
send({
|
|
22691
22962
|
t: "res",
|
|
22692
22963
|
id: frame.id,
|
|
22693
22964
|
status: res.statusCode ?? 502,
|
|
@@ -22695,28 +22966,28 @@ function serveRelayRequest(frame, options2) {
|
|
|
22695
22966
|
...body.byteLength > 0 ? { body: encodeBody(new Uint8Array(body)) } : {},
|
|
22696
22967
|
end: true
|
|
22697
22968
|
});
|
|
22698
|
-
|
|
22969
|
+
resolve6();
|
|
22699
22970
|
return;
|
|
22700
22971
|
}
|
|
22701
|
-
|
|
22972
|
+
send({ t: "res", id: frame.id, status: res.statusCode ?? 502, headers: outHeaders, end: false });
|
|
22702
22973
|
for (let at = 0; at < body.byteLength; at += RELAY_MAX_FRAME_BODY) {
|
|
22703
|
-
|
|
22974
|
+
send({
|
|
22704
22975
|
t: "res-chunk",
|
|
22705
22976
|
id: frame.id,
|
|
22706
22977
|
data: encodeBody(new Uint8Array(body.subarray(at, at + RELAY_MAX_FRAME_BODY)))
|
|
22707
22978
|
});
|
|
22708
22979
|
}
|
|
22709
|
-
|
|
22710
|
-
|
|
22980
|
+
send({ t: "res-end", id: frame.id });
|
|
22981
|
+
resolve6();
|
|
22711
22982
|
});
|
|
22712
22983
|
res.on("error", () => {
|
|
22713
|
-
|
|
22714
|
-
|
|
22984
|
+
send({ t: "res", id: frame.id, status: 502, headers: [], end: true });
|
|
22985
|
+
resolve6();
|
|
22715
22986
|
});
|
|
22716
22987
|
}
|
|
22717
22988
|
);
|
|
22718
22989
|
req.on("error", (error) => {
|
|
22719
|
-
|
|
22990
|
+
send({
|
|
22720
22991
|
t: "res",
|
|
22721
22992
|
id: frame.id,
|
|
22722
22993
|
status: 502,
|
|
@@ -22724,11 +22995,23 @@ function serveRelayRequest(frame, options2) {
|
|
|
22724
22995
|
body: encodeBody(new TextEncoder().encode(`Frizz is not answering on this machine: ${error.message}`)),
|
|
22725
22996
|
end: true
|
|
22726
22997
|
});
|
|
22727
|
-
|
|
22998
|
+
resolve6();
|
|
22728
22999
|
});
|
|
22729
23000
|
if (frame.body) req.write(Buffer.from(decodeBody(frame.body)));
|
|
22730
23001
|
req.end();
|
|
23002
|
+
abort = () => {
|
|
23003
|
+
req.destroy();
|
|
23004
|
+
resolve6();
|
|
23005
|
+
};
|
|
22731
23006
|
});
|
|
23007
|
+
return {
|
|
23008
|
+
done,
|
|
23009
|
+
cancel: () => {
|
|
23010
|
+
if (cancelled) return;
|
|
23011
|
+
cancelled = true;
|
|
23012
|
+
abort?.();
|
|
23013
|
+
}
|
|
23014
|
+
};
|
|
22732
23015
|
}
|
|
22733
23016
|
var HANDSHAKE_HEADERS = /* @__PURE__ */ new Set([
|
|
22734
23017
|
"sec-websocket-key",
|
|
@@ -22810,6 +23093,7 @@ function defaultBackoff(attempt, random = Math.random) {
|
|
|
22810
23093
|
const base = Math.min(3e4, 500 * 2 ** Math.min(attempt, 6));
|
|
22811
23094
|
return Math.round(base / 2 + random() * (base / 2));
|
|
22812
23095
|
}
|
|
23096
|
+
var RELAY_KEEPALIVE_INTERVAL_MS = 45e3;
|
|
22813
23097
|
async function signRelayHandshake(name, identity, issuedAt) {
|
|
22814
23098
|
const pubkey = await exportClaimPublicKey(identity.publicKey);
|
|
22815
23099
|
const signature = await crypto.subtle.sign(
|
|
@@ -22827,9 +23111,22 @@ function connectRelay(options2) {
|
|
|
22827
23111
|
const makeSocket = options2.socketFactory ?? ((url) => new WebSocket(url));
|
|
22828
23112
|
let socket = null;
|
|
22829
23113
|
const nested = /* @__PURE__ */ new Map();
|
|
23114
|
+
const requests = /* @__PURE__ */ new Map();
|
|
22830
23115
|
let attempt = 0;
|
|
22831
23116
|
let stopped = false;
|
|
22832
23117
|
let retryHandle;
|
|
23118
|
+
let keepaliveHandle;
|
|
23119
|
+
let awaitingPong = false;
|
|
23120
|
+
const clearKeepalive = () => {
|
|
23121
|
+
if (keepaliveHandle !== void 0) {
|
|
23122
|
+
clearTimer(keepaliveHandle);
|
|
23123
|
+
keepaliveHandle = void 0;
|
|
23124
|
+
}
|
|
23125
|
+
};
|
|
23126
|
+
const cancelRequests = () => {
|
|
23127
|
+
for (const request of requests.values()) request.cancel();
|
|
23128
|
+
requests.clear();
|
|
23129
|
+
};
|
|
22833
23130
|
const send = (frame) => {
|
|
22834
23131
|
try {
|
|
22835
23132
|
socket?.send(serializeFrame(frame));
|
|
@@ -22856,7 +23153,26 @@ function connectRelay(options2) {
|
|
|
22856
23153
|
const next = makeSocket(url);
|
|
22857
23154
|
socket = next;
|
|
22858
23155
|
let settled;
|
|
23156
|
+
const beat = () => {
|
|
23157
|
+
if (stopped || socket !== next) return;
|
|
23158
|
+
if (awaitingPong) {
|
|
23159
|
+
dropped();
|
|
23160
|
+
try {
|
|
23161
|
+
next.close();
|
|
23162
|
+
} catch {
|
|
23163
|
+
}
|
|
23164
|
+
return;
|
|
23165
|
+
}
|
|
23166
|
+
awaitingPong = true;
|
|
23167
|
+
try {
|
|
23168
|
+
next.send(RELAY_KEEPALIVE_PING);
|
|
23169
|
+
} catch {
|
|
23170
|
+
}
|
|
23171
|
+
keepaliveHandle = setTimer(beat, RELAY_KEEPALIVE_INTERVAL_MS);
|
|
23172
|
+
};
|
|
22859
23173
|
next.addEventListener("open", () => {
|
|
23174
|
+
awaitingPong = false;
|
|
23175
|
+
keepaliveHandle = setTimer(beat, RELAY_KEEPALIVE_INTERVAL_MS);
|
|
22860
23176
|
settled = setTimer(() => {
|
|
22861
23177
|
attempt = 0;
|
|
22862
23178
|
}, SETTLED_MS);
|
|
@@ -22870,12 +23186,25 @@ function connectRelay(options2) {
|
|
|
22870
23186
|
send({ t: "pong", id: frame.id });
|
|
22871
23187
|
return;
|
|
22872
23188
|
}
|
|
23189
|
+
if (frame.t === "pong") {
|
|
23190
|
+
awaitingPong = false;
|
|
23191
|
+
return;
|
|
23192
|
+
}
|
|
22873
23193
|
if (frame.t === "req") {
|
|
22874
|
-
|
|
23194
|
+
const handle = serveRelayRequest(frame, {
|
|
22875
23195
|
origin: options2.boardOrigin,
|
|
22876
23196
|
publicOrigin: options2.publicOrigin,
|
|
22877
23197
|
send
|
|
22878
23198
|
});
|
|
23199
|
+
requests.set(frame.id, handle);
|
|
23200
|
+
void handle.done.then(() => {
|
|
23201
|
+
if (requests.get(frame.id) === handle) requests.delete(frame.id);
|
|
23202
|
+
});
|
|
23203
|
+
return;
|
|
23204
|
+
}
|
|
23205
|
+
if (frame.t === "req-cancel") {
|
|
23206
|
+
requests.get(frame.id)?.cancel();
|
|
23207
|
+
requests.delete(frame.id);
|
|
22879
23208
|
return;
|
|
22880
23209
|
}
|
|
22881
23210
|
if (frame.t === "ws-open") {
|
|
@@ -22904,9 +23233,11 @@ function connectRelay(options2) {
|
|
|
22904
23233
|
clearTimer(settled);
|
|
22905
23234
|
settled = void 0;
|
|
22906
23235
|
}
|
|
23236
|
+
clearKeepalive();
|
|
22907
23237
|
socket = null;
|
|
22908
23238
|
for (const session of nested.values()) session.close();
|
|
22909
23239
|
nested.clear();
|
|
23240
|
+
cancelRequests();
|
|
22910
23241
|
options2.onStatus?.("disconnected");
|
|
22911
23242
|
scheduleRetry("the relay connection closed");
|
|
22912
23243
|
};
|
|
@@ -22918,12 +23249,14 @@ function connectRelay(options2) {
|
|
|
22918
23249
|
stop() {
|
|
22919
23250
|
stopped = true;
|
|
22920
23251
|
if (retryHandle !== void 0) clearTimer(retryHandle);
|
|
23252
|
+
clearKeepalive();
|
|
22921
23253
|
try {
|
|
22922
23254
|
socket?.close();
|
|
22923
23255
|
} catch {
|
|
22924
23256
|
}
|
|
22925
23257
|
for (const session of nested.values()) session.close();
|
|
22926
23258
|
nested.clear();
|
|
23259
|
+
cancelRequests();
|
|
22927
23260
|
socket = null;
|
|
22928
23261
|
},
|
|
22929
23262
|
get connected() {
|
|
@@ -22955,7 +23288,7 @@ function zoneClaimLabel(hostname) {
|
|
|
22955
23288
|
const label = hostname.slice(0, -suffix.length);
|
|
22956
23289
|
return label.length > 0 && !label.includes(".") ? label : null;
|
|
22957
23290
|
}
|
|
22958
|
-
async function reconcileCloudConfig(config, port, home =
|
|
23291
|
+
async function reconcileCloudConfig(config, port, home = homedir4(), onNotice, origin, github = githubCli) {
|
|
22959
23292
|
if (isRelayConfig(config)) return config;
|
|
22960
23293
|
const label = config.claim ?? zoneClaimLabel(config.hostname);
|
|
22961
23294
|
if (!label) return config;
|
|
@@ -22964,10 +23297,10 @@ async function reconcileCloudConfig(config, port, home = homedir3(), onNotice, o
|
|
|
22964
23297
|
);
|
|
22965
23298
|
return establishCloudConfig(label, port, home, origin, github);
|
|
22966
23299
|
}
|
|
22967
|
-
function cloudConfigPath(home =
|
|
22968
|
-
return
|
|
23300
|
+
function cloudConfigPath(home = homedir4()) {
|
|
23301
|
+
return join5(home, ".frizz", "cloud.json");
|
|
22969
23302
|
}
|
|
22970
|
-
function readCloudConfig(home =
|
|
23303
|
+
function readCloudConfig(home = homedir4()) {
|
|
22971
23304
|
try {
|
|
22972
23305
|
const parsed = JSON.parse(readFileSync4(cloudConfigPath(home), "utf8"));
|
|
22973
23306
|
if (typeof parsed.hostname !== "string" || !parsed.hostname) return null;
|
|
@@ -22987,10 +23320,10 @@ function readCloudConfig(home = homedir3()) {
|
|
|
22987
23320
|
return null;
|
|
22988
23321
|
}
|
|
22989
23322
|
}
|
|
22990
|
-
function tunnelTokenPath(home =
|
|
22991
|
-
return
|
|
23323
|
+
function tunnelTokenPath(home = homedir4()) {
|
|
23324
|
+
return join5(home, ".frizz", "tunnel-token");
|
|
22992
23325
|
}
|
|
22993
|
-
function readTunnelToken(home =
|
|
23326
|
+
function readTunnelToken(home = homedir4()) {
|
|
22994
23327
|
try {
|
|
22995
23328
|
const token = readFileSync4(tunnelTokenPath(home), "utf8").trim();
|
|
22996
23329
|
return token.length > 0 ? token : null;
|
|
@@ -22998,18 +23331,18 @@ function readTunnelToken(home = homedir3()) {
|
|
|
22998
23331
|
return null;
|
|
22999
23332
|
}
|
|
23000
23333
|
}
|
|
23001
|
-
function writeTunnelToken(token, home =
|
|
23334
|
+
function writeTunnelToken(token, home = homedir4()) {
|
|
23002
23335
|
const path = tunnelTokenPath(home);
|
|
23003
|
-
mkdirSync3(
|
|
23336
|
+
mkdirSync3(dirname4(path), { recursive: true });
|
|
23004
23337
|
writeFileSync3(path, `${token}
|
|
23005
23338
|
`, { mode: 384 });
|
|
23006
23339
|
}
|
|
23007
|
-
function deleteCloudConfig(home =
|
|
23340
|
+
function deleteCloudConfig(home = homedir4()) {
|
|
23008
23341
|
rmSync(cloudConfigPath(home), { force: true });
|
|
23009
23342
|
}
|
|
23010
|
-
function writeCloudConfig(config, home =
|
|
23343
|
+
function writeCloudConfig(config, home = homedir4()) {
|
|
23011
23344
|
const path = cloudConfigPath(home);
|
|
23012
|
-
mkdirSync3(
|
|
23345
|
+
mkdirSync3(dirname4(path), { recursive: true });
|
|
23013
23346
|
writeFileSync3(path, `${JSON.stringify(config, null, 2)}
|
|
23014
23347
|
`);
|
|
23015
23348
|
}
|
|
@@ -23030,7 +23363,7 @@ async function promptForTunnelName(hostname, fallback) {
|
|
|
23030
23363
|
rl.close();
|
|
23031
23364
|
}
|
|
23032
23365
|
}
|
|
23033
|
-
async function establishCloudConfig(answer, port, home =
|
|
23366
|
+
async function establishCloudConfig(answer, port, home = homedir4(), origin, github = githubCli) {
|
|
23034
23367
|
if (answer.includes(".")) {
|
|
23035
23368
|
const hostname = normalizeHostname(answer);
|
|
23036
23369
|
const tunnel = await promptForTunnelName(hostname, hostname.split(".")[0]);
|
|
@@ -23041,17 +23374,23 @@ async function establishCloudConfig(answer, port, home = homedir3(), origin, git
|
|
|
23041
23374
|
"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."
|
|
23042
23375
|
);
|
|
23043
23376
|
}
|
|
23044
|
-
|
|
23377
|
+
const anonymous = answer === "" || isAnonymousClaimName(answer);
|
|
23378
|
+
if (!anonymous && !claimNameIsValid(answer)) {
|
|
23045
23379
|
normalizeClaimName(answer);
|
|
23046
23380
|
}
|
|
23047
|
-
const name = normalizeClaimName(answer);
|
|
23381
|
+
const name = answer === "" ? generateAnonymousClaimName() : normalizeClaimName(answer);
|
|
23048
23382
|
const identity = await loadOrCreateClaimIdentity(home);
|
|
23049
|
-
|
|
23050
|
-
|
|
23051
|
-
|
|
23383
|
+
let token;
|
|
23384
|
+
if (!anonymous) {
|
|
23385
|
+
token = await github.accessToken();
|
|
23386
|
+
const login = await github.login();
|
|
23387
|
+
if (login) console.log(` claiming ${name}.frizz.sh for GitHub user ${login}`);
|
|
23388
|
+
} else {
|
|
23389
|
+
console.log(" claiming a private name on frizz.sh \u2014 no account needed");
|
|
23390
|
+
}
|
|
23052
23391
|
let result;
|
|
23053
23392
|
try {
|
|
23054
|
-
result = await claimName({ name, port, identity, github: token, ...origin ? { origin } : {} });
|
|
23393
|
+
result = await claimName({ name, port, identity, ...token ? { github: token } : {}, ...origin ? { origin } : {} });
|
|
23055
23394
|
} catch (error) {
|
|
23056
23395
|
if (error instanceof ClaimError && error.code === "unreachable") {
|
|
23057
23396
|
throw new ClaimError(
|
|
@@ -23068,7 +23407,7 @@ async function establishCloudConfig(answer, port, home = homedir3(), origin, git
|
|
|
23068
23407
|
}
|
|
23069
23408
|
return { hostname: result.hostname, claim: name, serve: "relay" };
|
|
23070
23409
|
}
|
|
23071
|
-
async function resolveRunToken(config, port, home =
|
|
23410
|
+
async function resolveRunToken(config, port, home = homedir4(), onWarning, origin) {
|
|
23072
23411
|
if (!isClaimedConfig(config)) return null;
|
|
23073
23412
|
const cached2 = readTunnelToken(home);
|
|
23074
23413
|
try {
|
|
@@ -23085,12 +23424,12 @@ async function resolveRunToken(config, port, home = homedir3(), onWarning, origi
|
|
|
23085
23424
|
throw error;
|
|
23086
23425
|
}
|
|
23087
23426
|
}
|
|
23088
|
-
function resolveTunnelConfigPath(config, home =
|
|
23427
|
+
function resolveTunnelConfigPath(config, home = homedir4()) {
|
|
23089
23428
|
if (config.config) return config.config;
|
|
23090
|
-
const candidate =
|
|
23091
|
-
return
|
|
23429
|
+
const candidate = join5(home, ".cloudflared", "frizz.yml");
|
|
23430
|
+
return existsSync2(candidate) ? candidate : null;
|
|
23092
23431
|
}
|
|
23093
|
-
async function startRelay(config, port, home =
|
|
23432
|
+
async function startRelay(config, port, home = homedir4(), onStatus) {
|
|
23094
23433
|
const identity = await loadOrCreateClaimIdentity(home);
|
|
23095
23434
|
const origin = `https://${config.hostname}`;
|
|
23096
23435
|
return connectRelay({
|
|
@@ -23108,7 +23447,7 @@ async function startRelay(config, port, home = homedir3(), onStatus) {
|
|
|
23108
23447
|
} : {}
|
|
23109
23448
|
});
|
|
23110
23449
|
}
|
|
23111
|
-
function startTunnel(config, onExit, onError, home =
|
|
23450
|
+
function startTunnel(config, onExit, onError, home = homedir4(), runToken) {
|
|
23112
23451
|
const configPath = runToken ? null : resolveTunnelConfigPath(config, home);
|
|
23113
23452
|
const args2 = runToken ? ["tunnel", "--no-autoupdate", "run", "--token", runToken] : [
|
|
23114
23453
|
"tunnel",
|
|
@@ -23139,7 +23478,7 @@ function startTunnel(config, onExit, onError, home = homedir3(), runToken) {
|
|
|
23139
23478
|
|
|
23140
23479
|
// src/remote-controller.ts
|
|
23141
23480
|
function createRemoteController(options2) {
|
|
23142
|
-
const home = options2.home ??
|
|
23481
|
+
const home = options2.home ?? homedir5();
|
|
23143
23482
|
let config = null;
|
|
23144
23483
|
let transport = null;
|
|
23145
23484
|
const stopTransport = () => {
|
|
@@ -23221,9 +23560,9 @@ function createRemoteController(options2) {
|
|
|
23221
23560
|
import { execFile as execFile3 } from "node:child_process";
|
|
23222
23561
|
var PROBE_TIMEOUT_MS = 4e3;
|
|
23223
23562
|
function run2(command, args2) {
|
|
23224
|
-
return new Promise((
|
|
23563
|
+
return new Promise((resolve6) => {
|
|
23225
23564
|
execFile3(command, args2, { encoding: "utf8", timeout: PROBE_TIMEOUT_MS }, (error, stdout) => {
|
|
23226
|
-
|
|
23565
|
+
resolve6(error ? null : stdout);
|
|
23227
23566
|
});
|
|
23228
23567
|
});
|
|
23229
23568
|
}
|
|
@@ -23251,8 +23590,10 @@ async function probeTailscale() {
|
|
|
23251
23590
|
}
|
|
23252
23591
|
|
|
23253
23592
|
// src/remote-pane.ts
|
|
23593
|
+
init_src();
|
|
23254
23594
|
var CHOICES = [
|
|
23255
|
-
{ kind: "
|
|
23595
|
+
{ kind: "private", title: "Private name", blurb: "an unguessable name on frizz.sh \u2014 no account, nothing to install" },
|
|
23596
|
+
{ kind: "frizz", title: "Custom name", blurb: "<name>.frizz.sh of your choosing; needs the GitHub CLI" },
|
|
23256
23597
|
{ kind: "cloudflare", title: "Cloudflare Tunnel", blurb: "a domain you own on Cloudflare; cloudflared on this machine" },
|
|
23257
23598
|
{ kind: "tailscale", title: "Tailscale", blurb: "your tailnet; tailscale serve does the TLS" },
|
|
23258
23599
|
{ kind: "other", title: "Something else", blurb: "any proxy or tunnel you run \u2014 tell Frizz its address" },
|
|
@@ -23267,7 +23608,7 @@ var TAB = " ";
|
|
|
23267
23608
|
var SHIFT_TAB = "\x1B[Z";
|
|
23268
23609
|
function kindOf(config) {
|
|
23269
23610
|
if (!config) return "off";
|
|
23270
|
-
if (isClaimedConfig(config)) return "frizz";
|
|
23611
|
+
if (isClaimedConfig(config)) return isAnonymousClaimName(config.claim) ? "private" : "frizz";
|
|
23271
23612
|
if (isExternalConfig(config)) return config.provider === "tailscale" ? "tailscale" : "other";
|
|
23272
23613
|
return "cloudflare";
|
|
23273
23614
|
}
|
|
@@ -23354,10 +23695,10 @@ function createRemotePane(options2) {
|
|
|
23354
23695
|
if (kind === "frizz") {
|
|
23355
23696
|
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";
|
|
23356
23697
|
return [
|
|
23357
|
-
"frizz.sh name",
|
|
23698
|
+
"Custom frizz.sh name",
|
|
23358
23699
|
"",
|
|
23359
23700
|
...wrap(
|
|
23360
|
-
"Claims <name>.frizz.sh
|
|
23701
|
+
"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.)"
|
|
23361
23702
|
),
|
|
23362
23703
|
...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.")] : [],
|
|
23363
23704
|
"",
|
|
@@ -23478,6 +23819,22 @@ function createRemotePane(options2) {
|
|
|
23478
23819
|
}
|
|
23479
23820
|
paint();
|
|
23480
23821
|
};
|
|
23822
|
+
const claimPrivate = async () => {
|
|
23823
|
+
const back = { name: "menu", index: 0 };
|
|
23824
|
+
screen = { name: "busy", message: "claiming a private name on frizz.sh\u2026" };
|
|
23825
|
+
paint();
|
|
23826
|
+
try {
|
|
23827
|
+
const next = await options2.claim("");
|
|
23828
|
+
screen = { name: "busy", message: `serving ${next.hostname}\u2026` };
|
|
23829
|
+
paint();
|
|
23830
|
+
await options2.apply(next, { justClaimed: true });
|
|
23831
|
+
options2.onChanged?.(next);
|
|
23832
|
+
screen = { name: "done", message: `Serving https://${next.hostname} (${describeCloudConfig(next)}).`, link: options2.issueLink(), config: next };
|
|
23833
|
+
} catch (error) {
|
|
23834
|
+
screen = { name: "error", message: error instanceof Error ? error.message : String(error), back };
|
|
23835
|
+
}
|
|
23836
|
+
paint();
|
|
23837
|
+
};
|
|
23481
23838
|
const turnOff = async () => {
|
|
23482
23839
|
screen = { name: "busy", message: "back to loopback only\u2026" };
|
|
23483
23840
|
paint();
|
|
@@ -23513,10 +23870,11 @@ function createRemotePane(options2) {
|
|
|
23513
23870
|
if (key === ESC || key === "q") return "close";
|
|
23514
23871
|
if (key === UP || key === "k") s.index = (s.index + CHOICES.length - 1) % CHOICES.length;
|
|
23515
23872
|
else if (key === DOWN || key === "j") s.index = (s.index + 1) % CHOICES.length;
|
|
23516
|
-
else if (/^[1-
|
|
23873
|
+
else if (/^[1-6]$/.test(key)) s.index = Number(key) - 1;
|
|
23517
23874
|
else if (ENTER.has(key)) {
|
|
23518
23875
|
const choice = CHOICES[s.index];
|
|
23519
23876
|
if (choice.kind === "off") void turnOff();
|
|
23877
|
+
else if (choice.kind === "private") void claimPrivate();
|
|
23520
23878
|
else openForm(choice.kind);
|
|
23521
23879
|
return "keep";
|
|
23522
23880
|
}
|
|
@@ -23892,22 +24250,22 @@ init_project_launch();
|
|
|
23892
24250
|
init_local_origin();
|
|
23893
24251
|
init_boot_progress();
|
|
23894
24252
|
init_frizz_paths();
|
|
23895
|
-
init_project_root();
|
|
23896
|
-
init_logging();
|
|
23897
|
-
init_src();
|
|
23898
|
-
init_project_registry();
|
|
23899
24253
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
23900
24254
|
import { createServer as createServer2 } from "node:net";
|
|
23901
24255
|
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";
|
|
23902
24256
|
import { homedir as homedir10, tmpdir as tmpdir2 } from "node:os";
|
|
23903
|
-
import { basename as basename5, join as join13, resolve as
|
|
24257
|
+
import { basename as basename5, dirname as dirname10, join as join13, resolve as resolve4 } from "node:path";
|
|
23904
24258
|
import { setTimeout as delay2 } from "node:timers/promises";
|
|
24259
|
+
init_project_root();
|
|
24260
|
+
init_logging();
|
|
24261
|
+
init_src();
|
|
24262
|
+
init_project_registry();
|
|
23905
24263
|
var PORT_SCAN_COUNT = 100;
|
|
23906
24264
|
var LAUNCH_TIMEOUT_MS = 3e4;
|
|
23907
24265
|
var LAUNCH_HARD_TIMEOUT_MS = 10 * 6e4;
|
|
23908
24266
|
var RETIRED_NETWORK_FLAGS = ["--host", "--allowed-host", "--public-origin", "--cloud"];
|
|
23909
24267
|
function retiredFlagMessage(flag) {
|
|
23910
|
-
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.`;
|
|
24268
|
+
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.`;
|
|
23911
24269
|
}
|
|
23912
24270
|
function parseCliArgs(argv) {
|
|
23913
24271
|
const args2 = new Set(argv);
|
|
@@ -24040,9 +24398,11 @@ function shareCredentials(realHome, home) {
|
|
|
24040
24398
|
} catch {
|
|
24041
24399
|
}
|
|
24042
24400
|
};
|
|
24043
|
-
|
|
24044
|
-
|
|
24045
|
-
|
|
24401
|
+
const realKey = claimIdentityPath(realHome);
|
|
24402
|
+
const sandboxKey = claimIdentityPath(home);
|
|
24403
|
+
mkdirSync10(dirname10(realKey), { recursive: true });
|
|
24404
|
+
mkdirSync10(dirname10(sandboxKey), { recursive: true });
|
|
24405
|
+
link(realKey, sandboxKey);
|
|
24046
24406
|
if (existsSync5(join13(realHome, ".config", "gh"))) {
|
|
24047
24407
|
mkdirSync10(join13(home, ".config"), { recursive: true });
|
|
24048
24408
|
link(join13(realHome, ".config", "gh"), join13(home, ".config", "gh"));
|
|
@@ -24324,7 +24684,7 @@ import { fork } from "node:child_process";
|
|
|
24324
24684
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
24325
24685
|
import { existsSync as existsSync6, mkdirSync as mkdirSync11, readFileSync as readFileSync12 } from "node:fs";
|
|
24326
24686
|
import { createServer as createNetServer } from "node:net";
|
|
24327
|
-
import { basename as basename6, dirname as
|
|
24687
|
+
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";
|
|
24328
24688
|
import { fileURLToPath } from "node:url";
|
|
24329
24689
|
import watcher from "@parcel/watcher";
|
|
24330
24690
|
init_logging();
|
|
@@ -24415,29 +24775,29 @@ function createSupervisorShutdownHandler(options2) {
|
|
|
24415
24775
|
);
|
|
24416
24776
|
};
|
|
24417
24777
|
}
|
|
24418
|
-
var packagesDir =
|
|
24419
|
-
var workspaceDir =
|
|
24778
|
+
var packagesDir = resolve5(import.meta.dirname, "..", "..");
|
|
24779
|
+
var workspaceDir = resolve5(packagesDir, "..");
|
|
24420
24780
|
var INITIAL_BOOT_REASON = "initial boot";
|
|
24421
24781
|
function defaultDevWatchRoots() {
|
|
24422
24782
|
return [workspaceDir];
|
|
24423
24783
|
}
|
|
24424
24784
|
function isWithin(path, root) {
|
|
24425
|
-
const rel =
|
|
24426
|
-
return rel === "" || rel !== ".." && !rel.startsWith(`..${
|
|
24785
|
+
const rel = relative2(root, path);
|
|
24786
|
+
return rel === "" || rel !== ".." && !rel.startsWith(`..${sep3}`) && !isAbsolute4(rel);
|
|
24427
24787
|
}
|
|
24428
24788
|
function ignoredDevPath(path) {
|
|
24429
|
-
const parts =
|
|
24789
|
+
const parts = resolve5(path).split(sep3);
|
|
24430
24790
|
const name = parts.at(-1) ?? "";
|
|
24431
24791
|
return parts.some((part) => GENERATED_DIRS.has(part) || part === "fixtures" || part.endsWith(".fixtures")) || /\.(?:test|spec)\.[^.]+$/.test(name) || name.includes(".golden.");
|
|
24432
24792
|
}
|
|
24433
24793
|
function classifyDevChange(path, roots = defaultDevWatchRoots()) {
|
|
24434
|
-
const absolute =
|
|
24435
|
-
const root = roots.find((candidate) => isWithin(absolute,
|
|
24794
|
+
const absolute = resolve5(path);
|
|
24795
|
+
const root = roots.find((candidate) => isWithin(absolute, resolve5(candidate)));
|
|
24436
24796
|
if (!root) return null;
|
|
24437
24797
|
if (ignoredDevPath(absolute)) return null;
|
|
24438
24798
|
const name = basename6(absolute);
|
|
24439
|
-
const relToWorkspace =
|
|
24440
|
-
const parts = relToWorkspace.split(
|
|
24799
|
+
const relToWorkspace = relative2(resolve5(root), absolute);
|
|
24800
|
+
const parts = relToWorkspace.split(sep3);
|
|
24441
24801
|
const packageName = parts[0] === "packages" ? parts[1] : void 0;
|
|
24442
24802
|
if (name === "package.json" && parts.length === 3 && packageName && CHILD_PACKAGE_METADATA.has(packageName)) {
|
|
24443
24803
|
return "child";
|
|
@@ -24584,10 +24944,10 @@ var Supervisor = class {
|
|
|
24584
24944
|
if (launchOwner.pid !== callerGeneration.pid || launchOwner.processStart !== callerGeneration.processStart) throw new Error("dev supervisor caller is not the exact project launch owner");
|
|
24585
24945
|
this.port = opts.port;
|
|
24586
24946
|
this.launchTarget = opts.launchTarget;
|
|
24587
|
-
this.cwd =
|
|
24947
|
+
this.cwd = resolve5(opts.cwd ?? opts.launchTarget.projectDir);
|
|
24588
24948
|
if (this.cwd !== opts.launchTarget.projectDir) throw new Error("dev supervisor cwd does not match its owned project");
|
|
24589
24949
|
this.parentEnv = projectLaunchEnvironment(opts.env ?? process.env, opts.launchTarget, opts.launchOwnerToken);
|
|
24590
|
-
this.roots = (opts.watchRoots ?? defaultDevWatchRoots()).map((root) =>
|
|
24950
|
+
this.roots = (opts.watchRoots ?? defaultDevWatchRoots()).map((root) => resolve5(root));
|
|
24591
24951
|
this.watchEnabled = opts.watch !== false;
|
|
24592
24952
|
this.childEnvironment = opts.childEnvironment ?? (() => ({}));
|
|
24593
24953
|
this.debounceMs = opts.debounceMs ?? DEV_RESTART_DEBOUNCE_MS;
|
|
@@ -24597,10 +24957,10 @@ var Supervisor = class {
|
|
|
24597
24957
|
this.childArgs = opts.childArgs ?? [];
|
|
24598
24958
|
this.watchSubscribe = opts.watchSubscribe ?? ((root, callback, options2) => watcher.subscribe(root, callback, options2));
|
|
24599
24959
|
this.reexec = opts.reexec ?? (typeof process.execve === "function" ? (request) => process.execve(request.executable, request.argv, request.env) : void 0);
|
|
24600
|
-
if (opts.stateDir &&
|
|
24960
|
+
if (opts.stateDir && resolve5(opts.stateDir) !== opts.launchTarget.stateDir) {
|
|
24601
24961
|
throw new Error("dev supervisor state directory does not match its owned project");
|
|
24602
24962
|
}
|
|
24603
|
-
this.supervisorLock =
|
|
24963
|
+
this.supervisorLock = resolve5(opts.launchTarget.stateDir, "dev-supervisor.lock");
|
|
24604
24964
|
this.ownerToken = opts.launchOwnerToken;
|
|
24605
24965
|
this.logLine = opts.log ?? ((line) => log.info("supervisor", stripPrefix(line)));
|
|
24606
24966
|
this.errorLine = opts.error ?? ((line) => log.error("supervisor", stripPrefix(line)));
|
|
@@ -24652,7 +25012,7 @@ var Supervisor = class {
|
|
|
24652
25012
|
}
|
|
24653
25013
|
async start() {
|
|
24654
25014
|
if (this.supervisorLock) {
|
|
24655
|
-
mkdirSync11(
|
|
25015
|
+
mkdirSync11(dirname11(this.supervisorLock), { recursive: true });
|
|
24656
25016
|
this.writeStatus("starting", "watcher initializing");
|
|
24657
25017
|
}
|
|
24658
25018
|
try {
|
|
@@ -24707,7 +25067,7 @@ var Supervisor = class {
|
|
|
24707
25067
|
return;
|
|
24708
25068
|
}
|
|
24709
25069
|
this.crashAttempts = 0;
|
|
24710
|
-
this.requestRestart(
|
|
25070
|
+
this.requestRestart(relative2(workspaceDir, relevant.path), false, kind === "launcher");
|
|
24711
25071
|
}
|
|
24712
25072
|
}
|
|
24713
25073
|
requestRestart(reason, immediate = false, reloadLauncher = false, delayMs = this.debounceMs) {
|
|
@@ -25185,7 +25545,7 @@ var npmRegistryReleaseAdapter = {
|
|
|
25185
25545
|
import { spawnSync } from "node:child_process";
|
|
25186
25546
|
import { chmodSync as chmodSync2, statSync as statSync5 } from "node:fs";
|
|
25187
25547
|
import { createRequire } from "node:module";
|
|
25188
|
-
import { dirname as
|
|
25548
|
+
import { dirname as dirname12, join as join14 } from "node:path";
|
|
25189
25549
|
var SUPPORTED_NODE_LINES = [
|
|
25190
25550
|
{ major: 22, minor: 13 },
|
|
25191
25551
|
{ major: 23, minor: 4 }
|
|
@@ -25237,7 +25597,7 @@ function ensureNativeHelperPermissions(options2 = {}) {
|
|
|
25237
25597
|
const resolvePty = options2.resolvePty ?? (() => createRequire(import.meta.url).resolve("node-pty/package.json"));
|
|
25238
25598
|
try {
|
|
25239
25599
|
const helper = join14(
|
|
25240
|
-
|
|
25600
|
+
dirname12(resolvePty()),
|
|
25241
25601
|
"prebuilds",
|
|
25242
25602
|
`${platform}-${options2.arch ?? process.arch}`,
|
|
25243
25603
|
"spawn-helper"
|
|
@@ -25302,7 +25662,8 @@ Options:
|
|
|
25302
25662
|
|
|
25303
25663
|
|
|
25304
25664
|
To reach the board from a phone or another machine, press R in the terminal running it: a short
|
|
25305
|
-
walkthrough sets up a frizz.sh name
|
|
25665
|
+
walkthrough sets up a private frizz.sh name (no account needed), a custom one, a Cloudflare
|
|
25666
|
+
Tunnel, Tailscale, or a proxy of your own, and
|
|
25306
25667
|
remembers the choice, so a plain launch serves it from then on. The board stays on loopback and
|
|
25307
25668
|
shows a single-use sign-in link as a QR; press L for a fresh one, or run --link from another shell.`
|
|
25308
25669
|
);
|