@opengeni/react 4.6.1 → 4.6.2-canary.39853438886001

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 (467) hide show
  1. package/dist/app/app-state.js +13 -13
  2. package/dist/app/components/Composer.js +14 -14
  3. package/dist/app/components/artifacts/artifact-library.js +5 -5
  4. package/dist/app/components/artifacts/chat-interactive-block.js +10 -10
  5. package/dist/app/components/artifacts/inline-chat-image.js +14 -14
  6. package/dist/app/components/artifacts/retained-file-preview.js +16 -16
  7. package/dist/app/components/artifacts/retained-text-preview.js +2 -2
  8. package/dist/app/components/artifacts/site-conversations.js +5 -4
  9. package/dist/app/components/artifacts/site-data.js +2 -2
  10. package/dist/app/components/artifacts/site-publishing.js +11 -11
  11. package/dist/app/components/artifacts/site-settings.js +15 -15
  12. package/dist/app/components/billing-class-mark.js +3 -3
  13. package/dist/app/components/capabilities/capability-detail-sheet.js +2 -2
  14. package/dist/app/components/capabilities/capability-logo-source.js +7 -7
  15. package/dist/app/components/capabilities/native-connect-readiness.js +1 -0
  16. package/dist/app/components/capabilities/native-connect-readiness.js.map +1 -1
  17. package/dist/app/components/capabilities/native-connect-setup.js +6 -6
  18. package/dist/app/components/capabilities/perform-capability-action.js +2 -1
  19. package/dist/app/components/capabilities/prepared-mcp-setup-card.js +8 -8
  20. package/dist/app/components/capabilities/session-capability-card.js +32 -31
  21. package/dist/app/components/capabilities/session-capability-card.js.map +1 -1
  22. package/dist/app/components/capabilities/session-chrome-card.js +14 -14
  23. package/dist/app/components/capabilities/session-custom-mcp-card.js +9 -9
  24. package/dist/app/components/capabilities/session-github-card.js +9 -9
  25. package/dist/app/components/capabilities/session-machine-card.js +14 -14
  26. package/dist/app/components/command-menu/chat-status.js +6 -5
  27. package/dist/app/components/command-menu/chat-switcher.d.ts +2 -0
  28. package/dist/app/components/command-menu/chat-switcher.js +26 -9
  29. package/dist/app/components/command-menu/chat-switcher.js.map +1 -1
  30. package/dist/app/components/command-menu/command-menu.js +16 -15
  31. package/dist/app/components/command-menu/command-menu.js.map +1 -1
  32. package/dist/app/components/command-menu/shortcut-sheet.js +8 -8
  33. package/dist/app/components/composer-mobile-plus-panel.js +5 -5
  34. package/dist/app/components/composer-mobile-plus.js +1 -1
  35. package/dist/app/components/credit-required-gate.js +1 -1
  36. package/dist/app/components/credit-required-prompt.js +4 -4
  37. package/dist/app/components/desktop/app-shots.js +5 -5
  38. package/dist/app/components/desktop/this-computer.js +4 -4
  39. package/dist/app/components/feedback.js +3 -3
  40. package/dist/app/components/github-app-connect-launcher.js +1 -1
  41. package/dist/app/components/machines/connect-machine-dialog.js +3 -3
  42. package/dist/app/components/markdown.js +4 -4
  43. package/dist/app/components/models/models-ui.js +2 -2
  44. package/dist/app/components/pickers.js +5 -5
  45. package/dist/app/components/rail/rail-context.js +3 -3
  46. package/dist/app/components/rail/rail-sections.js +28 -27
  47. package/dist/app/components/rail/session-header.d.ts +6 -5
  48. package/dist/app/components/rail/session-header.js +20 -19
  49. package/dist/app/components/rail/session-list.js +27 -26
  50. package/dist/app/components/rail/session-row-hover-details.js +7 -6
  51. package/dist/app/components/rail/session-shell.js +51 -53
  52. package/dist/app/components/rail/site-session-group-heading.js +2 -1
  53. package/dist/app/components/session/agent-configuration-panel.js +6 -6
  54. package/dist/app/components/session/banners.js +6 -6
  55. package/dist/app/components/session/conversation-find.js +3 -3
  56. package/dist/app/components/session/editable-artifacts-workspace.js +17 -17
  57. package/dist/app/components/session/failed-session-banner.js +5 -5
  58. package/dist/app/components/session/human-input.js +26 -26
  59. package/dist/app/components/session/inspector.js +37 -37
  60. package/dist/app/components/session/message-actions.js +3 -3
  61. package/dist/app/components/session/message-resource-attachments.js +5 -5
  62. package/dist/app/components/session/model-recovery-notice.js +3 -3
  63. package/dist/app/components/session/new-session-settings-menu.js +4 -4
  64. package/dist/app/components/session/sandbox-switcher.js +8 -8
  65. package/dist/app/components/session/sandbox-workspace.js +36 -36
  66. package/dist/app/components/session/search-markdown-highlight.js +5 -5
  67. package/dist/app/components/session/search-results-view.js +6 -6
  68. package/dist/app/components/session/session-admission-notice.js +4 -4
  69. package/dist/app/components/session/session-machine-access-notice.js +4 -4
  70. package/dist/app/components/session/session-search-dialog.js +6 -6
  71. package/dist/app/components/session/session-tenancy-control.js +4 -4
  72. package/dist/app/components/session/session-usage-limit-section.js +3 -3
  73. package/dist/app/components/session/session-wait-status.js +2 -1
  74. package/dist/app/components/session/session-wait-status.js.map +1 -1
  75. package/dist/app/components/session/subagents.js +6 -5
  76. package/dist/app/components/session/subscription-account-indicator.d.ts +35 -0
  77. package/dist/app/components/session/{codex-account-indicator.js → subscription-account-indicator.js} +23 -10
  78. package/dist/app/components/session/subscription-account-menu.d.ts +11 -12
  79. package/dist/app/components/session/subscription-account-menu.js +1 -1
  80. package/dist/app/components/session/subscription-account.d.ts +105 -0
  81. package/dist/app/components/usage/usage-entry.js +3 -3
  82. package/dist/app/components/workspace-composer-plus.js +10 -10
  83. package/dist/app/embed/session-app.js +154 -156
  84. package/dist/app/lib/actions/actions-provider.js +8 -8
  85. package/dist/app/lib/actions/chat-switcher.d.ts +19 -7
  86. package/dist/app/lib/codex-usage-query.js +2 -2
  87. package/dist/app/lib/composer-connectors.js +8 -8
  88. package/dist/app/lib/console-text.js +2 -2
  89. package/dist/app/lib/drive-connect-return.d.ts +26 -0
  90. package/dist/app/lib/drive-connect-return.js +16 -0
  91. package/dist/app/lib/events.js +7 -7
  92. package/dist/app/lib/failed-session-copy.js +3 -3
  93. package/dist/app/lib/model-access-onboarding.js +3 -3
  94. package/dist/app/lib/move-chat-to-machine.js +3 -3
  95. package/dist/app/lib/session-branch-cache.js +6 -5
  96. package/dist/app/lib/session-group-pagination.js +6 -5
  97. package/dist/app/lib/session-hover-facts.js +6 -5
  98. package/dist/app/lib/session-rail.js +2 -1
  99. package/dist/app/lib/sessions-group.js +5 -4
  100. package/dist/app/lib/turn-failure-analytics.js +5 -5
  101. package/dist/app/lib/use-workspace-machines.js +4 -4
  102. package/dist/app/lib/use-workspace-model-catalog.js +3 -3
  103. package/dist/app/lib/use-workspace-rigs.js +2 -2
  104. package/dist/app/lib/workspace-navigation-preference.js +4 -4
  105. package/dist/app/lib/workspace-scope-context.js +3 -3
  106. package/dist/app/routes/artifacts.js +50 -49
  107. package/dist/app/routes/artifacts.js.map +1 -1
  108. package/dist/app/routes/retained-artifact.js +23 -23
  109. package/dist/app/routes/session.js +92 -91
  110. package/dist/app/routes/sessions-index.js +52 -52
  111. package/dist/app/routes/site-view.js +35 -34
  112. package/dist/app/routes/site-view.js.map +1 -1
  113. package/dist/artifacts-document.js +4 -4
  114. package/dist/artifacts-presentation.js +4 -4
  115. package/dist/artifacts-spreadsheet.js +4 -4
  116. package/dist/artifacts.js +10 -10
  117. package/dist/{browser-viewer-YQC6BFMS.js → browser-viewer-VKIAULG7.js} +4 -4
  118. package/dist/{chat-interactive-block-Z22YHDRU.js → chat-interactive-block-JGYSW4KB.js} +5 -5
  119. package/dist/{chunk-WN2MIB4Q.js → chunk-22V2QCEM.js} +2 -2
  120. package/dist/{chunk-SJPAKWWP.js → chunk-2BISI664.js} +2 -2
  121. package/dist/{chunk-O5UOCMH4.js → chunk-2LPJVEWY.js} +3 -3
  122. package/dist/{chunk-NPDL4W4Y.js → chunk-2MLJHNKJ.js} +108 -109
  123. package/dist/chunk-2MLJHNKJ.js.map +1 -0
  124. package/dist/{chunk-JI6WPLZB.js → chunk-2SBCOGQN.js} +4 -4
  125. package/dist/{chunk-6JF7C3U3.js → chunk-2WERWWSS.js} +2 -2
  126. package/dist/{chunk-4XKT4ENZ.js → chunk-2Y3QL3DA.js} +4 -4
  127. package/dist/{chunk-KVMFT6FN.js → chunk-3FL3F4WF.js} +2 -2
  128. package/dist/{chunk-4VJOZJDV.js → chunk-3JPQAIYJ.js} +2 -2
  129. package/dist/{chunk-27EORKJ4.js → chunk-3N4LNBJF.js} +2 -2
  130. package/dist/{chunk-7JZSFJHB.js → chunk-3OJU3RUR.js} +2 -2
  131. package/dist/{chunk-NV5OYV3G.js → chunk-3U6K36QA.js} +5 -5
  132. package/dist/{chunk-MDRLP5DO.js → chunk-3W7ROHN4.js} +3 -3
  133. package/dist/{chunk-3MQM4ZOC.js → chunk-3Y6ZR2VN.js} +3 -3
  134. package/dist/{chunk-HXZIX7MR.js → chunk-47AB65IO.js} +4 -4
  135. package/dist/{chunk-DNYD7AUG.js → chunk-4BOLIZ7Y.js} +3 -3
  136. package/dist/{chunk-4XO346BW.js → chunk-4FBJFQFU.js} +2 -2
  137. package/dist/{chunk-BWKZEW6K.js → chunk-4T3E56NT.js} +3 -3
  138. package/dist/{chunk-4PC7LIQK.js → chunk-4ZMUWRFF.js} +3 -3
  139. package/dist/{chunk-TM2ZLY3Q.js → chunk-5OLFYSVG.js} +13 -13
  140. package/dist/{chunk-D4QOZXPM.js → chunk-5WBRM7V4.js} +5 -5
  141. package/dist/{chunk-GXK4CUAB.js → chunk-5WQKTT5Z.js} +2 -2
  142. package/dist/{chunk-6N7W3TOV.js → chunk-63BPMTBM.js} +2 -2
  143. package/dist/{chunk-R5YZ3ROM.js → chunk-63PQKTTT.js} +2 -2
  144. package/dist/{chunk-WLZVXCPZ.js → chunk-6GO6WN22.js} +3 -3
  145. package/dist/{chunk-6PQBKMUL.js → chunk-6IIA63VD.js} +11 -7
  146. package/dist/chunk-6IIA63VD.js.map +1 -0
  147. package/dist/{chunk-XDCZBOEY.js → chunk-6LGBGPBU.js} +1 -1
  148. package/dist/{chunk-FMATVQFW.js → chunk-6XXMG5YP.js} +9 -9
  149. package/dist/{chunk-M5E3CKSE.js → chunk-7QWWE5XL.js} +2 -2
  150. package/dist/{chunk-RABKQFTA.js → chunk-A2HCAMRH.js} +2 -2
  151. package/dist/{chunk-6K3WNTRI.js → chunk-AODISQO6.js} +2 -2
  152. package/dist/{chunk-C6JL6PBL.js → chunk-AQDRH6VF.js} +3 -3
  153. package/dist/{chunk-72XEFLMD.js → chunk-ASWINLSW.js} +2 -2
  154. package/dist/{chunk-ZPZYYSHW.js → chunk-BVMDON5T.js} +8 -8
  155. package/dist/{chunk-EURDMOXZ.js → chunk-BYJZUCOQ.js} +2 -2
  156. package/dist/{chunk-BQWUXC55.js → chunk-CAVAVT5S.js} +9 -9
  157. package/dist/{chunk-ZWACUOU5.js → chunk-CDBGAAJY.js} +3 -3
  158. package/dist/chunk-CDBGAAJY.js.map +1 -0
  159. package/dist/{chunk-BPD4IJBG.js → chunk-CG6CJMIS.js} +2 -2
  160. package/dist/{chunk-B254JG72.js → chunk-CQX24PT7.js} +2 -2
  161. package/dist/{chunk-65K5LV4L.js → chunk-CTCOVPZU.js} +51 -50
  162. package/dist/{chunk-65K5LV4L.js.map → chunk-CTCOVPZU.js.map} +1 -1
  163. package/dist/{chunk-HJTTDLF6.js → chunk-CY3NO4JN.js} +4 -4
  164. package/dist/{chunk-OLUG4IFF.js → chunk-D2RLPRSG.js} +2 -2
  165. package/dist/{chunk-74NIHMAT.js → chunk-D653JH6D.js} +3 -3
  166. package/dist/{chunk-2LUO22FR.js → chunk-DAI5CTQF.js} +4 -4
  167. package/dist/{chunk-HTKVYEVB.js → chunk-DBM4ZXDN.js} +2 -2
  168. package/dist/{chunk-MB2DTUEG.js → chunk-DNYKLU3K.js} +4 -4
  169. package/dist/{chunk-26P7B46A.js → chunk-DXYARXK3.js} +3 -3
  170. package/dist/{chunk-JQKURO3S.js → chunk-E4MQRQ6Z.js} +2 -2
  171. package/dist/{chunk-KW53DBY7.js → chunk-EBW2E32G.js} +2 -2
  172. package/dist/{chunk-O73DRA77.js → chunk-ENKBO7FC.js} +4 -4
  173. package/dist/{chunk-FVCLVASD.js → chunk-FI3KRVOF.js} +24 -24
  174. package/dist/{chunk-WWM7WVD2.js → chunk-GABFKHQE.js} +2 -2
  175. package/dist/chunk-GLCOKWLH.js +42 -0
  176. package/dist/chunk-GLCOKWLH.js.map +1 -0
  177. package/dist/{chunk-32HA7DXJ.js → chunk-GNBRB3DH.js} +25 -25
  178. package/dist/{chunk-CEQUNJJY.js → chunk-HPALK6LD.js} +2 -2
  179. package/dist/{chunk-LR7U3HCD.js → chunk-HPSATFLQ.js} +4 -4
  180. package/dist/{chunk-O4AWXTZQ.js → chunk-HUYLQW75.js} +6 -6
  181. package/dist/{chunk-PQCFW2KT.js → chunk-IDDHH5AQ.js} +29 -24
  182. package/dist/chunk-IDDHH5AQ.js.map +1 -0
  183. package/dist/{chunk-ZZUKJ5HQ.js → chunk-IG2ERMSB.js} +2 -2
  184. package/dist/{chunk-2SZ3KC5S.js → chunk-IMKIIS4Y.js} +2 -2
  185. package/dist/{chunk-CA64OZLZ.js → chunk-IRXPXDY5.js} +4 -4
  186. package/dist/{chunk-I57HZMMA.js → chunk-IXIE3H43.js} +2 -2
  187. package/dist/{chunk-OWJD3V4V.js → chunk-J3YQ3554.js} +2 -2
  188. package/dist/{chunk-BCFHMBMK.js → chunk-J5HZBHU4.js} +7 -7
  189. package/dist/{chunk-UHMMRQGU.js → chunk-KD7GNHOP.js} +3 -3
  190. package/dist/{chunk-X7Z4B5GK.js → chunk-KPL7EXS6.js} +2 -2
  191. package/dist/{chunk-GTR2WUBA.js → chunk-KX6M5CJI.js} +1 -1
  192. package/dist/{chunk-CYO5HL4C.js → chunk-KYL2BPS2.js} +2 -2
  193. package/dist/{chunk-QLDMF7MH.js → chunk-LC5HE7PZ.js} +2 -2
  194. package/dist/{chunk-3SMJ2BIQ.js → chunk-LGD5RESZ.js} +7 -33
  195. package/dist/chunk-LGD5RESZ.js.map +1 -0
  196. package/dist/{chunk-4ICPJZAB.js → chunk-LMYSYG6U.js} +2 -2
  197. package/dist/{chunk-3ZZOE4SN.js → chunk-LOCDYMD6.js} +4 -4
  198. package/dist/{chunk-DNWBLT4U.js → chunk-MASBMJ2M.js} +2 -2
  199. package/dist/{chunk-NZMQDUOD.js → chunk-MU6HYDNF.js} +5 -5
  200. package/dist/{chunk-GMVKCEBG.js → chunk-MY6QEDZ2.js} +2 -2
  201. package/dist/{chunk-SK57RWSA.js → chunk-MZGKQ5WV.js} +2 -2
  202. package/dist/{chunk-HSQRYJ4P.js → chunk-N52SFH2K.js} +2 -2
  203. package/dist/{chunk-MY6VZVCP.js → chunk-OAJX5CEL.js} +4 -4
  204. package/dist/{chunk-IWIMIRV3.js → chunk-OSJTLQXA.js} +9 -4
  205. package/dist/chunk-OSJTLQXA.js.map +1 -0
  206. package/dist/{chunk-FH75NNLB.js → chunk-OZ5NAXCP.js} +2 -2
  207. package/dist/{chunk-PEGNFZ3F.js → chunk-P5S777YI.js} +2 -2
  208. package/dist/{chunk-LY6727IF.js → chunk-PPSVFNEA.js} +1 -1
  209. package/dist/{chunk-K4FDZVMQ.js → chunk-PR42VIVY.js} +2 -2
  210. package/dist/{chunk-I74J2UZ2.js → chunk-PWMZCW4H.js} +8 -8
  211. package/dist/{chunk-6YDXUE5H.js → chunk-PYA2O3WS.js} +2 -2
  212. package/dist/{chunk-GUIZDI5T.js → chunk-Q2PA4KZS.js} +2 -2
  213. package/dist/{chunk-JJ7VMIEQ.js → chunk-QCANSTLU.js} +64 -64
  214. package/dist/{chunk-DZH2HTTB.js → chunk-R27GW5WV.js} +1 -1
  215. package/dist/chunk-R4U4EWZG.js +414 -0
  216. package/dist/chunk-R4U4EWZG.js.map +1 -0
  217. package/dist/{chunk-DAQG3C4W.js → chunk-R6JY22SG.js} +29 -29
  218. package/dist/{chunk-7OIBLMDP.js → chunk-RAQISW42.js} +2 -2
  219. package/dist/{chunk-DNLXQUBX.js → chunk-RLS6PTL4.js} +32 -44
  220. package/dist/chunk-RLS6PTL4.js.map +1 -0
  221. package/dist/{chunk-CPKD2YGK.js → chunk-RNU5CUPI.js} +2 -2
  222. package/dist/{chunk-467VRP4E.js → chunk-RO5YZQHZ.js} +3 -3
  223. package/dist/{chunk-SSZROOOI.js → chunk-ROLXYGT5.js} +2 -2
  224. package/dist/{chunk-6VITVQ23.js → chunk-SHJ5SQOW.js} +7 -7
  225. package/dist/{chunk-F4B2YYCN.js → chunk-TAWFXRXB.js} +3 -3
  226. package/dist/{chunk-G3FU2IF7.js → chunk-TB7UW5BB.js} +3 -3
  227. package/dist/{chunk-NF6Q4XTN.js → chunk-TQF2I5SY.js} +3 -3
  228. package/dist/{chunk-MM7OKOTE.js → chunk-UBXHP224.js} +43 -18
  229. package/dist/chunk-UBXHP224.js.map +1 -0
  230. package/dist/{chunk-M7A226EQ.js → chunk-UL44R3W2.js} +2 -2
  231. package/dist/{chunk-GTR5NLVP.js → chunk-VCRQPLKS.js} +2 -2
  232. package/dist/{chunk-MHIYYHCL.js → chunk-VJU3ET7N.js} +12 -12
  233. package/dist/{chunk-RXMIXKB3.js → chunk-WGJUARF3.js} +13 -13
  234. package/dist/{chunk-NWSAF6P5.js → chunk-WJDH7CH5.js} +22 -1
  235. package/dist/chunk-WJDH7CH5.js.map +1 -0
  236. package/dist/{chunk-LG67ZNRU.js → chunk-WK2ZCTUF.js} +2 -2
  237. package/dist/{chunk-XGE75VPK.js → chunk-WNARM3LY.js} +3 -3
  238. package/dist/{chunk-RNBH5TSM.js → chunk-WQ2RTQYO.js} +2 -2
  239. package/dist/chunk-X5XEYQ4B.js +84 -0
  240. package/dist/chunk-X5XEYQ4B.js.map +1 -0
  241. package/dist/{chunk-W57QFLQD.js → chunk-X6JIGNLI.js} +4 -4
  242. package/dist/{chunk-CKA4SJRK.js → chunk-XIQDCQX7.js} +2 -2
  243. package/dist/{chunk-AJ7PY4FJ.js → chunk-Y3GCG6CA.js} +2 -2
  244. package/dist/{chunk-2K27S6LK.js → chunk-Y565N5ZJ.js} +24 -7
  245. package/dist/chunk-Y565N5ZJ.js.map +1 -0
  246. package/dist/{chunk-ZRB4M3GG.js → chunk-YC5KH7ZB.js} +3 -3
  247. package/dist/{chunk-4RY64KQY.js → chunk-YJUKLLNP.js} +2 -2
  248. package/dist/{chunk-OHG2UQ2O.js → chunk-YWP2H7SX.js} +60 -22
  249. package/dist/chunk-YWP2H7SX.js.map +1 -0
  250. package/dist/{chunk-24POWVUY.js → chunk-ZDJNRRVS.js} +4 -4
  251. package/dist/{chunk-S6WJ6TUT.js → chunk-ZEVJGMNB.js} +2 -2
  252. package/dist/chunk-ZEVJGMNB.js.map +1 -0
  253. package/dist/{chunk-M7YEZR6X.js → chunk-ZITMDA4C.js} +2 -2
  254. package/dist/components/model-policy-picker.d.ts +2 -0
  255. package/dist/composer.js +6 -6
  256. package/dist/{computer-viewer-BWVNDFTO.js → computer-viewer-6CRLWQHP.js} +5 -5
  257. package/dist/connect.js +6 -6
  258. package/dist/connection-service-presentation.d.ts +1 -4
  259. package/dist/desktop.js +2 -2
  260. package/dist/editor.js +2 -2
  261. package/dist/{embedded-new-voice-GBXSZ3TO.js → embedded-new-voice-KILV3RYM.js} +5 -5
  262. package/dist/{embedded-voice-MGI7EK7C.js → embedded-voice-GHDRLCFX.js} +5 -5
  263. package/dist/{fleet-decision-row-35S3GAUN.js → fleet-decision-row-DQXRRBT7.js} +2 -2
  264. package/dist/index.js +44 -44
  265. package/dist/interaction.js +5 -5
  266. package/dist/machines.js +3 -3
  267. package/dist/messages/en.d.ts +1 -1
  268. package/dist/messages.js +1 -1
  269. package/dist/{model-policy-picker-menu-KP53N6UJ.js → model-policy-picker-menu-5ALKUJMR.js} +4 -4
  270. package/dist/{platform-activity-row-ISMXR7NJ.js → platform-activity-row-227C764Z.js} +2 -2
  271. package/dist/{queue-surface-implementation-ULW7DDJA.js → queue-surface-implementation-H3NOBXU5.js} +5 -5
  272. package/dist/realtime.js +4 -4
  273. package/dist/{sandbox-files-QYSD4XCZ.js → sandbox-files-5FEOHUMD.js} +6 -6
  274. package/dist/session-app.js +155 -157
  275. package/dist/{session-realtime-JXRLPNUH.js → session-realtime-OHBMODNX.js} +3 -3
  276. package/dist/session-realtime.js +2 -2
  277. package/dist/session-ui.js +26 -26
  278. package/dist/session.js +6 -6
  279. package/dist/sites.js +2 -2
  280. package/dist/terminal.js +2 -2
  281. package/dist/this-computer.js +3 -3
  282. package/dist/timeline/connector-logo-index.d.ts +19 -0
  283. package/dist/{timeline-annotation-markers-OJYKHBEO.js → timeline-annotation-markers-NDHS7MCK.js} +2 -2
  284. package/dist/{timeline-annotation-selection-6OAZLXFU.js → timeline-annotation-selection-DRQSTJOV.js} +2 -2
  285. package/dist/{timeline-annotations-dialog-5M6DP5FX.js → timeline-annotations-dialog-G6J5ZJKN.js} +3 -3
  286. package/dist/timeline-model.d.ts +2 -0
  287. package/dist/timeline-model.js +9 -1
  288. package/dist/ui/list-row.js +1 -1
  289. package/dist/usage.js +2 -2
  290. package/dist/workbench.js +4 -4
  291. package/package.json +4 -4
  292. package/src/app/components/capabilities/native-connect-readiness.tsx +1 -0
  293. package/src/app/components/capabilities/perform-capability-action.test.ts +67 -0
  294. package/src/app/components/capabilities/perform-capability-action.tsx +28 -0
  295. package/src/app/components/command-menu/chat-switcher.tsx +25 -4
  296. package/src/app/components/rail/session-header.test.tsx +73 -2
  297. package/src/app/components/rail/session-header.tsx +20 -12
  298. package/src/app/components/rail/session-shell.tsx +10 -18
  299. package/src/app/components/session/subscription-account-indicator.test.ts +239 -0
  300. package/src/app/components/session/subscription-account-indicator.tsx +361 -0
  301. package/src/app/components/session/subscription-account-menu.tsx +21 -43
  302. package/src/app/components/session/subscription-account.test.ts +314 -0
  303. package/src/app/components/session/subscription-account.ts +354 -0
  304. package/src/app/lib/actions/actions-provider.tsx +11 -0
  305. package/src/app/lib/actions/actions.test.ts +59 -4
  306. package/src/app/lib/actions/chat-switcher.ts +73 -20
  307. package/src/app/lib/drive-connect-return.test.ts +183 -0
  308. package/src/app/lib/drive-connect-return.tsx +116 -0
  309. package/src/app/routes/session.tsx +12 -14
  310. package/src/app/routes/sessions-index.tsx +1 -0
  311. package/src/components/model-policy-picker-menu.tsx +25 -4
  312. package/src/components/model-policy-picker.tsx +2 -0
  313. package/src/components/session-mcp-capability-card.tsx +13 -4
  314. package/src/connection-service-presentation.ts +6 -1
  315. package/src/messages/en.ts +1 -1
  316. package/src/timeline/connector-logo-index.test.ts +46 -0
  317. package/src/timeline/connector-logo-index.ts +68 -0
  318. package/src/timeline-model.ts +6 -0
  319. package/src/ui/list-row.tsx +38 -10
  320. package/styles/compiled.css +13 -0
  321. package/dist/app/components/session/codex-account-indicator.d.ts +0 -9
  322. package/dist/app/components/session/model-account-indicator.d.ts +0 -10
  323. package/dist/app/components/session/model-account-indicator.js +0 -34
  324. package/dist/app/components/session/model-account-usage.d.ts +0 -8
  325. package/dist/app/components/session/model-account-usage.js +0 -8
  326. package/dist/chunk-2K27S6LK.js.map +0 -1
  327. package/dist/chunk-3SMJ2BIQ.js.map +0 -1
  328. package/dist/chunk-6PQBKMUL.js.map +0 -1
  329. package/dist/chunk-7H2D4VNU.js +0 -150
  330. package/dist/chunk-7H2D4VNU.js.map +0 -1
  331. package/dist/chunk-DNLXQUBX.js.map +0 -1
  332. package/dist/chunk-HCCSAECI.js +0 -132
  333. package/dist/chunk-HCCSAECI.js.map +0 -1
  334. package/dist/chunk-IWIMIRV3.js.map +0 -1
  335. package/dist/chunk-M77ZQE5T.js +0 -58
  336. package/dist/chunk-M77ZQE5T.js.map +0 -1
  337. package/dist/chunk-MM7OKOTE.js.map +0 -1
  338. package/dist/chunk-NPDL4W4Y.js.map +0 -1
  339. package/dist/chunk-NWSAF6P5.js.map +0 -1
  340. package/dist/chunk-OHG2UQ2O.js.map +0 -1
  341. package/dist/chunk-PQCFW2KT.js.map +0 -1
  342. package/dist/chunk-S6WJ6TUT.js.map +0 -1
  343. package/dist/chunk-ZWACUOU5.js.map +0 -1
  344. package/dist/session-realtime-JXRLPNUH.js.map +0 -1
  345. package/src/app/components/session/codex-account-indicator.tsx +0 -207
  346. package/src/app/components/session/model-account-indicator.tsx +0 -189
  347. package/src/app/components/session/model-account-usage.test.ts +0 -59
  348. package/src/app/components/session/model-account-usage.tsx +0 -89
  349. /package/dist/app/components/session/{codex-account-indicator.js.map → subscription-account-indicator.js.map} +0 -0
  350. /package/dist/app/{components/session/model-account-indicator.js.map → lib/drive-connect-return.js.map} +0 -0
  351. /package/dist/{app/components/session/model-account-usage.js.map → browser-viewer-VKIAULG7.js.map} +0 -0
  352. /package/dist/{browser-viewer-YQC6BFMS.js.map → chat-interactive-block-JGYSW4KB.js.map} +0 -0
  353. /package/dist/{chunk-WN2MIB4Q.js.map → chunk-22V2QCEM.js.map} +0 -0
  354. /package/dist/{chunk-SJPAKWWP.js.map → chunk-2BISI664.js.map} +0 -0
  355. /package/dist/{chunk-O5UOCMH4.js.map → chunk-2LPJVEWY.js.map} +0 -0
  356. /package/dist/{chunk-JI6WPLZB.js.map → chunk-2SBCOGQN.js.map} +0 -0
  357. /package/dist/{chunk-6JF7C3U3.js.map → chunk-2WERWWSS.js.map} +0 -0
  358. /package/dist/{chunk-4XKT4ENZ.js.map → chunk-2Y3QL3DA.js.map} +0 -0
  359. /package/dist/{chunk-KVMFT6FN.js.map → chunk-3FL3F4WF.js.map} +0 -0
  360. /package/dist/{chunk-4VJOZJDV.js.map → chunk-3JPQAIYJ.js.map} +0 -0
  361. /package/dist/{chunk-27EORKJ4.js.map → chunk-3N4LNBJF.js.map} +0 -0
  362. /package/dist/{chunk-7JZSFJHB.js.map → chunk-3OJU3RUR.js.map} +0 -0
  363. /package/dist/{chunk-NV5OYV3G.js.map → chunk-3U6K36QA.js.map} +0 -0
  364. /package/dist/{chunk-MDRLP5DO.js.map → chunk-3W7ROHN4.js.map} +0 -0
  365. /package/dist/{chunk-3MQM4ZOC.js.map → chunk-3Y6ZR2VN.js.map} +0 -0
  366. /package/dist/{chunk-HXZIX7MR.js.map → chunk-47AB65IO.js.map} +0 -0
  367. /package/dist/{chunk-DNYD7AUG.js.map → chunk-4BOLIZ7Y.js.map} +0 -0
  368. /package/dist/{chunk-4XO346BW.js.map → chunk-4FBJFQFU.js.map} +0 -0
  369. /package/dist/{chunk-BWKZEW6K.js.map → chunk-4T3E56NT.js.map} +0 -0
  370. /package/dist/{chunk-4PC7LIQK.js.map → chunk-4ZMUWRFF.js.map} +0 -0
  371. /package/dist/{chunk-TM2ZLY3Q.js.map → chunk-5OLFYSVG.js.map} +0 -0
  372. /package/dist/{chunk-D4QOZXPM.js.map → chunk-5WBRM7V4.js.map} +0 -0
  373. /package/dist/{chunk-GXK4CUAB.js.map → chunk-5WQKTT5Z.js.map} +0 -0
  374. /package/dist/{chunk-6N7W3TOV.js.map → chunk-63BPMTBM.js.map} +0 -0
  375. /package/dist/{chunk-R5YZ3ROM.js.map → chunk-63PQKTTT.js.map} +0 -0
  376. /package/dist/{chunk-WLZVXCPZ.js.map → chunk-6GO6WN22.js.map} +0 -0
  377. /package/dist/{chunk-XDCZBOEY.js.map → chunk-6LGBGPBU.js.map} +0 -0
  378. /package/dist/{chunk-FMATVQFW.js.map → chunk-6XXMG5YP.js.map} +0 -0
  379. /package/dist/{chunk-M5E3CKSE.js.map → chunk-7QWWE5XL.js.map} +0 -0
  380. /package/dist/{chunk-RABKQFTA.js.map → chunk-A2HCAMRH.js.map} +0 -0
  381. /package/dist/{chunk-6K3WNTRI.js.map → chunk-AODISQO6.js.map} +0 -0
  382. /package/dist/{chunk-C6JL6PBL.js.map → chunk-AQDRH6VF.js.map} +0 -0
  383. /package/dist/{chunk-72XEFLMD.js.map → chunk-ASWINLSW.js.map} +0 -0
  384. /package/dist/{chunk-ZPZYYSHW.js.map → chunk-BVMDON5T.js.map} +0 -0
  385. /package/dist/{chunk-EURDMOXZ.js.map → chunk-BYJZUCOQ.js.map} +0 -0
  386. /package/dist/{chunk-BQWUXC55.js.map → chunk-CAVAVT5S.js.map} +0 -0
  387. /package/dist/{chunk-BPD4IJBG.js.map → chunk-CG6CJMIS.js.map} +0 -0
  388. /package/dist/{chunk-B254JG72.js.map → chunk-CQX24PT7.js.map} +0 -0
  389. /package/dist/{chunk-HJTTDLF6.js.map → chunk-CY3NO4JN.js.map} +0 -0
  390. /package/dist/{chunk-OLUG4IFF.js.map → chunk-D2RLPRSG.js.map} +0 -0
  391. /package/dist/{chunk-74NIHMAT.js.map → chunk-D653JH6D.js.map} +0 -0
  392. /package/dist/{chunk-2LUO22FR.js.map → chunk-DAI5CTQF.js.map} +0 -0
  393. /package/dist/{chunk-HTKVYEVB.js.map → chunk-DBM4ZXDN.js.map} +0 -0
  394. /package/dist/{chunk-MB2DTUEG.js.map → chunk-DNYKLU3K.js.map} +0 -0
  395. /package/dist/{chunk-26P7B46A.js.map → chunk-DXYARXK3.js.map} +0 -0
  396. /package/dist/{chunk-JQKURO3S.js.map → chunk-E4MQRQ6Z.js.map} +0 -0
  397. /package/dist/{chunk-KW53DBY7.js.map → chunk-EBW2E32G.js.map} +0 -0
  398. /package/dist/{chunk-O73DRA77.js.map → chunk-ENKBO7FC.js.map} +0 -0
  399. /package/dist/{chunk-FVCLVASD.js.map → chunk-FI3KRVOF.js.map} +0 -0
  400. /package/dist/{chunk-WWM7WVD2.js.map → chunk-GABFKHQE.js.map} +0 -0
  401. /package/dist/{chunk-32HA7DXJ.js.map → chunk-GNBRB3DH.js.map} +0 -0
  402. /package/dist/{chunk-CEQUNJJY.js.map → chunk-HPALK6LD.js.map} +0 -0
  403. /package/dist/{chunk-LR7U3HCD.js.map → chunk-HPSATFLQ.js.map} +0 -0
  404. /package/dist/{chunk-O4AWXTZQ.js.map → chunk-HUYLQW75.js.map} +0 -0
  405. /package/dist/{chunk-ZZUKJ5HQ.js.map → chunk-IG2ERMSB.js.map} +0 -0
  406. /package/dist/{chunk-2SZ3KC5S.js.map → chunk-IMKIIS4Y.js.map} +0 -0
  407. /package/dist/{chunk-CA64OZLZ.js.map → chunk-IRXPXDY5.js.map} +0 -0
  408. /package/dist/{chunk-I57HZMMA.js.map → chunk-IXIE3H43.js.map} +0 -0
  409. /package/dist/{chunk-OWJD3V4V.js.map → chunk-J3YQ3554.js.map} +0 -0
  410. /package/dist/{chunk-BCFHMBMK.js.map → chunk-J5HZBHU4.js.map} +0 -0
  411. /package/dist/{chunk-UHMMRQGU.js.map → chunk-KD7GNHOP.js.map} +0 -0
  412. /package/dist/{chunk-X7Z4B5GK.js.map → chunk-KPL7EXS6.js.map} +0 -0
  413. /package/dist/{chunk-GTR2WUBA.js.map → chunk-KX6M5CJI.js.map} +0 -0
  414. /package/dist/{chunk-CYO5HL4C.js.map → chunk-KYL2BPS2.js.map} +0 -0
  415. /package/dist/{chunk-QLDMF7MH.js.map → chunk-LC5HE7PZ.js.map} +0 -0
  416. /package/dist/{chunk-4ICPJZAB.js.map → chunk-LMYSYG6U.js.map} +0 -0
  417. /package/dist/{chunk-3ZZOE4SN.js.map → chunk-LOCDYMD6.js.map} +0 -0
  418. /package/dist/{chunk-DNWBLT4U.js.map → chunk-MASBMJ2M.js.map} +0 -0
  419. /package/dist/{chunk-NZMQDUOD.js.map → chunk-MU6HYDNF.js.map} +0 -0
  420. /package/dist/{chunk-GMVKCEBG.js.map → chunk-MY6QEDZ2.js.map} +0 -0
  421. /package/dist/{chunk-SK57RWSA.js.map → chunk-MZGKQ5WV.js.map} +0 -0
  422. /package/dist/{chunk-HSQRYJ4P.js.map → chunk-N52SFH2K.js.map} +0 -0
  423. /package/dist/{chunk-MY6VZVCP.js.map → chunk-OAJX5CEL.js.map} +0 -0
  424. /package/dist/{chunk-FH75NNLB.js.map → chunk-OZ5NAXCP.js.map} +0 -0
  425. /package/dist/{chunk-PEGNFZ3F.js.map → chunk-P5S777YI.js.map} +0 -0
  426. /package/dist/{chunk-LY6727IF.js.map → chunk-PPSVFNEA.js.map} +0 -0
  427. /package/dist/{chunk-K4FDZVMQ.js.map → chunk-PR42VIVY.js.map} +0 -0
  428. /package/dist/{chunk-I74J2UZ2.js.map → chunk-PWMZCW4H.js.map} +0 -0
  429. /package/dist/{chunk-6YDXUE5H.js.map → chunk-PYA2O3WS.js.map} +0 -0
  430. /package/dist/{chunk-GUIZDI5T.js.map → chunk-Q2PA4KZS.js.map} +0 -0
  431. /package/dist/{chunk-JJ7VMIEQ.js.map → chunk-QCANSTLU.js.map} +0 -0
  432. /package/dist/{chunk-DZH2HTTB.js.map → chunk-R27GW5WV.js.map} +0 -0
  433. /package/dist/{chunk-DAQG3C4W.js.map → chunk-R6JY22SG.js.map} +0 -0
  434. /package/dist/{chunk-7OIBLMDP.js.map → chunk-RAQISW42.js.map} +0 -0
  435. /package/dist/{chunk-CPKD2YGK.js.map → chunk-RNU5CUPI.js.map} +0 -0
  436. /package/dist/{chunk-467VRP4E.js.map → chunk-RO5YZQHZ.js.map} +0 -0
  437. /package/dist/{chunk-SSZROOOI.js.map → chunk-ROLXYGT5.js.map} +0 -0
  438. /package/dist/{chunk-6VITVQ23.js.map → chunk-SHJ5SQOW.js.map} +0 -0
  439. /package/dist/{chunk-F4B2YYCN.js.map → chunk-TAWFXRXB.js.map} +0 -0
  440. /package/dist/{chunk-G3FU2IF7.js.map → chunk-TB7UW5BB.js.map} +0 -0
  441. /package/dist/{chunk-NF6Q4XTN.js.map → chunk-TQF2I5SY.js.map} +0 -0
  442. /package/dist/{chunk-M7A226EQ.js.map → chunk-UL44R3W2.js.map} +0 -0
  443. /package/dist/{chunk-GTR5NLVP.js.map → chunk-VCRQPLKS.js.map} +0 -0
  444. /package/dist/{chunk-MHIYYHCL.js.map → chunk-VJU3ET7N.js.map} +0 -0
  445. /package/dist/{chunk-RXMIXKB3.js.map → chunk-WGJUARF3.js.map} +0 -0
  446. /package/dist/{chunk-LG67ZNRU.js.map → chunk-WK2ZCTUF.js.map} +0 -0
  447. /package/dist/{chunk-XGE75VPK.js.map → chunk-WNARM3LY.js.map} +0 -0
  448. /package/dist/{chunk-RNBH5TSM.js.map → chunk-WQ2RTQYO.js.map} +0 -0
  449. /package/dist/{chunk-W57QFLQD.js.map → chunk-X6JIGNLI.js.map} +0 -0
  450. /package/dist/{chunk-CKA4SJRK.js.map → chunk-XIQDCQX7.js.map} +0 -0
  451. /package/dist/{chunk-AJ7PY4FJ.js.map → chunk-Y3GCG6CA.js.map} +0 -0
  452. /package/dist/{chunk-ZRB4M3GG.js.map → chunk-YC5KH7ZB.js.map} +0 -0
  453. /package/dist/{chunk-4RY64KQY.js.map → chunk-YJUKLLNP.js.map} +0 -0
  454. /package/dist/{chunk-24POWVUY.js.map → chunk-ZDJNRRVS.js.map} +0 -0
  455. /package/dist/{chunk-M7YEZR6X.js.map → chunk-ZITMDA4C.js.map} +0 -0
  456. /package/dist/{chat-interactive-block-Z22YHDRU.js.map → computer-viewer-6CRLWQHP.js.map} +0 -0
  457. /package/dist/{computer-viewer-BWVNDFTO.js.map → embedded-new-voice-KILV3RYM.js.map} +0 -0
  458. /package/dist/{embedded-new-voice-GBXSZ3TO.js.map → embedded-voice-GHDRLCFX.js.map} +0 -0
  459. /package/dist/{fleet-decision-row-35S3GAUN.js.map → fleet-decision-row-DQXRRBT7.js.map} +0 -0
  460. /package/dist/{embedded-voice-MGI7EK7C.js.map → model-policy-picker-menu-5ALKUJMR.js.map} +0 -0
  461. /package/dist/{platform-activity-row-ISMXR7NJ.js.map → platform-activity-row-227C764Z.js.map} +0 -0
  462. /package/dist/{queue-surface-implementation-ULW7DDJA.js.map → queue-surface-implementation-H3NOBXU5.js.map} +0 -0
  463. /package/dist/{model-policy-picker-menu-KP53N6UJ.js.map → sandbox-files-5FEOHUMD.js.map} +0 -0
  464. /package/dist/{sandbox-files-QYSD4XCZ.js.map → session-realtime-OHBMODNX.js.map} +0 -0
  465. /package/dist/{timeline-annotation-markers-OJYKHBEO.js.map → timeline-annotation-markers-NDHS7MCK.js.map} +0 -0
  466. /package/dist/{timeline-annotation-selection-6OAZLXFU.js.map → timeline-annotation-selection-DRQSTJOV.js.map} +0 -0
  467. /package/dist/{timeline-annotations-dialog-5M6DP5FX.js.map → timeline-annotations-dialog-G6J5ZJKN.js.map} +0 -0
@@ -83,7 +83,7 @@ function ScopedCard({
83
83
  onConfigured,
84
84
  dialogOnly = false,
85
85
  onClose,
86
- personalOnly = false,
86
+ personalOnly: configuredPersonalOnly = false,
87
87
  connectLabel,
88
88
  dialogSubtitle,
89
89
  description: hostDescription,
@@ -96,6 +96,9 @@ function ScopedCard({
96
96
  );
97
97
  const view = useConnect(controller);
98
98
  const [item, setItem] = useState<CapabilityCatalogItem | null>(null);
99
+ const personalOnly =
100
+ configuredPersonalOnly ||
101
+ (item?.mcpUrl ?? item?.endpointUrl) === "https://drivemcp.googleapis.com/mcp/v1";
99
102
  const [logo, setLogo] = useState<string | null>(null);
100
103
  const [expanded, setExpanded] = useState(dialogOnly);
101
104
  const [complete, setComplete] = useState(false);
@@ -151,7 +154,9 @@ function ScopedCard({
151
154
  setOwnership(resolved.connectionRef.subjectScope === "subject" ? "personal" : "workspace");
152
155
  else if (
153
156
  !item &&
154
- (personalOnly || resolved.metadata?.defaultConnectionOwnership === "personal")
157
+ (personalOnly ||
158
+ (resolved.mcpUrl ?? resolved.endpointUrl) === "https://drivemcp.googleapis.com/mcp/v1" ||
159
+ resolved.metadata?.defaultConnectionOwnership === "personal")
155
160
  )
156
161
  setOwnership("personal");
157
162
  let accountReady = false;
@@ -399,7 +404,8 @@ function ScopedCard({
399
404
  }
400
405
  startInput.current = input;
401
406
  let attempt = await controller.begin({
402
- providerId: "mcp-oauth",
407
+ providerId:
408
+ mcpUrl === "https://drivemcp.googleapis.com/mcp/v1" ? "google-drive" : "mcp-oauth",
403
409
  ownership,
404
410
  returnUrl,
405
411
  idempotencyKey: startKey.current,
@@ -409,7 +415,10 @@ function ScopedCard({
409
415
  remember(attempt.id);
410
416
  if (attempt.state === "credential_input")
411
417
  attempt = await controller.advance(
412
- { type: "credentials", values: { mcpUrl } },
418
+ {
419
+ type: "credentials",
420
+ values: mcpUrl === "https://drivemcp.googleapis.com/mcp/v1" ? {} : { mcpUrl },
421
+ },
413
422
  advanceKey.current,
414
423
  );
415
424
  if (!active()) return;
@@ -4,7 +4,12 @@ import gmailLogo from "./assets/gmail.ico";
4
4
  import outlookLogo from "./assets/outlook.ico";
5
5
 
6
6
  /** Passive service identity only. Never selects an account or grants tool access. */
7
- const services: Record<string, { name: string; logo: string; mcpUrl?: string }> = {
7
+ const services: Record<string, { name: string; logo: string | null; mcpUrl?: string }> = {
8
+ "google-drive": {
9
+ name: "Google Drive",
10
+ logo: null,
11
+ mcpUrl: "https://drivemcp.googleapis.com/mcp/v1",
12
+ },
8
13
  gmail: { name: "Gmail", logo: gmailLogo, mcpUrl: "https://gmailmcp.googleapis.com/mcp/v1" },
9
14
  "microsoft-outlook-mail": { name: "Outlook Mail", logo: outlookLogo },
10
15
  "microsoft-outlook-calendar": { name: "Outlook Calendar", logo: outlookLogo },
@@ -1817,7 +1817,7 @@ export const englishMessages = {
1817
1817
  "modelPolicy.billedToTheWorkspaceProvider": "Billed to the workspace provider account",
1818
1818
  "modelPolicy.billedToTheWorkspaceVercel": "Billed to the workspace Vercel account",
1819
1819
  "modelPolicy.blockedByWorkspacePolicy": "Blocked by workspace policy",
1820
- "modelPolicy.claudeSubscription": "Claude subscription",
1820
+ "modelPolicy.claudeSubscription": "Claude",
1821
1821
  "modelPolicy.claudeSubscriptionExternalBilling": "Claude subscription · external billing",
1822
1822
  "modelPolicy.codex": "Codex",
1823
1823
  "modelPolicy.codexSubscriptionExternalBilling": "Codex subscription · external billing",
@@ -0,0 +1,46 @@
1
+ import { describe, expect, test } from "bun:test";
2
+
3
+ import { connectorLogo, connectorLogoIndex } from "./connector-logo-index";
4
+
5
+ const url = (path: string | null | undefined) => (path ? `/v1/${path}` : null);
6
+
7
+ describe("connectorLogoIndex", () => {
8
+ test("a connector's server host finds the provider's logo", () => {
9
+ const index = connectorLogoIndex(
10
+ [
11
+ {
12
+ providerDomain: "linear.app",
13
+ mcpUrl: "https://mcp.linear.app/mcp",
14
+ logoAssetPath: "logos/linear.png",
15
+ },
16
+ {
17
+ providerDomain: "notion.com",
18
+ connectionRef: { providerDomain: "mcp.notion.com" },
19
+ logoAssetPath: "logos/notion.png",
20
+ },
21
+ ],
22
+ url,
23
+ );
24
+ expect(connectorLogo(index, "mcp.linear.app")).toBe("/v1/logos/linear.png");
25
+ expect(connectorLogo(index, "Linear.app")).toBe("/v1/logos/linear.png");
26
+ expect(connectorLogo(index, "mcp.notion.com")).toBe("/v1/logos/notion.png");
27
+ expect(connectorLogo(index, "example.com")).toBeNull();
28
+ });
29
+
30
+ test("a provider's own domain wins over another entry's server host", () => {
31
+ const index = connectorLogoIndex(
32
+ [
33
+ {
34
+ providerDomain: "relay.example",
35
+ mcpUrl: "https://github.com/mcp",
36
+ logoAssetPath: "logos/relay.png",
37
+ },
38
+ { providerDomain: "github.com", logoAssetPath: "logos/github.png" },
39
+ { providerDomain: "nologo.app", logoAssetPath: null },
40
+ ],
41
+ url,
42
+ );
43
+ expect(connectorLogo(index, "github.com")).toBe("/v1/logos/github.png");
44
+ expect(connectorLogo(index, "nologo.app")).toBeNull();
45
+ });
46
+ });
@@ -0,0 +1,68 @@
1
+ /*
2
+ * Which logo belongs to a connector domain. Tool steps and sign-in cards name
3
+ * their connector by the domain of the connection or MCP server they used
4
+ * (Linear's is mcp.linear.app), while the catalog files the logo under the
5
+ * provider's own domain (linear.app). Indexing every domain a catalog entry is
6
+ * known by lets any of them find the logo. Framework-neutral, so web, native
7
+ * and embedded surfaces resolve logos the same way.
8
+ */
9
+
10
+ /** The catalog fields that name a connector's domains and logo. */
11
+ export type ConnectorLogoSource = {
12
+ providerDomain?: string | null | undefined;
13
+ mcpUrl?: string | null | undefined;
14
+ connectionRef?: { providerDomain?: string | null | undefined } | null | undefined;
15
+ logoAssetPath?: string | null | undefined;
16
+ };
17
+
18
+ /** "WWW.Linear.app " → "linear.app". */
19
+ export function normalizeConnectorDomain(domain: string): string {
20
+ return domain
21
+ .trim()
22
+ .toLowerCase()
23
+ .replace(/^www\./, "");
24
+ }
25
+
26
+ function urlHost(url: string | null | undefined): string | null {
27
+ if (!url) return null;
28
+ try {
29
+ return new URL(url).hostname || null;
30
+ } catch {
31
+ return null;
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Every domain each catalog entry is known by, mapped to its logo URL. The
37
+ * provider's own domain is claimed first across the whole catalog, so another
38
+ * entry's server host never takes over a provider's logo.
39
+ */
40
+ export function connectorLogoIndex(
41
+ catalog: readonly ConnectorLogoSource[],
42
+ logoUrl: (logoAssetPath: string | null | undefined) => string | null | undefined,
43
+ ): ReadonlyMap<string, string> {
44
+ const logos = new Map<string, string>();
45
+ const entries = catalog.flatMap((item) => {
46
+ const url = logoUrl(item.logoAssetPath);
47
+ return url ? [{ item, url }] : [];
48
+ });
49
+ const claim = (domain: string | null | undefined, url: string) => {
50
+ if (!domain) return;
51
+ const key = normalizeConnectorDomain(domain);
52
+ if (key && !logos.has(key)) logos.set(key, url);
53
+ };
54
+ for (const { item, url } of entries) claim(item.providerDomain, url);
55
+ for (const { item, url } of entries) {
56
+ claim(item.connectionRef?.providerDomain, url);
57
+ claim(urlHost(item.mcpUrl), url);
58
+ }
59
+ return logos;
60
+ }
61
+
62
+ /** The logo for a connector domain from an index built by `connectorLogoIndex`. */
63
+ export function connectorLogo(
64
+ index: ReadonlyMap<string, string>,
65
+ domain: string | null | undefined,
66
+ ): string | null {
67
+ return domain ? (index.get(normalizeConnectorDomain(domain)) ?? null) : null;
68
+ }
@@ -32,6 +32,12 @@ export {
32
32
  export type { ActivityGroup, ReadableWorkOptions, TurnGroup } from "./timeline/work-presentation";
33
33
  export { timelineGroupContainsPresentedImage } from "./timeline/presented-image";
34
34
  export { mcpToolLeaf, toolDisplayName } from "./timeline/tool-display-name";
35
+ export {
36
+ connectorLogo,
37
+ connectorLogoIndex,
38
+ normalizeConnectorDomain,
39
+ } from "./timeline/connector-logo-index";
40
+ export type { ConnectorLogoSource } from "./timeline/connector-logo-index";
35
41
  export {
36
42
  BUILT_IN_TOOL_STEP_NAMES,
37
43
  builtInToolStep,
@@ -550,6 +550,11 @@ export function ListRow({
550
550
  const hasColumns = gridded && columns.length > 0;
551
551
  const expandable = !table && expanded !== undefined;
552
552
 
553
+ // Resource and table rows keep one fixed height: the description, the meta
554
+ // facts and (on narrow lists) the status and indicator words share ONE
555
+ // secondary line that truncates. Catalog rows keep a two-line description
556
+ // with the facts under it.
557
+ const singleLine = !catalog;
553
558
  /* The meta line: quiet facts, then the fact columns folded in on narrow lists. */
554
559
  const presentFacts = columns.filter((column) => cells[column.id] != null);
555
560
  const facts = [
@@ -568,6 +573,7 @@ export function ListRow({
568
573
  key={column.id}
569
574
  order={order}
570
575
  keep={leads}
576
+ oneLine={singleLine}
571
577
  className={cn(
572
578
  hasColumns && "@[640px]/list:hidden",
573
579
  // A phone-width line has room for one folded fact (none next to a
@@ -586,8 +592,13 @@ export function ListRow({
586
592
  ...metaItems.map((item, index) => {
587
593
  const last = index === metaItems.length - 1;
588
594
  return (
589
- // oxlint-disable-next-line react/no-array-index-key -- meta items are positional
590
- <MetaPart key={`meta-${index}`} order={leadingFacts + index} keep={!last}>
595
+ <MetaPart
596
+ // oxlint-disable-next-line react/no-array-index-key -- meta items are positional
597
+ key={`meta-${index}`}
598
+ order={leadingFacts + index}
599
+ keep={!last}
600
+ oneLine={singleLine}
601
+ >
591
602
  {item}
592
603
  </MetaPart>
593
604
  );
@@ -598,11 +609,6 @@ export function ListRow({
598
609
  foldedFact(column, leadingFacts + index, leadingFacts + metaItems.length + index, false),
599
610
  ),
600
611
  ];
601
- // Resource and table rows keep one fixed height: the description, the meta
602
- // facts and (on narrow lists) the status and indicator words share ONE
603
- // secondary line that truncates. Catalog rows keep a two-line description
604
- // with the facts under it.
605
- const singleLine = !catalog;
606
612
  const statusPart = status ? (
607
613
  <MetaPart key="status" keep className="@[480px]/list:hidden">
608
614
  {status}
@@ -840,13 +846,18 @@ export function ListRow({
840
846
  <span className="flex shrink-0 items-center">{keptLeadParts}</span>
841
847
  ) : null}
842
848
  {restLineParts.length > 0 ? (
849
+ // One line tall and wrapping: a part with no room for a few
850
+ // letters wraps onto the clipped second line and disappears
851
+ // whole, instead of staying behind as a lone dot. The empty
852
+ // first item lets even the first part wrap away.
843
853
  <span
844
854
  className={cn(
845
- "flex min-w-0 shrink-[2] items-center overflow-hidden",
855
+ "flex h-4.5 min-w-0 shrink-[2] flex-wrap content-start items-center overflow-hidden",
846
856
  // No description: drop the first part's leading dot.
847
857
  !(secondary && !(disabled && disabledReason)) && "-ml-4",
848
858
  )}
849
859
  >
860
+ <span aria-hidden="true" className="h-4.5 w-0 shrink-0" />
850
861
  {restLineParts}
851
862
  </span>
852
863
  ) : null}
@@ -1018,6 +1029,7 @@ function MetaPart({
1018
1029
  hidden = false,
1019
1030
  order = 0,
1020
1031
  keep = false,
1032
+ oneLine = false,
1021
1033
  }: {
1022
1034
  className?: string | undefined;
1023
1035
  children: ReactNode;
@@ -1027,13 +1039,29 @@ function MetaPart({
1027
1039
  order?: number | undefined;
1028
1040
  /** Never shrinks (a status): it stays whole while the facts before it give way. */
1029
1041
  keep?: boolean | undefined;
1042
+ /**
1043
+ * On a one-line meta line (which wraps into a clipped second line): the part
1044
+ * claims room for its dot and a few letters, then takes what is left in
1045
+ * order. One without even that much wraps away whole.
1046
+ */
1047
+ oneLine?: boolean | undefined;
1030
1048
  }) {
1049
+ const sizing: CSSProperties = keep
1050
+ ? { flexShrink: 0 }
1051
+ : oneLine
1052
+ ? // Earlier parts fill to their full width before later ones grow past
1053
+ // their few letters, so the line still gives way from the end.
1054
+ { flexBasis: "3.5rem", flexGrow: 64 ** (4 - Math.min(order, 4)), flexShrink: 0 }
1055
+ : { flexShrink: 64 ** Math.min(order, 4) };
1031
1056
  return (
1032
1057
  <span
1033
1058
  aria-hidden={hidden || undefined}
1034
- style={{ flexShrink: keep ? 0 : 64 ** Math.min(order, 4) }}
1059
+ style={sizing}
1035
1060
  className={cn(
1036
- "flex max-w-full min-w-0 items-center overflow-hidden whitespace-nowrap",
1061
+ "flex min-w-0 items-center overflow-hidden whitespace-nowrap",
1062
+ // max-content caps the growth; the 3.5rem basis is the most a part
1063
+ // asks for before it fits, so a short fact never gains empty space.
1064
+ oneLine && !keep ? "max-w-max" : "max-w-full",
1037
1065
  className,
1038
1066
  )}
1039
1067
  >
@@ -2177,6 +2177,9 @@
2177
2177
  :where(.og-root).max-w-lg,:where(.og-root) .max-w-lg {
2178
2178
  max-width: var(--container-lg);
2179
2179
  }
2180
+ :where(.og-root).max-w-max,:where(.og-root) .max-w-max {
2181
+ max-width: max-content;
2182
+ }
2180
2183
  :where(.og-root).max-w-md,:where(.og-root) .max-w-md {
2181
2184
  max-width: var(--container-md);
2182
2185
  }
@@ -2581,6 +2584,9 @@
2581
2584
  :where(.og-root).content-center,:where(.og-root) .content-center {
2582
2585
  align-content: center;
2583
2586
  }
2587
+ :where(.og-root).content-start,:where(.og-root) .content-start {
2588
+ align-content: flex-start;
2589
+ }
2584
2590
  :where(.og-root).items-baseline,:where(.og-root) .items-baseline {
2585
2591
  align-items: baseline;
2586
2592
  }
@@ -6589,6 +6595,13 @@
6589
6595
  padding-bottom: calc(var(--spacing) * 0);
6590
6596
  }
6591
6597
  }
6598
+ :where(.og-root).odd\:last\:col-span-2,:where(.og-root) .odd\:last\:col-span-2 {
6599
+ &:nth-child(odd) {
6600
+ &:last-child {
6601
+ grid-column: span 2 / span 2;
6602
+ }
6603
+ }
6604
+ }
6592
6605
  :where(.og-root).open\:basis-full,:where(.og-root) .open\:basis-full {
6593
6606
  &:is([open], :popover-open, :open) {
6594
6607
  flex-basis: 100%;
@@ -1,9 +0,0 @@
1
- import type { SessionEvent } from "@opengeni/sdk";
2
- export declare function CodexAccountIndicator({ workspaceId: _workspaceId, sessionId, model, modelReady, events, }: {
3
- workspaceId: string;
4
- sessionId: string;
5
- model: string;
6
- /** False while the session's admitted model identity is still loading. */
7
- modelReady?: boolean;
8
- events?: SessionEvent[];
9
- }): import("react").JSX.Element | null;
@@ -1,10 +0,0 @@
1
- import type { SessionEvent } from "@opengeni/sdk";
2
- export declare function ModelAccountIndicator({ workspaceId, sessionId, organizationId, provider, servingTurnId, events, }: {
3
- workspaceId: string;
4
- sessionId: string;
5
- organizationId: string | null;
6
- /** The session model's subscription provider; only its accounts are offered. */
7
- provider: string;
8
- servingTurnId?: string | undefined;
9
- events?: SessionEvent[];
10
- }): import("react").JSX.Element | null;
@@ -1,34 +0,0 @@
1
- "use client";
2
- import {
3
- ModelAccountIndicator
4
- } from "../../../chunk-HCCSAECI.js";
5
- import "../../../chunk-M77ZQE5T.js";
6
- import "../../../chunk-3SMJ2BIQ.js";
7
- import "../../../chunk-M7YEZR6X.js";
8
- import "../../../chunk-Z63GB7JI.js";
9
- import "../../../chunk-A3MTTRCX.js";
10
- import "../../../chunk-TREHTIBD.js";
11
- import "../../../chunk-5OTQA7CM.js";
12
- import "../../../chunk-BMJTNPWK.js";
13
- import "../../../chunk-CKA4SJRK.js";
14
- import "../../../chunk-NLAFNMPK.js";
15
- import "../../../chunk-RZLBICR5.js";
16
- import "../../../chunk-IGVL3ELX.js";
17
- import "../../../chunk-ZWACUOU5.js";
18
- import "../../../chunk-PNNTR6KP.js";
19
- import "../../../chunk-WJPMYXKZ.js";
20
- import "../../../chunk-VYT4POBH.js";
21
- import "../../../chunk-IQ64BNAG.js";
22
- import "../../../chunk-J3BHDXQQ.js";
23
- import "../../../chunk-CFEFYPNR.js";
24
- import "../../../chunk-N7S72EXK.js";
25
- import "../../../chunk-XEA5BCMA.js";
26
- import "../../../chunk-2KO2G3RI.js";
27
- import "../../../chunk-CM7LVUKC.js";
28
- import "../../../chunk-TVQCDDSZ.js";
29
- import "../../../chunk-TXS65BB2.js";
30
- import "../../../chunk-S6WJ6TUT.js";
31
- export {
32
- ModelAccountIndicator
33
- };
34
- //# sourceMappingURL=model-account-indicator.js.map
@@ -1,8 +0,0 @@
1
- import type { ModelAccountUsageSnapshot } from "@opengeni/sdk";
2
- import type { SubscriptionAccountUsageWindow } from "./subscription-account-menu.js";
3
- export declare function modelAccountUsage(usage: ModelAccountUsageSnapshot | null | undefined, now?: number): {
4
- windows?: SubscriptionAccountUsageWindow[];
5
- message?: string;
6
- note?: string;
7
- summary?: string;
8
- };
@@ -1,8 +0,0 @@
1
- "use client";
2
- import {
3
- modelAccountUsage
4
- } from "../../../chunk-M77ZQE5T.js";
5
- export {
6
- modelAccountUsage
7
- };
8
- //# sourceMappingURL=model-account-usage.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/model-policy-picker-menu.tsx"],"sourcesContent":["import type { ClientModel, LatencyMode, ReasoningEffort } from \"@opengeni/sdk\";\nimport { ArrowRightIcon, CheckIcon, SearchIcon, ZapIcon } from \"lucide-react\";\nimport { useRef, useState, type RefObject, type CSSProperties } from \"react\";\nimport { Popover, RadioGroup } from \"radix-ui\";\nimport { containedPortal } from \"../ui/portal-container\";\nimport { cn } from \"../lib/cn\";\nimport {\n MENU_CHECK_CLASS,\n MENU_LABEL_CLASS,\n MENU_NOTE_CLASS,\n MENU_SURFACE_CLASS,\n} from \"../lib/menu-styles\";\nimport { labelReasoningEffort, type PickerModelRow } from \"../model-policy\";\nimport {\n compactEffortLabel,\n groupPresentationFor,\n modelPickerChoice,\n modelPickerMenuView,\n} from \"../model-picker-model\";\nimport {\n BillingClassMark,\n defaultModelPolicyPickerMessages,\n PickerNavRow,\n type ModelPolicyPickerProps,\n} from \"./model-policy-picker\";\nimport { ModelMark } from \"./model-mark\";\nimport { useOpenGeniText, type OpenGeniText } from \"../messages/runtime\";\n\nconst PopoverContainedPortal = containedPortal(Popover.Portal);\ntype ClientPickerModelRow = PickerModelRow<ClientModel>;\n\n/** Model selection stays flat; reasoning never becomes a navigation destination. */\nexport function ModelPolicyPickerMenu(props: ModelPolicyPickerProps) {\n const t = useOpenGeniText();\n const [query, setQuery] = useState(\"\");\n const view = modelPickerMenuView(t, props, query);\n const { messages, rows, groups } = view;\n const selected = view.selected;\n const choose = (row: ClientPickerModelRow) => {\n if (props.disabled) return;\n const choice = modelPickerChoice(props, row);\n if (!choice) return;\n if (choice.model !== null) props.onModelChange(choice.model);\n // Hosts may commit the combined model/effort draft through this callback.\n props.onEffortChange(choice.effort);\n if (choice.latencyMode !== null) props.onLatencyModeChange(choice.latencyMode);\n };\n const modelRow = (row: ClientPickerModelRow) => (\n <PickerNavRow\n key={row.id}\n icon={\n props.collapseScopes === false ? undefined : (\n <ModelMark model={row.catalog} className=\"size-4 text-og-fg-muted\" />\n )\n }\n label={row.label}\n hint={row.unavailableReason ?? row.fundingHint}\n disabled={props.disabled || !row.selectable}\n title={[row.label, row.unavailableReason ?? row.fundingHint].filter(Boolean).join(\" · \")}\n active={row.selectable && row.id === props.model}\n showChevron={false}\n trailing={\n row.catalog.cost === \"free\" || row.id === props.model ? (\n <span className=\"flex items-center gap-2\">\n {row.catalog.cost === \"free\" ? (\n <span className=\"rounded-full bg-og-surface-2 px-1.5 py-0.5 text-og-control text-og-fg-muted\">\n {messages.free}\n </span>\n ) : null}\n {row.id === props.model ? (\n <CheckIcon className={MENU_CHECK_CLASS} aria-label={messages.selected} />\n ) : null}\n </span>\n ) : null\n }\n testId={`model-picker-choice-${row.id}`}\n onClick={() => choose(row)}\n />\n );\n return (\n <div\n data-testid=\"model-picker-menu\"\n className=\"flex min-h-0 flex-col\"\n onKeyDown={(event) => {\n if (\n !(event.target instanceof HTMLButtonElement) ||\n ![\"ArrowDown\", \"ArrowUp\", \"Home\", \"End\"].includes(event.key)\n )\n return;\n const buttons = Array.from(\n event.currentTarget.querySelectorAll<HTMLButtonElement>(\n '[data-testid^=\"model-picker-choice-\"]:not(:disabled)',\n ),\n );\n const index = buttons.indexOf(event.target);\n if (index < 0) return;\n event.preventDefault();\n const next =\n event.key === \"Home\"\n ? 0\n : event.key === \"End\"\n ? buttons.length - 1\n : (index + (event.key === \"ArrowDown\" ? 1 : -1) + buttons.length) % buttons.length;\n buttons[next]?.focus();\n }}\n >\n {rows.some((row) => row.selectable) ? (\n <div className=\"border-b border-og-border py-1\">\n <label className=\"og-model-policy-search flex items-center gap-2 px-2.5 py-0.5\">\n <SearchIcon className=\"size-4 shrink-0 text-og-fg-subtle\" aria-hidden />\n <input\n aria-label={messages.searchLabel}\n placeholder={messages.searchPlaceholder}\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n onKeyDown={(event) => {\n if (event.key !== \"Escape\" && event.key !== \"Tab\") event.stopPropagation();\n if (event.key === \"ArrowDown\") {\n event.preventDefault();\n event.currentTarget\n .closest('[data-testid=\"model-picker-menu\"]')\n ?.querySelector<HTMLButtonElement>(\"button:not(:disabled)\")\n ?.focus();\n }\n }}\n className=\"og-model-policy-search-input h-8 min-w-0 flex-1 bg-transparent text-og-menu text-og-fg outline-hidden placeholder:text-og-fg-subtle\"\n />\n </label>\n </div>\n ) : null}\n {props.error ? (\n <p className={cn(MENU_NOTE_CLASS, \"text-og-sm text-og-status-failed\")} role=\"alert\">\n {props.error}\n </p>\n ) : null}\n <div\n className=\"min-h-0 flex-1 overflow-y-auto overscroll-contain py-1\"\n data-testid=\"model-picker-models\"\n >\n {props.loading ? (\n // Rows at the menu's row height, never a sentence, so nothing jumps.\n <div role=\"status\" aria-label={messages.loading}>\n {[58, 44, 66, 50].map((width) => (\n <div key={width} aria-hidden=\"true\" className=\"flex h-8 items-center gap-3 px-2.5\">\n <span className=\"size-4 shrink-0 animate-pulse rounded bg-og-surface-2\" />\n <span\n className=\"h-2.5 animate-pulse rounded bg-og-surface-2\"\n style={{ width: `${width}%` }}\n />\n </div>\n ))}\n </div>\n ) : rows.some((row) => row.selectable) ? (\n <>\n {groups.map((group) => (\n <section\n key={group.billingClass}\n aria-label={group.label}\n className=\"[&+section]:mt-1.5 [&+section]:border-t [&+section]:border-og-border [&+section]:pt-1.5\"\n >\n <div className={cn(MENU_LABEL_CLASS, \"flex items-center gap-2\")}>\n <BillingClassMark\n billingClass={group.billingClass}\n presentation={groupPresentationFor(props, group.billingClass)}\n aria-label=\"\"\n />\n <span className=\"min-w-0 break-words\">{group.label}</span>\n </div>\n {group.description ? (\n <p className=\"break-words px-2.5 pb-1 text-og-sm text-og-fg-muted\">\n {group.description}\n </p>\n ) : null}\n {group.rows.map(modelRow)}\n </section>\n ))}\n {view.matchCount === 0 ? (\n <p className={MENU_NOTE_CLASS}>\n {view.searching ? messages.noMatches : messages.noModels}\n </p>\n ) : null}\n </>\n ) : props.connectModelsHref || rows.length > 0 ? (\n <ConnectModelsPanel href={props.connectModelsHref} messages={messages} />\n ) : (\n <p className={MENU_NOTE_CLASS}>{messages.noModels}</p>\n )}\n </div>\n {view.anySelectable &&\n selected &&\n (view.unsupportedAttachments || (props.allowModelOptions !== false && view.thinking)) ? (\n <div className=\"border-t border-og-border px-2.5 py-2.5\">\n {view.unsupportedAttachments ? (\n <p className=\"pb-1.5 text-og-control leading-relaxed text-og-fg-subtle\">\n {messages.unsupportedAttachments}\n </p>\n ) : null}\n {props.allowModelOptions !== false ? <ModelThinkingControls {...props} /> : null}\n </div>\n ) : null}\n </div>\n );\n}\n\nconst CONNECT_MODEL_OPTIONS = (\n t: OpenGeniText,\n): Array<{\n billingClass: \"codex_subscription\" | \"supergrok_subscription\" | \"byok\" | \"external\";\n title: string;\n detail: string;\n}> => [\n {\n billingClass: \"codex_subscription\",\n title: t(\"modelPolicyPickerMenu.codex\"),\n detail: \"ChatGPT\",\n },\n { billingClass: \"supergrok_subscription\", title: \"SuperGrok\", detail: \"xAI\" },\n {\n billingClass: \"byok\",\n title: t(\"modelPolicyPickerMenu.aiGateway\"),\n detail: t(\"modelPolicyPickerMenu.vercel\"),\n },\n { billingClass: \"external\", title: \"OpenRouter\", detail: t(\"modelPolicyPickerMenu.apiKey\") },\n];\n\nfunction ConnectModelsPanel(props: {\n href: string | undefined;\n messages: ReturnType<typeof defaultModelPolicyPickerMessages>;\n}) {\n const t = useOpenGeniText();\n return (\n <div className=\"px-1.5 pb-1.5 pt-2\" data-testid=\"model-picker-connect\">\n <div className=\"px-1.5 pb-3\">\n <p className=\"text-og-menu font-medium tracking-tight text-og-fg\">\n {props.messages.connectTitle}\n </p>\n <p className=\"mt-1 text-og-control leading-snug text-og-fg-subtle\">\n {props.messages.connectBody}\n </p>\n </div>\n <div className=\"grid grid-cols-2 gap-1\">\n {CONNECT_MODEL_OPTIONS(t).map((option) => {\n const content = (\n <>\n <span className=\"flex size-8 shrink-0 items-center justify-center rounded-og-md bg-og-surface-2 text-og-fg\">\n <BillingClassMark\n billingClass={option.billingClass}\n aria-label=\"\"\n className=\"size-4 text-og-fg\"\n />\n </span>\n <span className=\"min-w-0\">\n <span className=\"block truncate text-og-control font-medium text-og-fg\">\n {option.title}\n </span>\n <span className=\"block truncate text-og-control text-og-fg-subtle\">\n {option.detail}\n </span>\n </span>\n </>\n );\n const className =\n \"flex min-w-0 items-center gap-2 rounded-og-md px-1.5 py-1.5 outline-hidden transition-colors hover:bg-og-hover focus-visible:ring-2 focus-visible:ring-og-accent/40\";\n return props.href ? (\n <a key={option.title} href={props.href} className={className}>\n {content}\n </a>\n ) : (\n <div key={option.title} className={className}>\n {content}\n </div>\n );\n })}\n </div>\n {props.href ? (\n <a\n href={props.href}\n className=\"mt-2 flex h-9 w-full items-center justify-center gap-1.5 rounded-og-md border border-og-primary-border bg-og-primary text-og-primary-fg hover:bg-og-primary-hover text-og-control font-medium outline-hidden transition-colors focus-visible:ring-2 focus-visible:ring-og-accent/40\"\n >\n {props.messages.connectAction}\n <ArrowRightIcon className=\"size-3.5\" aria-hidden />\n </a>\n ) : (\n <p className=\"px-1.5 pt-3 text-og-control text-og-fg-subtle\">{props.messages.noModels}</p>\n )}\n </div>\n );\n}\n\nfunction ModelThinkingControls(props: ModelPolicyPickerProps) {\n const t = useOpenGeniText();\n const view = modelPickerMenuView(t, props, \"\");\n const thinking = view.thinking;\n if (!view.selected || !thinking) return null;\n const messages = view.messages;\n const efforts = thinking.efforts;\n const showThinking = thinking.showThinking;\n const showFast = thinking.showFast;\n const speeds = thinking.speeds;\n const selectedSpeed = speeds?.find((speed) => speed.id === props.latencyMode) ?? speeds?.[0];\n return (\n <div className=\"space-y-2 text-og-control\" data-testid=\"model-picker-reasoning\">\n {showThinking || showFast ? (\n <div className=\"flex min-h-7 items-center justify-between gap-3\">\n {showThinking ? <span className=\"text-og-fg-subtle\">{messages.thinking}</span> : <span />}\n {showFast ? (\n <button\n type=\"button\"\n data-testid=\"model-picker-fast\"\n disabled={props.disabled || thinking.disabled}\n aria-pressed={props.latencyMode === \"fast\"}\n title={messages.fast + \" · \" + messages.fastRateHint}\n onClick={() =>\n props.onLatencyModeChange(props.latencyMode === \"fast\" ? \"standard\" : \"fast\")\n }\n className=\"flex min-h-8 shrink-0 items-center gap-1.5 whitespace-nowrap rounded-og-sm px-2 text-og-fg-muted hover:bg-og-hover focus-visible:ring-2 focus-visible:ring-og-accent/40 disabled:opacity-50\"\n >\n <ZapIcon className={cn(\"size-3.5\", props.latencyMode === \"fast\" && \"fill-current\")} />\n {messages.fast}\n <span className=\"text-og-fg-subtle\">{messages.fastRateHint}</span>\n </button>\n ) : null}\n </div>\n ) : null}\n {showThinking ? (\n <RadioGroup.Root\n aria-label={messages.thinkingEffort}\n value={thinking.value}\n disabled={props.disabled || thinking.disabled}\n onValueChange={(value) => props.onEffortChange(value as ReasoningEffort)}\n orientation=\"horizontal\"\n className=\"flex flex-wrap gap-0.5 rounded-og-md bg-og-surface-2 p-0.5\"\n >\n {efforts.map((effort) => (\n <RadioGroup.Item\n key={effort}\n value={effort}\n aria-label={labelReasoningEffort(t, effort)}\n title={labelReasoningEffort(t, effort)}\n className=\"min-h-8 min-w-10 flex-1 cursor-pointer whitespace-nowrap rounded-og-sm px-1.5 text-og-control text-og-fg-muted outline-hidden transition-colors hover:text-og-fg focus-visible:ring-2 focus-visible:ring-og-accent/40 data-[state=checked]:bg-og-surface-1 data-[state=checked]:text-og-fg data-[state=checked]:shadow-sm disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {compactEffortLabel(t, effort, labelReasoningEffort(t, effort))}\n </RadioGroup.Item>\n ))}\n </RadioGroup.Root>\n ) : null}\n {speeds && selectedSpeed ? (\n <div className=\"space-y-2 pt-1\" data-testid=\"model-picker-speed\">\n <div className=\"flex min-h-7 items-center justify-between gap-3\">\n <span className=\"text-og-fg-subtle\">{messages.speed}</span>\n {selectedSpeed.hint ? (\n <span className=\"text-og-fg-subtle\">{selectedSpeed.hint}</span>\n ) : null}\n </div>\n <RadioGroup.Root\n aria-label={messages.speed}\n value={selectedSpeed.id}\n disabled={props.disabled || thinking.disabled}\n onValueChange={(value) => props.onLatencyModeChange(value as LatencyMode)}\n orientation=\"horizontal\"\n className=\"flex flex-wrap gap-0.5 rounded-og-md bg-og-surface-2 p-0.5\"\n >\n {speeds.map((speed) => (\n <RadioGroup.Item\n key={speed.id}\n value={speed.id}\n aria-label={speed.hint ? `${speed.label} · ${speed.hint}` : speed.label}\n title={speed.hint ? `${speed.label} · ${speed.hint}` : speed.label}\n className=\"flex min-h-8 min-w-10 flex-1 cursor-pointer items-center justify-center gap-1 whitespace-nowrap rounded-og-sm px-1.5 text-og-control text-og-fg-muted outline-hidden transition-colors hover:text-og-fg focus-visible:ring-2 focus-visible:ring-og-accent/40 data-[state=checked]:bg-og-surface-1 data-[state=checked]:text-og-fg data-[state=checked]:shadow-sm disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {speed.id === \"standard\" ? null : (\n <ZapIcon\n aria-hidden\n className={cn(\n \"size-3.5 shrink-0\",\n speed.id === selectedSpeed.id && \"fill-current\",\n )}\n />\n )}\n {speed.label}\n </RadioGroup.Item>\n ))}\n </RadioGroup.Root>\n </div>\n ) : null}\n </div>\n );\n}\n\nexport function ModelPolicyPickerPopover(\n props: ModelPolicyPickerProps & {\n anchor: RefObject<HTMLButtonElement | null>;\n contentId: string;\n portalStyle: CSSProperties;\n },\n) {\n const t = useOpenGeniText();\n const outside = useRef(false);\n const messages = { ...defaultModelPolicyPickerMessages(t), ...props.messages };\n return (\n <Popover.Root open onOpenChange={(open) => props.onOpenChange?.(open)}>\n <Popover.Anchor virtualRef={props.anchor} />\n <PopoverContainedPortal>\n <Popover.Content\n id={props.contentId}\n aria-label={messages.label}\n align=\"start\"\n side={props.menuSide ?? \"bottom\"}\n sideOffset={8}\n collisionPadding={12}\n onInteractOutside={(event) => {\n if (props.anchor.current?.contains(event.target as Node)) event.preventDefault();\n else outside.current = true;\n }}\n onCloseAutoFocus={(event) => {\n event.preventDefault();\n if (!outside.current) props.anchor.current?.focus();\n }}\n className={cn(\n MENU_SURFACE_CLASS,\n \"og-root og-model-policy-menu z-50 flex max-h-[min(32rem,var(--radix-popover-content-available-height))] w-[22rem] max-w-[calc(100vw-16px)] flex-col overflow-hidden p-[var(--og-model-picker-menu-padding)]\",\n props.contentClassName,\n )}\n style={{ ...props.portalStyle, ...props.contentStyle }}\n data-testid=\"model-picker-content\"\n >\n <ModelPolicyPickerMenu {...props} />\n </Popover.Content>\n </PopoverContainedPortal>\n </Popover.Root>\n );\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/app/components/session/subscription-account-menu.tsx"],"sourcesContent":["// Shared presentation extracted from the Codex subscription-account dropdown.\n// Adapters own loading, authorization, usage freshness, and selection semantics.\nimport { ChevronDownIcon, Loader2Icon } from \"lucide-react\";\nimport type { ReactNode } from \"react\";\n\nimport {\n DropdownMenu,\n DropdownMenuCheck,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuMeta,\n DropdownMenuNote,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"../../../ui/dropdown-menu\";\nimport { cn } from \"../../lib/utils\";\n\nexport type SubscriptionAccountMenuRow = {\n id: string;\n label: string;\n plan?: string | null | undefined;\n status?: string | null;\n detail?: string;\n personal?: boolean;\n disabled?: boolean;\n /** Only supplied when the adapter has a trustworthy quota reading. */\n remaining?: number | null;\n /** Cached window readings, not an aggregate capacity/eligibility estimate. */\n usageSummary?: string | undefined;\n};\n\nexport type SubscriptionAccountUsageWindow = {\n label: string;\n remaining?: number;\n usedPercent?: number | null;\n detail?: string;\n};\n\nfunction UsageRow({ label, remaining, usedPercent, detail }: SubscriptionAccountUsageWindow) {\n const value = remaining ?? usedPercent;\n const known = typeof value === \"number\" && Number.isFinite(value);\n const pct = known ? Math.min(100, Math.max(0, value)) : 0;\n const measure = remaining !== undefined ? \"remaining\" : \"used\";\n const text = known ? `${Math.round(value)}% ${measure}` : \"Unknown\";\n return (\n <div className=\"space-y-0.5 text-2xs text-fg-subtle\">\n <div className=\"flex items-center gap-2\">\n <span className=\"max-w-28 min-w-10 shrink-0 truncate\" title={label}>\n {label}\n </span>\n {known ? (\n <span\n className=\"h-1 min-w-0 flex-1 overflow-hidden rounded-full bg-surface-2\"\n role=\"progressbar\"\n aria-label={`${label} ${measure}`}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={pct}\n aria-valuetext={text}\n >\n <span\n className={cn(\n \"block h-full rounded-full\",\n (measure === \"remaining\" ? pct <= 10 : pct >= 90)\n ? \"bg-status-waiting\"\n : \"bg-brand\",\n )}\n style={{ width: `${pct}%` }}\n />\n </span>\n ) : (\n <span className=\"flex-1\" />\n )}\n <span className=\"shrink-0 whitespace-nowrap text-right tabular-nums\">{text}</span>\n </div>\n {detail ? <p>{detail}</p> : null}\n </div>\n );\n}\n\nfunction MiniBar({ remaining }: { remaining: number }) {\n const pct = Math.min(100, Math.max(0, remaining));\n return (\n <span\n className=\"inline-flex shrink-0 items-center gap-1.5 text-2xs text-fg-subtle\"\n title={`${Math.round(pct)}% remaining in the tighter usage window`}\n >\n <span className=\"h-1 w-8 overflow-hidden rounded-full bg-surface-2\" aria-hidden=\"true\">\n <span\n className={cn(\"block h-full rounded-full\", pct <= 10 ? \"bg-status-waiting\" : \"bg-brand\")}\n style={{ width: `${pct}%` }}\n />\n </span>\n <span className=\"whitespace-nowrap tabular-nums\">{Math.round(pct)}% remaining</span>\n </span>\n );\n}\n\nexport function SubscriptionAccountMenu({\n ariaLabel,\n triggerMark,\n headerMark,\n selectionLabel,\n displayName,\n metadata,\n identity,\n tone = \"ok\",\n usage,\n accounts,\n selectedId,\n automaticSelected,\n choosing,\n choosingTarget,\n actionLabel = \"Use for next turn\",\n automaticLabel = \"Automatic\",\n emptyMessage,\n error,\n note,\n onOpenChange,\n onChoose,\n}: {\n ariaLabel: string;\n triggerMark: ReactNode;\n headerMark: ReactNode;\n selectionLabel: string;\n displayName: string;\n metadata: string;\n identity?: string | null | undefined;\n tone?: \"ok\" | \"warn\" | \"bad\" | undefined;\n usage: {\n checking?: boolean | undefined;\n unavailable?: boolean | undefined;\n message?: string | undefined;\n note?: string | undefined;\n windows?: SubscriptionAccountUsageWindow[] | undefined;\n };\n accounts: SubscriptionAccountMenuRow[];\n selectedId: string | null;\n automaticSelected: boolean;\n choosing: boolean;\n choosingTarget: string | null | undefined;\n actionLabel?: string | undefined;\n automaticLabel?: string | undefined;\n emptyMessage?: string | undefined;\n error?: string | null | undefined;\n note: string;\n onOpenChange?: ((open: boolean) => void) | undefined;\n onChoose: (connectionId: string | null) => void;\n}) {\n const row = (account: SubscriptionAccountMenuRow) => (\n <DropdownMenuItem\n key={account.id}\n disabled={choosing || account.disabled}\n title={account.detail}\n onSelect={(event) => {\n event.preventDefault();\n onChoose(account.id);\n }}\n className=\"cursor-pointer\"\n >\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate\">{account.label}</span>\n {account.usageSummary ? (\n <span className=\"block truncate text-2xs text-fg-subtle\" title={account.usageSummary}>\n {account.usageSummary}\n </span>\n ) : null}\n </span>\n {account.plan ? <DropdownMenuMeta>{account.plan}</DropdownMenuMeta> : null}\n {account.remaining != null ? <MiniBar remaining={account.remaining} /> : null}\n {account.status ? (\n <span className=\"shrink-0 text-xs text-status-waiting\">{account.status}</span>\n ) : null}\n {choosingTarget === account.id ? (\n <Loader2Icon className=\"size-4 shrink-0 animate-spin\" />\n ) : (\n <DropdownMenuCheck checked={account.id === selectedId} className=\"ml-0\" />\n )}\n </DropdownMenuItem>\n );\n const personal = accounts.filter((account) => account.personal);\n return (\n <DropdownMenu {...(onOpenChange ? { onOpenChange } : {})}>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n aria-label={ariaLabel}\n title={ariaLabel}\n className={cn(\n \"group/account relative inline-flex h-6 shrink-0 cursor-pointer items-center gap-0.5 rounded-full border border-border/70 bg-surface-2/50 px-1.5 text-fg-muted outline-hidden transition-[background-color,border-color,color] hover:border-border hover:bg-surface-2 hover:text-fg focus-visible:ring-1 focus-visible:ring-ring/40 data-[state=open]:border-border data-[state=open]:bg-surface-2 data-[state=open]:text-fg\",\n choosing && \"opacity-60\",\n )}\n >\n {triggerMark}\n {choosing ? (\n <Loader2Icon className=\"size-2.5 animate-spin text-current\" aria-hidden />\n ) : (\n <ChevronDownIcon\n className=\"size-2.5 shrink-0 opacity-70 transition-opacity group-hover/account:opacity-100\"\n aria-hidden\n />\n )}\n {tone !== \"ok\" ? (\n <span\n className={cn(\n \"absolute -top-0.5 -right-0.5 size-1.5 rounded-full ring-1 ring-surface\",\n tone === \"bad\" ? \"bg-destructive\" : \"bg-status-waiting\",\n )}\n aria-hidden\n />\n ) : null}\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n align=\"start\"\n side=\"bottom\"\n sideOffset={8}\n collisionPadding={12}\n className=\"flex max-h-[min(32rem,var(--radix-dropdown-menu-content-available-height))] w-72 flex-col overflow-hidden\"\n >\n <div className=\"shrink-0 space-y-2 px-2.5 pt-1.5 pb-2\">\n <div className=\"flex items-start gap-2\">\n <span className=\"mt-0.5 inline-flex size-7 shrink-0 items-center justify-center overflow-hidden rounded-md bg-surface-2 text-fg\">\n {headerMark}\n </span>\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-2xs text-fg-subtle\">{selectionLabel}</p>\n <p className=\"truncate text-sm font-medium text-fg\">{displayName}</p>\n {identity ? (\n <p className=\"truncate text-2xs text-fg-subtle\" title={identity}>\n {identity}\n </p>\n ) : null}\n <p className=\"truncate text-2xs text-fg-subtle\" title={metadata}>\n {metadata}\n </p>\n </div>\n </div>\n {usage.checking ? (\n <p className=\"text-2xs text-fg-subtle\">Checking usage…</p>\n ) : usage.unavailable ? (\n <p className=\"text-2xs text-fg-subtle\">Usage unavailable</p>\n ) : usage.message ? (\n <p className=\"text-2xs text-fg-subtle\">{usage.message}</p>\n ) : (\n <div className=\"max-h-36 space-y-1.5 overflow-y-auto overscroll-contain\">\n {usage.windows?.map((window) => (\n <UsageRow key={window.label} {...window} />\n ))}\n </div>\n )}\n {usage.note ? <p className=\"text-2xs text-fg-subtle\">{usage.note}</p> : null}\n </div>\n <DropdownMenuSeparator className=\"shrink-0\" />\n <DropdownMenuLabel className=\"shrink-0\">{actionLabel}</DropdownMenuLabel>\n <div className=\"min-h-0 flex-1 overflow-y-auto overscroll-contain\">\n <DropdownMenuItem\n disabled={choosing}\n onSelect={(event) => {\n event.preventDefault();\n onChoose(null);\n }}\n className=\"cursor-pointer\"\n >\n <span className=\"min-w-0 flex-1 truncate\">{automaticLabel}</span>\n {choosingTarget === null ? (\n <Loader2Icon className=\"size-4 shrink-0 animate-spin\" />\n ) : (\n <DropdownMenuCheck checked={automaticSelected} className=\"ml-0\" />\n )}\n </DropdownMenuItem>\n {accounts.filter((account) => !account.personal).map(row)}\n {personal.length > 0 ? (\n <>\n <DropdownMenuLabel className=\"pt-2\">Your accounts</DropdownMenuLabel>\n {personal.map(row)}\n </>\n ) : null}\n {accounts.length === 0 && emptyMessage ? (\n <DropdownMenuNote>{emptyMessage}</DropdownMenuNote>\n ) : null}\n {error ? (\n <DropdownMenuNote role=\"alert\" className=\"text-xs text-danger\">\n {error}\n </DropdownMenuNote>\n ) : (\n <p className=\"px-2.5 pt-1.5 pb-1 text-xs text-fg-muted\">{note}</p>\n )}\n </div>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAEA,SAAS,iBAAiB,mBAAmB;AA6CvC,SAmOM,UAlOJ,KADF;AARN,SAAS,SAAS,EAAE,OAAO,WAAW,aAAa,OAAO,GAAmC;AAC3F,QAAM,QAAQ,aAAa;AAC3B,QAAM,QAAQ,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK;AAChE,QAAM,MAAM,QAAQ,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,KAAK,CAAC,IAAI;AACxD,QAAM,UAAU,cAAc,SAAY,cAAc;AACxD,QAAM,OAAO,QAAQ,GAAG,KAAK,MAAM,KAAK,CAAC,KAAK,OAAO,KAAK;AAC1D,SACE,qBAAC,SAAI,WAAU,uCACb;AAAA,yBAAC,SAAI,WAAU,2BACb;AAAA,0BAAC,UAAK,WAAU,uCAAsC,OAAO,OAC1D,iBACH;AAAA,MACC,QACC;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,MAAK;AAAA,UACL,cAAY,GAAG,KAAK,IAAI,OAAO;AAAA,UAC/B,iBAAe;AAAA,UACf,iBAAe;AAAA,UACf,iBAAe;AAAA,UACf,kBAAgB;AAAA,UAEhB;AAAA,YAAC;AAAA;AAAA,cACC,WAAW;AAAA,gBACT;AAAA,iBACC,YAAY,cAAc,OAAO,KAAK,OAAO,MAC1C,sBACA;AAAA,cACN;AAAA,cACA,OAAO,EAAE,OAAO,GAAG,GAAG,IAAI;AAAA;AAAA,UAC5B;AAAA;AAAA,MACF,IAEA,oBAAC,UAAK,WAAU,UAAS;AAAA,MAE3B,oBAAC,UAAK,WAAU,sDAAsD,gBAAK;AAAA,OAC7E;AAAA,IACC,SAAS,oBAAC,OAAG,kBAAO,IAAO;AAAA,KAC9B;AAEJ;AAEA,SAAS,QAAQ,EAAE,UAAU,GAA0B;AACrD,QAAM,MAAM,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,SAAS,CAAC;AAChD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,GAAG,KAAK,MAAM,GAAG,CAAC;AAAA,MAEzB;AAAA,4BAAC,UAAK,WAAU,qDAAoD,eAAY,QAC9E;AAAA,UAAC;AAAA;AAAA,YACC,WAAW,GAAG,6BAA6B,OAAO,KAAK,sBAAsB,UAAU;AAAA,YACvF,OAAO,EAAE,OAAO,GAAG,GAAG,IAAI;AAAA;AAAA,QAC5B,GACF;AAAA,QACA,qBAAC,UAAK,WAAU,kCAAkC;AAAA,eAAK,MAAM,GAAG;AAAA,UAAE;AAAA,WAAW;AAAA;AAAA;AAAA,EAC/E;AAEJ;AAEO,SAAS,wBAAwB;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GA4BG;AACD,QAAM,MAAM,CAAC,YACX;AAAA,IAAC;AAAA;AAAA,MAEC,UAAU,YAAY,QAAQ;AAAA,MAC9B,OAAO,QAAQ;AAAA,MACf,UAAU,CAAC,UAAU;AACnB,cAAM,eAAe;AACrB,iBAAS,QAAQ,EAAE;AAAA,MACrB;AAAA,MACA,WAAU;AAAA,MAEV;AAAA,6BAAC,UAAK,WAAU,kBACd;AAAA,8BAAC,UAAK,WAAU,kBAAkB,kBAAQ,OAAM;AAAA,UAC/C,QAAQ,eACP,oBAAC,UAAK,WAAU,0CAAyC,OAAO,QAAQ,cACrE,kBAAQ,cACX,IACE;AAAA,WACN;AAAA,QACC,QAAQ,OAAO,oBAAC,oBAAkB,kBAAQ,MAAK,IAAsB;AAAA,QACrE,QAAQ,aAAa,OAAO,oBAAC,WAAQ,WAAW,QAAQ,WAAW,IAAK;AAAA,QACxE,QAAQ,SACP,oBAAC,UAAK,WAAU,wCAAwC,kBAAQ,QAAO,IACrE;AAAA,QACH,mBAAmB,QAAQ,KAC1B,oBAAC,eAAY,WAAU,gCAA+B,IAEtD,oBAAC,qBAAkB,SAAS,QAAQ,OAAO,YAAY,WAAU,QAAO;AAAA;AAAA;AAAA,IAzBrE,QAAQ;AAAA,EA2Bf;AAEF,QAAM,WAAW,SAAS,OAAO,CAAC,YAAY,QAAQ,QAAQ;AAC9D,SACE,qBAAC,gBAAc,GAAI,eAAe,EAAE,aAAa,IAAI,CAAC,GACpD;AAAA,wBAAC,uBAAoB,SAAO,MAC1B;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,cAAY;AAAA,QACZ,OAAO;AAAA,QACP,WAAW;AAAA,UACT;AAAA,UACA,YAAY;AAAA,QACd;AAAA,QAEC;AAAA;AAAA,UACA,WACC,oBAAC,eAAY,WAAU,sCAAqC,eAAW,MAAC,IAExE;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,eAAW;AAAA;AAAA,UACb;AAAA,UAED,SAAS,OACR;AAAA,YAAC;AAAA;AAAA,cACC,WAAW;AAAA,gBACT;AAAA,gBACA,SAAS,QAAQ,mBAAmB;AAAA,cACtC;AAAA,cACA,eAAW;AAAA;AAAA,UACb,IACE;AAAA;AAAA;AAAA,IACN,GACF;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,OAAM;AAAA,QACN,MAAK;AAAA,QACL,YAAY;AAAA,QACZ,kBAAkB;AAAA,QAClB,WAAU;AAAA,QAEV;AAAA,+BAAC,SAAI,WAAU,yCACb;AAAA,iCAAC,SAAI,WAAU,0BACb;AAAA,kCAAC,UAAK,WAAU,kHACb,sBACH;AAAA,cACA,qBAAC,SAAI,WAAU,kBACb;AAAA,oCAAC,OAAE,WAAU,2BAA2B,0BAAe;AAAA,gBACvD,oBAAC,OAAE,WAAU,wCAAwC,uBAAY;AAAA,gBAChE,WACC,oBAAC,OAAE,WAAU,oCAAmC,OAAO,UACpD,oBACH,IACE;AAAA,gBACJ,oBAAC,OAAE,WAAU,oCAAmC,OAAO,UACpD,oBACH;AAAA,iBACF;AAAA,eACF;AAAA,YACC,MAAM,WACL,oBAAC,OAAE,WAAU,2BAA0B,kCAAe,IACpD,MAAM,cACR,oBAAC,OAAE,WAAU,2BAA0B,+BAAiB,IACtD,MAAM,UACR,oBAAC,OAAE,WAAU,2BAA2B,gBAAM,SAAQ,IAEtD,oBAAC,SAAI,WAAU,2DACZ,gBAAM,SAAS,IAAI,CAAC,WACnB,oBAAC,YAA6B,GAAG,UAAlB,OAAO,KAAmB,CAC1C,GACH;AAAA,YAED,MAAM,OAAO,oBAAC,OAAE,WAAU,2BAA2B,gBAAM,MAAK,IAAO;AAAA,aAC1E;AAAA,UACA,oBAAC,yBAAsB,WAAU,YAAW;AAAA,UAC5C,oBAAC,qBAAkB,WAAU,YAAY,uBAAY;AAAA,UACrD,qBAAC,SAAI,WAAU,qDACb;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,UAAU;AAAA,gBACV,UAAU,CAAC,UAAU;AACnB,wBAAM,eAAe;AACrB,2BAAS,IAAI;AAAA,gBACf;AAAA,gBACA,WAAU;AAAA,gBAEV;AAAA,sCAAC,UAAK,WAAU,2BAA2B,0BAAe;AAAA,kBACzD,mBAAmB,OAClB,oBAAC,eAAY,WAAU,gCAA+B,IAEtD,oBAAC,qBAAkB,SAAS,mBAAmB,WAAU,QAAO;AAAA;AAAA;AAAA,YAEpE;AAAA,YACC,SAAS,OAAO,CAAC,YAAY,CAAC,QAAQ,QAAQ,EAAE,IAAI,GAAG;AAAA,YACvD,SAAS,SAAS,IACjB,iCACE;AAAA,kCAAC,qBAAkB,WAAU,QAAO,2BAAa;AAAA,cAChD,SAAS,IAAI,GAAG;AAAA,eACnB,IACE;AAAA,YACH,SAAS,WAAW,KAAK,eACxB,oBAAC,oBAAkB,wBAAa,IAC9B;AAAA,YACH,QACC,oBAAC,oBAAiB,MAAK,SAAQ,WAAU,uBACtC,iBACH,IAEA,oBAAC,OAAE,WAAU,4CAA4C,gBAAK;AAAA,aAElE;AAAA;AAAA;AAAA,IACF;AAAA,KACF;AAEJ;","names":[]}