@opengeni/react 0.46.1 → 0.52.1

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 (341) hide show
  1. package/README.md +158 -14
  2. package/dist/artifacts-document.d.ts +3 -0
  3. package/dist/artifacts-document.js +17 -0
  4. package/dist/artifacts-document.js.map +1 -0
  5. package/dist/artifacts-presentation.d.ts +3 -0
  6. package/dist/artifacts-presentation.js +17 -0
  7. package/dist/artifacts-presentation.js.map +1 -0
  8. package/dist/artifacts-spreadsheet.d.ts +3 -0
  9. package/dist/artifacts-spreadsheet.js +17 -0
  10. package/dist/artifacts-spreadsheet.js.map +1 -0
  11. package/dist/artifacts.d.ts +2 -0
  12. package/dist/artifacts.js +170 -0
  13. package/dist/artifacts.js.map +1 -0
  14. package/dist/chunk-6BBWWOOU.js +82 -0
  15. package/dist/chunk-6BBWWOOU.js.map +1 -0
  16. package/dist/{chunk-HFO4ERGQ.js → chunk-724BW4TW.js} +586 -35
  17. package/dist/chunk-724BW4TW.js.map +1 -0
  18. package/dist/chunk-7I2KB3OK.js +3895 -0
  19. package/dist/chunk-7I2KB3OK.js.map +1 -0
  20. package/dist/chunk-7WCLAEFV.js +2828 -0
  21. package/dist/chunk-7WCLAEFV.js.map +1 -0
  22. package/dist/{chunk-U3CSCMWA.js → chunk-FK6VG4LL.js} +9 -13
  23. package/dist/chunk-FK6VG4LL.js.map +1 -0
  24. package/dist/{chunk-SRFUT2ZU.js → chunk-FWS3KC3Z.js} +120 -64
  25. package/dist/chunk-FWS3KC3Z.js.map +1 -0
  26. package/dist/{chunk-EKZH6IDG.js → chunk-HDBG7XGO.js} +62 -1
  27. package/dist/chunk-HDBG7XGO.js.map +1 -0
  28. package/dist/chunk-HUIKIDM5.js +2148 -0
  29. package/dist/chunk-HUIKIDM5.js.map +1 -0
  30. package/dist/{chunk-LGVMUIRV.js → chunk-JAGDUCZQ.js} +1053 -390
  31. package/dist/chunk-JAGDUCZQ.js.map +1 -0
  32. package/dist/{chunk-LWR4MXSS.js → chunk-JR3QFY6B.js} +420 -35
  33. package/dist/chunk-JR3QFY6B.js.map +1 -0
  34. package/dist/chunk-JVYQRRC4.js +53 -0
  35. package/dist/chunk-JVYQRRC4.js.map +1 -0
  36. package/dist/chunk-KCGXPP5V.js +157 -0
  37. package/dist/chunk-KCGXPP5V.js.map +1 -0
  38. package/dist/{chunk-EB67J347.js → chunk-KZ73RL76.js} +111 -31
  39. package/dist/chunk-KZ73RL76.js.map +1 -0
  40. package/dist/chunk-PEI6RANI.js +3234 -0
  41. package/dist/chunk-PEI6RANI.js.map +1 -0
  42. package/dist/{chunk-3PB7MIT6.js → chunk-ROIRTM37.js} +220 -72
  43. package/dist/chunk-ROIRTM37.js.map +1 -0
  44. package/dist/chunk-VZTQ73XT.js +86 -0
  45. package/dist/chunk-VZTQ73XT.js.map +1 -0
  46. package/dist/{chunk-VCBFUSUZ.js → chunk-WSK7G5LE.js} +72 -4
  47. package/dist/chunk-WSK7G5LE.js.map +1 -0
  48. package/dist/{chunk-FGZUCXZF.js → chunk-WYA65Y3F.js} +16 -16
  49. package/dist/chunk-WYA65Y3F.js.map +1 -0
  50. package/dist/{chunk-6EDV6YFE.js → chunk-X4S56Y2H.js} +147 -35
  51. package/dist/chunk-X4S56Y2H.js.map +1 -0
  52. package/dist/client.d.ts +7 -1
  53. package/dist/clipboard.d.ts +1 -0
  54. package/dist/clipboard.js +7 -0
  55. package/dist/clipboard.js.map +1 -0
  56. package/dist/commands/index.d.ts +3 -3
  57. package/dist/commands/registry.d.ts +1 -1
  58. package/dist/commands/types.d.ts +1 -1
  59. package/dist/components/approval-surface.d.ts +2 -2
  60. package/dist/components/artifacts/artifact-surface.d.ts +18 -0
  61. package/dist/components/artifacts/document-editor.d.ts +172 -0
  62. package/dist/components/artifacts/editable-artifact-ui.d.ts +13 -0
  63. package/dist/components/artifacts/editable-artifact-workbench.d.ts +49 -0
  64. package/dist/components/artifacts/editable-document.d.ts +24 -0
  65. package/dist/components/artifacts/editable-presentation.d.ts +24 -0
  66. package/dist/components/artifacts/editable-spreadsheet.d.ts +32 -0
  67. package/dist/components/artifacts/index.d.ts +8 -0
  68. package/dist/components/artifacts/presentation-editor.d.ts +297 -0
  69. package/dist/components/artifacts/spreadsheet-canvas.d.ts +120 -0
  70. package/dist/components/artifacts/spreadsheet-grid.d.ts +113 -0
  71. package/dist/components/browser-viewer.d.ts +29 -0
  72. package/dist/components/chat-composer.d.ts +13 -8
  73. package/dist/components/code-editor.d.ts +25 -3
  74. package/dist/components/command-palette.d.ts +2 -2
  75. package/dist/components/composer-transcription-control.d.ts +4 -2
  76. package/dist/components/composer.d.ts +29 -15
  77. package/dist/components/computer-viewer.d.ts +23 -0
  78. package/dist/components/copy-button.d.ts +2 -2
  79. package/dist/components/desktop-viewer.d.ts +25 -21
  80. package/dist/components/diff-view.d.ts +1 -1
  81. package/dist/components/enrollment-consent.d.ts +1 -1
  82. package/dist/components/enrollment-device-flow.d.ts +1 -1
  83. package/dist/components/file-browser.d.ts +2 -2
  84. package/dist/components/fleet-tile.d.ts +1 -1
  85. package/dist/components/generated-video-player.d.ts +10 -0
  86. package/dist/components/human-input-form.d.ts +1 -1
  87. package/dist/components/human-input-surface.d.ts +2 -2
  88. package/dist/components/interactive-workbench-viewers.d.ts +2 -0
  89. package/dist/components/machine-card.d.ts +2 -2
  90. package/dist/components/machine-dock-bar.d.ts +3 -3
  91. package/dist/components/machine-health-pill.d.ts +2 -2
  92. package/dist/components/machine-input-display.d.ts +1 -1
  93. package/dist/components/machine-metrics.d.ts +2 -2
  94. package/dist/components/machine-status-pill.d.ts +4 -4
  95. package/dist/components/machines/health.d.ts +1 -1
  96. package/dist/components/machines/machine-detail.d.ts +5 -3
  97. package/dist/components/machines/metric-history-chart.d.ts +1 -1
  98. package/dist/components/machines/metric-sparkline.d.ts +2 -2
  99. package/dist/components/machines/series.d.ts +2 -2
  100. package/dist/components/machines-dashboard.d.ts +5 -5
  101. package/dist/components/markdown.d.ts +1 -1
  102. package/dist/components/message-timeline.d.ts +22 -5
  103. package/dist/components/model-picker.d.ts +2 -2
  104. package/dist/components/model-policy-picker.d.ts +7 -7
  105. package/dist/components/pierre-diff.d.ts +1 -1
  106. package/dist/components/pierre-file.d.ts +1 -1
  107. package/dist/components/queue-draft-policy.d.ts +1 -1
  108. package/dist/components/queue-surface-implementation.d.ts +3 -3
  109. package/dist/components/queue-surface-state.d.ts +4 -4
  110. package/dist/components/queue-surface.d.ts +5 -5
  111. package/dist/components/sandbox-files.d.ts +5 -5
  112. package/dist/components/sandbox-terminal.d.ts +50 -4
  113. package/dist/components/sandbox-workspace.d.ts +30 -10
  114. package/dist/components/session-chrome.d.ts +4 -4
  115. package/dist/components/session-status.d.ts +2 -2
  116. package/dist/components/timeline-annotation-selection.d.ts +9 -0
  117. package/dist/components/timeline-annotations-dialog.d.ts +16 -0
  118. package/dist/components/timeline-annotations.d.ts +13 -0
  119. package/dist/components/tooltip.d.ts +4 -4
  120. package/dist/components/user-message-body.d.ts +2 -2
  121. package/dist/components/workbench-changes.d.ts +2 -2
  122. package/dist/components/workspace-dock.d.ts +3 -1
  123. package/dist/composer.d.ts +11 -11
  124. package/dist/composer.js +7 -7
  125. package/dist/hooks/internal.d.ts +7 -1
  126. package/dist/hooks/use-attached-browsers.d.ts +21 -0
  127. package/dist/hooks/use-available-models.d.ts +2 -2
  128. package/dist/hooks/use-billing-usage.d.ts +1 -1
  129. package/dist/hooks/use-browser-frame-stream.d.ts +28 -0
  130. package/dist/hooks/use-browser-identities.d.ts +26 -0
  131. package/dist/hooks/use-browser-session.d.ts +28 -0
  132. package/dist/hooks/use-browser-sessions.d.ts +32 -0
  133. package/dist/hooks/use-codex-accounts.d.ts +3 -3
  134. package/dist/hooks/use-composer.d.ts +36 -9
  135. package/dist/hooks/use-computer-frame-stream.d.ts +24 -0
  136. package/dist/hooks/use-computer-session.d.ts +28 -0
  137. package/dist/hooks/use-computer-sessions.d.ts +28 -0
  138. package/dist/hooks/use-desktop-stream.d.ts +1 -1
  139. package/dist/hooks/use-environments.d.ts +11 -5
  140. package/dist/hooks/use-file-attachments.d.ts +1 -1
  141. package/dist/hooks/use-goal.d.ts +2 -2
  142. package/dist/hooks/use-human-input.d.ts +2 -2
  143. package/dist/hooks/use-last-started-turn-policy.d.ts +2 -2
  144. package/dist/hooks/use-machine-chip.d.ts +2 -2
  145. package/dist/hooks/use-machines.d.ts +10 -3
  146. package/dist/hooks/use-packs.d.ts +7 -2
  147. package/dist/hooks/use-rigs.d.ts +1 -1
  148. package/dist/hooks/use-sandbox-files.d.ts +25 -4
  149. package/dist/hooks/use-sandbox-git.d.ts +13 -5
  150. package/dist/hooks/use-sandbox-terminal.d.ts +1 -1
  151. package/dist/hooks/use-scheduled-tasks.d.ts +1 -1
  152. package/dist/hooks/use-session-capabilities.d.ts +5 -4
  153. package/dist/hooks/use-session-control.d.ts +1 -1
  154. package/dist/hooks/use-session-events.d.ts +2 -2
  155. package/dist/hooks/use-session-lineage.d.ts +1 -1
  156. package/dist/hooks/use-session-mcp-approval-policy.d.ts +2 -2
  157. package/dist/hooks/use-session.d.ts +2 -2
  158. package/dist/hooks/use-slash-commands.d.ts +1 -1
  159. package/dist/hooks/use-terminal-stream.d.ts +8 -2
  160. package/dist/hooks/use-transcription.d.ts +2 -2
  161. package/dist/hooks/use-turn-queue.d.ts +2 -2
  162. package/dist/hooks/use-video-artifact-playback.d.ts +9 -0
  163. package/dist/hooks/use-voice-input.d.ts +6 -4
  164. package/dist/hooks/use-workspace-capture.d.ts +1 -1
  165. package/dist/hooks/use-workspace-edit.d.ts +1 -1
  166. package/dist/hooks/use-workspace-sessions.d.ts +1 -1
  167. package/dist/hooks/use-workspaces.d.ts +1 -1
  168. package/dist/index.d.ts +158 -154
  169. package/dist/index.js +1718 -908
  170. package/dist/index.js.map +1 -1
  171. package/dist/interaction.d.ts +23 -0
  172. package/dist/interaction.js +36 -0
  173. package/dist/interaction.js.map +1 -0
  174. package/dist/interactive-workbench-viewers-KHNOHWQE.js +13 -0
  175. package/dist/interactive-workbench-viewers-KHNOHWQE.js.map +1 -0
  176. package/dist/lib/composer-responsive-context.d.ts +9 -0
  177. package/dist/lib/relay-wire.d.ts +4 -0
  178. package/dist/lib/sandbox-liveness.d.ts +9 -0
  179. package/dist/lib/terminal-capability.d.ts +5 -0
  180. package/dist/lib/use-portal-token-style.d.ts +14 -3
  181. package/dist/lib/xterm-theme.d.ts +1 -1
  182. package/dist/machines.d.ts +30 -30
  183. package/dist/machines.js +3 -3
  184. package/dist/provider.d.ts +4 -4
  185. package/dist/{queue-surface-implementation-J4XJFKRW.js → queue-surface-implementation-2KVJTYXH.js} +117 -64
  186. package/dist/queue-surface-implementation-2KVJTYXH.js.map +1 -0
  187. package/dist/realtime/dropdown-menu.d.ts +8 -8
  188. package/dist/realtime/realtime-control.d.ts +15 -6
  189. package/dist/realtime.d.ts +4 -4
  190. package/dist/realtime.js +30 -33
  191. package/dist/realtime.js.map +1 -1
  192. package/dist/session-context.d.ts +19 -1
  193. package/dist/session-ui.d.ts +14 -14
  194. package/dist/session-ui.js +6 -5
  195. package/dist/session.d.ts +28 -28
  196. package/dist/session.js +5 -5
  197. package/dist/timeline/activity-rail.d.ts +6 -3
  198. package/dist/timeline/disclosure-context.d.ts +1 -1
  199. package/dist/timeline/fleet-decision-projection.d.ts +1 -1
  200. package/dist/timeline/fleet-decision-row.d.ts +3 -3
  201. package/dist/timeline/index.d.ts +19 -19
  202. package/dist/timeline/parsers.d.ts +6 -3
  203. package/dist/timeline/projection.d.ts +3 -3
  204. package/dist/timeline/registry.d.ts +10 -1
  205. package/dist/timeline/screenshot-lightbox.d.ts +2 -2
  206. package/dist/timeline/shared.d.ts +21 -10
  207. package/dist/timeline/tool-diff.d.ts +2 -2
  208. package/dist/timeline/tool-renderers.d.ts +1 -1
  209. package/dist/timeline/turn-summary.d.ts +3 -3
  210. package/dist/timeline/types.d.ts +42 -2
  211. package/dist/timeline-annotation-selection-3L7LHGG2.js +187 -0
  212. package/dist/timeline-annotation-selection-3L7LHGG2.js.map +1 -0
  213. package/dist/timeline-annotations-dialog-U7EVLR75.js +196 -0
  214. package/dist/timeline-annotations-dialog-U7EVLR75.js.map +1 -0
  215. package/dist/voice-recording-store.d.ts +8 -2
  216. package/package.json +52 -7
  217. package/src/artifacts-document.ts +31 -0
  218. package/src/artifacts-presentation.ts +36 -0
  219. package/src/artifacts-spreadsheet.ts +21 -0
  220. package/src/artifacts.ts +86 -0
  221. package/src/client.ts +90 -1
  222. package/src/clipboard.ts +2 -0
  223. package/src/components/artifacts/artifact-surface.tsx +93 -0
  224. package/src/components/artifacts/document-editor.tsx +2255 -0
  225. package/src/components/artifacts/editable-artifact-ui.tsx +89 -0
  226. package/src/components/artifacts/editable-artifact-workbench.tsx +203 -0
  227. package/src/components/artifacts/editable-document.tsx +657 -0
  228. package/src/components/artifacts/editable-presentation.tsx +1020 -0
  229. package/src/components/artifacts/editable-spreadsheet.tsx +733 -0
  230. package/src/components/artifacts/index.ts +99 -0
  231. package/src/components/artifacts/presentation-editor.tsx +3148 -0
  232. package/src/components/artifacts/spreadsheet-canvas.ts +799 -0
  233. package/src/components/artifacts/spreadsheet-grid.tsx +2129 -0
  234. package/src/components/browser-viewer.tsx +1592 -0
  235. package/src/components/chat-composer.tsx +25 -2
  236. package/src/components/code-editor.tsx +90 -31
  237. package/src/components/command-palette.tsx +1 -1
  238. package/src/components/composer-transcription-control.tsx +51 -22
  239. package/src/components/composer.tsx +49 -23
  240. package/src/components/computer-viewer.tsx +1139 -0
  241. package/src/components/copy-button.tsx +1 -1
  242. package/src/components/desktop-viewer.tsx +103 -75
  243. package/src/components/file-browser.tsx +39 -17
  244. package/src/components/generated-video-player.tsx +89 -0
  245. package/src/components/human-input-form.tsx +2 -2
  246. package/src/components/interactive-workbench-viewers.ts +2 -0
  247. package/src/components/machine-card.tsx +1 -1
  248. package/src/components/machine-input-display.ts +3 -0
  249. package/src/components/machines/machine-detail.tsx +39 -15
  250. package/src/components/machines-dashboard.tsx +7 -6
  251. package/src/components/message-timeline.tsx +327 -37
  252. package/src/components/model-picker.tsx +2 -2
  253. package/src/components/model-policy-picker.tsx +16 -15
  254. package/src/components/queue-surface-implementation.tsx +135 -75
  255. package/src/components/queue-surface-state.tsx +2 -2
  256. package/src/components/sandbox-files.tsx +142 -62
  257. package/src/components/sandbox-terminal.tsx +119 -35
  258. package/src/components/sandbox-workspace.tsx +394 -228
  259. package/src/components/session-chrome.tsx +67 -27
  260. package/src/components/timeline-annotation-selection.tsx +221 -0
  261. package/src/components/timeline-annotations-dialog.tsx +213 -0
  262. package/src/components/timeline-annotations.tsx +84 -0
  263. package/src/components/tooltip.tsx +13 -16
  264. package/src/components/user-message-body.tsx +1 -1
  265. package/src/components/workbench-changes.tsx +192 -35
  266. package/src/components/workspace-dock.tsx +13 -5
  267. package/src/composer.ts +3 -0
  268. package/src/hooks/internal.ts +132 -38
  269. package/src/hooks/use-attached-browsers.ts +152 -0
  270. package/src/hooks/use-browser-frame-stream.ts +316 -0
  271. package/src/hooks/use-browser-identities.ts +225 -0
  272. package/src/hooks/use-browser-session.ts +476 -0
  273. package/src/hooks/use-browser-sessions.ts +281 -0
  274. package/src/hooks/use-codex-accounts.ts +4 -4
  275. package/src/hooks/use-composer.ts +769 -24
  276. package/src/hooks/use-computer-frame-stream.ts +311 -0
  277. package/src/hooks/use-computer-session.ts +442 -0
  278. package/src/hooks/use-computer-sessions.ts +245 -0
  279. package/src/hooks/use-environments.ts +24 -5
  280. package/src/hooks/use-file-attachments.ts +70 -32
  281. package/src/hooks/use-goal.ts +17 -5
  282. package/src/hooks/use-machine-chip.ts +5 -3
  283. package/src/hooks/use-machines.ts +79 -3
  284. package/src/hooks/use-packs.ts +51 -0
  285. package/src/hooks/use-sandbox-files.ts +382 -88
  286. package/src/hooks/use-sandbox-git.ts +208 -46
  287. package/src/hooks/use-sandbox-terminal.ts +3 -2
  288. package/src/hooks/use-session-capabilities.ts +94 -70
  289. package/src/hooks/use-session-events.ts +18 -4
  290. package/src/hooks/use-terminal-stream.ts +102 -23
  291. package/src/hooks/use-transcription.ts +4 -14
  292. package/src/hooks/use-turn-queue.ts +17 -5
  293. package/src/hooks/use-video-artifact-playback.ts +28 -0
  294. package/src/hooks/use-voice-input.ts +163 -19
  295. package/src/hooks/use-windowed-sections.ts +9 -7
  296. package/src/hooks/use-workspace-edit.ts +2 -1
  297. package/src/index.ts +21 -6
  298. package/src/interaction.ts +71 -0
  299. package/src/lib/composer-responsive-context.ts +15 -0
  300. package/src/lib/relay-wire.ts +4 -0
  301. package/src/lib/sandbox-liveness.ts +11 -0
  302. package/src/lib/terminal-capability.ts +10 -0
  303. package/src/lib/use-portal-token-style.ts +60 -15
  304. package/src/provider.tsx +52 -7
  305. package/src/realtime/dropdown-menu.tsx +15 -19
  306. package/src/realtime/realtime-control.tsx +16 -5
  307. package/src/session-context.ts +90 -0
  308. package/src/timeline/activity-rail.tsx +31 -6
  309. package/src/timeline/index.ts +4 -1
  310. package/src/timeline/parsers.ts +46 -20
  311. package/src/timeline/projection.ts +233 -13
  312. package/src/timeline/registry.ts +19 -0
  313. package/src/timeline/screenshot-lightbox.tsx +30 -9
  314. package/src/timeline/shared.tsx +59 -11
  315. package/src/timeline/tool-renderers.tsx +421 -24
  316. package/src/timeline/turn-summary.tsx +2 -2
  317. package/src/timeline/types.ts +58 -2
  318. package/src/voice-recording-store.ts +15 -0
  319. package/styles/compiled.css +5298 -0
  320. package/styles/compiled.d.ts +2 -0
  321. package/styles/effective-tokens.css +27 -0
  322. package/styles/index.css +18 -0
  323. package/styles/responsive.css +208 -0
  324. package/styles/responsive.d.ts +2 -0
  325. package/styles/tokens.css +50 -17
  326. package/dist/chunk-3PB7MIT6.js.map +0 -1
  327. package/dist/chunk-6EDV6YFE.js.map +0 -1
  328. package/dist/chunk-EB67J347.js.map +0 -1
  329. package/dist/chunk-EKZH6IDG.js.map +0 -1
  330. package/dist/chunk-FGZUCXZF.js.map +0 -1
  331. package/dist/chunk-HFO4ERGQ.js.map +0 -1
  332. package/dist/chunk-JB5725BI.js +0 -48
  333. package/dist/chunk-JB5725BI.js.map +0 -1
  334. package/dist/chunk-LGVMUIRV.js.map +0 -1
  335. package/dist/chunk-LWR4MXSS.js.map +0 -1
  336. package/dist/chunk-SRFUT2ZU.js.map +0 -1
  337. package/dist/chunk-U3CSCMWA.js.map +0 -1
  338. package/dist/chunk-VCBFUSUZ.js.map +0 -1
  339. package/dist/fleet-decision-projection-SLNZMS42.js +0 -241
  340. package/dist/fleet-decision-projection-SLNZMS42.js.map +0 -1
  341. package/dist/queue-surface-implementation-J4XJFKRW.js.map +0 -1
@@ -1,7 +1,3 @@
1
- import {
2
- shouldSteerOnKey,
3
- shouldSubmitOnKey
4
- } from "./chunk-HFO4ERGQ.js";
5
1
  import {
6
2
  groupPickerRowsByBillingClass
7
3
  } from "./chunk-23EJ676W.js";
@@ -10,7 +6,14 @@ import {
10
6
  TooltipContent,
11
7
  TooltipProvider,
12
8
  TooltipTrigger
13
- } from "./chunk-U3CSCMWA.js";
9
+ } from "./chunk-FK6VG4LL.js";
10
+ import {
11
+ ComposerResponsiveContext
12
+ } from "./chunk-VZTQ73XT.js";
13
+ import {
14
+ shouldSteerOnKey,
15
+ shouldSubmitOnKey
16
+ } from "./chunk-724BW4TW.js";
14
17
  import {
15
18
  composerSubmissionErrorMessage,
16
19
  formatBytes,
@@ -69,6 +72,8 @@ function createVoiceRecordingManifest(input) {
69
72
  uploadState: "pending",
70
73
  transcriptionState: "pending",
71
74
  finalizationState: "pending",
75
+ recoveryMode: "automatic",
76
+ handoffMode: "append",
72
77
  ownerId: input.ownerId ?? null,
73
78
  ownerHeartbeatAt: input.ownerId ? input.createdAt : null,
74
79
  transcriptText: null,
@@ -184,6 +189,7 @@ var IndexedDbVoiceRecordingStore = class {
184
189
  const updated = {
185
190
  ...manifest,
186
191
  captureState: manifest.captureState === "capturing" ? "stopped" : manifest.captureState,
192
+ handoffMode: "explicit",
187
193
  ownerId,
188
194
  ownerHeartbeatAt: claimedAt,
189
195
  updatedAt: claimedAt
@@ -300,7 +306,9 @@ function normalizeManifest(manifest) {
300
306
  ...manifest,
301
307
  ownerId: manifest.ownerId ?? null,
302
308
  ownerHeartbeatAt: manifest.ownerHeartbeatAt ?? null,
303
- transcriptText: manifest.transcriptText ?? null
309
+ transcriptText: manifest.transcriptText ?? null,
310
+ recoveryMode: manifest.recoveryMode ?? "manual",
311
+ handoffMode: manifest.handoffMode ?? "explicit"
304
312
  };
305
313
  }
306
314
  function manifestAvailableToOwner(manifest, ownership) {
@@ -546,7 +554,7 @@ function useTranscription({
546
554
  (diagnostic) => {
547
555
  if (!onDiagnostic) return;
548
556
  try {
549
- onDiagnostic(sanitizeTranscriptionDiagnostic(diagnostic));
557
+ onDiagnostic(normalizeTranscriptionDiagnostic(diagnostic));
550
558
  } catch {
551
559
  }
552
560
  },
@@ -840,18 +848,14 @@ function normalizeTranscriptionErrorCode(code) {
840
848
  return "unknown";
841
849
  }
842
850
  }
843
- function sanitizeTranscriptionDiagnostic(diagnostic) {
851
+ function normalizeTranscriptionDiagnostic(diagnostic) {
844
852
  const source = isRecord(diagnostic) ? diagnostic : {};
845
853
  const operation = source.operation === "start" || source.operation === "session" || source.operation === "cancel" || source.operation === "close" ? source.operation : "session";
846
854
  const rawDetail = typeof source.detail === "string" ? source.detail : "No diagnostic detail.";
847
- const detail = rawDetail.replace(/[\u0000-\u001f\u007f]+/gu, " ").replace(/\bBearer\s+[A-Za-z0-9._~+/=-]+/giu, "Bearer [REDACTED]").replace(/\bsk-[A-Za-z0-9_-]{4,}\b/gu, "[REDACTED]").replace(
848
- /\b(api[-_ ]?key|authorization|access[-_ ]?token|refresh[-_ ]?token|token|secret)\b\s*[:=]\s*[^\s,;]+/giu,
849
- "$1=[REDACTED]"
850
- ).trim().slice(0, 512);
851
855
  return {
852
856
  operation,
853
857
  code: normalizeTranscriptionErrorCode(source.code),
854
- detail: detail || "No diagnostic detail."
858
+ detail: rawDetail
855
859
  };
856
860
  }
857
861
  function detachSessionCleanup(session, options) {
@@ -929,6 +933,7 @@ function transcriptionPolicyRevision(policy, selection) {
929
933
  }
930
934
 
931
935
  // src/hooks/use-voice-input.ts
936
+ import { OpenGeniApiError } from "@opengeni/sdk";
932
937
  import { useCallback as useCallback2, useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
933
938
 
934
939
  // src/voice-recording-owner.ts
@@ -1150,7 +1155,8 @@ function useVoiceInput({
1150
1155
  createRecordingStore,
1151
1156
  createRecordingId = createDefaultVoiceRecordingId,
1152
1157
  createOwnerId,
1153
- now = currentDate
1158
+ now = currentDate,
1159
+ automaticRetryDelayMilliseconds
1154
1160
  }) {
1155
1161
  const [status, setStatus] = useState2("idle");
1156
1162
  const [error, setError] = useState2(null);
@@ -1175,6 +1181,8 @@ function useVoiceInput({
1175
1181
  const recorderRef = useRef2(null);
1176
1182
  const streamRef = useRef2(null);
1177
1183
  const timerRef = useRef2(null);
1184
+ const automaticRetryTimerRef = useRef2(null);
1185
+ const automaticRetryAttemptRef = useRef2(0);
1178
1186
  const ownerHeartbeatTimerRef = useRef2(null);
1179
1187
  const controllerRef = useRef2(null);
1180
1188
  const valueRef = useRef2(value);
@@ -1226,6 +1234,7 @@ function useVoiceInput({
1226
1234
  setRecordingId(null);
1227
1235
  setDurationSeconds(0);
1228
1236
  setLocallySaved(false);
1237
+ automaticRetryAttemptRef.current = 0;
1229
1238
  }, [stopOwnerHeartbeat]);
1230
1239
  const ensureStore = useCallback2(async () => {
1231
1240
  if (storeRef.current) return storeRef.current;
@@ -1340,7 +1349,7 @@ function useVoiceInput({
1340
1349
  rememberManifest(claimed);
1341
1350
  beginOwnerHeartbeat(claimed);
1342
1351
  setStatus(
1343
- claimed.finalizationState === "transcript-ready" && claimed.transcriptText !== null ? "transcript-ready" : "recovered"
1352
+ claimed.finalizationState === "transcript-ready" && claimed.transcriptText !== null ? "transcript-ready" : claimed.recoveryMode === "automatic" ? "retrying" : "recovered"
1344
1353
  );
1345
1354
  setError(null);
1346
1355
  return;
@@ -1394,7 +1403,12 @@ function useVoiceInput({
1394
1403
  if (chunks.length === 0) {
1395
1404
  const retained = await store.updateManifest(
1396
1405
  transcribing.recordingId,
1397
- { uploadState: "retrying", transcriptionState: "retrying" },
1406
+ {
1407
+ uploadState: "retrying",
1408
+ transcriptionState: "retrying",
1409
+ recoveryMode: "manual",
1410
+ handoffMode: "explicit"
1411
+ },
1398
1412
  readNow().toISOString(),
1399
1413
  ownerIdRef.current ?? void 0
1400
1414
  );
@@ -1425,6 +1439,13 @@ function useVoiceInput({
1425
1439
  );
1426
1440
  if (!active()) return;
1427
1441
  rememberManifest(ready);
1442
+ automaticRetryAttemptRef.current = 0;
1443
+ if (ready.handoffMode === "explicit") {
1444
+ setStatus("transcript-ready");
1445
+ setError("handoff_uncertain");
1446
+ focusInput();
1447
+ return;
1448
+ }
1428
1449
  const next = appendFinalTranscript(valueRef.current, response.text);
1429
1450
  if (next !== valueRef.current) {
1430
1451
  valueRef.current = next;
@@ -1463,16 +1484,22 @@ function useVoiceInput({
1463
1484
  await loadNextRecoverable(generation);
1464
1485
  } catch (reason) {
1465
1486
  if (!active()) return;
1487
+ const code = controller.signal.aborted ? null : errorCode(reason);
1488
+ const retryable = !controller.signal.aborted && isRetryableVoiceInputError(reason);
1466
1489
  const retained = await updateManifestBestEffort(transcribing, {
1467
1490
  uploadState: "retrying",
1468
- transcriptionState: "retrying"
1491
+ transcriptionState: "retrying",
1492
+ recoveryMode: retryable ? "automatic" : "manual",
1493
+ handoffMode: "explicit"
1469
1494
  });
1470
1495
  if (!active()) return;
1471
- await preserveForRetry(
1472
- retained,
1473
- controller.signal.aborted ? null : errorCode(reason),
1474
- generation
1475
- );
1496
+ if (retryable) {
1497
+ rememberManifest(retained);
1498
+ setStatus("retrying");
1499
+ setError(code);
1500
+ } else {
1501
+ await preserveForRetry(retained, code, generation);
1502
+ }
1476
1503
  } finally {
1477
1504
  if (controllerRef.current === controller) controllerRef.current = null;
1478
1505
  }
@@ -1492,6 +1519,44 @@ function useVoiceInput({
1492
1519
  workspaceId
1493
1520
  ]
1494
1521
  );
1522
+ const finalizePersistedRecordingRef = useRef2(finalizePersistedRecording);
1523
+ finalizePersistedRecordingRef.current = finalizePersistedRecording;
1524
+ const clientAvailable = client !== null && client !== void 0;
1525
+ useEffect2(() => {
1526
+ if (status !== "retrying" || !manifestRef.current || manifestRef.current.recoveryMode !== "automatic" || manifestRef.current.workspaceId !== workspaceId || !clientAvailable || disabled || !enabled) {
1527
+ return;
1528
+ }
1529
+ const generation = generationRef.current;
1530
+ let started = false;
1531
+ const run = () => {
1532
+ if (started || generation !== generationRef.current || statusRef.current !== "retrying" || workspaceIdRef.current !== workspaceId) {
1533
+ return;
1534
+ }
1535
+ started = true;
1536
+ if (automaticRetryTimerRef.current) clearTimeout(automaticRetryTimerRef.current);
1537
+ automaticRetryTimerRef.current = null;
1538
+ automaticRetryAttemptRef.current += 1;
1539
+ void finalizePersistedRecordingRef.current(generation);
1540
+ };
1541
+ const onOnline = () => run();
1542
+ globalThis.addEventListener?.("online", onOnline);
1543
+ if (typeof navigator !== "undefined" && navigator.onLine === false) {
1544
+ return () => globalThis.removeEventListener?.("online", onOnline);
1545
+ }
1546
+ const delay2 = Math.max(
1547
+ 0,
1548
+ automaticRetryDelayMilliseconds ?? transcriptionRecoveryMutationDelayMilliseconds(
1549
+ TRANSCRIPTION_RECORDING_RECOVERY_RETRY_AFTER_MILLISECONDS,
1550
+ automaticRetryAttemptRef.current
1551
+ )
1552
+ );
1553
+ automaticRetryTimerRef.current = setTimeout(run, delay2);
1554
+ return () => {
1555
+ globalThis.removeEventListener?.("online", onOnline);
1556
+ if (automaticRetryTimerRef.current) clearTimeout(automaticRetryTimerRef.current);
1557
+ automaticRetryTimerRef.current = null;
1558
+ };
1559
+ }, [automaticRetryDelayMilliseconds, clientAvailable, disabled, enabled, status, workspaceId]);
1495
1560
  const stop = useCallback2(() => {
1496
1561
  const recorder = recorderRef.current;
1497
1562
  if (!recorder || recorder.state === "inactive") return;
@@ -1501,7 +1566,7 @@ function useVoiceInput({
1501
1566
  recorder.stop();
1502
1567
  }, []);
1503
1568
  const start = useCallback2(async () => {
1504
- if (disabled || !client || !enabled || !capability?.available || manifestRef.current !== null || status === "requesting-permission" || status === "recording" || status === "saving" || status === "transcribing" || !navigator.mediaDevices?.getUserMedia || typeof MediaRecorder === "undefined") {
1569
+ if (disabled || !client || !enabled || !capability?.available || manifestRef.current !== null || status === "requesting-permission" || status === "recording" || status === "saving" || status === "transcribing" || status === "retrying" || !navigator.mediaDevices?.getUserMedia || typeof MediaRecorder === "undefined") {
1505
1570
  return false;
1506
1571
  }
1507
1572
  const prerequisiteGeneration = generationRef.current;
@@ -1634,11 +1699,19 @@ function useVoiceInput({
1634
1699
  }
1635
1700
  rememberManifest(stopped);
1636
1701
  if (attemptPersistenceError) {
1637
- await preserveForRetry(stopped, "storage_unavailable", generation);
1702
+ const retained = await updateManifestBestEffort(stopped, {
1703
+ recoveryMode: "manual",
1704
+ handoffMode: "explicit"
1705
+ });
1706
+ await preserveForRetry(retained, "storage_unavailable", generation);
1638
1707
  return;
1639
1708
  }
1640
1709
  if (attemptCaptureLimitError) {
1641
- await preserveForRetry(stopped, attemptCaptureLimitError, generation);
1710
+ const retained = await updateManifestBestEffort(stopped, {
1711
+ recoveryMode: "manual",
1712
+ handoffMode: "explicit"
1713
+ });
1714
+ await preserveForRetry(retained, attemptCaptureLimitError, generation);
1642
1715
  return;
1643
1716
  }
1644
1717
  await finalizePersistedRecording(generation);
@@ -1723,9 +1796,29 @@ function useVoiceInput({
1723
1796
  }
1724
1797
  const generation = ++generationRef.current;
1725
1798
  controllerRef.current?.abort();
1799
+ if (automaticRetryTimerRef.current) clearTimeout(automaticRetryTimerRef.current);
1800
+ automaticRetryTimerRef.current = null;
1801
+ automaticRetryAttemptRef.current = 0;
1726
1802
  setError(null);
1727
- void finalizePersistedRecording(generation);
1728
- }, [client, disabled, enabled, finalizePersistedRecording, status, workspaceId]);
1803
+ const manifest = manifestRef.current;
1804
+ void updateManifestBestEffort(manifest, {
1805
+ recoveryMode: "automatic",
1806
+ handoffMode: "append"
1807
+ }).then((retained) => {
1808
+ if (generation !== generationRef.current) return;
1809
+ rememberManifest(retained);
1810
+ void finalizePersistedRecording(generation);
1811
+ });
1812
+ }, [
1813
+ client,
1814
+ disabled,
1815
+ enabled,
1816
+ finalizePersistedRecording,
1817
+ rememberManifest,
1818
+ status,
1819
+ updateManifestBestEffort,
1820
+ workspaceId
1821
+ ]);
1729
1822
  const insertSavedTranscript = useCallback2(async () => {
1730
1823
  const manifest = manifestRef.current;
1731
1824
  if (!manifest || manifest.workspaceId !== workspaceId || manifest.finalizationState !== "transcript-ready" || manifest.transcriptText === null) {
@@ -1834,10 +1927,12 @@ function useVoiceInput({
1834
1927
  void discard();
1835
1928
  return;
1836
1929
  }
1837
- if (status === "saving" || status === "transcribing") {
1930
+ if (status === "saving" || status === "transcribing" || status === "retrying") {
1838
1931
  const generation = ++generationRef.current;
1839
1932
  controllerRef.current?.abort();
1840
1933
  controllerRef.current = null;
1934
+ if (automaticRetryTimerRef.current) clearTimeout(automaticRetryTimerRef.current);
1935
+ automaticRetryTimerRef.current = null;
1841
1936
  const captureSettled = status === "saving" ? captureSettledRef.current : Promise.resolve();
1842
1937
  void captureSettled.then(async () => {
1843
1938
  const manifest = manifestRef.current;
@@ -1845,7 +1940,9 @@ function useVoiceInput({
1845
1940
  const retained = await updateManifestBestEffort(manifest, {
1846
1941
  captureState: "stopped",
1847
1942
  uploadState: "retrying",
1848
- transcriptionState: "retrying"
1943
+ transcriptionState: "retrying",
1944
+ recoveryMode: "manual",
1945
+ handoffMode: "explicit"
1849
1946
  });
1850
1947
  await preserveForRetry(retained, null, generation);
1851
1948
  });
@@ -1874,7 +1971,12 @@ function useVoiceInput({
1874
1971
  current.recordingId,
1875
1972
  {
1876
1973
  ...current.captureState === "capturing" ? { captureState: "stopped" } : {},
1877
- ...wasProcessing ? { uploadState: "retrying", transcriptionState: "retrying" } : {},
1974
+ ...wasProcessing ? {
1975
+ uploadState: "retrying",
1976
+ transcriptionState: "retrying",
1977
+ recoveryMode: "automatic",
1978
+ handoffMode: "explicit"
1979
+ } : {},
1878
1980
  ownerId: null,
1879
1981
  ownerHeartbeatAt: null
1880
1982
  },
@@ -1898,7 +2000,7 @@ function useVoiceInput({
1898
2000
  ]);
1899
2001
  useEffect2(() => {
1900
2002
  const onKeyDown = (event) => {
1901
- if (event.key === "Escape" && (status === "requesting-permission" || status === "recording" || status === "saving" || status === "transcribing")) {
2003
+ if (event.key === "Escape" && (status === "requesting-permission" || status === "recording" || status === "saving" || status === "transcribing" || status === "retrying")) {
1902
2004
  event.preventDefault();
1903
2005
  cancel();
1904
2006
  }
@@ -1911,6 +2013,8 @@ function useVoiceInput({
1911
2013
  generationRef.current += 1;
1912
2014
  controllerRef.current?.abort();
1913
2015
  controllerRef.current = null;
2016
+ if (automaticRetryTimerRef.current) clearTimeout(automaticRetryTimerRef.current);
2017
+ automaticRetryTimerRef.current = null;
1914
2018
  const manifest = manifestRef.current;
1915
2019
  const ownerReady = ownerIdPromiseRef.current;
1916
2020
  stopOwnerHeartbeat();
@@ -1925,14 +2029,16 @@ function useVoiceInput({
1925
2029
  const ownerId = ownerIdRef.current ?? (ownerReady ? await ownerReady.catch(() => null) : null);
1926
2030
  const store = storeRef.current;
1927
2031
  if (store && manifest && ownerId) {
1928
- const wasProcessing = statusRef.current === "saving" || statusRef.current === "transcribing";
2032
+ const wasProcessing = statusRef.current === "saving" || statusRef.current === "transcribing" || statusRef.current === "retrying";
1929
2033
  await store.updateManifest(
1930
2034
  manifest.recordingId,
1931
2035
  {
1932
2036
  ...manifest.captureState === "capturing" ? { captureState: "stopped" } : {},
1933
2037
  ...wasProcessing ? {
1934
2038
  uploadState: "retrying",
1935
- transcriptionState: "retrying"
2039
+ transcriptionState: "retrying",
2040
+ recoveryMode: "automatic",
2041
+ handoffMode: "explicit"
1936
2042
  } : {},
1937
2043
  ownerId: null,
1938
2044
  ownerHeartbeatAt: null
@@ -2062,7 +2168,7 @@ async function transcribePersistedRecording(input) {
2062
2168
  break;
2063
2169
  case "failed": {
2064
2170
  if (!remote.recording.retryable) {
2065
- throw { code: remote.recording.errorCode ?? "unknown" };
2171
+ throw { code: remote.recording.errorCode ?? "unknown", retryable: false };
2066
2172
  }
2067
2173
  const retried = remote.recording.segmentCount === 0 ? await client.finalizeTranscriptionRecording(
2068
2174
  input.workspaceId,
@@ -2074,7 +2180,10 @@ async function transcribePersistedRecording(input) {
2074
2180
  { signal: input.signal }
2075
2181
  );
2076
2182
  if (retried.recording.state === "failed") {
2077
- throw { code: retried.recording.errorCode ?? "unknown" };
2183
+ throw {
2184
+ code: retried.recording.errorCode ?? "unknown",
2185
+ retryable: retried.recording.retryable
2186
+ };
2078
2187
  }
2079
2188
  remote = retried;
2080
2189
  scheduleRecoveryMutation(remote);
@@ -2154,6 +2263,9 @@ function chooseMimeType(accepted) {
2154
2263
  });
2155
2264
  }
2156
2265
  function errorCode(error) {
2266
+ if (error instanceof OpenGeniApiError && typeof error.details?.transcriptionCode === "string") {
2267
+ return error.details.transcriptionCode;
2268
+ }
2157
2269
  if (error && typeof error === "object" && "code" in error && typeof error.code === "string") {
2158
2270
  return error.code;
2159
2271
  }
@@ -2161,6 +2273,16 @@ function errorCode(error) {
2161
2273
  if (error instanceof DOMException && error.name === "NotSupportedError") return "not_supported";
2162
2274
  return "unknown";
2163
2275
  }
2276
+ function isRetryableVoiceInputError(error) {
2277
+ if (error instanceof OpenGeniApiError) {
2278
+ return error.retryable && error.status !== 409;
2279
+ }
2280
+ if (error instanceof TypeError) return true;
2281
+ if (error && typeof error === "object" && "retryable" in error) {
2282
+ return error.retryable === true;
2283
+ }
2284
+ return false;
2285
+ }
2164
2286
 
2165
2287
  // src/workstream-control-event.ts
2166
2288
  var OPEN_WORKSTREAM_CONTROL_EVENT = "opengeni:open-workstream-control";
@@ -2633,7 +2755,7 @@ function CommandPalette({
2633
2755
  ] }),
2634
2756
  /* @__PURE__ */ jsxs("span", { className: "ml-auto flex items-center gap-1.5", children: [
2635
2757
  command.danger ? /* @__PURE__ */ jsx("span", { className: "rounded-og-xs bg-og-status-failed/15 px-1 text-[10px] uppercase tracking-wide text-og-status-failed", children: dangerLabel }) : null,
2636
- /* @__PURE__ */ jsx("span", { className: "truncate text-[12px] text-og-fg-subtle max-sm:hidden", children: command.description })
2758
+ /* @__PURE__ */ jsx("span", { className: "og-command-description truncate text-[12px] text-og-fg-subtle max-sm:hidden", children: command.description })
2637
2759
  ] })
2638
2760
  ]
2639
2761
  },
@@ -2720,10 +2842,10 @@ function ModelPicker({
2720
2842
  disabled: disabled === true,
2721
2843
  "aria-label": label,
2722
2844
  className: cn(
2723
- "h-8 max-w-[180px] cursor-pointer appearance-none truncate rounded-og-md bg-transparent pointer-coarse:h-11",
2845
+ "og-model-picker-native h-8 max-w-[180px] cursor-pointer appearance-none truncate rounded-og-md bg-transparent pointer-coarse:h-11",
2724
2846
  "py-0 pl-2 pr-6 text-[13px] text-og-fg-muted",
2725
2847
  "transition-colors duration-150 hover:bg-og-surface-2 hover:text-og-fg",
2726
- "focus:outline-none focus-visible:outline-none",
2848
+ "focus:outline-hidden focus-visible:outline-hidden",
2727
2849
  "disabled:cursor-not-allowed disabled:opacity-50"
2728
2850
  ),
2729
2851
  children: useBillingGroups ? billingGroups.map((group) => /* @__PURE__ */ jsx2("optgroup", { label: group.label, children: group.rows.map((row) => /* @__PURE__ */ jsx2("option", { value: row.id, disabled: !row.selectable, children: row.unavailableReason ? `${row.label} (${row.unavailableReason})` : row.label }, row.id)) }, group.billingClass)) : providerGroupList.map((group) => /* @__PURE__ */ jsx2("optgroup", { label: group.label, children: group.models.map((model) => /* @__PURE__ */ jsx2("option", { value: model.id, disabled: model.optionDisabled, children: model.label }, model.id)) }, group.label))
@@ -3224,21 +3346,27 @@ function useChatComposer() {
3224
3346
  function isRecord2(value) {
3225
3347
  return typeof value === "object" && value !== null;
3226
3348
  }
3227
- var Root = forwardRef(function ComposerRoot({ controller, children, className, style, ...props }, forwardedRef) {
3228
- return /* @__PURE__ */ jsx3(ComposerContext.Provider, { value: controller, children: /* @__PURE__ */ jsx3(TooltipProvider, { delayDuration: 300, children: /* @__PURE__ */ jsxs3(
3349
+ var Root = forwardRef(function ComposerRoot({ controller, children, className, style, responsiveBasis = "viewport", ...props }, forwardedRef) {
3350
+ const responsiveRootRef = useRef4(null);
3351
+ const responsiveContext = useMemo4(
3352
+ () => ({ responsiveBasis, rootRef: responsiveRootRef }),
3353
+ [responsiveBasis]
3354
+ );
3355
+ return /* @__PURE__ */ jsx3(ComposerContext.Provider, { value: controller, children: /* @__PURE__ */ jsx3(ComposerResponsiveContext.Provider, { value: responsiveContext, children: /* @__PURE__ */ jsx3(TooltipProvider, { delayDuration: 300, children: /* @__PURE__ */ jsxs3(
3229
3356
  "div",
3230
3357
  {
3231
3358
  ...props,
3232
- ref: mergeRefs(controller.rootRef, forwardedRef),
3359
+ ref: mergeRefs(controller.rootRef, responsiveRootRef, forwardedRef),
3233
3360
  "data-og-composer-id": controller.id,
3234
- className: cn("og-root", className),
3361
+ "data-og-responsive-basis": responsiveBasis,
3362
+ className: cn("og-root og-composer", className),
3235
3363
  style: { paddingBottom: "env(safe-area-inset-bottom)", ...style },
3236
3364
  children: [
3237
3365
  children,
3238
3366
  /* @__PURE__ */ jsx3(ComposerAnnouncements, {})
3239
3367
  ]
3240
3368
  }
3241
- ) }) });
3369
+ ) }) }) });
3242
3370
  });
3243
3371
  var Frame = forwardRef(function ComposerFrame({ className, ...props }, ref) {
3244
3372
  return /* @__PURE__ */ jsx3("div", { ...props, ref, className: cn("relative", className) });
@@ -3384,8 +3512,8 @@ var Input = forwardRef(function ComposerInput({ rows = 1, placeholder, className
3384
3512
  "aria-controls": paletteOpen ? controller.listboxId : void 0,
3385
3513
  "aria-activedescendant": paletteOpen ? `${controller.listboxId}-option-${controller.palette.highlight}` : void 0,
3386
3514
  className: cn(
3387
- "block w-full resize-none bg-transparent px-3.5 pt-3 pb-1 text-og-composer md:px-4 md:text-og-composer-wide pointer-coarse:min-h-11",
3388
- "text-og-fg placeholder:text-og-fg-subtle focus:outline-none focus-visible:outline-none",
3515
+ "og-composer-input block w-full resize-none bg-transparent px-3.5 pt-3 pb-1 text-og-composer md:px-4 md:text-og-composer-wide pointer-coarse:min-h-11",
3516
+ "text-og-fg placeholder:text-og-fg-subtle focus:outline-hidden focus-visible:outline-hidden",
3389
3517
  "disabled:cursor-not-allowed disabled:opacity-60",
3390
3518
  className
3391
3519
  )
@@ -3414,7 +3542,7 @@ var Footer = forwardRef(function ComposerFooter({ className, ...props }, ref) {
3414
3542
  ...props,
3415
3543
  ref,
3416
3544
  className: cn(
3417
- "flex items-end gap-1.5 px-2 pb-2 pt-0.5 sm:px-2.5 sm:pb-2.5",
3545
+ "og-composer-footer flex items-end gap-1.5 px-2 pb-2 pt-0.5 sm:px-2.5 sm:pb-2.5",
3418
3546
  // Mobile: one control row — never wrap into a second toolbar line.
3419
3547
  "max-sm:flex-nowrap max-sm:items-center max-sm:gap-1",
3420
3548
  className
@@ -3430,7 +3558,7 @@ var Controls = forwardRef(
3430
3558
  ...props,
3431
3559
  ref,
3432
3560
  className: cn(
3433
- "flex min-w-0 flex-1 flex-wrap items-center gap-1.5",
3561
+ "og-composer-controls flex min-w-0 flex-1 flex-wrap items-center gap-1.5",
3434
3562
  "max-sm:flex-nowrap max-sm:gap-1",
3435
3563
  className
3436
3564
  )
@@ -3445,7 +3573,10 @@ var Hint = forwardRef(function ComposerHint({ className, children, ...props }, r
3445
3573
  {
3446
3574
  ...props,
3447
3575
  ref,
3448
- className: cn("min-w-0 flex-1 px-1.5 text-og-xs text-og-fg-subtle max-sm:hidden", className),
3576
+ className: cn(
3577
+ "og-composer-hint min-w-0 flex-1 px-1.5 text-og-xs text-og-fg-subtle max-sm:hidden",
3578
+ className
3579
+ ),
3449
3580
  children: children ?? controller.messages.keyboardHint
3450
3581
  }
3451
3582
  );
@@ -3457,7 +3588,7 @@ var Actions = forwardRef(function ComposerActions({ className, ...props }, ref)
3457
3588
  ...props,
3458
3589
  ref,
3459
3590
  className: cn(
3460
- "ml-auto flex shrink-0 items-center gap-1.5",
3591
+ "og-composer-actions ml-auto flex shrink-0 items-center gap-1.5",
3461
3592
  "max-sm:flex-nowrap max-sm:gap-1",
3462
3593
  className
3463
3594
  )
@@ -3691,8 +3822,8 @@ function WorkstreamPausedStrip({
3691
3822
  onClick: onResume,
3692
3823
  children: [
3693
3824
  busy ? /* @__PURE__ */ jsx3(LoaderCircleIcon, { className: "size-3.5 animate-og-spin" }) : /* @__PURE__ */ jsx3(PlayIcon, { className: "size-3.5 fill-current" }),
3694
- /* @__PURE__ */ jsx3("span", { className: "hidden min-[400px]:inline", children: messages.resumeThisWorkstream }),
3695
- /* @__PURE__ */ jsx3("span", { className: "min-[400px]:hidden", children: messages.resumeShort })
3825
+ /* @__PURE__ */ jsx3("span", { className: "og-composer-resume-label-long hidden min-[400px]:inline", children: messages.resumeThisWorkstream }),
3826
+ /* @__PURE__ */ jsx3("span", { className: "og-composer-resume-label-short min-[400px]:hidden", children: messages.resumeShort })
3696
3827
  ]
3697
3828
  }
3698
3829
  ),
@@ -3718,7 +3849,7 @@ function WorkstreamPausedStrip({
3718
3849
  "a",
3719
3850
  {
3720
3851
  href: blockerHref(entry, controlLinks),
3721
- className: "font-medium text-og-fg underline decoration-og-border-strong underline-offset-2 hover:text-og-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-og-ring/40",
3852
+ className: "font-medium text-og-fg underline decoration-og-border-strong underline-offset-2 hover:text-og-accent focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-og-ring/40",
3722
3853
  children: entry.displayName
3723
3854
  }
3724
3855
  ) : /* @__PURE__ */ jsx3("span", { className: "font-medium text-og-fg", children: entry.displayName }),
@@ -3864,7 +3995,7 @@ function AttachmentChips({
3864
3995
  onRemove,
3865
3996
  onRetry
3866
3997
  }) {
3867
- return /* @__PURE__ */ jsx3("div", { className: "flex flex-wrap gap-2 border-b border-og-border px-3 py-2", children: attachments.map((attachment) => {
3998
+ return /* @__PURE__ */ jsx3("div", { className: "flex flex-wrap gap-2 px-3 py-2", children: attachments.map((attachment) => {
3868
3999
  const failed = attachment.status === "failed";
3869
4000
  const statusText = attachment.status === "uploading" ? messages.uploading : failed ? attachment.error || messages.uploadFailed : messages.formatBytes(attachment.sizeBytes);
3870
4001
  return /* @__PURE__ */ jsxs3(
@@ -3980,10 +4111,12 @@ var defaultMessages = {
3980
4111
  stop: "Stop and transcribe",
3981
4112
  cancel: "Cancel recording",
3982
4113
  retry: "Retry voice input",
4114
+ pauseRetrying: "Pause automatic retry",
3983
4115
  requestingPermission: "Requesting microphone\u2026",
3984
4116
  recording: "Recording. Press Escape to cancel.",
3985
4117
  saving: "Saving audio locally\u2026",
3986
4118
  transcribing: "Transcribing\u2026",
4119
+ retrying: "Recording saved. Retrying automatically\u2026",
3987
4120
  recovered: "Recording recovered and saved locally.",
3988
4121
  recoveredTranscript: "Transcript saved locally. Check your draft before inserting.",
3989
4122
  insertRecoveredTranscript: "Insert saved transcript",
@@ -4031,6 +4164,8 @@ function ComposerTranscriptionControl({
4031
4164
  createOwnerId
4032
4165
  });
4033
4166
  const { status } = transcription;
4167
+ const retrying = status === "retrying";
4168
+ const capturing = status === "requesting-permission" || status === "recording";
4034
4169
  const cancelTranscription = transcription.cancel;
4035
4170
  useEffect4(() => {
4036
4171
  if (!suppressed) return;
@@ -4038,13 +4173,13 @@ function ComposerTranscriptionControl({
4038
4173
  cancelTranscription();
4039
4174
  }
4040
4175
  }, [cancelTranscription, status, suppressed]);
4041
- const active = status === "requesting-permission" || status === "recording" || status === "saving" || status === "transcribing";
4042
- const recoverable = transcription.hasRecoverableRecording && (status === "recovered" || status === "transcript-ready" || status === "error");
4176
+ const active = capturing || status === "saving" || status === "transcribing";
4177
+ const recoverable = transcription.hasRecoverableRecording && (retrying || status === "recovered" || status === "transcript-ready" || status === "error");
4043
4178
  const savedTranscript = status === "transcript-ready" && transcription.savedTranscript !== null;
4044
4179
  const unavailableMessage = composer.disabled ? messages.unavailableDisabled : !capability?.available || !workspaceEnabled ? messages.unavailable : !transcription.available ? messages.errorStorageUnavailable : null;
4045
4180
  const idleLabel = unavailableMessage ?? (status === "error" ? messages.retry : messages.start);
4046
4181
  const errorMessage3 = transcription.error ? transcriptionErrorMessage(transcription.error, messages) : null;
4047
- const announcement = status === "requesting-permission" ? messages.requestingPermission : status === "recording" ? messages.recording : status === "saving" ? messages.saving : status === "transcribing" ? messages.transcribing : status === "recovered" ? messages.recovered : status === "transcript-ready" ? messages.recoveredTranscript : status === "error" ? errorMessage3 ?? messages.errorUnknown : unavailableMessage;
4182
+ const announcement = status === "requesting-permission" ? messages.requestingPermission : status === "recording" ? messages.recording : status === "saving" ? messages.saving : status === "transcribing" ? messages.transcribing : retrying ? messages.retrying : status === "recovered" ? messages.recovered : status === "transcript-ready" ? messages.recoveredTranscript : status === "error" ? errorMessage3 ?? messages.errorUnknown : unavailableMessage;
4048
4183
  function start(event) {
4049
4184
  if (unavailableMessage) {
4050
4185
  event.preventDefault();
@@ -4059,8 +4194,15 @@ function ComposerTranscriptionControl({
4059
4194
  animate: { opacity: 1, width: "auto" },
4060
4195
  exit: { opacity: 0, width: 0 },
4061
4196
  transition: { duration: 0.36, ease: [0.22, 1, 0.36, 1] },
4062
- className: cn("inline-flex min-w-0 overflow-hidden", className),
4197
+ className: cn(
4198
+ "inline-flex min-w-0 overflow-hidden",
4199
+ // Mobile capture mode reserves the footer for this control. Keep the
4200
+ // shell itself from shrinking and clipping its trailing actions.
4201
+ capturing && "shrink-0",
4202
+ className
4203
+ ),
4063
4204
  "data-transcription-status": status,
4205
+ "data-transcription-capturing": capturing ? "" : void 0,
4064
4206
  children: /* @__PURE__ */ jsxs4("span", { className: "inline-flex min-w-0 items-center gap-1.5", children: [
4065
4207
  /* @__PURE__ */ jsx4(AnimatePresence3, { mode: "popLayout", initial: false, children: recoverable ? /* @__PURE__ */ jsxs4(
4066
4208
  motion3.span,
@@ -4074,21 +4216,27 @@ function ComposerTranscriptionControl({
4074
4216
  "bg-og-surface-2/70 pl-2 pr-1 pointer-coarse:h-11"
4075
4217
  ),
4076
4218
  children: [
4077
- /* @__PURE__ */ jsx4("span", { className: "max-w-44 truncate text-og-xs text-og-fg-muted max-sm:max-w-28", children: savedTranscript ? errorMessage3 ?? messages.recoveredTranscript : status === "error" ? errorMessage3 ?? messages.errorRetryable : messages.recovered }),
4078
- /* @__PURE__ */ jsx4(Tip, { tip: savedTranscript ? messages.insertRecoveredTranscript : messages.retry, children: /* @__PURE__ */ jsx4(
4079
- "button",
4219
+ /* @__PURE__ */ jsx4("span", { className: "og-transcription-recovered-label max-w-44 truncate text-og-xs text-og-fg-muted max-sm:max-w-28", children: savedTranscript ? errorMessage3 ?? messages.recoveredTranscript : retrying ? messages.retrying : status === "error" ? errorMessage3 ?? messages.errorRetryable : messages.recovered }),
4220
+ /* @__PURE__ */ jsx4(
4221
+ Tip,
4080
4222
  {
4081
- type: "button",
4082
- onClick: () => savedTranscript ? void transcription.insertSavedTranscript() : transcription.retry(),
4083
- "aria-label": savedTranscript ? messages.insertRecoveredTranscript : messages.retry,
4084
- className: cn(
4085
- "inline-flex size-7 shrink-0 items-center justify-center rounded-og-sm",
4086
- "bg-og-fg text-og-bg transition-colors duration-150 motion-reduce:transition-none",
4087
- "hover:bg-og-fg-muted pointer-coarse:size-11"
4088
- ),
4089
- children: savedTranscript ? /* @__PURE__ */ jsx4(ClipboardPasteIcon, { className: "size-3.5" }) : /* @__PURE__ */ jsx4(RefreshCwIcon, { className: "size-3.5" })
4223
+ tip: savedTranscript ? messages.insertRecoveredTranscript : retrying ? messages.pauseRetrying : messages.retry,
4224
+ children: /* @__PURE__ */ jsx4(
4225
+ "button",
4226
+ {
4227
+ type: "button",
4228
+ onClick: () => savedTranscript ? void transcription.insertSavedTranscript() : retrying ? transcription.cancel() : transcription.retry(),
4229
+ "aria-label": savedTranscript ? messages.insertRecoveredTranscript : retrying ? messages.pauseRetrying : messages.retry,
4230
+ className: cn(
4231
+ "inline-flex size-7 shrink-0 items-center justify-center rounded-og-sm",
4232
+ "bg-og-fg text-og-bg transition-colors duration-150 motion-reduce:transition-none",
4233
+ "hover:bg-og-fg-muted pointer-coarse:size-11"
4234
+ ),
4235
+ children: savedTranscript ? /* @__PURE__ */ jsx4(ClipboardPasteIcon, { className: "size-3.5" }) : retrying ? /* @__PURE__ */ jsx4(SquareIcon, { className: "size-3.5" }) : /* @__PURE__ */ jsx4(RefreshCwIcon, { className: "size-3.5" })
4236
+ }
4237
+ )
4090
4238
  }
4091
- ) }),
4239
+ ),
4092
4240
  /* @__PURE__ */ jsx4(Tip, { tip: messages.discardRecovered, children: /* @__PURE__ */ jsx4(
4093
4241
  "button",
4094
4242
  {
@@ -4199,7 +4347,7 @@ function ComposerTranscriptionControl({
4199
4347
  "span",
4200
4348
  {
4201
4349
  "aria-hidden": "true",
4202
- className: "max-w-40 truncate text-og-xs text-og-status-failed max-sm:max-w-24",
4350
+ className: "og-transcription-error-label max-w-40 truncate text-og-xs text-og-status-failed max-sm:max-w-24",
4203
4351
  children: errorMessage3
4204
4352
  }
4205
4353
  ) }) : null,
@@ -4383,4 +4531,4 @@ export {
4383
4531
  Status,
4384
4532
  ComposerTranscriptionControl
4385
4533
  };
4386
- //# sourceMappingURL=chunk-3PB7MIT6.js.map
4534
+ //# sourceMappingURL=chunk-ROIRTM37.js.map