@opengeni/react 0.3.0 → 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.
- package/dist/index.d.ts +1035 -14
- package/dist/index.js +6867 -1884
- package/dist/index.js.map +1 -1
- package/package.json +65 -2
- package/src/client.ts +21 -0
- package/src/components/code-editor.tsx +398 -0
- package/src/components/desktop-viewer.tsx +647 -0
- package/src/components/diff-view.tsx +230 -0
- package/src/components/file-browser.tsx +838 -0
- package/src/components/message-timeline.tsx +70 -196
- package/src/components/pierre-diff.tsx +140 -0
- package/src/components/pierre-file.tsx +142 -0
- package/src/components/sandbox-files.tsx +509 -0
- package/src/components/sandbox-terminal.tsx +425 -0
- package/src/components/workspace-dock.tsx +247 -0
- package/src/hooks/use-desktop-stream.ts +214 -0
- package/src/hooks/use-sandbox-files.ts +670 -0
- package/src/hooks/use-sandbox-git.ts +105 -0
- package/src/hooks/use-sandbox-terminal.ts +226 -0
- package/src/hooks/use-session-capabilities.ts +415 -0
- package/src/hooks/use-terminal-stream.ts +207 -0
- package/src/index.ts +111 -2
- package/src/lib/cn.ts +20 -1
- package/src/lib/git-patch.ts +37 -0
- package/src/lib/use-theme-type.ts +40 -0
- package/src/lib/xterm-theme.ts +34 -0
- package/src/timeline/activity-rail.tsx +207 -0
- package/src/timeline/disclosure-context.tsx +34 -0
- package/src/timeline/index.ts +85 -0
- package/src/timeline/parsers.ts +248 -0
- package/src/{timeline.ts → timeline/projection.ts} +59 -134
- package/src/timeline/registry.ts +96 -0
- package/src/timeline/screenshot-lightbox.tsx +152 -0
- package/src/timeline/shared.tsx +481 -0
- package/src/timeline/tool-diff.tsx +91 -0
- package/src/timeline/tool-renderers.tsx +882 -0
- package/src/timeline/turn-summary.tsx +125 -0
- package/src/timeline/types.ts +131 -0
- package/src/types/external.d.ts +7 -0
- 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
|
-
|
|
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
|
-
|
|
142
|
-
|
|
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:
|
|
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
|
-
|
|
162
|
-
|
|
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,
|
|
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 };
|