@opengeni/react 0.5.0 → 0.6.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.
package/README.md CHANGED
@@ -3,7 +3,17 @@
3
3
  React hooks and styled components for OpenGeni, built on
4
4
  [`@opengeni/sdk`](../sdk): live session streaming, a chat composer, a message
5
5
  timeline that renders streaming deltas / tool calls / spawned-worker status,
6
- session status badges, and fleet tiles for workspace overviews.
6
+ session status badges, and fleet tiles for workspace overviews. Two opt-in
7
+ surfaces layer on top: a **sandbox-surfacing** workbench (files, terminal, diff,
8
+ and an optional desktop stream) and, at the
9
+ [`@opengeni/react/machines`](#connected-machines-opengenireactmachines) subpath,
10
+ the **Connected Machines** dashboard + enrollment flow.
11
+
12
+ The default root import (`@opengeni/react`) is the clean sandbox-agnostic
13
+ surface — the chat/timeline hooks and components plus the sandbox-surfacing
14
+ suite. Connected-Machine UI lives under the `@opengeni/react/machines` subpath so
15
+ consumers that never surface machines don't pull it in. (The root barrel still
16
+ re-exports the machines island for back-compat, deprecated per #144.)
7
17
 
8
18
  Design-system-first: every visual decision routes through CSS-variable tokens
9
19
  (`styles/tokens.css`) — color, typography, radius, shadow, motion. Dark mode is
@@ -90,7 +100,16 @@ export function App() {
90
100
  events.
91
101
  - `useSessionControl(sessionId)` — `interrupt(reason?)` and
92
102
  `approve`/`reject(approvalId, message?)` for `requires_action` approvals.
93
- - `useSession(sessionId)` — fetch one session (optional polling).
103
+ - `useSession(sessionId)` — fetch one session (optional polling) with
104
+ `updateTitle(title)` (rename) and live title-patching on `session.title_set`.
105
+ - `useFileAttachments()` — the composer's attach flow: stages files, drives the
106
+ SDK's direct-to-blob upload, and yields the `resources` to send with a message.
107
+ - `useAvailableModels()` — the deployment's provider-grouped selectable `models`
108
+ plus the `defaultModel` to preselect (from the client config) for a picker.
109
+ - `useCodexAccounts()` — connected Codex (ChatGPT) accounts, the active/next-run
110
+ pointer, and per-session account pinning for multi-account subscriptions.
111
+ - `useSlashCommands(...)` — the slash-command palette state (registry + parsing +
112
+ handlers) behind `CommandPalette`.
94
113
  - `useWorkspaceSessions()` / `useScheduledTasks()` — workspace lists for
95
114
  fleet/manager views (optional polling).
96
115
  - `useEnvironments()` — workspace environments with create/update/remove and
@@ -132,6 +151,94 @@ with the same semantics.
132
151
  `renderMessageText` to plug a markdown renderer.
133
152
  - `SessionStatus` / `StatusDot` — status badges; live states breathe.
134
153
  - `FleetTile` — one session in a fleet grid: title, status, model, recency.
154
+ - `ModelPicker` — a compact model dropdown for a composer slot, grouping the
155
+ host-exposed models by provider.
156
+ - `Markdown` — the timeline's markdown renderer (GFM), also usable standalone.
157
+ - `CommandPalette` — the slash-command palette UI over `useSlashCommands`.
158
+
159
+ The timeline is extensible: `createToolRegistry` / `defaultToolRegistry` plug
160
+ per-tool renderers, and the rendering primitives (`ActivityDisclosure`,
161
+ `ScreenshotFigure`, `TermBlock`, `LightboxProvider`, …) compose custom rows with
162
+ the same semantics.
163
+
164
+ ## Sandbox surfacing
165
+
166
+ An opt-in workbench that surfaces a session's live sandbox — files, terminal,
167
+ diff, and (when available) a desktop pixel stream — driven by a negotiated
168
+ capability document so every surface degrades to a reason instead of crashing.
169
+
170
+ - `useSessionCapabilities(sessionId, { attachDesktop?, attachTerminal?, attachFiles? })`
171
+ — negotiates the per-session capability doc, tracks lease liveness
172
+ (`cold`/`warming`/`warm`), and acquires the viewer holder(s) that keep the box
173
+ warm. Desktop attach is gated behind the un-redacted-pixel acknowledgment.
174
+ - `useSandboxFiles` / `useSandboxGit` — the Pierre file tree + git status/diff
175
+ feeds (the synchronous `fs*`/`git*` SDK point queries plus `fs.changed` /
176
+ `git.changed` live notifications).
177
+ - `useSandboxTerminal` / `useTerminalStream` — the read-only command-output
178
+ firehose and the real interactive PTY over the minted `pty-ws` cell.
179
+ - `useDesktopStream` — the noVNC socket, hot-swapped on box rollover via
180
+ `stream.url.rotated`.
181
+ - Components: `WorkspaceDock` (the resizable/collapsible right-hand dock),
182
+ `FileBrowser` / `SandboxFiles`, `DiffView` / `PierreDiff` / `PierreFile`,
183
+ `CodeEditor`, `SandboxTerminal`, and `DesktopViewer`.
184
+
185
+ These surfaces pull in [optional peer dependencies](#optional-peer-dependencies)
186
+ — install only the ones for surfaces you actually mount.
187
+
188
+ ## Connected Machines (`@opengeni/react/machines`)
189
+
190
+ Bring-your-own-compute UI: the Machines dashboard, per-machine metrics, the
191
+ active-sandbox swap, and the enrollment flow. Imported from the
192
+ `@opengeni/react/machines` subpath so consumers that never surface machines
193
+ never pull it in.
194
+
195
+ - `useMachines({ sessionId? })` — polls the fleet, exposes `attach(sandboxId)`
196
+ (wired to the SDK's active-sandbox swap when a `sessionId` is in scope),
197
+ `fetchSeries`, and the `activeSandboxId` / `activeEpoch` pointer.
198
+ - `MachinesDashboard` / `MachineCard` / `MachineMetrics` — the fleet grid with
199
+ per-machine meters and an attach/swap affordance.
200
+ - `MachineDockBar` / `SharedMachineDisclosure` — the backend-aware bar over the
201
+ sandbox dock naming which machine (Modal box or your machine) it is bound to.
202
+ - `EnrollmentDeviceFlow` — the in-session device-flow panel (`userCode` +
203
+ `verificationUri`, pending → authorized/denied/expired).
204
+ - `EnrollmentConsent` — the loud whole-machine approve page.
205
+ - `MachineStatusPill` / `ConnectionStatusPill` / `ConnectionDot` — status chips,
206
+ plus the `MachineView` / `MachineState` / `MetricSample` view-model types.
207
+
208
+ ```tsx
209
+ import { MachinesDashboard, useMachines } from "@opengeni/react/machines";
210
+
211
+ function Fleet({ sessionId }: { sessionId: string }) {
212
+ const { machines, activeSandboxId, attach, attachingSandboxId, refresh } =
213
+ useMachines({ sessionId, pollIntervalMs: 5000 });
214
+ return (
215
+ <MachinesDashboard
216
+ machines={machines}
217
+ activeSandboxId={activeSandboxId}
218
+ attachingSandboxId={attachingSandboxId}
219
+ onAttach={(m) => attach(m.sandboxId)}
220
+ onRefresh={refresh}
221
+ />
222
+ );
223
+ }
224
+ ```
225
+
226
+ See the [Connected Machines guide](../../docs/connected-machines.md) for the
227
+ end-to-end embedder story (create-on-machine, discover, swap, enroll, revoke).
228
+
229
+ ## Optional peer dependencies
230
+
231
+ The chat/timeline surface has none. The sandbox-surfacing and diff surfaces pull
232
+ their heavy libraries from **optional** `peerDependencies`, so you install only
233
+ what the surfaces you mount need:
234
+
235
+ - Terminal (`SandboxTerminal`): `@xterm/xterm`, `@xterm/addon-fit`,
236
+ `@xterm/addon-web-links`.
237
+ - Desktop (`DesktopViewer`): `@novnc/novnc`.
238
+ - Diff (`DiffView` / `PierreDiff` / `PierreFile`): `@pierre/diffs`.
239
+ - Code editor (`CodeEditor`): `@uiw/react-codemirror` + the `@codemirror/lang-*`
240
+ language packs you need (`css`, `html`, `javascript`, `json`, `markdown`,
241
+ `python`).
135
242
 
136
243
  ## Demo harness
137
244