@opengeni/react 7.4.0 → 7.5.0-canary.36927100590001

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 (210) hide show
  1. package/README.md +124 -27
  2. package/dist/artifacts-document.js +3 -2
  3. package/dist/artifacts-presentation.js +3 -2
  4. package/dist/artifacts-spreadsheet.js +2 -2
  5. package/dist/artifacts.d.ts +1 -0
  6. package/dist/artifacts.js +516 -1413
  7. package/dist/artifacts.js.map +1 -1
  8. package/dist/{browser-viewer-2E6R2Y4W.js → browser-viewer-Z7S7QEJL.js} +6 -5
  9. package/dist/chat-interactive-block-UGBTNB3L.js +11 -0
  10. package/dist/{chunk-Y3QTZN2F.js → chunk-2VFNCX4E.js} +6 -6
  11. package/dist/{chunk-UDD6DLLT.js → chunk-3IJJEYW4.js} +15 -3
  12. package/dist/chunk-3IJJEYW4.js.map +1 -0
  13. package/dist/chunk-4RVYOY4O.js +379 -0
  14. package/dist/chunk-4RVYOY4O.js.map +1 -0
  15. package/dist/chunk-5CVXZA3Y.js +292 -0
  16. package/dist/chunk-5CVXZA3Y.js.map +1 -0
  17. package/dist/{chunk-5YK2ZDIG.js → chunk-5J4FOW6Q.js} +2 -10
  18. package/dist/chunk-5J4FOW6Q.js.map +1 -0
  19. package/dist/{chunk-KVERXCFY.js → chunk-5KYZIQFY.js} +40 -3
  20. package/dist/chunk-5KYZIQFY.js.map +1 -0
  21. package/dist/{chunk-KNDIXZN6.js → chunk-7UAMYXJY.js} +25 -18
  22. package/dist/{chunk-KNDIXZN6.js.map → chunk-7UAMYXJY.js.map} +1 -1
  23. package/dist/{chunk-SEEVCT36.js → chunk-A4UJB2MM.js} +2 -2
  24. package/dist/{chunk-X4HIN6TV.js → chunk-AFLPWUQ7.js} +71 -162
  25. package/dist/chunk-AFLPWUQ7.js.map +1 -0
  26. package/dist/chunk-B3V6TG77.js +41 -0
  27. package/dist/chunk-B3V6TG77.js.map +1 -0
  28. package/dist/{chunk-XEJEOAOV.js → chunk-B7WMS3CS.js} +51 -40
  29. package/dist/chunk-B7WMS3CS.js.map +1 -0
  30. package/dist/{chunk-S5JQ4R22.js → chunk-BDKR6BAR.js} +54 -24
  31. package/dist/chunk-BDKR6BAR.js.map +1 -0
  32. package/dist/{chunk-4MDLEHXL.js → chunk-DYWBUX5Q.js} +24 -12
  33. package/dist/chunk-DYWBUX5Q.js.map +1 -0
  34. package/dist/{chunk-YZ3YYMOM.js → chunk-E3G7SAYZ.js} +252 -624
  35. package/dist/chunk-E3G7SAYZ.js.map +1 -0
  36. package/dist/chunk-JT4JW7BC.js +54 -0
  37. package/dist/chunk-JT4JW7BC.js.map +1 -0
  38. package/dist/{chunk-5AZSK6MV.js → chunk-LWNLETQT.js} +5 -5
  39. package/dist/{chunk-USXVQACU.js → chunk-M7LBYP63.js} +5 -4
  40. package/dist/{chunk-USXVQACU.js.map → chunk-M7LBYP63.js.map} +1 -1
  41. package/dist/{chunk-L4OSXQ6H.js → chunk-NBOHNRLJ.js} +1289 -1060
  42. package/dist/chunk-NBOHNRLJ.js.map +1 -0
  43. package/dist/chunk-RHREZ7BO.js +11 -0
  44. package/dist/chunk-RHREZ7BO.js.map +1 -0
  45. package/dist/chunk-SCOTPE2I.js +589 -0
  46. package/dist/chunk-SCOTPE2I.js.map +1 -0
  47. package/dist/chunk-WEHMPOXK.js +39 -0
  48. package/dist/chunk-WEHMPOXK.js.map +1 -0
  49. package/dist/chunk-WRHIZYZF.js +988 -0
  50. package/dist/chunk-WRHIZYZF.js.map +1 -0
  51. package/dist/{chunk-3E2AITTZ.js → chunk-WUISZ3WU.js} +32 -28
  52. package/dist/{chunk-3E2AITTZ.js.map → chunk-WUISZ3WU.js.map} +1 -1
  53. package/dist/chunk-XCHWDJ22.js +107 -0
  54. package/dist/chunk-XCHWDJ22.js.map +1 -0
  55. package/dist/{chunk-DUEBTL3N.js → chunk-Y2PRMYLC.js} +4 -3
  56. package/dist/{chunk-DUEBTL3N.js.map → chunk-Y2PRMYLC.js.map} +1 -1
  57. package/dist/chunk-YBXQDQFX.js +1772 -0
  58. package/dist/chunk-YBXQDQFX.js.map +1 -0
  59. package/dist/chunk-YV4L3ILF.js +9 -0
  60. package/dist/chunk-YV4L3ILF.js.map +1 -0
  61. package/dist/{chunk-V2ABIVYJ.js → chunk-ZXSEDZP7.js} +70 -6
  62. package/dist/chunk-ZXSEDZP7.js.map +1 -0
  63. package/dist/components/artifacts/artifact-chrome.d.ts +120 -0
  64. package/dist/components/artifacts/artifact-sandbox.d.ts +27 -0
  65. package/dist/components/artifacts/chat-interactive-block.d.ts +29 -0
  66. package/dist/components/artifacts/deferred-chat-media.d.ts +15 -0
  67. package/dist/components/artifacts/editable-artifact-ui.d.ts +2 -1
  68. package/dist/components/artifacts/editable-artifact-view.d.ts +46 -0
  69. package/dist/components/artifacts/index.d.ts +7 -0
  70. package/dist/components/artifacts/latest-task-runner.d.ts +15 -0
  71. package/dist/components/artifacts/session-artifact-viewer.d.ts +39 -0
  72. package/dist/components/artifacts/site-view.d.ts +23 -0
  73. package/dist/components/browser-select-control.d.ts +3 -1
  74. package/dist/components/code-editor.d.ts +1 -4
  75. package/dist/components/desktop-viewer.d.ts +1 -1
  76. package/dist/components/message-timeline.d.ts +20 -3
  77. package/dist/components/open-geni-links.d.ts +16 -0
  78. package/dist/components/session-conversation.d.ts +20 -1
  79. package/dist/components/timeline-pill-geometry.d.ts +8 -0
  80. package/dist/components/timeline-pill-placement.d.ts +24 -0
  81. package/dist/components/usage-limit-notice.d.ts +49 -0
  82. package/dist/components/usage-member-list.d.ts +91 -0
  83. package/dist/components/usage-meter.d.ts +73 -0
  84. package/dist/composer.js +5 -5
  85. package/dist/{computer-viewer-WMJE6OA3.js → computer-viewer-KJWLH3GI.js} +7 -5
  86. package/dist/connect.js +7 -6
  87. package/dist/connect.js.map +1 -1
  88. package/dist/conversation-timeline.d.ts +1 -1
  89. package/dist/desktop.d.ts +7 -0
  90. package/dist/desktop.js +26 -0
  91. package/dist/desktop.js.map +1 -0
  92. package/dist/editor.d.ts +7 -0
  93. package/dist/editor.js +21 -0
  94. package/dist/editor.js.map +1 -0
  95. package/dist/hooks/latest-question.d.ts +1 -1
  96. package/dist/hooks/use-composer.d.ts +4 -0
  97. package/dist/hooks/use-desktop-stream.d.ts +1 -1
  98. package/dist/hooks/use-usage.d.ts +40 -0
  99. package/dist/index.d.ts +7 -2
  100. package/dist/index.js +460 -1386
  101. package/dist/index.js.map +1 -1
  102. package/dist/interaction.js +8 -6
  103. package/dist/interaction.js.map +1 -1
  104. package/dist/{latest-question-QB4EUCW5.js → latest-question-IS445HOW.js} +3 -3
  105. package/dist/lib/format.d.ts +6 -1
  106. package/dist/lib/workbench-peers.d.ts +36 -0
  107. package/dist/machines.js +2 -2
  108. package/dist/{markdown-table-layout-PFUEZ2U4.js → markdown-table-layout-QXSLK4BY.js} +37 -5
  109. package/dist/markdown-table-layout-QXSLK4BY.js.map +1 -0
  110. package/dist/{queue-surface-implementation-IM2HD3SK.js → queue-surface-implementation-2CAQAIHM.js} +2 -2
  111. package/dist/realtime.js +3 -3
  112. package/dist/{sandbox-files-PXPIZAFG.js → sandbox-files-AEJTWGT4.js} +8 -5
  113. package/dist/sandbox-files-AEJTWGT4.js.map +1 -0
  114. package/dist/session-ui.d.ts +9 -2
  115. package/dist/session-ui.js +39 -20
  116. package/dist/session-ui.js.map +1 -1
  117. package/dist/session.js +4 -4
  118. package/dist/sites.js +4 -289
  119. package/dist/sites.js.map +1 -1
  120. package/dist/terminal.d.ts +8 -0
  121. package/dist/terminal.js +31 -0
  122. package/dist/terminal.js.map +1 -0
  123. package/dist/timeline/allowance-exhausted-row.d.ts +24 -0
  124. package/dist/timeline/genie-loading.d.ts +3 -1
  125. package/dist/timeline/types.d.ts +8 -1
  126. package/dist/{timeline-annotation-selection-ODLVF4OI.js → timeline-annotation-selection-DMLMM2TX.js} +6 -1
  127. package/dist/timeline-annotation-selection-DMLMM2TX.js.map +1 -0
  128. package/dist/timeline-pill-geometry-Z23V243M.js +110 -0
  129. package/dist/timeline-pill-geometry-Z23V243M.js.map +1 -0
  130. package/dist/usage/allowance-copy.d.ts +25 -0
  131. package/dist/usage/summary.d.ts +35 -0
  132. package/dist/usage.d.ts +13 -0
  133. package/dist/usage.js +1073 -0
  134. package/dist/usage.js.map +1 -0
  135. package/package.json +19 -3
  136. package/src/artifacts.ts +37 -0
  137. package/src/components/artifacts/artifact-chrome.tsx +413 -0
  138. package/src/components/artifacts/artifact-sandbox.tsx +185 -0
  139. package/src/components/artifacts/chat-interactive-block.tsx +260 -0
  140. package/src/components/artifacts/deferred-chat-media.tsx +67 -0
  141. package/src/components/artifacts/editable-artifact-ui.tsx +3 -1
  142. package/src/components/artifacts/editable-artifact-view.tsx +187 -0
  143. package/src/components/artifacts/editable-artifact-workbench.tsx +5 -2
  144. package/src/components/artifacts/editable-document.tsx +34 -36
  145. package/src/components/artifacts/editable-presentation.tsx +21 -16
  146. package/src/components/artifacts/index.ts +41 -0
  147. package/src/components/artifacts/latest-task-runner.ts +49 -0
  148. package/src/components/artifacts/session-artifact-viewer.tsx +376 -0
  149. package/src/components/artifacts/site-view.tsx +116 -0
  150. package/src/components/browser-select-control.tsx +4 -1
  151. package/src/components/browser-viewer.tsx +81 -22
  152. package/src/components/code-editor.tsx +13 -16
  153. package/src/components/computer-viewer.tsx +51 -23
  154. package/src/components/desktop-viewer.tsx +1 -1
  155. package/src/components/markdown-table-layout.ts +49 -5
  156. package/src/components/markdown.tsx +5 -2
  157. package/src/components/message-timeline.tsx +557 -516
  158. package/src/components/open-geni-links.tsx +24 -0
  159. package/src/components/sandbox-terminal.tsx +48 -11
  160. package/src/components/session-chrome.tsx +22 -3
  161. package/src/components/session-conversation.tsx +195 -102
  162. package/src/components/timeline-annotation-selection.tsx +7 -0
  163. package/src/components/timeline-pill-geometry.ts +169 -0
  164. package/src/components/timeline-pill-placement.ts +99 -0
  165. package/src/components/usage-limit-notice.tsx +179 -0
  166. package/src/components/usage-member-list.tsx +792 -0
  167. package/src/components/usage-meter.tsx +382 -0
  168. package/src/conversation-timeline.ts +10 -2
  169. package/src/desktop.ts +24 -0
  170. package/src/editor.ts +13 -0
  171. package/src/hooks/use-available-models.ts +1 -1
  172. package/src/hooks/use-composer.ts +57 -2
  173. package/src/hooks/use-desktop-stream.ts +19 -28
  174. package/src/hooks/use-usage.ts +100 -0
  175. package/src/index.ts +22 -0
  176. package/src/lib/format.ts +32 -6
  177. package/src/lib/workbench-peers.ts +62 -0
  178. package/src/session-ui.ts +22 -0
  179. package/src/terminal.ts +26 -0
  180. package/src/timeline/activity-rail.tsx +5 -3
  181. package/src/timeline/allowance-exhausted-row.tsx +86 -0
  182. package/src/timeline/genie-loading.tsx +16 -6
  183. package/src/timeline/projection.ts +78 -4
  184. package/src/timeline/types.ts +8 -0
  185. package/src/usage/allowance-copy.ts +64 -0
  186. package/src/usage/summary.ts +93 -0
  187. package/src/usage.ts +50 -0
  188. package/styles/compiled.css +325 -0
  189. package/dist/chunk-4MDLEHXL.js.map +0 -1
  190. package/dist/chunk-5YK2ZDIG.js.map +0 -1
  191. package/dist/chunk-KVERXCFY.js.map +0 -1
  192. package/dist/chunk-L4OSXQ6H.js.map +0 -1
  193. package/dist/chunk-S5JQ4R22.js.map +0 -1
  194. package/dist/chunk-UDD6DLLT.js.map +0 -1
  195. package/dist/chunk-UGMKPUEM.js +0 -299
  196. package/dist/chunk-UGMKPUEM.js.map +0 -1
  197. package/dist/chunk-V2ABIVYJ.js.map +0 -1
  198. package/dist/chunk-X4HIN6TV.js.map +0 -1
  199. package/dist/chunk-XEJEOAOV.js.map +0 -1
  200. package/dist/chunk-YZ3YYMOM.js.map +0 -1
  201. package/dist/markdown-table-layout-PFUEZ2U4.js.map +0 -1
  202. package/dist/timeline-annotation-selection-ODLVF4OI.js.map +0 -1
  203. /package/dist/{browser-viewer-2E6R2Y4W.js.map → browser-viewer-Z7S7QEJL.js.map} +0 -0
  204. /package/dist/{computer-viewer-WMJE6OA3.js.map → chat-interactive-block-UGBTNB3L.js.map} +0 -0
  205. /package/dist/{chunk-Y3QTZN2F.js.map → chunk-2VFNCX4E.js.map} +0 -0
  206. /package/dist/{chunk-SEEVCT36.js.map → chunk-A4UJB2MM.js.map} +0 -0
  207. /package/dist/{chunk-5AZSK6MV.js.map → chunk-LWNLETQT.js.map} +0 -0
  208. /package/dist/{sandbox-files-PXPIZAFG.js.map → computer-viewer-KJWLH3GI.js.map} +0 -0
  209. /package/dist/{latest-question-QB4EUCW5.js.map → latest-question-IS445HOW.js.map} +0 -0
  210. /package/dist/{queue-surface-implementation-IM2HD3SK.js.map → queue-surface-implementation-2CAQAIHM.js.map} +0 -0
package/README.md CHANGED
@@ -115,6 +115,11 @@ separately. Pass `conversationProps` for message rendering and tool renderers,
115
115
  deployment enables uploads (`attachments={false}` opts out), pending tool
116
116
  approvals render Approve/Reject, and `toolRegistry` customizes tool rendering.
117
117
 
118
+ The root keeps all existing exports, including workbench components, but never
119
+ imports their optional peers. Conversation-only Next.js/Vite hosts do not need
120
+ terminal, desktop, editor, or diff packages. Hosts mounting those surfaces opt
121
+ in through the [per-surface setup entries](#optional-peer-dependencies).
122
+
118
123
  Highlighted diffs use the optional `@pierre/diffs` peer only after an explicit
119
124
  opt-in, so a host without it still builds with any bundler (Turbopack resolves
120
125
  every reachable `import()`). Hosts that install it call `enablePierreDiffs()`
@@ -639,13 +644,22 @@ returned ComputerSession must be the exact placement/window the browser uses.
639
644
  `onOpenComputer` then changes the host layout to that resource—it must not open a
640
645
  lookalike desktop. Closing either viewer never ends its durable resource.
641
646
 
647
+ If the chat's latest browser was lost or failed, the viewer names it and explains
648
+ why it is unavailable instead of showing the ordinary empty state. It offers the
649
+ existing new-browser controls without reopening the lost controller or selecting
650
+ another chat's browser. Explicitly closed browsers still use the empty state;
651
+ older failures do not replace a newer closed browser. This loss notice also takes
652
+ precedence over `renderEmpty`. Preview the deadline-loss case with
653
+ `browser.html?mode=mock&lost=1` (add `width=360&theme=light` for a narrow light dock).
654
+
642
655
  Native dropdown popups may not appear in page frames. With a controller that
643
656
  advertises focused input observations, clicking one opens its choices beside
644
657
  the click. Ordinary clicks use a bounded focus probe instead of a full page
645
658
  snapshot; only a focused native dropdown (or a child-frame focus hint) requests
646
- semantic options. **Choose option** remains an explicit fallback for older
647
- controllers and controls that cannot be identified automatically. Selection uses the
648
- normal browser action API. The viewer retains that
659
+ semantic options. Current controllers show no permanent **Choose option** button
660
+ over the page; older controllers retain that explicit fallback. **Alt+Down** opens
661
+ the focused dropdown and reads its options on either controller generation.
662
+ Selection uses the normal browser action API. The viewer retains that
649
663
  observation's target/document/frame fence. Private, oversized, or ambiguous
650
664
  choices remain unavailable; the page's keyboard controls still work. This
651
665
  fallback requires a controller with focused native-select metadata support and
@@ -906,6 +920,8 @@ intentional changes should regenerate those snapshots and review the diff.
906
920
  paragraphs, user bubbles, and nested or standalone Markdown keep their normal
907
921
  width; oversized tables retain table-only horizontal scrolling. No host prop
908
922
  or viewport-wide layout override is required.
923
+ Remeasurement during host rerenders or tail streaming does not temporarily
924
+ resize the live table or displace an unpinned history reader.
909
925
  With `onSandboxFile`, a valid `sandbox:<path>[:line]` application link becomes
910
926
  an in-session Open action. The callback receives the decoded path unchanged;
911
927
  the optional line is positive and 1-based. Invalid sandbox references render
@@ -967,12 +983,25 @@ earlier prose and activity in chronological order, not a fold of multiple turns.
967
983
  An already expanded or actively read view is preserved through settlement.
968
984
  Routine machine inputs get one compact reason per resumed turn. Normal tip-follow
969
985
  continues through long answers, and manual scrolling never auto-repins on new work.
970
- Expanded outer work headers stay reachable at the top of the timeline (below
971
- Latest question when shown) until their own details end; nested headers never stick.
972
-
973
- Wire the newest-question resolver when history can be unloaded:
974
-
975
- `SessionConversation` includes the readable-turn presentation and this wiring automatically.
986
+ Expanded outer work headers stay reachable at the top of the timeline until
987
+ their own details end; nested headers never stick. The contextual navigation
988
+ pill stays below the sticky-header strip and avoids interactive controls. If
989
+ no horizontal slot fits beside a toolbar, only the pill moves below it; the
990
+ timeline's size and scroll position do not change.
991
+
992
+ The single **Back to your message** button returns to the loaded user prompt
993
+ associated with the response or work being read: the latest prompt preceding
994
+ the viewport midpoint. It appears only when that prompt's start is more than
995
+ 24 px above the viewport and its entire body and attachments are out of view.
996
+ Clicking synchronously scrolls and focuses that exact
997
+ mounted prompt near the top and leaves tip-follow. Later messages and queued
998
+ prompts do not change the destination while the reader remains in older work.
999
+ An older bounded window uses its own loaded context; a window with no associated
1000
+ prompt shows no action. Navigation never replaces the history window or looks up
1001
+ the globally newest message. There are no previous/next arrows.
1002
+
1003
+ `SessionConversation` includes this behavior automatically. Custom timelines
1004
+ need no prompt-navigation callback:
976
1005
 
977
1006
  ```tsx
978
1007
  const events = useSessionEvents(sessionId);
@@ -982,28 +1011,32 @@ const events = useSessionEvents(sessionId);
982
1011
  turnSummary={{ rolling: true }}
983
1012
  hasNewer={events.hasNewer}
984
1013
  onJumpToLatest={events.jumpToLatest}
985
- onJumpToLatestQuestion={events.jumpToLatestQuestion}
986
1014
  />;
987
1015
  ```
988
1016
 
989
- The single **Latest question** button targets the newest durable user message,
990
- not the viewport-relative question or the newest message in an older loaded page.
991
- The resolver checks the authoritative queue and normally uses one filtered forensic
1017
+ `onJumpToLatest` retains its separate live-bottom behavior. The deprecated
1018
+ `MessageTimeline.onJumpToLatestQuestion` prop remains source-compatible but is
1019
+ not invoked by contextual navigation.
1020
+
1021
+ ### Optional global newest-message lookup
1022
+
1023
+ The public `useSessionEvents().jumpToLatestQuestion()` hook remains available for
1024
+ hosts that deliberately build a **separate** global lookup action. It is not wired
1025
+ to `MessageTimeline` or the first-party conversation's contextual button.
1026
+ The hook checks the authoritative queue and normally uses one filtered forensic
992
1027
  lookup plus, if needed, two bounded context reads. It pages past legacy worker
993
1028
  completions and withdrawn/cancelled-before-start prompts, never substituting an
994
1029
  arbitrary question from a loaded old page. Queued/legacy admission uses filtered
995
1030
  lifecycle evidence to locate its real turn start. A distant prompt is retained as
996
1031
  one projection-only witness in `events.timeline`; `events.events` remains the
997
1032
  bounded contiguous raw window, so pass `items` as above.
998
- The optional resolver loads on the first click, not when opening a session.
1033
+ The optional resolver loads on its first invocation, not when opening a session.
999
1034
  Identity and navigation guards also cover that module-loading delay.
1000
1035
 
1001
- `SessionConversation` also opens and focuses the newest pending prompt in
1002
- `SessionChrome`. Custom hosts can provide the same destination without changing
1003
- the existing `Promise<number | null>` timeline callback:
1036
+ Custom hosts can provide their own queue destination when invoking this hook:
1004
1037
 
1005
1038
  ```tsx
1006
- onJumpToLatestQuestion={() => events.jumpToLatestQuestion({
1039
+ const navigateToNewest = () => events.jumpToLatestQuestion({
1007
1040
  onQueuedQuestion: async (turn, navigation) => {
1008
1041
  await queue.refresh();
1009
1042
  if (!navigation.isCurrent()) return;
@@ -1013,21 +1046,19 @@ onJumpToLatestQuestion={() => events.jumpToLatestQuestion({
1013
1046
  requestId: (previous?.requestId ?? 0) + 1,
1014
1047
  }));
1015
1048
  },
1016
- })}
1049
+ });
1017
1050
  // Pass queueFocusTarget to SessionChrome; each new request opens/focuses once.
1018
1051
  ```
1019
1052
 
1020
1053
  A queue destination returns `null`, not an invisible transcript sequence. Without
1021
- `onQueuedQuestion`, a pending prompt produces explicit queue guidance in the
1022
- timeline; transitional queue state can be retried rather than silently no-oping.
1054
+ `onQueuedQuestion`, a pending prompt rejects with `LatestQuestionQueuedError`;
1055
+ the custom host can show guidance. Transitional queue state can be retried.
1023
1056
  Check `navigation.isCurrent()` after awaits and immediately before queue UI effects:
1024
1057
  an explicit history jump can supersede a queued lookup without changing the session.
1025
1058
  The shared projection predicate supplies execution evidence for older queued turns
1026
1059
  without `turn.started`, including tools, agent/sandbox activity, startup, recovery,
1027
1060
  and capacity events. Compact cursor coverage skips coalesced delta runs.
1028
- Without `onJumpToLatestQuestion`, local navigation is available only at the live history
1029
- window; the component never guesses from an older page. `onJumpToLatest` retains
1030
- its separate bottom-follow behavior. `groupTimeline(items)` retains classic
1061
+ `groupTimeline(items)` retains classic
1031
1062
  grouping; `{ readableTurns: true }` selects the new projection. The deprecated
1032
1063
  `foldExchanges` option aliases readable turns, not the removed cross-turn fold. See
1033
1064
  [`docs/design/genie-loading.md`](../../docs/design/genie-loading.md).
@@ -1114,11 +1145,46 @@ function Fleet({ sessionId }: { sessionId: string }) {
1114
1145
  See the [Connected Machines guide](../../docs/connected-machines.md) for the
1115
1146
  end-to-end embedder story (create-on-machine, discover, swap, enroll, revoke).
1116
1147
 
1148
+ ## Usage allowances (`@opengeni/react/usage`)
1149
+
1150
+ Show people where they stand against a workspace or member usage allowance.
1151
+ A separate subpath, so hosts that don't meter usage never load it.
1152
+
1153
+ - `useUsage({ workspaceId? })` — the signed-in person's own `/usage/me`
1154
+ (through `getMyUsage` or any client with `requestJson`) plus a summary of
1155
+ which limit binds first. `refreshKey` re-reads when work settles.
1156
+ - `UsageMeter` — "38% left · Resets Nov 1". Shares only; pass `formatAmount`
1157
+ for money, credits or plan multiples. `density="compact"` for menus,
1158
+ `"hero"` to lead a page.
1159
+ - `UsageLimitNotice` — the calm composer line: nothing while comfortable, a
1160
+ dismissible heads-up near the limit, then who can raise it and when it
1161
+ resets. `labels` rewords it; `action` adds your own "Upgrade" button.
1162
+ - `UsageMemberList` — the admin roster with a share-of-budget slider,
1163
+ optional fixed amounts, and a visible note when shares add up to more than
1164
+ the pool. Save rules through your backend in `onChangeRule`.
1165
+
1166
+ ```tsx
1167
+ import { UsageLimitNotice, UsageMeter } from "@opengeni/react/usage";
1168
+
1169
+ <UsageMeter workspaceId={workspaceId} />
1170
+ <SessionConversation
1171
+ sessionId={sessionId}
1172
+ composerProps={{ header: <UsageLimitNotice workspaceId={workspaceId} /> }}
1173
+ allowanceExhaustedLabels={{ memberRemedy: "Ask your team admin for more." }}
1174
+ />
1175
+ ```
1176
+
1177
+ The conversation's "usage limit reached" row is customized on
1178
+ `MessageTimeline`/`SessionConversation` with `allowanceExhaustedLabels` or
1179
+ replaced with `renderAllowanceExhausted`. See
1180
+ [usage allowances](../../docs/usage-allowances.md#react-components-and-the-console).
1181
+
1117
1182
  ## Optional peer dependencies
1118
1183
 
1119
- The chat/timeline surface has none. The sandbox workspace and diff surfaces pull
1120
- their heavy libraries from **optional** `peerDependencies`, so you install only
1121
- what the surfaces you mount need:
1184
+ The chat/timeline surface needs only the required React/React DOM peers. All
1185
+ existing root exports remain available without optional workbench peers, even
1186
+ when a bundler resolves every reachable dynamic import. Install and enable
1187
+ only the surfaces you mount, once in their client route or bootstrap:
1122
1188
 
1123
1189
  - Terminal (`SandboxTerminal`): `@xterm/xterm`, `@xterm/addon-fit`,
1124
1190
  `@xterm/addon-web-links`.
@@ -1128,6 +1194,37 @@ what the surfaces you mount need:
1128
1194
  language packs you need (`css`, `html`, `javascript`, `json`, `markdown`,
1129
1195
  `python`).
1130
1196
 
1197
+ ```ts
1198
+ import { enableSandboxTerminal } from "@opengeni/react/terminal";
1199
+ import { enableDesktopViewer } from "@opengeni/react/desktop";
1200
+ import { enableCodeEditor } from "@opengeni/react/editor";
1201
+
1202
+ enableSandboxTerminal();
1203
+ enableDesktopViewer();
1204
+ enableCodeEditor({
1205
+ javascript: async () =>
1206
+ (await import("@codemirror/lang-javascript")).javascript({ jsx: true, typescript: true }),
1207
+ });
1208
+ ```
1209
+
1210
+ Omit imports and calls for surfaces you do not use. These entries also re-export
1211
+ their components; root component imports continue to work after setup. The
1212
+ libraries load on mount, not during setup or SSR. Import the setup from a lazy
1213
+ route to keep its peer chunks outside the initial conversation graph.
1214
+
1215
+ For optional terminal WebGL acceleration, install `@xterm/addon-webgl` and call
1216
+ `enableSandboxTerminal({ webgl: () => import("@xterm/addon-webgl") })`. Without
1217
+ it, or if it fails, the terminal uses its DOM renderer. Only supply editor
1218
+ grammar loaders for packages you installed; absent/failed grammars use plain
1219
+ CodeMirror. Without editor setup, the existing textarea fallback remains usable.
1220
+ Without terminal/VNC setup, those surfaces show a setup error; relay-frame
1221
+ desktops and a custom `rfbFactory` need no noVNC setup.
1222
+
1223
+ Custom hosts may supply `registerSandboxTerminal`, `registerCodeEditor`, or
1224
+ `registerDesktopViewer` loaders from the root instead. Mounted fallbacks retry
1225
+ when registration changes. Do not hide peer imports behind runtime bare strings
1226
+ or `@vite-ignore`: browsers cannot resolve those without an import map.
1227
+
1131
1228
  ## Demo harness
1132
1229
 
1133
1230
  `bun run demo` (from this package) serves a harness that drives the real hooks
@@ -4,8 +4,9 @@ import {
4
4
  DocumentProjectionArtifactSurface,
5
5
  DocumentProjectionEditor,
6
6
  EditableDocumentArtifactSurface
7
- } from "./chunk-3E2AITTZ.js";
8
- import "./chunk-DUEBTL3N.js";
7
+ } from "./chunk-WUISZ3WU.js";
8
+ import "./chunk-WEHMPOXK.js";
9
+ import "./chunk-Y2PRMYLC.js";
9
10
  import "./chunk-22KP6LR5.js";
10
11
  export {
11
12
  DocumentArtifactSurface,
@@ -4,8 +4,9 @@ import {
4
4
  PresentationEditor,
5
5
  PresentationProjectionArtifactSurface,
6
6
  PresentationProjectionEditor
7
- } from "./chunk-KNDIXZN6.js";
8
- import "./chunk-DUEBTL3N.js";
7
+ } from "./chunk-7UAMYXJY.js";
8
+ import "./chunk-WEHMPOXK.js";
9
+ import "./chunk-Y2PRMYLC.js";
9
10
  import "./chunk-22KP6LR5.js";
10
11
  export {
11
12
  EditablePresentationArtifactSurface,
@@ -4,8 +4,8 @@ import {
4
4
  SpreadsheetArtifactSurface,
5
5
  SpreadsheetGrid,
6
6
  SpreadsheetProjectionGrid
7
- } from "./chunk-SEEVCT36.js";
8
- import "./chunk-DUEBTL3N.js";
7
+ } from "./chunk-A4UJB2MM.js";
8
+ import "./chunk-Y2PRMYLC.js";
9
9
  import "./chunk-22KP6LR5.js";
10
10
  export {
11
11
  EditableSpreadsheetArtifactSurface,
@@ -1,4 +1,5 @@
1
1
  export { inlineHtmlDocument } from "./components/artifacts/inline-html-document.js";
2
2
  export { isRetainedImageContentType, useRetainedImageObjectUrl } from "./timeline/retained-image.js";
3
+ export { ArtifactBadge, ArtifactLabelsProvider, DEFAULT_ARTIFACT_LABELS, useArtifactLabels, type ArtifactLabels, ArtifactButton, ArtifactLoading, ArtifactProblem, ArtifactSelect, ArtifactViewerHeader, artifactKindIcon, artifactKindSubtitle, artifactLoadErrorMessage, artifactLoadErrorView, type ArtifactKind, type ArtifactLoadErrorKind, type ArtifactLoadErrorView, ArtifactSandbox, type ArtifactSandboxProps, DeferredChatMedia, SiteView, type SiteViewProps, ChatInteractiveBlock, type ChatInteractiveBlockProps, type SiteSnapshotClient, type SiteToolBridgeFactory, type SiteToolScope, EditableArtifactView, type EditableArtifactRuntimes, type EditableArtifactViewProps, type OpenedEditableArtifact, SessionArtifactViewer, type SessionArtifactTarget, type SessionArtifactViewerLabels, type SessionArtifactViewerProps, } from "./components/artifacts/index.js";
3
4
  /** Public artifact surfaces. Import from `@opengeni/react/artifacts`. */
4
5
  export { ArtifactSurface, DocumentArtifactSurface, DocumentEditor, DocumentProjectionArtifactSurface, DocumentProjectionEditor, BrowserEditableArtifactWorkbench, EditableDocumentArtifactSurface, EditableArtifactWorkbench, EditableArtifactWorkbenchHost, EditablePresentationArtifactSurface, EditableSpreadsheetArtifactSurface, EditableSpreadsheetGrid, PresentationArtifactSurface, PresentationEditor, PresentationProjectionArtifactSurface, PresentationProjectionEditor, PublishedHtmlArtifactFrame, PUBLISHED_HTML_ARTIFACT_IFRAME_SANDBOX, openGeniSiteBridgePortFromBootstrap, publishedHtmlArtifactDocument, SpreadsheetArtifactSurface, SpreadsheetGrid, SpreadsheetProjectionGrid, type ArtifactModality, type ArtifactSurfaceProps, type DocumentArtifactSurfaceProps, type DocumentCommit, type DocumentCommitHandler, type DocumentEditorProps, type DocumentEditorProjection, type DocumentLayoutMode, type DocumentProjectionArtifactSurfaceProps, type DocumentProjectionBlock, type DocumentProjectionChange, type DocumentProjectionComment, type DocumentProjectionEditorProps, type DocumentProjectionPageBreak, type DocumentProjectionPageGeometry, type DocumentProjectionParagraph, type DocumentProjectionParagraphStyle, type DocumentProjectionSection, type DocumentProjectionTable, type DocumentProjectionTextRun, type DocumentProjectionTextStyle, type DocumentSelection, type BrowserEditableArtifactWorkbenchOptions, type BrowserEditableArtifactWorkbenchProps, type EditableDocumentArtifactSurfaceProps, type EditableArtifactWorkbenchHostProps, type EditableArtifactWorkbenchProps, type EditablePresentationArtifactSurfaceProps, type EditableSpreadsheetArtifactSurfaceProps, type EditableSpreadsheetGridProps, type PresentationArtifactSurfaceProps, type PresentationCommit, type PresentationCommitHandler, type PresentationEditorProps, type PresentationEditorProjection, type PresentationProjectionArtifactSurfaceProps, type PresentationProjectionChart, type PresentationProjectionChartSeries, type PresentationProjectionConnector, type PresentationProjectionEditorProps, type PublishedHtmlArtifactFrameProps, type PublishedHtmlArtifactToolBridge, type PresentationProjectionElementMetadata, type PresentationProjectionElement, type PresentationProjectionFill, type PresentationProjectionGroup, type PresentationProjectionImage, type PresentationProjectionLine, type PresentationProjectionPosition, type PresentationProjectionRichText, type PresentationProjectionShape, type PresentationProjectionTable, type PresentationProjectionTableCell, type PresentationProjectionTextParagraph, type PresentationProjectionTextRun, type PresentationProjectionTextStyle, type PresentationSlideProjection, type SpreadsheetArtifactSurfaceProps, type SpreadsheetCommit, type SpreadsheetRangeCommit, type SpreadsheetGridProps, type SpreadsheetGridProjection, type SpreadsheetProjectionCell, type SpreadsheetProjectionGridProps, type SpreadsheetSelection, type SpreadsheetViewport, } from "./components/artifacts/index.js";