frizz 0.7.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.
Files changed (92) hide show
  1. package/README.md +1 -1
  2. package/dist/codex-app-server-daemon.js +12 -3
  3. package/dist/dev-child.js +147 -52
  4. package/dist/frizz.js +12 -1
  5. package/package.json +2 -2
  6. package/web-dist/assets/{TerminalPane-DW91LtY6.js → TerminalPane-DBmtdVkV.js} +1 -1
  7. package/web-dist/assets/{abnfDiagram-VRR7QNED-Cz9pKsnx.js → abnfDiagram-VRR7QNED-s9x3PTMx.js} +1 -1
  8. package/web-dist/assets/architecture-TIHT7OUA-Eb73yePg.js +1 -0
  9. package/web-dist/assets/{architectureDiagram-ZJ3FMSHR-Cx1Inab9.js → architectureDiagram-ZJ3FMSHR-CIFfgliT.js} +1 -1
  10. package/web-dist/assets/{blockDiagram-677ZJIJ3-Dkow3KWq.js → blockDiagram-677ZJIJ3-BC-TeFao.js} +1 -1
  11. package/web-dist/assets/{c4Diagram-LMCZKHZV-D54f0v8B.js → c4Diagram-LMCZKHZV-DoJ_Bulk.js} +1 -1
  12. package/web-dist/assets/channel-CgSC9ikg.js +1 -0
  13. package/web-dist/assets/{chunk-32BRIVSS-5HfLNqOq.js → chunk-32BRIVSS-BgchlScG.js} +1 -1
  14. package/web-dist/assets/{chunk-52WLFC77-CoVH-jjk.js → chunk-52WLFC77-D94nMfY5.js} +1 -1
  15. package/web-dist/assets/{chunk-C7G6YPKG-w41h00On.js → chunk-C7G6YPKG-BNU4g2Rm.js} +1 -1
  16. package/web-dist/assets/{chunk-EX3LRPZG-BC_Frphy.js → chunk-EX3LRPZG-DooNeZ0v.js} +1 -1
  17. package/web-dist/assets/{chunk-FWX5IMBZ-DLZVUhWr.js → chunk-FWX5IMBZ-DuXYfpte.js} +2 -2
  18. package/web-dist/assets/{chunk-HOUHSVGY-DCl7dozs.js → chunk-HOUHSVGY-DDtc0Lod.js} +1 -1
  19. package/web-dist/assets/{chunk-ICXQ74PX-I8bc3hpu.js → chunk-ICXQ74PX-D1soMHlW.js} +1 -1
  20. package/web-dist/assets/{chunk-MOJQB5TN-D1tbS5-A.js → chunk-MOJQB5TN-BYZZoPrO.js} +1 -1
  21. package/web-dist/assets/{chunk-OGEWGWER-CLa17J5_.js → chunk-OGEWGWER-CSI1op21.js} +1 -1
  22. package/web-dist/assets/{chunk-PUDLZKDR-DcYIQuxf.js → chunk-PUDLZKDR-B2_qeHID.js} +1 -1
  23. package/web-dist/assets/{chunk-Q4XR5HBZ-DGHqsWli.js → chunk-Q4XR5HBZ-BNiafbsU.js} +1 -1
  24. package/web-dist/assets/{chunk-V7JOEXUC-DdVYI4tg.js → chunk-V7JOEXUC-D9aOhGjB.js} +1 -1
  25. package/web-dist/assets/{chunk-VAUOI2AC-Dn_uoDoN.js → chunk-VAUOI2AC-mt04_MVl.js} +1 -1
  26. package/web-dist/assets/{chunk-VR4S4FIN-AM_J_EWt.js → chunk-VR4S4FIN-CTbhzN9l.js} +1 -1
  27. package/web-dist/assets/{chunk-WYO6CB5R-BldKUlC0.js → chunk-WYO6CB5R-t-QJiLir.js} +1 -1
  28. package/web-dist/assets/{chunk-ZGVPDNZ5-Oh85mcuX.js → chunk-ZGVPDNZ5-BNBiwqoz.js} +1 -1
  29. package/web-dist/assets/classDiagram-OUVF2IWQ-DrMJp1ua.js +1 -0
  30. package/web-dist/assets/classDiagram-v2-EOCWNBFH-DrMJp1ua.js +1 -0
  31. package/web-dist/assets/{cynefin-VYW2F7L2-5lF8kTLT.js → cynefin-VYW2F7L2-CJzDWQw9.js} +1 -1
  32. package/web-dist/assets/{cynefinDiagram-TSTJHNR4-_otwu953.js → cynefinDiagram-TSTJHNR4-C_wWdWpO.js} +1 -1
  33. package/web-dist/assets/{dagre-VKFMJZFB-DxX5d4Jp.js → dagre-VKFMJZFB-JcoSMott.js} +1 -1
  34. package/web-dist/assets/{diagram-FQU43EPY-JkCl7NEC.js → diagram-FQU43EPY-DwPIrxvI.js} +1 -1
  35. package/web-dist/assets/{diagram-G47NLZAW-ETwnVi8G.js → diagram-G47NLZAW-Bs1Iyjn4.js} +1 -1
  36. package/web-dist/assets/{diagram-NH7WQ7WH-DZXKHMOv.js → diagram-NH7WQ7WH-DFXMkDQZ.js} +1 -1
  37. package/web-dist/assets/{diagram-OA4YK3LP--Yt9Hbcy.js → diagram-OA4YK3LP-BdeEougN.js} +1 -1
  38. package/web-dist/assets/{diagram-WEI45ONY-BXUskT8t.js → diagram-WEI45ONY-DOeCVBYO.js} +1 -1
  39. package/web-dist/assets/{ebnfDiagram-CCIWWBDH-C7E1X1Dl.js → ebnfDiagram-CCIWWBDH-Dm5CrqN3.js} +1 -1
  40. package/web-dist/assets/{erDiagram-Q63AITRT-DOfGp1t7.js → erDiagram-Q63AITRT-B0ud7ncc.js} +1 -1
  41. package/web-dist/assets/eventmodeling-45OFAUF4-B52bjxMe.js +1 -0
  42. package/web-dist/assets/flowDiagram-23GEKE2U-DbFccp_w.js +1 -0
  43. package/web-dist/assets/{ganttDiagram-NO4QXBWP-P5HZV3uF.js → ganttDiagram-NO4QXBWP-BdowNjAm.js} +1 -1
  44. package/web-dist/assets/{gitGraph-TEB2WS4Q-CsJYjOme.js → gitGraph-TEB2WS4Q-BSDXrBNB.js} +1 -1
  45. package/web-dist/assets/{gitGraphDiagram-IHSO6WYX-BNyrduBc.js → gitGraphDiagram-IHSO6WYX-B3i3egZt.js} +1 -1
  46. package/web-dist/assets/{index-CYVVF_ZU.js → index-BUX0IseR.js} +102 -102
  47. package/web-dist/assets/{info-DKCQHKI2-WzpT_dbU.js → info-DKCQHKI2-B7CT3rc8.js} +1 -1
  48. package/web-dist/assets/{infoDiagram-FWYZ7A6U-CA_SxvAY.js → infoDiagram-FWYZ7A6U-Bqmpgcu2.js} +1 -1
  49. package/web-dist/assets/{ishikawaDiagram-FXEZZL3T-DXMy0GH9.js → ishikawaDiagram-FXEZZL3T-Bd5LBQOn.js} +1 -1
  50. package/web-dist/assets/{journeyDiagram-5HDEW3XC-Bwmn4bNv.js → journeyDiagram-5HDEW3XC-lJOF3I7X.js} +1 -1
  51. package/web-dist/assets/{kanban-definition-HUTT4EX6-D265Z0Fg.js → kanban-definition-HUTT4EX6-D4E5PRAv.js} +1 -1
  52. package/web-dist/assets/{line-DNn_Towe.js → line-C9ZcrRyz.js} +1 -1
  53. package/web-dist/assets/{mermaid-parser.core-3CrMhKoT.js → mermaid-parser.core-DkaL73Gv.js} +3 -3
  54. package/web-dist/assets/{mermaid.core-DfCFu8_x.js → mermaid.core-BQ89ySVU.js} +3 -3
  55. package/web-dist/assets/{mindmap-definition-LN4V7U3C-CQ5g8Qrh.js → mindmap-definition-LN4V7U3C-CB7JnCHh.js} +1 -1
  56. package/web-dist/assets/{packet-7NZHBO7P-CRDQ5t5W.js → packet-7NZHBO7P-BvyvpOhm.js} +1 -1
  57. package/web-dist/assets/{pegDiagram-2B236MQR-B0XFyb7d.js → pegDiagram-2B236MQR-BoygVhix.js} +1 -1
  58. package/web-dist/assets/{pie-RZYD4A2V-DqjiBFGO.js → pie-RZYD4A2V-ChTjZLeC.js} +1 -1
  59. package/web-dist/assets/{pieDiagram-ENE6RG2P-C41GJ3-U.js → pieDiagram-ENE6RG2P-B3UNPTpF.js} +1 -1
  60. package/web-dist/assets/{quadrantDiagram-ABIIQ3AL-9cF0WJaM.js → quadrantDiagram-ABIIQ3AL-DJdWJ4GS.js} +1 -1
  61. package/web-dist/assets/{radar-I7S5WNFK-S1F7Z4Kj.js → radar-I7S5WNFK-DHi5ReAY.js} +1 -1
  62. package/web-dist/assets/{railroad-3IZDKUUU-da9Pjcp1.js → railroad-3IZDKUUU-DcLJuGRW.js} +1 -1
  63. package/web-dist/assets/railroad-abnf-AHOZXSZD-BJcLzkwL.js +1 -0
  64. package/web-dist/assets/railroad-ebnf-EBAXGLYW-B4jrlWYB.js +1 -0
  65. package/web-dist/assets/railroad-peg-LSFZ7HO6-BpIzbo9k.js +1 -0
  66. package/web-dist/assets/{railroadDiagram-RFXS5EU6-CkXBDByE.js → railroadDiagram-RFXS5EU6-W4vnMFZ2.js} +1 -1
  67. package/web-dist/assets/{requirementDiagram-TGXJPOKE-CL9Famg0.js → requirementDiagram-TGXJPOKE-CV_V-9DW.js} +1 -1
  68. package/web-dist/assets/{sankeyDiagram-HTMAVEWB-LyB-A0pD.js → sankeyDiagram-HTMAVEWB-DuIIsNBv.js} +1 -1
  69. package/web-dist/assets/{sequenceDiagram-DBY2YBRQ-DXfA9UDM.js → sequenceDiagram-DBY2YBRQ-DTT8ETnv.js} +1 -1
  70. package/web-dist/assets/{stateDiagram-2N3HPSRC-DgxMkPRv.js → stateDiagram-2N3HPSRC-HVZaDROf.js} +1 -1
  71. package/web-dist/assets/stateDiagram-v2-6OUMAXLB-DF9q3s7U.js +1 -0
  72. package/web-dist/assets/{swimlanes-5IMT3BWC-TvRb3Iib.js → swimlanes-5IMT3BWC-DpGdPqRB.js} +1 -1
  73. package/web-dist/assets/swimlanesDiagram-G3AALYLV-BNeW4PCd.js +8 -0
  74. package/web-dist/assets/{timeline-definition-FHXFAJF6-BBvC3bzZ.js → timeline-definition-FHXFAJF6-D9u3mgpd.js} +1 -1
  75. package/web-dist/assets/{treeView-QDETBFTQ-CvCYIkJk.js → treeView-QDETBFTQ-Dga6MhEJ.js} +1 -1
  76. package/web-dist/assets/{treemap-6X3UGDF4-Bj60PrS0.js → treemap-6X3UGDF4-BwEXmcD6.js} +1 -1
  77. package/web-dist/assets/{vennDiagram-L72KCM5P-CLuLJiNi.js → vennDiagram-L72KCM5P-BMvodYUW.js} +1 -1
  78. package/web-dist/assets/{wardley-OPB4EBWU-C4tNB2Mi.js → wardley-OPB4EBWU-BzB6QK8X.js} +1 -1
  79. package/web-dist/assets/{wardleyDiagram-EHGQE667-D_bno6Pc.js → wardleyDiagram-EHGQE667-4ID7QRJi.js} +1 -1
  80. package/web-dist/assets/{xychartDiagram-FW5EYKEG-CklFVNTA.js → xychartDiagram-FW5EYKEG-Ckob9hhW.js} +1 -1
  81. package/web-dist/index.html +1 -1
  82. package/web-dist/assets/architecture-TIHT7OUA-pEHgxrgQ.js +0 -1
  83. package/web-dist/assets/channel-DmtoXjBB.js +0 -1
  84. package/web-dist/assets/classDiagram-OUVF2IWQ-CUGsPtaX.js +0 -1
  85. package/web-dist/assets/classDiagram-v2-EOCWNBFH-CUGsPtaX.js +0 -1
  86. package/web-dist/assets/eventmodeling-45OFAUF4-D47al60X.js +0 -1
  87. package/web-dist/assets/flowDiagram-23GEKE2U-Cfew-ywI.js +0 -1
  88. package/web-dist/assets/railroad-abnf-AHOZXSZD-cPb8e4yf.js +0 -1
  89. package/web-dist/assets/railroad-ebnf-EBAXGLYW-BdArTI_P.js +0 -1
  90. package/web-dist/assets/railroad-peg-LSFZ7HO6-cRtFMlRA.js +0 -1
  91. package/web-dist/assets/stateDiagram-v2-6OUMAXLB-BVl1T6pD.js +0 -1
  92. package/web-dist/assets/swimlanesDiagram-G3AALYLV-CaBRomjp.js +0 -8
package/README.md CHANGED
@@ -292,7 +292,7 @@ $ node scripts/sync-portable-monitors.mjs --check
292
292
  $ node --test monitors/*.test.mjs
293
293
  ```
294
294
 
295
- Everything else runs locally. Install with `pnpm install`, typecheck with `pnpm typecheck`, and run the full suite with `pnpm test` — that suite drives real agent CLIs and a real browser, which is why CI does not gate on it. Say in the PR what you ran.
295
+ Everything else runs locally. Install with `pnpm install`, typecheck with `pnpm typecheck`, and run the full suite with `pnpm test` — that suite drives real agent CLIs and a real browser, which is why CI does not gate on it. Say in the PR what you ran. The suite needs a newer Node than the runtime does: early 22.x point releases (22.15 measured) fail `receipt-bus.test.ts` on a since-fixed test-runner defect, so run it on current 22.x or ≥ 23.4.
296
296
 
297
297
  <br/>
298
298
 
@@ -12,13 +12,22 @@ import { execFile } from "node:child_process";
12
12
  import { readdirSync, unlinkSync } from "node:fs";
13
13
  import { connect as connectSocket } from "node:net";
14
14
  import { join } from "node:path";
15
+ function parseLsofSocketNames(stdout) {
16
+ const referenced = /* @__PURE__ */ new Set();
17
+ for (const line of stdout.split("\n")) {
18
+ if (!line.startsWith("n/")) continue;
19
+ const raw = line.slice(1);
20
+ referenced.add(raw);
21
+ const meta = raw.indexOf(" type=");
22
+ if (meta > 0) referenced.add(raw.slice(0, meta));
23
+ }
24
+ return referenced;
25
+ }
15
26
  var defaultListReferenced = (prefix, done) => {
16
27
  execFile("lsof", ["-U", "-F", "n"], { timeout: 3e4, maxBuffer: 16 * 1024 * 1024 }, (error, stdout) => {
17
28
  if (!stdout) return done(null);
18
29
  if (error && !stdout.includes(prefix)) return done(null);
19
- const referenced = /* @__PURE__ */ new Set();
20
- for (const line of stdout.split("\n")) if (line.startsWith("n/")) referenced.add(line.slice(1));
21
- done(referenced);
30
+ done(parseLsofSocketNames(stdout));
22
31
  }).unref?.();
23
32
  };
24
33
  var defaultProbe = (path, verdict) => {
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();
@@ -20916,6 +20927,21 @@ function retireOutstandingDeliveries(storage, slug) {
20916
20927
  storage.setDeliveryLedger(slug, serializeDeliveryLedger(next));
20917
20928
  return items.length - next.length;
20918
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
+ }
20919
20945
  function deliveryItem(storage, slug, id) {
20920
20946
  const row = storage.getSession(slug);
20921
20947
  if (!row) return null;
@@ -38480,6 +38506,17 @@ import { execFile as execFile7 } from "node:child_process";
38480
38506
  import { readdirSync as readdirSync8, unlinkSync as unlinkSync4 } from "node:fs";
38481
38507
  import { connect as connectSocket } from "node:net";
38482
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
+ }
38483
38520
  function sweepStaleSockets(options, deps = {}) {
38484
38521
  if (process.platform === "win32") return;
38485
38522
  const keep = new Set(options.keep ?? []);
@@ -38515,9 +38552,7 @@ var init_stale_socket_sweep = __esm({
38515
38552
  execFile7("lsof", ["-U", "-F", "n"], { timeout: 3e4, maxBuffer: 16 * 1024 * 1024 }, (error, stdout) => {
38516
38553
  if (!stdout) return done(null);
38517
38554
  if (error && !stdout.includes(prefix)) return done(null);
38518
- const referenced = /* @__PURE__ */ new Set();
38519
- for (const line of stdout.split("\n")) if (line.startsWith("n/")) referenced.add(line.slice(1));
38520
- done(referenced);
38555
+ done(parseLsofSocketNames(stdout));
38521
38556
  }).unref?.();
38522
38557
  };
38523
38558
  defaultProbe = (path, verdict) => {
@@ -38537,6 +38572,7 @@ var init_stale_socket_sweep = __esm({
38537
38572
 
38538
38573
  // packages/server/src/orphan-reaper.ts
38539
38574
  import { execFileSync as execFileSync5 } from "node:child_process";
38575
+ import { readFileSync as readFileSync17 } from "node:fs";
38540
38576
  import { dirname as dirname12 } from "node:path";
38541
38577
  function firstTokenBasename(command) {
38542
38578
  const first = command.trimStart().split(/\s+/, 1)[0] ?? "";
@@ -38636,8 +38672,8 @@ function parseEtimeMs(etime) {
38636
38672
  else return 0;
38637
38673
  return (((days * 24 + h) * 60 + m) * 60 + s) * 1e3;
38638
38674
  }
38639
- function enumerateProcs(exec = defaultExec) {
38640
- const base = exec("ps", ["-axww", "-o", "pid=,ppid=,etime=,command="]);
38675
+ function enumerateProcs(exec = defaultExec, opts = {}) {
38676
+ const base = exec("ps", ["-Aww", "-o", "pid=,ppid=,etime=,command="]);
38641
38677
  const rows = [];
38642
38678
  const byPid = /* @__PURE__ */ new Map();
38643
38679
  const pids = [];
@@ -38653,6 +38689,21 @@ function enumerateProcs(exec = defaultExec) {
38653
38689
  pids.push(pid);
38654
38690
  }
38655
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
+ }
38656
38707
  let text;
38657
38708
  try {
38658
38709
  text = exec("ps", ["-Eww", "-o", "pid=,command=", "-p", pids.join(",")]);
@@ -38728,7 +38779,7 @@ function sweepOrphansOnce(deps = {}) {
38728
38779
  const minAgeMs = deps.minAgeMs ?? ORPHAN_MIN_AGE_MS;
38729
38780
  let rows;
38730
38781
  try {
38731
- rows = enumerateProcs(exec);
38782
+ rows = enumerateProcs(exec, { platform: deps.platform, readEnv: deps.readEnv });
38732
38783
  } catch {
38733
38784
  return { reaped: 0, deadSlugs: [], liveSlugs: [] };
38734
38785
  }
@@ -38776,7 +38827,7 @@ function startOrphanReaper(deps = {}) {
38776
38827
  clearInterval(socketTimer);
38777
38828
  };
38778
38829
  }
38779
- 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;
38780
38831
  var init_orphan_reaper = __esm({
38781
38832
  "packages/server/src/orphan-reaper.ts"() {
38782
38833
  "use strict";
@@ -38786,6 +38837,13 @@ var init_orphan_reaper = __esm({
38786
38837
  ORPHAN_MIN_AGE_MS = 12e4;
38787
38838
  SLUG_RE = /FRIZZ_THREAD=([A-Za-z0-9._-]+)/;
38788
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
+ };
38789
38847
  defaultKill = (pid) => {
38790
38848
  try {
38791
38849
  process.kill(pid, "SIGKILL");
@@ -42113,7 +42171,7 @@ var init_server = __esm({
42113
42171
  });
42114
42172
 
42115
42173
  // packages/server/src/repair.ts
42116
- import { existsSync as existsSync12, readFileSync as readFileSync17, writeFileSync as writeFileSync11 } from "node:fs";
42174
+ import { existsSync as existsSync12, readFileSync as readFileSync18, writeFileSync as writeFileSync11 } from "node:fs";
42117
42175
  import { basename as basename7, dirname as dirname13, resolve as resolve6 } from "node:path";
42118
42176
  function quoteValue(v) {
42119
42177
  if (/^[\w./#:+-]+$/.test(v)) return v;
@@ -42129,7 +42187,7 @@ function repairThreadFile(frizzDir, file) {
42129
42187
  if (dirname13(abs) !== root) throw new RepairError(`refusing to repair "${file}": not directly under .frizz/`);
42130
42188
  if (!abs.endsWith(".md")) throw new RepairError(`refusing to repair "${file}": not a .md thread file`);
42131
42189
  if (!existsSync12(abs)) throw new RepairError(`no thread file to repair: ${basename7(abs)}`);
42132
- const content = readFileSync17(abs, "utf8");
42190
+ const content = readFileSync18(abs, "utf8");
42133
42191
  const firstLine2 = content.replace(/^/, "").split(/\r?\n/).find((l) => l.trim() !== "");
42134
42192
  if (firstLine2?.trim() === "---") {
42135
42193
  throw new RepairError(`${basename7(abs)} already opens with a "---" block \u2014 repair only heals a MISSING frontmatter block`);
@@ -42162,7 +42220,7 @@ var init_repair = __esm({
42162
42220
  });
42163
42221
 
42164
42222
  // cc-worker/hooks/bash-background.mjs
42165
- import { readFileSync as readFileSync18 } from "node:fs";
42223
+ import { readFileSync as readFileSync19 } from "node:fs";
42166
42224
  import { basename as basename8 } from "node:path";
42167
42225
  import { pathToFileURL } from "node:url";
42168
42226
  function emit(obj) {
@@ -42311,7 +42369,7 @@ var init_bash_background = __esm({
42311
42369
  if (isDirectHookExecution(process.argv[1], import.meta.url)) {
42312
42370
  try {
42313
42371
  const env = process.argv.includes("--frizz-thread") ? { ...process.env, FRIZZ_THREAD: process.env.FRIZZ_THREAD || "codex-worker" } : process.env;
42314
- emit(evaluateBashBackgroundHook(JSON.parse(readFileSync18(0, "utf8")), env));
42372
+ emit(evaluateBashBackgroundHook(JSON.parse(readFileSync19(0, "utf8")), env));
42315
42373
  } catch {
42316
42374
  emit({});
42317
42375
  }
@@ -42320,7 +42378,7 @@ var init_bash_background = __esm({
42320
42378
  });
42321
42379
 
42322
42380
  // packages/server/src/transcript.ts
42323
- import { closeSync as closeSync13, existsSync as existsSync13, fstatSync as fstatSync3, mkdirSync as mkdirSync15, openSync as openSync14, readdirSync as readdirSync9, readFileSync as readFileSync19, readSync as readSync7, renameSync as renameSync9, statSync as statSync14, unlinkSync as unlinkSync5, writeFileSync as writeFileSync12 } from "node:fs";
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";
42324
42382
  import { createHash as createHash13 } from "node:crypto";
42325
42383
  import { StringDecoder as StringDecoder4 } from "node:string_decoder";
42326
42384
  import { join as join31 } from "node:path";
@@ -42428,17 +42486,28 @@ function pushToolPart(m, call) {
42428
42486
  else m.parts.push({ kind: "tools", tools: [call] });
42429
42487
  }
42430
42488
  function coalescedQueuedKeys(deliveredText, pendingKeys) {
42431
- const consumed = [];
42432
- let cursor = 0;
42433
- for (const key of pendingKeys) {
42434
- if (!deliveredText.startsWith(key, cursor)) break;
42435
- cursor += key.length;
42436
- consumed.push(key);
42437
- if (cursor === deliveredText.length) return consumed;
42438
- if (!deliveredText.startsWith("\n", cursor)) break;
42439
- cursor += 1;
42440
- }
42441
- return cursor === deliveredText.length && consumed.length > 0 ? consumed : [];
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) ?? [];
42442
42511
  }
42443
42512
  function commandEnvelopeQueuedKey(deliveredText) {
42444
42513
  const name = COMMAND_NAME_RE.exec(deliveredText)?.[1]?.trim();
@@ -42925,7 +42994,7 @@ function persistSentFile(srcPath, idKey) {
42925
42994
  if (existsSync13(dest)) return dest;
42926
42995
  const size = statSync14(srcPath).size;
42927
42996
  if (size === 0 || size > SENT_IMAGE_MAX_BYTES) return void 0;
42928
- const buf = readFileSync19(srcPath);
42997
+ const buf = readFileSync20(srcPath);
42929
42998
  if (!looksLikeImage(buf, outExt)) return void 0;
42930
42999
  mkdirSync15(SCREENSHOT_CACHE_DIR, { recursive: true });
42931
43000
  const tmp = join31(SCREENSHOT_CACHE_DIR, `.${name}.${process.pid}.${screenshotTmpSeq++}.tmp`);
@@ -43345,7 +43414,7 @@ function readTranscript(project, sessionId) {
43345
43414
  }
43346
43415
  function verifyIncrementalParse(path, identityPrefix, incremental) {
43347
43416
  try {
43348
- const fresh = parseTranscript(readFileSync19(path, "utf8"), identityPrefix);
43417
+ const fresh = parseTranscript(readFileSync20(path, "utf8"), identityPrefix);
43349
43418
  const a = JSON.stringify(incremental);
43350
43419
  const b = JSON.stringify(fresh);
43351
43420
  if (a !== b) {
@@ -44577,7 +44646,7 @@ function readEarlierThreadTranscriptPage(project, storage, slug, cursor, backend
44577
44646
  }
44578
44647
  function readCodexTranscriptFile(absPath, nativeId = absPath) {
44579
44648
  try {
44580
- return parseCodexTranscript(readFileSync19(absPath, "utf8"), `codex:${nativeId}`);
44649
+ return parseCodexTranscript(readFileSync20(absPath, "utf8"), `codex:${nativeId}`);
44581
44650
  } catch {
44582
44651
  return [];
44583
44652
  }
@@ -44671,7 +44740,7 @@ function projectTranscriptPageAgentLifecycles(page, lookup, peerLookup) {
44671
44740
  function readTranscriptFile(absPath) {
44672
44741
  try {
44673
44742
  const pathKey = createHash13("sha256").update(absPath).digest("base64url").slice(0, 16);
44674
- return parseTranscript(readFileSync19(absPath, "utf8"), `claude-file:${pathKey}`);
44743
+ return parseTranscript(readFileSync20(absPath, "utf8"), `claude-file:${pathKey}`);
44675
44744
  } catch {
44676
44745
  return [];
44677
44746
  }
@@ -44768,7 +44837,7 @@ var init_open_external = __esm({
44768
44837
 
44769
44838
  // packages/server/src/local-file.ts
44770
44839
  import { spawn as spawn6 } from "node:child_process";
44771
- import { readFileSync as readFileSync20, realpathSync as realpathSync8, statSync as statSync15 } from "node:fs";
44840
+ import { readFileSync as readFileSync21, realpathSync as realpathSync8, statSync as statSync15 } from "node:fs";
44772
44841
  import { homedir as homedir15 } from "node:os";
44773
44842
  import { isAbsolute as isAbsolute3, join as join32, resolve as resolve7, sep } from "node:path";
44774
44843
  function isUnder(real, root) {
@@ -44811,7 +44880,7 @@ function readLocalMarkdown(rawPath, roots) {
44811
44880
  if (!MARKDOWN_FILE_EXT.test(rawPath.trim())) throw new Error("Local file is not a Markdown file");
44812
44881
  const path = resolveLocalFile(rawPath, roots);
44813
44882
  if (!MARKDOWN_FILE_EXT.test(path)) throw new Error("Local file is not a Markdown file");
44814
- const bytes = readFileSync20(path);
44883
+ const bytes = readFileSync21(path);
44815
44884
  if (bytes.length <= MARKDOWN_READ_LIMIT) return { path, markdown: bytes.toString("utf8"), truncated: false };
44816
44885
  const head = bytes.subarray(0, MARKDOWN_READ_LIMIT);
44817
44886
  const lastBreak = head.lastIndexOf(10);
@@ -45257,6 +45326,17 @@ function readBackgroundShellOutput(path, maxBytes = OUTPUT_TAIL_BYTES) {
45257
45326
  if (fd !== void 0) closeSync14(fd);
45258
45327
  }
45259
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
+ }
45260
45340
  function backgroundShellLineCount(path) {
45261
45341
  let fd;
45262
45342
  try {
@@ -45264,9 +45344,21 @@ function backgroundShellLineCount(path) {
45264
45344
  const stat2 = fstatSync4(fd);
45265
45345
  const size = stat2.size;
45266
45346
  let state = scans.get(path);
45267
- 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;
45268
45349
  if (state?.overflowed) return void 0;
45269
- if (!state) state = { ino: stat2.ino, bytes: 0, breaks: 0, pendingCR: false, trailing: false, overflowed: false };
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
+ }
45270
45362
  if (size - state.bytes > SCAN_CEILING_BYTES) {
45271
45363
  scans.set(path, { ...state, overflowed: true });
45272
45364
  return void 0;
@@ -45302,7 +45394,7 @@ function backgroundShellLineCount(path) {
45302
45394
  if (fd !== void 0) closeSync14(fd);
45303
45395
  }
45304
45396
  }
45305
- 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;
45306
45398
  var init_background_shell_output = __esm({
45307
45399
  "packages/server/src/background-shell-output.ts"() {
45308
45400
  "use strict";
@@ -45310,6 +45402,7 @@ var init_background_shell_output = __esm({
45310
45402
  SCAN_CHUNK_BYTES = 256 * 1024;
45311
45403
  SCAN_CEILING_BYTES = 128 * 1024 * 1024;
45312
45404
  SCAN_CACHE_LIMIT = 512;
45405
+ FINGERPRINT_BYTES = 64;
45313
45406
  ANSI_ESCAPE_RE = /\x1b(?:\][^\x07]*(?:\x07|\x1b\\)|\[[0-?]*[ -/]*[@-~])/g;
45314
45407
  scans = /* @__PURE__ */ new Map();
45315
45408
  }
@@ -45318,7 +45411,7 @@ var init_background_shell_output = __esm({
45318
45411
  // packages/server/src/image-header.ts
45319
45412
  import { closeSync as closeSync15, openSync as openSync16, readSync as readSync9, statSync as statSync16 } from "node:fs";
45320
45413
  import { extname } from "node:path";
45321
- function readHead2(path, budget) {
45414
+ function readHead3(path, budget) {
45322
45415
  let fd;
45323
45416
  try {
45324
45417
  const size = statSync16(path).size;
@@ -45426,7 +45519,7 @@ function svg(head) {
45426
45519
  }
45427
45520
  function svgDeclaresColour(path) {
45428
45521
  if (extname(path).toLowerCase() !== ".svg") return void 0;
45429
- const head = readHead2(path, 512 * 1024);
45522
+ const head = readHead3(path, 512 * 1024);
45430
45523
  if (!head) return void 0;
45431
45524
  const source = head.toString("utf8");
45432
45525
  if (!/<svg\b/iu.test(source)) return void 0;
@@ -45439,7 +45532,7 @@ function svgDeclaresColour(path) {
45439
45532
  function imageDimensions(path) {
45440
45533
  const extension2 = extname(path).toLowerCase();
45441
45534
  const budget = extension2 === ".jpg" || extension2 === ".jpeg" ? JPEG_SCAN_BYTES : HEAD_BYTES2;
45442
- const head = readHead2(path, budget);
45535
+ const head = readHead3(path, budget);
45443
45536
  if (!head) return void 0;
45444
45537
  return png(head) ?? gif(head) ?? webp(head) ?? ico(head) ?? jpeg(head) ?? svg(head);
45445
45538
  }
@@ -45547,7 +45640,7 @@ var init_directory_picker = __esm({
45547
45640
  });
45548
45641
 
45549
45642
  // packages/server/src/router.ts
45550
- import { readFileSync as readFileSync21, statSync as statSync17 } from "node:fs";
45643
+ import { readFileSync as readFileSync22, statSync as statSync17 } from "node:fs";
45551
45644
  import { join as join33, resolve as resolve8 } from "node:path";
45552
45645
  import { randomUUID as randomUUID16 } from "node:crypto";
45553
45646
  import { basename as basename9, dirname as dirname14 } from "node:path";
@@ -45756,7 +45849,7 @@ function storeProjectIcon(id, name, bytes) {
45756
45849
  function setProjectIconFromFile(id, file) {
45757
45850
  let bytes;
45758
45851
  try {
45759
- bytes = readFileSync21(file);
45852
+ bytes = readFileSync22(file);
45760
45853
  } catch {
45761
45854
  throw new Error("That file could not be read.");
45762
45855
  }
@@ -46396,15 +46489,16 @@ ${gapNote}` : input.message;
46396
46489
  )
46397
46490
  });
46398
46491
  if (input.freshProcess) retireOutstandingDeliveries(ctx.storage, input.slug);
46399
- if (input.interrupt) bridge.interruptTurn({ threadSlug: input.slug, sessionId: row.session_id });
46492
+ const preempted = input.interrupt === true && bridge.interruptTurn({ threadSlug: input.slug, sessionId: row.session_id });
46400
46493
  if (input.deliveryId) {
46401
46494
  appendDelivery(ctx.storage, input.slug, {
46402
46495
  id: input.deliveryId,
46403
46496
  text: input.message,
46404
46497
  state: midTurn && input.freshProcess !== true ? "enqueued" : "delivered"
46405
46498
  });
46406
- ctx.transcriptChange.emit([input.slug]);
46407
46499
  }
46500
+ if (preempted) deliverOutstandingDeliveries(ctx.storage, input.slug);
46501
+ if (input.deliveryId || preempted) ctx.transcriptChange.emit([input.slug]);
46408
46502
  ctx.board.refresh();
46409
46503
  return;
46410
46504
  }
@@ -46490,6 +46584,7 @@ ${gapNote}` : input.message;
46490
46584
  if (!bridge.interruptTurn({ threadSlug: input.slug, sessionId: row.session_id })) {
46491
46585
  return { interrupted: false, reason: "Nothing to interrupt \u2014 this thread has no turn running" };
46492
46586
  }
46587
+ if (deliverOutstandingDeliveries(ctx.storage, input.slug)) ctx.transcriptChange.emit([input.slug]);
46493
46588
  return { interrupted: true };
46494
46589
  }
46495
46590
  }),
@@ -47745,7 +47840,7 @@ var init_compression = __esm({
47745
47840
  });
47746
47841
 
47747
47842
  // packages/server/src/local-image.ts
47748
- import { readFileSync as readFileSync22, realpathSync as realpathSync9, statSync as statSync18 } from "node:fs";
47843
+ import { readFileSync as readFileSync23, realpathSync as realpathSync9, statSync as statSync18 } from "node:fs";
47749
47844
  import { extname as extname2, isAbsolute as isAbsolute4 } from "node:path";
47750
47845
  function resolveLocalImage(rawPath) {
47751
47846
  if (!rawPath || !isAbsolute4(rawPath)) return { status: 400 };
@@ -47759,7 +47854,7 @@ function resolveLocalImage(rawPath) {
47759
47854
  }
47760
47855
  try {
47761
47856
  if (!statSync18(real).isFile()) return { status: 404 };
47762
- return { status: 200, contentType, body: readFileSync22(real) };
47857
+ return { status: 200, contentType, body: readFileSync23(real) };
47763
47858
  } catch {
47764
47859
  return { status: 404 };
47765
47860
  }
@@ -47779,7 +47874,7 @@ var init_local_image = __esm({
47779
47874
  });
47780
47875
 
47781
47876
  // packages/server/src/project-icon.ts
47782
- import { readFileSync as readFileSync23, readdirSync as readdirSync10, realpathSync as realpathSync10, statSync as statSync19 } from "node:fs";
47877
+ import { readFileSync as readFileSync24, readdirSync as readdirSync10, realpathSync as realpathSync10, statSync as statSync19 } from "node:fs";
47783
47878
  import { homedir as homedir17 } from "node:os";
47784
47879
  import { basename as basename10, dirname as dirname15, extname as extname3, join as join34, relative, sep as sep2 } from "node:path";
47785
47880
  function normalizeStem(stem) {
@@ -47841,7 +47936,7 @@ function iconDirectories(root) {
47841
47936
  function manifestIcons(manifestPath) {
47842
47937
  let parsed;
47843
47938
  try {
47844
- parsed = JSON.parse(readFileSync23(manifestPath, "utf8"));
47939
+ parsed = JSON.parse(readFileSync24(manifestPath, "utf8"));
47845
47940
  } catch {
47846
47941
  return [];
47847
47942
  }
@@ -47942,7 +48037,7 @@ function resolveProjectIconResponse(id, options = {}) {
47942
48037
  });
47943
48038
  if (!roots.some((root) => real === root || real.startsWith(root + sep2))) return { status: 404 };
47944
48039
  try {
47945
- return { status: 200, contentType, body: readFileSync23(real) };
48040
+ return { status: 200, contentType, body: readFileSync24(real) };
47946
48041
  } catch {
47947
48042
  return { status: 404 };
47948
48043
  }
@@ -48054,7 +48149,7 @@ var init_project_icon = __esm({
48054
48149
  });
48055
48150
 
48056
48151
  // packages/server/src/local-visualization.ts
48057
- import { readdirSync as readdirSync11, readFileSync as readFileSync24, realpathSync as realpathSync11, statSync as statSync20 } from "node:fs";
48152
+ import { readdirSync as readdirSync11, readFileSync as readFileSync25, realpathSync as realpathSync11, statSync as statSync20 } from "node:fs";
48058
48153
  import { join as join35, sep as sep3 } from "node:path";
48059
48154
  function children(path, pattern) {
48060
48155
  try {
@@ -48169,7 +48264,7 @@ function resolveLocalVisualization(projectDir, sessionId, file) {
48169
48264
  try {
48170
48265
  const size = statSync20(path).size;
48171
48266
  if (size > MAX_FRAGMENT_BYTES) return { status: 413 };
48172
- fragment = readFileSync24(path, "utf8");
48267
+ fragment = readFileSync25(path, "utf8");
48173
48268
  } catch {
48174
48269
  return { status: 404 };
48175
48270
  }
@@ -49558,7 +49653,7 @@ var init_app_socket = __esm({
49558
49653
  });
49559
49654
 
49560
49655
  // packages/server/src/boot-progress.ts
49561
- import { mkdirSync as mkdirSync18, readFileSync as readFileSync25, renameSync as renameSync10, rmSync as rmSync10, writeFileSync as writeFileSync15 } from "node:fs";
49656
+ import { mkdirSync as mkdirSync18, readFileSync as readFileSync26, renameSync as renameSync10, rmSync as rmSync10, writeFileSync as writeFileSync15 } from "node:fs";
49562
49657
  import { basename as basename11, dirname as dirname16, join as join37 } from "node:path";
49563
49658
  function bootProgressPath(stateDir) {
49564
49659
  return join37(stateDir, BOOT_PROGRESS_NAME);
@@ -49699,11 +49794,11 @@ __export(index_exports, {
49699
49794
  unknownProjectPage: () => unknownProjectPage
49700
49795
  });
49701
49796
  import { createServer } from "node:http";
49702
- import { readFileSync as readFileSync26, existsSync as existsSync15 } from "node:fs";
49797
+ import { readFileSync as readFileSync27, existsSync as existsSync15 } from "node:fs";
49703
49798
  import { dirname as dirname17, join as join38, resolve as resolve9, extname as extname4, normalize } from "node:path";
49704
49799
  function readServerAddressHolder(path) {
49705
49800
  try {
49706
- const value = JSON.parse(readFileSync26(path, "utf8"));
49801
+ const value = JSON.parse(readFileSync27(path, "utf8"));
49707
49802
  if (typeof value?.pid !== "number") return void 0;
49708
49803
  return { pid: value.pid, port: typeof value.port === "number" ? value.port : -1 };
49709
49804
  } catch {
@@ -49807,7 +49902,7 @@ function serveStatic(distDir, req, res) {
49807
49902
  if (!file.startsWith(distDir)) file = join38(distDir, "index.html");
49808
49903
  if (!existsSync15(file)) file = join38(distDir, "index.html");
49809
49904
  try {
49810
- const body = readFileSync26(file);
49905
+ const body = readFileSync27(file);
49811
49906
  res.writeHead(200, { "content-type": MIME[extname4(file)] ?? "application/octet-stream" });
49812
49907
  res.end(body);
49813
49908
  } catch {
@@ -50230,7 +50325,7 @@ async function startServer(opts = {}) {
50230
50325
  if (vite) {
50231
50326
  vite.middlewares(req, res, () => {
50232
50327
  try {
50233
- const html = readFileSync26(join38(webRoot, "index.html"), "utf8");
50328
+ const html = readFileSync27(join38(webRoot, "index.html"), "utf8");
50234
50329
  void vite.transformIndexHtml(url, html).then((out) => {
50235
50330
  res.writeHead(200, { "content-type": "text/html" });
50236
50331
  res.end(out);
package/dist/frizz.js CHANGED
@@ -860,7 +860,7 @@ function readGitWorktreeProjectId(worktree) {
860
860
  );
861
861
  }
862
862
  function syncGitConfigPath(path) {
863
- const fd = openSync2(path, "r");
863
+ const fd = openSync2(path, process.platform === "win32" ? "r+" : "r");
864
864
  try {
865
865
  fsyncSync(fd);
866
866
  } finally {
@@ -13594,6 +13594,16 @@ var init_interactions = __esm({
13594
13594
  }
13595
13595
  });
13596
13596
 
13597
+ // packages/shared/src/claim.ts
13598
+ var CLAIM_MAX_AGE_MS, CLAIM_LEASE_MS;
13599
+ var init_claim = __esm({
13600
+ "packages/shared/src/claim.ts"() {
13601
+ "use strict";
13602
+ CLAIM_MAX_AGE_MS = 5 * 6e4;
13603
+ CLAIM_LEASE_MS = 30 * 24 * 60 * 6e4;
13604
+ }
13605
+ });
13606
+
13597
13607
  // packages/shared/src/code-fences.ts
13598
13608
  var init_code_fences = __esm({
13599
13609
  "packages/shared/src/code-fences.ts"() {
@@ -13634,6 +13644,7 @@ var init_src = __esm({
13634
13644
  init_zod();
13635
13645
  init_interactions();
13636
13646
  init_thread_slug();
13647
+ init_claim();
13637
13648
  init_code_fences();
13638
13649
  init_delta();
13639
13650
  init_drainable_worker();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "frizz",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "private": false,
5
5
  "description": "A local web UI for running many coding agents at once",
6
6
  "keywords": [
@@ -37,7 +37,7 @@
37
37
  "frizz-dev:check": "nub scripts/install-global-cli.mjs --check",
38
38
  "frizz-dev:uninstall": "nub scripts/install-global-cli.mjs --uninstall",
39
39
  "install:global": "nub scripts/install-global-cli.mjs",
40
- "typecheck": "tsc -b packages/shared packages/rpc packages/server . && pnpm --filter @frizz/web typecheck",
40
+ "typecheck": "tsc -b packages/shared packages/rpc packages/server packages/registrar . && pnpm --filter @frizz/web typecheck",
41
41
  "test": "nub scripts/run-tests.mjs",
42
42
  "test:e2e": "nub scripts/e2e-web.mjs",
43
43
  "prepack": "node ./scripts/prepare-package.mjs && node ./scripts/build-package.mjs && node ./scripts/publish-manifest.mjs --strip",