@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
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/app/lib/session-pins.tsx"],"sourcesContent":["import type { Session as SessionDetails } from \"../types\";\n// Cross-tab invalidation for personal session pins. Postgres remains truth;\n// this message carries only workspace/session ids and tells sibling tabs to\n// re-read. Cross-device clients reconcile through the normal page refresh/poll.\n\nimport type { RailSession as Session } from \"./session-list-entry\";\n\nconst SESSION_PIN_CHANNEL_PREFIX = \"opengeni.session-pins\";\nconst SESSION_PIN_STORAGE_PREFIX = \"opengeni.session-pins.changed\";\nconst ACCEPTED_SESSION_CHANNEL_READ_SOFT_LIMIT = 512;\nconst outboundChannels = new Map<string, BroadcastChannel>();\n\ntype SessionTreeStats = NonNullable<Session[\"treeStats\"]>;\ntype SessionChannelProjection = Pick<Session, \"id\" | \"workspaceId\" | \"channelId\">;\ntype SessionChannelEvidence = [\n channelId: string | null,\n priority: number,\n readGeneration: number,\n retainsAcceptedRead?: boolean,\n];\ntype SessionChannelRead = [channelId: string | null, present: boolean, readGeneration: number];\ntype SessionChannelCommittedMove = [channelId: string | null, readGeneration: number];\ntype SessionChannelRetainedOwner = [\n channelId: string | null,\n readGeneration: number,\n blockingReads: Set<number>,\n];\ntype SessionChannelAcceptedRead = SessionChannelProjection & {\n readGeneration: number;\n};\nexport type SessionChannelMoveRequest = Readonly<{\n workspaceId: string;\n sessionId: string;\n operation: number;\n readGeneration: number;\n}>;\nexport type SessionChannelMoveResponseDisposition =\n | \"accepted\"\n | \"verification-required\"\n | \"rejected\";\n\nfunction sessionChannelProjectionKey(projection: Pick<Session, \"id\" | \"workspaceId\">): string {\n return `${projection.workspaceId}\\u0000${projection.id}`;\n}\n\n/**\n * Tracks list, exact-read, and settled-move ownership of channel projections\n * without putting browser-only provenance onto the public Session contract.\n */\nexport class SessionChannelProjectionAuthority {\n private readonly owners = new Map<object, Map<string, SessionChannelEvidence>>();\n private readonly reads = new Map<string, SessionChannelRead>();\n private readonly moves = new Map<string, SessionChannelCommittedMove>();\n private readonly retainedOwners = new Map<string, SessionChannelRetainedOwner>();\n private readonly detailReads = new Map<object, Map<number, string>>();\n private readonly listeners = new Set<(accepted?: SessionChannelAcceptedRead) => void>();\n private readonly requests = new Map<string, [owner: object, operation: number]>();\n private readClock = 0;\n private moveClock = 0;\n private revision = 0;\n\n readonly beginRead = (): number => ++this.readClock;\n\n /**\n * Register an exact/detail request whose delayed result can outlive a list\n * owner. One logical consumer keeps only its latest request generation; a\n * successor starts after the prior shared GET settled, so the older result\n * can no longer arrive and no longer blocks owner cleanup.\n */\n beginDetailRead(\n owner: object,\n projection: Pick<SessionChannelProjection, \"id\" | \"workspaceId\">,\n ): number {\n this.finishDetailReads(owner);\n const readGeneration = this.beginRead();\n this.detailReads.set(\n owner,\n new Map([[readGeneration, sessionChannelProjectionKey(projection)]]),\n );\n return readGeneration;\n }\n\n /** Retire every exact/detail request owned by one route or point probe. */\n finishDetailReads(owner: object): void {\n const reads = this.detailReads.get(owner);\n if (!reads) return;\n this.detailReads.delete(owner);\n const finished = new Set(reads.keys());\n for (const [key, retained] of this.retainedOwners) {\n for (const readGeneration of finished) retained[2].delete(readGeneration);\n if (retained[2].size === 0) this.retainedOwners.delete(key);\n }\n }\n\n /** React to persistent accepted server/write authority advancing. */\n readonly subscribe = (\n listener: (accepted?: SessionChannelAcceptedRead) => void,\n ): (() => void) => {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n };\n\n /** Reactive snapshot for consumers whose projected rows depend on persistent authority. */\n readonly getRevision = (): number => this.revision;\n\n /**\n * Persist one pending move across rail lifetimes. The same mounted owner\n * cannot duplicate its request; a new mount may supersede it with a new\n * explicit user intent, after which the older response loses authority.\n */\n beginMove(\n owner: object,\n projection: Pick<SessionChannelProjection, \"id\" | \"workspaceId\">,\n ): SessionChannelMoveRequest | null {\n const key = sessionChannelProjectionKey(projection);\n if (this.requests.get(key)?.[0] === owner) return null;\n const request = {\n workspaceId: projection.workspaceId,\n sessionId: projection.id,\n operation: ++this.moveClock,\n // A mutation response is evidence from the request start, not from the\n // later time at which its promise happens to settle.\n readGeneration: this.beginRead(),\n };\n this.requests.set(key, [owner, request.operation]);\n return request;\n }\n\n ownsMove(owner: object, request: SessionChannelMoveRequest): boolean {\n const current = this.requests.get(\n sessionChannelProjectionKey({ id: request.sessionId, workspaceId: request.workspaceId }),\n );\n return current?.[0] === owner && current[1] === request.operation;\n }\n\n recordMove(\n owner: object,\n request: SessionChannelMoveRequest,\n projection: SessionChannelProjection,\n ): SessionChannelMoveResponseDisposition {\n if (\n projection.id !== request.sessionId ||\n projection.workspaceId !== request.workspaceId ||\n !this.ownsMove(owner, request)\n ) {\n return \"rejected\";\n }\n const key = sessionChannelProjectionKey(projection);\n // Completed evidence newer than the mutation start may already be a\n // post-commit value, so only a fresh point read can choose between it and\n // this response. In either case retain exact B at a new settlement\n // generation: every overlapping read already has an older generation even\n // if it has not completed, and a rail unmount cannot discard this fence.\n const verificationRequired = this.highestGeneration(key) > request.readGeneration;\n const readGeneration = this.beginRead();\n this.moves.set(key, [projection.channelId ?? null, readGeneration]);\n this.publish({ ...projection, readGeneration });\n return verificationRequired ? \"verification-required\" : \"accepted\";\n }\n\n finishMove(owner: object, request: SessionChannelMoveRequest): void {\n if (!this.ownsMove(owner, request)) return;\n this.requests.delete(\n sessionChannelProjectionKey({ id: request.sessionId, workspaceId: request.workspaceId }),\n );\n }\n\n replace(\n owner: object,\n projections: readonly SessionChannelProjection[],\n priority = 0,\n readGeneration = 0,\n ): void {\n this.replaceOwner(\n owner,\n projections.map((projection) => [projection, readGeneration] as const),\n priority,\n );\n }\n\n replaceOwner(\n owner: object,\n evidence: readonly (readonly [projection: SessionChannelProjection, readGeneration: number])[],\n priority = 0,\n ): void {\n if (evidence.length === 0) {\n this.clear(owner);\n return;\n }\n const next = new Map<string, SessionChannelEvidence>();\n for (const [projection, readGeneration] of evidence) {\n const key = sessionChannelProjectionKey(projection);\n next.set(key, [projection.channelId ?? null, priority, readGeneration]);\n }\n const previous = this.owners.get(owner);\n if (previous) this.retainOwner(previous, next);\n this.owners.set(owner, next);\n if (priority === 0) {\n for (const [projection] of evidence) {\n const key = sessionChannelProjectionKey(projection);\n const candidate = next.get(key);\n const committedMove = this.moves.get(key);\n // Current server-owned page/lineage evidence is as authoritative as an\n // exact read for channel filing when its request actually started after\n // the successful move settled. Promote it persistently before retiring\n // B so owner cleanup/remount cannot revive either B or a pre-move A.\n if (candidate && committedMove && candidate[2] > committedMove[1]) {\n this.recordObservation(projection, candidate[2], true);\n }\n }\n }\n this.compact();\n }\n\n clear(owner: object): void {\n const previous = this.owners.get(owner);\n if (previous) this.retainOwner(previous);\n this.owners.delete(owner);\n }\n\n /** Drop browser-only evidence when its workspace principal/route fence is retired. */\n clearWorkspace(workspaceId: string): void {\n const prefix = `${workspaceId}\\u0000`;\n for (const key of this.reads.keys()) {\n if (!key.startsWith(prefix)) continue;\n this.reads.delete(key);\n }\n for (const [owner, projections] of this.owners) {\n for (const key of projections.keys()) {\n if (key.startsWith(prefix)) projections.delete(key);\n }\n if (projections.size === 0) this.owners.delete(owner);\n }\n for (const key of this.requests.keys()) {\n if (key.startsWith(prefix)) this.requests.delete(key);\n }\n for (const key of this.moves.keys()) {\n if (key.startsWith(prefix)) this.moves.delete(key);\n }\n for (const key of this.retainedOwners.keys()) {\n if (key.startsWith(prefix)) this.retainedOwners.delete(key);\n }\n for (const [owner, reads] of this.detailReads) {\n for (const [readGeneration, key] of reads) {\n if (key.startsWith(prefix)) reads.delete(readGeneration);\n }\n if (reads.size === 0) this.detailReads.delete(owner);\n }\n }\n\n /** Retain an accepted exact/detail read so older list requests cannot revive stale filing. */\n recordRead(projection: SessionChannelProjection, readGeneration: number): boolean {\n return this.recordObservation(projection, readGeneration, true);\n }\n\n /** Fence a not-found point read without treating absence as a channel projection. */\n recordMissing(\n projection: Pick<SessionChannelProjection, \"id\" | \"workspaceId\">,\n readGeneration: number,\n ): boolean {\n return this.recordObservation(projection, readGeneration, false);\n }\n\n private recordObservation(\n projection: Pick<SessionChannelProjection, \"id\" | \"workspaceId\"> &\n Partial<Pick<SessionChannelProjection, \"channelId\">>,\n readGeneration: number,\n present: boolean,\n ): boolean {\n if (readGeneration <= 0) return false;\n const key = sessionChannelProjectionKey(projection);\n if (this.highestGeneration(key) > readGeneration) return false;\n const retainedOwner = this.retainedOwners.get(key);\n if (retainedOwner && retainedOwner[1] <= readGeneration) {\n this.retainedOwners.delete(key);\n }\n const committedMove = this.moves.get(key);\n // Only accepted server evidence that started after settlement can choose\n // B, a genuinely newer C, or deletion and retire the persistent move\n // fence. Point/detail reads arrive here directly; current priority-0 list\n // owners are promoted by replaceOwner after the same causal check.\n if (committedMove && readGeneration > committedMove[1]) {\n this.moves.delete(key);\n }\n // Refresh iteration order when exact evidence for one session advances so\n // compaction considers genuinely older observations first.\n for (const projections of this.owners.values()) {\n const candidate = projections.get(key);\n if (candidate) candidate[3] = false;\n }\n this.reads.delete(key);\n this.reads.set(key, [projection.channelId ?? null, present, readGeneration]);\n this.compact();\n const accepted = present\n ? {\n id: projection.id,\n workspaceId: projection.workspaceId,\n channelId: projection.channelId ?? null,\n readGeneration,\n }\n : undefined;\n this.publish(accepted);\n return true;\n }\n\n private publish(accepted?: SessionChannelAcceptedRead): void {\n this.revision += 1;\n for (const listener of this.listeners) listener(accepted);\n }\n\n /**\n * Transfer a priority-0 owner's newest value before cleanup when compaction\n * already delegated an accepted fence or an older exact request for the same\n * session can still arrive. Request-causal transfers are released with their\n * blocker; optimistic priority owners are never promoted.\n */\n private retainOwner(\n previous: ReadonlyMap<string, SessionChannelEvidence>,\n replacement: ReadonlyMap<string, SessionChannelEvidence> = new Map(),\n ): void {\n for (const [key, candidate] of previous) {\n const retainsAcceptedRead = candidate[3] === true;\n candidate[3] = false;\n const next = replacement.get(key);\n if (retainsAcceptedRead && next && next[1] === 0 && next[2] >= candidate[2]) {\n next[3] = true;\n continue;\n }\n if (candidate[1] !== 0) continue;\n const newerOwner = this.highestOwnerEvidence(key, previous, replacement);\n if (newerOwner && newerOwner[2] >= candidate[2]) continue;\n if (this.highestPersistentGeneration(key) >= candidate[2]) continue;\n if (retainsAcceptedRead) {\n this.retainedOwners.delete(key);\n this.reads.set(key, [candidate[0], true, candidate[2]]);\n continue;\n }\n const blockingReads = this.blockingDetailReads(key, candidate[2]);\n if (blockingReads.size === 0) continue;\n this.retainedOwners.set(key, [candidate[0], candidate[2], blockingReads]);\n }\n }\n\n private highestOwnerEvidence(\n key: string,\n previous: ReadonlyMap<string, SessionChannelEvidence>,\n replacement: ReadonlyMap<string, SessionChannelEvidence>,\n ): SessionChannelEvidence | undefined {\n let highest = replacement.get(key);\n if (highest?.[1] !== 0) highest = undefined;\n for (const projections of this.owners.values()) {\n if (projections === previous) continue;\n const candidate = projections.get(key);\n if (candidate?.[1] !== 0) continue;\n if (!highest || candidate[2] > highest[2]) highest = candidate;\n }\n return highest;\n }\n\n private blockingDetailReads(key: string, readGeneration: number): Set<number> {\n const blocking = new Set<number>();\n for (const reads of this.detailReads.values()) {\n for (const [candidateGeneration, candidateKey] of reads) {\n if (candidateKey === key && candidateGeneration < readGeneration) {\n blocking.add(candidateGeneration);\n }\n }\n }\n return blocking;\n }\n\n private highestPersistentGeneration(key: string): number {\n return Math.max(\n this.reads.get(key)?.[2] ?? Number.NEGATIVE_INFINITY,\n this.moves.get(key)?.[1] ?? Number.NEGATIVE_INFINITY,\n this.retainedOwners.get(key)?.[1] ?? Number.NEGATIVE_INFINITY,\n );\n }\n\n /**\n * The limit is deliberately soft: an accepted read is the only fence that\n * can stop an older retained branch/page owner from reviving stale filing.\n * Compact only after every current owner for that session is at least as\n * new; otherwise retaining the winner is required for correctness. Workspace\n * transitions provide the hard lifecycle bound for unresolved evidence.\n */\n private compact(): void {\n if (this.reads.size <= ACCEPTED_SESSION_CHANNEL_READ_SOFT_LIMIT) return;\n for (const [key, accepted] of this.reads) {\n const ownerEvidence = [...this.owners.values()]\n .map((projections) => projections.get(key))\n .filter((candidate): candidate is SessionChannelEvidence => candidate?.[1] === 0);\n if (\n ownerEvidence.length === 0 ||\n ownerEvidence.some((candidate) => candidate[2] < accepted[2])\n ) {\n continue;\n }\n for (const candidate of ownerEvidence) candidate[3] = true;\n this.reads.delete(key);\n if (this.reads.size <= ACCEPTED_SESSION_CHANNEL_READ_SOFT_LIMIT) return;\n }\n }\n\n private highestGeneration(key: string): number {\n let generation = this.highestPersistentGeneration(key);\n for (const projections of this.owners.values()) {\n const candidate = projections.get(key);\n if (candidate) generation = Math.max(generation, candidate[2]);\n }\n return generation;\n }\n\n project<T extends SessionChannelProjection>(projection: T, readGeneration: number): T {\n const key = sessionChannelProjectionKey(projection);\n const committedMove = this.moves.get(key);\n if (committedMove && committedMove[0] !== (projection.channelId ?? null)) {\n return { ...projection, channelId: committedMove[0] };\n }\n const read = this.reads.get(key);\n const retainedOwner = this.retainedOwners.get(key);\n const accepted =\n retainedOwner && (!read || retainedOwner[1] > read[2])\n ? ([retainedOwner[0], true, retainedOwner[1]] as SessionChannelRead)\n : read;\n if (\n !accepted ||\n !accepted[1] ||\n accepted[2] <= readGeneration ||\n accepted[0] === (projection.channelId ?? null)\n ) {\n return projection;\n }\n return { ...projection, channelId: accepted[0] };\n }\n\n owns(projection: SessionChannelProjection | null): boolean {\n if (!projection) return false;\n const key = sessionChannelProjectionKey(projection);\n const channelId = projection.channelId ?? null;\n const committedMove = this.moves.get(key);\n if (committedMove) return committedMove[0] === channelId;\n const read = this.reads.get(key);\n const retainedOwner = this.retainedOwners.get(key);\n const accepted =\n retainedOwner && (!read || retainedOwner[1] > read[2])\n ? ([retainedOwner[0], true, retainedOwner[1]] as SessionChannelRead)\n : read;\n let highestPriority = accepted ? 0 : Number.NEGATIVE_INFINITY;\n let highestGeneration = accepted?.[2] ?? Number.NEGATIVE_INFINITY;\n let owned = accepted?.[1] === true && accepted[0] === channelId;\n for (const projections of this.owners.values()) {\n const candidate = projections.get(key);\n if (!candidate || candidate[1] < highestPriority) continue;\n if (candidate[1] > highestPriority || candidate[2] > highestGeneration) {\n highestPriority = candidate[1];\n highestGeneration = candidate[2];\n owned = candidate[0] === channelId;\n } else if (candidate[2] === highestGeneration && candidate[0] === channelId) {\n owned = true;\n }\n }\n return owned;\n }\n}\n\ntype SessionPinChangeMessage = {\n type: \"session-pin.changed\";\n sessionId: string;\n messageId: string;\n};\n\nfunction channelName(workspaceId: string): string {\n return `${SESSION_PIN_CHANNEL_PREFIX}:${workspaceId}`;\n}\n\nfunction storageKey(workspaceId: string): string {\n return `${SESSION_PIN_STORAGE_PREFIX}:${workspaceId}`;\n}\n\nfunction newMessageId(): string {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return crypto.randomUUID();\n }\n return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;\n}\n\nfunction sessionPinChangeMessage(value: unknown): SessionPinChangeMessage | null {\n const message = value as Partial<SessionPinChangeMessage> | null;\n return message?.type === \"session-pin.changed\" &&\n typeof message.sessionId === \"string\" &&\n message.sessionId.length > 0 &&\n typeof message.messageId === \"string\" &&\n message.messageId.length > 0\n ? (message as SessionPinChangeMessage)\n : null;\n}\n\nfunction sameTreeStats(a: SessionTreeStats | undefined, b: SessionTreeStats | undefined): boolean {\n if (a === b) {\n return true;\n }\n if (!a || !b) {\n return false;\n }\n return (\n a.directChildren === b.directChildren &&\n a.totalDescendants === b.totalDescendants &&\n a.runningDescendants === b.runningDescendants &&\n a.queuedDescendants === b.queuedDescendants &&\n a.attentionDescendants === b.attentionDescendants &&\n a.pausedDescendants === b.pausedDescendants &&\n a.failedDescendants === b.failedDescendants &&\n (a.unreadFailedDescendants ?? a.failedDescendants) ===\n (b.unreadFailedDescendants ?? b.failedDescendants) &&\n (a.unreadDescendants ?? 0) === (b.unreadDescendants ?? 0) &&\n (a.activelyWorkingDescendants ?? 0) === (b.activelyWorkingDescendants ?? 0) &&\n (a.attentionSince ?? null) === (b.attentionSince ?? null) &&\n a.truncated === b.truncated\n );\n}\n\n/**\n * Merge a fresh hierarchy summary without letting an older personal failure\n * projection resurrect attention the viewer already consumed locally.\n *\n * `failedDescendants` is durable lifecycle history, while\n * `unreadFailedDescendants` is viewer-specific. When the lifecycle count is\n * unchanged but an incoming page reports more unread failures, the excess may\n * be a list read that started before the local acknowledgement committed. Keep\n * the acknowledged failure count, and remove only that stale failure delta\n * from the broader unread count so genuinely new unrelated unread work still\n * surfaces.\n */\nfunction mergeTreeStats(\n current: SessionTreeStats | undefined,\n projected: SessionTreeStats | undefined,\n): SessionTreeStats | undefined {\n if (!projected || !current) return projected ?? current;\n\n const currentUnreadFailed = current.unreadFailedDescendants ?? current.failedDescendants;\n const projectedUnreadFailed = projected.unreadFailedDescendants ?? projected.failedDescendants;\n if (\n current.failedDescendants !== projected.failedDescendants ||\n currentUnreadFailed >= projectedUnreadFailed\n ) {\n return projected;\n }\n\n const staleFailureDelta = projectedUnreadFailed - currentUnreadFailed;\n return {\n ...projected,\n unreadFailedDescendants: currentUnreadFailed,\n unreadDescendants: Math.max(\n current.unreadDescendants ?? 0,\n (projected.unreadDescendants ?? 0) - staleFailureDelta,\n ),\n };\n}\n\n/**\n * Merge only personal pin fields from a list/page projection into the open\n * route projection. Lifecycle and event-driven session fields remain owned by\n * the route/SSE reducer and cannot be regressed by a slower list poll.\n */\nexport function applySessionPinProjection<T extends Session>(\n current: T | null,\n projected: Pick<Session, \"id\" | \"workspaceId\" | \"pinned\" | \"pinnedAt\" | \"pinVersion\">,\n): T | null {\n if (!current || current.id !== projected.id || current.workspaceId !== projected.workspaceId) {\n return current;\n }\n const pinned = Boolean(projected.pinned);\n const pinnedAt = projected.pinnedAt ?? null;\n const pinVersion = projected.pinVersion ?? 0;\n // A page poll, mutation response, or legacy-replica response can finish\n // after a newer optimistic/authoritative projection is already visible.\n // Pin revisions are monotonic, so never let that older response undo the\n // newer header/list state. Equal revisions remain authoritative: they let a\n // server response replace the local optimistic timestamp for that revision.\n if (pinVersion < (current.pinVersion ?? 0)) {\n return current;\n }\n if (\n Boolean(current.pinned) === pinned &&\n (current.pinnedAt ?? null) === pinnedAt &&\n (current.pinVersion ?? 0) === pinVersion\n ) {\n return current;\n }\n return { ...current, pinned, pinnedAt, pinVersion };\n}\n\n/** Merge the list-owned project filing without replacing route/SSE content. */\nexport function applySessionChannelProjection<T extends Session>(\n current: T | null,\n projected: Pick<Session, \"id\" | \"workspaceId\" | \"channelId\">,\n): T | null {\n if (!current || current.id !== projected.id || current.workspaceId !== projected.workspaceId) {\n return current;\n }\n const channelId = projected.channelId ?? null;\n return (current.channelId ?? null) === channelId ? current : { ...current, channelId };\n}\n\n/**\n * Merge a detail/SSE projection into the root context without allowing a\n * slower detail read to erase newer list-owned pin or project projections.\n * Detail remains authoritative for route-owned fields; the current context\n * contributes personal pin fields and the project filing.\n */\nexport function mergeSessionContextProjection(\n current: SessionDetails | null,\n projected: SessionDetails | null,\n channelAuthority: SessionChannelProjectionAuthority,\n source: \"detail\" | \"live\",\n): SessionDetails | null {\n if (!projected) {\n return null;\n }\n const pinned = applySessionPinProjection(projected, current ?? projected) ?? projected;\n return source === \"live\" || channelAuthority.owns(current)\n ? (applySessionChannelProjection(pinned, current ?? projected) ?? pinned)\n : pinned;\n}\n\n/**\n * Merge a completed detail request only through the channel evidence that won\n * its request generation. A rejected late detail may still contribute its\n * route-owned fields when persistent authority can project the newer channel;\n * without such a winner it cannot seed stale route context after the rail (and\n * its transient owner evidence) has unmounted.\n */\nexport function mergeSessionDetailReadProjection(\n current: SessionDetails | null,\n projected: SessionDetails,\n channelAuthority: SessionChannelProjectionAuthority,\n readGeneration: number,\n accepted: boolean,\n): SessionDetails | null {\n const authoritative = accepted ? projected : channelAuthority.project(projected, readGeneration);\n if (!accepted && authoritative === projected && !channelAuthority.owns(projected)) {\n return current;\n }\n return mergeSessionContextProjection(current, authoritative, channelAuthority, \"detail\");\n}\n\n/**\n * Merge list-owned personal pin and hierarchy fields into route-owned session\n * content. A route/SSE object must never overwrite a newer cross-device unpin,\n * while a list poll must never regress lifecycle state or message content.\n * Activity ordering belongs to the list too: borrowing the selected route's\n * timestamp would move that row on selection and move it back on deselection.\n * List refreshes advance recency consistently for selected and unselected rows.\n * Creation ordering also keeps the list's exact SQL timestamp; route/lineage\n * Date hydration can discard the microseconds that distinguish adjacent rows.\n * When both agree the session needs a person and the list row is at least as\n * fresh as the detail, the list's `requiresActionSince` fills in for a detail\n * read, which never carries it, so selecting a row does not erase how long it\n * has been waiting.\n */\nexport function applySessionRailProjection<T extends Session>(\n current: T,\n projected: Session,\n options: { channelOwned?: boolean | undefined } = {},\n): T {\n const timed =\n current.updatedAt === projected.updatedAt && current.createdAt === projected.createdAt\n ? current\n : { ...current, updatedAt: projected.updatedAt, createdAt: projected.createdAt };\n const activity =\n timed.requiresActionSince == null &&\n projected.requiresActionSince != null &&\n timed.status === \"requires_action\" &&\n projected.status === \"requires_action\" &&\n // A list row older than the detail may describe an earlier request.\n projected.lastSequence >= timed.lastSequence\n ? { ...timed, requiresActionSince: projected.requiresActionSince }\n : timed;\n const pinned = applySessionPinProjection(activity, projected) ?? activity;\n const merged =\n options.channelOwned === false\n ? pinned\n : (applySessionChannelProjection(pinned, projected) ?? pinned);\n if (sameTreeStats(merged.treeStats, projected.treeStats)) {\n return merged;\n }\n const treeStats = mergeTreeStats(merged.treeStats, projected.treeStats);\n return treeStats ? { ...merged, treeStats } : merged;\n}\n\n/**\n * Reconcile the point read performed after a failed pin request.\n *\n * An optimistic first pin projects version 1 before the server responds. If the\n * request fails before commit, the authoritative point read correctly returns\n * the absent relation at version 0. The normal monotonic merge must reject an\n * arbitrary lower revision, but doing so here would leave the exact optimistic\n * projection stuck forever. Allow the lower authoritative revision only while\n * the current state is still byte-for-byte the projection installed by this\n * operation. Any intervening poll, mutation, or device response wins instead.\n */\nexport function reconcileFailedSessionPin(\n current: SessionDetails | null,\n optimistic: Pick<Session, \"id\" | \"workspaceId\" | \"pinned\" | \"pinnedAt\" | \"pinVersion\"> | null,\n authoritative: Pick<Session, \"id\" | \"workspaceId\" | \"pinned\" | \"pinnedAt\" | \"pinVersion\">,\n): SessionDetails | null;\nexport function reconcileFailedSessionPin(\n current: Session | null,\n optimistic: Pick<Session, \"id\" | \"workspaceId\" | \"pinned\" | \"pinnedAt\" | \"pinVersion\"> | null,\n authoritative: Pick<Session, \"id\" | \"workspaceId\" | \"pinned\" | \"pinnedAt\" | \"pinVersion\">,\n): Session | null;\nexport function reconcileFailedSessionPin<T extends Session>(\n current: T | null,\n optimistic: Pick<Session, \"id\" | \"workspaceId\" | \"pinned\" | \"pinnedAt\" | \"pinVersion\"> | null,\n authoritative: Pick<Session, \"id\" | \"workspaceId\" | \"pinned\" | \"pinnedAt\" | \"pinVersion\">,\n): T | null {\n if (\n !current ||\n !optimistic ||\n current.id !== optimistic.id ||\n current.workspaceId !== optimistic.workspaceId ||\n authoritative.id !== optimistic.id ||\n authoritative.workspaceId !== optimistic.workspaceId\n ) {\n return applySessionPinProjection(current, authoritative);\n }\n const stillExactOptimistic =\n Boolean(current.pinned) === Boolean(optimistic.pinned) &&\n (current.pinnedAt ?? null) === (optimistic.pinnedAt ?? null) &&\n (current.pinVersion ?? 0) === (optimistic.pinVersion ?? 0);\n if (!stillExactOptimistic) {\n return applySessionPinProjection(current, authoritative);\n }\n const authoritativePinned = Boolean(authoritative.pinned);\n const authoritativePinnedAt = authoritative.pinnedAt ?? null;\n const authoritativeVersion = authoritative.pinVersion ?? 0;\n if (\n Boolean(current.pinned) === authoritativePinned &&\n (current.pinnedAt ?? null) === authoritativePinnedAt &&\n (current.pinVersion ?? 0) === authoritativeVersion\n ) {\n return current;\n }\n return {\n ...current,\n pinned: authoritativePinned,\n pinnedAt: authoritativePinnedAt,\n pinVersion: authoritativeVersion,\n };\n}\n\nexport function notifySessionPinChanged(workspaceId: string, sessionId: string): void {\n const message: SessionPinChangeMessage = {\n type: \"session-pin.changed\",\n sessionId,\n messageId: newMessageId(),\n };\n if (typeof BroadcastChannel !== \"undefined\") {\n const name = channelName(workspaceId);\n try {\n let channel = outboundChannels.get(name);\n if (!channel) {\n // Closing immediately after postMessage is observably lossy in real\n // browsers. Keep one document-scoped outbound channel alive instead.\n channel = new BroadcastChannel(name);\n outboundChannels.set(name, channel);\n }\n channel.postMessage(message);\n } catch {\n // localStorage below remains the cross-document fallback.\n }\n }\n\n if (typeof window === \"undefined\") return;\n const key = storageKey(workspaceId);\n const serialized = JSON.stringify(message);\n try {\n window.localStorage.setItem(key, serialized);\n // Removing synchronously can race delivery in sibling tabs. Leave the\n // unique payload long enough to emit a storage event, then remove only the\n // value written by this notification.\n window.setTimeout(() => {\n try {\n if (window.localStorage.getItem(key) === serialized) {\n window.localStorage.removeItem(key);\n }\n } catch {\n // Storage may become unavailable after the page was backgrounded.\n }\n }, 1_000);\n } catch {\n // Private browsing and embedded contexts may deny localStorage entirely.\n }\n}\n\nexport function subscribeToSessionPinChanges(\n workspaceId: string,\n onChange: (sessionId: string) => void,\n): () => void {\n // BroadcastChannel and storage events can arrive in either order, and two\n // rapid mutations can interleave those transports. Remember a small bounded\n // window rather than only the immediately previous id so A, B, A still\n // invalidates exactly once per mutation without growing for the tab's life.\n const seenMessageIds = new Set<string>();\n const receive = (value: unknown): void => {\n const message = sessionPinChangeMessage(value);\n if (!message || seenMessageIds.has(message.messageId)) return;\n seenMessageIds.add(message.messageId);\n if (seenMessageIds.size > 64) {\n const oldest = seenMessageIds.values().next().value;\n if (oldest !== undefined) seenMessageIds.delete(oldest);\n }\n onChange(message.sessionId);\n };\n\n let channel: BroadcastChannel | null = null;\n if (typeof BroadcastChannel !== \"undefined\") {\n try {\n channel = new BroadcastChannel(channelName(workspaceId));\n channel.addEventListener(\"message\", (event: MessageEvent<unknown>) => receive(event.data));\n } catch {\n channel = null;\n }\n }\n\n const key = storageKey(workspaceId);\n const onStorage = (event: StorageEvent): void => {\n if (event.key !== key || !event.newValue) return;\n try {\n receive(JSON.parse(event.newValue));\n } catch {\n // Ignore malformed or unrelated storage payloads.\n }\n };\n if (typeof window !== \"undefined\") {\n window.addEventListener(\"storage\", onStorage);\n }\n\n return () => {\n channel?.close();\n if (typeof window !== \"undefined\") {\n window.removeEventListener(\"storage\", onStorage);\n }\n };\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/timeline/question-nav-model.ts","../src/timeline/focus-sequence.ts","../src/timeline/work-presentation.ts","../src/timeline/notice-presentation.ts"],"sourcesContent":["/**\n * \"Back to your message\": which prompt the reader is reading the answer to, and\n * whether that prompt has scrolled out of view. Renderer-neutral geometry so\n * the web timeline (DOM rects) and native timelines (layout offsets) agree.\n */\n\n/** How far above the viewport a prompt must be before the pill appears. */\nexport const QUESTION_NAV_HIDDEN_PX = 24;\n/** Breathing room above the question when the reader jumps back to it. */\nexport const QUESTION_NAV_MARGIN_PX = 12;\n\nexport type QuestionNavPrompt = { key: string; top: number; bottom: number };\n\n/**\n * The last prompt before the reading position (the viewport's middle) owns the\n * response in view; it is a target only once it has scrolled fully above the\n * viewport. Prompts are in document order; coordinates share one axis.\n */\nexport function questionNavTarget(\n prompts: readonly QuestionNavPrompt[],\n view: { top: number; height: number },\n): string | null {\n const middle = view.top + view.height / 2;\n const prompt = [...prompts].reverse().find((candidate) => candidate.top <= middle);\n if (!prompt) return null;\n if (prompt.top >= view.top - QUESTION_NAV_HIDDEN_PX || prompt.bottom > view.top) return null;\n return prompt.key;\n}\n","import type { TimelineGroup, TimelineItem } from \"./types\";\n\n/*\n * Landing on a moment in a session: an inbox item or a phone notification\n * points at the durable event that raised it, and the timeline opens on the\n * row that holds that moment. Events that render no row of their own (an\n * agent's notification, a goal change) land on the nearest row before them.\n */\n\nfunction itemSequences(item: TimelineItem): number[] {\n const sources =\n item.sourceEvents ??\n (\"annotationSource\" in item && item.annotationSource ? [item.annotationSource] : []);\n return sources.map((source) => source.sequence);\n}\n\n/** Every durable event sequence a group renders, nested work included. */\nexport function timelineGroupSequences(group: TimelineGroup): number[] {\n if (group.kind === \"item\") return itemSequences(group.item);\n if (group.kind === \"turn\") return group.groups.flatMap(timelineGroupSequences);\n return [\n ...group.items.flatMap((item) => itemSequences(item)),\n ...(group.work?.details.flatMap(timelineGroupSequences) ?? []),\n ];\n}\n\n/**\n * The index of the group to land on for `sequence`: the group that holds it,\n * else the last group that starts before it. -1 when every loaded group is\n * later (the moment is in older history) or nothing is loaded.\n */\nexport function timelineGroupIndexAtSequence(\n groups: readonly TimelineGroup[],\n sequence: number,\n): number {\n let landing = -1;\n for (let index = 0; index < groups.length; index += 1) {\n const sequences = timelineGroupSequences(groups[index]!);\n if (sequences.length === 0) continue;\n if (sequences.includes(sequence)) return index;\n if (Math.min(...sequences) <= sequence) landing = index;\n }\n return landing;\n}\n","// Pure presentation decisions for a timeline turn's work, shared by the web and native\n// timelines. Every function here is extracted verbatim from the web MessageTimeline so both\n// renderers decide identically what a turn shows (preparing, working, waiting, worked).\nimport { timelineGroupContainsPresentedImage } from \"./presented-image\";\nimport type { TurnSummaryStatus } from \"./turn-summary-model\";\nimport type { ActivityItem, TimelineGroup, TimelineItem } from \"./types\";\nimport { type OpenGeniText } from \"../messages/runtime\";\n\nexport type ActivityGroup = Extract<TimelineGroup, { kind: \"activity\" }>;\nexport type TurnGroup = Extract<TimelineGroup, { kind: \"turn\" }>;\n\n/** Once useful output exists, startup decoration must not compete with it. */\nexport function timelineTurnsWithOutput(items: readonly TimelineItem[]): Set<string> {\n return new Set(\n items.flatMap((item) =>\n \"turnId\" in item &&\n item.turnId &&\n (item.kind === \"tool-call\" ||\n ((item.kind === \"agent-message\" || item.kind === \"reasoning\") && item.text.trim()))\n ? [item.turnId]\n : [],\n ),\n );\n}\n\nexport function durationBetween(startedAt: string, endedAt: string): number | undefined {\n const started = Date.parse(startedAt);\n const ended = Date.parse(endedAt);\n if (!Number.isFinite(started) || !Number.isFinite(ended) || ended < started) {\n return undefined;\n }\n return ended - started;\n}\n\n/**\n * Compaction landmarks among a fold's groups (secondary summary facet). The\n * one-time rebuild for a new model has its own note and is not counted.\n */\nexport function compactedLandmarkCount(groups: readonly TimelineGroup[]): number {\n return groups.filter(\n (group) =>\n group.kind === \"item\" &&\n group.item.kind === \"context-compaction\" &&\n group.item.phase === \"compacted\" &&\n group.item.implementation !== \"portable_model_switch\",\n ).length;\n}\n\nexport function clusterIsSettled(group: ActivityGroup): boolean {\n return group.items.every((item) => {\n if (item.kind === \"reasoning\" || item.kind === \"agent-message\") {\n return !item.streaming;\n }\n // Memory writes and fleet observations are discrete, already-settled events.\n if (item.kind === \"memory\" || item.kind === \"fleet-decision\") {\n return true;\n }\n return item.status !== \"running\";\n });\n}\n\nexport function flattenActivityItems(groups: readonly TimelineGroup[]): ActivityItem[] {\n const items: ActivityItem[] = [];\n for (const group of groups) {\n if (group.kind === \"activity\") {\n items.push(...flattenActivityItems(group.work?.details ?? []), ...group.items);\n } else if (group.kind === \"turn\") {\n items.push(...flattenActivityItems(group.groups));\n }\n }\n return items;\n}\n\nexport type ReadableWorkOptions = {\n /** Host shows startup phases as ordinary details (web: startup-details context). */\n startupDetails: boolean;\n /** Startup chrome was dismissed by the reader. */\n startupDismissed: boolean;\n};\n\n/**\n * A readable turn whose only work so far is environment preparation renders as one quiet\n * preparation surface instead of a \"Working\" fold.\n */\nexport function isPreparingWork(group: ActivityGroup, options: ReadableWorkOptions): boolean {\n if (!group.work) return false;\n // Steps not loaded yet are work the reader can open, not preparation.\n if (group.work.steps && group.work.steps.state !== \"complete\") return false;\n const phases = group.items.filter((item) => item.kind === \"startup-phase\");\n return (\n !options.startupDetails &&\n !options.startupDismissed &&\n !group.work.endedAt &&\n !group.work.waiting &&\n phases.length > 0 &&\n group.items.every(\n (item) => item.kind === \"startup-phase\" || (item.kind === \"reasoning\" && !item.text.trim()),\n ) &&\n !phases.some((item) => item.status === \"failed\" || item.status === \"cancelled\")\n );\n}\n\n/**\n * Whether a readable turn's work row has anything to reveal when expanded.\n * Unless the host shows startup phases as details, the work row's rail only\n * renders failed or cancelled preparation steps, so a detail made only of\n * completed or still-running steps (for example the queue phase before a turn\n * was parked on a usage limit) renders nothing and does not make the row\n * expandable.\n */\nexport function readableWorkHasDetails(\n group: ActivityGroup & { work: NonNullable<ActivityGroup[\"work\"]> },\n options: Pick<ReadableWorkOptions, \"startupDetails\">,\n): boolean {\n // Steps not loaded yet are revealed (and loaded) by opening the row.\n if (group.work.steps && group.work.steps.state !== \"complete\") return true;\n return group.work.details.some(\n (detail) =>\n options.startupDetails ||\n detail.kind !== \"activity\" ||\n Boolean(detail.work) ||\n !detail.items.every(\n (item) =>\n (item.kind === \"startup-phase\" &&\n item.status !== \"failed\" &&\n item.status !== \"cancelled\") ||\n (item.kind === \"reasoning\" && !item.text.trim()),\n ),\n );\n}\n\n/**\n * Status of a readable turn's work row, minus the host-rendered live preview.\n * Time spent waiting for model capacity, or between a failed attempt and its\n * Retry, is not work: the worked duration and the live working clock exclude\n * it, and a capacity wait itself shows no clock. A\n * wait's `detail` is its one quiet secondary line.\n */\nexport function readableWorkStatus(\n t: OpenGeniText,\n group: ActivityGroup & { work: NonNullable<ActivityGroup[\"work\"]> },\n): Omit<TurnSummaryStatus, \"preview\"> & { detail?: string | undefined } {\n const end = group.work.endedAt;\n const pausedMs = group.work.pausedMs ?? 0;\n if (end) {\n const durationMs = durationBetween(group.work.startedAt, end);\n const cycles = group.work.cycles;\n // Folded quiet cycles report their wall-clock span: waits are the point.\n if (cycles)\n return {\n kind: \"worked\",\n label: t(\"timeline.workPresentation.countUpdatesOver\", { count: cycles.count }),\n durationMs,\n };\n return {\n kind: \"worked\",\n durationMs: durationMs === undefined ? undefined : Math.max(0, durationMs - pausedMs),\n };\n }\n if (group.work.waiting) {\n const { untimed, since, ...waiting } = group.work.waiting;\n return { kind: \"waiting\", ...waiting, ...(untimed ? {} : { since }) };\n }\n const started = Date.parse(group.work.startedAt);\n return {\n kind: \"working\",\n since:\n pausedMs > 0 && Number.isFinite(started)\n ? new Date(started + pausedMs).toISOString()\n : group.work.startedAt,\n };\n}\n\n/** Whether a readable turn's work fold starts expanded. */\nexport function readableWorkDefaultOpen(group: ActivityGroup): true | undefined {\n return timelineGroupContainsPresentedImage(group) ||\n group.outcome === \"failed\" ||\n group.items.some(\n (item) =>\n item.kind === \"startup-phase\" &&\n (item.status === \"failed\" ||\n // A cancelled phase with a blocked reason is an expected wait (for\n // example compacting the conversation first), not an interruption.\n (item.status === \"cancelled\" && !item.blockedReason)),\n )\n ? true\n : undefined;\n}\n\n/** Whether the live preview should show (images stay primary output instead). */\nexport function readableWorkShowsPreview(group: ActivityGroup): boolean {\n return !timelineGroupContainsPresentedImage(group);\n}\n\n/**\n * The step a rolling preview shows: steps advance with event order (progress notes and\n * startup phases have their own surfaces). Mirrors the web RollingActivity selection.\n */\nexport function rollingActivityItem(\n items: readonly ActivityItem[],\n previousItem?: ActivityItem,\n mounted = true,\n): { item: ActivityItem; running: boolean; earlierCount: number } | null {\n const work = items.filter(\n (item) => item.kind !== \"startup-phase\" && item.kind !== \"agent-message\",\n );\n const active = work.filter((item) =>\n item.kind === \"reasoning\" ? item.streaming : \"status\" in item && item.status === \"running\",\n );\n const item =\n !mounted && previousItem && previousItem.kind !== \"agent-message\" ? previousItem : work.at(-1);\n if (!item) return null;\n return {\n item,\n running: active.some((entry) => entry.id === item.id),\n earlierCount: Math.max(\n 0,\n work.findIndex((entry) => entry.id === item.id),\n ),\n };\n}\n","import { formatClockTime } from \"../lib/format\";\nimport { formatElapsed } from \"./turn-summary-model\";\nimport type { NoticeItem } from \"./types\";\nimport { durationBetween } from \"./work-presentation\";\nimport { type OpenGeniText } from \"../messages/runtime\";\n\n/** An approval notice the person has since answered. */\nexport function noticeIsResolvedApproval(\n item: Pick<NoticeItem, \"approval\" | \"resolvedAt\">,\n): boolean {\n return Boolean(item.resolvedAt && item.approval);\n}\n\n/**\n * What an approval asked, as history: its question without the question mark\n * or anything after it (\"Remove the Gmail connection for anna@example.com?\n * …\" → \"Remove the Gmail connection for anna@example.com\"). A quoted name\n * (“…”) keeps its own punctuation.\n */\nexport function approvalHistoryTitle(title: string): string {\n // A question cut short lost its own \"?\": an earlier one is a name's.\n if (title.trimEnd().endsWith(\"…\")) return title.trim();\n let quoted = 0;\n let end = -1;\n for (let index = 0; index < title.length; index += 1) {\n const char = title[index];\n if (char === \"“\") quoted += 1;\n else if (char === \"”\") quoted = Math.max(0, quoted - 1);\n // The question ends at the last \"?\" that ends the title or starts\n // another sentence, so a \"?\" inside a name doesn't cut it short.\n else if (char === \"?\" && quoted === 0 && /^(\\s+\\p{Lu}|\\s*$)/u.test(title.slice(index + 1)))\n end = index;\n }\n return (end < 0 ? title : title.slice(0, end)).trim();\n}\n\ntype ApprovalAction = NonNullable<NoticeItem[\"approvalActions\"]>[number];\n\n/**\n * \"Added: 2 Oct 2026, 10:12 UTC\": the first of this action's facts whose\n * value differs from every other alike action's, or undefined when none do.\n */\nfunction tellingFact(action: ApprovalAction, alike: ApprovalAction[]): string | undefined {\n const valueOf = (other: ApprovalAction, label: string) =>\n other.facts?.find((fact) => fact.label === label)?.value;\n const fact = action.facts?.find((candidate) =>\n alike.every((other) => other === action || valueOf(other, candidate.label) !== candidate.value),\n );\n return fact ? `${fact.label}: ${fact.value}` : undefined;\n}\n\n/**\n * A resolved approval notice reads as history, saying what the person\n * decided for each action whose answer is known, one line each: \"You\n * approved “Remove the Gmail connection for anna@example.com”.\" Actions it\n * asked about but never got an answer for here (a later wait asked again)\n * are left out. Two that would read the same get the first fact that tells\n * them apart: \"(Added: 2 Oct 2026, 10:12 UTC)\".\n */\nexport function noticeDisplayText(\n t: OpenGeniText,\n item: Pick<NoticeItem, \"text\" | \"approval\" | \"resolvedAt\" | \"approvalActions\">,\n): string {\n if (!noticeIsResolvedApproval(item)) return item.text;\n const actions = item.approvalActions ?? [];\n const decided = actions.filter((action) => action.decision !== undefined);\n // Without any answer (an older replay), say only that it was answered.\n if (decided.length === 0) return t(\"timeline.noticePresentation.youRespondedToThisApproval\");\n // Each answered action, by what it asked.\n if (decided.every((action) => action.title)) {\n const titled = decided.map((action) => ({\n action,\n title: approvalHistoryTitle(action.title!),\n }));\n return titled\n .map(({ action, title }) => {\n const alike = titled.filter((other) => other.title === title).map((other) => other.action);\n const detail = alike.length > 1 ? tellingFact(action, alike) : undefined;\n if (detail)\n return action.decision === \"approve\"\n ? t(\"timeline.noticePresentation.youApprovedTitleWithDetail\", { title, detail })\n : action.decision === \"reject\"\n ? t(\"timeline.noticePresentation.youRejectedTitleWithDetail\", { title, detail })\n : t(\"timeline.noticePresentation.declinedAutomaticallyTitleWithDetail\", {\n title,\n detail,\n });\n return action.decision === \"approve\"\n ? t(\"timeline.noticePresentation.youApprovedTitle\", { title })\n : action.decision === \"reject\"\n ? t(\"timeline.noticePresentation.youRejectedTitle\", { title })\n : t(\"timeline.noticePresentation.declinedAutomaticallyTitle\", { title });\n })\n .join(\"\\n\");\n }\n // Declined by Opengeni rather than the person: never say \"You\".\n const automatic = decided.filter((action) => action.decision === \"automatic_reject\").length;\n if (automatic === decided.length) return t(\"timeline.noticePresentation.declinedAutomatically\");\n if (automatic > 0) return t(\"timeline.noticePresentation.youRespondedToThisApproval\");\n const approved = decided.filter((action) => action.decision === \"approve\").length;\n const rejected = decided.length - approved;\n if (decided.length === 1)\n return approved === 1\n ? t(\"timeline.noticePresentation.youApprovedThis\")\n : t(\"timeline.noticePresentation.youRejectedThis\");\n if (rejected === 0)\n return t(\"timeline.noticePresentation.youApprovedActions\", { count: approved });\n if (approved === 0)\n return t(\"timeline.noticePresentation.youRejectedActions\", { count: rejected });\n return t(\"timeline.noticePresentation.youApprovedAndRejected\", { approved, rejected });\n}\n\n/** Notice pill tone: failures stay red, an open wait keeps the waiting hue. */\nexport function noticeTone(\n item: Pick<NoticeItem, \"tone\" | \"resolvedAt\">,\n): \"failed\" | \"waiting\" | \"neutral\" {\n return item.tone === \"failed\"\n ? \"failed\"\n : item.tone === \"waiting\" && !item.resolvedAt\n ? \"waiting\"\n : \"neutral\";\n}\n\n/**\n * Plain-text summary of a recorded agent wait, as web's quiet disclosure reads\n * it: \"Waited for 2 agents · 3m 5s\" once later input ended the wait, otherwise\n * \"Waiting · since 10:32\" (with the date on a later day).\n */\nexport function recordedWaitSummaryText(\n t: OpenGeniText,\n item: Pick<NoticeItem, \"occurredAt\" | \"waitingAgents\" | \"waitEndedAt\">,\n now: Date = new Date(),\n): string {\n const agents = item.waitingAgents ?? 0;\n const waitedMs = item.waitEndedAt\n ? durationBetween(item.occurredAt, item.waitEndedAt)\n : undefined;\n if (waitedMs !== undefined) {\n const elapsed = formatElapsed(t, waitedMs);\n return agents > 0\n ? t(\"timeline.noticePresentation.waitedForAgentsElapsed\", { count: agents, elapsed })\n : t(\"timeline.noticePresentation.waitedElapsed\", { elapsed });\n }\n const started = new Date(item.occurredAt);\n const since =\n started.toDateString() === now.toDateString()\n ? formatClockTime(t, item.occurredAt)\n : started.toLocaleString(t.locale, { dateStyle: \"medium\", timeStyle: \"short\" });\n if (item.waitEndedAt)\n return agents > 0\n ? t(\"timeline.noticePresentation.waitedForAgentsSince\", { count: agents, since })\n : t(\"timeline.noticePresentation.waitedSince\", { since });\n return agents > 0\n ? t(\"timeline.noticePresentation.waitingForAgentsSince\", { count: agents, since })\n : t(\"timeline.noticePresentation.waitingSince\", { since });\n}\n"],"mappings":"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","names":["item","fact"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/app/components/rail/session-row-content.tsx"],"sourcesContent":["import {\n CalendarClockIcon,\n Clock3Icon,\n HourglassIcon,\n Loader2Icon,\n TriangleAlertIcon,\n ZapIcon,\n} from \"lucide-react\";\nimport { Children, isValidElement, useId, type ReactNode } from \"react\";\n\nimport { CreatorMonogram } from \"../creator-monogram\";\nimport { type CreatorRef, creatorAnnouncement, creatorInitials } from \"../../lib/creator-initials\";\nimport { formatWaitingSince } from \"../../lib/format\";\nimport { t } from \"../../lib/console-text\";\nimport { cn } from \"../../lib/utils\";\nimport type { RailAggregateStatus } from \"../../lib/sessions-group\";\nimport {\n sessionAutomationWaitLabel,\n type SessionAutomationWait,\n} from \"../../../session-list-model\";\n\nexport function ActiveWorkMark({ className }: { className?: string | undefined }) {\n const maskId = `active-work-${useId().replaceAll(\":\", \"\")}`;\n return (\n <svg\n aria-hidden=\"true\"\n viewBox=\"0 0 108 108\"\n className={cn(\"size-2.5 shrink-0 text-session-update\", className)}\n >\n <defs>\n <mask id={maskId} maskUnits=\"userSpaceOnUse\" x=\"0\" y=\"0\" width=\"108\" height=\"108\">\n <circle cx=\"54\" cy=\"54\" r=\"48\" fill=\"white\" />\n <g fill=\"none\" stroke=\"black\" strokeWidth=\"21\" strokeLinecap=\"round\">\n <path d=\"M-8 43 C35 40 71 29 116 16\" />\n <path d=\"M-8 86 C35 83 71 72 116 59\" />\n </g>\n </mask>\n </defs>\n <circle cx=\"54\" cy=\"54\" r=\"48\" fill=\"currentColor\" mask={`url(#${maskId})`} />\n <circle cx=\"54\" cy=\"54\" r=\"48\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" />\n </svg>\n );\n}\n\n/** The one descendant-aware status marker shared by rows and section headers. */\nfunction RailAggregateDot({ summary }: { summary: RailAggregateStatus }) {\n if (summary.kind === \"neutral\") return null;\n if (summary.kind === \"active\") {\n return (\n <Loader2Icon\n aria-hidden=\"true\"\n className=\"size-3 shrink-0 animate-spin text-fg-subtle motion-reduce:animate-none\"\n style={{ animationDuration: \"1.333333s\" }}\n />\n );\n }\n if (summary.kind === \"queued\") {\n return <Clock3Icon aria-hidden=\"true\" className=\"size-3 shrink-0 text-fg-subtle\" />;\n }\n if (summary.kind === \"waiting\") {\n // Parked until input or its wake-up time: nothing is executing, so no spinner.\n return <HourglassIcon aria-hidden=\"true\" className=\"size-3 shrink-0 text-fg-subtle\" />;\n }\n if (summary.kind === \"active_work\") {\n return <ActiveWorkMark />;\n }\n if (summary.kind === \"send_failed\") {\n return (\n <TriangleAlertIcon aria-hidden=\"true\" className=\"size-3.5 shrink-0 text-status-failed\" />\n );\n }\n const tone =\n summary.kind === \"needs_attention\"\n ? \"bg-status-waiting\"\n : summary.kind === \"failed\"\n ? \"bg-status-failed\"\n : \"bg-session-update\";\n return (\n <span\n aria-hidden=\"true\"\n className={cn(\"relative inline-flex size-2 shrink-0 rounded-full\", tone)}\n />\n );\n}\n\n/**\n * The row's announced name.\n *\n * `aria-label` replaces name-from-content, so this string is the whole of what\n * a screen reader hears for the row: the creator chip is `aria-hidden`, and\n * even the sr-only state line inside the link is inert for it. Every fact a\n * sighted user reads off the row belongs here, and in exactly one place.\n */\nexport function sessionRowAccessibleName({\n title,\n stateLabel,\n pinned,\n statusLabel,\n spawnedLabel,\n creator,\n}: {\n title: string;\n stateLabel: string;\n pinned: boolean;\n statusLabel: string;\n spawnedLabel?: string | null | undefined;\n creator?: CreatorRef | null | undefined;\n}): string {\n const spokenCreator = creatorAnnouncement(creator ?? null);\n return `Open ${title}. ${stateLabel}${pinned ? \". Pinned\" : \"\"}. ${statusLabel}${\n spawnedLabel ? `. ${spawnedLabel}` : \"\"\n }${spokenCreator ? `. Created by ${spokenCreator}` : \"\"}`;\n}\n\n/**\n * The quiet mark for a chat an automation will post into: a clock while it\n * waits for its schedule, a bolt while it waits for an event. `label` says\n * what exactly (\"Waiting for deploy.finished from Deploys\"); without it the\n * plain wait is named.\n */\nexport function AutomationWaitIcon({\n wait,\n label: detail,\n className,\n}: {\n wait: SessionAutomationWait;\n label?: string | undefined;\n className?: string | undefined;\n}) {\n const Icon = wait === \"event\" ? ZapIcon : CalendarClockIcon;\n const label = detail || sessionAutomationWaitLabel(t, wait);\n return (\n <span role=\"img\" aria-label={label} title={label} className=\"inline-flex shrink-0\">\n <Icon\n aria-hidden=\"true\"\n data-automation-wait={wait}\n className={cn(\"size-3.5 shrink-0 text-fg-subtle\", className)}\n />\n </span>\n );\n}\n\nexport function RailTrailingMetadata({\n summary,\n automationWait = null,\n automationWaitLabel,\n relativeTime,\n jumpKey,\n creator,\n quickActionSlots = 0,\n}: {\n summary: RailAggregateStatus;\n /** What an automation posting into this chat is waiting for; null for none. */\n automationWait?: SessionAutomationWait | null | undefined;\n /** That wait in words, for the mark's tooltip and accessible name. */\n automationWaitLabel?: string | undefined;\n relativeTime?: string | undefined;\n /** The key that opens this row (\"⌘3\"), shown in place of the time while ⌘ is held. */\n jumpKey?: string | undefined;\n /** Rightmost items replaced in place by the row's desktop quick actions. */\n quickActionSlots?: number | undefined;\n /**\n * Session creator for a top-level row, else null; callers decide which rows\n * are roots. A chip is its own reason to render this block: a mobile root row\n * can have no status marker and no time and still name who started it.\n */\n creator?: CreatorRef | null | undefined;\n}) {\n const hasStatusMarker = summary.kind !== \"neutral\";\n const hasRelativeTime = Boolean(relativeTime);\n const hasMonogram = creator ? creatorInitials(creator) !== null : false;\n // How long the longest-waiting session behind a \"needs you\" marker has been\n // blocked on a human. A collapsed parent with a child parked for ten hours\n // must say so, not hide it behind a dot.\n const waitingFor =\n summary.kind === \"needs_attention\" && summary.attentionSince\n ? formatWaitingSince(summary.attentionSince)\n : \"\";\n if (\n !automationWait &&\n !hasStatusMarker &&\n !hasRelativeTime &&\n !jumpKey &&\n !hasMonogram &&\n !quickActionSlots\n )\n return null;\n const items = Children.toArray([\n automationWait ? (\n <AutomationWaitIcon key=\"automation\" wait={automationWait} label={automationWaitLabel} />\n ) : null,\n hasMonogram && creator ? (\n <CreatorMonogram key=\"creator\" createdBy={creator} showTitle={false} />\n ) : null,\n waitingFor ? (\n <span\n key=\"waiting\"\n data-session-row-waiting\n title={summary.label}\n className=\"shrink-0 whitespace-nowrap text-2xs tabular-nums text-status-waiting\"\n >\n {waitingFor}\n </span>\n ) : null,\n hasStatusMarker ? (\n <span key=\"status\" className=\"flex size-3 items-center justify-center\" title={summary.label}>\n <RailAggregateDot summary={summary} />\n </span>\n ) : null,\n jumpKey ? (\n <kbd\n key=\"time\"\n data-session-row-jump-key\n className=\"inline-flex h-4.5 min-w-9 shrink-0 items-center justify-center rounded-[4px] border border-border bg-surface-2 px-1 font-sans text-2xs leading-none font-medium whitespace-nowrap text-fg-muted\"\n >\n {jumpKey}\n </kbd>\n ) : hasRelativeTime ? (\n <span\n key=\"time\"\n className=\"min-w-9 shrink-0 whitespace-nowrap text-right text-2xs tabular-nums text-fg\"\n >\n {relativeTime}\n </span>\n ) : null,\n ]).filter(isValidElement);\n if (!quickActionSlots) {\n return (\n <span\n data-session-row-metadata\n className=\"inline-flex shrink-0 items-center justify-end gap-1\"\n >\n {items}\n </span>\n );\n }\n // Empty rows still reserve their action footprint. Visibility (never display\n // or padding) swaps the last items, keeping every other box stationary.\n while (items.length < quickActionSlots) items.unshift(<span key={`empty-${items.length}`} />);\n return (\n <span data-session-row-metadata className=\"inline-flex shrink-0 items-center justify-end\">\n {items.map((item, index) => (\n <span\n key={item.key}\n data-session-row-slot\n className={cn(\n \"inline-flex min-w-6 shrink-0 items-center justify-center last:min-w-10\",\n index >= items.length - quickActionSlots &&\n \"pointer-fine:group-hover:invisible pointer-fine:group-focus-within:invisible\",\n )}\n >\n {item}\n </span>\n ))}\n </span>\n );\n}\n\nexport function SessionRowContent({\n title,\n stateLabel,\n depthLabel,\n descendantLabel,\n mobile,\n summary,\n automationWait = null,\n automationWaitLabel,\n relativeTime,\n jumpKey,\n creator,\n quickActionSlots = 0,\n leading,\n parentTitle,\n}: {\n /** Before the title: a bot's avatar. */\n leading?: ReactNode | undefined;\n title: string;\n /** For a pinned sub-agent chat, the chat it belongs to, said quietly after the title. */\n parentTitle?: string | null | undefined;\n stateLabel: string;\n depthLabel?: string | null | undefined;\n descendantLabel?: string | null | undefined;\n mobile: boolean;\n summary: RailAggregateStatus;\n /** What an automation posting into this chat is waiting for; null for none. */\n automationWait?: SessionAutomationWait | null | undefined;\n /** See RailTrailingMetadata. */\n automationWaitLabel?: string | undefined;\n relativeTime?: string | undefined;\n /** See RailTrailingMetadata. */\n jumpKey?: string | undefined;\n quickActionSlots?: number | undefined;\n /** Session creator for a top-level row, else null. See RailTrailingMetadata. */\n creator?: CreatorRef | null | undefined;\n}) {\n return (\n <>\n {/* Inert for the row's accessible name, which its `aria-label` owns -\n including the creator. Kept as-is so this change regresses nothing. */}\n <span className=\"sr-only\">{stateLabel}. </span>\n {leading}\n <span className=\"flex min-w-0 flex-1 flex-col leading-tight\">\n {parentTitle ? (\n // The title keeps its room; the parent's name gives way first. The\n // line as a whole fades at the column's edge, as a title does.\n <span\n data-session-row-title\n className=\"flex min-w-0 items-baseline gap-1.5 overflow-hidden whitespace-nowrap\"\n >\n <span className=\"min-w-0 truncate\">{title}</span>\n <span\n data-session-row-parent\n className=\"min-w-10 max-w-[55%] shrink-3 truncate text-2xs text-fg-muted\"\n >\n in {parentTitle}\n </span>\n </span>\n ) : (\n <span data-session-row-title className=\"block min-w-0 overflow-hidden whitespace-nowrap\">\n {title}\n </span>\n )}\n {mobile ? (\n <span\n data-session-row-state\n className=\"mt-0.5 truncate text-2xs font-normal text-fg-muted\"\n >\n {[stateLabel, depthLabel, descendantLabel, relativeTime].filter(Boolean).join(\" · \")}\n </span>\n ) : null}\n </span>\n <RailTrailingMetadata\n quickActionSlots={quickActionSlots}\n summary={summary}\n automationWait={automationWait}\n automationWaitLabel={automationWaitLabel}\n relativeTime={relativeTime}\n jumpKey={jumpKey}\n creator={creator}\n />\n </>\n );\n}\n"],"mappings":"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","names":[]}
@@ -1,2 +0,0 @@
1
- "use client";
2
- //# sourceMappingURL=chunk-O2UPPN5M.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/app/components/session/subscription-account-menu.tsx"],"sourcesContent":["// The subscription-account dropdown every provider shares. Its content comes\n// from `subscriptionAccountMenuContent`; data sources own loading,\n// authorization, usage freshness and selection.\nimport { ChevronDownIcon, Loader2Icon } from \"lucide-react\";\nimport type { ReactNode } from \"react\";\n\nimport {\n DropdownMenu,\n DropdownMenuCheck,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuMeta,\n DropdownMenuNote,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"../../../ui/dropdown-menu\";\nimport { cn } from \"../../lib/utils\";\n\nexport type SubscriptionAccountMenuRow = {\n id: string;\n label: string;\n plan?: string | null | undefined;\n status?: string | null;\n detail?: string;\n personal?: boolean;\n disabled?: boolean;\n /** Per-window readings, not an aggregate capacity/eligibility estimate. */\n usageSummary?: string | undefined;\n /** The row's most-used window, drawn as a small bar beside the summary. */\n usageBar?: { label: string; usedPercent: number } | undefined;\n};\n\nexport type SubscriptionAccountUsageWindow = {\n label: string;\n /** Null means unknown; values over 100 can represent overage. */\n usedPercent: number | null;\n detail?: string;\n};\n\nexport type SubscriptionAccountMenuUsage = {\n checking?: boolean | undefined;\n unavailable?: boolean | undefined;\n message?: string | undefined;\n note?: string | undefined;\n windows?: SubscriptionAccountUsageWindow[] | undefined;\n};\n\nfunction UsageRow({ label, usedPercent, detail }: SubscriptionAccountUsageWindow) {\n const known = typeof usedPercent === \"number\" && Number.isFinite(usedPercent);\n const pct = known ? Math.min(100, Math.max(0, usedPercent)) : 0;\n const text = known ? `${Math.round(usedPercent)}% used` : \"Unknown\";\n return (\n <div className=\"space-y-0.5 text-2xs text-fg-subtle\">\n <div className=\"flex items-center gap-2\">\n <span className=\"max-w-28 min-w-10 shrink-0 truncate\" title={label}>\n {label}\n </span>\n {known ? (\n <span\n className=\"h-1 min-w-0 flex-1 overflow-hidden rounded-full bg-surface-2\"\n role=\"progressbar\"\n aria-label={`${label} used`}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={pct}\n aria-valuetext={text}\n >\n <span\n className={cn(\n \"block h-full rounded-full\",\n pct >= 90 ? \"bg-status-waiting\" : \"bg-brand\",\n )}\n style={{ width: `${pct}%` }}\n />\n </span>\n ) : (\n <span className=\"flex-1\" />\n )}\n <span className=\"shrink-0 whitespace-nowrap text-right tabular-nums\">{text}</span>\n </div>\n {detail ? <p>{detail}</p> : null}\n </div>\n );\n}\n\nfunction RowUsageBar({ label, usedPercent }: { label: string; usedPercent: number }) {\n const pct = Math.min(100, Math.max(0, usedPercent));\n return (\n <span\n className=\"h-1 w-10 shrink-0 overflow-hidden rounded-full bg-surface-2\"\n role=\"progressbar\"\n aria-label={`${label} used`}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={pct}\n aria-valuetext={`${Math.round(usedPercent)}% used`}\n >\n <span\n className={cn(\"block h-full rounded-full\", pct >= 90 ? \"bg-status-waiting\" : \"bg-brand\")}\n style={{ width: `${pct}%` }}\n />\n </span>\n );\n}\n\nexport function SubscriptionAccountMenu({\n ariaLabel,\n triggerMark,\n headerMark,\n selectionLabel,\n displayName,\n metadata,\n identity,\n tone = \"ok\",\n usage,\n accounts,\n selectedId,\n automaticSelected,\n choosing,\n choosingTarget,\n actionLabel = \"Use for next turn\",\n automaticLabel = \"Automatic\",\n emptyMessage,\n error,\n note,\n onOpenChange,\n onChoose,\n}: {\n ariaLabel: string;\n triggerMark: ReactNode;\n headerMark: ReactNode;\n selectionLabel: string;\n displayName: string;\n metadata: string;\n identity?: string | null | undefined;\n tone?: \"ok\" | \"warn\" | \"bad\" | undefined;\n usage: SubscriptionAccountMenuUsage;\n accounts: SubscriptionAccountMenuRow[];\n selectedId: string | null;\n automaticSelected: boolean;\n choosing: boolean;\n choosingTarget: string | null | undefined;\n actionLabel?: string | undefined;\n automaticLabel?: string | undefined;\n emptyMessage?: string | undefined;\n error?: string | null | undefined;\n note: string;\n onOpenChange?: ((open: boolean) => void) | undefined;\n onChoose: (connectionId: string | null) => void;\n}) {\n const row = (account: SubscriptionAccountMenuRow) => (\n <DropdownMenuItem\n key={account.id}\n disabled={choosing || account.disabled}\n title={account.detail}\n onSelect={(event) => {\n event.preventDefault();\n onChoose(account.id);\n }}\n className=\"cursor-pointer\"\n >\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate\">{account.label}</span>\n {account.usageSummary ? (\n <span className=\"flex min-w-0 items-center gap-1.5 text-2xs text-fg-subtle\">\n {account.usageBar ? <RowUsageBar {...account.usageBar} /> : null}\n <span className=\"min-w-0 truncate\" title={account.usageSummary}>\n {account.usageSummary}\n </span>\n </span>\n ) : null}\n </span>\n {account.plan ? <DropdownMenuMeta>{account.plan}</DropdownMenuMeta> : null}\n {account.status ? (\n <span className=\"shrink-0 text-xs text-status-waiting\">{account.status}</span>\n ) : null}\n {choosingTarget === account.id ? (\n <Loader2Icon className=\"size-4 shrink-0 animate-spin\" />\n ) : (\n <DropdownMenuCheck checked={account.id === selectedId} className=\"ml-0\" />\n )}\n </DropdownMenuItem>\n );\n const personal = accounts.filter((account) => account.personal);\n return (\n <DropdownMenu {...(onOpenChange ? { onOpenChange } : {})}>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n aria-label={ariaLabel}\n title={ariaLabel}\n className={cn(\n \"group/account relative inline-flex h-6 shrink-0 cursor-pointer items-center gap-0.5 rounded-full border border-border/70 bg-surface-2/50 px-1.5 text-fg-muted outline-hidden transition-[background-color,border-color,color] hover:border-border hover:bg-surface-2 hover:text-fg focus-visible:ring-1 focus-visible:ring-ring/40 data-[state=open]:border-border data-[state=open]:bg-surface-2 data-[state=open]:text-fg\",\n choosing && \"opacity-60\",\n )}\n >\n {triggerMark}\n {choosing ? (\n <Loader2Icon className=\"size-2.5 animate-spin text-current\" aria-hidden />\n ) : (\n <ChevronDownIcon\n className=\"size-2.5 shrink-0 opacity-70 transition-opacity group-hover/account:opacity-100\"\n aria-hidden\n />\n )}\n {tone !== \"ok\" ? (\n <span\n className={cn(\n \"absolute -top-0.5 -right-0.5 size-1.5 rounded-full ring-1 ring-surface\",\n tone === \"bad\" ? \"bg-destructive\" : \"bg-status-waiting\",\n )}\n aria-hidden\n />\n ) : null}\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n align=\"start\"\n side=\"bottom\"\n sideOffset={8}\n collisionPadding={12}\n className=\"flex max-h-[min(32rem,var(--radix-dropdown-menu-content-available-height))] w-72 flex-col overflow-hidden\"\n >\n <div className=\"shrink-0 space-y-2 px-2.5 pt-1.5 pb-2\">\n <div className=\"flex items-start gap-2\">\n <span className=\"mt-0.5 inline-flex size-7 shrink-0 items-center justify-center overflow-hidden rounded-md bg-surface-2 text-fg\">\n {headerMark}\n </span>\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-2xs text-fg-subtle\">{selectionLabel}</p>\n <p className=\"truncate text-sm font-medium text-fg\">{displayName}</p>\n {identity ? (\n <p className=\"truncate text-2xs text-fg-subtle\" title={identity}>\n {identity}\n </p>\n ) : null}\n <p className=\"truncate text-2xs text-fg-subtle\" title={metadata}>\n {metadata}\n </p>\n </div>\n </div>\n {usage.checking ? (\n <p className=\"text-2xs text-fg-subtle\">Checking usage…</p>\n ) : usage.unavailable ? (\n <p className=\"text-2xs text-fg-subtle\">Usage unavailable</p>\n ) : usage.message ? (\n <p className=\"text-2xs text-fg-subtle\">{usage.message}</p>\n ) : (\n <div className=\"max-h-36 space-y-1.5 overflow-y-auto overscroll-contain\">\n {usage.windows?.map((window) => (\n <UsageRow key={window.label} {...window} />\n ))}\n </div>\n )}\n {usage.note ? <p className=\"text-2xs text-fg-subtle\">{usage.note}</p> : null}\n </div>\n <DropdownMenuSeparator className=\"shrink-0\" />\n <DropdownMenuLabel className=\"shrink-0\">{actionLabel}</DropdownMenuLabel>\n <div className=\"min-h-0 flex-1 overflow-y-auto overscroll-contain\">\n <DropdownMenuItem\n disabled={choosing}\n onSelect={(event) => {\n event.preventDefault();\n onChoose(null);\n }}\n className=\"cursor-pointer\"\n >\n <span className=\"min-w-0 flex-1 truncate\">{automaticLabel}</span>\n {choosingTarget === null ? (\n <Loader2Icon className=\"size-4 shrink-0 animate-spin\" />\n ) : (\n <DropdownMenuCheck checked={automaticSelected} className=\"ml-0\" />\n )}\n </DropdownMenuItem>\n {accounts.filter((account) => !account.personal).map(row)}\n {personal.length > 0 ? (\n <>\n <DropdownMenuLabel className=\"pt-2\">Your accounts</DropdownMenuLabel>\n {personal.map(row)}\n </>\n ) : null}\n {accounts.length === 0 && emptyMessage ? (\n <DropdownMenuNote>{emptyMessage}</DropdownMenuNote>\n ) : null}\n {error ? (\n <DropdownMenuNote role=\"alert\" className=\"text-xs text-danger\">\n {error}\n </DropdownMenuNote>\n ) : (\n <p className=\"px-2.5 pt-1.5 pb-1 text-xs text-fg-muted\">{note}</p>\n )}\n </div>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n"],"mappings":"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","names":[]}