@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
@@ -6,8 +6,14 @@ import {
6
6
  Suspense,
7
7
  useEffect,
8
8
  useState,
9
+ useSyncExternalStore,
9
10
  } from "react";
10
11
  import { cn } from "../lib/cn";
12
+ import {
13
+ loadPierreDiffs,
14
+ pierreDiffsRevision,
15
+ subscribePierreDiffs,
16
+ } from "../lib/pierre-diffs-loader";
11
17
 
12
18
  /** Pierre `File` props subset we drive — the single-file, syntax-highlighted view
13
19
  * (Shiki), the read counterpart of `PatchDiff`. */
@@ -25,7 +31,7 @@ type FileComponent = ComponentType<{
25
31
  }>;
26
32
 
27
33
  export type PierreFileProps = {
28
- /** Workspace-relative path (used for the header + language inference). */
34
+ /** Target path (used for the header + language inference). */
29
35
  path: string;
30
36
  /** The decoded text contents. */
31
37
  contents: string;
@@ -44,7 +50,7 @@ export type PierreFileProps = {
44
50
  // Lazy-load `@pierre/diffs/react`'s `File` so Shiki + the worker pool stay off the
45
51
  // critical path (and out of an SSR bundle) until a file is actually viewed.
46
52
  const LazyFile = lazy(async () => {
47
- const mod = (await import("@pierre/diffs/react")) as unknown as { File: FileComponent };
53
+ const mod = (await loadPierreDiffs()) as { File: FileComponent };
48
54
  return { default: mod.File };
49
55
  });
50
56
 
@@ -65,18 +71,30 @@ export function PierreFile({
65
71
  className,
66
72
  }: PierreFileProps) {
67
73
  const [failed, setFailed] = useState(false);
74
+ const [ready, setReady] = useState(false);
68
75
 
69
76
  // Probe the import once so a hard failure (peer missing) shows `fallback`
70
77
  // rather than a Suspense boundary that never resolves.
78
+ const loaderRevision = useSyncExternalStore(
79
+ subscribePierreDiffs,
80
+ pierreDiffsRevision,
81
+ pierreDiffsRevision,
82
+ );
71
83
  useEffect(() => {
72
84
  let cancelled = false;
73
- void import("@pierre/diffs/react").catch(() => {
74
- if (!cancelled) setFailed(true);
75
- });
85
+ setFailed(false);
86
+ loadPierreDiffs().then(
87
+ () => {
88
+ if (!cancelled) setReady(true);
89
+ },
90
+ () => {
91
+ if (!cancelled) setFailed(true);
92
+ },
93
+ );
76
94
  return () => {
77
95
  cancelled = true;
78
96
  };
79
- }, []);
97
+ }, [loaderRevision]);
80
98
 
81
99
  const name = path.split("/").filter(Boolean).pop() ?? path;
82
100
 
@@ -108,6 +126,9 @@ export function PierreFile({
108
126
  "--diffs-light-bg": "var(--og-color-bg)",
109
127
  "--diffs-bg-buffer-override": "var(--og-color-surface-1)",
110
128
  "--diffs-bg-separator-override": "var(--og-color-surface-1)",
129
+ // Pierre's default (fg mixed 65% into bg) falls under 4.5:1 on the lifted
130
+ // graphite separator; quiet meta text keeps AA on every diff surface.
131
+ "--diffs-fg-number-override": "var(--og-color-fg-subtle)",
111
132
  "--diffs-font-size": "var(--og-code-font-size)",
112
133
  "--diffs-line-height": "var(--og-code-line-height)",
113
134
  } as CSSProperties;
@@ -117,11 +138,15 @@ export function PierreFile({
117
138
  <Suspense fallback={loading ?? <FileSkeleton />}>
118
139
  {/* `cacheKey` keys Pierre's worker-pool highlight cache on path+size so a
119
140
  re-select of the same file is instant but an edited file re-highlights. */}
120
- <LazyFile
121
- file={{ name, contents }}
122
- options={options}
123
- {...(disableWorkerPool !== undefined ? { disableWorkerPool } : {})}
124
- />
141
+ {ready ? (
142
+ <LazyFile
143
+ file={{ name, contents }}
144
+ options={options}
145
+ {...(disableWorkerPool !== undefined ? { disableWorkerPool } : {})}
146
+ />
147
+ ) : (
148
+ (loading ?? <FileSkeleton />)
149
+ )}
125
150
  </Suspense>
126
151
  </div>
127
152
  );
@@ -0,0 +1,154 @@
1
+ import { useEffect, useRef } from "react";
2
+
3
+ /** Private loading surface: never receives or executes the unfinished fence. */
4
+ export function PreviewLoading() {
5
+ const ref = useRef<HTMLCanvasElement>(null);
6
+ useEffect(() => {
7
+ const canvas = ref.current;
8
+ if (!canvas) return;
9
+ let ctx: CanvasRenderingContext2D | null;
10
+ try {
11
+ ctx = canvas.getContext("2d");
12
+ } catch {
13
+ return; // The CSS grid and status remain when canvas is unavailable.
14
+ }
15
+ if (!ctx) return;
16
+ const context = ctx;
17
+ const motion = window.matchMedia?.("(prefers-reduced-motion: reduce)");
18
+ let frame: number | undefined;
19
+ let time = 2;
20
+ let last: number | undefined;
21
+ let disposed = false;
22
+ // Without visibility observation, keep a static surface rather than doing
23
+ // unbounded work for previews that may be outside the viewport.
24
+ let visible = false;
25
+ const canAnimate = () => !disposed && visible && !document.hidden && motion?.matches === false;
26
+
27
+ function draw() {
28
+ const w = canvas!.clientWidth;
29
+ const h = canvas!.clientHeight;
30
+ if (!w || !h || document.hidden || disposed) return;
31
+ const d = Math.min(window.devicePixelRatio || 1, 2);
32
+ if (canvas!.width !== Math.round(w * d) || canvas!.height !== Math.round(h * d)) {
33
+ canvas!.width = Math.round(w * d);
34
+ canvas!.height = Math.round(h * d);
35
+ }
36
+ const style = getComputedStyle(canvas!);
37
+ const ink = style.getPropertyValue("--_og-preview-ink").trim() || "#9fdccd";
38
+ const glowColor = style.getPropertyValue("--_og-preview-glow").trim() || "#5fb8a3";
39
+ context.setTransform(d, 0, 0, d, 0, 0);
40
+ context.clearRect(0, 0, w, h);
41
+ const cx = w * (0.5 + 0.13 * Math.sin(time * 0.21));
42
+ const cy = h * (0.5 + 0.12 * Math.cos(time * 0.27));
43
+ const glow = context.createRadialGradient(cx, cy, 0, cx, cy, Math.max(w, h) * 0.65);
44
+ glow.addColorStop(0, glowColor);
45
+ glow.addColorStop(1, "transparent");
46
+ context.globalAlpha = 0.09;
47
+ context.fillStyle = glow;
48
+ context.fillRect(0, 0, w, h);
49
+ const rows = Math.ceil(h / 18) + 7;
50
+ const cols = Math.ceil(w / 18) + 7;
51
+ const points = Array.from({ length: rows }, (_row, r) =>
52
+ Array.from({ length: cols }, (_col, c) => {
53
+ const x = (c - 3) * 18;
54
+ const y = (r - 3) * 18;
55
+ const dist = Math.hypot((x - cx) * 0.8, y - cy);
56
+ const wave = Math.sin(dist * 0.032 - time * 0.95);
57
+ return {
58
+ x: x + ((x - cx) / Math.max(dist, 1)) * wave * 4,
59
+ y: y + ((y - cy) / Math.max(dist, 1)) * wave * 4,
60
+ l: Math.pow((wave + 1) / 2, 5),
61
+ };
62
+ }),
63
+ );
64
+ context.strokeStyle = ink;
65
+ context.fillStyle = ink;
66
+ context.lineWidth = 0.65;
67
+ points.forEach((row, r) =>
68
+ row.forEach((p, c) => {
69
+ context.globalAlpha = 0.035 + p.l * 0.055;
70
+ context.beginPath();
71
+ if (c + 1 < cols) {
72
+ context.moveTo(p.x, p.y);
73
+ context.lineTo(row[c + 1]!.x, row[c + 1]!.y);
74
+ }
75
+ if (r + 1 < rows) {
76
+ context.moveTo(p.x, p.y);
77
+ context.lineTo(points[r + 1]![c]!.x, points[r + 1]![c]!.y);
78
+ }
79
+ context.stroke();
80
+ context.globalAlpha = 0.15 + p.l * 0.55;
81
+ context.beginPath();
82
+ context.arc(p.x, p.y, 0.85 + p.l * 0.65, 0, Math.PI * 2);
83
+ context.fill();
84
+ }),
85
+ );
86
+ context.globalAlpha = 1;
87
+ canvas!.dataset.painted = "true";
88
+ }
89
+
90
+ function stop() {
91
+ if (frame !== undefined) window.cancelAnimationFrame(frame);
92
+ frame = undefined;
93
+ last = undefined;
94
+ }
95
+ function tick(stamp: number) {
96
+ frame = undefined;
97
+ if (!canAnimate()) return;
98
+ if (last !== undefined) time += Math.min((stamp - last) / 1000, 0.05);
99
+ last = stamp;
100
+ draw();
101
+ frame = window.requestAnimationFrame(tick);
102
+ }
103
+ function refresh() {
104
+ stop();
105
+ if (disposed || document.hidden || (!visible && intersection)) return;
106
+ draw();
107
+ if (canAnimate() && typeof window.requestAnimationFrame === "function") {
108
+ frame = window.requestAnimationFrame(tick);
109
+ }
110
+ }
111
+ const intersection =
112
+ typeof IntersectionObserver === "function"
113
+ ? new IntersectionObserver(([entry]) => {
114
+ visible = entry?.isIntersecting === true;
115
+ refresh();
116
+ })
117
+ : undefined;
118
+ intersection?.observe(canvas);
119
+ const resize = typeof ResizeObserver === "function" ? new ResizeObserver(refresh) : undefined;
120
+ resize?.observe(canvas);
121
+ // Observe only ancestors, not the document subtree. This also updates the
122
+ // static reduced-motion canvas when a host changes its local theme.
123
+ const theme =
124
+ typeof MutationObserver === "function" ? new MutationObserver(refresh) : undefined;
125
+ for (let ancestor = canvas.parentElement; ancestor; ancestor = ancestor.parentElement) {
126
+ theme?.observe(ancestor, {
127
+ attributes: true,
128
+ attributeFilter: ["class", "style", "data-og-theme"],
129
+ });
130
+ }
131
+ motion?.addEventListener?.("change", refresh);
132
+ document.addEventListener("visibilitychange", refresh);
133
+ window.addEventListener("resize", refresh);
134
+ // Old hosts get one still frame; observed surfaces wait until onscreen.
135
+ if (!intersection) draw();
136
+ return () => {
137
+ disposed = true;
138
+ stop();
139
+ intersection?.disconnect();
140
+ resize?.disconnect();
141
+ theme?.disconnect();
142
+ motion?.removeEventListener?.("change", refresh);
143
+ document.removeEventListener("visibilitychange", refresh);
144
+ window.removeEventListener("resize", refresh);
145
+ };
146
+ }, []);
147
+
148
+ return (
149
+ <div className="og-preview-loading">
150
+ <canvas ref={ref} aria-hidden="true" />
151
+ <span className="og-preview-loading-label">Preparing preview…</span>
152
+ </div>
153
+ );
154
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * One presentation rule for a queued item, shared by the full queue and the
3
+ * compact session-chrome dock so the two cannot drift. A turn with an empty
4
+ * prompt and timeline annotations is valid content; an item with neither is a
5
+ * malformed or legacy object that gets an explicit fallback, never a blank row.
6
+ */
7
+ export type QueueItemContent = "text" | "annotations" | "unavailable";
8
+
9
+ export const QUEUE_ITEM_CONTENT_UNAVAILABLE = "Content unavailable";
10
+
11
+ export function queueItemContent(text: string, annotationCount: number): QueueItemContent {
12
+ if (text.length > 0) return "text";
13
+ return annotationCount > 0 ? "annotations" : "unavailable";
14
+ }
@@ -17,6 +17,7 @@ import {
17
17
  } from "@dnd-kit/sortable";
18
18
  import { CSS } from "@dnd-kit/utilities";
19
19
  import type { SessionPendingInputPreview, SessionTurn, TimelineAnnotation } from "@opengeni/sdk";
20
+ import { modelDisplayName } from "@opengeni/sdk/model-display";
20
21
  import {
21
22
  ArrowDownToLineIcon,
22
23
  ArrowUpToLineIcon,
@@ -37,6 +38,7 @@ import {
37
38
  } from "react";
38
39
 
39
40
  import { DropdownMenu } from "radix-ui";
41
+ import { MENU_ITEM_CLASS, MENU_SEPARATOR_CLASS, MENU_SURFACE_CLASS } from "../lib/menu-styles";
40
42
  import type { ComposerState } from "../hooks/use-composer";
41
43
  import type { QueueMutationKind, UseTurnQueueResult } from "../hooks/use-turn-queue";
42
44
  import {
@@ -45,9 +47,13 @@ import {
45
47
  usePortalTokenStyle,
46
48
  } from "../lib/use-portal-token-style";
47
49
  import { requestQueueDraftEdit } from "./queue-draft-policy";
50
+ import { QUEUE_ITEM_CONTENT_UNAVAILABLE, queueItemContent } from "./queue-item-content";
48
51
  import { QueueErrorAlert, QueueStoppingStatus } from "./queue-surface-state";
49
52
  import { TimelineAnnotationsChip } from "./timeline-annotations";
50
53
 
54
+ // Queued prompts can be long; menu rows wrap instead of truncating.
55
+ const QUEUE_MENU_ITEM_CLASS = `${MENU_ITEM_CLASS} whitespace-normal break-words`;
56
+
51
57
  /** The sole pending-input surface: compact above Goal, Agents, and composer. */
52
58
  type QueueSurfaceCommonProps = {
53
59
  /** Focus the composer owned by this queue after checkout/removal. */
@@ -84,6 +90,10 @@ export function QueueSurface({
84
90
  const [replaceDraftFor, setReplaceDraftFor] = useState<string | null>(null);
85
91
  const [announcement, setAnnouncement] = useState("");
86
92
  const [draggedTurnId, setDraggedTurnId] = useState<string | null>(null);
93
+ const [pendingMove, setPendingMove] = useState<{
94
+ baseVersion: number | null;
95
+ turnIds: string[];
96
+ } | null>(null);
87
97
  const surface = usePortalTokenSource<HTMLDivElement>();
88
98
  const surfaceRef = surface.currentRef;
89
99
  const portalTokenStyle = usePortalTokenStyle(surface.source);
@@ -112,30 +122,56 @@ export function QueueSurface({
112
122
  const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 6 } }));
113
123
 
114
124
  const displayedQueue = useMemo(() => {
115
- if (!keyboardDrag) return queue.queue;
116
- const oldIndex = queue.queue.findIndex((turn) => turn.id === keyboardDrag.turnId);
117
- if (oldIndex < 0) return queue.queue;
118
- return arrayMove(queue.queue, oldIndex, keyboardDrag.projectedIndex);
119
- }, [keyboardDrag, queue.queue]);
125
+ if (keyboardDrag) {
126
+ const oldIndex = queue.queue.findIndex((turn) => turn.id === keyboardDrag.turnId);
127
+ if (oldIndex < 0) return queue.queue;
128
+ return arrayMove(queue.queue, oldIndex, keyboardDrag.projectedIndex);
129
+ }
130
+ if (
131
+ !pendingMove ||
132
+ pendingMove.baseVersion === null ||
133
+ queue.snapshot?.version !== pendingMove.baseVersion
134
+ ) {
135
+ return queue.queue;
136
+ }
137
+ const byId = new Map(queue.queue.map((turn) => [turn.id, turn]));
138
+ const projected = pendingMove.turnIds.map((turnId) => byId.get(turnId));
139
+ // Never let an optimistic ordering projection omit or invent a row. Any
140
+ // concurrent authoritative membership change wins immediately.
141
+ if (projected.some((turn) => !turn) || projected.length !== queue.queue.length) {
142
+ return queue.queue;
143
+ }
144
+ return projected as SessionTurn[];
145
+ }, [keyboardDrag, pendingMove, queue.queue, queue.snapshot?.version]);
120
146
 
121
147
  const ids = useMemo(() => displayedQueue.map((turn) => turn.id), [displayedQueue]);
122
148
  const moveToIndex = useCallback(
123
149
  async (turnId: string, nextIndex: number): Promise<void> => {
150
+ if (queue.mutating || pendingMove) return;
124
151
  const oldIndex = queue.queue.findIndex((turn) => turn.id === turnId);
125
152
  if (oldIndex < 0) return;
126
153
  const boundedIndex = Math.max(0, Math.min(nextIndex, queue.queue.length - 1));
127
154
  if (oldIndex === boundedIndex) return;
128
155
  const ordered = arrayMove(queue.queue, oldIndex, boundedIndex);
129
156
  const beforeTurnId = ordered[boundedIndex + 1]?.id ?? null;
130
- const moved = await queue.moveTurn(turnId, beforeTurnId);
131
- setAnnouncement(
132
- moved
133
- ? `Queued prompt moved to position ${boundedIndex + 1}.`
134
- : "The queue changed before that prompt could be moved. Refreshed server order.",
135
- );
136
- if (moved) focusQueueTurn(surfaceRef.current, turnId);
157
+ setPendingMove({
158
+ baseVersion: queue.snapshot?.version ?? null,
159
+ turnIds: ordered.map((turn) => turn.id),
160
+ });
161
+ setAnnouncement(`Saving queued prompt at position ${boundedIndex + 1}.`);
162
+ try {
163
+ const moved = await queue.moveTurn(turnId, beforeTurnId);
164
+ setAnnouncement(
165
+ moved
166
+ ? `Queued prompt moved to position ${boundedIndex + 1}.`
167
+ : "The queue changed before that prompt could be moved. Refreshed server order.",
168
+ );
169
+ if (moved) focusQueueTurn(surfaceRef.current, turnId);
170
+ } finally {
171
+ setPendingMove(null);
172
+ }
137
173
  },
138
- [queue, surfaceRef],
174
+ [pendingMove, queue, surfaceRef],
139
175
  );
140
176
 
141
177
  const onDragEnd = useCallback(
@@ -211,11 +247,15 @@ export function QueueSurface({
211
247
  const edit = useCallback(
212
248
  async (turn: SessionTurn, replaceDraft: boolean) => {
213
249
  if (!composer || !canEditInComposer) return;
250
+ setAnnouncement("Moving queued prompt to the composer…");
214
251
  const restored = await queue.editTurn(turn.id, {
215
252
  expectedDraftRevision: composer.draftRevision,
216
253
  replaceDraft,
217
254
  });
218
- if (!restored) return;
255
+ if (!restored) {
256
+ setAnnouncement("That prompt changed before it could be moved to the composer.");
257
+ return;
258
+ }
219
259
  composer.applyDraft(restored);
220
260
  setReplaceDraftFor(null);
221
261
  setAnnouncement("Queued prompt moved back to the composer for editing.");
@@ -358,6 +398,7 @@ export function QueueSurface({
358
398
  turn.id === queue.pendingInputAttachment?.turnId ? attachedInputs : []
359
399
  }
360
400
  pending={queue.mutationFor(turn.id)}
401
+ reorderDisabled={queue.mutating || pendingMove !== null}
361
402
  confirmingReplace={replaceDraftFor === turn.id}
362
403
  keyboardDragging={keyboardDrag?.turnId === turn.id}
363
404
  portalTokenStyle={portalTokenStyle}
@@ -367,6 +408,7 @@ export function QueueSurface({
367
408
  onConfirmReplace={() => void edit(turn, true)}
368
409
  onCancelReplace={() => setReplaceDraftFor(null)}
369
410
  onSteer={() => {
411
+ setAnnouncement("Requesting this queued prompt as the next direction…");
370
412
  void queue.steerTurn(turn.id).then((steered) => {
371
413
  setAnnouncement(
372
414
  steered
@@ -379,6 +421,7 @@ export function QueueSurface({
379
421
  });
380
422
  }}
381
423
  onDelete={() => {
424
+ setAnnouncement("Deleting queued prompt…");
382
425
  void queue.removeTurn(turn.id).then((removed) => {
383
426
  setAnnouncement(
384
427
  removed
@@ -492,8 +535,7 @@ type QueuePromptPreview = {
492
535
  isFallback: boolean;
493
536
  };
494
537
 
495
- function annotationOnlyQueuePreview(count: number): QueuePromptPreview {
496
- const summary = `${count} timeline ${count === 1 ? "annotation" : "annotations"}`;
538
+ function labelQueuePreview(summary: string): QueuePromptPreview {
497
539
  return {
498
540
  summary,
499
541
  collapsedVisual: summary,
@@ -509,10 +551,24 @@ function queueTurnPreview(
509
551
  maxCharacters: number,
510
552
  ): QueuePromptPreview {
511
553
  if (!turn) return queuePromptPreview("", maxCharacters);
512
- const annotations = turn.annotations ?? [];
513
- return turn.prompt.length === 0 && annotations.length > 0
514
- ? annotationOnlyQueuePreview(annotations.length)
515
- : queuePromptPreview(turn.prompt, maxCharacters);
554
+ return queueContentPreview(turn.prompt, turn.annotations?.length ?? 0, maxCharacters);
555
+ }
556
+
557
+ function queueContentPreview(
558
+ prompt: string,
559
+ annotationCount: number,
560
+ maxCharacters: number,
561
+ ): QueuePromptPreview {
562
+ switch (queueItemContent(prompt, annotationCount)) {
563
+ case "text":
564
+ return queuePromptPreview(prompt, maxCharacters);
565
+ case "annotations":
566
+ return labelQueuePreview(
567
+ `${annotationCount} timeline ${annotationCount === 1 ? "annotation" : "annotations"}`,
568
+ );
569
+ case "unavailable":
570
+ return labelQueuePreview(QUEUE_ITEM_CONTENT_UNAVAILABLE);
571
+ }
516
572
  }
517
573
 
518
574
  /**
@@ -788,11 +844,9 @@ function QueuePrompt({
788
844
  }) {
789
845
  const [expanded, setExpanded] = useState(false);
790
846
  const fullContentId = useId();
847
+ const content = queueItemContent(prompt, annotations.length);
791
848
  const preview = useMemo(
792
- () =>
793
- prompt.length === 0 && annotations.length > 0
794
- ? annotationOnlyQueuePreview(annotations.length)
795
- : queuePromptPreview(prompt, QUEUE_ROW_PREVIEW_CHARACTERS),
849
+ () => queueContentPreview(prompt, annotations.length, QUEUE_ROW_PREVIEW_CHARACTERS),
796
850
  [annotations.length, prompt],
797
851
  );
798
852
 
@@ -843,6 +897,14 @@ function QueuePrompt({
843
897
  className={prompt ? "mt-1" : undefined}
844
898
  />
845
899
  ) : null}
900
+ {content === "unavailable" ? (
901
+ <p
902
+ className="text-og-control leading-5 text-fg-muted italic"
903
+ data-testid={`queue-prompt-unavailable-${index + 1}`}
904
+ >
905
+ {QUEUE_ITEM_CONTENT_UNAVAILABLE}
906
+ </p>
907
+ ) : null}
846
908
  {prompt ? (
847
909
  <button
848
910
  type="button"
@@ -916,7 +978,7 @@ function ReadOnlyQueueRow({
916
978
  {turn.tools.length} tool{turn.tools.length === 1 ? "" : "s"}
917
979
  </span>
918
980
  ) : null}
919
- <span className="min-w-0 truncate">{turn.model}</span>
981
+ <span className="min-w-0 truncate">{modelDisplayName(turn.model)}</span>
920
982
  <span className="shrink-0">{turn.reasoningEffort}</span>
921
983
  </div>
922
984
  </div>
@@ -930,6 +992,7 @@ function SortableQueueRow({
930
992
  count,
931
993
  attachedInputs,
932
994
  pending,
995
+ reorderDisabled,
933
996
  confirmingReplace,
934
997
  keyboardDragging,
935
998
  portalTokenStyle,
@@ -947,6 +1010,7 @@ function SortableQueueRow({
947
1010
  count: number;
948
1011
  attachedInputs: SessionPendingInputPreview[];
949
1012
  pending: QueueMutationKind | null;
1013
+ reorderDisabled: boolean;
950
1014
  confirmingReplace: boolean;
951
1015
  keyboardDragging: boolean;
952
1016
  portalTokenStyle: PortalTokenStyle;
@@ -961,7 +1025,7 @@ function SortableQueueRow({
961
1025
  }) {
962
1026
  const sortable = useSortable({
963
1027
  id: turn.id,
964
- disabled: pending !== null || keyboardDragging,
1028
+ disabled: reorderDisabled || keyboardDragging,
965
1029
  });
966
1030
  return (
967
1031
  <li
@@ -981,7 +1045,7 @@ function SortableQueueRow({
981
1045
  {...sortable.attributes}
982
1046
  {...sortable.listeners}
983
1047
  onKeyDown={onHandleKeyDown}
984
- disabled={pending !== null}
1048
+ disabled={reorderDisabled}
985
1049
  className="col-start-1 row-start-1 mt-0.5 inline-flex size-7 shrink-0 touch-none items-center justify-center rounded-md text-fg-subtle hover:bg-surface-2 hover:text-fg focus-visible:ring-2 focus-visible:ring-ring/40 pointer-coarse:size-[44px]"
986
1050
  aria-label={`Reorder queued prompt ${index + 1}`}
987
1051
  title="Drag to reorder. Press Space, arrows, then Space to drop."
@@ -1012,9 +1076,23 @@ function SortableQueueRow({
1012
1076
  {turn.tools.length} tool{turn.tools.length === 1 ? "" : "s"}
1013
1077
  </span>
1014
1078
  ) : null}
1015
- <span className="min-w-0 truncate">{turn.model}</span>
1079
+ <span className="min-w-0 truncate">{modelDisplayName(turn.model)}</span>
1016
1080
  <span className="shrink-0">{turn.reasoningEffort}</span>
1017
1081
  </div>
1082
+ {pending ? (
1083
+ <div
1084
+ role="status"
1085
+ aria-live="polite"
1086
+ className="mt-1 flex items-center gap-1.5 text-og-xs font-medium text-status-waiting"
1087
+ data-testid={`queue-mutation-${pending}`}
1088
+ >
1089
+ <Loader2Icon
1090
+ aria-hidden="true"
1091
+ className="size-3 shrink-0 animate-spin motion-reduce:animate-none"
1092
+ />
1093
+ {queueMutationPendingLabel(pending)}
1094
+ </div>
1095
+ ) : null}
1018
1096
  </div>
1019
1097
  <div className="col-span-full row-start-3 flex min-w-0 items-start justify-end gap-1.5 sm:col-span-1 sm:col-start-4 sm:row-start-1 sm:gap-2">
1020
1098
  <button
@@ -1022,6 +1100,7 @@ function SortableQueueRow({
1022
1100
  disabled={pending !== null}
1023
1101
  onClick={onSteer}
1024
1102
  aria-label={`Steer queued prompt ${index + 1}`}
1103
+ data-analytics-action="steer"
1025
1104
  title="Steer — interrupt the current turn and send this message now"
1026
1105
  className="inline-flex h-7 shrink-0 items-center justify-center gap-1 rounded-md px-2 text-og-control font-medium text-fg outline-hidden transition-[background-color] hover:bg-surface-2 focus-visible:ring-2 focus-visible:ring-ring/40 disabled:pointer-events-none disabled:opacity-50 pointer-coarse:min-h-[44px] pointer-coarse:min-w-[44px]"
1027
1106
  >
@@ -1065,48 +1144,46 @@ function SortableQueueRow({
1065
1144
  <DropdownMenu.Content
1066
1145
  align="end"
1067
1146
  sideOffset={4}
1068
- className="og-root z-50 w-48 max-w-[calc(100vw-16px)] rounded-md border border-border bg-surface p-1 text-og-control text-fg shadow-lg"
1147
+ collisionPadding={8}
1148
+ className={`${MENU_SURFACE_CLASS} og-root z-50 max-h-(--radix-dropdown-menu-content-available-height) w-52 max-w-[calc(100vw-16px)] overflow-x-hidden overflow-y-auto`}
1069
1149
  style={portalTokenStyle}
1070
1150
  data-testid={`queue-actions-menu-${index + 1}`}
1071
1151
  >
1072
1152
  {onEdit ? (
1073
1153
  <>
1074
- <DropdownMenu.Item
1075
- className="flex min-w-0 cursor-default items-center gap-2 whitespace-normal break-words rounded-sm px-2 py-1.5 outline-hidden focus:bg-surface-2 pointer-coarse:min-h-[44px]"
1076
- onSelect={onEdit}
1077
- >
1078
- <PencilIcon className="size-3.5" /> Edit in composer
1154
+ <DropdownMenu.Item className={QUEUE_MENU_ITEM_CLASS} onSelect={onEdit}>
1155
+ <PencilIcon /> Edit in composer
1079
1156
  </DropdownMenu.Item>
1080
- <DropdownMenu.Separator className="my-1 h-px bg-border" />
1157
+ <DropdownMenu.Separator className={MENU_SEPARATOR_CLASS} />
1081
1158
  </>
1082
1159
  ) : null}
1083
1160
  <DropdownMenu.Item
1084
- className="flex min-w-0 cursor-default items-center gap-2 whitespace-normal break-words rounded-sm px-2 py-1.5 outline-hidden focus:bg-surface-2 data-[disabled]:opacity-50 pointer-coarse:min-h-[44px]"
1161
+ className={QUEUE_MENU_ITEM_CLASS}
1085
1162
  disabled={index === 0}
1086
1163
  onSelect={() => onMove(0)}
1087
1164
  >
1088
- <ArrowUpToLineIcon className="size-3.5" /> Move to top
1165
+ <ArrowUpToLineIcon /> Move to top
1089
1166
  </DropdownMenu.Item>
1090
1167
  <DropdownMenu.Item
1091
- className="flex min-w-0 cursor-default items-center gap-2 whitespace-normal break-words rounded-sm px-2 py-1.5 outline-hidden focus:bg-surface-2 data-[disabled]:opacity-50 pointer-coarse:min-h-[44px]"
1168
+ className={QUEUE_MENU_ITEM_CLASS}
1092
1169
  disabled={index === 0}
1093
1170
  onSelect={() => onMove(index - 1)}
1094
1171
  >
1095
1172
  Move up
1096
1173
  </DropdownMenu.Item>
1097
1174
  <DropdownMenu.Item
1098
- className="flex min-w-0 cursor-default items-center gap-2 whitespace-normal break-words rounded-sm px-2 py-1.5 outline-hidden focus:bg-surface-2 data-[disabled]:opacity-50 pointer-coarse:min-h-[44px]"
1175
+ className={QUEUE_MENU_ITEM_CLASS}
1099
1176
  disabled={index === count - 1}
1100
1177
  onSelect={() => onMove(index + 1)}
1101
1178
  >
1102
1179
  Move down
1103
1180
  </DropdownMenu.Item>
1104
1181
  <DropdownMenu.Item
1105
- className="flex min-w-0 cursor-default items-center gap-2 whitespace-normal break-words rounded-sm px-2 py-1.5 outline-hidden focus:bg-surface-2 data-[disabled]:opacity-50 pointer-coarse:min-h-[44px]"
1182
+ className={QUEUE_MENU_ITEM_CLASS}
1106
1183
  disabled={index === count - 1}
1107
1184
  onSelect={() => onMove(count - 1)}
1108
1185
  >
1109
- <ArrowDownToLineIcon className="size-3.5" /> Move to bottom
1186
+ <ArrowDownToLineIcon /> Move to bottom
1110
1187
  </DropdownMenu.Item>
1111
1188
  </DropdownMenu.Content>
1112
1189
  </DropdownMenu.Portal>
@@ -1130,7 +1207,7 @@ function SortableQueueRow({
1130
1207
  </button>
1131
1208
  <button
1132
1209
  type="button"
1133
- className="rounded-md bg-brand px-2 py-1 font-medium text-white hover:bg-brand/90 focus-visible:ring-2 focus-visible:ring-ring/40"
1210
+ className="rounded-md border border-og-primary-border bg-og-primary text-og-primary-fg px-2 py-1 font-medium hover:bg-og-primary-hover focus-visible:ring-2 focus-visible:ring-ring/40"
1134
1211
  onClick={onConfirmReplace}
1135
1212
  >
1136
1213
  Replace and edit
@@ -1142,6 +1219,19 @@ function SortableQueueRow({
1142
1219
  );
1143
1220
  }
1144
1221
 
1222
+ function queueMutationPendingLabel(kind: QueueMutationKind): string {
1223
+ switch (kind) {
1224
+ case "move":
1225
+ return "Saving new position…";
1226
+ case "edit":
1227
+ return "Moving to composer…";
1228
+ case "steer":
1229
+ return "Changing direction…";
1230
+ case "delete":
1231
+ return "Deleting…";
1232
+ }
1233
+ }
1234
+
1145
1235
  const verticalOnly: Modifier = ({ transform }) => ({ ...transform, x: 0 });
1146
1236
 
1147
1237
  function focusQueueTurn(surface: HTMLElement | null, turnId: string): void {
@@ -1,6 +1,7 @@
1
1
  import { Loader2Icon, RotateCwIcon } from "lucide-react";
2
2
 
3
3
  import type { UseTurnQueueResult } from "../hooks/use-turn-queue";
4
+ import { useErrorMessage } from "../lib/error-message";
4
5
 
5
6
  type QueueStateProps = {
6
7
  queue: UseTurnQueueResult;
@@ -60,6 +61,7 @@ export function QueueErrorAlert({
60
61
  queue,
61
62
  dividerBefore = false,
62
63
  }: QueueStateProps & { dividerBefore?: boolean }) {
64
+ const formatError = useErrorMessage();
63
65
  return (
64
66
  <div className={`${dividerBefore ? "border-t border-border" : ""} p-2`}>
65
67
  <div
@@ -74,7 +76,7 @@ export function QueueErrorAlert({
74
76
  data-testid="queue-error-message"
75
77
  dir="auto"
76
78
  >
77
- {(queue.mutationError ?? queue.error)?.message}
79
+ {formatError(queue.mutationError ?? queue.error)}
78
80
  </span>
79
81
  <button
80
82
  type="button"