frizz 0.7.4 → 0.7.7
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 +28 -15
- package/dist/dev-child.js +376 -306
- package/dist/frizz.js +12908 -6474
- package/package.json +5 -3
- package/runtime/cc-worker/DECISIONS.md +11 -0
- package/web-dist/assets/{TerminalPane-Cyao7kTi.js → TerminalPane-Cb8jOFP9.js} +1 -1
- package/web-dist/assets/{abnfDiagram-VRR7QNED-D1U0Q_zY.js → abnfDiagram-VRR7QNED-Dtbg2eZ0.js} +1 -1
- package/web-dist/assets/architecture-TIHT7OUA-CTxVpl9_.js +1 -0
- package/web-dist/assets/{architectureDiagram-ZJ3FMSHR-CtUBwBcU.js → architectureDiagram-ZJ3FMSHR-DzQjWW7u.js} +1 -1
- package/web-dist/assets/{blockDiagram-677ZJIJ3-OzqrN18g.js → blockDiagram-677ZJIJ3-BJnpkLMt.js} +1 -1
- package/web-dist/assets/{c4Diagram-LMCZKHZV-DgYAtD7L.js → c4Diagram-LMCZKHZV-COdatsYu.js} +1 -1
- package/web-dist/assets/channel-COS0Ygbp.js +1 -0
- package/web-dist/assets/{chunk-32BRIVSS-CKwBruPa.js → chunk-32BRIVSS-CORMw4Vm.js} +1 -1
- package/web-dist/assets/{chunk-52WLFC77-gvoNW_ar.js → chunk-52WLFC77-C7lEadTg.js} +1 -1
- package/web-dist/assets/{chunk-C7G6YPKG-EJ5BdmRQ.js → chunk-C7G6YPKG-DZy4F97l.js} +1 -1
- package/web-dist/assets/{chunk-EX3LRPZG-DJQF-VwN.js → chunk-EX3LRPZG-HynlfV9p.js} +1 -1
- package/web-dist/assets/{chunk-FWX5IMBZ-CXBLvjvR.js → chunk-FWX5IMBZ-BbwKNhKm.js} +2 -2
- package/web-dist/assets/{chunk-HOUHSVGY-De3ULdBq.js → chunk-HOUHSVGY-lIhOZSmL.js} +1 -1
- package/web-dist/assets/{chunk-ICXQ74PX-aUbMdGsl.js → chunk-ICXQ74PX-WGxaMO8c.js} +1 -1
- package/web-dist/assets/{chunk-MOJQB5TN-BLK44SUW.js → chunk-MOJQB5TN-B-cx0f3u.js} +1 -1
- package/web-dist/assets/{chunk-OGEWGWER-CQZ3zQ2q.js → chunk-OGEWGWER-DJceVwZH.js} +1 -1
- package/web-dist/assets/{chunk-PUDLZKDR-DcdN44K2.js → chunk-PUDLZKDR-CGwHZns8.js} +1 -1
- package/web-dist/assets/{chunk-Q4XR5HBZ-Db2ge7fW.js → chunk-Q4XR5HBZ-PTSWtmk1.js} +1 -1
- package/web-dist/assets/{chunk-V7JOEXUC-D80jxcmB.js → chunk-V7JOEXUC-VNxHZPcf.js} +1 -1
- package/web-dist/assets/{chunk-VAUOI2AC-nDGsXZZE.js → chunk-VAUOI2AC-ZXYCz_Aw.js} +1 -1
- package/web-dist/assets/{chunk-VR4S4FIN-BGXgLAsD.js → chunk-VR4S4FIN-9WCtmFJp.js} +1 -1
- package/web-dist/assets/{chunk-WYO6CB5R-BbGEK50o.js → chunk-WYO6CB5R-V4EBjpmt.js} +1 -1
- package/web-dist/assets/{chunk-ZGVPDNZ5-CjEI23Vu.js → chunk-ZGVPDNZ5-CPW0Z0ae.js} +1 -1
- package/web-dist/assets/classDiagram-OUVF2IWQ-Df5TLnrN.js +1 -0
- package/web-dist/assets/classDiagram-v2-EOCWNBFH-Df5TLnrN.js +1 -0
- package/web-dist/assets/{cynefin-VYW2F7L2-CR69iDgw.js → cynefin-VYW2F7L2-E7PklfJD.js} +1 -1
- package/web-dist/assets/{cynefinDiagram-TSTJHNR4-Le_FSC65.js → cynefinDiagram-TSTJHNR4-JIXAPjDf.js} +1 -1
- package/web-dist/assets/{dagre-VKFMJZFB-CxAlFDI9.js → dagre-VKFMJZFB-DjXrdcNx.js} +1 -1
- package/web-dist/assets/{diagram-FQU43EPY-BFMwv6Pj.js → diagram-FQU43EPY--i9i0qhm.js} +1 -1
- package/web-dist/assets/{diagram-G47NLZAW-mWAc5hJ0.js → diagram-G47NLZAW-DxgcENZ_.js} +1 -1
- package/web-dist/assets/{diagram-NH7WQ7WH-CC-QXuir.js → diagram-NH7WQ7WH-CUy9Nr90.js} +1 -1
- package/web-dist/assets/{diagram-OA4YK3LP-Cqs5o39q.js → diagram-OA4YK3LP-DbTbUaCb.js} +1 -1
- package/web-dist/assets/{diagram-WEI45ONY-B9PF6IpG.js → diagram-WEI45ONY-2gk6xhOq.js} +1 -1
- package/web-dist/assets/{ebnfDiagram-CCIWWBDH-C1DkTGUE.js → ebnfDiagram-CCIWWBDH-uE2iDETg.js} +1 -1
- package/web-dist/assets/{erDiagram-Q63AITRT-CbCG5w3K.js → erDiagram-Q63AITRT-dztd4MUw.js} +1 -1
- package/web-dist/assets/eventmodeling-45OFAUF4-DPVPOEaJ.js +1 -0
- package/web-dist/assets/flowDiagram-23GEKE2U-BMIMgVYd.js +1 -0
- package/web-dist/assets/{ganttDiagram-NO4QXBWP-CaywKz56.js → ganttDiagram-NO4QXBWP-DAds6Aht.js} +1 -1
- package/web-dist/assets/{gitGraph-TEB2WS4Q-DhbijOBs.js → gitGraph-TEB2WS4Q-Ci0XVvIa.js} +1 -1
- package/web-dist/assets/{gitGraphDiagram-IHSO6WYX-DHngf1QZ.js → gitGraphDiagram-IHSO6WYX-C6FULyt8.js} +1 -1
- package/web-dist/assets/{index-CxwWndgM.js → index-CNy5uOpI.js} +116 -111
- package/web-dist/assets/{index-C-3lsl4q.css → index-D6LsViUY.css} +1 -1
- package/web-dist/assets/{info-DKCQHKI2-D2uo8Yq_.js → info-DKCQHKI2-9N77dOiw.js} +1 -1
- package/web-dist/assets/{infoDiagram-FWYZ7A6U-Bixn1mvJ.js → infoDiagram-FWYZ7A6U-BymP3PgG.js} +1 -1
- package/web-dist/assets/{ishikawaDiagram-FXEZZL3T-DG48ASOp.js → ishikawaDiagram-FXEZZL3T-CU_kQBz1.js} +1 -1
- package/web-dist/assets/{journeyDiagram-5HDEW3XC-DpQOwYAS.js → journeyDiagram-5HDEW3XC-DZN15HSd.js} +1 -1
- package/web-dist/assets/{kanban-definition-HUTT4EX6-Dph0AMZo.js → kanban-definition-HUTT4EX6-J4wR5g_3.js} +1 -1
- package/web-dist/assets/{line-hnYRfUMr.js → line-SRzGpiDr.js} +1 -1
- package/web-dist/assets/{mermaid-parser.core-DdD3ClpS.js → mermaid-parser.core-CGBscNGo.js} +3 -3
- package/web-dist/assets/{mermaid.core-C2DMq9ss.js → mermaid.core-xNdwXb1r.js} +3 -3
- package/web-dist/assets/{mindmap-definition-LN4V7U3C-CirJBG-x.js → mindmap-definition-LN4V7U3C-gR2dbzrj.js} +1 -1
- package/web-dist/assets/{packet-7NZHBO7P-kD-OtFAF.js → packet-7NZHBO7P-DrR4W6I3.js} +1 -1
- package/web-dist/assets/{pegDiagram-2B236MQR-DGmi8fl-.js → pegDiagram-2B236MQR-DN7R-_t4.js} +1 -1
- package/web-dist/assets/{pie-RZYD4A2V-DpKplj-N.js → pie-RZYD4A2V-C8VjQAFZ.js} +1 -1
- package/web-dist/assets/{pieDiagram-ENE6RG2P-CW-zVLyR.js → pieDiagram-ENE6RG2P-5w64zdD1.js} +1 -1
- package/web-dist/assets/{quadrantDiagram-ABIIQ3AL-fxSaIvo2.js → quadrantDiagram-ABIIQ3AL-B4rbezq_.js} +1 -1
- package/web-dist/assets/{radar-I7S5WNFK-BPu7ClHP.js → radar-I7S5WNFK-CTbbPB8m.js} +1 -1
- package/web-dist/assets/{railroad-3IZDKUUU-CoQXFYm6.js → railroad-3IZDKUUU-CY1er15b.js} +1 -1
- package/web-dist/assets/railroad-abnf-AHOZXSZD-DfEpkrtJ.js +1 -0
- package/web-dist/assets/railroad-ebnf-EBAXGLYW-Csunejgu.js +1 -0
- package/web-dist/assets/railroad-peg-LSFZ7HO6-BgRslbM_.js +1 -0
- package/web-dist/assets/{railroadDiagram-RFXS5EU6-Bqnz_3Bc.js → railroadDiagram-RFXS5EU6-Bx2HJ3yT.js} +1 -1
- package/web-dist/assets/{requirementDiagram-TGXJPOKE-DJHMdBhh.js → requirementDiagram-TGXJPOKE-BLK-Y2rx.js} +1 -1
- package/web-dist/assets/{sankeyDiagram-HTMAVEWB-BlxzmT-W.js → sankeyDiagram-HTMAVEWB-Dk-8Miv-.js} +1 -1
- package/web-dist/assets/{sequenceDiagram-DBY2YBRQ-BT7Rn1Uo.js → sequenceDiagram-DBY2YBRQ-DL2alfR-.js} +1 -1
- package/web-dist/assets/{stateDiagram-2N3HPSRC-CDoiFcke.js → stateDiagram-2N3HPSRC-Bka44wf1.js} +1 -1
- package/web-dist/assets/stateDiagram-v2-6OUMAXLB-6KcScVPX.js +1 -0
- package/web-dist/assets/{swimlanes-5IMT3BWC-DtzTgSSP.js → swimlanes-5IMT3BWC-e0GbMwIr.js} +1 -1
- package/web-dist/assets/swimlanesDiagram-G3AALYLV-jaJhlDbE.js +8 -0
- package/web-dist/assets/{timeline-definition-FHXFAJF6-Dn63VmSO.js → timeline-definition-FHXFAJF6-CT3GFq89.js} +1 -1
- package/web-dist/assets/{treeView-QDETBFTQ-DIfJIc9R.js → treeView-QDETBFTQ-BJauJ0bm.js} +1 -1
- package/web-dist/assets/{treemap-6X3UGDF4-n9Fwqngl.js → treemap-6X3UGDF4-DCX7A-nx.js} +1 -1
- package/web-dist/assets/{vennDiagram-L72KCM5P-C1thEMxE.js → vennDiagram-L72KCM5P-D4dm2iTR.js} +1 -1
- package/web-dist/assets/{wardley-OPB4EBWU-Dl6RiScD.js → wardley-OPB4EBWU-DklTDSId.js} +1 -1
- package/web-dist/assets/{wardleyDiagram-EHGQE667-DBelgTwB.js → wardleyDiagram-EHGQE667-CikP5hBd.js} +1 -1
- package/web-dist/assets/{xychartDiagram-FW5EYKEG-DFGVnPLj.js → xychartDiagram-FW5EYKEG-FXuOAFpz.js} +1 -1
- package/web-dist/index.html +2 -2
- package/web-dist/assets/architecture-TIHT7OUA-BS8x9TQa.js +0 -1
- package/web-dist/assets/channel-DHZV3ADN.js +0 -1
- package/web-dist/assets/classDiagram-OUVF2IWQ-Dcx3TDdU.js +0 -1
- package/web-dist/assets/classDiagram-v2-EOCWNBFH-Dcx3TDdU.js +0 -1
- package/web-dist/assets/eventmodeling-45OFAUF4-DAhP7KCX.js +0 -1
- package/web-dist/assets/flowDiagram-23GEKE2U-Be2iuqwq.js +0 -1
- package/web-dist/assets/railroad-abnf-AHOZXSZD-BiqkuXNr.js +0 -1
- package/web-dist/assets/railroad-ebnf-EBAXGLYW-CDaukY4Z.js +0 -1
- package/web-dist/assets/railroad-peg-LSFZ7HO6-CsUPdvVL.js +0 -1
- package/web-dist/assets/stateDiagram-v2-6OUMAXLB-DiLnjG8k.js +0 -1
- package/web-dist/assets/swimlanesDiagram-G3AALYLV-BqvWOcR2.js +0 -8
package/dist/dev-child.js
CHANGED
|
@@ -129,6 +129,7 @@ var init_frizz_paths = __esm({
|
|
|
129
129
|
import { execFileSync } from "node:child_process";
|
|
130
130
|
import { randomUUID } from "node:crypto";
|
|
131
131
|
import { readFileSync } from "node:fs";
|
|
132
|
+
import { join as join2 } from "node:path";
|
|
132
133
|
function errorCode(error) {
|
|
133
134
|
return error && typeof error === "object" && "code" in error && typeof error.code === "string" ? error.code : void 0;
|
|
134
135
|
}
|
|
@@ -169,6 +170,38 @@ function fixedPsGeneration(pid) {
|
|
|
169
170
|
return null;
|
|
170
171
|
}
|
|
171
172
|
}
|
|
173
|
+
function windowsGeneration(pid) {
|
|
174
|
+
if (!Number.isInteger(pid) || pid <= 0) return null;
|
|
175
|
+
try {
|
|
176
|
+
const shell = join2(
|
|
177
|
+
process.env.SystemRoot ?? "C:\\Windows",
|
|
178
|
+
"System32",
|
|
179
|
+
"WindowsPowerShell",
|
|
180
|
+
"v1.0",
|
|
181
|
+
"powershell.exe"
|
|
182
|
+
);
|
|
183
|
+
const value = execFileSync(shell, [
|
|
184
|
+
"-NoProfile",
|
|
185
|
+
"-NonInteractive",
|
|
186
|
+
"-NoLogo",
|
|
187
|
+
"-Command",
|
|
188
|
+
// A vanished PID, a protected process and an access-denied StartTime all throw. Exit non-zero
|
|
189
|
+
// so execFileSync rejects, rather than letting PowerShell's error prose become a marker.
|
|
190
|
+
`try{[Console]::Out.Write((Get-Process -Id ${pid} -ErrorAction Stop).StartTime.ToFileTimeUtc())}catch{exit 1}`
|
|
191
|
+
], {
|
|
192
|
+
encoding: "utf8",
|
|
193
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
194
|
+
// A wedged spawn must not hold a launcher's poll loop open forever; a timeout reads as
|
|
195
|
+
// unavailable, which retains the owner.
|
|
196
|
+
timeout: 5e3,
|
|
197
|
+
windowsHide: true
|
|
198
|
+
}).trim();
|
|
199
|
+
if (!/^\d{1,20}$/u.test(value)) return null;
|
|
200
|
+
return { processStart: `win32:${value}`, confidence: "exact" };
|
|
201
|
+
} catch {
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
172
205
|
function observeDefault(pid) {
|
|
173
206
|
if (!processAlive(pid)) return { confidence: "unavailable" };
|
|
174
207
|
if (process.platform === "linux") {
|
|
@@ -178,6 +211,7 @@ function observeDefault(pid) {
|
|
|
178
211
|
return fallback ?? { confidence: "unavailable" };
|
|
179
212
|
}
|
|
180
213
|
if (process.platform === "darwin") return fixedPsGeneration(pid) ?? { confidence: "unavailable" };
|
|
214
|
+
if (process.platform === "win32") return windowsGeneration(pid) ?? { confidence: "unavailable" };
|
|
181
215
|
return { confidence: "unavailable" };
|
|
182
216
|
}
|
|
183
217
|
function observeProcessGeneration(generation, adapter = defaultProcessPlatformAdapter) {
|
|
@@ -185,7 +219,7 @@ function observeProcessGeneration(generation, adapter = defaultProcessPlatformAd
|
|
|
185
219
|
const self = adapter.current();
|
|
186
220
|
if (generation.pid === self.pid && generation.processStart === self.processStart) return "exact";
|
|
187
221
|
if (generation.processStart.startsWith("opaque:")) return "unavailable";
|
|
188
|
-
if (!/^(?:linux|ps-utc|opaque):/u.test(generation.processStart)) return "unavailable";
|
|
222
|
+
if (!/^(?:linux|ps-utc|win32|opaque):/u.test(generation.processStart)) return "unavailable";
|
|
189
223
|
const observed = adapter.observe(generation.pid);
|
|
190
224
|
if (!observed.processStart || observed.confidence === "unavailable") return "unavailable";
|
|
191
225
|
if (observed.processStart.split(":", 1)[0] !== generation.processStart.split(":", 1)[0]) {
|
|
@@ -241,7 +275,7 @@ import {
|
|
|
241
275
|
writeFileSync
|
|
242
276
|
} from "node:fs";
|
|
243
277
|
import { homedir as homedir2 } from "node:os";
|
|
244
|
-
import { dirname as dirname2, join as
|
|
278
|
+
import { dirname as dirname2, join as join3, resolve } from "node:path";
|
|
245
279
|
function errorCode2(error) {
|
|
246
280
|
return error && typeof error === "object" && "code" in error && typeof error.code === "string" ? error.code : void 0;
|
|
247
281
|
}
|
|
@@ -256,7 +290,7 @@ function canonicalHome(home) {
|
|
|
256
290
|
}
|
|
257
291
|
}
|
|
258
292
|
function namedLaunchLockPath(home, name) {
|
|
259
|
-
return
|
|
293
|
+
return join3(frizzPaths({ home: canonicalHome(home) }).state, name);
|
|
260
294
|
}
|
|
261
295
|
function pidIsAlive(pid) {
|
|
262
296
|
if (!Number.isInteger(pid) || pid <= 0) return false;
|
|
@@ -284,7 +318,7 @@ function syncDirectory(path) {
|
|
|
284
318
|
}
|
|
285
319
|
function lockOwnerPath(lockPath) {
|
|
286
320
|
try {
|
|
287
|
-
return statSync(lockPath).isDirectory() ?
|
|
321
|
+
return statSync(lockPath).isDirectory() ? join3(lockPath, GLOBAL_LOCK_OWNER) : lockPath;
|
|
288
322
|
} catch {
|
|
289
323
|
return lockPath;
|
|
290
324
|
}
|
|
@@ -446,7 +480,7 @@ function resolveGitWorktree(dir) {
|
|
|
446
480
|
// Do not enable Git's repository-wide `extensions.worktreeConfig` merely to hold one private Frizz
|
|
447
481
|
// value. A config file inside the linked worktree's own administrative directory has Git's atomic
|
|
448
482
|
// config-lock behavior, survives `git worktree move`, and disappears with `git worktree remove`.
|
|
449
|
-
...scope === "worktree" ? { identityConfig:
|
|
483
|
+
...scope === "worktree" ? { identityConfig: join3(gitDir, "frizz.config") } : {}
|
|
450
484
|
};
|
|
451
485
|
}
|
|
452
486
|
function readProjectIdConfig(dir, args, description) {
|
|
@@ -615,9 +649,9 @@ var init_project_identity = __esm({
|
|
|
615
649
|
import { createHash as createHash3, randomUUID as randomUUID3 } from "node:crypto";
|
|
616
650
|
import { closeSync as closeSync2, existsSync as existsSync2, fsyncSync as fsyncSync2, mkdirSync as mkdirSync2, openSync as openSync2, readFileSync as readFileSync3, realpathSync as realpathSync2, renameSync as renameSync2, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
617
651
|
import { homedir as homedir3 } from "node:os";
|
|
618
|
-
import { dirname as dirname3, join as
|
|
652
|
+
import { dirname as dirname3, join as join4, parse, resolve as resolve2 } from "node:path";
|
|
619
653
|
function projectIdPath(root) {
|
|
620
|
-
return
|
|
654
|
+
return join4(root, FRIZZ_DIR, ID_FILE);
|
|
621
655
|
}
|
|
622
656
|
function readProjectIdFile(root) {
|
|
623
657
|
let raw2;
|
|
@@ -633,9 +667,9 @@ function readProjectIdFile(root) {
|
|
|
633
667
|
}
|
|
634
668
|
}
|
|
635
669
|
function writeProjectIdFile(root, id) {
|
|
636
|
-
const dir =
|
|
670
|
+
const dir = join4(root, FRIZZ_DIR);
|
|
637
671
|
mkdirSync2(dir, { recursive: true });
|
|
638
|
-
const ignore =
|
|
672
|
+
const ignore = join4(dir, SELF_IGNORE);
|
|
639
673
|
if (!existsSync2(ignore)) {
|
|
640
674
|
try {
|
|
641
675
|
writeFileSync2(ignore, "*\n", { flag: "wx" });
|
|
@@ -643,7 +677,7 @@ function writeProjectIdFile(root, id) {
|
|
|
643
677
|
}
|
|
644
678
|
}
|
|
645
679
|
const path = projectIdPath(root);
|
|
646
|
-
const temp =
|
|
680
|
+
const temp = join4(dir, `.${ID_FILE}.${process.pid}.${randomUUID3()}.tmp`);
|
|
647
681
|
let fd;
|
|
648
682
|
try {
|
|
649
683
|
fd = openSync2(temp, "wx", 384);
|
|
@@ -684,7 +718,7 @@ function ensureProjectIdFile(root, home = homedir3(), seed) {
|
|
|
684
718
|
}
|
|
685
719
|
}
|
|
686
720
|
function hasAny(dir, names) {
|
|
687
|
-
return names.some((name) => existsSync2(
|
|
721
|
+
return names.some((name) => existsSync2(join4(dir, name)));
|
|
688
722
|
}
|
|
689
723
|
function existingProjectId(dir) {
|
|
690
724
|
const fromFile = readProjectIdFile(dir);
|
|
@@ -12871,6 +12905,16 @@ var init_receipt_bus = __esm({
|
|
|
12871
12905
|
}
|
|
12872
12906
|
});
|
|
12873
12907
|
|
|
12908
|
+
// packages/shared/src/relay-protocol.ts
|
|
12909
|
+
var RELAY_MAX_FRAME_BODY, RELAY_MAX_WS_CHUNK;
|
|
12910
|
+
var init_relay_protocol = __esm({
|
|
12911
|
+
"packages/shared/src/relay-protocol.ts"() {
|
|
12912
|
+
"use strict";
|
|
12913
|
+
RELAY_MAX_FRAME_BODY = 512 * 1024;
|
|
12914
|
+
RELAY_MAX_WS_CHUNK = 64 * 1024;
|
|
12915
|
+
}
|
|
12916
|
+
});
|
|
12917
|
+
|
|
12874
12918
|
// packages/shared/src/index.ts
|
|
12875
12919
|
function attachmentExtension(name) {
|
|
12876
12920
|
const m = /\.([a-zA-Z0-9]+)$/.exec(name.trim());
|
|
@@ -13233,6 +13277,7 @@ var init_src = __esm({
|
|
|
13233
13277
|
init_drainable_worker();
|
|
13234
13278
|
init_interactions();
|
|
13235
13279
|
init_receipt_bus();
|
|
13280
|
+
init_relay_protocol();
|
|
13236
13281
|
init_thread_slug();
|
|
13237
13282
|
ATTACHMENT_IMAGE_EXTENSIONS = ["png", "jpg", "jpeg", "gif", "webp"];
|
|
13238
13283
|
ATTACHMENT_DOC_EXTENSIONS = [
|
|
@@ -14925,9 +14970,9 @@ ${DISPATCH_TASK_BANNER}
|
|
|
14925
14970
|
// packages/server/src/project-registry.ts
|
|
14926
14971
|
import { closeSync as closeSync3, existsSync as existsSync3, fsyncSync as fsyncSync3, mkdirSync as mkdirSync3, openSync as openSync3, readFileSync as readFileSync4, readdirSync, realpathSync as realpathSync3, renameSync as renameSync3, rmSync as rmSync3, writeFileSync as writeFileSync3 } from "node:fs";
|
|
14927
14972
|
import { homedir as homedir4 } from "node:os";
|
|
14928
|
-
import { basename, dirname as dirname4, join as
|
|
14973
|
+
import { basename, dirname as dirname4, join as join5 } from "node:path";
|
|
14929
14974
|
function registryPath(home = homedir4()) {
|
|
14930
|
-
return
|
|
14975
|
+
return join5(frizzPaths({ home }).data, "registry.json");
|
|
14931
14976
|
}
|
|
14932
14977
|
function readRegistry(home = homedir4()) {
|
|
14933
14978
|
let raw2;
|
|
@@ -15016,7 +15061,7 @@ function registerProject(input, home = homedir4()) {
|
|
|
15016
15061
|
writeRegistry(registry, home);
|
|
15017
15062
|
return { entry: byId, action: "reopened" };
|
|
15018
15063
|
}
|
|
15019
|
-
if (existsSync3(
|
|
15064
|
+
if (existsSync3(join5(byId.path, ".frizz", ".id"))) return { action: "duplicate" };
|
|
15020
15065
|
byId.path = input.dir;
|
|
15021
15066
|
byId.lastOpenedAt = at;
|
|
15022
15067
|
writeRegistry(registry, home);
|
|
@@ -15043,14 +15088,14 @@ function registerProject(input, home = homedir4()) {
|
|
|
15043
15088
|
function backfillRegistry(home = homedir4(), read = existingProjectId) {
|
|
15044
15089
|
let dirs;
|
|
15045
15090
|
try {
|
|
15046
|
-
dirs = readdirSync(
|
|
15091
|
+
dirs = readdirSync(join5(frizzPaths({ home }).data, "projects"), { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
|
|
15047
15092
|
} catch {
|
|
15048
15093
|
return 0;
|
|
15049
15094
|
}
|
|
15050
15095
|
const known = new Set(readRegistry(home).projects.map((p) => p.path));
|
|
15051
15096
|
let added = 0;
|
|
15052
15097
|
for (const id of dirs) {
|
|
15053
|
-
const recorded = recordedProjectDir(
|
|
15098
|
+
const recorded = recordedProjectDir(join5(frizzPaths({ home }).data, "projects", id));
|
|
15054
15099
|
const dir = recorded ? canonicalPath(recorded) : void 0;
|
|
15055
15100
|
if (!dir || known.has(dir)) continue;
|
|
15056
15101
|
if (read(dir) !== id) continue;
|
|
@@ -15068,7 +15113,7 @@ function backfillRegistry(home = homedir4(), read = existingProjectId) {
|
|
|
15068
15113
|
function recordedProjectDir(stateDir) {
|
|
15069
15114
|
for (const name of ["launcher.json", "server.lock", "project-launch.owner"]) {
|
|
15070
15115
|
try {
|
|
15071
|
-
const value = JSON.parse(readFileSync4(
|
|
15116
|
+
const value = JSON.parse(readFileSync4(join5(stateDir, name), "utf8")).projectDir;
|
|
15072
15117
|
if (typeof value === "string" && value.length > 0 && existsSync3(value)) return value;
|
|
15073
15118
|
} catch {
|
|
15074
15119
|
}
|
|
@@ -15111,7 +15156,7 @@ function findProjectBySegment(segment, home = homedir4()) {
|
|
|
15111
15156
|
return findBySlug(segment, home) ?? findById(segment, home);
|
|
15112
15157
|
}
|
|
15113
15158
|
function customIconPath(id, extension2, home = homedir4()) {
|
|
15114
|
-
return
|
|
15159
|
+
return join5(frizzPaths({ home }).data, "projects", id, `icon${extension2}`);
|
|
15115
15160
|
}
|
|
15116
15161
|
function updateEntry(id, apply, home) {
|
|
15117
15162
|
const registry = readRegistry(home);
|
|
@@ -15576,7 +15621,7 @@ CI (PRs): \`gh pr checks {n} -R {repo}\``;
|
|
|
15576
15621
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
15577
15622
|
import { mkdirSync as mkdirSync4, realpathSync as realpathSync4 } from "node:fs";
|
|
15578
15623
|
import { homedir as homedir5, tmpdir as tmpdir2 } from "node:os";
|
|
15579
|
-
import { basename as basename2, join as
|
|
15624
|
+
import { basename as basename2, join as join6, resolve as resolve3 } from "node:path";
|
|
15580
15625
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
15581
15626
|
function projectRepoIdentity(dir, name) {
|
|
15582
15627
|
const url = originRemoteUrl(dir);
|
|
@@ -15585,7 +15630,7 @@ function projectRepoIdentity(dir, name) {
|
|
|
15585
15630
|
return { label: parseRepoLabel(url) ?? name, ...githubRepo ? { githubRepo } : {} };
|
|
15586
15631
|
}
|
|
15587
15632
|
function trustedLocalFileRoots(project) {
|
|
15588
|
-
return [project.dir, tmpdir2(), "/tmp", resolve3(homedir5(), "Screenshots"),
|
|
15633
|
+
return [project.dir, tmpdir2(), "/tmp", resolve3(homedir5(), "Screenshots"), join6(project.stateDir, "attachments")];
|
|
15589
15634
|
}
|
|
15590
15635
|
function openableFileRoots(project) {
|
|
15591
15636
|
return [homedir5(), ...trustedLocalFileRoots(project)];
|
|
@@ -15691,10 +15736,10 @@ function resolveProject(cwd = process.cwd(), home = homedir5(), env = process.en
|
|
|
15691
15736
|
};
|
|
15692
15737
|
}
|
|
15693
15738
|
function permRequestDir(project) {
|
|
15694
|
-
return
|
|
15739
|
+
return join6(project.stateDir, "perm-requests");
|
|
15695
15740
|
}
|
|
15696
15741
|
function permMarkerPath(project, slug) {
|
|
15697
|
-
return
|
|
15742
|
+
return join6(permRequestDir(project), `${slug}.json`);
|
|
15698
15743
|
}
|
|
15699
15744
|
function projectLaunchTarget(project) {
|
|
15700
15745
|
return {
|
|
@@ -15749,7 +15794,7 @@ import {
|
|
|
15749
15794
|
statSync as statSync2,
|
|
15750
15795
|
writeFileSync as writeFileSync4
|
|
15751
15796
|
} from "node:fs";
|
|
15752
|
-
import { basename as basename3, dirname as dirname5, isAbsolute, join as
|
|
15797
|
+
import { basename as basename3, dirname as dirname5, isAbsolute, join as join7 } from "node:path";
|
|
15753
15798
|
function errorCode3(error) {
|
|
15754
15799
|
return error && typeof error === "object" && "code" in error && typeof error.code === "string" ? error.code : void 0;
|
|
15755
15800
|
}
|
|
@@ -15773,7 +15818,7 @@ function syncDirectory2(path) {
|
|
|
15773
15818
|
}
|
|
15774
15819
|
function atomicJson(path, value) {
|
|
15775
15820
|
mkdirSync5(dirname5(path), { recursive: true, mode: 448 });
|
|
15776
|
-
const temp =
|
|
15821
|
+
const temp = join7(dirname5(path), `.${basename3(path)}.${process.pid}.${randomUUID5()}.tmp`);
|
|
15777
15822
|
let fd;
|
|
15778
15823
|
try {
|
|
15779
15824
|
fd = openSync4(temp, "wx", 384);
|
|
@@ -15832,7 +15877,7 @@ function parseGuard(path) {
|
|
|
15832
15877
|
}
|
|
15833
15878
|
}
|
|
15834
15879
|
function acquireMutationGuard(stateDir, timeoutMs = GUARD_TIMEOUT_MS, adapter = defaultProcessPlatformAdapter) {
|
|
15835
|
-
const path =
|
|
15880
|
+
const path = join7(stateDir, MUTATION_GUARD_NAME);
|
|
15836
15881
|
mkdirSync5(stateDir, { recursive: true, mode: 448 });
|
|
15837
15882
|
const deadline = adapter.now() + Math.max(0, timeoutMs);
|
|
15838
15883
|
for (; ; ) {
|
|
@@ -15926,7 +15971,7 @@ function parseOwner(path) {
|
|
|
15926
15971
|
}
|
|
15927
15972
|
}
|
|
15928
15973
|
function projectLaunchOwnerPath(stateDir) {
|
|
15929
|
-
return
|
|
15974
|
+
return join7(stateDir, OWNER_NAME);
|
|
15930
15975
|
}
|
|
15931
15976
|
function servedByAnotherProcess(stateDir, projectId, self = process.pid, alive = pidIsAlive) {
|
|
15932
15977
|
const owner = readProjectLaunchOwner(stateDir);
|
|
@@ -15949,7 +15994,7 @@ function projectLaunchTokenProof(target, token) {
|
|
|
15949
15994
|
}
|
|
15950
15995
|
function removeStatusesForToken(stateDir, token) {
|
|
15951
15996
|
for (const name of ["dev-supervisor.lock", "server.lock"]) {
|
|
15952
|
-
const path =
|
|
15997
|
+
const path = join7(stateDir, name);
|
|
15953
15998
|
try {
|
|
15954
15999
|
const value = JSON.parse(readFileSync5(path, "utf8"));
|
|
15955
16000
|
if (value.ownerToken === token) quarantine(path, "stale");
|
|
@@ -16450,9 +16495,9 @@ import {
|
|
|
16450
16495
|
writeSync
|
|
16451
16496
|
} from "node:fs";
|
|
16452
16497
|
import { homedir as homedir6 } from "node:os";
|
|
16453
|
-
import { join as
|
|
16498
|
+
import { join as join8 } from "node:path";
|
|
16454
16499
|
function defaultLogRoot(stateDir, home = homedir6()) {
|
|
16455
|
-
return stateDir ?
|
|
16500
|
+
return stateDir ? join8(stateDir, "logs") : join8(frizzPaths({ home }).state, "logs");
|
|
16456
16501
|
}
|
|
16457
16502
|
function runStamp(at) {
|
|
16458
16503
|
const pad = (value) => String(value).padStart(2, "0");
|
|
@@ -16461,11 +16506,11 @@ function runStamp(at) {
|
|
|
16461
16506
|
function runLogPath(stateDir, at = /* @__PURE__ */ new Date(), pid = process.pid, home = homedir6(), env = process.env) {
|
|
16462
16507
|
const name = `frizz-${runStamp(at)}-${pid}.log`;
|
|
16463
16508
|
const override = env[LOG_PATH_ENV]?.trim();
|
|
16464
|
-
if (override) return override.endsWith(".log") ? override :
|
|
16465
|
-
return
|
|
16509
|
+
if (override) return override.endsWith(".log") ? override : join8(override, name);
|
|
16510
|
+
return join8(defaultLogRoot(stateDir, home), name);
|
|
16466
16511
|
}
|
|
16467
16512
|
function latestLogPath(dir) {
|
|
16468
|
-
return
|
|
16513
|
+
return join8(dir, "latest.log");
|
|
16469
16514
|
}
|
|
16470
16515
|
function linkLatest(dir, target) {
|
|
16471
16516
|
const link = latestLogPath(dir);
|
|
@@ -16489,7 +16534,7 @@ function pruneRunLogs(dir, keep = RETAINED_RUNS, days = RETAINED_DAYS, now = Dat
|
|
|
16489
16534
|
}
|
|
16490
16535
|
const dated = entries.map((name) => {
|
|
16491
16536
|
try {
|
|
16492
|
-
return { name, at: statSync3(
|
|
16537
|
+
return { name, at: statSync3(join8(dir, name)).mtimeMs };
|
|
16493
16538
|
} catch {
|
|
16494
16539
|
return { name, at: 0 };
|
|
16495
16540
|
}
|
|
@@ -16498,7 +16543,7 @@ function pruneRunLogs(dir, keep = RETAINED_RUNS, days = RETAINED_DAYS, now = Dat
|
|
|
16498
16543
|
const stale = dated.filter((entry, index) => index >= keep || entry.at < cutoff);
|
|
16499
16544
|
for (const entry of stale) {
|
|
16500
16545
|
try {
|
|
16501
|
-
rmSync5(
|
|
16546
|
+
rmSync5(join8(dir, entry.name), { force: true });
|
|
16502
16547
|
} catch {
|
|
16503
16548
|
}
|
|
16504
16549
|
}
|
|
@@ -16512,7 +16557,7 @@ function formatDiskLine(record) {
|
|
|
16512
16557
|
}
|
|
16513
16558
|
function openLogFile(path) {
|
|
16514
16559
|
try {
|
|
16515
|
-
mkdirSync6(
|
|
16560
|
+
mkdirSync6(join8(path, ".."), { recursive: true, mode: 448 });
|
|
16516
16561
|
return openSync5(path, "a", 384);
|
|
16517
16562
|
} catch {
|
|
16518
16563
|
return null;
|
|
@@ -16526,7 +16571,7 @@ function createLogger(options = {}) {
|
|
|
16526
16571
|
const maxBytes = options.maxBytes ?? MAX_LOG_BYTES;
|
|
16527
16572
|
let fd = path === null ? null : openLogFile(path);
|
|
16528
16573
|
if (fd !== null && path !== null && options.owner !== false) {
|
|
16529
|
-
const dir =
|
|
16574
|
+
const dir = join8(path, "..");
|
|
16530
16575
|
pruneRunLogs(dir);
|
|
16531
16576
|
linkLatest(dir, path);
|
|
16532
16577
|
}
|
|
@@ -19475,9 +19520,9 @@ var init_storage = __esm({
|
|
|
19475
19520
|
|
|
19476
19521
|
// packages/server/src/settings.ts
|
|
19477
19522
|
import { closeSync as closeSync5, fsyncSync as fsyncSync5, mkdirSync as mkdirSync7, openSync as openSync6, readFileSync as readFileSync6, renameSync as renameSync5, rmSync as rmSync6, writeFileSync as writeFileSync6 } from "node:fs";
|
|
19478
|
-
import { dirname as dirname6, join as
|
|
19523
|
+
import { dirname as dirname6, join as join9 } from "node:path";
|
|
19479
19524
|
function machineSettingsPath(home) {
|
|
19480
|
-
return
|
|
19525
|
+
return join9(frizzPaths({ home }).data, "settings.json");
|
|
19481
19526
|
}
|
|
19482
19527
|
function pickMachine(settings) {
|
|
19483
19528
|
return Object.fromEntries(MACHINE_KEYS.map((key) => [key, settings[key]]));
|
|
@@ -19500,13 +19545,15 @@ function pickPresent(partial) {
|
|
|
19500
19545
|
return out;
|
|
19501
19546
|
}
|
|
19502
19547
|
function writeMachineSettings(next, home) {
|
|
19503
|
-
|
|
19548
|
+
writeMachineFile(machineSettingsPath(home), next);
|
|
19549
|
+
}
|
|
19550
|
+
function writeMachineFile(path, value) {
|
|
19504
19551
|
mkdirSync7(dirname6(path), { recursive: true });
|
|
19505
19552
|
const temp = `${path}.${process.pid}.tmp`;
|
|
19506
19553
|
let fd;
|
|
19507
19554
|
try {
|
|
19508
19555
|
fd = openSync6(temp, "w", 384);
|
|
19509
|
-
writeFileSync6(fd, `${JSON.stringify(
|
|
19556
|
+
writeFileSync6(fd, `${JSON.stringify(value, null, 2)}
|
|
19510
19557
|
`, "utf8");
|
|
19511
19558
|
fsyncSync5(fd);
|
|
19512
19559
|
closeSync5(fd);
|
|
@@ -19569,9 +19616,90 @@ var init_settings = __esm({
|
|
|
19569
19616
|
}
|
|
19570
19617
|
});
|
|
19571
19618
|
|
|
19619
|
+
// packages/server/src/dispatch-preferences.ts
|
|
19620
|
+
import { readFileSync as readFileSync7 } from "node:fs";
|
|
19621
|
+
import { join as join10 } from "node:path";
|
|
19622
|
+
function machineDispatchPreferencesPath(home) {
|
|
19623
|
+
return join10(frizzPaths({ home }).data, "dispatch-preferences.json");
|
|
19624
|
+
}
|
|
19625
|
+
function readMachineDispatchPreferences(home) {
|
|
19626
|
+
let raw2;
|
|
19627
|
+
try {
|
|
19628
|
+
raw2 = JSON.parse(readFileSync7(machineDispatchPreferencesPath(home), "utf8"));
|
|
19629
|
+
} catch {
|
|
19630
|
+
return void 0;
|
|
19631
|
+
}
|
|
19632
|
+
const parsed = DispatchPreferences.safeParse(raw2);
|
|
19633
|
+
return parsed.success ? parsed.data : void 0;
|
|
19634
|
+
}
|
|
19635
|
+
function permissionFor(backend, mode) {
|
|
19636
|
+
if (backend === "codex") {
|
|
19637
|
+
if (mode === "plan" || mode === "bypassPermissions") return mode;
|
|
19638
|
+
return "default";
|
|
19639
|
+
}
|
|
19640
|
+
return mode === "plan" ? "auto" : mode;
|
|
19641
|
+
}
|
|
19642
|
+
function defaultDispatchPreferences(settings, codexModels = []) {
|
|
19643
|
+
const backend = settings.backend ?? (codexModels.some((model) => model.slug === settings.model) ? "codex" : "claude");
|
|
19644
|
+
const selected = {
|
|
19645
|
+
...settings.model ? { model: settings.model } : {},
|
|
19646
|
+
...settings.effort ? { effort: settings.effort } : {},
|
|
19647
|
+
permissionMode: permissionFor(backend, settings.permissionMode)
|
|
19648
|
+
};
|
|
19649
|
+
return {
|
|
19650
|
+
backend,
|
|
19651
|
+
claude: backend === "claude" ? selected : { permissionMode: "auto" },
|
|
19652
|
+
codex: backend === "codex" ? selected : { permissionMode: "default" }
|
|
19653
|
+
};
|
|
19654
|
+
}
|
|
19655
|
+
function getDispatchPreferences(storage, settings, home, codexModels = []) {
|
|
19656
|
+
const machine = readMachineDispatchPreferences(home);
|
|
19657
|
+
if (machine) return machine;
|
|
19658
|
+
const parsed = DispatchPreferences.safeParse(storage.getSetting(KEY));
|
|
19659
|
+
return parsed.success ? parsed.data : defaultDispatchPreferences(settings, codexModels);
|
|
19660
|
+
}
|
|
19661
|
+
function setDispatchPreference(storage, settings, home, update, codexModels = []) {
|
|
19662
|
+
const current = getDispatchPreferences(storage, settings, home, codexModels);
|
|
19663
|
+
let next;
|
|
19664
|
+
if (update.field === "backend") {
|
|
19665
|
+
next = { ...current, backend: update.value };
|
|
19666
|
+
} else if (update.field === "profile") {
|
|
19667
|
+
next = {
|
|
19668
|
+
...current,
|
|
19669
|
+
backend: update.backend,
|
|
19670
|
+
[update.backend]: {
|
|
19671
|
+
...current[update.backend],
|
|
19672
|
+
model: update.model,
|
|
19673
|
+
effort: update.effort
|
|
19674
|
+
}
|
|
19675
|
+
};
|
|
19676
|
+
} else {
|
|
19677
|
+
const profile = current[update.backend];
|
|
19678
|
+
next = {
|
|
19679
|
+
...current,
|
|
19680
|
+
...update.field === "model" ? { backend: update.backend } : {},
|
|
19681
|
+
[update.backend]: { ...profile, [update.field]: update.value }
|
|
19682
|
+
};
|
|
19683
|
+
}
|
|
19684
|
+
const validated = DispatchPreferences.parse(next);
|
|
19685
|
+
writeMachineFile(machineDispatchPreferencesPath(home), validated);
|
|
19686
|
+
storage.setSetting(KEY, validated);
|
|
19687
|
+
return validated;
|
|
19688
|
+
}
|
|
19689
|
+
var KEY;
|
|
19690
|
+
var init_dispatch_preferences = __esm({
|
|
19691
|
+
"packages/server/src/dispatch-preferences.ts"() {
|
|
19692
|
+
"use strict";
|
|
19693
|
+
init_src();
|
|
19694
|
+
init_frizz_paths();
|
|
19695
|
+
init_settings();
|
|
19696
|
+
KEY = "dispatch-preferences.v1";
|
|
19697
|
+
}
|
|
19698
|
+
});
|
|
19699
|
+
|
|
19572
19700
|
// packages/server/src/discover.ts
|
|
19573
19701
|
import { readdirSync as readdirSync3, statSync as statSync4, openSync as openSync7, readSync, closeSync as closeSync6 } from "node:fs";
|
|
19574
|
-
import { dirname as dirname7, join as
|
|
19702
|
+
import { dirname as dirname7, join as join11 } from "node:path";
|
|
19575
19703
|
function sentinelFor(sessionId) {
|
|
19576
19704
|
return `threads/${sessionId}/`;
|
|
19577
19705
|
}
|
|
@@ -19608,7 +19736,7 @@ function discoverTranscriptId(logDir, sessionId, opts = {}) {
|
|
|
19608
19736
|
if (name.startsWith(".") || !name.endsWith(".jsonl")) continue;
|
|
19609
19737
|
const id = name.slice(0, -".jsonl".length);
|
|
19610
19738
|
if (!id || id === sessionId || exclude?.has(id)) continue;
|
|
19611
|
-
const path =
|
|
19739
|
+
const path = join11(logDir, name);
|
|
19612
19740
|
let mtime;
|
|
19613
19741
|
try {
|
|
19614
19742
|
mtime = statSync4(path).mtimeMs;
|
|
@@ -19636,7 +19764,7 @@ function discoverTranscriptDir(logDir, sessionId, memo3 = strandedLogDirs) {
|
|
|
19636
19764
|
const name = `${sessionId}.jsonl`;
|
|
19637
19765
|
const better = (best2, dir) => {
|
|
19638
19766
|
if (dir === logDir) return best2;
|
|
19639
|
-
const at = mtimeOfNonEmpty(
|
|
19767
|
+
const at = mtimeOfNonEmpty(join11(dir, name));
|
|
19640
19768
|
if (at === void 0) return best2;
|
|
19641
19769
|
return !best2 || at > best2.mtimeMs ? { dir, mtimeMs: at } : best2;
|
|
19642
19770
|
};
|
|
@@ -19649,7 +19777,7 @@ function discoverTranscriptDir(logDir, sessionId, memo3 = strandedLogDirs) {
|
|
|
19649
19777
|
} catch {
|
|
19650
19778
|
return void 0;
|
|
19651
19779
|
}
|
|
19652
|
-
for (const entry of entries) best = better(best,
|
|
19780
|
+
for (const entry of entries) best = better(best, join11(dirname7(logDir), entry));
|
|
19653
19781
|
if (!best) return void 0;
|
|
19654
19782
|
memo3.add(best.dir);
|
|
19655
19783
|
return best.dir;
|
|
@@ -19668,10 +19796,10 @@ var init_discover = __esm({
|
|
|
19668
19796
|
|
|
19669
19797
|
// packages/server/src/session-files.ts
|
|
19670
19798
|
import { lstatSync, rmSync as rmSync7 } from "node:fs";
|
|
19671
|
-
import { join as
|
|
19799
|
+
import { join as join12 } from "node:path";
|
|
19672
19800
|
function systemPromptPath(sessionId) {
|
|
19673
19801
|
if (!SESSION_ID_RE.test(sessionId)) throw new Error("invalid session id");
|
|
19674
|
-
return
|
|
19802
|
+
return join12(SYSTEM_PROMPT_DIR, `${sessionId}.md`);
|
|
19675
19803
|
}
|
|
19676
19804
|
function isDirectDirectory(path) {
|
|
19677
19805
|
try {
|
|
@@ -19691,7 +19819,7 @@ function pathAbsent(path) {
|
|
|
19691
19819
|
}
|
|
19692
19820
|
function unlinkDirectChild(parent, filename) {
|
|
19693
19821
|
if (!isDirectDirectory(parent)) return pathAbsent(parent);
|
|
19694
|
-
const child =
|
|
19822
|
+
const child = join12(parent, filename);
|
|
19695
19823
|
try {
|
|
19696
19824
|
rmSync7(child, { force: true });
|
|
19697
19825
|
} catch {
|
|
@@ -19701,12 +19829,12 @@ function unlinkDirectChild(parent, filename) {
|
|
|
19701
19829
|
}
|
|
19702
19830
|
function cleanupAdoptionSessionFiles(projectDir, sessionId) {
|
|
19703
19831
|
if (!SESSION_ID_RE.test(sessionId)) return false;
|
|
19704
|
-
const frizzDir =
|
|
19832
|
+
const frizzDir = join12(projectDir, ".frizz");
|
|
19705
19833
|
let clean = true;
|
|
19706
19834
|
if (isDirectDirectory(frizzDir)) {
|
|
19707
|
-
const threads =
|
|
19835
|
+
const threads = join12(frizzDir, "threads");
|
|
19708
19836
|
if (isDirectDirectory(threads)) {
|
|
19709
|
-
const child =
|
|
19837
|
+
const child = join12(threads, sessionId);
|
|
19710
19838
|
try {
|
|
19711
19839
|
rmSync7(child, { recursive: true, force: true });
|
|
19712
19840
|
} catch {
|
|
@@ -19958,10 +20086,10 @@ var init_adoption_recovery = __esm({
|
|
|
19958
20086
|
});
|
|
19959
20087
|
|
|
19960
20088
|
// packages/server/src/backend/codex-models.ts
|
|
19961
|
-
import { join as
|
|
19962
|
-
import { readFileSync as
|
|
20089
|
+
import { join as join13 } from "node:path";
|
|
20090
|
+
import { readFileSync as readFileSync8 } from "node:fs";
|
|
19963
20091
|
function cachePath(codexHome) {
|
|
19964
|
-
return
|
|
20092
|
+
return join13(codexHome, "models_cache.json");
|
|
19965
20093
|
}
|
|
19966
20094
|
function toCodexModel(raw2) {
|
|
19967
20095
|
if (!raw2 || typeof raw2 !== "object") return void 0;
|
|
@@ -19997,7 +20125,7 @@ function readCodexModels(codexHome = defaultCodexHome()) {
|
|
|
19997
20125
|
if (hit && now - hit.at < TTL_MS) return hit.models;
|
|
19998
20126
|
let models;
|
|
19999
20127
|
try {
|
|
20000
|
-
models = parseCodexModelsCache(
|
|
20128
|
+
models = parseCodexModelsCache(readFileSync8(path, "utf8"));
|
|
20001
20129
|
} catch {
|
|
20002
20130
|
models = CODEX_MODELS_FALLBACK;
|
|
20003
20131
|
}
|
|
@@ -20539,10 +20667,10 @@ var init_claude_agent_sdk_protocol = __esm({
|
|
|
20539
20667
|
});
|
|
20540
20668
|
|
|
20541
20669
|
// packages/server/src/backend/claude-broker-diagnostics.ts
|
|
20542
|
-
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync8, readFileSync as
|
|
20543
|
-
import { join as
|
|
20670
|
+
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync8, readFileSync as readFileSync9, renameSync as renameSync6, statSync as statSync5 } from "node:fs";
|
|
20671
|
+
import { join as join14 } from "node:path";
|
|
20544
20672
|
function claudeBrokerDiagnosticLogPath(stateDir, sessionId) {
|
|
20545
|
-
return
|
|
20673
|
+
return join14(stateDir, "claude-broker", `${sessionId}.diagnostics.log`);
|
|
20546
20674
|
}
|
|
20547
20675
|
function readClaudeBrokerExit(stateDir, sessionId, generation) {
|
|
20548
20676
|
if (!generation) return null;
|
|
@@ -20550,7 +20678,7 @@ function readClaudeBrokerExit(stateDir, sessionId, generation) {
|
|
|
20550
20678
|
for (const path of [`${claudeBrokerDiagnosticLogPath(stateDir, sessionId)}.1`, claudeBrokerDiagnosticLogPath(stateDir, sessionId)]) {
|
|
20551
20679
|
let text;
|
|
20552
20680
|
try {
|
|
20553
|
-
text =
|
|
20681
|
+
text = readFileSync9(path, "utf8");
|
|
20554
20682
|
} catch {
|
|
20555
20683
|
continue;
|
|
20556
20684
|
}
|
|
@@ -20614,10 +20742,10 @@ var init_detached_daemons = __esm({
|
|
|
20614
20742
|
});
|
|
20615
20743
|
|
|
20616
20744
|
// packages/server/src/backend/ipc-path.ts
|
|
20617
|
-
import { join as
|
|
20745
|
+
import { join as join15 } from "node:path";
|
|
20618
20746
|
function frizzIpcPath(name) {
|
|
20619
20747
|
if (process.platform === "win32") return `\\\\.\\pipe\\${name}`;
|
|
20620
|
-
return
|
|
20748
|
+
return join15(process.env.TMPDIR ?? "/tmp", `${name}.sock`);
|
|
20621
20749
|
}
|
|
20622
20750
|
var init_ipc_path = __esm({
|
|
20623
20751
|
"packages/server/src/backend/ipc-path.ts"() {
|
|
@@ -20628,18 +20756,18 @@ var init_ipc_path = __esm({
|
|
|
20628
20756
|
// packages/server/src/backend/claude-broker-host.ts
|
|
20629
20757
|
import { spawn } from "node:child_process";
|
|
20630
20758
|
import { createHash as createHash5, randomUUID as randomUUID8 } from "node:crypto";
|
|
20631
|
-
import { accessSync, constants as fsConstants, mkdirSync as mkdirSync9, readFileSync as
|
|
20632
|
-
import { delimiter, dirname as dirname8, isAbsolute as isAbsolute2, join as
|
|
20759
|
+
import { accessSync, constants as fsConstants, mkdirSync as mkdirSync9, readFileSync as readFileSync10, readdirSync as readdirSync4, unlinkSync, writeFileSync as writeFileSync7 } from "node:fs";
|
|
20760
|
+
import { delimiter, dirname as dirname8, isAbsolute as isAbsolute2, join as join16 } from "node:path";
|
|
20633
20761
|
function windowsShimTarget(shimPath) {
|
|
20634
20762
|
let body;
|
|
20635
20763
|
try {
|
|
20636
|
-
body =
|
|
20764
|
+
body = readFileSync10(shimPath, "utf8");
|
|
20637
20765
|
} catch {
|
|
20638
20766
|
return void 0;
|
|
20639
20767
|
}
|
|
20640
20768
|
const target = WINDOWS_SHIM_TARGET.exec(body)?.[1];
|
|
20641
20769
|
if (!target) return void 0;
|
|
20642
|
-
const full =
|
|
20770
|
+
const full = join16(dirname8(shimPath), target);
|
|
20643
20771
|
try {
|
|
20644
20772
|
accessSync(full, fsConstants.F_OK);
|
|
20645
20773
|
return full;
|
|
@@ -20660,17 +20788,17 @@ function resolveClaudeExecutableAbsolute(bin, env = process.env) {
|
|
|
20660
20788
|
for (const dir of searchPath(env).split(delimiter)) {
|
|
20661
20789
|
if (!dir) continue;
|
|
20662
20790
|
if (windows) {
|
|
20663
|
-
const exe =
|
|
20791
|
+
const exe = join16(dir, `${candidate}.exe`);
|
|
20664
20792
|
try {
|
|
20665
20793
|
accessSync(exe, fsConstants.F_OK);
|
|
20666
20794
|
return exe;
|
|
20667
20795
|
} catch {
|
|
20668
20796
|
}
|
|
20669
|
-
const viaShim = windowsShimTarget(
|
|
20797
|
+
const viaShim = windowsShimTarget(join16(dir, `${candidate}.cmd`));
|
|
20670
20798
|
if (viaShim) return viaShim;
|
|
20671
20799
|
continue;
|
|
20672
20800
|
}
|
|
20673
|
-
const full =
|
|
20801
|
+
const full = join16(dir, candidate);
|
|
20674
20802
|
try {
|
|
20675
20803
|
accessSync(full, fsConstants.X_OK);
|
|
20676
20804
|
return full;
|
|
@@ -20685,11 +20813,11 @@ function claudeBrokerSocketPath(stateDir, sessionId) {
|
|
|
20685
20813
|
}
|
|
20686
20814
|
function claudeBrokerRecordPath(stateDir, sessionId) {
|
|
20687
20815
|
const key = createHash5("sha256").update(sessionId).digest("hex").slice(0, 16);
|
|
20688
|
-
return
|
|
20816
|
+
return join16(stateDir, "claude-broker", `${key}.json`);
|
|
20689
20817
|
}
|
|
20690
20818
|
function claudeBrokerRetirementPath(stateDir, sessionId) {
|
|
20691
20819
|
const key = createHash5("sha256").update(sessionId).digest("hex").slice(0, 16);
|
|
20692
|
-
return
|
|
20820
|
+
return join16(stateDir, "claude-broker", `${key}.retired`);
|
|
20693
20821
|
}
|
|
20694
20822
|
function markBrokerRetired(stateDir, sessionId, reason, generation) {
|
|
20695
20823
|
const mark = { at: (/* @__PURE__ */ new Date()).toISOString(), generation, reason };
|
|
@@ -20704,7 +20832,7 @@ function takeBrokerRetirement(stateDir, sessionId) {
|
|
|
20704
20832
|
const path = claudeBrokerRetirementPath(stateDir, sessionId);
|
|
20705
20833
|
let mark = null;
|
|
20706
20834
|
try {
|
|
20707
|
-
const parsed = JSON.parse(
|
|
20835
|
+
const parsed = JSON.parse(readFileSync10(path, "utf8"));
|
|
20708
20836
|
if (typeof parsed?.at === "string" && typeof parsed.generation === "string" && typeof parsed.reason === "string") {
|
|
20709
20837
|
mark = { at: parsed.at, generation: parsed.generation, reason: parsed.reason };
|
|
20710
20838
|
}
|
|
@@ -20726,7 +20854,7 @@ function pidAlive(pid) {
|
|
|
20726
20854
|
}
|
|
20727
20855
|
function readBrokerRecord(recordPath2) {
|
|
20728
20856
|
try {
|
|
20729
|
-
return JSON.parse(
|
|
20857
|
+
return JSON.parse(readFileSync10(recordPath2, "utf8"));
|
|
20730
20858
|
} catch {
|
|
20731
20859
|
return null;
|
|
20732
20860
|
}
|
|
@@ -20756,7 +20884,7 @@ function liveBrokerRecord(recordPath2) {
|
|
|
20756
20884
|
return null;
|
|
20757
20885
|
}
|
|
20758
20886
|
function liveBrokerRecords(stateDir) {
|
|
20759
|
-
const dir =
|
|
20887
|
+
const dir = join16(stateDir, "claude-broker");
|
|
20760
20888
|
let names;
|
|
20761
20889
|
try {
|
|
20762
20890
|
names = readdirSync4(dir);
|
|
@@ -20766,7 +20894,7 @@ function liveBrokerRecords(stateDir) {
|
|
|
20766
20894
|
const out = [];
|
|
20767
20895
|
for (const name of names) {
|
|
20768
20896
|
if (!name.endsWith(".json")) continue;
|
|
20769
|
-
const record = liveBrokerRecord(
|
|
20897
|
+
const record = liveBrokerRecord(join16(dir, name));
|
|
20770
20898
|
if (record) out.push(record);
|
|
20771
20899
|
}
|
|
20772
20900
|
return out;
|
|
@@ -21574,15 +21702,15 @@ var init_completion_relay = __esm({
|
|
|
21574
21702
|
|
|
21575
21703
|
// packages/server/src/tail-cache.ts
|
|
21576
21704
|
import { createHash as createHash6 } from "node:crypto";
|
|
21577
|
-
import { closeSync as closeSync8, openSync as openSync9, readFileSync as
|
|
21578
|
-
import { join as
|
|
21705
|
+
import { closeSync as closeSync8, openSync as openSync9, readFileSync as readFileSync11, readSync as readSync3, statSync as statSync7 } from "node:fs";
|
|
21706
|
+
import { join as join17 } from "node:path";
|
|
21579
21707
|
function foldSchemaDigest(dir = import.meta.dirname) {
|
|
21580
21708
|
if (foldSchemaMemo) return foldSchemaMemo;
|
|
21581
21709
|
const hash = createHash6("sha256").update("frizz-tail-state-v1\0");
|
|
21582
21710
|
let read = 0;
|
|
21583
21711
|
for (const name of FOLD_SOURCES) {
|
|
21584
21712
|
try {
|
|
21585
|
-
hash.update(name).update("\0").update(
|
|
21713
|
+
hash.update(name).update("\0").update(readFileSync11(join17(dir, name)));
|
|
21586
21714
|
read++;
|
|
21587
21715
|
} catch {
|
|
21588
21716
|
hash.update(name).update("\0missing\0");
|
|
@@ -21778,9 +21906,9 @@ var init_tail_cache = __esm({
|
|
|
21778
21906
|
});
|
|
21779
21907
|
|
|
21780
21908
|
// packages/server/src/tailer.ts
|
|
21781
|
-
import { statSync as statSync8, openSync as openSync10, readSync as readSync4, closeSync as closeSync9, readdirSync as readdirSync5, realpathSync as realpathSync5, mkdirSync as mkdirSync10, writeFileSync as writeFileSync8, readFileSync as
|
|
21909
|
+
import { statSync as statSync8, openSync as openSync10, readSync as readSync4, closeSync as closeSync9, readdirSync as readdirSync5, realpathSync as realpathSync5, mkdirSync as mkdirSync10, writeFileSync as writeFileSync8, readFileSync as readFileSync12, existsSync as existsSync5 } from "node:fs";
|
|
21782
21910
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
21783
|
-
import { basename as basename4, join as
|
|
21911
|
+
import { basename as basename4, join as join18 } from "node:path";
|
|
21784
21912
|
import { homedir as homedir7 } from "node:os";
|
|
21785
21913
|
function probeShellAlive(outputFile) {
|
|
21786
21914
|
if (!existsSync5(outputFile)) return void 0;
|
|
@@ -22042,7 +22170,7 @@ function launchTaskId(text) {
|
|
|
22042
22170
|
function readDescendantSidecars(sessionDir, mtimeMs) {
|
|
22043
22171
|
let names;
|
|
22044
22172
|
try {
|
|
22045
|
-
names = readdirSync5(
|
|
22173
|
+
names = readdirSync5(join18(sessionDir, "subagents"));
|
|
22046
22174
|
} catch {
|
|
22047
22175
|
return [];
|
|
22048
22176
|
}
|
|
@@ -22053,7 +22181,7 @@ function readDescendantSidecars(sessionDir, mtimeMs) {
|
|
|
22053
22181
|
if (!agentId) continue;
|
|
22054
22182
|
let parsed;
|
|
22055
22183
|
try {
|
|
22056
|
-
parsed = JSON.parse(
|
|
22184
|
+
parsed = JSON.parse(readFileSync12(join18(sessionDir, "subagents", name), "utf8"));
|
|
22057
22185
|
} catch {
|
|
22058
22186
|
continue;
|
|
22059
22187
|
}
|
|
@@ -22067,7 +22195,7 @@ function readDescendantSidecars(sessionDir, mtimeMs) {
|
|
|
22067
22195
|
agentType: text(meta.agentType),
|
|
22068
22196
|
parentAgentId: text(meta.parentAgentId),
|
|
22069
22197
|
spawnDepth: typeof meta.spawnDepth === "number" && Number.isFinite(meta.spawnDepth) ? meta.spawnDepth : void 0,
|
|
22070
|
-
spawnedAtMs: mtimeMs(
|
|
22198
|
+
spawnedAtMs: mtimeMs(join18(sessionDir, "subagents", name))
|
|
22071
22199
|
});
|
|
22072
22200
|
}
|
|
22073
22201
|
return out;
|
|
@@ -22547,13 +22675,13 @@ function defaultMtimeMs(path) {
|
|
|
22547
22675
|
}
|
|
22548
22676
|
}
|
|
22549
22677
|
function defaultLogDir(project) {
|
|
22550
|
-
return
|
|
22678
|
+
return join18(homedir7(), ".claude", "projects", project.cwdSlug);
|
|
22551
22679
|
}
|
|
22552
22680
|
function defaultReadPermMarker(project) {
|
|
22553
22681
|
if (!project.stateDir) return () => void 0;
|
|
22554
22682
|
return (slug) => {
|
|
22555
22683
|
try {
|
|
22556
|
-
const parsed = JSON.parse(
|
|
22684
|
+
const parsed = JSON.parse(readFileSync12(permMarkerPath(project, slug), "utf8"));
|
|
22557
22685
|
return isPermMarker(parsed) ? parsed : void 0;
|
|
22558
22686
|
} catch {
|
|
22559
22687
|
return void 0;
|
|
@@ -22593,6 +22721,7 @@ function rowIsArchived(row) {
|
|
|
22593
22721
|
}
|
|
22594
22722
|
function createTailer(deps) {
|
|
22595
22723
|
const now = deps.now ?? Date.now;
|
|
22724
|
+
const monotonicNow = deps.monotonicNow ?? (() => performance.now());
|
|
22596
22725
|
const paneDead = deps.paneDead ?? (() => true);
|
|
22597
22726
|
const brokerDaemonAlive = deps.brokerDaemonAlive ?? defaultBrokerDaemonAlive(deps.project, now);
|
|
22598
22727
|
const logDir = deps.sessionLogDir ?? defaultLogDir(deps.project);
|
|
@@ -22678,7 +22807,7 @@ function createTailer(deps) {
|
|
|
22678
22807
|
return paneDead(row.slug);
|
|
22679
22808
|
}
|
|
22680
22809
|
const defaultBackend = {
|
|
22681
|
-
transcriptPath: (sessionId) =>
|
|
22810
|
+
transcriptPath: (sessionId) => join18(logDir, `${sessionId}.jsonl`),
|
|
22682
22811
|
foldLine: (state, line) => {
|
|
22683
22812
|
const rec = parseLine(line);
|
|
22684
22813
|
if (rec) applyRecord(state, rec);
|
|
@@ -22803,7 +22932,7 @@ ${ask}`;
|
|
|
22803
22932
|
return state.path.replace(/\.jsonl$/, "");
|
|
22804
22933
|
}
|
|
22805
22934
|
function descendantSidecars(state) {
|
|
22806
|
-
const at = mtimeMs(
|
|
22935
|
+
const at = mtimeMs(join18(sessionDirOf(state), "subagents"));
|
|
22807
22936
|
const cached2 = descendantIndex.get(state.slug);
|
|
22808
22937
|
if (cached2 && cached2.at === at) return cached2.all;
|
|
22809
22938
|
const all = readDescendantSidecars(sessionDirOf(state), mtimeMs);
|
|
@@ -22817,7 +22946,7 @@ ${ask}`;
|
|
|
22817
22946
|
return descendantIndex.get(state.slug)?.byToolUse.get(id);
|
|
22818
22947
|
}
|
|
22819
22948
|
function descendantTranscript(state, meta) {
|
|
22820
|
-
return
|
|
22949
|
+
return join18(sessionDirOf(state), "subagents", `agent-${meta.agentId}.jsonl`);
|
|
22821
22950
|
}
|
|
22822
22951
|
function subAgentDescendantTasks(slug, id) {
|
|
22823
22952
|
const state = states.get(slug);
|
|
@@ -23131,7 +23260,7 @@ ${ask}`;
|
|
|
23131
23260
|
if (name.startsWith(".") || !name.endsWith(".jsonl")) continue;
|
|
23132
23261
|
const id = name.slice(0, -".jsonl".length);
|
|
23133
23262
|
if (!id || registered.has(id)) continue;
|
|
23134
|
-
const path =
|
|
23263
|
+
const path = join18(logDir, name);
|
|
23135
23264
|
let mtime;
|
|
23136
23265
|
try {
|
|
23137
23266
|
mtime = statSync8(path).mtimeMs;
|
|
@@ -23403,7 +23532,7 @@ ${ask}`;
|
|
|
23403
23532
|
);
|
|
23404
23533
|
try {
|
|
23405
23534
|
mkdirSync10(stallLogDir, { recursive: true });
|
|
23406
|
-
writeFileSync8(
|
|
23535
|
+
writeFileSync8(join18(stallLogDir, `${row.slug}.stall.log`), `session_id: ${row.session_id}
|
|
23407
23536
|
captured_at: ${new Date(now()).toISOString()}
|
|
23408
23537
|
|
|
23409
23538
|
${detail}
|
|
@@ -23431,7 +23560,7 @@ ${detail}
|
|
|
23431
23560
|
state.nextDiscoverMs = nowMs + DISCOVER_RETRY_MS;
|
|
23432
23561
|
const strandedDir = discoverTranscriptDir(logDir, row.session_id);
|
|
23433
23562
|
if (strandedDir) {
|
|
23434
|
-
state.path =
|
|
23563
|
+
state.path = join18(strandedDir, `${row.session_id}.jsonl`);
|
|
23435
23564
|
state.offset = 0;
|
|
23436
23565
|
state.partial = "";
|
|
23437
23566
|
state.primed = false;
|
|
@@ -23454,7 +23583,7 @@ ${detail}
|
|
|
23454
23583
|
committed = false;
|
|
23455
23584
|
}
|
|
23456
23585
|
if (!committed) return false;
|
|
23457
|
-
state.path =
|
|
23586
|
+
state.path = join18(logDir, `${found}.jsonl`);
|
|
23458
23587
|
state.offset = 0;
|
|
23459
23588
|
state.partial = "";
|
|
23460
23589
|
state.primed = false;
|
|
@@ -23490,7 +23619,7 @@ ${detail}
|
|
|
23490
23619
|
}
|
|
23491
23620
|
let primed = 0;
|
|
23492
23621
|
let primedRows = 0;
|
|
23493
|
-
const tickStartedMs =
|
|
23622
|
+
const tickStartedMs = monotonicNow();
|
|
23494
23623
|
primeIncomplete = false;
|
|
23495
23624
|
for (const row of rows) {
|
|
23496
23625
|
if (primeProgress && primed % PRIME_PROGRESS_EVERY === 0) primeProgress(primed, rows.length);
|
|
@@ -23500,7 +23629,7 @@ ${detail}
|
|
|
23500
23629
|
let state = states.get(row.slug);
|
|
23501
23630
|
const runtimeGeneration = row.runtime_generation ?? 0;
|
|
23502
23631
|
if (!state || state.sessionId !== row.session_id || state.nativeSessionId !== nativeId || state.runtimeGeneration !== runtimeGeneration) {
|
|
23503
|
-
const path = backend.transcriptPath(nativeId) ??
|
|
23632
|
+
const path = backend.transcriptPath(nativeId) ?? join18(logDir, `${nativeId}.jsonl`);
|
|
23504
23633
|
state = newTailState(row.slug, row.session_id, path, false, nativeId, runtimeGeneration);
|
|
23505
23634
|
state.dismissedOps = deps.storage.retiredOps(row.slug, row.session_id);
|
|
23506
23635
|
hydrateFromCache(state, row, nativeId);
|
|
@@ -23518,7 +23647,7 @@ ${detail}
|
|
|
23518
23647
|
// guarantee below. `primedRows > 0` keeps the archive advancing by at least one row per tick
|
|
23519
23648
|
// even if a visible row were somehow to stay cold indefinitely, so deferral can never become
|
|
23520
23649
|
// starvation. The visible row still primes on this same tick; it just is not necessarily first.
|
|
23521
|
-
coldVisibleRow && primedRows > 0 && rowIsArchived(row) || primedRows >= MAX_PRIME_ROWS_PER_TICK || primedRows > 0 &&
|
|
23650
|
+
coldVisibleRow && primedRows > 0 && rowIsArchived(row) || primedRows >= MAX_PRIME_ROWS_PER_TICK || primedRows > 0 && monotonicNow() - tickStartedMs > PRIME_BUDGET_MS
|
|
23522
23651
|
) {
|
|
23523
23652
|
primeIncomplete = true;
|
|
23524
23653
|
continue;
|
|
@@ -23721,11 +23850,11 @@ ${detail}
|
|
|
23721
23850
|
let lastTickMs = 0;
|
|
23722
23851
|
let primeIncomplete = false;
|
|
23723
23852
|
function tickWithBudget() {
|
|
23724
|
-
const started =
|
|
23853
|
+
const started = monotonicNow();
|
|
23725
23854
|
try {
|
|
23726
23855
|
tick();
|
|
23727
23856
|
} finally {
|
|
23728
|
-
const elapsed =
|
|
23857
|
+
const elapsed = monotonicNow() - started;
|
|
23729
23858
|
lastTickMs = elapsed;
|
|
23730
23859
|
lastTickEndedAtMs = now();
|
|
23731
23860
|
if (elapsed > POLL_MS2) {
|
|
@@ -23949,14 +24078,14 @@ var init_tailer = __esm({
|
|
|
23949
24078
|
});
|
|
23950
24079
|
|
|
23951
24080
|
// packages/server/src/backend/codex.ts
|
|
23952
|
-
import { join as
|
|
24081
|
+
import { join as join19 } from "node:path";
|
|
23953
24082
|
import { homedir as homedir8 } from "node:os";
|
|
23954
|
-
import { readdirSync as readdirSync6, statSync as statSync9, readFileSync as
|
|
24083
|
+
import { readdirSync as readdirSync6, statSync as statSync9, readFileSync as readFileSync13, openSync as openSync11, readSync as readSync5, closeSync as closeSync10 } from "node:fs";
|
|
23955
24084
|
function defaultCodexHome() {
|
|
23956
|
-
return process.env.CODEX_HOME && process.env.CODEX_HOME.trim() ? process.env.CODEX_HOME :
|
|
24085
|
+
return process.env.CODEX_HOME && process.env.CODEX_HOME.trim() ? process.env.CODEX_HOME : join19(homedir8(), ".codex");
|
|
23957
24086
|
}
|
|
23958
24087
|
function sessionsDir(codexHome) {
|
|
23959
|
-
return
|
|
24088
|
+
return join19(codexHome, "sessions");
|
|
23960
24089
|
}
|
|
23961
24090
|
function codexSandbox(mode) {
|
|
23962
24091
|
switch (mode) {
|
|
@@ -24337,17 +24466,17 @@ function collectRollouts(dir, out, budget) {
|
|
|
24337
24466
|
const files = entries.filter((e) => e.isFile() && e.name.startsWith("rollout-") && e.name.endsWith(".jsonl")).sort(descByName);
|
|
24338
24467
|
for (const d of dirs) {
|
|
24339
24468
|
if (budget.n <= 0) return;
|
|
24340
|
-
collectRollouts(
|
|
24469
|
+
collectRollouts(join19(dir, d.name), out, budget);
|
|
24341
24470
|
}
|
|
24342
24471
|
for (const f of files) {
|
|
24343
24472
|
if (budget.n <= 0) return;
|
|
24344
24473
|
let mtimeMs;
|
|
24345
24474
|
try {
|
|
24346
|
-
mtimeMs = statSync9(
|
|
24475
|
+
mtimeMs = statSync9(join19(dir, f.name)).mtimeMs;
|
|
24347
24476
|
} catch {
|
|
24348
24477
|
continue;
|
|
24349
24478
|
}
|
|
24350
|
-
out.push({ path:
|
|
24479
|
+
out.push({ path: join19(dir, f.name), mtimeMs });
|
|
24351
24480
|
budget.n--;
|
|
24352
24481
|
}
|
|
24353
24482
|
}
|
|
@@ -24391,9 +24520,9 @@ function readCodexThreadNames(codexHome = defaultCodexHome()) {
|
|
|
24391
24520
|
const out = /* @__PURE__ */ new Map();
|
|
24392
24521
|
let raw2;
|
|
24393
24522
|
try {
|
|
24394
|
-
const path =
|
|
24523
|
+
const path = join19(codexHome, "session_index.jsonl");
|
|
24395
24524
|
if (statSync9(path).size > SESSION_INDEX_MAX_BYTES) return out;
|
|
24396
|
-
raw2 =
|
|
24525
|
+
raw2 = readFileSync13(path, "utf8");
|
|
24397
24526
|
} catch {
|
|
24398
24527
|
return out;
|
|
24399
24528
|
}
|
|
@@ -28429,16 +28558,16 @@ var init_wrapper = __esm({
|
|
|
28429
28558
|
|
|
28430
28559
|
// packages/server/src/worker-plugin-dir.ts
|
|
28431
28560
|
import { existsSync as existsSync6 } from "node:fs";
|
|
28432
|
-
import { dirname as dirname9, join as
|
|
28561
|
+
import { dirname as dirname9, join as join20 } from "node:path";
|
|
28433
28562
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
28434
28563
|
function resolveWorkerPluginDir(moduleUrl = import.meta.url, env = process.env) {
|
|
28435
28564
|
const override = env.FRIZZ_WORKER_PLUGIN_DIR;
|
|
28436
|
-
if (override && existsSync6(
|
|
28565
|
+
if (override && existsSync6(join20(override, ".claude-plugin", "plugin.json")))
|
|
28437
28566
|
return override;
|
|
28438
28567
|
let current = dirname9(fileURLToPath2(moduleUrl));
|
|
28439
28568
|
for (; ; ) {
|
|
28440
|
-
const candidate =
|
|
28441
|
-
if (existsSync6(
|
|
28569
|
+
const candidate = join20(current, "cc-worker");
|
|
28570
|
+
if (existsSync6(join20(candidate, ".claude-plugin", "plugin.json"))) return candidate;
|
|
28442
28571
|
const parent = dirname9(current);
|
|
28443
28572
|
if (parent === current) return void 0;
|
|
28444
28573
|
current = parent;
|
|
@@ -28452,7 +28581,7 @@ var init_worker_plugin_dir = __esm({
|
|
|
28452
28581
|
|
|
28453
28582
|
// packages/server/src/backend/types.ts
|
|
28454
28583
|
import { existsSync as existsSync7 } from "node:fs";
|
|
28455
|
-
import { join as
|
|
28584
|
+
import { join as join21 } from "node:path";
|
|
28456
28585
|
function frizzMcpEnv(mcp) {
|
|
28457
28586
|
return {
|
|
28458
28587
|
FRIZZ_STATE_DIR: mcp.stateDir,
|
|
@@ -28476,7 +28605,7 @@ function chromeDevtoolsMcpMount() {
|
|
|
28476
28605
|
function resolveBrowserMcpScript(moduleUrl = import.meta.url, env = process.env) {
|
|
28477
28606
|
const pluginDir = resolveWorkerPluginDir(moduleUrl, env);
|
|
28478
28607
|
if (!pluginDir) return void 0;
|
|
28479
|
-
const scriptPath =
|
|
28608
|
+
const scriptPath = join21(pluginDir, "bin", CHROME_DEVTOOLS_MCP.script);
|
|
28480
28609
|
return existsSync7(scriptPath) ? scriptPath : void 0;
|
|
28481
28610
|
}
|
|
28482
28611
|
function workerCap(name, lifted, env) {
|
|
@@ -28574,15 +28703,15 @@ import { spawn as spawn2 } from "node:child_process";
|
|
|
28574
28703
|
import { connect } from "node:net";
|
|
28575
28704
|
import { Agent as HttpAgent } from "node:http";
|
|
28576
28705
|
import { createHash as createHash7, randomUUID as randomUUID9 } from "node:crypto";
|
|
28577
|
-
import { existsSync as existsSync8, mkdirSync as mkdirSync11, readFileSync as
|
|
28578
|
-
import { join as
|
|
28706
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync11, readFileSync as readFileSync14, unlinkSync as unlinkSync2, writeFileSync as writeFileSync9 } from "node:fs";
|
|
28707
|
+
import { join as join22 } from "node:path";
|
|
28579
28708
|
import { PassThrough, Writable } from "node:stream";
|
|
28580
28709
|
import { StringDecoder } from "node:string_decoder";
|
|
28581
28710
|
function nativeDir(stateDir) {
|
|
28582
|
-
return
|
|
28711
|
+
return join22(stateDir, "codex-app-server-native");
|
|
28583
28712
|
}
|
|
28584
28713
|
function nativeRecordPath(stateDir, projectId) {
|
|
28585
|
-
return
|
|
28714
|
+
return join22(nativeDir(stateDir), `${projectId}.json`);
|
|
28586
28715
|
}
|
|
28587
28716
|
function nativeListenSocketPath(stateDir, projectId) {
|
|
28588
28717
|
const key = createHash7("sha256").update(stateDir).update("\0").update(projectId).digest("hex").slice(0, 16);
|
|
@@ -28598,7 +28727,7 @@ function pidAlive2(pid) {
|
|
|
28598
28727
|
}
|
|
28599
28728
|
function readNativeRecord(stateDir, projectId) {
|
|
28600
28729
|
try {
|
|
28601
|
-
const value = JSON.parse(
|
|
28730
|
+
const value = JSON.parse(readFileSync14(nativeRecordPath(stateDir, projectId), "utf8"));
|
|
28602
28731
|
if (typeof value.listenerPid !== "number" || typeof value.socketPath !== "string" || typeof value.generation !== "string") return null;
|
|
28603
28732
|
return {
|
|
28604
28733
|
projectId,
|
|
@@ -28846,15 +28975,15 @@ var init_codex_app_server_native = __esm({
|
|
|
28846
28975
|
import { spawn as spawn3, spawnSync } from "node:child_process";
|
|
28847
28976
|
import { createConnection } from "node:net";
|
|
28848
28977
|
import { createHash as createHash8, randomUUID as randomUUID10 } from "node:crypto";
|
|
28849
|
-
import { existsSync as existsSync9, mkdirSync as mkdirSync12, readFileSync as
|
|
28850
|
-
import { join as
|
|
28978
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync12, readFileSync as readFileSync15, unlinkSync as unlinkSync3 } from "node:fs";
|
|
28979
|
+
import { join as join23 } from "node:path";
|
|
28851
28980
|
import { PassThrough as PassThrough2, Writable as Writable2 } from "node:stream";
|
|
28852
28981
|
import { StringDecoder as StringDecoder2 } from "node:string_decoder";
|
|
28853
28982
|
function daemonDir(stateDir) {
|
|
28854
|
-
return
|
|
28983
|
+
return join23(stateDir, "codex-app-server");
|
|
28855
28984
|
}
|
|
28856
28985
|
function recordPath(stateDir, projectId) {
|
|
28857
|
-
return
|
|
28986
|
+
return join23(daemonDir(stateDir), `${projectId}.json`);
|
|
28858
28987
|
}
|
|
28859
28988
|
function codexAppServerSocketPath(stateDir, projectId) {
|
|
28860
28989
|
const key = createHash8("sha256").update(stateDir).update("\0").update(projectId).digest("hex").slice(0, 16);
|
|
@@ -28870,7 +28999,7 @@ function pidAlive3(pid) {
|
|
|
28870
28999
|
}
|
|
28871
29000
|
function readDaemonRecord(stateDir, projectId) {
|
|
28872
29001
|
try {
|
|
28873
|
-
const value = JSON.parse(
|
|
29002
|
+
const value = JSON.parse(readFileSync15(recordPath(stateDir, projectId), "utf8"));
|
|
28874
29003
|
if (typeof value.daemonPid !== "number" || typeof value.socketPath !== "string" || typeof value.generation !== "string") return null;
|
|
28875
29004
|
return {
|
|
28876
29005
|
projectId,
|
|
@@ -28886,7 +29015,7 @@ function readDaemonRecord(stateDir, projectId) {
|
|
|
28886
29015
|
}
|
|
28887
29016
|
function readDaemonExitBreadcrumb(stateDir, projectId) {
|
|
28888
29017
|
try {
|
|
28889
|
-
const value = JSON.parse(
|
|
29018
|
+
const value = JSON.parse(readFileSync15(`${recordPath(stateDir, projectId)}.exit`, "utf8"));
|
|
28890
29019
|
if (typeof value.generation !== "string" || typeof value.reason !== "string") return null;
|
|
28891
29020
|
return {
|
|
28892
29021
|
generation: value.generation,
|
|
@@ -32082,11 +32211,11 @@ var init_codex_app_server = __esm({
|
|
|
32082
32211
|
});
|
|
32083
32212
|
|
|
32084
32213
|
// packages/server/src/backend/codex-quota.ts
|
|
32085
|
-
import { join as
|
|
32214
|
+
import { join as join24 } from "node:path";
|
|
32086
32215
|
import { readdirSync as readdirSync7, statSync as statSync10, openSync as openSync12, readSync as readSync6, fstatSync, closeSync as closeSync11 } from "node:fs";
|
|
32087
32216
|
import { spawn as spawn4 } from "node:child_process";
|
|
32088
32217
|
function sessionsDir2(codexHome) {
|
|
32089
|
-
return
|
|
32218
|
+
return join24(codexHome, "sessions");
|
|
32090
32219
|
}
|
|
32091
32220
|
function newestRollouts(dir, out, budget) {
|
|
32092
32221
|
if (budget.n <= 0) return;
|
|
@@ -32100,11 +32229,11 @@ function newestRollouts(dir, out, budget) {
|
|
|
32100
32229
|
const files = entries.filter((e) => e.isFile() && e.name.startsWith("rollout-") && e.name.endsWith(".jsonl")).map((e) => e.name).sort(descByName2);
|
|
32101
32230
|
for (const d of dirs) {
|
|
32102
32231
|
if (budget.n <= 0) return;
|
|
32103
|
-
newestRollouts(
|
|
32232
|
+
newestRollouts(join24(dir, d), out, budget);
|
|
32104
32233
|
}
|
|
32105
32234
|
for (const f of files) {
|
|
32106
32235
|
if (budget.n <= 0) return;
|
|
32107
|
-
out.push(
|
|
32236
|
+
out.push(join24(dir, f));
|
|
32108
32237
|
budget.n--;
|
|
32109
32238
|
}
|
|
32110
32239
|
}
|
|
@@ -32304,7 +32433,7 @@ var init_codex_quota = __esm({
|
|
|
32304
32433
|
});
|
|
32305
32434
|
|
|
32306
32435
|
// packages/server/src/backend/claude-quota.ts
|
|
32307
|
-
import { join as
|
|
32436
|
+
import { join as join25 } from "node:path";
|
|
32308
32437
|
import { homedir as homedir9, platform } from "node:os";
|
|
32309
32438
|
import { createHash as createHash10 } from "node:crypto";
|
|
32310
32439
|
import { mkdir, readFile, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
@@ -32312,7 +32441,7 @@ import { execFile as execFile2 } from "node:child_process";
|
|
|
32312
32441
|
import { promisify as promisify2 } from "node:util";
|
|
32313
32442
|
function claudeConfigDir() {
|
|
32314
32443
|
const override = process.env.CLAUDE_CONFIG_DIR;
|
|
32315
|
-
return override && override.trim() ? override :
|
|
32444
|
+
return override && override.trim() ? override : join25(homedir9(), ".claude");
|
|
32316
32445
|
}
|
|
32317
32446
|
function tokenFromCredentialsJson(raw2) {
|
|
32318
32447
|
let doc;
|
|
@@ -32341,7 +32470,7 @@ async function readKeychainToken() {
|
|
|
32341
32470
|
}
|
|
32342
32471
|
async function readAccessToken(configDir) {
|
|
32343
32472
|
try {
|
|
32344
|
-
const fromFile = tokenFromCredentialsJson(await readFile(
|
|
32473
|
+
const fromFile = tokenFromCredentialsJson(await readFile(join25(configDir, ".credentials.json"), "utf8"));
|
|
32345
32474
|
if (fromFile) return fromFile;
|
|
32346
32475
|
} catch {
|
|
32347
32476
|
}
|
|
@@ -32410,8 +32539,8 @@ function parseClaudeUsage(body, planType) {
|
|
|
32410
32539
|
function cachePaths(cacheDir, configDir) {
|
|
32411
32540
|
const profile = createHash10("sha256").update(configDir).digest("hex").slice(0, 12);
|
|
32412
32541
|
return {
|
|
32413
|
-
data:
|
|
32414
|
-
lock:
|
|
32542
|
+
data: join25(cacheDir, `claude-${profile}.json`),
|
|
32543
|
+
lock: join25(cacheDir, `claude-${profile}.lock`)
|
|
32415
32544
|
};
|
|
32416
32545
|
}
|
|
32417
32546
|
async function readShared(path) {
|
|
@@ -32607,7 +32736,7 @@ function refreshSharedInBackground(paths, claudeBin, deps, now) {
|
|
|
32607
32736
|
async function refreshClaudeQuotaInBackground(claudeBin = "claude", deps = {}) {
|
|
32608
32737
|
const now = (deps.now ?? Date.now)();
|
|
32609
32738
|
const configDir = claudeConfigDir();
|
|
32610
|
-
const cacheDir = deps.cacheDir ??
|
|
32739
|
+
const cacheDir = deps.cacheDir ?? join25(frizzRoots().cache, "quota-cache");
|
|
32611
32740
|
try {
|
|
32612
32741
|
await mkdir(cacheDir, { recursive: true, mode: 448 });
|
|
32613
32742
|
} catch {
|
|
@@ -32618,7 +32747,7 @@ async function refreshClaudeQuotaInBackground(claudeBin = "claude", deps = {}) {
|
|
|
32618
32747
|
async function readClaudeQuota(claudeBin = "claude", deps = {}, options = {}) {
|
|
32619
32748
|
const now = (deps.now ?? Date.now)();
|
|
32620
32749
|
const configDir = claudeConfigDir();
|
|
32621
|
-
const cacheDir = deps.cacheDir ??
|
|
32750
|
+
const cacheDir = deps.cacheDir ?? join25(frizzRoots().cache, "quota-cache");
|
|
32622
32751
|
const paths = cachePaths(cacheDir, configDir);
|
|
32623
32752
|
try {
|
|
32624
32753
|
await mkdir(cacheDir, { recursive: true, mode: 448 });
|
|
@@ -32778,7 +32907,7 @@ var init_quota = __esm({
|
|
|
32778
32907
|
// packages/server/src/frizz.ts
|
|
32779
32908
|
import { execFile as execFile3 } from "node:child_process";
|
|
32780
32909
|
import { lstatSync as lstatSync2, realpathSync as realpathSync6 } from "node:fs";
|
|
32781
|
-
import { basename as basename5, dirname as dirname10, join as
|
|
32910
|
+
import { basename as basename5, dirname as dirname10, join as join26, resolve as resolve4 } from "node:path";
|
|
32782
32911
|
import { promisify as promisify3 } from "node:util";
|
|
32783
32912
|
function frizzScriptsDir() {
|
|
32784
32913
|
if (process.env.FRIZZ_SCRIPTS_DIR) return process.env.FRIZZ_SCRIPTS_DIR;
|
|
@@ -32787,7 +32916,7 @@ function frizzScriptsDir() {
|
|
|
32787
32916
|
function directFrizzRoot(projectDir) {
|
|
32788
32917
|
try {
|
|
32789
32918
|
const projectRoot = realpathSync6(projectDir);
|
|
32790
|
-
const path =
|
|
32919
|
+
const path = join26(projectRoot, ".frizz");
|
|
32791
32920
|
const stat2 = lstatSync2(path);
|
|
32792
32921
|
if (!stat2.isDirectory() || stat2.isSymbolicLink()) return null;
|
|
32793
32922
|
const real = realpathSync6(path);
|
|
@@ -32801,7 +32930,7 @@ function frizzDirExists(projectDir) {
|
|
|
32801
32930
|
}
|
|
32802
32931
|
async function readBoard(projectDir, scriptsDir = frizzScriptsDir()) {
|
|
32803
32932
|
if (!directFrizzRoot(projectDir)) throw new Error("unsafe or missing .frizz directory");
|
|
32804
|
-
const { stdout } = await execFileP("node", [
|
|
32933
|
+
const { stdout } = await execFileP("node", [join26(scriptsDir, "index.mjs"), "--json"], {
|
|
32805
32934
|
cwd: projectDir,
|
|
32806
32935
|
env: { ...process.env, CLAUDE_PROJECT_DIR: projectDir },
|
|
32807
32936
|
maxBuffer: 32 * 1024 * 1024
|
|
@@ -32826,7 +32955,7 @@ async function readBoard(projectDir, scriptsDir = frizzScriptsDir()) {
|
|
|
32826
32955
|
};
|
|
32827
32956
|
}
|
|
32828
32957
|
async function runThreadUpdate(projectDir, slug, args, scriptsDir = frizzScriptsDir()) {
|
|
32829
|
-
await execFileP("node", [
|
|
32958
|
+
await execFileP("node", [join26(scriptsDir, "thread-update.mjs"), slug, ...args], {
|
|
32830
32959
|
cwd: projectDir,
|
|
32831
32960
|
env: { ...process.env, CLAUDE_PROJECT_DIR: projectDir }
|
|
32832
32961
|
});
|
|
@@ -34711,19 +34840,19 @@ var init_claude_agent_broker_bridge = __esm({
|
|
|
34711
34840
|
});
|
|
34712
34841
|
|
|
34713
34842
|
// packages/server/src/backend/auth-status.ts
|
|
34714
|
-
import { join as
|
|
34843
|
+
import { join as join27 } from "node:path";
|
|
34715
34844
|
import { homedir as homedir11, platform as platform2 } from "node:os";
|
|
34716
|
-
import { readFileSync as
|
|
34845
|
+
import { readFileSync as readFileSync16, statSync as statSync11 } from "node:fs";
|
|
34717
34846
|
import { execFile as execFile4 } from "node:child_process";
|
|
34718
34847
|
import { promisify as promisify4 } from "node:util";
|
|
34719
34848
|
function claudeConfigDir2() {
|
|
34720
34849
|
const override = process.env.CLAUDE_CONFIG_DIR;
|
|
34721
|
-
return override && override.trim() ? override :
|
|
34850
|
+
return override && override.trim() ? override : join27(homedir11(), ".claude");
|
|
34722
34851
|
}
|
|
34723
34852
|
function claudeFileState(configDir) {
|
|
34724
34853
|
let raw2;
|
|
34725
34854
|
try {
|
|
34726
|
-
raw2 =
|
|
34855
|
+
raw2 = readFileSync16(join27(configDir, ".credentials.json"), "utf8");
|
|
34727
34856
|
} catch (err) {
|
|
34728
34857
|
return err.code === "ENOENT" ? "absent" : "error";
|
|
34729
34858
|
}
|
|
@@ -34756,7 +34885,7 @@ function readCodexAuthState(codexHome = defaultCodexHome()) {
|
|
|
34756
34885
|
if (process.env.OPENAI_API_KEY || process.env.CODEX_API_KEY || process.env.CODEX_ACCESS_TOKEN) return "authed";
|
|
34757
34886
|
let raw2;
|
|
34758
34887
|
try {
|
|
34759
|
-
raw2 =
|
|
34888
|
+
raw2 = readFileSync16(join27(codexHome, "auth.json"), "utf8");
|
|
34760
34889
|
} catch (err) {
|
|
34761
34890
|
return err.code === "ENOENT" ? "signed-out" : "unknown";
|
|
34762
34891
|
}
|
|
@@ -34821,7 +34950,7 @@ function asEmail(value) {
|
|
|
34821
34950
|
}
|
|
34822
34951
|
function claudeAccountFile() {
|
|
34823
34952
|
const override = process.env.CLAUDE_CONFIG_DIR;
|
|
34824
|
-
return override && override.trim() ?
|
|
34953
|
+
return override && override.trim() ? join27(override, ".claude.json") : join27(homedir11(), ".claude.json");
|
|
34825
34954
|
}
|
|
34826
34955
|
function readClaudeAccountEmail(path = claudeAccountFile()) {
|
|
34827
34956
|
let stat2;
|
|
@@ -34834,7 +34963,7 @@ function readClaudeAccountEmail(path = claudeAccountFile()) {
|
|
|
34834
34963
|
if (memo3 && memo3.path === path && memo3.mtimeMs === stat2.mtimeMs && memo3.size === stat2.size) return memo3.email;
|
|
34835
34964
|
let email;
|
|
34836
34965
|
try {
|
|
34837
|
-
const doc = JSON.parse(
|
|
34966
|
+
const doc = JSON.parse(readFileSync16(path, "utf8"));
|
|
34838
34967
|
email = asEmail(doc?.oauthAccount?.emailAddress);
|
|
34839
34968
|
} catch {
|
|
34840
34969
|
email = void 0;
|
|
@@ -34845,7 +34974,7 @@ function readClaudeAccountEmail(path = claudeAccountFile()) {
|
|
|
34845
34974
|
function readCodexAccountEmail(codexHome = defaultCodexHome()) {
|
|
34846
34975
|
let doc;
|
|
34847
34976
|
try {
|
|
34848
|
-
doc = JSON.parse(
|
|
34977
|
+
doc = JSON.parse(readFileSync16(join27(codexHome, "auth.json"), "utf8"));
|
|
34849
34978
|
} catch {
|
|
34850
34979
|
return void 0;
|
|
34851
34980
|
}
|
|
@@ -34913,8 +35042,8 @@ var init_auth_status = __esm({
|
|
|
34913
35042
|
});
|
|
34914
35043
|
|
|
34915
35044
|
// packages/server/src/dispatch.ts
|
|
34916
|
-
import { closeSync as closeSync12, constants, existsSync as existsSync10, fstatSync as fstatSync2, lstatSync as lstatSync3, openSync as openSync13, readFileSync as
|
|
34917
|
-
import { basename as basename6, join as
|
|
35045
|
+
import { closeSync as closeSync12, constants, existsSync as existsSync10, fstatSync as fstatSync2, lstatSync as lstatSync3, openSync as openSync13, readFileSync as readFileSync17, realpathSync as realpathSync7, statSync as statSync12, writeFileSync as writeFileSync10, mkdirSync as mkdirSync13, rmSync as rmSync8 } from "node:fs";
|
|
35046
|
+
import { basename as basename6, join as join28, dirname as dirname11 } from "node:path";
|
|
34918
35047
|
import { createHash as createHash11, randomUUID as randomUUID13 } from "node:crypto";
|
|
34919
35048
|
function fallbackTitle(prompt) {
|
|
34920
35049
|
const firstLine2 = prompt.trim().split("\n", 1)[0].trim();
|
|
@@ -34933,7 +35062,7 @@ function fallbackTitle(prompt) {
|
|
|
34933
35062
|
}
|
|
34934
35063
|
function resolveSlug(frizzDir, base, taken) {
|
|
34935
35064
|
base = ThreadSlug.parse(base);
|
|
34936
|
-
const isTaken = (slug) => existsSync10(
|
|
35065
|
+
const isTaken = (slug) => existsSync10(join28(frizzDir, `${slug}.md`)) || (taken?.(slug) ?? false);
|
|
34937
35066
|
if (!isTaken(base)) return base;
|
|
34938
35067
|
for (let n = 2; ; n++) {
|
|
34939
35068
|
const suffix = `-${n}`;
|
|
@@ -34950,12 +35079,12 @@ function resolveLegacyThreadFile(projectDir, value) {
|
|
|
34950
35079
|
if (!parsed.success) return null;
|
|
34951
35080
|
try {
|
|
34952
35081
|
const projectRoot = realpathSync7(projectDir);
|
|
34953
|
-
const frizzPath =
|
|
35082
|
+
const frizzPath = join28(projectRoot, ".frizz");
|
|
34954
35083
|
const frizzStat = lstatSync3(frizzPath);
|
|
34955
35084
|
if (!frizzStat.isDirectory() || frizzStat.isSymbolicLink()) return null;
|
|
34956
35085
|
const realFrizz = realpathSync7(frizzPath);
|
|
34957
35086
|
if (dirname11(realFrizz) !== projectRoot || basename6(realFrizz) !== ".frizz") return null;
|
|
34958
|
-
const path =
|
|
35087
|
+
const path = join28(realFrizz, `${parsed.data}.md`);
|
|
34959
35088
|
const before = lstatSync3(path);
|
|
34960
35089
|
if (!before.isFile() || before.isSymbolicLink()) return null;
|
|
34961
35090
|
const realPath = realpathSync7(path);
|
|
@@ -34966,7 +35095,7 @@ function resolveLegacyThreadFile(projectDir, value) {
|
|
|
34966
35095
|
const fd = openSync13(path, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
34967
35096
|
try {
|
|
34968
35097
|
openedBefore = fstatSync2(fd);
|
|
34969
|
-
contents =
|
|
35098
|
+
contents = readFileSync17(fd);
|
|
34970
35099
|
openedAfter = fstatSync2(fd);
|
|
34971
35100
|
} finally {
|
|
34972
35101
|
closeSync12(fd);
|
|
@@ -34999,7 +35128,7 @@ function boardAuthorizesAdoption(board, slug) {
|
|
|
34999
35128
|
return !board.errorItems.some((item) => item.file === `${slug}.md`);
|
|
35000
35129
|
}
|
|
35001
35130
|
function ensureSafeDirectDirectory(parent, name) {
|
|
35002
|
-
const path =
|
|
35131
|
+
const path = join28(parent, name);
|
|
35003
35132
|
try {
|
|
35004
35133
|
mkdirSync13(path);
|
|
35005
35134
|
} catch (error) {
|
|
@@ -35029,8 +35158,8 @@ function loadWorkerPrompt(kind = "claude") {
|
|
|
35029
35158
|
function monitorScriptsDir() {
|
|
35030
35159
|
const plugin = workerPluginDir();
|
|
35031
35160
|
if (!plugin) return void 0;
|
|
35032
|
-
const dir =
|
|
35033
|
-
return existsSync10(
|
|
35161
|
+
const dir = join28(plugin, "skills", "gh", "scripts");
|
|
35162
|
+
return existsSync10(join28(dir, "ci-watch.mjs")) ? dir : void 0;
|
|
35034
35163
|
}
|
|
35035
35164
|
function codexScratchpadHookConfig(hookScript, sessionId) {
|
|
35036
35165
|
if (!hookScript || !sessionId) return {};
|
|
@@ -35042,7 +35171,7 @@ function codexScratchpadHookConfig(hookScript, sessionId) {
|
|
|
35042
35171
|
}
|
|
35043
35172
|
]
|
|
35044
35173
|
});
|
|
35045
|
-
const bashBackgroundHook =
|
|
35174
|
+
const bashBackgroundHook = join28(dirname11(hookScript), "bash-background.mjs");
|
|
35046
35175
|
return {
|
|
35047
35176
|
bypass_hook_trust: true,
|
|
35048
35177
|
hooks: {
|
|
@@ -35068,7 +35197,7 @@ function codexScratchpadHookConfig(hookScript, sessionId) {
|
|
|
35068
35197
|
}
|
|
35069
35198
|
function scratchpadHookScript() {
|
|
35070
35199
|
const plugin = workerPluginDir();
|
|
35071
|
-
return plugin ?
|
|
35200
|
+
return plugin ? join28(plugin, "hooks", "scratchpad.mjs") : void 0;
|
|
35072
35201
|
}
|
|
35073
35202
|
function composePrompt(sessionId, prompt, kind = "claude") {
|
|
35074
35203
|
const children2 = kind === "codex" ? "Native sub-agents share it \u2014 have each write its OWN file rather than all editing one." : "Name it in a sub-agent's prompt when you want its notes to land somewhere you can read; give each child its OWN file rather than having them all edit one.";
|
|
@@ -35084,12 +35213,12 @@ function scratchpadOrientation(sessionId, kind = "claude") {
|
|
|
35084
35213
|
return `SCRATCH DIRECTORY: .frizz/threads/${sessionId}/ \u2014 yours, free-form, as many files as you like, and nothing is expected in it. A single direct task usually needs none; writing notes is never a substitute for doing the work. On a long effort write the doc you would want if you lost your context (${children2}), then arm mcp__frizz__recurring_prompt with post_compaction: true and a prompt LINKING that file \u2014 frizz hands the link back when your context is compacted. Nothing in this directory is read automatically.`;
|
|
35085
35214
|
}
|
|
35086
35215
|
function frizzConfigBlock(projectDir) {
|
|
35087
|
-
const path =
|
|
35216
|
+
const path = join28(projectDir, "FRIZZ.md");
|
|
35088
35217
|
let body;
|
|
35089
35218
|
try {
|
|
35090
35219
|
const st = statSync12(path);
|
|
35091
35220
|
if (!st.isFile() || st.size > FRIZZ_MD_MAX_BYTES) return "";
|
|
35092
|
-
body =
|
|
35221
|
+
body = readFileSync17(path, "utf8").trim();
|
|
35093
35222
|
} catch {
|
|
35094
35223
|
return "";
|
|
35095
35224
|
}
|
|
@@ -35124,7 +35253,7 @@ function resolveFrizzMcp(target, moduleUrl = import.meta.url, env = process.env,
|
|
|
35124
35253
|
const { stateDir, serverLock, projectId } = typeof target === "string" ? { stateDir: target } : target;
|
|
35125
35254
|
const pluginDir = resolveWorkerPluginDir(moduleUrl, env);
|
|
35126
35255
|
if (!pluginDir) return void 0;
|
|
35127
|
-
const scriptPath =
|
|
35256
|
+
const scriptPath = join28(pluginDir, "bin", FRIZZ_MCP.script);
|
|
35128
35257
|
if (!existsSync10(scriptPath)) return void 0;
|
|
35129
35258
|
return {
|
|
35130
35259
|
scriptPath,
|
|
@@ -35207,7 +35336,7 @@ function buildClaudeResumeCommand(opts) {
|
|
|
35207
35336
|
}
|
|
35208
35337
|
function createDispatcher(deps) {
|
|
35209
35338
|
const readBoardSource = deps.readBoard ?? readBoard;
|
|
35210
|
-
const frizzDir =
|
|
35339
|
+
const frizzDir = join28(deps.project.dir, ".frizz");
|
|
35211
35340
|
const adoptionRuntime = deps.adoptionRuntime ?? productionRuntime;
|
|
35212
35341
|
function cleanupPrewrites(built) {
|
|
35213
35342
|
for (const path of new Set(built.prewrite.map((file) => file.path))) {
|
|
@@ -35220,7 +35349,7 @@ function createDispatcher(deps) {
|
|
|
35220
35349
|
function cleanupDispatchFiles(scratchRel, built, sessionId) {
|
|
35221
35350
|
cleanupPrewrites(built);
|
|
35222
35351
|
try {
|
|
35223
|
-
rmSync8(
|
|
35352
|
+
rmSync8(join28(deps.project.dir, scratchRel), { force: true, recursive: true });
|
|
35224
35353
|
} catch {
|
|
35225
35354
|
}
|
|
35226
35355
|
cleanupAdoptionSessionFiles(deps.project.dir, sessionId);
|
|
@@ -35653,7 +35782,7 @@ import {
|
|
|
35653
35782
|
watch as fsWatch
|
|
35654
35783
|
} from "node:fs";
|
|
35655
35784
|
import { homedir as homedir12 } from "node:os";
|
|
35656
|
-
import { join as
|
|
35785
|
+
import { join as join29 } from "node:path";
|
|
35657
35786
|
import watcher from "@parcel/watcher";
|
|
35658
35787
|
function appServerTurnStalled(liveness, lastActivityAt, nowMs) {
|
|
35659
35788
|
if (!liveness) return false;
|
|
@@ -36338,7 +36467,7 @@ function createBoard(project, storage, bus, tailer, bootId, deps = {}) {
|
|
|
36338
36467
|
if (parcelSub || stopped) return Promise.resolve();
|
|
36339
36468
|
if (watchSetup) return watchSetup;
|
|
36340
36469
|
const setup = (async () => {
|
|
36341
|
-
const next = await subscribe(
|
|
36470
|
+
const next = await subscribe(join29(project.dir, ".frizz"), () => scheduleRebuild());
|
|
36342
36471
|
if (stopped) {
|
|
36343
36472
|
await next.unsubscribe();
|
|
36344
36473
|
return;
|
|
@@ -38272,7 +38401,7 @@ var init_resume = __esm({
|
|
|
38272
38401
|
});
|
|
38273
38402
|
|
|
38274
38403
|
// packages/server/src/backend/claude.ts
|
|
38275
|
-
import { join as
|
|
38404
|
+
import { join as join30 } from "node:path";
|
|
38276
38405
|
function toolResultText2(content) {
|
|
38277
38406
|
if (typeof content === "string") return content;
|
|
38278
38407
|
if (!Array.isArray(content)) return "";
|
|
@@ -38361,7 +38490,7 @@ function createClaudeBackend(opts) {
|
|
|
38361
38490
|
return { argv, env: claudeWorkerEnvironment(), prewrite: [] };
|
|
38362
38491
|
},
|
|
38363
38492
|
transcriptPath(sessionId) {
|
|
38364
|
-
return
|
|
38493
|
+
return join30(opts.logDir, `${sessionId}.jsonl`);
|
|
38365
38494
|
},
|
|
38366
38495
|
parseLine(line) {
|
|
38367
38496
|
return parseClaudeLine(line);
|
|
@@ -38531,12 +38660,12 @@ var init_login_utility = __esm({
|
|
|
38531
38660
|
|
|
38532
38661
|
// packages/server/src/backend/codex-app-server-diagnostics.ts
|
|
38533
38662
|
import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync14, renameSync as renameSync8, statSync as statSync13 } from "node:fs";
|
|
38534
|
-
import { join as
|
|
38663
|
+
import { join as join31 } from "node:path";
|
|
38535
38664
|
function codexDiagnosticLogPath(stateDir, projectId) {
|
|
38536
|
-
return
|
|
38665
|
+
return join31(stateDir, "codex-app-server", `${projectId}.diagnostics.log`);
|
|
38537
38666
|
}
|
|
38538
38667
|
function createCodexDiagnosticSink(stateDir, projectId, now = () => /* @__PURE__ */ new Date()) {
|
|
38539
|
-
const dir =
|
|
38668
|
+
const dir = join31(stateDir, "codex-app-server");
|
|
38540
38669
|
const path = codexDiagnosticLogPath(stateDir, projectId);
|
|
38541
38670
|
let ensured = false;
|
|
38542
38671
|
return (event) => {
|
|
@@ -38568,7 +38697,7 @@ var init_codex_app_server_diagnostics = __esm({
|
|
|
38568
38697
|
import { execFile as execFile7 } from "node:child_process";
|
|
38569
38698
|
import { readdirSync as readdirSync8, unlinkSync as unlinkSync4 } from "node:fs";
|
|
38570
38699
|
import { connect as connectSocket } from "node:net";
|
|
38571
|
-
import { join as
|
|
38700
|
+
import { join as join32 } from "node:path";
|
|
38572
38701
|
function parseLsofSocketNames(stdout) {
|
|
38573
38702
|
const referenced = /* @__PURE__ */ new Set();
|
|
38574
38703
|
for (const line of stdout.split("\n")) {
|
|
@@ -38585,7 +38714,7 @@ function sweepStaleSockets(options, deps = {}) {
|
|
|
38585
38714
|
const keep = new Set(options.keep ?? []);
|
|
38586
38715
|
let candidates;
|
|
38587
38716
|
try {
|
|
38588
|
-
candidates = (deps.readdir ?? readdirSync8)(options.dir).filter((name) => name.startsWith(options.prefix) && name.endsWith(".sock")).map((name) =>
|
|
38717
|
+
candidates = (deps.readdir ?? readdirSync8)(options.dir).filter((name) => name.startsWith(options.prefix) && name.endsWith(".sock")).map((name) => join32(options.dir, name)).filter((path) => !keep.has(path));
|
|
38589
38718
|
} catch {
|
|
38590
38719
|
return;
|
|
38591
38720
|
}
|
|
@@ -38635,7 +38764,7 @@ var init_stale_socket_sweep = __esm({
|
|
|
38635
38764
|
|
|
38636
38765
|
// packages/server/src/orphan-reaper.ts
|
|
38637
38766
|
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
38638
|
-
import { readFileSync as
|
|
38767
|
+
import { readFileSync as readFileSync18 } from "node:fs";
|
|
38639
38768
|
import { dirname as dirname12 } from "node:path";
|
|
38640
38769
|
function firstTokenBasename(command) {
|
|
38641
38770
|
const first = command.trimStart().split(/\s+/, 1)[0] ?? "";
|
|
@@ -38902,7 +39031,7 @@ var init_orphan_reaper = __esm({
|
|
|
38902
39031
|
defaultExec = (file, args) => execFileSync5(file, args, { encoding: "utf8", maxBuffer: 16 * 1024 * 1024, timeout: 1e4 });
|
|
38903
39032
|
defaultReadEnv = (pid) => {
|
|
38904
39033
|
try {
|
|
38905
|
-
return
|
|
39034
|
+
return readFileSync18(`/proc/${pid}/environ`, "utf8");
|
|
38906
39035
|
} catch {
|
|
38907
39036
|
return null;
|
|
38908
39037
|
}
|
|
@@ -39049,7 +39178,7 @@ var init_thread_hibernation = __esm({
|
|
|
39049
39178
|
});
|
|
39050
39179
|
|
|
39051
39180
|
// packages/server/src/context.ts
|
|
39052
|
-
import { join as
|
|
39181
|
+
import { join as join33 } from "node:path";
|
|
39053
39182
|
import { randomUUID as randomUUID15 } from "node:crypto";
|
|
39054
39183
|
import { homedir as homedir13 } from "node:os";
|
|
39055
39184
|
function reconcileSessions(storage) {
|
|
@@ -39207,7 +39336,7 @@ async function createContext(opts = {}) {
|
|
|
39207
39336
|
function createContextUnchecked(opts, resources) {
|
|
39208
39337
|
const home = opts.home ?? homedir13();
|
|
39209
39338
|
const project = opts.project ?? resolveProject();
|
|
39210
|
-
const dbPath =
|
|
39339
|
+
const dbPath = join33(project.stateDir, "ui.db");
|
|
39211
39340
|
const storage = createStorage(dbPath);
|
|
39212
39341
|
resources.storage = storage;
|
|
39213
39342
|
const bus = new Bus();
|
|
@@ -39535,6 +39664,8 @@ ${wakeDeliveryToken(deliveryId)}`;
|
|
|
39535
39664
|
getSettings: () => getSettings(storage, home),
|
|
39536
39665
|
setSettings: (s) => setSettings(storage, s, home),
|
|
39537
39666
|
resetSettings: () => resetSettings(storage, home),
|
|
39667
|
+
getDispatchPreferences: (codexModels) => getDispatchPreferences(storage, getSettings(storage, home), home, codexModels),
|
|
39668
|
+
setDispatchPreference: (update, codexModels) => setDispatchPreference(storage, getSettings(storage, home), home, update, codexModels),
|
|
39538
39669
|
activeTenants: opts.activeTenants,
|
|
39539
39670
|
claudeBin: opts.claudeBin,
|
|
39540
39671
|
codexBin: opts.codexBin,
|
|
@@ -39550,6 +39681,7 @@ var init_context = __esm({
|
|
|
39550
39681
|
init_project();
|
|
39551
39682
|
init_storage();
|
|
39552
39683
|
init_settings();
|
|
39684
|
+
init_dispatch_preferences();
|
|
39553
39685
|
init_quota();
|
|
39554
39686
|
init_claude_quota();
|
|
39555
39687
|
init_board();
|
|
@@ -42235,7 +42367,7 @@ var init_server = __esm({
|
|
|
42235
42367
|
});
|
|
42236
42368
|
|
|
42237
42369
|
// packages/server/src/repair.ts
|
|
42238
|
-
import { existsSync as existsSync12, readFileSync as
|
|
42370
|
+
import { existsSync as existsSync12, readFileSync as readFileSync19, writeFileSync as writeFileSync11 } from "node:fs";
|
|
42239
42371
|
import { basename as basename7, dirname as dirname13, resolve as resolve6 } from "node:path";
|
|
42240
42372
|
function quoteValue(v) {
|
|
42241
42373
|
if (/^[\w./#:+-]+$/.test(v)) return v;
|
|
@@ -42251,7 +42383,7 @@ function repairThreadFile(frizzDir, file) {
|
|
|
42251
42383
|
if (dirname13(abs) !== root) throw new RepairError(`refusing to repair "${file}": not directly under .frizz/`);
|
|
42252
42384
|
if (!abs.endsWith(".md")) throw new RepairError(`refusing to repair "${file}": not a .md thread file`);
|
|
42253
42385
|
if (!existsSync12(abs)) throw new RepairError(`no thread file to repair: ${basename7(abs)}`);
|
|
42254
|
-
const content =
|
|
42386
|
+
const content = readFileSync19(abs, "utf8");
|
|
42255
42387
|
const firstLine2 = content.replace(/^/, "").split(/\r?\n/).find((l) => l.trim() !== "");
|
|
42256
42388
|
if (firstLine2?.trim() === "---") {
|
|
42257
42389
|
throw new RepairError(`${basename7(abs)} already opens with a "---" block \u2014 repair only heals a MISSING frontmatter block`);
|
|
@@ -42284,7 +42416,7 @@ var init_repair = __esm({
|
|
|
42284
42416
|
});
|
|
42285
42417
|
|
|
42286
42418
|
// cc-worker/hooks/bash-background.mjs
|
|
42287
|
-
import { readFileSync as
|
|
42419
|
+
import { readFileSync as readFileSync20 } from "node:fs";
|
|
42288
42420
|
import { basename as basename8 } from "node:path";
|
|
42289
42421
|
import { pathToFileURL } from "node:url";
|
|
42290
42422
|
function emit(obj) {
|
|
@@ -42433,7 +42565,7 @@ var init_bash_background = __esm({
|
|
|
42433
42565
|
if (isDirectHookExecution(process.argv[1], import.meta.url)) {
|
|
42434
42566
|
try {
|
|
42435
42567
|
const env = process.argv.includes("--frizz-thread") ? { ...process.env, FRIZZ_THREAD: process.env.FRIZZ_THREAD || "codex-worker" } : process.env;
|
|
42436
|
-
emit(evaluateBashBackgroundHook(JSON.parse(
|
|
42568
|
+
emit(evaluateBashBackgroundHook(JSON.parse(readFileSync20(0, "utf8")), env));
|
|
42437
42569
|
} catch {
|
|
42438
42570
|
emit({});
|
|
42439
42571
|
}
|
|
@@ -42442,10 +42574,10 @@ var init_bash_background = __esm({
|
|
|
42442
42574
|
});
|
|
42443
42575
|
|
|
42444
42576
|
// packages/server/src/transcript.ts
|
|
42445
|
-
import { closeSync as closeSync13, existsSync as existsSync13, fstatSync as fstatSync3, mkdirSync as mkdirSync15, openSync as openSync14, readdirSync as readdirSync9, readFileSync as
|
|
42577
|
+
import { closeSync as closeSync13, existsSync as existsSync13, fstatSync as fstatSync3, mkdirSync as mkdirSync15, openSync as openSync14, readdirSync as readdirSync9, readFileSync as readFileSync21, readSync as readSync7, renameSync as renameSync9, statSync as statSync14, unlinkSync as unlinkSync5, writeFileSync as writeFileSync12 } from "node:fs";
|
|
42446
42578
|
import { createHash as createHash13 } from "node:crypto";
|
|
42447
42579
|
import { StringDecoder as StringDecoder4 } from "node:string_decoder";
|
|
42448
|
-
import { join as
|
|
42580
|
+
import { join as join34 } from "node:path";
|
|
42449
42581
|
import { homedir as homedir14 } from "node:os";
|
|
42450
42582
|
function formatTokens(n) {
|
|
42451
42583
|
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
@@ -42995,14 +43127,14 @@ function pruneScreenshotCache() {
|
|
|
42995
43127
|
if (entries.length <= SCREENSHOT_CACHE_MAX) return;
|
|
42996
43128
|
const byMtime = entries.map((n) => {
|
|
42997
43129
|
try {
|
|
42998
|
-
return { n, m: statSync14(
|
|
43130
|
+
return { n, m: statSync14(join34(SCREENSHOT_CACHE_DIR, n)).mtimeMs };
|
|
42999
43131
|
} catch {
|
|
43000
43132
|
return { n, m: 0 };
|
|
43001
43133
|
}
|
|
43002
43134
|
}).sort((a, b) => b.m - a.m);
|
|
43003
43135
|
for (const { n } of byMtime.slice(SCREENSHOT_CACHE_MAX)) {
|
|
43004
43136
|
try {
|
|
43005
|
-
unlinkSync5(
|
|
43137
|
+
unlinkSync5(join34(SCREENSHOT_CACHE_DIR, n));
|
|
43006
43138
|
} catch {
|
|
43007
43139
|
}
|
|
43008
43140
|
}
|
|
@@ -43032,14 +43164,14 @@ function persistBase64Image(mediaType, data, idKey) {
|
|
|
43032
43164
|
const ext = IMAGE_MEDIA_EXT[typeof mediaType === "string" ? mediaType.toLowerCase() : ""];
|
|
43033
43165
|
if (!ext || !data) return void 0;
|
|
43034
43166
|
const name = createHash13("sha256").update(idKey).digest("hex").slice(0, 32);
|
|
43035
|
-
const path =
|
|
43167
|
+
const path = join34(SCREENSHOT_CACHE_DIR, `${name}.${ext}`);
|
|
43036
43168
|
try {
|
|
43037
43169
|
if (existsSync13(path)) return path;
|
|
43038
43170
|
if (data.length > SCREENSHOT_MAX_BASE64) return void 0;
|
|
43039
43171
|
const buf = Buffer.from(data, "base64");
|
|
43040
43172
|
if (buf.length === 0 || !looksLikeImage(buf, ext)) return void 0;
|
|
43041
43173
|
mkdirSync15(SCREENSHOT_CACHE_DIR, { recursive: true });
|
|
43042
|
-
const tmp =
|
|
43174
|
+
const tmp = join34(SCREENSHOT_CACHE_DIR, `.${name}.${process.pid}.${screenshotTmpSeq++}.tmp`);
|
|
43043
43175
|
writeFileSync12(tmp, buf);
|
|
43044
43176
|
renameSync9(tmp, path);
|
|
43045
43177
|
pruneScreenshotCache();
|
|
@@ -43054,14 +43186,14 @@ function persistSentFile(srcPath, idKey) {
|
|
|
43054
43186
|
const outExt = ext === "jpeg" ? "jpg" : ext;
|
|
43055
43187
|
try {
|
|
43056
43188
|
const name = createHash13("sha256").update(idKey).digest("hex").slice(0, 32);
|
|
43057
|
-
const dest =
|
|
43189
|
+
const dest = join34(SCREENSHOT_CACHE_DIR, `${name}.${outExt}`);
|
|
43058
43190
|
if (existsSync13(dest)) return dest;
|
|
43059
43191
|
const size = statSync14(srcPath).size;
|
|
43060
43192
|
if (size === 0 || size > SENT_IMAGE_MAX_BYTES) return void 0;
|
|
43061
|
-
const buf =
|
|
43193
|
+
const buf = readFileSync21(srcPath);
|
|
43062
43194
|
if (!looksLikeImage(buf, outExt)) return void 0;
|
|
43063
43195
|
mkdirSync15(SCREENSHOT_CACHE_DIR, { recursive: true });
|
|
43064
|
-
const tmp =
|
|
43196
|
+
const tmp = join34(SCREENSHOT_CACHE_DIR, `.${name}.${process.pid}.${screenshotTmpSeq++}.tmp`);
|
|
43065
43197
|
writeFileSync12(tmp, buf);
|
|
43066
43198
|
renameSync9(tmp, dest);
|
|
43067
43199
|
pruneScreenshotCache();
|
|
@@ -43478,7 +43610,7 @@ function readTranscript(project, sessionId) {
|
|
|
43478
43610
|
}
|
|
43479
43611
|
function verifyIncrementalParse(path, identityPrefix, incremental) {
|
|
43480
43612
|
try {
|
|
43481
|
-
const fresh = parseTranscript(
|
|
43613
|
+
const fresh = parseTranscript(readFileSync21(path, "utf8"), identityPrefix);
|
|
43482
43614
|
const a = JSON.stringify(incremental);
|
|
43483
43615
|
const b = JSON.stringify(fresh);
|
|
43484
43616
|
if (a !== b) {
|
|
@@ -43498,16 +43630,16 @@ function verifyIncrementalParse(path, identityPrefix, incremental) {
|
|
|
43498
43630
|
}
|
|
43499
43631
|
}
|
|
43500
43632
|
function logDirOf(project) {
|
|
43501
|
-
return
|
|
43633
|
+
return join34(homedir14(), ".claude", "projects", project.cwdSlug);
|
|
43502
43634
|
}
|
|
43503
43635
|
function resolveTranscriptPath(project, sessionId) {
|
|
43504
|
-
const path =
|
|
43636
|
+
const path = join34(logDirOf(project), `${sessionId}.jsonl`);
|
|
43505
43637
|
try {
|
|
43506
43638
|
if (statSync14(path).size > 0) return path;
|
|
43507
43639
|
} catch {
|
|
43508
43640
|
}
|
|
43509
43641
|
const stranded = discoverTranscriptDir(logDirOf(project), sessionId);
|
|
43510
|
-
return stranded ?
|
|
43642
|
+
return stranded ? join34(stranded, `${sessionId}.jsonl`) : path;
|
|
43511
43643
|
}
|
|
43512
43644
|
function projectCodexTranscript(raw2, identityPrefix = "codex") {
|
|
43513
43645
|
const out = [];
|
|
@@ -44710,7 +44842,7 @@ function readEarlierThreadTranscriptPage(project, storage, slug, cursor, backend
|
|
|
44710
44842
|
}
|
|
44711
44843
|
function readCodexTranscriptFile(absPath, nativeId = absPath) {
|
|
44712
44844
|
try {
|
|
44713
|
-
return parseCodexTranscript(
|
|
44845
|
+
return parseCodexTranscript(readFileSync21(absPath, "utf8"), `codex:${nativeId}`);
|
|
44714
44846
|
} catch {
|
|
44715
44847
|
return [];
|
|
44716
44848
|
}
|
|
@@ -44808,7 +44940,7 @@ function projectTranscriptPageAgentLifecycles(page, lookup, peerLookup) {
|
|
|
44808
44940
|
function readTranscriptFile(absPath) {
|
|
44809
44941
|
try {
|
|
44810
44942
|
const pathKey = createHash13("sha256").update(absPath).digest("base64url").slice(0, 16);
|
|
44811
|
-
return parseTranscript(
|
|
44943
|
+
return parseTranscript(readFileSync21(absPath, "utf8"), `claude-file:${pathKey}`);
|
|
44812
44944
|
} catch {
|
|
44813
44945
|
return [];
|
|
44814
44946
|
}
|
|
@@ -44905,9 +45037,9 @@ var init_open_external = __esm({
|
|
|
44905
45037
|
|
|
44906
45038
|
// packages/server/src/local-file.ts
|
|
44907
45039
|
import { spawn as spawn6 } from "node:child_process";
|
|
44908
|
-
import { readFileSync as
|
|
45040
|
+
import { readFileSync as readFileSync22, realpathSync as realpathSync8, statSync as statSync15 } from "node:fs";
|
|
44909
45041
|
import { homedir as homedir15 } from "node:os";
|
|
44910
|
-
import { isAbsolute as isAbsolute3, join as
|
|
45042
|
+
import { isAbsolute as isAbsolute3, join as join35, resolve as resolve7, sep } from "node:path";
|
|
44911
45043
|
function isUnder(real, root) {
|
|
44912
45044
|
let rootReal;
|
|
44913
45045
|
try {
|
|
@@ -44937,7 +45069,7 @@ function resolveLocalFile(rawPath, roots) {
|
|
|
44937
45069
|
function resolveOpenableFile(raw2, projectDir, roots, home = homedir15()) {
|
|
44938
45070
|
const trimmed = raw2.trim().replace(/:\d+(?::\d+)?$/, "");
|
|
44939
45071
|
if (!trimmed) return null;
|
|
44940
|
-
const abs = trimmed === "~" ? home : trimmed.startsWith("~/") ?
|
|
45072
|
+
const abs = trimmed === "~" ? home : trimmed.startsWith("~/") ? join35(home, trimmed.slice(2)) : isAbsolute3(trimmed) ? trimmed : resolve7(projectDir, trimmed);
|
|
44941
45073
|
try {
|
|
44942
45074
|
return resolveLocalFile(abs, roots);
|
|
44943
45075
|
} catch {
|
|
@@ -44948,7 +45080,7 @@ function readLocalMarkdown(rawPath, roots) {
|
|
|
44948
45080
|
if (!MARKDOWN_FILE_EXT.test(rawPath.trim())) throw new Error("Local file is not a Markdown file");
|
|
44949
45081
|
const path = resolveLocalFile(rawPath, roots);
|
|
44950
45082
|
if (!MARKDOWN_FILE_EXT.test(path)) throw new Error("Local file is not a Markdown file");
|
|
44951
|
-
const bytes =
|
|
45083
|
+
const bytes = readFileSync22(path);
|
|
44952
45084
|
if (bytes.length <= MARKDOWN_READ_LIMIT) return { path, markdown: bytes.toString("utf8"), truncated: false };
|
|
44953
45085
|
const head = bytes.subarray(0, MARKDOWN_READ_LIMIT);
|
|
44954
45086
|
const lastBreak = head.lastIndexOf(10);
|
|
@@ -45295,67 +45427,6 @@ var init_account_actions = __esm({
|
|
|
45295
45427
|
}
|
|
45296
45428
|
});
|
|
45297
45429
|
|
|
45298
|
-
// packages/server/src/dispatch-preferences.ts
|
|
45299
|
-
function permissionFor(backend, mode) {
|
|
45300
|
-
if (backend === "codex") {
|
|
45301
|
-
if (mode === "plan" || mode === "bypassPermissions") return mode;
|
|
45302
|
-
return "default";
|
|
45303
|
-
}
|
|
45304
|
-
return mode === "plan" ? "auto" : mode;
|
|
45305
|
-
}
|
|
45306
|
-
function defaultDispatchPreferences(settings, codexModels = []) {
|
|
45307
|
-
const backend = settings.backend ?? (codexModels.some((model) => model.slug === settings.model) ? "codex" : "claude");
|
|
45308
|
-
const selected = {
|
|
45309
|
-
...settings.model ? { model: settings.model } : {},
|
|
45310
|
-
...settings.effort ? { effort: settings.effort } : {},
|
|
45311
|
-
permissionMode: permissionFor(backend, settings.permissionMode)
|
|
45312
|
-
};
|
|
45313
|
-
return {
|
|
45314
|
-
backend,
|
|
45315
|
-
claude: backend === "claude" ? selected : { permissionMode: "auto" },
|
|
45316
|
-
codex: backend === "codex" ? selected : { permissionMode: "default" }
|
|
45317
|
-
};
|
|
45318
|
-
}
|
|
45319
|
-
function getDispatchPreferences(storage, settings, codexModels = []) {
|
|
45320
|
-
const parsed = DispatchPreferences.safeParse(storage.getSetting(KEY));
|
|
45321
|
-
return parsed.success ? parsed.data : defaultDispatchPreferences(settings, codexModels);
|
|
45322
|
-
}
|
|
45323
|
-
function setDispatchPreference(storage, settings, update, codexModels = []) {
|
|
45324
|
-
const current = getDispatchPreferences(storage, settings, codexModels);
|
|
45325
|
-
let next;
|
|
45326
|
-
if (update.field === "backend") {
|
|
45327
|
-
next = { ...current, backend: update.value };
|
|
45328
|
-
} else if (update.field === "profile") {
|
|
45329
|
-
next = {
|
|
45330
|
-
...current,
|
|
45331
|
-
backend: update.backend,
|
|
45332
|
-
[update.backend]: {
|
|
45333
|
-
...current[update.backend],
|
|
45334
|
-
model: update.model,
|
|
45335
|
-
effort: update.effort
|
|
45336
|
-
}
|
|
45337
|
-
};
|
|
45338
|
-
} else {
|
|
45339
|
-
const profile = current[update.backend];
|
|
45340
|
-
next = {
|
|
45341
|
-
...current,
|
|
45342
|
-
...update.field === "model" ? { backend: update.backend } : {},
|
|
45343
|
-
[update.backend]: { ...profile, [update.field]: update.value }
|
|
45344
|
-
};
|
|
45345
|
-
}
|
|
45346
|
-
const validated = DispatchPreferences.parse(next);
|
|
45347
|
-
storage.setSetting(KEY, validated);
|
|
45348
|
-
return validated;
|
|
45349
|
-
}
|
|
45350
|
-
var KEY;
|
|
45351
|
-
var init_dispatch_preferences = __esm({
|
|
45352
|
-
"packages/server/src/dispatch-preferences.ts"() {
|
|
45353
|
-
"use strict";
|
|
45354
|
-
init_src();
|
|
45355
|
-
KEY = "dispatch-preferences.v1";
|
|
45356
|
-
}
|
|
45357
|
-
});
|
|
45358
|
-
|
|
45359
45430
|
// packages/server/src/external-terminal.ts
|
|
45360
45431
|
function shellQuote(value) {
|
|
45361
45432
|
return `'${value.replace(/'/g, `'"'"'`)}'`;
|
|
@@ -45708,8 +45779,8 @@ var init_directory_picker = __esm({
|
|
|
45708
45779
|
});
|
|
45709
45780
|
|
|
45710
45781
|
// packages/server/src/router.ts
|
|
45711
|
-
import { readFileSync as
|
|
45712
|
-
import { join as
|
|
45782
|
+
import { readFileSync as readFileSync23, statSync as statSync17 } from "node:fs";
|
|
45783
|
+
import { join as join36, resolve as resolve8 } from "node:path";
|
|
45713
45784
|
import { randomUUID as randomUUID16 } from "node:crypto";
|
|
45714
45785
|
import { basename as basename9, dirname as dirname14 } from "node:path";
|
|
45715
45786
|
import { existsSync as existsSync14, mkdirSync as mkdirSync16, rmSync as rmSync9, writeFileSync as writeFileSync13 } from "node:fs";
|
|
@@ -45872,7 +45943,7 @@ function projectCard(entry, stale) {
|
|
|
45872
45943
|
function addProjectAtPath(input) {
|
|
45873
45944
|
const typed = input.trim();
|
|
45874
45945
|
if (!typed) throw new Error("Enter a folder path.");
|
|
45875
|
-
const expanded = typed === "~" || typed.startsWith("~/") ?
|
|
45946
|
+
const expanded = typed === "~" || typed.startsWith("~/") ? join36(homedir16(), typed.slice(1)) : typed;
|
|
45876
45947
|
const absolute = resolve8(expanded);
|
|
45877
45948
|
let stats;
|
|
45878
45949
|
try {
|
|
@@ -45917,7 +45988,7 @@ function storeProjectIcon(id, name, bytes) {
|
|
|
45917
45988
|
function setProjectIconFromFile(id, file) {
|
|
45918
45989
|
let bytes;
|
|
45919
45990
|
try {
|
|
45920
|
-
bytes =
|
|
45991
|
+
bytes = readFileSync23(file);
|
|
45921
45992
|
} catch {
|
|
45922
45993
|
throw new Error("That file could not be read.");
|
|
45923
45994
|
}
|
|
@@ -45925,7 +45996,7 @@ function setProjectIconFromFile(id, file) {
|
|
|
45925
45996
|
return storeProjectIcon(id, file, bytes);
|
|
45926
45997
|
}
|
|
45927
45998
|
function createRouter(ctx) {
|
|
45928
|
-
const frizzDir =
|
|
45999
|
+
const frizzDir = join36(ctx.project.dir, ".frizz");
|
|
45929
46000
|
const openRoots = openableFileRoots(ctx.project);
|
|
45930
46001
|
function isAutoTitledSession(slug) {
|
|
45931
46002
|
return ctx.storage.getSession(slug)?.title_auto === 1;
|
|
@@ -47580,7 +47651,7 @@ ${gapNote}` : input.message;
|
|
|
47580
47651
|
for (const entry of listProjects()) {
|
|
47581
47652
|
if (entry.stale) continue;
|
|
47582
47653
|
try {
|
|
47583
|
-
const db = new sqlite_default(
|
|
47654
|
+
const db = new sqlite_default(join36(projectStateDir(entry.id), "ui.db"), { readonly: true });
|
|
47584
47655
|
try {
|
|
47585
47656
|
const hit = db.prepare("SELECT 1 FROM session WHERE slug = ? LIMIT 1").get(input.slug);
|
|
47586
47657
|
if (hit) found.push({ projectSlug: entry.slug, projectName: entry.name ?? entry.slug });
|
|
@@ -47610,12 +47681,12 @@ ${gapNote}` : input.message;
|
|
|
47610
47681
|
}),
|
|
47611
47682
|
dispatchPreferencesGet: query({
|
|
47612
47683
|
output: DispatchPreferences,
|
|
47613
|
-
handler: async () =>
|
|
47684
|
+
handler: async () => ctx.getDispatchPreferences(readCodexModels())
|
|
47614
47685
|
}),
|
|
47615
47686
|
dispatchPreferenceSet: mutation({
|
|
47616
47687
|
input: SetDispatchPreferenceInput,
|
|
47617
47688
|
output: DispatchPreferences,
|
|
47618
|
-
handler: async ({ input }) =>
|
|
47689
|
+
handler: async ({ input }) => ctx.setDispatchPreference(input, readCodexModels())
|
|
47619
47690
|
}),
|
|
47620
47691
|
// The shipped GitHub batch-dispatch prompt template (single source of truth: server/github.ts).
|
|
47621
47692
|
// The Settings UI reads it to prefill the editor and to power "reset to default"; an empty/unset
|
|
@@ -47726,7 +47797,6 @@ var init_router5 = __esm({
|
|
|
47726
47797
|
init_thread_profiles();
|
|
47727
47798
|
init_adoption_recovery();
|
|
47728
47799
|
init_awaiting();
|
|
47729
|
-
init_dispatch_preferences();
|
|
47730
47800
|
init_storage();
|
|
47731
47801
|
init_external_terminal();
|
|
47732
47802
|
init_background_shell_output();
|
|
@@ -47937,7 +48007,7 @@ var init_compression = __esm({
|
|
|
47937
48007
|
});
|
|
47938
48008
|
|
|
47939
48009
|
// packages/server/src/local-image.ts
|
|
47940
|
-
import { readFileSync as
|
|
48010
|
+
import { readFileSync as readFileSync24, realpathSync as realpathSync9, statSync as statSync18 } from "node:fs";
|
|
47941
48011
|
import { extname as extname2, isAbsolute as isAbsolute4 } from "node:path";
|
|
47942
48012
|
function resolveLocalImage(rawPath) {
|
|
47943
48013
|
if (!rawPath || !isAbsolute4(rawPath)) return { status: 400 };
|
|
@@ -47951,7 +48021,7 @@ function resolveLocalImage(rawPath) {
|
|
|
47951
48021
|
}
|
|
47952
48022
|
try {
|
|
47953
48023
|
if (!statSync18(real).isFile()) return { status: 404 };
|
|
47954
|
-
return { status: 200, contentType, body:
|
|
48024
|
+
return { status: 200, contentType, body: readFileSync24(real) };
|
|
47955
48025
|
} catch {
|
|
47956
48026
|
return { status: 404 };
|
|
47957
48027
|
}
|
|
@@ -47971,9 +48041,9 @@ var init_local_image = __esm({
|
|
|
47971
48041
|
});
|
|
47972
48042
|
|
|
47973
48043
|
// packages/server/src/project-icon.ts
|
|
47974
|
-
import { readFileSync as
|
|
48044
|
+
import { readFileSync as readFileSync25, readdirSync as readdirSync10, realpathSync as realpathSync10, statSync as statSync19 } from "node:fs";
|
|
47975
48045
|
import { homedir as homedir17 } from "node:os";
|
|
47976
|
-
import { basename as basename10, dirname as dirname15, extname as extname3, join as
|
|
48046
|
+
import { basename as basename10, dirname as dirname15, extname as extname3, join as join37, relative, sep as sep2 } from "node:path";
|
|
47977
48047
|
function normalizeStem(stem) {
|
|
47978
48048
|
const sized = stem.toLowerCase().replace(/[@-]\d+(\.\d+)?x(\d+)?$/u, "").replace(/[-_]\d{2,4}$/u, "");
|
|
47979
48049
|
const normalized = sized.replace(VARIANT_SUFFIX, "");
|
|
@@ -47991,7 +48061,7 @@ function sizeScore(dimensions) {
|
|
|
47991
48061
|
return Math.max(0, Math.min(40, Math.round(Math.log2(edge / 24) * 8)));
|
|
47992
48062
|
}
|
|
47993
48063
|
function under(root, relativeDirectory) {
|
|
47994
|
-
return relativeDirectory ?
|
|
48064
|
+
return relativeDirectory ? join37(root, relativeDirectory) : root;
|
|
47995
48065
|
}
|
|
47996
48066
|
function listFiles(directory) {
|
|
47997
48067
|
try {
|
|
@@ -48013,19 +48083,19 @@ function iconDirectories(root) {
|
|
|
48013
48083
|
for (const asset of ASSET_DIRECTORIES) directories.push(under(root, asset));
|
|
48014
48084
|
for (const host of HOST_DIRECTORIES) {
|
|
48015
48085
|
if (!children2.has(host)) continue;
|
|
48016
|
-
for (const asset of ASSET_DIRECTORIES) directories.push(under(
|
|
48086
|
+
for (const asset of ASSET_DIRECTORIES) directories.push(under(join37(root, host), asset));
|
|
48017
48087
|
}
|
|
48018
48088
|
for (const extra of EXTRA_DIRECTORIES) directories.push(under(root, extra));
|
|
48019
48089
|
for (const container of WORKSPACE_CONTAINERS) {
|
|
48020
48090
|
if (!children2.has(container)) continue;
|
|
48021
48091
|
let members;
|
|
48022
48092
|
try {
|
|
48023
|
-
members = readdirSync10(
|
|
48093
|
+
members = readdirSync10(join37(root, container), { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name);
|
|
48024
48094
|
} catch {
|
|
48025
48095
|
continue;
|
|
48026
48096
|
}
|
|
48027
48097
|
for (const member of members) {
|
|
48028
|
-
for (const asset of ASSET_DIRECTORIES) directories.push(under(
|
|
48098
|
+
for (const asset of ASSET_DIRECTORIES) directories.push(under(join37(root, container, member), asset));
|
|
48029
48099
|
}
|
|
48030
48100
|
}
|
|
48031
48101
|
return [...new Set(directories)];
|
|
@@ -48033,13 +48103,13 @@ function iconDirectories(root) {
|
|
|
48033
48103
|
function manifestIcons(manifestPath) {
|
|
48034
48104
|
let parsed;
|
|
48035
48105
|
try {
|
|
48036
|
-
parsed = JSON.parse(
|
|
48106
|
+
parsed = JSON.parse(readFileSync25(manifestPath, "utf8"));
|
|
48037
48107
|
} catch {
|
|
48038
48108
|
return [];
|
|
48039
48109
|
}
|
|
48040
48110
|
if (!Array.isArray(parsed?.icons)) return [];
|
|
48041
48111
|
const directory = dirname15(manifestPath);
|
|
48042
|
-
return parsed.icons.map((icon) => typeof icon?.src === "string" ? icon.src : void 0).filter((src) => !!src && !/^(https?:)?\/\//u.test(src) && !src.startsWith("data:")).map((src) =>
|
|
48112
|
+
return parsed.icons.map((icon) => typeof icon?.src === "string" ? icon.src : void 0).filter((src) => !!src && !/^(https?:)?\/\//u.test(src) && !src.startsWith("data:")).map((src) => join37(directory, src.replace(/[?#].*$/u, "").replace(/^\//u, "")));
|
|
48043
48113
|
}
|
|
48044
48114
|
function projectIconCandidates(root) {
|
|
48045
48115
|
const projectStem = normalizeStem(basename10(root)).normalized;
|
|
@@ -48058,7 +48128,7 @@ function projectIconCandidates(root) {
|
|
|
48058
48128
|
for (const name of listFiles(directory)) {
|
|
48059
48129
|
const extension2 = extname3(name).toLowerCase();
|
|
48060
48130
|
if (MANIFEST_NAMES.includes(name.toLowerCase())) {
|
|
48061
|
-
for (const icon of manifestIcons(
|
|
48131
|
+
for (const icon of manifestIcons(join37(directory, name))) {
|
|
48062
48132
|
if (MEASURABLE_IMAGE_EXTENSIONS.has(extname3(icon).toLowerCase())) {
|
|
48063
48133
|
fromManifest.add(icon);
|
|
48064
48134
|
files.push({ path: icon, directory: dirname15(icon) });
|
|
@@ -48069,7 +48139,7 @@ function projectIconCandidates(root) {
|
|
|
48069
48139
|
if (!MEASURABLE_IMAGE_EXTENSIONS.has(extension2)) continue;
|
|
48070
48140
|
const stem = name.slice(0, name.length - extension2.length);
|
|
48071
48141
|
if (normalizeStem(stem).normalized === "favicon") iconHomes.add(directory);
|
|
48072
|
-
files.push({ path:
|
|
48142
|
+
files.push({ path: join37(directory, name), directory });
|
|
48073
48143
|
if (files.length >= MAX_CANDIDATES) break;
|
|
48074
48144
|
}
|
|
48075
48145
|
}
|
|
@@ -48134,7 +48204,7 @@ function resolveProjectIconResponse(id, options = {}) {
|
|
|
48134
48204
|
});
|
|
48135
48205
|
if (!roots.some((root) => real === root || real.startsWith(root + sep2))) return { status: 404 };
|
|
48136
48206
|
try {
|
|
48137
|
-
return { status: 200, contentType, body:
|
|
48207
|
+
return { status: 200, contentType, body: readFileSync25(real) };
|
|
48138
48208
|
} catch {
|
|
48139
48209
|
return { status: 404 };
|
|
48140
48210
|
}
|
|
@@ -48246,8 +48316,8 @@ var init_project_icon = __esm({
|
|
|
48246
48316
|
});
|
|
48247
48317
|
|
|
48248
48318
|
// packages/server/src/local-visualization.ts
|
|
48249
|
-
import { readdirSync as readdirSync11, readFileSync as
|
|
48250
|
-
import { join as
|
|
48319
|
+
import { readdirSync as readdirSync11, readFileSync as readFileSync26, realpathSync as realpathSync11, statSync as statSync20 } from "node:fs";
|
|
48320
|
+
import { join as join38, sep as sep3 } from "node:path";
|
|
48251
48321
|
function children(path, pattern) {
|
|
48252
48322
|
try {
|
|
48253
48323
|
return readdirSync11(path, { withFileTypes: true }).filter((entry) => entry.isDirectory() && pattern.test(entry.name)).map((entry) => entry.name).sort().reverse();
|
|
@@ -48259,7 +48329,7 @@ function isUnder2(path, root) {
|
|
|
48259
48329
|
return path === root || path.startsWith(root.endsWith(sep3) ? root : root + sep3);
|
|
48260
48330
|
}
|
|
48261
48331
|
function resolveFragment(projectDir, sessionId, file) {
|
|
48262
|
-
const base =
|
|
48332
|
+
const base = join38(projectDir, ".codex", "visualizations");
|
|
48263
48333
|
let projectReal;
|
|
48264
48334
|
let baseReal;
|
|
48265
48335
|
try {
|
|
@@ -48270,12 +48340,12 @@ function resolveFragment(projectDir, sessionId, file) {
|
|
|
48270
48340
|
}
|
|
48271
48341
|
if (!isUnder2(baseReal, projectReal)) return null;
|
|
48272
48342
|
for (const year of children(base, YEAR_PART)) {
|
|
48273
|
-
const yearDir =
|
|
48343
|
+
const yearDir = join38(base, year);
|
|
48274
48344
|
for (const month of children(yearDir, DATE_PART)) {
|
|
48275
|
-
const monthDir =
|
|
48345
|
+
const monthDir = join38(yearDir, month);
|
|
48276
48346
|
for (const day of children(monthDir, DATE_PART)) {
|
|
48277
|
-
const sessionRoot =
|
|
48278
|
-
const candidate =
|
|
48347
|
+
const sessionRoot = join38(baseReal, year, month, day, sessionId);
|
|
48348
|
+
const candidate = join38(monthDir, day, sessionId, file);
|
|
48279
48349
|
try {
|
|
48280
48350
|
const real = realpathSync11(candidate);
|
|
48281
48351
|
if (isUnder2(real, sessionRoot) && statSync20(real).isFile()) return real;
|
|
@@ -48361,7 +48431,7 @@ function resolveLocalVisualization(projectDir, sessionId, file) {
|
|
|
48361
48431
|
try {
|
|
48362
48432
|
const size = statSync20(path).size;
|
|
48363
48433
|
if (size > MAX_FRAGMENT_BYTES) return { status: 413 };
|
|
48364
|
-
fragment =
|
|
48434
|
+
fragment = readFileSync26(path, "utf8");
|
|
48365
48435
|
} catch {
|
|
48366
48436
|
return { status: 404 };
|
|
48367
48437
|
}
|
|
@@ -48404,7 +48474,7 @@ var init_local_visualization = __esm({
|
|
|
48404
48474
|
|
|
48405
48475
|
// packages/server/src/app.ts
|
|
48406
48476
|
import { mkdirSync as mkdirSync17, writeFileSync as writeFileSync14 } from "node:fs";
|
|
48407
|
-
import { join as
|
|
48477
|
+
import { join as join39 } from "node:path";
|
|
48408
48478
|
import { randomUUID as randomUUID17 } from "node:crypto";
|
|
48409
48479
|
function createApp(ctx, options = {}) {
|
|
48410
48480
|
const app = new Hono2();
|
|
@@ -48508,10 +48578,10 @@ function createApp(ctx, options = {}) {
|
|
|
48508
48578
|
if (typeof body.data !== "string" || body.data.length > ATTACHMENT_MAX_BASE64_CHARS) return c.json({ error: "bad payload" }, 400);
|
|
48509
48579
|
const ext = `.${attachmentExtension(name)}`;
|
|
48510
48580
|
const buf = Buffer.from(body.data, "base64");
|
|
48511
|
-
const dir =
|
|
48581
|
+
const dir = join39(ctx.project.stateDir, "attachments");
|
|
48512
48582
|
mkdirSync17(dir, { recursive: true });
|
|
48513
48583
|
const base = name.replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9_-]+/g, "-").slice(0, 40) || "file";
|
|
48514
|
-
const path =
|
|
48584
|
+
const path = join39(dir, `${Date.now()}-${randomUUID17().slice(0, 8)}-${base}${ext}`);
|
|
48515
48585
|
writeFileSync14(path, buf);
|
|
48516
48586
|
return c.json({ path });
|
|
48517
48587
|
});
|
|
@@ -49750,10 +49820,10 @@ var init_app_socket = __esm({
|
|
|
49750
49820
|
});
|
|
49751
49821
|
|
|
49752
49822
|
// packages/server/src/boot-progress.ts
|
|
49753
|
-
import { mkdirSync as mkdirSync18, readFileSync as
|
|
49754
|
-
import { basename as basename11, dirname as dirname16, join as
|
|
49823
|
+
import { mkdirSync as mkdirSync18, readFileSync as readFileSync27, renameSync as renameSync10, rmSync as rmSync10, writeFileSync as writeFileSync15 } from "node:fs";
|
|
49824
|
+
import { basename as basename11, dirname as dirname16, join as join40 } from "node:path";
|
|
49755
49825
|
function bootProgressPath(stateDir) {
|
|
49756
|
-
return
|
|
49826
|
+
return join40(stateDir, BOOT_PROGRESS_NAME);
|
|
49757
49827
|
}
|
|
49758
49828
|
function createBootProgressPublisher(stateDir, minIntervalMs = 200) {
|
|
49759
49829
|
if (!stateDir) {
|
|
@@ -49774,7 +49844,7 @@ function createBootProgressPublisher(stateDir, minIntervalMs = 200) {
|
|
|
49774
49844
|
step++;
|
|
49775
49845
|
try {
|
|
49776
49846
|
mkdirSync18(dirname16(path), { recursive: true, mode: 448 });
|
|
49777
|
-
const temp =
|
|
49847
|
+
const temp = join40(dirname16(path), `.${basename11(path)}.${process.pid}.tmp`);
|
|
49778
49848
|
writeFileSync15(temp, `${JSON.stringify({ pid: process.pid, step, phase, at: new Date(now).toISOString() })}
|
|
49779
49849
|
`, "utf8");
|
|
49780
49850
|
renameSync10(temp, path);
|
|
@@ -49891,11 +49961,11 @@ __export(index_exports, {
|
|
|
49891
49961
|
unknownProjectPage: () => unknownProjectPage
|
|
49892
49962
|
});
|
|
49893
49963
|
import { createServer } from "node:http";
|
|
49894
|
-
import { readFileSync as
|
|
49895
|
-
import { dirname as dirname17, join as
|
|
49964
|
+
import { readFileSync as readFileSync28, existsSync as existsSync15 } from "node:fs";
|
|
49965
|
+
import { dirname as dirname17, join as join41, resolve as resolve9, extname as extname4, normalize } from "node:path";
|
|
49896
49966
|
function readServerAddressHolder(path) {
|
|
49897
49967
|
try {
|
|
49898
|
-
const value = JSON.parse(
|
|
49968
|
+
const value = JSON.parse(readFileSync28(path, "utf8"));
|
|
49899
49969
|
if (typeof value?.pid !== "number") return void 0;
|
|
49900
49970
|
return { pid: value.pid, port: typeof value.port === "number" ? value.port : -1 };
|
|
49901
49971
|
} catch {
|
|
@@ -49995,11 +50065,11 @@ function createShutdownSignalHandler(options) {
|
|
|
49995
50065
|
}
|
|
49996
50066
|
function serveStatic(distDir, req, res) {
|
|
49997
50067
|
const rel = normalize((req.url ?? "/").split("?")[0]).replace(/^(\.\.[/\\])+/, "");
|
|
49998
|
-
let file =
|
|
49999
|
-
if (!file.startsWith(distDir)) file =
|
|
50000
|
-
if (!existsSync15(file)) file =
|
|
50068
|
+
let file = join41(distDir, rel === "/" ? "index.html" : rel);
|
|
50069
|
+
if (!file.startsWith(distDir)) file = join41(distDir, "index.html");
|
|
50070
|
+
if (!existsSync15(file)) file = join41(distDir, "index.html");
|
|
50001
50071
|
try {
|
|
50002
|
-
const body =
|
|
50072
|
+
const body = readFileSync28(file);
|
|
50003
50073
|
res.writeHead(200, { "content-type": MIME[extname4(file)] ?? "application/octet-stream" });
|
|
50004
50074
|
res.end(body);
|
|
50005
50075
|
} catch {
|
|
@@ -50348,7 +50418,7 @@ async function startServer(opts = {}) {
|
|
|
50348
50418
|
}
|
|
50349
50419
|
statusPath = serverLockPathFor(ctx.project);
|
|
50350
50420
|
const webRoot = resolve9(import.meta.dirname, "..", "..", "web");
|
|
50351
|
-
const distDir = opts.webDistDir ? resolve9(opts.webDistDir) :
|
|
50421
|
+
const distDir = opts.webDistDir ? resolve9(opts.webDistDir) : join41(webRoot, "dist");
|
|
50352
50422
|
startupPhase = "Vite";
|
|
50353
50423
|
if (opts.dev) {
|
|
50354
50424
|
try {
|
|
@@ -50424,7 +50494,7 @@ async function startServer(opts = {}) {
|
|
|
50424
50494
|
if (vite) {
|
|
50425
50495
|
vite.middlewares(req, res, () => {
|
|
50426
50496
|
try {
|
|
50427
|
-
const html =
|
|
50497
|
+
const html = readFileSync28(join41(webRoot, "index.html"), "utf8");
|
|
50428
50498
|
void vite.transformIndexHtml(url, html).then((out) => {
|
|
50429
50499
|
res.writeHead(200, { "content-type": "text/html" });
|
|
50430
50500
|
res.end(out);
|
|
@@ -50616,7 +50686,7 @@ var init_index = __esm({
|
|
|
50616
50686
|
}
|
|
50617
50687
|
};
|
|
50618
50688
|
isApiUrl = (url) => url === FRIZZ_ROUTE_PREFIX || url.startsWith(`${FRIZZ_ROUTE_PREFIX}/`);
|
|
50619
|
-
serverLockPathFor = (project) =>
|
|
50689
|
+
serverLockPathFor = (project) => join41(project.stateDir, "server.lock");
|
|
50620
50690
|
MIME = {
|
|
50621
50691
|
".html": "text/html",
|
|
50622
50692
|
".js": "text/javascript",
|
|
@@ -50635,7 +50705,7 @@ init_project_launch();
|
|
|
50635
50705
|
init_shutdown();
|
|
50636
50706
|
init_logging();
|
|
50637
50707
|
import { existsSync as existsSync16 } from "node:fs";
|
|
50638
|
-
import { join as
|
|
50708
|
+
import { join as join42 } from "node:path";
|
|
50639
50709
|
process.on("uncaughtException", (error) => {
|
|
50640
50710
|
log.error("dev-child", `uncaught exception: ${error instanceof Error ? error.stack ?? error.message : error}`);
|
|
50641
50711
|
process.exit(1);
|
|
@@ -50675,7 +50745,7 @@ try {
|
|
|
50675
50745
|
];
|
|
50676
50746
|
if (!existsSync16(stableWebDist)) throw new Error("stable artifact launch is missing its verified web directory");
|
|
50677
50747
|
for (const [name, directory, requiredFile] of required) {
|
|
50678
|
-
if (!directory || !existsSync16(
|
|
50748
|
+
if (!directory || !existsSync16(join42(directory, requiredFile)))
|
|
50679
50749
|
throw new Error(`stable artifact launch is missing verified ${name}`);
|
|
50680
50750
|
}
|
|
50681
50751
|
}
|