import { type ReactNode } from "react"; import type { SessionEvent } from "@opengeni/sdk"; import { type ClientOverride } from "../provider.js"; import type { BrowserFrameWebSocketFactory } from "../hooks/use-browser-frame-stream.js"; import type { ComputerFrameWebSocketFactory } from "../hooks/use-computer-frame-stream.js"; import type { FileNodeVisibilityPredicate } from "../file-node-visibility.js"; import { type MachineChip } from "../hooks/use-machine-chip.js"; import type { MachineView } from "../types/machines.js"; import { type WorkspaceDockProps, type WorkspaceTab } from "./workspace-dock.js"; /** A host-routed notification (replaces the app-only `sonner` toast coupling). */ export type WorkspaceNotification = { kind: "error" | "info"; message: string; }; /** The workbench's canonical tab ids (a host injects extras around these). */ export declare const WORKBENCH_TAB_CHANGES = "changes"; export declare const WORKBENCH_TAB_FILES = "files"; export declare const WORKBENCH_TAB_TERMINAL = "terminal"; export declare const WORKBENCH_TAB_BROWSER = "browser"; export declare const WORKBENCH_TAB_DESKTOP = "desktop"; /** * The built-in workbench surfaces in their canonical display order. Hosts can * pass a subset through `surfaces`; omission preserves the complete standalone * workbench. */ export declare const WORKBENCH_SURFACES: readonly ["changes", "files", "terminal", "browser", "desktop"]; export type SandboxWorkspaceSurface = (typeof WORKBENCH_SURFACES)[number]; /** * Decide a workspace tab from an already-local event log: the newest * `workspace.revision.captured` announce carries the change surface stats, so * "changes exist → Changes, else Files" needs zero machine round-trips. A host * `override` (e.g. a landing "run" tab) wins when supplied. * * `` uses this only as an optional early hint after its own * capture GET reports no durable capture. A pure embedder needs no events-at-mount * contract: it falls through to authoritative live Git instead. */ export declare function initialWorkspaceTab(events: SessionEvent[] | undefined, override?: string | null): string; export type WorkspaceMachine = { /** Whether at least one built-in workbench surface is enabled. */ enabled: boolean; /** The derived live/waking/sleeping-or-offline chip model. */ chip: MachineChip; /** The machine these surfaces are bound to (the Modal group box or a * self-hosted machine), or null while the fleet is still resolving. */ activeMachine: MachineView | null; loading: boolean; error: Error | null; refresh: () => Promise; }; export type UseSandboxWorkspaceTabsOptions = ClientOverride & { sessionId: string; /** Live event log (usually `useSessionEvents().events`). */ events: SessionEvent[]; /** * Built-in surfaces this host wants to expose. Omit for all five. A disabled * surface is behaviorally dormant: its data hooks, warm intents, stream * attachment, and navigation callbacks are not activated. */ surfaces?: readonly SandboxWorkspaceSurface[] | undefined; /** * Whether this viewer may read the workspace machine fleet * (`GET /machines`, permission `enrollments:read`). Defaults to true. Pass * false for a viewer without it: the dock then never requests the fleet and * the machine chip derives from the session's own capabilities alone. */ machinesEnabled?: boolean | undefined; /** Override the source-driven default tab (e.g. a host landing tab id). When * omitted the workbench picks Changes-vs-Files from capture or live Git. */ initialTab?: string | null | undefined; /** Actually selected dock tab. Inactive data surfaces retain cache but issue no live reads. */ activeTab?: string | null | undefined; /** Whether the dock is visible. Hidden docks retain UI state but must not keep * expensive browser/computer media streams alive. */ workspaceVisible?: boolean | undefined; /** Host-routed notifications (mutation errors, desktop-consent failures). The * package never imports a toast library — the host decides how to surface. */ onNotify?: ((notification: WorkspaceNotification) => void) | undefined; /** Alternate frame transport for non-browser runtimes and deterministic tests. */ browserWebSocketFactory?: BrowserFrameWebSocketFactory | undefined; /** Alternate Computer frame transport for non-browser runtimes and deterministic tests. */ computerWebSocketFactory?: ComputerFrameWebSocketFactory | undefined; /** Host-owned setup page or store listing for attaching an existing Chrome profile. */ browserExtensionSetupUrl?: string | undefined; /** File requested by a Changes guard. The Files surface defers the read until * the sandbox is live, then reveals this path. */ requestedFilePath?: string | null | undefined; /** Unique identity for `requestedFilePath`, including repeated requests for the * same path. */ requestedFileRequestId?: string | number | null | undefined; /** 1-based line to reveal after `requestedFilePath` opens. */ requestedFileLine?: number | null | undefined; /** Route a guarded diff into the host's Files tab. */ onOpenFile?: ((path: string) => void) | undefined; /** Restore and report navigation inside the built-in workbench surfaces. */ initialFilePath?: string | null | undefined; onFilePathChange?: ((path: string | null) => void) | undefined; /** Presentation-only filter for Files tree nodes and selected-file viewing. */ isFileNodeVisible?: FileNodeVisibilityPredicate | undefined; initialBrowserSessionId?: string | null | undefined; onBrowserSessionIdChange?: ((browserSessionId: string | null) => void) | undefined; initialComputerSessionId?: string | null | undefined; onComputerSessionIdChange?: ((computerSessionId: string | null) => void) | undefined; /** Navigate the host dock to one exact linked ComputerSession. */ onOpenComputerSession?: ((computerSessionId: string) => void) | undefined; requestedComputerSessionId?: string | null | undefined; requestedComputerRequestId?: string | number | null | undefined; }; export type UseSandboxWorkspaceTabsResult = { /** Changes | Files | Terminal | Browser | Desktop (capability-gated where noted). */ tabs: WorkspaceTab[]; /** The source-driven default tab: Changes when the first authoritative capture * has changes, else Files (a host `initialTab` overrides). Choosing a tab * never performs hidden live workspace I/O. * null while that source resolves, or permanently when neither Changes nor * Files is enabled; the choice latches once. */ defaultTab: string | null; /** The machine-state model for the dock-header chip. */ machine: WorkspaceMachine; }; /** * Build the workbench tabs + the machine-chip model for one session. This is the * dock "brain": capability negotiation, capture-backed cold reads, prewarm * flags, automatic desktop acknowledgment, and the xterm theme observer — all * package-local. */ export declare function useSandboxWorkspaceTabs(options: UseSandboxWorkspaceTabsOptions): UseSandboxWorkspaceTabsResult; export type SandboxWorkspaceProps = ClientOverride & { sessionId: string; /** Live event log (usually `useSessionEvents().events`). */ events: SessionEvent[]; /** The chat / primary pane shown beside the dock. */ primary: ReactNode; /** * Built-in surfaces this host wants to expose. Omit for Changes, Files, * Terminal, Browser, and Desktop. Disabled surfaces remain behaviorally dormant. */ surfaces?: readonly SandboxWorkspaceSurface[] | undefined; /** * Whether this viewer may read the workspace machine fleet * (`GET /machines`, permission `enrollments:read`). Defaults to true. Pass * false for a viewer without it so the dock never requests the fleet. */ machinesEnabled?: boolean | undefined; /** Host tabs injected BEFORE the workbench tabs (e.g. a "Run" landing tab). */ leadingTabs?: WorkspaceTab[] | undefined; /** Host tabs injected AFTER the workbench tabs (e.g. a "Debug" tab). */ trailingTabs?: WorkspaceTab[] | undefined; /** Override the pre-paint default tab (e.g. a host landing tab id). When * omitted the workbench decides from the durable workspace capture. */ initialTab?: string | undefined; onActiveTabChange?: ((activeTab: string) => void) | undefined; /** Open a built-in or host-injected tab. A new requestId reopens the same tab. */ openTabRequest?: { tab: string; requestId: number; } | null | undefined; initialFilePath?: string | null | undefined; onFilePathChange?: ((path: string | null) => void) | undefined; /** Presentation-only filter for Files tree nodes and selected-file viewing. */ isFileNodeVisible?: FileNodeVisibilityPredicate | undefined; /** * Host request to open a workspace file (and optional line) in Files. A new * `requestId` re-opens even the same path. */ openFileRequest?: { path: string; line?: number | null | undefined; requestId: number; } | null | undefined; initialBrowserSessionId?: string | null | undefined; onBrowserSessionIdChange?: ((browserSessionId: string | null) => void) | undefined; initialComputerSessionId?: string | null | undefined; onComputerSessionIdChange?: ((computerSessionId: string | null) => void) | undefined; /** Host-routed notifications (no toast dependency in the package). */ onNotify?: ((notification: WorkspaceNotification) => void) | undefined; /** Alternate Browser frame transport for non-browser runtimes and deterministic tests. */ browserWebSocketFactory?: BrowserFrameWebSocketFactory | undefined; /** Alternate Computer frame transport for non-browser runtimes and deterministic tests. */ computerWebSocketFactory?: ComputerFrameWebSocketFactory | undefined; /** Host-owned setup page or store listing for attaching an existing Chrome profile. */ browserExtensionSetupUrl?: string | undefined; /** Controlled collapsed state for hosts with their own dock toggle. */ collapsed?: boolean | undefined; onCollapsedChange?: ((collapsed: boolean) => void) | undefined; /** Keep the dock's built-in collapse control with controlled collapsed state. */ showCollapseControl?: boolean | undefined; /** Host navigation shown only in the phone workspace overlay header. */ mobileLeadingControl?: ReactNode | undefined; autoSaveId?: string | undefined; defaultSize?: number | undefined; minSize?: number | undefined; maxSize?: number | undefined; className?: string | undefined; }; /** * The whole session workspace, ready to mount: `` assembles the * capability-gated tabs, pins the machine-state chip in the dock header, and * renders the resizable ``. Wrap the tree in `` * (client + workspaceId) and import `@opengeni/react/compiled.css`; that is the * entire integration (see `docs/embedding-workbench.md`). */ export declare function SandboxWorkspace(props: SandboxWorkspaceProps): ReactNode; export type { WorkspaceDockProps };