@opengeni/react 3.3.2 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (855) hide show
  1. package/README.md +769 -22
  2. package/dist/accounts.js +2 -0
  3. package/dist/accounts.js.map +1 -1
  4. package/dist/approvals.d.ts +2 -1
  5. package/dist/artifacts-document.js +5 -3
  6. package/dist/artifacts-presentation.js +5 -3
  7. package/dist/artifacts-spreadsheet.d.ts +1 -1
  8. package/dist/artifacts-spreadsheet.js +5 -3
  9. package/dist/artifacts.d.ts +5 -1
  10. package/dist/artifacts.js +536 -42
  11. package/dist/artifacts.js.map +1 -1
  12. package/dist/browser-viewer-ZWR6MWJ7.js +19 -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-4EUKJXUO.js +14 -0
  16. package/dist/chunk-2DDJ6YH6.js +41 -0
  17. package/dist/chunk-2DDJ6YH6.js.map +1 -0
  18. package/dist/chunk-2HVLQ26H.js +183 -0
  19. package/dist/chunk-2HVLQ26H.js.map +1 -0
  20. package/dist/{chunk-XYRDDSXF.js → chunk-2I6R3GCZ.js} +4285 -3980
  21. package/dist/chunk-2I6R3GCZ.js.map +1 -0
  22. package/dist/{chunk-JAQ5K7W6.js → chunk-2SFFYIH3.js} +1178 -166
  23. package/dist/chunk-2SFFYIH3.js.map +1 -0
  24. package/dist/chunk-3PVDYTTB.js +24 -0
  25. package/dist/chunk-3PVDYTTB.js.map +1 -0
  26. package/dist/chunk-3RJKUVCA.js +14068 -0
  27. package/dist/chunk-3RJKUVCA.js.map +1 -0
  28. package/dist/chunk-3UZCWK46.js +298 -0
  29. package/dist/chunk-3UZCWK46.js.map +1 -0
  30. package/dist/chunk-47CKUXTW.js +293 -0
  31. package/dist/chunk-47CKUXTW.js.map +1 -0
  32. package/dist/chunk-4QYP6QUI.js +109 -0
  33. package/dist/chunk-4QYP6QUI.js.map +1 -0
  34. package/dist/chunk-5EY26VZ7.js +1053 -0
  35. package/dist/chunk-5EY26VZ7.js.map +1 -0
  36. package/dist/chunk-5I4VRWBB.js +56 -0
  37. package/dist/chunk-5I4VRWBB.js.map +1 -0
  38. package/dist/chunk-5WOR7UCL.js +191 -0
  39. package/dist/chunk-5WOR7UCL.js.map +1 -0
  40. package/dist/chunk-5YJLGOM5.js +51 -0
  41. package/dist/chunk-5YJLGOM5.js.map +1 -0
  42. package/dist/chunk-6JFN3OWG.js +386 -0
  43. package/dist/chunk-6JFN3OWG.js.map +1 -0
  44. package/dist/chunk-7QJT5O4S.js +35 -0
  45. package/dist/chunk-7QJT5O4S.js.map +1 -0
  46. package/dist/chunk-A55KV72M.js +402 -0
  47. package/dist/chunk-A55KV72M.js.map +1 -0
  48. package/dist/chunk-ADWCLI4G.js +2028 -0
  49. package/dist/chunk-ADWCLI4G.js.map +1 -0
  50. package/dist/chunk-B27E3V37.js +29 -0
  51. package/dist/chunk-B27E3V37.js.map +1 -0
  52. package/dist/chunk-B7TC2A33.js +83 -0
  53. package/dist/chunk-B7TC2A33.js.map +1 -0
  54. package/dist/chunk-BLL56F7R.js +385 -0
  55. package/dist/chunk-BLL56F7R.js.map +1 -0
  56. package/dist/chunk-BOFEQC6K.js +162 -0
  57. package/dist/chunk-BOFEQC6K.js.map +1 -0
  58. package/dist/chunk-CM7LVUKC.js +35 -0
  59. package/dist/chunk-CM7LVUKC.js.map +1 -0
  60. package/dist/chunk-CORUP6JB.js +122 -0
  61. package/dist/chunk-CORUP6JB.js.map +1 -0
  62. package/dist/chunk-CSX5FFKZ.js +35 -0
  63. package/dist/chunk-CSX5FFKZ.js.map +1 -0
  64. package/dist/chunk-EGVHJKGJ.js +3125 -0
  65. package/dist/chunk-EGVHJKGJ.js.map +1 -0
  66. package/dist/{chunk-NEXLLTP4.js → chunk-G76LSA76.js} +6 -5
  67. package/dist/chunk-G76LSA76.js.map +1 -0
  68. package/dist/{chunk-PEI6RANI.js → chunk-GQMRL52F.js} +311 -75
  69. package/dist/chunk-GQMRL52F.js.map +1 -0
  70. package/dist/{chunk-ELIYWBZR.js → chunk-GUUXOISA.js} +1113 -457
  71. package/dist/chunk-GUUXOISA.js.map +1 -0
  72. package/dist/{chunk-HUIKIDM5.js → chunk-I7X2P4FU.js} +225 -116
  73. package/dist/chunk-I7X2P4FU.js.map +1 -0
  74. package/dist/chunk-IGFZFLI2.js +1390 -0
  75. package/dist/chunk-IGFZFLI2.js.map +1 -0
  76. package/dist/{chunk-4MDLEHXL.js → chunk-IMSUVYQB.js} +26 -13
  77. package/dist/chunk-IMSUVYQB.js.map +1 -0
  78. package/dist/chunk-IOYHDEP3.js +38 -0
  79. package/dist/chunk-IOYHDEP3.js.map +1 -0
  80. package/dist/chunk-IZV5FTJC.js +55 -0
  81. package/dist/chunk-IZV5FTJC.js.map +1 -0
  82. package/dist/chunk-KF33GTWN.js +343 -0
  83. package/dist/chunk-KF33GTWN.js.map +1 -0
  84. package/dist/chunk-KSGQ5ODA.js +457 -0
  85. package/dist/chunk-KSGQ5ODA.js.map +1 -0
  86. package/dist/{chunk-ZPBTI3TE.js → chunk-KZC6QRNR.js} +1513 -697
  87. package/dist/chunk-KZC6QRNR.js.map +1 -0
  88. package/dist/chunk-LJUMYUBO.js +218 -0
  89. package/dist/chunk-LJUMYUBO.js.map +1 -0
  90. package/dist/chunk-LSW2OJVV.js +380 -0
  91. package/dist/chunk-LSW2OJVV.js.map +1 -0
  92. package/dist/chunk-M357MHH3.js +2 -0
  93. package/dist/chunk-M357MHH3.js.map +1 -0
  94. package/dist/chunk-MK2TQO4Y.js +24 -0
  95. package/dist/chunk-MK2TQO4Y.js.map +1 -0
  96. package/dist/chunk-N7S72EXK.js +25 -0
  97. package/dist/chunk-N7S72EXK.js.map +1 -0
  98. package/dist/{chunk-YVCHAQZY.js → chunk-NKMYZFHA.js} +616 -621
  99. package/dist/chunk-NKMYZFHA.js.map +1 -0
  100. package/dist/chunk-NX4ADH73.js +14 -0
  101. package/dist/chunk-NX4ADH73.js.map +1 -0
  102. package/dist/chunk-O7F6UJO4.js +71 -0
  103. package/dist/chunk-O7F6UJO4.js.map +1 -0
  104. package/dist/chunk-OYQQJL3J.js +16 -0
  105. package/dist/chunk-OYQQJL3J.js.map +1 -0
  106. package/dist/{chunk-H5YGYNXS.js → chunk-P4BNUO57.js} +60 -17
  107. package/dist/chunk-P4BNUO57.js.map +1 -0
  108. package/dist/{chunk-JVYQRRC4.js → chunk-PEHTX3V7.js} +21 -1
  109. package/dist/chunk-PEHTX3V7.js.map +1 -0
  110. package/dist/chunk-PMV53IMM.js +26 -0
  111. package/dist/chunk-PMV53IMM.js.map +1 -0
  112. package/dist/{chunk-KCGXPP5V.js → chunk-PYEOPA4M.js} +13 -7
  113. package/dist/chunk-PYEOPA4M.js.map +1 -0
  114. package/dist/{chunk-KZ73RL76.js → chunk-QHUE7E4N.js} +8 -3
  115. package/dist/chunk-QHUE7E4N.js.map +1 -0
  116. package/dist/chunk-QV3DJVRZ.js +11 -0
  117. package/dist/chunk-QV3DJVRZ.js.map +1 -0
  118. package/dist/chunk-R5SBNG7S.js +810 -0
  119. package/dist/chunk-R5SBNG7S.js.map +1 -0
  120. package/dist/chunk-RI42H5IU.js +326 -0
  121. package/dist/chunk-RI42H5IU.js.map +1 -0
  122. package/dist/chunk-S2QH6EZ5.js +211 -0
  123. package/dist/chunk-S2QH6EZ5.js.map +1 -0
  124. package/dist/chunk-SHLZMAJN.js +304 -0
  125. package/dist/chunk-SHLZMAJN.js.map +1 -0
  126. package/dist/chunk-TGXK4BAZ.js +293 -0
  127. package/dist/chunk-TGXK4BAZ.js.map +1 -0
  128. package/dist/{chunk-5YK2ZDIG.js → chunk-TNEZNMSN.js} +4 -10
  129. package/dist/chunk-TNEZNMSN.js.map +1 -0
  130. package/dist/{chunk-22KP6LR5.js → chunk-TXS65BB2.js} +3 -1
  131. package/dist/{chunk-22KP6LR5.js.map → chunk-TXS65BB2.js.map} +1 -1
  132. package/dist/chunk-UNJPZGNK.js +63 -0
  133. package/dist/chunk-UNJPZGNK.js.map +1 -0
  134. package/dist/{chunk-IOLVN74D.js → chunk-V5ZUJT2T.js} +175 -42
  135. package/dist/chunk-V5ZUJT2T.js.map +1 -0
  136. package/dist/chunk-WBJY57A3.js +402 -0
  137. package/dist/chunk-WBJY57A3.js.map +1 -0
  138. package/dist/chunk-WIUKB3LD.js +1911 -0
  139. package/dist/chunk-WIUKB3LD.js.map +1 -0
  140. package/dist/{chunk-ICA6R6TW.js → chunk-WNN7NO2N.js} +1451 -355
  141. package/dist/chunk-WNN7NO2N.js.map +1 -0
  142. package/dist/{chunk-3AGBGTRT.js → chunk-X5UVUIMF.js} +1712 -1174
  143. package/dist/chunk-X5UVUIMF.js.map +1 -0
  144. package/dist/chunk-XDA5QJE7.js +402 -0
  145. package/dist/chunk-XDA5QJE7.js.map +1 -0
  146. package/dist/{chunk-VZTQ73XT.js → chunk-XEA5BCMA.js} +3 -1
  147. package/dist/{chunk-VZTQ73XT.js.map → chunk-XEA5BCMA.js.map} +1 -1
  148. package/dist/chunk-XHF7OYAN.js +1150 -0
  149. package/dist/chunk-XHF7OYAN.js.map +1 -0
  150. package/dist/chunk-YSRBFJMQ.js +43 -0
  151. package/dist/chunk-YSRBFJMQ.js.map +1 -0
  152. package/dist/chunk-ZOZAPAUO.js +174 -0
  153. package/dist/chunk-ZOZAPAUO.js.map +1 -0
  154. package/dist/chunk-ZQV5W7YC.js +809 -0
  155. package/dist/chunk-ZQV5W7YC.js.map +1 -0
  156. package/dist/chunk-ZUWF4NF7.js +13 -0
  157. package/dist/chunk-ZUWF4NF7.js.map +1 -0
  158. package/dist/client.d.ts +16 -7
  159. package/dist/clipboard.js +3 -1
  160. package/dist/commands/types.d.ts +2 -0
  161. package/dist/components/anthropic-mark.d.ts +3 -0
  162. package/dist/components/approval-surface.d.ts +19 -6
  163. package/dist/components/artifacts/artifact-chrome.d.ts +120 -0
  164. package/dist/components/artifacts/artifact-sandbox.d.ts +30 -0
  165. package/dist/components/artifacts/artifact-surface.d.ts +4 -2
  166. package/dist/components/artifacts/chat-interactive-block.d.ts +29 -0
  167. package/dist/components/artifacts/deferred-chat-media.d.ts +15 -0
  168. package/dist/components/artifacts/document-editor.d.ts +4 -2
  169. package/dist/components/artifacts/editable-artifact-ui.d.ts +2 -1
  170. package/dist/components/artifacts/editable-artifact-view.d.ts +48 -0
  171. package/dist/components/artifacts/editable-document.d.ts +1 -1
  172. package/dist/components/artifacts/editable-presentation.d.ts +2 -2
  173. package/dist/components/artifacts/editable-spreadsheet.d.ts +8 -3
  174. package/dist/components/artifacts/index.d.ts +9 -2
  175. package/dist/components/artifacts/inline-html-document.d.ts +2 -0
  176. package/dist/components/artifacts/latest-task-runner.d.ts +15 -0
  177. package/dist/components/artifacts/presentation-editor.d.ts +6 -2
  178. package/dist/components/artifacts/published-html-artifact-frame.d.ts +23 -3
  179. package/dist/components/artifacts/session-artifact-viewer.d.ts +39 -0
  180. package/dist/components/artifacts/site-view.d.ts +26 -0
  181. package/dist/components/artifacts/spreadsheet-command-queue.d.ts +20 -0
  182. package/dist/components/artifacts/spreadsheet-download.d.ts +7 -0
  183. package/dist/components/artifacts/spreadsheet-general-display.d.ts +24 -0
  184. package/dist/components/artifacts/spreadsheet-grid.d.ts +10 -3
  185. package/dist/components/artifacts/spreadsheet-resize.d.ts +50 -0
  186. package/dist/components/artifacts/spreadsheet-submissions.d.ts +9 -0
  187. package/dist/components/artifacts/visualization-assets.gen.d.ts +2 -0
  188. package/dist/components/browser-select-control.d.ts +16 -0
  189. package/dist/components/browser-viewer.d.ts +11 -2
  190. package/dist/components/chat-composer.d.ts +21 -3
  191. package/dist/components/child-session-link.d.ts +9 -0
  192. package/dist/components/claude-mark.d.ts +3 -0
  193. package/dist/components/code-editor.d.ts +1 -4
  194. package/dist/components/composer-transcription-control.d.ts +7 -0
  195. package/dist/components/composer.d.ts +34 -67
  196. package/dist/components/computer-viewer.d.ts +1 -1
  197. package/dist/components/copy-button.d.ts +3 -1
  198. package/dist/components/desktop-viewer.d.ts +1 -1
  199. package/dist/components/grok-mark.d.ts +26 -0
  200. package/dist/components/human-input-form.d.ts +28 -32
  201. package/dist/components/human-input-surface.d.ts +7 -2
  202. package/dist/components/linkified-text.d.ts +18 -0
  203. package/dist/components/machine-input-display.d.ts +22 -1
  204. package/dist/components/machines/agent-status-icon.d.ts +6 -0
  205. package/dist/components/machines/machine-detail.d.ts +7 -1
  206. package/dist/components/machines/machine-status.d.ts +48 -0
  207. package/dist/components/markdown-table-layout.d.ts +18 -0
  208. package/dist/components/markdown.d.ts +37 -4
  209. package/dist/components/message-timeline.d.ts +86 -7
  210. package/dist/components/model-mark.d.ts +29 -0
  211. package/dist/components/model-policy-picker-menu.d.ts +9 -0
  212. package/dist/components/model-policy-picker.d.ts +35 -28
  213. package/dist/components/new-conversation.d.ts +32 -0
  214. package/dist/components/open-geni-chat.d.ts +73 -0
  215. package/dist/components/open-geni-links.d.ts +68 -0
  216. package/dist/components/openrouter-mark.d.ts +6 -0
  217. package/dist/components/opper-mark.d.ts +7 -0
  218. package/dist/components/preview-loading.d.ts +2 -0
  219. package/dist/components/provider-recovery-notice.d.ts +16 -0
  220. package/dist/components/queue-item-content.d.ts +9 -0
  221. package/dist/components/rehype-secret-refs.d.ts +23 -0
  222. package/dist/components/remark-soft-line-breaks.d.ts +38 -0
  223. package/dist/components/sandbox-files.d.ts +3 -1
  224. package/dist/components/sandbox-workspace.d.ts +18 -0
  225. package/dist/components/secret-question-field.d.ts +31 -0
  226. package/dist/components/secret-ref-chip.d.ts +35 -0
  227. package/dist/components/session-capability-frame.d.ts +37 -0
  228. package/dist/components/session-chrome.d.ts +57 -8
  229. package/dist/components/session-commands-panel.d.ts +6 -0
  230. package/dist/components/session-commands.d.ts +6 -0
  231. package/dist/components/session-connection-request.d.ts +8 -0
  232. package/dist/components/session-conversation.d.ts +157 -0
  233. package/dist/components/session-list.d.ts +39 -0
  234. package/dist/components/session-mcp-capability-card.d.ts +41 -0
  235. package/dist/components/session-proxy-scope.d.ts +35 -0
  236. package/dist/components/session-status.d.ts +4 -1
  237. package/dist/components/session-usage-limit-notice.d.ts +39 -0
  238. package/dist/components/timeline-anchor.d.ts +24 -0
  239. package/dist/components/timeline-annotation-chrome.d.ts +25 -0
  240. package/dist/components/timeline-annotation-layout.d.ts +42 -0
  241. package/dist/components/timeline-annotation-markers.d.ts +8 -0
  242. package/dist/components/timeline-annotation-reveal-context.d.ts +4 -0
  243. package/dist/components/timeline-annotation-shared.d.ts +31 -0
  244. package/dist/components/timeline-annotations-dialog.d.ts +3 -2
  245. package/dist/components/timeline-annotations.d.ts +13 -3
  246. package/dist/components/timeline-reading-progress.d.ts +11 -0
  247. package/dist/components/timeline-search.d.ts +34 -0
  248. package/dist/components/timeline-settlement.d.ts +16 -0
  249. package/dist/components/tool-action-review.d.ts +47 -0
  250. package/dist/components/tool-review-history.d.ts +25 -0
  251. package/dist/components/usage-limit-notice.d.ts +49 -0
  252. package/dist/components/usage-member-list.d.ts +91 -0
  253. package/dist/components/usage-meter.d.ts +73 -0
  254. package/dist/components/use-viewer-menu-dismiss.d.ts +2 -0
  255. package/dist/components/user-message-body.d.ts +10 -1
  256. package/dist/composer-messages.d.ts +74 -0
  257. package/dist/composer-messages.js +9 -0
  258. package/dist/composer-messages.js.map +1 -0
  259. package/dist/composer-voice-events.d.ts +8 -0
  260. package/dist/composer.d.ts +5 -4
  261. package/dist/composer.js +26 -13
  262. package/dist/computer-viewer-GMLDXPON.js +20 -0
  263. package/dist/computer-viewer-GMLDXPON.js.map +1 -0
  264. package/dist/connect-account-identity.d.ts +8 -0
  265. package/dist/connect-accounts.d.ts +15 -0
  266. package/dist/connect-chooser.d.ts +18 -0
  267. package/dist/connect-panel.d.ts +18 -0
  268. package/dist/connect-setup.d.ts +18 -0
  269. package/dist/connect.d.ts +21 -0
  270. package/dist/connect.js +2149 -0
  271. package/dist/connect.js.map +1 -0
  272. package/dist/connection-catalog.d.ts +38 -0
  273. package/dist/connection-discovery.d.ts +12 -0
  274. package/dist/connection-installed.d.ts +17 -0
  275. package/dist/connection-logo.d.ts +9 -0
  276. package/dist/connection-service-logo.d.ts +8 -0
  277. package/dist/connection-service-presentation.d.ts +13 -0
  278. package/dist/connection-skeleton.d.ts +5 -0
  279. package/dist/connection-type-picker.d.ts +6 -0
  280. package/dist/conversation-timeline.d.ts +5 -0
  281. package/dist/desktop.d.ts +7 -0
  282. package/dist/desktop.js +27 -0
  283. package/dist/desktop.js.map +1 -0
  284. package/dist/device-authorization.d.ts +23 -0
  285. package/dist/diffs.d.ts +8 -0
  286. package/dist/diffs.js +15 -0
  287. package/dist/diffs.js.map +1 -0
  288. package/dist/discovery-cache.d.ts +5 -0
  289. package/dist/editor.d.ts +7 -0
  290. package/dist/editor.js +22 -0
  291. package/dist/editor.js.map +1 -0
  292. package/dist/embedded-new-voice-OCRNT6U5.js +18 -0
  293. package/dist/embedded-new-voice-OCRNT6U5.js.map +1 -0
  294. package/dist/embedded-voice-RPHPYVBT.js +18 -0
  295. package/dist/embedded-voice-RPHPYVBT.js.map +1 -0
  296. package/dist/{fleet-decision-row-GGCAT4E4.js → fleet-decision-row-SI63O5V4.js} +4 -1
  297. package/dist/fleet-decision-row-SI63O5V4.js.map +1 -0
  298. package/dist/hooks/latest-question.d.ts +25 -0
  299. package/dist/hooks/shared-machines-list.d.ts +4 -0
  300. package/dist/hooks/shared-query.d.ts +113 -0
  301. package/dist/hooks/use-attached-browsers.d.ts +1 -1
  302. package/dist/hooks/use-auth-runs.d.ts +1 -4
  303. package/dist/hooks/use-available-models.d.ts +1 -1
  304. package/dist/hooks/use-browser-frame-stream.d.ts +1 -1
  305. package/dist/hooks/use-browser-session.d.ts +12 -1
  306. package/dist/hooks/use-client-config-flags.d.ts +49 -0
  307. package/dist/hooks/use-codex-accounts.d.ts +59 -10
  308. package/dist/hooks/use-composer.d.ts +24 -2
  309. package/dist/hooks/use-computer-frame-stream.d.ts +1 -1
  310. package/dist/hooks/use-computer-input-posture.d.ts +13 -0
  311. package/dist/hooks/use-computer-session.d.ts +4 -0
  312. package/dist/hooks/use-connect.d.ts +23 -0
  313. package/dist/hooks/use-desktop-stream.d.ts +1 -1
  314. package/dist/hooks/use-file-attachments.d.ts +12 -0
  315. package/dist/hooks/use-goal.d.ts +2 -1
  316. package/dist/hooks/use-last-started-turn-policy.d.ts +5 -1
  317. package/dist/hooks/use-new-conversation.d.ts +56 -0
  318. package/dist/hooks/use-new-session-draft.d.ts +74 -0
  319. package/dist/hooks/use-realtime-voice-models.d.ts +7 -0
  320. package/dist/hooks/use-sandbox-files.d.ts +4 -1
  321. package/dist/hooks/use-session-conversation.d.ts +49 -0
  322. package/dist/hooks/use-session-events.d.ts +26 -5
  323. package/dist/hooks/use-session-mcp-approval-policy.d.ts +2 -2
  324. package/dist/hooks/use-session-model-account.d.ts +48 -0
  325. package/dist/hooks/use-supergrok-accounts.d.ts +7 -1
  326. package/dist/hooks/use-terminal-stream.d.ts +11 -5
  327. package/dist/hooks/use-usage.d.ts +40 -0
  328. package/dist/hooks/use-vaults.d.ts +53 -0
  329. package/dist/hooks/use-voice-input.d.ts +8 -1
  330. package/dist/hooks/use-workspace-edit.d.ts +4 -0
  331. package/dist/hooks/use-workspace-sessions.d.ts +24 -5
  332. package/dist/human-input-model.d.ts +122 -0
  333. package/dist/identity-link-accounts.d.ts +11 -0
  334. package/dist/identity-link-consent.d.ts +18 -0
  335. package/dist/index.d.ts +82 -20
  336. package/dist/index.js +2340 -6603
  337. package/dist/index.js.map +1 -1
  338. package/dist/interaction.d.ts +1 -1
  339. package/dist/interaction.js +14 -24
  340. package/dist/interaction.js.map +1 -1
  341. package/dist/latest-question-R77KWSUP.js +118 -0
  342. package/dist/latest-question-R77KWSUP.js.map +1 -0
  343. package/dist/lib/clipboard.d.ts +7 -0
  344. package/dist/lib/error-message.d.ts +7 -0
  345. package/dist/lib/format.d.ts +58 -4
  346. package/dist/lib/host-theme.d.ts +77 -0
  347. package/dist/lib/interaction-errors.d.ts +3 -0
  348. package/dist/lib/menu-styles.d.ts +22 -0
  349. package/dist/lib/notify-observer.d.ts +2 -0
  350. package/dist/lib/pierre-diffs-loader.d.ts +20 -0
  351. package/dist/lib/provider-recovery.d.ts +55 -0
  352. package/dist/lib/scrollbars.d.ts +11 -0
  353. package/dist/lib/terminal-input-readiness.d.ts +11 -0
  354. package/dist/lib/transient-retry.d.ts +25 -0
  355. package/dist/lib/workbench-peers.d.ts +36 -0
  356. package/dist/lib/xterm-theme.d.ts +7 -5
  357. package/dist/machines.js +9 -5
  358. package/dist/markdown-table-layout-3PV2UAAH.js +113 -0
  359. package/dist/markdown-table-layout-3PV2UAAH.js.map +1 -0
  360. package/dist/mcp-connection-status.d.ts +14 -0
  361. package/dist/model-mark-paths.d.ts +34 -0
  362. package/dist/model-mark-paths.js +16 -0
  363. package/dist/model-mark-paths.js.map +1 -0
  364. package/dist/model-picker-model.d.ts +111 -0
  365. package/dist/model-picker-model.js +25 -0
  366. package/dist/model-picker-model.js.map +1 -0
  367. package/dist/model-policy-picker-menu-7GJ5URPR.js +17 -0
  368. package/dist/model-policy-picker-menu-7GJ5URPR.js.map +1 -0
  369. package/dist/model-policy.d.ts +30 -3
  370. package/dist/model-policy.js +14 -1
  371. package/dist/native-previews.d.ts +28 -0
  372. package/dist/native-previews.js +82 -0
  373. package/dist/native-previews.js.map +1 -0
  374. package/dist/new-session-draft.d.ts +7 -0
  375. package/dist/new-session-draft.js +639 -0
  376. package/dist/new-session-draft.js.map +1 -0
  377. package/dist/notification-text.d.ts +27 -0
  378. package/dist/{noto-sans-arabic-loader-IA2T4X2A.js → noto-sans-arabic-loader-XSH2KYWJ.js} +3 -1
  379. package/dist/{noto-sans-arabic-loader-IA2T4X2A.js.map → noto-sans-arabic-loader-XSH2KYWJ.js.map} +1 -1
  380. package/dist/{noto-sans-jp-loader.generated-HFGLYBR3.js → noto-sans-jp-loader.generated-MR5L6V7K.js} +3 -1
  381. package/dist/{noto-sans-jp-loader.generated-HFGLYBR3.js.map → noto-sans-jp-loader.generated-MR5L6V7K.js.map} +1 -1
  382. package/dist/older-history.d.ts +3 -2
  383. package/dist/organization-model.d.ts +32 -0
  384. package/dist/organization-model.js +65 -0
  385. package/dist/organization-model.js.map +1 -0
  386. package/dist/{platform-activity-row-BJHUHXAT.js → platform-activity-row-5OCKOQWZ.js} +16 -78
  387. package/dist/platform-activity-row-5OCKOQWZ.js.map +1 -0
  388. package/dist/plugin-details.d.ts +14 -0
  389. package/dist/plugin-discovery.d.ts +25 -0
  390. package/dist/preview-loading-paint.d.ts +20 -0
  391. package/dist/provider.d.ts +25 -2
  392. package/dist/queue-presentation-model.d.ts +72 -0
  393. package/dist/queue-presentation-model.js +38 -0
  394. package/dist/queue-presentation-model.js.map +1 -0
  395. package/dist/{queue-surface-implementation-BSKUWHRI.js → queue-surface-implementation-GJBH7NKO.js} +65 -265
  396. package/dist/queue-surface-implementation-GJBH7NKO.js.map +1 -0
  397. package/dist/realtime/embedded-new-voice.d.ts +1 -0
  398. package/dist/realtime/embedded-voice.d.ts +1 -0
  399. package/dist/realtime/realtime-control.d.ts +4 -65
  400. package/dist/realtime/session-realtime.d.ts +78 -0
  401. package/dist/realtime.js +25 -1333
  402. package/dist/realtime.js.map +1 -1
  403. package/dist/sandbox-files-O27IPOZW.js +21 -0
  404. package/dist/sandbox-files-O27IPOZW.js.map +1 -0
  405. package/dist/sandbox-label-model.d.ts +30 -0
  406. package/dist/sandbox-label-model.js +20 -0
  407. package/dist/sandbox-label-model.js.map +1 -0
  408. package/dist/scrollbars.d.ts +1 -0
  409. package/dist/scrollbars.js +10 -0
  410. package/dist/scrollbars.js.map +1 -0
  411. package/dist/secret-reference-label.d.ts +14 -0
  412. package/dist/secrets-ui.d.ts +57 -0
  413. package/dist/session-agents-model.d.ts +10 -0
  414. package/dist/session-agents-model.js +25 -0
  415. package/dist/session-agents-model.js.map +1 -0
  416. package/dist/session-attention-model.d.ts +8 -0
  417. package/dist/session-attention-model.js +47 -0
  418. package/dist/session-attention-model.js.map +1 -0
  419. package/dist/session-auth-recommendation.d.ts +5 -0
  420. package/dist/session-capability-policy.d.ts +31 -0
  421. package/dist/session-feedback-model.d.ts +20 -0
  422. package/dist/session-feedback-model.js +56 -0
  423. package/dist/session-feedback-model.js.map +1 -0
  424. package/dist/session-list-model.d.ts +138 -0
  425. package/dist/session-list-model.js +274 -0
  426. package/dist/session-list-model.js.map +1 -0
  427. package/dist/session-realtime-7DJOIHQW.js +21 -0
  428. package/dist/session-realtime-7DJOIHQW.js.map +1 -0
  429. package/dist/session-realtime.d.ts +7 -0
  430. package/dist/session-realtime.js +19 -0
  431. package/dist/session-realtime.js.map +1 -0
  432. package/dist/session-status-model.d.ts +36 -0
  433. package/dist/session-ui.d.ts +39 -1
  434. package/dist/session-ui.js +126 -12
  435. package/dist/session-ui.js.map +1 -1
  436. package/dist/session.d.ts +8 -2
  437. package/dist/session.js +35 -20
  438. package/dist/site-snapshot.d.ts +14 -0
  439. package/dist/sites-ui.d.ts +24 -0
  440. package/dist/sites.d.ts +3 -0
  441. package/dist/sites.js +14 -0
  442. package/dist/sites.js.map +1 -0
  443. package/dist/skill-discovery.d.ts +47 -0
  444. package/dist/terminal.d.ts +8 -0
  445. package/dist/terminal.js +32 -0
  446. package/dist/terminal.js.map +1 -0
  447. package/dist/testing/session-scenarios.d.ts +10 -0
  448. package/dist/testing/session-scenarios.js +367 -0
  449. package/dist/testing/session-scenarios.js.map +1 -0
  450. package/dist/timeline/activity-rail.d.ts +11 -2
  451. package/dist/timeline/agent-identity.d.ts +30 -0
  452. package/dist/timeline/agent-row.d.ts +31 -0
  453. package/dist/timeline/allowance-exhausted-row.d.ts +24 -0
  454. package/dist/timeline/compaction-copy.d.ts +46 -0
  455. package/dist/timeline/focus-sequence.d.ts +9 -0
  456. package/dist/timeline/genie-copy.d.ts +3 -0
  457. package/dist/timeline/genie-loading.d.ts +47 -0
  458. package/dist/timeline/index.d.ts +10 -5
  459. package/dist/timeline/knowledge-receipt.d.ts +17 -0
  460. package/dist/timeline/message-sender.d.ts +19 -0
  461. package/dist/timeline/notice-presentation.d.ts +13 -0
  462. package/dist/timeline/parsers.d.ts +11 -0
  463. package/dist/timeline/patch-apply-command.d.ts +18 -0
  464. package/dist/timeline/platform-activity-presentation.d.ts +21 -0
  465. package/dist/timeline/platform-activity-row.d.ts +1 -2
  466. package/dist/timeline/presented-image.d.ts +11 -0
  467. package/dist/timeline/projection.d.ts +31 -2
  468. package/dist/timeline/provider-logo.d.ts +15 -0
  469. package/dist/timeline/question-nav-model.d.ts +23 -0
  470. package/dist/timeline/registry.d.ts +12 -1
  471. package/dist/timeline/retained-image.d.ts +18 -0
  472. package/dist/timeline/retained-loaders.d.ts +27 -0
  473. package/dist/timeline/rolling-activity.d.ts +11 -0
  474. package/dist/timeline/screenshot-lightbox.d.ts +23 -1
  475. package/dist/timeline/session-usage-limit-row.d.ts +11 -0
  476. package/dist/timeline/shared.d.ts +4 -1
  477. package/dist/timeline/startup-dispatch-details.d.ts +5 -0
  478. package/dist/timeline/startup-preference.d.ts +3 -0
  479. package/dist/timeline/startup-timings.d.ts +4 -0
  480. package/dist/timeline/tool-display-name.d.ts +5 -2
  481. package/dist/timeline/tool-presentation.d.ts +172 -0
  482. package/dist/timeline/turn-summary-model.d.ts +95 -0
  483. package/dist/timeline/turn-summary.d.ts +20 -54
  484. package/dist/timeline/types.d.ts +179 -7
  485. package/dist/timeline/work-presentation.d.ts +60 -0
  486. package/dist/timeline-annotation-markers-U3G66KUD.js +166 -0
  487. package/dist/timeline-annotation-markers-U3G66KUD.js.map +1 -0
  488. package/dist/timeline-annotation-selection-BI7QTPTZ.js +242 -0
  489. package/dist/timeline-annotation-selection-BI7QTPTZ.js.map +1 -0
  490. package/dist/timeline-annotations-dialog-FOMHSDTE.js +274 -0
  491. package/dist/timeline-annotations-dialog-FOMHSDTE.js.map +1 -0
  492. package/dist/timeline-model.d.ts +29 -0
  493. package/dist/timeline-model.js +254 -0
  494. package/dist/timeline-model.js.map +1 -0
  495. package/dist/usage/allowance-copy.d.ts +25 -0
  496. package/dist/usage/session-usage-limit.d.ts +88 -0
  497. package/dist/usage/summary.d.ts +35 -0
  498. package/dist/usage.d.ts +17 -0
  499. package/dist/usage.js +1187 -0
  500. package/dist/usage.js.map +1 -0
  501. package/dist/voice-recording-owner.d.ts +7 -0
  502. package/package.json +106 -7
  503. package/src/approvals.ts +8 -1
  504. package/src/artifacts-spreadsheet.ts +1 -0
  505. package/src/artifacts.ts +44 -0
  506. package/src/assets/README.md +8 -0
  507. package/src/assets/gmail.ico +0 -0
  508. package/src/assets/outlook.ico +0 -0
  509. package/src/capability-catalog-row.tsx +94 -0
  510. package/src/capability-logo-fallback.ts +22 -0
  511. package/src/client.ts +20 -31
  512. package/src/commands/registry.ts +18 -15
  513. package/src/commands/types.ts +2 -0
  514. package/src/components/anthropic-mark.tsx +10 -0
  515. package/src/components/approval-surface.tsx +401 -138
  516. package/src/components/artifacts/artifact-chrome.tsx +413 -0
  517. package/src/components/artifacts/artifact-sandbox.tsx +193 -0
  518. package/src/components/artifacts/artifact-surface.tsx +40 -20
  519. package/src/components/artifacts/chat-interactive-block.tsx +260 -0
  520. package/src/components/artifacts/deferred-chat-media.tsx +67 -0
  521. package/src/components/artifacts/document-editor.tsx +141 -16
  522. package/src/components/artifacts/editable-artifact-ui.tsx +4 -2
  523. package/src/components/artifacts/editable-artifact-view.tsx +197 -0
  524. package/src/components/artifacts/editable-artifact-workbench.tsx +5 -2
  525. package/src/components/artifacts/editable-document.tsx +37 -36
  526. package/src/components/artifacts/editable-presentation.tsx +36 -18
  527. package/src/components/artifacts/editable-spreadsheet.tsx +543 -103
  528. package/src/components/artifacts/index.ts +45 -0
  529. package/src/components/artifacts/inline-html-document.ts +24 -0
  530. package/src/components/artifacts/latest-task-runner.ts +49 -0
  531. package/src/components/artifacts/presentation-editor.tsx +323 -67
  532. package/src/components/artifacts/published-html-artifact-frame.tsx +122 -5
  533. package/src/components/artifacts/session-artifact-viewer.tsx +378 -0
  534. package/src/components/artifacts/site-view.tsx +121 -0
  535. package/src/components/artifacts/spreadsheet-canvas.ts +5 -10
  536. package/src/components/artifacts/spreadsheet-command-queue.ts +184 -0
  537. package/src/components/artifacts/spreadsheet-download.tsx +109 -0
  538. package/src/components/artifacts/spreadsheet-general-display.ts +43 -0
  539. package/src/components/artifacts/spreadsheet-grid.tsx +344 -144
  540. package/src/components/artifacts/spreadsheet-resize.tsx +421 -0
  541. package/src/components/artifacts/spreadsheet-submissions.tsx +46 -0
  542. package/src/components/artifacts/visualization-assets/base.css +1015 -0
  543. package/src/components/artifacts/visualization-assets/helpers.html +349 -0
  544. package/src/components/artifacts/visualization-assets.gen.ts +3 -0
  545. package/src/components/browser-select-control.tsx +312 -0
  546. package/src/components/browser-viewer.tsx +778 -318
  547. package/src/components/chat-composer.tsx +47 -5
  548. package/src/components/child-session-link.tsx +36 -0
  549. package/src/components/claude-mark.tsx +11 -0
  550. package/src/components/code-editor.tsx +13 -16
  551. package/src/components/composer-transcription-control.tsx +128 -30
  552. package/src/components/composer.tsx +404 -195
  553. package/src/components/computer-viewer.tsx +880 -253
  554. package/src/components/copy-button.tsx +13 -5
  555. package/src/components/desktop-viewer.tsx +1 -1
  556. package/src/components/enrollment-consent.tsx +1 -1
  557. package/src/components/enrollment-device-flow.tsx +1 -1
  558. package/src/components/file-browser.tsx +10 -14
  559. package/src/components/fleet-tile.tsx +5 -3
  560. package/src/components/generated-video-player.tsx +4 -2
  561. package/src/components/grok-mark.tsx +34 -0
  562. package/src/components/human-input-form.tsx +590 -283
  563. package/src/components/human-input-surface.tsx +11 -0
  564. package/src/components/interaction-intervention-banner.tsx +2 -2
  565. package/src/components/linkified-text.tsx +79 -0
  566. package/src/components/machine-card.tsx +35 -78
  567. package/src/components/machine-dock-bar.tsx +1 -1
  568. package/src/components/machine-input-display.ts +197 -3
  569. package/src/components/machines/agent-status-icon.tsx +31 -0
  570. package/src/components/machines/machine-detail.tsx +200 -31
  571. package/src/components/machines/machine-operation-policy.tsx +1 -1
  572. package/src/components/machines/machine-status.ts +241 -0
  573. package/src/components/machines-dashboard.tsx +2 -17
  574. package/src/components/markdown-table-layout.ts +143 -0
  575. package/src/components/markdown.tsx +466 -129
  576. package/src/components/message-timeline.tsx +2370 -667
  577. package/src/components/model-mark.tsx +102 -0
  578. package/src/components/model-picker.tsx +15 -4
  579. package/src/components/model-policy-picker-menu.tsx +371 -0
  580. package/src/components/model-policy-picker.tsx +252 -429
  581. package/src/components/new-conversation.tsx +221 -0
  582. package/src/components/open-geni-chat.tsx +309 -0
  583. package/src/components/open-geni-links.tsx +179 -0
  584. package/src/components/openrouter-mark.tsx +13 -0
  585. package/src/components/opper-mark.tsx +18 -0
  586. package/src/components/pierre-diff.tsx +41 -16
  587. package/src/components/pierre-file.tsx +35 -10
  588. package/src/components/preview-loading.tsx +109 -0
  589. package/src/components/provider-recovery-notice.tsx +49 -0
  590. package/src/components/queue-item-content.ts +14 -0
  591. package/src/components/queue-surface-implementation.tsx +51 -356
  592. package/src/components/queue-surface-state.tsx +3 -1
  593. package/src/components/rehype-secret-refs.ts +98 -0
  594. package/src/components/remark-soft-line-breaks.ts +166 -0
  595. package/src/components/sandbox-files.tsx +91 -15
  596. package/src/components/sandbox-terminal.tsx +84 -13
  597. package/src/components/sandbox-workspace.tsx +147 -51
  598. package/src/components/secret-question-field.tsx +324 -0
  599. package/src/components/secret-ref-chip.tsx +185 -0
  600. package/src/components/session-capability-frame.tsx +197 -0
  601. package/src/components/session-chrome.tsx +842 -251
  602. package/src/components/session-commands-panel.tsx +126 -0
  603. package/src/components/session-commands.tsx +18 -0
  604. package/src/components/session-connection-request.tsx +97 -0
  605. package/src/components/session-conversation.tsx +876 -0
  606. package/src/components/session-list.tsx +257 -0
  607. package/src/components/session-mcp-capability-card.tsx +680 -0
  608. package/src/components/session-proxy-scope.tsx +153 -0
  609. package/src/components/session-status.tsx +26 -17
  610. package/src/components/session-usage-limit-notice.tsx +174 -0
  611. package/src/components/timeline-anchor.tsx +119 -0
  612. package/src/components/timeline-annotation-chrome.tsx +196 -0
  613. package/src/components/timeline-annotation-layout.ts +268 -0
  614. package/src/components/timeline-annotation-markers.tsx +185 -0
  615. package/src/components/timeline-annotation-reveal-context.ts +9 -0
  616. package/src/components/timeline-annotation-selection.tsx +106 -54
  617. package/src/components/timeline-annotation-shared.ts +245 -0
  618. package/src/components/timeline-annotations-dialog.tsx +185 -128
  619. package/src/components/timeline-annotations.tsx +189 -45
  620. package/src/components/timeline-reading-progress.ts +80 -0
  621. package/src/components/timeline-search.tsx +168 -0
  622. package/src/components/timeline-settlement.ts +60 -0
  623. package/src/components/tool-action-review.tsx +650 -0
  624. package/src/components/tool-review-history.tsx +88 -0
  625. package/src/components/usage-limit-notice.tsx +179 -0
  626. package/src/components/usage-member-list.tsx +792 -0
  627. package/src/components/usage-meter.tsx +382 -0
  628. package/src/components/use-viewer-menu-dismiss.ts +33 -0
  629. package/src/components/user-message-body.tsx +27 -2
  630. package/src/components/workspace-dock.tsx +18 -1
  631. package/src/composer-messages.ts +150 -0
  632. package/src/composer-voice-events.ts +12 -0
  633. package/src/composer.ts +6 -1
  634. package/src/connect-account-identity.tsx +34 -0
  635. package/src/connect-accounts.tsx +233 -0
  636. package/src/connect-chooser.tsx +336 -0
  637. package/src/connect-panel.tsx +99 -0
  638. package/src/connect-setup.tsx +355 -0
  639. package/src/connect.ts +60 -0
  640. package/src/connection-assets.d.ts +4 -0
  641. package/src/connection-catalog.tsx +162 -0
  642. package/src/connection-discovery.tsx +238 -0
  643. package/src/connection-installed.tsx +51 -0
  644. package/src/connection-logo.tsx +37 -0
  645. package/src/connection-service-logo.tsx +55 -0
  646. package/src/connection-service-presentation.ts +46 -0
  647. package/src/connection-skeleton.tsx +16 -0
  648. package/src/connection-type-picker.tsx +36 -0
  649. package/src/conversation-timeline.ts +92 -0
  650. package/src/desktop.ts +24 -0
  651. package/src/device-authorization.tsx +98 -0
  652. package/src/diffs.ts +16 -0
  653. package/src/discovery-cache.ts +42 -0
  654. package/src/editor.ts +13 -0
  655. package/src/hooks/internal.ts +3 -2
  656. package/src/hooks/latest-question.ts +164 -0
  657. package/src/hooks/shared-machines-list.ts +34 -1
  658. package/src/hooks/shared-query.ts +721 -0
  659. package/src/hooks/use-attached-browsers.ts +1 -1
  660. package/src/hooks/use-auth-runs.ts +0 -27
  661. package/src/hooks/use-available-models.ts +2 -2
  662. package/src/hooks/use-browser-frame-stream.ts +19 -2
  663. package/src/hooks/use-browser-session.ts +680 -205
  664. package/src/hooks/use-browser-sessions.ts +32 -1
  665. package/src/hooks/use-client-config-flags.ts +118 -0
  666. package/src/hooks/use-codex-accounts.ts +247 -47
  667. package/src/hooks/use-composer.ts +227 -44
  668. package/src/hooks/use-computer-frame-stream.ts +25 -7
  669. package/src/hooks/use-computer-input-posture.ts +94 -0
  670. package/src/hooks/use-computer-session.ts +409 -95
  671. package/src/hooks/use-connect.ts +23 -0
  672. package/src/hooks/use-desktop-stream.ts +19 -28
  673. package/src/hooks/use-file-attachments.ts +80 -4
  674. package/src/hooks/use-goal.ts +79 -9
  675. package/src/hooks/use-last-started-turn-policy.ts +37 -11
  676. package/src/hooks/use-machines.ts +4 -0
  677. package/src/hooks/use-new-conversation.ts +374 -0
  678. package/src/hooks/use-new-session-draft.ts +813 -0
  679. package/src/hooks/use-realtime-voice-models.ts +46 -0
  680. package/src/hooks/use-sandbox-files.ts +68 -20
  681. package/src/hooks/use-session-background-commands.ts +22 -11
  682. package/src/hooks/use-session-capabilities.ts +3 -2
  683. package/src/hooks/use-session-conversation.ts +150 -0
  684. package/src/hooks/use-session-events.ts +531 -335
  685. package/src/hooks/use-session-mcp-approval-policy.ts +13 -5
  686. package/src/hooks/use-session-model-account.ts +174 -0
  687. package/src/hooks/use-session.ts +30 -2
  688. package/src/hooks/use-slash-commands.ts +6 -11
  689. package/src/hooks/use-supergrok-accounts.ts +22 -8
  690. package/src/hooks/use-terminal-stream.ts +153 -27
  691. package/src/hooks/use-transcription.ts +6 -0
  692. package/src/hooks/use-turn-queue.ts +2 -1
  693. package/src/hooks/use-usage.ts +100 -0
  694. package/src/hooks/use-vaults.ts +153 -0
  695. package/src/hooks/use-video-artifact-playback.ts +1 -1
  696. package/src/hooks/use-voice-input.ts +127 -19
  697. package/src/hooks/use-workspace-capture.ts +3 -2
  698. package/src/hooks/use-workspace-edit.ts +23 -5
  699. package/src/hooks/use-workspace-sessions.ts +74 -7
  700. package/src/human-input-model.ts +359 -0
  701. package/src/identity-link-accounts.tsx +148 -0
  702. package/src/identity-link-consent.tsx +192 -0
  703. package/src/index.ts +262 -16
  704. package/src/interaction.ts +1 -0
  705. package/src/lib/clipboard.ts +29 -0
  706. package/src/lib/error-message.ts +37 -0
  707. package/src/lib/format.ts +205 -10
  708. package/src/lib/host-theme.ts +529 -0
  709. package/src/lib/interaction-errors.ts +15 -0
  710. package/src/lib/menu-styles.ts +44 -0
  711. package/src/lib/notify-observer.ts +15 -0
  712. package/src/lib/pierre-diffs-loader.ts +53 -0
  713. package/src/lib/provider-recovery.ts +243 -0
  714. package/src/lib/scrollbars.ts +30 -0
  715. package/src/lib/terminal-input-readiness.ts +51 -0
  716. package/src/lib/transient-retry.ts +99 -0
  717. package/src/lib/workbench-peers.ts +62 -0
  718. package/src/lib/xterm-theme.ts +23 -21
  719. package/src/mcp-connection-status.ts +35 -0
  720. package/src/model-mark-paths.ts +53 -0
  721. package/src/model-picker-model.ts +330 -0
  722. package/src/model-policy.ts +299 -74
  723. package/src/native-previews.ts +100 -0
  724. package/src/new-session-draft.ts +22 -0
  725. package/src/notification-text.ts +81 -0
  726. package/src/older-history.ts +22 -4
  727. package/src/organization-model.ts +118 -0
  728. package/src/plugin-details.tsx +185 -0
  729. package/src/plugin-discovery.tsx +196 -0
  730. package/src/preview-loading-paint.ts +68 -0
  731. package/src/provider.tsx +74 -15
  732. package/src/queue-presentation-model.ts +464 -0
  733. package/src/realtime/dropdown-menu.tsx +19 -12
  734. package/src/realtime/embedded-new-voice.tsx +1 -0
  735. package/src/realtime/embedded-voice.tsx +3 -0
  736. package/src/realtime/realtime-control.tsx +138 -550
  737. package/src/realtime/session-realtime.ts +566 -0
  738. package/src/sandbox-label-model.ts +53 -0
  739. package/src/scrollbars.ts +3 -0
  740. package/src/secret-reference-label.ts +43 -0
  741. package/src/secrets-ui.tsx +59 -0
  742. package/src/session-agents-model.ts +33 -0
  743. package/src/session-attention-model.ts +62 -0
  744. package/src/session-auth-recommendation.ts +48 -0
  745. package/src/session-capability-policy.ts +196 -0
  746. package/src/session-context.ts +3 -4
  747. package/src/session-feedback-model.ts +95 -0
  748. package/src/session-list-model.ts +434 -0
  749. package/src/session-realtime.ts +18 -0
  750. package/src/session-status-model.ts +99 -0
  751. package/src/session-ui.ts +98 -1
  752. package/src/session.ts +17 -1
  753. package/src/site-snapshot.ts +74 -0
  754. package/src/sites-ui.tsx +348 -0
  755. package/src/sites.ts +3 -0
  756. package/src/skill-discovery.tsx +208 -0
  757. package/src/terminal.ts +26 -0
  758. package/src/testing/session-scenarios.ts +404 -0
  759. package/src/timeline/activity-rail.tsx +242 -101
  760. package/src/timeline/agent-identity.tsx +84 -0
  761. package/src/timeline/agent-row.tsx +231 -0
  762. package/src/timeline/allowance-exhausted-row.tsx +86 -0
  763. package/src/timeline/compaction-copy.ts +115 -0
  764. package/src/timeline/fleet-decision-projection.ts +2 -1
  765. package/src/timeline/fleet-decision-row.tsx +1 -0
  766. package/src/timeline/focus-sequence.ts +44 -0
  767. package/src/timeline/genie-copy.ts +19 -0
  768. package/src/timeline/genie-loading.tsx +143 -0
  769. package/src/timeline/index.ts +30 -2
  770. package/src/timeline/knowledge-receipt.tsx +100 -0
  771. package/src/timeline/message-sender.tsx +71 -0
  772. package/src/timeline/notice-presentation.ts +48 -0
  773. package/src/timeline/parsers.ts +42 -2
  774. package/src/timeline/patch-apply-command.tsx +135 -0
  775. package/src/timeline/platform-activity-presentation.ts +166 -0
  776. package/src/timeline/platform-activity-row.tsx +15 -90
  777. package/src/timeline/presented-image.ts +63 -0
  778. package/src/timeline/projection.ts +1742 -76
  779. package/src/timeline/provider-logo.tsx +53 -0
  780. package/src/timeline/question-nav-model.ts +28 -0
  781. package/src/timeline/registry.ts +26 -4
  782. package/src/timeline/retained-image.ts +97 -0
  783. package/src/timeline/retained-loaders.ts +91 -0
  784. package/src/timeline/rolling-activity.tsx +80 -0
  785. package/src/timeline/screenshot-lightbox.tsx +228 -5
  786. package/src/timeline/session-usage-limit-row.tsx +42 -0
  787. package/src/timeline/shared.tsx +42 -15
  788. package/src/timeline/startup-dispatch-details.tsx +36 -0
  789. package/src/timeline/startup-preference.ts +33 -0
  790. package/src/timeline/startup-timings.tsx +145 -0
  791. package/src/timeline/tool-display-name.ts +19 -7
  792. package/src/timeline/tool-presentation.ts +1316 -0
  793. package/src/timeline/tool-renderers.tsx +835 -1138
  794. package/src/timeline/turn-summary-model.ts +343 -0
  795. package/src/timeline/turn-summary.tsx +272 -365
  796. package/src/timeline/types.ts +189 -6
  797. package/src/timeline/work-presentation.ts +189 -0
  798. package/src/timeline-model.ts +143 -0
  799. package/src/usage/allowance-copy.ts +64 -0
  800. package/src/usage/session-usage-limit.ts +266 -0
  801. package/src/usage/summary.ts +93 -0
  802. package/src/usage.ts +70 -0
  803. package/src/voice-recording-owner.ts +22 -0
  804. package/styles/compiled.css +2319 -748
  805. package/styles/connect.css +290 -0
  806. package/styles/connect.d.ts +1 -0
  807. package/styles/effective-tokens.css +1 -0
  808. package/styles/index.css +309 -9
  809. package/styles/responsive.css +99 -7
  810. package/styles/session-capability.css +44 -0
  811. package/styles/tokens.css +134 -66
  812. package/dist/browser-viewer-MKKFRRRV.js +0 -14
  813. package/dist/chunk-2DZVYHVO.js +0 -470
  814. package/dist/chunk-2DZVYHVO.js.map +0 -1
  815. package/dist/chunk-3AGBGTRT.js.map +0 -1
  816. package/dist/chunk-4MDLEHXL.js.map +0 -1
  817. package/dist/chunk-5YK2ZDIG.js.map +0 -1
  818. package/dist/chunk-7EAFGICR.js +0 -302
  819. package/dist/chunk-7EAFGICR.js.map +0 -1
  820. package/dist/chunk-ELIYWBZR.js.map +0 -1
  821. package/dist/chunk-H5YGYNXS.js.map +0 -1
  822. package/dist/chunk-HUIKIDM5.js.map +0 -1
  823. package/dist/chunk-ICA6R6TW.js.map +0 -1
  824. package/dist/chunk-IOLVN74D.js.map +0 -1
  825. package/dist/chunk-JAQ5K7W6.js.map +0 -1
  826. package/dist/chunk-JVYQRRC4.js.map +0 -1
  827. package/dist/chunk-KCGXPP5V.js.map +0 -1
  828. package/dist/chunk-KZ73RL76.js.map +0 -1
  829. package/dist/chunk-NEXLLTP4.js.map +0 -1
  830. package/dist/chunk-PEI6RANI.js.map +0 -1
  831. package/dist/chunk-VTOREEXF.js +0 -142
  832. package/dist/chunk-VTOREEXF.js.map +0 -1
  833. package/dist/chunk-WSK7G5LE.js +0 -170
  834. package/dist/chunk-WSK7G5LE.js.map +0 -1
  835. package/dist/chunk-X4A66EWZ.js +0 -223
  836. package/dist/chunk-X4A66EWZ.js.map +0 -1
  837. package/dist/chunk-XYRDDSXF.js.map +0 -1
  838. package/dist/chunk-YG4QEQF5.js +0 -9557
  839. package/dist/chunk-YG4QEQF5.js.map +0 -1
  840. package/dist/chunk-YVCHAQZY.js.map +0 -1
  841. package/dist/chunk-ZPBTI3TE.js.map +0 -1
  842. package/dist/computer-viewer-FWEZISW4.js +0 -16
  843. package/dist/fleet-decision-row-GGCAT4E4.js.map +0 -1
  844. package/dist/hooks/use-environments.d.ts +0 -41
  845. package/dist/hooks/use-packs.d.ts +0 -32
  846. package/dist/platform-activity-row-BJHUHXAT.js.map +0 -1
  847. package/dist/queue-surface-implementation-BSKUWHRI.js.map +0 -1
  848. package/dist/timeline-annotation-selection-3L7LHGG2.js +0 -187
  849. package/dist/timeline-annotation-selection-3L7LHGG2.js.map +0 -1
  850. package/dist/timeline-annotations-dialog-U7EVLR75.js +0 -196
  851. package/dist/timeline-annotations-dialog-U7EVLR75.js.map +0 -1
  852. package/src/hooks/use-environments.ts +0 -182
  853. package/src/hooks/use-packs.ts +0 -157
  854. /package/dist/{browser-viewer-MKKFRRRV.js.map → browser-viewer-ZWR6MWJ7.js.map} +0 -0
  855. /package/dist/{computer-viewer-FWEZISW4.js.map → chat-interactive-block-4EUKJXUO.js.map} +0 -0
@@ -9,6 +9,7 @@ import {
9
9
  PauseIcon,
10
10
  PlayIcon,
11
11
  RotateCwIcon,
12
+ SquareIcon,
12
13
  XIcon,
13
14
  } from "lucide-react";
14
15
  import { AnimatePresence, motion } from "motion/react";
@@ -36,6 +37,7 @@ import {
36
37
  type RefObject,
37
38
  } from "react";
38
39
  import { argHint, defaultCommands } from "../commands/registry";
40
+ import { useErrorMessage } from "../lib/error-message";
39
41
  import type { Notice, SlashCommand } from "../commands/types";
40
42
  import type { ComposerState } from "../hooks/use-composer";
41
43
  import { shouldSteerOnKey, shouldSubmitOnKey } from "../hooks/use-composer";
@@ -50,7 +52,8 @@ import {
50
52
  ComposerResponsiveContext,
51
53
  type ResponsiveBasis,
52
54
  } from "../lib/composer-responsive-context";
53
- import { composerSubmissionErrorMessage, formatBytes, formatRelativeTime } from "../lib/format";
55
+ import { composerSubmissionErrorMessage } from "../lib/format";
56
+ import { defaultChatComposerMessages, type ChatComposerMessages } from "../composer-messages";
54
57
  import type { PickerModelRow } from "../model-policy";
55
58
  import { useLightboxOptional } from "../timeline/screenshot-lightbox";
56
59
  import { OPEN_WORKSTREAM_CONTROL_EVENT } from "../workstream-control-event";
@@ -74,7 +77,16 @@ function ComposerTip({
74
77
 
75
78
  export type ComposerDelivery = Pick<
76
79
  ComposerState,
77
- "value" | "setValue" | "send" | "steer" | "sending" | "canSend" | "error" | "clearError"
80
+ | "value"
81
+ | "setValue"
82
+ | "send"
83
+ | "steer"
84
+ | "sending"
85
+ | "canSend"
86
+ | "error"
87
+ | "clearError"
88
+ | "annotations"
89
+ | "requestAnnotationReview"
78
90
  >;
79
91
 
80
92
  export type ComposerDraftState = Pick<
@@ -96,138 +108,8 @@ export type ComposerControlLinks = {
96
108
  sessionHref?: ((sessionId: string) => string) | undefined;
97
109
  };
98
110
 
99
- export type ChatComposerMessages = {
100
- messagePlaceholder: string;
101
- pausedPlaceholder: string;
102
- inputLabel: string;
103
- keyboardHint: string;
104
- slashCommandBlocked: string;
105
- controlChangedError: string;
106
- sendFailedError: string;
107
- dropFiles: string;
108
- attachFiles: string;
109
- pauseAriaLabel: string;
110
- pauseTitle: string;
111
- sendMessageAriaLabel: string;
112
- sendAndResumeAriaLabel: string;
113
- sendTitle: string;
114
- sendAndResumeTitle: string;
115
- workspacePaused: string;
116
- pausedHere: string;
117
- parentBlocker: string;
118
- narrowerPause: string;
119
- pausedBy: (displayName: string) => string;
120
- queuedAhead: (count: number) => string;
121
- resumingAndSending: string;
122
- nextMessageResumes: string;
123
- resumeThisWorkstream: string;
124
- resumeShort: string;
125
- hidePauseDetails: string;
126
- showPauseDetails: string;
127
- pauseReasonsLabel: string;
128
- pausedByLabel: string;
129
- alsoPausedByLabel: string;
130
- resumeWorkspace: string;
131
- resumeFromSession: string;
132
- sessionCanRun: string;
133
- stillPausedBy: (displayName: string) => string;
134
- restoredResourcesLabel: string;
135
- restoredFile: (fileId: string) => string;
136
- removeRestoredResource: (index: number) => string;
137
- uploading: string;
138
- uploadFailed: string;
139
- previewAttachment: (name: string) => string;
140
- attachmentPreviewLabel: string;
141
- downloadAttachment: (name: string) => string;
142
- closeAttachmentPreview: string;
143
- retryAttachment: (name: string) => string;
144
- retryUpload: string;
145
- removeAttachment: (name: string) => string;
146
- confirmCommand: (name: string) => string;
147
- confirmDescription: (command: SlashCommand) => string;
148
- cancel: string;
149
- runCommand: (name: string) => string;
150
- commands: string;
151
- slashCommandsLabel: string;
152
- modelLabel: string;
153
- close: string;
154
- danger: string;
155
- draftConflict: string;
156
- useOtherDraft: string;
157
- keepMine: string;
158
- savingDraft: string;
159
- formatBytes: (bytes: number) => string;
160
- formatRelativeTime: (changedAt: string) => string;
161
- };
162
-
163
- export const defaultChatComposerMessages: ChatComposerMessages = {
164
- messagePlaceholder: "Message the agent…",
165
- pausedPlaceholder: "Message the agent — it will wait in the queue…",
166
- inputLabel: "Message the agent",
167
- keyboardHint: "Enter to queue · Cmd/Ctrl+Enter to steer · Shift+Enter for a new line",
168
- slashCommandBlocked:
169
- "That's a slash command — press Enter in the command list to run it, or edit the line to send a message.",
170
- controlChangedError:
171
- "This workstream was paused while you were sending. Nothing was sent, and your draft is still here.",
172
- sendFailedError: "Sending failed — your draft is still here. Try again.",
173
- dropFiles: "Drop files to attach",
174
- attachFiles: "Attach files",
175
- pauseAriaLabel: "Pause this workstream",
176
- pauseTitle: "Pause this workstream; queued prompts and approvals are preserved",
177
- sendMessageAriaLabel: "Send message",
178
- sendAndResumeAriaLabel: "Add message to queue",
179
- sendTitle: "Queue message (Enter); steer with Cmd/Ctrl+Enter",
180
- sendAndResumeTitle: "Add to queue (Enter); steer now with Cmd/Ctrl+Enter",
181
- workspacePaused: "Workspace paused",
182
- pausedHere: "Paused here",
183
- parentBlocker: "parent",
184
- narrowerPause: "a narrower pause",
185
- pausedBy: (displayName) => `Paused by ${displayName}`,
186
- queuedAhead: (count) =>
187
- `${count} waiting prompt${count === 1 ? "" : "s"}; your message joins the queue.`,
188
- resumingAndSending: "Sending…",
189
- nextMessageResumes: "Messages wait in the queue until you resume.",
190
- resumeThisWorkstream: "Resume this workstream",
191
- resumeShort: "Resume",
192
- hidePauseDetails: "Hide pause details",
193
- showPauseDetails: "Show pause details",
194
- pauseReasonsLabel: "Reasons this workstream is paused",
195
- pausedByLabel: "Paused by ",
196
- alsoPausedByLabel: "Also paused by ",
197
- resumeWorkspace: "Resume workspace",
198
- resumeFromSession: "Resume from this session",
199
- sessionCanRun: "This session will be able to run",
200
- stillPausedBy: (displayName) => `Still paused by ${displayName}`,
201
- restoredResourcesLabel: "Restored prompt resources",
202
- restoredFile: (fileId) => `File ${fileId.slice(0, 8)}`,
203
- removeRestoredResource: (index) => `Remove restored resource ${index + 1}`,
204
- uploading: "Uploading",
205
- uploadFailed: "Upload failed",
206
- previewAttachment: (name) => `Preview ${name}`,
207
- attachmentPreviewLabel: "Attachment preview",
208
- downloadAttachment: (name) => `Download ${name}`,
209
- closeAttachmentPreview: "Close",
210
- retryAttachment: (name) => `Retry ${name}`,
211
- retryUpload: "Retry upload",
212
- removeAttachment: (name) => `Remove ${name}`,
213
- confirmCommand: (name) => `Confirm /${name}`,
214
- confirmDescription: (command) => `Run /${command.name}? ${command.description}`,
215
- cancel: "Cancel",
216
- runCommand: (name) => `Run /${name}`,
217
- commands: "Commands",
218
- slashCommandsLabel: "Slash commands",
219
- modelLabel: "Model",
220
- close: "Close",
221
- danger: "danger",
222
- draftConflict: "This draft changed in another tab. Your local draft is still here.",
223
- useOtherDraft: "Use other draft",
224
- keepMine: "Keep mine",
225
- // Kept for embedder message overrides / back-compat. Routine autosave is
226
- // silent — only draft conflicts surface under the composer.
227
- savingDraft: "Saving draft…",
228
- formatBytes,
229
- formatRelativeTime,
230
- };
111
+ export { defaultChatComposerMessages } from "../composer-messages";
112
+ export type { ChatComposerMessages } from "../composer-messages";
231
113
 
232
114
  export type ComposerSubmitMode = "queue" | "steer";
233
115
  export type ComposerSubmitBlocker =
@@ -235,9 +117,21 @@ export type ComposerSubmitBlocker =
235
117
  | "attachment"
236
118
  | "sending"
237
119
  | "command"
120
+ | "annotations"
238
121
  | "empty"
239
122
  | null;
240
123
 
124
+ /**
125
+ * How the composer offers run control.
126
+ * - `pause`: the workstream Pause control and paused-state strip (default; the
127
+ * Opengeni console).
128
+ * - `stop`: a Stop control only while a response runs. Stopping pauses this
129
+ * conversation; the next message continues it, so people never see a paused
130
+ * state they have to resume. Pauses applied elsewhere still show.
131
+ * - `none`: no run control.
132
+ */
133
+ export type ComposerRunControl = "pause" | "stop" | "none";
134
+
241
135
  export type UseChatComposerControllerOptions = {
242
136
  delivery: ComposerDelivery;
243
137
  draft?: ComposerDraftState | undefined;
@@ -253,6 +147,10 @@ export type UseChatComposerControllerOptions = {
253
147
  onClearView?: (() => void) | undefined;
254
148
  onPaste?: ((event: ClipboardEvent<HTMLTextAreaElement>) => void) | undefined;
255
149
  messages?: Partial<ChatComposerMessages> | undefined;
150
+ /** Run control presentation. Defaults to `pause`. */
151
+ runControl?: ComposerRunControl | undefined;
152
+ /** A response is in progress; shows the Stop control under `runControl="stop"`. */
153
+ running?: boolean | undefined;
256
154
  };
257
155
 
258
156
  /**
@@ -279,7 +177,7 @@ function measureComposerContentHeight(textarea: HTMLTextAreaElement): number {
279
177
  mirror.tabIndex = -1;
280
178
  mirror.rows = 1;
281
179
  mirror.style.cssText =
282
- "position:absolute;top:0;left:0;visibility:hidden;pointer-events:none;height:auto;min-height:0;max-height:none;overflow:hidden;z-index:-1;";
180
+ "position:fixed;top:0;left:-100000px;visibility:hidden;pointer-events:none;height:auto;min-height:0;max-height:none;overflow:hidden;z-index:-1;";
283
181
  composerHeightMirror = mirror;
284
182
  }
285
183
 
@@ -359,7 +257,10 @@ export function useChatComposerController({
359
257
  onClearView,
360
258
  onPaste,
361
259
  messages: messageOverrides,
260
+ runControl = "pause",
261
+ running = false,
362
262
  }: UseChatComposerControllerOptions) {
263
+ const formatError = useErrorMessage();
363
264
  const messages = useMemo(
364
265
  () => ({ ...defaultChatComposerMessages, ...messageOverrides }),
365
266
  [messageOverrides],
@@ -370,7 +271,24 @@ export function useChatComposerController({
370
271
  const pauseButtonRef = useRef<HTMLButtonElement | null>(null);
371
272
  const fileInputRef = useRef<HTMLInputElement | null>(null);
372
273
  const listboxId = useId();
373
- const paused = effectiveControl?.state === "paused";
274
+ const controlPaused = effectiveControl?.state === "paused";
275
+ // Set when this composer's Stop paused the conversation; cleared once it runs
276
+ // again. Pauses from anyone or anywhere else are never reinterpreted.
277
+ const [stoppedHere, setStoppedHere] = useState(false);
278
+ useEffect(() => {
279
+ if (!controlPaused) setStoppedHere(false);
280
+ }, [controlPaused]);
281
+ // Under Stop, the stopped response is not a state to manage: hide it and let
282
+ // the next message continue (a Steer resumes a paused branch). It applies
283
+ // only to this conversation's own pause with nothing queued behind it.
284
+ const resumesOnSend =
285
+ runControl === "stop" &&
286
+ stoppedHere &&
287
+ controlPaused &&
288
+ effectiveControl?.directState === "paused" &&
289
+ effectiveControl.additionalBlockerCount === 0 &&
290
+ queuedAheadCount === 0;
291
+ const paused = controlPaused && !resumesOnSend;
374
292
  const [controlDetailsOpen, setControlDetailsOpen] = useState(false);
375
293
  const [paletteMounted, setPaletteMounted] = useState(false);
376
294
  const [submitting, setSubmitting] = useState(false);
@@ -435,7 +353,6 @@ export function useChatComposerController({
435
353
  }, [id, paused]);
436
354
 
437
355
  const blockedByAttachment = attachments?.hasUnresolved === true;
438
- const hasReadyAttachment = (attachments?.readyResources.length ?? 0) > 0;
439
356
 
440
357
  const [dragging, setDragging] = useState(false);
441
358
  const dragCarriesFiles = (event: { dataTransfer: DataTransfer | null }): boolean =>
@@ -444,9 +361,9 @@ export function useChatComposerController({
444
361
  (event: DragEvent<HTMLDivElement>) => {
445
362
  if (!attachments || !dragCarriesFiles(event)) return;
446
363
  event.preventDefault();
447
- setDragging(true);
364
+ if (!disabled) setDragging(true);
448
365
  },
449
- [attachments],
366
+ [attachments, disabled],
450
367
  );
451
368
  const handleDragLeave = useCallback(
452
369
  (event: DragEvent<HTMLDivElement>) => {
@@ -461,11 +378,16 @@ export function useChatComposerController({
461
378
  if (!attachments || !dragCarriesFiles(event)) return;
462
379
  event.preventDefault();
463
380
  setDragging(false);
464
- if (event.dataTransfer.files.length > 0) attachments.addFiles(event.dataTransfer.files);
381
+ if (!disabled && event.dataTransfer.files.length > 0)
382
+ attachments.addFiles(event.dataTransfer.files);
465
383
  },
466
- [attachments],
384
+ [attachments, disabled],
467
385
  );
468
386
 
387
+ useEffect(() => {
388
+ if (disabled) setDragging(false);
389
+ }, [disabled]);
390
+
469
391
  const [notice, setNotice] = useState<Notice | null>(null);
470
392
  const [helpOpen, setHelpOpen] = useState(false);
471
393
  const [confirmState, setConfirmState] = useState<ConfirmState>(null);
@@ -545,6 +467,9 @@ export function useChatComposerController({
545
467
  });
546
468
  const paletteEnabled = commandContext !== undefined;
547
469
  const commandDraftBlocked = paletteEnabled && palette.isCommandDraft;
470
+ const annotationsIncomplete = (delivery.annotations ?? []).some(
471
+ (annotation) => annotation.note.trim().length === 0,
472
+ );
548
473
 
549
474
  const submitBlocker: ComposerSubmitBlocker = disabled
550
475
  ? "disabled"
@@ -554,9 +479,11 @@ export function useChatComposerController({
554
479
  ? "sending"
555
480
  : commandDraftBlocked
556
481
  ? "command"
557
- : delivery.canSend || hasReadyAttachment
558
- ? null
559
- : "empty";
482
+ : annotationsIncomplete
483
+ ? "annotations"
484
+ : delivery.canSend
485
+ ? null
486
+ : "empty";
560
487
  const canSubmit = submitBlocker === null;
561
488
 
562
489
  const submit = useCallback(
@@ -568,23 +495,31 @@ export function useChatComposerController({
568
495
  }
569
496
  if (disabled || blockedByAttachment || delivery.sending || submittingRef.current)
570
497
  return false;
571
- if (!delivery.canSend && !hasReadyAttachment) return false;
498
+ if (annotationsIncomplete) {
499
+ setNotice({ tone: "error", message: messages.annotationNotesRequired });
500
+ delivery.clearError();
501
+ delivery.requestAnnotationReview?.();
502
+ return false;
503
+ }
504
+ if (!delivery.canSend) return false;
572
505
  submittingRef.current = true;
573
506
  setSubmitting(true);
574
507
  try {
575
- return mode === "steer" ? await delivery.steer() : await delivery.send();
508
+ return mode === "steer" || resumesOnSend ? await delivery.steer() : await delivery.send();
576
509
  } finally {
577
510
  submittingRef.current = false;
578
511
  if (mountedRef.current) setSubmitting(false);
579
512
  }
580
513
  },
581
514
  [
515
+ annotationsIncomplete,
582
516
  blockedByAttachment,
583
517
  commandDraftBlocked,
584
518
  delivery,
585
519
  disabled,
586
- hasReadyAttachment,
520
+ messages.annotationNotesRequired,
587
521
  messages.slashCommandBlocked,
522
+ resumesOnSend,
588
523
  ],
589
524
  );
590
525
 
@@ -599,17 +534,18 @@ export function useChatComposerController({
599
534
  );
600
535
  const handlePaste = useCallback(
601
536
  (event: ClipboardEvent<HTMLTextAreaElement>) => {
537
+ if (disabled) return;
602
538
  onPaste?.(event);
603
539
  attachments?.addFromPaste(event);
604
540
  },
605
- [attachments, onPaste],
541
+ [attachments, disabled, onPaste],
606
542
  );
607
543
  const handleFileChange = useCallback(
608
544
  (event: ChangeEvent<HTMLInputElement>) => {
609
- if (event.target.files) attachments?.addFiles(event.target.files);
545
+ if (!disabled && event.target.files) attachments?.addFiles(event.target.files);
610
546
  event.target.value = "";
611
547
  },
612
- [attachments],
548
+ [attachments, disabled],
613
549
  );
614
550
 
615
551
  const helpCommands = useMemo(
@@ -632,7 +568,10 @@ export function useChatComposerController({
632
568
  tone: "error" as const,
633
569
  message: /control changed|paused while/i.test(delivery.error.message)
634
570
  ? messages.controlChangedError
635
- : composerSubmissionErrorMessage(delivery.error) || messages.sendFailedError,
571
+ : formatError(
572
+ delivery.error,
573
+ composerSubmissionErrorMessage(delivery.error) || messages.sendFailedError,
574
+ ),
636
575
  }
637
576
  : null);
638
577
  useEffect(() => {
@@ -643,6 +582,12 @@ export function useChatComposerController({
643
582
  );
644
583
  return () => window.clearTimeout(timer);
645
584
  }, [notice]);
585
+ useEffect(() => {
586
+ if (annotationsIncomplete) return;
587
+ setNotice((current) =>
588
+ current?.message === messages.annotationNotesRequired ? null : current,
589
+ );
590
+ }, [annotationsIncomplete, messages.annotationNotesRequired]);
646
591
 
647
592
  const runControlOperation = useCallback(async (operation: () => Promise<void>) => {
648
593
  if (controlOperationRef.current) return false;
@@ -677,6 +622,12 @@ export function useChatComposerController({
677
622
  [control, runControlOperation],
678
623
  );
679
624
 
625
+ const stop = useCallback(async (): Promise<boolean> => {
626
+ const stopped = await pause();
627
+ if (stopped && mountedRef.current) setStoppedHere(true);
628
+ return stopped;
629
+ }, [pause]);
630
+
680
631
  return {
681
632
  id,
682
633
  rootRef,
@@ -701,9 +652,12 @@ export function useChatComposerController({
701
652
  removeRestoredResource: draft?.removeRestoredResource,
702
653
  resolveDraftConflict: draft?.resolveDraftConflict,
703
654
  hasControl: control !== undefined,
655
+ runControl,
656
+ running,
704
657
  pausing: control?.pausing ?? false,
705
658
  resuming: control?.resuming ?? false,
706
659
  pause,
660
+ stop,
707
661
  resume,
708
662
  resumeScope,
709
663
  paused,
@@ -873,6 +827,7 @@ export const Surface = forwardRef<HTMLDivElement, ComposerSurfaceProps>(function
873
827
  const controller = useComposerController();
874
828
  return (
875
829
  <div
830
+ data-og-composer-surface=""
876
831
  {...props}
877
832
  ref={ref}
878
833
  onDragOver={controller.attachments ? controller.handleDragOver : undefined}
@@ -944,9 +899,11 @@ export function Attachments() {
944
899
  <AttachmentChips
945
900
  attachments={controller.attachments.attachments}
946
901
  messages={controller.messages}
902
+ disabled={controller.disabled}
947
903
  onRemove={controller.attachments.remove}
948
904
  onRetry={controller.attachments.retry}
949
905
  onRetainPreview={controller.attachments.retainPreview}
906
+ onLoadPreview={controller.attachments.loadPreview}
950
907
  />
951
908
  );
952
909
  }
@@ -964,6 +921,31 @@ type OwnedInputProps =
964
921
  | "aria-keyshortcuts";
965
922
  export type ComposerInputProps = Omit<ComponentPropsWithoutRef<"textarea">, OwnedInputProps>;
966
923
 
924
+ const EDITING_FOCUS_SELECTOR =
925
+ 'input, textarea, select, [contenteditable="true"], [role="textbox"]';
926
+ const POPUP_FOCUS_SELECTOR =
927
+ '[role="menu"], [role="menubar"], [role="listbox"], [role="dialog"], [role="alertdialog"]';
928
+
929
+ /**
930
+ * Initial focus is a convenience, not authority to move focus the person has
931
+ * placed elsewhere. It yields to a field they started editing and to an open
932
+ * menu, listbox, or dialog that does not contain the composer: moving focus
933
+ * behind a non-modal popup dismisses it, and a modal surface owns focus until
934
+ * it closes.
935
+ */
936
+ function focusBelongsElsewhere(textarea: HTMLTextAreaElement): boolean {
937
+ const active = textarea.ownerDocument.activeElement;
938
+ if (!active || active === textarea) return false;
939
+ if (active.closest(EDITING_FOCUS_SELECTOR)) return true;
940
+ const popup = active.closest(POPUP_FOCUS_SELECTOR);
941
+ if (popup) return !popup.contains(textarea);
942
+ // A dismissed popup can restore a button or link while draft hydration is
943
+ // still pending. Its focus remains intentional after the popup disappears.
944
+ return (
945
+ active !== textarea.ownerDocument.body && active !== textarea.ownerDocument.documentElement
946
+ );
947
+ }
948
+
967
949
  export const Input = forwardRef<HTMLTextAreaElement, ComposerInputProps>(function ComposerInput(
968
950
  { rows = 1, placeholder, className, "aria-label": ariaLabel, autoFocus = false, ...props },
969
951
  forwardedRef,
@@ -973,19 +955,45 @@ export const Input = forwardRef<HTMLTextAreaElement, ComposerInputProps>(functio
973
955
  const paletteOpen =
974
956
  controller.paletteEnabled && controller.paletteMounted && controller.palette.open;
975
957
 
976
- // Native autoFocus loses when the textarea mounts disabled (create-session draft
977
- // hydrate). Retry once the controller becomes interactive.
958
+ // Focus once the controller is interactive. The textarea can mount disabled
959
+ // (create-session draft hydrate), and the route can finish loading after the
960
+ // person has already moved on, so this deliberately does not use the native
961
+ // autoFocus attribute: that would take focus at mount without the guard.
978
962
  useEffect(() => {
979
963
  if (!autoFocus || controller.disabled || autoFocusedRef.current) return;
980
964
  const frame = window.requestAnimationFrame(() => {
981
965
  const textarea = controller.textareaRef.current;
982
966
  if (!textarea || textarea.disabled) return;
983
967
  autoFocusedRef.current = true;
968
+ if (focusBelongsElsewhere(textarea)) return;
984
969
  textarea.focus();
985
970
  });
986
971
  return () => window.cancelAnimationFrame(frame);
987
972
  }, [autoFocus, controller.disabled, controller.textareaRef]);
988
973
 
974
+ // Text rewraps when the box gets narrower or wider (panel resize, viewport
975
+ // change), so refit the height on width changes, not only on edits.
976
+ useEffect(() => {
977
+ const textarea = controller.textareaRef.current;
978
+ if (!textarea || typeof ResizeObserver === "undefined") return;
979
+ let width = textarea.clientWidth;
980
+ let frame: number | null = null;
981
+ const observer = new ResizeObserver(() => {
982
+ if (textarea.clientWidth === width) return;
983
+ width = textarea.clientWidth;
984
+ if (frame !== null) return;
985
+ frame = window.requestAnimationFrame(() => {
986
+ frame = null;
987
+ applyComposerTextareaHeight(textarea, 220);
988
+ });
989
+ });
990
+ observer.observe(textarea);
991
+ return () => {
992
+ observer.disconnect();
993
+ if (frame !== null) window.cancelAnimationFrame(frame);
994
+ };
995
+ }, [controller.textareaRef]);
996
+
989
997
  return (
990
998
  <textarea
991
999
  {...props}
@@ -1001,7 +1009,6 @@ export const Input = forwardRef<HTMLTextAreaElement, ComposerInputProps>(functio
1001
1009
  : (placeholder ?? controller.messages.messagePlaceholder)
1002
1010
  }
1003
1011
  disabled={controller.disabled}
1004
- autoFocus={autoFocus && !controller.disabled}
1005
1012
  aria-label={ariaLabel ?? controller.messages.inputLabel}
1006
1013
  aria-keyshortcuts="Enter Meta+Enter Control+Enter Shift+Enter"
1007
1014
  aria-autocomplete={
@@ -1066,7 +1073,9 @@ export const Controls = forwardRef<HTMLSpanElement, ComposerControlsProps>(
1066
1073
  ref={ref}
1067
1074
  className={cn(
1068
1075
  "og-composer-controls flex min-w-0 flex-1 flex-wrap items-center gap-1.5",
1069
- "max-sm:flex-nowrap max-sm:gap-1",
1076
+ // Phone: 44px touch targets already space themselves; tight gaps leave
1077
+ // the model pill room for its name.
1078
+ "max-sm:flex-nowrap max-sm:gap-0.5",
1070
1079
  className,
1071
1080
  )}
1072
1081
  />
@@ -1107,7 +1116,7 @@ export const Actions = forwardRef<HTMLSpanElement, ComposerActionsProps>(functio
1107
1116
  ref={ref}
1108
1117
  className={cn(
1109
1118
  "og-composer-actions ml-auto flex shrink-0 items-center gap-1.5",
1110
- "max-sm:flex-nowrap max-sm:gap-1",
1119
+ "max-sm:flex-nowrap max-sm:gap-0.5",
1111
1120
  className,
1112
1121
  )}
1113
1122
  />
@@ -1212,12 +1221,19 @@ export const PauseButton = forwardRef<HTMLButtonElement, ComposerPauseButtonProp
1212
1221
  ref,
1213
1222
  ) {
1214
1223
  const controller = useComposerController();
1215
- if (!controller.effectiveControl || controller.paused || !controller.hasControl) return null;
1224
+ if (
1225
+ controller.runControl !== "pause" ||
1226
+ !controller.effectiveControl ||
1227
+ controller.paused ||
1228
+ !controller.hasControl
1229
+ )
1230
+ return null;
1216
1231
  const busy = controller.pausing || controller.resuming;
1217
1232
  const tip = title ?? controller.messages.pauseTitle;
1218
1233
  return (
1219
1234
  <ComposerTip tip={tip}>
1220
1235
  <button
1236
+ data-analytics-action="pause"
1221
1237
  {...props}
1222
1238
  ref={mergeRefs(controller.pauseButtonRef, ref)}
1223
1239
  type="button"
@@ -1244,6 +1260,62 @@ export const PauseButton = forwardRef<HTMLButtonElement, ComposerPauseButtonProp
1244
1260
  },
1245
1261
  );
1246
1262
 
1263
+ export type ComposerStopButtonProps = Omit<
1264
+ ButtonHTMLAttributes<HTMLButtonElement>,
1265
+ OwnedButtonProps
1266
+ >;
1267
+
1268
+ /**
1269
+ * Stop the running response. Rendered only under `runControl="stop"` while a
1270
+ * response runs; stopping pauses this conversation and the next message
1271
+ * continues it.
1272
+ */
1273
+ export const StopButton = forwardRef<HTMLButtonElement, ComposerStopButtonProps>(
1274
+ function ComposerStopButton(
1275
+ { className, "aria-label": ariaLabel, title, children, ...props },
1276
+ ref,
1277
+ ) {
1278
+ const controller = useComposerController();
1279
+ if (
1280
+ controller.runControl !== "stop" ||
1281
+ !controller.running ||
1282
+ !controller.hasControl ||
1283
+ controller.effectiveControl?.state === "paused"
1284
+ )
1285
+ return null;
1286
+ const busy = controller.pausing;
1287
+ const label = ariaLabel ?? controller.messages.stopAriaLabel ?? "Stop";
1288
+ const tip = title ?? controller.messages.stopTitle ?? label;
1289
+ return (
1290
+ <ComposerTip tip={tip}>
1291
+ <button
1292
+ data-analytics-action="stop"
1293
+ data-og-composer-stop=""
1294
+ {...props}
1295
+ ref={ref}
1296
+ type="button"
1297
+ onClick={() => void controller.stop()}
1298
+ disabled={busy}
1299
+ aria-label={label}
1300
+ className={cn(
1301
+ "inline-flex size-8 items-center justify-center rounded-og-md border border-og-border pointer-coarse:size-11",
1302
+ "bg-og-surface-1 text-og-fg transition-colors duration-150",
1303
+ "hover:bg-og-surface-2 disabled:opacity-50",
1304
+ className,
1305
+ )}
1306
+ >
1307
+ {children ??
1308
+ (busy ? (
1309
+ <LoaderCircleIcon className="size-3.5 animate-og-spin" />
1310
+ ) : (
1311
+ <SquareIcon className="size-3 fill-current" />
1312
+ ))}
1313
+ </button>
1314
+ </ComposerTip>
1315
+ );
1316
+ },
1317
+ );
1318
+
1247
1319
  export type ComposerSendButtonProps = Omit<
1248
1320
  ButtonHTMLAttributes<HTMLButtonElement>,
1249
1321
  OwnedButtonProps
@@ -1257,10 +1329,15 @@ export const SendButton = forwardRef<HTMLButtonElement, ComposerSendButtonProps>
1257
1329
  const controller = useComposerController();
1258
1330
  const tip =
1259
1331
  title ??
1260
- (controller.paused ? controller.messages.sendAndResumeTitle : controller.messages.sendTitle);
1332
+ (controller.submitBlocker === "annotations"
1333
+ ? controller.messages.annotationNotesRequired
1334
+ : controller.paused
1335
+ ? controller.messages.sendAndResumeTitle
1336
+ : controller.messages.sendTitle);
1261
1337
  return (
1262
1338
  <ComposerTip tip={tip}>
1263
1339
  <button
1340
+ data-analytics-action="send"
1264
1341
  {...props}
1265
1342
  ref={ref}
1266
1343
  type="button"
@@ -1275,10 +1352,10 @@ export const SendButton = forwardRef<HTMLButtonElement, ComposerSendButtonProps>
1275
1352
  }
1276
1353
  className={cn(
1277
1354
  "inline-flex size-8 items-center justify-center rounded-og-md pointer-coarse:size-11",
1278
- "bg-og-accent text-og-accent-fg shadow-og-sm",
1355
+ "border border-og-primary-border bg-og-primary text-og-primary-fg",
1279
1356
  "transition-[background-color,transform,opacity] duration-150 ease-og-spring",
1280
- "hover:bg-og-accent-strong active:scale-95",
1281
- "disabled:cursor-not-allowed disabled:bg-og-surface-3 disabled:text-og-fg-subtle disabled:shadow-none",
1357
+ "hover:bg-og-primary-hover active:scale-95",
1358
+ "disabled:cursor-not-allowed disabled:opacity-50",
1282
1359
  className,
1283
1360
  )}
1284
1361
  >
@@ -1435,7 +1512,7 @@ function WorkstreamPausedStrip({
1435
1512
  <button
1436
1513
  type="button"
1437
1514
  aria-label={messages.resumeThisWorkstream}
1438
- className="inline-flex min-h-8 shrink-0 items-center gap-1.5 rounded-og-md border border-og-status-waiting/35 bg-og-surface-1 px-2.5 text-og-xs font-medium text-og-fg hover:bg-og-surface-2 pointer-coarse:min-h-11"
1515
+ className="inline-flex min-h-8 shrink-0 items-center gap-1.5 rounded-og-md border border-og-primary-border bg-og-primary px-2.5 text-og-xs font-medium text-og-primary-fg hover:bg-og-primary-hover disabled:cursor-not-allowed disabled:opacity-50 pointer-coarse:min-h-11"
1439
1516
  disabled={busy}
1440
1517
  onClick={onResume}
1441
1518
  >
@@ -1635,23 +1712,143 @@ function ConfirmBar({
1635
1712
  function AttachmentChips({
1636
1713
  attachments,
1637
1714
  messages,
1715
+ disabled,
1638
1716
  onRemove,
1639
1717
  onRetry,
1640
1718
  onRetainPreview,
1719
+ onLoadPreview,
1641
1720
  }: {
1642
1721
  attachments: UseFileAttachmentsResult["attachments"];
1643
1722
  messages: ChatComposerMessages;
1723
+ disabled: boolean;
1644
1724
  onRemove: (id: string) => void;
1645
1725
  onRetry?: ((id: string) => void) | undefined;
1646
1726
  onRetainPreview: UseFileAttachmentsResult["retainPreview"];
1727
+ onLoadPreview: UseFileAttachmentsResult["loadPreview"];
1647
1728
  }) {
1648
1729
  const lightbox = useLightboxOptional();
1730
+ const previewRequest = useRef<AbortController | null>(null);
1731
+ const [previewLoadingId, setPreviewLoadingId] = useState<string | null>(null);
1732
+ const [previewErrorId, setPreviewErrorId] = useState<string | null>(null);
1733
+ // Thumbnails always show: an uploaded image without a live local preview (a
1734
+ // restored draft, a revoked or broken object URL) loads its stored copy.
1735
+ const [storedThumbs, setStoredThumbs] = useState<Record<string, string>>({});
1736
+ const [brokenLocal, setBrokenLocal] = useState<ReadonlySet<string>>(() => new Set());
1737
+ const thumbRequests = useRef<Map<string, AbortController>>(new Map());
1738
+ const localPreview = (attachment: UseFileAttachmentsResult["attachments"][number]) =>
1739
+ attachment.previewUrl && !brokenLocal.has(attachment.id) ? attachment.previewUrl : undefined;
1740
+
1741
+ useEffect(() => {
1742
+ if (!onLoadPreview) return;
1743
+ for (const attachment of attachments) {
1744
+ const id = attachment.id;
1745
+ if (
1746
+ attachment.status !== "ready" ||
1747
+ !attachment.file ||
1748
+ !attachment.contentType.startsWith("image/") ||
1749
+ (attachment.previewUrl && !brokenLocal.has(id)) ||
1750
+ storedThumbs[id] ||
1751
+ thumbRequests.current.has(id)
1752
+ ) {
1753
+ continue;
1754
+ }
1755
+ const controller = new AbortController();
1756
+ thumbRequests.current.set(id, controller);
1757
+ void onLoadPreview(id, controller.signal)
1758
+ .then((url) => {
1759
+ if (url && !controller.signal.aborted) {
1760
+ setStoredThumbs((current) => ({ ...current, [id]: url }));
1761
+ }
1762
+ })
1763
+ .catch(() => undefined)
1764
+ .finally(() => {
1765
+ if (thumbRequests.current.get(id) === controller) thumbRequests.current.delete(id);
1766
+ });
1767
+ }
1768
+ }, [attachments, brokenLocal, onLoadPreview, storedThumbs]);
1769
+ useEffect(() => {
1770
+ const requests = thumbRequests.current;
1771
+ return () => {
1772
+ for (const controller of requests.values()) controller.abort();
1773
+ requests.clear();
1774
+ };
1775
+ }, []);
1776
+
1777
+ useEffect(() => () => previewRequest.current?.abort(), [onLoadPreview]);
1778
+
1779
+ async function openPreview(
1780
+ attachment: UseFileAttachmentsResult["attachments"][number],
1781
+ source: HTMLButtonElement,
1782
+ canLoadPreview: boolean,
1783
+ ) {
1784
+ previewRequest.current?.abort();
1785
+ const attachmentId = attachment.id;
1786
+ const local = localPreview(attachment);
1787
+ const releaseSource = local ? onRetainPreview(attachmentId) : undefined;
1788
+ let src = local ?? storedThumbs[attachmentId];
1789
+ // An unretained local URL may already be revoked: prefer the stored copy.
1790
+ if (!releaseSource && canLoadPreview) src = storedThumbs[attachmentId];
1791
+ if (!src && canLoadPreview) {
1792
+ const controller = new AbortController();
1793
+ previewRequest.current = controller;
1794
+ setPreviewLoadingId(attachmentId);
1795
+ setPreviewErrorId(null);
1796
+ try {
1797
+ src = await onLoadPreview!(attachmentId, controller.signal);
1798
+ if (controller.signal.aborted) return;
1799
+ if (!src) {
1800
+ setPreviewErrorId(attachmentId);
1801
+ return;
1802
+ }
1803
+ } catch {
1804
+ if (!controller.signal.aborted) setPreviewErrorId(attachmentId);
1805
+ return;
1806
+ } finally {
1807
+ if (previewRequest.current === controller) {
1808
+ setPreviewLoadingId(null);
1809
+ }
1810
+ }
1811
+ }
1812
+ lightbox!.open(
1813
+ src!,
1814
+ attachment.name,
1815
+ source,
1816
+ messages.attachmentPreviewLabel,
1817
+ attachment.name,
1818
+ {
1819
+ download: messages.downloadAttachment(attachment.name),
1820
+ close: messages.closeAttachmentPreview,
1821
+ },
1822
+ releaseSource,
1823
+ );
1824
+ }
1825
+
1649
1826
  return (
1650
1827
  <div className="flex flex-wrap gap-2 px-3 py-2">
1651
1828
  {attachments.map((attachment) => {
1652
1829
  const failed = attachment.status === "failed";
1653
- const statusText =
1654
- attachment.status === "uploading"
1830
+ const secureContextRequired = attachment.errorCode === "secure_context_required";
1831
+ const previewFailed = previewErrorId === attachment.id;
1832
+ const previewLoading = previewLoadingId === attachment.id;
1833
+ const local = localPreview(attachment);
1834
+ const thumb = local ?? storedThumbs[attachment.id];
1835
+ // A local object URL that fails (revoked, unreadable) falls back to the stored copy.
1836
+ const onThumbError = local
1837
+ ? () =>
1838
+ setBrokenLocal((current) =>
1839
+ current.has(attachment.id) ? current : new Set(current).add(attachment.id),
1840
+ )
1841
+ : undefined;
1842
+ const canLoadPreview = Boolean(
1843
+ lightbox &&
1844
+ onLoadPreview &&
1845
+ attachment.status === "ready" &&
1846
+ attachment.file &&
1847
+ attachment.contentType.startsWith("image/"),
1848
+ );
1849
+ const statusText = previewFailed
1850
+ ? (messages.previewUnavailable ?? "Preview unavailable")
1851
+ : attachment.status === "uploading"
1655
1852
  ? messages.uploading
1656
1853
  : failed
1657
1854
  ? attachment.error || messages.uploadFailed
@@ -1660,43 +1857,49 @@ function AttachmentChips({
1660
1857
  <div
1661
1858
  key={attachment.id}
1662
1859
  className={cn(
1663
- "flex min-w-0 max-w-[240px] items-center gap-2 rounded-og-md border px-2 py-1.5 text-og-sm",
1860
+ "flex min-w-0 items-center gap-2 rounded-og-md border px-2 py-1.5 text-og-sm",
1664
1861
  failed
1665
- ? "border-og-status-failed/40 bg-og-status-failed/10"
1666
- : "border-og-border bg-og-surface-2",
1862
+ ? cn(
1863
+ "border-og-status-failed/40 bg-og-status-failed/10",
1864
+ secureContextRequired
1865
+ ? "max-w-full items-start sm:max-w-[32rem]"
1866
+ : "max-w-[240px]",
1867
+ )
1868
+ : "max-w-[240px] border-og-border bg-og-surface-2",
1667
1869
  )}
1668
1870
  >
1669
- {attachment.previewUrl && lightbox ? (
1871
+ {lightbox && (thumb || canLoadPreview) ? (
1670
1872
  <button
1671
1873
  type="button"
1672
- className="size-8 shrink-0 overflow-hidden rounded outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent"
1874
+ className={cn(
1875
+ "size-8 shrink-0 overflow-hidden rounded outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent",
1876
+ !thumb && "flex items-center justify-center disabled:cursor-wait",
1877
+ )}
1673
1878
  aria-label={messages.previewAttachment(attachment.name)}
1674
- onClick={(event) => {
1675
- const releasePreview = onRetainPreview(attachment.id);
1676
- lightbox.open(
1677
- attachment.previewUrl!,
1678
- attachment.name,
1679
- event.currentTarget,
1680
- messages.attachmentPreviewLabel,
1681
- attachment.name,
1682
- {
1683
- download: messages.downloadAttachment(attachment.name),
1684
- close: messages.closeAttachmentPreview,
1685
- },
1686
- releasePreview,
1687
- );
1688
- }}
1879
+ aria-busy={previewLoading || undefined}
1880
+ disabled={previewLoading}
1881
+ onClick={(event) =>
1882
+ void openPreview(attachment, event.currentTarget, canLoadPreview)
1883
+ }
1689
1884
  >
1690
- <img
1691
- src={attachment.previewUrl}
1692
- alt=""
1693
- className="h-full w-full object-cover transition-opacity hover:opacity-80"
1694
- />
1885
+ {thumb ? (
1886
+ <img
1887
+ src={thumb}
1888
+ alt=""
1889
+ onError={onThumbError}
1890
+ className="h-full w-full object-cover transition-opacity hover:opacity-80"
1891
+ />
1892
+ ) : previewLoading ? (
1893
+ <LoaderCircleIcon className="size-4 animate-og-spin text-og-fg-muted" />
1894
+ ) : (
1895
+ <ImageIcon className="size-4 text-og-fg-muted" />
1896
+ )}
1695
1897
  </button>
1696
- ) : attachment.previewUrl ? (
1898
+ ) : thumb ? (
1697
1899
  <img
1698
- src={attachment.previewUrl}
1900
+ src={thumb}
1699
1901
  alt=""
1902
+ onError={onThumbError}
1700
1903
  className="size-8 shrink-0 rounded object-cover"
1701
1904
  />
1702
1905
  ) : attachment.contentType.startsWith("image/") ? (
@@ -1706,7 +1909,11 @@ function AttachmentChips({
1706
1909
  )}
1707
1910
  <div className="min-w-0 flex-1">
1708
1911
  <div className="truncate font-medium text-og-fg">{attachment.name}</div>
1709
- {failed ? (
1912
+ {secureContextRequired ? (
1913
+ <div className="break-words text-og-xs leading-4 text-og-status-failed">
1914
+ {statusText}
1915
+ </div>
1916
+ ) : failed || previewFailed ? (
1710
1917
  <ComposerTip tip={statusText}>
1711
1918
  <div className="truncate text-og-xs text-og-status-failed">{statusText}</div>
1712
1919
  </ComposerTip>
@@ -1717,12 +1924,13 @@ function AttachmentChips({
1717
1924
  {attachment.status === "uploading" ? (
1718
1925
  <LoaderCircleIcon className="size-3.5 shrink-0 animate-og-spin" />
1719
1926
  ) : null}
1720
- {failed && onRetry ? (
1927
+ {failed && !secureContextRequired && onRetry ? (
1721
1928
  <ComposerTip tip={messages.retryUpload}>
1722
1929
  <button
1723
1930
  type="button"
1724
1931
  onClick={() => onRetry(attachment.id)}
1725
- className="shrink-0 rounded-og-xs p-1 text-og-fg-muted hover:bg-og-surface-1 hover:text-og-fg pointer-coarse:size-10"
1932
+ disabled={disabled}
1933
+ className="shrink-0 rounded-og-xs p-1 text-og-fg-muted hover:bg-og-surface-1 hover:text-og-fg disabled:cursor-not-allowed disabled:opacity-50 pointer-coarse:size-10"
1726
1934
  aria-label={messages.retryAttachment(attachment.name)}
1727
1935
  >
1728
1936
  <RotateCwIcon className="size-3.5" />
@@ -1732,7 +1940,8 @@ function AttachmentChips({
1732
1940
  <button
1733
1941
  type="button"
1734
1942
  onClick={() => onRemove(attachment.id)}
1735
- className="shrink-0 rounded-og-xs p-1 text-og-fg-muted hover:bg-og-surface-1 hover:text-og-fg pointer-coarse:size-10"
1943
+ disabled={disabled}
1944
+ className="shrink-0 rounded-og-xs p-1 text-og-fg-muted hover:bg-og-surface-1 hover:text-og-fg disabled:cursor-not-allowed disabled:opacity-50 pointer-coarse:size-10"
1736
1945
  aria-label={messages.removeAttachment(attachment.name)}
1737
1946
  >
1738
1947
  <XIcon className="size-3.5" />