@dotobokuri/fleet-console 1.39.0 → 1.40.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/cli.mjs +43 -1090
- package/dist/client/assets/{_baseUniq-BDfju2rW.js → _baseUniq-Bao5GOIa.js} +1 -1
- package/dist/client/assets/{arc-DWcMv-ui.js → arc-DnhHMLy9.js} +1 -1
- package/dist/client/assets/{architectureDiagram-Q4EWVU46-DhPv_Uba.js → architectureDiagram-Q4EWVU46-DAbURr0a.js} +1 -1
- package/dist/client/assets/{blockDiagram-DXYQGD6D-D7RYcNDP.js → blockDiagram-DXYQGD6D-DE1raZQ6.js} +1 -1
- package/dist/client/assets/{c4Diagram-AHTNJAMY-9_4dQBo3.js → c4Diagram-AHTNJAMY-beLZlUB3.js} +1 -1
- package/dist/client/assets/channel-Bn1wyUhs.js +1 -0
- package/dist/client/assets/{chunk-4BX2VUAB-CQf5x2mT.js → chunk-4BX2VUAB-DEqdunZS.js} +1 -1
- package/dist/client/assets/{chunk-4TB4RGXK-eeG8BKQB.js → chunk-4TB4RGXK-D8i5nx4L.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-1dkBlsDt.js → chunk-55IACEB6-eM3-fH_e.js} +1 -1
- package/dist/client/assets/{chunk-EDXVE4YY-C5vcF-lT.js → chunk-EDXVE4YY-nQoyt_Pd.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-CGelAuwP.js → chunk-FMBD7UC4-D8Wq8CYj.js} +1 -1
- package/dist/client/assets/{chunk-OYMX7WX6-CbKgVyop.js → chunk-OYMX7WX6-Cx4Wr2ZT.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-CT0ppG8R.js → chunk-QZHKN3VN-BM2v7Krr.js} +1 -1
- package/dist/client/assets/{chunk-YZCP3GAM-BEf8DhxB.js → chunk-YZCP3GAM-zTniPxm7.js} +1 -1
- package/dist/client/assets/classDiagram-6PBFFD2Q-DBE3Ix3c.js +1 -0
- package/dist/client/assets/classDiagram-v2-HSJHXN6E-DBE3Ix3c.js +1 -0
- package/dist/client/assets/clone-COL47Wy_.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-C6GtvpYi.js → cose-bilkent-S5V4N54A-B5pl2A_p.js} +1 -1
- package/dist/client/assets/{dagre-KV5264BT-DvrU2BgH.js → dagre-KV5264BT-KHPgW9C2.js} +1 -1
- package/dist/client/assets/{diagram-5BDNPKRD-Cy1qKKqt.js → diagram-5BDNPKRD-DCv28c7S.js} +1 -1
- package/dist/client/assets/{diagram-G4DWMVQ6-C4GGKnnD.js → diagram-G4DWMVQ6-mT5WQ415.js} +1 -1
- package/dist/client/assets/{diagram-MMDJMWI5-By7JFsIw.js → diagram-MMDJMWI5-iKYfjiRC.js} +1 -1
- package/dist/client/assets/{diagram-TYMM5635-YwzVWpID.js → diagram-TYMM5635-_uqBP7vH.js} +1 -1
- package/dist/client/assets/{erDiagram-SMLLAGMA-CDsNlmLk.js → erDiagram-SMLLAGMA-DxNN1WhN.js} +1 -1
- package/dist/client/assets/{flowDiagram-DWJPFMVM-BuUpIzTa.js → flowDiagram-DWJPFMVM-DGTsrBvM.js} +1 -1
- package/dist/client/assets/{ganttDiagram-T4ZO3ILL-Dqv9t2x8.js → ganttDiagram-T4ZO3ILL-C17hg4lr.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-UUTBAWPF-DApQn2c7.js → gitGraphDiagram-UUTBAWPF-CeJ25hAd.js} +1 -1
- package/dist/client/assets/{graph-CyX-IC4n.js → graph-BQvb-BfT.js} +1 -1
- package/dist/client/assets/index-Ca6HkGPQ.css +1 -0
- package/dist/client/assets/index-Cr3Xq85X.js +452 -0
- package/dist/client/assets/{infoDiagram-42DDH7IO-DIf3qelw.js → infoDiagram-42DDH7IO-BctsofOZ.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-UXIWVN3A-CU3QtNdx.js → ishikawaDiagram-UXIWVN3A-PiPmxcg9.js} +1 -1
- package/dist/client/assets/{journeyDiagram-VCZTEJTY-Dfq4OBhW.js → journeyDiagram-VCZTEJTY-BwkjYq3n.js} +1 -1
- package/dist/client/assets/{kanban-definition-6JOO6SKY-CWSe3eh7.js → kanban-definition-6JOO6SKY-CSV4dYfF.js} +1 -1
- package/dist/client/assets/{layout-CfdpDpEB.js → layout-DdReLJnP.js} +1 -1
- package/dist/client/assets/{linear-BQA5wLDW.js → linear-B54euy_k.js} +1 -1
- package/dist/client/assets/{mermaid.core-BwJS5O4y.js → mermaid.core-CF92I5mT.js} +4 -4
- package/dist/client/assets/{min-Cg-Q6TB5.js → min-BcETQ2qJ.js} +1 -1
- package/dist/client/assets/{mindmap-definition-QFDTVHPH-BNXT0q7L.js → mindmap-definition-QFDTVHPH-CrmVPycO.js} +1 -1
- package/dist/client/assets/{pieDiagram-DEJITSTG-Cot4WNe7.js → pieDiagram-DEJITSTG-B5d4jR0H.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-34T5L4WZ-_YW3nZwc.js → quadrantDiagram-34T5L4WZ-DlgCNExa.js} +1 -1
- package/dist/client/assets/{requirementDiagram-MS252O5E-didEilrX.js → requirementDiagram-MS252O5E-CeuVib_X.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-XADWPNL6-CIpzp5Ep.js → sankeyDiagram-XADWPNL6-Bzxv73ik.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-FGHM5R23-CqvwD_CI.js → sequenceDiagram-FGHM5R23-B0Ondg0u.js} +1 -1
- package/dist/client/assets/{stateDiagram-FHFEXIEX-D492KgCG.js → stateDiagram-FHFEXIEX-CuNHg5DJ.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-BVPbUfrG.js +1 -0
- package/dist/client/assets/{timeline-definition-GMOUNBTQ-BpAwqH0H.js → timeline-definition-GMOUNBTQ-DXcye6z7.js} +1 -1
- package/dist/client/assets/{vennDiagram-DHZGUBPP-DDMPO_HG.js → vennDiagram-DHZGUBPP-CL4rbpzL.js} +1 -1
- package/dist/client/assets/{wardley-RL74JXVD-TKEj0wFU.js → wardley-RL74JXVD-rVZBTA_R.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-NUSXRM2D-CLjBh2KA.js → wardleyDiagram-NUSXRM2D-Cb8Arj1F.js} +1 -1
- package/dist/client/assets/{xychartDiagram-5P7HB3ND-DEn2Z9lG.js → xychartDiagram-5P7HB3ND-C-qp4Say.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/client/theme-boot.js +5 -4
- package/dist/fleet-plugins/ledger/routes.mjs +0 -33
- package/dist/fleet-plugins/quota/routes.mjs +672 -0
- package/dist/fleet-plugins/scuttlebutt/routes.mjs +1 -351
- package/dist/fleet-plugins/skills/routes.mjs +0 -33
- package/dist/fleet-plugins/terminal/routes.mjs +462 -2017
- package/package.json +1 -1
- package/dist/client/assets/channel-Cjiuj1tM.js +0 -1
- package/dist/client/assets/classDiagram-6PBFFD2Q-B-_6FtAZ.js +0 -1
- package/dist/client/assets/classDiagram-v2-HSJHXN6E-B-_6FtAZ.js +0 -1
- package/dist/client/assets/clone-BF2H_qSP.js +0 -1
- package/dist/client/assets/index-RzoF0XVt.js +0 -452
- package/dist/client/assets/index-bog2t8Rz.css +0 -1
- package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-DUe9CEL6.js +0 -1
package/dist/cli.mjs
CHANGED
|
@@ -993,56 +993,6 @@ function ensureWorkspaceDirectory(dataDir, cwd) {
|
|
|
993
993
|
});
|
|
994
994
|
return workspace;
|
|
995
995
|
}
|
|
996
|
-
function findWorkspaceDirectory(dataDir, cwd) {
|
|
997
|
-
const expected = resolveWorkspaceDirectory(dataDir, cwd);
|
|
998
|
-
assertSafeWorkspaceRoot(dataDir, expected.root);
|
|
999
|
-
const workspaceStat = safeLstat(expected.path);
|
|
1000
|
-
if (!workspaceStat) return null;
|
|
1001
|
-
if (!workspaceStat.isDirectory() || workspaceStat.isSymbolicLink()) {
|
|
1002
|
-
throw new Error(`Workspace directory not found or unsafe: ${expected.name}`);
|
|
1003
|
-
}
|
|
1004
|
-
const existing = readExistingWorkspaceDirectory(expected.root, expected.name, expected.path);
|
|
1005
|
-
if (existing.cwd !== expected.cwd) {
|
|
1006
|
-
throw new Error(
|
|
1007
|
-
`Workspace directory identity collision for ${expected.name}: expected ${expected.cwd}, found ${existing.cwd}`
|
|
1008
|
-
);
|
|
1009
|
-
}
|
|
1010
|
-
return existing;
|
|
1011
|
-
}
|
|
1012
|
-
function readExistingWorkspaceDirectory(root, name, workspacePath) {
|
|
1013
|
-
const identityPath = path23.join(workspacePath, WORKSPACE_IDENTITY_FILE_NAME);
|
|
1014
|
-
const identity2 = readWorkspaceIdentity(identityPath);
|
|
1015
|
-
if (!identity2) {
|
|
1016
|
-
throw new Error(`Workspace directory identity is missing: ${name}`);
|
|
1017
|
-
}
|
|
1018
|
-
if (toWorkspaceDirectoryName(identity2.cwd) !== name) {
|
|
1019
|
-
throw new Error(`Workspace directory identity does not match its name: ${name}`);
|
|
1020
|
-
}
|
|
1021
|
-
return {
|
|
1022
|
-
cwd: identity2.cwd,
|
|
1023
|
-
identityPath,
|
|
1024
|
-
name,
|
|
1025
|
-
path: workspacePath,
|
|
1026
|
-
root
|
|
1027
|
-
};
|
|
1028
|
-
}
|
|
1029
|
-
function assertSafeWorkspaceRoot(dataDir, root, allowMissing) {
|
|
1030
|
-
const resolvedDataDir = path23.resolve(dataDir);
|
|
1031
|
-
const dataDirStat = safeLstat(resolvedDataDir);
|
|
1032
|
-
if (!dataDirStat) {
|
|
1033
|
-
return;
|
|
1034
|
-
}
|
|
1035
|
-
if (!dataDirStat.isDirectory() || dataDirStat.isSymbolicLink()) {
|
|
1036
|
-
throw new Error(`Workspace data directory not found or unsafe: ${resolvedDataDir}`);
|
|
1037
|
-
}
|
|
1038
|
-
const rootStat = safeLstat(root);
|
|
1039
|
-
if (!rootStat) {
|
|
1040
|
-
return;
|
|
1041
|
-
}
|
|
1042
|
-
if (!rootStat.isDirectory() || rootStat.isSymbolicLink()) {
|
|
1043
|
-
throw new Error(`Workspace directory root not found or unsafe: ${root}`);
|
|
1044
|
-
}
|
|
1045
|
-
}
|
|
1046
996
|
function buildWorkspaceDirectory(dataDir, name, cwd) {
|
|
1047
997
|
assertWorkspaceDirectoryName(name);
|
|
1048
998
|
const root = getWorkspaceDirectoryRoot(dataDir);
|
|
@@ -12164,9 +12114,7 @@ var DESKTOP_TITLE_BAR_OVERLAYS = {
|
|
|
12164
12114
|
instrument: { color: "#03080e", symbolColor: "#989fa6", height: 43 },
|
|
12165
12115
|
maritime: { color: "#041729", symbolColor: "#c8c4b7", height: 43 },
|
|
12166
12116
|
carbon: { color: "#101215", symbolColor: "#bfc1c3", height: 43 },
|
|
12167
|
-
|
|
12168
|
-
whites: { color: "#eef0f3", symbolColor: "#334055", height: 43 },
|
|
12169
|
-
drydock: { color: "#ddeaf2", symbolColor: "#30475d", height: 43 }
|
|
12117
|
+
whites: { color: "#f1f0ec", symbolColor: "#424038", height: 43 }
|
|
12170
12118
|
};
|
|
12171
12119
|
function desktopThemeSnapshot(theme) {
|
|
12172
12120
|
return { theme, titleBarOverlay: { ...DESKTOP_TITLE_BAR_OVERLAYS[theme] } };
|
|
@@ -12281,7 +12229,7 @@ function readConsoleGeneralSettings(value) {
|
|
|
12281
12229
|
const language = value.language === "auto" || value.language === "en" || value.language === "ko" ? value.language : void 0;
|
|
12282
12230
|
const reducePanelMotion = typeof value.reducePanelMotion === "boolean" ? value.reducePanelMotion : void 0;
|
|
12283
12231
|
const seenFeatureTours = sanitizeSeenFeatureTours(value.seenFeatureTours);
|
|
12284
|
-
const theme = value.theme === "instrument" || value.theme === "maritime" || value.theme === "carbon" || value.theme === "
|
|
12232
|
+
const theme = value.theme === "instrument" || value.theme === "maritime" || value.theme === "carbon" || value.theme === "whites" ? value.theme : value.theme === "daywatch" || value.theme === "drydock" ? "whites" : void 0;
|
|
12285
12233
|
const uiFont = sanitizeUiFontSettings(value.uiFont);
|
|
12286
12234
|
return {
|
|
12287
12235
|
...consolePortMode !== void 0 ? { consolePortMode } : {},
|
|
@@ -12393,7 +12341,7 @@ async function mutateGlobalSettings(req, res, deps) {
|
|
|
12393
12341
|
deps.writeJson(res, 400, { error: "invalid_seen_feature_tours" });
|
|
12394
12342
|
return;
|
|
12395
12343
|
}
|
|
12396
|
-
if (body2.theme !== void 0 && body2.theme !== "instrument" && body2.theme !== "maritime" && body2.theme !== "carbon" && body2.theme !== "
|
|
12344
|
+
if (body2.theme !== void 0 && body2.theme !== "instrument" && body2.theme !== "maritime" && body2.theme !== "carbon" && body2.theme !== "whites") {
|
|
12397
12345
|
deps.writeJson(res, 400, { error: "invalid_theme" });
|
|
12398
12346
|
return;
|
|
12399
12347
|
}
|
|
@@ -12401,7 +12349,7 @@ async function mutateGlobalSettings(req, res, deps) {
|
|
|
12401
12349
|
deps.writeJson(res, 400, { error: "invalid_ui_font" });
|
|
12402
12350
|
return;
|
|
12403
12351
|
}
|
|
12404
|
-
const theme = body2.theme === "instrument" || body2.theme === "maritime" || body2.theme === "carbon" || body2.theme === "
|
|
12352
|
+
const theme = body2.theme === "instrument" || body2.theme === "maritime" || body2.theme === "carbon" || body2.theme === "whites" ? body2.theme : void 0;
|
|
12405
12353
|
const updated = deps.consoleSettingsStore.update((current) => ({
|
|
12406
12354
|
...current,
|
|
12407
12355
|
version: 1,
|
|
@@ -13523,10 +13471,10 @@ function mergeDefs(...defs) {
|
|
|
13523
13471
|
function cloneDef(schema) {
|
|
13524
13472
|
return mergeDefs(schema._zod.def);
|
|
13525
13473
|
}
|
|
13526
|
-
function getElementAtPath(obj,
|
|
13527
|
-
if (!
|
|
13474
|
+
function getElementAtPath(obj, path47) {
|
|
13475
|
+
if (!path47)
|
|
13528
13476
|
return obj;
|
|
13529
|
-
return
|
|
13477
|
+
return path47.reduce((acc, key) => acc?.[key], obj);
|
|
13530
13478
|
}
|
|
13531
13479
|
function promiseAllObject(promisesObj) {
|
|
13532
13480
|
const keys = Object.keys(promisesObj);
|
|
@@ -13935,11 +13883,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
13935
13883
|
}
|
|
13936
13884
|
return false;
|
|
13937
13885
|
}
|
|
13938
|
-
function prefixIssues(
|
|
13886
|
+
function prefixIssues(path47, issues) {
|
|
13939
13887
|
return issues.map((iss) => {
|
|
13940
13888
|
var _a3;
|
|
13941
13889
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
13942
|
-
iss.path.unshift(
|
|
13890
|
+
iss.path.unshift(path47);
|
|
13943
13891
|
return iss;
|
|
13944
13892
|
});
|
|
13945
13893
|
}
|
|
@@ -14086,16 +14034,16 @@ function flattenError(error51, mapper = (issue3) => issue3.message) {
|
|
|
14086
14034
|
}
|
|
14087
14035
|
function formatError(error51, mapper = (issue3) => issue3.message) {
|
|
14088
14036
|
const fieldErrors = { _errors: [] };
|
|
14089
|
-
const processError = (error52,
|
|
14037
|
+
const processError = (error52, path47 = []) => {
|
|
14090
14038
|
for (const issue3 of error52.issues) {
|
|
14091
14039
|
if (issue3.code === "invalid_union" && issue3.errors.length) {
|
|
14092
|
-
issue3.errors.map((issues) => processError({ issues }, [...
|
|
14040
|
+
issue3.errors.map((issues) => processError({ issues }, [...path47, ...issue3.path]));
|
|
14093
14041
|
} else if (issue3.code === "invalid_key") {
|
|
14094
|
-
processError({ issues: issue3.issues }, [...
|
|
14042
|
+
processError({ issues: issue3.issues }, [...path47, ...issue3.path]);
|
|
14095
14043
|
} else if (issue3.code === "invalid_element") {
|
|
14096
|
-
processError({ issues: issue3.issues }, [...
|
|
14044
|
+
processError({ issues: issue3.issues }, [...path47, ...issue3.path]);
|
|
14097
14045
|
} else {
|
|
14098
|
-
const fullpath = [...
|
|
14046
|
+
const fullpath = [...path47, ...issue3.path];
|
|
14099
14047
|
if (fullpath.length === 0) {
|
|
14100
14048
|
fieldErrors._errors.push(mapper(issue3));
|
|
14101
14049
|
} else {
|
|
@@ -14122,17 +14070,17 @@ function formatError(error51, mapper = (issue3) => issue3.message) {
|
|
|
14122
14070
|
}
|
|
14123
14071
|
function treeifyError(error51, mapper = (issue3) => issue3.message) {
|
|
14124
14072
|
const result = { errors: [] };
|
|
14125
|
-
const processError = (error52,
|
|
14073
|
+
const processError = (error52, path47 = []) => {
|
|
14126
14074
|
var _a3, _b;
|
|
14127
14075
|
for (const issue3 of error52.issues) {
|
|
14128
14076
|
if (issue3.code === "invalid_union" && issue3.errors.length) {
|
|
14129
|
-
issue3.errors.map((issues) => processError({ issues }, [...
|
|
14077
|
+
issue3.errors.map((issues) => processError({ issues }, [...path47, ...issue3.path]));
|
|
14130
14078
|
} else if (issue3.code === "invalid_key") {
|
|
14131
|
-
processError({ issues: issue3.issues }, [...
|
|
14079
|
+
processError({ issues: issue3.issues }, [...path47, ...issue3.path]);
|
|
14132
14080
|
} else if (issue3.code === "invalid_element") {
|
|
14133
|
-
processError({ issues: issue3.issues }, [...
|
|
14081
|
+
processError({ issues: issue3.issues }, [...path47, ...issue3.path]);
|
|
14134
14082
|
} else {
|
|
14135
|
-
const fullpath = [...
|
|
14083
|
+
const fullpath = [...path47, ...issue3.path];
|
|
14136
14084
|
if (fullpath.length === 0) {
|
|
14137
14085
|
result.errors.push(mapper(issue3));
|
|
14138
14086
|
continue;
|
|
@@ -14164,8 +14112,8 @@ function treeifyError(error51, mapper = (issue3) => issue3.message) {
|
|
|
14164
14112
|
}
|
|
14165
14113
|
function toDotPath(_path) {
|
|
14166
14114
|
const segs = [];
|
|
14167
|
-
const
|
|
14168
|
-
for (const seg of
|
|
14115
|
+
const path47 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
14116
|
+
for (const seg of path47) {
|
|
14169
14117
|
if (typeof seg === "number")
|
|
14170
14118
|
segs.push(`[${seg}]`);
|
|
14171
14119
|
else if (typeof seg === "symbol")
|
|
@@ -26829,13 +26777,13 @@ function resolveRef(ref, ctx) {
|
|
|
26829
26777
|
if (!ref.startsWith("#")) {
|
|
26830
26778
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
26831
26779
|
}
|
|
26832
|
-
const
|
|
26833
|
-
if (
|
|
26780
|
+
const path47 = ref.slice(1).split("/").filter(Boolean);
|
|
26781
|
+
if (path47.length === 0) {
|
|
26834
26782
|
return ctx.rootSchema;
|
|
26835
26783
|
}
|
|
26836
26784
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
26837
|
-
if (
|
|
26838
|
-
const key =
|
|
26785
|
+
if (path47[0] === defsKey) {
|
|
26786
|
+
const key = path47[1];
|
|
26839
26787
|
if (!key || !ctx.defs[key]) {
|
|
26840
26788
|
throw new Error(`Reference not found: ${ref}`);
|
|
26841
26789
|
}
|
|
@@ -32036,23 +31984,6 @@ var models_default = {
|
|
|
32036
31984
|
{ modelId: "gpt-5.5-fast", name: "GPT-5.5 Fast", providerModelId: "gpt-5.5", serviceTier: "priority", effort: { supported: true, levels: ["low", "medium", "high", "xhigh"], default: "high" } }
|
|
32037
31985
|
]
|
|
32038
31986
|
},
|
|
32039
|
-
"opencode-go": {
|
|
32040
|
-
name: "OpenCode Go",
|
|
32041
|
-
defaultModel: "opencode-go/deepseek-v4-flash",
|
|
32042
|
-
models: [
|
|
32043
|
-
{ modelId: "opencode-go/deepseek-v4-flash", name: "DeepSeek V4 Flash", effort: { supported: false } },
|
|
32044
|
-
{ modelId: "opencode-go/deepseek-v4-pro", name: "DeepSeek V4 Pro", effort: { supported: false } },
|
|
32045
|
-
{ modelId: "opencode-go/glm-5.2", name: "GLM-5.2", effort: { supported: false } },
|
|
32046
|
-
{ modelId: "opencode-go/grok-4.5", name: "Grok 4.5", effort: { supported: false } },
|
|
32047
|
-
{ modelId: "opencode-go/kimi-k3", name: "Kimi K3", effort: { supported: false } },
|
|
32048
|
-
{ modelId: "opencode-go/kimi-k2.7-code", name: "Kimi K2.7 Code", effort: { supported: false } },
|
|
32049
|
-
{ modelId: "opencode-go/mimo-v2.5", name: "MiMo V2.5", effort: { supported: false } },
|
|
32050
|
-
{ modelId: "opencode-go/mimo-v2.5-pro", name: "MiMo V2.5 Pro", effort: { supported: false } },
|
|
32051
|
-
{ modelId: "opencode-go/minimax-m3", name: "MiniMax M3", effort: { supported: false } },
|
|
32052
|
-
{ modelId: "opencode-go/qwen3.7-max", name: "Qwen3.7 Max", effort: { supported: false } },
|
|
32053
|
-
{ modelId: "opencode-go/qwen3.7-plus", name: "Qwen3.7 Plus", effort: { supported: false } }
|
|
32054
|
-
]
|
|
32055
|
-
},
|
|
32056
31987
|
cursor: {
|
|
32057
31988
|
name: "Cursor Agent",
|
|
32058
31989
|
defaultModel: "auto",
|
|
@@ -32314,22 +32245,6 @@ var CLI_BACKENDS = {
|
|
|
32314
32245
|
usesNpxBridge: false,
|
|
32315
32246
|
defaultMaxTokens: 1e5
|
|
32316
32247
|
},
|
|
32317
|
-
"opencode-go": {
|
|
32318
|
-
id: "opencode-go",
|
|
32319
|
-
cliCommand: "opencode",
|
|
32320
|
-
protocol: "acp",
|
|
32321
|
-
authRequired: false,
|
|
32322
|
-
acpArgs: ["acp"],
|
|
32323
|
-
modes: [
|
|
32324
|
-
{ id: "build", label: "Build" },
|
|
32325
|
-
{ id: "plan", label: "Plan" }
|
|
32326
|
-
],
|
|
32327
|
-
supportsSessionClose: true,
|
|
32328
|
-
supportsSessionLoad: true,
|
|
32329
|
-
requiresModelAtSpawn: true,
|
|
32330
|
-
usesNpxBridge: false,
|
|
32331
|
-
defaultMaxTokens: 128e3
|
|
32332
|
-
},
|
|
32333
32248
|
cursor: {
|
|
32334
32249
|
id: "cursor",
|
|
32335
32250
|
cliCommand: "cursor-agent",
|
|
@@ -32391,8 +32306,6 @@ function getYoloModeId(cli) {
|
|
|
32391
32306
|
case "claude":
|
|
32392
32307
|
case "claude-kimi":
|
|
32393
32308
|
return "bypassPermissions";
|
|
32394
|
-
case "opencode-go":
|
|
32395
|
-
return "build";
|
|
32396
32309
|
case "cursor":
|
|
32397
32310
|
return "agent";
|
|
32398
32311
|
case "codex":
|
|
@@ -34795,319 +34708,6 @@ var UnifiedCursorAgentClient = class extends EventEmitter {
|
|
|
34795
34708
|
return patterns.some((pattern) => pattern.test(text));
|
|
34796
34709
|
}
|
|
34797
34710
|
};
|
|
34798
|
-
var UnifiedOpenCodeAgentClient = class _UnifiedOpenCodeAgentClient extends EventEmitter {
|
|
34799
|
-
providerId;
|
|
34800
|
-
connection = null;
|
|
34801
|
-
sessionId = null;
|
|
34802
|
-
sessionCwd = null;
|
|
34803
|
-
currentSystemPrompt = null;
|
|
34804
|
-
/** 첫 프롬프트 전송 시 systemPrompt를 텍스트 블록으로 앞에 붙이기 위한 플래그 */
|
|
34805
|
-
firstPromptPending = null;
|
|
34806
|
-
detector = new CliDetector();
|
|
34807
|
-
constructor(providerId) {
|
|
34808
|
-
super();
|
|
34809
|
-
this.providerId = providerId;
|
|
34810
|
-
}
|
|
34811
|
-
on(event, listener) {
|
|
34812
|
-
return super.on(event, listener);
|
|
34813
|
-
}
|
|
34814
|
-
once(event, listener) {
|
|
34815
|
-
return super.once(event, listener);
|
|
34816
|
-
}
|
|
34817
|
-
off(event, listener) {
|
|
34818
|
-
return super.off(event, listener);
|
|
34819
|
-
}
|
|
34820
|
-
emitTyped(event, ...args) {
|
|
34821
|
-
return super.emit(event, ...args);
|
|
34822
|
-
}
|
|
34823
|
-
async connect(options) {
|
|
34824
|
-
await this.disconnect();
|
|
34825
|
-
if (options.cli && options.cli !== this.providerId) {
|
|
34826
|
-
throw new Error(`UnifiedOpenCodeAgentClient\uB294 ${this.providerId} CLI\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4.`);
|
|
34827
|
-
}
|
|
34828
|
-
const acpMcpServers = this.resolveMcpServers(options.mcpServers);
|
|
34829
|
-
const spawnConfig = createSpawnConfig(this.providerId, options);
|
|
34830
|
-
const cleanEnv = cleanEnvironment(process.env, options.env);
|
|
34831
|
-
cleanEnv.OPENCODE_CONFIG_CONTENT = JSON.stringify({
|
|
34832
|
-
agent: {
|
|
34833
|
-
explore: { disable: true },
|
|
34834
|
-
plan: { disable: true },
|
|
34835
|
-
general: { disable: true }
|
|
34836
|
-
}
|
|
34837
|
-
});
|
|
34838
|
-
const connection = new AcpConnection({
|
|
34839
|
-
command: spawnConfig.command,
|
|
34840
|
-
args: spawnConfig.args,
|
|
34841
|
-
cliType: this.providerId,
|
|
34842
|
-
cwd: options.cwd,
|
|
34843
|
-
env: cleanEnv,
|
|
34844
|
-
requestTimeout: options.timeout,
|
|
34845
|
-
initTimeout: options.timeout,
|
|
34846
|
-
promptIdleTimeout: options.promptIdleTimeout,
|
|
34847
|
-
clientInfo: options.clientInfo,
|
|
34848
|
-
autoApprove: options.autoApprove,
|
|
34849
|
-
fsAccess: options.fsAccess
|
|
34850
|
-
});
|
|
34851
|
-
this.connection = connection;
|
|
34852
|
-
this.setupEventForwarding();
|
|
34853
|
-
const recentLogs = [];
|
|
34854
|
-
const collectLog = (message) => {
|
|
34855
|
-
recentLogs.push(message);
|
|
34856
|
-
if (recentLogs.length > 30) {
|
|
34857
|
-
recentLogs.shift();
|
|
34858
|
-
}
|
|
34859
|
-
};
|
|
34860
|
-
connection.on("log", collectLog);
|
|
34861
|
-
let session;
|
|
34862
|
-
try {
|
|
34863
|
-
session = await connection.connect(
|
|
34864
|
-
options.cwd,
|
|
34865
|
-
options.sessionId,
|
|
34866
|
-
acpMcpServers,
|
|
34867
|
-
void 0
|
|
34868
|
-
);
|
|
34869
|
-
} catch (error51) {
|
|
34870
|
-
const connectionError = this.buildConnectionError(error51, recentLogs);
|
|
34871
|
-
await this.cleanupFailedConnection();
|
|
34872
|
-
throw connectionError;
|
|
34873
|
-
} finally {
|
|
34874
|
-
connection.off("log", collectLog);
|
|
34875
|
-
}
|
|
34876
|
-
return this.finalizeConnect(options, session);
|
|
34877
|
-
}
|
|
34878
|
-
async disconnect() {
|
|
34879
|
-
if (!this.connection) {
|
|
34880
|
-
this.clearSessionState();
|
|
34881
|
-
return;
|
|
34882
|
-
}
|
|
34883
|
-
const conn = this.connection;
|
|
34884
|
-
await conn.disconnect();
|
|
34885
|
-
conn.removeAllListeners();
|
|
34886
|
-
this.connection = null;
|
|
34887
|
-
this.clearSessionState();
|
|
34888
|
-
}
|
|
34889
|
-
async endSession() {
|
|
34890
|
-
if (!this.connection || !this.sessionId) {
|
|
34891
|
-
throw new Error("\uC5F0\uACB0\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
|
|
34892
|
-
}
|
|
34893
|
-
await this.connection.endSession(this.sessionId);
|
|
34894
|
-
this.sessionId = null;
|
|
34895
|
-
}
|
|
34896
|
-
getConnectionInfo() {
|
|
34897
|
-
return {
|
|
34898
|
-
cli: this.connection ? this.providerId : null,
|
|
34899
|
-
protocol: this.connection ? "acp" : null,
|
|
34900
|
-
sessionId: this.sessionId,
|
|
34901
|
-
state: this.connection ? this.connection.connectionState : "disconnected"
|
|
34902
|
-
};
|
|
34903
|
-
}
|
|
34904
|
-
async detectClis() {
|
|
34905
|
-
return this.detector.detectAll(true);
|
|
34906
|
-
}
|
|
34907
|
-
async sendMessage(content) {
|
|
34908
|
-
if (!this.connection || !this.sessionId) {
|
|
34909
|
-
throw new Error("\uC5F0\uACB0\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
|
|
34910
|
-
}
|
|
34911
|
-
const systemPrompt = this.firstPromptPending;
|
|
34912
|
-
if (!systemPrompt) {
|
|
34913
|
-
return this.connection.sendPrompt(this.sessionId, content);
|
|
34914
|
-
}
|
|
34915
|
-
const userBlocks = typeof content === "string" ? [{ type: "text", text: content }] : content;
|
|
34916
|
-
const response = await this.connection.sendPrompt(this.sessionId, [
|
|
34917
|
-
{ type: "text", text: systemPrompt },
|
|
34918
|
-
...userBlocks
|
|
34919
|
-
]);
|
|
34920
|
-
this.firstPromptPending = null;
|
|
34921
|
-
return response;
|
|
34922
|
-
}
|
|
34923
|
-
async cancelPrompt() {
|
|
34924
|
-
if (!this.connection || !this.sessionId) {
|
|
34925
|
-
throw new Error("\uC5F0\uACB0\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
|
|
34926
|
-
}
|
|
34927
|
-
await this.connection.cancelSession(this.sessionId);
|
|
34928
|
-
}
|
|
34929
|
-
async setModel(model) {
|
|
34930
|
-
if (!this.connection || !this.sessionId) {
|
|
34931
|
-
throw new Error("\uC5F0\uACB0\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
|
|
34932
|
-
}
|
|
34933
|
-
await this.connection.setModel(this.sessionId, model);
|
|
34934
|
-
}
|
|
34935
|
-
async setConfigOption(configId, value) {
|
|
34936
|
-
if (!this.connection || !this.sessionId) {
|
|
34937
|
-
throw new Error("\uC5F0\uACB0\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
|
|
34938
|
-
}
|
|
34939
|
-
await this.connection.setConfigOption(this.sessionId, configId, value);
|
|
34940
|
-
}
|
|
34941
|
-
async setMode(mode) {
|
|
34942
|
-
if (!this.connection || !this.sessionId) {
|
|
34943
|
-
throw new Error("\uC5F0\uACB0\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
|
|
34944
|
-
}
|
|
34945
|
-
await this.connection.setMode(this.sessionId, mode);
|
|
34946
|
-
}
|
|
34947
|
-
async setYoloMode(enabled) {
|
|
34948
|
-
return this.setMode(enabled ? getYoloModeId(this.providerId) : "plan");
|
|
34949
|
-
}
|
|
34950
|
-
getAvailableModes() {
|
|
34951
|
-
return getBackendConfig(this.providerId).modes ?? [];
|
|
34952
|
-
}
|
|
34953
|
-
getAvailableModels() {
|
|
34954
|
-
return getProviderModels(this.providerId);
|
|
34955
|
-
}
|
|
34956
|
-
getCurrentSystemPrompt() {
|
|
34957
|
-
return this.currentSystemPrompt;
|
|
34958
|
-
}
|
|
34959
|
-
async loadSession(sessionId, mcpServers) {
|
|
34960
|
-
if (!this.connection) {
|
|
34961
|
-
throw new Error("\uC5F0\uACB0\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
|
|
34962
|
-
}
|
|
34963
|
-
await this.connection.loadSession({
|
|
34964
|
-
sessionId,
|
|
34965
|
-
cwd: this.sessionCwd ?? process.cwd(),
|
|
34966
|
-
mcpServers: this.resolveMcpServers(mcpServers)
|
|
34967
|
-
});
|
|
34968
|
-
this.sessionId = sessionId;
|
|
34969
|
-
this.currentSystemPrompt = null;
|
|
34970
|
-
this.firstPromptPending = null;
|
|
34971
|
-
}
|
|
34972
|
-
async resetSession(cwd) {
|
|
34973
|
-
if (!this.connection) {
|
|
34974
|
-
throw new Error("\uC5F0\uACB0\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
|
|
34975
|
-
}
|
|
34976
|
-
const targetCwd = cwd ?? this.sessionCwd ?? process.cwd();
|
|
34977
|
-
await this.disconnect();
|
|
34978
|
-
const newClient = new _UnifiedOpenCodeAgentClient(this.providerId);
|
|
34979
|
-
const result = await newClient.connect({
|
|
34980
|
-
cwd: targetCwd,
|
|
34981
|
-
autoApprove: true,
|
|
34982
|
-
systemPrompt: this.currentSystemPrompt ?? void 0
|
|
34983
|
-
});
|
|
34984
|
-
this.connection = newClient.connection;
|
|
34985
|
-
this.sessionId = newClient.sessionId;
|
|
34986
|
-
this.sessionCwd = newClient.sessionCwd;
|
|
34987
|
-
this.currentSystemPrompt = newClient.currentSystemPrompt;
|
|
34988
|
-
this.firstPromptPending = newClient.firstPromptPending;
|
|
34989
|
-
this.setupEventForwarding();
|
|
34990
|
-
newClient.removeAllListeners();
|
|
34991
|
-
return {
|
|
34992
|
-
cli: this.providerId,
|
|
34993
|
-
protocol: "acp",
|
|
34994
|
-
session: result.session
|
|
34995
|
-
};
|
|
34996
|
-
}
|
|
34997
|
-
resolveMcpServers(servers) {
|
|
34998
|
-
return servers?.length ? mcpServerConfigsToAcp(servers) : [];
|
|
34999
|
-
}
|
|
35000
|
-
async finalizeConnect(options, session) {
|
|
35001
|
-
if (options.yoloMode && session.sessionId) {
|
|
35002
|
-
try {
|
|
35003
|
-
await this.connection.setMode(session.sessionId, getYoloModeId(this.providerId));
|
|
35004
|
-
} catch {
|
|
35005
|
-
}
|
|
35006
|
-
}
|
|
35007
|
-
if (options.model && session.sessionId) {
|
|
35008
|
-
try {
|
|
35009
|
-
await this.connection.setModel(session.sessionId, options.model);
|
|
35010
|
-
} catch {
|
|
35011
|
-
}
|
|
35012
|
-
}
|
|
35013
|
-
this.sessionId = session.sessionId;
|
|
35014
|
-
this.sessionCwd = options.cwd;
|
|
35015
|
-
this.currentSystemPrompt = options.systemPrompt ?? null;
|
|
35016
|
-
this.firstPromptPending = options.sessionId ? null : this.currentSystemPrompt;
|
|
35017
|
-
return {
|
|
35018
|
-
cli: this.providerId,
|
|
35019
|
-
protocol: "acp",
|
|
35020
|
-
session
|
|
35021
|
-
};
|
|
35022
|
-
}
|
|
35023
|
-
clearSessionState() {
|
|
35024
|
-
this.sessionId = null;
|
|
35025
|
-
this.sessionCwd = null;
|
|
35026
|
-
this.currentSystemPrompt = null;
|
|
35027
|
-
this.firstPromptPending = null;
|
|
35028
|
-
}
|
|
35029
|
-
setupEventForwarding() {
|
|
35030
|
-
if (!this.connection) return;
|
|
35031
|
-
this.connection.on("stateChange", (state) => {
|
|
35032
|
-
this.emitTyped("stateChange", state);
|
|
35033
|
-
});
|
|
35034
|
-
this.connection.on("userMessageChunk", (text, sessionId) => {
|
|
35035
|
-
this.emitTyped("userMessageChunk", text, sessionId);
|
|
35036
|
-
});
|
|
35037
|
-
this.connection.on("messageChunk", (text, sessionId) => {
|
|
35038
|
-
this.emitTyped("messageChunk", text, sessionId);
|
|
35039
|
-
});
|
|
35040
|
-
this.connection.on("thoughtChunk", (text, sessionId) => {
|
|
35041
|
-
this.emitTyped("thoughtChunk", text, sessionId);
|
|
35042
|
-
});
|
|
35043
|
-
this.connection.on("toolCall", (title, status, sessionId, data) => {
|
|
35044
|
-
this.emitTyped("toolCall", title, status, sessionId, data);
|
|
35045
|
-
});
|
|
35046
|
-
this.connection.on("toolCallUpdate", (title, status, sessionId, data) => {
|
|
35047
|
-
this.emitTyped("toolCallUpdate", title, status, sessionId, data);
|
|
35048
|
-
});
|
|
35049
|
-
this.connection.on("plan", (plan, sessionId) => {
|
|
35050
|
-
this.emitTyped("plan", plan, sessionId);
|
|
35051
|
-
});
|
|
35052
|
-
this.connection.on("availableCommandsUpdate", (commands, sessionId) => {
|
|
35053
|
-
this.emitTyped("availableCommandsUpdate", commands, sessionId);
|
|
35054
|
-
});
|
|
35055
|
-
this.connection.on("sessionUpdate", (update) => {
|
|
35056
|
-
this.emitTyped("sessionUpdate", update);
|
|
35057
|
-
});
|
|
35058
|
-
this.connection.on("permissionRequest", (params, resolve3) => {
|
|
35059
|
-
this.emitTyped("permissionRequest", params, resolve3);
|
|
35060
|
-
});
|
|
35061
|
-
this.connection.on("fileRead", (params, resolve3) => {
|
|
35062
|
-
this.emitTyped("fileRead", params, resolve3);
|
|
35063
|
-
});
|
|
35064
|
-
this.connection.on("fileWrite", (params, resolve3) => {
|
|
35065
|
-
this.emitTyped("fileWrite", params, resolve3);
|
|
35066
|
-
});
|
|
35067
|
-
this.connection.on("promptComplete", (sessionId) => {
|
|
35068
|
-
this.emitTyped("promptComplete", sessionId);
|
|
35069
|
-
});
|
|
35070
|
-
this.connection.on("error", (err) => {
|
|
35071
|
-
this.emitTyped("error", err);
|
|
35072
|
-
});
|
|
35073
|
-
this.connection.on("exit", (code, signal) => {
|
|
35074
|
-
this.emitTyped("exit", code, signal);
|
|
35075
|
-
});
|
|
35076
|
-
this.connection.on("log", (msg) => {
|
|
35077
|
-
this.emitTyped("log", msg);
|
|
35078
|
-
});
|
|
35079
|
-
this.connection.on("logEntry", (entry) => {
|
|
35080
|
-
this.emitTyped("logEntry", entry);
|
|
35081
|
-
});
|
|
35082
|
-
}
|
|
35083
|
-
async cleanupFailedConnection() {
|
|
35084
|
-
if (!this.connection) {
|
|
35085
|
-
return;
|
|
35086
|
-
}
|
|
35087
|
-
try {
|
|
35088
|
-
await this.connection.disconnect();
|
|
35089
|
-
} catch {
|
|
35090
|
-
}
|
|
35091
|
-
this.connection.removeAllListeners();
|
|
35092
|
-
this.connection = null;
|
|
35093
|
-
this.clearSessionState();
|
|
35094
|
-
}
|
|
35095
|
-
buildConnectionError(error51, _recentLogs) {
|
|
35096
|
-
if (error51 instanceof Error) {
|
|
35097
|
-
return error51;
|
|
35098
|
-
}
|
|
35099
|
-
if (typeof error51 === "object" && error51 !== null) {
|
|
35100
|
-
const obj = error51;
|
|
35101
|
-
if (typeof obj.message === "string") {
|
|
35102
|
-
const code = typeof obj.code === "number" ? ` (code: ${obj.code})` : "";
|
|
35103
|
-
const data = obj.data ? ` \u2014 ${JSON.stringify(obj.data)}` : "";
|
|
35104
|
-
return new Error(`${obj.message}${code}${data}`);
|
|
35105
|
-
}
|
|
35106
|
-
return new Error(JSON.stringify(error51));
|
|
35107
|
-
}
|
|
35108
|
-
return new Error(String(error51));
|
|
35109
|
-
}
|
|
35110
|
-
};
|
|
35111
34711
|
|
|
35112
34712
|
// ../../packages/core-unified-agent/src/client/UnifiedAgent.ts
|
|
35113
34713
|
var UnifiedAgent = {
|
|
@@ -35118,8 +34718,6 @@ var UnifiedAgent = {
|
|
|
35118
34718
|
return new UnifiedClaudeAgentClient(cli);
|
|
35119
34719
|
case "codex":
|
|
35120
34720
|
return new UnifiedCodexAgentClient();
|
|
35121
|
-
case "opencode-go":
|
|
35122
|
-
return new UnifiedOpenCodeAgentClient("opencode-go");
|
|
35123
34721
|
case "cursor":
|
|
35124
34722
|
return new UnifiedCursorAgentClient();
|
|
35125
34723
|
}
|
|
@@ -35134,7 +34732,7 @@ var UnifiedAgent = {
|
|
|
35134
34732
|
const preferred = await new CliDetector().getPreferred();
|
|
35135
34733
|
if (!preferred) {
|
|
35136
34734
|
throw new Error(
|
|
35137
|
-
"\uC0AC\uC6A9 \uAC00\uB2A5\uD55C CLI\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. claude, claude-kimi, codex,
|
|
34735
|
+
"\uC0AC\uC6A9 \uAC00\uB2A5\uD55C CLI\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. claude, claude-kimi, codex, cursor \uC911 \uD558\uB098\uB97C \uC124\uCE58\uD574\uC8FC\uC138\uC694."
|
|
35138
34736
|
);
|
|
35139
34737
|
}
|
|
35140
34738
|
return this.createClient(preferred.cli);
|
|
@@ -36115,11 +35713,6 @@ var CoworkStore = class {
|
|
|
36115
35713
|
function hash2(value) {
|
|
36116
35714
|
return crypto2.createHash("sha256").update(value).digest("hex");
|
|
36117
35715
|
}
|
|
36118
|
-
|
|
36119
|
-
// ../../packages/core-agent/src/types.ts
|
|
36120
|
-
function snapshotAgentServerBindings(bindings) {
|
|
36121
|
-
return bindings === void 0 ? void 0 : Object.freeze({ ...bindings });
|
|
36122
|
-
}
|
|
36123
35716
|
function specToMcpTool(spec) {
|
|
36124
35717
|
return {
|
|
36125
35718
|
name: spec.id,
|
|
@@ -36134,8 +35727,7 @@ function installExecutorToolCallRouter(runtime, sessionToken, ctx) {
|
|
|
36134
35727
|
cwd: ctx.cwd,
|
|
36135
35728
|
sessionLabel: ctx.sessionLabel,
|
|
36136
35729
|
toolCallId,
|
|
36137
|
-
signal: ctx.signal
|
|
36138
|
-
serverBindings: ctx.serverBindings
|
|
35730
|
+
signal: ctx.signal
|
|
36139
35731
|
}).then((result) => runtime.server.resolveNextToolCall(sessionToken, toolCallId, result)).catch((err) => {
|
|
36140
35732
|
runtime.server.resolveNextToolCall(sessionToken, toolCallId, {
|
|
36141
35733
|
content: [{ type: "text", text: err instanceof Error ? err.message : String(err) }],
|
|
@@ -36223,8 +35815,7 @@ function createMcpToolRegistry() {
|
|
|
36223
35815
|
cwd: ctx?.cwd ?? process.cwd(),
|
|
36224
35816
|
sessionLabel: ctx?.sessionLabel,
|
|
36225
35817
|
toolCallId: ctx?.toolCallId,
|
|
36226
|
-
signal: ctx?.signal
|
|
36227
|
-
serverBindings: ctx?.serverBindings
|
|
35818
|
+
signal: ctx?.signal
|
|
36228
35819
|
};
|
|
36229
35820
|
const spec = primaryToolSpecs.get(name);
|
|
36230
35821
|
if (!spec) {
|
|
@@ -36785,12 +36376,10 @@ function createExecutorMcpSession(deps, toolTimeoutSeconds, request) {
|
|
|
36785
36376
|
}
|
|
36786
36377
|
assertNonEmptyExecutorTools(request.serverName, request.specs);
|
|
36787
36378
|
const token = crypto2.randomUUID();
|
|
36788
|
-
const serverBindings = snapshotAgentServerBindings(request.serverBindings);
|
|
36789
36379
|
registerExecutorSessionTools(runtime.runtime, token, [...request.specs]);
|
|
36790
36380
|
installExecutorToolCallRouter(runtime.runtime, token, {
|
|
36791
36381
|
cwd,
|
|
36792
|
-
signal: request.signal
|
|
36793
|
-
serverBindings
|
|
36382
|
+
signal: request.signal
|
|
36794
36383
|
});
|
|
36795
36384
|
return runtime.runtime.server.start().then((url2) => ({
|
|
36796
36385
|
serverName: request.serverName,
|
|
@@ -36820,7 +36409,6 @@ function issueSessionToken(deps, sessionTokensByLabel, request) {
|
|
|
36820
36409
|
cleanupExecutorServerTokens(deps, previous.tokens);
|
|
36821
36410
|
}
|
|
36822
36411
|
const tokens = [];
|
|
36823
|
-
const serverBindings = snapshotAgentServerBindings(request.serverBindings);
|
|
36824
36412
|
try {
|
|
36825
36413
|
for (const { name, runtime } of deps.runtimes) {
|
|
36826
36414
|
const tools = runtime.registry.getAllAgentTools();
|
|
@@ -36830,8 +36418,7 @@ function issueSessionToken(deps, sessionTokensByLabel, request) {
|
|
|
36830
36418
|
installExecutorToolCallRouter(runtime, token, {
|
|
36831
36419
|
cwd,
|
|
36832
36420
|
sessionLabel: label,
|
|
36833
|
-
signal: request.signal
|
|
36834
|
-
serverBindings
|
|
36421
|
+
signal: request.signal
|
|
36835
36422
|
});
|
|
36836
36423
|
tokens.push({ name, token });
|
|
36837
36424
|
}
|
|
@@ -36842,8 +36429,7 @@ function issueSessionToken(deps, sessionTokensByLabel, request) {
|
|
|
36842
36429
|
sessionTokensByLabel.set(label, {
|
|
36843
36430
|
tokens,
|
|
36844
36431
|
cwd,
|
|
36845
|
-
signal: request.signal
|
|
36846
|
-
serverBindings
|
|
36432
|
+
signal: request.signal
|
|
36847
36433
|
});
|
|
36848
36434
|
return tokens;
|
|
36849
36435
|
}
|
|
@@ -38830,573 +38416,6 @@ function sanitizeReplacementNodes(nextNodes) {
|
|
|
38830
38416
|
return result;
|
|
38831
38417
|
}
|
|
38832
38418
|
|
|
38833
|
-
// core/host/plans/plan-parse.ts
|
|
38834
|
-
var TITLE_PATTERN = /^#\s+(.+)$/;
|
|
38835
|
-
var EXECUTION_MODE_PATTERN = /^-\s*Execution mode:\s*(sequential|parallel)\b/i;
|
|
38836
|
-
var WAVE_PATTERN = /^##\s+wave\s+(\d+)\b/i;
|
|
38837
|
-
var LANE_PATTERN = /^###\s+lane\s+(.+)$/i;
|
|
38838
|
-
var LANE_ID_PATTERN = /^(W\d+-[A-Za-z0-9]+)\b/i;
|
|
38839
|
-
var LANE_BOUNDARY_PATTERN = /^#{1,3}\s/;
|
|
38840
|
-
var SECTION_HEADING_PATTERN = /^#{1,2}\s/;
|
|
38841
|
-
var CHECKBOX_PATTERN = /^\s*-\s*\[( |x|X)\]/;
|
|
38842
|
-
var FENCE_PATTERN = /^\s*(`{3,}|~{3,})/;
|
|
38843
|
-
var CLOSING_FENCE_PATTERN = /^\s*(`{3,}|~{3,})\s*$/;
|
|
38844
|
-
var TEMPLATE_SECTION_TITLES = /* @__PURE__ */ new Set([
|
|
38845
|
-
"objective",
|
|
38846
|
-
"file ownership",
|
|
38847
|
-
"waves",
|
|
38848
|
-
"qa gates",
|
|
38849
|
-
"acceptance criteria",
|
|
38850
|
-
"documentation updates",
|
|
38851
|
-
"final review loop"
|
|
38852
|
-
]);
|
|
38853
|
-
function parsePlan(content) {
|
|
38854
|
-
const lines = scanPlanLines(content.split(/\r?\n/));
|
|
38855
|
-
const title = findTitle(lines);
|
|
38856
|
-
const executionMode = findExecutionMode(lines);
|
|
38857
|
-
const waveStarts = findWaveStarts(lines);
|
|
38858
|
-
const waves = waveStarts.map(({ index, heading, lineIndex }, waveIndex) => {
|
|
38859
|
-
const nextWaveLineIndex = waveStarts[waveIndex + 1]?.lineIndex ?? lines.length;
|
|
38860
|
-
const endLineIndex = findSectionEnd(lines, lineIndex + 1, nextWaveLineIndex);
|
|
38861
|
-
const waveLines = lines.slice(lineIndex + 1, endLineIndex);
|
|
38862
|
-
const counts = countTasks(waveLines);
|
|
38863
|
-
return { index, heading, lanes: findLanes(waveLines), ...counts };
|
|
38864
|
-
});
|
|
38865
|
-
return { title, executionMode, waves, ...countTasks(lines) };
|
|
38866
|
-
}
|
|
38867
|
-
function scanPlanLines(lines) {
|
|
38868
|
-
let activeFence = null;
|
|
38869
|
-
return lines.map((text) => {
|
|
38870
|
-
if (activeFence !== null) {
|
|
38871
|
-
const closer = CLOSING_FENCE_PATTERN.exec(text)?.[1];
|
|
38872
|
-
if (closer !== void 0 && closer.startsWith(activeFence.char) && closer.length >= activeFence.length) {
|
|
38873
|
-
activeFence = null;
|
|
38874
|
-
}
|
|
38875
|
-
return { text, isFenced: true };
|
|
38876
|
-
}
|
|
38877
|
-
const marker = FENCE_PATTERN.exec(text)?.[1];
|
|
38878
|
-
if (marker !== void 0) {
|
|
38879
|
-
activeFence = { char: marker[0] ?? "`", length: marker.length };
|
|
38880
|
-
return { text, isFenced: true };
|
|
38881
|
-
}
|
|
38882
|
-
return { text, isFenced: false };
|
|
38883
|
-
});
|
|
38884
|
-
}
|
|
38885
|
-
function findTitle(lines) {
|
|
38886
|
-
for (const line of lines) {
|
|
38887
|
-
if (line.isFenced) continue;
|
|
38888
|
-
const match = TITLE_PATTERN.exec(line.text);
|
|
38889
|
-
if (!match?.[1]) continue;
|
|
38890
|
-
const heading = match[1].trim();
|
|
38891
|
-
if (TEMPLATE_SECTION_TITLES.has(heading.toLowerCase())) return null;
|
|
38892
|
-
return heading;
|
|
38893
|
-
}
|
|
38894
|
-
return null;
|
|
38895
|
-
}
|
|
38896
|
-
function findExecutionMode(lines) {
|
|
38897
|
-
for (const line of lines) {
|
|
38898
|
-
if (line.isFenced) continue;
|
|
38899
|
-
const match = EXECUTION_MODE_PATTERN.exec(line.text.trim());
|
|
38900
|
-
if (match?.[1]) return match[1].toLowerCase();
|
|
38901
|
-
}
|
|
38902
|
-
return null;
|
|
38903
|
-
}
|
|
38904
|
-
function findWaveStarts(lines) {
|
|
38905
|
-
const waves = [];
|
|
38906
|
-
for (const [lineIndex, line] of lines.entries()) {
|
|
38907
|
-
if (line.isFenced) continue;
|
|
38908
|
-
const match = WAVE_PATTERN.exec(line.text);
|
|
38909
|
-
if (!match?.[1]) continue;
|
|
38910
|
-
waves.push({
|
|
38911
|
-
index: Number(match[1]),
|
|
38912
|
-
heading: line.text.replace(/^##\s+/, ""),
|
|
38913
|
-
lineIndex
|
|
38914
|
-
});
|
|
38915
|
-
}
|
|
38916
|
-
return waves;
|
|
38917
|
-
}
|
|
38918
|
-
function findLanes(waveLines) {
|
|
38919
|
-
const laneStarts = [];
|
|
38920
|
-
for (const [lineIndex, line] of waveLines.entries()) {
|
|
38921
|
-
if (line.isFenced) continue;
|
|
38922
|
-
const match = LANE_PATTERN.exec(line.text);
|
|
38923
|
-
if (!match?.[1]) continue;
|
|
38924
|
-
const heading = match[1].trim();
|
|
38925
|
-
laneStarts.push({ heading, id: LANE_ID_PATTERN.exec(heading)?.[1]?.toUpperCase() ?? null, lineIndex });
|
|
38926
|
-
}
|
|
38927
|
-
return laneStarts.map(({ heading, id, lineIndex }, laneIndex) => {
|
|
38928
|
-
const nextLaneLineIndex = laneStarts[laneIndex + 1]?.lineIndex ?? waveLines.length;
|
|
38929
|
-
let endLineIndex = nextLaneLineIndex;
|
|
38930
|
-
for (let cursor = lineIndex + 1; cursor < nextLaneLineIndex; cursor++) {
|
|
38931
|
-
const line = waveLines[cursor];
|
|
38932
|
-
if (!line?.isFenced && LANE_BOUNDARY_PATTERN.test(line?.text ?? "")) {
|
|
38933
|
-
endLineIndex = cursor;
|
|
38934
|
-
break;
|
|
38935
|
-
}
|
|
38936
|
-
}
|
|
38937
|
-
return { id, heading, ...countTasks(waveLines.slice(lineIndex + 1, endLineIndex)) };
|
|
38938
|
-
});
|
|
38939
|
-
}
|
|
38940
|
-
function findSectionEnd(lines, startLineIndex, maxLineIndex) {
|
|
38941
|
-
for (let lineIndex = startLineIndex; lineIndex < maxLineIndex; lineIndex++) {
|
|
38942
|
-
const line = lines[lineIndex];
|
|
38943
|
-
if (!line?.isFenced && SECTION_HEADING_PATTERN.test(line?.text ?? "")) return lineIndex;
|
|
38944
|
-
}
|
|
38945
|
-
return maxLineIndex;
|
|
38946
|
-
}
|
|
38947
|
-
function countTasks(lines) {
|
|
38948
|
-
let tasksDone = 0;
|
|
38949
|
-
let tasksTotal = 0;
|
|
38950
|
-
for (const line of lines) {
|
|
38951
|
-
if (line.isFenced) continue;
|
|
38952
|
-
const match = CHECKBOX_PATTERN.exec(line.text);
|
|
38953
|
-
if (!match) continue;
|
|
38954
|
-
tasksTotal++;
|
|
38955
|
-
if (match[1] === "x" || match[1] === "X") tasksDone++;
|
|
38956
|
-
}
|
|
38957
|
-
return { tasksDone, tasksTotal };
|
|
38958
|
-
}
|
|
38959
|
-
|
|
38960
|
-
// core/host/plans/plan-store.ts
|
|
38961
|
-
var PLANS_DIRECTORY_NAME = "plans";
|
|
38962
|
-
var MARKDOWN_EXTENSION = ".md";
|
|
38963
|
-
var PLAN_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*\.md$/;
|
|
38964
|
-
var LIST_READ_CONCURRENCY = 16;
|
|
38965
|
-
var PLAN_READ_SIZE_CAP = 2 * 1024 * 1024;
|
|
38966
|
-
var PlanStoreError = class extends Error {
|
|
38967
|
-
code;
|
|
38968
|
-
constructor(code) {
|
|
38969
|
-
super(code);
|
|
38970
|
-
this.name = "PlanStoreError";
|
|
38971
|
-
this.code = code;
|
|
38972
|
-
}
|
|
38973
|
-
};
|
|
38974
|
-
async function listPlansForWorkspace(dataDir, cwd) {
|
|
38975
|
-
const plansRoot = resolvePlansRoot(dataDir, cwd, true);
|
|
38976
|
-
if (plansRoot === null) return [];
|
|
38977
|
-
let entries;
|
|
38978
|
-
try {
|
|
38979
|
-
entries = await fs10__default.promises.readdir(plansRoot.plansPath, { withFileTypes: true });
|
|
38980
|
-
} catch (error51) {
|
|
38981
|
-
throw toPlanStoreError(error51);
|
|
38982
|
-
}
|
|
38983
|
-
const names = entries.filter((entry) => (entry.isFile() || entry.isSymbolicLink()) && entry.name.endsWith(MARKDOWN_EXTENSION) && isValidPlanName(entry.name)).map((entry) => entry.name);
|
|
38984
|
-
const plans = [];
|
|
38985
|
-
for (let startIndex = 0; startIndex < names.length; startIndex += LIST_READ_CONCURRENCY) {
|
|
38986
|
-
const chunk = names.slice(startIndex, startIndex + LIST_READ_CONCURRENCY);
|
|
38987
|
-
const results = await Promise.all(chunk.map((name) => toPlanListItem(plansRoot, name).catch(() => null)));
|
|
38988
|
-
plans.push(...results.filter((plan) => plan !== null));
|
|
38989
|
-
}
|
|
38990
|
-
return plans.sort((left, right) => right.updatedAt.localeCompare(left.updatedAt));
|
|
38991
|
-
}
|
|
38992
|
-
function resolvePlansWatchDirectory(dataDir, cwd) {
|
|
38993
|
-
return resolvePlansRoot(dataDir, cwd, true)?.plansPath ?? null;
|
|
38994
|
-
}
|
|
38995
|
-
function isValidPlanName(name) {
|
|
38996
|
-
return PLAN_NAME_PATTERN.test(name) && !name.includes("..");
|
|
38997
|
-
}
|
|
38998
|
-
async function readPlanForWorkspace(dataDir, cwd, name) {
|
|
38999
|
-
const plansRoot = resolvePlansRoot(dataDir, cwd, false);
|
|
39000
|
-
if (plansRoot === null) throw new PlanStoreError("not_found");
|
|
39001
|
-
const file2 = await resolvePlanFile(plansRoot, name);
|
|
39002
|
-
if (file2.stat.size > PLAN_READ_SIZE_CAP) throw new PlanStoreError("too_large");
|
|
39003
|
-
let content;
|
|
39004
|
-
try {
|
|
39005
|
-
content = await fs10__default.promises.readFile(file2.path, "utf8");
|
|
39006
|
-
} catch (error51) {
|
|
39007
|
-
throw toPlanStoreError(error51);
|
|
39008
|
-
}
|
|
39009
|
-
const parsed = parsePlan(content);
|
|
39010
|
-
return {
|
|
39011
|
-
name,
|
|
39012
|
-
title: parsed.title ?? name,
|
|
39013
|
-
executionMode: parsed.executionMode,
|
|
39014
|
-
updatedAt: file2.stat.mtime.toISOString(),
|
|
39015
|
-
content,
|
|
39016
|
-
waves: parsed.waves,
|
|
39017
|
-
tasksDone: parsed.tasksDone,
|
|
39018
|
-
tasksTotal: parsed.tasksTotal
|
|
39019
|
-
};
|
|
39020
|
-
}
|
|
39021
|
-
async function deletePlanForWorkspace(dataDir, cwd, name) {
|
|
39022
|
-
const plansRoot = resolvePlansRoot(dataDir, cwd, false);
|
|
39023
|
-
if (plansRoot === null) throw new PlanStoreError("not_found");
|
|
39024
|
-
const file2 = await resolvePlanFile(plansRoot, name);
|
|
39025
|
-
try {
|
|
39026
|
-
await fs10__default.promises.unlink(file2.path);
|
|
39027
|
-
} catch (error51) {
|
|
39028
|
-
throw toPlanStoreError(error51);
|
|
39029
|
-
}
|
|
39030
|
-
}
|
|
39031
|
-
async function toPlanListItem(plansRoot, name) {
|
|
39032
|
-
const file2 = await resolvePlanFile(plansRoot, name);
|
|
39033
|
-
if (file2.stat.size > PLAN_READ_SIZE_CAP) {
|
|
39034
|
-
return {
|
|
39035
|
-
name,
|
|
39036
|
-
title: name,
|
|
39037
|
-
executionMode: null,
|
|
39038
|
-
waveCount: 0,
|
|
39039
|
-
tasksDone: 0,
|
|
39040
|
-
tasksTotal: 0,
|
|
39041
|
-
updatedAt: file2.stat.mtime.toISOString(),
|
|
39042
|
-
sizeBytes: file2.stat.size
|
|
39043
|
-
};
|
|
39044
|
-
}
|
|
39045
|
-
const content = await fs10__default.promises.readFile(file2.path, "utf8").catch((error51) => {
|
|
39046
|
-
throw toPlanStoreError(error51);
|
|
39047
|
-
});
|
|
39048
|
-
const parsed = parsePlan(content);
|
|
39049
|
-
return {
|
|
39050
|
-
name,
|
|
39051
|
-
title: parsed.title ?? name,
|
|
39052
|
-
executionMode: parsed.executionMode,
|
|
39053
|
-
waveCount: parsed.waves.length,
|
|
39054
|
-
tasksDone: parsed.tasksDone,
|
|
39055
|
-
tasksTotal: parsed.tasksTotal,
|
|
39056
|
-
updatedAt: file2.stat.mtime.toISOString(),
|
|
39057
|
-
sizeBytes: file2.stat.size
|
|
39058
|
-
};
|
|
39059
|
-
}
|
|
39060
|
-
function resolvePlansRoot(dataDir, cwd, allowMissing) {
|
|
39061
|
-
let workspace;
|
|
39062
|
-
try {
|
|
39063
|
-
workspace = findWorkspaceDirectory(dataDir, cwd);
|
|
39064
|
-
} catch {
|
|
39065
|
-
throw new PlanStoreError("unsafe_path");
|
|
39066
|
-
}
|
|
39067
|
-
if (!workspace) {
|
|
39068
|
-
if (allowMissing) return null;
|
|
39069
|
-
throw new PlanStoreError("not_found");
|
|
39070
|
-
}
|
|
39071
|
-
const plansPath = path23__default.join(workspace.path, PLANS_DIRECTORY_NAME);
|
|
39072
|
-
assertWithinRoot(workspace.path, plansPath);
|
|
39073
|
-
const stat4 = safeLstat(plansPath);
|
|
39074
|
-
if (!stat4) {
|
|
39075
|
-
if (allowMissing) return null;
|
|
39076
|
-
throw new PlanStoreError("not_found");
|
|
39077
|
-
}
|
|
39078
|
-
if (!stat4.isDirectory() || stat4.isSymbolicLink()) throw new PlanStoreError("unsafe_path");
|
|
39079
|
-
return { plansPath, workspacePath: workspace.path };
|
|
39080
|
-
}
|
|
39081
|
-
async function resolvePlanFile(plansRoot, name) {
|
|
39082
|
-
try {
|
|
39083
|
-
const candidatePath = path23__default.resolve(plansRoot.plansPath, name);
|
|
39084
|
-
assertWithinRoot(plansRoot.plansPath, candidatePath);
|
|
39085
|
-
assertWithinRoot(plansRoot.workspacePath, candidatePath);
|
|
39086
|
-
const stat4 = safeLstat(candidatePath);
|
|
39087
|
-
if (stat4?.isSymbolicLink()) throw new PlanStoreError("unsafe_path");
|
|
39088
|
-
if (!stat4?.isFile()) throw new PlanStoreError("not_found");
|
|
39089
|
-
return { path: candidatePath, stat: stat4 };
|
|
39090
|
-
} catch (error51) {
|
|
39091
|
-
if (error51 instanceof PlanStoreError) throw error51;
|
|
39092
|
-
throw new PlanStoreError("unsafe_path");
|
|
39093
|
-
}
|
|
39094
|
-
}
|
|
39095
|
-
function toPlanStoreError(error51) {
|
|
39096
|
-
if (error51 instanceof PlanStoreError) return error51;
|
|
39097
|
-
return new PlanStoreError("not_found");
|
|
39098
|
-
}
|
|
39099
|
-
var TheaterRootError = class extends Error {
|
|
39100
|
-
code;
|
|
39101
|
-
constructor(code) {
|
|
39102
|
-
super(code);
|
|
39103
|
-
this.code = code;
|
|
39104
|
-
}
|
|
39105
|
-
};
|
|
39106
|
-
async function resolveTheaterRoot(theaterRoot) {
|
|
39107
|
-
const nominalRoot = path23__default.resolve(theaterRoot);
|
|
39108
|
-
let realRoot;
|
|
39109
|
-
try {
|
|
39110
|
-
realRoot = await fs10__default.promises.realpath(nominalRoot);
|
|
39111
|
-
} catch (error51) {
|
|
39112
|
-
throw mapFsError(error51);
|
|
39113
|
-
}
|
|
39114
|
-
let stat4;
|
|
39115
|
-
try {
|
|
39116
|
-
stat4 = await fs10__default.promises.stat(realRoot);
|
|
39117
|
-
} catch (error51) {
|
|
39118
|
-
throw mapFsError(error51);
|
|
39119
|
-
}
|
|
39120
|
-
if (!stat4.isDirectory()) throw new TheaterRootError("invalid_path");
|
|
39121
|
-
return { realRoot };
|
|
39122
|
-
}
|
|
39123
|
-
function mapFsError(error51) {
|
|
39124
|
-
const code = error51.code;
|
|
39125
|
-
if (code === "ENOENT" || code === "ENOTDIR") return new TheaterRootError("not_found");
|
|
39126
|
-
if (code === "EACCES" || code === "EPERM") return new TheaterRootError("forbidden");
|
|
39127
|
-
return new TheaterRootError("invalid_path");
|
|
39128
|
-
}
|
|
39129
|
-
|
|
39130
|
-
// core/host/plans/routes.ts
|
|
39131
|
-
function createPlansRouter(deps) {
|
|
39132
|
-
return async function handlePlansRoute(context) {
|
|
39133
|
-
const { req, res, pathname } = context;
|
|
39134
|
-
if (pathname === "/api/v1/plans/list") {
|
|
39135
|
-
await handlePlansList(req, res, deps);
|
|
39136
|
-
return true;
|
|
39137
|
-
}
|
|
39138
|
-
if (pathname === "/api/v1/plans/read") {
|
|
39139
|
-
await handlePlansRead(req, res, deps);
|
|
39140
|
-
return true;
|
|
39141
|
-
}
|
|
39142
|
-
if (pathname === "/api/v1/plans/delete") {
|
|
39143
|
-
await handlePlansDelete(req, res, deps);
|
|
39144
|
-
return true;
|
|
39145
|
-
}
|
|
39146
|
-
if (pathname === "/api/v1/plans/search") {
|
|
39147
|
-
await handlePlansSearch(req, res, deps);
|
|
39148
|
-
return true;
|
|
39149
|
-
}
|
|
39150
|
-
if (pathname === "/api/v1/plans/events") {
|
|
39151
|
-
await handlePlansEvents(req, res, deps);
|
|
39152
|
-
return true;
|
|
39153
|
-
}
|
|
39154
|
-
return false;
|
|
39155
|
-
};
|
|
39156
|
-
}
|
|
39157
|
-
async function handlePlansSearch(req, res, deps) {
|
|
39158
|
-
if (req.method !== "POST") {
|
|
39159
|
-
deps.writeJson(res, 405, { error: "Method not allowed" });
|
|
39160
|
-
return;
|
|
39161
|
-
}
|
|
39162
|
-
if (!deps.isAuthorized(req)) {
|
|
39163
|
-
deps.writeJson(res, 401, { error: "unauthorized" });
|
|
39164
|
-
return;
|
|
39165
|
-
}
|
|
39166
|
-
const body2 = await deps.readJsonBody(req);
|
|
39167
|
-
if (!isPlainObject2(body2) || typeof body2.theaterId !== "string" || typeof body2.query !== "string" || body2.query.trim() === "" || !Number.isInteger(body2.limit) || body2.limit < 1 || body2.limit > 8 || "relPath" in body2) {
|
|
39168
|
-
deps.writeJson(res, 400, { error: "invalid_request" });
|
|
39169
|
-
return;
|
|
39170
|
-
}
|
|
39171
|
-
const theaterPath = deps.resolveTheaterPath(body2.theaterId);
|
|
39172
|
-
if (!theaterPath) {
|
|
39173
|
-
deps.writeJson(res, 404, { error: "theater_not_found" });
|
|
39174
|
-
return;
|
|
39175
|
-
}
|
|
39176
|
-
try {
|
|
39177
|
-
const context = await resolveTheaterRoot(theaterPath);
|
|
39178
|
-
const tokens = body2.query.trim().toLocaleLowerCase().split(/\s+/).filter(Boolean);
|
|
39179
|
-
const plans = (await listPlansForWorkspace(deps.dataDir, context.realRoot)).filter((plan) => {
|
|
39180
|
-
const text = `${plan.name}
|
|
39181
|
-
${plan.title}`.toLocaleLowerCase();
|
|
39182
|
-
return tokens.every((token) => text.includes(token));
|
|
39183
|
-
}).slice(0, body2.limit).map((plan) => ({ name: plan.name, title: plan.title }));
|
|
39184
|
-
deps.writeJson(res, 200, { plans });
|
|
39185
|
-
} catch (error51) {
|
|
39186
|
-
writePlanStoreError(res, deps, error51);
|
|
39187
|
-
}
|
|
39188
|
-
}
|
|
39189
|
-
async function handlePlansEvents(req, res, deps) {
|
|
39190
|
-
if (req.method !== "GET") {
|
|
39191
|
-
deps.writeJson(res, 405, { error: "Method not allowed" });
|
|
39192
|
-
return;
|
|
39193
|
-
}
|
|
39194
|
-
if (!deps.isEventsAuthorized?.(req)) {
|
|
39195
|
-
deps.writeJson(res, 401, { error: "unauthorized" });
|
|
39196
|
-
return;
|
|
39197
|
-
}
|
|
39198
|
-
const theaterId = readEventsTheaterId(req);
|
|
39199
|
-
if (!theaterId) {
|
|
39200
|
-
deps.writeJson(res, 400, { error: "invalid_request" });
|
|
39201
|
-
return;
|
|
39202
|
-
}
|
|
39203
|
-
const theaterPath = deps.resolveTheaterPath(theaterId);
|
|
39204
|
-
if (!theaterPath) {
|
|
39205
|
-
deps.writeJson(res, 404, { error: "theater_not_found" });
|
|
39206
|
-
return;
|
|
39207
|
-
}
|
|
39208
|
-
try {
|
|
39209
|
-
const context = await resolveTheaterRoot(theaterPath);
|
|
39210
|
-
const watchPath = resolvePlansWatchDirectory(deps.dataDir, context.realRoot);
|
|
39211
|
-
if (!watchPath || !deps.subscribeToChanges) {
|
|
39212
|
-
deps.writeJson(res, 404, { error: "not_found" });
|
|
39213
|
-
return;
|
|
39214
|
-
}
|
|
39215
|
-
deps.subscribeToChanges(res, watchPath);
|
|
39216
|
-
} catch (error51) {
|
|
39217
|
-
writePlanStoreError(res, deps, error51);
|
|
39218
|
-
}
|
|
39219
|
-
}
|
|
39220
|
-
function readEventsTheaterId(req) {
|
|
39221
|
-
const url2 = new URL(req.url ?? "/", "http://localhost");
|
|
39222
|
-
const theaterIds = url2.searchParams.getAll("theaterId");
|
|
39223
|
-
if (theaterIds.length !== 1 || theaterIds[0] === "" || [...url2.searchParams.keys()].some((key) => key !== "theaterId")) return null;
|
|
39224
|
-
return theaterIds[0] ?? null;
|
|
39225
|
-
}
|
|
39226
|
-
async function handlePlansList(req, res, deps) {
|
|
39227
|
-
if (req.method !== "POST") {
|
|
39228
|
-
deps.writeJson(res, 405, { error: "Method not allowed" });
|
|
39229
|
-
return;
|
|
39230
|
-
}
|
|
39231
|
-
if (!deps.isAuthorized(req)) {
|
|
39232
|
-
deps.writeJson(res, 401, { error: "unauthorized" });
|
|
39233
|
-
return;
|
|
39234
|
-
}
|
|
39235
|
-
const body2 = await deps.readJsonBody(req);
|
|
39236
|
-
if (!isPlainObject2(body2) || typeof body2.theaterId !== "string" || "relPath" in body2) {
|
|
39237
|
-
deps.writeJson(res, 400, { error: "invalid_request" });
|
|
39238
|
-
return;
|
|
39239
|
-
}
|
|
39240
|
-
const theaterPath = deps.resolveTheaterPath(body2.theaterId);
|
|
39241
|
-
if (!theaterPath) {
|
|
39242
|
-
deps.writeJson(res, 404, { error: "theater_not_found" });
|
|
39243
|
-
return;
|
|
39244
|
-
}
|
|
39245
|
-
try {
|
|
39246
|
-
const context = await resolveTheaterRoot(theaterPath);
|
|
39247
|
-
deps.writeJson(res, 200, { plans: await listPlansForWorkspace(deps.dataDir, context.realRoot) });
|
|
39248
|
-
} catch (error51) {
|
|
39249
|
-
writePlanStoreError(res, deps, error51);
|
|
39250
|
-
}
|
|
39251
|
-
}
|
|
39252
|
-
async function handlePlansRead(req, res, deps) {
|
|
39253
|
-
if (req.method !== "POST") {
|
|
39254
|
-
deps.writeJson(res, 405, { error: "Method not allowed" });
|
|
39255
|
-
return;
|
|
39256
|
-
}
|
|
39257
|
-
if (!deps.isAuthorized(req)) {
|
|
39258
|
-
deps.writeJson(res, 401, { error: "unauthorized" });
|
|
39259
|
-
return;
|
|
39260
|
-
}
|
|
39261
|
-
const body2 = await deps.readJsonBody(req);
|
|
39262
|
-
if (!isPlainObject2(body2) || typeof body2.theaterId !== "string" || "relPath" in body2) {
|
|
39263
|
-
deps.writeJson(res, 400, { error: "invalid_request" });
|
|
39264
|
-
return;
|
|
39265
|
-
}
|
|
39266
|
-
if (typeof body2.name !== "string" || !isValidPlanName(body2.name)) {
|
|
39267
|
-
deps.writeJson(res, 400, { error: "invalid_name" });
|
|
39268
|
-
return;
|
|
39269
|
-
}
|
|
39270
|
-
const theaterPath = deps.resolveTheaterPath(body2.theaterId);
|
|
39271
|
-
if (!theaterPath) {
|
|
39272
|
-
deps.writeJson(res, 404, { error: "theater_not_found" });
|
|
39273
|
-
return;
|
|
39274
|
-
}
|
|
39275
|
-
try {
|
|
39276
|
-
const context = await resolveTheaterRoot(theaterPath);
|
|
39277
|
-
deps.writeJson(res, 200, await readPlanForWorkspace(deps.dataDir, context.realRoot, body2.name));
|
|
39278
|
-
} catch (error51) {
|
|
39279
|
-
writePlanStoreError(res, deps, error51);
|
|
39280
|
-
}
|
|
39281
|
-
}
|
|
39282
|
-
async function handlePlansDelete(req, res, deps) {
|
|
39283
|
-
if (req.method !== "POST") {
|
|
39284
|
-
deps.writeJson(res, 405, { error: "Method not allowed" });
|
|
39285
|
-
return;
|
|
39286
|
-
}
|
|
39287
|
-
if (!deps.isAuthorized(req)) {
|
|
39288
|
-
deps.writeJson(res, 401, { error: "unauthorized" });
|
|
39289
|
-
return;
|
|
39290
|
-
}
|
|
39291
|
-
const body2 = await deps.readJsonBody(req);
|
|
39292
|
-
if (!isPlainObject2(body2) || typeof body2.theaterId !== "string" || "relPath" in body2) {
|
|
39293
|
-
deps.writeJson(res, 400, { error: "invalid_request" });
|
|
39294
|
-
return;
|
|
39295
|
-
}
|
|
39296
|
-
if (typeof body2.name !== "string" || !isValidPlanName(body2.name)) {
|
|
39297
|
-
deps.writeJson(res, 400, { error: "invalid_name" });
|
|
39298
|
-
return;
|
|
39299
|
-
}
|
|
39300
|
-
const theaterPath = deps.resolveTheaterPath(body2.theaterId);
|
|
39301
|
-
if (!theaterPath) {
|
|
39302
|
-
deps.writeJson(res, 404, { error: "theater_not_found" });
|
|
39303
|
-
return;
|
|
39304
|
-
}
|
|
39305
|
-
try {
|
|
39306
|
-
const context = await resolveTheaterRoot(theaterPath);
|
|
39307
|
-
await deletePlanForWorkspace(deps.dataDir, context.realRoot, body2.name);
|
|
39308
|
-
deps.writeJson(res, 200, { deleted: true });
|
|
39309
|
-
} catch (error51) {
|
|
39310
|
-
writePlanStoreError(res, deps, error51);
|
|
39311
|
-
}
|
|
39312
|
-
}
|
|
39313
|
-
function isPlainObject2(value) {
|
|
39314
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
39315
|
-
}
|
|
39316
|
-
function writePlanStoreError(res, deps, error51) {
|
|
39317
|
-
if (error51 instanceof TheaterRootError) {
|
|
39318
|
-
const httpStatus2 = error51.code === "forbidden" ? 403 : error51.code === "not_found" ? 404 : 400;
|
|
39319
|
-
deps.writeJson(res, httpStatus2, { error: error51.code });
|
|
39320
|
-
return;
|
|
39321
|
-
}
|
|
39322
|
-
if (!(error51 instanceof PlanStoreError)) throw error51;
|
|
39323
|
-
const httpStatus = error51.code === "unsafe_path" ? 403 : error51.code === "too_large" ? 413 : 404;
|
|
39324
|
-
deps.writeJson(res, httpStatus, { error: error51.code });
|
|
39325
|
-
}
|
|
39326
|
-
var PLANS_WATCH_DEBOUNCE_MS = 200;
|
|
39327
|
-
function createPlansWatcherRegistry(watcherFactory = (watchPath, options, listener) => fs10__default.watch(watchPath, options, listener), debounceMs = PLANS_WATCH_DEBOUNCE_MS, directoryIdentity = (watchPath) => {
|
|
39328
|
-
try {
|
|
39329
|
-
const stat4 = fs10__default.statSync(watchPath);
|
|
39330
|
-
return { dev: stat4.dev, ino: stat4.ino };
|
|
39331
|
-
} catch {
|
|
39332
|
-
return null;
|
|
39333
|
-
}
|
|
39334
|
-
}) {
|
|
39335
|
-
const entries = /* @__PURE__ */ new Map();
|
|
39336
|
-
return {
|
|
39337
|
-
subscribe(watchPath, onChange, onClose) {
|
|
39338
|
-
let entry = entries.get(watchPath);
|
|
39339
|
-
if (!entry) {
|
|
39340
|
-
entry = createEntry(watchPath);
|
|
39341
|
-
if (!entry) {
|
|
39342
|
-
onClose();
|
|
39343
|
-
return () => {
|
|
39344
|
-
};
|
|
39345
|
-
}
|
|
39346
|
-
entries.set(watchPath, entry);
|
|
39347
|
-
}
|
|
39348
|
-
const subscriber = { onChange, onClose };
|
|
39349
|
-
entry.subscribers.add(subscriber);
|
|
39350
|
-
let unsubscribed = false;
|
|
39351
|
-
return () => {
|
|
39352
|
-
if (unsubscribed) return;
|
|
39353
|
-
unsubscribed = true;
|
|
39354
|
-
entry.subscribers.delete(subscriber);
|
|
39355
|
-
if (entry.subscribers.size !== 0) return;
|
|
39356
|
-
closeEntry(watchPath, entry);
|
|
39357
|
-
};
|
|
39358
|
-
}
|
|
39359
|
-
};
|
|
39360
|
-
function createEntry(watchPath) {
|
|
39361
|
-
const subscribers = /* @__PURE__ */ new Set();
|
|
39362
|
-
let entry;
|
|
39363
|
-
try {
|
|
39364
|
-
const watcher = watcherFactory(watchPath, { recursive: false }, () => {
|
|
39365
|
-
if (entry.closed) return;
|
|
39366
|
-
const current = directoryIdentity(watchPath);
|
|
39367
|
-
if (!current || entry.identity === null || current.dev !== entry.identity.dev || current.ino !== entry.identity.ino) {
|
|
39368
|
-
closeEntry(watchPath, entry, true);
|
|
39369
|
-
return;
|
|
39370
|
-
}
|
|
39371
|
-
if (entry.timer) clearTimeout(entry.timer);
|
|
39372
|
-
entry.timer = setTimeout(() => {
|
|
39373
|
-
entry.timer = null;
|
|
39374
|
-
for (const subscriber of entry.subscribers) subscriber.onChange();
|
|
39375
|
-
}, debounceMs);
|
|
39376
|
-
});
|
|
39377
|
-
entry = { watcher, subscribers, identity: directoryIdentity(watchPath), timer: null, closed: false };
|
|
39378
|
-
watcher.on("error", () => closeEntry(watchPath, entry, true));
|
|
39379
|
-
return entry;
|
|
39380
|
-
} catch {
|
|
39381
|
-
return null;
|
|
39382
|
-
}
|
|
39383
|
-
}
|
|
39384
|
-
function closeEntry(watchPath, entry, notifySubscribers = false) {
|
|
39385
|
-
if (entry.closed) return;
|
|
39386
|
-
entry.closed = true;
|
|
39387
|
-
if (entry.timer) clearTimeout(entry.timer);
|
|
39388
|
-
entry.timer = null;
|
|
39389
|
-
try {
|
|
39390
|
-
entry.watcher.close();
|
|
39391
|
-
} catch {
|
|
39392
|
-
}
|
|
39393
|
-
if (entries.get(watchPath) === entry) entries.delete(watchPath);
|
|
39394
|
-
if (notifySubscribers) {
|
|
39395
|
-
for (const subscriber of entry.subscribers) subscriber.onClose();
|
|
39396
|
-
}
|
|
39397
|
-
}
|
|
39398
|
-
}
|
|
39399
|
-
|
|
39400
38419
|
// sdk/version.ts
|
|
39401
38420
|
var SDK_API_VERSION = 1;
|
|
39402
38421
|
|
|
@@ -40298,7 +39317,7 @@ function serveFallbackIndex(req, res, consoleRoot, getActiveTheme) {
|
|
|
40298
39317
|
function injectActiveTheme(html, getActiveTheme) {
|
|
40299
39318
|
if (!getActiveTheme) return html;
|
|
40300
39319
|
const theme = getActiveTheme();
|
|
40301
|
-
if (theme !== "instrument" && theme !== "maritime" && theme !== "carbon" && theme !== "
|
|
39320
|
+
if (theme !== "instrument" && theme !== "maritime" && theme !== "carbon" && theme !== "whites") {
|
|
40302
39321
|
return html;
|
|
40303
39322
|
}
|
|
40304
39323
|
return html.replace('data-theme="instrument"', `data-theme="${theme}" data-theme-source="server"`);
|
|
@@ -40375,7 +39394,7 @@ async function statDirectory(targetPath, stat4) {
|
|
|
40375
39394
|
try {
|
|
40376
39395
|
return await stat4(targetPath);
|
|
40377
39396
|
} catch (error51) {
|
|
40378
|
-
throw
|
|
39397
|
+
throw mapFsError(error51);
|
|
40379
39398
|
}
|
|
40380
39399
|
}
|
|
40381
39400
|
async function collectDirectoryEntries(targetPath, opendir, stat4, entries) {
|
|
@@ -40392,7 +39411,7 @@ async function collectDirectoryEntries(targetPath, opendir, stat4, entries) {
|
|
|
40392
39411
|
}
|
|
40393
39412
|
return false;
|
|
40394
39413
|
} catch (error51) {
|
|
40395
|
-
throw
|
|
39414
|
+
throw mapFsError(error51);
|
|
40396
39415
|
} finally {
|
|
40397
39416
|
await directory.close();
|
|
40398
39417
|
}
|
|
@@ -40401,7 +39420,7 @@ async function openDirectory(targetPath, opendir) {
|
|
|
40401
39420
|
try {
|
|
40402
39421
|
return await opendir(targetPath);
|
|
40403
39422
|
} catch (error51) {
|
|
40404
|
-
throw
|
|
39423
|
+
throw mapFsError(error51);
|
|
40405
39424
|
}
|
|
40406
39425
|
}
|
|
40407
39426
|
async function toTheaterFolderEntry(targetPath, dirent, stat4) {
|
|
@@ -40419,7 +39438,7 @@ async function statSymlinkDirectory(entryPath, stat4) {
|
|
|
40419
39438
|
return false;
|
|
40420
39439
|
}
|
|
40421
39440
|
}
|
|
40422
|
-
function
|
|
39441
|
+
function mapFsError(error51) {
|
|
40423
39442
|
const code = error51.code;
|
|
40424
39443
|
if (code === "EACCES" || code === "EPERM") return new TheaterFolderListError("forbidden");
|
|
40425
39444
|
if (code === "ENOENT" || code === "ENOTDIR") return new TheaterFolderListError("not_found");
|
|
@@ -41148,34 +40167,6 @@ var SERVER_API_CATALOG = [
|
|
|
41148
40167
|
category: "Observer",
|
|
41149
40168
|
gate: "origin-write"
|
|
41150
40169
|
},
|
|
41151
|
-
{
|
|
41152
|
-
method: "POST",
|
|
41153
|
-
path: "/api/v1/plans/list",
|
|
41154
|
-
summary: "Theater\uC758 \uC2E4\uD589 \uACC4\uD68D \uBAA9\uB85D\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4.",
|
|
41155
|
-
category: "Observer",
|
|
41156
|
-
gate: "origin-write"
|
|
41157
|
-
},
|
|
41158
|
-
{
|
|
41159
|
-
method: "POST",
|
|
41160
|
-
path: "/api/v1/plans/read",
|
|
41161
|
-
summary: "\uC2E4\uD589 \uACC4\uD68D \uBB38\uC11C\uB97C \uC870\uD68C\uD569\uB2C8\uB2E4.",
|
|
41162
|
-
category: "Observer",
|
|
41163
|
-
gate: "origin-write"
|
|
41164
|
-
},
|
|
41165
|
-
{
|
|
41166
|
-
method: "POST",
|
|
41167
|
-
path: "/api/v1/plans/delete",
|
|
41168
|
-
summary: "\uC2E4\uD589 \uACC4\uD68D \uD30C\uC77C\uC744 \uC0AD\uC81C\uD569\uB2C8\uB2E4.",
|
|
41169
|
-
category: "Observer",
|
|
41170
|
-
gate: "origin-write"
|
|
41171
|
-
},
|
|
41172
|
-
{
|
|
41173
|
-
method: "GET",
|
|
41174
|
-
path: "/api/v1/plans/events",
|
|
41175
|
-
summary: "Theater \uC2E4\uD589 \uACC4\uD68D \uBCC0\uACBD \uC2E0\uD638\uB97C \uC2A4\uD2B8\uB9AC\uBC0D\uD569\uB2C8\uB2E4.",
|
|
41176
|
-
category: "Observer",
|
|
41177
|
-
gate: "origin-write"
|
|
41178
|
-
},
|
|
41179
40170
|
{
|
|
41180
40171
|
method: "POST",
|
|
41181
40172
|
path: "/api/v1/updates/apply",
|
|
@@ -41458,40 +40449,6 @@ function createConsoleServer(deps = {}) {
|
|
|
41458
40449
|
systemFonts: deps.systemFonts ?? createSystemFontsService(),
|
|
41459
40450
|
writeJson
|
|
41460
40451
|
});
|
|
41461
|
-
const plansWatcherRegistry = createPlansWatcherRegistry();
|
|
41462
|
-
const plansRouter = createPlansRouter({
|
|
41463
|
-
dataDir: fleetDataDir,
|
|
41464
|
-
isAuthorized: isTerminalAuthorized,
|
|
41465
|
-
// events는 same-origin EventSource가 Origin 헤더를 보내지 않으므로 exact-Origin 게이트를 쓸 수 없다.
|
|
41466
|
-
// list/read와 동일한 terminal Origin 게이트(무-Origin 허용·존재 시 정확 일치)를 적용한다.
|
|
41467
|
-
isEventsAuthorized: isTerminalAuthorized,
|
|
41468
|
-
readJsonBody,
|
|
41469
|
-
resolveTheaterPath: (theaterId) => theaters.get(theaterId)?.realpath ?? null,
|
|
41470
|
-
writeJson,
|
|
41471
|
-
subscribeToChanges: (res, watchPath) => {
|
|
41472
|
-
res.writeHead(200, withSecurityHeaders2({
|
|
41473
|
-
"Content-Type": "text/event-stream",
|
|
41474
|
-
"Cache-Control": "no-cache",
|
|
41475
|
-
"Connection": "keep-alive"
|
|
41476
|
-
}));
|
|
41477
|
-
res.write(":connected\n\n");
|
|
41478
|
-
const unsubscribe = plansWatcherRegistry.subscribe(
|
|
41479
|
-
watchPath,
|
|
41480
|
-
() => {
|
|
41481
|
-
res.write(encodeSseData("plans-changed", {}));
|
|
41482
|
-
},
|
|
41483
|
-
() => res.end()
|
|
41484
|
-
);
|
|
41485
|
-
let cleanedUp = false;
|
|
41486
|
-
const cleanup = () => {
|
|
41487
|
-
if (cleanedUp) return;
|
|
41488
|
-
cleanedUp = true;
|
|
41489
|
-
unsubscribe();
|
|
41490
|
-
};
|
|
41491
|
-
res.on("close", cleanup);
|
|
41492
|
-
res.on("error", cleanup);
|
|
41493
|
-
}
|
|
41494
|
-
});
|
|
41495
40452
|
const codexWorkspaceRouter = createCodexWorkspaceRouter({
|
|
41496
40453
|
getTheater: (theaterId) => theaters.get(theaterId),
|
|
41497
40454
|
isAuthorized: isTerminalAuthorized,
|
|
@@ -41592,10 +40549,6 @@ function createConsoleServer(deps = {}) {
|
|
|
41592
40549
|
runAsyncHandler(handleTheaterFolderGrants(req, res), res);
|
|
41593
40550
|
return;
|
|
41594
40551
|
}
|
|
41595
|
-
if (pathname === "/api/v1/plans/list" || pathname === "/api/v1/plans/read" || pathname === "/api/v1/plans/delete" || pathname === "/api/v1/plans/events") {
|
|
41596
|
-
runAsyncBooleanHandler(plansRouter({ req, res, pathname }), res, () => false);
|
|
41597
|
-
return;
|
|
41598
|
-
}
|
|
41599
40552
|
const restoreMatch = pathname.match(/^\/api\/v1\/deletions\/([^/]+)\/restore$/);
|
|
41600
40553
|
if (restoreMatch) {
|
|
41601
40554
|
runAsyncHandler(handleDeferredDeletionRestore(req, res, decodeURIComponent(restoreMatch[1] ?? "")), res);
|
|
@@ -41690,7 +40643,7 @@ function createConsoleServer(deps = {}) {
|
|
|
41690
40643
|
return;
|
|
41691
40644
|
}
|
|
41692
40645
|
const body2 = await readJsonBody(req);
|
|
41693
|
-
if (!
|
|
40646
|
+
if (!isPlainObject2(body2) || body2.path !== void 0 && body2.path !== null && typeof body2.path !== "string") {
|
|
41694
40647
|
writeJson(res, 400, { error: "invalid_path" });
|
|
41695
40648
|
return;
|
|
41696
40649
|
}
|
|
@@ -41715,7 +40668,7 @@ function createConsoleServer(deps = {}) {
|
|
|
41715
40668
|
return;
|
|
41716
40669
|
}
|
|
41717
40670
|
const body2 = await readJsonBody(req);
|
|
41718
|
-
if (!
|
|
40671
|
+
if (!isPlainObject2(body2) || typeof body2.path !== "string") {
|
|
41719
40672
|
writeJson(res, 400, { error: "invalid_folder" });
|
|
41720
40673
|
return;
|
|
41721
40674
|
}
|
|
@@ -41739,7 +40692,7 @@ function createConsoleServer(deps = {}) {
|
|
|
41739
40692
|
return;
|
|
41740
40693
|
}
|
|
41741
40694
|
const body2 = await readJsonBody(req);
|
|
41742
|
-
if (!
|
|
40695
|
+
if (!isPlainObject2(body2) || typeof body2.folderGrantId !== "string") {
|
|
41743
40696
|
writeJson(res, 400, { error: "invalid_folder_grant" });
|
|
41744
40697
|
return;
|
|
41745
40698
|
}
|
|
@@ -41769,7 +40722,7 @@ function createConsoleServer(deps = {}) {
|
|
|
41769
40722
|
}
|
|
41770
40723
|
if (req.method === "PATCH") {
|
|
41771
40724
|
const body2 = await readJsonBody(req);
|
|
41772
|
-
if (!
|
|
40725
|
+
if (!isPlainObject2(body2) || typeof body2.order !== "number" || !Number.isInteger(body2.order) || body2.order < 0) {
|
|
41773
40726
|
writeJson(res, 400, { error: "invalid_theater_order" });
|
|
41774
40727
|
return;
|
|
41775
40728
|
}
|
|
@@ -41886,7 +40839,7 @@ function createConsoleServer(deps = {}) {
|
|
|
41886
40839
|
writeJson(res, 400, { error: "invalid_update_apply_body" });
|
|
41887
40840
|
return;
|
|
41888
40841
|
}
|
|
41889
|
-
if (body2 !== null && (!
|
|
40842
|
+
if (body2 !== null && (!isPlainObject2(body2) || hasForbiddenUpdateApplyBodyKeys(body2))) {
|
|
41890
40843
|
writeJson(res, 400, { error: "invalid_update_apply_body" });
|
|
41891
40844
|
return;
|
|
41892
40845
|
}
|
|
@@ -42281,7 +41234,7 @@ function theaterFolderListStatus(error51) {
|
|
|
42281
41234
|
if (error51.code === "not_found") return 404;
|
|
42282
41235
|
return 400;
|
|
42283
41236
|
}
|
|
42284
|
-
function
|
|
41237
|
+
function isPlainObject2(value) {
|
|
42285
41238
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
42286
41239
|
}
|
|
42287
41240
|
function hasForbiddenUpdateApplyBodyKeys(body2) {
|
|
@@ -42291,7 +41244,7 @@ function isValidConsoleStaticPort3(value) {
|
|
|
42291
41244
|
return typeof value === "number" && Number.isInteger(value) && value >= MIN_CONSOLE_STATIC_PORT3 && value <= MAX_CONSOLE_STATIC_PORT3;
|
|
42292
41245
|
}
|
|
42293
41246
|
function sanitizeLaunchKind(value) {
|
|
42294
|
-
if (!
|
|
41247
|
+
if (!isPlainObject2(value) || typeof value.id !== "string" || typeof value.type !== "string" || typeof value.title !== "string") return null;
|
|
42295
41248
|
return {
|
|
42296
41249
|
id: value.id,
|
|
42297
41250
|
type: value.type,
|