frizz-server 0.13.8 → 0.14.0
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/claude-agent-broker.js +14659 -14376
- package/dist/dev-child.js +217 -107
- package/package.json +1 -1
- package/web-dist/assets/{TerminalPane-CgFt4ple.js → TerminalPane-DcNJcvz9.js} +1 -1
- package/web-dist/assets/{abnfDiagram-VRR7QNED-DoVWUENi.js → abnfDiagram-VRR7QNED-BFKPkR0J.js} +1 -1
- package/web-dist/assets/architecture-TIHT7OUA-3cEHc0mh.js +1 -0
- package/web-dist/assets/{architectureDiagram-ZJ3FMSHR-BE2vu5s4.js → architectureDiagram-ZJ3FMSHR-BugbGvF7.js} +1 -1
- package/web-dist/assets/{blockDiagram-677ZJIJ3-D6LvUZ6S.js → blockDiagram-677ZJIJ3-B1drPHOm.js} +1 -1
- package/web-dist/assets/{c4Diagram-LMCZKHZV-BDZel4B4.js → c4Diagram-LMCZKHZV-jA8etf56.js} +1 -1
- package/web-dist/assets/channel-BYQQkw21.js +1 -0
- package/web-dist/assets/{chunk-32BRIVSS-fmjhgloi.js → chunk-32BRIVSS-BfMUf_Yy.js} +1 -1
- package/web-dist/assets/{chunk-52WLFC77-sfh419xE.js → chunk-52WLFC77-Fo52YmmC.js} +1 -1
- package/web-dist/assets/{chunk-C7G6YPKG-D-LGx-oa.js → chunk-C7G6YPKG-CPiVGUnC.js} +1 -1
- package/web-dist/assets/{chunk-EX3LRPZG-DriDj_NL.js → chunk-EX3LRPZG-DllbzsPn.js} +1 -1
- package/web-dist/assets/{chunk-FWX5IMBZ-DetgkllZ.js → chunk-FWX5IMBZ-Cr7SCNOQ.js} +2 -2
- package/web-dist/assets/{chunk-HOUHSVGY-CDGGE0PL.js → chunk-HOUHSVGY-D2qjbRMK.js} +1 -1
- package/web-dist/assets/{chunk-ICXQ74PX-CIgu37mb.js → chunk-ICXQ74PX-Dl8ZZqX4.js} +1 -1
- package/web-dist/assets/{chunk-MOJQB5TN-BNj77oeQ.js → chunk-MOJQB5TN-C7X9x33F.js} +1 -1
- package/web-dist/assets/{chunk-OGEWGWER-BRoVc26C.js → chunk-OGEWGWER-DrlPoLRT.js} +1 -1
- package/web-dist/assets/{chunk-PUDLZKDR-B9bHTS14.js → chunk-PUDLZKDR-C1WS3qVH.js} +1 -1
- package/web-dist/assets/{chunk-Q4XR5HBZ-CjqwAtw6.js → chunk-Q4XR5HBZ-CNhqnN4i.js} +1 -1
- package/web-dist/assets/{chunk-V7JOEXUC-ClYL5Jo9.js → chunk-V7JOEXUC-BQsiP60Y.js} +1 -1
- package/web-dist/assets/{chunk-VAUOI2AC-DsyULg7-.js → chunk-VAUOI2AC-DeQswo6G.js} +1 -1
- package/web-dist/assets/{chunk-VR4S4FIN-x_8ywB7J.js → chunk-VR4S4FIN-QCzpzy3F.js} +1 -1
- package/web-dist/assets/{chunk-WYO6CB5R-BDWUsOuN.js → chunk-WYO6CB5R-DYEAXxaM.js} +1 -1
- package/web-dist/assets/{chunk-ZGVPDNZ5-wAbPuGaE.js → chunk-ZGVPDNZ5-BRwJsVqD.js} +1 -1
- package/web-dist/assets/classDiagram-OUVF2IWQ-BgM58S9B.js +1 -0
- package/web-dist/assets/classDiagram-v2-EOCWNBFH-BgM58S9B.js +1 -0
- package/web-dist/assets/{cynefin-VYW2F7L2-DLLNSytS.js → cynefin-VYW2F7L2-DFY4wScy.js} +1 -1
- package/web-dist/assets/{cynefinDiagram-TSTJHNR4-6kBJrScm.js → cynefinDiagram-TSTJHNR4-BFd6vF05.js} +1 -1
- package/web-dist/assets/{dagre-VKFMJZFB-Z_OVqFBK.js → dagre-VKFMJZFB-BTSZ-kNz.js} +1 -1
- package/web-dist/assets/{diagram-FQU43EPY-C_nG5FUG.js → diagram-FQU43EPY-CM5L_Teo.js} +1 -1
- package/web-dist/assets/{diagram-G47NLZAW-CYQTveO9.js → diagram-G47NLZAW-DMEMjhev.js} +1 -1
- package/web-dist/assets/{diagram-NH7WQ7WH-C2DkBAm5.js → diagram-NH7WQ7WH-BINXDe2x.js} +1 -1
- package/web-dist/assets/{diagram-OA4YK3LP-CSDwzhMR.js → diagram-OA4YK3LP-DhKBXS5G.js} +1 -1
- package/web-dist/assets/{diagram-WEI45ONY-R1MvefNj.js → diagram-WEI45ONY-QaICPLa1.js} +1 -1
- package/web-dist/assets/{ebnfDiagram-CCIWWBDH-DBXUjfz2.js → ebnfDiagram-CCIWWBDH-DDQ6NAEt.js} +1 -1
- package/web-dist/assets/{erDiagram-Q63AITRT-D2XH_vxG.js → erDiagram-Q63AITRT-eftnFvxT.js} +1 -1
- package/web-dist/assets/eventmodeling-45OFAUF4-KZNoVoEu.js +1 -0
- package/web-dist/assets/flowDiagram-23GEKE2U-m4sDfmpP.js +1 -0
- package/web-dist/assets/{ganttDiagram-NO4QXBWP-BqJqGmJu.js → ganttDiagram-NO4QXBWP-CBUUxbvO.js} +1 -1
- package/web-dist/assets/{gitGraph-TEB2WS4Q-BpED4Y4w.js → gitGraph-TEB2WS4Q-B4j6N6bC.js} +1 -1
- package/web-dist/assets/{gitGraphDiagram-IHSO6WYX-CpCzUYgA.js → gitGraphDiagram-IHSO6WYX-mrIlQ6c3.js} +1 -1
- package/web-dist/assets/index-BI0k4RW8.js +319 -0
- package/web-dist/assets/index-CzN-tCOl.css +1 -0
- package/web-dist/assets/{info-DKCQHKI2-Bm1fWKNN.js → info-DKCQHKI2-Dj4G-7Y8.js} +1 -1
- package/web-dist/assets/{infoDiagram-FWYZ7A6U-C61BGKNf.js → infoDiagram-FWYZ7A6U-Baz07f6h.js} +1 -1
- package/web-dist/assets/{ishikawaDiagram-FXEZZL3T-0Fmof1Bc.js → ishikawaDiagram-FXEZZL3T-C4og8CF4.js} +1 -1
- package/web-dist/assets/{journeyDiagram-5HDEW3XC-DHuJoS_U.js → journeyDiagram-5HDEW3XC-B0WV30vH.js} +1 -1
- package/web-dist/assets/{kanban-definition-HUTT4EX6-ClLsOpPq.js → kanban-definition-HUTT4EX6-BgDiY6B1.js} +1 -1
- package/web-dist/assets/{line-BQNlaa-L.js → line-D0SxxXfr.js} +1 -1
- package/web-dist/assets/{mermaid-parser.core-Dhg0FCF0.js → mermaid-parser.core-CWj7pjCH.js} +3 -3
- package/web-dist/assets/{mermaid.core-OSL7u28D.js → mermaid.core-Dpi4Z-WK.js} +3 -3
- package/web-dist/assets/{mindmap-definition-LN4V7U3C-CMh2RRdG.js → mindmap-definition-LN4V7U3C-DLmQQ7LC.js} +1 -1
- package/web-dist/assets/{packet-7NZHBO7P-DqizytaZ.js → packet-7NZHBO7P-T7pVIfFz.js} +1 -1
- package/web-dist/assets/{pegDiagram-2B236MQR-C_xsQ7ey.js → pegDiagram-2B236MQR-BvVxzZmj.js} +1 -1
- package/web-dist/assets/{pie-RZYD4A2V-Dg0NeJ6P.js → pie-RZYD4A2V-BGz-hjIz.js} +1 -1
- package/web-dist/assets/{pieDiagram-ENE6RG2P-B2przwvg.js → pieDiagram-ENE6RG2P-pdOHyNTd.js} +1 -1
- package/web-dist/assets/{quadrantDiagram-ABIIQ3AL-B5xLDvCk.js → quadrantDiagram-ABIIQ3AL-fLy3coW3.js} +1 -1
- package/web-dist/assets/{radar-I7S5WNFK-DItULivd.js → radar-I7S5WNFK-C-VKX4OE.js} +1 -1
- package/web-dist/assets/{railroad-3IZDKUUU-BVSgw6fD.js → railroad-3IZDKUUU-BwC-mtji.js} +1 -1
- package/web-dist/assets/railroad-abnf-AHOZXSZD-CNsCN0k6.js +1 -0
- package/web-dist/assets/railroad-ebnf-EBAXGLYW-Bjabtkan.js +1 -0
- package/web-dist/assets/railroad-peg-LSFZ7HO6-DjPlt8Lc.js +1 -0
- package/web-dist/assets/{railroadDiagram-RFXS5EU6-DQh-iy6H.js → railroadDiagram-RFXS5EU6-BxPp9neb.js} +1 -1
- package/web-dist/assets/{requirementDiagram-TGXJPOKE-B2bjpE-s.js → requirementDiagram-TGXJPOKE-P_BvOjKp.js} +1 -1
- package/web-dist/assets/{sankeyDiagram-HTMAVEWB-C-vr6CRd.js → sankeyDiagram-HTMAVEWB-DUv1nZCv.js} +1 -1
- package/web-dist/assets/{sequenceDiagram-DBY2YBRQ-C48rDu8k.js → sequenceDiagram-DBY2YBRQ-DWNx793M.js} +1 -1
- package/web-dist/assets/{stateDiagram-2N3HPSRC-BEHBNPlt.js → stateDiagram-2N3HPSRC-CaOUtkvy.js} +1 -1
- package/web-dist/assets/stateDiagram-v2-6OUMAXLB-CbgDxwEv.js +1 -0
- package/web-dist/assets/{swimlanes-5IMT3BWC-BK0pUXUO.js → swimlanes-5IMT3BWC-D764GMah.js} +1 -1
- package/web-dist/assets/swimlanesDiagram-G3AALYLV-QPzvJba6.js +8 -0
- package/web-dist/assets/{timeline-definition-FHXFAJF6-CQ3rH4CA.js → timeline-definition-FHXFAJF6-DeKz_jJG.js} +1 -1
- package/web-dist/assets/{treeView-QDETBFTQ-DrgwDaib.js → treeView-QDETBFTQ-D3UnDOk3.js} +1 -1
- package/web-dist/assets/{treemap-6X3UGDF4-CGlOb_mN.js → treemap-6X3UGDF4-VItEAzU3.js} +1 -1
- package/web-dist/assets/{vennDiagram-L72KCM5P-BB9TjfQX.js → vennDiagram-L72KCM5P-DuzNjZFZ.js} +1 -1
- package/web-dist/assets/{wardley-OPB4EBWU-C8EK8ow0.js → wardley-OPB4EBWU-B1uIoPVb.js} +1 -1
- package/web-dist/assets/{wardleyDiagram-EHGQE667-CUeOWZBB.js → wardleyDiagram-EHGQE667-H60TjU5y.js} +1 -1
- package/web-dist/assets/{xychartDiagram-FW5EYKEG-8ZymnyMt.js → xychartDiagram-FW5EYKEG-BqTqYEwv.js} +1 -1
- package/web-dist/index.html +2 -2
- package/web-dist/assets/architecture-TIHT7OUA-DJ_aT0bS.js +0 -1
- package/web-dist/assets/channel-D3v1O4Wy.js +0 -1
- package/web-dist/assets/classDiagram-OUVF2IWQ-LvSRVuLl.js +0 -1
- package/web-dist/assets/classDiagram-v2-EOCWNBFH-LvSRVuLl.js +0 -1
- package/web-dist/assets/eventmodeling-45OFAUF4-DQtNFbyn.js +0 -1
- package/web-dist/assets/flowDiagram-23GEKE2U-DPAGYT4s.js +0 -1
- package/web-dist/assets/index-DfJaB5hp.css +0 -1
- package/web-dist/assets/index-vTgjYcOv.js +0 -319
- package/web-dist/assets/railroad-abnf-AHOZXSZD-Du1T7UC_.js +0 -1
- package/web-dist/assets/railroad-ebnf-EBAXGLYW-Ck5QAc8a.js +0 -1
- package/web-dist/assets/railroad-peg-LSFZ7HO6-CA1OLi4_.js +0 -1
- package/web-dist/assets/stateDiagram-v2-6OUMAXLB-BiZG09Uh.js +0 -1
- package/web-dist/assets/swimlanesDiagram-G3AALYLV-CenRab4t.js +0 -8
package/dist/dev-child.js
CHANGED
|
@@ -15290,7 +15290,9 @@ var init_src = __esm({
|
|
|
15290
15290
|
SetThreadProfileInput = external_exports.object({
|
|
15291
15291
|
slug: ThreadSlug,
|
|
15292
15292
|
model: external_exports.string().trim().min(1).max(200),
|
|
15293
|
-
|
|
15293
|
+
// Absent ONLY for an ACP thread, whose model slug (`acp:<agent>@<model>`) carries no effort axis; the
|
|
15294
|
+
// router refuses a Claude/Codex profile without one rather than storing "".
|
|
15295
|
+
effort: external_exports.string().trim().min(1).max(100).optional()
|
|
15294
15296
|
}).strict();
|
|
15295
15297
|
SetThreadProfileResult = external_exports.object({
|
|
15296
15298
|
effect: external_exports.enum(["applied", "next-resume"])
|
|
@@ -16139,6 +16141,39 @@ function resolveProjectIcon(id, detect, options = {}) {
|
|
|
16139
16141
|
}, home);
|
|
16140
16142
|
return found;
|
|
16141
16143
|
}
|
|
16144
|
+
function renameProject(id, update, home = homedir4()) {
|
|
16145
|
+
const registry = readRegistry(home);
|
|
16146
|
+
const entry = registry.projects.find((p) => p.id === id);
|
|
16147
|
+
if (!entry) return void 0;
|
|
16148
|
+
if (update.slug !== void 0) {
|
|
16149
|
+
const slug = slugifyProject(update.slug);
|
|
16150
|
+
if (RESERVED.has(slug)) throw new Error(`"${slug}" is reserved by Frizz itself`);
|
|
16151
|
+
if (registry.projects.some((p) => p.id !== id && p.slug === slug)) {
|
|
16152
|
+
throw new Error(`another project already uses "${slug}"`);
|
|
16153
|
+
}
|
|
16154
|
+
entry.slug = slug;
|
|
16155
|
+
}
|
|
16156
|
+
if (update.name === null) delete entry.name;
|
|
16157
|
+
else if (update.name !== void 0) entry.name = update.name;
|
|
16158
|
+
if (update.archived !== void 0) entry.archived = update.archived;
|
|
16159
|
+
writeRegistry(registry, home);
|
|
16160
|
+
return entry;
|
|
16161
|
+
}
|
|
16162
|
+
function moveProjectDirectory(id, newBasename, home = homedir4()) {
|
|
16163
|
+
const entry = findById(id, home);
|
|
16164
|
+
if (!entry) throw new Error("No such project.");
|
|
16165
|
+
const name = newBasename.trim();
|
|
16166
|
+
if (!name || name === "." || name === ".." || /[\\/\0]/u.test(name)) {
|
|
16167
|
+
throw new Error("A folder name cannot contain a slash.");
|
|
16168
|
+
}
|
|
16169
|
+
if (!existsSync3(entry.path)) throw new Error(`The folder is missing: ${entry.path}`);
|
|
16170
|
+
const target = join5(dirname4(entry.path), name);
|
|
16171
|
+
if (target === entry.path) return entry;
|
|
16172
|
+
if (existsSync3(target)) throw new Error(`Something already exists at ${target}`);
|
|
16173
|
+
renameSync3(entry.path, target);
|
|
16174
|
+
const moved = registerProject({ dir: target, id }, home);
|
|
16175
|
+
return moved.entry ?? entry;
|
|
16176
|
+
}
|
|
16142
16177
|
function forgetProject(id, home = homedir4()) {
|
|
16143
16178
|
const registry = readRegistry(home);
|
|
16144
16179
|
const before = registry.projects.length;
|
|
@@ -26616,13 +26651,13 @@ function searchPath2(env) {
|
|
|
26616
26651
|
function vendoredNativeBeside(launcherJs, arch, access) {
|
|
26617
26652
|
const triple = WINDOWS_TRIPLE[arch];
|
|
26618
26653
|
if (!triple) return void 0;
|
|
26619
|
-
const { dirname:
|
|
26620
|
-
const pkgRoot =
|
|
26654
|
+
const { dirname: dirname27, join: join49 } = win322;
|
|
26655
|
+
const pkgRoot = dirname27(dirname27(launcherJs));
|
|
26621
26656
|
const platformPkg = `codex-win32-${arch}`;
|
|
26622
26657
|
const vendorRoots = [
|
|
26623
26658
|
join49(pkgRoot, "node_modules", "@openai", platformPkg, "vendor"),
|
|
26624
26659
|
// nested under the package
|
|
26625
|
-
join49(
|
|
26660
|
+
join49(dirname27(pkgRoot), platformPkg, "vendor"),
|
|
26626
26661
|
// hoisted beside it: <prefix>\node_modules\@openai\<pkg>
|
|
26627
26662
|
join49(pkgRoot, "vendor")
|
|
26628
26663
|
// the pre-platform-package layout, binaries inside @openai/codex itself
|
|
@@ -32451,11 +32486,11 @@ var init_codex_app_server = __esm({
|
|
|
32451
32486
|
init_logging();
|
|
32452
32487
|
CODEX_APP_SERVER_PROVIDER = "codex-app-server";
|
|
32453
32488
|
CODEX_NATIVE_LISTEN_FLAG = "FRIZZ_CODEX_NATIVE_LISTEN";
|
|
32454
|
-
CODEX_APP_SERVER_SUPPORTED_VERSION = "0.
|
|
32489
|
+
CODEX_APP_SERVER_SUPPORTED_VERSION = "0.155.0";
|
|
32455
32490
|
CODEX_APP_SERVER_PROTOCOL_REVISION = Object.freeze({
|
|
32456
32491
|
packageVersion: CODEX_APP_SERVER_SUPPORTED_VERSION,
|
|
32457
|
-
sourceTag: "rust-v0.
|
|
32458
|
-
sourceCommit: "
|
|
32492
|
+
sourceTag: "rust-v0.155.0",
|
|
32493
|
+
sourceCommit: "f0a1b8f0849d90960bc406b848f32e5a129b0457"
|
|
32459
32494
|
});
|
|
32460
32495
|
PROTOCOL_FINGERPRINT = [
|
|
32461
32496
|
CODEX_APP_SERVER_PROTOCOL_REVISION.sourceTag,
|
|
@@ -35204,11 +35239,21 @@ var init_quota = __esm({
|
|
|
35204
35239
|
}
|
|
35205
35240
|
});
|
|
35206
35241
|
|
|
35242
|
+
// packages/server/src/local-path.ts
|
|
35243
|
+
function normalizeLocalPath(path3, platform3 = process.platform) {
|
|
35244
|
+
return platform3 === "win32" ? path3.replace(/^\/([a-zA-Z]:[\\/])/, "$1") : path3;
|
|
35245
|
+
}
|
|
35246
|
+
var init_local_path = __esm({
|
|
35247
|
+
"packages/server/src/local-path.ts"() {
|
|
35248
|
+
"use strict";
|
|
35249
|
+
}
|
|
35250
|
+
});
|
|
35251
|
+
|
|
35207
35252
|
// packages/server/src/local-file.ts
|
|
35208
35253
|
import { spawn as spawn5 } from "node:child_process";
|
|
35209
35254
|
import { existsSync as existsSync8, readFileSync as readFileSync18, realpathSync as realpathSync6, statSync as statSync13 } from "node:fs";
|
|
35210
35255
|
import { homedir as homedir11 } from "node:os";
|
|
35211
|
-
import { isAbsolute as isAbsolute4, join as join26, resolve as resolve5, sep as sep2 } from "node:path";
|
|
35256
|
+
import { dirname as dirname10, isAbsolute as isAbsolute4, join as join26, resolve as resolve5, sep as sep2 } from "node:path";
|
|
35212
35257
|
function isUnder(real, root) {
|
|
35213
35258
|
let rootReal;
|
|
35214
35259
|
try {
|
|
@@ -35216,9 +35261,25 @@ function isUnder(real, root) {
|
|
|
35216
35261
|
} catch {
|
|
35217
35262
|
return false;
|
|
35218
35263
|
}
|
|
35219
|
-
|
|
35264
|
+
if (process.platform !== "win32") {
|
|
35265
|
+
return real === rootReal || real.startsWith(rootReal.endsWith(sep2) ? rootReal : rootReal + sep2);
|
|
35266
|
+
}
|
|
35267
|
+
try {
|
|
35268
|
+
const trusted = statSync13(rootReal, { bigint: true });
|
|
35269
|
+
if (!trusted.isDirectory() || trusted.ino === 0n) return false;
|
|
35270
|
+
for (let ancestor = real; ; ) {
|
|
35271
|
+
const actual = statSync13(ancestor, { bigint: true });
|
|
35272
|
+
if (actual.dev === trusted.dev && actual.ino === trusted.ino) return true;
|
|
35273
|
+
const parent = dirname10(ancestor);
|
|
35274
|
+
if (parent === ancestor) return false;
|
|
35275
|
+
ancestor = parent;
|
|
35276
|
+
}
|
|
35277
|
+
} catch {
|
|
35278
|
+
return false;
|
|
35279
|
+
}
|
|
35220
35280
|
}
|
|
35221
35281
|
function resolveLocalFile(rawPath, roots) {
|
|
35282
|
+
rawPath = normalizeLocalPath(rawPath);
|
|
35222
35283
|
if (!isAbsolute4(rawPath)) throw new Error("Local path must be absolute");
|
|
35223
35284
|
let real;
|
|
35224
35285
|
try {
|
|
@@ -35323,6 +35384,7 @@ var MARKDOWN_FILE_EXT, MARKDOWN_READ_LIMIT, WINDOWS_EDITOR_EXE;
|
|
|
35323
35384
|
var init_local_file = __esm({
|
|
35324
35385
|
"packages/server/src/local-file.ts"() {
|
|
35325
35386
|
"use strict";
|
|
35387
|
+
init_local_path();
|
|
35326
35388
|
MARKDOWN_FILE_EXT = /\.(?:md|mdx|markdown)$/i;
|
|
35327
35389
|
MARKDOWN_READ_LIMIT = 1024 * 1024;
|
|
35328
35390
|
WINDOWS_EDITOR_EXE = {
|
|
@@ -35366,7 +35428,7 @@ var init_thread_links = __esm({
|
|
|
35366
35428
|
// packages/server/src/frizz.ts
|
|
35367
35429
|
import { execFile as execFile6 } from "node:child_process";
|
|
35368
35430
|
import { lstatSync as lstatSync2, realpathSync as realpathSync7 } from "node:fs";
|
|
35369
|
-
import { basename as basename5, dirname as
|
|
35431
|
+
import { basename as basename5, dirname as dirname11, join as join27, resolve as resolve6 } from "node:path";
|
|
35370
35432
|
import { promisify as promisify5 } from "node:util";
|
|
35371
35433
|
function frizzScriptsDir() {
|
|
35372
35434
|
if (process.env.FRIZZ_SCRIPTS_DIR) return process.env.FRIZZ_SCRIPTS_DIR;
|
|
@@ -35379,7 +35441,7 @@ function directFrizzRoot(projectDir) {
|
|
|
35379
35441
|
const stat2 = lstatSync2(path3);
|
|
35380
35442
|
if (!stat2.isDirectory() || stat2.isSymbolicLink()) return null;
|
|
35381
35443
|
const real = realpathSync7(path3);
|
|
35382
|
-
return
|
|
35444
|
+
return dirname11(real) === projectRoot && basename5(real) === ".frizz" ? real : null;
|
|
35383
35445
|
} catch {
|
|
35384
35446
|
return null;
|
|
35385
35447
|
}
|
|
@@ -35655,17 +35717,17 @@ var init_project_mcp_servers = __esm({
|
|
|
35655
35717
|
|
|
35656
35718
|
// packages/server/src/worker-plugin-dir.ts
|
|
35657
35719
|
import { existsSync as existsSync9 } from "node:fs";
|
|
35658
|
-
import { dirname as
|
|
35720
|
+
import { dirname as dirname12, join as join29 } from "node:path";
|
|
35659
35721
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
35660
35722
|
function resolveWorkerPluginDir(moduleUrl = import.meta.url, env = process.env) {
|
|
35661
35723
|
const override = env.FRIZZ_WORKER_PLUGIN_DIR;
|
|
35662
35724
|
if (override && existsSync9(join29(override, ".claude-plugin", "plugin.json")))
|
|
35663
35725
|
return override;
|
|
35664
|
-
let current =
|
|
35726
|
+
let current = dirname12(fileURLToPath3(moduleUrl));
|
|
35665
35727
|
for (; ; ) {
|
|
35666
35728
|
const candidate = join29(current, "cc-worker");
|
|
35667
35729
|
if (existsSync9(join29(candidate, ".claude-plugin", "plugin.json"))) return candidate;
|
|
35668
|
-
const parent =
|
|
35730
|
+
const parent = dirname12(current);
|
|
35669
35731
|
if (parent === current) return void 0;
|
|
35670
35732
|
current = parent;
|
|
35671
35733
|
}
|
|
@@ -37638,7 +37700,7 @@ var init_claude_agent_broker_bridge = __esm({
|
|
|
37638
37700
|
|
|
37639
37701
|
// packages/server/src/dispatch.ts
|
|
37640
37702
|
import { closeSync as closeSync12, constants as constants2, existsSync as existsSync10, fstatSync as fstatSync2, lstatSync as lstatSync3, openSync as openSync13, readFileSync as readFileSync20, realpathSync as realpathSync8, statSync as statSync15, writeFileSync as writeFileSync10, mkdirSync as mkdirSync13, rmSync as rmSync9 } from "node:fs";
|
|
37641
|
-
import { basename as basename6, join as join31, dirname as
|
|
37703
|
+
import { basename as basename6, join as join31, dirname as dirname13 } from "node:path";
|
|
37642
37704
|
import { createHash as createHash11, randomUUID as randomUUID13 } from "node:crypto";
|
|
37643
37705
|
function fallbackTitle(prompt) {
|
|
37644
37706
|
const firstLine2 = prompt.trim().split("\n", 1)[0].trim();
|
|
@@ -37678,12 +37740,12 @@ function resolveLegacyThreadFile(projectDir, value) {
|
|
|
37678
37740
|
const frizzStat = lstatSync3(frizzPath);
|
|
37679
37741
|
if (!frizzStat.isDirectory() || frizzStat.isSymbolicLink()) return null;
|
|
37680
37742
|
const realFrizz = realpathSync8(frizzPath);
|
|
37681
|
-
if (
|
|
37743
|
+
if (dirname13(realFrizz) !== projectRoot || basename6(realFrizz) !== ".frizz") return null;
|
|
37682
37744
|
const path3 = join31(realFrizz, `${parsed.data}.md`);
|
|
37683
37745
|
const before = lstatSync3(path3);
|
|
37684
37746
|
if (!before.isFile() || before.isSymbolicLink()) return null;
|
|
37685
37747
|
const realPath = realpathSync8(path3);
|
|
37686
|
-
if (
|
|
37748
|
+
if (dirname13(realPath) !== realFrizz || basename6(realPath) !== `${parsed.data}.md`) return null;
|
|
37687
37749
|
let contents;
|
|
37688
37750
|
let openedBefore;
|
|
37689
37751
|
let openedAfter;
|
|
@@ -37733,7 +37795,7 @@ function ensureSafeDirectDirectory(parent, name) {
|
|
|
37733
37795
|
const stat2 = lstatSync3(path3);
|
|
37734
37796
|
if (!stat2.isDirectory() || stat2.isSymbolicLink()) throw new Error("unsafe project directory");
|
|
37735
37797
|
const real = realpathSync8(path3);
|
|
37736
|
-
if (
|
|
37798
|
+
if (dirname13(real) !== parent || basename6(real) !== name) throw new Error("unsafe project directory");
|
|
37737
37799
|
return real;
|
|
37738
37800
|
}
|
|
37739
37801
|
function scratchDirRelPath(sessionId) {
|
|
@@ -37766,7 +37828,7 @@ function codexScratchpadHookConfig(hookScript, sessionId) {
|
|
|
37766
37828
|
}
|
|
37767
37829
|
]
|
|
37768
37830
|
});
|
|
37769
|
-
const bashBackgroundHook = join31(
|
|
37831
|
+
const bashBackgroundHook = join31(dirname13(hookScript), "bash-background.mjs");
|
|
37770
37832
|
return {
|
|
37771
37833
|
bypass_hook_trust: true,
|
|
37772
37834
|
hooks: {
|
|
@@ -38441,7 +38503,7 @@ import {
|
|
|
38441
38503
|
watch as fsWatch
|
|
38442
38504
|
} from "node:fs";
|
|
38443
38505
|
import { homedir as homedir14 } from "node:os";
|
|
38444
|
-
import { dirname as
|
|
38506
|
+
import { dirname as dirname14, join as join32 } from "node:path";
|
|
38445
38507
|
import watcher from "@parcel/watcher";
|
|
38446
38508
|
function appServerTurnStalled(liveness, lastActivityAt, nowMs) {
|
|
38447
38509
|
if (!liveness) return false;
|
|
@@ -38490,7 +38552,7 @@ function registeredLegacyFileIsTerminal(projectDir, slug) {
|
|
|
38490
38552
|
return status === "done" || status === "dismissed";
|
|
38491
38553
|
}
|
|
38492
38554
|
function isBoardRelevantFrizzPath(roots, path3) {
|
|
38493
|
-
return path3.endsWith(".md") && roots.has(
|
|
38555
|
+
return path3.endsWith(".md") && roots.has(dirname14(path3));
|
|
38494
38556
|
}
|
|
38495
38557
|
function futureSnooze(row, nowMs) {
|
|
38496
38558
|
const parsed = SnoozeUntil.safeParse(row.snoozed_until);
|
|
@@ -42307,7 +42369,7 @@ var init_claude = __esm({
|
|
|
42307
42369
|
|
|
42308
42370
|
// packages/server/src/backend/acp-transcript.ts
|
|
42309
42371
|
import { appendFileSync as appendFileSync3, existsSync as existsSync12, mkdirSync as mkdirSync14, readFileSync as readFileSync21 } from "node:fs";
|
|
42310
|
-
import { dirname as
|
|
42372
|
+
import { dirname as dirname15, join as join34 } from "node:path";
|
|
42311
42373
|
function acpTranscriptPath(stateDir, sessionId) {
|
|
42312
42374
|
return join34(stateDir, ACP_TRANSCRIPT_DIR, `${sessionId}.jsonl`);
|
|
42313
42375
|
}
|
|
@@ -42486,13 +42548,6 @@ function projectAcpTranscript(raw2, identityPrefix = "acp") {
|
|
|
42486
42548
|
}
|
|
42487
42549
|
return out;
|
|
42488
42550
|
}
|
|
42489
|
-
function readAcpTranscriptFile(absPath, nativeId = absPath) {
|
|
42490
|
-
try {
|
|
42491
|
-
return projectAcpTranscript(readFileSync21(absPath, "utf8"), `acp:${nativeId}`);
|
|
42492
|
-
} catch {
|
|
42493
|
-
return [];
|
|
42494
|
-
}
|
|
42495
|
-
}
|
|
42496
42551
|
var ACP_TRANSCRIPT_DIR, EVENT_KINDS, AcpTranscriptWriter, TOOL_TEXT_MAX;
|
|
42497
42552
|
var init_acp_transcript = __esm({
|
|
42498
42553
|
"packages/server/src/backend/acp-transcript.ts"() {
|
|
@@ -42517,7 +42572,7 @@ var init_acp_transcript = __esm({
|
|
|
42517
42572
|
AcpTranscriptWriter = class {
|
|
42518
42573
|
constructor(path3) {
|
|
42519
42574
|
this.path = path3;
|
|
42520
|
-
mkdirSync14(
|
|
42575
|
+
mkdirSync14(dirname15(path3), { recursive: true });
|
|
42521
42576
|
if (!existsSync12(path3)) appendFileSync3(path3, "");
|
|
42522
42577
|
}
|
|
42523
42578
|
append(record) {
|
|
@@ -43236,6 +43291,17 @@ var init_acp_bridge = __esm({
|
|
|
43236
43291
|
if (live.turn) live.conn.notify("session/cancel", { sessionId: live.acpSessionId });
|
|
43237
43292
|
void live.conn.close(reason === "shutdown" ? 1e3 : 3e3);
|
|
43238
43293
|
}
|
|
43294
|
+
/** Switch a LIVE session's model (`session/set_config_option`); `applied: false` when the session is
|
|
43295
|
+
* not open, in which case the caller's stored slug reaches the agent on the next open. A refusal is
|
|
43296
|
+
* written to the transcript as a note, exactly as on open, and still counts as applied: the agent
|
|
43297
|
+
* answered, and the note says what it runs on. */
|
|
43298
|
+
async setModel(threadSlug, sessionId, modelId) {
|
|
43299
|
+
const live = this.sessions.get(sessionId);
|
|
43300
|
+
if (!live || live.slug !== threadSlug || live.exited || live.conn.closed) return { applied: false };
|
|
43301
|
+
const problem = await this.applyModel(live, modelId);
|
|
43302
|
+
if (problem) live.writer.append({ kind: "acp-note", at: this.now(), text: problem });
|
|
43303
|
+
return { applied: true, ...live.model ? { model: live.model } : {} };
|
|
43304
|
+
}
|
|
43239
43305
|
turnLiveness(threadSlug, sessionId) {
|
|
43240
43306
|
const live = this.sessions.get(sessionId);
|
|
43241
43307
|
if (!live || live.slug !== threadSlug) return void 0;
|
|
@@ -43763,7 +43829,7 @@ var init_stale_socket_sweep = __esm({
|
|
|
43763
43829
|
// packages/server/src/orphan-reaper.ts
|
|
43764
43830
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
43765
43831
|
import { readFileSync as readFileSync22 } from "node:fs";
|
|
43766
|
-
import { dirname as
|
|
43832
|
+
import { dirname as dirname16 } from "node:path";
|
|
43767
43833
|
function firstTokenBasename(command) {
|
|
43768
43834
|
const first = command.trimStart().split(/\s+/, 1)[0] ?? "";
|
|
43769
43835
|
const slash = first.lastIndexOf("/");
|
|
@@ -43991,7 +44057,7 @@ function sweepOrphansOnce(deps = {}) {
|
|
|
43991
44057
|
}
|
|
43992
44058
|
function sweepStaleBrokerSockets() {
|
|
43993
44059
|
try {
|
|
43994
|
-
sweepStaleSockets({ dir:
|
|
44060
|
+
sweepStaleSockets({ dir: dirname16(claudeBrokerSocketPath("", "")), prefix: CLAUDE_BROKER_SOCKET_PREFIX });
|
|
43995
44061
|
} catch {
|
|
43996
44062
|
}
|
|
43997
44063
|
}
|
|
@@ -47435,7 +47501,7 @@ var init_server = __esm({
|
|
|
47435
47501
|
|
|
47436
47502
|
// packages/server/src/repair.ts
|
|
47437
47503
|
import { existsSync as existsSync13, readFileSync as readFileSync23, writeFileSync as writeFileSync11 } from "node:fs";
|
|
47438
|
-
import { basename as basename7, dirname as
|
|
47504
|
+
import { basename as basename7, dirname as dirname17, resolve as resolve8 } from "node:path";
|
|
47439
47505
|
function quoteValue(v) {
|
|
47440
47506
|
if (/^[\w./#:+-]+$/.test(v)) return v;
|
|
47441
47507
|
return `"${v.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
@@ -47447,7 +47513,7 @@ function deriveTitle(body, slug) {
|
|
|
47447
47513
|
function repairThreadFile(frizzDir, file) {
|
|
47448
47514
|
const root = resolve8(frizzDir);
|
|
47449
47515
|
const abs = resolve8(root, file);
|
|
47450
|
-
if (
|
|
47516
|
+
if (dirname17(abs) !== root) throw new RepairError(`refusing to repair "${file}": not directly under .frizz/`);
|
|
47451
47517
|
if (!abs.endsWith(".md")) throw new RepairError(`refusing to repair "${file}": not a .md thread file`);
|
|
47452
47518
|
if (!existsSync13(abs)) throw new RepairError(`no thread file to repair: ${basename7(abs)}`);
|
|
47453
47519
|
const content = readFileSync23(abs, "utf8");
|
|
@@ -49217,6 +49283,17 @@ function parseCodexTranscript(raw2, identityPrefix = "codex") {
|
|
|
49217
49283
|
return latestTranscriptWindow(out);
|
|
49218
49284
|
}
|
|
49219
49285
|
function latestWindowStart(messages) {
|
|
49286
|
+
return byteBoundedStart(messages, countBoundedStart(messages));
|
|
49287
|
+
}
|
|
49288
|
+
function byteBoundedStart(messages, start) {
|
|
49289
|
+
let bytes = 0;
|
|
49290
|
+
for (let i = messages.length - 1; i >= start; i--) {
|
|
49291
|
+
bytes += messageBytes(messages[i]);
|
|
49292
|
+
if (bytes > LATEST_WINDOW_MAX_BYTES) return Math.min(i + 1, messages.length - 1);
|
|
49293
|
+
}
|
|
49294
|
+
return start;
|
|
49295
|
+
}
|
|
49296
|
+
function countBoundedStart(messages) {
|
|
49220
49297
|
const tail = Math.max(0, messages.length - MAX_MESSAGES);
|
|
49221
49298
|
if (tail === 0) return 0;
|
|
49222
49299
|
let boundary = -1;
|
|
@@ -50177,7 +50254,7 @@ function emptyTranscriptPage(source) {
|
|
|
50177
50254
|
editedFiles: []
|
|
50178
50255
|
};
|
|
50179
50256
|
}
|
|
50180
|
-
function readLatestThreadTranscriptPage(project, storage, slug, backendFor) {
|
|
50257
|
+
function readLatestThreadTranscriptPage(project, storage, slug, backendFor, opts = {}) {
|
|
50181
50258
|
let source = sourceForThread(project, storage, slug, backendFor);
|
|
50182
50259
|
if (!source) return emptyTranscriptPage();
|
|
50183
50260
|
let snapshot = fixedSnapshot(source);
|
|
@@ -50213,7 +50290,7 @@ function readLatestThreadTranscriptPage(project, storage, slug, backendFor) {
|
|
|
50213
50290
|
// ones inside this checkout belong on the rail (edited-files.ts). Then git drops whatever the
|
|
50214
50291
|
// repository would not carry — scratch, build output — leaving the rail an account of repo work
|
|
50215
50292
|
// (repo-files.ts).
|
|
50216
|
-
editedFiles: repoCarriedEditedFiles(project.dir, editedFilesOf(projected, project.dir))
|
|
50293
|
+
...opts.editedFiles === false ? {} : { editedFiles: repoCarriedEditedFiles(project.dir, editedFilesOf(projected, project.dir)) }
|
|
50217
50294
|
};
|
|
50218
50295
|
}
|
|
50219
50296
|
function readEarlierThreadTranscriptPage(project, storage, slug, cursor, backendFor) {
|
|
@@ -50252,41 +50329,6 @@ function readCodexTranscriptFile(absPath, nativeId = absPath) {
|
|
|
50252
50329
|
return [];
|
|
50253
50330
|
}
|
|
50254
50331
|
}
|
|
50255
|
-
function readThreadTranscript(project, storage, slug, backendFor) {
|
|
50256
|
-
const row = storage.getSession(slug);
|
|
50257
|
-
if (row) {
|
|
50258
|
-
if (row.backend === "acp") {
|
|
50259
|
-
const path3 = backendFor?.("acp")?.transcriptPath(row.session_id);
|
|
50260
|
-
const acpLedger = parseDeliveryLedger(row.delivery_ledger);
|
|
50261
|
-
return projectDeliveryLedger(path3 ? readAcpTranscriptFile(path3, row.session_id) : [], acpLedger);
|
|
50262
|
-
}
|
|
50263
|
-
if (row.backend === "codex") {
|
|
50264
|
-
const backend = backendFor?.("codex") ?? defaultCodexBackend();
|
|
50265
|
-
const nativeId = row.agent_session_id ?? row.session_id;
|
|
50266
|
-
const path3 = backend.transcriptPath(nativeId);
|
|
50267
|
-
const codexLedger = parseDeliveryLedger(row.delivery_ledger);
|
|
50268
|
-
return projectDeliveryLedger(path3 ? readCodexTranscriptFile(path3, nativeId) : [], codexLedger);
|
|
50269
|
-
}
|
|
50270
|
-
const ledger = parseDeliveryLedger(row.delivery_ledger);
|
|
50271
|
-
const msgs = readTranscript(project, row.transcript_id ?? row.session_id);
|
|
50272
|
-
if (msgs.length || row.transcript_id) return projectDeliveryLedger(msgs, ledger);
|
|
50273
|
-
if (Date.now() - Date.parse(row.spawned_at) < DISCOVERY_GRACE_MS) return projectDeliveryLedger(msgs, ledger);
|
|
50274
|
-
const exclude = /* @__PURE__ */ new Set();
|
|
50275
|
-
for (const r of storage.allSessions()) {
|
|
50276
|
-
if (r.slug === row.slug) continue;
|
|
50277
|
-
exclude.add(r.session_id);
|
|
50278
|
-
if (r.transcript_id) exclude.add(r.transcript_id);
|
|
50279
|
-
}
|
|
50280
|
-
const found = discoverTranscriptId(logDirOf(project), row.session_id, { exclude });
|
|
50281
|
-
return projectDeliveryLedger(found ? readTranscript(project, found) : msgs, ledger);
|
|
50282
|
-
}
|
|
50283
|
-
if (FOREIGN_SESSION_ID_RE.test(slug)) {
|
|
50284
|
-
const source = sourceForThread(project, storage, slug, backendFor);
|
|
50285
|
-
if (!source) return [];
|
|
50286
|
-
return source.backend === "codex" ? readCodexTranscriptFile(source.path, slug) : readTranscript(project, slug);
|
|
50287
|
-
}
|
|
50288
|
-
return [];
|
|
50289
|
-
}
|
|
50290
50332
|
function projectTranscriptAgentLifecycles(messages, lookup) {
|
|
50291
50333
|
const cache2 = /* @__PURE__ */ new Map();
|
|
50292
50334
|
const projectTool = (tool) => {
|
|
@@ -50355,7 +50397,7 @@ function readTranscriptFile(absPath) {
|
|
|
50355
50397
|
return [];
|
|
50356
50398
|
}
|
|
50357
50399
|
}
|
|
50358
|
-
var MAX_MESSAGES, LATEST_WINDOW_ASK_REACH_ITEMS, LATEST_WINDOW_ASK_REACH_BYTES, REST_LABEL, LEGACY_TASK_MARKER, LEGACY_BANNER_PREAMBLE, COMMAND_NAME_RE, COMMAND_ARGS_RE, PEER_SESSION_PREAMBLE, CLAUDE_COORDINATOR_INSTRUCTION_PREFIX, CLAUDE_COORDINATOR_INSTRUCTION_SUFFIX, CLAUDE_PEER_INSTRUCTION_PREFIX, QUEUED_STALE_MS, EDIT_CAP, TRUNC_MARKER, ENCRYPTED_PAYLOAD, AGENT_PROMPT_CAP, SEND_BODY_CAP, COMMAND_CAP, TOOL_INPUT_CAP, READ_LINE_CAP, READ_BYTE_CAP, IMAGE_MEDIA_EXT, SCREENSHOT_CACHE_DIR, SCREENSHOT_CACHE_MAX, SCREENSHOT_MAX_BASE64, screenshotTmpSeq, SENT_IMAGE_MAX_BYTES, SENT_FILES_MAX, TODO_ROWS_MAX, TODO_TEXT_CAP, TRANSCRIPT_CACHE_CAP, transcriptCache, PARSE_VERIFY_SAMPLE, TRANSCRIPT_DECODE_WINDOW, FOREIGN_SESSION_ID_RE, MAX_PINNED_BACKGROUND_OPERATIONS, CAPTION_MAX, _defaultCodexBackend, TRANSCRIPT_EARLIER_MAX_ITEMS, TRANSCRIPT_EARLIER_MAX_BYTES, fullDigestCache, FULL_DIGEST_CACHE_CAP, EMPTY_RETIRED_OPS;
|
|
50400
|
+
var MAX_MESSAGES, LATEST_WINDOW_ASK_REACH_ITEMS, LATEST_WINDOW_ASK_REACH_BYTES, LATEST_WINDOW_MAX_BYTES, REST_LABEL, LEGACY_TASK_MARKER, LEGACY_BANNER_PREAMBLE, COMMAND_NAME_RE, COMMAND_ARGS_RE, PEER_SESSION_PREAMBLE, CLAUDE_COORDINATOR_INSTRUCTION_PREFIX, CLAUDE_COORDINATOR_INSTRUCTION_SUFFIX, CLAUDE_PEER_INSTRUCTION_PREFIX, QUEUED_STALE_MS, EDIT_CAP, TRUNC_MARKER, ENCRYPTED_PAYLOAD, AGENT_PROMPT_CAP, SEND_BODY_CAP, COMMAND_CAP, TOOL_INPUT_CAP, READ_LINE_CAP, READ_BYTE_CAP, IMAGE_MEDIA_EXT, SCREENSHOT_CACHE_DIR, SCREENSHOT_CACHE_MAX, SCREENSHOT_MAX_BASE64, screenshotTmpSeq, SENT_IMAGE_MAX_BYTES, SENT_FILES_MAX, TODO_ROWS_MAX, TODO_TEXT_CAP, TRANSCRIPT_CACHE_CAP, transcriptCache, PARSE_VERIFY_SAMPLE, TRANSCRIPT_DECODE_WINDOW, FOREIGN_SESSION_ID_RE, MAX_PINNED_BACKGROUND_OPERATIONS, CAPTION_MAX, _defaultCodexBackend, TRANSCRIPT_EARLIER_MAX_ITEMS, TRANSCRIPT_EARLIER_MAX_BYTES, fullDigestCache, FULL_DIGEST_CACHE_CAP, EMPTY_RETIRED_OPS;
|
|
50359
50401
|
var init_transcript = __esm({
|
|
50360
50402
|
"packages/server/src/transcript.ts"() {
|
|
50361
50403
|
"use strict";
|
|
@@ -50376,6 +50418,7 @@ var init_transcript = __esm({
|
|
|
50376
50418
|
MAX_MESSAGES = 300;
|
|
50377
50419
|
LATEST_WINDOW_ASK_REACH_ITEMS = 100;
|
|
50378
50420
|
LATEST_WINDOW_ASK_REACH_BYTES = 512 * 1024;
|
|
50421
|
+
LATEST_WINDOW_MAX_BYTES = 3 * 1024 * 1024;
|
|
50379
50422
|
REST_LABEL = "Agent rested";
|
|
50380
50423
|
LEGACY_TASK_MARKER = "\nTASK:\n";
|
|
50381
50424
|
LEGACY_BANNER_PREAMBLE = "Everything ABOVE this line is frizz system orientation. Everything BELOW the `TASK:` marker is the human operator's own prompt, verbatim.";
|
|
@@ -51151,7 +51194,7 @@ var init_directory_picker = __esm({
|
|
|
51151
51194
|
import { readFileSync as readFileSync26, statSync as statSync19 } from "node:fs";
|
|
51152
51195
|
import { join as join39, resolve as resolve9 } from "node:path";
|
|
51153
51196
|
import { randomUUID as randomUUID16 } from "node:crypto";
|
|
51154
|
-
import { basename as basename9, dirname as
|
|
51197
|
+
import { basename as basename9, dirname as dirname18 } from "node:path";
|
|
51155
51198
|
import { existsSync as existsSync15, mkdirSync as mkdirSync17, rmSync as rmSync10, writeFileSync as writeFileSync13 } from "node:fs";
|
|
51156
51199
|
import { homedir as homedir17 } from "node:os";
|
|
51157
51200
|
function validateGithubDispatchProfile(input) {
|
|
@@ -51351,7 +51394,7 @@ function storeProjectIcon(id, name, bytes) {
|
|
|
51351
51394
|
if (!entry) throw new Error("No such project.");
|
|
51352
51395
|
if (bytes.length === 0) throw new Error("That file is empty.");
|
|
51353
51396
|
const path3 = customIconPath(id, `.${extension2}`);
|
|
51354
|
-
mkdirSync17(
|
|
51397
|
+
mkdirSync17(dirname18(path3), { recursive: true });
|
|
51355
51398
|
writeFileSync13(path3, bytes);
|
|
51356
51399
|
if (!imageDimensions(path3)) {
|
|
51357
51400
|
rmSync10(path3, { force: true });
|
|
@@ -52304,7 +52347,16 @@ ${gapNote}` : input.message;
|
|
|
52304
52347
|
const thread = (await ctx.board.snapshot()).threads.find((candidate) => candidate.id === input.slug);
|
|
52305
52348
|
if (!thread || thread.foreign || thread.kind !== "session") throw new Error(`thread ${input.slug} is not editable`);
|
|
52306
52349
|
const profRow = ctx.storage.getSession(input.slug);
|
|
52307
|
-
if (profRow?.backend === "acp")
|
|
52350
|
+
if (profRow?.backend === "acp") {
|
|
52351
|
+
if (acpAgentIdFromModel(input.model) !== acpAgentIdFromModel(profRow.model ?? "")) {
|
|
52352
|
+
throw new Error("An ACP thread's agent cannot change; pick a model of the same agent");
|
|
52353
|
+
}
|
|
52354
|
+
ctx.storage.setProfile(input.slug, input.model, "");
|
|
52355
|
+
const live = ctx.acpBridge ? await ctx.acpBridge.setModel(input.slug, profRow.session_id, acpModelIdFromModel(input.model)) : { applied: false };
|
|
52356
|
+
ctx.board.refresh();
|
|
52357
|
+
return { effect: live.applied ? "applied" : "next-resume" };
|
|
52358
|
+
}
|
|
52359
|
+
if (!input.effort) throw new Error(`effort is required for a ${profRow?.backend ?? "claude"} thread`);
|
|
52308
52360
|
if (profRow?.backend === "codex") {
|
|
52309
52361
|
ctx.storage.setProfile(input.slug, input.model, input.effort);
|
|
52310
52362
|
ctx.board.refresh();
|
|
@@ -53448,6 +53500,47 @@ Say which way you went and why in your write-up, so the human can course-correct
|
|
|
53448
53500
|
return projectCard(updated, !existsSync15(updated.path));
|
|
53449
53501
|
}
|
|
53450
53502
|
}),
|
|
53503
|
+
/**
|
|
53504
|
+
* Rename a project — the name Frizz shows and the URL it answers on, and, only when asked, the
|
|
53505
|
+
* folder itself.
|
|
53506
|
+
*
|
|
53507
|
+
* The name is the registry's display override, cleared again when it matches the folder so the
|
|
53508
|
+
* card keeps following a later `mv`. The slug follows the name on purpose: a rename is the one
|
|
53509
|
+
* time an operator has said what this project is called, and `deriveSlug`'s never-re-derive rule
|
|
53510
|
+
* exists to protect bookmarks from SILENT changes, not from this one. A taken or reserved slug is
|
|
53511
|
+
* refused with the registry's own message, and nothing is written.
|
|
53512
|
+
*
|
|
53513
|
+
* `renameDirectory` is opt-in and the dialog only offers it when the folder is already named after
|
|
53514
|
+
* the project (maintainer 2026-09-18: "without actually changing the directory name by default").
|
|
53515
|
+
* It moves the folder to a sibling of the same name and re-registers the id there, then closes
|
|
53516
|
+
* the tenant so the next request reopens it at the new path — a context built on the old one
|
|
53517
|
+
* would spawn every worker into a directory that no longer exists. The launching project is
|
|
53518
|
+
* refused for the same reason `projectRemove` refuses it: this process is standing in it.
|
|
53519
|
+
*/
|
|
53520
|
+
projectRename: mutation({
|
|
53521
|
+
input: external_exports.object({
|
|
53522
|
+
id: external_exports.string().min(1),
|
|
53523
|
+
name: external_exports.string().trim().min(1).max(120),
|
|
53524
|
+
renameDirectory: external_exports.boolean().optional()
|
|
53525
|
+
}).strict(),
|
|
53526
|
+
output: ProjectCard,
|
|
53527
|
+
handler: async ({ input }) => {
|
|
53528
|
+
const entry = findById(input.id);
|
|
53529
|
+
if (!entry) throw new Error("No such project.");
|
|
53530
|
+
const name = input.name.trim();
|
|
53531
|
+
let path3 = entry.path;
|
|
53532
|
+
if (input.renameDirectory && name !== basename9(entry.path)) {
|
|
53533
|
+
if (ctx.launchProjectId === entry.id) {
|
|
53534
|
+
throw new Error("Frizz is serving from this project, so its folder cannot be renamed. Restart Frizz from another folder first.");
|
|
53535
|
+
}
|
|
53536
|
+
path3 = moveProjectDirectory(entry.id, name).path;
|
|
53537
|
+
await ctx.teardownProject?.(entry.id, {});
|
|
53538
|
+
}
|
|
53539
|
+
const updated = renameProject(entry.id, { name: name === basename9(path3) ? null : name, slug: name });
|
|
53540
|
+
if (!updated) throw new Error("No such project.");
|
|
53541
|
+
return projectCard(updated, !existsSync15(updated.path));
|
|
53542
|
+
}
|
|
53543
|
+
}),
|
|
53451
53544
|
/**
|
|
53452
53545
|
* Open the machine's own folder picker, and add whatever comes back.
|
|
53453
53546
|
*
|
|
@@ -53865,6 +53958,7 @@ var init_compression = __esm({
|
|
|
53865
53958
|
import { readFileSync as readFileSync27, realpathSync as realpathSync11, statSync as statSync20 } from "node:fs";
|
|
53866
53959
|
import { extname as extname2, isAbsolute as isAbsolute7 } from "node:path";
|
|
53867
53960
|
function resolveLocalImage(rawPath) {
|
|
53961
|
+
if (rawPath) rawPath = normalizeLocalPath(rawPath);
|
|
53868
53962
|
if (!rawPath || !isAbsolute7(rawPath)) return { status: 400 };
|
|
53869
53963
|
const contentType = IMAGE_CONTENT_TYPE[extname2(rawPath).toLowerCase()];
|
|
53870
53964
|
if (!contentType) return { status: 400 };
|
|
@@ -53885,6 +53979,7 @@ var IMAGE_CONTENT_TYPE;
|
|
|
53885
53979
|
var init_local_image = __esm({
|
|
53886
53980
|
"packages/server/src/local-image.ts"() {
|
|
53887
53981
|
"use strict";
|
|
53982
|
+
init_local_path();
|
|
53888
53983
|
IMAGE_CONTENT_TYPE = {
|
|
53889
53984
|
".png": "image/png",
|
|
53890
53985
|
".jpg": "image/jpeg",
|
|
@@ -53898,7 +53993,7 @@ var init_local_image = __esm({
|
|
|
53898
53993
|
// packages/server/src/project-icon.ts
|
|
53899
53994
|
import { readFileSync as readFileSync28, readdirSync as readdirSync10, realpathSync as realpathSync12, statSync as statSync21 } from "node:fs";
|
|
53900
53995
|
import { homedir as homedir18 } from "node:os";
|
|
53901
|
-
import { basename as basename10, dirname as
|
|
53996
|
+
import { basename as basename10, dirname as dirname19, extname as extname3, join as join40, relative as relative2, sep as sep3 } from "node:path";
|
|
53902
53997
|
function normalizeStem(stem) {
|
|
53903
53998
|
const sized = stem.toLowerCase().replace(/[@-]\d+(\.\d+)?x(\d+)?$/u, "").replace(/[-_]\d{2,4}$/u, "");
|
|
53904
53999
|
const normalized = sized.replace(VARIANT_SUFFIX, "");
|
|
@@ -53963,7 +54058,7 @@ function manifestIcons(manifestPath) {
|
|
|
53963
54058
|
return [];
|
|
53964
54059
|
}
|
|
53965
54060
|
if (!Array.isArray(parsed?.icons)) return [];
|
|
53966
|
-
const directory =
|
|
54061
|
+
const directory = dirname19(manifestPath);
|
|
53967
54062
|
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) => join40(directory, src.replace(/[?#].*$/u, "").replace(/^\//u, "")));
|
|
53968
54063
|
}
|
|
53969
54064
|
function projectIconCandidates(root) {
|
|
@@ -53986,7 +54081,7 @@ function projectIconCandidates(root) {
|
|
|
53986
54081
|
for (const icon of manifestIcons(join40(directory, name))) {
|
|
53987
54082
|
if (MEASURABLE_IMAGE_EXTENSIONS.has(extname3(icon).toLowerCase())) {
|
|
53988
54083
|
fromManifest.add(icon);
|
|
53989
|
-
files.push({ path: icon, directory:
|
|
54084
|
+
files.push({ path: icon, directory: dirname19(icon) });
|
|
53990
54085
|
}
|
|
53991
54086
|
}
|
|
53992
54087
|
continue;
|
|
@@ -54902,10 +54997,19 @@ function isWsPath(url) {
|
|
|
54902
54997
|
}
|
|
54903
54998
|
function makeTranscriptReader(project, storage, backendFor, lifecycleFor, peerNameFor, ownerGone) {
|
|
54904
54999
|
return (slug) => {
|
|
54905
|
-
const
|
|
54906
|
-
const named = peerNameFor ? projectTranscriptPeerNames(messages, (taskId) => peerNameFor(slug, taskId)) : messages;
|
|
55000
|
+
const page = readLatestThreadTranscriptPage(project, storage, slug, backendFor, { editedFiles: false });
|
|
55001
|
+
const named = peerNameFor ? projectTranscriptPeerNames(page.messages, (taskId) => peerNameFor(slug, taskId)) : page.messages;
|
|
54907
55002
|
const projected = lifecycleFor ? projectTranscriptAgentLifecycles(named, (id) => lifecycleFor(slug, id)) : named;
|
|
54908
|
-
|
|
55003
|
+
const messages = projectRetiredBackgroundOps(projected, retiredOpsFor(storage, slug), ownerGone?.(slug) ?? false);
|
|
55004
|
+
return {
|
|
55005
|
+
messages,
|
|
55006
|
+
page: {
|
|
55007
|
+
beforeCursor: page.beforeCursor,
|
|
55008
|
+
hasEarlier: page.hasEarlier,
|
|
55009
|
+
reachedTurnBoundary: page.reachedTurnBoundary,
|
|
55010
|
+
transcriptKey: page.transcriptKey
|
|
55011
|
+
}
|
|
55012
|
+
};
|
|
54909
55013
|
};
|
|
54910
55014
|
}
|
|
54911
55015
|
function createAppSocketServer(deps) {
|
|
@@ -55186,9 +55290,9 @@ function createAppSocketServer(deps) {
|
|
|
55186
55290
|
if (cached2) return { kind: "ready", snapshot: cached2 };
|
|
55187
55291
|
const reservation = reserveTranscriptRead(origin);
|
|
55188
55292
|
if (reservation.kind === "limited") return reservation;
|
|
55189
|
-
const
|
|
55190
|
-
if (!
|
|
55191
|
-
const frame = encodeMsg({ t: "transcript", slug, messages });
|
|
55293
|
+
const read = readTranscript2(slug);
|
|
55294
|
+
if (!read) return { kind: "unavailable" };
|
|
55295
|
+
const frame = encodeMsg(read.page ? { t: "transcript", slug, messages: read.messages, page: read.page } : { t: "transcript", slug, messages: read.messages });
|
|
55192
55296
|
if (!frame) return { kind: "unavailable" };
|
|
55193
55297
|
if (frame.bytes > maxLogicalFrameBytes) return { kind: "oversized", actualBytes: frame.bytes };
|
|
55194
55298
|
const snapshot = { frame, sig: frameSignature(frame), weight: snapshotWeight(frame) };
|
|
@@ -55749,7 +55853,7 @@ var init_app_socket = __esm({
|
|
|
55749
55853
|
|
|
55750
55854
|
// packages/server/src/local-file-watch.ts
|
|
55751
55855
|
import { statSync as statSync23, watch } from "node:fs";
|
|
55752
|
-
import { basename as basename11, dirname as
|
|
55856
|
+
import { basename as basename11, dirname as dirname20 } from "node:path";
|
|
55753
55857
|
function stampOf(path3) {
|
|
55754
55858
|
try {
|
|
55755
55859
|
const s = statSync23(path3, { bigint: true });
|
|
@@ -55772,7 +55876,7 @@ function watchLocalFile(path3, onChange) {
|
|
|
55772
55876
|
let entry = entries.get(path3);
|
|
55773
55877
|
if (!entry) {
|
|
55774
55878
|
const name = basename11(path3);
|
|
55775
|
-
const watcher2 = watch(
|
|
55879
|
+
const watcher2 = watch(dirname20(path3), { persistent: false }, (_event, changed) => {
|
|
55776
55880
|
if (changed !== null && changed !== void 0 && changed.toString() !== name) return;
|
|
55777
55881
|
const current = entries.get(path3);
|
|
55778
55882
|
if (!current) return;
|
|
@@ -55809,7 +55913,7 @@ var init_local_file_watch = __esm({
|
|
|
55809
55913
|
|
|
55810
55914
|
// packages/server/src/boot-progress.ts
|
|
55811
55915
|
import { mkdirSync as mkdirSync19, readFileSync as readFileSync30, renameSync as renameSync10, rmSync as rmSync11, writeFileSync as writeFileSync15 } from "node:fs";
|
|
55812
|
-
import { basename as basename12, dirname as
|
|
55916
|
+
import { basename as basename12, dirname as dirname21, join as join43 } from "node:path";
|
|
55813
55917
|
function bootProgressPath(stateDir) {
|
|
55814
55918
|
return join43(stateDir, BOOT_PROGRESS_NAME);
|
|
55815
55919
|
}
|
|
@@ -55831,8 +55935,8 @@ function createBootProgressPublisher(stateDir, minIntervalMs = 200) {
|
|
|
55831
55935
|
lastAt = now;
|
|
55832
55936
|
step++;
|
|
55833
55937
|
try {
|
|
55834
|
-
mkdirSync19(
|
|
55835
|
-
const temp = join43(
|
|
55938
|
+
mkdirSync19(dirname21(path3), { recursive: true, mode: 448 });
|
|
55939
|
+
const temp = join43(dirname21(path3), `.${basename12(path3)}.${process.pid}.tmp`);
|
|
55836
55940
|
writeFileSync15(temp, `${JSON.stringify({ pid: process.pid, step, phase, at: new Date(now).toISOString() })}
|
|
55837
55941
|
`, "utf8");
|
|
55838
55942
|
renameSync10(temp, path3);
|
|
@@ -55859,12 +55963,12 @@ var init_boot_progress = __esm({
|
|
|
55859
55963
|
|
|
55860
55964
|
// packages/server/src/runtime-lease.ts
|
|
55861
55965
|
import { existsSync as existsSync16, mkdirSync as mkdirSync20, readdirSync as readdirSync12, readFileSync as readFileSync31, unlinkSync as unlinkSync6, writeFileSync as writeFileSync16 } from "node:fs";
|
|
55862
|
-
import { dirname as
|
|
55966
|
+
import { dirname as dirname22, join as join44 } from "node:path";
|
|
55863
55967
|
function runtimeVersionDir(bin) {
|
|
55864
|
-
let dir =
|
|
55968
|
+
let dir = dirname22(bin);
|
|
55865
55969
|
for (let step = 0; step < MAX_ASCENT; step++) {
|
|
55866
55970
|
if (existsSync16(join44(dir, PROVISIONED_MARKER))) return dir;
|
|
55867
|
-
const parent =
|
|
55971
|
+
const parent = dirname22(dir);
|
|
55868
55972
|
if (parent === dir) return void 0;
|
|
55869
55973
|
dir = parent;
|
|
55870
55974
|
}
|
|
@@ -55884,7 +55988,7 @@ function leaseRuntime(bin, role) {
|
|
|
55884
55988
|
};
|
|
55885
55989
|
const path3 = join44(versionDir, LEASES_DIR, `${process.pid}.json`);
|
|
55886
55990
|
try {
|
|
55887
|
-
mkdirSync20(
|
|
55991
|
+
mkdirSync20(dirname22(path3), { recursive: true });
|
|
55888
55992
|
const lease = { pid: process.pid, role, bin, at: (/* @__PURE__ */ new Date()).toISOString() };
|
|
55889
55993
|
writeFileSync16(path3, JSON.stringify(lease));
|
|
55890
55994
|
} catch {
|
|
@@ -55954,7 +56058,7 @@ import {
|
|
|
55954
56058
|
writeFileSync as writeFileSync17,
|
|
55955
56059
|
writeSync as writeSync2
|
|
55956
56060
|
} from "node:fs";
|
|
55957
|
-
import { dirname as
|
|
56061
|
+
import { dirname as dirname23, isAbsolute as isAbsolute8, join as join45, normalize, relative as relative3, sep as sep5 } from "node:path";
|
|
55958
56062
|
import { Readable, Transform, Writable as Writable3 } from "node:stream";
|
|
55959
56063
|
import { pipeline } from "node:stream/promises";
|
|
55960
56064
|
import { createGunzip } from "node:zlib";
|
|
@@ -56215,8 +56319,8 @@ var init_runtimes = __esm({
|
|
|
56215
56319
|
init_codex_app_server();
|
|
56216
56320
|
init_frizz_paths();
|
|
56217
56321
|
init_runtime_lease();
|
|
56218
|
-
CLAUDE_AGENT_SDK_VERSION = "0.3.
|
|
56219
|
-
CLAUDE_CODE_VERSION = "2.1.
|
|
56322
|
+
CLAUDE_AGENT_SDK_VERSION = "0.3.275";
|
|
56323
|
+
CLAUDE_CODE_VERSION = "2.1.275";
|
|
56220
56324
|
CODEX_VERSION = CODEX_APP_SERVER_SUPPORTED_VERSION;
|
|
56221
56325
|
RUNTIMES_MODE_ENV = "FRIZZ_RUNTIMES";
|
|
56222
56326
|
RUNTIMES_DIR_ENV = "FRIZZ_RUNTIMES_DIR";
|
|
@@ -56313,7 +56417,7 @@ var init_runtimes = __esm({
|
|
|
56313
56417
|
case "7": {
|
|
56314
56418
|
const file = safeEntryPath(this.dest, name);
|
|
56315
56419
|
if (!file) return;
|
|
56316
|
-
mkdirSync21(
|
|
56420
|
+
mkdirSync21(dirname23(file), { recursive: true });
|
|
56317
56421
|
this.fd = openSync17(file, "w", octal(header, 100, 8) & 511 || 420);
|
|
56318
56422
|
this.written.push(file);
|
|
56319
56423
|
return;
|
|
@@ -56372,11 +56476,15 @@ function createTenantMap(options) {
|
|
|
56372
56476
|
};
|
|
56373
56477
|
async function activate(project) {
|
|
56374
56478
|
const already = open.get(project.id);
|
|
56375
|
-
if (already) return already.ctx;
|
|
56479
|
+
if (already && already.project.dir === project.dir) return already.ctx;
|
|
56376
56480
|
const inFlight = opening.get(project.id);
|
|
56377
56481
|
if (inFlight) return inFlight;
|
|
56378
56482
|
const attempt = (async () => {
|
|
56379
56483
|
try {
|
|
56484
|
+
if (already) {
|
|
56485
|
+
log.info("tenants", `project ${project.name} (${project.id}) moved from ${already.project.dir} to ${project.dir}; reopening it there`);
|
|
56486
|
+
await deactivate(project.id);
|
|
56487
|
+
}
|
|
56380
56488
|
const ctx = await options.createContext({ ...options.contextOptions, project });
|
|
56381
56489
|
open.set(project.id, { project, ctx, app: options.createApp?.(ctx) });
|
|
56382
56490
|
await options.startProducers?.(ctx);
|
|
@@ -56891,12 +56999,12 @@ var init_legacy_project_db = __esm({
|
|
|
56891
56999
|
|
|
56892
57000
|
// packages/server/src/frizz-db.ts
|
|
56893
57001
|
import { existsSync as existsSync18, mkdirSync as mkdirSync22, readdirSync as readdirSync14, renameSync as renameSync12, statSync as statSync25 } from "node:fs";
|
|
56894
|
-
import { basename as basename13, dirname as
|
|
57002
|
+
import { basename as basename13, dirname as dirname24, join as join46 } from "node:path";
|
|
56895
57003
|
function frizzDatabaseLocation(options) {
|
|
56896
57004
|
if (options.stateDir !== void 0) {
|
|
56897
|
-
const projectsDir =
|
|
57005
|
+
const projectsDir = dirname24(options.stateDir);
|
|
56898
57006
|
if (basename13(projectsDir) === "projects") {
|
|
56899
|
-
return { path: options.path ?? join46(
|
|
57007
|
+
return { path: options.path ?? join46(dirname24(projectsDir), "ui.db"), projectsDir };
|
|
56900
57008
|
}
|
|
56901
57009
|
return { path: options.path ?? join46(options.stateDir, "ui.db"), projectsDir: void 0 };
|
|
56902
57010
|
}
|
|
@@ -56920,7 +57028,7 @@ function ensureFrizzSchema(db) {
|
|
|
56920
57028
|
}
|
|
56921
57029
|
function openFrizzDatabase(options = {}) {
|
|
56922
57030
|
const { path: path3, projectsDir } = frizzDatabaseLocation(options);
|
|
56923
|
-
mkdirSync22(
|
|
57031
|
+
mkdirSync22(dirname24(path3), { recursive: true });
|
|
56924
57032
|
const db = new sqlite_default(path3);
|
|
56925
57033
|
db.pragma("busy_timeout = 5000");
|
|
56926
57034
|
db.pragma("journal_mode = WAL");
|
|
@@ -57144,7 +57252,7 @@ var init_tenant_prime = __esm({
|
|
|
57144
57252
|
// packages/server/src/project-teardown.ts
|
|
57145
57253
|
import { rmSync as rmSync13 } from "node:fs";
|
|
57146
57254
|
import { homedir as homedir19 } from "node:os";
|
|
57147
|
-
import { dirname as
|
|
57255
|
+
import { dirname as dirname25, resolve as resolve10 } from "node:path";
|
|
57148
57256
|
async function stopProjectWorkers(ctx) {
|
|
57149
57257
|
let stopped = 0;
|
|
57150
57258
|
for (const row of ctx.storage.allSessions()) {
|
|
@@ -57164,7 +57272,7 @@ function deleteProjectState(projectId, home = homedir19()) {
|
|
|
57164
57272
|
if (!/^[\w.-]+$/u.test(projectId) || projectId === "." || projectId === "..") {
|
|
57165
57273
|
throw new Error(`Refusing to delete state for a malformed project id: ${projectId}`);
|
|
57166
57274
|
}
|
|
57167
|
-
if (
|
|
57275
|
+
if (dirname25(resolve10(target)) !== resolve10(dirname25(projectStateDir("x", home)))) {
|
|
57168
57276
|
throw new Error(`Refusing to delete ${target} \u2014 it is not a project state directory`);
|
|
57169
57277
|
}
|
|
57170
57278
|
rmSync13(target, { recursive: true, force: true });
|
|
@@ -57194,7 +57302,7 @@ __export(index_exports, {
|
|
|
57194
57302
|
});
|
|
57195
57303
|
import { createServer } from "node:http";
|
|
57196
57304
|
import { readFileSync as readFileSync33, existsSync as existsSync19, statSync as statSync26 } from "node:fs";
|
|
57197
|
-
import { dirname as
|
|
57305
|
+
import { dirname as dirname26, join as join47, resolve as resolve11, extname as extname4, posix as posix2, sep as sep6 } from "node:path";
|
|
57198
57306
|
function readServerAddressHolder(path3) {
|
|
57199
57307
|
try {
|
|
57200
57308
|
const value = JSON.parse(readFileSync33(path3, "utf8"));
|
|
@@ -57605,7 +57713,7 @@ async function startServer(opts = {}) {
|
|
|
57605
57713
|
if (statusPath && statusIdentity) runtime.removeStatus(statusPath, statusIdentity);
|
|
57606
57714
|
if (statusPath && statusIdentity) {
|
|
57607
57715
|
try {
|
|
57608
|
-
runtime.removeStatus(serverAddressPathForStateDir(
|
|
57716
|
+
runtime.removeStatus(serverAddressPathForStateDir(dirname26(statusPath)), statusIdentity);
|
|
57609
57717
|
} catch {
|
|
57610
57718
|
}
|
|
57611
57719
|
}
|
|
@@ -57768,7 +57876,9 @@ async function startServer(opts = {}) {
|
|
|
57768
57876
|
const entry = findProjectBySegment(split.slug);
|
|
57769
57877
|
if (!entry) return void 0;
|
|
57770
57878
|
const existing = tenants.appFor(entry.id);
|
|
57771
|
-
if (existing
|
|
57879
|
+
if (existing && (entry.id === project.id || tenants.get(entry.id)?.project.dir === entry.path)) {
|
|
57880
|
+
return { surfaces: existing, url: split.rest };
|
|
57881
|
+
}
|
|
57772
57882
|
if (!await tenants.activate(projectFromRegistryEntry(entry))) return void 0;
|
|
57773
57883
|
const built = tenants.appFor(entry.id);
|
|
57774
57884
|
return built ? { surfaces: built, url: split.rest } : void 0;
|