@dotobokuri/fleet-console 1.39.0 → 1.41.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/README.md +2 -3
- package/dist/cli.d.ts +2 -1
- package/dist/cli.mjs +152 -1182
- package/dist/client/assets/{_baseUniq-BDfju2rW.js → _baseUniq-CImzMrtU.js} +1 -1
- package/dist/client/assets/{arc-DWcMv-ui.js → arc-CKb0rHjN.js} +1 -1
- package/dist/client/assets/{architectureDiagram-Q4EWVU46-DhPv_Uba.js → architectureDiagram-Q4EWVU46-BaZipXSe.js} +1 -1
- package/dist/client/assets/{blockDiagram-DXYQGD6D-D7RYcNDP.js → blockDiagram-DXYQGD6D-D4sS9TjR.js} +1 -1
- package/dist/client/assets/{c4Diagram-AHTNJAMY-9_4dQBo3.js → c4Diagram-AHTNJAMY-DvjpMsKx.js} +1 -1
- package/dist/client/assets/channel-dSuGhtYS.js +1 -0
- package/dist/client/assets/{chunk-4BX2VUAB-CQf5x2mT.js → chunk-4BX2VUAB-B47BryhY.js} +1 -1
- package/dist/client/assets/{chunk-4TB4RGXK-eeG8BKQB.js → chunk-4TB4RGXK-DKIhSC52.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-1dkBlsDt.js → chunk-55IACEB6-B3Gvpef7.js} +1 -1
- package/dist/client/assets/{chunk-EDXVE4YY-C5vcF-lT.js → chunk-EDXVE4YY-C4gFtvU8.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-CGelAuwP.js → chunk-FMBD7UC4-BADPieOa.js} +1 -1
- package/dist/client/assets/{chunk-OYMX7WX6-CbKgVyop.js → chunk-OYMX7WX6-BUdtWGUY.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-CT0ppG8R.js → chunk-QZHKN3VN-CMxkeGnM.js} +1 -1
- package/dist/client/assets/{chunk-YZCP3GAM-BEf8DhxB.js → chunk-YZCP3GAM-Br6N7t8d.js} +1 -1
- package/dist/client/assets/classDiagram-6PBFFD2Q-DEN4mh7x.js +1 -0
- package/dist/client/assets/classDiagram-v2-HSJHXN6E-DEN4mh7x.js +1 -0
- package/dist/client/assets/clone-BbTnmCoq.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-C6GtvpYi.js → cose-bilkent-S5V4N54A-D1Uw7i5_.js} +1 -1
- package/dist/client/assets/{dagre-KV5264BT-DvrU2BgH.js → dagre-KV5264BT-kop0bHkM.js} +1 -1
- package/dist/client/assets/{diagram-5BDNPKRD-Cy1qKKqt.js → diagram-5BDNPKRD-B9e41qNA.js} +1 -1
- package/dist/client/assets/{diagram-G4DWMVQ6-C4GGKnnD.js → diagram-G4DWMVQ6-Wew8X03k.js} +1 -1
- package/dist/client/assets/{diagram-MMDJMWI5-By7JFsIw.js → diagram-MMDJMWI5-DGBb5Oqa.js} +1 -1
- package/dist/client/assets/{diagram-TYMM5635-YwzVWpID.js → diagram-TYMM5635-CiVNsAz6.js} +1 -1
- package/dist/client/assets/{erDiagram-SMLLAGMA-CDsNlmLk.js → erDiagram-SMLLAGMA-BdemYTgC.js} +1 -1
- package/dist/client/assets/{flowDiagram-DWJPFMVM-BuUpIzTa.js → flowDiagram-DWJPFMVM-CXC6yxhU.js} +1 -1
- package/dist/client/assets/{ganttDiagram-T4ZO3ILL-Dqv9t2x8.js → ganttDiagram-T4ZO3ILL-SMUpaiUg.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-UUTBAWPF-DApQn2c7.js → gitGraphDiagram-UUTBAWPF-UaFgTHEh.js} +1 -1
- package/dist/client/assets/{graph-CyX-IC4n.js → graph-Ch8F0gMI.js} +1 -1
- package/dist/client/assets/index-D38r12i5.css +1 -0
- package/dist/client/assets/index-DkTcJcbj.js +452 -0
- package/dist/client/assets/{infoDiagram-42DDH7IO-DIf3qelw.js → infoDiagram-42DDH7IO-BHBzw0bu.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-UXIWVN3A-CU3QtNdx.js → ishikawaDiagram-UXIWVN3A-CnDea8bw.js} +1 -1
- package/dist/client/assets/{journeyDiagram-VCZTEJTY-Dfq4OBhW.js → journeyDiagram-VCZTEJTY-CI91m8BP.js} +1 -1
- package/dist/client/assets/{kanban-definition-6JOO6SKY-CWSe3eh7.js → kanban-definition-6JOO6SKY-D-rn-rG2.js} +1 -1
- package/dist/client/assets/{layout-CfdpDpEB.js → layout-Cd9zpG94.js} +1 -1
- package/dist/client/assets/{linear-BQA5wLDW.js → linear-Cucr1ojd.js} +1 -1
- package/dist/client/assets/{mermaid.core-BwJS5O4y.js → mermaid.core-G36P12JZ.js} +4 -4
- package/dist/client/assets/{min-Cg-Q6TB5.js → min-CzfCLG7v.js} +1 -1
- package/dist/client/assets/{mindmap-definition-QFDTVHPH-BNXT0q7L.js → mindmap-definition-QFDTVHPH-4e1VjBV7.js} +1 -1
- package/dist/client/assets/{pieDiagram-DEJITSTG-Cot4WNe7.js → pieDiagram-DEJITSTG-m2CGbU51.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-34T5L4WZ-_YW3nZwc.js → quadrantDiagram-34T5L4WZ-BKNPGqMc.js} +1 -1
- package/dist/client/assets/{requirementDiagram-MS252O5E-didEilrX.js → requirementDiagram-MS252O5E-D2BMwnpz.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-XADWPNL6-CIpzp5Ep.js → sankeyDiagram-XADWPNL6-Bm6hTqEh.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-FGHM5R23-CqvwD_CI.js → sequenceDiagram-FGHM5R23-Ds2FEGPj.js} +1 -1
- package/dist/client/assets/{stateDiagram-FHFEXIEX-D492KgCG.js → stateDiagram-FHFEXIEX-CrXn2Tb7.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-BbzpXIlW.js +1 -0
- package/dist/client/assets/{timeline-definition-GMOUNBTQ-BpAwqH0H.js → timeline-definition-GMOUNBTQ-mw053fb5.js} +1 -1
- package/dist/client/assets/{vennDiagram-DHZGUBPP-DDMPO_HG.js → vennDiagram-DHZGUBPP-CAws0Vt2.js} +1 -1
- package/dist/client/assets/{wardley-RL74JXVD-TKEj0wFU.js → wardley-RL74JXVD-DGad2cmz.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-NUSXRM2D-CLjBh2KA.js → wardleyDiagram-NUSXRM2D-BlIyft8I.js} +1 -1
- package/dist/client/assets/{xychartDiagram-5P7HB3ND-DEn2Z9lG.js → xychartDiagram-5P7HB3ND-DHmSULAI.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/client/theme-boot.js +5 -4
- package/dist/fleet-plugins/file-explorer/routes.mjs +484 -56
- package/dist/fleet-plugins/ledger/routes.mjs +56 -80
- package/dist/fleet-plugins/quota/routes.mjs +19806 -0
- package/dist/fleet-plugins/repository/routes.mjs +274 -17
- package/dist/fleet-plugins/scuttlebutt/routes.mjs +6 -431
- package/dist/fleet-plugins/skills/routes.mjs +1 -79
- package/dist/fleet-plugins/terminal/routes.mjs +12449 -2974
- 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
|
@@ -902,16 +902,14 @@ function sanitizeGlobalOptionsData(value) {
|
|
|
902
902
|
if (value.version !== GLOBAL_OPTIONS_VERSION) {
|
|
903
903
|
return { data: createEmptyGlobalOptionsData(), changed: true };
|
|
904
904
|
}
|
|
905
|
-
const kimiModel = sanitizeKimiModel(value.kimiModel);
|
|
906
905
|
const agentIdleDormantMinutes = sanitizeAgentIdleDormantMinutes(value.agentIdleDormantMinutes);
|
|
907
906
|
const data = {
|
|
908
907
|
version: GLOBAL_OPTIONS_VERSION,
|
|
909
908
|
...typeof value.enableMetaphor === "boolean" ? { enableMetaphor: value.enableMetaphor } : {},
|
|
910
|
-
...kimiModel ? { kimiModel } : {},
|
|
911
909
|
...agentIdleDormantMinutes !== void 0 ? { agentIdleDormantMinutes } : {}
|
|
912
910
|
};
|
|
913
|
-
const allowedKeys = /* @__PURE__ */ new Set(["version", "enableMetaphor", "
|
|
914
|
-
const changed = Object.keys(value).some((key) => !allowedKeys.has(key)) || "enableMetaphor" in value && typeof value.enableMetaphor !== "boolean" || "
|
|
911
|
+
const allowedKeys = /* @__PURE__ */ new Set(["version", "enableMetaphor", "agentIdleDormantMinutes"]);
|
|
912
|
+
const changed = Object.keys(value).some((key) => !allowedKeys.has(key)) || "enableMetaphor" in value && typeof value.enableMetaphor !== "boolean" || "agentIdleDormantMinutes" in value && agentIdleDormantMinutes === void 0;
|
|
915
913
|
return { data, changed };
|
|
916
914
|
}
|
|
917
915
|
function sanitizeAgentIdleDormantMinutes(value) {
|
|
@@ -919,18 +917,6 @@ function sanitizeAgentIdleDormantMinutes(value) {
|
|
|
919
917
|
if (typeof value === "number" && Number.isFinite(value) && Number.isInteger(value) && value > 0) return value;
|
|
920
918
|
return void 0;
|
|
921
919
|
}
|
|
922
|
-
function sanitizeKimiModel(value) {
|
|
923
|
-
if (!isRecord(value)) {
|
|
924
|
-
return void 0;
|
|
925
|
-
}
|
|
926
|
-
if (typeof value.model !== "string" || value.model.length === 0) {
|
|
927
|
-
return void 0;
|
|
928
|
-
}
|
|
929
|
-
return {
|
|
930
|
-
model: value.model,
|
|
931
|
-
...typeof value.effort === "string" ? { effort: value.effort } : {}
|
|
932
|
-
};
|
|
933
|
-
}
|
|
934
920
|
function isRecord(value) {
|
|
935
921
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
936
922
|
}
|
|
@@ -993,56 +979,6 @@ function ensureWorkspaceDirectory(dataDir, cwd) {
|
|
|
993
979
|
});
|
|
994
980
|
return workspace;
|
|
995
981
|
}
|
|
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
982
|
function buildWorkspaceDirectory(dataDir, name, cwd) {
|
|
1047
983
|
assertWorkspaceDirectoryName(name);
|
|
1048
984
|
const root = getWorkspaceDirectoryRoot(dataDir);
|
|
@@ -1218,7 +1154,6 @@ var CONSOLE_RUNTIME_DIR_NAME = "console";
|
|
|
1218
1154
|
var CONSOLE_DATA_DIR_NAME2 = "console";
|
|
1219
1155
|
var CONSOLE_STATE_FILE_NAME2 = "state.json";
|
|
1220
1156
|
var CONSOLE_SETTINGS_FILE_NAME2 = "settings.json";
|
|
1221
|
-
var CONSOLE_CAPTURES_DIR_NAME2 = "captures";
|
|
1222
1157
|
function createConsolePaths(deps = {}) {
|
|
1223
1158
|
const env = deps.env ?? process.env;
|
|
1224
1159
|
const base = env.FLEET_CONSOLE_DIR ?? defaultConsoleBaseDir(deps);
|
|
@@ -1229,8 +1164,7 @@ function createConsoleDataPaths(deps = {}) {
|
|
|
1229
1164
|
return {
|
|
1230
1165
|
dir,
|
|
1231
1166
|
stateFile: path23__default.join(dir, CONSOLE_STATE_FILE_NAME2),
|
|
1232
|
-
settingsFile: path23__default.join(dir, CONSOLE_SETTINGS_FILE_NAME2)
|
|
1233
|
-
capturesDir: path23__default.join(dir, CONSOLE_CAPTURES_DIR_NAME2)
|
|
1167
|
+
settingsFile: path23__default.join(dir, CONSOLE_SETTINGS_FILE_NAME2)
|
|
1234
1168
|
};
|
|
1235
1169
|
}
|
|
1236
1170
|
function defaultConsoleBaseDir(deps) {
|
|
@@ -12164,9 +12098,7 @@ var DESKTOP_TITLE_BAR_OVERLAYS = {
|
|
|
12164
12098
|
instrument: { color: "#03080e", symbolColor: "#989fa6", height: 43 },
|
|
12165
12099
|
maritime: { color: "#041729", symbolColor: "#c8c4b7", height: 43 },
|
|
12166
12100
|
carbon: { color: "#101215", symbolColor: "#bfc1c3", height: 43 },
|
|
12167
|
-
|
|
12168
|
-
whites: { color: "#eef0f3", symbolColor: "#334055", height: 43 },
|
|
12169
|
-
drydock: { color: "#ddeaf2", symbolColor: "#30475d", height: 43 }
|
|
12101
|
+
whites: { color: "#f1f0ec", symbolColor: "#424038", height: 43 }
|
|
12170
12102
|
};
|
|
12171
12103
|
function desktopThemeSnapshot(theme) {
|
|
12172
12104
|
return { theme, titleBarOverlay: { ...DESKTOP_TITLE_BAR_OVERLAYS[theme] } };
|
|
@@ -12281,7 +12213,7 @@ function readConsoleGeneralSettings(value) {
|
|
|
12281
12213
|
const language = value.language === "auto" || value.language === "en" || value.language === "ko" ? value.language : void 0;
|
|
12282
12214
|
const reducePanelMotion = typeof value.reducePanelMotion === "boolean" ? value.reducePanelMotion : void 0;
|
|
12283
12215
|
const seenFeatureTours = sanitizeSeenFeatureTours(value.seenFeatureTours);
|
|
12284
|
-
const theme = value.theme === "instrument" || value.theme === "maritime" || value.theme === "carbon" || value.theme === "
|
|
12216
|
+
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
12217
|
const uiFont = sanitizeUiFontSettings(value.uiFont);
|
|
12286
12218
|
return {
|
|
12287
12219
|
...consolePortMode !== void 0 ? { consolePortMode } : {},
|
|
@@ -12393,7 +12325,7 @@ async function mutateGlobalSettings(req, res, deps) {
|
|
|
12393
12325
|
deps.writeJson(res, 400, { error: "invalid_seen_feature_tours" });
|
|
12394
12326
|
return;
|
|
12395
12327
|
}
|
|
12396
|
-
if (body2.theme !== void 0 && body2.theme !== "instrument" && body2.theme !== "maritime" && body2.theme !== "carbon" && body2.theme !== "
|
|
12328
|
+
if (body2.theme !== void 0 && body2.theme !== "instrument" && body2.theme !== "maritime" && body2.theme !== "carbon" && body2.theme !== "whites") {
|
|
12397
12329
|
deps.writeJson(res, 400, { error: "invalid_theme" });
|
|
12398
12330
|
return;
|
|
12399
12331
|
}
|
|
@@ -12401,7 +12333,7 @@ async function mutateGlobalSettings(req, res, deps) {
|
|
|
12401
12333
|
deps.writeJson(res, 400, { error: "invalid_ui_font" });
|
|
12402
12334
|
return;
|
|
12403
12335
|
}
|
|
12404
|
-
const theme = body2.theme === "instrument" || body2.theme === "maritime" || body2.theme === "carbon" || body2.theme === "
|
|
12336
|
+
const theme = body2.theme === "instrument" || body2.theme === "maritime" || body2.theme === "carbon" || body2.theme === "whites" ? body2.theme : void 0;
|
|
12405
12337
|
const updated = deps.consoleSettingsStore.update((current) => ({
|
|
12406
12338
|
...current,
|
|
12407
12339
|
version: 1,
|
|
@@ -13523,10 +13455,10 @@ function mergeDefs(...defs) {
|
|
|
13523
13455
|
function cloneDef(schema) {
|
|
13524
13456
|
return mergeDefs(schema._zod.def);
|
|
13525
13457
|
}
|
|
13526
|
-
function getElementAtPath(obj,
|
|
13527
|
-
if (!
|
|
13458
|
+
function getElementAtPath(obj, path48) {
|
|
13459
|
+
if (!path48)
|
|
13528
13460
|
return obj;
|
|
13529
|
-
return
|
|
13461
|
+
return path48.reduce((acc, key) => acc?.[key], obj);
|
|
13530
13462
|
}
|
|
13531
13463
|
function promiseAllObject(promisesObj) {
|
|
13532
13464
|
const keys = Object.keys(promisesObj);
|
|
@@ -13935,11 +13867,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
13935
13867
|
}
|
|
13936
13868
|
return false;
|
|
13937
13869
|
}
|
|
13938
|
-
function prefixIssues(
|
|
13870
|
+
function prefixIssues(path48, issues) {
|
|
13939
13871
|
return issues.map((iss) => {
|
|
13940
13872
|
var _a3;
|
|
13941
13873
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
13942
|
-
iss.path.unshift(
|
|
13874
|
+
iss.path.unshift(path48);
|
|
13943
13875
|
return iss;
|
|
13944
13876
|
});
|
|
13945
13877
|
}
|
|
@@ -14086,16 +14018,16 @@ function flattenError(error51, mapper = (issue3) => issue3.message) {
|
|
|
14086
14018
|
}
|
|
14087
14019
|
function formatError(error51, mapper = (issue3) => issue3.message) {
|
|
14088
14020
|
const fieldErrors = { _errors: [] };
|
|
14089
|
-
const processError = (error52,
|
|
14021
|
+
const processError = (error52, path48 = []) => {
|
|
14090
14022
|
for (const issue3 of error52.issues) {
|
|
14091
14023
|
if (issue3.code === "invalid_union" && issue3.errors.length) {
|
|
14092
|
-
issue3.errors.map((issues) => processError({ issues }, [...
|
|
14024
|
+
issue3.errors.map((issues) => processError({ issues }, [...path48, ...issue3.path]));
|
|
14093
14025
|
} else if (issue3.code === "invalid_key") {
|
|
14094
|
-
processError({ issues: issue3.issues }, [...
|
|
14026
|
+
processError({ issues: issue3.issues }, [...path48, ...issue3.path]);
|
|
14095
14027
|
} else if (issue3.code === "invalid_element") {
|
|
14096
|
-
processError({ issues: issue3.issues }, [...
|
|
14028
|
+
processError({ issues: issue3.issues }, [...path48, ...issue3.path]);
|
|
14097
14029
|
} else {
|
|
14098
|
-
const fullpath = [...
|
|
14030
|
+
const fullpath = [...path48, ...issue3.path];
|
|
14099
14031
|
if (fullpath.length === 0) {
|
|
14100
14032
|
fieldErrors._errors.push(mapper(issue3));
|
|
14101
14033
|
} else {
|
|
@@ -14122,17 +14054,17 @@ function formatError(error51, mapper = (issue3) => issue3.message) {
|
|
|
14122
14054
|
}
|
|
14123
14055
|
function treeifyError(error51, mapper = (issue3) => issue3.message) {
|
|
14124
14056
|
const result = { errors: [] };
|
|
14125
|
-
const processError = (error52,
|
|
14057
|
+
const processError = (error52, path48 = []) => {
|
|
14126
14058
|
var _a3, _b;
|
|
14127
14059
|
for (const issue3 of error52.issues) {
|
|
14128
14060
|
if (issue3.code === "invalid_union" && issue3.errors.length) {
|
|
14129
|
-
issue3.errors.map((issues) => processError({ issues }, [...
|
|
14061
|
+
issue3.errors.map((issues) => processError({ issues }, [...path48, ...issue3.path]));
|
|
14130
14062
|
} else if (issue3.code === "invalid_key") {
|
|
14131
|
-
processError({ issues: issue3.issues }, [...
|
|
14063
|
+
processError({ issues: issue3.issues }, [...path48, ...issue3.path]);
|
|
14132
14064
|
} else if (issue3.code === "invalid_element") {
|
|
14133
|
-
processError({ issues: issue3.issues }, [...
|
|
14065
|
+
processError({ issues: issue3.issues }, [...path48, ...issue3.path]);
|
|
14134
14066
|
} else {
|
|
14135
|
-
const fullpath = [...
|
|
14067
|
+
const fullpath = [...path48, ...issue3.path];
|
|
14136
14068
|
if (fullpath.length === 0) {
|
|
14137
14069
|
result.errors.push(mapper(issue3));
|
|
14138
14070
|
continue;
|
|
@@ -14164,8 +14096,8 @@ function treeifyError(error51, mapper = (issue3) => issue3.message) {
|
|
|
14164
14096
|
}
|
|
14165
14097
|
function toDotPath(_path) {
|
|
14166
14098
|
const segs = [];
|
|
14167
|
-
const
|
|
14168
|
-
for (const seg of
|
|
14099
|
+
const path48 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
14100
|
+
for (const seg of path48) {
|
|
14169
14101
|
if (typeof seg === "number")
|
|
14170
14102
|
segs.push(`[${seg}]`);
|
|
14171
14103
|
else if (typeof seg === "symbol")
|
|
@@ -26829,13 +26761,13 @@ function resolveRef(ref, ctx) {
|
|
|
26829
26761
|
if (!ref.startsWith("#")) {
|
|
26830
26762
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
26831
26763
|
}
|
|
26832
|
-
const
|
|
26833
|
-
if (
|
|
26764
|
+
const path48 = ref.slice(1).split("/").filter(Boolean);
|
|
26765
|
+
if (path48.length === 0) {
|
|
26834
26766
|
return ctx.rootSchema;
|
|
26835
26767
|
}
|
|
26836
26768
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
26837
|
-
if (
|
|
26838
|
-
const key =
|
|
26769
|
+
if (path48[0] === defsKey) {
|
|
26770
|
+
const key = path48[1];
|
|
26839
26771
|
if (!key || !ctx.defs[key]) {
|
|
26840
26772
|
throw new Error(`Reference not found: ${ref}`);
|
|
26841
26773
|
}
|
|
@@ -31540,7 +31472,7 @@ var AcpConnection = class extends BaseConnection {
|
|
|
31540
31472
|
}
|
|
31541
31473
|
/** Claude 계열 브릿지인지 여부를 단일 판별 지점으로 유지합니다. */
|
|
31542
31474
|
isClaudeBackend() {
|
|
31543
|
-
return this.cliType === "claude"
|
|
31475
|
+
return this.cliType === "claude";
|
|
31544
31476
|
}
|
|
31545
31477
|
/** Claude bridge 전용 system prompt replacement, strict-MCP와 effort `_meta`를 조립합니다. */
|
|
31546
31478
|
buildClaudeSessionMeta(systemPrompt, strictMcp, effort) {
|
|
@@ -32006,22 +31938,6 @@ var models_default = {
|
|
|
32006
31938
|
{ modelId: "claude-opus-4-8[1m]", name: "Claude Opus 4.8 [1M]", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "high" } }
|
|
32007
31939
|
]
|
|
32008
31940
|
},
|
|
32009
|
-
"claude-kimi": {
|
|
32010
|
-
name: "Kimi via Claude Code",
|
|
32011
|
-
defaultModel: "kimi-for-coding",
|
|
32012
|
-
models: [
|
|
32013
|
-
{ modelId: "kimi-for-coding", name: "Kimi for Coding", description: "Available on every Kimi Code membership tier (262K context)", effort: { supported: false }, contextWindow: 262144 },
|
|
32014
|
-
{ modelId: "k3", name: "Kimi K3", description: "Available on Moderato and higher tiers (262K context)", effort: { supported: true, levels: ["low", "high", "max"], default: "high" }, contextWindow: 262144 },
|
|
32015
|
-
{ modelId: "k3[1m]", name: "Kimi K3 [1M]", description: "Available on Allegretto and higher tiers (1M context)", effort: { supported: true, levels: ["low", "high", "max"], default: "high" }, contextWindow: 1048576 },
|
|
32016
|
-
{ modelId: "kimi-for-coding-highspeed", name: "Kimi for Coding Highspeed", description: "Available on Allegretto and higher tiers (262K context)", effort: { supported: false }, contextWindow: 262144 }
|
|
32017
|
-
],
|
|
32018
|
-
modelsMapping: {
|
|
32019
|
-
haiku: "kimi-for-coding",
|
|
32020
|
-
sonnet: "kimi-for-coding",
|
|
32021
|
-
opus: "kimi-for-coding",
|
|
32022
|
-
fable: "kimi-for-coding"
|
|
32023
|
-
}
|
|
32024
|
-
},
|
|
32025
31941
|
codex: {
|
|
32026
31942
|
name: "Codex",
|
|
32027
31943
|
defaultModel: "gpt-5.6-sol",
|
|
@@ -32036,23 +31952,6 @@ var models_default = {
|
|
|
32036
31952
|
{ 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
31953
|
]
|
|
32038
31954
|
},
|
|
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
31955
|
cursor: {
|
|
32057
31956
|
name: "Cursor Agent",
|
|
32058
31957
|
defaultModel: "auto",
|
|
@@ -32154,16 +32053,13 @@ var ModelEntrySchema = external_exports.object({
|
|
|
32154
32053
|
});
|
|
32155
32054
|
}
|
|
32156
32055
|
});
|
|
32157
|
-
var ModelsMappingSchema = external_exports.record(external_exports.string(), external_exports.string());
|
|
32158
32056
|
var ProviderSchema = external_exports.object({
|
|
32159
32057
|
/** 프로바이더 표시 이름 */
|
|
32160
32058
|
name: external_exports.string(),
|
|
32161
32059
|
/** 기본 모델 ID */
|
|
32162
32060
|
defaultModel: external_exports.string(),
|
|
32163
32061
|
/** 사용 가능한 모델 목록 */
|
|
32164
|
-
models: external_exports.array(ModelEntrySchema).min(1)
|
|
32165
|
-
/** modelId와 연관된 매핑 모델 (선택) */
|
|
32166
|
-
modelsMapping: ModelsMappingSchema.optional()
|
|
32062
|
+
models: external_exports.array(ModelEntrySchema).min(1)
|
|
32167
32063
|
}).check((ctx) => {
|
|
32168
32064
|
const ids = new Set(ctx.value.models.map((m) => m.modelId));
|
|
32169
32065
|
if (!ids.has(ctx.value.defaultModel)) {
|
|
@@ -32233,13 +32129,6 @@ function resolveCursorSpawnModel(modelId, effort) {
|
|
|
32233
32129
|
}
|
|
32234
32130
|
return model.spawnModelTemplate.replace("{effort}", resolvedLevel);
|
|
32235
32131
|
}
|
|
32236
|
-
function getProviderModelsMapping(cli) {
|
|
32237
|
-
const provider = registry2.providers[cli];
|
|
32238
|
-
if (!provider) {
|
|
32239
|
-
throw new Error(`\uC54C \uC218 \uC5C6\uB294 \uD504\uB85C\uBC14\uC774\uB354: "${cli}"`);
|
|
32240
|
-
}
|
|
32241
|
-
return provider.modelsMapping ? structuredClone(provider.modelsMapping) : null;
|
|
32242
|
-
}
|
|
32243
32132
|
function findProviderModel(cli, modelId) {
|
|
32244
32133
|
const provider = registry2.providers[cli];
|
|
32245
32134
|
if (!provider) {
|
|
@@ -32271,32 +32160,6 @@ var CLI_BACKENDS = {
|
|
|
32271
32160
|
usesNpxBridge: true,
|
|
32272
32161
|
defaultMaxTokens: 16384
|
|
32273
32162
|
},
|
|
32274
|
-
"claude-kimi": {
|
|
32275
|
-
id: "claude-kimi",
|
|
32276
|
-
cliCommand: "claude",
|
|
32277
|
-
protocol: "acp",
|
|
32278
|
-
authRequired: true,
|
|
32279
|
-
npxPackage: "@agentclientprotocol/claude-agent-acp@0.33.1",
|
|
32280
|
-
modes: [
|
|
32281
|
-
{ id: "default", label: "Default" },
|
|
32282
|
-
{ id: "plan", label: "Plan" },
|
|
32283
|
-
{ id: "bypassPermissions", label: "YOLO" }
|
|
32284
|
-
],
|
|
32285
|
-
supportsSessionClose: true,
|
|
32286
|
-
supportsSessionLoad: true,
|
|
32287
|
-
requiresModelAtSpawn: false,
|
|
32288
|
-
usesNpxBridge: true,
|
|
32289
|
-
defaultMaxTokens: 262144,
|
|
32290
|
-
defaultEnv: {
|
|
32291
|
-
ANTHROPIC_BASE_URL: "https://api.kimi.com/coding/",
|
|
32292
|
-
ANTHROPIC_MODEL: "kimi-for-coding",
|
|
32293
|
-
ANTHROPIC_DEFAULT_HAIKU_MODEL: "kimi-for-coding",
|
|
32294
|
-
ANTHROPIC_DEFAULT_SONNET_MODEL: "kimi-for-coding",
|
|
32295
|
-
ANTHROPIC_DEFAULT_OPUS_MODEL: "kimi-for-coding",
|
|
32296
|
-
CLAUDE_CODE_SUBAGENT_MODEL: "kimi-for-coding",
|
|
32297
|
-
API_TIMEOUT_MS: "3000000"
|
|
32298
|
-
}
|
|
32299
|
-
},
|
|
32300
32163
|
codex: {
|
|
32301
32164
|
id: "codex",
|
|
32302
32165
|
cliCommand: "codex",
|
|
@@ -32314,22 +32177,6 @@ var CLI_BACKENDS = {
|
|
|
32314
32177
|
usesNpxBridge: false,
|
|
32315
32178
|
defaultMaxTokens: 1e5
|
|
32316
32179
|
},
|
|
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
32180
|
cursor: {
|
|
32334
32181
|
id: "cursor",
|
|
32335
32182
|
cliCommand: "cursor-agent",
|
|
@@ -32389,10 +32236,7 @@ function getBackendConfig(cli) {
|
|
|
32389
32236
|
function getYoloModeId(cli) {
|
|
32390
32237
|
switch (cli) {
|
|
32391
32238
|
case "claude":
|
|
32392
|
-
case "claude-kimi":
|
|
32393
32239
|
return "bypassPermissions";
|
|
32394
|
-
case "opencode-go":
|
|
32395
|
-
return "build";
|
|
32396
32240
|
case "cursor":
|
|
32397
32241
|
return "agent";
|
|
32398
32242
|
case "codex":
|
|
@@ -32606,11 +32450,7 @@ var UnifiedClaudeAgentClient = class extends EventEmitter {
|
|
|
32606
32450
|
firstPromptPending = null;
|
|
32607
32451
|
currentEffort = null;
|
|
32608
32452
|
detector = new CliDetector();
|
|
32609
|
-
cliType;
|
|
32610
|
-
constructor(cliType = "claude") {
|
|
32611
|
-
super();
|
|
32612
|
-
this.cliType = cliType;
|
|
32613
|
-
}
|
|
32453
|
+
cliType = "claude";
|
|
32614
32454
|
on(event, listener) {
|
|
32615
32455
|
return super.on(event, listener);
|
|
32616
32456
|
}
|
|
@@ -32626,31 +32466,14 @@ var UnifiedClaudeAgentClient = class extends EventEmitter {
|
|
|
32626
32466
|
async connect(options) {
|
|
32627
32467
|
await this.disconnect();
|
|
32628
32468
|
const systemPromptMode = options.systemPromptMode ?? "prepend";
|
|
32629
|
-
const requestedCli = options.cli ?? this.cliType;
|
|
32630
|
-
if (systemPromptMode === "replace" && requestedCli !== "claude" && requestedCli !== "claude-kimi") {
|
|
32631
|
-
throw new Error(
|
|
32632
|
-
`system prompt replacement is not supported by the "${requestedCli}" backend`
|
|
32633
|
-
);
|
|
32634
|
-
}
|
|
32635
32469
|
if (options.cli && options.cli !== this.cliType) {
|
|
32636
32470
|
throw new Error(`UnifiedClaudeAgentClient\uB294 ${this.cliType} CLI\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4.`);
|
|
32637
32471
|
}
|
|
32638
32472
|
const acpMcpServers = this.resolveMcpServers(options.mcpServers);
|
|
32639
32473
|
const spawnConfig = createSpawnConfig(this.cliType, options);
|
|
32640
|
-
const modelsMapping = getProviderModelsMapping(this.cliType);
|
|
32641
|
-
const mappingEnv = {};
|
|
32642
|
-
if (modelsMapping) {
|
|
32643
|
-
for (const [modelId, mappedModel] of Object.entries(modelsMapping)) {
|
|
32644
|
-
const envKey = `ANTHROPIC_DEFAULT_${modelId.toUpperCase()}_MODEL`;
|
|
32645
|
-
mappingEnv[envKey] = mappedModel;
|
|
32646
|
-
}
|
|
32647
|
-
}
|
|
32648
32474
|
const backendConfig = getBackendConfig(this.cliType);
|
|
32649
32475
|
const defaultEnv = backendConfig.defaultEnv ?? {};
|
|
32650
|
-
const cleanEnv = cleanEnvironment(process.env, { ...defaultEnv, ...
|
|
32651
|
-
if (this.cliType === "claude-kimi") {
|
|
32652
|
-
delete cleanEnv.ANTHROPIC_AUTH_TOKEN;
|
|
32653
|
-
}
|
|
32476
|
+
const cleanEnv = cleanEnvironment(process.env, { ...defaultEnv, ...options.env });
|
|
32654
32477
|
if (defaultEnv.ANTHROPIC_BASE_URL && !cleanEnv.ANTHROPIC_API_KEY && !cleanEnv.ANTHROPIC_AUTH_TOKEN) {
|
|
32655
32478
|
throw new Error(
|
|
32656
32479
|
`[${this.cliType}] ANTHROPIC_API_KEY \uD658\uACBD\uBCC0\uC218\uAC00 \uC124\uC815\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. ${getProviderModels(this.cliType).name} API \uD0A4\uB97C \uC124\uC815\uD574\uC8FC\uC138\uC694.`
|
|
@@ -34795,331 +34618,15 @@ var UnifiedCursorAgentClient = class extends EventEmitter {
|
|
|
34795
34618
|
return patterns.some((pattern) => pattern.test(text));
|
|
34796
34619
|
}
|
|
34797
34620
|
};
|
|
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
34621
|
|
|
35112
34622
|
// ../../packages/core-unified-agent/src/client/UnifiedAgent.ts
|
|
35113
34623
|
var UnifiedAgent = {
|
|
35114
34624
|
createClient(cli) {
|
|
35115
34625
|
switch (cli) {
|
|
35116
34626
|
case "claude":
|
|
35117
|
-
|
|
35118
|
-
return new UnifiedClaudeAgentClient(cli);
|
|
34627
|
+
return new UnifiedClaudeAgentClient();
|
|
35119
34628
|
case "codex":
|
|
35120
34629
|
return new UnifiedCodexAgentClient();
|
|
35121
|
-
case "opencode-go":
|
|
35122
|
-
return new UnifiedOpenCodeAgentClient("opencode-go");
|
|
35123
34630
|
case "cursor":
|
|
35124
34631
|
return new UnifiedCursorAgentClient();
|
|
35125
34632
|
}
|
|
@@ -35134,7 +34641,7 @@ var UnifiedAgent = {
|
|
|
35134
34641
|
const preferred = await new CliDetector().getPreferred();
|
|
35135
34642
|
if (!preferred) {
|
|
35136
34643
|
throw new Error(
|
|
35137
|
-
"\uC0AC\uC6A9 \uAC00\uB2A5\uD55C CLI\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. claude,
|
|
34644
|
+
"\uC0AC\uC6A9 \uAC00\uB2A5\uD55C CLI\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. claude, codex, cursor \uC911 \uD558\uB098\uB97C \uC124\uCE58\uD574\uC8FC\uC138\uC694."
|
|
35138
34645
|
);
|
|
35139
34646
|
}
|
|
35140
34647
|
return this.createClient(preferred.cli);
|
|
@@ -36115,11 +35622,6 @@ var CoworkStore = class {
|
|
|
36115
35622
|
function hash2(value) {
|
|
36116
35623
|
return crypto2.createHash("sha256").update(value).digest("hex");
|
|
36117
35624
|
}
|
|
36118
|
-
|
|
36119
|
-
// ../../packages/core-agent/src/types.ts
|
|
36120
|
-
function snapshotAgentServerBindings(bindings) {
|
|
36121
|
-
return bindings === void 0 ? void 0 : Object.freeze({ ...bindings });
|
|
36122
|
-
}
|
|
36123
35625
|
function specToMcpTool(spec) {
|
|
36124
35626
|
return {
|
|
36125
35627
|
name: spec.id,
|
|
@@ -36134,8 +35636,7 @@ function installExecutorToolCallRouter(runtime, sessionToken, ctx) {
|
|
|
36134
35636
|
cwd: ctx.cwd,
|
|
36135
35637
|
sessionLabel: ctx.sessionLabel,
|
|
36136
35638
|
toolCallId,
|
|
36137
|
-
signal: ctx.signal
|
|
36138
|
-
serverBindings: ctx.serverBindings
|
|
35639
|
+
signal: ctx.signal
|
|
36139
35640
|
}).then((result) => runtime.server.resolveNextToolCall(sessionToken, toolCallId, result)).catch((err) => {
|
|
36140
35641
|
runtime.server.resolveNextToolCall(sessionToken, toolCallId, {
|
|
36141
35642
|
content: [{ type: "text", text: err instanceof Error ? err.message : String(err) }],
|
|
@@ -36223,8 +35724,7 @@ function createMcpToolRegistry() {
|
|
|
36223
35724
|
cwd: ctx?.cwd ?? process.cwd(),
|
|
36224
35725
|
sessionLabel: ctx?.sessionLabel,
|
|
36225
35726
|
toolCallId: ctx?.toolCallId,
|
|
36226
|
-
signal: ctx?.signal
|
|
36227
|
-
serverBindings: ctx?.serverBindings
|
|
35727
|
+
signal: ctx?.signal
|
|
36228
35728
|
};
|
|
36229
35729
|
const spec = primaryToolSpecs.get(name);
|
|
36230
35730
|
if (!spec) {
|
|
@@ -36785,12 +36285,10 @@ function createExecutorMcpSession(deps, toolTimeoutSeconds, request) {
|
|
|
36785
36285
|
}
|
|
36786
36286
|
assertNonEmptyExecutorTools(request.serverName, request.specs);
|
|
36787
36287
|
const token = crypto2.randomUUID();
|
|
36788
|
-
const serverBindings = snapshotAgentServerBindings(request.serverBindings);
|
|
36789
36288
|
registerExecutorSessionTools(runtime.runtime, token, [...request.specs]);
|
|
36790
36289
|
installExecutorToolCallRouter(runtime.runtime, token, {
|
|
36791
36290
|
cwd,
|
|
36792
|
-
signal: request.signal
|
|
36793
|
-
serverBindings
|
|
36291
|
+
signal: request.signal
|
|
36794
36292
|
});
|
|
36795
36293
|
return runtime.runtime.server.start().then((url2) => ({
|
|
36796
36294
|
serverName: request.serverName,
|
|
@@ -36820,18 +36318,17 @@ function issueSessionToken(deps, sessionTokensByLabel, request) {
|
|
|
36820
36318
|
cleanupExecutorServerTokens(deps, previous.tokens);
|
|
36821
36319
|
}
|
|
36822
36320
|
const tokens = [];
|
|
36823
|
-
const serverBindings = snapshotAgentServerBindings(request.serverBindings);
|
|
36824
36321
|
try {
|
|
36825
36322
|
for (const { name, runtime } of deps.runtimes) {
|
|
36826
|
-
const
|
|
36323
|
+
const allTools = runtime.registry.getAllAgentTools();
|
|
36324
|
+
const tools = request.includeTool ? allTools.filter((tool) => request.includeTool?.(tool.id) ?? true) : allTools;
|
|
36827
36325
|
assertNonEmptyExecutorTools(name, tools);
|
|
36828
36326
|
const token = crypto2.randomUUID();
|
|
36829
36327
|
registerExecutorSessionTools(runtime, token, tools);
|
|
36830
36328
|
installExecutorToolCallRouter(runtime, token, {
|
|
36831
36329
|
cwd,
|
|
36832
36330
|
sessionLabel: label,
|
|
36833
|
-
signal: request.signal
|
|
36834
|
-
serverBindings
|
|
36331
|
+
signal: request.signal
|
|
36835
36332
|
});
|
|
36836
36333
|
tokens.push({ name, token });
|
|
36837
36334
|
}
|
|
@@ -36842,8 +36339,7 @@ function issueSessionToken(deps, sessionTokensByLabel, request) {
|
|
|
36842
36339
|
sessionTokensByLabel.set(label, {
|
|
36843
36340
|
tokens,
|
|
36844
36341
|
cwd,
|
|
36845
|
-
signal: request.signal
|
|
36846
|
-
serverBindings
|
|
36342
|
+
signal: request.signal
|
|
36847
36343
|
});
|
|
36848
36344
|
return tokens;
|
|
36849
36345
|
}
|
|
@@ -38829,572 +38325,94 @@ function sanitizeReplacementNodes(nextNodes) {
|
|
|
38829
38325
|
}
|
|
38830
38326
|
return result;
|
|
38831
38327
|
}
|
|
38832
|
-
|
|
38833
|
-
|
|
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;
|
|
38328
|
+
var LEGACY_CAPTURES_DIR_NAME = "captures";
|
|
38329
|
+
function migrateLegacyCaptures(deps) {
|
|
39004
38330
|
try {
|
|
39005
|
-
|
|
38331
|
+
migrateLegacyCapturesStrict(deps);
|
|
39006
38332
|
} catch (error51) {
|
|
39007
|
-
|
|
38333
|
+
console.warn(`[fleet-console] Legacy capture migration skipped: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
39008
38334
|
}
|
|
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
38335
|
}
|
|
39021
|
-
|
|
39022
|
-
|
|
39023
|
-
|
|
39024
|
-
|
|
39025
|
-
|
|
39026
|
-
|
|
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;
|
|
38336
|
+
function migrateLegacyCapturesStrict(deps) {
|
|
38337
|
+
if (!path23__default.isAbsolute(deps.consoleDataDir)) return;
|
|
38338
|
+
const capturesDir = path23__default.join(deps.consoleDataDir, LEGACY_CAPTURES_DIR_NAME);
|
|
38339
|
+
if (!fs10__default.existsSync(capturesDir)) return;
|
|
38340
|
+
let migrated = false;
|
|
38341
|
+
let retained = false;
|
|
39109
38342
|
try {
|
|
39110
|
-
|
|
39111
|
-
|
|
39112
|
-
|
|
39113
|
-
|
|
39114
|
-
|
|
39115
|
-
|
|
39116
|
-
|
|
39117
|
-
|
|
39118
|
-
|
|
39119
|
-
|
|
39120
|
-
|
|
39121
|
-
|
|
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;
|
|
38343
|
+
const entries = fs10__default.readdirSync(capturesDir);
|
|
38344
|
+
for (const entry of entries) {
|
|
38345
|
+
if (!entry.endsWith(".json")) continue;
|
|
38346
|
+
const operationId = entry.slice(0, -".json".length);
|
|
38347
|
+
if (!isSafeCaptureId(operationId)) continue;
|
|
38348
|
+
try {
|
|
38349
|
+
const outcome = processCaptureFile(deps, capturesDir, operationId, entry);
|
|
38350
|
+
if (outcome.migrated) migrated = true;
|
|
38351
|
+
if (outcome.retained) retained = true;
|
|
38352
|
+
} catch (error51) {
|
|
38353
|
+
retained = true;
|
|
38354
|
+
console.warn(`[fleet-console] Legacy capture migrate failed for ${entry}: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
38355
|
+
}
|
|
39153
38356
|
}
|
|
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
38357
|
} catch (error51) {
|
|
39186
|
-
|
|
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;
|
|
38358
|
+
retained = true;
|
|
38359
|
+
console.warn(`[fleet-console] Legacy capture directory read failed: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
39193
38360
|
}
|
|
39194
|
-
|
|
39195
|
-
|
|
39196
|
-
|
|
39197
|
-
|
|
39198
|
-
|
|
39199
|
-
|
|
39200
|
-
|
|
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;
|
|
38361
|
+
let saved = false;
|
|
38362
|
+
if (migrated) {
|
|
38363
|
+
try {
|
|
38364
|
+
deps.save?.();
|
|
38365
|
+
saved = true;
|
|
38366
|
+
} catch (error51) {
|
|
38367
|
+
console.warn(`[fleet-console] Legacy capture migration save failed: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
39214
38368
|
}
|
|
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
38369
|
}
|
|
39240
|
-
|
|
39241
|
-
|
|
39242
|
-
|
|
39243
|
-
|
|
39244
|
-
|
|
39245
|
-
|
|
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);
|
|
38370
|
+
if ((!migrated || saved) && !retained) {
|
|
38371
|
+
try {
|
|
38372
|
+
fs10__default.rmSync(capturesDir, { recursive: true, force: true });
|
|
38373
|
+
} catch (error51) {
|
|
38374
|
+
console.warn(`[fleet-console] Legacy captures directory removal failed: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
38375
|
+
}
|
|
39280
38376
|
}
|
|
39281
38377
|
}
|
|
39282
|
-
|
|
39283
|
-
|
|
39284
|
-
|
|
39285
|
-
return;
|
|
39286
|
-
|
|
39287
|
-
|
|
39288
|
-
|
|
39289
|
-
return;
|
|
39290
|
-
|
|
39291
|
-
|
|
39292
|
-
|
|
39293
|
-
|
|
39294
|
-
return;
|
|
39295
|
-
}
|
|
39296
|
-
if (typeof body2.name !== "string" || !isValidPlanName(body2.name)) {
|
|
39297
|
-
deps.writeJson(res, 400, { error: "invalid_name" });
|
|
39298
|
-
return;
|
|
38378
|
+
function processCaptureFile(deps, capturesDir, operationId, entry) {
|
|
38379
|
+
const operation = deps.operations.get(operationId);
|
|
38380
|
+
if (operation) {
|
|
38381
|
+
if (hasProviderSession(operation.payload)) return { migrated: false, retained: false };
|
|
38382
|
+
const filePath = path23__default.join(capturesDir, entry);
|
|
38383
|
+
const parsed = JSON.parse(fs10__default.readFileSync(filePath, "utf8"));
|
|
38384
|
+
const providerSession = sanitizeProviderSession(parsed);
|
|
38385
|
+
if (!providerSession) return { migrated: false, retained: false };
|
|
38386
|
+
deps.operations.patch(operationId, {
|
|
38387
|
+
payload: { ...operation.payload, providerSession }
|
|
38388
|
+
});
|
|
38389
|
+
return { migrated: true, retained: false };
|
|
39299
38390
|
}
|
|
39300
|
-
const
|
|
39301
|
-
if (!
|
|
39302
|
-
|
|
39303
|
-
return;
|
|
38391
|
+
const tombstoned = deps.tombstonedOperations?.find((candidate) => candidate.id === operationId);
|
|
38392
|
+
if (tombstoned && !hasProviderSession(tombstoned.payload)) {
|
|
38393
|
+
return { migrated: false, retained: true };
|
|
39304
38394
|
}
|
|
39305
|
-
|
|
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);
|
|
38395
|
+
return { migrated: false, retained: false };
|
|
39315
38396
|
}
|
|
39316
|
-
function
|
|
39317
|
-
|
|
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 });
|
|
38397
|
+
function hasProviderSession(payload) {
|
|
38398
|
+
return sanitizeProviderSession(payload?.providerSession) !== void 0;
|
|
39325
38399
|
}
|
|
39326
|
-
|
|
39327
|
-
|
|
39328
|
-
|
|
39329
|
-
|
|
39330
|
-
return
|
|
39331
|
-
} catch {
|
|
39332
|
-
return null;
|
|
38400
|
+
function sanitizeProviderSession(value) {
|
|
38401
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
38402
|
+
const candidate = value;
|
|
38403
|
+
if (candidate.provider !== "claude" && candidate.provider !== "codex" || typeof candidate.sessionId !== "string" || typeof candidate.capturedAt !== "string") {
|
|
38404
|
+
return void 0;
|
|
39333
38405
|
}
|
|
39334
|
-
}) {
|
|
39335
|
-
const entries = /* @__PURE__ */ new Map();
|
|
39336
38406
|
return {
|
|
39337
|
-
|
|
39338
|
-
|
|
39339
|
-
|
|
39340
|
-
|
|
39341
|
-
|
|
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
|
-
}
|
|
38407
|
+
provider: candidate.provider,
|
|
38408
|
+
sessionId: candidate.sessionId,
|
|
38409
|
+
capturedAt: candidate.capturedAt,
|
|
38410
|
+
...typeof candidate.transcriptPath === "string" && candidate.transcriptPath.length > 0 ? { transcriptPath: candidate.transcriptPath } : {},
|
|
38411
|
+
...typeof candidate.source === "string" && candidate.source.length > 0 ? { source: candidate.source } : {}
|
|
39359
38412
|
};
|
|
39360
|
-
|
|
39361
|
-
|
|
39362
|
-
|
|
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
|
-
}
|
|
38413
|
+
}
|
|
38414
|
+
function isSafeCaptureId(value) {
|
|
38415
|
+
return value.length > 0 && path23__default.basename(value) === value && !value.includes(path23__default.sep) && !value.includes(path23__default.posix.sep);
|
|
39398
38416
|
}
|
|
39399
38417
|
|
|
39400
38418
|
// sdk/version.ts
|
|
@@ -40298,7 +39316,7 @@ function serveFallbackIndex(req, res, consoleRoot, getActiveTheme) {
|
|
|
40298
39316
|
function injectActiveTheme(html, getActiveTheme) {
|
|
40299
39317
|
if (!getActiveTheme) return html;
|
|
40300
39318
|
const theme = getActiveTheme();
|
|
40301
|
-
if (theme !== "instrument" && theme !== "maritime" && theme !== "carbon" && theme !== "
|
|
39319
|
+
if (theme !== "instrument" && theme !== "maritime" && theme !== "carbon" && theme !== "whites") {
|
|
40302
39320
|
return html;
|
|
40303
39321
|
}
|
|
40304
39322
|
return html.replace('data-theme="instrument"', `data-theme="${theme}" data-theme-source="server"`);
|
|
@@ -40375,7 +39393,7 @@ async function statDirectory(targetPath, stat4) {
|
|
|
40375
39393
|
try {
|
|
40376
39394
|
return await stat4(targetPath);
|
|
40377
39395
|
} catch (error51) {
|
|
40378
|
-
throw
|
|
39396
|
+
throw mapFsError(error51);
|
|
40379
39397
|
}
|
|
40380
39398
|
}
|
|
40381
39399
|
async function collectDirectoryEntries(targetPath, opendir, stat4, entries) {
|
|
@@ -40392,7 +39410,7 @@ async function collectDirectoryEntries(targetPath, opendir, stat4, entries) {
|
|
|
40392
39410
|
}
|
|
40393
39411
|
return false;
|
|
40394
39412
|
} catch (error51) {
|
|
40395
|
-
throw
|
|
39413
|
+
throw mapFsError(error51);
|
|
40396
39414
|
} finally {
|
|
40397
39415
|
await directory.close();
|
|
40398
39416
|
}
|
|
@@ -40401,7 +39419,7 @@ async function openDirectory(targetPath, opendir) {
|
|
|
40401
39419
|
try {
|
|
40402
39420
|
return await opendir(targetPath);
|
|
40403
39421
|
} catch (error51) {
|
|
40404
|
-
throw
|
|
39422
|
+
throw mapFsError(error51);
|
|
40405
39423
|
}
|
|
40406
39424
|
}
|
|
40407
39425
|
async function toTheaterFolderEntry(targetPath, dirent, stat4) {
|
|
@@ -40419,7 +39437,7 @@ async function statSymlinkDirectory(entryPath, stat4) {
|
|
|
40419
39437
|
return false;
|
|
40420
39438
|
}
|
|
40421
39439
|
}
|
|
40422
|
-
function
|
|
39440
|
+
function mapFsError(error51) {
|
|
40423
39441
|
const code = error51.code;
|
|
40424
39442
|
if (code === "EACCES" || code === "EPERM") return new TheaterFolderListError("forbidden");
|
|
40425
39443
|
if (code === "ENOENT" || code === "ENOTDIR") return new TheaterFolderListError("not_found");
|
|
@@ -41148,34 +40166,6 @@ var SERVER_API_CATALOG = [
|
|
|
41148
40166
|
category: "Observer",
|
|
41149
40167
|
gate: "origin-write"
|
|
41150
40168
|
},
|
|
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
40169
|
{
|
|
41180
40170
|
method: "POST",
|
|
41181
40171
|
path: "/api/v1/updates/apply",
|
|
@@ -41333,9 +40323,14 @@ function createConsoleServer(deps = {}) {
|
|
|
41333
40323
|
},
|
|
41334
40324
|
registerSseChannel: () => () => void 0
|
|
41335
40325
|
},
|
|
40326
|
+
server: {
|
|
40327
|
+
origin: () => {
|
|
40328
|
+
const activePort = lockHandle?.payload.port ?? port;
|
|
40329
|
+
return activePort ? `http://127.0.0.1:${activePort}` : null;
|
|
40330
|
+
}
|
|
40331
|
+
},
|
|
41336
40332
|
paths: {
|
|
41337
40333
|
fleetDataDir,
|
|
41338
|
-
capturesDir: durablePaths.capturesDir,
|
|
41339
40334
|
pluginDataDir: (pluginId) => path23__default.join(durablePaths.dir, "plugins", pluginId),
|
|
41340
40335
|
resolveTheaterPath: (theaterId) => theaters.get(theaterId)?.realpath ?? null,
|
|
41341
40336
|
canonicalizeTheaterPath: canonicalizeTheaterPathSync,
|
|
@@ -41458,40 +40453,6 @@ function createConsoleServer(deps = {}) {
|
|
|
41458
40453
|
systemFonts: deps.systemFonts ?? createSystemFontsService(),
|
|
41459
40454
|
writeJson
|
|
41460
40455
|
});
|
|
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
40456
|
const codexWorkspaceRouter = createCodexWorkspaceRouter({
|
|
41496
40457
|
getTheater: (theaterId) => theaters.get(theaterId),
|
|
41497
40458
|
isAuthorized: isTerminalAuthorized,
|
|
@@ -41592,10 +40553,6 @@ function createConsoleServer(deps = {}) {
|
|
|
41592
40553
|
runAsyncHandler(handleTheaterFolderGrants(req, res), res);
|
|
41593
40554
|
return;
|
|
41594
40555
|
}
|
|
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
40556
|
const restoreMatch = pathname.match(/^\/api\/v1\/deletions\/([^/]+)\/restore$/);
|
|
41600
40557
|
if (restoreMatch) {
|
|
41601
40558
|
runAsyncHandler(handleDeferredDeletionRestore(req, res, decodeURIComponent(restoreMatch[1] ?? "")), res);
|
|
@@ -41690,7 +40647,7 @@ function createConsoleServer(deps = {}) {
|
|
|
41690
40647
|
return;
|
|
41691
40648
|
}
|
|
41692
40649
|
const body2 = await readJsonBody(req);
|
|
41693
|
-
if (!
|
|
40650
|
+
if (!isPlainObject2(body2) || body2.path !== void 0 && body2.path !== null && typeof body2.path !== "string") {
|
|
41694
40651
|
writeJson(res, 400, { error: "invalid_path" });
|
|
41695
40652
|
return;
|
|
41696
40653
|
}
|
|
@@ -41715,7 +40672,7 @@ function createConsoleServer(deps = {}) {
|
|
|
41715
40672
|
return;
|
|
41716
40673
|
}
|
|
41717
40674
|
const body2 = await readJsonBody(req);
|
|
41718
|
-
if (!
|
|
40675
|
+
if (!isPlainObject2(body2) || typeof body2.path !== "string") {
|
|
41719
40676
|
writeJson(res, 400, { error: "invalid_folder" });
|
|
41720
40677
|
return;
|
|
41721
40678
|
}
|
|
@@ -41739,7 +40696,7 @@ function createConsoleServer(deps = {}) {
|
|
|
41739
40696
|
return;
|
|
41740
40697
|
}
|
|
41741
40698
|
const body2 = await readJsonBody(req);
|
|
41742
|
-
if (!
|
|
40699
|
+
if (!isPlainObject2(body2) || typeof body2.folderGrantId !== "string") {
|
|
41743
40700
|
writeJson(res, 400, { error: "invalid_folder_grant" });
|
|
41744
40701
|
return;
|
|
41745
40702
|
}
|
|
@@ -41769,7 +40726,7 @@ function createConsoleServer(deps = {}) {
|
|
|
41769
40726
|
}
|
|
41770
40727
|
if (req.method === "PATCH") {
|
|
41771
40728
|
const body2 = await readJsonBody(req);
|
|
41772
|
-
if (!
|
|
40729
|
+
if (!isPlainObject2(body2) || typeof body2.order !== "number" || !Number.isInteger(body2.order) || body2.order < 0) {
|
|
41773
40730
|
writeJson(res, 400, { error: "invalid_theater_order" });
|
|
41774
40731
|
return;
|
|
41775
40732
|
}
|
|
@@ -41886,7 +40843,7 @@ function createConsoleServer(deps = {}) {
|
|
|
41886
40843
|
writeJson(res, 400, { error: "invalid_update_apply_body" });
|
|
41887
40844
|
return;
|
|
41888
40845
|
}
|
|
41889
|
-
if (body2 !== null && (!
|
|
40846
|
+
if (body2 !== null && (!isPlainObject2(body2) || hasForbiddenUpdateApplyBodyKeys(body2))) {
|
|
41890
40847
|
writeJson(res, 400, { error: "invalid_update_apply_body" });
|
|
41891
40848
|
return;
|
|
41892
40849
|
}
|
|
@@ -42020,6 +40977,13 @@ function createConsoleServer(deps = {}) {
|
|
|
42020
40977
|
operations.replaceGroups([]);
|
|
42021
40978
|
}
|
|
42022
40979
|
deletionCoordinator.load(state.deletionTombstones ?? []);
|
|
40980
|
+
migrateLegacyCaptures({
|
|
40981
|
+
consoleDataDir: durablePaths.dir,
|
|
40982
|
+
operations,
|
|
40983
|
+
// 삭제 유예 중인 Operation은 live store에 없으므로 tombstone에서 flatten해 넘긴다.
|
|
40984
|
+
tombstonedOperations: deletionCoordinator.list().flatMap((tombstone) => tombstone.kind === "operation" ? [tombstone.operation] : tombstone.operations),
|
|
40985
|
+
save: () => saveDurableState(deletionCoordinator.list())
|
|
40986
|
+
});
|
|
42023
40987
|
try {
|
|
42024
40988
|
deletionCoordinator.sweepExpired();
|
|
42025
40989
|
} catch (error51) {
|
|
@@ -42281,7 +41245,7 @@ function theaterFolderListStatus(error51) {
|
|
|
42281
41245
|
if (error51.code === "not_found") return 404;
|
|
42282
41246
|
return 400;
|
|
42283
41247
|
}
|
|
42284
|
-
function
|
|
41248
|
+
function isPlainObject2(value) {
|
|
42285
41249
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
42286
41250
|
}
|
|
42287
41251
|
function hasForbiddenUpdateApplyBodyKeys(body2) {
|
|
@@ -42291,7 +41255,7 @@ function isValidConsoleStaticPort3(value) {
|
|
|
42291
41255
|
return typeof value === "number" && Number.isInteger(value) && value >= MIN_CONSOLE_STATIC_PORT3 && value <= MAX_CONSOLE_STATIC_PORT3;
|
|
42292
41256
|
}
|
|
42293
41257
|
function sanitizeLaunchKind(value) {
|
|
42294
|
-
if (!
|
|
41258
|
+
if (!isPlainObject2(value) || typeof value.id !== "string" || typeof value.type !== "string" || typeof value.title !== "string") return null;
|
|
42295
41259
|
return {
|
|
42296
41260
|
id: value.id,
|
|
42297
41261
|
type: value.type,
|
|
@@ -42427,12 +41391,12 @@ function parseConsoleCliMode(argv) {
|
|
|
42427
41391
|
mode = "status";
|
|
42428
41392
|
} else {
|
|
42429
41393
|
throw new Error(`Unknown fleet console command: ${first}
|
|
42430
|
-
Run 'fleet
|
|
41394
|
+
Run 'fleet-console --help' for usage.`);
|
|
42431
41395
|
}
|
|
42432
41396
|
for (const arg of rest) {
|
|
42433
41397
|
if (arg === "--help" || arg === "-h") return "help";
|
|
42434
41398
|
throw new Error(`Unknown fleet console option: ${arg}
|
|
42435
|
-
Run 'fleet
|
|
41399
|
+
Run 'fleet-console --help' for usage.`);
|
|
42436
41400
|
}
|
|
42437
41401
|
return mode;
|
|
42438
41402
|
}
|
|
@@ -42460,8 +41424,7 @@ function buildConsoleHelpText(options = {}) {
|
|
|
42460
41424
|
dim("Observe carrier jobs, live output streams, and console-owned terminal sessions.", colorEnabled),
|
|
42461
41425
|
"",
|
|
42462
41426
|
section("USAGE", colorEnabled),
|
|
42463
|
-
` ${command("fleet
|
|
42464
|
-
` ${dim("Standalone binary:", colorEnabled)} ${command("fleet-console", colorEnabled)} ${dim("[start|stop|restart|status]", colorEnabled)}`,
|
|
41427
|
+
` ${command("fleet-console", colorEnabled)} ${dim("[start|stop|restart|status] [--help]", colorEnabled)}`,
|
|
42465
41428
|
"",
|
|
42466
41429
|
section("COMMANDS", colorEnabled),
|
|
42467
41430
|
` ${command("start", colorEnabled)} ${dim("Ensure the local Fleet Console server, then open it in your browser. (default)", colorEnabled)}`,
|
|
@@ -42473,10 +41436,10 @@ function buildConsoleHelpText(options = {}) {
|
|
|
42473
41436
|
` ${option("--help, -h", colorEnabled)} ${dim("Show this help message and exit.", colorEnabled)}`,
|
|
42474
41437
|
"",
|
|
42475
41438
|
section("EXAMPLES", colorEnabled),
|
|
42476
|
-
` ${command("fleet
|
|
42477
|
-
` ${command("fleet
|
|
42478
|
-
` ${command("fleet
|
|
42479
|
-
` ${command("fleet
|
|
41439
|
+
` ${command("fleet-console", colorEnabled)}`,
|
|
41440
|
+
` ${command("fleet-console status", colorEnabled)}`,
|
|
41441
|
+
` ${command("fleet-console restart", colorEnabled)}`,
|
|
41442
|
+
` ${command("fleet-console stop", colorEnabled)}`,
|
|
42480
41443
|
""
|
|
42481
41444
|
];
|
|
42482
41445
|
const text = lines.join("\n");
|
|
@@ -42719,8 +41682,15 @@ function readStdinBestEffort() {
|
|
|
42719
41682
|
});
|
|
42720
41683
|
});
|
|
42721
41684
|
}
|
|
42722
|
-
|
|
42723
|
-
if (
|
|
41685
|
+
function isCliDirectRun(argv1, moduleUrl = import.meta.url) {
|
|
41686
|
+
if (!argv1) return false;
|
|
41687
|
+
try {
|
|
41688
|
+
return fs10__default.realpathSync(path23__default.resolve(argv1)) === fs10__default.realpathSync(fileURLToPath(moduleUrl));
|
|
41689
|
+
} catch {
|
|
41690
|
+
return false;
|
|
41691
|
+
}
|
|
41692
|
+
}
|
|
41693
|
+
if (isCliDirectRun(process4.argv[1])) {
|
|
42724
41694
|
await main().catch((error51) => {
|
|
42725
41695
|
process4.stderr.write(`${error51 instanceof Error ? error51.message : String(error51)}
|
|
42726
41696
|
`);
|
|
@@ -42728,4 +41698,4 @@ if (isDirectRun) {
|
|
|
42728
41698
|
});
|
|
42729
41699
|
}
|
|
42730
41700
|
|
|
42731
|
-
export { assertCliCanControlDaemon, buildConsoleHelpText, createConsoleDaemonLifecycle, isLockProcessAlive, main, openFleetConsole, parseConsoleCliMode, parseConsoleHookCommand, runConsoleRestart, runConsoleStatus, runConsoleStop };
|
|
41701
|
+
export { assertCliCanControlDaemon, buildConsoleHelpText, createConsoleDaemonLifecycle, isCliDirectRun, isLockProcessAlive, main, openFleetConsole, parseConsoleCliMode, parseConsoleHookCommand, runConsoleRestart, runConsoleStatus, runConsoleStop };
|