@opengeni/react 0.57.0 → 1.0.2-canary.37191796234001

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 (629) hide show
  1. package/README.md +654 -22
  2. package/dist/accounts.d.ts +64 -0
  3. package/dist/accounts.js +822 -0
  4. package/dist/accounts.js.map +1 -0
  5. package/dist/approvals.d.ts +2 -1
  6. package/dist/artifacts-document.js +3 -2
  7. package/dist/artifacts-presentation.js +3 -2
  8. package/dist/artifacts-spreadsheet.js +2 -2
  9. package/dist/artifacts.d.ts +4 -1
  10. package/dist/artifacts.js +518 -42
  11. package/dist/artifacts.js.map +1 -1
  12. package/dist/browser-viewer-GTR5XQ7X.js +16 -0
  13. package/dist/capability-catalog-row.d.ts +20 -0
  14. package/dist/capability-logo-fallback.d.ts +3 -0
  15. package/dist/chat-interactive-block-UGBTNB3L.js +11 -0
  16. package/dist/chat-interactive-block-UGBTNB3L.js.map +1 -0
  17. package/dist/{chunk-5UQPNLIO.js → chunk-23J2ZNXT.js} +4117 -3896
  18. package/dist/chunk-23J2ZNXT.js.map +1 -0
  19. package/dist/chunk-447JLCBU.js +209 -0
  20. package/dist/chunk-447JLCBU.js.map +1 -0
  21. package/dist/chunk-4RVYOY4O.js +379 -0
  22. package/dist/chunk-4RVYOY4O.js.map +1 -0
  23. package/dist/chunk-5CVXZA3Y.js +292 -0
  24. package/dist/chunk-5CVXZA3Y.js.map +1 -0
  25. package/dist/chunk-5J4FOW6Q.js +108 -0
  26. package/dist/chunk-5J4FOW6Q.js.map +1 -0
  27. package/dist/chunk-A2PI6UMY.js +41 -0
  28. package/dist/chunk-A2PI6UMY.js.map +1 -0
  29. package/dist/{chunk-7WCLAEFV.js → chunk-A4UJB2MM.js} +37 -27
  30. package/dist/chunk-A4UJB2MM.js.map +1 -0
  31. package/dist/chunk-B3V6TG77.js +41 -0
  32. package/dist/chunk-B3V6TG77.js.map +1 -0
  33. package/dist/chunk-BRM6FVZA.js +302 -0
  34. package/dist/chunk-BRM6FVZA.js.map +1 -0
  35. package/dist/chunk-C5X5AJXK.js +182 -0
  36. package/dist/chunk-C5X5AJXK.js.map +1 -0
  37. package/dist/chunk-CR7U7HAR.js +453 -0
  38. package/dist/chunk-CR7U7HAR.js.map +1 -0
  39. package/dist/{chunk-R3AZOAB5.js → chunk-DYWBUX5Q.js} +29 -123
  40. package/dist/chunk-DYWBUX5Q.js.map +1 -0
  41. package/dist/chunk-E3G7SAYZ.js +3124 -0
  42. package/dist/chunk-E3G7SAYZ.js.map +1 -0
  43. package/dist/chunk-ELCE5SXV.js +359 -0
  44. package/dist/chunk-ELCE5SXV.js.map +1 -0
  45. package/dist/chunk-ERGYJIBB.js +21 -0
  46. package/dist/chunk-ERGYJIBB.js.map +1 -0
  47. package/dist/chunk-FFA2OVOV.js +319 -0
  48. package/dist/chunk-FFA2OVOV.js.map +1 -0
  49. package/dist/chunk-FZCP527Y.js +116 -0
  50. package/dist/chunk-FZCP527Y.js.map +1 -0
  51. package/dist/chunk-GIMRELBW.js +14 -0
  52. package/dist/chunk-GIMRELBW.js.map +1 -0
  53. package/dist/{chunk-6KLX2RH5.js → chunk-H2NJQORO.js} +1069 -79
  54. package/dist/chunk-H2NJQORO.js.map +1 -0
  55. package/dist/chunk-I7IWRQLN.js +1608 -0
  56. package/dist/chunk-I7IWRQLN.js.map +1 -0
  57. package/dist/{chunk-HA46CYQK.js → chunk-IQUCRAT7.js} +792 -537
  58. package/dist/chunk-IQUCRAT7.js.map +1 -0
  59. package/dist/chunk-IWIDV7SB.js +1 -0
  60. package/dist/chunk-IWIDV7SB.js.map +1 -0
  61. package/dist/chunk-J2QWVSQY.js +312 -0
  62. package/dist/chunk-J2QWVSQY.js.map +1 -0
  63. package/dist/chunk-JFNEV4LU.js +2733 -0
  64. package/dist/chunk-JFNEV4LU.js.map +1 -0
  65. package/dist/chunk-JT4JW7BC.js +54 -0
  66. package/dist/chunk-JT4JW7BC.js.map +1 -0
  67. package/dist/chunk-K3HQAKQX.js +24 -0
  68. package/dist/chunk-K3HQAKQX.js.map +1 -0
  69. package/dist/{chunk-C5ZPSSS5.js → chunk-NEXLLTP4.js} +2 -1
  70. package/dist/{chunk-C5ZPSSS5.js.map → chunk-NEXLLTP4.js.map} +1 -1
  71. package/dist/chunk-NZUI76EM.js +371 -0
  72. package/dist/chunk-NZUI76EM.js.map +1 -0
  73. package/dist/{chunk-PEI6RANI.js → chunk-PNY3JKBJ.js} +309 -74
  74. package/dist/chunk-PNY3JKBJ.js.map +1 -0
  75. package/dist/{chunk-IGC6A2ZI.js → chunk-Q5QBEZIQ.js} +777 -246
  76. package/dist/chunk-Q5QBEZIQ.js.map +1 -0
  77. package/dist/chunk-RHREZ7BO.js +11 -0
  78. package/dist/chunk-RHREZ7BO.js.map +1 -0
  79. package/dist/chunk-SCOTPE2I.js +589 -0
  80. package/dist/chunk-SCOTPE2I.js.map +1 -0
  81. package/dist/{chunk-B6WPZSTT.js → chunk-SJZDKVW2.js} +1331 -1163
  82. package/dist/chunk-SJZDKVW2.js.map +1 -0
  83. package/dist/chunk-TMJRG4YC.js +12803 -0
  84. package/dist/chunk-TMJRG4YC.js.map +1 -0
  85. package/dist/chunk-TMYGL6X5.js +742 -0
  86. package/dist/chunk-TMYGL6X5.js.map +1 -0
  87. package/dist/chunk-UGLEYEMP.js +33 -0
  88. package/dist/chunk-UGLEYEMP.js.map +1 -0
  89. package/dist/chunk-UK4TINKT.js +27 -0
  90. package/dist/chunk-UK4TINKT.js.map +1 -0
  91. package/dist/chunk-UTRTG6LH.js +220 -0
  92. package/dist/chunk-UTRTG6LH.js.map +1 -0
  93. package/dist/chunk-WEHMPOXK.js +39 -0
  94. package/dist/chunk-WEHMPOXK.js.map +1 -0
  95. package/dist/chunk-WRHIZYZF.js +988 -0
  96. package/dist/chunk-WRHIZYZF.js.map +1 -0
  97. package/dist/{chunk-HUIKIDM5.js → chunk-WUISZ3WU.js} +223 -115
  98. package/dist/chunk-WUISZ3WU.js.map +1 -0
  99. package/dist/chunk-XCHWDJ22.js +107 -0
  100. package/dist/chunk-XCHWDJ22.js.map +1 -0
  101. package/dist/chunk-XOAMRDDK.js +481 -0
  102. package/dist/chunk-XOAMRDDK.js.map +1 -0
  103. package/dist/chunk-XUW2UWQM.js +299 -0
  104. package/dist/chunk-XUW2UWQM.js.map +1 -0
  105. package/dist/{chunk-KCGXPP5V.js → chunk-Y2PRMYLC.js} +11 -6
  106. package/dist/chunk-Y2PRMYLC.js.map +1 -0
  107. package/dist/chunk-YBXQDQFX.js +1772 -0
  108. package/dist/chunk-YBXQDQFX.js.map +1 -0
  109. package/dist/{chunk-KZ73RL76.js → chunk-YQEAA6LT.js} +7 -3
  110. package/dist/chunk-YQEAA6LT.js.map +1 -0
  111. package/dist/chunk-YV4L3ILF.js +9 -0
  112. package/dist/chunk-YV4L3ILF.js.map +1 -0
  113. package/dist/{chunk-LLOLUHVG.js → chunk-YWFG7ZX7.js} +1358 -2746
  114. package/dist/chunk-YWFG7ZX7.js.map +1 -0
  115. package/dist/chunk-ZYRGEKWS.js +216 -0
  116. package/dist/chunk-ZYRGEKWS.js.map +1 -0
  117. package/dist/client.d.ts +7 -4
  118. package/dist/clipboard.js +1 -0
  119. package/dist/commands/types.d.ts +2 -0
  120. package/dist/components/anthropic-mark.d.ts +3 -0
  121. package/dist/components/approval-surface.d.ts +15 -0
  122. package/dist/components/artifacts/artifact-chrome.d.ts +120 -0
  123. package/dist/components/artifacts/artifact-sandbox.d.ts +27 -0
  124. package/dist/components/artifacts/artifact-surface.d.ts +3 -1
  125. package/dist/components/artifacts/chat-interactive-block.d.ts +29 -0
  126. package/dist/components/artifacts/deferred-chat-media.d.ts +15 -0
  127. package/dist/components/artifacts/document-editor.d.ts +4 -2
  128. package/dist/components/artifacts/editable-artifact-ui.d.ts +2 -1
  129. package/dist/components/artifacts/editable-artifact-view.d.ts +46 -0
  130. package/dist/components/artifacts/editable-document.d.ts +1 -1
  131. package/dist/components/artifacts/editable-presentation.d.ts +2 -2
  132. package/dist/components/artifacts/editable-spreadsheet.d.ts +2 -1
  133. package/dist/components/artifacts/index.d.ts +8 -1
  134. package/dist/components/artifacts/inline-html-document.d.ts +2 -0
  135. package/dist/components/artifacts/latest-task-runner.d.ts +15 -0
  136. package/dist/components/artifacts/presentation-editor.d.ts +6 -2
  137. package/dist/components/artifacts/published-html-artifact-frame.d.ts +48 -3
  138. package/dist/components/artifacts/session-artifact-viewer.d.ts +39 -0
  139. package/dist/components/artifacts/site-view.d.ts +23 -0
  140. package/dist/components/artifacts/spreadsheet-general-display.d.ts +24 -0
  141. package/dist/components/artifacts/visualization-assets.gen.d.ts +2 -0
  142. package/dist/components/browser-select-control.d.ts +16 -0
  143. package/dist/components/browser-viewer.d.ts +10 -1
  144. package/dist/components/chat-composer.d.ts +21 -3
  145. package/dist/components/child-session-link.d.ts +5 -0
  146. package/dist/components/claude-mark.d.ts +3 -0
  147. package/dist/components/code-editor.d.ts +1 -4
  148. package/dist/components/composer.d.ts +45 -4
  149. package/dist/components/computer-viewer.d.ts +4 -1
  150. package/dist/components/copy-button.d.ts +3 -1
  151. package/dist/components/desktop-viewer.d.ts +1 -1
  152. package/dist/components/enrollment-consent.d.ts +6 -3
  153. package/dist/components/file-browser.d.ts +10 -1
  154. package/dist/components/fleet-tile.d.ts +2 -2
  155. package/dist/components/grok-mark.d.ts +26 -0
  156. package/dist/components/human-input-form.d.ts +21 -2
  157. package/dist/components/human-input-surface.d.ts +6 -3
  158. package/dist/components/machine-card.d.ts +4 -1
  159. package/dist/components/machines/machine-detail.d.ts +4 -1
  160. package/dist/components/machines/machine-operation-policy.d.ts +11 -0
  161. package/dist/components/machines-dashboard.d.ts +3 -1
  162. package/dist/components/markdown-table-layout.d.ts +12 -0
  163. package/dist/components/markdown.d.ts +47 -3
  164. package/dist/components/message-timeline.d.ts +72 -9
  165. package/dist/components/model-mark.d.ts +29 -0
  166. package/dist/components/model-policy-picker-menu.d.ts +9 -0
  167. package/dist/components/model-policy-picker.d.ts +62 -13
  168. package/dist/components/open-geni-chat.d.ts +55 -0
  169. package/dist/components/open-geni-links.d.ts +68 -0
  170. package/dist/components/openrouter-mark.d.ts +6 -0
  171. package/dist/components/pierre-file.d.ts +1 -1
  172. package/dist/components/preview-loading.d.ts +2 -0
  173. package/dist/components/queue-item-content.d.ts +9 -0
  174. package/dist/components/sandbox-files.d.ts +13 -2
  175. package/dist/components/sandbox-workspace.d.ts +43 -3
  176. package/dist/components/session-capability-frame.d.ts +35 -0
  177. package/dist/components/session-chrome.d.ts +66 -8
  178. package/dist/components/session-commands-panel.d.ts +6 -0
  179. package/dist/components/session-commands.d.ts +6 -0
  180. package/dist/components/session-connection-request.d.ts +8 -0
  181. package/dist/components/session-conversation.d.ts +86 -0
  182. package/dist/components/session-list.d.ts +36 -0
  183. package/dist/components/session-mcp-capability-card.d.ts +41 -0
  184. package/dist/components/timeline-anchor.d.ts +24 -0
  185. package/dist/components/timeline-annotation-chrome.d.ts +25 -0
  186. package/dist/components/timeline-annotation-layout.d.ts +42 -0
  187. package/dist/components/timeline-annotation-markers.d.ts +8 -0
  188. package/dist/components/timeline-annotation-reveal-context.d.ts +4 -0
  189. package/dist/components/timeline-annotation-shared.d.ts +31 -0
  190. package/dist/components/timeline-annotations-dialog.d.ts +3 -2
  191. package/dist/components/timeline-annotations.d.ts +13 -3
  192. package/dist/components/timeline-reading-progress.d.ts +11 -0
  193. package/dist/components/timeline-search.d.ts +34 -0
  194. package/dist/components/timeline-settlement.d.ts +16 -0
  195. package/dist/components/tip-follow.d.ts +16 -0
  196. package/dist/components/usage-limit-notice.d.ts +49 -0
  197. package/dist/components/usage-member-list.d.ts +91 -0
  198. package/dist/components/usage-meter.d.ts +73 -0
  199. package/dist/components/use-viewer-menu-dismiss.d.ts +2 -0
  200. package/dist/components/user-message-body.d.ts +10 -1
  201. package/dist/components/workspace-dock.d.ts +6 -2
  202. package/dist/composer.d.ts +5 -4
  203. package/dist/composer.js +15 -9
  204. package/dist/computer-viewer-ENHVAZ2Q.js +19 -0
  205. package/dist/computer-viewer-ENHVAZ2Q.js.map +1 -0
  206. package/dist/connect-account-identity.d.ts +8 -0
  207. package/dist/connect-accounts.d.ts +15 -0
  208. package/dist/connect-chooser.d.ts +18 -0
  209. package/dist/connect-panel.d.ts +18 -0
  210. package/dist/connect-setup.d.ts +16 -0
  211. package/dist/connect.d.ts +21 -0
  212. package/dist/connect.js +2129 -0
  213. package/dist/connect.js.map +1 -0
  214. package/dist/connection-catalog.d.ts +38 -0
  215. package/dist/connection-discovery.d.ts +12 -0
  216. package/dist/connection-installed.d.ts +17 -0
  217. package/dist/connection-logo.d.ts +9 -0
  218. package/dist/connection-service-logo.d.ts +8 -0
  219. package/dist/connection-service-presentation.d.ts +13 -0
  220. package/dist/connection-skeleton.d.ts +5 -0
  221. package/dist/connection-type-picker.d.ts +6 -0
  222. package/dist/conversation-timeline.d.ts +5 -0
  223. package/dist/desktop.d.ts +7 -0
  224. package/dist/desktop.js +26 -0
  225. package/dist/desktop.js.map +1 -0
  226. package/dist/device-authorization.d.ts +23 -0
  227. package/dist/diffs.d.ts +8 -0
  228. package/dist/diffs.js +14 -0
  229. package/dist/diffs.js.map +1 -0
  230. package/dist/discovery-cache.d.ts +5 -0
  231. package/dist/editor.d.ts +7 -0
  232. package/dist/editor.js +21 -0
  233. package/dist/editor.js.map +1 -0
  234. package/dist/embedded-session-client.d.ts +23 -0
  235. package/dist/file-node-visibility.d.ts +15 -0
  236. package/dist/{fleet-decision-row-GGCAT4E4.js → fleet-decision-row-YZ3ZKWMM.js} +2 -1
  237. package/dist/fleet-decision-row-YZ3ZKWMM.js.map +1 -0
  238. package/dist/hooks/channel-cache.d.ts +23 -0
  239. package/dist/hooks/latest-question.d.ts +25 -0
  240. package/dist/hooks/shared-machines-list.d.ts +14 -0
  241. package/dist/hooks/use-attached-browsers.d.ts +2 -1
  242. package/dist/hooks/use-browser-frame-stream.d.ts +1 -1
  243. package/dist/hooks/use-browser-session.d.ts +12 -1
  244. package/dist/hooks/use-channels.d.ts +1 -0
  245. package/dist/hooks/use-codex-accounts.d.ts +25 -7
  246. package/dist/hooks/use-composer.d.ts +45 -9
  247. package/dist/hooks/use-computer-frame-stream.d.ts +1 -1
  248. package/dist/hooks/use-computer-input-posture.d.ts +13 -0
  249. package/dist/hooks/use-computer-session.d.ts +2 -0
  250. package/dist/hooks/use-connect.d.ts +22 -0
  251. package/dist/hooks/use-desktop-stream.d.ts +1 -1
  252. package/dist/hooks/use-file-attachments.d.ts +21 -2
  253. package/dist/hooks/use-machine-chip.d.ts +3 -3
  254. package/dist/hooks/use-machines.d.ts +19 -1
  255. package/dist/hooks/use-sandbox-files.d.ts +5 -1
  256. package/dist/hooks/use-session-background-commands.d.ts +14 -0
  257. package/dist/hooks/use-session-events.d.ts +30 -8
  258. package/dist/hooks/use-session-lineage.d.ts +4 -0
  259. package/dist/hooks/use-session-mcp-approval-policy.d.ts +2 -2
  260. package/dist/hooks/use-session.d.ts +6 -0
  261. package/dist/hooks/use-turn-queue.d.ts +12 -0
  262. package/dist/hooks/use-usage.d.ts +40 -0
  263. package/dist/hooks/use-workspace-edit.d.ts +4 -0
  264. package/dist/hooks/use-workspace-sessions.d.ts +27 -5
  265. package/dist/human-input.d.ts +3 -1
  266. package/dist/identity-link-accounts.d.ts +11 -0
  267. package/dist/identity-link-consent.d.ts +18 -0
  268. package/dist/index.d.ts +60 -17
  269. package/dist/index.js +2237 -6200
  270. package/dist/index.js.map +1 -1
  271. package/dist/interaction.d.ts +1 -1
  272. package/dist/interaction.js +35 -184
  273. package/dist/interaction.js.map +1 -1
  274. package/dist/latest-question-755OW5DS.js +117 -0
  275. package/dist/latest-question-755OW5DS.js.map +1 -0
  276. package/dist/lib/error-message.d.ts +7 -0
  277. package/dist/lib/format.d.ts +36 -2
  278. package/dist/lib/host-theme.d.ts +70 -0
  279. package/dist/lib/interaction-errors.d.ts +6 -0
  280. package/dist/lib/menu-styles.d.ts +22 -0
  281. package/dist/lib/pierre-diffs-loader.d.ts +20 -0
  282. package/dist/lib/workbench-peers.d.ts +36 -0
  283. package/dist/lib/xterm-theme.d.ts +7 -5
  284. package/dist/machines.d.ts +4 -2
  285. package/dist/machines.js +14 -4
  286. package/dist/markdown-table-layout-QXSLK4BY.js +106 -0
  287. package/dist/markdown-table-layout-QXSLK4BY.js.map +1 -0
  288. package/dist/mcp-connection-status.d.ts +14 -0
  289. package/dist/model-policy-picker-menu-PWRI7R2X.js +14 -0
  290. package/dist/model-policy-picker-menu-PWRI7R2X.js.map +1 -0
  291. package/dist/model-policy.d.ts +19 -3
  292. package/dist/model-policy.js +9 -1
  293. package/dist/older-history.d.ts +30 -0
  294. package/dist/platform-activity-row-627BFZ46.js +182 -0
  295. package/dist/platform-activity-row-627BFZ46.js.map +1 -0
  296. package/dist/plugin-details.d.ts +14 -0
  297. package/dist/plugin-discovery.d.ts +25 -0
  298. package/dist/provider.d.ts +13 -1
  299. package/dist/{queue-surface-implementation-2KVJTYXH.js → queue-surface-implementation-ZHFI5JBP.js} +131 -44
  300. package/dist/queue-surface-implementation-ZHFI5JBP.js.map +1 -0
  301. package/dist/realtime/realtime-control.d.ts +10 -3
  302. package/dist/realtime.js +229 -83
  303. package/dist/realtime.js.map +1 -1
  304. package/dist/sandbox-files-BBC47SLD.js +20 -0
  305. package/dist/sandbox-files-BBC47SLD.js.map +1 -0
  306. package/dist/session-auth-recommendation.d.ts +5 -0
  307. package/dist/session-capability-policy.d.ts +12 -0
  308. package/dist/session-ui.d.ts +30 -2
  309. package/dist/session-ui.js +85 -7
  310. package/dist/session-ui.js.map +1 -1
  311. package/dist/session.d.ts +8 -2
  312. package/dist/session.js +30 -19
  313. package/dist/sites-ui.d.ts +34 -0
  314. package/dist/sites.d.ts +3 -0
  315. package/dist/sites.js +11 -0
  316. package/dist/sites.js.map +1 -0
  317. package/dist/skill-discovery.d.ts +47 -0
  318. package/dist/terminal.d.ts +8 -0
  319. package/dist/terminal.js +31 -0
  320. package/dist/terminal.js.map +1 -0
  321. package/dist/timeline/activity-rail.d.ts +11 -2
  322. package/dist/timeline/allowance-exhausted-row.d.ts +24 -0
  323. package/dist/timeline/compaction-copy.d.ts +10 -0
  324. package/dist/timeline/entrance.d.ts +13 -1
  325. package/dist/timeline/genie-loading.d.ts +34 -0
  326. package/dist/timeline/index.d.ts +6 -2
  327. package/dist/timeline/knowledge-receipt.d.ts +17 -0
  328. package/dist/timeline/platform-activity-row.d.ts +14 -0
  329. package/dist/timeline/presented-image.d.ts +6 -0
  330. package/dist/timeline/projection.d.ts +31 -2
  331. package/dist/timeline/registry.d.ts +2 -0
  332. package/dist/timeline/retained-image.d.ts +18 -0
  333. package/dist/timeline/rolling-activity.d.ts +11 -0
  334. package/dist/timeline/screenshot-lightbox.d.ts +16 -1
  335. package/dist/timeline/shared.d.ts +8 -3
  336. package/dist/timeline/startup-preference.d.ts +3 -0
  337. package/dist/timeline/startup-timings.d.ts +4 -0
  338. package/dist/timeline/tool-display-name.d.ts +2 -1
  339. package/dist/timeline/turn-summary.d.ts +32 -3
  340. package/dist/timeline/types.d.ts +141 -7
  341. package/dist/timeline-annotation-markers-GNDHTGBD.js +165 -0
  342. package/dist/timeline-annotation-markers-GNDHTGBD.js.map +1 -0
  343. package/dist/timeline-annotation-selection-DMLMM2TX.js +241 -0
  344. package/dist/timeline-annotation-selection-DMLMM2TX.js.map +1 -0
  345. package/dist/timeline-annotations-dialog-ELRDBHTS.js +273 -0
  346. package/dist/timeline-annotations-dialog-ELRDBHTS.js.map +1 -0
  347. package/dist/types/machines.d.ts +2 -2
  348. package/dist/usage/allowance-copy.d.ts +25 -0
  349. package/dist/usage/summary.d.ts +35 -0
  350. package/dist/usage.d.ts +13 -0
  351. package/dist/usage.js +1074 -0
  352. package/dist/usage.js.map +1 -0
  353. package/package.json +44 -4
  354. package/src/accounts.tsx +1072 -0
  355. package/src/approvals.ts +8 -1
  356. package/src/artifacts.ts +42 -0
  357. package/src/assets/README.md +8 -0
  358. package/src/assets/gmail.ico +0 -0
  359. package/src/assets/outlook.ico +0 -0
  360. package/src/capability-catalog-row.tsx +94 -0
  361. package/src/capability-logo-fallback.ts +22 -0
  362. package/src/client.ts +22 -13
  363. package/src/commands/registry.ts +18 -15
  364. package/src/commands/types.ts +2 -0
  365. package/src/components/anthropic-mark.tsx +10 -0
  366. package/src/components/approval-surface.tsx +171 -37
  367. package/src/components/artifacts/artifact-chrome.tsx +413 -0
  368. package/src/components/artifacts/artifact-sandbox.tsx +185 -0
  369. package/src/components/artifacts/artifact-surface.tsx +39 -19
  370. package/src/components/artifacts/chat-interactive-block.tsx +260 -0
  371. package/src/components/artifacts/deferred-chat-media.tsx +67 -0
  372. package/src/components/artifacts/document-editor.tsx +141 -16
  373. package/src/components/artifacts/editable-artifact-ui.tsx +4 -2
  374. package/src/components/artifacts/editable-artifact-view.tsx +187 -0
  375. package/src/components/artifacts/editable-artifact-workbench.tsx +5 -2
  376. package/src/components/artifacts/editable-document.tsx +37 -36
  377. package/src/components/artifacts/editable-presentation.tsx +36 -18
  378. package/src/components/artifacts/editable-spreadsheet.tsx +5 -2
  379. package/src/components/artifacts/index.ts +44 -0
  380. package/src/components/artifacts/inline-html-document.ts +24 -0
  381. package/src/components/artifacts/latest-task-runner.ts +49 -0
  382. package/src/components/artifacts/presentation-editor.tsx +323 -67
  383. package/src/components/artifacts/published-html-artifact-frame.tsx +338 -5
  384. package/src/components/artifacts/session-artifact-viewer.tsx +376 -0
  385. package/src/components/artifacts/site-view.tsx +116 -0
  386. package/src/components/artifacts/spreadsheet-canvas.ts +5 -10
  387. package/src/components/artifacts/spreadsheet-general-display.ts +43 -0
  388. package/src/components/artifacts/spreadsheet-grid.tsx +12 -13
  389. package/src/components/artifacts/visualization-assets/base.css +1015 -0
  390. package/src/components/artifacts/visualization-assets/helpers.html +349 -0
  391. package/src/components/artifacts/visualization-assets.gen.ts +3 -0
  392. package/src/components/browser-select-control.tsx +312 -0
  393. package/src/components/browser-viewer.tsx +1054 -314
  394. package/src/components/chat-composer.tsx +131 -85
  395. package/src/components/child-session-link.tsx +27 -0
  396. package/src/components/claude-mark.tsx +10 -0
  397. package/src/components/code-editor.tsx +13 -16
  398. package/src/components/composer-transcription-control.tsx +7 -5
  399. package/src/components/composer.tsx +376 -49
  400. package/src/components/computer-viewer.tsx +1041 -329
  401. package/src/components/copy-button.tsx +13 -5
  402. package/src/components/desktop-viewer.tsx +1 -1
  403. package/src/components/enrollment-consent.tsx +65 -7
  404. package/src/components/enrollment-device-flow.tsx +1 -1
  405. package/src/components/file-browser.tsx +158 -34
  406. package/src/components/fleet-tile.tsx +8 -16
  407. package/src/components/generated-video-player.tsx +4 -2
  408. package/src/components/grok-mark.tsx +33 -0
  409. package/src/components/human-input-form.tsx +455 -114
  410. package/src/components/human-input-surface.tsx +18 -7
  411. package/src/components/interaction-intervention-banner.tsx +2 -2
  412. package/src/components/machine-card.tsx +119 -4
  413. package/src/components/machine-dock-bar.tsx +1 -1
  414. package/src/components/machine-input-display.ts +23 -2
  415. package/src/components/machines/machine-detail.tsx +52 -2
  416. package/src/components/machines/machine-operation-policy.tsx +179 -0
  417. package/src/components/machines-dashboard.tsx +8 -17
  418. package/src/components/markdown-table-layout.ts +132 -0
  419. package/src/components/markdown.tsx +473 -44
  420. package/src/components/message-timeline.tsx +2498 -663
  421. package/src/components/model-mark.tsx +90 -0
  422. package/src/components/model-picker.tsx +15 -4
  423. package/src/components/model-policy-picker-menu.tsx +424 -0
  424. package/src/components/model-policy-picker.tsx +337 -381
  425. package/src/components/open-geni-chat.tsx +319 -0
  426. package/src/components/open-geni-links.tsx +179 -0
  427. package/src/components/openrouter-mark.tsx +13 -0
  428. package/src/components/pierre-diff.tsx +41 -16
  429. package/src/components/pierre-file.tsx +36 -11
  430. package/src/components/preview-loading.tsx +154 -0
  431. package/src/components/queue-item-content.ts +14 -0
  432. package/src/components/queue-surface-implementation.tsx +132 -42
  433. package/src/components/queue-surface-state.tsx +3 -1
  434. package/src/components/sandbox-files.tsx +267 -35
  435. package/src/components/sandbox-terminal.tsx +48 -11
  436. package/src/components/sandbox-workspace.tsx +337 -135
  437. package/src/components/session-capability-frame.tsx +192 -0
  438. package/src/components/session-chrome.tsx +1027 -328
  439. package/src/components/session-commands-panel.tsx +126 -0
  440. package/src/components/session-commands.tsx +18 -0
  441. package/src/components/session-connection-request.tsx +97 -0
  442. package/src/components/session-conversation.tsx +512 -0
  443. package/src/components/session-list.tsx +250 -0
  444. package/src/components/session-mcp-capability-card.tsx +680 -0
  445. package/src/components/session-status.tsx +1 -1
  446. package/src/components/timeline-anchor.tsx +119 -0
  447. package/src/components/timeline-annotation-chrome.tsx +196 -0
  448. package/src/components/timeline-annotation-layout.ts +268 -0
  449. package/src/components/timeline-annotation-markers.tsx +185 -0
  450. package/src/components/timeline-annotation-reveal-context.ts +9 -0
  451. package/src/components/timeline-annotation-selection.tsx +106 -54
  452. package/src/components/timeline-annotation-shared.ts +245 -0
  453. package/src/components/timeline-annotations-dialog.tsx +185 -128
  454. package/src/components/timeline-annotations.tsx +189 -45
  455. package/src/components/timeline-reading-progress.ts +80 -0
  456. package/src/components/timeline-search.tsx +168 -0
  457. package/src/components/timeline-settlement.ts +60 -0
  458. package/src/components/tip-follow.ts +70 -7
  459. package/src/components/tooltip.tsx +38 -5
  460. package/src/components/usage-limit-notice.tsx +179 -0
  461. package/src/components/usage-member-list.tsx +792 -0
  462. package/src/components/usage-meter.tsx +382 -0
  463. package/src/components/use-viewer-menu-dismiss.ts +33 -0
  464. package/src/components/user-message-body.tsx +194 -49
  465. package/src/components/workspace-dock.tsx +141 -175
  466. package/src/composer.ts +6 -1
  467. package/src/connect-account-identity.tsx +34 -0
  468. package/src/connect-accounts.tsx +233 -0
  469. package/src/connect-chooser.tsx +336 -0
  470. package/src/connect-panel.tsx +99 -0
  471. package/src/connect-setup.tsx +307 -0
  472. package/src/connect.ts +60 -0
  473. package/src/connection-assets.d.ts +4 -0
  474. package/src/connection-catalog.tsx +162 -0
  475. package/src/connection-discovery.tsx +235 -0
  476. package/src/connection-installed.tsx +51 -0
  477. package/src/connection-logo.tsx +37 -0
  478. package/src/connection-service-logo.tsx +55 -0
  479. package/src/connection-service-presentation.ts +46 -0
  480. package/src/connection-skeleton.tsx +16 -0
  481. package/src/connection-type-picker.tsx +36 -0
  482. package/src/conversation-timeline.ts +92 -0
  483. package/src/desktop.ts +24 -0
  484. package/src/device-authorization.tsx +98 -0
  485. package/src/diffs.ts +16 -0
  486. package/src/discovery-cache.ts +42 -0
  487. package/src/editor.ts +13 -0
  488. package/src/embedded-session-client.ts +104 -0
  489. package/src/file-node-visibility.ts +66 -0
  490. package/src/hooks/channel-cache.ts +104 -0
  491. package/src/hooks/internal.ts +3 -2
  492. package/src/hooks/latest-question.ts +164 -0
  493. package/src/hooks/shared-machines-list.ts +239 -0
  494. package/src/hooks/use-attached-browsers.ts +5 -1
  495. package/src/hooks/use-available-models.ts +20 -14
  496. package/src/hooks/use-browser-frame-stream.ts +25 -3
  497. package/src/hooks/use-browser-session.ts +271 -71
  498. package/src/hooks/use-browser-sessions.ts +7 -1
  499. package/src/hooks/use-channels.ts +32 -10
  500. package/src/hooks/use-codex-accounts.ts +78 -21
  501. package/src/hooks/use-composer.ts +1034 -320
  502. package/src/hooks/use-computer-frame-stream.ts +39 -16
  503. package/src/hooks/use-computer-input-posture.ts +94 -0
  504. package/src/hooks/use-computer-session.ts +110 -32
  505. package/src/hooks/use-computer-sessions.ts +8 -1
  506. package/src/hooks/use-connect.ts +23 -0
  507. package/src/hooks/use-desktop-stream.ts +19 -28
  508. package/src/hooks/use-file-attachments.ts +118 -10
  509. package/src/hooks/use-goal.ts +36 -9
  510. package/src/hooks/use-human-input.ts +31 -4
  511. package/src/hooks/use-last-started-turn-policy.ts +15 -13
  512. package/src/hooks/use-machine-chip.ts +23 -6
  513. package/src/hooks/use-machines.ts +104 -6
  514. package/src/hooks/use-sandbox-files.ts +253 -150
  515. package/src/hooks/use-sandbox-git.ts +58 -29
  516. package/src/hooks/use-session-background-commands.ts +67 -0
  517. package/src/hooks/use-session-capabilities.ts +21 -2
  518. package/src/hooks/use-session-events.ts +759 -433
  519. package/src/hooks/use-session-lineage.ts +28 -6
  520. package/src/hooks/use-session-mcp-approval-policy.ts +13 -5
  521. package/src/hooks/use-session.ts +75 -16
  522. package/src/hooks/use-slash-commands.ts +6 -11
  523. package/src/hooks/use-turn-queue.ts +113 -13
  524. package/src/hooks/use-usage.ts +100 -0
  525. package/src/hooks/use-voice-input.ts +12 -1
  526. package/src/hooks/use-workspace-capture.ts +3 -2
  527. package/src/hooks/use-workspace-edit.ts +23 -5
  528. package/src/hooks/use-workspace-sessions.ts +99 -11
  529. package/src/human-input.ts +12 -1
  530. package/src/identity-link-accounts.tsx +148 -0
  531. package/src/identity-link-consent.tsx +192 -0
  532. package/src/index.ts +157 -12
  533. package/src/interaction.ts +1 -0
  534. package/src/lib/error-message.ts +37 -0
  535. package/src/lib/format.ts +150 -14
  536. package/src/lib/host-theme.ts +511 -0
  537. package/src/lib/interaction-errors.ts +33 -0
  538. package/src/lib/menu-styles.ts +44 -0
  539. package/src/lib/pierre-diffs-loader.ts +53 -0
  540. package/src/lib/workbench-peers.ts +62 -0
  541. package/src/lib/xterm-theme.ts +23 -21
  542. package/src/machines.ts +9 -1
  543. package/src/mcp-connection-status.ts +35 -0
  544. package/src/model-policy.ts +223 -69
  545. package/src/older-history.ts +87 -0
  546. package/src/plugin-details.tsx +185 -0
  547. package/src/plugin-discovery.tsx +196 -0
  548. package/src/provider.tsx +55 -14
  549. package/src/realtime/dropdown-menu.tsx +19 -12
  550. package/src/realtime/realtime-control.tsx +274 -60
  551. package/src/session-auth-recommendation.ts +48 -0
  552. package/src/session-capability-policy.ts +83 -0
  553. package/src/session-context.ts +1 -0
  554. package/src/session-ui.ts +66 -2
  555. package/src/session.ts +18 -1
  556. package/src/sites-ui.tsx +402 -0
  557. package/src/sites.ts +3 -0
  558. package/src/skill-discovery.tsx +208 -0
  559. package/src/terminal.ts +26 -0
  560. package/src/timeline/activity-rail.tsx +171 -80
  561. package/src/timeline/allowance-exhausted-row.tsx +86 -0
  562. package/src/timeline/compaction-copy.ts +42 -0
  563. package/src/timeline/entrance.tsx +28 -3
  564. package/src/timeline/fleet-decision-projection.ts +2 -1
  565. package/src/timeline/fleet-decision-row.tsx +1 -0
  566. package/src/timeline/genie-loading.tsx +136 -0
  567. package/src/timeline/index.ts +11 -0
  568. package/src/timeline/knowledge-receipt.tsx +100 -0
  569. package/src/timeline/parsers.ts +2 -2
  570. package/src/timeline/platform-activity-row.tsx +216 -0
  571. package/src/timeline/presented-image.ts +49 -0
  572. package/src/timeline/projection.ts +1600 -84
  573. package/src/timeline/registry.ts +15 -3
  574. package/src/timeline/retained-image.ts +97 -0
  575. package/src/timeline/rolling-activity.tsx +92 -0
  576. package/src/timeline/screenshot-lightbox.tsx +115 -17
  577. package/src/timeline/shared.tsx +47 -15
  578. package/src/timeline/startup-preference.ts +33 -0
  579. package/src/timeline/startup-timings.tsx +145 -0
  580. package/src/timeline/tool-display-name.ts +8 -6
  581. package/src/timeline/tool-renderers.tsx +497 -128
  582. package/src/timeline/turn-summary.tsx +208 -44
  583. package/src/timeline/types.ts +186 -7
  584. package/src/types/machines.ts +10 -0
  585. package/src/usage/allowance-copy.ts +64 -0
  586. package/src/usage/summary.ts +93 -0
  587. package/src/usage.ts +50 -0
  588. package/styles/compiled.css +2098 -757
  589. package/styles/connect.css +284 -0
  590. package/styles/connect.d.ts +1 -0
  591. package/styles/effective-tokens.css +1 -0
  592. package/styles/index.css +201 -9
  593. package/styles/responsive.css +27 -1
  594. package/styles/session-capability.css +44 -0
  595. package/styles/tokens.css +135 -65
  596. package/dist/chunk-5UQPNLIO.js.map +0 -1
  597. package/dist/chunk-6KLX2RH5.js.map +0 -1
  598. package/dist/chunk-7WCLAEFV.js.map +0 -1
  599. package/dist/chunk-B6WPZSTT.js.map +0 -1
  600. package/dist/chunk-FK6VG4LL.js +0 -90
  601. package/dist/chunk-FK6VG4LL.js.map +0 -1
  602. package/dist/chunk-HA46CYQK.js.map +0 -1
  603. package/dist/chunk-HUIKIDM5.js.map +0 -1
  604. package/dist/chunk-IGC6A2ZI.js.map +0 -1
  605. package/dist/chunk-KCGXPP5V.js.map +0 -1
  606. package/dist/chunk-KZ73RL76.js.map +0 -1
  607. package/dist/chunk-LAKLF4PA.js +0 -141
  608. package/dist/chunk-LAKLF4PA.js.map +0 -1
  609. package/dist/chunk-LLOLUHVG.js.map +0 -1
  610. package/dist/chunk-MKPIAGVL.js +0 -465
  611. package/dist/chunk-MKPIAGVL.js.map +0 -1
  612. package/dist/chunk-PEI6RANI.js.map +0 -1
  613. package/dist/chunk-R3AZOAB5.js.map +0 -1
  614. package/dist/chunk-WSK7G5LE.js +0 -170
  615. package/dist/chunk-WSK7G5LE.js.map +0 -1
  616. package/dist/chunk-XBZWOM2K.js +0 -218
  617. package/dist/chunk-XBZWOM2K.js.map +0 -1
  618. package/dist/chunk-Y7OEDUJ5.js +0 -8810
  619. package/dist/chunk-Y7OEDUJ5.js.map +0 -1
  620. package/dist/fleet-decision-row-GGCAT4E4.js.map +0 -1
  621. package/dist/hooks/use-packs.d.ts +0 -32
  622. package/dist/interactive-workbench-viewers-TOHBXJEE.js +0 -15
  623. package/dist/queue-surface-implementation-2KVJTYXH.js.map +0 -1
  624. package/dist/timeline-annotation-selection-3L7LHGG2.js +0 -187
  625. package/dist/timeline-annotation-selection-3L7LHGG2.js.map +0 -1
  626. package/dist/timeline-annotations-dialog-U7EVLR75.js +0 -196
  627. package/dist/timeline-annotations-dialog-U7EVLR75.js.map +0 -1
  628. package/src/hooks/use-packs.ts +0 -157
  629. /package/dist/{interactive-workbench-viewers-TOHBXJEE.js.map → browser-viewer-GTR5XQ7X.js.map} +0 -0
@@ -16,12 +16,31 @@ import {
16
16
  type EmbeddedBrowserInteractionClientOverride,
17
17
  useEmbeddedBrowserInteraction,
18
18
  } from "../session-context";
19
+ import { isNonRetryableInteractionError } from "../lib/interaction-errors";
19
20
  import { usePageLiveActivity } from "./internal";
20
21
 
22
+ /** Immutable input fence; queued actions never need the encoded screenshot. */
23
+ export type BrowserFrameInputFence = Pick<
24
+ BrowserFrame,
25
+ | "browserSessionId"
26
+ | "controllerGeneration"
27
+ | "targetId"
28
+ | "targetGeneration"
29
+ | "documentGeneration"
30
+ | "frameId"
31
+ >;
32
+
33
+ export type BrowserInputFailure = Pick<BrowserActionReceipt, "operationId" | "error"> & {
34
+ state: Exclude<BrowserActionReceipt["state"], "completed">;
35
+ };
36
+
21
37
  export type UseBrowserSessionOptions = EmbeddedBrowserInteractionClientOverride & {
22
38
  browserSessionId: string | null;
23
39
  enabled?: boolean | undefined;
24
40
  pollIntervalMs?: number | undefined;
41
+ /** Keep session/tab inventory current without repeatedly fetching the full
42
+ * accessibility tree while a live frame is available or the viewer is hidden. */
43
+ semanticObservationEnabled?: boolean | undefined;
25
44
  };
26
45
 
27
46
  export type UseBrowserSessionResult = {
@@ -32,7 +51,13 @@ export type UseBrowserSessionResult = {
32
51
  loading: boolean;
33
52
  mutating: boolean;
34
53
  error: Error | null;
54
+ inputFailure: BrowserInputFailure | null;
35
55
  refresh: () => Promise<void>;
56
+ observeForInput: () => Promise<BrowserObservation>;
57
+ actFromObservation: (
58
+ action: BrowserAction,
59
+ observation: BrowserObservation,
60
+ ) => Promise<BrowserActionReceipt>;
36
61
  selectTarget: (targetId: string) => Promise<BrowserTarget>;
37
62
  openTarget: (url?: string) => Promise<BrowserTarget>;
38
63
  closeTarget: (targetId: string) => Promise<void>;
@@ -44,8 +69,9 @@ export type UseBrowserSessionResult = {
44
69
  * the controller fence instead of targeting a newer page. */
45
70
  actFromFrame: (
46
71
  action: BrowserAction | BrowserActionBatch,
47
- frame: BrowserFrame,
72
+ frame: BrowserFrameInputFence,
48
73
  operationId?: string,
74
+ observationMode?: "none" | "input",
49
75
  ) => Promise<BrowserActionReceipt>;
50
76
  readClipboard: () => Promise<BrowserClipboard>;
51
77
  diagnostics: (options?: BrowserDiagnosticsOptions) => Promise<BrowserDiagnosticBatch>;
@@ -57,6 +83,13 @@ export function useBrowserSession(options: UseBrowserSessionOptions): UseBrowser
57
83
  const { client, workspaceId } = useEmbeddedBrowserInteraction(options);
58
84
  const browserSessionId = options.browserSessionId;
59
85
  const enabled = (options.enabled ?? true) && browserSessionId !== null;
86
+ const semanticObservationEnabled = options.semanticObservationEnabled ?? true;
87
+ const semanticObservationEnabledRef = useRef(semanticObservationEnabled);
88
+ semanticObservationEnabledRef.current = semanticObservationEnabled;
89
+ const previousSemanticObservationRef = useRef({
90
+ browserSessionId,
91
+ enabled: semanticObservationEnabled,
92
+ });
60
93
  const pageLive = usePageLiveActivity();
61
94
  const pollIntervalMs = Math.max(750, options.pollIntervalMs ?? 2_000);
62
95
  const [state, setState] = useState<{
@@ -68,15 +101,25 @@ export function useBrowserSession(options: UseBrowserSessionOptions): UseBrowser
68
101
  loading: boolean;
69
102
  mutating: boolean;
70
103
  error: Error | null;
104
+ inputFailure: BrowserInputFailure | null;
71
105
  }>(() => emptyState(browserSessionId, enabled));
72
106
  const visible =
73
107
  state.browserSessionId === browserSessionId ? state : emptyState(browserSessionId, enabled);
108
+ const refreshBlocked = isNonRetryableInteractionError(visible.error);
109
+ const inputFailureRef = useRef(visible.inputFailure);
110
+ inputFailureRef.current = visible.inputFailure;
74
111
  const selectedTargetIdRef = useRef<string | null>(visible.selectedTargetId);
75
112
  selectedTargetIdRef.current = visible.selectedTargetId;
113
+ const selectedTargetRef = useRef<BrowserTarget | null>(
114
+ visible.targets.find((target) => target.id === visible.selectedTargetId) ?? null,
115
+ );
116
+ selectedTargetRef.current =
117
+ visible.targets.find((target) => target.id === visible.selectedTargetId) ?? null;
76
118
  const observationRef = useRef<{
77
119
  browserSessionId: string | null;
78
120
  observation: BrowserObservation | null;
79
121
  }>({ browserSessionId, observation: visible.observation });
122
+ const lastObservationAtRef = useRef(0);
80
123
  if (observationRef.current.browserSessionId !== browserSessionId) {
81
124
  observationRef.current = {
82
125
  browserSessionId,
@@ -104,77 +147,133 @@ export function useBrowserSession(options: UseBrowserSessionOptions): UseBrowser
104
147
  requestRef.current = { id, controller: null };
105
148
  }, []);
106
149
 
107
- const refresh = useCallback(async (): Promise<void> => {
108
- if (!enabled || !browserSessionId) return;
109
- const id = requestRef.current.id + 1;
110
- requestRef.current.controller?.abort();
111
- const controller = new AbortController();
112
- requestRef.current = { id, controller };
113
- try {
114
- const [session, targetResponse] = await Promise.all([
115
- client.getBrowserSession(workspaceId, browserSessionId, {
116
- signal: controller.signal,
117
- }),
118
- client.listBrowserTargets(workspaceId, browserSessionId, {
119
- signal: controller.signal,
120
- }),
121
- ]);
122
- if (!mountedRef.current || requestRef.current.id !== id) return;
123
- const selected = chooseTarget(targetResponse.targets, selectedTargetIdRef.current);
124
- selectedTargetIdRef.current = selected?.id ?? null;
125
- observationRef.current = { browserSessionId, observation: null };
126
- setState((current) =>
127
- current.browserSessionId === browserSessionId
128
- ? {
129
- ...current,
130
- session,
131
- targets: targetResponse.targets,
132
- selectedTargetId: selected?.id ?? null,
133
- observation: null,
134
- loading: false,
135
- error: null,
136
- }
137
- : current,
138
- );
139
- if (!selected) return;
150
+ const refreshInventory = useCallback(
151
+ async (checkInput = false) => {
152
+ if (!enabled || !browserSessionId) return;
153
+ const checkedInputFailure = inputFailureRef.current;
154
+ const id = requestRef.current.id + 1;
155
+ requestRef.current.controller?.abort();
156
+ const controller = new AbortController();
157
+ requestRef.current = { id, controller };
140
158
  try {
141
- const observation = await client.observeBrowserTarget(
142
- workspaceId,
143
- browserSessionId,
144
- selected.id,
145
- { signal: controller.signal },
146
- );
159
+ const [session, targetResponse] = await Promise.all([
160
+ client.getBrowserSession(workspaceId, browserSessionId, {
161
+ signal: controller.signal,
162
+ }),
163
+ client.listBrowserTargets(workspaceId, browserSessionId, {
164
+ signal: controller.signal,
165
+ }),
166
+ ]);
147
167
  if (!mountedRef.current || requestRef.current.id !== id) return;
148
- observationRef.current = { browserSessionId, observation };
168
+ const selected = chooseTarget(targetResponse.targets, selectedTargetIdRef.current);
169
+ selectedTargetIdRef.current = selected?.id ?? null;
170
+ const previousObservation =
171
+ observationRef.current.browserSessionId === browserSessionId
172
+ ? observationRef.current.observation
173
+ : null;
174
+ const retainedObservation =
175
+ selected && previousObservation && sameObservationTarget(previousObservation, selected)
176
+ ? previousObservation
177
+ : null;
178
+ observationRef.current = { browserSessionId, observation: retainedObservation };
149
179
  setState((current) =>
150
- current.browserSessionId === browserSessionId &&
151
- current.selectedTargetId === observation.target.id
152
- ? { ...current, observation }
180
+ current.browserSessionId === browserSessionId
181
+ ? {
182
+ ...current,
183
+ session,
184
+ targets: targetResponse.targets,
185
+ selectedTargetId: selected?.id ?? null,
186
+ observation: retainedObservation,
187
+ loading: false,
188
+ error: null,
189
+ // Media and background polling cannot confirm an input outcome.
190
+ // Only an explicit fresh check clears the notice it began with.
191
+ inputFailure:
192
+ checkInput &&
193
+ session.id === browserSessionId &&
194
+ targetResponse.browserSessionId === browserSessionId &&
195
+ current.inputFailure === checkedInputFailure
196
+ ? null
197
+ : current.inputFailure,
198
+ }
153
199
  : current,
154
200
  );
201
+ if (!selected || !semanticObservationEnabledRef.current) return;
202
+ try {
203
+ const observation = await client.observeBrowserTarget(
204
+ workspaceId,
205
+ browserSessionId,
206
+ selected.id,
207
+ { signal: controller.signal },
208
+ );
209
+ if (!mountedRef.current || requestRef.current.id !== id) return;
210
+ observationRef.current = { browserSessionId, observation };
211
+ lastObservationAtRef.current = Date.now();
212
+ setState((current) =>
213
+ current.browserSessionId === browserSessionId &&
214
+ current.selectedTargetId === observation.target.id
215
+ ? { ...current, observation }
216
+ : current,
217
+ );
218
+ } catch (cause) {
219
+ if (controller.signal.aborted || !mountedRef.current || requestRef.current.id !== id)
220
+ return;
221
+ // Target inventory and the media plane remain authoritative for the
222
+ // human-facing browser. A failed semantic snapshot must not blank or
223
+ // disable an otherwise live visual browser.
224
+ void cause;
225
+ }
155
226
  } catch (cause) {
156
227
  if (controller.signal.aborted || !mountedRef.current || requestRef.current.id !== id)
157
228
  return;
158
- // Target inventory and the media plane remain authoritative for the
159
- // human-facing browser. A failed semantic snapshot must not blank or
160
- // disable an otherwise live visual browser.
161
- void cause;
229
+ setState((current) =>
230
+ current.browserSessionId === browserSessionId
231
+ ? {
232
+ ...current,
233
+ loading: false,
234
+ error: cause instanceof Error ? cause : new Error(String(cause)),
235
+ }
236
+ : current,
237
+ );
238
+ } finally {
239
+ if (requestRef.current.id === id) {
240
+ requestRef.current = { id, controller: null };
241
+ }
162
242
  }
163
- } catch (cause) {
164
- if (controller.signal.aborted || !mountedRef.current || requestRef.current.id !== id) return;
243
+ },
244
+ [browserSessionId, client, enabled, workspaceId],
245
+ );
246
+
247
+ const refresh = useCallback(async () => await refreshInventory(true), [refreshInventory]);
248
+
249
+ const refreshSemantic = useCallback(async (): Promise<void> => {
250
+ if (!enabled || !browserSessionId) return;
251
+ const target = selectedTargetRef.current;
252
+ if (!target) return;
253
+ const id = requestRef.current.id + 1;
254
+ requestRef.current.controller?.abort();
255
+ const controller = new AbortController();
256
+ requestRef.current = { id, controller };
257
+ try {
258
+ const observation = await client.observeBrowserTarget(
259
+ workspaceId,
260
+ browserSessionId,
261
+ target.id,
262
+ { signal: controller.signal },
263
+ );
264
+ if (!mountedRef.current || requestRef.current.id !== id) return;
265
+ if (!sameObservationTarget(observation, selectedTargetRef.current)) return;
266
+ observationRef.current = { browserSessionId, observation };
267
+ lastObservationAtRef.current = Date.now();
165
268
  setState((current) =>
166
- current.browserSessionId === browserSessionId
167
- ? {
168
- ...current,
169
- loading: false,
170
- error: cause instanceof Error ? cause : new Error(String(cause)),
171
- }
269
+ current.browserSessionId === browserSessionId && current.selectedTargetId === target.id
270
+ ? { ...current, observation }
172
271
  : current,
173
272
  );
273
+ } catch {
274
+ // A failed semantic fallback cannot disable an otherwise live browser.
174
275
  } finally {
175
- if (requestRef.current.id === id) {
176
- requestRef.current = { id, controller: null };
177
- }
276
+ if (requestRef.current.id === id) requestRef.current = { id, controller: null };
178
277
  }
179
278
  }, [browserSessionId, client, enabled, workspaceId]);
180
279
 
@@ -190,27 +289,58 @@ export function useBrowserSession(options: UseBrowserSessionOptions): UseBrowser
190
289
  ? { ...current, loading: true }
191
290
  : emptyState(browserSessionId, true),
192
291
  );
193
- void refresh();
292
+ void refreshInventory();
194
293
  return () => {
195
294
  mountedRef.current = false;
196
295
  invalidateRefresh();
197
296
  };
198
- }, [browserSessionId, enabled, invalidateRefresh, refresh]);
297
+ }, [browserSessionId, enabled, invalidateRefresh, refreshInventory]);
298
+
299
+ useEffect(() => {
300
+ const previous = previousSemanticObservationRef.current;
301
+ previousSemanticObservationRef.current = {
302
+ browserSessionId,
303
+ enabled: semanticObservationEnabled,
304
+ };
305
+ if (
306
+ enabled &&
307
+ semanticObservationEnabled &&
308
+ previous.browserSessionId === browserSessionId &&
309
+ !previous.enabled
310
+ ) {
311
+ // The media stream disappeared or the user returned to the Browser tab.
312
+ // A just-returned action/tab observation is already a fresh fallback.
313
+ // Otherwise drop the old tree/fence until a new read settles.
314
+ const currentObservation = observationRef.current.observation;
315
+ if (
316
+ currentObservation &&
317
+ sameObservationTarget(currentObservation, selectedTargetRef.current) &&
318
+ Date.now() - lastObservationAtRef.current < pollIntervalMs
319
+ ) {
320
+ return;
321
+ }
322
+ observationRef.current = { browserSessionId, observation: null };
323
+ setState((current) =>
324
+ current.browserSessionId === browserSessionId ? { ...current, observation: null } : current,
325
+ );
326
+ void refreshSemantic();
327
+ }
328
+ }, [browserSessionId, enabled, pollIntervalMs, refreshSemantic, semanticObservationEnabled]);
199
329
 
200
330
  useEffect(() => {
201
- if (!enabled || !pageLive || visible.mutating) return;
331
+ if (!enabled || !pageLive || visible.mutating || refreshBlocked) return;
202
332
  const timer = setInterval(() => {
203
- if (!requestRef.current.controller) void refresh();
333
+ if (!requestRef.current.controller) void refreshInventory();
204
334
  }, pollIntervalMs);
205
335
  return () => clearInterval(timer);
206
- }, [enabled, pageLive, pollIntervalMs, refresh, visible.mutating]);
336
+ }, [enabled, pageLive, pollIntervalMs, refreshInventory, refreshBlocked, visible.mutating]);
207
337
 
208
338
  useEffect(() => {
209
- if (!enabled || !browserSessionId || !pageLive) return;
339
+ if (!enabled || !browserSessionId || !pageLive || refreshBlocked) return;
210
340
  let disposed = false;
211
341
  const heartbeat = () => {
212
342
  void client.heartbeatBrowserSession(workspaceId, browserSessionId).catch(() => {
213
- if (!disposed) void refresh();
343
+ if (!disposed) void refreshInventory();
214
344
  });
215
345
  };
216
346
  const timer = setInterval(heartbeat, 30_000);
@@ -218,7 +348,7 @@ export function useBrowserSession(options: UseBrowserSessionOptions): UseBrowser
218
348
  disposed = true;
219
349
  clearInterval(timer);
220
350
  };
221
- }, [browserSessionId, client, enabled, pageLive, refresh, workspaceId]);
351
+ }, [browserSessionId, client, enabled, pageLive, refreshInventory, refreshBlocked, workspaceId]);
222
352
 
223
353
  const runMutation = useCallback(
224
354
  async <T>(scopeBrowserSessionId: string, operation: () => Promise<T>): Promise<T> => {
@@ -299,6 +429,7 @@ export function useBrowserSession(options: UseBrowserSessionOptions): UseBrowser
299
429
  }
300
430
  selectedTargetIdRef.current = target.id;
301
431
  observationRef.current = { browserSessionId, observation };
432
+ lastObservationAtRef.current = Date.now();
302
433
  setState((current) =>
303
434
  current.browserSessionId === browserSessionId
304
435
  ? {
@@ -330,6 +461,7 @@ export function useBrowserSession(options: UseBrowserSessionOptions): UseBrowser
330
461
  const target = observation.target;
331
462
  selectedTargetIdRef.current = target.id;
332
463
  observationRef.current = { browserSessionId, observation };
464
+ lastObservationAtRef.current = Date.now();
333
465
  setState((current) =>
334
466
  current.browserSessionId === browserSessionId
335
467
  ? {
@@ -363,6 +495,7 @@ export function useBrowserSession(options: UseBrowserSessionOptions): UseBrowser
363
495
  : null;
364
496
  selectedTargetIdRef.current = selected?.id ?? null;
365
497
  observationRef.current = { browserSessionId, observation };
498
+ if (observation) lastObservationAtRef.current = Date.now();
366
499
  setState((current) =>
367
500
  current.browserSessionId === browserSessionId
368
501
  ? {
@@ -382,7 +515,13 @@ export function useBrowserSession(options: UseBrowserSessionOptions): UseBrowser
382
515
  async (
383
516
  action: BrowserAction | BrowserActionBatch,
384
517
  operationId: string,
385
- frame: BrowserFrame | null,
518
+ frame:
519
+ | (Pick<BrowserFrame, "browserSessionId" | "targetId" | "targetGeneration"> & {
520
+ frameId: string | null;
521
+ documentGeneration: string | null;
522
+ })
523
+ | null,
524
+ observationMode: "none" | "input" = "none",
386
525
  ): Promise<BrowserActionReceipt> => {
387
526
  if (!browserSessionId) throw new Error("No BrowserSession is selected.");
388
527
  if (frame && frame.browserSessionId !== browserSessionId) {
@@ -414,14 +553,25 @@ export function useBrowserSession(options: UseBrowserSessionOptions): UseBrowser
414
553
  const receipt = await client.actInBrowser(workspaceId, browserSessionId, {
415
554
  operationId,
416
555
  ...fence,
417
- observationMode: "none",
556
+ observationMode,
418
557
  action,
419
558
  });
559
+ if (receipt.state !== "completed") {
560
+ const inputFailure: BrowserInputFailure = {
561
+ operationId: receipt.operationId,
562
+ state: receipt.state,
563
+ error: receipt.error,
564
+ };
565
+ setState((current) =>
566
+ current.browserSessionId === browserSessionId ? { ...current, inputFailure } : current,
567
+ );
568
+ }
420
569
  if (receipt.observation) {
421
570
  observationRef.current = {
422
571
  browserSessionId,
423
572
  observation: receipt.observation,
424
573
  };
574
+ lastObservationAtRef.current = Date.now();
425
575
  setState((current) =>
426
576
  current.browserSessionId === browserSessionId
427
577
  ? {
@@ -455,9 +605,41 @@ export function useBrowserSession(options: UseBrowserSessionOptions): UseBrowser
455
605
  const actFromFrame = useCallback(
456
606
  async (
457
607
  action: BrowserAction | BrowserActionBatch,
458
- frame: BrowserFrame,
608
+ frame: BrowserFrameInputFence,
459
609
  operationId: string = crypto.randomUUID(),
460
- ): Promise<BrowserActionReceipt> => await dispatchAction(action, operationId, frame),
610
+ observationMode: "none" | "input" = "none",
611
+ ): Promise<BrowserActionReceipt> =>
612
+ await dispatchAction(action, operationId, frame, observationMode),
613
+ [dispatchAction],
614
+ );
615
+
616
+ const observeForInput = useCallback(async (): Promise<BrowserObservation> => {
617
+ const target = selectedTargetRef.current;
618
+ if (!browserSessionId || !target) throw new Error("No browser tab is selected.");
619
+ const observation = await client.observeBrowserTarget(workspaceId, browserSessionId, target.id);
620
+ if (
621
+ !mountedRef.current ||
622
+ observation.browserSessionId !== browserSessionId ||
623
+ !sameObservationTarget(observation, selectedTargetRef.current)
624
+ ) {
625
+ throw new Error("The browser page changed. Open the options again.");
626
+ }
627
+ return observation;
628
+ }, [browserSessionId, client, workspaceId]);
629
+
630
+ const actFromObservation = useCallback(
631
+ async (action: BrowserAction, observation: BrowserObservation) => {
632
+ if (!sameObservationTarget(observation, selectedTargetRef.current)) {
633
+ throw new Error("The browser page changed. Open the options again.");
634
+ }
635
+ return await dispatchAction(action, crypto.randomUUID(), {
636
+ browserSessionId: observation.browserSessionId,
637
+ targetId: observation.target.id,
638
+ targetGeneration: observation.target.targetGeneration,
639
+ documentGeneration: observation.target.documentGeneration,
640
+ frameId: observation.frameId,
641
+ });
642
+ },
461
643
  [dispatchAction],
462
644
  );
463
645
 
@@ -495,7 +677,10 @@ export function useBrowserSession(options: UseBrowserSessionOptions): UseBrowser
495
677
  loading: visible.loading,
496
678
  mutating: visible.mutating,
497
679
  error: visible.error,
680
+ inputFailure: visible.inputFailure,
498
681
  refresh,
682
+ observeForInput,
683
+ actFromObservation,
499
684
  selectTarget,
500
685
  openTarget,
501
686
  closeTarget,
@@ -516,6 +701,7 @@ function emptyState(browserSessionId: string | null, loading: boolean) {
516
701
  loading,
517
702
  mutating: false,
518
703
  error: null as Error | null,
704
+ inputFailure: null as BrowserInputFailure | null,
519
705
  };
520
706
  }
521
707
 
@@ -538,6 +724,20 @@ function replaceTarget(targets: readonly BrowserTarget[], target: BrowserTarget)
538
724
  return next.sort((left, right) => left.createdAt.localeCompare(right.createdAt));
539
725
  }
540
726
 
727
+ function sameObservationTarget(
728
+ observation: BrowserObservation,
729
+ target: BrowserTarget | null,
730
+ ): boolean {
731
+ return (
732
+ target !== null &&
733
+ observation.browserSessionId === target.browserSessionId &&
734
+ observation.target.id === target.id &&
735
+ observation.target.controllerGeneration === target.controllerGeneration &&
736
+ observation.target.targetGeneration === target.targetGeneration &&
737
+ observation.target.documentGeneration === target.documentGeneration
738
+ );
739
+ }
740
+
541
741
  function isMissingBrowserTarget(error: unknown): boolean {
542
742
  return error instanceof OpenGeniApiError && error.code === "target_not_found";
543
743
  }
@@ -60,6 +60,7 @@ export function useBrowserSessions(
60
60
  const enabled = options.enabled ?? true;
61
61
  const [state, setState] = useState<{
62
62
  workspaceId: string;
63
+ active: boolean;
63
64
  revision: number;
64
65
  sessions: BrowserSession[];
65
66
  loading: boolean;
@@ -89,6 +90,7 @@ export function useBrowserSessions(
89
90
  requestRef.current = { id, controller };
90
91
  setState((current) => ({
91
92
  ...(current.workspaceId === workspaceId ? current : emptyState(workspaceId, true)),
93
+ active: true,
92
94
  loading: foreground,
93
95
  refreshing: !foreground,
94
96
  error: foreground || current.workspaceId !== workspaceId ? null : current.error,
@@ -100,6 +102,7 @@ export function useBrowserSessions(
100
102
  if (!mountedRef.current || requestRef.current.id !== id) return;
101
103
  setState({
102
104
  workspaceId,
105
+ active: true,
103
106
  revision: response.revision,
104
107
  sessions: sortBrowserSessions(response.sessions),
105
108
  loading: false,
@@ -229,7 +232,9 @@ export function useBrowserSessions(
229
232
  revision: visibleState.revision,
230
233
  sessions: visibleState.sessions,
231
234
  relevantSessions,
232
- loading: visibleState.loading,
235
+ // A disabled registry is deliberately empty. Expose the first re-enabled
236
+ // render as loading so consumers do not reconcile against that empty gap.
237
+ loading: enabled ? !visibleState.active || visibleState.loading : false,
233
238
  refreshing: visibleState.refreshing,
234
239
  error: visibleState.error,
235
240
  refresh,
@@ -243,6 +248,7 @@ export function useBrowserSessions(
243
248
  function emptyState(workspaceId: string, loading: boolean) {
244
249
  return {
245
250
  workspaceId,
251
+ active: false,
246
252
  revision: 0,
247
253
  sessions: [] as BrowserSession[],
248
254
  loading,
@@ -1,6 +1,7 @@
1
1
  import type { Channel, CreateChannelRequest, Session, UpdateChannelRequest } from "@opengeni/sdk";
2
- import { useCallback } from "react";
2
+ import { useCallback, useMemo, useSyncExternalStore } from "react";
3
3
  import { useOpenGeni, type ClientOverride } from "../provider";
4
+ import { channelCacheFor } from "./channel-cache";
4
5
  import { useMutationRunner, usePolledValue } from "./internal";
5
6
 
6
7
  export type UseChannelsOptions = ClientOverride & {
@@ -15,6 +16,7 @@ export type UseChannelsResult = {
15
16
  refresh: () => Promise<void>;
16
17
  create: (request: CreateChannelRequest) => Promise<Channel | null>;
17
18
  update: (channelId: string, request: UpdateChannelRequest) => Promise<Channel | null>;
19
+ reorder: (channelIds: string[]) => Promise<Channel[] | null>;
18
20
  remove: (channelId: string) => Promise<boolean>;
19
21
  /** Re-file a session into a channel; null moves it back to the inbox. */
20
22
  moveSession: (sessionId: string, channelId: string | null) => Promise<Session | null>;
@@ -30,25 +32,33 @@ export type UseChannelsResult = {
30
32
  */
31
33
  export function useChannels(options: UseChannelsOptions = {}): UseChannelsResult {
32
34
  const { client, workspaceId } = useOpenGeni(options);
33
- const load = useCallback(
34
- async () => await client.listChannels(workspaceId),
35
- [client, workspaceId],
36
- );
37
- const { data, loading, error, refresh } = usePolledValue(load, {
35
+ const cache = useMemo(() => channelCacheFor(client, workspaceId), [client, workspaceId]);
36
+ const snapshot = useSyncExternalStore(cache.subscribe, cache.getSnapshot, cache.getSnapshot);
37
+ const load = useCallback(async () => {
38
+ const ticket = cache.beginLoad();
39
+ const channels = await client.listChannels(workspaceId);
40
+ cache.acceptLoad(ticket, channels);
41
+ return channels;
42
+ }, [cache, client, workspaceId]);
43
+ const { loading, error, refresh } = usePolledValue(load, {
38
44
  pollIntervalMs: options.pollIntervalMs,
39
45
  enabled: options.enabled,
40
46
  });
41
- const { run, mutating, mutationError, clearMutationError } = useMutationRunner();
47
+ const { run, mutating, mutationError, clearMutationError } = useMutationRunner(cache);
42
48
 
43
49
  const create = useCallback(
44
50
  async (request: CreateChannelRequest): Promise<Channel | null> => {
45
51
  const result = await run(() => client.createChannel(workspaceId, request));
46
52
  if (result) {
53
+ // Publish the canonical write response before this promise can resolve.
54
+ // The composer may create a session with this id immediately, while a
55
+ // sibling rail hook could still have an older list request in flight.
56
+ cache.publishCreated(result);
47
57
  await refresh();
48
58
  }
49
59
  return result;
50
60
  },
51
- [client, workspaceId, run, refresh],
61
+ [cache, client, workspaceId, run, refresh],
52
62
  );
53
63
 
54
64
  const update = useCallback(
@@ -76,6 +86,15 @@ export function useChannels(options: UseChannelsOptions = {}): UseChannelsResult
76
86
  [client, workspaceId, run, refresh],
77
87
  );
78
88
 
89
+ const reorder = useCallback(
90
+ async (channelIds: string[]): Promise<Channel[] | null> => {
91
+ const result = await run(() => client.reorderChannels(workspaceId, { channelIds }));
92
+ if (result) await refresh();
93
+ return result;
94
+ },
95
+ [client, workspaceId, run, refresh],
96
+ );
97
+
79
98
  const moveSession = useCallback(
80
99
  async (sessionId: string, channelId: string | null): Promise<Session | null> => {
81
100
  return await run(() => client.updateSessionChannel(workspaceId, sessionId, { channelId }));
@@ -84,12 +103,15 @@ export function useChannels(options: UseChannelsOptions = {}): UseChannelsResult
84
103
  );
85
104
 
86
105
  return {
87
- channels: data ?? [],
88
- loading,
106
+ // Cache snapshots replace arrays instead of mutating them, so preserve the
107
+ // stable reference expected from the previous polled-value implementation.
108
+ channels: snapshot.channels as Channel[],
109
+ loading: loading && !snapshot.ready,
89
110
  error,
90
111
  refresh,
91
112
  create,
92
113
  update,
114
+ reorder,
93
115
  remove,
94
116
  moveSession,
95
117
  mutating,