frizz 0.6.0 → 0.7.1
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 +9 -6
- package/dist/codex-app-server-daemon.js +12 -3
- package/dist/dev-child.js +196 -66
- package/dist/frizz.js +50 -18
- package/package.json +2 -2
- package/runtime/cc-worker/bin/frizz-mcp.mjs +2 -2
- package/runtime/cc-worker/hooks/session-seed.mjs +2 -2
- package/runtime/cc-worker/skills/gh/SKILL.md +8 -7
- package/runtime/cc-worker/skills/waits/SKILL.md +4 -3
- package/web-dist/assets/{TerminalPane-GfnCbZQ8.js → TerminalPane-DBmtdVkV.js} +1 -1
- package/web-dist/assets/{abnfDiagram-VRR7QNED-By12QfQW.js → abnfDiagram-VRR7QNED-s9x3PTMx.js} +1 -1
- package/web-dist/assets/architecture-TIHT7OUA-Eb73yePg.js +1 -0
- package/web-dist/assets/{architectureDiagram-ZJ3FMSHR-CcXU45QO.js → architectureDiagram-ZJ3FMSHR-CIFfgliT.js} +1 -1
- package/web-dist/assets/{blockDiagram-677ZJIJ3-CmzyO2OF.js → blockDiagram-677ZJIJ3-BC-TeFao.js} +1 -1
- package/web-dist/assets/{c4Diagram-LMCZKHZV-DFGSW_ZS.js → c4Diagram-LMCZKHZV-DoJ_Bulk.js} +1 -1
- package/web-dist/assets/channel-CgSC9ikg.js +1 -0
- package/web-dist/assets/{chunk-32BRIVSS-whgaFxPY.js → chunk-32BRIVSS-BgchlScG.js} +1 -1
- package/web-dist/assets/{chunk-52WLFC77-DCT0MLgl.js → chunk-52WLFC77-D94nMfY5.js} +1 -1
- package/web-dist/assets/{chunk-C7G6YPKG-Br0OaxIX.js → chunk-C7G6YPKG-BNU4g2Rm.js} +1 -1
- package/web-dist/assets/{chunk-EX3LRPZG-CUnQkdEF.js → chunk-EX3LRPZG-DooNeZ0v.js} +1 -1
- package/web-dist/assets/{chunk-FWX5IMBZ-D1NqKRFr.js → chunk-FWX5IMBZ-DuXYfpte.js} +2 -2
- package/web-dist/assets/{chunk-HOUHSVGY-7ZL78OrO.js → chunk-HOUHSVGY-DDtc0Lod.js} +1 -1
- package/web-dist/assets/{chunk-ICXQ74PX-QSgBAuYw.js → chunk-ICXQ74PX-D1soMHlW.js} +1 -1
- package/web-dist/assets/{chunk-MOJQB5TN-DOI-0kaG.js → chunk-MOJQB5TN-BYZZoPrO.js} +1 -1
- package/web-dist/assets/{chunk-OGEWGWER-CZ3ED-QB.js → chunk-OGEWGWER-CSI1op21.js} +1 -1
- package/web-dist/assets/{chunk-PUDLZKDR-BQJElUFX.js → chunk-PUDLZKDR-B2_qeHID.js} +1 -1
- package/web-dist/assets/{chunk-Q4XR5HBZ-5B6Qs7rQ.js → chunk-Q4XR5HBZ-BNiafbsU.js} +1 -1
- package/web-dist/assets/{chunk-V7JOEXUC-DkMaAMFK.js → chunk-V7JOEXUC-D9aOhGjB.js} +1 -1
- package/web-dist/assets/{chunk-VAUOI2AC-Bvq-8GYO.js → chunk-VAUOI2AC-mt04_MVl.js} +1 -1
- package/web-dist/assets/{chunk-VR4S4FIN-DRVTU-HZ.js → chunk-VR4S4FIN-CTbhzN9l.js} +1 -1
- package/web-dist/assets/{chunk-WYO6CB5R-CRxI5d1E.js → chunk-WYO6CB5R-t-QJiLir.js} +1 -1
- package/web-dist/assets/{chunk-ZGVPDNZ5-D_3ow6xU.js → chunk-ZGVPDNZ5-BNBiwqoz.js} +1 -1
- package/web-dist/assets/classDiagram-OUVF2IWQ-DrMJp1ua.js +1 -0
- package/web-dist/assets/classDiagram-v2-EOCWNBFH-DrMJp1ua.js +1 -0
- package/web-dist/assets/{cynefin-VYW2F7L2-Bexf41pD.js → cynefin-VYW2F7L2-CJzDWQw9.js} +1 -1
- package/web-dist/assets/{cynefinDiagram-TSTJHNR4-9gbbl1EH.js → cynefinDiagram-TSTJHNR4-C_wWdWpO.js} +1 -1
- package/web-dist/assets/{dagre-VKFMJZFB-B04shbL0.js → dagre-VKFMJZFB-JcoSMott.js} +1 -1
- package/web-dist/assets/{diagram-FQU43EPY-CGXlhEsB.js → diagram-FQU43EPY-DwPIrxvI.js} +1 -1
- package/web-dist/assets/{diagram-G47NLZAW-DmPCeTOa.js → diagram-G47NLZAW-Bs1Iyjn4.js} +1 -1
- package/web-dist/assets/{diagram-NH7WQ7WH-D8Hthvi7.js → diagram-NH7WQ7WH-DFXMkDQZ.js} +1 -1
- package/web-dist/assets/{diagram-OA4YK3LP-DbLR6tfL.js → diagram-OA4YK3LP-BdeEougN.js} +1 -1
- package/web-dist/assets/{diagram-WEI45ONY-B6YWev_0.js → diagram-WEI45ONY-DOeCVBYO.js} +1 -1
- package/web-dist/assets/{ebnfDiagram-CCIWWBDH-8G1uf683.js → ebnfDiagram-CCIWWBDH-Dm5CrqN3.js} +1 -1
- package/web-dist/assets/{erDiagram-Q63AITRT-U_VRdQHz.js → erDiagram-Q63AITRT-B0ud7ncc.js} +1 -1
- package/web-dist/assets/eventmodeling-45OFAUF4-B52bjxMe.js +1 -0
- package/web-dist/assets/flowDiagram-23GEKE2U-DbFccp_w.js +1 -0
- package/web-dist/assets/{ganttDiagram-NO4QXBWP-Cnsi9uVf.js → ganttDiagram-NO4QXBWP-BdowNjAm.js} +1 -1
- package/web-dist/assets/{gitGraph-TEB2WS4Q-DYf7ka-G.js → gitGraph-TEB2WS4Q-BSDXrBNB.js} +1 -1
- package/web-dist/assets/{gitGraphDiagram-IHSO6WYX-Bvmr7dEH.js → gitGraphDiagram-IHSO6WYX-B3i3egZt.js} +1 -1
- package/web-dist/assets/{index-Czv3R-v0.js → index-BUX0IseR.js} +118 -118
- package/web-dist/assets/index-CjEngYN7.css +1 -0
- package/web-dist/assets/{info-DKCQHKI2-CdP9Q9r0.js → info-DKCQHKI2-B7CT3rc8.js} +1 -1
- package/web-dist/assets/{infoDiagram-FWYZ7A6U-RBcOH3Pi.js → infoDiagram-FWYZ7A6U-Bqmpgcu2.js} +1 -1
- package/web-dist/assets/{ishikawaDiagram-FXEZZL3T-zS0gy3fS.js → ishikawaDiagram-FXEZZL3T-Bd5LBQOn.js} +1 -1
- package/web-dist/assets/{journeyDiagram-5HDEW3XC-cOciJlFY.js → journeyDiagram-5HDEW3XC-lJOF3I7X.js} +1 -1
- package/web-dist/assets/{kanban-definition-HUTT4EX6-B-v0XClo.js → kanban-definition-HUTT4EX6-D4E5PRAv.js} +1 -1
- package/web-dist/assets/{line-z44YXdci.js → line-C9ZcrRyz.js} +1 -1
- package/web-dist/assets/{mermaid-parser.core-0Bg1x4p0.js → mermaid-parser.core-DkaL73Gv.js} +3 -3
- package/web-dist/assets/{mermaid.core-ByFqgcIE.js → mermaid.core-BQ89ySVU.js} +3 -3
- package/web-dist/assets/{mindmap-definition-LN4V7U3C-DiGaAQFh.js → mindmap-definition-LN4V7U3C-CB7JnCHh.js} +1 -1
- package/web-dist/assets/{packet-7NZHBO7P-Bv8ILo_S.js → packet-7NZHBO7P-BvyvpOhm.js} +1 -1
- package/web-dist/assets/{pegDiagram-2B236MQR-CtOUW7n0.js → pegDiagram-2B236MQR-BoygVhix.js} +1 -1
- package/web-dist/assets/{pie-RZYD4A2V-Dz4Bm-Vx.js → pie-RZYD4A2V-ChTjZLeC.js} +1 -1
- package/web-dist/assets/{pieDiagram-ENE6RG2P-VMY_CK3i.js → pieDiagram-ENE6RG2P-B3UNPTpF.js} +1 -1
- package/web-dist/assets/{quadrantDiagram-ABIIQ3AL-V7HZxM7j.js → quadrantDiagram-ABIIQ3AL-DJdWJ4GS.js} +1 -1
- package/web-dist/assets/{radar-I7S5WNFK-CWk6RruH.js → radar-I7S5WNFK-DHi5ReAY.js} +1 -1
- package/web-dist/assets/{railroad-3IZDKUUU-m_8st_Ez.js → railroad-3IZDKUUU-DcLJuGRW.js} +1 -1
- package/web-dist/assets/railroad-abnf-AHOZXSZD-BJcLzkwL.js +1 -0
- package/web-dist/assets/railroad-ebnf-EBAXGLYW-B4jrlWYB.js +1 -0
- package/web-dist/assets/railroad-peg-LSFZ7HO6-BpIzbo9k.js +1 -0
- package/web-dist/assets/{railroadDiagram-RFXS5EU6-Dz80V-7-.js → railroadDiagram-RFXS5EU6-W4vnMFZ2.js} +1 -1
- package/web-dist/assets/{requirementDiagram-TGXJPOKE-DrDDgTwm.js → requirementDiagram-TGXJPOKE-CV_V-9DW.js} +1 -1
- package/web-dist/assets/{sankeyDiagram-HTMAVEWB-D4SeC-Bi.js → sankeyDiagram-HTMAVEWB-DuIIsNBv.js} +1 -1
- package/web-dist/assets/{sequenceDiagram-DBY2YBRQ-CA-ZO_qp.js → sequenceDiagram-DBY2YBRQ-DTT8ETnv.js} +1 -1
- package/web-dist/assets/{stateDiagram-2N3HPSRC-C_ZYvV2s.js → stateDiagram-2N3HPSRC-HVZaDROf.js} +1 -1
- package/web-dist/assets/stateDiagram-v2-6OUMAXLB-DF9q3s7U.js +1 -0
- package/web-dist/assets/{swimlanes-5IMT3BWC-DGMDseYx.js → swimlanes-5IMT3BWC-DpGdPqRB.js} +1 -1
- package/web-dist/assets/swimlanesDiagram-G3AALYLV-BNeW4PCd.js +8 -0
- package/web-dist/assets/{timeline-definition-FHXFAJF6-CEiMp3_j.js → timeline-definition-FHXFAJF6-D9u3mgpd.js} +1 -1
- package/web-dist/assets/{treeView-QDETBFTQ-BSspY0US.js → treeView-QDETBFTQ-Dga6MhEJ.js} +1 -1
- package/web-dist/assets/{treemap-6X3UGDF4-DXNQxmQ7.js → treemap-6X3UGDF4-BwEXmcD6.js} +1 -1
- package/web-dist/assets/{vennDiagram-L72KCM5P-C-khqkdm.js → vennDiagram-L72KCM5P-BMvodYUW.js} +1 -1
- package/web-dist/assets/{wardley-OPB4EBWU-B9QCQ_Tm.js → wardley-OPB4EBWU-BzB6QK8X.js} +1 -1
- package/web-dist/assets/{wardleyDiagram-EHGQE667-vhVpAUzh.js → wardleyDiagram-EHGQE667-4ID7QRJi.js} +1 -1
- package/web-dist/assets/{xychartDiagram-FW5EYKEG-B8ev9zqs.js → xychartDiagram-FW5EYKEG-Ckob9hhW.js} +1 -1
- package/web-dist/index.html +2 -2
- package/web-dist/assets/architecture-TIHT7OUA-XOYod28l.js +0 -1
- package/web-dist/assets/channel-Bqn3pFKp.js +0 -1
- package/web-dist/assets/classDiagram-OUVF2IWQ-DEMCehy_.js +0 -1
- package/web-dist/assets/classDiagram-v2-EOCWNBFH-DEMCehy_.js +0 -1
- package/web-dist/assets/eventmodeling-45OFAUF4-DIpO2jQx.js +0 -1
- package/web-dist/assets/flowDiagram-23GEKE2U-aERDdceE.js +0 -1
- package/web-dist/assets/index-D8iyWUZ0.css +0 -1
- package/web-dist/assets/railroad-abnf-AHOZXSZD-DIaRscxr.js +0 -1
- package/web-dist/assets/railroad-ebnf-EBAXGLYW-CeHpbK-W.js +0 -1
- package/web-dist/assets/railroad-peg-LSFZ7HO6-CbhVIbOj.js +0 -1
- package/web-dist/assets/stateDiagram-v2-6OUMAXLB-BLevFa3H.js +0 -1
- package/web-dist/assets/swimlanesDiagram-G3AALYLV-00mQRq57.js +0 -8
package/dist/dev-child.js
CHANGED
|
@@ -475,7 +475,7 @@ function readGitWorktreeProjectId(worktree) {
|
|
|
475
475
|
);
|
|
476
476
|
}
|
|
477
477
|
function syncGitConfigPath(path) {
|
|
478
|
-
const fd = openSync(path, "r");
|
|
478
|
+
const fd = openSync(path, process.platform === "win32" ? "r+" : "r");
|
|
479
479
|
try {
|
|
480
480
|
fsyncSync(fd);
|
|
481
481
|
} finally {
|
|
@@ -12702,6 +12702,16 @@ var init_interactions = __esm({
|
|
|
12702
12702
|
}
|
|
12703
12703
|
});
|
|
12704
12704
|
|
|
12705
|
+
// packages/shared/src/claim.ts
|
|
12706
|
+
var CLAIM_MAX_AGE_MS, CLAIM_LEASE_MS;
|
|
12707
|
+
var init_claim = __esm({
|
|
12708
|
+
"packages/shared/src/claim.ts"() {
|
|
12709
|
+
"use strict";
|
|
12710
|
+
CLAIM_MAX_AGE_MS = 5 * 6e4;
|
|
12711
|
+
CLAIM_LEASE_MS = 30 * 24 * 60 * 6e4;
|
|
12712
|
+
}
|
|
12713
|
+
});
|
|
12714
|
+
|
|
12705
12715
|
// packages/shared/src/code-fences.ts
|
|
12706
12716
|
function fencedInteriors(text) {
|
|
12707
12717
|
const out = [];
|
|
@@ -13208,6 +13218,7 @@ var init_src = __esm({
|
|
|
13208
13218
|
init_zod();
|
|
13209
13219
|
init_interactions();
|
|
13210
13220
|
init_thread_slug();
|
|
13221
|
+
init_claim();
|
|
13211
13222
|
init_code_fences();
|
|
13212
13223
|
init_delta();
|
|
13213
13224
|
init_drainable_worker();
|
|
@@ -13598,7 +13609,7 @@ var init_src = __esm({
|
|
|
13598
13609
|
].join("\n");
|
|
13599
13610
|
PARK_CORRECTION_NAMES_LEAD = "\u26A0\uFE0F Your ```awaiting fence names ";
|
|
13600
13611
|
PARK_CORRECTION_RETIRED_LEAD = "\u26D4 Your ```awaiting fence uses ";
|
|
13601
|
-
ThreadWatchKind = external_exports.enum(["shell", "github"]);
|
|
13612
|
+
ThreadWatchKind = external_exports.enum(["shell", "github", "timer"]);
|
|
13602
13613
|
GithubChecksState = external_exports.enum(["none", "running", "passing", "failing"]);
|
|
13603
13614
|
GithubMergeState = external_exports.enum(["mergeable", "blocked", "conflicting", "unknown"]);
|
|
13604
13615
|
GithubWatchStatus = external_exports.object({
|
|
@@ -13632,7 +13643,12 @@ var init_src = __esm({
|
|
|
13632
13643
|
state: external_exports.enum(["armed", "fired", "dropped"]),
|
|
13633
13644
|
createdAt: external_exports.string(),
|
|
13634
13645
|
/** `github` rows only, and absent until the first successful poll. */
|
|
13635
|
-
github: GithubWatchStatus.optional()
|
|
13646
|
+
github: GithubWatchStatus.optional(),
|
|
13647
|
+
/** `timer` rows only: the armed timer's own registration, which is everything the row renders — the
|
|
13648
|
+
* worker's prompt is the row's NAME (a `tmr_…` id names nothing to a human) and the fire instant is
|
|
13649
|
+
* its status. Unlike `github` there is no polled half to be absent: a timer that exists is fully
|
|
13650
|
+
* known, so a timer row always carries this. */
|
|
13651
|
+
timer: external_exports.object({ fireAt: external_exports.string(), prompt: external_exports.string() }).strict().optional()
|
|
13636
13652
|
}).strict();
|
|
13637
13653
|
PR_WATCH_DEFAULT_FOR_MS = 6 * 60 * 60 * 1e3;
|
|
13638
13654
|
PR_WATCH_MAX_ARMED = 32;
|
|
@@ -20911,6 +20927,21 @@ function retireOutstandingDeliveries(storage, slug) {
|
|
|
20911
20927
|
storage.setDeliveryLedger(slug, serializeDeliveryLedger(next));
|
|
20912
20928
|
return items.length - next.length;
|
|
20913
20929
|
}
|
|
20930
|
+
function deliverOutstandingDeliveries(storage, slug) {
|
|
20931
|
+
const row = storage.getSession(slug);
|
|
20932
|
+
if (!row) return 0;
|
|
20933
|
+
const items = parseDeliveryLedger(row.delivery_ledger);
|
|
20934
|
+
const at = (/* @__PURE__ */ new Date()).toISOString();
|
|
20935
|
+
let moved = 0;
|
|
20936
|
+
const next = items.map((item) => {
|
|
20937
|
+
if (item.state !== "pending" && item.state !== "enqueued") return item;
|
|
20938
|
+
moved++;
|
|
20939
|
+
return { ...item, state: "delivered", updatedAt: at };
|
|
20940
|
+
});
|
|
20941
|
+
if (!moved) return 0;
|
|
20942
|
+
storage.setDeliveryLedger(slug, serializeDeliveryLedger(next));
|
|
20943
|
+
return moved;
|
|
20944
|
+
}
|
|
20914
20945
|
function deliveryItem(storage, slug, id) {
|
|
20915
20946
|
const row = storage.getSession(slug);
|
|
20916
20947
|
if (!row) return null;
|
|
@@ -21112,13 +21143,13 @@ function dropCancelled(messages, items) {
|
|
|
21112
21143
|
const dropped = /* @__PURE__ */ new Set();
|
|
21113
21144
|
for (const item of items) {
|
|
21114
21145
|
if (item.state !== "cancelled") continue;
|
|
21115
|
-
const text =
|
|
21146
|
+
const text = renderMatchKey(item.text);
|
|
21116
21147
|
const from = Date.parse(item.at) - 5e3;
|
|
21117
21148
|
const to = Date.parse(item.updatedAt) + CANCEL_MATCH_SLACK_MS;
|
|
21118
21149
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
21119
21150
|
const m = messages[i];
|
|
21120
21151
|
if (m.role !== "user" || dropped.has(i)) continue;
|
|
21121
|
-
if (
|
|
21152
|
+
if (renderMatchKey(m.text) !== text) continue;
|
|
21122
21153
|
const at = m.at ? Date.parse(m.at) : NaN;
|
|
21123
21154
|
if (Number.isFinite(at) && Number.isFinite(from) && Number.isFinite(to) && (at < from || at > to)) continue;
|
|
21124
21155
|
dropped.add(i);
|
|
@@ -21134,13 +21165,13 @@ function projectDeliveryLedger(messages, items) {
|
|
|
21134
21165
|
if (!cancelled.live.length) return messages;
|
|
21135
21166
|
const claimed = /* @__PURE__ */ new Set();
|
|
21136
21167
|
for (const item of cancelled.live) {
|
|
21137
|
-
const text =
|
|
21168
|
+
const text = renderMatchKey(item.text);
|
|
21138
21169
|
const tag = deliveryTag(item.id);
|
|
21139
21170
|
let handled = false;
|
|
21140
21171
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
21141
21172
|
const m = messages[i];
|
|
21142
21173
|
if (m.role !== "user" || claimed.has(i)) continue;
|
|
21143
|
-
if (!decodeDeliveryMarkers(m.text).includes(tag) &&
|
|
21174
|
+
if (!decodeDeliveryMarkers(m.text).includes(tag) && renderMatchKey(m.text) !== text) continue;
|
|
21144
21175
|
if (m.queued) {
|
|
21145
21176
|
if (item.state === "delivered") {
|
|
21146
21177
|
messages[i] = { ...m, queued: false, deliveryId: item.id, deliveryState: item.state };
|
|
@@ -21171,10 +21202,11 @@ function projectDeliveryLedger(messages, items) {
|
|
|
21171
21202
|
}
|
|
21172
21203
|
return messages;
|
|
21173
21204
|
}
|
|
21174
|
-
var PENDING_TIMEOUT_MS, UNCONFIRMED_DROP_MS, MAX_LEDGER_ITEMS, MAX_CANCELLED_ITEMS, canon, COMPOSED_ANCHOR_MIN, CANCEL_MATCH_SLACK_MS;
|
|
21205
|
+
var PENDING_TIMEOUT_MS, UNCONFIRMED_DROP_MS, MAX_LEDGER_ITEMS, MAX_CANCELLED_ITEMS, canon, COMPOSED_ANCHOR_MIN, renderMatchKey, CANCEL_MATCH_SLACK_MS;
|
|
21175
21206
|
var init_delivery_ledger = __esm({
|
|
21176
21207
|
"packages/server/src/delivery-ledger.ts"() {
|
|
21177
21208
|
"use strict";
|
|
21209
|
+
init_src();
|
|
21178
21210
|
init_delivery_marker();
|
|
21179
21211
|
PENDING_TIMEOUT_MS = 6e4;
|
|
21180
21212
|
UNCONFIRMED_DROP_MS = 60 * 6e4;
|
|
@@ -21182,6 +21214,7 @@ var init_delivery_ledger = __esm({
|
|
|
21182
21214
|
MAX_CANCELLED_ITEMS = 12;
|
|
21183
21215
|
canon = (s) => s.replace(/\s+/g, " ").trim();
|
|
21184
21216
|
COMPOSED_ANCHOR_MIN = 24;
|
|
21217
|
+
renderMatchKey = (s) => canon(stripHumanGapNote(stripWakeDeliveryToken(stripDeliveryMarkers(s))));
|
|
21185
21218
|
CANCEL_MATCH_SLACK_MS = 5e3;
|
|
21186
21219
|
}
|
|
21187
21220
|
});
|
|
@@ -35651,9 +35684,14 @@ function hasDeclaredBackgroundPark(tele, nowMs) {
|
|
|
35651
35684
|
if (Number.isFinite(restedMs) && nowMs - restedMs > DECLARED_PARK_MAX_MS) return false;
|
|
35652
35685
|
return true;
|
|
35653
35686
|
}
|
|
35654
|
-
function
|
|
35687
|
+
function hasParkedTimerWatch(tele, armedTimerIds) {
|
|
35688
|
+
if (tele?.lastFence?.kind !== "awaiting") return false;
|
|
35689
|
+
return tele.lastFence.hints.some((hint) => hint.kind === "timer" && armedTimerIds.has(hint.value.trim()));
|
|
35690
|
+
}
|
|
35691
|
+
function hasDeclaredWait(tele, nowMs, armedTimerIds = /* @__PURE__ */ new Set()) {
|
|
35655
35692
|
if (hasDeclaredBackgroundPark(tele, nowMs)) return true;
|
|
35656
35693
|
if (tele?.lastFence?.kind === "awaiting" && hasParkedPrWatch(tele)) return true;
|
|
35694
|
+
if (hasParkedTimerWatch(tele, armedTimerIds)) return true;
|
|
35657
35695
|
return (tele?.subAgents ?? []).some((a) => isDirectSubAgent(a) && a.state === "running");
|
|
35658
35696
|
}
|
|
35659
35697
|
function heldByRunningChecks(tele, github, registered) {
|
|
@@ -35691,9 +35729,23 @@ function bgSnoozeArmed(row) {
|
|
|
35691
35729
|
function hasParkedExternalWait(tele, _nowMs) {
|
|
35692
35730
|
return false;
|
|
35693
35731
|
}
|
|
35694
|
-
function fenceWatchViews(slug, tele, fenceAt, github = {}, registered = []) {
|
|
35732
|
+
function fenceWatchViews(slug, tele, fenceAt, github = {}, registered = [], armedTimers = []) {
|
|
35695
35733
|
const seen = /* @__PURE__ */ new Set();
|
|
35696
35734
|
const out = [];
|
|
35735
|
+
for (const t of armedTimers) {
|
|
35736
|
+
if (seen.has(`timer:${t.id}`)) continue;
|
|
35737
|
+
seen.add(`timer:${t.id}`);
|
|
35738
|
+
out.push({
|
|
35739
|
+
id: `timer:${slug}:${t.id}`,
|
|
35740
|
+
kind: "timer",
|
|
35741
|
+
target: t.id,
|
|
35742
|
+
state: "armed",
|
|
35743
|
+
createdAt: t.createdAt,
|
|
35744
|
+
// Always present, unlike the github half above: a timer that exists is fully known — there is no
|
|
35745
|
+
// poller to wait for. The prompt is the row's NAME client-side (a `tmr_…` id names nothing).
|
|
35746
|
+
timer: { fireAt: t.fireAt, prompt: t.prompt }
|
|
35747
|
+
});
|
|
35748
|
+
}
|
|
35697
35749
|
for (const w of registered) {
|
|
35698
35750
|
if (seen.has(`github:${w.target}`)) continue;
|
|
35699
35751
|
seen.add(`github:${w.target}`);
|
|
@@ -35742,11 +35794,13 @@ function deriveNeedsYou(row, tele, runtime, hasActionableInteraction = false, no
|
|
|
35742
35794
|
if (tele?.lastFence?.kind === "done") return true;
|
|
35743
35795
|
return true;
|
|
35744
35796
|
}
|
|
35745
|
-
function deriveAwaitingBackground(row, tele, runtime, hasActionableInteraction = false, nowMs = Date.now(), limitPause = void 0, deliveryProcessGone = false, github = {}, registeredPrWatches = /* @__PURE__ */ new Set()) {
|
|
35746
|
-
if (runtime !== "turn-idle" || !hasDeclaredWait(tele, nowMs)) return false;
|
|
35797
|
+
function deriveAwaitingBackground(row, tele, runtime, hasActionableInteraction = false, nowMs = Date.now(), limitPause = void 0, deliveryProcessGone = false, github = {}, registeredPrWatches = /* @__PURE__ */ new Set(), armedTimerIds = /* @__PURE__ */ new Set()) {
|
|
35798
|
+
if (runtime !== "turn-idle" || !hasDeclaredWait(tele, nowMs, armedTimerIds)) return false;
|
|
35747
35799
|
if (hasActionableInteraction || tele?.pendingAsk || tele?.pendingQuestion) return false;
|
|
35748
35800
|
if (tele?.lastFence?.kind === "done") return false;
|
|
35749
|
-
if (tele?.lastFence?.kind === "awaiting" && !hasParkedPrWatch(tele) && !hasDeclaredBackgroundPark(tele, nowMs))
|
|
35801
|
+
if (tele?.lastFence?.kind === "awaiting" && !hasParkedPrWatch(tele) && !hasDeclaredBackgroundPark(tele, nowMs) && // A TIMER PARK IS THE SAME EXCEPTION AGAIN (2026-08-24): its fence has no park action either, so
|
|
35802
|
+
// suppressing this card left the wait stated nowhere but the fence's own machinery footer.
|
|
35803
|
+
!hasParkedTimerWatch(tele, armedTimerIds)) return false;
|
|
35750
35804
|
return deriveNeedsYou({ ...row, bg_snooze_rested_at: null }, tele, runtime, hasActionableInteraction, nowMs, limitPause, false, deliveryProcessGone);
|
|
35751
35805
|
}
|
|
35752
35806
|
function resolveSessionProfile(row, tele) {
|
|
@@ -35830,6 +35884,13 @@ function sessionThreadView(projectDir, storage, row, tele, registeredLegacyTermi
|
|
|
35830
35884
|
createdAt: new Date(w.created_at).toISOString()
|
|
35831
35885
|
}));
|
|
35832
35886
|
const registeredPrWatches = new Set(armedPrWatches.map((w) => w.target));
|
|
35887
|
+
const armedTimers = storage.listThreadTimers(row.slug, { armedOnly: true }).map((t) => ({
|
|
35888
|
+
id: t.id,
|
|
35889
|
+
prompt: t.prompt,
|
|
35890
|
+
fireAt: new Date(t.fire_at).toISOString(),
|
|
35891
|
+
createdAt: new Date(t.created_at).toISOString()
|
|
35892
|
+
}));
|
|
35893
|
+
const armedTimerIds = new Set(armedTimers.map((t) => t.id));
|
|
35833
35894
|
const headlessStalled = row.codex_runtime === "app-server" ? appServerTurnStalled(codexTurnLiveness(row.slug, row.session_id), tele?.lastActivityAt, nowMs) : isBrokerClaudeRow(row) ? !claudeBrokerDaemonAlive(row.session_id) : false;
|
|
35834
35895
|
const headlessLostWork = isBrokerClaudeRow(row) && headlessStalled && hasUnretiredOwnAgents(tele);
|
|
35835
35896
|
const deliveryProcessGone = isBrokerClaudeRow(row) && headlessStalled;
|
|
@@ -35847,7 +35908,7 @@ function sessionThreadView(projectDir, storage, row, tele, registeredLegacyTermi
|
|
|
35847
35908
|
const archived = state === "archived";
|
|
35848
35909
|
const limitPause = resolveLimitPause(row, tele, nowMs);
|
|
35849
35910
|
const needsYou = archived ? false : deriveNeedsYou(row, tele, runtime, interactionPresence.needsUser, nowMs, limitPause, true, deliveryProcessGone, github, registeredPrWatches);
|
|
35850
|
-
const awaitingBackground = archived ? false : deriveAwaitingBackground(row, tele, runtime, interactionPresence.needsUser, nowMs, limitPause, deliveryProcessGone, github, registeredPrWatches);
|
|
35911
|
+
const awaitingBackground = archived ? false : deriveAwaitingBackground(row, tele, runtime, interactionPresence.needsUser, nowMs, limitPause, deliveryProcessGone, github, registeredPrWatches, armedTimerIds);
|
|
35851
35912
|
const crashed = runtime === "exited" && (tele?.turn === "in-flight" || hasLiveBackgroundWork(tele) || headlessLostWork);
|
|
35852
35913
|
const snoozedUntil = futureSnooze(row, nowMs);
|
|
35853
35914
|
const profile = resolveSessionProfile(row, tele);
|
|
@@ -35883,7 +35944,7 @@ function sessionThreadView(projectDir, storage, row, tele, registeredLegacyTermi
|
|
|
35883
35944
|
// become the github rows, `watch:` lines the shell rows — so this strip lists exactly what will
|
|
35884
35945
|
// actually wake the thread, and the two cannot drift into claiming different things. There is no
|
|
35885
35946
|
// registry behind either any more (`thread_watch`, retired 2026-08-14).
|
|
35886
|
-
watches: fenceWatchViews(row.slug, tele, tele?.lastAssistantAt, github, armedPrWatches),
|
|
35947
|
+
watches: fenceWatchViews(row.slug, tele, tele?.lastAssistantAt, github, armedPrWatches, armedTimers),
|
|
35887
35948
|
pendingAsk: tele?.pendingAsk ? { questions: tele.pendingAsk.questions } : void 0,
|
|
35888
35949
|
pendingQuestion: tele?.pendingQuestion ?? false,
|
|
35889
35950
|
lastUserAt: tele?.lastUserAt,
|
|
@@ -38445,6 +38506,17 @@ import { execFile as execFile7 } from "node:child_process";
|
|
|
38445
38506
|
import { readdirSync as readdirSync8, unlinkSync as unlinkSync4 } from "node:fs";
|
|
38446
38507
|
import { connect as connectSocket } from "node:net";
|
|
38447
38508
|
import { join as join29 } from "node:path";
|
|
38509
|
+
function parseLsofSocketNames(stdout) {
|
|
38510
|
+
const referenced = /* @__PURE__ */ new Set();
|
|
38511
|
+
for (const line of stdout.split("\n")) {
|
|
38512
|
+
if (!line.startsWith("n/")) continue;
|
|
38513
|
+
const raw2 = line.slice(1);
|
|
38514
|
+
referenced.add(raw2);
|
|
38515
|
+
const meta = raw2.indexOf(" type=");
|
|
38516
|
+
if (meta > 0) referenced.add(raw2.slice(0, meta));
|
|
38517
|
+
}
|
|
38518
|
+
return referenced;
|
|
38519
|
+
}
|
|
38448
38520
|
function sweepStaleSockets(options, deps = {}) {
|
|
38449
38521
|
if (process.platform === "win32") return;
|
|
38450
38522
|
const keep = new Set(options.keep ?? []);
|
|
@@ -38480,9 +38552,7 @@ var init_stale_socket_sweep = __esm({
|
|
|
38480
38552
|
execFile7("lsof", ["-U", "-F", "n"], { timeout: 3e4, maxBuffer: 16 * 1024 * 1024 }, (error, stdout) => {
|
|
38481
38553
|
if (!stdout) return done(null);
|
|
38482
38554
|
if (error && !stdout.includes(prefix)) return done(null);
|
|
38483
|
-
|
|
38484
|
-
for (const line of stdout.split("\n")) if (line.startsWith("n/")) referenced.add(line.slice(1));
|
|
38485
|
-
done(referenced);
|
|
38555
|
+
done(parseLsofSocketNames(stdout));
|
|
38486
38556
|
}).unref?.();
|
|
38487
38557
|
};
|
|
38488
38558
|
defaultProbe = (path, verdict) => {
|
|
@@ -38502,6 +38572,7 @@ var init_stale_socket_sweep = __esm({
|
|
|
38502
38572
|
|
|
38503
38573
|
// packages/server/src/orphan-reaper.ts
|
|
38504
38574
|
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
38575
|
+
import { readFileSync as readFileSync17 } from "node:fs";
|
|
38505
38576
|
import { dirname as dirname12 } from "node:path";
|
|
38506
38577
|
function firstTokenBasename(command) {
|
|
38507
38578
|
const first = command.trimStart().split(/\s+/, 1)[0] ?? "";
|
|
@@ -38601,8 +38672,8 @@ function parseEtimeMs(etime) {
|
|
|
38601
38672
|
else return 0;
|
|
38602
38673
|
return (((days * 24 + h) * 60 + m) * 60 + s) * 1e3;
|
|
38603
38674
|
}
|
|
38604
|
-
function enumerateProcs(exec = defaultExec) {
|
|
38605
|
-
const base = exec("ps", ["-
|
|
38675
|
+
function enumerateProcs(exec = defaultExec, opts = {}) {
|
|
38676
|
+
const base = exec("ps", ["-Aww", "-o", "pid=,ppid=,etime=,command="]);
|
|
38606
38677
|
const rows = [];
|
|
38607
38678
|
const byPid = /* @__PURE__ */ new Map();
|
|
38608
38679
|
const pids = [];
|
|
@@ -38618,6 +38689,21 @@ function enumerateProcs(exec = defaultExec) {
|
|
|
38618
38689
|
pids.push(pid);
|
|
38619
38690
|
}
|
|
38620
38691
|
if (!pids.length) return rows;
|
|
38692
|
+
if ((opts.platform ?? process.platform) === "linux") {
|
|
38693
|
+
const readEnv = opts.readEnv ?? defaultReadEnv;
|
|
38694
|
+
for (const row of rows) {
|
|
38695
|
+
const environ = readEnv(row.pid);
|
|
38696
|
+
if (environ === null) continue;
|
|
38697
|
+
for (const entry of environ.split("\0")) {
|
|
38698
|
+
const m = entry.match(/^FRIZZ_THREAD=([A-Za-z0-9._-]+)$/);
|
|
38699
|
+
if (m) {
|
|
38700
|
+
row.slug = m[1];
|
|
38701
|
+
break;
|
|
38702
|
+
}
|
|
38703
|
+
}
|
|
38704
|
+
}
|
|
38705
|
+
return rows;
|
|
38706
|
+
}
|
|
38621
38707
|
let text;
|
|
38622
38708
|
try {
|
|
38623
38709
|
text = exec("ps", ["-Eww", "-o", "pid=,command=", "-p", pids.join(",")]);
|
|
@@ -38693,7 +38779,7 @@ function sweepOrphansOnce(deps = {}) {
|
|
|
38693
38779
|
const minAgeMs = deps.minAgeMs ?? ORPHAN_MIN_AGE_MS;
|
|
38694
38780
|
let rows;
|
|
38695
38781
|
try {
|
|
38696
|
-
rows = enumerateProcs(exec);
|
|
38782
|
+
rows = enumerateProcs(exec, { platform: deps.platform, readEnv: deps.readEnv });
|
|
38697
38783
|
} catch {
|
|
38698
38784
|
return { reaped: 0, deadSlugs: [], liveSlugs: [] };
|
|
38699
38785
|
}
|
|
@@ -38741,7 +38827,7 @@ function startOrphanReaper(deps = {}) {
|
|
|
38741
38827
|
clearInterval(socketTimer);
|
|
38742
38828
|
};
|
|
38743
38829
|
}
|
|
38744
|
-
var ORPHAN_REAP_INTERVAL_MS, ORPHAN_MIN_AGE_MS, SLUG_RE, defaultExec, defaultKill, STALE_SOCKET_SWEEP_INTERVAL_MS, STALE_SOCKET_SWEEP_DELAY_MS, CLAUDE_BROKER_SOCKET_PREFIX;
|
|
38830
|
+
var ORPHAN_REAP_INTERVAL_MS, ORPHAN_MIN_AGE_MS, SLUG_RE, defaultExec, defaultReadEnv, defaultKill, STALE_SOCKET_SWEEP_INTERVAL_MS, STALE_SOCKET_SWEEP_DELAY_MS, CLAUDE_BROKER_SOCKET_PREFIX;
|
|
38745
38831
|
var init_orphan_reaper = __esm({
|
|
38746
38832
|
"packages/server/src/orphan-reaper.ts"() {
|
|
38747
38833
|
"use strict";
|
|
@@ -38751,6 +38837,13 @@ var init_orphan_reaper = __esm({
|
|
|
38751
38837
|
ORPHAN_MIN_AGE_MS = 12e4;
|
|
38752
38838
|
SLUG_RE = /FRIZZ_THREAD=([A-Za-z0-9._-]+)/;
|
|
38753
38839
|
defaultExec = (file, args) => execFileSync5(file, args, { encoding: "utf8", maxBuffer: 16 * 1024 * 1024, timeout: 1e4 });
|
|
38840
|
+
defaultReadEnv = (pid) => {
|
|
38841
|
+
try {
|
|
38842
|
+
return readFileSync17(`/proc/${pid}/environ`, "utf8");
|
|
38843
|
+
} catch {
|
|
38844
|
+
return null;
|
|
38845
|
+
}
|
|
38846
|
+
};
|
|
38754
38847
|
defaultKill = (pid) => {
|
|
38755
38848
|
try {
|
|
38756
38849
|
process.kill(pid, "SIGKILL");
|
|
@@ -42078,7 +42171,7 @@ var init_server = __esm({
|
|
|
42078
42171
|
});
|
|
42079
42172
|
|
|
42080
42173
|
// packages/server/src/repair.ts
|
|
42081
|
-
import { existsSync as existsSync12, readFileSync as
|
|
42174
|
+
import { existsSync as existsSync12, readFileSync as readFileSync18, writeFileSync as writeFileSync11 } from "node:fs";
|
|
42082
42175
|
import { basename as basename7, dirname as dirname13, resolve as resolve6 } from "node:path";
|
|
42083
42176
|
function quoteValue(v) {
|
|
42084
42177
|
if (/^[\w./#:+-]+$/.test(v)) return v;
|
|
@@ -42094,7 +42187,7 @@ function repairThreadFile(frizzDir, file) {
|
|
|
42094
42187
|
if (dirname13(abs) !== root) throw new RepairError(`refusing to repair "${file}": not directly under .frizz/`);
|
|
42095
42188
|
if (!abs.endsWith(".md")) throw new RepairError(`refusing to repair "${file}": not a .md thread file`);
|
|
42096
42189
|
if (!existsSync12(abs)) throw new RepairError(`no thread file to repair: ${basename7(abs)}`);
|
|
42097
|
-
const content =
|
|
42190
|
+
const content = readFileSync18(abs, "utf8");
|
|
42098
42191
|
const firstLine2 = content.replace(/^/, "").split(/\r?\n/).find((l) => l.trim() !== "");
|
|
42099
42192
|
if (firstLine2?.trim() === "---") {
|
|
42100
42193
|
throw new RepairError(`${basename7(abs)} already opens with a "---" block \u2014 repair only heals a MISSING frontmatter block`);
|
|
@@ -42127,7 +42220,7 @@ var init_repair = __esm({
|
|
|
42127
42220
|
});
|
|
42128
42221
|
|
|
42129
42222
|
// cc-worker/hooks/bash-background.mjs
|
|
42130
|
-
import { readFileSync as
|
|
42223
|
+
import { readFileSync as readFileSync19 } from "node:fs";
|
|
42131
42224
|
import { basename as basename8 } from "node:path";
|
|
42132
42225
|
import { pathToFileURL } from "node:url";
|
|
42133
42226
|
function emit(obj) {
|
|
@@ -42276,7 +42369,7 @@ var init_bash_background = __esm({
|
|
|
42276
42369
|
if (isDirectHookExecution(process.argv[1], import.meta.url)) {
|
|
42277
42370
|
try {
|
|
42278
42371
|
const env = process.argv.includes("--frizz-thread") ? { ...process.env, FRIZZ_THREAD: process.env.FRIZZ_THREAD || "codex-worker" } : process.env;
|
|
42279
|
-
emit(evaluateBashBackgroundHook(JSON.parse(
|
|
42372
|
+
emit(evaluateBashBackgroundHook(JSON.parse(readFileSync19(0, "utf8")), env));
|
|
42280
42373
|
} catch {
|
|
42281
42374
|
emit({});
|
|
42282
42375
|
}
|
|
@@ -42285,7 +42378,7 @@ var init_bash_background = __esm({
|
|
|
42285
42378
|
});
|
|
42286
42379
|
|
|
42287
42380
|
// packages/server/src/transcript.ts
|
|
42288
|
-
import { closeSync as closeSync13, existsSync as existsSync13, fstatSync as fstatSync3, mkdirSync as mkdirSync15, openSync as openSync14, readdirSync as readdirSync9, readFileSync as
|
|
42381
|
+
import { closeSync as closeSync13, existsSync as existsSync13, fstatSync as fstatSync3, mkdirSync as mkdirSync15, openSync as openSync14, readdirSync as readdirSync9, readFileSync as readFileSync20, readSync as readSync7, renameSync as renameSync9, statSync as statSync14, unlinkSync as unlinkSync5, writeFileSync as writeFileSync12 } from "node:fs";
|
|
42289
42382
|
import { createHash as createHash13 } from "node:crypto";
|
|
42290
42383
|
import { StringDecoder as StringDecoder4 } from "node:string_decoder";
|
|
42291
42384
|
import { join as join31 } from "node:path";
|
|
@@ -42393,17 +42486,28 @@ function pushToolPart(m, call) {
|
|
|
42393
42486
|
else m.parts.push({ kind: "tools", tools: [call] });
|
|
42394
42487
|
}
|
|
42395
42488
|
function coalescedQueuedKeys(deliveredText, pendingKeys) {
|
|
42396
|
-
|
|
42397
|
-
|
|
42398
|
-
|
|
42399
|
-
|
|
42400
|
-
|
|
42401
|
-
|
|
42402
|
-
if (
|
|
42403
|
-
|
|
42404
|
-
cursor
|
|
42405
|
-
|
|
42406
|
-
|
|
42489
|
+
if (!deliveredText) return [];
|
|
42490
|
+
const keys = [...pendingKeys];
|
|
42491
|
+
const dead = /* @__PURE__ */ new Set();
|
|
42492
|
+
const walk = (cursor, index) => {
|
|
42493
|
+
if (index >= keys.length) return null;
|
|
42494
|
+
const state = cursor * (keys.length + 1) + index;
|
|
42495
|
+
if (dead.has(state)) return null;
|
|
42496
|
+
const key = keys[index];
|
|
42497
|
+
if (key && deliveredText.startsWith(key, cursor)) {
|
|
42498
|
+
const next = cursor + key.length;
|
|
42499
|
+
if (next === deliveredText.length) return [key];
|
|
42500
|
+
if (deliveredText.startsWith("\n", next)) {
|
|
42501
|
+
const rest = walk(next + 1, index + 1);
|
|
42502
|
+
if (rest) return [key, ...rest];
|
|
42503
|
+
}
|
|
42504
|
+
}
|
|
42505
|
+
const skipped = walk(cursor, index + 1);
|
|
42506
|
+
if (skipped) return skipped;
|
|
42507
|
+
dead.add(state);
|
|
42508
|
+
return null;
|
|
42509
|
+
};
|
|
42510
|
+
return walk(0, 0) ?? [];
|
|
42407
42511
|
}
|
|
42408
42512
|
function commandEnvelopeQueuedKey(deliveredText) {
|
|
42409
42513
|
const name = COMMAND_NAME_RE.exec(deliveredText)?.[1]?.trim();
|
|
@@ -42890,7 +42994,7 @@ function persistSentFile(srcPath, idKey) {
|
|
|
42890
42994
|
if (existsSync13(dest)) return dest;
|
|
42891
42995
|
const size = statSync14(srcPath).size;
|
|
42892
42996
|
if (size === 0 || size > SENT_IMAGE_MAX_BYTES) return void 0;
|
|
42893
|
-
const buf =
|
|
42997
|
+
const buf = readFileSync20(srcPath);
|
|
42894
42998
|
if (!looksLikeImage(buf, outExt)) return void 0;
|
|
42895
42999
|
mkdirSync15(SCREENSHOT_CACHE_DIR, { recursive: true });
|
|
42896
43000
|
const tmp = join31(SCREENSHOT_CACHE_DIR, `.${name}.${process.pid}.${screenshotTmpSeq++}.tmp`);
|
|
@@ -43310,7 +43414,7 @@ function readTranscript(project, sessionId) {
|
|
|
43310
43414
|
}
|
|
43311
43415
|
function verifyIncrementalParse(path, identityPrefix, incremental) {
|
|
43312
43416
|
try {
|
|
43313
|
-
const fresh = parseTranscript(
|
|
43417
|
+
const fresh = parseTranscript(readFileSync20(path, "utf8"), identityPrefix);
|
|
43314
43418
|
const a = JSON.stringify(incremental);
|
|
43315
43419
|
const b = JSON.stringify(fresh);
|
|
43316
43420
|
if (a !== b) {
|
|
@@ -44542,7 +44646,7 @@ function readEarlierThreadTranscriptPage(project, storage, slug, cursor, backend
|
|
|
44542
44646
|
}
|
|
44543
44647
|
function readCodexTranscriptFile(absPath, nativeId = absPath) {
|
|
44544
44648
|
try {
|
|
44545
|
-
return parseCodexTranscript(
|
|
44649
|
+
return parseCodexTranscript(readFileSync20(absPath, "utf8"), `codex:${nativeId}`);
|
|
44546
44650
|
} catch {
|
|
44547
44651
|
return [];
|
|
44548
44652
|
}
|
|
@@ -44636,7 +44740,7 @@ function projectTranscriptPageAgentLifecycles(page, lookup, peerLookup) {
|
|
|
44636
44740
|
function readTranscriptFile(absPath) {
|
|
44637
44741
|
try {
|
|
44638
44742
|
const pathKey = createHash13("sha256").update(absPath).digest("base64url").slice(0, 16);
|
|
44639
|
-
return parseTranscript(
|
|
44743
|
+
return parseTranscript(readFileSync20(absPath, "utf8"), `claude-file:${pathKey}`);
|
|
44640
44744
|
} catch {
|
|
44641
44745
|
return [];
|
|
44642
44746
|
}
|
|
@@ -44733,7 +44837,7 @@ var init_open_external = __esm({
|
|
|
44733
44837
|
|
|
44734
44838
|
// packages/server/src/local-file.ts
|
|
44735
44839
|
import { spawn as spawn6 } from "node:child_process";
|
|
44736
|
-
import { readFileSync as
|
|
44840
|
+
import { readFileSync as readFileSync21, realpathSync as realpathSync8, statSync as statSync15 } from "node:fs";
|
|
44737
44841
|
import { homedir as homedir15 } from "node:os";
|
|
44738
44842
|
import { isAbsolute as isAbsolute3, join as join32, resolve as resolve7, sep } from "node:path";
|
|
44739
44843
|
function isUnder(real, root) {
|
|
@@ -44776,7 +44880,7 @@ function readLocalMarkdown(rawPath, roots) {
|
|
|
44776
44880
|
if (!MARKDOWN_FILE_EXT.test(rawPath.trim())) throw new Error("Local file is not a Markdown file");
|
|
44777
44881
|
const path = resolveLocalFile(rawPath, roots);
|
|
44778
44882
|
if (!MARKDOWN_FILE_EXT.test(path)) throw new Error("Local file is not a Markdown file");
|
|
44779
|
-
const bytes =
|
|
44883
|
+
const bytes = readFileSync21(path);
|
|
44780
44884
|
if (bytes.length <= MARKDOWN_READ_LIMIT) return { path, markdown: bytes.toString("utf8"), truncated: false };
|
|
44781
44885
|
const head = bytes.subarray(0, MARKDOWN_READ_LIMIT);
|
|
44782
44886
|
const lastBreak = head.lastIndexOf(10);
|
|
@@ -45222,6 +45326,17 @@ function readBackgroundShellOutput(path, maxBytes = OUTPUT_TAIL_BYTES) {
|
|
|
45222
45326
|
if (fd !== void 0) closeSync14(fd);
|
|
45223
45327
|
}
|
|
45224
45328
|
}
|
|
45329
|
+
function readHead2(fd, length) {
|
|
45330
|
+
if (length <= 0) return "";
|
|
45331
|
+
const buffer = Buffer.alloc(length);
|
|
45332
|
+
let read = 0;
|
|
45333
|
+
while (read < length) {
|
|
45334
|
+
const count = readSync8(fd, buffer, read, length - read, read);
|
|
45335
|
+
if (count === 0) break;
|
|
45336
|
+
read += count;
|
|
45337
|
+
}
|
|
45338
|
+
return buffer.subarray(0, read).toString("latin1");
|
|
45339
|
+
}
|
|
45225
45340
|
function backgroundShellLineCount(path) {
|
|
45226
45341
|
let fd;
|
|
45227
45342
|
try {
|
|
@@ -45229,9 +45344,21 @@ function backgroundShellLineCount(path) {
|
|
|
45229
45344
|
const stat2 = fstatSync4(fd);
|
|
45230
45345
|
const size = stat2.size;
|
|
45231
45346
|
let state = scans.get(path);
|
|
45232
|
-
if (state && (state.bytes > size || state.ino !== stat2.ino)) state = void 0;
|
|
45347
|
+
if (state && (state.bytes > size || state.ino !== stat2.ino || state.birthtimeMs !== stat2.birthtimeMs)) state = void 0;
|
|
45348
|
+
if (state && state.fingerprint !== readHead2(fd, state.fingerprint.length)) state = void 0;
|
|
45233
45349
|
if (state?.overflowed) return void 0;
|
|
45234
|
-
if (!state)
|
|
45350
|
+
if (!state) {
|
|
45351
|
+
state = {
|
|
45352
|
+
ino: stat2.ino,
|
|
45353
|
+
birthtimeMs: stat2.birthtimeMs,
|
|
45354
|
+
fingerprint: readHead2(fd, Math.min(FINGERPRINT_BYTES, size)),
|
|
45355
|
+
bytes: 0,
|
|
45356
|
+
breaks: 0,
|
|
45357
|
+
pendingCR: false,
|
|
45358
|
+
trailing: false,
|
|
45359
|
+
overflowed: false
|
|
45360
|
+
};
|
|
45361
|
+
}
|
|
45235
45362
|
if (size - state.bytes > SCAN_CEILING_BYTES) {
|
|
45236
45363
|
scans.set(path, { ...state, overflowed: true });
|
|
45237
45364
|
return void 0;
|
|
@@ -45267,7 +45394,7 @@ function backgroundShellLineCount(path) {
|
|
|
45267
45394
|
if (fd !== void 0) closeSync14(fd);
|
|
45268
45395
|
}
|
|
45269
45396
|
}
|
|
45270
|
-
var OUTPUT_TAIL_BYTES, SCAN_CHUNK_BYTES, SCAN_CEILING_BYTES, SCAN_CACHE_LIMIT, ANSI_ESCAPE_RE, scans;
|
|
45397
|
+
var OUTPUT_TAIL_BYTES, SCAN_CHUNK_BYTES, SCAN_CEILING_BYTES, SCAN_CACHE_LIMIT, FINGERPRINT_BYTES, ANSI_ESCAPE_RE, scans;
|
|
45271
45398
|
var init_background_shell_output = __esm({
|
|
45272
45399
|
"packages/server/src/background-shell-output.ts"() {
|
|
45273
45400
|
"use strict";
|
|
@@ -45275,6 +45402,7 @@ var init_background_shell_output = __esm({
|
|
|
45275
45402
|
SCAN_CHUNK_BYTES = 256 * 1024;
|
|
45276
45403
|
SCAN_CEILING_BYTES = 128 * 1024 * 1024;
|
|
45277
45404
|
SCAN_CACHE_LIMIT = 512;
|
|
45405
|
+
FINGERPRINT_BYTES = 64;
|
|
45278
45406
|
ANSI_ESCAPE_RE = /\x1b(?:\][^\x07]*(?:\x07|\x1b\\)|\[[0-?]*[ -/]*[@-~])/g;
|
|
45279
45407
|
scans = /* @__PURE__ */ new Map();
|
|
45280
45408
|
}
|
|
@@ -45283,7 +45411,7 @@ var init_background_shell_output = __esm({
|
|
|
45283
45411
|
// packages/server/src/image-header.ts
|
|
45284
45412
|
import { closeSync as closeSync15, openSync as openSync16, readSync as readSync9, statSync as statSync16 } from "node:fs";
|
|
45285
45413
|
import { extname } from "node:path";
|
|
45286
|
-
function
|
|
45414
|
+
function readHead3(path, budget) {
|
|
45287
45415
|
let fd;
|
|
45288
45416
|
try {
|
|
45289
45417
|
const size = statSync16(path).size;
|
|
@@ -45391,7 +45519,7 @@ function svg(head) {
|
|
|
45391
45519
|
}
|
|
45392
45520
|
function svgDeclaresColour(path) {
|
|
45393
45521
|
if (extname(path).toLowerCase() !== ".svg") return void 0;
|
|
45394
|
-
const head =
|
|
45522
|
+
const head = readHead3(path, 512 * 1024);
|
|
45395
45523
|
if (!head) return void 0;
|
|
45396
45524
|
const source = head.toString("utf8");
|
|
45397
45525
|
if (!/<svg\b/iu.test(source)) return void 0;
|
|
@@ -45404,7 +45532,7 @@ function svgDeclaresColour(path) {
|
|
|
45404
45532
|
function imageDimensions(path) {
|
|
45405
45533
|
const extension2 = extname(path).toLowerCase();
|
|
45406
45534
|
const budget = extension2 === ".jpg" || extension2 === ".jpeg" ? JPEG_SCAN_BYTES : HEAD_BYTES2;
|
|
45407
|
-
const head =
|
|
45535
|
+
const head = readHead3(path, budget);
|
|
45408
45536
|
if (!head) return void 0;
|
|
45409
45537
|
return png(head) ?? gif(head) ?? webp(head) ?? ico(head) ?? jpeg(head) ?? svg(head);
|
|
45410
45538
|
}
|
|
@@ -45512,7 +45640,7 @@ var init_directory_picker = __esm({
|
|
|
45512
45640
|
});
|
|
45513
45641
|
|
|
45514
45642
|
// packages/server/src/router.ts
|
|
45515
|
-
import { readFileSync as
|
|
45643
|
+
import { readFileSync as readFileSync22, statSync as statSync17 } from "node:fs";
|
|
45516
45644
|
import { join as join33, resolve as resolve8 } from "node:path";
|
|
45517
45645
|
import { randomUUID as randomUUID16 } from "node:crypto";
|
|
45518
45646
|
import { basename as basename9, dirname as dirname14 } from "node:path";
|
|
@@ -45721,7 +45849,7 @@ function storeProjectIcon(id, name, bytes) {
|
|
|
45721
45849
|
function setProjectIconFromFile(id, file) {
|
|
45722
45850
|
let bytes;
|
|
45723
45851
|
try {
|
|
45724
|
-
bytes =
|
|
45852
|
+
bytes = readFileSync22(file);
|
|
45725
45853
|
} catch {
|
|
45726
45854
|
throw new Error("That file could not be read.");
|
|
45727
45855
|
}
|
|
@@ -46361,15 +46489,16 @@ ${gapNote}` : input.message;
|
|
|
46361
46489
|
)
|
|
46362
46490
|
});
|
|
46363
46491
|
if (input.freshProcess) retireOutstandingDeliveries(ctx.storage, input.slug);
|
|
46364
|
-
|
|
46492
|
+
const preempted = input.interrupt === true && bridge.interruptTurn({ threadSlug: input.slug, sessionId: row.session_id });
|
|
46365
46493
|
if (input.deliveryId) {
|
|
46366
46494
|
appendDelivery(ctx.storage, input.slug, {
|
|
46367
46495
|
id: input.deliveryId,
|
|
46368
46496
|
text: input.message,
|
|
46369
46497
|
state: midTurn && input.freshProcess !== true ? "enqueued" : "delivered"
|
|
46370
46498
|
});
|
|
46371
|
-
ctx.transcriptChange.emit([input.slug]);
|
|
46372
46499
|
}
|
|
46500
|
+
if (preempted) deliverOutstandingDeliveries(ctx.storage, input.slug);
|
|
46501
|
+
if (input.deliveryId || preempted) ctx.transcriptChange.emit([input.slug]);
|
|
46373
46502
|
ctx.board.refresh();
|
|
46374
46503
|
return;
|
|
46375
46504
|
}
|
|
@@ -46455,6 +46584,7 @@ ${gapNote}` : input.message;
|
|
|
46455
46584
|
if (!bridge.interruptTurn({ threadSlug: input.slug, sessionId: row.session_id })) {
|
|
46456
46585
|
return { interrupted: false, reason: "Nothing to interrupt \u2014 this thread has no turn running" };
|
|
46457
46586
|
}
|
|
46587
|
+
if (deliverOutstandingDeliveries(ctx.storage, input.slug)) ctx.transcriptChange.emit([input.slug]);
|
|
46458
46588
|
return { interrupted: true };
|
|
46459
46589
|
}
|
|
46460
46590
|
}),
|
|
@@ -47710,7 +47840,7 @@ var init_compression = __esm({
|
|
|
47710
47840
|
});
|
|
47711
47841
|
|
|
47712
47842
|
// packages/server/src/local-image.ts
|
|
47713
|
-
import { readFileSync as
|
|
47843
|
+
import { readFileSync as readFileSync23, realpathSync as realpathSync9, statSync as statSync18 } from "node:fs";
|
|
47714
47844
|
import { extname as extname2, isAbsolute as isAbsolute4 } from "node:path";
|
|
47715
47845
|
function resolveLocalImage(rawPath) {
|
|
47716
47846
|
if (!rawPath || !isAbsolute4(rawPath)) return { status: 400 };
|
|
@@ -47724,7 +47854,7 @@ function resolveLocalImage(rawPath) {
|
|
|
47724
47854
|
}
|
|
47725
47855
|
try {
|
|
47726
47856
|
if (!statSync18(real).isFile()) return { status: 404 };
|
|
47727
|
-
return { status: 200, contentType, body:
|
|
47857
|
+
return { status: 200, contentType, body: readFileSync23(real) };
|
|
47728
47858
|
} catch {
|
|
47729
47859
|
return { status: 404 };
|
|
47730
47860
|
}
|
|
@@ -47744,7 +47874,7 @@ var init_local_image = __esm({
|
|
|
47744
47874
|
});
|
|
47745
47875
|
|
|
47746
47876
|
// packages/server/src/project-icon.ts
|
|
47747
|
-
import { readFileSync as
|
|
47877
|
+
import { readFileSync as readFileSync24, readdirSync as readdirSync10, realpathSync as realpathSync10, statSync as statSync19 } from "node:fs";
|
|
47748
47878
|
import { homedir as homedir17 } from "node:os";
|
|
47749
47879
|
import { basename as basename10, dirname as dirname15, extname as extname3, join as join34, relative, sep as sep2 } from "node:path";
|
|
47750
47880
|
function normalizeStem(stem) {
|
|
@@ -47806,7 +47936,7 @@ function iconDirectories(root) {
|
|
|
47806
47936
|
function manifestIcons(manifestPath) {
|
|
47807
47937
|
let parsed;
|
|
47808
47938
|
try {
|
|
47809
|
-
parsed = JSON.parse(
|
|
47939
|
+
parsed = JSON.parse(readFileSync24(manifestPath, "utf8"));
|
|
47810
47940
|
} catch {
|
|
47811
47941
|
return [];
|
|
47812
47942
|
}
|
|
@@ -47907,7 +48037,7 @@ function resolveProjectIconResponse(id, options = {}) {
|
|
|
47907
48037
|
});
|
|
47908
48038
|
if (!roots.some((root) => real === root || real.startsWith(root + sep2))) return { status: 404 };
|
|
47909
48039
|
try {
|
|
47910
|
-
return { status: 200, contentType, body:
|
|
48040
|
+
return { status: 200, contentType, body: readFileSync24(real) };
|
|
47911
48041
|
} catch {
|
|
47912
48042
|
return { status: 404 };
|
|
47913
48043
|
}
|
|
@@ -48019,7 +48149,7 @@ var init_project_icon = __esm({
|
|
|
48019
48149
|
});
|
|
48020
48150
|
|
|
48021
48151
|
// packages/server/src/local-visualization.ts
|
|
48022
|
-
import { readdirSync as readdirSync11, readFileSync as
|
|
48152
|
+
import { readdirSync as readdirSync11, readFileSync as readFileSync25, realpathSync as realpathSync11, statSync as statSync20 } from "node:fs";
|
|
48023
48153
|
import { join as join35, sep as sep3 } from "node:path";
|
|
48024
48154
|
function children(path, pattern) {
|
|
48025
48155
|
try {
|
|
@@ -48134,7 +48264,7 @@ function resolveLocalVisualization(projectDir, sessionId, file) {
|
|
|
48134
48264
|
try {
|
|
48135
48265
|
const size = statSync20(path).size;
|
|
48136
48266
|
if (size > MAX_FRAGMENT_BYTES) return { status: 413 };
|
|
48137
|
-
fragment =
|
|
48267
|
+
fragment = readFileSync25(path, "utf8");
|
|
48138
48268
|
} catch {
|
|
48139
48269
|
return { status: 404 };
|
|
48140
48270
|
}
|
|
@@ -49523,7 +49653,7 @@ var init_app_socket = __esm({
|
|
|
49523
49653
|
});
|
|
49524
49654
|
|
|
49525
49655
|
// packages/server/src/boot-progress.ts
|
|
49526
|
-
import { mkdirSync as mkdirSync18, readFileSync as
|
|
49656
|
+
import { mkdirSync as mkdirSync18, readFileSync as readFileSync26, renameSync as renameSync10, rmSync as rmSync10, writeFileSync as writeFileSync15 } from "node:fs";
|
|
49527
49657
|
import { basename as basename11, dirname as dirname16, join as join37 } from "node:path";
|
|
49528
49658
|
function bootProgressPath(stateDir) {
|
|
49529
49659
|
return join37(stateDir, BOOT_PROGRESS_NAME);
|
|
@@ -49664,11 +49794,11 @@ __export(index_exports, {
|
|
|
49664
49794
|
unknownProjectPage: () => unknownProjectPage
|
|
49665
49795
|
});
|
|
49666
49796
|
import { createServer } from "node:http";
|
|
49667
|
-
import { readFileSync as
|
|
49797
|
+
import { readFileSync as readFileSync27, existsSync as existsSync15 } from "node:fs";
|
|
49668
49798
|
import { dirname as dirname17, join as join38, resolve as resolve9, extname as extname4, normalize } from "node:path";
|
|
49669
49799
|
function readServerAddressHolder(path) {
|
|
49670
49800
|
try {
|
|
49671
|
-
const value = JSON.parse(
|
|
49801
|
+
const value = JSON.parse(readFileSync27(path, "utf8"));
|
|
49672
49802
|
if (typeof value?.pid !== "number") return void 0;
|
|
49673
49803
|
return { pid: value.pid, port: typeof value.port === "number" ? value.port : -1 };
|
|
49674
49804
|
} catch {
|
|
@@ -49772,7 +49902,7 @@ function serveStatic(distDir, req, res) {
|
|
|
49772
49902
|
if (!file.startsWith(distDir)) file = join38(distDir, "index.html");
|
|
49773
49903
|
if (!existsSync15(file)) file = join38(distDir, "index.html");
|
|
49774
49904
|
try {
|
|
49775
|
-
const body =
|
|
49905
|
+
const body = readFileSync27(file);
|
|
49776
49906
|
res.writeHead(200, { "content-type": MIME[extname4(file)] ?? "application/octet-stream" });
|
|
49777
49907
|
res.end(body);
|
|
49778
49908
|
} catch {
|
|
@@ -50195,7 +50325,7 @@ async function startServer(opts = {}) {
|
|
|
50195
50325
|
if (vite) {
|
|
50196
50326
|
vite.middlewares(req, res, () => {
|
|
50197
50327
|
try {
|
|
50198
|
-
const html =
|
|
50328
|
+
const html = readFileSync27(join38(webRoot, "index.html"), "utf8");
|
|
50199
50329
|
void vite.transformIndexHtml(url, html).then((out) => {
|
|
50200
50330
|
res.writeHead(200, { "content-type": "text/html" });
|
|
50201
50331
|
res.end(out);
|