frizz-server 0.15.12 → 0.15.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dev-child.js +244 -121
- package/package.json +1 -1
- package/runtime/cc-worker/bin/frizz-mcp.mjs +16 -11
- package/runtime/cc-worker/hooks/session-seed.mjs +1 -1
- package/web-dist/assets/{abnfDiagram-VRR7QNED-CnXrrU0W.js → abnfDiagram-VRR7QNED-BBUrh3y4.js} +1 -1
- package/web-dist/assets/{arc-CmRXAX4k.js → arc-CzSC2w85.js} +1 -1
- package/web-dist/assets/architecture-TIHT7OUA-Bkytur05.js +1 -0
- package/web-dist/assets/{architectureDiagram-ZJ3FMSHR-Pdv71Zuq.js → architectureDiagram-ZJ3FMSHR-BZdFvCPS.js} +1 -1
- package/web-dist/assets/{blockDiagram-677ZJIJ3-B0b2_ZpN.js → blockDiagram-677ZJIJ3-CFw4HlAZ.js} +1 -1
- package/web-dist/assets/{c4Diagram-LMCZKHZV-GSc1L18t.js → c4Diagram-LMCZKHZV-BeWg4GGT.js} +1 -1
- package/web-dist/assets/channel-CRbCFAU9.js +1 -0
- package/web-dist/assets/{chunk-32BRIVSS-C0vobooW.js → chunk-32BRIVSS-Q_OGIKCm.js} +1 -1
- package/web-dist/assets/{chunk-52WLFC77-15f3pZkP.js → chunk-52WLFC77-C2ghSBWi.js} +1 -1
- package/web-dist/assets/{chunk-C7G6YPKG-m8AKg2cJ.js → chunk-C7G6YPKG-E7JHlQhC.js} +1 -1
- package/web-dist/assets/{chunk-EX3LRPZG-BW0qg3im.js → chunk-EX3LRPZG-c7FlR3e8.js} +1 -1
- package/web-dist/assets/{chunk-FWX5IMBZ-Ds3wze9N.js → chunk-FWX5IMBZ-1mU_aS7O.js} +2 -2
- package/web-dist/assets/{chunk-HOUHSVGY-B01xY05R.js → chunk-HOUHSVGY-DLJJRwLZ.js} +1 -1
- package/web-dist/assets/{chunk-ICXQ74PX-DLoF7WQO.js → chunk-ICXQ74PX-D7jDcuWv.js} +1 -1
- package/web-dist/assets/{chunk-MOJQB5TN-q3Li6yTJ.js → chunk-MOJQB5TN-C-KYsjX1.js} +1 -1
- package/web-dist/assets/{chunk-OGEWGWER-CgMb4Plp.js → chunk-OGEWGWER-Dnfz8Ffe.js} +1 -1
- package/web-dist/assets/{chunk-PUDLZKDR-DjLXqXCy.js → chunk-PUDLZKDR-BdzmoKkv.js} +1 -1
- package/web-dist/assets/{chunk-Q4XR5HBZ-DgVAx69q.js → chunk-Q4XR5HBZ-HNAZNAAv.js} +1 -1
- package/web-dist/assets/{chunk-RYQCIY6F-jOR4GLsC.js → chunk-RYQCIY6F-e5BApeF1.js} +1 -1
- package/web-dist/assets/{chunk-V7JOEXUC-N7ybBPSc.js → chunk-V7JOEXUC-cK1Hu1b4.js} +1 -1
- package/web-dist/assets/{chunk-VAUOI2AC-nUxrqZNY.js → chunk-VAUOI2AC-Df9HZp6Z.js} +1 -1
- package/web-dist/assets/{chunk-VR4S4FIN-6hmO23ny.js → chunk-VR4S4FIN-D6CAtMMq.js} +1 -1
- package/web-dist/assets/{chunk-WYO6CB5R--VNr0O3X.js → chunk-WYO6CB5R-JyE0Wb29.js} +1 -1
- package/web-dist/assets/{chunk-XXDRQBXY-nI5LprjB.js → chunk-XXDRQBXY-D_O0RmZ-.js} +1 -1
- package/web-dist/assets/{chunk-ZGVPDNZ5-BqBpuih6.js → chunk-ZGVPDNZ5-TKNm5tbx.js} +1 -1
- package/web-dist/assets/classDiagram-OUVF2IWQ-DV4x88Gs.js +1 -0
- package/web-dist/assets/classDiagram-v2-EOCWNBFH-DV4x88Gs.js +1 -0
- package/web-dist/assets/{cose-bilkent-JH36ORCC-DDZerLcw.js → cose-bilkent-JH36ORCC-aJ2vJo3h.js} +1 -1
- package/web-dist/assets/{cynefin-VYW2F7L2-e1KR3fxM.js → cynefin-VYW2F7L2-BzC5SCFm.js} +1 -1
- package/web-dist/assets/{cynefinDiagram-TSTJHNR4-C8BKMn0G.js → cynefinDiagram-TSTJHNR4-BUBneCyZ.js} +1 -1
- package/web-dist/assets/{dagre-VKFMJZFB-BmMWANIX.js → dagre-VKFMJZFB-CyqWV8--.js} +1 -1
- package/web-dist/assets/{diagram-FQU43EPY-dy3NpwvL.js → diagram-FQU43EPY-4Mmv21C-.js} +1 -1
- package/web-dist/assets/{diagram-G47NLZAW-Cpu90AXQ.js → diagram-G47NLZAW-C2RFiyED.js} +1 -1
- package/web-dist/assets/{diagram-NH7WQ7WH-5SHLGdgc.js → diagram-NH7WQ7WH-hZnAY_wV.js} +1 -1
- package/web-dist/assets/{diagram-OA4YK3LP-CLPs2sBw.js → diagram-OA4YK3LP-K1Zd1JAb.js} +1 -1
- package/web-dist/assets/{diagram-WEI45ONY-CMEkLLze.js → diagram-WEI45ONY-CHKaRrZp.js} +1 -1
- package/web-dist/assets/{dist-rUBtQxB1.js → dist-ImoGVzkQ.js} +1 -1
- package/web-dist/assets/{ebnfDiagram-CCIWWBDH-ClagaphN.js → ebnfDiagram-CCIWWBDH-BMR3sXl5.js} +1 -1
- package/web-dist/assets/{erDiagram-Q63AITRT-BEXXtSN9.js → erDiagram-Q63AITRT-DZmU3YbK.js} +1 -1
- package/web-dist/assets/eventmodeling-45OFAUF4-DGvQ-Cb8.js +1 -0
- package/web-dist/assets/flowDiagram-23GEKE2U-COGNeA6-.js +1 -0
- package/web-dist/assets/{ganttDiagram-NO4QXBWP-BoI4Xvme.js → ganttDiagram-NO4QXBWP-0cAynm96.js} +1 -1
- package/web-dist/assets/{gitGraph-TEB2WS4Q-D5Xdj6HL.js → gitGraph-TEB2WS4Q-DQgaAaBP.js} +1 -1
- package/web-dist/assets/{gitGraphDiagram-IHSO6WYX-o_hWIe-e.js → gitGraphDiagram-IHSO6WYX-BnULFM88.js} +1 -1
- package/web-dist/assets/index-Cs3gPFNZ.js +330 -0
- package/web-dist/assets/index-DA4tWPyA.css +2 -0
- package/web-dist/assets/{info-DKCQHKI2-BwhA8Kcv.js → info-DKCQHKI2-DlvSk8u3.js} +1 -1
- package/web-dist/assets/{infoDiagram-FWYZ7A6U-D1bT6ACJ.js → infoDiagram-FWYZ7A6U-CV-UmITw.js} +1 -1
- package/web-dist/assets/{ishikawaDiagram-FXEZZL3T-P7IDrOwM.js → ishikawaDiagram-FXEZZL3T-xQWAaJiF.js} +1 -1
- package/web-dist/assets/{journeyDiagram-5HDEW3XC-6XJBNIRb.js → journeyDiagram-5HDEW3XC-DJK8kVzY.js} +1 -1
- package/web-dist/assets/{kanban-definition-HUTT4EX6-La7dnlhq.js → kanban-definition-HUTT4EX6-moIoFsSZ.js} +1 -1
- package/web-dist/assets/{line-Dv2tv-OY.js → line-B9t5KW3M.js} +1 -1
- package/web-dist/assets/{linear-BO4R75Jg.js → linear-p05acNA3.js} +1 -1
- package/web-dist/assets/{mermaid-parser.core-DfuFuqcx.js → mermaid-parser.core-Db7dttgI.js} +3 -3
- package/web-dist/assets/{mermaid.core-BP_gsV2E.js → mermaid.core-BFbkt8RT.js} +3 -3
- package/web-dist/assets/{mindmap-definition-LN4V7U3C-BPDWuBXV.js → mindmap-definition-LN4V7U3C-dOYDtsm4.js} +1 -1
- package/web-dist/assets/{packet-7NZHBO7P-DvGyCLho.js → packet-7NZHBO7P-Y34L2B_H.js} +1 -1
- package/web-dist/assets/{pegDiagram-2B236MQR-B3XyjF78.js → pegDiagram-2B236MQR-BlI8nWnE.js} +1 -1
- package/web-dist/assets/{pie-RZYD4A2V-BcmTzATg.js → pie-RZYD4A2V-n-Qg1sTG.js} +1 -1
- package/web-dist/assets/{pieDiagram-ENE6RG2P-B13x3h-1.js → pieDiagram-ENE6RG2P-DoHW9Gyq.js} +1 -1
- package/web-dist/assets/{quadrantDiagram-ABIIQ3AL-B_qjpmSD.js → quadrantDiagram-ABIIQ3AL-BMUuqVdW.js} +1 -1
- package/web-dist/assets/{radar-I7S5WNFK-zvSO8c-R.js → radar-I7S5WNFK-skxmXNaM.js} +1 -1
- package/web-dist/assets/{railroad-3IZDKUUU-CJtUTUYW.js → railroad-3IZDKUUU-LfjLO5Ny.js} +1 -1
- package/web-dist/assets/railroad-abnf-AHOZXSZD-D4N57HJe.js +1 -0
- package/web-dist/assets/railroad-ebnf-EBAXGLYW-kukg91Jv.js +1 -0
- package/web-dist/assets/railroad-peg-LSFZ7HO6-4UH_xlt7.js +1 -0
- package/web-dist/assets/{railroadDiagram-RFXS5EU6-BP7Scsjp.js → railroadDiagram-RFXS5EU6-Zdj5BMQG.js} +1 -1
- package/web-dist/assets/{requirementDiagram-TGXJPOKE-BLn9ee9E.js → requirementDiagram-TGXJPOKE-DcFm1DAf.js} +1 -1
- package/web-dist/assets/{sankeyDiagram-HTMAVEWB-DhjUURDl.js → sankeyDiagram-HTMAVEWB-BcRmQRQe.js} +1 -1
- package/web-dist/assets/{sequenceDiagram-DBY2YBRQ-alvtgf-F.js → sequenceDiagram-DBY2YBRQ-bET8bpzv.js} +1 -1
- package/web-dist/assets/{src-C6GQP2x2.js → src-CUSFAnq6.js} +1 -1
- package/web-dist/assets/{stateDiagram-2N3HPSRC-sga-NxRF.js → stateDiagram-2N3HPSRC-AGBIK4Rz.js} +1 -1
- package/web-dist/assets/stateDiagram-v2-6OUMAXLB-CGZk-pxB.js +1 -0
- package/web-dist/assets/{swimlanes-5IMT3BWC-tVkOu3TT.js → swimlanes-5IMT3BWC-BrxNGoSO.js} +1 -1
- package/web-dist/assets/swimlanesDiagram-G3AALYLV-tBUJkYsP.js +8 -0
- package/web-dist/assets/{timeline-definition-FHXFAJF6-DEAZRgmn.js → timeline-definition-FHXFAJF6-Dqoh4MQ-.js} +1 -1
- package/web-dist/assets/{treeView-QDETBFTQ-Dnvq1Ma7.js → treeView-QDETBFTQ-C_vYdzCy.js} +1 -1
- package/web-dist/assets/{treemap-6X3UGDF4-Ce3cuN8q.js → treemap-6X3UGDF4-B_o40Eep.js} +1 -1
- package/web-dist/assets/{vennDiagram-L72KCM5P-DMyU7yi9.js → vennDiagram-L72KCM5P-AHb21nUH.js} +1 -1
- package/web-dist/assets/{wardley-OPB4EBWU-Dyao3Zne.js → wardley-OPB4EBWU-CDvRbffW.js} +1 -1
- package/web-dist/assets/{wardleyDiagram-EHGQE667-B6C8_1LE.js → wardleyDiagram-EHGQE667-DmLMQrCO.js} +1 -1
- package/web-dist/assets/{xychartDiagram-FW5EYKEG-_P-iqki1.js → xychartDiagram-FW5EYKEG-CBq8Fuud.js} +1 -1
- package/web-dist/index.html +2 -2
- package/web-dist/assets/architecture-TIHT7OUA-C-U11PKN.js +0 -1
- package/web-dist/assets/channel-jQPajw2y.js +0 -1
- package/web-dist/assets/classDiagram-OUVF2IWQ-BVGlW0VN.js +0 -1
- package/web-dist/assets/classDiagram-v2-EOCWNBFH-BVGlW0VN.js +0 -1
- package/web-dist/assets/eventmodeling-45OFAUF4-BPmoLPav.js +0 -1
- package/web-dist/assets/flowDiagram-23GEKE2U-CC63wNIt.js +0 -1
- package/web-dist/assets/index-DTxhrDcZ.js +0 -330
- package/web-dist/assets/index-W88ZnKOr.css +0 -2
- package/web-dist/assets/railroad-abnf-AHOZXSZD-CM-7EymF.js +0 -1
- package/web-dist/assets/railroad-ebnf-EBAXGLYW--3-yYzZ6.js +0 -1
- package/web-dist/assets/railroad-peg-LSFZ7HO6-CgVkrtHL.js +0 -1
- package/web-dist/assets/stateDiagram-v2-6OUMAXLB-BburKdyU.js +0 -1
- package/web-dist/assets/swimlanesDiagram-G3AALYLV-eANJELfk.js +0 -8
package/dist/dev-child.js
CHANGED
|
@@ -13349,7 +13349,8 @@ function splitAwaitingFrontmatter(raw2) {
|
|
|
13349
13349
|
if (title) parsed.hints.push({ kind: "title", value: title });
|
|
13350
13350
|
const stepHints = steps.map((step) => step.trim()).filter(Boolean).slice(0, AWAITING_STEPS_MAX).map((step) => ({ kind: "step", value: step.slice(0, AWAITING_STEP_VALUE_MAX) }));
|
|
13351
13351
|
const questionHints = parsed.hints.filter((h10) => h10.kind === "question").slice(0, AWAITING_QUESTIONS_MAX);
|
|
13352
|
-
|
|
13352
|
+
let items = 0;
|
|
13353
|
+
const capped = parsed.hints.filter((h10) => h10.kind !== "question" && (AWAITING_SCALAR_KINDS.has(h10.kind) || items++ < AWAITING_HINT_MAX));
|
|
13353
13354
|
return { body: rest.join("\n").trim(), hints: [...capped, ...questionHints, ...stepHints] };
|
|
13354
13355
|
}
|
|
13355
13356
|
function inlineSteps(value) {
|
|
@@ -13397,21 +13398,44 @@ function parseAwaitingYaml(text2) {
|
|
|
13397
13398
|
for (const entry of Array.isArray(raw2) ? raw2 : [raw2]) push("question", entry);
|
|
13398
13399
|
} else if (key === "for") {
|
|
13399
13400
|
push("for", raw2);
|
|
13401
|
+
} else if (key === "status") {
|
|
13402
|
+
push("status", raw2);
|
|
13400
13403
|
} else if (key === "needs_input" || key === "needs-input") {
|
|
13401
13404
|
push("needs_input", raw2);
|
|
13402
13405
|
}
|
|
13403
13406
|
}
|
|
13404
13407
|
return { ok: true, hints };
|
|
13405
13408
|
}
|
|
13406
|
-
function
|
|
13407
|
-
|
|
13408
|
-
|
|
13409
|
+
function statusValueOf(value) {
|
|
13410
|
+
const v = value.trim().toLowerCase().replace(/-/g, "_");
|
|
13411
|
+
return AWAITING_STATUSES.includes(v) ? v : null;
|
|
13412
|
+
}
|
|
13413
|
+
function restAnswerLines(hints) {
|
|
13414
|
+
let status = null;
|
|
13415
|
+
let needsInput = null;
|
|
13409
13416
|
for (const h10 of hints ?? []) {
|
|
13410
|
-
if (h10.kind
|
|
13411
|
-
|
|
13412
|
-
|
|
13417
|
+
if (h10.kind === "status") status = statusValueOf(h10.value);
|
|
13418
|
+
else if (h10.kind === "needs_input") {
|
|
13419
|
+
const value = h10.value.trim().toLowerCase();
|
|
13420
|
+
needsInput = value === "true" ? true : value === "false" ? false : null;
|
|
13421
|
+
}
|
|
13413
13422
|
}
|
|
13414
|
-
return
|
|
13423
|
+
return { status, needsInput };
|
|
13424
|
+
}
|
|
13425
|
+
function fenceWaitsOnHuman(hints) {
|
|
13426
|
+
return awaitingSteps(hints).length > 0 || awaitingQuestions(hints).length > 0;
|
|
13427
|
+
}
|
|
13428
|
+
function awaitingStatus(hints) {
|
|
13429
|
+
if (fenceWaitsOnHuman(hints)) return "needs_input";
|
|
13430
|
+
const { status, needsInput } = restAnswerLines(hints);
|
|
13431
|
+
if (status) return status;
|
|
13432
|
+
return needsInput === true ? "needs_input" : null;
|
|
13433
|
+
}
|
|
13434
|
+
function awaitingNeedsInput(hints) {
|
|
13435
|
+
if (fenceWaitsOnHuman(hints)) return true;
|
|
13436
|
+
const { status, needsInput } = restAnswerLines(hints);
|
|
13437
|
+
if (status) return status === "needs_input";
|
|
13438
|
+
return needsInput;
|
|
13415
13439
|
}
|
|
13416
13440
|
function isAwaitingItemKind(kind) {
|
|
13417
13441
|
return AWAITING_ITEM_KINDS.includes(kind);
|
|
@@ -13546,9 +13570,9 @@ function signoffNudgeMessage(ops, needsInput = false) {
|
|
|
13546
13570
|
if (lines.length) {
|
|
13547
13571
|
lines.push("", "An ```awaiting fence names only what you are ACTUALLY waiting on, one such list per kind, plus");
|
|
13548
13572
|
if (needsInput) {
|
|
13549
|
-
lines.push("a required `for:` duration (`30s`/`15m`/`2h`/`3d`) and a required `
|
|
13550
|
-
lines.push("a `---` line and whatever prose the human needs. Frizz checks every id:
|
|
13551
|
-
lines.push("not running and you are bumped rather than parked.");
|
|
13573
|
+
lines.push("a required `for:` duration (`30s`/`15m`/`2h`/`3d`) and a required `status:` (`working`, `watching`");
|
|
13574
|
+
lines.push("or `needs_input`), then a `---` line and whatever prose the human needs. Frizz checks every id:");
|
|
13575
|
+
lines.push("name something that is not running and you are bumped rather than parked.");
|
|
13552
13576
|
} else {
|
|
13553
13577
|
lines.push("a required `for:` duration (`30s`/`15m`/`2h`/`3d`), then a `---` line and whatever prose you want");
|
|
13554
13578
|
lines.push("(optional). Frizz checks every id: name something that is not running and you are bumped");
|
|
@@ -13577,22 +13601,27 @@ function signoffNudgeAwaitingLines(needsInput) {
|
|
|
13577
13601
|
return [
|
|
13578
13602
|
"- `` ```awaiting `` \u2014 you are WAITING on work that is actually running: a background shell, a",
|
|
13579
13603
|
" sub-agent, a timer or a registered PR. FRONTMATTER, THEN MARKDOWN: one YAML list per kind of thing",
|
|
13580
|
-
" you are waiting on, a REQUIRED `for:` duration, a REQUIRED `
|
|
13581
|
-
"
|
|
13604
|
+
" you are waiting on, a REQUIRED `for:` duration, a REQUIRED `status:`, then optionally a `---` line",
|
|
13605
|
+
" and prose.",
|
|
13582
13606
|
"",
|
|
13583
13607
|
" ```awaiting",
|
|
13584
13608
|
" agents: [<the id your runtime gave you>]",
|
|
13585
|
-
"
|
|
13609
|
+
" status: working",
|
|
13586
13610
|
" for: 2h",
|
|
13587
13611
|
" ```",
|
|
13588
13612
|
"",
|
|
13589
|
-
" `
|
|
13590
|
-
"
|
|
13591
|
-
"
|
|
13592
|
-
"
|
|
13593
|
-
"
|
|
13594
|
-
"
|
|
13595
|
-
"
|
|
13613
|
+
" `status:` says where the thread sits while you wait, in one of three words:",
|
|
13614
|
+
" - `working` \u2014 what you named finishes by itself: a test, a build, a benchmark, CI, a sub-agent doing",
|
|
13615
|
+
" a task. The thread shows as running until the work wakes you.",
|
|
13616
|
+
" - `watching` \u2014 something has to HAPPEN outside the thread: a release, a review, another agent's",
|
|
13617
|
+
" merge, the next daily cycle. The thread is snoozed, and nothing on its row moves, until a named",
|
|
13618
|
+
" item reports or `for:` runs out.",
|
|
13619
|
+
" - `needs_input` \u2014 the human can read, try or act on something NOW while the work runs (a partial",
|
|
13620
|
+
" result, a file you wrote, a server to try), even if you need nothing back from them. The thread",
|
|
13621
|
+
" goes into their queue, and the prose under `---` says what to look at.",
|
|
13622
|
+
" `working` and `watching` owe NO write-up: the fence alone is the whole message. If you wrote ANY",
|
|
13623
|
+
" words for the human at this rest, it is `needs_input` \u2014 nothing else is put in front of them. A rest",
|
|
13624
|
+
" on running work with NO fence is a bare rest, and it lands in the human's queue."
|
|
13596
13625
|
];
|
|
13597
13626
|
}
|
|
13598
13627
|
function signoffNudgeText(needsInput) {
|
|
@@ -13805,9 +13834,13 @@ function hasLiveSubAgents(t) {
|
|
|
13805
13834
|
return (t.subAgents ?? []).some((s) => isDirectSubAgent(s) && s.state === "running");
|
|
13806
13835
|
}
|
|
13807
13836
|
function hasLiveOps(t) {
|
|
13837
|
+
if (watchingRest(t)) return false;
|
|
13808
13838
|
if (hasLiveSubAgents(t)) return true;
|
|
13809
13839
|
return t.awaitingBackground === true && !parkedOnArmedTimerAlone(t);
|
|
13810
13840
|
}
|
|
13841
|
+
function watchingRest(t) {
|
|
13842
|
+
return t.waitStatus === "watching" && t.runtime === "turn-idle";
|
|
13843
|
+
}
|
|
13811
13844
|
function parkedOnArmedTimerAlone(t) {
|
|
13812
13845
|
if (t.awaitingBackground !== true) return false;
|
|
13813
13846
|
const watches = t.watches ?? [];
|
|
@@ -13823,12 +13856,14 @@ function isSnoozed(t, nowMs = Date.now()) {
|
|
|
13823
13856
|
const userSnooze = futureSnoozedUntil(t, nowMs) !== void 0;
|
|
13824
13857
|
if (t.state === "archived") return false;
|
|
13825
13858
|
const eventSnooze = t.bgSnoozed === true && t.runtime === "turn-idle";
|
|
13826
|
-
|
|
13859
|
+
const watching = watchingRest(t);
|
|
13860
|
+
if (!watching && (hasLiveSubAgents(t) || hasLiveOps(t) && !eventSnooze)) return false;
|
|
13827
13861
|
if (userSnooze) return t.runtime !== "running" && t.runtime !== "spawning";
|
|
13828
13862
|
if (t.limitPause && t.foreign !== true) return false;
|
|
13829
13863
|
if (t.needsYou || t.pendingAsk || t.runtime === "perm-prompt") return false;
|
|
13830
13864
|
if (!atRest(t)) return false;
|
|
13831
13865
|
if (eventSnooze) return true;
|
|
13866
|
+
if (watching) return true;
|
|
13832
13867
|
const declaredWait = t.lastFence?.kind === "awaiting";
|
|
13833
13868
|
return userSnooze || declaredWait;
|
|
13834
13869
|
}
|
|
@@ -14021,7 +14056,7 @@ function parseGithubWakeSteer(text2) {
|
|
|
14021
14056
|
function frizzRoute(path3) {
|
|
14022
14057
|
return `${FRIZZ_ROUTE_PREFIX}${path3.startsWith("/") ? path3 : `/${path3}`}`;
|
|
14023
14058
|
}
|
|
14024
|
-
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, ClaudeModel, AcpAgent, ACP_MODEL_PREFIX, AcpAgentModel, AcpAgentModels, AcpAgentModelsInput, ThreadProfileOption, ThreadAgent, SubAgentView, BgShellView, CompletionHoldOp, CompletionHold, AskOption, AskQuestion, PendingAsk, AwaitingHint, RETIRED_AWAITING_KINDS, RETIRED_LINE_RE, RETIRED_AWAITING_REPLACEMENT, AWAITING_KEY_RE, AWAITING_YAML_KEYS, AWAITING_SEQUENCE_KEYS, AWAITING_HINT_MAX, AWAITING_HINT_VALUE_MAX, AWAITING_STEPS_MAX, AWAITING_STEP_VALUE_MAX, AWAITING_QUESTIONS_MAX, AWAITING_TITLE_MAX, AWAITING_ITEM_KINDS, AWAITING_DURATION_RE, DURATION_UNIT_MS, AWAITING_FOR_MAX_MS, SnoozeUntil, SNOOZE_PROMPT_MAX, SnoozePrompt, RECURRING_PROMPT_MAX, RECURRING_MIN_INTERVAL_SECONDS, RECURRING_MAX_INTERVAL_SECONDS, RecurringPromptText, RecurringIntervalSeconds, ThreadRecurringPrompt, INTERRUPT_MARKERS, ALLDONE_SENTINEL, OPT_OUT_NOTE, OVER_QUESTION_NOTE, TIMER_PROMPT_MAX, TIMER_MAX_DELAY_SECONDS, TIMER_MAX_ARMED, TimerPromptText, PR_WATCH_SPENT_TRAILER, PR_WATCH_ARMED_TRAILER, SHELL_DONE_TRAILER, ISSUE_WATCH_SPENT_TRAILER, ISSUE_WATCH_ARMED_TRAILER, INTERRUPT_ENDED_LEAD, SIGNOFF_NUDGE_MARKER, SIGNOFF_NUDGE_MESSAGE, SIGNOFF_NUDGE_MESSAGE_NEEDS_INPUT, PARK_CORRECTION_NAMES_LEAD, PARK_CORRECTION_RETIRED_LEAD, PARK_CORRECTION_QUESTION_LEAD, PARK_CORRECTION_NEEDS_INPUT_LEAD, ThreadWatchKind, GithubChecksState, GithubMergeState, GithubWatchStatus, GithubIssueStatus, ThreadWatchView, PR_WATCH_FOR_MAX_MS, PR_WATCH_DEFAULT_FOR_MS, PR_WATCH_MAX_ARMED, PrWatchView, AddOwnPrWatchInput, AddOwnPrWatchResult, DropOwnPrWatchInput, DropOwnPrWatchResult, OwnWatchKind, AddOwnWatchInput, OwnWatchView, AddOwnWatchResult, DropOwnWatchInput, DropOwnWatchResult, OWN_WATCH_MAX_ARMED, QUESTION_FENCE_RETIRED_AT, NEEDS_INPUT_REQUIRED_AT, AskQuestionKind, ASK_MAX_DEPTH, AskedOptionSchema, AskedQuestionSchema, AskInput, RegisteredQuestionView, AskResult, UnaskInput, UnaskResult, QuestionAnswerSchema, AnswerQuestionsInput, AnswerQuestionsResult, DismissQuestionsInput, DismissQuestionsResult, SettledQuestionView, ThreadSettledQuestionsResult, BURIED_ANSWERS_HEADER, ANSWER_FOLLOW_UP_MARKER, ANSWER_CONTINUATION_INDENT, indentAnswerContinuation, DISMISSED_ANSWER, MarkOwnDoneInput, MarkOwnDoneResult, ListOwnPrWatchesInput, OwnPrWatchesResult, ThreadTimerView, ThreadFence, LimitWindow, LimitPause, ProviderError, ThreadLinkView, UpsertOwnLinkInput, UpsertOwnLinkResult, DropOwnLinkInput, DropOwnLinkResult, LiveTool, ThreadView, BoardErrorItem, BoardSnapshot, QuotaWindow, ProviderQuota, QuotaSnapshot, ProviderAuth, AccountEmails, AuthSnapshot, AccountBackend, AccountLogoutInput, AccountLogoutResult, PermissionMode, LocalFileOpener, Settings, DispatchProviderPreferences, DispatchPreferences, DispatchProfileSnapshotShape, DispatchProfileSnapshot, SetDispatchPreferenceInput, DispatchInput, ADOPT_THREAD_MESSAGE_MAX_CHARS, AdoptThreadInput, AdoptThreadResult, AdoptSessionInput, FollowUpInput, DismissFailedFollowUpInput, DismissFailedFollowUpResult, UnqueueFollowUpInput, UnqueueFollowUpResult, DeliverQueuedNowInput, DeliverQueuedNowResult, CompactThreadInput, SetThreadSnoozeInput, SetThreadPinnedInput, SetThreadRecurringPromptInput, SetOwnThreadRecurringPromptInput, SetOwnThreadRecurringPromptResult, GetOwnThreadRecurringPromptInput, OwnThreadRecurringPromptResult, SetOwnThreadTimerInput, CancelOwnThreadTimerInput, ListOwnThreadTimersInput, OwnThreadTimersResult, ThreadActivityItem, ListOwnThreadActivityInput, OwnThreadActivityResult, SetOwnThreadTimerResult, CancelOwnThreadTimerResult, SetOwnThreadStopHookInput, SetOwnThreadHeartbeatInput, ThreadPluginReloadResult, RenameThreadInput, AiRenameThreadInput, AiRenameThreadResult, SetOwnThreadTitleInput, SetOwnThreadTitleResult, SetThreadPermissionInput, SetThreadPermissionResult, ThreadProfileOptionsInput, ThreadProfileOptionsResult, ThreadSkillSource, ThreadSkill, ThreadSkillsInput, ThreadSkillsResult, SetThreadProfileInput, SetThreadProfileResult, UpgradeThreadModelInput, UpgradeThreadModelResult, DISPATCH_TASK_BANNER, DISPATCH_TASK_BANNER_MARKER, GITHUB_DISPATCH_UI_BOUNDARY, WAKE_TIME_HEADER_TAIL, WAKE_TRAILERS, HUMAN_GAP_FLOOR_MS, HUMAN_GAP_NOTE_TAIL, WAKE_DELIVERY_TOKEN_TAIL, WAKE_DELIVERY_TOKEN_LINE, NOISE_PREFIXES, AGENT_MESSAGE_WRAPPER, GithubWakeItem, GithubWakeSteer, WAKE_SCOPE, WAKE_REVIEW_LEAD, WAKE_BACKLOG_TAIL, WAKE_REF, WAKE_SINGLE, WAKE_MULTI_HEAD, WAKE_ITEM, WAKE_MORE, PR_WATCH_FINISHED, PR_WATCH_CI_PASSED, PR_WATCH_CI_GATED, PR_WATCH_STATE, PR_WATCH_CI_FAILED, GithubStatus, GithubRefCard, GithubRefPreviewInput, GithubRefPreviewResult, GithubItem, GithubListInput, GithubListResult, GithubBatchInput, GithubBatchResult, BoardMeta, ServerEvent, TranscriptEdit, TranscriptTodo, TranscriptToolCall, TranscriptPart, TranscriptMessage, TranscriptPageCursor, EditedFile, TranscriptPage, TranscriptEarlierInput, SocketTranscriptSlug, SocketFilePath, SocketTranscriptClientMsg, SocketFileClientMsg, SocketClientMsg, ProjectCard, ProjectRailCounts, PROJECT_ICON_EXTENSIONS, PROJECT_ICON_MAX_BASE64_CHARS, DirectoryPickResult, ThreadLocation, FRIZZ_ROUTE_PREFIX, DEFAULT_PORT, threadIdentityName;
|
|
14059
|
+
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, ClaudeModel, CODEX_MODELS_FALLBACK, AcpAgent, ACP_MODEL_PREFIX, AcpAgentModel, AcpAgentModels, AcpAgentModelsInput, ThreadProfileOption, ThreadAgent, SubAgentView, BgShellView, CompletionHoldOp, CompletionHold, AskOption, AskQuestion, PendingAsk, AwaitingHint, RETIRED_AWAITING_KINDS, RETIRED_LINE_RE, RETIRED_AWAITING_REPLACEMENT, AWAITING_KEY_RE, AWAITING_YAML_KEYS, AWAITING_SEQUENCE_KEYS, AWAITING_HINT_MAX, AWAITING_HINT_VALUE_MAX, AWAITING_SCALAR_KINDS, AWAITING_STEPS_MAX, AWAITING_STEP_VALUE_MAX, AWAITING_QUESTIONS_MAX, AWAITING_TITLE_MAX, AWAITING_STATUSES, AWAITING_ITEM_KINDS, AWAITING_DURATION_RE, DURATION_UNIT_MS, AWAITING_FOR_MAX_MS, SnoozeUntil, SNOOZE_PROMPT_MAX, SnoozePrompt, RECURRING_PROMPT_MAX, RECURRING_MIN_INTERVAL_SECONDS, RECURRING_MAX_INTERVAL_SECONDS, RecurringPromptText, RecurringIntervalSeconds, ThreadRecurringPrompt, INTERRUPT_MARKERS, ALLDONE_SENTINEL, OPT_OUT_NOTE, OVER_QUESTION_NOTE, TIMER_PROMPT_MAX, TIMER_MAX_DELAY_SECONDS, TIMER_MAX_ARMED, TimerPromptText, PR_WATCH_SPENT_TRAILER, PR_WATCH_ARMED_TRAILER, SHELL_DONE_TRAILER, ISSUE_WATCH_SPENT_TRAILER, ISSUE_WATCH_ARMED_TRAILER, INTERRUPT_ENDED_LEAD, SIGNOFF_NUDGE_MARKER, SIGNOFF_NUDGE_MESSAGE, SIGNOFF_NUDGE_MESSAGE_NEEDS_INPUT, PARK_CORRECTION_NAMES_LEAD, PARK_CORRECTION_RETIRED_LEAD, PARK_CORRECTION_QUESTION_LEAD, PARK_CORRECTION_NEEDS_INPUT_LEAD, ThreadWatchKind, GithubChecksState, GithubMergeState, GithubWatchStatus, GithubIssueStatus, ThreadWatchView, PR_WATCH_FOR_MAX_MS, PR_WATCH_DEFAULT_FOR_MS, PR_WATCH_MAX_ARMED, PrWatchView, AddOwnPrWatchInput, AddOwnPrWatchResult, DropOwnPrWatchInput, DropOwnPrWatchResult, OwnWatchKind, AddOwnWatchInput, OwnWatchView, AddOwnWatchResult, DropOwnWatchInput, DropOwnWatchResult, OWN_WATCH_MAX_ARMED, QUESTION_FENCE_RETIRED_AT, NEEDS_INPUT_REQUIRED_AT, AskQuestionKind, ASK_MAX_DEPTH, AskedOptionSchema, AskedQuestionSchema, AskInput, RegisteredQuestionView, AskResult, UnaskInput, UnaskResult, QuestionAnswerSchema, AnswerQuestionsInput, AnswerQuestionsResult, DismissQuestionsInput, DismissQuestionsResult, SettledQuestionView, ThreadSettledQuestionsResult, BURIED_ANSWERS_HEADER, ANSWER_FOLLOW_UP_MARKER, ANSWER_CONTINUATION_INDENT, indentAnswerContinuation, DISMISSED_ANSWER, MarkOwnDoneInput, MarkOwnDoneResult, ListOwnPrWatchesInput, OwnPrWatchesResult, ThreadTimerView, ThreadFence, LimitWindow, LimitPause, ProviderError, ThreadLinkView, UpsertOwnLinkInput, UpsertOwnLinkResult, DropOwnLinkInput, DropOwnLinkResult, LiveTool, ThreadView, BoardErrorItem, BoardSnapshot, QuotaWindow, ProviderQuota, QuotaSnapshot, ProviderAuth, AccountEmails, AuthSnapshot, AccountBackend, AccountLogoutInput, AccountLogoutResult, PermissionMode, LocalFileOpener, Settings, DispatchProviderPreferences, DispatchPreferences, DispatchProfileSnapshotShape, DispatchProfileSnapshot, SetDispatchPreferenceInput, DispatchInput, ADOPT_THREAD_MESSAGE_MAX_CHARS, AdoptThreadInput, AdoptThreadResult, AdoptSessionInput, FollowUpInput, DismissFailedFollowUpInput, DismissFailedFollowUpResult, UnqueueFollowUpInput, UnqueueFollowUpResult, DeliverQueuedNowInput, DeliverQueuedNowResult, CompactThreadInput, SetThreadSnoozeInput, SetThreadPinnedInput, SetThreadRecurringPromptInput, SetOwnThreadRecurringPromptInput, SetOwnThreadRecurringPromptResult, GetOwnThreadRecurringPromptInput, OwnThreadRecurringPromptResult, SetOwnThreadTimerInput, CancelOwnThreadTimerInput, ListOwnThreadTimersInput, OwnThreadTimersResult, ThreadActivityItem, ListOwnThreadActivityInput, OwnThreadActivityResult, SetOwnThreadTimerResult, CancelOwnThreadTimerResult, SetOwnThreadStopHookInput, SetOwnThreadHeartbeatInput, ThreadPluginReloadResult, RenameThreadInput, AiRenameThreadInput, AiRenameThreadResult, SetOwnThreadTitleInput, SetOwnThreadTitleResult, SetThreadPermissionInput, SetThreadPermissionResult, ThreadProfileOptionsInput, ThreadProfileOptionsResult, ThreadSkillSource, ThreadSkill, ThreadSkillsInput, ThreadSkillsResult, SetThreadProfileInput, SetThreadProfileResult, UpgradeThreadModelInput, UpgradeThreadModelResult, DISPATCH_TASK_BANNER, DISPATCH_TASK_BANNER_MARKER, GITHUB_DISPATCH_UI_BOUNDARY, WAKE_TIME_HEADER_TAIL, WAKE_TRAILERS, HUMAN_GAP_FLOOR_MS, HUMAN_GAP_NOTE_TAIL, WAKE_DELIVERY_TOKEN_TAIL, WAKE_DELIVERY_TOKEN_LINE, NOISE_PREFIXES, AGENT_MESSAGE_WRAPPER, GithubWakeItem, GithubWakeSteer, WAKE_SCOPE, WAKE_REVIEW_LEAD, WAKE_BACKLOG_TAIL, WAKE_REF, WAKE_SINGLE, WAKE_MULTI_HEAD, WAKE_ITEM, WAKE_MORE, PR_WATCH_FINISHED, PR_WATCH_CI_PASSED, PR_WATCH_CI_GATED, PR_WATCH_STATE, PR_WATCH_CI_FAILED, GithubStatus, GithubRefCard, GithubRefPreviewInput, GithubRefPreviewResult, GithubItem, GithubListInput, GithubListResult, GithubBatchInput, GithubBatchResult, BoardMeta, ServerEvent, TranscriptEdit, TranscriptTodo, TranscriptToolCall, TranscriptPart, TranscriptMessage, TranscriptPageCursor, EditedFile, TranscriptPage, TranscriptEarlierInput, SocketTranscriptSlug, SocketFilePath, SocketTranscriptClientMsg, SocketFileClientMsg, SocketClientMsg, ProjectCard, ProjectRailCounts, PROJECT_ICON_EXTENSIONS, PROJECT_ICON_MAX_BASE64_CHARS, DirectoryPickResult, ThreadLocation, FRIZZ_ROUTE_PREFIX, DEFAULT_PORT, threadIdentityName;
|
|
14025
14060
|
var init_src = __esm({
|
|
14026
14061
|
"packages/shared/src/index.ts"() {
|
|
14027
14062
|
"use strict";
|
|
@@ -14163,6 +14198,15 @@ var init_src = __esm({
|
|
|
14163
14198
|
// Absent exactly when `resolvedModel` is.
|
|
14164
14199
|
edition: external_exports.string().optional()
|
|
14165
14200
|
});
|
|
14201
|
+
CODEX_MODELS_FALLBACK = [
|
|
14202
|
+
{ slug: "gpt-6.1-sol", displayName: "GPT-6.1 Sol", defaultEffort: "low", efforts: ["low", "medium", "high", "xhigh", "max", "ultra"] },
|
|
14203
|
+
{ slug: "gpt-6-astra", displayName: "GPT-6 Astra", defaultEffort: "medium", efforts: ["low", "medium", "high", "xhigh", "max", "ultra"] },
|
|
14204
|
+
{ slug: "gpt-6-sol", displayName: "GPT-6 Sol", defaultEffort: "medium", efforts: ["low", "medium", "high", "xhigh", "max", "ultra"] },
|
|
14205
|
+
{ slug: "gpt-6-luna", displayName: "GPT-6 Luna", defaultEffort: "medium", efforts: ["low", "medium", "high", "xhigh", "max"] },
|
|
14206
|
+
{ slug: "gpt-5.6-sol", displayName: "GPT-5.6 Sol", defaultEffort: "low", efforts: ["low", "medium", "high", "xhigh", "max", "ultra"] },
|
|
14207
|
+
{ slug: "gpt-5.6-terra", displayName: "GPT-5.6 Terra", defaultEffort: "medium", efforts: ["low", "medium", "high", "xhigh", "max", "ultra"] },
|
|
14208
|
+
{ slug: "gpt-5.6-luna", displayName: "GPT-5.6 Luna", defaultEffort: "medium", efforts: ["low", "medium", "high", "xhigh", "max"] }
|
|
14209
|
+
];
|
|
14166
14210
|
AcpAgent = external_exports.object({
|
|
14167
14211
|
id: external_exports.string(),
|
|
14168
14212
|
label: external_exports.string(),
|
|
@@ -14360,7 +14404,7 @@ var init_src = __esm({
|
|
|
14360
14404
|
questions: external_exports.array(AskQuestion)
|
|
14361
14405
|
});
|
|
14362
14406
|
AwaitingHint = external_exports.object({
|
|
14363
|
-
kind: external_exports.enum(["shell", "agent", "timer", "pr", "issue", "for", "title", "needs_input", "step", "question"]),
|
|
14407
|
+
kind: external_exports.enum(["shell", "agent", "timer", "pr", "issue", "for", "title", "status", "needs_input", "step", "question"]),
|
|
14364
14408
|
value: external_exports.string()
|
|
14365
14409
|
});
|
|
14366
14410
|
RETIRED_AWAITING_KINDS = ["watch", "pr-watch", "human", "ci", "session", "shell", "agent", "timer", "pr", "reason"];
|
|
@@ -14382,7 +14426,7 @@ var init_src = __esm({
|
|
|
14382
14426
|
"reason": "put it below the `---` as ordinary Markdown \u2014 the frontmatter is YAML now and takes no prose"
|
|
14383
14427
|
};
|
|
14384
14428
|
AWAITING_KEY_RE = /^([a-z][a-z_-]*):\s*(\S.*)?$/i;
|
|
14385
|
-
AWAITING_YAML_KEYS = /* @__PURE__ */ new Set(["shells", "agents", "timers", "prs", "issues", "questions", "for", "title", "steps", "needs_input", "needs-input"]);
|
|
14429
|
+
AWAITING_YAML_KEYS = /* @__PURE__ */ new Set(["shells", "agents", "timers", "prs", "issues", "questions", "for", "title", "steps", "status", "needs_input", "needs-input"]);
|
|
14386
14430
|
AWAITING_SEQUENCE_KEYS = {
|
|
14387
14431
|
shells: "shell",
|
|
14388
14432
|
agents: "agent",
|
|
@@ -14395,10 +14439,12 @@ var init_src = __esm({
|
|
|
14395
14439
|
};
|
|
14396
14440
|
AWAITING_HINT_MAX = 8;
|
|
14397
14441
|
AWAITING_HINT_VALUE_MAX = 200;
|
|
14442
|
+
AWAITING_SCALAR_KINDS = /* @__PURE__ */ new Set(["for", "title", "status", "needs_input"]);
|
|
14398
14443
|
AWAITING_STEPS_MAX = 12;
|
|
14399
14444
|
AWAITING_STEP_VALUE_MAX = 500;
|
|
14400
14445
|
AWAITING_QUESTIONS_MAX = 24;
|
|
14401
14446
|
AWAITING_TITLE_MAX = 120;
|
|
14447
|
+
AWAITING_STATUSES = ["needs_input", "working", "watching"];
|
|
14402
14448
|
AWAITING_ITEM_KINDS = ["shell", "agent", "timer", "pr", "issue"];
|
|
14403
14449
|
AWAITING_DURATION_RE = /^(\d{1,5})(s|m|h|d)$/;
|
|
14404
14450
|
DURATION_UNIT_MS = { s: 1e3, m: 6e4, h: 36e5, d: 864e5 };
|
|
@@ -15024,6 +15070,13 @@ ${ANSWER_CONTINUATION_INDENT}`);
|
|
|
15024
15070
|
// Optional like needsYou/crashed: absent ⇒ a pre-restart server or a non-session row; the client
|
|
15025
15071
|
// treats absence as false.
|
|
15026
15072
|
awaitingBackground: external_exports.boolean().optional(),
|
|
15073
|
+
// SERVER-DERIVED: which band a rest OUT OF THE QUEUE sits in (board.deriveWaitStatus, 2026-10-05).
|
|
15074
|
+
// `working` — the work it waits on finishes by itself, so it is Running and spins; `watching` —
|
|
15075
|
+
// something must happen outside the thread, so it is Snoozed and still. Present only for a thread at
|
|
15076
|
+
// rest behind a wait the server honoured with no queue card; absent everywhere else, including every
|
|
15077
|
+
// queued rest, which never spins. Absent from a pre-2026-10-05 server, which the client reads as the
|
|
15078
|
+
// old Running placement.
|
|
15079
|
+
waitStatus: external_exports.enum(["working", "watching"]).optional(),
|
|
15027
15080
|
// Exact typed-interaction presence for this CURRENT registered session. The board already derives
|
|
15028
15081
|
// this from the scoped durable journal to compute needsYou; exposing the reason lets React avoid a
|
|
15029
15082
|
// pendingInteractions RPC for every unrelated question/completion card. Optional preserves rolling
|
|
@@ -22025,42 +22078,51 @@ function toCodexModel(raw2) {
|
|
|
22025
22078
|
priority
|
|
22026
22079
|
};
|
|
22027
22080
|
}
|
|
22028
|
-
function parseCodexModelsCache(raw2) {
|
|
22081
|
+
function parseCodexModelsCache(raw2, expectedClientVersion, previousModels = CODEX_MODELS_FALLBACK) {
|
|
22029
22082
|
let doc;
|
|
22030
22083
|
try {
|
|
22031
22084
|
doc = JSON.parse(raw2);
|
|
22032
22085
|
} catch {
|
|
22033
|
-
return
|
|
22086
|
+
return [...previousModels];
|
|
22034
22087
|
}
|
|
22035
|
-
const
|
|
22036
|
-
if (
|
|
22088
|
+
const record = doc && typeof doc === "object" ? doc : void 0;
|
|
22089
|
+
if (expectedClientVersion && record?.client_version !== expectedClientVersion) return [...previousModels];
|
|
22090
|
+
const models = record?.models;
|
|
22091
|
+
if (!Array.isArray(models)) return [...previousModels];
|
|
22037
22092
|
const parsed = models.map(toCodexModel).filter((x) => x !== void 0).sort((a, b) => a.priority - b.priority).map((x) => x.model);
|
|
22038
|
-
return parsed.length ? parsed :
|
|
22093
|
+
return parsed.length ? parsed : [...previousModels];
|
|
22039
22094
|
}
|
|
22040
|
-
function readCodexModels(codexHome = defaultCodexHome()) {
|
|
22095
|
+
function readCodexModels(codexHome = defaultCodexHome(), expectedClientVersion, nowMs = Date.now()) {
|
|
22041
22096
|
const path3 = cachePath(codexHome);
|
|
22042
|
-
const
|
|
22043
|
-
const
|
|
22044
|
-
if (hit &&
|
|
22097
|
+
const key = `${path3}\0${expectedClientVersion}`;
|
|
22098
|
+
const hit = memo.get(key);
|
|
22099
|
+
if (hit && nowMs - hit.at < TTL_MS) return hit.models;
|
|
22045
22100
|
let models;
|
|
22046
22101
|
try {
|
|
22047
|
-
|
|
22102
|
+
const raw2 = readFileSync8(path3, "utf8");
|
|
22103
|
+
models = parseCodexModelsCache(raw2, expectedClientVersion, trusted.get(key));
|
|
22104
|
+
let writer;
|
|
22105
|
+
try {
|
|
22106
|
+
writer = JSON.parse(raw2).client_version;
|
|
22107
|
+
} catch {
|
|
22108
|
+
}
|
|
22109
|
+
if (writer === expectedClientVersion) trusted.set(key, models);
|
|
22048
22110
|
} catch {
|
|
22049
|
-
models = CODEX_MODELS_FALLBACK;
|
|
22111
|
+
models = trusted.get(key) ?? CODEX_MODELS_FALLBACK;
|
|
22050
22112
|
}
|
|
22051
|
-
memo.set(
|
|
22113
|
+
memo.set(key, { at: nowMs, models });
|
|
22052
22114
|
return models;
|
|
22053
22115
|
}
|
|
22054
|
-
var
|
|
22116
|
+
var TTL_MS, memo, trusted;
|
|
22055
22117
|
var init_codex_models = __esm({
|
|
22056
22118
|
"packages/server/src/backend/codex-models.ts"() {
|
|
22057
22119
|
"use strict";
|
|
22120
|
+
init_src();
|
|
22058
22121
|
init_codex();
|
|
22059
|
-
|
|
22060
|
-
{ slug: "gpt-5.5", displayName: "GPT-5.5", defaultEffort: "medium", efforts: ["low", "medium", "high", "xhigh"] }
|
|
22061
|
-
];
|
|
22122
|
+
init_src();
|
|
22062
22123
|
TTL_MS = 5e3;
|
|
22063
22124
|
memo = /* @__PURE__ */ new Map();
|
|
22125
|
+
trusted = /* @__PURE__ */ new Map();
|
|
22064
22126
|
}
|
|
22065
22127
|
});
|
|
22066
22128
|
|
|
@@ -22105,7 +22167,7 @@ function claudeModelFromLimitName(name) {
|
|
|
22105
22167
|
if (!slug) return void 0;
|
|
22106
22168
|
return CLAUDE_THREAD_PROFILES.find(({ model }) => slug === model || slug.startsWith(`${model}-`) || model.startsWith(`${slug}-`))?.model;
|
|
22107
22169
|
}
|
|
22108
|
-
function threadProfileOptions(backend, claudeModels) {
|
|
22170
|
+
function threadProfileOptions(backend, claudeModels, codexModels) {
|
|
22109
22171
|
if (backend === "claude") {
|
|
22110
22172
|
return {
|
|
22111
22173
|
backend,
|
|
@@ -22123,7 +22185,7 @@ function threadProfileOptions(backend, claudeModels) {
|
|
|
22123
22185
|
if (backend === "codex") {
|
|
22124
22186
|
return {
|
|
22125
22187
|
backend,
|
|
22126
|
-
options: readCodexModels().map((model) => ({
|
|
22188
|
+
options: (codexModels ?? readCodexModels()).map((model) => ({
|
|
22127
22189
|
model: model.slug,
|
|
22128
22190
|
label: model.displayName,
|
|
22129
22191
|
defaultEffort: model.defaultEffort,
|
|
@@ -22134,16 +22196,18 @@ function threadProfileOptions(backend, claudeModels) {
|
|
|
22134
22196
|
if (backend === "acp") return { backend, options: [] };
|
|
22135
22197
|
throw new Error("This thread has an unknown backend; its runtime profile cannot be changed");
|
|
22136
22198
|
}
|
|
22137
|
-
function validateThreadProfile(backend, model, effort) {
|
|
22138
|
-
const catalogue = threadProfileOptions(backend);
|
|
22199
|
+
function validateThreadProfile(backend, model, effort, codexModels) {
|
|
22200
|
+
const catalogue = threadProfileOptions(backend, void 0, codexModels);
|
|
22139
22201
|
const option = catalogue.options.find((candidate) => candidate.model === model);
|
|
22140
22202
|
if (!option || !option.efforts.includes(effort)) {
|
|
22141
22203
|
throw new Error(`Unsupported ${catalogue.backend} model/effort pair: ${model} / ${effort}`);
|
|
22142
22204
|
}
|
|
22143
22205
|
}
|
|
22144
|
-
function normalizeObservedThreadModel(backend, model) {
|
|
22206
|
+
function normalizeObservedThreadModel(backend, model, codexModels) {
|
|
22145
22207
|
const value = model.trim();
|
|
22146
|
-
if (backend === "codex")
|
|
22208
|
+
if (backend === "codex") {
|
|
22209
|
+
return threadProfileOptions(backend, void 0, codexModels).options.some((option) => option.model === value) ? value : void 0;
|
|
22210
|
+
}
|
|
22147
22211
|
if (backend === "claude") {
|
|
22148
22212
|
const exact = CLAUDE_THREAD_PROFILES.find((option) => option.model === value);
|
|
22149
22213
|
if (exact) return exact.model;
|
|
@@ -26357,11 +26421,13 @@ ${detail2}
|
|
|
26357
26421
|
if (profileRecordLanded && state.model && state.profileAt) {
|
|
26358
26422
|
const observedAt = Date.parse(state.profileAt);
|
|
26359
26423
|
const spawnedAt = Date.parse(row.spawned_at);
|
|
26360
|
-
const
|
|
26424
|
+
const backendKind = row.backend ?? "claude";
|
|
26425
|
+
const codexModels = backendKind === "codex" ? deps.codexModels?.() : void 0;
|
|
26426
|
+
const model = normalizeObservedThreadModel(backendKind, state.model, codexModels);
|
|
26361
26427
|
const effort = state.effort?.trim() || row.effort?.trim();
|
|
26362
26428
|
if (model && effort && Number.isFinite(observedAt) && Number.isFinite(spawnedAt) && observedAt >= spawnedAt) {
|
|
26363
26429
|
try {
|
|
26364
|
-
validateThreadProfile(
|
|
26430
|
+
validateThreadProfile(backendKind, model, effort, codexModels);
|
|
26365
26431
|
deps.storage.setObservedProfileIfCurrent(
|
|
26366
26432
|
row.slug,
|
|
26367
26433
|
{ sessionId: row.session_id, generation: runtimeGeneration },
|
|
@@ -36147,7 +36213,7 @@ async function readQuota(opts = {}) {
|
|
|
36147
36213
|
}
|
|
36148
36214
|
const [claude, codex] = await Promise.all([
|
|
36149
36215
|
readClaudeQuota(opts.claudeBin, {}, { force: opts.force }),
|
|
36150
|
-
readCodexQuota()
|
|
36216
|
+
readCodexQuota(void 0, opts.codexBin)
|
|
36151
36217
|
]);
|
|
36152
36218
|
return { claude, codex };
|
|
36153
36219
|
}
|
|
@@ -36186,11 +36252,11 @@ function isUnder(real, root) {
|
|
|
36186
36252
|
return real === rootReal || real.startsWith(rootReal.endsWith(sep2) ? rootReal : rootReal + sep2);
|
|
36187
36253
|
}
|
|
36188
36254
|
try {
|
|
36189
|
-
const
|
|
36190
|
-
if (!
|
|
36255
|
+
const trusted2 = statSync12(rootReal, { bigint: true });
|
|
36256
|
+
if (!trusted2.isDirectory() || trusted2.ino === 0n) return false;
|
|
36191
36257
|
for (let ancestor = real; ; ) {
|
|
36192
36258
|
const actual = statSync12(ancestor, { bigint: true });
|
|
36193
|
-
if (actual.dev ===
|
|
36259
|
+
if (actual.dev === trusted2.dev && actual.ino === trusted2.ino) return true;
|
|
36194
36260
|
const parent = dirname9(ancestor);
|
|
36195
36261
|
if (parent === ancestor) return false;
|
|
36196
36262
|
ancestor = parent;
|
|
@@ -36983,12 +37049,12 @@ found, changed, and would do next. Be concise but do not omit; use whatever mark
|
|
|
36983
37049
|
|
|
36984
37050
|
**A QUIET PARK NEEDS NO WRITE-UP.** When you rest on work that is still running and the human has
|
|
36985
37051
|
nothing to read, try or act on yet \u2014 a sub-agent mid-task, a build, CI \u2014 end with an \` \`\`\`awaiting \`
|
|
36986
|
-
fence carrying \`
|
|
36987
|
-
thread stays out of the human's queue and nobody is meant to read that message, so
|
|
36988
|
-
a turn of tokens for no reader. The moment there IS something for them \u2014 a partial
|
|
36989
|
-
server, a question \u2014 the rest is \`
|
|
36990
|
-
DOES need them \u2014 \`
|
|
36991
|
-
last message, the quiet stretches included.
|
|
37052
|
+
fence carrying \`status: working\` or \`status: watching\` and NOTHING else: no summary, no progress
|
|
37053
|
+
report, no prose. The thread stays out of the human's queue and nobody is meant to read that message, so
|
|
37054
|
+
writing one costs you a turn of tokens for no reader. The moment there IS something for them \u2014 a partial
|
|
37055
|
+
result, a file, a server, a question \u2014 the rest is \`status: needs_input\` instead. The write-up is owed
|
|
37056
|
+
at the rest that DOES need them \u2014 \`status: needs_input\`, a question, or \`done\` \u2014 and it covers
|
|
37057
|
+
everything since their last message, the quiet stretches included.
|
|
36992
37058
|
|
|
36993
37059
|
**ALWAYS SIGN OFF.** A bare rest \u2014 nothing said about where you stand \u2014 is not a handoff, it is an item
|
|
36994
37060
|
nobody can triage: it says neither "answer me" nor "this is finished", so it sits in the queue meaning
|
|
@@ -37001,8 +37067,8 @@ has to be rewritten at every rest and is wrong the moment anything changes; a ro
|
|
|
37001
37067
|
ending, a compaction and a frizz restart. **The \`done\` fence below still works**, and it is still the
|
|
37002
37068
|
right shape for the prose the human reads \u2014 but where a verb exists for what you are saying, call it.
|
|
37003
37069
|
**A WAIT IS THE ONE EXCEPTION, and it always takes the fence.** \`mcp__frizz__watch\` registers WHEN you
|
|
37004
|
-
wake;
|
|
37005
|
-
\` \`\`\`awaiting \` fence carries it (\`
|
|
37070
|
+
wake; where the thread sits meanwhile is an answer about THIS rest, and only the
|
|
37071
|
+
\` \`\`\`awaiting \` fence carries it (\`status:\`, below). A rest on running work with no fence is a
|
|
37006
37072
|
bare rest, and it lands in the human's queue. **A QUESTION HAS NO FENCE ANY MORE** (retired
|
|
37007
37073
|
2026-09-11): the only way to ask is \`mcp__frizz__ask\`, and a question written into a fence's body is
|
|
37008
37074
|
plain prose \u2014 no card, no answer, and no sign-off.
|
|
@@ -37099,23 +37165,31 @@ exactly ONE of them.
|
|
|
37099
37165
|
- \` \`\`\`awaiting \` \u2014 you have STOPPED, and you are waiting on work that is actually running, or on the
|
|
37100
37166
|
human to PERFORM steps you cannot (\`steps:\`, below). A DECISION you need from them is a question, never
|
|
37101
37167
|
a fence. The fence is PURE STRUCTURE: YAML frontmatter naming what frizz can
|
|
37102
|
-
look up and saying
|
|
37103
|
-
The everyday shape is a QUIET PARK, the fence alone
|
|
37168
|
+
look up and saying where the thread sits meanwhile, then \u2014 only when the human is needed \u2014 \`---\` and
|
|
37169
|
+
Markdown prose. The everyday shape is a QUIET PARK, the fence alone \u2014 here, on a test run and a
|
|
37170
|
+
sub-agent that finish by themselves:
|
|
37104
37171
|
|
|
37105
37172
|
\`\`\`awaiting
|
|
37106
37173
|
shells: [bzvtnt3ig]
|
|
37107
37174
|
agents: [<the runtime agent id>]
|
|
37108
|
-
|
|
37109
|
-
prs: [acme/app#391]
|
|
37110
|
-
needs_input: false
|
|
37175
|
+
status: working
|
|
37111
37176
|
for: 2h
|
|
37112
37177
|
\`\`\`
|
|
37113
37178
|
|
|
37179
|
+
And on a wait whose end is someone else's \u2014 a review, a release, a reply:
|
|
37180
|
+
|
|
37181
|
+
\`\`\`awaiting
|
|
37182
|
+
prs: [acme/app#391]
|
|
37183
|
+
timers: [tmr_a1b2c3d4e5f6]
|
|
37184
|
+
status: watching
|
|
37185
|
+
for: 1d
|
|
37186
|
+
\`\`\`
|
|
37187
|
+
|
|
37114
37188
|
And when the human can already act on something while the work runs:
|
|
37115
37189
|
|
|
37116
37190
|
\`\`\`awaiting
|
|
37117
37191
|
agents: [<the runtime agent id>]
|
|
37118
|
-
|
|
37192
|
+
status: needs_input
|
|
37119
37193
|
for: 1h
|
|
37120
37194
|
title: Three of five audits ready
|
|
37121
37195
|
---
|
|
@@ -37135,20 +37209,31 @@ exactly ONE of them.
|
|
|
37135
37209
|
The publish step runs as the maintainer, and no token for that account is available to this thread.
|
|
37136
37210
|
\`\`\`
|
|
37137
37211
|
|
|
37138
|
-
- **\`
|
|
37139
|
-
|
|
37140
|
-
\`
|
|
37141
|
-
|
|
37142
|
-
|
|
37143
|
-
|
|
37144
|
-
|
|
37145
|
-
|
|
37146
|
-
|
|
37147
|
-
|
|
37148
|
-
|
|
37149
|
-
|
|
37212
|
+
- **\`status:\` \u2014 REQUIRED: where does the thread sit while the work runs?** One of three values, one
|
|
37213
|
+
per place on the board:
|
|
37214
|
+
- \`working\` \u2014 the work finishes BY ITSELF: a test run, a build, a benchmark, CI, a sub-agent doing
|
|
37215
|
+
a job. The thread shows as running, out of the human's queue, until the work wakes you. It shows so
|
|
37216
|
+
only while something you named is actually MOVING \u2014 a live sub-agent, a shell you name here or
|
|
37217
|
+
registered with \`mcp__frizz__watch\`, CI that is still running \u2014 so \`working\` on a timer or on a
|
|
37218
|
+
PR whose checks have settled shows as the watch it is.
|
|
37219
|
+
- \`watching\` \u2014 the wait is on something OUTSIDE the thread: a review, a release, a reporter's
|
|
37220
|
+
reply, another agent's merge, a poller you left running. The thread is snoozed \u2014 out of the queue
|
|
37221
|
+
and out of the running rows \u2014 until the watch wakes you. Pick it beside a sub-agent too when that
|
|
37222
|
+
child does nothing but watch the world for you.
|
|
37223
|
+
- \`needs_input\` \u2014 the human can read, try or act on something NOW while the work runs. The thread
|
|
37224
|
+
goes into their queue \u2014 the live work is listed on the card \u2014 and the prose under \`---\` says
|
|
37225
|
+
what to look at. **IT IS NOT ONLY FOR A QUESTION.** A partial result, a file you wrote, a server
|
|
37226
|
+
to click through is \`needs_input\`, even when you need nothing back from them. And if you wrote
|
|
37227
|
+
ANY words for the human at this rest, the answer is \`needs_input\`: a \`working\` or \`watching\`
|
|
37228
|
+
rest is never put in front of them, so those words would go unread.
|
|
37229
|
+
It is YOUR call, and frizz does not second-guess it: no rule about which kinds of wait need the
|
|
37230
|
+
human overrides what you say. A fence without the line \u2014 or with any other value \u2014 is not a park:
|
|
37231
|
+
the thread queues and frizz tells you which line is missing. And \`working\` or \`watching\` holds
|
|
37232
|
+
only while every name is live and \`for:\` has not run out, so a wrong answer cannot hide the
|
|
37233
|
+
thread. (\`needs_input: true\` and \`needs_input: false\`, the answer before 2026-10-05, are still
|
|
37234
|
+
read. Write \`status:\`.)
|
|
37150
37235
|
- **THE FRONTMATTER IS YAML. THE BODY IS MARKDOWN.** The PLURAL keys take LISTS (either list form;
|
|
37151
|
-
a single item may be written bare), plus the scalars \`for:\`, \`
|
|
37236
|
+
a single item may be written bare), plus the scalars \`for:\`, \`status:\` and \`title:\`. **NO PROSE ABOVE THE
|
|
37152
37237
|
\`---\`, EVER** \u2014 a colon or a \` #\` inside a sentence breaks the parse. (The \`title:\` and \`steps:\`
|
|
37153
37238
|
values are the exceptions: frizz reads them verbatim, so code, \`#391\` and a colon are safe there.) There is no \`reason:\` key any more;
|
|
37154
37239
|
the reason goes in the body, which is the handoff the human reads. **THE SINGULAR KEYS ARE GONE** \u2014 \`shell:\`,
|
|
@@ -37166,7 +37251,7 @@ exactly ONE of them.
|
|
|
37166
37251
|
and a frizz restart, and \`activity\` marks anything already covered. It refuses a handle nothing
|
|
37167
37252
|
live answers to, and a \`kind\` that disagrees with what frizz can see, so you cannot register a
|
|
37168
37253
|
wait that will not fire. It does NOT replace the fence: each rest still ends with one, naming the
|
|
37169
|
-
work and answering \`
|
|
37254
|
+
work and answering \`status:\`. Withdraw a registration with \`mcp__frizz__unwatch\`. A sub-agent
|
|
37170
37255
|
needs no registration \u2014 its return re-invokes you \u2014 but resting on one still takes the fence,
|
|
37171
37256
|
\`agents: [<id>]\`.
|
|
37172
37257
|
- \`timers:\` \u2014 timer ids from \`mcp__frizz__timer\`. NOT instants; the tool creates the timer.
|
|
@@ -37199,7 +37284,7 @@ exactly ONE of them.
|
|
|
37199
37284
|
may not, press a button you are not allowed to press. One \`- \` item per step, each written to be
|
|
37200
37285
|
followed COLD by someone who has read nothing else; frizz reads them verbatim. Steps NAME THE HUMAN
|
|
37201
37286
|
as the wait, so the fence needs no other name and no \`for:\` (add one only if you want to be woken
|
|
37202
|
-
to re-check), and it always puts the thread in their queue \u2014 \`
|
|
37287
|
+
to re-check), and it always puts the thread in their queue \u2014 \`status:\` may be left out. Their
|
|
37203
37288
|
card shows the steps over one **Done** button, and its click comes back to you as their reply,
|
|
37204
37289
|
\`Done\`, the same as anything they type; anything else they need to tell you \u2014 a step that failed,
|
|
37205
37290
|
the account they used \u2014 comes as a message of their own. An act is not a decision: never ask
|
|
@@ -37213,8 +37298,8 @@ exactly ONE of them.
|
|
|
37213
37298
|
- **REGISTERING IS NOT PARKING, AND PARKING IS NOT REGISTERING.** Your shells, sub-agents, timers
|
|
37214
37299
|
and PR watchers are watched AUTOMATICALLY, fence or no fence \u2014 frizz wakes you when one finishes,
|
|
37215
37300
|
every time. The fence only declares that you have STOPPED, names which of them you stopped for,
|
|
37216
|
-
and says
|
|
37217
|
-
of them live \u21D2 your thread rests where \`
|
|
37301
|
+
and says where the thread sits meanwhile. **FRIZZ CHECKS EVERY NAME THE MOMENT YOU REST:** all
|
|
37302
|
+
of them live \u21D2 your thread rests where \`status:\` put it; any one dead, unknown or not yours \u21D2
|
|
37218
37303
|
you are BUMPED immediately and told which, and the thread sits in the queue until you fix it.
|
|
37219
37304
|
**A FENCE THAT NAMES NOTHING IS NOT A PARK** \u2014 \`for:\` describes a wait, it is not one \u2014 so
|
|
37220
37305
|
"waiting on the checks" plus a duration just sits in the queue: REGISTER the PR and name it, and
|
|
@@ -37603,15 +37688,16 @@ the handoff.
|
|
|
37603
37688
|
## Automated waits in Claude Code
|
|
37604
37689
|
|
|
37605
37690
|
**The mechanism is decided by whether you will REST while it runs.** Only an \` \`\`\`awaiting \` fence
|
|
37606
|
-
answering \`
|
|
37691
|
+
answering \`status: working\` or \`status: watching\` keeps a rested thread out of the queue \u2014 a live
|
|
37692
|
+
sub-agent alone does not.
|
|
37607
37693
|
|
|
37608
37694
|
- **Resting until a condition is met** (the usual CI / PR / release wait) \u2192 for a pull request,
|
|
37609
37695
|
\`mcp__frizz__watch_pr\`; for a GitHub issue, \`mcp__frizz__watch_issue\`; for anything else dispatch a
|
|
37610
37696
|
SUB-AGENT to own the wait. It runs the watcher
|
|
37611
|
-
to completion in its own foreground and returns the verdict
|
|
37612
|
-
|
|
37613
|
-
watcher names one sized to the wait (up to 24h) and loops until its terminal
|
|
37614
|
-
not hand back while its own watcher is still live.
|
|
37697
|
+
to completion in its own foreground and returns the verdict, and its return re-invokes you; rest on
|
|
37698
|
+
it with \`status: watching\`. A Bash call that names no \`timeout\` moves to the background after a
|
|
37699
|
+
minute, so the watcher names one sized to the wait (up to 24h) and loops until its terminal
|
|
37700
|
+
condition. A helper must not hand back while its own watcher is still live.
|
|
37615
37701
|
- **Working alongside a process you launched** (dev server, log tail) \u2192 \`Bash\` with
|
|
37616
37702
|
\`run_in_background: true\`. Never put shell job control (\`&\`, \`nohup \u2026 &\`, \`disown\`) inside the
|
|
37617
37703
|
command to imitate the native flag: frizz's hook rejects an escaping job, because the process could
|
|
@@ -37634,7 +37720,7 @@ its outbox and is unaffected:
|
|
|
37634
37720
|
on a CLOCK, whatever you are doing, delivered MID-TURN at your next tool boundary and never aborting
|
|
37635
37721
|
what you are running; \`post_compaction\` \u2014 into the emptied window after a compaction. Disarm with
|
|
37636
37722
|
\`action: "stop"\` when the work it drives is finished \u2014 one left armed on a finished thread wakes it
|
|
37637
|
-
forever, and the human can also switch it off
|
|
37723
|
+
forever, and the human can also switch it off from the thread's Goal control. Replying \`ALLDONE\` on its own
|
|
37638
37724
|
line stops it too, but that permanently stalls the run: a last resort, only when nothing is left.
|
|
37639
37725
|
- \`mcp__frizz__timer\` is your own alarm clock: \`action: "set"\` with \`prompt\` plus \`in_seconds\` or an
|
|
37640
37726
|
ISO \`at\`, delivered exactly once, mid-turn, and then gone. You may hold MANY at once; \`action: "list"\`
|
|
@@ -39974,11 +40060,11 @@ function hasDeclaredWait(tele, nowMs, armedTimerIds = /* @__PURE__ */ new Set(),
|
|
|
39974
40060
|
}
|
|
39975
40061
|
function heldByRunningChecks(github, registered) {
|
|
39976
40062
|
if (registered.size === 0) return false;
|
|
39977
|
-
return [...registered].every((key) =>
|
|
39978
|
-
|
|
39979
|
-
|
|
39980
|
-
|
|
39981
|
-
|
|
40063
|
+
return [...registered].every((key) => ciInMotion(github[key]));
|
|
40064
|
+
}
|
|
40065
|
+
function ciInMotion(status) {
|
|
40066
|
+
if (!status || status.checks !== "running" || status.state !== "open") return false;
|
|
40067
|
+
return !(status.running === 0 && (status.gated ?? 0) > 0);
|
|
39982
40068
|
}
|
|
39983
40069
|
function hasLiveOwnWork(tele, registeredPrWatches) {
|
|
39984
40070
|
return Boolean(
|
|
@@ -40117,6 +40203,20 @@ function deriveAwaitingBackground(row, tele, runtime, hasActionableInteraction =
|
|
|
40117
40203
|
!hasHumanSteps(tele)) return false;
|
|
40118
40204
|
return deriveNeedsYou({ ...row, bg_snooze_rested_at: null }, tele, runtime, hasActionableInteraction, nowMs, limitPause, false, deliveryProcessGone, {}, /* @__PURE__ */ new Set(), armedTimerIds, armedWatches, openQuestions);
|
|
40119
40205
|
}
|
|
40206
|
+
function deriveWaitStatus(tele, runtime, needsYou, awaitingBackground, messageInFlight, nowMs, github = {}, registeredPrWatches = /* @__PURE__ */ new Set(), armedWatches = []) {
|
|
40207
|
+
if (runtime !== "turn-idle" || needsYou || messageInFlight) return void 0;
|
|
40208
|
+
const liveChild = hasLiveBackgroundWork(tele);
|
|
40209
|
+
if (!awaitingBackground && !liveChild) return void 0;
|
|
40210
|
+
const fence = tele?.lastFence?.kind === "awaiting" ? tele.lastFence : void 0;
|
|
40211
|
+
const declared = fence ? awaitingStatus(fence.hints) : null;
|
|
40212
|
+
if (declared === "needs_input") return void 0;
|
|
40213
|
+
if (declared === "watching") return "watching";
|
|
40214
|
+
if (liveChild || [...registeredPrWatches].some((key) => ciInMotion(github[key]))) return "working";
|
|
40215
|
+
if (declared !== "working") return "watching";
|
|
40216
|
+
const namedShell = readAwaitingPark(fence?.hints ?? []).items.some((i) => i.kind === "shell" && resolveLiveWatchTarget(tele, i.value)?.kind === "shell");
|
|
40217
|
+
const registeredShell = armedWatches.some((w2) => w2.kind === "shell" && Date.parse(w2.expiresAt) > nowMs && resolveLiveWatchTarget(tele, w2.target)?.kind === "shell");
|
|
40218
|
+
return namedShell || registeredShell ? "working" : "watching";
|
|
40219
|
+
}
|
|
40120
40220
|
function resolveSessionProfile(row, tele) {
|
|
40121
40221
|
const persistedModel = row.model?.trim() || void 0;
|
|
40122
40222
|
const persistedEffort = row.effort?.trim() || void 0;
|
|
@@ -40288,6 +40388,7 @@ function sessionThreadView(projectDir, storage, row, rawTele, registeredLegacyTe
|
|
|
40288
40388
|
const needsYou = archived ? false : deriveNeedsYou(row, tele, runtime, interactionPresence.needsUser, nowMs, limitPause, true, deliveryProcessGone, github, registeredPrWatches, armedTimerIds, armedWatches, questions.length, answerInFlight);
|
|
40289
40389
|
const deliveryInFlight = !archived && deriveDeliveryInFlight(row, runtime, needsYou, deliveryProcessGone, answerInFlight, nowMs);
|
|
40290
40390
|
const awaitingBackground = archived ? false : deriveAwaitingBackground(row, tele, runtime, interactionPresence.needsUser, nowMs, limitPause, deliveryProcessGone, github, registeredPrWatches, armedTimerIds, armedWatches, questions.length);
|
|
40391
|
+
const waitStatus = archived ? void 0 : deriveWaitStatus(tele, runtime, needsYou, awaitingBackground, answerInFlight || hasFreshDelivery(row, deliveryProcessGone), nowMs, github, registeredPrWatches, armedWatches);
|
|
40291
40392
|
const crashed = runtime === "exited" && (tele?.turn === "in-flight" || hasLiveBackgroundWork(tele) || headlessLostWork);
|
|
40292
40393
|
const snoozedUntil = futureSnooze(row, nowMs);
|
|
40293
40394
|
const profile = resolveSessionProfile(row, tele);
|
|
@@ -40361,6 +40462,7 @@ function sessionThreadView(projectDir, storage, row, rawTele, registeredLegacyTe
|
|
|
40361
40462
|
recurringPrompt: resolveRecurringPrompt(row),
|
|
40362
40463
|
needsYou,
|
|
40363
40464
|
awaitingBackground,
|
|
40465
|
+
waitStatus,
|
|
40364
40466
|
crashed,
|
|
40365
40467
|
pendingInteraction: interactionPresence.pending,
|
|
40366
40468
|
actionableInteraction: interactionPresence.needsUser,
|
|
@@ -42504,16 +42606,20 @@ ${wakeTimeHeader(nowMs, spokeAt)}`,
|
|
|
42504
42606
|
const fenceId2 = parkFenceId("needs-input", spokeAt);
|
|
42505
42607
|
const deliveryId2 = wakeDeliveryId(row.slug, row.session_id, fenceId2);
|
|
42506
42608
|
if (outbox.get(deliveryId2)) continue;
|
|
42507
|
-
const written = tele.lastFence.hints.find((h10) => h10.kind === "needs_input")
|
|
42609
|
+
const written = [...tele.lastFence.hints].reverse().find((h10) => h10.kind === "status") ?? [...tele.lastFence.hints].reverse().find((h10) => h10.kind === "needs_input");
|
|
42508
42610
|
const message2 = [
|
|
42509
|
-
`${PARK_CORRECTION_NEEDS_INPUT_LEAD}\`
|
|
42611
|
+
`${PARK_CORRECTION_NEEDS_INPUT_LEAD}\`status:\` that frizz can read \u2014 \`working\`, \`watching\` or \`needs_input\`${written ? ` (it says \`${written.kind}: ${written.value}\`)` : ""} \u2014 so frizz did not park it, and your thread is in the human's queue.`,
|
|
42612
|
+
"",
|
|
42613
|
+
"Every ```awaiting fence answers one question: where does this rest sit while the work runs?",
|
|
42510
42614
|
"",
|
|
42511
|
-
"
|
|
42615
|
+
"- `status: working` \u2014 the work finishes by itself: a test run, a build, CI, a sub-agent doing a job.",
|
|
42616
|
+
" The thread shows as running until the work wakes you.",
|
|
42617
|
+
"- `status: watching` \u2014 the wait is on something outside the thread: a review, a release, a",
|
|
42618
|
+
" reporter, another agent's merge. The thread is snoozed until the watch wakes you.",
|
|
42619
|
+
"- `status: needs_input` \u2014 the human can act on something now while the work runs. The thread goes",
|
|
42620
|
+
" into their queue, and the prose under `---` says what to look at.",
|
|
42512
42621
|
"",
|
|
42513
|
-
"
|
|
42514
|
-
" wakes you, and the fence alone is the whole message: no write-up.",
|
|
42515
|
-
"- `needs_input: true` \u2014 they can act on something now while the work runs. The thread goes into",
|
|
42516
|
-
" their queue, and the prose under `---` says what to look at.",
|
|
42622
|
+
"With `working` or `watching` the fence alone is the whole message: no write-up.",
|
|
42517
42623
|
"",
|
|
42518
42624
|
"Re-send the same fence with that line added."
|
|
42519
42625
|
].join("\n");
|
|
@@ -42526,7 +42632,7 @@ ${wakeTimeHeader(nowMs, spokeAt)}`,
|
|
|
42526
42632
|
message: `${message2}
|
|
42527
42633
|
|
|
42528
42634
|
${wakeTimeHeader(nowMs, spokeAt)}`,
|
|
42529
|
-
reason: "awaiting fence gives no
|
|
42635
|
+
reason: "awaiting fence gives no status answer"
|
|
42530
42636
|
}, nowMs).delivery;
|
|
42531
42637
|
deps.storage.countParkBump(row.slug, fenceId2);
|
|
42532
42638
|
log3(`waker: queued ${row.slug} \u2014 ${item2.reason}`);
|
|
@@ -72350,6 +72456,7 @@ function createContextUnchecked(opts, resources) {
|
|
|
72350
72456
|
storage,
|
|
72351
72457
|
bus,
|
|
72352
72458
|
backendFor,
|
|
72459
|
+
codexModels: () => readCodexModels(void 0, opts.codexVersion),
|
|
72353
72460
|
onChange: () => board.refresh(),
|
|
72354
72461
|
onTranscriptChange: (slugs) => transcriptChange.emit(slugs),
|
|
72355
72462
|
// The SDK's own reading of a headless broker session: its turn (so the fold's 5s unknown-stop_reason
|
|
@@ -72407,8 +72514,9 @@ function createContextUnchecked(opts, resources) {
|
|
|
72407
72514
|
// Second wake source: every thread a subscription window cut off mid-turn gets its own "continue"
|
|
72408
72515
|
// once that window rolls, over this same delivery path. The quota reader supplies the fallback
|
|
72409
72516
|
// instant for a weekly limit, whose message text carries a clock but no date; readQuota memoizes,
|
|
72410
|
-
// so consulting it per tick costs a live request only every few minutes.
|
|
72411
|
-
|
|
72517
|
+
// so consulting it per tick costs a live request only every few minutes. Read through the resolved
|
|
72518
|
+
// runtimes, as the quota RPC does: a bare call would start whatever `codex` is first on PATH.
|
|
72519
|
+
readQuota: () => readQuota({ claudeBin: opts.claudeBin, codexBin: opts.codexBin }),
|
|
72412
72520
|
// The only runtime that can answer is the broker: its daemon record is on disk while the daemon
|
|
72413
72521
|
// lives and is unlinked when it dies (liveBrokerRecords checks the pid), so "did the process that
|
|
72414
72522
|
// took this wake survive" is one directory read. Codex and any row whose session moved on answer
|
|
@@ -72534,7 +72642,8 @@ ${wakeDeliveryToken(deliveryId)}`;
|
|
|
72534
72642
|
teardownProject: opts.teardownProject,
|
|
72535
72643
|
launchProjectId: opts.launchProjectId,
|
|
72536
72644
|
claudeBin: opts.claudeBin,
|
|
72537
|
-
codexBin: opts.codexBin
|
|
72645
|
+
codexBin: opts.codexBin,
|
|
72646
|
+
codexVersion: opts.codexVersion
|
|
72538
72647
|
};
|
|
72539
72648
|
}
|
|
72540
72649
|
var CONTEXT_STARTUP_CLEANUP_TIMEOUT_MS, QUOTA_REFRESH_INTERVAL_MS, ContextStartupError;
|
|
@@ -72556,6 +72665,7 @@ var init_context = __esm({
|
|
|
72556
72665
|
init_resume();
|
|
72557
72666
|
init_claude();
|
|
72558
72667
|
init_codex();
|
|
72668
|
+
init_codex_models();
|
|
72559
72669
|
init_acp_transcript();
|
|
72560
72670
|
init_acp_bridge();
|
|
72561
72671
|
init_auth_status();
|
|
@@ -79158,10 +79268,10 @@ import { randomUUID as randomUUID17 } from "node:crypto";
|
|
|
79158
79268
|
import { basename as basename9, dirname as dirname18 } from "node:path";
|
|
79159
79269
|
import { existsSync as existsSync18, mkdirSync as mkdirSync20, rmSync as rmSync11, writeFileSync as writeFileSync14 } from "node:fs";
|
|
79160
79270
|
import { homedir as homedir17 } from "node:os";
|
|
79161
|
-
function validateGithubDispatchProfile(input) {
|
|
79271
|
+
function validateGithubDispatchProfile(input, codexModels) {
|
|
79162
79272
|
if (input.backend === "acp") return;
|
|
79163
79273
|
if (input.effort === void 0) throw new Error(`Unsupported ${input.backend} model/effort pair: ${input.model} / (no effort)`);
|
|
79164
|
-
validateThreadProfile(input.backend, input.model, input.effort);
|
|
79274
|
+
validateThreadProfile(input.backend, input.model, input.effort, codexModels);
|
|
79165
79275
|
}
|
|
79166
79276
|
function githubDispatcherRequest(input, item) {
|
|
79167
79277
|
return {
|
|
@@ -80418,7 +80528,8 @@ ${gapNote}` : input.message;
|
|
|
80418
80528
|
handler: async ({ input }) => {
|
|
80419
80529
|
const row = ctx.storage.getSession(input.slug);
|
|
80420
80530
|
if (!row) throw new Error(`thread ${input.slug} is not editable`);
|
|
80421
|
-
|
|
80531
|
+
const claudeModels = row.backend === "claude" ? await readClaudeModels({ claudeBin: ctx.claudeBin, cwd: ctx.project.dir }) : void 0;
|
|
80532
|
+
return threadProfileOptions(row.backend, claudeModels, readCodexModels(void 0, ctx.codexVersion));
|
|
80422
80533
|
}
|
|
80423
80534
|
}),
|
|
80424
80535
|
// The composer's `/` typeahead asks the thread's HARNESS for its skills — the broker daemon's
|
|
@@ -81400,7 +81511,7 @@ Say which way you went and why in your write-up, so the human can course-correct
|
|
|
81400
81511
|
// hand-maintained list. Degrades to a minimal fallback (never throws) when the cache is absent.
|
|
81401
81512
|
codexModels: query({
|
|
81402
81513
|
output: external_exports.array(CodexModel),
|
|
81403
|
-
handler: async () => readCodexModels()
|
|
81514
|
+
handler: async () => readCodexModels(void 0, ctx.codexVersion)
|
|
81404
81515
|
}),
|
|
81405
81516
|
// The Claude aliases with the EDITION the pinned runtime resolves each to ("Opus 5.5"), asked of the
|
|
81406
81517
|
// runtime itself once per server life; the bare family words while it answers (claude-models.ts).
|
|
@@ -81429,7 +81540,7 @@ Say which way you went and why in your write-up, so the human can course-correct
|
|
|
81429
81540
|
quota: query({
|
|
81430
81541
|
input: external_exports.object({ force: external_exports.boolean().optional() }).strict().optional(),
|
|
81431
81542
|
output: QuotaSnapshot,
|
|
81432
|
-
handler: async ({ input }) => readQuota({ claudeBin: ctx.claudeBin, force: input?.force })
|
|
81543
|
+
handler: async ({ input }) => readQuota({ claudeBin: ctx.claudeBin, codexBin: ctx.codexBin, force: input?.force })
|
|
81433
81544
|
}),
|
|
81434
81545
|
// Per-provider LOCAL credential presence for the new-thread dispatch gate. Distinct from `quota`
|
|
81435
81546
|
// (whose "unavailable" is overloaded with transient endpoint failures): this reports only whether a
|
|
@@ -81760,12 +81871,12 @@ Say which way you went and why in your write-up, so the human can course-correct
|
|
|
81760
81871
|
}),
|
|
81761
81872
|
dispatchPreferencesGet: query({
|
|
81762
81873
|
output: DispatchPreferences,
|
|
81763
|
-
handler: async () => ctx.getDispatchPreferences(readCodexModels())
|
|
81874
|
+
handler: async () => ctx.getDispatchPreferences(readCodexModels(void 0, ctx.codexVersion))
|
|
81764
81875
|
}),
|
|
81765
81876
|
dispatchPreferenceSet: mutation({
|
|
81766
81877
|
input: SetDispatchPreferenceInput,
|
|
81767
81878
|
output: DispatchPreferences,
|
|
81768
|
-
handler: async ({ input }) => ctx.setDispatchPreference(input, readCodexModels())
|
|
81879
|
+
handler: async ({ input }) => ctx.setDispatchPreference(input, readCodexModels(void 0, ctx.codexVersion))
|
|
81769
81880
|
}),
|
|
81770
81881
|
// The shipped GitHub batch-dispatch prompt template (single source of truth: server/github.ts).
|
|
81771
81882
|
// The Settings UI reads it to prefill the editor and to power "reset to default"; an empty/unset
|
|
@@ -81824,7 +81935,7 @@ Say which way you went and why in your write-up, so the human can course-correct
|
|
|
81824
81935
|
input: GithubBatchInput,
|
|
81825
81936
|
output: GithubBatchResult,
|
|
81826
81937
|
handler: async ({ input }) => {
|
|
81827
|
-
validateGithubDispatchProfile(input);
|
|
81938
|
+
validateGithubDispatchProfile(input, readCodexModels(void 0, ctx.codexVersion));
|
|
81828
81939
|
const repo = await resolveRepo();
|
|
81829
81940
|
if (!repo) throw new Error("not a GitHub repo");
|
|
81830
81941
|
const template = effectiveTemplate(ctx.getSettings().githubPrompt);
|
|
@@ -85295,13 +85406,24 @@ async function startServer(opts = {}) {
|
|
|
85295
85406
|
},
|
|
85296
85407
|
// serverLockPath is the LAUNCHING project's: it is the only `server.lock` this process publishes
|
|
85297
85408
|
// (see "status publication"), so it is the only file a tenant's worker can read the port out of.
|
|
85298
|
-
contextOptions: {
|
|
85299
|
-
|
|
85300
|
-
|
|
85301
|
-
|
|
85302
|
-
|
|
85303
|
-
|
|
85304
|
-
|
|
85409
|
+
contextOptions: {
|
|
85410
|
+
get claudeBin() {
|
|
85411
|
+
return runtimes?.claude.bin ?? opts.claudeBin;
|
|
85412
|
+
},
|
|
85413
|
+
get codexBin() {
|
|
85414
|
+
return runtimes?.codex.bin ?? opts.codexBin;
|
|
85415
|
+
},
|
|
85416
|
+
get codexVersion() {
|
|
85417
|
+
return runtimes?.codex.version === "unknown" ? void 0 : runtimes?.codex.version;
|
|
85418
|
+
},
|
|
85419
|
+
serverLockPath: serverLockPathFor(project),
|
|
85420
|
+
activeTenants,
|
|
85421
|
+
teardownProject,
|
|
85422
|
+
launchProjectId: project.id,
|
|
85423
|
+
get database() {
|
|
85424
|
+
return frizzDb?.db;
|
|
85425
|
+
}
|
|
85426
|
+
},
|
|
85305
85427
|
// Each project's app carries ITS OWN owner proof, so /health stays honest per project rather than
|
|
85306
85428
|
// answering for whichever one happened to launch the server. The socket is per project for a
|
|
85307
85429
|
// blunter reason: it is a live feed of ONE board, so sharing the launcher's would push its
|
|
@@ -85563,6 +85685,7 @@ async function startServer(opts = {}) {
|
|
|
85563
85685
|
() => runtime.createContext({
|
|
85564
85686
|
claudeBin: runtimes.claude.bin,
|
|
85565
85687
|
codexBin: runtimes.codex.bin,
|
|
85688
|
+
codexVersion: runtimes.codex.version === "unknown" ? void 0 : runtimes.codex.version,
|
|
85566
85689
|
project,
|
|
85567
85690
|
database: frizzDb.db,
|
|
85568
85691
|
serverLockPath: serverLockPathFor(project),
|