@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.
Files changed (71) hide show
  1. package/README.md +2 -3
  2. package/dist/cli.d.ts +2 -1
  3. package/dist/cli.mjs +152 -1182
  4. package/dist/client/assets/{_baseUniq-BDfju2rW.js → _baseUniq-CImzMrtU.js} +1 -1
  5. package/dist/client/assets/{arc-DWcMv-ui.js → arc-CKb0rHjN.js} +1 -1
  6. package/dist/client/assets/{architectureDiagram-Q4EWVU46-DhPv_Uba.js → architectureDiagram-Q4EWVU46-BaZipXSe.js} +1 -1
  7. package/dist/client/assets/{blockDiagram-DXYQGD6D-D7RYcNDP.js → blockDiagram-DXYQGD6D-D4sS9TjR.js} +1 -1
  8. package/dist/client/assets/{c4Diagram-AHTNJAMY-9_4dQBo3.js → c4Diagram-AHTNJAMY-DvjpMsKx.js} +1 -1
  9. package/dist/client/assets/channel-dSuGhtYS.js +1 -0
  10. package/dist/client/assets/{chunk-4BX2VUAB-CQf5x2mT.js → chunk-4BX2VUAB-B47BryhY.js} +1 -1
  11. package/dist/client/assets/{chunk-4TB4RGXK-eeG8BKQB.js → chunk-4TB4RGXK-DKIhSC52.js} +1 -1
  12. package/dist/client/assets/{chunk-55IACEB6-1dkBlsDt.js → chunk-55IACEB6-B3Gvpef7.js} +1 -1
  13. package/dist/client/assets/{chunk-EDXVE4YY-C5vcF-lT.js → chunk-EDXVE4YY-C4gFtvU8.js} +1 -1
  14. package/dist/client/assets/{chunk-FMBD7UC4-CGelAuwP.js → chunk-FMBD7UC4-BADPieOa.js} +1 -1
  15. package/dist/client/assets/{chunk-OYMX7WX6-CbKgVyop.js → chunk-OYMX7WX6-BUdtWGUY.js} +1 -1
  16. package/dist/client/assets/{chunk-QZHKN3VN-CT0ppG8R.js → chunk-QZHKN3VN-CMxkeGnM.js} +1 -1
  17. package/dist/client/assets/{chunk-YZCP3GAM-BEf8DhxB.js → chunk-YZCP3GAM-Br6N7t8d.js} +1 -1
  18. package/dist/client/assets/classDiagram-6PBFFD2Q-DEN4mh7x.js +1 -0
  19. package/dist/client/assets/classDiagram-v2-HSJHXN6E-DEN4mh7x.js +1 -0
  20. package/dist/client/assets/clone-BbTnmCoq.js +1 -0
  21. package/dist/client/assets/{cose-bilkent-S5V4N54A-C6GtvpYi.js → cose-bilkent-S5V4N54A-D1Uw7i5_.js} +1 -1
  22. package/dist/client/assets/{dagre-KV5264BT-DvrU2BgH.js → dagre-KV5264BT-kop0bHkM.js} +1 -1
  23. package/dist/client/assets/{diagram-5BDNPKRD-Cy1qKKqt.js → diagram-5BDNPKRD-B9e41qNA.js} +1 -1
  24. package/dist/client/assets/{diagram-G4DWMVQ6-C4GGKnnD.js → diagram-G4DWMVQ6-Wew8X03k.js} +1 -1
  25. package/dist/client/assets/{diagram-MMDJMWI5-By7JFsIw.js → diagram-MMDJMWI5-DGBb5Oqa.js} +1 -1
  26. package/dist/client/assets/{diagram-TYMM5635-YwzVWpID.js → diagram-TYMM5635-CiVNsAz6.js} +1 -1
  27. package/dist/client/assets/{erDiagram-SMLLAGMA-CDsNlmLk.js → erDiagram-SMLLAGMA-BdemYTgC.js} +1 -1
  28. package/dist/client/assets/{flowDiagram-DWJPFMVM-BuUpIzTa.js → flowDiagram-DWJPFMVM-CXC6yxhU.js} +1 -1
  29. package/dist/client/assets/{ganttDiagram-T4ZO3ILL-Dqv9t2x8.js → ganttDiagram-T4ZO3ILL-SMUpaiUg.js} +1 -1
  30. package/dist/client/assets/{gitGraphDiagram-UUTBAWPF-DApQn2c7.js → gitGraphDiagram-UUTBAWPF-UaFgTHEh.js} +1 -1
  31. package/dist/client/assets/{graph-CyX-IC4n.js → graph-Ch8F0gMI.js} +1 -1
  32. package/dist/client/assets/index-D38r12i5.css +1 -0
  33. package/dist/client/assets/index-DkTcJcbj.js +452 -0
  34. package/dist/client/assets/{infoDiagram-42DDH7IO-DIf3qelw.js → infoDiagram-42DDH7IO-BHBzw0bu.js} +1 -1
  35. package/dist/client/assets/{ishikawaDiagram-UXIWVN3A-CU3QtNdx.js → ishikawaDiagram-UXIWVN3A-CnDea8bw.js} +1 -1
  36. package/dist/client/assets/{journeyDiagram-VCZTEJTY-Dfq4OBhW.js → journeyDiagram-VCZTEJTY-CI91m8BP.js} +1 -1
  37. package/dist/client/assets/{kanban-definition-6JOO6SKY-CWSe3eh7.js → kanban-definition-6JOO6SKY-D-rn-rG2.js} +1 -1
  38. package/dist/client/assets/{layout-CfdpDpEB.js → layout-Cd9zpG94.js} +1 -1
  39. package/dist/client/assets/{linear-BQA5wLDW.js → linear-Cucr1ojd.js} +1 -1
  40. package/dist/client/assets/{mermaid.core-BwJS5O4y.js → mermaid.core-G36P12JZ.js} +4 -4
  41. package/dist/client/assets/{min-Cg-Q6TB5.js → min-CzfCLG7v.js} +1 -1
  42. package/dist/client/assets/{mindmap-definition-QFDTVHPH-BNXT0q7L.js → mindmap-definition-QFDTVHPH-4e1VjBV7.js} +1 -1
  43. package/dist/client/assets/{pieDiagram-DEJITSTG-Cot4WNe7.js → pieDiagram-DEJITSTG-m2CGbU51.js} +1 -1
  44. package/dist/client/assets/{quadrantDiagram-34T5L4WZ-_YW3nZwc.js → quadrantDiagram-34T5L4WZ-BKNPGqMc.js} +1 -1
  45. package/dist/client/assets/{requirementDiagram-MS252O5E-didEilrX.js → requirementDiagram-MS252O5E-D2BMwnpz.js} +1 -1
  46. package/dist/client/assets/{sankeyDiagram-XADWPNL6-CIpzp5Ep.js → sankeyDiagram-XADWPNL6-Bm6hTqEh.js} +1 -1
  47. package/dist/client/assets/{sequenceDiagram-FGHM5R23-CqvwD_CI.js → sequenceDiagram-FGHM5R23-Ds2FEGPj.js} +1 -1
  48. package/dist/client/assets/{stateDiagram-FHFEXIEX-D492KgCG.js → stateDiagram-FHFEXIEX-CrXn2Tb7.js} +1 -1
  49. package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-BbzpXIlW.js +1 -0
  50. package/dist/client/assets/{timeline-definition-GMOUNBTQ-BpAwqH0H.js → timeline-definition-GMOUNBTQ-mw053fb5.js} +1 -1
  51. package/dist/client/assets/{vennDiagram-DHZGUBPP-DDMPO_HG.js → vennDiagram-DHZGUBPP-CAws0Vt2.js} +1 -1
  52. package/dist/client/assets/{wardley-RL74JXVD-TKEj0wFU.js → wardley-RL74JXVD-DGad2cmz.js} +1 -1
  53. package/dist/client/assets/{wardleyDiagram-NUSXRM2D-CLjBh2KA.js → wardleyDiagram-NUSXRM2D-BlIyft8I.js} +1 -1
  54. package/dist/client/assets/{xychartDiagram-5P7HB3ND-DEn2Z9lG.js → xychartDiagram-5P7HB3ND-DHmSULAI.js} +1 -1
  55. package/dist/client/index.html +2 -2
  56. package/dist/client/theme-boot.js +5 -4
  57. package/dist/fleet-plugins/file-explorer/routes.mjs +484 -56
  58. package/dist/fleet-plugins/ledger/routes.mjs +56 -80
  59. package/dist/fleet-plugins/quota/routes.mjs +19806 -0
  60. package/dist/fleet-plugins/repository/routes.mjs +274 -17
  61. package/dist/fleet-plugins/scuttlebutt/routes.mjs +6 -431
  62. package/dist/fleet-plugins/skills/routes.mjs +1 -79
  63. package/dist/fleet-plugins/terminal/routes.mjs +12449 -2974
  64. package/package.json +1 -1
  65. package/dist/client/assets/channel-Cjiuj1tM.js +0 -1
  66. package/dist/client/assets/classDiagram-6PBFFD2Q-B-_6FtAZ.js +0 -1
  67. package/dist/client/assets/classDiagram-v2-HSJHXN6E-B-_6FtAZ.js +0 -1
  68. package/dist/client/assets/clone-BF2H_qSP.js +0 -1
  69. package/dist/client/assets/index-RzoF0XVt.js +0 -452
  70. package/dist/client/assets/index-bog2t8Rz.css +0 -1
  71. 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", "kimiModel", "agentIdleDormantMinutes"]);
914
- const changed = Object.keys(value).some((key) => !allowedKeys.has(key)) || "enableMetaphor" in value && typeof value.enableMetaphor !== "boolean" || "kimiModel" in value && kimiModel === void 0 || "agentIdleDormantMinutes" in value && agentIdleDormantMinutes === void 0;
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
- daywatch: { color: "#e6ecf2", symbolColor: "#3e4953", height: 43 },
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 === "daywatch" || value.theme === "whites" || value.theme === "drydock" ? value.theme : void 0;
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 !== "daywatch" && body2.theme !== "whites" && body2.theme !== "drydock") {
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 === "daywatch" || body2.theme === "whites" || body2.theme === "drydock" ? body2.theme : void 0;
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, path49) {
13527
- if (!path49)
13458
+ function getElementAtPath(obj, path48) {
13459
+ if (!path48)
13528
13460
  return obj;
13529
- return path49.reduce((acc, key) => acc?.[key], obj);
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(path49, issues) {
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(path49);
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, path49 = []) => {
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 }, [...path49, ...issue3.path]));
14024
+ issue3.errors.map((issues) => processError({ issues }, [...path48, ...issue3.path]));
14093
14025
  } else if (issue3.code === "invalid_key") {
14094
- processError({ issues: issue3.issues }, [...path49, ...issue3.path]);
14026
+ processError({ issues: issue3.issues }, [...path48, ...issue3.path]);
14095
14027
  } else if (issue3.code === "invalid_element") {
14096
- processError({ issues: issue3.issues }, [...path49, ...issue3.path]);
14028
+ processError({ issues: issue3.issues }, [...path48, ...issue3.path]);
14097
14029
  } else {
14098
- const fullpath = [...path49, ...issue3.path];
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, path49 = []) => {
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 }, [...path49, ...issue3.path]));
14061
+ issue3.errors.map((issues) => processError({ issues }, [...path48, ...issue3.path]));
14130
14062
  } else if (issue3.code === "invalid_key") {
14131
- processError({ issues: issue3.issues }, [...path49, ...issue3.path]);
14063
+ processError({ issues: issue3.issues }, [...path48, ...issue3.path]);
14132
14064
  } else if (issue3.code === "invalid_element") {
14133
- processError({ issues: issue3.issues }, [...path49, ...issue3.path]);
14065
+ processError({ issues: issue3.issues }, [...path48, ...issue3.path]);
14134
14066
  } else {
14135
- const fullpath = [...path49, ...issue3.path];
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 path49 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
14168
- for (const seg of path49) {
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 path49 = ref.slice(1).split("/").filter(Boolean);
26833
- if (path49.length === 0) {
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 (path49[0] === defsKey) {
26838
- const key = path49[1];
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" || this.cliType === "claude-kimi";
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, ...mappingEnv, ...options.env });
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
- case "claude-kimi":
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, claude-kimi, codex, opencode-go, cursor \uC911 \uD558\uB098\uB97C \uC124\uCE58\uD574\uC8FC\uC138\uC694."
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 tools = runtime.registry.getAllAgentTools();
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
- // core/host/plans/plan-parse.ts
38834
- var TITLE_PATTERN = /^#\s+(.+)$/;
38835
- var EXECUTION_MODE_PATTERN = /^-\s*Execution mode:\s*(sequential|parallel)\b/i;
38836
- var WAVE_PATTERN = /^##\s+wave\s+(\d+)\b/i;
38837
- var LANE_PATTERN = /^###\s+lane\s+(.+)$/i;
38838
- var LANE_ID_PATTERN = /^(W\d+-[A-Za-z0-9]+)\b/i;
38839
- var LANE_BOUNDARY_PATTERN = /^#{1,3}\s/;
38840
- var SECTION_HEADING_PATTERN = /^#{1,2}\s/;
38841
- var CHECKBOX_PATTERN = /^\s*-\s*\[( |x|X)\]/;
38842
- var FENCE_PATTERN = /^\s*(`{3,}|~{3,})/;
38843
- var CLOSING_FENCE_PATTERN = /^\s*(`{3,}|~{3,})\s*$/;
38844
- var TEMPLATE_SECTION_TITLES = /* @__PURE__ */ new Set([
38845
- "objective",
38846
- "file ownership",
38847
- "waves",
38848
- "qa gates",
38849
- "acceptance criteria",
38850
- "documentation updates",
38851
- "final review loop"
38852
- ]);
38853
- function parsePlan(content) {
38854
- const lines = scanPlanLines(content.split(/\r?\n/));
38855
- const title = findTitle(lines);
38856
- const executionMode = findExecutionMode(lines);
38857
- const waveStarts = findWaveStarts(lines);
38858
- const waves = waveStarts.map(({ index, heading, lineIndex }, waveIndex) => {
38859
- const nextWaveLineIndex = waveStarts[waveIndex + 1]?.lineIndex ?? lines.length;
38860
- const endLineIndex = findSectionEnd(lines, lineIndex + 1, nextWaveLineIndex);
38861
- const waveLines = lines.slice(lineIndex + 1, endLineIndex);
38862
- const counts = countTasks(waveLines);
38863
- return { index, heading, lanes: findLanes(waveLines), ...counts };
38864
- });
38865
- return { title, executionMode, waves, ...countTasks(lines) };
38866
- }
38867
- function scanPlanLines(lines) {
38868
- let activeFence = null;
38869
- return lines.map((text) => {
38870
- if (activeFence !== null) {
38871
- const closer = CLOSING_FENCE_PATTERN.exec(text)?.[1];
38872
- if (closer !== void 0 && closer.startsWith(activeFence.char) && closer.length >= activeFence.length) {
38873
- activeFence = null;
38874
- }
38875
- return { text, isFenced: true };
38876
- }
38877
- const marker = FENCE_PATTERN.exec(text)?.[1];
38878
- if (marker !== void 0) {
38879
- activeFence = { char: marker[0] ?? "`", length: marker.length };
38880
- return { text, isFenced: true };
38881
- }
38882
- return { text, isFenced: false };
38883
- });
38884
- }
38885
- function findTitle(lines) {
38886
- for (const line of lines) {
38887
- if (line.isFenced) continue;
38888
- const match = TITLE_PATTERN.exec(line.text);
38889
- if (!match?.[1]) continue;
38890
- const heading = match[1].trim();
38891
- if (TEMPLATE_SECTION_TITLES.has(heading.toLowerCase())) return null;
38892
- return heading;
38893
- }
38894
- return null;
38895
- }
38896
- function findExecutionMode(lines) {
38897
- for (const line of lines) {
38898
- if (line.isFenced) continue;
38899
- const match = EXECUTION_MODE_PATTERN.exec(line.text.trim());
38900
- if (match?.[1]) return match[1].toLowerCase();
38901
- }
38902
- return null;
38903
- }
38904
- function findWaveStarts(lines) {
38905
- const waves = [];
38906
- for (const [lineIndex, line] of lines.entries()) {
38907
- if (line.isFenced) continue;
38908
- const match = WAVE_PATTERN.exec(line.text);
38909
- if (!match?.[1]) continue;
38910
- waves.push({
38911
- index: Number(match[1]),
38912
- heading: line.text.replace(/^##\s+/, ""),
38913
- lineIndex
38914
- });
38915
- }
38916
- return waves;
38917
- }
38918
- function findLanes(waveLines) {
38919
- const laneStarts = [];
38920
- for (const [lineIndex, line] of waveLines.entries()) {
38921
- if (line.isFenced) continue;
38922
- const match = LANE_PATTERN.exec(line.text);
38923
- if (!match?.[1]) continue;
38924
- const heading = match[1].trim();
38925
- laneStarts.push({ heading, id: LANE_ID_PATTERN.exec(heading)?.[1]?.toUpperCase() ?? null, lineIndex });
38926
- }
38927
- return laneStarts.map(({ heading, id, lineIndex }, laneIndex) => {
38928
- const nextLaneLineIndex = laneStarts[laneIndex + 1]?.lineIndex ?? waveLines.length;
38929
- let endLineIndex = nextLaneLineIndex;
38930
- for (let cursor = lineIndex + 1; cursor < nextLaneLineIndex; cursor++) {
38931
- const line = waveLines[cursor];
38932
- if (!line?.isFenced && LANE_BOUNDARY_PATTERN.test(line?.text ?? "")) {
38933
- endLineIndex = cursor;
38934
- break;
38935
- }
38936
- }
38937
- return { id, heading, ...countTasks(waveLines.slice(lineIndex + 1, endLineIndex)) };
38938
- });
38939
- }
38940
- function findSectionEnd(lines, startLineIndex, maxLineIndex) {
38941
- for (let lineIndex = startLineIndex; lineIndex < maxLineIndex; lineIndex++) {
38942
- const line = lines[lineIndex];
38943
- if (!line?.isFenced && SECTION_HEADING_PATTERN.test(line?.text ?? "")) return lineIndex;
38944
- }
38945
- return maxLineIndex;
38946
- }
38947
- function countTasks(lines) {
38948
- let tasksDone = 0;
38949
- let tasksTotal = 0;
38950
- for (const line of lines) {
38951
- if (line.isFenced) continue;
38952
- const match = CHECKBOX_PATTERN.exec(line.text);
38953
- if (!match) continue;
38954
- tasksTotal++;
38955
- if (match[1] === "x" || match[1] === "X") tasksDone++;
38956
- }
38957
- return { tasksDone, tasksTotal };
38958
- }
38959
-
38960
- // core/host/plans/plan-store.ts
38961
- var PLANS_DIRECTORY_NAME = "plans";
38962
- var MARKDOWN_EXTENSION = ".md";
38963
- var PLAN_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*\.md$/;
38964
- var LIST_READ_CONCURRENCY = 16;
38965
- var PLAN_READ_SIZE_CAP = 2 * 1024 * 1024;
38966
- var PlanStoreError = class extends Error {
38967
- code;
38968
- constructor(code) {
38969
- super(code);
38970
- this.name = "PlanStoreError";
38971
- this.code = code;
38972
- }
38973
- };
38974
- async function listPlansForWorkspace(dataDir, cwd) {
38975
- const plansRoot = resolvePlansRoot(dataDir, cwd, true);
38976
- if (plansRoot === null) return [];
38977
- let entries;
38978
- try {
38979
- entries = await fs10__default.promises.readdir(plansRoot.plansPath, { withFileTypes: true });
38980
- } catch (error51) {
38981
- throw toPlanStoreError(error51);
38982
- }
38983
- const names = entries.filter((entry) => (entry.isFile() || entry.isSymbolicLink()) && entry.name.endsWith(MARKDOWN_EXTENSION) && isValidPlanName(entry.name)).map((entry) => entry.name);
38984
- const plans = [];
38985
- for (let startIndex = 0; startIndex < names.length; startIndex += LIST_READ_CONCURRENCY) {
38986
- const chunk = names.slice(startIndex, startIndex + LIST_READ_CONCURRENCY);
38987
- const results = await Promise.all(chunk.map((name) => toPlanListItem(plansRoot, name).catch(() => null)));
38988
- plans.push(...results.filter((plan) => plan !== null));
38989
- }
38990
- return plans.sort((left, right) => right.updatedAt.localeCompare(left.updatedAt));
38991
- }
38992
- function resolvePlansWatchDirectory(dataDir, cwd) {
38993
- return resolvePlansRoot(dataDir, cwd, true)?.plansPath ?? null;
38994
- }
38995
- function isValidPlanName(name) {
38996
- return PLAN_NAME_PATTERN.test(name) && !name.includes("..");
38997
- }
38998
- async function readPlanForWorkspace(dataDir, cwd, name) {
38999
- const plansRoot = resolvePlansRoot(dataDir, cwd, false);
39000
- if (plansRoot === null) throw new PlanStoreError("not_found");
39001
- const file2 = await resolvePlanFile(plansRoot, name);
39002
- if (file2.stat.size > PLAN_READ_SIZE_CAP) throw new PlanStoreError("too_large");
39003
- let content;
38328
+ var LEGACY_CAPTURES_DIR_NAME = "captures";
38329
+ function migrateLegacyCaptures(deps) {
39004
38330
  try {
39005
- content = await fs10__default.promises.readFile(file2.path, "utf8");
38331
+ migrateLegacyCapturesStrict(deps);
39006
38332
  } catch (error51) {
39007
- throw toPlanStoreError(error51);
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
- async function deletePlanForWorkspace(dataDir, cwd, name) {
39022
- const plansRoot = resolvePlansRoot(dataDir, cwd, false);
39023
- if (plansRoot === null) throw new PlanStoreError("not_found");
39024
- const file2 = await resolvePlanFile(plansRoot, name);
39025
- try {
39026
- await fs10__default.promises.unlink(file2.path);
39027
- } catch (error51) {
39028
- throw toPlanStoreError(error51);
39029
- }
39030
- }
39031
- async function toPlanListItem(plansRoot, name) {
39032
- const file2 = await resolvePlanFile(plansRoot, name);
39033
- if (file2.stat.size > PLAN_READ_SIZE_CAP) {
39034
- return {
39035
- name,
39036
- title: name,
39037
- executionMode: null,
39038
- waveCount: 0,
39039
- tasksDone: 0,
39040
- tasksTotal: 0,
39041
- updatedAt: file2.stat.mtime.toISOString(),
39042
- sizeBytes: file2.stat.size
39043
- };
39044
- }
39045
- const content = await fs10__default.promises.readFile(file2.path, "utf8").catch((error51) => {
39046
- throw toPlanStoreError(error51);
39047
- });
39048
- const parsed = parsePlan(content);
39049
- return {
39050
- name,
39051
- title: parsed.title ?? name,
39052
- executionMode: parsed.executionMode,
39053
- waveCount: parsed.waves.length,
39054
- tasksDone: parsed.tasksDone,
39055
- tasksTotal: parsed.tasksTotal,
39056
- updatedAt: file2.stat.mtime.toISOString(),
39057
- sizeBytes: file2.stat.size
39058
- };
39059
- }
39060
- function resolvePlansRoot(dataDir, cwd, allowMissing) {
39061
- let workspace;
39062
- try {
39063
- workspace = findWorkspaceDirectory(dataDir, cwd);
39064
- } catch {
39065
- throw new PlanStoreError("unsafe_path");
39066
- }
39067
- if (!workspace) {
39068
- if (allowMissing) return null;
39069
- throw new PlanStoreError("not_found");
39070
- }
39071
- const plansPath = path23__default.join(workspace.path, PLANS_DIRECTORY_NAME);
39072
- assertWithinRoot(workspace.path, plansPath);
39073
- const stat4 = safeLstat(plansPath);
39074
- if (!stat4) {
39075
- if (allowMissing) return null;
39076
- throw new PlanStoreError("not_found");
39077
- }
39078
- if (!stat4.isDirectory() || stat4.isSymbolicLink()) throw new PlanStoreError("unsafe_path");
39079
- return { plansPath, workspacePath: workspace.path };
39080
- }
39081
- async function resolvePlanFile(plansRoot, name) {
39082
- try {
39083
- const candidatePath = path23__default.resolve(plansRoot.plansPath, name);
39084
- assertWithinRoot(plansRoot.plansPath, candidatePath);
39085
- assertWithinRoot(plansRoot.workspacePath, candidatePath);
39086
- const stat4 = safeLstat(candidatePath);
39087
- if (stat4?.isSymbolicLink()) throw new PlanStoreError("unsafe_path");
39088
- if (!stat4?.isFile()) throw new PlanStoreError("not_found");
39089
- return { path: candidatePath, stat: stat4 };
39090
- } catch (error51) {
39091
- if (error51 instanceof PlanStoreError) throw error51;
39092
- throw new PlanStoreError("unsafe_path");
39093
- }
39094
- }
39095
- function toPlanStoreError(error51) {
39096
- if (error51 instanceof PlanStoreError) return error51;
39097
- return new PlanStoreError("not_found");
39098
- }
39099
- var TheaterRootError = class extends Error {
39100
- code;
39101
- constructor(code) {
39102
- super(code);
39103
- this.code = code;
39104
- }
39105
- };
39106
- async function resolveTheaterRoot(theaterRoot) {
39107
- const nominalRoot = path23__default.resolve(theaterRoot);
39108
- let realRoot;
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
- realRoot = await fs10__default.promises.realpath(nominalRoot);
39111
- } catch (error51) {
39112
- throw mapFsError(error51);
39113
- }
39114
- let stat4;
39115
- try {
39116
- stat4 = await fs10__default.promises.stat(realRoot);
39117
- } catch (error51) {
39118
- throw mapFsError(error51);
39119
- }
39120
- if (!stat4.isDirectory()) throw new TheaterRootError("invalid_path");
39121
- return { realRoot };
39122
- }
39123
- function mapFsError(error51) {
39124
- const code = error51.code;
39125
- if (code === "ENOENT" || code === "ENOTDIR") return new TheaterRootError("not_found");
39126
- if (code === "EACCES" || code === "EPERM") return new TheaterRootError("forbidden");
39127
- return new TheaterRootError("invalid_path");
39128
- }
39129
-
39130
- // core/host/plans/routes.ts
39131
- function createPlansRouter(deps) {
39132
- return async function handlePlansRoute(context) {
39133
- const { req, res, pathname } = context;
39134
- if (pathname === "/api/v1/plans/list") {
39135
- await handlePlansList(req, res, deps);
39136
- return true;
39137
- }
39138
- if (pathname === "/api/v1/plans/read") {
39139
- await handlePlansRead(req, res, deps);
39140
- return true;
39141
- }
39142
- if (pathname === "/api/v1/plans/delete") {
39143
- await handlePlansDelete(req, res, deps);
39144
- return true;
39145
- }
39146
- if (pathname === "/api/v1/plans/search") {
39147
- await handlePlansSearch(req, res, deps);
39148
- return true;
39149
- }
39150
- if (pathname === "/api/v1/plans/events") {
39151
- await handlePlansEvents(req, res, deps);
39152
- return true;
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
- writePlanStoreError(res, deps, error51);
39187
- }
39188
- }
39189
- async function handlePlansEvents(req, res, deps) {
39190
- if (req.method !== "GET") {
39191
- deps.writeJson(res, 405, { error: "Method not allowed" });
39192
- return;
38358
+ retained = true;
38359
+ console.warn(`[fleet-console] Legacy capture directory read failed: ${error51 instanceof Error ? error51.message : String(error51)}`);
39193
38360
  }
39194
- if (!deps.isEventsAuthorized?.(req)) {
39195
- deps.writeJson(res, 401, { error: "unauthorized" });
39196
- return;
39197
- }
39198
- const theaterId = readEventsTheaterId(req);
39199
- if (!theaterId) {
39200
- deps.writeJson(res, 400, { error: "invalid_request" });
39201
- return;
39202
- }
39203
- const theaterPath = deps.resolveTheaterPath(theaterId);
39204
- if (!theaterPath) {
39205
- deps.writeJson(res, 404, { error: "theater_not_found" });
39206
- return;
39207
- }
39208
- try {
39209
- const context = await resolveTheaterRoot(theaterPath);
39210
- const watchPath = resolvePlansWatchDirectory(deps.dataDir, context.realRoot);
39211
- if (!watchPath || !deps.subscribeToChanges) {
39212
- deps.writeJson(res, 404, { error: "not_found" });
39213
- return;
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
- const theaterPath = deps.resolveTheaterPath(body2.theaterId);
39241
- if (!theaterPath) {
39242
- deps.writeJson(res, 404, { error: "theater_not_found" });
39243
- return;
39244
- }
39245
- try {
39246
- const context = await resolveTheaterRoot(theaterPath);
39247
- deps.writeJson(res, 200, { plans: await listPlansForWorkspace(deps.dataDir, context.realRoot) });
39248
- } catch (error51) {
39249
- writePlanStoreError(res, deps, error51);
39250
- }
39251
- }
39252
- async function handlePlansRead(req, res, deps) {
39253
- if (req.method !== "POST") {
39254
- deps.writeJson(res, 405, { error: "Method not allowed" });
39255
- return;
39256
- }
39257
- if (!deps.isAuthorized(req)) {
39258
- deps.writeJson(res, 401, { error: "unauthorized" });
39259
- return;
39260
- }
39261
- const body2 = await deps.readJsonBody(req);
39262
- if (!isPlainObject2(body2) || typeof body2.theaterId !== "string" || "relPath" in body2) {
39263
- deps.writeJson(res, 400, { error: "invalid_request" });
39264
- return;
39265
- }
39266
- if (typeof body2.name !== "string" || !isValidPlanName(body2.name)) {
39267
- deps.writeJson(res, 400, { error: "invalid_name" });
39268
- return;
39269
- }
39270
- const theaterPath = deps.resolveTheaterPath(body2.theaterId);
39271
- if (!theaterPath) {
39272
- deps.writeJson(res, 404, { error: "theater_not_found" });
39273
- return;
39274
- }
39275
- try {
39276
- const context = await resolveTheaterRoot(theaterPath);
39277
- deps.writeJson(res, 200, await readPlanForWorkspace(deps.dataDir, context.realRoot, body2.name));
39278
- } catch (error51) {
39279
- writePlanStoreError(res, deps, error51);
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
- async function handlePlansDelete(req, res, deps) {
39283
- if (req.method !== "POST") {
39284
- deps.writeJson(res, 405, { error: "Method not allowed" });
39285
- return;
39286
- }
39287
- if (!deps.isAuthorized(req)) {
39288
- deps.writeJson(res, 401, { error: "unauthorized" });
39289
- return;
39290
- }
39291
- const body2 = await deps.readJsonBody(req);
39292
- if (!isPlainObject2(body2) || typeof body2.theaterId !== "string" || "relPath" in body2) {
39293
- deps.writeJson(res, 400, { error: "invalid_request" });
39294
- return;
39295
- }
39296
- if (typeof body2.name !== "string" || !isValidPlanName(body2.name)) {
39297
- deps.writeJson(res, 400, { error: "invalid_name" });
39298
- return;
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 theaterPath = deps.resolveTheaterPath(body2.theaterId);
39301
- if (!theaterPath) {
39302
- deps.writeJson(res, 404, { error: "theater_not_found" });
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
- try {
39306
- const context = await resolveTheaterRoot(theaterPath);
39307
- await deletePlanForWorkspace(deps.dataDir, context.realRoot, body2.name);
39308
- deps.writeJson(res, 200, { deleted: true });
39309
- } catch (error51) {
39310
- writePlanStoreError(res, deps, error51);
39311
- }
39312
- }
39313
- function isPlainObject2(value) {
39314
- return typeof value === "object" && value !== null && !Array.isArray(value);
38395
+ return { migrated: false, retained: false };
39315
38396
  }
39316
- function writePlanStoreError(res, deps, error51) {
39317
- if (error51 instanceof TheaterRootError) {
39318
- const httpStatus2 = error51.code === "forbidden" ? 403 : error51.code === "not_found" ? 404 : 400;
39319
- deps.writeJson(res, httpStatus2, { error: error51.code });
39320
- return;
39321
- }
39322
- if (!(error51 instanceof PlanStoreError)) throw error51;
39323
- const httpStatus = error51.code === "unsafe_path" ? 403 : error51.code === "too_large" ? 413 : 404;
39324
- deps.writeJson(res, httpStatus, { error: error51.code });
38397
+ function hasProviderSession(payload) {
38398
+ return sanitizeProviderSession(payload?.providerSession) !== void 0;
39325
38399
  }
39326
- var PLANS_WATCH_DEBOUNCE_MS = 200;
39327
- function createPlansWatcherRegistry(watcherFactory = (watchPath, options, listener) => fs10__default.watch(watchPath, options, listener), debounceMs = PLANS_WATCH_DEBOUNCE_MS, directoryIdentity = (watchPath) => {
39328
- try {
39329
- const stat4 = fs10__default.statSync(watchPath);
39330
- return { dev: stat4.dev, ino: stat4.ino };
39331
- } catch {
39332
- return null;
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
- subscribe(watchPath, onChange, onClose) {
39338
- let entry = entries.get(watchPath);
39339
- if (!entry) {
39340
- entry = createEntry(watchPath);
39341
- if (!entry) {
39342
- onClose();
39343
- return () => {
39344
- };
39345
- }
39346
- entries.set(watchPath, entry);
39347
- }
39348
- const subscriber = { onChange, onClose };
39349
- entry.subscribers.add(subscriber);
39350
- let unsubscribed = false;
39351
- return () => {
39352
- if (unsubscribed) return;
39353
- unsubscribed = true;
39354
- entry.subscribers.delete(subscriber);
39355
- if (entry.subscribers.size !== 0) return;
39356
- closeEntry(watchPath, entry);
39357
- };
39358
- }
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
- function createEntry(watchPath) {
39361
- const subscribers = /* @__PURE__ */ new Set();
39362
- let entry;
39363
- try {
39364
- const watcher = watcherFactory(watchPath, { recursive: false }, () => {
39365
- if (entry.closed) return;
39366
- const current = directoryIdentity(watchPath);
39367
- if (!current || entry.identity === null || current.dev !== entry.identity.dev || current.ino !== entry.identity.ino) {
39368
- closeEntry(watchPath, entry, true);
39369
- return;
39370
- }
39371
- if (entry.timer) clearTimeout(entry.timer);
39372
- entry.timer = setTimeout(() => {
39373
- entry.timer = null;
39374
- for (const subscriber of entry.subscribers) subscriber.onChange();
39375
- }, debounceMs);
39376
- });
39377
- entry = { watcher, subscribers, identity: directoryIdentity(watchPath), timer: null, closed: false };
39378
- watcher.on("error", () => closeEntry(watchPath, entry, true));
39379
- return entry;
39380
- } catch {
39381
- return null;
39382
- }
39383
- }
39384
- function closeEntry(watchPath, entry, notifySubscribers = false) {
39385
- if (entry.closed) return;
39386
- entry.closed = true;
39387
- if (entry.timer) clearTimeout(entry.timer);
39388
- entry.timer = null;
39389
- try {
39390
- entry.watcher.close();
39391
- } catch {
39392
- }
39393
- if (entries.get(watchPath) === entry) entries.delete(watchPath);
39394
- if (notifySubscribers) {
39395
- for (const subscriber of entry.subscribers) subscriber.onClose();
39396
- }
39397
- }
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 !== "daywatch" && theme !== "whites" && theme !== "drydock") {
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 mapFsError2(error51);
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 mapFsError2(error51);
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 mapFsError2(error51);
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 mapFsError2(error51) {
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 (!isPlainObject3(body2) || body2.path !== void 0 && body2.path !== null && typeof body2.path !== "string") {
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 (!isPlainObject3(body2) || typeof body2.path !== "string") {
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 (!isPlainObject3(body2) || typeof body2.folderGrantId !== "string") {
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 (!isPlainObject3(body2) || typeof body2.order !== "number" || !Number.isInteger(body2.order) || body2.order < 0) {
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 && (!isPlainObject3(body2) || hasForbiddenUpdateApplyBodyKeys(body2))) {
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 isPlainObject3(value) {
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 (!isPlainObject3(value) || typeof value.id !== "string" || typeof value.type !== "string" || typeof value.title !== "string") return null;
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 console --help' for usage.`);
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 console --help' for usage.`);
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 console", colorEnabled)} ${dim("[start|stop|restart|status] [--help]", colorEnabled)}`,
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 console", colorEnabled)}`,
42477
- ` ${command("fleet console status", colorEnabled)}`,
42478
- ` ${command("fleet console restart", colorEnabled)}`,
42479
- ` ${command("fleet console stop", colorEnabled)}`,
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
- var isDirectRun = process4.argv[1] && path23__default.resolve(process4.argv[1]) === fileURLToPath(import.meta.url);
42723
- if (isDirectRun) {
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 };