@opengeni/react 0.3.1 → 0.4.0

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 (40) hide show
  1. package/dist/index.d.ts +1035 -14
  2. package/dist/index.js +6867 -1884
  3. package/dist/index.js.map +1 -1
  4. package/package.json +65 -2
  5. package/src/client.ts +21 -0
  6. package/src/components/code-editor.tsx +398 -0
  7. package/src/components/desktop-viewer.tsx +647 -0
  8. package/src/components/diff-view.tsx +230 -0
  9. package/src/components/file-browser.tsx +838 -0
  10. package/src/components/message-timeline.tsx +70 -196
  11. package/src/components/pierre-diff.tsx +140 -0
  12. package/src/components/pierre-file.tsx +142 -0
  13. package/src/components/sandbox-files.tsx +509 -0
  14. package/src/components/sandbox-terminal.tsx +425 -0
  15. package/src/components/workspace-dock.tsx +247 -0
  16. package/src/hooks/use-desktop-stream.ts +214 -0
  17. package/src/hooks/use-sandbox-files.ts +670 -0
  18. package/src/hooks/use-sandbox-git.ts +105 -0
  19. package/src/hooks/use-sandbox-terminal.ts +226 -0
  20. package/src/hooks/use-session-capabilities.ts +415 -0
  21. package/src/hooks/use-terminal-stream.ts +207 -0
  22. package/src/index.ts +111 -2
  23. package/src/lib/cn.ts +20 -1
  24. package/src/lib/git-patch.ts +37 -0
  25. package/src/lib/use-theme-type.ts +40 -0
  26. package/src/lib/xterm-theme.ts +34 -0
  27. package/src/timeline/activity-rail.tsx +207 -0
  28. package/src/timeline/disclosure-context.tsx +34 -0
  29. package/src/timeline/index.ts +85 -0
  30. package/src/timeline/parsers.ts +248 -0
  31. package/src/{timeline.ts → timeline/projection.ts} +59 -134
  32. package/src/timeline/registry.ts +96 -0
  33. package/src/timeline/screenshot-lightbox.tsx +152 -0
  34. package/src/timeline/shared.tsx +481 -0
  35. package/src/timeline/tool-diff.tsx +91 -0
  36. package/src/timeline/tool-renderers.tsx +882 -0
  37. package/src/timeline/turn-summary.tsx +125 -0
  38. package/src/timeline/types.ts +131 -0
  39. package/src/types/external.d.ts +7 -0
  40. package/styles/index.css +72 -0
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { OpenGeniClient, Session, ResourceRef, ToolRef, SessionStatus as SessionStatus$1, SessionEvent, StreamConnectionState, SendMessageInput, FileAsset, FileResourceRef, SessionTurn, UpdateSessionTurnRequest, SessionGoal, ScheduledTask, WorkspaceEnvironment, CreateWorkspaceEnvironmentRequest, UpdateWorkspaceEnvironmentRequest, WorkspaceEnvironmentVariableMetadata, CapabilityPack, PackInstallation, RegisterCapabilityPackRequest, WorkspaceRegisteredPack, EnablePackRequest, Workspace, CreateWorkspaceRequest, UpdateWorkspaceRequest, BillingBalance, UsageEvent, ClientModel, Permission } from '@opengeni/sdk';
1
+ import { OpenGeniClient, Session, ResourceRef, ToolRef, SessionStatus as SessionStatus$1, SessionEvent, GitFileDiff, StreamConnectionState, SendMessageInput, FileAsset, FileResourceRef, SessionTurn, UpdateSessionTurnRequest, SessionGoal, ScheduledTask, WorkspaceEnvironment, CreateWorkspaceEnvironmentRequest, UpdateWorkspaceEnvironmentRequest, WorkspaceEnvironmentVariableMetadata, CapabilityPack, PackInstallation, RegisterCapabilityPackRequest, WorkspaceRegisteredPack, EnablePackRequest, Workspace, CreateWorkspaceRequest, UpdateWorkspaceRequest, BillingBalance, UsageEvent, ClientModel, SessionCapabilities, DesktopStreamCapability, DesktopRfbFactory, DesktopConnectionState, TerminalCapability, FsReadResponse, FsWriteResponse, Permission, CapabilityUnavailableReason } from '@opengeni/sdk';
2
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
3
  import * as react from 'react';
4
- import { ReactNode, KeyboardEvent, ClipboardEvent } from 'react';
4
+ import { ReactNode, ComponentType, RefObject, KeyboardEvent, ClipboardEvent } from 'react';
5
5
  import { ClassValue } from 'clsx';
6
6
 
7
7
  /**
@@ -9,7 +9,7 @@ import { ClassValue } from 'clsx';
9
9
  * pass the real SDK client, a proxy-backed client that routes through their
10
10
  * own API, or a scripted client in tests/demos.
11
11
  */
12
- type SessionClientLike = Pick<OpenGeniClient, "getClientConfig" | "getSession" | "listSessions" | "sendMessage" | "steerMessage" | "interrupt" | "sendApprovalDecision" | "streamEvents" | "listTurns" | "updateQueuedTurn" | "reorderQueuedTurns" | "deleteQueuedTurn" | "getGoal" | "updateGoal" | "clearSessionContext" | "compactSessionContext" | "listScheduledTasks" | "uploadFile" | "getFile" | "createFileDownloadUrl" | "listEnvironments" | "createEnvironment" | "updateEnvironment" | "deleteEnvironment" | "setEnvironmentVariable" | "deleteEnvironmentVariable" | "listPacks" | "registerPack" | "enablePack" | "deletePack" | "listWorkspaces" | "createWorkspace" | "updateWorkspace" | "getBillingUsage">;
12
+ type SessionClientLike = Pick<OpenGeniClient, "getClientConfig" | "getSession" | "listSessions" | "sendMessage" | "steerMessage" | "interrupt" | "sendApprovalDecision" | "streamEvents" | "listTurns" | "updateQueuedTurn" | "reorderQueuedTurns" | "deleteQueuedTurn" | "getGoal" | "updateGoal" | "clearSessionContext" | "compactSessionContext" | "listScheduledTasks" | "uploadFile" | "getFile" | "createFileDownloadUrl" | "listEnvironments" | "createEnvironment" | "updateEnvironment" | "deleteEnvironment" | "setEnvironmentVariable" | "deleteEnvironmentVariable" | "listPacks" | "registerPack" | "enablePack" | "deletePack" | "listWorkspaces" | "createWorkspace" | "updateWorkspace" | "getBillingUsage" | "getClientConfig" | "getStreamCapabilities" | "acknowledgeStream" | "attachViewer" | "heartbeatViewer" | "detachViewer" | "fsList" | "fsRead" | "fsWrite" | "fsDelete" | "fsMove" | "fsMkdir" | "gitStatus" | "gitDiff" | "terminalExec" | "terminalPtyOpen" | "terminalPtyWrite" | "terminalPtyResize" | "terminalPtyClose">;
13
13
 
14
14
  type OpenGeniContextValue = {
15
15
  client: SessionClientLike;
@@ -86,7 +86,15 @@ type ToolCallItem = {
86
86
  name: string;
87
87
  arguments: unknown;
88
88
  output: unknown;
89
- status: "running" | "complete";
89
+ /**
90
+ * The provider-native tool item (`agent.toolCall.created.payload.raw`). Carries
91
+ * `type` (e.g. `apply_patch_call`, `computer_call`, `hosted_tool_call`) and the
92
+ * tool-specific fields the per-tool renderers read (`operation`, `action`,
93
+ * `providerData`, …). `undefined` for first-party MCP tools, which carry their
94
+ * payload in `arguments`/`output` instead.
95
+ */
96
+ raw: unknown;
97
+ status: "running" | "complete" | "failed" | "cancelled";
90
98
  occurredAt: string;
91
99
  };
92
100
  /**
@@ -104,7 +112,7 @@ type WorkerItem = {
104
112
  prompt: string | null;
105
113
  /** The target/spawned worker session id, when parseable from args/output. */
106
114
  workerSessionId: string | null;
107
- status: "running" | "complete";
115
+ status: "running" | "complete" | "failed" | "cancelled";
108
116
  occurredAt: string;
109
117
  };
110
118
  type SandboxItem = {
@@ -114,7 +122,7 @@ type SandboxItem = {
114
122
  name: string;
115
123
  command: string | null;
116
124
  output: string;
117
- status: "running" | "complete" | "failed";
125
+ status: "running" | "complete" | "failed" | "cancelled";
118
126
  occurredAt: string;
119
127
  };
120
128
  type SessionStatusItem = {
@@ -138,17 +146,20 @@ type NoticeItem = {
138
146
  occurredAt: string;
139
147
  };
140
148
  type TimelineItem = UserMessageItem | AgentMessageItem | ReasoningItem | ToolCallItem | WorkerItem | SandboxItem | SessionStatusItem | GoalItem | NoticeItem;
141
- declare function buildTimeline(events: SessionEvent[]): TimelineItem[];
142
- /** The latest session status carried in the event log, if any. */
143
- declare function sessionStatusFromEvents(events: SessionEvent[]): SessionStatus$1 | null;
149
+ /** Activity items cluster between chat messages (reasoning, tools, workers, sandbox). */
150
+ type ActivityItem = ReasoningItem | ToolCallItem | WorkerItem | SandboxItem;
144
151
  type TimelineGroup = {
145
152
  kind: "item";
146
153
  item: TimelineItem;
147
154
  } | {
148
155
  kind: "activity";
149
156
  id: string;
150
- items: (ReasoningItem | ToolCallItem | WorkerItem | SandboxItem)[];
157
+ items: ActivityItem[];
151
158
  };
159
+
160
+ declare function buildTimeline(events: SessionEvent[]): TimelineItem[];
161
+ /** The latest session status carried in the event log, if any. */
162
+ declare function sessionStatusFromEvents(events: SessionEvent[]): SessionStatus$1 | null;
152
163
  declare function groupTimeline(items: TimelineItem[]): TimelineGroup[];
153
164
  /**
154
165
  * Find a session id in orchestration tool arguments or output. Handles raw
@@ -158,8 +169,308 @@ declare function groupTimeline(items: TimelineItem[]): TimelineGroup[];
158
169
  declare function extractSessionRef(value: unknown, depth?: number): string | null;
159
170
  /** Readable label for a tool call ("session_create" -> "session create"). */
160
171
  declare function toolDisplayName(name: string): string;
161
- /** Compact, single-line preview of tool arguments/outputs for collapsed rows. */
162
- declare function compactPayloadPreview(value: unknown, maxLength?: number): string;
172
+
173
+ type ToolRendererProps = {
174
+ item: ToolCallItem;
175
+ };
176
+ type ToolRenderer = ComponentType<ToolRendererProps>;
177
+ /** A registry entry: which key it matches and the component that renders it. */
178
+ type ToolRegistryEntry = {
179
+ match: "rawType";
180
+ type: string;
181
+ render: ToolRenderer;
182
+ } | {
183
+ match: "name";
184
+ name: string;
185
+ render: ToolRenderer;
186
+ };
187
+ type ToolRegistry = {
188
+ /** Resolve the renderer for a call (never null — falls back to generic). */
189
+ resolve: (item: ToolCallItem) => ToolRenderer;
190
+ /** The generic fallback renderer. */
191
+ fallback: ToolRenderer;
192
+ };
193
+ type CreateToolRegistryOptions = {
194
+ /**
195
+ * Entries that take precedence over the built-ins. Earlier entries win, so a
196
+ * consumer can shadow a default renderer for the same key.
197
+ */
198
+ entries?: ToolRegistryEntry[] | undefined;
199
+ /** Replace the generic fallback used for unmatched tools. */
200
+ fallback?: ToolRenderer | undefined;
201
+ };
202
+ /** The `raw.type` of a projected tool call, when the provider item carries one. */
203
+ declare function rawTypeOf(item: ToolCallItem): string | null;
204
+ /**
205
+ * Build a tool registry from a set of entries and a fallback. The returned
206
+ * registry resolves in priority order: `raw.type` entries first, then `name`
207
+ * entries, then the fallback. Consumer `entries` are consulted before the
208
+ * built-in `baseEntries`, so they shadow defaults cleanly.
209
+ */
210
+ declare function createToolRegistry(baseEntries: ToolRegistryEntry[], baseFallback: ToolRenderer, options?: CreateToolRegistryOptions): ToolRegistry;
211
+
212
+ /** The built-in tool renderer registry: every first-party tool plus a fallback. */
213
+ declare const defaultToolRegistry: ToolRegistry;
214
+ /** Build a registry that extends the built-ins with consumer entries/fallback. */
215
+ declare function createDefaultToolRegistry(options?: Parameters<typeof createToolRegistry>[2]): ToolRegistry;
216
+
217
+ type ActivityRailProps = {
218
+ items: ActivityItem[];
219
+ /** Renderer registry for tool calls. Defaults to {@link defaultToolRegistry}. */
220
+ toolRegistry?: ToolRegistry | undefined;
221
+ /** Drill into a spawned worker session. */
222
+ onOpenSession?: ((sessionId: string) => void) | undefined;
223
+ /** Drop the left rule + indent (used inside a folded turn summary). */
224
+ bare?: boolean | undefined;
225
+ className?: string | undefined;
226
+ };
227
+ declare function ActivityRail({ items, toolRegistry, onOpenSession, bare, className }: ActivityRailProps): react_jsx_runtime.JSX.Element;
228
+
229
+ /**
230
+ * A subtle settle signal — see the CHIP DOCTRINE above. The closed tone set.
231
+ * `"interrupted"` is a calm neutral tone for cancelled items — no dot, same
232
+ * quiet weight as `"muted"`, but semantically distinct from metadata.
233
+ */
234
+ type DisclosureChip = {
235
+ tone: "ok" | "bad" | "muted" | "interrupted";
236
+ text: string;
237
+ };
238
+ type ActivityDisclosureProps = {
239
+ icon: ReactNode;
240
+ /** Icon tint. Defaults to the muted foreground; renderers pass accent/failed. */
241
+ iconTone?: "accent" | "failed" | "running" | "muted" | undefined;
242
+ title: ReactNode;
243
+ /** Render the title in the mono face (commands, paths). */
244
+ titleMono?: boolean | undefined;
245
+ /** Shimmer the title while the tool is in-flight. */
246
+ running?: boolean | undefined;
247
+ /**
248
+ * Quiet single-line secondary text (truncated). It is detail-on-demand: hidden
249
+ * when a media preview is set, AND hidden once the row is expanded (the body
250
+ * then owns the detail), so a stat/path never appears twice at once.
251
+ */
252
+ preview?: ReactNode | undefined;
253
+ /** A small inline media preview (a screenshot thumbnail) shown in place of `preview`. */
254
+ media?: ReactNode | undefined;
255
+ /** At most one quiet settle chip, right-aligned to the gutter. */
256
+ chip?: DisclosureChip | undefined;
257
+ /**
258
+ * When true the row carries the standard failure affordance: the icon is tinted
259
+ * red and a "failed" bad-chip appears in the right gutter (unless an explicit
260
+ * `chip` is already supplied — the caller's chip wins). Output is still visible
261
+ * on expand; this is a quiet status signal, not a blocking banner.
262
+ *
263
+ * Renderers should pass `failed={item.status === "failed"}` on their settled
264
+ * (non-running) paths so any tool with a failed status shows a consistent
265
+ * affordance without each renderer having to duplicate the logic.
266
+ */
267
+ failed?: boolean | undefined;
268
+ /**
269
+ * When true the row carries a calm "interrupted" affordance: the icon stays
270
+ * muted (no red) and a quiet "interrupted" chip appears in the right gutter
271
+ * (unless an explicit `chip` is already supplied — the caller's chip wins).
272
+ * This is the cancelled-status analogue of `failed`, but deliberately calm
273
+ * and neutral — it is NOT an error; the user chose to stop.
274
+ *
275
+ * Renderers should pass `cancelled={item.status === "cancelled"}` so any
276
+ * in-flight item that was interrupted on turn.cancelled reads consistently.
277
+ * `cancelled` is ignored when `failed` is also true (failure takes precedence).
278
+ */
279
+ cancelled?: boolean | undefined;
280
+ /** When false the row is a static line (no expand affordance). */
281
+ expandable?: boolean | undefined;
282
+ children?: ReactNode | undefined;
283
+ };
284
+ /**
285
+ * The one disclosure row shape every activity row reuses (tool calls, reasoning,
286
+ * sandbox ops): a chevron, a tinted icon, a title, an optional muted preview or
287
+ * inline media, and at most one right-gutter settle chip. Compact by default;
288
+ * the body mounts only when expanded.
289
+ */
290
+ declare function ActivityDisclosure({ icon, iconTone: iconToneProp, title, titleMono, running, preview, media, chip: chipProp, failed, cancelled, expandable, children, }: ActivityDisclosureProps): react_jsx_runtime.JSX.Element;
291
+ declare function TermBlock({ command, workdir, output, live, tailLines, }: {
292
+ /**
293
+ * The command shown in the prompt header. Pass `null` when the row title
294
+ * already carries it (e.g. an exec row titled `$ cmd`): the header then drops
295
+ * the command — and the whole prompt line if there is no workdir either — so
296
+ * the command never reads twice, stacked, above the output.
297
+ */
298
+ command: string | null;
299
+ workdir?: string | null | undefined;
300
+ /** The FULL output. TermBlock owns the tail/full slicing internally. */
301
+ output: string;
302
+ live?: boolean | undefined;
303
+ /**
304
+ * When the output exceeds the tail window, only the last `tailLines` are shown
305
+ * with a "show full output" toggle. The component holds the full text, so the
306
+ * toggle reveals the rest (never a dead affordance). Defaults to 12.
307
+ */
308
+ tailLines?: number | undefined;
309
+ }): react_jsx_runtime.JSX.Element;
310
+ declare function PayloadBlock({ label, value, failed }: {
311
+ label: string;
312
+ value: unknown;
313
+ failed?: boolean | undefined;
314
+ }): react_jsx_runtime.JSX.Element | null;
315
+ /** A quiet inline note inside an expanded body (lost output, empty frame, …). */
316
+ declare function BodyNote({ children, tone }: {
317
+ children: ReactNode;
318
+ tone?: "error" | "muted" | undefined;
319
+ }): react_jsx_runtime.JSX.Element;
320
+ /**
321
+ * A loading screenshot placeholder. A faint camera glyph over a shimmering box,
322
+ * so a still frame of the running state reads unambiguously as "capturing" — not
323
+ * a broken thumbnail.
324
+ */
325
+ declare function MediaSkeleton(): react_jsx_runtime.JSX.Element;
326
+ /** A standardized "tool ran, produced no image" placeholder in the media slot. */
327
+ declare function MediaEmpty(): react_jsx_runtime.JSX.Element;
328
+ /**
329
+ * A small inline screenshot thumbnail that opens the app lightbox on click.
330
+ *
331
+ * Requires a `LightboxProvider` ancestor for the click-to-expand affordance.
332
+ * Outside one it degrades to a plain, non-interactive image — never a dead
333
+ * "Expand" button that announces an action it cannot perform.
334
+ */
335
+ declare function Thumbnail({ src, caption, alt }: {
336
+ src: string;
337
+ caption?: string | undefined;
338
+ alt?: string;
339
+ }): react_jsx_runtime.JSX.Element;
340
+ /**
341
+ * The expanded screenshot inside a tool body: a contained, clickable preview
342
+ * (opens the lightbox) with a quiet caption. Constrained height + object-contain
343
+ * so it never breaks the row layout. Like {@link Thumbnail}, it degrades to a
344
+ * plain image outside a `LightboxProvider`.
345
+ */
346
+ declare function ScreenshotFigure({ src, caption, alt }: {
347
+ src: string;
348
+ caption?: string | undefined;
349
+ alt?: string;
350
+ }): react_jsx_runtime.JSX.Element;
351
+
352
+ type LightboxController = {
353
+ open: (src: string, caption?: string) => void;
354
+ };
355
+ /** Open the app-level screenshot lightbox. No-op outside a `LightboxProvider`. */
356
+ declare function useLightbox(): LightboxController;
357
+ /**
358
+ * The lightbox controller when one is mounted, or `null` outside a
359
+ * `LightboxProvider`. Lets a media primitive degrade to a non-interactive image
360
+ * (rather than a dead "Expand" button that announces an action it cannot do).
361
+ */
362
+ declare function useLightboxOptional(): LightboxController | null;
363
+ /**
364
+ * The app-level screenshot lightbox. Render once near the timeline; renderers
365
+ * call `useLightbox().open(src)`.
366
+ *
367
+ * Idempotent by design: when an ancestor `LightboxProvider` already exists (e.g.
368
+ * a `MessageTimeline` mounted inside an app that already wraps its shell), this
369
+ * one becomes a pass-through and does NOT mount a second focus-trapping Dialog.
370
+ * That keeps `MessageTimeline` self-sufficient (it owns its own provider) while
371
+ * composing cleanly when nested.
372
+ */
373
+ declare function LightboxProvider({ children }: {
374
+ children: ReactNode;
375
+ }): react_jsx_runtime.JSX.Element;
376
+
377
+ /**
378
+ * Seed the initial open state of every timeline collapsible below this node.
379
+ * Intended for screenshot/test instrumentation only; absent by default.
380
+ */
381
+ declare function DisclosureDefaultsProvider({ defaultOpen, children }: {
382
+ defaultOpen: boolean;
383
+ children: ReactNode;
384
+ }): react_jsx_runtime.JSX.Element;
385
+
386
+ type TurnOutcome = "complete" | "failed" | "cancelled";
387
+ type TurnSummaryProps = {
388
+ /** The activity items in the turn (used only to compute the facet counts). */
389
+ items: ActivityItem[];
390
+ outcome: TurnOutcome;
391
+ /** A short failure reason shown inline on a failed chip (never hidden). */
392
+ failureText?: string | undefined;
393
+ /** Start expanded. */
394
+ defaultOpen?: boolean | undefined;
395
+ /** The rendered activity rail revealed on expand. */
396
+ children: React.ReactNode;
397
+ };
398
+ declare function TurnSummary({ items, outcome, failureText, defaultOpen, children }: TurnSummaryProps): react_jsx_runtime.JSX.Element;
399
+
400
+ /** Recover the exit code from a sandbox exec banner (`Process exited with code N`). */
401
+ declare function sandboxCommandExitCode(out: unknown): number | null;
402
+ /**
403
+ * Recover the numeric exec-session id the sandbox embeds for a STILL-RUNNING
404
+ * (backgrounded) process (`Process running with session ID N`). A finished
405
+ * command emits `Process exited with code N` instead, which yields `null`.
406
+ */
407
+ declare function parseExecBannerSessionId(out: unknown): number | null;
408
+ /** Strip the exec banner (`Chunk ID ...\n...\nOutput:\n`) down to the command's stdout. */
409
+ declare function stripExecBanner(out: unknown): string;
410
+ /** The sandbox clamped the output (token/line truncation markers in the banner). */
411
+ declare function execTruncated(out: unknown): boolean;
412
+ /** A `write_stdin` whose target PTY vanished (`write_stdin failed: session not found: N`). */
413
+ declare function isExecSessionLostBanner(out: unknown): boolean;
414
+ /** True when the exec stdout looks binary/garbled (a NUL byte or ELF magic). */
415
+ declare function looksBinary(text: string): boolean;
416
+ /**
417
+ * Render unprintable control characters as caret notation (0x03 -> `^C`) so a
418
+ * `write_stdin` keystroke payload reads cleanly in the row title.
419
+ */
420
+ declare function controlCaret(printable: string): string;
421
+ /** One operation inside an `apply_patch_call` (a V4A file edit). */
422
+ type ApplyPatchOperation = {
423
+ /**
424
+ * The V4A op kind. The three canonical values are `create_file`,
425
+ * `update_file`, and `delete_file`; the open `string` tail tolerates a
426
+ * forward-compatible/unknown op kind from the provider without a type error
427
+ * (it falls through to the "Edited" treatment).
428
+ */
429
+ type: "create_file" | "update_file" | "delete_file" | (string & {});
430
+ path: string;
431
+ /** Rename target -- when present the op is a move/rename. */
432
+ moveTo?: string | null | undefined;
433
+ /** The V4A hunk string (`@@ ...` lines with `+`/`-`/context prefixes). */
434
+ diff?: string | undefined;
435
+ };
436
+ /**
437
+ * Parse a single V4A `apply_patch` operation into the SDK's `GitFileDiff` shape
438
+ * so it can flow into the SAME `DiffView` / `PierreDiff` the Files tab uses.
439
+ * Throws on a hunk string it cannot structure (no `@@` anchor on an update); the
440
+ * renderer catches and falls back to a raw-patch view.
441
+ */
442
+ declare function v4aToGitFileDiff(op: ApplyPatchOperation): GitFileDiff;
443
+ /**
444
+ * Extract the `apply_patch` operations from a provider-native tool item's `raw`
445
+ * payload, normalizing the two wire shapes (`raw.operations[]` for a multi-file
446
+ * patch, `raw.operation` for a single op). The single owner of this shape so the
447
+ * renderer and the turn-summary facet counter never drift.
448
+ */
449
+ declare function applyPatchOps(raw: unknown): ApplyPatchOperation[];
450
+ /**
451
+ * True when a tool item is an `apply_patch_call` — by its provider-native
452
+ * `raw.type` (the live-wire source of truth) or by tool `name` (first-party
453
+ * replays that omit `raw`). Centralizes the rawType-or-name check.
454
+ */
455
+ declare function isApplyPatch(item: {
456
+ name: string;
457
+ raw: unknown;
458
+ }): boolean;
459
+ /** Deep-redact secret-looking values so arguments never leak a key into the UI. */
460
+ declare function redactSecrets(value: unknown): unknown;
461
+ /** Parse tool arguments that may arrive as a JSON string or an object. */
462
+ declare function parseToolArgs(args: unknown): Record<string, unknown>;
463
+ /** The last non-empty line of a string -- the compact "what happened" peek. */
464
+ declare function tailPeek(text: string): string;
465
+ /**
466
+ * Unwrap an MCP tool result (`{ content: [{ type: "text", text }], isError? }`)
467
+ * into a flat `{ text, isError }`. Non-MCP outputs pass through as their string
468
+ * form.
469
+ */
470
+ declare function unwrapMcpOutput(output: unknown): {
471
+ text: string;
472
+ isError: boolean;
473
+ };
163
474
 
164
475
  type SessionEventsConnectionState = StreamConnectionState | "idle" | "ended" | "error";
165
476
  type UseSessionEventsOptions = ClientOverride & {
@@ -561,6 +872,323 @@ type UseAvailableModelsResult = {
561
872
  */
562
873
  declare function useAvailableModels(options?: UseAvailableModelsOptions): UseAvailableModelsResult;
563
874
 
875
+ type SessionCapabilitiesState = "idle" | "negotiating" | "ready" | "cold" | "error";
876
+ type UseSessionCapabilitiesOptions = ClientOverride & {
877
+ /**
878
+ * Live event log to fold `stream.url.rotated` from (usually
879
+ * `useSessionEvents().events`). When present the desktop socket stays fresh on
880
+ * a box rollover without a round-trip; stale-epoch rotations are dropped.
881
+ */
882
+ events?: SessionEvent[] | undefined;
883
+ /**
884
+ * Whether to acquire a viewer holder for the desktop pixel plane. Requires the
885
+ * un-redacted acknowledgment to have been recorded (else the attach 409s and
886
+ * the hook surfaces the consent requirement). Default false: read-only
887
+ * negotiation (no holder, no warm) — terminal/files/git work without it.
888
+ */
889
+ attachDesktop?: boolean | undefined;
890
+ /**
891
+ * Whether to acquire a viewer holder to warm the box for the REAL interactive
892
+ * terminal (the ttyd pty-ws plane). Symmetric with `attachDesktop` and shares
893
+ * the SAME viewer attach (one warm box serves both planes), but needs NO
894
+ * un-redacted acknowledgment — a shell is interactive by nature, and the gate
895
+ * is the scoped tunnel URL + stream token. Default false: the terminal stays on
896
+ * the read-only Channel-A firehose until the user opens/focuses it. The attach
897
+ * folds the minted `pty-ws` url+token into the `Terminal` cell.
898
+ */
899
+ attachTerminal?: boolean | undefined;
900
+ /**
901
+ * Whether to acquire a viewer holder purely to KEEP THE BOX WARM while the
902
+ * structured Files surface is open. Shares the SAME viewer attach as the
903
+ * desktop/terminal (one warm box, one holder) and — like the terminal — needs
904
+ * NO un-redacted acknowledgment: listing/reading/writing files is the ordinary
905
+ * Channel-A control plane, not the pixel plane. Default false: the Files tab
906
+ * negotiates read-only and each op pays the cold-box resume (~5s). When true,
907
+ * the holder warms the box once and heartbeats it, so subsequent fs ops are
908
+ * ~100ms instead of re-resuming the box on every list/write. It folds NO live
909
+ * URL (files ride the stateless HTTP plane) — it only refcounts liveness.
910
+ */
911
+ attachFiles?: boolean | undefined;
912
+ /** Hold off negotiating (e.g. the workbench panel is collapsed). Default true. */
913
+ enabled?: boolean | undefined;
914
+ /** Poll cadence (ms) while the lease is cold/warming. Default 1500. */
915
+ warmingPollMs?: number | undefined;
916
+ /**
917
+ * Give up waiting for `warm` after this long while polling (ms) and surface a
918
+ * stalled error with a manual `renegotiate`. Default 30000 (must agree with
919
+ * the lease warming TTL — I15). 0 disables the deadline.
920
+ */
921
+ warmingDeadlineMs?: number | undefined;
922
+ };
923
+ type UseSessionCapabilitiesResult = {
924
+ /** The negotiated capability doc — the single source of UI truth. */
925
+ capabilities: SessionCapabilities | null;
926
+ state: SessionCapabilitiesState;
927
+ error: Error | null;
928
+ /**
929
+ * 409 from the desktop attach: the un-redacted (or shared) plane needs explicit
930
+ * acknowledgment before a viewer holder is granted. Drives the consent prompt.
931
+ */
932
+ acknowledgmentRequired: "unredacted" | "shared" | null;
933
+ /** 429 from the desktop attach: the per-session viewer cap is reached. */
934
+ viewerCapReached: boolean;
935
+ /** The viewer holder id minted on a desktop attach (for detach/heartbeat). */
936
+ viewerId: string | null;
937
+ /** Force a re-negotiation (after acknowledging, a resolution change, etc.). */
938
+ renegotiate: () => void;
939
+ };
940
+ /**
941
+ * The capability-negotiation hook. Discovers what THIS session+backend+OS
942
+ * supports (FileSystem/Terminal/Git always-ish; DesktopStream/Recording
943
+ * sometimes), drives capability-gated rendering, and — when `attachDesktop` —
944
+ * holds a viewer lease + heartbeats it so the box stays warm while watched.
945
+ *
946
+ * Degradation is a value, never a crash: an unsupported surface comes back
947
+ * `available:false`/`transport:null` + a `reason`; the components render the
948
+ * reason-aware empty state. 409 (consent) and 429 (viewer cap) are surfaced as
949
+ * typed signals, not thrown.
950
+ */
951
+ declare function useSessionCapabilities(sessionId: string | null | undefined, options?: UseSessionCapabilitiesOptions): UseSessionCapabilitiesResult;
952
+
953
+ type UseDesktopStreamOptions = {
954
+ /** The desktop cell of the negotiated capabilities (`capabilities.DesktopStream`). */
955
+ capability: DesktopStreamCapability | null;
956
+ /** The mount target. RFB attaches here on connect. */
957
+ containerRef: RefObject<HTMLDivElement | null>;
958
+ /** Read-only by default (v1 ruling H). interactive only when cap.mode allows. */
959
+ interactive?: boolean | undefined;
960
+ scaleViewport?: boolean | undefined;
961
+ /** Custom RFB factory (tests / a WebRTC swap). Defaults to a lazy @novnc/novnc. */
962
+ rfbFactory?: DesktopRfbFactory | undefined;
963
+ };
964
+ type UseDesktopStreamResult = {
965
+ state: DesktopConnectionState;
966
+ error: Error | null;
967
+ /** Manual reconnect (e.g. after a securityfailure once a fresh URL arrives). */
968
+ reconnect: () => void;
969
+ };
970
+ /**
971
+ * Drive the noVNC RFB lifecycle from a `DesktopStreamCapability`, using the
972
+ * SDK's `desktop.ts` reducer + `desktopSocketUrl`. SSR-safe: the RFB import and
973
+ * the DOM attach happen inside `useEffect`, so a server render is a no-op and
974
+ * the component shows its placeholder until hydration.
975
+ *
976
+ * Read-only is enforced at three layers: `capability.mode` (server) →
977
+ * `interactive` prop → `RFB.viewOnly`. v1 always resolves to read-only. On a
978
+ * capability `url` change (a rotation), the old RFB disconnects and a fresh one
979
+ * connects to the new URL — a brief "desktop blink", acceptable on rollover.
980
+ */
981
+ declare function useDesktopStream(options: UseDesktopStreamOptions): UseDesktopStreamResult;
982
+
983
+ /** The ttyd connection lifecycle as surfaced to the component. */
984
+ type TerminalStreamStatus = "connecting" | "open" | "closed" | "error";
985
+ type UseTerminalStreamOptions = {
986
+ /** The Terminal cell of the negotiated capabilities (`capabilities.Terminal`).
987
+ * The stream connects ONLY when `transport === "pty-ws"` and `url` is set; on a
988
+ * cold box (`transport === "sse-events"` / no url) it stays idle and the caller
989
+ * falls back to the Channel-A read-only firehose. */
990
+ capability: Pick<TerminalCapability, "transport" | "url" | "token"> | null;
991
+ /** Called for each OUTPUT payload from ttyd (write verbatim into xterm). */
992
+ onOutput?: ((data: string) => void) | undefined;
993
+ /** Called when ttyd sends a SET_WINDOW_TITLE frame. */
994
+ onTitle?: ((title: string) => void) | undefined;
995
+ /** Initial PTY size to seed the ttyd auth frame + first resize. */
996
+ initialCols?: number | undefined;
997
+ initialRows?: number | undefined;
998
+ };
999
+ type UseTerminalStreamResult = {
1000
+ /** True once the ttyd socket is open (and the auth frame has been sent). */
1001
+ connected: boolean;
1002
+ status: TerminalStreamStatus;
1003
+ /** Pipe a keystroke/paste to the PTY stdin. No-op until the socket is open. */
1004
+ write: (data: string) => void;
1005
+ /** Tell ttyd the PTY window changed size (on xterm fit/resize). */
1006
+ resize: (cols: number, rows: number) => void;
1007
+ /** Tear the socket down (the effect also tears down on unmount / url change). */
1008
+ disconnect: () => void;
1009
+ };
1010
+ /**
1011
+ * Drive a ttyd PTY-over-websocket connection from a `pty-ws` Terminal capability,
1012
+ * symmetric with `use-desktop-stream` (the noVNC-over-tunnel hook). The scoped
1013
+ * stream token is already embedded in the minted tunnel `url`; the WebSocket is
1014
+ * opened with the REQUIRED ttyd subprotocol "tty".
1015
+ *
1016
+ * ttyd wire protocol (see `@opengeni/sdk/terminal`):
1017
+ * - first frame: `JSON.stringify({ AuthToken: "" })` (+ optional columns/rows).
1018
+ * - client→server: INPUT = "0"+data ; RESIZE = "1"+JSON({columns,rows}).
1019
+ * - server→client: "0" = OUTPUT (→ xterm) ; "1" = SET_WINDOW_TITLE ;
1020
+ * "2" = SET_PREFERENCES (ignored). Binary frames are decoded the same way.
1021
+ *
1022
+ * On a `url`/`token` rotation (a box rollover folds a fresh address into the cell)
1023
+ * the effect re-runs: the old socket closes and a fresh one connects — a brief
1024
+ * terminal blink, acceptable on rollover (mirrors the desktop's RFB hot-swap).
1025
+ * SSR-safe: the socket open lives in `useEffect`, so a server render is a no-op.
1026
+ */
1027
+ declare function useTerminalStream(options: UseTerminalStreamOptions): UseTerminalStreamResult;
1028
+
1029
+ type TerminalChunk = {
1030
+ /** Stable key (the source event id) so the xterm writer tracks a written-cursor. */
1031
+ id: string;
1032
+ /** Raw output bytes (utf-8 lossy) — written verbatim into xterm. */
1033
+ text: string;
1034
+ /** stdout vs stderr (drives optional tinting). */
1035
+ stream: "stdout" | "stderr";
1036
+ /** Global ordering: the source event sequence. */
1037
+ seq: number;
1038
+ };
1039
+ type UseSandboxTerminalOptions = ClientOverride & {
1040
+ /** The live session event log (usually `useSessionEvents().events`). */
1041
+ events: SessionEvent[];
1042
+ /** Restrict to one PTY (by ptyId). Omit to interleave the agent firehose +
1043
+ * every PTY. */
1044
+ ptyId?: string | undefined;
1045
+ /** Include the agent's command-output firehose (sandbox.command.output.delta).
1046
+ * Default true — the read-only "terminal-as-events" the data path settled on. */
1047
+ includeAgentFirehose?: boolean | undefined;
1048
+ /**
1049
+ * OPEN an interactive PTY against the box so the user can type, not just watch.
1050
+ * When true (and the session is live) the hook calls `terminalPtyOpen` once,
1051
+ * tracks the returned ptyId, exposes `write` immediately (bound to that ptyId),
1052
+ * and closes the PTY on unmount. The PTY's banner + every output delta ride the
1053
+ * SSE spine (`terminal.pty.*`) back into `events`, so xterm fills in. Default
1054
+ * false — a caller that only wants the read-only firehose stays projection-only.
1055
+ */
1056
+ interactive?: boolean | undefined;
1057
+ /** Lease liveness ("cold" | "warm" | "draining"). The interactive PTY is only
1058
+ * opened once the box is warm — opening on a cold box (ptyCapable is advertised
1059
+ * cold too) races the box and leaves a dead read-only terminal. */
1060
+ liveness?: string | undefined;
1061
+ };
1062
+ type UseSandboxTerminalResult = {
1063
+ /** Ordered, deduped output chunks to write() into xterm.js. */
1064
+ chunks: TerminalChunk[];
1065
+ /** Whether a PTY is currently open (drives the prompt/cursor affordance). */
1066
+ running: boolean;
1067
+ /**
1068
+ * Interactive write fn when a PTY is open and the backend supports stdin
1069
+ * (`terminal.transport === "pty-ws"` / `PtyOpenResponse.supportsInput`). Null
1070
+ * in the read-only event-projection case (v1 default).
1071
+ */
1072
+ write: ((data: string) => void) | null;
1073
+ /** The active PTY id, if one is open. */
1074
+ activePtyId: string | null;
1075
+ /** Close the active PTY (no-op when none is open). */
1076
+ close: () => void;
1077
+ /** A PTY-open failure (interactive mode), if any. */
1078
+ error: Error | null;
1079
+ };
1080
+ /**
1081
+ * Project the Channel-A event log into an xterm-writable byte stream. The
1082
+ * terminal is "terminal-as-events": there is NO new socket in v1 — the agent's
1083
+ * command output (`sandbox.command.output.delta`) and any interactive PTY
1084
+ * (`terminal.pty.output.delta`) ride the existing SSE spine. When a PTY is open
1085
+ * and the backend accepts stdin, `write` pipes keystrokes via the SDK
1086
+ * `terminalPtyWrite` (the synchronous Channel-A control path).
1087
+ */
1088
+ declare function useSandboxTerminal(sessionId: string | null | undefined, options: UseSandboxTerminalOptions): UseSandboxTerminalResult;
1089
+
1090
+ /** The git-status overlay a file row may carry (tints modified files in the tree). */
1091
+ type FileTreeStatus = "added" | "modified" | "deleted" | "renamed" | "untracked";
1092
+ /** A node in the Pierre file tree. `children === undefined` ⇒ an unexpanded dir
1093
+ * (lazy treeMode); `children: []` ⇒ an expanded-but-empty dir. */
1094
+ type FileTreeNode = {
1095
+ path: string;
1096
+ name: string;
1097
+ kind: "file" | "dir";
1098
+ children?: FileTreeNode[] | undefined;
1099
+ size?: number | null | undefined;
1100
+ status?: FileTreeStatus | undefined;
1101
+ };
1102
+ type UseSandboxFilesOptions = ClientOverride & {
1103
+ /** Live event log (usually `useSessionEvents().events`) — drives auto-refresh
1104
+ * on `fs.changed` / `git.changed`. */
1105
+ events?: SessionEvent[] | undefined;
1106
+ /** Initial path to list (workspace root by default). */
1107
+ rootPath?: string | undefined;
1108
+ /** Hold off the initial list (e.g. panel collapsed). Default true. */
1109
+ enabled?: boolean | undefined;
1110
+ /** The lease liveness ("cold" | "warm" | "draining"). The structured FileSystem
1111
+ * capability is advertised even on a COLD box, so the mount-time list can race
1112
+ * the box: it lists before the box is warm, gets an empty/errored result, and
1113
+ * (with no `fs.changed` event) never re-lists. Passing liveness re-lists when
1114
+ * the box first becomes warm, so the tree populates as soon as the box is up. */
1115
+ liveness?: string | undefined;
1116
+ /** Called when an OPTIMISTIC mutation is reverted because its background
1117
+ * Channel-A op failed (e.g. a 409 rename collision). The host wires this to a
1118
+ * toast — the tree silently rolls the node back, the user sees why. */
1119
+ onMutationError?: ((error: Error, op: string) => void) | undefined;
1120
+ };
1121
+ type UseSandboxFilesResult = {
1122
+ /** The tree roots (the listed root's children). */
1123
+ tree: FileTreeNode[];
1124
+ /** Lazy-expand a directory node in place (lists its immediate children). */
1125
+ expand: (path: string) => Promise<void>;
1126
+ /** Paths whose lazy `fs.list` is currently in flight — the FileBrowser shows a
1127
+ * spinner on these nodes so a 2-3s Channel-A list never looks frozen. */
1128
+ expandingPaths: Set<string>;
1129
+ /** Read a file for the preview pane (text or base64-for-binary, size-capped). */
1130
+ readFile: (path: string) => Promise<FsReadResponse>;
1131
+ /** Write a file (overwrite, last-writer-wins) — the editor save path.
1132
+ * Optimistic: a brand-new file is spliced into the tree immediately and the
1133
+ * Channel-A write runs in the background; on failure the splice is reverted. */
1134
+ writeFile: (path: string, content: string) => Promise<FsWriteResponse>;
1135
+ /** Create a new empty file (refuses to clobber an existing path: overwrite=false). */
1136
+ createFile: (path: string) => Promise<void>;
1137
+ /** Create a directory (recursive by default). */
1138
+ createDir: (path: string) => Promise<void>;
1139
+ /** Delete a path (pass recursive=true for a non-empty directory). */
1140
+ deleteEntry: (path: string, recursive?: boolean) => Promise<void>;
1141
+ /** Move / rename a path (rename == move). Refuses to clobber unless overwrite=true. */
1142
+ moveEntry: (path: string, newPath: string, opts?: {
1143
+ overwrite?: boolean;
1144
+ }) => Promise<void>;
1145
+ /** Re-list the whole tree from the root. */
1146
+ refresh: () => Promise<void>;
1147
+ loading: boolean;
1148
+ error: Error | null;
1149
+ };
1150
+ /**
1151
+ * Project the FileSystem service into a lazy-loaded Pierre tree. The initial
1152
+ * list pulls one level (depth 1); `expand(path)` lists a directory's immediate
1153
+ * children on demand (the fast lazy-tree UX). A git-status overlay tints
1154
+ * modified files. Auto-refreshes when an `fs.changed` / `git.changed` event
1155
+ * arrives on the live log.
1156
+ */
1157
+ declare function useSandboxFiles(sessionId: string | null | undefined, options?: UseSandboxFilesOptions): UseSandboxFilesResult;
1158
+
1159
+ type UseSandboxGitOptions = ClientOverride & {
1160
+ /** Live event log (usually `useSessionEvents().events`) — drives auto-refresh
1161
+ * on `git.changed`. */
1162
+ events?: SessionEvent[] | undefined;
1163
+ /** Repo root within the workspace (multi-repo). Default: workspace root. */
1164
+ repoPath?: string | undefined;
1165
+ /** Diff the staged index vs HEAD (`--cached`) instead of the working tree. */
1166
+ staged?: boolean | undefined;
1167
+ /** Hold off the initial fetch. Default true. */
1168
+ enabled?: boolean | undefined;
1169
+ };
1170
+ type UseSandboxGitResult = {
1171
+ /** Working-tree (or staged) diff vs HEAD — the structured hunks the Pierre
1172
+ * diff view renders. */
1173
+ diff: GitFileDiff[];
1174
+ branch: string | null;
1175
+ /** Whether a repo is actually mounted (drives "no repository" vs "no changes"). */
1176
+ isRepo: boolean;
1177
+ ahead: number;
1178
+ behind: number;
1179
+ refresh: () => Promise<void>;
1180
+ loading: boolean;
1181
+ error: Error | null;
1182
+ };
1183
+ /**
1184
+ * Project the Git service into the Pierre diff data contract: structured
1185
+ * `GitFileDiff[]` (per-file hunks with per-line old/new numbers, rename
1186
+ * detection, binary flag, add/del counts) plus branch + ahead/behind. The
1187
+ * `git diff` runs in-box (API-direct) and the hunks come back inline. Refreshes
1188
+ * on `git.changed`.
1189
+ */
1190
+ declare function useSandboxGit(sessionId: string | null | undefined, options?: UseSandboxGitOptions): UseSandboxGitResult;
1191
+
564
1192
  type PendingApproval = {
565
1193
  /** The id to send back via `user.approvalDecision` (`approvalId`). */
566
1194
  id: string;
@@ -884,6 +1512,12 @@ type MessageTimelineProps = {
884
1512
  renderMessageText?: ((text: string, item: AgentMessageItem | UserMessageItem) => ReactNode) | undefined;
885
1513
  /** Drill into a spawned worker session. */
886
1514
  onOpenSession?: ((sessionId: string) => void) | undefined;
1515
+ /**
1516
+ * The tool-renderer registry that resolves how each tool call is drawn.
1517
+ * Defaults to {@link defaultToolRegistry}; pass a registry from
1518
+ * `createDefaultToolRegistry({ entries })` to add custom tool renderers.
1519
+ */
1520
+ toolRegistry?: ToolRegistry | undefined;
887
1521
  /** Follow new events when pinned to the bottom. Defaults to true. */
888
1522
  autoFollow?: boolean | undefined;
889
1523
  emptyState?: ReactNode | undefined;
@@ -895,7 +1529,16 @@ type MessageTimelineProps = {
895
1529
  * cards, goal markers, and status transitions. Owns stick-to-bottom scrolling
896
1530
  * with a "jump to latest" affordance when the reader scrolls back.
897
1531
  */
898
- declare function MessageTimeline({ events, items, status, renderMessageText, onOpenSession, autoFollow, emptyState, className, }: MessageTimelineProps): react_jsx_runtime.JSX.Element;
1532
+ declare function MessageTimeline({ events, items, status, renderMessageText, onOpenSession, toolRegistry, autoFollow, emptyState, className, }: MessageTimelineProps): react_jsx_runtime.JSX.Element;
1533
+ /**
1534
+ * Render one non-activity timeline item (chat message, status divider, goal
1535
+ * landmark, notice). Exported so the component demo draws the EXACT same rows as
1536
+ * the live app — no forked bubble/goal markup.
1537
+ */
1538
+ declare function TimelineRow({ item, renderMessageText, }: {
1539
+ item: TimelineItem;
1540
+ renderMessageText?: ((text: string, item: AgentMessageItem | UserMessageItem) => ReactNode) | undefined;
1541
+ }): react_jsx_runtime.JSX.Element | null;
899
1542
 
900
1543
  /**
901
1544
  * The default renderer for chat message bodies in {@link MessageTimeline}.
@@ -962,6 +1605,384 @@ declare function sessionDisplayTitle(session: Session): string;
962
1605
  */
963
1606
  declare function FleetTile({ session, title, subtitle, onOpen, className }: FleetTileProps): react_jsx_runtime.JSX.Element;
964
1607
 
1608
+ /** A subset of xterm.js's ITheme — the tokens worth themeing from a host app. */
1609
+ type XtermTheme = {
1610
+ background?: string;
1611
+ foreground?: string;
1612
+ cursor?: string;
1613
+ cursorAccent?: string;
1614
+ selectionBackground?: string;
1615
+ };
1616
+ type SandboxTerminalProps = {
1617
+ /** From `useSandboxTerminal(...)`. */
1618
+ result: UseSandboxTerminalResult;
1619
+ /**
1620
+ * The negotiated Terminal capability cell. When it advertises `transport:
1621
+ * "pty-ws"` + a live `url` (a warm box with a viewer attached), the terminal is
1622
+ * driven by a REAL bidirectional PTY over the Modal tunnel (ttyd-over-websocket)
1623
+ * INSTEAD of the broken ptyWrite-over-HTTP path: xterm input → the socket, the
1624
+ * socket's output → xterm, xterm resize → the socket. On a cold box / no url
1625
+ * (`transport: "sse-events"`) it stays on the read-only Channel-A firehose
1626
+ * (`result.chunks`). Omit to force the legacy firehose-only behavior.
1627
+ */
1628
+ terminalCapability?: TerminalCapability | null | undefined;
1629
+ theme?: XtermTheme | undefined;
1630
+ fontFamily?: string | undefined;
1631
+ fontSize?: number | undefined;
1632
+ /**
1633
+ * Force read-only even when the PTY accepts stdin. Default: interactive
1634
+ * whenever a live pty-ws stream is connected OR `result.write !== null` (the box
1635
+ * advertises an interactive PTY); otherwise the read-only agent firehose.
1636
+ */
1637
+ readOnly?: boolean | undefined;
1638
+ /** Shown on the server / before xterm hydrates (SSR-safe placeholder). */
1639
+ placeholder?: ReactNode | undefined;
1640
+ /** Render the small status header (pty/shell + running dot + read-only pill). */
1641
+ showHeader?: boolean | undefined;
1642
+ /** Shell label for the header (e.g. `/bin/bash`). */
1643
+ shell?: string | undefined;
1644
+ /**
1645
+ * Fired the first time the user engages the terminal surface (focus or click).
1646
+ * The host wires this to warm the box for the REAL pty-ws terminal (the viewer
1647
+ * attach), so a cold box upgrades from the read-only firehose to a live PTY ON
1648
+ * INTERACT — never on mere mount (which would force a box spin-up and regress
1649
+ * the firehose-only default).
1650
+ */
1651
+ onActivate?: (() => void) | undefined;
1652
+ className?: string | undefined;
1653
+ };
1654
+ /**
1655
+ * An xterm.js terminal fed by the Channel-A event projection
1656
+ * (`useSandboxTerminal`). xterm + the fit + web-links addons are lazy-imported
1657
+ * inside an effect, so SSR renders the placeholder and the terminal mounts on
1658
+ * hydration. Output chunks are written incrementally (tracking a written-cursor
1659
+ * by chunk id so a re-render never re-writes). When `result.write` is non-null
1660
+ * and not forced read-only, keystrokes pipe back through the PTY.
1661
+ *
1662
+ * Resizes are tracked with a `ResizeObserver` on the container (not just
1663
+ * `window.resize`) so dragging the dock handle refits the grid instead of
1664
+ * leaving the terminal mis-sized.
1665
+ */
1666
+ declare function SandboxTerminal({ result, terminalCapability, theme, fontFamily, fontSize, readOnly, placeholder, showHeader, shell, onActivate, className, }: SandboxTerminalProps): react_jsx_runtime.JSX.Element;
1667
+
1668
+ type FileBrowserProps = {
1669
+ /** From `useSandboxFiles(...)`. */
1670
+ result: UseSandboxFilesResult;
1671
+ /**
1672
+ * Rendered instead of the built-in tree when the file surface is unavailable
1673
+ * (e.g. a `FileSystem.available === false` capability). Default: a quiet notice.
1674
+ */
1675
+ fallback?: ReactNode | undefined;
1676
+ /** Selection callback for the preview pane. */
1677
+ onSelectFile?: ((path: string) => void) | undefined;
1678
+ selectedPath?: string | undefined;
1679
+ /** Render-prop to theme/replace a row entirely (the Pierre-swap escape hatch). */
1680
+ renderNode?: ((node: FileTreeNode, depth: number, expanded: boolean) => ReactNode) | undefined;
1681
+ /** Shown when the tree is empty (no files / not loaded yet). */
1682
+ emptyState?: ReactNode | undefined;
1683
+ /**
1684
+ * Enable the file-manager affordances (toolbar, context menu, drag-drop move,
1685
+ * inline rename, delete, new file/folder). Defaults to `true` when the hook
1686
+ * exposes the mutation methods; pass `false` for a strictly read-only tree.
1687
+ */
1688
+ editable?: boolean | undefined;
1689
+ /**
1690
+ * Confirm a (recursive) delete before it runs. Return `false` to cancel.
1691
+ * Defaults to `window.confirm`. Pass a no-op returning `true` to skip.
1692
+ */
1693
+ confirmDelete?: ((node: FileTreeNode) => boolean | Promise<boolean>) | undefined;
1694
+ className?: string | undefined;
1695
+ };
1696
+ /**
1697
+ * The file MANAGER, fed by the FileSystem service via `useSandboxFiles`. This is
1698
+ * a first-class editable tree (not a render-only view): lazy-expand with a
1699
+ * spinner on the in-flight node, git-status tinting, full keyboard navigation,
1700
+ * selection, and the mutating affordances wired straight to the hook —
1701
+ *
1702
+ * • drag-and-drop MOVE → `moveEntry(from, to)`
1703
+ * • inline RENAME → `moveEntry(path, newPath)` (F2 / double-click / menu)
1704
+ * • DELETE → `deleteEntry(path, recursive)` (Del / menu, confirmed)
1705
+ * • NEW FILE / FOLDER → `createFile` / `createDir` (toolbar + menu), then open
1706
+ * • right-click CONTEXT MENU
1707
+ *
1708
+ * `renderNode` is still honoured as the Pierre-swap escape hatch for the row
1709
+ * chrome; the manager scaffolding (toolbar, dnd, menu, inline inputs) wraps it.
1710
+ */
1711
+ declare function FileBrowser({ result, fallback, onSelectFile, selectedPath, renderNode, emptyState, editable, confirmDelete, className, }: FileBrowserProps): react_jsx_runtime.JSX.Element;
1712
+
1713
+ /** Theme tokens for the diff line backgrounds. */
1714
+ type DiffTheme = {
1715
+ addBackground?: string;
1716
+ delBackground?: string;
1717
+ contextBackground?: string;
1718
+ metaForeground?: string;
1719
+ };
1720
+ type DiffViewProps = {
1721
+ /** From `useSandboxGit().diff` — the structured per-file hunks. */
1722
+ diff: GitFileDiff[];
1723
+ /** Rendered instead of the built-in diff (the Pierre-swap escape hatch). */
1724
+ fallback?: ReactNode | undefined;
1725
+ /** unified | split. Default "unified". */
1726
+ layout?: "unified" | "split" | undefined;
1727
+ theme?: DiffTheme | undefined;
1728
+ onSelectFile?: ((path: string) => void) | undefined;
1729
+ /** Distinguishes "no changes" from "no repository mounted". */
1730
+ isRepo?: boolean | undefined;
1731
+ emptyState?: ReactNode | undefined;
1732
+ className?: string | undefined;
1733
+ };
1734
+ /**
1735
+ * The diff view, fed by the Git service via `useSandboxGit().diff`. This is our
1736
+ * `PierreDiff` boundary: the built-in renderer delivers the same UX (per-file
1737
+ * hunks, unified or side-by-side, old/new line numbers, add/del counts), and a
1738
+ * consumer with Pierre's `@pierre/diffs` installed can swap it via `fallback`
1739
+ * while keeping the same `GitFileDiff[]` data contract from the hook.
1740
+ */
1741
+ declare function DiffView({ diff, fallback, layout, theme, onSelectFile, isRepo, emptyState, className, }: DiffViewProps): react_jsx_runtime.JSX.Element;
1742
+
1743
+ type PierreDiffProps = {
1744
+ diff: GitFileDiff[];
1745
+ layout?: "unified" | "split" | undefined;
1746
+ themeType?: "dark" | "light" | undefined;
1747
+ /** Shiki bundled theme names (dark/light) — derived from the host palette. */
1748
+ theme?: {
1749
+ dark: string;
1750
+ light: string;
1751
+ } | undefined;
1752
+ /** Disable Pierre's worker pool if its worker bundling fights the host bundler. */
1753
+ disableWorkerPool?: boolean | undefined;
1754
+ /** Rendered while the (lazy) Pierre bundle loads. */
1755
+ loading?: ReactNode | undefined;
1756
+ /** Rendered if `@pierre/diffs/react` is not installed / fails to import. */
1757
+ fallback?: ReactNode | undefined;
1758
+ className?: string | undefined;
1759
+ };
1760
+ /**
1761
+ * The Pierre-backed diff: Shiki-highlighted, virtualized, unified/split. Renders
1762
+ * one `PatchDiff` per changed file (a reconstructed unified patch from the
1763
+ * `GitFileDiff` hunks). This sits behind `DiffView`'s `fallback` seam so a host
1764
+ * that lacks `@pierre/diffs` keeps the hand-rolled renderer.
1765
+ */
1766
+ declare function PierreDiff({ diff, layout, themeType, theme, disableWorkerPool, loading, fallback, className, }: PierreDiffProps): react_jsx_runtime.JSX.Element;
1767
+
1768
+ type PierreFileProps = {
1769
+ /** Workspace-relative path (used for the header + language inference). */
1770
+ path: string;
1771
+ /** The decoded text contents. */
1772
+ contents: string;
1773
+ themeType?: "dark" | "light" | undefined;
1774
+ /** Shiki bundled theme names (dark/light) — derived from the host palette. */
1775
+ theme?: {
1776
+ dark: string;
1777
+ light: string;
1778
+ } | undefined;
1779
+ /** Disable Pierre's worker pool if its worker bundling fights the host bundler. */
1780
+ disableWorkerPool?: boolean | undefined;
1781
+ /** Rendered while the (lazy) Pierre bundle loads. */
1782
+ loading?: ReactNode | undefined;
1783
+ /** Rendered if `@pierre/diffs/react` is not installed / fails to import. */
1784
+ fallback?: ReactNode | undefined;
1785
+ className?: string | undefined;
1786
+ };
1787
+ /**
1788
+ * The Pierre-backed single-file VIEWER: Shiki-highlighted, language inferred from
1789
+ * the filename — the read complement of `PierreDiff`. Wired to `fs.read` so
1790
+ * clicking any file in the tree shows its contents (NOT a diff; no repo needed).
1791
+ * Falls back to a plain `<pre>` when `@pierre/diffs` is absent / fails to import.
1792
+ */
1793
+ declare function PierreFile({ path, contents, themeType, theme, disableWorkerPool, loading, fallback, className, }: PierreFileProps): react_jsx_runtime.JSX.Element;
1794
+
1795
+ /** Language grammar loaders, keyed by the extension class we infer from the path. */
1796
+ declare const LANGUAGE_LOADERS: Record<string, () => Promise<unknown>>;
1797
+ /** Map a filename to a grammar key (or null for plain text — still fully editable). */
1798
+ declare function languageForPath(path: string): keyof typeof LANGUAGE_LOADERS | null;
1799
+ type CodeEditorProps = {
1800
+ /** Workspace-relative path — drives language inference (and the save target upstream). */
1801
+ path: string;
1802
+ /** The decoded text contents to seed the editor with. */
1803
+ initialContents: string;
1804
+ /** Persist the current buffer. Resolves when the write lands; rejects to surface an error. */
1805
+ onSave: (contents: string) => Promise<unknown>;
1806
+ /** Read-only mode (e.g. a truncated/too-large file shown for reference only). */
1807
+ readOnly?: boolean | undefined;
1808
+ themeType?: "dark" | "light" | undefined;
1809
+ /** Rendered while the (lazy) CodeMirror bundle loads. */
1810
+ loading?: ReactNode | undefined;
1811
+ /** Rendered if `@uiw/react-codemirror` is not installed / fails to import. */
1812
+ fallback?: ReactNode | undefined;
1813
+ className?: string | undefined;
1814
+ };
1815
+ /**
1816
+ * The EDITABLE single-file pane: CodeMirror 6 with a per-language grammar chosen
1817
+ * from the filename, og-* themed, with dirty tracking and a save path wired to
1818
+ * `Cmd/Ctrl+S` *and* an explicit Save button. The viewer (Pierre `File`) stays
1819
+ * the read-only complement — this is only mounted when the user opts to edit.
1820
+ *
1821
+ * Save semantics: the buffer is "dirty" the moment it diverges from the last
1822
+ * saved baseline; a successful `onSave` clears dirty and re-baselines. A failed
1823
+ * save keeps the buffer dirty (nothing is lost) and surfaces the error inline.
1824
+ * `readOnly` suppresses every mutation path so a truncated/binary file can never
1825
+ * be saved back (which would corrupt it by writing the truncated prefix).
1826
+ */
1827
+ declare function CodeEditor({ path, initialContents, onSave, readOnly, themeType, loading, fallback, className, }: CodeEditorProps): react_jsx_runtime.JSX.Element;
1828
+
1829
+ type SandboxFilesProps = {
1830
+ /** From `useSandboxFiles(...)`. */
1831
+ files: UseSandboxFilesResult;
1832
+ /** From `useSandboxGit(...)` — the working-tree diff. */
1833
+ git: UseSandboxGitResult;
1834
+ /** From a second `useSandboxGit(..., { staged: true })` — the staged diff. */
1835
+ stagedGit?: UseSandboxGitResult | undefined;
1836
+ /** Whether a FileSystem surface is advertised (drives the unavailable notice). */
1837
+ fileSystemAvailable?: boolean | undefined;
1838
+ /** Use Pierre's Shiki-highlighted diff (default true; falls back to built-in). */
1839
+ usePierre?: boolean | undefined;
1840
+ /** Allow in-place editing of tree files (CodeMirror). Default true. When false
1841
+ * the surface is review-only: every text file opens in the read-only viewer. */
1842
+ editable?: boolean | undefined;
1843
+ themeType?: "dark" | "light" | undefined;
1844
+ className?: string | undefined;
1845
+ };
1846
+ /**
1847
+ * The review-first Files surface: a sticky branch/dirty header, a "Changes"
1848
+ * group (changed files vs HEAD, badged), the full lazy file tree for context,
1849
+ * and an inline diff pane below for the selected changed file. The agent
1850
+ * commits; the human reviews — there is no stage/commit/push UI here (power-git
1851
+ * lives in the terminal).
1852
+ */
1853
+ declare function SandboxFiles({ files, git, stagedGit, fileSystemAvailable, usePierre, editable, themeType, className, }: SandboxFilesProps): react_jsx_runtime.JSX.Element;
1854
+
1855
+ type DesktopViewerProps = {
1856
+ /** The desktop cell of the negotiated capabilities (`capabilities.DesktopStream`). */
1857
+ capability: DesktopStreamCapability | null;
1858
+ /**
1859
+ * Initial control mode. Default false (watch). When the user flips
1860
+ * "Take control" the viewer drives input — but only if `capability.mode`
1861
+ * permits it (server-gated; a read-only deployment disables the toggle).
1862
+ * Pass a value to control it externally; omit to let the viewer own the state.
1863
+ */
1864
+ interactive?: boolean | undefined;
1865
+ /** Render the built-in Watching ⇄ Take control toggle (default true). */
1866
+ showControlToggle?: boolean | undefined;
1867
+ scaleViewport?: boolean | undefined;
1868
+ /** Custom RFB factory (tests / a WebRTC swap). Defaults to lazy @novnc/novnc. */
1869
+ rfbFactory?: DesktopRfbFactory | undefined;
1870
+ /**
1871
+ * Consent gate for the un-redacted (and possibly shared) pixel plane. Rendered
1872
+ * BEFORE connecting whenever the desktop requires acknowledgment that hasn't
1873
+ * been given. Call `onAccept` to record consent (the host wires it to
1874
+ * `client.acknowledgeStream` + a re-negotiate). When omitted, a default
1875
+ * banner is shown.
1876
+ */
1877
+ renderConsentGate?: ((onAccept: () => void, shared: boolean) => ReactNode) | undefined;
1878
+ /** Called when the default consent gate's accept button is pressed. */
1879
+ onAcknowledge?: (() => void) | undefined;
1880
+ /**
1881
+ * Whether the host has the viewer attach engaged (i.e. the user has opted into
1882
+ * watching — the parent's `watchDesktop`/`attachDesktop`). Drives the
1883
+ * cold-state behaviour: when watching, a cold-but-warmable lease AUTO-WARMS
1884
+ * (and re-warms when the box drains) instead of dead-ending. When omitted we
1885
+ * infer it from a recorded consent (the default gate's accept), so the
1886
+ * component still self-heals after the first acknowledgment.
1887
+ */
1888
+ watching?: boolean | undefined;
1889
+ /**
1890
+ * Request a (re)warm of the sandbox WITHOUT re-acknowledging (the consent has
1891
+ * already been recorded — only the box drained). The host wires this to
1892
+ * "engage the viewer attach + re-negotiate". Called automatically when a
1893
+ * watched desktop is found cold-but-warmable, and behind the manual retry on
1894
+ * the warming notice. Distinct from `onAcknowledge`, which is the FIRST,
1895
+ * consent-bearing warm.
1896
+ */
1897
+ onWarm?: (() => void) | undefined;
1898
+ /** Shown when transport is null (headless backend / degraded / disabled). */
1899
+ renderUnavailable?: ((reason: CapabilityUnavailableReason | null) => ReactNode) | undefined;
1900
+ /** Shown while the box is cold/warming (no live address yet). */
1901
+ renderWarming?: (() => ReactNode) | undefined;
1902
+ /** Shown when the per-session viewer cap (429) was hit. */
1903
+ renderViewerCap?: (() => ReactNode) | undefined;
1904
+ /** Surface the 429 cap state from `useSessionCapabilities().viewerCapReached`. */
1905
+ viewerCapReached?: boolean | undefined;
1906
+ /**
1907
+ * Connect watchdog (ms): if a live url is present but the RFB hasn't connected
1908
+ * within this window, surface a "Couldn't connect" + Reconnect instead of an
1909
+ * eternal idle scrim. Default 13000. 0 disables the watchdog.
1910
+ */
1911
+ connectTimeoutMs?: number | undefined;
1912
+ className?: string | undefined;
1913
+ };
1914
+ /**
1915
+ * The desktop surface: a noVNC client connecting to the Channel-B scoped tunnel
1916
+ * URL from the capability doc. Owns the mount `<div ref>`, drives
1917
+ * `useDesktopStream` (SSR-safe lazy RFB), and renders a real
1918
+ * cold → warming → connecting → connected → error state machine with live
1919
+ * feedback (spinners, transitions) — never a dead black box with stale text.
1920
+ *
1921
+ * The read-only vs interactive decision is enforced server-first
1922
+ * (`capability.mode`): when the deployment advertises mode "interactive" the
1923
+ * viewer can TAKE CONTROL and drive the mouse & keyboard into the box's :0; a
1924
+ * "read-only" deployment disables the take-control affordance (graceful, with a
1925
+ * reason).
1926
+ *
1927
+ * Warming: a cold-but-warmable lease (`reason: "lease_cold"`) is NOT a dead end.
1928
+ * When the user is watching (consented), the viewer asks the host to (re)warm
1929
+ * the box (`onWarm`) and shows a "Warming…" spinner; if the box later drains to
1930
+ * cold it re-warms. Genuinely-unavailable surfaces (headless/policy/os/backend)
1931
+ * keep a clear, static unavailable notice.
1932
+ */
1933
+ declare function DesktopViewer({ capability, interactive, showControlToggle, scaleViewport, rfbFactory, renderConsentGate, onAcknowledge, watching, onWarm, renderUnavailable, renderWarming, renderViewerCap, viewerCapReached, connectTimeoutMs, className, }: DesktopViewerProps): react_jsx_runtime.JSX.Element;
1934
+
1935
+ type WorkspaceTab = {
1936
+ id: string;
1937
+ label: ReactNode;
1938
+ /** Rendered as the active surface. */
1939
+ content: ReactNode;
1940
+ /** A small badge after the label (e.g. dirty count, live pill). */
1941
+ badge?: ReactNode | undefined;
1942
+ };
1943
+ type WorkspaceDockProps = {
1944
+ /** The chat / primary pane shown beside the dock. */
1945
+ primary: ReactNode;
1946
+ tabs: WorkspaceTab[];
1947
+ /** Controlled active tab. Falls back to the first tab. */
1948
+ activeTab?: string | undefined;
1949
+ onActiveTabChange?: ((id: string) => void) | undefined;
1950
+ /** Persisted layout id (localStorage key) for react-resizable-panels. */
1951
+ autoSaveId?: string | undefined;
1952
+ /** Default dock width as a percent of the session area. */
1953
+ defaultSize?: number | undefined;
1954
+ minSize?: number | undefined;
1955
+ maxSize?: number | undefined;
1956
+ className?: string | undefined;
1957
+ };
1958
+ /**
1959
+ * The resizable / collapsible / maximizable right-hand Workspace dock. Replaces
1960
+ * a fixed grid column: drag the separator to set width, collapse to a thin rail
1961
+ * that re-opens on click, and maximize to a full-workspace overlay (Esc /
1962
+ * restore button returns). Layout persists via `useDefaultLayout` keyed on
1963
+ * `autoSaveId`. Maximize is a mode ABOVE the Group (a `fixed inset-0` overlay) —
1964
+ * pushing a Panel to ~100% still fights min sizes and leaves a chat sliver.
1965
+ */
1966
+ declare function WorkspaceDock({ primary, tabs, activeTab, onActiveTabChange, autoSaveId, defaultSize, minSize, maxSize, className, }: WorkspaceDockProps): react_jsx_runtime.JSX.Element;
1967
+
1968
+ /**
1969
+ * Reconstruct a unified-diff patch string for a single `GitFileDiff` so it can
1970
+ * be fed to a generic patch renderer (e.g. Pierre's `PatchDiff`). The hook
1971
+ * already carries per-line old/new numbers and a hunk header, so we emit a
1972
+ * conventional `--- / +++ / @@` patch the parser understands.
1973
+ */
1974
+ declare function gitFileDiffToPatch(file: GitFileDiff): string;
1975
+
1976
+ /**
1977
+ * Derive an xterm `ITheme` subset from the live OKLCH `--og-*` token system (or
1978
+ * the app's `--color-*` aliases). Reads the COMPUTED values so xterm — which
1979
+ * paints into a canvas and can't consume CSS vars — gets concrete colors. Call
1980
+ * on mount and re-derive on a `data-og-theme` flip.
1981
+ *
1982
+ * SSR-safe: returns undefined off the DOM (the caller keeps xterm's defaults).
1983
+ */
1984
+ declare function xtermThemeFromTokens(root?: HTMLElement | null): XtermTheme | undefined;
1985
+
965
1986
  /** Merge class names with Tailwind-aware conflict resolution. */
966
1987
  declare function cn(...inputs: ClassValue[]): string;
967
1988
 
@@ -976,4 +1997,4 @@ declare function stringifyPayload(value: unknown): string;
976
1997
  /** JSON.parse that returns `undefined` instead of throwing. */
977
1998
  declare function tryParseJson(text: string): unknown;
978
1999
 
979
- export { type AgentMessageItem, ChatComposer, type ChatComposerProps, type ClientOverride, type CommandContext, CommandPalette, type CommandPaletteProps, type CommandResult, type ComposerMode, type ComposerSendExtras, type ComposerState, type ConfirmState, type FileAttachment, FleetTile, type FleetTileProps, type GoalItem, Markdown, type MarkdownProps, MessageTimeline, type MessageTimelineProps, ModelPicker, type ModelPickerProps, type Notice, type NoticeItem, type OpenGeniContextValue, OpenGeniProvider, type OpenGeniProviderProps, type ParsedCommandLine, type PendingApproval, type ReasoningItem, SESSION_STATUS_META, type SandboxItem, type SessionClientLike, type SessionEventsConnectionState, SessionStatus, type SessionStatusItem, type SessionStatusMeta, type SessionStatusProps, type SlashArg, type SlashCommand, type SlashCommandContext, type SlashCommandHandlers, StatusDot, type StatusDotProps, type TimelineGroup, type TimelineItem, type ToolCallItem, type UseAvailableModelsOptions, type UseAvailableModelsResult, type UseBillingUsageOptions, type UseBillingUsageResult, type UseComposerOptions, type UseEnvironmentsOptions, type UseEnvironmentsResult, type UseFileAttachmentsOptions, type UseFileAttachmentsResult, type UseGoalOptions, type UseGoalResult, type UsePacksOptions, type UsePacksResult, type UseScheduledTasksOptions, type UseScheduledTasksResult, type UseSessionControlOptions, type UseSessionControlResult, type UseSessionEventsOptions, type UseSessionEventsResult, type UseSessionOptions, type UseSessionResult, type UseSlashCommandsOptions, type UseSlashCommandsResult, type UseTurnQueueOptions, type UseTurnQueueResult, type UseWorkspaceSessionsOptions, type UseWorkspaceSessionsResult, type UseWorkspacesOptions, type UseWorkspacesResult, type UserMessageItem, type WorkerItem, activeTurnFromTurns, applyTurnEdit, applyTurnRemoval, applyTurnReorder, approvalsFromRequiresAction, argHint, buildTimeline, cn, compactPayloadPreview, composeSendInput, defaultCommands, extractSessionRef, filterCommands, firstMissingRequiredArg, formatBytes, formatRelativeTime, groupTimeline, hasPermission, isGoalEvent, isTurnQueueEvent, matchCommand, parseCommandLine, projectPendingApprovals, queueFromTurns, sessionDisplayTitle, sessionStatusFromEvents, shouldSubmitOnKey, stringifyPayload, toolDisplayName, truncate, tryParseJson, useAvailableModels, useBillingUsage, useComposer, useEnvironments, useFileAttachments, useGoal, useOpenGeni, useOpenGeniClient, usePacks, useScheduledTasks, useSession, useSessionControl, useSessionEvents, useSlashCommands, useTurnQueue, useWorkspaceSessions, useWorkspaces };
2000
+ export { ActivityDisclosure, type ActivityDisclosureProps, type ActivityItem, ActivityRail, type ActivityRailProps, type AgentMessageItem, type ApplyPatchOperation, BodyNote, ChatComposer, type ChatComposerProps, type ClientOverride, CodeEditor, type CodeEditorProps, type CommandContext, CommandPalette, type CommandPaletteProps, type CommandResult, type ComposerMode, type ComposerSendExtras, type ComposerState, type ConfirmState, type CreateToolRegistryOptions, DesktopViewer, type DesktopViewerProps, type DiffTheme, DiffView, type DiffViewProps, type DisclosureChip, DisclosureDefaultsProvider, type FileAttachment, FileBrowser, type FileBrowserProps, type FileTreeNode, type FileTreeStatus, FleetTile, type FleetTileProps, type GoalItem, LightboxProvider, Markdown, type MarkdownProps, MediaEmpty, MediaSkeleton, MessageTimeline, type MessageTimelineProps, ModelPicker, type ModelPickerProps, type Notice, type NoticeItem, type OpenGeniContextValue, OpenGeniProvider, type OpenGeniProviderProps, type ParsedCommandLine, PayloadBlock, type PendingApproval, PierreDiff, type PierreDiffProps, PierreFile, type PierreFileProps, type ReasoningItem, SESSION_STATUS_META, SandboxFiles, type SandboxFilesProps, type SandboxItem, SandboxTerminal, type SandboxTerminalProps, ScreenshotFigure, type SessionCapabilitiesState, type SessionClientLike, type SessionEventsConnectionState, SessionStatus, type SessionStatusItem, type SessionStatusMeta, type SessionStatusProps, type SlashArg, type SlashCommand, type SlashCommandContext, type SlashCommandHandlers, StatusDot, type StatusDotProps, TermBlock, type TerminalChunk, type TerminalStreamStatus, Thumbnail, type TimelineGroup, type TimelineItem, TimelineRow, type ToolCallItem, type ToolRegistry, type ToolRegistryEntry, type ToolRenderer, type ToolRendererProps, type TurnOutcome, TurnSummary, type TurnSummaryProps, type UseAvailableModelsOptions, type UseAvailableModelsResult, type UseBillingUsageOptions, type UseBillingUsageResult, type UseComposerOptions, type UseDesktopStreamOptions, type UseDesktopStreamResult, type UseEnvironmentsOptions, type UseEnvironmentsResult, type UseFileAttachmentsOptions, type UseFileAttachmentsResult, type UseGoalOptions, type UseGoalResult, type UsePacksOptions, type UsePacksResult, type UseSandboxFilesOptions, type UseSandboxFilesResult, type UseSandboxGitOptions, type UseSandboxGitResult, type UseSandboxTerminalOptions, type UseSandboxTerminalResult, type UseScheduledTasksOptions, type UseScheduledTasksResult, type UseSessionCapabilitiesOptions, type UseSessionCapabilitiesResult, type UseSessionControlOptions, type UseSessionControlResult, type UseSessionEventsOptions, type UseSessionEventsResult, type UseSessionOptions, type UseSessionResult, type UseSlashCommandsOptions, type UseSlashCommandsResult, type UseTerminalStreamOptions, type UseTerminalStreamResult, type UseTurnQueueOptions, type UseTurnQueueResult, type UseWorkspaceSessionsOptions, type UseWorkspaceSessionsResult, type UseWorkspacesOptions, type UseWorkspacesResult, type UserMessageItem, type WorkerItem, WorkspaceDock, type WorkspaceDockProps, type WorkspaceTab, type XtermTheme, activeTurnFromTurns, applyPatchOps, applyTurnEdit, applyTurnRemoval, applyTurnReorder, approvalsFromRequiresAction, argHint, buildTimeline, cn, composeSendInput, controlCaret, createDefaultToolRegistry, createToolRegistry, defaultCommands, defaultToolRegistry, execTruncated, extractSessionRef, filterCommands, firstMissingRequiredArg, formatBytes, formatRelativeTime, gitFileDiffToPatch, groupTimeline, hasPermission, isApplyPatch, isExecSessionLostBanner, isGoalEvent, isTurnQueueEvent, languageForPath, looksBinary, matchCommand, parseCommandLine, parseExecBannerSessionId, parseToolArgs, projectPendingApprovals, queueFromTurns, rawTypeOf, redactSecrets, sandboxCommandExitCode, sessionDisplayTitle, sessionStatusFromEvents, shouldSubmitOnKey, stringifyPayload, stripExecBanner, tailPeek, toolDisplayName, truncate, tryParseJson, unwrapMcpOutput, useAvailableModels, useBillingUsage, useComposer, useDesktopStream, useEnvironments, useFileAttachments, useGoal, useLightbox, useLightboxOptional, useOpenGeni, useOpenGeniClient, usePacks, useSandboxFiles, useSandboxGit, useSandboxTerminal, useScheduledTasks, useSession, useSessionCapabilities, useSessionControl, useSessionEvents, useSlashCommands, useTerminalStream, useTurnQueue, useWorkspaceSessions, useWorkspaces, v4aToGitFileDiff, xtermThemeFromTokens };