@opengeni/react 6.8.0 → 6.9.1-canary.41937124785001

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 (719) hide show
  1. package/dist/app/app-state.js +8 -8
  2. package/dist/app/components/Composer.js +18 -18
  3. package/dist/app/components/agent/agent-capability-picker.js +6 -6
  4. package/dist/app/components/artifacts/artifact-library.js +6 -6
  5. package/dist/app/components/artifacts/artifact-viewer.js +18 -18
  6. package/dist/app/components/artifacts/chat-interactive-block.js +11 -11
  7. package/dist/app/components/artifacts/file-reach-dialog.js +6 -6
  8. package/dist/app/components/artifacts/inline-chat-image.js +19 -19
  9. package/dist/app/components/artifacts/retained-file-preview.js +20 -20
  10. package/dist/app/components/artifacts/retained-text-preview.js +3 -3
  11. package/dist/app/components/artifacts/site-audience.js +3 -3
  12. package/dist/app/components/artifacts/site-conversations.js +9 -9
  13. package/dist/app/components/artifacts/site-data.js +10 -10
  14. package/dist/app/components/artifacts/site-publishing-page.js +25 -25
  15. package/dist/app/components/artifacts/site-publishing.js +22 -22
  16. package/dist/app/components/artifacts/site-settings.js +24 -24
  17. package/dist/app/components/artifacts/site-version-menu.js +3 -3
  18. package/dist/app/components/billing-class-mark.js +3 -3
  19. package/dist/app/components/bots/bot-launch-strip.js +20 -20
  20. package/dist/app/components/bots/bot-template-dialog.js +26 -26
  21. package/dist/app/components/bots/bot-template-shortcuts.js +20 -20
  22. package/dist/app/components/bots/bot-templates-page.js +30 -30
  23. package/dist/app/components/capabilities/capability-detail-sheet.js +6 -6
  24. package/dist/app/components/capabilities/capability-logo-source.js +13 -13
  25. package/dist/app/components/capabilities/connector-tool-permissions.js +4 -4
  26. package/dist/app/components/capabilities/native-connect-setup.js +13 -13
  27. package/dist/app/components/capabilities/own-logins-shared-heads-up.js +3 -3
  28. package/dist/app/components/capabilities/prepared-mcp-setup-card.js +15 -15
  29. package/dist/app/components/capabilities/session-capability-card.js +52 -52
  30. package/dist/app/components/capabilities/session-chrome-card.js +20 -20
  31. package/dist/app/components/capabilities/session-custom-mcp-card.js +16 -16
  32. package/dist/app/components/capabilities/session-github-card.js +16 -16
  33. package/dist/app/components/capabilities/session-machine-card.js +19 -19
  34. package/dist/app/components/capabilities/session-personal-github-card.js +14 -14
  35. package/dist/app/components/capabilities/session-plugin-card.js +8 -8
  36. package/dist/app/components/command-menu/chat-status.js +15 -15
  37. package/dist/app/components/command-menu/chat-switcher.js +35 -35
  38. package/dist/app/components/command-menu/command-menu.js +39 -39
  39. package/dist/app/components/command-menu/shortcut-sheet.js +8 -8
  40. package/dist/app/components/composer-capabilities-menu-body.js +4 -4
  41. package/dist/app/components/composer-mobile-plus-panel.js +8 -8
  42. package/dist/app/components/composer-mobile-plus.js +1 -1
  43. package/dist/app/components/desktop/app-shots.js +6 -6
  44. package/dist/app/components/desktop/computer-use.js +2 -2
  45. package/dist/app/components/desktop/this-computer.js +5 -5
  46. package/dist/app/components/feedback.js +3 -3
  47. package/dist/app/components/github-app-connect-launcher.js +1 -1
  48. package/dist/app/components/machines/connect-machine-dialog.js +11 -11
  49. package/dist/app/components/markdown.js +6 -6
  50. package/dist/app/components/models/models-ui.js +5 -5
  51. package/dist/app/components/models/subscription-usage.d.ts +34 -0
  52. package/dist/app/components/models/subscription-usage.js +24 -0
  53. package/dist/app/components/my-things.js +4 -4
  54. package/dist/app/components/own-where-it-works.js +3 -3
  55. package/dist/app/components/personal-resource-attachment-surface.js +4 -4
  56. package/dist/app/components/pickers.js +5 -5
  57. package/dist/app/components/rail/channel-create-dialog.js +3 -3
  58. package/dist/app/components/rail/project-glyph.js +20 -20
  59. package/dist/app/components/rail/project-profile.js +27 -27
  60. package/dist/app/components/rail/rail-context.js +1 -1
  61. package/dist/app/components/rail/rail-sections.js +55 -55
  62. package/dist/app/components/rail/session-header.js +47 -47
  63. package/dist/app/components/rail/session-list.js +53 -53
  64. package/dist/app/components/rail/session-row-content.js +4 -4
  65. package/dist/app/components/rail/session-row-hover-details.js +14 -14
  66. package/dist/app/components/rail/session-shell.js +76 -73
  67. package/dist/app/components/rail/site-session-group-heading.js +8 -8
  68. package/dist/app/components/session/agent-configuration-panel.js +12 -12
  69. package/dist/app/components/session/banners.js +8 -8
  70. package/dist/app/components/session/console-new-conversation.js +39 -39
  71. package/dist/app/components/session/descendant-requests.js +36 -36
  72. package/dist/app/components/session/editable-artifacts-workspace.js +16 -16
  73. package/dist/app/components/session/failed-session-banner.js +6 -6
  74. package/dist/app/components/session/failure-recovery-boundary.js +3 -3
  75. package/dist/app/components/session/human-input-delegation-record.js +2 -2
  76. package/dist/app/components/session/human-input.js +33 -33
  77. package/dist/app/components/session/inspector.js +43 -43
  78. package/dist/app/components/session/message-actions.js +3 -3
  79. package/dist/app/components/session/message-resource-attachments.js +10 -10
  80. package/dist/app/components/session/model-recovery-notice.js +3 -3
  81. package/dist/app/components/session/new-session-settings-menu.js +6 -6
  82. package/dist/app/components/session/new-session-setup-strip.js +21 -21
  83. package/dist/app/components/session/sandbox-recovery-actions.js +3 -3
  84. package/dist/app/components/session/sandbox-switcher.js +7 -7
  85. package/dist/app/components/session/sandbox-workspace.js +48 -48
  86. package/dist/app/components/session/search-markdown-highlight.js +7 -7
  87. package/dist/app/components/session/search-results-view.js +8 -8
  88. package/dist/app/components/session/session-admin-access.js +4 -4
  89. package/dist/app/components/session/session-admission-notice.js +4 -4
  90. package/dist/app/components/session/session-avatar-picker.js +21 -21
  91. package/dist/app/components/session/session-avatar.js +19 -19
  92. package/dist/app/components/session/session-machine-access-notice.js +4 -4
  93. package/dist/app/components/session/session-profile-dialog.js +25 -25
  94. package/dist/app/components/session/session-profile-editor.js +26 -26
  95. package/dist/app/components/session/session-retention.js +3 -3
  96. package/dist/app/components/session/session-search-dialog.js +8 -8
  97. package/dist/app/components/session/session-tenancy-control.js +2 -2
  98. package/dist/app/components/session/session-usage-limit-section.js +4 -4
  99. package/dist/app/components/session/share-chat-dialog.js +5 -5
  100. package/dist/app/components/session/subagents.js +8 -8
  101. package/dist/app/components/session/subscription-account-indicator.js +12 -7
  102. package/dist/app/components/session/subscription-account-menu.d.ts +15 -15
  103. package/dist/app/components/session/subscription-account-menu.js +6 -1
  104. package/dist/app/components/session/subscription-account.d.ts +16 -9
  105. package/dist/app/components/settings/row-select.js +4 -4
  106. package/dist/app/components/transcription-settings.js +6 -6
  107. package/dist/app/components/ui/destructive-confirm.js +5 -5
  108. package/dist/app/components/usage/usage-entry.js +3 -3
  109. package/dist/app/components/window-bar.js +9 -9
  110. package/dist/app/components/workspace-composer-plus.js +16 -16
  111. package/dist/app/components/workspace-reach.js +4 -4
  112. package/dist/app/embed/session-app.js +160 -157
  113. package/dist/app/lib/actions/actions-provider.js +8 -8
  114. package/dist/app/lib/agent-capabilities.d.ts +12 -2
  115. package/dist/app/lib/agent-capabilities.js +3 -3
  116. package/dist/app/lib/codex-usage-query.js +2 -2
  117. package/dist/app/lib/composer-connectors.js +14 -14
  118. package/dist/app/lib/console-site.js +2 -2
  119. package/dist/app/lib/console-text.js +2 -2
  120. package/dist/app/lib/events.js +12 -12
  121. package/dist/app/lib/failed-session-copy.js +3 -3
  122. package/dist/app/lib/model-access-onboarding.js +3 -3
  123. package/dist/app/lib/move-chat-to-machine.js +3 -3
  124. package/dist/app/lib/session-branch-cache.js +8 -8
  125. package/dist/app/lib/session-create.js +4 -4
  126. package/dist/app/lib/session-group-pagination.js +8 -8
  127. package/dist/app/lib/session-hover-facts.js +13 -13
  128. package/dist/app/lib/session-model.js +2 -2
  129. package/dist/app/lib/session-pins.js +1 -1
  130. package/dist/app/lib/session-rail.js +5 -5
  131. package/dist/app/lib/session-rename.js +3 -3
  132. package/dist/app/lib/sessions-group.d.ts +5 -3
  133. package/dist/app/lib/sessions-group.js +7 -7
  134. package/dist/app/lib/site-tool-consent-dialog.js +7 -7
  135. package/dist/app/lib/site-tool-consent.js +1 -1
  136. package/dist/app/lib/subscription-accounts.d.ts +79 -0
  137. package/dist/app/lib/subscription-accounts.js +18 -0
  138. package/dist/app/lib/turn-failure-analytics.js +4 -4
  139. package/dist/app/lib/use-follow-up-repositories.js +3 -3
  140. package/dist/app/lib/use-workspace-machines.js +4 -4
  141. package/dist/app/lib/use-workspace-model-catalog.js +3 -3
  142. package/dist/app/lib/use-workspace-rigs.js +2 -2
  143. package/dist/app/lib/workspace-navigation-preference.js +4 -4
  144. package/dist/app/lib/workspace-scope-context.js +3 -3
  145. package/dist/app/routes/artifacts.js +48 -48
  146. package/dist/app/routes/retained-artifact.js +32 -32
  147. package/dist/app/routes/session.js +96 -96
  148. package/dist/app/routes/sessions-index-hydration.js +5 -5
  149. package/dist/app/routes/sessions-index.js +76 -76
  150. package/dist/app/routes/site-view.js +55 -55
  151. package/dist/artifacts-document.js +4 -4
  152. package/dist/artifacts-presentation.js +4 -4
  153. package/dist/artifacts-spreadsheet.js +4 -4
  154. package/dist/artifacts.js +10 -10
  155. package/dist/automations.js +10 -10
  156. package/dist/{browser-viewer-ZHQDVHZ2.js → browser-viewer-F4FL7JKB.js} +4 -4
  157. package/dist/{chat-interactive-block-VSDD6X3M.js → chat-interactive-block-4U5JWRSY.js} +5 -5
  158. package/dist/{chunk-4K64EKM7.js → chunk-22YIIM3X.js} +4 -4
  159. package/dist/{chunk-3NNAC43A.js → chunk-2N7ACQ7M.js} +2 -2
  160. package/dist/{chunk-7Z76QP64.js → chunk-2PY5XD3F.js} +35 -5
  161. package/dist/chunk-2PY5XD3F.js.map +1 -0
  162. package/dist/{chunk-WDASYY4S.js → chunk-2TEYUDJD.js} +8 -8
  163. package/dist/{chunk-OTW25A6I.js → chunk-37JJQNZB.js} +3 -3
  164. package/dist/{chunk-VCJQQYRE.js → chunk-3DWQPURZ.js} +4 -4
  165. package/dist/{chunk-GTRAH4FG.js → chunk-3GWC3FU3.js} +2 -2
  166. package/dist/{chunk-AB5IW227.js → chunk-3ICY6LP3.js} +3 -3
  167. package/dist/{chunk-WIFDNUKD.js → chunk-3OCU5RX5.js} +3 -3
  168. package/dist/{chunk-UBRQ3PQD.js → chunk-3SPDJLOR.js} +2 -2
  169. package/dist/{chunk-IZXYFWA4.js → chunk-3WVLR7UA.js} +12 -12
  170. package/dist/{chunk-DEHLWZSI.js → chunk-3XMB3L57.js} +4 -4
  171. package/dist/{chunk-AJBDAVX3.js → chunk-4IUOBO2H.js} +7 -7
  172. package/dist/{chunk-NFCS5WYC.js → chunk-4KQ3A3EO.js} +3 -3
  173. package/dist/{chunk-LIJNVIT3.js → chunk-4L5B5AZT.js} +3 -3
  174. package/dist/{chunk-EDDKPIIV.js → chunk-4NB3TPNE.js} +2 -2
  175. package/dist/{chunk-PSM3CU7N.js → chunk-4TDKXHCD.js} +46 -39
  176. package/dist/chunk-4TDKXHCD.js.map +1 -0
  177. package/dist/{chunk-OJWDNNW3.js → chunk-4TPTGBIO.js} +5 -5
  178. package/dist/{chunk-J2WY42FA.js → chunk-4UHGW6WF.js} +2 -2
  179. package/dist/{chunk-7NLF35YL.js → chunk-4YN2JLYK.js} +4 -4
  180. package/dist/{chunk-OOOSGPJL.js → chunk-53MYEEMA.js} +1 -1
  181. package/dist/{chunk-467WDSOK.js → chunk-5HYWXPMA.js} +2 -2
  182. package/dist/{chunk-XMBOLFFS.js → chunk-5IMNL6IV.js} +2 -2
  183. package/dist/{chunk-4Z5X7PLC.js → chunk-5MLM5T5C.js} +3 -3
  184. package/dist/{chunk-YMI27QPF.js → chunk-5NKQZVXP.js} +2 -2
  185. package/dist/{chunk-ZW5YTIH3.js → chunk-5PB46DAA.js} +1 -1
  186. package/dist/{chunk-ZW5YTIH3.js.map → chunk-5PB46DAA.js.map} +1 -1
  187. package/dist/{chunk-CYDXCILL.js → chunk-5SODSGW7.js} +7 -7
  188. package/dist/{chunk-Q5EZNBPI.js → chunk-5YAJASCO.js} +3 -3
  189. package/dist/{chunk-M3FDGRB4.js → chunk-62XAL5BA.js} +3 -3
  190. package/dist/{chunk-SGH7I7OY.js → chunk-67R6NAFI.js} +2 -2
  191. package/dist/{chunk-Q5K2J5GG.js → chunk-6BN3RU7T.js} +13 -3
  192. package/dist/chunk-6BN3RU7T.js.map +1 -0
  193. package/dist/{chunk-PYB4BFEC.js → chunk-6BQLDL6R.js} +3 -3
  194. package/dist/{chunk-YJSCLGAW.js → chunk-6EZYHJTL.js} +3 -3
  195. package/dist/{chunk-OWET7EY2.js → chunk-6GW7NJMK.js} +19 -13
  196. package/dist/{chunk-OWET7EY2.js.map → chunk-6GW7NJMK.js.map} +1 -1
  197. package/dist/{chunk-G5UQBTXY.js → chunk-6LXIL3Q3.js} +2 -2
  198. package/dist/{chunk-T67LTMSW.js → chunk-6LYVAJFZ.js} +10 -10
  199. package/dist/{chunk-3L465FBR.js → chunk-6WB5UXMZ.js} +6 -6
  200. package/dist/{chunk-EKJHOWTZ.js → chunk-74UGYVCA.js} +4 -4
  201. package/dist/{chunk-PWUSSSSL.js → chunk-7BTNYZC7.js} +2 -2
  202. package/dist/{chunk-NQ2CPQJF.js → chunk-7D3WIDKK.js} +26 -3
  203. package/dist/chunk-7D3WIDKK.js.map +1 -0
  204. package/dist/{chunk-ESXAECZ3.js → chunk-7KZFGA25.js} +2 -2
  205. package/dist/{chunk-EGKARC53.js → chunk-7MGDX2TD.js} +2 -2
  206. package/dist/{chunk-Y3XZEKDQ.js → chunk-7N3GFGB6.js} +2 -2
  207. package/dist/{chunk-AH3DGOTK.js → chunk-7SFSN6AX.js} +2 -2
  208. package/dist/{chunk-QPQ7R77C.js → chunk-7SU4YVZ5.js} +5 -1
  209. package/dist/chunk-7SU4YVZ5.js.map +1 -0
  210. package/dist/{chunk-6QK65ZWM.js → chunk-7TGUHFGO.js} +3 -3
  211. package/dist/{chunk-QURYQFDN.js → chunk-7ZIWO65F.js} +2 -2
  212. package/dist/{chunk-OYCK4JRS.js → chunk-AJHLEJTK.js} +2 -2
  213. package/dist/{chunk-3PZ3LRPV.js → chunk-AN4U7EPH.js} +3 -3
  214. package/dist/{chunk-77BHKC43.js → chunk-APG6CEG7.js} +1 -1
  215. package/dist/{chunk-FSDQQQIA.js → chunk-APHLXQNP.js} +3 -3
  216. package/dist/{chunk-SN2WENRP.js → chunk-AXHQ7QXV.js} +3 -3
  217. package/dist/{chunk-54U6ZBEX.js → chunk-AYTLSPF6.js} +3 -3
  218. package/dist/{chunk-WYGTAQMX.js → chunk-AZFVRPQM.js} +76 -22
  219. package/dist/chunk-AZFVRPQM.js.map +1 -0
  220. package/dist/{chunk-R33SBMB7.js → chunk-BBSKKBMV.js} +3 -3
  221. package/dist/{chunk-2GCHGWNE.js → chunk-BGH6TU2P.js} +3 -3
  222. package/dist/{chunk-D3PTVN2I.js → chunk-BGIYL26H.js} +2 -2
  223. package/dist/{chunk-BQYRZIZ7.js → chunk-BL7UQUC3.js} +2 -2
  224. package/dist/{chunk-EBTUPRRQ.js → chunk-BOUHCYL6.js} +4 -4
  225. package/dist/{chunk-MKDFYE2E.js → chunk-BVNGDFBC.js} +2 -2
  226. package/dist/{chunk-ICAMYP5M.js → chunk-BWJK64CP.js} +2 -2
  227. package/dist/{chunk-RHXYO4H2.js → chunk-BZ2GTCQV.js} +2 -2
  228. package/dist/{chunk-GIWFLWXG.js → chunk-C2KASMJK.js} +4 -4
  229. package/dist/{chunk-KO3OHHY2.js → chunk-CAZDRDQT.js} +2 -2
  230. package/dist/{chunk-OK7BQMCI.js → chunk-CBJRZKZB.js} +9 -9
  231. package/dist/{chunk-OYOFPNLC.js → chunk-CF6NYG7J.js} +4 -4
  232. package/dist/{chunk-MT2R57SF.js → chunk-COITN7WN.js} +2 -2
  233. package/dist/{chunk-OCXTTKVA.js → chunk-CPVOXM2Q.js} +2 -2
  234. package/dist/{chunk-HYEIA25Y.js → chunk-CTZRCBKH.js} +2 -2
  235. package/dist/{chunk-OCXEY7HE.js → chunk-CWL27YTB.js} +2 -2
  236. package/dist/{chunk-K4DQS2ML.js → chunk-D2I33V5P.js} +4 -4
  237. package/dist/{chunk-736RUNIA.js → chunk-DF7WI4JH.js} +4 -4
  238. package/dist/{chunk-KUE5BOQE.js → chunk-DKZYCJCO.js} +4 -4
  239. package/dist/{chunk-74CBR5YE.js → chunk-DQ32FKFQ.js} +2 -2
  240. package/dist/{chunk-4O2XWOLZ.js → chunk-DTKG2YUF.js} +3 -3
  241. package/dist/{chunk-GMHIOYB7.js → chunk-DUDA4V5R.js} +4 -4
  242. package/dist/{chunk-XUOYNJPB.js → chunk-ECROT4M5.js} +24 -24
  243. package/dist/{chunk-PVB4YVDP.js → chunk-EOXV5XGY.js} +2 -2
  244. package/dist/{chunk-U6552Q3T.js → chunk-EQQOZ6DD.js} +2 -2
  245. package/dist/{chunk-G6ICCGJ3.js → chunk-EY6W5H4B.js} +2 -2
  246. package/dist/{chunk-HWVPLFIW.js → chunk-EYRFEWXJ.js} +2 -2
  247. package/dist/{chunk-7YTR3UFO.js → chunk-FB4JWUVJ.js} +8 -5
  248. package/dist/chunk-FB4JWUVJ.js.map +1 -0
  249. package/dist/{chunk-U4LTPFD2.js → chunk-FKK2PD7K.js} +2 -2
  250. package/dist/{chunk-PUUEI4W3.js → chunk-FPHHIC5K.js} +5 -5
  251. package/dist/{chunk-SP44O3OU.js → chunk-FQM6L22H.js} +2 -2
  252. package/dist/{chunk-2J77TWGH.js → chunk-FW22IREV.js} +3 -3
  253. package/dist/{chunk-EBIVTDEG.js → chunk-G4M6AYDB.js} +2 -2
  254. package/dist/{chunk-O4JOE3R7.js → chunk-G55NAU5M.js} +60 -74
  255. package/dist/chunk-G55NAU5M.js.map +1 -0
  256. package/dist/{chunk-BASI553K.js → chunk-G6AZ2WIU.js} +4 -4
  257. package/dist/{chunk-SJYTQLN3.js → chunk-GJ5IDSAX.js} +3 -3
  258. package/dist/{chunk-TDTD66BK.js → chunk-GRDSEZWZ.js} +2 -2
  259. package/dist/{chunk-MV2CLIO6.js → chunk-HBVJIGY2.js} +6 -6
  260. package/dist/{chunk-R4JA5JFI.js → chunk-HCWQLIOE.js} +3 -3
  261. package/dist/{chunk-MZY3VKKM.js → chunk-HEVD4A5G.js} +2 -2
  262. package/dist/{chunk-DLVIRJGK.js → chunk-HNDHSEVJ.js} +2 -2
  263. package/dist/{chunk-LPKJ77EK.js → chunk-HNTZ7B7M.js} +2 -2
  264. package/dist/{chunk-QQIZMVAJ.js → chunk-HQ7GTMII.js} +59 -57
  265. package/dist/chunk-HQ7GTMII.js.map +1 -0
  266. package/dist/{chunk-IN3VQFKS.js → chunk-I2FC7CAI.js} +2 -2
  267. package/dist/{chunk-SK5S2PCK.js → chunk-I7BGHBOM.js} +14 -14
  268. package/dist/chunk-I7BGHBOM.js.map +1 -0
  269. package/dist/{chunk-ZBHGNE2J.js → chunk-IEHZFYMH.js} +3 -3
  270. package/dist/{chunk-DWJ6J3YW.js → chunk-IXISEVD7.js} +4 -4
  271. package/dist/{chunk-TK5FWVZR.js → chunk-IZEDVQUD.js} +3 -3
  272. package/dist/{chunk-HEGV4QMS.js → chunk-J42QE4VO.js} +2 -2
  273. package/dist/{chunk-PRT4J2DL.js → chunk-J555XSUM.js} +2 -2
  274. package/dist/{chunk-SBXSKRFA.js → chunk-JNMHFSDF.js} +3 -3
  275. package/dist/{chunk-KI46GKMD.js → chunk-JTBAOPYO.js} +7 -7
  276. package/dist/{chunk-JHZRAYI4.js → chunk-JWSRFXRN.js} +2 -2
  277. package/dist/chunk-JWSRFXRN.js.map +1 -0
  278. package/dist/{chunk-SXGJL7UT.js → chunk-K376MPJH.js} +14 -14
  279. package/dist/{chunk-OSJ366KR.js → chunk-KEBVT55V.js} +30 -30
  280. package/dist/{chunk-U5UGM5XD.js → chunk-KFIZAXHI.js} +5 -5
  281. package/dist/{chunk-KFNZZ2N6.js → chunk-KKGRDBMK.js} +2 -2
  282. package/dist/{chunk-PLYVGZIN.js → chunk-KKIG6DN5.js} +1 -1
  283. package/dist/{chunk-3OK7Y6ES.js → chunk-KKQO2GAA.js} +2 -2
  284. package/dist/{chunk-DQPIEQGP.js → chunk-KO753ZCZ.js} +2 -2
  285. package/dist/{chunk-YNTLWCF4.js → chunk-KYIRWU65.js} +3 -3
  286. package/dist/{chunk-JKL5S7UQ.js → chunk-L6V63DVI.js} +6 -6
  287. package/dist/{chunk-M5IQVMLR.js → chunk-LAZ2QZTJ.js} +11 -4
  288. package/dist/chunk-LAZ2QZTJ.js.map +1 -0
  289. package/dist/{chunk-CV4VVLPZ.js → chunk-LCNJ2KNS.js} +2 -2
  290. package/dist/{chunk-D74Z2N4K.js → chunk-LE7YKMTU.js} +2 -2
  291. package/dist/{chunk-D5TIVCXG.js → chunk-LEBEOMVT.js} +2 -2
  292. package/dist/chunk-LKLQVANM.js +2 -0
  293. package/dist/{chunk-2OXSB2OL.js → chunk-LKWVBUH6.js} +3 -2
  294. package/dist/chunk-LKWVBUH6.js.map +1 -0
  295. package/dist/{chunk-WXF2RTS4.js → chunk-M6URPYUB.js} +2 -2
  296. package/dist/{chunk-H6BX6WOW.js → chunk-MDHFMRBC.js} +3 -3
  297. package/dist/{chunk-3CDJSKDW.js → chunk-MGZO7CHI.js} +3 -3
  298. package/dist/{chunk-DCEQCGVN.js → chunk-MIWU52TW.js} +2 -2
  299. package/dist/{chunk-PF2WU2IL.js → chunk-ND4IQJUM.js} +120 -17
  300. package/dist/chunk-ND4IQJUM.js.map +1 -0
  301. package/dist/{chunk-3PM3M2Q6.js → chunk-NDXBF3RW.js} +27 -11
  302. package/dist/chunk-NDXBF3RW.js.map +1 -0
  303. package/dist/{chunk-LVELUUK6.js → chunk-NF6QVVMP.js} +2 -2
  304. package/dist/{chunk-UMX6DZME.js → chunk-NTZ5ZNVK.js} +2 -2
  305. package/dist/{chunk-FBA2NXYH.js → chunk-NWLRABUR.js} +3 -3
  306. package/dist/{chunk-TNSJFZ6Q.js → chunk-O2H2U7YS.js} +4 -4
  307. package/dist/{chunk-BFFNINCC.js → chunk-OAL2PPX4.js} +3 -3
  308. package/dist/{chunk-WTSQUCHB.js → chunk-OCYTHZ4A.js} +3 -3
  309. package/dist/{chunk-ZAX4XQLN.js → chunk-OEDTCIXF.js} +2 -2
  310. package/dist/{chunk-CHU3RDV4.js → chunk-OLVSYB3P.js} +3 -3
  311. package/dist/{chunk-PZKHST7A.js → chunk-OQ6QOPK6.js} +10 -3
  312. package/dist/chunk-OQ6QOPK6.js.map +1 -0
  313. package/dist/{chunk-IFSXVU2S.js → chunk-OQHTFOCA.js} +2 -2
  314. package/dist/{chunk-OXQ2SXVC.js → chunk-P56AVROH.js} +2 -2
  315. package/dist/{chunk-CXAN2FHF.js → chunk-PCEJHHGP.js} +6 -6
  316. package/dist/{chunk-5MIBQ4P5.js → chunk-PHGQGVVL.js} +2 -2
  317. package/dist/{chunk-FLWQJDJ5.js → chunk-PUZRHEQI.js} +6 -6
  318. package/dist/{chunk-OP2GD6QW.js → chunk-PV7U6OOJ.js} +2 -2
  319. package/dist/{chunk-SPD4ULVB.js → chunk-PYMROAWS.js} +2 -1
  320. package/dist/chunk-PYMROAWS.js.map +1 -0
  321. package/dist/{chunk-X2QJXDE4.js → chunk-PZQACDH5.js} +8 -8
  322. package/dist/{chunk-CH4UQ4NO.js → chunk-PZTS4O6E.js} +5 -5
  323. package/dist/{chunk-TKQL7EDB.js → chunk-Q42QHUAQ.js} +2 -2
  324. package/dist/{chunk-MRECRNVU.js → chunk-QCYGB6TZ.js} +5 -5
  325. package/dist/{chunk-GSCGKJNK.js → chunk-QECMETOF.js} +2 -2
  326. package/dist/{chunk-RMCLFSMX.js → chunk-QGX3LE6H.js} +2 -2
  327. package/dist/{chunk-HTMQGS63.js → chunk-QI3NDQFP.js} +8 -8
  328. package/dist/{chunk-UU5FBVRX.js → chunk-QZE4BTLA.js} +6 -5
  329. package/dist/chunk-QZE4BTLA.js.map +1 -0
  330. package/dist/{chunk-R5QAL43H.js → chunk-RA3Q52O2.js} +2 -2
  331. package/dist/chunk-RBOHWUSN.js +151 -0
  332. package/dist/chunk-RBOHWUSN.js.map +1 -0
  333. package/dist/{chunk-AJDGP2N4.js → chunk-RJNOQEJJ.js} +20 -20
  334. package/dist/{chunk-477DTTMH.js → chunk-RSFOFUR7.js} +3 -3
  335. package/dist/{chunk-JV5ULONH.js → chunk-RXR6PMSH.js} +39 -39
  336. package/dist/{chunk-J2BTILRR.js → chunk-SM7HFCGC.js} +2 -2
  337. package/dist/{chunk-UTRNLNCW.js → chunk-SN6ZWYOP.js} +69 -97
  338. package/dist/chunk-SN6ZWYOP.js.map +1 -0
  339. package/dist/{chunk-OBGOLHCP.js → chunk-T4HK4XCI.js} +3 -3
  340. package/dist/{chunk-XVLEBB4Y.js → chunk-TBWL6YWL.js} +2 -2
  341. package/dist/{chunk-AAS7OWV6.js → chunk-TIDXYWFX.js} +3 -3
  342. package/dist/{chunk-N3FM4BNA.js → chunk-TKHRGY2P.js} +2 -2
  343. package/dist/{chunk-GU7T2S5N.js → chunk-TU2GSZL7.js} +2 -2
  344. package/dist/{chunk-OI6VI6SU.js → chunk-U6HGJXXQ.js} +8 -8
  345. package/dist/{chunk-4BWMAGJJ.js → chunk-UGRW6RTR.js} +3 -3
  346. package/dist/{chunk-AVXDIRRW.js → chunk-UMRUDYUK.js} +2 -2
  347. package/dist/{chunk-FNXCFIPW.js → chunk-UOT2R5ZD.js} +2 -2
  348. package/dist/{chunk-DIP7YALH.js → chunk-USURKJVT.js} +2 -2
  349. package/dist/{chunk-S27VZ5DO.js → chunk-UU6Q67XM.js} +6 -6
  350. package/dist/{chunk-LTJFV2JI.js → chunk-UZ7NP5CW.js} +2 -2
  351. package/dist/{chunk-H6MJFMHZ.js → chunk-V4FO7UOE.js} +3 -3
  352. package/dist/{chunk-RGR57NYY.js → chunk-V4ZOZRCW.js} +2 -2
  353. package/dist/{chunk-LQKVNREV.js → chunk-V57YMKQZ.js} +3 -3
  354. package/dist/{chunk-XZCCEKPW.js → chunk-VOIWZBY6.js} +6 -6
  355. package/dist/{chunk-E5KOWRDU.js → chunk-VPHPLPDA.js} +2 -2
  356. package/dist/{chunk-OGU73VUN.js → chunk-VUL4KPUU.js} +2 -2
  357. package/dist/{chunk-SFIXTOOJ.js → chunk-VWF6ILAR.js} +3 -3
  358. package/dist/{chunk-FER6EVIY.js → chunk-W54BHJO7.js} +2 -2
  359. package/dist/{chunk-34NV52R3.js → chunk-WCYE4BLC.js} +4 -4
  360. package/dist/{chunk-RISUROBM.js → chunk-WTV25ELY.js} +4 -4
  361. package/dist/{chunk-UO35OEOX.js → chunk-WZYGH7CN.js} +3 -3
  362. package/dist/{chunk-CEMSIU4Z.js → chunk-XG2RWUF7.js} +5 -5
  363. package/dist/chunk-XK72HZ4C.js +147 -0
  364. package/dist/chunk-XK72HZ4C.js.map +1 -0
  365. package/dist/{chunk-K3D7IQQP.js → chunk-XV7QOT7W.js} +6 -6
  366. package/dist/{chunk-GOCODNQS.js → chunk-XWECT3GX.js} +2 -2
  367. package/dist/{chunk-5MHMCE2G.js → chunk-XZQK2ZLW.js} +3 -3
  368. package/dist/{chunk-JV3UI7BH.js → chunk-Y5BR66OH.js} +3 -3
  369. package/dist/{chunk-VXORMNU4.js → chunk-YBHAAULA.js} +67 -2
  370. package/dist/chunk-YBHAAULA.js.map +1 -0
  371. package/dist/{chunk-4F3AEJI6.js → chunk-YD6XU6FY.js} +4 -4
  372. package/dist/{chunk-VATYK3JQ.js → chunk-YFE47G3C.js} +3 -3
  373. package/dist/{chunk-ZR5EKJT6.js → chunk-YG6TWPP7.js} +2 -2
  374. package/dist/{chunk-44JWVYJB.js → chunk-YH3ARKBB.js} +2 -2
  375. package/dist/{chunk-752WXSDN.js → chunk-YI66STKJ.js} +2 -2
  376. package/dist/{chunk-QRECBCJM.js → chunk-YMVPYMKB.js} +2 -2
  377. package/dist/{chunk-77SYIH6O.js → chunk-YPIXBAF6.js} +2 -2
  378. package/dist/{chunk-WRMUXZ7C.js → chunk-YSWPNY6G.js} +3 -3
  379. package/dist/{chunk-GTHCHCWW.js → chunk-YWNNMBZG.js} +3 -3
  380. package/dist/{chunk-3DRLCX5V.js → chunk-Z3HYM2JT.js} +2 -2
  381. package/dist/{chunk-M3HGBO2Y.js → chunk-ZAC7YPRA.js} +1 -1
  382. package/dist/{chunk-2VJOSU4H.js → chunk-ZENESDAF.js} +2 -2
  383. package/dist/{chunk-4JXPLTWV.js → chunk-ZHAPMETO.js} +2 -2
  384. package/dist/{chunk-IJR6VOLU.js → chunk-ZVR6DUZH.js} +2 -2
  385. package/dist/components/message-timeline.d.ts +10 -2
  386. package/dist/composer.js +8 -8
  387. package/dist/{computer-viewer-5LKRCEVQ.js → computer-viewer-FOIOZUF5.js} +5 -5
  388. package/dist/connect.js +12 -12
  389. package/dist/desktop-dictation.js +8 -8
  390. package/dist/desktop.js +2 -2
  391. package/dist/editor.js +2 -2
  392. package/dist/{embedded-new-voice-GHJRY3YL.js → embedded-new-voice-WTXAJNGO.js} +5 -5
  393. package/dist/{embedded-voice-ASQXBSTX.js → embedded-voice-SIJOPN2G.js} +5 -5
  394. package/dist/{fleet-decision-row-U7LDVBEM.js → fleet-decision-row-XKQ3GMYT.js} +2 -2
  395. package/dist/hooks/use-recordings.d.ts +4 -2
  396. package/dist/in-chat-connect-model.js +5 -5
  397. package/dist/index.d.ts +2 -2
  398. package/dist/index.js +66 -60
  399. package/dist/interaction.js +5 -5
  400. package/dist/{latest-question-RNVF262Q.js → latest-question-KA7AQYVI.js} +2 -2
  401. package/dist/machines.js +3 -3
  402. package/dist/meetings/recorder-context.d.ts +6 -1
  403. package/dist/meetings/recorder-panel.d.ts +2 -5
  404. package/dist/meetings-recorder.js +1 -1
  405. package/dist/meetings.js +25 -23
  406. package/dist/meetings.js.map +1 -1
  407. package/dist/messages/en.d.ts +4 -0
  408. package/dist/messages.js +1 -1
  409. package/dist/{model-policy-picker-menu-E6XKMFTA.js → model-policy-picker-menu-6N2G7VGX.js} +4 -4
  410. package/dist/{payment-page-card-DJDKV2LW.js → payment-page-card-IJFZHQ52.js} +4 -4
  411. package/dist/{platform-activity-row-MSDCSMET.js → platform-activity-row-MFCMGI43.js} +2 -2
  412. package/dist/{queue-surface-implementation-GUAIG6TK.js → queue-surface-implementation-BBCDWWOP.js} +5 -5
  413. package/dist/realtime.js +4 -4
  414. package/dist/{recorder-host-2MYDJPQW.js → recorder-host-LDYYOKG7.js} +5 -5
  415. package/dist/recordings.js +4 -4
  416. package/dist/{sandbox-files-W5W2LW4K.js → sandbox-files-VYRBIXJY.js} +6 -6
  417. package/dist/session-app.js +160 -157
  418. package/dist/{session-connect-cards-HPH7JOZP.js → session-connect-cards-GBPSL6OT.js} +9 -9
  419. package/dist/session-connect-cards-GBPSL6OT.js.map +1 -0
  420. package/dist/session-list-model.js +2 -2
  421. package/dist/{session-realtime-SDTKFFIR.js → session-realtime-QGU57TND.js} +3 -3
  422. package/dist/session-realtime-QGU57TND.js.map +1 -0
  423. package/dist/session-realtime.js +2 -2
  424. package/dist/session-ui.js +33 -33
  425. package/dist/session.d.ts +3 -2
  426. package/dist/session.js +16 -10
  427. package/dist/sites.js +2 -2
  428. package/dist/terminal.js +2 -2
  429. package/dist/this-computer.js +3 -3
  430. package/dist/timeline/index.d.ts +3 -2
  431. package/dist/timeline/projection.d.ts +52 -0
  432. package/dist/timeline/turn-summary-model.d.ts +4 -3
  433. package/dist/timeline/types.d.ts +8 -2
  434. package/dist/timeline/use-timeline-pauses.d.ts +12 -0
  435. package/dist/timeline/work-presentation.d.ts +4 -3
  436. package/dist/{timeline-annotation-markers-FNILLWNU.js → timeline-annotation-markers-LL6ZVBZH.js} +2 -2
  437. package/dist/{timeline-annotation-selection-MBCIDO2Q.js → timeline-annotation-selection-WQA76WYC.js} +2 -2
  438. package/dist/{timeline-annotations-dialog-JPNKLOTE.js → timeline-annotations-dialog-HHETAEZA.js} +3 -3
  439. package/dist/timeline-model.js +2 -2
  440. package/dist/ui/access-list.js +5 -5
  441. package/dist/ui/cadence-picker.js +4 -4
  442. package/dist/ui/choice-cards.js +3 -3
  443. package/dist/ui/confirm-dialog.js +2 -2
  444. package/dist/ui/copy-field.js +3 -3
  445. package/dist/ui/detail-page.js +2 -2
  446. package/dist/ui/detail-sheet.js +2 -2
  447. package/dist/ui/disclosure.js +3 -3
  448. package/dist/ui/email-chips-input.js +3 -3
  449. package/dist/ui/field.js +2 -2
  450. package/dist/ui/flush-form-page.js +3 -3
  451. package/dist/ui/form-dialog.js +2 -2
  452. package/dist/ui/list-row.js +3 -3
  453. package/dist/ui/relative-time.js +2 -2
  454. package/dist/ui/revision-history.js +4 -4
  455. package/dist/ui/role-select.js +5 -5
  456. package/dist/ui/select-menu.js +3 -3
  457. package/dist/ui/usage-meter.d.ts +8 -2
  458. package/dist/ui/usage-meter.js +5 -3
  459. package/dist/usage.js +2 -2
  460. package/dist/workbench.js +4 -4
  461. package/package.json +6 -5
  462. package/src/app/components/agent/agent-capability-picker.test.tsx +1 -1
  463. package/src/app/components/models/subscription-usage.tsx +178 -0
  464. package/src/app/components/rail/session-row-content.tsx +27 -0
  465. package/src/app/components/session/subscription-account-indicator.test.ts +78 -18
  466. package/src/app/components/session/subscription-account-indicator.tsx +16 -31
  467. package/src/app/components/session/subscription-account-menu.tsx +79 -101
  468. package/src/app/components/session/subscription-account.test.ts +161 -54
  469. package/src/app/components/session/subscription-account.ts +106 -117
  470. package/src/app/lib/agent-capabilities.tsx +34 -7
  471. package/src/app/lib/session-branch-cache.tsx +1 -0
  472. package/src/app/lib/session-pins.tsx +1 -0
  473. package/src/app/lib/session-row-paused.test.tsx +183 -0
  474. package/src/app/lib/sessions-group-channels.test.ts +4 -4
  475. package/src/app/lib/sessions-group.tsx +62 -4
  476. package/src/app/lib/subscription-accounts.tsx +283 -0
  477. package/src/app/routes/session.tsx +2 -0
  478. package/src/components/message-timeline.tsx +14 -2
  479. package/src/components/session-conversation.tsx +2 -1
  480. package/src/components/timeline-annotations.tsx +4 -1
  481. package/src/components/timeline-settlement.ts +1 -1
  482. package/src/hooks/use-composer.ts +104 -25
  483. package/src/hooks/use-recordings.ts +5 -0
  484. package/src/index.ts +5 -0
  485. package/src/meetings/meeting-detail-page.tsx +4 -2
  486. package/src/meetings/meetings-pages.test.tsx +38 -0
  487. package/src/meetings/recorder-context.tsx +28 -5
  488. package/src/meetings/recorder-panel.tsx +13 -5
  489. package/src/meetings/recorder-workspace.test.tsx +57 -8
  490. package/src/messages/en.ts +5 -0
  491. package/src/recordings-model.ts +7 -0
  492. package/src/session.ts +8 -1
  493. package/src/timeline/index.ts +4 -1
  494. package/src/timeline/projection.ts +228 -16
  495. package/src/timeline/turn-summary-model.ts +4 -3
  496. package/src/timeline/turn-summary.tsx +15 -2
  497. package/src/timeline/types.ts +8 -2
  498. package/src/timeline/use-timeline-pauses.ts +105 -0
  499. package/src/timeline/work-presentation.ts +13 -4
  500. package/src/ui/usage-meter.tsx +10 -7
  501. package/styles/compiled.css +3 -0
  502. package/dist/chunk-2OXSB2OL.js.map +0 -1
  503. package/dist/chunk-3PM3M2Q6.js.map +0 -1
  504. package/dist/chunk-7YTR3UFO.js.map +0 -1
  505. package/dist/chunk-7Z76QP64.js.map +0 -1
  506. package/dist/chunk-JHZRAYI4.js.map +0 -1
  507. package/dist/chunk-M5IQVMLR.js.map +0 -1
  508. package/dist/chunk-NQ2CPQJF.js.map +0 -1
  509. package/dist/chunk-O2UPPN5M.js +0 -2
  510. package/dist/chunk-O4JOE3R7.js.map +0 -1
  511. package/dist/chunk-PF2WU2IL.js.map +0 -1
  512. package/dist/chunk-PSM3CU7N.js.map +0 -1
  513. package/dist/chunk-PZKHST7A.js.map +0 -1
  514. package/dist/chunk-Q5K2J5GG.js.map +0 -1
  515. package/dist/chunk-QPQ7R77C.js.map +0 -1
  516. package/dist/chunk-QQIZMVAJ.js.map +0 -1
  517. package/dist/chunk-SK5S2PCK.js.map +0 -1
  518. package/dist/chunk-SPD4ULVB.js.map +0 -1
  519. package/dist/chunk-UTRNLNCW.js.map +0 -1
  520. package/dist/chunk-UU5FBVRX.js.map +0 -1
  521. package/dist/chunk-VXORMNU4.js.map +0 -1
  522. package/dist/chunk-WYGTAQMX.js.map +0 -1
  523. /package/dist/{browser-viewer-ZHQDVHZ2.js.map → app/components/models/subscription-usage.js.map} +0 -0
  524. /package/dist/{chat-interactive-block-VSDD6X3M.js.map → app/lib/subscription-accounts.js.map} +0 -0
  525. /package/dist/{chunk-O2UPPN5M.js.map → browser-viewer-F4FL7JKB.js.map} +0 -0
  526. /package/dist/{computer-viewer-5LKRCEVQ.js.map → chat-interactive-block-4U5JWRSY.js.map} +0 -0
  527. /package/dist/{chunk-4K64EKM7.js.map → chunk-22YIIM3X.js.map} +0 -0
  528. /package/dist/{chunk-3NNAC43A.js.map → chunk-2N7ACQ7M.js.map} +0 -0
  529. /package/dist/{chunk-WDASYY4S.js.map → chunk-2TEYUDJD.js.map} +0 -0
  530. /package/dist/{chunk-OTW25A6I.js.map → chunk-37JJQNZB.js.map} +0 -0
  531. /package/dist/{chunk-VCJQQYRE.js.map → chunk-3DWQPURZ.js.map} +0 -0
  532. /package/dist/{chunk-GTRAH4FG.js.map → chunk-3GWC3FU3.js.map} +0 -0
  533. /package/dist/{chunk-AB5IW227.js.map → chunk-3ICY6LP3.js.map} +0 -0
  534. /package/dist/{chunk-WIFDNUKD.js.map → chunk-3OCU5RX5.js.map} +0 -0
  535. /package/dist/{chunk-UBRQ3PQD.js.map → chunk-3SPDJLOR.js.map} +0 -0
  536. /package/dist/{chunk-IZXYFWA4.js.map → chunk-3WVLR7UA.js.map} +0 -0
  537. /package/dist/{chunk-DEHLWZSI.js.map → chunk-3XMB3L57.js.map} +0 -0
  538. /package/dist/{chunk-AJBDAVX3.js.map → chunk-4IUOBO2H.js.map} +0 -0
  539. /package/dist/{chunk-NFCS5WYC.js.map → chunk-4KQ3A3EO.js.map} +0 -0
  540. /package/dist/{chunk-LIJNVIT3.js.map → chunk-4L5B5AZT.js.map} +0 -0
  541. /package/dist/{chunk-EDDKPIIV.js.map → chunk-4NB3TPNE.js.map} +0 -0
  542. /package/dist/{chunk-OJWDNNW3.js.map → chunk-4TPTGBIO.js.map} +0 -0
  543. /package/dist/{chunk-J2WY42FA.js.map → chunk-4UHGW6WF.js.map} +0 -0
  544. /package/dist/{chunk-7NLF35YL.js.map → chunk-4YN2JLYK.js.map} +0 -0
  545. /package/dist/{chunk-OOOSGPJL.js.map → chunk-53MYEEMA.js.map} +0 -0
  546. /package/dist/{chunk-467WDSOK.js.map → chunk-5HYWXPMA.js.map} +0 -0
  547. /package/dist/{chunk-XMBOLFFS.js.map → chunk-5IMNL6IV.js.map} +0 -0
  548. /package/dist/{chunk-4Z5X7PLC.js.map → chunk-5MLM5T5C.js.map} +0 -0
  549. /package/dist/{chunk-YMI27QPF.js.map → chunk-5NKQZVXP.js.map} +0 -0
  550. /package/dist/{chunk-CYDXCILL.js.map → chunk-5SODSGW7.js.map} +0 -0
  551. /package/dist/{chunk-Q5EZNBPI.js.map → chunk-5YAJASCO.js.map} +0 -0
  552. /package/dist/{chunk-M3FDGRB4.js.map → chunk-62XAL5BA.js.map} +0 -0
  553. /package/dist/{chunk-SGH7I7OY.js.map → chunk-67R6NAFI.js.map} +0 -0
  554. /package/dist/{chunk-PYB4BFEC.js.map → chunk-6BQLDL6R.js.map} +0 -0
  555. /package/dist/{chunk-YJSCLGAW.js.map → chunk-6EZYHJTL.js.map} +0 -0
  556. /package/dist/{chunk-G5UQBTXY.js.map → chunk-6LXIL3Q3.js.map} +0 -0
  557. /package/dist/{chunk-T67LTMSW.js.map → chunk-6LYVAJFZ.js.map} +0 -0
  558. /package/dist/{chunk-3L465FBR.js.map → chunk-6WB5UXMZ.js.map} +0 -0
  559. /package/dist/{chunk-EKJHOWTZ.js.map → chunk-74UGYVCA.js.map} +0 -0
  560. /package/dist/{chunk-PWUSSSSL.js.map → chunk-7BTNYZC7.js.map} +0 -0
  561. /package/dist/{chunk-ESXAECZ3.js.map → chunk-7KZFGA25.js.map} +0 -0
  562. /package/dist/{chunk-EGKARC53.js.map → chunk-7MGDX2TD.js.map} +0 -0
  563. /package/dist/{chunk-Y3XZEKDQ.js.map → chunk-7N3GFGB6.js.map} +0 -0
  564. /package/dist/{chunk-AH3DGOTK.js.map → chunk-7SFSN6AX.js.map} +0 -0
  565. /package/dist/{chunk-6QK65ZWM.js.map → chunk-7TGUHFGO.js.map} +0 -0
  566. /package/dist/{chunk-QURYQFDN.js.map → chunk-7ZIWO65F.js.map} +0 -0
  567. /package/dist/{chunk-OYCK4JRS.js.map → chunk-AJHLEJTK.js.map} +0 -0
  568. /package/dist/{chunk-3PZ3LRPV.js.map → chunk-AN4U7EPH.js.map} +0 -0
  569. /package/dist/{chunk-77BHKC43.js.map → chunk-APG6CEG7.js.map} +0 -0
  570. /package/dist/{chunk-FSDQQQIA.js.map → chunk-APHLXQNP.js.map} +0 -0
  571. /package/dist/{chunk-SN2WENRP.js.map → chunk-AXHQ7QXV.js.map} +0 -0
  572. /package/dist/{chunk-54U6ZBEX.js.map → chunk-AYTLSPF6.js.map} +0 -0
  573. /package/dist/{chunk-R33SBMB7.js.map → chunk-BBSKKBMV.js.map} +0 -0
  574. /package/dist/{chunk-2GCHGWNE.js.map → chunk-BGH6TU2P.js.map} +0 -0
  575. /package/dist/{chunk-D3PTVN2I.js.map → chunk-BGIYL26H.js.map} +0 -0
  576. /package/dist/{chunk-BQYRZIZ7.js.map → chunk-BL7UQUC3.js.map} +0 -0
  577. /package/dist/{chunk-EBTUPRRQ.js.map → chunk-BOUHCYL6.js.map} +0 -0
  578. /package/dist/{chunk-MKDFYE2E.js.map → chunk-BVNGDFBC.js.map} +0 -0
  579. /package/dist/{chunk-ICAMYP5M.js.map → chunk-BWJK64CP.js.map} +0 -0
  580. /package/dist/{chunk-RHXYO4H2.js.map → chunk-BZ2GTCQV.js.map} +0 -0
  581. /package/dist/{chunk-GIWFLWXG.js.map → chunk-C2KASMJK.js.map} +0 -0
  582. /package/dist/{chunk-KO3OHHY2.js.map → chunk-CAZDRDQT.js.map} +0 -0
  583. /package/dist/{chunk-OK7BQMCI.js.map → chunk-CBJRZKZB.js.map} +0 -0
  584. /package/dist/{chunk-OYOFPNLC.js.map → chunk-CF6NYG7J.js.map} +0 -0
  585. /package/dist/{chunk-MT2R57SF.js.map → chunk-COITN7WN.js.map} +0 -0
  586. /package/dist/{chunk-OCXTTKVA.js.map → chunk-CPVOXM2Q.js.map} +0 -0
  587. /package/dist/{chunk-HYEIA25Y.js.map → chunk-CTZRCBKH.js.map} +0 -0
  588. /package/dist/{chunk-OCXEY7HE.js.map → chunk-CWL27YTB.js.map} +0 -0
  589. /package/dist/{chunk-K4DQS2ML.js.map → chunk-D2I33V5P.js.map} +0 -0
  590. /package/dist/{chunk-736RUNIA.js.map → chunk-DF7WI4JH.js.map} +0 -0
  591. /package/dist/{chunk-KUE5BOQE.js.map → chunk-DKZYCJCO.js.map} +0 -0
  592. /package/dist/{chunk-74CBR5YE.js.map → chunk-DQ32FKFQ.js.map} +0 -0
  593. /package/dist/{chunk-4O2XWOLZ.js.map → chunk-DTKG2YUF.js.map} +0 -0
  594. /package/dist/{chunk-GMHIOYB7.js.map → chunk-DUDA4V5R.js.map} +0 -0
  595. /package/dist/{chunk-XUOYNJPB.js.map → chunk-ECROT4M5.js.map} +0 -0
  596. /package/dist/{chunk-PVB4YVDP.js.map → chunk-EOXV5XGY.js.map} +0 -0
  597. /package/dist/{chunk-U6552Q3T.js.map → chunk-EQQOZ6DD.js.map} +0 -0
  598. /package/dist/{chunk-G6ICCGJ3.js.map → chunk-EY6W5H4B.js.map} +0 -0
  599. /package/dist/{chunk-HWVPLFIW.js.map → chunk-EYRFEWXJ.js.map} +0 -0
  600. /package/dist/{chunk-U4LTPFD2.js.map → chunk-FKK2PD7K.js.map} +0 -0
  601. /package/dist/{chunk-PUUEI4W3.js.map → chunk-FPHHIC5K.js.map} +0 -0
  602. /package/dist/{chunk-SP44O3OU.js.map → chunk-FQM6L22H.js.map} +0 -0
  603. /package/dist/{chunk-2J77TWGH.js.map → chunk-FW22IREV.js.map} +0 -0
  604. /package/dist/{chunk-EBIVTDEG.js.map → chunk-G4M6AYDB.js.map} +0 -0
  605. /package/dist/{chunk-BASI553K.js.map → chunk-G6AZ2WIU.js.map} +0 -0
  606. /package/dist/{chunk-SJYTQLN3.js.map → chunk-GJ5IDSAX.js.map} +0 -0
  607. /package/dist/{chunk-TDTD66BK.js.map → chunk-GRDSEZWZ.js.map} +0 -0
  608. /package/dist/{chunk-MV2CLIO6.js.map → chunk-HBVJIGY2.js.map} +0 -0
  609. /package/dist/{chunk-R4JA5JFI.js.map → chunk-HCWQLIOE.js.map} +0 -0
  610. /package/dist/{chunk-MZY3VKKM.js.map → chunk-HEVD4A5G.js.map} +0 -0
  611. /package/dist/{chunk-DLVIRJGK.js.map → chunk-HNDHSEVJ.js.map} +0 -0
  612. /package/dist/{chunk-LPKJ77EK.js.map → chunk-HNTZ7B7M.js.map} +0 -0
  613. /package/dist/{chunk-IN3VQFKS.js.map → chunk-I2FC7CAI.js.map} +0 -0
  614. /package/dist/{chunk-ZBHGNE2J.js.map → chunk-IEHZFYMH.js.map} +0 -0
  615. /package/dist/{chunk-DWJ6J3YW.js.map → chunk-IXISEVD7.js.map} +0 -0
  616. /package/dist/{chunk-TK5FWVZR.js.map → chunk-IZEDVQUD.js.map} +0 -0
  617. /package/dist/{chunk-HEGV4QMS.js.map → chunk-J42QE4VO.js.map} +0 -0
  618. /package/dist/{chunk-PRT4J2DL.js.map → chunk-J555XSUM.js.map} +0 -0
  619. /package/dist/{chunk-SBXSKRFA.js.map → chunk-JNMHFSDF.js.map} +0 -0
  620. /package/dist/{chunk-KI46GKMD.js.map → chunk-JTBAOPYO.js.map} +0 -0
  621. /package/dist/{chunk-SXGJL7UT.js.map → chunk-K376MPJH.js.map} +0 -0
  622. /package/dist/{chunk-OSJ366KR.js.map → chunk-KEBVT55V.js.map} +0 -0
  623. /package/dist/{chunk-U5UGM5XD.js.map → chunk-KFIZAXHI.js.map} +0 -0
  624. /package/dist/{chunk-KFNZZ2N6.js.map → chunk-KKGRDBMK.js.map} +0 -0
  625. /package/dist/{chunk-PLYVGZIN.js.map → chunk-KKIG6DN5.js.map} +0 -0
  626. /package/dist/{chunk-3OK7Y6ES.js.map → chunk-KKQO2GAA.js.map} +0 -0
  627. /package/dist/{chunk-DQPIEQGP.js.map → chunk-KO753ZCZ.js.map} +0 -0
  628. /package/dist/{chunk-YNTLWCF4.js.map → chunk-KYIRWU65.js.map} +0 -0
  629. /package/dist/{chunk-JKL5S7UQ.js.map → chunk-L6V63DVI.js.map} +0 -0
  630. /package/dist/{chunk-CV4VVLPZ.js.map → chunk-LCNJ2KNS.js.map} +0 -0
  631. /package/dist/{chunk-D74Z2N4K.js.map → chunk-LE7YKMTU.js.map} +0 -0
  632. /package/dist/{chunk-D5TIVCXG.js.map → chunk-LEBEOMVT.js.map} +0 -0
  633. /package/dist/{embedded-new-voice-GHJRY3YL.js.map → chunk-LKLQVANM.js.map} +0 -0
  634. /package/dist/{chunk-WXF2RTS4.js.map → chunk-M6URPYUB.js.map} +0 -0
  635. /package/dist/{chunk-H6BX6WOW.js.map → chunk-MDHFMRBC.js.map} +0 -0
  636. /package/dist/{chunk-3CDJSKDW.js.map → chunk-MGZO7CHI.js.map} +0 -0
  637. /package/dist/{chunk-DCEQCGVN.js.map → chunk-MIWU52TW.js.map} +0 -0
  638. /package/dist/{chunk-LVELUUK6.js.map → chunk-NF6QVVMP.js.map} +0 -0
  639. /package/dist/{chunk-UMX6DZME.js.map → chunk-NTZ5ZNVK.js.map} +0 -0
  640. /package/dist/{chunk-FBA2NXYH.js.map → chunk-NWLRABUR.js.map} +0 -0
  641. /package/dist/{chunk-TNSJFZ6Q.js.map → chunk-O2H2U7YS.js.map} +0 -0
  642. /package/dist/{chunk-BFFNINCC.js.map → chunk-OAL2PPX4.js.map} +0 -0
  643. /package/dist/{chunk-WTSQUCHB.js.map → chunk-OCYTHZ4A.js.map} +0 -0
  644. /package/dist/{chunk-ZAX4XQLN.js.map → chunk-OEDTCIXF.js.map} +0 -0
  645. /package/dist/{chunk-CHU3RDV4.js.map → chunk-OLVSYB3P.js.map} +0 -0
  646. /package/dist/{chunk-IFSXVU2S.js.map → chunk-OQHTFOCA.js.map} +0 -0
  647. /package/dist/{chunk-OXQ2SXVC.js.map → chunk-P56AVROH.js.map} +0 -0
  648. /package/dist/{chunk-CXAN2FHF.js.map → chunk-PCEJHHGP.js.map} +0 -0
  649. /package/dist/{chunk-5MIBQ4P5.js.map → chunk-PHGQGVVL.js.map} +0 -0
  650. /package/dist/{chunk-FLWQJDJ5.js.map → chunk-PUZRHEQI.js.map} +0 -0
  651. /package/dist/{chunk-OP2GD6QW.js.map → chunk-PV7U6OOJ.js.map} +0 -0
  652. /package/dist/{chunk-X2QJXDE4.js.map → chunk-PZQACDH5.js.map} +0 -0
  653. /package/dist/{chunk-CH4UQ4NO.js.map → chunk-PZTS4O6E.js.map} +0 -0
  654. /package/dist/{chunk-TKQL7EDB.js.map → chunk-Q42QHUAQ.js.map} +0 -0
  655. /package/dist/{chunk-MRECRNVU.js.map → chunk-QCYGB6TZ.js.map} +0 -0
  656. /package/dist/{chunk-GSCGKJNK.js.map → chunk-QECMETOF.js.map} +0 -0
  657. /package/dist/{chunk-RMCLFSMX.js.map → chunk-QGX3LE6H.js.map} +0 -0
  658. /package/dist/{chunk-HTMQGS63.js.map → chunk-QI3NDQFP.js.map} +0 -0
  659. /package/dist/{chunk-R5QAL43H.js.map → chunk-RA3Q52O2.js.map} +0 -0
  660. /package/dist/{chunk-AJDGP2N4.js.map → chunk-RJNOQEJJ.js.map} +0 -0
  661. /package/dist/{chunk-477DTTMH.js.map → chunk-RSFOFUR7.js.map} +0 -0
  662. /package/dist/{chunk-JV5ULONH.js.map → chunk-RXR6PMSH.js.map} +0 -0
  663. /package/dist/{chunk-J2BTILRR.js.map → chunk-SM7HFCGC.js.map} +0 -0
  664. /package/dist/{chunk-OBGOLHCP.js.map → chunk-T4HK4XCI.js.map} +0 -0
  665. /package/dist/{chunk-XVLEBB4Y.js.map → chunk-TBWL6YWL.js.map} +0 -0
  666. /package/dist/{chunk-AAS7OWV6.js.map → chunk-TIDXYWFX.js.map} +0 -0
  667. /package/dist/{chunk-N3FM4BNA.js.map → chunk-TKHRGY2P.js.map} +0 -0
  668. /package/dist/{chunk-GU7T2S5N.js.map → chunk-TU2GSZL7.js.map} +0 -0
  669. /package/dist/{chunk-OI6VI6SU.js.map → chunk-U6HGJXXQ.js.map} +0 -0
  670. /package/dist/{chunk-4BWMAGJJ.js.map → chunk-UGRW6RTR.js.map} +0 -0
  671. /package/dist/{chunk-AVXDIRRW.js.map → chunk-UMRUDYUK.js.map} +0 -0
  672. /package/dist/{chunk-FNXCFIPW.js.map → chunk-UOT2R5ZD.js.map} +0 -0
  673. /package/dist/{chunk-DIP7YALH.js.map → chunk-USURKJVT.js.map} +0 -0
  674. /package/dist/{chunk-S27VZ5DO.js.map → chunk-UU6Q67XM.js.map} +0 -0
  675. /package/dist/{chunk-LTJFV2JI.js.map → chunk-UZ7NP5CW.js.map} +0 -0
  676. /package/dist/{chunk-H6MJFMHZ.js.map → chunk-V4FO7UOE.js.map} +0 -0
  677. /package/dist/{chunk-RGR57NYY.js.map → chunk-V4ZOZRCW.js.map} +0 -0
  678. /package/dist/{chunk-LQKVNREV.js.map → chunk-V57YMKQZ.js.map} +0 -0
  679. /package/dist/{chunk-XZCCEKPW.js.map → chunk-VOIWZBY6.js.map} +0 -0
  680. /package/dist/{chunk-E5KOWRDU.js.map → chunk-VPHPLPDA.js.map} +0 -0
  681. /package/dist/{chunk-OGU73VUN.js.map → chunk-VUL4KPUU.js.map} +0 -0
  682. /package/dist/{chunk-SFIXTOOJ.js.map → chunk-VWF6ILAR.js.map} +0 -0
  683. /package/dist/{chunk-FER6EVIY.js.map → chunk-W54BHJO7.js.map} +0 -0
  684. /package/dist/{chunk-34NV52R3.js.map → chunk-WCYE4BLC.js.map} +0 -0
  685. /package/dist/{chunk-RISUROBM.js.map → chunk-WTV25ELY.js.map} +0 -0
  686. /package/dist/{chunk-UO35OEOX.js.map → chunk-WZYGH7CN.js.map} +0 -0
  687. /package/dist/{chunk-CEMSIU4Z.js.map → chunk-XG2RWUF7.js.map} +0 -0
  688. /package/dist/{chunk-K3D7IQQP.js.map → chunk-XV7QOT7W.js.map} +0 -0
  689. /package/dist/{chunk-GOCODNQS.js.map → chunk-XWECT3GX.js.map} +0 -0
  690. /package/dist/{chunk-5MHMCE2G.js.map → chunk-XZQK2ZLW.js.map} +0 -0
  691. /package/dist/{chunk-JV3UI7BH.js.map → chunk-Y5BR66OH.js.map} +0 -0
  692. /package/dist/{chunk-4F3AEJI6.js.map → chunk-YD6XU6FY.js.map} +0 -0
  693. /package/dist/{chunk-VATYK3JQ.js.map → chunk-YFE47G3C.js.map} +0 -0
  694. /package/dist/{chunk-ZR5EKJT6.js.map → chunk-YG6TWPP7.js.map} +0 -0
  695. /package/dist/{chunk-44JWVYJB.js.map → chunk-YH3ARKBB.js.map} +0 -0
  696. /package/dist/{chunk-752WXSDN.js.map → chunk-YI66STKJ.js.map} +0 -0
  697. /package/dist/{chunk-QRECBCJM.js.map → chunk-YMVPYMKB.js.map} +0 -0
  698. /package/dist/{chunk-77SYIH6O.js.map → chunk-YPIXBAF6.js.map} +0 -0
  699. /package/dist/{chunk-WRMUXZ7C.js.map → chunk-YSWPNY6G.js.map} +0 -0
  700. /package/dist/{chunk-GTHCHCWW.js.map → chunk-YWNNMBZG.js.map} +0 -0
  701. /package/dist/{chunk-3DRLCX5V.js.map → chunk-Z3HYM2JT.js.map} +0 -0
  702. /package/dist/{chunk-M3HGBO2Y.js.map → chunk-ZAC7YPRA.js.map} +0 -0
  703. /package/dist/{chunk-2VJOSU4H.js.map → chunk-ZENESDAF.js.map} +0 -0
  704. /package/dist/{chunk-4JXPLTWV.js.map → chunk-ZHAPMETO.js.map} +0 -0
  705. /package/dist/{chunk-IJR6VOLU.js.map → chunk-ZVR6DUZH.js.map} +0 -0
  706. /package/dist/{embedded-voice-ASQXBSTX.js.map → computer-viewer-FOIOZUF5.js.map} +0 -0
  707. /package/dist/{model-policy-picker-menu-E6XKMFTA.js.map → embedded-new-voice-WTXAJNGO.js.map} +0 -0
  708. /package/dist/{sandbox-files-W5W2LW4K.js.map → embedded-voice-SIJOPN2G.js.map} +0 -0
  709. /package/dist/{fleet-decision-row-U7LDVBEM.js.map → fleet-decision-row-XKQ3GMYT.js.map} +0 -0
  710. /package/dist/{latest-question-RNVF262Q.js.map → latest-question-KA7AQYVI.js.map} +0 -0
  711. /package/dist/{session-connect-cards-HPH7JOZP.js.map → model-policy-picker-menu-6N2G7VGX.js.map} +0 -0
  712. /package/dist/{payment-page-card-DJDKV2LW.js.map → payment-page-card-IJFZHQ52.js.map} +0 -0
  713. /package/dist/{platform-activity-row-MSDCSMET.js.map → platform-activity-row-MFCMGI43.js.map} +0 -0
  714. /package/dist/{queue-surface-implementation-GUAIG6TK.js.map → queue-surface-implementation-BBCDWWOP.js.map} +0 -0
  715. /package/dist/{recorder-host-2MYDJPQW.js.map → recorder-host-LDYYOKG7.js.map} +0 -0
  716. /package/dist/{session-realtime-SDTKFFIR.js.map → sandbox-files-VYRBIXJY.js.map} +0 -0
  717. /package/dist/{timeline-annotation-markers-FNILLWNU.js.map → timeline-annotation-markers-LL6ZVBZH.js.map} +0 -0
  718. /package/dist/{timeline-annotation-selection-MBCIDO2Q.js.map → timeline-annotation-selection-WQA76WYC.js.map} +0 -0
  719. /package/dist/{timeline-annotations-dialog-JPNKLOTE.js.map → timeline-annotations-dialog-HHETAEZA.js.map} +0 -0
@@ -1503,6 +1503,44 @@ describe("Meeting page", () => {
1503
1503
  }
1504
1504
  });
1505
1505
 
1506
+ test("a delayed subscription plan refusal offers upgrading, not adding credits", async () => {
1507
+ const fixture = createMeetingsFixture();
1508
+ const client = {
1509
+ ...fixture.client,
1510
+ getRecording: async (workspaceId: string, id: string) => {
1511
+ const recording = await fixture.client.getRecording(workspaceId, id);
1512
+ return {
1513
+ ...recording,
1514
+ transcript: { ...recording.transcript!, errorCode: "subscription_plan_required" },
1515
+ };
1516
+ },
1517
+ } as typeof fixture.client;
1518
+ let opened = 0;
1519
+ const view = await render(
1520
+ <MeetingDetailPage
1521
+ workspaceId={fixture.workspaceId}
1522
+ recordingId={FAILED_RECORDING_ID}
1523
+ viewerSubjectId={fixture.viewerSubjectId}
1524
+ recordings={client}
1525
+ onBack={() => {}}
1526
+ onOpenBilling={() => {
1527
+ opened++;
1528
+ }}
1529
+ />,
1530
+ );
1531
+ try {
1532
+ await waitForText(view.container, "Upgrade to Pro to use your own subscription.");
1533
+ const buttons = [...view.container.querySelectorAll("button")];
1534
+ expect(buttons.some((button) => button.textContent?.trim() === "Add credits")).toBe(false);
1535
+ const upgrade = buttons.find((button) => button.textContent?.trim() === "Upgrade to Pro")!;
1536
+ expect(upgrade).toBeDefined();
1537
+ await act(async () => upgrade.click());
1538
+ expect(opened).toBe(1);
1539
+ } finally {
1540
+ await view.unmount();
1541
+ }
1542
+ });
1543
+
1506
1544
  /** The fixture's failed meeting, refused for credits on the deployment's model. */
1507
1545
  async function creditRefusal(withSubscription: boolean) {
1508
1546
  const fixture = createMeetingsFixture();
@@ -42,9 +42,14 @@ export type MeetingRecorder = UseRecorderResult;
42
42
  * A recording someone asked for outside the recorder, such as from a desktop
43
43
  * call notification. An empty title leaves the name to Opengeni; `app` marks
44
44
  * a title the app guessed (the call app's name), which a calendar event or
45
- * the conversation replaces.
45
+ * the conversation replaces. `calendarEvent` is the owner's calendar event
46
+ * the meeting is of, such as one joined from a reminder; it names the meeting.
46
47
  */
47
- export type MeetingStartRequest = { title: string; titleSource?: "person" | "app" };
48
+ export type MeetingStartRequest = {
49
+ title: string;
50
+ titleSource?: "person" | "app";
51
+ calendarEvent?: { provider: "google" | "microsoft"; id: string };
52
+ };
48
53
 
49
54
  export type MeetingRecorderStore = {
50
55
  get: () => MeetingRecorder | null;
@@ -280,10 +285,28 @@ function useDesktopMeetingRequests(
280
285
  // Nobody signed in: a start kept for later would record, for whoever
281
286
  // signs in next, a call that may be long over.
282
287
  if (latest.current.signedOut) return;
283
- // Already recording shows that recording rather than start a second one.
284
- // The call app's name is only a guess at the meeting's.
288
+ // The call app's name is only a guess at the meeting's; the calendar
289
+ // event a reminder joined names it.
290
+ const start: MeetingStartRequest = {
291
+ title: request.title,
292
+ titleSource: "app",
293
+ ...(request.calendarEvent ? { calendarEvent: request.calendarEvent } : {}),
294
+ };
295
+ // Already recording shows that recording rather than start a second
296
+ // one, unless the person chose to switch to recording the next meeting:
297
+ // this one stops and is kept, then the next starts.
285
298
  if (canStartRecording(recorder?.state)) {
286
- store.requestStart({ title: request.title, titleSource: "app" });
299
+ store.requestStart(start);
300
+ } else if (
301
+ request.replace === true &&
302
+ recorder &&
303
+ (recorder.state === "recording" || recorder.state === "paused")
304
+ ) {
305
+ // A stop that fails leaves that recording showing its error, and starts nothing.
306
+ void recorder.stop().then(
307
+ () => store.requestStart(start),
308
+ () => undefined,
309
+ );
287
310
  }
288
311
  latest.current.onOpenMeetings?.();
289
312
  return;
@@ -48,7 +48,7 @@ import { Notice } from "../ui/notice";
48
48
  import { cn } from "../app/lib/utils";
49
49
 
50
50
  import { formatClock, ownerLiveLaneName } from "../recordings";
51
- import type { MeetingRecorder } from "./recorder-context";
51
+ import type { MeetingRecorder, MeetingStartRequest } from "./recorder-context";
52
52
  import { canStartRecording } from "./recorder-state";
53
53
  import { LiveTranscript, liveStatus, type LiveTranscriptLine } from "./live-transcript";
54
54
  import { DETECT_LANGUAGE, meetingLanguageOptions } from "./meeting-languages";
@@ -618,7 +618,7 @@ function RecorderPanelContent({
618
618
  */
619
619
  autoStart?: {
620
620
  pending: boolean;
621
- take: () => { title: string; titleSource?: "person" | "app" } | null;
621
+ take: () => MeetingStartRequest | null;
622
622
  } | null;
623
623
  /** The host's own id for what new recordings belong to, such as a project. */
624
624
  externalRef?: string | null | undefined;
@@ -645,8 +645,15 @@ function RecorderPanelContent({
645
645
  const state = recorder?.state ?? "idle";
646
646
  const live = state === "recording" || state === "paused" || state === "stopping";
647
647
 
648
- /** `guess` is the app's name for the meeting, used only when nobody typed one. */
649
- const start = async (titleText: string = title, guess?: string) => {
648
+ /**
649
+ * `guess` is the app's name for the meeting, used only when nobody typed
650
+ * one; `calendarEvent` the calendar event it is of, which names it.
651
+ */
652
+ const start = async (
653
+ titleText: string = title,
654
+ guess?: string,
655
+ calendarEvent?: MeetingStartRequest["calendarEvent"],
656
+ ) => {
650
657
  if (!recorder) return;
651
658
  setErrorDismissed(false);
652
659
  const name = titleText.trim();
@@ -658,6 +665,7 @@ function RecorderPanelContent({
658
665
  systemAudio: tabAudio,
659
666
  ...(liveOn ? { liveTranscript: true } : {}),
660
667
  ...(externalRef ? { externalRef } : {}),
668
+ ...(calendarEvent ? { calendarEvent } : {}),
661
669
  // Names their microphone in the transcript when Opengeni has no name for them.
662
670
  ...(viewerName?.trim() ? { ownerName: viewerName } : {}),
663
671
  // Sent even when it's the workspace's, so this meeting keeps it.
@@ -679,7 +687,7 @@ function RecorderPanelContent({
679
687
  if (!request) return;
680
688
  // The call app's name is a guess: a title already typed wins over it.
681
689
  if (request.titleSource === "app") {
682
- void startRef.current(undefined, request.title);
690
+ void startRef.current(undefined, request.title, request.calendarEvent);
683
691
  return;
684
692
  }
685
693
  // A start without a title (the Start recording key) keeps one already typed, as the button does.
@@ -6,7 +6,11 @@ import { GlobalRegistrator } from "@happy-dom/global-registrator";
6
6
  import { act, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
7
7
  import { createRoot } from "react-dom/client";
8
8
 
9
- import type { MeetingRecorder, MeetingRecorderStore } from "./recorder-context";
9
+ import type {
10
+ MeetingRecorder,
11
+ MeetingRecorderStore,
12
+ MeetingStartRequest,
13
+ } from "./recorder-context";
10
14
 
11
15
  beforeAll(() => {
12
16
  GlobalRegistrator.register();
@@ -83,7 +87,17 @@ async function until(check: () => boolean) {
83
87
 
84
88
  type Desktop = {
85
89
  listener:
86
- | ((request: { kind: "record"; title?: string } | { kind: "stop" } | { kind: "open" }) => void)
90
+ | ((
91
+ request:
92
+ | {
93
+ kind: "record";
94
+ title?: string;
95
+ calendarEvent?: { provider: "google" | "microsoft"; id: string };
96
+ replace?: boolean;
97
+ }
98
+ | { kind: "stop" }
99
+ | { kind: "open" },
100
+ ) => void)
87
101
  | null;
88
102
  };
89
103
 
@@ -118,7 +132,7 @@ function mountProvider() {
118
132
  };
119
133
  const opened: string[] = [];
120
134
  const meetingsOpened: string[] = [];
121
- let pendingStart: () => boolean = () => false;
135
+ let pendingStart: () => MeetingStartRequest | null = () => null;
122
136
  let open: ((recordingId: string, workspaceId: string) => boolean) | null = null;
123
137
  function Probe() {
124
138
  const current = useMeetingRecorder();
@@ -129,23 +143,24 @@ function mountProvider() {
129
143
  }
130
144
  function PendingStart() {
131
145
  const { take } = usePendingMeetingStart();
132
- pendingStart = () => take() !== null;
146
+ pendingStart = take;
133
147
  return null;
134
148
  }
135
149
  const container = document.createElement("div");
136
150
  document.body.append(container);
137
151
  const root = createRoot(container);
138
- return {
152
+ const view = {
139
153
  seen,
140
154
  opened,
141
155
  meetingsOpened,
142
156
  // Taking the pending start clears provider state, so it runs inside act.
143
- takePendingStart: () => {
144
- let taken = false;
157
+ takePendingStart: () => view.takePendingRequest() !== null,
158
+ takePendingRequest: () => {
159
+ let taken: MeetingStartRequest | null = null;
145
160
  act(() => {
146
161
  taken = pendingStart();
147
162
  });
148
- return taken;
163
+ return taken as MeetingStartRequest | null;
149
164
  },
150
165
  open: (recordingId: string, workspaceId: string) => open!(recordingId, workspaceId),
151
166
  render: (workspaceId: string | null, options: { scope?: string | null } = {}) =>
@@ -170,6 +185,7 @@ function mountProvider() {
170
185
  container.remove();
171
186
  },
172
187
  };
188
+ return view;
173
189
  }
174
190
 
175
191
  describe("A recording and the workspace it was made in", () => {
@@ -423,4 +439,37 @@ describe("A recording and the person who made it", () => {
423
439
  removeDesktop();
424
440
  }
425
441
  });
442
+ test("a reminder's Join and record this one stops the recording, then starts the next meeting's", async () => {
443
+ events.length = 0;
444
+ const desktop = installDesktop();
445
+ const view = mountProvider();
446
+ try {
447
+ await view.render("workspace-a");
448
+ await until(() => view.seen.recorder !== null);
449
+ await settle();
450
+ await act(async () => setStates.get("workspace-a")!("recording"));
451
+ const calendarEvent = { provider: "google" as const, id: "event-2" };
452
+ // Without replace, a reminder's Join shows the recording going on.
453
+ await act(async () =>
454
+ desktop.listener!({ kind: "record", title: "Planning", calendarEvent }),
455
+ );
456
+ expect(view.takePendingRequest()).toBeNull();
457
+ expect(view.seen.recorder?.state).toBe("recording");
458
+ // With it, the recording stops and is kept, then the next one starts for its event.
459
+ await act(async () =>
460
+ desktop.listener!({ kind: "record", title: "Planning", calendarEvent, replace: true }),
461
+ );
462
+ await settle();
463
+ expect(view.seen.recorder?.state).toBe("stopped");
464
+ expect(view.takePendingRequest()).toEqual({
465
+ title: "Planning",
466
+ titleSource: "app",
467
+ calendarEvent,
468
+ });
469
+ expect(view.meetingsOpened).toEqual(["workspace-a", "workspace-a"]);
470
+ } finally {
471
+ await view.unmount();
472
+ removeDesktop();
473
+ }
474
+ });
426
475
  });
@@ -2524,6 +2524,7 @@ export const englishMessages = {
2524
2524
  "meetings.detailPage.aboutLessThan001": "Less than $0.01 for this {duration} meeting.",
2525
2525
  "meetings.detailPage.aboutThisTranscript": "About this transcript",
2526
2526
  "meetings.detailPage.addCredits": "Add credits",
2527
+ "meetings.detailPage.upgradeToPro": "Upgrade to Pro",
2527
2528
  "meetings.detailPage.auto": "Auto",
2528
2529
  "meetings.detailPage.backToMeetings": "Back to Meetings",
2529
2530
  "meetings.detailPage.canTLoadThePreview": "Can't show the live text right now",
@@ -2945,6 +2946,8 @@ export const englishMessages = {
2945
2946
  "The credit allowance is used up for now. An admin can raise it, or transcribe with a model that doesn't use credits.",
2946
2947
  "meetings.recordings.errorMonthlyCostLimit":
2947
2948
  "This organization has reached its monthly spending limit. An admin can raise it, or transcribe with a model that doesn't use credits.",
2949
+ "meetings.recordings.errorSubscriptionApiUnavailable":
2950
+ "Connected subscriptions aren't available through the API. Choose a credit-billed model.",
2948
2951
  "meetings.recordings.errorPolicyBlocked":
2949
2952
  "This organization's policy doesn't allow this model. Try another model.",
2950
2953
  "meetings.recordings.errorTimedOut":
@@ -3740,6 +3743,7 @@ export const englishMessages = {
3740
3743
  "native.timeline.messages.onAMachine": "On a machine",
3741
3744
  "native.timeline.messages.output": "Output",
3742
3745
  "native.timeline.messages.pauseGoal": "Pause goal",
3746
+ "native.timeline.messages.paused": "Paused",
3743
3747
  "native.timeline.messages.pin": "Pin",
3744
3748
  "native.timeline.messages.pinned": "Pinned",
3745
3749
  "native.timeline.messages.proposedKnowledge": "Proposed knowledge",
@@ -6081,6 +6085,7 @@ export const englishMessages = {
6081
6085
  "timeline.turnSummary.contextCompactedExpandForDetails": "Context compacted; expand for details",
6082
6086
  "timeline.turnSummary.copyTurn": "Copy turn",
6083
6087
  "timeline.turnSummary.interrupted": "· interrupted",
6088
+ "timeline.turnSummary.paused": "Paused",
6084
6089
  "timeline.turnSummary.preparation": "Preparation",
6085
6090
  "timeline.turnSummary.steps": "Steps",
6086
6091
  "timeline.turnSummary.waiting": "Waiting",
@@ -175,6 +175,7 @@ const PROVIDER_FAILURES = new Set([
175
175
  "provider_unauthorized",
176
176
  "provider_quota_exceeded",
177
177
  "policy_blocked",
178
+ "subscription_api_unavailable",
178
179
  ]);
179
180
  /** Failures of the model: another model, even the same provider's, may work. */
180
181
  const MODEL_FAILURES = new Set([
@@ -211,6 +212,8 @@ export function transcriptFixModel(
211
212
  : 2;
212
213
  const candidates = models.filter((entry) => {
213
214
  if (!entry.available || !entry.capabilities.batch) return false;
215
+ if (code === "subscription_api_unavailable" && entry.funding === "workspace_subscription")
216
+ return false;
214
217
  if (failed && entry.providerId === failed.providerId) {
215
218
  if (!MODEL_FAILURES.has(code) || entry.model === failed.model) return false;
216
219
  }
@@ -259,6 +262,10 @@ export function transcriptErrorText(
259
262
  } | null,
260
263
  ): string {
261
264
  switch (code) {
265
+ case "subscription_plan_required":
266
+ return msg("lib.format.subscriptionUpgradeRequiredHeadline");
267
+ case "subscription_api_unavailable":
268
+ return msg("meetings.recordings.errorSubscriptionApiUnavailable");
262
269
  case "missing_provider_key": {
263
270
  if (!model) return msg("meetings.recordings.errorMissingProviderKey");
264
271
  const names = { modelName: model.modelName, providerName: model.providerName };
package/src/session.ts CHANGED
@@ -141,9 +141,16 @@ export {
141
141
  extractSessionRef,
142
142
  groupTimeline,
143
143
  sessionStatusFromEvents,
144
+ timelineLivePause,
145
+ timelinePauseSpans,
144
146
  toolDisplayName,
145
147
  } from "./timeline/projection";
146
- export type { GroupTimelineOptions } from "./timeline/projection";
148
+ export type {
149
+ GroupTimelineOptions,
150
+ TimelineLivePause,
151
+ TimelinePauseSpan,
152
+ } from "./timeline/projection";
153
+ export { useTimelinePauses } from "./timeline/use-timeline-pauses";
147
154
  export type {
148
155
  ActivityItem,
149
156
  AgentMessageItem,
@@ -24,10 +24,13 @@ export {
24
24
  groupTimeline,
25
25
  sessionStatusFromEvents,
26
26
  mcpToolLeaf,
27
+ timelineLivePause,
28
+ timelinePauseSpans,
27
29
  toolDisplayName,
28
30
  toolMatchesLeaf,
29
31
  } from "./projection";
30
- export type { GroupTimelineOptions } from "./projection";
32
+ export type { GroupTimelineOptions, TimelineLivePause, TimelinePauseSpan } from "./projection";
33
+ export { useTimelinePauses } from "./use-timeline-pauses";
31
34
 
32
35
  // item types
33
36
  export type {
@@ -2482,6 +2482,184 @@ export function sessionStatusFromEvents(events: SessionEvent[]): SessionStatus |
2482
2482
  return null;
2483
2483
  }
2484
2484
 
2485
+ /**
2486
+ * A span in which the session's work was paused: by Pause of the chat, of
2487
+ * an ancestor, or of the workspace. An open span (no `endedAt`) is a pause
2488
+ * still in force.
2489
+ */
2490
+ export type TimelinePauseSpan = { startedAt: string; endedAt?: string };
2491
+
2492
+ /**
2493
+ * The host's live view of the session's Pause, from its effective control.
2494
+ * `since` is when the pause in force began, when known. `resumedAt` is when
2495
+ * the host saw the pause end, for a resume whose events have not arrived.
2496
+ */
2497
+ export type TimelineLivePause = {
2498
+ paused: boolean;
2499
+ since?: string | null | undefined;
2500
+ resumedAt?: string | null | undefined;
2501
+ };
2502
+
2503
+ /** Interruption reasons that park a turn for Resume rather than end it. */
2504
+ const PAUSE_INTERRUPTION_REASONS: ReadonlySet<unknown> = new Set([
2505
+ "session_pause",
2506
+ "workspace_pause",
2507
+ ]);
2508
+
2509
+ type LivePauseBlocker = { changedAt?: string | null | undefined };
2510
+
2511
+ /**
2512
+ * The live pause from an effective session control; undefined when it is
2513
+ * unknown. A pause in force since several blockers took hold began with the
2514
+ * earliest of them.
2515
+ */
2516
+ export function timelineLivePause(
2517
+ control:
2518
+ | {
2519
+ state: string;
2520
+ primaryBlocker?: LivePauseBlocker | null | undefined;
2521
+ blockers?: readonly LivePauseBlocker[] | null | undefined;
2522
+ }
2523
+ | null
2524
+ | undefined,
2525
+ ): TimelineLivePause | undefined {
2526
+ if (!control) return undefined;
2527
+ if (control.state !== "paused") return { paused: false };
2528
+ let since: string | null = null;
2529
+ for (const blocker of [control.primaryBlocker, ...(control.blockers ?? [])]) {
2530
+ const changedAt = blocker?.changedAt;
2531
+ if (changedAt && (since === null || Date.parse(changedAt) < Date.parse(since)))
2532
+ since = changedAt;
2533
+ }
2534
+ return { paused: true, since };
2535
+ }
2536
+
2537
+ /** Events that start or end a pause span. */
2538
+ const PAUSE_EVENT_TYPES: ReadonlySet<string> = new Set([
2539
+ "session.control.paused",
2540
+ "session.control.resumed",
2541
+ "turn.recovery.requested",
2542
+ "session.status.changed",
2543
+ "turn.started",
2544
+ ]);
2545
+
2546
+ /**
2547
+ * When the session's work was paused, from its events and (when the host
2548
+ * knows it) its live control.
2549
+ *
2550
+ * Pause parks the running turn for Resume instead of ending it, so the turn
2551
+ * stays open. A direct Pause records `session.control.paused`; a Pause of an
2552
+ * ancestor or of the workspace reaches the chat only as the interruption
2553
+ * (`turn.recovery.requested` with a pause reason) and the parked idle status.
2554
+ * Work resumes with `session.control.resumed`, or when the turn runs again.
2555
+ * A wait that a pause held without interrupting anything has no events at
2556
+ * all, so the live control decides whether a pause is in force now, and
2557
+ * `observed` carries pauses the host saw begin and end only through it.
2558
+ */
2559
+ export function timelinePauseSpans(
2560
+ events: readonly SessionEvent[],
2561
+ live?: TimelineLivePause | null,
2562
+ observed: readonly TimelinePauseSpan[] = [],
2563
+ ): TimelinePauseSpan[] {
2564
+ let latest: SessionEvent | undefined;
2565
+ const relevant: SessionEvent[] = [];
2566
+ for (const event of events) {
2567
+ if (!latest || event.sequence > latest.sequence) latest = event;
2568
+ if (PAUSE_EVENT_TYPES.has(event.type)) relevant.push(event);
2569
+ }
2570
+ relevant.sort((left, right) => left.sequence - right.sequence);
2571
+ const spans: TimelinePauseSpan[] = [];
2572
+ let open: TimelinePauseSpan | null = null;
2573
+ // Cancel also leaves the control paused while the turn winds down; that is
2574
+ // not a pause of the work, which is ending.
2575
+ let cancelling = false;
2576
+ for (const event of relevant) {
2577
+ const payload = asRecord(event.payload);
2578
+ if (
2579
+ (event.type === "session.control.paused" && payload.terminal === true) ||
2580
+ // A parent's Cancel reaches its sub-chats as their status alone.
2581
+ (event.type === "session.status.changed" && payload.status === "cancelled")
2582
+ ) {
2583
+ cancelling = true;
2584
+ continue;
2585
+ }
2586
+ const starts =
2587
+ event.type === "session.control.paused" ||
2588
+ (event.type === "turn.recovery.requested" &&
2589
+ PAUSE_INTERRUPTION_REASONS.has(payload.reason)) ||
2590
+ (event.type === "session.status.changed" &&
2591
+ payload.status === "idle" &&
2592
+ payload.reason === "paused_recovery_settled");
2593
+ if (starts) {
2594
+ open ??= { startedAt: event.occurredAt };
2595
+ continue;
2596
+ }
2597
+ if (
2598
+ event.type === "session.control.resumed" ||
2599
+ event.type === "turn.started" ||
2600
+ (event.type === "session.status.changed" && payload.status === "running")
2601
+ ) {
2602
+ cancelling = false;
2603
+ if (open) {
2604
+ spans.push({ startedAt: open.startedAt, endedAt: event.occurredAt });
2605
+ open = null;
2606
+ }
2607
+ }
2608
+ }
2609
+ const latestAt = latest?.occurredAt;
2610
+ if (live?.paused && !cancelling) {
2611
+ const startedAt = open?.startedAt ?? live.since ?? latestAt;
2612
+ if (startedAt) spans.push({ startedAt });
2613
+ } else if (open) {
2614
+ if (live) {
2615
+ // The host already sees the session running again; its resume events
2616
+ // are still on their way. End the pause when the host saw it end.
2617
+ const endedAt = live.resumedAt ?? latestAt ?? open.startedAt;
2618
+ spans.push({
2619
+ startedAt: open.startedAt,
2620
+ endedAt: Date.parse(endedAt) > Date.parse(open.startedAt) ? endedAt : open.startedAt,
2621
+ });
2622
+ } else {
2623
+ spans.push(open);
2624
+ }
2625
+ }
2626
+ // A pause seen only through the live control, by the host's clock; skip it
2627
+ // where the events record the same pause.
2628
+ const recorded = [...spans];
2629
+ for (const span of observed) {
2630
+ if (!span.endedAt) continue;
2631
+ const start = Date.parse(span.startedAt);
2632
+ const end = Date.parse(span.endedAt);
2633
+ const overlaps = recorded.some(
2634
+ (other) =>
2635
+ Date.parse(other.startedAt) < end &&
2636
+ (other.endedAt === undefined || Date.parse(other.endedAt) > start),
2637
+ );
2638
+ if (!overlaps) spans.push(span);
2639
+ }
2640
+ return spans;
2641
+ }
2642
+
2643
+ /** Total length of the union of intervals, each clipped to `[from, to)`. */
2644
+ function unionLength(
2645
+ intervals: ReadonlyArray<readonly [number, number]>,
2646
+ from: number,
2647
+ to: number,
2648
+ ): number {
2649
+ const clipped = intervals
2650
+ .map(([start, end]) => [Math.max(start, from), Math.min(end, to)] as const)
2651
+ .filter(([start, end]) => Number.isFinite(start) && Number.isFinite(end) && end > start)
2652
+ .sort((left, right) => left[0] - right[0]);
2653
+ let total = 0;
2654
+ let cursor = Number.NEGATIVE_INFINITY;
2655
+ for (const [start, end] of clipped) {
2656
+ const begin = Math.max(start, cursor);
2657
+ if (end > begin) total += end - begin;
2658
+ cursor = Math.max(cursor, end);
2659
+ }
2660
+ return total;
2661
+ }
2662
+
2485
2663
  /* ----------------------------------------------------------------------------
2486
2664
  Visual grouping: consecutive activity items (reasoning / tools / workers /
2487
2665
  sandbox) cluster into collapsible blocks. Once a turn settles, the full
@@ -2549,6 +2727,12 @@ export type GroupTimelineOptions = {
2549
2727
  readableTurns?: boolean;
2550
2728
  /** @deprecated Use readableTurns. Cross-turn exchange folding has been removed. */
2551
2729
  foldExchanges?: boolean;
2730
+ /**
2731
+ * When the session was paused ({@link timelinePauseSpans}). A readable
2732
+ * turn still open under a pause in force reads as paused, and paused time
2733
+ * is not counted as work.
2734
+ */
2735
+ pauses?: readonly TimelinePauseSpan[];
2552
2736
  };
2553
2737
 
2554
2738
  export function groupTimeline(
@@ -2556,7 +2740,8 @@ export function groupTimeline(
2556
2740
  items: TimelineItem[],
2557
2741
  options: GroupTimelineOptions = {},
2558
2742
  ): TimelineGroup[] {
2559
- if (options.readableTurns || options.foldExchanges) return groupReadableTurns(t, items);
2743
+ if (options.readableTurns || options.foldExchanges)
2744
+ return groupReadableTurns(t, items, options.pauses ?? []);
2560
2745
  const groups: TimelineGroup[] = [];
2561
2746
  for (const item of items) {
2562
2747
  // A recovered capacity wait is over; it leaves no warning behind.
@@ -2585,7 +2770,11 @@ export function groupTimeline(
2585
2770
  }
2586
2771
 
2587
2772
  /** Live prose stays primary; settled progress joins its own turn's work history. */
2588
- function groupReadableTurns(t: OpenGeniText, items: TimelineItem[]): TimelineGroup[] {
2773
+ function groupReadableTurns(
2774
+ t: OpenGeniText,
2775
+ items: TimelineItem[],
2776
+ pauses: readonly TimelinePauseSpan[],
2777
+ ): TimelineGroup[] {
2589
2778
  type Work = Extract<TimelineGroup, { kind: "activity" }>;
2590
2779
  let groups: TimelineGroup[] = [];
2591
2780
  const turns = new Map<string, Work>();
@@ -2721,12 +2910,12 @@ function groupReadableTurns(t: OpenGeniText, items: TimelineItem[]): TimelineGro
2721
2910
  group.work!.details.push({ kind: "activity", id: `work-item-${item.id}`, items: [item] });
2722
2911
  delete group.work!.waiting;
2723
2912
  } else if (item.kind === "notice" && item.capacityWait) {
2724
- const pauses = idleSpans.get(key) ?? [];
2725
- pauses.push({
2913
+ const idle = idleSpans.get(key) ?? [];
2914
+ idle.push({
2726
2915
  startedAt: item.occurredAt,
2727
2916
  ...(item.resolvedAt ? { endedAt: item.resolvedAt } : {}),
2728
2917
  });
2729
- idleSpans.set(key, pauses);
2918
+ idleSpans.set(key, idle);
2730
2919
  if (!item.resolvedAt) {
2731
2920
  if (settlements.has(key)) groups.push({ kind: "item", item });
2732
2921
  else {
@@ -2842,6 +3031,7 @@ function groupReadableTurns(t: OpenGeniText, items: TimelineItem[]): TimelineGro
2842
3031
  ? t("timeline.projection.waitingForYou")
2843
3032
  : t("timeline.projection.waiting"),
2844
3033
  since: item.occurredAt,
3034
+ ...(item.approval === true ? { waitingOn: "you" as const } : {}),
2845
3035
  };
2846
3036
  } else if (
2847
3037
  item.kind === "session-status" &&
@@ -2852,6 +3042,7 @@ function groupReadableTurns(t: OpenGeniText, items: TimelineItem[]): TimelineGro
2852
3042
  current.waiting = {
2853
3043
  label: t("timeline.projection.waitingForYou"),
2854
3044
  since: item.occurredAt,
3045
+ waitingOn: "you",
2855
3046
  };
2856
3047
  } else if (
2857
3048
  item.kind === "session-status" &&
@@ -2890,17 +3081,38 @@ function groupReadableTurns(t: OpenGeniText, items: TimelineItem[]): TimelineGro
2890
3081
  untimed: true,
2891
3082
  };
2892
3083
  }
2893
- const pausedMs = (idleSpans.get(key) ?? []).reduce((total, pause) => {
2894
- if (!pause.endedAt) return total;
2895
- const start = Math.max(Date.parse(work.startedAt), Date.parse(pause.startedAt));
2896
- const end = Math.min(
2897
- work.endedAt ? Date.parse(work.endedAt) : Number.POSITIVE_INFINITY,
2898
- Date.parse(pause.endedAt),
2899
- );
2900
- return Number.isFinite(start) && Number.isFinite(end) && end > start
2901
- ? total + end - start
2902
- : total;
2903
- }, 0);
3084
+ const workStart = Date.parse(work.startedAt);
3085
+ const workEnd = work.endedAt ? Date.parse(work.endedAt) : Number.POSITIVE_INFINITY;
3086
+ // A pause still in force over this open turn: the turn is parked for
3087
+ // Resume, so it reads as paused and its clock stops when the pause began.
3088
+ // A wait on the person (an approval, a question) keeps saying so.
3089
+ const openPause =
3090
+ work.endedAt || work.waiting?.waitingOn === "you"
3091
+ ? undefined
3092
+ : pauses.find((pause) => !pause.endedAt && Date.parse(pause.startedAt) < workEnd);
3093
+ const pausedAt = openPause
3094
+ ? Math.max(workStart, Date.parse(openPause.startedAt))
3095
+ : Number.POSITIVE_INFINITY;
3096
+ if (openPause && Number.isFinite(pausedAt)) {
3097
+ work.pausedAt = new Date(pausedAt).toISOString();
3098
+ delete work.waiting;
3099
+ }
3100
+ // Capacity waits, failed-attempt gaps and pauses can overlap; their union
3101
+ // is time the agent was not working. A span still open runs to the end of
3102
+ // the work (a turn cancelled while paused) or to the pause that stopped
3103
+ // its clock; on a turn still running it has no end yet and counts later.
3104
+ const until = Math.min(workEnd, pausedAt);
3105
+ const pausedMs = unionLength(
3106
+ [...(idleSpans.get(key) ?? []), ...pauses].flatMap((span) =>
3107
+ span.endedAt
3108
+ ? [[Date.parse(span.startedAt), Date.parse(span.endedAt)] as const]
3109
+ : Number.isFinite(until)
3110
+ ? [[Date.parse(span.startedAt), until] as const]
3111
+ : [],
3112
+ ),
3113
+ workStart,
3114
+ until,
3115
+ );
2904
3116
  if (pausedMs > 0) work.pausedMs = pausedMs;
2905
3117
  }
2906
3118
  groups = groups.filter((entry) => {