@opengeni/react 0.28.2 → 0.32.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/approvals.d.ts +14 -0
- package/dist/{chunk-M7X4JZOD.js → chunk-4QOQ2DSR.js} +8 -1
- package/dist/chunk-4QOQ2DSR.js.map +1 -0
- package/dist/{chunk-HQFPO7VX.js → chunk-7CJOAW3V.js} +24 -3
- package/dist/{chunk-HQFPO7VX.js.map → chunk-7CJOAW3V.js.map} +1 -1
- package/dist/{chunk-PMSGE233.js → chunk-A2WITZTI.js} +377 -113
- package/dist/chunk-A2WITZTI.js.map +1 -0
- package/dist/{chunk-BC6RKIHS.js → chunk-GZ4KR67U.js} +11 -11
- package/dist/{chunk-4F2YLLHP.js → chunk-KZRUYCL4.js} +14 -17
- package/dist/chunk-KZRUYCL4.js.map +1 -0
- package/dist/{chunk-OCHBZ2X7.js → chunk-TCCE5ZU5.js} +192 -28
- package/dist/chunk-TCCE5ZU5.js.map +1 -0
- package/dist/chunk-U255M5EZ.js +178 -0
- package/dist/chunk-U255M5EZ.js.map +1 -0
- package/dist/{chunk-XVVQP7A4.js → chunk-WY2QN2CX.js} +2539 -2174
- package/dist/chunk-WY2QN2CX.js.map +1 -0
- package/dist/chunk-ZNNE2VES.js +6413 -0
- package/dist/chunk-ZNNE2VES.js.map +1 -0
- package/dist/client.d.ts +33 -0
- package/dist/commands/index.d.ts +3 -0
- package/dist/commands/registry.d.ts +41 -0
- package/dist/commands/types.d.ts +85 -0
- package/dist/components/approval-surface.d.ts +28 -0
- package/dist/components/chat-composer.d.ts +51 -0
- package/dist/components/code-editor.d.ts +43 -0
- package/dist/components/command-palette.d.ts +25 -0
- package/dist/components/composer-transcription-control.d.ts +36 -0
- package/dist/components/composer.d.ts +277 -0
- package/dist/components/copy-button.d.ts +26 -0
- package/dist/components/desktop-viewer.d.ts +85 -0
- package/dist/components/diff-view.d.ts +38 -0
- package/dist/components/enrollment-consent.d.ts +33 -0
- package/dist/components/enrollment-device-flow.d.ts +27 -0
- package/dist/components/file-browser.d.ts +47 -0
- package/dist/components/fleet-tile.d.ts +18 -0
- package/dist/components/human-input-form.d.ts +47 -0
- package/dist/components/machine-card.d.ts +21 -0
- package/dist/components/machine-dock-bar.d.ts +31 -0
- package/dist/components/machine-health-pill.d.ts +9 -0
- package/dist/components/machine-metrics.d.ts +15 -0
- package/dist/components/machine-status-pill.d.ts +54 -0
- package/dist/components/machines/health.d.ts +25 -0
- package/dist/components/machines/machine-detail.d.ts +14 -0
- package/dist/components/machines/metric-history-chart.d.ts +24 -0
- package/dist/components/machines/metric-sparkline.d.ts +9 -0
- package/dist/components/machines/series.d.ts +24 -0
- package/dist/components/machines-dashboard.d.ts +30 -0
- package/dist/components/markdown.d.ts +31 -0
- package/dist/components/message-timeline.d.ts +98 -0
- package/dist/components/model-picker.d.ts +19 -0
- package/dist/components/pierre-diff.d.ts +34 -0
- package/dist/components/pierre-file.d.ts +27 -0
- package/dist/components/queue-draft-policy.d.ts +7 -0
- package/dist/components/queue-surface-implementation.d.ts +20 -0
- package/dist/components/queue-surface-state.d.ts +12 -0
- package/dist/components/queue-surface.d.ts +12 -0
- package/dist/components/sandbox-files.d.ts +49 -0
- package/dist/components/sandbox-terminal.d.ts +123 -0
- package/dist/components/sandbox-workspace.d.ts +128 -0
- package/dist/components/session-chrome.d.ts +70 -0
- package/dist/components/session-status.d.ts +25 -0
- package/dist/components/soften-streaming-markdown.d.ts +13 -0
- package/dist/components/stream-reveal.d.ts +37 -0
- package/dist/components/tip-follow.d.ts +139 -0
- package/dist/components/tooltip.d.ts +16 -0
- package/dist/components/workbench-changes.d.ts +34 -0
- package/dist/components/workspace-dock.d.ts +35 -0
- package/dist/composer.d.ts +11 -7
- package/dist/composer.js +9 -6
- package/dist/hooks/internal.d.ts +46 -0
- package/dist/hooks/use-available-models.d.ts +37 -0
- package/dist/hooks/use-billing-usage.d.ts +26 -0
- package/dist/hooks/use-codex-accounts.d.ts +69 -0
- package/dist/{use-composer-ClHy1rkL.d.ts → hooks/use-composer.d.ts} +16 -24
- package/dist/hooks/use-desktop-stream.d.ts +43 -0
- package/dist/hooks/use-environments.d.ts +35 -0
- package/dist/{use-file-attachments-BmT8WtqO.d.ts → hooks/use-file-attachments.d.ts} +6 -9
- package/dist/hooks/use-goal.d.ts +46 -0
- package/dist/hooks/use-human-input.d.ts +26 -0
- package/dist/hooks/use-last-started-turn-policy.d.ts +27 -0
- package/dist/hooks/use-machine-chip.d.ts +54 -0
- package/dist/hooks/use-machines.d.ts +81 -0
- package/dist/hooks/use-packs.d.ts +27 -0
- package/dist/hooks/use-relay-frame-stream.d.ts +53 -0
- package/dist/hooks/use-rigs.d.ts +87 -0
- package/dist/hooks/use-sandbox-files.d.ts +108 -0
- package/dist/hooks/use-sandbox-git.d.ts +58 -0
- package/dist/hooks/use-sandbox-terminal.d.ts +62 -0
- package/dist/hooks/use-scheduled-tasks.d.ts +15 -0
- package/dist/hooks/use-session-capabilities.d.ts +83 -0
- package/dist/hooks/use-session-control.d.ts +22 -0
- package/dist/hooks/use-session-events.d.ts +92 -0
- package/dist/hooks/use-session-lineage.d.ts +17 -0
- package/dist/hooks/use-session-mcp-approval-policy.d.ts +23 -0
- package/dist/hooks/use-session.d.ts +23 -0
- package/dist/hooks/use-slash-commands.d.ts +66 -0
- package/dist/hooks/use-terminal-stream.d.ts +46 -0
- package/dist/hooks/use-transcription.d.ts +73 -0
- package/dist/hooks/use-turn-queue.d.ts +44 -0
- package/dist/hooks/use-voice-input.d.ts +25 -0
- package/dist/hooks/use-windowed-sections.d.ts +42 -0
- package/dist/hooks/use-workspace-capture.d.ts +49 -0
- package/dist/hooks/use-workspace-edit.d.ts +73 -0
- package/dist/hooks/use-workspace-sessions.d.ts +30 -0
- package/dist/hooks/use-workspaces.d.ts +22 -0
- package/dist/human-input.d.ts +18 -0
- package/dist/index.d.ts +144 -2119
- package/dist/index.js +421 -324
- package/dist/index.js.map +1 -1
- package/dist/lib/clipboard.d.ts +7 -0
- package/dist/lib/cn.d.ts +3 -0
- package/dist/lib/format.d.ts +48 -0
- package/dist/lib/git-patch.d.ts +8 -0
- package/dist/lib/motion-inspect.d.ts +5 -0
- package/dist/lib/motion.d.ts +14 -0
- package/dist/lib/noto-sans-arabic-loader.d.ts +1 -0
- package/dist/lib/noto-sans-jp-loader.generated.d.ts +1 -0
- package/dist/lib/relay-wire.d.ts +30 -0
- package/dist/lib/use-portal-token-style.d.ts +9 -0
- package/dist/lib/use-theme-type.d.ts +5 -0
- package/dist/lib/use-unicode-fonts.d.ts +12 -0
- package/dist/lib/xterm-renderer.d.ts +19 -0
- package/dist/lib/xterm-theme.d.ts +75 -0
- package/dist/machines.d.ts +30 -413
- package/dist/machines.js +3 -3
- package/dist/model-policy.d.ts +32 -0
- package/dist/model-policy.js +33 -0
- package/dist/model-policy.js.map +1 -0
- package/dist/provider.d.ts +16 -0
- package/dist/{queue-surface-implementation-UQ535OKQ.js → queue-surface-implementation-THPAKGMD.js} +2 -2
- package/dist/{queue-surface-implementation-UQ535OKQ.js.map → queue-surface-implementation-THPAKGMD.js.map} +1 -1
- package/dist/session-context.d.ts +82 -0
- package/dist/session-ui.d.ts +10 -7
- package/dist/session-ui.js +9 -5
- package/dist/session.d.ts +28 -6
- package/dist/session.js +11 -11
- package/dist/timeline/activity-rail.d.ts +19 -0
- package/dist/timeline/disclosure-context.d.ts +14 -0
- package/dist/timeline/entrance.d.ts +14 -0
- package/dist/timeline/fleet-decision-projection.d.ts +9 -0
- package/dist/timeline/fleet-decision-row.d.ts +11 -0
- package/dist/timeline/fold-memory.d.ts +15 -0
- package/dist/timeline/index.d.ts +18 -0
- package/dist/timeline/parsers.d.ts +96 -0
- package/dist/timeline/projection.d.ts +38 -0
- package/dist/timeline/registry.d.ts +40 -0
- package/dist/timeline/screenshot-lightbox.d.ts +26 -0
- package/dist/timeline/seen-activity-ids.d.ts +2 -0
- package/dist/timeline/shared.d.ts +125 -0
- package/dist/timeline/tool-diff.d.ts +8 -0
- package/dist/timeline/tool-display-name.d.ts +10 -0
- package/dist/timeline/tool-renderers.d.ts +5 -0
- package/dist/timeline/turn-summary.d.ts +116 -0
- package/dist/{use-turn-queue-Drm_ypue.d.ts → timeline/types.d.ts} +57 -67
- package/dist/types/machines.d.ts +11 -0
- package/package.json +8 -4
- package/src/client.ts +1 -0
- package/src/components/composer-transcription-control.tsx +278 -130
- package/src/components/composer.tsx +20 -15
- package/src/components/copy-button.tsx +127 -0
- package/src/components/markdown.tsx +231 -32
- package/src/components/message-timeline.tsx +1382 -378
- package/src/components/model-picker.tsx +83 -43
- package/src/components/queue-surface-implementation.tsx +1 -1
- package/src/components/session-chrome.tsx +942 -0
- package/src/components/soften-streaming-markdown.ts +205 -0
- package/src/components/stream-reveal.ts +195 -0
- package/src/components/tip-follow.ts +459 -0
- package/src/components/tooltip.tsx +103 -0
- package/src/composer.ts +6 -0
- package/src/hooks/internal.ts +30 -4
- package/src/hooks/use-available-models.ts +51 -4
- package/src/hooks/use-composer.ts +24 -18
- package/src/hooks/use-last-started-turn-policy.ts +95 -0
- package/src/hooks/use-session-events.ts +359 -5
- package/src/hooks/use-voice-input.ts +232 -0
- package/src/index.ts +49 -1
- package/src/lib/clipboard.ts +58 -0
- package/src/lib/format.ts +18 -0
- package/src/lib/motion-inspect.ts +5 -0
- package/src/lib/motion.ts +80 -0
- package/src/model-policy.ts +210 -0
- package/src/session-ui.ts +7 -0
- package/src/session.ts +2 -0
- package/src/timeline/activity-rail.tsx +46 -7
- package/src/timeline/entrance.tsx +10 -0
- package/src/timeline/fold-memory.ts +52 -0
- package/src/timeline/index.ts +11 -1
- package/src/timeline/projection.ts +252 -47
- package/src/timeline/seen-activity-ids.ts +19 -0
- package/src/timeline/shared.tsx +1 -1
- package/src/timeline/tool-renderers.tsx +75 -6
- package/src/timeline/turn-summary.tsx +387 -97
- package/src/timeline/types.ts +47 -0
- package/styles/index.css +99 -7
- package/styles/tokens.css +44 -3
- package/dist/chunk-4F2YLLHP.js.map +0 -1
- package/dist/chunk-M7X4JZOD.js.map +0 -1
- package/dist/chunk-OCHBZ2X7.js.map +0 -1
- package/dist/chunk-PMSGE233.js.map +0 -1
- package/dist/chunk-WAA247AB.js +0 -3858
- package/dist/chunk-WAA247AB.js.map +0 -1
- package/dist/chunk-XVVQP7A4.js.map +0 -1
- package/dist/composer-BMzimGTO.d.ts +0 -528
- package/dist/session-C3tIXLim.d.ts +0 -264
- package/dist/session-context-CAjlaeZb.d.ts +0 -84
- package/dist/session-ui-B_7cfN5u.d.ts +0 -259
- /package/dist/{chunk-BC6RKIHS.js.map → chunk-GZ4KR67U.js.map} +0 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { CreateVariableSetRequest, UpdateVariableSetRequest, VariableSet, VariableSetVariableMetadata } from "@opengeni/sdk";
|
|
2
|
+
import { type ClientOverride } from "../provider";
|
|
3
|
+
export type UseVariableSetsOptions = ClientOverride & {
|
|
4
|
+
pollIntervalMs?: number | undefined;
|
|
5
|
+
enabled?: boolean | undefined;
|
|
6
|
+
};
|
|
7
|
+
export type UseVariableSetsResult = {
|
|
8
|
+
variableSets: VariableSet[];
|
|
9
|
+
loading: boolean;
|
|
10
|
+
error: Error | null;
|
|
11
|
+
refresh: () => Promise<void>;
|
|
12
|
+
create: (request: CreateVariableSetRequest) => Promise<VariableSet | null>;
|
|
13
|
+
update: (variableSetId: string, request: UpdateVariableSetRequest) => Promise<VariableSet | null>;
|
|
14
|
+
remove: (variableSetId: string) => Promise<boolean>;
|
|
15
|
+
/** Set/rotate a variable. Values are write-only — reads expose metadata only. */
|
|
16
|
+
setVariable: (variableSetId: string, name: string, value: string) => Promise<VariableSetVariableMetadata | null>;
|
|
17
|
+
deleteVariable: (variableSetId: string, name: string) => Promise<boolean>;
|
|
18
|
+
mutating: boolean;
|
|
19
|
+
mutationError: Error | null;
|
|
20
|
+
clearMutationError: () => void;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Variable sets (named, encrypted variable sets attached to sessions
|
|
24
|
+
* and scheduled tasks). Variable values are write-only end to end: this hook
|
|
25
|
+
* never sees a value after it is sent.
|
|
26
|
+
*/
|
|
27
|
+
export declare function useVariableSets(options?: UseVariableSetsOptions): UseVariableSetsResult;
|
|
28
|
+
/** @deprecated use UseVariableSetsOptions */
|
|
29
|
+
export type UseEnvironmentsOptions = UseVariableSetsOptions;
|
|
30
|
+
/** @deprecated use UseVariableSetsResult */
|
|
31
|
+
export type UseEnvironmentsResult = UseVariableSetsResult & {
|
|
32
|
+
environments: VariableSet[];
|
|
33
|
+
};
|
|
34
|
+
/** @deprecated use useVariableSets */
|
|
35
|
+
export declare function useEnvironments(options?: UseEnvironmentsOptions): UseEnvironmentsResult;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { FileAsset, FileResourceRef } from
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
type UseFileAttachmentsOptions = EmbeddedFileAttachmentClientOverride & {
|
|
1
|
+
import type { FileAsset, FileResourceRef } from "@opengeni/sdk";
|
|
2
|
+
import { type EmbeddedFileAttachmentClientOverride } from "../session-context";
|
|
3
|
+
export type UseFileAttachmentsOptions = EmbeddedFileAttachmentClientOverride & {
|
|
5
4
|
/**
|
|
6
5
|
* Only files matching this predicate are accepted by {@link
|
|
7
6
|
* UseFileAttachmentsResult.addFromPaste} (the clipboard path). Defaults to
|
|
@@ -11,7 +10,7 @@ type UseFileAttachmentsOptions = EmbeddedFileAttachmentClientOverride & {
|
|
|
11
10
|
*/
|
|
12
11
|
pasteFilter?: ((file: File) => boolean) | undefined;
|
|
13
12
|
};
|
|
14
|
-
type FileAttachment = {
|
|
13
|
+
export type FileAttachment = {
|
|
15
14
|
id: string;
|
|
16
15
|
name: string;
|
|
17
16
|
contentType: string;
|
|
@@ -23,7 +22,7 @@ type FileAttachment = {
|
|
|
23
22
|
previewUrl?: string | undefined;
|
|
24
23
|
error?: string | undefined;
|
|
25
24
|
};
|
|
26
|
-
type UseFileAttachmentsResult = {
|
|
25
|
+
export type UseFileAttachmentsResult = {
|
|
27
26
|
attachments: FileAttachment[];
|
|
28
27
|
/**
|
|
29
28
|
* `FileResourceRef[]` for every attachment that finished uploading — feed
|
|
@@ -71,6 +70,4 @@ type UseFileAttachmentsResult = {
|
|
|
71
70
|
* `resources`. Workspace-scoped, so it resolves both client and workspace from
|
|
72
71
|
* the {@link OpenGeniProvider} (or a per-call `{ client, workspaceId }`).
|
|
73
72
|
*/
|
|
74
|
-
declare function useFileAttachments(options?: UseFileAttachmentsOptions): UseFileAttachmentsResult;
|
|
75
|
-
|
|
76
|
-
export { type FileAttachment as F, type UseFileAttachmentsResult as U, type UseFileAttachmentsOptions as a, useFileAttachments as u };
|
|
73
|
+
export declare function useFileAttachments(options?: UseFileAttachmentsOptions): UseFileAttachmentsResult;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { type SessionEvent, type SessionGoal } from "@opengeni/sdk";
|
|
2
|
+
import { type EmbeddedGoalClientOverride } from "../session-context";
|
|
3
|
+
import { type SessionEventFeedOptions } from "./internal";
|
|
4
|
+
/** Event types that change the session goal (set/updated/completed/paused/...). */
|
|
5
|
+
export declare function isGoalEvent(event: Pick<SessionEvent, "type">): boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Events that can change the server-authoritative continuation projection.
|
|
8
|
+
* The projection is derived from durable turn, session, control, and system
|
|
9
|
+
* update state, so those events refresh the goal without model polling.
|
|
10
|
+
*/
|
|
11
|
+
export declare function isGoalRefreshEvent(event: Pick<SessionEvent, "type">): boolean;
|
|
12
|
+
export type UseGoalOptions = EmbeddedGoalClientOverride & SessionEventFeedOptions & {
|
|
13
|
+
/** Optional safety-net polling (ms). Off by default — event refreshes drive updates. */
|
|
14
|
+
pollIntervalMs?: number | undefined;
|
|
15
|
+
};
|
|
16
|
+
export type UseGoalResult = {
|
|
17
|
+
/** The session goal, or null when the session has none. */
|
|
18
|
+
goal: SessionGoal | null;
|
|
19
|
+
/** Convenience flags over `goal.status`. */
|
|
20
|
+
isActive: boolean;
|
|
21
|
+
isPaused: boolean;
|
|
22
|
+
isCompleted: boolean;
|
|
23
|
+
loading: boolean;
|
|
24
|
+
error: Error | null;
|
|
25
|
+
refresh: () => Promise<void>;
|
|
26
|
+
/** Pause the goal loop (PATCH status=paused). */
|
|
27
|
+
pause: (rationale?: string) => Promise<SessionGoal | null>;
|
|
28
|
+
/** Resume a paused goal: resets counters and re-arms continuations. */
|
|
29
|
+
resume: () => Promise<SessionGoal | null>;
|
|
30
|
+
/** Clear the session goal; goal-less sessions remain a successful no-op. */
|
|
31
|
+
clearGoal: () => Promise<void>;
|
|
32
|
+
/** Alias for `clearGoal`. */
|
|
33
|
+
deleteGoal: () => Promise<void>;
|
|
34
|
+
/** True while a pause/resume/clear is in flight. */
|
|
35
|
+
updating: boolean;
|
|
36
|
+
mutationError: Error | null;
|
|
37
|
+
clearMutationError: () => void;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* The session's goal: state, the autonomy counters (`autoContinuations`,
|
|
41
|
+
* `noProgressStreak`), and pause/resume control. A goal-less session yields
|
|
42
|
+
* `goal: null` (the 404 is absorbed). Live-updates on goal, turn, session,
|
|
43
|
+
* control, and system-update events — pass `options.events` from
|
|
44
|
+
* `useSessionEvents` to reuse its stream.
|
|
45
|
+
*/
|
|
46
|
+
export declare function useGoal(sessionId: string | null | undefined, options?: UseGoalOptions): UseGoalResult;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { SessionEvent, SessionHumanInputRequest, SubmitHumanInputResponseRequest } from "@opengeni/sdk";
|
|
2
|
+
import { type EmbeddedHumanInputClientOverride } from "../session-context";
|
|
3
|
+
import { type SessionEventFeedOptions } from "./internal";
|
|
4
|
+
/** Events that can create, settle, or invalidate an actionable request. */
|
|
5
|
+
export declare function isHumanInputEvent(event: Pick<SessionEvent, "type">): boolean;
|
|
6
|
+
export type UseHumanInputRequestsOptions = EmbeddedHumanInputClientOverride & SessionEventFeedOptions & {
|
|
7
|
+
/** Optional safety-net polling. Durable events drive refresh by default. */
|
|
8
|
+
pollIntervalMs?: number | undefined;
|
|
9
|
+
};
|
|
10
|
+
export type UseHumanInputRequestsResult = {
|
|
11
|
+
requests: SessionHumanInputRequest[];
|
|
12
|
+
loading: boolean;
|
|
13
|
+
error: Error | null;
|
|
14
|
+
refresh: () => Promise<void>;
|
|
15
|
+
respond: (requestId: string, response: SubmitHumanInputResponseRequest) => Promise<SessionEvent | null>;
|
|
16
|
+
respondingRequestId: string | null;
|
|
17
|
+
mutationError: Error | null;
|
|
18
|
+
clearMutationError: () => void;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Authoritative structured-human-input hook. The server's pending-request
|
|
22
|
+
* table is the read model; events only trigger reconciliation. This lets an
|
|
23
|
+
* embedded host use the same primitive with a shared event feed or its own SDK
|
|
24
|
+
* proxy without rebuilding request lifecycle logic.
|
|
25
|
+
*/
|
|
26
|
+
export declare function useHumanInputRequests(sessionId: string | null | undefined, options?: UseHumanInputRequestsOptions): UseHumanInputRequestsResult;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { LatencyMode, ReasoningEffort, SessionEvent } from "@opengeni/sdk";
|
|
2
|
+
import { type ClientOverride } from "../session-context";
|
|
3
|
+
import { type SessionEventFeedOptions } from "./internal";
|
|
4
|
+
/** Refresh when a turn actually admits — not on composer picker / queue-only changes. */
|
|
5
|
+
export declare function isLastStartedTurnPolicyEvent(event: Pick<SessionEvent, "type">): boolean;
|
|
6
|
+
export type LastStartedTurnPolicy = {
|
|
7
|
+
model: string;
|
|
8
|
+
reasoningEffort: ReasoningEffort;
|
|
9
|
+
latencyMode: LatencyMode;
|
|
10
|
+
turnId: string;
|
|
11
|
+
};
|
|
12
|
+
export type UseLastStartedTurnPolicyOptions = ClientOverride & SessionEventFeedOptions & {
|
|
13
|
+
pollIntervalMs?: number | undefined;
|
|
14
|
+
};
|
|
15
|
+
export type UseLastStartedTurnPolicyResult = {
|
|
16
|
+
/** Null until some turn has durably emitted `turn.started`. */
|
|
17
|
+
policy: LastStartedTurnPolicy | null;
|
|
18
|
+
loading: boolean;
|
|
19
|
+
error: Error | null;
|
|
20
|
+
refresh: () => Promise<void>;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Model·effort·latency of the newest admitted turn (`turn.started`). This is
|
|
24
|
+
* historical runtime truth for the session header — not the composer next-turn
|
|
25
|
+
* picker and not the frozen session creation defaults.
|
|
26
|
+
*/
|
|
27
|
+
export declare function useLastStartedTurnPolicy(sessionId: string | null | undefined, options?: UseLastStartedTurnPolicyOptions): UseLastStartedTurnPolicyResult;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { MachineState } from "@opengeni/sdk";
|
|
2
|
+
import type { SessionCapabilitiesState } from "./use-session-capabilities";
|
|
3
|
+
/** The one truthful machine indicator. Honest staleness beats
|
|
4
|
+
* fake liveness: a cold/asleep box reads "offline — as of <time>", never "live". */
|
|
5
|
+
export type MachineChipState = "live" | "waking" | "offline";
|
|
6
|
+
export type MachineChip = {
|
|
7
|
+
state: MachineChipState;
|
|
8
|
+
/** A ready-to-render label ("Live" / "Waking…" / "Offline — as of 3m ago"). */
|
|
9
|
+
label: string;
|
|
10
|
+
/** The capture time backing an offline/stale label (ISO), or null. M4 may
|
|
11
|
+
* reformat this; `label` already embeds a relative form. */
|
|
12
|
+
asOf: string | null;
|
|
13
|
+
};
|
|
14
|
+
export type DeriveMachineChipInput = {
|
|
15
|
+
/** `capabilities.liveness` — "warm" | "draining" | "cold" (or null pre-negotiation). */
|
|
16
|
+
liveness?: string | null | undefined;
|
|
17
|
+
/** `useSessionCapabilities().state` — drives the "waking" (negotiating) read. */
|
|
18
|
+
capabilitiesState?: SessionCapabilitiesState | null | undefined;
|
|
19
|
+
/** The ACTIVE machine's connection state (from `useMachines`), when known. A
|
|
20
|
+
* self-hosted machine that is `offline` cannot be remotely woken. */
|
|
21
|
+
activeMachineState?: MachineState | null | undefined;
|
|
22
|
+
/** Whether the active sandbox is a user-owned self-hosted machine (no remote wake). */
|
|
23
|
+
activeIsSelfhosted?: boolean | undefined;
|
|
24
|
+
/** An interaction (wake-on-edit, terminal focus) is actively warming the box. */
|
|
25
|
+
wantsWarm?: boolean | undefined;
|
|
26
|
+
/** The latest capture's `capturedAt` (ISO) — the "as of <time>" backing. */
|
|
27
|
+
capturedAt?: string | null | undefined;
|
|
28
|
+
/** Injectable clock for deterministic relative labels (defaults to Date.now). */
|
|
29
|
+
now?: number | undefined;
|
|
30
|
+
};
|
|
31
|
+
/** Compact relative-time for the "as of" label. Pure, no Intl dependency. */
|
|
32
|
+
export declare function formatAsOf(capturedAt: string, now: number): string;
|
|
33
|
+
/**
|
|
34
|
+
* Derive the machine-state chip from the live capability/liveness surface, the
|
|
35
|
+
* active machine's connection state, and the latest capture time. PURE (M4 renders
|
|
36
|
+
* it; the whole point is a deterministic, testable projection).
|
|
37
|
+
*
|
|
38
|
+
* Precedence:
|
|
39
|
+
* 1. warm/draining lease → **live** (a warm box always wins).
|
|
40
|
+
* 2. actively warming (negotiating, wake-on-edit, or a reconnecting/enrolling
|
|
41
|
+
* machine) → **waking**.
|
|
42
|
+
* 3. everything else (a cold/asleep box, a self-hosted machine that's offline,
|
|
43
|
+
* an error) → **offline**, labelled "as of <capture time>".
|
|
44
|
+
*/
|
|
45
|
+
export declare function deriveMachineChip(input: DeriveMachineChipInput): MachineChip;
|
|
46
|
+
export type UseMachineChipOptions = DeriveMachineChipInput;
|
|
47
|
+
/**
|
|
48
|
+
* Thin memoized wrapper over `deriveMachineChip` for the dock header (M4). The
|
|
49
|
+
* dock already runs `useSessionCapabilities` + `useMachines` + `useWorkspace
|
|
50
|
+
* capture`; it feeds their `liveness` / `state` / active-machine state /
|
|
51
|
+
* `capturedAt` here. Pass a periodically-updated `now` if you want the relative
|
|
52
|
+
* "as of" label to tick.
|
|
53
|
+
*/
|
|
54
|
+
export declare function useMachineChip(input: UseMachineChipOptions): MachineChip;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { type ClientOverride } from "../provider";
|
|
2
|
+
import type { MachinesResponse, MachineView, MetricSample } from "../types/machines";
|
|
3
|
+
/**
|
|
4
|
+
* The slice of the SDK client the Machines surface needs. The method NAMES +
|
|
5
|
+
* SIGNATURES match M10's `OpenGeniClient` (`listMachines`, `machineMetricsSeries`)
|
|
6
|
+
* so the real SDK client satisfies this surface DIRECTLY for the read paths — no
|
|
7
|
+
* adapter needed. It is declared structurally (not a hard `OpenGeniClient` Pick)
|
|
8
|
+
* so a test/demo/Geni-frontend client can stand in, keeping the hook dual-consumer
|
|
9
|
+
* safe (works in apps/web AND the separate Geni frontend).
|
|
10
|
+
*
|
|
11
|
+
* The active-sandbox SWAP is now a typed SDK call (`swapActiveSandbox`, the M7
|
|
12
|
+
* user-authenticated REST equivalent of the `sandbox_swap` MCP tool). The real
|
|
13
|
+
* SDK client satisfies it structurally, so the default attach path is wired
|
|
14
|
+
* WHENEVER a sessionId is in scope (the swap is session-scoped). `attachMachine`
|
|
15
|
+
* stays an OPTIONAL escape hatch for a host that wants to supply its own swap
|
|
16
|
+
* adapter; when neither it nor a sessionId is present, attach is a no-op and the
|
|
17
|
+
* card hides the button.
|
|
18
|
+
*/
|
|
19
|
+
export type MachinesClientLike = {
|
|
20
|
+
/** GET /v1/workspaces/:ws/machines — the dashboard list + active pointer. */
|
|
21
|
+
listMachines: (workspaceId: string, options?: {
|
|
22
|
+
sessionId?: string;
|
|
23
|
+
signal?: AbortSignal;
|
|
24
|
+
}) => Promise<MachinesResponse>;
|
|
25
|
+
/** GET .../machines/:enrollmentId/metrics/series — the downsampled history. */
|
|
26
|
+
machineMetricsSeries?: (workspaceId: string, enrollmentId: string, options?: {
|
|
27
|
+
window?: "15m" | "1h" | "6h" | "24h";
|
|
28
|
+
}) => Promise<MetricSample[]>;
|
|
29
|
+
/**
|
|
30
|
+
* POST .../sessions/:sessionId/active-sandbox — swap the session's active
|
|
31
|
+
* sandbox to a machine. The default swap path; the real SDK client provides it.
|
|
32
|
+
*/
|
|
33
|
+
swapActiveSandbox?: (workspaceId: string, sessionId: string, request: {
|
|
34
|
+
target: string;
|
|
35
|
+
}) => Promise<unknown>;
|
|
36
|
+
/**
|
|
37
|
+
* Host-supplied swap adapter (an escape hatch). When present it wins over the
|
|
38
|
+
* default `swapActiveSandbox` path. Session-scoped, like the swap it backs.
|
|
39
|
+
*/
|
|
40
|
+
attachMachine?: (workspaceId: string, sessionId: string, sandboxId: string) => Promise<unknown>;
|
|
41
|
+
};
|
|
42
|
+
export type UseMachinesOptions = ClientOverride & {
|
|
43
|
+
pollIntervalMs?: number | undefined;
|
|
44
|
+
enabled?: boolean | undefined;
|
|
45
|
+
/** Scope the list to a session (adds the synthetic Modal group box + pointer). */
|
|
46
|
+
sessionId?: string | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* Override the client with one implementing `MachinesClientLike`. Defaults to
|
|
49
|
+
* the provider client cast to the surface (the real SDK client satisfies the
|
|
50
|
+
* read paths). An app supplies an adapter to wire `attachMachine` (the swap).
|
|
51
|
+
*/
|
|
52
|
+
machinesClient?: MachinesClientLike | undefined;
|
|
53
|
+
};
|
|
54
|
+
export type UseMachinesResult = {
|
|
55
|
+
machines: MachineView[];
|
|
56
|
+
activeSandboxId: string | null;
|
|
57
|
+
activeEpoch: number;
|
|
58
|
+
loading: boolean;
|
|
59
|
+
error: Error | null;
|
|
60
|
+
refresh: () => Promise<void>;
|
|
61
|
+
/** Attach/swap the session's active sandbox to a machine (returns the new pointer). */
|
|
62
|
+
attach: (sandboxId: string) => Promise<boolean>;
|
|
63
|
+
/** Whether the host wired an attach/swap path (drives the card affordance). */
|
|
64
|
+
canAttach: boolean;
|
|
65
|
+
/** Fetch a downsampled metric series for one enrolled machine. */
|
|
66
|
+
fetchSeries: (enrollmentId: string, window?: "15m" | "1h" | "6h" | "24h") => Promise<MetricSample[]>;
|
|
67
|
+
attaching: boolean;
|
|
68
|
+
/** The sandbox id of the in-flight attach (for per-card spinner gating). */
|
|
69
|
+
attachingSandboxId: string | null;
|
|
70
|
+
mutationError: Error | null;
|
|
71
|
+
clearMutationError: () => void;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* The workspace Machines fleet: the selfhosted enrollments + the session's Modal
|
|
75
|
+
* box, each with latest metrics + state, plus the active-sandbox pointer. Polls
|
|
76
|
+
* the M10 `GET /machines` endpoint and exposes attach/swap + a metric-series
|
|
77
|
+
* fetch. Renders via `<MachinesDashboard>`. Dual-consumer safe: it reads only the
|
|
78
|
+
* structural `MachinesClientLike` surface, so it works in apps/web AND the Geni
|
|
79
|
+
* frontend (each provides its own client/adapter).
|
|
80
|
+
*/
|
|
81
|
+
export declare function useMachines(options?: UseMachinesOptions): UseMachinesResult;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { CapabilityPack, EnablePackRequest, PackInstallation, RegisterCapabilityPackRequest, WorkspaceRegisteredPack } from "@opengeni/sdk";
|
|
2
|
+
import { type ClientOverride } from "../provider";
|
|
3
|
+
export type UsePacksOptions = ClientOverride & {
|
|
4
|
+
pollIntervalMs?: number | undefined;
|
|
5
|
+
enabled?: boolean | undefined;
|
|
6
|
+
};
|
|
7
|
+
export type UsePacksResult = {
|
|
8
|
+
/** Built-in + registered packs available to the workspace. */
|
|
9
|
+
packs: CapabilityPack[];
|
|
10
|
+
/** Enable/disable state per pack. */
|
|
11
|
+
installations: PackInstallation[];
|
|
12
|
+
/** The installation for a pack id, if any. */
|
|
13
|
+
installationFor: (packId: string) => PackInstallation | null;
|
|
14
|
+
loading: boolean;
|
|
15
|
+
error: Error | null;
|
|
16
|
+
refresh: () => Promise<void>;
|
|
17
|
+
/** Register (or replace) a workspace-scoped pack manifest. */
|
|
18
|
+
register: (manifest: RegisterCapabilityPackRequest) => Promise<WorkspaceRegisteredPack | null>;
|
|
19
|
+
enable: (packId: string, request?: EnablePackRequest) => Promise<PackInstallation | null>;
|
|
20
|
+
/** Unregister a workspace-scoped pack (built-ins cannot be removed). */
|
|
21
|
+
remove: (packId: string) => Promise<boolean>;
|
|
22
|
+
mutating: boolean;
|
|
23
|
+
mutationError: Error | null;
|
|
24
|
+
clearMutationError: () => void;
|
|
25
|
+
};
|
|
26
|
+
/** Capability packs: catalog + installations + register/enable/unregister. */
|
|
27
|
+
export declare function usePacks(options?: UsePacksOptions): UsePacksResult;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { DesktopConnectionState, DesktopStreamCapability } from "@opengeni/sdk";
|
|
2
|
+
import { type RefObject } from "react";
|
|
3
|
+
/**
|
|
4
|
+
* The minimal WebSocket surface the frame renderer drives. Lets tests (and a
|
|
5
|
+
* future transport swap) inject a fake without a live socket — the exact
|
|
6
|
+
* analogue of `DesktopRfbFactory` for the noVNC path. Structurally a subset of
|
|
7
|
+
* the browser `WebSocket`.
|
|
8
|
+
*/
|
|
9
|
+
export interface DesktopWebSocketLike {
|
|
10
|
+
binaryType: string;
|
|
11
|
+
send(data: ArrayBuffer): void;
|
|
12
|
+
close(): void;
|
|
13
|
+
addEventListener(type: "open" | "message" | "error" | "close", listener: (ev: {
|
|
14
|
+
data?: unknown;
|
|
15
|
+
} & Record<string, unknown>) => void): void;
|
|
16
|
+
removeEventListener(type: "open" | "message" | "error" | "close", listener: (ev: {
|
|
17
|
+
data?: unknown;
|
|
18
|
+
} & Record<string, unknown>) => void): void;
|
|
19
|
+
}
|
|
20
|
+
export type DesktopWebSocketFactory = (url: string) => DesktopWebSocketLike;
|
|
21
|
+
export type UseRelayFrameStreamOptions = {
|
|
22
|
+
/** The desktop cell of the negotiated capabilities (`capabilities.DesktopStream`). */
|
|
23
|
+
capability: DesktopStreamCapability | null;
|
|
24
|
+
/** The mount target. A `<canvas>` is appended here on connect. */
|
|
25
|
+
containerRef: RefObject<HTMLDivElement | null>;
|
|
26
|
+
/** Custom socket factory (tests / a transport swap). Defaults to `new WebSocket(url)`. */
|
|
27
|
+
webSocketFactory?: DesktopWebSocketFactory | undefined;
|
|
28
|
+
};
|
|
29
|
+
export type UseRelayFrameStreamResult = {
|
|
30
|
+
state: DesktopConnectionState;
|
|
31
|
+
error: Error | null;
|
|
32
|
+
/** Tear down + reopen the socket (e.g. after a drop, once a fresh url arrives). */
|
|
33
|
+
reconnect: () => void;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* VIEW-ONLY PNG-frame renderer for a SELF-HOSTED desktop stream — the relay
|
|
37
|
+
* transport (`transport: "relay-frames"`, `client: "frames"`). The self-hosted
|
|
38
|
+
* agent produces one PNG per frame as a protobuf datagram over the relay; there
|
|
39
|
+
* is no RFB/noVNC here. This hook opens the relay DESKTOP channel as a CLIENT
|
|
40
|
+
* (mirroring the proven diagnostic wire protocol), decodes each PNG onto a
|
|
41
|
+
* `<canvas>` mounted into `containerRef`, and drives the connection state
|
|
42
|
+
* machine: idle → connecting (ws opening) → connected (first painted frame) →
|
|
43
|
+
* error (ws error/close/ack rejection).
|
|
44
|
+
*
|
|
45
|
+
* It is DORMANT for any other transport (or no url): it stays idle and touches
|
|
46
|
+
* nothing, so the noVNC path owns the surface. SSR-safe: the socket + DOM attach
|
|
47
|
+
* live inside `useEffect`.
|
|
48
|
+
*
|
|
49
|
+
* Backpressure (critical — frames are ~1.8MB at ~10fps): at most one frame is
|
|
50
|
+
* decoded at a time; a frame arriving mid-decode replaces the pending one
|
|
51
|
+
* (latest-wins), so a slow decode can never build an unbounded queue.
|
|
52
|
+
*/
|
|
53
|
+
export declare function useRelayFrameStream(options: UseRelayFrameStreamOptions): UseRelayFrameStreamResult;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { CreateRigRequest, ProposeRigChangeRequest, Rig, RigChange, RigVersion, UpdateRigRequest } from "@opengeni/sdk";
|
|
2
|
+
import { type ClientOverride } from "../provider";
|
|
3
|
+
export type UseRigsOptions = ClientOverride & {
|
|
4
|
+
pollIntervalMs?: number | undefined;
|
|
5
|
+
enabled?: boolean | undefined;
|
|
6
|
+
};
|
|
7
|
+
export type UseRigsResult = {
|
|
8
|
+
rigs: Rig[];
|
|
9
|
+
loading: boolean;
|
|
10
|
+
error: Error | null;
|
|
11
|
+
refresh: () => Promise<void>;
|
|
12
|
+
create: (request: CreateRigRequest) => Promise<Rig | null>;
|
|
13
|
+
update: (rigId: string, request: UpdateRigRequest) => Promise<Rig | null>;
|
|
14
|
+
remove: (rigId: string) => Promise<boolean>;
|
|
15
|
+
listVersions: (rigId: string) => Promise<RigVersion[] | null>;
|
|
16
|
+
activateVersion: (rigId: string, versionId: string) => Promise<RigVersion | null>;
|
|
17
|
+
listChanges: (rigId: string) => Promise<RigChange[] | null>;
|
|
18
|
+
proposeChange: (rigId: string, request: ProposeRigChangeRequest) => Promise<RigChange | null>;
|
|
19
|
+
mutating: boolean;
|
|
20
|
+
mutationError: Error | null;
|
|
21
|
+
clearMutationError: () => void;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Rigs (workspace-scoped, versioned sandbox machine definitions). The list
|
|
25
|
+
* polls; version/change reads are on-demand (they are per-rig detail, not part
|
|
26
|
+
* of the list surface).
|
|
27
|
+
*/
|
|
28
|
+
export declare function useRigs(options?: UseRigsOptions): UseRigsResult;
|
|
29
|
+
export type UseRigOptions = ClientOverride & {
|
|
30
|
+
pollIntervalMs?: number | undefined;
|
|
31
|
+
enabled?: boolean | undefined;
|
|
32
|
+
};
|
|
33
|
+
export type UseRigResult = {
|
|
34
|
+
rig: Rig | null;
|
|
35
|
+
loading: boolean;
|
|
36
|
+
error: Error | null;
|
|
37
|
+
refresh: () => Promise<void>;
|
|
38
|
+
update: (request: UpdateRigRequest) => Promise<Rig | null>;
|
|
39
|
+
remove: () => Promise<boolean>;
|
|
40
|
+
activateVersion: (versionId: string) => Promise<RigVersion | null>;
|
|
41
|
+
proposeChange: (request: ProposeRigChangeRequest) => Promise<RigChange | null>;
|
|
42
|
+
/** Re-run verification for a change (asynchronous — poll for the outcome). */
|
|
43
|
+
verifyChange: (changeId: string) => Promise<RigChange | null>;
|
|
44
|
+
/** Promote a verified definition_edit into a new active version (rigs:manage). */
|
|
45
|
+
promoteChange: (changeId: string) => Promise<RigVersion | null>;
|
|
46
|
+
/** Re-verify the active version's checks in a clean throwaway sandbox. */
|
|
47
|
+
verify: () => Promise<{
|
|
48
|
+
ok: boolean;
|
|
49
|
+
versionId: string;
|
|
50
|
+
} | null>;
|
|
51
|
+
mutating: boolean;
|
|
52
|
+
mutationError: Error | null;
|
|
53
|
+
clearMutationError: () => void;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* A single rig (its active version + counts), polled so verification and
|
|
57
|
+
* promotion state stay live. Owns the rig's write actions; the versions and
|
|
58
|
+
* changes lists are separate polled reads (`useRigVersions`/`useRigChanges`).
|
|
59
|
+
*/
|
|
60
|
+
export declare function useRig(rigId: string, options?: UseRigOptions): UseRigResult;
|
|
61
|
+
export type UseRigVersionsOptions = ClientOverride & {
|
|
62
|
+
pollIntervalMs?: number | undefined;
|
|
63
|
+
enabled?: boolean | undefined;
|
|
64
|
+
};
|
|
65
|
+
export type UseRigVersionsResult = {
|
|
66
|
+
versions: RigVersion[];
|
|
67
|
+
loading: boolean;
|
|
68
|
+
error: Error | null;
|
|
69
|
+
refresh: () => Promise<void>;
|
|
70
|
+
};
|
|
71
|
+
/** A rig's append-only version history, newest-first (polled). */
|
|
72
|
+
export declare function useRigVersions(rigId: string, options?: UseRigVersionsOptions): UseRigVersionsResult;
|
|
73
|
+
export type UseRigChangesOptions = ClientOverride & {
|
|
74
|
+
pollIntervalMs?: number | undefined;
|
|
75
|
+
enabled?: boolean | undefined;
|
|
76
|
+
};
|
|
77
|
+
export type UseRigChangesResult = {
|
|
78
|
+
changes: RigChange[];
|
|
79
|
+
loading: boolean;
|
|
80
|
+
error: Error | null;
|
|
81
|
+
refresh: () => Promise<void>;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* A rig's change queue (polled). The default poll cadence lets a change move
|
|
85
|
+
* through verifying → merged/rejected without a manual refresh.
|
|
86
|
+
*/
|
|
87
|
+
export declare function useRigChanges(rigId: string, options?: UseRigChangesOptions): UseRigChangesResult;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type { FsReadResponse, FsWriteResponse, OpenGeniRequestOptions, SessionEvent, WorkspaceCaptureManifest } from "@opengeni/sdk";
|
|
2
|
+
import { type ClientOverride } from "../provider";
|
|
3
|
+
/** The git-status overlay a file row may carry (tints modified files in the tree). */
|
|
4
|
+
export type FileTreeStatus = "added" | "modified" | "deleted" | "renamed" | "untracked";
|
|
5
|
+
export type CapturedFileUnavailableReason = "not-captured" | "too-large" | "content-missing";
|
|
6
|
+
/** A cold capture can index a path without retaining its contents. Components
|
|
7
|
+
* use this typed result to offer an explicit wake action instead of silently
|
|
8
|
+
* turning passive review into a live sandbox read. */
|
|
9
|
+
export declare class CapturedFileUnavailableError extends Error {
|
|
10
|
+
readonly path: string;
|
|
11
|
+
readonly reason: CapturedFileUnavailableReason;
|
|
12
|
+
readonly code = "captured_file_unavailable";
|
|
13
|
+
constructor(path: string, reason: CapturedFileUnavailableReason);
|
|
14
|
+
}
|
|
15
|
+
export declare class FileWriteConflictError extends Error {
|
|
16
|
+
readonly path: string;
|
|
17
|
+
readonly expectedContent: string;
|
|
18
|
+
readonly liveContent: string;
|
|
19
|
+
readonly code = "file_write_conflict";
|
|
20
|
+
constructor(path: string, expectedContent: string, liveContent: string);
|
|
21
|
+
}
|
|
22
|
+
export type SandboxWriteFileOptions = {
|
|
23
|
+
/** Exact text loaded into the editor. The live file is re-read before write;
|
|
24
|
+
* divergence fails closed with FileWriteConflictError. */
|
|
25
|
+
expectedContent?: string | undefined;
|
|
26
|
+
/** Deliberately bypass the expected-content guard after a visible conflict. */
|
|
27
|
+
force?: boolean | undefined;
|
|
28
|
+
};
|
|
29
|
+
/** A node in the Pierre file tree. `children === undefined` ⇒ an unexpanded dir
|
|
30
|
+
* (lazy treeMode); `children: []` ⇒ an expanded-but-empty dir. */
|
|
31
|
+
export type FileTreeNode = {
|
|
32
|
+
path: string;
|
|
33
|
+
name: string;
|
|
34
|
+
kind: "file" | "dir";
|
|
35
|
+
children?: FileTreeNode[] | undefined;
|
|
36
|
+
size?: number | null | undefined;
|
|
37
|
+
status?: FileTreeStatus | undefined;
|
|
38
|
+
/** A residue dir the capture COLLAPSED (node_modules, .git, dist, …): its
|
|
39
|
+
* contents were never indexed. Cold, expanding it can't list children — the
|
|
40
|
+
* UI shows an inline "contents on machine" row until the box is warm. */
|
|
41
|
+
truncated?: boolean | undefined;
|
|
42
|
+
};
|
|
43
|
+
export type UseSandboxFilesOptions = ClientOverride & {
|
|
44
|
+
/** Live event log (usually `useSessionEvents().events`) — drives auto-refresh
|
|
45
|
+
* on `fs.changed` / `git.changed`. */
|
|
46
|
+
events?: SessionEvent[] | undefined;
|
|
47
|
+
/** Initial path to list (workspace root by default). */
|
|
48
|
+
rootPath?: string | undefined;
|
|
49
|
+
/** Hold off the initial list (e.g. panel collapsed). Default true. */
|
|
50
|
+
enabled?: boolean | undefined;
|
|
51
|
+
/** The lease liveness ("cold" | "warm" | "draining"). The structured FileSystem
|
|
52
|
+
* capability is advertised even on a COLD box, so the mount-time list can race
|
|
53
|
+
* the box: it lists before the box is warm, gets an empty/errored result, and
|
|
54
|
+
* (with no `fs.changed` event) never re-lists. Passing liveness re-lists when
|
|
55
|
+
* the box first becomes warm, so the tree populates as soon as the box is up. */
|
|
56
|
+
liveness?: string | undefined;
|
|
57
|
+
/** The latest turn-end workspace capture (from `useWorkspaceCapture`). The tree
|
|
58
|
+
* paints immediately from this durable index, then a warm box reconciles live
|
|
59
|
+
* in place. If that live read fails, the capture remains a truthful read-only
|
|
60
|
+
* fallback instead of turning into an empty error surface. */
|
|
61
|
+
capture?: WorkspaceCaptureManifest | null | undefined;
|
|
62
|
+
/** Called when an OPTIMISTIC mutation is reverted because its background
|
|
63
|
+
* Channel-A op failed (e.g. a 409 rename collision). The host wires this to a
|
|
64
|
+
* toast — the tree silently rolls the node back, the user sees why. */
|
|
65
|
+
onMutationError?: ((error: Error, op: string) => void) | undefined;
|
|
66
|
+
};
|
|
67
|
+
export type UseSandboxFilesResult = {
|
|
68
|
+
/** The tree roots (the listed root's children). */
|
|
69
|
+
tree: FileTreeNode[];
|
|
70
|
+
/** Lazy-expand a directory node in place (lists its immediate children). */
|
|
71
|
+
expand: (path: string) => Promise<void>;
|
|
72
|
+
/** Paths whose lazy `fs.list` is currently in flight — the FileBrowser shows a
|
|
73
|
+
* spinner on these nodes so a 2-3s Channel-A list never looks frozen. */
|
|
74
|
+
expandingPaths: Set<string>;
|
|
75
|
+
/** Read a file for the preview pane (text or base64-for-binary, size-capped). */
|
|
76
|
+
readFile: (path: string, options?: OpenGeniRequestOptions) => Promise<FsReadResponse>;
|
|
77
|
+
/** Write a file (overwrite, last-writer-wins) — the editor save path.
|
|
78
|
+
* Optimistic: a brand-new file is spliced into the tree immediately and the
|
|
79
|
+
* Channel-A write runs in the background; on failure the splice is reverted. */
|
|
80
|
+
writeFile: (path: string, content: string, options?: SandboxWriteFileOptions) => Promise<FsWriteResponse>;
|
|
81
|
+
/** Create a new empty file (refuses to clobber an existing path: overwrite=false). */
|
|
82
|
+
createFile: (path: string) => Promise<void>;
|
|
83
|
+
/** Create a directory (recursive by default). */
|
|
84
|
+
createDir: (path: string) => Promise<void>;
|
|
85
|
+
/** Delete a path (pass recursive=true for a non-empty directory). */
|
|
86
|
+
deleteEntry: (path: string, recursive?: boolean) => Promise<void>;
|
|
87
|
+
/** Move / rename a path (rename == move). Refuses to clobber unless overwrite=true. */
|
|
88
|
+
moveEntry: (path: string, newPath: string, opts?: {
|
|
89
|
+
overwrite?: boolean;
|
|
90
|
+
}) => Promise<void>;
|
|
91
|
+
/** Re-list the whole tree from the root. */
|
|
92
|
+
refresh: () => Promise<void>;
|
|
93
|
+
/** Which source the tree is currently served from: the live box, the turn-end
|
|
94
|
+
* capture (cold/offline), or neither yet. M5's source badge reads this. */
|
|
95
|
+
source: "live" | "capture" | null;
|
|
96
|
+
/** When the served capture was taken (ISO), when `source === "capture"`. */
|
|
97
|
+
capturedAt: string | null;
|
|
98
|
+
loading: boolean;
|
|
99
|
+
error: Error | null;
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Project the FileSystem service into a lazy-loaded Pierre tree. The initial
|
|
103
|
+
* list pulls one level (depth 1); `expand(path)` lists a directory's immediate
|
|
104
|
+
* children on demand (the fast lazy-tree UX). A git-status overlay tints
|
|
105
|
+
* modified files. Auto-refreshes when an `fs.changed` / `git.changed` event
|
|
106
|
+
* arrives on the live log.
|
|
107
|
+
*/
|
|
108
|
+
export declare function useSandboxFiles(sessionId: string | null | undefined, options?: UseSandboxFilesOptions): UseSandboxFilesResult;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { GitFileDiff, SessionEvent, WorkspaceCaptureManifest } from "@opengeni/sdk";
|
|
2
|
+
import { type ClientOverride } from "../provider";
|
|
3
|
+
export type UseSandboxGitOptions = ClientOverride & {
|
|
4
|
+
/** Live event log (usually `useSessionEvents().events`) — drives auto-refresh
|
|
5
|
+
* on `git.changed`. */
|
|
6
|
+
events?: SessionEvent[] | undefined;
|
|
7
|
+
/** Repo root within the workspace (multi-repo). Default: workspace root. */
|
|
8
|
+
repoPath?: string | undefined;
|
|
9
|
+
/** All repository roots in the workspace. When supplied, status and diff are
|
|
10
|
+
* aggregated into one workspace-wide result and paths are workspace-relative. */
|
|
11
|
+
repoPaths?: readonly string[] | undefined;
|
|
12
|
+
/** Diff the staged index vs HEAD (`--cached`) instead of the working tree. */
|
|
13
|
+
staged?: boolean | undefined;
|
|
14
|
+
/** Hold off the initial fetch. Default true. */
|
|
15
|
+
enabled?: boolean | undefined;
|
|
16
|
+
/** Lease liveness ("warm" | "draining" | "cold"). When NOT warm, the diff is
|
|
17
|
+
* served from the capture (cold/offline) instead of a live `gitDiff` RPC. */
|
|
18
|
+
liveness?: string | undefined;
|
|
19
|
+
/** The latest turn-end capture (from `useWorkspaceCapture`). Seeds the diff
|
|
20
|
+
* immediately; a warm box reconciles live and leaves this durable review
|
|
21
|
+
* surface in place if the live request is temporarily unavailable. */
|
|
22
|
+
capture?: WorkspaceCaptureManifest | null | undefined;
|
|
23
|
+
};
|
|
24
|
+
/** A Git diff qualified into workspace scope. `repoRoot` is present for the
|
|
25
|
+
* workspace-wide path and lets review UI group real repositories without
|
|
26
|
+
* guessing from the first path segment. */
|
|
27
|
+
export type SandboxGitFileDiff = GitFileDiff & {
|
|
28
|
+
repoRoot?: string | undefined;
|
|
29
|
+
};
|
|
30
|
+
export type UseSandboxGitResult = {
|
|
31
|
+
/** Working-tree (or staged) diff vs HEAD — the structured hunks the Pierre
|
|
32
|
+
* diff view renders. */
|
|
33
|
+
diff: SandboxGitFileDiff[];
|
|
34
|
+
branch: string | null;
|
|
35
|
+
/** Whether a repo is actually mounted (drives "no repository" vs "no changes"). */
|
|
36
|
+
isRepo: boolean;
|
|
37
|
+
ahead: number;
|
|
38
|
+
behind: number;
|
|
39
|
+
/** Number and workspace-relative roots of repositories represented here. */
|
|
40
|
+
repoCount: number;
|
|
41
|
+
repoRoots: string[];
|
|
42
|
+
refresh: () => Promise<void>;
|
|
43
|
+
/** Which source the diff is served from: the live box or the turn-end capture. */
|
|
44
|
+
source: "live" | "capture" | null;
|
|
45
|
+
/** When the served capture was taken (ISO), when `source === "capture"`. */
|
|
46
|
+
capturedAt: string | null;
|
|
47
|
+
loading: boolean;
|
|
48
|
+
error: Error | null;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Project the Git service into the Pierre diff data contract: structured
|
|
52
|
+
* `GitFileDiff[]` (per-file hunks with per-line old/new numbers, rename
|
|
53
|
+
* detection, binary flag, add/del counts) plus branch + ahead/behind. When the
|
|
54
|
+
* box is warm the `git diff` runs in-box (API-direct); when it is cold/offline the
|
|
55
|
+
* diff is served from the turn-end capture instead. Refreshes on
|
|
56
|
+
* `git.changed`; reconciles live in place on the cold→warm transition.
|
|
57
|
+
*/
|
|
58
|
+
export declare function useSandboxGit(sessionId: string | null | undefined, options?: UseSandboxGitOptions): UseSandboxGitResult;
|