@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
@@ -0,0 +1,92 @@
1
+ import { OpenGeniBrowserClient } from "@opengeni/sdk/browser";
2
+ import { useEffect, useMemo, useState, type ReactNode } from "react";
3
+ import { OpenGeniProvider } from "../provider";
4
+
5
+ export type SessionProxyBaseUrl = {
6
+ /**
7
+ * Mount path of your `createSessionProxyHandler` (for example
8
+ * `"/api/opengeni"`). The component then needs no `OpenGeniProvider`,
9
+ * client, or workspace id: it creates the browser client for that path and
10
+ * uses the workspace the proxy resolved for the signed-in user. An explicit
11
+ * `workspaceId` skips that lookup.
12
+ */
13
+ baseUrl?: string | undefined;
14
+ };
15
+
16
+ type ScopeState =
17
+ | { status: "loading" }
18
+ | { status: "ready"; workspaceId: string }
19
+ | { status: "error"; message: string };
20
+
21
+ /**
22
+ * `OpenGeniProvider` for a same-origin session proxy, from its base URL alone.
23
+ * The proxy's client config names the resolved workspace, so the browser
24
+ * never handles an Opengeni id. Provider-based usage is unchanged.
25
+ */
26
+ export function SessionProxyScope({
27
+ baseUrl,
28
+ workspaceId,
29
+ children,
30
+ }: {
31
+ baseUrl: string;
32
+ workspaceId?: string | undefined;
33
+ children: ReactNode;
34
+ }) {
35
+ // Version skew between this bundle and the server SDK is tolerated, as for
36
+ // any embedded host: the proxy reports its own contract revision.
37
+ const client = useMemo(
38
+ () => new OpenGeniBrowserClient({ baseUrl, apiContract: "compatible" }),
39
+ [baseUrl],
40
+ );
41
+ const [state, setState] = useState<ScopeState>(
42
+ workspaceId ? { status: "ready", workspaceId } : { status: "loading" },
43
+ );
44
+ useEffect(() => {
45
+ if (workspaceId) {
46
+ setState({ status: "ready", workspaceId });
47
+ return;
48
+ }
49
+ let active = true;
50
+ setState({ status: "loading" });
51
+ client.getClientConfig().then(
52
+ (config) => {
53
+ if (!active) return;
54
+ setState(
55
+ config.workspaceId
56
+ ? { status: "ready", workspaceId: config.workspaceId }
57
+ : {
58
+ status: "error",
59
+ message:
60
+ "This server does not report its workspace. Update @opengeni/sdk on the server, or pass workspaceId.",
61
+ },
62
+ );
63
+ },
64
+ (error: unknown) => {
65
+ if (!active) return;
66
+ setState({
67
+ status: "error",
68
+ message: error instanceof Error ? error.message : "Could not load the conversation.",
69
+ });
70
+ },
71
+ );
72
+ return () => {
73
+ active = false;
74
+ };
75
+ }, [client, workspaceId]);
76
+
77
+ if (state.status === "error") {
78
+ return (
79
+ <div role="alert" className="og-root p-3 text-og-sm text-og-danger" data-og-proxy-error="">
80
+ {state.message}
81
+ </div>
82
+ );
83
+ }
84
+ if (state.status === "loading") {
85
+ return <div className="og-root" aria-busy="true" data-og-proxy-loading="" />;
86
+ }
87
+ return (
88
+ <OpenGeniProvider client={client} workspaceId={state.workspaceId}>
89
+ {children}
90
+ </OpenGeniProvider>
91
+ );
92
+ }
@@ -15,7 +15,7 @@ export const SESSION_STATUS_META: Record<SessionStatusValue, SessionStatusMeta>
15
15
  label: "Queued",
16
16
  dotClassName: "bg-og-status-queued",
17
17
  badgeClassName: "text-og-fg-muted border-og-border bg-og-status-queued/10",
18
- pulse: true,
18
+ pulse: false,
19
19
  },
20
20
  running: {
21
21
  label: "Running",
@@ -0,0 +1,119 @@
1
+ import { Component, type ReactNode } from "react";
2
+
3
+ type Anchor = {
4
+ element: HTMLElement;
5
+ key: string | null;
6
+ text: string | null;
7
+ top: number;
8
+ focused?: boolean;
9
+ };
10
+ export type TimelineAnchor = Anchor[];
11
+
12
+ /** Read ownership synchronously: selectionchange may follow the next React commit. */
13
+ export function timelineHasReader(scroller: HTMLElement | null): boolean {
14
+ if (!scroller) return false;
15
+ const focused = scroller.ownerDocument.activeElement;
16
+ const selection = scroller.ownerDocument.getSelection();
17
+ return Boolean(
18
+ (focused && focused !== scroller && scroller.contains(focused)) ||
19
+ (selection &&
20
+ !selection.isCollapsed &&
21
+ (scroller.contains(selection.anchorNode) || scroller.contains(selection.focusNode))),
22
+ );
23
+ }
24
+
25
+ /** Read the old DOM immediately before React changes it, not when a fetch starts. */
26
+ export class TimelineBeforeLayout extends Component<{
27
+ capture: () => void;
28
+ children: ReactNode;
29
+ }> {
30
+ getSnapshotBeforeUpdate() {
31
+ this.props.capture();
32
+ return null;
33
+ }
34
+ componentDidUpdate() {}
35
+ render() {
36
+ return this.props.children;
37
+ }
38
+ }
39
+
40
+ export function captureTimelineAnchor(scroller: HTMLElement): TimelineAnchor | null {
41
+ const viewport = scroller.getBoundingClientRect();
42
+ if (viewport.height <= 0) return null;
43
+ // Capture each box once: these measurements share one pre-commit DOM snapshot.
44
+ const groups = Array.from(scroller.querySelectorAll<HTMLElement>("[data-og-group-key]"))
45
+ .map((element) => ({ element, rect: element.getBoundingClientRect() }))
46
+ .filter(({ rect }) => rect.height > 0);
47
+ const anchors: TimelineAnchor = [];
48
+ let stickyFocus: Anchor | undefined;
49
+ // A disclosure is the reader's explicit point of interaction. In particular,
50
+ // anchoring a paragraph below an expanding disclosure would move its button.
51
+ const focused = scroller.ownerDocument.activeElement;
52
+ if (focused instanceof HTMLElement && scroller.contains(focused) && focused !== scroller) {
53
+ const box = focused.getBoundingClientRect();
54
+ if (box.bottom > viewport.top && box.top < viewport.bottom) {
55
+ const anchor = { element: focused, key: null, text: null, top: box.top, focused: true };
56
+ const section = focused.closest("[data-og-work-section]");
57
+ // A stuck header stays put even when its section moves. Anchor the work
58
+ // being read beneath it instead, while still retaining its focus identity.
59
+ if (
60
+ focused.matches('[data-og-work-header="outer"]') &&
61
+ section &&
62
+ section.getBoundingClientRect().top < box.top - 1
63
+ )
64
+ stickyFocus = anchor;
65
+ else anchors.push(anchor);
66
+ }
67
+ }
68
+ // A paragraph survives even when earlier deltas reconstruct its containing message.
69
+ for (const { element: group, rect } of groups) {
70
+ if (rect.bottom <= viewport.top || rect.top >= viewport.bottom) continue;
71
+ for (const element of group.querySelectorAll<HTMLElement>("p, li, pre, h1, h2, h3, h4")) {
72
+ const box = element.getBoundingClientRect();
73
+ const text = element.textContent;
74
+ if (box.bottom > viewport.top && box.top < viewport.bottom && text && text.length >= 12) {
75
+ anchors.push({ element, key: null, text, top: box.top });
76
+ }
77
+ }
78
+ }
79
+ // Prefer a retained visible row, then a following row. A following row also
80
+ // anchors the unchanged suffix of a partially loaded message above it.
81
+ const rows = groups.map(({ element, rect }) => ({
82
+ element,
83
+ key: element.getAttribute("data-og-group-key"),
84
+ text: null,
85
+ top: rect.top,
86
+ }));
87
+ anchors.push(...rows.filter((row) => row.top >= viewport.top));
88
+ anchors.push(...rows.filter((row) => row.top < viewport.top).reverse());
89
+ if (stickyFocus) anchors.push(stickyFocus);
90
+ return anchors;
91
+ }
92
+
93
+ /** Return only the correction native browser anchoring has not already made. */
94
+ export function timelineAnchorCorrection(
95
+ scroller: HTMLElement,
96
+ anchors: TimelineAnchor,
97
+ ): number | null {
98
+ let blocks: HTMLElement[] | undefined;
99
+ let groups: HTMLElement[] | undefined;
100
+ for (const anchor of anchors) {
101
+ let element: HTMLElement | undefined;
102
+ if (
103
+ scroller.contains(anchor.element) &&
104
+ (!anchor.text || anchor.element.textContent === anchor.text)
105
+ ) {
106
+ element = anchor.element;
107
+ } else if (anchor.key) {
108
+ groups ??= Array.from(scroller.querySelectorAll<HTMLElement>("[data-og-group-key]"));
109
+ element = groups.find((group) => group.getAttribute("data-og-group-key") === anchor.key);
110
+ } else if (anchor.text) {
111
+ blocks ??= Array.from(scroller.querySelectorAll<HTMLElement>("p, li, pre, h1, h2, h3, h4"));
112
+ const matches = blocks.filter((block) => block.textContent === anchor.text);
113
+ // Repeated boilerplate is not sufficient evidence of retained content.
114
+ if (matches.length === 1) element = matches[0];
115
+ }
116
+ if (element) return element.getBoundingClientRect().top - anchor.top;
117
+ }
118
+ return null;
119
+ }
@@ -0,0 +1,196 @@
1
+ import type {
2
+ DraftTimelineAnnotation,
3
+ TimelineAnnotation,
4
+ TimelineAnnotationSource,
5
+ } from "@opengeni/sdk";
6
+ import { useLayoutEffect, useRef, useState, type ReactNode } from "react";
7
+ import { cn } from "../lib/cn";
8
+ import { annotationNoteNeedsDisclosure } from "./timeline-annotation-layout";
9
+ import { useTimelineAnnotationSourceRoot } from "./timeline-annotation-reveal-context";
10
+ import {
11
+ annotationSourceLabel,
12
+ revealLoadedAnnotationSource,
13
+ truncateAnnotationQuote,
14
+ } from "./timeline-annotation-shared";
15
+
16
+ export type TimelineAnnotationLike = DraftTimelineAnnotation | TimelineAnnotation;
17
+
18
+ const NOTE_MAX_HEIGHT_PX = 160;
19
+
20
+ function autosizeNote(textarea: HTMLTextAreaElement | null): void {
21
+ if (!textarea) return;
22
+ textarea.style.height = "auto";
23
+ textarea.style.height = `${Math.min(Math.max(textarea.scrollHeight, 32), NOTE_MAX_HEIGHT_PX)}px`;
24
+ }
25
+
26
+ function quotePreview(quote: string): { text: string; multiline: boolean } {
27
+ const trimmed = quote.trim();
28
+ const multiline = trimmed.includes("\n");
29
+ return {
30
+ text: multiline ? trimmed : trimmed.replace(/\s+/g, " "),
31
+ multiline,
32
+ };
33
+ }
34
+
35
+ export function AnnotationQuoteSourceButton({
36
+ annotation,
37
+ lines = 2,
38
+ onRevealSource,
39
+ onUnavailable,
40
+ }: {
41
+ annotation: TimelineAnnotationLike;
42
+ lines?: 2 | 3;
43
+ onRevealSource?: ((source: TimelineAnnotationSource) => boolean) | undefined;
44
+ onUnavailable: (id: string | null) => void;
45
+ }) {
46
+ const preview = quotePreview(annotation.quote);
47
+ const sourceLabel = annotationSourceLabel(annotation.source);
48
+ const sourceRoot = useTimelineAnnotationSourceRoot();
49
+ return (
50
+ <button
51
+ type="button"
52
+ title={annotation.quote}
53
+ aria-label={`View ${sourceLabel} source: ${truncateAnnotationQuote(annotation.quote, 88)}`}
54
+ className="block w-full min-w-0 rounded-sm border-0 bg-transparent text-left text-og-sm leading-5 text-og-fg-muted outline-hidden transition-colors hover:text-og-fg focus-visible:ring-2 focus-visible:ring-og-accent pointer-coarse:min-h-[44px]"
55
+ onClick={() => {
56
+ const revealed =
57
+ onRevealSource?.(annotation.source) ??
58
+ (sourceRoot
59
+ ? revealLoadedAnnotationSource(annotation.source, sourceRoot.current)
60
+ : revealLoadedAnnotationSource(annotation.source));
61
+ onUnavailable(revealed ? null : annotation.id);
62
+ }}
63
+ >
64
+ <span
65
+ className={cn(
66
+ "block min-w-0 max-w-full break-words",
67
+ preview.multiline ? "whitespace-pre-wrap" : "whitespace-normal",
68
+ lines === 3 ? "line-clamp-3" : "line-clamp-2",
69
+ )}
70
+ >
71
+ {preview.text}
72
+ </span>
73
+ <span className="sr-only"> view source</span>
74
+ </button>
75
+ );
76
+ }
77
+
78
+ export function AnnotationAccentRow({
79
+ children,
80
+ className,
81
+ }: {
82
+ children: ReactNode;
83
+ className?: string | undefined;
84
+ }) {
85
+ return (
86
+ <div className={cn("flex gap-2.5", className)}>
87
+ <div aria-hidden="true" className="w-0.5 shrink-0 rounded-full bg-og-accent/55" />
88
+ <div className="min-w-0 flex-1">{children}</div>
89
+ </div>
90
+ );
91
+ }
92
+
93
+ export function AnnotationNotePreview({
94
+ note,
95
+ annotationId,
96
+ ordinal,
97
+ className,
98
+ }: {
99
+ note: string;
100
+ annotationId: string;
101
+ ordinal: number;
102
+ className?: string | undefined;
103
+ }) {
104
+ const [expanded, setExpanded] = useState(false);
105
+ if (!note) return null;
106
+ const collapsible = annotationNoteNeedsDisclosure(note);
107
+ const contentId = `og-annotation-note-${annotationId}`;
108
+ return (
109
+ <div className={className}>
110
+ <p
111
+ id={contentId}
112
+ data-og-annotation-note=""
113
+ data-og-annotation-note-expanded={expanded ? "true" : "false"}
114
+ className={cn(
115
+ "mt-0.5 break-words whitespace-pre-wrap text-og-sm leading-5 text-og-fg",
116
+ !expanded && "line-clamp-4",
117
+ )}
118
+ >
119
+ {note}
120
+ </p>
121
+ {collapsible ? (
122
+ <button
123
+ type="button"
124
+ className="mt-0.5 inline-flex min-h-7 items-center rounded-og-sm px-1 text-og-xs font-medium text-og-fg-muted outline-hidden hover:text-og-fg focus-visible:ring-2 focus-visible:ring-og-accent pointer-coarse:min-h-11"
125
+ aria-expanded={expanded}
126
+ aria-controls={contentId}
127
+ aria-label={
128
+ expanded ? `Show less annotation ${ordinal}` : `Show more annotation ${ordinal}`
129
+ }
130
+ onClick={() => setExpanded((current) => !current)}
131
+ >
132
+ {expanded ? "Show less" : "Show more"}
133
+ </button>
134
+ ) : null}
135
+ </div>
136
+ );
137
+ }
138
+
139
+ export function AnnotationNoteField({
140
+ annotation,
141
+ inputRef,
142
+ onUpdate,
143
+ onCommit,
144
+ }: {
145
+ annotation: TimelineAnnotationLike;
146
+ inputRef?: ((node: HTMLTextAreaElement | null) => void) | undefined;
147
+ onUpdate: (id: string, note: string) => void;
148
+ onCommit?: (() => void) | undefined;
149
+ }) {
150
+ const localRef = useRef<HTMLTextAreaElement | null>(null);
151
+ const setRef = (node: HTMLTextAreaElement | null) => {
152
+ localRef.current = node;
153
+ inputRef?.(node);
154
+ };
155
+
156
+ useLayoutEffect(() => {
157
+ const textarea = localRef.current;
158
+ if (!textarea) return;
159
+ // Ref callbacks can reattach on every scroll-driven parent render. Reflowing
160
+ // unchanged notes there interrupts native scrolling, particularly in WebKit.
161
+ autosizeNote(textarea);
162
+ if (typeof ResizeObserver === "undefined") return;
163
+ let width = textarea.getBoundingClientRect().width;
164
+ const observer = new ResizeObserver(() => {
165
+ const nextWidth = textarea.getBoundingClientRect().width;
166
+ if (nextWidth === width) return;
167
+ width = nextWidth;
168
+ autosizeNote(textarea);
169
+ });
170
+ observer.observe(textarea);
171
+ return () => observer.disconnect();
172
+ }, [annotation.note]);
173
+
174
+ return (
175
+ <textarea
176
+ ref={setRef}
177
+ value={annotation.note}
178
+ rows={1}
179
+ maxLength={2048}
180
+ placeholder="Add a note…"
181
+ aria-label="Note"
182
+ className="mt-0.5 max-h-40 min-h-8 w-full resize-none overflow-y-auto break-words border-0 bg-transparent px-0 py-1 text-og-sm leading-5 text-og-fg outline-hidden placeholder:text-og-fg-subtle focus-visible:ring-0"
183
+ onInput={(event) => {
184
+ autosizeNote(event.currentTarget);
185
+ onUpdate(annotation.id, event.currentTarget.value);
186
+ }}
187
+ onKeyDown={(event) => {
188
+ if (event.key !== "Enter" || event.shiftKey || event.nativeEvent.isComposing) return;
189
+ event.preventDefault();
190
+ event.stopPropagation();
191
+ if (event.currentTarget.value.trim().length === 0) return;
192
+ onCommit?.();
193
+ }}
194
+ />
195
+ );
196
+ }
@@ -0,0 +1,268 @@
1
+ export type AnnotationBox = {
2
+ left: number;
3
+ right: number;
4
+ top: number;
5
+ bottom: number;
6
+ };
7
+
8
+ export type AnnotationBadgeAnchor = {
9
+ id: string;
10
+ ordinal: number;
11
+ left: number;
12
+ top: number;
13
+ incomplete: boolean;
14
+ };
15
+
16
+ export const ANNOTATION_BADGE_GAP_PX = 32;
17
+ export const ANNOTATION_BADGE_MIN_GAP_PX = 12;
18
+ export const ANNOTATION_REVIEW_DIALOG_WIDTH_PX = 400;
19
+ export const ANNOTATION_REVIEW_DIALOG_MAX_HEIGHT_PX = 32 * 16;
20
+ export const ANNOTATION_REVIEW_DIALOG_MIN_HEIGHT_PX = 160;
21
+ export const ANNOTATION_REVIEW_DIALOG_FLOOR_HEIGHT_PX = 80;
22
+ export const ANNOTATION_REVIEW_MARGIN_PX = 12;
23
+ export const ANNOTATION_NOTE_PREVIEW_CHARS = 280;
24
+ export const ANNOTATION_CARD_STACK_SCROLL_AT = 4;
25
+
26
+ function clampAnnotationAxis(value: number, min: number, max: number): number {
27
+ return Math.min(Math.max(value, min), Math.max(min, max));
28
+ }
29
+
30
+ export function annotationBoxIntersects(a: AnnotationBox, b: AnnotationBox): boolean {
31
+ return a.left <= b.right && a.right >= b.left && a.top <= b.bottom && a.bottom >= b.top;
32
+ }
33
+
34
+ export function annotationViewportBox(
35
+ viewportWidth: number,
36
+ viewportHeight: number,
37
+ scroller?: AnnotationBox | null,
38
+ ): AnnotationBox {
39
+ const viewport: AnnotationBox = {
40
+ left: 0,
41
+ top: 0,
42
+ right: Math.max(1, viewportWidth),
43
+ bottom: Math.max(1, viewportHeight),
44
+ };
45
+ if (!scroller || scroller.right - scroller.left <= 0 || scroller.bottom - scroller.top <= 0) {
46
+ return viewport;
47
+ }
48
+ return {
49
+ left: Math.max(viewport.left, scroller.left),
50
+ top: Math.max(viewport.top, scroller.top),
51
+ right: Math.min(viewport.right, scroller.right),
52
+ bottom: Math.min(viewport.bottom, scroller.bottom),
53
+ };
54
+ }
55
+
56
+ export function annotationNoteNeedsDisclosure(note: string): boolean {
57
+ const trimmed = note.trim();
58
+ if (trimmed.length === 0) return false;
59
+ return trimmed.length > ANNOTATION_NOTE_PREVIEW_CHARS || trimmed.split("\n").length > 4;
60
+ }
61
+
62
+ function annotationAxisStops(min: number, max: number, gap: number): number[] {
63
+ if (max <= min) return [min];
64
+ const stops: number[] = [];
65
+ for (let value = min; value <= max + 1e-6; value += gap) {
66
+ stops.push(value);
67
+ }
68
+ return stops;
69
+ }
70
+
71
+ function annotationPointKey(left: number, top: number): string {
72
+ return `${Math.round(left * 100) / 100},${Math.round(top * 100) / 100}`;
73
+ }
74
+
75
+ function annotationPointFree(
76
+ left: number,
77
+ top: number,
78
+ placed: readonly AnnotationBadgeAnchor[],
79
+ gap: number,
80
+ ): boolean {
81
+ return placed.every((other) => Math.hypot(left - other.left, top - other.top) >= gap);
82
+ }
83
+
84
+ export function annotationBadgePackGap(
85
+ viewport: AnnotationBox,
86
+ count: number,
87
+ preferred = ANNOTATION_BADGE_GAP_PX,
88
+ ): number {
89
+ if (count <= 1) return preferred;
90
+ const width = Math.max(
91
+ 1,
92
+ viewport.right - ANNOTATION_REVIEW_MARGIN_PX - (viewport.left + ANNOTATION_REVIEW_MARGIN_PX),
93
+ );
94
+ const height = Math.max(1, viewport.bottom - ANNOTATION_REVIEW_MARGIN_PX - (viewport.top + 8));
95
+ let gap = preferred;
96
+ const capacity = (step: number) =>
97
+ (Math.floor(width / step) + 1) * (Math.floor(height / step) + 1);
98
+ while (gap > ANNOTATION_BADGE_MIN_GAP_PX && capacity(gap) < count) {
99
+ gap -= 1;
100
+ }
101
+ return gap;
102
+ }
103
+
104
+ const ANNOTATION_BADGE_SHIFT_DIRS: Array<[number, number]> = [
105
+ [1, 0],
106
+ [1, 1],
107
+ [0, 1],
108
+ [-1, 1],
109
+ [-1, 0],
110
+ [-1, -1],
111
+ [0, -1],
112
+ [1, -1],
113
+ ];
114
+
115
+ export function layoutAnnotationBadges(
116
+ anchors: readonly AnnotationBadgeAnchor[],
117
+ viewport: AnnotationBox,
118
+ preferredGap = ANNOTATION_BADGE_GAP_PX,
119
+ ): AnnotationBadgeAnchor[] {
120
+ const minLeft = viewport.left + ANNOTATION_REVIEW_MARGIN_PX;
121
+ const maxLeft = viewport.right - ANNOTATION_REVIEW_MARGIN_PX;
122
+ const minTop = viewport.top + 8;
123
+ const maxTop = viewport.bottom - ANNOTATION_REVIEW_MARGIN_PX;
124
+ const gap = annotationBadgePackGap(viewport, anchors.length, preferredGap);
125
+ const cells = annotationAxisStops(minLeft, maxLeft, gap).flatMap((left) =>
126
+ annotationAxisStops(minTop, maxTop, gap).map((top) => ({ left, top })),
127
+ );
128
+ const placed: AnnotationBadgeAnchor[] = [];
129
+ for (const anchor of [...anchors].sort((left, right) => left.ordinal - right.ordinal)) {
130
+ const originLeft = clampAnnotationAxis(anchor.left, minLeft, maxLeft);
131
+ const originTop = clampAnnotationAxis(anchor.top, minTop, maxTop);
132
+ const seen = new Set<string>();
133
+ const candidates: Array<{ left: number; top: number }> = [];
134
+ const pushCandidate = (left: number, top: number) => {
135
+ if (left < minLeft || left > maxLeft || top < minTop || top > maxTop) return;
136
+ const key = annotationPointKey(left, top);
137
+ if (seen.has(key)) return;
138
+ seen.add(key);
139
+ candidates.push({ left, top });
140
+ };
141
+ pushCandidate(originLeft, originTop);
142
+ for (const [dx, dy] of ANNOTATION_BADGE_SHIFT_DIRS) {
143
+ const colliders = [...placed].sort(
144
+ (left, right) => right.left * dx + right.top * dy - (left.left * dx + left.top * dy),
145
+ );
146
+ for (const collider of colliders) {
147
+ pushCandidate(collider.left + dx * gap, collider.top + dy * gap);
148
+ }
149
+ }
150
+ const maxRadius =
151
+ Math.ceil(Math.max(maxLeft - minLeft, maxTop - minTop) / Math.max(gap, 1)) + 1;
152
+ for (let radius = 1; radius <= maxRadius; radius++) {
153
+ const ring: Array<[number, number]> = [];
154
+ for (let dx = -radius; dx <= radius; dx++) {
155
+ for (let dy = -radius; dy <= radius; dy++) {
156
+ if (Math.max(Math.abs(dx), Math.abs(dy)) !== radius) continue;
157
+ ring.push([dx, dy]);
158
+ }
159
+ }
160
+ ring.sort((left, right) => {
161
+ const leftDir = (left[0] < 0 ? 2 : 0) + (left[1] < 0 ? 1 : 0);
162
+ const rightDir = (right[0] < 0 ? 2 : 0) + (right[1] < 0 ? 1 : 0);
163
+ if (leftDir !== rightDir) return leftDir - rightDir;
164
+ const hypot = Math.hypot(left[0], left[1]) - Math.hypot(right[0], right[1]);
165
+ if (hypot !== 0) return hypot;
166
+ if (left[0] !== right[0]) return right[0] - left[0];
167
+ return left[1] - right[1];
168
+ });
169
+ for (const [dx, dy] of ring) {
170
+ pushCandidate(originLeft + dx * gap, originTop + dy * gap);
171
+ }
172
+ }
173
+ for (const cell of cells) {
174
+ pushCandidate(cell.left, cell.top);
175
+ }
176
+ const free = candidates.find((point) =>
177
+ annotationPointFree(point.left, point.top, placed, gap),
178
+ );
179
+ let chosen = free ?? candidates[0]!;
180
+ if (!free && placed.length > 0) {
181
+ let bestMin = Number.NEGATIVE_INFINITY;
182
+ for (const point of candidates) {
183
+ const minDist = placed.reduce(
184
+ (current, other) =>
185
+ Math.min(current, Math.hypot(point.left - other.left, point.top - other.top)),
186
+ Number.POSITIVE_INFINITY,
187
+ );
188
+ if (minDist > bestMin) {
189
+ bestMin = minDist;
190
+ chosen = point;
191
+ }
192
+ }
193
+ }
194
+ placed.push({ ...anchor, left: chosen.left, top: chosen.top });
195
+ }
196
+ return placed;
197
+ }
198
+
199
+ export function scrollAnnotationRowIntoList(
200
+ list: HTMLElement | null | undefined,
201
+ row: HTMLElement | null | undefined,
202
+ ): void {
203
+ if (!list || !row || !list.contains(row)) return;
204
+ const listRect = list.getBoundingClientRect();
205
+ const rowRect = row.getBoundingClientRect();
206
+ if (rowRect.top < listRect.top) {
207
+ list.scrollTop -= listRect.top - rowRect.top;
208
+ return;
209
+ }
210
+ if (rowRect.bottom > listRect.bottom) {
211
+ list.scrollTop += rowRect.bottom - listRect.bottom;
212
+ }
213
+ }
214
+
215
+ export function clampAnnotationDialogPlacement(input: {
216
+ triggerLeft: number;
217
+ triggerTop: number;
218
+ triggerBottom: number;
219
+ contentHeight: number;
220
+ viewportWidth: number;
221
+ viewportHeight: number;
222
+ panelWidth?: number;
223
+ }): {
224
+ left: number;
225
+ top: number;
226
+ maxHeight: number;
227
+ above: boolean;
228
+ } {
229
+ const margin = ANNOTATION_REVIEW_MARGIN_PX;
230
+ const panelWidth = Math.min(
231
+ input.panelWidth ?? ANNOTATION_REVIEW_DIALOG_WIDTH_PX,
232
+ Math.max(1, input.viewportWidth - margin * 2),
233
+ );
234
+ const left = Math.min(
235
+ Math.max(margin, input.triggerLeft),
236
+ Math.max(margin, input.viewportWidth - panelWidth - margin),
237
+ );
238
+ const spaceBelow = input.viewportHeight - input.triggerBottom - margin;
239
+ const spaceAbove = input.triggerTop - margin;
240
+ const above = spaceBelow < Math.min(input.contentHeight, 200) && spaceAbove > spaceBelow;
241
+ const viewportBudget = Math.max(
242
+ ANNOTATION_REVIEW_DIALOG_FLOOR_HEIGHT_PX,
243
+ input.viewportHeight - margin * 2,
244
+ );
245
+ const available = Math.max(
246
+ Math.min(ANNOTATION_REVIEW_DIALOG_MIN_HEIGHT_PX, viewportBudget),
247
+ above ? spaceAbove : spaceBelow,
248
+ );
249
+ let maxHeight = Math.min(
250
+ Math.max(input.contentHeight, Math.min(ANNOTATION_REVIEW_DIALOG_MIN_HEIGHT_PX, viewportBudget)),
251
+ available,
252
+ Math.floor(input.viewportHeight * 0.7) || viewportBudget,
253
+ ANNOTATION_REVIEW_DIALOG_MAX_HEIGHT_PX,
254
+ viewportBudget,
255
+ );
256
+ let top = above
257
+ ? Math.max(margin, input.triggerTop - 8 - maxHeight)
258
+ : Math.min(
259
+ input.triggerBottom + 8,
260
+ Math.max(margin, input.viewportHeight - margin - maxHeight),
261
+ );
262
+ top = Math.max(margin, top);
263
+ maxHeight = Math.min(
264
+ maxHeight,
265
+ Math.max(ANNOTATION_REVIEW_DIALOG_FLOOR_HEIGHT_PX, input.viewportHeight - margin - top),
266
+ );
267
+ return { left, top, maxHeight, above };
268
+ }