@qredence/fleet 0.8.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/CHANGELOG.md +90 -0
  2. package/dist/web/client/assets/DialogTitle-BlVq-tcv.js +1 -0
  3. package/dist/web/client/assets/FloatingPortal-D8-EPDs2.js +1 -0
  4. package/dist/web/client/assets/activity-BPIKUzOU.js +1 -0
  5. package/dist/web/client/assets/agents-BMQXA18L.js +2 -0
  6. package/dist/web/client/assets/agents-page-D2soW46O.js +1 -0
  7. package/dist/web/client/assets/alert-CzWGeumf.js +1 -0
  8. package/dist/web/client/assets/alert-dialog-D-e1Pr4q.js +1 -0
  9. package/dist/web/client/assets/artifacts-panel-6JEdy6jU.js +1 -0
  10. package/dist/web/client/assets/badge-CzQFgmVK.js +1 -0
  11. package/dist/web/client/assets/chat-command-palette-Bxr5EkO6.js +1 -0
  12. package/dist/web/client/assets/chat-hpzV6IA6.js +57 -0
  13. package/dist/web/client/assets/chat-queries-ty76G6rK.js +3 -0
  14. package/dist/web/client/assets/clock-3-BwWCSCm_.js +1 -0
  15. package/dist/web/client/assets/{command-imgUMV3r.js → command-xo-NK4xO.js} +1 -1
  16. package/dist/web/client/assets/connectors-E4KW6hBL.js +2 -0
  17. package/dist/web/client/assets/connectors-page-CDzzjCIJ.js +1 -0
  18. package/dist/web/client/assets/create-project-dialog-Db-WhUmP.js +1 -0
  19. package/dist/web/client/assets/dialog-CK8dym6z.js +1 -0
  20. package/dist/web/client/assets/{fork-picker-dialog-Cgi48NnT.js → fork-picker-dialog-DSaFeUii.js} +1 -1
  21. package/dist/web/client/assets/globals-DDDleTbS.css +2 -0
  22. package/dist/web/client/assets/index-Cf8tRpHL.js +13 -0
  23. package/dist/web/client/assets/{input-7g8_nw-Z.js → input-CBoTMPC_.js} +1 -1
  24. package/dist/web/client/assets/{input-group-Nq03Qums.js → input-group-BFubAtz9.js} +1 -1
  25. package/dist/web/client/assets/mcp-connections-section-BsNhp1b2.js +2 -0
  26. package/dist/web/client/assets/message-queue-Btjt9wK2.js +1 -0
  27. package/dist/web/client/assets/{model-selector-list-Cp687pdm.js → model-selector-list-CbDAT0Rw.js} +1 -1
  28. package/dist/web/client/assets/mutation-Da9zdeWr.js +1 -0
  29. package/dist/web/client/assets/notify-BIL0-CGy.js +1 -0
  30. package/dist/web/client/assets/open-panel-action-message-SdA1VU42.js +1 -0
  31. package/dist/web/client/assets/openui-renderer-DG-iML7M.js +291 -0
  32. package/dist/web/client/assets/pencil-Cbgq3ybX.js +1 -0
  33. package/dist/web/client/assets/plus-DUP2JPVG.js +1 -0
  34. package/dist/web/client/assets/product-page-header-Ck6I13CE.js +1 -0
  35. package/dist/web/client/assets/provider-catalog-CLEDlH_v.js +1 -0
  36. package/dist/web/client/assets/provider-label-BItazQ6H.js +1 -0
  37. package/dist/web/client/assets/right-panel-context-CjX-HkDO.js +1 -0
  38. package/dist/web/client/assets/right-panel-registry-BAJ6TuEY.js +2 -0
  39. package/dist/web/client/assets/rotate-ccw-DLkfsmG9.js +1 -0
  40. package/dist/web/client/assets/routes--tnF7d6H.js +14 -0
  41. package/dist/web/client/assets/select-DYh951qi.js +1 -0
  42. package/dist/web/client/assets/{session-activity-panel-Bc4-HSfb.js → session-activity-panel-DwaXiSrS.js} +1 -1
  43. package/dist/web/client/assets/{session-insights-panel-D0v_DKcb.js → session-insights-panel-BXEmuJKf.js} +1 -1
  44. package/dist/web/client/assets/{session-tool-renderer-C7mYeUOs.js → session-tool-renderer-DEABxZG3.js} +25 -25
  45. package/dist/web/client/assets/{session-tree-panel-By9m9tGB.js → session-tree-panel-5QgMvXoX.js} +1 -1
  46. package/dist/web/client/assets/settings-dialog-BomLOETY.js +3 -0
  47. package/dist/web/client/assets/sparkles-CASAe1AI.js +1 -0
  48. package/dist/web/client/assets/{subagent-chat-panel-DsPmLZSf.js → subagent-chat-panel-R2RoX1Yt.js} +1 -1
  49. package/dist/web/client/assets/subagent-transcript-DVZhMo7a.js +1 -0
  50. package/dist/web/client/assets/{subagents-panel-gQ9BLfV3.js → subagents-panel-CMMRUP8F.js} +1 -1
  51. package/dist/web/client/assets/switch-BrxDfsX6.js +1 -0
  52. package/dist/web/client/assets/toast-BNWkgZ0u.js +1 -0
  53. package/dist/web/client/assets/{tool-output-normalizer-CADgEiI4.js → tool-output-normalizer-DDU09Zc6.js} +1 -1
  54. package/dist/web/client/assets/tool-part-normalizer-CF6bmJ0s.js +4 -0
  55. package/dist/web/client/assets/tool-result-7qREIVv_.js +5 -0
  56. package/dist/web/client/assets/tool-timeline-CGhwMeNl.js +2 -0
  57. package/dist/web/client/assets/trash-sm2UyOxe.js +1 -0
  58. package/dist/web/client/assets/types-gIgIxnnG.js +1 -0
  59. package/dist/web/client/assets/useNavigate-CVhM7pag.js +1 -0
  60. package/dist/web/client/assets/useRender-CzJUrRlB.js +1 -0
  61. package/dist/web/client/assets/useScrollLock-BcsteNzT.js +1 -0
  62. package/dist/web/client/assets/with-selector-B_VDO56x.js +1 -0
  63. package/dist/web/client/bundle-budget.json +6 -6
  64. package/dist/web/server/{_tanstack-start-manifest_v-BiNPG4xt-BZTMSM2I.js → _tanstack-start-manifest_v-Io433TLr-YWPNQWQI.js} +44 -23
  65. package/dist/web/server/agents-DOgCHixY-KUZP2VDO.js +22 -0
  66. package/dist/web/server/agents-page-BdiR9H8w-M6X6SXMF.js +215 -0
  67. package/dist/web/server/{artifacts-panel-CqGBNU4q-UHNMC7PK.js → artifacts-panel-cYqS54cM-K6SF3K6W.js} +27 -17
  68. package/dist/web/server/{chat-command-palette-B94-zIEz-ES2ZB4ZF.js → chat-command-palette-BDnwcymZ-DSTFIAOD.js} +22 -13
  69. package/dist/web/server/chunk-2ETDIMNM.js +40 -0
  70. package/dist/web/server/{chunk-K67IDUAI.js → chunk-2OC2FKHR.js} +42 -32
  71. package/dist/web/server/{chunk-2VKVSL6Y.js → chunk-35RIM6VP.js} +128 -127
  72. package/dist/web/server/{chunk-5GUEYYYO.js → chunk-37EK2TYH.js} +4591 -13688
  73. package/dist/web/server/chunk-5MOXRFX6.js +826 -0
  74. package/dist/web/server/chunk-6GYLXDX3.js +588 -0
  75. package/dist/web/server/chunk-7DQQMT5V.js +8993 -0
  76. package/dist/web/server/chunk-APOS34PW.js +8965 -0
  77. package/dist/web/server/{chunk-YQO36OP6.js → chunk-AXN2OBPF.js} +2 -4
  78. package/dist/web/server/chunk-BD7YKYWL.js +1007 -0
  79. package/dist/web/server/chunk-BLGKLQJG.js +432 -0
  80. package/dist/web/server/{chunk-BAHZXA4D.js → chunk-BZ2EAUZZ.js} +10 -12
  81. package/dist/web/server/chunk-C5XHGLET.js +193 -0
  82. package/dist/web/server/chunk-CE7U5QB2.js +42 -0
  83. package/dist/web/server/{chunk-E6T36NM5.js → chunk-FI3UF2GW.js} +36 -353
  84. package/dist/web/server/{chunk-LTTBT3J7.js → chunk-FNV3WZXL.js} +5 -9
  85. package/dist/web/server/{chunk-2FHYWKDN.js → chunk-FSQWWR2M.js} +46 -16
  86. package/dist/web/server/chunk-FT7HNDR5.js +143 -0
  87. package/dist/web/server/chunk-GNXIDE26.js +44 -0
  88. package/dist/web/server/{chunk-EAKPTSWR.js → chunk-HAFELESQ.js} +5 -7
  89. package/dist/web/server/{chunk-WSK55TKE.js → chunk-KBMRRJQN.js} +96 -10
  90. package/dist/web/server/chunk-KSGGSGOA.js +50 -0
  91. package/dist/web/server/{chunk-SGAQVAYL.js → chunk-NSFKPEFI.js} +2 -2
  92. package/dist/web/server/chunk-NZCEQWK2.js +6891 -0
  93. package/dist/web/server/chunk-OO7NBFQQ.js +15 -0
  94. package/dist/web/server/{chunk-EL2JCDAM.js → chunk-PQVTLG3E.js} +9 -9
  95. package/dist/web/server/{chunk-LQM6QR7S.js → chunk-Q4ECIATK.js} +61 -47
  96. package/dist/web/server/chunk-QOZCYKMA.js +769 -0
  97. package/dist/web/server/{chunk-CZLGB3NE.js → chunk-R4BS3KYI.js} +2 -4
  98. package/dist/web/server/{chunk-FB2QLQTN.js → chunk-RHJEOG37.js} +12 -13
  99. package/dist/web/server/chunk-RX2ZJARF.js +73 -0
  100. package/dist/web/server/chunk-TXZDDJCT.js +5115 -0
  101. package/dist/web/server/{chunk-OAYEN3JV.js → chunk-VDEUVEWL.js} +2253 -1
  102. package/dist/web/server/{chunk-ABMGW6QH.js → chunk-W2GI7NRX.js} +16140 -15708
  103. package/dist/web/server/{chunk-SI5IQSG4.js → chunk-W7GGECTL.js} +8 -7
  104. package/dist/web/server/connectors-Dv_uPdv0-2X5VWQXK.js +22 -0
  105. package/dist/web/server/connectors-page-DW75T-uH-EKRHUZ6K.js +66 -0
  106. package/dist/web/server/{create-project-dialog-CFPX6Ihl-EO4XTINS.js → create-project-dialog-BS5Sva46-BO4RLW2Q.js} +25 -14
  107. package/dist/web/server/{fork-picker-dialog-B2RBFzoZ-R6GXPSPL.js → fork-picker-dialog-DFpKOdAw-JPLJSYYU.js} +7 -10
  108. package/dist/web/server/{markdown-BvCfOB26-VDH4YOQD.js → markdown-Cc8V9dOF-JTNTJKQU.js} +5 -6
  109. package/dist/web/server/{markdown-code-SYc-BQvp-MR4FXT5C.js → markdown-code-gaRnbgNM-V5LIRYCD.js} +7 -8
  110. package/dist/web/server/{message-queue-D32rLiJo-HEBRGH5B.js → message-queue-nQ2_kU82-KKSLYR4S.js} +7 -14
  111. package/dist/web/server/{model-selector-list-DKzt_xEN-5ZPU6XDY.js → model-selector-list-By_G7_Hr-GXT27BZO.js} +12 -14
  112. package/dist/web/server/{openui-renderer-CeVtOdYl-PY37PCJI.js → openui-renderer-Q31y65CQ-QNVSP4NN.js} +20 -13
  113. package/dist/web/server/{prompt-suggestions-CpTK_fHV-Q4ILLZKC.js → prompt-suggestions-B67Uy5Rk-5SMTSIFQ.js} +5 -4
  114. package/dist/web/server/{repl-panel-1kSS1UGd-DDM5ADGZ.js → repl-panel-1kSS1UGd-POXRYDDJ.js} +2 -3
  115. package/dist/web/server/{resources-panel-S4NHlpz7-NF7WYYSR.js → resources-panel-CH8sG0Od-4BZN6SLY.js} +18 -10
  116. package/dist/web/server/router-8EzTM9Eq-COVGJKKX.js +23 -0
  117. package/dist/web/server/routes-88H0fiN3-WIAZJ3RT.js +124 -0
  118. package/dist/web/server/server.js +3 -3
  119. package/dist/web/server/{session-activity-panel-Bz2GrdMk-PCOXG46X.js → session-activity-panel-CgSOde03-B5RCAGB4.js} +18 -10
  120. package/dist/web/server/{session-insights-panel-CfMX2NRu-6HWZTTAC.js → session-insights-panel-BiVObm_6-AP4FITT7.js} +2 -12
  121. package/dist/web/server/{session-reasoning-panel-CpiTdyQz-O3B5CDKS.js → session-reasoning-panel-Dmny6YTk-D3HQV2YB.js} +17 -9
  122. package/dist/web/server/session-tool-renderer-BrnTO2w3-V6EE6AB2.js +34 -0
  123. package/dist/web/server/{session-tree-panel-CzkE0RFB-P4KWA7S2.js → session-tree-panel-BEqR_cAJ-TZS7VRCB.js} +18 -11
  124. package/dist/web/server/{settings-dialog-BUgVNpr1-THSYIOZL.js → settings-dialog-DkesVBrS-BAAA3YNU.js} +238 -847
  125. package/dist/web/server/{subagent-chat-panel-mw3kEFfK-CDYX7LST.js → subagent-chat-panel-Bfmt1bCE-DKDVH3NJ.js} +23 -15
  126. package/dist/web/server/{subagents-panel-2ZJfYrXG-NDJKHJHD.js → subagents-panel-ChJDDvad-GNCHDTPB.js} +24 -17
  127. package/dist/web/server/{workspace-panel-xznrPDLt-QCJRZOF3.js → workspace-panel-Cij_JylD-WPYSV5FA.js} +23 -15
  128. package/package.json +1 -1
  129. package/dist/web/client/assets/DialogTitle-RY2UDuCY.js +0 -1
  130. package/dist/web/client/assets/FloatingPortal-XC0MCNnD.js +0 -1
  131. package/dist/web/client/assets/action-swap-BWRUNKQA.js +0 -1
  132. package/dist/web/client/assets/alert-dialog-DGNvg0B1.js +0 -1
  133. package/dist/web/client/assets/artifacts-panel-BGXpKRJ7.js +0 -1
  134. package/dist/web/client/assets/badge-DM06QVqB.js +0 -57
  135. package/dist/web/client/assets/chat-command-palette-PenyaZBw.js +0 -1
  136. package/dist/web/client/assets/create-project-dialog-C00d5yCq.js +0 -1
  137. package/dist/web/client/assets/dialog-zCNOQI63.js +0 -1
  138. package/dist/web/client/assets/globals-BuMuB_ea.css +0 -2
  139. package/dist/web/client/assets/index-BqBdQGWs.js +0 -13
  140. package/dist/web/client/assets/message-queue-sSljtjYz.js +0 -1
  141. package/dist/web/client/assets/mutation-DOi2Qgfa.js +0 -1
  142. package/dist/web/client/assets/notify-Cqdu6EV8.js +0 -1
  143. package/dist/web/client/assets/openui-renderer-BdYTcn-_.js +0 -291
  144. package/dist/web/client/assets/provider-label-QrVOwKBO.js +0 -1
  145. package/dist/web/client/assets/right-panel-context-DHKWoetk.js +0 -1
  146. package/dist/web/client/assets/right-panel-registry-BaLZiKny.js +0 -2
  147. package/dist/web/client/assets/routes-BkFkhfO3.js +0 -16
  148. package/dist/web/client/assets/select-BhV4ikeN.js +0 -1
  149. package/dist/web/client/assets/settings-dialog-Dpt4Ha_m.js +0 -2
  150. package/dist/web/client/assets/sparkles-BwVa9zQJ.js +0 -1
  151. package/dist/web/client/assets/subagent-transcript-CNQ9wGk2.js +0 -1
  152. package/dist/web/client/assets/switch-C7Myu-Dt.js +0 -1
  153. package/dist/web/client/assets/toast-DlbKi6K-.js +0 -1
  154. package/dist/web/client/assets/tool-part-normalizer-CYK62WZM.js +0 -4
  155. package/dist/web/client/assets/tool-result-bjAGZ2qm.js +0 -5
  156. package/dist/web/client/assets/tool-timeline-eNqH1zj7.js +0 -2
  157. package/dist/web/client/assets/types-D5hZ8IyV.js +0 -1
  158. package/dist/web/client/assets/useRender-Bbk_fl72.js +0 -1
  159. package/dist/web/server/chunk-2PAW6K4Q.js +0 -56
  160. package/dist/web/server/chunk-7L5PCCYR.js +0 -2287
  161. package/dist/web/server/chunk-FB3UHLLN.js +0 -49
  162. package/dist/web/server/chunk-OSPDNT7S.js +0 -25404
  163. package/dist/web/server/router-DVKxZik_-254GZAJW.js +0 -30
  164. package/dist/web/server/routes-BTxAklRp-UM7ZTLLP.js +0 -140
  165. package/dist/web/server/session-tool-renderer-BZiOxtt1-T3ZGAQKX.js +0 -26
@@ -1,26 +1,42 @@
1
+ import {
2
+ ItemRow,
3
+ McpConnectionsSection,
4
+ RowSurface,
5
+ SettingsCommitActions,
6
+ SettingsPane
7
+ } from "./chunk-BLGKLQJG.js";
1
8
  import {
2
9
  Spinner
3
- } from "./chunk-YQO36OP6.js";
10
+ } from "./chunk-AXN2OBPF.js";
4
11
  import {
5
12
  InputGroup,
6
13
  InputGroupAddon,
7
14
  InputGroupButton,
8
15
  InputGroupInput
9
- } from "./chunk-EAKPTSWR.js";
16
+ } from "./chunk-HAFELESQ.js";
10
17
  import {
11
- Alert,
12
- AlertDescription,
13
18
  Field,
14
19
  FieldDescription,
15
20
  FieldGroup,
16
21
  FieldLabel,
17
22
  Switch$1
18
- } from "./chunk-LQM6QR7S.js";
23
+ } from "./chunk-Q4ECIATK.js";
24
+ import {
25
+ Alert,
26
+ AlertDescription
27
+ } from "./chunk-GNXIDE26.js";
19
28
  import {
20
29
  isModelPatternEnabled,
21
30
  modelMatchesPattern,
22
31
  modelPattern
23
32
  } from "./chunk-TAPQMXA7.js";
33
+ import {
34
+ Dialog$1,
35
+ DialogContent,
36
+ DialogDescription,
37
+ DialogHeader,
38
+ DialogTitle
39
+ } from "./chunk-FT7HNDR5.js";
24
40
  import {
25
41
  AlertDialog$1,
26
42
  AlertDialogAction,
@@ -29,60 +45,60 @@ import {
29
45
  AlertDialogDescription,
30
46
  AlertDialogFooter,
31
47
  AlertDialogTitle,
32
- Dialog$1,
33
- DialogContent,
34
- DialogDescription,
35
- DialogHeader,
36
- DialogTitle,
37
- Input$1,
38
48
  PROVIDER_METADATA,
39
49
  ProviderBrandIcon,
40
- Select$1,
41
50
  formatProviderLabel,
42
- normalizeScrollOffset,
43
- notify,
44
- styleDisableScrollbar,
45
- useBaseUiId,
46
- useCSPContext,
47
51
  useChatPanelDataContext,
48
52
  useSettingsActionsContext
49
- } from "./chunk-5GUEYYYO.js";
53
+ } from "./chunk-37EK2TYH.js";
54
+ import "./chunk-QOZCYKMA.js";
55
+ import "./chunk-5MOXRFX6.js";
56
+ import "./chunk-RX2ZJARF.js";
57
+ import "./chunk-C5XHGLET.js";
58
+ import "./chunk-CE7U5QB2.js";
50
59
  import {
51
- addEventListener,
52
60
  applyUiPreferencesToDocument,
53
- clamp,
54
- contains,
55
- getTarget,
56
61
  isCustomProviderId,
57
62
  isNamedOccInstanceId,
58
63
  isOccProviderId,
59
- parts_exports,
60
64
  readUiPreferences,
61
- useDirection,
62
- useTimeout,
63
65
  writeUiPreferences
64
- } from "./chunk-OSPDNT7S.js";
66
+ } from "./chunk-6GYLXDX3.js";
67
+ import "./chunk-NZCEQWK2.js";
68
+ import "./chunk-7DQQMT5V.js";
69
+ import "./chunk-BD7YKYWL.js";
65
70
  import {
66
- COMPACT_ACTION_BUTTON_CLASS,
67
71
  HIT_AREA_EXPAND_CLASS,
68
72
  HIT_AREA_EXPAND_DENSE_CLASS,
69
- rowSurface
70
- } from "./chunk-2PAW6K4Q.js";
73
+ Select$1,
74
+ normalizeScrollOffset,
75
+ notify,
76
+ styleDisableScrollbar,
77
+ useBaseUiId,
78
+ useCSPContext
79
+ } from "./chunk-TXZDDJCT.js";
80
+ import {
81
+ addEventListener,
82
+ clamp,
83
+ contains,
84
+ getTarget,
85
+ parts_exports,
86
+ useDirection,
87
+ useTimeout
88
+ } from "./chunk-APOS34PW.js";
89
+ import "./chunk-OO7NBFQQ.js";
71
90
  import {
72
91
  Button$1,
73
92
  formatErrorMessage_default,
74
93
  useIsoLayoutEffect,
75
94
  useRenderElement,
76
95
  useStableCallback
77
- } from "./chunk-2FHYWKDN.js";
78
- import "./chunk-FB3UHLLN.js";
96
+ } from "./chunk-FSQWWR2M.js";
79
97
  import {
80
98
  ArrowLeft,
81
99
  Box,
82
- Check,
83
100
  ChevronRight,
84
101
  Cpu,
85
- ExternalLink,
86
102
  Eye,
87
103
  EyeOff,
88
104
  Globe,
@@ -91,7 +107,6 @@ import {
91
107
  KeyRound,
92
108
  Keyboard,
93
109
  Layers,
94
- LoaderCircle,
95
110
  Lock,
96
111
  MessageSquare,
97
112
  Monitor,
@@ -101,8 +116,6 @@ import {
101
116
  Plug,
102
117
  Plus,
103
118
  RefreshCw,
104
- RotateCcw,
105
- Save,
106
119
  Search,
107
120
  Settings,
108
121
  Sparkles,
@@ -110,19 +123,17 @@ import {
110
123
  Sun,
111
124
  Tag,
112
125
  Trash,
113
- Users
114
- } from "./chunk-7L5PCCYR.js";
115
- import {
126
+ Users,
116
127
  cn
117
- } from "./chunk-OAYEN3JV.js";
128
+ } from "./chunk-VDEUVEWL.js";
118
129
  import "./chunk-6JOAWERA.js";
119
- import "./chunk-2VKVSL6Y.js";
130
+ import "./chunk-35RIM6VP.js";
120
131
  import "./chunk-NXAVRSI5.js";
121
132
  import {
122
133
  __export
123
134
  } from "./chunk-CZ7CSFO4.js";
124
135
 
125
- // web/app/dist/server/assets/settings-dialog-BUgVNpr1.js
136
+ // web/app/dist/server/assets/settings-dialog-DkesVBrS.js
126
137
  import { createContext as createContext4, forwardRef as forwardRef7, useCallback, useContext as useContext4, useEffect as useEffect2, useId, useMemo as useMemo3, useRef as useRef4, useState as useState2 } from "react";
127
138
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
128
139
 
@@ -1089,7 +1100,7 @@ var ScrollAreaCorner = /* @__PURE__ */ React9.forwardRef(function ScrollAreaCorn
1089
1100
  });
1090
1101
  if (process.env.NODE_ENV !== "production") ScrollAreaCorner.displayName = "ScrollAreaCorner";
1091
1102
 
1092
- // web/app/dist/server/assets/settings-dialog-BUgVNpr1.js
1103
+ // web/app/dist/server/assets/settings-dialog-DkesVBrS.js
1093
1104
  function isFieldInvalid(value, attemptedSave, required = true) {
1094
1105
  return attemptedSave && required && value.trim().length === 0;
1095
1106
  }
@@ -1278,700 +1289,6 @@ function ComposerIntentSection({ enabled, keySource, status, onClearKey, onEnabl
1278
1289
  })]
1279
1290
  });
1280
1291
  }
1281
- function RowSurface({ className, interactive, padding, tone, ...props }) {
1282
- return /* @__PURE__ */ jsx("div", {
1283
- className: cn(rowSurface({
1284
- interactive,
1285
- padding,
1286
- tone
1287
- }), className),
1288
- ...props
1289
- });
1290
- }
1291
- function ItemRow({ icon, title, subtitle, trailing, className, interactive = true, tone = "default", truncateSubtitle = true, truncateTitle = true }) {
1292
- return /* @__PURE__ */ jsxs(RowSurface, {
1293
- tone,
1294
- padding: "md",
1295
- interactive,
1296
- className: cn("items-center gap-3", className),
1297
- children: [
1298
- icon ? /* @__PURE__ */ jsx("div", {
1299
- className: "flex size-8 shrink-0 items-center justify-center rounded-md border border-border/40 bg-background/60 text-foreground/70",
1300
- children: icon
1301
- }) : null,
1302
- /* @__PURE__ */ jsxs("div", {
1303
- className: "min-w-0 flex-1",
1304
- children: [/* @__PURE__ */ jsx("div", {
1305
- className: cn("text-sm font-medium text-foreground", truncateTitle && "truncate"),
1306
- children: title
1307
- }), subtitle ? /* @__PURE__ */ jsx("div", {
1308
- className: cn("mt-0.5 text-xs text-muted-foreground", truncateSubtitle ? "truncate" : "leading-normal"),
1309
- children: subtitle
1310
- }) : null]
1311
- }),
1312
- trailing ? /* @__PURE__ */ jsx("div", {
1313
- className: "flex shrink-0 items-center gap-1.5",
1314
- children: trailing
1315
- }) : null
1316
- ]
1317
- });
1318
- }
1319
- function SettingsPane({ actions, children, description, title }) {
1320
- return /* @__PURE__ */ jsxs("div", {
1321
- className: "flex flex-col gap-4",
1322
- children: [/* @__PURE__ */ jsxs("div", {
1323
- className: "flex items-start justify-between gap-3",
1324
- children: [/* @__PURE__ */ jsxs("div", {
1325
- className: "min-w-0 flex-1",
1326
- children: [/* @__PURE__ */ jsx("h3", {
1327
- className: "text-lg font-medium text-balance",
1328
- children: title
1329
- }), /* @__PURE__ */ jsx("p", {
1330
- className: "mt-1 text-sm text-pretty text-muted-foreground",
1331
- children: description
1332
- })]
1333
- }), actions ? /* @__PURE__ */ jsx("div", {
1334
- className: "flex shrink-0 items-center gap-1.5 pt-0.5",
1335
- children: actions
1336
- }) : null]
1337
- }), /* @__PURE__ */ jsx("div", {
1338
- className: "flex flex-col gap-3",
1339
- children
1340
- })]
1341
- });
1342
- }
1343
- function SettingsCommitActions({ dirty, disabled, onRevert, onSave, saving }) {
1344
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [dirty ? /* @__PURE__ */ jsx(Button$1, {
1345
- type: "button",
1346
- variant: "ghost",
1347
- size: "icon-compact",
1348
- className: "text-muted-foreground transition-transform active:scale-[0.96]",
1349
- disabled: disabled || saving,
1350
- onClick: onRevert,
1351
- "aria-label": "Revert changes",
1352
- children: /* @__PURE__ */ jsx(RotateCcw, {})
1353
- }) : null, /* @__PURE__ */ jsxs(Button$1, {
1354
- type: "button",
1355
- variant: "outline",
1356
- size: "compact",
1357
- className: cn(COMPACT_ACTION_BUTTON_CLASS, "transition-transform active:scale-[0.96]", dirty && "border-primary/30 text-primary"),
1358
- disabled: !dirty || disabled || saving,
1359
- onClick: onSave,
1360
- children: [saving ? /* @__PURE__ */ jsx(LoaderCircle, {
1361
- className: "animate-spin",
1362
- "data-icon": "inline-start"
1363
- }) : /* @__PURE__ */ jsx(Save, { "data-icon": "inline-start" }), "Commit"]
1364
- })] });
1365
- }
1366
- var OAUTH_POLL_MS = 1500;
1367
- var STALE_LOGIN_ERROR = "Unknown or expired OAuth login";
1368
- function delay(ms) {
1369
- return new Promise((resolve) => {
1370
- setTimeout(resolve, ms);
1371
- });
1372
- }
1373
- function useOAuthLoginFlow({ onConfigured, onOAuthLogin, providerId }) {
1374
- const [login, setLogin] = useState2(null);
1375
- const [busy, setBusy] = useState2(false);
1376
- const [promptAnswer, setPromptAnswer] = useState2("");
1377
- const loginIdRef = useRef4(null);
1378
- const generationRef = useRef4(0);
1379
- const startingRef = useRef4(false);
1380
- const onOAuthLoginRef = useRef4(onOAuthLogin);
1381
- const onConfiguredRef = useRef4(onConfigured);
1382
- const providerIdRef = useRef4(providerId);
1383
- useEffect2(() => {
1384
- onOAuthLoginRef.current = onOAuthLogin;
1385
- onConfiguredRef.current = onConfigured;
1386
- providerIdRef.current = providerId;
1387
- }, [
1388
- onConfigured,
1389
- onOAuthLogin,
1390
- providerId
1391
- ]);
1392
- const cancelLoginId = useCallback(async (loginId) => {
1393
- if (!loginId || !onOAuthLoginRef.current) return;
1394
- try {
1395
- await onOAuthLoginRef.current({
1396
- providerId: providerIdRef.current,
1397
- loginId,
1398
- cancel: true
1399
- });
1400
- } catch {
1401
- }
1402
- }, []);
1403
- const resetLocal = useCallback(() => {
1404
- loginIdRef.current = null;
1405
- startingRef.current = false;
1406
- setLogin(null);
1407
- setPromptAnswer("");
1408
- setBusy(false);
1409
- }, []);
1410
- useEffect2(() => {
1411
- return () => {
1412
- generationRef.current += 1;
1413
- const loginId = loginIdRef.current;
1414
- loginIdRef.current = null;
1415
- cancelLoginId(loginId);
1416
- };
1417
- }, [cancelLoginId]);
1418
- const applyResult = useCallback((result, generation) => {
1419
- if (generation !== generationRef.current) {
1420
- if (result.status === "waiting" && result.loginId) cancelLoginId(result.loginId);
1421
- return;
1422
- }
1423
- if (result.status === "success") {
1424
- loginIdRef.current = null;
1425
- setLogin(null);
1426
- setPromptAnswer("");
1427
- setBusy(false);
1428
- notify.success("Provider credentials applied to your active sessions.");
1429
- onConfiguredRef.current?.();
1430
- return;
1431
- }
1432
- if (result.status === "error") {
1433
- if (result.error === STALE_LOGIN_ERROR && loginIdRef.current === null) return;
1434
- const loginId = loginIdRef.current;
1435
- loginIdRef.current = null;
1436
- if (loginId && result.error !== "Login cancelled") cancelLoginId(loginId);
1437
- setLogin(result);
1438
- setBusy(false);
1439
- return;
1440
- }
1441
- if (result.loginId) loginIdRef.current = result.loginId;
1442
- setLogin(result);
1443
- }, [cancelLoginId]);
1444
- const start = useCallback(async () => {
1445
- if (!onOAuthLoginRef.current || startingRef.current) return;
1446
- startingRef.current = true;
1447
- const generation = generationRef.current;
1448
- setBusy(true);
1449
- const previous = loginIdRef.current;
1450
- loginIdRef.current = null;
1451
- setLogin(null);
1452
- await cancelLoginId(previous);
1453
- if (generation !== generationRef.current) {
1454
- startingRef.current = false;
1455
- return;
1456
- }
1457
- try {
1458
- const result = await onOAuthLoginRef.current({ providerId: providerIdRef.current });
1459
- applyResult(result, generation);
1460
- } catch (error) {
1461
- if (generation !== generationRef.current) return;
1462
- setLogin({
1463
- status: "error",
1464
- error: error instanceof Error ? error.message : "Failed to start OAuth sign-in"
1465
- });
1466
- } finally {
1467
- startingRef.current = false;
1468
- if (generation === generationRef.current) setBusy(false);
1469
- }
1470
- }, [applyResult, cancelLoginId]);
1471
- const submitPrompt = useCallback(async () => {
1472
- const loginId = loginIdRef.current;
1473
- if (!onOAuthLoginRef.current || !loginId) return;
1474
- const generation = generationRef.current;
1475
- setBusy(true);
1476
- try {
1477
- const result = await onOAuthLoginRef.current({
1478
- providerId: providerIdRef.current,
1479
- loginId,
1480
- promptAnswer
1481
- });
1482
- setPromptAnswer("");
1483
- applyResult(result, generation);
1484
- } catch (error) {
1485
- if (generation !== generationRef.current) return;
1486
- notify.error(error instanceof Error ? error.message : "Failed to continue OAuth sign-in");
1487
- } finally {
1488
- if (generation === generationRef.current) setBusy(false);
1489
- }
1490
- }, [applyResult, promptAnswer]);
1491
- const cancel = useCallback(async () => {
1492
- generationRef.current += 1;
1493
- const loginId = loginIdRef.current;
1494
- resetLocal();
1495
- await cancelLoginId(loginId);
1496
- }, [cancelLoginId, resetLocal]);
1497
- useEffect2(() => {
1498
- if (!onOAuthLoginRef.current) return;
1499
- if (login?.status !== "waiting" || !login.loginId) return;
1500
- const generation = generationRef.current;
1501
- const loginId = login.loginId;
1502
- let stopped = false;
1503
- const poll = async () => {
1504
- while (!stopped) {
1505
- try {
1506
- const result = await onOAuthLoginRef.current({
1507
- providerId: providerIdRef.current,
1508
- loginId
1509
- });
1510
- if (stopped || generation !== generationRef.current) return;
1511
- applyResult(result, generation);
1512
- if (result.status !== "waiting") return;
1513
- } catch (error) {
1514
- if (stopped || generation !== generationRef.current) return;
1515
- if (loginIdRef.current !== loginId) return;
1516
- loginIdRef.current = null;
1517
- cancelLoginId(loginId);
1518
- setLogin({
1519
- status: "error",
1520
- error: error instanceof Error ? error.message : "OAuth sign-in failed"
1521
- });
1522
- return;
1523
- }
1524
- await delay(OAUTH_POLL_MS);
1525
- if (stopped || generation !== generationRef.current) return;
1526
- if (loginIdRef.current !== loginId) return;
1527
- }
1528
- };
1529
- poll();
1530
- return () => {
1531
- stopped = true;
1532
- };
1533
- }, [
1534
- applyResult,
1535
- cancelLoginId,
1536
- login?.loginId,
1537
- login?.status
1538
- ]);
1539
- return {
1540
- busy,
1541
- cancel,
1542
- canStart: Boolean(onOAuthLogin),
1543
- login,
1544
- promptAnswer,
1545
- setPromptAnswer,
1546
- start,
1547
- submitPrompt
1548
- };
1549
- }
1550
- function ProviderOAuthSignIn({ onConfigured, onOAuthLogin, provider }) {
1551
- const { busy, cancel, canStart, login, promptAnswer, setPromptAnswer, start, submitPrompt } = useOAuthLoginFlow({
1552
- onConfigured,
1553
- onOAuthLogin,
1554
- providerId: provider.id
1555
- });
1556
- const waiting = login?.status === "waiting";
1557
- const error = login?.status === "error" ? login.error : void 0;
1558
- const authUrl = waiting ? login?.authUrl : void 0;
1559
- const userCode = waiting ? login?.userCode : void 0;
1560
- const instructions = waiting ? login?.instructions : void 0;
1561
- const prompt = waiting ? login?.prompt : void 0;
1562
- const oauthOnly = provider.authType === "oauth";
1563
- return /* @__PURE__ */ jsxs("div", {
1564
- className: "flex flex-col gap-3",
1565
- children: [provider.isConfigured && oauthOnly && !waiting ? /* @__PURE__ */ jsxs("div", {
1566
- className: "flex items-center gap-2 text-sm",
1567
- children: [/* @__PURE__ */ jsx(Check, { className: "size-3.5 text-muted-foreground" }), /* @__PURE__ */ jsx("span", { children: "Connected" })]
1568
- }) : null, waiting ? /* @__PURE__ */ jsxs("div", {
1569
- className: "flex flex-col gap-2",
1570
- children: [
1571
- /* @__PURE__ */ jsxs("p", {
1572
- className: "text-sm",
1573
- children: [
1574
- "Sign in with ",
1575
- provider.name,
1576
- " to store OAuth credentials for this account."
1577
- ]
1578
- }),
1579
- userCode ? /* @__PURE__ */ jsxs("p", {
1580
- className: "text-sm",
1581
- children: ["Enter this code: ", /* @__PURE__ */ jsx("span", {
1582
- className: "font-mono text-foreground",
1583
- children: userCode
1584
- })]
1585
- }) : null,
1586
- instructions && !userCode ? /* @__PURE__ */ jsx("p", {
1587
- className: "text-xs text-pretty text-muted-foreground",
1588
- children: instructions
1589
- }) : null,
1590
- authUrl ? /* @__PURE__ */ jsxs(Button$1, {
1591
- type: "button",
1592
- size: "compact",
1593
- onClick: () => {
1594
- window.open(authUrl, "_blank", "noopener,noreferrer");
1595
- },
1596
- children: [/* @__PURE__ */ jsx(ExternalLink, { "data-icon": "inline-start" }), "Open sign-in page"]
1597
- }) : prompt ? null : /* @__PURE__ */ jsxs("div", {
1598
- className: "flex items-center gap-2 text-xs text-muted-foreground",
1599
- children: [/* @__PURE__ */ jsx(Spinner, { className: "size-3" }), "Waiting for sign-in\u2026"]
1600
- }),
1601
- prompt ? /* @__PURE__ */ jsxs("div", {
1602
- className: "flex flex-col gap-2",
1603
- children: [
1604
- /* @__PURE__ */ jsx("p", {
1605
- className: "text-xs text-pretty text-muted-foreground",
1606
- children: prompt.message
1607
- }),
1608
- /* @__PURE__ */ jsx(Input$1, {
1609
- value: promptAnswer,
1610
- placeholder: prompt.placeholder,
1611
- onChange: (event) => setPromptAnswer(event.target.value),
1612
- "aria-label": prompt.message
1613
- }),
1614
- /* @__PURE__ */ jsx("div", {
1615
- className: "flex justify-end",
1616
- children: /* @__PURE__ */ jsxs(Button$1, {
1617
- type: "button",
1618
- size: "compact",
1619
- disabled: busy || !prompt.allowEmpty && !promptAnswer.trim(),
1620
- onClick: () => {
1621
- submitPrompt();
1622
- },
1623
- children: [busy ? /* @__PURE__ */ jsx(Spinner, { "data-icon": "inline-start" }) : null, "Continue"]
1624
- })
1625
- })
1626
- ]
1627
- }) : null,
1628
- /* @__PURE__ */ jsx("div", {
1629
- className: "flex justify-end",
1630
- children: /* @__PURE__ */ jsx(Button$1, {
1631
- type: "button",
1632
- variant: "ghost",
1633
- size: "compact",
1634
- disabled: busy,
1635
- onClick: () => {
1636
- cancel();
1637
- },
1638
- children: "Cancel sign-in"
1639
- })
1640
- })
1641
- ]
1642
- }) : /* @__PURE__ */ jsxs("div", {
1643
- className: "flex flex-col gap-2",
1644
- children: [error ? /* @__PURE__ */ jsx(Alert, {
1645
- className: "px-3 py-2",
1646
- children: /* @__PURE__ */ jsx(AlertDescription, {
1647
- className: "text-xs text-pretty",
1648
- children: error
1649
- })
1650
- }) : /* @__PURE__ */ jsx("p", {
1651
- className: "text-xs text-pretty text-muted-foreground",
1652
- children: oauthOnly && provider.isConfigured ? `Sign in again with ${provider.name} to refresh OAuth credentials.` : oauthOnly ? `Sign in with ${provider.name}. No API key is stored; credentials are saved to auth.json.` : `Sign in with ${provider.name} to use OAuth credentials; API-key editing remains available above.`
1653
- }), /* @__PURE__ */ jsx("div", {
1654
- className: "flex justify-end",
1655
- children: /* @__PURE__ */ jsxs(Button$1, {
1656
- type: "button",
1657
- size: "compact",
1658
- disabled: busy || !canStart,
1659
- onClick: () => {
1660
- start();
1661
- },
1662
- children: [
1663
- busy ? /* @__PURE__ */ jsx(Spinner, { "data-icon": "inline-start" }) : null,
1664
- "Sign in with ",
1665
- provider.name
1666
- ]
1667
- })
1668
- })]
1669
- })]
1670
- });
1671
- }
1672
- function Textarea({ className, ...props }) {
1673
- return /* @__PURE__ */ jsx("textarea", {
1674
- "data-slot": "textarea",
1675
- className: cn("flex field-sizing-content min-h-16 w-full rounded-lg border border-input bg-transparent px-2.5 py-2 text-base transition-colors outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40", className),
1676
- ...props
1677
- });
1678
- }
1679
- function statusLabel(connection) {
1680
- switch (connection.status) {
1681
- case "connected":
1682
- return "Connected";
1683
- case "anonymous":
1684
- return "Available without sign-in";
1685
- case "needs_auth":
1686
- return "Sign-in required";
1687
- case "disabled":
1688
- return "Disabled";
1689
- default:
1690
- return connection.status;
1691
- }
1692
- }
1693
- function connectionSubtitle(connection) {
1694
- const details = connection.transport === "http" ? connection.url : connection.commandPreview;
1695
- return [
1696
- connection.source === "builtin" ? "Built-in" : "User",
1697
- connection.transport === "http" ? "HTTP" : "stdio",
1698
- statusLabel(connection),
1699
- details
1700
- ].filter((part) => Boolean(part)).join(" \xB7 ");
1701
- }
1702
- function McpConnectionsSection({ connections, isLoading, isPending, onOAuth, onRemove, onUpsert }) {
1703
- const [adding, setAdding] = useState2(false);
1704
- const [transport, setTransport] = useState2("http");
1705
- const [name, setName] = useState2("");
1706
- const [url, setUrl] = useState2("");
1707
- const [oauth, setOauth] = useState2(true);
1708
- const [bearerTokenEnvVar, setBearerTokenEnvVar] = useState2("");
1709
- const [command, setCommand] = useState2("");
1710
- const [args, setArgs] = useState2("");
1711
- const [cwd, setCwd] = useState2("");
1712
- const [envLines, setEnvLines] = useState2("");
1713
- const [confirmRemove, setConfirmRemove] = useState2(null);
1714
- const resetAddForm = () => {
1715
- setName("");
1716
- setUrl("");
1717
- setOauth(true);
1718
- setBearerTokenEnvVar("");
1719
- setCommand("");
1720
- setArgs("");
1721
- setCwd("");
1722
- setEnvLines("");
1723
- setTransport("http");
1724
- setAdding(false);
1725
- };
1726
- const handleAdd = async () => {
1727
- if (!onUpsert) return;
1728
- const trimmedName = name.trim();
1729
- try {
1730
- if (transport === "http") await onUpsert({
1731
- name: trimmedName,
1732
- transport: "http",
1733
- url: url.trim(),
1734
- ...oauth ? { oauth: true } : {},
1735
- ...bearerTokenEnvVar.trim() ? { bearerTokenEnvVar: bearerTokenEnvVar.trim() } : {},
1736
- force: true
1737
- });
1738
- else {
1739
- const parsedArgs = args.split(/\s+/).map((part) => part.trim()).filter(Boolean);
1740
- const env = envLines.split("\n").map((line) => line.trim()).filter(Boolean).flatMap((line) => {
1741
- const equals = line.indexOf("=");
1742
- if (equals <= 0) return [];
1743
- const child = line.slice(0, equals).trim();
1744
- const source = line.slice(equals + 1).trim();
1745
- if (!child || !source) return [];
1746
- return [{
1747
- child,
1748
- source
1749
- }];
1750
- });
1751
- await onUpsert({
1752
- name: trimmedName,
1753
- transport: "stdio",
1754
- command: command.trim(),
1755
- ...parsedArgs.length > 0 ? { args: parsedArgs } : {},
1756
- ...cwd.trim() ? { cwd: cwd.trim() } : {},
1757
- ...env.length > 0 ? { env } : {},
1758
- force: true
1759
- });
1760
- }
1761
- notify.success("MCP connection saved");
1762
- resetAddForm();
1763
- } catch (error) {
1764
- notify.error(error instanceof Error ? error.message : "Could not save MCP connection");
1765
- }
1766
- };
1767
- const handleRemove = async (connectionName) => {
1768
- if (!onRemove) return;
1769
- try {
1770
- await onRemove({ name: connectionName });
1771
- notify.success(`Removed ${connectionName}`);
1772
- setConfirmRemove(null);
1773
- } catch (error) {
1774
- notify.error(error instanceof Error ? error.message : "Could not remove MCP connection");
1775
- }
1776
- };
1777
- const handleLogout = async (connectionName) => {
1778
- if (!onOAuth) return;
1779
- try {
1780
- await onOAuth({
1781
- name: connectionName,
1782
- action: "logout"
1783
- });
1784
- notify.success(`Signed out of ${connectionName}`);
1785
- } catch (error) {
1786
- notify.error(error instanceof Error ? error.message : "Could not sign out");
1787
- }
1788
- };
1789
- const oauthAdapter = useMemo3(() => {
1790
- if (!onOAuth) return void 0;
1791
- return (connection) => async (request) => {
1792
- const starting = !request.loginId && !request.cancel;
1793
- return await onOAuth({
1794
- name: connection.name,
1795
- action: starting && connection.status === "connected" ? "reconnect" : "login",
1796
- loginId: request.loginId,
1797
- promptAnswer: request.promptAnswer,
1798
- cancel: request.cancel
1799
- });
1800
- };
1801
- }, [onOAuth]);
1802
- return /* @__PURE__ */ jsxs(SettingsPane, {
1803
- title: "MCP",
1804
- description: "Connect built-in and user MCP servers. Tokens stay on the server; this list only shows status and environment-variable names.",
1805
- actions: /* @__PURE__ */ jsxs(Button$1, {
1806
- type: "button",
1807
- size: "compact",
1808
- variant: "outline",
1809
- disabled: isPending || adding,
1810
- onClick: () => setAdding(true),
1811
- children: [/* @__PURE__ */ jsx(Plus, { "data-icon": "inline-start" }), "Add server"]
1812
- }),
1813
- children: [
1814
- isLoading ? /* @__PURE__ */ jsxs("div", {
1815
- className: "flex items-center gap-2 text-sm text-muted-foreground",
1816
- children: [/* @__PURE__ */ jsx(Spinner, { className: "size-3.5" }), "Loading MCP connections\u2026"]
1817
- }) : null,
1818
- adding ? /* @__PURE__ */ jsxs("div", {
1819
- className: "flex flex-col gap-3 rounded-xl border p-4",
1820
- children: [
1821
- /* @__PURE__ */ jsxs(Field, { children: [/* @__PURE__ */ jsx(FieldLabel, { children: "Name" }), /* @__PURE__ */ jsx(Input$1, {
1822
- value: name,
1823
- onChange: (event) => setName(event.target.value),
1824
- "aria-label": "MCP server name"
1825
- })] }),
1826
- /* @__PURE__ */ jsxs(Field, { children: [/* @__PURE__ */ jsx(FieldLabel, { children: "Transport" }), /* @__PURE__ */ jsx(Select$1, {
1827
- value: transport,
1828
- onValueChange: (value) => setTransport(value),
1829
- options: [{
1830
- label: "HTTP",
1831
- value: "http"
1832
- }, {
1833
- label: "stdio",
1834
- value: "stdio"
1835
- }]
1836
- })] }),
1837
- transport === "http" ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
1838
- /* @__PURE__ */ jsxs(Field, { children: [/* @__PURE__ */ jsx(FieldLabel, { children: "URL" }), /* @__PURE__ */ jsx(Input$1, {
1839
- value: url,
1840
- onChange: (event) => setUrl(event.target.value),
1841
- "aria-label": "MCP server URL"
1842
- })] }),
1843
- /* @__PURE__ */ jsxs(Field, {
1844
- orientation: "horizontal",
1845
- className: "items-center justify-between",
1846
- children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(FieldLabel, { children: "OAuth" }), /* @__PURE__ */ jsx(FieldDescription, { children: "Use the browser sign-in flow for this server." })] }), /* @__PURE__ */ jsx(Switch$1, {
1847
- checked: oauth,
1848
- onCheckedChange: (checked) => setOauth(checked),
1849
- "aria-label": "Use OAuth"
1850
- })]
1851
- }),
1852
- !oauth ? /* @__PURE__ */ jsxs(Field, { children: [/* @__PURE__ */ jsx(FieldLabel, { children: "Bearer token environment variable" }), /* @__PURE__ */ jsx(Input$1, {
1853
- value: bearerTokenEnvVar,
1854
- onChange: (event) => setBearerTokenEnvVar(event.target.value),
1855
- "aria-label": "Bearer token environment variable",
1856
- placeholder: "MCP_BEARER_TOKEN"
1857
- })] }) : null
1858
- ] }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
1859
- /* @__PURE__ */ jsxs(Field, { children: [/* @__PURE__ */ jsx(FieldLabel, { children: "Command" }), /* @__PURE__ */ jsx(Input$1, {
1860
- value: command,
1861
- onChange: (event) => setCommand(event.target.value),
1862
- "aria-label": "MCP command"
1863
- })] }),
1864
- /* @__PURE__ */ jsxs(Field, { children: [/* @__PURE__ */ jsx(FieldLabel, { children: "Arguments" }), /* @__PURE__ */ jsx(Input$1, {
1865
- value: args,
1866
- onChange: (event) => setArgs(event.target.value),
1867
- "aria-label": "MCP command arguments"
1868
- })] }),
1869
- /* @__PURE__ */ jsxs(Field, { children: [
1870
- /* @__PURE__ */ jsx(FieldLabel, { children: "Working directory" }),
1871
- /* @__PURE__ */ jsx(Input$1, {
1872
- value: cwd,
1873
- onChange: (event) => setCwd(event.target.value),
1874
- "aria-label": "MCP working directory"
1875
- }),
1876
- /* @__PURE__ */ jsx(FieldDescription, { children: "Must stay inside the current workspace." })
1877
- ] }),
1878
- /* @__PURE__ */ jsxs(Field, { children: [
1879
- /* @__PURE__ */ jsx(FieldLabel, { children: "Environment mappings" }),
1880
- /* @__PURE__ */ jsx(Textarea, {
1881
- value: envLines,
1882
- onChange: (event) => setEnvLines(event.target.value),
1883
- "aria-label": "MCP environment mappings",
1884
- placeholder: "CHILD=SOURCE"
1885
- }),
1886
- /* @__PURE__ */ jsx(FieldDescription, { children: "One CHILD=SOURCE pair per line. Only variable names are stored." })
1887
- ] })
1888
- ] }),
1889
- /* @__PURE__ */ jsxs("div", {
1890
- className: "flex justify-end gap-2",
1891
- children: [/* @__PURE__ */ jsx(Button$1, {
1892
- type: "button",
1893
- size: "compact",
1894
- variant: "ghost",
1895
- onClick: resetAddForm,
1896
- children: "Cancel"
1897
- }), /* @__PURE__ */ jsxs(Button$1, {
1898
- type: "button",
1899
- size: "compact",
1900
- disabled: isPending || !name.trim(),
1901
- onClick: () => void handleAdd(),
1902
- children: [isPending ? /* @__PURE__ */ jsx(Spinner, { "data-icon": "inline-start" }) : null, "Save"]
1903
- })]
1904
- })
1905
- ]
1906
- }) : null,
1907
- !isLoading && connections.length === 0 && !adding ? /* @__PURE__ */ jsx("p", {
1908
- className: "text-sm text-muted-foreground",
1909
- children: "No MCP connections yet."
1910
- }) : null,
1911
- /* @__PURE__ */ jsx("div", {
1912
- className: "flex flex-col gap-2",
1913
- children: connections.map((connection) => /* @__PURE__ */ jsxs("div", {
1914
- className: "flex flex-col gap-2",
1915
- children: [
1916
- /* @__PURE__ */ jsx(ItemRow, {
1917
- icon: /* @__PURE__ */ jsx(Plug, { className: "size-4" }),
1918
- title: connection.label,
1919
- subtitle: connectionSubtitle(connection),
1920
- trailing: /* @__PURE__ */ jsxs("div", {
1921
- className: "flex items-center gap-1.5",
1922
- children: [connection.usesOAuth && connection.status !== "needs_auth" ? /* @__PURE__ */ jsx(Button$1, {
1923
- type: "button",
1924
- size: "compact",
1925
- variant: "ghost",
1926
- disabled: isPending || !onOAuth,
1927
- onClick: () => {
1928
- handleLogout(connection.name);
1929
- },
1930
- children: "Sign out"
1931
- }) : null, connection.source === "user" ? confirmRemove === connection.name ? /* @__PURE__ */ jsx(Button$1, {
1932
- type: "button",
1933
- size: "compact",
1934
- variant: "destructive",
1935
- disabled: isPending,
1936
- onClick: () => {
1937
- handleRemove(connection.name);
1938
- },
1939
- children: "Confirm remove"
1940
- }) : /* @__PURE__ */ jsx(Button$1, {
1941
- type: "button",
1942
- size: "compact",
1943
- variant: "ghost",
1944
- disabled: isPending || !onRemove,
1945
- "aria-label": `Remove ${connection.name}`,
1946
- onClick: () => setConfirmRemove(connection.name),
1947
- children: /* @__PURE__ */ jsx(Trash, { className: "size-3.5" })
1948
- }) : null]
1949
- })
1950
- }),
1951
- connection.error ? /* @__PURE__ */ jsx(Alert, {
1952
- className: "px-3 py-2",
1953
- children: /* @__PURE__ */ jsx(AlertDescription, {
1954
- className: "text-xs text-pretty",
1955
- children: connection.error
1956
- })
1957
- }) : null,
1958
- connection.usesOAuth && oauthAdapter ? /* @__PURE__ */ jsx(ProviderOAuthSignIn, {
1959
- provider: {
1960
- id: connection.name,
1961
- name: connection.label,
1962
- isConfigured: connection.status === "connected",
1963
- envVarName: "",
1964
- authType: "oauth",
1965
- supportsOAuth: true
1966
- },
1967
- onOAuthLogin: oauthAdapter(connection)
1968
- }) : null
1969
- ]
1970
- }, `${connection.source}:${connection.name}`))
1971
- })
1972
- ]
1973
- });
1974
- }
1975
1292
  var THEME_OPTIONS = [
1976
1293
  {
1977
1294
  value: "system",
@@ -2043,6 +1360,46 @@ function AddModelsDialog({ configuredProviderIds, discoverableProviderIds, disco
2043
1360
  const [filter, setFilter] = useState2("");
2044
1361
  const [selectedKeys, setSelectedKeys] = useState2(/* @__PURE__ */ new Set());
2045
1362
  const normalizedFilter = filter.trim().toLowerCase();
1363
+ const [discovery, setDiscovery] = useState2({});
1364
+ const discoveryRef = useRef4(discovery);
1365
+ const discoverCallback = useRef4(onDiscoverProvider);
1366
+ useEffect2(() => {
1367
+ discoverCallback.current = onDiscoverProvider;
1368
+ }, [onDiscoverProvider]);
1369
+ const refreshProvider = useCallback(async (id, force = false) => {
1370
+ const previous = discoveryRef.current[id];
1371
+ if (previous?.loading || !force && previous?.updatedAt && Date.now() - previous.updatedAt < 6e4) return;
1372
+ const update = (value) => {
1373
+ discoveryRef.current = {
1374
+ ...discoveryRef.current,
1375
+ [id]: value ?? {}
1376
+ };
1377
+ setDiscovery(discoveryRef.current);
1378
+ };
1379
+ update({
1380
+ ...previous,
1381
+ loading: true,
1382
+ error: false
1383
+ });
1384
+ try {
1385
+ await discoverCallback.current(id);
1386
+ update({ updatedAt: Date.now() });
1387
+ } catch {
1388
+ update({
1389
+ loading: false,
1390
+ error: true
1391
+ });
1392
+ }
1393
+ }, []);
1394
+ const discoveryIds = [...discoverableProviderIds ?? []].filter((id) => configuredProviderIds.has(id)).sort((a, b) => a.localeCompare(b)).join("\n");
1395
+ useEffect2(() => {
1396
+ if (!open) return;
1397
+ for (const id of discoveryIds.split("\n").filter(Boolean)) refreshProvider(id);
1398
+ }, [
1399
+ open,
1400
+ discoveryIds,
1401
+ refreshProvider
1402
+ ]);
2046
1403
  const candidateModels = useMemo3(() => {
2047
1404
  return modelOptions.filter((model) => {
2048
1405
  if (!configuredProviderIds.has(model.provider)) return false;
@@ -2088,49 +1445,61 @@ function AddModelsDialog({ configuredProviderIds, discoverableProviderIds, disco
2088
1445
  const confirmAdd = () => {
2089
1446
  const selected = candidateModels.filter((model) => selectedKeys.has(model.id));
2090
1447
  if (selected.length > 0) onAddModels(selected);
1448
+ setSelectedKeys(/* @__PURE__ */ new Set());
2091
1449
  onOpenChange(false);
2092
1450
  };
2093
1451
  return /* @__PURE__ */ jsx(Dialog$1, {
2094
1452
  open,
2095
- onOpenChange,
1453
+ onOpenChange: (next) => {
1454
+ if (!next) setSelectedKeys(/* @__PURE__ */ new Set());
1455
+ onOpenChange(next);
1456
+ },
2096
1457
  children: /* @__PURE__ */ jsxs(DialogContent, {
2097
- className: "max-w-lg",
1458
+ className: "flex max-h-[calc(100dvh-2rem)] min-w-0 max-w-[calc(100%-2rem)] sm:max-w-lg flex-col overflow-hidden",
2098
1459
  children: [
2099
- /* @__PURE__ */ jsxs(DialogHeader, { children: [/* @__PURE__ */ jsx(DialogTitle, { children: "Add models" }), /* @__PURE__ */ jsxs(DialogDescription, { children: [
2100
- "Pick models discovered from your configured providers. For OpenAI Chat Completions, refresh runs",
2101
- " ",
2102
- /* @__PURE__ */ jsxs("span", {
2103
- className: "font-medium",
2104
- children: ["GET ", "{baseUrl}/models"]
2105
- }),
2106
- "."
2107
- ] })] }),
1460
+ /* @__PURE__ */ jsxs(DialogHeader, {
1461
+ className: "shrink-0",
1462
+ children: [/* @__PURE__ */ jsx(DialogTitle, { children: "Add models" }), /* @__PURE__ */ jsxs(DialogDescription, { children: [
1463
+ "Pick models discovered from your configured providers. For OpenAI Chat Completions, refresh runs",
1464
+ " ",
1465
+ /* @__PURE__ */ jsxs("span", {
1466
+ className: "font-medium",
1467
+ children: ["GET ", "{baseUrl}/models"]
1468
+ }),
1469
+ "."
1470
+ ] })]
1471
+ }),
2108
1472
  /* @__PURE__ */ jsx("div", {
2109
- className: "flex flex-wrap gap-1.5",
2110
- children: discoverableProviders.map((providerId) => {
2111
- const discovering = discoveringProviderId === providerId;
2112
- const activeCount = activeCountByProvider.get(providerId) ?? 0;
2113
- return /* @__PURE__ */ jsxs(Button$1, {
2114
- type: "button",
2115
- variant: "outline",
2116
- size: "compact",
2117
- disabled: discoveringProviderId !== null,
2118
- onClick: () => {
2119
- onDiscoverProvider(providerId);
2120
- },
2121
- children: [
2122
- discovering ? /* @__PURE__ */ jsx(Spinner, { "data-icon": "inline-start" }) : /* @__PURE__ */ jsx(RefreshCw, { "data-icon": "inline-start" }),
2123
- providerLabel(providerId),
2124
- activeCount > 0 ? /* @__PURE__ */ jsxs("span", {
2125
- className: "tabular-nums text-muted-foreground",
2126
- children: [
2127
- "\xB7 ",
2128
- activeCount,
2129
- " active"
2130
- ]
2131
- }) : null
2132
- ]
2133
- }, providerId);
1473
+ className: "max-h-28 shrink-0 overflow-y-auto",
1474
+ children: /* @__PURE__ */ jsx("div", {
1475
+ className: "flex min-w-0 flex-wrap gap-1.5 [&_button]:max-w-full [&_button]:h-auto [&_button]:whitespace-normal [&_button]:break-words",
1476
+ children: discoverableProviders.map((providerId) => {
1477
+ const discovering = discovery[providerId]?.loading ?? discoveringProviderId === providerId;
1478
+ const activeCount = activeCountByProvider.get(providerId) ?? 0;
1479
+ return /* @__PURE__ */ jsxs(Button$1, {
1480
+ type: "button",
1481
+ variant: "outline",
1482
+ size: "compact",
1483
+ disabled: discovering,
1484
+ onClick: () => {
1485
+ refreshProvider(providerId, true);
1486
+ },
1487
+ children: [
1488
+ discovering ? /* @__PURE__ */ jsx(Spinner, { "data-icon": "inline-start" }) : /* @__PURE__ */ jsx(RefreshCw, { "data-icon": "inline-start" }),
1489
+ "Refresh ",
1490
+ providerLabel(providerId),
1491
+ discovery[providerId]?.error ? " \xB7 Refresh failed (stale)" : "",
1492
+ activeCount > 0 ? /* @__PURE__ */ jsxs("span", {
1493
+ className: "tabular-nums text-muted-foreground",
1494
+ children: [
1495
+ "\xB7 ",
1496
+ activeCount,
1497
+ " active"
1498
+ ]
1499
+ }) : null
1500
+ ]
1501
+ }, providerId);
1502
+ })
2134
1503
  })
2135
1504
  }),
2136
1505
  /* @__PURE__ */ jsxs(InputGroup, { children: [/* @__PURE__ */ jsx(InputGroupAddon, {
@@ -2143,10 +1512,11 @@ function AddModelsDialog({ configuredProviderIds, discoverableProviderIds, disco
2143
1512
  placeholder: "Search discovered models\u2026"
2144
1513
  })] }),
2145
1514
  /* @__PURE__ */ jsx("div", {
2146
- className: "max-h-72 overflow-y-auto overscroll-contain",
1515
+ className: "min-h-0 min-w-0 flex-1 overflow-y-auto overflow-x-hidden overscroll-contain",
1516
+ "aria-live": "polite",
2147
1517
  children: groupedCandidates.length === 0 ? /* @__PURE__ */ jsx("p", {
2148
1518
  className: "py-6 text-center text-xs text-pretty text-muted-foreground",
2149
- children: candidateModels.length === 0 && !normalizedFilter ? "All discovered models are already in your list, or none are available yet." : "No models match your search."
1519
+ children: Object.values(discovery).some((state) => state.loading) ? "Loading models\u2026" : candidateModels.length === 0 && !normalizedFilter ? "No additional models available. Providers may have returned an empty list or all models are already enabled." : "No models match your search."
2150
1520
  }) : /* @__PURE__ */ jsx("div", {
2151
1521
  className: "flex flex-col gap-3",
2152
1522
  children: groupedCandidates.map(([provider, models]) => /* @__PURE__ */ jsxs("div", {
@@ -2197,7 +1567,7 @@ function AddModelsDialog({ configuredProviderIds, discoverableProviderIds, disco
2197
1567
  })
2198
1568
  }),
2199
1569
  /* @__PURE__ */ jsxs("div", {
2200
- className: "flex items-center justify-end gap-1.5",
1570
+ className: "flex shrink-0 items-center justify-end gap-1.5",
2201
1571
  children: [/* @__PURE__ */ jsx(Button$1, {
2202
1572
  type: "button",
2203
1573
  variant: "ghost",
@@ -2287,7 +1657,7 @@ function ModelDefaultsSection({ draft, discoveringProviderId, modelDirty, modelF
2287
1657
  return /* @__PURE__ */ jsxs(SettingsPane, {
2288
1658
  title: "LLM Models",
2289
1659
  description: /* @__PURE__ */ jsxs(Fragment$1, { children: [
2290
- "Models available in chat. Discover from configured providers, add the ones you want, and remove any you do not need \u2014 changes save automatically. ",
1660
+ "Models available in chat. ",
2291
1661
  /* @__PURE__ */ jsx("span", {
2292
1662
  className: "tabular-nums",
2293
1663
  children: listedModels.length
@@ -2501,6 +1871,32 @@ function isOAuthProvider(provider) {
2501
1871
  function supportsOAuth(provider) {
2502
1872
  return provider.supportsOAuth === true;
2503
1873
  }
1874
+ function ProviderOAuthTerminalFallback({ provider }) {
1875
+ return /* @__PURE__ */ jsx(Alert, {
1876
+ className: "px-3 py-2",
1877
+ children: /* @__PURE__ */ jsxs(AlertDescription, {
1878
+ className: "text-xs text-pretty",
1879
+ children: [
1880
+ "Sign-in has to run inside Prime Agent. In a terminal, start Prime Agent against the same account as Fleet, then run ",
1881
+ /* @__PURE__ */ jsx("code", {
1882
+ className: "rounded bg-muted px-1 py-0.5 font-mono text-caption text-foreground",
1883
+ children: "/login"
1884
+ }),
1885
+ " ",
1886
+ "and choose ",
1887
+ provider.name,
1888
+ ". Fleet reads the stored credential on every request, so a restart is not needed. If Fleet uses a non-default account directory, start Prime Agent with the same",
1889
+ " ",
1890
+ /* @__PURE__ */ jsx("code", {
1891
+ className: "rounded bg-muted px-1 py-0.5 font-mono text-caption text-foreground",
1892
+ children: "PRIME_AGENT_CODING_AGENT_DIR"
1893
+ }),
1894
+ " ",
1895
+ "it uses."
1896
+ ]
1897
+ })
1898
+ });
1899
+ }
2504
1900
  var CUSTOM_PROVIDER_PICKER_ROW = {
2505
1901
  id: "custom",
2506
1902
  name: "Custom provider",
@@ -2538,7 +1934,7 @@ function useProviderCredentialsController({ onRemoveProvider, onUpdateProvider,
2538
1934
  }, [activeProviders, searchQuery]);
2539
1935
  const filteredPickerAvailable = useMemo3(() => {
2540
1936
  const query = addPickerQuery.trim().toLowerCase();
2541
- return unconfiguredProviders.filter((provider) => providerMatchesQuery(provider, query));
1937
+ return unconfiguredProviders.filter((provider) => providerMatchesQuery(provider, query)).sort((a, b) => a.id === "custom" ? -1 : b.id === "custom" ? 1 : a.name.localeCompare(b.name));
2542
1938
  }, [addPickerQuery, unconfiguredProviders]);
2543
1939
  const filteredPickerConfigured = useMemo3(() => {
2544
1940
  const query = addPickerQuery.trim().toLowerCase();
@@ -2745,7 +2141,7 @@ function AddProviderPickerPanel({ addPickerQuery, credentialProvidersLength, fil
2745
2141
  children: "Add provider"
2746
2142
  }), /* @__PURE__ */ jsx("p", {
2747
2143
  className: "text-xs text-pretty text-muted-foreground",
2748
- children: "Choose a provider to store encrypted credentials for this account."
2144
+ children: "Choose a provider to save credentials in Prime Agent\u2019s auth.json."
2749
2145
  })]
2750
2146
  })]
2751
2147
  }),
@@ -2789,7 +2185,7 @@ function AddProviderPickerPanel({ addPickerQuery, credentialProvidersLength, fil
2789
2185
  ]
2790
2186
  });
2791
2187
  }
2792
- function AddProviderOAuthPanel({ onBack, onConfigured, onOAuthLogin, provider }) {
2188
+ function AddProviderOAuthPanel({ onBack, provider }) {
2793
2189
  return /* @__PURE__ */ jsxs("div", {
2794
2190
  className: "flex flex-col gap-3",
2795
2191
  children: [/* @__PURE__ */ jsxs("div", {
@@ -2811,14 +2207,10 @@ function AddProviderOAuthPanel({ onBack, onConfigured, onOAuthLogin, provider })
2811
2207
  children: "OAuth sign-in. Credentials are stored in auth.json for this account."
2812
2208
  })]
2813
2209
  })]
2814
- }), /* @__PURE__ */ jsx(ProviderOAuthSignIn, {
2815
- provider,
2816
- onConfigured,
2817
- onOAuthLogin
2818
- }, provider.id)]
2210
+ }), /* @__PURE__ */ jsx(ProviderOAuthTerminalFallback, { provider })]
2819
2211
  });
2820
2212
  }
2821
- function AddProviderEditorPanel({ provider, api, apiKey, baseUrl, modelId, models, displayName, showPassword, attemptedSave, isPending, canSave, onApiKeyChange, onApiChange, onBaseUrlChange, onModelIdChange, onModelsChange, onDisplayNameChange, onTogglePassword, onBack, onCancel, onConfigured, onOAuthLogin, onSave }) {
2213
+ function AddProviderEditorPanel({ provider, api, apiKey, baseUrl, modelId, models, displayName, showPassword, attemptedSave, isPending, canSave, onApiKeyChange, onApiChange, onBaseUrlChange, onModelIdChange, onModelsChange, onDisplayNameChange, onTogglePassword, onBack, onCancel, onSave }) {
2822
2214
  const isCustomTemplate = provider.id === "custom" || isCustomProviderId(provider.id);
2823
2215
  const meta = PROVIDER_METADATA[provider.id] ?? (isCustomTemplate ? PROVIDER_METADATA["custom"] : {
2824
2216
  placeholder: "Enter credentials\u2026",
@@ -2892,11 +2284,7 @@ function AddProviderEditorPanel({ provider, api, apiKey, baseUrl, modelId, model
2892
2284
  children: [isPending ? /* @__PURE__ */ jsx(Spinner, { "data-icon": "inline-start" }) : null, "Save"]
2893
2285
  })]
2894
2286
  }),
2895
- oauthAvailable ? /* @__PURE__ */ jsx(ProviderOAuthSignIn, {
2896
- provider,
2897
- onConfigured: onConfigured ?? onCancel,
2898
- onOAuthLogin
2899
- }, `${provider.id}-oauth`) : null
2287
+ oauthAvailable ? /* @__PURE__ */ jsx(ProviderOAuthTerminalFallback, { provider }) : null
2900
2288
  ]
2901
2289
  });
2902
2290
  }
@@ -2953,7 +2341,7 @@ function ProviderPickerRow({ configured, onSelect, provider }) {
2953
2341
  })]
2954
2342
  });
2955
2343
  }
2956
- function ActiveProviderList({ providers, editingProvider, form, operation, actions, onEdit, onCancelEdit, onSave, onRemove, onOAuthLogin, onConfigured }) {
2344
+ function ActiveProviderList({ providers, editingProvider, form, operation, actions, onEdit, onCancelEdit, onSave, onRemove }) {
2957
2345
  const { api, apiKey, baseUrl, modelId, models, displayName, showPassword, attemptedSave, canSave } = form;
2958
2346
  const { isPending, canRemove } = operation;
2959
2347
  const { onApiKeyChange, onApiChange, onBaseUrlChange, onModelIdChange, onModelsChange, onDisplayNameChange, onTogglePassword } = actions;
@@ -3008,11 +2396,7 @@ function ActiveProviderList({ providers, editingProvider, form, operation, actio
3008
2396
  tone: "inset",
3009
2397
  padding: "md",
3010
2398
  className: "flex flex-col gap-2 border-t border-border/30",
3011
- children: oauthOnly ? /* @__PURE__ */ jsx(ProviderOAuthSignIn, {
3012
- provider,
3013
- onConfigured,
3014
- onOAuthLogin
3015
- }, provider.id) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
2399
+ children: oauthOnly ? /* @__PURE__ */ jsx(ProviderOAuthTerminalFallback, { provider }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
3016
2400
  /* @__PURE__ */ jsx(ProviderCredentialFields, {
3017
2401
  attemptedSave,
3018
2402
  api: provider.api ?? api,
@@ -3050,18 +2434,14 @@ function ActiveProviderList({ providers, editingProvider, form, operation, actio
3050
2434
  children: [isPending ? /* @__PURE__ */ jsx(Spinner, { "data-icon": "inline-start" }) : null, "Save"]
3051
2435
  })
3052
2436
  }),
3053
- oauthAvailable ? /* @__PURE__ */ jsx(ProviderOAuthSignIn, {
3054
- provider,
3055
- onConfigured,
3056
- onOAuthLogin
3057
- }, `${provider.id}-oauth`) : null
2437
+ oauthAvailable ? /* @__PURE__ */ jsx(ProviderOAuthTerminalFallback, { provider }) : null
3058
2438
  ] })
3059
2439
  }) : null]
3060
2440
  }, provider.id);
3061
2441
  })
3062
2442
  });
3063
2443
  }
3064
- function ProviderCredentialsSection({ isLoading, isPending, onOAuthLogin, onRemoveProvider, onUpdateProvider, providers }) {
2444
+ function ProviderCredentialsSection({ isLoading, isPending, onRemoveProvider, onUpdateProvider, providers }) {
3065
2445
  const { activeProviders, addPickerOpen, addPickerQuery, api, apiKey, attemptedSave, baseUrl, canSave, closeAddPicker, closeEditor, confirmRemoveProvider, credentialProviders, displayName, editingProvider, editingUnconfiguredProvider, filteredActiveProviders, filteredPickerAvailable, filteredPickerConfigured, handleRemove, handleSave, modelId, models, openAddPicker, openEditor, pickerHasResults, searchQuery, selectProviderFromPicker, setAddPickerQuery, setApi, setApiKey, setBaseUrl, setConfirmRemoveProvider, setDisplayName, setModelId, setModels, setSearchQuery, setShowPassword, showPassword } = useProviderCredentialsController({
3066
2446
  onRemoveProvider,
3067
2447
  onUpdateProvider,
@@ -3094,13 +2474,13 @@ function ProviderCredentialsSection({ isLoading, isPending, onOAuthLogin, onRemo
3094
2474
  return /* @__PURE__ */ jsxs(SettingsPane, {
3095
2475
  title: "Providers",
3096
2476
  description: /* @__PURE__ */ jsxs(Fragment$1, { children: [
3097
- "Locally, API keys are stored in",
2477
+ "Provider credentials are stored in Prime Agent\u2019s",
3098
2478
  " ",
3099
2479
  /* @__PURE__ */ jsx("code", {
3100
2480
  className: "rounded bg-muted px-1 py-0.5 font-mono text-caption text-foreground",
3101
- children: ".env.local"
2481
+ children: "auth.json"
3102
2482
  }),
3103
- ". When deployed, they are stored encrypted in your account."
2483
+ ". Custom providers and model definitions are stored in models.json. Enabled models and defaults are saved in settings.json, or the existing project settings file."
3104
2484
  ] }),
3105
2485
  children: [addPickerOpen ? /* @__PURE__ */ jsx(AddProviderPickerPanel, {
3106
2486
  addPickerQuery,
@@ -3113,9 +2493,7 @@ function ProviderCredentialsSection({ isLoading, isPending, onOAuthLogin, onRemo
3113
2493
  onSelect: selectProviderFromPicker
3114
2494
  }) : editingUnconfiguredProvider && isOAuthProvider(editingUnconfiguredProvider) ? /* @__PURE__ */ jsx(AddProviderOAuthPanel, {
3115
2495
  provider: editingUnconfiguredProvider,
3116
- onBack: openAddPicker,
3117
- onConfigured: closeEditor,
3118
- onOAuthLogin
2496
+ onBack: openAddPicker
3119
2497
  }, editingUnconfiguredProvider.id) : editingUnconfiguredProvider ? /* @__PURE__ */ jsx(AddProviderEditorPanel, {
3120
2498
  provider: editingUnconfiguredProvider,
3121
2499
  api,
@@ -3137,8 +2515,6 @@ function ProviderCredentialsSection({ isLoading, isPending, onOAuthLogin, onRemo
3137
2515
  onTogglePassword: () => setShowPassword((current) => !current),
3138
2516
  onBack: openAddPicker,
3139
2517
  onCancel: closeEditor,
3140
- onConfigured: closeEditor,
3141
- onOAuthLogin,
3142
2518
  onSave: () => {
3143
2519
  if (editingProvider) handleSave(editingProvider);
3144
2520
  }
@@ -3195,9 +2571,7 @@ function ProviderCredentialsSection({ isLoading, isPending, onOAuthLogin, onRemo
3195
2571
  onEdit: openEditor,
3196
2572
  onCancelEdit: closeEditor,
3197
2573
  onSave: (providerId) => void handleSave(providerId),
3198
- onRemove: setConfirmRemoveProvider,
3199
- onOAuthLogin,
3200
- onConfigured: closeEditor
2574
+ onRemove: setConfirmRemoveProvider
3201
2575
  })]
3202
2576
  }), /* @__PURE__ */ jsx(RemoveProviderConfirmDialog, {
3203
2577
  confirmRemoveProvider,
@@ -3300,7 +2674,7 @@ function sanitizeStringList(values) {
3300
2674
  }
3301
2675
  function useModelDefaultsForm({ draft, setDraft, updateDraft, settings, providers, models, modelCatalog, onDiscoverModels, saveSettings, setSavingSection }) {
3302
2676
  const [modelFilter, setModelFilter] = useState2("");
3303
- const [discoveredModels, setDiscoveredModels] = useState2([]);
2677
+ const [discoveredModels, setDiscoveredModels] = useState2({});
3304
2678
  const [discoveringProviderId, setDiscoveringProviderId] = useState2(null);
3305
2679
  const lastCommittedModelSettings = useRef4(null);
3306
2680
  const configuredProviderIds = useMemo3(() => {
@@ -3311,13 +2685,24 @@ function useModelDefaultsForm({ draft, setDraft, updateDraft, settings, provider
3311
2685
  const catalogModels = modelCatalog ?? models;
3312
2686
  const modelOptions = useMemo3(() => {
3313
2687
  const byId = /* @__PURE__ */ new Map();
3314
- for (const model of catalogModels) if (configuredProviderIds.has(model.provider) && model.available !== false) byId.set(model.id, model);
3315
- for (const model of discoveredModels) if (configuredProviderIds.has(model.provider) && model.available !== false) byId.set(model.id, model);
2688
+ const catalogById = new Map(catalogModels.map((model) => [model.id, model]));
2689
+ for (const model of catalogModels) {
2690
+ if (Object.hasOwn(discoveredModels, model.provider) && !isModelEnabled(model, draft?.enabledModels)) continue;
2691
+ if (configuredProviderIds.has(model.provider) && model.available !== false) byId.set(model.id, model);
2692
+ }
2693
+ for (const model of Object.values(discoveredModels).flat()) if (configuredProviderIds.has(model.provider) && model.available !== false) {
2694
+ const existing = catalogById.get(model.id);
2695
+ byId.set(model.id, existing ? {
2696
+ ...model,
2697
+ ...existing
2698
+ } : model);
2699
+ }
3316
2700
  return [...byId.values()];
3317
2701
  }, [
3318
2702
  catalogModels,
3319
2703
  configuredProviderIds,
3320
- discoveredModels
2704
+ discoveredModels,
2705
+ draft?.enabledModels
3321
2706
  ]);
3322
2707
  const modelBaseline = lastCommittedModelSettings.current ?? (settings ? comparableModelSettings(settings.effective) : null);
3323
2708
  const modelDirty = !!draft && !!modelBaseline && !sameJson(comparableModelSettings(draft), modelBaseline);
@@ -3393,11 +2778,10 @@ function useModelDefaultsForm({ draft, setDraft, updateDraft, settings, provider
3393
2778
  setDiscoveringProviderId(providerId);
3394
2779
  try {
3395
2780
  const discovered = await onDiscoverModels(providerId);
3396
- setDiscoveredModels((current) => {
3397
- const byId = new Map(current.map((model) => [model.id, model]));
3398
- for (const model of discovered) byId.set(model.id, model);
3399
- return [...byId.values()];
3400
- });
2781
+ setDiscoveredModels((current) => ({
2782
+ ...current,
2783
+ [providerId]: discovered
2784
+ }));
3401
2785
  } finally {
3402
2786
  setDiscoveringProviderId(null);
3403
2787
  }
@@ -4104,7 +3488,7 @@ var ScrollArea$1 = forwardRef7(({ className, children, viewportClassName, orient
4104
3488
  "data-slot": "scroll-area-viewport",
4105
3489
  className: cn("size-full rounded-[inherit]", viewportClassName),
4106
3490
  children: /* @__PURE__ */ jsx(index_parts_exports.Content, {
4107
- className: cn(orientation2 === "vertical" && "w-full min-w-full"),
3491
+ className: cn(orientation2 === "vertical" && "block! w-full min-w-0! max-w-full"),
4108
3492
  children
4109
3493
  })
4110
3494
  }),
@@ -4132,10 +3516,11 @@ var ScrollBar = forwardRef7(({ className, orientation: orientation2 = "vertical"
4132
3516
  });
4133
3517
  ScrollBar.displayName = "ScrollBar";
4134
3518
  function useSettingsForm() {
4135
- const { isLoadingMcp, isLoadingProviders, isUpdatingMcp, isUpdatingProvider, mcpConnections = [], modelCatalog, onDiscoverModels, onMcpOAuth, onOAuthLogin, onRemoveMcp, onRemoveProvider, onThemePreferenceChange, onUpdateMcp, onUpdateProvider, providers = [], saveSettings, settings, settingsLoading, themePreference } = useSettingsActionsContext();
3519
+ const { isLoadingMcp, isLoadingProviders, isUpdatingMcp, isUpdatingProvider, mcpConnections = [], modelCatalog, onDiscoverModels, onMcpOAuth, onRemoveMcp, onRemoveProvider, onThemePreferenceChange, onUpdateMcp, onUpdateProvider, providers = [], saveSettings, settings, settingsLoading, themePreference } = useSettingsActionsContext();
4136
3520
  const { models, resources } = useChatPanelDataContext();
4137
3521
  const [draft, setDraft] = useState2(null);
4138
3522
  const [savingSection, setSavingSection] = useState2(null);
3523
+ const syncedSettings = useRef4(void 0);
4139
3524
  const resourceSummary = summarizeResources(resources);
4140
3525
  const updateDraft = (updater) => {
4141
3526
  setDraft((current) => current ? updater(current) : current);
@@ -4163,9 +3548,10 @@ function useSettingsForm() {
4163
3548
  setDraft(settings.effective);
4164
3549
  };
4165
3550
  useEffect2(() => {
4166
- if (!settings) return;
3551
+ if (!settings || syncedSettings.current === settings) return;
4167
3552
  const nextDraft = settings.effective;
4168
3553
  if (draft && hasUnsavedChanges) return;
3554
+ syncedSettings.current = settings;
4169
3555
  if (draft && sameJson(draft, nextDraft)) return;
4170
3556
  setDraft(nextDraft);
4171
3557
  }, [
@@ -4202,7 +3588,6 @@ function useSettingsForm() {
4202
3588
  isUpdatingProvider,
4203
3589
  mcpConnections,
4204
3590
  onMcpOAuth,
4205
- onOAuthLogin,
4206
3591
  onRemoveMcp,
4207
3592
  onRemoveProvider,
4208
3593
  onThemePreferenceChange,
@@ -4276,7 +3661,7 @@ function SettingsDialogSession({ initialTab, onOpenChange, open }) {
4276
3661
  });
4277
3662
  }
4278
3663
  function SettingsDialogPaneContent({ activeTab, composerIntent, form, onComposerIntentChange, onComposerIntentKeyChange, preferences, updatePreference }) {
4279
- const { isLoadingMcp, isLoadingProviders, isUpdatingMcp, isUpdatingProvider, mcpConnections, onMcpOAuth, onOAuthLogin, onRemoveMcp, onRemoveProvider, onThemePreferenceChange, onUpdateMcp, onUpdateProvider, providers, resources, settingsLoading, themePreference, draft, savingSection, packageRows, packageError, modelFilter, setModelFilter, resourceSummary, modelOptions, modelDirty, resourceDirty, revertResourceDraft, revertModelDraft, updateDraft, handlePackageRowsChange, addModels, removeModel, setDefaultModel, discoverProvider, discoveringProviderId, saveSection } = form;
3664
+ const { isLoadingMcp, isLoadingProviders, isUpdatingMcp, isUpdatingProvider, mcpConnections, onMcpOAuth, onRemoveMcp, onRemoveProvider, onThemePreferenceChange, onUpdateMcp, onUpdateProvider, providers, resources, settingsLoading, themePreference, draft, savingSection, packageRows, packageError, modelFilter, setModelFilter, resourceSummary, modelOptions, modelDirty, resourceDirty, revertResourceDraft, revertModelDraft, updateDraft, handlePackageRowsChange, addModels, removeModel, setDefaultModel, discoverProvider, discoveringProviderId, saveSection } = form;
4280
3665
  const resourcesPane = (scope) => /* @__PURE__ */ jsx(ResourcesSection, {
4281
3666
  scope,
4282
3667
  draft,
@@ -4418,26 +3803,31 @@ function SettingsDialogPaneContent({ activeTab, composerIntent, form, onComposer
4418
3803
  isLoading: isLoadingProviders ?? false,
4419
3804
  isPending: isUpdatingProvider ?? false,
4420
3805
  providers,
4421
- onOAuthLogin,
4422
3806
  onRemoveProvider,
4423
3807
  onUpdateProvider
4424
3808
  }),
4425
- "llm-models": () => /* @__PURE__ */ jsx(ModelDefaultsSection, {
4426
- draft,
4427
- discoveringProviderId,
4428
- modelDirty,
4429
- modelFilter,
4430
- modelOptions,
4431
- onAddModels: addModels,
4432
- onDiscoverProvider: discoverProvider,
4433
- onModelFilterChange: setModelFilter,
4434
- onRemoveModel: removeModel,
4435
- onSetDefaultModel: setDefaultModel,
4436
- providers,
4437
- onRevert: revertModelDraft,
4438
- onSave: () => draft && saveSection("models", modelSettings(draft)),
4439
- saving: savingSection === "models",
4440
- settingsLoading
3809
+ "llm-models": () => /* @__PURE__ */ jsxs("div", {
3810
+ className: "flex flex-col gap-3",
3811
+ children: [/* @__PURE__ */ jsx("p", {
3812
+ className: "text-sm text-muted-foreground",
3813
+ children: "Saving writes the same settings file Prime Agent reads. If you change these settings in the Prime Agent terminal at the same moment, the later save wins."
3814
+ }), /* @__PURE__ */ jsx(ModelDefaultsSection, {
3815
+ draft,
3816
+ discoveringProviderId,
3817
+ modelDirty,
3818
+ modelFilter,
3819
+ modelOptions,
3820
+ onAddModels: addModels,
3821
+ onDiscoverProvider: discoverProvider,
3822
+ onModelFilterChange: setModelFilter,
3823
+ onRemoveModel: removeModel,
3824
+ onSetDefaultModel: setDefaultModel,
3825
+ providers,
3826
+ onRevert: revertModelDraft,
3827
+ onSave: () => draft && saveSection("models", modelSettings(draft)),
3828
+ saving: savingSection === "models",
3829
+ settingsLoading
3830
+ })]
4441
3831
  }),
4442
3832
  skills: () => resourcesPane("skills"),
4443
3833
  "pi-harness": () => resourcesPane("harness"),
@@ -4619,13 +4009,14 @@ function SettingsDialogBody({ initialTab, onCloseAttemptRef, onOpenChange }) {
4619
4009
  })
4620
4010
  }),
4621
4011
  /* @__PURE__ */ jsx(ScrollArea$1, {
4622
- className: "min-h-0 w-full flex-1",
4012
+ className: "min-h-0 min-w-0 w-full flex-1",
4013
+ viewportClassName: "overflow-x-hidden",
4623
4014
  children: /* @__PURE__ */ jsx("div", {
4624
4015
  id: `panel-${activeTab}`,
4625
4016
  role: "tabpanel",
4626
4017
  "aria-label": activeSection.title,
4627
4018
  tabIndex: 0,
4628
- className: "w-full p-6 outline-none",
4019
+ className: "min-w-0 w-full max-w-full p-4 outline-none [overflow-wrap:anywhere] sm:p-6",
4629
4020
  children: paneContent
4630
4021
  })
4631
4022
  })