@opengeni/react 6.5.2-canary.41607687019001 → 6.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1154) hide show
  1. package/dist/app/app-state.d.ts +4 -0
  2. package/dist/app/app-state.js +19 -14
  3. package/dist/app/components/Composer.js +25 -23
  4. package/dist/app/components/agent/agent-capability-picker.js +10 -8
  5. package/dist/app/components/artifacts/artifact-browse-controls.js +4 -4
  6. package/dist/app/components/artifacts/artifact-library.js +21 -19
  7. package/dist/app/components/artifacts/artifact-page-chrome.js +3 -3
  8. package/dist/app/components/artifacts/artifact-viewer.js +23 -22
  9. package/dist/app/components/artifacts/artifact-viewer.js.map +1 -1
  10. package/dist/app/components/artifacts/chat-interactive-block.js +12 -12
  11. package/dist/app/components/artifacts/copy-artifact-link.js +7 -5
  12. package/dist/app/components/artifacts/file-reach-dialog.js +11 -9
  13. package/dist/app/components/artifacts/inline-chat-image.js +18 -18
  14. package/dist/app/components/artifacts/retained-file-preview.js +24 -23
  15. package/dist/app/components/artifacts/retained-text-preview.js +3 -3
  16. package/dist/app/components/artifacts/site-audience.js +6 -5
  17. package/dist/app/components/artifacts/site-conversations.js +16 -14
  18. package/dist/app/components/artifacts/site-data.js +18 -16
  19. package/dist/app/components/artifacts/site-public-link.js +3 -2
  20. package/dist/app/components/artifacts/site-publishing-page.js +39 -37
  21. package/dist/app/components/artifacts/site-publishing.js +34 -32
  22. package/dist/app/components/artifacts/site-settings.js +38 -36
  23. package/dist/app/components/artifacts/site-version-menu.js +8 -7
  24. package/dist/app/components/billing-class-mark.js +3 -3
  25. package/dist/app/components/bots/bot-launch-strip.js +17 -17
  26. package/dist/app/components/bots/bot-template-dialog.js +30 -28
  27. package/dist/app/components/bots/bot-template-shortcuts.js +19 -19
  28. package/dist/app/components/bots/bot-templates-page.js +38 -36
  29. package/dist/app/components/bots/bot-templates-page.js.map +1 -1
  30. package/dist/app/components/capabilities/capability-detail-sheet.js +13 -11
  31. package/dist/app/components/capabilities/capability-logo-source.js +13 -13
  32. package/dist/app/components/capabilities/capability-logo.js +4 -3
  33. package/dist/app/components/capabilities/connector-tool-permissions.js +8 -6
  34. package/dist/app/components/capabilities/native-connect-setup.js +14 -14
  35. package/dist/app/components/capabilities/own-logins-shared-heads-up.js +7 -6
  36. package/dist/app/components/capabilities/perform-capability-action.js +7 -6
  37. package/dist/app/components/capabilities/prepared-mcp-setup-card.js +17 -17
  38. package/dist/app/components/capabilities/session-capability-card.js +72 -70
  39. package/dist/app/components/capabilities/session-capability-card.js.map +1 -1
  40. package/dist/app/components/capabilities/session-chrome-card.js +28 -26
  41. package/dist/app/components/capabilities/session-connection-accounts.js +4 -3
  42. package/dist/app/components/capabilities/session-custom-mcp-card.js +20 -19
  43. package/dist/app/components/capabilities/session-github-card.js +22 -20
  44. package/dist/app/components/capabilities/session-machine-card.js +27 -25
  45. package/dist/app/components/capabilities/session-personal-github-card.js +16 -16
  46. package/dist/app/components/capabilities/session-plugin-card.js +10 -9
  47. package/dist/app/components/capabilities/use-capabilities-catalog.js +4 -3
  48. package/dist/app/components/capabilities/use-connection-accounts.js +5 -4
  49. package/dist/app/components/command-menu/chat-status.js +15 -13
  50. package/dist/app/components/command-menu/chat-switcher.js +35 -33
  51. package/dist/app/components/command-menu/chat-switcher.js.map +1 -1
  52. package/dist/app/components/command-menu/command-menu.js +53 -50
  53. package/dist/app/components/command-menu/command-menu.js.map +1 -1
  54. package/dist/app/components/command-menu/shortcut-sheet.js +18 -16
  55. package/dist/app/components/command-menu/shortcut-sheet.js.map +1 -1
  56. package/dist/app/components/common.js +4 -3
  57. package/dist/app/components/composer-capabilities-menu-body.js +4 -4
  58. package/dist/app/components/composer-mobile-plus-panel.js +8 -8
  59. package/dist/app/components/composer-mobile-plus.js +1 -1
  60. package/dist/app/components/credit-required-gate.js +3 -3
  61. package/dist/app/components/credit-required-prompt.js +10 -8
  62. package/dist/app/components/credit-required-prompt.js.map +1 -1
  63. package/dist/app/components/credits/checkout-credits-celebration.js +3 -2
  64. package/dist/app/components/credits/checkout-return.js +3 -2
  65. package/dist/app/components/credits/checkout-return.js.map +1 -1
  66. package/dist/app/components/credits/coupon-redeem.js +5 -4
  67. package/dist/app/components/credits/credit-refusal-notice.js +7 -5
  68. package/dist/app/components/cross-slot-deep-link-recovery.js +5 -4
  69. package/dist/app/components/desktop/app-shots.js +13 -11
  70. package/dist/app/components/desktop/computer-use.js +6 -4
  71. package/dist/app/components/desktop/this-computer.js +9 -7
  72. package/dist/app/components/feedback.js +5 -4
  73. package/dist/app/components/follow-up-repository-menu-body.js +8 -6
  74. package/dist/app/components/follow-up-repository-menu-body.js.map +1 -1
  75. package/dist/app/components/follow-up-repository-picker.js +1 -1
  76. package/dist/app/components/github-app-connect-launcher.js +5 -4
  77. package/dist/app/components/in-app-help-link.js +3 -3
  78. package/dist/app/components/knowledge/agent-learning-settings.js +3 -2
  79. package/dist/app/components/knowledge/agent-learning-settings.js.map +1 -1
  80. package/dist/app/components/machines/connect-machine-dialog.js +18 -16
  81. package/dist/app/components/manual-repository-editor.js +3 -2
  82. package/dist/app/components/markdown.js +6 -6
  83. package/dist/app/components/models/models-ui.js +12 -10
  84. package/dist/app/components/my-things.js +12 -10
  85. package/dist/app/components/my-things.js.map +1 -1
  86. package/dist/app/components/new-session-starters.js +3 -3
  87. package/dist/app/components/own-where-it-works.js +9 -7
  88. package/dist/app/components/personal-resource-attachment-surface.js +4 -4
  89. package/dist/app/components/pickers.js +5 -5
  90. package/dist/app/components/rail/channel-create-dialog.js +7 -5
  91. package/dist/app/components/rail/project-glyph.js +17 -17
  92. package/dist/app/components/rail/project-profile.js +31 -29
  93. package/dist/app/components/rail/rail-context.js +3 -3
  94. package/dist/app/components/rail/rail-sections.js +68 -66
  95. package/dist/app/components/rail/session-header.js +59 -57
  96. package/dist/app/components/rail/session-list.js +66 -64
  97. package/dist/app/components/rail/session-row-content.js +4 -4
  98. package/dist/app/components/rail/session-row-hover-details.js +14 -12
  99. package/dist/app/components/rail/session-shell.js +90 -88
  100. package/dist/app/components/rail/site-session-group-heading.js +8 -8
  101. package/dist/app/components/repository-picker.js +8 -6
  102. package/dist/app/components/secrets/session-secrets-panel.js +4 -3
  103. package/dist/app/components/secrets/vault-model.js +3 -2
  104. package/dist/app/components/session/agent-configuration-panel.js +25 -23
  105. package/dist/app/components/session/agent-configuration-panel.js.map +1 -1
  106. package/dist/app/components/session/artifact-link-boundary.js +3 -3
  107. package/dist/app/components/session/artifact-session-page.js +11 -9
  108. package/dist/app/components/session/banners.js +8 -8
  109. package/dist/app/components/session/codex-usage-notice.js +5 -3
  110. package/dist/app/components/session/console-new-conversation.js +42 -40
  111. package/dist/app/components/session/context-text-reader.js +3 -2
  112. package/dist/app/components/session/descendant-requests.js +39 -37
  113. package/dist/app/components/session/descendant-requests.js.map +1 -1
  114. package/dist/app/components/session/editable-artifacts-workspace.js +36 -34
  115. package/dist/app/components/session/editable-artifacts-workspace.js.map +1 -1
  116. package/dist/app/components/session/failed-session-banner.js +13 -11
  117. package/dist/app/components/session/failed-session-banner.js.map +1 -1
  118. package/dist/app/components/session/failure-recovery-boundary.js +3 -3
  119. package/dist/app/components/session/human-input-delegation-record.js +2 -2
  120. package/dist/app/components/session/human-input.js +33 -31
  121. package/dist/app/components/session/inspector.js +57 -55
  122. package/dist/app/components/session/inspector.js.map +1 -1
  123. package/dist/app/components/session/message-actions.js +5 -4
  124. package/dist/app/components/session/message-actions.js.map +1 -1
  125. package/dist/app/components/session/message-resource-attachments.js +12 -11
  126. package/dist/app/components/session/message-resource-attachments.js.map +1 -1
  127. package/dist/app/components/session/model-context-inspector.js +6 -4
  128. package/dist/app/components/session/model-recovery-notice.js +3 -3
  129. package/dist/app/components/session/new-session-settings-menu.js +11 -9
  130. package/dist/app/components/session/new-session-setup-strip.js +18 -18
  131. package/dist/app/components/session/sandbox-recovery-actions.js +3 -3
  132. package/dist/app/components/session/sandbox-switcher.js +10 -9
  133. package/dist/app/components/session/sandbox-workspace.js +47 -46
  134. package/dist/app/components/session/search-markdown-highlight.js +7 -7
  135. package/dist/app/components/session/search-results-view.js +8 -8
  136. package/dist/app/components/session/session-admin-access.js +13 -11
  137. package/dist/app/components/session/session-admission-notice.js +7 -5
  138. package/dist/app/components/session/session-avatar-picker.js +22 -20
  139. package/dist/app/components/session/session-avatar.js +16 -16
  140. package/dist/app/components/session/session-machine-access-notice.js +7 -5
  141. package/dist/app/components/session/session-profile-dialog.js +29 -27
  142. package/dist/app/components/session/session-profile-editor.js +30 -28
  143. package/dist/app/components/session/session-retention.js +10 -8
  144. package/dist/app/components/session/session-search-dialog.js +10 -10
  145. package/dist/app/components/session/session-skill-reviews.js +2 -1
  146. package/dist/app/components/session/session-skill-reviews.js.map +1 -1
  147. package/dist/app/components/session/session-tenancy-control.js +13 -11
  148. package/dist/app/components/session/session-tenancy-control.js.map +1 -1
  149. package/dist/app/components/session/session-unattended-setting.js +7 -5
  150. package/dist/app/components/session/session-usage-limit-section.js +11 -9
  151. package/dist/app/components/session/share-chat-dialog.js +9 -7
  152. package/dist/app/components/session/site-origin-link.js +3 -3
  153. package/dist/app/components/session/subagents.js +8 -8
  154. package/dist/app/components/session/subscription-account-indicator.js +6 -6
  155. package/dist/app/components/session-connectors-menu-body.js +4 -3
  156. package/dist/app/components/session-connectors-menu-body.js.map +1 -1
  157. package/dist/app/components/settings/row-select.js +7 -5
  158. package/dist/app/components/toaster.js +3 -2
  159. package/dist/app/components/transcription-settings.js +11 -9
  160. package/dist/app/components/ui/destructive-confirm.js +11 -9
  161. package/dist/app/components/usage/usage-entry.js +5 -5
  162. package/dist/app/components/window-bar.js +16 -14
  163. package/dist/app/components/workspace-composer-plus.js +22 -21
  164. package/dist/app/components/workspace-reach.js +6 -4
  165. package/dist/app/components/workspace-tenant-boundary.js +5 -4
  166. package/dist/app/embed/memory-navigation.js +3 -3
  167. package/dist/app/embed/session-app.js +211 -209
  168. package/dist/app/lib/actions/actions-provider.js +15 -13
  169. package/dist/app/lib/agent-capabilities.js +3 -3
  170. package/dist/app/lib/app-surfaces.js +7 -6
  171. package/dist/app/lib/archive-session.d.ts +9 -4
  172. package/dist/app/lib/archive-session.js +4 -2
  173. package/dist/app/lib/bot-templates.js +3 -2
  174. package/dist/app/lib/capabilities.js +3 -2
  175. package/dist/app/lib/codex-usage-query.js +2 -2
  176. package/dist/app/lib/composer-connectors.js +17 -16
  177. package/dist/app/lib/console-site.js +2 -2
  178. package/dist/app/lib/console-text.js +2 -2
  179. package/dist/app/lib/events.js +9 -9
  180. package/dist/app/lib/failed-session-copy.js +3 -3
  181. package/dist/app/lib/inbox.js +4 -2
  182. package/dist/app/lib/model-access-onboarding.js +3 -3
  183. package/dist/app/lib/move-chat-to-machine.js +3 -3
  184. package/dist/app/lib/navigation.js +2 -2
  185. package/dist/app/lib/session-branch-cache.js +6 -6
  186. package/dist/app/lib/session-create.js +4 -4
  187. package/dist/app/lib/session-group-pagination.js +6 -6
  188. package/dist/app/lib/session-hover-facts.js +13 -11
  189. package/dist/app/lib/session-model.js +2 -2
  190. package/dist/app/lib/session-rail.js +3 -3
  191. package/dist/app/lib/session-rename.js +3 -3
  192. package/dist/app/lib/session-restart-operation-controller.js +4 -3
  193. package/dist/app/lib/session-tenancy.js +3 -2
  194. package/dist/app/lib/session-usage-limit.js +3 -2
  195. package/dist/app/lib/sessions-group.js +5 -5
  196. package/dist/app/lib/site-publishing.js +3 -2
  197. package/dist/app/lib/site-tool-consent-dialog.js +9 -7
  198. package/dist/app/lib/site-tool-consent-dialog.js.map +1 -1
  199. package/dist/app/lib/site-tool-consent.js +1 -1
  200. package/dist/app/lib/subscription-plans.js +3 -2
  201. package/dist/app/lib/toast.js +2 -1
  202. package/dist/app/lib/turn-failure-analytics.js +4 -4
  203. package/dist/app/lib/use-duplicate-site.js +6 -5
  204. package/dist/app/lib/use-follow-up-repositories.js +6 -5
  205. package/dist/app/lib/use-workspace-integrations.js +4 -3
  206. package/dist/app/lib/use-workspace-machines.js +4 -4
  207. package/dist/app/lib/use-workspace-model-catalog.js +5 -4
  208. package/dist/app/lib/use-workspace-rigs.js +2 -2
  209. package/dist/app/lib/workspace-navigation-preference.js +4 -4
  210. package/dist/app/lib/workspace-scope-context.js +3 -3
  211. package/dist/app/routes/artifacts.js +67 -66
  212. package/dist/app/routes/artifacts.js.map +1 -1
  213. package/dist/app/routes/retained-artifact.js +42 -40
  214. package/dist/app/routes/retained-artifact.js.map +1 -1
  215. package/dist/app/routes/session-unavailable.js +8 -7
  216. package/dist/app/routes/session.js +119 -117
  217. package/dist/app/routes/sessions-index-hydration.js +5 -5
  218. package/dist/app/routes/sessions-index.js +104 -102
  219. package/dist/app/routes/site-view.js +67 -65
  220. package/dist/app/routes/site-view.js.map +1 -1
  221. package/dist/artifacts-document.js +4 -4
  222. package/dist/artifacts-presentation.js +4 -4
  223. package/dist/artifacts-spreadsheet.js +4 -4
  224. package/dist/artifacts.js +10 -10
  225. package/dist/automations.js +17 -15
  226. package/dist/automations.js.map +1 -1
  227. package/dist/browser-viewer-TC27OCIP.js +23 -0
  228. package/dist/chat-interactive-block-RWPQBHVS.js +18 -0
  229. package/dist/chunk-2BDT3UZQ.js +229 -0
  230. package/dist/chunk-2CLNIEK4.js +373 -0
  231. package/dist/chunk-2FSBSCZJ.js +451 -0
  232. package/dist/chunk-2I7HDP53.js +199 -0
  233. package/dist/chunk-2INLDVK3.js +15 -0
  234. package/dist/chunk-2KALVELR.js +126 -0
  235. package/dist/chunk-2M3J7ZWQ.js +418 -0
  236. package/dist/chunk-2OP6WLGV.js +708 -0
  237. package/dist/chunk-2RG7NIAS.js +2936 -0
  238. package/dist/chunk-2STUPWEL.js +135 -0
  239. package/dist/chunk-2YUOVM3G.js +271 -0
  240. package/dist/chunk-2Z3NQNTM.js +3670 -0
  241. package/dist/chunk-3CPWWGNK.js +920 -0
  242. package/dist/chunk-3ED2U6XE.js +37 -0
  243. package/dist/chunk-3GZA4BUW.js +216 -0
  244. package/dist/chunk-3IK6UYO6.js +1022 -0
  245. package/dist/chunk-3PZ7JZI2.js +431 -0
  246. package/dist/chunk-4DVJ6ONS.js +50 -0
  247. package/dist/chunk-4DVNUCRR.js +2386 -0
  248. package/dist/chunk-4DVNUCRR.js.map +1 -0
  249. package/dist/chunk-4E3ZJRTZ.js +41 -0
  250. package/dist/chunk-4SAWSRAA.js +141 -0
  251. package/dist/chunk-53AGXXZM.js +307 -0
  252. package/dist/chunk-54YW6SZZ.js +818 -0
  253. package/dist/chunk-57AZS3IE.js +2317 -0
  254. package/dist/chunk-5CPEEAFD.js +143 -0
  255. package/dist/chunk-5EWSRZ2Y.js +340 -0
  256. package/dist/chunk-5IE76VCY.js +387 -0
  257. package/dist/chunk-5NWEKLDZ.js +170 -0
  258. package/dist/chunk-5O2FCCHZ.js +198 -0
  259. package/dist/chunk-5QAY6K77.js +399 -0
  260. package/dist/chunk-5YKW2K6I.js +625 -0
  261. package/dist/chunk-5YKW2K6I.js.map +1 -0
  262. package/dist/chunk-6BCXNDEI.js +4116 -0
  263. package/dist/chunk-6BCXNDEI.js.map +1 -0
  264. package/dist/chunk-6DK6Z4UN.js +2599 -0
  265. package/dist/chunk-6DVCC7QS.js +702 -0
  266. package/dist/chunk-6JHU2UBS.js +2058 -0
  267. package/dist/chunk-6PZ7OBYU.js +490 -0
  268. package/dist/chunk-6WD2INST.js +539 -0
  269. package/dist/chunk-6WD2INST.js.map +1 -0
  270. package/dist/chunk-6WGRDRMA.js +163 -0
  271. package/dist/chunk-77WAKEAH.js +186 -0
  272. package/dist/chunk-7T2ZE3VT.js +5558 -0
  273. package/dist/chunk-7T2ZE3VT.js.map +1 -0
  274. package/dist/chunk-7TDO3CUM.js +393 -0
  275. package/dist/chunk-7TIX2UAR.js +247 -0
  276. package/dist/chunk-7V5REBCP.js +148 -0
  277. package/dist/chunk-7VMZGLYI.js +339 -0
  278. package/dist/chunk-7W37NS3I.js +236 -0
  279. package/dist/chunk-7X6SDK2C.js +111 -0
  280. package/dist/chunk-7ZNUHRP5.js +95 -0
  281. package/dist/chunk-A36PZALD.js +84 -0
  282. package/dist/chunk-AUI6VA63.js +107 -0
  283. package/dist/chunk-AW2MQB37.js +24 -0
  284. package/dist/chunk-AWKES45Y.js +198 -0
  285. package/dist/chunk-AXHZYXUV.js +132 -0
  286. package/dist/chunk-BHNSJVBC.js +129 -0
  287. package/dist/chunk-BJEJFISW.js +50 -0
  288. package/dist/chunk-BJFH6JI5.js +422 -0
  289. package/dist/chunk-BMICEQZQ.js +960 -0
  290. package/dist/chunk-BTLBYBLU.js +29 -0
  291. package/dist/chunk-BXBDYNRP.js +89 -0
  292. package/dist/chunk-C372BFOV.js +357 -0
  293. package/dist/chunk-C43KRXGA.js +234 -0
  294. package/dist/chunk-C43KRXGA.js.map +1 -0
  295. package/dist/chunk-CMKGILJK.js +4824 -0
  296. package/dist/chunk-CRAOSVHC.js +50 -0
  297. package/dist/chunk-CRU35QQH.js +281 -0
  298. package/dist/chunk-CUIWCGMA.js +172 -0
  299. package/dist/chunk-D5TWNFFE.js +38 -0
  300. package/dist/chunk-DF5EAHDN.js +4461 -0
  301. package/dist/chunk-DJAXC5OK.js +56 -0
  302. package/dist/chunk-DXBYWSL5.js +3550 -0
  303. package/dist/chunk-DXR5PDFP.js +84 -0
  304. package/dist/chunk-DZWARC4M.js +267 -0
  305. package/dist/chunk-DZXEDSQI.js +106 -0
  306. package/dist/chunk-E7XERZWC.js +48 -0
  307. package/dist/chunk-ECJBYNLJ.js +79 -0
  308. package/dist/chunk-EDI6SJ2N.js +43 -0
  309. package/dist/chunk-EWSOC6WF.js +114 -0
  310. package/dist/chunk-F2OPHAUN.js +103 -0
  311. package/dist/chunk-F4ISQGGM.js +81 -0
  312. package/dist/chunk-FO4LYKJL.js +197 -0
  313. package/dist/chunk-FPXASDG5.js +73 -0
  314. package/dist/chunk-FSOQDUCG.js +117 -0
  315. package/dist/chunk-FSOQDUCG.js.map +1 -0
  316. package/dist/chunk-FVXBNBHO.js +157 -0
  317. package/dist/chunk-FYWT2O76.js +34 -0
  318. package/dist/chunk-FYWT2O76.js.map +1 -0
  319. package/dist/chunk-FZC5N55X.js +981 -0
  320. package/dist/chunk-GAVYGBFI.js +99 -0
  321. package/dist/chunk-GFIMOUDT.js +846 -0
  322. package/dist/chunk-GFIMOUDT.js.map +1 -0
  323. package/dist/chunk-GKVJIDHF.js +33 -0
  324. package/dist/chunk-GVN5SZLX.js +212 -0
  325. package/dist/chunk-H3T7IWNA.js +134 -0
  326. package/dist/chunk-HAX4LCR5.js +261 -0
  327. package/dist/chunk-HC4JFZVU.js +121 -0
  328. package/dist/chunk-HEFPPMBQ.js +581 -0
  329. package/dist/chunk-HGKTHF2U.js +1356 -0
  330. package/dist/chunk-HGKTHF2U.js.map +1 -0
  331. package/dist/chunk-HNLR7Q4Z.js +83 -0
  332. package/dist/chunk-HSOXMJOT.js +12 -0
  333. package/dist/chunk-I4MRDSUF.js +281 -0
  334. package/dist/chunk-I4QEJ62Y.js +202 -0
  335. package/dist/chunk-I5B5L6Q4.js +56 -0
  336. package/dist/chunk-I5QZJODL.js +264 -0
  337. package/dist/chunk-I7ITSXSJ.js +603 -0
  338. package/dist/chunk-I7XIZRFD.js +390 -0
  339. package/dist/chunk-IDANQPRH.js +82 -0
  340. package/dist/chunk-IFB3WJ36.js +212 -0
  341. package/dist/chunk-IHTAKKTK.js +264 -0
  342. package/dist/chunk-IKXNLWAL.js +205 -0
  343. package/dist/chunk-IKXNLWAL.js.map +1 -0
  344. package/dist/chunk-ILDXWY37.js +173 -0
  345. package/dist/chunk-IMDQUHBJ.js +570 -0
  346. package/dist/chunk-IMZCQBOT.js +119 -0
  347. package/dist/chunk-IXPTECSC.js +403 -0
  348. package/dist/chunk-J255A3N5.js +71 -0
  349. package/dist/chunk-J5F5HPPW.js +141 -0
  350. package/dist/chunk-JDTGRRNU.js +5045 -0
  351. package/dist/chunk-JDTGRRNU.js.map +1 -0
  352. package/dist/chunk-JEA3QDX7.js +2469 -0
  353. package/dist/chunk-JEUPAVYY.js +156 -0
  354. package/dist/chunk-JKHKLL5W.js +194 -0
  355. package/dist/chunk-JQL7ZH6C.js +650 -0
  356. package/dist/chunk-JWB44UGJ.js +57 -0
  357. package/dist/chunk-JZ4NLCAP.js +333 -0
  358. package/dist/chunk-K2A5PXQ5.js +412 -0
  359. package/dist/chunk-K56XV3C3.js +623 -0
  360. package/dist/chunk-K6GAXXVA.js +23 -0
  361. package/dist/chunk-KCBMFSMS.js +199 -0
  362. package/dist/chunk-KF2FV3ZJ.js +268 -0
  363. package/dist/chunk-KJD65EJP.js +278 -0
  364. package/dist/chunk-KLEUWIMZ.js +386 -0
  365. package/dist/chunk-KODELWYT.js +309 -0
  366. package/dist/chunk-KRDR5RJD.js +83 -0
  367. package/dist/chunk-KUDGXAF7.js +914 -0
  368. package/dist/chunk-KY2R73CG.js +171 -0
  369. package/dist/chunk-KY2R73CG.js.map +1 -0
  370. package/dist/chunk-KYS77RPN.js +85 -0
  371. package/dist/chunk-L7YTNTIK.js +368 -0
  372. package/dist/chunk-LHPNABDH.js +686 -0
  373. package/dist/chunk-MFROMEKA.js +401 -0
  374. package/dist/chunk-MIHN76LX.js +2656 -0
  375. package/dist/chunk-MIYFS2XN.js +42 -0
  376. package/dist/chunk-MJUCFQMS.js +65 -0
  377. package/dist/chunk-MM4FNWI4.js +3064 -0
  378. package/dist/chunk-MNZG4OHU.js +790 -0
  379. package/dist/chunk-MVW6HNPI.js +250 -0
  380. package/dist/chunk-MVW6HNPI.js.map +1 -0
  381. package/dist/chunk-N6AACDUW.js +200 -0
  382. package/dist/chunk-NC55IFN3.js +781 -0
  383. package/dist/chunk-NC7PVOEK.js +98 -0
  384. package/dist/chunk-NCYMNCJO.js +70 -0
  385. package/dist/chunk-ND2BXV3P.js +259 -0
  386. package/dist/chunk-NDBTFUO6.js +272 -0
  387. package/dist/chunk-NDQJZ7HF.js +206 -0
  388. package/dist/chunk-NGJJJPZZ.js +162 -0
  389. package/dist/chunk-NJTSNNE7.js +251 -0
  390. package/dist/chunk-NPGISCU6.js +4159 -0
  391. package/dist/chunk-NPGISCU6.js.map +1 -0
  392. package/dist/chunk-NRTE7DNV.js +1270 -0
  393. package/dist/chunk-NULUNM7H.js +290 -0
  394. package/dist/chunk-NUNZS36W.js +227 -0
  395. package/dist/chunk-NW53H5RW.js +2424 -0
  396. package/dist/chunk-NXCMHIKI.js +263 -0
  397. package/dist/chunk-O3LKCBP5.js +159 -0
  398. package/dist/chunk-O4EA4F3W.js +103 -0
  399. package/dist/chunk-O4EA4F3W.js.map +1 -0
  400. package/dist/chunk-O4OOG3D6.js +116 -0
  401. package/dist/chunk-O4OOG3D6.js.map +1 -0
  402. package/dist/chunk-O6N4ABCA.js +376 -0
  403. package/dist/chunk-O732GAFC.js +112 -0
  404. package/dist/chunk-OF4TIKYC.js +690 -0
  405. package/dist/chunk-OMPVOMPP.js +70 -0
  406. package/dist/chunk-OPJJSKUK.js +118 -0
  407. package/dist/chunk-OPWCMA4D.js +196 -0
  408. package/dist/chunk-ORJPS5VN.js +1193 -0
  409. package/dist/chunk-OSY5K7L7.js +187 -0
  410. package/dist/chunk-OV6QJRT4.js +45 -0
  411. package/dist/chunk-OVKYVZMW.js +108 -0
  412. package/dist/chunk-OZCBM3UC.js +171 -0
  413. package/dist/chunk-P3A2EINJ.js +61 -0
  414. package/dist/chunk-PTAG4PDC.js +27 -0
  415. package/dist/chunk-PTF5B7TJ.js +298 -0
  416. package/dist/chunk-Q3DPEYX4.js +848 -0
  417. package/dist/chunk-Q6CGOPJD.js +215 -0
  418. package/dist/chunk-Q6CGOPJD.js.map +1 -0
  419. package/dist/chunk-QB2KMIDP.js +100 -0
  420. package/dist/chunk-QCSJ4CWE.js +1067 -0
  421. package/dist/chunk-QIOQ2NPQ.js +414 -0
  422. package/dist/chunk-QK5EFEUT.js +353 -0
  423. package/dist/chunk-QPQBLYQJ.js +41 -0
  424. package/dist/chunk-QPSGCC5D.js +184 -0
  425. package/dist/chunk-QZAAUQRN.js +474 -0
  426. package/dist/chunk-QZM6YDJW.js +489 -0
  427. package/dist/chunk-QZM6YDJW.js.map +1 -0
  428. package/dist/chunk-RGBI63KJ.js +188 -0
  429. package/dist/chunk-RLBKLAEY.js +138 -0
  430. package/dist/chunk-RMFKVOM7.js +304 -0
  431. package/dist/chunk-ROKQU7WG.js +258 -0
  432. package/dist/chunk-RPVREAU7.js +251 -0
  433. package/dist/chunk-RQKLF42C.js +723 -0
  434. package/dist/chunk-SC6RRD2D.js +38 -0
  435. package/dist/chunk-SC6RRD2D.js.map +1 -0
  436. package/dist/chunk-SEO7TICN.js +94 -0
  437. package/dist/chunk-SHHJCL7X.js +432 -0
  438. package/dist/chunk-SIRLACNZ.js +114 -0
  439. package/dist/chunk-SKPHMYAA.js +237 -0
  440. package/dist/chunk-SODC7T6L.js +1583 -0
  441. package/dist/chunk-SQJIKMN3.js +366 -0
  442. package/dist/chunk-SVINDKVW.js +26 -0
  443. package/dist/chunk-SYCDHPZF.js +335 -0
  444. package/dist/chunk-T2QX3FDP.js +133 -0
  445. package/dist/chunk-T3OWFVMS.js +1187 -0
  446. package/dist/chunk-T6XI5FLY.js +61 -0
  447. package/dist/chunk-T7OXJZCX.js +62 -0
  448. package/dist/chunk-TAT5USZN.js +353 -0
  449. package/dist/chunk-TPQTRNER.js +172 -0
  450. package/dist/chunk-TUIN4MB7.js +266 -0
  451. package/dist/chunk-TX3VECZU.js +71 -0
  452. package/dist/chunk-TXLIEOJX.js +9624 -0
  453. package/dist/chunk-U3DN4HEY.js +27 -0
  454. package/dist/chunk-U7XM7CB4.js +191 -0
  455. package/dist/chunk-UJK53QFL.js +140 -0
  456. package/dist/chunk-UMTXA2TH.js +319 -0
  457. package/dist/chunk-UPDSXFK5.js +199 -0
  458. package/dist/chunk-UTIAXH52.js +269 -0
  459. package/dist/chunk-UVN5TMHU.js +1184 -0
  460. package/dist/chunk-V4Z4B2E3.js +52 -0
  461. package/dist/chunk-V4Z4B2E3.js.map +1 -0
  462. package/dist/chunk-VGYXW3VG.js +246 -0
  463. package/dist/chunk-VS7AHPCZ.js +255 -0
  464. package/dist/chunk-VTTAJOQ7.js +121 -0
  465. package/dist/chunk-VWPOLUAO.js +99 -0
  466. package/dist/chunk-X3MWB2QU.js +3851 -0
  467. package/dist/chunk-X6KAJI3V.js +211 -0
  468. package/dist/chunk-XBLRHV5R.js +50 -0
  469. package/dist/chunk-XDFP2LMW.js +605 -0
  470. package/dist/chunk-XEQMZB3C.js +525 -0
  471. package/dist/chunk-XEYLT5VA.js +223 -0
  472. package/dist/chunk-XHIQ5I6N.js +918 -0
  473. package/dist/chunk-XLH7QY2R.js +378 -0
  474. package/dist/chunk-XWFAMUZQ.js +113 -0
  475. package/dist/chunk-Y4BB2KS2.js +294 -0
  476. package/dist/chunk-Y4BB2KS2.js.map +1 -0
  477. package/dist/chunk-Y4OBB2VN.js +84 -0
  478. package/dist/chunk-YCVD6CI3.js +234 -0
  479. package/dist/chunk-YENLNISG.js +270 -0
  480. package/dist/chunk-YIRVLKAX.js +351 -0
  481. package/dist/chunk-YL73CVNK.js +390 -0
  482. package/dist/chunk-YLS6QE5G.js +288 -0
  483. package/dist/chunk-YNF2OC54.js +366 -0
  484. package/dist/chunk-YNF2OC54.js.map +1 -0
  485. package/dist/chunk-YPWU5KPE.js +147 -0
  486. package/dist/chunk-YQXTDZSU.js +2984 -0
  487. package/dist/chunk-YSJEAAOL.js +178 -0
  488. package/dist/chunk-YWIFM7D7.js +499 -0
  489. package/dist/chunk-YWVI6ZMK.js +103 -0
  490. package/dist/chunk-Z4FMAFNH.js +847 -0
  491. package/dist/chunk-Z654FWNU.js +136 -0
  492. package/dist/chunk-Z7Y523PS.js +130 -0
  493. package/dist/chunk-ZD67RM6G.js +60 -0
  494. package/dist/chunk-ZEG4VPBL.js +187 -0
  495. package/dist/chunk-ZHDFQITM.js +283 -0
  496. package/dist/chunk-ZHDFQITM.js.map +1 -0
  497. package/dist/chunk-ZLYCOBHW.js +75 -0
  498. package/dist/chunk-ZNJ5MTXV.js +89 -0
  499. package/dist/chunk-ZSGY3H53.js +155 -0
  500. package/dist/chunk-ZTPXACWB.js +1788 -0
  501. package/dist/chunk-ZUA3JMI6.js +107 -0
  502. package/dist/chunk-ZYAZUPPV.js +559 -0
  503. package/dist/composer.js +8 -8
  504. package/dist/computer-viewer-TDDO25AV.js +21 -0
  505. package/dist/connect.js +12 -12
  506. package/dist/desktop-dictation.js +12 -10
  507. package/dist/desktop-dictation.js.map +1 -1
  508. package/dist/desktop.js +2 -2
  509. package/dist/editor.js +2 -2
  510. package/dist/embedded-new-voice-2G3VLPVQ.js +24 -0
  511. package/dist/embedded-voice-T5IWOWGD.js +24 -0
  512. package/dist/fleet-decision-row-WM64KXP3.js +361 -0
  513. package/dist/in-chat-connect-model.js +5 -5
  514. package/dist/index.js +51 -51
  515. package/dist/interaction.js +5 -5
  516. package/dist/machines.js +3 -3
  517. package/dist/meetings-recorder.js +1 -1
  518. package/dist/meetings.js +40 -32
  519. package/dist/meetings.js.map +1 -1
  520. package/dist/messages/en.d.ts +3 -0
  521. package/dist/messages.js +1 -1
  522. package/dist/model-policy-picker-menu-SMC6J6QN.js +22 -0
  523. package/dist/payment-page-card-G4U63KUV.js +223 -0
  524. package/dist/platform-activity-row-BUZGZAKZ.js +128 -0
  525. package/dist/queue-surface-implementation-4KUZ4PJV.js +908 -0
  526. package/dist/realtime.js +4 -4
  527. package/dist/recorder-host-WF2RRR56.js +69 -0
  528. package/dist/recorder-host-WF2RRR56.js.map +1 -0
  529. package/dist/recordings.js +3 -3
  530. package/dist/sandbox-files-ESDMOFSD.js +27 -0
  531. package/dist/session-app.js +211 -209
  532. package/dist/session-connect-cards-Q53KMMYY.js +25 -0
  533. package/dist/session-list-model.js +2 -2
  534. package/dist/session-realtime-CF3I35WJ.js +30 -0
  535. package/dist/session-realtime.js +2 -2
  536. package/dist/session-ui.js +33 -31
  537. package/dist/session.js +5 -5
  538. package/dist/sites.js +2 -2
  539. package/dist/terminal.js +2 -2
  540. package/dist/this-computer.js +3 -3
  541. package/dist/timeline-annotation-markers-CJK4RYZ4.js +157 -0
  542. package/dist/timeline-annotation-selection-67GF5H26.js +208 -0
  543. package/dist/timeline-annotations-dialog-ONJPQDJQ.js +283 -0
  544. package/dist/ui/access-list.js +11 -9
  545. package/dist/ui/access-list.js.map +1 -1
  546. package/dist/ui/api-error.d.ts +6 -3
  547. package/dist/ui/api-error.js +2 -1
  548. package/dist/ui/cadence-picker.js +6 -4
  549. package/dist/ui/choice-cards.js +5 -3
  550. package/dist/ui/confirm-dialog.js +2 -2
  551. package/dist/ui/copy-field.js +5 -3
  552. package/dist/ui/detail-page.js +2 -2
  553. package/dist/ui/detail-sheet.js +2 -2
  554. package/dist/ui/diff-view.js +4 -3
  555. package/dist/ui/disclosure.js +3 -3
  556. package/dist/ui/email-chips-input.js +5 -3
  557. package/dist/ui/error-message.js +2 -1
  558. package/dist/ui/error-reference.d.ts +15 -0
  559. package/dist/ui/error-text.d.ts +10 -0
  560. package/dist/ui/error-text.js +9 -0
  561. package/dist/ui/error-text.js.map +1 -0
  562. package/dist/ui/field.js +4 -2
  563. package/dist/ui/flush-form-page.js +8 -6
  564. package/dist/ui/form-dialog.js +7 -5
  565. package/dist/ui/list-row.js +3 -3
  566. package/dist/ui/load-failure.js +3 -2
  567. package/dist/ui/load-failure.js.map +1 -1
  568. package/dist/ui/notice.js +3 -1
  569. package/dist/ui/relative-time.js +2 -2
  570. package/dist/ui/revision-history.js +9 -7
  571. package/dist/ui/revision-history.js.map +1 -1
  572. package/dist/ui/role-select.js +10 -8
  573. package/dist/ui/segmented-control.js +4 -2
  574. package/dist/ui/select-menu.js +5 -3
  575. package/dist/ui/setting-row.js +3 -1
  576. package/dist/ui/switch.js +4 -2
  577. package/dist/ui/usage-meter.js +3 -3
  578. package/dist/ui/word-list-row.js +4 -2
  579. package/dist/usage.js +2 -2
  580. package/dist/workbench.js +4 -4
  581. package/package.json +5 -6
  582. package/src/app/app-state.tsx +126 -14
  583. package/src/app/components/artifacts/site-data.tsx +2 -2
  584. package/src/app/components/artifacts/site-settings.tsx +2 -2
  585. package/src/app/components/rail/session-list.tsx +7 -8
  586. package/src/app/components/rail/session-shell.tsx +3 -3
  587. package/src/app/components/repository-picker.tsx +8 -1
  588. package/src/app/components/session/model-context-inspector.tsx +2 -1
  589. package/src/app/components/session/session-admin-access.tsx +2 -2
  590. package/src/app/lib/actions/chat-operations.ts +4 -4
  591. package/src/app/lib/archive-session.test.tsx +265 -2
  592. package/src/app/lib/archive-session.tsx +175 -9
  593. package/src/app/lib/copy-link.ts +2 -2
  594. package/src/app/lib/inbox.tsx +2 -2
  595. package/src/app/lib/session-failure-toasts.ts +3 -2
  596. package/src/app/lib/toast.test.tsx +215 -0
  597. package/src/app/lib/toast.tsx +67 -2
  598. package/src/app/personal-github-reconnect.test.tsx +356 -0
  599. package/src/app/routes/artifacts.tsx +1 -2
  600. package/src/components/tool-action-review.tsx +14 -1
  601. package/src/meetings/delete-meeting-dialog.tsx +2 -1
  602. package/src/meetings/meeting-ask.tsx +2 -1
  603. package/src/meetings/meeting-detail-page.tsx +2 -1
  604. package/src/meetings/meeting-notes.tsx +2 -1
  605. package/src/meetings/meeting-settings.tsx +4 -1
  606. package/src/meetings/meeting-transcript.tsx +4 -1
  607. package/src/meetings/recorder-context.tsx +10 -0
  608. package/src/meetings/recorder-host.test.tsx +60 -2
  609. package/src/meetings/recorder-host.tsx +16 -3
  610. package/src/meetings/recorder-panel.tsx +2 -1
  611. package/src/meetings/recorder-workspace.test.tsx +26 -1
  612. package/src/messages/en.ts +6 -0
  613. package/src/ui/api-error.test.ts +29 -5
  614. package/src/ui/api-error.tsx +10 -4
  615. package/src/ui/error-message.tsx +8 -0
  616. package/src/ui/error-reference.test.ts +54 -0
  617. package/src/ui/error-reference.ts +51 -0
  618. package/src/ui/error-text.test.tsx +66 -0
  619. package/src/ui/error-text.tsx +49 -0
  620. package/src/ui/field.tsx +4 -1
  621. package/src/ui/notice.tsx +7 -2
  622. package/src/ui/setting-row.tsx +4 -1
  623. package/styles/app.css +12 -0
  624. package/styles/compiled.css +9 -0
  625. package/dist/browser-viewer-NOP5EAUO.js +0 -23
  626. package/dist/chat-interactive-block-G7O44JHR.js +0 -18
  627. package/dist/chunk-26RWVLRD.js +0 -135
  628. package/dist/chunk-2AHTY7OT.js +0 -247
  629. package/dist/chunk-2GDNWKSC.js +0 -3670
  630. package/dist/chunk-2JENKGCE.js +0 -339
  631. package/dist/chunk-2KYQC4T5.js +0 -155
  632. package/dist/chunk-2RREGDQH.js +0 -708
  633. package/dist/chunk-2T7DX6KR.js +0 -353
  634. package/dist/chunk-2VB2O4FQ.js +0 -920
  635. package/dist/chunk-2VTTKH23.js +0 -94
  636. package/dist/chunk-2XNG2KNT.js +0 -172
  637. package/dist/chunk-2YC6JQRO.js +0 -399
  638. package/dist/chunk-2ZVRJRXC.js +0 -27
  639. package/dist/chunk-35737UT4.js +0 -162
  640. package/dist/chunk-366XZ4PM.js +0 -41
  641. package/dist/chunk-36MIDGAH.js +0 -199
  642. package/dist/chunk-3FD76LXM.js +0 -212
  643. package/dist/chunk-3OVIXY4O.js +0 -213
  644. package/dist/chunk-3OVIXY4O.js.map +0 -1
  645. package/dist/chunk-3QNRBEYH.js +0 -432
  646. package/dist/chunk-3QX55WLC.js +0 -15
  647. package/dist/chunk-3USJPT2S.js +0 -1022
  648. package/dist/chunk-42CMQ5VR.js +0 -251
  649. package/dist/chunk-4LPOWQJY.js +0 -42
  650. package/dist/chunk-4NBTZRKT.js +0 -79
  651. package/dist/chunk-4OXI6HCV.js +0 -118
  652. package/dist/chunk-4SZZAFYQ.js +0 -2317
  653. package/dist/chunk-4TQL3WP2.js +0 -140
  654. package/dist/chunk-4Y6BK7IU.js +0 -196
  655. package/dist/chunk-4YD7YZC5.js +0 -373
  656. package/dist/chunk-5DTST3TP.js +0 -81
  657. package/dist/chunk-5FH5LQVS.js +0 -130
  658. package/dist/chunk-5KWMYPJV.js +0 -847
  659. package/dist/chunk-5MUJDC6C.js +0 -84
  660. package/dist/chunk-5QM2WPKV.js +0 -41
  661. package/dist/chunk-5WUN7XPD.js +0 -1184
  662. package/dist/chunk-64PO2WXU.js +0 -1067
  663. package/dist/chunk-6AHATAAY.js +0 -431
  664. package/dist/chunk-6ED2YWBT.js +0 -56
  665. package/dist/chunk-6GXVYAGR.js +0 -170
  666. package/dist/chunk-6H4SJBPE.js +0 -85
  667. package/dist/chunk-6MT3HHUB.js +0 -84
  668. package/dist/chunk-6UHCBH4G.js +0 -198
  669. package/dist/chunk-6WLX3NR3.js +0 -198
  670. package/dist/chunk-73NXYYWE.js +0 -112
  671. package/dist/chunk-76ERNKIZ.js +0 -603
  672. package/dist/chunk-776QZ573.js +0 -57
  673. package/dist/chunk-7BYWOFVH.js +0 -171
  674. package/dist/chunk-7O5CGGIQ.js +0 -108
  675. package/dist/chunk-7QOHRZ67.js +0 -251
  676. package/dist/chunk-7WIDB4PL.js +0 -2058
  677. package/dist/chunk-7WKP3DYJ.js +0 -37
  678. package/dist/chunk-7XOVTPDI.js +0 -227
  679. package/dist/chunk-AB5MBIXY.js +0 -281
  680. package/dist/chunk-ADNMXBCX.js +0 -1193
  681. package/dist/chunk-AFBJTUFK.js +0 -202
  682. package/dist/chunk-ALVRWCXE.js +0 -61
  683. package/dist/chunk-AOHU6O3M.js +0 -247
  684. package/dist/chunk-AOHU6O3M.js.map +0 -1
  685. package/dist/chunk-APW4T4SW.js +0 -270
  686. package/dist/chunk-AXBSYWKX.js +0 -2656
  687. package/dist/chunk-B2I5ZW35.js +0 -422
  688. package/dist/chunk-B3LMRTRF.js +0 -223
  689. package/dist/chunk-BE2XENG2.js +0 -292
  690. package/dist/chunk-BE2XENG2.js.map +0 -1
  691. package/dist/chunk-BF4SADKX.js +0 -29
  692. package/dist/chunk-BKP43KK4.js +0 -1788
  693. package/dist/chunk-BM3NEZ6X.js +0 -781
  694. package/dist/chunk-BT3BAGB5.js +0 -216
  695. package/dist/chunk-BTSYDIVJ.js +0 -357
  696. package/dist/chunk-BUBNGKWG.js +0 -70
  697. package/dist/chunk-BVUJV5WR.js +0 -126
  698. package/dist/chunk-BZO5ZMUP.js +0 -27
  699. package/dist/chunk-C3HUF3M2.js +0 -157
  700. package/dist/chunk-C5QCAOES.js +0 -264
  701. package/dist/chunk-CGK6ALQU.js +0 -159
  702. package/dist/chunk-CPYGO76Q.js +0 -335
  703. package/dist/chunk-CQH4FWYA.js +0 -490
  704. package/dist/chunk-CZP5QXNB.js +0 -234
  705. package/dist/chunk-D2TOWEYH.js +0 -266
  706. package/dist/chunk-D6L4GHRH.js +0 -340
  707. package/dist/chunk-DKT3N37I.js +0 -50
  708. package/dist/chunk-DMMJIFKA.js +0 -84
  709. package/dist/chunk-DO74DQC7.js +0 -26
  710. package/dist/chunk-DOFJZ2JU.js +0 -83
  711. package/dist/chunk-DSXVY5WZ.js +0 -119
  712. package/dist/chunk-E337C2VK.js +0 -82
  713. package/dist/chunk-E6NRSRBE.js +0 -114
  714. package/dist/chunk-E6SQKHAU.js +0 -114
  715. package/dist/chunk-E7UIVD7F.js +0 -236
  716. package/dist/chunk-EGBII4CP.js +0 -229
  717. package/dist/chunk-EILSAQVJ.js +0 -200
  718. package/dist/chunk-ELL6HSYR.js +0 -307
  719. package/dist/chunk-EUBGLFFR.js +0 -73
  720. package/dist/chunk-EW6RNWSH.js +0 -212
  721. package/dist/chunk-EYUT5Y6V.js +0 -2599
  722. package/dist/chunk-F7U3QPZ3.js +0 -304
  723. package/dist/chunk-FBTJKSTM.js +0 -1270
  724. package/dist/chunk-FC2FTSK3.js +0 -2424
  725. package/dist/chunk-FOGNA3BU.js +0 -148
  726. package/dist/chunk-FQFKHNC7.js +0 -650
  727. package/dist/chunk-FTCHM755.js +0 -50
  728. package/dist/chunk-FXSHP4JZ.js +0 -3550
  729. package/dist/chunk-G6ZZC543.js +0 -818
  730. package/dist/chunk-G7FU6PUA.js +0 -100
  731. package/dist/chunk-GA4YEAMX.js +0 -3851
  732. package/dist/chunk-GE33BGB7.js +0 -12
  733. package/dist/chunk-GQ67HSJY.js +0 -570
  734. package/dist/chunk-GXXZ3WAK.js +0 -106
  735. package/dist/chunk-H2TCRX3H.js +0 -237
  736. package/dist/chunk-HLL4PBO7.js +0 -60
  737. package/dist/chunk-HLOEPV5C.js +0 -259
  738. package/dist/chunk-HUAGBS4O.js +0 -56
  739. package/dist/chunk-I36GSRUJ.js +0 -211
  740. package/dist/chunk-I6VBHT7S.js +0 -261
  741. package/dist/chunk-ICNNNOXE.js +0 -333
  742. package/dist/chunk-ICX64J4U.js +0 -172
  743. package/dist/chunk-ID36Y46W.js +0 -5046
  744. package/dist/chunk-ID36Y46W.js.map +0 -1
  745. package/dist/chunk-IGVVXLKJ.js +0 -559
  746. package/dist/chunk-IKJLSBUI.js +0 -2984
  747. package/dist/chunk-IKMUFDVS.js +0 -50
  748. package/dist/chunk-IKUNOX7F.js +0 -255
  749. package/dist/chunk-ILKDYBON.js +0 -288
  750. package/dist/chunk-IVYJX3OY.js +0 -187
  751. package/dist/chunk-JCY4CMDH.js +0 -107
  752. package/dist/chunk-JJZPLGIP.js +0 -474
  753. package/dist/chunk-JW33RV4V.js +0 -143
  754. package/dist/chunk-JWPA6ZPZ.js +0 -351
  755. package/dist/chunk-JZ4QXS6D.js +0 -50
  756. package/dist/chunk-K42OUZQ3.js +0 -386
  757. package/dist/chunk-K5TOVX5A.js +0 -206
  758. package/dist/chunk-K63HGHZX.js +0 -99
  759. package/dist/chunk-K6R5T44I.js +0 -75
  760. package/dist/chunk-KHJ5PXFM.js +0 -914
  761. package/dist/chunk-KJZRQ55O.js +0 -2319
  762. package/dist/chunk-KJZRQ55O.js.map +0 -1
  763. package/dist/chunk-KKI55ZMW.js +0 -65
  764. package/dist/chunk-KRPLAAFP.js +0 -199
  765. package/dist/chunk-KVFEZDBO.js +0 -134
  766. package/dist/chunk-L4I665WK.js +0 -45
  767. package/dist/chunk-L4OF77LE.js +0 -110
  768. package/dist/chunk-L4OF77LE.js.map +0 -1
  769. package/dist/chunk-LA5T52RM.js +0 -70
  770. package/dist/chunk-LM2W5YAT.js +0 -401
  771. package/dist/chunk-LQ62ECE6.js +0 -390
  772. package/dist/chunk-LQDUHU3Y.js +0 -71
  773. package/dist/chunk-LRJIYTZW.js +0 -4157
  774. package/dist/chunk-LRJIYTZW.js.map +0 -1
  775. package/dist/chunk-LRN6GYAZ.js +0 -138
  776. package/dist/chunk-M4SDVTKJ.js +0 -790
  777. package/dist/chunk-MA6O7CM6.js +0 -99
  778. package/dist/chunk-MBIBB6GI.js +0 -197
  779. package/dist/chunk-MF3ZFB4H.js +0 -199
  780. package/dist/chunk-MJJGJMYJ.js +0 -98
  781. package/dist/chunk-MLJADQFI.js +0 -4824
  782. package/dist/chunk-MQG7RV3B.js +0 -62
  783. package/dist/chunk-MTTGSQA5.js +0 -186
  784. package/dist/chunk-MW7Y3T55.js +0 -525
  785. package/dist/chunk-MYUFMVCH.js +0 -121
  786. package/dist/chunk-N3OARGH2.js +0 -61
  787. package/dist/chunk-NB2HMRT2.js +0 -353
  788. package/dist/chunk-NFDFYWMV.js +0 -141
  789. package/dist/chunk-NWGNFN3N.js +0 -1187
  790. package/dist/chunk-NWJRPDIO.js +0 -840
  791. package/dist/chunk-NWJRPDIO.js.map +0 -1
  792. package/dist/chunk-NXWBBZJV.js +0 -267
  793. package/dist/chunk-NY2QWROL.js +0 -71
  794. package/dist/chunk-O2IOPP3R.js +0 -848
  795. package/dist/chunk-O2UWH5RG.js +0 -141
  796. package/dist/chunk-O5YWDLYF.js +0 -393
  797. package/dist/chunk-OBMCZO7E.js +0 -121
  798. package/dist/chunk-OD3DCCCB.js +0 -132
  799. package/dist/chunk-OMH7R6I3.js +0 -390
  800. package/dist/chunk-OSA5EQG5.js +0 -113
  801. package/dist/chunk-OSJ3MUTZ.js +0 -2936
  802. package/dist/chunk-OWAYJ2OV.js +0 -368
  803. package/dist/chunk-OYXBFSGK.js +0 -269
  804. package/dist/chunk-PC2EBA5G.js +0 -4116
  805. package/dist/chunk-PC2EBA5G.js.map +0 -1
  806. package/dist/chunk-PC2MVXIP.js +0 -363
  807. package/dist/chunk-PC2MVXIP.js.map +0 -1
  808. package/dist/chunk-PENGLDR5.js +0 -309
  809. package/dist/chunk-PSMAWRPL.js +0 -191
  810. package/dist/chunk-PW4IMTYR.js +0 -702
  811. package/dist/chunk-PW54V7T5.js +0 -387
  812. package/dist/chunk-Q2EXYSMO.js +0 -24
  813. package/dist/chunk-Q2XJK5I4.js +0 -51
  814. package/dist/chunk-Q2XJK5I4.js.map +0 -1
  815. package/dist/chunk-Q4EFRI6X.js +0 -258
  816. package/dist/chunk-Q52CXW6C.js +0 -48
  817. package/dist/chunk-Q6XQ2R37.js +0 -184
  818. package/dist/chunk-QAJ53XBW.js +0 -23
  819. package/dist/chunk-QDTKECT4.js +0 -129
  820. package/dist/chunk-QE3ZFGI3.js +0 -43
  821. package/dist/chunk-QHHSUR2Y.js +0 -298
  822. package/dist/chunk-QHNVNR7B.js +0 -173
  823. package/dist/chunk-QIK2Q6N5.js +0 -376
  824. package/dist/chunk-QWL4L366.js +0 -38
  825. package/dist/chunk-R3J2PTVQ.js +0 -690
  826. package/dist/chunk-RBRX5ZS3.js +0 -319
  827. package/dist/chunk-REX6JIC7.js +0 -33
  828. package/dist/chunk-RGZ7EEC3.js +0 -537
  829. package/dist/chunk-RGZ7EEC3.js.map +0 -1
  830. package/dist/chunk-RIPS7GFR.js +0 -960
  831. package/dist/chunk-RTBZNFNV.js +0 -1354
  832. package/dist/chunk-RTBZNFNV.js.map +0 -1
  833. package/dist/chunk-SKMNW4SW.js +0 -187
  834. package/dist/chunk-SRFARKXC.js +0 -623
  835. package/dist/chunk-SWIHWCTW.js +0 -4461
  836. package/dist/chunk-TA5CFTO4.js +0 -103
  837. package/dist/chunk-TF4ZVJLI.js +0 -156
  838. package/dist/chunk-TG7DADJR.js +0 -9624
  839. package/dist/chunk-TI4R2ZD5.js +0 -623
  840. package/dist/chunk-TI4R2ZD5.js.map +0 -1
  841. package/dist/chunk-TNKWOUWP.js +0 -412
  842. package/dist/chunk-TNUSPXPW.js +0 -5555
  843. package/dist/chunk-TNUSPXPW.js.map +0 -1
  844. package/dist/chunk-TNYFHKVV.js +0 -366
  845. package/dist/chunk-TPMZBOFH.js +0 -178
  846. package/dist/chunk-TW3LKRJF.js +0 -263
  847. package/dist/chunk-TZAO65I4.js +0 -83
  848. package/dist/chunk-U5EFEMYU.js +0 -89
  849. package/dist/chunk-U6M4LS3M.js +0 -378
  850. package/dist/chunk-UI4HI5QK.js +0 -918
  851. package/dist/chunk-UJDOWCQ3.js +0 -272
  852. package/dist/chunk-UJUQ2QOX.js +0 -581
  853. package/dist/chunk-UQ3IM6FY.js +0 -133
  854. package/dist/chunk-UYE47LO6.js +0 -246
  855. package/dist/chunk-VADHIT26.js +0 -89
  856. package/dist/chunk-VFQ3H6CO.js +0 -163
  857. package/dist/chunk-VGUN6VB2.js +0 -188
  858. package/dist/chunk-VGWWEVSD.js +0 -723
  859. package/dist/chunk-VIEFJ2DM.js +0 -2469
  860. package/dist/chunk-VLXM36VS.js +0 -268
  861. package/dist/chunk-W3BFRR2G.js +0 -499
  862. package/dist/chunk-W5MPXR3A.js +0 -981
  863. package/dist/chunk-W5OWKVZG.js +0 -136
  864. package/dist/chunk-W6FRORMX.js +0 -486
  865. package/dist/chunk-W6FRORMX.js.map +0 -1
  866. package/dist/chunk-W7XROSZO.js +0 -232
  867. package/dist/chunk-W7XROSZO.js.map +0 -1
  868. package/dist/chunk-WEZ5PXZP.js +0 -403
  869. package/dist/chunk-WHWUWN2X.js +0 -197
  870. package/dist/chunk-WHWUWN2X.js.map +0 -1
  871. package/dist/chunk-WLEDGIVS.js +0 -114
  872. package/dist/chunk-WLEDGIVS.js.map +0 -1
  873. package/dist/chunk-WNDAKLHG.js +0 -281
  874. package/dist/chunk-WTJ4PLMU.js +0 -103
  875. package/dist/chunk-WV2KPJUW.js +0 -107
  876. package/dist/chunk-X3VY5EGY.js +0 -277
  877. package/dist/chunk-X3VY5EGY.js.map +0 -1
  878. package/dist/chunk-XDBYWVCW.js +0 -418
  879. package/dist/chunk-XF7MA4U5.js +0 -36
  880. package/dist/chunk-XF7MA4U5.js.map +0 -1
  881. package/dist/chunk-XOSQP3YA.js +0 -605
  882. package/dist/chunk-XYBV4ZJQ.js +0 -271
  883. package/dist/chunk-YBKVGLQR.js +0 -147
  884. package/dist/chunk-YDCUBUWH.js +0 -1583
  885. package/dist/chunk-YG6NARQY.js +0 -51
  886. package/dist/chunk-YG6NARQY.js.map +0 -1
  887. package/dist/chunk-YSVD5HI4.js +0 -278
  888. package/dist/chunk-YT3WGNG6.js +0 -290
  889. package/dist/chunk-YYICQDK4.js +0 -414
  890. package/dist/chunk-YYLMZLI6.js +0 -686
  891. package/dist/chunk-ZAMTKG5U.js +0 -95
  892. package/dist/chunk-ZDLYSXKN.js +0 -111
  893. package/dist/chunk-ZG447FSS.js +0 -194
  894. package/dist/chunk-ZIT5KD4Q.js +0 -264
  895. package/dist/chunk-ZUDOVDKR.js +0 -3064
  896. package/dist/chunk-ZW2ECJ3A.js +0 -451
  897. package/dist/computer-viewer-LPZ763KF.js +0 -21
  898. package/dist/embedded-new-voice-YVMKSLKJ.js +0 -24
  899. package/dist/embedded-voice-BJPQFXSU.js +0 -24
  900. package/dist/fleet-decision-row-AA4H5CDT.js +0 -361
  901. package/dist/model-policy-picker-menu-HSMWVO4P.js +0 -22
  902. package/dist/payment-page-card-3LTSFJGN.js +0 -223
  903. package/dist/platform-activity-row-5VYV6TX4.js +0 -128
  904. package/dist/queue-surface-implementation-NXHZUKD2.js +0 -908
  905. package/dist/recorder-host-ZKRWTDBM.js +0 -57
  906. package/dist/recorder-host-ZKRWTDBM.js.map +0 -1
  907. package/dist/sandbox-files-YCMLQUFU.js +0 -27
  908. package/dist/session-connect-cards-KSQLMRM5.js +0 -25
  909. package/dist/session-realtime-ZR6JLG3Y.js +0 -30
  910. package/dist/timeline-annotation-markers-YAHDPWVG.js +0 -157
  911. package/dist/timeline-annotation-selection-KHXNCEJP.js +0 -208
  912. package/dist/timeline-annotations-dialog-Y4XD3N7B.js +0 -283
  913. /package/dist/{browser-viewer-NOP5EAUO.js.map → browser-viewer-TC27OCIP.js.map} +0 -0
  914. /package/dist/{chat-interactive-block-G7O44JHR.js.map → chat-interactive-block-RWPQBHVS.js.map} +0 -0
  915. /package/dist/{chunk-EGBII4CP.js.map → chunk-2BDT3UZQ.js.map} +0 -0
  916. /package/dist/{chunk-4YD7YZC5.js.map → chunk-2CLNIEK4.js.map} +0 -0
  917. /package/dist/{chunk-ZW2ECJ3A.js.map → chunk-2FSBSCZJ.js.map} +0 -0
  918. /package/dist/{chunk-KRPLAAFP.js.map → chunk-2I7HDP53.js.map} +0 -0
  919. /package/dist/{chunk-3QX55WLC.js.map → chunk-2INLDVK3.js.map} +0 -0
  920. /package/dist/{chunk-BVUJV5WR.js.map → chunk-2KALVELR.js.map} +0 -0
  921. /package/dist/{chunk-XDBYWVCW.js.map → chunk-2M3J7ZWQ.js.map} +0 -0
  922. /package/dist/{chunk-2RREGDQH.js.map → chunk-2OP6WLGV.js.map} +0 -0
  923. /package/dist/{chunk-OSJ3MUTZ.js.map → chunk-2RG7NIAS.js.map} +0 -0
  924. /package/dist/{chunk-26RWVLRD.js.map → chunk-2STUPWEL.js.map} +0 -0
  925. /package/dist/{chunk-XYBV4ZJQ.js.map → chunk-2YUOVM3G.js.map} +0 -0
  926. /package/dist/{chunk-2GDNWKSC.js.map → chunk-2Z3NQNTM.js.map} +0 -0
  927. /package/dist/{chunk-2VB2O4FQ.js.map → chunk-3CPWWGNK.js.map} +0 -0
  928. /package/dist/{chunk-7WKP3DYJ.js.map → chunk-3ED2U6XE.js.map} +0 -0
  929. /package/dist/{chunk-BT3BAGB5.js.map → chunk-3GZA4BUW.js.map} +0 -0
  930. /package/dist/{chunk-3USJPT2S.js.map → chunk-3IK6UYO6.js.map} +0 -0
  931. /package/dist/{chunk-6AHATAAY.js.map → chunk-3PZ7JZI2.js.map} +0 -0
  932. /package/dist/{chunk-JZ4QXS6D.js.map → chunk-4DVJ6ONS.js.map} +0 -0
  933. /package/dist/{chunk-5QM2WPKV.js.map → chunk-4E3ZJRTZ.js.map} +0 -0
  934. /package/dist/{chunk-NFDFYWMV.js.map → chunk-4SAWSRAA.js.map} +0 -0
  935. /package/dist/{chunk-ELL6HSYR.js.map → chunk-53AGXXZM.js.map} +0 -0
  936. /package/dist/{chunk-G6ZZC543.js.map → chunk-54YW6SZZ.js.map} +0 -0
  937. /package/dist/{chunk-4SZZAFYQ.js.map → chunk-57AZS3IE.js.map} +0 -0
  938. /package/dist/{chunk-JW33RV4V.js.map → chunk-5CPEEAFD.js.map} +0 -0
  939. /package/dist/{chunk-D6L4GHRH.js.map → chunk-5EWSRZ2Y.js.map} +0 -0
  940. /package/dist/{chunk-PW54V7T5.js.map → chunk-5IE76VCY.js.map} +0 -0
  941. /package/dist/{chunk-6GXVYAGR.js.map → chunk-5NWEKLDZ.js.map} +0 -0
  942. /package/dist/{chunk-6UHCBH4G.js.map → chunk-5O2FCCHZ.js.map} +0 -0
  943. /package/dist/{chunk-2YC6JQRO.js.map → chunk-5QAY6K77.js.map} +0 -0
  944. /package/dist/{chunk-EYUT5Y6V.js.map → chunk-6DK6Z4UN.js.map} +0 -0
  945. /package/dist/{chunk-PW4IMTYR.js.map → chunk-6DVCC7QS.js.map} +0 -0
  946. /package/dist/{chunk-7WIDB4PL.js.map → chunk-6JHU2UBS.js.map} +0 -0
  947. /package/dist/{chunk-CQH4FWYA.js.map → chunk-6PZ7OBYU.js.map} +0 -0
  948. /package/dist/{chunk-VFQ3H6CO.js.map → chunk-6WGRDRMA.js.map} +0 -0
  949. /package/dist/{chunk-MTTGSQA5.js.map → chunk-77WAKEAH.js.map} +0 -0
  950. /package/dist/{chunk-O5YWDLYF.js.map → chunk-7TDO3CUM.js.map} +0 -0
  951. /package/dist/{chunk-2AHTY7OT.js.map → chunk-7TIX2UAR.js.map} +0 -0
  952. /package/dist/{chunk-FOGNA3BU.js.map → chunk-7V5REBCP.js.map} +0 -0
  953. /package/dist/{chunk-2JENKGCE.js.map → chunk-7VMZGLYI.js.map} +0 -0
  954. /package/dist/{chunk-E7UIVD7F.js.map → chunk-7W37NS3I.js.map} +0 -0
  955. /package/dist/{chunk-ZDLYSXKN.js.map → chunk-7X6SDK2C.js.map} +0 -0
  956. /package/dist/{chunk-ZAMTKG5U.js.map → chunk-7ZNUHRP5.js.map} +0 -0
  957. /package/dist/{chunk-DMMJIFKA.js.map → chunk-A36PZALD.js.map} +0 -0
  958. /package/dist/{chunk-WV2KPJUW.js.map → chunk-AUI6VA63.js.map} +0 -0
  959. /package/dist/{chunk-Q2EXYSMO.js.map → chunk-AW2MQB37.js.map} +0 -0
  960. /package/dist/{chunk-6WLX3NR3.js.map → chunk-AWKES45Y.js.map} +0 -0
  961. /package/dist/{chunk-OD3DCCCB.js.map → chunk-AXHZYXUV.js.map} +0 -0
  962. /package/dist/{chunk-QDTKECT4.js.map → chunk-BHNSJVBC.js.map} +0 -0
  963. /package/dist/{chunk-FTCHM755.js.map → chunk-BJEJFISW.js.map} +0 -0
  964. /package/dist/{chunk-B2I5ZW35.js.map → chunk-BJFH6JI5.js.map} +0 -0
  965. /package/dist/{chunk-RIPS7GFR.js.map → chunk-BMICEQZQ.js.map} +0 -0
  966. /package/dist/{chunk-BF4SADKX.js.map → chunk-BTLBYBLU.js.map} +0 -0
  967. /package/dist/{chunk-U5EFEMYU.js.map → chunk-BXBDYNRP.js.map} +0 -0
  968. /package/dist/{chunk-BTSYDIVJ.js.map → chunk-C372BFOV.js.map} +0 -0
  969. /package/dist/{chunk-MLJADQFI.js.map → chunk-CMKGILJK.js.map} +0 -0
  970. /package/dist/{chunk-DKT3N37I.js.map → chunk-CRAOSVHC.js.map} +0 -0
  971. /package/dist/{chunk-WNDAKLHG.js.map → chunk-CRU35QQH.js.map} +0 -0
  972. /package/dist/{chunk-2XNG2KNT.js.map → chunk-CUIWCGMA.js.map} +0 -0
  973. /package/dist/{chunk-QWL4L366.js.map → chunk-D5TWNFFE.js.map} +0 -0
  974. /package/dist/{chunk-SWIHWCTW.js.map → chunk-DF5EAHDN.js.map} +0 -0
  975. /package/dist/{chunk-HUAGBS4O.js.map → chunk-DJAXC5OK.js.map} +0 -0
  976. /package/dist/{chunk-FXSHP4JZ.js.map → chunk-DXBYWSL5.js.map} +0 -0
  977. /package/dist/{chunk-5MUJDC6C.js.map → chunk-DXR5PDFP.js.map} +0 -0
  978. /package/dist/{chunk-NXWBBZJV.js.map → chunk-DZWARC4M.js.map} +0 -0
  979. /package/dist/{chunk-GXXZ3WAK.js.map → chunk-DZXEDSQI.js.map} +0 -0
  980. /package/dist/{chunk-Q52CXW6C.js.map → chunk-E7XERZWC.js.map} +0 -0
  981. /package/dist/{chunk-4NBTZRKT.js.map → chunk-ECJBYNLJ.js.map} +0 -0
  982. /package/dist/{chunk-QE3ZFGI3.js.map → chunk-EDI6SJ2N.js.map} +0 -0
  983. /package/dist/{chunk-E6NRSRBE.js.map → chunk-EWSOC6WF.js.map} +0 -0
  984. /package/dist/{chunk-TA5CFTO4.js.map → chunk-F2OPHAUN.js.map} +0 -0
  985. /package/dist/{chunk-5DTST3TP.js.map → chunk-F4ISQGGM.js.map} +0 -0
  986. /package/dist/{chunk-MBIBB6GI.js.map → chunk-FO4LYKJL.js.map} +0 -0
  987. /package/dist/{chunk-EUBGLFFR.js.map → chunk-FPXASDG5.js.map} +0 -0
  988. /package/dist/{chunk-C3HUF3M2.js.map → chunk-FVXBNBHO.js.map} +0 -0
  989. /package/dist/{chunk-W5MPXR3A.js.map → chunk-FZC5N55X.js.map} +0 -0
  990. /package/dist/{chunk-MA6O7CM6.js.map → chunk-GAVYGBFI.js.map} +0 -0
  991. /package/dist/{chunk-REX6JIC7.js.map → chunk-GKVJIDHF.js.map} +0 -0
  992. /package/dist/{chunk-EW6RNWSH.js.map → chunk-GVN5SZLX.js.map} +0 -0
  993. /package/dist/{chunk-KVFEZDBO.js.map → chunk-H3T7IWNA.js.map} +0 -0
  994. /package/dist/{chunk-I6VBHT7S.js.map → chunk-HAX4LCR5.js.map} +0 -0
  995. /package/dist/{chunk-OBMCZO7E.js.map → chunk-HC4JFZVU.js.map} +0 -0
  996. /package/dist/{chunk-UJUQ2QOX.js.map → chunk-HEFPPMBQ.js.map} +0 -0
  997. /package/dist/{chunk-DOFJZ2JU.js.map → chunk-HNLR7Q4Z.js.map} +0 -0
  998. /package/dist/{chunk-GE33BGB7.js.map → chunk-HSOXMJOT.js.map} +0 -0
  999. /package/dist/{chunk-AB5MBIXY.js.map → chunk-I4MRDSUF.js.map} +0 -0
  1000. /package/dist/{chunk-AFBJTUFK.js.map → chunk-I4QEJ62Y.js.map} +0 -0
  1001. /package/dist/{chunk-6ED2YWBT.js.map → chunk-I5B5L6Q4.js.map} +0 -0
  1002. /package/dist/{chunk-C5QCAOES.js.map → chunk-I5QZJODL.js.map} +0 -0
  1003. /package/dist/{chunk-76ERNKIZ.js.map → chunk-I7ITSXSJ.js.map} +0 -0
  1004. /package/dist/{chunk-OMH7R6I3.js.map → chunk-I7XIZRFD.js.map} +0 -0
  1005. /package/dist/{chunk-E337C2VK.js.map → chunk-IDANQPRH.js.map} +0 -0
  1006. /package/dist/{chunk-3FD76LXM.js.map → chunk-IFB3WJ36.js.map} +0 -0
  1007. /package/dist/{chunk-ZIT5KD4Q.js.map → chunk-IHTAKKTK.js.map} +0 -0
  1008. /package/dist/{chunk-QHNVNR7B.js.map → chunk-ILDXWY37.js.map} +0 -0
  1009. /package/dist/{chunk-GQ67HSJY.js.map → chunk-IMDQUHBJ.js.map} +0 -0
  1010. /package/dist/{chunk-DSXVY5WZ.js.map → chunk-IMZCQBOT.js.map} +0 -0
  1011. /package/dist/{chunk-WEZ5PXZP.js.map → chunk-IXPTECSC.js.map} +0 -0
  1012. /package/dist/{chunk-NY2QWROL.js.map → chunk-J255A3N5.js.map} +0 -0
  1013. /package/dist/{chunk-O2UWH5RG.js.map → chunk-J5F5HPPW.js.map} +0 -0
  1014. /package/dist/{chunk-VIEFJ2DM.js.map → chunk-JEA3QDX7.js.map} +0 -0
  1015. /package/dist/{chunk-TF4ZVJLI.js.map → chunk-JEUPAVYY.js.map} +0 -0
  1016. /package/dist/{chunk-ZG447FSS.js.map → chunk-JKHKLL5W.js.map} +0 -0
  1017. /package/dist/{chunk-FQFKHNC7.js.map → chunk-JQL7ZH6C.js.map} +0 -0
  1018. /package/dist/{chunk-776QZ573.js.map → chunk-JWB44UGJ.js.map} +0 -0
  1019. /package/dist/{chunk-ICNNNOXE.js.map → chunk-JZ4NLCAP.js.map} +0 -0
  1020. /package/dist/{chunk-TNKWOUWP.js.map → chunk-K2A5PXQ5.js.map} +0 -0
  1021. /package/dist/{chunk-SRFARKXC.js.map → chunk-K56XV3C3.js.map} +0 -0
  1022. /package/dist/{chunk-QAJ53XBW.js.map → chunk-K6GAXXVA.js.map} +0 -0
  1023. /package/dist/{chunk-MF3ZFB4H.js.map → chunk-KCBMFSMS.js.map} +0 -0
  1024. /package/dist/{chunk-VLXM36VS.js.map → chunk-KF2FV3ZJ.js.map} +0 -0
  1025. /package/dist/{chunk-YSVD5HI4.js.map → chunk-KJD65EJP.js.map} +0 -0
  1026. /package/dist/{chunk-K42OUZQ3.js.map → chunk-KLEUWIMZ.js.map} +0 -0
  1027. /package/dist/{chunk-PENGLDR5.js.map → chunk-KODELWYT.js.map} +0 -0
  1028. /package/dist/{chunk-TZAO65I4.js.map → chunk-KRDR5RJD.js.map} +0 -0
  1029. /package/dist/{chunk-KHJ5PXFM.js.map → chunk-KUDGXAF7.js.map} +0 -0
  1030. /package/dist/{chunk-6H4SJBPE.js.map → chunk-KYS77RPN.js.map} +0 -0
  1031. /package/dist/{chunk-OWAYJ2OV.js.map → chunk-L7YTNTIK.js.map} +0 -0
  1032. /package/dist/{chunk-YYLMZLI6.js.map → chunk-LHPNABDH.js.map} +0 -0
  1033. /package/dist/{chunk-LM2W5YAT.js.map → chunk-MFROMEKA.js.map} +0 -0
  1034. /package/dist/{chunk-AXBSYWKX.js.map → chunk-MIHN76LX.js.map} +0 -0
  1035. /package/dist/{chunk-4LPOWQJY.js.map → chunk-MIYFS2XN.js.map} +0 -0
  1036. /package/dist/{chunk-KKI55ZMW.js.map → chunk-MJUCFQMS.js.map} +0 -0
  1037. /package/dist/{chunk-ZUDOVDKR.js.map → chunk-MM4FNWI4.js.map} +0 -0
  1038. /package/dist/{chunk-M4SDVTKJ.js.map → chunk-MNZG4OHU.js.map} +0 -0
  1039. /package/dist/{chunk-EILSAQVJ.js.map → chunk-N6AACDUW.js.map} +0 -0
  1040. /package/dist/{chunk-BM3NEZ6X.js.map → chunk-NC55IFN3.js.map} +0 -0
  1041. /package/dist/{chunk-MJJGJMYJ.js.map → chunk-NC7PVOEK.js.map} +0 -0
  1042. /package/dist/{chunk-LA5T52RM.js.map → chunk-NCYMNCJO.js.map} +0 -0
  1043. /package/dist/{chunk-HLOEPV5C.js.map → chunk-ND2BXV3P.js.map} +0 -0
  1044. /package/dist/{chunk-UJDOWCQ3.js.map → chunk-NDBTFUO6.js.map} +0 -0
  1045. /package/dist/{chunk-K5TOVX5A.js.map → chunk-NDQJZ7HF.js.map} +0 -0
  1046. /package/dist/{chunk-35737UT4.js.map → chunk-NGJJJPZZ.js.map} +0 -0
  1047. /package/dist/{chunk-42CMQ5VR.js.map → chunk-NJTSNNE7.js.map} +0 -0
  1048. /package/dist/{chunk-FBTJKSTM.js.map → chunk-NRTE7DNV.js.map} +0 -0
  1049. /package/dist/{chunk-YT3WGNG6.js.map → chunk-NULUNM7H.js.map} +0 -0
  1050. /package/dist/{chunk-7XOVTPDI.js.map → chunk-NUNZS36W.js.map} +0 -0
  1051. /package/dist/{chunk-FC2FTSK3.js.map → chunk-NW53H5RW.js.map} +0 -0
  1052. /package/dist/{chunk-TW3LKRJF.js.map → chunk-NXCMHIKI.js.map} +0 -0
  1053. /package/dist/{chunk-CGK6ALQU.js.map → chunk-O3LKCBP5.js.map} +0 -0
  1054. /package/dist/{chunk-QIK2Q6N5.js.map → chunk-O6N4ABCA.js.map} +0 -0
  1055. /package/dist/{chunk-73NXYYWE.js.map → chunk-O732GAFC.js.map} +0 -0
  1056. /package/dist/{chunk-R3J2PTVQ.js.map → chunk-OF4TIKYC.js.map} +0 -0
  1057. /package/dist/{chunk-BUBNGKWG.js.map → chunk-OMPVOMPP.js.map} +0 -0
  1058. /package/dist/{chunk-4OXI6HCV.js.map → chunk-OPJJSKUK.js.map} +0 -0
  1059. /package/dist/{chunk-4Y6BK7IU.js.map → chunk-OPWCMA4D.js.map} +0 -0
  1060. /package/dist/{chunk-ADNMXBCX.js.map → chunk-ORJPS5VN.js.map} +0 -0
  1061. /package/dist/{chunk-SKMNW4SW.js.map → chunk-OSY5K7L7.js.map} +0 -0
  1062. /package/dist/{chunk-L4I665WK.js.map → chunk-OV6QJRT4.js.map} +0 -0
  1063. /package/dist/{chunk-7O5CGGIQ.js.map → chunk-OVKYVZMW.js.map} +0 -0
  1064. /package/dist/{chunk-7BYWOFVH.js.map → chunk-OZCBM3UC.js.map} +0 -0
  1065. /package/dist/{chunk-ALVRWCXE.js.map → chunk-P3A2EINJ.js.map} +0 -0
  1066. /package/dist/{chunk-BZO5ZMUP.js.map → chunk-PTAG4PDC.js.map} +0 -0
  1067. /package/dist/{chunk-QHHSUR2Y.js.map → chunk-PTF5B7TJ.js.map} +0 -0
  1068. /package/dist/{chunk-O2IOPP3R.js.map → chunk-Q3DPEYX4.js.map} +0 -0
  1069. /package/dist/{chunk-G7FU6PUA.js.map → chunk-QB2KMIDP.js.map} +0 -0
  1070. /package/dist/{chunk-64PO2WXU.js.map → chunk-QCSJ4CWE.js.map} +0 -0
  1071. /package/dist/{chunk-YYICQDK4.js.map → chunk-QIOQ2NPQ.js.map} +0 -0
  1072. /package/dist/{chunk-NB2HMRT2.js.map → chunk-QK5EFEUT.js.map} +0 -0
  1073. /package/dist/{chunk-366XZ4PM.js.map → chunk-QPQBLYQJ.js.map} +0 -0
  1074. /package/dist/{chunk-Q6XQ2R37.js.map → chunk-QPSGCC5D.js.map} +0 -0
  1075. /package/dist/{chunk-JJZPLGIP.js.map → chunk-QZAAUQRN.js.map} +0 -0
  1076. /package/dist/{chunk-VGUN6VB2.js.map → chunk-RGBI63KJ.js.map} +0 -0
  1077. /package/dist/{chunk-LRN6GYAZ.js.map → chunk-RLBKLAEY.js.map} +0 -0
  1078. /package/dist/{chunk-F7U3QPZ3.js.map → chunk-RMFKVOM7.js.map} +0 -0
  1079. /package/dist/{chunk-Q4EFRI6X.js.map → chunk-ROKQU7WG.js.map} +0 -0
  1080. /package/dist/{chunk-7QOHRZ67.js.map → chunk-RPVREAU7.js.map} +0 -0
  1081. /package/dist/{chunk-VGWWEVSD.js.map → chunk-RQKLF42C.js.map} +0 -0
  1082. /package/dist/{chunk-2VTTKH23.js.map → chunk-SEO7TICN.js.map} +0 -0
  1083. /package/dist/{chunk-3QNRBEYH.js.map → chunk-SHHJCL7X.js.map} +0 -0
  1084. /package/dist/{chunk-E6SQKHAU.js.map → chunk-SIRLACNZ.js.map} +0 -0
  1085. /package/dist/{chunk-H2TCRX3H.js.map → chunk-SKPHMYAA.js.map} +0 -0
  1086. /package/dist/{chunk-YDCUBUWH.js.map → chunk-SODC7T6L.js.map} +0 -0
  1087. /package/dist/{chunk-TNYFHKVV.js.map → chunk-SQJIKMN3.js.map} +0 -0
  1088. /package/dist/{chunk-DO74DQC7.js.map → chunk-SVINDKVW.js.map} +0 -0
  1089. /package/dist/{chunk-CPYGO76Q.js.map → chunk-SYCDHPZF.js.map} +0 -0
  1090. /package/dist/{chunk-UQ3IM6FY.js.map → chunk-T2QX3FDP.js.map} +0 -0
  1091. /package/dist/{chunk-NWGNFN3N.js.map → chunk-T3OWFVMS.js.map} +0 -0
  1092. /package/dist/{chunk-N3OARGH2.js.map → chunk-T6XI5FLY.js.map} +0 -0
  1093. /package/dist/{chunk-MQG7RV3B.js.map → chunk-T7OXJZCX.js.map} +0 -0
  1094. /package/dist/{chunk-2T7DX6KR.js.map → chunk-TAT5USZN.js.map} +0 -0
  1095. /package/dist/{chunk-ICX64J4U.js.map → chunk-TPQTRNER.js.map} +0 -0
  1096. /package/dist/{chunk-D2TOWEYH.js.map → chunk-TUIN4MB7.js.map} +0 -0
  1097. /package/dist/{chunk-LQDUHU3Y.js.map → chunk-TX3VECZU.js.map} +0 -0
  1098. /package/dist/{chunk-TG7DADJR.js.map → chunk-TXLIEOJX.js.map} +0 -0
  1099. /package/dist/{chunk-2ZVRJRXC.js.map → chunk-U3DN4HEY.js.map} +0 -0
  1100. /package/dist/{chunk-PSMAWRPL.js.map → chunk-U7XM7CB4.js.map} +0 -0
  1101. /package/dist/{chunk-4TQL3WP2.js.map → chunk-UJK53QFL.js.map} +0 -0
  1102. /package/dist/{chunk-RBRX5ZS3.js.map → chunk-UMTXA2TH.js.map} +0 -0
  1103. /package/dist/{chunk-36MIDGAH.js.map → chunk-UPDSXFK5.js.map} +0 -0
  1104. /package/dist/{chunk-OYXBFSGK.js.map → chunk-UTIAXH52.js.map} +0 -0
  1105. /package/dist/{chunk-5WUN7XPD.js.map → chunk-UVN5TMHU.js.map} +0 -0
  1106. /package/dist/{chunk-UYE47LO6.js.map → chunk-VGYXW3VG.js.map} +0 -0
  1107. /package/dist/{chunk-IKUNOX7F.js.map → chunk-VS7AHPCZ.js.map} +0 -0
  1108. /package/dist/{chunk-MYUFMVCH.js.map → chunk-VTTAJOQ7.js.map} +0 -0
  1109. /package/dist/{chunk-K63HGHZX.js.map → chunk-VWPOLUAO.js.map} +0 -0
  1110. /package/dist/{chunk-GA4YEAMX.js.map → chunk-X3MWB2QU.js.map} +0 -0
  1111. /package/dist/{chunk-I36GSRUJ.js.map → chunk-X6KAJI3V.js.map} +0 -0
  1112. /package/dist/{chunk-IKMUFDVS.js.map → chunk-XBLRHV5R.js.map} +0 -0
  1113. /package/dist/{chunk-XOSQP3YA.js.map → chunk-XDFP2LMW.js.map} +0 -0
  1114. /package/dist/{chunk-MW7Y3T55.js.map → chunk-XEQMZB3C.js.map} +0 -0
  1115. /package/dist/{chunk-B3LMRTRF.js.map → chunk-XEYLT5VA.js.map} +0 -0
  1116. /package/dist/{chunk-UI4HI5QK.js.map → chunk-XHIQ5I6N.js.map} +0 -0
  1117. /package/dist/{chunk-U6M4LS3M.js.map → chunk-XLH7QY2R.js.map} +0 -0
  1118. /package/dist/{chunk-OSA5EQG5.js.map → chunk-XWFAMUZQ.js.map} +0 -0
  1119. /package/dist/{chunk-6MT3HHUB.js.map → chunk-Y4OBB2VN.js.map} +0 -0
  1120. /package/dist/{chunk-CZP5QXNB.js.map → chunk-YCVD6CI3.js.map} +0 -0
  1121. /package/dist/{chunk-APW4T4SW.js.map → chunk-YENLNISG.js.map} +0 -0
  1122. /package/dist/{chunk-JWPA6ZPZ.js.map → chunk-YIRVLKAX.js.map} +0 -0
  1123. /package/dist/{chunk-LQ62ECE6.js.map → chunk-YL73CVNK.js.map} +0 -0
  1124. /package/dist/{chunk-ILKDYBON.js.map → chunk-YLS6QE5G.js.map} +0 -0
  1125. /package/dist/{chunk-YBKVGLQR.js.map → chunk-YPWU5KPE.js.map} +0 -0
  1126. /package/dist/{chunk-IKJLSBUI.js.map → chunk-YQXTDZSU.js.map} +0 -0
  1127. /package/dist/{chunk-TPMZBOFH.js.map → chunk-YSJEAAOL.js.map} +0 -0
  1128. /package/dist/{chunk-W3BFRR2G.js.map → chunk-YWIFM7D7.js.map} +0 -0
  1129. /package/dist/{chunk-WTJ4PLMU.js.map → chunk-YWVI6ZMK.js.map} +0 -0
  1130. /package/dist/{chunk-5KWMYPJV.js.map → chunk-Z4FMAFNH.js.map} +0 -0
  1131. /package/dist/{chunk-W5OWKVZG.js.map → chunk-Z654FWNU.js.map} +0 -0
  1132. /package/dist/{chunk-5FH5LQVS.js.map → chunk-Z7Y523PS.js.map} +0 -0
  1133. /package/dist/{chunk-HLL4PBO7.js.map → chunk-ZD67RM6G.js.map} +0 -0
  1134. /package/dist/{chunk-IVYJX3OY.js.map → chunk-ZEG4VPBL.js.map} +0 -0
  1135. /package/dist/{chunk-K6R5T44I.js.map → chunk-ZLYCOBHW.js.map} +0 -0
  1136. /package/dist/{chunk-VADHIT26.js.map → chunk-ZNJ5MTXV.js.map} +0 -0
  1137. /package/dist/{chunk-2KYQC4T5.js.map → chunk-ZSGY3H53.js.map} +0 -0
  1138. /package/dist/{chunk-BKP43KK4.js.map → chunk-ZTPXACWB.js.map} +0 -0
  1139. /package/dist/{chunk-JCY4CMDH.js.map → chunk-ZUA3JMI6.js.map} +0 -0
  1140. /package/dist/{chunk-IGVVXLKJ.js.map → chunk-ZYAZUPPV.js.map} +0 -0
  1141. /package/dist/{computer-viewer-LPZ763KF.js.map → computer-viewer-TDDO25AV.js.map} +0 -0
  1142. /package/dist/{embedded-new-voice-YVMKSLKJ.js.map → embedded-new-voice-2G3VLPVQ.js.map} +0 -0
  1143. /package/dist/{embedded-voice-BJPQFXSU.js.map → embedded-voice-T5IWOWGD.js.map} +0 -0
  1144. /package/dist/{fleet-decision-row-AA4H5CDT.js.map → fleet-decision-row-WM64KXP3.js.map} +0 -0
  1145. /package/dist/{model-policy-picker-menu-HSMWVO4P.js.map → model-policy-picker-menu-SMC6J6QN.js.map} +0 -0
  1146. /package/dist/{payment-page-card-3LTSFJGN.js.map → payment-page-card-G4U63KUV.js.map} +0 -0
  1147. /package/dist/{platform-activity-row-5VYV6TX4.js.map → platform-activity-row-BUZGZAKZ.js.map} +0 -0
  1148. /package/dist/{queue-surface-implementation-NXHZUKD2.js.map → queue-surface-implementation-4KUZ4PJV.js.map} +0 -0
  1149. /package/dist/{sandbox-files-YCMLQUFU.js.map → sandbox-files-ESDMOFSD.js.map} +0 -0
  1150. /package/dist/{session-connect-cards-KSQLMRM5.js.map → session-connect-cards-Q53KMMYY.js.map} +0 -0
  1151. /package/dist/{session-realtime-ZR6JLG3Y.js.map → session-realtime-CF3I35WJ.js.map} +0 -0
  1152. /package/dist/{timeline-annotation-markers-YAHDPWVG.js.map → timeline-annotation-markers-CJK4RYZ4.js.map} +0 -0
  1153. /package/dist/{timeline-annotation-selection-KHXNCEJP.js.map → timeline-annotation-selection-67GF5H26.js.map} +0 -0
  1154. /package/dist/{timeline-annotations-dialog-Y4XD3N7B.js.map → timeline-annotations-dialog-ONJPQDJQ.js.map} +0 -0
@@ -1,3670 +0,0 @@
1
- "use client";
2
- import {
3
- useSandboxFiles,
4
- useUnicodeFallbackFonts
5
- } from "./chunk-ZUDOVDKR.js";
6
- import {
7
- WorkspaceDock
8
- } from "./chunk-YYLMZLI6.js";
9
- import {
10
- SessionMcpCapabilityCard
11
- } from "./chunk-EILSAQVJ.js";
12
- import {
13
- SessionStatus
14
- } from "./chunk-OD3DCCCB.js";
15
- import {
16
- PierreDiff
17
- } from "./chunk-LRJIYTZW.js";
18
- import {
19
- useThemeType
20
- } from "./chunk-B27E3V37.js";
21
- import {
22
- useTurnlessOutputGap
23
- } from "./chunk-SWIHWCTW.js";
24
- import {
25
- invalidateSharedQueries,
26
- useSharedQuery
27
- } from "./chunk-IWUGGOXA.js";
28
- import {
29
- sessionAdmissionBlocked,
30
- sessionDisplayStatus
31
- } from "./chunk-TSENLSW6.js";
32
- import {
33
- connectionStatusForState
34
- } from "./chunk-EYUT5Y6V.js";
35
- import {
36
- MACHINES_SESSION_POLL_MS,
37
- useMachines
38
- } from "./chunk-XDBYWVCW.js";
39
- import {
40
- useMutationRunner,
41
- usePageLiveActivity,
42
- usePolledValue
43
- } from "./chunk-RV3O5OCQ.js";
44
- import {
45
- normalizeError
46
- } from "./chunk-CM7LVUKC.js";
47
- import {
48
- formatRelativeTime
49
- } from "./chunk-5MOJZORA.js";
50
- import {
51
- SandboxTerminal,
52
- terminalCanAcquirePty,
53
- xtermThemeFromTokens
54
- } from "./chunk-5WUN7XPD.js";
55
- import {
56
- sandboxAcceptsLiveIo
57
- } from "./chunk-QV3DJVRZ.js";
58
- import {
59
- useOpenGeni,
60
- useOpenGeniClient
61
- } from "./chunk-TVQCDDSZ.js";
62
- import {
63
- cn
64
- } from "./chunk-TXS65BB2.js";
65
- import {
66
- useOpenGeniText
67
- } from "./chunk-TNUSPXPW.js";
68
-
69
- // src/session-auth-recommendation.ts
70
- function sessionAuthRecommendation(t, item, catalog) {
71
- if (item.authoritySource === "host" || item.reason === "unsupported_auth" || item.reason === "resource_scope_unavailable")
72
- return void 0;
73
- if (item.capability) return item;
74
- const recoveryServerId = item.canonicalServerId ?? item.serverId;
75
- const matches = catalog.filter(
76
- (candidate) => recoveryServerId !== null && candidate.runtime.mcpServerId === recoveryServerId && recoveryServerId !== "opengeni" || item.connectionId !== null && candidate.connectionRef?.connectionId === item.connectionId
77
- );
78
- if (matches.length !== 1) return void 0;
79
- const entry = matches[0];
80
- const personalAccess = item.reason === "personal_authority_unavailable";
81
- if (personalAccess && ((item.connectionSubjectScope ?? entry.connectionRef?.subjectScope) !== "subject" || entry.connectionRef?.authoritySource === "host"))
82
- return void 0;
83
- return {
84
- ...item,
85
- capability: {
86
- id: entry.id,
87
- name: entry.name,
88
- kind: entry.kind,
89
- source: entry.source,
90
- action: "connect",
91
- rationale: personalAccess ? t("sessionAuthRecommendation.reviewPermissionToUseYour") : t("sessionAuthRecommendation.reconnectThisIntegrationToUse"),
92
- requiredVariables: []
93
- }
94
- };
95
- }
96
-
97
- // src/components/session-connection-request.tsx
98
- import { useEffect, useRef, useState } from "react";
99
- import { jsx, jsxs } from "react/jsx-runtime";
100
- function SessionConnectionRequest(props) {
101
- const [client, setClient] = useState(props.client);
102
- const [generation, setGeneration] = useState(0);
103
- if (client !== props.client) {
104
- setClient(props.client);
105
- setGeneration(generation + 1);
106
- }
107
- return /* @__PURE__ */ jsx(
108
- ScopedRequest,
109
- {
110
- ...props
111
- },
112
- `${generation}:${props.workspaceId}:${props.sessionId}:${props.request.id}`
113
- );
114
- }
115
- function ScopedRequest({ request, ...props }) {
116
- const t = useOpenGeniText();
117
- const [resolved, setResolved] = useState(null);
118
- const [error, setError] = useState(null);
119
- const [retry, setRetry] = useState(0);
120
- const requestRef = useRef(request);
121
- requestRef.current = request;
122
- useEffect(() => {
123
- let current = true;
124
- const event = requestRef.current;
125
- setResolved(null);
126
- setError(null);
127
- void props.client.listCapabilities(props.workspaceId).then((catalog) => {
128
- if (!current) return;
129
- const recommendation = sessionAuthRecommendation(t, event, catalog.items);
130
- const candidate = catalog.items.find(
131
- (entry) => entry.id === recommendation?.capability?.id
132
- );
133
- if (!recommendation || candidate?.kind !== "mcp" || candidate.authKind !== "oauth2") {
134
- setError(t("sessionConnectionRequest.thisRequestCouldNotBe"));
135
- return;
136
- }
137
- setResolved(recommendation);
138
- }).catch(() => {
139
- if (current) setError(t("sessionConnectionRequest.couldnTLoadConnectionDetails"));
140
- });
141
- return () => {
142
- current = false;
143
- };
144
- }, [
145
- props.client,
146
- props.workspaceId,
147
- request.id,
148
- request.serverId,
149
- request.connectionId,
150
- request.authoritySource,
151
- request.reason,
152
- request.capability?.id,
153
- retry,
154
- t
155
- ]);
156
- if (!resolved?.capability)
157
- return /* @__PURE__ */ jsxs("div", { className: "og-session-capability-setup", children: [
158
- /* @__PURE__ */ jsx("p", { role: error ? "alert" : "status", children: error ?? t("sessionConnectionRequest.loadingConnectionDetails") }),
159
- error ? /* @__PURE__ */ jsx("button", { type: "button", onClick: () => setRetry((value) => value + 1), children: t("sessionConnectionRequest.retry") }) : null
160
- ] });
161
- return /* @__PURE__ */ jsx(
162
- SessionMcpCapabilityCard,
163
- {
164
- ...props,
165
- capabilityId: resolved.capability.id,
166
- name: resolved.capability.name,
167
- rationale: resolved.capability.rationale
168
- }
169
- );
170
- }
171
-
172
- // src/hooks/use-video-artifact-playback.ts
173
- import { useMemo } from "react";
174
- function useVideoArtifactPlaybackLoader(options = {}) {
175
- const { client, workspaceId } = useOpenGeni(options);
176
- return useMemo(
177
- () => async (artifactId, signal) => {
178
- if (typeof client.createVideoArtifactPlaybackSource !== "function") {
179
- throw new Error("This Opengeni host does not expose retained-video playback.");
180
- }
181
- return await client.createVideoArtifactPlaybackSource(
182
- workspaceId,
183
- artifactId,
184
- signal ? { signal } : {}
185
- );
186
- },
187
- [client, workspaceId]
188
- );
189
- }
190
-
191
- // src/hooks/use-scheduled-tasks.ts
192
- import { useCallback } from "react";
193
- function useScheduledTasks(options = {}) {
194
- const { client, workspaceId } = useOpenGeni(options);
195
- const limit = options.limit;
196
- const load = useCallback(
197
- async () => await client.listScheduledTasks(workspaceId, limit !== void 0 ? { limit } : {}),
198
- [client, workspaceId, limit]
199
- );
200
- const state = usePolledValue(load, {
201
- pollIntervalMs: options.pollIntervalMs,
202
- enabled: options.enabled
203
- });
204
- return {
205
- tasks: state.data ?? [],
206
- loading: state.loading,
207
- error: state.error,
208
- refresh: state.refresh
209
- };
210
- }
211
-
212
- // src/hooks/use-workspace-background-commands.ts
213
- import { useCallback as useCallback2, useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
214
- function useWorkspaceBackgroundCommands(options = {}) {
215
- const { client, workspaceId } = useOpenGeni(options);
216
- const [pages, setPages] = useState2(1);
217
- const enabled = options.enabled ?? true;
218
- useEffect2(() => setPages(1), [client, workspaceId]);
219
- const load = useCallback2(
220
- async (signal) => {
221
- if (!client.listWorkspaceBackgroundCommands)
222
- throw new Error("The configured client does not support workspace commands");
223
- const commands = /* @__PURE__ */ new Map();
224
- let cursor;
225
- for (let page = 0; page < pages; page += 1) {
226
- signal?.throwIfAborted();
227
- const result = await client.listWorkspaceBackgroundCommands(workspaceId, {
228
- ...cursor ? { cursor } : {},
229
- ...signal ? { signal } : {}
230
- });
231
- for (const command of result.commands) commands.set(command.id, command);
232
- cursor = result.nextCursor ?? void 0;
233
- if (!cursor) break;
234
- }
235
- return { commands: [...commands.values()], hasMore: Boolean(cursor) };
236
- },
237
- [client, workspaceId, pages]
238
- );
239
- const state = usePolledValue(load, { enabled, pollIntervalMs: options.pollIntervalMs ?? 5e3 });
240
- const { data, refresh } = state;
241
- const generation = useRef2(0);
242
- useEffect2(() => {
243
- generation.current += 1;
244
- return () => {
245
- generation.current += 1;
246
- };
247
- }, [client, workspaceId, enabled]);
248
- const cancel = useCallback2(
249
- async (commandId) => {
250
- const command = data?.commands.find((item) => item.id === commandId);
251
- if (!command || !enabled) return;
252
- if (!client.cancelSessionBackgroundCommand)
253
- throw new Error("The configured client does not support stopping commands");
254
- const ticket = generation.current;
255
- await client.cancelSessionBackgroundCommand(workspaceId, command.sessionId, commandId);
256
- if (ticket === generation.current) await refresh();
257
- },
258
- [client, workspaceId, enabled, data, refresh]
259
- );
260
- return {
261
- commands: enabled && !state.error ? state.data?.commands ?? [] : [],
262
- loading: enabled && state.loading,
263
- error: enabled ? state.error : null,
264
- refresh: state.refresh,
265
- cancel,
266
- hasMore: enabled && !state.error && (state.data?.hasMore ?? false),
267
- loadMore: () => setPages((value) => value + 1)
268
- };
269
- }
270
-
271
- // src/index.ts
272
- import { asVaultClient, vaultsApi, vaultErrorCode, vaultErrorDetail } from "@opengeni/sdk";
273
-
274
- // src/hooks/use-workspaces.ts
275
- import { useCallback as useCallback3 } from "react";
276
- function useWorkspaces(options = {}) {
277
- const client = useOpenGeniClient(options);
278
- const load = useCallback3(async () => await client.listWorkspaces(), [client]);
279
- const { data, loading, error, refresh } = usePolledValue(load, {
280
- pollIntervalMs: options.pollIntervalMs,
281
- enabled: options.enabled
282
- });
283
- const { run, mutating, mutationError, clearMutationError } = useMutationRunner();
284
- const create = useCallback3(
285
- async (request) => {
286
- const result = await run(() => client.createWorkspace(request));
287
- if (result) {
288
- await refresh();
289
- }
290
- return result;
291
- },
292
- [client, run, refresh]
293
- );
294
- const update = useCallback3(
295
- async (workspaceId, request) => {
296
- const result = await run(() => client.updateWorkspace(workspaceId, request));
297
- if (result) {
298
- await refresh();
299
- }
300
- return result;
301
- },
302
- [client, run, refresh]
303
- );
304
- return {
305
- workspaces: data ?? [],
306
- loading,
307
- error,
308
- refresh,
309
- create,
310
- update,
311
- mutating,
312
- mutationError,
313
- clearMutationError
314
- };
315
- }
316
-
317
- // src/hooks/use-billing-usage.ts
318
- import { useCallback as useCallback4 } from "react";
319
- function useBillingUsage(options = {}) {
320
- const client = useOpenGeniClient(options);
321
- const accountId = options.accountId;
322
- const workspaceId = options.workspaceId;
323
- const load = useCallback4(
324
- async () => await client.getBillingUsage({
325
- ...accountId !== void 0 ? { accountId } : {},
326
- ...workspaceId !== void 0 ? { workspaceId } : {}
327
- }),
328
- [client, accountId, workspaceId]
329
- );
330
- const state = usePolledValue(load, {
331
- pollIntervalMs: options.pollIntervalMs,
332
- enabled: options.enabled
333
- });
334
- return {
335
- balance: state.data?.balance ?? null,
336
- usage: state.data?.usage ?? [],
337
- loading: state.loading,
338
- error: state.error,
339
- refresh: state.refresh
340
- };
341
- }
342
-
343
- // src/hooks/use-session-capabilities.ts
344
- import {
345
- OpenGeniApiError,
346
- applyUrlRotation
347
- } from "@opengeni/sdk";
348
- import { useCallback as useCallback5, useEffect as useEffect3, useRef as useRef3, useState as useState3 } from "react";
349
- function desktopAttachable(cell) {
350
- if (cell.transport !== null) return true;
351
- return cell.reason === "lease_cold" || cell.reason === "not_provisioned" || cell.reason === null;
352
- }
353
- function rotationsFrom(events) {
354
- const out = [];
355
- for (const event of events) {
356
- if (event.type === "stream.url.rotated" && event.payload && typeof event.payload === "object") {
357
- out.push(event.payload);
358
- }
359
- }
360
- return out;
361
- }
362
- function useSessionCapabilities(sessionId, options = {}) {
363
- const { client, workspaceId } = useOpenGeni(options);
364
- const enabled = (options.enabled ?? true) && Boolean(sessionId);
365
- const pageLive = usePageLiveActivity();
366
- const lifecycleEnabled = enabled && pageLive;
367
- const attachDesktop = options.attachDesktop ?? false;
368
- const attachTerminal = options.attachTerminal ?? false;
369
- const attachFiles = options.attachFiles ?? false;
370
- const warmingPollMs = options.warmingPollMs ?? 1500;
371
- const warmingDeadlineMs = options.warmingDeadlineMs ?? 3e4;
372
- const identityKey = `${workspaceId}\0${sessionId ?? ""}\0${enabled}`;
373
- const [capabilities, setCapabilities] = useState3(null);
374
- const [state, setState] = useState3("idle");
375
- const [error, setError] = useState3(null);
376
- const [acknowledgmentRequired, setAcknowledgmentRequired] = useState3(null);
377
- const [viewerCapReached, setViewerCapReached] = useState3(false);
378
- const [viewerId, setViewerId] = useState3(null);
379
- const [stateIdentity, setStateIdentity] = useState3(identityKey);
380
- const [nonce, setNonce] = useState3(0);
381
- const epochRef = useRef3(0);
382
- const viewerIdRef = useRef3(null);
383
- const previousIdentityRef = useRef3(identityKey);
384
- const renegotiate = useCallback5(() => {
385
- setNonce((n) => n + 1);
386
- }, []);
387
- useEffect3(() => {
388
- const identityChanged = previousIdentityRef.current !== identityKey;
389
- previousIdentityRef.current = identityKey;
390
- if (identityChanged) {
391
- setStateIdentity(identityKey);
392
- setCapabilities(null);
393
- setState("idle");
394
- setError(null);
395
- setAcknowledgmentRequired(null);
396
- setViewerCapReached(false);
397
- setViewerId(null);
398
- epochRef.current = 0;
399
- viewerIdRef.current = null;
400
- }
401
- if (!lifecycleEnabled || !sessionId) {
402
- setState("idle");
403
- setCapabilities(null);
404
- viewerIdRef.current = null;
405
- setViewerId(null);
406
- return;
407
- }
408
- viewerIdRef.current = null;
409
- setViewerId(null);
410
- let cancelled = false;
411
- let pollTimer = null;
412
- let heartbeatTimer = null;
413
- let localViewerId = null;
414
- const requestAbort = new AbortController();
415
- const startedAt = Date.now();
416
- const clearTimers = () => {
417
- if (pollTimer !== null) clearTimeout(pollTimer);
418
- if (heartbeatTimer !== null) clearTimeout(heartbeatTimer);
419
- pollTimer = null;
420
- heartbeatTimer = null;
421
- };
422
- const settle = (caps) => {
423
- if (cancelled) return;
424
- epochRef.current = caps.leaseEpoch;
425
- setCapabilities(caps);
426
- setError(null);
427
- };
428
- const startHeartbeat = (caps) => {
429
- if (!localViewerId || heartbeatTimer !== null) return;
430
- const intervalMs = caps.viewerHeartbeatIntervalMs > 0 ? caps.viewerHeartbeatIntervalMs : 3e4;
431
- const schedule = () => {
432
- if (cancelled || !localViewerId) return;
433
- heartbeatTimer = setTimeout(() => {
434
- heartbeatTimer = null;
435
- if (cancelled || !localViewerId) return;
436
- void client.heartbeatViewer(workspaceId, sessionId, localViewerId, {
437
- leaseEpoch: epochRef.current
438
- }).then((res) => {
439
- if (!res.alive && !cancelled) {
440
- renegotiate();
441
- }
442
- }).catch((cause) => {
443
- if (cancelled) return;
444
- if (cause instanceof OpenGeniApiError && (cause.status === 409 || cause.status === 410)) {
445
- renegotiate();
446
- }
447
- }).finally(schedule);
448
- }, intervalMs);
449
- };
450
- schedule();
451
- };
452
- const pollUntilWarm = () => {
453
- pollTimer = setTimeout(() => {
454
- if (cancelled) return;
455
- void client.getStreamCapabilities(workspaceId, sessionId, { signal: requestAbort.signal }).then((caps) => {
456
- if (cancelled) return;
457
- settle(caps);
458
- if (sandboxAcceptsLiveIo(caps.liveness)) {
459
- setState("ready");
460
- return;
461
- }
462
- if (warmingDeadlineMs > 0 && Date.now() - startedAt > warmingDeadlineMs) {
463
- setState("error");
464
- setError(new Error("sandbox did not warm in time \u2014 retry to re-negotiate"));
465
- return;
466
- }
467
- pollUntilWarm();
468
- }).catch((cause) => {
469
- if (!cancelled) {
470
- if (isSandboxOwnershipDisabledError(cause)) {
471
- setState("on-demand");
472
- setError(null);
473
- return;
474
- }
475
- setState("error");
476
- setError(normalizeError(cause));
477
- }
478
- });
479
- }, warmingPollMs);
480
- };
481
- void (async () => {
482
- setState("negotiating");
483
- setAcknowledgmentRequired(null);
484
- setViewerCapReached(false);
485
- try {
486
- const caps = await client.getStreamCapabilities(workspaceId, sessionId, {
487
- signal: requestAbort.signal
488
- });
489
- if (cancelled) return;
490
- settle(caps);
491
- const wantDesktopAttach = attachDesktop && desktopAttachable(caps.DesktopStream);
492
- const wantTerminalAttach = attachTerminal && terminalCanAcquirePty(caps.Terminal);
493
- const wantFilesAttach = attachFiles && caps.FileSystem.available;
494
- if (wantDesktopAttach || wantTerminalAttach || wantFilesAttach) {
495
- try {
496
- const holder = await client.attachViewer(workspaceId, sessionId, {
497
- desktop: wantDesktopAttach,
498
- terminal: wantTerminalAttach,
499
- files: wantFilesAttach
500
- });
501
- if (cancelled) {
502
- void client.detachViewer(workspaceId, sessionId, holder.viewerId).catch(() => {
503
- });
504
- return;
505
- }
506
- if (wantDesktopAttach && (!holder.dataPlaneUrl || !holder.transport || !holder.client) || wantTerminalAttach && (!holder.terminalUrl || !holder.terminalTransport)) {
507
- await client.detachViewer(workspaceId, sessionId, holder.viewerId).catch(() => {
508
- });
509
- throw new Error("live plane unavailable");
510
- }
511
- localViewerId = holder.viewerId;
512
- viewerIdRef.current = holder.viewerId;
513
- setViewerId(holder.viewerId);
514
- epochRef.current = holder.leaseEpoch;
515
- setCapabilities(
516
- (prev) => prev ? {
517
- ...prev,
518
- liveness: holder.liveness,
519
- leaseEpoch: holder.leaseEpoch,
520
- viewerHeartbeatIntervalMs: holder.viewerHeartbeatIntervalMs,
521
- DesktopStream: wantDesktopAttach ? {
522
- ...prev.DesktopStream,
523
- transport: holder.transport ?? prev.DesktopStream.transport,
524
- client: holder.client ?? prev.DesktopStream.client,
525
- url: holder.dataPlaneUrl,
526
- token: holder.streamToken,
527
- expiresAt: holder.streamExpiresAt,
528
- resolution: holder.resolution ?? prev.DesktopStream.resolution
529
- } : prev.DesktopStream,
530
- Terminal: wantTerminalAttach ? {
531
- ...prev.Terminal,
532
- transport: holder.terminalTransport ?? prev.Terminal.transport,
533
- url: holder.terminalUrl,
534
- token: holder.terminalToken,
535
- expiresAt: holder.terminalExpiresAt,
536
- // A live pty-ws means the box is pty-capable for real.
537
- ptyCapable: holder.terminalTransport ? true : prev.Terminal.ptyCapable,
538
- reason: holder.terminalTransport ? null : prev.Terminal.reason
539
- } : prev.Terminal
540
- } : prev
541
- );
542
- } catch (cause) {
543
- if (cancelled) return;
544
- if (cause instanceof OpenGeniApiError) {
545
- if (cause.status === 409) {
546
- if (wantDesktopAttach) {
547
- setAcknowledgmentRequired(
548
- cause.message.includes("shared_acknowledgment") ? "shared" : "unredacted"
549
- );
550
- }
551
- } else if (cause.status === 429) {
552
- setViewerCapReached(true);
553
- } else if (cause.status === 403) {
554
- setState("error");
555
- setError(cause);
556
- return;
557
- } else {
558
- throw cause;
559
- }
560
- } else {
561
- throw cause;
562
- }
563
- }
564
- }
565
- const warmUpRequested = wantDesktopAttach || wantTerminalAttach || wantFilesAttach;
566
- if (sandboxAcceptsLiveIo(caps.liveness) || localViewerId) {
567
- setState("ready");
568
- startHeartbeat(caps);
569
- } else if (warmUpRequested) {
570
- setState("cold");
571
- pollUntilWarm();
572
- } else {
573
- setState("on-demand");
574
- }
575
- } catch (cause) {
576
- if (cancelled) return;
577
- if (isSandboxOwnershipDisabledError(cause)) {
578
- setState("on-demand");
579
- setError(null);
580
- return;
581
- }
582
- if (cause instanceof OpenGeniApiError && cause.status === 403) {
583
- setState("error");
584
- setError(new Error("not permitted to view this session's sandbox"));
585
- return;
586
- }
587
- setState("error");
588
- setError(normalizeError(cause));
589
- }
590
- })();
591
- return () => {
592
- cancelled = true;
593
- requestAbort.abort();
594
- clearTimers();
595
- const releaseId = localViewerId ?? viewerIdRef.current;
596
- if (releaseId) {
597
- void client.detachViewer(workspaceId, sessionId, releaseId).catch(() => {
598
- });
599
- }
600
- };
601
- }, [
602
- client,
603
- workspaceId,
604
- sessionId,
605
- lifecycleEnabled,
606
- attachDesktop,
607
- attachTerminal,
608
- attachFiles,
609
- warmingPollMs,
610
- warmingDeadlineMs,
611
- nonce,
612
- identityKey
613
- ]);
614
- const events = options.events;
615
- useEffect3(() => {
616
- if (!events || events.length === 0) return;
617
- setCapabilities((prev) => {
618
- if (!prev || !prev.DesktopStream.url) return prev;
619
- let next = prev.DesktopStream;
620
- let changed = false;
621
- for (const rotation of rotationsFrom(events)) {
622
- if (rotation.viewerId && viewerIdRef.current && rotation.viewerId !== viewerIdRef.current) {
623
- continue;
624
- }
625
- const applied = applyUrlRotation(next, rotation, epochRef.current);
626
- if (applied) {
627
- next = { ...next, url: applied.url, token: applied.token, expiresAt: applied.expiresAt };
628
- epochRef.current = Math.max(epochRef.current, rotation.leaseEpoch);
629
- changed = true;
630
- }
631
- }
632
- return changed ? { ...prev, DesktopStream: next, leaseEpoch: epochRef.current } : prev;
633
- });
634
- }, [events]);
635
- const identityMatches = enabled && stateIdentity === identityKey;
636
- return {
637
- capabilities: identityMatches ? capabilities : null,
638
- state: identityMatches ? state : "idle",
639
- error: identityMatches ? error : null,
640
- acknowledgmentRequired: identityMatches ? acknowledgmentRequired : null,
641
- viewerCapReached: identityMatches && viewerCapReached,
642
- viewerId: identityMatches ? viewerId : null,
643
- renegotiate
644
- };
645
- }
646
- function isSandboxOwnershipDisabledError(error) {
647
- return error instanceof OpenGeniApiError && error.status === 404 && error.message.includes("sandbox ownership is not enabled");
648
- }
649
-
650
- // src/hooks/use-sandbox-terminal.ts
651
- import { OpenGeniApiError as OpenGeniApiError2 } from "@opengeni/sdk";
652
- import { useCallback as useCallback6, useEffect as useEffect4, useMemo as useMemo2, useRef as useRef4, useState as useState4 } from "react";
653
- var SANDBOX_TERMINAL_HISTORY_ROWS = 1e3;
654
- var SANDBOX_TERMINAL_MAX_ROWS = 4e3;
655
- function useSandboxTerminal(sessionId, options) {
656
- const { client, workspaceId } = useOpenGeni(options);
657
- const includeAgentFirehose = options.includeAgentFirehose ?? true;
658
- const interactive = options.interactive ?? false;
659
- const ptyFilter = options.ptyId;
660
- const liveness = options.liveness;
661
- const identityKey = `${workspaceId}\0${sessionId ?? ""}\0${interactive}\0${ptyFilter ?? ""}`;
662
- const [openedPtyId, setOpenedPtyId] = useState4(null);
663
- const [openError, setOpenError] = useState4(null);
664
- const [stateIdentity, setStateIdentity] = useState4(identityKey);
665
- const [reopenNonce, setReopenNonce] = useState4(0);
666
- const currentIdentityRef = useRef4(identityKey);
667
- currentIdentityRef.current = identityKey;
668
- useEffect4(() => {
669
- setStateIdentity(identityKey);
670
- setOpenedPtyId(null);
671
- setOpenError(null);
672
- }, [identityKey]);
673
- const openInFlight = useRef4(false);
674
- const boxWarm = liveness === void 0 || sandboxAcceptsLiveIo(liveness);
675
- useEffect4(() => {
676
- if (!interactive || !sessionId || ptyFilter || !boxWarm) {
677
- setOpenError(null);
678
- return;
679
- }
680
- let cancelled = false;
681
- setOpenError(null);
682
- openInFlight.current = true;
683
- let openedId = null;
684
- void client.terminalPtyOpen(workspaceId, sessionId, {}).then((res) => {
685
- if (cancelled) {
686
- void client.terminalPtyClose(workspaceId, sessionId, { ptyId: res.ptyId }).catch(() => {
687
- });
688
- return;
689
- }
690
- openedId = res.ptyId;
691
- setOpenedPtyId(res.ptyId);
692
- }).catch((cause) => {
693
- if (!cancelled) setOpenError(cause instanceof Error ? cause : new Error(String(cause)));
694
- }).finally(() => {
695
- openInFlight.current = false;
696
- });
697
- return () => {
698
- cancelled = true;
699
- setOpenedPtyId(null);
700
- const id = openedId;
701
- if (id) void client.terminalPtyClose(workspaceId, sessionId, { ptyId: id }).catch(() => {
702
- });
703
- };
704
- }, [interactive, client, workspaceId, sessionId, ptyFilter, boxWarm, reopenNonce]);
705
- const outputTypes = useMemo2(
706
- () => includeAgentFirehose && !ptyFilter ? ["terminal.pty.output.delta", "sandbox.command.output.delta"] : ["terminal.pty.output.delta"],
707
- [includeAgentFirehose, ptyFilter]
708
- );
709
- const historyKey = `${workspaceId}\0${sessionId ?? ""}\0${outputTypes.join(",")}`;
710
- const historyEnabled = (options.history ?? true) && Boolean(sessionId);
711
- const gapGeneration = useTurnlessOutputGap(workspaceId, sessionId);
712
- const [history, setHistory] = useState4(null);
713
- const [historyTick, setHistoryTick] = useState4(0);
714
- const readRef = useRef4(historyReadState(historyKey));
715
- const mountedRef = useRef4(false);
716
- useEffect4(() => {
717
- mountedRef.current = true;
718
- return () => {
719
- mountedRef.current = false;
720
- const state = readRef.current;
721
- if (state.timer) clearTimeout(state.timer);
722
- state.timer = null;
723
- };
724
- }, []);
725
- useEffect4(() => {
726
- let state = readRef.current;
727
- if (state.key !== historyKey) {
728
- if (state.timer) clearTimeout(state.timer);
729
- state = historyReadState(historyKey);
730
- readRef.current = state;
731
- setHistory(null);
732
- }
733
- if (!historyEnabled || !sessionId || state.inFlight || state.timer) return;
734
- if (!state.failed && state.generation === gapGeneration) return;
735
- const now = Date.now();
736
- const wait = state.failed ? terminalHistoryRetryDelay(state.failures) - (now - state.startedAt) : state.generation === null ? 0 : SANDBOX_TERMINAL_REREAD_MIN_MS - (now - state.startedAt);
737
- if (wait > 0) {
738
- state.timer = setTimeout(() => {
739
- state.timer = null;
740
- if (mountedRef.current) setHistoryTick((tick) => tick + 1);
741
- }, wait);
742
- return;
743
- }
744
- const generation = gapGeneration;
745
- state.inFlight = true;
746
- state.startedAt = now;
747
- const current = () => mountedRef.current && readRef.current === state;
748
- void readTerminalHistory(client, workspaceId, sessionId, outputTypes).then(
749
- (page) => {
750
- state.inFlight = false;
751
- if (!current()) return;
752
- state.failed = false;
753
- state.failures = 0;
754
- state.generation = generation;
755
- setHistory({ key: state.key, events: page.events, complete: page.complete });
756
- setHistoryTick((tick) => tick + 1);
757
- },
758
- (cause) => {
759
- state.inFlight = false;
760
- if (!current()) return;
761
- if (cause instanceof OpenGeniApiError2 && cause.status >= 400 && cause.status < 500 && cause.status !== 408 && cause.status !== 429) {
762
- state.failed = false;
763
- state.failures = 0;
764
- state.generation = generation;
765
- return;
766
- }
767
- state.failed = true;
768
- state.failures += 1;
769
- setHistoryTick((tick) => tick + 1);
770
- }
771
- );
772
- }, [
773
- historyEnabled,
774
- historyKey,
775
- gapGeneration,
776
- historyTick,
777
- outputTypes,
778
- client,
779
- workspaceId,
780
- sessionId
781
- ]);
782
- const liveRef = useRef4({ key: historyKey, rows: /* @__PURE__ */ new Map(), below: 0 });
783
- const { chunks, openPty, supportsInput } = useMemo2(() => {
784
- const open = /* @__PURE__ */ new Map();
785
- let lastOpened = null;
786
- let lastSupportsInput = false;
787
- if (liveRef.current.key !== historyKey) {
788
- liveRef.current = { key: historyKey, rows: /* @__PURE__ */ new Map(), below: 0 };
789
- }
790
- const liveRows = liveRef.current;
791
- const live = liveRows.rows;
792
- const types = new Set(outputTypes);
793
- for (const event of options.events) {
794
- if (event.workspaceId !== workspaceId || event.sessionId !== sessionId) continue;
795
- if (event.type === "terminal.pty.started") {
796
- const payload = event.payload;
797
- if (payload?.ptyId) {
798
- open.set(payload.ptyId, { supportsInput: true });
799
- lastOpened = payload.ptyId;
800
- }
801
- continue;
802
- }
803
- if (event.type === "terminal.pty.exited") {
804
- const payload = event.payload;
805
- if (payload?.ptyId) {
806
- open.delete(payload.ptyId);
807
- if (lastOpened === payload.ptyId) lastOpened = null;
808
- }
809
- continue;
810
- }
811
- if (types.has(event.type) && event.sequence >= liveRows.below && !live.has(event.id)) {
812
- live.set(event.id, event);
813
- }
814
- }
815
- trimLiveRows(liveRows);
816
- const loaded = history?.key === historyKey ? history : null;
817
- const floor = loaded && !loaded.complete ? loaded.events[0]?.sequence ?? 0 : 0;
818
- const seen = /* @__PURE__ */ new Set();
819
- const out = [];
820
- const add = (event) => {
821
- if (seen.has(event.id) || event.sequence < floor) return;
822
- seen.add(event.id);
823
- const chunk = terminalChunk(event, ptyFilter);
824
- if (chunk) out.push(chunk);
825
- };
826
- loaded?.events.forEach(add);
827
- live.forEach(add);
828
- out.sort((a, b) => a.seq - b.seq);
829
- const activePty = ptyFilter && open.has(ptyFilter) ? ptyFilter : lastOpened;
830
- lastSupportsInput = activePty ? open.get(activePty)?.supportsInput ?? false : false;
831
- return {
832
- chunks: out.length > SANDBOX_TERMINAL_MAX_ROWS ? out.slice(-SANDBOX_TERMINAL_MAX_ROWS) : out,
833
- openPty: activePty,
834
- supportsInput: lastSupportsInput
835
- };
836
- }, [options.events, history, historyKey, outputTypes, ptyFilter, workspaceId, sessionId]);
837
- const identityMatches = stateIdentity === identityKey;
838
- const activePtyId = identityMatches ? openedPtyId ?? openPty : null;
839
- const canWrite = openedPtyId !== null || supportsInput;
840
- const write = useMemo2(() => {
841
- if (!activePtyId || !canWrite || !sessionId) return null;
842
- const writeIdentity = identityKey;
843
- return (data) => {
844
- void client.terminalPtyWrite(workspaceId, sessionId, { ptyId: activePtyId, data }).catch((cause) => {
845
- if (cause instanceof OpenGeniApiError2 && (cause.status === 409 || cause.status === 404) && activePtyId === openedPtyId && currentIdentityRef.current === writeIdentity) {
846
- setOpenedPtyId(null);
847
- setReopenNonce((n) => n + 1);
848
- }
849
- });
850
- };
851
- }, [client, workspaceId, sessionId, activePtyId, canWrite, openedPtyId, identityKey]);
852
- const close = useCallback6(() => {
853
- if (!activePtyId || !sessionId) return;
854
- void client.terminalPtyClose(workspaceId, sessionId, { ptyId: activePtyId }).catch(() => {
855
- });
856
- }, [client, workspaceId, sessionId, activePtyId]);
857
- return {
858
- chunks,
859
- running: activePtyId !== null,
860
- write,
861
- activePtyId,
862
- close,
863
- error: identityMatches ? openError : null
864
- };
865
- }
866
- function trimLiveRows(live) {
867
- const { rows } = live;
868
- if (rows.size <= SANDBOX_TERMINAL_MAX_ROWS + SANDBOX_TERMINAL_MAX_ROWS / 4) return;
869
- const sorted = [...rows.values()].sort((left, right) => left.sequence - right.sequence);
870
- const drop = sorted.length - SANDBOX_TERMINAL_MAX_ROWS;
871
- for (const event of sorted.slice(0, drop)) rows.delete(event.id);
872
- live.below = Math.max(live.below, sorted[drop].sequence);
873
- }
874
- function historyReadState(key) {
875
- return {
876
- key,
877
- generation: null,
878
- inFlight: false,
879
- failed: false,
880
- failures: 0,
881
- startedAt: 0,
882
- timer: null
883
- };
884
- }
885
- var SANDBOX_TERMINAL_REREAD_MIN_MS = 1e3;
886
- function terminalHistoryRetryDelay(failures) {
887
- return Math.min(3e4, 1e3 * 2 ** Math.max(0, failures - 1));
888
- }
889
- function terminalChunk(event, ptyFilter) {
890
- if (event.type === "terminal.pty.output.delta") {
891
- const payload = event.payload;
892
- if (!payload || typeof payload.chunk !== "string") return null;
893
- if (ptyFilter && payload.ptyId !== ptyFilter) return null;
894
- return {
895
- id: event.id,
896
- text: payload.chunk,
897
- stream: payload.stream === "stderr" ? "stderr" : "stdout",
898
- seq: event.sequence
899
- };
900
- }
901
- if (event.type === "sandbox.command.output.delta" && !ptyFilter) {
902
- const payload = event.payload;
903
- if (!payload?.chunk) return null;
904
- return {
905
- id: event.id,
906
- text: payload.chunk,
907
- stream: payload.stream === "stderr" ? "stderr" : "stdout",
908
- seq: event.sequence
909
- };
910
- }
911
- return null;
912
- }
913
- async function readTerminalHistory(client, workspaceId, sessionId, includeTypes) {
914
- const options = {
915
- includeTypes,
916
- direction: "before",
917
- // Explicit: a cursorless read otherwise defaults to the monitoring tail,
918
- // which drops raw output deltas.
919
- mode: "forensic",
920
- payloadMode: "full",
921
- limit: SANDBOX_TERMINAL_HISTORY_ROWS
922
- };
923
- const pageClient = client;
924
- const page = typeof pageClient.listEventPage === "function" ? await pageClient.listEventPage(workspaceId, sessionId, options) : null;
925
- const events = page ? page.events : await client.listEvents(workspaceId, sessionId, options);
926
- const sorted = [...events].sort((left, right) => left.sequence - right.sequence);
927
- return {
928
- events: sorted,
929
- // Without a continuation fact, only an empty read is known complete: the
930
- // server's byte bound can cut a page short of the row limit.
931
- complete: page ? !page.hasMore : sorted.length === 0
932
- };
933
- }
934
-
935
- // src/hooks/use-sandbox-git.ts
936
- import { useCallback as useCallback7, useEffect as useEffect5, useMemo as useMemo3, useRef as useRef5, useState as useState5 } from "react";
937
- function normalizeRoot(root) {
938
- const normalized = root.replaceAll("\\", "/").replace(/^\.\/+/, "").replace(/\/+$/, "");
939
- return normalized === "." ? "" : normalized;
940
- }
941
- function qualifyPath(repoRoot, path) {
942
- const root = normalizeRoot(repoRoot);
943
- return root ? `${root}/${path}` : path;
944
- }
945
- function qualifyDiff(repoRoot, file) {
946
- const root = normalizeRoot(repoRoot);
947
- return {
948
- ...file,
949
- path: qualifyPath(root, file.path),
950
- oldPath: file.oldPath === null ? null : qualifyPath(root, file.oldPath),
951
- repoRoot: root
952
- };
953
- }
954
- function uniqueRoots(roots) {
955
- return [...new Set(roots.map(normalizeRoot))].sort((a, b) => a.localeCompare(b));
956
- }
957
- var GIT_READ_BATCH_REQUEST_LIMIT = 32;
958
- function repoForPath(manifest, repoPath) {
959
- const want = normalizeRoot(repoPath);
960
- const exact = manifest.repos.find((r) => normalizeRoot(r.root) === want);
961
- if (exact) return exact;
962
- if (want === "" && manifest.repos.length === 1) return manifest.repos[0] ?? null;
963
- return null;
964
- }
965
- function sameFileDiff(a, b) {
966
- if (a.path !== b.path || a.oldPath !== b.oldPath || a.repoRoot !== b.repoRoot || a.status !== b.status || a.isBinary !== b.isBinary || a.isImage !== b.isImage || a.additions !== b.additions || a.deletions !== b.deletions || a.truncated !== b.truncated || a.hunks.length !== b.hunks.length)
967
- return false;
968
- return a.hunks.every((hunk, hunkIndex) => {
969
- const other = b.hunks[hunkIndex];
970
- if (!other || hunk.oldStart !== other.oldStart || hunk.oldLines !== other.oldLines || hunk.newStart !== other.newStart || hunk.newLines !== other.newLines || hunk.header !== other.header || hunk.lines.length !== other.lines.length)
971
- return false;
972
- return hunk.lines.every((line, lineIndex) => {
973
- const otherLine = other.lines[lineIndex];
974
- return otherLine !== void 0 && line.type === otherLine.type && line.oldNo === otherLine.oldNo && line.newNo === otherLine.newNo && line.text === otherLine.text;
975
- });
976
- });
977
- }
978
- function mergeDiffs(current, next) {
979
- if (current.length === 0) return next;
980
- const byPath = new Map(current.map((d) => [d.path, d]));
981
- let changed = current.length !== next.length;
982
- const merged = next.map((file, index) => {
983
- const existing = byPath.get(file.path);
984
- if (existing && sameFileDiff(existing, file)) {
985
- if (current[index] !== existing) changed = true;
986
- return existing;
987
- }
988
- changed = true;
989
- return file;
990
- });
991
- return changed ? merged : current;
992
- }
993
- function useSandboxGit(sessionId, options = {}) {
994
- const { client, workspaceId } = useOpenGeni(options);
995
- const enabled = (options.enabled ?? true) && Boolean(sessionId);
996
- const active = options.active ?? true;
997
- const repoPath = options.repoPath ?? "";
998
- const workspaceWide = options.repoPaths !== void 0;
999
- const repoPathsKey = uniqueRoots(
1000
- options.repoPaths && options.repoPaths.length > 0 ? options.repoPaths : [repoPath]
1001
- ).join("\0");
1002
- const repoPaths = useMemo3(() => repoPathsKey.split("\0"), [repoPathsKey]);
1003
- const comparison = options.comparison ?? (options.staged ? "staged" : "working");
1004
- const hasAdvertisedRepoPaths = (options.repoPaths?.length ?? 0) > 0;
1005
- const capture = comparison === "staged" ? null : options.capture ?? null;
1006
- const isLive2 = sandboxAcceptsLiveIo(options.liveness);
1007
- const acceptsEventReads = options.liveness === void 0 || isLive2;
1008
- const acceptsEventReadsRef = useRef5(acceptsEventReads);
1009
- acceptsEventReadsRef.current = acceptsEventReads;
1010
- const hasLiveIoFence = options.liveness !== void 0;
1011
- const identityKey = `${workspaceId}\0${sessionId ?? ""}\0${repoPathsKey}\0${workspaceWide}\0${comparison}`;
1012
- const [diff, setDiff] = useState5([]);
1013
- const [branch, setBranch] = useState5(null);
1014
- const [isRepo, setIsRepo] = useState5(false);
1015
- const [ahead, setAhead] = useState5(0);
1016
- const [behind, setBehind] = useState5(0);
1017
- const [repoRoots, setRepoRoots] = useState5([]);
1018
- const [source, setSource] = useState5(null);
1019
- const sourceRef = useRef5(null);
1020
- const [loading, setLoading] = useState5(false);
1021
- const [error, setError] = useState5(null);
1022
- const [stateIdentity, setStateIdentity] = useState5(identityKey);
1023
- const refreshGenerationRef = useRef5(0);
1024
- const refreshAbortRef = useRef5(null);
1025
- const refreshInFlightRef = useRef5(null);
1026
- const refreshPendingRef = useRef5(false);
1027
- const refreshWorkerEpochRef = useRef5(0);
1028
- const lastChangeRef = useRef5(0);
1029
- const eventRefreshTimerRef = useRef5(null);
1030
- const performRefresh = useCallback7(async () => {
1031
- if (!sessionId) return;
1032
- const refreshAbort = new AbortController();
1033
- refreshAbortRef.current = refreshAbort;
1034
- const generation = refreshGenerationRef.current += 1;
1035
- setLoading(true);
1036
- setError(null);
1037
- try {
1038
- const diffRequest = (root) => client.gitDiff(
1039
- workspaceId,
1040
- sessionId,
1041
- {
1042
- path: root,
1043
- ...comparison === "branch" ? { fromRef: "origin/HEAD", includeUntracked: true } : comparison === "working" ? { fromRef: "HEAD", includeUntracked: true } : { staged: true, includeUntracked: false }
1044
- },
1045
- { signal: refreshAbort.signal }
1046
- );
1047
- const prefetched = hasAdvertisedRepoPaths ? await (async () => {
1048
- const prefetchedRepos = [];
1049
- for (let offset = 0; offset < repoPaths.length; offset += GIT_READ_BATCH_REQUEST_LIMIT) {
1050
- const roots2 = repoPaths.slice(offset, offset + GIT_READ_BATCH_REQUEST_LIMIT);
1051
- const batch = await client.gitReadBatch(
1052
- workspaceId,
1053
- sessionId,
1054
- {
1055
- requests: roots2.map((root) => ({
1056
- status: { path: root },
1057
- diff: {
1058
- path: root,
1059
- ...comparison === "branch" ? { fromRef: "origin/HEAD", includeUntracked: true } : comparison === "working" ? { fromRef: "HEAD", includeUntracked: true } : { staged: true, includeUntracked: false }
1060
- }
1061
- }))
1062
- },
1063
- { signal: refreshAbort.signal }
1064
- );
1065
- if (batch.results.length !== roots2.length) {
1066
- throw new Error(
1067
- `Workspace Git batch returned ${batch.results.length} results for ${roots2.length} repositories.`
1068
- );
1069
- }
1070
- batch.results.forEach((item, index) => {
1071
- prefetchedRepos.push({
1072
- root: roots2[index],
1073
- status: item.status,
1074
- result: item.diff ?? {
1075
- files: [],
1076
- revision: item.status.revision
1077
- }
1078
- });
1079
- });
1080
- }
1081
- return prefetchedRepos;
1082
- })() : null;
1083
- const statuses = prefetched ?? await Promise.all(
1084
- repoPaths.map(async (root) => ({
1085
- root,
1086
- status: await client.gitStatus(
1087
- workspaceId,
1088
- sessionId,
1089
- { path: root },
1090
- { signal: refreshAbort.signal }
1091
- )
1092
- }))
1093
- );
1094
- if (refreshGenerationRef.current !== generation) return;
1095
- const repositories = statuses.filter(({ status }) => status.isRepo);
1096
- const roots = repositories.map(({ root }) => root);
1097
- setRepoRoots(roots);
1098
- setIsRepo(repositories.length > 0);
1099
- setBranch(repositories.length === 1 ? repositories[0]?.status.head ?? null : null);
1100
- setAhead(repositories.reduce((sum, { status }) => sum + status.ahead, 0));
1101
- setBehind(repositories.reduce((sum, { status }) => sum + status.behind, 0));
1102
- if (repositories.length === 0) {
1103
- setDiff([]);
1104
- sourceRef.current = "live";
1105
- setSource("live");
1106
- return;
1107
- }
1108
- const prefetchedByRoot = new Map(prefetched?.map(({ root, result }) => [root, result]));
1109
- const results = await Promise.all(
1110
- repositories.map(async ({ root }) => ({
1111
- root,
1112
- result: prefetchedByRoot.get(root) ?? await diffRequest(root)
1113
- }))
1114
- );
1115
- if (refreshGenerationRef.current !== generation) return;
1116
- setDiff(
1117
- (prev) => mergeDiffs(
1118
- prev,
1119
- results.flatMap(
1120
- ({ root, result }) => workspaceWide ? result.files.map((file) => qualifyDiff(root, file)) : result.files
1121
- )
1122
- )
1123
- );
1124
- sourceRef.current = "live";
1125
- setSource("live");
1126
- } catch (cause) {
1127
- if (refreshGenerationRef.current !== generation) return;
1128
- setError(cause instanceof Error ? cause : new Error(String(cause)));
1129
- } finally {
1130
- if (refreshGenerationRef.current === generation) setLoading(false);
1131
- if (refreshAbortRef.current === refreshAbort) refreshAbortRef.current = null;
1132
- }
1133
- }, [
1134
- client,
1135
- workspaceId,
1136
- sessionId,
1137
- repoPaths,
1138
- hasAdvertisedRepoPaths,
1139
- workspaceWide,
1140
- comparison
1141
- ]);
1142
- const performRefreshRef = useRef5(performRefresh);
1143
- performRefreshRef.current = performRefresh;
1144
- const refresh = useCallback7(async () => {
1145
- refreshPendingRef.current = true;
1146
- const existing = refreshInFlightRef.current;
1147
- if (existing) return await existing;
1148
- const workerEpoch = refreshWorkerEpochRef.current;
1149
- const run = (async () => {
1150
- while (refreshPendingRef.current && refreshWorkerEpochRef.current === workerEpoch) {
1151
- refreshPendingRef.current = false;
1152
- await performRefreshRef.current();
1153
- }
1154
- })();
1155
- refreshInFlightRef.current = run;
1156
- try {
1157
- await run;
1158
- } finally {
1159
- if (refreshInFlightRef.current === run) refreshInFlightRef.current = null;
1160
- }
1161
- }, []);
1162
- const seedFromCapture = useCallback7(
1163
- (manifest) => {
1164
- const repositories = workspaceWide ? manifest.repos : [repoForPath(manifest, repoPath)].filter(Boolean);
1165
- if (comparison === "branch" && repositories.some((repo) => repo.branchDiff === void 0)) {
1166
- return;
1167
- }
1168
- if (repositories.length === 0) {
1169
- setIsRepo(false);
1170
- setBranch(null);
1171
- setAhead(0);
1172
- setBehind(0);
1173
- setRepoRoots([]);
1174
- setDiff((prev) => prev.length === 0 ? prev : []);
1175
- sourceRef.current = "capture";
1176
- setSource("capture");
1177
- return;
1178
- }
1179
- setIsRepo(true);
1180
- setBranch(repositories.length === 1 ? repositories[0]?.head ?? null : null);
1181
- setAhead(repositories.reduce((sum, repo) => sum + repo.ahead, 0));
1182
- setBehind(repositories.reduce((sum, repo) => sum + repo.behind, 0));
1183
- setRepoRoots(repositories.map((repo) => normalizeRoot(repo.root)));
1184
- setDiff(
1185
- (prev) => mergeDiffs(
1186
- prev,
1187
- repositories.flatMap((repo) => {
1188
- const capturedDiff = comparison === "branch" ? repo.branchDiff ?? [] : repo.diff;
1189
- return workspaceWide ? capturedDiff.map((file) => qualifyDiff(repo.root, file)) : capturedDiff;
1190
- })
1191
- )
1192
- );
1193
- sourceRef.current = "capture";
1194
- setSource("capture");
1195
- setError(null);
1196
- },
1197
- [comparison, repoPath, workspaceWide]
1198
- );
1199
- const captureRef = useRef5(capture);
1200
- captureRef.current = capture;
1201
- const captureRevision = capture?.revision ?? null;
1202
- const previousIdentityRef = useRef5(identityKey);
1203
- useEffect5(() => {
1204
- refreshAbortRef.current?.abort();
1205
- refreshAbortRef.current = null;
1206
- refreshPendingRef.current = false;
1207
- refreshGenerationRef.current += 1;
1208
- const identityChanged = previousIdentityRef.current !== identityKey;
1209
- previousIdentityRef.current = identityKey;
1210
- if (identityChanged) {
1211
- refreshWorkerEpochRef.current += 1;
1212
- refreshInFlightRef.current = null;
1213
- }
1214
- if (identityChanged || !enabled) {
1215
- lastChangeRef.current = 0;
1216
- setDiff([]);
1217
- setStateIdentity(identityKey);
1218
- setIsRepo(false);
1219
- setBranch(null);
1220
- setAhead(0);
1221
- setBehind(0);
1222
- setRepoRoots([]);
1223
- sourceRef.current = null;
1224
- setSource(null);
1225
- setLoading(false);
1226
- setError(null);
1227
- }
1228
- if (!enabled) {
1229
- return;
1230
- }
1231
- const currentCapture = captureRevision !== null ? captureRef.current : null;
1232
- if (currentCapture && (identityChanged || !isLive2 || sourceRef.current !== "live")) {
1233
- seedFromCapture(currentCapture);
1234
- }
1235
- if (!active) {
1236
- if (!active) setLoading(false);
1237
- return;
1238
- }
1239
- if (isLive2 || !hasLiveIoFence && !currentCapture) {
1240
- void refresh();
1241
- }
1242
- return () => {
1243
- refreshAbortRef.current?.abort();
1244
- refreshAbortRef.current = null;
1245
- refreshPendingRef.current = false;
1246
- refreshGenerationRef.current += 1;
1247
- };
1248
- }, [
1249
- enabled,
1250
- active,
1251
- isLive2,
1252
- hasLiveIoFence,
1253
- captureRevision,
1254
- identityKey,
1255
- refresh,
1256
- seedFromCapture
1257
- ]);
1258
- const events = options.events;
1259
- useEffect5(() => {
1260
- if (!enabled || !events) {
1261
- if (eventRefreshTimerRef.current) {
1262
- clearTimeout(eventRefreshTimerRef.current);
1263
- eventRefreshTimerRef.current = null;
1264
- }
1265
- return;
1266
- }
1267
- if (!active || !acceptsEventReads) {
1268
- for (const event of events) {
1269
- if (event.sequence > lastChangeRef.current) lastChangeRef.current = event.sequence;
1270
- }
1271
- if (eventRefreshTimerRef.current) {
1272
- clearTimeout(eventRefreshTimerRef.current);
1273
- eventRefreshTimerRef.current = null;
1274
- }
1275
- return;
1276
- }
1277
- let latest = lastChangeRef.current;
1278
- let changed = false;
1279
- for (const event of events) {
1280
- if (event.sequence <= latest) continue;
1281
- if (event.type === "git.changed") {
1282
- latest = event.sequence;
1283
- changed = true;
1284
- }
1285
- }
1286
- if (latest > lastChangeRef.current) {
1287
- lastChangeRef.current = latest;
1288
- if (!changed) return;
1289
- if (eventRefreshTimerRef.current) clearTimeout(eventRefreshTimerRef.current);
1290
- eventRefreshTimerRef.current = setTimeout(() => {
1291
- eventRefreshTimerRef.current = null;
1292
- if (acceptsEventReadsRef.current) void refresh();
1293
- }, 150);
1294
- }
1295
- }, [enabled, active, acceptsEventReads, events, refresh]);
1296
- useEffect5(
1297
- () => () => {
1298
- if (eventRefreshTimerRef.current) clearTimeout(eventRefreshTimerRef.current);
1299
- },
1300
- []
1301
- );
1302
- const identityMatches = enabled && stateIdentity === identityKey;
1303
- const visibleRepoRoots = identityMatches ? repoRoots : [];
1304
- return {
1305
- diff: identityMatches ? diff : [],
1306
- branch: identityMatches ? branch : null,
1307
- isRepo: identityMatches && isRepo,
1308
- ahead: identityMatches ? ahead : 0,
1309
- behind: identityMatches ? behind : 0,
1310
- repoCount: visibleRepoRoots.length,
1311
- repoRoots: visibleRepoRoots,
1312
- refresh,
1313
- source: identityMatches ? source : null,
1314
- capturedAt: identityMatches && source === "capture" ? capture?.capturedAt ?? null : null,
1315
- loading: identityMatches && loading,
1316
- error: identityMatches ? error : null
1317
- };
1318
- }
1319
-
1320
- // src/hooks/use-workspace-capture.ts
1321
- import { useCallback as useCallback8, useEffect as useEffect6, useRef as useRef6, useState as useState6 } from "react";
1322
- import { isRecord } from "@opengeni/contracts/values";
1323
- var REVISION_CAPTURED = "workspace.revision.captured";
1324
- var REVISION_DEGRADED = "workspace.revision.degraded";
1325
- var MANIFEST_FETCH_TIMEOUT_MS = 15e3;
1326
- var CAPTURE_STATS_NUMBER_FIELDS = [
1327
- "repoCount",
1328
- "fileCount",
1329
- "additions",
1330
- "deletions",
1331
- "totalBytes",
1332
- "tooLargeCount",
1333
- "binaryCount",
1334
- "treeEntryCount",
1335
- "durationMs"
1336
- ];
1337
- function captureManifestForResponse(value, response) {
1338
- if (!isRecord(value) || value.version !== 1 || !Number.isSafeInteger(value.revision) || typeof value.capturedAt !== "string" || !(value.turnId === null || typeof value.turnId === "string") || !Number.isSafeInteger(value.leaseEpoch) || !isRecord(value.treeIndex) || typeof value.treeTruncated !== "boolean" || !Array.isArray(value.repos) || !Array.isArray(value.files) || !isRecord(value.stats)) {
1339
- throw new Error("Workspace capture manifest failed validation.");
1340
- }
1341
- if (value.revision !== response.revision || value.capturedAt !== response.capturedAt || value.turnId !== response.turnId || value.leaseEpoch !== response.leaseEpoch) {
1342
- throw new Error("Workspace capture manifest identity did not match its response.");
1343
- }
1344
- for (const field of CAPTURE_STATS_NUMBER_FIELDS) {
1345
- if (!Number.isSafeInteger(value.stats[field]) || value.stats[field] !== response.stats[field]) {
1346
- throw new Error("Workspace capture manifest statistics did not match its response.");
1347
- }
1348
- }
1349
- if (typeof value.stats.treeTruncated !== "boolean" || value.stats.treeTruncated !== response.stats.treeTruncated || (value.stats.fingerprint ?? null) !== (response.stats.fingerprint ?? null) || value.repos.length !== response.stats.repoCount || value.files.length !== response.stats.fileCount || value.treeTruncated !== response.stats.treeTruncated) {
1350
- throw new Error("Workspace capture manifest statistics did not match its response.");
1351
- }
1352
- return value;
1353
- }
1354
- function useWorkspaceCapture(sessionId, options = {}) {
1355
- const { client, workspaceId } = useOpenGeni(options);
1356
- const enabled = (options.enabled ?? true) && Boolean(sessionId);
1357
- const identityKey = `${workspaceId}\0${sessionId ?? ""}`;
1358
- const [capture, setCapture] = useState6(null);
1359
- const [available, setAvailable] = useState6(false);
1360
- const [degradedReason, setDegradedReason] = useState6(null);
1361
- const [fileCount, setFileCount] = useState6(null);
1362
- const [loading, setLoading] = useState6(false);
1363
- const [error, setError] = useState6(null);
1364
- const [announcedRevision, setAnnouncedRevision] = useState6(null);
1365
- const [stateIdentity, setStateIdentity] = useState6(identityKey);
1366
- const generationRef = useRef6(0);
1367
- const requestAbortRef = useRef6(null);
1368
- const lastSeqRef = useRef6(0);
1369
- const refresh = useCallback8(async () => {
1370
- if (!sessionId) return;
1371
- requestAbortRef.current?.abort();
1372
- const requestAbort = new AbortController();
1373
- requestAbortRef.current = requestAbort;
1374
- const generation = generationRef.current += 1;
1375
- setStateIdentity(identityKey);
1376
- setLoading(true);
1377
- setError(null);
1378
- try {
1379
- for (let attempt = 0; attempt < 2; attempt += 1) {
1380
- const res = await client.getWorkspaceCapture(
1381
- workspaceId,
1382
- sessionId,
1383
- { signal: requestAbort.signal }
1384
- );
1385
- if (generationRef.current !== generation) return;
1386
- if (!res.available) {
1387
- setCapture(null);
1388
- setAvailable(false);
1389
- setFileCount(0);
1390
- setDegradedReason(res.degradedReason ?? null);
1391
- return;
1392
- }
1393
- setDegradedReason(null);
1394
- setFileCount(res.stats.fileCount);
1395
- let manifestValue = res.manifest;
1396
- if (!manifestValue && res.manifestUrl) {
1397
- const response = await fetch(res.manifestUrl.url, {
1398
- signal: AbortSignal.any([
1399
- requestAbort.signal,
1400
- AbortSignal.timeout(MANIFEST_FETCH_TIMEOUT_MS)
1401
- ]),
1402
- credentials: "omit",
1403
- cache: "no-store",
1404
- referrerPolicy: "no-referrer"
1405
- }).catch(() => null);
1406
- if (generationRef.current !== generation) return;
1407
- if (!response?.ok) {
1408
- if (attempt === 0 && (response === null || response.status === 401 || response.status === 403)) {
1409
- continue;
1410
- }
1411
- throw new Error(
1412
- `Workspace capture manifest download failed${response ? ` (${response.status})` : ""}.`
1413
- );
1414
- }
1415
- try {
1416
- manifestValue = await response.json();
1417
- } catch {
1418
- throw new Error("Workspace capture manifest was not valid JSON.");
1419
- }
1420
- if (generationRef.current !== generation) return;
1421
- }
1422
- if (!manifestValue) {
1423
- throw new Error("Workspace capture response did not include a manifest.");
1424
- }
1425
- const manifest = captureManifestForResponse(manifestValue, res);
1426
- setCapture(manifest);
1427
- setAvailable(true);
1428
- setAnnouncedRevision(
1429
- (prev) => prev === null || manifest.revision > prev ? manifest.revision : prev
1430
- );
1431
- return;
1432
- }
1433
- throw new Error("Workspace capture manifest download failed after refreshing its URL.");
1434
- } catch (cause) {
1435
- if (generationRef.current !== generation) return;
1436
- setError(cause instanceof Error ? cause : new Error(String(cause)));
1437
- } finally {
1438
- if (generationRef.current === generation) setLoading(false);
1439
- if (requestAbortRef.current === requestAbort) requestAbortRef.current = null;
1440
- }
1441
- }, [client, workspaceId, sessionId, identityKey]);
1442
- useEffect6(() => {
1443
- requestAbortRef.current?.abort();
1444
- requestAbortRef.current = null;
1445
- generationRef.current += 1;
1446
- lastSeqRef.current = 0;
1447
- setCapture(null);
1448
- setAvailable(false);
1449
- setDegradedReason(null);
1450
- setFileCount(null);
1451
- setAnnouncedRevision(null);
1452
- setError(null);
1453
- if (!enabled) {
1454
- setLoading(false);
1455
- return;
1456
- }
1457
- void refresh();
1458
- return () => {
1459
- requestAbortRef.current?.abort();
1460
- requestAbortRef.current = null;
1461
- generationRef.current += 1;
1462
- };
1463
- }, [enabled, refresh]);
1464
- const events = options.events;
1465
- useEffect6(() => {
1466
- if (!enabled || !events) return;
1467
- let newest = null;
1468
- for (const event of events) {
1469
- if (event.sequence <= lastSeqRef.current) continue;
1470
- if (event.type === REVISION_CAPTURED) {
1471
- const payload = event.payload;
1472
- if (payload && typeof payload === "object" && typeof payload.revision === "number") {
1473
- newest = newest === null ? payload.revision : Math.max(newest, payload.revision);
1474
- }
1475
- } else if (event.type === REVISION_DEGRADED) {
1476
- const payload = event.payload;
1477
- if (payload && typeof payload === "object" && typeof payload.revision === "number") {
1478
- newest = newest === null ? payload.revision : Math.max(newest, payload.revision);
1479
- }
1480
- }
1481
- }
1482
- for (const event of events)
1483
- if (event.sequence > lastSeqRef.current) lastSeqRef.current = event.sequence;
1484
- if (newest === null) return;
1485
- setAnnouncedRevision((prev) => prev === null || newest > prev ? newest : prev);
1486
- }, [enabled, events]);
1487
- const identityMatches = enabled && stateIdentity === identityKey;
1488
- const visibleCapture = identityMatches ? capture : null;
1489
- const visibleAnnouncedRevision = identityMatches ? announcedRevision : null;
1490
- const loadedRevision = visibleCapture?.revision ?? null;
1491
- useEffect6(() => {
1492
- if (!enabled) return;
1493
- if (visibleAnnouncedRevision === null) return;
1494
- if (loadedRevision !== null && visibleAnnouncedRevision <= loadedRevision) return;
1495
- if (requestAbortRef.current) return;
1496
- void refresh();
1497
- }, [enabled, visibleAnnouncedRevision, loadedRevision, refresh]);
1498
- const isStale = loadedRevision !== null && visibleAnnouncedRevision !== null && visibleAnnouncedRevision > loadedRevision;
1499
- return {
1500
- capture: visibleCapture,
1501
- revision: loadedRevision,
1502
- capturedAt: visibleCapture?.capturedAt ?? null,
1503
- available: identityMatches && available,
1504
- degradedReason: identityMatches ? degradedReason : null,
1505
- fileCount: identityMatches ? fileCount : null,
1506
- isStale,
1507
- loading: identityMatches && loading,
1508
- error: identityMatches ? error : null,
1509
- refresh
1510
- };
1511
- }
1512
-
1513
- // src/hooks/use-workspace-edit.ts
1514
- import { useCallback as useCallback9, useEffect as useEffect7, useMemo as useMemo4, useRef as useRef7, useState as useState7 } from "react";
1515
- function isLive(liveness) {
1516
- return sandboxAcceptsLiveIo(liveness);
1517
- }
1518
- function useWorkspaceEdit(sessionId, options = {}) {
1519
- const { client, workspaceId } = useOpenGeni(options);
1520
- const path = options.path ?? null;
1521
- const baseContent = options.baseContent ?? null;
1522
- const routeEpoch = options.route?.epoch;
1523
- const routeRoot = options.route?.root;
1524
- const route = useMemo4(
1525
- () => routeEpoch !== void 0 && routeRoot !== void 0 ? { epoch: routeEpoch, root: routeRoot } : void 0,
1526
- [routeEpoch, routeRoot]
1527
- );
1528
- const live = isLive(options.liveness);
1529
- const offline = options.offline === true;
1530
- const identityKey = `${workspaceId}\0${sessionId ?? ""}\0${path ?? ""}\0${routeEpoch ?? ""}\0${routeRoot ?? ""}`;
1531
- const [buffer, setBuffer] = useState7(null);
1532
- const [wantsWarm, setWantsWarm] = useState7(false);
1533
- const [flush, setFlush] = useState7("idle");
1534
- const [conflict, setConflict] = useState7(null);
1535
- const [error, setError] = useState7(null);
1536
- const [stateIdentity, setStateIdentity] = useState7(identityKey);
1537
- const onWarmRequested = options.onWarmRequested;
1538
- const bufferRef = useRef7(null);
1539
- bufferRef.current = buffer;
1540
- const flushingRef = useRef7(false);
1541
- const identityGenerationRef = useRef7(0);
1542
- const flushAttemptRef = useRef7(0);
1543
- const readAbortRef = useRef7(null);
1544
- useEffect7(() => {
1545
- identityGenerationRef.current += 1;
1546
- flushAttemptRef.current += 1;
1547
- readAbortRef.current?.abort();
1548
- readAbortRef.current = null;
1549
- setStateIdentity(identityKey);
1550
- setBuffer(null);
1551
- setWantsWarm(false);
1552
- setFlush("idle");
1553
- setConflict(null);
1554
- setError(null);
1555
- flushingRef.current = false;
1556
- return () => {
1557
- identityGenerationRef.current += 1;
1558
- flushAttemptRef.current += 1;
1559
- readAbortRef.current?.abort();
1560
- readAbortRef.current = null;
1561
- };
1562
- }, [identityKey]);
1563
- const edit = useCallback9(
1564
- (content) => {
1565
- if (stateIdentity !== identityKey) return;
1566
- if (offline) return;
1567
- setBuffer((prev) => prev === content ? prev : content);
1568
- setFlush((prev) => prev === "flushing" ? prev : "idle");
1569
- setConflict(null);
1570
- if (!live) {
1571
- setWantsWarm((prev) => {
1572
- if (!prev) onWarmRequested?.();
1573
- return true;
1574
- });
1575
- }
1576
- },
1577
- [offline, live, onWarmRequested, stateIdentity, identityKey]
1578
- );
1579
- const doFlush = useCallback9(
1580
- async (force) => {
1581
- if (stateIdentity !== identityKey) return;
1582
- if (!sessionId || !path) return;
1583
- const content = bufferRef.current;
1584
- if (content === null) return;
1585
- if (flushingRef.current) return;
1586
- const identityGeneration = identityGenerationRef.current;
1587
- const flushAttempt = flushAttemptRef.current += 1;
1588
- flushingRef.current = true;
1589
- setFlush("flushing");
1590
- setError(null);
1591
- try {
1592
- if (!force) {
1593
- const readAbort = new AbortController();
1594
- readAbortRef.current?.abort();
1595
- readAbortRef.current = readAbort;
1596
- const liveRead = await client.fsRead(
1597
- workspaceId,
1598
- sessionId,
1599
- { path, ...route ? { route } : {} },
1600
- { signal: readAbort.signal }
1601
- );
1602
- if (readAbortRef.current === readAbort) readAbortRef.current = null;
1603
- if (identityGenerationRef.current !== identityGeneration) return;
1604
- const liveContent = liveRead.content;
1605
- if (baseContent !== null && liveContent !== baseContent) {
1606
- setConflict({ path, base: baseContent, live: liveContent });
1607
- setFlush("conflict");
1608
- return;
1609
- }
1610
- }
1611
- await client.fsWrite(workspaceId, sessionId, {
1612
- path,
1613
- content,
1614
- overwrite: true,
1615
- ...route ? { route } : {}
1616
- });
1617
- if (identityGenerationRef.current !== identityGeneration) return;
1618
- setConflict(null);
1619
- setFlush("flushed");
1620
- setWantsWarm(false);
1621
- } catch (cause) {
1622
- if (identityGenerationRef.current !== identityGeneration) return;
1623
- setError(cause instanceof Error ? cause : new Error(String(cause)));
1624
- setFlush("idle");
1625
- } finally {
1626
- if (flushAttemptRef.current === flushAttempt) {
1627
- flushingRef.current = false;
1628
- readAbortRef.current = null;
1629
- }
1630
- }
1631
- },
1632
- [client, workspaceId, sessionId, path, baseContent, route, stateIdentity, identityKey]
1633
- );
1634
- useEffect7(() => {
1635
- if (offline) return;
1636
- if (!live) return;
1637
- if (buffer === null) return;
1638
- if (flush === "flushed" || flush === "conflict" || flush === "flushing") return;
1639
- void doFlush(false);
1640
- }, [offline, live, buffer, flush, doFlush]);
1641
- const overwrite = useCallback9(async () => {
1642
- await doFlush(true);
1643
- }, [doFlush]);
1644
- const discard = useCallback9(() => {
1645
- setBuffer(null);
1646
- setWantsWarm(false);
1647
- setFlush("idle");
1648
- setConflict(null);
1649
- setError(null);
1650
- }, []);
1651
- let state;
1652
- if (offline) {
1653
- state = "readonly-offline";
1654
- } else if (flush === "flushing") {
1655
- state = "flushing";
1656
- } else if (flush === "flushed") {
1657
- state = "flushed";
1658
- } else if (flush === "conflict") {
1659
- state = "conflict";
1660
- } else if (buffer === null) {
1661
- state = "viewing-cold";
1662
- } else if (live) {
1663
- state = "flushing";
1664
- } else if (options.warming === true) {
1665
- state = "warming";
1666
- } else {
1667
- state = "buffering";
1668
- }
1669
- const identityMatches = stateIdentity === identityKey;
1670
- return {
1671
- state: identityMatches ? state : offline ? "readonly-offline" : "viewing-cold",
1672
- readOnly: offline,
1673
- buffer: identityMatches ? buffer : null,
1674
- wantsWarm: identityMatches && wantsWarm,
1675
- edit,
1676
- conflict: identityMatches ? conflict : null,
1677
- overwrite,
1678
- discard,
1679
- error: identityMatches ? error : null
1680
- };
1681
- }
1682
-
1683
- // src/hooks/use-machine-chip.ts
1684
- import { useMemo as useMemo5 } from "react";
1685
- function formatAsOf(t, capturedAt, now) {
1686
- const then = Date.parse(capturedAt);
1687
- if (Number.isNaN(then)) return "recently";
1688
- const seconds = Math.max(0, Math.round((now - then) / 1e3));
1689
- if (seconds < 45) return t("hooks.useMachineChip.justNow");
1690
- const minutes = Math.round(seconds / 60);
1691
- if (minutes < 60) return `${minutes}m ago`;
1692
- const hours = Math.round(minutes / 60);
1693
- if (hours < 24) return `${hours}h ago`;
1694
- const days = Math.round(hours / 24);
1695
- return `${days}d ago`;
1696
- }
1697
- function deriveMachineChip(t, input) {
1698
- const now = input.now ?? Date.now();
1699
- const asOf = input.capturedAt ?? null;
1700
- const managedRestingLabel = asOf ? t("hooks.useMachineChip.sleepingSavedAsof", { asOf: formatAsOf(t, asOf, now) }) : t("hooks.useMachineChip.sleeping");
1701
- const offlineLabel = t("hooks.useMachineChip.offline");
1702
- const selfhostedOnline = input.activeIsSelfhosted === true && input.activeMachineState != null && connectionStatusForState(input.activeMachineState) === "online";
1703
- if (sandboxAcceptsLiveIo(input.liveness) || selfhostedOnline) {
1704
- return { state: "live", label: t("hooks.useMachineChip.live"), asOf: null };
1705
- }
1706
- const selfhostedOffline = input.activeIsSelfhosted === true && input.activeMachineState === "offline";
1707
- if (input.capabilitiesState === "error") {
1708
- return {
1709
- state: "offline",
1710
- label: input.activeIsSelfhosted === true ? offlineLabel : managedRestingLabel,
1711
- asOf
1712
- };
1713
- }
1714
- const machineWarming = input.activeMachineState === "reconnecting" || input.activeMachineState === "enrolling";
1715
- if (!selfhostedOffline && (input.capabilitiesState === "negotiating" || input.wantsWarm === true || machineWarming)) {
1716
- return { state: "waking", label: t("hooks.useMachineChip.waking"), asOf };
1717
- }
1718
- return {
1719
- state: "offline",
1720
- label: input.activeIsSelfhosted === true ? offlineLabel : managedRestingLabel,
1721
- asOf
1722
- };
1723
- }
1724
- function useMachineChip(input) {
1725
- const t = useOpenGeniText();
1726
- const {
1727
- liveness,
1728
- capabilitiesState,
1729
- activeMachineState,
1730
- activeIsSelfhosted,
1731
- wantsWarm,
1732
- capturedAt,
1733
- now
1734
- } = input;
1735
- return useMemo5(
1736
- () => deriveMachineChip(t, {
1737
- liveness,
1738
- capabilitiesState,
1739
- activeMachineState,
1740
- activeIsSelfhosted,
1741
- wantsWarm,
1742
- capturedAt,
1743
- now
1744
- }),
1745
- // Depend on the primitive fields (not the object identity) so a caller passing
1746
- // a fresh object each render doesn't recompute needlessly.
1747
- [
1748
- liveness,
1749
- capabilitiesState,
1750
- activeMachineState,
1751
- activeIsSelfhosted,
1752
- wantsWarm,
1753
- capturedAt,
1754
- now,
1755
- t
1756
- ]
1757
- );
1758
- }
1759
-
1760
- // src/index.ts
1761
- import {
1762
- humanizeModelSlug,
1763
- isRawModelLabel,
1764
- modelDisplayName as modelDisplayName2,
1765
- modelSlug,
1766
- modelVendor
1767
- } from "@opengeni/sdk/model-display";
1768
- import { parseOpenGeniLink } from "@opengeni/sdk";
1769
-
1770
- // src/components/fleet-tile.tsx
1771
- import { deriveSessionDisplayTitle } from "@opengeni/sdk";
1772
- import { modelDisplayName } from "@opengeni/sdk/model-display";
1773
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
1774
- var SESSION_METADATA_TITLE_KEYS = ["title", "name"];
1775
- function sessionDisplayTitle(session) {
1776
- return deriveSessionDisplayTitle(session, { metadataKeys: SESSION_METADATA_TITLE_KEYS });
1777
- }
1778
- function FleetTile({ session, title, subtitle, onOpen, className }) {
1779
- const msg = useOpenGeniText();
1780
- const running = session.status === "running" || session.status === "queued";
1781
- const needsYou = session.status === "requires_action" && !sessionAdmissionBlocked(session);
1782
- return /* @__PURE__ */ jsxs2(
1783
- "button",
1784
- {
1785
- type: "button",
1786
- "data-status": session.status,
1787
- onClick: onOpen ? () => onOpen(session) : void 0,
1788
- disabled: !onOpen,
1789
- className: cn(
1790
- "og-root group relative flex w-full flex-col gap-2.5 overflow-hidden rounded-og-lg border border-og-border",
1791
- "bg-og-surface-1 p-4 text-left shadow-og-sm",
1792
- "transition-[border-color,background-color,box-shadow,transform] duration-200 ease-og-out",
1793
- onOpen && "hover:-translate-y-px hover:border-og-border-strong hover:bg-og-surface-2 hover:shadow-og-md",
1794
- "disabled:cursor-default",
1795
- className
1796
- ),
1797
- children: [
1798
- /* @__PURE__ */ jsx2(
1799
- "span",
1800
- {
1801
- "aria-hidden": true,
1802
- className: cn(
1803
- "absolute inset-y-0 left-0 w-0.5 transition-opacity duration-300",
1804
- running ? "bg-og-accent opacity-100" : needsYou ? "bg-og-status-waiting opacity-100" : "opacity-0"
1805
- )
1806
- }
1807
- ),
1808
- /* @__PURE__ */ jsxs2("span", { className: "flex w-full items-start justify-between gap-3", children: [
1809
- /* @__PURE__ */ jsx2("span", { className: "line-clamp-2 min-w-0 text-og-base font-medium leading-snug text-og-fg", children: title ?? sessionDisplayTitle(session) }),
1810
- /* @__PURE__ */ jsx2(SessionStatus, { status: sessionDisplayStatus(session), size: "sm", className: "mt-px" })
1811
- ] }),
1812
- subtitle ? /* @__PURE__ */ jsx2("span", { className: "line-clamp-1 text-og-sm text-og-fg-muted", children: subtitle }) : null,
1813
- /* @__PURE__ */ jsxs2("span", { className: "mt-auto flex w-full items-center gap-2 text-og-xs text-og-fg-subtle", children: [
1814
- /* @__PURE__ */ jsx2("span", { className: "font-og-mono", children: session.id.slice(0, 8) }),
1815
- /* @__PURE__ */ jsx2("span", { "aria-hidden": true, children: "\xB7" }),
1816
- /* @__PURE__ */ jsx2("span", { className: "truncate", children: modelDisplayName(session.model) }),
1817
- /* @__PURE__ */ jsx2("span", { className: "ml-auto shrink-0", title: session.updatedAt, children: formatRelativeTime(msg, session.updatedAt) })
1818
- ] })
1819
- ]
1820
- }
1821
- );
1822
- }
1823
-
1824
- // src/components/workbench-changes.tsx
1825
- import { ArrowUpRightIcon, FileWarningIcon, HistoryIcon } from "lucide-react";
1826
- import {
1827
- Component,
1828
- useCallback as useCallback11,
1829
- useEffect as useEffect9,
1830
- useId,
1831
- useLayoutEffect,
1832
- useMemo as useMemo7,
1833
- useRef as useRef9,
1834
- useState as useState9
1835
- } from "react";
1836
- import { VList } from "virtua";
1837
-
1838
- // src/hooks/use-windowed-sections.ts
1839
- import { useCallback as useCallback10, useEffect as useEffect8, useMemo as useMemo6, useRef as useRef8, useState as useState8 } from "react";
1840
- function computeWindowRange(heights, scrollTop, viewport, overscan) {
1841
- const n = heights.length;
1842
- if (n === 0) return { start: 0, end: 0 };
1843
- const top = Math.max(scrollTop, 0);
1844
- const bottom = top + Math.max(viewport, 0);
1845
- let firstVisible = -1;
1846
- let lastVisible = -1;
1847
- let acc = 0;
1848
- let anchor = 0;
1849
- for (let i = 0; i < n; i++) {
1850
- const secTop = acc;
1851
- const secBottom = secTop + Math.max(heights[i] ?? 0, 0);
1852
- if (secTop <= top) anchor = i;
1853
- if (secBottom > top && secTop < bottom) {
1854
- if (firstVisible === -1) firstVisible = i;
1855
- lastVisible = i;
1856
- }
1857
- acc = secBottom;
1858
- }
1859
- if (firstVisible === -1) {
1860
- firstVisible = anchor;
1861
- lastVisible = anchor;
1862
- }
1863
- return {
1864
- start: Math.max(0, firstVisible - overscan),
1865
- end: Math.min(n, lastVisible + 1 + overscan)
1866
- };
1867
- }
1868
- function useWindowedSections(opts) {
1869
- const { count, estimateHeight, overscan = 3 } = opts;
1870
- const scrollRef = useRef8(null);
1871
- const [heights, setHeights] = useState8(
1872
- () => Array.from({ length: count }, (_, i) => estimateHeight(i))
1873
- );
1874
- useEffect8(() => {
1875
- setHeights((prev) => {
1876
- const next = Array.from({ length: count }, (_, i) => estimateHeight(i));
1877
- return prev.length === next.length && prev.every((height, index) => height === next[index]) ? prev : next;
1878
- });
1879
- }, [count, estimateHeight]);
1880
- const heightsRef = useRef8(heights);
1881
- heightsRef.current = heights;
1882
- const [range, setRange] = useState8(() => ({
1883
- start: 0,
1884
- end: Math.min(count, overscan + 1)
1885
- }));
1886
- const recompute = useCallback10(() => {
1887
- const el = scrollRef.current;
1888
- if (!el) return;
1889
- const next = computeWindowRange(heightsRef.current, el.scrollTop, el.clientHeight, overscan);
1890
- setRange((prev) => prev.start === next.start && prev.end === next.end ? prev : next);
1891
- }, [overscan]);
1892
- useEffect8(() => {
1893
- const el = scrollRef.current;
1894
- if (!el) return;
1895
- let raf = 0;
1896
- const onScroll = () => {
1897
- if (raf) return;
1898
- raf = typeof requestAnimationFrame === "function" ? requestAnimationFrame(() => {
1899
- raf = 0;
1900
- recompute();
1901
- }) : (recompute(), 0);
1902
- };
1903
- el.addEventListener("scroll", onScroll, { passive: true });
1904
- const ro = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => recompute()) : null;
1905
- ro?.observe(el);
1906
- recompute();
1907
- return () => {
1908
- el.removeEventListener("scroll", onScroll);
1909
- ro?.disconnect();
1910
- if (raf && typeof cancelAnimationFrame === "function") cancelAnimationFrame(raf);
1911
- };
1912
- }, [recompute, count]);
1913
- const measure = useCallback10((index, height) => {
1914
- if (height <= 0) return;
1915
- setHeights((prev) => {
1916
- if (Math.abs((prev[index] ?? 0) - height) < 1) return prev;
1917
- const next = prev.slice();
1918
- next[index] = height;
1919
- return next;
1920
- });
1921
- }, []);
1922
- const offsets = useMemo6(() => {
1923
- const out = new Array(count + 1);
1924
- out[0] = 0;
1925
- for (let i = 0; i < count; i++) out[i + 1] = (out[i] ?? 0) + Math.max(heights[i] ?? 0, 0);
1926
- return out;
1927
- }, [heights, count]);
1928
- useEffect8(() => {
1929
- recompute();
1930
- }, [offsets, recompute]);
1931
- const scrollToIndex = useCallback10(
1932
- (index) => {
1933
- const el = scrollRef.current;
1934
- if (!el) return;
1935
- const clamped = Math.max(0, Math.min(count - 1, index));
1936
- el.scrollTop = offsets[clamped] ?? 0;
1937
- },
1938
- [offsets, count]
1939
- );
1940
- return {
1941
- scrollRef,
1942
- range,
1943
- offsets,
1944
- totalHeight: offsets[count] ?? 0,
1945
- measure,
1946
- scrollToIndex
1947
- };
1948
- }
1949
-
1950
- // src/components/workbench-changes.tsx
1951
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
1952
- var GROUP_THRESHOLD = 20;
1953
- var OVERSCAN = 2;
1954
- var HEADER_PX = 30;
1955
- var LINE_PX = 18;
1956
- var GUARD_BODY_PX = 52;
1957
- var COMPACT_SURFACE_PX = 560;
1958
- var useChangesLayoutEffect = typeof window === "undefined" ? useEffect9 : useLayoutEffect;
1959
- var STATUS_TINT = {
1960
- added: "text-og-status-idle",
1961
- modified: "text-og-status-running",
1962
- deleted: "text-og-status-failed",
1963
- renamed: "text-og-accent",
1964
- copied: "text-og-accent",
1965
- untracked: "text-og-fg-subtle",
1966
- ignored: "text-og-fg-subtle",
1967
- conflicted: "text-og-status-failed",
1968
- typechange: "text-og-status-running"
1969
- };
1970
- var STATUS_LETTER = {
1971
- added: "A",
1972
- modified: "M",
1973
- deleted: "D",
1974
- renamed: "R",
1975
- copied: "C",
1976
- untracked: "U",
1977
- ignored: "I",
1978
- conflicted: "!",
1979
- typechange: "T"
1980
- };
1981
- function compactFileLabel(file) {
1982
- const slash = file.path.lastIndexOf("/");
1983
- const basename = slash >= 0 ? file.path.slice(slash + 1) : file.path;
1984
- const parent = slash >= 0 ? file.path.slice(0, slash + 1) : "";
1985
- return `${STATUS_LETTER[file.status]} \xB7 ${basename}${parent ? ` \u2014 ${parent}` : ""}`;
1986
- }
1987
- var ChangesRailVList = class extends Component {
1988
- state = {
1989
- renderedRowCount: this.props.rowCount,
1990
- resetVersion: 0
1991
- };
1992
- host = null;
1993
- listHandle = null;
1994
- pendingFocusedPath = null;
1995
- restoreFrame = null;
1996
- static getDerivedStateFromProps(props, state) {
1997
- if (props.rowCount === state.renderedRowCount) return null;
1998
- return {
1999
- renderedRowCount: props.rowCount,
2000
- resetVersion: props.rowCount < state.renderedRowCount ? state.resetVersion + 1 : state.resetVersion
2001
- };
2002
- }
2003
- getSnapshotBeforeUpdate(_previousProps, previousState) {
2004
- if (previousState.resetVersion === this.state.resetVersion) return null;
2005
- const scroller = this.host?.firstElementChild;
2006
- if (!(scroller instanceof HTMLElement)) return null;
2007
- const active = document.activeElement;
2008
- const focusedRow = active instanceof HTMLElement && scroller.contains(active) ? active.closest("[data-rail-file-path]") : null;
2009
- return {
2010
- focusedPath: focusedRow?.dataset.railFilePath ?? this.pendingFocusedPath,
2011
- scrollOffset: scroller.scrollTop
2012
- };
2013
- }
2014
- componentDidUpdate(_previousProps, _previousState, snapshot) {
2015
- if (!snapshot || !this.listHandle) return;
2016
- this.cancelRestoreFrame();
2017
- const maxOffset = Math.max(0, this.listHandle.scrollSize - this.listHandle.viewportSize);
2018
- this.listHandle.scrollTo(Math.min(Math.max(snapshot.scrollOffset, 0), maxOffset));
2019
- const focusedPath = snapshot.focusedPath;
2020
- if (!focusedPath) return;
2021
- this.pendingFocusedPath = focusedPath;
2022
- this.continueFocusRestore();
2023
- }
2024
- componentWillUnmount() {
2025
- this.cancelRestoreFrame();
2026
- this.pendingFocusedPath = null;
2027
- }
2028
- cancelRestoreFrame() {
2029
- if (this.restoreFrame === null) return;
2030
- if (typeof cancelAnimationFrame === "function") cancelAnimationFrame(this.restoreFrame);
2031
- this.restoreFrame = null;
2032
- }
2033
- continueFocusRestore = () => {
2034
- const path = this.pendingFocusedPath;
2035
- if (!path) return;
2036
- if (this.restoreFocusedPath(path)) {
2037
- this.pendingFocusedPath = null;
2038
- return;
2039
- }
2040
- if (this.restoreFrame === null && typeof requestAnimationFrame === "function") {
2041
- this.restoreFrame = requestAnimationFrame(() => {
2042
- this.restoreFrame = null;
2043
- this.continueFocusRestore();
2044
- });
2045
- }
2046
- };
2047
- restoreFocusedPath(path) {
2048
- const host = this.host;
2049
- if (!host) return true;
2050
- const active = document.activeElement;
2051
- if (active instanceof HTMLElement && active.isConnected && active !== document.body) {
2052
- return true;
2053
- }
2054
- if (!this.props.files.some((file) => file.path === path)) return true;
2055
- const row = Array.from(host.querySelectorAll("[data-rail-file-path]")).find(
2056
- (candidate) => candidate.dataset.railFilePath === path
2057
- );
2058
- if (!row) return false;
2059
- row.focus({ preventScroll: true });
2060
- return true;
2061
- }
2062
- setHost = (host) => {
2063
- this.host = host;
2064
- };
2065
- setListHandle = (handle) => {
2066
- this.listHandle = handle;
2067
- };
2068
- render() {
2069
- return /* @__PURE__ */ jsx3("div", { ref: this.setHost, "data-opengeni-changes-rail": true, className: this.props.className, children: /* @__PURE__ */ jsx3(
2070
- VList,
2071
- {
2072
- ref: this.setListHandle,
2073
- className: "h-full",
2074
- itemSize: this.props.coarsePointer ? 44 : 28,
2075
- ssrCount: Math.min(30, this.props.rowCount),
2076
- children: this.props.children
2077
- },
2078
- this.state.resetVersion
2079
- ) });
2080
- }
2081
- };
2082
- function buildRail(t, files) {
2083
- const roots = new Set(
2084
- files.flatMap((file) => file.repoRoot === void 0 ? [] : [file.repoRoot])
2085
- );
2086
- const groupByRepo = roots.size > 1;
2087
- if (!groupByRepo && files.length <= GROUP_THRESHOLD) {
2088
- return {
2089
- orderedFiles: files,
2090
- rows: files.map((file, index) => ({ kind: "file", file, index })),
2091
- grouped: false
2092
- };
2093
- }
2094
- const groups = /* @__PURE__ */ new Map();
2095
- for (const file of files) {
2096
- const slash = file.path.indexOf("/");
2097
- const key = groupByRepo ? file.repoRoot || t("workbenchChanges.workspace") : slash > 0 ? file.path.slice(0, slash) : t("workbenchChanges.root");
2098
- const bucket = groups.get(key);
2099
- if (bucket) bucket.push(file);
2100
- else groups.set(key, [file]);
2101
- }
2102
- const labels = [...groups.keys()].sort((a, b) => a.localeCompare(b));
2103
- const orderedFiles = [];
2104
- const rows = [];
2105
- for (const label of labels) {
2106
- const bucket = (groups.get(label) ?? []).slice().sort((a, b) => a.path.localeCompare(b.path));
2107
- rows.push({ kind: "group", label, count: bucket.length });
2108
- for (const file of bucket) {
2109
- rows.push({ kind: "file", file, index: orderedFiles.length });
2110
- orderedFiles.push(file);
2111
- }
2112
- }
2113
- return { orderedFiles, rows, grouped: true };
2114
- }
2115
- function isGuarded(file) {
2116
- return file.isBinary || file.truncated;
2117
- }
2118
- function estimateSectionHeight(file) {
2119
- if (isGuarded(file)) return HEADER_PX + GUARD_BODY_PX;
2120
- let lines = 0;
2121
- for (const hunk of file.hunks) lines += hunk.lines.length + 1;
2122
- return HEADER_PX + Math.max(lines, 1) * LINE_PX + 8;
2123
- }
2124
- function WorkbenchChanges({
2125
- diff,
2126
- source,
2127
- capturedAt,
2128
- captureRevision,
2129
- themeType,
2130
- onOpenFile,
2131
- className
2132
- }) {
2133
- const t = useOpenGeniText();
2134
- const rootRef = useRef9(null);
2135
- const [compact, setCompact] = useState9(false);
2136
- const [coarsePointer, setCoarsePointer] = useState9(false);
2137
- const resolvedTheme = useThemeType(themeType);
2138
- const [layout, setLayout] = useState9("unified");
2139
- const [activePath, setActivePath] = useState9(null);
2140
- const pickerId = useId();
2141
- const unicodeFontPaths = useMemo7(
2142
- () => diff.flatMap((file) => file.oldPath ? [file.path, file.oldPath] : [file.path]),
2143
- [diff]
2144
- );
2145
- useUnicodeFallbackFonts(unicodeFontPaths);
2146
- const { orderedFiles, rows, grouped } = useMemo7(() => buildRail(t, diff), [diff, t]);
2147
- const selectedIndex = orderedFiles.findIndex((file) => file.path === activePath);
2148
- const activeIndex = selectedIndex >= 0 ? selectedIndex : 0;
2149
- useChangesLayoutEffect(() => {
2150
- const root = rootRef.current;
2151
- if (!root || typeof ResizeObserver === "undefined") return;
2152
- const update = (width) => {
2153
- if (width > 0) setCompact(width < COMPACT_SURFACE_PX);
2154
- };
2155
- update(root.getBoundingClientRect().width);
2156
- const observer = new ResizeObserver((entries) => {
2157
- update(entries[0]?.contentRect.width ?? root.getBoundingClientRect().width);
2158
- });
2159
- observer.observe(root);
2160
- return () => observer.disconnect();
2161
- }, []);
2162
- useChangesLayoutEffect(() => {
2163
- if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
2164
- const query = window.matchMedia("(pointer: coarse)");
2165
- const update = () => setCoarsePointer(query.matches);
2166
- update();
2167
- if (typeof query.addEventListener === "function") {
2168
- query.addEventListener("change", update);
2169
- return () => query.removeEventListener("change", update);
2170
- }
2171
- if (typeof query.addListener === "function") {
2172
- query.addListener(update);
2173
- return () => query.removeListener(update);
2174
- }
2175
- }, []);
2176
- const additions = useMemo7(() => diff.reduce((sum, f) => sum + f.additions, 0), [diff]);
2177
- const deletions = useMemo7(() => diff.reduce((sum, f) => sum + f.deletions, 0), [diff]);
2178
- const estimateHeight = useCallback11(
2179
- (index) => {
2180
- const file = orderedFiles[index];
2181
- return file ? estimateSectionHeight(file) : HEADER_PX + LINE_PX;
2182
- },
2183
- [orderedFiles]
2184
- );
2185
- const windowed = useWindowedSections({
2186
- count: orderedFiles.length,
2187
- estimateHeight,
2188
- overscan: OVERSCAN
2189
- });
2190
- const jumpTo = useCallback11(
2191
- (index) => {
2192
- setActivePath(orderedFiles[index]?.path ?? null);
2193
- windowed.scrollToIndex(index);
2194
- },
2195
- [orderedFiles, windowed]
2196
- );
2197
- const onPaneScroll = useCallback11(() => {
2198
- const el = windowed.scrollRef.current;
2199
- if (!el) {
2200
- return;
2201
- }
2202
- const top = el.scrollTop;
2203
- const offsets = windowed.offsets;
2204
- let idx = 0;
2205
- for (let i = 0; i < orderedFiles.length; i++) {
2206
- if ((offsets[i] ?? 0) <= top + 4) idx = i;
2207
- else break;
2208
- }
2209
- const nextPath = orderedFiles[idx]?.path ?? null;
2210
- setActivePath((previous) => previous === nextPath ? previous : nextPath);
2211
- }, [windowed, orderedFiles]);
2212
- useEffect9(() => {
2213
- const el = windowed.scrollRef.current;
2214
- if (!el) return;
2215
- el.addEventListener("scroll", onPaneScroll, { passive: true });
2216
- return () => el.removeEventListener("scroll", onPaneScroll);
2217
- }, [windowed.scrollRef, onPaneScroll]);
2218
- const sourceBadge = describeSource(t, source, capturedAt, captureRevision ?? null);
2219
- const activeFile = orderedFiles[activeIndex] ?? orderedFiles[0];
2220
- return /* @__PURE__ */ jsxs3(
2221
- "div",
2222
- {
2223
- ref: rootRef,
2224
- className: cn("flex h-full min-h-0 min-w-0 flex-col", className),
2225
- "data-workbench-changes-layout": compact ? "compact" : "rail",
2226
- children: [
2227
- /* @__PURE__ */ jsxs3(
2228
- "div",
2229
- {
2230
- className: cn(
2231
- "flex shrink-0 items-center justify-between gap-2 border-b border-og-border px-3 py-1.5",
2232
- compact && source === "capture" && "flex-col items-stretch gap-1.5 py-2"
2233
- ),
2234
- children: [
2235
- /* @__PURE__ */ jsxs3(
2236
- "span",
2237
- {
2238
- role: "status",
2239
- "aria-atomic": "true",
2240
- "aria-live": "polite",
2241
- "data-contrast-audited": true,
2242
- className: "min-w-0 text-og-xs text-og-fg-muted",
2243
- children: [
2244
- t("workbenchChanges.filesChanged", { count: diff.length }),
2245
- /* @__PURE__ */ jsxs3("span", { "data-contrast-audited": true, className: "ml-2 text-og-status-idle", children: [
2246
- "+",
2247
- additions
2248
- ] }),
2249
- /* @__PURE__ */ jsxs3("span", { "data-contrast-audited": true, className: "ml-1 text-og-status-failed", children: [
2250
- "\u2212",
2251
- deletions
2252
- ] })
2253
- ]
2254
- }
2255
- ),
2256
- /* @__PURE__ */ jsxs3(
2257
- "div",
2258
- {
2259
- className: cn(
2260
- "flex shrink-0 items-center gap-2",
2261
- compact && source === "capture" && "self-start"
2262
- ),
2263
- children: [
2264
- compact ? null : /* @__PURE__ */ jsx3(LayoutToggle, { layout, onChange: setLayout }),
2265
- /* @__PURE__ */ jsx3(SourceBadge, { source, capturedAt, label: sourceBadge })
2266
- ]
2267
- }
2268
- )
2269
- ]
2270
- }
2271
- ),
2272
- compact ? /* @__PURE__ */ jsxs3("div", { className: "flex min-h-0 flex-1 flex-col", children: [
2273
- /* @__PURE__ */ jsxs3("div", { className: "shrink-0 border-b border-og-border bg-og-surface-1 p-2", children: [
2274
- /* @__PURE__ */ jsx3("label", { className: "sr-only", htmlFor: pickerId, children: t("workbenchChanges.changedFile") }),
2275
- /* @__PURE__ */ jsx3(
2276
- "select",
2277
- {
2278
- id: pickerId,
2279
- "aria-label": t("workbenchChanges.changedFile"),
2280
- value: activeIndex,
2281
- onChange: (event) => {
2282
- const index = Number(event.currentTarget.value);
2283
- setActivePath(orderedFiles[index]?.path ?? null);
2284
- },
2285
- title: activeFile?.path,
2286
- "data-compact-file-picker": true,
2287
- className: "h-11 w-full rounded-og-md border border-og-border bg-og-bg px-3 font-og-mono text-og-sm text-og-fg outline-hidden transition-colors focus:border-og-accent focus:ring-2 focus:ring-og-accent-soft",
2288
- children: orderedFiles.map((file, index) => /* @__PURE__ */ jsx3("option", { value: index, children: compactFileLabel(file) }, file.path))
2289
- }
2290
- )
2291
- ] }),
2292
- /* @__PURE__ */ jsx3(
2293
- "div",
2294
- {
2295
- "aria-label": t("workbenchChanges.changedFileDiff"),
2296
- className: "min-h-0 min-w-0 flex-1 overflow-auto outline-hidden focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-og-accent",
2297
- "data-opengeni-changes-pane": true,
2298
- role: "region",
2299
- tabIndex: 0,
2300
- children: activeFile ? /* @__PURE__ */ jsx3(
2301
- DiffSection,
2302
- {
2303
- file: activeFile,
2304
- layout: "unified",
2305
- themeType: resolvedTheme,
2306
- ...onOpenFile ? { onOpenFile } : {}
2307
- }
2308
- ) : null
2309
- }
2310
- )
2311
- ] }) : /* @__PURE__ */ jsxs3("div", { className: "flex min-h-0 flex-1", children: [
2312
- /* @__PURE__ */ jsx3(
2313
- ChangesRailVList,
2314
- {
2315
- rowCount: rows.length,
2316
- coarsePointer,
2317
- files: orderedFiles,
2318
- className: "w-[clamp(12rem,28%,15rem)] shrink-0 border-r border-og-border bg-og-surface-1/35",
2319
- children: rows.map(
2320
- (row) => row.kind === "group" ? /* @__PURE__ */ jsxs3(
2321
- "div",
2322
- {
2323
- "data-rail-group": true,
2324
- className: "flex items-center gap-1.5 px-2 pb-0.5 pt-2 text-og-xs font-medium uppercase tracking-wide text-og-fg-subtle",
2325
- children: [
2326
- /* @__PURE__ */ jsx3("span", { className: "min-w-0 truncate", children: row.label }),
2327
- /* @__PURE__ */ jsx3("span", { className: "shrink-0", children: row.count })
2328
- ]
2329
- },
2330
- `g:${row.label}`
2331
- ) : /* @__PURE__ */ jsx3(
2332
- RailFileRow,
2333
- {
2334
- file: row.file,
2335
- grouped,
2336
- active: row.index === activeIndex,
2337
- onClick: () => jumpTo(row.index)
2338
- },
2339
- row.file.path
2340
- )
2341
- )
2342
- }
2343
- ),
2344
- /* @__PURE__ */ jsx3(
2345
- "div",
2346
- {
2347
- ref: windowed.scrollRef,
2348
- "aria-label": t("workbenchChanges.changedFilesDiff"),
2349
- className: "min-h-0 min-w-0 flex-1 overflow-auto outline-hidden focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-og-accent",
2350
- "data-opengeni-changes-pane": true,
2351
- role: "region",
2352
- tabIndex: 0,
2353
- children: /* @__PURE__ */ jsx3("div", { style: { position: "relative", height: windowed.totalHeight }, children: orderedFiles.map((file, index) => {
2354
- if (index < windowed.range.start || index >= windowed.range.end) return null;
2355
- return /* @__PURE__ */ jsx3(
2356
- MeasuredSection,
2357
- {
2358
- index,
2359
- top: windowed.offsets[index] ?? 0,
2360
- onMeasure: windowed.measure,
2361
- children: /* @__PURE__ */ jsx3(
2362
- DiffSection,
2363
- {
2364
- file,
2365
- layout,
2366
- themeType: resolvedTheme,
2367
- ...onOpenFile ? { onOpenFile } : {}
2368
- }
2369
- )
2370
- },
2371
- file.path
2372
- );
2373
- }) })
2374
- }
2375
- )
2376
- ] })
2377
- ]
2378
- }
2379
- );
2380
- }
2381
- function SourceBadge({
2382
- source,
2383
- capturedAt,
2384
- label
2385
- }) {
2386
- const t = useOpenGeniText();
2387
- if (source === "capture" && capturedAt) {
2388
- return /* @__PURE__ */ jsxs3(
2389
- "span",
2390
- {
2391
- className: "inline-flex items-center gap-1 rounded-og-xs border border-og-border px-1.5 py-px text-og-xs text-og-fg-muted",
2392
- title: new Date(capturedAt).toLocaleString(t.locale),
2393
- children: [
2394
- /* @__PURE__ */ jsx3(HistoryIcon, { className: "size-3 shrink-0 text-og-status-running", "aria-hidden": true }),
2395
- label
2396
- ]
2397
- }
2398
- );
2399
- }
2400
- return /* @__PURE__ */ jsx3("span", { className: "rounded-og-xs bg-og-surface-2 px-1.5 py-px text-og-xs text-og-fg-subtle", children: label });
2401
- }
2402
- function describeSource(t, source, capturedAt, revision) {
2403
- if (source !== "capture" || !capturedAt) return t("workbenchChanges.liveDiff");
2404
- const time = formatAsOf(t, capturedAt, Date.now());
2405
- return revision !== null ? t("workbenchChanges.asOfTurnRevisionTime", { revision, time }) : `as of ${time}`;
2406
- }
2407
- function RailFileRow({
2408
- file,
2409
- grouped,
2410
- active,
2411
- onClick
2412
- }) {
2413
- const repoPrefix = file.repoRoot ? `${file.repoRoot}/` : null;
2414
- const shown = grouped ? file.repoRoot !== void 0 ? repoPrefix && file.path.startsWith(repoPrefix) ? file.path.slice(repoPrefix.length) : file.path : file.path.slice(file.path.indexOf("/") + 1) || file.path : file.path;
2415
- return /* @__PURE__ */ jsxs3(
2416
- "button",
2417
- {
2418
- type: "button",
2419
- onClick,
2420
- title: file.path,
2421
- "data-rail-file": true,
2422
- "data-rail-file-path": file.path,
2423
- className: cn(
2424
- "relative flex min-h-7 w-full items-center gap-1.5 truncate px-2 py-0.5 text-left text-og-sm transition-colors hover:bg-og-surface-2 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-og-accent pointer-coarse:min-h-11",
2425
- grouped && "pl-3",
2426
- active && "bg-og-accent-soft text-og-fg before:absolute before:inset-y-1 before:left-0 before:w-0.5 before:rounded-r-full before:bg-og-accent"
2427
- ),
2428
- children: [
2429
- /* @__PURE__ */ jsx3(
2430
- "span",
2431
- {
2432
- "data-contrast-audited": true,
2433
- className: cn("w-3 shrink-0 text-center font-og-mono text-og-xs", STATUS_TINT[file.status]),
2434
- children: STATUS_LETTER[file.status]
2435
- }
2436
- ),
2437
- /* @__PURE__ */ jsx3("span", { className: "min-w-0 flex-1 truncate", children: shown }),
2438
- /* @__PURE__ */ jsxs3("span", { className: "ml-auto flex shrink-0 items-center gap-1 pl-1 font-og-mono text-og-xs", children: [
2439
- /* @__PURE__ */ jsxs3("span", { "data-contrast-audited": true, className: "text-og-status-idle", children: [
2440
- "+",
2441
- file.additions
2442
- ] }),
2443
- /* @__PURE__ */ jsxs3("span", { "data-contrast-audited": true, className: "text-og-status-failed", children: [
2444
- "\u2212",
2445
- file.deletions
2446
- ] })
2447
- ] })
2448
- ]
2449
- }
2450
- );
2451
- }
2452
- function MeasuredSection({
2453
- index,
2454
- top,
2455
- onMeasure,
2456
- children
2457
- }) {
2458
- const ref = useRef9(null);
2459
- useEffect9(() => {
2460
- const el = ref.current;
2461
- if (!el) return;
2462
- const report = () => onMeasure(index, el.offsetHeight);
2463
- report();
2464
- const ro = typeof ResizeObserver !== "undefined" ? new ResizeObserver(report) : null;
2465
- ro?.observe(el);
2466
- return () => ro?.disconnect();
2467
- }, [index, onMeasure]);
2468
- return /* @__PURE__ */ jsx3(
2469
- "div",
2470
- {
2471
- ref,
2472
- "data-diff-section": true,
2473
- "data-diff-index": index,
2474
- style: { position: "absolute", top, left: 0, right: 0 },
2475
- children
2476
- }
2477
- );
2478
- }
2479
- function DiffSection({
2480
- file,
2481
- layout,
2482
- themeType,
2483
- onOpenFile
2484
- }) {
2485
- if (isGuarded(file)) {
2486
- const renamed = file.oldPath && file.oldPath !== file.path;
2487
- return /* @__PURE__ */ jsxs3("section", { className: "border-b border-og-border pb-1", children: [
2488
- /* @__PURE__ */ jsxs3("header", { className: "flex items-center justify-between gap-2 bg-og-surface-1 px-3 py-1.5 text-og-sm", children: [
2489
- /* @__PURE__ */ jsx3("span", { className: "min-w-0 truncate font-og-mono text-og-xs", children: renamed ? `${file.oldPath} \u2192 ${file.path}` : file.path }),
2490
- /* @__PURE__ */ jsxs3("span", { className: "flex shrink-0 items-center gap-2 font-og-mono text-og-xs", children: [
2491
- /* @__PURE__ */ jsxs3("span", { className: "text-og-status-idle", children: [
2492
- "+",
2493
- file.additions
2494
- ] }),
2495
- /* @__PURE__ */ jsxs3("span", { className: "text-og-status-failed", children: [
2496
- "\u2212",
2497
- file.deletions
2498
- ] })
2499
- ] })
2500
- ] }),
2501
- /* @__PURE__ */ jsx3(GuardBody, { file, ...onOpenFile ? { onOpenFile } : {} })
2502
- ] });
2503
- }
2504
- return /* @__PURE__ */ jsx3("section", { "data-pierre-section": true, className: "border-b border-og-border pb-2", children: /* @__PURE__ */ jsx3(PierreDiff, { diff: [file], layout, themeType, className: "px-1" }) });
2505
- }
2506
- function GuardBody({
2507
- file,
2508
- onOpenFile
2509
- }) {
2510
- const t = useOpenGeniText();
2511
- const reason = file.isBinary ? t("workbenchChanges.binaryFile") : t("workbenchChanges.diffTooLargeToShow");
2512
- return /* @__PURE__ */ jsxs3("div", { className: "flex flex-wrap items-center gap-2 px-3 py-3 text-og-sm text-og-fg-subtle", children: [
2513
- /* @__PURE__ */ jsx3(FileWarningIcon, { className: "size-3.5 shrink-0", "aria-hidden": true }),
2514
- /* @__PURE__ */ jsxs3("span", { className: "min-w-0 flex-1", children: [
2515
- reason,
2516
- "."
2517
- ] }),
2518
- onOpenFile ? /* @__PURE__ */ jsxs3(
2519
- "button",
2520
- {
2521
- type: "button",
2522
- onClick: () => onOpenFile(file.path),
2523
- className: "inline-flex min-h-8 shrink-0 items-center gap-1.5 rounded-og-sm border border-og-border px-2 py-1 text-og-xs font-medium text-og-fg-muted transition-colors hover:border-og-border-strong hover:bg-og-surface-2 hover:text-og-fg focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent pointer-coarse:min-h-11",
2524
- children: [
2525
- t("workbenchChanges.openInFiles"),
2526
- /* @__PURE__ */ jsx3(ArrowUpRightIcon, { className: "size-3.5", "aria-hidden": true })
2527
- ]
2528
- }
2529
- ) : null
2530
- ] });
2531
- }
2532
- function LayoutToggle({
2533
- layout,
2534
- onChange
2535
- }) {
2536
- return /* @__PURE__ */ jsx3("div", { className: "inline-flex items-center rounded-og-sm border border-og-border p-0.5", children: ["unified", "split"].map((value) => /* @__PURE__ */ jsx3(
2537
- "button",
2538
- {
2539
- type: "button",
2540
- onClick: () => onChange(value),
2541
- className: cn(
2542
- "min-h-7 rounded-og-xs px-1.5 py-0.5 text-og-xs capitalize focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent max-[1023px]:min-w-11 pointer-coarse:min-h-11 pointer-coarse:min-w-11",
2543
- layout === value ? "bg-og-accent-soft text-og-fg" : "text-og-fg-subtle hover:text-og-fg"
2544
- ),
2545
- children: value
2546
- },
2547
- value
2548
- )) });
2549
- }
2550
-
2551
- // src/components/diff-view.tsx
2552
- import { jsx as jsx4 } from "react/jsx-runtime";
2553
- function DiffView({
2554
- diff,
2555
- fallback,
2556
- layout = "unified",
2557
- themeType,
2558
- isRepo = true,
2559
- emptyState,
2560
- className
2561
- }) {
2562
- const t = useOpenGeniText();
2563
- if (diff.length === 0) {
2564
- return /* @__PURE__ */ jsx4("div", { className: cn("p-3 text-og-sm text-og-fg-subtle", className), children: emptyState ?? (isRepo ? t("diffView.noChanges") : t("diffView.noRepositoryMounted")) });
2565
- }
2566
- return /* @__PURE__ */ jsx4(
2567
- PierreDiff,
2568
- {
2569
- diff,
2570
- layout,
2571
- themeType,
2572
- ...fallback !== void 0 ? { fallback } : {},
2573
- className
2574
- }
2575
- );
2576
- }
2577
-
2578
- // src/components/sandbox-workspace.tsx
2579
- import {
2580
- lazy,
2581
- Suspense,
2582
- useCallback as useCallback12,
2583
- useEffect as useEffect10,
2584
- useMemo as useMemo8,
2585
- useRef as useRef10,
2586
- useState as useState10
2587
- } from "react";
2588
- import {
2589
- CircleCheckIcon,
2590
- CpuIcon,
2591
- FileCode2Icon,
2592
- GitCompareArrowsIcon,
2593
- Globe2Icon,
2594
- LoaderCircleIcon,
2595
- MonitorIcon,
2596
- RefreshCwIcon,
2597
- SquareTerminalIcon,
2598
- TriangleAlertIcon
2599
- } from "lucide-react";
2600
- import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
2601
- var LazySandboxFiles = lazy(
2602
- () => import("./sandbox-files-YCMLQUFU.js").then(({ SandboxFiles: SandboxFiles2 }) => ({ default: SandboxFiles2 })).catch(() => ({ default: FilesLoadFailed }))
2603
- );
2604
- function FilesLoadFailed() {
2605
- const t = useOpenGeniText();
2606
- return /* @__PURE__ */ jsxs4(CenteredState, { tone: "danger", icon: /* @__PURE__ */ jsx5(TriangleAlertIcon, { className: "size-5", "aria-hidden": true }), children: [
2607
- /* @__PURE__ */ jsx5("p", { className: "text-og-sm font-medium text-og-fg", children: t("sandboxWorkspace.filesCouldNotBeLoaded") }),
2608
- /* @__PURE__ */ jsxs4(DockActionButton, { onClick: () => window.location.reload(), children: [
2609
- /* @__PURE__ */ jsx5(RefreshCwIcon, { className: "size-3", "aria-hidden": true }),
2610
- t("sandboxWorkspace.reload")
2611
- ] })
2612
- ] });
2613
- }
2614
- function FilesTabBody(props) {
2615
- return /* @__PURE__ */ jsx5(Suspense, { fallback: /* @__PURE__ */ jsx5(WorkbenchSurfaceLoading, { name: "Files" }), children: /* @__PURE__ */ jsx5(LazySandboxFiles, { ...props }) });
2616
- }
2617
- var LazyBrowserViewer = lazy(async () => {
2618
- const { BrowserViewer } = await import("./browser-viewer-NOP5EAUO.js");
2619
- return { default: BrowserViewer };
2620
- });
2621
- var LazyComputerViewer = lazy(async () => {
2622
- const { ComputerViewer } = await import("./computer-viewer-LPZ763KF.js");
2623
- return { default: ComputerViewer };
2624
- });
2625
- var WORKBENCH_TAB_CHANGES = "changes";
2626
- var WORKBENCH_TAB_FILES = "files";
2627
- var WORKBENCH_TAB_TERMINAL = "terminal";
2628
- var WORKBENCH_TAB_BROWSER = "browser";
2629
- var WORKBENCH_TAB_DESKTOP = "desktop";
2630
- var WORKBENCH_SURFACES = [
2631
- WORKBENCH_TAB_CHANGES,
2632
- WORKBENCH_TAB_FILES,
2633
- WORKBENCH_TAB_TERMINAL,
2634
- WORKBENCH_TAB_BROWSER,
2635
- WORKBENCH_TAB_DESKTOP
2636
- ];
2637
- function isWorkbenchSurface(value) {
2638
- return WORKBENCH_SURFACES.includes(value);
2639
- }
2640
- function isCanonicalAbsoluteSandboxPath(value) {
2641
- if (!value) return false;
2642
- const portable = value.replaceAll("\\", "/");
2643
- return portable.startsWith("/") || /^[A-Za-z]:\//u.test(portable);
2644
- }
2645
- function sourceDrivenDefaultTab(hasChanges, changesEnabled, filesEnabled) {
2646
- if (hasChanges && changesEnabled) return WORKBENCH_TAB_CHANGES;
2647
- if (filesEnabled) return WORKBENCH_TAB_FILES;
2648
- if (changesEnabled) return WORKBENCH_TAB_CHANGES;
2649
- return null;
2650
- }
2651
- function WorkbenchSurfaceLoading({ name }) {
2652
- const t = useOpenGeniText();
2653
- return /* @__PURE__ */ jsx5(
2654
- CenteredState,
2655
- {
2656
- icon: /* @__PURE__ */ jsx5(LoaderCircleIcon, { className: "size-5 animate-spin motion-reduce:animate-none", "aria-hidden": true }),
2657
- children: /* @__PURE__ */ jsx5("p", { className: "text-og-sm font-medium text-og-fg", children: t("sandboxWorkspace.openingName", { name }) })
2658
- }
2659
- );
2660
- }
2661
- function initialWorkspaceTab(events, override) {
2662
- if (override) return override;
2663
- let bestSeq = -1;
2664
- let bestFileCount = 0;
2665
- for (const event of events ?? []) {
2666
- if (event.type !== "workspace.revision.captured") continue;
2667
- if (event.sequence <= bestSeq) continue;
2668
- const stats = event.payload?.stats;
2669
- bestSeq = event.sequence;
2670
- bestFileCount = typeof stats?.fileCount === "number" ? stats.fileCount : 0;
2671
- }
2672
- if (bestFileCount > 0) return WORKBENCH_TAB_CHANGES;
2673
- let latestGitSeq = -1;
2674
- let committedOnly = false;
2675
- for (const event of events ?? []) {
2676
- if (event.type !== "git.changed" || event.sequence > bestSeq) continue;
2677
- if (event.sequence <= latestGitSeq) continue;
2678
- const payload = event.payload;
2679
- latestGitSeq = event.sequence;
2680
- committedOnly = typeof payload?.ahead === "number" && payload.ahead > 0 || payload?.reason === "commit";
2681
- }
2682
- return committedOnly ? WORKBENCH_TAB_CHANGES : WORKBENCH_TAB_FILES;
2683
- }
2684
- function sandboxProvisionInFlight(events) {
2685
- let inFlight = false;
2686
- for (const event of events) {
2687
- if (event.type !== "sandbox.operation.started" && event.type !== "sandbox.operation.completed" && event.type !== "sandbox.operation.failed") {
2688
- continue;
2689
- }
2690
- const payload = event.payload;
2691
- const name = payload && typeof payload === "object" && !Array.isArray(payload) ? payload.name : null;
2692
- if (name !== "sandbox.provision") continue;
2693
- if (event.type === "sandbox.operation.started") {
2694
- inFlight = true;
2695
- } else {
2696
- inFlight = false;
2697
- }
2698
- }
2699
- return inFlight;
2700
- }
2701
- function workspaceTurnInFlight(events) {
2702
- const activeTurnIds = /* @__PURE__ */ new Set();
2703
- let anonymousTurnInFlight = false;
2704
- let sessionOwnsWorkspace = false;
2705
- for (const event of events) {
2706
- if (event.type === "session.status.changed") {
2707
- const status = event.payload && typeof event.payload === "object" && !Array.isArray(event.payload) ? event.payload.status : null;
2708
- sessionOwnsWorkspace = status === "running" || status === "recovering";
2709
- continue;
2710
- }
2711
- if (event.type === "turn.started") {
2712
- if (event.turnId) activeTurnIds.add(event.turnId);
2713
- else anonymousTurnInFlight = true;
2714
- continue;
2715
- }
2716
- if (event.type !== "turn.completed" && event.type !== "turn.failed" && event.type !== "turn.cancelled" && event.type !== "turn.superseded") {
2717
- continue;
2718
- }
2719
- if (event.turnId) activeTurnIds.delete(event.turnId);
2720
- else anonymousTurnInFlight = false;
2721
- }
2722
- return sessionOwnsWorkspace || anonymousTurnInFlight || activeTurnIds.size > 0;
2723
- }
2724
- function emptyWarmIntents(sessionId) {
2725
- return {
2726
- sessionId,
2727
- warmTerminal: false,
2728
- warmFiles: false
2729
- };
2730
- }
2731
- function useSandboxWorkspaceTabs(options) {
2732
- const t = useOpenGeniText();
2733
- const { client, workspaceId, workspaceInteractionEvent } = useOpenGeni(options);
2734
- const {
2735
- sessionId,
2736
- events,
2737
- onNotify,
2738
- browserWebSocketFactory,
2739
- computerWebSocketFactory,
2740
- browserExtensionSetupUrl,
2741
- requestedFilePath,
2742
- requestedFileRequestId,
2743
- requestedFileLine,
2744
- onOpenFile,
2745
- initialFilePath,
2746
- onFilePathChange,
2747
- isFileNodeVisible,
2748
- initialBrowserSessionId,
2749
- onBrowserSessionIdChange,
2750
- initialComputerSessionId,
2751
- onComputerSessionIdChange,
2752
- onOpenComputerSession,
2753
- requestedComputerSessionId,
2754
- requestedComputerRequestId
2755
- } = options;
2756
- const initialTab = options.initialTab ?? null;
2757
- const activeTab = options.activeTab ?? initialTab;
2758
- const workspaceVisible = options.workspaceVisible ?? true;
2759
- const machinesEnabled = options.machinesEnabled ?? true;
2760
- const requestedSurfaces = options.surfaces ?? WORKBENCH_SURFACES;
2761
- const surfaceSet = new Set(requestedSurfaces);
2762
- const changesEnabled = surfaceSet.has(WORKBENCH_TAB_CHANGES);
2763
- const filesEnabled = surfaceSet.has(WORKBENCH_TAB_FILES);
2764
- const terminalEnabled = surfaceSet.has(WORKBENCH_TAB_TERMINAL);
2765
- const browserEnabled = surfaceSet.has(WORKBENCH_TAB_BROWSER);
2766
- const desktopEnabled = surfaceSet.has(WORKBENCH_TAB_DESKTOP);
2767
- const createLinkedComputer = useCallback12(
2768
- async (name, placement) => {
2769
- const response = await client.createComputerSession(workspaceId, {
2770
- operationId: crypto.randomUUID(),
2771
- sessionId,
2772
- name,
2773
- ...placement ? { placement } : {}
2774
- });
2775
- if (response.operation.state !== "completed" || response.session.lifecycle !== "active") {
2776
- throw new Error(
2777
- response.operation.error?.message ?? t("sandboxWorkspace.theDesktopCouldNotBe")
2778
- );
2779
- }
2780
- return {
2781
- id: response.session.id,
2782
- placement: response.session.placement
2783
- };
2784
- },
2785
- [client, sessionId, workspaceId, t]
2786
- );
2787
- const workspaceDataEnabled = changesEnabled || filesEnabled;
2788
- const machineSurfaceEnabled = workspaceDataEnabled || terminalEnabled || desktopEnabled;
2789
- const resolvedActiveTab = activeTab ?? initialTab;
2790
- const changesActive = resolvedActiveTab === WORKBENCH_TAB_CHANGES;
2791
- const filesActive = resolvedActiveTab === WORKBENCH_TAB_FILES;
2792
- const turnInFlight = workspaceTurnInFlight(events);
2793
- const surfaceIdentity = WORKBENCH_SURFACES.filter((surface) => surfaceSet.has(surface)).join(",");
2794
- const [storedWarmIntents, setStoredWarmIntents] = useState10(
2795
- () => emptyWarmIntents(sessionId)
2796
- );
2797
- const warmIntents = storedWarmIntents.sessionId === sessionId ? storedWarmIntents : emptyWarmIntents(sessionId);
2798
- const { warmTerminal, warmFiles } = warmIntents;
2799
- const filesWarmRequested = warmFiles || Boolean(requestedFilePath);
2800
- const requestWarmIntent = useCallback12(
2801
- (intent) => {
2802
- setStoredWarmIntents((previous) => {
2803
- const current = previous.sessionId === sessionId ? previous : emptyWarmIntents(sessionId);
2804
- return current[intent] ? current : { ...current, [intent]: true };
2805
- });
2806
- },
2807
- [sessionId]
2808
- );
2809
- const machines = useMachines({
2810
- workspaceId,
2811
- sessionId,
2812
- pollIntervalMs: MACHINES_SESSION_POLL_MS,
2813
- enabled: machineSurfaceEnabled && machinesEnabled
2814
- });
2815
- const activeMachine = machines.machines.find((m) => m.sandboxId === machines.activeSandboxId) ?? machines.machines.find((m) => m.active) ?? null;
2816
- const caps = useSessionCapabilities(sessionId, {
2817
- events,
2818
- enabled: machineSurfaceEnabled,
2819
- attachDesktop: false,
2820
- attachTerminal: terminalEnabled && warmTerminal,
2821
- // Explicit live-file intent only — NOT "the Files tab is open". A cold edit
2822
- // or guarded-file open wakes the box; a glance at the tree/diff does not.
2823
- attachFiles: workspaceDataEnabled && filesWarmRequested
2824
- });
2825
- const capabilities = caps.capabilities;
2826
- const liveness = capabilities?.liveness;
2827
- const liveIoLiveness = liveness ?? null;
2828
- const fileSystemOn = capabilities?.FileSystem.available ?? false;
2829
- const fileSystemRoute = capabilities ? { epoch: capabilities.leaseEpoch, root: capabilities.FileSystem.root } : void 0;
2830
- const fsReadOnly = capabilities?.FileSystem.readOnly ?? false;
2831
- const filesEditable = fileSystemOn && !fsReadOnly && sandboxAcceptsLiveIo(liveness);
2832
- const gitOn = capabilities?.Git.available ?? false;
2833
- const terminalOn = terminalEnabled && (capabilities?.Terminal.transport ?? null) !== null;
2834
- const ptyCapable = warmTerminal && (capabilities?.Terminal.ptyCapable ?? false) && capabilities?.Terminal.transport === "sse-events" && capabilities?.Terminal.reason === null;
2835
- const terminalShown = terminalOn && workspaceVisible && resolvedActiveTab === WORKBENCH_TAB_TERMINAL;
2836
- const [terminalOpenedSession, setTerminalOpenedSession] = useState10(null);
2837
- useEffect10(() => {
2838
- if (terminalShown) setTerminalOpenedSession(sessionId);
2839
- }, [terminalShown, sessionId]);
2840
- const terminal = useSandboxTerminal(sessionId, {
2841
- events: terminalEnabled ? events : [],
2842
- interactive: terminalEnabled && ptyCapable,
2843
- liveness,
2844
- history: terminalShown || terminalOpenedSession === sessionId
2845
- });
2846
- const provisioning = sandboxProvisionInFlight(events);
2847
- const renegotiate = caps.renegotiate;
2848
- const provisioningRef = useRef10({ sessionId, provisioning });
2849
- useEffect10(() => {
2850
- const previous = provisioningRef.current;
2851
- if (previous.sessionId === sessionId && previous.provisioning && !provisioning) {
2852
- renegotiate();
2853
- }
2854
- provisioningRef.current = { sessionId, provisioning };
2855
- }, [sessionId, provisioning, renegotiate]);
2856
- useEffect10(() => {
2857
- if (workspaceInteractionEvent?.workspaceId !== workspaceId) return;
2858
- renegotiate();
2859
- }, [workspaceId, workspaceInteractionEvent, renegotiate]);
2860
- const captureState = useWorkspaceCapture(sessionId, {
2861
- events,
2862
- enabled: workspaceDataEnabled
2863
- });
2864
- const captureAvailable = captureState.available;
2865
- const liveWorkspaceExpected = sandboxAcceptsLiveIo(liveness);
2866
- const capturePending = !liveWorkspaceExpected && (captureState.fileCount === null || captureState.loading);
2867
- const repoPaths = useMemo8(() => {
2868
- const advertised = capabilities?.Git.repos ?? [];
2869
- if (advertised.length > 0) return advertised;
2870
- return captureState.capture?.repos.map((repo) => repo.root) ?? [];
2871
- }, [capabilities?.Git.repos, captureState.capture]);
2872
- const files = useSandboxFiles(sessionId, {
2873
- events,
2874
- // No passive Channel-A reads while cold, even after a conclusive capture
2875
- // miss. A missing capture gets an explicit "Open live workspace" gate.
2876
- enabled: filesEnabled && (captureAvailable || fileSystemOn && liveWorkspaceExpected),
2877
- // A cold sandbox can become warm while the first agent command still owns
2878
- // startup. Do not race that command with an automatic Files read. Keeping
2879
- // this fence at turn scope also avoids unsafe millisecond gaps between
2880
- // sequential tool calls; rendered state and explicit user actions remain.
2881
- active: filesActive && !turnInFlight,
2882
- // A deliberate canonical absolute-path open browses in the selected target's
2883
- // advertised namespace, so the authoritative tree and link share exact paths.
2884
- ...isCanonicalAbsoluteSandboxPath(requestedFilePath) && capabilities?.FileSystem.root ? { rootPath: capabilities.FileSystem.root } : {},
2885
- ...fileSystemRoute ? { route: fileSystemRoute } : {},
2886
- repoPaths,
2887
- liveness: liveIoLiveness,
2888
- capture: captureState.capture,
2889
- // A reverted optimistic mutation (e.g. a 409 rename collision) surfaces as a
2890
- // host notification — the tree silently rolls back, the user sees why.
2891
- onMutationError: (error, op) => onNotify?.({
2892
- kind: "error",
2893
- message: t("sandboxWorkspace.couldNotOpMessage", { op, message: error.message })
2894
- })
2895
- });
2896
- const [storedChangesComparison, setStoredChangesComparison] = useState10(null);
2897
- const captureSupportsBranch = captureState.capture !== null && captureState.capture.repos.length > 0 && captureState.capture.repos.every((repo) => repo.branchDiff !== void 0);
2898
- const changesComparison = storedChangesComparison?.sessionId === sessionId ? storedChangesComparison.value : liveWorkspaceExpected || captureSupportsBranch ? "branch" : "working";
2899
- const setChangesComparison = useCallback12(
2900
- (value) => setStoredChangesComparison({ sessionId, value }),
2901
- [sessionId]
2902
- );
2903
- const git = useSandboxGit(sessionId, {
2904
- events,
2905
- enabled: changesComparison === "working" ? workspaceDataEnabled && (captureAvailable || gitOn && liveWorkspaceExpected) : changesComparison === "branch" ? workspaceDataEnabled && (captureSupportsBranch || gitOn && liveWorkspaceExpected) : workspaceDataEnabled && gitOn && liveWorkspaceExpected,
2906
- // Live Git belongs to the visible Changes surface. In particular, do not
2907
- // turn an unresolved/default tab into a hidden provider read: that races the
2908
- // agent's own sandbox commands and used to refresh after every tool output
2909
- // even while Files was visibly selected.
2910
- active: changesActive && !turnInFlight,
2911
- repoPaths,
2912
- liveness: liveIoLiveness,
2913
- comparison: changesComparison,
2914
- capture: changesComparison === "staged" ? null : captureState.capture
2915
- });
2916
- useEffect10(() => {
2917
- if (changesComparison === "branch" && git.error && storedChangesComparison?.sessionId !== sessionId) {
2918
- setStoredChangesComparison({ sessionId, value: "working" });
2919
- }
2920
- }, [changesComparison, git.error, sessionId, storedChangesComparison?.sessionId]);
2921
- const [xtermTheme, setXtermTheme] = useState10(void 0);
2922
- useEffect10(() => {
2923
- if (!terminalEnabled || typeof document === "undefined") return;
2924
- const derive = () => setXtermTheme(xtermThemeFromTokens());
2925
- derive();
2926
- const observer = new MutationObserver(derive);
2927
- observer.observe(document.documentElement, {
2928
- attributes: true,
2929
- attributeFilter: ["data-og-theme", "class"]
2930
- });
2931
- return () => observer.disconnect();
2932
- }, [terminalEnabled]);
2933
- const dirtyCount = git.diff.length;
2934
- const chip = useMachineChip({
2935
- liveness,
2936
- capabilitiesState: caps.state,
2937
- activeMachineState: activeMachine?.state ?? null,
2938
- activeIsSelfhosted: activeMachine?.kind === "selfhosted",
2939
- wantsWarm: terminalEnabled && warmTerminal || workspaceDataEnabled && filesWarmRequested,
2940
- capturedAt: captureState.capturedAt
2941
- });
2942
- const workspaceWaking = chip.state === "waking";
2943
- const defaultIdentity = `${sessionId}\0${surfaceIdentity}`;
2944
- const defaultTabRef = useRef10({
2945
- identity: defaultIdentity,
2946
- value: null
2947
- });
2948
- if (defaultTabRef.current.identity !== defaultIdentity) {
2949
- defaultTabRef.current = { identity: defaultIdentity, value: null };
2950
- }
2951
- const captureHasChanges = (captureState.fileCount ?? 0) > 0 || (captureState.capture?.repos.some((repo) => (repo.branchDiff?.length ?? 0) > 0) ?? false);
2952
- const captureUnavailable = !captureState.loading && (captureState.fileCount === 0 && !captureHasChanges || captureState.error !== null);
2953
- if (defaultTabRef.current.value === null) {
2954
- if (initialTab && (!isWorkbenchSurface(initialTab) || surfaceSet.has(initialTab))) {
2955
- defaultTabRef.current.value = initialTab;
2956
- } else if (captureState.fileCount !== null && captureState.available) {
2957
- defaultTabRef.current.value = sourceDrivenDefaultTab(
2958
- captureHasChanges,
2959
- changesEnabled,
2960
- filesEnabled
2961
- );
2962
- } else if (captureUnavailable && initialWorkspaceTab(events) === WORKBENCH_TAB_CHANGES) {
2963
- defaultTabRef.current.value = sourceDrivenDefaultTab(true, changesEnabled, filesEnabled);
2964
- } else if (!captureState.loading && (captureState.fileCount !== null || captureState.error !== null)) {
2965
- defaultTabRef.current.value = sourceDrivenDefaultTab(false, changesEnabled, filesEnabled);
2966
- }
2967
- }
2968
- const defaultTab = defaultTabRef.current.value;
2969
- const tabs = useMemo8(() => {
2970
- const list = [];
2971
- if (changesEnabled)
2972
- list.push({
2973
- id: WORKBENCH_TAB_CHANGES,
2974
- label: t("sandboxWorkspace.changes"),
2975
- icon: /* @__PURE__ */ jsx5(GitCompareArrowsIcon, {}),
2976
- badge: dirtyCount > 0 ? /* @__PURE__ */ jsx5(DirtyBadge, { count: dirtyCount }) : void 0,
2977
- content: /* @__PURE__ */ jsx5(
2978
- ChangesTabBody,
2979
- {
2980
- git,
2981
- comparison: changesComparison,
2982
- onComparisonChange: setChangesComparison,
2983
- captureAvailable,
2984
- captureDegraded: captureState.degradedReason !== null,
2985
- captureRevision: captureState.revision,
2986
- capturePending,
2987
- liveWorkspaceExpected,
2988
- workspaceWaking,
2989
- capabilitiesState: caps.state,
2990
- capabilitiesError: caps.error,
2991
- onRetry: caps.renegotiate,
2992
- onWake: () => requestWarmIntent("warmFiles"),
2993
- ...filesEnabled && onOpenFile ? {
2994
- onOpenFile: (path) => {
2995
- requestWarmIntent("warmFiles");
2996
- onOpenFile(path);
2997
- }
2998
- } : {}
2999
- }
3000
- )
3001
- });
3002
- if (filesEnabled)
3003
- list.push({
3004
- id: WORKBENCH_TAB_FILES,
3005
- label: t("sandboxWorkspace.files"),
3006
- icon: /* @__PURE__ */ jsx5(FileCode2Icon, {}),
3007
- content: /* @__PURE__ */ jsx5(
3008
- FilesTabBody,
3009
- {
3010
- files,
3011
- git,
3012
- isNodeVisible: isFileNodeVisible,
3013
- fileSystemAvailable: fileSystemOn || captureAvailable,
3014
- editable: filesEditable && files.source === "live" && files.error === null && !files.loading,
3015
- workspaceResting: !liveWorkspaceExpected && liveness !== void 0 && !capturePending && !captureAvailable && !workspaceWaking,
3016
- workspaceWaking: !liveWorkspaceExpected && !captureAvailable && workspaceWaking,
3017
- liveWorkspaceReady: liveWorkspaceExpected,
3018
- workspaceError: caps.error ?? (caps.viewerCapReached ? new Error(t("sandboxWorkspace.theLiveWorkspaceViewerLimit")) : filesWarmRequested && caps.state === "on-demand" && !fileSystemOn ? new Error(t("sandboxWorkspace.thisMachineDoesNotCurrently")) : null),
3019
- onWakeWorkspace: () => {
3020
- if (filesWarmRequested) caps.renegotiate();
3021
- else requestWarmIntent("warmFiles");
3022
- },
3023
- ...requestedFilePath ? {
3024
- requestedPath: requestedFilePath,
3025
- ...requestedFileRequestId !== null && requestedFileRequestId !== void 0 ? { requestedPathRequestId: requestedFileRequestId } : {},
3026
- requestedPathReady: sandboxAcceptsLiveIo(liveness),
3027
- ...requestedFileLine != null && requestedFileLine > 0 ? { requestedLine: requestedFileLine } : {}
3028
- } : {},
3029
- onEditIntent: () => requestWarmIntent("warmFiles"),
3030
- initialSelectedPath: initialFilePath,
3031
- onSelectedPathChange: onFilePathChange,
3032
- className: "h-full"
3033
- },
3034
- sessionId
3035
- )
3036
- });
3037
- if (terminalOn) {
3038
- list.push({
3039
- id: WORKBENCH_TAB_TERMINAL,
3040
- label: t("sandboxWorkspace.terminal"),
3041
- icon: /* @__PURE__ */ jsx5(SquareTerminalIcon, {}),
3042
- content: /* @__PURE__ */ jsx5("div", { className: "h-full bg-og-bg p-1", children: /* @__PURE__ */ jsx5(
3043
- SandboxTerminal,
3044
- {
3045
- result: terminal,
3046
- terminalCapability: capabilities?.Terminal ?? null,
3047
- onActivate: () => requestWarmIntent("warmTerminal"),
3048
- onReconnectNeeded: caps.renegotiate,
3049
- showHeader: true,
3050
- shell: capabilities?.Terminal.shell ?? void 0,
3051
- liveness,
3052
- ...xtermTheme ? { theme: xtermTheme } : {}
3053
- },
3054
- sessionId
3055
- ) })
3056
- });
3057
- }
3058
- if (browserEnabled) {
3059
- list.push({
3060
- id: WORKBENCH_TAB_BROWSER,
3061
- label: t("sandboxWorkspace.browser"),
3062
- icon: /* @__PURE__ */ jsx5(Globe2Icon, {}),
3063
- content: /* @__PURE__ */ jsx5(Suspense, { fallback: /* @__PURE__ */ jsx5(WorkbenchSurfaceLoading, { name: "Browser" }), children: /* @__PURE__ */ jsx5(
3064
- LazyBrowserViewer,
3065
- {
3066
- client,
3067
- workspaceId,
3068
- sessionId,
3069
- enabled: workspaceVisible,
3070
- active: resolvedActiveTab === WORKBENCH_TAB_BROWSER,
3071
- onNotify,
3072
- initialBrowserSessionId,
3073
- onBrowserSessionIdChange,
3074
- ...desktopEnabled ? { createLinkedComputer } : {},
3075
- ...onOpenComputerSession ? { onOpenComputer: onOpenComputerSession } : {},
3076
- ...browserWebSocketFactory ? { webSocketFactory: browserWebSocketFactory } : {},
3077
- ...browserExtensionSetupUrl ? { browserExtensionSetupUrl } : {},
3078
- className: "h-full"
3079
- },
3080
- sessionId
3081
- ) })
3082
- });
3083
- }
3084
- if (desktopEnabled) {
3085
- list.push({
3086
- id: WORKBENCH_TAB_DESKTOP,
3087
- label: t("sandboxWorkspace.desktop"),
3088
- icon: /* @__PURE__ */ jsx5(MonitorIcon, {}),
3089
- content: /* @__PURE__ */ jsx5(Suspense, { fallback: /* @__PURE__ */ jsx5(WorkbenchSurfaceLoading, { name: "Desktop" }), children: /* @__PURE__ */ jsx5(
3090
- LazyComputerViewer,
3091
- {
3092
- client,
3093
- workspaceId,
3094
- sessionId,
3095
- enabled: workspaceVisible,
3096
- onNotify,
3097
- initialComputerSessionId,
3098
- onComputerSessionIdChange,
3099
- requestedComputerSessionId,
3100
- requestedComputerRequestId,
3101
- ...computerWebSocketFactory ? { webSocketFactory: computerWebSocketFactory } : {},
3102
- className: "h-full"
3103
- },
3104
- sessionId
3105
- ) })
3106
- });
3107
- }
3108
- return list;
3109
- }, [
3110
- fileSystemOn,
3111
- changesEnabled,
3112
- filesEnabled,
3113
- terminalOn,
3114
- browserEnabled,
3115
- desktopEnabled,
3116
- captureAvailable,
3117
- captureState.degradedReason,
3118
- dirtyCount,
3119
- warmTerminal,
3120
- requestedFilePath,
3121
- requestedFileRequestId,
3122
- requestedFileLine,
3123
- onOpenFile,
3124
- initialFilePath,
3125
- onFilePathChange,
3126
- isFileNodeVisible,
3127
- initialBrowserSessionId,
3128
- onBrowserSessionIdChange,
3129
- initialComputerSessionId,
3130
- onComputerSessionIdChange,
3131
- onOpenComputerSession,
3132
- requestedComputerSessionId,
3133
- requestedComputerRequestId,
3134
- onNotify,
3135
- browserWebSocketFactory,
3136
- computerWebSocketFactory,
3137
- workspaceVisible,
3138
- resolvedActiveTab,
3139
- client,
3140
- workspaceId,
3141
- liveness,
3142
- sessionId,
3143
- files,
3144
- git,
3145
- changesComparison,
3146
- terminal,
3147
- xtermTheme,
3148
- capabilities,
3149
- workspaceWaking,
3150
- caps.state,
3151
- caps.error,
3152
- caps.viewerCapReached,
3153
- caps.renegotiate,
3154
- filesWarmRequested,
3155
- requestWarmIntent,
3156
- createLinkedComputer,
3157
- t
3158
- ]);
3159
- return {
3160
- tabs,
3161
- defaultTab,
3162
- machine: {
3163
- enabled: machineSurfaceEnabled,
3164
- chip,
3165
- activeMachine,
3166
- loading: machines.loading,
3167
- error: machines.error,
3168
- refresh: machines.refresh
3169
- }
3170
- };
3171
- }
3172
- function SandboxWorkspace(props) {
3173
- const {
3174
- sessionId,
3175
- events,
3176
- primary,
3177
- surfaces,
3178
- machinesEnabled,
3179
- leadingTabs,
3180
- trailingTabs,
3181
- initialTab,
3182
- onActiveTabChange,
3183
- openTabRequest,
3184
- initialFilePath,
3185
- onFilePathChange,
3186
- isFileNodeVisible,
3187
- openFileRequest,
3188
- initialBrowserSessionId,
3189
- onBrowserSessionIdChange,
3190
- initialComputerSessionId,
3191
- onComputerSessionIdChange,
3192
- onNotify,
3193
- browserWebSocketFactory,
3194
- computerWebSocketFactory,
3195
- browserExtensionSetupUrl,
3196
- collapsed,
3197
- onCollapsedChange,
3198
- showCollapseControl,
3199
- mobileLeadingControl,
3200
- autoSaveId,
3201
- defaultSize,
3202
- minSize,
3203
- maxSize,
3204
- className
3205
- } = props;
3206
- const [storedSelection, setStoredSelection] = useState10(null);
3207
- const [requestedFile, setRequestedFile] = useState10(null);
3208
- const [requestedComputer, setRequestedComputer] = useState10(null);
3209
- const nextFileRequestId = useRef10(0);
3210
- const nextComputerRequestId = useRef10(0);
3211
- const selectedTab = storedSelection?.sessionId === sessionId ? storedSelection.tab : null;
3212
- const handledTabRequest = useRef10(null);
3213
- useEffect10(() => {
3214
- if (!openTabRequest || handledTabRequest.current?.sessionId === sessionId && handledTabRequest.current.requestId === openTabRequest.requestId)
3215
- return;
3216
- const available = [...leadingTabs ?? [], ...trailingTabs ?? []].some(
3217
- (tab) => tab.id === openTabRequest.tab
3218
- ) || (surfaces ?? WORKBENCH_SURFACES).some((tab) => tab === openTabRequest.tab);
3219
- if (!available) return;
3220
- handledTabRequest.current = { sessionId, requestId: openTabRequest.requestId };
3221
- setStoredSelection({ sessionId, tab: openTabRequest.tab });
3222
- onActiveTabChange?.(openTabRequest.tab);
3223
- onCollapsedChange?.(false);
3224
- }, [
3225
- openTabRequest,
3226
- sessionId,
3227
- leadingTabs,
3228
- trailingTabs,
3229
- surfaces,
3230
- onActiveTabChange,
3231
- onCollapsedChange
3232
- ]);
3233
- const activeTabHint = selectedTab ?? initialTab ?? leadingTabs?.[0]?.id ?? null;
3234
- const openFile = useCallback12(
3235
- (path, line) => {
3236
- setRequestedFile({
3237
- sessionId,
3238
- path,
3239
- line: line != null && line > 0 ? line : null,
3240
- requestId: ++nextFileRequestId.current
3241
- });
3242
- setStoredSelection({ sessionId, tab: WORKBENCH_TAB_FILES });
3243
- onActiveTabChange?.(WORKBENCH_TAB_FILES);
3244
- onFilePathChange?.(path);
3245
- onCollapsedChange?.(false);
3246
- },
3247
- [onActiveTabChange, onCollapsedChange, onFilePathChange, sessionId]
3248
- );
3249
- const handledOpenFileRequestId = useRef10(null);
3250
- useEffect10(() => {
3251
- if (!openFileRequest) return;
3252
- if (handledOpenFileRequestId.current === openFileRequest.requestId) return;
3253
- handledOpenFileRequestId.current = openFileRequest.requestId;
3254
- openFile(openFileRequest.path, openFileRequest.line);
3255
- }, [openFile, openFileRequest]);
3256
- const openComputer = useCallback12(
3257
- (computerSessionId) => {
3258
- nextComputerRequestId.current += 1;
3259
- setRequestedComputer({
3260
- sessionId,
3261
- computerSessionId,
3262
- requestId: nextComputerRequestId.current
3263
- });
3264
- setStoredSelection({ sessionId, tab: WORKBENCH_TAB_DESKTOP });
3265
- onActiveTabChange?.(WORKBENCH_TAB_DESKTOP);
3266
- onComputerSessionIdChange?.(computerSessionId);
3267
- },
3268
- [onActiveTabChange, onComputerSessionIdChange, sessionId]
3269
- );
3270
- const {
3271
- tabs: workbenchTabs,
3272
- machine,
3273
- defaultTab
3274
- } = useSandboxWorkspaceTabs({
3275
- ...props.client ? { client: props.client } : {},
3276
- ...props.workspaceId ? { workspaceId: props.workspaceId } : {},
3277
- sessionId,
3278
- events,
3279
- ...surfaces ? { surfaces } : {},
3280
- ...machinesEnabled !== void 0 ? { machinesEnabled } : {},
3281
- ...initialTab ? { initialTab } : {},
3282
- activeTab: activeTabHint,
3283
- workspaceVisible: collapsed !== true,
3284
- ...onNotify ? { onNotify } : {},
3285
- ...browserWebSocketFactory ? { browserWebSocketFactory } : {},
3286
- ...computerWebSocketFactory ? { computerWebSocketFactory } : {},
3287
- ...browserExtensionSetupUrl ? { browserExtensionSetupUrl } : {},
3288
- initialFilePath,
3289
- onFilePathChange,
3290
- isFileNodeVisible,
3291
- initialBrowserSessionId,
3292
- onBrowserSessionIdChange,
3293
- initialComputerSessionId,
3294
- onComputerSessionIdChange,
3295
- requestedFilePath: requestedFile?.sessionId === sessionId ? requestedFile.path : null,
3296
- requestedFileRequestId: requestedFile?.sessionId === sessionId ? requestedFile.requestId : null,
3297
- requestedFileLine: requestedFile?.sessionId === sessionId ? requestedFile.line : null,
3298
- onOpenFile: openFile,
3299
- onOpenComputerSession: openComputer,
3300
- requestedComputerSessionId: requestedComputer?.sessionId === sessionId ? requestedComputer.computerSessionId : null,
3301
- requestedComputerRequestId: requestedComputer?.sessionId === sessionId ? requestedComputer.requestId : null
3302
- });
3303
- const tabs = [...leadingTabs ?? [], ...workbenchTabs, ...trailingTabs ?? []];
3304
- const preferredTab = selectedTab ?? defaultTab;
3305
- const activeTab = preferredTab && tabs.some((tab) => tab.id === preferredTab) ? preferredTab : tabs[0]?.id;
3306
- const selectTab = useCallback12(
3307
- (tab) => {
3308
- setStoredSelection({ sessionId, tab });
3309
- onActiveTabChange?.(tab);
3310
- },
3311
- [onActiveTabChange, sessionId]
3312
- );
3313
- useEffect10(() => {
3314
- if (selectedTab !== null || defaultTab === null) return;
3315
- setStoredSelection({ sessionId, tab: defaultTab });
3316
- }, [defaultTab, selectedTab, sessionId]);
3317
- return /* @__PURE__ */ jsx5(
3318
- WorkspaceDock,
3319
- {
3320
- primary,
3321
- tabs,
3322
- ...activeTab !== void 0 ? { activeTab } : {},
3323
- onActiveTabChange: selectTab,
3324
- ...machine.enabled && activeTab !== WORKBENCH_TAB_BROWSER && activeTab !== WORKBENCH_TAB_DESKTOP ? {
3325
- headerAccessory: /* @__PURE__ */ jsx5(MachineStateChip, { chip: machine.chip })
3326
- } : {},
3327
- ...mobileLeadingControl !== void 0 ? { mobileLeadingControl } : {},
3328
- ...collapsed !== void 0 ? { collapsed } : {},
3329
- ...onCollapsedChange ? { onCollapsedChange } : {},
3330
- ...showCollapseControl !== void 0 ? { showCollapseControl } : {},
3331
- ...autoSaveId !== void 0 ? { autoSaveId } : {},
3332
- ...defaultSize !== void 0 ? { defaultSize } : {},
3333
- ...minSize !== void 0 ? { minSize } : {},
3334
- ...maxSize !== void 0 ? { maxSize } : {},
3335
- ...className !== void 0 ? { className } : {}
3336
- }
3337
- );
3338
- }
3339
- function DirtyBadge({ count }) {
3340
- return /* @__PURE__ */ jsx5("span", { className: "rounded-og-xs bg-og-accent-soft px-1 text-og-xs text-og-fg-muted", children: count });
3341
- }
3342
- function chipDotClass(state) {
3343
- if (state === "live") return "bg-og-status-running";
3344
- if (state === "waking") return "bg-og-status-idle animate-pulse motion-reduce:animate-none";
3345
- return "bg-og-fg-subtle";
3346
- }
3347
- function MachineStateChip({ chip }) {
3348
- const t = useOpenGeniText();
3349
- return /* @__PURE__ */ jsxs4(
3350
- "div",
3351
- {
3352
- role: "status",
3353
- "aria-label": t("sandboxWorkspace.machineLabel", { label: chip.label }),
3354
- title: chip.label,
3355
- className: "inline-flex min-h-7 min-w-0 max-w-full items-center gap-1.5 px-2 py-1 text-og-xs font-medium text-og-fg-muted max-[1023px]:min-h-11 pointer-coarse:min-h-11",
3356
- children: [
3357
- /* @__PURE__ */ jsx5(
3358
- "span",
3359
- {
3360
- className: cn("size-1.5 shrink-0 rounded-full", chipDotClass(chip.state)),
3361
- "aria-hidden": true
3362
- }
3363
- ),
3364
- /* @__PURE__ */ jsx5("span", { className: "min-w-0 max-w-[11rem] truncate", children: chip.label })
3365
- ]
3366
- }
3367
- );
3368
- }
3369
- function DockActionButton({ onClick, children }) {
3370
- return /* @__PURE__ */ jsx5(
3371
- "button",
3372
- {
3373
- type: "button",
3374
- onClick,
3375
- className: "inline-flex items-center gap-1.5 rounded-og-sm border border-og-border px-2 py-1 text-og-xs font-medium text-og-fg-muted transition-colors hover:border-og-border-strong hover:text-og-fg focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent max-[1023px]:min-h-11 pointer-coarse:min-h-11",
3376
- children
3377
- }
3378
- );
3379
- }
3380
- function ChangesTabBody({
3381
- comparison,
3382
- onComparisonChange,
3383
- ...props
3384
- }) {
3385
- const t = useOpenGeniText();
3386
- return /* @__PURE__ */ jsxs4("div", { className: "flex h-full min-h-0 flex-col", children: [
3387
- /* @__PURE__ */ jsx5("div", { className: "flex shrink-0 items-center gap-1 border-b border-og-border bg-og-surface-1 px-2 py-1.5", children: [
3388
- ["branch", t("sandboxWorkspace.branch")],
3389
- ["working", t("sandboxWorkspace.uncommitted")],
3390
- ["staged", t("sandboxWorkspace.staged")]
3391
- ].map(([value, label]) => /* @__PURE__ */ jsx5(
3392
- "button",
3393
- {
3394
- type: "button",
3395
- "aria-pressed": comparison === value,
3396
- onClick: () => onComparisonChange(value),
3397
- className: cn(
3398
- "rounded-og-sm px-2 py-1 text-og-xs font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent max-[1023px]:min-h-11 pointer-coarse:min-h-11",
3399
- comparison === value ? "bg-og-surface-2 text-og-fg shadow-sm" : "text-og-fg-muted hover:bg-og-surface-2 hover:text-og-fg"
3400
- ),
3401
- children: label
3402
- },
3403
- value
3404
- )) }),
3405
- /* @__PURE__ */ jsx5("div", { className: "min-h-0 flex-1", children: /* @__PURE__ */ jsx5(ChangesTabContent, { comparison, ...props }) })
3406
- ] });
3407
- }
3408
- function ChangesTabContent({
3409
- git,
3410
- comparison,
3411
- captureAvailable,
3412
- captureDegraded,
3413
- captureRevision,
3414
- capturePending,
3415
- liveWorkspaceExpected,
3416
- workspaceWaking,
3417
- capabilitiesState,
3418
- capabilitiesError,
3419
- onRetry,
3420
- onWake,
3421
- onOpenFile
3422
- }) {
3423
- const t = useOpenGeniText();
3424
- const diff = git.diff;
3425
- if (diff.length > 0) {
3426
- return /* @__PURE__ */ jsxs4("div", { className: "flex h-full min-h-0 flex-col", children: [
3427
- git.error ? /* @__PURE__ */ jsxs4(
3428
- "div",
3429
- {
3430
- role: "status",
3431
- "aria-live": "polite",
3432
- "data-opengeni-changes-degraded": true,
3433
- className: "flex shrink-0 items-center gap-2 border-b border-og-status-running/30 bg-og-status-running/10 px-2 py-1.5 text-og-xs text-og-fg-muted",
3434
- children: [
3435
- /* @__PURE__ */ jsx5(TriangleAlertIcon, { className: "size-3.5 shrink-0 text-og-status-running", "aria-hidden": true }),
3436
- /* @__PURE__ */ jsx5("span", { className: "min-w-0 flex-1", children: git.source === "capture" ? t("sandboxWorkspace.liveChangesAreTemporarilyUnavailable") : t("sandboxWorkspace.liveRefreshFailedShowingThe") }),
3437
- /* @__PURE__ */ jsxs4(
3438
- "button",
3439
- {
3440
- type: "button",
3441
- onClick: () => void git.refresh(),
3442
- disabled: git.loading,
3443
- className: "inline-flex min-h-7 shrink-0 items-center gap-1 rounded-og-sm border border-og-border bg-og-surface-1 px-2 font-medium text-og-fg transition-colors hover:border-og-border-strong focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent disabled:cursor-not-allowed disabled:opacity-50 pointer-coarse:min-h-11",
3444
- children: [
3445
- /* @__PURE__ */ jsx5(
3446
- RefreshCwIcon,
3447
- {
3448
- className: cn("size-3", git.loading && "animate-spin motion-reduce:animate-none"),
3449
- "aria-hidden": true
3450
- }
3451
- ),
3452
- t("sandboxWorkspace.retry")
3453
- ]
3454
- }
3455
- )
3456
- ]
3457
- }
3458
- ) : null,
3459
- /* @__PURE__ */ jsx5("div", { className: "min-h-0 flex-1", children: /* @__PURE__ */ jsx5(
3460
- WorkbenchChanges,
3461
- {
3462
- diff,
3463
- source: git.source,
3464
- capturedAt: git.capturedAt,
3465
- captureRevision,
3466
- ...onOpenFile ? { onOpenFile } : {}
3467
- }
3468
- ) })
3469
- ] });
3470
- }
3471
- if (capabilitiesError && !captureAvailable) {
3472
- return /* @__PURE__ */ jsxs4(CenteredState, { icon: /* @__PURE__ */ jsx5(TriangleAlertIcon, { className: "size-5", "aria-hidden": true }), tone: "danger", children: [
3473
- /* @__PURE__ */ jsx5("p", { className: "text-og-sm font-medium text-og-fg", children: t("sandboxWorkspace.sandboxUnavailable") }),
3474
- /* @__PURE__ */ jsx5("p", { "data-contrast-audited": true, className: "text-og-sm leading-5 text-og-fg-muted", children: capabilitiesError.message || t("sandboxWorkspace.couldnTReachTheSandbox") }),
3475
- /* @__PURE__ */ jsxs4(DockActionButton, { onClick: onRetry, children: [
3476
- /* @__PURE__ */ jsx5(RefreshCwIcon, { className: "size-3" }),
3477
- t("sandboxWorkspace.retry")
3478
- ] })
3479
- ] });
3480
- }
3481
- if ((capturePending || capabilitiesState === "negotiating") && !captureAvailable && !workspaceWaking) {
3482
- return /* @__PURE__ */ jsxs4(
3483
- CenteredState,
3484
- {
3485
- icon: /* @__PURE__ */ jsx5(
3486
- LoaderCircleIcon,
3487
- {
3488
- className: "size-5 animate-spin motion-reduce:animate-none",
3489
- "aria-hidden": true
3490
- }
3491
- ),
3492
- children: [
3493
- /* @__PURE__ */ jsx5("p", { className: "text-og-sm font-medium text-og-fg", children: t("sandboxWorkspace.connectingWorkspace") }),
3494
- /* @__PURE__ */ jsx5("p", { className: "text-og-sm leading-5 text-og-fg-subtle", children: t("sandboxWorkspace.lookingForTheLatestFiles") })
3495
- ]
3496
- }
3497
- );
3498
- }
3499
- if (!liveWorkspaceExpected && (comparison !== "working" || !captureAvailable)) {
3500
- const previewUnavailable = captureDegraded && !captureAvailable && comparison !== "staged";
3501
- return /* @__PURE__ */ jsxs4(
3502
- CenteredState,
3503
- {
3504
- icon: workspaceWaking ? /* @__PURE__ */ jsx5(
3505
- LoaderCircleIcon,
3506
- {
3507
- className: "size-5 animate-spin motion-reduce:animate-none",
3508
- "aria-hidden": true
3509
- }
3510
- ) : previewUnavailable ? /* @__PURE__ */ jsx5(TriangleAlertIcon, { className: "size-5", "aria-hidden": true }) : /* @__PURE__ */ jsx5(CpuIcon, { className: "size-5", "aria-hidden": true }),
3511
- children: [
3512
- /* @__PURE__ */ jsx5("p", { className: "text-og-sm font-medium text-og-fg", children: workspaceWaking ? t("sandboxWorkspace.wakingWorkspace") : previewUnavailable ? t("sandboxWorkspace.savedChangesPreviewIsUnavailable") : t("sandboxWorkspace.workspaceIsResting") }),
3513
- /* @__PURE__ */ jsx5("p", { className: "text-og-sm leading-5 text-og-fg-subtle", children: workspaceWaking ? t("sandboxWorkspace.connectingToTheLiveWorking") : previewUnavailable ? t("sandboxWorkspace.openTheLiveWorkspaceTo") : comparison === "branch" ? t("sandboxWorkspace.wakeTheSandboxToCompare") : comparison === "staged" ? t("sandboxWorkspace.wakeTheSandboxToInspect") : t("sandboxWorkspace.noCapturedRevisionIsAvailable") }),
3514
- !workspaceWaking ? /* @__PURE__ */ jsxs4(DockActionButton, { onClick: onWake, children: [
3515
- /* @__PURE__ */ jsx5(CpuIcon, { className: "size-3" }),
3516
- t("sandboxWorkspace.openLiveWorkspace")
3517
- ] }) : null
3518
- ]
3519
- }
3520
- );
3521
- }
3522
- if (git.loading && git.source === null) {
3523
- return /* @__PURE__ */ jsxs4(
3524
- CenteredState,
3525
- {
3526
- icon: /* @__PURE__ */ jsx5(
3527
- LoaderCircleIcon,
3528
- {
3529
- className: "size-5 animate-spin motion-reduce:animate-none",
3530
- "aria-hidden": true
3531
- }
3532
- ),
3533
- children: [
3534
- /* @__PURE__ */ jsx5("p", { className: "text-og-sm font-medium text-og-fg", children: t("sandboxWorkspace.loadingWorkspace") }),
3535
- /* @__PURE__ */ jsx5("p", { className: "text-og-sm leading-5 text-og-fg-subtle", children: t("sandboxWorkspace.readingTheCurrentWorkingTree") })
3536
- ]
3537
- }
3538
- );
3539
- }
3540
- return /* @__PURE__ */ jsxs4(CenteredState, { icon: /* @__PURE__ */ jsx5(CircleCheckIcon, { className: "size-5", "aria-hidden": true }), tone: "success", children: [
3541
- /* @__PURE__ */ jsx5("p", { className: "text-og-sm font-medium text-og-fg", children: comparison === "branch" ? t("sandboxWorkspace.noBranchChanges") : comparison === "staged" ? t("sandboxWorkspace.noStagedChanges") : t("sandboxWorkspace.noUncommittedChanges") }),
3542
- /* @__PURE__ */ jsx5("p", { className: "text-og-sm leading-5 text-og-fg-subtle", children: comparison === "branch" ? t("sandboxWorkspace.thisBranchMatchesTheRemote") : comparison === "staged" ? t("sandboxWorkspace.stageFilesToReviewThe") : t("sandboxWorkspace.localEditsNotYetCommitted") })
3543
- ] });
3544
- }
3545
- function CenteredState({
3546
- children,
3547
- icon,
3548
- tone = "neutral"
3549
- }) {
3550
- return /* @__PURE__ */ jsx5(
3551
- "div",
3552
- {
3553
- role: tone === "danger" ? "alert" : "status",
3554
- "aria-atomic": "true",
3555
- "aria-live": tone === "danger" ? "assertive" : "polite",
3556
- className: "grid h-full place-items-center p-6 text-center",
3557
- children: /* @__PURE__ */ jsxs4("div", { className: "flex max-w-sm flex-col items-center gap-2.5", children: [
3558
- icon ? /* @__PURE__ */ jsx5(
3559
- "span",
3560
- {
3561
- className: cn(
3562
- "grid size-10 place-items-center rounded-og-lg border bg-og-surface-1 shadow-sm",
3563
- tone === "success" && "border-og-status-idle/30 text-og-status-idle",
3564
- tone === "danger" && "border-og-status-failed/30 text-og-status-failed",
3565
- tone === "neutral" && "border-og-border text-og-fg-muted"
3566
- ),
3567
- children: icon
3568
- }
3569
- ) : null,
3570
- children
3571
- ] })
3572
- }
3573
- );
3574
- }
3575
-
3576
- // src/hooks/use-supergrok-accounts.ts
3577
- import { useCallback as useCallback13 } from "react";
3578
- var superGrokAccountsQueryKey = (workspaceId) => ["supergrok-accounts", workspaceId];
3579
- var EMPTY = {
3580
- accounts: [],
3581
- activeAccountId: null,
3582
- settings: {
3583
- rotationEnabled: false,
3584
- rotationStrategy: "sharded",
3585
- activeCredentialId: null
3586
- }
3587
- };
3588
- function useSuperGrokAccounts(options = {}) {
3589
- const { client, workspaceId } = useOpenGeni(options);
3590
- const supergrokClient = options.supergrokClient ?? client;
3591
- const load = useCallback13(
3592
- async () => await supergrokClient.listSuperGrokAccounts(workspaceId),
3593
- [supergrokClient, workspaceId]
3594
- );
3595
- const { data, loading, refresh } = useSharedQuery(
3596
- supergrokClient,
3597
- superGrokAccountsQueryKey(workspaceId),
3598
- load,
3599
- { enabled: options.enabled, pollIntervalMs: options.pollIntervalMs }
3600
- );
3601
- const { run, mutating: activating, mutationError } = useMutationRunner();
3602
- const activate = useCallback13(
3603
- async (accountId) => {
3604
- if (!supergrokClient.activateSuperGrokAccount) return false;
3605
- const invalidated = { current: null };
3606
- const result = await run(async () => {
3607
- await supergrokClient.activateSuperGrokAccount(workspaceId, accountId);
3608
- invalidated.current = invalidateSharedQueries(supergrokClient, ["supergrok-accounts"]);
3609
- return true;
3610
- });
3611
- if (result) await invalidated.current;
3612
- return result === true;
3613
- },
3614
- [run, supergrokClient, workspaceId]
3615
- );
3616
- const state = data ?? EMPTY;
3617
- return {
3618
- accounts: state.accounts,
3619
- activeAccountId: state.activeAccountId,
3620
- settings: state.settings,
3621
- loading,
3622
- refresh,
3623
- activate,
3624
- activating,
3625
- mutationError
3626
- };
3627
- }
3628
-
3629
- export {
3630
- sessionAuthRecommendation,
3631
- SessionConnectionRequest,
3632
- useVideoArtifactPlaybackLoader,
3633
- useScheduledTasks,
3634
- useWorkspaceBackgroundCommands,
3635
- useWorkspaces,
3636
- useBillingUsage,
3637
- useSessionCapabilities,
3638
- useSandboxTerminal,
3639
- useSandboxGit,
3640
- useWorkspaceCapture,
3641
- useWorkspaceEdit,
3642
- formatAsOf,
3643
- deriveMachineChip,
3644
- useMachineChip,
3645
- sessionDisplayTitle,
3646
- FleetTile,
3647
- WorkbenchChanges,
3648
- DiffView,
3649
- WORKBENCH_TAB_CHANGES,
3650
- WORKBENCH_TAB_FILES,
3651
- WORKBENCH_TAB_TERMINAL,
3652
- WORKBENCH_TAB_BROWSER,
3653
- WORKBENCH_TAB_DESKTOP,
3654
- WORKBENCH_SURFACES,
3655
- initialWorkspaceTab,
3656
- useSandboxWorkspaceTabs,
3657
- SandboxWorkspace,
3658
- useSuperGrokAccounts,
3659
- asVaultClient,
3660
- vaultsApi,
3661
- vaultErrorCode,
3662
- vaultErrorDetail,
3663
- humanizeModelSlug,
3664
- isRawModelLabel,
3665
- modelDisplayName2 as modelDisplayName,
3666
- modelSlug,
3667
- modelVendor,
3668
- parseOpenGeniLink
3669
- };
3670
- //# sourceMappingURL=chunk-2GDNWKSC.js.map