@qredence/fleet 0.5.11 → 0.6.1

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 (132) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/web/client/assets/action-swap-roll-COzQ86wm.js +1 -0
  3. package/dist/web/client/assets/agent-activity-svETLf_5.js +1 -0
  4. package/dist/web/client/assets/agent-disclosure-DAMuuGcM.js +1 -0
  5. package/dist/web/client/assets/analytics-stub-B6zGMuSV.js +1 -0
  6. package/dist/web/client/assets/{artifacts-panel-CQmFEF_H.js → artifacts-panel-HVjqBMyx.js} +1 -1
  7. package/dist/web/client/assets/button-C5wFDY5_.js +1 -0
  8. package/dist/web/client/assets/card-DA3Vnqay.js +1 -0
  9. package/dist/web/client/assets/{chat-yh02zgA7.js → chat-BhYseKd6.js} +7 -7
  10. package/dist/web/client/assets/{chat-command-palette-CmHTS3rs.js → chat-command-palette-LILDO_vG.js} +1 -1
  11. package/dist/web/client/assets/{citations-C_tPOJE_.js → citations-BPv8HIpf.js} +2 -2
  12. package/dist/web/client/assets/command-PhicLCoO.js +1 -0
  13. package/dist/web/client/assets/dialog-pBGUjAQ7.js +1 -0
  14. package/dist/web/client/assets/fleet-message-queue-fbYYwMj0.js +1 -0
  15. package/dist/web/client/assets/{fleet-pi-tool-renderer-BEDIO3al.js → fleet-pi-tool-renderer-BRgNnmaJ.js} +28 -28
  16. package/dist/web/client/assets/fleet-reasoning-panel-CjA2dwUJ.js +1 -0
  17. package/dist/web/client/assets/{fork-picker-dialog-ByBOGVsa.js → fork-picker-dialog-B7NNpVmW.js} +1 -1
  18. package/dist/web/client/assets/globals-CuIiqOTg.css +2 -0
  19. package/dist/web/client/assets/horizontal-resize-Cp3iHMH7.js +1 -0
  20. package/dist/web/client/assets/index-CSGplyr_.js +12 -0
  21. package/dist/web/client/assets/{input-0wwjWjKq.js → input-PcdubeKn.js} +1 -1
  22. package/dist/web/client/assets/input-group-C2HJEZvl.js +1 -0
  23. package/dist/web/client/assets/ipython-tool-CyuMOxz1.js +3 -0
  24. package/dist/web/client/assets/{markdown-code-CuQcR3UO.js → markdown-code-xNyjdZ4g.js} +1 -1
  25. package/dist/web/client/assets/{markdown-DInPmRUG.js → markdown-lvexwooo.js} +2 -2
  26. package/dist/web/client/assets/{model-selector-list-DsKTuAgS.js → model-selector-list-CoXX358G.js} +1 -1
  27. package/dist/web/client/assets/{notify-DgMKgZZW.js → notify-DxL0VD7Z.js} +1 -1
  28. package/dist/web/client/assets/openui-renderer-TLNe5e_Q.js +378 -0
  29. package/dist/web/client/assets/pencil-DcUwsKLn.js +1 -0
  30. package/dist/web/client/assets/prompt-input-fwP8TsgQ.js +1 -0
  31. package/dist/web/client/assets/{prompt-suggestions-Cc--lSNR.js → prompt-suggestions-BlGXmWS7.js} +1 -1
  32. package/dist/web/client/assets/provider-catalog-DYMFdbKc.js +1 -0
  33. package/dist/web/client/assets/provider-label-B4q5mI65.js +1 -0
  34. package/dist/web/client/assets/{repl-panel-DsPX04Xr.js → repl-panel-C5om8MGU.js} +1 -1
  35. package/dist/web/client/assets/{right-panel-registry-DewpBWHM.js → right-panel-registry-BBlxLxnx.js} +2 -2
  36. package/dist/web/client/assets/routes-XGsAIqBJ.js +16 -0
  37. package/dist/web/client/assets/settings-dialog-BSBasR3o.js +2 -0
  38. package/dist/web/client/assets/{subagent-chat-panel-DkVUumrP.js → subagent-chat-panel-oeLDPDAK.js} +1 -1
  39. package/dist/web/client/assets/{subagent-transcript-D8wmQxXe.js → subagent-transcript-DaVHjNUH.js} +1 -1
  40. package/dist/web/client/assets/{subagents-panel-BMp2Ego0.js → subagents-panel-D_aVgSCi.js} +1 -1
  41. package/dist/web/client/assets/surfaces-BhAXz9So.js +1 -0
  42. package/dist/web/client/assets/{switch-9rTeg6J6.js → switch-WhXeJNNY.js} +1 -1
  43. package/dist/web/client/assets/{toast-Bt9p2OL4.js → toast-D3c9XeGe.js} +1 -1
  44. package/dist/web/client/assets/{tool-result-DfnPN0FQ.js → tool-result-Cki8WUNc.js} +3 -3
  45. package/dist/web/client/assets/virtualized-turn-list-CdMa-ydT.js +6 -0
  46. package/dist/web/client/assets/workspace-panel-77bDbprs.js +1 -0
  47. package/dist/web/client/bundle-budget.json +6 -6
  48. package/dist/web/launcher.mjs +10 -1
  49. package/dist/web/server/{_tanstack-start-manifest_v-po4woX6g-AUGCOEZ2.js → _tanstack-start-manifest_v-0L7fqnH4-KMVGUFE4.js} +25 -24
  50. package/dist/web/server/{agent-activity-CS2rbF_C-A3R26CYH.js → agent-activity-BuEE6iVw-CDZLK4D2.js} +4 -4
  51. package/dist/web/server/{artifacts-panel-8GGUCtOd-X5TNKTY2.js → artifacts-panel-D3ySO--V-XSL53CXL.js} +18 -18
  52. package/dist/web/server/{chat-command-palette-Dgl5tqWn-72LLEWUD.js → chat-command-palette-kAbXhWVg-TJWXH2WW.js} +9 -9
  53. package/dist/web/server/{chunk-O4OTWWPF.js → chunk-2DDWXTVG.js} +5 -5
  54. package/dist/web/server/{chunk-MIW4LJTV.js → chunk-2JHTYWD5.js} +15 -23
  55. package/dist/web/server/{chunk-7MDZVLIY.js → chunk-3TIMGWWI.js} +1 -2
  56. package/dist/web/server/{chunk-AGFRJQZ7.js → chunk-4WBFCB4O.js} +257 -257
  57. package/dist/web/server/{chunk-P6UMR32I.js → chunk-5UCAJBAH.js} +4 -4
  58. package/dist/web/server/{chunk-BXWAUTTH.js → chunk-D27LRYVT.js} +42 -42
  59. package/dist/web/server/{chunk-YXXRP3NS.js → chunk-DLUZFOG3.js} +5 -5
  60. package/dist/web/server/{chunk-K3BXQG3N.js → chunk-EBG3XFGQ.js} +60 -60
  61. package/dist/web/server/{chunk-2ATMSG7U.js → chunk-EJEPDVK6.js} +3 -3
  62. package/dist/web/server/{chunk-IJPCV6DH.js → chunk-FYDQK6UX.js} +1 -1
  63. package/dist/web/server/{chunk-WKV2Z4KO.js → chunk-HF7DG7PC.js} +74 -74
  64. package/dist/web/server/{chunk-WYL2DW5R.js → chunk-JTCCQZLN.js} +2 -2
  65. package/dist/web/server/{chunk-UAPNEWCA.js → chunk-KP2PNDGL.js} +6 -6
  66. package/dist/web/server/chunk-M5RSPNYN.js +22 -0
  67. package/dist/web/server/{chunk-7SR6WDM2.js → chunk-MNBGB2SP.js} +2 -2
  68. package/dist/web/server/{chunk-HSJMLO36.js → chunk-MNPHMZU7.js} +3 -3
  69. package/dist/web/server/{chunk-JQDLJ7KI.js → chunk-NGCQJ33Y.js} +1134 -1134
  70. package/dist/web/server/{chunk-7SD2ZSEA.js → chunk-NIDBN7BQ.js} +1 -1
  71. package/dist/web/server/{chunk-ZJFA4F5X.js → chunk-NIZBFVJF.js} +2 -2
  72. package/dist/web/server/{chunk-P7H2OPKF.js → chunk-NJ4QEZHK.js} +11 -4
  73. package/dist/web/server/{chunk-WM4PUT6M.js → chunk-NNKJTKOQ.js} +234 -234
  74. package/dist/web/server/{chunk-N6NOTURM.js → chunk-NWDI3OWB.js} +4 -4
  75. package/dist/web/server/{chunk-ABBWBBSS.js → chunk-O3HDELZ2.js} +74826 -74825
  76. package/dist/web/server/{chunk-GGT2ZKDB.js → chunk-PLYZ7P2Y.js} +11 -155
  77. package/dist/web/server/chunk-PTCKOR23.js +39 -0
  78. package/dist/web/server/{chunk-RNOJACWQ.js → chunk-QFRCJWQQ.js} +7 -7
  79. package/dist/web/server/{chunk-NXJ32VFR.js → chunk-QIULBRTU.js} +13 -13
  80. package/dist/web/server/{chunk-XKKXXG6N.js → chunk-RIP3PBWT.js} +3 -3
  81. package/dist/web/server/{chunk-YKVGQBZA.js → chunk-S5LFXXDY.js} +625 -622
  82. package/dist/web/server/{chunk-XLNCWZMZ.js → chunk-UCUFC553.js} +3 -1
  83. package/dist/web/server/{chunk-KOUEJ3NU.js → chunk-UL2725KQ.js} +3 -3
  84. package/dist/web/server/{chunk-HFQTI7AX.js → chunk-VPKX7QRU.js} +3 -3
  85. package/dist/web/server/{chunk-LZ4Q5KUJ.js → chunk-WNCAL4HN.js} +133 -133
  86. package/dist/web/server/{chunk-C5X6G26O.js → chunk-XIB6XNUX.js} +436 -436
  87. package/dist/web/server/{chunk-JUROEEWM.js → chunk-YGYOBX7G.js} +82 -4
  88. package/dist/web/server/{chunk-WILCIZYU.js → chunk-ZIFSJ3HQ.js} +626 -626
  89. package/dist/web/server/fleet-message-queue-D_w8lSeY-T3HB7HVQ.js +152 -0
  90. package/dist/web/server/{fleet-pi-tool-renderer-umKunT3K-O4GBH35V.js → fleet-pi-tool-renderer-qwc-qZFq-4U556N5Q.js} +12 -12
  91. package/dist/web/server/{fleet-reasoning-panel-BxC2COxi-GPLMQSTT.js → fleet-reasoning-panel-DG_vuvv0-NCZWEEIT.js} +26 -26
  92. package/dist/web/server/{fleet-subagent-list-CpSYzCIq-JDH2LHSS.js → fleet-subagent-list-BGb0PjhF-2X67FMUV.js} +1 -1
  93. package/dist/web/server/{fleet-tool-timeline-IB36_PB2-XJENTO6I.js → fleet-tool-timeline-D6yM4ZMz-ZSFVRRRI.js} +1 -1
  94. package/dist/web/server/{fork-picker-dialog-DlINz9UQ-UWIXFDJX.js → fork-picker-dialog-Ds6Tgtu3-DIBWN7MV.js} +5 -5
  95. package/dist/web/server/{model-selector-list-OYnzNbyu-HBGCNF2L.js → model-selector-list-DxeGZoD2-P6S6FSJH.js} +9 -9
  96. package/dist/web/server/{openui-renderer-Cj7kfqyL-EKJ6JTTQ.js → openui-renderer-MKFv6LlH-MDRSVFEY.js} +11 -11
  97. package/dist/web/server/{prompt-suggestions-D4AEEY7K-RZSP7PWV.js → prompt-suggestions-BOItmGnD-YQA7RHLG.js} +2 -2
  98. package/dist/web/server/{repl-panel-D5KsoJik-BQKO53JO.js → repl-panel-CuyF8wt5-CHDT2Q3N.js} +2 -2
  99. package/dist/web/server/{router-Ci1wxI7I-E2AYMNON.js → router-Dg72SESP-PCWKLFRG.js} +1239 -470
  100. package/dist/web/server/{routes-CRpm9-Sa-IYK6MUJO.js → routes-BGrVtPYF-SURPAJN6.js} +5781 -5588
  101. package/dist/web/server/server.js +2 -2
  102. package/dist/web/server/{settings-dialog-BvkgNflv-GPJ6COQO.js → settings-dialog-CK0FJlTg-HZRBAXDZ.js} +1577 -1264
  103. package/dist/web/server/{subagent-chat-panel-CMuvW9Sd-M5TEEGQW.js → subagent-chat-panel-gzamnTgK-PQ2TLLJF.js} +21 -21
  104. package/dist/web/server/{subagents-panel-DgfB6_Yy-4INEPE3Y.js → subagents-panel-Berjd7HJ-EI5ZKC6V.js} +20 -20
  105. package/dist/web/server/{workspace-panel-bpwj-Veu-Q2CEJMN4.js → workspace-panel-CBBa_3UO-B4PPFPMA.js} +46 -21
  106. package/package.json +1 -1
  107. package/dist/web/client/assets/action-swap-roll-BB8DFMuf.js +0 -1
  108. package/dist/web/client/assets/agent-activity-CwMDU7aP.js +0 -1
  109. package/dist/web/client/assets/agent-disclosure-B8SnhQXL.js +0 -1
  110. package/dist/web/client/assets/analytics-stub-Cas1He0w.js +0 -1
  111. package/dist/web/client/assets/button-BR2WWrFo.js +0 -1
  112. package/dist/web/client/assets/card-BKl76a3R.js +0 -1
  113. package/dist/web/client/assets/command-DPfiaYUL.js +0 -1
  114. package/dist/web/client/assets/dialog-BEZuZhzk.js +0 -1
  115. package/dist/web/client/assets/fleet-message-queue-DUz6Hfrf.js +0 -1
  116. package/dist/web/client/assets/fleet-reasoning-panel-CbkO7u-v.js +0 -1
  117. package/dist/web/client/assets/globals-B_I1Eq1u.css +0 -2
  118. package/dist/web/client/assets/horizontal-resize-qK6eRhIG.js +0 -1
  119. package/dist/web/client/assets/index-C1zOjrMK.js +0 -12
  120. package/dist/web/client/assets/input-group-BFDsCVS9.js +0 -1
  121. package/dist/web/client/assets/ipython-tool-ldJ9F1Cw.js +0 -3
  122. package/dist/web/client/assets/openui-renderer-J3dhPpL4.js +0 -378
  123. package/dist/web/client/assets/prompt-input-qPIXZ-Rb.js +0 -1
  124. package/dist/web/client/assets/provider-catalog-D8G66gwc.js +0 -1
  125. package/dist/web/client/assets/provider-label-Dpr7djG9.js +0 -1
  126. package/dist/web/client/assets/routes-vNkVToAF.js +0 -16
  127. package/dist/web/client/assets/settings-dialog-B-v4me3Y.js +0 -1
  128. package/dist/web/client/assets/surfaces-DI-U-_2a.js +0 -1
  129. package/dist/web/client/assets/virtualized-turn-list-DMJENRY0.js +0 -6
  130. package/dist/web/client/assets/workspace-panel-G6yMpKJ8.js +0 -1
  131. package/dist/web/server/chunk-QK4CHLVV.js +0 -17
  132. package/dist/web/server/fleet-message-queue-j0DCU5Xy-5HKBHMPV.js +0 -75
@@ -1,4 +1,7 @@
1
1
  import {
2
+ ChatMcpDeleteRequestSchema,
3
+ ChatMcpOAuthLoginRequestSchema,
4
+ ChatMcpUpsertRequestSchema,
2
5
  ChatModelsDiscoverRequestSchema,
3
6
  ChatProviderOAuthLoginRequestSchema,
4
7
  ChatProviderRemoveRequestSchema,
@@ -12,7 +15,7 @@ import {
12
15
  domAnimation,
13
16
  initAnalytics,
14
17
  isServer
15
- } from "./chunk-JUROEEWM.js";
18
+ } from "./chunk-YGYOBX7G.js";
16
19
  import {
17
20
  DEFAULT_UI_PREFERENCES,
18
21
  isModelPatternEnabled,
@@ -20,10 +23,12 @@ import {
20
23
  } from "./chunk-ETTDO4UO.js";
21
24
  import {
22
25
  Toaster
23
- } from "./chunk-KOUEJ3NU.js";
26
+ } from "./chunk-UL2725KQ.js";
24
27
  import {
28
+ fallbackSessionLabel,
29
+ meaningfulSessionLabel,
25
30
  redactSessionLabelSecrets
26
- } from "./chunk-QK4CHLVV.js";
31
+ } from "./chunk-PTCKOR23.js";
27
32
  import "./chunk-SZJUXVWG.js";
28
33
  import "./chunk-TNL4YV63.js";
29
34
  import {
@@ -37,7 +42,7 @@ import {
37
42
  CardHeader,
38
43
  CardTitle,
39
44
  validateAndNormalizeOpenUIHtmlArtifact
40
- } from "./chunk-7MDZVLIY.js";
45
+ } from "./chunk-3TIMGWWI.js";
41
46
  import {
42
47
  ChatNewRequestSchema,
43
48
  ChatOpenUIArtifactUpsertRequestSchema,
@@ -57,7 +62,7 @@ import {
57
62
  UploadedAttachmentSchema,
58
63
  ZodError,
59
64
  external_exports
60
- } from "./chunk-GGT2ZKDB.js";
65
+ } from "./chunk-PLYZ7P2Y.js";
61
66
  import {
62
67
  KNOWN_PROVIDERS,
63
68
  OPENAI_CHAT_COMPLETIONS_PROVIDER_ID,
@@ -72,9 +77,9 @@ import {
72
77
  toInstanceSlug,
73
78
  toOccInstanceId
74
79
  } from "./chunk-RJOANOT4.js";
75
- import "./chunk-LZ4Q5KUJ.js";
80
+ import "./chunk-WNCAL4HN.js";
76
81
  import "./chunk-JBLHIEVG.js";
77
- import "./chunk-C5X6G26O.js";
82
+ import "./chunk-XIB6XNUX.js";
78
83
  import "./chunk-HFQZLPU2.js";
79
84
  import "./chunk-4ZIEVI5O.js";
80
85
  import "./chunk-DJMHPJBP.js";
@@ -91,7 +96,7 @@ import "./chunk-JDCCC7A7.js";
91
96
  import "./chunk-L547YHC4.js";
92
97
  import "./chunk-MLKGABMK.js";
93
98
 
94
- // web/app/dist/server/assets/router-Ci1wxI7I.js
99
+ // web/app/dist/server/assets/router-Dg72SESP.js
95
100
  import { useEffect, useLayoutEffect } from "react";
96
101
  import { jsx, jsxs } from "react/jsx-runtime";
97
102
  import { basename, dirname, extname, isAbsolute, join, relative, resolve, sep } from "node:path";
@@ -107,12 +112,7 @@ var domMax = {
107
112
  ...drag,
108
113
  ...layout
109
114
  };
110
- function MotionRuntime({ children }) {
111
- return /* @__PURE__ */ jsx(LazyMotion, {
112
- features: domMax,
113
- children
114
- });
115
- }
115
+ var inter_latin_wght_normal_default = "/assets/inter-latin-wght-normal-Dx4kXJAl.woff2";
116
116
  function NotFoundPage({ title = "404", description = "The requested page could not be found." }) {
117
117
  return /* @__PURE__ */ jsx("main", {
118
118
  className: "container mx-auto flex min-h-svh items-center justify-center p-4",
@@ -125,8 +125,13 @@ function NotFoundPage({ title = "404", description = "The requested page could n
125
125
  })
126
126
  });
127
127
  }
128
- var globals_default = "/assets/globals-B_I1Eq1u.css";
129
- var inter_latin_wght_normal_default = "/assets/inter-latin-wght-normal-Dx4kXJAl.woff2";
128
+ function MotionRuntime({ children }) {
129
+ return /* @__PURE__ */ jsx(LazyMotion, {
130
+ features: domMax,
131
+ children
132
+ });
133
+ }
134
+ var globals_default = "/assets/globals-CuIiqOTg.css";
130
135
  function makeQueryClient() {
131
136
  return new QueryClient({ defaultOptions: { queries: {
132
137
  staleTime: 6e4,
@@ -140,7 +145,7 @@ function getQueryClient() {
140
145
  if (!browserQueryClient) browserQueryClient = makeQueryClient();
141
146
  return browserQueryClient;
142
147
  }
143
- var Route$27 = createRootRoute({
148
+ var Route$29 = createRootRoute({
144
149
  head: () => ({
145
150
  meta: [
146
151
  { charSet: "utf-8" },
@@ -210,8 +215,8 @@ function RootDocument({ children }) {
210
215
  ] })]
211
216
  });
212
217
  }
213
- var $$splitComponentImporter = () => import("./routes-CRpm9-Sa-IYK6MUJO.js");
214
- var Route$26 = createFileRoute("/")({ component: lazyRouteComponent($$splitComponentImporter, "component") });
218
+ var $$splitComponentImporter = () => import("./routes-BGrVtPYF-SURPAJN6.js");
219
+ var Route$28 = createFileRoute("/")({ component: lazyRouteComponent($$splitComponentImporter, "component") });
215
220
  var ManagedAttachmentValidationError = class extends Error {
216
221
  status;
217
222
  constructor(message, status) {
@@ -5626,9 +5631,14 @@ var PrimeBridge = class {
5626
5631
  async followUp(sessionId, text) {
5627
5632
  await this.#requireSession(sessionId).connection.followUp(text);
5628
5633
  }
5629
- async deleteQueuedMessage(sessionId, lane, index, expectedText) {
5634
+ async mutateQueuedMessage(sessionId, lane, index, expectedText, mutation) {
5630
5635
  const session = this.#requireSession(sessionId);
5631
- const status = await session.connection.mutateQueuedMessage(lane, index, expectedText, { type: "delete" });
5636
+ const upstreamMutation = mutation.type === "delete" ? { type: "delete" } : {
5637
+ type: "replace",
5638
+ text: mutation.text,
5639
+ lane: mutation.lane ?? lane
5640
+ };
5641
+ const status = await session.connection.mutateQueuedMessage(lane, index, expectedText, upstreamMutation);
5632
5642
  const queue = await session.connection.getQueue();
5633
5643
  return {
5634
5644
  status,
@@ -5638,6 +5648,9 @@ var PrimeBridge = class {
5638
5648
  }
5639
5649
  };
5640
5650
  }
5651
+ async deleteQueuedMessage(sessionId, lane, index, expectedText) {
5652
+ return this.mutateQueuedMessage(sessionId, lane, index, expectedText, { type: "delete" });
5653
+ }
5641
5654
  async abort(sessionId) {
5642
5655
  const session = this.#requireSession(sessionId);
5643
5656
  this.#dialogs.cancelAll(sessionId, "user-abort");
@@ -6886,370 +6899,6 @@ function handleChatEventsGet(request) {
6886
6899
  return createSseResponse(request, getBridge(), { sessionId: sessionId.data }, lastEventIdFor(request, url));
6887
6900
  }, request);
6888
6901
  }
6889
- var BodySchema$1 = external_exports.object({
6890
- sessionId: SessionIdSchema,
6891
- model: external_exports.object({
6892
- provider: external_exports.string(),
6893
- id: external_exports.string()
6894
- })
6895
- });
6896
- function handleChatModelPost(request) {
6897
- return wrapApiHandler(async () => {
6898
- const raw = await request.json().catch(() => ({}));
6899
- const body = BodySchema$1.parse(raw);
6900
- const bridge = getBridge();
6901
- const session = bridge.getSession(body.sessionId) ?? await bridge.resumeSessionById(body.sessionId);
6902
- if (!session || !await requireProjectSession(session)) return Response.json({ message: `Unknown session: ${body.sessionId}` }, { status: 404 });
6903
- await bridge.setModel(body.sessionId, {
6904
- provider: body.model.provider,
6905
- id: body.model.id
6906
- });
6907
- return Response.json({ ok: true });
6908
- }, request);
6909
- }
6910
- function toPatternCandidate(model) {
6911
- return {
6912
- id: model.id,
6913
- name: model.name,
6914
- provider: model.provider,
6915
- modelId: model.id,
6916
- key: `${model.provider}/${model.id}`
6917
- };
6918
- }
6919
- function handleChatModelsGet(request) {
6920
- return wrapApiHandler(async () => {
6921
- const config = getPrimeConfig();
6922
- const cwd = await cwdForRequest(request);
6923
- const settings = config.settingsFor(cwd);
6924
- const registry = config.modelRegistry;
6925
- const scope = new URL(request.url).searchParams.get("scope") === "all" ? "all" : "enabled";
6926
- let models = registry.getAll();
6927
- if (scope === "enabled") {
6928
- models = models.filter((model) => registry.hasConfiguredAuth(model));
6929
- const patterns = settings.getEnabledModels();
6930
- if (patterns !== void 0) models = models.filter((model) => isModelPatternEnabled(toPatternCandidate(model), patterns));
6931
- }
6932
- const diagnostics = [];
6933
- const defaultProvider = settings.getDefaultProvider();
6934
- const defaultModel = settings.getDefaultModel();
6935
- const defaultThinkingLevel = settings.getDefaultThinkingLevel();
6936
- const selectedModelKey = defaultProvider && defaultModel ? `${defaultProvider}/${defaultModel}` : void 0;
6937
- return Response.json({
6938
- models: models.map((m) => {
6939
- const thinkingLevels = getSupportedThinkingLevels(m);
6940
- const fallback = m.reasoning ? "medium" : "off";
6941
- return {
6942
- key: `${m.provider}/${m.id}`,
6943
- provider: m.provider,
6944
- id: m.id,
6945
- name: m.name,
6946
- reasoning: m.reasoning,
6947
- input: m.input,
6948
- contextWindow: m.contextWindow,
6949
- maxTokens: m.maxTokens,
6950
- available: registry.hasConfiguredAuth(m),
6951
- thinkingLevels,
6952
- defaultThinkingLevel: thinkingLevels.includes(fallback) ? fallback : thinkingLevels[0] ?? "off"
6953
- };
6954
- }),
6955
- ...selectedModelKey ? { selectedModelKey } : {},
6956
- ...defaultProvider ? { defaultProvider } : {},
6957
- ...defaultModel ? { defaultModel } : {},
6958
- ...defaultThinkingLevel ? { defaultThinkingLevel } : {},
6959
- diagnostics
6960
- });
6961
- }, request);
6962
- }
6963
- function storedApiForCustomProvider(api) {
6964
- return api === "google-genai" ? "google-generative-ai" : api;
6965
- }
6966
- function uiApiForCustomProvider(value) {
6967
- if (value === "google-generative-ai") return "google-genai";
6968
- return isPiCustomProviderApi(value) ? value : void 0;
6969
- }
6970
- function envVarNameForManagedProvider(providerId) {
6971
- if (providerId === "openai-chat-completions") return "OPENAI_CHAT_COMPLETIONS_API_KEY";
6972
- const slug = providerId.slice(providerId.indexOf("+") + 1).toUpperCase().replace(/[^A-Z0-9]+/g, "_");
6973
- return isOccProviderId(providerId) ? `OPENAI_CHAT_COMPLETIONS_${slug}_API_KEY` : `CUSTOM_${slug}_API_KEY`;
6974
- }
6975
- function readModelsJson(filePath) {
6976
- try {
6977
- if (!existsSync(filePath)) return {};
6978
- return parseModelsJson(readFileSync(filePath, "utf-8"));
6979
- } catch {
6980
- return {};
6981
- }
6982
- }
6983
- function stripJsonComments(input) {
6984
- return input.replace(/"(?:\\.|[^"\\])*"|\/\/[^\n]*/g, (match) => match[0] === '"' ? match : "").replace(/"(?:\\.|[^"\\])*"|,(\s*[}\]])/g, (match, tail) => tail ?? (match[0] === '"' ? match : ""));
6985
- }
6986
- function parseModelsJson(raw) {
6987
- const parsed = JSON.parse(stripJsonComments(raw));
6988
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("models.json must contain an object");
6989
- return parsed;
6990
- }
6991
- function readModelsJsonForWrite(filePath) {
6992
- if (!existsSync(filePath)) return {};
6993
- try {
6994
- return parseModelsJson(readFileSync(filePath, "utf-8"));
6995
- } catch (error) {
6996
- throw new Error(`Refusing to update models.json because it could not be parsed: ${error instanceof Error ? error.message : error}`);
6997
- }
6998
- }
6999
- function mergeModelDefinitions(existing, incoming) {
7000
- const existingById = new Map((existing ?? []).map((model) => [model.id, model]));
7001
- const seen = /* @__PURE__ */ new Set();
7002
- return incoming.flatMap((model) => {
7003
- if (seen.has(model.id)) return [];
7004
- seen.add(model.id);
7005
- return [{
7006
- ...existingById.get(model.id),
7007
- ...model
7008
- }];
7009
- });
7010
- }
7011
- function listCustomProviders(filePath) {
7012
- return readModelsJson(filePath).providers ?? {};
7013
- }
7014
- function writeModelsJson(filePath, data) {
7015
- mkdirSync(dirname(filePath), {
7016
- recursive: true,
7017
- mode: 448
7018
- });
7019
- const serialized = `${JSON.stringify(data, null, " ")}
7020
- `;
7021
- const tmpPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
7022
- writeFileSync(tmpPath, serialized, "utf-8");
7023
- renameSync(tmpPath, filePath);
7024
- }
7025
- function upsertCustomProvider(filePath, providerId, input) {
7026
- const data = readModelsJsonForWrite(filePath);
7027
- const providers = { ...data.providers ?? {} };
7028
- const existing = providers[providerId] ?? {};
7029
- providers[providerId] = {
7030
- ...existing,
7031
- name: input.name ?? existing.name,
7032
- baseUrl: input.baseUrl,
7033
- api: storedApiForCustomProvider(input.api),
7034
- apiKey: input.apiKey,
7035
- models: mergeModelDefinitions(existing.models, input.models)
7036
- };
7037
- writeModelsJson(filePath, {
7038
- ...data,
7039
- providers
7040
- });
7041
- }
7042
- function addCustomProviderModelIds(filePath, providerId, modelIds) {
7043
- const data = readModelsJsonForWrite(filePath);
7044
- const providers = { ...data.providers ?? {} };
7045
- const existing = providers[providerId];
7046
- if (!existing) return;
7047
- providers[providerId] = {
7048
- ...existing,
7049
- models: mergeModelDefinitions(existing.models, [...existing.models ?? [], ...modelIds.map((id) => ({ id }))])
7050
- };
7051
- writeModelsJson(filePath, {
7052
- ...data,
7053
- providers
7054
- });
7055
- }
7056
- function removeCustomProvider(filePath, providerId) {
7057
- const data = readModelsJsonForWrite(filePath);
7058
- const providers = data.providers;
7059
- if (!providers || !(providerId in providers)) return;
7060
- const next = { ...providers };
7061
- delete next[providerId];
7062
- writeModelsJson(filePath, {
7063
- ...data,
7064
- providers: next
7065
- });
7066
- }
7067
- function isDiscoverableEntry(entry) {
7068
- const baseUrl = entry?.baseUrl;
7069
- if (!baseUrl) return false;
7070
- const api = uiApiForCustomProvider(entry?.api);
7071
- if (api && !isOccFamilyApi(api)) return false;
7072
- if (entry?.api && !api) return false;
7073
- try {
7074
- const parsed = new URL(baseUrl);
7075
- return parsed.protocol === "https:" || parsed.protocol === "http:";
7076
- } catch {
7077
- return false;
7078
- }
7079
- }
7080
- function openAiModelsUrl(baseUrl) {
7081
- const parsed = new URL(baseUrl);
7082
- if (parsed.protocol !== "https:" && parsed.protocol !== "http:") throw new Error("model discovery requires an http(s) URL");
7083
- if (parsed.protocol === "http:" && !isLoopbackHostname(parsed.hostname)) throw new Error("model discovery requires https for non-loopback hosts");
7084
- const path = parsed.pathname.replace(/\/+$/, "");
7085
- parsed.pathname = path.endsWith("/v1") ? `${path}/models` : `${path}/v1/models`;
7086
- parsed.search = "";
7087
- parsed.hash = "";
7088
- return parsed;
7089
- }
7090
- function handleChatModelsDiscoverPost(request) {
7091
- return wrapApiHandler(async () => {
7092
- const raw = await request.json().catch(() => ({}));
7093
- const body = ChatModelsDiscoverRequestSchema.parse(raw);
7094
- const config = getPrimeConfig();
7095
- const apiKey = await config.modelRegistry.getApiKeyForProvider(body.providerId);
7096
- if (!apiKey) return Response.json({
7097
- providerId: body.providerId,
7098
- models: []
7099
- });
7100
- const provider = body.providerId;
7101
- const entry = listCustomProviders(`${config.agentDir}/models.json`)[provider];
7102
- const api = uiApiForCustomProvider(entry?.api);
7103
- if (entry?.api && !api || api && !isOccFamilyApi(api)) return Response.json({
7104
- providerId: provider,
7105
- models: []
7106
- });
7107
- const baseUrl = entry?.baseUrl;
7108
- if (!baseUrl) return Response.json({
7109
- providerId: provider,
7110
- models: []
7111
- });
7112
- try {
7113
- const modelsUrl = openAiModelsUrl(baseUrl);
7114
- const response = await fetch(modelsUrl, {
7115
- headers: { Authorization: `Bearer ${apiKey}` },
7116
- redirect: "error",
7117
- signal: AbortSignal.timeout(1e4)
7118
- });
7119
- if (!response.ok) return Response.json({
7120
- providerId: provider,
7121
- models: []
7122
- });
7123
- const models = ((await response.json()).data ?? []).map((m) => ({
7124
- key: `${provider}/${m.id}`,
7125
- provider,
7126
- id: m.id,
7127
- name: m.id,
7128
- reasoning: false,
7129
- input: ["text"],
7130
- available: true,
7131
- defaultThinkingLevel: "off",
7132
- thinkingLevels: ["off"]
7133
- }));
7134
- if (models.length > 0) {
7135
- addCustomProviderModelIds(`${config.agentDir}/models.json`, provider, models.map((model) => model.id));
7136
- config.reloadAuth();
7137
- }
7138
- return Response.json({
7139
- providerId: provider,
7140
- models
7141
- });
7142
- } catch {
7143
- return Response.json({
7144
- providerId: provider,
7145
- models: []
7146
- });
7147
- }
7148
- }, request);
7149
- }
7150
- function toThinkingLevel(level) {
7151
- return level;
7152
- }
7153
- function handleChatNewPost(request) {
7154
- return wrapApiHandler(async () => {
7155
- const bridge = getBridge();
7156
- const registry = getPrimeConfig().projectRegistry;
7157
- const raw = await request.json().catch(() => ({}));
7158
- const body = ChatNewRequestSchema.parse(raw);
7159
- const projectId = body.projectId ?? await registry.projectIdForCwd(getPrimeConfig().defaultCwd) ?? (await registry.register(getPrimeConfig().defaultCwd)).projectId;
7160
- const project = await registry.get(projectId);
7161
- bridge.ensureKernelReady(project.canonicalPath).catch(() => {
7162
- });
7163
- const session = await bridge.createSession({
7164
- cwd: project.canonicalPath,
7165
- projectId,
7166
- thinkingLevel: toThinkingLevel(body.thinkingLevel),
7167
- mode: body.mode,
7168
- openUI: body.openUI
7169
- });
7170
- if (body.model) {
7171
- await bridge.setModel(session.sessionId, body.model);
7172
- const thinking = body.model.thinkingLevel ?? body.thinkingLevel;
7173
- if (thinking) await session.connection.setThinkingLevel(toThinkingLevel(thinking));
7174
- }
7175
- return Response.json({
7176
- session: {
7177
- sessionId: session.sessionId,
7178
- projectId
7179
- },
7180
- messages: [],
7181
- planPresentations: [],
7182
- presentation: bridge.getPresentation(session.sessionId)
7183
- });
7184
- }, request);
7185
- }
7186
- function record(value) {
7187
- return typeof value === "object" && value !== null ? value : void 0;
7188
- }
7189
- function artifactIndexFor(artifact) {
7190
- const input = record(artifact.input);
7191
- return typeof input?.artifactIndex === "number" ? input.artifactIndex : void 0;
7192
- }
7193
- function handleChatOpenUIArtifactPut(request) {
7194
- return wrapApiHandler(async () => {
7195
- const raw = await request.json().catch(() => ({}));
7196
- const parsed = ChatOpenUIArtifactUpsertRequestSchema.safeParse(raw);
7197
- if (!parsed.success) return Response.json({ message: "Invalid OpenUI artifact request." }, { status: 400 });
7198
- const body = parsed.data;
7199
- const validation = validateAndNormalizeOpenUIHtmlArtifact(body.artifact);
7200
- if (!validation.ok) return Response.json({ message: validation.reason }, { status: validation.status ?? 400 });
7201
- const bridge = getBridge();
7202
- const session = bridge.getSession(body.sessionId) ?? await bridge.resumeSessionById(body.sessionId);
7203
- if (!session || !await requireProjectSession(session)) return Response.json({ message: `Unknown session: ${body.sessionId}` }, { status: 404 });
7204
- const messages = await bridge.getMessages(session.sessionId);
7205
- const incomingId = body.assistantMessageId;
7206
- const exact = messages.find((message) => message.role === "assistant" && message.id === incomingId);
7207
- const existing = bridge.getPresentation(session.sessionId).artifactRuns.flatMap((run) => run.artifacts).filter((artifact2) => artifact2.kind === "openui-html").find((artifact2) => artifactIndexFor(artifact2) === body.artifactIndex && (record(artifact2.input)?.clientMessageId === incomingId || artifact2.sourceMessageId === incomingId));
7208
- const fallback = existing ? void 0 : [...messages].reverse().find((message) => message.role === "assistant");
7209
- const assistantMessageId = exact?.id ?? existing?.sourceMessageId ?? fallback?.id;
7210
- if (!assistantMessageId) return Response.json({ message: "Unable to associate OpenUI artifact with an assistant message." }, { status: 409 });
7211
- const artifact = {
7212
- id: stablePresentationId(`${assistantMessageId}:openui-html:${body.artifactIndex}`),
7213
- runId: stablePresentationId(`${assistantMessageId}:openui`),
7214
- sourceMessageId: assistantMessageId,
7215
- kind: "openui-html",
7216
- title: validation.value.title,
7217
- status: "success",
7218
- input: {
7219
- clientMessageId: incomingId,
7220
- artifactIndex: body.artifactIndex
7221
- },
7222
- output: validation.value,
7223
- timestamp: Date.now()
7224
- };
7225
- const presentation = await bridge.upsertPresentationArtifact(session.sessionId, artifact);
7226
- return Response.json({
7227
- artifact,
7228
- presentation
7229
- });
7230
- }, request);
7231
- }
7232
- function handleChatPlanPresentationPut(request) {
7233
- return wrapApiHandler(async () => {
7234
- const body = ChatPlanPresentationUpsertRequestSchema.parse(await request.json().catch(() => ({})));
7235
- const bridge = getBridge();
7236
- const session = bridge.getSession(body.sessionId) ?? await bridge.resumeSessionById(body.sessionId);
7237
- if (!session || !await requireProjectSession(session)) return Response.json({ message: `Unknown session: ${body.sessionId}` }, { status: 404 });
7238
- const messages = await bridge.getMessages(body.sessionId);
7239
- const incomingId = body.presentation.assistantMessageId;
7240
- const known = messages.find((message) => message.id === incomingId && message.role === "assistant");
7241
- const existing = (await loadManagedPlanPresentations(session)).find((item) => item.assistantMessageId === incomingId || item.clientMessageId === incomingId);
7242
- const fallback = existing ? void 0 : [...messages].reverse().find((message) => message.role === "assistant");
7243
- const assistantMessageId = known?.id ?? existing?.assistantMessageId ?? fallback?.id;
7244
- if (!assistantMessageId) return Response.json({ message: "Unable to associate Plan presentation with an assistant message" }, { status: 409 });
7245
- const clientMessageId = incomingId !== assistantMessageId ? existing?.clientMessageId ?? incomingId : existing?.clientMessageId;
7246
- return Response.json({ presentation: await upsertManagedPlanPresentation(session, {
7247
- ...body.presentation,
7248
- assistantMessageId,
7249
- ...clientMessageId ? { clientMessageId } : {}
7250
- }) });
7251
- }, request);
7252
- }
7253
6902
  var PRIME_BUTTERFLY_SVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 178 178" aria-hidden="true"><path fill="currentColor" d="m 123.322,84.092671 c -0.192,0.0065 -0.43,0.0147 -0.74,0.0147 l -0.018,-0.0247 c -0.873,0.1977 -1.958,0.1266 -3.067,0.0537 -3.29,-0.216 -6.799,-0.4465 -5.635,6.2824 0.259,1.4822 -1.538,1.8465 -2.73,1.9082 -3.384,0.1853 -6.78,0.2594 -10.171,0.1915 -0.641,-0.0106 -1.2979,-0.5506 -1.8904,-1.0388 -0.1022,-0.0844 -0.2034,-0.1673 -0.3016,-0.2457 -0.1052,-0.0865 0.2898,-1.2042 0.4942,-1.2166 3.3078,-0.1931 4.5068,-2.4361 5.7028,-4.6724 0.603,-1.1253 1.204,-2.2488 2.072,-3.1088 7.856,-7.7874 15.878,-15.4265 25.054,-21.7008 0.895,-0.6114 1.989,-1.1733 2.73,-0.1111 0.571,0.8205 0.036,1.2854 -0.512,1.7627 -0.24,0.2088 -0.482,0.4199 -0.637,0.6642 -0.554,0.8792 -1.538,1.5273 -2.514,2.1717 -1.92,1.2655 -3.82,2.5172 -2.408,5.4798 1.225,2.5651 0.129,3.0202 -1.555,3.7198 l -0.069,0.0287 c -0.72,0.3021 -1.458,0.5764 -2.194,0.8506 -1.568,0.5835 -3.134,1.1662 -4.537,2.0149 -1.408,0.8522 -2.081,2.5134 0.222,3.4954 5.033,2.1428 18.064,-1.2784 20.608,-5.9965 2.377,-4.4147 5.931,-7.6891 9.481,-10.9611 1.992,-1.836 3.984,-3.6712 5.767,-5.7067 3.844,-4.3849 8.344,-8.1939 12.846,-12.005 2.239,-1.8944 4.478,-3.78938 6.637,-5.75588 1.624,-1.48207 2.297,-3.43353 1.026,-5.56412 -1.267,-2.118215 -3.416,-2.402287 -5.435,-1.926802 -13.309,3.130982 -26.166,7.355122 -37.585,15.241302 -18.23,12.5919 -36.4911,25.1406 -54.9002,37.4669 -6.2743,4.2056 -10.0723,2.1491 -12.1657,-5.1318 -4.6502,-16.1676 -11.4681,-30.2664 -31.0569,-32.4587 -7.1574,-0.8028 -12.4066,3.6807 -11.3692,10.7949 0.5249,3.6065 0.0495,7.003 -1.6858,10.3872 -0.3827,0.7472 -0.7689,1.4947 -1.1556,2.243 -2.672,5.1706 -5.3671,10.3857 -7.0394,15.8885 -0.1399,0.4602 -0.3002,0.9444 -0.4654,1.4437 -1.4909,4.5052 -3.3862,10.2323 5.659,10.5492 0.3705,0.0123 1.0808,0.944799 0.9943,1.290699 -0.1976,0.8213 -0.5991,1.797 -1.2413,2.2725 -8.6705,6.3917 -15.79706,14.1294 -18.860151,24.5971 -1.550066,5.2865 -0.524909,10.7765 3.989391,14.8705 3.22984,2.928 7.35516,4.625 10.97396,2.162 3.3009,-2.247 6.9232,-3.754 10.538,-5.259 3.1819,-1.324 6.358,-2.646 9.3041,-4.468 0.7101,-0.439 1.5727,-0.841 2.4456,-1.248 2.4138,-1.1228 4.9063,-2.2843 4.4709,-4.3841 -0.6854,-3.2908 -4.1623,-6.3418 -7.0586,-8.7384 -2.8716,-2.3769 -10.1897,-18.3411 -9.3189,-22.176099 1.2193,-5.3704 3.9645,-10.0201 6.7125,-14.6744 2.3458,-3.9731 4.6935,-7.9497 6.0956,-12.3806 0.5804,-1.828 2.8037,-2.8284 4.9466,-2.0997 1.4543,0.4928 1.2068,1.8278 0.9762,3.0715 -0.0063,0.0344 -0.0127,0.0685 -0.019,0.1027 -0.8688,4.7802 -1.721,9.566 -2.5733,14.3517 -0.4261,2.3924 -0.8521,4.7847 -1.2803,7.1762 -0.2717,1.5316 0.2038,2.7544 1.7909,3.0631 3.0569,0.599 2.989,1.9762 1.6119,4.341499 -1.4636,2.5072 -1.6674,5.5703 -0.0309,7.8861 1.6427,2.3282 4.3908,2.8161 7.1821,1.4204 1.7415,-0.8646 3.094,-0.0927 3.0755,1.6612 -0.1112,9.3688 3.8103,7.2561 8.584,3.1681 0.439,-0.3763 1.0373,-0.5846 1.6152,-0.7857 0.1048,-0.0366 0.2091,-0.0728 0.3116,-0.1098 0.4529,-0.1616 0.9062,-0.3224 1.3595,-0.4833 8.986,-3.1884 17.9603,-6.3725 23.0334,-15.573099 0.392,-0.7187 1.6783,-1.0669 2.6795,-1.3377 0.057,-0.0154 0.113,-0.0307 0.1681,-0.0456 5.8013,-1.5766 11.7248,-1.6001 17.6438,-1.6237 4.445,-0.0176 8.888,-0.0352 13.277,-0.7107 4.329,-0.667 9.047,-3.1928 9.084,-7.3736 0.035,-3.3707 -2.546,-3.1612 -5.123,-2.9519 -1.115,0.0906 -2.231,0.1811 -3.134,-0.0185 -0.182,-0.0381 -0.375,-0.0316 -0.686,-0.0209 z"/><path fill="currentColor" d="m 55.1325,131.29447 c -1.0745,7.1515 1.6551,13.2715 12.8266,13.1915 h -0.0062 c 9.5413,-0.389 20.3365,-6.164 30.8838,-13.5492 6.9653,-4.8787 12.9873,-10.0236 16.8903,-17.6253 2.872,-5.5889 1.395,-10.0723 -2.933,-13.993799 -1.908,-1.7291 -3.73,-1.9205 -5.867,0.1667 -7.5842,7.423099 -17.0261,11.474299 -26.7218,15.550099 -2.4706,1.0393 -5.2847,1.5582 -8.1187,2.0809 -7.5511,1.3924 -15.2431,2.8103 -16.954,14.1791 z"/></svg>`;
7254
6903
  function escapeHtml(value) {
7255
6904
  return value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
@@ -7377,10 +7026,10 @@ var decode$1 = (s) => atob(s);
7377
7026
  var CLIENT_ID$2 = decode$1("OWQxYzI1MGEtZTYxYi00NGQ5LTg4ZWQtNTk0NGQxOTYyZjVl");
7378
7027
  var AUTHORIZE_URL$1 = "https://claude.ai/oauth/authorize";
7379
7028
  var TOKEN_URL$1 = "https://platform.claude.com/v1/oauth/token";
7380
- var CALLBACK_HOST$1 = process.env.PI_OAUTH_CALLBACK_HOST || "127.0.0.1";
7029
+ var CALLBACK_HOST$2 = process.env.PI_OAUTH_CALLBACK_HOST || "127.0.0.1";
7381
7030
  var CALLBACK_PORT = 53692;
7382
- var CALLBACK_PATH = "/callback";
7383
- var REDIRECT_URI$1 = `http://localhost:${CALLBACK_PORT}${CALLBACK_PATH}`;
7031
+ var CALLBACK_PATH$1 = "/callback";
7032
+ var REDIRECT_URI$1 = `http://localhost:${CALLBACK_PORT}${CALLBACK_PATH$1}`;
7384
7033
  var SCOPES = "org:create_api_key user:profile user:inference user:sessions:claude_code user:mcp_servers user:file_upload";
7385
7034
  async function getNodeApis() {
7386
7035
  if (nodeApis) return nodeApis;
@@ -7430,7 +7079,7 @@ function formatErrorDetails(error) {
7430
7079
  }
7431
7080
  return String(error);
7432
7081
  }
7433
- async function startCallbackServer(expectedState) {
7082
+ async function startCallbackServer$1(expectedState) {
7434
7083
  const { createServer } = await getNodeApis();
7435
7084
  return new Promise((resolve2, reject) => {
7436
7085
  let settleWait;
@@ -7445,7 +7094,7 @@ async function startCallbackServer(expectedState) {
7445
7094
  const server = createServer((req, res) => {
7446
7095
  try {
7447
7096
  const url = new URL(req.url || "", "http://localhost");
7448
- if (url.pathname !== CALLBACK_PATH) {
7097
+ if (url.pathname !== CALLBACK_PATH$1) {
7449
7098
  res.writeHead(404, { "Content-Type": "text/html; charset=utf-8" });
7450
7099
  res.end(oauthErrorHtml("Callback route not found."));
7451
7100
  return;
@@ -7482,7 +7131,7 @@ async function startCallbackServer(expectedState) {
7482
7131
  server.on("error", (err) => {
7483
7132
  reject(err);
7484
7133
  });
7485
- server.listen(CALLBACK_PORT, CALLBACK_HOST$1, () => {
7134
+ server.listen(CALLBACK_PORT, CALLBACK_HOST$2, () => {
7486
7135
  resolve2({
7487
7136
  server,
7488
7137
  redirectUri: REDIRECT_URI$1,
@@ -7536,7 +7185,7 @@ async function exchangeAuthorizationCode$1(code, state, verifier, redirectUri) {
7536
7185
  }
7537
7186
  async function loginAnthropic(options) {
7538
7187
  const { verifier, challenge } = await generatePKCE();
7539
- const server = await startCallbackServer(verifier);
7188
+ const server = await startCallbackServer$1(verifier);
7540
7189
  let code;
7541
7190
  let state;
7542
7191
  let redirectUriForExchange = REDIRECT_URI$1;
@@ -34611,7 +34260,7 @@ function getGitHubCopilotBaseUrl(token, enterpriseDomain) {
34611
34260
  if (enterpriseDomain) return `https://copilot-api.${enterpriseDomain}`;
34612
34261
  return "https://api.individual.githubcopilot.com";
34613
34262
  }
34614
- async function fetchJson(url, init) {
34263
+ async function fetchJson$1(url, init) {
34615
34264
  const response = await fetch(url, init);
34616
34265
  if (!response.ok) {
34617
34266
  const text = await response.text();
@@ -34620,7 +34269,7 @@ async function fetchJson(url, init) {
34620
34269
  return response.json();
34621
34270
  }
34622
34271
  async function startDeviceFlow(domain) {
34623
- const data = await fetchJson(getUrls(domain).deviceCodeUrl, {
34272
+ const data = await fetchJson$1(getUrls(domain).deviceCodeUrl, {
34624
34273
  method: "POST",
34625
34274
  headers: {
34626
34275
  Accept: "application/json",
@@ -34670,7 +34319,7 @@ async function pollForGitHubAccessToken(domain, deviceCode, intervalSeconds, exp
34670
34319
  if (signal?.aborted) throw new Error("Login cancelled");
34671
34320
  const remainingMs = deadline - Date.now();
34672
34321
  await abortableSleep(Math.min(Math.ceil(intervalMs * intervalMultiplier), remainingMs), signal);
34673
- const raw = await fetchJson(urls.accessTokenUrl, {
34322
+ const raw = await fetchJson$1(urls.accessTokenUrl, {
34674
34323
  method: "POST",
34675
34324
  headers: {
34676
34325
  Accept: "application/json",
@@ -34701,7 +34350,7 @@ async function pollForGitHubAccessToken(domain, deviceCode, intervalSeconds, exp
34701
34350
  throw new Error("Device flow timed out");
34702
34351
  }
34703
34352
  async function refreshGitHubCopilotToken(refreshToken, enterpriseDomain) {
34704
- const raw = await fetchJson(getUrls(enterpriseDomain || "github.com").copilotTokenUrl, { headers: {
34353
+ const raw = await fetchJson$1(getUrls(enterpriseDomain || "github.com").copilotTokenUrl, { headers: {
34705
34354
  Accept: "application/json",
34706
34355
  Authorization: `Bearer ${refreshToken}`,
34707
34356
  ...COPILOT_HEADERS
@@ -34801,7 +34450,7 @@ if (typeof process !== "undefined" && (process.versions?.node || process.version
34801
34450
  _http = m;
34802
34451
  });
34803
34452
  }
34804
- var CALLBACK_HOST = process.env.PI_OAUTH_CALLBACK_HOST || "127.0.0.1";
34453
+ var CALLBACK_HOST$1 = process.env.PI_OAUTH_CALLBACK_HOST || "127.0.0.1";
34805
34454
  var CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann";
34806
34455
  var AUTHORIZE_URL = "https://auth.openai.com/oauth/authorize";
34807
34456
  var TOKEN_URL = "https://auth.openai.com/oauth/token";
@@ -34983,7 +34632,7 @@ function startLocalOAuthServer(state) {
34983
34632
  }
34984
34633
  });
34985
34634
  return new Promise((resolve2) => {
34986
- server.listen(1455, CALLBACK_HOST, () => {
34635
+ server.listen(1455, CALLBACK_HOST$1, () => {
34987
34636
  resolve2({
34988
34637
  close: () => server.close(),
34989
34638
  cancelWait: () => {
@@ -35109,9 +34758,652 @@ var oauthProviderRegistry = new Map([
35109
34758
  function getOAuthProvider(id) {
35110
34759
  return oauthProviderRegistry.get(id);
35111
34760
  }
34761
+ function registerOAuthProvider(provider) {
34762
+ oauthProviderRegistry.set(provider.id, provider);
34763
+ }
35112
34764
  function getOAuthProviders() {
35113
34765
  return Array.from(oauthProviderRegistry.values());
35114
34766
  }
34767
+ var CALLBACK_HOST = process.env.PI_OAUTH_CALLBACK_HOST || "127.0.0.1";
34768
+ var CALLBACK_PORT_BASE = Number(process.env.PI_MCP_OAUTH_CALLBACK_PORT || 53700);
34769
+ var CALLBACK_PORT_COUNT = 10;
34770
+ var CALLBACK_PATH = "/callback";
34771
+ var CALLBACK_PORTS = Array.from({ length: CALLBACK_PORT_COUNT }, (_, i) => CALLBACK_PORT_BASE + i);
34772
+ var redirectUriFor = (port) => `http://localhost:${port}${CALLBACK_PATH}`;
34773
+ var ALL_REDIRECT_URIS = CALLBACK_PORTS.map(redirectUriFor);
34774
+ var TOKEN_EXPIRY_BUFFER_MS = 3e5;
34775
+ function validatedHttpsUrl(value, name) {
34776
+ let url;
34777
+ try {
34778
+ url = new URL(value);
34779
+ } catch {
34780
+ throw new Error(`${name} must be an absolute HTTPS URL`);
34781
+ }
34782
+ if (url.protocol !== "https:" || url.username || url.password || url.hash) throw new Error(`${name} must be an absolute HTTPS URL without credentials or a fragment`);
34783
+ return url;
34784
+ }
34785
+ function canonicalResource(url) {
34786
+ if (url.pathname === "/" && !url.search) return url.origin;
34787
+ return `${url.origin}${url.pathname}${url.search}`;
34788
+ }
34789
+ function authorizationServerMetadataUrls(issuer) {
34790
+ const url = validatedHttpsUrl(issuer, "Authorization server issuer");
34791
+ if (url.search) throw new Error("Authorization server issuer must not contain a query string");
34792
+ const path = url.pathname === "/" ? "" : url.pathname.replace(/\/$/, "");
34793
+ return [new URL(`/.well-known/oauth-authorization-server${path}`, url.origin).toString(), new URL(`${path}/.well-known/openid-configuration`, url.origin).toString()];
34794
+ }
34795
+ async function fetchResponse(url, init) {
34796
+ return fetch(url, {
34797
+ ...init,
34798
+ redirect: "error"
34799
+ });
34800
+ }
34801
+ async function fetchJson(url, init) {
34802
+ const res = await fetchResponse(url, init);
34803
+ if (!res.ok) throw new Error(`${init?.method ?? "GET"} ${url} failed: ${res.status}`);
34804
+ return res.json();
34805
+ }
34806
+ function authorizationServerMetadata(value, issuer, requireExactIssuer) {
34807
+ if (!value || typeof value !== "object") throw new Error(`Authorization server metadata for ${issuer} is invalid`);
34808
+ const metadata = value;
34809
+ if (typeof metadata.issuer !== "string") throw new Error(`Authorization server metadata for ${issuer} is missing its issuer`);
34810
+ if (requireExactIssuer) {
34811
+ if (metadata.issuer !== issuer) throw new Error(`Authorization server metadata issuer does not exactly match ${issuer}`);
34812
+ } else {
34813
+ const advertisedIssuer = validatedHttpsUrl(metadata.issuer, "Authorization server metadata issuer");
34814
+ if (advertisedIssuer.origin !== new URL(issuer).origin || advertisedIssuer.search) throw new Error(`Origin authorization server metadata issuer must stay on ${new URL(issuer).origin}`);
34815
+ }
34816
+ if (typeof metadata.authorization_endpoint !== "string" || typeof metadata.token_endpoint !== "string") throw new Error(`Authorization server metadata for ${issuer} is missing required endpoints`);
34817
+ validatedHttpsUrl(metadata.authorization_endpoint, "Authorization endpoint");
34818
+ validatedHttpsUrl(metadata.token_endpoint, "Token endpoint");
34819
+ if (metadata.registration_endpoint) validatedHttpsUrl(metadata.registration_endpoint, "Registration endpoint");
34820
+ return metadata;
34821
+ }
34822
+ async function jsonMetadata(response, url) {
34823
+ if (response.status !== 200) throw new Error(`GET ${url} failed: ${response.status}`);
34824
+ if (response.headers.get("content-type")?.split(";", 1)[0].trim().toLowerCase() !== "application/json") throw new Error(`GET ${url} did not return application/json`);
34825
+ return response.json();
34826
+ }
34827
+ async function discoverAuthorizationServer(issuer, requireExactIssuer) {
34828
+ const candidates = authorizationServerMetadataUrls(issuer);
34829
+ let lastError;
34830
+ for (const candidate of candidates) try {
34831
+ const response = await fetchResponse(candidate);
34832
+ if (response.status === 404) continue;
34833
+ return authorizationServerMetadata(await jsonMetadata(response, candidate), issuer, requireExactIssuer);
34834
+ } catch (error) {
34835
+ lastError = error;
34836
+ }
34837
+ throw new Error(`Could not discover OAuth metadata for ${issuer}. Tried ${candidates.join(", ")}. Last error: ${String(lastError)}`);
34838
+ }
34839
+ function randomState() {
34840
+ const bytes = /* @__PURE__ */ new Uint8Array(32);
34841
+ crypto.getRandomValues(bytes);
34842
+ return btoa(String.fromCharCode(...bytes)).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
34843
+ }
34844
+ function resourceMetadata(value, resource) {
34845
+ if (!value || typeof value !== "object") throw new Error("Protected-resource metadata is invalid");
34846
+ const metadata = value;
34847
+ if (metadata.resource !== resource) throw new Error(`Protected-resource metadata resource does not exactly match ${resource}`);
34848
+ if (!Array.isArray(metadata.authorization_servers) || metadata.authorization_servers.length === 0) throw new Error("Protected-resource metadata has no authorization_servers");
34849
+ for (const issuer of metadata.authorization_servers) {
34850
+ if (typeof issuer !== "string") throw new Error("Protected-resource metadata has an invalid authorization server");
34851
+ validatedHttpsUrl(issuer, "Authorization server issuer");
34852
+ }
34853
+ return metadata;
34854
+ }
34855
+ function resourceMetadataUrl(resource) {
34856
+ const path = resource.pathname === "/" ? "" : resource.pathname;
34857
+ return `${resource.origin}/.well-known/oauth-protected-resource${path}${resource.search}`;
34858
+ }
34859
+ function headerResourceMetadata(value) {
34860
+ const match = value?.match(/(?:^|[,\s])resource_metadata\s*=\s*"((?:[^"\\]|\\.)*)"/i);
34861
+ if (!match) return void 0;
34862
+ return match[1].replace(/\\(.)/g, "$1");
34863
+ }
34864
+ async function tryProtectedResourceMetadata(url) {
34865
+ const resource = validatedHttpsUrl(url, "MCP endpoint");
34866
+ let headerUrl;
34867
+ try {
34868
+ const response2 = await fetchResponse(resource.toString());
34869
+ headerUrl = headerResourceMetadata(response2.headers.get("www-authenticate"));
34870
+ await response2.body?.cancel();
34871
+ } catch {
34872
+ }
34873
+ const candidate = headerUrl ? validatedHttpsUrl(headerUrl, "resource_metadata").toString() : resourceMetadataUrl(resource);
34874
+ const response = await fetchResponse(candidate);
34875
+ if (response.status === 404 && !headerUrl) return void 0;
34876
+ return resourceMetadata(await jsonMetadata(response, candidate), canonicalResource(resource));
34877
+ }
34878
+ async function discover(url) {
34879
+ const protectedResource = await tryProtectedResourceMetadata(url);
34880
+ if (protectedResource) {
34881
+ const issuer2 = protectedResource.authorization_servers[0];
34882
+ return {
34883
+ metadata: await discoverAuthorizationServer(issuer2, true),
34884
+ resource: protectedResource.resource,
34885
+ issuer: issuer2
34886
+ };
34887
+ }
34888
+ const issuer = validatedHttpsUrl(url, "MCP endpoint").origin;
34889
+ return { metadata: await discoverAuthorizationServer(issuer, false) };
34890
+ }
34891
+ async function registerClient(registrationEndpoint, label) {
34892
+ validatedHttpsUrl(registrationEndpoint, "Registration endpoint");
34893
+ const data = await fetchJson(registrationEndpoint, {
34894
+ method: "POST",
34895
+ headers: { "Content-Type": "application/json" },
34896
+ body: JSON.stringify({
34897
+ client_name: label,
34898
+ redirect_uris: ALL_REDIRECT_URIS,
34899
+ grant_types: ["authorization_code", "refresh_token"],
34900
+ response_types: ["code"],
34901
+ token_endpoint_auth_method: "none"
34902
+ })
34903
+ });
34904
+ if (typeof data.client_id !== "string" || !data.client_id) throw new Error(`Dynamic client registration at ${registrationEndpoint} returned no client_id`);
34905
+ return data.client_id;
34906
+ }
34907
+ async function startCallbackServer(label) {
34908
+ const { createServer } = await import("node:http");
34909
+ let settle;
34910
+ const waitPromise = new Promise((resolve2) => {
34911
+ let settled = false;
34912
+ settle = (value) => {
34913
+ if (!settled) {
34914
+ settled = true;
34915
+ resolve2(value);
34916
+ }
34917
+ };
34918
+ });
34919
+ const handler = (req, res) => {
34920
+ const url = new URL(req.url || "", "http://localhost");
34921
+ if (url.pathname !== CALLBACK_PATH) {
34922
+ res.writeHead(404, { "Content-Type": "text/html; charset=utf-8" });
34923
+ res.end(oauthErrorHtml("Callback route not found."));
34924
+ return;
34925
+ }
34926
+ const error = url.searchParams.get("error");
34927
+ const code = url.searchParams.get("code");
34928
+ const state = url.searchParams.get("state");
34929
+ res.writeHead(error || !code ? 400 : 200, { "Content-Type": "text/html; charset=utf-8" });
34930
+ if (error) {
34931
+ res.end(oauthErrorHtml(`${label} authentication failed.`, `Error: ${error}`));
34932
+ settle?.(null);
34933
+ return;
34934
+ }
34935
+ if (!code || !state) {
34936
+ res.end(oauthErrorHtml("Missing code or state parameter."));
34937
+ settle?.(null);
34938
+ return;
34939
+ }
34940
+ res.end(oauthSuccessHtml(`${label} authentication completed. You can close this window.`));
34941
+ settle?.({
34942
+ code,
34943
+ state
34944
+ });
34945
+ };
34946
+ let lastError;
34947
+ for (const port of CALLBACK_PORTS) {
34948
+ const server = createServer(handler);
34949
+ let bindErr;
34950
+ server.on("error", (err) => bindErr?.(err));
34951
+ try {
34952
+ if (await new Promise((resolve2) => {
34953
+ bindErr = () => resolve2(false);
34954
+ server.listen(port, CALLBACK_HOST, () => {
34955
+ bindErr = void 0;
34956
+ resolve2(true);
34957
+ });
34958
+ })) return {
34959
+ server,
34960
+ redirectUri: redirectUriFor(port),
34961
+ cancel: () => settle?.(null),
34962
+ waitForCode: () => waitPromise
34963
+ };
34964
+ lastError = `port ${port} in use`;
34965
+ server.close();
34966
+ } catch (err) {
34967
+ lastError = err;
34968
+ server.close();
34969
+ }
34970
+ }
34971
+ throw new Error(`Could not start the OAuth callback server: ports ${CALLBACK_PORT_BASE}-${CALLBACK_PORT_BASE + CALLBACK_PORT_COUNT - 1} are all in use. Close other login attempts and retry. (${String(lastError)})`);
34972
+ }
34973
+ function parseRedirectInput(input, expectedState) {
34974
+ const value = input.trim();
34975
+ let code;
34976
+ let state;
34977
+ try {
34978
+ const url = new URL(value);
34979
+ code = url.searchParams.get("code") ?? void 0;
34980
+ state = url.searchParams.get("state") ?? void 0;
34981
+ } catch {
34982
+ const params = new URLSearchParams(value);
34983
+ code = params.get("code") ?? value;
34984
+ state = params.get("state") ?? void 0;
34985
+ }
34986
+ if (state && state !== expectedState) throw new Error("OAuth state mismatch");
34987
+ if (!code) throw new Error("Missing authorization code");
34988
+ return {
34989
+ code,
34990
+ state: state ?? expectedState
34991
+ };
34992
+ }
34993
+ async function exchangeToken(tokenEndpoint, params) {
34994
+ validatedHttpsUrl(tokenEndpoint, "Token endpoint");
34995
+ const res = await fetchResponse(tokenEndpoint, {
34996
+ method: "POST",
34997
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
34998
+ body: new URLSearchParams(params).toString()
34999
+ });
35000
+ const text = await res.text();
35001
+ if (!res.ok) throw new Error(`Token request to ${tokenEndpoint} failed: ${res.status}`);
35002
+ let token;
35003
+ try {
35004
+ token = JSON.parse(text);
35005
+ } catch {
35006
+ throw new Error(`Token request to ${tokenEndpoint} returned invalid JSON`);
35007
+ }
35008
+ if (!token || typeof token !== "object" || typeof token.access_token !== "string") throw new Error(`Token request to ${tokenEndpoint} returned no access_token`);
35009
+ const result = token;
35010
+ if (!result.access_token) throw new Error(`Token request to ${tokenEndpoint} returned no access_token`);
35011
+ if (result.refresh_token !== void 0 && typeof result.refresh_token !== "string") throw new Error(`Token request to ${tokenEndpoint} returned an invalid refresh_token`);
35012
+ if (result.expires_in !== void 0 && (typeof result.expires_in !== "number" || !Number.isFinite(result.expires_in))) throw new Error(`Token request to ${tokenEndpoint} returned an invalid expires_in`);
35013
+ return result;
35014
+ }
35015
+ function toCredentials(token, tokenEndpoint, clientId, endpoint, resource, issuer, previousRefresh) {
35016
+ return {
35017
+ access: token.access_token,
35018
+ refresh: token.refresh_token ?? previousRefresh ?? "",
35019
+ expires: token.expires_in ? Date.now() + token.expires_in * 1e3 - TOKEN_EXPIRY_BUFFER_MS : Date.now() + 36e5 - TOKEN_EXPIRY_BUFFER_MS,
35020
+ tokenEndpoint,
35021
+ clientId,
35022
+ endpoint,
35023
+ resource,
35024
+ issuer
35025
+ };
35026
+ }
35027
+ function createMcpOAuthProvider(config) {
35028
+ const label = config.label ?? config.server;
35029
+ async function login(callbacks) {
35030
+ const discovery = await discover(config.url);
35031
+ const { metadata: meta } = discovery;
35032
+ callbacks.onProgress?.(`Discovered ${discovery.issuer ?? meta.issuer}`);
35033
+ let clientId = config.clientId;
35034
+ if (!clientId) {
35035
+ if (!meta.registration_endpoint) throw new Error(`${label} does not support dynamic client registration and no clientId was configured. Set a pre-registered client id for this server.`);
35036
+ callbacks.onProgress?.("Registering OAuth client\u2026");
35037
+ clientId = await registerClient(meta.registration_endpoint, `Prime Agent (${label})`);
35038
+ }
35039
+ const { verifier, challenge } = await generatePKCE();
35040
+ const state = randomState();
35041
+ const scope = config.scopes ?? meta.scopes_supported?.join(" ");
35042
+ const cb = await startCallbackServer(label);
35043
+ try {
35044
+ const authParams = new URLSearchParams({
35045
+ client_id: clientId,
35046
+ response_type: "code",
35047
+ redirect_uri: cb.redirectUri,
35048
+ code_challenge: challenge,
35049
+ code_challenge_method: "S256",
35050
+ state
35051
+ });
35052
+ if (scope) authParams.set("scope", scope);
35053
+ if (discovery.resource) authParams.set("resource", discovery.resource);
35054
+ const authorizationUrl = new URL(meta.authorization_endpoint);
35055
+ for (const [name, value] of authParams) authorizationUrl.searchParams.set(name, value);
35056
+ callbacks.onAuth({
35057
+ url: authorizationUrl.toString(),
35058
+ instructions: "Complete login in your browser. If the browser is on another machine, paste the final redirect URL here."
35059
+ });
35060
+ let result;
35061
+ let manualCancelled = false;
35062
+ let manualError;
35063
+ if (callbacks.onManualCodeInput) {
35064
+ const manual = callbacks.onManualCodeInput().then((input) => {
35065
+ const parsed = parseRedirectInput(input, state);
35066
+ cb.cancel();
35067
+ return parsed;
35068
+ }).catch(async (err) => {
35069
+ if (err instanceof Error && /state mismatch|authorization code/i.test(err.message)) manualError = err;
35070
+ else manualCancelled = true;
35071
+ await new Promise((r) => setTimeout(r, 500));
35072
+ cb.cancel();
35073
+ return null;
35074
+ });
35075
+ result = await cb.waitForCode() ?? await manual;
35076
+ if (!result && manualError) throw manualError;
35077
+ } else {
35078
+ result = await cb.waitForCode();
35079
+ if (!result) result = parseRedirectInput(await callbacks.onPrompt({
35080
+ message: "Paste the authorization code or full redirect URL:",
35081
+ placeholder: cb.redirectUri
35082
+ }), state);
35083
+ }
35084
+ if (!result) throw new Error(manualCancelled ? "Login cancelled" : "Missing authorization code");
35085
+ if (result.state !== state) throw new Error("OAuth state mismatch");
35086
+ callbacks.onProgress?.("Exchanging authorization code for tokens\u2026");
35087
+ return toCredentials(await exchangeToken(meta.token_endpoint, {
35088
+ grant_type: "authorization_code",
35089
+ code: result.code,
35090
+ redirect_uri: cb.redirectUri,
35091
+ client_id: clientId,
35092
+ code_verifier: verifier,
35093
+ ...discovery.resource ? { resource: discovery.resource } : {}
35094
+ }), meta.token_endpoint, clientId, config.url, discovery.resource, discovery.issuer);
35095
+ } finally {
35096
+ cb.server.close();
35097
+ }
35098
+ }
35099
+ async function refreshToken(credentials) {
35100
+ const creds = credentials;
35101
+ if (creds.endpoint !== config.url) throw new Error(`Stored OAuth credentials are not bound to ${config.url}; re-run /mcp login ${config.server}`);
35102
+ const configuredResource = canonicalResource(validatedHttpsUrl(config.url, "MCP endpoint"));
35103
+ if (creds.resource !== void 0 && creds.resource !== configuredResource) throw new Error(`Stored OAuth credentials are not bound to ${configuredResource}; re-run /mcp login ${config.server}`);
35104
+ if (creds.resource === void 0 !== (creds.issuer === void 0)) throw new Error(`Stored OAuth credentials for ${label} have incomplete resource binding; re-run /mcp login ${config.server}`);
35105
+ if (creds.issuer !== void 0) validatedHttpsUrl(creds.issuer, "Stored authorization server issuer");
35106
+ if (!creds.refresh) throw new Error(`No refresh token stored for ${label}; re-run /mcp login ${config.server}`);
35107
+ const discovery = await discover(config.url);
35108
+ if (creds.resource === void 0 !== (discovery.resource === void 0)) throw new Error(`OAuth discovery mode changed for ${config.url}; re-run /mcp login ${config.server}`);
35109
+ if (creds.resource) {
35110
+ if (discovery.resource !== creds.resource || discovery.issuer !== creds.issuer) throw new Error(`Stored OAuth credentials do not match current protected-resource metadata for ${config.url}`);
35111
+ }
35112
+ const tokenEndpoint = creds.tokenEndpoint ?? discovery.metadata.token_endpoint;
35113
+ if (creds.tokenEndpoint && discovery.metadata.token_endpoint !== creds.tokenEndpoint) throw new Error(`Stored OAuth token endpoint does not match current authorization-server metadata for ${config.url}`);
35114
+ const clientId = creds.clientId ?? config.clientId;
35115
+ if (!tokenEndpoint) throw new Error(`No token endpoint stored for ${label}; re-run /mcp login ${config.server}`);
35116
+ return toCredentials(await exchangeToken(tokenEndpoint, {
35117
+ grant_type: "refresh_token",
35118
+ refresh_token: creds.refresh,
35119
+ ...clientId ? { client_id: clientId } : {},
35120
+ ...creds.resource ? { resource: creds.resource } : {}
35121
+ }), tokenEndpoint, clientId ?? "", creds.endpoint, creds.resource, creds.issuer, creds.refresh);
35122
+ }
35123
+ return {
35124
+ id: `mcp:${config.server}`,
35125
+ name: label,
35126
+ usesCallbackServer: true,
35127
+ login,
35128
+ refreshToken,
35129
+ getApiKey: (credentials) => credentials.access
35130
+ };
35131
+ }
35132
+ var BUILTIN_MCP_CATALOG = [{
35133
+ server: "linear",
35134
+ label: "Linear",
35135
+ url: "https://mcp.linear.app/mcp",
35136
+ oauth: {
35137
+ kind: "oauth",
35138
+ label: "Linear"
35139
+ }
35140
+ }, {
35141
+ server: "notion",
35142
+ label: "Notion",
35143
+ url: "https://mcp.notion.com/mcp",
35144
+ oauth: {
35145
+ kind: "oauth",
35146
+ label: "Notion"
35147
+ }
35148
+ }];
35149
+ function getCatalogEntry(server) {
35150
+ return BUILTIN_MCP_CATALOG.find((entry) => entry.server === server);
35151
+ }
35152
+ function registerBuiltinMcpOAuthProviders() {
35153
+ for (const entry of BUILTIN_MCP_CATALOG) {
35154
+ if (entry.oauth?.kind !== "oauth") continue;
35155
+ if (getOAuthProvider(`mcp:${entry.server}`)) continue;
35156
+ registerOAuthProvider(createMcpOAuthProvider({
35157
+ server: entry.server,
35158
+ label: entry.label,
35159
+ url: entry.url,
35160
+ scopes: entry.oauth.scopes,
35161
+ clientId: entry.oauth.clientId
35162
+ }));
35163
+ }
35164
+ }
35165
+ var MCP_AUTH_PREFIX = "mcp:";
35166
+ function mcpProviderId(name) {
35167
+ return `${MCP_AUTH_PREFIX}${name}`;
35168
+ }
35169
+ var McpRequestError = class extends Error {
35170
+ status = 400;
35171
+ constructor(message) {
35172
+ super(message);
35173
+ this.name = "McpRequestError";
35174
+ }
35175
+ };
35176
+ function validateHttpMcpUrl(value) {
35177
+ let url;
35178
+ try {
35179
+ url = new URL(value);
35180
+ } catch {
35181
+ throw new McpRequestError("Invalid MCP URL.");
35182
+ }
35183
+ if (url.protocol !== "http:" && url.protocol !== "https:" || !url.hostname || url.username || url.password) throw new McpRequestError("MCP URL must be an http(s) URL without embedded credentials.");
35184
+ return url.toString();
35185
+ }
35186
+ function stdioCommandPreview(config) {
35187
+ return [config.command, ...config.args ?? []].join(" ");
35188
+ }
35189
+ function mcpEnvBindings(config) {
35190
+ if (config.type !== "stdio" || !config.env) return void 0;
35191
+ const bindings = Object.entries(config.env).map(([child, mapping]) => ({
35192
+ child,
35193
+ source: mapping.env
35194
+ }));
35195
+ return bindings.length > 0 ? bindings : void 0;
35196
+ }
35197
+ function isMcpAuthed(server, auth, env) {
35198
+ if (server.config.enabled === false) return false;
35199
+ if (server.userDeclared && getCatalogEntry(server.name)) return false;
35200
+ if (server.config.type === "stdio") return true;
35201
+ const usesOAuth = server.config.type === "http" && server.config.oauth === true;
35202
+ const bearerTokenEnvVar = server.config.type === "http" ? server.config.bearerTokenEnvVar : void 0;
35203
+ if (!usesOAuth && !bearerTokenEnvVar) return true;
35204
+ if (bearerTokenEnvVar && env[bearerTokenEnvVar]?.trim()) return true;
35205
+ const cred = auth.get(mcpProviderId(server.name));
35206
+ if (cred === void 0) return false;
35207
+ if (!server.userDeclared) return true;
35208
+ const endpoint = cred.endpoint;
35209
+ return typeof endpoint === "string" && server.config.type === "http" && endpoint === server.config.url;
35210
+ }
35211
+ function mcpConnectionStatus(server, authed) {
35212
+ if (server.config.enabled === false) return "disabled";
35213
+ if (authed) return server.config.type === "http" && server.config.oauth !== true && !server.config.bearerTokenEnvVar ? "anonymous" : "connected";
35214
+ return "needs_auth";
35215
+ }
35216
+ function toMcpConnectionInfo(server, auth, env) {
35217
+ const usesOAuth = server.config.type === "http" && server.config.oauth === true;
35218
+ const catalogShadow = server.userDeclared && Boolean(getCatalogEntry(server.name));
35219
+ const authed = isMcpAuthed(server, auth, env);
35220
+ const envBindings = mcpEnvBindings(server.config);
35221
+ return {
35222
+ name: server.name,
35223
+ label: server.label,
35224
+ source: server.source,
35225
+ transport: server.config.type,
35226
+ usesOAuth,
35227
+ enabled: authed,
35228
+ status: mcpConnectionStatus(server, authed),
35229
+ ...server.config.type === "http" ? { url: server.config.url } : {},
35230
+ ...server.config.type === "stdio" ? { commandPreview: stdioCommandPreview(server.config) } : {},
35231
+ ...server.config.type === "stdio" && server.config.cwd ? { cwdPreview: safePathLabel(server.config.cwd) } : {},
35232
+ ...server.config.type === "http" && server.config.bearerTokenEnvVar ? { bearerTokenEnvVar: server.config.bearerTokenEnvVar } : {},
35233
+ ...envBindings ? { envBindings } : {},
35234
+ ...catalogShadow ? { error: "This name is reserved for a built-in integration." } : {}
35235
+ };
35236
+ }
35237
+ function listMcpServers(userServers) {
35238
+ const listed = [];
35239
+ for (const entry of BUILTIN_MCP_CATALOG) listed.push({
35240
+ name: entry.server,
35241
+ label: entry.label,
35242
+ source: "builtin",
35243
+ userDeclared: false,
35244
+ config: {
35245
+ type: "http",
35246
+ url: entry.url,
35247
+ oauth: true
35248
+ }
35249
+ });
35250
+ for (const [name, config] of Object.entries(userServers ?? {}).sort(([left], [right]) => left.localeCompare(right))) listed.push({
35251
+ name,
35252
+ label: name,
35253
+ source: "user",
35254
+ userDeclared: true,
35255
+ config
35256
+ });
35257
+ return listed;
35258
+ }
35259
+ function listMcpConnections(userServers, auth, env = process.env) {
35260
+ return listMcpServers(userServers).map((server) => toMcpConnectionInfo(server, auth, env));
35261
+ }
35262
+ function dropMcpServerCredentials(name, auth) {
35263
+ if (getCatalogEntry(name)) return;
35264
+ try {
35265
+ auth.removeVerified(mcpProviderId(name));
35266
+ } catch (error) {
35267
+ throw new McpRequestError(`Could not remove stored credentials for this MCP server: ${error instanceof Error ? error.message : String(error)}`);
35268
+ }
35269
+ }
35270
+ async function confineMcpStdioCwd(cwd, workspaceRoot) {
35271
+ if (cwd === void 0 || cwd.trim() === "") return void 0;
35272
+ const root2 = resolve(workspaceRoot);
35273
+ const canonicalRoot = await realpath(root2).catch(() => root2);
35274
+ const candidate = resolve(root2, cwd);
35275
+ const existingCandidate = await realpath(candidate).catch(() => void 0);
35276
+ if (existingCandidate && existingCandidate !== canonicalRoot && !existingCandidate.startsWith(`${canonicalRoot}${sep}`)) throw new McpRequestError("MCP stdio working directory must stay inside the workspace.");
35277
+ let ancestor = dirname(candidate);
35278
+ while (true) {
35279
+ const resolvedAncestor = await realpath(ancestor).catch(() => void 0);
35280
+ if (resolvedAncestor) {
35281
+ if (resolvedAncestor !== canonicalRoot && !resolvedAncestor.startsWith(`${canonicalRoot}${sep}`)) throw new McpRequestError("MCP stdio working directory must stay inside the workspace.");
35282
+ break;
35283
+ }
35284
+ const parent = dirname(ancestor);
35285
+ if (parent === ancestor) throw new McpRequestError("MCP stdio working directory must stay inside the workspace.");
35286
+ ancestor = parent;
35287
+ }
35288
+ return candidate;
35289
+ }
35290
+ function storedApiForCustomProvider(api) {
35291
+ return api === "google-genai" ? "google-generative-ai" : api;
35292
+ }
35293
+ function uiApiForCustomProvider(value) {
35294
+ if (value === "google-generative-ai") return "google-genai";
35295
+ return isPiCustomProviderApi(value) ? value : void 0;
35296
+ }
35297
+ function envVarNameForManagedProvider(providerId) {
35298
+ if (providerId === "openai-chat-completions") return "OPENAI_CHAT_COMPLETIONS_API_KEY";
35299
+ const slug = providerId.slice(providerId.indexOf("+") + 1).toUpperCase().replace(/[^A-Z0-9]+/g, "_");
35300
+ return isOccProviderId(providerId) ? `OPENAI_CHAT_COMPLETIONS_${slug}_API_KEY` : `CUSTOM_${slug}_API_KEY`;
35301
+ }
35302
+ function readModelsJson(filePath) {
35303
+ try {
35304
+ if (!existsSync(filePath)) return {};
35305
+ return parseModelsJson(readFileSync(filePath, "utf-8"));
35306
+ } catch {
35307
+ return {};
35308
+ }
35309
+ }
35310
+ function stripJsonComments(input) {
35311
+ return input.replace(/"(?:\\.|[^"\\])*"|\/\/[^\n]*/g, (match) => match[0] === '"' ? match : "").replace(/"(?:\\.|[^"\\])*"|,(\s*[}\]])/g, (match, tail) => tail ?? (match[0] === '"' ? match : ""));
35312
+ }
35313
+ function parseModelsJson(raw) {
35314
+ const parsed = JSON.parse(stripJsonComments(raw));
35315
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("models.json must contain an object");
35316
+ return parsed;
35317
+ }
35318
+ function readModelsJsonForWrite(filePath) {
35319
+ if (!existsSync(filePath)) return {};
35320
+ try {
35321
+ return parseModelsJson(readFileSync(filePath, "utf-8"));
35322
+ } catch (error) {
35323
+ throw new Error(`Refusing to update models.json because it could not be parsed: ${error instanceof Error ? error.message : error}`);
35324
+ }
35325
+ }
35326
+ function mergeModelDefinitions(existing, incoming) {
35327
+ const existingById = new Map((existing ?? []).map((model) => [model.id, model]));
35328
+ const seen = /* @__PURE__ */ new Set();
35329
+ return incoming.flatMap((model) => {
35330
+ if (seen.has(model.id)) return [];
35331
+ seen.add(model.id);
35332
+ return [{
35333
+ ...existingById.get(model.id),
35334
+ ...model
35335
+ }];
35336
+ });
35337
+ }
35338
+ function listCustomProviders(filePath) {
35339
+ return readModelsJson(filePath).providers ?? {};
35340
+ }
35341
+ function writeModelsJson(filePath, data) {
35342
+ mkdirSync(dirname(filePath), {
35343
+ recursive: true,
35344
+ mode: 448
35345
+ });
35346
+ const serialized = `${JSON.stringify(data, null, " ")}
35347
+ `;
35348
+ const tmpPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
35349
+ writeFileSync(tmpPath, serialized, "utf-8");
35350
+ renameSync(tmpPath, filePath);
35351
+ }
35352
+ function upsertCustomProvider(filePath, providerId, input) {
35353
+ const data = readModelsJsonForWrite(filePath);
35354
+ const providers = { ...data.providers ?? {} };
35355
+ const existing = providers[providerId] ?? {};
35356
+ providers[providerId] = {
35357
+ ...existing,
35358
+ name: input.name ?? existing.name,
35359
+ baseUrl: input.baseUrl,
35360
+ api: storedApiForCustomProvider(input.api),
35361
+ apiKey: input.apiKey,
35362
+ models: mergeModelDefinitions(existing.models, input.models)
35363
+ };
35364
+ writeModelsJson(filePath, {
35365
+ ...data,
35366
+ providers
35367
+ });
35368
+ }
35369
+ function addCustomProviderModelIds(filePath, providerId, modelIds) {
35370
+ const data = readModelsJsonForWrite(filePath);
35371
+ const providers = { ...data.providers ?? {} };
35372
+ const existing = providers[providerId];
35373
+ if (!existing) return;
35374
+ providers[providerId] = {
35375
+ ...existing,
35376
+ models: mergeModelDefinitions(existing.models, [...existing.models ?? [], ...modelIds.map((id) => ({ id }))])
35377
+ };
35378
+ writeModelsJson(filePath, {
35379
+ ...data,
35380
+ providers
35381
+ });
35382
+ }
35383
+ function removeCustomProvider(filePath, providerId) {
35384
+ const data = readModelsJsonForWrite(filePath);
35385
+ const providers = data.providers;
35386
+ if (!providers || !(providerId in providers)) return;
35387
+ const next = { ...providers };
35388
+ delete next[providerId];
35389
+ writeModelsJson(filePath, {
35390
+ ...data,
35391
+ providers: next
35392
+ });
35393
+ }
35394
+ function isDiscoverableEntry(entry) {
35395
+ const baseUrl = entry?.baseUrl;
35396
+ if (!baseUrl) return false;
35397
+ const api = uiApiForCustomProvider(entry?.api);
35398
+ if (api && !isOccFamilyApi(api)) return false;
35399
+ if (entry?.api && !api) return false;
35400
+ try {
35401
+ const parsed = new URL(baseUrl);
35402
+ return parsed.protocol === "https:" || parsed.protocol === "http:";
35403
+ } catch {
35404
+ return false;
35405
+ }
35406
+ }
35115
35407
  var PRIME_PROVIDER_ENV_MAP = {
35116
35408
  openai: "OPENAI_API_KEY",
35117
35409
  "azure-openai-responses": "AZURE_OPENAI_API_KEY",
@@ -35448,7 +35740,7 @@ function cancelOAuthLogin(loginId) {
35448
35740
  error: "Login cancelled"
35449
35741
  };
35450
35742
  }
35451
- function oauthDeps() {
35743
+ function oauthDeps$1() {
35452
35744
  const config = getPrimeConfig();
35453
35745
  return {
35454
35746
  login: (providerId, callbacks) => config.authStorage.login(providerId, callbacks),
@@ -35475,7 +35767,422 @@ function handleChatProvidersOAuthPost(request) {
35475
35767
  status: "error",
35476
35768
  error: `Unknown OAuth provider: ${body.providerId}`
35477
35769
  }, { status: 400 });
35478
- return Response.json(startOAuthLogin(body.providerId, oauthDeps()));
35770
+ return Response.json(startOAuthLogin(body.providerId, oauthDeps$1()));
35771
+ }, request);
35772
+ }
35773
+ function defaultMcpDeps() {
35774
+ const config = getPrimeConfig();
35775
+ const settings = config.defaultSettings;
35776
+ return {
35777
+ getUserServers: () => settings.getGlobalMcpServers(),
35778
+ setUserServer: (name, serverConfig, force) => {
35779
+ settings.setGlobalMcpServer(name, serverConfig, force);
35780
+ },
35781
+ removeUserServer: (name) => settings.removeGlobalMcpServer(name),
35782
+ flushSettings: async () => {
35783
+ await settings.flush();
35784
+ const error = settings.drainErrors("global")[0];
35785
+ if (error) throw error.error;
35786
+ },
35787
+ auth: config.authStorage,
35788
+ workspaceRoot: config.defaultCwd,
35789
+ env: process.env,
35790
+ reloadAuth: () => {
35791
+ config.reloadAuth();
35792
+ },
35793
+ reloadResources: async () => {
35794
+ await getBridge().reloadResources();
35795
+ }
35796
+ };
35797
+ }
35798
+ function listedConnections(deps) {
35799
+ return listMcpConnections(deps.getUserServers(), deps.auth, deps.env);
35800
+ }
35801
+ function listResponse(deps) {
35802
+ return { connections: listedConnections(deps) };
35803
+ }
35804
+ function toMcpOAuthResponse(snapshot2, connections) {
35805
+ return {
35806
+ status: snapshot2.status,
35807
+ ...snapshot2.loginId ? { loginId: snapshot2.loginId } : {},
35808
+ ...snapshot2.authUrl ? { authUrl: snapshot2.authUrl } : {},
35809
+ ...snapshot2.userCode ? { userCode: snapshot2.userCode } : {},
35810
+ ...snapshot2.instructions ? { instructions: snapshot2.instructions } : {},
35811
+ ...snapshot2.prompt ? { prompt: snapshot2.prompt } : {},
35812
+ ...snapshot2.error ? { error: snapshot2.error } : {},
35813
+ ...connections ? { connections } : {}
35814
+ };
35815
+ }
35816
+ function ensureMcpOAuthProvider(name, deps) {
35817
+ registerBuiltinMcpOAuthProviders();
35818
+ if (getCatalogEntry(name)) return;
35819
+ const config = deps.getUserServers()?.[name];
35820
+ if (!config || config.type !== "http" || config.oauth !== true) throw new McpRequestError("This MCP server does not use OAuth.");
35821
+ registerOAuthProvider(createMcpOAuthProvider({
35822
+ server: name,
35823
+ label: name,
35824
+ url: config.url
35825
+ }));
35826
+ }
35827
+ function oauthDeps(deps) {
35828
+ return {
35829
+ login: (providerId, callbacks) => deps.auth.login(providerId, callbacks),
35830
+ reloadAuth: () => {
35831
+ deps.reloadAuth();
35832
+ deps.reloadResources();
35833
+ },
35834
+ listProviders: () => []
35835
+ };
35836
+ }
35837
+ async function logoutMcp(name, deps) {
35838
+ try {
35839
+ deps.auth.removeVerified(mcpProviderId(name));
35840
+ } catch (error) {
35841
+ throw new McpRequestError(`Could not remove stored credentials: ${error instanceof Error ? error.message : String(error)}`);
35842
+ }
35843
+ deps.reloadAuth();
35844
+ await deps.reloadResources();
35845
+ return {
35846
+ status: "success",
35847
+ connections: listedConnections(deps)
35848
+ };
35849
+ }
35850
+ function handleChatMcpGet(_request, deps = defaultMcpDeps()) {
35851
+ return wrapApiHandler(async () => Response.json(listResponse(deps)), _request);
35852
+ }
35853
+ function handleChatMcpPost(request, deps = defaultMcpDeps()) {
35854
+ return wrapApiHandler(async () => {
35855
+ const body = ChatMcpUpsertRequestSchema.parse(await request.json().catch(() => ({})));
35856
+ if (getCatalogEntry(body.name)) throw new McpRequestError(`MCP server name "${body.name}" is reserved for a built-in integration.`);
35857
+ if (deps.getUserServers()?.[body.name] && body.force !== true) throw new McpRequestError(`MCP server "${body.name}" already exists. Replace it to continue.`);
35858
+ let config;
35859
+ switch (body.transport) {
35860
+ case "http":
35861
+ if (body.bearerTokenEnvVar && body.oauth) throw new McpRequestError("OAuth and a bearer-token environment variable cannot be combined.");
35862
+ config = {
35863
+ type: "http",
35864
+ url: validateHttpMcpUrl(body.url),
35865
+ ...body.bearerTokenEnvVar ? { bearerTokenEnvVar: body.bearerTokenEnvVar } : {},
35866
+ ...body.oauth ? { oauth: true } : {}
35867
+ };
35868
+ break;
35869
+ case "stdio": {
35870
+ if (body.command.includes("\0") || body.args?.some((part) => part.includes("\0"))) throw new McpRequestError("MCP command arguments cannot contain NUL.");
35871
+ const env = Object.fromEntries((body.env ?? []).map((binding) => [binding.child, { env: binding.source }]));
35872
+ const cwd = await confineMcpStdioCwd(body.cwd, deps.workspaceRoot);
35873
+ config = {
35874
+ type: "stdio",
35875
+ command: body.command,
35876
+ ...body.args && body.args.length > 0 ? { args: body.args } : {},
35877
+ ...cwd ? { cwd } : {},
35878
+ ...Object.keys(env).length > 0 ? { env } : {}
35879
+ };
35880
+ break;
35881
+ }
35882
+ default:
35883
+ throw new McpRequestError(`Unsupported MCP transport: ${String(body)}`);
35884
+ }
35885
+ dropMcpServerCredentials(body.name, deps.auth);
35886
+ deps.setUserServer(body.name, config, true);
35887
+ await deps.flushSettings();
35888
+ deps.reloadAuth();
35889
+ await deps.reloadResources();
35890
+ return Response.json(listResponse(deps));
35891
+ }, request);
35892
+ }
35893
+ function handleChatMcpDelete(request, deps = defaultMcpDeps()) {
35894
+ return wrapApiHandler(async () => {
35895
+ const body = ChatMcpDeleteRequestSchema.parse(await request.json().catch(() => ({})));
35896
+ if (!deps.removeUserServer(body.name)) throw new McpRequestError(`MCP server "${body.name}" was not found.`);
35897
+ await deps.flushSettings();
35898
+ dropMcpServerCredentials(body.name, deps.auth);
35899
+ deps.reloadAuth();
35900
+ await deps.reloadResources();
35901
+ return Response.json(listResponse(deps));
35902
+ }, request);
35903
+ }
35904
+ function handleChatMcpOAuthPost(request, deps = defaultMcpDeps()) {
35905
+ return wrapApiHandler(async () => {
35906
+ const body = ChatMcpOAuthLoginRequestSchema.parse(await request.json().catch(() => ({})));
35907
+ if (![...BUILTIN_MCP_CATALOG.map((entry) => entry.server), ...Object.keys(deps.getUserServers() ?? {})].includes(body.name) && !body.loginId) throw new McpRequestError(`Unknown MCP server: ${body.name}`);
35908
+ if (body.cancel) {
35909
+ if (!body.loginId) return Response.json({
35910
+ status: "error",
35911
+ error: "loginId is required to cancel"
35912
+ }, { status: 400 });
35913
+ return Response.json(toMcpOAuthResponse(cancelOAuthLogin(body.loginId)));
35914
+ }
35915
+ if (body.loginId && body.promptAnswer !== void 0) return Response.json(toMcpOAuthResponse(continueOAuthLogin(body.loginId, body.promptAnswer)));
35916
+ if (body.loginId) {
35917
+ const snapshot2 = pollOAuthLogin(body.loginId);
35918
+ return Response.json(toMcpOAuthResponse(snapshot2, snapshot2.status === "success" ? listedConnections(deps) : void 0));
35919
+ }
35920
+ const action = body.action ?? "login";
35921
+ switch (action) {
35922
+ case "logout":
35923
+ return Response.json(await logoutMcp(body.name, deps));
35924
+ case "reconnect":
35925
+ await logoutMcp(body.name, deps);
35926
+ break;
35927
+ case "login":
35928
+ break;
35929
+ default:
35930
+ throw new McpRequestError(`Unsupported MCP OAuth action: ${String(action)}`);
35931
+ }
35932
+ ensureMcpOAuthProvider(body.name, deps);
35933
+ const providerId = mcpProviderId(body.name);
35934
+ if (!getOAuthProvider(providerId)) return Response.json({
35935
+ status: "error",
35936
+ error: `Unknown OAuth provider: ${providerId}`
35937
+ }, { status: 400 });
35938
+ return Response.json(toMcpOAuthResponse(startOAuthLogin(providerId, oauthDeps(deps))));
35939
+ }, request);
35940
+ }
35941
+ var BodySchema$1 = external_exports.object({
35942
+ sessionId: SessionIdSchema,
35943
+ model: external_exports.object({
35944
+ provider: external_exports.string(),
35945
+ id: external_exports.string()
35946
+ })
35947
+ });
35948
+ function handleChatModelPost(request) {
35949
+ return wrapApiHandler(async () => {
35950
+ const raw = await request.json().catch(() => ({}));
35951
+ const body = BodySchema$1.parse(raw);
35952
+ const bridge = getBridge();
35953
+ const session = bridge.getSession(body.sessionId) ?? await bridge.resumeSessionById(body.sessionId);
35954
+ if (!session || !await requireProjectSession(session)) return Response.json({ message: `Unknown session: ${body.sessionId}` }, { status: 404 });
35955
+ await bridge.setModel(body.sessionId, {
35956
+ provider: body.model.provider,
35957
+ id: body.model.id
35958
+ });
35959
+ return Response.json({ ok: true });
35960
+ }, request);
35961
+ }
35962
+ function toPatternCandidate(model) {
35963
+ return {
35964
+ id: model.id,
35965
+ name: model.name,
35966
+ provider: model.provider,
35967
+ modelId: model.id,
35968
+ key: `${model.provider}/${model.id}`
35969
+ };
35970
+ }
35971
+ function handleChatModelsGet(request) {
35972
+ return wrapApiHandler(async () => {
35973
+ const config = getPrimeConfig();
35974
+ const cwd = await cwdForRequest(request);
35975
+ const settings = config.settingsFor(cwd);
35976
+ const registry = config.modelRegistry;
35977
+ const scope = new URL(request.url).searchParams.get("scope") === "all" ? "all" : "enabled";
35978
+ let models = registry.getAll();
35979
+ if (scope === "enabled") {
35980
+ models = models.filter((model) => registry.hasConfiguredAuth(model));
35981
+ const patterns = settings.getEnabledModels();
35982
+ if (patterns !== void 0) models = models.filter((model) => isModelPatternEnabled(toPatternCandidate(model), patterns));
35983
+ }
35984
+ const diagnostics = [];
35985
+ const defaultProvider = settings.getDefaultProvider();
35986
+ const defaultModel = settings.getDefaultModel();
35987
+ const defaultThinkingLevel = settings.getDefaultThinkingLevel();
35988
+ const selectedModelKey = defaultProvider && defaultModel ? `${defaultProvider}/${defaultModel}` : void 0;
35989
+ return Response.json({
35990
+ models: models.map((m) => {
35991
+ const thinkingLevels = getSupportedThinkingLevels(m);
35992
+ const fallback = m.reasoning ? "medium" : "off";
35993
+ return {
35994
+ key: `${m.provider}/${m.id}`,
35995
+ provider: m.provider,
35996
+ id: m.id,
35997
+ name: m.name,
35998
+ reasoning: m.reasoning,
35999
+ input: m.input,
36000
+ contextWindow: m.contextWindow,
36001
+ maxTokens: m.maxTokens,
36002
+ available: registry.hasConfiguredAuth(m),
36003
+ thinkingLevels,
36004
+ defaultThinkingLevel: thinkingLevels.includes(fallback) ? fallback : thinkingLevels[0] ?? "off"
36005
+ };
36006
+ }),
36007
+ ...selectedModelKey ? { selectedModelKey } : {},
36008
+ ...defaultProvider ? { defaultProvider } : {},
36009
+ ...defaultModel ? { defaultModel } : {},
36010
+ ...defaultThinkingLevel ? { defaultThinkingLevel } : {},
36011
+ diagnostics
36012
+ });
36013
+ }, request);
36014
+ }
36015
+ function openAiModelsUrl(baseUrl) {
36016
+ const parsed = new URL(baseUrl);
36017
+ if (parsed.protocol !== "https:" && parsed.protocol !== "http:") throw new Error("model discovery requires an http(s) URL");
36018
+ if (parsed.protocol === "http:" && !isLoopbackHostname(parsed.hostname)) throw new Error("model discovery requires https for non-loopback hosts");
36019
+ const path = parsed.pathname.replace(/\/+$/, "");
36020
+ parsed.pathname = path.endsWith("/v1") ? `${path}/models` : `${path}/v1/models`;
36021
+ parsed.search = "";
36022
+ parsed.hash = "";
36023
+ return parsed;
36024
+ }
36025
+ function handleChatModelsDiscoverPost(request) {
36026
+ return wrapApiHandler(async () => {
36027
+ const raw = await request.json().catch(() => ({}));
36028
+ const body = ChatModelsDiscoverRequestSchema.parse(raw);
36029
+ const config = getPrimeConfig();
36030
+ const apiKey = await config.modelRegistry.getApiKeyForProvider(body.providerId);
36031
+ if (!apiKey) return Response.json({
36032
+ providerId: body.providerId,
36033
+ models: []
36034
+ });
36035
+ const provider = body.providerId;
36036
+ const entry = listCustomProviders(`${config.agentDir}/models.json`)[provider];
36037
+ const api = uiApiForCustomProvider(entry?.api);
36038
+ if (entry?.api && !api || api && !isOccFamilyApi(api)) return Response.json({
36039
+ providerId: provider,
36040
+ models: []
36041
+ });
36042
+ const baseUrl = entry?.baseUrl;
36043
+ if (!baseUrl) return Response.json({
36044
+ providerId: provider,
36045
+ models: []
36046
+ });
36047
+ try {
36048
+ const modelsUrl = openAiModelsUrl(baseUrl);
36049
+ const response = await fetch(modelsUrl, {
36050
+ headers: { Authorization: `Bearer ${apiKey}` },
36051
+ redirect: "error",
36052
+ signal: AbortSignal.timeout(1e4)
36053
+ });
36054
+ if (!response.ok) return Response.json({
36055
+ providerId: provider,
36056
+ models: []
36057
+ });
36058
+ const models = ((await response.json()).data ?? []).map((m) => ({
36059
+ key: `${provider}/${m.id}`,
36060
+ provider,
36061
+ id: m.id,
36062
+ name: m.id,
36063
+ reasoning: false,
36064
+ input: ["text"],
36065
+ available: true,
36066
+ defaultThinkingLevel: "off",
36067
+ thinkingLevels: ["off"]
36068
+ }));
36069
+ if (models.length > 0) {
36070
+ addCustomProviderModelIds(`${config.agentDir}/models.json`, provider, models.map((model) => model.id));
36071
+ config.reloadAuth();
36072
+ }
36073
+ return Response.json({
36074
+ providerId: provider,
36075
+ models
36076
+ });
36077
+ } catch {
36078
+ return Response.json({
36079
+ providerId: provider,
36080
+ models: []
36081
+ });
36082
+ }
36083
+ }, request);
36084
+ }
36085
+ function toThinkingLevel(level) {
36086
+ return level;
36087
+ }
36088
+ function handleChatNewPost(request) {
36089
+ return wrapApiHandler(async () => {
36090
+ const bridge = getBridge();
36091
+ const registry = getPrimeConfig().projectRegistry;
36092
+ const raw = await request.json().catch(() => ({}));
36093
+ const body = ChatNewRequestSchema.parse(raw);
36094
+ const projectId = body.projectId ?? await registry.projectIdForCwd(getPrimeConfig().defaultCwd) ?? (await registry.register(getPrimeConfig().defaultCwd)).projectId;
36095
+ const project = await registry.get(projectId);
36096
+ bridge.ensureKernelReady(project.canonicalPath).catch(() => {
36097
+ });
36098
+ const session = await bridge.createSession({
36099
+ cwd: project.canonicalPath,
36100
+ projectId,
36101
+ thinkingLevel: toThinkingLevel(body.thinkingLevel),
36102
+ mode: body.mode,
36103
+ openUI: body.openUI
36104
+ });
36105
+ if (body.model) {
36106
+ await bridge.setModel(session.sessionId, body.model);
36107
+ const thinking = body.model.thinkingLevel ?? body.thinkingLevel;
36108
+ if (thinking) await session.connection.setThinkingLevel(toThinkingLevel(thinking));
36109
+ }
36110
+ return Response.json({
36111
+ session: {
36112
+ sessionId: session.sessionId,
36113
+ projectId
36114
+ },
36115
+ messages: [],
36116
+ planPresentations: [],
36117
+ presentation: bridge.getPresentation(session.sessionId)
36118
+ });
36119
+ }, request);
36120
+ }
36121
+ function record(value) {
36122
+ return typeof value === "object" && value !== null ? value : void 0;
36123
+ }
36124
+ function artifactIndexFor(artifact) {
36125
+ const input = record(artifact.input);
36126
+ return typeof input?.artifactIndex === "number" ? input.artifactIndex : void 0;
36127
+ }
36128
+ function handleChatOpenUIArtifactPut(request) {
36129
+ return wrapApiHandler(async () => {
36130
+ const raw = await request.json().catch(() => ({}));
36131
+ const parsed = ChatOpenUIArtifactUpsertRequestSchema.safeParse(raw);
36132
+ if (!parsed.success) return Response.json({ message: "Invalid OpenUI artifact request." }, { status: 400 });
36133
+ const body = parsed.data;
36134
+ const validation = validateAndNormalizeOpenUIHtmlArtifact(body.artifact);
36135
+ if (!validation.ok) return Response.json({ message: validation.reason }, { status: validation.status ?? 400 });
36136
+ const bridge = getBridge();
36137
+ const session = bridge.getSession(body.sessionId) ?? await bridge.resumeSessionById(body.sessionId);
36138
+ if (!session || !await requireProjectSession(session)) return Response.json({ message: `Unknown session: ${body.sessionId}` }, { status: 404 });
36139
+ const messages = await bridge.getMessages(session.sessionId);
36140
+ const incomingId = body.assistantMessageId;
36141
+ const exact = messages.find((message) => message.role === "assistant" && message.id === incomingId);
36142
+ const existing = bridge.getPresentation(session.sessionId).artifactRuns.flatMap((run) => run.artifacts).filter((artifact2) => artifact2.kind === "openui-html").find((artifact2) => artifactIndexFor(artifact2) === body.artifactIndex && (record(artifact2.input)?.clientMessageId === incomingId || artifact2.sourceMessageId === incomingId));
36143
+ const fallback = existing ? void 0 : [...messages].reverse().find((message) => message.role === "assistant");
36144
+ const assistantMessageId = exact?.id ?? existing?.sourceMessageId ?? fallback?.id;
36145
+ if (!assistantMessageId) return Response.json({ message: "Unable to associate OpenUI artifact with an assistant message." }, { status: 409 });
36146
+ const artifact = {
36147
+ id: stablePresentationId(`${assistantMessageId}:openui-html:${body.artifactIndex}`),
36148
+ runId: stablePresentationId(`${assistantMessageId}:openui`),
36149
+ sourceMessageId: assistantMessageId,
36150
+ kind: "openui-html",
36151
+ title: validation.value.title,
36152
+ status: "success",
36153
+ input: {
36154
+ clientMessageId: incomingId,
36155
+ artifactIndex: body.artifactIndex
36156
+ },
36157
+ output: validation.value,
36158
+ timestamp: Date.now()
36159
+ };
36160
+ const presentation = await bridge.upsertPresentationArtifact(session.sessionId, artifact);
36161
+ return Response.json({
36162
+ artifact,
36163
+ presentation
36164
+ });
36165
+ }, request);
36166
+ }
36167
+ function handleChatPlanPresentationPut(request) {
36168
+ return wrapApiHandler(async () => {
36169
+ const body = ChatPlanPresentationUpsertRequestSchema.parse(await request.json().catch(() => ({})));
36170
+ const bridge = getBridge();
36171
+ const session = bridge.getSession(body.sessionId) ?? await bridge.resumeSessionById(body.sessionId);
36172
+ if (!session || !await requireProjectSession(session)) return Response.json({ message: `Unknown session: ${body.sessionId}` }, { status: 404 });
36173
+ const messages = await bridge.getMessages(body.sessionId);
36174
+ const incomingId = body.presentation.assistantMessageId;
36175
+ const known = messages.find((message) => message.id === incomingId && message.role === "assistant");
36176
+ const existing = (await loadManagedPlanPresentations(session)).find((item) => item.assistantMessageId === incomingId || item.clientMessageId === incomingId);
36177
+ const fallback = existing ? void 0 : [...messages].reverse().find((message) => message.role === "assistant");
36178
+ const assistantMessageId = known?.id ?? existing?.assistantMessageId ?? fallback?.id;
36179
+ if (!assistantMessageId) return Response.json({ message: "Unable to associate Plan presentation with an assistant message" }, { status: 409 });
36180
+ const clientMessageId = incomingId !== assistantMessageId ? existing?.clientMessageId ?? incomingId : existing?.clientMessageId;
36181
+ return Response.json({ presentation: await upsertManagedPlanPresentation(session, {
36182
+ ...body.presentation,
36183
+ assistantMessageId,
36184
+ ...clientMessageId ? { clientMessageId } : {}
36185
+ }) });
35479
36186
  }, request);
35480
36187
  }
35481
36188
  function handleChatQuestionPost(request) {
@@ -35505,7 +36212,8 @@ function handleChatQueueMutationPost(request) {
35505
36212
  const body = ChatQueueMutationRequestSchema.parse(await request.json().catch(() => ({})));
35506
36213
  const bridge = getBridge();
35507
36214
  if (!await requireProjectSession(bridge.getSession(body.sessionId) ?? await bridge.resumeSessionById(body.sessionId))) return Response.json({ message: `Unknown session: ${body.sessionId}` }, { status: 404 });
35508
- const result = await bridge.deleteQueuedMessage(body.sessionId, body.lane, body.index, body.expectedText);
36215
+ const mutation = body.mutation ?? { type: "delete" };
36216
+ const result = await bridge.mutateQueuedMessage(body.sessionId, body.lane, body.index, body.expectedText, mutation);
35509
36217
  return Response.json(ChatQueueMutationResponseSchema.parse(result));
35510
36218
  }, request);
35511
36219
  }
@@ -35686,14 +36394,53 @@ function normalizeSessionListRow(source) {
35686
36394
  source,
35687
36395
  sessionId,
35688
36396
  cwd,
35689
- title: stringValue(raw.sessionName) ?? stringValue(raw.name),
36397
+ title: meaningfulSessionLabel(stringValue(raw.sessionName) ?? stringValue(raw.name)),
35690
36398
  createdAt,
35691
36399
  updatedAt,
35692
36400
  messageCount: messageCountValue(raw.messageCount),
35693
- firstMessage: typeof raw.firstMessage === "string" ? raw.firstMessage : "",
36401
+ firstMessage: meaningfulSessionLabel(typeof raw.firstMessage === "string" ? raw.firstMessage : void 0) ?? "",
35694
36402
  isSubagent
35695
36403
  };
35696
36404
  }
36405
+ function sessionSourcePath(source) {
36406
+ const raw = source;
36407
+ return stringValue(raw.sessionFile) ?? stringValue(raw.path);
36408
+ }
36409
+ function latestBy(entries, time) {
36410
+ if (entries.length === 0) return void 0;
36411
+ return entries.reduce((latest, entry) => time(entry) >= time(latest) ? entry : latest);
36412
+ }
36413
+ function presentationListActivity(presentation) {
36414
+ if (!presentation) return { activityCount: 0 };
36415
+ const artifacts = presentation.artifactRuns.flatMap((run) => run.artifacts);
36416
+ const latestRefinement = latestBy(presentation.refinements, (entry) => entry.timestamp);
36417
+ const latestArtifact = latestBy(artifacts, (entry) => entry.timestamp);
36418
+ const latestBash = latestBy(presentation.userBash, (entry) => entry.startedAt);
36419
+ return {
36420
+ title: meaningfulSessionLabel(presentation.sessionName) ?? meaningfulSessionLabel(latestRefinement?.summary) ?? meaningfulSessionLabel(latestArtifact?.title) ?? meaningfulSessionLabel(latestBash?.command),
36421
+ activityCount: presentation.refinements.length + artifacts.length + presentation.userBash.length
36422
+ };
36423
+ }
36424
+ function applyPresentationToSessionRow(row, presentation) {
36425
+ const { title: presentationTitle, activityCount } = presentationListActivity(presentation);
36426
+ const firstMessage = row.firstMessage || presentationTitle || "";
36427
+ return {
36428
+ title: row.title ?? meaningfulSessionLabel(firstMessage) ?? presentationTitle ?? fallbackSessionLabel(row.sessionId),
36429
+ firstMessage,
36430
+ messageCount: row.messageCount > 0 ? row.messageCount : activityCount > 0 ? 1 : 0
36431
+ };
36432
+ }
36433
+ function sessionNeedsPresentationJoin(row) {
36434
+ return row.messageCount === 0 || !row.title || !row.firstMessage;
36435
+ }
36436
+ async function loadSessionListPresentation(row, source, livePresentation) {
36437
+ const liveActivity = presentationListActivity(livePresentation);
36438
+ if (liveActivity.activityCount > 0 || liveActivity.title) return livePresentation;
36439
+ if (!sessionNeedsPresentationJoin(row)) return livePresentation;
36440
+ const path = sessionSourcePath(source);
36441
+ if (!path) return livePresentation;
36442
+ return await loadManagedPrimePresentation({ sessionPath: path }) ?? livePresentation;
36443
+ }
35697
36444
  function sessionStatus(info, live) {
35698
36445
  if (live?.isStreaming || live?.session?.isStreaming || info.isStreaming) return "running";
35699
36446
  if (info.activity === "working" && (info.isSessionActive || info.hasRunningRlmChildren === true)) return "running";
@@ -35721,20 +36468,22 @@ function handleProjectsGet(_request) {
35721
36468
  for (const projectId of assignments.values()) if (projectId) counts.set(projectId, (counts.get(projectId) ?? 0) + 1);
35722
36469
  return Response.json({
35723
36470
  projects: await getPrimeConfig().projectRegistry.list(counts),
35724
- sessions: sessions2.map((source) => {
36471
+ sessions: await Promise.all(sessions2.map(async (source) => {
35725
36472
  const session = normalizeSessionListRow(source);
36473
+ const liveSession = getBridge().getSession(session.sessionId);
36474
+ const fields = applyPresentationToSessionRow(session, await loadSessionListPresentation(session, source, liveSession?.mapperState?.presentation));
35726
36475
  return {
35727
36476
  sessionId: session.sessionId,
35728
36477
  projectId: assignments.get(session.sessionId) ?? null,
35729
- title: redactSessionLabelSecrets(session.title || session.firstMessage || session.sessionId.slice(0, 8)),
36478
+ title: redactSessionLabelSecrets(fields.title),
35730
36479
  createdAt: session.createdAt,
35731
36480
  updatedAt: session.updatedAt,
35732
- status: sessionStatus(session.source, getBridge().getSession(session.sessionId)),
35733
- messageCount: session.messageCount,
35734
- firstMessage: session.firstMessage ? redactSessionLabelSecrets(session.firstMessage) : "",
36481
+ status: sessionStatus(session.source, liveSession),
36482
+ messageCount: fields.messageCount,
36483
+ firstMessage: fields.firstMessage ? redactSessionLabelSecrets(fields.firstMessage) : "",
35735
36484
  ...session.isSubagent ? { isSubagent: true } : {}
35736
36485
  };
35737
- })
36486
+ }))
35738
36487
  });
35739
36488
  }, _request);
35740
36489
  }
@@ -35788,15 +36537,16 @@ function handleChatSessionsGet(_request) {
35788
36537
  const formatted = await Promise.all(sessions2.map(async (s) => {
35789
36538
  const session = normalizeSessionListRow(s);
35790
36539
  const liveSession = bridge.getSession(session.sessionId);
36540
+ const fields = applyPresentationToSessionRow(session, await loadSessionListPresentation(session, s, liveSession?.mapperState?.presentation));
35791
36541
  return {
35792
36542
  sessionId: session.sessionId,
35793
36543
  projectId: await getPrimeConfig().projectRegistry.projectIdForSession(session.sessionId, liveSession?.cwd ?? session.cwd),
35794
- title: session.title || session.firstMessage || session.sessionId.slice(0, 8),
36544
+ title: fields.title,
35795
36545
  createdAt: session.createdAt,
35796
36546
  updatedAt: session.updatedAt,
35797
36547
  status: sessionStatus(session.source, liveSession),
35798
- messageCount: session.messageCount,
35799
- firstMessage: session.firstMessage,
36548
+ messageCount: fields.messageCount,
36549
+ firstMessage: fields.firstMessage,
35800
36550
  ...session.isSubagent ? { isSubagent: true } : {}
35801
36551
  };
35802
36552
  }));
@@ -36114,177 +36864,193 @@ function handleWorkspaceTreeGet(_request) {
36114
36864
  });
36115
36865
  }, _request);
36116
36866
  }
36117
- var Route$25 = createFileRoute("/api/chat")({ server: { handlers: { POST: ({ request }) => handleChatPost(request) } } });
36118
- var Route$24 = createFileRoute("/api/health")({ server: { handlers: { GET: ({ request }) => handleHealthGet(request) } } });
36119
- var Route$23 = createFileRoute("/api/projects")({ server: { handlers: {
36867
+ var Route$27 = createFileRoute("/api/chat")({ server: { handlers: { POST: ({ request }) => handleChatPost(request) } } });
36868
+ var Route$26 = createFileRoute("/api/health")({ server: { handlers: { GET: ({ request }) => handleHealthGet(request) } } });
36869
+ var Route$25 = createFileRoute("/api/projects")({ server: { handlers: {
36120
36870
  DELETE: ({ request }) => handleProjectDelete(request),
36121
36871
  GET: ({ request }) => handleProjectsGet(request),
36122
36872
  PATCH: ({ request }) => handleProjectPatch(request),
36123
36873
  POST: ({ request }) => handleProjectsPost(request)
36124
36874
  } } });
36125
- var Route$22 = createFileRoute("/api/chat/abort")({ server: { handlers: { POST: ({ request }) => handleChatAbortPost(request) } } });
36126
- var Route$21 = createFileRoute("/api/chat/artifacts")({ server: { handlers: { PUT: ({ request }) => handleChatOpenUIArtifactPut(request) } } });
36127
- var Route$20 = createFileRoute("/api/chat/command")({ server: { handlers: { POST: ({ request }) => handleChatCommandPost(request) } } });
36128
- var Route$19 = createFileRoute("/api/chat/commands")({ server: { handlers: { GET: ({ request }) => handleChatCommandsGet(request) } } });
36129
- var Route$18 = createFileRoute("/api/chat/events")({ server: { handlers: { GET: ({ request }) => handleChatEventsGet(request) } } });
36130
- var Route$17 = createFileRoute("/api/chat/model")({ server: { handlers: { POST: ({ request }) => handleChatModelPost(request) } } });
36131
- var Route$16 = createFileRoute("/api/chat/models")({ server: { handlers: { GET: ({ request }) => handleChatModelsGet(request) } } });
36132
- var Route$15 = createFileRoute("/api/chat/new")({ server: { handlers: { POST: ({ request }) => handleChatNewPost(request) } } });
36133
- var Route$14 = createFileRoute("/api/chat/providers")({ server: { handlers: {
36875
+ var Route$24 = createFileRoute("/api/chat/abort")({ server: { handlers: { POST: ({ request }) => handleChatAbortPost(request) } } });
36876
+ var Route$23 = createFileRoute("/api/chat/artifacts")({ server: { handlers: { PUT: ({ request }) => handleChatOpenUIArtifactPut(request) } } });
36877
+ var Route$22 = createFileRoute("/api/chat/command")({ server: { handlers: { POST: ({ request }) => handleChatCommandPost(request) } } });
36878
+ var Route$21 = createFileRoute("/api/chat/commands")({ server: { handlers: { GET: ({ request }) => handleChatCommandsGet(request) } } });
36879
+ var Route$20 = createFileRoute("/api/chat/events")({ server: { handlers: { GET: ({ request }) => handleChatEventsGet(request) } } });
36880
+ var Route$19 = createFileRoute("/api/chat/mcp")({ server: { handlers: {
36881
+ GET: ({ request }) => handleChatMcpGet(request),
36882
+ POST: ({ request }) => handleChatMcpPost(request),
36883
+ DELETE: ({ request }) => handleChatMcpDelete(request)
36884
+ } } });
36885
+ var Route$18 = createFileRoute("/api/chat/model")({ server: { handlers: { POST: ({ request }) => handleChatModelPost(request) } } });
36886
+ var Route$17 = createFileRoute("/api/chat/models")({ server: { handlers: { GET: ({ request }) => handleChatModelsGet(request) } } });
36887
+ var Route$16 = createFileRoute("/api/chat/new")({ server: { handlers: { POST: ({ request }) => handleChatNewPost(request) } } });
36888
+ var Route$15 = createFileRoute("/api/chat/providers")({ server: { handlers: {
36134
36889
  GET: ({ request }) => handleChatProvidersGet(request),
36135
36890
  POST: ({ request }) => handleChatProvidersPost(request),
36136
36891
  DELETE: ({ request }) => handleChatProvidersDelete(request)
36137
36892
  } } });
36138
- var Route$13 = createFileRoute("/api/chat/question")({ server: { handlers: { POST: ({ request }) => handleChatQuestionPost(request) } } });
36139
- var Route$12 = createFileRoute("/api/chat/resources")({ server: { handlers: { GET: ({ request }) => handleChatResourcesGet(request) } } });
36140
- var Route$11 = createFileRoute("/api/chat/resume")({ server: { handlers: { POST: ({ request }) => handleChatResumePost(request) } } });
36141
- var Route$10 = createFileRoute("/api/chat/session")({ server: { handlers: {
36893
+ var Route$14 = createFileRoute("/api/chat/question")({ server: { handlers: { POST: ({ request }) => handleChatQuestionPost(request) } } });
36894
+ var Route$13 = createFileRoute("/api/chat/resources")({ server: { handlers: { GET: ({ request }) => handleChatResourcesGet(request) } } });
36895
+ var Route$12 = createFileRoute("/api/chat/resume")({ server: { handlers: { POST: ({ request }) => handleChatResumePost(request) } } });
36896
+ var Route$11 = createFileRoute("/api/chat/session")({ server: { handlers: {
36142
36897
  GET: ({ request }) => new URL(request.url).searchParams.has("attachmentId") ? handleChatAttachmentGet(request) : handleChatSessionGet(request),
36143
36898
  POST: ({ request }) => handleChatAttachmentsPost(request),
36144
36899
  PUT: ({ request }) => handleChatPlanPresentationPut(request),
36145
36900
  PATCH: ({ request }) => handleChatQueueMutationPost(request)
36146
36901
  } } });
36147
- var Route$9 = createFileRoute("/api/chat/sessions")({ server: { handlers: {
36902
+ var Route$10 = createFileRoute("/api/chat/sessions")({ server: { handlers: {
36148
36903
  DELETE: ({ request }) => handleChatSessionDelete(request),
36149
36904
  GET: ({ request }) => handleChatSessionsGet(request),
36150
36905
  PATCH: ({ request }) => handleChatSessionRenamePatch(request)
36151
36906
  } } });
36152
- var Route$8 = createFileRoute("/api/chat/settings")({ server: { handlers: {
36907
+ var Route$9 = createFileRoute("/api/chat/settings")({ server: { handlers: {
36153
36908
  GET: ({ request }) => handleChatSettingsGet(request),
36154
36909
  PATCH: ({ request }) => handleChatSettingsPatch(request)
36155
36910
  } } });
36156
- var Route$7 = createFileRoute("/api/projects/browse")({ server: { handlers: { GET: ({ request }) => handleProjectBrowseGet(request) } } });
36157
- var Route$6 = createFileRoute("/api/projects/fork")({ server: { handlers: { POST: ({ request }) => handleProjectSessionFork(request) } } });
36158
- var Route$5 = createFileRoute("/api/workspace/browse")({ server: { handlers: { GET: ({ request }) => handleWorkspaceBrowseGet(request) } } });
36159
- var Route$4 = createFileRoute("/api/workspace/file")({ server: { handlers: { GET: ({ request }) => handleWorkspaceFileGet(request) } } });
36160
- var Route$3 = createFileRoute("/api/workspace/root")({ server: { handlers: { POST: () => Response.json({ message: "The workspace root is fixed when Fleet starts" }, { status: 405 }) } } });
36161
- var Route$2 = createFileRoute("/api/workspace/tree")({ server: { handlers: { GET: ({ request }) => handleWorkspaceTreeGet(request) } } });
36911
+ var Route$8 = createFileRoute("/api/projects/browse")({ server: { handlers: { GET: ({ request }) => handleProjectBrowseGet(request) } } });
36912
+ var Route$7 = createFileRoute("/api/projects/fork")({ server: { handlers: { POST: ({ request }) => handleProjectSessionFork(request) } } });
36913
+ var Route$6 = createFileRoute("/api/workspace/browse")({ server: { handlers: { GET: ({ request }) => handleWorkspaceBrowseGet(request) } } });
36914
+ var Route$5 = createFileRoute("/api/workspace/file")({ server: { handlers: { GET: ({ request }) => handleWorkspaceFileGet(request) } } });
36915
+ var Route$4 = createFileRoute("/api/workspace/root")({ server: { handlers: { POST: () => Response.json({ message: "The workspace root is fixed when Fleet starts" }, { status: 405 }) } } });
36916
+ var Route$3 = createFileRoute("/api/workspace/tree")({ server: { handlers: { GET: ({ request }) => handleWorkspaceTreeGet(request) } } });
36917
+ var Route$2 = createFileRoute("/api/chat/mcp/oauth")({ server: { handlers: { POST: ({ request }) => handleChatMcpOAuthPost(request) } } });
36162
36918
  var Route$1 = createFileRoute("/api/chat/models/discover")({ server: { handlers: { POST: ({ request }) => handleChatModelsDiscoverPost(request) } } });
36163
36919
  var Route = createFileRoute("/api/chat/providers/oauth")({ server: { handlers: { POST: ({ request }) => handleChatProvidersOAuthPost(request) } } });
36164
- var IndexRoute = Route$26.update({
36920
+ var IndexRoute = Route$28.update({
36165
36921
  id: "/",
36166
36922
  path: "/",
36167
- getParentRoute: () => Route$27
36923
+ getParentRoute: () => Route$29
36168
36924
  });
36169
- var ApiChatRoute = Route$25.update({
36925
+ var ApiChatRoute = Route$27.update({
36170
36926
  id: "/api/chat",
36171
36927
  path: "/api/chat",
36172
- getParentRoute: () => Route$27
36928
+ getParentRoute: () => Route$29
36173
36929
  });
36174
- var ApiHealthRoute = Route$24.update({
36930
+ var ApiHealthRoute = Route$26.update({
36175
36931
  id: "/api/health",
36176
36932
  path: "/api/health",
36177
- getParentRoute: () => Route$27
36933
+ getParentRoute: () => Route$29
36178
36934
  });
36179
- var ApiProjectsRoute = Route$23.update({
36935
+ var ApiProjectsRoute = Route$25.update({
36180
36936
  id: "/api/projects",
36181
36937
  path: "/api/projects",
36182
- getParentRoute: () => Route$27
36938
+ getParentRoute: () => Route$29
36183
36939
  });
36184
- var ApiChatAbortRoute = Route$22.update({
36940
+ var ApiChatAbortRoute = Route$24.update({
36185
36941
  id: "/abort",
36186
36942
  path: "/abort",
36187
36943
  getParentRoute: () => ApiChatRoute
36188
36944
  });
36189
- var ApiChatArtifactsRoute = Route$21.update({
36945
+ var ApiChatArtifactsRoute = Route$23.update({
36190
36946
  id: "/artifacts",
36191
36947
  path: "/artifacts",
36192
36948
  getParentRoute: () => ApiChatRoute
36193
36949
  });
36194
- var ApiChatCommandRoute = Route$20.update({
36950
+ var ApiChatCommandRoute = Route$22.update({
36195
36951
  id: "/command",
36196
36952
  path: "/command",
36197
36953
  getParentRoute: () => ApiChatRoute
36198
36954
  });
36199
- var ApiChatCommandsRoute = Route$19.update({
36955
+ var ApiChatCommandsRoute = Route$21.update({
36200
36956
  id: "/commands",
36201
36957
  path: "/commands",
36202
36958
  getParentRoute: () => ApiChatRoute
36203
36959
  });
36204
- var ApiChatEventsRoute = Route$18.update({
36960
+ var ApiChatEventsRoute = Route$20.update({
36205
36961
  id: "/events",
36206
36962
  path: "/events",
36207
36963
  getParentRoute: () => ApiChatRoute
36208
36964
  });
36209
- var ApiChatModelRoute = Route$17.update({
36965
+ var ApiChatMcpRoute = Route$19.update({
36966
+ id: "/mcp",
36967
+ path: "/mcp",
36968
+ getParentRoute: () => ApiChatRoute
36969
+ });
36970
+ var ApiChatModelRoute = Route$18.update({
36210
36971
  id: "/model",
36211
36972
  path: "/model",
36212
36973
  getParentRoute: () => ApiChatRoute
36213
36974
  });
36214
- var ApiChatModelsRoute = Route$16.update({
36975
+ var ApiChatModelsRoute = Route$17.update({
36215
36976
  id: "/models",
36216
36977
  path: "/models",
36217
36978
  getParentRoute: () => ApiChatRoute
36218
36979
  });
36219
- var ApiChatNewRoute = Route$15.update({
36980
+ var ApiChatNewRoute = Route$16.update({
36220
36981
  id: "/new",
36221
36982
  path: "/new",
36222
36983
  getParentRoute: () => ApiChatRoute
36223
36984
  });
36224
- var ApiChatProvidersRoute = Route$14.update({
36985
+ var ApiChatProvidersRoute = Route$15.update({
36225
36986
  id: "/providers",
36226
36987
  path: "/providers",
36227
36988
  getParentRoute: () => ApiChatRoute
36228
36989
  });
36229
- var ApiChatQuestionRoute = Route$13.update({
36990
+ var ApiChatQuestionRoute = Route$14.update({
36230
36991
  id: "/question",
36231
36992
  path: "/question",
36232
36993
  getParentRoute: () => ApiChatRoute
36233
36994
  });
36234
- var ApiChatResourcesRoute = Route$12.update({
36995
+ var ApiChatResourcesRoute = Route$13.update({
36235
36996
  id: "/resources",
36236
36997
  path: "/resources",
36237
36998
  getParentRoute: () => ApiChatRoute
36238
36999
  });
36239
- var ApiChatResumeRoute = Route$11.update({
37000
+ var ApiChatResumeRoute = Route$12.update({
36240
37001
  id: "/resume",
36241
37002
  path: "/resume",
36242
37003
  getParentRoute: () => ApiChatRoute
36243
37004
  });
36244
- var ApiChatSessionRoute = Route$10.update({
37005
+ var ApiChatSessionRoute = Route$11.update({
36245
37006
  id: "/session",
36246
37007
  path: "/session",
36247
37008
  getParentRoute: () => ApiChatRoute
36248
37009
  });
36249
- var ApiChatSessionsRoute = Route$9.update({
37010
+ var ApiChatSessionsRoute = Route$10.update({
36250
37011
  id: "/sessions",
36251
37012
  path: "/sessions",
36252
37013
  getParentRoute: () => ApiChatRoute
36253
37014
  });
36254
- var ApiChatSettingsRoute = Route$8.update({
37015
+ var ApiChatSettingsRoute = Route$9.update({
36255
37016
  id: "/settings",
36256
37017
  path: "/settings",
36257
37018
  getParentRoute: () => ApiChatRoute
36258
37019
  });
36259
- var ApiProjectsBrowseRoute = Route$7.update({
37020
+ var ApiProjectsBrowseRoute = Route$8.update({
36260
37021
  id: "/browse",
36261
37022
  path: "/browse",
36262
37023
  getParentRoute: () => ApiProjectsRoute
36263
37024
  });
36264
- var ApiProjectsForkRoute = Route$6.update({
37025
+ var ApiProjectsForkRoute = Route$7.update({
36265
37026
  id: "/fork",
36266
37027
  path: "/fork",
36267
37028
  getParentRoute: () => ApiProjectsRoute
36268
37029
  });
36269
- var ApiWorkspaceBrowseRoute = Route$5.update({
37030
+ var ApiWorkspaceBrowseRoute = Route$6.update({
36270
37031
  id: "/api/workspace/browse",
36271
37032
  path: "/api/workspace/browse",
36272
- getParentRoute: () => Route$27
37033
+ getParentRoute: () => Route$29
36273
37034
  });
36274
- var ApiWorkspaceFileRoute = Route$4.update({
37035
+ var ApiWorkspaceFileRoute = Route$5.update({
36275
37036
  id: "/api/workspace/file",
36276
37037
  path: "/api/workspace/file",
36277
- getParentRoute: () => Route$27
37038
+ getParentRoute: () => Route$29
36278
37039
  });
36279
- var ApiWorkspaceRootRoute = Route$3.update({
37040
+ var ApiWorkspaceRootRoute = Route$4.update({
36280
37041
  id: "/api/workspace/root",
36281
37042
  path: "/api/workspace/root",
36282
- getParentRoute: () => Route$27
37043
+ getParentRoute: () => Route$29
36283
37044
  });
36284
- var ApiWorkspaceTreeRoute = Route$2.update({
37045
+ var ApiWorkspaceTreeRoute = Route$3.update({
36285
37046
  id: "/api/workspace/tree",
36286
37047
  path: "/api/workspace/tree",
36287
- getParentRoute: () => Route$27
37048
+ getParentRoute: () => Route$29
37049
+ });
37050
+ var ApiChatMcpOauthRoute = Route$2.update({
37051
+ id: "/oauth",
37052
+ path: "/oauth",
37053
+ getParentRoute: () => ApiChatMcpRoute
36288
37054
  });
36289
37055
  var ApiChatModelsDiscoverRoute = Route$1.update({
36290
37056
  id: "/discover",
@@ -36296,6 +37062,8 @@ var ApiChatProvidersOauthRoute = Route.update({
36296
37062
  path: "/oauth",
36297
37063
  getParentRoute: () => ApiChatProvidersRoute
36298
37064
  });
37065
+ var ApiChatMcpRouteChildren = { ApiChatMcpOauthRoute };
37066
+ var ApiChatMcpRouteWithChildren = ApiChatMcpRoute._addFileChildren(ApiChatMcpRouteChildren);
36299
37067
  var ApiChatModelsRouteChildren = { ApiChatModelsDiscoverRoute };
36300
37068
  var ApiChatModelsRouteWithChildren = ApiChatModelsRoute._addFileChildren(ApiChatModelsRouteChildren);
36301
37069
  var ApiChatProvidersRouteChildren = { ApiChatProvidersOauthRoute };
@@ -36305,6 +37073,7 @@ var ApiChatRouteChildren = {
36305
37073
  ApiChatCommandRoute,
36306
37074
  ApiChatCommandsRoute,
36307
37075
  ApiChatEventsRoute,
37076
+ ApiChatMcpRoute: ApiChatMcpRouteWithChildren,
36308
37077
  ApiChatModelRoute,
36309
37078
  ApiChatModelsRoute: ApiChatModelsRouteWithChildren,
36310
37079
  ApiChatNewRoute,
@@ -36331,7 +37100,7 @@ var rootRouteChildren = {
36331
37100
  ApiWorkspaceRootRoute,
36332
37101
  ApiWorkspaceTreeRoute
36333
37102
  };
36334
- var routeTree = Route$27._addFileChildren(rootRouteChildren)._addFileTypes();
37103
+ var routeTree = Route$29._addFileChildren(rootRouteChildren)._addFileTypes();
36335
37104
  function getRouter() {
36336
37105
  return createRouter({
36337
37106
  routeTree,