frizz 0.7.3 → 0.7.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dev-child.js +246 -195
- package/dist/frizz.js +70 -36
- package/package.json +1 -1
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);
|
|
@@ -14925,9 +14959,9 @@ ${DISPATCH_TASK_BANNER}
|
|
|
14925
14959
|
// packages/server/src/project-registry.ts
|
|
14926
14960
|
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
14961
|
import { homedir as homedir4 } from "node:os";
|
|
14928
|
-
import { basename, dirname as dirname4, join as
|
|
14962
|
+
import { basename, dirname as dirname4, join as join5 } from "node:path";
|
|
14929
14963
|
function registryPath(home = homedir4()) {
|
|
14930
|
-
return
|
|
14964
|
+
return join5(frizzPaths({ home }).data, "registry.json");
|
|
14931
14965
|
}
|
|
14932
14966
|
function readRegistry(home = homedir4()) {
|
|
14933
14967
|
let raw2;
|
|
@@ -15016,7 +15050,7 @@ function registerProject(input, home = homedir4()) {
|
|
|
15016
15050
|
writeRegistry(registry, home);
|
|
15017
15051
|
return { entry: byId, action: "reopened" };
|
|
15018
15052
|
}
|
|
15019
|
-
if (existsSync3(
|
|
15053
|
+
if (existsSync3(join5(byId.path, ".frizz", ".id"))) return { action: "duplicate" };
|
|
15020
15054
|
byId.path = input.dir;
|
|
15021
15055
|
byId.lastOpenedAt = at;
|
|
15022
15056
|
writeRegistry(registry, home);
|
|
@@ -15043,14 +15077,14 @@ function registerProject(input, home = homedir4()) {
|
|
|
15043
15077
|
function backfillRegistry(home = homedir4(), read = existingProjectId) {
|
|
15044
15078
|
let dirs;
|
|
15045
15079
|
try {
|
|
15046
|
-
dirs = readdirSync(
|
|
15080
|
+
dirs = readdirSync(join5(frizzPaths({ home }).data, "projects"), { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
|
|
15047
15081
|
} catch {
|
|
15048
15082
|
return 0;
|
|
15049
15083
|
}
|
|
15050
15084
|
const known = new Set(readRegistry(home).projects.map((p) => p.path));
|
|
15051
15085
|
let added = 0;
|
|
15052
15086
|
for (const id of dirs) {
|
|
15053
|
-
const recorded = recordedProjectDir(
|
|
15087
|
+
const recorded = recordedProjectDir(join5(frizzPaths({ home }).data, "projects", id));
|
|
15054
15088
|
const dir = recorded ? canonicalPath(recorded) : void 0;
|
|
15055
15089
|
if (!dir || known.has(dir)) continue;
|
|
15056
15090
|
if (read(dir) !== id) continue;
|
|
@@ -15068,7 +15102,7 @@ function backfillRegistry(home = homedir4(), read = existingProjectId) {
|
|
|
15068
15102
|
function recordedProjectDir(stateDir) {
|
|
15069
15103
|
for (const name of ["launcher.json", "server.lock", "project-launch.owner"]) {
|
|
15070
15104
|
try {
|
|
15071
|
-
const value = JSON.parse(readFileSync4(
|
|
15105
|
+
const value = JSON.parse(readFileSync4(join5(stateDir, name), "utf8")).projectDir;
|
|
15072
15106
|
if (typeof value === "string" && value.length > 0 && existsSync3(value)) return value;
|
|
15073
15107
|
} catch {
|
|
15074
15108
|
}
|
|
@@ -15111,7 +15145,7 @@ function findProjectBySegment(segment, home = homedir4()) {
|
|
|
15111
15145
|
return findBySlug(segment, home) ?? findById(segment, home);
|
|
15112
15146
|
}
|
|
15113
15147
|
function customIconPath(id, extension2, home = homedir4()) {
|
|
15114
|
-
return
|
|
15148
|
+
return join5(frizzPaths({ home }).data, "projects", id, `icon${extension2}`);
|
|
15115
15149
|
}
|
|
15116
15150
|
function updateEntry(id, apply, home) {
|
|
15117
15151
|
const registry = readRegistry(home);
|
|
@@ -15576,7 +15610,7 @@ CI (PRs): \`gh pr checks {n} -R {repo}\``;
|
|
|
15576
15610
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
15577
15611
|
import { mkdirSync as mkdirSync4, realpathSync as realpathSync4 } from "node:fs";
|
|
15578
15612
|
import { homedir as homedir5, tmpdir as tmpdir2 } from "node:os";
|
|
15579
|
-
import { basename as basename2, join as
|
|
15613
|
+
import { basename as basename2, join as join6, resolve as resolve3 } from "node:path";
|
|
15580
15614
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
15581
15615
|
function projectRepoIdentity(dir, name) {
|
|
15582
15616
|
const url = originRemoteUrl(dir);
|
|
@@ -15585,7 +15619,7 @@ function projectRepoIdentity(dir, name) {
|
|
|
15585
15619
|
return { label: parseRepoLabel(url) ?? name, ...githubRepo ? { githubRepo } : {} };
|
|
15586
15620
|
}
|
|
15587
15621
|
function trustedLocalFileRoots(project) {
|
|
15588
|
-
return [project.dir, tmpdir2(), "/tmp", resolve3(homedir5(), "Screenshots"),
|
|
15622
|
+
return [project.dir, tmpdir2(), "/tmp", resolve3(homedir5(), "Screenshots"), join6(project.stateDir, "attachments")];
|
|
15589
15623
|
}
|
|
15590
15624
|
function openableFileRoots(project) {
|
|
15591
15625
|
return [homedir5(), ...trustedLocalFileRoots(project)];
|
|
@@ -15691,10 +15725,10 @@ function resolveProject(cwd = process.cwd(), home = homedir5(), env = process.en
|
|
|
15691
15725
|
};
|
|
15692
15726
|
}
|
|
15693
15727
|
function permRequestDir(project) {
|
|
15694
|
-
return
|
|
15728
|
+
return join6(project.stateDir, "perm-requests");
|
|
15695
15729
|
}
|
|
15696
15730
|
function permMarkerPath(project, slug) {
|
|
15697
|
-
return
|
|
15731
|
+
return join6(permRequestDir(project), `${slug}.json`);
|
|
15698
15732
|
}
|
|
15699
15733
|
function projectLaunchTarget(project) {
|
|
15700
15734
|
return {
|
|
@@ -15749,7 +15783,7 @@ import {
|
|
|
15749
15783
|
statSync as statSync2,
|
|
15750
15784
|
writeFileSync as writeFileSync4
|
|
15751
15785
|
} from "node:fs";
|
|
15752
|
-
import { basename as basename3, dirname as dirname5, isAbsolute, join as
|
|
15786
|
+
import { basename as basename3, dirname as dirname5, isAbsolute, join as join7 } from "node:path";
|
|
15753
15787
|
function errorCode3(error) {
|
|
15754
15788
|
return error && typeof error === "object" && "code" in error && typeof error.code === "string" ? error.code : void 0;
|
|
15755
15789
|
}
|
|
@@ -15773,7 +15807,7 @@ function syncDirectory2(path) {
|
|
|
15773
15807
|
}
|
|
15774
15808
|
function atomicJson(path, value) {
|
|
15775
15809
|
mkdirSync5(dirname5(path), { recursive: true, mode: 448 });
|
|
15776
|
-
const temp =
|
|
15810
|
+
const temp = join7(dirname5(path), `.${basename3(path)}.${process.pid}.${randomUUID5()}.tmp`);
|
|
15777
15811
|
let fd;
|
|
15778
15812
|
try {
|
|
15779
15813
|
fd = openSync4(temp, "wx", 384);
|
|
@@ -15832,7 +15866,7 @@ function parseGuard(path) {
|
|
|
15832
15866
|
}
|
|
15833
15867
|
}
|
|
15834
15868
|
function acquireMutationGuard(stateDir, timeoutMs = GUARD_TIMEOUT_MS, adapter = defaultProcessPlatformAdapter) {
|
|
15835
|
-
const path =
|
|
15869
|
+
const path = join7(stateDir, MUTATION_GUARD_NAME);
|
|
15836
15870
|
mkdirSync5(stateDir, { recursive: true, mode: 448 });
|
|
15837
15871
|
const deadline = adapter.now() + Math.max(0, timeoutMs);
|
|
15838
15872
|
for (; ; ) {
|
|
@@ -15926,7 +15960,7 @@ function parseOwner(path) {
|
|
|
15926
15960
|
}
|
|
15927
15961
|
}
|
|
15928
15962
|
function projectLaunchOwnerPath(stateDir) {
|
|
15929
|
-
return
|
|
15963
|
+
return join7(stateDir, OWNER_NAME);
|
|
15930
15964
|
}
|
|
15931
15965
|
function servedByAnotherProcess(stateDir, projectId, self = process.pid, alive = pidIsAlive) {
|
|
15932
15966
|
const owner = readProjectLaunchOwner(stateDir);
|
|
@@ -15949,7 +15983,7 @@ function projectLaunchTokenProof(target, token) {
|
|
|
15949
15983
|
}
|
|
15950
15984
|
function removeStatusesForToken(stateDir, token) {
|
|
15951
15985
|
for (const name of ["dev-supervisor.lock", "server.lock"]) {
|
|
15952
|
-
const path =
|
|
15986
|
+
const path = join7(stateDir, name);
|
|
15953
15987
|
try {
|
|
15954
15988
|
const value = JSON.parse(readFileSync5(path, "utf8"));
|
|
15955
15989
|
if (value.ownerToken === token) quarantine(path, "stale");
|
|
@@ -16450,9 +16484,9 @@ import {
|
|
|
16450
16484
|
writeSync
|
|
16451
16485
|
} from "node:fs";
|
|
16452
16486
|
import { homedir as homedir6 } from "node:os";
|
|
16453
|
-
import { join as
|
|
16487
|
+
import { join as join8 } from "node:path";
|
|
16454
16488
|
function defaultLogRoot(stateDir, home = homedir6()) {
|
|
16455
|
-
return stateDir ?
|
|
16489
|
+
return stateDir ? join8(stateDir, "logs") : join8(frizzPaths({ home }).state, "logs");
|
|
16456
16490
|
}
|
|
16457
16491
|
function runStamp(at) {
|
|
16458
16492
|
const pad = (value) => String(value).padStart(2, "0");
|
|
@@ -16461,11 +16495,11 @@ function runStamp(at) {
|
|
|
16461
16495
|
function runLogPath(stateDir, at = /* @__PURE__ */ new Date(), pid = process.pid, home = homedir6(), env = process.env) {
|
|
16462
16496
|
const name = `frizz-${runStamp(at)}-${pid}.log`;
|
|
16463
16497
|
const override = env[LOG_PATH_ENV]?.trim();
|
|
16464
|
-
if (override) return override.endsWith(".log") ? override :
|
|
16465
|
-
return
|
|
16498
|
+
if (override) return override.endsWith(".log") ? override : join8(override, name);
|
|
16499
|
+
return join8(defaultLogRoot(stateDir, home), name);
|
|
16466
16500
|
}
|
|
16467
16501
|
function latestLogPath(dir) {
|
|
16468
|
-
return
|
|
16502
|
+
return join8(dir, "latest.log");
|
|
16469
16503
|
}
|
|
16470
16504
|
function linkLatest(dir, target) {
|
|
16471
16505
|
const link = latestLogPath(dir);
|
|
@@ -16489,7 +16523,7 @@ function pruneRunLogs(dir, keep = RETAINED_RUNS, days = RETAINED_DAYS, now = Dat
|
|
|
16489
16523
|
}
|
|
16490
16524
|
const dated = entries.map((name) => {
|
|
16491
16525
|
try {
|
|
16492
|
-
return { name, at: statSync3(
|
|
16526
|
+
return { name, at: statSync3(join8(dir, name)).mtimeMs };
|
|
16493
16527
|
} catch {
|
|
16494
16528
|
return { name, at: 0 };
|
|
16495
16529
|
}
|
|
@@ -16498,7 +16532,7 @@ function pruneRunLogs(dir, keep = RETAINED_RUNS, days = RETAINED_DAYS, now = Dat
|
|
|
16498
16532
|
const stale = dated.filter((entry, index) => index >= keep || entry.at < cutoff);
|
|
16499
16533
|
for (const entry of stale) {
|
|
16500
16534
|
try {
|
|
16501
|
-
rmSync5(
|
|
16535
|
+
rmSync5(join8(dir, entry.name), { force: true });
|
|
16502
16536
|
} catch {
|
|
16503
16537
|
}
|
|
16504
16538
|
}
|
|
@@ -16512,7 +16546,7 @@ function formatDiskLine(record) {
|
|
|
16512
16546
|
}
|
|
16513
16547
|
function openLogFile(path) {
|
|
16514
16548
|
try {
|
|
16515
|
-
mkdirSync6(
|
|
16549
|
+
mkdirSync6(join8(path, ".."), { recursive: true, mode: 448 });
|
|
16516
16550
|
return openSync5(path, "a", 384);
|
|
16517
16551
|
} catch {
|
|
16518
16552
|
return null;
|
|
@@ -16526,7 +16560,7 @@ function createLogger(options = {}) {
|
|
|
16526
16560
|
const maxBytes = options.maxBytes ?? MAX_LOG_BYTES;
|
|
16527
16561
|
let fd = path === null ? null : openLogFile(path);
|
|
16528
16562
|
if (fd !== null && path !== null && options.owner !== false) {
|
|
16529
|
-
const dir =
|
|
16563
|
+
const dir = join8(path, "..");
|
|
16530
16564
|
pruneRunLogs(dir);
|
|
16531
16565
|
linkLatest(dir, path);
|
|
16532
16566
|
}
|
|
@@ -19475,9 +19509,9 @@ var init_storage = __esm({
|
|
|
19475
19509
|
|
|
19476
19510
|
// packages/server/src/settings.ts
|
|
19477
19511
|
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
|
|
19512
|
+
import { dirname as dirname6, join as join9 } from "node:path";
|
|
19479
19513
|
function machineSettingsPath(home) {
|
|
19480
|
-
return
|
|
19514
|
+
return join9(frizzPaths({ home }).data, "settings.json");
|
|
19481
19515
|
}
|
|
19482
19516
|
function pickMachine(settings) {
|
|
19483
19517
|
return Object.fromEntries(MACHINE_KEYS.map((key) => [key, settings[key]]));
|
|
@@ -19571,7 +19605,7 @@ var init_settings = __esm({
|
|
|
19571
19605
|
|
|
19572
19606
|
// packages/server/src/discover.ts
|
|
19573
19607
|
import { readdirSync as readdirSync3, statSync as statSync4, openSync as openSync7, readSync, closeSync as closeSync6 } from "node:fs";
|
|
19574
|
-
import { dirname as dirname7, join as
|
|
19608
|
+
import { dirname as dirname7, join as join10 } from "node:path";
|
|
19575
19609
|
function sentinelFor(sessionId) {
|
|
19576
19610
|
return `threads/${sessionId}/`;
|
|
19577
19611
|
}
|
|
@@ -19608,7 +19642,7 @@ function discoverTranscriptId(logDir, sessionId, opts = {}) {
|
|
|
19608
19642
|
if (name.startsWith(".") || !name.endsWith(".jsonl")) continue;
|
|
19609
19643
|
const id = name.slice(0, -".jsonl".length);
|
|
19610
19644
|
if (!id || id === sessionId || exclude?.has(id)) continue;
|
|
19611
|
-
const path =
|
|
19645
|
+
const path = join10(logDir, name);
|
|
19612
19646
|
let mtime;
|
|
19613
19647
|
try {
|
|
19614
19648
|
mtime = statSync4(path).mtimeMs;
|
|
@@ -19636,7 +19670,7 @@ function discoverTranscriptDir(logDir, sessionId, memo3 = strandedLogDirs) {
|
|
|
19636
19670
|
const name = `${sessionId}.jsonl`;
|
|
19637
19671
|
const better = (best2, dir) => {
|
|
19638
19672
|
if (dir === logDir) return best2;
|
|
19639
|
-
const at = mtimeOfNonEmpty(
|
|
19673
|
+
const at = mtimeOfNonEmpty(join10(dir, name));
|
|
19640
19674
|
if (at === void 0) return best2;
|
|
19641
19675
|
return !best2 || at > best2.mtimeMs ? { dir, mtimeMs: at } : best2;
|
|
19642
19676
|
};
|
|
@@ -19649,7 +19683,7 @@ function discoverTranscriptDir(logDir, sessionId, memo3 = strandedLogDirs) {
|
|
|
19649
19683
|
} catch {
|
|
19650
19684
|
return void 0;
|
|
19651
19685
|
}
|
|
19652
|
-
for (const entry of entries) best = better(best,
|
|
19686
|
+
for (const entry of entries) best = better(best, join10(dirname7(logDir), entry));
|
|
19653
19687
|
if (!best) return void 0;
|
|
19654
19688
|
memo3.add(best.dir);
|
|
19655
19689
|
return best.dir;
|
|
@@ -19668,10 +19702,10 @@ var init_discover = __esm({
|
|
|
19668
19702
|
|
|
19669
19703
|
// packages/server/src/session-files.ts
|
|
19670
19704
|
import { lstatSync, rmSync as rmSync7 } from "node:fs";
|
|
19671
|
-
import { join as
|
|
19705
|
+
import { join as join11 } from "node:path";
|
|
19672
19706
|
function systemPromptPath(sessionId) {
|
|
19673
19707
|
if (!SESSION_ID_RE.test(sessionId)) throw new Error("invalid session id");
|
|
19674
|
-
return
|
|
19708
|
+
return join11(SYSTEM_PROMPT_DIR, `${sessionId}.md`);
|
|
19675
19709
|
}
|
|
19676
19710
|
function isDirectDirectory(path) {
|
|
19677
19711
|
try {
|
|
@@ -19691,7 +19725,7 @@ function pathAbsent(path) {
|
|
|
19691
19725
|
}
|
|
19692
19726
|
function unlinkDirectChild(parent, filename) {
|
|
19693
19727
|
if (!isDirectDirectory(parent)) return pathAbsent(parent);
|
|
19694
|
-
const child =
|
|
19728
|
+
const child = join11(parent, filename);
|
|
19695
19729
|
try {
|
|
19696
19730
|
rmSync7(child, { force: true });
|
|
19697
19731
|
} catch {
|
|
@@ -19701,12 +19735,12 @@ function unlinkDirectChild(parent, filename) {
|
|
|
19701
19735
|
}
|
|
19702
19736
|
function cleanupAdoptionSessionFiles(projectDir, sessionId) {
|
|
19703
19737
|
if (!SESSION_ID_RE.test(sessionId)) return false;
|
|
19704
|
-
const frizzDir =
|
|
19738
|
+
const frizzDir = join11(projectDir, ".frizz");
|
|
19705
19739
|
let clean = true;
|
|
19706
19740
|
if (isDirectDirectory(frizzDir)) {
|
|
19707
|
-
const threads =
|
|
19741
|
+
const threads = join11(frizzDir, "threads");
|
|
19708
19742
|
if (isDirectDirectory(threads)) {
|
|
19709
|
-
const child =
|
|
19743
|
+
const child = join11(threads, sessionId);
|
|
19710
19744
|
try {
|
|
19711
19745
|
rmSync7(child, { recursive: true, force: true });
|
|
19712
19746
|
} catch {
|
|
@@ -19958,10 +19992,10 @@ var init_adoption_recovery = __esm({
|
|
|
19958
19992
|
});
|
|
19959
19993
|
|
|
19960
19994
|
// packages/server/src/backend/codex-models.ts
|
|
19961
|
-
import { join as
|
|
19995
|
+
import { join as join12 } from "node:path";
|
|
19962
19996
|
import { readFileSync as readFileSync7 } from "node:fs";
|
|
19963
19997
|
function cachePath(codexHome) {
|
|
19964
|
-
return
|
|
19998
|
+
return join12(codexHome, "models_cache.json");
|
|
19965
19999
|
}
|
|
19966
20000
|
function toCodexModel(raw2) {
|
|
19967
20001
|
if (!raw2 || typeof raw2 !== "object") return void 0;
|
|
@@ -20540,9 +20574,9 @@ var init_claude_agent_sdk_protocol = __esm({
|
|
|
20540
20574
|
|
|
20541
20575
|
// packages/server/src/backend/claude-broker-diagnostics.ts
|
|
20542
20576
|
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync8, readFileSync as readFileSync8, renameSync as renameSync6, statSync as statSync5 } from "node:fs";
|
|
20543
|
-
import { join as
|
|
20577
|
+
import { join as join13 } from "node:path";
|
|
20544
20578
|
function claudeBrokerDiagnosticLogPath(stateDir, sessionId) {
|
|
20545
|
-
return
|
|
20579
|
+
return join13(stateDir, "claude-broker", `${sessionId}.diagnostics.log`);
|
|
20546
20580
|
}
|
|
20547
20581
|
function readClaudeBrokerExit(stateDir, sessionId, generation) {
|
|
20548
20582
|
if (!generation) return null;
|
|
@@ -20614,10 +20648,10 @@ var init_detached_daemons = __esm({
|
|
|
20614
20648
|
});
|
|
20615
20649
|
|
|
20616
20650
|
// packages/server/src/backend/ipc-path.ts
|
|
20617
|
-
import { join as
|
|
20651
|
+
import { join as join14 } from "node:path";
|
|
20618
20652
|
function frizzIpcPath(name) {
|
|
20619
20653
|
if (process.platform === "win32") return `\\\\.\\pipe\\${name}`;
|
|
20620
|
-
return
|
|
20654
|
+
return join14(process.env.TMPDIR ?? "/tmp", `${name}.sock`);
|
|
20621
20655
|
}
|
|
20622
20656
|
var init_ipc_path = __esm({
|
|
20623
20657
|
"packages/server/src/backend/ipc-path.ts"() {
|
|
@@ -20629,7 +20663,7 @@ var init_ipc_path = __esm({
|
|
|
20629
20663
|
import { spawn } from "node:child_process";
|
|
20630
20664
|
import { createHash as createHash5, randomUUID as randomUUID8 } from "node:crypto";
|
|
20631
20665
|
import { accessSync, constants as fsConstants, mkdirSync as mkdirSync9, readFileSync as readFileSync9, readdirSync as readdirSync4, unlinkSync, writeFileSync as writeFileSync7 } from "node:fs";
|
|
20632
|
-
import { delimiter, dirname as dirname8, isAbsolute as isAbsolute2, join as
|
|
20666
|
+
import { delimiter, dirname as dirname8, isAbsolute as isAbsolute2, join as join15 } from "node:path";
|
|
20633
20667
|
function windowsShimTarget(shimPath) {
|
|
20634
20668
|
let body;
|
|
20635
20669
|
try {
|
|
@@ -20639,7 +20673,7 @@ function windowsShimTarget(shimPath) {
|
|
|
20639
20673
|
}
|
|
20640
20674
|
const target = WINDOWS_SHIM_TARGET.exec(body)?.[1];
|
|
20641
20675
|
if (!target) return void 0;
|
|
20642
|
-
const full =
|
|
20676
|
+
const full = join15(dirname8(shimPath), target);
|
|
20643
20677
|
try {
|
|
20644
20678
|
accessSync(full, fsConstants.F_OK);
|
|
20645
20679
|
return full;
|
|
@@ -20647,24 +20681,30 @@ function windowsShimTarget(shimPath) {
|
|
|
20647
20681
|
return void 0;
|
|
20648
20682
|
}
|
|
20649
20683
|
}
|
|
20684
|
+
function searchPath(env) {
|
|
20685
|
+
const direct = env.PATH ?? env.Path ?? env.path;
|
|
20686
|
+
if (direct !== void 0) return direct;
|
|
20687
|
+
for (const [key, value] of Object.entries(env)) if (key.toLowerCase() === "path") return value ?? "";
|
|
20688
|
+
return "";
|
|
20689
|
+
}
|
|
20650
20690
|
function resolveClaudeExecutableAbsolute(bin, env = process.env) {
|
|
20651
20691
|
const candidate = bin && bin.length > 0 ? bin : "claude";
|
|
20652
20692
|
if (isAbsolute2(candidate)) return candidate;
|
|
20653
20693
|
const windows = process.platform === "win32";
|
|
20654
|
-
for (const dir of (env
|
|
20694
|
+
for (const dir of searchPath(env).split(delimiter)) {
|
|
20655
20695
|
if (!dir) continue;
|
|
20656
20696
|
if (windows) {
|
|
20657
|
-
const exe =
|
|
20697
|
+
const exe = join15(dir, `${candidate}.exe`);
|
|
20658
20698
|
try {
|
|
20659
20699
|
accessSync(exe, fsConstants.F_OK);
|
|
20660
20700
|
return exe;
|
|
20661
20701
|
} catch {
|
|
20662
20702
|
}
|
|
20663
|
-
const viaShim = windowsShimTarget(
|
|
20703
|
+
const viaShim = windowsShimTarget(join15(dir, `${candidate}.cmd`));
|
|
20664
20704
|
if (viaShim) return viaShim;
|
|
20665
20705
|
continue;
|
|
20666
20706
|
}
|
|
20667
|
-
const full =
|
|
20707
|
+
const full = join15(dir, candidate);
|
|
20668
20708
|
try {
|
|
20669
20709
|
accessSync(full, fsConstants.X_OK);
|
|
20670
20710
|
return full;
|
|
@@ -20679,11 +20719,11 @@ function claudeBrokerSocketPath(stateDir, sessionId) {
|
|
|
20679
20719
|
}
|
|
20680
20720
|
function claudeBrokerRecordPath(stateDir, sessionId) {
|
|
20681
20721
|
const key = createHash5("sha256").update(sessionId).digest("hex").slice(0, 16);
|
|
20682
|
-
return
|
|
20722
|
+
return join15(stateDir, "claude-broker", `${key}.json`);
|
|
20683
20723
|
}
|
|
20684
20724
|
function claudeBrokerRetirementPath(stateDir, sessionId) {
|
|
20685
20725
|
const key = createHash5("sha256").update(sessionId).digest("hex").slice(0, 16);
|
|
20686
|
-
return
|
|
20726
|
+
return join15(stateDir, "claude-broker", `${key}.retired`);
|
|
20687
20727
|
}
|
|
20688
20728
|
function markBrokerRetired(stateDir, sessionId, reason, generation) {
|
|
20689
20729
|
const mark = { at: (/* @__PURE__ */ new Date()).toISOString(), generation, reason };
|
|
@@ -20750,7 +20790,7 @@ function liveBrokerRecord(recordPath2) {
|
|
|
20750
20790
|
return null;
|
|
20751
20791
|
}
|
|
20752
20792
|
function liveBrokerRecords(stateDir) {
|
|
20753
|
-
const dir =
|
|
20793
|
+
const dir = join15(stateDir, "claude-broker");
|
|
20754
20794
|
let names;
|
|
20755
20795
|
try {
|
|
20756
20796
|
names = readdirSync4(dir);
|
|
@@ -20760,7 +20800,7 @@ function liveBrokerRecords(stateDir) {
|
|
|
20760
20800
|
const out = [];
|
|
20761
20801
|
for (const name of names) {
|
|
20762
20802
|
if (!name.endsWith(".json")) continue;
|
|
20763
|
-
const record = liveBrokerRecord(
|
|
20803
|
+
const record = liveBrokerRecord(join15(dir, name));
|
|
20764
20804
|
if (record) out.push(record);
|
|
20765
20805
|
}
|
|
20766
20806
|
return out;
|
|
@@ -21569,14 +21609,14 @@ var init_completion_relay = __esm({
|
|
|
21569
21609
|
// packages/server/src/tail-cache.ts
|
|
21570
21610
|
import { createHash as createHash6 } from "node:crypto";
|
|
21571
21611
|
import { closeSync as closeSync8, openSync as openSync9, readFileSync as readFileSync10, readSync as readSync3, statSync as statSync7 } from "node:fs";
|
|
21572
|
-
import { join as
|
|
21612
|
+
import { join as join16 } from "node:path";
|
|
21573
21613
|
function foldSchemaDigest(dir = import.meta.dirname) {
|
|
21574
21614
|
if (foldSchemaMemo) return foldSchemaMemo;
|
|
21575
21615
|
const hash = createHash6("sha256").update("frizz-tail-state-v1\0");
|
|
21576
21616
|
let read = 0;
|
|
21577
21617
|
for (const name of FOLD_SOURCES) {
|
|
21578
21618
|
try {
|
|
21579
|
-
hash.update(name).update("\0").update(readFileSync10(
|
|
21619
|
+
hash.update(name).update("\0").update(readFileSync10(join16(dir, name)));
|
|
21580
21620
|
read++;
|
|
21581
21621
|
} catch {
|
|
21582
21622
|
hash.update(name).update("\0missing\0");
|
|
@@ -21774,7 +21814,7 @@ var init_tail_cache = __esm({
|
|
|
21774
21814
|
// packages/server/src/tailer.ts
|
|
21775
21815
|
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 readFileSync11, existsSync as existsSync5 } from "node:fs";
|
|
21776
21816
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
21777
|
-
import { basename as basename4, join as
|
|
21817
|
+
import { basename as basename4, join as join17 } from "node:path";
|
|
21778
21818
|
import { homedir as homedir7 } from "node:os";
|
|
21779
21819
|
function probeShellAlive(outputFile) {
|
|
21780
21820
|
if (!existsSync5(outputFile)) return void 0;
|
|
@@ -22036,7 +22076,7 @@ function launchTaskId(text) {
|
|
|
22036
22076
|
function readDescendantSidecars(sessionDir, mtimeMs) {
|
|
22037
22077
|
let names;
|
|
22038
22078
|
try {
|
|
22039
|
-
names = readdirSync5(
|
|
22079
|
+
names = readdirSync5(join17(sessionDir, "subagents"));
|
|
22040
22080
|
} catch {
|
|
22041
22081
|
return [];
|
|
22042
22082
|
}
|
|
@@ -22047,7 +22087,7 @@ function readDescendantSidecars(sessionDir, mtimeMs) {
|
|
|
22047
22087
|
if (!agentId) continue;
|
|
22048
22088
|
let parsed;
|
|
22049
22089
|
try {
|
|
22050
|
-
parsed = JSON.parse(readFileSync11(
|
|
22090
|
+
parsed = JSON.parse(readFileSync11(join17(sessionDir, "subagents", name), "utf8"));
|
|
22051
22091
|
} catch {
|
|
22052
22092
|
continue;
|
|
22053
22093
|
}
|
|
@@ -22061,7 +22101,7 @@ function readDescendantSidecars(sessionDir, mtimeMs) {
|
|
|
22061
22101
|
agentType: text(meta.agentType),
|
|
22062
22102
|
parentAgentId: text(meta.parentAgentId),
|
|
22063
22103
|
spawnDepth: typeof meta.spawnDepth === "number" && Number.isFinite(meta.spawnDepth) ? meta.spawnDepth : void 0,
|
|
22064
|
-
spawnedAtMs: mtimeMs(
|
|
22104
|
+
spawnedAtMs: mtimeMs(join17(sessionDir, "subagents", name))
|
|
22065
22105
|
});
|
|
22066
22106
|
}
|
|
22067
22107
|
return out;
|
|
@@ -22541,7 +22581,7 @@ function defaultMtimeMs(path) {
|
|
|
22541
22581
|
}
|
|
22542
22582
|
}
|
|
22543
22583
|
function defaultLogDir(project) {
|
|
22544
|
-
return
|
|
22584
|
+
return join17(homedir7(), ".claude", "projects", project.cwdSlug);
|
|
22545
22585
|
}
|
|
22546
22586
|
function defaultReadPermMarker(project) {
|
|
22547
22587
|
if (!project.stateDir) return () => void 0;
|
|
@@ -22587,6 +22627,7 @@ function rowIsArchived(row) {
|
|
|
22587
22627
|
}
|
|
22588
22628
|
function createTailer(deps) {
|
|
22589
22629
|
const now = deps.now ?? Date.now;
|
|
22630
|
+
const monotonicNow = deps.monotonicNow ?? (() => performance.now());
|
|
22590
22631
|
const paneDead = deps.paneDead ?? (() => true);
|
|
22591
22632
|
const brokerDaemonAlive = deps.brokerDaemonAlive ?? defaultBrokerDaemonAlive(deps.project, now);
|
|
22592
22633
|
const logDir = deps.sessionLogDir ?? defaultLogDir(deps.project);
|
|
@@ -22672,7 +22713,7 @@ function createTailer(deps) {
|
|
|
22672
22713
|
return paneDead(row.slug);
|
|
22673
22714
|
}
|
|
22674
22715
|
const defaultBackend = {
|
|
22675
|
-
transcriptPath: (sessionId) =>
|
|
22716
|
+
transcriptPath: (sessionId) => join17(logDir, `${sessionId}.jsonl`),
|
|
22676
22717
|
foldLine: (state, line) => {
|
|
22677
22718
|
const rec = parseLine(line);
|
|
22678
22719
|
if (rec) applyRecord(state, rec);
|
|
@@ -22797,7 +22838,7 @@ ${ask}`;
|
|
|
22797
22838
|
return state.path.replace(/\.jsonl$/, "");
|
|
22798
22839
|
}
|
|
22799
22840
|
function descendantSidecars(state) {
|
|
22800
|
-
const at = mtimeMs(
|
|
22841
|
+
const at = mtimeMs(join17(sessionDirOf(state), "subagents"));
|
|
22801
22842
|
const cached2 = descendantIndex.get(state.slug);
|
|
22802
22843
|
if (cached2 && cached2.at === at) return cached2.all;
|
|
22803
22844
|
const all = readDescendantSidecars(sessionDirOf(state), mtimeMs);
|
|
@@ -22811,7 +22852,7 @@ ${ask}`;
|
|
|
22811
22852
|
return descendantIndex.get(state.slug)?.byToolUse.get(id);
|
|
22812
22853
|
}
|
|
22813
22854
|
function descendantTranscript(state, meta) {
|
|
22814
|
-
return
|
|
22855
|
+
return join17(sessionDirOf(state), "subagents", `agent-${meta.agentId}.jsonl`);
|
|
22815
22856
|
}
|
|
22816
22857
|
function subAgentDescendantTasks(slug, id) {
|
|
22817
22858
|
const state = states.get(slug);
|
|
@@ -23125,7 +23166,7 @@ ${ask}`;
|
|
|
23125
23166
|
if (name.startsWith(".") || !name.endsWith(".jsonl")) continue;
|
|
23126
23167
|
const id = name.slice(0, -".jsonl".length);
|
|
23127
23168
|
if (!id || registered.has(id)) continue;
|
|
23128
|
-
const path =
|
|
23169
|
+
const path = join17(logDir, name);
|
|
23129
23170
|
let mtime;
|
|
23130
23171
|
try {
|
|
23131
23172
|
mtime = statSync8(path).mtimeMs;
|
|
@@ -23397,7 +23438,7 @@ ${ask}`;
|
|
|
23397
23438
|
);
|
|
23398
23439
|
try {
|
|
23399
23440
|
mkdirSync10(stallLogDir, { recursive: true });
|
|
23400
|
-
writeFileSync8(
|
|
23441
|
+
writeFileSync8(join17(stallLogDir, `${row.slug}.stall.log`), `session_id: ${row.session_id}
|
|
23401
23442
|
captured_at: ${new Date(now()).toISOString()}
|
|
23402
23443
|
|
|
23403
23444
|
${detail}
|
|
@@ -23425,7 +23466,7 @@ ${detail}
|
|
|
23425
23466
|
state.nextDiscoverMs = nowMs + DISCOVER_RETRY_MS;
|
|
23426
23467
|
const strandedDir = discoverTranscriptDir(logDir, row.session_id);
|
|
23427
23468
|
if (strandedDir) {
|
|
23428
|
-
state.path =
|
|
23469
|
+
state.path = join17(strandedDir, `${row.session_id}.jsonl`);
|
|
23429
23470
|
state.offset = 0;
|
|
23430
23471
|
state.partial = "";
|
|
23431
23472
|
state.primed = false;
|
|
@@ -23448,7 +23489,7 @@ ${detail}
|
|
|
23448
23489
|
committed = false;
|
|
23449
23490
|
}
|
|
23450
23491
|
if (!committed) return false;
|
|
23451
|
-
state.path =
|
|
23492
|
+
state.path = join17(logDir, `${found}.jsonl`);
|
|
23452
23493
|
state.offset = 0;
|
|
23453
23494
|
state.partial = "";
|
|
23454
23495
|
state.primed = false;
|
|
@@ -23484,7 +23525,7 @@ ${detail}
|
|
|
23484
23525
|
}
|
|
23485
23526
|
let primed = 0;
|
|
23486
23527
|
let primedRows = 0;
|
|
23487
|
-
const tickStartedMs =
|
|
23528
|
+
const tickStartedMs = monotonicNow();
|
|
23488
23529
|
primeIncomplete = false;
|
|
23489
23530
|
for (const row of rows) {
|
|
23490
23531
|
if (primeProgress && primed % PRIME_PROGRESS_EVERY === 0) primeProgress(primed, rows.length);
|
|
@@ -23494,7 +23535,7 @@ ${detail}
|
|
|
23494
23535
|
let state = states.get(row.slug);
|
|
23495
23536
|
const runtimeGeneration = row.runtime_generation ?? 0;
|
|
23496
23537
|
if (!state || state.sessionId !== row.session_id || state.nativeSessionId !== nativeId || state.runtimeGeneration !== runtimeGeneration) {
|
|
23497
|
-
const path = backend.transcriptPath(nativeId) ??
|
|
23538
|
+
const path = backend.transcriptPath(nativeId) ?? join17(logDir, `${nativeId}.jsonl`);
|
|
23498
23539
|
state = newTailState(row.slug, row.session_id, path, false, nativeId, runtimeGeneration);
|
|
23499
23540
|
state.dismissedOps = deps.storage.retiredOps(row.slug, row.session_id);
|
|
23500
23541
|
hydrateFromCache(state, row, nativeId);
|
|
@@ -23512,7 +23553,7 @@ ${detail}
|
|
|
23512
23553
|
// guarantee below. `primedRows > 0` keeps the archive advancing by at least one row per tick
|
|
23513
23554
|
// even if a visible row were somehow to stay cold indefinitely, so deferral can never become
|
|
23514
23555
|
// starvation. The visible row still primes on this same tick; it just is not necessarily first.
|
|
23515
|
-
coldVisibleRow && primedRows > 0 && rowIsArchived(row) || primedRows >= MAX_PRIME_ROWS_PER_TICK || primedRows > 0 &&
|
|
23556
|
+
coldVisibleRow && primedRows > 0 && rowIsArchived(row) || primedRows >= MAX_PRIME_ROWS_PER_TICK || primedRows > 0 && monotonicNow() - tickStartedMs > PRIME_BUDGET_MS
|
|
23516
23557
|
) {
|
|
23517
23558
|
primeIncomplete = true;
|
|
23518
23559
|
continue;
|
|
@@ -23715,11 +23756,11 @@ ${detail}
|
|
|
23715
23756
|
let lastTickMs = 0;
|
|
23716
23757
|
let primeIncomplete = false;
|
|
23717
23758
|
function tickWithBudget() {
|
|
23718
|
-
const started =
|
|
23759
|
+
const started = monotonicNow();
|
|
23719
23760
|
try {
|
|
23720
23761
|
tick();
|
|
23721
23762
|
} finally {
|
|
23722
|
-
const elapsed =
|
|
23763
|
+
const elapsed = monotonicNow() - started;
|
|
23723
23764
|
lastTickMs = elapsed;
|
|
23724
23765
|
lastTickEndedAtMs = now();
|
|
23725
23766
|
if (elapsed > POLL_MS2) {
|
|
@@ -23943,14 +23984,14 @@ var init_tailer = __esm({
|
|
|
23943
23984
|
});
|
|
23944
23985
|
|
|
23945
23986
|
// packages/server/src/backend/codex.ts
|
|
23946
|
-
import { join as
|
|
23987
|
+
import { join as join18 } from "node:path";
|
|
23947
23988
|
import { homedir as homedir8 } from "node:os";
|
|
23948
23989
|
import { readdirSync as readdirSync6, statSync as statSync9, readFileSync as readFileSync12, openSync as openSync11, readSync as readSync5, closeSync as closeSync10 } from "node:fs";
|
|
23949
23990
|
function defaultCodexHome() {
|
|
23950
|
-
return process.env.CODEX_HOME && process.env.CODEX_HOME.trim() ? process.env.CODEX_HOME :
|
|
23991
|
+
return process.env.CODEX_HOME && process.env.CODEX_HOME.trim() ? process.env.CODEX_HOME : join18(homedir8(), ".codex");
|
|
23951
23992
|
}
|
|
23952
23993
|
function sessionsDir(codexHome) {
|
|
23953
|
-
return
|
|
23994
|
+
return join18(codexHome, "sessions");
|
|
23954
23995
|
}
|
|
23955
23996
|
function codexSandbox(mode) {
|
|
23956
23997
|
switch (mode) {
|
|
@@ -24331,17 +24372,17 @@ function collectRollouts(dir, out, budget) {
|
|
|
24331
24372
|
const files = entries.filter((e) => e.isFile() && e.name.startsWith("rollout-") && e.name.endsWith(".jsonl")).sort(descByName);
|
|
24332
24373
|
for (const d of dirs) {
|
|
24333
24374
|
if (budget.n <= 0) return;
|
|
24334
|
-
collectRollouts(
|
|
24375
|
+
collectRollouts(join18(dir, d.name), out, budget);
|
|
24335
24376
|
}
|
|
24336
24377
|
for (const f of files) {
|
|
24337
24378
|
if (budget.n <= 0) return;
|
|
24338
24379
|
let mtimeMs;
|
|
24339
24380
|
try {
|
|
24340
|
-
mtimeMs = statSync9(
|
|
24381
|
+
mtimeMs = statSync9(join18(dir, f.name)).mtimeMs;
|
|
24341
24382
|
} catch {
|
|
24342
24383
|
continue;
|
|
24343
24384
|
}
|
|
24344
|
-
out.push({ path:
|
|
24385
|
+
out.push({ path: join18(dir, f.name), mtimeMs });
|
|
24345
24386
|
budget.n--;
|
|
24346
24387
|
}
|
|
24347
24388
|
}
|
|
@@ -24385,7 +24426,7 @@ function readCodexThreadNames(codexHome = defaultCodexHome()) {
|
|
|
24385
24426
|
const out = /* @__PURE__ */ new Map();
|
|
24386
24427
|
let raw2;
|
|
24387
24428
|
try {
|
|
24388
|
-
const path =
|
|
24429
|
+
const path = join18(codexHome, "session_index.jsonl");
|
|
24389
24430
|
if (statSync9(path).size > SESSION_INDEX_MAX_BYTES) return out;
|
|
24390
24431
|
raw2 = readFileSync12(path, "utf8");
|
|
24391
24432
|
} catch {
|
|
@@ -28423,16 +28464,16 @@ var init_wrapper = __esm({
|
|
|
28423
28464
|
|
|
28424
28465
|
// packages/server/src/worker-plugin-dir.ts
|
|
28425
28466
|
import { existsSync as existsSync6 } from "node:fs";
|
|
28426
|
-
import { dirname as dirname9, join as
|
|
28467
|
+
import { dirname as dirname9, join as join19 } from "node:path";
|
|
28427
28468
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
28428
28469
|
function resolveWorkerPluginDir(moduleUrl = import.meta.url, env = process.env) {
|
|
28429
28470
|
const override = env.FRIZZ_WORKER_PLUGIN_DIR;
|
|
28430
|
-
if (override && existsSync6(
|
|
28471
|
+
if (override && existsSync6(join19(override, ".claude-plugin", "plugin.json")))
|
|
28431
28472
|
return override;
|
|
28432
28473
|
let current = dirname9(fileURLToPath2(moduleUrl));
|
|
28433
28474
|
for (; ; ) {
|
|
28434
|
-
const candidate =
|
|
28435
|
-
if (existsSync6(
|
|
28475
|
+
const candidate = join19(current, "cc-worker");
|
|
28476
|
+
if (existsSync6(join19(candidate, ".claude-plugin", "plugin.json"))) return candidate;
|
|
28436
28477
|
const parent = dirname9(current);
|
|
28437
28478
|
if (parent === current) return void 0;
|
|
28438
28479
|
current = parent;
|
|
@@ -28446,7 +28487,7 @@ var init_worker_plugin_dir = __esm({
|
|
|
28446
28487
|
|
|
28447
28488
|
// packages/server/src/backend/types.ts
|
|
28448
28489
|
import { existsSync as existsSync7 } from "node:fs";
|
|
28449
|
-
import { join as
|
|
28490
|
+
import { join as join20 } from "node:path";
|
|
28450
28491
|
function frizzMcpEnv(mcp) {
|
|
28451
28492
|
return {
|
|
28452
28493
|
FRIZZ_STATE_DIR: mcp.stateDir,
|
|
@@ -28470,7 +28511,7 @@ function chromeDevtoolsMcpMount() {
|
|
|
28470
28511
|
function resolveBrowserMcpScript(moduleUrl = import.meta.url, env = process.env) {
|
|
28471
28512
|
const pluginDir = resolveWorkerPluginDir(moduleUrl, env);
|
|
28472
28513
|
if (!pluginDir) return void 0;
|
|
28473
|
-
const scriptPath =
|
|
28514
|
+
const scriptPath = join20(pluginDir, "bin", CHROME_DEVTOOLS_MCP.script);
|
|
28474
28515
|
return existsSync7(scriptPath) ? scriptPath : void 0;
|
|
28475
28516
|
}
|
|
28476
28517
|
function workerCap(name, lifted, env) {
|
|
@@ -28569,14 +28610,14 @@ import { connect } from "node:net";
|
|
|
28569
28610
|
import { Agent as HttpAgent } from "node:http";
|
|
28570
28611
|
import { createHash as createHash7, randomUUID as randomUUID9 } from "node:crypto";
|
|
28571
28612
|
import { existsSync as existsSync8, mkdirSync as mkdirSync11, readFileSync as readFileSync13, unlinkSync as unlinkSync2, writeFileSync as writeFileSync9 } from "node:fs";
|
|
28572
|
-
import { join as
|
|
28613
|
+
import { join as join21 } from "node:path";
|
|
28573
28614
|
import { PassThrough, Writable } from "node:stream";
|
|
28574
28615
|
import { StringDecoder } from "node:string_decoder";
|
|
28575
28616
|
function nativeDir(stateDir) {
|
|
28576
|
-
return
|
|
28617
|
+
return join21(stateDir, "codex-app-server-native");
|
|
28577
28618
|
}
|
|
28578
28619
|
function nativeRecordPath(stateDir, projectId) {
|
|
28579
|
-
return
|
|
28620
|
+
return join21(nativeDir(stateDir), `${projectId}.json`);
|
|
28580
28621
|
}
|
|
28581
28622
|
function nativeListenSocketPath(stateDir, projectId) {
|
|
28582
28623
|
const key = createHash7("sha256").update(stateDir).update("\0").update(projectId).digest("hex").slice(0, 16);
|
|
@@ -28841,14 +28882,14 @@ import { spawn as spawn3, spawnSync } from "node:child_process";
|
|
|
28841
28882
|
import { createConnection } from "node:net";
|
|
28842
28883
|
import { createHash as createHash8, randomUUID as randomUUID10 } from "node:crypto";
|
|
28843
28884
|
import { existsSync as existsSync9, mkdirSync as mkdirSync12, readFileSync as readFileSync14, unlinkSync as unlinkSync3 } from "node:fs";
|
|
28844
|
-
import { join as
|
|
28885
|
+
import { join as join22 } from "node:path";
|
|
28845
28886
|
import { PassThrough as PassThrough2, Writable as Writable2 } from "node:stream";
|
|
28846
28887
|
import { StringDecoder as StringDecoder2 } from "node:string_decoder";
|
|
28847
28888
|
function daemonDir(stateDir) {
|
|
28848
|
-
return
|
|
28889
|
+
return join22(stateDir, "codex-app-server");
|
|
28849
28890
|
}
|
|
28850
28891
|
function recordPath(stateDir, projectId) {
|
|
28851
|
-
return
|
|
28892
|
+
return join22(daemonDir(stateDir), `${projectId}.json`);
|
|
28852
28893
|
}
|
|
28853
28894
|
function codexAppServerSocketPath(stateDir, projectId) {
|
|
28854
28895
|
const key = createHash8("sha256").update(stateDir).update("\0").update(projectId).digest("hex").slice(0, 16);
|
|
@@ -32076,11 +32117,11 @@ var init_codex_app_server = __esm({
|
|
|
32076
32117
|
});
|
|
32077
32118
|
|
|
32078
32119
|
// packages/server/src/backend/codex-quota.ts
|
|
32079
|
-
import { join as
|
|
32120
|
+
import { join as join23 } from "node:path";
|
|
32080
32121
|
import { readdirSync as readdirSync7, statSync as statSync10, openSync as openSync12, readSync as readSync6, fstatSync, closeSync as closeSync11 } from "node:fs";
|
|
32081
32122
|
import { spawn as spawn4 } from "node:child_process";
|
|
32082
32123
|
function sessionsDir2(codexHome) {
|
|
32083
|
-
return
|
|
32124
|
+
return join23(codexHome, "sessions");
|
|
32084
32125
|
}
|
|
32085
32126
|
function newestRollouts(dir, out, budget) {
|
|
32086
32127
|
if (budget.n <= 0) return;
|
|
@@ -32094,11 +32135,11 @@ function newestRollouts(dir, out, budget) {
|
|
|
32094
32135
|
const files = entries.filter((e) => e.isFile() && e.name.startsWith("rollout-") && e.name.endsWith(".jsonl")).map((e) => e.name).sort(descByName2);
|
|
32095
32136
|
for (const d of dirs) {
|
|
32096
32137
|
if (budget.n <= 0) return;
|
|
32097
|
-
newestRollouts(
|
|
32138
|
+
newestRollouts(join23(dir, d), out, budget);
|
|
32098
32139
|
}
|
|
32099
32140
|
for (const f of files) {
|
|
32100
32141
|
if (budget.n <= 0) return;
|
|
32101
|
-
out.push(
|
|
32142
|
+
out.push(join23(dir, f));
|
|
32102
32143
|
budget.n--;
|
|
32103
32144
|
}
|
|
32104
32145
|
}
|
|
@@ -32298,7 +32339,7 @@ var init_codex_quota = __esm({
|
|
|
32298
32339
|
});
|
|
32299
32340
|
|
|
32300
32341
|
// packages/server/src/backend/claude-quota.ts
|
|
32301
|
-
import { join as
|
|
32342
|
+
import { join as join24 } from "node:path";
|
|
32302
32343
|
import { homedir as homedir9, platform } from "node:os";
|
|
32303
32344
|
import { createHash as createHash10 } from "node:crypto";
|
|
32304
32345
|
import { mkdir, readFile, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
@@ -32306,7 +32347,7 @@ import { execFile as execFile2 } from "node:child_process";
|
|
|
32306
32347
|
import { promisify as promisify2 } from "node:util";
|
|
32307
32348
|
function claudeConfigDir() {
|
|
32308
32349
|
const override = process.env.CLAUDE_CONFIG_DIR;
|
|
32309
|
-
return override && override.trim() ? override :
|
|
32350
|
+
return override && override.trim() ? override : join24(homedir9(), ".claude");
|
|
32310
32351
|
}
|
|
32311
32352
|
function tokenFromCredentialsJson(raw2) {
|
|
32312
32353
|
let doc;
|
|
@@ -32335,7 +32376,7 @@ async function readKeychainToken() {
|
|
|
32335
32376
|
}
|
|
32336
32377
|
async function readAccessToken(configDir) {
|
|
32337
32378
|
try {
|
|
32338
|
-
const fromFile = tokenFromCredentialsJson(await readFile(
|
|
32379
|
+
const fromFile = tokenFromCredentialsJson(await readFile(join24(configDir, ".credentials.json"), "utf8"));
|
|
32339
32380
|
if (fromFile) return fromFile;
|
|
32340
32381
|
} catch {
|
|
32341
32382
|
}
|
|
@@ -32404,8 +32445,8 @@ function parseClaudeUsage(body, planType) {
|
|
|
32404
32445
|
function cachePaths(cacheDir, configDir) {
|
|
32405
32446
|
const profile = createHash10("sha256").update(configDir).digest("hex").slice(0, 12);
|
|
32406
32447
|
return {
|
|
32407
|
-
data:
|
|
32408
|
-
lock:
|
|
32448
|
+
data: join24(cacheDir, `claude-${profile}.json`),
|
|
32449
|
+
lock: join24(cacheDir, `claude-${profile}.lock`)
|
|
32409
32450
|
};
|
|
32410
32451
|
}
|
|
32411
32452
|
async function readShared(path) {
|
|
@@ -32453,7 +32494,11 @@ async function acquireLock(path) {
|
|
|
32453
32494
|
}
|
|
32454
32495
|
async function runClaudeUsage(claudeBin) {
|
|
32455
32496
|
const { stdout } = await execFileAsync(
|
|
32456
|
-
|
|
32497
|
+
// Never a bare name: on Windows `execFile("claude")` is ENOENT and `execFile("claude.cmd")` is
|
|
32498
|
+
// EINVAL (node refuses .cmd/.bat without a shell since CVE-2024-27980), so this reader could
|
|
32499
|
+
// never reach the CLI there and every quota refresh threw. See auth-status.ts for the measurement.
|
|
32500
|
+
// A resolver throw is a refresh failure like any other — the callers' stale-serving catch owns it.
|
|
32501
|
+
resolveClaudeExecutableAbsolute(claudeBin),
|
|
32457
32502
|
["-p", "/usage", "--safe-mode", "--output-format", "json", "--no-session-persistence", "--tools", ""],
|
|
32458
32503
|
{ encoding: "utf8", timeout: CLI_TIMEOUT_MS, maxBuffer: 2 * 1024 * 1024 }
|
|
32459
32504
|
);
|
|
@@ -32597,7 +32642,7 @@ function refreshSharedInBackground(paths, claudeBin, deps, now) {
|
|
|
32597
32642
|
async function refreshClaudeQuotaInBackground(claudeBin = "claude", deps = {}) {
|
|
32598
32643
|
const now = (deps.now ?? Date.now)();
|
|
32599
32644
|
const configDir = claudeConfigDir();
|
|
32600
|
-
const cacheDir = deps.cacheDir ??
|
|
32645
|
+
const cacheDir = deps.cacheDir ?? join24(frizzRoots().cache, "quota-cache");
|
|
32601
32646
|
try {
|
|
32602
32647
|
await mkdir(cacheDir, { recursive: true, mode: 448 });
|
|
32603
32648
|
} catch {
|
|
@@ -32608,7 +32653,7 @@ async function refreshClaudeQuotaInBackground(claudeBin = "claude", deps = {}) {
|
|
|
32608
32653
|
async function readClaudeQuota(claudeBin = "claude", deps = {}, options = {}) {
|
|
32609
32654
|
const now = (deps.now ?? Date.now)();
|
|
32610
32655
|
const configDir = claudeConfigDir();
|
|
32611
|
-
const cacheDir = deps.cacheDir ??
|
|
32656
|
+
const cacheDir = deps.cacheDir ?? join24(frizzRoots().cache, "quota-cache");
|
|
32612
32657
|
const paths = cachePaths(cacheDir, configDir);
|
|
32613
32658
|
try {
|
|
32614
32659
|
await mkdir(cacheDir, { recursive: true, mode: 448 });
|
|
@@ -32660,6 +32705,7 @@ var init_claude_quota = __esm({
|
|
|
32660
32705
|
"packages/server/src/backend/claude-quota.ts"() {
|
|
32661
32706
|
"use strict";
|
|
32662
32707
|
init_frizz_paths();
|
|
32708
|
+
init_claude_broker_host();
|
|
32663
32709
|
execFileAsync = promisify2(execFile2);
|
|
32664
32710
|
USAGE_URL = "https://api.anthropic.com/api/oauth/usage";
|
|
32665
32711
|
OAUTH_BETA = "oauth-2025-04-20";
|
|
@@ -32767,7 +32813,7 @@ var init_quota = __esm({
|
|
|
32767
32813
|
// packages/server/src/frizz.ts
|
|
32768
32814
|
import { execFile as execFile3 } from "node:child_process";
|
|
32769
32815
|
import { lstatSync as lstatSync2, realpathSync as realpathSync6 } from "node:fs";
|
|
32770
|
-
import { basename as basename5, dirname as dirname10, join as
|
|
32816
|
+
import { basename as basename5, dirname as dirname10, join as join25, resolve as resolve4 } from "node:path";
|
|
32771
32817
|
import { promisify as promisify3 } from "node:util";
|
|
32772
32818
|
function frizzScriptsDir() {
|
|
32773
32819
|
if (process.env.FRIZZ_SCRIPTS_DIR) return process.env.FRIZZ_SCRIPTS_DIR;
|
|
@@ -32776,7 +32822,7 @@ function frizzScriptsDir() {
|
|
|
32776
32822
|
function directFrizzRoot(projectDir) {
|
|
32777
32823
|
try {
|
|
32778
32824
|
const projectRoot = realpathSync6(projectDir);
|
|
32779
|
-
const path =
|
|
32825
|
+
const path = join25(projectRoot, ".frizz");
|
|
32780
32826
|
const stat2 = lstatSync2(path);
|
|
32781
32827
|
if (!stat2.isDirectory() || stat2.isSymbolicLink()) return null;
|
|
32782
32828
|
const real = realpathSync6(path);
|
|
@@ -32790,7 +32836,7 @@ function frizzDirExists(projectDir) {
|
|
|
32790
32836
|
}
|
|
32791
32837
|
async function readBoard(projectDir, scriptsDir = frizzScriptsDir()) {
|
|
32792
32838
|
if (!directFrizzRoot(projectDir)) throw new Error("unsafe or missing .frizz directory");
|
|
32793
|
-
const { stdout } = await execFileP("node", [
|
|
32839
|
+
const { stdout } = await execFileP("node", [join25(scriptsDir, "index.mjs"), "--json"], {
|
|
32794
32840
|
cwd: projectDir,
|
|
32795
32841
|
env: { ...process.env, CLAUDE_PROJECT_DIR: projectDir },
|
|
32796
32842
|
maxBuffer: 32 * 1024 * 1024
|
|
@@ -32815,7 +32861,7 @@ async function readBoard(projectDir, scriptsDir = frizzScriptsDir()) {
|
|
|
32815
32861
|
};
|
|
32816
32862
|
}
|
|
32817
32863
|
async function runThreadUpdate(projectDir, slug, args, scriptsDir = frizzScriptsDir()) {
|
|
32818
|
-
await execFileP("node", [
|
|
32864
|
+
await execFileP("node", [join25(scriptsDir, "thread-update.mjs"), slug, ...args], {
|
|
32819
32865
|
cwd: projectDir,
|
|
32820
32866
|
env: { ...process.env, CLAUDE_PROJECT_DIR: projectDir }
|
|
32821
32867
|
});
|
|
@@ -34700,19 +34746,19 @@ var init_claude_agent_broker_bridge = __esm({
|
|
|
34700
34746
|
});
|
|
34701
34747
|
|
|
34702
34748
|
// packages/server/src/backend/auth-status.ts
|
|
34703
|
-
import { join as
|
|
34749
|
+
import { join as join26 } from "node:path";
|
|
34704
34750
|
import { homedir as homedir11, platform as platform2 } from "node:os";
|
|
34705
34751
|
import { readFileSync as readFileSync15, statSync as statSync11 } from "node:fs";
|
|
34706
34752
|
import { execFile as execFile4 } from "node:child_process";
|
|
34707
34753
|
import { promisify as promisify4 } from "node:util";
|
|
34708
34754
|
function claudeConfigDir2() {
|
|
34709
34755
|
const override = process.env.CLAUDE_CONFIG_DIR;
|
|
34710
|
-
return override && override.trim() ? override :
|
|
34756
|
+
return override && override.trim() ? override : join26(homedir11(), ".claude");
|
|
34711
34757
|
}
|
|
34712
34758
|
function claudeFileState(configDir) {
|
|
34713
34759
|
let raw2;
|
|
34714
34760
|
try {
|
|
34715
|
-
raw2 = readFileSync15(
|
|
34761
|
+
raw2 = readFileSync15(join26(configDir, ".credentials.json"), "utf8");
|
|
34716
34762
|
} catch (err) {
|
|
34717
34763
|
return err.code === "ENOENT" ? "absent" : "error";
|
|
34718
34764
|
}
|
|
@@ -34745,7 +34791,7 @@ function readCodexAuthState(codexHome = defaultCodexHome()) {
|
|
|
34745
34791
|
if (process.env.OPENAI_API_KEY || process.env.CODEX_API_KEY || process.env.CODEX_ACCESS_TOKEN) return "authed";
|
|
34746
34792
|
let raw2;
|
|
34747
34793
|
try {
|
|
34748
|
-
raw2 = readFileSync15(
|
|
34794
|
+
raw2 = readFileSync15(join26(codexHome, "auth.json"), "utf8");
|
|
34749
34795
|
} catch (err) {
|
|
34750
34796
|
return err.code === "ENOENT" ? "signed-out" : "unknown";
|
|
34751
34797
|
}
|
|
@@ -34782,8 +34828,8 @@ function parseClaudeAuthStatusJson(stdout) {
|
|
|
34782
34828
|
}
|
|
34783
34829
|
}
|
|
34784
34830
|
async function readClaudeAuthStatusCli(opts) {
|
|
34785
|
-
const bin = opts?.claudeBin ?? "claude";
|
|
34786
34831
|
try {
|
|
34832
|
+
const bin = resolveClaudeExecutableAbsolute(opts?.claudeBin);
|
|
34787
34833
|
const { stdout } = await execFileAsync2(bin, ["auth", "status", "--json"], {
|
|
34788
34834
|
encoding: "utf8",
|
|
34789
34835
|
timeout: opts?.timeoutMs ?? 5e3,
|
|
@@ -34810,7 +34856,7 @@ function asEmail(value) {
|
|
|
34810
34856
|
}
|
|
34811
34857
|
function claudeAccountFile() {
|
|
34812
34858
|
const override = process.env.CLAUDE_CONFIG_DIR;
|
|
34813
|
-
return override && override.trim() ?
|
|
34859
|
+
return override && override.trim() ? join26(override, ".claude.json") : join26(homedir11(), ".claude.json");
|
|
34814
34860
|
}
|
|
34815
34861
|
function readClaudeAccountEmail(path = claudeAccountFile()) {
|
|
34816
34862
|
let stat2;
|
|
@@ -34834,7 +34880,7 @@ function readClaudeAccountEmail(path = claudeAccountFile()) {
|
|
|
34834
34880
|
function readCodexAccountEmail(codexHome = defaultCodexHome()) {
|
|
34835
34881
|
let doc;
|
|
34836
34882
|
try {
|
|
34837
|
-
doc = JSON.parse(readFileSync15(
|
|
34883
|
+
doc = JSON.parse(readFileSync15(join26(codexHome, "auth.json"), "utf8"));
|
|
34838
34884
|
} catch {
|
|
34839
34885
|
return void 0;
|
|
34840
34886
|
}
|
|
@@ -34888,6 +34934,7 @@ var init_auth_status = __esm({
|
|
|
34888
34934
|
"use strict";
|
|
34889
34935
|
init_claude_quota();
|
|
34890
34936
|
init_codex();
|
|
34937
|
+
init_claude_broker_host();
|
|
34891
34938
|
execFileAsync2 = promisify4(execFile4);
|
|
34892
34939
|
ProviderAuthRequiredError = class extends Error {
|
|
34893
34940
|
backend;
|
|
@@ -34902,7 +34949,7 @@ var init_auth_status = __esm({
|
|
|
34902
34949
|
|
|
34903
34950
|
// packages/server/src/dispatch.ts
|
|
34904
34951
|
import { closeSync as closeSync12, constants, existsSync as existsSync10, fstatSync as fstatSync2, lstatSync as lstatSync3, openSync as openSync13, readFileSync as readFileSync16, realpathSync as realpathSync7, statSync as statSync12, writeFileSync as writeFileSync10, mkdirSync as mkdirSync13, rmSync as rmSync8 } from "node:fs";
|
|
34905
|
-
import { basename as basename6, join as
|
|
34952
|
+
import { basename as basename6, join as join27, dirname as dirname11 } from "node:path";
|
|
34906
34953
|
import { createHash as createHash11, randomUUID as randomUUID13 } from "node:crypto";
|
|
34907
34954
|
function fallbackTitle(prompt) {
|
|
34908
34955
|
const firstLine2 = prompt.trim().split("\n", 1)[0].trim();
|
|
@@ -34921,7 +34968,7 @@ function fallbackTitle(prompt) {
|
|
|
34921
34968
|
}
|
|
34922
34969
|
function resolveSlug(frizzDir, base, taken) {
|
|
34923
34970
|
base = ThreadSlug.parse(base);
|
|
34924
|
-
const isTaken = (slug) => existsSync10(
|
|
34971
|
+
const isTaken = (slug) => existsSync10(join27(frizzDir, `${slug}.md`)) || (taken?.(slug) ?? false);
|
|
34925
34972
|
if (!isTaken(base)) return base;
|
|
34926
34973
|
for (let n = 2; ; n++) {
|
|
34927
34974
|
const suffix = `-${n}`;
|
|
@@ -34938,12 +34985,12 @@ function resolveLegacyThreadFile(projectDir, value) {
|
|
|
34938
34985
|
if (!parsed.success) return null;
|
|
34939
34986
|
try {
|
|
34940
34987
|
const projectRoot = realpathSync7(projectDir);
|
|
34941
|
-
const frizzPath =
|
|
34988
|
+
const frizzPath = join27(projectRoot, ".frizz");
|
|
34942
34989
|
const frizzStat = lstatSync3(frizzPath);
|
|
34943
34990
|
if (!frizzStat.isDirectory() || frizzStat.isSymbolicLink()) return null;
|
|
34944
34991
|
const realFrizz = realpathSync7(frizzPath);
|
|
34945
34992
|
if (dirname11(realFrizz) !== projectRoot || basename6(realFrizz) !== ".frizz") return null;
|
|
34946
|
-
const path =
|
|
34993
|
+
const path = join27(realFrizz, `${parsed.data}.md`);
|
|
34947
34994
|
const before = lstatSync3(path);
|
|
34948
34995
|
if (!before.isFile() || before.isSymbolicLink()) return null;
|
|
34949
34996
|
const realPath = realpathSync7(path);
|
|
@@ -34987,7 +35034,7 @@ function boardAuthorizesAdoption(board, slug) {
|
|
|
34987
35034
|
return !board.errorItems.some((item) => item.file === `${slug}.md`);
|
|
34988
35035
|
}
|
|
34989
35036
|
function ensureSafeDirectDirectory(parent, name) {
|
|
34990
|
-
const path =
|
|
35037
|
+
const path = join27(parent, name);
|
|
34991
35038
|
try {
|
|
34992
35039
|
mkdirSync13(path);
|
|
34993
35040
|
} catch (error) {
|
|
@@ -35017,8 +35064,8 @@ function loadWorkerPrompt(kind = "claude") {
|
|
|
35017
35064
|
function monitorScriptsDir() {
|
|
35018
35065
|
const plugin = workerPluginDir();
|
|
35019
35066
|
if (!plugin) return void 0;
|
|
35020
|
-
const dir =
|
|
35021
|
-
return existsSync10(
|
|
35067
|
+
const dir = join27(plugin, "skills", "gh", "scripts");
|
|
35068
|
+
return existsSync10(join27(dir, "ci-watch.mjs")) ? dir : void 0;
|
|
35022
35069
|
}
|
|
35023
35070
|
function codexScratchpadHookConfig(hookScript, sessionId) {
|
|
35024
35071
|
if (!hookScript || !sessionId) return {};
|
|
@@ -35030,7 +35077,7 @@ function codexScratchpadHookConfig(hookScript, sessionId) {
|
|
|
35030
35077
|
}
|
|
35031
35078
|
]
|
|
35032
35079
|
});
|
|
35033
|
-
const bashBackgroundHook =
|
|
35080
|
+
const bashBackgroundHook = join27(dirname11(hookScript), "bash-background.mjs");
|
|
35034
35081
|
return {
|
|
35035
35082
|
bypass_hook_trust: true,
|
|
35036
35083
|
hooks: {
|
|
@@ -35056,7 +35103,7 @@ function codexScratchpadHookConfig(hookScript, sessionId) {
|
|
|
35056
35103
|
}
|
|
35057
35104
|
function scratchpadHookScript() {
|
|
35058
35105
|
const plugin = workerPluginDir();
|
|
35059
|
-
return plugin ?
|
|
35106
|
+
return plugin ? join27(plugin, "hooks", "scratchpad.mjs") : void 0;
|
|
35060
35107
|
}
|
|
35061
35108
|
function composePrompt(sessionId, prompt, kind = "claude") {
|
|
35062
35109
|
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.";
|
|
@@ -35072,7 +35119,7 @@ function scratchpadOrientation(sessionId, kind = "claude") {
|
|
|
35072
35119
|
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.`;
|
|
35073
35120
|
}
|
|
35074
35121
|
function frizzConfigBlock(projectDir) {
|
|
35075
|
-
const path =
|
|
35122
|
+
const path = join27(projectDir, "FRIZZ.md");
|
|
35076
35123
|
let body;
|
|
35077
35124
|
try {
|
|
35078
35125
|
const st = statSync12(path);
|
|
@@ -35112,7 +35159,7 @@ function resolveFrizzMcp(target, moduleUrl = import.meta.url, env = process.env,
|
|
|
35112
35159
|
const { stateDir, serverLock, projectId } = typeof target === "string" ? { stateDir: target } : target;
|
|
35113
35160
|
const pluginDir = resolveWorkerPluginDir(moduleUrl, env);
|
|
35114
35161
|
if (!pluginDir) return void 0;
|
|
35115
|
-
const scriptPath =
|
|
35162
|
+
const scriptPath = join27(pluginDir, "bin", FRIZZ_MCP.script);
|
|
35116
35163
|
if (!existsSync10(scriptPath)) return void 0;
|
|
35117
35164
|
return {
|
|
35118
35165
|
scriptPath,
|
|
@@ -35195,7 +35242,7 @@ function buildClaudeResumeCommand(opts) {
|
|
|
35195
35242
|
}
|
|
35196
35243
|
function createDispatcher(deps) {
|
|
35197
35244
|
const readBoardSource = deps.readBoard ?? readBoard;
|
|
35198
|
-
const frizzDir =
|
|
35245
|
+
const frizzDir = join27(deps.project.dir, ".frizz");
|
|
35199
35246
|
const adoptionRuntime = deps.adoptionRuntime ?? productionRuntime;
|
|
35200
35247
|
function cleanupPrewrites(built) {
|
|
35201
35248
|
for (const path of new Set(built.prewrite.map((file) => file.path))) {
|
|
@@ -35208,7 +35255,7 @@ function createDispatcher(deps) {
|
|
|
35208
35255
|
function cleanupDispatchFiles(scratchRel, built, sessionId) {
|
|
35209
35256
|
cleanupPrewrites(built);
|
|
35210
35257
|
try {
|
|
35211
|
-
rmSync8(
|
|
35258
|
+
rmSync8(join27(deps.project.dir, scratchRel), { force: true, recursive: true });
|
|
35212
35259
|
} catch {
|
|
35213
35260
|
}
|
|
35214
35261
|
cleanupAdoptionSessionFiles(deps.project.dir, sessionId);
|
|
@@ -35641,7 +35688,7 @@ import {
|
|
|
35641
35688
|
watch as fsWatch
|
|
35642
35689
|
} from "node:fs";
|
|
35643
35690
|
import { homedir as homedir12 } from "node:os";
|
|
35644
|
-
import { join as
|
|
35691
|
+
import { join as join28 } from "node:path";
|
|
35645
35692
|
import watcher from "@parcel/watcher";
|
|
35646
35693
|
function appServerTurnStalled(liveness, lastActivityAt, nowMs) {
|
|
35647
35694
|
if (!liveness) return false;
|
|
@@ -36326,7 +36373,7 @@ function createBoard(project, storage, bus, tailer, bootId, deps = {}) {
|
|
|
36326
36373
|
if (parcelSub || stopped) return Promise.resolve();
|
|
36327
36374
|
if (watchSetup) return watchSetup;
|
|
36328
36375
|
const setup = (async () => {
|
|
36329
|
-
const next = await subscribe(
|
|
36376
|
+
const next = await subscribe(join28(project.dir, ".frizz"), () => scheduleRebuild());
|
|
36330
36377
|
if (stopped) {
|
|
36331
36378
|
await next.unsubscribe();
|
|
36332
36379
|
return;
|
|
@@ -38260,7 +38307,7 @@ var init_resume = __esm({
|
|
|
38260
38307
|
});
|
|
38261
38308
|
|
|
38262
38309
|
// packages/server/src/backend/claude.ts
|
|
38263
|
-
import { join as
|
|
38310
|
+
import { join as join29 } from "node:path";
|
|
38264
38311
|
function toolResultText2(content) {
|
|
38265
38312
|
if (typeof content === "string") return content;
|
|
38266
38313
|
if (!Array.isArray(content)) return "";
|
|
@@ -38349,7 +38396,7 @@ function createClaudeBackend(opts) {
|
|
|
38349
38396
|
return { argv, env: claudeWorkerEnvironment(), prewrite: [] };
|
|
38350
38397
|
},
|
|
38351
38398
|
transcriptPath(sessionId) {
|
|
38352
|
-
return
|
|
38399
|
+
return join29(opts.logDir, `${sessionId}.jsonl`);
|
|
38353
38400
|
},
|
|
38354
38401
|
parseLine(line) {
|
|
38355
38402
|
return parseClaudeLine(line);
|
|
@@ -38519,12 +38566,12 @@ var init_login_utility = __esm({
|
|
|
38519
38566
|
|
|
38520
38567
|
// packages/server/src/backend/codex-app-server-diagnostics.ts
|
|
38521
38568
|
import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync14, renameSync as renameSync8, statSync as statSync13 } from "node:fs";
|
|
38522
|
-
import { join as
|
|
38569
|
+
import { join as join30 } from "node:path";
|
|
38523
38570
|
function codexDiagnosticLogPath(stateDir, projectId) {
|
|
38524
|
-
return
|
|
38571
|
+
return join30(stateDir, "codex-app-server", `${projectId}.diagnostics.log`);
|
|
38525
38572
|
}
|
|
38526
38573
|
function createCodexDiagnosticSink(stateDir, projectId, now = () => /* @__PURE__ */ new Date()) {
|
|
38527
|
-
const dir =
|
|
38574
|
+
const dir = join30(stateDir, "codex-app-server");
|
|
38528
38575
|
const path = codexDiagnosticLogPath(stateDir, projectId);
|
|
38529
38576
|
let ensured = false;
|
|
38530
38577
|
return (event) => {
|
|
@@ -38556,7 +38603,7 @@ var init_codex_app_server_diagnostics = __esm({
|
|
|
38556
38603
|
import { execFile as execFile7 } from "node:child_process";
|
|
38557
38604
|
import { readdirSync as readdirSync8, unlinkSync as unlinkSync4 } from "node:fs";
|
|
38558
38605
|
import { connect as connectSocket } from "node:net";
|
|
38559
|
-
import { join as
|
|
38606
|
+
import { join as join31 } from "node:path";
|
|
38560
38607
|
function parseLsofSocketNames(stdout) {
|
|
38561
38608
|
const referenced = /* @__PURE__ */ new Set();
|
|
38562
38609
|
for (const line of stdout.split("\n")) {
|
|
@@ -38573,7 +38620,7 @@ function sweepStaleSockets(options, deps = {}) {
|
|
|
38573
38620
|
const keep = new Set(options.keep ?? []);
|
|
38574
38621
|
let candidates;
|
|
38575
38622
|
try {
|
|
38576
|
-
candidates = (deps.readdir ?? readdirSync8)(options.dir).filter((name) => name.startsWith(options.prefix) && name.endsWith(".sock")).map((name) =>
|
|
38623
|
+
candidates = (deps.readdir ?? readdirSync8)(options.dir).filter((name) => name.startsWith(options.prefix) && name.endsWith(".sock")).map((name) => join31(options.dir, name)).filter((path) => !keep.has(path));
|
|
38577
38624
|
} catch {
|
|
38578
38625
|
return;
|
|
38579
38626
|
}
|
|
@@ -39037,7 +39084,7 @@ var init_thread_hibernation = __esm({
|
|
|
39037
39084
|
});
|
|
39038
39085
|
|
|
39039
39086
|
// packages/server/src/context.ts
|
|
39040
|
-
import { join as
|
|
39087
|
+
import { join as join32 } from "node:path";
|
|
39041
39088
|
import { randomUUID as randomUUID15 } from "node:crypto";
|
|
39042
39089
|
import { homedir as homedir13 } from "node:os";
|
|
39043
39090
|
function reconcileSessions(storage) {
|
|
@@ -39195,7 +39242,7 @@ async function createContext(opts = {}) {
|
|
|
39195
39242
|
function createContextUnchecked(opts, resources) {
|
|
39196
39243
|
const home = opts.home ?? homedir13();
|
|
39197
39244
|
const project = opts.project ?? resolveProject();
|
|
39198
|
-
const dbPath =
|
|
39245
|
+
const dbPath = join32(project.stateDir, "ui.db");
|
|
39199
39246
|
const storage = createStorage(dbPath);
|
|
39200
39247
|
resources.storage = storage;
|
|
39201
39248
|
const bus = new Bus();
|
|
@@ -42433,7 +42480,7 @@ var init_bash_background = __esm({
|
|
|
42433
42480
|
import { closeSync as closeSync13, existsSync as existsSync13, fstatSync as fstatSync3, mkdirSync as mkdirSync15, openSync as openSync14, readdirSync as readdirSync9, readFileSync as readFileSync20, readSync as readSync7, renameSync as renameSync9, statSync as statSync14, unlinkSync as unlinkSync5, writeFileSync as writeFileSync12 } from "node:fs";
|
|
42434
42481
|
import { createHash as createHash13 } from "node:crypto";
|
|
42435
42482
|
import { StringDecoder as StringDecoder4 } from "node:string_decoder";
|
|
42436
|
-
import { join as
|
|
42483
|
+
import { join as join33 } from "node:path";
|
|
42437
42484
|
import { homedir as homedir14 } from "node:os";
|
|
42438
42485
|
function formatTokens(n) {
|
|
42439
42486
|
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
@@ -42983,14 +43030,14 @@ function pruneScreenshotCache() {
|
|
|
42983
43030
|
if (entries.length <= SCREENSHOT_CACHE_MAX) return;
|
|
42984
43031
|
const byMtime = entries.map((n) => {
|
|
42985
43032
|
try {
|
|
42986
|
-
return { n, m: statSync14(
|
|
43033
|
+
return { n, m: statSync14(join33(SCREENSHOT_CACHE_DIR, n)).mtimeMs };
|
|
42987
43034
|
} catch {
|
|
42988
43035
|
return { n, m: 0 };
|
|
42989
43036
|
}
|
|
42990
43037
|
}).sort((a, b) => b.m - a.m);
|
|
42991
43038
|
for (const { n } of byMtime.slice(SCREENSHOT_CACHE_MAX)) {
|
|
42992
43039
|
try {
|
|
42993
|
-
unlinkSync5(
|
|
43040
|
+
unlinkSync5(join33(SCREENSHOT_CACHE_DIR, n));
|
|
42994
43041
|
} catch {
|
|
42995
43042
|
}
|
|
42996
43043
|
}
|
|
@@ -43020,14 +43067,14 @@ function persistBase64Image(mediaType, data, idKey) {
|
|
|
43020
43067
|
const ext = IMAGE_MEDIA_EXT[typeof mediaType === "string" ? mediaType.toLowerCase() : ""];
|
|
43021
43068
|
if (!ext || !data) return void 0;
|
|
43022
43069
|
const name = createHash13("sha256").update(idKey).digest("hex").slice(0, 32);
|
|
43023
|
-
const path =
|
|
43070
|
+
const path = join33(SCREENSHOT_CACHE_DIR, `${name}.${ext}`);
|
|
43024
43071
|
try {
|
|
43025
43072
|
if (existsSync13(path)) return path;
|
|
43026
43073
|
if (data.length > SCREENSHOT_MAX_BASE64) return void 0;
|
|
43027
43074
|
const buf = Buffer.from(data, "base64");
|
|
43028
43075
|
if (buf.length === 0 || !looksLikeImage(buf, ext)) return void 0;
|
|
43029
43076
|
mkdirSync15(SCREENSHOT_CACHE_DIR, { recursive: true });
|
|
43030
|
-
const tmp =
|
|
43077
|
+
const tmp = join33(SCREENSHOT_CACHE_DIR, `.${name}.${process.pid}.${screenshotTmpSeq++}.tmp`);
|
|
43031
43078
|
writeFileSync12(tmp, buf);
|
|
43032
43079
|
renameSync9(tmp, path);
|
|
43033
43080
|
pruneScreenshotCache();
|
|
@@ -43042,14 +43089,14 @@ function persistSentFile(srcPath, idKey) {
|
|
|
43042
43089
|
const outExt = ext === "jpeg" ? "jpg" : ext;
|
|
43043
43090
|
try {
|
|
43044
43091
|
const name = createHash13("sha256").update(idKey).digest("hex").slice(0, 32);
|
|
43045
|
-
const dest =
|
|
43092
|
+
const dest = join33(SCREENSHOT_CACHE_DIR, `${name}.${outExt}`);
|
|
43046
43093
|
if (existsSync13(dest)) return dest;
|
|
43047
43094
|
const size = statSync14(srcPath).size;
|
|
43048
43095
|
if (size === 0 || size > SENT_IMAGE_MAX_BYTES) return void 0;
|
|
43049
43096
|
const buf = readFileSync20(srcPath);
|
|
43050
43097
|
if (!looksLikeImage(buf, outExt)) return void 0;
|
|
43051
43098
|
mkdirSync15(SCREENSHOT_CACHE_DIR, { recursive: true });
|
|
43052
|
-
const tmp =
|
|
43099
|
+
const tmp = join33(SCREENSHOT_CACHE_DIR, `.${name}.${process.pid}.${screenshotTmpSeq++}.tmp`);
|
|
43053
43100
|
writeFileSync12(tmp, buf);
|
|
43054
43101
|
renameSync9(tmp, dest);
|
|
43055
43102
|
pruneScreenshotCache();
|
|
@@ -43486,16 +43533,16 @@ function verifyIncrementalParse(path, identityPrefix, incremental) {
|
|
|
43486
43533
|
}
|
|
43487
43534
|
}
|
|
43488
43535
|
function logDirOf(project) {
|
|
43489
|
-
return
|
|
43536
|
+
return join33(homedir14(), ".claude", "projects", project.cwdSlug);
|
|
43490
43537
|
}
|
|
43491
43538
|
function resolveTranscriptPath(project, sessionId) {
|
|
43492
|
-
const path =
|
|
43539
|
+
const path = join33(logDirOf(project), `${sessionId}.jsonl`);
|
|
43493
43540
|
try {
|
|
43494
43541
|
if (statSync14(path).size > 0) return path;
|
|
43495
43542
|
} catch {
|
|
43496
43543
|
}
|
|
43497
43544
|
const stranded = discoverTranscriptDir(logDirOf(project), sessionId);
|
|
43498
|
-
return stranded ?
|
|
43545
|
+
return stranded ? join33(stranded, `${sessionId}.jsonl`) : path;
|
|
43499
43546
|
}
|
|
43500
43547
|
function projectCodexTranscript(raw2, identityPrefix = "codex") {
|
|
43501
43548
|
const out = [];
|
|
@@ -44726,7 +44773,11 @@ function readThreadTranscript(project, storage, slug, backendFor) {
|
|
|
44726
44773
|
const found = discoverTranscriptId(logDirOf(project), row.session_id, { exclude });
|
|
44727
44774
|
return projectDeliveryLedger(found ? readTranscript(project, found) : msgs, ledger);
|
|
44728
44775
|
}
|
|
44729
|
-
if (FOREIGN_SESSION_ID_RE.test(slug))
|
|
44776
|
+
if (FOREIGN_SESSION_ID_RE.test(slug)) {
|
|
44777
|
+
const source = sourceForThread(project, storage, slug, backendFor);
|
|
44778
|
+
if (!source) return [];
|
|
44779
|
+
return source.backend === "codex" ? readCodexTranscriptFile(source.path, slug) : readTranscript(project, slug);
|
|
44780
|
+
}
|
|
44730
44781
|
return [];
|
|
44731
44782
|
}
|
|
44732
44783
|
function projectTranscriptAgentLifecycles(messages, lookup) {
|
|
@@ -44891,7 +44942,7 @@ var init_open_external = __esm({
|
|
|
44891
44942
|
import { spawn as spawn6 } from "node:child_process";
|
|
44892
44943
|
import { readFileSync as readFileSync21, realpathSync as realpathSync8, statSync as statSync15 } from "node:fs";
|
|
44893
44944
|
import { homedir as homedir15 } from "node:os";
|
|
44894
|
-
import { isAbsolute as isAbsolute3, join as
|
|
44945
|
+
import { isAbsolute as isAbsolute3, join as join34, resolve as resolve7, sep } from "node:path";
|
|
44895
44946
|
function isUnder(real, root) {
|
|
44896
44947
|
let rootReal;
|
|
44897
44948
|
try {
|
|
@@ -44921,7 +44972,7 @@ function resolveLocalFile(rawPath, roots) {
|
|
|
44921
44972
|
function resolveOpenableFile(raw2, projectDir, roots, home = homedir15()) {
|
|
44922
44973
|
const trimmed = raw2.trim().replace(/:\d+(?::\d+)?$/, "");
|
|
44923
44974
|
if (!trimmed) return null;
|
|
44924
|
-
const abs = trimmed === "~" ? home : trimmed.startsWith("~/") ?
|
|
44975
|
+
const abs = trimmed === "~" ? home : trimmed.startsWith("~/") ? join34(home, trimmed.slice(2)) : isAbsolute3(trimmed) ? trimmed : resolve7(projectDir, trimmed);
|
|
44925
44976
|
try {
|
|
44926
44977
|
return resolveLocalFile(abs, roots);
|
|
44927
44978
|
} catch {
|
|
@@ -45693,7 +45744,7 @@ var init_directory_picker = __esm({
|
|
|
45693
45744
|
|
|
45694
45745
|
// packages/server/src/router.ts
|
|
45695
45746
|
import { readFileSync as readFileSync22, statSync as statSync17 } from "node:fs";
|
|
45696
|
-
import { join as
|
|
45747
|
+
import { join as join35, resolve as resolve8 } from "node:path";
|
|
45697
45748
|
import { randomUUID as randomUUID16 } from "node:crypto";
|
|
45698
45749
|
import { basename as basename9, dirname as dirname14 } from "node:path";
|
|
45699
45750
|
import { existsSync as existsSync14, mkdirSync as mkdirSync16, rmSync as rmSync9, writeFileSync as writeFileSync13 } from "node:fs";
|
|
@@ -45856,7 +45907,7 @@ function projectCard(entry, stale) {
|
|
|
45856
45907
|
function addProjectAtPath(input) {
|
|
45857
45908
|
const typed = input.trim();
|
|
45858
45909
|
if (!typed) throw new Error("Enter a folder path.");
|
|
45859
|
-
const expanded = typed === "~" || typed.startsWith("~/") ?
|
|
45910
|
+
const expanded = typed === "~" || typed.startsWith("~/") ? join35(homedir16(), typed.slice(1)) : typed;
|
|
45860
45911
|
const absolute = resolve8(expanded);
|
|
45861
45912
|
let stats;
|
|
45862
45913
|
try {
|
|
@@ -45909,7 +45960,7 @@ function setProjectIconFromFile(id, file) {
|
|
|
45909
45960
|
return storeProjectIcon(id, file, bytes);
|
|
45910
45961
|
}
|
|
45911
45962
|
function createRouter(ctx) {
|
|
45912
|
-
const frizzDir =
|
|
45963
|
+
const frizzDir = join35(ctx.project.dir, ".frizz");
|
|
45913
45964
|
const openRoots = openableFileRoots(ctx.project);
|
|
45914
45965
|
function isAutoTitledSession(slug) {
|
|
45915
45966
|
return ctx.storage.getSession(slug)?.title_auto === 1;
|
|
@@ -47564,7 +47615,7 @@ ${gapNote}` : input.message;
|
|
|
47564
47615
|
for (const entry of listProjects()) {
|
|
47565
47616
|
if (entry.stale) continue;
|
|
47566
47617
|
try {
|
|
47567
|
-
const db = new sqlite_default(
|
|
47618
|
+
const db = new sqlite_default(join35(projectStateDir(entry.id), "ui.db"), { readonly: true });
|
|
47568
47619
|
try {
|
|
47569
47620
|
const hit = db.prepare("SELECT 1 FROM session WHERE slug = ? LIMIT 1").get(input.slug);
|
|
47570
47621
|
if (hit) found.push({ projectSlug: entry.slug, projectName: entry.name ?? entry.slug });
|
|
@@ -47957,7 +48008,7 @@ var init_local_image = __esm({
|
|
|
47957
48008
|
// packages/server/src/project-icon.ts
|
|
47958
48009
|
import { readFileSync as readFileSync24, readdirSync as readdirSync10, realpathSync as realpathSync10, statSync as statSync19 } from "node:fs";
|
|
47959
48010
|
import { homedir as homedir17 } from "node:os";
|
|
47960
|
-
import { basename as basename10, dirname as dirname15, extname as extname3, join as
|
|
48011
|
+
import { basename as basename10, dirname as dirname15, extname as extname3, join as join36, relative, sep as sep2 } from "node:path";
|
|
47961
48012
|
function normalizeStem(stem) {
|
|
47962
48013
|
const sized = stem.toLowerCase().replace(/[@-]\d+(\.\d+)?x(\d+)?$/u, "").replace(/[-_]\d{2,4}$/u, "");
|
|
47963
48014
|
const normalized = sized.replace(VARIANT_SUFFIX, "");
|
|
@@ -47975,7 +48026,7 @@ function sizeScore(dimensions) {
|
|
|
47975
48026
|
return Math.max(0, Math.min(40, Math.round(Math.log2(edge / 24) * 8)));
|
|
47976
48027
|
}
|
|
47977
48028
|
function under(root, relativeDirectory) {
|
|
47978
|
-
return relativeDirectory ?
|
|
48029
|
+
return relativeDirectory ? join36(root, relativeDirectory) : root;
|
|
47979
48030
|
}
|
|
47980
48031
|
function listFiles(directory) {
|
|
47981
48032
|
try {
|
|
@@ -47997,19 +48048,19 @@ function iconDirectories(root) {
|
|
|
47997
48048
|
for (const asset of ASSET_DIRECTORIES) directories.push(under(root, asset));
|
|
47998
48049
|
for (const host of HOST_DIRECTORIES) {
|
|
47999
48050
|
if (!children2.has(host)) continue;
|
|
48000
|
-
for (const asset of ASSET_DIRECTORIES) directories.push(under(
|
|
48051
|
+
for (const asset of ASSET_DIRECTORIES) directories.push(under(join36(root, host), asset));
|
|
48001
48052
|
}
|
|
48002
48053
|
for (const extra of EXTRA_DIRECTORIES) directories.push(under(root, extra));
|
|
48003
48054
|
for (const container of WORKSPACE_CONTAINERS) {
|
|
48004
48055
|
if (!children2.has(container)) continue;
|
|
48005
48056
|
let members;
|
|
48006
48057
|
try {
|
|
48007
|
-
members = readdirSync10(
|
|
48058
|
+
members = readdirSync10(join36(root, container), { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name);
|
|
48008
48059
|
} catch {
|
|
48009
48060
|
continue;
|
|
48010
48061
|
}
|
|
48011
48062
|
for (const member of members) {
|
|
48012
|
-
for (const asset of ASSET_DIRECTORIES) directories.push(under(
|
|
48063
|
+
for (const asset of ASSET_DIRECTORIES) directories.push(under(join36(root, container, member), asset));
|
|
48013
48064
|
}
|
|
48014
48065
|
}
|
|
48015
48066
|
return [...new Set(directories)];
|
|
@@ -48023,7 +48074,7 @@ function manifestIcons(manifestPath) {
|
|
|
48023
48074
|
}
|
|
48024
48075
|
if (!Array.isArray(parsed?.icons)) return [];
|
|
48025
48076
|
const directory = dirname15(manifestPath);
|
|
48026
|
-
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) =>
|
|
48077
|
+
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) => join36(directory, src.replace(/[?#].*$/u, "").replace(/^\//u, "")));
|
|
48027
48078
|
}
|
|
48028
48079
|
function projectIconCandidates(root) {
|
|
48029
48080
|
const projectStem = normalizeStem(basename10(root)).normalized;
|
|
@@ -48042,7 +48093,7 @@ function projectIconCandidates(root) {
|
|
|
48042
48093
|
for (const name of listFiles(directory)) {
|
|
48043
48094
|
const extension2 = extname3(name).toLowerCase();
|
|
48044
48095
|
if (MANIFEST_NAMES.includes(name.toLowerCase())) {
|
|
48045
|
-
for (const icon of manifestIcons(
|
|
48096
|
+
for (const icon of manifestIcons(join36(directory, name))) {
|
|
48046
48097
|
if (MEASURABLE_IMAGE_EXTENSIONS.has(extname3(icon).toLowerCase())) {
|
|
48047
48098
|
fromManifest.add(icon);
|
|
48048
48099
|
files.push({ path: icon, directory: dirname15(icon) });
|
|
@@ -48053,7 +48104,7 @@ function projectIconCandidates(root) {
|
|
|
48053
48104
|
if (!MEASURABLE_IMAGE_EXTENSIONS.has(extension2)) continue;
|
|
48054
48105
|
const stem = name.slice(0, name.length - extension2.length);
|
|
48055
48106
|
if (normalizeStem(stem).normalized === "favicon") iconHomes.add(directory);
|
|
48056
|
-
files.push({ path:
|
|
48107
|
+
files.push({ path: join36(directory, name), directory });
|
|
48057
48108
|
if (files.length >= MAX_CANDIDATES) break;
|
|
48058
48109
|
}
|
|
48059
48110
|
}
|
|
@@ -48231,7 +48282,7 @@ var init_project_icon = __esm({
|
|
|
48231
48282
|
|
|
48232
48283
|
// packages/server/src/local-visualization.ts
|
|
48233
48284
|
import { readdirSync as readdirSync11, readFileSync as readFileSync25, realpathSync as realpathSync11, statSync as statSync20 } from "node:fs";
|
|
48234
|
-
import { join as
|
|
48285
|
+
import { join as join37, sep as sep3 } from "node:path";
|
|
48235
48286
|
function children(path, pattern) {
|
|
48236
48287
|
try {
|
|
48237
48288
|
return readdirSync11(path, { withFileTypes: true }).filter((entry) => entry.isDirectory() && pattern.test(entry.name)).map((entry) => entry.name).sort().reverse();
|
|
@@ -48243,7 +48294,7 @@ function isUnder2(path, root) {
|
|
|
48243
48294
|
return path === root || path.startsWith(root.endsWith(sep3) ? root : root + sep3);
|
|
48244
48295
|
}
|
|
48245
48296
|
function resolveFragment(projectDir, sessionId, file) {
|
|
48246
|
-
const base =
|
|
48297
|
+
const base = join37(projectDir, ".codex", "visualizations");
|
|
48247
48298
|
let projectReal;
|
|
48248
48299
|
let baseReal;
|
|
48249
48300
|
try {
|
|
@@ -48254,12 +48305,12 @@ function resolveFragment(projectDir, sessionId, file) {
|
|
|
48254
48305
|
}
|
|
48255
48306
|
if (!isUnder2(baseReal, projectReal)) return null;
|
|
48256
48307
|
for (const year of children(base, YEAR_PART)) {
|
|
48257
|
-
const yearDir =
|
|
48308
|
+
const yearDir = join37(base, year);
|
|
48258
48309
|
for (const month of children(yearDir, DATE_PART)) {
|
|
48259
|
-
const monthDir =
|
|
48310
|
+
const monthDir = join37(yearDir, month);
|
|
48260
48311
|
for (const day of children(monthDir, DATE_PART)) {
|
|
48261
|
-
const sessionRoot =
|
|
48262
|
-
const candidate =
|
|
48312
|
+
const sessionRoot = join37(baseReal, year, month, day, sessionId);
|
|
48313
|
+
const candidate = join37(monthDir, day, sessionId, file);
|
|
48263
48314
|
try {
|
|
48264
48315
|
const real = realpathSync11(candidate);
|
|
48265
48316
|
if (isUnder2(real, sessionRoot) && statSync20(real).isFile()) return real;
|
|
@@ -48388,7 +48439,7 @@ var init_local_visualization = __esm({
|
|
|
48388
48439
|
|
|
48389
48440
|
// packages/server/src/app.ts
|
|
48390
48441
|
import { mkdirSync as mkdirSync17, writeFileSync as writeFileSync14 } from "node:fs";
|
|
48391
|
-
import { join as
|
|
48442
|
+
import { join as join38 } from "node:path";
|
|
48392
48443
|
import { randomUUID as randomUUID17 } from "node:crypto";
|
|
48393
48444
|
function createApp(ctx, options = {}) {
|
|
48394
48445
|
const app = new Hono2();
|
|
@@ -48492,10 +48543,10 @@ function createApp(ctx, options = {}) {
|
|
|
48492
48543
|
if (typeof body.data !== "string" || body.data.length > ATTACHMENT_MAX_BASE64_CHARS) return c.json({ error: "bad payload" }, 400);
|
|
48493
48544
|
const ext = `.${attachmentExtension(name)}`;
|
|
48494
48545
|
const buf = Buffer.from(body.data, "base64");
|
|
48495
|
-
const dir =
|
|
48546
|
+
const dir = join38(ctx.project.stateDir, "attachments");
|
|
48496
48547
|
mkdirSync17(dir, { recursive: true });
|
|
48497
48548
|
const base = name.replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9_-]+/g, "-").slice(0, 40) || "file";
|
|
48498
|
-
const path =
|
|
48549
|
+
const path = join38(dir, `${Date.now()}-${randomUUID17().slice(0, 8)}-${base}${ext}`);
|
|
48499
48550
|
writeFileSync14(path, buf);
|
|
48500
48551
|
return c.json({ path });
|
|
48501
48552
|
});
|
|
@@ -49735,9 +49786,9 @@ var init_app_socket = __esm({
|
|
|
49735
49786
|
|
|
49736
49787
|
// packages/server/src/boot-progress.ts
|
|
49737
49788
|
import { mkdirSync as mkdirSync18, readFileSync as readFileSync26, renameSync as renameSync10, rmSync as rmSync10, writeFileSync as writeFileSync15 } from "node:fs";
|
|
49738
|
-
import { basename as basename11, dirname as dirname16, join as
|
|
49789
|
+
import { basename as basename11, dirname as dirname16, join as join39 } from "node:path";
|
|
49739
49790
|
function bootProgressPath(stateDir) {
|
|
49740
|
-
return
|
|
49791
|
+
return join39(stateDir, BOOT_PROGRESS_NAME);
|
|
49741
49792
|
}
|
|
49742
49793
|
function createBootProgressPublisher(stateDir, minIntervalMs = 200) {
|
|
49743
49794
|
if (!stateDir) {
|
|
@@ -49758,7 +49809,7 @@ function createBootProgressPublisher(stateDir, minIntervalMs = 200) {
|
|
|
49758
49809
|
step++;
|
|
49759
49810
|
try {
|
|
49760
49811
|
mkdirSync18(dirname16(path), { recursive: true, mode: 448 });
|
|
49761
|
-
const temp =
|
|
49812
|
+
const temp = join39(dirname16(path), `.${basename11(path)}.${process.pid}.tmp`);
|
|
49762
49813
|
writeFileSync15(temp, `${JSON.stringify({ pid: process.pid, step, phase, at: new Date(now).toISOString() })}
|
|
49763
49814
|
`, "utf8");
|
|
49764
49815
|
renameSync10(temp, path);
|
|
@@ -49876,7 +49927,7 @@ __export(index_exports, {
|
|
|
49876
49927
|
});
|
|
49877
49928
|
import { createServer } from "node:http";
|
|
49878
49929
|
import { readFileSync as readFileSync27, existsSync as existsSync15 } from "node:fs";
|
|
49879
|
-
import { dirname as dirname17, join as
|
|
49930
|
+
import { dirname as dirname17, join as join40, resolve as resolve9, extname as extname4, normalize } from "node:path";
|
|
49880
49931
|
function readServerAddressHolder(path) {
|
|
49881
49932
|
try {
|
|
49882
49933
|
const value = JSON.parse(readFileSync27(path, "utf8"));
|
|
@@ -49979,9 +50030,9 @@ function createShutdownSignalHandler(options) {
|
|
|
49979
50030
|
}
|
|
49980
50031
|
function serveStatic(distDir, req, res) {
|
|
49981
50032
|
const rel = normalize((req.url ?? "/").split("?")[0]).replace(/^(\.\.[/\\])+/, "");
|
|
49982
|
-
let file =
|
|
49983
|
-
if (!file.startsWith(distDir)) file =
|
|
49984
|
-
if (!existsSync15(file)) file =
|
|
50033
|
+
let file = join40(distDir, rel === "/" ? "index.html" : rel);
|
|
50034
|
+
if (!file.startsWith(distDir)) file = join40(distDir, "index.html");
|
|
50035
|
+
if (!existsSync15(file)) file = join40(distDir, "index.html");
|
|
49985
50036
|
try {
|
|
49986
50037
|
const body = readFileSync27(file);
|
|
49987
50038
|
res.writeHead(200, { "content-type": MIME[extname4(file)] ?? "application/octet-stream" });
|
|
@@ -50332,7 +50383,7 @@ async function startServer(opts = {}) {
|
|
|
50332
50383
|
}
|
|
50333
50384
|
statusPath = serverLockPathFor(ctx.project);
|
|
50334
50385
|
const webRoot = resolve9(import.meta.dirname, "..", "..", "web");
|
|
50335
|
-
const distDir = opts.webDistDir ? resolve9(opts.webDistDir) :
|
|
50386
|
+
const distDir = opts.webDistDir ? resolve9(opts.webDistDir) : join40(webRoot, "dist");
|
|
50336
50387
|
startupPhase = "Vite";
|
|
50337
50388
|
if (opts.dev) {
|
|
50338
50389
|
try {
|
|
@@ -50408,7 +50459,7 @@ async function startServer(opts = {}) {
|
|
|
50408
50459
|
if (vite) {
|
|
50409
50460
|
vite.middlewares(req, res, () => {
|
|
50410
50461
|
try {
|
|
50411
|
-
const html = readFileSync27(
|
|
50462
|
+
const html = readFileSync27(join40(webRoot, "index.html"), "utf8");
|
|
50412
50463
|
void vite.transformIndexHtml(url, html).then((out) => {
|
|
50413
50464
|
res.writeHead(200, { "content-type": "text/html" });
|
|
50414
50465
|
res.end(out);
|
|
@@ -50600,7 +50651,7 @@ var init_index = __esm({
|
|
|
50600
50651
|
}
|
|
50601
50652
|
};
|
|
50602
50653
|
isApiUrl = (url) => url === FRIZZ_ROUTE_PREFIX || url.startsWith(`${FRIZZ_ROUTE_PREFIX}/`);
|
|
50603
|
-
serverLockPathFor = (project) =>
|
|
50654
|
+
serverLockPathFor = (project) => join40(project.stateDir, "server.lock");
|
|
50604
50655
|
MIME = {
|
|
50605
50656
|
".html": "text/html",
|
|
50606
50657
|
".js": "text/javascript",
|
|
@@ -50619,7 +50670,7 @@ init_project_launch();
|
|
|
50619
50670
|
init_shutdown();
|
|
50620
50671
|
init_logging();
|
|
50621
50672
|
import { existsSync as existsSync16 } from "node:fs";
|
|
50622
|
-
import { join as
|
|
50673
|
+
import { join as join41 } from "node:path";
|
|
50623
50674
|
process.on("uncaughtException", (error) => {
|
|
50624
50675
|
log.error("dev-child", `uncaught exception: ${error instanceof Error ? error.stack ?? error.message : error}`);
|
|
50625
50676
|
process.exit(1);
|
|
@@ -50659,7 +50710,7 @@ try {
|
|
|
50659
50710
|
];
|
|
50660
50711
|
if (!existsSync16(stableWebDist)) throw new Error("stable artifact launch is missing its verified web directory");
|
|
50661
50712
|
for (const [name, directory, requiredFile] of required) {
|
|
50662
|
-
if (!directory || !existsSync16(
|
|
50713
|
+
if (!directory || !existsSync16(join41(directory, requiredFile)))
|
|
50663
50714
|
throw new Error(`stable artifact launch is missing verified ${name}`);
|
|
50664
50715
|
}
|
|
50665
50716
|
}
|