@giselles-ai/sandkit 0.1.1 → 0.1.2

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.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/context.ts","../src/core/workspace-policy.ts","../src/core/workspace-sandbox-config.ts","../src/core/workspace-state.ts","../src/core/sandbox.ts","../src/core/workspace.ts","../src/core/sandkit.ts"],"sourcesContent":["import { createMemoryAdapter } from \"../adapters/index.ts\";\nimport { getSandboxDriverFactory } from \"../types.ts\";\nimport type { SandkitOptions, SandboxDriverFactory } from \"../types.ts\";\n\nexport interface SandkitContext {\n readonly adapter: NonNullable<SandkitOptions[\"database\"]>;\n readonly driverFactory: SandboxDriverFactory;\n readonly options: SandkitOptions;\n}\n\nfunction resolveDeprecatedNetworkOption(options: SandkitOptions): void {\n if (options.network !== undefined) {\n throw new Error(\n \"SandkitOptions.network has been removed. Use createWorkspace({ policy }), workspace.setPolicy(...), or per-run policy overrides instead.\",\n );\n }\n}\n\nexport function createSandkitContext(options: SandkitOptions): SandkitContext {\n if (!options) {\n throw new Error(\"SandkitOptions is required. Set sandbox to a Sandkit sandbox provider.\");\n }\n\n resolveDeprecatedNetworkOption(options);\n if (!options.sandbox) {\n throw new Error(\n \"SandkitOptions.sandbox is required. Set it to a Sandkit sandbox provider (for example, vercelSandbox(...)).\",\n );\n }\n\n return {\n adapter: options.database ?? createMemoryAdapter(),\n driverFactory: getSandboxDriverFactory(options.sandbox),\n options,\n };\n}\n","import type {\n WorkspaceMetadata,\n WorkspaceRecord,\n WorkspaceUpdateInput,\n} from \"../adapters/types.ts\";\nimport {\n allowAll,\n assertWorkspacePolicyIsDurable,\n describeWorkspacePolicy,\n parseWorkspacePolicy,\n redactWorkspacePolicy,\n serializeWorkspacePolicy,\n} from \"../policies/dsl.ts\";\nimport type { WorkspacePolicy } from \"../policies/types.ts\";\n\nexport const WORKSPACE_POLICY_METADATA_KEY = \"sandkit:policy\";\n\nfunction corruptionError(reason: string): Error {\n return new Error(`Sandkit durable state corruption in sandkit_workspaces.metadata: ${reason}`);\n}\n\nexport function readWorkspacePolicy(\n workspace: WorkspaceRecord,\n fallback: WorkspacePolicy = allowAll(),\n): WorkspacePolicy {\n const value = workspace.metadata?.[WORKSPACE_POLICY_METADATA_KEY];\n if (value === undefined) {\n return fallback;\n }\n\n try {\n return parseWorkspacePolicy(value);\n } catch (error) {\n throw corruptionError(error instanceof Error ? error.message : \"invalid workspace policy\");\n }\n}\n\nexport function asWorkspacePolicyMetadata(policy: WorkspacePolicy): WorkspaceMetadata {\n assertWorkspacePolicyIsDurable(policy);\n return {\n [WORKSPACE_POLICY_METADATA_KEY]: serializeWorkspacePolicy(policy),\n };\n}\n\nexport function removeWorkspacePolicyMetadata(\n metadata?: WorkspaceMetadata | undefined,\n): WorkspaceMetadata | undefined {\n if (!metadata || typeof metadata !== \"object\") {\n return metadata;\n }\n\n if (!Object.prototype.hasOwnProperty.call(metadata, WORKSPACE_POLICY_METADATA_KEY)) {\n return metadata;\n }\n\n const { [WORKSPACE_POLICY_METADATA_KEY]: _policyMetadata, ...rest } = metadata;\n return rest;\n}\n\nexport function asWorkspacePolicyPatch(policy: WorkspacePolicy): WorkspaceUpdateInput {\n return {\n metadata: asWorkspacePolicyMetadata(policy),\n };\n}\n\nexport function describeWorkspacePolicyId(policy: WorkspacePolicy): string {\n return describeWorkspacePolicy(policy);\n}\n\nexport function asPolicySnapshotConfig(policy: WorkspacePolicy): unknown {\n return redactWorkspacePolicy(policy);\n}\n","import type { WorkspaceMetadata, WorkspaceRecord } from \"../adapters/types.ts\";\nimport type { WorkspaceCreateOptions } from \"../types.ts\";\n\nexport const WORKSPACE_SANDBOX_CONFIG_METADATA_KEY = \"sandkit:sandbox-config\";\n\nexport interface WorkspaceSandboxConfig {\n readonly exposedPorts?: readonly number[];\n}\n\nfunction isFinitePort(value: unknown): value is number {\n return typeof value === \"number\" && Number.isInteger(value) && value >= 1 && value <= 65535;\n}\n\nfunction normalizeExposedPorts(ports: unknown): readonly number[] {\n if (ports === undefined) {\n return [];\n }\n\n if (!Array.isArray(ports)) {\n throw new Error(\"exposedPorts must be an array of positive integers in [1, 65535]\");\n }\n\n const normalized = ports.map((value, index) => {\n if (!isFinitePort(value)) {\n throw new Error(`exposedPorts[${index}] must be a positive integer in [1, 65535]`);\n }\n\n return value;\n });\n\n return [...normalized];\n}\n\nfunction corruptionError(reason: string): Error {\n return new Error(`Sandkit durable state corruption in sandkit_workspaces.metadata: ${reason}`);\n}\n\nfunction readWorkspaceSandboxConfigValue(value: unknown): WorkspaceSandboxConfig {\n if (value === undefined) {\n return {};\n }\n\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n throw new Error(\"Expected sandbox config metadata object\");\n }\n\n const candidate = value as WorkspaceSandboxConfig;\n const ports = normalizeExposedPorts((candidate as { exposedPorts?: unknown }).exposedPorts);\n return ports.length === 0 ? {} : { exposedPorts: ports };\n}\n\nexport function normalizeWorkspaceSandboxCreateConfig(\n config?: WorkspaceCreateOptions[\"sandbox\"],\n): WorkspaceSandboxConfig {\n if (config === undefined) {\n return {};\n }\n\n return {\n exposedPorts: normalizeExposedPorts(config.exposedPorts),\n };\n}\n\nexport function asWorkspaceSandboxConfigMetadata(\n config: WorkspaceSandboxConfig,\n): WorkspaceMetadata {\n if (!config.exposedPorts || config.exposedPorts.length === 0) {\n return {};\n }\n\n return {\n [WORKSPACE_SANDBOX_CONFIG_METADATA_KEY]: {\n exposedPorts: [...config.exposedPorts],\n },\n };\n}\n\nexport function removeWorkspaceSandboxConfigMetadata(\n metadata?: WorkspaceMetadata | undefined,\n): WorkspaceMetadata | undefined {\n if (!metadata || typeof metadata !== \"object\") {\n return metadata;\n }\n\n if (!Object.prototype.hasOwnProperty.call(metadata, WORKSPACE_SANDBOX_CONFIG_METADATA_KEY)) {\n return metadata;\n }\n\n const { [WORKSPACE_SANDBOX_CONFIG_METADATA_KEY]: _sandboxConfigMetadata, ...rest } = metadata;\n return rest;\n}\n\nexport function readWorkspaceSandboxConfig(workspace: WorkspaceRecord): WorkspaceSandboxConfig {\n const metadataValue = workspace.metadata?.[WORKSPACE_SANDBOX_CONFIG_METADATA_KEY];\n if (metadataValue === undefined) {\n return {};\n }\n\n try {\n return readWorkspaceSandboxConfigValue(metadataValue);\n } catch (error) {\n throw corruptionError(\n error instanceof Error ? error.message : \"invalid workspace sandbox config\",\n );\n }\n}\n","import type { WorkspaceRecord, WorkspaceUpdateInput } from \"../adapters/types.ts\";\nimport { parseWorkspacePolicy, serializeWorkspacePolicy } from \"../policies/dsl.ts\";\nimport type { WorkspacePolicy } from \"../policies/types.ts\";\nimport type {\n JsonValue,\n PersistedSandboxState,\n SandboxSessionLease,\n WorkspaceSandboxLease,\n} from \"../types.ts\";\n\nconst SANDBOX_METADATA_KEY = \"sandkit:sandbox\";\n\ntype RawWorkspaceSandboxState = {\n kind?: unknown;\n sessionId?: unknown;\n state?: unknown;\n lease?: unknown;\n policy?: unknown;\n};\n\ntype SerializedWorkspaceSandboxState =\n | { kind: \"cold\" }\n | {\n kind: \"session\";\n sessionId: string;\n lease: SerializedSessionLease;\n policy?: JsonValue;\n }\n | { kind: \"snapshot\"; state: PersistedSandboxState };\n\ntype SerializedSessionLease = {\n observedAt: string;\n expiresAt: string;\n};\n\ninterface WorkspaceSandboxStateBase {\n readonly kind: string;\n}\n\ninterface WorkspaceSandboxStateCold extends WorkspaceSandboxStateBase {\n readonly kind: \"cold\";\n}\n\ninterface WorkspaceSandboxStateSession extends WorkspaceSandboxStateBase {\n readonly kind: \"session\";\n readonly sandboxId: string;\n readonly lease: SandboxSessionLease;\n readonly sessionPolicy?: WorkspacePolicy;\n}\n\ninterface WorkspaceSandboxStateSnapshot extends WorkspaceSandboxStateBase {\n readonly kind: \"snapshot\";\n readonly commit: SandboxCommit;\n}\n\nexport type WorkspaceSandboxState =\n | WorkspaceSandboxStateCold\n | WorkspaceSandboxStateSession\n | WorkspaceSandboxStateSnapshot;\n\nexport type SandboxCommit = SandboxSnapshotCommit;\n\ninterface SandboxSnapshotCommit {\n readonly kind: \"snapshot\";\n readonly state: PersistedSandboxState;\n}\n\nexport interface WorkspaceSandboxTransition {\n readonly nextState: WorkspaceSandboxState;\n readonly patch: WorkspaceUpdateInput;\n}\n\nexport interface WorkspaceSandboxTransitionResult {\n readonly record: WorkspaceRecord;\n readonly state: WorkspaceSandboxState;\n}\n\nexport interface WorkspaceStateStore {\n updateWorkspace(id: string, input: WorkspaceUpdateInput): Promise<WorkspaceRecord>;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isPersistedSandboxState(value: unknown): value is PersistedSandboxState {\n if (!isRecord(value)) {\n return false;\n }\n\n if (typeof value.kind !== \"string\" || typeof value.sessionId !== \"string\") {\n return false;\n }\n\n return value.state === undefined || isJsonValue(value.state);\n}\n\nfunction isJsonValue(value: unknown): value is JsonValue {\n if (\n value === null ||\n typeof value === \"boolean\" ||\n typeof value === \"number\" ||\n typeof value === \"string\"\n ) {\n return true;\n }\n\n if (Array.isArray(value)) {\n return value.every((item) => isJsonValue(item));\n }\n\n if (!isRecord(value)) {\n return false;\n }\n\n return Object.values(value).every((item) => isJsonValue(item));\n}\n\nfunction isIsoTimestamp(value: unknown): value is string {\n return typeof value === \"string\" && !Number.isNaN(Date.parse(value));\n}\n\nfunction isSerializedSessionLease(value: unknown): value is SerializedSessionLease {\n if (!isRecord(value)) {\n return false;\n }\n\n return isIsoTimestamp(value.observedAt) && isIsoTimestamp(value.expiresAt);\n}\n\nfunction readWorkspaceSessionPolicy(value: unknown): WorkspacePolicy | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n try {\n return parseWorkspacePolicy(value);\n } catch {\n return undefined;\n }\n}\n\nfunction toSnapshotCommit(snapshot: PersistedSandboxState): SandboxSnapshotCommit {\n return { kind: \"snapshot\", state: snapshot };\n}\n\nfunction toSerializedWorkspaceState(state: WorkspaceSandboxState): SerializedWorkspaceSandboxState {\n switch (state.kind) {\n case \"cold\":\n return { kind: \"cold\" };\n case \"session\":\n return {\n kind: \"session\",\n sessionId: state.sandboxId,\n lease: {\n observedAt: state.lease.observedAt,\n expiresAt: state.lease.expiresAt,\n },\n policy:\n state.sessionPolicy === undefined\n ? undefined\n : serializeWorkspacePolicy(state.sessionPolicy),\n };\n case \"snapshot\":\n return { kind: \"snapshot\", state: state.commit.state };\n default:\n return { kind: \"cold\" };\n }\n}\n\nexport function makeSnapshotCommit(state: PersistedSandboxState): SandboxCommit {\n return toSnapshotCommit(state);\n}\n\nexport function asWorkspaceSandboxStateMetadata(\n state: WorkspaceSandboxState,\n): WorkspaceRecord[\"metadata\"] {\n return {\n [SANDBOX_METADATA_KEY]: toSerializedWorkspaceState(state) as JsonValue,\n };\n}\n\nexport function readWorkspaceSandboxState(workspace: WorkspaceRecord): WorkspaceSandboxState {\n const value = workspace.metadata?.[SANDBOX_METADATA_KEY];\n if (!isRecord(value)) {\n return { kind: \"cold\" };\n }\n\n const raw = value as RawWorkspaceSandboxState;\n if (\n raw.kind === \"session\" &&\n typeof raw.sessionId === \"string\" &&\n isSerializedSessionLease(raw.lease)\n ) {\n return {\n kind: \"session\",\n sandboxId: raw.sessionId,\n lease: {\n sandboxId: raw.sessionId,\n observedAt: raw.lease.observedAt,\n expiresAt: raw.lease.expiresAt,\n },\n sessionPolicy: readWorkspaceSessionPolicy(raw.policy),\n };\n }\n\n if (\n (raw.kind === \"session\" || raw.kind === \"sandbox-session\") &&\n typeof raw.sessionId === \"string\"\n ) {\n return { kind: \"cold\" };\n }\n\n if (raw.kind === \"snapshot\") {\n const snapshot = isPersistedSandboxState(raw.state) ? raw.state : null;\n if (!snapshot) {\n return { kind: \"cold\" };\n }\n\n return {\n kind: \"snapshot\",\n commit: toSnapshotCommit(snapshot),\n };\n }\n\n return { kind: \"cold\" };\n}\n\nexport function readWorkspaceSandboxLease(\n workspace: WorkspaceRecord,\n): WorkspaceSandboxLease | null {\n return workspaceSandboxLeaseFromState(readWorkspaceSandboxState(workspace));\n}\n\nexport function workspaceSandboxLeaseFromState(\n state: WorkspaceSandboxState,\n): WorkspaceSandboxLease | null {\n if (state.kind !== \"session\") {\n return null;\n }\n\n const expiresAtMs = Date.parse(state.lease.expiresAt);\n if (!Number.isFinite(expiresAtMs)) {\n return null;\n }\n\n const remainingMs = Math.max(0, expiresAtMs - Date.now());\n if (remainingMs <= 0) {\n return null;\n }\n\n return {\n sandboxId: state.sandboxId,\n observedAt: state.lease.observedAt,\n expiresAt: state.lease.expiresAt,\n remainingMs,\n };\n}\n\nexport function isWorkspaceSessionStateExpired(\n state: WorkspaceSandboxState,\n nowMs = Date.now(),\n): boolean {\n if (state.kind !== \"session\") {\n return false;\n }\n\n return Date.parse(state.lease.expiresAt) <= nowMs;\n}\n\nexport function transitionToCold(at = new Date().toISOString()): WorkspaceSandboxTransition {\n const nextState: WorkspaceSandboxState = { kind: \"cold\" };\n\n return {\n nextState,\n patch: {\n metadata: asWorkspaceSandboxStateMetadata(nextState),\n sandboxId: null,\n lastResumedAt: at,\n },\n };\n}\n\nexport function transitionToSession(\n sandboxId: string,\n lease: SandboxSessionLease,\n sessionPolicy?: WorkspacePolicy,\n): WorkspaceSandboxTransition {\n const nextState: WorkspaceSandboxState = {\n kind: \"session\",\n sandboxId,\n lease,\n sessionPolicy,\n };\n\n return {\n nextState,\n patch: {\n metadata: asWorkspaceSandboxStateMetadata(nextState),\n sandboxId,\n lastResumedAt: lease.observedAt,\n },\n };\n}\n\nexport function transitionAfterCommandCommit(\n commit: SandboxCommit,\n at: string,\n): WorkspaceSandboxTransition {\n const nextState: WorkspaceSandboxState = {\n kind: \"snapshot\",\n commit,\n };\n\n return {\n nextState,\n patch: {\n metadata: asWorkspaceSandboxStateMetadata(nextState),\n sandboxId: commit.state.sessionId,\n lastResumedAt: at,\n },\n };\n}\n\nexport function toDriverResumeState(state: WorkspaceSandboxState): PersistedSandboxState | null {\n if (state.kind === \"snapshot\") {\n return state.commit.state;\n }\n\n if (state.kind === \"session\") {\n return {\n kind: \"sandbox-session\",\n sessionId: state.sandboxId,\n };\n }\n\n return null;\n}\n\nexport async function persistSandboxTransition(\n store: WorkspaceStateStore,\n workspaceId: string,\n transition: WorkspaceSandboxTransition,\n): Promise<WorkspaceSandboxTransitionResult> {\n const record = await store.updateWorkspace(workspaceId, transition.patch);\n return {\n record,\n state: transition.nextState,\n };\n}\n","import type { WorkspacePolicy } from \"../policies/types.ts\";\nimport type {\n CommandResult,\n SandboxDriver,\n SandboxRunCommandOptions,\n WorkspaceSessionProcessStartInput,\n WorkspaceSessionProcess,\n WorkspaceSandboxLease,\n} from \"../types.ts\";\nimport { makeSnapshotCommit, type SandboxCommit } from \"./workspace-state.ts\";\n\nexport interface WorkspaceSandboxHandle {\n runCommand(command: string, args: string[]): Promise<CommandResult>;\n runCommand(input: SandboxRunCommandOptions): Promise<CommandResult>;\n /**\n * Opens a live sandbox lease. timeoutMs overrides the provider's default\n * lease timeout for this session start; it does not change runCommand()\n * semantics or command-level timeouts.\n */\n openSession(input?: { timeoutMs?: number }): Promise<WorkspaceSessionHandle>;\n attachSession(): Promise<WorkspaceSessionHandle>;\n getActiveLease(): Promise<WorkspaceSandboxLease | null>;\n}\n\nexport interface WorkspaceSessionHandle {\n exec(command: string, args: string[]): Promise<CommandResult>;\n exec(input: SandboxRunCommandOptions): Promise<CommandResult>;\n commit(): Promise<void>;\n /**\n * Sets a non-durable, session-scoped policy override for subsequent session\n * commands and process launches.\n */\n setPolicy(policy: WorkspacePolicy): Promise<void>;\n startProcess(command: string, args: string[]): Promise<WorkspaceSessionProcess>;\n startProcess(input: WorkspaceSessionProcessStartInput): Promise<WorkspaceSessionProcess>;\n url(port: number): Promise<string>;\n extendTimeout(durationMs: number): Promise<void>;\n}\n\ninterface RunStartInput {\n readonly command: string;\n readonly args: readonly string[];\n readonly effectivePolicy: WorkspacePolicy;\n readonly startedAt: string;\n}\n\ninterface RunFinishInput {\n readonly runId: string;\n readonly status: \"started\" | \"succeeded\" | \"failed\";\n readonly finishedAt: string;\n readonly exitCode?: number | null;\n readonly stdout?: string | null;\n readonly stderr?: string | null;\n readonly providerCommit?: unknown;\n}\n\ninterface RunLifecycle {\n readonly onRunStart?: (input: RunStartInput) => Promise<string>;\n readonly onRunFinish?: (input: RunFinishInput) => Promise<void>;\n}\n\ninterface SessionStateValidator {\n readonly assertActive: () => Promise<void>;\n}\n\ninterface SessionLeaseLifecycle {\n readonly onLeaseRefresh?: () => Promise<void>;\n}\n\ninterface SessionPolicyLifecycle {\n readonly initialSessionPolicy?: WorkspacePolicy;\n readonly onPolicyChange?: (policy: WorkspacePolicy) => Promise<void>;\n}\n\ntype CommitHook = (commit: SandboxCommit) => Promise<void>;\ntype DefaultPolicyResolver = () => Promise<WorkspacePolicy>;\n\nexport class ManagedSandbox {\n readonly #driver: SandboxDriver;\n readonly #onCommit?: CommitHook;\n readonly #runLifecycle?: RunLifecycle;\n readonly #resolveDefaultPolicy: DefaultPolicyResolver;\n\n constructor(\n driver: SandboxDriver,\n resolveDefaultPolicy: DefaultPolicyResolver,\n onCommit?: CommitHook,\n runLifecycle?: RunLifecycle,\n ) {\n this.#driver = driver;\n this.#resolveDefaultPolicy = resolveDefaultPolicy;\n this.#onCommit = onCommit;\n this.#runLifecycle = runLifecycle;\n }\n\n get id(): string {\n return this.#driver.id;\n }\n\n async runCommand(command: string, args: string[]): Promise<CommandResult>;\n async runCommand(input: SandboxRunCommandOptions): Promise<CommandResult>;\n async runCommand(\n inputOrCommand: string | SandboxRunCommandOptions,\n args: string[] = [],\n ): Promise<CommandResult> {\n const normalized = await this.normalizeRunCommandInput(inputOrCommand, args);\n this.ensureCommandShape(normalized.command, normalized.args);\n return this.runUnitOfWork(normalized.command, normalized.args, normalized.policy, () =>\n this.executeCommand(normalized.command, normalized.args, normalized.policy),\n );\n }\n\n private async normalizeRunCommandInput(\n inputOrCommand: string | SandboxRunCommandOptions,\n args: readonly string[],\n ): Promise<Required<SandboxRunCommandOptions>> {\n if (typeof inputOrCommand === \"string\") {\n return {\n command: inputOrCommand,\n args,\n policy: await this.#resolveDefaultPolicy(),\n };\n }\n\n return {\n command: inputOrCommand.command,\n args: inputOrCommand.args ?? [],\n policy: inputOrCommand.policy ?? (await this.#resolveDefaultPolicy()),\n };\n }\n\n private ensureCommandShape(command: string, args: readonly string[]): void {\n if (!command.trim()) {\n throw new Error(\"Sandbox command must not be empty.\");\n }\n\n if (!Array.isArray(args)) {\n throw new Error(\"Sandbox command arguments must be an array.\");\n }\n }\n\n private async runUnitOfWork(\n command: string,\n args: readonly string[],\n effectivePolicy: WorkspacePolicy,\n operation: () => Promise<CommandResult>,\n ): Promise<CommandResult> {\n const now = new Date().toISOString();\n const runId = await this.startRun(command, args, effectivePolicy, now);\n let commandError: unknown | undefined;\n let commandResult: CommandResult | undefined;\n\n try {\n commandResult = await operation();\n } catch (error) {\n commandError = error;\n }\n\n const finishedAt = new Date().toISOString();\n const commandStatus: \"succeeded\" | \"failed\" =\n commandError === undefined\n ? commandResult?.exitCode === 0\n ? \"succeeded\"\n : \"failed\"\n : \"failed\";\n let providerCommit: unknown;\n let finalizeError: unknown | undefined;\n\n try {\n const commit = await this.snapshotWithFallback();\n providerCommit = commit.state;\n\n if (this.#onCommit) {\n await this.persistCommit(commit);\n }\n } catch (error) {\n finalizeError = error;\n providerCommit = undefined;\n }\n\n const finalRunStatus: \"succeeded\" | \"failed\" =\n commandError === undefined && finalizeError === undefined ? commandStatus : \"failed\";\n\n try {\n if (runId) {\n await this.finishRun({\n runId,\n status: finalRunStatus,\n providerCommit,\n finishedAt,\n exitCode: commandResult?.exitCode,\n stdout: commandResult?.stdout,\n stderr: commandResult?.stderr,\n });\n }\n } catch (error) {\n finalizeError = finalizeError ?? error;\n }\n\n if (commandError !== undefined) {\n if (finalizeError !== undefined) {\n throw new AggregateError(\n [commandError, finalizeError],\n \"Sandbox command failed and unit-of-work durability finalization did not complete.\",\n );\n }\n throw commandError;\n }\n\n if (finalizeError !== undefined) {\n throw finalizeError;\n }\n\n if (!commandResult) {\n throw new Error(\"Command result was missing after successful execution.\");\n }\n\n return commandResult;\n }\n\n private async startRun(\n command: string,\n args: readonly string[],\n effectivePolicy: WorkspacePolicy,\n at: string,\n ): Promise<string | undefined> {\n if (!this.#runLifecycle?.onRunStart) {\n return undefined;\n }\n\n return this.#runLifecycle.onRunStart({\n command,\n args,\n effectivePolicy,\n startedAt: at,\n });\n }\n\n private async executeCommand(\n command: string,\n args: readonly string[],\n policy: WorkspacePolicy,\n ): Promise<CommandResult> {\n await this.#driver.applyPolicy(policy);\n return this.#driver.runCommand(command, [...args]);\n }\n\n private async finishRun(input: RunFinishInput): Promise<void> {\n if (!this.#runLifecycle?.onRunFinish) {\n return;\n }\n\n await this.#runLifecycle.onRunFinish(input);\n }\n\n private async snapshotWithFallback(): Promise<SandboxCommit> {\n const snapshot = await this.#driver.snapshot();\n return makeSnapshotCommit(snapshot);\n }\n\n private async persistCommit(commit: SandboxCommit): Promise<void> {\n if (!this.#onCommit) {\n return;\n }\n\n await this.#onCommit(commit);\n }\n}\n\nexport class ManagedSession implements WorkspaceSessionHandle {\n readonly #driver: SandboxDriver;\n readonly #onCommit?: CommitHook;\n readonly #resolveDefaultPolicy: DefaultPolicyResolver;\n readonly #onPolicyChange?: (policy: WorkspacePolicy) => Promise<void>;\n readonly #stateValidator?: SessionStateValidator;\n readonly #leaseLifecycle?: SessionLeaseLifecycle;\n #sessionPolicyOverride: WorkspacePolicy | undefined;\n #isActive = true;\n\n constructor(\n driver: SandboxDriver,\n resolveDefaultPolicy: DefaultPolicyResolver,\n onCommit?: CommitHook,\n stateValidator?: SessionStateValidator,\n leaseLifecycle?: SessionLeaseLifecycle,\n policyLifecycle?: SessionPolicyLifecycle,\n ) {\n this.#driver = driver;\n this.#resolveDefaultPolicy = resolveDefaultPolicy;\n this.#onCommit = onCommit;\n this.#stateValidator = stateValidator;\n this.#leaseLifecycle = leaseLifecycle;\n this.#onPolicyChange = policyLifecycle?.onPolicyChange;\n this.#sessionPolicyOverride = policyLifecycle?.initialSessionPolicy;\n }\n\n get id(): string {\n return this.#driver.id;\n }\n\n async exec(command: string, args: string[]): Promise<CommandResult>;\n async exec(input: SandboxRunCommandOptions): Promise<CommandResult>;\n async exec(\n inputOrCommand: string | SandboxRunCommandOptions,\n args: string[] = [],\n ): Promise<CommandResult> {\n await this.assertSessionActive();\n const normalized = await this.normalizeSessionInput(inputOrCommand, args);\n this.ensureCommandShape(normalized.command, normalized.args);\n await this.#driver.applyPolicy(normalized.policy);\n return this.#driver.runCommand(normalized.command, [...normalized.args]);\n }\n\n async commit(): Promise<void> {\n await this.assertSessionActive();\n let snapshot: SandboxCommit;\n try {\n snapshot = await this.snapshotWithFallback();\n if (this.#onCommit) {\n await this.persistCommit(snapshot);\n }\n } finally {\n this.#isActive = false;\n }\n }\n\n async setPolicy(policy: WorkspacePolicy): Promise<void> {\n await this.assertSessionActive();\n this.#sessionPolicyOverride = policy;\n await this.#driver.applyPolicy(policy);\n if (this.#onPolicyChange !== undefined) {\n await this.#onPolicyChange(policy);\n }\n }\n\n async startProcess(command: string, args: string[]): Promise<WorkspaceSessionProcess>;\n async startProcess(input: WorkspaceSessionProcessStartInput): Promise<WorkspaceSessionProcess>;\n async startProcess(\n inputOrCommand: string | WorkspaceSessionProcessStartInput,\n args: string[] = [],\n ): Promise<WorkspaceSessionProcess> {\n await this.assertSessionActive();\n const startProcess = this.#driver.startProcess;\n if (!startProcess) {\n throw new Error(`This sandbox provider does not support startProcess().`);\n }\n\n const normalized =\n typeof inputOrCommand === \"string\"\n ? {\n command: inputOrCommand,\n args,\n policy: this.#sessionPolicyOverride,\n onStdout: undefined,\n onStderr: undefined,\n }\n : inputOrCommand;\n if (!normalized.command.trim()) {\n throw new Error(\"Sandbox process command must not be empty.\");\n }\n if (!Array.isArray(normalized.args)) {\n throw new Error(\"Sandbox process args must be an array.\");\n }\n\n const policy = await this.resolveSessionPolicy(normalized.policy);\n await this.#driver.applyPolicy(policy);\n\n return startProcess.call(this.#driver, {\n command: normalized.command,\n args: [...normalized.args],\n policy,\n onStdout: normalized.onStdout,\n onStderr: normalized.onStderr,\n });\n }\n\n async url(port: number): Promise<string> {\n await this.assertSessionActive();\n const url = this.#driver.url;\n if (!url) {\n throw new Error(`This sandbox provider does not support url(port).`);\n }\n\n return url.call(this.#driver, port);\n }\n\n async extendTimeout(durationMs: number): Promise<void> {\n await this.assertSessionActive();\n const extendTimeout = this.#driver.extendTimeout;\n if (!extendTimeout) {\n throw new Error(`This sandbox provider does not support extendTimeout().`);\n }\n\n await extendTimeout.call(this.#driver, durationMs);\n if (this.#leaseLifecycle?.onLeaseRefresh) {\n await this.#leaseLifecycle.onLeaseRefresh();\n }\n }\n\n private async normalizeSessionInput(\n inputOrCommand: string | SandboxRunCommandOptions,\n args: readonly string[],\n ): Promise<Required<SandboxRunCommandOptions>> {\n if (typeof inputOrCommand === \"string\") {\n return {\n command: inputOrCommand,\n args,\n policy: await this.resolveSessionPolicy(),\n };\n }\n\n return {\n command: inputOrCommand.command,\n args: inputOrCommand.args ?? [],\n policy: await this.resolveSessionPolicy(inputOrCommand.policy),\n };\n }\n\n private async resolveSessionPolicy(override?: WorkspacePolicy): Promise<WorkspacePolicy> {\n if (override !== undefined) {\n return override;\n }\n\n if (this.#sessionPolicyOverride !== undefined) {\n return this.#sessionPolicyOverride;\n }\n\n return this.#resolveDefaultPolicy();\n }\n\n private ensureCommandShape(command: string, args: readonly string[]): void {\n if (!command.trim()) {\n throw new Error(\"Sandbox command must not be empty.\");\n }\n\n if (!Array.isArray(args)) {\n throw new Error(\"Sandbox command arguments must be an array.\");\n }\n }\n\n private async assertSessionActive(): Promise<void> {\n if (!this.#isActive) {\n throw new Error(\"This sandbox session has already been committed and is no longer active.\");\n }\n if (this.#stateValidator) {\n await this.#stateValidator.assertActive();\n }\n }\n\n private async snapshotWithFallback(): Promise<SandboxCommit> {\n const snapshot = await this.#driver.snapshot();\n return makeSnapshotCommit(snapshot);\n }\n\n private async persistCommit(commit: SandboxCommit): Promise<void> {\n if (!this.#onCommit) {\n return;\n }\n\n await this.#onCommit(commit);\n }\n}\n\nexport class LazySandboxHandle implements WorkspaceSandboxHandle {\n readonly #resolveSandbox: () => Promise<ManagedSandbox>;\n readonly #openSession: (input?: { timeoutMs?: number }) => Promise<WorkspaceSessionHandle>;\n readonly #attachSession: () => Promise<WorkspaceSessionHandle>;\n readonly #getActiveLease: () => Promise<WorkspaceSandboxLease | null>;\n\n constructor(\n resolveSandbox: () => Promise<ManagedSandbox>,\n openSession: (input?: { timeoutMs?: number }) => Promise<WorkspaceSessionHandle>,\n attachSession: () => Promise<WorkspaceSessionHandle>,\n getActiveLease: () => Promise<WorkspaceSandboxLease | null>,\n ) {\n this.#resolveSandbox = resolveSandbox;\n this.#openSession = openSession;\n this.#attachSession = attachSession;\n this.#getActiveLease = getActiveLease;\n }\n\n async runCommand(command: string, args: string[]): Promise<CommandResult>;\n async runCommand(input: SandboxRunCommandOptions): Promise<CommandResult>;\n async runCommand(\n inputOrCommand: string | SandboxRunCommandOptions,\n args: string[] = [],\n ): Promise<CommandResult> {\n const sandbox = await this.#resolveSandbox();\n if (typeof inputOrCommand === \"string\") {\n return sandbox.runCommand(inputOrCommand, args);\n }\n return sandbox.runCommand(inputOrCommand);\n }\n\n async openSession(input?: { timeoutMs?: number }): Promise<WorkspaceSessionHandle> {\n return this.#openSession(input);\n }\n\n async attachSession(): Promise<WorkspaceSessionHandle> {\n return this.#attachSession();\n }\n\n async getActiveLease(): Promise<WorkspaceSandboxLease | null> {\n return this.#getActiveLease();\n }\n}\n","import { allowAll } from \"../policies/dsl.ts\";\nimport { assertWorkspacePolicyIsDurable } from \"../policies/dsl.ts\";\nimport type {\n RunFinishInput as AdapterRunFinishInput,\n SandboxDriver,\n SandboxCreateOptions,\n SandboxSessionLease,\n WorkspacePolicy,\n WorkspaceRecord,\n WorkspaceSandboxLease,\n PersistedSandboxState,\n} from \"../types.ts\";\nimport type { SandkitContext } from \"./context.ts\";\nimport {\n LazySandboxHandle,\n ManagedSandbox,\n ManagedSession,\n type WorkspaceSessionHandle,\n type WorkspaceSandboxHandle,\n} from \"./sandbox.ts\";\nimport {\n asPolicySnapshotConfig,\n asWorkspacePolicyPatch,\n describeWorkspacePolicyId,\n readWorkspacePolicy,\n} from \"./workspace-policy.ts\";\nimport {\n readWorkspaceSandboxConfig,\n type WorkspaceSandboxConfig,\n} from \"./workspace-sandbox-config.ts\";\nimport type { SandboxCommit, WorkspaceSandboxState } from \"./workspace-state.ts\";\nimport {\n isWorkspaceSessionStateExpired,\n persistSandboxTransition,\n readWorkspaceSandboxLease,\n readWorkspaceSandboxState,\n toDriverResumeState,\n transitionAfterCommandCommit,\n transitionToCold,\n transitionToSession,\n type WorkspaceSandboxTransition,\n} from \"./workspace-state.ts\";\n\nfunction setupStateFingerprint(\n command: string,\n args: readonly string[],\n policy: WorkspacePolicy | undefined,\n): string {\n return encodeURIComponent(\n JSON.stringify({\n command,\n args,\n policy: policy\n ? {\n id: describeWorkspacePolicyId(policy),\n config: asPolicySnapshotConfig(policy),\n }\n : null,\n }),\n );\n}\n\nexport const sharedSetupStateId = (\n adapterId: string,\n setup: { command: string; args?: readonly string[]; policy?: WorkspacePolicy } | undefined,\n): string => {\n if (setup?.policy) {\n assertWorkspacePolicyIsDurable(setup.policy);\n }\n const fingerprint = setup\n ? setupStateFingerprint(setup.command, [...(setup.args ?? [])], setup.policy)\n : \"no-bootstrap\";\n return `${adapterId}:shared-bootstrap:${fingerprint}`;\n};\n\nexport interface PublicWorkspaceHandle {\n readonly id: string;\n readonly descriptor: WorkspaceDescriptor;\n readonly sandbox: WorkspaceSandboxHandle;\n setPolicy(policy: WorkspacePolicy): Promise<void>;\n}\n\nexport type WorkspaceStatus = \"active\" | \"inactive\" | \"archived\";\n\nexport interface WorkspaceDescriptor {\n readonly id: string;\n readonly name?: string;\n readonly status: WorkspaceStatus;\n readonly createdAt: string;\n readonly updatedAt: string;\n}\n\ninterface RunFinishInput extends AdapterRunFinishInput {\n runId: string;\n}\n\nexport class WorkspaceHandle implements PublicWorkspaceHandle {\n readonly #ctx: SandkitContext;\n #record: WorkspaceRecord;\n #sandboxState: WorkspaceSandboxState;\n #sandboxConfig: WorkspaceSandboxConfig;\n #descriptor: WorkspaceDescriptor;\n #lazySandbox?: LazySandboxHandle;\n\n constructor(ctx: SandkitContext, record: WorkspaceRecord) {\n this.#ctx = ctx;\n this.#record = record;\n this.#descriptor = this.resolveDescriptor(record);\n this.#sandboxState = readWorkspaceSandboxState(record);\n this.#sandboxConfig = readWorkspaceSandboxConfig(record);\n }\n\n get id(): string {\n return this.#record.id;\n }\n\n get descriptor(): WorkspaceDescriptor {\n return this.#descriptor;\n }\n\n get sandbox(): LazySandboxHandle {\n if (!this.#lazySandbox) {\n this.#lazySandbox = new LazySandboxHandle(\n () => this.createOrResumeSandboxForCommand(),\n (input?: { timeoutMs?: number }) => this.openSession(input),\n () => this.attachSession(),\n () => this.getActiveLease(),\n );\n }\n\n return this.#lazySandbox;\n }\n\n async setPolicy(policy: WorkspacePolicy): Promise<void> {\n await this.resolveLatestWorkspace();\n const result = await this.#ctx.adapter.workspaces.updateWorkspace(\n this.#record.id,\n asWorkspacePolicyPatch(policy),\n );\n this.updateFromRecord(result);\n this.#sandboxState = readWorkspaceSandboxState(result);\n }\n\n /**\n * Returns a current lease only if a session is still attachable and unexpired.\n * This is attachment-state derived from persisted metadata; it is not intended\n * to reset expiry on read.\n */\n async getActiveLease(): Promise<WorkspaceSandboxLease | null> {\n await this.resolveLatestWorkspace();\n const sandbox = await this.resolveAttachableSession();\n if (!sandbox) {\n return null;\n }\n\n return readWorkspaceSandboxLease(this.#record);\n }\n\n async createOrResumeSandboxForCommand(): Promise<ManagedSandbox> {\n await this.resolveLatestWorkspace();\n if (await this.resolveAttachableSession()) {\n throw new Error(\n \"Cannot run command while a sandbox session is active. Use attachSession() to reuse it or commit the session first.\",\n );\n }\n\n const workspace = await this.resolveLatestWorkspace();\n const sandbox = await this.resolveSandboxDriver(workspace);\n\n return this.createManagedSandbox(sandbox);\n }\n\n async openSession(input?: { timeoutMs?: number }): Promise<WorkspaceSessionHandle> {\n await this.resolveLatestWorkspace();\n if (await this.resolveAttachableSession()) {\n throw new Error(\"A sandbox session is already active for this workspace.\");\n }\n\n const workspace = await this.resolveLatestWorkspace();\n const sandbox = await this.resolveSandboxDriver(workspace, {\n timeoutMs: normalizeSessionTimeoutMs(input?.timeoutMs),\n });\n const lease = await sandbox.getSessionLease();\n await this.persistSandboxState(transitionToSession(sandbox.id, lease));\n\n return this.makeSession(sandbox);\n }\n\n async attachSession(): Promise<WorkspaceSessionHandle> {\n await this.resolveLatestWorkspace();\n const sandbox = await this.resolveAttachableSession();\n if (!sandbox) {\n throw new Error(\"There is no active sandbox session to attach for this workspace.\");\n }\n\n return this.makeSession(sandbox);\n }\n\n private async persistSessionPolicy(policy: WorkspacePolicy): Promise<void> {\n await this.resolveLatestWorkspace();\n if (!workspaceStateIsSession(this.#sandboxState)) {\n throw new Error(\"Cannot persist session policy without an active sandbox session.\");\n }\n\n await this.persistSandboxState(\n transitionToSession(this.#sandboxState.sandboxId, this.#sandboxState.lease, policy),\n );\n }\n\n private makeSession(sandbox: SandboxDriver): ManagedSession {\n const sessionPolicy = workspaceStateIsSession(this.#sandboxState)\n ? this.#sandboxState.sessionPolicy\n : undefined;\n\n return new ManagedSession(\n sandbox,\n async () => this.resolveDefaultPolicy(),\n async (commit: SandboxCommit) =>\n this.persistSandboxState(transitionAfterCommandCommit(commit, new Date().toISOString())),\n {\n assertActive: async () => {\n const activeSandbox = await this.resolveAttachableSession();\n if (!activeSandbox || activeSandbox.id !== sandbox.id) {\n throw new Error(\"This sandbox session is no longer active.\");\n }\n },\n },\n {\n onLeaseRefresh: async () => {\n const lease = await sandbox.getSessionLease();\n await this.refreshSessionLease(sandbox.id, lease);\n },\n },\n {\n initialSessionPolicy: sessionPolicy,\n onPolicyChange: async (policy: WorkspacePolicy) => {\n await this.persistSessionPolicy(policy);\n },\n },\n );\n }\n\n private async refreshSessionLease(sandboxId: string, lease: SandboxSessionLease): Promise<void> {\n await this.resolveLatestWorkspace();\n if (\n !workspaceStateIsSession(this.#sandboxState) ||\n this.#sandboxState.sandboxId !== sandboxId\n ) {\n throw new Error(\"Cannot refresh lease for an inactive sandbox session.\");\n }\n\n await this.persistSandboxState(\n transitionToSession(sandboxId, lease, this.#sandboxState.sessionPolicy),\n );\n }\n\n private async resolveAttachableSession(): Promise<SandboxDriver | null> {\n if (!workspaceStateIsSession(this.#sandboxState)) {\n return null;\n }\n\n if (isWorkspaceSessionStateExpired(this.#sandboxState)) {\n await this.persistSandboxState(transitionToCold());\n return null;\n }\n\n try {\n return await this.resolveSandboxDriver(this.#record);\n } catch (error) {\n if (!this.#ctx.driverFactory.isSessionUnavailableError?.(error)) {\n throw error;\n }\n\n await this.persistSandboxState(transitionToCold());\n return null;\n }\n }\n\n private async resolveSandboxDriver(\n workspace: WorkspaceRecord,\n overrides?: { timeoutMs?: number },\n ): Promise<SandboxDriver> {\n const policy = readWorkspacePolicy(workspace, allowAll());\n const options = this.makeSandboxDriverOptions(policy, overrides?.timeoutMs);\n const currentState = toDriverResumeState(this.#sandboxState);\n if (currentState) {\n return this.#ctx.driverFactory.resumeSandbox(workspace, currentState, options);\n }\n\n try {\n const setupState = await this.#readSharedSetupState();\n if (!setupState) {\n return this.#bootstrapSetupState(workspace, options);\n }\n\n return await this.#ctx.driverFactory.resumeSandbox(workspace, setupState, options);\n } catch (error) {\n if (\n !this.#ctx.driverFactory.isSessionUnavailableError?.(error) &&\n !this.#isRecoverableSetupStateError(error)\n ) {\n throw error;\n }\n\n await this.#clearSharedSetupState();\n return this.#bootstrapSetupState(workspace, options);\n }\n }\n\n async #bootstrapSetupState(\n workspace: WorkspaceRecord,\n options: SandboxCreateOptions,\n ): Promise<SandboxDriver> {\n const setup = this.#ctx.options.setup;\n if (!setup) {\n return this.#ctx.driverFactory.createSandbox(workspace, options);\n }\n\n const setupPolicy = setup.policy ?? options.policy;\n const sandbox = await this.#ctx.driverFactory.createSandbox(workspace, {\n ...options,\n policy: setupPolicy,\n });\n const result = await sandbox.runCommand(setup.command, [...(setup.args ?? [])]);\n if (result.exitCode !== 0) {\n throw new Error(\n `Workspace setup failed with exit code ${result.exitCode}. ${result.stderr.trim()}`.trim(),\n );\n }\n\n const setupState = await sandbox.snapshot();\n await this.#persistSharedSetupState(setupState);\n\n return this.#ctx.driverFactory.resumeSandbox(workspace, setupState, options);\n }\n\n async #readSharedSetupState(): Promise<PersistedSandboxState | null> {\n if (!this.#ctx.options.setup) {\n return null;\n }\n\n const setupState = await this.#ctx.adapter.setupStates.getSetupState(\n this.#sharedSetupStateId(),\n );\n return setupState ? setupState.state : null;\n }\n\n async #persistSharedSetupState(state: PersistedSandboxState): Promise<void> {\n await this.#ctx.adapter.setupStates.putSetupState({\n id: this.#sharedSetupStateId(),\n state: {\n kind: state.kind,\n sessionId: state.sessionId,\n state: state.state,\n },\n });\n }\n\n async #clearSharedSetupState(): Promise<void> {\n await this.#ctx.adapter.setupStates.deleteSetupState(this.#sharedSetupStateId());\n }\n\n #sharedSetupStateId(): string {\n return sharedSetupStateId(this.#ctx.adapter.id, this.#ctx.options.setup);\n }\n\n #isRecoverableSetupStateError(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n\n return (\n error.message.includes(\"Sandkit durable state corruption\") &&\n error.message.includes(\"sandkit_setup_states\")\n );\n }\n\n private createManagedSandbox(sandbox: SandboxDriver): ManagedSandbox {\n return new ManagedSandbox(\n sandbox,\n async () => this.resolveDefaultPolicy(),\n async (commit: SandboxCommit) =>\n this.persistSandboxState(transitionAfterCommandCommit(commit, new Date().toISOString())),\n this.createRunLifecycle(sandbox),\n );\n }\n\n private makeSandboxDriverOptions(\n policy: WorkspacePolicy,\n timeoutMs: number | undefined,\n ): SandboxCreateOptions {\n const next: {\n policy: WorkspacePolicy;\n exposedPorts?: readonly number[];\n timeoutMs?: number;\n } = {\n policy,\n };\n\n if (this.#sandboxConfig.exposedPorts && this.#sandboxConfig.exposedPorts.length > 0) {\n next.exposedPorts = this.#sandboxConfig.exposedPorts;\n }\n if (timeoutMs !== undefined) {\n next.timeoutMs = timeoutMs;\n }\n\n return next;\n }\n\n private createRunLifecycle(sandbox: SandboxDriver) {\n return {\n onRunStart: async (input: {\n command: string;\n args: readonly string[];\n effectivePolicy: WorkspacePolicy;\n startedAt: string;\n }) => {\n const policySnapshot = await this.createPolicySnapshot(input.effectivePolicy);\n const run = await this.#ctx.adapter.runs.createRun({\n workspaceId: this.#record.id,\n provider: sandbox.provider,\n executionTargetId: sandbox.id,\n command: input.command,\n args: input.args,\n status: \"started\",\n startedAt: input.startedAt,\n policySnapshotId: policySnapshot.id,\n });\n\n return run.id;\n },\n onRunFinish: async (input: RunFinishInput) => {\n await this.#ctx.adapter.runs.finishRun(input.runId, {\n status: input.status,\n finishedAt: input.finishedAt,\n exitCode: input.exitCode ?? null,\n stdout: input.stdout ?? null,\n stderr: input.stderr ?? null,\n providerCommit: input.providerCommit,\n });\n },\n };\n }\n\n private async persistSandboxState(transition: WorkspaceSandboxTransition): Promise<void> {\n const result = await persistSandboxTransition(\n this.#ctx.adapter.workspaces,\n this.#record.id,\n transition,\n );\n this.updateFromRecord(result.record);\n this.#sandboxState = result.state;\n }\n\n private async resolveLatestWorkspace(): Promise<WorkspaceRecord> {\n const latest = await this.#ctx.adapter.workspaces.getWorkspace(this.#record.id);\n if (!latest) {\n throw new Error(`Workspace with id \"${this.#record.id}\" no longer exists`);\n }\n\n this.updateFromRecord(latest);\n this.#sandboxState = readWorkspaceSandboxState(latest);\n this.#sandboxConfig = readWorkspaceSandboxConfig(latest);\n if (isWorkspaceSessionStateExpired(this.#sandboxState)) {\n const result = await persistSandboxTransition(\n this.#ctx.adapter.workspaces,\n this.#record.id,\n transitionToCold(),\n );\n this.updateFromRecord(result.record);\n this.#sandboxState = result.state;\n this.#sandboxConfig = readWorkspaceSandboxConfig(result.record);\n }\n\n return this.#record;\n }\n\n private resolveDescriptor(record: WorkspaceRecord): WorkspaceDescriptor {\n return {\n id: record.id,\n name: record.name,\n status: record.status,\n createdAt: record.createdAt,\n updatedAt: record.updatedAt,\n };\n }\n\n private updateFromRecord(record: WorkspaceRecord): void {\n this.#record = record;\n this.#descriptor = this.resolveDescriptor(record);\n this.#sandboxConfig = readWorkspaceSandboxConfig(record);\n }\n\n private async createPolicySnapshot(policy: WorkspacePolicy) {\n return this.#ctx.adapter.policySnapshots.createPolicySnapshot({\n workspaceId: this.#record.id,\n policyId: describeWorkspacePolicyId(policy),\n config: asPolicySnapshotConfig(policy),\n });\n }\n\n private async resolveDefaultPolicy(): Promise<WorkspacePolicy> {\n const workspace = await this.resolveLatestWorkspace();\n return readWorkspacePolicy(workspace, allowAll());\n }\n}\n\nfunction normalizeSessionTimeoutMs(timeoutMs: number | undefined): number | undefined {\n if (timeoutMs === undefined) {\n return undefined;\n }\n\n if (!Number.isInteger(timeoutMs) || !Number.isFinite(timeoutMs) || timeoutMs <= 0) {\n throw new Error(\"openSession timeoutMs must be a positive integer in milliseconds.\");\n }\n\n return timeoutMs;\n}\n\nfunction workspaceStateIsSession(\n state: WorkspaceSandboxState,\n): state is Extract<WorkspaceSandboxState, { kind: \"session\" }> {\n return state.kind === \"session\";\n}\n","import type { SandkitOptions, WorkspaceCreateOptions } from \"../types.ts\";\nimport { createSandkitContext, type SandkitContext } from \"./context.ts\";\nimport { asWorkspacePolicyMetadata, removeWorkspacePolicyMetadata } from \"./workspace-policy.ts\";\nimport {\n asWorkspaceSandboxConfigMetadata,\n normalizeWorkspaceSandboxCreateConfig,\n removeWorkspaceSandboxConfigMetadata,\n} from \"./workspace-sandbox-config.ts\";\nimport { type PublicWorkspaceHandle, WorkspaceHandle } from \"./workspace.ts\";\n\nexport class Sandkit {\n readonly #ctx: SandkitContext;\n\n constructor(options: SandkitOptions) {\n this.#ctx = createSandkitContext(options);\n }\n\n get context(): SandkitContext {\n return this.#ctx;\n }\n\n async createWorkspace(input: WorkspaceCreateOptions = {}): Promise<PublicWorkspaceHandle> {\n const { id, name, policy, metadata, status, sandboxId, lastResumedAt } = input;\n const sandboxConfig = normalizeWorkspaceSandboxCreateConfig(input.sandbox);\n const sanitizedMetadata = removeWorkspaceSandboxConfigMetadata(\n removeWorkspacePolicyMetadata(metadata),\n );\n const workspaceMetadata = policy\n ? {\n ...sanitizedMetadata,\n ...asWorkspacePolicyMetadata(policy),\n ...asWorkspaceSandboxConfigMetadata(sandboxConfig),\n }\n : {\n ...sanitizedMetadata,\n ...asWorkspaceSandboxConfigMetadata(sandboxConfig),\n };\n\n const workspace = await this.#ctx.adapter.workspaces.createWorkspace({\n id,\n name,\n metadata: workspaceMetadata,\n status,\n sandboxId,\n lastResumedAt,\n });\n return new WorkspaceHandle(this.#ctx, workspace);\n }\n\n async getWorkspace(id: string): Promise<PublicWorkspaceHandle> {\n const workspace = await this.#ctx.adapter.workspaces.getWorkspace(id);\n if (!workspace) {\n throw new Error(`Workspace not found: ${id}`);\n }\n\n return new WorkspaceHandle(this.#ctx, workspace);\n }\n}\n\nexport function createSandkit(options: SandkitOptions): Sandkit {\n return new Sandkit(options);\n}\n"],"mappings":"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","names":["corruptionError"]}
1
+ {"version":3,"sources":["../src/core/context.ts","../src/core/workspace-policy.ts","../src/core/workspace-sandbox-config.ts","../src/core/workspace-state.ts","../src/core/sandbox.ts","../src/core/workspace.ts","../src/core/sandkit.ts"],"sourcesContent":["import { createMemoryAdapter } from \"../adapters/index.ts\";\nimport { getSandboxDriverFactory } from \"../types.ts\";\nimport type { SandkitOptions, SandboxDriverFactory } from \"../types.ts\";\n\nexport interface SandkitContext {\n readonly adapter: NonNullable<SandkitOptions[\"database\"]>;\n readonly driverFactory: SandboxDriverFactory;\n readonly options: SandkitOptions;\n}\n\nfunction resolveDeprecatedNetworkOption(options: SandkitOptions): void {\n if (options.network !== undefined) {\n throw new Error(\n \"SandkitOptions.network has been removed. Use createWorkspace({ policy }), workspace.setPolicy(...), or per-run policy overrides instead.\",\n );\n }\n}\n\nexport function createSandkitContext(options: SandkitOptions): SandkitContext {\n if (!options) {\n throw new Error(\"SandkitOptions is required. Set sandbox to a Sandkit sandbox provider.\");\n }\n\n resolveDeprecatedNetworkOption(options);\n if (!options.sandbox) {\n throw new Error(\n \"SandkitOptions.sandbox is required. Set it to a Sandkit sandbox provider (for example, vercelSandbox(...)).\",\n );\n }\n\n return {\n adapter: options.database ?? createMemoryAdapter(),\n driverFactory: getSandboxDriverFactory(options.sandbox),\n options,\n };\n}\n","import type {\n WorkspaceMetadata,\n WorkspaceRecord,\n WorkspaceUpdateInput,\n} from \"../adapters/types.ts\";\nimport {\n allowAll,\n assertWorkspacePolicyIsDurable,\n describeWorkspacePolicy,\n parseWorkspacePolicy,\n redactWorkspacePolicy,\n serializeWorkspacePolicy,\n} from \"../policies/dsl.ts\";\nimport type { WorkspacePolicy } from \"../policies/types.ts\";\n\nexport const WORKSPACE_POLICY_METADATA_KEY = \"sandkit:policy\";\n\nfunction corruptionError(reason: string): Error {\n return new Error(`Sandkit durable state corruption in sandkit_workspaces.metadata: ${reason}`);\n}\n\nexport function readWorkspacePolicy(\n workspace: WorkspaceRecord,\n fallback: WorkspacePolicy = allowAll(),\n): WorkspacePolicy {\n const value = workspace.metadata?.[WORKSPACE_POLICY_METADATA_KEY];\n if (value === undefined) {\n return fallback;\n }\n\n try {\n return parseWorkspacePolicy(value);\n } catch (error) {\n throw corruptionError(error instanceof Error ? error.message : \"invalid workspace policy\");\n }\n}\n\nexport function asWorkspacePolicyMetadata(policy: WorkspacePolicy): WorkspaceMetadata {\n assertWorkspacePolicyIsDurable(policy);\n return {\n [WORKSPACE_POLICY_METADATA_KEY]: serializeWorkspacePolicy(policy),\n };\n}\n\nexport function removeWorkspacePolicyMetadata(\n metadata?: WorkspaceMetadata | undefined,\n): WorkspaceMetadata | undefined {\n if (!metadata || typeof metadata !== \"object\") {\n return metadata;\n }\n\n if (!Object.prototype.hasOwnProperty.call(metadata, WORKSPACE_POLICY_METADATA_KEY)) {\n return metadata;\n }\n\n const { [WORKSPACE_POLICY_METADATA_KEY]: _policyMetadata, ...rest } = metadata;\n return rest;\n}\n\nexport function asWorkspacePolicyPatch(policy: WorkspacePolicy): WorkspaceUpdateInput {\n return {\n metadata: asWorkspacePolicyMetadata(policy),\n };\n}\n\nexport function describeWorkspacePolicyId(policy: WorkspacePolicy): string {\n return describeWorkspacePolicy(policy);\n}\n\nexport function asPolicySnapshotConfig(policy: WorkspacePolicy): unknown {\n return redactWorkspacePolicy(policy);\n}\n","import type { WorkspaceMetadata, WorkspaceRecord } from \"../adapters/types.ts\";\nimport type { WorkspaceCreateOptions } from \"../types.ts\";\n\nexport const WORKSPACE_SANDBOX_CONFIG_METADATA_KEY = \"sandkit:sandbox-config\";\n\nexport interface WorkspaceSandboxConfig {\n readonly exposedPorts?: readonly number[];\n}\n\nfunction isFinitePort(value: unknown): value is number {\n return typeof value === \"number\" && Number.isInteger(value) && value >= 1 && value <= 65535;\n}\n\nfunction normalizeExposedPorts(ports: unknown): readonly number[] {\n if (ports === undefined) {\n return [];\n }\n\n if (!Array.isArray(ports)) {\n throw new Error(\"exposedPorts must be an array of positive integers in [1, 65535]\");\n }\n\n const normalized = ports.map((value, index) => {\n if (!isFinitePort(value)) {\n throw new Error(`exposedPorts[${index}] must be a positive integer in [1, 65535]`);\n }\n\n return value;\n });\n\n return [...normalized];\n}\n\nfunction corruptionError(reason: string): Error {\n return new Error(`Sandkit durable state corruption in sandkit_workspaces.metadata: ${reason}`);\n}\n\nfunction readWorkspaceSandboxConfigValue(value: unknown): WorkspaceSandboxConfig {\n if (value === undefined) {\n return {};\n }\n\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n throw new Error(\"Expected sandbox config metadata object\");\n }\n\n const candidate = value as WorkspaceSandboxConfig;\n const ports = normalizeExposedPorts((candidate as { exposedPorts?: unknown }).exposedPorts);\n return ports.length === 0 ? {} : { exposedPorts: ports };\n}\n\nexport function normalizeWorkspaceSandboxCreateConfig(\n config?: WorkspaceCreateOptions[\"sandbox\"],\n): WorkspaceSandboxConfig {\n if (config === undefined) {\n return {};\n }\n\n return {\n exposedPorts: normalizeExposedPorts(config.exposedPorts),\n };\n}\n\nexport function asWorkspaceSandboxConfigMetadata(\n config: WorkspaceSandboxConfig,\n): WorkspaceMetadata {\n if (!config.exposedPorts || config.exposedPorts.length === 0) {\n return {};\n }\n\n return {\n [WORKSPACE_SANDBOX_CONFIG_METADATA_KEY]: {\n exposedPorts: [...config.exposedPorts],\n },\n };\n}\n\nexport function removeWorkspaceSandboxConfigMetadata(\n metadata?: WorkspaceMetadata | undefined,\n): WorkspaceMetadata | undefined {\n if (!metadata || typeof metadata !== \"object\") {\n return metadata;\n }\n\n if (!Object.prototype.hasOwnProperty.call(metadata, WORKSPACE_SANDBOX_CONFIG_METADATA_KEY)) {\n return metadata;\n }\n\n const { [WORKSPACE_SANDBOX_CONFIG_METADATA_KEY]: _sandboxConfigMetadata, ...rest } = metadata;\n return rest;\n}\n\nexport function readWorkspaceSandboxConfig(workspace: WorkspaceRecord): WorkspaceSandboxConfig {\n const metadataValue = workspace.metadata?.[WORKSPACE_SANDBOX_CONFIG_METADATA_KEY];\n if (metadataValue === undefined) {\n return {};\n }\n\n try {\n return readWorkspaceSandboxConfigValue(metadataValue);\n } catch (error) {\n throw corruptionError(\n error instanceof Error ? error.message : \"invalid workspace sandbox config\",\n );\n }\n}\n","import type { WorkspaceRecord, WorkspaceUpdateInput } from \"../adapters/types.ts\";\nimport { parseWorkspacePolicy, serializeWorkspacePolicy } from \"../policies/dsl.ts\";\nimport type { WorkspacePolicy } from \"../policies/types.ts\";\nimport type {\n JsonValue,\n PersistedSandboxState,\n SandboxSessionLease,\n WorkspaceSandboxLease,\n} from \"../types.ts\";\n\nconst SANDBOX_METADATA_KEY = \"sandkit:sandbox\";\n\ntype RawWorkspaceSandboxState = {\n kind?: unknown;\n sessionId?: unknown;\n state?: unknown;\n lease?: unknown;\n policy?: unknown;\n};\n\ntype SerializedWorkspaceSandboxState =\n | { kind: \"cold\" }\n | {\n kind: \"session\";\n sessionId: string;\n lease: SerializedSessionLease;\n policy?: JsonValue;\n }\n | { kind: \"snapshot\"; state: PersistedSandboxState };\n\ntype SerializedSessionLease = {\n observedAt: string;\n expiresAt: string;\n};\n\ninterface WorkspaceSandboxStateBase {\n readonly kind: string;\n}\n\ninterface WorkspaceSandboxStateCold extends WorkspaceSandboxStateBase {\n readonly kind: \"cold\";\n}\n\ninterface WorkspaceSandboxStateSession extends WorkspaceSandboxStateBase {\n readonly kind: \"session\";\n readonly sandboxId: string;\n readonly lease: SandboxSessionLease;\n readonly sessionPolicy?: WorkspacePolicy;\n}\n\ninterface WorkspaceSandboxStateSnapshot extends WorkspaceSandboxStateBase {\n readonly kind: \"snapshot\";\n readonly commit: SandboxCommit;\n}\n\nexport type WorkspaceSandboxState =\n | WorkspaceSandboxStateCold\n | WorkspaceSandboxStateSession\n | WorkspaceSandboxStateSnapshot;\n\nexport type SandboxCommit = SandboxSnapshotCommit;\n\ninterface SandboxSnapshotCommit {\n readonly kind: \"snapshot\";\n readonly state: PersistedSandboxState;\n}\n\nexport interface WorkspaceSandboxTransition {\n readonly nextState: WorkspaceSandboxState;\n readonly patch: WorkspaceUpdateInput;\n}\n\nexport interface WorkspaceSandboxTransitionResult {\n readonly record: WorkspaceRecord;\n readonly state: WorkspaceSandboxState;\n}\n\nexport interface WorkspaceStateStore {\n updateWorkspace(id: string, input: WorkspaceUpdateInput): Promise<WorkspaceRecord>;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isPersistedSandboxState(value: unknown): value is PersistedSandboxState {\n if (!isRecord(value)) {\n return false;\n }\n\n if (typeof value.kind !== \"string\" || typeof value.sessionId !== \"string\") {\n return false;\n }\n\n return value.state === undefined || isJsonValue(value.state);\n}\n\nfunction isJsonValue(value: unknown): value is JsonValue {\n if (\n value === null ||\n typeof value === \"boolean\" ||\n typeof value === \"number\" ||\n typeof value === \"string\"\n ) {\n return true;\n }\n\n if (Array.isArray(value)) {\n return value.every((item) => isJsonValue(item));\n }\n\n if (!isRecord(value)) {\n return false;\n }\n\n return Object.values(value).every((item) => isJsonValue(item));\n}\n\nfunction isIsoTimestamp(value: unknown): value is string {\n return typeof value === \"string\" && !Number.isNaN(Date.parse(value));\n}\n\nfunction isSerializedSessionLease(value: unknown): value is SerializedSessionLease {\n if (!isRecord(value)) {\n return false;\n }\n\n return isIsoTimestamp(value.observedAt) && isIsoTimestamp(value.expiresAt);\n}\n\nfunction readWorkspaceSessionPolicy(value: unknown): WorkspacePolicy | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n try {\n return parseWorkspacePolicy(value);\n } catch {\n return undefined;\n }\n}\n\nfunction toSnapshotCommit(snapshot: PersistedSandboxState): SandboxSnapshotCommit {\n return { kind: \"snapshot\", state: snapshot };\n}\n\nfunction toSerializedWorkspaceState(state: WorkspaceSandboxState): SerializedWorkspaceSandboxState {\n switch (state.kind) {\n case \"cold\":\n return { kind: \"cold\" };\n case \"session\":\n return {\n kind: \"session\",\n sessionId: state.sandboxId,\n lease: {\n observedAt: state.lease.observedAt,\n expiresAt: state.lease.expiresAt,\n },\n policy:\n state.sessionPolicy === undefined\n ? undefined\n : serializeWorkspacePolicy(state.sessionPolicy),\n };\n case \"snapshot\":\n return { kind: \"snapshot\", state: state.commit.state };\n default:\n return { kind: \"cold\" };\n }\n}\n\nexport function makeSnapshotCommit(state: PersistedSandboxState): SandboxCommit {\n return toSnapshotCommit(state);\n}\n\nexport function asWorkspaceSandboxStateMetadata(\n state: WorkspaceSandboxState,\n): WorkspaceRecord[\"metadata\"] {\n return {\n [SANDBOX_METADATA_KEY]: toSerializedWorkspaceState(state) as JsonValue,\n };\n}\n\nexport function readWorkspaceSandboxState(workspace: WorkspaceRecord): WorkspaceSandboxState {\n const value = workspace.metadata?.[SANDBOX_METADATA_KEY];\n if (!isRecord(value)) {\n return { kind: \"cold\" };\n }\n\n const raw = value as RawWorkspaceSandboxState;\n if (\n raw.kind === \"session\" &&\n typeof raw.sessionId === \"string\" &&\n isSerializedSessionLease(raw.lease)\n ) {\n return {\n kind: \"session\",\n sandboxId: raw.sessionId,\n lease: {\n sandboxId: raw.sessionId,\n observedAt: raw.lease.observedAt,\n expiresAt: raw.lease.expiresAt,\n },\n sessionPolicy: readWorkspaceSessionPolicy(raw.policy),\n };\n }\n\n if (\n (raw.kind === \"session\" || raw.kind === \"sandbox-session\") &&\n typeof raw.sessionId === \"string\"\n ) {\n return { kind: \"cold\" };\n }\n\n if (raw.kind === \"snapshot\") {\n const snapshot = isPersistedSandboxState(raw.state) ? raw.state : null;\n if (!snapshot) {\n return { kind: \"cold\" };\n }\n\n return {\n kind: \"snapshot\",\n commit: toSnapshotCommit(snapshot),\n };\n }\n\n return { kind: \"cold\" };\n}\n\nexport function readWorkspaceSandboxLease(\n workspace: WorkspaceRecord,\n): WorkspaceSandboxLease | null {\n return workspaceSandboxLeaseFromState(readWorkspaceSandboxState(workspace));\n}\n\nexport function workspaceSandboxLeaseFromState(\n state: WorkspaceSandboxState,\n): WorkspaceSandboxLease | null {\n if (state.kind !== \"session\") {\n return null;\n }\n\n const expiresAtMs = Date.parse(state.lease.expiresAt);\n if (!Number.isFinite(expiresAtMs)) {\n return null;\n }\n\n const remainingMs = Math.max(0, expiresAtMs - Date.now());\n if (remainingMs <= 0) {\n return null;\n }\n\n return {\n sandboxId: state.sandboxId,\n observedAt: state.lease.observedAt,\n expiresAt: state.lease.expiresAt,\n remainingMs,\n };\n}\n\nexport function isWorkspaceSessionStateExpired(\n state: WorkspaceSandboxState,\n nowMs = Date.now(),\n): boolean {\n if (state.kind !== \"session\") {\n return false;\n }\n\n return Date.parse(state.lease.expiresAt) <= nowMs;\n}\n\nexport function transitionToCold(at = new Date().toISOString()): WorkspaceSandboxTransition {\n const nextState: WorkspaceSandboxState = { kind: \"cold\" };\n\n return {\n nextState,\n patch: {\n metadata: asWorkspaceSandboxStateMetadata(nextState),\n sandboxId: null,\n lastResumedAt: at,\n },\n };\n}\n\nexport function transitionToSession(\n sandboxId: string,\n lease: SandboxSessionLease,\n sessionPolicy?: WorkspacePolicy,\n): WorkspaceSandboxTransition {\n const nextState: WorkspaceSandboxState = {\n kind: \"session\",\n sandboxId,\n lease,\n sessionPolicy,\n };\n\n return {\n nextState,\n patch: {\n metadata: asWorkspaceSandboxStateMetadata(nextState),\n sandboxId,\n lastResumedAt: lease.observedAt,\n },\n };\n}\n\nexport function transitionAfterCommandCommit(\n commit: SandboxCommit,\n at: string,\n): WorkspaceSandboxTransition {\n const nextState: WorkspaceSandboxState = {\n kind: \"snapshot\",\n commit,\n };\n\n return {\n nextState,\n patch: {\n metadata: asWorkspaceSandboxStateMetadata(nextState),\n sandboxId: commit.state.sessionId,\n lastResumedAt: at,\n },\n };\n}\n\nexport function toDriverResumeState(state: WorkspaceSandboxState): PersistedSandboxState | null {\n if (state.kind === \"snapshot\") {\n return state.commit.state;\n }\n\n if (state.kind === \"session\") {\n return {\n kind: \"sandbox-session\",\n sessionId: state.sandboxId,\n };\n }\n\n return null;\n}\n\nexport async function persistSandboxTransition(\n store: WorkspaceStateStore,\n workspaceId: string,\n transition: WorkspaceSandboxTransition,\n): Promise<WorkspaceSandboxTransitionResult> {\n const record = await store.updateWorkspace(workspaceId, transition.patch);\n return {\n record,\n state: transition.nextState,\n };\n}\n","import type { WorkspacePolicy } from \"../policies/types.ts\";\nimport type {\n CommandResult,\n Command,\n WorkspaceSessionRunCommandOptions,\n SandboxDriver,\n SandboxRunCommandOptions,\n WorkspaceRunCommandOptions,\n WorkspaceRunCommandDetachedOptions,\n WorkspaceSessionProcessStartInput,\n WorkspaceSessionProcess,\n WorkspaceSandboxLease,\n} from \"../types.ts\";\nimport { makeSnapshotCommit, type SandboxCommit } from \"./workspace-state.ts\";\n\nexport interface WorkspaceSandboxHandle {\n runCommand(command: string, args: string[]): Promise<CommandResult>;\n runCommand(input: WorkspaceRunCommandOptions): Promise<CommandResult>;\n runCommand(input: WorkspaceRunCommandDetachedOptions): Promise<Command>;\n /**\n * Opens a live sandbox lease. timeoutMs overrides the provider's default\n * lease timeout for this session start; it does not change runCommand()\n * semantics or command-level timeouts.\n */\n openSession(input?: { timeoutMs?: number }): Promise<WorkspaceSessionHandle>;\n attachSession(): Promise<WorkspaceSessionHandle>;\n getActiveLease(): Promise<WorkspaceSandboxLease | null>;\n}\n\nexport interface WorkspaceSessionHandle {\n exec(command: string, args: string[]): Promise<CommandResult>;\n exec(input: WorkspaceSessionRunCommandOptions): Promise<CommandResult>;\n commit(): Promise<void>;\n /**\n * Sets a non-durable, session-scoped policy override for subsequent session\n * commands and process launches.\n */\n setPolicy(policy: WorkspacePolicy): Promise<void>;\n startProcess(command: string, args: string[]): Promise<WorkspaceSessionProcess>;\n startProcess(input: WorkspaceSessionProcessStartInput): Promise<WorkspaceSessionProcess>;\n url(port: number): Promise<string>;\n extendTimeout(durationMs: number): Promise<void>;\n}\n\ninterface RunStartInput {\n readonly command: string;\n readonly args: readonly string[];\n readonly effectivePolicy: WorkspacePolicy;\n readonly startedAt: string;\n}\n\ninterface RunFinishInput {\n readonly runId: string;\n readonly status: \"started\" | \"succeeded\" | \"failed\";\n readonly finishedAt: string;\n readonly exitCode?: number | null;\n readonly stdout?: string | null;\n readonly stderr?: string | null;\n readonly providerCommit?: unknown;\n}\n\ninterface RunLifecycle {\n readonly onRunStart?: (input: RunStartInput) => Promise<string>;\n readonly onRunFinish?: (input: RunFinishInput) => Promise<void>;\n}\n\ninterface SessionStateValidator {\n readonly assertActive: () => Promise<void>;\n}\n\ninterface SessionLeaseLifecycle {\n readonly onLeaseRefresh?: () => Promise<void>;\n}\n\ninterface SessionPolicyLifecycle {\n readonly initialSessionPolicy?: WorkspacePolicy;\n readonly onPolicyChange?: (policy: WorkspacePolicy) => Promise<void>;\n}\n\ntype NormalizedRunCommandInput = {\n readonly command: string;\n readonly args: readonly string[];\n readonly policy: WorkspacePolicy;\n readonly timeoutMs: number | undefined;\n readonly detached: boolean;\n};\ntype SessionRunCommandInput = {\n readonly command: string;\n readonly args: readonly string[];\n readonly policy: WorkspacePolicy;\n};\n\ntype CommitHook = (commit: SandboxCommit) => Promise<void>;\ntype DefaultPolicyResolver = () => Promise<WorkspacePolicy>;\n\nexport class ManagedSandbox {\n readonly #driver: SandboxDriver;\n readonly #onCommit?: CommitHook;\n readonly #runLifecycle?: RunLifecycle;\n readonly #resolveDefaultPolicy: DefaultPolicyResolver;\n\n constructor(\n driver: SandboxDriver,\n resolveDefaultPolicy: DefaultPolicyResolver,\n onCommit?: CommitHook,\n runLifecycle?: RunLifecycle,\n ) {\n this.#driver = driver;\n this.#resolveDefaultPolicy = resolveDefaultPolicy;\n this.#onCommit = onCommit;\n this.#runLifecycle = runLifecycle;\n }\n\n get id(): string {\n return this.#driver.id;\n }\n\n async runCommand(command: string, args: string[]): Promise<Command>;\n async runCommand(input: WorkspaceRunCommandOptions): Promise<Command>;\n async runCommand(input: WorkspaceRunCommandDetachedOptions): Promise<Command>;\n async runCommand(\n inputOrCommand: string | SandboxRunCommandOptions,\n args: string[] = [],\n ): Promise<Command> {\n const normalized = await this.normalizeRunCommandInput(inputOrCommand, args);\n this.ensureCommandShape(normalized.command, normalized.args);\n return this.runUnitOfWork(normalized.command, normalized.args, normalized.policy, () =>\n this.executeCommand(\n normalized.command,\n normalized.args,\n normalized.policy,\n normalized.detached,\n ),\n );\n }\n\n private async normalizeRunCommandInput(\n inputOrCommand: string | SandboxRunCommandOptions,\n args: readonly string[],\n ): Promise<NormalizedRunCommandInput> {\n if (typeof inputOrCommand === \"string\") {\n return {\n command: inputOrCommand,\n args,\n policy: await this.#resolveDefaultPolicy(),\n timeoutMs: undefined,\n detached: false,\n };\n }\n\n return {\n command: inputOrCommand.command,\n args: inputOrCommand.args ?? [],\n policy: inputOrCommand.policy ?? (await this.#resolveDefaultPolicy()),\n timeoutMs: inputOrCommand.timeoutMs,\n detached: \"detached\" in inputOrCommand ? inputOrCommand.detached : false,\n };\n }\n\n private ensureCommandShape(command: string, args: readonly string[]): void {\n if (!command.trim()) {\n throw new Error(\"Sandbox command must not be empty.\");\n }\n\n if (!Array.isArray(args)) {\n throw new Error(\"Sandbox command arguments must be an array.\");\n }\n }\n\n private async runUnitOfWork(\n command: string,\n args: readonly string[],\n effectivePolicy: WorkspacePolicy,\n operation: () => Promise<Command>,\n ): Promise<Command> {\n const now = new Date().toISOString();\n const runId = await this.startRun(command, args, effectivePolicy, now);\n let commandHandle: Command;\n try {\n commandHandle = await operation();\n } catch (commandError) {\n const finishedAt = new Date().toISOString();\n let providerCommit: unknown;\n let finalizeError: unknown | undefined;\n\n try {\n const commit = await this.snapshotWithFallback();\n providerCommit = commit.state;\n\n if (this.#onCommit) {\n await this.persistCommit(commit);\n }\n } catch (error) {\n finalizeError = error;\n providerCommit = undefined;\n }\n\n try {\n if (runId) {\n await this.finishRun({\n runId,\n status: \"failed\",\n providerCommit,\n finishedAt,\n });\n }\n } catch (error) {\n finalizeError = finalizeError ?? error;\n }\n\n if (finalizeError !== undefined) {\n throw new AggregateError(\n [commandError, finalizeError],\n \"Sandbox command failed and unit-of-work durability finalization did not complete.\",\n );\n }\n\n throw commandError;\n }\n\n const waitResult = (async () => {\n let commandError: unknown | undefined;\n let commandResult: CommandResult | undefined;\n let providerCommit: unknown;\n let finalizeError: unknown | undefined;\n\n try {\n commandResult = await commandHandle.wait();\n } catch (error) {\n commandError = error;\n }\n\n const finishedAt = new Date().toISOString();\n const commandStatus: \"succeeded\" | \"failed\" =\n commandError === undefined\n ? commandResult?.exitCode === 0\n ? \"succeeded\"\n : \"failed\"\n : \"failed\";\n\n try {\n const commit = await this.snapshotWithFallback();\n providerCommit = commit.state;\n\n if (this.#onCommit) {\n await this.persistCommit(commit);\n }\n } catch (error) {\n finalizeError = error;\n providerCommit = undefined;\n }\n\n const finalRunStatus: \"succeeded\" | \"failed\" =\n commandError === undefined && finalizeError === undefined ? commandStatus : \"failed\";\n\n try {\n if (runId) {\n await this.finishRun({\n runId,\n status: finalRunStatus,\n providerCommit,\n finishedAt,\n exitCode: commandResult?.exitCode,\n stdout: commandResult?.stdout,\n stderr: commandResult?.stderr,\n });\n }\n } catch (error) {\n finalizeError = finalizeError ?? error;\n }\n\n if (commandError !== undefined) {\n if (finalizeError !== undefined) {\n throw new AggregateError(\n [commandError, finalizeError],\n \"Sandbox command failed and unit-of-work durability finalization did not complete.\",\n );\n }\n throw commandError;\n }\n\n if (finalizeError !== undefined) {\n throw finalizeError;\n }\n\n if (!commandResult) {\n throw new Error(\"Command result was missing after successful execution.\");\n }\n\n return commandResult;\n })();\n void waitResult.catch(() => {});\n\n return {\n wait: async () => waitResult,\n logs: commandHandle.logs,\n };\n }\n\n private async startRun(\n command: string,\n args: readonly string[],\n effectivePolicy: WorkspacePolicy,\n at: string,\n ): Promise<string | undefined> {\n if (!this.#runLifecycle?.onRunStart) {\n return undefined;\n }\n\n return this.#runLifecycle.onRunStart({\n command,\n args,\n effectivePolicy,\n startedAt: at,\n });\n }\n\n private async executeCommand(\n command: string,\n args: readonly string[],\n policy: WorkspacePolicy,\n detached: boolean,\n ): Promise<Command> {\n await this.#driver.applyPolicy(policy);\n return this.#driver.runCommand(command, [...args], { detached });\n }\n\n private async finishRun(input: RunFinishInput): Promise<void> {\n if (!this.#runLifecycle?.onRunFinish) {\n return;\n }\n\n await this.#runLifecycle.onRunFinish(input);\n }\n\n private async snapshotWithFallback(): Promise<SandboxCommit> {\n const snapshot = await this.#driver.snapshot();\n return makeSnapshotCommit(snapshot);\n }\n\n private async persistCommit(commit: SandboxCommit): Promise<void> {\n if (!this.#onCommit) {\n return;\n }\n\n await this.#onCommit(commit);\n }\n}\n\nexport class ManagedSession implements WorkspaceSessionHandle {\n readonly #driver: SandboxDriver;\n readonly #onCommit?: CommitHook;\n readonly #resolveDefaultPolicy: DefaultPolicyResolver;\n readonly #onPolicyChange?: (policy: WorkspacePolicy) => Promise<void>;\n readonly #stateValidator?: SessionStateValidator;\n readonly #leaseLifecycle?: SessionLeaseLifecycle;\n #sessionPolicyOverride: WorkspacePolicy | undefined;\n #isActive = true;\n\n constructor(\n driver: SandboxDriver,\n resolveDefaultPolicy: DefaultPolicyResolver,\n onCommit?: CommitHook,\n stateValidator?: SessionStateValidator,\n leaseLifecycle?: SessionLeaseLifecycle,\n policyLifecycle?: SessionPolicyLifecycle,\n ) {\n this.#driver = driver;\n this.#resolveDefaultPolicy = resolveDefaultPolicy;\n this.#onCommit = onCommit;\n this.#stateValidator = stateValidator;\n this.#leaseLifecycle = leaseLifecycle;\n this.#onPolicyChange = policyLifecycle?.onPolicyChange;\n this.#sessionPolicyOverride = policyLifecycle?.initialSessionPolicy;\n }\n\n get id(): string {\n return this.#driver.id;\n }\n\n async exec(command: string, args: string[]): Promise<CommandResult>;\n async exec(input: WorkspaceSessionRunCommandOptions): Promise<CommandResult>;\n async exec(\n inputOrCommand: string | WorkspaceSessionRunCommandOptions,\n args: string[] = [],\n ): Promise<CommandResult> {\n await this.assertSessionActive();\n const normalized = await this.normalizeSessionInput(inputOrCommand, args);\n this.ensureCommandShape(normalized.command, normalized.args);\n await this.#driver.applyPolicy(normalized.policy);\n return (\n await this.#driver.runCommand(normalized.command, [...normalized.args], {\n detached: false,\n })\n ).wait();\n }\n\n async commit(): Promise<void> {\n await this.assertSessionActive();\n let snapshot: SandboxCommit;\n try {\n snapshot = await this.snapshotWithFallback();\n if (this.#onCommit) {\n await this.persistCommit(snapshot);\n }\n } finally {\n this.#isActive = false;\n }\n }\n\n async setPolicy(policy: WorkspacePolicy): Promise<void> {\n await this.assertSessionActive();\n this.#sessionPolicyOverride = policy;\n await this.#driver.applyPolicy(policy);\n if (this.#onPolicyChange !== undefined) {\n await this.#onPolicyChange(policy);\n }\n }\n\n async startProcess(command: string, args: string[]): Promise<WorkspaceSessionProcess>;\n async startProcess(input: WorkspaceSessionProcessStartInput): Promise<WorkspaceSessionProcess>;\n async startProcess(\n inputOrCommand: string | WorkspaceSessionProcessStartInput,\n args: string[] = [],\n ): Promise<WorkspaceSessionProcess> {\n await this.assertSessionActive();\n const startProcess = this.#driver.startProcess;\n if (!startProcess) {\n throw new Error(`This sandbox provider does not support startProcess().`);\n }\n\n const normalized =\n typeof inputOrCommand === \"string\"\n ? {\n command: inputOrCommand,\n args,\n policy: this.#sessionPolicyOverride,\n onStdout: undefined,\n onStderr: undefined,\n }\n : inputOrCommand;\n if (!normalized.command.trim()) {\n throw new Error(\"Sandbox process command must not be empty.\");\n }\n if (!Array.isArray(normalized.args)) {\n throw new Error(\"Sandbox process args must be an array.\");\n }\n\n const policy = await this.resolveSessionPolicy(normalized.policy);\n await this.#driver.applyPolicy(policy);\n\n return startProcess.call(this.#driver, {\n command: normalized.command,\n args: [...normalized.args],\n policy,\n onStdout: normalized.onStdout,\n onStderr: normalized.onStderr,\n });\n }\n\n async url(port: number): Promise<string> {\n await this.assertSessionActive();\n const url = this.#driver.url;\n if (!url) {\n throw new Error(`This sandbox provider does not support url(port).`);\n }\n\n return url.call(this.#driver, port);\n }\n\n async extendTimeout(durationMs: number): Promise<void> {\n await this.assertSessionActive();\n const extendTimeout = this.#driver.extendTimeout;\n if (!extendTimeout) {\n throw new Error(`This sandbox provider does not support extendTimeout().`);\n }\n\n await extendTimeout.call(this.#driver, durationMs);\n if (this.#leaseLifecycle?.onLeaseRefresh) {\n await this.#leaseLifecycle.onLeaseRefresh();\n }\n }\n\n private async normalizeSessionInput(\n inputOrCommand: string | WorkspaceSessionRunCommandOptions,\n args: readonly string[],\n ): Promise<SessionRunCommandInput> {\n if (typeof inputOrCommand === \"string\") {\n return {\n command: inputOrCommand,\n args,\n policy: await this.resolveSessionPolicy(),\n };\n }\n\n if (\"detached\" in inputOrCommand) {\n throw new Error(\"session exec does not support detached execution.\");\n }\n\n return {\n command: inputOrCommand.command,\n args: inputOrCommand.args ?? [],\n policy: await this.resolveSessionPolicy(inputOrCommand.policy),\n };\n }\n\n private async resolveSessionPolicy(override?: WorkspacePolicy): Promise<WorkspacePolicy> {\n if (override !== undefined) {\n return override;\n }\n\n if (this.#sessionPolicyOverride !== undefined) {\n return this.#sessionPolicyOverride;\n }\n\n return this.#resolveDefaultPolicy();\n }\n\n private ensureCommandShape(command: string, args: readonly string[]): void {\n if (!command.trim()) {\n throw new Error(\"Sandbox command must not be empty.\");\n }\n\n if (!Array.isArray(args)) {\n throw new Error(\"Sandbox command arguments must be an array.\");\n }\n }\n\n private async assertSessionActive(): Promise<void> {\n if (!this.#isActive) {\n throw new Error(\"This sandbox session has already been committed and is no longer active.\");\n }\n if (this.#stateValidator) {\n await this.#stateValidator.assertActive();\n }\n }\n\n private async snapshotWithFallback(): Promise<SandboxCommit> {\n const snapshot = await this.#driver.snapshot();\n return makeSnapshotCommit(snapshot);\n }\n\n private async persistCommit(commit: SandboxCommit): Promise<void> {\n if (!this.#onCommit) {\n return;\n }\n\n await this.#onCommit(commit);\n }\n}\n\nexport class LazySandboxHandle implements WorkspaceSandboxHandle {\n readonly #resolveSandbox: (input?: SandboxRunCommandOptions) => Promise<ManagedSandbox>;\n readonly #openSession: (input?: { timeoutMs?: number }) => Promise<WorkspaceSessionHandle>;\n readonly #attachSession: () => Promise<WorkspaceSessionHandle>;\n readonly #getActiveLease: () => Promise<WorkspaceSandboxLease | null>;\n\n constructor(\n resolveSandbox: (input?: SandboxRunCommandOptions) => Promise<ManagedSandbox>,\n openSession: (input?: { timeoutMs?: number }) => Promise<WorkspaceSessionHandle>,\n attachSession: () => Promise<WorkspaceSessionHandle>,\n getActiveLease: () => Promise<WorkspaceSandboxLease | null>,\n ) {\n this.#resolveSandbox = resolveSandbox;\n this.#openSession = openSession;\n this.#attachSession = attachSession;\n this.#getActiveLease = getActiveLease;\n }\n\n async runCommand(command: string, args: string[]): Promise<CommandResult>;\n async runCommand(input: WorkspaceRunCommandOptions): Promise<CommandResult>;\n async runCommand(input: WorkspaceRunCommandDetachedOptions): Promise<Command>;\n async runCommand(\n inputOrCommand: string | SandboxRunCommandOptions,\n args: string[] = [],\n ): Promise<CommandResult | Command> {\n const sandbox =\n typeof inputOrCommand === \"string\"\n ? await this.#resolveSandbox()\n : await this.#resolveSandbox(inputOrCommand);\n if (typeof inputOrCommand === \"string\") {\n return sandbox.runCommand(inputOrCommand, args).then((command) => command.wait());\n }\n const command = await sandbox.runCommand(inputOrCommand);\n if (\"detached\" in inputOrCommand && inputOrCommand.detached === true) {\n return command;\n }\n\n return command.wait();\n }\n\n async openSession(input?: { timeoutMs?: number }): Promise<WorkspaceSessionHandle> {\n return this.#openSession(input);\n }\n\n async attachSession(): Promise<WorkspaceSessionHandle> {\n return this.#attachSession();\n }\n\n async getActiveLease(): Promise<WorkspaceSandboxLease | null> {\n return this.#getActiveLease();\n }\n}\n","import { allowAll } from \"../policies/dsl.ts\";\nimport { assertWorkspacePolicyIsDurable } from \"../policies/dsl.ts\";\nimport type {\n RunFinishInput as AdapterRunFinishInput,\n SandboxDriver,\n SandboxCreateOptions,\n SandboxSessionLease,\n Command,\n CommandResult,\n WorkspaceRunCommandOptions,\n WorkspaceRunCommandDetachedOptions,\n WorkspacePolicy,\n SharedSetup,\n WorkspaceRecord,\n WorkspaceSandboxLease,\n PersistedSandboxState,\n} from \"../types.ts\";\nimport type { SandkitContext } from \"./context.ts\";\nimport { createId } from \"./ids.ts\";\nimport {\n LazySandboxHandle,\n ManagedSandbox,\n ManagedSession,\n type WorkspaceSessionHandle,\n type WorkspaceSandboxHandle,\n} from \"./sandbox.ts\";\nimport {\n asPolicySnapshotConfig,\n asWorkspacePolicyPatch,\n describeWorkspacePolicyId,\n readWorkspacePolicy,\n} from \"./workspace-policy.ts\";\nimport {\n readWorkspaceSandboxConfig,\n type WorkspaceSandboxConfig,\n} from \"./workspace-sandbox-config.ts\";\nimport type { SandboxCommit, WorkspaceSandboxState } from \"./workspace-state.ts\";\nimport {\n isWorkspaceSessionStateExpired,\n persistSandboxTransition,\n readWorkspaceSandboxLease,\n readWorkspaceSandboxState,\n toDriverResumeState,\n transitionAfterCommandCommit,\n transitionToCold,\n transitionToSession,\n type WorkspaceSandboxTransition,\n} from \"./workspace-state.ts\";\n\n// Process-local lock to serialize durable work for a workspace within this runtime\n// instance. This does not coordinate across processes.\nconst inFlightDurableCommands = new Set<string>();\n\nfunction setupStateFingerprint(\n command: string,\n args: readonly string[],\n policy: WorkspacePolicy,\n): string {\n return encodeURIComponent(\n JSON.stringify({\n command,\n args,\n policy: {\n id: describeWorkspacePolicyId(policy),\n config: asPolicySnapshotConfig(policy),\n },\n }),\n );\n}\n\nexport const sharedSetupStateId = (adapterId: string, setup: SharedSetup | undefined): string => {\n if (setup) {\n assertWorkspacePolicyIsDurable(setup.policy);\n }\n const fingerprint = setup\n ? setupStateFingerprint(setup.command, [...(setup.args ?? [])], setup.policy)\n : \"no-bootstrap\";\n return `${adapterId}:shared-bootstrap:${fingerprint}`;\n};\n\nfunction sharedSetupRecordId(ctx: SandkitContext): string | null {\n if (!ctx.options.setup) {\n return null;\n }\n\n return sharedSetupStateId(ctx.adapter.id, ctx.options.setup);\n}\n\nfunction assertNoDurableCommandInFlight(workspaceId: string): void {\n if (inFlightDurableCommands.has(workspaceId)) {\n throw new Error(\n \"Cannot run a durable command while another durable command is still in flight.\",\n );\n }\n}\n\nfunction beginDurableCommand(workspaceId: string): void {\n assertNoDurableCommandInFlight(workspaceId);\n inFlightDurableCommands.add(workspaceId);\n}\n\nfunction endDurableCommand(workspaceId: string): void {\n inFlightDurableCommands.delete(workspaceId);\n}\n\nasync function readSharedSetupState(ctx: SandkitContext): Promise<PersistedSandboxState | null> {\n if (!ctx.options.setup) {\n return null;\n }\n\n const sharedSetupId = sharedSetupRecordId(ctx);\n if (!sharedSetupId) {\n return null;\n }\n\n const setupState = await ctx.adapter.setupStates.getSetupState(sharedSetupId);\n return setupState ? setupState.state : null;\n}\n\nasync function persistSharedSetupState(\n ctx: SandkitContext,\n state: PersistedSandboxState,\n): Promise<void> {\n const sharedSetupId = sharedSetupRecordId(ctx);\n if (!sharedSetupId) {\n return;\n }\n\n await ctx.adapter.setupStates.putSetupState({\n id: sharedSetupId,\n state: {\n kind: state.kind,\n sessionId: state.sessionId,\n state: state.state,\n },\n });\n}\n\nasync function clearSharedSetupState(ctx: SandkitContext): Promise<void> {\n const sharedSetupId = sharedSetupRecordId(ctx);\n if (!sharedSetupId) {\n return;\n }\n\n await ctx.adapter.setupStates.deleteSetupState(sharedSetupId);\n}\n\nfunction isRecoverableSetupStateError(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n\n return (\n error.message.includes(\"Sandkit durable state corruption\") &&\n error.message.includes(\"sandkit_setup_states\")\n );\n}\n\nfunction assertSharedSetupAndPolicy(ctx: SandkitContext): SharedSetup {\n if (!ctx.options.setup) {\n throw new Error(\"Sandkit setup is not configured.\");\n }\n\n const { setup } = ctx.options;\n if (!setup.policy) {\n throw new Error(\"Shared setup policy is required.\");\n }\n\n return setup;\n}\n\nasync function bootstrapSharedSetupState(\n ctx: SandkitContext,\n workspace: WorkspaceRecord,\n options: SandboxCreateOptions,\n): Promise<PersistedSandboxState> {\n const setup = assertSharedSetupAndPolicy(ctx);\n const sandbox = await ctx.driverFactory.createSandbox(workspace, {\n ...options,\n policy: setup.policy,\n });\n const result = await runCommandAndWait(sandbox, setup.command, setup.args);\n if (result.exitCode !== 0) {\n throw new Error(\n `Workspace setup failed with exit code ${result.exitCode}. ${result.stderr.trim()}`.trim(),\n );\n }\n\n const state = await sandbox.snapshot();\n await persistSharedSetupState(ctx, state);\n return state;\n}\n\nasync function runCommandAndWait(\n sandbox: SandboxDriver,\n command: string,\n args?: readonly string[],\n): Promise<CommandResult> {\n const commandArgs = args ?? [];\n return (await sandbox.runCommand(command, [...commandArgs])).wait();\n}\n\nasync function resolveSharedSetupState(\n ctx: SandkitContext,\n workspace: WorkspaceRecord,\n options: SandboxCreateOptions,\n): Promise<PersistedSandboxState | null> {\n if (!ctx.options.setup) {\n return null;\n }\n assertSharedSetupAndPolicy(ctx);\n\n try {\n const setupState = await readSharedSetupState(ctx);\n if (!setupState) {\n return bootstrapSharedSetupState(ctx, workspace, options);\n }\n\n return setupState;\n } catch (error) {\n if (!isRecoverableSetupStateError(error)) {\n throw error;\n }\n\n await clearSharedSetupState(ctx);\n return bootstrapSharedSetupState(ctx, workspace, options);\n }\n}\n\n// Internal helper: build a transient, non-user workspace record for executing a missing\n// shared bootstrap command. This record is never persisted and is intentionally opaque.\nfunction createInternalSharedBootstrapWorkspaceRecord(): WorkspaceRecord {\n const now = new Date().toISOString();\n return {\n id: createId(\"sandkit-internal-bootstrap\"),\n status: \"inactive\",\n createdAt: now,\n updatedAt: now,\n };\n}\n\nexport async function bootstrapSharedSetup(ctx: SandkitContext): Promise<void> {\n if (!ctx.options.setup) {\n return;\n }\n const setup = assertSharedSetupAndPolicy(ctx);\n const sharedSetupId = sharedSetupRecordId(ctx);\n if (!sharedSetupId) {\n return;\n }\n const workspace = createInternalSharedBootstrapWorkspaceRecord();\n const setupOptions: SandboxCreateOptions = {\n policy: setup.policy,\n };\n\n let setupState: PersistedSandboxState | null;\n try {\n setupState = await readSharedSetupState(ctx);\n } catch (error) {\n if (!isRecoverableSetupStateError(error)) {\n throw error;\n }\n\n await clearSharedSetupState(ctx);\n setupState = null;\n }\n\n if (!setupState) {\n await bootstrapSharedSetupState(ctx, workspace, setupOptions);\n }\n}\n\nexport interface PublicWorkspaceHandle {\n readonly id: string;\n readonly descriptor: WorkspaceDescriptor;\n readonly sandbox: WorkspaceSandboxHandle;\n setPolicy(policy: WorkspacePolicy): Promise<void>;\n}\n\nexport type WorkspaceStatus = \"active\" | \"inactive\" | \"archived\";\n\nexport interface WorkspaceDescriptor {\n readonly id: string;\n readonly name?: string;\n readonly status: WorkspaceStatus;\n readonly createdAt: string;\n readonly updatedAt: string;\n}\n\ninterface RunFinishInput extends AdapterRunFinishInput {\n runId: string;\n}\n\nexport class WorkspaceHandle implements PublicWorkspaceHandle {\n readonly #ctx: SandkitContext;\n #record: WorkspaceRecord;\n #sandboxState: WorkspaceSandboxState;\n #sandboxConfig: WorkspaceSandboxConfig;\n #descriptor: WorkspaceDescriptor;\n #lazySandbox?: LazySandboxHandle;\n\n constructor(ctx: SandkitContext, record: WorkspaceRecord) {\n this.#ctx = ctx;\n this.#record = record;\n this.#descriptor = this.resolveDescriptor(record);\n this.#sandboxState = readWorkspaceSandboxState(record);\n this.#sandboxConfig = readWorkspaceSandboxConfig(record);\n }\n\n get id(): string {\n return this.#record.id;\n }\n\n get descriptor(): WorkspaceDescriptor {\n return this.#descriptor;\n }\n\n get sandbox(): LazySandboxHandle {\n if (!this.#lazySandbox) {\n this.#lazySandbox = new LazySandboxHandle(\n (input?: { timeoutMs?: number }) => this.createOrResumeSandboxForCommand(input),\n (input?: { timeoutMs?: number }) => this.openSession(input),\n () => this.attachSession(),\n () => this.getActiveLease(),\n );\n }\n\n return this.#lazySandbox;\n }\n\n async setPolicy(policy: WorkspacePolicy): Promise<void> {\n await this.resolveLatestWorkspace();\n const result = await this.#ctx.adapter.workspaces.updateWorkspace(\n this.#record.id,\n asWorkspacePolicyPatch(policy),\n );\n this.updateFromRecord(result);\n this.#sandboxState = readWorkspaceSandboxState(result);\n }\n\n /**\n * Returns a current lease only if a session is still attachable and unexpired.\n * This is attachment-state derived from persisted metadata; it is not intended\n * to reset expiry on read.\n */\n async getActiveLease(): Promise<WorkspaceSandboxLease | null> {\n await this.resolveLatestWorkspace();\n const sandbox = await this.resolveAttachableSession();\n if (!sandbox) {\n return null;\n }\n\n return readWorkspaceSandboxLease(this.#record);\n }\n\n async createOrResumeSandboxForCommand(input?: { timeoutMs?: number }): Promise<ManagedSandbox> {\n await this.resolveLatestWorkspace();\n if (await this.resolveAttachableSession()) {\n throw new Error(\n \"Cannot run command while a sandbox session is active. Use attachSession() to reuse it or commit the session first.\",\n );\n }\n assertNoDurableCommandInFlight(this.#record.id);\n beginDurableCommand(this.#record.id);\n\n const workspace = await this.resolveLatestWorkspace();\n try {\n const sandbox = await this.resolveSandboxDriver(workspace, {\n timeoutMs: normalizeRunCommandTimeoutMs(input?.timeoutMs),\n });\n\n return this.createManagedSandbox(sandbox);\n } catch (error) {\n endDurableCommand(this.#record.id);\n throw error;\n }\n }\n\n async openSession(input?: { timeoutMs?: number }): Promise<WorkspaceSessionHandle> {\n await this.resolveLatestWorkspace();\n assertNoDurableCommandInFlight(this.#record.id);\n if (await this.resolveAttachableSession()) {\n throw new Error(\"A sandbox session is already active for this workspace.\");\n }\n\n const workspace = await this.resolveLatestWorkspace();\n const sandbox = await this.resolveSandboxDriver(workspace, {\n timeoutMs: normalizeSessionTimeoutMs(input?.timeoutMs),\n });\n const lease = await sandbox.getSessionLease();\n await this.persistSandboxState(transitionToSession(sandbox.id, lease));\n\n return this.makeSession(sandbox);\n }\n\n async attachSession(): Promise<WorkspaceSessionHandle> {\n await this.resolveLatestWorkspace();\n const sandbox = await this.resolveAttachableSession();\n if (!sandbox) {\n throw new Error(\"There is no active sandbox session to attach for this workspace.\");\n }\n\n return this.makeSession(sandbox);\n }\n\n private async persistSessionPolicy(policy: WorkspacePolicy): Promise<void> {\n await this.resolveLatestWorkspace();\n if (!workspaceStateIsSession(this.#sandboxState)) {\n throw new Error(\"Cannot persist session policy without an active sandbox session.\");\n }\n\n await this.persistSandboxState(\n transitionToSession(this.#sandboxState.sandboxId, this.#sandboxState.lease, policy),\n );\n }\n\n private makeSession(sandbox: SandboxDriver): ManagedSession {\n const sessionPolicy = workspaceStateIsSession(this.#sandboxState)\n ? this.#sandboxState.sessionPolicy\n : undefined;\n\n return new ManagedSession(\n sandbox,\n async () => this.resolveDefaultPolicy(),\n async (commit: SandboxCommit) =>\n this.persistSandboxState(transitionAfterCommandCommit(commit, new Date().toISOString())),\n {\n assertActive: async () => {\n const activeSandbox = await this.resolveAttachableSession();\n if (!activeSandbox || activeSandbox.id !== sandbox.id) {\n throw new Error(\"This sandbox session is no longer active.\");\n }\n },\n },\n {\n onLeaseRefresh: async () => {\n const lease = await sandbox.getSessionLease();\n await this.refreshSessionLease(sandbox.id, lease);\n },\n },\n {\n initialSessionPolicy: sessionPolicy,\n onPolicyChange: async (policy: WorkspacePolicy) => {\n await this.persistSessionPolicy(policy);\n },\n },\n );\n }\n\n private async refreshSessionLease(sandboxId: string, lease: SandboxSessionLease): Promise<void> {\n await this.resolveLatestWorkspace();\n if (\n !workspaceStateIsSession(this.#sandboxState) ||\n this.#sandboxState.sandboxId !== sandboxId\n ) {\n throw new Error(\"Cannot refresh lease for an inactive sandbox session.\");\n }\n\n await this.persistSandboxState(\n transitionToSession(sandboxId, lease, this.#sandboxState.sessionPolicy),\n );\n }\n\n private async resolveAttachableSession(): Promise<SandboxDriver | null> {\n if (!workspaceStateIsSession(this.#sandboxState)) {\n return null;\n }\n\n if (isWorkspaceSessionStateExpired(this.#sandboxState)) {\n await this.persistSandboxState(transitionToCold());\n return null;\n }\n\n try {\n return await this.resolveSandboxDriver(this.#record);\n } catch (error) {\n if (!this.#ctx.driverFactory.isSessionUnavailableError?.(error)) {\n throw error;\n }\n\n await this.persistSandboxState(transitionToCold());\n return null;\n }\n }\n\n private async resolveSandboxDriver(\n workspace: WorkspaceRecord,\n overrides?: { timeoutMs?: number },\n ): Promise<SandboxDriver> {\n const policy = readWorkspacePolicy(workspace, allowAll());\n const options = this.makeSandboxDriverOptions(policy, overrides?.timeoutMs);\n const currentState = toDriverResumeState(this.#sandboxState);\n if (currentState) {\n return this.#ctx.driverFactory.resumeSandbox(workspace, currentState, options);\n }\n\n const setupState = await resolveSharedSetupState(this.#ctx, workspace, options);\n if (!setupState) {\n return this.#ctx.driverFactory.createSandbox(workspace, options);\n }\n\n try {\n return await this.#ctx.driverFactory.resumeSandbox(workspace, setupState, options);\n } catch (error) {\n if (\n !this.#ctx.driverFactory.isSessionUnavailableError?.(error) &&\n !isRecoverableSetupStateError(error)\n ) {\n throw error;\n }\n\n await clearSharedSetupState(this.#ctx);\n const rerunSetupState = await bootstrapSharedSetupState(this.#ctx, workspace, options);\n return this.#ctx.driverFactory.resumeSandbox(workspace, rerunSetupState, options);\n }\n }\n\n private createManagedSandbox(sandbox: SandboxDriver): ManagedSandbox {\n const managed = new ManagedSandbox(\n sandbox,\n async () => this.resolveDefaultPolicy(),\n async (commit: SandboxCommit) =>\n this.persistSandboxState(transitionAfterCommandCommit(commit, new Date().toISOString())),\n this.createRunLifecycle(sandbox),\n );\n\n const workspaceId = this.#record.id;\n const originalRunCommand = managed.runCommand.bind(managed);\n const wrappedRunCommand: {\n (command: string, args: string[]): Promise<Command>;\n (input: WorkspaceRunCommandOptions): Promise<Command>;\n (input: WorkspaceRunCommandDetachedOptions): Promise<Command>;\n (\n inputOrCommand: string | WorkspaceRunCommandOptions | WorkspaceRunCommandDetachedOptions,\n args?: string[],\n ): Promise<Command>;\n } = async (\n inputOrCommand: string | WorkspaceRunCommandOptions | WorkspaceRunCommandDetachedOptions,\n args: string[] = [],\n ): Promise<Command> => {\n let releaseCalled = false;\n const release = async () => {\n if (releaseCalled) {\n return;\n }\n releaseCalled = true;\n endDurableCommand(workspaceId);\n };\n\n try {\n const command =\n typeof inputOrCommand === \"string\"\n ? await originalRunCommand(inputOrCommand, args)\n : await originalRunCommand(inputOrCommand);\n\n const completion = (async () => {\n try {\n return await command.wait();\n } finally {\n await release();\n }\n })();\n void completion.catch(() => {});\n\n return {\n wait: () => completion,\n logs: command.logs,\n };\n } catch (error) {\n await release();\n throw error;\n }\n };\n\n managed.runCommand = wrappedRunCommand;\n\n return managed;\n }\n\n private makeSandboxDriverOptions(\n policy: WorkspacePolicy,\n timeoutMs: number | undefined,\n ): SandboxCreateOptions {\n const next: {\n policy: WorkspacePolicy;\n exposedPorts?: readonly number[];\n timeoutMs?: number;\n } = {\n policy,\n };\n\n if (this.#sandboxConfig.exposedPorts && this.#sandboxConfig.exposedPorts.length > 0) {\n next.exposedPorts = this.#sandboxConfig.exposedPorts;\n }\n if (timeoutMs !== undefined) {\n next.timeoutMs = timeoutMs;\n }\n\n return next;\n }\n\n private createRunLifecycle(sandbox: SandboxDriver) {\n return {\n onRunStart: async (input: {\n command: string;\n args: readonly string[];\n effectivePolicy: WorkspacePolicy;\n startedAt: string;\n }) => {\n const policySnapshot = await this.createPolicySnapshot(input.effectivePolicy);\n const run = await this.#ctx.adapter.runs.createRun({\n workspaceId: this.#record.id,\n provider: sandbox.provider,\n executionTargetId: sandbox.id,\n command: input.command,\n args: input.args,\n status: \"started\",\n startedAt: input.startedAt,\n policySnapshotId: policySnapshot.id,\n });\n\n return run.id;\n },\n onRunFinish: async (input: RunFinishInput) => {\n await this.#ctx.adapter.runs.finishRun(input.runId, {\n status: input.status,\n finishedAt: input.finishedAt,\n exitCode: input.exitCode ?? null,\n stdout: input.stdout ?? null,\n stderr: input.stderr ?? null,\n providerCommit: input.providerCommit,\n });\n },\n };\n }\n\n private async persistSandboxState(transition: WorkspaceSandboxTransition): Promise<void> {\n const result = await persistSandboxTransition(\n this.#ctx.adapter.workspaces,\n this.#record.id,\n transition,\n );\n this.updateFromRecord(result.record);\n this.#sandboxState = result.state;\n }\n\n private async resolveLatestWorkspace(): Promise<WorkspaceRecord> {\n const latest = await this.#ctx.adapter.workspaces.getWorkspace(this.#record.id);\n if (!latest) {\n throw new Error(`Workspace with id \"${this.#record.id}\" no longer exists`);\n }\n\n this.updateFromRecord(latest);\n this.#sandboxState = readWorkspaceSandboxState(latest);\n this.#sandboxConfig = readWorkspaceSandboxConfig(latest);\n if (isWorkspaceSessionStateExpired(this.#sandboxState)) {\n const result = await persistSandboxTransition(\n this.#ctx.adapter.workspaces,\n this.#record.id,\n transitionToCold(),\n );\n this.updateFromRecord(result.record);\n this.#sandboxState = result.state;\n this.#sandboxConfig = readWorkspaceSandboxConfig(result.record);\n }\n\n return this.#record;\n }\n\n private resolveDescriptor(record: WorkspaceRecord): WorkspaceDescriptor {\n return {\n id: record.id,\n name: record.name,\n status: record.status,\n createdAt: record.createdAt,\n updatedAt: record.updatedAt,\n };\n }\n\n private updateFromRecord(record: WorkspaceRecord): void {\n this.#record = record;\n this.#descriptor = this.resolveDescriptor(record);\n this.#sandboxConfig = readWorkspaceSandboxConfig(record);\n }\n\n private async createPolicySnapshot(policy: WorkspacePolicy) {\n return this.#ctx.adapter.policySnapshots.createPolicySnapshot({\n workspaceId: this.#record.id,\n policyId: describeWorkspacePolicyId(policy),\n config: asPolicySnapshotConfig(policy),\n });\n }\n\n private async resolveDefaultPolicy(): Promise<WorkspacePolicy> {\n const workspace = await this.resolveLatestWorkspace();\n return readWorkspacePolicy(workspace, allowAll());\n }\n}\n\nfunction normalizeSessionTimeoutMs(timeoutMs: number | undefined): number | undefined {\n if (timeoutMs === undefined) {\n return undefined;\n }\n\n if (!Number.isInteger(timeoutMs) || !Number.isFinite(timeoutMs) || timeoutMs <= 0) {\n throw new Error(\"openSession timeoutMs must be a positive integer in milliseconds.\");\n }\n\n return timeoutMs;\n}\n\nfunction normalizeRunCommandTimeoutMs(timeoutMs: number | undefined): number | undefined {\n if (timeoutMs === undefined) {\n return undefined;\n }\n\n if (!Number.isInteger(timeoutMs) || !Number.isFinite(timeoutMs) || timeoutMs <= 0) {\n throw new Error(\"runCommand timeoutMs must be a positive integer in milliseconds.\");\n }\n\n return timeoutMs;\n}\n\nfunction workspaceStateIsSession(\n state: WorkspaceSandboxState,\n): state is Extract<WorkspaceSandboxState, { kind: \"session\" }> {\n return state.kind === \"session\";\n}\n","import type { SandkitOptions, WorkspaceCreateOptions } from \"../types.ts\";\nimport { createSandkitContext, type SandkitContext } from \"./context.ts\";\nimport { asWorkspacePolicyMetadata, removeWorkspacePolicyMetadata } from \"./workspace-policy.ts\";\nimport {\n asWorkspaceSandboxConfigMetadata,\n normalizeWorkspaceSandboxCreateConfig,\n removeWorkspaceSandboxConfigMetadata,\n} from \"./workspace-sandbox-config.ts\";\nimport { bootstrapSharedSetup, type PublicWorkspaceHandle, WorkspaceHandle } from \"./workspace.ts\";\n\nexport class Sandkit {\n readonly #ctx: SandkitContext;\n\n constructor(options: SandkitOptions) {\n this.#ctx = createSandkitContext(options);\n }\n\n get context(): SandkitContext {\n return this.#ctx;\n }\n\n async bootstrap(): Promise<void> {\n await bootstrapSharedSetup(this.#ctx);\n }\n\n async createWorkspace(input: WorkspaceCreateOptions = {}): Promise<PublicWorkspaceHandle> {\n const { id, name, policy, metadata, status, sandboxId, lastResumedAt } = input;\n const sandboxConfig = normalizeWorkspaceSandboxCreateConfig(input.sandbox);\n const sanitizedMetadata = removeWorkspaceSandboxConfigMetadata(\n removeWorkspacePolicyMetadata(metadata),\n );\n const workspaceMetadata = policy\n ? {\n ...sanitizedMetadata,\n ...asWorkspacePolicyMetadata(policy),\n ...asWorkspaceSandboxConfigMetadata(sandboxConfig),\n }\n : {\n ...sanitizedMetadata,\n ...asWorkspaceSandboxConfigMetadata(sandboxConfig),\n };\n\n const workspace = await this.#ctx.adapter.workspaces.createWorkspace({\n id,\n name,\n metadata: workspaceMetadata,\n status,\n sandboxId,\n lastResumedAt,\n });\n return new WorkspaceHandle(this.#ctx, workspace);\n }\n\n async getWorkspace(id: string): Promise<PublicWorkspaceHandle> {\n const workspace = await this.#ctx.adapter.workspaces.getWorkspace(id);\n if (!workspace) {\n throw new Error(`Workspace not found: ${id}`);\n }\n\n return new WorkspaceHandle(this.#ctx, workspace);\n }\n}\n\nexport function createSandkit(options: SandkitOptions): Sandkit {\n return new Sandkit(options);\n}\n"],"mappings":"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","names":["corruptionError","command"]}
@@ -1,5 +1,5 @@
1
- import { a as SandboxDriverFactory, f as SandboxCreateOptions, g as SandboxDriver, P as PersistedSandboxState, h as SandkitSandboxProvider } from '../types-B5N9o-ew.js';
2
- import { W as WorkspaceRecord } from '../types-BRMAvcWc.js';
1
+ import { a as SandboxDriverFactory, i as SandboxCreateOptions, j as SandboxDriver, P as PersistedSandboxState, k as SandkitSandboxProvider } from '../types-nu3vpBCZ.js';
2
+ import { W as WorkspaceRecord } from '../types-DNpj280o.js';
3
3
  import '../types-Dpr_BkF9.js';
4
4
 
5
5
  declare class MockSandboxDriverFactory implements SandboxDriverFactory {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createSandboxProvider
3
- } from "../chunk-HVYCAAZQ.js";
3
+ } from "../chunk-XN6DGLRP.js";
4
4
  import {
5
5
  createId
6
6
  } from "../chunk-DLGUA3H7.js";
@@ -53,7 +53,8 @@ var MockSandboxDriver = class {
53
53
  this.#expiresAtMs = this.#expiresAtMs + durationMs;
54
54
  }
55
55
  async startProcess(input) {
56
- const commandResult = await this.runCommand(input.command, [...input.args]);
56
+ const command = await this.runCommand(input.command, [...input.args]);
57
+ const commandResult = await command.wait();
57
58
  if (input.onStdout && commandResult.stdout) {
58
59
  input.onStdout(commandResult.stdout);
59
60
  }
@@ -75,7 +76,23 @@ var MockSandboxDriver = class {
75
76
  }
76
77
  };
77
78
  }
78
- async runCommand(command, args) {
79
+ async runCommand(command, args, options) {
80
+ const commandResult = await this.#executeCommand(command, args);
81
+ return {
82
+ wait: async () => commandResult,
83
+ logs: options?.detached ? () => {
84
+ const chunks = [];
85
+ if (commandResult.stdout) {
86
+ chunks.push({ stream: "stdout", chunk: commandResult.stdout });
87
+ }
88
+ if (commandResult.stderr) {
89
+ chunks.push({ stream: "stderr", chunk: commandResult.stderr });
90
+ }
91
+ return toAsyncIterable(chunks);
92
+ } : void 0
93
+ };
94
+ }
95
+ async #executeCommand(command, args) {
79
96
  switch (command) {
80
97
  case "echo":
81
98
  return this.runEcho(args);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/mock-driver.ts","../../src/integrations/mock.ts"],"sourcesContent":["import { allowAll, describeWorkspacePolicy } from \"../policies/dsl.ts\";\nimport type { WorkspacePolicy } from \"../policies/types.ts\";\nimport type {\n CommandResult,\n SandboxSessionLease,\n PersistedSandboxState,\n SandboxDriver,\n WorkspaceSessionLog,\n WorkspaceSessionProcessStartInput,\n SandboxCreateOptions,\n SandboxDriverFactory,\n WorkspaceRecord,\n} from \"../types.ts\";\nimport { createId } from \"./ids.ts\";\n\ntype FileMap = Record<string, string>;\n\ninterface MockSandboxSnapshotState {\n files: FileMap;\n}\n\nfunction toSnapshotState(snapshot: PersistedSandboxState): MockSandboxSnapshotState {\n const files =\n snapshot.state &&\n typeof snapshot.state === \"object\" &&\n !Array.isArray(snapshot.state) &&\n \"files\" in snapshot.state &&\n snapshot.state.files &&\n typeof snapshot.state.files === \"object\" &&\n !Array.isArray(snapshot.state.files)\n ? (snapshot.state.files as FileMap)\n : {};\n return { files: { ...files } };\n}\n\nclass MockSandboxDriver implements SandboxDriver {\n readonly #files: FileMap;\n #policy: WorkspacePolicy;\n readonly id: string;\n readonly provider = \"mock\";\n #timeoutMs: number;\n #expiresAtMs: number | null = null;\n\n constructor(id: string, files: FileMap = {}, policy: WorkspacePolicy = allowAll()) {\n this.id = id;\n this.#files = { ...files };\n this.#policy = policy;\n this.#timeoutMs = 60_000 * 60;\n }\n\n async applyPolicy(policy: WorkspacePolicy): Promise<void> {\n this.#policy = policy;\n }\n\n async getSessionLease(): Promise<SandboxSessionLease> {\n const observedAt = new Date().toISOString();\n const observedAtMs = Date.parse(observedAt);\n if (this.#expiresAtMs === null) {\n this.#expiresAtMs = observedAtMs + this.#timeoutMs;\n }\n if (this.#expiresAtMs < observedAtMs) {\n this.#expiresAtMs = observedAtMs;\n }\n\n return {\n sandboxId: this.id,\n observedAt,\n expiresAt: new Date(this.#expiresAtMs).toISOString(),\n };\n }\n\n async extendTimeout(durationMs: number): Promise<void> {\n const observedAtMs = Date.now();\n if (this.#expiresAtMs === null || this.#expiresAtMs < observedAtMs) {\n this.#expiresAtMs = observedAtMs;\n }\n this.#expiresAtMs = this.#expiresAtMs + durationMs;\n }\n\n async startProcess(input: WorkspaceSessionProcessStartInput): Promise<{\n processId: string;\n wait: () => Promise<CommandResult>;\n logs: () => AsyncIterable<WorkspaceSessionLog>;\n }> {\n const commandResult = await this.runCommand(input.command, [...input.args]);\n if (input.onStdout && commandResult.stdout) {\n input.onStdout(commandResult.stdout);\n }\n if (input.onStderr && commandResult.stderr) {\n input.onStderr(commandResult.stderr);\n }\n\n return {\n processId: `${this.id}-${Date.now()}`,\n wait: async () => commandResult,\n logs: () => {\n const chunks: WorkspaceSessionLog[] = [];\n if (commandResult.stdout) {\n chunks.push({ stream: \"stdout\", chunk: commandResult.stdout });\n }\n if (commandResult.stderr) {\n chunks.push({ stream: \"stderr\", chunk: commandResult.stderr });\n }\n return toAsyncIterable(chunks);\n },\n };\n }\n\n async runCommand(command: string, args: string[]): Promise<CommandResult> {\n switch (command) {\n case \"echo\":\n return this.runEcho(args);\n case \"cat\":\n return this.runCat(args);\n case \"pwd\":\n return this.ok(\"/workspace\\n\");\n case \"ls\":\n return this.ok(`${Object.keys(this.#files).sort().join(\"\\n\")}\\n`);\n case \"policy\":\n return this.ok(`${JSON.stringify(this.#policy)}\\n`);\n case \"policy-id\":\n return this.ok(`${describeWorkspacePolicy(this.#policy)}\\n`);\n default:\n return {\n exitCode: 127,\n stderr: `Unsupported mock command: ${command}\\n`,\n stdout: \"\",\n };\n }\n }\n\n async snapshot(): Promise<PersistedSandboxState> {\n return {\n kind: \"mock\",\n sessionId: this.id,\n state: {\n files: { ...this.#files },\n },\n };\n }\n\n private ok(stdout: string): CommandResult {\n return {\n exitCode: 0,\n stderr: \"\",\n stdout,\n };\n }\n\n private runCat(args: string[]): CommandResult {\n const target = args[0];\n if (!target) {\n return {\n exitCode: 1,\n stderr: \"cat: missing file operand\\n\",\n stdout: \"\",\n };\n }\n\n const content = this.#files[target];\n if (typeof content !== \"string\") {\n return {\n exitCode: 1,\n stderr: `cat: ${target}: No such file or directory\\n`,\n stdout: \"\",\n };\n }\n\n return this.ok(content.endsWith(\"\\n\") ? content : `${content}\\n`);\n }\n\n private runEcho(args: string[]): CommandResult {\n const redirectIndex = args.indexOf(\">\");\n if (redirectIndex === -1) {\n return this.ok(`${args.join(\" \")}\\n`);\n }\n\n const target = args[redirectIndex + 1];\n if (!target) {\n return {\n exitCode: 1,\n stderr: \"echo: missing redirect target\\n\",\n stdout: \"\",\n };\n }\n\n const content = args.slice(0, redirectIndex).join(\" \");\n this.#files[target] = content;\n return this.ok(\"\");\n }\n}\n\nfunction toAsyncIterable<T>(items: T[]): AsyncIterable<T> {\n return {\n async *[Symbol.asyncIterator]() {\n for (const item of items) {\n yield item;\n }\n },\n };\n}\n\nexport class MockSandboxDriverFactory implements SandboxDriverFactory {\n readonly #sessions = new Map<string, MockSandboxDriver>();\n\n async createSandbox(\n _workspace: WorkspaceRecord,\n options: SandboxCreateOptions,\n ): Promise<SandboxDriver> {\n const driver = new MockSandboxDriver(createId(\"sandbox\"), {}, options.policy);\n this.#sessions.set(driver.id, driver);\n return driver;\n }\n\n isSessionUnavailableError(error: unknown): boolean {\n return error instanceof Error && error.message.startsWith(\"Mock sandbox session not found:\");\n }\n\n async resumeSandbox(\n _workspace: WorkspaceRecord,\n snapshot: PersistedSandboxState,\n options: SandboxCreateOptions,\n ): Promise<SandboxDriver> {\n if (snapshot.kind === \"sandbox-session\") {\n const existing = this.#sessions.get(snapshot.sessionId);\n if (!existing) {\n throw new Error(`Mock sandbox session not found: ${snapshot.sessionId}`);\n }\n\n await existing.applyPolicy(options.policy);\n return existing;\n }\n\n const state = toSnapshotState(snapshot);\n const driver = new MockSandboxDriver(snapshot.sessionId, state.files, options.policy);\n this.#sessions.set(driver.id, driver);\n return driver;\n }\n}\n","import { MockSandboxDriverFactory } from \"../core/mock-driver.ts\";\nimport { createSandboxProvider } from \"../types.ts\";\nimport type { SandkitSandboxProvider, SandboxDriverFactory } from \"../types.ts\";\n\nexport { MockSandboxDriverFactory } from \"../core/mock-driver.ts\";\n\nexport function mockSandbox(): SandkitSandboxProvider {\n return createSandboxProvider(\"mock\", new MockSandboxDriverFactory());\n}\n\n/**\n * Internal helper for tests and smoke setups that need custom driver factories.\n * Not part of public API usage.\n */\nexport function internalSandboxProvider(\n driverFactory: SandboxDriverFactory,\n provider = \"custom\",\n): SandkitSandboxProvider {\n return createSandboxProvider(provider, driverFactory);\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/core/mock-driver.ts","../../src/integrations/mock.ts"],"sourcesContent":["import { allowAll, describeWorkspacePolicy } from \"../policies/dsl.ts\";\nimport type { WorkspacePolicy } from \"../policies/types.ts\";\nimport type {\n Command,\n CommandResult,\n SandboxSessionLease,\n PersistedSandboxState,\n SandboxDriver,\n WorkspaceSessionLog,\n WorkspaceSessionProcessStartInput,\n SandboxCreateOptions,\n SandboxDriverFactory,\n WorkspaceRecord,\n} from \"../types.ts\";\nimport { createId } from \"./ids.ts\";\n\ntype FileMap = Record<string, string>;\n\ninterface MockSandboxSnapshotState {\n files: FileMap;\n}\n\nfunction toSnapshotState(snapshot: PersistedSandboxState): MockSandboxSnapshotState {\n const files =\n snapshot.state &&\n typeof snapshot.state === \"object\" &&\n !Array.isArray(snapshot.state) &&\n \"files\" in snapshot.state &&\n snapshot.state.files &&\n typeof snapshot.state.files === \"object\" &&\n !Array.isArray(snapshot.state.files)\n ? (snapshot.state.files as FileMap)\n : {};\n return { files: { ...files } };\n}\n\nclass MockSandboxDriver implements SandboxDriver {\n readonly #files: FileMap;\n #policy: WorkspacePolicy;\n readonly id: string;\n readonly provider = \"mock\";\n #timeoutMs: number;\n #expiresAtMs: number | null = null;\n\n constructor(id: string, files: FileMap = {}, policy: WorkspacePolicy = allowAll()) {\n this.id = id;\n this.#files = { ...files };\n this.#policy = policy;\n this.#timeoutMs = 60_000 * 60;\n }\n\n async applyPolicy(policy: WorkspacePolicy): Promise<void> {\n this.#policy = policy;\n }\n\n async getSessionLease(): Promise<SandboxSessionLease> {\n const observedAt = new Date().toISOString();\n const observedAtMs = Date.parse(observedAt);\n if (this.#expiresAtMs === null) {\n this.#expiresAtMs = observedAtMs + this.#timeoutMs;\n }\n if (this.#expiresAtMs < observedAtMs) {\n this.#expiresAtMs = observedAtMs;\n }\n\n return {\n sandboxId: this.id,\n observedAt,\n expiresAt: new Date(this.#expiresAtMs).toISOString(),\n };\n }\n\n async extendTimeout(durationMs: number): Promise<void> {\n const observedAtMs = Date.now();\n if (this.#expiresAtMs === null || this.#expiresAtMs < observedAtMs) {\n this.#expiresAtMs = observedAtMs;\n }\n this.#expiresAtMs = this.#expiresAtMs + durationMs;\n }\n\n async startProcess(input: WorkspaceSessionProcessStartInput): Promise<{\n processId: string;\n wait: () => Promise<CommandResult>;\n logs: () => AsyncIterable<WorkspaceSessionLog>;\n }> {\n const command = await this.runCommand(input.command, [...input.args]);\n const commandResult = await command.wait();\n if (input.onStdout && commandResult.stdout) {\n input.onStdout(commandResult.stdout);\n }\n if (input.onStderr && commandResult.stderr) {\n input.onStderr(commandResult.stderr);\n }\n\n return {\n processId: `${this.id}-${Date.now()}`,\n wait: async () => commandResult,\n logs: () => {\n const chunks: WorkspaceSessionLog[] = [];\n if (commandResult.stdout) {\n chunks.push({ stream: \"stdout\", chunk: commandResult.stdout });\n }\n if (commandResult.stderr) {\n chunks.push({ stream: \"stderr\", chunk: commandResult.stderr });\n }\n return toAsyncIterable(chunks);\n },\n };\n }\n\n async runCommand(\n command: string,\n args: string[],\n options?: { readonly detached?: boolean },\n ): Promise<Command> {\n const commandResult = await this.#executeCommand(command, args);\n\n return {\n wait: async () => commandResult,\n logs: options?.detached\n ? () => {\n const chunks: WorkspaceSessionLog[] = [];\n if (commandResult.stdout) {\n chunks.push({ stream: \"stdout\", chunk: commandResult.stdout });\n }\n if (commandResult.stderr) {\n chunks.push({ stream: \"stderr\", chunk: commandResult.stderr });\n }\n return toAsyncIterable(chunks);\n }\n : undefined,\n };\n }\n\n async #executeCommand(command: string, args: string[]): Promise<CommandResult> {\n switch (command) {\n case \"echo\":\n return this.runEcho(args);\n case \"cat\":\n return this.runCat(args);\n case \"pwd\":\n return this.ok(\"/workspace\\n\");\n case \"ls\":\n return this.ok(`${Object.keys(this.#files).sort().join(\"\\n\")}\\n`);\n case \"policy\":\n return this.ok(`${JSON.stringify(this.#policy)}\\n`);\n case \"policy-id\":\n return this.ok(`${describeWorkspacePolicy(this.#policy)}\\n`);\n default:\n return {\n exitCode: 127,\n stderr: `Unsupported mock command: ${command}\\n`,\n stdout: \"\",\n };\n }\n }\n\n async snapshot(): Promise<PersistedSandboxState> {\n return {\n kind: \"mock\",\n sessionId: this.id,\n state: {\n files: { ...this.#files },\n },\n };\n }\n\n private ok(stdout: string): CommandResult {\n return {\n exitCode: 0,\n stderr: \"\",\n stdout,\n };\n }\n\n private runCat(args: string[]): CommandResult {\n const target = args[0];\n if (!target) {\n return {\n exitCode: 1,\n stderr: \"cat: missing file operand\\n\",\n stdout: \"\",\n };\n }\n\n const content = this.#files[target];\n if (typeof content !== \"string\") {\n return {\n exitCode: 1,\n stderr: `cat: ${target}: No such file or directory\\n`,\n stdout: \"\",\n };\n }\n\n return this.ok(content.endsWith(\"\\n\") ? content : `${content}\\n`);\n }\n\n private runEcho(args: string[]): CommandResult {\n const redirectIndex = args.indexOf(\">\");\n if (redirectIndex === -1) {\n return this.ok(`${args.join(\" \")}\\n`);\n }\n\n const target = args[redirectIndex + 1];\n if (!target) {\n return {\n exitCode: 1,\n stderr: \"echo: missing redirect target\\n\",\n stdout: \"\",\n };\n }\n\n const content = args.slice(0, redirectIndex).join(\" \");\n this.#files[target] = content;\n return this.ok(\"\");\n }\n}\n\nfunction toAsyncIterable<T>(items: T[]): AsyncIterable<T> {\n return {\n async *[Symbol.asyncIterator]() {\n for (const item of items) {\n yield item;\n }\n },\n };\n}\n\nexport class MockSandboxDriverFactory implements SandboxDriverFactory {\n readonly #sessions = new Map<string, MockSandboxDriver>();\n\n async createSandbox(\n _workspace: WorkspaceRecord,\n options: SandboxCreateOptions,\n ): Promise<SandboxDriver> {\n const driver = new MockSandboxDriver(createId(\"sandbox\"), {}, options.policy);\n this.#sessions.set(driver.id, driver);\n return driver;\n }\n\n isSessionUnavailableError(error: unknown): boolean {\n return error instanceof Error && error.message.startsWith(\"Mock sandbox session not found:\");\n }\n\n async resumeSandbox(\n _workspace: WorkspaceRecord,\n snapshot: PersistedSandboxState,\n options: SandboxCreateOptions,\n ): Promise<SandboxDriver> {\n if (snapshot.kind === \"sandbox-session\") {\n const existing = this.#sessions.get(snapshot.sessionId);\n if (!existing) {\n throw new Error(`Mock sandbox session not found: ${snapshot.sessionId}`);\n }\n\n await existing.applyPolicy(options.policy);\n return existing;\n }\n\n const state = toSnapshotState(snapshot);\n const driver = new MockSandboxDriver(snapshot.sessionId, state.files, options.policy);\n this.#sessions.set(driver.id, driver);\n return driver;\n }\n}\n","import { MockSandboxDriverFactory } from \"../core/mock-driver.ts\";\nimport { createSandboxProvider } from \"../types.ts\";\nimport type { SandkitSandboxProvider, SandboxDriverFactory } from \"../types.ts\";\n\nexport { MockSandboxDriverFactory } from \"../core/mock-driver.ts\";\n\nexport function mockSandbox(): SandkitSandboxProvider {\n return createSandboxProvider(\"mock\", new MockSandboxDriverFactory());\n}\n\n/**\n * Internal helper for tests and smoke setups that need custom driver factories.\n * Not part of public API usage.\n */\nexport function internalSandboxProvider(\n driverFactory: SandboxDriverFactory,\n provider = \"custom\",\n): SandkitSandboxProvider {\n return createSandboxProvider(provider, driverFactory);\n}\n"],"mappings":"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","names":[]}
@@ -1,5 +1,5 @@
1
- import { V as VercelSandboxOptions, h as SandkitSandboxProvider } from '../types-B5N9o-ew.js';
2
- import '../types-BRMAvcWc.js';
1
+ import { V as VercelSandboxOptions, k as SandkitSandboxProvider } from '../types-nu3vpBCZ.js';
2
+ import '../types-DNpj280o.js';
3
3
  import '../types-Dpr_BkF9.js';
4
4
 
5
5
  declare function vercelSandbox(options?: VercelSandboxOptions): SandkitSandboxProvider;
@@ -1,6 +1,9 @@
1
1
  import {
2
2
  resolveGithubDefaultApiKey
3
3
  } from "../chunk-5MXHFOJH.js";
4
+ import {
5
+ createSandboxProvider
6
+ } from "../chunk-XN6DGLRP.js";
4
7
  import {
5
8
  resolveCodexDefaultApiKey
6
9
  } from "../chunk-2M2AZUOC.js";
@@ -10,9 +13,6 @@ import {
10
13
  import {
11
14
  resolveAiGatewayDefaultApiKey
12
15
  } from "../chunk-UEAKE56H.js";
13
- import {
14
- createSandboxProvider
15
- } from "../chunk-HVYCAAZQ.js";
16
16
  import "../chunk-NKTNTBOY.js";
17
17
 
18
18
  // src/drivers/vercel-sandbox.ts
@@ -141,13 +141,24 @@ var VercelSandboxDriver = class {
141
141
  expiresAt: new Date(Date.parse(observedAt) + timeoutMs).toISOString()
142
142
  };
143
143
  }
144
- async runCommand(command, args) {
145
- const result = await this.#sandbox.runCommand(command, args);
146
- const finished = await this.#toCommandFinished(result);
144
+ async runCommand(command, args, options) {
145
+ const rawResult = options?.detached ? await this.#sandbox.runCommand({
146
+ cmd: command,
147
+ args,
148
+ detached: true
149
+ }) : await this.#sandbox.runCommand(command, args);
150
+ const logIterator = options?.detached ? getCommandLogIterator(rawResult) : void 0;
151
+ const commandLogs = logIterator ? () => createEphemeralCommandLogStream(logIterator) : void 0;
147
152
  return {
148
- exitCode: finished.exitCode,
149
- stdout: await finished.stdout(),
150
- stderr: await finished.stderr()
153
+ wait: async () => {
154
+ const finished = await this.#toCommandFinished(rawResult);
155
+ return {
156
+ exitCode: finished.exitCode,
157
+ stdout: await finished.stdout(),
158
+ stderr: await finished.stderr()
159
+ };
160
+ },
161
+ logs: commandLogs
151
162
  };
152
163
  }
153
164
  async startProcess(input) {
@@ -168,7 +179,7 @@ var VercelSandboxDriver = class {
168
179
  return {
169
180
  processId,
170
181
  wait: async () => {
171
- const finished = await started.wait();
182
+ const finished = await this.#toCommandFinished(started);
172
183
  return {
173
184
  exitCode: finished.exitCode,
174
185
  stdout: await finished.stdout(),
@@ -217,6 +228,25 @@ var VercelSandboxDriver = class {
217
228
  return raw;
218
229
  }
219
230
  };
231
+ function createEphemeralCommandLogStream(logs) {
232
+ return {
233
+ async *[Symbol.asyncIterator]() {
234
+ try {
235
+ for await (const log of logs) {
236
+ const normalized = normalizeCommandLog(log);
237
+ if (normalized) {
238
+ yield normalized;
239
+ }
240
+ }
241
+ } catch (cause) {
242
+ if (cause instanceof Error) {
243
+ throw cause;
244
+ }
245
+ throw new Error("Command logs failed.");
246
+ }
247
+ }
248
+ };
249
+ }
220
250
  function isVercelCommandHandle(value) {
221
251
  if (typeof value !== "object" || value === null) {
222
252
  return false;