@opengeni/react 1.0.1 → 1.0.2-canary.37202341988001

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 (632) hide show
  1. package/README.md +660 -21
  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-SHYKQRNX.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-26ZNDDLZ.js +453 -0
  18. package/dist/chunk-26ZNDDLZ.js.map +1 -0
  19. package/dist/chunk-3CTRFMAK.js +359 -0
  20. package/dist/chunk-3CTRFMAK.js.map +1 -0
  21. package/dist/chunk-447JLCBU.js +209 -0
  22. package/dist/chunk-447JLCBU.js.map +1 -0
  23. package/dist/chunk-4RVYOY4O.js +379 -0
  24. package/dist/chunk-4RVYOY4O.js.map +1 -0
  25. package/dist/chunk-5CVXZA3Y.js +292 -0
  26. package/dist/chunk-5CVXZA3Y.js.map +1 -0
  27. package/dist/chunk-5J4FOW6Q.js +108 -0
  28. package/dist/chunk-5J4FOW6Q.js.map +1 -0
  29. package/dist/chunk-742CZ3L3.js +481 -0
  30. package/dist/chunk-742CZ3L3.js.map +1 -0
  31. package/dist/chunk-A2PI6UMY.js +41 -0
  32. package/dist/chunk-A2PI6UMY.js.map +1 -0
  33. package/dist/{chunk-7WCLAEFV.js → chunk-A4UJB2MM.js} +37 -27
  34. package/dist/chunk-A4UJB2MM.js.map +1 -0
  35. package/dist/chunk-B3V6TG77.js +41 -0
  36. package/dist/chunk-B3V6TG77.js.map +1 -0
  37. package/dist/chunk-BRM6FVZA.js +302 -0
  38. package/dist/chunk-BRM6FVZA.js.map +1 -0
  39. package/dist/chunk-C5X5AJXK.js +182 -0
  40. package/dist/chunk-C5X5AJXK.js.map +1 -0
  41. package/dist/{chunk-6KLX2RH5.js → chunk-DO544OSV.js} +1075 -79
  42. package/dist/chunk-DO544OSV.js.map +1 -0
  43. package/dist/{chunk-R3AZOAB5.js → chunk-DYWBUX5Q.js} +29 -123
  44. package/dist/chunk-DYWBUX5Q.js.map +1 -0
  45. package/dist/{chunk-HA46CYQK.js → chunk-EESD3PY3.js} +792 -537
  46. package/dist/chunk-EESD3PY3.js.map +1 -0
  47. package/dist/{chunk-5UQPNLIO.js → chunk-EN3YTHKR.js} +4117 -3896
  48. package/dist/chunk-EN3YTHKR.js.map +1 -0
  49. package/dist/chunk-ERGYJIBB.js +21 -0
  50. package/dist/chunk-ERGYJIBB.js.map +1 -0
  51. package/dist/chunk-FZCP527Y.js +116 -0
  52. package/dist/chunk-FZCP527Y.js.map +1 -0
  53. package/dist/chunk-GIMRELBW.js +14 -0
  54. package/dist/chunk-GIMRELBW.js.map +1 -0
  55. package/dist/chunk-GYVRFZDY.js +2733 -0
  56. package/dist/chunk-GYVRFZDY.js.map +1 -0
  57. package/dist/{chunk-LLOLUHVG.js → chunk-HDJWDK7W.js} +1358 -2746
  58. package/dist/chunk-HDJWDK7W.js.map +1 -0
  59. package/dist/chunk-I7IWRQLN.js +1608 -0
  60. package/dist/chunk-I7IWRQLN.js.map +1 -0
  61. package/dist/chunk-IT4BJUGF.js +13055 -0
  62. package/dist/chunk-IT4BJUGF.js.map +1 -0
  63. package/dist/chunk-IWIDV7SB.js +1 -0
  64. package/dist/chunk-IWIDV7SB.js.map +1 -0
  65. package/dist/chunk-J2QWVSQY.js +312 -0
  66. package/dist/chunk-J2QWVSQY.js.map +1 -0
  67. package/dist/chunk-J6DBS4T3.js +371 -0
  68. package/dist/chunk-J6DBS4T3.js.map +1 -0
  69. package/dist/{chunk-B6WPZSTT.js → chunk-JIQYUGVL.js} +1331 -1163
  70. package/dist/chunk-JIQYUGVL.js.map +1 -0
  71. package/dist/chunk-JT4JW7BC.js +54 -0
  72. package/dist/chunk-JT4JW7BC.js.map +1 -0
  73. package/dist/chunk-K3HQAKQX.js +24 -0
  74. package/dist/chunk-K3HQAKQX.js.map +1 -0
  75. package/dist/{chunk-PEI6RANI.js → chunk-PNY3JKBJ.js} +309 -74
  76. package/dist/chunk-PNY3JKBJ.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-RLUSC2WA.js +299 -0
  80. package/dist/chunk-RLUSC2WA.js.map +1 -0
  81. package/dist/{chunk-IGC6A2ZI.js → chunk-RSI7XYXL.js} +777 -246
  82. package/dist/chunk-RSI7XYXL.js.map +1 -0
  83. package/dist/chunk-SCOTPE2I.js +589 -0
  84. package/dist/chunk-SCOTPE2I.js.map +1 -0
  85. package/dist/{chunk-C5ZPSSS5.js → chunk-TKOTKRWY.js} +5 -4
  86. package/dist/{chunk-C5ZPSSS5.js.map → chunk-TKOTKRWY.js.map} +1 -1
  87. package/dist/chunk-TMYGL6X5.js +742 -0
  88. package/dist/chunk-TMYGL6X5.js.map +1 -0
  89. package/dist/chunk-UGLEYEMP.js +33 -0
  90. package/dist/chunk-UGLEYEMP.js.map +1 -0
  91. package/dist/chunk-UK4TINKT.js +27 -0
  92. package/dist/chunk-UK4TINKT.js.map +1 -0
  93. package/dist/chunk-UTRTG6LH.js +220 -0
  94. package/dist/chunk-UTRTG6LH.js.map +1 -0
  95. package/dist/chunk-WEHMPOXK.js +39 -0
  96. package/dist/chunk-WEHMPOXK.js.map +1 -0
  97. package/dist/chunk-WGXVEJO5.js +319 -0
  98. package/dist/chunk-WGXVEJO5.js.map +1 -0
  99. package/dist/chunk-WRHIZYZF.js +988 -0
  100. package/dist/chunk-WRHIZYZF.js.map +1 -0
  101. package/dist/{chunk-HUIKIDM5.js → chunk-WUISZ3WU.js} +223 -115
  102. package/dist/chunk-WUISZ3WU.js.map +1 -0
  103. package/dist/chunk-XCHWDJ22.js +107 -0
  104. package/dist/chunk-XCHWDJ22.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-YM2DE7BQ.js +3124 -0
  110. package/dist/chunk-YM2DE7BQ.js.map +1 -0
  111. package/dist/{chunk-KZ73RL76.js → chunk-YQEAA6LT.js} +7 -3
  112. package/dist/chunk-YQEAA6LT.js.map +1 -0
  113. package/dist/chunk-YV4L3ILF.js +9 -0
  114. package/dist/chunk-YV4L3ILF.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 +58 -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 +89 -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/session-proxy-scope.d.ts +21 -0
  185. package/dist/components/timeline-anchor.d.ts +24 -0
  186. package/dist/components/timeline-annotation-chrome.d.ts +25 -0
  187. package/dist/components/timeline-annotation-layout.d.ts +42 -0
  188. package/dist/components/timeline-annotation-markers.d.ts +8 -0
  189. package/dist/components/timeline-annotation-reveal-context.d.ts +4 -0
  190. package/dist/components/timeline-annotation-shared.d.ts +31 -0
  191. package/dist/components/timeline-annotations-dialog.d.ts +3 -2
  192. package/dist/components/timeline-annotations.d.ts +13 -3
  193. package/dist/components/timeline-reading-progress.d.ts +11 -0
  194. package/dist/components/timeline-search.d.ts +34 -0
  195. package/dist/components/timeline-settlement.d.ts +16 -0
  196. package/dist/components/tip-follow.d.ts +16 -0
  197. package/dist/components/usage-limit-notice.d.ts +49 -0
  198. package/dist/components/usage-member-list.d.ts +91 -0
  199. package/dist/components/usage-meter.d.ts +73 -0
  200. package/dist/components/use-viewer-menu-dismiss.d.ts +2 -0
  201. package/dist/components/user-message-body.d.ts +10 -1
  202. package/dist/components/workspace-dock.d.ts +6 -2
  203. package/dist/composer.d.ts +5 -4
  204. package/dist/composer.js +15 -9
  205. package/dist/computer-viewer-6SRGWRUX.js +19 -0
  206. package/dist/computer-viewer-6SRGWRUX.js.map +1 -0
  207. package/dist/connect-account-identity.d.ts +8 -0
  208. package/dist/connect-accounts.d.ts +15 -0
  209. package/dist/connect-chooser.d.ts +18 -0
  210. package/dist/connect-panel.d.ts +18 -0
  211. package/dist/connect-setup.d.ts +16 -0
  212. package/dist/connect.d.ts +21 -0
  213. package/dist/connect.js +2129 -0
  214. package/dist/connect.js.map +1 -0
  215. package/dist/connection-catalog.d.ts +38 -0
  216. package/dist/connection-discovery.d.ts +12 -0
  217. package/dist/connection-installed.d.ts +17 -0
  218. package/dist/connection-logo.d.ts +9 -0
  219. package/dist/connection-service-logo.d.ts +8 -0
  220. package/dist/connection-service-presentation.d.ts +13 -0
  221. package/dist/connection-skeleton.d.ts +5 -0
  222. package/dist/connection-type-picker.d.ts +6 -0
  223. package/dist/conversation-timeline.d.ts +5 -0
  224. package/dist/desktop.d.ts +7 -0
  225. package/dist/desktop.js +26 -0
  226. package/dist/desktop.js.map +1 -0
  227. package/dist/device-authorization.d.ts +23 -0
  228. package/dist/diffs.d.ts +8 -0
  229. package/dist/diffs.js +14 -0
  230. package/dist/diffs.js.map +1 -0
  231. package/dist/discovery-cache.d.ts +5 -0
  232. package/dist/editor.d.ts +7 -0
  233. package/dist/editor.js +21 -0
  234. package/dist/editor.js.map +1 -0
  235. package/dist/embedded-session-client.d.ts +23 -0
  236. package/dist/file-node-visibility.d.ts +15 -0
  237. package/dist/{fleet-decision-row-GGCAT4E4.js → fleet-decision-row-YZ3ZKWMM.js} +2 -1
  238. package/dist/fleet-decision-row-YZ3ZKWMM.js.map +1 -0
  239. package/dist/hooks/channel-cache.d.ts +23 -0
  240. package/dist/hooks/latest-question.d.ts +25 -0
  241. package/dist/hooks/shared-machines-list.d.ts +14 -0
  242. package/dist/hooks/use-attached-browsers.d.ts +2 -1
  243. package/dist/hooks/use-browser-frame-stream.d.ts +1 -1
  244. package/dist/hooks/use-browser-session.d.ts +12 -1
  245. package/dist/hooks/use-channels.d.ts +1 -0
  246. package/dist/hooks/use-codex-accounts.d.ts +25 -7
  247. package/dist/hooks/use-composer.d.ts +45 -9
  248. package/dist/hooks/use-computer-frame-stream.d.ts +1 -1
  249. package/dist/hooks/use-computer-input-posture.d.ts +13 -0
  250. package/dist/hooks/use-computer-session.d.ts +2 -0
  251. package/dist/hooks/use-connect.d.ts +22 -0
  252. package/dist/hooks/use-desktop-stream.d.ts +1 -1
  253. package/dist/hooks/use-file-attachments.d.ts +21 -2
  254. package/dist/hooks/use-machine-chip.d.ts +3 -3
  255. package/dist/hooks/use-machines.d.ts +19 -1
  256. package/dist/hooks/use-sandbox-files.d.ts +5 -1
  257. package/dist/hooks/use-session-background-commands.d.ts +14 -0
  258. package/dist/hooks/use-session-events.d.ts +30 -8
  259. package/dist/hooks/use-session-lineage.d.ts +4 -0
  260. package/dist/hooks/use-session-mcp-approval-policy.d.ts +2 -2
  261. package/dist/hooks/use-session.d.ts +6 -0
  262. package/dist/hooks/use-turn-queue.d.ts +12 -0
  263. package/dist/hooks/use-usage.d.ts +40 -0
  264. package/dist/hooks/use-workspace-edit.d.ts +4 -0
  265. package/dist/hooks/use-workspace-sessions.d.ts +27 -5
  266. package/dist/human-input.d.ts +3 -1
  267. package/dist/identity-link-accounts.d.ts +11 -0
  268. package/dist/identity-link-consent.d.ts +18 -0
  269. package/dist/index.d.ts +60 -17
  270. package/dist/index.js +2238 -6201
  271. package/dist/index.js.map +1 -1
  272. package/dist/interaction.d.ts +1 -1
  273. package/dist/interaction.js +35 -184
  274. package/dist/interaction.js.map +1 -1
  275. package/dist/latest-question-HTRIS4KJ.js +117 -0
  276. package/dist/latest-question-HTRIS4KJ.js.map +1 -0
  277. package/dist/lib/error-message.d.ts +7 -0
  278. package/dist/lib/format.d.ts +36 -2
  279. package/dist/lib/host-theme.d.ts +70 -0
  280. package/dist/lib/interaction-errors.d.ts +6 -0
  281. package/dist/lib/menu-styles.d.ts +22 -0
  282. package/dist/lib/pierre-diffs-loader.d.ts +20 -0
  283. package/dist/lib/workbench-peers.d.ts +36 -0
  284. package/dist/lib/xterm-theme.d.ts +7 -5
  285. package/dist/machines.d.ts +4 -2
  286. package/dist/machines.js +14 -4
  287. package/dist/markdown-table-layout-QXSLK4BY.js +106 -0
  288. package/dist/markdown-table-layout-QXSLK4BY.js.map +1 -0
  289. package/dist/mcp-connection-status.d.ts +14 -0
  290. package/dist/model-policy-picker-menu-M54ISBMN.js +14 -0
  291. package/dist/model-policy-picker-menu-M54ISBMN.js.map +1 -0
  292. package/dist/model-policy.d.ts +19 -3
  293. package/dist/model-policy.js +9 -1
  294. package/dist/older-history.d.ts +30 -0
  295. package/dist/platform-activity-row-627BFZ46.js +182 -0
  296. package/dist/platform-activity-row-627BFZ46.js.map +1 -0
  297. package/dist/plugin-details.d.ts +14 -0
  298. package/dist/plugin-discovery.d.ts +25 -0
  299. package/dist/provider.d.ts +13 -1
  300. package/dist/{queue-surface-implementation-2KVJTYXH.js → queue-surface-implementation-ZHFI5JBP.js} +131 -44
  301. package/dist/queue-surface-implementation-ZHFI5JBP.js.map +1 -0
  302. package/dist/realtime/realtime-control.d.ts +6 -3
  303. package/dist/realtime.js +133 -74
  304. package/dist/realtime.js.map +1 -1
  305. package/dist/sandbox-files-GORZOUUJ.js +20 -0
  306. package/dist/sandbox-files-GORZOUUJ.js.map +1 -0
  307. package/dist/session-auth-recommendation.d.ts +5 -0
  308. package/dist/session-capability-policy.d.ts +12 -0
  309. package/dist/session-ui.d.ts +30 -2
  310. package/dist/session-ui.js +85 -7
  311. package/dist/session-ui.js.map +1 -1
  312. package/dist/session.d.ts +8 -2
  313. package/dist/session.js +30 -19
  314. package/dist/sites-ui.d.ts +34 -0
  315. package/dist/sites.d.ts +3 -0
  316. package/dist/sites.js +11 -0
  317. package/dist/sites.js.map +1 -0
  318. package/dist/skill-discovery.d.ts +47 -0
  319. package/dist/terminal.d.ts +8 -0
  320. package/dist/terminal.js +31 -0
  321. package/dist/terminal.js.map +1 -0
  322. package/dist/timeline/activity-rail.d.ts +11 -2
  323. package/dist/timeline/allowance-exhausted-row.d.ts +24 -0
  324. package/dist/timeline/compaction-copy.d.ts +10 -0
  325. package/dist/timeline/entrance.d.ts +13 -1
  326. package/dist/timeline/genie-loading.d.ts +34 -0
  327. package/dist/timeline/index.d.ts +6 -2
  328. package/dist/timeline/knowledge-receipt.d.ts +17 -0
  329. package/dist/timeline/platform-activity-row.d.ts +14 -0
  330. package/dist/timeline/presented-image.d.ts +6 -0
  331. package/dist/timeline/projection.d.ts +31 -2
  332. package/dist/timeline/registry.d.ts +2 -0
  333. package/dist/timeline/retained-image.d.ts +18 -0
  334. package/dist/timeline/rolling-activity.d.ts +11 -0
  335. package/dist/timeline/screenshot-lightbox.d.ts +16 -1
  336. package/dist/timeline/shared.d.ts +8 -3
  337. package/dist/timeline/startup-preference.d.ts +3 -0
  338. package/dist/timeline/startup-timings.d.ts +4 -0
  339. package/dist/timeline/tool-display-name.d.ts +2 -1
  340. package/dist/timeline/turn-summary.d.ts +34 -3
  341. package/dist/timeline/types.d.ts +147 -7
  342. package/dist/timeline-annotation-markers-GNDHTGBD.js +165 -0
  343. package/dist/timeline-annotation-markers-GNDHTGBD.js.map +1 -0
  344. package/dist/timeline-annotation-selection-DMLMM2TX.js +241 -0
  345. package/dist/timeline-annotation-selection-DMLMM2TX.js.map +1 -0
  346. package/dist/timeline-annotations-dialog-ELRDBHTS.js +273 -0
  347. package/dist/timeline-annotations-dialog-ELRDBHTS.js.map +1 -0
  348. package/dist/types/machines.d.ts +2 -2
  349. package/dist/usage/allowance-copy.d.ts +25 -0
  350. package/dist/usage/summary.d.ts +35 -0
  351. package/dist/usage.d.ts +13 -0
  352. package/dist/usage.js +1074 -0
  353. package/dist/usage.js.map +1 -0
  354. package/package.json +44 -4
  355. package/src/accounts.tsx +1072 -0
  356. package/src/approvals.ts +8 -1
  357. package/src/artifacts.ts +42 -0
  358. package/src/assets/README.md +8 -0
  359. package/src/assets/gmail.ico +0 -0
  360. package/src/assets/outlook.ico +0 -0
  361. package/src/capability-catalog-row.tsx +94 -0
  362. package/src/capability-logo-fallback.ts +22 -0
  363. package/src/client.ts +22 -13
  364. package/src/commands/registry.ts +18 -15
  365. package/src/commands/types.ts +2 -0
  366. package/src/components/anthropic-mark.tsx +10 -0
  367. package/src/components/approval-surface.tsx +171 -37
  368. package/src/components/artifacts/artifact-chrome.tsx +413 -0
  369. package/src/components/artifacts/artifact-sandbox.tsx +185 -0
  370. package/src/components/artifacts/artifact-surface.tsx +39 -19
  371. package/src/components/artifacts/chat-interactive-block.tsx +260 -0
  372. package/src/components/artifacts/deferred-chat-media.tsx +67 -0
  373. package/src/components/artifacts/document-editor.tsx +141 -16
  374. package/src/components/artifacts/editable-artifact-ui.tsx +4 -2
  375. package/src/components/artifacts/editable-artifact-view.tsx +187 -0
  376. package/src/components/artifacts/editable-artifact-workbench.tsx +5 -2
  377. package/src/components/artifacts/editable-document.tsx +37 -36
  378. package/src/components/artifacts/editable-presentation.tsx +36 -18
  379. package/src/components/artifacts/editable-spreadsheet.tsx +5 -2
  380. package/src/components/artifacts/index.ts +44 -0
  381. package/src/components/artifacts/inline-html-document.ts +24 -0
  382. package/src/components/artifacts/latest-task-runner.ts +49 -0
  383. package/src/components/artifacts/presentation-editor.tsx +323 -67
  384. package/src/components/artifacts/published-html-artifact-frame.tsx +338 -5
  385. package/src/components/artifacts/session-artifact-viewer.tsx +376 -0
  386. package/src/components/artifacts/site-view.tsx +116 -0
  387. package/src/components/artifacts/spreadsheet-canvas.ts +5 -10
  388. package/src/components/artifacts/spreadsheet-general-display.ts +43 -0
  389. package/src/components/artifacts/spreadsheet-grid.tsx +12 -13
  390. package/src/components/artifacts/visualization-assets/base.css +1015 -0
  391. package/src/components/artifacts/visualization-assets/helpers.html +349 -0
  392. package/src/components/artifacts/visualization-assets.gen.ts +3 -0
  393. package/src/components/browser-select-control.tsx +312 -0
  394. package/src/components/browser-viewer.tsx +1054 -314
  395. package/src/components/chat-composer.tsx +131 -85
  396. package/src/components/child-session-link.tsx +27 -0
  397. package/src/components/claude-mark.tsx +10 -0
  398. package/src/components/code-editor.tsx +13 -16
  399. package/src/components/composer-transcription-control.tsx +7 -5
  400. package/src/components/composer.tsx +376 -49
  401. package/src/components/computer-viewer.tsx +1041 -329
  402. package/src/components/copy-button.tsx +13 -5
  403. package/src/components/desktop-viewer.tsx +1 -1
  404. package/src/components/enrollment-consent.tsx +65 -7
  405. package/src/components/enrollment-device-flow.tsx +1 -1
  406. package/src/components/file-browser.tsx +158 -34
  407. package/src/components/fleet-tile.tsx +8 -16
  408. package/src/components/generated-video-player.tsx +4 -2
  409. package/src/components/grok-mark.tsx +33 -0
  410. package/src/components/human-input-form.tsx +455 -114
  411. package/src/components/human-input-surface.tsx +18 -7
  412. package/src/components/interaction-intervention-banner.tsx +2 -2
  413. package/src/components/machine-card.tsx +119 -4
  414. package/src/components/machine-dock-bar.tsx +1 -1
  415. package/src/components/machine-input-display.ts +23 -2
  416. package/src/components/machines/machine-detail.tsx +52 -2
  417. package/src/components/machines/machine-operation-policy.tsx +179 -0
  418. package/src/components/machines-dashboard.tsx +8 -17
  419. package/src/components/markdown-table-layout.ts +132 -0
  420. package/src/components/markdown.tsx +473 -44
  421. package/src/components/message-timeline.tsx +2754 -665
  422. package/src/components/model-mark.tsx +90 -0
  423. package/src/components/model-picker.tsx +15 -4
  424. package/src/components/model-policy-picker-menu.tsx +424 -0
  425. package/src/components/model-policy-picker.tsx +337 -381
  426. package/src/components/open-geni-chat.tsx +338 -0
  427. package/src/components/open-geni-links.tsx +179 -0
  428. package/src/components/openrouter-mark.tsx +13 -0
  429. package/src/components/pierre-diff.tsx +41 -16
  430. package/src/components/pierre-file.tsx +36 -11
  431. package/src/components/preview-loading.tsx +154 -0
  432. package/src/components/queue-item-content.ts +14 -0
  433. package/src/components/queue-surface-implementation.tsx +132 -42
  434. package/src/components/queue-surface-state.tsx +3 -1
  435. package/src/components/sandbox-files.tsx +267 -35
  436. package/src/components/sandbox-terminal.tsx +48 -11
  437. package/src/components/sandbox-workspace.tsx +337 -135
  438. package/src/components/session-capability-frame.tsx +192 -0
  439. package/src/components/session-chrome.tsx +1027 -328
  440. package/src/components/session-commands-panel.tsx +126 -0
  441. package/src/components/session-commands.tsx +18 -0
  442. package/src/components/session-connection-request.tsx +97 -0
  443. package/src/components/session-conversation.tsx +526 -0
  444. package/src/components/session-list.tsx +250 -0
  445. package/src/components/session-mcp-capability-card.tsx +680 -0
  446. package/src/components/session-proxy-scope.tsx +92 -0
  447. package/src/components/session-status.tsx +1 -1
  448. package/src/components/timeline-anchor.tsx +119 -0
  449. package/src/components/timeline-annotation-chrome.tsx +196 -0
  450. package/src/components/timeline-annotation-layout.ts +268 -0
  451. package/src/components/timeline-annotation-markers.tsx +185 -0
  452. package/src/components/timeline-annotation-reveal-context.ts +9 -0
  453. package/src/components/timeline-annotation-selection.tsx +106 -54
  454. package/src/components/timeline-annotation-shared.ts +245 -0
  455. package/src/components/timeline-annotations-dialog.tsx +185 -128
  456. package/src/components/timeline-annotations.tsx +189 -45
  457. package/src/components/timeline-reading-progress.ts +80 -0
  458. package/src/components/timeline-search.tsx +168 -0
  459. package/src/components/timeline-settlement.ts +60 -0
  460. package/src/components/tip-follow.ts +70 -7
  461. package/src/components/tooltip.tsx +38 -5
  462. package/src/components/usage-limit-notice.tsx +179 -0
  463. package/src/components/usage-member-list.tsx +792 -0
  464. package/src/components/usage-meter.tsx +382 -0
  465. package/src/components/use-viewer-menu-dismiss.ts +33 -0
  466. package/src/components/user-message-body.tsx +194 -49
  467. package/src/components/workspace-dock.tsx +141 -175
  468. package/src/composer.ts +6 -1
  469. package/src/connect-account-identity.tsx +34 -0
  470. package/src/connect-accounts.tsx +233 -0
  471. package/src/connect-chooser.tsx +336 -0
  472. package/src/connect-panel.tsx +99 -0
  473. package/src/connect-setup.tsx +307 -0
  474. package/src/connect.ts +60 -0
  475. package/src/connection-assets.d.ts +4 -0
  476. package/src/connection-catalog.tsx +162 -0
  477. package/src/connection-discovery.tsx +235 -0
  478. package/src/connection-installed.tsx +51 -0
  479. package/src/connection-logo.tsx +37 -0
  480. package/src/connection-service-logo.tsx +55 -0
  481. package/src/connection-service-presentation.ts +46 -0
  482. package/src/connection-skeleton.tsx +16 -0
  483. package/src/connection-type-picker.tsx +36 -0
  484. package/src/conversation-timeline.ts +92 -0
  485. package/src/desktop.ts +24 -0
  486. package/src/device-authorization.tsx +98 -0
  487. package/src/diffs.ts +16 -0
  488. package/src/discovery-cache.ts +42 -0
  489. package/src/editor.ts +13 -0
  490. package/src/embedded-session-client.ts +104 -0
  491. package/src/file-node-visibility.ts +66 -0
  492. package/src/hooks/channel-cache.ts +104 -0
  493. package/src/hooks/internal.ts +3 -2
  494. package/src/hooks/latest-question.ts +164 -0
  495. package/src/hooks/shared-machines-list.ts +239 -0
  496. package/src/hooks/use-attached-browsers.ts +5 -1
  497. package/src/hooks/use-available-models.ts +20 -14
  498. package/src/hooks/use-browser-frame-stream.ts +25 -3
  499. package/src/hooks/use-browser-session.ts +271 -71
  500. package/src/hooks/use-browser-sessions.ts +7 -1
  501. package/src/hooks/use-channels.ts +32 -10
  502. package/src/hooks/use-codex-accounts.ts +78 -21
  503. package/src/hooks/use-composer.ts +1034 -320
  504. package/src/hooks/use-computer-frame-stream.ts +39 -16
  505. package/src/hooks/use-computer-input-posture.ts +94 -0
  506. package/src/hooks/use-computer-session.ts +110 -32
  507. package/src/hooks/use-computer-sessions.ts +8 -1
  508. package/src/hooks/use-connect.ts +23 -0
  509. package/src/hooks/use-desktop-stream.ts +19 -28
  510. package/src/hooks/use-file-attachments.ts +118 -10
  511. package/src/hooks/use-goal.ts +36 -9
  512. package/src/hooks/use-human-input.ts +31 -4
  513. package/src/hooks/use-last-started-turn-policy.ts +15 -13
  514. package/src/hooks/use-machine-chip.ts +23 -6
  515. package/src/hooks/use-machines.ts +104 -6
  516. package/src/hooks/use-sandbox-files.ts +253 -150
  517. package/src/hooks/use-sandbox-git.ts +58 -29
  518. package/src/hooks/use-session-background-commands.ts +67 -0
  519. package/src/hooks/use-session-capabilities.ts +21 -2
  520. package/src/hooks/use-session-events.ts +759 -433
  521. package/src/hooks/use-session-lineage.ts +28 -6
  522. package/src/hooks/use-session-mcp-approval-policy.ts +13 -5
  523. package/src/hooks/use-session.ts +75 -16
  524. package/src/hooks/use-slash-commands.ts +6 -11
  525. package/src/hooks/use-turn-queue.ts +113 -13
  526. package/src/hooks/use-usage.ts +100 -0
  527. package/src/hooks/use-video-artifact-playback.ts +1 -1
  528. package/src/hooks/use-voice-input.ts +12 -1
  529. package/src/hooks/use-workspace-capture.ts +3 -2
  530. package/src/hooks/use-workspace-edit.ts +23 -5
  531. package/src/hooks/use-workspace-sessions.ts +99 -11
  532. package/src/human-input.ts +12 -1
  533. package/src/identity-link-accounts.tsx +148 -0
  534. package/src/identity-link-consent.tsx +192 -0
  535. package/src/index.ts +157 -12
  536. package/src/interaction.ts +1 -0
  537. package/src/lib/error-message.ts +37 -0
  538. package/src/lib/format.ts +150 -14
  539. package/src/lib/host-theme.ts +511 -0
  540. package/src/lib/interaction-errors.ts +33 -0
  541. package/src/lib/menu-styles.ts +44 -0
  542. package/src/lib/pierre-diffs-loader.ts +53 -0
  543. package/src/lib/workbench-peers.ts +62 -0
  544. package/src/lib/xterm-theme.ts +23 -21
  545. package/src/machines.ts +9 -1
  546. package/src/mcp-connection-status.ts +35 -0
  547. package/src/model-policy.ts +223 -69
  548. package/src/older-history.ts +87 -0
  549. package/src/plugin-details.tsx +185 -0
  550. package/src/plugin-discovery.tsx +196 -0
  551. package/src/provider.tsx +55 -14
  552. package/src/realtime/dropdown-menu.tsx +19 -12
  553. package/src/realtime/realtime-control.tsx +133 -46
  554. package/src/session-auth-recommendation.ts +48 -0
  555. package/src/session-capability-policy.ts +83 -0
  556. package/src/session-context.ts +4 -3
  557. package/src/session-ui.ts +66 -2
  558. package/src/session.ts +18 -1
  559. package/src/sites-ui.tsx +402 -0
  560. package/src/sites.ts +3 -0
  561. package/src/skill-discovery.tsx +208 -0
  562. package/src/terminal.ts +26 -0
  563. package/src/timeline/activity-rail.tsx +171 -80
  564. package/src/timeline/allowance-exhausted-row.tsx +86 -0
  565. package/src/timeline/compaction-copy.ts +42 -0
  566. package/src/timeline/entrance.tsx +28 -3
  567. package/src/timeline/fleet-decision-projection.ts +2 -1
  568. package/src/timeline/fleet-decision-row.tsx +1 -0
  569. package/src/timeline/genie-loading.tsx +136 -0
  570. package/src/timeline/index.ts +11 -0
  571. package/src/timeline/knowledge-receipt.tsx +100 -0
  572. package/src/timeline/parsers.ts +2 -2
  573. package/src/timeline/platform-activity-row.tsx +216 -0
  574. package/src/timeline/presented-image.ts +49 -0
  575. package/src/timeline/projection.ts +1609 -84
  576. package/src/timeline/registry.ts +15 -3
  577. package/src/timeline/retained-image.ts +97 -0
  578. package/src/timeline/rolling-activity.tsx +92 -0
  579. package/src/timeline/screenshot-lightbox.tsx +115 -17
  580. package/src/timeline/shared.tsx +47 -15
  581. package/src/timeline/startup-preference.ts +33 -0
  582. package/src/timeline/startup-timings.tsx +145 -0
  583. package/src/timeline/tool-display-name.ts +8 -6
  584. package/src/timeline/tool-renderers.tsx +497 -128
  585. package/src/timeline/turn-summary.tsx +218 -44
  586. package/src/timeline/types.ts +192 -7
  587. package/src/types/machines.ts +10 -0
  588. package/src/usage/allowance-copy.ts +64 -0
  589. package/src/usage/summary.ts +93 -0
  590. package/src/usage.ts +50 -0
  591. package/styles/compiled.css +2098 -757
  592. package/styles/connect.css +284 -0
  593. package/styles/connect.d.ts +1 -0
  594. package/styles/effective-tokens.css +1 -0
  595. package/styles/index.css +201 -9
  596. package/styles/responsive.css +27 -1
  597. package/styles/session-capability.css +44 -0
  598. package/styles/tokens.css +135 -65
  599. package/dist/chunk-5UQPNLIO.js.map +0 -1
  600. package/dist/chunk-6KLX2RH5.js.map +0 -1
  601. package/dist/chunk-7WCLAEFV.js.map +0 -1
  602. package/dist/chunk-B6WPZSTT.js.map +0 -1
  603. package/dist/chunk-FK6VG4LL.js +0 -90
  604. package/dist/chunk-FK6VG4LL.js.map +0 -1
  605. package/dist/chunk-HA46CYQK.js.map +0 -1
  606. package/dist/chunk-HUIKIDM5.js.map +0 -1
  607. package/dist/chunk-IGC6A2ZI.js.map +0 -1
  608. package/dist/chunk-KCGXPP5V.js.map +0 -1
  609. package/dist/chunk-KZ73RL76.js.map +0 -1
  610. package/dist/chunk-LAKLF4PA.js +0 -141
  611. package/dist/chunk-LAKLF4PA.js.map +0 -1
  612. package/dist/chunk-LLOLUHVG.js.map +0 -1
  613. package/dist/chunk-MKPIAGVL.js +0 -465
  614. package/dist/chunk-MKPIAGVL.js.map +0 -1
  615. package/dist/chunk-PEI6RANI.js.map +0 -1
  616. package/dist/chunk-R3AZOAB5.js.map +0 -1
  617. package/dist/chunk-WSK7G5LE.js +0 -170
  618. package/dist/chunk-WSK7G5LE.js.map +0 -1
  619. package/dist/chunk-XBZWOM2K.js +0 -218
  620. package/dist/chunk-XBZWOM2K.js.map +0 -1
  621. package/dist/chunk-Y7OEDUJ5.js +0 -8810
  622. package/dist/chunk-Y7OEDUJ5.js.map +0 -1
  623. package/dist/fleet-decision-row-GGCAT4E4.js.map +0 -1
  624. package/dist/hooks/use-packs.d.ts +0 -32
  625. package/dist/interactive-workbench-viewers-TOHBXJEE.js +0 -15
  626. package/dist/queue-surface-implementation-2KVJTYXH.js.map +0 -1
  627. package/dist/timeline-annotation-selection-3L7LHGG2.js +0 -187
  628. package/dist/timeline-annotation-selection-3L7LHGG2.js.map +0 -1
  629. package/dist/timeline-annotations-dialog-U7EVLR75.js +0 -196
  630. package/dist/timeline-annotations-dialog-U7EVLR75.js.map +0 -1
  631. package/src/hooks/use-packs.ts +0 -157
  632. /package/dist/{interactive-workbench-viewers-TOHBXJEE.js.map → browser-viewer-SHYKQRNX.js.map} +0 -0
package/README.md CHANGED
@@ -19,11 +19,234 @@ island for back-compat, deprecated per #144.)
19
19
 
20
20
  Design-system-first: every visual decision routes through CSS-variable tokens
21
21
  (`styles/tokens.css`) — color, typography, radius, shadow, motion. Dark mode is
22
- the first-class default; light is an opt-in via `data-og-theme="light"` on any
23
- ancestor. Components are styled with Tailwind v4 utilities mapped onto the
22
+ the first-class token default; light is an opt-in via `data-og-theme="light"` on
23
+ any ancestor. The embedded chat roots (`OpenGeniChat`, `SessionConversation`)
24
+ resolve light or dark from the host page instead; see
25
+ [Conversation UI](#conversation-ui). Components are styled with Tailwind v4 utilities mapped onto the
24
26
  tokens, Radix primitives for behavior, and Motion for state-communicating
25
27
  animation. Override the tokens to rebrand everything.
26
28
 
29
+ ## Embedded connections and Sites
30
+
31
+ Optional `@opengeni/react/connect` exports `useConnect`, `ConnectChooser`,
32
+ `ConnectSetup`, `ConnectAccounts`, and the composed `ConnectPanel`. Inject one
33
+ `@opengeni/connect` controller per authenticated actor/workspace and dispose it
34
+ when that scope changes. The controller uses your authenticated backend proxy;
35
+ never place an organization key in browser props. Import
36
+ `@opengeni/react/connect.css` for opt-in, scoped styles without Tailwind.
37
+ `DeviceAuthorization` also accepts an optional `render` callback for host presentation;
38
+ it receives shared copy state, the copy action, and the validated verification URL.
39
+ Omitting it preserves the default embedded presentation.
40
+
41
+ `CapabilityCatalogRow` gives connections, skills, and plugins one consistent
42
+ icon/name/description button with a decorative plus/check and visible exception
43
+ states. Supply `onOpen` and an explicit `status`; the host owns setup and
44
+ installation. `ConnectionCatalog` accepts the same states through each option's
45
+ `state`. Older callers that omit `state` keep their visible status labels, so
46
+ provider warnings are not hidden during migration.
47
+
48
+ `PluginDiscovery` accepts `defaultProvider="openai"` or `"anthropic"` to choose
49
+ the initial registry. Omitting it starts with All. Users can still switch among
50
+ All, OpenAI, and Anthropic; changing the search preserves their selection. The
51
+ OpenGeni Plugins page starts with OpenAI.
52
+
53
+ ```tsx
54
+ import { ConnectPanel } from "@opengeni/react/connect";
55
+ import "@opengeni/react/connect.css";
56
+
57
+ <ConnectPanel
58
+ controller={controller}
59
+ returnUrl={hostSelectedReturnUrl}
60
+ onAuthorize={hostAuthorizeFromClick}
61
+ />;
62
+ ```
63
+
64
+ The host owns synchronous popup/full-redirect navigation and pending-attempt
65
+ recovery. Backend state, not a popup message or URL query, proves completion.
66
+ Operation installation uses explicit selection; OAuth success alone is not
67
+ installation. Account disconnect requires an observed version and confirmation,
68
+ revokes local OpenGeni access only, and never silently retries an unknown outcome.
69
+ Provider readiness is deployment-dependent; use the server catalog rather than
70
+ assuming every OAuth application or operator-managed provider is configured.
71
+
72
+ Optional `@opengeni/react/sites` exports `SiteList`, `SiteDetail`, and `SiteClient`.
73
+ Pass the public SDK client through your host proxy. `onOpen` owns list
74
+ navigation. Authoring buttons and prompts belong to the host and use the ordinary
75
+ session SDK; they are not part of the Site component API. `SiteDetail` reuses `PublishedHtmlArtifactFrame`, accepts
76
+ an optional authenticated/filtered tool bridge, and removes the frame after
77
+ read-authority refresh failure. Loaded Sites revalidate every 15 seconds;
78
+ downloaded HTML cannot be recalled and every tool call still needs live authority.
79
+
80
+ `canPublish` is only a presentation hint. Version-checked rollback/archive/restore
81
+ remain subject to backend `artifacts:publish` permission. Sites stay workspace
82
+ shared, even if a source session is private. See
83
+ [`examples/embedded-product`](../../examples/embedded-product/README.md) for the
84
+ runnable loopback host reference. Native route reuse and full visual acceptance
85
+ are not implied by these optional package surfaces.
86
+ ## Conversation UI
87
+
88
+ `OpenGeniChat` and `SessionConversation` are the default product integration.
89
+ Back them with `createSessionProxyHandler` from `@opengeni/sdk`, mounted on your
90
+ server, and pass its mount as `baseUrl`. No provider, client, or workspace id
91
+ is needed: the component creates the browser client and uses the workspace the
92
+ proxy resolved for the signed-in user (from the proxy's client config).
93
+
94
+ ```tsx
95
+ import "@opengeni/react/compiled.css";
96
+
97
+ <OpenGeniChat baseUrl="/api/opengeni" />;
98
+ // or one conversation: <SessionConversation baseUrl="/api/opengeni" sessionId={sessionId} />
99
+ ```
100
+
101
+ The provider form keeps working, for example for several components sharing one
102
+ client or the headless hooks:
103
+
104
+ ```tsx
105
+ <OpenGeniProvider client={new OpenGeniClient({ baseUrl: "/api/opengeni" })} workspaceId={workspaceId}>
106
+ <SessionConversation sessionId={sessionId} />
107
+ </OpenGeniProvider>
108
+ ```
109
+
110
+ Compose `MessageTimeline` and `ChatComposer` with the session hooks only when
111
+ the product needs a materially different interaction model. These components do
112
+ not consume the text-only `@opengeni/sdk/chat` fallback protocol.
113
+
114
+ `OpenGeniChat` adds the user's chat list to the conversation: a sidebar when
115
+ the component is wide and a drawer behind a menu button when narrow (measured on
116
+ its own container, so it works inside panels), a new-chat composer that creates
117
+ the session from its first message, and inline rename and archive. It is
118
+ composed from `SessionList` and `SessionConversation`, which you can also mount
119
+ separately. Pass `conversationProps` for message rendering and tool renderers,
120
+ `createSession` to create chats through your own endpoint, or `sessionId` /
121
+ `onSessionChange` to control the selection (for example from the URL).
122
+
123
+ `SessionConversation` and `OpenGeniChat` are built to look native inside
124
+ someone else's product with zero styling:
125
+
126
+ - **Theme follows the host**, not the OS: an enclosing `data-og-theme`, then
127
+ `class="dark"`/`data-theme` (and similar) on `<html>`/`<body>`, the host's
128
+ `color-scheme`, then the luminance of the background the chat sits on. Pass
129
+ `theme="light" | "dark"` to force one.
130
+ - **Surfaces blend into the host** (`surface="host"`, default): backgrounds and
131
+ cards are opaque mixes of the host background, so a navy app gets navy cards.
132
+ Host-customized `--og-color-*` tokens are kept; `surface="theme"` uses the
133
+ token surfaces as they are.
134
+ - **Run control is Stop, not Pause**: a Stop control appears only while a
135
+ response runs, and the next message continues a stopped conversation. Opt
136
+ into the console's workstream Pause with `composerProps={{ runControl: "pause" }}`
137
+ (`"none"` hides both).
138
+ - **No model picker by default**: end users rarely choose models. Pass
139
+ `modelPicker`, or report `modelSelection: true` from the proxy
140
+ (`createSessionProxyHandler({ modelSelection: true })`); `modelSelection: false`
141
+ also fixes the policy server-side.
142
+
143
+ Attachments appear when the deployment enables uploads (`attachments={false}`
144
+ opts out), pending tool approvals render Approve/Reject, a yes/no question
145
+ renders as two buttons, a failed load offers Try again, and `toolRegistry`
146
+ customizes tool rendering.
147
+
148
+ The root keeps all existing exports, including workbench components, but never
149
+ imports their optional peers. Conversation-only Next.js/Vite hosts do not need
150
+ terminal, desktop, editor, or diff packages. Hosts mounting those surfaces opt
151
+ in through the [per-surface setup entries](#optional-peer-dependencies).
152
+
153
+ Highlighted diffs use the optional `@pierre/diffs` peer only after an explicit
154
+ opt-in, so a host without it still builds with any bundler (Turbopack resolves
155
+ every reachable `import()`). Hosts that install it call `enablePierreDiffs()`
156
+ once; call it from the lazily loaded route that renders diffs to keep the peer
157
+ out of your initial bundle. Views already on screen upgrade when it registers:
158
+
159
+ ```ts
160
+ import { enablePierreDiffs } from "@opengeni/react/diffs";
161
+ enablePierreDiffs();
162
+ ```
163
+
164
+ Without it, diffs and file views render as plain text.
165
+
166
+ `OpenGeniProvider` never blocks or reloads the host page when OpenGeni deploys
167
+ a new API contract revision. The stock OpenGeni console opts into that
168
+ stale-tab protection with `reloadOnApiContractChange`; embedded products
169
+ should leave it off.
170
+
171
+ ### Exact conversation search navigation
172
+
173
+ `useSessionEvents().initialHistoryReady` becomes true when a history window has
174
+ loaded successfully, including an empty tail. It stays true through later stream
175
+ errors, history navigation, and tip reloads, and resets for a new session/replay
176
+ identity. Use it rather than inferring initial success from `initialLoading` or
177
+ the combined `error`. A failed first load stays unready until recovery;
178
+ `jumpToLatest()` clears its stale error and retries. Full replay has no history
179
+ snapshot-completion watermark, so SSE alone does not set this flag.
180
+
181
+ `useSessionEvents(sessionId).jumpToSequence(sequence)` replaces the current
182
+ window with at most two bounded cursor reads around an exact durable event.
183
+ It resolves `true` only when that event is retained, `false` for a missing or
184
+ superseded target, and rejects current request errors. `loadingTarget` exposes
185
+ the pending state. New targets supersede older targets/pages; session/client
186
+ changes fence stale results. Search enters history mode; use the existing
187
+ `loadOlder`, `loadNewer`, and `jumpToLatest` controls to navigate onward. It does
188
+ not download the intervening session history.
189
+ Pass `jumpToSequence(sequence, { signal })` to cancel one navigation: an
190
+ aborted signal fences the pending jump before its fetched window is applied
191
+ (the underlying reads may still complete), resolves `false`, and settles
192
+ `loadingTarget` without disturbing any newer navigation that superseded it.
193
+
194
+ Pass the selected hit to `MessageTimeline` independently of loading:
195
+
196
+ ```tsx
197
+ const history = useSessionEvents(sessionId);
198
+ const [target, setTarget] = useState<TimelineSearchTarget | null>(null);
199
+
200
+ function selectHit(hit: { sequence: number; eventId: string }, query: string, occurrence = 0) {
201
+ setTarget({ ...hit, query, occurrence });
202
+ void history.jumpToSequence(hit.sequence);
203
+ }
204
+
205
+ <MessageTimeline events={history.events} items={history.timeline} searchTarget={target} />;
206
+ ```
207
+
208
+ The host owns search results, error handling, next/previous controls and query
209
+ state. `TimelineSearchTarget` is exported from the root and `session-ui` entry:
210
+ `{ sequence: number; eventId?: string; query: string; occurrence?: number; offset?: number }`.
211
+ Matching is literal, case-insensitive, non-overlapping; `occurrence` is zero-based
212
+ within the message, defaulting to zero. When the backend all-occurrence search
213
+ returns `messageMatchOffset`, pass it as `offset`: the zero-based UTF-16 position
214
+ of the match in the original message text. An explicit `offset` takes precedence
215
+ over `occurrence` and is validated against the query, so a stale offset simply
216
+ produces no highlight. `buildTimeline` supplies `sourceEvents`
217
+ identities so completed assistant events remain addressable when the renderer
218
+ keeps a first-delta ID. Hosts supplying their own items should preserve those
219
+ identities (or the canonical `annotationSource`).
220
+
221
+ The active message's group and long-user disclosure open persistently. Setting
222
+ `searchTarget={null}` removes the active highlight without collapsing content or
223
+ restoring a former scroll position. The package mounts its complete bounded
224
+ window. The default Markdown renderer shows a labeled, bounded **message source**
225
+ excerpt for the active match, including Markdown syntax and link destinations;
226
+ closing find removes the highlight but retains that excerpt and its layout.
227
+ An explicit **Show formatted message** action restores the full body; this can
228
+ expand a huge message, so it is never done automatically on closing Find.
229
+ Raw UTF-16 offsets are never applied
230
+ to rendered Markdown text. Custom hosts can use
231
+ `<Markdown searchTarget={searchTarget}>{text}</Markdown>` for the same behavior.
232
+ A custom virtualized renderer receives
233
+ `renderMessageText(text, item, { searchTarget })` and must materialize the exact
234
+ occurrence when that context is non-null. Existing two-argument renderers remain
235
+ compatible. If previous occurrences are omitted from the virtualized DOM, wrap
236
+ the materialized match in an element with `data-og-search-occurrence` (zero-based
237
+ index), `data-og-search-sequence` and `data-og-search-query`, each set from the
238
+ target; when the target carries an `offset`, set `data-og-search-offset` to it
239
+ alongside `data-og-search-occurrence` (which can be zero). This lets navigation
240
+ identify that exact occurrence without recounting an incomplete DOM. Keep the
241
+ materialized window when the context clears to
242
+ preserve position. Navigation waits for the mounted text and highlights the active
243
+ DOM range using the CSS Custom Highlight API, without rewriting React-owned
244
+ text. Explicit source-offset targets require this marker: matching characters
245
+ at the same rendered offset are not proof of source identity. A custom renderer
246
+ that omits source text or puts it in an opaque iframe must reveal that text
247
+ itself. Existing renderers without this mapping remain render-compatible but
248
+ cannot provide exact source-offset navigation.
249
+
27
250
  ## Editable Office artifacts
28
251
 
29
252
  The optional artifact workbench is isolated from the ordinary session and
@@ -135,6 +358,21 @@ can therefore implement only the methods used by each hook. A shared event feed
135
358
  also avoids requiring a client-owned event stream at runtime. Workspace-level
136
359
  Resume is an optional authority.
137
360
 
361
+ Use `createEmbeddedSessionClient(base, options)` to bind that narrow surface
362
+ from a full SDK client or host proxy. Delegated methods preserve their SDK
363
+ receiver, `options.overrides.submitComposerDraft` can route atomic submission
364
+ through a host-authenticated endpoint, and `mapComposerDraft` can project every
365
+ read/save/submit draft before React adopts it. Construction fails immediately
366
+ when a required method is missing, and submit returns the host/native
367
+ `SubmitComposerDraftResponse` unchanged apart from an explicitly configured
368
+ draft projection.
369
+
370
+ The styled file surfaces accept a presentation-only node predicate:
371
+ `FileBrowser.isNodeVisible`, `SandboxFiles.isNodeVisible`, and
372
+ `SandboxWorkspace.isFileNodeVisible`. Hidden parents never expose orphaned
373
+ children, hidden selections/reveal requests are ignored, and omitting the prop
374
+ preserves the complete authoritative tree. This is not an authorization seam.
375
+
138
376
  The styled root surface ships with ready-to-use CSS. Import it once; the host
139
377
  does not need Tailwind:
140
378
 
@@ -272,7 +510,7 @@ function OpsChannel({ sessionId }: { sessionId: string }) {
272
510
  status={sessionStatus}
273
511
  hasOlder={hasOlder}
274
512
  loadingOlder={loadingOlder}
275
- onLoadOlder={() => void loadOlder()}
513
+ onLoadOlder={loadOlder}
276
514
  className="min-h-0 flex-1"
277
515
  />
278
516
  <QueueSurface queue={queue} composer={composer} />
@@ -391,6 +629,41 @@ workspace discovery, peer switching, tabs/windows, live frames, human input,
391
629
  identity versions, interventions, diagnostics, reconnect, and lifecycle state do
392
630
  not require app-private controller glue.
393
631
 
632
+ Managed browser actions keep the foreground tab in place. Target-local Chromium
633
+ focus emulation keeps animation callbacks running without an open preview;
634
+ explicit activation brings a tab forward. The override ends when its controller
635
+ detaches. Native **App controls** also work in the background where supported.
636
+ Physical desktop mouse/keyboard input shares the foreground seat; **Bring to front**
637
+ makes that change explicit.
638
+ Computer frames fit the dock while preserving their proportions. Resizing or
639
+ reopening the dock refits the visible image without changing capture resolution
640
+ or the coordinates sent to the computer.
641
+ Desktop opens a whole screen by default. Multiple screens use a compact screen
642
+ selector; app controls and window views are available from **Advanced**. Explicit
643
+ view choices survive refreshes while the target remains available.
644
+
645
+ Desktop IME candidates and their selection keys stay local; only committed text is sent.
646
+
647
+ A managed browser's attachment authority error keeps a same-browser **Reconnect**
648
+ action available. It obtains a fresh server-authorized attachment without creating
649
+ a replacement browser or replaying input. The fresh Connected Chrome instruction
650
+ is reserved for the selected extension-attached browser's generation loss; a
651
+ different lost browser in the workspace cannot change that recovery path.
652
+
653
+ The browser viewer negotiates bounded typing batches from the active controller's
654
+ short-lived attachment. Supporting helpers recheck the original controller,
655
+ target, document and frame fence before every action; old helpers retain one
656
+ request per action. Only queued text actions share a request (at most 16), with
657
+ each text/input event preserved. Keys, pointer input and clipboard operations
658
+ remain ordering barriers. A failed or uncertain action discards the queued suffix
659
+ without replay.
660
+ IME candidate-selection keys stay local to the viewer; only committed text is
661
+ sent to the remote page. A later ordinary Enter remains a remote key action.
662
+ Live image props use opaque byte buffers so React development timing diagnostics
663
+ cannot expand and retain every screenshot byte. Normal timing diagnostics remain enabled.
664
+ Queued inputs retain only immutable frame fences, not screenshot bytes or prior
665
+ render callbacks. Replacing the selected viewer invalidates its queued suffix.
666
+
394
667
  ```tsx
395
668
  import { OpenGeniProvider } from "@opengeni/react";
396
669
  import { BrowserViewer, ComputerViewer } from "@opengeni/react/interaction";
@@ -416,6 +689,33 @@ returned ComputerSession must be the exact placement/window the browser uses.
416
689
  `onOpenComputer` then changes the host layout to that resource—it must not open a
417
690
  lookalike desktop. Closing either viewer never ends its durable resource.
418
691
 
692
+ `ComputerViewer` disables input when its control service is unavailable, even if
693
+ frames keep arriving. Reconnect refreshes the selected desktop's controls and
694
+ frames. App accessibility inspection failures leave independent live input
695
+ available; `useComputerSession().controlError` reports service loss separately
696
+ from the hook's general `error`.
697
+
698
+ If the chat's latest browser was lost or failed, the viewer names it and explains
699
+ why it is unavailable instead of showing the ordinary empty state. It offers the
700
+ existing new-browser controls without reopening the lost controller or selecting
701
+ another chat's browser. Explicitly closed browsers still use the empty state;
702
+ older failures do not replace a newer closed browser. This loss notice also takes
703
+ precedence over `renderEmpty`. Preview the deadline-loss case with
704
+ `browser.html?mode=mock&lost=1` (add `width=360&theme=light` for a narrow light dock).
705
+
706
+ Native dropdown popups may not appear in page frames. With a controller that
707
+ advertises focused input observations, clicking one opens its choices beside
708
+ the click. Ordinary clicks use a bounded focus probe instead of a full page
709
+ snapshot; only a focused native dropdown (or a child-frame focus hint) requests
710
+ semantic options. Current controllers show no permanent **Choose option** button
711
+ over the page; older controllers retain that explicit fallback. **Alt+Down** opens
712
+ the focused dropdown and reads its options on either controller generation.
713
+ Selection uses the normal browser action API. The viewer retains that
714
+ observation's target/document/frame fence. Private, oversized, or ambiguous
715
+ choices remain unavailable; the page's keyboard controls still work. This
716
+ fallback requires a controller with focused native-select metadata support and
717
+ does not rewrite the page or capture the desktop.
718
+
419
719
  The provider opens one shared workspace interaction-revision stream and every
420
720
  catalog refreshes only when its revision advances; hidden or disconnected pages
421
721
  fall back to bounded polling and reconcile from the retained cursor. Hosts that
@@ -428,6 +728,18 @@ same-origin `/demo-api` proxy and the exact published SDK/React entrypoints.
428
728
 
429
729
  ## Composer customization (`@opengeni/react/composer`)
430
730
 
731
+ `SessionChrome` accepts `onComposerFocus` for queue editing. Connect it to
732
+ `controller.focusInput` from `useChatComposerController`, or focus a custom
733
+ input through its ref. Chrome calls it after a successful checkout and
734
+ `composer.applyDraft`, including confirmed draft replacement; failed checkout
735
+ and pending/cancelled replacement do not request focus. The host retains
736
+ ownership of the input and no DOM selector or global focus event is needed.
737
+
738
+ When sharing `useSessionEvents().events` with `useGoal`, the hook still fetches
739
+ the authoritative goal on mount and target changes, even when the supplied log
740
+ already contains goal events. The shared log drives subsequent invalidations
741
+ without opening another event stream. A 404 remains a normal goal-less state.
742
+
431
743
  Use `ChatComposer` for the standard layout and its `controlsStart`, `header`,
432
744
  and `messages` props for small additions. For a different layout, import the
433
745
  headless controller and compound primitives as a namespace. The controller is
@@ -506,20 +818,53 @@ state remains application-owned; durable draft and session state remain in
506
818
 
507
819
  - `useSessionEvents(sessionId)` — loads a compact, bounded tail window by
508
820
  default, then live-streams on the SDK's exactly-once/ordered event delivery.
509
- Initial replay is capped at three 5000-row raw pages and `loadOlder` at two;
821
+ Initial replay reads one 1000-row raw page, with at most one extra page to
822
+ recover a dense turn's boundary; `loadOlder` is capped at two such pages;
510
823
  timeline group density is only an early stop. It returns the raw windowed
511
824
  `events`, projected `timeline`, latest `sessionStatus`, connection state, and
512
825
  older-history controls (`hasOlder`, `loadingOlder`, `loadOlder`). Pass
513
826
  `replay: "full"` to opt back into full replay; a nonzero `after` keeps the
514
- previous resume semantics.
827
+ previous resume semantics. `loadOlder()` remains await-compatible and resolves
828
+ to the existing `boolean`, while its promise also carries the causal
829
+ `committed` receipt used by `MessageTimeline`. Pass it directly or through an
830
+ existing wrapper, including `onLoadOlder={() => void loadOlder()}`; synchronous
831
+ receipt capture preserves the commit signal without narrowing the historical
832
+ callback return type. Custom loaders can use `createOlderHistoryLoadReceipt`
833
+ and call `markCommitted` immediately before publishing their accepted older
834
+ window.
835
+ - Browser retention limits are exported as `SESSION_EVENT_BROWSER_MAX_BYTES`
836
+ and `SESSION_EVENT_BROWSER_MAX_COUNT`; they do not change fetch page sizes.
837
+ The live working set is at most 16 MiB or 20,000 events. One event larger than
838
+ the byte target stays complete in a window of its own.
839
+ Live appends reuse the retained window's byte total, measuring only incoming
840
+ and evicted events. History still pages when either retention limit is reached.
841
+ - Newer history uses `hasNewer`, `loadingNewer`, and `loadNewer`. A failed
842
+ `loadNewer()` preserves the retained events and cursors, exposes the original
843
+ failure through `error`, and still rejects for the caller to handle. Pass
844
+ `onLoadNewer={loadNewer}` (or return its promise from your wrapper) to
845
+ `MessageTimeline`: it catches the request failure, shows the error and an
846
+ explicit **Retry later activity** action, and does not automatically retry
847
+ the failed boundary. A successful retry, jump to the start/latest window,
848
+ or session change clears that failure. Loading older rows alone does not
849
+ resolve a failed newer read. Late failures from a previous session are ignored.
850
+ A host that discards the promise must handle its own rejected request.
515
851
  - `useComposer(sessionId, { sendExtras, effectiveControl })` — revisioned private
516
852
  draft, Send, Steer, and workstream Pause/Resume state. `send()` appends in
517
- visible queue order; `steer()` supersedes the current direction. Drafts
853
+ visible queue order (including while paused); `steer()` puts the new direction
854
+ directly in chat and supersedes the current direction. Resume is always an
855
+ explicit control action and never an implicit side effect of Send. Drafts
518
856
  autosave with optimistic concurrency, survive failed sends, and reuse one
519
- `clientEventId` across retries so the server dedupes.
520
- `sendExtras` (object or function evaluated at send time) merges
521
- resources/tools/model/reasoningEffort into every message. All human input is
522
- plain chat text by design; approvals flow as control events
857
+ `clientEventId` across retries so the server dedupes. Draft reads retry transient
858
+ failures, including request timeouts, with backoff. Successful refreshes clear
859
+ draft-read errors without dismissing Send, Steer, or control errors; a draft
860
+ sync timeout does not mean the agent turn has stopped. `composer.policy` and
861
+ `setModel` / `setReasoningEffort` / `setLatencyMode` expose the exact policy
862
+ owned by that actor/session draft; policy is `null` until hydration completes.
863
+ `sendExtras` (object or function evaluated at send time) is only for
864
+ non-policy per-message fields such as live attachment resources and connection
865
+ authority. Disabling durable draft persistence requires an explicit
866
+ `initialPolicy`; no session or workspace fallback is invented. All human input
867
+ is plain chat text by design; approvals flow as control events
523
868
  (`useSessionControl`), not bespoke widgets.
524
869
  - `useTurnQueue(sessionId, { events })` — the one server-authoritative human
525
870
  prompt queue with `moveTurn`, crash-safe `editTurn`, identity-preserving
@@ -547,13 +892,14 @@ state remains application-owned; durable draft and session state remain in
547
892
  - `useSlashCommands(...)` — the slash-command palette state (registry + parsing +
548
893
  handlers) behind `CommandPalette`.
549
894
  - `useWorkspaceSessions()` / `useScheduledTasks()` — workspace lists for
550
- fleet/manager views (optional polling).
895
+ fleet/manager views (optional polling). `useWorkspaceSessions({ projection:
896
+ "summary" })` returns compact list entries; omit the option for full sessions.
897
+ Scripted clients can omit the summary method and the hook projects full pages
898
+ locally while retaining cancellation and causal read revisions.
551
899
  - `useVariableSets()` — workspace variable sets with metadata-only generic
552
900
  reads and create/update/remove/set/delete operations. Dedicated permissioned
553
901
  exact-value reveal is part of the held React/UI train rather than an
554
902
  implicit field on ordinary reads.
555
- - `usePacks()` — capability packs + installations with
556
- register/enable/remove and `installationFor(packId)`.
557
903
  - `useWorkspaces()` — the caller's workspaces with create/update (client-only;
558
904
  not bound to the provider's workspace).
559
905
  - `useBillingUsage({ accountId?, workspaceId? })` — credit balance + recent
@@ -591,8 +937,9 @@ intentional changes should regenerate those snapshots and review the diff.
591
937
 
592
938
  ## Components
593
939
 
594
- - `ChatComposer` — auto-growing textarea, Enter-to-send (IME-safe), pause/resume
595
- controls, inline error recovery. Slots for app chrome:
940
+ - `ChatComposer` — auto-growing textarea, Enter-to-send (IME-safe), direct
941
+ Cmd/Ctrl+Enter steering, pause/resume controls, and inline finite error
942
+ recovery. Paused sends visibly join the queue without resuming. Slots for app chrome:
596
943
  `controlsStart` (footer controls like model pickers / attach buttons),
597
944
  `header` (e.g. attachment chips above the field), and `onPaste`
598
945
  (paste-image-to-attach). Its advanced controller and compound primitives are
@@ -607,6 +954,15 @@ intentional changes should regenerate those snapshots and review the diff.
607
954
  - `UserMessageBody` — the shared lossless rendered-height disclosure for
608
955
  already-sent user text. Use it inside a custom `renderMessageText` user branch
609
956
  so attachments and voice identity remain outside the clipped Markdown region.
957
+ Pass `disclosureLabels={{ showMore: "Afficher davantage", showLess: "Réduire" }}`
958
+ to localize a direct instance. For the default timeline, pass the same object
959
+ as `MessageTimeline.userMessageDisclosureLabels` or
960
+ `SessionConversation.userMessageDisclosureLabels`; custom `UserMessageBody`
961
+ renderers inside that timeline inherit these labels too. Each direct label
962
+ overrides its timeline label independently, then falls back to `Show more`
963
+ or `Show less`. Changing labels does not reset a message's expanded state.
964
+ `UserMessageDisclosureLabels` is exported from both `@opengeni/react` and
965
+ `@opengeni/react/session-ui`.
610
966
  - `SessionStatus` / `StatusDot` — status badges; live states breathe.
611
967
  - `FleetTile` — one session in a fleet grid: title, status, model, recency.
612
968
  - `ModelPicker` — a compact model dropdown for a composer slot, grouping the
@@ -616,8 +972,26 @@ intentional changes should regenerate those snapshots and review the diff.
616
972
  runnable latency modes such as Fast. It accepts either `ClientModel[]` or
617
973
  catalog-backed `PickerModelRow[]`, and supports host-supplied labels.
618
974
  - `Markdown` — the timeline's markdown renderer (GFM), also usable standalone.
975
+ Top-level assistant tables in `MessageTimeline` can expand beyond the prose
976
+ column into the actual conversation panel's available space. Small tables,
977
+ paragraphs, user bubbles, and nested or standalone Markdown keep their normal
978
+ width; oversized tables retain table-only horizontal scrolling. No host prop
979
+ or viewport-wide layout override is required.
980
+ Remeasurement during host rerenders or tail streaming does not temporarily
981
+ resize the live table or displace an unpinned history reader.
982
+ With `onSandboxFile`, a valid `sandbox:<path>[:line]` application link becomes
983
+ an in-session Open action. The callback receives the decoded path unchanged;
984
+ the optional line is positive and 1-based. Invalid sandbox references render
985
+ as disabled text, never as empty or browser-navigation links.
619
986
  - `CommandPalette` — the slash-command palette UI over `useSlashCommands`.
620
987
 
988
+ `SandboxWorkspace.openFileRequest` is the host seam for that callback. Each new
989
+ `requestId` selects Files, opens the exact path on the already selected session
990
+ target, reveals its loaded/lazy ancestors in the file tree, selects and scrolls
991
+ to the file, and optionally focuses the requested line. A request without a line
992
+ opens the top of the file; file publication/download remains a separate explicit
993
+ artifact action.
994
+
621
995
  The timeline is extensible: `createToolRegistry` / `defaultToolRegistry` plug
622
996
  per-tool renderers, and the rendering primitives (`ActivityDisclosure`,
623
997
  `ScreenshotFigure`, `TermBlock`, `LightboxProvider`, …) compose custom rows with
@@ -655,6 +1029,97 @@ remaining built-ins in supplied order. Duplicate IDs keep their first
655
1029
  definition; remove a built-in before adding a custom facet with the same ID.
656
1030
  `replace` is type-exclusive with `add` and `remove`.
657
1031
 
1032
+ `turnSummary={{ rolling: true }}` selects the readable per-turn presentation:
1033
+ startup shows the preparation orb outside any disclosure, then hands over to
1034
+ Working without resetting the startup-inclusive elapsed clock. While work is
1035
+ live, assistant progress messages stay fully formatted and visible,
1036
+ followed by one Working or Waiting disclosure with the rolling latest step.
1037
+ When the turn finishes, earlier assistant messages and tools share the Worked
1038
+ disclosure; the final response remains visible. Expanding reveals that turn's
1039
+ earlier prose and activity in chronological order, not a fold of multiple turns.
1040
+ An already expanded or actively read view is preserved through settlement.
1041
+ Routine machine inputs get one compact reason per resumed turn. Normal tip-follow
1042
+ continues through long answers, and manual scrolling never auto-repins on new work.
1043
+ Expanded outer work headers stay reachable at the top of the timeline until
1044
+ their own details end; nested headers never stick. The contextual navigation
1045
+ pill stays below the sticky-header strip and avoids interactive controls. If
1046
+ no horizontal slot fits beside a toolbar, only the pill moves below it; the
1047
+ timeline's size and scroll position do not change.
1048
+
1049
+ The single **Back to your message** button returns to the loaded user prompt
1050
+ associated with the response or work being read: the latest prompt preceding
1051
+ the viewport midpoint. It appears only when that prompt's start is more than
1052
+ 24 px above the viewport and its entire body and attachments are out of view.
1053
+ Clicking synchronously scrolls and focuses that exact
1054
+ mounted prompt near the top and leaves tip-follow. Later messages and queued
1055
+ prompts do not change the destination while the reader remains in older work.
1056
+ An older bounded window uses its own loaded context; a window with no associated
1057
+ prompt shows no action. Navigation never replaces the history window or looks up
1058
+ the globally newest message. There are no previous/next arrows.
1059
+
1060
+ `SessionConversation` includes this behavior automatically. Custom timelines
1061
+ need no prompt-navigation callback:
1062
+
1063
+ ```tsx
1064
+ const events = useSessionEvents(sessionId);
1065
+ <MessageTimeline
1066
+ events={events.events}
1067
+ items={events.timeline}
1068
+ turnSummary={{ rolling: true }}
1069
+ hasNewer={events.hasNewer}
1070
+ onJumpToLatest={events.jumpToLatest}
1071
+ />;
1072
+ ```
1073
+
1074
+ `onJumpToLatest` retains its separate live-bottom behavior. The deprecated
1075
+ `MessageTimeline.onJumpToLatestQuestion` prop remains source-compatible but is
1076
+ not invoked by contextual navigation.
1077
+
1078
+ ### Optional global newest-message lookup
1079
+
1080
+ The public `useSessionEvents().jumpToLatestQuestion()` hook remains available for
1081
+ hosts that deliberately build a **separate** global lookup action. It is not wired
1082
+ to `MessageTimeline` or the first-party conversation's contextual button.
1083
+ The hook checks the authoritative queue and normally uses one filtered forensic
1084
+ lookup plus, if needed, two bounded context reads. It pages past legacy worker
1085
+ completions and withdrawn/cancelled-before-start prompts, never substituting an
1086
+ arbitrary question from a loaded old page. Queued/legacy admission uses filtered
1087
+ lifecycle evidence to locate its real turn start. A distant prompt is retained as
1088
+ one projection-only witness in `events.timeline`; `events.events` remains the
1089
+ bounded contiguous raw window, so pass `items` as above.
1090
+ The optional resolver loads on its first invocation, not when opening a session.
1091
+ Identity and navigation guards also cover that module-loading delay.
1092
+
1093
+ Custom hosts can provide their own queue destination when invoking this hook:
1094
+
1095
+ ```tsx
1096
+ const navigateToNewest = () => events.jumpToLatestQuestion({
1097
+ onQueuedQuestion: async (turn, navigation) => {
1098
+ await queue.refresh();
1099
+ if (!navigation.isCurrent()) return;
1100
+ // Check the host's latest queue/error state before applying its focus request.
1101
+ setQueueFocusTarget((previous) => ({
1102
+ turnId: turn.id,
1103
+ requestId: (previous?.requestId ?? 0) + 1,
1104
+ }));
1105
+ },
1106
+ });
1107
+ // Pass queueFocusTarget to SessionChrome; each new request opens/focuses once.
1108
+ ```
1109
+
1110
+ A queue destination returns `null`, not an invisible transcript sequence. Without
1111
+ `onQueuedQuestion`, a pending prompt rejects with `LatestQuestionQueuedError`;
1112
+ the custom host can show guidance. Transitional queue state can be retried.
1113
+ Check `navigation.isCurrent()` after awaits and immediately before queue UI effects:
1114
+ an explicit history jump can supersede a queued lookup without changing the session.
1115
+ The shared projection predicate supplies execution evidence for older queued turns
1116
+ without `turn.started`, including tools, agent/sandbox activity, startup, recovery,
1117
+ and capacity events. Compact cursor coverage skips coalesced delta runs.
1118
+ `groupTimeline(items)` retains classic
1119
+ grouping; `{ readableTurns: true }` selects the new projection. The deprecated
1120
+ `foldExchanges` option aliases readable turns, not the removed cross-turn fold. See
1121
+ [`docs/design/genie-loading.md`](../../docs/design/genie-loading.md).
1122
+
658
1123
  ## Sandbox surfacing
659
1124
 
660
1125
  An opt-in workbench that surfaces a session's live sandbox — files, terminal,
@@ -674,13 +1139,24 @@ capability document so every surface degrades to a reason instead of crashing.
674
1139
  firehose and the real interactive PTY over the minted `pty-ws` cell.
675
1140
  - `useDesktopStream` — the noVNC socket, hot-swapped on box rollover via
676
1141
  `stream.url.rotated`.
677
- - Components: `WorkspaceDock` (the resizable/collapsible right-hand dock),
1142
+ - Components: `WorkspaceDock` (the resizable/collapsible right-hand dock with a
1143
+ vertical activity rail, persistent visited panels, and a panel-local Hide action),
678
1144
  `FileBrowser` / `SandboxFiles`, `DiffView` / `PierreDiff` / `PierreFile`,
679
1145
  `CodeEditor`, `SandboxTerminal`, and `DesktopViewer`.
680
1146
 
681
1147
  These surfaces pull in [optional peer dependencies](#optional-peer-dependencies)
682
1148
  — install only the ones for surfaces you actually mount.
683
1149
 
1150
+ `SandboxWorkspace` keeps capture-backed file browsing passive, but an explicit
1151
+ live-file open acquires a viewer. Failed opens show the connection error and a
1152
+ retry that renegotiates the viewer instead of leaving a waking spinner running.
1153
+ When composing `SandboxFiles` directly, pass `workspaceError` alongside
1154
+ `liveWorkspaceReady` and supply an `onWakeWorkspace` callback that can retry a
1155
+ failed negotiation. Complete PNG, JPEG, GIF, and WebP reads render as read-only
1156
+ image previews; truncated reads and other binary formats remain non-editable
1157
+ notices. Image previews use the existing bounded file-read path and do not
1158
+ publish or retain additional files.
1159
+
684
1160
  ## Connected Machines (`@opengeni/react/machines`)
685
1161
 
686
1162
  Bring-your-own-compute UI: the Machines dashboard, per-machine metrics, the
@@ -702,11 +1178,15 @@ never pull it in.
702
1178
  plus the `MachineView` / `MachineState` / `MetricSample` view-model types.
703
1179
 
704
1180
  ```tsx
705
- import { MachinesDashboard, useMachines } from "@opengeni/react/machines";
1181
+ import {
1182
+ MACHINES_SESSION_POLL_MS,
1183
+ MachinesDashboard,
1184
+ useMachines,
1185
+ } from "@opengeni/react/machines";
706
1186
 
707
1187
  function Fleet({ sessionId }: { sessionId: string }) {
708
1188
  const { machines, activeSandboxId, attach, attachingSandboxId, refresh } =
709
- useMachines({ sessionId, pollIntervalMs: 5000 });
1189
+ useMachines({ sessionId, pollIntervalMs: MACHINES_SESSION_POLL_MS });
710
1190
  return (
711
1191
  <MachinesDashboard
712
1192
  machines={machines}
@@ -722,11 +1202,46 @@ function Fleet({ sessionId }: { sessionId: string }) {
722
1202
  See the [Connected Machines guide](../../docs/connected-machines.md) for the
723
1203
  end-to-end embedder story (create-on-machine, discover, swap, enroll, revoke).
724
1204
 
1205
+ ## Usage allowances (`@opengeni/react/usage`)
1206
+
1207
+ Show people where they stand against a workspace or member usage allowance.
1208
+ A separate subpath, so hosts that don't meter usage never load it.
1209
+
1210
+ - `useUsage({ workspaceId? })` — the signed-in person's own `/usage/me`
1211
+ (through `getMyUsage` or any client with `requestJson`) plus a summary of
1212
+ which limit binds first. `refreshKey` re-reads when work settles.
1213
+ - `UsageMeter` — "38% left · Resets Nov 1". Shares only; pass `formatAmount`
1214
+ for money, credits or plan multiples. `density="compact"` for menus,
1215
+ `"hero"` to lead a page.
1216
+ - `UsageLimitNotice` — the calm composer line: nothing while comfortable, a
1217
+ dismissible heads-up near the limit, then who can raise it and when it
1218
+ resets. `labels` rewords it; `action` adds your own "Upgrade" button.
1219
+ - `UsageMemberList` — the admin roster with a share-of-budget slider,
1220
+ optional fixed amounts, and a visible note when shares add up to more than
1221
+ the pool. Save rules through your backend in `onChangeRule`.
1222
+
1223
+ ```tsx
1224
+ import { UsageLimitNotice, UsageMeter } from "@opengeni/react/usage";
1225
+
1226
+ <UsageMeter workspaceId={workspaceId} />
1227
+ <SessionConversation
1228
+ sessionId={sessionId}
1229
+ composerProps={{ header: <UsageLimitNotice workspaceId={workspaceId} /> }}
1230
+ allowanceExhaustedLabels={{ memberRemedy: "Ask your team admin for more." }}
1231
+ />
1232
+ ```
1233
+
1234
+ The conversation's "usage limit reached" row is customized on
1235
+ `MessageTimeline`/`SessionConversation` with `allowanceExhaustedLabels` or
1236
+ replaced with `renderAllowanceExhausted`. See
1237
+ [usage allowances](../../docs/usage-allowances.md#react-components-and-the-console).
1238
+
725
1239
  ## Optional peer dependencies
726
1240
 
727
- The chat/timeline surface has none. The sandbox workspace and diff surfaces pull
728
- their heavy libraries from **optional** `peerDependencies`, so you install only
729
- what the surfaces you mount need:
1241
+ The chat/timeline surface needs only the required React/React DOM peers. All
1242
+ existing root exports remain available without optional workbench peers, even
1243
+ when a bundler resolves every reachable dynamic import. Install and enable
1244
+ only the surfaces you mount, once in their client route or bootstrap:
730
1245
 
731
1246
  - Terminal (`SandboxTerminal`): `@xterm/xterm`, `@xterm/addon-fit`,
732
1247
  `@xterm/addon-web-links`.
@@ -736,6 +1251,37 @@ what the surfaces you mount need:
736
1251
  language packs you need (`css`, `html`, `javascript`, `json`, `markdown`,
737
1252
  `python`).
738
1253
 
1254
+ ```ts
1255
+ import { enableSandboxTerminal } from "@opengeni/react/terminal";
1256
+ import { enableDesktopViewer } from "@opengeni/react/desktop";
1257
+ import { enableCodeEditor } from "@opengeni/react/editor";
1258
+
1259
+ enableSandboxTerminal();
1260
+ enableDesktopViewer();
1261
+ enableCodeEditor({
1262
+ javascript: async () =>
1263
+ (await import("@codemirror/lang-javascript")).javascript({ jsx: true, typescript: true }),
1264
+ });
1265
+ ```
1266
+
1267
+ Omit imports and calls for surfaces you do not use. These entries also re-export
1268
+ their components; root component imports continue to work after setup. The
1269
+ libraries load on mount, not during setup or SSR. Import the setup from a lazy
1270
+ route to keep its peer chunks outside the initial conversation graph.
1271
+
1272
+ For optional terminal WebGL acceleration, install `@xterm/addon-webgl` and call
1273
+ `enableSandboxTerminal({ webgl: () => import("@xterm/addon-webgl") })`. Without
1274
+ it, or if it fails, the terminal uses its DOM renderer. Only supply editor
1275
+ grammar loaders for packages you installed; absent/failed grammars use plain
1276
+ CodeMirror. Without editor setup, the existing textarea fallback remains usable.
1277
+ Without terminal/VNC setup, those surfaces show a setup error; relay-frame
1278
+ desktops and a custom `rfbFactory` need no noVNC setup.
1279
+
1280
+ Custom hosts may supply `registerSandboxTerminal`, `registerCodeEditor`, or
1281
+ `registerDesktopViewer` loaders from the root instead. Mounted fallbacks retry
1282
+ when registration changes. Do not hide peer imports behind runtime bare strings
1283
+ or `@vite-ignore`: browsers cannot resolve those without an import map.
1284
+
739
1285
  ## Demo harness
740
1286
 
741
1287
  `bun run demo` (from this package) serves a harness that drives the real hooks
@@ -744,3 +1290,96 @@ with streaming, tool calls, and a worker spawn, plus fleet and scheduled-task
744
1290
  views and a dark/light toggle. `realtime.html` is the public-package reference
745
1291
  consumer described above, with deterministic mock and same-origin live modes.
746
1292
  `bun run demo:build` is part of the repo gate.
1293
+
1294
+ ### Model selection
1295
+
1296
+ `ModelPolicyPicker` opens a flat, searchable list grouped by payment source, with
1297
+ the selected model checked in its provider group. Choosing a model applies it and closes the popover.
1298
+ Thinking and supported speed controls remain in a fixed footer instead of a
1299
+ nested page. Model changes preserve supported reasoning effort and latency;
1300
+ unsupported effort falls back to the new model's default, and unsupported speed
1301
+ returns to Standard. Thinking uses inline radio choices and is hidden when the
1302
+ model has no adjustable reasoning levels. Availability and Codex-only session restrictions still disable choices.
1303
+
1304
+ The trigger renders immediately; the searchable popover loads when opened. Hosts
1305
+ can translate its search, current-selection, empty-result, attachment-warning, and
1306
+ thinking labels through `messages`, and override payment descriptions through
1307
+ `messages.billingHints`.
1308
+
1309
+ The stock deployment-provided group is labeled **Models**, with a generic model
1310
+ icon. It can contain both credit-backed and free models; the **Free** badge
1311
+ depends on the model's explicit cost, not its group. Genuine external-provider
1312
+ and subscription identities retain their own labels and marks.
1313
+
1314
+ Hosts can rebrand the full picker without replacing its interaction logic:
1315
+
1316
+ ```tsx
1317
+ <ModelPolicyPicker
1318
+ {...pickerProps}
1319
+ groupPresentation={{
1320
+ opengeni_credits: {
1321
+ label: "Acme Assist",
1322
+ icon: <AcmeMark aria-hidden="true" />,
1323
+ description: "Provided by your workspace",
1324
+ },
1325
+ codex_subscription: { description: null },
1326
+ }}
1327
+ />
1328
+ ```
1329
+
1330
+ `groupPresentation` is a partial map keyed by `PickerBillingClass`. Labels apply
1331
+ to group headings, search, and trigger-icon accessibility. Icons apply to both
1332
+ the menu and trigger; supply decorative, non-interactive content (SVG or image)
1333
+ that fits the existing 14px slot. Explicit `null` hides an icon or description;
1334
+ omitted fields retain defaults. Descriptions override `messages.billingHints`,
1335
+ can also be shown for the deployment-provided group, and are searchable. Existing
1336
+ `rows[].billingClassLabel` remains the fallback when no label override is supplied.
1337
+ This is presentation only: model IDs, billing, ordering, availability and callbacks
1338
+ are unchanged. The type `ModelPolicyPickerGroupPresentation` is exported from
1339
+ both `@opengeni/react` and `@opengeni/react/composer`. The native `ModelPicker`
1340
+ is a separate control; this API targets the full `ModelPolicyPicker` shown above.
1341
+
1342
+ The complete conversation uses this same neutral picker. Customize its appearance
1343
+ without replacing composer controls through `SessionConversation.modelPickerProps`,
1344
+ or through `OpenGeniChat.conversationProps`:
1345
+
1346
+ ```tsx
1347
+ <OpenGeniChat
1348
+ client={client}
1349
+ workspaceId={workspaceId}
1350
+ conversationProps={{
1351
+ modelPickerProps: {
1352
+ groupPresentation: {
1353
+ opengeni_credits: { label: "Acme Assist", icon: <AcmeMark aria-hidden="true" /> },
1354
+ },
1355
+ messages: { label: "Choose a model" },
1356
+ },
1357
+ }}
1358
+ />
1359
+ ```
1360
+
1361
+ `modelPickerProps` accepts only `groupPresentation` and `messages`; it does not
1362
+ enable a hidden picker or change policy, model availability or callbacks. Keep
1363
+ model-picker visibility controlled by `modelPicker` and the client configuration.
1364
+
1365
+ For a rendered example, open the composer-responsive demo with `?branding=host`.
1366
+
1367
+ Models always show their clean name and maker logo: picker rows carry
1368
+ `modelDisplayName(model)` (`claude-opus-4-8` and
1369
+ `organization-claude-subscription/claude-opus-5-5` read `Claude Opus 4.8` and
1370
+ `Claude Opus 5.5`) and a `ModelMark`. Organization- and workspace-connected API
1371
+ keys share one "API keys" group, and identical copies of one model in a
1372
+ connection group show once. Render a model anywhere else with
1373
+ `<ModelName model={id} />`, or `modelDisplayName` / `modelVendor` from
1374
+ `@opengeni/react` or `@opengeni/sdk/model-display`. The trigger keeps a host's
1375
+ explicit group icon; otherwise API-key models show the maker's logo.
1376
+
1377
+ Subscription descriptions appear once per provider group. Free models carry a
1378
+ Free badge. Pass `hasImageAttachments` for the current draft to show an image
1379
+ compatibility warning only when the selected model cannot view those images.
1380
+
1381
+ `MessageTimeline.renderMessageActions(item)` places host-owned controls beside
1382
+ Copy and the timestamp for user messages and completed assistant messages.
1383
+ The host owns feedback, fork authorization, and mutations; streaming assistant
1384
+ messages omit this slot. Use the `group/copy` hover/focus state and preserve
1385
+ visible touch targets when styling actions.