@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
@@ -0,0 +1,84 @@
1
+ import type {
2
+ DraftTimelineAnnotation,
3
+ TimelineAnnotation,
4
+ TimelineAnnotationSource,
5
+ } from "@opengeni/sdk";
6
+ import { Suspense, lazy, useRef, useState } from "react";
7
+ import { cn } from "../lib/cn";
8
+
9
+ export type TimelineAnnotationLike = DraftTimelineAnnotation | TimelineAnnotation;
10
+
11
+ const TimelineAnnotationsDialog = lazy(() => import("./timeline-annotations-dialog"));
12
+
13
+ export function TimelineAnnotationsChip({
14
+ annotations,
15
+ editable = false,
16
+ focusAnnotationId,
17
+ onFocusConsumed,
18
+ onUpdate,
19
+ onRemove,
20
+ onRevealSource,
21
+ className,
22
+ }: {
23
+ annotations: readonly TimelineAnnotationLike[];
24
+ editable?: boolean | undefined;
25
+ focusAnnotationId?: string | null | undefined;
26
+ onFocusConsumed?: (() => void) | undefined;
27
+ onUpdate?: ((id: string, note: string) => void) | undefined;
28
+ onRemove?: ((id: string) => void) | undefined;
29
+ onRevealSource?: ((source: TimelineAnnotationSource) => boolean) | undefined;
30
+ className?: string | undefined;
31
+ }) {
32
+ const [open, setOpen] = useState(false);
33
+ const triggerRef = useRef<HTMLButtonElement | null>(null);
34
+
35
+ if (annotations.length === 0) return null;
36
+ const focusRequested = Boolean(
37
+ focusAnnotationId && annotations.some((item) => item.id === focusAnnotationId),
38
+ );
39
+ const visible = open || focusRequested;
40
+ const countLabel = `${annotations.length} ${annotations.length === 1 ? "annotation" : "annotations"}`;
41
+
42
+ return (
43
+ <>
44
+ <button
45
+ ref={triggerRef}
46
+ type="button"
47
+ className={cn(
48
+ "inline-flex min-h-8 items-center gap-1.5 rounded-full border border-og-border bg-og-surface-1 px-2.5 py-1 text-og-sm font-medium text-og-fg-muted outline-hidden transition hover:bg-og-surface-2 hover:text-og-fg focus-visible:ring-2 focus-visible:ring-og-accent pointer-coarse:min-h-[44px]",
49
+ className,
50
+ )}
51
+ aria-label={`Review ${countLabel}`}
52
+ aria-haspopup="dialog"
53
+ aria-expanded={visible}
54
+ onClick={() => setOpen((current) => !current)}
55
+ >
56
+ {countLabel}
57
+ </button>
58
+ {visible ? (
59
+ <Suspense fallback={null}>
60
+ <TimelineAnnotationsDialog
61
+ annotations={annotations}
62
+ editable={editable}
63
+ focusAnnotationId={focusAnnotationId}
64
+ onFocusConsumed={() => {
65
+ setOpen(true);
66
+ onFocusConsumed?.();
67
+ }}
68
+ onUpdate={onUpdate}
69
+ onRemove={onRemove}
70
+ onRevealSource={onRevealSource}
71
+ triggerRef={triggerRef}
72
+ countLabel={countLabel}
73
+ onDismiss={(restoreFocus) => {
74
+ setOpen(false);
75
+ if (restoreFocus) triggerRef.current?.focus();
76
+ }}
77
+ />
78
+ </Suspense>
79
+ ) : null}
80
+ </>
81
+ );
82
+ }
83
+
84
+ export default TimelineAnnotationsChip;
@@ -8,19 +8,17 @@
8
8
  * tips and look like a blank white bubble.
9
9
  */
10
10
  import { Tooltip as TooltipPrimitive } from "radix-ui";
11
- import {
12
- createContext,
13
- useContext,
14
- useRef,
15
- type ComponentProps,
16
- type CSSProperties,
17
- type RefObject,
18
- } from "react";
11
+ import { createContext, useContext, type ComponentProps, type CSSProperties } from "react";
19
12
 
20
13
  import { cn } from "../lib/cn";
21
- import { usePortalTokenStyle } from "../lib/use-portal-token-style";
14
+ import { usePortalTokenSource, usePortalTokenStyle } from "../lib/use-portal-token-style";
22
15
 
23
- const TooltipSourceContext = createContext<RefObject<HTMLElement | null> | null>(null);
16
+ type TooltipSourceContextValue = {
17
+ source: HTMLElement | null;
18
+ ref: (node: HTMLElement | null) => void;
19
+ };
20
+
21
+ const TooltipSourceContext = createContext<TooltipSourceContextValue | null>(null);
24
22
 
25
23
  function TooltipProvider({
26
24
  delayDuration = 300,
@@ -30,9 +28,9 @@ function TooltipProvider({
30
28
  }
31
29
 
32
30
  function Tooltip({ children, ...props }: ComponentProps<typeof TooltipPrimitive.Root>) {
33
- const sourceRef = useRef<HTMLElement | null>(null);
31
+ const source = usePortalTokenSource<HTMLElement>();
34
32
  return (
35
- <TooltipSourceContext.Provider value={sourceRef}>
33
+ <TooltipSourceContext.Provider value={source}>
36
34
  <TooltipPrimitive.Root data-slot="tooltip" {...props}>
37
35
  {children}
38
36
  </TooltipPrimitive.Root>
@@ -50,7 +48,7 @@ function TooltipTrigger({
50
48
  data-slot="tooltip-trigger"
51
49
  asChild={asChild}
52
50
  ref={(node) => {
53
- if (sourceRef) sourceRef.current = node;
51
+ sourceRef?.ref(node);
54
52
  }}
55
53
  {...props}
56
54
  />
@@ -69,9 +67,8 @@ function TooltipContent({
69
67
  style,
70
68
  ...props
71
69
  }: ComponentProps<typeof TooltipPrimitive.Content>) {
72
- const sourceRef = useContext(TooltipSourceContext);
73
- const fallbackRef = useRef<HTMLElement | null>(null);
74
- const portalStyle = usePortalTokenStyle(sourceRef ?? fallbackRef);
70
+ const source = useContext(TooltipSourceContext);
71
+ const portalStyle = usePortalTokenStyle(source?.source ?? null);
75
72
 
76
73
  return (
77
74
  <TooltipPrimitive.Portal>
@@ -330,7 +330,7 @@ export function UserMessageBody({ messageId, text, children, className }: UserMe
330
330
  aria-controls={contentId}
331
331
  aria-expanded={expanded}
332
332
  data-og-user-message-disclosure=""
333
- className="mt-1.5 inline-flex min-h-7 items-center rounded-og-sm px-1.5 text-og-xs font-medium text-og-fg-muted outline-none transition-colors hover:bg-og-surface-3/60 hover:text-og-fg focus-visible:ring-2 focus-visible:ring-og-accent/45 pointer-coarse:min-h-11"
333
+ className="mt-1.5 inline-flex min-h-7 items-center rounded-og-sm px-1.5 text-og-xs font-medium text-og-fg-muted outline-hidden transition-colors hover:bg-og-surface-3/60 hover:text-og-fg focus-visible:ring-2 focus-visible:ring-og-accent/45 pointer-coarse:min-h-11"
334
334
  onClick={(event) => toggle(event.currentTarget)}
335
335
  >
336
336
  {expanded ? "Show less" : "Show more"}
@@ -1,6 +1,7 @@
1
1
  import type { GitFileDiff } from "@opengeni/sdk";
2
2
  import { ArrowUpRightIcon, FileWarningIcon, HistoryIcon } from "lucide-react";
3
3
  import {
4
+ Component,
4
5
  type ReactNode,
5
6
  useCallback,
6
7
  useEffect,
@@ -10,7 +11,7 @@ import {
10
11
  useRef,
11
12
  useState,
12
13
  } from "react";
13
- import { VList } from "virtua";
14
+ import { VList, type VListHandle } from "virtua";
14
15
  import { cn } from "../lib/cn";
15
16
  import { useUnicodeFallbackFonts } from "../lib/use-unicode-fonts";
16
17
  import { useThemeType } from "../lib/use-theme-type";
@@ -96,6 +97,153 @@ type RailRow =
96
97
  | { kind: "group"; label: string; count: number }
97
98
  | { kind: "file"; file: SandboxGitFileDiff; index: number };
98
99
 
100
+ type ChangesRailVListProps = {
101
+ children: ReactNode;
102
+ className: string;
103
+ coarsePointer: boolean;
104
+ files: readonly SandboxGitFileDiff[];
105
+ rowCount: number;
106
+ };
107
+
108
+ type ChangesRailVListState = {
109
+ renderedRowCount: number;
110
+ resetVersion: number;
111
+ };
112
+
113
+ type ChangesRailSnapshot = {
114
+ focusedPath: string | null;
115
+ scrollOffset: number;
116
+ };
117
+
118
+ /** Virtua must reset its cached range when the rail shrinks. Keep that remount
119
+ * scoped to shrink transitions and preserve the reader's focus/scroll context. */
120
+ class ChangesRailVList extends Component<
121
+ ChangesRailVListProps,
122
+ ChangesRailVListState,
123
+ ChangesRailSnapshot | null
124
+ > {
125
+ state: ChangesRailVListState = {
126
+ renderedRowCount: this.props.rowCount,
127
+ resetVersion: 0,
128
+ };
129
+
130
+ private host: HTMLDivElement | null = null;
131
+ private listHandle: VListHandle | null = null;
132
+ private pendingFocusedPath: string | null = null;
133
+ private restoreFrame: number | null = null;
134
+
135
+ static getDerivedStateFromProps(
136
+ props: ChangesRailVListProps,
137
+ state: ChangesRailVListState,
138
+ ): ChangesRailVListState | null {
139
+ if (props.rowCount === state.renderedRowCount) return null;
140
+ return {
141
+ renderedRowCount: props.rowCount,
142
+ resetVersion:
143
+ props.rowCount < state.renderedRowCount ? state.resetVersion + 1 : state.resetVersion,
144
+ };
145
+ }
146
+
147
+ getSnapshotBeforeUpdate(
148
+ _previousProps: ChangesRailVListProps,
149
+ previousState: ChangesRailVListState,
150
+ ): ChangesRailSnapshot | null {
151
+ if (previousState.resetVersion === this.state.resetVersion) return null;
152
+ const scroller = this.host?.firstElementChild;
153
+ if (!(scroller instanceof HTMLElement)) return null;
154
+ const active = document.activeElement;
155
+ const focusedRow =
156
+ active instanceof HTMLElement && scroller.contains(active)
157
+ ? active.closest<HTMLElement>("[data-rail-file-path]")
158
+ : null;
159
+ return {
160
+ focusedPath: focusedRow?.dataset.railFilePath ?? this.pendingFocusedPath,
161
+ scrollOffset: scroller.scrollTop,
162
+ };
163
+ }
164
+
165
+ componentDidUpdate(
166
+ _previousProps: ChangesRailVListProps,
167
+ _previousState: ChangesRailVListState,
168
+ snapshot: ChangesRailSnapshot | null,
169
+ ): void {
170
+ if (!snapshot || !this.listHandle) return;
171
+ this.cancelRestoreFrame();
172
+ const maxOffset = Math.max(0, this.listHandle.scrollSize - this.listHandle.viewportSize);
173
+ this.listHandle.scrollTo(Math.min(Math.max(snapshot.scrollOffset, 0), maxOffset));
174
+ const focusedPath = snapshot.focusedPath;
175
+ if (!focusedPath) return;
176
+ this.pendingFocusedPath = focusedPath;
177
+ this.continueFocusRestore();
178
+ }
179
+
180
+ componentWillUnmount(): void {
181
+ this.cancelRestoreFrame();
182
+ this.pendingFocusedPath = null;
183
+ }
184
+
185
+ private cancelRestoreFrame(): void {
186
+ if (this.restoreFrame === null) return;
187
+ if (typeof cancelAnimationFrame === "function") cancelAnimationFrame(this.restoreFrame);
188
+ this.restoreFrame = null;
189
+ }
190
+
191
+ private continueFocusRestore = (): void => {
192
+ const path = this.pendingFocusedPath;
193
+ if (!path) return;
194
+ if (this.restoreFocusedPath(path)) {
195
+ this.pendingFocusedPath = null;
196
+ return;
197
+ }
198
+ if (this.restoreFrame === null && typeof requestAnimationFrame === "function") {
199
+ this.restoreFrame = requestAnimationFrame(() => {
200
+ this.restoreFrame = null;
201
+ this.continueFocusRestore();
202
+ });
203
+ }
204
+ };
205
+
206
+ private restoreFocusedPath(path: string): boolean {
207
+ const host = this.host;
208
+ if (!host) return true;
209
+ const active = document.activeElement;
210
+ if (active instanceof HTMLElement && active.isConnected && active !== document.body) {
211
+ return true;
212
+ }
213
+ if (!this.props.files.some((file) => file.path === path)) return true;
214
+ const row = Array.from(host.querySelectorAll<HTMLButtonElement>("[data-rail-file-path]")).find(
215
+ (candidate) => candidate.dataset.railFilePath === path,
216
+ );
217
+ if (!row) return false;
218
+ row.focus({ preventScroll: true });
219
+ return true;
220
+ }
221
+
222
+ private setHost = (host: HTMLDivElement | null): void => {
223
+ this.host = host;
224
+ };
225
+
226
+ private setListHandle = (handle: VListHandle | null): void => {
227
+ this.listHandle = handle;
228
+ };
229
+
230
+ render() {
231
+ return (
232
+ <div ref={this.setHost} data-opengeni-changes-rail className={this.props.className}>
233
+ <VList
234
+ key={this.state.resetVersion}
235
+ ref={this.setListHandle}
236
+ className="h-full"
237
+ itemSize={this.props.coarsePointer ? 44 : 28}
238
+ ssrCount={Math.min(30, this.props.rowCount)}
239
+ >
240
+ {this.props.children}
241
+ </VList>
242
+ </div>
243
+ );
244
+ }
245
+ }
246
+
99
247
  /** Order the files and build the rail rows (grouped past the threshold). The
100
248
  * returned `orderedFiles` drives BOTH the rail and the diff pane so a rail row's
101
249
  * `index` addresses the matching pane section. Exported for tests. */
@@ -321,7 +469,7 @@ export function WorkbenchChanges({
321
469
  }}
322
470
  title={activeFile?.path}
323
471
  data-compact-file-picker
324
- className="h-11 w-full rounded-og-md border border-og-border bg-og-bg px-3 font-og-mono text-og-sm text-og-fg outline-none transition-colors focus:border-og-accent focus:ring-2 focus:ring-og-accent-soft"
472
+ className="h-11 w-full rounded-og-md border border-og-border bg-og-bg px-3 font-og-mono text-og-sm text-og-fg outline-hidden transition-colors focus:border-og-accent focus:ring-2 focus:ring-og-accent-soft"
325
473
  >
326
474
  {orderedFiles.map((file, index) => (
327
475
  <option key={file.path} value={index}>
@@ -330,7 +478,13 @@ export function WorkbenchChanges({
330
478
  ))}
331
479
  </select>
332
480
  </div>
333
- <div className="min-h-0 min-w-0 flex-1 overflow-auto" data-opengeni-changes-pane>
481
+ <div
482
+ aria-label="Changed file diff"
483
+ className="min-h-0 min-w-0 flex-1 overflow-auto outline-hidden focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-og-accent"
484
+ data-opengeni-changes-pane
485
+ role="region"
486
+ tabIndex={0}
487
+ >
334
488
  {activeFile ? (
335
489
  <DiffSection
336
490
  file={activeFile}
@@ -344,42 +498,44 @@ export function WorkbenchChanges({
344
498
  ) : (
345
499
  <div className="flex min-h-0 flex-1">
346
500
  {/* File rail — virtualized (virtua): a dense change set is fine. */}
347
- <div className="w-[clamp(12rem,28%,15rem)] shrink-0 border-r border-og-border bg-og-surface-1/35">
348
- <VList
349
- className="h-full"
350
- itemSize={coarsePointer ? 44 : 28}
351
- ssrCount={Math.min(30, rows.length)}
352
- >
353
- {rows.map((row) =>
354
- row.kind === "group" ? (
355
- <div
356
- key={`g:${row.label}`}
357
- data-rail-group
358
- className="flex items-center gap-1.5 px-2 pb-0.5 pt-2 text-og-xs font-medium uppercase tracking-wide text-og-fg-subtle"
359
- >
360
- <span className="min-w-0 truncate">{row.label}</span>
361
- <span className="shrink-0">{row.count}</span>
362
- </div>
363
- ) : (
364
- <RailFileRow
365
- key={row.file.path}
366
- file={row.file}
367
- grouped={grouped}
368
- active={row.index === activeIndex}
369
- onClick={() => jumpTo(row.index)}
370
- />
371
- ),
372
- )}
373
- </VList>
374
- </div>
501
+ <ChangesRailVList
502
+ rowCount={rows.length}
503
+ coarsePointer={coarsePointer}
504
+ files={orderedFiles}
505
+ className="w-[clamp(12rem,28%,15rem)] shrink-0 border-r border-og-border bg-og-surface-1/35"
506
+ >
507
+ {rows.map((row) =>
508
+ row.kind === "group" ? (
509
+ <div
510
+ key={`g:${row.label}`}
511
+ data-rail-group
512
+ className="flex items-center gap-1.5 px-2 pb-0.5 pt-2 text-og-xs font-medium uppercase tracking-wide text-og-fg-subtle"
513
+ >
514
+ <span className="min-w-0 truncate">{row.label}</span>
515
+ <span className="shrink-0">{row.count}</span>
516
+ </div>
517
+ ) : (
518
+ <RailFileRow
519
+ key={row.file.path}
520
+ file={row.file}
521
+ grouped={grouped}
522
+ active={row.index === activeIndex}
523
+ onClick={() => jumpTo(row.index)}
524
+ />
525
+ ),
526
+ )}
527
+ </ChangesRailVList>
375
528
 
376
529
  {/* Diff pane — windowed file sections. Only the sections inside the
377
530
  visible window ± overscan are in the DOM; the container reserves the
378
531
  full scroll height so scrolling + the rail-jump stay accurate. */}
379
532
  <div
380
533
  ref={windowed.scrollRef}
381
- className="min-h-0 min-w-0 flex-1 overflow-auto"
534
+ aria-label="Changed files diff"
535
+ className="min-h-0 min-w-0 flex-1 overflow-auto outline-hidden focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-og-accent"
382
536
  data-opengeni-changes-pane
537
+ role="region"
538
+ tabIndex={0}
383
539
  >
384
540
  <div style={{ position: "relative", height: windowed.totalHeight }}>
385
541
  {orderedFiles.map((file, index) => {
@@ -479,8 +635,9 @@ function RailFileRow({
479
635
  onClick={onClick}
480
636
  title={file.path}
481
637
  data-rail-file
638
+ data-rail-file-path={file.path}
482
639
  className={cn(
483
- "relative flex min-h-7 w-full items-center gap-1.5 truncate px-2 py-0.5 text-left text-og-sm transition-colors hover:bg-og-surface-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-og-accent pointer-coarse:min-h-11",
640
+ "relative flex min-h-7 w-full items-center gap-1.5 truncate px-2 py-0.5 text-left text-og-sm transition-colors hover:bg-og-surface-2 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-og-accent pointer-coarse:min-h-11",
484
641
  grouped && "pl-3",
485
642
  active &&
486
643
  "bg-og-accent-soft text-og-fg before:absolute before:inset-y-1 before:left-0 before:w-0.5 before:rounded-r-full before:bg-og-accent",
@@ -597,7 +754,7 @@ function GuardBody({
597
754
  <button
598
755
  type="button"
599
756
  onClick={() => onOpenFile(file.path)}
600
- className="inline-flex min-h-8 shrink-0 items-center gap-1.5 rounded-og-sm border border-og-border px-2 py-1 text-og-xs font-medium text-og-fg-muted transition-colors hover:border-og-border-strong hover:bg-og-surface-2 hover:text-og-fg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-og-accent pointer-coarse:min-h-11"
757
+ className="inline-flex min-h-8 shrink-0 items-center gap-1.5 rounded-og-sm border border-og-border px-2 py-1 text-og-xs font-medium text-og-fg-muted transition-colors hover:border-og-border-strong hover:bg-og-surface-2 hover:text-og-fg focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent pointer-coarse:min-h-11"
601
758
  >
602
759
  Open in Files
603
760
  <ArrowUpRightIcon className="size-3.5" aria-hidden />
@@ -622,7 +779,7 @@ function LayoutToggle({
622
779
  type="button"
623
780
  onClick={() => onChange(value)}
624
781
  className={cn(
625
- "min-h-7 rounded-og-xs px-1.5 py-0.5 text-og-xs capitalize focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-og-accent max-[1023px]:min-w-11 pointer-coarse:min-h-11 pointer-coarse:min-w-11",
782
+ "min-h-7 rounded-og-xs px-1.5 py-0.5 text-og-xs capitalize focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent max-[1023px]:min-w-11 pointer-coarse:min-h-11 pointer-coarse:min-w-11",
626
783
  layout === value
627
784
  ? "bg-og-accent-soft text-og-fg"
628
785
  : "text-og-fg-subtle hover:text-og-fg",
@@ -44,6 +44,8 @@ export type WorkspaceDockProps = {
44
44
  /** Controlled collapsed state for hosts that expose their own dock toggle. */
45
45
  collapsed?: boolean | undefined;
46
46
  onCollapsedChange?: ((collapsed: boolean) => void) | undefined;
47
+ /** Keep the built-in collapse control when the host controls collapsed state. */
48
+ showCollapseControl?: boolean | undefined;
47
49
  /** A status accessory pinned to the right of the tab strip, left of the
48
50
  * maximize/collapse controls (e.g. the machine-state chip). Renders in both
49
51
  * the docked header and the full-screen overlay header. */
@@ -129,6 +131,7 @@ export function WorkspaceDock({
129
131
  onActiveTabChange,
130
132
  collapsed: collapsedProp,
131
133
  onCollapsedChange,
134
+ showCollapseControl = false,
132
135
  headerAccessory,
133
136
  mobileLeadingControl,
134
137
  autoSaveId = "og.session.dock",
@@ -343,6 +346,11 @@ export function WorkspaceDock({
343
346
  className="fixed inset-0 z-40 flex flex-col bg-og-bg"
344
347
  hidden={collapsed}
345
348
  style={{
349
+ // Author utility classes can override the user-agent `[hidden]`
350
+ // rule (for example this surface's `flex` class). Keep an inline
351
+ // display guard so a collapsed mobile workspace is actually gone
352
+ // visually as well as from the accessibility tree.
353
+ display: collapsed ? "none" : undefined,
346
354
  paddingTop: "env(safe-area-inset-top)",
347
355
  paddingBottom: "env(safe-area-inset-bottom)",
348
356
  }}
@@ -367,7 +375,7 @@ export function WorkspaceDock({
367
375
  onClick={expand}
368
376
  title="Open workspace"
369
377
  aria-label="Open workspace"
370
- className="absolute right-3 top-3 z-30 inline-flex size-11 items-center justify-center rounded-og-md border border-og-border bg-og-surface-1 text-og-fg-muted shadow-lg transition-colors hover:border-og-border-strong hover:text-og-fg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-og-accent"
378
+ className="absolute right-3 top-3 z-30 inline-flex size-11 items-center justify-center rounded-og-md border border-og-border bg-og-surface-1 text-og-fg-muted shadow-lg transition-colors hover:border-og-border-strong hover:text-og-fg focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent"
371
379
  style={{ marginTop: "env(safe-area-inset-top)" }}
372
380
  >
373
381
  <ChevronsLeftRightIcon className="size-4" aria-hidden />
@@ -396,7 +404,7 @@ export function WorkspaceDock({
396
404
  <Maximize2Icon className="size-3.5" />
397
405
  )}
398
406
  </ChromeButton>
399
- {hostControlled ? null : (
407
+ {hostControlled && !showCollapseControl ? null : (
400
408
  <ChromeButton onClick={collapse} title="Collapse" label="Collapse dock">
401
409
  <PanelRightCloseIcon className="size-3.5" />
402
410
  </ChromeButton>
@@ -426,7 +434,7 @@ export function WorkspaceDock({
426
434
  </Panel>
427
435
 
428
436
  {!collapsed && (
429
- <Separator className="group relative z-10 w-1.5 shrink-0 outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-og-accent max-[1023px]:-mx-[19px] max-[1023px]:w-11 pointer-coarse:-mx-[19px] pointer-coarse:w-11">
437
+ <Separator className="group relative z-10 w-1.5 shrink-0 outline-hidden focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-og-accent max-[1023px]:-mx-[19px] max-[1023px]:w-11 pointer-coarse:-mx-[19px] pointer-coarse:w-11">
430
438
  <span className="absolute inset-y-0 left-1/2 w-px -translate-x-1/2 bg-og-border transition-colors group-hover:bg-og-accent group-focus-visible:bg-og-accent group-data-[separator-state=dragging]:bg-og-accent" />
431
439
  </Separator>
432
440
  )}
@@ -503,7 +511,7 @@ function ChromeButton({
503
511
  onClick={onClick}
504
512
  title={title}
505
513
  aria-label={label}
506
- className="inline-flex size-7 items-center justify-center rounded-og-sm p-1 transition-colors hover:bg-og-surface-2 hover:text-og-fg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-og-accent max-[1023px]:size-11 pointer-coarse:size-11"
514
+ className="inline-flex size-7 items-center justify-center rounded-og-sm p-1 transition-colors hover:bg-og-surface-2 hover:text-og-fg focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent max-[1023px]:size-11 pointer-coarse:size-11"
507
515
  >
508
516
  {children}
509
517
  </button>
@@ -664,7 +672,7 @@ function DockChrome({
664
672
  onClick={() => onTab(tab.id)}
665
673
  onKeyDown={(event) => onTabKeyDown(event, index)}
666
674
  className={cn(
667
- "flex min-h-7 shrink-0 items-center justify-center gap-1 rounded-og-sm px-2 py-1 text-og-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-og-accent max-[1023px]:min-h-11 max-[1023px]:min-w-11 pointer-coarse:min-h-11 pointer-coarse:min-w-11",
675
+ "flex min-h-7 shrink-0 items-center justify-center gap-1 rounded-og-sm px-2 py-1 text-og-xs font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent max-[1023px]:min-h-11 max-[1023px]:min-w-11 pointer-coarse:min-h-11 pointer-coarse:min-w-11",
668
676
  tab.id === current
669
677
  ? "bg-og-accent-soft text-og-fg"
670
678
  : "text-og-fg-subtle hover:text-og-fg",
package/src/composer.ts CHANGED
@@ -64,6 +64,7 @@ export type {
64
64
  ComposerSubmitBlocker,
65
65
  ComposerSubmitMode,
66
66
  ComposerSurfaceProps,
67
+ ResponsiveBasis,
67
68
  UseChatComposerControllerOptions,
68
69
  } from "./components/composer";
69
70
  export { ComposerTranscriptionControl } from "./components/composer-transcription-control";
@@ -101,7 +102,9 @@ export type {
101
102
  VoiceRecordingChunk,
102
103
  VoiceRecordingChunkUploadState,
103
104
  VoiceRecordingFinalizationState,
105
+ VoiceRecordingHandoffMode,
104
106
  VoiceRecordingManifest,
107
+ VoiceRecordingRecoveryMode,
105
108
  VoiceRecordingStore,
106
109
  VoiceRecordingTranscriptionState,
107
110
  VoiceRecordingUploadState,