@opengeni/react 4.5.1-canary.39832248373001 → 4.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (409) hide show
  1. package/dist/app/app-state.js +7 -7
  2. package/dist/app/components/Composer.js +14 -14
  3. package/dist/app/components/artifacts/artifact-library.js +1 -1
  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-data.js +4 -2
  9. package/dist/app/components/artifacts/site-publishing.js +9 -9
  10. package/dist/app/components/artifacts/site-settings.js +11 -11
  11. package/dist/app/components/billing-class-mark.js +3 -3
  12. package/dist/app/components/capabilities/capability-detail-sheet.js +3 -3
  13. package/dist/app/components/capabilities/capability-logo-source.js +7 -7
  14. package/dist/app/components/capabilities/native-connect-setup.js +7 -7
  15. package/dist/app/components/capabilities/prepared-mcp-setup-card.js +8 -8
  16. package/dist/app/components/capabilities/session-capability-card.js +33 -33
  17. package/dist/app/components/capabilities/session-chrome-card.js +13 -13
  18. package/dist/app/components/capabilities/session-custom-mcp-card.js +9 -9
  19. package/dist/app/components/capabilities/session-github-card.js +8 -8
  20. package/dist/app/components/capabilities/session-machine-card.js +12 -12
  21. package/dist/app/components/command-menu/chat-status.js +7 -6
  22. package/dist/app/components/command-menu/chat-switcher.js +7 -6
  23. package/dist/app/components/command-menu/chat-switcher.js.map +1 -1
  24. package/dist/app/components/command-menu/command-menu.js +13 -12
  25. package/dist/app/components/command-menu/command-menu.js.map +1 -1
  26. package/dist/app/components/command-menu/shortcut-sheet.js +8 -8
  27. package/dist/app/components/composer-mobile-plus-panel.js +5 -5
  28. package/dist/app/components/composer-mobile-plus.js +1 -1
  29. package/dist/app/components/credit-required-gate.js +1 -1
  30. package/dist/app/components/credit-required-prompt.js +6 -4
  31. package/dist/app/components/credit-required-prompt.js.map +1 -1
  32. package/dist/app/components/credits/credit-refusal-notice.js +5 -3
  33. package/dist/app/components/desktop/app-shots.js +5 -5
  34. package/dist/app/components/desktop/this-computer.js +4 -4
  35. package/dist/app/components/feedback.js +3 -3
  36. package/dist/app/components/follow-up-repository-menu-body.js +4 -2
  37. package/dist/app/components/follow-up-repository-menu-body.js.map +1 -1
  38. package/dist/app/components/follow-up-repository-picker.js +4 -2
  39. package/dist/app/components/github-app-connect-launcher.js +1 -1
  40. package/dist/app/components/machines/connect-machine-dialog.js +3 -3
  41. package/dist/app/components/markdown.js +4 -4
  42. package/dist/app/components/models/models-ui.js +1 -1
  43. package/dist/app/components/pickers.js +5 -5
  44. package/dist/app/components/rail/rail-context.js +2 -2
  45. package/dist/app/components/rail/rail-sections.js +19 -18
  46. package/dist/app/components/rail/session-header.js +13 -13
  47. package/dist/app/components/rail/session-list.js +20 -19
  48. package/dist/app/components/rail/session-row-content.js +4 -2
  49. package/dist/app/components/rail/session-row-hover-details.js +7 -6
  50. package/dist/app/components/rail/session-shell.js +35 -34
  51. package/dist/app/components/rail/site-session-group-heading.js +4 -3
  52. package/dist/app/components/repository-picker.js +4 -2
  53. package/dist/app/components/session/agent-configuration-panel.js +5 -5
  54. package/dist/app/components/session/banners.js +9 -7
  55. package/dist/app/components/session/codex-account-indicator.js +5 -5
  56. package/dist/app/components/session/editable-artifacts-workspace.js +11 -11
  57. package/dist/app/components/session/failed-session-banner.js +4 -4
  58. package/dist/app/components/session/human-input.js +24 -24
  59. package/dist/app/components/session/inspector.js +32 -31
  60. package/dist/app/components/session/inspector.js.map +1 -1
  61. package/dist/app/components/session/message-actions.js +3 -3
  62. package/dist/app/components/session/message-resource-attachments.js +5 -5
  63. package/dist/app/components/session/model-account-indicator.js +5 -5
  64. package/dist/app/components/session/model-recovery-notice.js +3 -3
  65. package/dist/app/components/session/new-session-settings-menu.js +4 -4
  66. package/dist/app/components/session/sandbox-switcher.js +8 -8
  67. package/dist/app/components/session/sandbox-workspace.js +33 -33
  68. package/dist/app/components/session/search-markdown-highlight.js +5 -5
  69. package/dist/app/components/session/search-results-view.js +6 -6
  70. package/dist/app/components/session/session-admission-notice.js +4 -4
  71. package/dist/app/components/session/session-machine-access-notice.js +4 -4
  72. package/dist/app/components/session/session-search-dialog.js +6 -6
  73. package/dist/app/components/session/session-usage-limit-section.js +3 -3
  74. package/dist/app/components/session/subagents.js +4 -4
  75. package/dist/app/components/usage/usage-entry.js +3 -3
  76. package/dist/app/components/workspace-composer-plus.js +10 -10
  77. package/dist/app/embed/session-app.js +109 -109
  78. package/dist/app/lib/actions/actions-provider.js +5 -5
  79. package/dist/app/lib/codex-usage-query.js +2 -2
  80. package/dist/app/lib/composer-connectors.js +8 -8
  81. package/dist/app/lib/console-text.js +2 -2
  82. package/dist/app/lib/credit-coverage.js +4 -2
  83. package/dist/app/lib/events.js +7 -7
  84. package/dist/app/lib/failed-session-copy.js +3 -3
  85. package/dist/app/lib/format.d.ts +2 -7
  86. package/dist/app/lib/format.js +5 -2
  87. package/dist/app/lib/model-access-onboarding.js +3 -3
  88. package/dist/app/lib/move-chat-to-machine.js +3 -3
  89. package/dist/app/lib/session-branch-cache.js +6 -5
  90. package/dist/app/lib/session-group-pagination.js +6 -5
  91. package/dist/app/lib/session-hover-facts.js +6 -5
  92. package/dist/app/lib/sessions-group.js +5 -4
  93. package/dist/app/lib/turn-failure-analytics.js +4 -4
  94. package/dist/app/lib/use-workspace-machines.js +4 -4
  95. package/dist/app/lib/use-workspace-model-catalog.js +3 -3
  96. package/dist/app/lib/use-workspace-rigs.js +2 -2
  97. package/dist/app/lib/workspace-navigation-preference.js +4 -4
  98. package/dist/app/lib/workspace-scope-context.js +3 -3
  99. package/dist/app/routes/artifacts.js +25 -24
  100. package/dist/app/routes/artifacts.js.map +1 -1
  101. package/dist/app/routes/retained-artifact.js +16 -16
  102. package/dist/app/routes/session.js +73 -73
  103. package/dist/app/routes/sessions-index.js +51 -50
  104. package/dist/app/routes/site-view.js +30 -29
  105. package/dist/app/routes/site-view.js.map +1 -1
  106. package/dist/artifacts-document.js +4 -4
  107. package/dist/artifacts-presentation.js +4 -4
  108. package/dist/artifacts-spreadsheet.js +4 -4
  109. package/dist/artifacts.js +10 -10
  110. package/dist/{browser-viewer-VPK3CV2H.js → browser-viewer-YQC6BFMS.js} +4 -4
  111. package/dist/{chat-interactive-block-AMDSW656.js → chat-interactive-block-Z22YHDRU.js} +5 -5
  112. package/dist/{chunk-TDIOBPLA.js → chunk-24POWVUY.js} +4 -4
  113. package/dist/{chunk-SJORXXLV.js → chunk-26P7B46A.js} +3 -3
  114. package/dist/{chunk-6O4VWKSO.js → chunk-27EORKJ4.js} +2 -2
  115. package/dist/{chunk-WWOHORRO.js → chunk-2K27S6LK.js} +3 -3
  116. package/dist/{chunk-OFB6TUDC.js → chunk-2LUO22FR.js} +4 -4
  117. package/dist/{chunk-FSP334UU.js → chunk-2SZ3KC5S.js} +2 -2
  118. package/dist/{chunk-GZGQHQI7.js → chunk-32HA7DXJ.js} +14 -14
  119. package/dist/{chunk-PCJLH45G.js → chunk-3MQM4ZOC.js} +3 -3
  120. package/dist/{chunk-SD4PPZFB.js → chunk-3ZZOE4SN.js} +4 -4
  121. package/dist/{chunk-YGSJWWT3.js → chunk-467VRP4E.js} +3 -3
  122. package/dist/{chunk-D3RK3NGM.js → chunk-4BF3DD6R.js} +2 -2
  123. package/dist/{chunk-CDUDKETD.js → chunk-4ICPJZAB.js} +2 -2
  124. package/dist/{chunk-I66ZB6KD.js → chunk-4PC7LIQK.js} +3 -3
  125. package/dist/{chunk-D5OWJZQR.js → chunk-4RY64KQY.js} +2 -2
  126. package/dist/{chunk-PUTS4DYW.js → chunk-4VJOZJDV.js} +2 -2
  127. package/dist/{chunk-AOUCHCSB.js → chunk-4XKT4ENZ.js} +4 -4
  128. package/dist/{chunk-F3FN6DO6.js → chunk-4XO346BW.js} +2 -2
  129. package/dist/{chunk-YO64YVYL.js → chunk-65K5LV4L.js} +30 -30
  130. package/dist/{chunk-KFWVBTUH.js → chunk-6JF7C3U3.js} +2 -2
  131. package/dist/{chunk-LQ47YL6E.js → chunk-6K3WNTRI.js} +2 -2
  132. package/dist/{chunk-CCR33J7L.js → chunk-6N7W3TOV.js} +2 -2
  133. package/dist/chunk-6NXQCOLD.js +71 -0
  134. package/dist/chunk-6NXQCOLD.js.map +1 -0
  135. package/dist/{chunk-ILDOW2IQ.js → chunk-6PQBKMUL.js} +3 -3
  136. package/dist/{chunk-VO6RVVP7.js → chunk-6VITVQ23.js} +4 -4
  137. package/dist/{chunk-AIEXYO2X.js → chunk-6YDXUE5H.js} +2 -2
  138. package/dist/{chunk-HPB4KSV3.js → chunk-72XEFLMD.js} +2 -2
  139. package/dist/{chunk-7R2JQHBX.js → chunk-74NIHMAT.js} +3 -3
  140. package/dist/{chunk-5MJHH72T.js → chunk-7EGWIME2.js} +4 -4
  141. package/dist/{chunk-WVX5AQXS.js → chunk-7H2D4VNU.js} +2 -2
  142. package/dist/{chunk-IUK5QGP5.js → chunk-7JZSFJHB.js} +2 -2
  143. package/dist/{chunk-AJPW3SV4.js → chunk-7OIBLMDP.js} +2 -2
  144. package/dist/{chunk-5YFY4SFC.js → chunk-AJ7PY4FJ.js} +2 -2
  145. package/dist/{chunk-3ABPIUCK.js → chunk-B254JG72.js} +2 -2
  146. package/dist/{chunk-F33EDYS7.js → chunk-BCFHMBMK.js} +7 -7
  147. package/dist/{chunk-TJQDL3JH.js → chunk-BPD4IJBG.js} +2 -2
  148. package/dist/{chunk-FB3B45FP.js → chunk-BQWUXC55.js} +9 -9
  149. package/dist/{chunk-DGLRZMXL.js → chunk-BWKZEW6K.js} +3 -3
  150. package/dist/{chunk-MOKYT3X3.js → chunk-C6JL6PBL.js} +3 -3
  151. package/dist/{chunk-JWN7SLTO.js → chunk-CA64OZLZ.js} +6 -6
  152. package/dist/{chunk-GFSOXB2K.js → chunk-CEQUNJJY.js} +2 -2
  153. package/dist/{chunk-DFXZYNTX.js → chunk-CKA4SJRK.js} +2 -2
  154. package/dist/{chunk-D64Z4V26.js → chunk-CPKD2YGK.js} +5 -5
  155. package/dist/{chunk-PKEKZ2VA.js → chunk-CYO5HL4C.js} +9 -25
  156. package/dist/chunk-CYO5HL4C.js.map +1 -0
  157. package/dist/{chunk-A2E3ZF6N.js → chunk-D4QOZXPM.js} +2 -2
  158. package/dist/{chunk-A6CK4ENG.js → chunk-DAQG3C4W.js} +6 -6
  159. package/dist/{chunk-7PUFAH4I.js → chunk-DNLXQUBX.js} +12 -12
  160. package/dist/{chunk-ZX5H7LWD.js → chunk-DNWBLT4U.js} +2 -2
  161. package/dist/{chunk-4U4GXWXS.js → chunk-DNYD7AUG.js} +3 -3
  162. package/dist/{chunk-EMCB6XKU.js → chunk-DZH2HTTB.js} +1 -1
  163. package/dist/{chunk-Z6E6TUAE.js → chunk-EURDMOXZ.js} +2 -2
  164. package/dist/{chunk-UUSAOIJR.js → chunk-F4B2YYCN.js} +3 -3
  165. package/dist/{chunk-ENS6E4RZ.js → chunk-FH75NNLB.js} +2 -2
  166. package/dist/{chunk-H4IE2PYF.js → chunk-FMATVQFW.js} +6 -6
  167. package/dist/{chunk-ECHYJP63.js → chunk-FVCLVASD.js} +21 -21
  168. package/dist/{chunk-PMD7V4N7.js → chunk-G3FU2IF7.js} +3 -3
  169. package/dist/{chunk-HUXDGWAN.js → chunk-GMVKCEBG.js} +2 -2
  170. package/dist/{chunk-SWCLN6JE.js → chunk-GRNE5ANU.js} +2 -2
  171. package/dist/{chunk-IPPVX5GF.js → chunk-GTR2WUBA.js} +1 -1
  172. package/dist/{chunk-BT2MVGHT.js → chunk-GTR5NLVP.js} +2 -2
  173. package/dist/{chunk-HNNM2GDN.js → chunk-GUIZDI5T.js} +2 -2
  174. package/dist/{chunk-ND2WCWXI.js → chunk-GXK4CUAB.js} +2 -2
  175. package/dist/{chunk-MJQBC7C5.js → chunk-HCCSAECI.js} +2 -2
  176. package/dist/{chunk-QLIDZGPV.js → chunk-HJTTDLF6.js} +4 -4
  177. package/dist/{chunk-WUHB422G.js → chunk-HTKVYEVB.js} +2 -2
  178. package/dist/{chunk-DKCX643S.js → chunk-HXZIX7MR.js} +8 -8
  179. package/dist/{chunk-DJFTH2DI.js → chunk-I57HZMMA.js} +2 -2
  180. package/dist/{chunk-VPNXQUUS.js → chunk-I74J2UZ2.js} +8 -8
  181. package/dist/{chunk-5TLEWXAB.js → chunk-IKQMSROV.js} +1 -13
  182. package/dist/chunk-IKQMSROV.js.map +1 -0
  183. package/dist/{chunk-A6T4FGE7.js → chunk-IWIMIRV3.js} +4 -4
  184. package/dist/{chunk-FVL4B552.js → chunk-JI6WPLZB.js} +4 -4
  185. package/dist/{chunk-RAMZTZOB.js → chunk-JJ7VMIEQ.js} +43 -43
  186. package/dist/{chunk-GDLDBR6B.js → chunk-JQKURO3S.js} +2 -2
  187. package/dist/{chunk-O2SBHS2N.js → chunk-K4FDZVMQ.js} +2 -2
  188. package/dist/{chunk-TLL22FFO.js → chunk-KUO5WFXG.js} +2 -2
  189. package/dist/{chunk-KUNFUSZ7.js → chunk-KVMFT6FN.js} +2 -2
  190. package/dist/{chunk-5M23GZA2.js → chunk-KW53DBY7.js} +2 -2
  191. package/dist/{chunk-5HIOVXOX.js → chunk-LG67ZNRU.js} +2 -2
  192. package/dist/{chunk-VW3BBTMA.js → chunk-LJZNHDKI.js} +2 -2
  193. package/dist/{chunk-CB574ERL.js → chunk-LR7U3HCD.js} +4 -4
  194. package/dist/{chunk-2FPS5H2D.js → chunk-M5E3CKSE.js} +2 -2
  195. package/dist/{chunk-3PEXVG4D.js → chunk-M7A226EQ.js} +2 -2
  196. package/dist/{chunk-IIO2MR3B.js → chunk-M7YEZR6X.js} +2 -2
  197. package/dist/{chunk-XU4I47IP.js → chunk-MB2DTUEG.js} +4 -4
  198. package/dist/{chunk-UGEWCWVV.js → chunk-MDRLP5DO.js} +3 -3
  199. package/dist/{chunk-SQDPHCK2.js → chunk-MHIYYHCL.js} +9 -9
  200. package/dist/{chunk-R7XCJWCD.js → chunk-MY6VZVCP.js} +3 -3
  201. package/dist/{chunk-BLPXOHG6.js → chunk-NF6Q4XTN.js} +3 -3
  202. package/dist/{chunk-EH7TTYE6.js → chunk-NPDL4W4Y.js} +52 -52
  203. package/dist/{chunk-NQQKOJDI.js → chunk-NURA4KUR.js} +2 -2
  204. package/dist/{chunk-25LWDG5D.js → chunk-NV5OYV3G.js} +5 -5
  205. package/dist/{chunk-TN5T5HRZ.js → chunk-NZMQDUOD.js} +5 -5
  206. package/dist/{chunk-WYDZP5F2.js → chunk-O4AWXTZQ.js} +3 -3
  207. package/dist/{chunk-XNACICAB.js → chunk-O5UOCMH4.js} +3 -3
  208. package/dist/{chunk-QBADR2FO.js → chunk-O73DRA77.js} +6 -6
  209. package/dist/{chunk-TR4HIKJ2.js → chunk-OHG2UQ2O.js} +3 -3
  210. package/dist/{chunk-7IYAHFPE.js → chunk-OLUG4IFF.js} +2 -2
  211. package/dist/{chunk-VWSFA4LJ.js → chunk-OWJD3V4V.js} +2 -2
  212. package/dist/{chunk-SFAU5R5S.js → chunk-PEGNFZ3F.js} +2 -2
  213. package/dist/{chunk-THVIT3PW.js → chunk-PQCFW2KT.js} +10 -10
  214. package/dist/{chunk-LMPTC4CX.js → chunk-QLDMF7MH.js} +2 -2
  215. package/dist/{chunk-DYJGYGPB.js → chunk-R5YZ3ROM.js} +2 -2
  216. package/dist/{chunk-SCNEQFIW.js → chunk-RABKQFTA.js} +2 -2
  217. package/dist/{chunk-PVR5EELP.js → chunk-RNBH5TSM.js} +2 -2
  218. package/dist/{chunk-2DL6NJP5.js → chunk-RXMIXKB3.js} +1 -1
  219. package/dist/{chunk-JFK7NTEA.js → chunk-S6WJ6TUT.js} +7 -1
  220. package/dist/{chunk-JFK7NTEA.js.map → chunk-S6WJ6TUT.js.map} +1 -1
  221. package/dist/{chunk-UXXFMF4X.js → chunk-SJPAKWWP.js} +2 -2
  222. package/dist/{chunk-FRP64DEK.js → chunk-SK57RWSA.js} +2 -2
  223. package/dist/{chunk-WSZQNTVN.js → chunk-SSZROOOI.js} +2 -2
  224. package/dist/{chunk-2CKVVAGP.js → chunk-TM2ZLY3Q.js} +13 -13
  225. package/dist/{chunk-7VN6VC3D.js → chunk-UHMMRQGU.js} +3 -3
  226. package/dist/{chunk-G2BX56CN.js → chunk-W57QFLQD.js} +3 -3
  227. package/dist/{chunk-TEPPPAJI.js → chunk-WLZVXCPZ.js} +3 -3
  228. package/dist/{chunk-PFAUGEV5.js → chunk-WN2MIB4Q.js} +2 -2
  229. package/dist/{chunk-QXEDIDBZ.js → chunk-WWM7WVD2.js} +2 -2
  230. package/dist/{chunk-AX6YJA5U.js → chunk-X7Z4B5GK.js} +2 -2
  231. package/dist/{chunk-WBPQ7OPC.js → chunk-XDCZBOEY.js} +1 -1
  232. package/dist/{chunk-4MQLGMV2.js → chunk-XGE75VPK.js} +3 -3
  233. package/dist/{chunk-LKJ2C7PH.js → chunk-ZPZYYSHW.js} +8 -8
  234. package/dist/{chunk-YG3IJCM2.js → chunk-ZRB4M3GG.js} +4 -4
  235. package/dist/{chunk-ERG355NM.js → chunk-ZWACUOU5.js} +3 -3
  236. package/dist/{chunk-XN6CALYY.js → chunk-ZZUKJ5HQ.js} +5 -5
  237. package/dist/composer.js +6 -6
  238. package/dist/{computer-viewer-VA5JONUH.js → computer-viewer-BWVNDFTO.js} +5 -5
  239. package/dist/connect.js +6 -6
  240. package/dist/desktop.js +2 -2
  241. package/dist/editor.js +2 -2
  242. package/dist/{embedded-new-voice-6BILAOUG.js → embedded-new-voice-GBXSZ3TO.js} +5 -5
  243. package/dist/{embedded-voice-UDE4JRKB.js → embedded-voice-MGI7EK7C.js} +5 -5
  244. package/dist/{fleet-decision-row-NN2HXDX3.js → fleet-decision-row-35S3GAUN.js} +2 -2
  245. package/dist/index.js +32 -32
  246. package/dist/interaction.js +5 -5
  247. package/dist/machines.js +3 -3
  248. package/dist/messages/en.d.ts +6 -0
  249. package/dist/messages.js +1 -1
  250. package/dist/{model-policy-picker-menu-NRTO6FRP.js → model-policy-picker-menu-KP53N6UJ.js} +4 -4
  251. package/dist/{platform-activity-row-ENQVIFTL.js → platform-activity-row-ISMXR7NJ.js} +2 -2
  252. package/dist/{queue-surface-implementation-H4XSNHZE.js → queue-surface-implementation-ULW7DDJA.js} +5 -5
  253. package/dist/realtime.js +4 -4
  254. package/dist/{sandbox-files-IEHODU35.js → sandbox-files-QYSD4XCZ.js} +6 -6
  255. package/dist/session-agents-model.d.ts +23 -1
  256. package/dist/session-agents-model.js +6 -1
  257. package/dist/session-app.js +109 -109
  258. package/dist/{session-realtime-JNKDSGH7.js → session-realtime-JXRLPNUH.js} +3 -3
  259. package/dist/session-realtime.js +2 -2
  260. package/dist/session-ui.js +24 -24
  261. package/dist/session.js +5 -5
  262. package/dist/sites.js +2 -2
  263. package/dist/terminal.js +2 -2
  264. package/dist/this-computer.js +3 -3
  265. package/dist/{timeline-annotation-markers-ZSOFW7PG.js → timeline-annotation-markers-OJYKHBEO.js} +2 -2
  266. package/dist/{timeline-annotation-selection-YWV2UC34.js → timeline-annotation-selection-6OAZLXFU.js} +2 -2
  267. package/dist/{timeline-annotations-dialog-ZWQVX2HI.js → timeline-annotations-dialog-5M6DP5FX.js} +3 -3
  268. package/dist/usage.js +2 -2
  269. package/dist/workbench.js +4 -4
  270. package/package.json +4 -4
  271. package/src/app/components/session/subagents.tsx +6 -28
  272. package/src/app/lib/format.tsx +2 -17
  273. package/src/messages/en.ts +6 -0
  274. package/src/session-agents-model.ts +75 -1
  275. package/dist/chunk-5TLEWXAB.js.map +0 -1
  276. package/dist/chunk-IE5YUCOT.js +0 -26
  277. package/dist/chunk-IE5YUCOT.js.map +0 -1
  278. package/dist/chunk-PKEKZ2VA.js.map +0 -1
  279. /package/dist/{browser-viewer-VPK3CV2H.js.map → browser-viewer-YQC6BFMS.js.map} +0 -0
  280. /package/dist/{chat-interactive-block-AMDSW656.js.map → chat-interactive-block-Z22YHDRU.js.map} +0 -0
  281. /package/dist/{chunk-TDIOBPLA.js.map → chunk-24POWVUY.js.map} +0 -0
  282. /package/dist/{chunk-SJORXXLV.js.map → chunk-26P7B46A.js.map} +0 -0
  283. /package/dist/{chunk-6O4VWKSO.js.map → chunk-27EORKJ4.js.map} +0 -0
  284. /package/dist/{chunk-WWOHORRO.js.map → chunk-2K27S6LK.js.map} +0 -0
  285. /package/dist/{chunk-OFB6TUDC.js.map → chunk-2LUO22FR.js.map} +0 -0
  286. /package/dist/{chunk-FSP334UU.js.map → chunk-2SZ3KC5S.js.map} +0 -0
  287. /package/dist/{chunk-GZGQHQI7.js.map → chunk-32HA7DXJ.js.map} +0 -0
  288. /package/dist/{chunk-PCJLH45G.js.map → chunk-3MQM4ZOC.js.map} +0 -0
  289. /package/dist/{chunk-SD4PPZFB.js.map → chunk-3ZZOE4SN.js.map} +0 -0
  290. /package/dist/{chunk-YGSJWWT3.js.map → chunk-467VRP4E.js.map} +0 -0
  291. /package/dist/{chunk-D3RK3NGM.js.map → chunk-4BF3DD6R.js.map} +0 -0
  292. /package/dist/{chunk-CDUDKETD.js.map → chunk-4ICPJZAB.js.map} +0 -0
  293. /package/dist/{chunk-I66ZB6KD.js.map → chunk-4PC7LIQK.js.map} +0 -0
  294. /package/dist/{chunk-D5OWJZQR.js.map → chunk-4RY64KQY.js.map} +0 -0
  295. /package/dist/{chunk-PUTS4DYW.js.map → chunk-4VJOZJDV.js.map} +0 -0
  296. /package/dist/{chunk-AOUCHCSB.js.map → chunk-4XKT4ENZ.js.map} +0 -0
  297. /package/dist/{chunk-F3FN6DO6.js.map → chunk-4XO346BW.js.map} +0 -0
  298. /package/dist/{chunk-YO64YVYL.js.map → chunk-65K5LV4L.js.map} +0 -0
  299. /package/dist/{chunk-KFWVBTUH.js.map → chunk-6JF7C3U3.js.map} +0 -0
  300. /package/dist/{chunk-LQ47YL6E.js.map → chunk-6K3WNTRI.js.map} +0 -0
  301. /package/dist/{chunk-CCR33J7L.js.map → chunk-6N7W3TOV.js.map} +0 -0
  302. /package/dist/{chunk-ILDOW2IQ.js.map → chunk-6PQBKMUL.js.map} +0 -0
  303. /package/dist/{chunk-VO6RVVP7.js.map → chunk-6VITVQ23.js.map} +0 -0
  304. /package/dist/{chunk-AIEXYO2X.js.map → chunk-6YDXUE5H.js.map} +0 -0
  305. /package/dist/{chunk-HPB4KSV3.js.map → chunk-72XEFLMD.js.map} +0 -0
  306. /package/dist/{chunk-7R2JQHBX.js.map → chunk-74NIHMAT.js.map} +0 -0
  307. /package/dist/{chunk-5MJHH72T.js.map → chunk-7EGWIME2.js.map} +0 -0
  308. /package/dist/{chunk-WVX5AQXS.js.map → chunk-7H2D4VNU.js.map} +0 -0
  309. /package/dist/{chunk-IUK5QGP5.js.map → chunk-7JZSFJHB.js.map} +0 -0
  310. /package/dist/{chunk-AJPW3SV4.js.map → chunk-7OIBLMDP.js.map} +0 -0
  311. /package/dist/{chunk-5YFY4SFC.js.map → chunk-AJ7PY4FJ.js.map} +0 -0
  312. /package/dist/{chunk-3ABPIUCK.js.map → chunk-B254JG72.js.map} +0 -0
  313. /package/dist/{chunk-F33EDYS7.js.map → chunk-BCFHMBMK.js.map} +0 -0
  314. /package/dist/{chunk-TJQDL3JH.js.map → chunk-BPD4IJBG.js.map} +0 -0
  315. /package/dist/{chunk-FB3B45FP.js.map → chunk-BQWUXC55.js.map} +0 -0
  316. /package/dist/{chunk-DGLRZMXL.js.map → chunk-BWKZEW6K.js.map} +0 -0
  317. /package/dist/{chunk-MOKYT3X3.js.map → chunk-C6JL6PBL.js.map} +0 -0
  318. /package/dist/{chunk-JWN7SLTO.js.map → chunk-CA64OZLZ.js.map} +0 -0
  319. /package/dist/{chunk-GFSOXB2K.js.map → chunk-CEQUNJJY.js.map} +0 -0
  320. /package/dist/{chunk-DFXZYNTX.js.map → chunk-CKA4SJRK.js.map} +0 -0
  321. /package/dist/{chunk-D64Z4V26.js.map → chunk-CPKD2YGK.js.map} +0 -0
  322. /package/dist/{chunk-A2E3ZF6N.js.map → chunk-D4QOZXPM.js.map} +0 -0
  323. /package/dist/{chunk-A6CK4ENG.js.map → chunk-DAQG3C4W.js.map} +0 -0
  324. /package/dist/{chunk-7PUFAH4I.js.map → chunk-DNLXQUBX.js.map} +0 -0
  325. /package/dist/{chunk-ZX5H7LWD.js.map → chunk-DNWBLT4U.js.map} +0 -0
  326. /package/dist/{chunk-4U4GXWXS.js.map → chunk-DNYD7AUG.js.map} +0 -0
  327. /package/dist/{chunk-EMCB6XKU.js.map → chunk-DZH2HTTB.js.map} +0 -0
  328. /package/dist/{chunk-Z6E6TUAE.js.map → chunk-EURDMOXZ.js.map} +0 -0
  329. /package/dist/{chunk-UUSAOIJR.js.map → chunk-F4B2YYCN.js.map} +0 -0
  330. /package/dist/{chunk-ENS6E4RZ.js.map → chunk-FH75NNLB.js.map} +0 -0
  331. /package/dist/{chunk-H4IE2PYF.js.map → chunk-FMATVQFW.js.map} +0 -0
  332. /package/dist/{chunk-ECHYJP63.js.map → chunk-FVCLVASD.js.map} +0 -0
  333. /package/dist/{chunk-PMD7V4N7.js.map → chunk-G3FU2IF7.js.map} +0 -0
  334. /package/dist/{chunk-HUXDGWAN.js.map → chunk-GMVKCEBG.js.map} +0 -0
  335. /package/dist/{chunk-SWCLN6JE.js.map → chunk-GRNE5ANU.js.map} +0 -0
  336. /package/dist/{chunk-IPPVX5GF.js.map → chunk-GTR2WUBA.js.map} +0 -0
  337. /package/dist/{chunk-BT2MVGHT.js.map → chunk-GTR5NLVP.js.map} +0 -0
  338. /package/dist/{chunk-HNNM2GDN.js.map → chunk-GUIZDI5T.js.map} +0 -0
  339. /package/dist/{chunk-ND2WCWXI.js.map → chunk-GXK4CUAB.js.map} +0 -0
  340. /package/dist/{chunk-MJQBC7C5.js.map → chunk-HCCSAECI.js.map} +0 -0
  341. /package/dist/{chunk-QLIDZGPV.js.map → chunk-HJTTDLF6.js.map} +0 -0
  342. /package/dist/{chunk-WUHB422G.js.map → chunk-HTKVYEVB.js.map} +0 -0
  343. /package/dist/{chunk-DKCX643S.js.map → chunk-HXZIX7MR.js.map} +0 -0
  344. /package/dist/{chunk-DJFTH2DI.js.map → chunk-I57HZMMA.js.map} +0 -0
  345. /package/dist/{chunk-VPNXQUUS.js.map → chunk-I74J2UZ2.js.map} +0 -0
  346. /package/dist/{chunk-A6T4FGE7.js.map → chunk-IWIMIRV3.js.map} +0 -0
  347. /package/dist/{chunk-FVL4B552.js.map → chunk-JI6WPLZB.js.map} +0 -0
  348. /package/dist/{chunk-RAMZTZOB.js.map → chunk-JJ7VMIEQ.js.map} +0 -0
  349. /package/dist/{chunk-GDLDBR6B.js.map → chunk-JQKURO3S.js.map} +0 -0
  350. /package/dist/{chunk-O2SBHS2N.js.map → chunk-K4FDZVMQ.js.map} +0 -0
  351. /package/dist/{chunk-TLL22FFO.js.map → chunk-KUO5WFXG.js.map} +0 -0
  352. /package/dist/{chunk-KUNFUSZ7.js.map → chunk-KVMFT6FN.js.map} +0 -0
  353. /package/dist/{chunk-5M23GZA2.js.map → chunk-KW53DBY7.js.map} +0 -0
  354. /package/dist/{chunk-5HIOVXOX.js.map → chunk-LG67ZNRU.js.map} +0 -0
  355. /package/dist/{chunk-VW3BBTMA.js.map → chunk-LJZNHDKI.js.map} +0 -0
  356. /package/dist/{chunk-CB574ERL.js.map → chunk-LR7U3HCD.js.map} +0 -0
  357. /package/dist/{chunk-2FPS5H2D.js.map → chunk-M5E3CKSE.js.map} +0 -0
  358. /package/dist/{chunk-3PEXVG4D.js.map → chunk-M7A226EQ.js.map} +0 -0
  359. /package/dist/{chunk-IIO2MR3B.js.map → chunk-M7YEZR6X.js.map} +0 -0
  360. /package/dist/{chunk-XU4I47IP.js.map → chunk-MB2DTUEG.js.map} +0 -0
  361. /package/dist/{chunk-UGEWCWVV.js.map → chunk-MDRLP5DO.js.map} +0 -0
  362. /package/dist/{chunk-SQDPHCK2.js.map → chunk-MHIYYHCL.js.map} +0 -0
  363. /package/dist/{chunk-R7XCJWCD.js.map → chunk-MY6VZVCP.js.map} +0 -0
  364. /package/dist/{chunk-BLPXOHG6.js.map → chunk-NF6Q4XTN.js.map} +0 -0
  365. /package/dist/{chunk-EH7TTYE6.js.map → chunk-NPDL4W4Y.js.map} +0 -0
  366. /package/dist/{chunk-NQQKOJDI.js.map → chunk-NURA4KUR.js.map} +0 -0
  367. /package/dist/{chunk-25LWDG5D.js.map → chunk-NV5OYV3G.js.map} +0 -0
  368. /package/dist/{chunk-TN5T5HRZ.js.map → chunk-NZMQDUOD.js.map} +0 -0
  369. /package/dist/{chunk-WYDZP5F2.js.map → chunk-O4AWXTZQ.js.map} +0 -0
  370. /package/dist/{chunk-XNACICAB.js.map → chunk-O5UOCMH4.js.map} +0 -0
  371. /package/dist/{chunk-QBADR2FO.js.map → chunk-O73DRA77.js.map} +0 -0
  372. /package/dist/{chunk-TR4HIKJ2.js.map → chunk-OHG2UQ2O.js.map} +0 -0
  373. /package/dist/{chunk-7IYAHFPE.js.map → chunk-OLUG4IFF.js.map} +0 -0
  374. /package/dist/{chunk-VWSFA4LJ.js.map → chunk-OWJD3V4V.js.map} +0 -0
  375. /package/dist/{chunk-SFAU5R5S.js.map → chunk-PEGNFZ3F.js.map} +0 -0
  376. /package/dist/{chunk-THVIT3PW.js.map → chunk-PQCFW2KT.js.map} +0 -0
  377. /package/dist/{chunk-LMPTC4CX.js.map → chunk-QLDMF7MH.js.map} +0 -0
  378. /package/dist/{chunk-DYJGYGPB.js.map → chunk-R5YZ3ROM.js.map} +0 -0
  379. /package/dist/{chunk-SCNEQFIW.js.map → chunk-RABKQFTA.js.map} +0 -0
  380. /package/dist/{chunk-PVR5EELP.js.map → chunk-RNBH5TSM.js.map} +0 -0
  381. /package/dist/{chunk-2DL6NJP5.js.map → chunk-RXMIXKB3.js.map} +0 -0
  382. /package/dist/{chunk-UXXFMF4X.js.map → chunk-SJPAKWWP.js.map} +0 -0
  383. /package/dist/{chunk-FRP64DEK.js.map → chunk-SK57RWSA.js.map} +0 -0
  384. /package/dist/{chunk-WSZQNTVN.js.map → chunk-SSZROOOI.js.map} +0 -0
  385. /package/dist/{chunk-2CKVVAGP.js.map → chunk-TM2ZLY3Q.js.map} +0 -0
  386. /package/dist/{chunk-7VN6VC3D.js.map → chunk-UHMMRQGU.js.map} +0 -0
  387. /package/dist/{chunk-G2BX56CN.js.map → chunk-W57QFLQD.js.map} +0 -0
  388. /package/dist/{chunk-TEPPPAJI.js.map → chunk-WLZVXCPZ.js.map} +0 -0
  389. /package/dist/{chunk-PFAUGEV5.js.map → chunk-WN2MIB4Q.js.map} +0 -0
  390. /package/dist/{chunk-QXEDIDBZ.js.map → chunk-WWM7WVD2.js.map} +0 -0
  391. /package/dist/{chunk-AX6YJA5U.js.map → chunk-X7Z4B5GK.js.map} +0 -0
  392. /package/dist/{chunk-WBPQ7OPC.js.map → chunk-XDCZBOEY.js.map} +0 -0
  393. /package/dist/{chunk-4MQLGMV2.js.map → chunk-XGE75VPK.js.map} +0 -0
  394. /package/dist/{chunk-LKJ2C7PH.js.map → chunk-ZPZYYSHW.js.map} +0 -0
  395. /package/dist/{chunk-YG3IJCM2.js.map → chunk-ZRB4M3GG.js.map} +0 -0
  396. /package/dist/{chunk-ERG355NM.js.map → chunk-ZWACUOU5.js.map} +0 -0
  397. /package/dist/{chunk-XN6CALYY.js.map → chunk-ZZUKJ5HQ.js.map} +0 -0
  398. /package/dist/{computer-viewer-VA5JONUH.js.map → computer-viewer-BWVNDFTO.js.map} +0 -0
  399. /package/dist/{embedded-new-voice-6BILAOUG.js.map → embedded-new-voice-GBXSZ3TO.js.map} +0 -0
  400. /package/dist/{embedded-voice-UDE4JRKB.js.map → embedded-voice-MGI7EK7C.js.map} +0 -0
  401. /package/dist/{fleet-decision-row-NN2HXDX3.js.map → fleet-decision-row-35S3GAUN.js.map} +0 -0
  402. /package/dist/{model-policy-picker-menu-NRTO6FRP.js.map → model-policy-picker-menu-KP53N6UJ.js.map} +0 -0
  403. /package/dist/{platform-activity-row-ENQVIFTL.js.map → platform-activity-row-ISMXR7NJ.js.map} +0 -0
  404. /package/dist/{queue-surface-implementation-H4XSNHZE.js.map → queue-surface-implementation-ULW7DDJA.js.map} +0 -0
  405. /package/dist/{sandbox-files-IEHODU35.js.map → sandbox-files-QYSD4XCZ.js.map} +0 -0
  406. /package/dist/{session-realtime-JNKDSGH7.js.map → session-realtime-JXRLPNUH.js.map} +0 -0
  407. /package/dist/{timeline-annotation-markers-ZSOFW7PG.js.map → timeline-annotation-markers-OJYKHBEO.js.map} +0 -0
  408. /package/dist/{timeline-annotation-selection-YWV2UC34.js.map → timeline-annotation-selection-6OAZLXFU.js.map} +0 -0
  409. /package/dist/{timeline-annotations-dialog-ZWQVX2HI.js.map → timeline-annotations-dialog-5M6DP5FX.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/app/components/command-menu/command-menu.tsx"],"sourcesContent":["/**\n * The ⌘K menu: find a chat by its title, or run any action, from one field.\n *\n * It opens instantly from what the app already knows (chats the sidebar has\n * loaded and the chats opened recently) and merges the server's title search as\n * it arrives. Chats in the person's other workspaces show too, tagged with\n * their workspace, and so do workspaces to switch to. Tab on a chat shows that\n * chat's actions; the chords of chat actions work on the highlighted chat\n * while the menu is open.\n */\nimport {\n useCallback,\n useEffect,\n useId,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type KeyboardEvent as ReactKeyboardEvent,\n type ReactNode,\n type RefObject,\n} from \"react\";\nimport { Dialog as DialogPrimitive } from \"radix-ui\";\nimport {\n ArchiveIcon,\n ArrowUpRightIcon,\n ChevronRightIcon,\n CornerDownLeftIcon,\n LockIcon,\n MessageSquareIcon,\n PinIcon,\n SearchIcon,\n TextSearchIcon,\n type LucideIcon,\n} from \"lucide-react\";\nimport type { SessionListRow } from \"../../../session-list-model\";\nimport { useAppContext } from \"../../app-context\";\nimport {\n readChatDirectory,\n rememberChats,\n useChatDirectoryVersion,\n type ChatRecord,\n} from \"../../lib/actions/chat-directory\";\nimport { matchesChord, type Chord } from \"../../lib/actions/chords\";\nimport { useAppActions } from \"../../lib/actions/actions-provider\";\nimport {\n foldForSearch,\n LOOSE_MATCH_BELOW,\n rankLabel,\n rankWithKeywords,\n} from \"../../lib/actions/rank\";\nimport {\n appActions,\n actionIcon,\n actionTitle,\n type ActionEnv,\n type AppAction,\n type WorkspaceChoice,\n} from \"../../lib/actions/registry\";\nimport { cn } from \"../../lib/utils\";\nimport { DialogOverlay, DialogPortal } from \"../../../ui/dialog\";\nimport { formatRelativeTime } from \"../../../ui/relative-time\";\nimport { Keycaps } from \"./keycaps\";\nimport { WorkspaceTag } from \"./workspace-tag\";\nimport { ChatStatusMarks, useChatStatusRefresh } from \"./chat-status\";\nimport { currentChatStatus, type ChatStatus } from \"../../lib/actions/chat-status\";\n\ntype Item = {\n key: string;\n group: string;\n icon: LucideIcon;\n /** A workspace's initial, drawn as the workspace picker draws it, instead of the icon. */\n tile?: string | undefined;\n title: string;\n /** Text to mark as matched in the title. */\n highlight?: string | undefined;\n /** Quiet text on the right (when, \"Archived\"). */\n meta?: string | undefined;\n /** The workspace a chat lives in, when it is not the one on screen. */\n workspaceTag?: string | undefined;\n chord?: Chord | undefined;\n /** Present on chat rows: Tab opens their actions, chat chords act on them. */\n chat?: ChatRecord | undefined;\n /** The chat's sidebar status marks, while its status is known to be current. */\n status?: ChatStatus | null | undefined;\n run(options: { newTab: boolean }): void;\n};\n\ntype Group = { label: string; items: Item[]; best: number };\n\nconst RECENT_LIMIT = 6;\nconst CHAT_RESULT_LIMIT = 8;\nconst ACTION_RESULT_LIMIT = 6;\nconst WORKSPACE_RESULT_LIMIT = 4;\nconst SERVER_DEBOUNCE_MS = 120;\n/** Other workspaces whose titles the server searches too, most used first. */\nconst OTHER_WORKSPACES_SEARCHED = 9;\n/** A chat in another workspace ranks just below an equal match here. */\nconst ELSEWHERE_PENALTY = 10;\n\nfunction relativeMeta(record: ChatRecord, now: number): string | undefined {\n if (record.archived) return \"Archived\";\n if (!record.updatedAt) return undefined;\n return formatRelativeTime(record.updatedAt, { now });\n}\n\nfunction chatIcon(record: ChatRecord): LucideIcon {\n if (record.archived) return ArchiveIcon;\n if (record.pinned) return PinIcon;\n return MessageSquareIcon;\n}\n\n/** Rows the menu may list: top-level chats only (subagent chats live under their parent). */\nfunction listable(record: ChatRecord): boolean {\n return !record.row || record.row.parentSessionId === null;\n}\n\n/** Marks the query's words in a title, case- and accent-insensitively. */\nfunction Highlighted(props: { text: string; query: string | undefined }) {\n const { text, query } = props;\n const words = query ? foldForSearch(query).split(\" \").filter(Boolean) : [];\n if (words.length === 0) return <>{text}</>;\n // Fold per character so positions in the folded text map back to the title.\n const folded = Array.from(text, (character) => foldForSearch(character) || \" \");\n const joined = folded.join(\"\");\n const marked = new Array<boolean>(folded.length).fill(false);\n const offsets: number[] = [];\n let offset = 0;\n for (const piece of folded) {\n offsets.push(offset);\n offset += piece.length;\n }\n const indexAt = (position: number) => {\n let index = offsets.findIndex((start) => start > position);\n index = index < 0 ? offsets.length - 1 : index - 1;\n return index;\n };\n const phrase = words.join(\" \");\n const ranges: Array<[number, number]> = [];\n const whole = joined.indexOf(phrase);\n if (whole >= 0) ranges.push([whole, whole + phrase.length]);\n else {\n for (const word of words) {\n const at = joined.indexOf(word);\n if (at >= 0) ranges.push([at, at + word.length]);\n }\n }\n for (const [start, end] of ranges) {\n for (let index = indexAt(start); index <= indexAt(end - 1); index++) marked[index] = true;\n }\n const characters = Array.from(text);\n const parts: ReactNode[] = [];\n let run = \"\";\n let runMarked = false;\n characters.forEach((character, index) => {\n const isMarked = marked[index] ?? false;\n if (index > 0 && isMarked !== runMarked) {\n parts.push(\n runMarked ? (\n <mark key={parts.length} className=\"bg-transparent font-medium text-fg\">\n {run}\n </mark>\n ) : (\n run\n ),\n );\n run = \"\";\n }\n run += character;\n runMarked = isMarked;\n });\n if (run) {\n parts.push(\n runMarked ? (\n <mark key={parts.length} className=\"bg-transparent font-medium text-fg\">\n {run}\n </mark>\n ) : (\n run\n ),\n );\n }\n return <>{parts}</>;\n}\n\n/**\n * The server's title search: this workspace, and the person's other workspaces\n * they use most, side by side. Each workspace's matches join the list as they\n * arrive.\n */\nfunction useServerTitleSearch(\n workspaceIds: readonly string[],\n subjectId: string,\n query: string,\n open: boolean,\n) {\n const { client } = useAppContext();\n const [state, setState] = useState<{ query: string; rows: SessionListRow[]; loading: boolean }>({\n query: \"\",\n rows: [],\n loading: false,\n });\n const searchKey = workspaceIds.join(\",\");\n useEffect(() => {\n const trimmed = query.trim();\n if (!open || !trimmed || !searchKey) {\n setState({ query: \"\", rows: [], loading: false });\n return;\n }\n setState((current) => ({ ...current, loading: true }));\n const controller = new AbortController();\n const timer = window.setTimeout(() => {\n const targets = searchKey.split(\",\");\n let pending = targets.length;\n let first = true;\n const settle = (rows: SessionListRow[]) => {\n if (controller.signal.aborted) return;\n pending -= 1;\n const replace = first;\n first = false;\n setState((current) => ({\n query: trimmed,\n rows: replace || current.query !== trimmed ? rows : [...current.rows, ...rows],\n loading: pending > 0,\n }));\n };\n targets.forEach((workspaceId, index) => {\n client\n .listSessionPage(workspaceId, {\n search: trimmed,\n archiveStatus: \"all\",\n // This workspace first and fullest; a few from each of the others.\n limit: index === 0 ? 20 : 6,\n signal: controller.signal,\n })\n .then((page) => {\n const rows = [...(page.pinned ?? []), ...page.sessions];\n rememberChats(subjectId, rows);\n settle(rows);\n })\n .catch(() => {\n // Local results still show; the server search is an addition.\n settle([]);\n });\n });\n }, SERVER_DEBOUNCE_MS);\n return () => {\n window.clearTimeout(timer);\n controller.abort();\n };\n }, [client, searchKey, subjectId, query, open]);\n return state;\n}\n\nexport default function CommandMenu(props: {\n open: boolean;\n /** Opens listing workspaces to switch to. */\n pickWorkspace: boolean;\n onOpenChange: (open: boolean) => void;\n /** Where focus goes back to after a plain close. */\n returnFocus: RefObject<HTMLElement | null>;\n}) {\n const actions = useAppActions();\n if (!actions) return null;\n return (\n <CommandMenuDialog\n {...props}\n env={actions.env}\n run={actions.run}\n chordsFor={actions.chordsFor}\n />\n );\n}\n\nfunction CommandMenuDialog(props: {\n open: boolean;\n pickWorkspace: boolean;\n onOpenChange: (open: boolean) => void;\n returnFocus: RefObject<HTMLElement | null>;\n env: ActionEnv;\n run(action: AppAction, chat?: SessionListRow | null, chord?: Chord): void;\n chordsFor(action: AppAction): Chord[];\n}) {\n const { env, run, chordsFor, onOpenChange } = props;\n const { workspaceId, subjectId, platform, surface, workspaces } = env;\n const directoryVersion = useChatDirectoryVersion(subjectId);\n const [query, setQuery] = useState(\"\");\n const [focusChat, setFocusChat] = useState<ChatRecord | null>(null);\n const [pickingWorkspace, setPickingWorkspace] = useState(props.pickWorkspace);\n const [active, setActive] = useState(0);\n const inputRef = useRef<HTMLInputElement>(null);\n const listRef = useRef<HTMLDivElement>(null);\n const ranAction = useRef(false);\n /** Runs right after the menu has returned focus (see `AppAction.opensDialog`). */\n const afterClose = useRef<(() => void) | null>(null);\n const listId = useId();\n const workspaceNames = useMemo(\n () => new Map(workspaces.map((workspace) => [workspace.id, workspace.name])),\n [workspaces],\n );\n /** Chats the menu may show: this workspace's, and those of other workspaces still open to the person. */\n const reachable = useCallback(\n (id: string) => id === workspaceId || workspaceNames.has(id),\n [workspaceId, workspaceNames],\n );\n // The server searches this workspace and the other workspaces used most recently.\n const searchWorkspaceIds = useMemo(() => {\n void directoryVersion;\n const directory = readChatDirectory(subjectId, workspaceId);\n const used: string[] = [];\n for (const id of directory.recent) {\n const record = directory.rows.get(id);\n if (record && !used.includes(record.workspaceId)) used.push(record.workspaceId);\n }\n const others = [...used, ...workspaces.map((workspace) => workspace.id)].filter(\n (id, index, all) => id !== workspaceId && reachable(id) && all.indexOf(id) === index,\n );\n return [workspaceId, ...others.slice(0, OTHER_WORKSPACES_SEARCHED)];\n // Which workspaces to search changes only when the menu opens.\n }, [props.open, subjectId, workspaceId, workspaces, reachable]); // eslint-disable-line react-hooks/exhaustive-deps\n const server = useServerTitleSearch(\n searchWorkspaceIds,\n subjectId,\n focusChat || pickingWorkspace ? \"\" : query,\n props.open,\n );\n\n // Every open starts fresh.\n useEffect(() => {\n if (!props.open) return;\n setQuery(\"\");\n setFocusChat(null);\n setPickingWorkspace(props.pickWorkspace);\n setActive(0);\n ranAction.current = false;\n afterClose.current = null;\n }, [props.open, props.pickWorkspace]);\n\n const close = useCallback(() => onOpenChange(false), [onOpenChange]);\n\n const runAction = useCallback(\n (action: AppAction, chat: SessionListRow | null, chord?: Chord) => {\n if (action.opensDialog) {\n afterClose.current = () => run(action, action.forChat ? chat : undefined, chord);\n close();\n return;\n }\n ranAction.current = true;\n close();\n run(action, action.forChat ? chat : undefined, chord);\n },\n [close, run],\n );\n\n const openChat = useCallback(\n (record: ChatRecord, newTab: boolean) => {\n ranAction.current = true;\n close();\n if (newTab && surface === \"web\") {\n window.open(env.ops.linkTo(record), \"_blank\", \"noopener\");\n return;\n }\n env.openChat(record.id, record.workspaceId);\n },\n [close, env, surface],\n );\n\n const openWorkspace = useCallback(\n (id: string) => {\n ranAction.current = true;\n close();\n if (id !== workspaceId) env.openWorkspace(id);\n },\n [close, env, workspaceId],\n );\n\n const startPickingWorkspace = useCallback(() => {\n setFocusChat(null);\n setPickingWorkspace(true);\n setQuery(\"\");\n inputRef.current?.focus();\n }, []);\n\n const actionItem = useCallback(\n (action: AppAction, chat: SessionListRow | null, group: string, highlight?: string): Item => ({\n key: `action:${action.id}`,\n group,\n icon: actionIcon(action, chat),\n title: actionTitle(action, env, chat),\n highlight,\n chord: chordsFor(action)[0],\n // Switching workspace lists the workspaces right here.\n run: () =>\n action.id === \"go.switchWorkspace\" ? startPickingWorkspace() : runAction(action, chat),\n }),\n [chordsFor, env, runAction, startPickingWorkspace],\n );\n\n const groups = useMemo<Group[]>(() => {\n void directoryVersion;\n const now = Date.now();\n const directory = readChatDirectory(subjectId, workspaceId);\n const current = env.currentChat;\n const sidebarIds = new Set([...directory.sidebarOrder, ...directory.pinnedOrder]);\n\n const chatItem = (record: ChatRecord, group: string, highlight?: string): Item => ({\n key: `chat:${record.id}`,\n group,\n icon: chatIcon(record),\n title: record.title,\n highlight,\n meta: current?.id === record.id ? \"Open now\" : relativeMeta(record, now),\n workspaceTag:\n record.workspaceId === workspaceId ? undefined : workspaceNames.get(record.workspaceId),\n chat: record,\n status: currentChatStatus(record, sidebarIds, now),\n run: ({ newTab }) => openChat(record, newTab),\n });\n\n const workspaceItem = (choice: WorkspaceChoice, group: string, highlight?: string): Item => ({\n key: `workspace:${choice.id}`,\n group,\n icon: LockIcon,\n // A Personal workspace shows its lock, as in the workspace picker.\n tile: choice.personal ? undefined : (choice.name.trim()[0] ?? \"W\").toUpperCase(),\n title: choice.name,\n highlight,\n meta: choice.id === workspaceId ? \"Current\" : undefined,\n run: () => openWorkspace(choice.id),\n });\n\n // Workspaces to switch to, by organization.\n if (pickingWorkspace) {\n const trimmed = query.trim();\n const organizations = new Set(workspaces.map((choice) => choice.organization));\n const scored = workspaces.flatMap((choice) => {\n if (!trimmed) return [{ choice, rank: 0 }];\n const rank =\n rankLabel(choice.name, trimmed) ??\n (organizations.size > 1 ? rankLabel(choice.organization, trimmed) : null);\n return rank === null ? [] : [{ choice, rank }];\n });\n const realMatch = scored.some((entry) => entry.rank >= LOOSE_MATCH_BELOW);\n const kept = scored.filter(\n (entry) => !trimmed || !realMatch || entry.rank >= LOOSE_MATCH_BELOW,\n );\n if (trimmed) {\n kept.sort((a, b) => b.rank - a.rank);\n return [\n {\n label: \"Workspaces\",\n items: kept.map((entry) => workspaceItem(entry.choice, \"Workspaces\", trimmed)),\n best: 0,\n },\n ];\n }\n const byOrganization = new Map<string, Item[]>();\n for (const { choice } of kept) {\n const label = organizations.size > 1 ? choice.organization : \"Workspaces\";\n const list = byOrganization.get(label) ?? [];\n list.push(workspaceItem(choice, label));\n byOrganization.set(label, list);\n }\n return [...byOrganization].map(([label, items]) => ({ label, items, best: 0 }));\n }\n\n // A chat's own actions (after Tab).\n if (focusChat) {\n // Chats in other workspaces offer what works from here: open and copy link.\n const sameWorkspace = focusChat.workspaceId === workspaceId;\n const row = sameWorkspace\n ? (focusChat.row ?? (current?.id === focusChat.id ? current : null))\n : null;\n const items: Array<{ item: Item; rank: number }> = [];\n const openRank = rankLabel(\"Open\", query);\n if (openRank !== null) {\n items.push({\n rank: openRank + 1,\n item: {\n key: \"open\",\n group: focusChat.title,\n icon: CornerDownLeftIcon,\n title: \"Open\",\n highlight: query,\n run: () => openChat(focusChat, false),\n },\n });\n }\n if (surface === \"web\") {\n const tabRank = rankLabel(\"Open in new tab\", query);\n if (tabRank !== null) {\n items.push({\n rank: tabRank,\n item: {\n key: \"open-tab\",\n group: focusChat.title,\n icon: ArrowUpRightIcon,\n title: \"Open in new tab\",\n highlight: query,\n run: () => openChat(focusChat, true),\n },\n });\n }\n }\n for (const action of appActions()) {\n if (!action.forChat || action.inCommandMenu === false) continue;\n // Copy link needs only the id; the rest need the chat's row.\n const target = row ?? (action.id === \"chat.copyLink\" ? pseudoRow(focusChat) : null);\n if (!target || !action.available(env, target)) continue;\n const rank = rankWithKeywords(actionTitle(action, env, target), action.keywords, query);\n if (rank === null) continue;\n items.push({ rank, item: actionItem(action, target, focusChat.title, query) });\n }\n if (query) items.sort((a, b) => b.rank - a.rank);\n return [{ label: focusChat.title, items: items.map((entry) => entry.item), best: 0 }];\n }\n\n const trimmed = query.trim();\n if (!trimmed) {\n const result: Group[] = [];\n // Chats opened recently come first; the top of the sidebar fills the\n // rest, so a fresh window still offers somewhere to go.\n const recentIds = [...new Set([...directory.recent, ...directory.sidebarOrder])].filter(\n (id) => id !== current?.id,\n );\n const recent = recentIds\n .map((id) => directory.rows.get(id))\n .filter((record): record is ChatRecord =>\n Boolean(record && listable(record) && !record.archived && reachable(record.workspaceId)),\n )\n .slice(0, RECENT_LIMIT);\n if (recent.length > 0) {\n result.push({\n label: \"Recent chats\",\n items: recent.map((record) => chatItem(record, \"Recent chats\")),\n best: 0,\n });\n }\n if (current) {\n const chatActions = appActions().filter(\n (action) =>\n action.forChat &&\n action.inCommandMenu !== false &&\n action.id !== \"chat.find\" &&\n action.available(env, current),\n );\n if (chatActions.length > 0) {\n result.push({\n label: \"This chat\",\n items: chatActions.map((action) => actionItem(action, current, \"This chat\")),\n best: 0,\n });\n }\n }\n const general = appActions().filter(\n (action) =>\n !action.forChat &&\n action.inCommandMenu !== false &&\n action.id !== \"commandMenu.open\" &&\n action.available(env, null),\n );\n if (general.length > 0) {\n result.push({\n label: \"Go to\",\n items: general.map((action) => actionItem(action, null, \"Go to\")),\n best: 0,\n });\n }\n return result;\n }\n\n // Chats: everything the app knows, ranked by title, plus the server's matches.\n const recentIndex = new Map(directory.recent.map((id, index) => [id, index]));\n const serverIds = new Set(server.query === trimmed ? server.rows.map((row) => row.id) : []);\n const scored: Array<{ record: ChatRecord; rank: number; loose: boolean }> = [];\n for (const record of directory.rows.values()) {\n if (!listable(record) || !reachable(record.workspaceId)) continue;\n let rank = rankLabel(record.title, trimmed);\n const loose = rank !== null && rank < LOOSE_MATCH_BELOW;\n // The server matched every word in the title or first message.\n if (rank === null && serverIds.has(record.id)) rank = 50;\n if (rank === null) continue;\n const visited = recentIndex.get(record.id);\n if (visited !== undefined) rank += Math.max(0, 20 - visited);\n if (record.pinned) rank += 5;\n if (record.archived) rank -= 300;\n if (record.workspaceId !== workspaceId) rank -= ELSEWHERE_PENALTY;\n scored.push({ record, rank, loose });\n }\n\n const actionScores: Array<{ item: Item; rank: number; loose: boolean }> = [];\n for (const action of appActions()) {\n if (action.inCommandMenu === false) continue;\n const target = action.forChat ? current : null;\n if (action.forChat && !target) continue;\n if (!action.available(env, target)) continue;\n const rank = rankWithKeywords(actionTitle(action, env, target), action.keywords, trimmed);\n if (rank === null) continue;\n actionScores.push({\n rank,\n loose: rank < LOOSE_MATCH_BELOW,\n item: actionItem(action, target, \"Actions\", trimmed),\n });\n }\n const workspaceScores: Array<{ item: Item; rank: number; loose: boolean }> = [];\n for (const choice of workspaces) {\n if (choice.id === workspaceId) continue;\n const rank = rankLabel(choice.name, trimmed);\n if (rank === null) continue;\n workspaceScores.push({\n rank,\n loose: rank < LOOSE_MATCH_BELOW,\n item: workspaceItem(choice, \"Workspaces\", trimmed),\n });\n }\n // Letters-in-order guesses only help when nothing really matches; next to\n // real matches they are noise (\"pin\" → \"Postgres … investigation\").\n const hasRealMatch =\n scored.some((entry) => !entry.loose) ||\n actionScores.some((entry) => !entry.loose) ||\n workspaceScores.some((entry) => !entry.loose);\n const chats = scored\n .filter((entry) => !hasRealMatch || !entry.loose)\n .sort((a, b) => b.rank - a.rank || b.record.updatedAt - a.record.updatedAt)\n .slice(0, CHAT_RESULT_LIMIT);\n const actionsFound = actionScores\n .filter((entry) => !hasRealMatch || !entry.loose)\n .sort((a, b) => b.rank - a.rank)\n .slice(0, ACTION_RESULT_LIMIT);\n const workspacesFound = workspaceScores\n .filter((entry) => !hasRealMatch || !entry.loose)\n .sort((a, b) => b.rank - a.rank)\n .slice(0, WORKSPACE_RESULT_LIMIT);\n\n const result: Group[] = [];\n if (chats.length > 0) {\n result.push({\n label: \"Chats\",\n items: chats.map((entry) => chatItem(entry.record, \"Chats\", trimmed)),\n best: chats[0]!.rank,\n });\n }\n if (actionsFound.length > 0) {\n result.push({\n label: \"Actions\",\n items: actionsFound.map((entry) => entry.item),\n best: actionsFound[0]!.rank,\n });\n }\n if (workspacesFound.length > 0) {\n result.push({\n label: \"Workspaces\",\n items: workspacesFound.map((entry) => entry.item),\n // Chats and actions first on a tie: a workspace is a bigger jump.\n best: workspacesFound[0]!.rank - 1,\n });\n }\n // A clearly better action match (\"new\" → New chat) comes before chats.\n result.sort((a, b) => b.best - a.best);\n result.push({\n label: \"Messages\",\n best: -Infinity,\n items: [\n {\n key: \"search-messages\",\n group: \"Messages\",\n icon: TextSearchIcon,\n title: `Search messages for “${trimmed}”`,\n run: () => {\n afterClose.current = () => env.searchMessages(trimmed);\n close();\n },\n },\n ],\n });\n return result;\n }, [\n actionItem,\n close,\n directoryVersion,\n env,\n focusChat,\n openChat,\n openWorkspace,\n pickingWorkspace,\n query,\n reachable,\n server.query,\n server.rows,\n subjectId,\n surface,\n workspaceId,\n workspaceNames,\n workspaces,\n ]);\n\n const items = useMemo(() => groups.flatMap((group) => group.items), [groups]);\n const listedChatIds = useMemo(\n () => items.flatMap((item) => (item.chat ? [item.chat.id] : [])),\n [items],\n );\n useChatStatusRefresh({ subjectId, workspaceId, ids: listedChatIds, active: props.open });\n const activeIndex = items.length === 0 ? -1 : Math.min(active, items.length - 1);\n const activeItem = activeIndex >= 0 ? items[activeIndex] : undefined;\n const searching = Boolean(query.trim()) && !focusChat && !pickingWorkspace && server.loading;\n\n // Typing starts at the best match; the workspace list starts at the current workspace's neighbour.\n useEffect(() => {\n if (pickingWorkspace && !query) {\n const index = workspaces.findIndex((choice) => choice.id === workspaceId);\n setActive(index >= 0 && workspaces.length > 1 ? (index + 1) % workspaces.length : 0);\n return;\n }\n setActive(0);\n }, [query, focusChat, pickingWorkspace, workspaces, workspaceId]);\n\n // Keep the highlighted row in view without scrolling the page.\n useLayoutEffect(() => {\n if (!activeItem) return;\n const element = listRef.current?.querySelector<HTMLElement>(\n `[data-item-key=\"${CSS.escape(activeItem.key)}\"]`,\n );\n element?.scrollIntoView({ block: \"nearest\" });\n }, [activeItem]);\n\n const enterChat = useCallback((record: ChatRecord) => {\n setFocusChat(record);\n setQuery(\"\");\n inputRef.current?.focus();\n }, []);\n const leaveChat = useCallback(() => {\n setFocusChat(null);\n setPickingWorkspace(false);\n setQuery(\"\");\n }, []);\n\n const onKeyDown = useCallback(\n (event: ReactKeyboardEvent<HTMLDivElement>) => {\n if (event.nativeEvent.isComposing) return;\n const count = items.length;\n const mod = platform === \"mac\" ? event.metaKey : event.ctrlKey;\n switch (event.key) {\n case \"ArrowDown\":\n case \"ArrowUp\": {\n if (event.altKey || mod) break;\n event.preventDefault();\n if (count === 0) return;\n const step = event.key === \"ArrowDown\" ? 1 : -1;\n setActive((current) => (Math.min(current, count - 1) + step + count) % count);\n return;\n }\n case \"PageDown\":\n case \"PageUp\": {\n event.preventDefault();\n if (count === 0) return;\n const step = event.key === \"PageDown\" ? 5 : -5;\n setActive((current) => Math.max(0, Math.min(count - 1, current + step)));\n return;\n }\n case \"Home\":\n case \"End\": {\n // Inside the field these move the caret, unless the field is empty.\n if (query) break;\n event.preventDefault();\n setActive(event.key === \"Home\" ? 0 : Math.max(0, count - 1));\n return;\n }\n case \"Enter\": {\n event.preventDefault();\n activeItem?.run({ newTab: mod });\n return;\n }\n case \"Tab\": {\n event.preventDefault();\n if (event.shiftKey) {\n if (focusChat || pickingWorkspace) leaveChat();\n return;\n }\n if (!focusChat && activeItem?.chat) enterChat(activeItem.chat);\n return;\n }\n case \"Backspace\": {\n if ((focusChat || pickingWorkspace) && !query) {\n event.preventDefault();\n leaveChat();\n }\n return;\n }\n default:\n break;\n }\n // A chat action's chord acts on the highlighted chat, as in Linear.\n const chatRecord = focusChat ?? activeItem?.chat;\n if (!chatRecord) return;\n const sameWorkspace = chatRecord.workspaceId === workspaceId;\n for (const action of appActions()) {\n if (!action.forChat) continue;\n const chord = chordsFor(action).find((candidate) =>\n matchesChord(event.nativeEvent, candidate, platform),\n );\n if (!chord) continue;\n const row =\n (sameWorkspace\n ? (chatRecord.row ?? (env.currentChat?.id === chatRecord.id ? env.currentChat : null))\n : null) ?? (action.id === \"chat.copyLink\" ? pseudoRow(chatRecord) : null);\n event.preventDefault();\n event.stopPropagation();\n if (row && action.available(env, row)) runAction(action, row, chord);\n return;\n }\n },\n [\n activeItem,\n chordsFor,\n enterChat,\n env,\n focusChat,\n items.length,\n leaveChat,\n pickingWorkspace,\n platform,\n query,\n runAction,\n workspaceId,\n ],\n );\n\n const placeholder = focusChat\n ? \"Search actions…\"\n : pickingWorkspace\n ? \"Switch to workspace…\"\n : \"Search chats or run an action…\";\n const optionId = (item: Item) => `${listId}-${item.key.replace(/[^a-zA-Z0-9_-]/g, \"_\")}`;\n\n return (\n <DialogPrimitive.Root open={props.open} onOpenChange={onOpenChange}>\n <DialogPortal>\n <DialogOverlay className=\"bg-black/25 dark:bg-black/45\" />\n <DialogPrimitive.Content\n data-og-command-menu=\"\"\n aria-label=\"Command menu\"\n aria-describedby={undefined}\n onOpenAutoFocus={(event) => {\n event.preventDefault();\n inputRef.current?.focus();\n }}\n onCloseAutoFocus={(event) => {\n // An action moves focus where it belongs (the new chat's composer,\n // the title being renamed); only a plain close returns focus.\n if (ranAction.current) {\n event.preventDefault();\n return;\n }\n const target = props.returnFocus.current;\n if (target?.isConnected) {\n event.preventDefault();\n target.focus({ preventScroll: true });\n }\n const next = afterClose.current;\n afterClose.current = null;\n next?.();\n }}\n onEscapeKeyDown={(event) => {\n // Esc steps back out of a chat's actions, or the workspace list\n // reached from the menu, before it closes the menu.\n if (!focusChat && !(pickingWorkspace && !props.pickWorkspace)) return;\n event.preventDefault();\n leaveChat();\n }}\n onKeyDown={onKeyDown}\n className={cn(\n \"fixed top-[12dvh] left-1/2 z-50 flex max-h-[min(560px,76dvh)] w-[calc(100vw-1.5rem)] max-w-[640px] -translate-x-1/2 flex-col overflow-hidden\",\n \"rounded-2xl border border-border bg-surface text-fg shadow-og-lg outline-hidden\",\n \"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-98\",\n \"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-98\",\n \"duration-[120ms] max-sm:top-3\",\n )}\n >\n <DialogPrimitive.Title className=\"sr-only\">Command menu</DialogPrimitive.Title>\n <div className=\"flex min-h-13 shrink-0 items-center gap-2.5 border-b border-border px-4\">\n <SearchIcon aria-hidden=\"true\" className=\"size-4 shrink-0 text-fg-muted\" />\n {focusChat ? (\n <button\n type=\"button\"\n onClick={leaveChat}\n title=\"Back to all results\"\n className=\"inline-flex max-w-[45%] shrink-0 items-center gap-1 rounded-full bg-hover py-0.5 pr-1.5 pl-2.5 text-xs font-medium text-fg outline-hidden hover:bg-selection focus-visible:outline-2 focus-visible:outline-ring/55\"\n >\n <span className=\"truncate\">{focusChat.title}</span>\n <ChevronRightIcon aria-hidden=\"true\" className=\"size-3.5 text-fg-muted\" />\n </button>\n ) : pickingWorkspace ? (\n <button\n type=\"button\"\n onClick={leaveChat}\n title=\"Back to all results\"\n className=\"inline-flex shrink-0 items-center gap-1 rounded-full bg-hover py-0.5 pr-1.5 pl-2.5 text-xs font-medium text-fg outline-hidden hover:bg-selection focus-visible:outline-2 focus-visible:outline-ring/55\"\n >\n Workspaces\n <ChevronRightIcon aria-hidden=\"true\" className=\"size-3.5 text-fg-muted\" />\n </button>\n ) : null}\n <input\n ref={inputRef}\n role=\"combobox\"\n aria-expanded=\"true\"\n aria-controls={listId}\n aria-autocomplete=\"list\"\n aria-activedescendant={activeItem ? optionId(activeItem) : undefined}\n aria-label={\n focusChat\n ? `Actions for ${focusChat.title}`\n : pickingWorkspace\n ? \"Search workspaces\"\n : \"Search chats and actions\"\n }\n autoComplete=\"off\"\n autoCorrect=\"off\"\n spellCheck={false}\n enterKeyHint=\"go\"\n value={query}\n maxLength={200}\n placeholder={placeholder}\n onChange={(event) => setQuery(event.target.value)}\n // The whole menu is the focus context; a ring on the field adds noise.\n style={{ outline: \"none\" }}\n className=\"h-13 min-w-0 flex-1 bg-transparent text-[15px] text-fg outline-hidden placeholder:text-fg-subtle\"\n />\n {searching ? (\n <span\n aria-hidden=\"true\"\n className=\"size-3.5 shrink-0 animate-spin rounded-full border-[1.5px] border-fg-subtle/40 border-t-fg-muted\"\n />\n ) : null}\n </div>\n <div\n ref={listRef}\n id={listId}\n role=\"listbox\"\n aria-label={focusChat ? \"Chat actions\" : pickingWorkspace ? \"Workspaces\" : \"Results\"}\n className=\"min-h-0 flex-1 overflow-y-auto overscroll-contain p-1.5\"\n >\n {items.length === 0 ? (\n <p className=\"px-2.5 py-6 text-center text-sm text-fg-muted\">\n {searching ? \"Searching…\" : \"No matches\"}\n </p>\n ) : (\n groups.map((group) =>\n group.items.length === 0 ? null : (\n <div key={group.label} role=\"group\" aria-label={group.label}>\n {groups.length > 1 || !focusChat ? (\n <div className=\"truncate px-2.5 pt-2 pb-1 text-xs leading-4.5 font-medium text-fg-muted\">\n {group.label}\n </div>\n ) : null}\n {group.items.map((item) => {\n const index = items.indexOf(item);\n const selected = index === activeIndex;\n const Icon = item.icon;\n return (\n <div\n key={item.key}\n id={optionId(item)}\n data-item-key={item.key}\n role=\"option\"\n aria-selected={selected}\n onPointerMove={() => {\n if (!selected) setActive(index);\n }}\n onPointerDown={(event) => event.preventDefault()}\n onClick={(event) =>\n item.run({ newTab: platform === \"mac\" ? event.metaKey : event.ctrlKey })\n }\n className={cn(\n \"relative flex min-h-9 w-full min-w-0 cursor-default items-center gap-2.5 rounded-[10px] px-2.5 py-1.5 text-sm text-fg-label select-none pointer-coarse:min-h-11\",\n selected ? \"bg-hover text-fg\" : null,\n )}\n >\n {item.tile ? (\n <span\n aria-hidden=\"true\"\n className=\"flex size-4 shrink-0 items-center justify-center rounded-[4px] bg-surface-3 text-2xs font-semibold text-fg-muted\"\n >\n {item.tile}\n </span>\n ) : (\n <Icon\n aria-hidden=\"true\"\n className={cn(\n \"size-4 shrink-0\",\n selected ? \"text-fg\" : \"text-fg-muted\",\n )}\n />\n )}\n <span className=\"min-w-0 flex-1 truncate\">\n <Highlighted text={item.title} query={item.highlight} />\n </span>\n {item.workspaceTag ? <WorkspaceTag name={item.workspaceTag} /> : null}\n <ChatStatusMarks status={item.status ?? null} />\n {item.meta ? (\n <span className=\"shrink-0 text-xs text-fg-muted tabular-nums\">\n {item.meta}\n </span>\n ) : null}\n {item.chord ? (\n // Touch screens have no keys to press.\n <Keycaps\n chord={item.chord}\n platform={platform}\n className=\"pointer-coarse:hidden\"\n />\n ) : null}\n </div>\n );\n })}\n </div>\n ),\n )\n )}\n </div>\n <div className=\"hidden shrink-0 items-center gap-4 border-t border-border px-4 py-2 text-xs text-fg-muted pointer-fine:flex\">\n <FooterHint\n keys={[{ code: \"ArrowUp\" }, { code: \"ArrowDown\" }]}\n label=\"Move\"\n platform={platform}\n />\n <FooterHint\n keys={[{ code: \"Enter\" }]}\n label={pickingWorkspace ? \"Switch\" : \"Open\"}\n platform={platform}\n />\n {focusChat || pickingWorkspace ? (\n <FooterHint keys={[{ code: \"Escape\" }]} label=\"Back\" platform={platform} />\n ) : (\n <FooterHint keys={[{ code: \"Tab\" }]} label=\"Chat actions\" platform={platform} />\n )}\n {surface === \"web\" && !focusChat && !pickingWorkspace ? (\n <FooterHint\n keys={[{ code: \"Enter\", mod: true }]}\n label=\"New tab\"\n platform={platform}\n />\n ) : null}\n <span className=\"ml-auto inline-flex items-center gap-1.5\">\n <Keycaps chord={{ code: \"Slash\", mod: true }} platform={platform} />\n All shortcuts\n </span>\n </div>\n </DialogPrimitive.Content>\n </DialogPortal>\n </DialogPrimitive.Root>\n );\n}\n\nfunction FooterHint(props: { keys: Chord[]; label: string; platform: ActionEnv[\"platform\"] }) {\n return (\n <span className=\"inline-flex items-center gap-1.5\">\n <span className=\"inline-flex items-center gap-0.5\">\n {props.keys.map((chord) => (\n <Keycaps key={chord.code} chord={chord} platform={props.platform} />\n ))}\n </span>\n {props.label}\n </span>\n );\n}\n\n/** Enough of a chat row to copy its link when only a recent-chats record is known. */\nfunction pseudoRow(record: ChatRecord): SessionListRow {\n return { id: record.id, workspaceId: record.workspaceId } as SessionListRow;\n}\n"],"mappings":"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","names":["trimmed","scored","items","result"]}
1
+ {"version":3,"sources":["../../../../src/app/components/command-menu/command-menu.tsx"],"sourcesContent":["/**\n * The ⌘K menu: find a chat by its title, or run any action, from one field.\n *\n * It opens instantly from what the app already knows (chats the sidebar has\n * loaded and the chats opened recently) and merges the server's title search as\n * it arrives. Chats in the person's other workspaces show too, tagged with\n * their workspace, and so do workspaces to switch to. Tab on a chat shows that\n * chat's actions; the chords of chat actions work on the highlighted chat\n * while the menu is open.\n */\nimport {\n useCallback,\n useEffect,\n useId,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type KeyboardEvent as ReactKeyboardEvent,\n type ReactNode,\n type RefObject,\n} from \"react\";\nimport { Dialog as DialogPrimitive } from \"radix-ui\";\nimport {\n ArchiveIcon,\n ArrowUpRightIcon,\n ChevronRightIcon,\n CornerDownLeftIcon,\n LockIcon,\n MessageSquareIcon,\n PinIcon,\n SearchIcon,\n TextSearchIcon,\n type LucideIcon,\n} from \"lucide-react\";\nimport type { SessionListRow } from \"../../../session-list-model\";\nimport { useAppContext } from \"../../app-context\";\nimport {\n readChatDirectory,\n rememberChats,\n useChatDirectoryVersion,\n type ChatRecord,\n} from \"../../lib/actions/chat-directory\";\nimport { matchesChord, type Chord } from \"../../lib/actions/chords\";\nimport { useAppActions } from \"../../lib/actions/actions-provider\";\nimport {\n foldForSearch,\n LOOSE_MATCH_BELOW,\n rankLabel,\n rankWithKeywords,\n} from \"../../lib/actions/rank\";\nimport {\n appActions,\n actionIcon,\n actionTitle,\n type ActionEnv,\n type AppAction,\n type WorkspaceChoice,\n} from \"../../lib/actions/registry\";\nimport { cn } from \"../../lib/utils\";\nimport { DialogOverlay, DialogPortal } from \"../../../ui/dialog\";\nimport { formatRelativeTime } from \"../../../ui/relative-time\";\nimport { Keycaps } from \"./keycaps\";\nimport { WorkspaceTag } from \"./workspace-tag\";\nimport { ChatStatusMarks, useChatStatusRefresh } from \"./chat-status\";\nimport { currentChatStatus, type ChatStatus } from \"../../lib/actions/chat-status\";\n\ntype Item = {\n key: string;\n group: string;\n icon: LucideIcon;\n /** A workspace's initial, drawn as the workspace picker draws it, instead of the icon. */\n tile?: string | undefined;\n title: string;\n /** Text to mark as matched in the title. */\n highlight?: string | undefined;\n /** Quiet text on the right (when, \"Archived\"). */\n meta?: string | undefined;\n /** The workspace a chat lives in, when it is not the one on screen. */\n workspaceTag?: string | undefined;\n chord?: Chord | undefined;\n /** Present on chat rows: Tab opens their actions, chat chords act on them. */\n chat?: ChatRecord | undefined;\n /** The chat's sidebar status marks, while its status is known to be current. */\n status?: ChatStatus | null | undefined;\n run(options: { newTab: boolean }): void;\n};\n\ntype Group = { label: string; items: Item[]; best: number };\n\nconst RECENT_LIMIT = 6;\nconst CHAT_RESULT_LIMIT = 8;\nconst ACTION_RESULT_LIMIT = 6;\nconst WORKSPACE_RESULT_LIMIT = 4;\nconst SERVER_DEBOUNCE_MS = 120;\n/** Other workspaces whose titles the server searches too, most used first. */\nconst OTHER_WORKSPACES_SEARCHED = 9;\n/** A chat in another workspace ranks just below an equal match here. */\nconst ELSEWHERE_PENALTY = 10;\n\nfunction relativeMeta(record: ChatRecord, now: number): string | undefined {\n if (record.archived) return \"Archived\";\n if (!record.updatedAt) return undefined;\n return formatRelativeTime(record.updatedAt, { now });\n}\n\nfunction chatIcon(record: ChatRecord): LucideIcon {\n if (record.archived) return ArchiveIcon;\n if (record.pinned) return PinIcon;\n return MessageSquareIcon;\n}\n\n/** Rows the menu may list: top-level chats only (subagent chats live under their parent). */\nfunction listable(record: ChatRecord): boolean {\n return !record.row || record.row.parentSessionId === null;\n}\n\n/** Marks the query's words in a title, case- and accent-insensitively. */\nfunction Highlighted(props: { text: string; query: string | undefined }) {\n const { text, query } = props;\n const words = query ? foldForSearch(query).split(\" \").filter(Boolean) : [];\n if (words.length === 0) return <>{text}</>;\n // Fold per character so positions in the folded text map back to the title.\n const folded = Array.from(text, (character) => foldForSearch(character) || \" \");\n const joined = folded.join(\"\");\n const marked = new Array<boolean>(folded.length).fill(false);\n const offsets: number[] = [];\n let offset = 0;\n for (const piece of folded) {\n offsets.push(offset);\n offset += piece.length;\n }\n const indexAt = (position: number) => {\n let index = offsets.findIndex((start) => start > position);\n index = index < 0 ? offsets.length - 1 : index - 1;\n return index;\n };\n const phrase = words.join(\" \");\n const ranges: Array<[number, number]> = [];\n const whole = joined.indexOf(phrase);\n if (whole >= 0) ranges.push([whole, whole + phrase.length]);\n else {\n for (const word of words) {\n const at = joined.indexOf(word);\n if (at >= 0) ranges.push([at, at + word.length]);\n }\n }\n for (const [start, end] of ranges) {\n for (let index = indexAt(start); index <= indexAt(end - 1); index++) marked[index] = true;\n }\n const characters = Array.from(text);\n const parts: ReactNode[] = [];\n let run = \"\";\n let runMarked = false;\n characters.forEach((character, index) => {\n const isMarked = marked[index] ?? false;\n if (index > 0 && isMarked !== runMarked) {\n parts.push(\n runMarked ? (\n <mark key={parts.length} className=\"bg-transparent font-medium text-fg\">\n {run}\n </mark>\n ) : (\n run\n ),\n );\n run = \"\";\n }\n run += character;\n runMarked = isMarked;\n });\n if (run) {\n parts.push(\n runMarked ? (\n <mark key={parts.length} className=\"bg-transparent font-medium text-fg\">\n {run}\n </mark>\n ) : (\n run\n ),\n );\n }\n return <>{parts}</>;\n}\n\n/**\n * The server's title search: this workspace, and the person's other workspaces\n * they use most, side by side. Each workspace's matches join the list as they\n * arrive.\n */\nfunction useServerTitleSearch(\n workspaceIds: readonly string[],\n subjectId: string,\n query: string,\n open: boolean,\n) {\n const { client } = useAppContext();\n const [state, setState] = useState<{ query: string; rows: SessionListRow[]; loading: boolean }>({\n query: \"\",\n rows: [],\n loading: false,\n });\n const searchKey = workspaceIds.join(\",\");\n useEffect(() => {\n const trimmed = query.trim();\n if (!open || !trimmed || !searchKey) {\n setState({ query: \"\", rows: [], loading: false });\n return;\n }\n setState((current) => ({ ...current, loading: true }));\n const controller = new AbortController();\n const timer = window.setTimeout(() => {\n const targets = searchKey.split(\",\");\n let pending = targets.length;\n let first = true;\n const settle = (rows: SessionListRow[]) => {\n if (controller.signal.aborted) return;\n pending -= 1;\n const replace = first;\n first = false;\n setState((current) => ({\n query: trimmed,\n rows: replace || current.query !== trimmed ? rows : [...current.rows, ...rows],\n loading: pending > 0,\n }));\n };\n targets.forEach((workspaceId, index) => {\n client\n .listSessionPage(workspaceId, {\n search: trimmed,\n archiveStatus: \"all\",\n // This workspace first and fullest; a few from each of the others.\n limit: index === 0 ? 20 : 6,\n signal: controller.signal,\n })\n .then((page) => {\n const rows = [...(page.pinned ?? []), ...page.sessions];\n rememberChats(subjectId, rows);\n settle(rows);\n })\n .catch(() => {\n // Local results still show; the server search is an addition.\n settle([]);\n });\n });\n }, SERVER_DEBOUNCE_MS);\n return () => {\n window.clearTimeout(timer);\n controller.abort();\n };\n }, [client, searchKey, subjectId, query, open]);\n return state;\n}\n\nexport default function CommandMenu(props: {\n open: boolean;\n /** Opens listing workspaces to switch to. */\n pickWorkspace: boolean;\n onOpenChange: (open: boolean) => void;\n /** Where focus goes back to after a plain close. */\n returnFocus: RefObject<HTMLElement | null>;\n}) {\n const actions = useAppActions();\n if (!actions) return null;\n return (\n <CommandMenuDialog\n {...props}\n env={actions.env}\n run={actions.run}\n chordsFor={actions.chordsFor}\n />\n );\n}\n\nfunction CommandMenuDialog(props: {\n open: boolean;\n pickWorkspace: boolean;\n onOpenChange: (open: boolean) => void;\n returnFocus: RefObject<HTMLElement | null>;\n env: ActionEnv;\n run(action: AppAction, chat?: SessionListRow | null, chord?: Chord): void;\n chordsFor(action: AppAction): Chord[];\n}) {\n const { env, run, chordsFor, onOpenChange } = props;\n const { workspaceId, subjectId, platform, surface, workspaces } = env;\n const directoryVersion = useChatDirectoryVersion(subjectId);\n const [query, setQuery] = useState(\"\");\n const [focusChat, setFocusChat] = useState<ChatRecord | null>(null);\n const [pickingWorkspace, setPickingWorkspace] = useState(props.pickWorkspace);\n const [active, setActive] = useState(0);\n const inputRef = useRef<HTMLInputElement>(null);\n const listRef = useRef<HTMLDivElement>(null);\n const ranAction = useRef(false);\n /** Runs right after the menu has returned focus (see `AppAction.opensDialog`). */\n const afterClose = useRef<(() => void) | null>(null);\n const listId = useId();\n const workspaceNames = useMemo(\n () => new Map(workspaces.map((workspace) => [workspace.id, workspace.name])),\n [workspaces],\n );\n /** Chats the menu may show: this workspace's, and those of other workspaces still open to the person. */\n const reachable = useCallback(\n (id: string) => id === workspaceId || workspaceNames.has(id),\n [workspaceId, workspaceNames],\n );\n // The server searches this workspace and the other workspaces used most recently.\n const searchWorkspaceIds = useMemo(() => {\n void directoryVersion;\n const directory = readChatDirectory(subjectId, workspaceId);\n const used: string[] = [];\n for (const id of directory.recent) {\n const record = directory.rows.get(id);\n if (record && !used.includes(record.workspaceId)) used.push(record.workspaceId);\n }\n const others = [...used, ...workspaces.map((workspace) => workspace.id)].filter(\n (id, index, all) => id !== workspaceId && reachable(id) && all.indexOf(id) === index,\n );\n return [workspaceId, ...others.slice(0, OTHER_WORKSPACES_SEARCHED)];\n // Which workspaces to search changes only when the menu opens.\n }, [props.open, subjectId, workspaceId, workspaces, reachable]); // eslint-disable-line react-hooks/exhaustive-deps\n const server = useServerTitleSearch(\n searchWorkspaceIds,\n subjectId,\n focusChat || pickingWorkspace ? \"\" : query,\n props.open,\n );\n\n // Every open starts fresh.\n useEffect(() => {\n if (!props.open) return;\n setQuery(\"\");\n setFocusChat(null);\n setPickingWorkspace(props.pickWorkspace);\n setActive(0);\n ranAction.current = false;\n afterClose.current = null;\n }, [props.open, props.pickWorkspace]);\n\n const close = useCallback(() => onOpenChange(false), [onOpenChange]);\n\n const runAction = useCallback(\n (action: AppAction, chat: SessionListRow | null, chord?: Chord) => {\n if (action.opensDialog) {\n afterClose.current = () => run(action, action.forChat ? chat : undefined, chord);\n close();\n return;\n }\n ranAction.current = true;\n close();\n run(action, action.forChat ? chat : undefined, chord);\n },\n [close, run],\n );\n\n const openChat = useCallback(\n (record: ChatRecord, newTab: boolean) => {\n ranAction.current = true;\n close();\n if (newTab && surface === \"web\") {\n window.open(env.ops.linkTo(record), \"_blank\", \"noopener\");\n return;\n }\n env.openChat(record.id, record.workspaceId);\n },\n [close, env, surface],\n );\n\n const openWorkspace = useCallback(\n (id: string) => {\n ranAction.current = true;\n close();\n if (id !== workspaceId) env.openWorkspace(id);\n },\n [close, env, workspaceId],\n );\n\n const startPickingWorkspace = useCallback(() => {\n setFocusChat(null);\n setPickingWorkspace(true);\n setQuery(\"\");\n inputRef.current?.focus();\n }, []);\n\n const actionItem = useCallback(\n (action: AppAction, chat: SessionListRow | null, group: string, highlight?: string): Item => ({\n key: `action:${action.id}`,\n group,\n icon: actionIcon(action, chat),\n title: actionTitle(action, env, chat),\n highlight,\n chord: chordsFor(action)[0],\n // Switching workspace lists the workspaces right here.\n run: () =>\n action.id === \"go.switchWorkspace\" ? startPickingWorkspace() : runAction(action, chat),\n }),\n [chordsFor, env, runAction, startPickingWorkspace],\n );\n\n const groups = useMemo<Group[]>(() => {\n void directoryVersion;\n const now = Date.now();\n const directory = readChatDirectory(subjectId, workspaceId);\n const current = env.currentChat;\n const sidebarIds = new Set([...directory.sidebarOrder, ...directory.pinnedOrder]);\n\n const chatItem = (record: ChatRecord, group: string, highlight?: string): Item => ({\n key: `chat:${record.id}`,\n group,\n icon: chatIcon(record),\n title: record.title,\n highlight,\n meta: current?.id === record.id ? \"Open now\" : relativeMeta(record, now),\n workspaceTag:\n record.workspaceId === workspaceId ? undefined : workspaceNames.get(record.workspaceId),\n chat: record,\n status: currentChatStatus(record, sidebarIds, now),\n run: ({ newTab }) => openChat(record, newTab),\n });\n\n const workspaceItem = (choice: WorkspaceChoice, group: string, highlight?: string): Item => ({\n key: `workspace:${choice.id}`,\n group,\n icon: LockIcon,\n // A Personal workspace shows its lock, as in the workspace picker.\n tile: choice.personal ? undefined : (choice.name.trim()[0] ?? \"W\").toUpperCase(),\n title: choice.name,\n highlight,\n meta: choice.id === workspaceId ? \"Current\" : undefined,\n run: () => openWorkspace(choice.id),\n });\n\n // Workspaces to switch to, by organization.\n if (pickingWorkspace) {\n const trimmed = query.trim();\n const organizations = new Set(workspaces.map((choice) => choice.organization));\n const scored = workspaces.flatMap((choice) => {\n if (!trimmed) return [{ choice, rank: 0 }];\n const rank =\n rankLabel(choice.name, trimmed) ??\n (organizations.size > 1 ? rankLabel(choice.organization, trimmed) : null);\n return rank === null ? [] : [{ choice, rank }];\n });\n const realMatch = scored.some((entry) => entry.rank >= LOOSE_MATCH_BELOW);\n const kept = scored.filter(\n (entry) => !trimmed || !realMatch || entry.rank >= LOOSE_MATCH_BELOW,\n );\n if (trimmed) {\n kept.sort((a, b) => b.rank - a.rank);\n return [\n {\n label: \"Workspaces\",\n items: kept.map((entry) => workspaceItem(entry.choice, \"Workspaces\", trimmed)),\n best: 0,\n },\n ];\n }\n const byOrganization = new Map<string, Item[]>();\n for (const { choice } of kept) {\n const label = organizations.size > 1 ? choice.organization : \"Workspaces\";\n const list = byOrganization.get(label) ?? [];\n list.push(workspaceItem(choice, label));\n byOrganization.set(label, list);\n }\n return [...byOrganization].map(([label, items]) => ({ label, items, best: 0 }));\n }\n\n // A chat's own actions (after Tab).\n if (focusChat) {\n // Chats in other workspaces offer what works from here: open and copy link.\n const sameWorkspace = focusChat.workspaceId === workspaceId;\n const row = sameWorkspace\n ? (focusChat.row ?? (current?.id === focusChat.id ? current : null))\n : null;\n const items: Array<{ item: Item; rank: number }> = [];\n const openRank = rankLabel(\"Open\", query);\n if (openRank !== null) {\n items.push({\n rank: openRank + 1,\n item: {\n key: \"open\",\n group: focusChat.title,\n icon: CornerDownLeftIcon,\n title: \"Open\",\n highlight: query,\n run: () => openChat(focusChat, false),\n },\n });\n }\n if (surface === \"web\") {\n const tabRank = rankLabel(\"Open in new tab\", query);\n if (tabRank !== null) {\n items.push({\n rank: tabRank,\n item: {\n key: \"open-tab\",\n group: focusChat.title,\n icon: ArrowUpRightIcon,\n title: \"Open in new tab\",\n highlight: query,\n run: () => openChat(focusChat, true),\n },\n });\n }\n }\n for (const action of appActions()) {\n if (!action.forChat || action.inCommandMenu === false) continue;\n // Copy link needs only the id; the rest need the chat's row.\n const target = row ?? (action.id === \"chat.copyLink\" ? pseudoRow(focusChat) : null);\n if (!target || !action.available(env, target)) continue;\n const rank = rankWithKeywords(actionTitle(action, env, target), action.keywords, query);\n if (rank === null) continue;\n items.push({ rank, item: actionItem(action, target, focusChat.title, query) });\n }\n if (query) items.sort((a, b) => b.rank - a.rank);\n return [{ label: focusChat.title, items: items.map((entry) => entry.item), best: 0 }];\n }\n\n const trimmed = query.trim();\n if (!trimmed) {\n const result: Group[] = [];\n // Chats opened recently come first; the top of the sidebar fills the\n // rest, so a fresh window still offers somewhere to go.\n const recentIds = [...new Set([...directory.recent, ...directory.sidebarOrder])].filter(\n (id) => id !== current?.id,\n );\n const recent = recentIds\n .map((id) => directory.rows.get(id))\n .filter((record): record is ChatRecord =>\n Boolean(record && listable(record) && !record.archived && reachable(record.workspaceId)),\n )\n .slice(0, RECENT_LIMIT);\n if (recent.length > 0) {\n result.push({\n label: \"Recent chats\",\n items: recent.map((record) => chatItem(record, \"Recent chats\")),\n best: 0,\n });\n }\n if (current) {\n const chatActions = appActions().filter(\n (action) =>\n action.forChat &&\n action.inCommandMenu !== false &&\n action.id !== \"chat.find\" &&\n action.available(env, current),\n );\n if (chatActions.length > 0) {\n result.push({\n label: \"This chat\",\n items: chatActions.map((action) => actionItem(action, current, \"This chat\")),\n best: 0,\n });\n }\n }\n const general = appActions().filter(\n (action) =>\n !action.forChat &&\n action.inCommandMenu !== false &&\n action.id !== \"commandMenu.open\" &&\n action.available(env, null),\n );\n if (general.length > 0) {\n result.push({\n label: \"Go to\",\n items: general.map((action) => actionItem(action, null, \"Go to\")),\n best: 0,\n });\n }\n return result;\n }\n\n // Chats: everything the app knows, ranked by title, plus the server's matches.\n const recentIndex = new Map(directory.recent.map((id, index) => [id, index]));\n const serverIds = new Set(server.query === trimmed ? server.rows.map((row) => row.id) : []);\n const scored: Array<{ record: ChatRecord; rank: number; loose: boolean }> = [];\n for (const record of directory.rows.values()) {\n if (!listable(record) || !reachable(record.workspaceId)) continue;\n let rank = rankLabel(record.title, trimmed);\n const loose = rank !== null && rank < LOOSE_MATCH_BELOW;\n // The server matched every word in the title or first message.\n if (rank === null && serverIds.has(record.id)) rank = 50;\n if (rank === null) continue;\n const visited = recentIndex.get(record.id);\n if (visited !== undefined) rank += Math.max(0, 20 - visited);\n if (record.pinned) rank += 5;\n if (record.archived) rank -= 300;\n if (record.workspaceId !== workspaceId) rank -= ELSEWHERE_PENALTY;\n scored.push({ record, rank, loose });\n }\n\n const actionScores: Array<{ item: Item; rank: number; loose: boolean }> = [];\n for (const action of appActions()) {\n if (action.inCommandMenu === false) continue;\n const target = action.forChat ? current : null;\n if (action.forChat && !target) continue;\n if (!action.available(env, target)) continue;\n const rank = rankWithKeywords(actionTitle(action, env, target), action.keywords, trimmed);\n if (rank === null) continue;\n actionScores.push({\n rank,\n loose: rank < LOOSE_MATCH_BELOW,\n item: actionItem(action, target, \"Actions\", trimmed),\n });\n }\n const workspaceScores: Array<{ item: Item; rank: number; loose: boolean }> = [];\n for (const choice of workspaces) {\n if (choice.id === workspaceId) continue;\n const rank = rankLabel(choice.name, trimmed);\n if (rank === null) continue;\n workspaceScores.push({\n rank,\n loose: rank < LOOSE_MATCH_BELOW,\n item: workspaceItem(choice, \"Workspaces\", trimmed),\n });\n }\n // Letters-in-order guesses only help when nothing really matches; next to\n // real matches they are noise (\"pin\" → \"Postgres … investigation\").\n const hasRealMatch =\n scored.some((entry) => !entry.loose) ||\n actionScores.some((entry) => !entry.loose) ||\n workspaceScores.some((entry) => !entry.loose);\n const chats = scored\n .filter((entry) => !hasRealMatch || !entry.loose)\n .sort((a, b) => b.rank - a.rank || b.record.updatedAt - a.record.updatedAt)\n .slice(0, CHAT_RESULT_LIMIT);\n const actionsFound = actionScores\n .filter((entry) => !hasRealMatch || !entry.loose)\n .sort((a, b) => b.rank - a.rank)\n .slice(0, ACTION_RESULT_LIMIT);\n const workspacesFound = workspaceScores\n .filter((entry) => !hasRealMatch || !entry.loose)\n .sort((a, b) => b.rank - a.rank)\n .slice(0, WORKSPACE_RESULT_LIMIT);\n\n const result: Group[] = [];\n if (chats.length > 0) {\n result.push({\n label: \"Chats\",\n items: chats.map((entry) => chatItem(entry.record, \"Chats\", trimmed)),\n best: chats[0]!.rank,\n });\n }\n if (actionsFound.length > 0) {\n result.push({\n label: \"Actions\",\n items: actionsFound.map((entry) => entry.item),\n best: actionsFound[0]!.rank,\n });\n }\n if (workspacesFound.length > 0) {\n result.push({\n label: \"Workspaces\",\n items: workspacesFound.map((entry) => entry.item),\n // Chats and actions first on a tie: a workspace is a bigger jump.\n best: workspacesFound[0]!.rank - 1,\n });\n }\n // A clearly better action match (\"new\" → New chat) comes before chats.\n result.sort((a, b) => b.best - a.best);\n result.push({\n label: \"Messages\",\n best: -Infinity,\n items: [\n {\n key: \"search-messages\",\n group: \"Messages\",\n icon: TextSearchIcon,\n title: `Search messages for “${trimmed}”`,\n run: () => {\n afterClose.current = () => env.searchMessages(trimmed);\n close();\n },\n },\n ],\n });\n return result;\n }, [\n actionItem,\n close,\n directoryVersion,\n env,\n focusChat,\n openChat,\n openWorkspace,\n pickingWorkspace,\n query,\n reachable,\n server.query,\n server.rows,\n subjectId,\n surface,\n workspaceId,\n workspaceNames,\n workspaces,\n ]);\n\n const items = useMemo(() => groups.flatMap((group) => group.items), [groups]);\n const listedChatIds = useMemo(\n () => items.flatMap((item) => (item.chat ? [item.chat.id] : [])),\n [items],\n );\n useChatStatusRefresh({ subjectId, workspaceId, ids: listedChatIds, active: props.open });\n const activeIndex = items.length === 0 ? -1 : Math.min(active, items.length - 1);\n const activeItem = activeIndex >= 0 ? items[activeIndex] : undefined;\n const searching = Boolean(query.trim()) && !focusChat && !pickingWorkspace && server.loading;\n\n // Typing starts at the best match; the workspace list starts at the current workspace's neighbour.\n useEffect(() => {\n if (pickingWorkspace && !query) {\n const index = workspaces.findIndex((choice) => choice.id === workspaceId);\n setActive(index >= 0 && workspaces.length > 1 ? (index + 1) % workspaces.length : 0);\n return;\n }\n setActive(0);\n }, [query, focusChat, pickingWorkspace, workspaces, workspaceId]);\n\n // Keep the highlighted row in view without scrolling the page.\n useLayoutEffect(() => {\n if (!activeItem) return;\n const element = listRef.current?.querySelector<HTMLElement>(\n `[data-item-key=\"${CSS.escape(activeItem.key)}\"]`,\n );\n element?.scrollIntoView({ block: \"nearest\" });\n }, [activeItem]);\n\n const enterChat = useCallback((record: ChatRecord) => {\n setFocusChat(record);\n setQuery(\"\");\n inputRef.current?.focus();\n }, []);\n const leaveChat = useCallback(() => {\n setFocusChat(null);\n setPickingWorkspace(false);\n setQuery(\"\");\n }, []);\n\n const onKeyDown = useCallback(\n (event: ReactKeyboardEvent<HTMLDivElement>) => {\n if (event.nativeEvent.isComposing) return;\n const count = items.length;\n const mod = platform === \"mac\" ? event.metaKey : event.ctrlKey;\n switch (event.key) {\n case \"ArrowDown\":\n case \"ArrowUp\": {\n if (event.altKey || mod) break;\n event.preventDefault();\n if (count === 0) return;\n const step = event.key === \"ArrowDown\" ? 1 : -1;\n setActive((current) => (Math.min(current, count - 1) + step + count) % count);\n return;\n }\n case \"PageDown\":\n case \"PageUp\": {\n event.preventDefault();\n if (count === 0) return;\n const step = event.key === \"PageDown\" ? 5 : -5;\n setActive((current) => Math.max(0, Math.min(count - 1, current + step)));\n return;\n }\n case \"Home\":\n case \"End\": {\n // Inside the field these move the caret, unless the field is empty.\n if (query) break;\n event.preventDefault();\n setActive(event.key === \"Home\" ? 0 : Math.max(0, count - 1));\n return;\n }\n case \"Enter\": {\n event.preventDefault();\n activeItem?.run({ newTab: mod });\n return;\n }\n case \"Tab\": {\n event.preventDefault();\n if (event.shiftKey) {\n if (focusChat || pickingWorkspace) leaveChat();\n return;\n }\n if (!focusChat && activeItem?.chat) enterChat(activeItem.chat);\n return;\n }\n case \"Backspace\": {\n if ((focusChat || pickingWorkspace) && !query) {\n event.preventDefault();\n leaveChat();\n }\n return;\n }\n default:\n break;\n }\n // A chat action's chord acts on the highlighted chat, as in Linear.\n const chatRecord = focusChat ?? activeItem?.chat;\n if (!chatRecord) return;\n const sameWorkspace = chatRecord.workspaceId === workspaceId;\n for (const action of appActions()) {\n if (!action.forChat) continue;\n const chord = chordsFor(action).find((candidate) =>\n matchesChord(event.nativeEvent, candidate, platform),\n );\n if (!chord) continue;\n const row =\n (sameWorkspace\n ? (chatRecord.row ?? (env.currentChat?.id === chatRecord.id ? env.currentChat : null))\n : null) ?? (action.id === \"chat.copyLink\" ? pseudoRow(chatRecord) : null);\n event.preventDefault();\n event.stopPropagation();\n if (row && action.available(env, row)) runAction(action, row, chord);\n return;\n }\n },\n [\n activeItem,\n chordsFor,\n enterChat,\n env,\n focusChat,\n items.length,\n leaveChat,\n pickingWorkspace,\n platform,\n query,\n runAction,\n workspaceId,\n ],\n );\n\n const placeholder = focusChat\n ? \"Search actions…\"\n : pickingWorkspace\n ? \"Switch to workspace…\"\n : \"Search chats or run an action…\";\n const optionId = (item: Item) => `${listId}-${item.key.replace(/[^a-zA-Z0-9_-]/g, \"_\")}`;\n\n return (\n <DialogPrimitive.Root open={props.open} onOpenChange={onOpenChange}>\n <DialogPortal>\n <DialogOverlay className=\"bg-black/25 dark:bg-black/45\" />\n <DialogPrimitive.Content\n data-og-command-menu=\"\"\n aria-label=\"Command menu\"\n aria-describedby={undefined}\n onOpenAutoFocus={(event) => {\n event.preventDefault();\n inputRef.current?.focus();\n }}\n onCloseAutoFocus={(event) => {\n // An action moves focus where it belongs (the new chat's composer,\n // the title being renamed); only a plain close returns focus.\n if (ranAction.current) {\n event.preventDefault();\n return;\n }\n const target = props.returnFocus.current;\n if (target?.isConnected) {\n event.preventDefault();\n target.focus({ preventScroll: true });\n }\n const next = afterClose.current;\n afterClose.current = null;\n next?.();\n }}\n onEscapeKeyDown={(event) => {\n // Esc steps back out of a chat's actions, or the workspace list\n // reached from the menu, before it closes the menu.\n if (!focusChat && !(pickingWorkspace && !props.pickWorkspace)) return;\n event.preventDefault();\n leaveChat();\n }}\n onKeyDown={onKeyDown}\n className={cn(\n \"fixed top-[12dvh] left-1/2 z-50 flex max-h-[min(560px,76dvh)] w-[calc(100vw-1.5rem)] max-w-[640px] -translate-x-1/2 flex-col overflow-hidden\",\n \"rounded-2xl border border-border bg-surface text-fg shadow-og-lg outline-hidden\",\n \"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-98\",\n \"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-98\",\n \"duration-[120ms] max-sm:top-3\",\n )}\n >\n <DialogPrimitive.Title className=\"sr-only\">Command menu</DialogPrimitive.Title>\n <div className=\"flex min-h-13 shrink-0 items-center gap-2.5 border-b border-border px-4\">\n <SearchIcon aria-hidden=\"true\" className=\"size-4 shrink-0 text-fg-muted\" />\n {focusChat ? (\n <button\n type=\"button\"\n onClick={leaveChat}\n title=\"Back to all results\"\n className=\"inline-flex max-w-[45%] shrink-0 items-center gap-1 rounded-full bg-hover py-0.5 pr-1.5 pl-2.5 text-xs font-medium text-fg outline-hidden hover:bg-selection focus-visible:outline-2 focus-visible:outline-ring/55\"\n >\n <span className=\"truncate\">{focusChat.title}</span>\n <ChevronRightIcon aria-hidden=\"true\" className=\"size-3.5 text-fg-muted\" />\n </button>\n ) : pickingWorkspace ? (\n <button\n type=\"button\"\n onClick={leaveChat}\n title=\"Back to all results\"\n className=\"inline-flex shrink-0 items-center gap-1 rounded-full bg-hover py-0.5 pr-1.5 pl-2.5 text-xs font-medium text-fg outline-hidden hover:bg-selection focus-visible:outline-2 focus-visible:outline-ring/55\"\n >\n Workspaces\n <ChevronRightIcon aria-hidden=\"true\" className=\"size-3.5 text-fg-muted\" />\n </button>\n ) : null}\n <input\n ref={inputRef}\n role=\"combobox\"\n aria-expanded=\"true\"\n aria-controls={listId}\n aria-autocomplete=\"list\"\n aria-activedescendant={activeItem ? optionId(activeItem) : undefined}\n aria-label={\n focusChat\n ? `Actions for ${focusChat.title}`\n : pickingWorkspace\n ? \"Search workspaces\"\n : \"Search chats and actions\"\n }\n autoComplete=\"off\"\n autoCorrect=\"off\"\n spellCheck={false}\n enterKeyHint=\"go\"\n value={query}\n maxLength={200}\n placeholder={placeholder}\n onChange={(event) => setQuery(event.target.value)}\n // The whole menu is the focus context; a ring on the field adds noise.\n style={{ outline: \"none\" }}\n className=\"h-13 min-w-0 flex-1 bg-transparent text-[15px] text-fg outline-hidden placeholder:text-fg-subtle\"\n />\n {searching ? (\n <span\n aria-hidden=\"true\"\n className=\"size-3.5 shrink-0 animate-spin rounded-full border-[1.5px] border-fg-subtle/40 border-t-fg-muted\"\n />\n ) : null}\n </div>\n <div\n ref={listRef}\n id={listId}\n role=\"listbox\"\n aria-label={focusChat ? \"Chat actions\" : pickingWorkspace ? \"Workspaces\" : \"Results\"}\n className=\"min-h-0 flex-1 overflow-y-auto overscroll-contain p-1.5\"\n >\n {items.length === 0 ? (\n <p className=\"px-2.5 py-6 text-center text-sm text-fg-muted\">\n {searching ? \"Searching…\" : \"No matches\"}\n </p>\n ) : (\n groups.map((group) =>\n group.items.length === 0 ? null : (\n <div key={group.label} role=\"group\" aria-label={group.label}>\n {groups.length > 1 || !focusChat ? (\n <div className=\"truncate px-2.5 pt-2 pb-1 text-xs leading-4.5 font-medium text-fg-muted\">\n {group.label}\n </div>\n ) : null}\n {group.items.map((item) => {\n const index = items.indexOf(item);\n const selected = index === activeIndex;\n const Icon = item.icon;\n return (\n <div\n key={item.key}\n id={optionId(item)}\n data-item-key={item.key}\n role=\"option\"\n aria-selected={selected}\n onPointerMove={() => {\n if (!selected) setActive(index);\n }}\n onPointerDown={(event) => event.preventDefault()}\n onClick={(event) =>\n item.run({ newTab: platform === \"mac\" ? event.metaKey : event.ctrlKey })\n }\n className={cn(\n \"relative flex min-h-9 w-full min-w-0 cursor-default items-center gap-2.5 rounded-[10px] px-2.5 py-1.5 text-sm text-fg-label select-none pointer-coarse:min-h-11\",\n selected ? \"bg-hover text-fg\" : null,\n )}\n >\n {item.tile ? (\n <span\n aria-hidden=\"true\"\n className=\"flex size-4 shrink-0 items-center justify-center rounded-[4px] bg-surface-3 text-2xs font-semibold text-fg-muted\"\n >\n {item.tile}\n </span>\n ) : (\n <Icon\n aria-hidden=\"true\"\n className={cn(\n \"size-4 shrink-0\",\n selected ? \"text-fg\" : \"text-fg-muted\",\n )}\n />\n )}\n <span className=\"min-w-0 flex-1 truncate\">\n <Highlighted text={item.title} query={item.highlight} />\n </span>\n {item.workspaceTag ? <WorkspaceTag name={item.workspaceTag} /> : null}\n <ChatStatusMarks status={item.status ?? null} />\n {item.meta ? (\n <span className=\"shrink-0 text-xs text-fg-muted tabular-nums\">\n {item.meta}\n </span>\n ) : null}\n {item.chord ? (\n // Touch screens have no keys to press.\n <Keycaps\n chord={item.chord}\n platform={platform}\n className=\"pointer-coarse:hidden\"\n />\n ) : null}\n </div>\n );\n })}\n </div>\n ),\n )\n )}\n </div>\n <div className=\"hidden shrink-0 items-center gap-4 border-t border-border px-4 py-2 text-xs text-fg-muted pointer-fine:flex\">\n <FooterHint\n keys={[{ code: \"ArrowUp\" }, { code: \"ArrowDown\" }]}\n label=\"Move\"\n platform={platform}\n />\n <FooterHint\n keys={[{ code: \"Enter\" }]}\n label={pickingWorkspace ? \"Switch\" : \"Open\"}\n platform={platform}\n />\n {focusChat || pickingWorkspace ? (\n <FooterHint keys={[{ code: \"Escape\" }]} label=\"Back\" platform={platform} />\n ) : (\n <FooterHint keys={[{ code: \"Tab\" }]} label=\"Chat actions\" platform={platform} />\n )}\n {surface === \"web\" && !focusChat && !pickingWorkspace ? (\n <FooterHint\n keys={[{ code: \"Enter\", mod: true }]}\n label=\"New tab\"\n platform={platform}\n />\n ) : null}\n <span className=\"ml-auto inline-flex items-center gap-1.5\">\n <Keycaps chord={{ code: \"Slash\", mod: true }} platform={platform} />\n All shortcuts\n </span>\n </div>\n </DialogPrimitive.Content>\n </DialogPortal>\n </DialogPrimitive.Root>\n );\n}\n\nfunction FooterHint(props: { keys: Chord[]; label: string; platform: ActionEnv[\"platform\"] }) {\n return (\n <span className=\"inline-flex items-center gap-1.5\">\n <span className=\"inline-flex items-center gap-0.5\">\n {props.keys.map((chord) => (\n <Keycaps key={chord.code} chord={chord} platform={props.platform} />\n ))}\n </span>\n {props.label}\n </span>\n );\n}\n\n/** Enough of a chat row to copy its link when only a recent-chats record is known. */\nfunction pseudoRow(record: ChatRecord): SessionListRow {\n return { id: record.id, workspaceId: record.workspaceId } as SessionListRow;\n}\n"],"mappings":"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","names":["trimmed","scored","items","result"]}
@@ -1,12 +1,12 @@
1
1
  "use client";
2
- import {
3
- Keycaps
4
- } from "../../../chunk-OHGG2G3A.js";
5
2
  import {
6
3
  appActions,
7
4
  findAction,
8
5
  useAppActions
9
- } from "../../../chunk-TR4HIKJ2.js";
6
+ } from "../../../chunk-OHG2UQ2O.js";
7
+ import {
8
+ Keycaps
9
+ } from "../../../chunk-OHGG2G3A.js";
10
10
  import {
11
11
  applicableChords,
12
12
  chordLabel
@@ -14,14 +14,14 @@ import {
14
14
  import "../../../chunk-NML44AW2.js";
15
15
  import "../../../chunk-O5S57N6H.js";
16
16
  import "../../../chunk-OSI2QWSL.js";
17
- import "../../../chunk-VO6RVVP7.js";
17
+ import "../../../chunk-6VITVQ23.js";
18
18
  import "../../../chunk-MMY23KS7.js";
19
19
  import "../../../chunk-TXIIBNCA.js";
20
20
  import "../../../chunk-3RWVKGQM.js";
21
21
  import "../../../chunk-XXZKL5UI.js";
22
22
  import "../../../chunk-7ZEGSUR7.js";
23
- import "../../../chunk-HQA6FUM5.js";
24
23
  import "../../../chunk-WGPLDFEC.js";
24
+ import "../../../chunk-HQA6FUM5.js";
25
25
  import "../../../chunk-H5M33DAL.js";
26
26
  import "../../../chunk-FABYS4WM.js";
27
27
  import "../../../chunk-A3MTTRCX.js";
@@ -32,7 +32,7 @@ import {
32
32
  DialogTitle
33
33
  } from "../../../chunk-HZUL2CUH.js";
34
34
  import "../../../chunk-I7NCHCA7.js";
35
- import "../../../chunk-TJQDL3JH.js";
35
+ import "../../../chunk-BPD4IJBG.js";
36
36
  import "../../../chunk-FIDD34ZF.js";
37
37
  import "../../../chunk-74JEZLLQ.js";
38
38
  import "../../../chunk-YG6NARQY.js";
@@ -47,7 +47,7 @@ import "../../../chunk-NRP4REXE.js";
47
47
  import "../../../chunk-J3BHDXQQ.js";
48
48
  import "../../../chunk-CFEFYPNR.js";
49
49
  import "../../../chunk-TXS65BB2.js";
50
- import "../../../chunk-JFK7NTEA.js";
50
+ import "../../../chunk-S6WJ6TUT.js";
51
51
 
52
52
  // src/app/components/command-menu/shortcut-sheet.tsx
53
53
  import { Fragment } from "react";
@@ -4,9 +4,9 @@ import {
4
4
  } from "../../chunk-OANSIX34.js";
5
5
  import {
6
6
  SessionToolsMenuBody
7
- } from "../../chunk-QLIDZGPV.js";
7
+ } from "../../chunk-HJTTDLF6.js";
8
8
  import "../../chunk-4NTPH5M6.js";
9
- import "../../chunk-IIO2MR3B.js";
9
+ import "../../chunk-M7YEZR6X.js";
10
10
  import "../../chunk-Z63GB7JI.js";
11
11
  import "../../chunk-A3MTTRCX.js";
12
12
  import {
@@ -42,8 +42,8 @@ import {
42
42
  MENU_CHEVRON_CLASS
43
43
  } from "../../chunk-5OTQA7CM.js";
44
44
  import "../../chunk-HMU5IELG.js";
45
- import "../../chunk-WWOHORRO.js";
46
- import "../../chunk-ERG355NM.js";
45
+ import "../../chunk-2K27S6LK.js";
46
+ import "../../chunk-ZWACUOU5.js";
47
47
  import "../../chunk-PNNTR6KP.js";
48
48
  import "../../chunk-WJPMYXKZ.js";
49
49
  import "../../chunk-VYT4POBH.js";
@@ -53,7 +53,7 @@ import "../../chunk-CFEFYPNR.js";
53
53
  import "../../chunk-N7S72EXK.js";
54
54
  import "../../chunk-XEA5BCMA.js";
55
55
  import "../../chunk-TXS65BB2.js";
56
- import "../../chunk-JFK7NTEA.js";
56
+ import "../../chunk-S6WJ6TUT.js";
57
57
 
58
58
  // src/app/components/composer-mobile-plus-panel.tsx
59
59
  import {
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  ComposerMobilePlus
4
- } from "../../chunk-IPPVX5GF.js";
4
+ } from "../../chunk-GTR2WUBA.js";
5
5
  import "../../chunk-O2LGEYG4.js";
6
6
  import "../../chunk-HZUL2CUH.js";
7
7
  import "../../chunk-TREHTIBD.js";
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  CreditRequiredGate
4
- } from "../../chunk-WBPQ7OPC.js";
4
+ } from "../../chunk-XDCZBOEY.js";
5
5
  import "../../chunk-FIDD34ZF.js";
6
6
  import "../../chunk-74JEZLLQ.js";
7
7
  import "../../chunk-NRP4REXE.js";
@@ -1,12 +1,12 @@
1
1
  "use client";
2
- import {
3
- CouponRedeem
4
- } from "../../chunk-UNNJUJVD.js";
5
2
  import {
6
3
  CreditsCelebrationDialog
7
4
  } from "../../chunk-FYJBNHFZ.js";
8
5
  import "../../chunk-U2MMLIOB.js";
9
6
  import "../../chunk-72GBRPJP.js";
7
+ import {
8
+ CouponRedeem
9
+ } from "../../chunk-UNNJUJVD.js";
10
10
  import "../../chunk-5BMOFQIH.js";
11
11
  import {
12
12
  subscriptionAction
@@ -26,7 +26,7 @@ import "../../chunk-55S3W7RZ.js";
26
26
  import "../../chunk-PRJUHXST.js";
27
27
  import {
28
28
  validTopupAmount
29
- } from "../../chunk-5TLEWXAB.js";
29
+ } from "../../chunk-IKQMSROV.js";
30
30
  import "../../chunk-ECNX3UOI.js";
31
31
  import "../../chunk-WMSCYECP.js";
32
32
  import {
@@ -55,12 +55,14 @@ import {
55
55
  import {
56
56
  useAppContext
57
57
  } from "../../chunk-W6KAUGXO.js";
58
+ import "../../chunk-6NXQCOLD.js";
58
59
  import {
59
60
  Notice
60
61
  } from "../../chunk-WLEDGIVS.js";
61
62
  import {
62
63
  Button
63
64
  } from "../../chunk-HMU5IELG.js";
65
+ import "../../chunk-DHXKEJBH.js";
64
66
  import "../../chunk-J3BHDXQQ.js";
65
67
  import "../../chunk-TXS65BB2.js";
66
68
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/app/components/credit-required-prompt.tsx"],"sourcesContent":["import { useCreditExposure } from \"../lib/use-analytics-exposure\";\nimport type { OpenGeniBrowserClient } from \"@opengeni/sdk/browser\";\nimport { Link, usePage } from \"../lib/navigation\";\nimport { CreditCardIcon, Loader2Icon, SparklesIcon } from \"lucide-react\";\nimport type { BillingCheckoutStatus, WorkspaceModelCatalogModel } from \"@opengeni/sdk\";\nimport { useEffect, useState } from \"react\";\nimport { toast } from \"../lib/toast\";\n\nimport { CouponRedeem } from \"./credits/coupon-redeem\";\nimport { CreditsCelebrationDialog } from \"./credits/checkout-credits-celebration\";\n\nimport { Button } from \"../../ui/button\";\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from \"../../ui/dialog\";\nimport { CreditAmountPicker } from \"./credit-amount-picker\";\nimport { Notice } from \"../../ui/notice\";\nimport { useAppContext } from \"../app-context\";\nimport { userErrorText } from \"../../ui/api-error\";\nimport { validTopupAmount } from \"../lib/format\";\nimport { analyticsAction } from \"../../ui/analytics-actions\";\nimport { billingCheckoutReturnUrl, checkoutTabReturnUrl } from \"../lib/credit-checkout\";\nimport { subscriptionAction } from \"../lib/subscription-plans\";\n\nconst DEFAULT_TOPUP = \"25.00\";\n\ntype CreditRequiredPromptProps = {\n open: boolean;\n workspaceId: string;\n accountId: string | null;\n canBuyCredits: boolean;\n purpose?: \"required\" | \"topup\" | undefined;\n onOpenChange: (open: boolean) => void;\n};\n\nexport function CreditRequiredPrompt(props: CreditRequiredPromptProps) {\n return <CreditRequiredPromptView {...props} client={useAppContext().client} />;\n}\n\nexport function CreditRequiredPromptView({\n client,\n open,\n workspaceId,\n accountId,\n canBuyCredits,\n purpose = \"required\",\n onOpenChange,\n}: CreditRequiredPromptProps & { client: OpenGeniBrowserClient }) {\n const page = usePage();\n const [topupAmount, setTopupAmount] = useState(DEFAULT_TOPUP);\n const [busy, setBusy] = useState(false);\n // A redeemed coupon, celebrated in this dialog with its real amount.\n const [granted, setGranted] = useState<BillingCheckoutStatus | null>(null);\n useEffect(() => {\n if (!open) setGranted(null);\n }, [open]);\n const [stripeEnabled, setStripeEnabled] = useState(false);\n const [upgradeAccountId, setUpgradeAccountId] = useState<string | null>(null);\n const canUpgrade = open && canBuyCredits && accountId !== null && upgradeAccountId === accountId;\n\n useEffect(() => {\n setUpgradeAccountId(null);\n if (!open || !accountId || !canBuyCredits) {\n setStripeEnabled(false);\n return;\n }\n let active = true;\n setStripeEnabled(false);\n void client\n .getBilling({ accountId })\n .then(async (billing) => {\n if (active) setStripeEnabled(billing.mode === \"stripe\");\n if (!active || !billing.balance.plan || billing.mode !== \"stripe\") return;\n const catalog = await client.getBillingSubscriptionPlans({ accountId }).catch(() => null);\n if (\n active &&\n catalog?.plan &&\n catalog.plans.some((target) => {\n const action = subscriptionAction(billing.balance.plan!, catalog.plans, target);\n return action === \"checkout\" || action === \"upgrade\";\n })\n )\n setUpgradeAccountId(accountId);\n })\n .catch(() => {\n if (active) setStripeEnabled(false);\n });\n return () => {\n active = false;\n };\n }, [accountId, canBuyCredits, client, open]);\n\n async function buyCredits(): Promise<void> {\n if (!accountId || !validTopupAmount(topupAmount) || busy) return;\n setBusy(true);\n try {\n const session = await client.createBillingCheckout({\n amountUsd: Number(topupAmount),\n accountId,\n // Beside an embed, checkout ends on a page that asks to go back to it.\n successUrl: page.opensBeside\n ? checkoutTabReturnUrl(page.origin(), \"success\")\n : billingCheckoutReturnUrl(page.origin(), workspaceId, \"success\"),\n cancelUrl: page.opensBeside\n ? checkoutTabReturnUrl(page.origin(), \"cancelled\")\n : billingCheckoutReturnUrl(page.origin(), workspaceId, \"cancelled\"),\n });\n page.assign(session.url);\n // The web app has left for checkout; an embed stays and can buy again.\n if (page.opensBeside) setBusy(false);\n } catch (error) {\n toast.error(\"Checkout failed\", { description: userErrorText(error) });\n setBusy(false);\n }\n }\n\n if (granted) {\n return <CreditsCelebrationDialog status={granted} open={open} onOpenChange={onOpenChange} />;\n }\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>\n {purpose === \"topup\" ? \"Add Opengeni credits\" : \"Add Opengeni credits to continue\"}\n </DialogTitle>\n <DialogDescription>\n {purpose === \"topup\"\n ? \"Choose an amount and pay in Stripe Checkout, or redeem a coupon code.\"\n : \"Add credits to use this model, or choose another model.\"}\n </DialogDescription>\n </DialogHeader>\n {canBuyCredits && stripeEnabled ? (\n <div className=\"grid gap-4\">\n <CreditAmountPicker value={topupAmount} onChange={setTopupAmount} disabled={busy} />\n <Button\n type=\"button\"\n variant={purpose === \"topup\" ? \"default\" : \"outline\"}\n disabled={busy || !validTopupAmount(topupAmount)}\n onClick={() => void buyCredits()}\n {...analyticsAction(\"buy_credits\")}\n >\n {busy ? (\n <Loader2Icon className=\"size-4 animate-spin\" />\n ) : (\n <CreditCardIcon className=\"size-4\" />\n )}\n {purpose === \"topup\" ? \"Continue to Stripe\" : \"Buy credits\"}\n </Button>\n {accountId ? (\n <div className=\"border-t border-border pt-3\">\n <CouponRedeem\n client={client}\n accountId={accountId}\n workspaceId={workspaceId}\n disabled={busy}\n onGranted={setGranted}\n />\n </div>\n ) : null}\n </div>\n ) : !canBuyCredits ? (\n <p className=\"text-sm text-fg-muted\">\n Ask an organization owner to add credits, or an admin to connect a model.\n </p>\n ) : null}\n {purpose === \"required\" ? (\n <DialogFooter>\n <Button asChild type=\"button\">\n <Link\n to=\"/workspaces/$workspaceId/organization\"\n params={{ workspaceId }}\n search={\n canUpgrade\n ? { section: \"billing\" }\n : { section: \"models\", workspace: workspaceId }\n }\n onClick={() => onOpenChange(false)}\n {...(canUpgrade ? {} : analyticsAction(\"connect_model\"))}\n >\n {canUpgrade ? (\n <CreditCardIcon className=\"size-3.5\" />\n ) : (\n <SparklesIcon className=\"size-3.5\" />\n )}\n {canUpgrade ? \"View upgrade options\" : \"Connect a model\"}\n </Link>\n </Button>\n </DialogFooter>\n ) : null}\n </DialogContent>\n </Dialog>\n );\n}\n\nexport function EmptyCreditsNotice({\n workspaceId,\n accountId,\n canBuyCredits,\n canReadBilling,\n creditFunding,\n}: {\n workspaceId: string;\n accountId: string | null;\n canBuyCredits: boolean;\n canReadBilling: boolean;\n creditFunding?: WorkspaceModelCatalogModel[\"creditFunding\"] | undefined;\n}) {\n const client = useAppContext().client;\n const [legacyEmpty, setEmpty] = useState(false);\n const [stripeEnabled, setStripeEnabled] = useState(false);\n\n useEffect(() => {\n setEmpty(false);\n setStripeEnabled(false);\n if (!accountId || !canReadBilling) return;\n let active = true;\n void client\n .getBilling({ accountId })\n .then((summary) => {\n if (!active) return;\n setEmpty(summary.mode !== \"disabled\" && summary.balance.balanceMicros <= 0);\n setStripeEnabled(summary.mode === \"stripe\");\n })\n .catch(() => {\n if (!active) return;\n setEmpty(false);\n setStripeEnabled(false);\n });\n return () => {\n active = false;\n };\n }, [accountId, canReadBilling, client]);\n\n const empty =\n stripeEnabled && (creditFunding === undefined ? legacyEmpty : creditFunding === \"unavailable\");\n useCreditExposure(empty, workspaceId);\n if (!empty) return null;\n return (\n <Notice tone=\"waiting\" title=\"This model uses Opengeni credits\">\n No credits are available for this model. Choose another model or add credits.\n <div className=\"mt-2 flex flex-wrap gap-2\">\n {canBuyCredits && stripeEnabled ? (\n <Button asChild type=\"button\" size=\"sm\" variant=\"outline\">\n <Link\n to=\"/workspaces/$workspaceId/organization\"\n params={{ workspaceId }}\n search={{ section: \"billing\" }}\n {...analyticsAction(\"buy_credits\")}\n >\n <CreditCardIcon className=\"size-3.5\" />\n Buy credits\n </Link>\n </Button>\n ) : null}\n <Button asChild type=\"button\" size=\"sm\">\n <Link\n to=\"/workspaces/$workspaceId/organization\"\n params={{ workspaceId }}\n search={{ section: \"models\", workspace: workspaceId }}\n {...analyticsAction(\"connect_model\")}\n >\n Connect a model\n </Link>\n </Button>\n </div>\n </Notice>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/app/components/credit-required-prompt.tsx"],"sourcesContent":["import { useCreditExposure } from \"../lib/use-analytics-exposure\";\nimport type { OpenGeniBrowserClient } from \"@opengeni/sdk/browser\";\nimport { Link, usePage } from \"../lib/navigation\";\nimport { CreditCardIcon, Loader2Icon, SparklesIcon } from \"lucide-react\";\nimport type { BillingCheckoutStatus, WorkspaceModelCatalogModel } from \"@opengeni/sdk\";\nimport { useEffect, useState } from \"react\";\nimport { toast } from \"../lib/toast\";\n\nimport { CouponRedeem } from \"./credits/coupon-redeem\";\nimport { CreditsCelebrationDialog } from \"./credits/checkout-credits-celebration\";\n\nimport { Button } from \"../../ui/button\";\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from \"../../ui/dialog\";\nimport { CreditAmountPicker } from \"./credit-amount-picker\";\nimport { Notice } from \"../../ui/notice\";\nimport { useAppContext } from \"../app-context\";\nimport { userErrorText } from \"../../ui/api-error\";\nimport { validTopupAmount } from \"../lib/format\";\nimport { analyticsAction } from \"../../ui/analytics-actions\";\nimport { billingCheckoutReturnUrl, checkoutTabReturnUrl } from \"../lib/credit-checkout\";\nimport { subscriptionAction } from \"../lib/subscription-plans\";\n\nconst DEFAULT_TOPUP = \"25.00\";\n\ntype CreditRequiredPromptProps = {\n open: boolean;\n workspaceId: string;\n accountId: string | null;\n canBuyCredits: boolean;\n purpose?: \"required\" | \"topup\" | undefined;\n onOpenChange: (open: boolean) => void;\n};\n\nexport function CreditRequiredPrompt(props: CreditRequiredPromptProps) {\n return <CreditRequiredPromptView {...props} client={useAppContext().client} />;\n}\n\nexport function CreditRequiredPromptView({\n client,\n open,\n workspaceId,\n accountId,\n canBuyCredits,\n purpose = \"required\",\n onOpenChange,\n}: CreditRequiredPromptProps & { client: OpenGeniBrowserClient }) {\n const page = usePage();\n const [topupAmount, setTopupAmount] = useState(DEFAULT_TOPUP);\n const [busy, setBusy] = useState(false);\n // A redeemed coupon, celebrated in this dialog with its real amount.\n const [granted, setGranted] = useState<BillingCheckoutStatus | null>(null);\n useEffect(() => {\n if (!open) setGranted(null);\n }, [open]);\n const [stripeEnabled, setStripeEnabled] = useState(false);\n const [upgradeAccountId, setUpgradeAccountId] = useState<string | null>(null);\n const canUpgrade = open && canBuyCredits && accountId !== null && upgradeAccountId === accountId;\n\n useEffect(() => {\n setUpgradeAccountId(null);\n if (!open || !accountId || !canBuyCredits) {\n setStripeEnabled(false);\n return;\n }\n let active = true;\n setStripeEnabled(false);\n void client\n .getBilling({ accountId })\n .then(async (billing) => {\n if (active) setStripeEnabled(billing.mode === \"stripe\");\n if (!active || !billing.balance.plan || billing.mode !== \"stripe\") return;\n const catalog = await client.getBillingSubscriptionPlans({ accountId }).catch(() => null);\n if (\n active &&\n catalog?.plan &&\n catalog.plans.some((target) => {\n const action = subscriptionAction(billing.balance.plan!, catalog.plans, target);\n return action === \"checkout\" || action === \"upgrade\";\n })\n )\n setUpgradeAccountId(accountId);\n })\n .catch(() => {\n if (active) setStripeEnabled(false);\n });\n return () => {\n active = false;\n };\n }, [accountId, canBuyCredits, client, open]);\n\n async function buyCredits(): Promise<void> {\n if (!accountId || !validTopupAmount(topupAmount) || busy) return;\n setBusy(true);\n try {\n const session = await client.createBillingCheckout({\n amountUsd: Number(topupAmount),\n accountId,\n // Beside an embed, checkout ends on a page that asks to go back to it.\n successUrl: page.opensBeside\n ? checkoutTabReturnUrl(page.origin(), \"success\")\n : billingCheckoutReturnUrl(page.origin(), workspaceId, \"success\"),\n cancelUrl: page.opensBeside\n ? checkoutTabReturnUrl(page.origin(), \"cancelled\")\n : billingCheckoutReturnUrl(page.origin(), workspaceId, \"cancelled\"),\n });\n page.assign(session.url);\n // The web app has left for checkout; an embed stays and can buy again.\n if (page.opensBeside) setBusy(false);\n } catch (error) {\n toast.error(\"Checkout failed\", { description: userErrorText(error) });\n setBusy(false);\n }\n }\n\n if (granted) {\n return <CreditsCelebrationDialog status={granted} open={open} onOpenChange={onOpenChange} />;\n }\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>\n {purpose === \"topup\" ? \"Add Opengeni credits\" : \"Add Opengeni credits to continue\"}\n </DialogTitle>\n <DialogDescription>\n {purpose === \"topup\"\n ? \"Choose an amount and pay in Stripe Checkout, or redeem a coupon code.\"\n : \"Add credits to use this model, or choose another model.\"}\n </DialogDescription>\n </DialogHeader>\n {canBuyCredits && stripeEnabled ? (\n <div className=\"grid gap-4\">\n <CreditAmountPicker value={topupAmount} onChange={setTopupAmount} disabled={busy} />\n <Button\n type=\"button\"\n variant={purpose === \"topup\" ? \"default\" : \"outline\"}\n disabled={busy || !validTopupAmount(topupAmount)}\n onClick={() => void buyCredits()}\n {...analyticsAction(\"buy_credits\")}\n >\n {busy ? (\n <Loader2Icon className=\"size-4 animate-spin\" />\n ) : (\n <CreditCardIcon className=\"size-4\" />\n )}\n {purpose === \"topup\" ? \"Continue to Stripe\" : \"Buy credits\"}\n </Button>\n {accountId ? (\n <div className=\"border-t border-border pt-3\">\n <CouponRedeem\n client={client}\n accountId={accountId}\n workspaceId={workspaceId}\n disabled={busy}\n onGranted={setGranted}\n />\n </div>\n ) : null}\n </div>\n ) : !canBuyCredits ? (\n <p className=\"text-sm text-fg-muted\">\n Ask an organization owner to add credits, or an admin to connect a model.\n </p>\n ) : null}\n {purpose === \"required\" ? (\n <DialogFooter>\n <Button asChild type=\"button\">\n <Link\n to=\"/workspaces/$workspaceId/organization\"\n params={{ workspaceId }}\n search={\n canUpgrade\n ? { section: \"billing\" }\n : { section: \"models\", workspace: workspaceId }\n }\n onClick={() => onOpenChange(false)}\n {...(canUpgrade ? {} : analyticsAction(\"connect_model\"))}\n >\n {canUpgrade ? (\n <CreditCardIcon className=\"size-3.5\" />\n ) : (\n <SparklesIcon className=\"size-3.5\" />\n )}\n {canUpgrade ? \"View upgrade options\" : \"Connect a model\"}\n </Link>\n </Button>\n </DialogFooter>\n ) : null}\n </DialogContent>\n </Dialog>\n );\n}\n\nexport function EmptyCreditsNotice({\n workspaceId,\n accountId,\n canBuyCredits,\n canReadBilling,\n creditFunding,\n}: {\n workspaceId: string;\n accountId: string | null;\n canBuyCredits: boolean;\n canReadBilling: boolean;\n creditFunding?: WorkspaceModelCatalogModel[\"creditFunding\"] | undefined;\n}) {\n const client = useAppContext().client;\n const [legacyEmpty, setEmpty] = useState(false);\n const [stripeEnabled, setStripeEnabled] = useState(false);\n\n useEffect(() => {\n setEmpty(false);\n setStripeEnabled(false);\n if (!accountId || !canReadBilling) return;\n let active = true;\n void client\n .getBilling({ accountId })\n .then((summary) => {\n if (!active) return;\n setEmpty(summary.mode !== \"disabled\" && summary.balance.balanceMicros <= 0);\n setStripeEnabled(summary.mode === \"stripe\");\n })\n .catch(() => {\n if (!active) return;\n setEmpty(false);\n setStripeEnabled(false);\n });\n return () => {\n active = false;\n };\n }, [accountId, canReadBilling, client]);\n\n const empty =\n stripeEnabled && (creditFunding === undefined ? legacyEmpty : creditFunding === \"unavailable\");\n useCreditExposure(empty, workspaceId);\n if (!empty) return null;\n return (\n <Notice tone=\"waiting\" title=\"This model uses Opengeni credits\">\n No credits are available for this model. Choose another model or add credits.\n <div className=\"mt-2 flex flex-wrap gap-2\">\n {canBuyCredits && stripeEnabled ? (\n <Button asChild type=\"button\" size=\"sm\" variant=\"outline\">\n <Link\n to=\"/workspaces/$workspaceId/organization\"\n params={{ workspaceId }}\n search={{ section: \"billing\" }}\n {...analyticsAction(\"buy_credits\")}\n >\n <CreditCardIcon className=\"size-3.5\" />\n Buy credits\n </Link>\n </Button>\n ) : null}\n <Button asChild type=\"button\" size=\"sm\">\n <Link\n to=\"/workspaces/$workspaceId/organization\"\n params={{ workspaceId }}\n search={{ section: \"models\", workspace: workspaceId }}\n {...analyticsAction(\"connect_model\")}\n >\n Connect a model\n </Link>\n </Button>\n </div>\n </Notice>\n );\n}\n"],"mappings":"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","names":[]}
@@ -1,15 +1,17 @@
1
1
  "use client";
2
2
  import {
3
3
  CreditRefusalNotice
4
- } from "../../../chunk-TLL22FFO.js";
5
- import "../../../chunk-SWCLN6JE.js";
6
- import "../../../chunk-5TLEWXAB.js";
4
+ } from "../../../chunk-KUO5WFXG.js";
5
+ import "../../../chunk-GRNE5ANU.js";
6
+ import "../../../chunk-IKQMSROV.js";
7
7
  import "../../../chunk-PYC2ZWBJ.js";
8
8
  import "../../../chunk-VYKW6TB2.js";
9
9
  import "../../../chunk-IZUAIHR4.js";
10
10
  import "../../../chunk-L4OF77LE.js";
11
+ import "../../../chunk-6NXQCOLD.js";
11
12
  import "../../../chunk-WLEDGIVS.js";
12
13
  import "../../../chunk-HMU5IELG.js";
14
+ import "../../../chunk-DHXKEJBH.js";
13
15
  import "../../../chunk-TXS65BB2.js";
14
16
  export {
15
17
  CreditRefusalNotice
@@ -7,8 +7,8 @@ import {
7
7
  deliverAppShot,
8
8
  resetAppShotTargetsForTest,
9
9
  useAppShotTarget
10
- } from "../../../chunk-AIEXYO2X.js";
11
- import "../../../chunk-PCJLH45G.js";
10
+ } from "../../../chunk-6YDXUE5H.js";
11
+ import "../../../chunk-3MQM4ZOC.js";
12
12
  import "../../../chunk-AVAR2CFB.js";
13
13
  import "../../../chunk-L5HJ4UYB.js";
14
14
  import "../../../chunk-FABYS4WM.js";
@@ -16,10 +16,10 @@ import "../../../chunk-YG6NARQY.js";
16
16
  import "../../../chunk-VYKW6TB2.js";
17
17
  import "../../../chunk-IZUAIHR4.js";
18
18
  import "../../../chunk-W6KAUGXO.js";
19
- import "../../../chunk-DGLRZMXL.js";
20
- import "../../../chunk-O2SBHS2N.js";
19
+ import "../../../chunk-BWKZEW6K.js";
20
+ import "../../../chunk-K4FDZVMQ.js";
21
21
  import "../../../chunk-XEA5BCMA.js";
22
- import "../../../chunk-JFK7NTEA.js";
22
+ import "../../../chunk-S6WJ6TUT.js";
23
23
  export {
24
24
  AppShotCoordinator,
25
25
  appShotCaptureFrom,
@@ -5,13 +5,13 @@ import {
5
5
  DesktopThisComputerProvider,
6
6
  insideDesktopApp,
7
7
  useDesktopThisComputer
8
- } from "../../../chunk-PCJLH45G.js";
8
+ } from "../../../chunk-3MQM4ZOC.js";
9
9
  import "../../../chunk-FABYS4WM.js";
10
10
  import "../../../chunk-W6KAUGXO.js";
11
- import "../../../chunk-DGLRZMXL.js";
12
- import "../../../chunk-O2SBHS2N.js";
11
+ import "../../../chunk-BWKZEW6K.js";
12
+ import "../../../chunk-K4FDZVMQ.js";
13
13
  import "../../../chunk-XEA5BCMA.js";
14
- import "../../../chunk-JFK7NTEA.js";
14
+ import "../../../chunk-S6WJ6TUT.js";
15
15
  export {
16
16
  DesktopThisComputerOffer,
17
17
  DesktopThisComputerPanel,
@@ -3,18 +3,18 @@ import {
3
3
  FeedbackDialog,
4
4
  MessageSquareIcon,
5
5
  SessionFeedback
6
- } from "../../chunk-VWSFA4LJ.js";
6
+ } from "../../chunk-OWJD3V4V.js";
7
7
  import "../../chunk-QAWWQS4L.js";
8
8
  import "../../chunk-WMSCYECP.js";
9
9
  import "../../chunk-HZUL2CUH.js";
10
- import "../../chunk-TJQDL3JH.js";
10
+ import "../../chunk-BPD4IJBG.js";
11
11
  import "../../chunk-L4OF77LE.js";
12
12
  import "../../chunk-A3KMTJZS.js";
13
13
  import "../../chunk-HMU5IELG.js";
14
14
  import "../../chunk-LRNZ5F2R.js";
15
15
  import "../../chunk-J3BHDXQQ.js";
16
16
  import "../../chunk-TXS65BB2.js";
17
- import "../../chunk-JFK7NTEA.js";
17
+ import "../../chunk-S6WJ6TUT.js";
18
18
  export {
19
19
  FeedbackDialog,
20
20
  MessageSquareIcon as FeedbackIcon,