@dotobokuri/fleet-console 1.54.1 → 1.56.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 (72) hide show
  1. package/AGENTS.md +1 -1
  2. package/dist/access-protocol.d.ts +58 -0
  3. package/dist/access-protocol.mjs +165 -0
  4. package/dist/cli.mjs +1205 -704
  5. package/dist/client/assets/{_baseUniq-B2XggV1b.js → _baseUniq-CK6xYLgK.js} +1 -1
  6. package/dist/client/assets/{arc-CPqvR_Wl.js → arc-SXOvBdpd.js} +1 -1
  7. package/dist/client/assets/{architectureDiagram-Q4EWVU46-BczXSpod.js → architectureDiagram-Q4EWVU46-r8NthnNU.js} +1 -1
  8. package/dist/client/assets/{blockDiagram-DXYQGD6D-BPtW_zZR.js → blockDiagram-DXYQGD6D-cThAFLEq.js} +1 -1
  9. package/dist/client/assets/{c4Diagram-AHTNJAMY-Cry2oyLL.js → c4Diagram-AHTNJAMY-BTVBd-sc.js} +1 -1
  10. package/dist/client/assets/channel-D2IH259w.js +1 -0
  11. package/dist/client/assets/{chunk-4BX2VUAB-DKkKt4m0.js → chunk-4BX2VUAB-9C8l-6y9.js} +1 -1
  12. package/dist/client/assets/{chunk-4TB4RGXK-DKGkDbqm.js → chunk-4TB4RGXK-C9D6fDG_.js} +1 -1
  13. package/dist/client/assets/{chunk-55IACEB6-DawsVr8O.js → chunk-55IACEB6-Da-xIjwX.js} +1 -1
  14. package/dist/client/assets/{chunk-EDXVE4YY-tS8vRy63.js → chunk-EDXVE4YY-BZq0sw-k.js} +1 -1
  15. package/dist/client/assets/{chunk-FMBD7UC4-B0jQQkjI.js → chunk-FMBD7UC4-DdnT_dau.js} +1 -1
  16. package/dist/client/assets/{chunk-OYMX7WX6-FZQSRkEo.js → chunk-OYMX7WX6-DNR2BWZl.js} +1 -1
  17. package/dist/client/assets/{chunk-QZHKN3VN-Bq1WBmr8.js → chunk-QZHKN3VN-Bcwbzg66.js} +1 -1
  18. package/dist/client/assets/{chunk-YZCP3GAM-CNWIYKHc.js → chunk-YZCP3GAM-DQxIeFfg.js} +1 -1
  19. package/dist/client/assets/classDiagram-6PBFFD2Q-4Tf8Kn3f.js +1 -0
  20. package/dist/client/assets/classDiagram-v2-HSJHXN6E-4Tf8Kn3f.js +1 -0
  21. package/dist/client/assets/clone-DrTZvd1g.js +1 -0
  22. package/dist/client/assets/{cose-bilkent-S5V4N54A-CmOaWS4P.js → cose-bilkent-S5V4N54A-DJHIszRn.js} +1 -1
  23. package/dist/client/assets/{dagre-KV5264BT-D2gJaf1o.js → dagre-KV5264BT-Da_rrC0z.js} +1 -1
  24. package/dist/client/assets/{diagram-5BDNPKRD-DH-M3VUk.js → diagram-5BDNPKRD-4WYyf116.js} +1 -1
  25. package/dist/client/assets/{diagram-G4DWMVQ6-169IB8uN.js → diagram-G4DWMVQ6-Bqg2XJLc.js} +1 -1
  26. package/dist/client/assets/{diagram-MMDJMWI5-D1OVxCyQ.js → diagram-MMDJMWI5-BZsChX00.js} +1 -1
  27. package/dist/client/assets/{diagram-TYMM5635-CkiS1glz.js → diagram-TYMM5635-jm8yzEDo.js} +1 -1
  28. package/dist/client/assets/{erDiagram-SMLLAGMA-CZUp7ncJ.js → erDiagram-SMLLAGMA-DSpJlu2o.js} +1 -1
  29. package/dist/client/assets/{flowDiagram-DWJPFMVM-9SIhR3aC.js → flowDiagram-DWJPFMVM-CqiKWWs9.js} +1 -1
  30. package/dist/client/assets/{ganttDiagram-T4ZO3ILL-CA4smcv3.js → ganttDiagram-T4ZO3ILL-_fJmxFiN.js} +1 -1
  31. package/dist/client/assets/{gitGraphDiagram-UUTBAWPF-DF8CSmoM.js → gitGraphDiagram-UUTBAWPF-BsdpdPvS.js} +1 -1
  32. package/dist/client/assets/{graph-Bc_ceTI8.js → graph-SYp_wy0X.js} +1 -1
  33. package/dist/client/assets/index-BVDwl8Ra.css +1 -0
  34. package/dist/client/assets/index-CMfaK7SS.js +481 -0
  35. package/dist/client/assets/{infoDiagram-42DDH7IO-BC5KSucM.js → infoDiagram-42DDH7IO-BBSeRYmH.js} +1 -1
  36. package/dist/client/assets/{ishikawaDiagram-UXIWVN3A-JJIJclQD.js → ishikawaDiagram-UXIWVN3A-ChZIc85I.js} +1 -1
  37. package/dist/client/assets/{journeyDiagram-VCZTEJTY-ERzBaHVf.js → journeyDiagram-VCZTEJTY-CvTt2PuE.js} +1 -1
  38. package/dist/client/assets/{kanban-definition-6JOO6SKY-KvnzNd3g.js → kanban-definition-6JOO6SKY-UMYXBksT.js} +1 -1
  39. package/dist/client/assets/{layout-DJbQbTix.js → layout-Cn0vKXiv.js} +1 -1
  40. package/dist/client/assets/{linear-BzBkH5Aq.js → linear-CN_VUHu1.js} +1 -1
  41. package/dist/client/assets/{mermaid.core-CAqwSbV2.js → mermaid.core-DJMXhYrb.js} +4 -4
  42. package/dist/client/assets/{min-giSfwdiX.js → min-B1XpSHw0.js} +1 -1
  43. package/dist/client/assets/{mindmap-definition-QFDTVHPH-BH0wnMRm.js → mindmap-definition-QFDTVHPH-ByB0aQCi.js} +1 -1
  44. package/dist/client/assets/{pieDiagram-DEJITSTG-WOHMlPDe.js → pieDiagram-DEJITSTG-pY6wSvtd.js} +1 -1
  45. package/dist/client/assets/{quadrantDiagram-34T5L4WZ-DcIpvIOj.js → quadrantDiagram-34T5L4WZ-CAEC8l7M.js} +1 -1
  46. package/dist/client/assets/{requirementDiagram-MS252O5E-C99uWiwG.js → requirementDiagram-MS252O5E-EZ8lFefP.js} +1 -1
  47. package/dist/client/assets/{sankeyDiagram-XADWPNL6-czWBcwBu.js → sankeyDiagram-XADWPNL6-CMKnCqsn.js} +1 -1
  48. package/dist/client/assets/{sequenceDiagram-FGHM5R23-CjtCPppG.js → sequenceDiagram-FGHM5R23-CkgQzi7b.js} +1 -1
  49. package/dist/client/assets/{stateDiagram-FHFEXIEX-D0UKF8ze.js → stateDiagram-FHFEXIEX-BJHLYr-N.js} +1 -1
  50. package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-Dume8vUa.js +1 -0
  51. package/dist/client/assets/{timeline-definition-GMOUNBTQ-3isWQZNU.js → timeline-definition-GMOUNBTQ-CGYZUMS9.js} +1 -1
  52. package/dist/client/assets/{vennDiagram-DHZGUBPP-C_LF2g8l.js → vennDiagram-DHZGUBPP-0uhxN1xs.js} +1 -1
  53. package/dist/client/assets/{wardley-RL74JXVD-Bw0Y4M6p.js → wardley-RL74JXVD-T5Y3bP7y.js} +1 -1
  54. package/dist/client/assets/{wardleyDiagram-NUSXRM2D-B6e3mxQI.js → wardleyDiagram-NUSXRM2D-DNaPZoGW.js} +1 -1
  55. package/dist/client/assets/{xychartDiagram-5P7HB3ND-DjlZXnLg.js → xychartDiagram-5P7HB3ND-BL_QQ9Qg.js} +1 -1
  56. package/dist/client/index.html +2 -2
  57. package/dist/fleet-plugins/file-explorer/routes.mjs +13 -9
  58. package/dist/fleet-plugins/ledger/routes.mjs +6 -2
  59. package/dist/fleet-plugins/quota/routes.mjs +22 -18
  60. package/dist/fleet-plugins/repository/routes.mjs +17 -13
  61. package/dist/fleet-plugins/scuttlebutt/routes.mjs +11 -2
  62. package/dist/fleet-plugins/skills/routes.mjs +14 -10
  63. package/dist/fleet-plugins/terminal/routes.mjs +317 -283
  64. package/dist/fleet.mjs +3914 -3456
  65. package/package.json +5 -1
  66. package/dist/client/assets/channel-D5C5uwWd.js +0 -1
  67. package/dist/client/assets/classDiagram-6PBFFD2Q-Cv4Bxw_r.js +0 -1
  68. package/dist/client/assets/classDiagram-v2-HSJHXN6E-Cv4Bxw_r.js +0 -1
  69. package/dist/client/assets/clone-C7dthYDe.js +0 -1
  70. package/dist/client/assets/index-NNL49IzO.css +0 -1
  71. package/dist/client/assets/index-kTAFpDLu.js +0 -479
  72. package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-BdRUP2Pp.js +0 -1
@@ -26,10 +26,18 @@ var __export = (target2, all) => {
26
26
  function definePlugin(definition) {
27
27
  return definition;
28
28
  }
29
- function registerRouter(ctx, path42, handler) {
29
+ function registerRouter(ctx, path42, handler, catalog) {
30
+ if (catalog) {
31
+ ctx.registerRouter(normalizePath(path42), handler, catalog);
32
+ return;
33
+ }
30
34
  ctx.registerRouter(normalizePath(path42), handler);
31
35
  }
32
- function registerWsHandler(ctx, path42, handler) {
36
+ function registerWsHandler(ctx, path42, handler, catalog) {
37
+ if (catalog) {
38
+ ctx.registerWsHandler(normalizePath(path42), handler, catalog);
39
+ return;
40
+ }
33
41
  ctx.registerWsHandler(normalizePath(path42), handler);
34
42
  }
35
43
  function registerLaunchCatalog(ctx, provider) {
@@ -22260,6 +22268,21 @@ function functionCallStart(item, index) {
22260
22268
  }
22261
22269
  };
22262
22270
  }
22271
+ function findCauseCode(error51) {
22272
+ let current = error51;
22273
+ const seen = /* @__PURE__ */ new Set();
22274
+ for (let depth = 0; depth <= 4; depth += 1) {
22275
+ if (current === null || typeof current !== "object") return void 0;
22276
+ if (seen.has(current)) return void 0;
22277
+ seen.add(current);
22278
+ if (Object.prototype.hasOwnProperty.call(current, "code")) {
22279
+ const code = current.code;
22280
+ if (typeof code === "string") return code;
22281
+ }
22282
+ current = current.cause;
22283
+ }
22284
+ return void 0;
22285
+ }
22263
22286
  var UpstreamBodyLimitError = class extends Error {
22264
22287
  constructor(maxBodyBytes) {
22265
22288
  super(`Upstream response exceeded ${maxBodyBytes} bytes`);
@@ -22350,6 +22373,51 @@ async function readWithIdleTimeout(reader, options) {
22350
22373
  );
22351
22374
  });
22352
22375
  }
22376
+ async function* parseUpstreamSseStream(body, options, parseFrame) {
22377
+ if (body === null) {
22378
+ options.onClose();
22379
+ throw new UpstreamProtocolError(options.missingBodyMessage);
22380
+ }
22381
+ const reader = body.getReader();
22382
+ const decoder = new TextDecoder();
22383
+ let buffer = "";
22384
+ let byteLength = 0;
22385
+ try {
22386
+ while (true) {
22387
+ const result = await readWithIdleTimeout(reader, options);
22388
+ if (result.done) {
22389
+ buffer += decoder.decode();
22390
+ break;
22391
+ }
22392
+ byteLength += result.value.byteLength;
22393
+ if (byteLength > options.maxBodyBytes) {
22394
+ const error51 = new UpstreamBodyLimitError(options.maxBodyBytes);
22395
+ options.controller.abort(error51);
22396
+ throw error51;
22397
+ }
22398
+ buffer += decoder.decode(result.value, { stream: true });
22399
+ let boundary = nextEventBoundary(buffer);
22400
+ while (boundary !== void 0) {
22401
+ const frame = buffer.slice(0, boundary.index);
22402
+ buffer = buffer.slice(boundary.index + boundary.length);
22403
+ const event = parseFrame(frame);
22404
+ if (event !== void 0) {
22405
+ yield event;
22406
+ }
22407
+ boundary = nextEventBoundary(buffer);
22408
+ }
22409
+ }
22410
+ if (buffer.trim().length > 0) {
22411
+ const event = parseFrame(buffer);
22412
+ if (event !== void 0) {
22413
+ yield event;
22414
+ }
22415
+ }
22416
+ } finally {
22417
+ await reader.cancel().catch(() => void 0);
22418
+ options.onClose();
22419
+ }
22420
+ }
22353
22421
  function nextEventBoundary(buffer) {
22354
22422
  const match = /\r\n\r\n|\n\n|\r\r/.exec(buffer);
22355
22423
  return match === null ? void 0 : { index: match.index, length: match[0].length };
@@ -22593,7 +22661,9 @@ var OpenAIResponsesAdapter = class {
22593
22661
  }
22594
22662
  };
22595
22663
  var CodexResponsesAdapter = class extends OpenAIResponsesAdapter {
22664
+ isMarkedFetchFailure;
22596
22665
  constructor(options = {}) {
22666
+ const fetchFailureTracker = createCodexFetchFailureTracker(options.fetch ?? globalThis.fetch.bind(globalThis));
22597
22667
  super({
22598
22668
  url: CHATGPT_CODEX_RESPONSES_URL,
22599
22669
  dropSamplingParams: true,
@@ -22601,11 +22671,12 @@ var CodexResponsesAdapter = class extends OpenAIResponsesAdapter {
22601
22671
  ...options.accountId ? { "chatgpt-account-id": options.accountId } : {},
22602
22672
  ...options.headers
22603
22673
  },
22604
- fetch: markCodexFetchFailures(options.fetch ?? globalThis.fetch.bind(globalThis)),
22674
+ fetch: fetchFailureTracker.fetch,
22605
22675
  // `!== undefined` 여야 명시적 0이 상속된 positiveInteger 검증을 통과한다.
22606
22676
  ...options.maxBodyBytes !== void 0 ? { maxBodyBytes: options.maxBodyBytes } : {},
22607
22677
  ...options.idleTimeoutMs !== void 0 ? { idleTimeoutMs: options.idleTimeoutMs } : {}
22608
22678
  });
22679
+ this.isMarkedFetchFailure = fetchFailureTracker.isMarkedFailure;
22609
22680
  }
22610
22681
  async stream(request, options) {
22611
22682
  const callController = new AbortController();
@@ -22616,7 +22687,7 @@ var CodexResponsesAdapter = class extends OpenAIResponsesAdapter {
22616
22687
  try {
22617
22688
  response = await super.stream(request, callOptions);
22618
22689
  } catch (error51) {
22619
- if (!isRetryableCodexFetchSocketTermination(error51, callOptions.signal)) {
22690
+ if (!isRetryableCodexFetchSocketTermination(error51, callOptions.signal, this.isMarkedFetchFailure)) {
22620
22691
  unlinkCallAbort();
22621
22692
  throw error51;
22622
22693
  }
@@ -22771,24 +22842,24 @@ function commitsCodexOutput(event) {
22771
22842
  return true;
22772
22843
  }
22773
22844
  }
22774
- var codexFetchFailures = /* @__PURE__ */ new WeakSet();
22775
- function markCodexFetchFailures(fetchImpl) {
22776
- return async (input, init) => {
22777
- try {
22778
- return await fetchImpl(input, init);
22779
- } catch (error51) {
22780
- if (error51 !== null && typeof error51 === "object") {
22781
- codexFetchFailures.add(error51);
22845
+ function createCodexFetchFailureTracker(fetchImpl) {
22846
+ const fetchFailures = /* @__PURE__ */ new WeakSet();
22847
+ return {
22848
+ fetch: async (input, init) => {
22849
+ try {
22850
+ return await fetchImpl(input, init);
22851
+ } catch (error51) {
22852
+ if (error51 !== null && typeof error51 === "object") {
22853
+ fetchFailures.add(error51);
22854
+ }
22855
+ throw error51;
22782
22856
  }
22783
- throw error51;
22784
- }
22857
+ },
22858
+ isMarkedFailure: (error51) => error51 !== null && typeof error51 === "object" && fetchFailures.has(error51)
22785
22859
  };
22786
22860
  }
22787
- function isRetryableCodexFetchSocketTermination(error51, signal) {
22788
- return signal?.aborted !== true && isMarkedCodexFetchFailure(error51) && isUndiciSocketTermination(error51);
22789
- }
22790
- function isMarkedCodexFetchFailure(error51) {
22791
- return error51 !== null && typeof error51 === "object" && codexFetchFailures.has(error51);
22861
+ function isRetryableCodexFetchSocketTermination(error51, signal, isMarkedFailure) {
22862
+ return signal?.aborted !== true && isMarkedFailure(error51) && isUndiciSocketTermination(error51);
22792
22863
  }
22793
22864
  function isUndiciSocketTermination(error51) {
22794
22865
  const seen = /* @__PURE__ */ new Set();
@@ -22904,50 +22975,12 @@ function isClaudeCodeSuggestionMode(request) {
22904
22975
  const last = request.input.at(-1);
22905
22976
  return last?.type === "message" && last.role === "user" && typeof last.content === "string" && last.content.startsWith(CLAUDE_CODE_SUGGESTION_MODE_PREFIX);
22906
22977
  }
22907
- async function* parseOpenAIEventStream(body, options) {
22908
- if (body === null) {
22909
- options.onClose();
22910
- throw new UpstreamProtocolError("OpenAI streaming response had no body");
22911
- }
22912
- const reader = body.getReader();
22913
- const decoder = new TextDecoder();
22914
- let buffer = "";
22915
- let byteLength = 0;
22916
- try {
22917
- while (true) {
22918
- const result = await readWithIdleTimeout(reader, options);
22919
- if (result.done) {
22920
- buffer += decoder.decode();
22921
- break;
22922
- }
22923
- byteLength += result.value.byteLength;
22924
- if (byteLength > options.maxBodyBytes) {
22925
- const error51 = new UpstreamBodyLimitError(options.maxBodyBytes);
22926
- options.controller.abort(error51);
22927
- throw error51;
22928
- }
22929
- buffer += decoder.decode(result.value, { stream: true });
22930
- let boundary = nextEventBoundary(buffer);
22931
- while (boundary !== void 0) {
22932
- const frame = buffer.slice(0, boundary.index);
22933
- buffer = buffer.slice(boundary.index + boundary.length);
22934
- const event = parseEventFrame(frame);
22935
- if (event !== void 0) {
22936
- yield event;
22937
- }
22938
- boundary = nextEventBoundary(buffer);
22939
- }
22940
- }
22941
- if (buffer.trim().length > 0) {
22942
- const event = parseEventFrame(buffer);
22943
- if (event !== void 0) {
22944
- yield event;
22945
- }
22946
- }
22947
- } finally {
22948
- await reader.cancel().catch(() => void 0);
22949
- options.onClose();
22950
- }
22978
+ function parseOpenAIEventStream(body, options) {
22979
+ return parseUpstreamSseStream(
22980
+ body,
22981
+ { ...options, missingBodyMessage: "OpenAI streaming response had no body" },
22982
+ parseEventFrame
22983
+ );
22951
22984
  }
22952
22985
  function parseEventFrame(frame) {
22953
22986
  const { event: eventName, data } = parseSseFrameFields(frame);
@@ -24396,50 +24429,12 @@ function forOpenCodeGoResponsesBackend(request) {
24396
24429
  }
24397
24430
  return payload;
24398
24431
  }
24399
- async function* parseOpenCodeGoEventStream(body, options) {
24400
- if (body === null) {
24401
- options.onClose();
24402
- throw new UpstreamProtocolError("OpenCode Go streaming response had no body");
24403
- }
24404
- const reader = body.getReader();
24405
- const decoder = new TextDecoder();
24406
- let buffer = "";
24407
- let byteLength = 0;
24408
- try {
24409
- while (true) {
24410
- const result = await readWithIdleTimeout(reader, options);
24411
- if (result.done) {
24412
- buffer += decoder.decode();
24413
- break;
24414
- }
24415
- byteLength += result.value.byteLength;
24416
- if (byteLength > options.maxBodyBytes) {
24417
- const error51 = new UpstreamBodyLimitError(options.maxBodyBytes);
24418
- options.controller.abort(error51);
24419
- throw error51;
24420
- }
24421
- buffer += decoder.decode(result.value, { stream: true });
24422
- let boundary = nextEventBoundary(buffer);
24423
- while (boundary !== void 0) {
24424
- const frame = buffer.slice(0, boundary.index);
24425
- buffer = buffer.slice(boundary.index + boundary.length);
24426
- const event = parseEventFrame2(frame);
24427
- if (event !== void 0) {
24428
- yield event;
24429
- }
24430
- boundary = nextEventBoundary(buffer);
24431
- }
24432
- }
24433
- if (buffer.trim().length > 0) {
24434
- const event = parseEventFrame2(buffer);
24435
- if (event !== void 0) {
24436
- yield event;
24437
- }
24438
- }
24439
- } finally {
24440
- await reader.cancel().catch(() => void 0);
24441
- options.onClose();
24442
- }
24432
+ function parseOpenCodeGoEventStream(body, options) {
24433
+ return parseUpstreamSseStream(
24434
+ body,
24435
+ { ...options, missingBodyMessage: "OpenCode Go streaming response had no body" },
24436
+ parseEventFrame2
24437
+ );
24443
24438
  }
24444
24439
  function parseEventFrame2(frame) {
24445
24440
  const { event: eventName, data } = parseSseFrameFields(frame);
@@ -25078,6 +25073,133 @@ function stringValue(value) {
25078
25073
  function isRecord7(value) {
25079
25074
  return typeof value === "object" && value !== null && !Array.isArray(value);
25080
25075
  }
25076
+ var EXECUTE_HOOK_FIELD_NUMBER = 27;
25077
+ var EXEC_CLIENT_MESSAGE_FIELD_NUMBER = 2;
25078
+ var EXEC_CLIENT_CONTROL_MESSAGE_FIELD_NUMBER = 5;
25079
+ var SUPPORTED_HOOK_CASES = /* @__PURE__ */ new Set([1, 2, 3, 4, 5, 6, 7, 8, 9, 11]);
25080
+ function cursorUnknownExecReply(exec2, unknownFields) {
25081
+ const executeHook = unknownFields.find(
25082
+ (field) => field.no === EXECUTE_HOOK_FIELD_NUMBER && field.wireType === WireType.LengthDelimited
25083
+ );
25084
+ if (executeHook) {
25085
+ const hookCase = executeHookRequestCase(executeHook);
25086
+ if (hookCase !== void 0 && SUPPORTED_HOOK_CASES.has(hookCase)) {
25087
+ return {
25088
+ payloads: [executeHookReply(exec2, hookCase)],
25089
+ replyKind: "exec.policy.executeHookArgs"
25090
+ };
25091
+ }
25092
+ }
25093
+ const caseName = cursorUnknownExecCaseName(unknownFields);
25094
+ return {
25095
+ payloads: unsupportedExecReplies(
25096
+ exec2,
25097
+ `Fleet AI Gateway cannot handle Cursor native exec ${caseName}; retry with an advertised client tool.`
25098
+ ),
25099
+ replyKind: `exec.control.${caseName}`
25100
+ };
25101
+ }
25102
+ function cursorUnknownExecCaseName(unknownFields) {
25103
+ const fieldNumbers = [...new Set(
25104
+ unknownFields.filter((field) => field.wireType === WireType.LengthDelimited).map((field) => field.no)
25105
+ )].sort((left, right) => left - right);
25106
+ if (fieldNumbers.includes(EXECUTE_HOOK_FIELD_NUMBER)) return "executeHookArgs";
25107
+ return fieldNumbers.length > 0 ? `unknownField${fieldNumbers.join("-")}` : "unknown";
25108
+ }
25109
+ function executeHookRequestCase(field) {
25110
+ const args = lengthDelimitedPayload(field);
25111
+ if (!args) return void 0;
25112
+ const request = embeddedMessage(args, 1);
25113
+ if (!request) return void 0;
25114
+ try {
25115
+ const reader = new BinaryReader(request);
25116
+ while (reader.pos < reader.len) {
25117
+ const [fieldNumber, wireType] = reader.tag();
25118
+ if (wireType === WireType.LengthDelimited) return fieldNumber;
25119
+ reader.skip(wireType, fieldNumber);
25120
+ }
25121
+ } catch {
25122
+ return void 0;
25123
+ }
25124
+ return void 0;
25125
+ }
25126
+ function lengthDelimitedPayload(field) {
25127
+ try {
25128
+ const reader = new BinaryReader(field.data);
25129
+ const payload = reader.bytes();
25130
+ return reader.pos === reader.len ? payload : void 0;
25131
+ } catch {
25132
+ return void 0;
25133
+ }
25134
+ }
25135
+ function embeddedMessage(message, wantedFieldNumber) {
25136
+ try {
25137
+ const reader = new BinaryReader(message);
25138
+ while (reader.pos < reader.len) {
25139
+ const [fieldNumber, wireType] = reader.tag();
25140
+ if (fieldNumber === wantedFieldNumber && wireType === WireType.LengthDelimited) {
25141
+ return reader.bytes();
25142
+ }
25143
+ reader.skip(wireType, fieldNumber);
25144
+ }
25145
+ } catch {
25146
+ return void 0;
25147
+ }
25148
+ return void 0;
25149
+ }
25150
+ function executeHookReply(exec2, hookCase) {
25151
+ const response = encodeMessage((writer) => {
25152
+ writer.tag(hookCase, WireType.LengthDelimited).bytes(new Uint8Array());
25153
+ });
25154
+ const result = encodeMessage((writer) => {
25155
+ writer.tag(1, WireType.LengthDelimited).bytes(response);
25156
+ });
25157
+ const execClientMessage = encodeMessage((writer) => {
25158
+ writer.tag(1, WireType.Varint).uint32(unknownExecUint32Value(exec2.id));
25159
+ const execId = unknownExecStringValue(exec2.execId);
25160
+ if (execId) writer.tag(15, WireType.LengthDelimited).string(execId);
25161
+ writer.tag(EXECUTE_HOOK_FIELD_NUMBER, WireType.LengthDelimited).bytes(result);
25162
+ });
25163
+ return encodeMessage((writer) => {
25164
+ writer.tag(EXEC_CLIENT_MESSAGE_FIELD_NUMBER, WireType.LengthDelimited).bytes(execClientMessage);
25165
+ });
25166
+ }
25167
+ function unsupportedExecReplies(exec2, error51) {
25168
+ const id = unknownExecUint32Value(exec2.id);
25169
+ const execThrow = encodeMessage((writer) => {
25170
+ writer.tag(1, WireType.Varint).uint32(id);
25171
+ writer.tag(2, WireType.LengthDelimited).string(error51);
25172
+ });
25173
+ const streamClose = encodeMessage((writer) => {
25174
+ writer.tag(1, WireType.Varint).uint32(id);
25175
+ });
25176
+ return [
25177
+ encodeControlMessage(2, execThrow),
25178
+ encodeControlMessage(1, streamClose)
25179
+ ];
25180
+ }
25181
+ function encodeControlMessage(caseNumber, value) {
25182
+ const control = encodeMessage((writer) => {
25183
+ writer.tag(caseNumber, WireType.LengthDelimited).bytes(value);
25184
+ });
25185
+ return encodeMessage((writer) => {
25186
+ writer.tag(EXEC_CLIENT_CONTROL_MESSAGE_FIELD_NUMBER, WireType.LengthDelimited).bytes(control);
25187
+ });
25188
+ }
25189
+ function encodeMessage(write) {
25190
+ const writer = new BinaryWriter();
25191
+ write(writer);
25192
+ return writer.finish();
25193
+ }
25194
+ function unknownExecUint32Value(value) {
25195
+ if (typeof value === "number" && Number.isSafeInteger(value) && value >= 0 && value <= 4294967295) {
25196
+ return value;
25197
+ }
25198
+ return 0;
25199
+ }
25200
+ function unknownExecStringValue(value) {
25201
+ return typeof value === "string" ? value : "";
25202
+ }
25081
25203
  var READ_CANDIDATES = ["Read"];
25082
25204
  var GREP_CANDIDATES = ["Grep"];
25083
25205
  var SHELL_CANDIDATES = ["Bash", "shell_command", "exec_command"];
@@ -25720,133 +25842,6 @@ function stringValue2(value) {
25720
25842
  function isRecord8(value) {
25721
25843
  return typeof value === "object" && value !== null && !Array.isArray(value);
25722
25844
  }
25723
- var EXECUTE_HOOK_FIELD_NUMBER = 27;
25724
- var EXEC_CLIENT_MESSAGE_FIELD_NUMBER = 2;
25725
- var EXEC_CLIENT_CONTROL_MESSAGE_FIELD_NUMBER = 5;
25726
- var SUPPORTED_HOOK_CASES = /* @__PURE__ */ new Set([1, 2, 3, 4, 5, 6, 7, 8, 9, 11]);
25727
- function cursorUnknownExecReply(exec2, unknownFields) {
25728
- const executeHook = unknownFields.find(
25729
- (field) => field.no === EXECUTE_HOOK_FIELD_NUMBER && field.wireType === WireType.LengthDelimited
25730
- );
25731
- if (executeHook) {
25732
- const hookCase = executeHookRequestCase(executeHook);
25733
- if (hookCase !== void 0 && SUPPORTED_HOOK_CASES.has(hookCase)) {
25734
- return {
25735
- payloads: [executeHookReply(exec2, hookCase)],
25736
- replyKind: "exec.policy.executeHookArgs"
25737
- };
25738
- }
25739
- }
25740
- const caseName = cursorUnknownExecCaseName(unknownFields);
25741
- return {
25742
- payloads: unsupportedExecReplies(
25743
- exec2,
25744
- `Fleet AI Gateway cannot handle Cursor native exec ${caseName}; retry with an advertised client tool.`
25745
- ),
25746
- replyKind: `exec.control.${caseName}`
25747
- };
25748
- }
25749
- function cursorUnknownExecCaseName(unknownFields) {
25750
- const fieldNumbers = [...new Set(
25751
- unknownFields.filter((field) => field.wireType === WireType.LengthDelimited).map((field) => field.no)
25752
- )].sort((left, right) => left - right);
25753
- if (fieldNumbers.includes(EXECUTE_HOOK_FIELD_NUMBER)) return "executeHookArgs";
25754
- return fieldNumbers.length > 0 ? `unknownField${fieldNumbers.join("-")}` : "unknown";
25755
- }
25756
- function executeHookRequestCase(field) {
25757
- const args = lengthDelimitedPayload(field);
25758
- if (!args) return void 0;
25759
- const request = embeddedMessage(args, 1);
25760
- if (!request) return void 0;
25761
- try {
25762
- const reader = new BinaryReader(request);
25763
- while (reader.pos < reader.len) {
25764
- const [fieldNumber, wireType] = reader.tag();
25765
- if (wireType === WireType.LengthDelimited) return fieldNumber;
25766
- reader.skip(wireType, fieldNumber);
25767
- }
25768
- } catch {
25769
- return void 0;
25770
- }
25771
- return void 0;
25772
- }
25773
- function lengthDelimitedPayload(field) {
25774
- try {
25775
- const reader = new BinaryReader(field.data);
25776
- const payload = reader.bytes();
25777
- return reader.pos === reader.len ? payload : void 0;
25778
- } catch {
25779
- return void 0;
25780
- }
25781
- }
25782
- function embeddedMessage(message, wantedFieldNumber) {
25783
- try {
25784
- const reader = new BinaryReader(message);
25785
- while (reader.pos < reader.len) {
25786
- const [fieldNumber, wireType] = reader.tag();
25787
- if (fieldNumber === wantedFieldNumber && wireType === WireType.LengthDelimited) {
25788
- return reader.bytes();
25789
- }
25790
- reader.skip(wireType, fieldNumber);
25791
- }
25792
- } catch {
25793
- return void 0;
25794
- }
25795
- return void 0;
25796
- }
25797
- function executeHookReply(exec2, hookCase) {
25798
- const response = encodeMessage((writer) => {
25799
- writer.tag(hookCase, WireType.LengthDelimited).bytes(new Uint8Array());
25800
- });
25801
- const result = encodeMessage((writer) => {
25802
- writer.tag(1, WireType.LengthDelimited).bytes(response);
25803
- });
25804
- const execClientMessage = encodeMessage((writer) => {
25805
- writer.tag(1, WireType.Varint).uint32(uint32Value(exec2.id));
25806
- const execId = stringValue3(exec2.execId);
25807
- if (execId) writer.tag(15, WireType.LengthDelimited).string(execId);
25808
- writer.tag(EXECUTE_HOOK_FIELD_NUMBER, WireType.LengthDelimited).bytes(result);
25809
- });
25810
- return encodeMessage((writer) => {
25811
- writer.tag(EXEC_CLIENT_MESSAGE_FIELD_NUMBER, WireType.LengthDelimited).bytes(execClientMessage);
25812
- });
25813
- }
25814
- function unsupportedExecReplies(exec2, error51) {
25815
- const id = uint32Value(exec2.id);
25816
- const execThrow = encodeMessage((writer) => {
25817
- writer.tag(1, WireType.Varint).uint32(id);
25818
- writer.tag(2, WireType.LengthDelimited).string(error51);
25819
- });
25820
- const streamClose = encodeMessage((writer) => {
25821
- writer.tag(1, WireType.Varint).uint32(id);
25822
- });
25823
- return [
25824
- encodeControlMessage(2, execThrow),
25825
- encodeControlMessage(1, streamClose)
25826
- ];
25827
- }
25828
- function encodeControlMessage(caseNumber, value) {
25829
- const control = encodeMessage((writer) => {
25830
- writer.tag(caseNumber, WireType.LengthDelimited).bytes(value);
25831
- });
25832
- return encodeMessage((writer) => {
25833
- writer.tag(EXEC_CLIENT_CONTROL_MESSAGE_FIELD_NUMBER, WireType.LengthDelimited).bytes(control);
25834
- });
25835
- }
25836
- function encodeMessage(write) {
25837
- const writer = new BinaryWriter();
25838
- write(writer);
25839
- return writer.finish();
25840
- }
25841
- function uint32Value(value) {
25842
- if (typeof value === "number" && Number.isSafeInteger(value) && value >= 0 && value <= 4294967295) {
25843
- return value;
25844
- }
25845
- return 0;
25846
- }
25847
- function stringValue3(value) {
25848
- return typeof value === "string" ? value : "";
25849
- }
25850
25845
  var cursorAgentDescriptor = [
25851
25846
  "CgthZ2VudC5wcm90bxIIYWdlbnQudjEicgoOR2xvYlRvb2xSZXN1bHQSLAoHc3VjY2VzcxgBIAEoCzIZLmFnZW50LnYxLkdsb2JUb29sU3VjY2Vzc0gAEigK",
25852
25847
  "BWVycm9yGAIgASgLMhcuYWdlbnQudjEuR2xvYlRvb2xFcnJvckgAQggKBnJlc3VsdCIeCg1HbG9iVG9vbEVycm9yEg0KBWVycm9yGAEgASgJIokBCg9HbG9i",
@@ -28767,9 +28762,9 @@ function cursorInteractionQueryReply(query) {
28767
28762
  });
28768
28763
  if (isRecord9(query.createPlanRequestQuery)) {
28769
28764
  const args = isRecord9(query.createPlanRequestQuery.args) ? query.createPlanRequestQuery.args : void 0;
28770
- const name = stringValue4(args?.name)?.trim();
28771
- const overview = stringValue4(args?.overview)?.trim();
28772
- const plan = stringValue4(args?.plan)?.trim();
28765
+ const name = stringValue3(args?.name)?.trim();
28766
+ const overview = stringValue3(args?.overview)?.trim();
28767
+ const plan = stringValue3(args?.plan)?.trim();
28773
28768
  const parts = [
28774
28769
  name ? `Plan: ${name}` : void 0,
28775
28770
  overview || void 0,
@@ -28924,16 +28919,16 @@ function mcpCallFromToolUpdate(value) {
28924
28919
  const toolCall = isRecord9(value.toolCall) ? value.toolCall : void 0;
28925
28920
  const args = toolCall ? mcpArgsFromToolCall(toolCall) : void 0;
28926
28921
  if (!args) return null;
28927
- const publicCallId = stringValue4(value.callId);
28928
- const toolCallId = stringValue4(args.toolCallId);
28922
+ const publicCallId = stringValue3(value.callId);
28923
+ const toolCallId = stringValue3(args.toolCallId);
28929
28924
  const callId = publicCallId ?? toolCallId;
28930
28925
  if (!callId) return null;
28931
28926
  return {
28932
28927
  callId,
28933
28928
  ...publicCallId ? { publicCallId } : {},
28934
28929
  ...toolCallId ? { toolCallId } : {},
28935
- name: stringValue4(args?.toolName) ?? stringValue4(args?.name) ?? "tool",
28936
- ...stringValue4(args?.providerIdentifier) ? { providerIdentifier: stringValue4(args?.providerIdentifier) } : {},
28930
+ name: stringValue3(args?.toolName) ?? stringValue3(args?.name) ?? "tool",
28931
+ ...stringValue3(args?.providerIdentifier) ? { providerIdentifier: stringValue3(args?.providerIdentifier) } : {},
28937
28932
  ...args ? cursorMcpArguments(args) : {}
28938
28933
  };
28939
28934
  }
@@ -28985,18 +28980,18 @@ function isCursorParkedResidueFrame(frame, parked) {
28985
28980
  function mcpCallFromExecMessage(value) {
28986
28981
  const args = isRecord9(value.mcpArgs) ? value.mcpArgs : void 0;
28987
28982
  if (!args) return null;
28988
- const toolCallId = stringValue4(args.toolCallId);
28983
+ const toolCallId = stringValue3(args.toolCallId);
28989
28984
  if (!toolCallId) return null;
28990
28985
  const rawMessageId = value.id ?? 0;
28991
28986
  const messageId = typeof rawMessageId === "number" && Number.isSafeInteger(rawMessageId) ? rawMessageId : void 0;
28992
- const execId = stringValue4(value.execId);
28987
+ const execId = stringValue3(value.execId);
28993
28988
  return {
28994
28989
  callId: toolCallId,
28995
28990
  toolCallId,
28996
28991
  ...messageId === void 0 ? {} : { messageId },
28997
28992
  ...execId ? { execId } : {},
28998
- name: stringValue4(args.toolName) ?? stringValue4(args.name) ?? "tool",
28999
- ...stringValue4(args.providerIdentifier) ? { providerIdentifier: stringValue4(args.providerIdentifier) } : {},
28993
+ name: stringValue3(args.toolName) ?? stringValue3(args.name) ?? "tool",
28994
+ ...stringValue3(args.providerIdentifier) ? { providerIdentifier: stringValue3(args.providerIdentifier) } : {},
29000
28995
  ...cursorMcpArguments(args)
29001
28996
  };
29002
28997
  }
@@ -29074,7 +29069,7 @@ function completeJson(value) {
29074
29069
  return void 0;
29075
29070
  }
29076
29071
  }
29077
- function stringValue4(value) {
29072
+ function stringValue3(value) {
29078
29073
  return typeof value === "string" && value.length > 0 ? value : void 0;
29079
29074
  }
29080
29075
  function cursorError(value) {
@@ -29501,24 +29496,9 @@ data: ${data}
29501
29496
  } catch {
29502
29497
  }
29503
29498
  }
29504
- function findCauseCode2(error51) {
29505
- let current = error51;
29506
- const seen = /* @__PURE__ */ new Set();
29507
- for (let depth = 0; depth <= 4; depth += 1) {
29508
- if (current === null || typeof current !== "object") return void 0;
29509
- if (seen.has(current)) return void 0;
29510
- seen.add(current);
29511
- if (Object.prototype.hasOwnProperty.call(current, "code")) {
29512
- const code = current.code;
29513
- if (typeof code === "string") return code;
29514
- }
29515
- current = current.cause;
29516
- }
29517
- return void 0;
29518
- }
29519
29499
  function errorMessage(error51) {
29520
29500
  const message = error51 instanceof Error ? error51.message : String(error51);
29521
- const code = findCauseCode2(error51);
29501
+ const code = findCauseCode(error51);
29522
29502
  return code !== void 0 && !message.includes(code) ? `${message} (${code})` : message;
29523
29503
  }
29524
29504
  function isOpencodeAnthropicPassthrough(model) {
@@ -33555,7 +33535,7 @@ async function writeWikiEntryAtTarget(entry, target2, paths) {
33555
33535
  throw new Error("wiki patch body id must match target filename");
33556
33536
  }
33557
33537
  await mkdir(path18__default.dirname(absoluteTarget), { recursive: true });
33558
- await writeMarkdownAtomic(absoluteTarget, serializeWikiEntry(entry), paths);
33538
+ await writeAtomic(absoluteTarget, serializeWikiEntry(entry), paths);
33559
33539
  return path18__default.join("wiki", relativeTarget).replaceAll(path18__default.sep, "/");
33560
33540
  }
33561
33541
  async function writeRawSourceEntry(entry, paths) {
@@ -33575,7 +33555,7 @@ async function writeRawSourceEntry(entry, paths) {
33575
33555
  },
33576
33556
  entry.content
33577
33557
  );
33578
- await writeMarkdownAtomic(path18__default.join(paths.root, relativePath), content, paths);
33558
+ await writeAtomic(path18__default.join(paths.root, relativePath), content, paths);
33579
33559
  return relativePath;
33580
33560
  }
33581
33561
  async function readRawSourceEntry(rawSourceRef, paths) {
@@ -33623,7 +33603,7 @@ async function rebuildIndex(paths) {
33623
33603
  entryPathMap[item.entry.id] = item.path;
33624
33604
  }
33625
33605
  await writeJsonAtomic(paths.indexFile, nextIndex, paths);
33626
- await writeMarkdownAtomic(getIndexMarkdownFile(paths), renderIndexMarkdown(entries.map((item) => item.entry), entryPathMap), paths);
33606
+ await writeAtomic(getIndexMarkdownFile(paths), renderIndexMarkdown(entries.map((item) => item.entry), entryPathMap), paths);
33627
33607
  await appendLog(paths, "index rebuilt", { entry_count: entries.length });
33628
33608
  return nextIndex;
33629
33609
  }
@@ -33703,7 +33683,7 @@ async function readPatchFile(filePath) {
33703
33683
  return readFile(filePath, "utf8");
33704
33684
  }
33705
33685
  async function writePatchFile(filePath, content, paths) {
33706
- await writeMarkdownAtomic(filePath, content, paths);
33686
+ await writeAtomic(filePath, content, paths);
33707
33687
  }
33708
33688
  async function readJsonFile2(filePath) {
33709
33689
  const raw = await readFile(filePath, "utf8");
@@ -33970,9 +33950,6 @@ function isFrontmatterBlock(rawFrontmatter) {
33970
33950
  }
33971
33951
  return keys.has("id") && keys.has("title");
33972
33952
  }
33973
- async function writeMarkdownAtomic(filePath, content, paths) {
33974
- await writeAtomic(filePath, content, paths);
33975
- }
33976
33953
  async function writeJsonAtomic(filePath, value, paths) {
33977
33954
  await writeAtomic(filePath, JSON.stringify(value, null, 2), paths);
33978
33955
  }
@@ -45273,7 +45250,10 @@ function registerTerminalSettingsRoutes(ctx, deps) {
45273
45250
  }
45274
45251
  ctx.host.http.writeJson(res, 405, { error: "Method not allowed" });
45275
45252
  return true;
45276
- });
45253
+ }, [
45254
+ { method: "GET", path: "", summary: "Read Terminal plugin settings.", category: "Terminal Plugin", gate: "loopback", transport: "http" },
45255
+ { method: "PUT", path: "", summary: "Save Terminal plugin settings.", category: "Terminal Plugin", gate: "origin-write", transport: "http" }
45256
+ ]);
45277
45257
  }
45278
45258
  function toTerminalSettingsState(data, aiGateway, wireLogEnabled2) {
45279
45259
  const configured = (aiGateway.models?.length ?? 0) > 0 || (aiGateway.providerPriority?.length ?? 0) > 0;
@@ -45370,7 +45350,23 @@ async function registerAgentRoutes(ctx, terminalRuntime, deps) {
45370
45350
  await api.handleExit(operationId);
45371
45351
  });
45372
45352
  ctx.host.lifecycle.registerCleanup(api.cleanup);
45373
- registerRouter(ctx, "agent", api.handle);
45353
+ registerRouter(ctx, "agent", api.handle, [
45354
+ { method: "GET", path: "/state", summary: "Read Agent session state.", category: "Terminal Plugin", gate: "loopback", transport: "http" },
45355
+ { method: "GET", path: "/agent-cli/state", summary: "Read installed Agent CLI status.", category: "Terminal Plugin", gate: "loopback", transport: "http" },
45356
+ { method: "GET", path: "/agent-cli/diagnostics", summary: "Read Agent CLI diagnostics.", category: "Terminal Plugin", gate: "origin-write", transport: "http" },
45357
+ { method: "PUT", path: "/agent-cli/path", summary: "Save an Agent CLI executable path.", category: "Terminal Plugin", gate: "origin-write", transport: "http" },
45358
+ { method: "GET", path: "/events", summary: "Stream Agent session events.", category: "Terminal Plugin", gate: "loopback", transport: "sse" },
45359
+ { method: "GET", path: "/sessions", summary: "List Agent sessions.", category: "Terminal Plugin", gate: "origin-write", transport: "http" },
45360
+ { method: "POST", path: "/sessions", summary: "Create an Agent session.", category: "Terminal Plugin", gate: "origin-write", transport: "http" },
45361
+ { method: "DELETE", path: "/sessions/:sessionId", summary: "Delete an Agent session.", category: "Terminal Plugin", gate: "origin-write", transport: "http" },
45362
+ { method: "POST", path: "/sessions/:sessionId/resume", summary: "Resume an Agent session.", category: "Terminal Plugin", gate: "origin-write", transport: "http" },
45363
+ { method: "POST", path: "/sessions/:sessionId/turn", summary: "Receive an Agent turn hook.", category: "Terminal Plugin", gate: "lock-token", transport: "http" },
45364
+ { method: "POST", path: "/sessions/:sessionId/background", summary: "Receive an Agent background-task hook.", category: "Terminal Plugin", gate: "lock-token", transport: "http" },
45365
+ { method: "POST", path: "/sessions/:sessionId/attention", summary: "Receive an Agent attention hook.", category: "Terminal Plugin", gate: "lock-token", transport: "http" },
45366
+ { method: "POST", path: "/sessions/:sessionId/auto-name", summary: "Receive an Agent auto-name hook.", category: "Terminal Plugin", gate: "lock-token", transport: "http" },
45367
+ { method: "POST", path: "/sessions/:sessionId/capture", summary: "Receive an Agent session capture hook.", category: "Terminal Plugin", gate: "lock-token", transport: "http" },
45368
+ { method: "POST", path: "/ticket", summary: "Issue an Agent Terminal WebSocket ticket.", category: "Terminal Plugin", gate: "origin-write", transport: "http" }
45369
+ ]);
45374
45370
  return api.launchKinds;
45375
45371
  }
45376
45372
  function buildAgentLaunchKindBackfillPatch(operation) {
@@ -45686,7 +45682,11 @@ async function createAgentApi(ctx, terminalRuntime, deps) {
45686
45682
  // toOperationPayload가 지우는 키 목록 밖이라 resume·복원을 지나도 그대로 남는다.
45687
45683
  payload: {
45688
45684
  ...toOperationPayload(void 0, cwd, session),
45689
- [AGENT_LAUNCH_PROVIDER_PAYLOAD_KEY]: agentLaunchProviderFromModel(launchOptions.model)
45685
+ [AGENT_LAUNCH_PROVIDER_PAYLOAD_KEY]: agentLaunchProviderFromModel(launchOptions.model),
45686
+ // Claude Code의 resume가 launch 좌표를 자체 복원한다고 가정하지 않는다 — 정규화된
45687
+ // 최초 선택을 Operation에 남겨 dormant·Console 재시작 뒤에도 같은 인자로 재개한다.
45688
+ ...launchOptions.model ? { launchModel: launchOptions.model } : {},
45689
+ ...launchOptions.effort ? { launchEffort: launchOptions.effort } : {}
45690
45690
  },
45691
45691
  createdAt: session.createdAt
45692
45692
  });
@@ -45714,7 +45714,7 @@ async function createAgentApi(ctx, terminalRuntime, deps) {
45714
45714
  } catch (error51) {
45715
45715
  if (error51 instanceof GatewayLaunchOptionError) {
45716
45716
  removeSession(sessionId);
45717
- ctx.host.http.writeJson(res, error51.code === "gateway_model_not_enabled" ? 409 : 400, { error: error51.code });
45717
+ ctx.host.http.writeJson(res, gatewayLaunchOptionErrorStatus(error51), { error: error51.code });
45718
45718
  return;
45719
45719
  }
45720
45720
  if (error51 instanceof LaunchPromptError) {
@@ -45747,6 +45747,8 @@ async function createAgentApi(ctx, terminalRuntime, deps) {
45747
45747
  ctx.host.http.writeJson(res, node ? 409 : 404, { error: node ? "resume_unavailable" : "session_not_found" });
45748
45748
  return true;
45749
45749
  }
45750
+ const launchModel = readPayloadString(node.payload, "launchModel") || (cliId === "claude-gateway" ? "opus[1m]" : void 0);
45751
+ const launchEffort = readPayloadString(node.payload, "launchEffort") || void 0;
45750
45752
  resetOscActivity(sessionId);
45751
45753
  const starting = observability.updateTerminalSessionStatus(sessionId, "starting") ?? injectOperation(node);
45752
45754
  try {
@@ -45769,6 +45771,8 @@ async function createAgentApi(ctx, terminalRuntime, deps) {
45769
45771
  pluginId: node.pluginId,
45770
45772
  theaterId: node.theaterId,
45771
45773
  cliId,
45774
+ ...launchModel ? { model: launchModel } : {},
45775
+ ...launchEffort ? { effort: launchEffort } : {},
45772
45776
  ...fresh ? {} : { resumeSessionId: providerSession?.sessionId }
45773
45777
  });
45774
45778
  const runtimeSession = pendingRuntimeSessions.get(sessionId);
@@ -45777,9 +45781,11 @@ async function createAgentApi(ctx, terminalRuntime, deps) {
45777
45781
  observability.notifySessionUpdated(resumed);
45778
45782
  const currentPayload = fresh ? ctx.host.operations.get(sessionId)?.payload : node.payload;
45779
45783
  const effectiveProviderSession = fresh ? readProviderSession(currentPayload) : providerSession;
45780
- ctx.host.operations.patch(sessionId, { payload: toOperationPayload(currentPayload ?? node.payload, cwd, resumed, effectiveProviderSession, observability.getDurableOperation(sessionId)?.providerTitle) });
45784
+ const resumedPayload = toOperationPayload(currentPayload ?? node.payload, cwd, resumed, effectiveProviderSession, observability.getDurableOperation(sessionId)?.providerTitle);
45785
+ if (!readPayloadString(resumedPayload, "launchModel") && launchModel) resumedPayload.launchModel = launchModel;
45786
+ ctx.host.operations.patch(sessionId, { payload: resumedPayload });
45781
45787
  ctx.host.http.writeJson(res, 200, resumed);
45782
- } catch {
45788
+ } catch (error51) {
45783
45789
  resetOscActivity(sessionId);
45784
45790
  if (fresh && providerSession) {
45785
45791
  const rollbackPayload = { ...ctx.host.operations.get(sessionId)?.payload ?? {} };
@@ -45790,7 +45796,11 @@ async function createAgentApi(ctx, terminalRuntime, deps) {
45790
45796
  pendingRuntimeSessions.delete(sessionId);
45791
45797
  const reverted = observability.updateTerminalSessionStatus(sessionId, "dormant");
45792
45798
  if (reverted) observability.notifySessionUpdated(reverted);
45793
- ctx.host.http.writeJson(res, 503, { error: "terminal_unavailable" });
45799
+ if (error51 instanceof GatewayLaunchOptionError) {
45800
+ ctx.host.http.writeJson(res, gatewayLaunchOptionErrorStatus(error51), { error: error51.code });
45801
+ } else {
45802
+ ctx.host.http.writeJson(res, 503, { error: "terminal_unavailable" });
45803
+ }
45794
45804
  }
45795
45805
  return true;
45796
45806
  }
@@ -46142,6 +46152,9 @@ function readProviderTitle(value) {
46142
46152
  if (candidate.source !== "provider" || Object.keys(candidate).length !== 1) return void 0;
46143
46153
  return { source: "provider" };
46144
46154
  }
46155
+ function gatewayLaunchOptionErrorStatus(error51) {
46156
+ return error51.code === "gateway_model_not_enabled" ? 409 : 400;
46157
+ }
46145
46158
  function readPayloadString(payload, key) {
46146
46159
  const value = payload[key];
46147
46160
  return typeof value === "string" ? value : "";
@@ -47097,7 +47110,17 @@ function registerAnalysisRoutes(ctx, deps = {}) {
47097
47110
  if (action === "message") return handleMessage(ctx, req, res, operationId, registry3);
47098
47111
  if (action === "stream") return handleStream(ctx, req, res, operationId, registry3);
47099
47112
  return handleStop(ctx, req, res, operationId, registry3);
47100
- });
47113
+ }, [
47114
+ { method: "GET", path: "/catalog", summary: "Read Analyst model catalog.", category: "Terminal Plugin", gate: "origin-write", transport: "http" },
47115
+ { method: "GET", path: "/stream", summary: "Stream all Analyst events.", category: "Terminal Plugin", gate: "origin-write", transport: "sse" },
47116
+ { method: "GET", path: "/artifacts/:artifactId", summary: "Read an Analyst artifact.", category: "Terminal Plugin", gate: "origin-write", transport: "http" },
47117
+ { method: "DELETE", path: "/:operationId/artifacts", summary: "Clear Analyst artifacts.", category: "Terminal Plugin", gate: "origin-write", transport: "http" },
47118
+ { method: "GET", path: "/:operationId/ready", summary: "Read Analyst readiness.", category: "Terminal Plugin", gate: "origin-write", transport: "http" },
47119
+ { method: "POST", path: "/:operationId/start", summary: "Start an Analyst session.", category: "Terminal Plugin", gate: "origin-write", transport: "http" },
47120
+ { method: "POST", path: "/:operationId/message", summary: "Send an Analyst message.", category: "Terminal Plugin", gate: "origin-write", transport: "http" },
47121
+ { method: "GET", path: "/:operationId/stream", summary: "Stream Analyst session events.", category: "Terminal Plugin", gate: "origin-write", transport: "sse" },
47122
+ { method: "POST", path: "/:operationId/stop", summary: "Stop an Analyst session.", category: "Terminal Plugin", gate: "origin-write", transport: "http" }
47123
+ ]);
47101
47124
  const unsubscribeDelete = ctx.host.events.subscribe(OPERATION_DELETED_EVENT_CHANNEL, (payload) => {
47102
47125
  if (isOperationDeletedEvent(payload) && payload.pluginId === ctx.pluginId) {
47103
47126
  for (const marker of inFlightStartDeletionMarkers) {
@@ -47589,7 +47612,11 @@ function registerAiGatewayRoutes(ctx, deps = {}) {
47589
47612
  router.dispose();
47590
47613
  return ownedDiagnostics?.flush();
47591
47614
  });
47592
- registerRouter(ctx, AI_GATEWAY_ROUTE_SEGMENT, router.handle);
47615
+ registerRouter(ctx, AI_GATEWAY_ROUTE_SEGMENT, router.handle, [
47616
+ { method: "*", path: "/api/hello", summary: "Read the AI Gateway health response.", category: "Terminal Plugin", gate: "loopback", transport: "http" },
47617
+ { method: "*", path: "/v1/models", summary: "Proxy the AI Gateway model listing.", category: "Terminal Plugin", gate: "anthropic-credential", transport: "proxy" },
47618
+ { method: "POST", path: "/v1/messages", summary: "Proxy an Anthropic Messages request through the AI Gateway.", category: "Terminal Plugin", gate: "anthropic-credential", transport: "proxy" }
47619
+ ]);
47593
47620
  }
47594
47621
 
47595
47622
  // ../fleet-plugins/terminal/server/global.ts
@@ -47663,7 +47690,7 @@ function registerGlobalShellRoutes(ctx, runtime) {
47663
47690
  ...role ? { role } : {}
47664
47691
  }));
47665
47692
  return true;
47666
- });
47693
+ }, { method: "POST", path: "", summary: "Issue a Global Shell WebSocket ticket.", category: "Terminal Plugin", gate: "origin-strict", transport: "http" });
47667
47694
  }
47668
47695
 
47669
47696
  // ../fleet-plugins/terminal/server/model-auth-state.ts
@@ -47699,7 +47726,11 @@ function registerTerminalModelAuthRoutes(ctx, deps) {
47699
47726
  registerRouter(ctx, "model-auth", createTerminalModelAuthRouter(ctx, {
47700
47727
  ...deps,
47701
47728
  validateApiKey: (provider, apiKey) => MODEL_AUTH_VALIDATORS[provider](apiKey)
47702
- }));
47729
+ }), [
47730
+ { method: "GET", path: "/state", summary: "Read Terminal model provider authentication state.", category: "Terminal Plugin", gate: "loopback", transport: "http" },
47731
+ { method: "PUT", path: "/providers/:providerId", summary: "Save Terminal model provider credentials.", category: "Terminal Plugin", gate: "origin-write", transport: "http" },
47732
+ { method: "DELETE", path: "/providers/:providerId", summary: "Remove Terminal model provider credentials.", category: "Terminal Plugin", gate: "origin-write", transport: "http" }
47733
+ ]);
47703
47734
  }
47704
47735
  function createTerminalModelAuthRouter(ctx, deps) {
47705
47736
  return async function handleTerminalModelAuthRoute({ req, res, pathname }) {
@@ -47864,7 +47895,7 @@ function registerShellRoutes(ctx, runtime) {
47864
47895
  ...role ? { role } : {}
47865
47896
  }));
47866
47897
  return true;
47867
- });
47898
+ }, { method: "POST", path: "", summary: "Issue a Shell WebSocket ticket.", category: "Terminal Plugin", gate: "origin-write", transport: "http" });
47868
47899
  registerRouter(ctx, "shell/sessions", ({ req, res, pathname }) => {
47869
47900
  const suffix = pathname.slice(`${ctx.basePath}/shell/sessions/`.length);
47870
47901
  const match = suffix.match(/^([^/]+)(?:\/(relaunch))?$/);
@@ -47901,7 +47932,10 @@ function registerShellRoutes(ctx, runtime) {
47901
47932
  ctx.host.operations.delete(operationId);
47902
47933
  ctx.host.http.writeJson(res, 200, { ok: true });
47903
47934
  return true;
47904
- });
47935
+ }, [
47936
+ { method: "DELETE", path: "/:operationId", summary: "Terminate a Shell session.", category: "Terminal Plugin", gate: "origin-write", transport: "http" },
47937
+ { method: "POST", path: "/:operationId/relaunch", summary: "Relaunch a dormant Shell session.", category: "Terminal Plugin", gate: "origin-write", transport: "http" }
47938
+ ]);
47905
47939
  }
47906
47940
  function isRestoredShellEvent(value, pluginId) {
47907
47941
  if (!value || typeof value !== "object") return false;
@@ -47943,7 +47977,7 @@ var routes_default = definePlugin({
47943
47977
  ctx.host.operations.registerPayloadSanitizer(ctx.pluginId, TERMINAL_SENSITIVE_FIELDS);
47944
47978
  const infraServices = createInfraServices();
47945
47979
  const runtime = createTerminalRuntime(ctx);
47946
- registerWsHandler(ctx, "/", runtime.handleUpgrade);
47980
+ registerWsHandler(ctx, "/", runtime.handleUpgrade, { method: "GET", path: "", summary: "Open the Terminal WebSocket transport.", category: "Terminal Plugin", gate: "one-use-ticket", transport: "websocket" });
47947
47981
  ctx.host.lifecycle.registerCleanup(() => runtime.stop());
47948
47982
  const unsubscribeDelete = ctx.host.events.subscribe(OPERATION_DELETED_EVENT_CHANNEL2, (payload) => {
47949
47983
  if (!isOperationDeletedEvent2(payload) || payload.pluginId !== ctx.pluginId) return;