tensorlake 0.5.1 → 0.5.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/models.ts","../src/defaults.ts","../src/errors.ts","../src/http.ts","../src/tunnel.ts","../src/desktop.ts","../src/sse.ts","../src/url.ts","../src/sandbox.ts","../src/client.ts","../src/image.ts","../src/sandbox-image.ts"],"sourcesContent":["// --- Enums ---\n\nexport enum SandboxStatus {\n PENDING = \"pending\",\n RUNNING = \"running\",\n SNAPSHOTTING = \"snapshotting\",\n SUSPENDING = \"suspending\",\n SUSPENDED = \"suspended\",\n TERMINATED = \"terminated\",\n}\n\nexport enum SnapshotStatus {\n IN_PROGRESS = \"in_progress\",\n COMPLETED = \"completed\",\n FAILED = \"failed\",\n}\n\n/**\n * Content mode for snapshot creation.\n *\n * - `\"full\"`: Full VM snapshot (memory + filesystem state). Sandboxes\n * restored from this snapshot warm-restore VM memory.\n * - `\"filesystem_only\"`: Filesystem-only snapshot. Sandboxes restored from\n * this snapshot cold-boot from the snapshot tarball instead of warm-\n * restoring VM state. Use this for sandbox image builds so that the\n * restored sandbox bypasses Firecracker's overlay-path constraints.\n */\nexport type SnapshotContentMode = \"full\" | \"filesystem_only\";\n\nexport enum ProcessStatus {\n RUNNING = \"running\",\n EXITED = \"exited\",\n SIGNALED = \"signaled\",\n}\n\nexport enum StdinMode {\n CLOSED = \"closed\",\n PIPE = \"pipe\",\n}\n\nexport enum OutputMode {\n CAPTURE = \"capture\",\n DISCARD = \"discard\",\n}\n\nexport enum ContainerState {\n IDLE = \"Idle\",\n RUNNING = \"Running\",\n}\n\n// --- Resource / Network ---\n\nexport interface ContainerResourcesInfo {\n cpus: number;\n memoryMb: number;\n ephemeralDiskMb: number;\n}\n\nexport interface NetworkConfig {\n allowInternetAccess: boolean;\n allowOut: string[];\n denyOut: string[];\n}\n\n// --- Sandbox lifecycle ---\n\nexport interface CreateSandboxOptions {\n /** Optional sandbox image name, such as `tensorlake/ubuntu-minimal` or a registered Sandbox Image. When omitted, Tensorlake uses the default managed environment. */\n image?: string;\n cpus?: number;\n memoryMb?: number;\n /** Root disk size in megabytes. When omitted, the server uses its default disk size. */\n diskMb?: number;\n secretNames?: string[];\n timeoutSecs?: number;\n entrypoint?: string[];\n allowInternetAccess?: boolean;\n allowOut?: string[];\n denyOut?: string[];\n snapshotId?: string;\n /** Optional name for the sandbox. Named sandboxes support suspend/resume. When absent the sandbox is ephemeral. */\n name?: string;\n}\n\nexport interface UpdateSandboxOptions {\n /** New name for the sandbox. Naming an ephemeral sandbox enables suspend/resume. */\n name?: string;\n /** Whether exposed user ports should be reachable without TensorLake auth. */\n allowUnauthenticatedAccess?: boolean;\n /** User ports that should be routable through the sandbox proxy. Port 9501 is reserved. */\n exposedPorts?: number[];\n}\n\nexport interface CreateSandboxResponse {\n sandboxId: string;\n status: SandboxStatus;\n routingHint?: string;\n name?: string | null;\n}\n\nexport interface SandboxInfo {\n sandboxId: string;\n namespace: string;\n status: SandboxStatus;\n /** Resolved sandbox image name. */\n image?: string;\n resources: ContainerResourcesInfo;\n secretNames: string[];\n timeoutSecs?: number;\n entrypoint?: string[];\n network?: NetworkConfig;\n poolId?: string;\n outcome?: string;\n createdAt?: Date;\n terminatedAt?: Date;\n name?: string;\n allowUnauthenticatedAccess?: boolean;\n exposedPorts?: number[];\n sandboxUrl?: string;\n routingHint?: string;\n}\n\nexport interface SandboxPortAccess {\n allowUnauthenticatedAccess: boolean;\n exposedPorts: number[];\n sandboxUrl?: string;\n}\n\n// --- Snapshots ---\n\nexport interface CreateSnapshotResponse {\n snapshotId: string;\n status: SnapshotStatus;\n}\n\nexport interface SnapshotInfo {\n snapshotId: string;\n namespace: string;\n sandboxId: string;\n baseImage: string;\n status: SnapshotStatus;\n error?: string;\n snapshotUri?: string;\n sizeBytes?: number;\n createdAt?: Date;\n}\n\nexport interface SnapshotOptions {\n /**\n * Optional content mode for the snapshot. When omitted the server picks\n * its default. Use `\"filesystem_only\"` for snapshots intended for sandbox\n * image builds so that restored sandboxes cold-boot.\n */\n contentMode?: SnapshotContentMode;\n}\n\nexport interface SnapshotAndWaitOptions extends SnapshotOptions {\n timeout?: number;\n pollInterval?: number;\n}\n\n// --- Pools ---\n\nexport interface CreatePoolOptions {\n /** Sandbox image name, such as `tensorlake/ubuntu-minimal` or a registered Sandbox Image. */\n image: string;\n cpus?: number;\n memoryMb?: number;\n ephemeralDiskMb?: number;\n secretNames?: string[];\n timeoutSecs?: number;\n entrypoint?: string[];\n maxContainers?: number;\n warmContainers?: number;\n}\n\nexport interface UpdatePoolOptions {\n /** Sandbox image name, such as `tensorlake/ubuntu-minimal` or a registered Sandbox Image. */\n image: string;\n cpus?: number;\n memoryMb?: number;\n ephemeralDiskMb?: number;\n secretNames?: string[];\n timeoutSecs?: number;\n entrypoint?: string[];\n maxContainers?: number;\n warmContainers?: number;\n}\n\nexport interface CreateSandboxPoolResponse {\n poolId: string;\n namespace: string;\n}\n\nexport interface PoolContainerInfo {\n id: string;\n state: string;\n sandboxId?: string;\n executorId: string;\n}\n\nexport interface SandboxPoolInfo {\n poolId: string;\n namespace: string;\n /** Sandbox image name backing the pool. */\n image: string;\n resources: ContainerResourcesInfo;\n secretNames: string[];\n timeoutSecs: number;\n entrypoint?: string[];\n maxContainers?: number;\n warmContainers?: number;\n containers?: PoolContainerInfo[];\n createdAt?: Date;\n updatedAt?: Date;\n}\n\n// --- Process management ---\n\nexport interface StartProcessOptions {\n args?: string[];\n env?: Record<string, string>;\n workingDir?: string;\n stdinMode?: StdinMode;\n stdoutMode?: OutputMode;\n stderrMode?: OutputMode;\n}\n\nexport interface ProcessInfo {\n pid: number;\n status: ProcessStatus;\n exitCode?: number;\n signal?: number;\n stdinWritable: boolean;\n command: string;\n args: string[];\n startedAt: Date;\n endedAt?: Date;\n}\n\nexport interface SendSignalResponse {\n success: boolean;\n}\n\nexport interface OutputResponse {\n pid: number;\n lines: string[];\n lineCount: number;\n}\n\nexport interface OutputEvent {\n line: string;\n timestamp: Date;\n stream?: string;\n}\n\n// --- Run ---\n\nexport interface RunOptions {\n args?: string[];\n env?: Record<string, string>;\n workingDir?: string;\n timeout?: number;\n}\n\nexport interface CommandResult {\n exitCode: number;\n stdout: string;\n stderr: string;\n}\n\n// --- File operations ---\n\nexport interface DirectoryEntry {\n name: string;\n isDir: boolean;\n size?: number;\n modifiedAt?: Date;\n}\n\nexport interface ListDirectoryResponse {\n path: string;\n entries: DirectoryEntry[];\n}\n\n// --- PTY ---\n\nexport interface CreatePtySessionOptions {\n command: string;\n args?: string[];\n env?: Record<string, string>;\n workingDir?: string;\n rows?: number;\n cols?: number;\n}\n\nexport interface PtySessionInfo {\n sessionId: string;\n token: string;\n}\n\n// --- Health ---\n\nexport interface HealthResponse {\n healthy: boolean;\n}\n\nexport interface DaemonInfo {\n version: string;\n uptimeSecs: number;\n runningProcesses: number;\n totalProcesses: number;\n}\n\n// --- Client options ---\n\nexport interface SandboxClientOptions {\n apiUrl?: string;\n apiKey?: string;\n organizationId?: string;\n projectId?: string;\n namespace?: string;\n maxRetries?: number;\n retryBackoffMs?: number;\n}\n\nexport interface SandboxOptions {\n sandboxId: string;\n proxyUrl?: string;\n apiKey?: string;\n organizationId?: string;\n projectId?: string;\n routingHint?: string;\n}\n\nexport interface CreateAndConnectOptions extends CreateSandboxOptions {\n poolId?: string;\n proxyUrl?: string;\n startupTimeout?: number;\n}\n\nexport interface SuspendResumeOptions {\n /** If false, fire-and-return without waiting for completion. Default: true. */\n wait?: boolean;\n /** Max seconds to wait when wait=true. Default: 300. */\n timeout?: number;\n /** Seconds between status polls when wait=true. Default: 1. */\n pollInterval?: number;\n}\n\nexport interface CheckpointOptions extends SuspendResumeOptions {\n contentMode?: SnapshotContentMode;\n}\n\nexport interface ConnectOptions {\n sandboxId: string;\n proxyUrl?: string;\n routingHint?: string;\n}\n\n// --- JSON key conversion helpers ---\n\nconst CAMEL_TO_SNAKE_RE = /[A-Z]/g;\n\n/** Convert a camelCase string to snake_case. */\nexport function camelToSnake(str: string): string {\n return str.replace(CAMEL_TO_SNAKE_RE, (ch) => \"_\" + ch.toLowerCase());\n}\n\n/** Convert a snake_case string to camelCase. */\nexport function snakeToCamel(str: string): string {\n return str.replace(/_([a-z])/g, (_, ch) => ch.toUpperCase());\n}\n\n/** Recursively convert all object keys from camelCase to snake_case. */\nexport function toSnakeKeys(obj: unknown): unknown {\n if (Array.isArray(obj)) return obj.map(toSnakeKeys);\n if (obj !== null && typeof obj === \"object\" && !(obj instanceof Date)) {\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj as Record<string, unknown>)) {\n result[camelToSnake(k)] = toSnakeKeys(v);\n }\n return result;\n }\n return obj;\n}\n\n/**\n * Parse a numeric timestamp into a Date.\n *\n * Handles seconds, milliseconds, and microseconds by checking magnitude.\n */\nexport function parseTimestamp(v: unknown): Date | undefined {\n if (v == null) return undefined;\n if (v instanceof Date) return v;\n if (typeof v === \"string\") {\n const parsed = Date.parse(v);\n return Number.isNaN(parsed) ? undefined : new Date(parsed);\n }\n const ts = Number(v);\n if (isNaN(ts)) return undefined;\n if (ts > 1e15) return new Date(ts / 1000); // microseconds → ms\n if (ts > 1e12) return new Date(ts); // already ms\n return new Date(ts * 1000); // seconds → ms\n}\n\n/**\n * Recursively convert all object keys from snake_case to camelCase,\n * with special handling for `id` → contextual name and timestamp parsing.\n */\nexport function fromSnakeKeys(\n obj: unknown,\n idField?: string,\n): unknown {\n if (Array.isArray(obj)) return obj.map((item) => fromSnakeKeys(item, idField));\n if (obj !== null && typeof obj === \"object\" && !(obj instanceof Date)) {\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj as Record<string, unknown>)) {\n let key: string;\n if (k === \"id\" && idField) {\n key = idField;\n } else {\n key = snakeToCamel(k);\n }\n\n // Parse timestamp fields\n if (\n key.endsWith(\"At\") ||\n key === \"timestamp\" ||\n key === \"startedAt\" ||\n key === \"endedAt\"\n ) {\n result[key] = parseTimestamp(v);\n } else if (typeof v === \"object\" && v !== null && !Array.isArray(v)) {\n result[key] = fromSnakeKeys(v);\n } else if (Array.isArray(v)) {\n result[key] = v.map((item) => fromSnakeKeys(item));\n } else {\n // Normalize null → undefined so optional fields match TypeScript's ? convention.\n result[key] = v === null ? undefined : v;\n }\n }\n return result;\n }\n return obj;\n}\n","export const SDK_VERSION = \"0.4.49\";\n\nexport const API_URL =\n process.env.TENSORLAKE_API_URL ?? \"https://api.tensorlake.ai\";\nexport const API_KEY = process.env.TENSORLAKE_API_KEY ?? undefined;\nexport const NAMESPACE = process.env.INDEXIFY_NAMESPACE ?? \"default\";\nexport const SANDBOX_PROXY_URL =\n process.env.TENSORLAKE_SANDBOX_PROXY_URL ?? \"https://sandbox.tensorlake.ai\";\n\nexport const DEFAULT_HTTP_TIMEOUT_MS = 30_000;\nexport const MAX_RETRIES = 3;\nexport const RETRY_BACKOFF_MS = 500;\nexport const RETRYABLE_STATUS_CODES = new Set([429, 502, 503, 504]);\n","/** Base exception for all sandbox-related errors. */\nexport class SandboxException extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"SandboxException\";\n }\n}\n\n/** General sandbox operation error. */\nexport class SandboxError extends SandboxException {\n constructor(message: string) {\n super(message);\n this.name = \"SandboxError\";\n }\n}\n\n/** Raised when the client cannot connect to the API server. */\nexport class SandboxConnectionError extends SandboxError {\n constructor(message: string) {\n super(`Connection error: ${message}`);\n this.name = \"SandboxConnectionError\";\n }\n}\n\n/** Raised when a sandbox is not found. */\nexport class SandboxNotFoundError extends SandboxError {\n readonly sandboxId: string;\n\n constructor(sandboxId: string) {\n super(`Sandbox not found: ${sandboxId}`);\n this.name = \"SandboxNotFoundError\";\n this.sandboxId = sandboxId;\n }\n}\n\n/** Raised when a sandbox pool is not found. */\nexport class PoolNotFoundError extends SandboxError {\n readonly poolId: string;\n\n constructor(poolId: string) {\n super(`Sandbox pool not found: ${poolId}`);\n this.name = \"PoolNotFoundError\";\n this.poolId = poolId;\n }\n}\n\n/** Raised when attempting to delete a pool that is in use. */\nexport class PoolInUseError extends SandboxError {\n readonly poolId: string;\n\n constructor(poolId: string, message?: string) {\n const base = `Cannot delete pool ${poolId}: pool is in use`;\n super(message ? `${base} - ${message}` : base);\n this.name = \"PoolInUseError\";\n this.poolId = poolId;\n }\n}\n\n/** Raised when the remote API returns an error. */\nexport class RemoteAPIError extends SandboxError {\n readonly statusCode: number;\n readonly responseMessage: string;\n\n constructor(statusCode: number, message: string) {\n super(`API error (status ${statusCode}): ${message}`);\n this.name = \"RemoteAPIError\";\n this.statusCode = statusCode;\n this.responseMessage = message;\n }\n}\n\n/** Raised when request output is fetched before the request has completed. */\nexport class RequestNotFinishedError extends Error {\n constructor() {\n super(\"Request has not finished yet\");\n this.name = \"RequestNotFinishedError\";\n }\n}\n\n/** Raised when a request completed unsuccessfully. */\nexport class RequestFailedError extends Error {\n readonly failure: string;\n\n constructor(failure: string) {\n super(`Request failed: ${failure}`);\n this.name = \"RequestFailedError\";\n this.failure = failure;\n }\n}\n\n/** Raised when a request surfaced an application-level error. */\nexport class RequestExecutionError extends Error {\n readonly functionName?: string;\n\n constructor(message: string, functionName?: string) {\n super(\n functionName ? `Request error in ${functionName}: ${message}` : message,\n );\n this.name = \"RequestExecutionError\";\n this.functionName = functionName;\n }\n}\n","import {\n Agent,\n fetch as undiciFetch,\n setGlobalDispatcher,\n type BodyInit as UndiciBodyInit,\n} from \"undici\";\nimport * as defaults from \"./defaults.js\";\nimport {\n PoolInUseError,\n PoolNotFoundError,\n RemoteAPIError,\n SandboxConnectionError,\n SandboxNotFoundError,\n} from \"./errors.js\";\n\nexport interface HttpClientOptions {\n baseUrl: string;\n apiKey?: string;\n organizationId?: string;\n projectId?: string;\n hostHeader?: string;\n routingHint?: string;\n maxRetries?: number;\n retryBackoffMs?: number;\n timeoutMs?: number;\n}\n\nsetGlobalDispatcher(\n new Agent({\n keepAliveTimeout: 60_000,\n allowH2: true,\n }),\n);\n\ntype RequestBody = BodyInit | Uint8Array | ArrayBuffer;\n\nexport interface HttpRequestOptions {\n body?: RequestBody | null;\n headers?: Record<string, string>;\n json?: unknown;\n signal?: AbortSignal;\n allowHttpErrors?: boolean;\n}\n\n/**\n * The return value of every SDK operation. Carries the W3C `trace_id` so callers\n * can correlate a specific request with its server-side spans in Datadog APM or\n * any other OTEL-compatible backend.\n *\n * Because this is an intersection type, all properties of `T` are accessible\n * directly — existing code that ignores `traceId` continues to compile and run\n * unchanged.\n *\n * @example\n * const sandbox = await client.createSandbox(req);\n * console.log(sandbox.id); // existing field — unchanged\n * console.log(sandbox.traceId); // new: look this up in Datadog APM\n */\nexport type Traced<T> = T & { readonly traceId: string };\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction withTraceId<T>(value: T, traceId: string): Traced<T> {\n if (value == null) {\n return { traceId } as unknown as Traced<T>;\n }\n return Object.assign(value as any, { traceId }) as Traced<T>;\n}\n\n/**\n * Internal HTTP client with retry logic, auth headers, and error mapping.\n *\n * Uses native `fetch`. Retries on transient status codes (429, 502, 503, 504)\n * with exponential backoff.\n */\nexport class HttpClient {\n private readonly baseUrl: string;\n private readonly headers: Record<string, string>;\n private readonly maxRetries: number;\n private readonly retryBackoffMs: number;\n private readonly timeoutMs: number;\n private abortController: AbortController | null = null;\n\n constructor(options: HttpClientOptions) {\n const url = options.baseUrl;\n this.baseUrl = url.endsWith(\"/\") ? url.slice(0, -1) : url;\n this.maxRetries = options.maxRetries ?? defaults.MAX_RETRIES;\n this.retryBackoffMs = options.retryBackoffMs ?? defaults.RETRY_BACKOFF_MS;\n this.timeoutMs = options.timeoutMs ?? defaults.DEFAULT_HTTP_TIMEOUT_MS;\n\n this.headers = {\n \"User-Agent\": `tensorlake-typescript-sdk/${defaults.SDK_VERSION}`,\n };\n if (options.apiKey) {\n this.headers[\"Authorization\"] = `Bearer ${options.apiKey}`;\n }\n if (options.organizationId) {\n this.headers[\"X-Forwarded-Organization-Id\"] = options.organizationId;\n }\n if (options.projectId) {\n this.headers[\"X-Forwarded-Project-Id\"] = options.projectId;\n }\n if (options.hostHeader) {\n this.headers[\"Host\"] = options.hostHeader;\n }\n if (options.routingHint) {\n this.headers[\"X-Tensorlake-Route-Hint\"] = options.routingHint;\n }\n }\n\n close(): void {\n this.abortController?.abort();\n this.abortController = null;\n }\n\n /** Make a JSON request, returning the parsed response body. */\n async requestJson<T>(\n method: string,\n path: string,\n options?: {\n body?: unknown;\n headers?: Record<string, string>;\n signal?: AbortSignal;\n },\n ): Promise<Traced<T>> {\n const response = await this.requestResponse(method, path, {\n json: options?.body,\n headers: options?.headers,\n signal: options?.signal,\n });\n const text = await response.text();\n const data = (text ? JSON.parse(text) : undefined) as T;\n return withTraceId(data, response.traceId);\n }\n\n /** Make a request returning raw bytes. */\n async requestBytes(\n method: string,\n path: string,\n options?: {\n body?: RequestBody | null;\n contentType?: string;\n headers?: Record<string, string>;\n signal?: AbortSignal;\n },\n ): Promise<Traced<Uint8Array>> {\n const headers = { ...(options?.headers ?? {}) };\n if (options?.contentType) {\n headers[\"Content-Type\"] = options.contentType;\n }\n\n const response = await this.requestResponse(method, path, {\n body: options?.body,\n headers,\n signal: options?.signal,\n });\n const buffer = await response.arrayBuffer();\n return withTraceId(new Uint8Array(buffer), response.traceId);\n }\n\n /** Make a request and return the response body as an SSE stream. */\n async requestStream(\n method: string,\n path: string,\n options?: { signal?: AbortSignal; json?: unknown },\n ): Promise<Traced<ReadableStream<Uint8Array>>> {\n const response = await this.requestResponse(method, path, {\n json: options?.json,\n headers: { Accept: \"text/event-stream\" },\n signal: options?.signal,\n });\n if (!response.body) {\n throw new RemoteAPIError(\n response.status,\n \"No response body for SSE stream\",\n );\n }\n return withTraceId(response.body, response.traceId);\n }\n\n /** Make a request and return the raw Response. */\n async requestResponse(\n method: string,\n path: string,\n options?: HttpRequestOptions,\n ): Promise<Traced<Response>> {\n const headers = {\n ...this.headers,\n ...(options?.headers ?? {}),\n };\n const hasJsonBody = options?.json !== undefined;\n if (hasJsonBody && !hasHeader(headers, \"Content-Type\")) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n\n const body = hasJsonBody\n ? JSON.stringify(options?.json)\n : normalizeRequestBody(options?.body);\n\n const { response, traceId } = await this.doFetch(\n method,\n path,\n body,\n headers,\n options?.signal,\n options?.allowHttpErrors ?? false,\n );\n return withTraceId(response, traceId);\n }\n\n private static makeTraceparent(): { traceparent: string; traceId: string } {\n const randomHex = (bytes: number) =>\n Array.from(crypto.getRandomValues(new Uint8Array(bytes)))\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n const traceId = randomHex(16);\n const spanId = randomHex(8);\n return { traceparent: `00-${traceId}-${spanId}-01`, traceId };\n }\n\n private async doFetch(\n method: string,\n path: string,\n body: UndiciBodyInit | undefined,\n headers: Record<string, string>,\n signal?: AbortSignal,\n allowHttpErrors = false,\n ): Promise<{ response: Response; traceId: string }> {\n const url = `${this.baseUrl}${path}`;\n const { traceparent, traceId } = HttpClient.makeTraceparent();\n headers[\"traceparent\"] = traceparent;\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n if (attempt > 0) {\n const delay = this.retryBackoffMs * Math.pow(2, attempt - 1);\n await sleep(delay);\n }\n\n this.abortController = new AbortController();\n const timeoutId = setTimeout(\n () => this.abortController?.abort(),\n this.timeoutMs,\n );\n\n // Combine external signal with internal timeout\n const combinedSignal = signal\n ? anySignal([signal, this.abortController.signal])\n : this.abortController.signal;\n\n try {\n const response = (await undiciFetch(url, {\n method,\n headers,\n body,\n signal: combinedSignal,\n })) as Response;\n\n clearTimeout(timeoutId);\n\n if (response.ok) return { response, traceId };\n\n // Check if retryable\n if (\n defaults.RETRYABLE_STATUS_CODES.has(response.status) &&\n attempt < this.maxRetries\n ) {\n lastError = new RemoteAPIError(\n response.status,\n await response.text().catch(() => \"\"),\n );\n continue;\n }\n\n if (allowHttpErrors) {\n return { response, traceId };\n }\n\n // Non-retryable error — throw mapped error\n const errorBody = await response.text().catch(() => \"\");\n throwMappedError(response.status, errorBody, path);\n } catch (err) {\n clearTimeout(timeoutId);\n\n if (\n err instanceof RemoteAPIError ||\n err instanceof SandboxNotFoundError ||\n err instanceof PoolNotFoundError ||\n err instanceof PoolInUseError\n ) {\n throw err;\n }\n\n if (signal?.aborted) {\n throw new SandboxConnectionError(\"Request aborted\");\n }\n\n // Network / timeout error\n lastError = err instanceof Error ? err : new Error(String(err));\n\n if (attempt >= this.maxRetries) {\n throw new SandboxConnectionError(lastError.message);\n }\n }\n }\n\n throw new SandboxConnectionError(lastError?.message ?? \"Request failed\");\n }\n}\n\nfunction hasHeader(headers: Record<string, string>, name: string): boolean {\n const lowered = name.toLowerCase();\n return Object.keys(headers).some((key) => key.toLowerCase() === lowered);\n}\n\nfunction normalizeRequestBody(\n body?: RequestBody | null,\n): UndiciBodyInit | undefined {\n if (body == null) {\n return undefined;\n }\n if (body instanceof Uint8Array) {\n return Uint8Array.from(body).buffer as ArrayBuffer;\n }\n return body as UndiciBodyInit;\n}\n\n/** Map HTTP status codes to specific error types. */\nfunction throwMappedError(status: number, body: string, path: string): never {\n let message = body;\n try {\n const parsed = JSON.parse(body);\n if (parsed.message) message = parsed.message;\n else if (parsed.error) message = parsed.error;\n } catch {\n // use raw body\n }\n\n if (status === 404) {\n // Determine entity type from path\n if (path.includes(\"sandbox-pools\") || path.includes(\"pools\")) {\n const match = path.match(/sandbox-pools\\/([^/]+)/);\n if (match) throw new PoolNotFoundError(match[1]);\n }\n if (path.includes(\"sandboxes\")) {\n const match = path.match(/sandboxes\\/([^/]+)/);\n if (match) throw new SandboxNotFoundError(match[1]);\n }\n throw new RemoteAPIError(404, message);\n }\n\n if (status === 409) {\n if (path.includes(\"sandbox-pools\") || path.includes(\"pools\")) {\n const match = path.match(/sandbox-pools\\/([^/]+)/);\n if (match) throw new PoolInUseError(match[1], message);\n }\n }\n\n throw new RemoteAPIError(status, message);\n}\n\n/** Combine multiple AbortSignals into one that aborts when any fires. */\nfunction anySignal(signals: AbortSignal[]): AbortSignal {\n const controller = new AbortController();\n for (const signal of signals) {\n if (signal.aborted) {\n controller.abort(signal.reason);\n return controller.signal;\n }\n signal.addEventListener(\"abort\", () => controller.abort(signal.reason), {\n once: true,\n });\n }\n return controller.signal;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import * as net from \"node:net\";\nimport { SandboxConnectionError, SandboxError } from \"./errors.js\";\nimport WebSocket, { type RawData } from \"ws\";\n\nconst DEFAULT_TUNNEL_CONNECT_TIMEOUT_MS = 10_000;\nconst WEBSOCKET_KEEPALIVE_INTERVAL_MS = 15_000;\n\nexport interface CreateTunnelOptions {\n /** Local host/interface to bind. Defaults to `127.0.0.1`. */\n localHost?: string;\n /** Local port to bind. Defaults to the remote port. Use `0` for an ephemeral port. */\n localPort?: number;\n /** Seconds to wait for each websocket tunnel connection. Defaults to `10`. */\n connectTimeout?: number;\n}\n\nexport interface TunnelAddress {\n host: string;\n port: number;\n}\n\ninterface TunnelWebSocketOptions {\n baseUrl: string;\n wsHeaders: Record<string, string>;\n remotePort: number;\n connectTimeoutMs?: number;\n}\n\ninterface PendingRead {\n length: number;\n resolve: (chunk: Buffer) => void;\n reject: (error: Error) => void;\n}\n\ninterface ActiveRelay {\n localSocket: net.Socket;\n websocket: WebSocket | null;\n}\n\nexport async function openTunnelWebSocket(\n options: TunnelWebSocketOptions,\n): Promise<WebSocket> {\n const wsUrl = buildTunnelWsUrl(options.baseUrl, options.remotePort);\n const timeoutMs = options.connectTimeoutMs ?? DEFAULT_TUNNEL_CONNECT_TIMEOUT_MS;\n\n return new Promise<WebSocket>((resolve, reject) => {\n const socket = new WebSocket(wsUrl, {\n headers: options.wsHeaders,\n });\n\n let settled = false;\n const timer = setTimeout(() => {\n fail(\n new SandboxError(\n `timed out while connecting tunnel websocket after ${(timeoutMs / 1000).toFixed(2)}s`,\n ),\n );\n }, timeoutMs);\n\n const cleanup = () => {\n clearTimeout(timer);\n socket.removeListener(\"open\", onOpen);\n socket.removeListener(\"error\", onError);\n socket.removeListener(\"close\", onCloseBeforeOpen);\n socket.removeListener(\"unexpected-response\", onUnexpectedResponse);\n };\n\n const settle = (callback: () => void) => {\n if (settled) return;\n settled = true;\n cleanup();\n callback();\n };\n\n const fail = (error: Error) => {\n settle(() => {\n reject(error);\n });\n };\n\n const onOpen = () => {\n settle(() => resolve(socket));\n };\n\n const onError = (error: Error) => {\n fail(new SandboxConnectionError(error.message));\n };\n\n const onCloseBeforeOpen = (code: number, reason: Buffer) => {\n const closeReason =\n reason.length > 0 ? reason.toString(\"utf8\") : \"no reason\";\n fail(\n new SandboxError(\n `tunnel websocket closed before opening: ${code} ${closeReason}`,\n ),\n );\n };\n\n const onUnexpectedResponse = (\n _request: unknown,\n response: { statusCode?: number; statusMessage?: string },\n ) => {\n const status = response.statusCode ?? 0;\n const statusMessage = response.statusMessage?.trim();\n fail(\n new SandboxError(\n `tunnel websocket handshake failed with HTTP ${status}${statusMessage ? ` ${statusMessage}` : \"\"}`,\n ),\n );\n };\n\n socket.on(\"open\", onOpen);\n socket.on(\"error\", onError);\n socket.on(\"close\", onCloseBeforeOpen);\n socket.on(\"unexpected-response\", onUnexpectedResponse);\n });\n}\n\nexport class TunnelByteStream {\n private readonly socket: WebSocket;\n private readBuffer: Buffer = Buffer.alloc(0);\n private readonly pendingReads: PendingRead[] = [];\n private closeError: Error | null = null;\n private closePromise: Promise<void> | null = null;\n private readonly keepAliveInterval: ReturnType<typeof setInterval>;\n\n constructor(socket: WebSocket) {\n this.socket = socket;\n this.keepAliveInterval = setInterval(() => {\n if (socket.readyState === WebSocket.OPEN) {\n socket.ping();\n }\n }, WEBSOCKET_KEEPALIVE_INTERVAL_MS);\n this.keepAliveInterval.unref?.();\n\n socket.on(\"message\", (message: RawData, isBinary: boolean) => {\n if (!isBinary) {\n this.fail(\n new SandboxError(\"desktop tunnel received unexpected text frame\"),\n );\n return;\n }\n this.pushBytes(normalizeWebSocketData(message));\n });\n\n socket.on(\"ping\", (data: Buffer) => {\n if (socket.readyState === WebSocket.OPEN) {\n socket.pong(data, false, () => {});\n }\n });\n\n socket.on(\"close\", (_code: number, reason: Buffer) => {\n clearInterval(this.keepAliveInterval);\n const closeReason =\n reason.length > 0 ? reason.toString(\"utf8\") : \"desktop tunnel closed unexpectedly\";\n this.fail(new SandboxError(closeReason));\n });\n\n socket.on(\"error\", (error: Error) => {\n clearInterval(this.keepAliveInterval);\n this.fail(new SandboxConnectionError(error.message));\n });\n }\n\n static async connect(options: TunnelWebSocketOptions): Promise<TunnelByteStream> {\n const socket = await openTunnelWebSocket(options);\n return new TunnelByteStream(socket);\n }\n\n async readExactly(length: number): Promise<Buffer> {\n if (length < 0) {\n throw new SandboxError(`read length must be >= 0, got ${length}`);\n }\n if (length === 0) {\n return Buffer.alloc(0);\n }\n if (this.readBuffer.length >= length) {\n const chunk = this.readBuffer.subarray(0, length);\n this.readBuffer = this.readBuffer.subarray(length);\n return chunk;\n }\n if (this.closeError) {\n throw this.closeError;\n }\n return new Promise<Buffer>((resolve, reject) => {\n this.pendingReads.push({ length, resolve, reject });\n });\n }\n\n async writeAll(data: Uint8Array): Promise<void> {\n if (this.closeError) {\n throw this.closeError;\n }\n if (this.socket.readyState !== WebSocket.OPEN) {\n throw new SandboxError(\"desktop tunnel is not connected\");\n }\n const payload = Buffer.from(data);\n await new Promise<void>((resolve, reject) => {\n this.socket.send(payload, { binary: true }, (error?: Error) => {\n if (error) {\n reject(new SandboxConnectionError(error.message));\n return;\n }\n resolve();\n });\n });\n }\n\n async close(): Promise<void> {\n if (this.closePromise) {\n return this.closePromise;\n }\n if (\n this.socket.readyState === WebSocket.CLOSED ||\n this.socket.readyState === WebSocket.CLOSING\n ) {\n this.closePromise = Promise.resolve();\n return this.closePromise;\n }\n\n this.closePromise = new Promise<void>((resolve) => {\n const onClose = () => {\n this.socket.removeListener(\"close\", onClose);\n resolve();\n };\n this.socket.on(\"close\", onClose);\n this.socket.close();\n });\n return this.closePromise;\n }\n\n private pushBytes(chunk: Buffer): void {\n this.readBuffer =\n this.readBuffer.length === 0\n ? chunk\n : Buffer.from(Buffer.concat([this.readBuffer, chunk]));\n this.flushPendingReads();\n }\n\n private flushPendingReads(): void {\n while (this.pendingReads.length > 0) {\n const next = this.pendingReads[0];\n if (this.readBuffer.length < next.length) {\n break;\n }\n const chunk = this.readBuffer.subarray(0, next.length);\n this.readBuffer = this.readBuffer.subarray(next.length);\n this.pendingReads.shift();\n next.resolve(chunk);\n }\n }\n\n private fail(error: Error): void {\n if (this.closeError) {\n return;\n }\n this.closeError = error;\n while (this.pendingReads.length > 0) {\n const pending = this.pendingReads.shift();\n pending?.reject(error);\n }\n }\n}\n\nexport class TcpTunnel {\n readonly remotePort: number;\n readonly localHost: string;\n readonly localPort: number;\n\n private readonly baseUrl: string;\n private readonly wsHeaders: Record<string, string>;\n private readonly server: net.Server;\n private readonly connectTimeoutMs: number;\n private readonly activeRelays = new Set<ActiveRelay>();\n private closePromise: Promise<void> | null = null;\n\n private constructor(options: {\n baseUrl: string;\n wsHeaders: Record<string, string>;\n remotePort: number;\n localHost: string;\n localPort: number;\n server: net.Server;\n connectTimeoutMs: number;\n }) {\n this.baseUrl = options.baseUrl;\n this.wsHeaders = options.wsHeaders;\n this.remotePort = options.remotePort;\n this.localHost = options.localHost;\n this.localPort = options.localPort;\n this.server = options.server;\n this.connectTimeoutMs = options.connectTimeoutMs;\n }\n\n static async listen(options: {\n baseUrl: string;\n wsHeaders: Record<string, string>;\n remotePort: number;\n localHost?: string;\n localPort?: number;\n connectTimeout?: number;\n }): Promise<TcpTunnel> {\n const remotePort = validatePort(options.remotePort, \"remote port\");\n const localHost = options.localHost ?? \"127.0.0.1\";\n const localPort = validatePort(\n options.localPort ?? remotePort,\n \"local port\",\n true,\n );\n const connectTimeoutMs = secondsToMillis(options.connectTimeout ?? 10);\n\n const server = net.createServer();\n await listenServer(server, localPort, localHost);\n\n const address = server.address();\n if (!address || typeof address === \"string\") {\n server.close();\n throw new SandboxError(\"failed to determine bound tunnel address\");\n }\n\n const tunnel = new TcpTunnel({\n baseUrl: options.baseUrl,\n wsHeaders: options.wsHeaders,\n remotePort,\n localHost,\n localPort: address.port,\n server,\n connectTimeoutMs,\n });\n\n server.on(\"connection\", (localSocket) => {\n void tunnel.handleConnection(localSocket);\n });\n\n return tunnel;\n }\n\n address(): TunnelAddress {\n return { host: this.localHost, port: this.localPort };\n }\n\n async close(): Promise<void> {\n if (this.closePromise) {\n return this.closePromise;\n }\n\n for (const relay of this.activeRelays) {\n relay.localSocket.destroy();\n relay.websocket?.close();\n }\n\n this.closePromise = new Promise<void>((resolve, reject) => {\n this.server.close((error) => {\n if (error) {\n reject(new SandboxError(`failed to close tunnel listener: ${error.message}`));\n return;\n }\n resolve();\n });\n });\n return this.closePromise;\n }\n\n private async handleConnection(localSocket: net.Socket): Promise<void> {\n localSocket.setNoDelay(true);\n\n const relay: ActiveRelay = { localSocket, websocket: null };\n this.activeRelays.add(relay);\n\n try {\n relay.websocket = await openTunnelWebSocket({\n baseUrl: this.baseUrl,\n wsHeaders: this.wsHeaders,\n remotePort: this.remotePort,\n connectTimeoutMs: this.connectTimeoutMs,\n });\n await relaySocket(localSocket, relay.websocket);\n } catch (error) {\n localSocket.destroy(\n error instanceof Error ? error : new Error(String(error)),\n );\n } finally {\n this.activeRelays.delete(relay);\n }\n }\n}\n\nexport function buildTunnelWsUrl(baseUrl: string, remotePort: number): string {\n const url = new URL(baseUrl);\n url.protocol = url.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n url.pathname = \"/api/v1/tunnels/tcp\";\n url.search = `port=${encodeURIComponent(String(remotePort))}`;\n return url.toString();\n}\n\nfunction normalizeWebSocketData(message: RawData): Buffer {\n if (Buffer.isBuffer(message)) return message;\n if (Array.isArray(message)) {\n return Buffer.concat(message.map((part) => Buffer.from(part)));\n }\n return Buffer.from(message);\n}\n\nasync function relaySocket(localSocket: net.Socket, websocket: WebSocket): Promise<void> {\n return new Promise<void>((resolve) => {\n let settled = false;\n const keepAliveInterval = setInterval(() => {\n if (websocket.readyState === WebSocket.OPEN) {\n websocket.ping();\n }\n }, WEBSOCKET_KEEPALIVE_INTERVAL_MS);\n keepAliveInterval.unref?.();\n\n const finish = () => {\n if (settled) return;\n settled = true;\n clearInterval(keepAliveInterval);\n cleanup();\n resolve();\n };\n\n const cleanup = () => {\n localSocket.removeListener(\"data\", onLocalData);\n localSocket.removeListener(\"end\", onLocalEnd);\n localSocket.removeListener(\"close\", onLocalClose);\n localSocket.removeListener(\"error\", onLocalError);\n websocket.removeListener(\"message\", onWsMessage);\n websocket.removeListener(\"close\", onWsClose);\n websocket.removeListener(\"error\", onWsError);\n websocket.removeListener(\"ping\", onWsPing);\n };\n\n const onLocalData = (chunk: Buffer) => {\n if (websocket.readyState !== WebSocket.OPEN) {\n localSocket.destroy();\n return;\n }\n\n websocket.send(chunk, { binary: true }, (error?: Error) => {\n if (error) {\n localSocket.destroy(error);\n }\n });\n };\n\n const onLocalEnd = () => {\n if (websocket.readyState === WebSocket.OPEN) {\n websocket.close();\n }\n };\n\n const onLocalClose = () => {\n if (\n websocket.readyState === WebSocket.OPEN ||\n websocket.readyState === WebSocket.CONNECTING\n ) {\n websocket.close();\n }\n finish();\n };\n\n const onLocalError = () => {\n websocket.close();\n finish();\n };\n\n const onWsMessage = (message: RawData, isBinary: boolean) => {\n if (!isBinary) {\n localSocket.destroy(\n new SandboxError(\"received unexpected text frame from tunnel\"),\n );\n websocket.close();\n return;\n }\n\n const payload = normalizeWebSocketData(message);\n if (!localSocket.destroyed) {\n localSocket.write(payload);\n }\n };\n\n const onWsClose = () => {\n if (!localSocket.destroyed) {\n localSocket.end();\n }\n finish();\n };\n\n const onWsError = (error: Error) => {\n localSocket.destroy(error);\n finish();\n };\n\n const onWsPing = (data: Buffer) => {\n if (websocket.readyState === WebSocket.OPEN) {\n websocket.pong(data, false, () => {});\n }\n };\n\n localSocket.on(\"data\", onLocalData);\n localSocket.on(\"end\", onLocalEnd);\n localSocket.on(\"close\", onLocalClose);\n localSocket.on(\"error\", onLocalError);\n websocket.on(\"message\", onWsMessage);\n websocket.on(\"close\", onWsClose);\n websocket.on(\"error\", onWsError);\n websocket.on(\"ping\", onWsPing);\n });\n}\n\nasync function listenServer(\n server: net.Server,\n localPort: number,\n localHost: string,\n): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n const onError = (error: Error) => {\n server.removeListener(\"listening\", onListening);\n reject(\n new SandboxError(\n `failed to bind local tunnel listener on ${localHost}:${localPort}: ${error.message}`,\n ),\n );\n };\n\n const onListening = () => {\n server.removeListener(\"error\", onError);\n resolve();\n };\n\n server.once(\"error\", onError);\n server.once(\"listening\", onListening);\n server.listen(localPort, localHost);\n });\n}\n\nfunction validatePort(port: number, label: string, allowZero = false): number {\n if (!Number.isInteger(port)) {\n throw new SandboxError(`${label} must be an integer, got ${port}`);\n }\n if (allowZero && port === 0) {\n return port;\n }\n if (port < 1 || port > 65535) {\n throw new SandboxError(`${label} must be between 1 and 65535, got ${port}`);\n }\n return port;\n}\n\nfunction secondsToMillis(seconds: number): number {\n if (!Number.isFinite(seconds) || seconds < 0) {\n throw new SandboxError(`timeout must be >= 0 seconds, got ${seconds}`);\n }\n return Math.round(seconds * 1000);\n}\n\nexport async function withTimeout<T>(\n timeoutMs: number,\n operation: () => Promise<T>,\n timeoutMessage: string,\n): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(() => {\n reject(new SandboxError(timeoutMessage));\n }, timeoutMs);\n\n void operation()\n .then((value) => {\n clearTimeout(timer);\n resolve(value);\n })\n .catch((error) => {\n clearTimeout(timer);\n reject(error);\n });\n });\n}\n","import { deflateSync } from \"node:zlib\";\nimport { SandboxError } from \"./errors.js\";\nimport { TunnelByteStream, withTimeout } from \"./tunnel.js\";\n\nconst SECURITY_TYPE_NONE = 1;\nconst SECURITY_TYPE_VNC_AUTH = 2;\nconst ENCODING_RAW = 0;\nconst ENCODING_DESKTOP_SIZE = -223;\n\nconst BUTTON_LEFT_MASK = 1;\nconst BUTTON_MIDDLE_MASK = 1 << 1;\nconst BUTTON_RIGHT_MASK = 1 << 2;\nconst BUTTON_SCROLL_UP_MASK = 1 << 3;\nconst BUTTON_SCROLL_DOWN_MASK = 1 << 4;\n\nconst PNG_SIGNATURE = Buffer.from([\n 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a,\n]);\n\nconst CRC32_TABLE = buildCrc32Table();\n\nexport type MouseButton = \"left\" | \"middle\" | \"right\";\n\nexport interface ConnectDesktopOptions {\n /** Remote VNC port. Defaults to `5901`. */\n port?: number;\n /** Optional VNC password for classic VNC authentication. */\n password?: string;\n /** Whether to request a shared VNC session. Defaults to `true`. */\n shared?: boolean;\n /** Seconds to wait while opening the desktop session. Defaults to `10`. */\n connectTimeout?: number;\n}\n\nexport interface DesktopPointerOptions {\n button?: MouseButton;\n x?: number;\n y?: number;\n}\n\nexport interface DesktopDoubleClickOptions extends DesktopPointerOptions {\n delayMs?: number;\n}\n\ninterface DesktopConnectRequest extends ConnectDesktopOptions {\n baseUrl: string;\n wsHeaders: Record<string, string>;\n}\n\ninterface FramebufferUpdateOutcome {\n kind: \"framebufferUpdate\";\n sawResize: boolean;\n sawRaw: boolean;\n}\n\ninterface BellOutcome {\n kind: \"bell\";\n}\n\ninterface ServerCutTextOutcome {\n kind: \"serverCutText\";\n}\n\ntype ServerMessageOutcome =\n | FramebufferUpdateOutcome\n | BellOutcome\n | ServerCutTextOutcome;\n\nexport interface DesktopTransport {\n readExactly(length: number): Promise<Buffer>;\n writeAll(data: Uint8Array): Promise<void>;\n close(): Promise<void>;\n}\n\nexport class DesktopSession<T extends DesktopTransport> {\n readonly transport: T;\n width: number;\n height: number;\n\n private pixelFormat: PixelFormat;\n private framebuffer: Uint8Array;\n private pointerX = 0;\n private pointerY = 0;\n private buttonMask = 0;\n private framebufferVersion = 0;\n private closed = false;\n private updateLoopError: Error | null = null;\n private readonly updateSignal = createDeferredSignal();\n private updateLoopPromise: Promise<void> | null = null;\n\n constructor(options: {\n transport: T;\n width: number;\n height: number;\n pixelFormat: PixelFormat;\n framebuffer: Uint8Array;\n }) {\n this.transport = options.transport;\n this.width = options.width;\n this.height = options.height;\n this.pixelFormat = options.pixelFormat;\n this.framebuffer = options.framebuffer;\n }\n\n static async connect<T extends DesktopTransport>(\n transport: T,\n password?: string,\n shared = true,\n ): Promise<DesktopSession<T>> {\n const serverVersion = await ProtocolVersion.read(transport);\n const clientVersion = serverVersion.negotiated();\n await transport.writeAll(Buffer.from(clientVersion.render(), \"ascii\"));\n\n await negotiateSecurity(transport, clientVersion, password);\n await transport.writeAll(Uint8Array.of(shared ? 1 : 0));\n\n const init = await ServerInit.read(transport);\n if (!init.pixelFormat.trueColor) {\n throw new SandboxError(\n \"desktop sessions require a true-color VNC pixel format\",\n );\n }\n\n const pixelFormat = PixelFormat.preferred();\n await sendSetPixelFormat(transport, pixelFormat);\n await sendSetEncodings(transport, [ENCODING_RAW, ENCODING_DESKTOP_SIZE]);\n\n const session = new DesktopSession({\n transport,\n width: init.width,\n height: init.height,\n pixelFormat,\n framebuffer: allocateFramebuffer(init.width, init.height),\n });\n session.startFramebufferUpdates();\n return session;\n }\n\n async close(): Promise<void> {\n this.closed = true;\n this.updateSignal.resolve();\n await this.transport.close();\n await this.updateLoopPromise;\n }\n\n async screenshot(timeoutSeconds = 5): Promise<Uint8Array> {\n await this.waitForFramebufferVersion(\n 1,\n timeoutSeconds,\n `timed out waiting for initial desktop framebuffer after ${timeoutSeconds.toFixed(2)}s`,\n );\n return encodePng(this.width, this.height, this.framebuffer);\n }\n\n getFrameVersion(): number {\n return this.framebufferVersion;\n }\n\n async screenshotAfter(frameVersion: number, timeoutSeconds = 1): Promise<Uint8Array> {\n const minimumVersion = validateNonNegativeInteger(frameVersion, \"frame version\") + 1;\n\n if (this.framebufferVersion < minimumVersion) {\n await this.waitForFramebufferVersion(\n minimumVersion,\n timeoutSeconds,\n `timed out waiting for a fresher desktop framebuffer after ${timeoutSeconds.toFixed(2)}s`,\n );\n }\n\n return encodePng(this.width, this.height, this.framebuffer);\n }\n\n async moveMouse(x: number, y: number): Promise<void> {\n const nextX = validateCoordinate(x, \"mouse x coordinate\");\n const nextY = validateCoordinate(y, \"mouse y coordinate\");\n this.ensurePointerInBounds(nextX, nextY);\n this.pointerX = nextX;\n this.pointerY = nextY;\n await sendPointerEvent(this.transport, this.buttonMask, nextX, nextY);\n }\n\n async mousePress(options?: DesktopPointerOptions): Promise<void> {\n const button = options?.button ?? \"left\";\n await this.moveIfRequested(options?.x, options?.y);\n this.buttonMask |= buttonMask(button);\n await sendPointerEvent(\n this.transport,\n this.buttonMask,\n this.pointerX,\n this.pointerY,\n );\n }\n\n async mouseRelease(options?: DesktopPointerOptions): Promise<void> {\n const button = options?.button ?? \"left\";\n await this.moveIfRequested(options?.x, options?.y);\n this.buttonMask &= ~buttonMask(button);\n await sendPointerEvent(\n this.transport,\n this.buttonMask,\n this.pointerX,\n this.pointerY,\n );\n }\n\n async click(options?: DesktopPointerOptions): Promise<void> {\n await this.mousePress(options);\n await this.mouseRelease({ button: options?.button ?? \"left\" });\n }\n\n async doubleClick(options?: DesktopDoubleClickOptions): Promise<void> {\n const button = options?.button ?? \"left\";\n const delayMs = options?.delayMs ?? 50;\n validateNonNegativeInteger(delayMs, \"double click delay\");\n\n await this.click({ button, x: options?.x, y: options?.y });\n if (delayMs > 0) {\n await new Promise((resolve) => setTimeout(resolve, delayMs));\n }\n await this.click({ button });\n }\n\n async scroll(steps: number, x?: number, y?: number): Promise<void> {\n const normalizedSteps = validateInteger(steps, \"scroll steps\");\n await this.moveIfRequested(x, y);\n\n if (normalizedSteps === 0) {\n return;\n }\n\n const wheelMask =\n normalizedSteps > 0 ? BUTTON_SCROLL_UP_MASK : BUTTON_SCROLL_DOWN_MASK;\n const stepCount = Math.abs(normalizedSteps);\n for (let index = 0; index < stepCount; index += 1) {\n await sendPointerEvent(\n this.transport,\n this.buttonMask | wheelMask,\n this.pointerX,\n this.pointerY,\n );\n await sendPointerEvent(\n this.transport,\n this.buttonMask,\n this.pointerX,\n this.pointerY,\n );\n }\n }\n\n async keyDown(key: string): Promise<void> {\n await sendKeyEvent(this.transport, true, keysymFromKeyName(key));\n }\n\n async keyUp(key: string): Promise<void> {\n await sendKeyEvent(this.transport, false, keysymFromKeyName(key));\n }\n\n async press(keys: string | string[]): Promise<void> {\n const parts = Array.isArray(keys) ? keys : [keys];\n if (parts.length === 0) {\n throw new SandboxError(\"desktop press requires at least one key\");\n }\n\n const keysyms = parts.map((part) => keysymFromKeyName(part));\n if (keysyms.length === 1) {\n await sendKeyEvent(this.transport, true, keysyms[0]);\n await sendKeyEvent(this.transport, false, keysyms[0]);\n return;\n }\n\n for (const keysym of keysyms.slice(0, -1)) {\n await sendKeyEvent(this.transport, true, keysym);\n }\n\n const last = keysyms[keysyms.length - 1];\n await sendKeyEvent(this.transport, true, last);\n await sendKeyEvent(this.transport, false, last);\n\n for (const keysym of keysyms.slice(0, -1).reverse()) {\n await sendKeyEvent(this.transport, false, keysym);\n }\n }\n\n async typeText(text: string): Promise<void> {\n for (const char of text) {\n const keysym = keysymFromChar(char);\n await sendKeyEvent(this.transport, true, keysym);\n await sendKeyEvent(this.transport, false, keysym);\n }\n }\n\n private async moveIfRequested(x?: number, y?: number): Promise<void> {\n if (x == null && y == null) {\n return;\n }\n if (x == null || y == null) {\n throw new SandboxError(\n \"desktop pointer actions require both x and y when specifying coordinates\",\n );\n }\n await this.moveMouse(x, y);\n }\n\n private ensurePointerInBounds(x: number, y: number): void {\n if (this.width > 0 && x >= this.width) {\n throw new SandboxError(\n `mouse x coordinate ${x} is outside desktop width ${this.width}`,\n );\n }\n if (this.height > 0 && y >= this.height) {\n throw new SandboxError(\n `mouse y coordinate ${y} is outside desktop height ${this.height}`,\n );\n }\n }\n\n private startFramebufferUpdates(): void {\n if (this.updateLoopPromise) {\n return;\n }\n\n this.updateLoopPromise = this.runFramebufferUpdateLoop().catch((error: unknown) => {\n if (this.closed) {\n return;\n }\n this.updateLoopError = normalizeError(error);\n this.updateSignal.resolve();\n });\n }\n\n private async runFramebufferUpdateLoop(): Promise<void> {\n let incremental = false;\n\n while (!this.closed) {\n await sendFramebufferUpdateRequest(\n this.transport,\n incremental,\n 0,\n 0,\n this.width,\n this.height,\n );\n\n const outcome = await this.readUntilFramebufferUpdate();\n if (outcome.sawResize && !outcome.sawRaw) {\n incremental = false;\n continue;\n }\n\n if (outcome.sawRaw) {\n this.framebufferVersion += 1;\n this.updateSignal.resolve();\n }\n\n incremental = true;\n }\n }\n\n private async readUntilFramebufferUpdate(): Promise<FramebufferUpdateOutcome> {\n while (true) {\n const outcome = await this.readServerMessage();\n if (outcome.kind === \"framebufferUpdate\") {\n return outcome;\n }\n }\n }\n\n private async waitForFramebufferVersion(\n minimumVersion: number,\n timeoutSeconds: number,\n timeoutMessage: string,\n ): Promise<void> {\n const timeoutMs = secondsToMillis(timeoutSeconds);\n const deadline = Date.now() + timeoutMs;\n\n while (this.framebufferVersion < minimumVersion) {\n if (this.updateLoopError) {\n throw this.updateLoopError;\n }\n if (this.closed) {\n throw new SandboxError(\"desktop session is closed\");\n }\n\n const observedVersion = this.framebufferVersion;\n const waitForUpdate = this.updateSignal.wait();\n if (this.framebufferVersion !== observedVersion) {\n continue;\n }\n\n const remainingMs = Math.max(0, deadline - Date.now());\n if (remainingMs === 0) {\n break;\n }\n\n await withTimeout(remainingMs, () => waitForUpdate, timeoutMessage);\n }\n\n if (this.framebufferVersion < minimumVersion) {\n throw new SandboxError(timeoutMessage);\n }\n }\n\n private async readServerMessage(): Promise<ServerMessageOutcome> {\n const messageType = await readU8(this.transport);\n if (messageType === 0) {\n return this.readFramebufferUpdate();\n }\n if (messageType === 1) {\n await this.readSetColorMapEntries();\n return { kind: \"bell\" };\n }\n if (messageType === 2) {\n return { kind: \"bell\" };\n }\n if (messageType === 3) {\n await this.readServerCutText();\n return { kind: \"serverCutText\" };\n }\n throw new SandboxError(`unsupported VNC server message type ${messageType}`);\n }\n\n private async readFramebufferUpdate(): Promise<FramebufferUpdateOutcome> {\n await readU8(this.transport);\n const rectangleCount = await readU16(this.transport);\n let sawResize = false;\n let sawRaw = false;\n\n for (let index = 0; index < rectangleCount; index += 1) {\n const x = await readU16(this.transport);\n const y = await readU16(this.transport);\n const width = await readU16(this.transport);\n const height = await readU16(this.transport);\n const encoding = await readI32(this.transport);\n\n if (encoding === ENCODING_RAW) {\n const bytesPerPixel = this.pixelFormat.bytesPerPixel();\n const length = width * height * bytesPerPixel;\n const data = await this.transport.readExactly(length);\n this.blitRawRectangle(x, y, width, height, data);\n sawRaw = true;\n continue;\n }\n\n if (encoding === ENCODING_DESKTOP_SIZE) {\n this.resizeFramebuffer(width, height);\n sawResize = true;\n continue;\n }\n\n throw new SandboxError(`unsupported VNC rectangle encoding ${encoding}`);\n }\n\n return { kind: \"framebufferUpdate\", sawResize, sawRaw };\n }\n\n private async readSetColorMapEntries(): Promise<void> {\n await readU8(this.transport);\n await readU16(this.transport);\n const colorCount = await readU16(this.transport);\n await this.transport.readExactly(colorCount * 6);\n throw new SandboxError(\n \"desktop sessions do not support color-map VNC pixel formats\",\n );\n }\n\n private async readServerCutText(): Promise<void> {\n await this.transport.readExactly(3);\n const length = await readU32(this.transport);\n await this.transport.readExactly(length);\n }\n\n private resizeFramebuffer(width: number, height: number): void {\n this.width = width;\n this.height = height;\n this.framebuffer = allocateFramebuffer(width, height);\n this.pointerX = width > 0 ? Math.min(this.pointerX, width - 1) : 0;\n this.pointerY = height > 0 ? Math.min(this.pointerY, height - 1) : 0;\n }\n\n private blitRawRectangle(\n x: number,\n y: number,\n width: number,\n height: number,\n data: Uint8Array,\n ): void {\n if (x + width > this.width || y + height > this.height) {\n throw new SandboxError(\"desktop raw rectangle exceeds framebuffer bounds\");\n }\n\n const bytesPerPixel = this.pixelFormat.bytesPerPixel();\n for (let row = 0; row < height; row += 1) {\n for (let col = 0; col < width; col += 1) {\n const srcIndex = (row * width + col) * bytesPerPixel;\n const rgba = this.pixelFormat.decodePixel(\n data.subarray(srcIndex, srcIndex + bytesPerPixel),\n );\n const dstIndex = ((y + row) * this.width + x + col) * 4;\n this.framebuffer.set(rgba, dstIndex);\n }\n }\n }\n}\n\nexport class Desktop {\n private session: DesktopSession<TunnelByteStream>;\n private readonly connectRequest: DesktopConnectRequest & {\n port: number;\n shared: boolean;\n connectTimeout: number;\n };\n private operationChain: Promise<void> = Promise.resolve();\n private reconnectPromise: Promise<void> | null = null;\n private closed = false;\n\n private constructor(\n session: DesktopSession<TunnelByteStream>,\n connectRequest: DesktopConnectRequest & {\n port: number;\n shared: boolean;\n connectTimeout: number;\n },\n ) {\n this.session = session;\n this.connectRequest = connectRequest;\n }\n\n static async connect(options: DesktopConnectRequest): Promise<Desktop> {\n const connectRequest = normalizeDesktopConnectRequest(options);\n const session = await openDesktopSession(connectRequest);\n return new Desktop(session, connectRequest);\n }\n\n get width(): number {\n return this.session.width;\n }\n\n get height(): number {\n return this.session.height;\n }\n\n async close(): Promise<void> {\n this.closed = true;\n await this.enqueue(() => this.session.close());\n }\n\n async screenshot(timeout = 5): Promise<Uint8Array> {\n return this.enqueue(() => this.captureScreenshot(timeout));\n }\n\n getFrameVersion(): number {\n return this.session.getFrameVersion();\n }\n\n async screenshotAfter(frameVersion: number, timeout = 1): Promise<Uint8Array> {\n return this.enqueue(() => this.captureScreenshotAfter(frameVersion, timeout));\n }\n\n async moveMouse(x: number, y: number): Promise<void> {\n await this.enqueue(() => this.session.moveMouse(x, y));\n }\n\n async mousePress(options?: DesktopPointerOptions): Promise<void> {\n await this.enqueue(() => this.session.mousePress(options));\n }\n\n async mouseRelease(options?: DesktopPointerOptions): Promise<void> {\n await this.enqueue(() => this.session.mouseRelease(options));\n }\n\n async click(options?: DesktopPointerOptions): Promise<void> {\n await this.enqueue(() => this.session.click(options));\n }\n\n async doubleClick(options?: DesktopDoubleClickOptions): Promise<void> {\n await this.enqueue(() => this.session.doubleClick(options));\n }\n\n async leftClick(x?: number, y?: number): Promise<void> {\n await this.click({ button: \"left\", x, y });\n }\n\n async middleClick(x?: number, y?: number): Promise<void> {\n await this.click({ button: \"middle\", x, y });\n }\n\n async rightClick(x?: number, y?: number): Promise<void> {\n await this.click({ button: \"right\", x, y });\n }\n\n async scroll(steps: number, x?: number, y?: number): Promise<void> {\n await this.enqueue(() => this.session.scroll(steps, x, y));\n }\n\n async scrollUp(steps = 1, x?: number, y?: number): Promise<void> {\n await this.scroll(Math.abs(steps), x, y);\n }\n\n async scrollDown(steps = 1, x?: number, y?: number): Promise<void> {\n await this.scroll(-Math.abs(steps), x, y);\n }\n\n async keyDown(key: string): Promise<void> {\n await this.enqueue(() => this.session.keyDown(key));\n }\n\n async keyUp(key: string): Promise<void> {\n await this.enqueue(() => this.session.keyUp(key));\n }\n\n async press(keys: string | string[]): Promise<void> {\n await this.enqueue(() => this.session.press(keys));\n }\n\n async typeText(text: string): Promise<void> {\n await this.enqueue(() => this.session.typeText(text));\n }\n\n private enqueue<T>(operation: () => Promise<T>): Promise<T> {\n const run = this.operationChain.catch(() => {}).then(operation);\n this.operationChain = run.then(\n () => undefined,\n () => undefined,\n );\n return run;\n }\n\n private async captureScreenshot(timeout: number): Promise<Uint8Array> {\n try {\n return await this.session.screenshot(timeout);\n } catch (error) {\n if (!isReconnectableDesktopScreenshotError(error) || this.closed) {\n throw error;\n }\n\n await this.reconnect();\n return this.session.screenshot(timeout);\n }\n }\n\n private async captureScreenshotAfter(\n frameVersion: number,\n timeout: number,\n ): Promise<Uint8Array> {\n try {\n return await this.session.screenshotAfter(frameVersion, timeout);\n } catch (error) {\n if (!isReconnectableDesktopScreenshotError(error) || this.closed) {\n throw error;\n }\n\n await this.reconnect();\n return this.session.screenshot(timeout);\n }\n }\n\n private async reconnect(): Promise<void> {\n if (this.reconnectPromise) {\n return this.reconnectPromise;\n }\n\n this.reconnectPromise = this.performReconnect().finally(() => {\n this.reconnectPromise = null;\n });\n return this.reconnectPromise;\n }\n\n private async performReconnect(): Promise<void> {\n const previousSession = this.session;\n await previousSession.close().catch(() => {});\n this.session = await openDesktopSession(this.connectRequest);\n }\n}\n\nclass ProtocolVersion {\n readonly major: number;\n readonly minor: number;\n\n constructor(major: number, minor: number) {\n this.major = major;\n this.minor = minor;\n }\n\n static async read(transport: DesktopTransport): Promise<ProtocolVersion> {\n const raw = await transport.readExactly(12);\n const text = raw.toString(\"ascii\");\n const trimmed = text.endsWith(\"\\n\") ? text.slice(0, -1) : text;\n const match = /^RFB (\\d{3})\\.(\\d{3})$/.exec(trimmed);\n if (!match) {\n throw new SandboxError(`invalid VNC protocol banner \\`${text}\\``);\n }\n return new ProtocolVersion(Number.parseInt(match[1], 10), Number.parseInt(match[2], 10));\n }\n\n negotiated(): ProtocolVersion {\n if (this.major !== 3 || this.minor >= 8) {\n return new ProtocolVersion(3, 8);\n }\n if (this.minor >= 7) {\n return new ProtocolVersion(3, 7);\n }\n return new ProtocolVersion(3, 3);\n }\n\n render(): string {\n return `RFB ${String(this.major).padStart(3, \"0\")}.${String(this.minor).padStart(3, \"0\")}\\n`;\n }\n}\n\nclass PixelFormat {\n readonly bitsPerPixel: number;\n readonly depth: number;\n readonly bigEndian: boolean;\n readonly trueColor: boolean;\n readonly redMax: number;\n readonly greenMax: number;\n readonly blueMax: number;\n readonly redShift: number;\n readonly greenShift: number;\n readonly blueShift: number;\n\n constructor(options: {\n bitsPerPixel: number;\n depth: number;\n bigEndian: boolean;\n trueColor: boolean;\n redMax: number;\n greenMax: number;\n blueMax: number;\n redShift: number;\n greenShift: number;\n blueShift: number;\n }) {\n this.bitsPerPixel = options.bitsPerPixel;\n this.depth = options.depth;\n this.bigEndian = options.bigEndian;\n this.trueColor = options.trueColor;\n this.redMax = options.redMax;\n this.greenMax = options.greenMax;\n this.blueMax = options.blueMax;\n this.redShift = options.redShift;\n this.greenShift = options.greenShift;\n this.blueShift = options.blueShift;\n }\n\n static preferred(): PixelFormat {\n return new PixelFormat({\n bitsPerPixel: 32,\n depth: 24,\n bigEndian: false,\n trueColor: true,\n redMax: 255,\n greenMax: 255,\n blueMax: 255,\n redShift: 16,\n greenShift: 8,\n blueShift: 0,\n });\n }\n\n static parse(bytes: Uint8Array): PixelFormat {\n if (bytes.length !== 16) {\n throw new SandboxError(\"invalid VNC pixel format payload length\");\n }\n return new PixelFormat({\n bitsPerPixel: bytes[0],\n depth: bytes[1],\n bigEndian: bytes[2] !== 0,\n trueColor: bytes[3] !== 0,\n redMax: Buffer.from(bytes.subarray(4, 6)).readUInt16BE(0),\n greenMax: Buffer.from(bytes.subarray(6, 8)).readUInt16BE(0),\n blueMax: Buffer.from(bytes.subarray(8, 10)).readUInt16BE(0),\n redShift: bytes[10],\n greenShift: bytes[11],\n blueShift: bytes[12],\n });\n }\n\n bytesPerPixel(): number {\n return this.bitsPerPixel / 8;\n }\n\n encode(): Uint8Array {\n const bytes = Buffer.alloc(16);\n bytes[0] = this.bitsPerPixel;\n bytes[1] = this.depth;\n bytes[2] = this.bigEndian ? 1 : 0;\n bytes[3] = this.trueColor ? 1 : 0;\n bytes.writeUInt16BE(this.redMax, 4);\n bytes.writeUInt16BE(this.greenMax, 6);\n bytes.writeUInt16BE(this.blueMax, 8);\n bytes[10] = this.redShift;\n bytes[11] = this.greenShift;\n bytes[12] = this.blueShift;\n return bytes;\n }\n\n decodePixel(bytes: Uint8Array): Uint8Array {\n if (bytes.length !== this.bytesPerPixel()) {\n throw new SandboxError(\"desktop pixel buffer has an unexpected size\");\n }\n\n let value = 0;\n if (this.bigEndian) {\n for (const byte of bytes) {\n value = (value << 8) | byte;\n }\n } else {\n for (let index = 0; index < bytes.length; index += 1) {\n value |= bytes[index] << (index * 8);\n }\n }\n\n const red = scaleChannel((value >> this.redShift) & this.redMax, this.redMax);\n const green = scaleChannel(\n (value >> this.greenShift) & this.greenMax,\n this.greenMax,\n );\n const blue = scaleChannel((value >> this.blueShift) & this.blueMax, this.blueMax);\n return Uint8Array.of(red, green, blue, 255);\n }\n}\n\nclass ServerInit {\n readonly width: number;\n readonly height: number;\n readonly pixelFormat: PixelFormat;\n\n constructor(width: number, height: number, pixelFormat: PixelFormat) {\n this.width = width;\n this.height = height;\n this.pixelFormat = pixelFormat;\n }\n\n static async read(transport: DesktopTransport): Promise<ServerInit> {\n const width = await readU16(transport);\n const height = await readU16(transport);\n const pixelFormat = PixelFormat.parse(await transport.readExactly(16));\n const nameLength = await readU32(transport);\n await transport.readExactly(nameLength);\n return new ServerInit(width, height, pixelFormat);\n }\n}\n\nasync function negotiateSecurity(\n transport: DesktopTransport,\n version: ProtocolVersion,\n password?: string,\n): Promise<number> {\n let securityTypes: number[];\n\n if (version.minor === 3) {\n const securityType = await readU32(transport);\n if (securityType === 0) {\n const reasonLength = await readU32(transport);\n const reason = (await transport.readExactly(reasonLength)).toString(\"utf8\");\n throw new SandboxError(`VNC security negotiation failed: ${reason}`);\n }\n securityTypes = [securityType];\n } else {\n const count = await readU8(transport);\n if (count === 0) {\n const reasonLength = await readU32(transport);\n const reason = (await transport.readExactly(reasonLength)).toString(\"utf8\");\n throw new SandboxError(`VNC security negotiation failed: ${reason}`);\n }\n securityTypes = [...(await transport.readExactly(count))];\n }\n\n let selected: number;\n if (password != null && securityTypes.includes(SECURITY_TYPE_VNC_AUTH)) {\n selected = SECURITY_TYPE_VNC_AUTH;\n } else if (securityTypes.includes(SECURITY_TYPE_NONE)) {\n selected = SECURITY_TYPE_NONE;\n } else if (securityTypes.includes(SECURITY_TYPE_VNC_AUTH)) {\n throw new SandboxError(\n \"VNC server requires password authentication but no password was provided\",\n );\n } else {\n throw new SandboxError(\n `unsupported VNC security types advertised by server: [${securityTypes.join(\", \")}]`,\n );\n }\n\n if (version.minor >= 7) {\n await transport.writeAll(Uint8Array.of(selected));\n }\n\n if (selected === SECURITY_TYPE_VNC_AUTH) {\n if (password == null) {\n throw new SandboxError(\n \"VNC server requires password authentication but no password was provided\",\n );\n }\n const challenge = await transport.readExactly(16);\n const response = encryptVncChallenge(Buffer.from(password, \"utf8\"), challenge);\n await transport.writeAll(response);\n await readSecurityResult(transport, version.minor >= 8);\n } else if (version.minor >= 8) {\n await readSecurityResult(transport, true);\n }\n\n return selected;\n}\n\nfunction encryptVncChallenge(password: Uint8Array, challenge: Uint8Array): Uint8Array {\n if (challenge.length !== 16) {\n throw new SandboxError(\"VNC authentication challenge must be 16 bytes\");\n }\n\n const key = Buffer.alloc(8);\n for (let index = 0; index < Math.min(password.length, 8); index += 1) {\n key[index] = reverseBits(password[index]);\n }\n\n const roundKeys = buildDesRoundKeys(key);\n const output = Buffer.alloc(16);\n for (let blockIndex = 0; blockIndex < 2; blockIndex += 1) {\n const start = blockIndex * 8;\n const encrypted = encryptDesBlock(challenge.subarray(start, start + 8), roundKeys);\n output.set(encrypted, start);\n }\n return output;\n}\n\nfunction reverseBits(value: number): number {\n let reversed = 0;\n for (let bit = 0; bit < 8; bit += 1) {\n reversed |= ((value >> bit) & 1) << (7 - bit);\n }\n return reversed;\n}\n\nasync function readSecurityResult(\n transport: DesktopTransport,\n hasReasonString: boolean,\n): Promise<void> {\n const status = await readU32(transport);\n if (status === 0) {\n return;\n }\n\n let reason: string;\n if (hasReasonString) {\n const reasonLength = await readU32(transport);\n reason = (await transport.readExactly(reasonLength)).toString(\"utf8\");\n } else if (status === 1) {\n reason = \"authentication failed\";\n } else {\n reason = `security handshake failed with status ${status}`;\n }\n\n throw new SandboxError(`VNC security negotiation failed: ${reason}`);\n}\n\nasync function sendSetPixelFormat(\n transport: DesktopTransport,\n pixelFormat: PixelFormat,\n): Promise<void> {\n const message = Buffer.alloc(20);\n message[0] = 0;\n message.set(pixelFormat.encode(), 4);\n await transport.writeAll(message);\n}\n\nasync function sendSetEncodings(\n transport: DesktopTransport,\n encodings: number[],\n): Promise<void> {\n const message = Buffer.alloc(4 + encodings.length * 4);\n message[0] = 2;\n message.writeUInt16BE(encodings.length, 2);\n for (let index = 0; index < encodings.length; index += 1) {\n message.writeInt32BE(encodings[index], 4 + index * 4);\n }\n await transport.writeAll(message);\n}\n\nasync function sendFramebufferUpdateRequest(\n transport: DesktopTransport,\n incremental: boolean,\n x: number,\n y: number,\n width: number,\n height: number,\n): Promise<void> {\n const message = Buffer.alloc(10);\n message[0] = 3;\n message[1] = incremental ? 1 : 0;\n message.writeUInt16BE(x, 2);\n message.writeUInt16BE(y, 4);\n message.writeUInt16BE(width, 6);\n message.writeUInt16BE(height, 8);\n await transport.writeAll(message);\n}\n\nasync function sendPointerEvent(\n transport: DesktopTransport,\n buttonMask: number,\n x: number,\n y: number,\n): Promise<void> {\n const message = Buffer.alloc(6);\n message[0] = 5;\n message[1] = buttonMask;\n message.writeUInt16BE(x, 2);\n message.writeUInt16BE(y, 4);\n await transport.writeAll(message);\n}\n\nasync function sendKeyEvent(\n transport: DesktopTransport,\n down: boolean,\n keysym: number,\n): Promise<void> {\n const message = Buffer.alloc(8);\n message[0] = 4;\n message[1] = down ? 1 : 0;\n message.writeUInt32BE(keysym, 4);\n await transport.writeAll(message);\n}\n\nasync function readU8(transport: DesktopTransport): Promise<number> {\n return (await transport.readExactly(1))[0];\n}\n\nasync function readU16(transport: DesktopTransport): Promise<number> {\n return (await transport.readExactly(2)).readUInt16BE(0);\n}\n\nasync function readU32(transport: DesktopTransport): Promise<number> {\n return (await transport.readExactly(4)).readUInt32BE(0);\n}\n\nasync function readI32(transport: DesktopTransport): Promise<number> {\n return (await transport.readExactly(4)).readInt32BE(0);\n}\n\nfunction scaleChannel(value: number, max: number): number {\n if (max === 0) {\n throw new SandboxError(\"invalid VNC pixel format with zero channel range\");\n }\n return Math.trunc((value * 255) / max);\n}\n\nfunction allocateFramebuffer(width: number, height: number): Uint8Array {\n return new Uint8Array(width * height * 4);\n}\n\nfunction normalizeDesktopConnectRequest(\n options: DesktopConnectRequest,\n): DesktopConnectRequest & {\n port: number;\n shared: boolean;\n connectTimeout: number;\n} {\n return {\n ...options,\n port: validatePort(options.port ?? 5901, \"desktop port\"),\n shared: options.shared ?? true,\n connectTimeout: options.connectTimeout ?? 10,\n };\n}\n\nasync function openDesktopSession(\n options: DesktopConnectRequest & {\n port: number;\n shared: boolean;\n connectTimeout: number;\n },\n): Promise<DesktopSession<TunnelByteStream>> {\n const connectTimeoutMs = secondsToMillis(options.connectTimeout);\n const state: { transport?: TunnelByteStream } = {};\n\n try {\n return await withTimeout(\n connectTimeoutMs,\n async () => {\n state.transport = await TunnelByteStream.connect({\n baseUrl: options.baseUrl,\n wsHeaders: options.wsHeaders,\n remotePort: options.port,\n connectTimeoutMs,\n });\n return DesktopSession.connect(\n state.transport,\n options.password,\n options.shared,\n );\n },\n `timed out while connecting desktop session after ${options.connectTimeout.toFixed(2)}s`,\n );\n } catch (error) {\n if (state.transport) {\n await state.transport.close().catch(() => {});\n }\n throw error;\n }\n}\n\nfunction isReconnectableDesktopScreenshotError(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n\n const message = error.message.toLowerCase();\n return (\n message.includes(\"desktop tunnel closed unexpectedly\") ||\n message.includes(\"desktop tunnel is not connected\") ||\n message.includes(\"connection closed\") ||\n message.includes(\"econnreset\") ||\n message.includes(\"timed out waiting for initial desktop framebuffer\") ||\n message.includes(\"timed out while connecting tunnel websocket\") ||\n message.includes(\"tunnel websocket closed before opening\") ||\n message.includes(\"tunnel websocket handshake failed\")\n );\n}\n\nfunction createDeferredSignal(): {\n resolve(): void;\n wait(): Promise<void>;\n} {\n let resolveCurrent!: () => void;\n let promise = new Promise<void>((resolve) => {\n resolveCurrent = resolve;\n });\n\n return {\n resolve() {\n resolveCurrent();\n promise = new Promise<void>((resolve) => {\n resolveCurrent = resolve;\n });\n },\n wait() {\n return promise;\n },\n };\n}\n\nfunction normalizeError(error: unknown): Error {\n return error instanceof Error ? error : new SandboxError(String(error));\n}\n\nfunction buttonMask(button: MouseButton | string): number {\n const normalized = button.trim().toLowerCase();\n if (normalized === \"left\") return BUTTON_LEFT_MASK;\n if (normalized === \"middle\") return BUTTON_MIDDLE_MASK;\n if (normalized === \"right\") return BUTTON_RIGHT_MASK;\n throw new SandboxError(\n `unsupported mouse button \\`${button}\\`; expected left, middle, or right`,\n );\n}\n\nfunction keysymFromKeyName(key: string): number {\n const trimmed = key.trim();\n if (trimmed.length === 0) {\n throw new SandboxError(\"desktop key name cannot be empty\");\n }\n\n if ([...trimmed].length === 1) {\n return keysymFromChar(trimmed);\n }\n\n const normalized = trimmed.toLowerCase();\n const special = SPECIAL_KEYSYMS.get(normalized);\n if (special != null) {\n return special;\n }\n\n const functionMatch = /^f([1-9]|1[0-2])$/.exec(normalized);\n if (functionMatch) {\n return 0xffbd + Number.parseInt(functionMatch[1], 10);\n }\n\n throw new SandboxError(`unsupported desktop key \\`${trimmed}\\``);\n}\n\nfunction keysymFromChar(char: string): number {\n const codePoint = char.codePointAt(0);\n if (codePoint == null) {\n throw new SandboxError(\"desktop key name cannot be empty\");\n }\n if (char === \"\\n\" || char === \"\\r\") return 0xff0d;\n if (char === \"\\t\") return 0xff09;\n if (char === \"\\b\") return 0xff08;\n if (codePoint >= 0x20 && codePoint <= 0x7e) return codePoint;\n if (codePoint < 0x20 || (codePoint >= 0x7f && codePoint <= 0x9f)) {\n throw new SandboxError(\n `unsupported control character U+${codePoint.toString(16).toUpperCase().padStart(4, \"0\")} for desktop typing`,\n );\n }\n return 0x0100_0000 | codePoint;\n}\n\nfunction encodePng(width: number, height: number, rgba: Uint8Array): Uint8Array {\n const stride = width * 4;\n const raw = Buffer.alloc((stride + 1) * height);\n for (let row = 0; row < height; row += 1) {\n const srcOffset = row * stride;\n const dstOffset = row * (stride + 1);\n raw[dstOffset] = 0;\n raw.set(rgba.subarray(srcOffset, srcOffset + stride), dstOffset + 1);\n }\n\n const ihdr = Buffer.alloc(13);\n ihdr.writeUInt32BE(width, 0);\n ihdr.writeUInt32BE(height, 4);\n ihdr[8] = 8;\n ihdr[9] = 6;\n ihdr[10] = 0;\n ihdr[11] = 0;\n ihdr[12] = 0;\n\n const idat = deflateSync(raw);\n return Buffer.concat([\n PNG_SIGNATURE,\n pngChunk(\"IHDR\", ihdr),\n pngChunk(\"IDAT\", idat),\n pngChunk(\"IEND\", Buffer.alloc(0)),\n ]);\n}\n\nfunction pngChunk(type: string, data: Buffer): Buffer {\n const chunkType = Buffer.from(type, \"ascii\");\n const length = Buffer.alloc(4);\n length.writeUInt32BE(data.length, 0);\n const crc = Buffer.alloc(4);\n crc.writeUInt32BE(crc32(Buffer.concat([chunkType, data])), 0);\n return Buffer.concat([length, chunkType, data, crc]);\n}\n\nfunction crc32(data: Uint8Array): number {\n let crc = 0xffff_ffff;\n for (const byte of data) {\n crc = CRC32_TABLE[(crc ^ byte) & 0xff] ^ (crc >>> 8);\n }\n return (crc ^ 0xffff_ffff) >>> 0;\n}\n\nfunction buildCrc32Table(): Uint32Array {\n const table = new Uint32Array(256);\n for (let index = 0; index < 256; index += 1) {\n let value = index;\n for (let bit = 0; bit < 8; bit += 1) {\n value = (value & 1) !== 0 ? 0xedb8_8320 ^ (value >>> 1) : value >>> 1;\n }\n table[index] = value >>> 0;\n }\n return table;\n}\n\nfunction validateCoordinate(value: number, label: string): number {\n return validateIntegerInRange(value, label, 0, 0xffff);\n}\n\nfunction validatePort(value: number, label: string): number {\n return validateIntegerInRange(value, label, 1, 65535);\n}\n\nfunction validateIntegerInRange(\n value: number,\n label: string,\n min: number,\n max: number,\n): number {\n if (!Number.isInteger(value) || value < min || value > max) {\n throw new SandboxError(`${label} must be an integer between ${min} and ${max}, got ${value}`);\n }\n return value;\n}\n\nfunction validateInteger(value: number, label: string): number {\n if (!Number.isInteger(value)) {\n throw new SandboxError(`${label} must be an integer, got ${value}`);\n }\n return value;\n}\n\nfunction validateNonNegativeInteger(value: number, label: string): number {\n if (!Number.isInteger(value) || value < 0) {\n throw new SandboxError(`${label} must be a non-negative integer, got ${value}`);\n }\n return value;\n}\n\nfunction secondsToMillis(seconds: number): number {\n if (!Number.isFinite(seconds) || seconds < 0) {\n throw new SandboxError(`timeout must be >= 0 seconds, got ${seconds}`);\n }\n return Math.round(seconds * 1000);\n}\n\nconst SPECIAL_KEYSYMS = new Map<string, number>([\n [\"enter\", 0xff0d],\n [\"tab\", 0xff09],\n [\"escape\", 0xff1b],\n [\"backspace\", 0xff08],\n [\"delete\", 0xffff],\n [\"space\", 0x0020],\n [\"up\", 0xff52],\n [\"down\", 0xff54],\n [\"left\", 0xff51],\n [\"right\", 0xff53],\n [\"home\", 0xff50],\n [\"end\", 0xff57],\n [\"pageup\", 0xff55],\n [\"pagedown\", 0xff56],\n [\"page_up\", 0xff55],\n [\"page_down\", 0xff56],\n [\"shift\", 0xffe1],\n [\"ctrl\", 0xffe3],\n [\"control\", 0xffe3],\n [\"alt\", 0xffe9],\n [\"meta\", 0xffe7],\n]);\n\nconst DES_INITIAL_PERMUTATION = [\n 58, 50, 42, 34, 26, 18, 10, 2,\n 60, 52, 44, 36, 28, 20, 12, 4,\n 62, 54, 46, 38, 30, 22, 14, 6,\n 64, 56, 48, 40, 32, 24, 16, 8,\n 57, 49, 41, 33, 25, 17, 9, 1,\n 59, 51, 43, 35, 27, 19, 11, 3,\n 61, 53, 45, 37, 29, 21, 13, 5,\n 63, 55, 47, 39, 31, 23, 15, 7,\n];\n\nconst DES_FINAL_PERMUTATION = [\n 40, 8, 48, 16, 56, 24, 64, 32,\n 39, 7, 47, 15, 55, 23, 63, 31,\n 38, 6, 46, 14, 54, 22, 62, 30,\n 37, 5, 45, 13, 53, 21, 61, 29,\n 36, 4, 44, 12, 52, 20, 60, 28,\n 35, 3, 43, 11, 51, 19, 59, 27,\n 34, 2, 42, 10, 50, 18, 58, 26,\n 33, 1, 41, 9, 49, 17, 57, 25,\n];\n\nconst DES_EXPANSION = [\n 32, 1, 2, 3, 4, 5,\n 4, 5, 6, 7, 8, 9,\n 8, 9, 10, 11, 12, 13,\n 12, 13, 14, 15, 16, 17,\n 16, 17, 18, 19, 20, 21,\n 20, 21, 22, 23, 24, 25,\n 24, 25, 26, 27, 28, 29,\n 28, 29, 30, 31, 32, 1,\n];\n\nconst DES_P_PERMUTATION = [\n 16, 7, 20, 21,\n 29, 12, 28, 17,\n 1, 15, 23, 26,\n 5, 18, 31, 10,\n 2, 8, 24, 14,\n 32, 27, 3, 9,\n 19, 13, 30, 6,\n 22, 11, 4, 25,\n];\n\nconst DES_PC1 = [\n 57, 49, 41, 33, 25, 17, 9,\n 1, 58, 50, 42, 34, 26, 18,\n 10, 2, 59, 51, 43, 35, 27,\n 19, 11, 3, 60, 52, 44, 36,\n 63, 55, 47, 39, 31, 23, 15,\n 7, 62, 54, 46, 38, 30, 22,\n 14, 6, 61, 53, 45, 37, 29,\n 21, 13, 5, 28, 20, 12, 4,\n];\n\nconst DES_PC2 = [\n 14, 17, 11, 24, 1, 5,\n 3, 28, 15, 6, 21, 10,\n 23, 19, 12, 4, 26, 8,\n 16, 7, 27, 20, 13, 2,\n 41, 52, 31, 37, 47, 55,\n 30, 40, 51, 45, 33, 48,\n 44, 49, 39, 56, 34, 53,\n 46, 42, 50, 36, 29, 32,\n];\n\nconst DES_ROTATIONS = [\n 1, 1, 2, 2, 2, 2, 2, 2,\n 1, 2, 2, 2, 2, 2, 2, 1,\n];\n\nconst DES_SBOXES = [\n [\n 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,\n 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,\n 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,\n 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,\n ],\n [\n 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,\n 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,\n 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,\n 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,\n ],\n [\n 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,\n 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,\n 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,\n 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,\n ],\n [\n 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,\n 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,\n 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,\n 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,\n ],\n [\n 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,\n 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,\n 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,\n 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,\n ],\n [\n 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,\n 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,\n 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,\n 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,\n ],\n [\n 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,\n 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,\n 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,\n 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,\n ],\n [\n 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,\n 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,\n 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,\n 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11,\n ],\n];\n\nfunction buildDesRoundKeys(key: Uint8Array): bigint[] {\n const keyBlock = bytesToBigInt(key);\n const permuted = permuteBits(keyBlock, DES_PC1, 64);\n let c = Number((permuted >> 28n) & 0x0fff_ffffn);\n let d = Number(permuted & 0x0fff_ffffn);\n\n const roundKeys: bigint[] = [];\n for (const rotation of DES_ROTATIONS) {\n c = rotateLeft28(c, rotation);\n d = rotateLeft28(d, rotation);\n const combined = (BigInt(c) << 28n) | BigInt(d);\n roundKeys.push(permuteBits(combined, DES_PC2, 56));\n }\n return roundKeys;\n}\n\nfunction encryptDesBlock(block: Uint8Array, roundKeys: bigint[]): Uint8Array {\n let value = permuteBits(bytesToBigInt(block), DES_INITIAL_PERMUTATION, 64);\n let left = Number((value >> 32n) & 0xffff_ffffn);\n let right = Number(value & 0xffff_ffffn);\n\n for (const roundKey of roundKeys) {\n const nextLeft = right;\n const nextRight = (left ^ feistel(right, roundKey)) >>> 0;\n left = nextLeft >>> 0;\n right = nextRight;\n }\n\n value = (BigInt(right) << 32n) | BigInt(left);\n return bigIntToBytes(permuteBits(value, DES_FINAL_PERMUTATION, 64), 8);\n}\n\nfunction feistel(right: number, roundKey: bigint): number {\n const expanded = permuteBits(BigInt(right >>> 0), DES_EXPANSION, 32) ^ roundKey;\n let output = 0;\n for (let index = 0; index < 8; index += 1) {\n const shift = BigInt((7 - index) * 6);\n const chunk = Number((expanded >> shift) & 0x3fn);\n const row = ((chunk & 0x20) >> 4) | (chunk & 0x01);\n const column = (chunk >> 1) & 0x0f;\n output = (output << 4) | DES_SBOXES[index][row * 16 + column];\n }\n return Number(permuteBits(BigInt(output >>> 0), DES_P_PERMUTATION, 32)) >>> 0;\n}\n\nfunction rotateLeft28(value: number, shift: number): number {\n const masked = value & 0x0fff_ffff;\n return ((masked << shift) | (masked >>> (28 - shift))) & 0x0fff_ffff;\n}\n\nfunction permuteBits(input: bigint, table: number[], inputBits: number): bigint {\n let output = 0n;\n for (const position of table) {\n const shift = BigInt(inputBits - position);\n output = (output << 1n) | ((input >> shift) & 1n);\n }\n return output;\n}\n\nfunction bytesToBigInt(bytes: Uint8Array): bigint {\n let value = 0n;\n for (const byte of bytes) {\n value = (value << 8n) | BigInt(byte);\n }\n return value;\n}\n\nfunction bigIntToBytes(value: bigint, length: number): Uint8Array {\n const out = Buffer.alloc(length);\n let remaining = value;\n for (let index = length - 1; index >= 0; index -= 1) {\n out[index] = Number(remaining & 0xffn);\n remaining >>= 8n;\n }\n return out;\n}\n","export interface SSEMessage {\n data: string;\n event?: string;\n id?: string;\n}\n\n/**\n * Parse a Server-Sent Events stream into raw SSE messages.\n */\nexport async function* parseSSEMessages(\n stream: ReadableStream<Uint8Array>,\n signal?: AbortSignal,\n): AsyncIterable<SSEMessage> {\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n try {\n while (true) {\n if (signal?.aborted) break;\n\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const parts = buffer.split(/\\r?\\n\\r?\\n/);\n buffer = parts.pop() ?? \"\";\n\n for (const part of parts) {\n const lines = part.split(/\\r?\\n/);\n const dataLines: string[] = [];\n let event: string | undefined;\n let id: string | undefined;\n\n for (const line of lines) {\n if (!line || line.startsWith(\":\")) continue;\n\n const separator = line.indexOf(\":\");\n const field = separator === -1 ? line : line.slice(0, separator);\n let value = separator === -1 ? \"\" : line.slice(separator + 1);\n if (value.startsWith(\" \")) {\n value = value.slice(1);\n }\n\n if (field === \"data\") {\n dataLines.push(value);\n } else if (field === \"event\") {\n event = value;\n } else if (field === \"id\") {\n id = value;\n }\n }\n\n if (dataLines.length > 0 || event || id) {\n yield { data: dataLines.join(\"\\n\"), event, id };\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n\n/**\n * Parse a Server-Sent Events stream from a ReadableStream<Uint8Array>.\n *\n * Yields parsed JSON objects for each `data:` line. Handles reconnection\n * by simply yielding events as they arrive.\n */\nexport async function* parseSSEStream<T>(\n stream: ReadableStream<Uint8Array>,\n signal?: AbortSignal,\n): AsyncIterable<T> {\n for await (const message of parseSSEMessages(stream, signal)) {\n if (!message.data) continue;\n try {\n yield JSON.parse(message.data) as T;\n } catch {\n // Skip malformed JSON\n }\n }\n}\n","import * as defaults from \"./defaults.js\";\n\n/** Remove a trailing slash from a URL string if present. */\nfunction trimTrailingSlashes(url: string): string {\n return url.endsWith(\"/\") ? url.slice(0, -1) : url;\n}\n\n/** Check whether a URL points to localhost. */\nexport function isLocalhost(apiUrl: string): boolean {\n try {\n const parsed = new URL(apiUrl);\n return parsed.hostname === \"localhost\" || parsed.hostname === \"127.0.0.1\";\n } catch {\n return false;\n }\n}\n\n/**\n * Derive the sandbox proxy URL from the API URL.\n *\n * Priority:\n * 1. TENSORLAKE_SANDBOX_PROXY_URL env var\n * 2. `http://localhost:9443` for localhost API URLs\n * 3. Transform `api.X` → `sandbox.X`\n * 4. Default fallback\n */\nexport function resolveProxyUrl(apiUrl: string): string {\n const explicit = process.env.TENSORLAKE_SANDBOX_PROXY_URL;\n if (explicit) return explicit;\n\n if (isLocalhost(apiUrl)) return \"http://localhost:9443\";\n\n try {\n const parsed = new URL(apiUrl);\n const host = parsed.hostname;\n if (host.startsWith(\"api.\")) {\n const proxyHost = \"sandbox.\" + host.slice(4);\n return `${parsed.protocol}//${proxyHost}`;\n }\n } catch {\n // fall through to default\n }\n\n return defaults.SANDBOX_PROXY_URL;\n}\n\n/**\n * Resolve the proxy target for a specific sandbox.\n *\n * - Localhost: base URL stays the same, Host header set to `{sandboxId}.local`\n * - Cloud: sandbox ID becomes a subdomain of the proxy host\n *\n * Returns `{ baseUrl, hostHeader }`.\n */\nexport function resolveProxyTarget(\n proxyUrl: string,\n sandboxId: string,\n): { baseUrl: string; hostHeader: string | undefined } {\n try {\n const parsed = new URL(proxyUrl);\n const host = parsed.hostname;\n\n if (host === \"localhost\" || host === \"127.0.0.1\") {\n return {\n baseUrl: trimTrailingSlashes(proxyUrl),\n hostHeader: `${sandboxId}.local`,\n };\n }\n\n const port = parsed.port ? `:${parsed.port}` : \"\";\n return {\n baseUrl: `${parsed.protocol}//${sandboxId}.${host}${port}`,\n hostHeader: undefined,\n };\n } catch {\n return {\n baseUrl: `${trimTrailingSlashes(proxyUrl)}/${sandboxId}`,\n hostHeader: undefined,\n };\n }\n}\n\n/**\n * Build a lifecycle API path.\n *\n * - Localhost (namespaced): `/v1/namespaces/{namespace}/{path}`\n * - Cloud (flat): `/{path}`\n */\nexport function lifecyclePath(\n path: string,\n isLocal: boolean,\n namespace: string,\n): string {\n if (isLocal) {\n return `/v1/namespaces/${namespace}/${path}`;\n }\n return `/${path}`;\n}\n","import type { SandboxClient } from \"./client.js\";\nimport {\n type ConnectDesktopOptions,\n Desktop,\n} from \"./desktop.js\";\nimport * as defaults from \"./defaults.js\";\nimport { SandboxError } from \"./errors.js\";\nimport { type Traced, HttpClient } from \"./http.js\";\nimport {\n type CheckpointOptions,\n type CommandResult,\n type ConnectOptions,\n type CreateAndConnectOptions,\n type CreatePtySessionOptions,\n type DaemonInfo,\n type DirectoryEntry,\n type HealthResponse,\n type ListDirectoryResponse,\n type OutputEvent,\n type OutputResponse,\n OutputMode,\n type ProcessInfo,\n type PtySessionInfo,\n type RunOptions,\n type SandboxClientOptions,\n type SandboxInfo,\n type SandboxOptions,\n type SendSignalResponse,\n type SnapshotInfo,\n type StartProcessOptions,\n SandboxStatus,\n SnapshotStatus,\n StdinMode,\n type SuspendResumeOptions,\n type UpdateSandboxOptions,\n fromSnakeKeys,\n} from \"./models.js\";\nimport {\n type CreateTunnelOptions,\n TcpTunnel,\n} from \"./tunnel.js\";\nimport { parseSSEStream } from \"./sse.js\";\nimport { resolveProxyTarget } from \"./url.js\";\nimport WebSocket, { type RawData } from \"ws\";\n\nconst PTY_OP_DATA = 0x00;\nconst PTY_OP_RESIZE = 0x01;\nconst PTY_OP_READY = 0x02;\nconst PTY_OP_EXIT = 0x03;\n\nexport type PtyDataHandler = (data: Uint8Array) => void;\nexport type PtyExitHandler = (exitCode: number) => void;\n\nexport interface PtyConnectionOptions {\n onData?: PtyDataHandler;\n onExit?: PtyExitHandler;\n}\n\nexport interface CreatePtyOptions\n extends CreatePtySessionOptions,\n PtyConnectionOptions {}\n\nexport class Pty {\n readonly sessionId: string;\n readonly token: string;\n\n private readonly wsUrl: string;\n private readonly wsHeaders: Record<string, string>;\n private readonly killSession: () => Promise<void>;\n private socket: WebSocket | null = null;\n private connectPromise: Promise<this> | null = null;\n private intentionalDisconnect = false;\n private exitCode: number | null = null;\n private waitSettled = false;\n private readonly dataHandlers = new Set<PtyDataHandler>();\n private readonly exitHandlers = new Set<PtyExitHandler>();\n private readonly waitPromise: Promise<number>;\n private resolveWait!: (exitCode: number) => void;\n private rejectWait!: (error: unknown) => void;\n\n constructor(options: {\n sessionId: string;\n token: string;\n wsUrl: string;\n wsHeaders: Record<string, string>;\n killSession: () => Promise<void>;\n }) {\n this.sessionId = options.sessionId;\n this.token = options.token;\n this.wsUrl = options.wsUrl;\n this.wsHeaders = options.wsHeaders;\n this.killSession = options.killSession;\n this.waitPromise = new Promise<number>((resolve, reject) => {\n this.resolveWait = resolve;\n this.rejectWait = reject;\n });\n }\n\n onData(handler: PtyDataHandler): () => void {\n this.dataHandlers.add(handler);\n return () => this.dataHandlers.delete(handler);\n }\n\n onExit(handler: PtyExitHandler): () => void {\n this.exitHandlers.add(handler);\n if (this.exitCode != null) {\n queueMicrotask(() => handler(this.exitCode!));\n }\n return () => this.exitHandlers.delete(handler);\n }\n\n async connect(): Promise<this> {\n if (this.socket?.readyState === WebSocket.OPEN) {\n return this;\n }\n if (this.connectPromise) {\n return this.connectPromise;\n }\n\n this.intentionalDisconnect = false;\n\n this.connectPromise = new Promise<this>((resolve, reject) => {\n let opened = false;\n const socket = new WebSocket(this.wsUrl, {\n headers: this.wsHeaders,\n });\n this.socket = socket;\n\n socket.on(\"open\", async () => {\n try {\n await sendPtyFrame(socket, Buffer.from([PTY_OP_READY]));\n opened = true;\n resolve(this);\n } catch (error) {\n reject(error);\n }\n });\n\n socket.on(\"message\", (message: RawData) => {\n const bytes = normalizePtyMessage(message);\n const opcode = bytes[0];\n\n if (opcode === PTY_OP_DATA) {\n const payload = bytes.subarray(1);\n for (const handler of this.dataHandlers) {\n handler(payload);\n }\n return;\n }\n\n if (opcode === PTY_OP_EXIT && bytes.length >= 5) {\n this.finishWait(bytes.readInt32BE(1));\n }\n });\n\n socket.on(\"close\", (code: number, reason: Buffer) => {\n const closeReason = Buffer.isBuffer(reason)\n ? reason.toString(\"utf8\")\n : String(reason);\n\n if (this.socket === socket) {\n this.socket = null;\n }\n this.connectPromise = null;\n\n if (this.exitCode != null) {\n this.finishWait(this.exitCode);\n return;\n }\n\n if (closeReason.startsWith(\"exit:\")) {\n const parsed = Number.parseInt(closeReason.slice(5), 10);\n this.finishWait(Number.isNaN(parsed) ? -1 : parsed);\n return;\n }\n\n if (this.intentionalDisconnect) {\n this.intentionalDisconnect = false;\n return;\n }\n\n if (!opened) {\n reject(new SandboxError(\n `PTY websocket closed before READY completed: ${code} ${closeReason || \"no reason\"}`,\n ));\n return;\n }\n\n if (closeReason === \"session terminated\") {\n this.failWait(new SandboxError(\"PTY session terminated\"));\n return;\n }\n\n this.failWait(\n new SandboxError(\n `PTY websocket closed unexpectedly: ${code} ${closeReason || \"no reason\"}`,\n ),\n );\n });\n\n socket.on(\"error\", (error: Error) => {\n if (!opened) {\n reject(error);\n }\n });\n });\n\n return this.connectPromise;\n }\n\n async sendInput(input: string | Uint8Array): Promise<void> {\n const socket = this.requireOpenSocket();\n await sendPtyFrame(socket, encodePtyInput(input));\n }\n\n async resize(cols: number, rows: number): Promise<void> {\n const socket = this.requireOpenSocket();\n await sendPtyFrame(socket, encodePtyResize(cols, rows));\n }\n\n disconnect(code = 1000, reason = \"client disconnect\"): void {\n if (!this.socket) return;\n this.intentionalDisconnect = true;\n this.socket.close(code, reason);\n }\n\n wait(): Promise<number> {\n return this.waitPromise;\n }\n\n async kill(): Promise<void> {\n await this.killSession();\n }\n\n private requireOpenSocket(): WebSocket {\n if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {\n throw new SandboxError(\"PTY is not connected\");\n }\n return this.socket;\n }\n\n private finishWait(exitCode: number): void {\n if (this.waitSettled) return;\n this.waitSettled = true;\n this.exitCode = exitCode;\n for (const handler of this.exitHandlers) {\n handler(exitCode);\n }\n this.resolveWait(exitCode);\n }\n\n private failWait(error: unknown): void {\n if (this.waitSettled) return;\n this.waitSettled = true;\n this.rejectWait(error);\n }\n}\n\nfunction normalizePtyMessage(message: RawData): Buffer {\n if (Buffer.isBuffer(message)) return message;\n if (Array.isArray(message)) {\n return Buffer.concat(message.map((part) => Buffer.from(part)));\n }\n return Buffer.from(message);\n}\n\nfunction encodePtyInput(input: string | Uint8Array): Buffer {\n const payload =\n typeof input === \"string\" ? Buffer.from(input, \"utf8\") : Buffer.from(input);\n return Buffer.concat([Buffer.from([PTY_OP_DATA]), payload]);\n}\n\nfunction encodePtyResize(cols: number, rows: number): Buffer {\n const frame = Buffer.alloc(5);\n frame[0] = PTY_OP_RESIZE;\n frame.writeUInt16BE(cols, 1);\n frame.writeUInt16BE(rows, 3);\n return frame;\n}\n\nfunction sendPtyFrame(socket: WebSocket, frame: Buffer): Promise<void> {\n return new Promise((resolve, reject) => {\n socket.send(frame, (error?: Error) => (error ? reject(error) : resolve()));\n });\n}\n\n/**\n * Client for interacting with a running sandbox.\n *\n * Provides process management, file operations, and I/O streaming\n * through the sandbox proxy.\n */\nexport class Sandbox {\n readonly sandboxId: string;\n traceId: string | null = null;\n private readonly http: HttpClient;\n private readonly baseUrl: string;\n private readonly wsHeaders: Record<string, string>;\n private ownsSandbox = false;\n private lifecycleClient: SandboxClient | null = null;\n private lifecycleIdentifier: string;\n private sandboxName: string | null = null;\n\n constructor(options: SandboxOptions) {\n this.sandboxId = options.sandboxId;\n this.lifecycleIdentifier = options.sandboxId;\n\n const proxyUrl = options.proxyUrl ?? defaults.SANDBOX_PROXY_URL;\n const { baseUrl, hostHeader } = resolveProxyTarget(proxyUrl, options.sandboxId);\n this.baseUrl = baseUrl;\n this.wsHeaders = {};\n if (options.apiKey) {\n this.wsHeaders.Authorization = `Bearer ${options.apiKey}`;\n }\n if (options.organizationId) {\n this.wsHeaders[\"X-Forwarded-Organization-Id\"] = options.organizationId;\n }\n if (options.projectId) {\n this.wsHeaders[\"X-Forwarded-Project-Id\"] = options.projectId;\n }\n if (hostHeader) {\n this.wsHeaders.Host = hostHeader;\n }\n\n this.http = new HttpClient({\n baseUrl,\n apiKey: options.apiKey,\n organizationId: options.organizationId,\n projectId: options.projectId,\n hostHeader,\n routingHint: options.routingHint,\n });\n }\n\n get name(): string | null {\n return this.sandboxName;\n }\n\n /** @internal Used by client wiring to keep locally cached name in sync. */\n _setName(name: string | null): void {\n this.sandboxName = name;\n }\n\n /** @internal Used by lifecycle operations to pin to canonical sandbox ID. */\n _setLifecycleIdentifier(identifier: string): void {\n this.lifecycleIdentifier = identifier;\n }\n\n /** @internal Used by SandboxClient.createAndConnect to set ownership. */\n _setOwner(client: SandboxClient): void {\n this.ownsSandbox = true;\n this.lifecycleClient = client;\n }\n\n // --- Static factory methods ---\n\n /**\n * Create a new sandbox and return a connected, running handle.\n *\n * Covers both fresh sandbox creation and restore-from-snapshot (set\n * `snapshotId`). Blocks until the sandbox is `Running`.\n */\n static async create(\n options?: CreateAndConnectOptions & Partial<SandboxClientOptions>,\n ): Promise<Sandbox> {\n // Dynamic import to break the circular dependency (client.ts imports Sandbox).\n const { SandboxClient } = await import(\"./client.js\");\n const client = new SandboxClient(options, /* _internal */ true);\n const sandbox = await client.createAndConnect(options);\n sandbox.lifecycleClient = client;\n return sandbox;\n }\n\n /**\n * Attach to an existing sandbox and return a connected handle.\n *\n * Verifies the sandbox exists via a server GET call, then returns a handle\n * in whatever state the sandbox is in. Does **not** auto-resume a suspended\n * sandbox — call `sandbox.resume()` explicitly.\n */\n static async connect(\n options: ConnectOptions & Partial<SandboxClientOptions>,\n ): Promise<Sandbox> {\n const { SandboxClient } = await import(\"./client.js\");\n const client = new SandboxClient(options, /* _internal */ true);\n const info = await client.get(options.sandboxId); // throws SandboxNotFoundError if not found\n const sandbox = client.connect(\n info.sandboxId,\n options.proxyUrl,\n options.routingHint ?? info.routingHint,\n );\n sandbox.lifecycleClient = client;\n sandbox._setLifecycleIdentifier(info.sandboxId);\n sandbox._setName(info.name ?? null);\n return sandbox;\n }\n\n // --- Static snapshot management ---\n\n /** Get information about a snapshot by ID. No sandbox handle needed. */\n static async getSnapshot(\n snapshotId: string,\n options?: Partial<SandboxClientOptions>,\n ): Promise<SnapshotInfo> {\n const { SandboxClient } = await import(\"./client.js\");\n const client = new SandboxClient(options, /* _internal */ true);\n return client.getSnapshot(snapshotId);\n }\n\n /** Delete a snapshot by ID. No sandbox handle needed. */\n static async deleteSnapshot(\n snapshotId: string,\n options?: Partial<SandboxClientOptions>,\n ): Promise<void> {\n const { SandboxClient } = await import(\"./client.js\");\n const client = new SandboxClient(options, /* _internal */ true);\n await client.deleteSnapshot(snapshotId);\n }\n\n // --- Instance lifecycle methods ---\n\n private requireLifecycleClient(operation: string): SandboxClient {\n if (!this.lifecycleClient) {\n throw new SandboxError(\n `Cannot ${operation}: no lifecycle client available. ` +\n \"Use Sandbox.create() or Sandbox.connect() to get a lifecycle-aware handle.\",\n );\n }\n return this.lifecycleClient;\n }\n\n /**\n * Fetch the current sandbox status from the server.\n *\n * Always hits the network — the value is not cached locally because the\n * status changes over the sandbox's lifecycle.\n */\n async status(): Promise<SandboxStatus> {\n const client = this.requireLifecycleClient(\"read_status\");\n const info = await client.get(this.lifecycleIdentifier);\n this._setLifecycleIdentifier(info.sandboxId);\n this._setName(info.name ?? null);\n return info.status;\n }\n\n /**\n * Update this sandbox's properties (name, exposed ports, proxy auth).\n *\n * Naming an ephemeral sandbox makes it non-ephemeral and enables\n * suspend/resume.\n */\n async update(options: UpdateSandboxOptions): Promise<SandboxInfo> {\n const client = this.requireLifecycleClient(\"update\");\n const info = await client.update(this.lifecycleIdentifier, options);\n this._setLifecycleIdentifier(info.sandboxId);\n this._setName(info.name ?? null);\n return info;\n }\n\n /**\n * Suspend this sandbox.\n *\n * By default blocks until the sandbox is fully `Suspended`. Pass\n * `{ wait: false }` for fire-and-return.\n */\n async suspend(options?: SuspendResumeOptions): Promise<void> {\n const client = this.requireLifecycleClient(\"suspend\");\n await client.suspend(this.lifecycleIdentifier, options);\n }\n\n /**\n * Resume this sandbox.\n *\n * By default blocks until the sandbox is `Running` and routable. Pass\n * `{ wait: false }` for fire-and-return.\n */\n async resume(options?: SuspendResumeOptions): Promise<void> {\n const client = this.requireLifecycleClient(\"resume\");\n await client.resume(this.lifecycleIdentifier, options);\n }\n\n /**\n * Create a snapshot of this sandbox's filesystem and wait for it to\n * be committed.\n *\n * By default blocks until the snapshot artifact is ready and returns\n * the completed `SnapshotInfo`. Pass `{ wait: false }` to fire-and-return\n * (returns `undefined`).\n */\n async checkpoint(options?: CheckpointOptions): Promise<SnapshotInfo | undefined> {\n const client = this.requireLifecycleClient(\"checkpoint\");\n if (options?.wait === false) {\n await client.snapshot(this.lifecycleIdentifier, { contentMode: options.contentMode });\n return undefined;\n }\n return client.snapshotAndWait(this.lifecycleIdentifier, {\n timeout: options?.timeout,\n pollInterval: options?.pollInterval,\n contentMode: options?.contentMode,\n });\n }\n\n /**\n * List snapshots taken from this sandbox.\n */\n async listSnapshots(): Promise<Traced<SnapshotInfo[]>> {\n const client = this.requireLifecycleClient(\"listSnapshots\");\n const all = await client.listSnapshots();\n const filtered = all.filter((s) => s.sandboxId === this.lifecycleIdentifier);\n return Object.assign(filtered, { traceId: all.traceId });\n }\n\n /** Close the HTTP client. The sandbox keeps running. */\n close(): void {\n this.http.close();\n }\n\n /** Terminate the sandbox and release all resources. */\n async terminate(): Promise<void> {\n const client = this.lifecycleClient;\n this.ownsSandbox = false;\n this.lifecycleClient = null;\n this.close();\n if (client) {\n await client.delete(this.lifecycleIdentifier);\n }\n }\n\n // --- High-level convenience ---\n\n /**\n * Run a command to completion and return its output.\n *\n * Uses a single streaming `POST /api/v1/processes/run` request that starts\n * the process, streams output, and delivers the exit code over one connection.\n */\n async run(command: string, options?: RunOptions): Promise<CommandResult> {\n const body: Record<string, unknown> = { command };\n if (options?.args) body.args = options.args;\n if (options?.env) body.env = options.env;\n if (options?.workingDir) body.working_dir = options.workingDir;\n if (options?.timeout != null) body.timeout = options.timeout;\n\n const sseStream = await this.http.requestStream(\n \"POST\",\n \"/api/v1/processes/run\",\n { json: body },\n );\n\n const stdoutLines: string[] = [];\n const stderrLines: string[] = [];\n let exitCode = -1;\n\n for await (const raw of parseSSEStream<Record<string, unknown>>(sseStream)) {\n if (typeof raw.line === \"string\") {\n if (raw.stream === \"stderr\") {\n stderrLines.push(raw.line);\n } else {\n stdoutLines.push(raw.line);\n }\n } else if (\"exit_code\" in raw || \"signal\" in raw) {\n if (typeof raw.exit_code === \"number\") {\n exitCode = raw.exit_code;\n } else if (typeof raw.signal === \"number\") {\n exitCode = -raw.signal;\n }\n }\n }\n\n return {\n exitCode,\n stdout: stdoutLines.join(\"\\n\"),\n stderr: stderrLines.join(\"\\n\"),\n };\n }\n\n // --- Process management ---\n\n /**\n * Start a process in the sandbox without waiting for it to exit.\n *\n * Returns a `ProcessInfo` with the assigned `pid`. Use `getProcess()` to\n * poll status, or `followStdout()` / `followOutput()` to stream output\n * until the process exits. Use `run()` instead to block until completion\n * and get combined output in one call.\n */\n async startProcess(\n command: string,\n options?: StartProcessOptions,\n ): Promise<ProcessInfo> {\n const payload: Record<string, unknown> = { command };\n if (options?.args != null) payload.args = options.args;\n if (options?.env != null) payload.env = options.env;\n if (options?.workingDir != null) payload.working_dir = options.workingDir;\n if (options?.stdinMode != null && options.stdinMode !== StdinMode.CLOSED) {\n payload.stdin_mode = options.stdinMode;\n }\n if (options?.stdoutMode != null && options.stdoutMode !== OutputMode.CAPTURE) {\n payload.stdout_mode = options.stdoutMode;\n }\n if (options?.stderrMode != null && options.stderrMode !== OutputMode.CAPTURE) {\n payload.stderr_mode = options.stderrMode;\n }\n\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"POST\",\n \"/api/v1/processes\",\n { body: payload },\n );\n return fromSnakeKeys(raw) as ProcessInfo;\n }\n\n /** List all processes (running and exited) tracked by the sandbox daemon. */\n async listProcesses(): Promise<Traced<ProcessInfo[]>> {\n const raw = await this.http.requestJson<{ processes: Record<string, unknown>[] }>(\n \"GET\",\n \"/api/v1/processes\",\n );\n const processes = (raw.processes ?? []).map((p) => fromSnakeKeys(p) as ProcessInfo);\n return Object.assign(processes, { traceId: raw.traceId });\n }\n\n /** Get current status and metadata for a process by PID. */\n async getProcess(pid: number): Promise<ProcessInfo> {\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"GET\",\n `/api/v1/processes/${pid}`,\n );\n return fromSnakeKeys(raw) as ProcessInfo;\n }\n\n /** Send SIGKILL to a process. */\n async killProcess(pid: number): Promise<void> {\n await this.http.requestJson(\"DELETE\", `/api/v1/processes/${pid}`);\n }\n\n /** Send an arbitrary signal to a process (e.g. `15` for SIGTERM, `9` for SIGKILL). */\n async sendSignal(pid: number, signal: number): Promise<SendSignalResponse> {\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"POST\",\n `/api/v1/processes/${pid}/signal`,\n { body: { signal } },\n );\n return fromSnakeKeys(raw) as SendSignalResponse;\n }\n\n // --- Process I/O ---\n\n /** Write bytes to a process's stdin. The process must have been started with `stdinMode: StdinMode.PIPE`. */\n async writeStdin(pid: number, data: Uint8Array): Promise<void> {\n await this.http.requestBytes(\"POST\", `/api/v1/processes/${pid}/stdin`, {\n body: data,\n contentType: \"application/octet-stream\",\n });\n }\n\n /** Close a process's stdin pipe, signalling EOF to the process. */\n async closeStdin(pid: number): Promise<void> {\n await this.http.requestJson(\"POST\", `/api/v1/processes/${pid}/stdin/close`);\n }\n\n /** Return all captured stdout lines produced so far by a process. */\n async getStdout(pid: number): Promise<OutputResponse> {\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"GET\",\n `/api/v1/processes/${pid}/stdout`,\n );\n return fromSnakeKeys(raw) as OutputResponse;\n }\n\n /** Return all captured stderr lines produced so far by a process. */\n async getStderr(pid: number): Promise<OutputResponse> {\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"GET\",\n `/api/v1/processes/${pid}/stderr`,\n );\n return fromSnakeKeys(raw) as OutputResponse;\n }\n\n /** Return all captured stdout+stderr lines produced so far by a process. */\n async getOutput(pid: number): Promise<OutputResponse> {\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"GET\",\n `/api/v1/processes/${pid}/output`,\n );\n return fromSnakeKeys(raw) as OutputResponse;\n }\n\n // --- Streaming (SSE) ---\n\n /** Stream stdout events from a process until it exits. Yields one `OutputEvent` per line. */\n async *followStdout(\n pid: number,\n options?: { signal?: AbortSignal },\n ): AsyncIterable<OutputEvent> {\n const stream = await this.http.requestStream(\n \"GET\",\n `/api/v1/processes/${pid}/stdout/follow`,\n options,\n );\n for await (const raw of parseSSEStream<Record<string, unknown>>(\n stream,\n options?.signal,\n )) {\n yield fromSnakeKeys(raw) as OutputEvent;\n }\n }\n\n /** Stream stderr events from a process until it exits. Yields one `OutputEvent` per line. */\n async *followStderr(\n pid: number,\n options?: { signal?: AbortSignal },\n ): AsyncIterable<OutputEvent> {\n const stream = await this.http.requestStream(\n \"GET\",\n `/api/v1/processes/${pid}/stderr/follow`,\n options,\n );\n for await (const raw of parseSSEStream<Record<string, unknown>>(\n stream,\n options?.signal,\n )) {\n yield fromSnakeKeys(raw) as OutputEvent;\n }\n }\n\n /** Stream combined stdout+stderr events from a process until it exits. Yields one `OutputEvent` per line. */\n async *followOutput(\n pid: number,\n options?: { signal?: AbortSignal },\n ): AsyncIterable<OutputEvent> {\n const stream = await this.http.requestStream(\n \"GET\",\n `/api/v1/processes/${pid}/output/follow`,\n options,\n );\n for await (const raw of parseSSEStream<Record<string, unknown>>(\n stream,\n options?.signal,\n )) {\n yield fromSnakeKeys(raw) as OutputEvent;\n }\n }\n\n // --- File operations ---\n\n /** Read a file from the sandbox and return its raw bytes. */\n async readFile(path: string): Promise<Uint8Array> {\n return this.http.requestBytes(\n \"GET\",\n `/api/v1/files?path=${encodeURIComponent(path)}`,\n );\n }\n\n /** Write raw bytes to a file in the sandbox, creating it if it does not exist. */\n async writeFile(path: string, content: Uint8Array): Promise<void> {\n await this.http.requestBytes(\n \"PUT\",\n `/api/v1/files?path=${encodeURIComponent(path)}`,\n { body: content, contentType: \"application/octet-stream\" },\n );\n }\n\n /** Delete a file from the sandbox. */\n async deleteFile(path: string): Promise<void> {\n await this.http.requestJson(\n \"DELETE\",\n `/api/v1/files?path=${encodeURIComponent(path)}`,\n );\n }\n\n /** List the contents of a directory in the sandbox. */\n async listDirectory(path: string): Promise<ListDirectoryResponse> {\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"GET\",\n `/api/v1/files/list?path=${encodeURIComponent(path)}`,\n );\n return fromSnakeKeys(raw) as ListDirectoryResponse;\n }\n\n // --- PTY ---\n\n /** Create an interactive PTY session. Returns a `sessionId` and `token` for WebSocket connection via `connectPty()`. */\n async createPtySession(\n options: CreatePtySessionOptions,\n ): Promise<PtySessionInfo> {\n const payload: Record<string, unknown> = {\n command: options.command,\n rows: options.rows ?? 24,\n cols: options.cols ?? 80,\n };\n if (options.args != null) payload.args = options.args;\n if (options.env != null) payload.env = options.env;\n if (options.workingDir != null) payload.working_dir = options.workingDir;\n\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"POST\",\n \"/api/v1/pty\",\n { body: payload },\n );\n return fromSnakeKeys(raw) as PtySessionInfo;\n }\n\n /** Create a PTY session and connect to it immediately. Cleans up the session if the WebSocket connection fails. */\n async createPty(options: CreatePtyOptions): Promise<Pty> {\n const { onData, onExit, ...createOptions } = options;\n const session = await this.createPtySession(createOptions);\n try {\n return await this.connectPty(session.sessionId, session.token, { onData, onExit });\n } catch (error) {\n try {\n await this.http.requestResponse(\"DELETE\", `/api/v1/pty/${session.sessionId}`);\n } catch {}\n throw error;\n }\n }\n\n /** Attach to an existing PTY session by ID and token and return a connected `Pty` handle. */\n async connectPty(\n sessionId: string,\n token: string,\n options?: PtyConnectionOptions,\n ): Promise<Pty> {\n const wsUrl = new URL(this.ptyWsUrl(sessionId, token));\n const authToken = wsUrl.searchParams.get(\"token\") ?? token;\n\n const pty = new Pty({\n sessionId,\n token: authToken,\n wsUrl: wsUrl.toString(),\n wsHeaders: {\n ...this.wsHeaders,\n \"X-PTY-Token\": authToken,\n },\n killSession: async () => {\n await this.http.requestResponse(\"DELETE\", `/api/v1/pty/${sessionId}`);\n },\n });\n\n if (options?.onData) {\n pty.onData(options.onData);\n }\n if (options?.onExit) {\n pty.onExit(options.onExit);\n }\n\n await pty.connect();\n return pty;\n }\n\n /** Open a TCP tunnel to a port inside the sandbox and return the local listener. */\n async createTunnel(\n remotePort: number,\n options?: CreateTunnelOptions,\n ): Promise<TcpTunnel> {\n return TcpTunnel.listen({\n baseUrl: this.baseUrl,\n wsHeaders: this.wsHeaders,\n remotePort,\n localHost: options?.localHost,\n localPort: options?.localPort,\n connectTimeout: options?.connectTimeout,\n });\n }\n\n /** Connect to a sandbox VNC session for programmatic desktop control. */\n async connectDesktop(options?: ConnectDesktopOptions): Promise<Desktop> {\n return Desktop.connect({\n baseUrl: this.baseUrl,\n wsHeaders: this.wsHeaders,\n port: options?.port,\n password: options?.password,\n shared: options?.shared,\n connectTimeout: options?.connectTimeout,\n });\n }\n\n ptyWsUrl(sessionId: string, token: string): string {\n let wsBase: string;\n if (this.baseUrl.startsWith(\"https://\")) {\n wsBase = \"wss://\" + this.baseUrl.slice(8);\n } else if (this.baseUrl.startsWith(\"http://\")) {\n wsBase = \"ws://\" + this.baseUrl.slice(7);\n } else {\n wsBase = this.baseUrl;\n }\n return `${wsBase}/api/v1/pty/${sessionId}/ws?token=${token}`;\n }\n\n // --- Health ---\n\n /** Check the sandbox daemon health. */\n async health(): Promise<HealthResponse> {\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"GET\",\n \"/api/v1/health\",\n );\n return fromSnakeKeys(raw) as HealthResponse;\n }\n\n /** Get sandbox daemon info (version, uptime, process counts). */\n async info(): Promise<DaemonInfo> {\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"GET\",\n \"/api/v1/info\",\n );\n return fromSnakeKeys(raw) as DaemonInfo;\n }\n}\n","import * as defaults from \"./defaults.js\";\nimport { SandboxError } from \"./errors.js\";\nimport { type Traced, HttpClient } from \"./http.js\";\nimport {\n type CheckpointOptions,\n type ConnectOptions,\n type CreateAndConnectOptions,\n type CreatePoolOptions,\n type CreateSandboxOptions,\n type CreateSandboxPoolResponse,\n type CreateSandboxResponse,\n type CreateSnapshotResponse,\n type SandboxClientOptions,\n type SandboxInfo,\n type SandboxPortAccess,\n type SandboxPoolInfo,\n SandboxStatus,\n type SnapshotAndWaitOptions,\n type SnapshotInfo,\n type SnapshotOptions,\n SnapshotStatus,\n type SuspendResumeOptions,\n type UpdatePoolOptions,\n type UpdateSandboxOptions,\n fromSnakeKeys,\n toSnakeKeys,\n} from \"./models.js\";\nimport { Sandbox } from \"./sandbox.js\";\nimport { isLocalhost, lifecyclePath, resolveProxyUrl } from \"./url.js\";\n\n/**\n * Client for managing TensorLake sandboxes, pools, and snapshots.\n *\n * Use `SandboxClient.forCloud()` or `SandboxClient.forLocalhost()` for\n * clearer construction depending on your deployment target.\n */\nexport class SandboxClient {\n private readonly http: HttpClient;\n private readonly apiUrl: string;\n private readonly apiKey: string | undefined;\n private readonly organizationId: string | undefined;\n private readonly projectId: string | undefined;\n private readonly namespace: string;\n private readonly local: boolean;\n\n /** @internal Pass `true` to suppress the deprecation warning when used by `Sandbox.create()` / `Sandbox.connect()`. */\n constructor(options?: SandboxClientOptions, _internal = false) {\n if (!_internal) {\n console.warn(\n \"[tensorlake] SandboxClient is deprecated; use Sandbox.create() / Sandbox.connect() instead.\",\n );\n }\n this.apiUrl = options?.apiUrl ?? defaults.API_URL;\n this.apiKey = options?.apiKey ?? defaults.API_KEY;\n this.organizationId = options?.organizationId;\n this.projectId = options?.projectId;\n this.namespace = options?.namespace ?? defaults.NAMESPACE;\n this.local = isLocalhost(this.apiUrl);\n\n this.http = new HttpClient({\n baseUrl: this.apiUrl,\n apiKey: this.apiKey,\n organizationId: this.organizationId,\n projectId: this.projectId,\n maxRetries: options?.maxRetries ?? defaults.MAX_RETRIES,\n retryBackoffMs: options?.retryBackoffMs ?? defaults.RETRY_BACKOFF_MS,\n });\n }\n\n /** Create a client for the TensorLake cloud platform. */\n static forCloud(options?: {\n apiKey?: string;\n organizationId?: string;\n projectId?: string;\n apiUrl?: string;\n }): SandboxClient {\n return new SandboxClient({\n apiUrl: options?.apiUrl ?? \"https://api.tensorlake.ai\",\n apiKey: options?.apiKey,\n organizationId: options?.organizationId,\n projectId: options?.projectId,\n });\n }\n\n /** Create a client for a local Indexify server. */\n static forLocalhost(options?: {\n apiUrl?: string;\n namespace?: string;\n }): SandboxClient {\n return new SandboxClient({\n apiUrl: options?.apiUrl ?? \"http://localhost:8900\",\n namespace: options?.namespace ?? \"default\",\n });\n }\n\n close(): void {\n this.http.close();\n }\n\n // --- Path helper ---\n\n private path(subpath: string): string {\n return lifecyclePath(subpath, this.local, this.namespace);\n }\n\n // --- Sandbox CRUD ---\n\n /** Create a new sandbox. Returns immediately; the sandbox may still be starting. Use `createAndConnect()` for a blocking, ready-to-use handle. */\n async create(options?: CreateSandboxOptions): Promise<Traced<CreateSandboxResponse>> {\n const body: Record<string, unknown> = {\n resources: {\n cpus: options?.cpus ?? 1.0,\n memory_mb: options?.memoryMb ?? 1024,\n ...(options?.diskMb != null ? { disk_mb: options.diskMb } : {}),\n },\n };\n\n if (options?.image != null) body.image = options.image;\n if (options?.secretNames != null) body.secret_names = options.secretNames;\n if (options?.timeoutSecs != null) body.timeout_secs = options.timeoutSecs;\n if (options?.entrypoint != null) body.entrypoint = options.entrypoint;\n if (options?.snapshotId != null) body.snapshot_id = options.snapshotId;\n if (options?.name != null) body.name = options.name;\n\n if (\n options?.allowInternetAccess === false ||\n options?.allowOut != null ||\n options?.denyOut != null\n ) {\n body.network = {\n allow_internet_access: options?.allowInternetAccess ?? true,\n allow_out: options?.allowOut ?? [],\n deny_out: options?.denyOut ?? [],\n };\n }\n\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"POST\",\n this.path(\"sandboxes\"),\n { body },\n );\n const result = fromSnakeKeys(raw, \"sandboxId\") as CreateSandboxResponse;\n return Object.assign(result, { traceId: raw.traceId }) as Traced<CreateSandboxResponse>;\n }\n\n /** Get current state and metadata for a sandbox by ID. */\n async get(sandboxId: string): Promise<SandboxInfo> {\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"GET\",\n this.path(`sandboxes/${sandboxId}`),\n );\n return fromSnakeKeys(raw, \"sandboxId\") as SandboxInfo;\n }\n\n /** List all sandboxes in the namespace. */\n async list(): Promise<Traced<SandboxInfo[]>> {\n const raw = await this.http.requestJson<{ sandboxes: Record<string, unknown>[] }>(\n \"GET\",\n this.path(\"sandboxes\"),\n );\n const sandboxes = (raw.sandboxes ?? []).map(\n (s) => fromSnakeKeys(s, \"sandboxId\") as SandboxInfo,\n );\n return Object.assign(sandboxes, { traceId: raw.traceId });\n }\n\n /** Update sandbox properties such as name, exposed ports, and proxy auth settings. */\n async update(sandboxId: string, options: UpdateSandboxOptions): Promise<SandboxInfo> {\n const body: Record<string, unknown> = {};\n if (options.name != null) body.name = options.name;\n if (options.allowUnauthenticatedAccess != null) {\n body.allow_unauthenticated_access = options.allowUnauthenticatedAccess;\n }\n if (options.exposedPorts != null) {\n body.exposed_ports = normalizeUserPorts(options.exposedPorts);\n }\n if (Object.keys(body).length === 0) {\n throw new SandboxError(\"At least one sandbox update field must be provided.\");\n }\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"PATCH\",\n this.path(`sandboxes/${sandboxId}`),\n { body },\n );\n return fromSnakeKeys(raw, \"sandboxId\") as SandboxInfo;\n }\n\n /** Get the current proxy port settings for a sandbox. */\n async getPortAccess(sandboxId: string): Promise<SandboxPortAccess> {\n const info = await this.get(sandboxId);\n return {\n allowUnauthenticatedAccess: info.allowUnauthenticatedAccess ?? false,\n exposedPorts: dedupeAndSortPorts(info.exposedPorts ?? []),\n sandboxUrl: info.sandboxUrl,\n };\n }\n\n /** Add one or more user ports to the sandbox proxy allowlist. */\n async exposePorts(\n sandboxId: string,\n ports: number[],\n options?: { allowUnauthenticatedAccess?: boolean },\n ): Promise<SandboxInfo> {\n const requestedPorts = normalizeUserPorts(ports);\n const current = await this.getPortAccess(sandboxId);\n const desiredPorts = dedupeAndSortPorts([\n ...current.exposedPorts,\n ...requestedPorts,\n ]);\n return this.update(sandboxId, {\n allowUnauthenticatedAccess:\n options?.allowUnauthenticatedAccess ??\n current.allowUnauthenticatedAccess,\n exposedPorts: desiredPorts,\n });\n }\n\n /** Remove one or more user ports from the sandbox proxy allowlist. */\n async unexposePorts(\n sandboxId: string,\n ports: number[],\n ): Promise<SandboxInfo> {\n const requestedPorts = normalizeUserPorts(ports);\n const current = await this.getPortAccess(sandboxId);\n const toRemove = new Set(requestedPorts);\n const desiredPorts = current.exposedPorts.filter((port) => !toRemove.has(port));\n return this.update(sandboxId, {\n allowUnauthenticatedAccess: desiredPorts.length\n ? current.allowUnauthenticatedAccess\n : false,\n exposedPorts: desiredPorts,\n });\n }\n\n /** Terminate and delete a sandbox. */\n async delete(sandboxId: string): Promise<void> {\n await this.http.requestJson(\n \"DELETE\",\n this.path(`sandboxes/${sandboxId}`),\n );\n }\n\n /**\n * Suspend a named sandbox, preserving its state for later resume.\n *\n * Only sandboxes created with a `name` can be suspended; ephemeral sandboxes\n * cannot. By default blocks until the sandbox is fully `Suspended`. Pass\n * `{ wait: false }` to return immediately after the request is sent\n * (fire-and-return); the server processes the suspend asynchronously.\n *\n * @param sandboxId - ID or name of the sandbox.\n * @param options.wait - If `true` (default), poll until `Suspended`. Pass `false` to fire-and-return.\n * @param options.timeout - Max seconds to wait when `wait=true` (default 300).\n * @param options.pollInterval - Seconds between status polls when `wait=true` (default 1).\n * @throws {SandboxError} If `wait=true` and the sandbox does not reach `Suspended` within `timeout`.\n */\n async suspend(sandboxId: string, options?: SuspendResumeOptions): Promise<void> {\n await this.http.requestResponse(\n \"POST\",\n this.path(`sandboxes/${sandboxId}/suspend`),\n );\n if (options?.wait === false) return;\n const timeout = options?.timeout ?? 300;\n const pollInterval = options?.pollInterval ?? 1;\n const deadline = Date.now() + timeout * 1000;\n while (Date.now() < deadline) {\n const info = await this.get(sandboxId);\n if (info.status === SandboxStatus.SUSPENDED) return;\n if (info.status === SandboxStatus.TERMINATED) {\n throw new SandboxError(`Sandbox ${sandboxId} terminated while waiting for suspend`);\n }\n await sleep(pollInterval * 1000);\n }\n throw new SandboxError(`Sandbox ${sandboxId} did not suspend within ${timeout}s`);\n }\n\n /**\n * Resume a suspended sandbox and bring it back to `Running`.\n *\n * By default blocks until the sandbox is `Running` and routable. Pass\n * `{ wait: false }` to return immediately after the request is sent\n * (fire-and-return); the server processes the resume asynchronously.\n *\n * @param sandboxId - ID or name of the sandbox.\n * @param options.wait - If `true` (default), poll until `Running`. Pass `false` to fire-and-return.\n * @param options.timeout - Max seconds to wait when `wait=true` (default 300).\n * @param options.pollInterval - Seconds between status polls when `wait=true` (default 1).\n * @throws {SandboxError} If `wait=true` and the sandbox does not reach `Running` within `timeout`.\n */\n async resume(sandboxId: string, options?: SuspendResumeOptions): Promise<void> {\n await this.http.requestResponse(\n \"POST\",\n this.path(`sandboxes/${sandboxId}/resume`),\n );\n if (options?.wait === false) return;\n const timeout = options?.timeout ?? 300;\n const pollInterval = options?.pollInterval ?? 1;\n const deadline = Date.now() + timeout * 1000;\n while (Date.now() < deadline) {\n const info = await this.get(sandboxId);\n if (info.status === SandboxStatus.RUNNING) return;\n if (info.status === SandboxStatus.TERMINATED) {\n throw new SandboxError(`Sandbox ${sandboxId} terminated while waiting for resume`);\n }\n await sleep(pollInterval * 1000);\n }\n throw new SandboxError(`Sandbox ${sandboxId} did not resume within ${timeout}s`);\n }\n\n /** Claim a warm sandbox from a pool, creating one if no warm containers are available. */\n async claim(poolId: string): Promise<Traced<CreateSandboxResponse>> {\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"POST\",\n this.path(`sandbox-pools/${poolId}/sandboxes`),\n );\n const result = fromSnakeKeys(raw, \"sandboxId\") as CreateSandboxResponse;\n return Object.assign(result, { traceId: raw.traceId }) as Traced<CreateSandboxResponse>;\n }\n\n // --- Snapshots ---\n\n /**\n * Request a snapshot of a running sandbox's filesystem.\n *\n * This call **returns immediately** with a `snapshotId` and `in_progress`\n * status — the snapshot is created asynchronously. Poll `getSnapshot()` until\n * `completed` or `failed`, or use `snapshotAndWait()` to block automatically.\n *\n * @param options.contentMode - `\"filesystem_only\"` for cold-boot snapshots (e.g. image builds).\n * Omit to use the server default (full VM snapshot).\n */\n async snapshot(\n sandboxId: string,\n options?: SnapshotOptions,\n ): Promise<CreateSnapshotResponse> {\n // Preserve today's wire shape (no body) when contentMode is not set.\n const requestOptions =\n options?.contentMode != null\n ? { body: { snapshot_content_mode: options.contentMode } }\n : undefined;\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"POST\",\n this.path(`sandboxes/${sandboxId}/snapshot`),\n requestOptions,\n );\n return fromSnakeKeys(raw, \"snapshotId\") as CreateSnapshotResponse;\n }\n\n /** Get current status and metadata for a snapshot by ID. */\n async getSnapshot(snapshotId: string): Promise<SnapshotInfo> {\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"GET\",\n this.path(`snapshots/${snapshotId}`),\n );\n return fromSnakeKeys(raw, \"snapshotId\") as SnapshotInfo;\n }\n\n /** List all snapshots in the namespace. */\n async listSnapshots(): Promise<Traced<SnapshotInfo[]>> {\n const raw = await this.http.requestJson<{ snapshots: Record<string, unknown>[] }>(\n \"GET\",\n this.path(\"snapshots\"),\n );\n const snapshots = (raw.snapshots ?? []).map(\n (s) => fromSnakeKeys(s, \"snapshotId\") as SnapshotInfo,\n );\n return Object.assign(snapshots, { traceId: raw.traceId });\n }\n\n /** Delete a snapshot by ID. */\n async deleteSnapshot(snapshotId: string): Promise<void> {\n await this.http.requestJson(\n \"DELETE\",\n this.path(`snapshots/${snapshotId}`),\n );\n }\n\n /**\n * Create a snapshot and block until it is committed.\n *\n * Combines `snapshot()` with polling `getSnapshot()` until `completed`.\n * Prefer `sandbox.checkpoint()` on a `Sandbox` handle for the same behavior\n * without managing the client separately.\n *\n * @param sandboxId - ID of the running sandbox to snapshot.\n * @param options.timeout - Max seconds to wait (default 300).\n * @param options.pollInterval - Seconds between status polls (default 1).\n * @param options.contentMode - Content mode passed through to `snapshot()`.\n * @throws {SandboxError} If the snapshot fails or `timeout` elapses.\n */\n async snapshotAndWait(\n sandboxId: string,\n options?: SnapshotAndWaitOptions,\n ): Promise<SnapshotInfo> {\n const timeout = options?.timeout ?? 300;\n const pollInterval = options?.pollInterval ?? 1;\n\n const result = await this.snapshot(sandboxId, {\n contentMode: options?.contentMode,\n });\n const deadline = Date.now() + timeout * 1000;\n\n while (Date.now() < deadline) {\n const info = await this.getSnapshot(result.snapshotId);\n if (info.status === SnapshotStatus.COMPLETED) return info;\n if (info.status === SnapshotStatus.FAILED) {\n throw new SandboxError(\n `Snapshot ${result.snapshotId} failed: ${info.error}`,\n );\n }\n await sleep(pollInterval * 1000);\n }\n\n throw new SandboxError(\n `Snapshot ${result.snapshotId} did not complete within ${timeout}s`,\n );\n }\n\n // --- Pools ---\n\n /** Create a new sandbox pool with warm pre-booted containers. */\n async createPool(options: CreatePoolOptions): Promise<CreateSandboxPoolResponse> {\n const body: Record<string, unknown> = {\n image: options.image,\n resources: {\n cpus: options.cpus ?? 1.0,\n memory_mb: options.memoryMb ?? 1024,\n ephemeral_disk_mb: options.ephemeralDiskMb ?? 1024,\n },\n timeout_secs: options.timeoutSecs ?? 0,\n };\n\n if (options.secretNames != null) body.secret_names = options.secretNames;\n if (options.entrypoint != null) body.entrypoint = options.entrypoint;\n if (options.maxContainers != null) body.max_containers = options.maxContainers;\n if (options.warmContainers != null) body.warm_containers = options.warmContainers;\n\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"POST\",\n this.path(\"sandbox-pools\"),\n { body },\n );\n return fromSnakeKeys(raw, \"poolId\") as CreateSandboxPoolResponse;\n }\n\n /** Get current state and metadata for a sandbox pool by ID. */\n async getPool(poolId: string): Promise<SandboxPoolInfo> {\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"GET\",\n this.path(`sandbox-pools/${poolId}`),\n );\n return fromSnakeKeys(raw, \"poolId\") as SandboxPoolInfo;\n }\n\n /** List all sandbox pools in the namespace. */\n async listPools(): Promise<Traced<SandboxPoolInfo[]>> {\n const raw = await this.http.requestJson<{ pools: Record<string, unknown>[] }>(\n \"GET\",\n this.path(\"sandbox-pools\"),\n );\n const pools = (raw.pools ?? []).map(\n (p) => fromSnakeKeys(p, \"poolId\") as SandboxPoolInfo,\n );\n return Object.assign(pools, { traceId: raw.traceId });\n }\n\n /** Replace the configuration of an existing sandbox pool. */\n async updatePool(\n poolId: string,\n options: UpdatePoolOptions,\n ): Promise<SandboxPoolInfo> {\n const body: Record<string, unknown> = {\n image: options.image,\n resources: {\n cpus: options.cpus ?? 1.0,\n memory_mb: options.memoryMb ?? 1024,\n ephemeral_disk_mb: options.ephemeralDiskMb ?? 1024,\n },\n timeout_secs: options.timeoutSecs ?? 0,\n };\n\n if (options.secretNames != null) body.secret_names = options.secretNames;\n if (options.entrypoint != null) body.entrypoint = options.entrypoint;\n if (options.maxContainers != null) body.max_containers = options.maxContainers;\n if (options.warmContainers != null) body.warm_containers = options.warmContainers;\n\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"PUT\",\n this.path(`sandbox-pools/${poolId}`),\n { body },\n );\n return fromSnakeKeys(raw, \"poolId\") as SandboxPoolInfo;\n }\n\n /** Delete a sandbox pool. Fails if the pool has active containers. */\n async deletePool(poolId: string): Promise<void> {\n await this.http.requestJson(\n \"DELETE\",\n this.path(`sandbox-pools/${poolId}`),\n );\n }\n\n // --- Connect ---\n\n /** Return a `Sandbox` handle for an existing running sandbox without verifying it exists. */\n connect(identifier: string, proxyUrl?: string, routingHint?: string): Sandbox {\n const resolvedProxy = proxyUrl ?? resolveProxyUrl(this.apiUrl);\n return new Sandbox({\n sandboxId: identifier,\n proxyUrl: resolvedProxy,\n apiKey: this.apiKey,\n organizationId: this.organizationId,\n projectId: this.projectId,\n routingHint,\n });\n }\n\n /**\n * Create a sandbox, wait for it to reach `Running`, and return a connected handle.\n *\n * Blocks until the sandbox is ready or `startupTimeout` elapses. The returned\n * `Sandbox` auto-terminates when `terminate()` is called.\n *\n * @param options.startupTimeout - Max seconds to wait for `Running` status (default 60).\n * @throws {SandboxError} If the sandbox terminates during startup or the timeout elapses.\n */\n async createAndConnect(\n options?: CreateAndConnectOptions,\n ): Promise<Sandbox> {\n const startupTimeout = options?.startupTimeout ?? 60;\n\n // claim() never sends options.name to the server, so only create() should fall\n // back to it locally when the server response omits a name.\n const result = options?.poolId != null\n ? await this.claim(options.poolId)\n : await this.create(options);\n const requestedName = options?.poolId != null ? null : options?.name ?? null;\n\n const finishConnect = (routingHint: string | undefined, name: string | null | undefined) => {\n const sandbox = this.connect(result.sandboxId, options?.proxyUrl, routingHint);\n sandbox._setOwner(this);\n sandbox.traceId = result.traceId;\n sandbox._setLifecycleIdentifier(result.sandboxId);\n sandbox._setName(name ?? requestedName);\n return sandbox;\n };\n\n // Fast path: the blocking create/claim response already carries Running status\n // and a short-lived routing hint. Use it immediately to skip an extra poll RTT\n // and let the proxy route the first request without a placement lookup.\n if (result.status === SandboxStatus.RUNNING) {\n return finishConnect(result.routingHint, result.name);\n }\n\n const deadline = Date.now() + startupTimeout * 1000;\n\n while (Date.now() < deadline) {\n const info = await this.get(result.sandboxId);\n if (info.status === SandboxStatus.RUNNING) {\n return finishConnect(info.routingHint, info.name);\n }\n if (info.status === SandboxStatus.TERMINATED) {\n throw new SandboxError(\n `Sandbox ${result.sandboxId} terminated during startup`,\n );\n }\n await sleep(500);\n }\n\n // Timed out — clean up\n try {\n await this.delete(result.sandboxId);\n } catch {\n // ignore cleanup failures\n }\n throw new SandboxError(\n `Sandbox ${result.sandboxId} did not start within ${startupTimeout}s`,\n );\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nconst RESERVED_SANDBOX_MANAGEMENT_PORT = 9501;\n\nfunction normalizeUserPorts(ports: number[]): number[] {\n return dedupeAndSortPorts(ports.map(validateUserPort));\n}\n\nfunction validateUserPort(port: number): number {\n if (!Number.isInteger(port) || port < 1 || port > 65535) {\n throw new SandboxError(`invalid port '${port}'`);\n }\n if (port === RESERVED_SANDBOX_MANAGEMENT_PORT) {\n throw new SandboxError(\"port 9501 is reserved for sandbox management\");\n }\n return port;\n}\n\nfunction dedupeAndSortPorts(ports: number[]): number[] {\n return [...new Set(ports)].sort((a, b) => a - b);\n}\n","import { randomUUID } from \"node:crypto\";\n\n// Erased at runtime — safe despite the module cycle with sandbox-image.ts,\n// which imports Image from here.\nimport type { CreateSandboxImageOptions } from \"./sandbox-image.js\";\n\nconst DEFAULT_IMAGE_NAME = \"default\";\n\nexport const ImageBuildOperationType = {\n ADD: \"ADD\",\n COPY: \"COPY\",\n ENV: \"ENV\",\n RUN: \"RUN\",\n WORKDIR: \"WORKDIR\",\n} as const;\n\nexport type ImageBuildOperationType =\n (typeof ImageBuildOperationType)[keyof typeof ImageBuildOperationType];\n\nexport interface ImageBuildOperation {\n type: ImageBuildOperationType;\n args: string[];\n options: Record<string, string>;\n}\n\nexport interface ImageOptions {\n name?: string;\n tag?: string;\n baseImage?: string | null;\n}\n\nfunction cloneOperation(op: ImageBuildOperation): ImageBuildOperation {\n return {\n type: op.type,\n args: [...op.args],\n options: { ...op.options },\n };\n}\n\nexport class Image {\n readonly _id: string;\n readonly _name: string;\n readonly _tag: string;\n readonly _baseImage: string | null;\n readonly _buildOperations: ImageBuildOperation[];\n\n constructor();\n constructor(name: string, tag?: string, baseImage?: string | null);\n constructor(options: ImageOptions);\n constructor(\n nameOrOptions: string | ImageOptions = {},\n tag = \"latest\",\n baseImage: string | null = null,\n ) {\n this._id = randomUUID();\n this._buildOperations = [];\n\n if (typeof nameOrOptions === \"string\") {\n this._name = nameOrOptions;\n this._tag = tag;\n this._baseImage = baseImage;\n return;\n }\n\n this._name = nameOrOptions.name ?? DEFAULT_IMAGE_NAME;\n this._tag = nameOrOptions.tag ?? \"latest\";\n this._baseImage = nameOrOptions.baseImage ?? null;\n }\n\n get name(): string {\n return this._name;\n }\n\n get tag(): string {\n return this._tag;\n }\n\n get baseImage(): string | null {\n return this._baseImage;\n }\n\n get buildOperations(): ImageBuildOperation[] {\n return this._buildOperations.map(cloneOperation);\n }\n\n add(\n src: string,\n dest: string,\n options: Record<string, string> | undefined = undefined,\n ): this {\n return this._addOperation({\n type: ImageBuildOperationType.ADD,\n args: [src, dest],\n options: options == null ? {} : { ...options },\n });\n }\n\n copy(\n src: string,\n dest: string,\n options: Record<string, string> | undefined = undefined,\n ): this {\n return this._addOperation({\n type: ImageBuildOperationType.COPY,\n args: [src, dest],\n options: options == null ? {} : { ...options },\n });\n }\n\n env(key: string, value: string): this {\n return this._addOperation({\n type: ImageBuildOperationType.ENV,\n args: [key, value],\n options: {},\n });\n }\n\n run(\n commands: string | string[],\n options: Record<string, string> | undefined = undefined,\n ): this {\n return this._addOperation({\n type: ImageBuildOperationType.RUN,\n args: Array.isArray(commands) ? [...commands] : [commands],\n options: options == null ? {} : { ...options },\n });\n }\n\n workdir(directory: string): this {\n return this._addOperation({\n type: ImageBuildOperationType.WORKDIR,\n args: [directory],\n options: {},\n });\n }\n\n /**\n * Build this image as a sandbox template and register it.\n *\n * Materializes the image in a build sandbox, snapshots the filesystem,\n * and registers the snapshot as a named sandbox template.\n */\n async build(\n options: CreateSandboxImageOptions = {},\n ): Promise<Record<string, unknown>> {\n if ((options.registeredName ?? this._name) === DEFAULT_IMAGE_NAME) {\n // eslint-disable-next-line no-console\n console.warn(\n `Building sandbox image with the default name \"${DEFAULT_IMAGE_NAME}\". ` +\n \"Pass `registeredName` or `Image({ name })` to avoid collisions \" +\n \"with other default-named images in this project.\",\n );\n }\n const { createSandboxImage } = await import(\"./sandbox-image.js\");\n return createSandboxImage(this, options);\n }\n\n private _addOperation(op: ImageBuildOperation): this {\n this._buildOperations.push(op);\n return this;\n }\n}\n\nfunction renderOptions(options: Record<string, string>): string {\n const entries = Object.entries(options);\n if (entries.length === 0) {\n return \"\";\n }\n return ` ${entries.map(([key, value]) => `--${key}=${value}`).join(\" \")}`;\n}\n\nfunction renderBuildOp(op: ImageBuildOperation): string {\n const options = renderOptions(op.options);\n if (op.type === ImageBuildOperationType.ENV) {\n return `ENV${options} ${op.args[0]}=${JSON.stringify(op.args[1])}`;\n }\n return `${op.type}${options} ${op.args.join(\" \")}`;\n}\n\nexport function dockerfileContent(image: Image): string {\n const lines = image.baseImage == null ? [] : [`FROM ${image.baseImage}`];\n lines.push(...image.buildOperations.map((op) => renderBuildOp(op)));\n return lines.join(\"\\n\");\n}\n","import { readFile, readdir, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { parseArgs } from \"node:util\";\nimport {\n type CommandResult,\n type ProcessInfo,\n type SnapshotContentMode,\n type SnapshotInfo,\n} from \"./models.js\";\nimport { type OutputResponse, ProcessStatus } from \"./models.js\";\nimport { SandboxClient } from \"./client.js\";\nimport { Image, dockerfileContent } from \"./image.js\";\n\nconst BUILD_SANDBOX_PIP_ENV = { PIP_BREAK_SYSTEM_PACKAGES: \"1\" } as const;\nconst IGNORED_DOCKERFILE_INSTRUCTIONS = new Set([\n \"CMD\",\n \"ENTRYPOINT\",\n \"EXPOSE\",\n \"HEALTHCHECK\",\n \"LABEL\",\n \"STOPSIGNAL\",\n \"VOLUME\",\n]);\nconst UNSUPPORTED_DOCKERFILE_INSTRUCTIONS = new Set([\n \"ARG\",\n \"ONBUILD\",\n \"SHELL\",\n \"USER\",\n]);\n\nexport interface DockerfileInstruction {\n keyword: string;\n value: string;\n lineNumber: number;\n}\n\nexport interface DockerfileBuildPlan {\n dockerfilePath: string;\n contextDir: string;\n registeredName: string;\n dockerfileText: string;\n baseImage?: string;\n instructions: DockerfileInstruction[];\n}\n\nexport interface CreateSandboxImageOptions {\n registeredName?: string;\n cpus?: number;\n memoryMb?: number;\n diskMb?: number;\n isPublic?: boolean;\n contextDir?: string;\n /**\n * Print build progress to stderr. Ignored when an explicit `emit` is passed\n * via `deps`. Defaults to false — `createSandboxImage` is silent by default\n * when invoked programmatically (e.g. `Image.build()`).\n */\n verbose?: boolean;\n}\n\nexport type SandboxImageSource = string | Image;\n\ninterface BuildContext {\n apiUrl: string;\n apiKey?: string;\n personalAccessToken?: string;\n namespace: string;\n organizationId?: string;\n projectId?: string;\n debug: boolean;\n}\n\ninterface BuildSandbox {\n sandboxId: string;\n run(\n command: string,\n options?: {\n args?: string[];\n env?: Record<string, string>;\n workingDir?: string;\n timeout?: number;\n },\n ): Promise<CommandResult>;\n startProcess(\n command: string,\n options?: {\n args?: string[];\n env?: Record<string, string>;\n workingDir?: string;\n },\n ): Promise<ProcessInfo>;\n getStdout(pid: number): Promise<OutputResponse>;\n getStderr(pid: number): Promise<OutputResponse>;\n getProcess(pid: number): Promise<ProcessInfo>;\n writeFile(path: string, content: Uint8Array): Promise<void>;\n terminate(): Promise<void>;\n}\n\ninterface BuildClient {\n createAndConnect(options: {\n image?: string;\n cpus?: number;\n memoryMb?: number;\n diskMb?: number;\n }): Promise<BuildSandbox>;\n snapshotAndWait(\n sandboxId: string,\n options?: {\n timeout?: number;\n pollInterval?: number;\n contentMode?: SnapshotContentMode;\n },\n ): Promise<SnapshotInfo>;\n close(): void;\n}\n\ninterface CreateSandboxImageDeps {\n emit?: (event: Record<string, unknown>) => void;\n createClient?: (context: BuildContext) => BuildClient;\n registerImage?: (\n context: BuildContext,\n name: string,\n dockerfile: string,\n snapshotId: string,\n snapshotUri: string,\n isPublic: boolean,\n ) => Promise<Record<string, unknown>>;\n sleep?: (ms: number) => Promise<void>;\n}\n\nexport function defaultRegisteredName(dockerfilePath: string): string {\n const parsed = path.parse(dockerfilePath);\n if (parsed.name.toLowerCase() === \"dockerfile\") {\n const parentName = path.basename(path.dirname(dockerfilePath)).trim();\n return parentName || \"sandbox-image\";\n }\n return parsed.name || \"sandbox-image\";\n}\n\nexport function logicalDockerfileLines(\n dockerfileText: string,\n): Array<{ lineNumber: number; line: string }> {\n const logicalLines: Array<{ lineNumber: number; line: string }> = [];\n let parts: string[] = [];\n let startLine: number | null = null;\n\n for (const [index, rawLine] of dockerfileText.split(/\\r?\\n/).entries()) {\n const lineNumber = index + 1;\n const stripped = rawLine.trim();\n if (parts.length === 0 && (!stripped || stripped.startsWith(\"#\"))) {\n continue;\n }\n\n if (startLine == null) {\n startLine = lineNumber;\n }\n\n let line = rawLine.replace(/\\s+$/, \"\");\n const continued = line.endsWith(\"\\\\\");\n if (continued) {\n line = line.slice(0, -1);\n }\n\n const normalized = line.trim();\n if (normalized && !normalized.startsWith(\"#\")) {\n parts.push(normalized);\n }\n\n if (continued) {\n continue;\n }\n\n if (parts.length > 0) {\n logicalLines.push({\n lineNumber: startLine ?? lineNumber,\n line: parts.join(\" \"),\n });\n }\n parts = [];\n startLine = null;\n }\n\n if (parts.length > 0) {\n logicalLines.push({\n lineNumber: startLine ?? 1,\n line: parts.join(\" \"),\n });\n }\n\n return logicalLines;\n}\n\nfunction splitInstruction(\n line: string,\n lineNumber: number,\n): { keyword: string; value: string } {\n const trimmed = line.trim();\n if (!trimmed) {\n throw new Error(`line ${lineNumber}: empty Dockerfile instruction`);\n }\n const match = trimmed.match(/^(\\S+)(?:\\s+(.*))?$/);\n if (!match) {\n throw new Error(`line ${lineNumber}: invalid Dockerfile instruction`);\n }\n return {\n keyword: match[1].toUpperCase(),\n value: (match[2] ?? \"\").trim(),\n };\n}\n\nfunction shellSplit(input: string): string[] {\n const tokens: string[] = [];\n let current = \"\";\n let quote: \"'\" | '\"' | null = null;\n let escape = false;\n\n for (let i = 0; i < input.length; i++) {\n const char = input[i];\n\n if (escape) {\n current += char;\n escape = false;\n continue;\n }\n\n if (quote == null) {\n if (/\\s/.test(char)) {\n if (current) {\n tokens.push(current);\n current = \"\";\n }\n continue;\n }\n if (char === \"'\" || char === '\"') {\n quote = char;\n continue;\n }\n if (char === \"\\\\\") {\n escape = true;\n continue;\n }\n current += char;\n continue;\n }\n\n if (quote === \"'\") {\n if (char === \"'\") {\n quote = null;\n } else {\n current += char;\n }\n continue;\n }\n\n if (char === '\"') {\n quote = null;\n continue;\n }\n if (char === \"\\\\\") {\n const next = input[++i];\n if (next == null) {\n throw new Error(`unterminated escape sequence in '${input}'`);\n }\n current += next;\n continue;\n }\n current += char;\n }\n\n if (escape) {\n throw new Error(`unterminated escape sequence in '${input}'`);\n }\n if (quote != null) {\n throw new Error(`unterminated quoted string in '${input}'`);\n }\n if (current) {\n tokens.push(current);\n }\n return tokens;\n}\n\nfunction shellQuote(value: string): string {\n if (!value) {\n return \"''\";\n }\n return `'${value.replace(/'/g, `'\\\\''`)}'`;\n}\n\nfunction stripLeadingFlags(value: string): {\n flags: Record<string, string>;\n remaining: string;\n} {\n const flags: Record<string, string> = {};\n let remaining = value.trimStart();\n\n while (remaining.startsWith(\"--\")) {\n const firstSpace = remaining.indexOf(\" \");\n if (firstSpace === -1) {\n throw new Error(`invalid Dockerfile flag syntax: ${value}`);\n }\n\n const token = remaining.slice(0, firstSpace);\n const rest = remaining.slice(firstSpace + 1).trimStart();\n const flagBody = token.slice(2);\n\n if (flagBody.includes(\"=\")) {\n const [key, flagValue] = flagBody.split(/=(.*)/s, 2);\n flags[key] = flagValue;\n remaining = rest;\n continue;\n }\n\n const [flagValue, ...restTokens] = shellSplit(rest);\n if (flagValue == null) {\n throw new Error(`missing value for Dockerfile flag '${token}'`);\n }\n flags[flagBody] = flagValue;\n remaining = restTokens.join(\" \");\n }\n\n return { flags, remaining };\n}\n\nfunction parseFromValue(value: string, lineNumber: number): string {\n const { remaining } = stripLeadingFlags(value);\n const tokens = shellSplit(remaining);\n if (tokens.length === 0) {\n throw new Error(`line ${lineNumber}: FROM must include a base image`);\n }\n if (tokens.length > 1 && tokens[1].toLowerCase() !== \"as\") {\n throw new Error(`line ${lineNumber}: unsupported FROM syntax '${value}'`);\n }\n return tokens[0];\n}\n\nfunction parseCopyLikeValues(\n value: string,\n lineNumber: number,\n keyword: string,\n): {\n flags: Record<string, string>;\n sources: string[];\n destination: string;\n} {\n const { flags, remaining } = stripLeadingFlags(value);\n if (\"from\" in flags) {\n throw new Error(\n `line ${lineNumber}: ${keyword} --from is not supported for sandbox image creation`,\n );\n }\n\n const payload = remaining.trim();\n if (!payload) {\n throw new Error(\n `line ${lineNumber}: ${keyword} must include source and destination`,\n );\n }\n\n let parts: string[];\n if (payload.startsWith(\"[\")) {\n let parsed: unknown;\n try {\n parsed = JSON.parse(payload);\n } catch (error) {\n throw new Error(\n `line ${lineNumber}: invalid JSON array syntax for ${keyword}: ${(error as Error).message}`,\n );\n }\n if (\n !Array.isArray(parsed) ||\n parsed.length < 2 ||\n parsed.some((item) => typeof item !== \"string\")\n ) {\n throw new Error(\n `line ${lineNumber}: ${keyword} JSON array form requires at least two string values`,\n );\n }\n parts = parsed as string[];\n } else {\n parts = shellSplit(payload);\n if (parts.length < 2) {\n throw new Error(\n `line ${lineNumber}: ${keyword} must include at least one source and one destination`,\n );\n }\n }\n\n return {\n flags,\n sources: parts.slice(0, -1),\n destination: parts[parts.length - 1],\n };\n}\n\nfunction parseEnvPairs(value: string, lineNumber: number): Array<[string, string]> {\n const tokens = shellSplit(value);\n if (tokens.length === 0) {\n throw new Error(`line ${lineNumber}: ENV must include a key and value`);\n }\n\n if (tokens.every((token) => token.includes(\"=\"))) {\n return tokens.map((token) => {\n const [key, envValue] = token.split(/=(.*)/s, 2);\n if (!key) {\n throw new Error(`line ${lineNumber}: invalid ENV token '${token}'`);\n }\n return [key, envValue] as [string, string];\n });\n }\n\n if (tokens.length < 2) {\n throw new Error(`line ${lineNumber}: ENV must include a key and value`);\n }\n\n return [[tokens[0], tokens.slice(1).join(\" \")]];\n}\n\nfunction resolveContainerPath(containerPath: string, workingDir: string): string {\n if (!containerPath) {\n return workingDir;\n }\n const normalized = containerPath.startsWith(\"/\")\n ? path.posix.normalize(containerPath)\n : path.posix.normalize(path.posix.join(workingDir, containerPath));\n return normalized.startsWith(\"/\") ? normalized : `/${normalized}`;\n}\n\nfunction buildPlanFromDockerfileText(\n dockerfileText: string,\n dockerfilePath: string,\n contextDir: string,\n registeredName?: string,\n): DockerfileBuildPlan {\n let baseImage: string | undefined;\n const instructions: DockerfileInstruction[] = [];\n\n for (const logicalLine of logicalDockerfileLines(dockerfileText)) {\n const { keyword, value } = splitInstruction(\n logicalLine.line,\n logicalLine.lineNumber,\n );\n if (keyword === \"FROM\") {\n if (baseImage != null) {\n throw new Error(\n `line ${logicalLine.lineNumber}: multi-stage Dockerfiles are not supported for sandbox image creation`,\n );\n }\n baseImage = parseFromValue(value, logicalLine.lineNumber);\n continue;\n }\n\n if (UNSUPPORTED_DOCKERFILE_INSTRUCTIONS.has(keyword)) {\n throw new Error(\n `line ${logicalLine.lineNumber}: Dockerfile instruction '${keyword}' is not supported for sandbox image creation`,\n );\n }\n\n instructions.push({\n keyword,\n value,\n lineNumber: logicalLine.lineNumber,\n });\n }\n\n if (!baseImage) {\n throw new Error(\"Dockerfile must contain a FROM instruction\");\n }\n\n return {\n dockerfilePath,\n contextDir,\n registeredName: registeredName ?? defaultRegisteredName(dockerfilePath),\n dockerfileText,\n baseImage,\n instructions,\n };\n}\n\nexport async function loadDockerfilePlan(\n dockerfilePath: string,\n registeredName?: string,\n): Promise<DockerfileBuildPlan> {\n const resolvedPath = path.resolve(dockerfilePath);\n const fileStats = await stat(resolvedPath).catch(() => null);\n if (!fileStats?.isFile()) {\n throw new Error(`Dockerfile not found: ${dockerfilePath}`);\n }\n\n const dockerfileText = await readFile(resolvedPath, \"utf8\");\n return buildPlanFromDockerfileText(\n dockerfileText,\n resolvedPath,\n path.dirname(resolvedPath),\n registeredName,\n );\n}\n\nexport function loadImagePlan(\n image: Image,\n options: Pick<CreateSandboxImageOptions, \"registeredName\" | \"contextDir\"> = {},\n): DockerfileBuildPlan {\n const contextDir = path.resolve(options.contextDir ?? process.cwd());\n const dockerfileText = dockerfileContent(image);\n const logicalLines = logicalDockerfileLines(dockerfileText);\n const instructions = image.baseImage == null ? logicalLines : logicalLines.slice(1);\n\n return {\n dockerfilePath: path.join(contextDir, \"Dockerfile\"),\n contextDir,\n registeredName: options.registeredName ?? image.name,\n dockerfileText,\n baseImage: image.baseImage ?? undefined,\n instructions: instructions.map(({ line, lineNumber }) => {\n const parsed = splitInstruction(line, lineNumber);\n return {\n keyword: parsed.keyword,\n value: parsed.value,\n lineNumber,\n };\n }),\n };\n}\n\nfunction ndjsonStdoutEmit(event: Record<string, unknown>) {\n process.stdout.write(`${JSON.stringify(event)}\\n`);\n}\n\nfunction noopEmit(_event: Record<string, unknown>) {}\n\nfunction stderrEmit(event: Record<string, unknown>) {\n const type = typeof event.type === \"string\" ? event.type : \"\";\n const message = typeof event.message === \"string\" ? event.message : \"\";\n if (type === \"build_log\") {\n const stream = typeof event.stream === \"string\" ? event.stream : \"stdout\";\n process.stderr.write(`[${stream}] ${message}\\n`);\n } else if (message) {\n process.stderr.write(`[${type}] ${message}\\n`);\n }\n}\n\nfunction debugEnabled(): boolean {\n return [\"1\", \"true\", \"yes\", \"on\"].includes(\n (process.env.TENSORLAKE_DEBUG ?? \"\").toLowerCase(),\n );\n}\n\nfunction buildContextFromEnv(): BuildContext {\n return {\n apiUrl: process.env.TENSORLAKE_API_URL ?? \"https://api.tensorlake.ai\",\n apiKey: process.env.TENSORLAKE_API_KEY,\n personalAccessToken: process.env.TENSORLAKE_PAT,\n namespace: process.env.INDEXIFY_NAMESPACE ?? \"default\",\n organizationId: process.env.TENSORLAKE_ORGANIZATION_ID,\n projectId: process.env.TENSORLAKE_PROJECT_ID,\n debug: debugEnabled(),\n };\n}\n\nfunction createDefaultClient(context: BuildContext): BuildClient {\n return new SandboxClient({\n apiUrl: context.apiUrl,\n apiKey: context.apiKey ?? context.personalAccessToken,\n organizationId: context.organizationId,\n projectId: context.projectId,\n namespace: context.namespace,\n });\n}\n\nasync function runChecked(\n sandbox: BuildSandbox,\n command: string,\n args: string[],\n env?: Record<string, string>,\n workingDir?: string,\n): Promise<CommandResult> {\n const result = await sandbox.run(command, {\n args,\n env,\n workingDir,\n });\n if (result.exitCode !== 0) {\n throw new Error(\n `Command '${command} ${args.join(\" \")}' failed with exit code ${result.exitCode}`,\n );\n }\n return result;\n}\n\nasync function runStreaming(\n sandbox: BuildSandbox,\n emit: (event: Record<string, unknown>) => void,\n sleep: (ms: number) => Promise<void>,\n command: string,\n args: string[] = [],\n env?: Record<string, string>,\n workingDir?: string,\n) {\n const proc = await sandbox.startProcess(command, {\n args,\n env,\n workingDir,\n });\n\n let stdoutSeen = 0;\n let stderrSeen = 0;\n let info: ProcessInfo;\n\n while (true) {\n const stdoutResp = await sandbox.getStdout(proc.pid);\n emitOutputLines(emit, \"stdout\", stdoutResp, stdoutSeen);\n stdoutSeen = stdoutResp.lines.length;\n\n const stderrResp = await sandbox.getStderr(proc.pid);\n emitOutputLines(emit, \"stderr\", stderrResp, stderrSeen);\n stderrSeen = stderrResp.lines.length;\n\n info = await sandbox.getProcess(proc.pid);\n if (info.status !== ProcessStatus.RUNNING) {\n const finalStdout = await sandbox.getStdout(proc.pid);\n emitOutputLines(emit, \"stdout\", finalStdout, stdoutSeen);\n stdoutSeen = finalStdout.lines.length;\n\n const finalStderr = await sandbox.getStderr(proc.pid);\n emitOutputLines(emit, \"stderr\", finalStderr, stderrSeen);\n break;\n }\n\n await sleep(300);\n }\n\n for (let i = 0; i < 10; i++) {\n if (info.exitCode != null || info.signal != null) {\n break;\n }\n await sleep(200);\n info = await sandbox.getProcess(proc.pid);\n }\n\n const exitCode =\n info.exitCode != null ? info.exitCode : info.signal != null ? -info.signal : 0;\n if (exitCode !== 0) {\n throw new Error(\n `Command '${command} ${args.join(\" \")}' failed with exit code ${exitCode}`,\n );\n }\n}\n\nfunction emitOutputLines(\n emit: (event: Record<string, unknown>) => void,\n stream: \"stdout\" | \"stderr\",\n response: OutputResponse,\n seen: number,\n) {\n for (const line of response.lines.slice(seen)) {\n emit({ type: \"build_log\", stream, message: line });\n }\n}\n\nfunction isPathWithinContext(contextDir: string, localPath: string): boolean {\n const relative = path.relative(contextDir, localPath);\n return relative === \"\" || (!relative.startsWith(\"..\") && !path.isAbsolute(relative));\n}\n\nfunction resolveContextSourcePath(contextDir: string, source: string): string {\n const resolvedContextDir = path.resolve(contextDir);\n const resolvedSource = path.resolve(resolvedContextDir, source);\n if (!isPathWithinContext(resolvedContextDir, resolvedSource)) {\n throw new Error(`Local path escapes the build context: ${source}`);\n }\n return resolvedSource;\n}\n\nasync function copyLocalPathToSandbox(\n sandbox: BuildSandbox,\n localPath: string,\n remotePath: string,\n) {\n const fileStats = await stat(localPath).catch(() => null);\n if (!fileStats) {\n throw new Error(`Local path not found: ${localPath}`);\n }\n\n if (fileStats.isFile()) {\n await runChecked(sandbox, \"mkdir\", [\"-p\", path.posix.dirname(remotePath)]);\n await sandbox.writeFile(remotePath, await readFile(localPath));\n return;\n }\n\n if (!fileStats.isDirectory()) {\n throw new Error(`Local path not found: ${localPath}`);\n }\n\n const entries = await readdir(localPath, { withFileTypes: true });\n for (const entry of entries) {\n const sourcePath = path.join(localPath, entry.name);\n const destinationPath = path.posix.join(remotePath, entry.name);\n if (entry.isDirectory()) {\n await runChecked(sandbox, \"mkdir\", [\"-p\", destinationPath]);\n await copyLocalPathToSandbox(sandbox, sourcePath, destinationPath);\n } else if (entry.isFile()) {\n await runChecked(\n sandbox,\n \"mkdir\",\n [\"-p\", path.posix.dirname(destinationPath)],\n );\n await sandbox.writeFile(destinationPath, await readFile(sourcePath));\n }\n }\n}\n\nasync function persistEnvVar(\n sandbox: BuildSandbox,\n processEnv: Record<string, string>,\n key: string,\n value: string,\n) {\n const exportLine = `export ${key}=${shellQuote(value)}`;\n await runChecked(\n sandbox,\n \"sh\",\n [\"-c\", `printf '%s\\\\n' ${shellQuote(exportLine)} >> /etc/environment`],\n processEnv,\n );\n}\n\nasync function copyFromContext(\n sandbox: BuildSandbox,\n emit: (event: Record<string, unknown>) => void,\n contextDir: string,\n sources: string[],\n destination: string,\n workingDir: string,\n keyword: string,\n) {\n const destinationPath = resolveContainerPath(destination, workingDir);\n if (sources.length > 1 && !destinationPath.endsWith(\"/\")) {\n throw new Error(\n `${keyword} with multiple sources requires a directory destination ending in '/'`,\n );\n }\n\n for (const source of sources) {\n const localSource = resolveContextSourcePath(contextDir, source);\n const localStats = await stat(localSource).catch(() => null);\n if (!localStats) {\n throw new Error(`Local path not found: ${localSource}`);\n }\n\n let remoteDestination = destinationPath;\n if (sources.length > 1) {\n remoteDestination = path.posix.join(\n destinationPath.replace(/\\/$/, \"\"),\n path.posix.basename(source.replace(/\\/$/, \"\")),\n );\n } else if (localStats.isFile() && destinationPath.endsWith(\"/\")) {\n remoteDestination = path.posix.join(\n destinationPath.replace(/\\/$/, \"\"),\n path.basename(source),\n );\n }\n\n emit({\n type: \"status\",\n message: `${keyword} ${source} -> ${remoteDestination}`,\n });\n await copyLocalPathToSandbox(sandbox, localSource, remoteDestination);\n }\n}\n\nasync function addUrlToSandbox(\n sandbox: BuildSandbox,\n emit: (event: Record<string, unknown>) => void,\n url: string,\n destination: string,\n workingDir: string,\n processEnv: Record<string, string>,\n sleep: (ms: number) => Promise<void>,\n) {\n let destinationPath = resolveContainerPath(destination, workingDir);\n const parsedUrl = new URL(url);\n const fileName = path.posix.basename(parsedUrl.pathname.replace(/\\/$/, \"\")) || \"downloaded\";\n if (destinationPath.endsWith(\"/\")) {\n destinationPath = path.posix.join(destinationPath.replace(/\\/$/, \"\"), fileName);\n }\n\n const parentDir = path.posix.dirname(destinationPath) || \"/\";\n emit({\n type: \"status\",\n message: `ADD ${url} -> ${destinationPath}`,\n });\n await runChecked(sandbox, \"mkdir\", [\"-p\", parentDir], processEnv);\n await runStreaming(\n sandbox,\n emit,\n sleep,\n \"sh\",\n [\n \"-c\",\n `curl -fsSL --location ${shellQuote(url)} -o ${shellQuote(destinationPath)}`,\n ],\n processEnv,\n workingDir,\n );\n}\n\nasync function executeDockerfilePlan(\n sandbox: BuildSandbox,\n plan: DockerfileBuildPlan,\n emit: (event: Record<string, unknown>) => void,\n sleep: (ms: number) => Promise<void>,\n) {\n const processEnv: Record<string, string> = { ...BUILD_SANDBOX_PIP_ENV };\n let workingDir = \"/\";\n\n for (const instruction of plan.instructions) {\n const { keyword, value, lineNumber } = instruction;\n\n if (keyword === \"RUN\") {\n emit({ type: \"status\", message: `RUN ${value}` });\n await runStreaming(\n sandbox,\n emit,\n sleep,\n \"sh\",\n [\"-c\", value],\n processEnv,\n workingDir,\n );\n continue;\n }\n\n if (keyword === \"WORKDIR\") {\n const tokens = shellSplit(value);\n if (tokens.length !== 1) {\n throw new Error(`line ${lineNumber}: WORKDIR must include exactly one path`);\n }\n workingDir = resolveContainerPath(tokens[0], workingDir);\n emit({ type: \"status\", message: `WORKDIR ${workingDir}` });\n await runChecked(sandbox, \"mkdir\", [\"-p\", workingDir], processEnv);\n continue;\n }\n\n if (keyword === \"ENV\") {\n for (const [key, envValue] of parseEnvPairs(value, lineNumber)) {\n emit({ type: \"status\", message: `ENV ${key}=${envValue}` });\n processEnv[key] = envValue;\n await persistEnvVar(sandbox, processEnv, key, envValue);\n }\n continue;\n }\n\n if (keyword === \"COPY\") {\n const { sources, destination } = parseCopyLikeValues(\n value,\n lineNumber,\n keyword,\n );\n await copyFromContext(\n sandbox,\n emit,\n plan.contextDir,\n sources,\n destination,\n workingDir,\n keyword,\n );\n continue;\n }\n\n if (keyword === \"ADD\") {\n const { sources, destination } = parseCopyLikeValues(\n value,\n lineNumber,\n keyword,\n );\n if (\n sources.length === 1 &&\n /^https?:\\/\\//.test(sources[0])\n ) {\n await addUrlToSandbox(\n sandbox,\n emit,\n sources[0],\n destination,\n workingDir,\n processEnv,\n sleep,\n );\n } else {\n await copyFromContext(\n sandbox,\n emit,\n plan.contextDir,\n sources,\n destination,\n workingDir,\n keyword,\n );\n }\n continue;\n }\n\n if (IGNORED_DOCKERFILE_INSTRUCTIONS.has(keyword)) {\n emit({\n type: \"warning\",\n message: `Skipping Dockerfile instruction '${keyword}' during snapshot materialization. It is still preserved in the registered Dockerfile.`,\n });\n continue;\n }\n\n throw new Error(\n `line ${lineNumber}: Dockerfile instruction '${keyword}' is not supported for sandbox image creation`,\n );\n }\n}\n\nasync function registerImage(\n context: BuildContext,\n name: string,\n dockerfile: string,\n snapshotId: string,\n snapshotUri: string,\n isPublic: boolean,\n): Promise<Record<string, unknown>> {\n if (!context.organizationId || !context.projectId) {\n throw new Error(\n \"Organization ID and Project ID are required. Run 'tl login' and 'tl init'.\",\n );\n }\n\n const bearerToken = context.apiKey ?? context.personalAccessToken;\n if (!bearerToken) {\n throw new Error(\"Missing TENSORLAKE_API_KEY or TENSORLAKE_PAT.\");\n }\n\n const baseUrl = context.apiUrl.replace(/\\/+$/, \"\");\n const url =\n `${baseUrl}/platform/v1/organizations/` +\n `${encodeURIComponent(context.organizationId)}/projects/` +\n `${encodeURIComponent(context.projectId)}/sandbox-templates`;\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${bearerToken}`,\n \"Content-Type\": \"application/json\",\n };\n if (context.personalAccessToken && !context.apiKey) {\n headers[\"X-Forwarded-Organization-Id\"] = context.organizationId;\n headers[\"X-Forwarded-Project-Id\"] = context.projectId;\n }\n\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n name,\n dockerfile,\n snapshotId,\n snapshotUri,\n isPublic,\n }),\n });\n\n if (!response.ok) {\n throw new Error(\n `${response.status} ${response.statusText}: ${await response.text()}`,\n );\n }\n\n const text = await response.text();\n return text ? (JSON.parse(text) as Record<string, unknown>) : {};\n}\n\nexport async function createSandboxImage(\n source: SandboxImageSource,\n options: CreateSandboxImageOptions = {},\n deps: CreateSandboxImageDeps = {},\n) {\n const emit = deps.emit ?? (options.verbose ? stderrEmit : noopEmit);\n const sleep = deps.sleep ?? ((ms: number) => new Promise((r) => setTimeout(r, ms)));\n const context = buildContextFromEnv();\n const clientFactory = deps.createClient ?? createDefaultClient;\n const register =\n deps.registerImage ??\n ((...args) => registerImage(...args));\n\n const sourceLabel =\n typeof source === \"string\" ? source : `Image(${source.name})`;\n emit({ type: \"status\", message: `Loading ${sourceLabel}...` });\n const plan =\n typeof source === \"string\"\n ? await loadDockerfilePlan(source, options.registeredName)\n : loadImagePlan(source, options);\n emit({\n type: \"status\",\n message:\n plan.baseImage == null\n ? \"Starting build sandbox with the default server image...\"\n : `Starting build sandbox from ${plan.baseImage}...`,\n });\n\n const client = clientFactory(context);\n let sandbox: BuildSandbox | undefined;\n\n try {\n sandbox = await client.createAndConnect({\n ...(plan.baseImage == null ? {} : { image: plan.baseImage }),\n cpus: options.cpus ?? 2.0,\n memoryMb: options.memoryMb ?? 4096,\n ...(options.diskMb != null ? { diskMb: options.diskMb } : {}),\n });\n\n emit({\n type: \"status\",\n message: `Materializing image in sandbox ${sandbox.sandboxId}...`,\n });\n await executeDockerfilePlan(sandbox, plan, emit, sleep);\n\n emit({ type: \"status\", message: \"Creating snapshot...\" });\n const snapshot = await client.snapshotAndWait(sandbox.sandboxId, {\n contentMode: \"filesystem_only\",\n });\n emit({\n type: \"snapshot_created\",\n snapshot_id: snapshot.snapshotId,\n });\n\n if (!snapshot.snapshotUri) {\n throw new Error(\n `Snapshot ${snapshot.snapshotId} is missing snapshotUri and cannot be registered as a sandbox image.`,\n );\n }\n\n emit({\n type: \"status\",\n message: `Registering image '${plan.registeredName}'...`,\n });\n const result = await register(\n context,\n plan.registeredName,\n plan.dockerfileText,\n snapshot.snapshotId,\n snapshot.snapshotUri,\n options.isPublic ?? false,\n );\n\n emit({\n type: \"image_registered\",\n name: plan.registeredName,\n image_id:\n (typeof result.id === \"string\" && result.id) ||\n (typeof result.templateId === \"string\" && result.templateId) ||\n \"\",\n });\n emit({ type: \"done\" });\n return result;\n } finally {\n if (sandbox) {\n try {\n await sandbox.terminate();\n } catch {}\n }\n client.close();\n }\n}\n\nexport async function runCreateSandboxImageCli(argv = process.argv.slice(2)) {\n const parsed = parseArgs({\n args: argv,\n allowPositionals: true,\n options: {\n name: { type: \"string\", short: \"n\" },\n cpus: { type: \"string\" },\n memory: { type: \"string\" },\n disk: { type: \"string\" },\n public: { type: \"boolean\", default: false },\n },\n });\n\n const dockerfilePath = parsed.positionals[0];\n if (!dockerfilePath) {\n throw new Error(\"Usage: tensorlake-create-sandbox-image <dockerfile_path> [--name NAME] [--cpus N] [--memory MB] [--disk GB] [--public]\");\n }\n\n const cpus =\n parsed.values.cpus != null ? Number(parsed.values.cpus) : undefined;\n const memoryMb =\n parsed.values.memory != null ? Number(parsed.values.memory) : undefined;\n const diskGb =\n parsed.values.disk != null ? Number(parsed.values.disk) : undefined;\n if (cpus != null && !Number.isFinite(cpus)) {\n throw new Error(`Invalid --cpus value: ${parsed.values.cpus}`);\n }\n if (memoryMb != null && !Number.isInteger(memoryMb)) {\n throw new Error(`Invalid --memory value: ${parsed.values.memory}`);\n }\n if (diskGb != null && !Number.isInteger(diskGb)) {\n throw new Error(`Invalid --disk value: ${parsed.values.disk}`);\n }\n\n await createSandboxImage(\n dockerfilePath,\n {\n registeredName: parsed.values.name,\n cpus,\n memoryMb,\n diskMb: diskGb != null ? diskGb * 1024 : undefined,\n isPublic: parsed.values.public,\n },\n { emit: ndjsonStdoutEmit },\n );\n}\n"],"mappings":"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QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAClD;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QACnD;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAClD;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,MACrD;AAAA,MACA;AAAA,QACE;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QACnD;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAI;AAAA,QAAI;AAAA,QACnD;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QACnD;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,MACpD;AAAA,MACA;AAAA,QACE;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAClD;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QACnD;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QACnD;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,MACpD;AAAA,MACA;AAAA,QACE;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QACnD;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QACnD;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAClD;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,MACrD;AAAA,MACA;AAAA,QACE;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAClD;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QACnD;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QACnD;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,MACpD;AAAA,MACA;AAAA,QACE;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QACnD;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QACnD;AAAA,QAAG;AAAA,QAAG;AAA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","names":["path","buttonMask","validatePort","secondsToMillis","value","path","WebSocket","SandboxClient","path","sleep","flagValue","sleep"]}
1
+ {"version":3,"sources":["../src/models.ts","../src/defaults.ts","../src/errors.ts","../src/http.ts","../src/tunnel.ts","../src/desktop.ts","../src/sse.ts","../src/url.ts","../src/sandbox.ts","../src/client.ts","../src/image.ts","../src/sandbox-image.ts"],"sourcesContent":["// --- Enums ---\n\nexport enum SandboxStatus {\n PENDING = \"pending\",\n RUNNING = \"running\",\n SNAPSHOTTING = \"snapshotting\",\n SUSPENDING = \"suspending\",\n SUSPENDED = \"suspended\",\n TERMINATED = \"terminated\",\n}\n\nexport enum SnapshotStatus {\n IN_PROGRESS = \"in_progress\",\n COMPLETED = \"completed\",\n FAILED = \"failed\",\n}\n\n/**\n * Content mode for snapshot creation.\n *\n * - `\"full\"`: Full VM snapshot (memory + filesystem state). Sandboxes\n * restored from this snapshot warm-restore VM memory.\n * - `\"filesystem_only\"`: Filesystem-only snapshot. Sandboxes restored from\n * this snapshot cold-boot from the snapshot tarball instead of warm-\n * restoring VM state. Use this for sandbox image builds so that the\n * restored sandbox bypasses Firecracker's overlay-path constraints.\n */\nexport type SnapshotContentMode = \"full\" | \"filesystem_only\";\n\nexport enum ProcessStatus {\n RUNNING = \"running\",\n EXITED = \"exited\",\n SIGNALED = \"signaled\",\n}\n\nexport enum StdinMode {\n CLOSED = \"closed\",\n PIPE = \"pipe\",\n}\n\nexport enum OutputMode {\n CAPTURE = \"capture\",\n DISCARD = \"discard\",\n}\n\nexport enum ContainerState {\n IDLE = \"Idle\",\n RUNNING = \"Running\",\n}\n\n// --- Resource / Network ---\n\nexport interface ContainerResourcesInfo {\n cpus: number;\n memoryMb: number;\n ephemeralDiskMb: number;\n}\n\nexport interface NetworkConfig {\n allowInternetAccess: boolean;\n allowOut: string[];\n denyOut: string[];\n}\n\n// --- Sandbox lifecycle ---\n\nexport interface CreateSandboxOptions {\n /** Optional sandbox image name, such as `tensorlake/ubuntu-minimal` or a registered Sandbox Image. When omitted, Tensorlake uses the default managed environment. */\n image?: string;\n cpus?: number;\n memoryMb?: number;\n /** Root disk size in megabytes. When omitted, the server uses its default disk size. */\n diskMb?: number;\n secretNames?: string[];\n timeoutSecs?: number;\n entrypoint?: string[];\n allowInternetAccess?: boolean;\n allowOut?: string[];\n denyOut?: string[];\n snapshotId?: string;\n /** Optional name for the sandbox. Named sandboxes support suspend/resume. When absent the sandbox is ephemeral. */\n name?: string;\n}\n\nexport interface UpdateSandboxOptions {\n /** New name for the sandbox. Naming an ephemeral sandbox enables suspend/resume. */\n name?: string;\n /** Whether exposed user ports should be reachable without TensorLake auth. */\n allowUnauthenticatedAccess?: boolean;\n /** User ports that should be routable through the sandbox proxy. Port 9501 is reserved. */\n exposedPorts?: number[];\n}\n\nexport interface CreateSandboxResponse {\n sandboxId: string;\n status: SandboxStatus;\n routingHint?: string;\n name?: string | null;\n terminationReason?: string;\n errorDetails?: unknown;\n}\n\nexport interface SandboxInfo {\n sandboxId: string;\n namespace: string;\n status: SandboxStatus;\n /** Resolved sandbox image name. */\n image?: string;\n resources: ContainerResourcesInfo;\n secretNames: string[];\n timeoutSecs?: number;\n entrypoint?: string[];\n network?: NetworkConfig;\n poolId?: string;\n outcome?: string;\n terminationReason?: string;\n errorDetails?: unknown;\n createdAt?: Date;\n terminatedAt?: Date;\n name?: string;\n allowUnauthenticatedAccess?: boolean;\n exposedPorts?: number[];\n sandboxUrl?: string;\n routingHint?: string;\n}\n\nexport interface SandboxPortAccess {\n allowUnauthenticatedAccess: boolean;\n exposedPorts: number[];\n sandboxUrl?: string;\n}\n\n// --- Snapshots ---\n\nexport interface CreateSnapshotResponse {\n snapshotId: string;\n status: SnapshotStatus;\n}\n\nexport interface SnapshotInfo {\n snapshotId: string;\n namespace: string;\n sandboxId: string;\n baseImage: string;\n status: SnapshotStatus;\n error?: string;\n snapshotUri?: string;\n sizeBytes?: number;\n rootfsDiskBytes?: number;\n createdAt?: Date;\n}\n\nexport interface SnapshotOptions {\n /**\n * Optional content mode for the snapshot. When omitted the server picks\n * its default. Use `\"filesystem_only\"` for snapshots intended for sandbox\n * image builds so that restored sandboxes cold-boot.\n */\n contentMode?: SnapshotContentMode;\n}\n\nexport interface SnapshotAndWaitOptions extends SnapshotOptions {\n timeout?: number;\n pollInterval?: number;\n}\n\n// --- Pools ---\n\nexport interface CreatePoolOptions {\n /** Sandbox image name, such as `tensorlake/ubuntu-minimal` or a registered Sandbox Image. */\n image: string;\n cpus?: number;\n memoryMb?: number;\n ephemeralDiskMb?: number;\n secretNames?: string[];\n timeoutSecs?: number;\n entrypoint?: string[];\n maxContainers?: number;\n warmContainers?: number;\n}\n\nexport interface UpdatePoolOptions {\n /** Sandbox image name, such as `tensorlake/ubuntu-minimal` or a registered Sandbox Image. */\n image: string;\n cpus?: number;\n memoryMb?: number;\n ephemeralDiskMb?: number;\n secretNames?: string[];\n timeoutSecs?: number;\n entrypoint?: string[];\n maxContainers?: number;\n warmContainers?: number;\n}\n\nexport interface CreateSandboxPoolResponse {\n poolId: string;\n namespace: string;\n}\n\nexport interface PoolContainerInfo {\n id: string;\n state: string;\n sandboxId?: string;\n executorId: string;\n}\n\nexport interface SandboxPoolInfo {\n poolId: string;\n namespace: string;\n /** Sandbox image name backing the pool. */\n image: string;\n resources: ContainerResourcesInfo;\n secretNames: string[];\n timeoutSecs: number;\n entrypoint?: string[];\n maxContainers?: number;\n warmContainers?: number;\n containers?: PoolContainerInfo[];\n createdAt?: Date;\n updatedAt?: Date;\n}\n\n// --- Process management ---\n\nexport interface StartProcessOptions {\n args?: string[];\n env?: Record<string, string>;\n workingDir?: string;\n stdinMode?: StdinMode;\n stdoutMode?: OutputMode;\n stderrMode?: OutputMode;\n}\n\nexport interface ProcessInfo {\n pid: number;\n status: ProcessStatus;\n exitCode?: number;\n signal?: number;\n stdinWritable: boolean;\n command: string;\n args: string[];\n startedAt: Date;\n endedAt?: Date;\n}\n\nexport interface SendSignalResponse {\n success: boolean;\n}\n\nexport interface OutputResponse {\n pid: number;\n lines: string[];\n lineCount: number;\n}\n\nexport interface OutputEvent {\n line: string;\n timestamp: Date;\n stream?: string;\n}\n\n// --- Run ---\n\nexport interface RunOptions {\n args?: string[];\n env?: Record<string, string>;\n workingDir?: string;\n timeout?: number;\n}\n\nexport interface CommandResult {\n exitCode: number;\n stdout: string;\n stderr: string;\n}\n\n// --- File operations ---\n\nexport interface DirectoryEntry {\n name: string;\n isDir: boolean;\n size?: number;\n modifiedAt?: Date;\n}\n\nexport interface ListDirectoryResponse {\n path: string;\n entries: DirectoryEntry[];\n}\n\n// --- PTY ---\n\nexport interface CreatePtySessionOptions {\n command: string;\n args?: string[];\n env?: Record<string, string>;\n workingDir?: string;\n rows?: number;\n cols?: number;\n}\n\nexport interface PtySessionInfo {\n sessionId: string;\n token: string;\n}\n\n// --- Health ---\n\nexport interface HealthResponse {\n healthy: boolean;\n}\n\nexport interface DaemonInfo {\n version: string;\n uptimeSecs: number;\n runningProcesses: number;\n totalProcesses: number;\n}\n\n// --- Client options ---\n\nexport interface SandboxClientOptions {\n apiUrl?: string;\n apiKey?: string;\n organizationId?: string;\n projectId?: string;\n namespace?: string;\n maxRetries?: number;\n retryBackoffMs?: number;\n}\n\nexport interface SandboxOptions {\n sandboxId: string;\n proxyUrl?: string;\n apiKey?: string;\n organizationId?: string;\n projectId?: string;\n routingHint?: string;\n}\n\nexport interface CreateAndConnectOptions extends CreateSandboxOptions {\n poolId?: string;\n proxyUrl?: string;\n startupTimeout?: number;\n}\n\nexport interface SuspendResumeOptions {\n /** If false, fire-and-return without waiting for completion. Default: true. */\n wait?: boolean;\n /** Max seconds to wait when wait=true. Default: 300. */\n timeout?: number;\n /** Seconds between status polls when wait=true. Default: 1. */\n pollInterval?: number;\n}\n\nexport interface CheckpointOptions extends SuspendResumeOptions {\n contentMode?: SnapshotContentMode;\n}\n\nexport interface ConnectOptions {\n sandboxId: string;\n proxyUrl?: string;\n routingHint?: string;\n}\n\n// --- JSON key conversion helpers ---\n\nconst CAMEL_TO_SNAKE_RE = /[A-Z]/g;\n\n/** Convert a camelCase string to snake_case. */\nexport function camelToSnake(str: string): string {\n return str.replace(CAMEL_TO_SNAKE_RE, (ch) => \"_\" + ch.toLowerCase());\n}\n\n/** Convert a snake_case string to camelCase. */\nexport function snakeToCamel(str: string): string {\n return str.replace(/_([a-z])/g, (_, ch) => ch.toUpperCase());\n}\n\n/** Recursively convert all object keys from camelCase to snake_case. */\nexport function toSnakeKeys(obj: unknown): unknown {\n if (Array.isArray(obj)) return obj.map(toSnakeKeys);\n if (obj !== null && typeof obj === \"object\" && !(obj instanceof Date)) {\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj as Record<string, unknown>)) {\n result[camelToSnake(k)] = toSnakeKeys(v);\n }\n return result;\n }\n return obj;\n}\n\n/**\n * Parse a numeric timestamp into a Date.\n *\n * Handles seconds, milliseconds, and microseconds by checking magnitude.\n */\nexport function parseTimestamp(v: unknown): Date | undefined {\n if (v == null) return undefined;\n if (v instanceof Date) return v;\n if (typeof v === \"string\") {\n const parsed = Date.parse(v);\n return Number.isNaN(parsed) ? undefined : new Date(parsed);\n }\n const ts = Number(v);\n if (isNaN(ts)) return undefined;\n if (ts > 1e15) return new Date(ts / 1000); // microseconds → ms\n if (ts > 1e12) return new Date(ts); // already ms\n return new Date(ts * 1000); // seconds → ms\n}\n\n/**\n * Recursively convert all object keys from snake_case to camelCase,\n * with special handling for `id` → contextual name and timestamp parsing.\n */\nexport function fromSnakeKeys(\n obj: unknown,\n idField?: string,\n): unknown {\n if (Array.isArray(obj)) return obj.map((item) => fromSnakeKeys(item, idField));\n if (obj !== null && typeof obj === \"object\" && !(obj instanceof Date)) {\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj as Record<string, unknown>)) {\n let key: string;\n if (k === \"id\" && idField) {\n key = idField;\n } else {\n key = snakeToCamel(k);\n }\n\n // Parse timestamp fields\n if (\n key.endsWith(\"At\") ||\n key === \"timestamp\" ||\n key === \"startedAt\" ||\n key === \"endedAt\"\n ) {\n result[key] = parseTimestamp(v);\n } else if (typeof v === \"object\" && v !== null && !Array.isArray(v)) {\n result[key] = fromSnakeKeys(v);\n } else if (Array.isArray(v)) {\n result[key] = v.map((item) => fromSnakeKeys(item));\n } else {\n // Normalize null → undefined so optional fields match TypeScript's ? convention.\n result[key] = v === null ? undefined : v;\n }\n }\n return result;\n }\n return obj;\n}\n","export const SDK_VERSION = \"0.4.49\";\n\nexport const API_URL =\n process.env.TENSORLAKE_API_URL ?? \"https://api.tensorlake.ai\";\nexport const API_KEY = process.env.TENSORLAKE_API_KEY ?? undefined;\nexport const NAMESPACE = process.env.INDEXIFY_NAMESPACE ?? \"default\";\nexport const SANDBOX_PROXY_URL =\n process.env.TENSORLAKE_SANDBOX_PROXY_URL ?? \"https://sandbox.tensorlake.ai\";\n\nexport const DEFAULT_HTTP_TIMEOUT_MS = 30_000;\nexport const MAX_RETRIES = 3;\nexport const RETRY_BACKOFF_MS = 500;\nexport const RETRYABLE_STATUS_CODES = new Set([429, 502, 503, 504]);\n","/** Base exception for all sandbox-related errors. */\nexport class SandboxException extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"SandboxException\";\n }\n}\n\n/** General sandbox operation error. */\nexport class SandboxError extends SandboxException {\n constructor(message: string) {\n super(message);\n this.name = \"SandboxError\";\n }\n}\n\n/** Raised when the client cannot connect to the API server. */\nexport class SandboxConnectionError extends SandboxError {\n constructor(message: string) {\n super(`Connection error: ${message}`);\n this.name = \"SandboxConnectionError\";\n }\n}\n\n/** Raised when a sandbox is not found. */\nexport class SandboxNotFoundError extends SandboxError {\n readonly sandboxId: string;\n\n constructor(sandboxId: string) {\n super(`Sandbox not found: ${sandboxId}`);\n this.name = \"SandboxNotFoundError\";\n this.sandboxId = sandboxId;\n }\n}\n\n/** Raised when a sandbox pool is not found. */\nexport class PoolNotFoundError extends SandboxError {\n readonly poolId: string;\n\n constructor(poolId: string) {\n super(`Sandbox pool not found: ${poolId}`);\n this.name = \"PoolNotFoundError\";\n this.poolId = poolId;\n }\n}\n\n/** Raised when attempting to delete a pool that is in use. */\nexport class PoolInUseError extends SandboxError {\n readonly poolId: string;\n\n constructor(poolId: string, message?: string) {\n const base = `Cannot delete pool ${poolId}: pool is in use`;\n super(message ? `${base} - ${message}` : base);\n this.name = \"PoolInUseError\";\n this.poolId = poolId;\n }\n}\n\n/** Raised when the remote API returns an error. */\nexport class RemoteAPIError extends SandboxError {\n readonly statusCode: number;\n readonly responseMessage: string;\n\n constructor(statusCode: number, message: string) {\n super(`API error (status ${statusCode}): ${message}`);\n this.name = \"RemoteAPIError\";\n this.statusCode = statusCode;\n this.responseMessage = message;\n }\n}\n\n/** Raised when request output is fetched before the request has completed. */\nexport class RequestNotFinishedError extends Error {\n constructor() {\n super(\"Request has not finished yet\");\n this.name = \"RequestNotFinishedError\";\n }\n}\n\n/** Raised when a request completed unsuccessfully. */\nexport class RequestFailedError extends Error {\n readonly failure: string;\n\n constructor(failure: string) {\n super(`Request failed: ${failure}`);\n this.name = \"RequestFailedError\";\n this.failure = failure;\n }\n}\n\n/** Raised when a request surfaced an application-level error. */\nexport class RequestExecutionError extends Error {\n readonly functionName?: string;\n\n constructor(message: string, functionName?: string) {\n super(\n functionName ? `Request error in ${functionName}: ${message}` : message,\n );\n this.name = \"RequestExecutionError\";\n this.functionName = functionName;\n }\n}\n","import {\n Agent,\n fetch as undiciFetch,\n setGlobalDispatcher,\n type BodyInit as UndiciBodyInit,\n} from \"undici\";\nimport * as defaults from \"./defaults.js\";\nimport {\n PoolInUseError,\n PoolNotFoundError,\n RemoteAPIError,\n SandboxConnectionError,\n SandboxNotFoundError,\n} from \"./errors.js\";\n\nexport interface HttpClientOptions {\n baseUrl: string;\n apiKey?: string;\n organizationId?: string;\n projectId?: string;\n hostHeader?: string;\n routingHint?: string;\n maxRetries?: number;\n retryBackoffMs?: number;\n timeoutMs?: number;\n}\n\nsetGlobalDispatcher(\n new Agent({\n keepAliveTimeout: 60_000,\n allowH2: true,\n }),\n);\n\ntype RequestBody = BodyInit | Uint8Array | ArrayBuffer;\n\nexport interface HttpRequestOptions {\n body?: RequestBody | null;\n headers?: Record<string, string>;\n json?: unknown;\n signal?: AbortSignal;\n allowHttpErrors?: boolean;\n}\n\n/**\n * The return value of every SDK operation. Carries the W3C `trace_id` so callers\n * can correlate a specific request with its server-side spans in Datadog APM or\n * any other OTEL-compatible backend.\n *\n * Because this is an intersection type, all properties of `T` are accessible\n * directly — existing code that ignores `traceId` continues to compile and run\n * unchanged.\n *\n * @example\n * const sandbox = await client.createSandbox(req);\n * console.log(sandbox.id); // existing field — unchanged\n * console.log(sandbox.traceId); // new: look this up in Datadog APM\n */\nexport type Traced<T> = T & { readonly traceId: string };\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction withTraceId<T>(value: T, traceId: string): Traced<T> {\n if (value == null) {\n return { traceId } as unknown as Traced<T>;\n }\n return Object.assign(value as any, { traceId }) as Traced<T>;\n}\n\n/**\n * Internal HTTP client with retry logic, auth headers, and error mapping.\n *\n * Uses native `fetch`. Retries on transient status codes (429, 502, 503, 504)\n * with exponential backoff.\n */\nexport class HttpClient {\n private readonly baseUrl: string;\n private readonly headers: Record<string, string>;\n private readonly maxRetries: number;\n private readonly retryBackoffMs: number;\n private readonly timeoutMs: number;\n private abortController: AbortController | null = null;\n\n constructor(options: HttpClientOptions) {\n const url = options.baseUrl;\n this.baseUrl = url.endsWith(\"/\") ? url.slice(0, -1) : url;\n this.maxRetries = options.maxRetries ?? defaults.MAX_RETRIES;\n this.retryBackoffMs = options.retryBackoffMs ?? defaults.RETRY_BACKOFF_MS;\n this.timeoutMs = options.timeoutMs ?? defaults.DEFAULT_HTTP_TIMEOUT_MS;\n\n this.headers = {\n \"User-Agent\": `tensorlake-typescript-sdk/${defaults.SDK_VERSION}`,\n };\n if (options.apiKey) {\n this.headers[\"Authorization\"] = `Bearer ${options.apiKey}`;\n }\n if (options.organizationId) {\n this.headers[\"X-Forwarded-Organization-Id\"] = options.organizationId;\n }\n if (options.projectId) {\n this.headers[\"X-Forwarded-Project-Id\"] = options.projectId;\n }\n if (options.hostHeader) {\n this.headers[\"Host\"] = options.hostHeader;\n }\n if (options.routingHint) {\n this.headers[\"X-Tensorlake-Route-Hint\"] = options.routingHint;\n }\n }\n\n close(): void {\n this.abortController?.abort();\n this.abortController = null;\n }\n\n /** Make a JSON request, returning the parsed response body. */\n async requestJson<T>(\n method: string,\n path: string,\n options?: {\n body?: unknown;\n headers?: Record<string, string>;\n signal?: AbortSignal;\n },\n ): Promise<Traced<T>> {\n const response = await this.requestResponse(method, path, {\n json: options?.body,\n headers: options?.headers,\n signal: options?.signal,\n });\n const text = await response.text();\n const data = (text ? JSON.parse(text) : undefined) as T;\n return withTraceId(data, response.traceId);\n }\n\n /** Make a request returning raw bytes. */\n async requestBytes(\n method: string,\n path: string,\n options?: {\n body?: RequestBody | null;\n contentType?: string;\n headers?: Record<string, string>;\n signal?: AbortSignal;\n },\n ): Promise<Traced<Uint8Array>> {\n const headers = { ...(options?.headers ?? {}) };\n if (options?.contentType) {\n headers[\"Content-Type\"] = options.contentType;\n }\n\n const response = await this.requestResponse(method, path, {\n body: options?.body,\n headers,\n signal: options?.signal,\n });\n const buffer = await response.arrayBuffer();\n return withTraceId(new Uint8Array(buffer), response.traceId);\n }\n\n /** Make a request and return the response body as an SSE stream. */\n async requestStream(\n method: string,\n path: string,\n options?: { signal?: AbortSignal; json?: unknown },\n ): Promise<Traced<ReadableStream<Uint8Array>>> {\n const response = await this.requestResponse(method, path, {\n json: options?.json,\n headers: { Accept: \"text/event-stream\" },\n signal: options?.signal,\n });\n if (!response.body) {\n throw new RemoteAPIError(\n response.status,\n \"No response body for SSE stream\",\n );\n }\n return withTraceId(response.body, response.traceId);\n }\n\n /** Make a request and return the raw Response. */\n async requestResponse(\n method: string,\n path: string,\n options?: HttpRequestOptions,\n ): Promise<Traced<Response>> {\n const headers = {\n ...this.headers,\n ...(options?.headers ?? {}),\n };\n const hasJsonBody = options?.json !== undefined;\n if (hasJsonBody && !hasHeader(headers, \"Content-Type\")) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n\n const body = hasJsonBody\n ? JSON.stringify(options?.json)\n : normalizeRequestBody(options?.body);\n\n const { response, traceId } = await this.doFetch(\n method,\n path,\n body,\n headers,\n options?.signal,\n options?.allowHttpErrors ?? false,\n );\n return withTraceId(response, traceId);\n }\n\n private static makeTraceparent(): { traceparent: string; traceId: string } {\n const randomHex = (bytes: number) =>\n Array.from(crypto.getRandomValues(new Uint8Array(bytes)))\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n const traceId = randomHex(16);\n const spanId = randomHex(8);\n return { traceparent: `00-${traceId}-${spanId}-01`, traceId };\n }\n\n private async doFetch(\n method: string,\n path: string,\n body: UndiciBodyInit | undefined,\n headers: Record<string, string>,\n signal?: AbortSignal,\n allowHttpErrors = false,\n ): Promise<{ response: Response; traceId: string }> {\n const url = `${this.baseUrl}${path}`;\n const { traceparent, traceId } = HttpClient.makeTraceparent();\n headers[\"traceparent\"] = traceparent;\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n if (attempt > 0) {\n const delay = this.retryBackoffMs * Math.pow(2, attempt - 1);\n await sleep(delay);\n }\n\n this.abortController = new AbortController();\n const timeoutId = setTimeout(\n () => this.abortController?.abort(),\n this.timeoutMs,\n );\n\n // Combine external signal with internal timeout\n const combinedSignal = signal\n ? anySignal([signal, this.abortController.signal])\n : this.abortController.signal;\n\n try {\n const response = (await undiciFetch(url, {\n method,\n headers,\n body,\n signal: combinedSignal,\n })) as Response;\n\n clearTimeout(timeoutId);\n\n if (response.ok) return { response, traceId };\n\n // Check if retryable\n if (\n defaults.RETRYABLE_STATUS_CODES.has(response.status) &&\n attempt < this.maxRetries\n ) {\n lastError = new RemoteAPIError(\n response.status,\n await response.text().catch(() => \"\"),\n );\n continue;\n }\n\n if (allowHttpErrors) {\n return { response, traceId };\n }\n\n // Non-retryable error — throw mapped error\n const errorBody = await response.text().catch(() => \"\");\n throwMappedError(response.status, errorBody, path);\n } catch (err) {\n clearTimeout(timeoutId);\n\n if (\n err instanceof RemoteAPIError ||\n err instanceof SandboxNotFoundError ||\n err instanceof PoolNotFoundError ||\n err instanceof PoolInUseError\n ) {\n throw err;\n }\n\n if (signal?.aborted) {\n throw new SandboxConnectionError(\"Request aborted\");\n }\n\n // Network / timeout error\n lastError = err instanceof Error ? err : new Error(String(err));\n\n if (attempt >= this.maxRetries) {\n throw new SandboxConnectionError(lastError.message);\n }\n }\n }\n\n throw new SandboxConnectionError(lastError?.message ?? \"Request failed\");\n }\n}\n\nfunction hasHeader(headers: Record<string, string>, name: string): boolean {\n const lowered = name.toLowerCase();\n return Object.keys(headers).some((key) => key.toLowerCase() === lowered);\n}\n\nfunction normalizeRequestBody(\n body?: RequestBody | null,\n): UndiciBodyInit | undefined {\n if (body == null) {\n return undefined;\n }\n if (body instanceof Uint8Array) {\n return Uint8Array.from(body).buffer as ArrayBuffer;\n }\n return body as UndiciBodyInit;\n}\n\n/** Map HTTP status codes to specific error types. */\nfunction throwMappedError(status: number, body: string, path: string): never {\n let message = body;\n try {\n const parsed = JSON.parse(body);\n if (parsed.message) message = parsed.message;\n else if (parsed.error) message = parsed.error;\n } catch {\n // use raw body\n }\n\n if (status === 404) {\n // Determine entity type from path\n if (path.includes(\"sandbox-pools\") || path.includes(\"pools\")) {\n const match = path.match(/sandbox-pools\\/([^/]+)/);\n if (match) throw new PoolNotFoundError(match[1]);\n }\n if (path.includes(\"sandboxes\")) {\n const match = path.match(/sandboxes\\/([^/]+)/);\n if (match) throw new SandboxNotFoundError(match[1]);\n }\n throw new RemoteAPIError(404, message);\n }\n\n if (status === 409) {\n if (path.includes(\"sandbox-pools\") || path.includes(\"pools\")) {\n const match = path.match(/sandbox-pools\\/([^/]+)/);\n if (match) throw new PoolInUseError(match[1], message);\n }\n }\n\n throw new RemoteAPIError(status, message);\n}\n\n/** Combine multiple AbortSignals into one that aborts when any fires. */\nfunction anySignal(signals: AbortSignal[]): AbortSignal {\n const controller = new AbortController();\n for (const signal of signals) {\n if (signal.aborted) {\n controller.abort(signal.reason);\n return controller.signal;\n }\n signal.addEventListener(\"abort\", () => controller.abort(signal.reason), {\n once: true,\n });\n }\n return controller.signal;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import * as net from \"node:net\";\nimport { SandboxConnectionError, SandboxError } from \"./errors.js\";\nimport WebSocket, { type RawData } from \"ws\";\n\nconst DEFAULT_TUNNEL_CONNECT_TIMEOUT_MS = 10_000;\nconst WEBSOCKET_KEEPALIVE_INTERVAL_MS = 15_000;\n\nexport interface CreateTunnelOptions {\n /** Local host/interface to bind. Defaults to `127.0.0.1`. */\n localHost?: string;\n /** Local port to bind. Defaults to the remote port. Use `0` for an ephemeral port. */\n localPort?: number;\n /** Seconds to wait for each websocket tunnel connection. Defaults to `10`. */\n connectTimeout?: number;\n}\n\nexport interface TunnelAddress {\n host: string;\n port: number;\n}\n\ninterface TunnelWebSocketOptions {\n baseUrl: string;\n wsHeaders: Record<string, string>;\n remotePort: number;\n connectTimeoutMs?: number;\n}\n\ninterface PendingRead {\n length: number;\n resolve: (chunk: Buffer) => void;\n reject: (error: Error) => void;\n}\n\ninterface ActiveRelay {\n localSocket: net.Socket;\n websocket: WebSocket | null;\n}\n\nexport async function openTunnelWebSocket(\n options: TunnelWebSocketOptions,\n): Promise<WebSocket> {\n const wsUrl = buildTunnelWsUrl(options.baseUrl, options.remotePort);\n const timeoutMs = options.connectTimeoutMs ?? DEFAULT_TUNNEL_CONNECT_TIMEOUT_MS;\n\n return new Promise<WebSocket>((resolve, reject) => {\n const socket = new WebSocket(wsUrl, {\n headers: options.wsHeaders,\n });\n\n let settled = false;\n const timer = setTimeout(() => {\n fail(\n new SandboxError(\n `timed out while connecting tunnel websocket after ${(timeoutMs / 1000).toFixed(2)}s`,\n ),\n );\n }, timeoutMs);\n\n const cleanup = () => {\n clearTimeout(timer);\n socket.removeListener(\"open\", onOpen);\n socket.removeListener(\"error\", onError);\n socket.removeListener(\"close\", onCloseBeforeOpen);\n socket.removeListener(\"unexpected-response\", onUnexpectedResponse);\n };\n\n const settle = (callback: () => void) => {\n if (settled) return;\n settled = true;\n cleanup();\n callback();\n };\n\n const fail = (error: Error) => {\n settle(() => {\n reject(error);\n });\n };\n\n const onOpen = () => {\n settle(() => resolve(socket));\n };\n\n const onError = (error: Error) => {\n fail(new SandboxConnectionError(error.message));\n };\n\n const onCloseBeforeOpen = (code: number, reason: Buffer) => {\n const closeReason =\n reason.length > 0 ? reason.toString(\"utf8\") : \"no reason\";\n fail(\n new SandboxError(\n `tunnel websocket closed before opening: ${code} ${closeReason}`,\n ),\n );\n };\n\n const onUnexpectedResponse = (\n _request: unknown,\n response: { statusCode?: number; statusMessage?: string },\n ) => {\n const status = response.statusCode ?? 0;\n const statusMessage = response.statusMessage?.trim();\n fail(\n new SandboxError(\n `tunnel websocket handshake failed with HTTP ${status}${statusMessage ? ` ${statusMessage}` : \"\"}`,\n ),\n );\n };\n\n socket.on(\"open\", onOpen);\n socket.on(\"error\", onError);\n socket.on(\"close\", onCloseBeforeOpen);\n socket.on(\"unexpected-response\", onUnexpectedResponse);\n });\n}\n\nexport class TunnelByteStream {\n private readonly socket: WebSocket;\n private readBuffer: Buffer = Buffer.alloc(0);\n private readonly pendingReads: PendingRead[] = [];\n private closeError: Error | null = null;\n private closePromise: Promise<void> | null = null;\n private readonly keepAliveInterval: ReturnType<typeof setInterval>;\n\n constructor(socket: WebSocket) {\n this.socket = socket;\n this.keepAliveInterval = setInterval(() => {\n if (socket.readyState === WebSocket.OPEN) {\n socket.ping();\n }\n }, WEBSOCKET_KEEPALIVE_INTERVAL_MS);\n this.keepAliveInterval.unref?.();\n\n socket.on(\"message\", (message: RawData, isBinary: boolean) => {\n if (!isBinary) {\n this.fail(\n new SandboxError(\"desktop tunnel received unexpected text frame\"),\n );\n return;\n }\n this.pushBytes(normalizeWebSocketData(message));\n });\n\n socket.on(\"ping\", (data: Buffer) => {\n if (socket.readyState === WebSocket.OPEN) {\n socket.pong(data, false, () => {});\n }\n });\n\n socket.on(\"close\", (_code: number, reason: Buffer) => {\n clearInterval(this.keepAliveInterval);\n const closeReason =\n reason.length > 0 ? reason.toString(\"utf8\") : \"desktop tunnel closed unexpectedly\";\n this.fail(new SandboxError(closeReason));\n });\n\n socket.on(\"error\", (error: Error) => {\n clearInterval(this.keepAliveInterval);\n this.fail(new SandboxConnectionError(error.message));\n });\n }\n\n static async connect(options: TunnelWebSocketOptions): Promise<TunnelByteStream> {\n const socket = await openTunnelWebSocket(options);\n return new TunnelByteStream(socket);\n }\n\n async readExactly(length: number): Promise<Buffer> {\n if (length < 0) {\n throw new SandboxError(`read length must be >= 0, got ${length}`);\n }\n if (length === 0) {\n return Buffer.alloc(0);\n }\n if (this.readBuffer.length >= length) {\n const chunk = this.readBuffer.subarray(0, length);\n this.readBuffer = this.readBuffer.subarray(length);\n return chunk;\n }\n if (this.closeError) {\n throw this.closeError;\n }\n return new Promise<Buffer>((resolve, reject) => {\n this.pendingReads.push({ length, resolve, reject });\n });\n }\n\n async writeAll(data: Uint8Array): Promise<void> {\n if (this.closeError) {\n throw this.closeError;\n }\n if (this.socket.readyState !== WebSocket.OPEN) {\n throw new SandboxError(\"desktop tunnel is not connected\");\n }\n const payload = Buffer.from(data);\n await new Promise<void>((resolve, reject) => {\n this.socket.send(payload, { binary: true }, (error?: Error) => {\n if (error) {\n reject(new SandboxConnectionError(error.message));\n return;\n }\n resolve();\n });\n });\n }\n\n async close(): Promise<void> {\n if (this.closePromise) {\n return this.closePromise;\n }\n if (\n this.socket.readyState === WebSocket.CLOSED ||\n this.socket.readyState === WebSocket.CLOSING\n ) {\n this.closePromise = Promise.resolve();\n return this.closePromise;\n }\n\n this.closePromise = new Promise<void>((resolve) => {\n const onClose = () => {\n this.socket.removeListener(\"close\", onClose);\n resolve();\n };\n this.socket.on(\"close\", onClose);\n this.socket.close();\n });\n return this.closePromise;\n }\n\n private pushBytes(chunk: Buffer): void {\n this.readBuffer =\n this.readBuffer.length === 0\n ? chunk\n : Buffer.from(Buffer.concat([this.readBuffer, chunk]));\n this.flushPendingReads();\n }\n\n private flushPendingReads(): void {\n while (this.pendingReads.length > 0) {\n const next = this.pendingReads[0];\n if (this.readBuffer.length < next.length) {\n break;\n }\n const chunk = this.readBuffer.subarray(0, next.length);\n this.readBuffer = this.readBuffer.subarray(next.length);\n this.pendingReads.shift();\n next.resolve(chunk);\n }\n }\n\n private fail(error: Error): void {\n if (this.closeError) {\n return;\n }\n this.closeError = error;\n while (this.pendingReads.length > 0) {\n const pending = this.pendingReads.shift();\n pending?.reject(error);\n }\n }\n}\n\nexport class TcpTunnel {\n readonly remotePort: number;\n readonly localHost: string;\n readonly localPort: number;\n\n private readonly baseUrl: string;\n private readonly wsHeaders: Record<string, string>;\n private readonly server: net.Server;\n private readonly connectTimeoutMs: number;\n private readonly activeRelays = new Set<ActiveRelay>();\n private closePromise: Promise<void> | null = null;\n\n private constructor(options: {\n baseUrl: string;\n wsHeaders: Record<string, string>;\n remotePort: number;\n localHost: string;\n localPort: number;\n server: net.Server;\n connectTimeoutMs: number;\n }) {\n this.baseUrl = options.baseUrl;\n this.wsHeaders = options.wsHeaders;\n this.remotePort = options.remotePort;\n this.localHost = options.localHost;\n this.localPort = options.localPort;\n this.server = options.server;\n this.connectTimeoutMs = options.connectTimeoutMs;\n }\n\n static async listen(options: {\n baseUrl: string;\n wsHeaders: Record<string, string>;\n remotePort: number;\n localHost?: string;\n localPort?: number;\n connectTimeout?: number;\n }): Promise<TcpTunnel> {\n const remotePort = validatePort(options.remotePort, \"remote port\");\n const localHost = options.localHost ?? \"127.0.0.1\";\n const localPort = validatePort(\n options.localPort ?? remotePort,\n \"local port\",\n true,\n );\n const connectTimeoutMs = secondsToMillis(options.connectTimeout ?? 10);\n\n const server = net.createServer();\n await listenServer(server, localPort, localHost);\n\n const address = server.address();\n if (!address || typeof address === \"string\") {\n server.close();\n throw new SandboxError(\"failed to determine bound tunnel address\");\n }\n\n const tunnel = new TcpTunnel({\n baseUrl: options.baseUrl,\n wsHeaders: options.wsHeaders,\n remotePort,\n localHost,\n localPort: address.port,\n server,\n connectTimeoutMs,\n });\n\n server.on(\"connection\", (localSocket) => {\n void tunnel.handleConnection(localSocket);\n });\n\n return tunnel;\n }\n\n address(): TunnelAddress {\n return { host: this.localHost, port: this.localPort };\n }\n\n async close(): Promise<void> {\n if (this.closePromise) {\n return this.closePromise;\n }\n\n for (const relay of this.activeRelays) {\n relay.localSocket.destroy();\n relay.websocket?.close();\n }\n\n this.closePromise = new Promise<void>((resolve, reject) => {\n this.server.close((error) => {\n if (error) {\n reject(new SandboxError(`failed to close tunnel listener: ${error.message}`));\n return;\n }\n resolve();\n });\n });\n return this.closePromise;\n }\n\n private async handleConnection(localSocket: net.Socket): Promise<void> {\n localSocket.setNoDelay(true);\n\n const relay: ActiveRelay = { localSocket, websocket: null };\n this.activeRelays.add(relay);\n\n try {\n relay.websocket = await openTunnelWebSocket({\n baseUrl: this.baseUrl,\n wsHeaders: this.wsHeaders,\n remotePort: this.remotePort,\n connectTimeoutMs: this.connectTimeoutMs,\n });\n await relaySocket(localSocket, relay.websocket);\n } catch (error) {\n localSocket.destroy(\n error instanceof Error ? error : new Error(String(error)),\n );\n } finally {\n this.activeRelays.delete(relay);\n }\n }\n}\n\nexport function buildTunnelWsUrl(baseUrl: string, remotePort: number): string {\n const url = new URL(baseUrl);\n url.protocol = url.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n url.pathname = \"/api/v1/tunnels/tcp\";\n url.search = `port=${encodeURIComponent(String(remotePort))}`;\n return url.toString();\n}\n\nfunction normalizeWebSocketData(message: RawData): Buffer {\n if (Buffer.isBuffer(message)) return message;\n if (Array.isArray(message)) {\n return Buffer.concat(message.map((part) => Buffer.from(part)));\n }\n return Buffer.from(message);\n}\n\nasync function relaySocket(localSocket: net.Socket, websocket: WebSocket): Promise<void> {\n return new Promise<void>((resolve) => {\n let settled = false;\n const keepAliveInterval = setInterval(() => {\n if (websocket.readyState === WebSocket.OPEN) {\n websocket.ping();\n }\n }, WEBSOCKET_KEEPALIVE_INTERVAL_MS);\n keepAliveInterval.unref?.();\n\n const finish = () => {\n if (settled) return;\n settled = true;\n clearInterval(keepAliveInterval);\n cleanup();\n resolve();\n };\n\n const cleanup = () => {\n localSocket.removeListener(\"data\", onLocalData);\n localSocket.removeListener(\"end\", onLocalEnd);\n localSocket.removeListener(\"close\", onLocalClose);\n localSocket.removeListener(\"error\", onLocalError);\n websocket.removeListener(\"message\", onWsMessage);\n websocket.removeListener(\"close\", onWsClose);\n websocket.removeListener(\"error\", onWsError);\n websocket.removeListener(\"ping\", onWsPing);\n };\n\n const onLocalData = (chunk: Buffer) => {\n if (websocket.readyState !== WebSocket.OPEN) {\n localSocket.destroy();\n return;\n }\n\n websocket.send(chunk, { binary: true }, (error?: Error) => {\n if (error) {\n localSocket.destroy(error);\n }\n });\n };\n\n const onLocalEnd = () => {\n if (websocket.readyState === WebSocket.OPEN) {\n websocket.close();\n }\n };\n\n const onLocalClose = () => {\n if (\n websocket.readyState === WebSocket.OPEN ||\n websocket.readyState === WebSocket.CONNECTING\n ) {\n websocket.close();\n }\n finish();\n };\n\n const onLocalError = () => {\n websocket.close();\n finish();\n };\n\n const onWsMessage = (message: RawData, isBinary: boolean) => {\n if (!isBinary) {\n localSocket.destroy(\n new SandboxError(\"received unexpected text frame from tunnel\"),\n );\n websocket.close();\n return;\n }\n\n const payload = normalizeWebSocketData(message);\n if (!localSocket.destroyed) {\n localSocket.write(payload);\n }\n };\n\n const onWsClose = () => {\n if (!localSocket.destroyed) {\n localSocket.end();\n }\n finish();\n };\n\n const onWsError = (error: Error) => {\n localSocket.destroy(error);\n finish();\n };\n\n const onWsPing = (data: Buffer) => {\n if (websocket.readyState === WebSocket.OPEN) {\n websocket.pong(data, false, () => {});\n }\n };\n\n localSocket.on(\"data\", onLocalData);\n localSocket.on(\"end\", onLocalEnd);\n localSocket.on(\"close\", onLocalClose);\n localSocket.on(\"error\", onLocalError);\n websocket.on(\"message\", onWsMessage);\n websocket.on(\"close\", onWsClose);\n websocket.on(\"error\", onWsError);\n websocket.on(\"ping\", onWsPing);\n });\n}\n\nasync function listenServer(\n server: net.Server,\n localPort: number,\n localHost: string,\n): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n const onError = (error: Error) => {\n server.removeListener(\"listening\", onListening);\n reject(\n new SandboxError(\n `failed to bind local tunnel listener on ${localHost}:${localPort}: ${error.message}`,\n ),\n );\n };\n\n const onListening = () => {\n server.removeListener(\"error\", onError);\n resolve();\n };\n\n server.once(\"error\", onError);\n server.once(\"listening\", onListening);\n server.listen(localPort, localHost);\n });\n}\n\nfunction validatePort(port: number, label: string, allowZero = false): number {\n if (!Number.isInteger(port)) {\n throw new SandboxError(`${label} must be an integer, got ${port}`);\n }\n if (allowZero && port === 0) {\n return port;\n }\n if (port < 1 || port > 65535) {\n throw new SandboxError(`${label} must be between 1 and 65535, got ${port}`);\n }\n return port;\n}\n\nfunction secondsToMillis(seconds: number): number {\n if (!Number.isFinite(seconds) || seconds < 0) {\n throw new SandboxError(`timeout must be >= 0 seconds, got ${seconds}`);\n }\n return Math.round(seconds * 1000);\n}\n\nexport async function withTimeout<T>(\n timeoutMs: number,\n operation: () => Promise<T>,\n timeoutMessage: string,\n): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(() => {\n reject(new SandboxError(timeoutMessage));\n }, timeoutMs);\n\n void operation()\n .then((value) => {\n clearTimeout(timer);\n resolve(value);\n })\n .catch((error) => {\n clearTimeout(timer);\n reject(error);\n });\n });\n}\n","import { deflateSync } from \"node:zlib\";\nimport { SandboxError } from \"./errors.js\";\nimport { TunnelByteStream, withTimeout } from \"./tunnel.js\";\n\nconst SECURITY_TYPE_NONE = 1;\nconst SECURITY_TYPE_VNC_AUTH = 2;\nconst ENCODING_RAW = 0;\nconst ENCODING_DESKTOP_SIZE = -223;\n\nconst BUTTON_LEFT_MASK = 1;\nconst BUTTON_MIDDLE_MASK = 1 << 1;\nconst BUTTON_RIGHT_MASK = 1 << 2;\nconst BUTTON_SCROLL_UP_MASK = 1 << 3;\nconst BUTTON_SCROLL_DOWN_MASK = 1 << 4;\n\nconst PNG_SIGNATURE = Buffer.from([\n 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a,\n]);\n\nconst CRC32_TABLE = buildCrc32Table();\n\nexport type MouseButton = \"left\" | \"middle\" | \"right\";\n\nexport interface ConnectDesktopOptions {\n /** Remote VNC port. Defaults to `5901`. */\n port?: number;\n /** Optional VNC password for classic VNC authentication. */\n password?: string;\n /** Whether to request a shared VNC session. Defaults to `true`. */\n shared?: boolean;\n /** Seconds to wait while opening the desktop session. Defaults to `10`. */\n connectTimeout?: number;\n}\n\nexport interface DesktopPointerOptions {\n button?: MouseButton;\n x?: number;\n y?: number;\n}\n\nexport interface DesktopDoubleClickOptions extends DesktopPointerOptions {\n delayMs?: number;\n}\n\ninterface DesktopConnectRequest extends ConnectDesktopOptions {\n baseUrl: string;\n wsHeaders: Record<string, string>;\n}\n\ninterface FramebufferUpdateOutcome {\n kind: \"framebufferUpdate\";\n sawResize: boolean;\n sawRaw: boolean;\n}\n\ninterface BellOutcome {\n kind: \"bell\";\n}\n\ninterface ServerCutTextOutcome {\n kind: \"serverCutText\";\n}\n\ntype ServerMessageOutcome =\n | FramebufferUpdateOutcome\n | BellOutcome\n | ServerCutTextOutcome;\n\nexport interface DesktopTransport {\n readExactly(length: number): Promise<Buffer>;\n writeAll(data: Uint8Array): Promise<void>;\n close(): Promise<void>;\n}\n\nexport class DesktopSession<T extends DesktopTransport> {\n readonly transport: T;\n width: number;\n height: number;\n\n private pixelFormat: PixelFormat;\n private framebuffer: Uint8Array;\n private pointerX = 0;\n private pointerY = 0;\n private buttonMask = 0;\n private framebufferVersion = 0;\n private closed = false;\n private updateLoopError: Error | null = null;\n private readonly updateSignal = createDeferredSignal();\n private updateLoopPromise: Promise<void> | null = null;\n\n constructor(options: {\n transport: T;\n width: number;\n height: number;\n pixelFormat: PixelFormat;\n framebuffer: Uint8Array;\n }) {\n this.transport = options.transport;\n this.width = options.width;\n this.height = options.height;\n this.pixelFormat = options.pixelFormat;\n this.framebuffer = options.framebuffer;\n }\n\n static async connect<T extends DesktopTransport>(\n transport: T,\n password?: string,\n shared = true,\n ): Promise<DesktopSession<T>> {\n const serverVersion = await ProtocolVersion.read(transport);\n const clientVersion = serverVersion.negotiated();\n await transport.writeAll(Buffer.from(clientVersion.render(), \"ascii\"));\n\n await negotiateSecurity(transport, clientVersion, password);\n await transport.writeAll(Uint8Array.of(shared ? 1 : 0));\n\n const init = await ServerInit.read(transport);\n if (!init.pixelFormat.trueColor) {\n throw new SandboxError(\n \"desktop sessions require a true-color VNC pixel format\",\n );\n }\n\n const pixelFormat = PixelFormat.preferred();\n await sendSetPixelFormat(transport, pixelFormat);\n await sendSetEncodings(transport, [ENCODING_RAW, ENCODING_DESKTOP_SIZE]);\n\n const session = new DesktopSession({\n transport,\n width: init.width,\n height: init.height,\n pixelFormat,\n framebuffer: allocateFramebuffer(init.width, init.height),\n });\n session.startFramebufferUpdates();\n return session;\n }\n\n async close(): Promise<void> {\n this.closed = true;\n this.updateSignal.resolve();\n await this.transport.close();\n await this.updateLoopPromise;\n }\n\n async screenshot(timeoutSeconds = 5): Promise<Uint8Array> {\n await this.waitForFramebufferVersion(\n 1,\n timeoutSeconds,\n `timed out waiting for initial desktop framebuffer after ${timeoutSeconds.toFixed(2)}s`,\n );\n return encodePng(this.width, this.height, this.framebuffer);\n }\n\n getFrameVersion(): number {\n return this.framebufferVersion;\n }\n\n async screenshotAfter(frameVersion: number, timeoutSeconds = 1): Promise<Uint8Array> {\n const minimumVersion = validateNonNegativeInteger(frameVersion, \"frame version\") + 1;\n\n if (this.framebufferVersion < minimumVersion) {\n await this.waitForFramebufferVersion(\n minimumVersion,\n timeoutSeconds,\n `timed out waiting for a fresher desktop framebuffer after ${timeoutSeconds.toFixed(2)}s`,\n );\n }\n\n return encodePng(this.width, this.height, this.framebuffer);\n }\n\n async moveMouse(x: number, y: number): Promise<void> {\n const nextX = validateCoordinate(x, \"mouse x coordinate\");\n const nextY = validateCoordinate(y, \"mouse y coordinate\");\n this.ensurePointerInBounds(nextX, nextY);\n this.pointerX = nextX;\n this.pointerY = nextY;\n await sendPointerEvent(this.transport, this.buttonMask, nextX, nextY);\n }\n\n async mousePress(options?: DesktopPointerOptions): Promise<void> {\n const button = options?.button ?? \"left\";\n await this.moveIfRequested(options?.x, options?.y);\n this.buttonMask |= buttonMask(button);\n await sendPointerEvent(\n this.transport,\n this.buttonMask,\n this.pointerX,\n this.pointerY,\n );\n }\n\n async mouseRelease(options?: DesktopPointerOptions): Promise<void> {\n const button = options?.button ?? \"left\";\n await this.moveIfRequested(options?.x, options?.y);\n this.buttonMask &= ~buttonMask(button);\n await sendPointerEvent(\n this.transport,\n this.buttonMask,\n this.pointerX,\n this.pointerY,\n );\n }\n\n async click(options?: DesktopPointerOptions): Promise<void> {\n await this.mousePress(options);\n await this.mouseRelease({ button: options?.button ?? \"left\" });\n }\n\n async doubleClick(options?: DesktopDoubleClickOptions): Promise<void> {\n const button = options?.button ?? \"left\";\n const delayMs = options?.delayMs ?? 50;\n validateNonNegativeInteger(delayMs, \"double click delay\");\n\n await this.click({ button, x: options?.x, y: options?.y });\n if (delayMs > 0) {\n await new Promise((resolve) => setTimeout(resolve, delayMs));\n }\n await this.click({ button });\n }\n\n async scroll(steps: number, x?: number, y?: number): Promise<void> {\n const normalizedSteps = validateInteger(steps, \"scroll steps\");\n await this.moveIfRequested(x, y);\n\n if (normalizedSteps === 0) {\n return;\n }\n\n const wheelMask =\n normalizedSteps > 0 ? BUTTON_SCROLL_UP_MASK : BUTTON_SCROLL_DOWN_MASK;\n const stepCount = Math.abs(normalizedSteps);\n for (let index = 0; index < stepCount; index += 1) {\n await sendPointerEvent(\n this.transport,\n this.buttonMask | wheelMask,\n this.pointerX,\n this.pointerY,\n );\n await sendPointerEvent(\n this.transport,\n this.buttonMask,\n this.pointerX,\n this.pointerY,\n );\n }\n }\n\n async keyDown(key: string): Promise<void> {\n await sendKeyEvent(this.transport, true, keysymFromKeyName(key));\n }\n\n async keyUp(key: string): Promise<void> {\n await sendKeyEvent(this.transport, false, keysymFromKeyName(key));\n }\n\n async press(keys: string | string[]): Promise<void> {\n const parts = Array.isArray(keys) ? keys : [keys];\n if (parts.length === 0) {\n throw new SandboxError(\"desktop press requires at least one key\");\n }\n\n const keysyms = parts.map((part) => keysymFromKeyName(part));\n if (keysyms.length === 1) {\n await sendKeyEvent(this.transport, true, keysyms[0]);\n await sendKeyEvent(this.transport, false, keysyms[0]);\n return;\n }\n\n for (const keysym of keysyms.slice(0, -1)) {\n await sendKeyEvent(this.transport, true, keysym);\n }\n\n const last = keysyms[keysyms.length - 1];\n await sendKeyEvent(this.transport, true, last);\n await sendKeyEvent(this.transport, false, last);\n\n for (const keysym of keysyms.slice(0, -1).reverse()) {\n await sendKeyEvent(this.transport, false, keysym);\n }\n }\n\n async typeText(text: string): Promise<void> {\n for (const char of text) {\n const keysym = keysymFromChar(char);\n await sendKeyEvent(this.transport, true, keysym);\n await sendKeyEvent(this.transport, false, keysym);\n }\n }\n\n private async moveIfRequested(x?: number, y?: number): Promise<void> {\n if (x == null && y == null) {\n return;\n }\n if (x == null || y == null) {\n throw new SandboxError(\n \"desktop pointer actions require both x and y when specifying coordinates\",\n );\n }\n await this.moveMouse(x, y);\n }\n\n private ensurePointerInBounds(x: number, y: number): void {\n if (this.width > 0 && x >= this.width) {\n throw new SandboxError(\n `mouse x coordinate ${x} is outside desktop width ${this.width}`,\n );\n }\n if (this.height > 0 && y >= this.height) {\n throw new SandboxError(\n `mouse y coordinate ${y} is outside desktop height ${this.height}`,\n );\n }\n }\n\n private startFramebufferUpdates(): void {\n if (this.updateLoopPromise) {\n return;\n }\n\n this.updateLoopPromise = this.runFramebufferUpdateLoop().catch((error: unknown) => {\n if (this.closed) {\n return;\n }\n this.updateLoopError = normalizeError(error);\n this.updateSignal.resolve();\n });\n }\n\n private async runFramebufferUpdateLoop(): Promise<void> {\n let incremental = false;\n\n while (!this.closed) {\n await sendFramebufferUpdateRequest(\n this.transport,\n incremental,\n 0,\n 0,\n this.width,\n this.height,\n );\n\n const outcome = await this.readUntilFramebufferUpdate();\n if (outcome.sawResize && !outcome.sawRaw) {\n incremental = false;\n continue;\n }\n\n if (outcome.sawRaw) {\n this.framebufferVersion += 1;\n this.updateSignal.resolve();\n }\n\n incremental = true;\n }\n }\n\n private async readUntilFramebufferUpdate(): Promise<FramebufferUpdateOutcome> {\n while (true) {\n const outcome = await this.readServerMessage();\n if (outcome.kind === \"framebufferUpdate\") {\n return outcome;\n }\n }\n }\n\n private async waitForFramebufferVersion(\n minimumVersion: number,\n timeoutSeconds: number,\n timeoutMessage: string,\n ): Promise<void> {\n const timeoutMs = secondsToMillis(timeoutSeconds);\n const deadline = Date.now() + timeoutMs;\n\n while (this.framebufferVersion < minimumVersion) {\n if (this.updateLoopError) {\n throw this.updateLoopError;\n }\n if (this.closed) {\n throw new SandboxError(\"desktop session is closed\");\n }\n\n const observedVersion = this.framebufferVersion;\n const waitForUpdate = this.updateSignal.wait();\n if (this.framebufferVersion !== observedVersion) {\n continue;\n }\n\n const remainingMs = Math.max(0, deadline - Date.now());\n if (remainingMs === 0) {\n break;\n }\n\n await withTimeout(remainingMs, () => waitForUpdate, timeoutMessage);\n }\n\n if (this.framebufferVersion < minimumVersion) {\n throw new SandboxError(timeoutMessage);\n }\n }\n\n private async readServerMessage(): Promise<ServerMessageOutcome> {\n const messageType = await readU8(this.transport);\n if (messageType === 0) {\n return this.readFramebufferUpdate();\n }\n if (messageType === 1) {\n await this.readSetColorMapEntries();\n return { kind: \"bell\" };\n }\n if (messageType === 2) {\n return { kind: \"bell\" };\n }\n if (messageType === 3) {\n await this.readServerCutText();\n return { kind: \"serverCutText\" };\n }\n throw new SandboxError(`unsupported VNC server message type ${messageType}`);\n }\n\n private async readFramebufferUpdate(): Promise<FramebufferUpdateOutcome> {\n await readU8(this.transport);\n const rectangleCount = await readU16(this.transport);\n let sawResize = false;\n let sawRaw = false;\n\n for (let index = 0; index < rectangleCount; index += 1) {\n const x = await readU16(this.transport);\n const y = await readU16(this.transport);\n const width = await readU16(this.transport);\n const height = await readU16(this.transport);\n const encoding = await readI32(this.transport);\n\n if (encoding === ENCODING_RAW) {\n const bytesPerPixel = this.pixelFormat.bytesPerPixel();\n const length = width * height * bytesPerPixel;\n const data = await this.transport.readExactly(length);\n this.blitRawRectangle(x, y, width, height, data);\n sawRaw = true;\n continue;\n }\n\n if (encoding === ENCODING_DESKTOP_SIZE) {\n this.resizeFramebuffer(width, height);\n sawResize = true;\n continue;\n }\n\n throw new SandboxError(`unsupported VNC rectangle encoding ${encoding}`);\n }\n\n return { kind: \"framebufferUpdate\", sawResize, sawRaw };\n }\n\n private async readSetColorMapEntries(): Promise<void> {\n await readU8(this.transport);\n await readU16(this.transport);\n const colorCount = await readU16(this.transport);\n await this.transport.readExactly(colorCount * 6);\n throw new SandboxError(\n \"desktop sessions do not support color-map VNC pixel formats\",\n );\n }\n\n private async readServerCutText(): Promise<void> {\n await this.transport.readExactly(3);\n const length = await readU32(this.transport);\n await this.transport.readExactly(length);\n }\n\n private resizeFramebuffer(width: number, height: number): void {\n this.width = width;\n this.height = height;\n this.framebuffer = allocateFramebuffer(width, height);\n this.pointerX = width > 0 ? Math.min(this.pointerX, width - 1) : 0;\n this.pointerY = height > 0 ? Math.min(this.pointerY, height - 1) : 0;\n }\n\n private blitRawRectangle(\n x: number,\n y: number,\n width: number,\n height: number,\n data: Uint8Array,\n ): void {\n if (x + width > this.width || y + height > this.height) {\n throw new SandboxError(\"desktop raw rectangle exceeds framebuffer bounds\");\n }\n\n const bytesPerPixel = this.pixelFormat.bytesPerPixel();\n for (let row = 0; row < height; row += 1) {\n for (let col = 0; col < width; col += 1) {\n const srcIndex = (row * width + col) * bytesPerPixel;\n const rgba = this.pixelFormat.decodePixel(\n data.subarray(srcIndex, srcIndex + bytesPerPixel),\n );\n const dstIndex = ((y + row) * this.width + x + col) * 4;\n this.framebuffer.set(rgba, dstIndex);\n }\n }\n }\n}\n\nexport class Desktop {\n private session: DesktopSession<TunnelByteStream>;\n private readonly connectRequest: DesktopConnectRequest & {\n port: number;\n shared: boolean;\n connectTimeout: number;\n };\n private operationChain: Promise<void> = Promise.resolve();\n private reconnectPromise: Promise<void> | null = null;\n private closed = false;\n\n private constructor(\n session: DesktopSession<TunnelByteStream>,\n connectRequest: DesktopConnectRequest & {\n port: number;\n shared: boolean;\n connectTimeout: number;\n },\n ) {\n this.session = session;\n this.connectRequest = connectRequest;\n }\n\n static async connect(options: DesktopConnectRequest): Promise<Desktop> {\n const connectRequest = normalizeDesktopConnectRequest(options);\n const session = await openDesktopSession(connectRequest);\n return new Desktop(session, connectRequest);\n }\n\n get width(): number {\n return this.session.width;\n }\n\n get height(): number {\n return this.session.height;\n }\n\n async close(): Promise<void> {\n this.closed = true;\n await this.enqueue(() => this.session.close());\n }\n\n async screenshot(timeout = 5): Promise<Uint8Array> {\n return this.enqueue(() => this.captureScreenshot(timeout));\n }\n\n getFrameVersion(): number {\n return this.session.getFrameVersion();\n }\n\n async screenshotAfter(frameVersion: number, timeout = 1): Promise<Uint8Array> {\n return this.enqueue(() => this.captureScreenshotAfter(frameVersion, timeout));\n }\n\n async moveMouse(x: number, y: number): Promise<void> {\n await this.enqueue(() => this.session.moveMouse(x, y));\n }\n\n async mousePress(options?: DesktopPointerOptions): Promise<void> {\n await this.enqueue(() => this.session.mousePress(options));\n }\n\n async mouseRelease(options?: DesktopPointerOptions): Promise<void> {\n await this.enqueue(() => this.session.mouseRelease(options));\n }\n\n async click(options?: DesktopPointerOptions): Promise<void> {\n await this.enqueue(() => this.session.click(options));\n }\n\n async doubleClick(options?: DesktopDoubleClickOptions): Promise<void> {\n await this.enqueue(() => this.session.doubleClick(options));\n }\n\n async leftClick(x?: number, y?: number): Promise<void> {\n await this.click({ button: \"left\", x, y });\n }\n\n async middleClick(x?: number, y?: number): Promise<void> {\n await this.click({ button: \"middle\", x, y });\n }\n\n async rightClick(x?: number, y?: number): Promise<void> {\n await this.click({ button: \"right\", x, y });\n }\n\n async scroll(steps: number, x?: number, y?: number): Promise<void> {\n await this.enqueue(() => this.session.scroll(steps, x, y));\n }\n\n async scrollUp(steps = 1, x?: number, y?: number): Promise<void> {\n await this.scroll(Math.abs(steps), x, y);\n }\n\n async scrollDown(steps = 1, x?: number, y?: number): Promise<void> {\n await this.scroll(-Math.abs(steps), x, y);\n }\n\n async keyDown(key: string): Promise<void> {\n await this.enqueue(() => this.session.keyDown(key));\n }\n\n async keyUp(key: string): Promise<void> {\n await this.enqueue(() => this.session.keyUp(key));\n }\n\n async press(keys: string | string[]): Promise<void> {\n await this.enqueue(() => this.session.press(keys));\n }\n\n async typeText(text: string): Promise<void> {\n await this.enqueue(() => this.session.typeText(text));\n }\n\n private enqueue<T>(operation: () => Promise<T>): Promise<T> {\n const run = this.operationChain.catch(() => {}).then(operation);\n this.operationChain = run.then(\n () => undefined,\n () => undefined,\n );\n return run;\n }\n\n private async captureScreenshot(timeout: number): Promise<Uint8Array> {\n try {\n return await this.session.screenshot(timeout);\n } catch (error) {\n if (!isReconnectableDesktopScreenshotError(error) || this.closed) {\n throw error;\n }\n\n await this.reconnect();\n return this.session.screenshot(timeout);\n }\n }\n\n private async captureScreenshotAfter(\n frameVersion: number,\n timeout: number,\n ): Promise<Uint8Array> {\n try {\n return await this.session.screenshotAfter(frameVersion, timeout);\n } catch (error) {\n if (!isReconnectableDesktopScreenshotError(error) || this.closed) {\n throw error;\n }\n\n await this.reconnect();\n return this.session.screenshot(timeout);\n }\n }\n\n private async reconnect(): Promise<void> {\n if (this.reconnectPromise) {\n return this.reconnectPromise;\n }\n\n this.reconnectPromise = this.performReconnect().finally(() => {\n this.reconnectPromise = null;\n });\n return this.reconnectPromise;\n }\n\n private async performReconnect(): Promise<void> {\n const previousSession = this.session;\n await previousSession.close().catch(() => {});\n this.session = await openDesktopSession(this.connectRequest);\n }\n}\n\nclass ProtocolVersion {\n readonly major: number;\n readonly minor: number;\n\n constructor(major: number, minor: number) {\n this.major = major;\n this.minor = minor;\n }\n\n static async read(transport: DesktopTransport): Promise<ProtocolVersion> {\n const raw = await transport.readExactly(12);\n const text = raw.toString(\"ascii\");\n const trimmed = text.endsWith(\"\\n\") ? text.slice(0, -1) : text;\n const match = /^RFB (\\d{3})\\.(\\d{3})$/.exec(trimmed);\n if (!match) {\n throw new SandboxError(`invalid VNC protocol banner \\`${text}\\``);\n }\n return new ProtocolVersion(Number.parseInt(match[1], 10), Number.parseInt(match[2], 10));\n }\n\n negotiated(): ProtocolVersion {\n if (this.major !== 3 || this.minor >= 8) {\n return new ProtocolVersion(3, 8);\n }\n if (this.minor >= 7) {\n return new ProtocolVersion(3, 7);\n }\n return new ProtocolVersion(3, 3);\n }\n\n render(): string {\n return `RFB ${String(this.major).padStart(3, \"0\")}.${String(this.minor).padStart(3, \"0\")}\\n`;\n }\n}\n\nclass PixelFormat {\n readonly bitsPerPixel: number;\n readonly depth: number;\n readonly bigEndian: boolean;\n readonly trueColor: boolean;\n readonly redMax: number;\n readonly greenMax: number;\n readonly blueMax: number;\n readonly redShift: number;\n readonly greenShift: number;\n readonly blueShift: number;\n\n constructor(options: {\n bitsPerPixel: number;\n depth: number;\n bigEndian: boolean;\n trueColor: boolean;\n redMax: number;\n greenMax: number;\n blueMax: number;\n redShift: number;\n greenShift: number;\n blueShift: number;\n }) {\n this.bitsPerPixel = options.bitsPerPixel;\n this.depth = options.depth;\n this.bigEndian = options.bigEndian;\n this.trueColor = options.trueColor;\n this.redMax = options.redMax;\n this.greenMax = options.greenMax;\n this.blueMax = options.blueMax;\n this.redShift = options.redShift;\n this.greenShift = options.greenShift;\n this.blueShift = options.blueShift;\n }\n\n static preferred(): PixelFormat {\n return new PixelFormat({\n bitsPerPixel: 32,\n depth: 24,\n bigEndian: false,\n trueColor: true,\n redMax: 255,\n greenMax: 255,\n blueMax: 255,\n redShift: 16,\n greenShift: 8,\n blueShift: 0,\n });\n }\n\n static parse(bytes: Uint8Array): PixelFormat {\n if (bytes.length !== 16) {\n throw new SandboxError(\"invalid VNC pixel format payload length\");\n }\n return new PixelFormat({\n bitsPerPixel: bytes[0],\n depth: bytes[1],\n bigEndian: bytes[2] !== 0,\n trueColor: bytes[3] !== 0,\n redMax: Buffer.from(bytes.subarray(4, 6)).readUInt16BE(0),\n greenMax: Buffer.from(bytes.subarray(6, 8)).readUInt16BE(0),\n blueMax: Buffer.from(bytes.subarray(8, 10)).readUInt16BE(0),\n redShift: bytes[10],\n greenShift: bytes[11],\n blueShift: bytes[12],\n });\n }\n\n bytesPerPixel(): number {\n return this.bitsPerPixel / 8;\n }\n\n encode(): Uint8Array {\n const bytes = Buffer.alloc(16);\n bytes[0] = this.bitsPerPixel;\n bytes[1] = this.depth;\n bytes[2] = this.bigEndian ? 1 : 0;\n bytes[3] = this.trueColor ? 1 : 0;\n bytes.writeUInt16BE(this.redMax, 4);\n bytes.writeUInt16BE(this.greenMax, 6);\n bytes.writeUInt16BE(this.blueMax, 8);\n bytes[10] = this.redShift;\n bytes[11] = this.greenShift;\n bytes[12] = this.blueShift;\n return bytes;\n }\n\n decodePixel(bytes: Uint8Array): Uint8Array {\n if (bytes.length !== this.bytesPerPixel()) {\n throw new SandboxError(\"desktop pixel buffer has an unexpected size\");\n }\n\n let value = 0;\n if (this.bigEndian) {\n for (const byte of bytes) {\n value = (value << 8) | byte;\n }\n } else {\n for (let index = 0; index < bytes.length; index += 1) {\n value |= bytes[index] << (index * 8);\n }\n }\n\n const red = scaleChannel((value >> this.redShift) & this.redMax, this.redMax);\n const green = scaleChannel(\n (value >> this.greenShift) & this.greenMax,\n this.greenMax,\n );\n const blue = scaleChannel((value >> this.blueShift) & this.blueMax, this.blueMax);\n return Uint8Array.of(red, green, blue, 255);\n }\n}\n\nclass ServerInit {\n readonly width: number;\n readonly height: number;\n readonly pixelFormat: PixelFormat;\n\n constructor(width: number, height: number, pixelFormat: PixelFormat) {\n this.width = width;\n this.height = height;\n this.pixelFormat = pixelFormat;\n }\n\n static async read(transport: DesktopTransport): Promise<ServerInit> {\n const width = await readU16(transport);\n const height = await readU16(transport);\n const pixelFormat = PixelFormat.parse(await transport.readExactly(16));\n const nameLength = await readU32(transport);\n await transport.readExactly(nameLength);\n return new ServerInit(width, height, pixelFormat);\n }\n}\n\nasync function negotiateSecurity(\n transport: DesktopTransport,\n version: ProtocolVersion,\n password?: string,\n): Promise<number> {\n let securityTypes: number[];\n\n if (version.minor === 3) {\n const securityType = await readU32(transport);\n if (securityType === 0) {\n const reasonLength = await readU32(transport);\n const reason = (await transport.readExactly(reasonLength)).toString(\"utf8\");\n throw new SandboxError(`VNC security negotiation failed: ${reason}`);\n }\n securityTypes = [securityType];\n } else {\n const count = await readU8(transport);\n if (count === 0) {\n const reasonLength = await readU32(transport);\n const reason = (await transport.readExactly(reasonLength)).toString(\"utf8\");\n throw new SandboxError(`VNC security negotiation failed: ${reason}`);\n }\n securityTypes = [...(await transport.readExactly(count))];\n }\n\n let selected: number;\n if (password != null && securityTypes.includes(SECURITY_TYPE_VNC_AUTH)) {\n selected = SECURITY_TYPE_VNC_AUTH;\n } else if (securityTypes.includes(SECURITY_TYPE_NONE)) {\n selected = SECURITY_TYPE_NONE;\n } else if (securityTypes.includes(SECURITY_TYPE_VNC_AUTH)) {\n throw new SandboxError(\n \"VNC server requires password authentication but no password was provided\",\n );\n } else {\n throw new SandboxError(\n `unsupported VNC security types advertised by server: [${securityTypes.join(\", \")}]`,\n );\n }\n\n if (version.minor >= 7) {\n await transport.writeAll(Uint8Array.of(selected));\n }\n\n if (selected === SECURITY_TYPE_VNC_AUTH) {\n if (password == null) {\n throw new SandboxError(\n \"VNC server requires password authentication but no password was provided\",\n );\n }\n const challenge = await transport.readExactly(16);\n const response = encryptVncChallenge(Buffer.from(password, \"utf8\"), challenge);\n await transport.writeAll(response);\n await readSecurityResult(transport, version.minor >= 8);\n } else if (version.minor >= 8) {\n await readSecurityResult(transport, true);\n }\n\n return selected;\n}\n\nfunction encryptVncChallenge(password: Uint8Array, challenge: Uint8Array): Uint8Array {\n if (challenge.length !== 16) {\n throw new SandboxError(\"VNC authentication challenge must be 16 bytes\");\n }\n\n const key = Buffer.alloc(8);\n for (let index = 0; index < Math.min(password.length, 8); index += 1) {\n key[index] = reverseBits(password[index]);\n }\n\n const roundKeys = buildDesRoundKeys(key);\n const output = Buffer.alloc(16);\n for (let blockIndex = 0; blockIndex < 2; blockIndex += 1) {\n const start = blockIndex * 8;\n const encrypted = encryptDesBlock(challenge.subarray(start, start + 8), roundKeys);\n output.set(encrypted, start);\n }\n return output;\n}\n\nfunction reverseBits(value: number): number {\n let reversed = 0;\n for (let bit = 0; bit < 8; bit += 1) {\n reversed |= ((value >> bit) & 1) << (7 - bit);\n }\n return reversed;\n}\n\nasync function readSecurityResult(\n transport: DesktopTransport,\n hasReasonString: boolean,\n): Promise<void> {\n const status = await readU32(transport);\n if (status === 0) {\n return;\n }\n\n let reason: string;\n if (hasReasonString) {\n const reasonLength = await readU32(transport);\n reason = (await transport.readExactly(reasonLength)).toString(\"utf8\");\n } else if (status === 1) {\n reason = \"authentication failed\";\n } else {\n reason = `security handshake failed with status ${status}`;\n }\n\n throw new SandboxError(`VNC security negotiation failed: ${reason}`);\n}\n\nasync function sendSetPixelFormat(\n transport: DesktopTransport,\n pixelFormat: PixelFormat,\n): Promise<void> {\n const message = Buffer.alloc(20);\n message[0] = 0;\n message.set(pixelFormat.encode(), 4);\n await transport.writeAll(message);\n}\n\nasync function sendSetEncodings(\n transport: DesktopTransport,\n encodings: number[],\n): Promise<void> {\n const message = Buffer.alloc(4 + encodings.length * 4);\n message[0] = 2;\n message.writeUInt16BE(encodings.length, 2);\n for (let index = 0; index < encodings.length; index += 1) {\n message.writeInt32BE(encodings[index], 4 + index * 4);\n }\n await transport.writeAll(message);\n}\n\nasync function sendFramebufferUpdateRequest(\n transport: DesktopTransport,\n incremental: boolean,\n x: number,\n y: number,\n width: number,\n height: number,\n): Promise<void> {\n const message = Buffer.alloc(10);\n message[0] = 3;\n message[1] = incremental ? 1 : 0;\n message.writeUInt16BE(x, 2);\n message.writeUInt16BE(y, 4);\n message.writeUInt16BE(width, 6);\n message.writeUInt16BE(height, 8);\n await transport.writeAll(message);\n}\n\nasync function sendPointerEvent(\n transport: DesktopTransport,\n buttonMask: number,\n x: number,\n y: number,\n): Promise<void> {\n const message = Buffer.alloc(6);\n message[0] = 5;\n message[1] = buttonMask;\n message.writeUInt16BE(x, 2);\n message.writeUInt16BE(y, 4);\n await transport.writeAll(message);\n}\n\nasync function sendKeyEvent(\n transport: DesktopTransport,\n down: boolean,\n keysym: number,\n): Promise<void> {\n const message = Buffer.alloc(8);\n message[0] = 4;\n message[1] = down ? 1 : 0;\n message.writeUInt32BE(keysym, 4);\n await transport.writeAll(message);\n}\n\nasync function readU8(transport: DesktopTransport): Promise<number> {\n return (await transport.readExactly(1))[0];\n}\n\nasync function readU16(transport: DesktopTransport): Promise<number> {\n return (await transport.readExactly(2)).readUInt16BE(0);\n}\n\nasync function readU32(transport: DesktopTransport): Promise<number> {\n return (await transport.readExactly(4)).readUInt32BE(0);\n}\n\nasync function readI32(transport: DesktopTransport): Promise<number> {\n return (await transport.readExactly(4)).readInt32BE(0);\n}\n\nfunction scaleChannel(value: number, max: number): number {\n if (max === 0) {\n throw new SandboxError(\"invalid VNC pixel format with zero channel range\");\n }\n return Math.trunc((value * 255) / max);\n}\n\nfunction allocateFramebuffer(width: number, height: number): Uint8Array {\n return new Uint8Array(width * height * 4);\n}\n\nfunction normalizeDesktopConnectRequest(\n options: DesktopConnectRequest,\n): DesktopConnectRequest & {\n port: number;\n shared: boolean;\n connectTimeout: number;\n} {\n return {\n ...options,\n port: validatePort(options.port ?? 5901, \"desktop port\"),\n shared: options.shared ?? true,\n connectTimeout: options.connectTimeout ?? 10,\n };\n}\n\nasync function openDesktopSession(\n options: DesktopConnectRequest & {\n port: number;\n shared: boolean;\n connectTimeout: number;\n },\n): Promise<DesktopSession<TunnelByteStream>> {\n const connectTimeoutMs = secondsToMillis(options.connectTimeout);\n const state: { transport?: TunnelByteStream } = {};\n\n try {\n return await withTimeout(\n connectTimeoutMs,\n async () => {\n state.transport = await TunnelByteStream.connect({\n baseUrl: options.baseUrl,\n wsHeaders: options.wsHeaders,\n remotePort: options.port,\n connectTimeoutMs,\n });\n return DesktopSession.connect(\n state.transport,\n options.password,\n options.shared,\n );\n },\n `timed out while connecting desktop session after ${options.connectTimeout.toFixed(2)}s`,\n );\n } catch (error) {\n if (state.transport) {\n await state.transport.close().catch(() => {});\n }\n throw error;\n }\n}\n\nfunction isReconnectableDesktopScreenshotError(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n\n const message = error.message.toLowerCase();\n return (\n message.includes(\"desktop tunnel closed unexpectedly\") ||\n message.includes(\"desktop tunnel is not connected\") ||\n message.includes(\"connection closed\") ||\n message.includes(\"econnreset\") ||\n message.includes(\"timed out waiting for initial desktop framebuffer\") ||\n message.includes(\"timed out while connecting tunnel websocket\") ||\n message.includes(\"tunnel websocket closed before opening\") ||\n message.includes(\"tunnel websocket handshake failed\")\n );\n}\n\nfunction createDeferredSignal(): {\n resolve(): void;\n wait(): Promise<void>;\n} {\n let resolveCurrent!: () => void;\n let promise = new Promise<void>((resolve) => {\n resolveCurrent = resolve;\n });\n\n return {\n resolve() {\n resolveCurrent();\n promise = new Promise<void>((resolve) => {\n resolveCurrent = resolve;\n });\n },\n wait() {\n return promise;\n },\n };\n}\n\nfunction normalizeError(error: unknown): Error {\n return error instanceof Error ? error : new SandboxError(String(error));\n}\n\nfunction buttonMask(button: MouseButton | string): number {\n const normalized = button.trim().toLowerCase();\n if (normalized === \"left\") return BUTTON_LEFT_MASK;\n if (normalized === \"middle\") return BUTTON_MIDDLE_MASK;\n if (normalized === \"right\") return BUTTON_RIGHT_MASK;\n throw new SandboxError(\n `unsupported mouse button \\`${button}\\`; expected left, middle, or right`,\n );\n}\n\nfunction keysymFromKeyName(key: string): number {\n const trimmed = key.trim();\n if (trimmed.length === 0) {\n throw new SandboxError(\"desktop key name cannot be empty\");\n }\n\n if ([...trimmed].length === 1) {\n return keysymFromChar(trimmed);\n }\n\n const normalized = trimmed.toLowerCase();\n const special = SPECIAL_KEYSYMS.get(normalized);\n if (special != null) {\n return special;\n }\n\n const functionMatch = /^f([1-9]|1[0-2])$/.exec(normalized);\n if (functionMatch) {\n return 0xffbd + Number.parseInt(functionMatch[1], 10);\n }\n\n throw new SandboxError(`unsupported desktop key \\`${trimmed}\\``);\n}\n\nfunction keysymFromChar(char: string): number {\n const codePoint = char.codePointAt(0);\n if (codePoint == null) {\n throw new SandboxError(\"desktop key name cannot be empty\");\n }\n if (char === \"\\n\" || char === \"\\r\") return 0xff0d;\n if (char === \"\\t\") return 0xff09;\n if (char === \"\\b\") return 0xff08;\n if (codePoint >= 0x20 && codePoint <= 0x7e) return codePoint;\n if (codePoint < 0x20 || (codePoint >= 0x7f && codePoint <= 0x9f)) {\n throw new SandboxError(\n `unsupported control character U+${codePoint.toString(16).toUpperCase().padStart(4, \"0\")} for desktop typing`,\n );\n }\n return 0x0100_0000 | codePoint;\n}\n\nfunction encodePng(width: number, height: number, rgba: Uint8Array): Uint8Array {\n const stride = width * 4;\n const raw = Buffer.alloc((stride + 1) * height);\n for (let row = 0; row < height; row += 1) {\n const srcOffset = row * stride;\n const dstOffset = row * (stride + 1);\n raw[dstOffset] = 0;\n raw.set(rgba.subarray(srcOffset, srcOffset + stride), dstOffset + 1);\n }\n\n const ihdr = Buffer.alloc(13);\n ihdr.writeUInt32BE(width, 0);\n ihdr.writeUInt32BE(height, 4);\n ihdr[8] = 8;\n ihdr[9] = 6;\n ihdr[10] = 0;\n ihdr[11] = 0;\n ihdr[12] = 0;\n\n const idat = deflateSync(raw);\n return Buffer.concat([\n PNG_SIGNATURE,\n pngChunk(\"IHDR\", ihdr),\n pngChunk(\"IDAT\", idat),\n pngChunk(\"IEND\", Buffer.alloc(0)),\n ]);\n}\n\nfunction pngChunk(type: string, data: Buffer): Buffer {\n const chunkType = Buffer.from(type, \"ascii\");\n const length = Buffer.alloc(4);\n length.writeUInt32BE(data.length, 0);\n const crc = Buffer.alloc(4);\n crc.writeUInt32BE(crc32(Buffer.concat([chunkType, data])), 0);\n return Buffer.concat([length, chunkType, data, crc]);\n}\n\nfunction crc32(data: Uint8Array): number {\n let crc = 0xffff_ffff;\n for (const byte of data) {\n crc = CRC32_TABLE[(crc ^ byte) & 0xff] ^ (crc >>> 8);\n }\n return (crc ^ 0xffff_ffff) >>> 0;\n}\n\nfunction buildCrc32Table(): Uint32Array {\n const table = new Uint32Array(256);\n for (let index = 0; index < 256; index += 1) {\n let value = index;\n for (let bit = 0; bit < 8; bit += 1) {\n value = (value & 1) !== 0 ? 0xedb8_8320 ^ (value >>> 1) : value >>> 1;\n }\n table[index] = value >>> 0;\n }\n return table;\n}\n\nfunction validateCoordinate(value: number, label: string): number {\n return validateIntegerInRange(value, label, 0, 0xffff);\n}\n\nfunction validatePort(value: number, label: string): number {\n return validateIntegerInRange(value, label, 1, 65535);\n}\n\nfunction validateIntegerInRange(\n value: number,\n label: string,\n min: number,\n max: number,\n): number {\n if (!Number.isInteger(value) || value < min || value > max) {\n throw new SandboxError(`${label} must be an integer between ${min} and ${max}, got ${value}`);\n }\n return value;\n}\n\nfunction validateInteger(value: number, label: string): number {\n if (!Number.isInteger(value)) {\n throw new SandboxError(`${label} must be an integer, got ${value}`);\n }\n return value;\n}\n\nfunction validateNonNegativeInteger(value: number, label: string): number {\n if (!Number.isInteger(value) || value < 0) {\n throw new SandboxError(`${label} must be a non-negative integer, got ${value}`);\n }\n return value;\n}\n\nfunction secondsToMillis(seconds: number): number {\n if (!Number.isFinite(seconds) || seconds < 0) {\n throw new SandboxError(`timeout must be >= 0 seconds, got ${seconds}`);\n }\n return Math.round(seconds * 1000);\n}\n\nconst SPECIAL_KEYSYMS = new Map<string, number>([\n [\"enter\", 0xff0d],\n [\"tab\", 0xff09],\n [\"escape\", 0xff1b],\n [\"backspace\", 0xff08],\n [\"delete\", 0xffff],\n [\"space\", 0x0020],\n [\"up\", 0xff52],\n [\"down\", 0xff54],\n [\"left\", 0xff51],\n [\"right\", 0xff53],\n [\"home\", 0xff50],\n [\"end\", 0xff57],\n [\"pageup\", 0xff55],\n [\"pagedown\", 0xff56],\n [\"page_up\", 0xff55],\n [\"page_down\", 0xff56],\n [\"shift\", 0xffe1],\n [\"ctrl\", 0xffe3],\n [\"control\", 0xffe3],\n [\"alt\", 0xffe9],\n [\"meta\", 0xffe7],\n]);\n\nconst DES_INITIAL_PERMUTATION = [\n 58, 50, 42, 34, 26, 18, 10, 2,\n 60, 52, 44, 36, 28, 20, 12, 4,\n 62, 54, 46, 38, 30, 22, 14, 6,\n 64, 56, 48, 40, 32, 24, 16, 8,\n 57, 49, 41, 33, 25, 17, 9, 1,\n 59, 51, 43, 35, 27, 19, 11, 3,\n 61, 53, 45, 37, 29, 21, 13, 5,\n 63, 55, 47, 39, 31, 23, 15, 7,\n];\n\nconst DES_FINAL_PERMUTATION = [\n 40, 8, 48, 16, 56, 24, 64, 32,\n 39, 7, 47, 15, 55, 23, 63, 31,\n 38, 6, 46, 14, 54, 22, 62, 30,\n 37, 5, 45, 13, 53, 21, 61, 29,\n 36, 4, 44, 12, 52, 20, 60, 28,\n 35, 3, 43, 11, 51, 19, 59, 27,\n 34, 2, 42, 10, 50, 18, 58, 26,\n 33, 1, 41, 9, 49, 17, 57, 25,\n];\n\nconst DES_EXPANSION = [\n 32, 1, 2, 3, 4, 5,\n 4, 5, 6, 7, 8, 9,\n 8, 9, 10, 11, 12, 13,\n 12, 13, 14, 15, 16, 17,\n 16, 17, 18, 19, 20, 21,\n 20, 21, 22, 23, 24, 25,\n 24, 25, 26, 27, 28, 29,\n 28, 29, 30, 31, 32, 1,\n];\n\nconst DES_P_PERMUTATION = [\n 16, 7, 20, 21,\n 29, 12, 28, 17,\n 1, 15, 23, 26,\n 5, 18, 31, 10,\n 2, 8, 24, 14,\n 32, 27, 3, 9,\n 19, 13, 30, 6,\n 22, 11, 4, 25,\n];\n\nconst DES_PC1 = [\n 57, 49, 41, 33, 25, 17, 9,\n 1, 58, 50, 42, 34, 26, 18,\n 10, 2, 59, 51, 43, 35, 27,\n 19, 11, 3, 60, 52, 44, 36,\n 63, 55, 47, 39, 31, 23, 15,\n 7, 62, 54, 46, 38, 30, 22,\n 14, 6, 61, 53, 45, 37, 29,\n 21, 13, 5, 28, 20, 12, 4,\n];\n\nconst DES_PC2 = [\n 14, 17, 11, 24, 1, 5,\n 3, 28, 15, 6, 21, 10,\n 23, 19, 12, 4, 26, 8,\n 16, 7, 27, 20, 13, 2,\n 41, 52, 31, 37, 47, 55,\n 30, 40, 51, 45, 33, 48,\n 44, 49, 39, 56, 34, 53,\n 46, 42, 50, 36, 29, 32,\n];\n\nconst DES_ROTATIONS = [\n 1, 1, 2, 2, 2, 2, 2, 2,\n 1, 2, 2, 2, 2, 2, 2, 1,\n];\n\nconst DES_SBOXES = [\n [\n 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,\n 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,\n 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,\n 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,\n ],\n [\n 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,\n 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,\n 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,\n 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,\n ],\n [\n 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,\n 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,\n 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,\n 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,\n ],\n [\n 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,\n 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,\n 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,\n 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,\n ],\n [\n 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,\n 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,\n 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,\n 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,\n ],\n [\n 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,\n 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,\n 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,\n 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,\n ],\n [\n 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,\n 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,\n 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,\n 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,\n ],\n [\n 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,\n 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,\n 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,\n 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11,\n ],\n];\n\nfunction buildDesRoundKeys(key: Uint8Array): bigint[] {\n const keyBlock = bytesToBigInt(key);\n const permuted = permuteBits(keyBlock, DES_PC1, 64);\n let c = Number((permuted >> 28n) & 0x0fff_ffffn);\n let d = Number(permuted & 0x0fff_ffffn);\n\n const roundKeys: bigint[] = [];\n for (const rotation of DES_ROTATIONS) {\n c = rotateLeft28(c, rotation);\n d = rotateLeft28(d, rotation);\n const combined = (BigInt(c) << 28n) | BigInt(d);\n roundKeys.push(permuteBits(combined, DES_PC2, 56));\n }\n return roundKeys;\n}\n\nfunction encryptDesBlock(block: Uint8Array, roundKeys: bigint[]): Uint8Array {\n let value = permuteBits(bytesToBigInt(block), DES_INITIAL_PERMUTATION, 64);\n let left = Number((value >> 32n) & 0xffff_ffffn);\n let right = Number(value & 0xffff_ffffn);\n\n for (const roundKey of roundKeys) {\n const nextLeft = right;\n const nextRight = (left ^ feistel(right, roundKey)) >>> 0;\n left = nextLeft >>> 0;\n right = nextRight;\n }\n\n value = (BigInt(right) << 32n) | BigInt(left);\n return bigIntToBytes(permuteBits(value, DES_FINAL_PERMUTATION, 64), 8);\n}\n\nfunction feistel(right: number, roundKey: bigint): number {\n const expanded = permuteBits(BigInt(right >>> 0), DES_EXPANSION, 32) ^ roundKey;\n let output = 0;\n for (let index = 0; index < 8; index += 1) {\n const shift = BigInt((7 - index) * 6);\n const chunk = Number((expanded >> shift) & 0x3fn);\n const row = ((chunk & 0x20) >> 4) | (chunk & 0x01);\n const column = (chunk >> 1) & 0x0f;\n output = (output << 4) | DES_SBOXES[index][row * 16 + column];\n }\n return Number(permuteBits(BigInt(output >>> 0), DES_P_PERMUTATION, 32)) >>> 0;\n}\n\nfunction rotateLeft28(value: number, shift: number): number {\n const masked = value & 0x0fff_ffff;\n return ((masked << shift) | (masked >>> (28 - shift))) & 0x0fff_ffff;\n}\n\nfunction permuteBits(input: bigint, table: number[], inputBits: number): bigint {\n let output = 0n;\n for (const position of table) {\n const shift = BigInt(inputBits - position);\n output = (output << 1n) | ((input >> shift) & 1n);\n }\n return output;\n}\n\nfunction bytesToBigInt(bytes: Uint8Array): bigint {\n let value = 0n;\n for (const byte of bytes) {\n value = (value << 8n) | BigInt(byte);\n }\n return value;\n}\n\nfunction bigIntToBytes(value: bigint, length: number): Uint8Array {\n const out = Buffer.alloc(length);\n let remaining = value;\n for (let index = length - 1; index >= 0; index -= 1) {\n out[index] = Number(remaining & 0xffn);\n remaining >>= 8n;\n }\n return out;\n}\n","export interface SSEMessage {\n data: string;\n event?: string;\n id?: string;\n}\n\n/**\n * Parse a Server-Sent Events stream into raw SSE messages.\n */\nexport async function* parseSSEMessages(\n stream: ReadableStream<Uint8Array>,\n signal?: AbortSignal,\n): AsyncIterable<SSEMessage> {\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n try {\n while (true) {\n if (signal?.aborted) break;\n\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const parts = buffer.split(/\\r?\\n\\r?\\n/);\n buffer = parts.pop() ?? \"\";\n\n for (const part of parts) {\n const lines = part.split(/\\r?\\n/);\n const dataLines: string[] = [];\n let event: string | undefined;\n let id: string | undefined;\n\n for (const line of lines) {\n if (!line || line.startsWith(\":\")) continue;\n\n const separator = line.indexOf(\":\");\n const field = separator === -1 ? line : line.slice(0, separator);\n let value = separator === -1 ? \"\" : line.slice(separator + 1);\n if (value.startsWith(\" \")) {\n value = value.slice(1);\n }\n\n if (field === \"data\") {\n dataLines.push(value);\n } else if (field === \"event\") {\n event = value;\n } else if (field === \"id\") {\n id = value;\n }\n }\n\n if (dataLines.length > 0 || event || id) {\n yield { data: dataLines.join(\"\\n\"), event, id };\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n\n/**\n * Parse a Server-Sent Events stream from a ReadableStream<Uint8Array>.\n *\n * Yields parsed JSON objects for each `data:` line. Handles reconnection\n * by simply yielding events as they arrive.\n */\nexport async function* parseSSEStream<T>(\n stream: ReadableStream<Uint8Array>,\n signal?: AbortSignal,\n): AsyncIterable<T> {\n for await (const message of parseSSEMessages(stream, signal)) {\n if (!message.data) continue;\n try {\n yield JSON.parse(message.data) as T;\n } catch {\n // Skip malformed JSON\n }\n }\n}\n","import * as defaults from \"./defaults.js\";\n\n/** Remove a trailing slash from a URL string if present. */\nfunction trimTrailingSlashes(url: string): string {\n return url.endsWith(\"/\") ? url.slice(0, -1) : url;\n}\n\n/** Check whether a URL points to localhost. */\nexport function isLocalhost(apiUrl: string): boolean {\n try {\n const parsed = new URL(apiUrl);\n return parsed.hostname === \"localhost\" || parsed.hostname === \"127.0.0.1\";\n } catch {\n return false;\n }\n}\n\n/**\n * Derive the sandbox proxy URL from the API URL.\n *\n * Priority:\n * 1. TENSORLAKE_SANDBOX_PROXY_URL env var\n * 2. `http://localhost:9443` for localhost API URLs\n * 3. Transform `api.X` → `sandbox.X`\n * 4. Default fallback\n */\nexport function resolveProxyUrl(apiUrl: string): string {\n const explicit = process.env.TENSORLAKE_SANDBOX_PROXY_URL;\n if (explicit) return explicit;\n\n if (isLocalhost(apiUrl)) return \"http://localhost:9443\";\n\n try {\n const parsed = new URL(apiUrl);\n const host = parsed.hostname;\n if (host.startsWith(\"api.\")) {\n const proxyHost = \"sandbox.\" + host.slice(4);\n return `${parsed.protocol}//${proxyHost}`;\n }\n } catch {\n // fall through to default\n }\n\n return defaults.SANDBOX_PROXY_URL;\n}\n\n/**\n * Resolve the proxy target for a specific sandbox.\n *\n * - Localhost: base URL stays the same, Host header set to `{sandboxId}.local`\n * - Cloud: sandbox ID becomes a subdomain of the proxy host\n *\n * Returns `{ baseUrl, hostHeader }`.\n */\nexport function resolveProxyTarget(\n proxyUrl: string,\n sandboxId: string,\n): { baseUrl: string; hostHeader: string | undefined } {\n try {\n const parsed = new URL(proxyUrl);\n const host = parsed.hostname;\n\n if (host === \"localhost\" || host === \"127.0.0.1\") {\n return {\n baseUrl: trimTrailingSlashes(proxyUrl),\n hostHeader: `${sandboxId}.local`,\n };\n }\n\n const port = parsed.port ? `:${parsed.port}` : \"\";\n return {\n baseUrl: `${parsed.protocol}//${sandboxId}.${host}${port}`,\n hostHeader: undefined,\n };\n } catch {\n return {\n baseUrl: `${trimTrailingSlashes(proxyUrl)}/${sandboxId}`,\n hostHeader: undefined,\n };\n }\n}\n\n/**\n * Build a lifecycle API path.\n *\n * - Localhost (namespaced): `/v1/namespaces/{namespace}/{path}`\n * - Cloud (flat): `/{path}`\n */\nexport function lifecyclePath(\n path: string,\n isLocal: boolean,\n namespace: string,\n): string {\n if (isLocal) {\n return `/v1/namespaces/${namespace}/${path}`;\n }\n return `/${path}`;\n}\n","import type { SandboxClient } from \"./client.js\";\nimport {\n type ConnectDesktopOptions,\n Desktop,\n} from \"./desktop.js\";\nimport * as defaults from \"./defaults.js\";\nimport { SandboxError } from \"./errors.js\";\nimport { type Traced, HttpClient } from \"./http.js\";\nimport {\n type CheckpointOptions,\n type CommandResult,\n type ConnectOptions,\n type CreateAndConnectOptions,\n type CreatePtySessionOptions,\n type DaemonInfo,\n type DirectoryEntry,\n type HealthResponse,\n type ListDirectoryResponse,\n type OutputEvent,\n type OutputResponse,\n OutputMode,\n type ProcessInfo,\n type PtySessionInfo,\n type RunOptions,\n type SandboxClientOptions,\n type SandboxInfo,\n type SandboxOptions,\n type SendSignalResponse,\n type SnapshotInfo,\n type StartProcessOptions,\n SandboxStatus,\n SnapshotStatus,\n StdinMode,\n type SuspendResumeOptions,\n type UpdateSandboxOptions,\n fromSnakeKeys,\n} from \"./models.js\";\nimport {\n type CreateTunnelOptions,\n TcpTunnel,\n} from \"./tunnel.js\";\nimport { parseSSEStream } from \"./sse.js\";\nimport { resolveProxyTarget } from \"./url.js\";\nimport WebSocket, { type RawData } from \"ws\";\n\nconst PTY_OP_DATA = 0x00;\nconst PTY_OP_RESIZE = 0x01;\nconst PTY_OP_READY = 0x02;\nconst PTY_OP_EXIT = 0x03;\n\nexport type PtyDataHandler = (data: Uint8Array) => void;\nexport type PtyExitHandler = (exitCode: number) => void;\n\nexport interface PtyConnectionOptions {\n onData?: PtyDataHandler;\n onExit?: PtyExitHandler;\n}\n\nexport interface CreatePtyOptions\n extends CreatePtySessionOptions,\n PtyConnectionOptions {}\n\nexport class Pty {\n readonly sessionId: string;\n readonly token: string;\n\n private readonly wsUrl: string;\n private readonly wsHeaders: Record<string, string>;\n private readonly killSession: () => Promise<void>;\n private socket: WebSocket | null = null;\n private connectPromise: Promise<this> | null = null;\n private intentionalDisconnect = false;\n private exitCode: number | null = null;\n private waitSettled = false;\n private readonly dataHandlers = new Set<PtyDataHandler>();\n private readonly exitHandlers = new Set<PtyExitHandler>();\n private readonly waitPromise: Promise<number>;\n private resolveWait!: (exitCode: number) => void;\n private rejectWait!: (error: unknown) => void;\n\n constructor(options: {\n sessionId: string;\n token: string;\n wsUrl: string;\n wsHeaders: Record<string, string>;\n killSession: () => Promise<void>;\n }) {\n this.sessionId = options.sessionId;\n this.token = options.token;\n this.wsUrl = options.wsUrl;\n this.wsHeaders = options.wsHeaders;\n this.killSession = options.killSession;\n this.waitPromise = new Promise<number>((resolve, reject) => {\n this.resolveWait = resolve;\n this.rejectWait = reject;\n });\n }\n\n onData(handler: PtyDataHandler): () => void {\n this.dataHandlers.add(handler);\n return () => this.dataHandlers.delete(handler);\n }\n\n onExit(handler: PtyExitHandler): () => void {\n this.exitHandlers.add(handler);\n if (this.exitCode != null) {\n queueMicrotask(() => handler(this.exitCode!));\n }\n return () => this.exitHandlers.delete(handler);\n }\n\n async connect(): Promise<this> {\n if (this.socket?.readyState === WebSocket.OPEN) {\n return this;\n }\n if (this.connectPromise) {\n return this.connectPromise;\n }\n\n this.intentionalDisconnect = false;\n\n this.connectPromise = new Promise<this>((resolve, reject) => {\n let opened = false;\n const socket = new WebSocket(this.wsUrl, {\n headers: this.wsHeaders,\n });\n this.socket = socket;\n\n socket.on(\"open\", async () => {\n try {\n await sendPtyFrame(socket, Buffer.from([PTY_OP_READY]));\n opened = true;\n resolve(this);\n } catch (error) {\n reject(error);\n }\n });\n\n socket.on(\"message\", (message: RawData) => {\n const bytes = normalizePtyMessage(message);\n const opcode = bytes[0];\n\n if (opcode === PTY_OP_DATA) {\n const payload = bytes.subarray(1);\n for (const handler of this.dataHandlers) {\n handler(payload);\n }\n return;\n }\n\n if (opcode === PTY_OP_EXIT && bytes.length >= 5) {\n this.finishWait(bytes.readInt32BE(1));\n }\n });\n\n socket.on(\"close\", (code: number, reason: Buffer) => {\n const closeReason = Buffer.isBuffer(reason)\n ? reason.toString(\"utf8\")\n : String(reason);\n\n if (this.socket === socket) {\n this.socket = null;\n }\n this.connectPromise = null;\n\n if (this.exitCode != null) {\n this.finishWait(this.exitCode);\n return;\n }\n\n if (closeReason.startsWith(\"exit:\")) {\n const parsed = Number.parseInt(closeReason.slice(5), 10);\n this.finishWait(Number.isNaN(parsed) ? -1 : parsed);\n return;\n }\n\n if (this.intentionalDisconnect) {\n this.intentionalDisconnect = false;\n return;\n }\n\n if (!opened) {\n reject(new SandboxError(\n `PTY websocket closed before READY completed: ${code} ${closeReason || \"no reason\"}`,\n ));\n return;\n }\n\n if (closeReason === \"session terminated\") {\n this.failWait(new SandboxError(\"PTY session terminated\"));\n return;\n }\n\n this.failWait(\n new SandboxError(\n `PTY websocket closed unexpectedly: ${code} ${closeReason || \"no reason\"}`,\n ),\n );\n });\n\n socket.on(\"error\", (error: Error) => {\n if (!opened) {\n reject(error);\n }\n });\n });\n\n return this.connectPromise;\n }\n\n async sendInput(input: string | Uint8Array): Promise<void> {\n const socket = this.requireOpenSocket();\n await sendPtyFrame(socket, encodePtyInput(input));\n }\n\n async resize(cols: number, rows: number): Promise<void> {\n const socket = this.requireOpenSocket();\n await sendPtyFrame(socket, encodePtyResize(cols, rows));\n }\n\n disconnect(code = 1000, reason = \"client disconnect\"): void {\n if (!this.socket) return;\n this.intentionalDisconnect = true;\n this.socket.close(code, reason);\n }\n\n wait(): Promise<number> {\n return this.waitPromise;\n }\n\n async kill(): Promise<void> {\n await this.killSession();\n }\n\n private requireOpenSocket(): WebSocket {\n if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {\n throw new SandboxError(\"PTY is not connected\");\n }\n return this.socket;\n }\n\n private finishWait(exitCode: number): void {\n if (this.waitSettled) return;\n this.waitSettled = true;\n this.exitCode = exitCode;\n for (const handler of this.exitHandlers) {\n handler(exitCode);\n }\n this.resolveWait(exitCode);\n }\n\n private failWait(error: unknown): void {\n if (this.waitSettled) return;\n this.waitSettled = true;\n this.rejectWait(error);\n }\n}\n\nfunction normalizePtyMessage(message: RawData): Buffer {\n if (Buffer.isBuffer(message)) return message;\n if (Array.isArray(message)) {\n return Buffer.concat(message.map((part) => Buffer.from(part)));\n }\n return Buffer.from(message);\n}\n\nfunction encodePtyInput(input: string | Uint8Array): Buffer {\n const payload =\n typeof input === \"string\" ? Buffer.from(input, \"utf8\") : Buffer.from(input);\n return Buffer.concat([Buffer.from([PTY_OP_DATA]), payload]);\n}\n\nfunction encodePtyResize(cols: number, rows: number): Buffer {\n const frame = Buffer.alloc(5);\n frame[0] = PTY_OP_RESIZE;\n frame.writeUInt16BE(cols, 1);\n frame.writeUInt16BE(rows, 3);\n return frame;\n}\n\nfunction sendPtyFrame(socket: WebSocket, frame: Buffer): Promise<void> {\n return new Promise((resolve, reject) => {\n socket.send(frame, (error?: Error) => (error ? reject(error) : resolve()));\n });\n}\n\n/**\n * Client for interacting with a running sandbox.\n *\n * Provides process management, file operations, and I/O streaming\n * through the sandbox proxy.\n */\nexport class Sandbox {\n readonly sandboxId: string;\n traceId: string | null = null;\n private readonly http: HttpClient;\n private readonly baseUrl: string;\n private readonly wsHeaders: Record<string, string>;\n private ownsSandbox = false;\n private lifecycleClient: SandboxClient | null = null;\n private lifecycleIdentifier: string;\n private sandboxName: string | null = null;\n\n constructor(options: SandboxOptions) {\n this.sandboxId = options.sandboxId;\n this.lifecycleIdentifier = options.sandboxId;\n\n const proxyUrl = options.proxyUrl ?? defaults.SANDBOX_PROXY_URL;\n const { baseUrl, hostHeader } = resolveProxyTarget(proxyUrl, options.sandboxId);\n this.baseUrl = baseUrl;\n this.wsHeaders = {};\n if (options.apiKey) {\n this.wsHeaders.Authorization = `Bearer ${options.apiKey}`;\n }\n if (options.organizationId) {\n this.wsHeaders[\"X-Forwarded-Organization-Id\"] = options.organizationId;\n }\n if (options.projectId) {\n this.wsHeaders[\"X-Forwarded-Project-Id\"] = options.projectId;\n }\n if (hostHeader) {\n this.wsHeaders.Host = hostHeader;\n }\n\n this.http = new HttpClient({\n baseUrl,\n apiKey: options.apiKey,\n organizationId: options.organizationId,\n projectId: options.projectId,\n hostHeader,\n routingHint: options.routingHint,\n });\n }\n\n get name(): string | null {\n return this.sandboxName;\n }\n\n /** @internal Used by client wiring to keep locally cached name in sync. */\n _setName(name: string | null): void {\n this.sandboxName = name;\n }\n\n /** @internal Used by lifecycle operations to pin to canonical sandbox ID. */\n _setLifecycleIdentifier(identifier: string): void {\n this.lifecycleIdentifier = identifier;\n }\n\n /** @internal Used by SandboxClient.createAndConnect to set ownership. */\n _setOwner(client: SandboxClient): void {\n this.ownsSandbox = true;\n this.lifecycleClient = client;\n }\n\n // --- Static factory methods ---\n\n /**\n * Create a new sandbox and return a connected, running handle.\n *\n * Covers both fresh sandbox creation and restore-from-snapshot (set\n * `snapshotId`). Blocks until the sandbox is `Running`.\n */\n static async create(\n options?: CreateAndConnectOptions & Partial<SandboxClientOptions>,\n ): Promise<Sandbox> {\n // Dynamic import to break the circular dependency (client.ts imports Sandbox).\n const { SandboxClient } = await import(\"./client.js\");\n const client = new SandboxClient(options, /* _internal */ true);\n const sandbox = await client.createAndConnect(options);\n sandbox.lifecycleClient = client;\n return sandbox;\n }\n\n /**\n * Attach to an existing sandbox and return a connected handle.\n *\n * Verifies the sandbox exists via a server GET call, then returns a handle\n * in whatever state the sandbox is in. Does **not** auto-resume a suspended\n * sandbox — call `sandbox.resume()` explicitly.\n */\n static async connect(\n options: ConnectOptions & Partial<SandboxClientOptions>,\n ): Promise<Sandbox> {\n const { SandboxClient } = await import(\"./client.js\");\n const client = new SandboxClient(options, /* _internal */ true);\n const info = await client.get(options.sandboxId); // throws SandboxNotFoundError if not found\n const sandbox = client.connect(\n info.sandboxId,\n options.proxyUrl,\n options.routingHint ?? info.routingHint,\n );\n sandbox.lifecycleClient = client;\n sandbox._setLifecycleIdentifier(info.sandboxId);\n sandbox._setName(info.name ?? null);\n return sandbox;\n }\n\n // --- Static snapshot management ---\n\n /** Get information about a snapshot by ID. No sandbox handle needed. */\n static async getSnapshot(\n snapshotId: string,\n options?: Partial<SandboxClientOptions>,\n ): Promise<SnapshotInfo> {\n const { SandboxClient } = await import(\"./client.js\");\n const client = new SandboxClient(options, /* _internal */ true);\n return client.getSnapshot(snapshotId);\n }\n\n /** Delete a snapshot by ID. No sandbox handle needed. */\n static async deleteSnapshot(\n snapshotId: string,\n options?: Partial<SandboxClientOptions>,\n ): Promise<void> {\n const { SandboxClient } = await import(\"./client.js\");\n const client = new SandboxClient(options, /* _internal */ true);\n await client.deleteSnapshot(snapshotId);\n }\n\n // --- Instance lifecycle methods ---\n\n private requireLifecycleClient(operation: string): SandboxClient {\n if (!this.lifecycleClient) {\n throw new SandboxError(\n `Cannot ${operation}: no lifecycle client available. ` +\n \"Use Sandbox.create() or Sandbox.connect() to get a lifecycle-aware handle.\",\n );\n }\n return this.lifecycleClient;\n }\n\n /**\n * Fetch the current sandbox status from the server.\n *\n * Always hits the network — the value is not cached locally because the\n * status changes over the sandbox's lifecycle.\n */\n async status(): Promise<SandboxStatus> {\n const client = this.requireLifecycleClient(\"read_status\");\n const info = await client.get(this.lifecycleIdentifier);\n this._setLifecycleIdentifier(info.sandboxId);\n this._setName(info.name ?? null);\n return info.status;\n }\n\n /**\n * Update this sandbox's properties (name, exposed ports, proxy auth).\n *\n * Naming an ephemeral sandbox makes it non-ephemeral and enables\n * suspend/resume.\n */\n async update(options: UpdateSandboxOptions): Promise<SandboxInfo> {\n const client = this.requireLifecycleClient(\"update\");\n const info = await client.update(this.lifecycleIdentifier, options);\n this._setLifecycleIdentifier(info.sandboxId);\n this._setName(info.name ?? null);\n return info;\n }\n\n /**\n * Suspend this sandbox.\n *\n * By default blocks until the sandbox is fully `Suspended`. Pass\n * `{ wait: false }` for fire-and-return.\n */\n async suspend(options?: SuspendResumeOptions): Promise<void> {\n const client = this.requireLifecycleClient(\"suspend\");\n await client.suspend(this.lifecycleIdentifier, options);\n }\n\n /**\n * Resume this sandbox.\n *\n * By default blocks until the sandbox is `Running` and routable. Pass\n * `{ wait: false }` for fire-and-return.\n */\n async resume(options?: SuspendResumeOptions): Promise<void> {\n const client = this.requireLifecycleClient(\"resume\");\n await client.resume(this.lifecycleIdentifier, options);\n }\n\n /**\n * Create a snapshot of this sandbox's filesystem and wait for it to\n * be committed.\n *\n * By default blocks until the snapshot artifact is ready and returns\n * the completed `SnapshotInfo`. Pass `{ wait: false }` to fire-and-return\n * (returns `undefined`).\n */\n async checkpoint(options?: CheckpointOptions): Promise<SnapshotInfo | undefined> {\n const client = this.requireLifecycleClient(\"checkpoint\");\n if (options?.wait === false) {\n await client.snapshot(this.lifecycleIdentifier, { contentMode: options.contentMode });\n return undefined;\n }\n return client.snapshotAndWait(this.lifecycleIdentifier, {\n timeout: options?.timeout,\n pollInterval: options?.pollInterval,\n contentMode: options?.contentMode,\n });\n }\n\n /**\n * List snapshots taken from this sandbox.\n */\n async listSnapshots(): Promise<Traced<SnapshotInfo[]>> {\n const client = this.requireLifecycleClient(\"listSnapshots\");\n const all = await client.listSnapshots();\n const filtered = all.filter((s) => s.sandboxId === this.lifecycleIdentifier);\n return Object.assign(filtered, { traceId: all.traceId });\n }\n\n /** Close the HTTP client. The sandbox keeps running. */\n close(): void {\n this.http.close();\n }\n\n /** Terminate the sandbox and release all resources. */\n async terminate(): Promise<void> {\n const client = this.lifecycleClient;\n this.ownsSandbox = false;\n this.lifecycleClient = null;\n this.close();\n if (client) {\n await client.delete(this.lifecycleIdentifier);\n }\n }\n\n // --- High-level convenience ---\n\n /**\n * Run a command to completion and return its output.\n *\n * Uses a single streaming `POST /api/v1/processes/run` request that starts\n * the process, streams output, and delivers the exit code over one connection.\n */\n async run(command: string, options?: RunOptions): Promise<CommandResult> {\n const body: Record<string, unknown> = { command };\n if (options?.args) body.args = options.args;\n if (options?.env) body.env = options.env;\n if (options?.workingDir) body.working_dir = options.workingDir;\n if (options?.timeout != null) body.timeout = options.timeout;\n\n const sseStream = await this.http.requestStream(\n \"POST\",\n \"/api/v1/processes/run\",\n { json: body },\n );\n\n const stdoutLines: string[] = [];\n const stderrLines: string[] = [];\n let exitCode = -1;\n\n for await (const raw of parseSSEStream<Record<string, unknown>>(sseStream)) {\n if (typeof raw.line === \"string\") {\n if (raw.stream === \"stderr\") {\n stderrLines.push(raw.line);\n } else {\n stdoutLines.push(raw.line);\n }\n } else if (\"exit_code\" in raw || \"signal\" in raw) {\n if (typeof raw.exit_code === \"number\") {\n exitCode = raw.exit_code;\n } else if (typeof raw.signal === \"number\") {\n exitCode = -raw.signal;\n }\n }\n }\n\n return {\n exitCode,\n stdout: stdoutLines.join(\"\\n\"),\n stderr: stderrLines.join(\"\\n\"),\n };\n }\n\n // --- Process management ---\n\n /**\n * Start a process in the sandbox without waiting for it to exit.\n *\n * Returns a `ProcessInfo` with the assigned `pid`. Use `getProcess()` to\n * poll status, or `followStdout()` / `followOutput()` to stream output\n * until the process exits. Use `run()` instead to block until completion\n * and get combined output in one call.\n */\n async startProcess(\n command: string,\n options?: StartProcessOptions,\n ): Promise<ProcessInfo> {\n const payload: Record<string, unknown> = { command };\n if (options?.args != null) payload.args = options.args;\n if (options?.env != null) payload.env = options.env;\n if (options?.workingDir != null) payload.working_dir = options.workingDir;\n if (options?.stdinMode != null && options.stdinMode !== StdinMode.CLOSED) {\n payload.stdin_mode = options.stdinMode;\n }\n if (options?.stdoutMode != null && options.stdoutMode !== OutputMode.CAPTURE) {\n payload.stdout_mode = options.stdoutMode;\n }\n if (options?.stderrMode != null && options.stderrMode !== OutputMode.CAPTURE) {\n payload.stderr_mode = options.stderrMode;\n }\n\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"POST\",\n \"/api/v1/processes\",\n { body: payload },\n );\n return fromSnakeKeys(raw) as ProcessInfo;\n }\n\n /** List all processes (running and exited) tracked by the sandbox daemon. */\n async listProcesses(): Promise<Traced<ProcessInfo[]>> {\n const raw = await this.http.requestJson<{ processes: Record<string, unknown>[] }>(\n \"GET\",\n \"/api/v1/processes\",\n );\n const processes = (raw.processes ?? []).map((p) => fromSnakeKeys(p) as ProcessInfo);\n return Object.assign(processes, { traceId: raw.traceId });\n }\n\n /** Get current status and metadata for a process by PID. */\n async getProcess(pid: number): Promise<ProcessInfo> {\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"GET\",\n `/api/v1/processes/${pid}`,\n );\n return fromSnakeKeys(raw) as ProcessInfo;\n }\n\n /** Send SIGKILL to a process. */\n async killProcess(pid: number): Promise<void> {\n await this.http.requestJson(\"DELETE\", `/api/v1/processes/${pid}`);\n }\n\n /** Send an arbitrary signal to a process (e.g. `15` for SIGTERM, `9` for SIGKILL). */\n async sendSignal(pid: number, signal: number): Promise<SendSignalResponse> {\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"POST\",\n `/api/v1/processes/${pid}/signal`,\n { body: { signal } },\n );\n return fromSnakeKeys(raw) as SendSignalResponse;\n }\n\n // --- Process I/O ---\n\n /** Write bytes to a process's stdin. The process must have been started with `stdinMode: StdinMode.PIPE`. */\n async writeStdin(pid: number, data: Uint8Array): Promise<void> {\n await this.http.requestBytes(\"POST\", `/api/v1/processes/${pid}/stdin`, {\n body: data,\n contentType: \"application/octet-stream\",\n });\n }\n\n /** Close a process's stdin pipe, signalling EOF to the process. */\n async closeStdin(pid: number): Promise<void> {\n await this.http.requestJson(\"POST\", `/api/v1/processes/${pid}/stdin/close`);\n }\n\n /** Return all captured stdout lines produced so far by a process. */\n async getStdout(pid: number): Promise<OutputResponse> {\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"GET\",\n `/api/v1/processes/${pid}/stdout`,\n );\n return fromSnakeKeys(raw) as OutputResponse;\n }\n\n /** Return all captured stderr lines produced so far by a process. */\n async getStderr(pid: number): Promise<OutputResponse> {\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"GET\",\n `/api/v1/processes/${pid}/stderr`,\n );\n return fromSnakeKeys(raw) as OutputResponse;\n }\n\n /** Return all captured stdout+stderr lines produced so far by a process. */\n async getOutput(pid: number): Promise<OutputResponse> {\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"GET\",\n `/api/v1/processes/${pid}/output`,\n );\n return fromSnakeKeys(raw) as OutputResponse;\n }\n\n // --- Streaming (SSE) ---\n\n /** Stream stdout events from a process until it exits. Yields one `OutputEvent` per line. */\n async *followStdout(\n pid: number,\n options?: { signal?: AbortSignal },\n ): AsyncIterable<OutputEvent> {\n const stream = await this.http.requestStream(\n \"GET\",\n `/api/v1/processes/${pid}/stdout/follow`,\n options,\n );\n for await (const raw of parseSSEStream<Record<string, unknown>>(\n stream,\n options?.signal,\n )) {\n yield fromSnakeKeys(raw) as OutputEvent;\n }\n }\n\n /** Stream stderr events from a process until it exits. Yields one `OutputEvent` per line. */\n async *followStderr(\n pid: number,\n options?: { signal?: AbortSignal },\n ): AsyncIterable<OutputEvent> {\n const stream = await this.http.requestStream(\n \"GET\",\n `/api/v1/processes/${pid}/stderr/follow`,\n options,\n );\n for await (const raw of parseSSEStream<Record<string, unknown>>(\n stream,\n options?.signal,\n )) {\n yield fromSnakeKeys(raw) as OutputEvent;\n }\n }\n\n /** Stream combined stdout+stderr events from a process until it exits. Yields one `OutputEvent` per line. */\n async *followOutput(\n pid: number,\n options?: { signal?: AbortSignal },\n ): AsyncIterable<OutputEvent> {\n const stream = await this.http.requestStream(\n \"GET\",\n `/api/v1/processes/${pid}/output/follow`,\n options,\n );\n for await (const raw of parseSSEStream<Record<string, unknown>>(\n stream,\n options?.signal,\n )) {\n yield fromSnakeKeys(raw) as OutputEvent;\n }\n }\n\n // --- File operations ---\n\n /** Read a file from the sandbox and return its raw bytes. */\n async readFile(path: string): Promise<Uint8Array> {\n return this.http.requestBytes(\n \"GET\",\n `/api/v1/files?path=${encodeURIComponent(path)}`,\n );\n }\n\n /** Write raw bytes to a file in the sandbox, creating it if it does not exist. */\n async writeFile(path: string, content: Uint8Array): Promise<void> {\n await this.http.requestBytes(\n \"PUT\",\n `/api/v1/files?path=${encodeURIComponent(path)}`,\n { body: content, contentType: \"application/octet-stream\" },\n );\n }\n\n /** Delete a file from the sandbox. */\n async deleteFile(path: string): Promise<void> {\n await this.http.requestJson(\n \"DELETE\",\n `/api/v1/files?path=${encodeURIComponent(path)}`,\n );\n }\n\n /** List the contents of a directory in the sandbox. */\n async listDirectory(path: string): Promise<ListDirectoryResponse> {\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"GET\",\n `/api/v1/files/list?path=${encodeURIComponent(path)}`,\n );\n return fromSnakeKeys(raw) as ListDirectoryResponse;\n }\n\n // --- PTY ---\n\n /** Create an interactive PTY session. Returns a `sessionId` and `token` for WebSocket connection via `connectPty()`. */\n async createPtySession(\n options: CreatePtySessionOptions,\n ): Promise<PtySessionInfo> {\n const payload: Record<string, unknown> = {\n command: options.command,\n rows: options.rows ?? 24,\n cols: options.cols ?? 80,\n };\n if (options.args != null) payload.args = options.args;\n if (options.env != null) payload.env = options.env;\n if (options.workingDir != null) payload.working_dir = options.workingDir;\n\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"POST\",\n \"/api/v1/pty\",\n { body: payload },\n );\n return fromSnakeKeys(raw) as PtySessionInfo;\n }\n\n /** Create a PTY session and connect to it immediately. Cleans up the session if the WebSocket connection fails. */\n async createPty(options: CreatePtyOptions): Promise<Pty> {\n const { onData, onExit, ...createOptions } = options;\n const session = await this.createPtySession(createOptions);\n try {\n return await this.connectPty(session.sessionId, session.token, { onData, onExit });\n } catch (error) {\n try {\n await this.http.requestResponse(\"DELETE\", `/api/v1/pty/${session.sessionId}`);\n } catch {}\n throw error;\n }\n }\n\n /** Attach to an existing PTY session by ID and token and return a connected `Pty` handle. */\n async connectPty(\n sessionId: string,\n token: string,\n options?: PtyConnectionOptions,\n ): Promise<Pty> {\n const wsUrl = new URL(this.ptyWsUrl(sessionId, token));\n const authToken = wsUrl.searchParams.get(\"token\") ?? token;\n\n const pty = new Pty({\n sessionId,\n token: authToken,\n wsUrl: wsUrl.toString(),\n wsHeaders: {\n ...this.wsHeaders,\n \"X-PTY-Token\": authToken,\n },\n killSession: async () => {\n await this.http.requestResponse(\"DELETE\", `/api/v1/pty/${sessionId}`);\n },\n });\n\n if (options?.onData) {\n pty.onData(options.onData);\n }\n if (options?.onExit) {\n pty.onExit(options.onExit);\n }\n\n await pty.connect();\n return pty;\n }\n\n /** Open a TCP tunnel to a port inside the sandbox and return the local listener. */\n async createTunnel(\n remotePort: number,\n options?: CreateTunnelOptions,\n ): Promise<TcpTunnel> {\n return TcpTunnel.listen({\n baseUrl: this.baseUrl,\n wsHeaders: this.wsHeaders,\n remotePort,\n localHost: options?.localHost,\n localPort: options?.localPort,\n connectTimeout: options?.connectTimeout,\n });\n }\n\n /** Connect to a sandbox VNC session for programmatic desktop control. */\n async connectDesktop(options?: ConnectDesktopOptions): Promise<Desktop> {\n return Desktop.connect({\n baseUrl: this.baseUrl,\n wsHeaders: this.wsHeaders,\n port: options?.port,\n password: options?.password,\n shared: options?.shared,\n connectTimeout: options?.connectTimeout,\n });\n }\n\n ptyWsUrl(sessionId: string, token: string): string {\n let wsBase: string;\n if (this.baseUrl.startsWith(\"https://\")) {\n wsBase = \"wss://\" + this.baseUrl.slice(8);\n } else if (this.baseUrl.startsWith(\"http://\")) {\n wsBase = \"ws://\" + this.baseUrl.slice(7);\n } else {\n wsBase = this.baseUrl;\n }\n return `${wsBase}/api/v1/pty/${sessionId}/ws?token=${token}`;\n }\n\n // --- Health ---\n\n /** Check the sandbox daemon health. */\n async health(): Promise<HealthResponse> {\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"GET\",\n \"/api/v1/health\",\n );\n return fromSnakeKeys(raw) as HealthResponse;\n }\n\n /** Get sandbox daemon info (version, uptime, process counts). */\n async info(): Promise<DaemonInfo> {\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"GET\",\n \"/api/v1/info\",\n );\n return fromSnakeKeys(raw) as DaemonInfo;\n }\n}\n","import * as defaults from \"./defaults.js\";\nimport { SandboxError } from \"./errors.js\";\nimport { type Traced, HttpClient } from \"./http.js\";\nimport {\n type CheckpointOptions,\n type ConnectOptions,\n type CreateAndConnectOptions,\n type CreatePoolOptions,\n type CreateSandboxOptions,\n type CreateSandboxPoolResponse,\n type CreateSandboxResponse,\n type CreateSnapshotResponse,\n type SandboxClientOptions,\n type SandboxInfo,\n type SandboxPortAccess,\n type SandboxPoolInfo,\n SandboxStatus,\n type SnapshotAndWaitOptions,\n type SnapshotInfo,\n type SnapshotOptions,\n SnapshotStatus,\n type SuspendResumeOptions,\n type UpdatePoolOptions,\n type UpdateSandboxOptions,\n fromSnakeKeys,\n toSnakeKeys,\n} from \"./models.js\";\nimport { Sandbox } from \"./sandbox.js\";\nimport { isLocalhost, lifecyclePath, resolveProxyUrl } from \"./url.js\";\n\n/**\n * Client for managing TensorLake sandboxes, pools, and snapshots.\n *\n * Use `SandboxClient.forCloud()` or `SandboxClient.forLocalhost()` for\n * clearer construction depending on your deployment target.\n */\nexport class SandboxClient {\n private readonly http: HttpClient;\n private readonly apiUrl: string;\n private readonly apiKey: string | undefined;\n private readonly organizationId: string | undefined;\n private readonly projectId: string | undefined;\n private readonly namespace: string;\n private readonly local: boolean;\n\n /** @internal Pass `true` to suppress the deprecation warning when used by `Sandbox.create()` / `Sandbox.connect()`. */\n constructor(options?: SandboxClientOptions, _internal = false) {\n if (!_internal) {\n console.warn(\n \"[tensorlake] SandboxClient is deprecated; use Sandbox.create() / Sandbox.connect() instead.\",\n );\n }\n this.apiUrl = options?.apiUrl ?? defaults.API_URL;\n this.apiKey = options?.apiKey ?? defaults.API_KEY;\n this.organizationId = options?.organizationId;\n this.projectId = options?.projectId;\n this.namespace = options?.namespace ?? defaults.NAMESPACE;\n this.local = isLocalhost(this.apiUrl);\n\n this.http = new HttpClient({\n baseUrl: this.apiUrl,\n apiKey: this.apiKey,\n organizationId: this.organizationId,\n projectId: this.projectId,\n maxRetries: options?.maxRetries ?? defaults.MAX_RETRIES,\n retryBackoffMs: options?.retryBackoffMs ?? defaults.RETRY_BACKOFF_MS,\n });\n }\n\n /** Create a client for the TensorLake cloud platform. */\n static forCloud(options?: {\n apiKey?: string;\n organizationId?: string;\n projectId?: string;\n apiUrl?: string;\n }): SandboxClient {\n return new SandboxClient({\n apiUrl: options?.apiUrl ?? \"https://api.tensorlake.ai\",\n apiKey: options?.apiKey,\n organizationId: options?.organizationId,\n projectId: options?.projectId,\n });\n }\n\n /** Create a client for a local Indexify server. */\n static forLocalhost(options?: {\n apiUrl?: string;\n namespace?: string;\n }): SandboxClient {\n return new SandboxClient({\n apiUrl: options?.apiUrl ?? \"http://localhost:8900\",\n namespace: options?.namespace ?? \"default\",\n });\n }\n\n close(): void {\n this.http.close();\n }\n\n // --- Path helper ---\n\n private path(subpath: string): string {\n return lifecyclePath(subpath, this.local, this.namespace);\n }\n\n // --- Sandbox CRUD ---\n\n /** Create a new sandbox. Returns immediately; the sandbox may still be starting. Use `createAndConnect()` for a blocking, ready-to-use handle. */\n async create(options?: CreateSandboxOptions): Promise<Traced<CreateSandboxResponse>> {\n const body: Record<string, unknown> = {\n resources: {\n cpus: options?.cpus ?? 1.0,\n memory_mb: options?.memoryMb ?? 1024,\n ...(options?.diskMb != null ? { disk_mb: options.diskMb } : {}),\n },\n };\n\n if (options?.image != null) body.image = options.image;\n if (options?.secretNames != null) body.secret_names = options.secretNames;\n if (options?.timeoutSecs != null) body.timeout_secs = options.timeoutSecs;\n if (options?.entrypoint != null) body.entrypoint = options.entrypoint;\n if (options?.snapshotId != null) body.snapshot_id = options.snapshotId;\n if (options?.name != null) body.name = options.name;\n\n if (\n options?.allowInternetAccess === false ||\n options?.allowOut != null ||\n options?.denyOut != null\n ) {\n body.network = {\n allow_internet_access: options?.allowInternetAccess ?? true,\n allow_out: options?.allowOut ?? [],\n deny_out: options?.denyOut ?? [],\n };\n }\n\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"POST\",\n this.path(\"sandboxes\"),\n { body },\n );\n const result = fromSnakeKeys(raw, \"sandboxId\") as CreateSandboxResponse;\n return Object.assign(result, { traceId: raw.traceId }) as Traced<CreateSandboxResponse>;\n }\n\n /** Get current state and metadata for a sandbox by ID. */\n async get(sandboxId: string): Promise<SandboxInfo> {\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"GET\",\n this.path(`sandboxes/${sandboxId}`),\n );\n return fromSnakeKeys(raw, \"sandboxId\") as SandboxInfo;\n }\n\n /** List all sandboxes in the namespace. */\n async list(): Promise<Traced<SandboxInfo[]>> {\n const raw = await this.http.requestJson<{ sandboxes: Record<string, unknown>[] }>(\n \"GET\",\n this.path(\"sandboxes\"),\n );\n const sandboxes = (raw.sandboxes ?? []).map(\n (s) => fromSnakeKeys(s, \"sandboxId\") as SandboxInfo,\n );\n return Object.assign(sandboxes, { traceId: raw.traceId });\n }\n\n /** Update sandbox properties such as name, exposed ports, and proxy auth settings. */\n async update(sandboxId: string, options: UpdateSandboxOptions): Promise<SandboxInfo> {\n const body: Record<string, unknown> = {};\n if (options.name != null) body.name = options.name;\n if (options.allowUnauthenticatedAccess != null) {\n body.allow_unauthenticated_access = options.allowUnauthenticatedAccess;\n }\n if (options.exposedPorts != null) {\n body.exposed_ports = normalizeUserPorts(options.exposedPorts);\n }\n if (Object.keys(body).length === 0) {\n throw new SandboxError(\"At least one sandbox update field must be provided.\");\n }\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"PATCH\",\n this.path(`sandboxes/${sandboxId}`),\n { body },\n );\n return fromSnakeKeys(raw, \"sandboxId\") as SandboxInfo;\n }\n\n /** Get the current proxy port settings for a sandbox. */\n async getPortAccess(sandboxId: string): Promise<SandboxPortAccess> {\n const info = await this.get(sandboxId);\n return {\n allowUnauthenticatedAccess: info.allowUnauthenticatedAccess ?? false,\n exposedPorts: dedupeAndSortPorts(info.exposedPorts ?? []),\n sandboxUrl: info.sandboxUrl,\n };\n }\n\n /** Add one or more user ports to the sandbox proxy allowlist. */\n async exposePorts(\n sandboxId: string,\n ports: number[],\n options?: { allowUnauthenticatedAccess?: boolean },\n ): Promise<SandboxInfo> {\n const requestedPorts = normalizeUserPorts(ports);\n const current = await this.getPortAccess(sandboxId);\n const desiredPorts = dedupeAndSortPorts([\n ...current.exposedPorts,\n ...requestedPorts,\n ]);\n return this.update(sandboxId, {\n allowUnauthenticatedAccess:\n options?.allowUnauthenticatedAccess ??\n current.allowUnauthenticatedAccess,\n exposedPorts: desiredPorts,\n });\n }\n\n /** Remove one or more user ports from the sandbox proxy allowlist. */\n async unexposePorts(\n sandboxId: string,\n ports: number[],\n ): Promise<SandboxInfo> {\n const requestedPorts = normalizeUserPorts(ports);\n const current = await this.getPortAccess(sandboxId);\n const toRemove = new Set(requestedPorts);\n const desiredPorts = current.exposedPorts.filter((port) => !toRemove.has(port));\n return this.update(sandboxId, {\n allowUnauthenticatedAccess: desiredPorts.length\n ? current.allowUnauthenticatedAccess\n : false,\n exposedPorts: desiredPorts,\n });\n }\n\n /** Terminate and delete a sandbox. */\n async delete(sandboxId: string): Promise<void> {\n await this.http.requestJson(\n \"DELETE\",\n this.path(`sandboxes/${sandboxId}`),\n );\n }\n\n /**\n * Suspend a named sandbox, preserving its state for later resume.\n *\n * Only sandboxes created with a `name` can be suspended; ephemeral sandboxes\n * cannot. By default blocks until the sandbox is fully `Suspended`. Pass\n * `{ wait: false }` to return immediately after the request is sent\n * (fire-and-return); the server processes the suspend asynchronously.\n *\n * @param sandboxId - ID or name of the sandbox.\n * @param options.wait - If `true` (default), poll until `Suspended`. Pass `false` to fire-and-return.\n * @param options.timeout - Max seconds to wait when `wait=true` (default 300).\n * @param options.pollInterval - Seconds between status polls when `wait=true` (default 1).\n * @throws {SandboxError} If `wait=true` and the sandbox does not reach `Suspended` within `timeout`.\n */\n async suspend(sandboxId: string, options?: SuspendResumeOptions): Promise<void> {\n await this.http.requestResponse(\n \"POST\",\n this.path(`sandboxes/${sandboxId}/suspend`),\n );\n if (options?.wait === false) return;\n const timeout = options?.timeout ?? 300;\n const pollInterval = options?.pollInterval ?? 1;\n const deadline = Date.now() + timeout * 1000;\n while (Date.now() < deadline) {\n const info = await this.get(sandboxId);\n if (info.status === SandboxStatus.SUSPENDED) return;\n if (info.status === SandboxStatus.TERMINATED) {\n throw new SandboxError(`Sandbox ${sandboxId} terminated while waiting for suspend`);\n }\n await sleep(pollInterval * 1000);\n }\n throw new SandboxError(`Sandbox ${sandboxId} did not suspend within ${timeout}s`);\n }\n\n /**\n * Resume a suspended sandbox and bring it back to `Running`.\n *\n * By default blocks until the sandbox is `Running` and routable. Pass\n * `{ wait: false }` to return immediately after the request is sent\n * (fire-and-return); the server processes the resume asynchronously.\n *\n * @param sandboxId - ID or name of the sandbox.\n * @param options.wait - If `true` (default), poll until `Running`. Pass `false` to fire-and-return.\n * @param options.timeout - Max seconds to wait when `wait=true` (default 300).\n * @param options.pollInterval - Seconds between status polls when `wait=true` (default 1).\n * @throws {SandboxError} If `wait=true` and the sandbox does not reach `Running` within `timeout`.\n */\n async resume(sandboxId: string, options?: SuspendResumeOptions): Promise<void> {\n await this.http.requestResponse(\n \"POST\",\n this.path(`sandboxes/${sandboxId}/resume`),\n );\n if (options?.wait === false) return;\n const timeout = options?.timeout ?? 300;\n const pollInterval = options?.pollInterval ?? 1;\n const deadline = Date.now() + timeout * 1000;\n while (Date.now() < deadline) {\n const info = await this.get(sandboxId);\n if (info.status === SandboxStatus.RUNNING) return;\n if (info.status === SandboxStatus.TERMINATED) {\n throw new SandboxError(`Sandbox ${sandboxId} terminated while waiting for resume`);\n }\n await sleep(pollInterval * 1000);\n }\n throw new SandboxError(`Sandbox ${sandboxId} did not resume within ${timeout}s`);\n }\n\n /** Claim a warm sandbox from a pool, creating one if no warm containers are available. */\n async claim(poolId: string): Promise<Traced<CreateSandboxResponse>> {\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"POST\",\n this.path(`sandbox-pools/${poolId}/sandboxes`),\n );\n const result = fromSnakeKeys(raw, \"sandboxId\") as CreateSandboxResponse;\n return Object.assign(result, { traceId: raw.traceId }) as Traced<CreateSandboxResponse>;\n }\n\n // --- Snapshots ---\n\n /**\n * Request a snapshot of a running sandbox's filesystem.\n *\n * This call **returns immediately** with a `snapshotId` and `in_progress`\n * status — the snapshot is created asynchronously. Poll `getSnapshot()` until\n * `completed` or `failed`, or use `snapshotAndWait()` to block automatically.\n *\n * @param options.contentMode - `\"filesystem_only\"` for cold-boot snapshots (e.g. image builds).\n * Omit to use the server default (full VM snapshot).\n */\n async snapshot(\n sandboxId: string,\n options?: SnapshotOptions,\n ): Promise<CreateSnapshotResponse> {\n // Preserve today's wire shape (no body) when contentMode is not set.\n const requestOptions =\n options?.contentMode != null\n ? { body: { snapshot_content_mode: options.contentMode } }\n : undefined;\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"POST\",\n this.path(`sandboxes/${sandboxId}/snapshot`),\n requestOptions,\n );\n return fromSnakeKeys(raw, \"snapshotId\") as CreateSnapshotResponse;\n }\n\n /** Get current status and metadata for a snapshot by ID. */\n async getSnapshot(snapshotId: string): Promise<SnapshotInfo> {\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"GET\",\n this.path(`snapshots/${snapshotId}`),\n );\n return fromSnakeKeys(raw, \"snapshotId\") as SnapshotInfo;\n }\n\n /** List all snapshots in the namespace. */\n async listSnapshots(): Promise<Traced<SnapshotInfo[]>> {\n const raw = await this.http.requestJson<{ snapshots: Record<string, unknown>[] }>(\n \"GET\",\n this.path(\"snapshots\"),\n );\n const snapshots = (raw.snapshots ?? []).map(\n (s) => fromSnakeKeys(s, \"snapshotId\") as SnapshotInfo,\n );\n return Object.assign(snapshots, { traceId: raw.traceId });\n }\n\n /** Delete a snapshot by ID. */\n async deleteSnapshot(snapshotId: string): Promise<void> {\n await this.http.requestJson(\n \"DELETE\",\n this.path(`snapshots/${snapshotId}`),\n );\n }\n\n /**\n * Create a snapshot and block until it is committed.\n *\n * Combines `snapshot()` with polling `getSnapshot()` until `completed`.\n * Prefer `sandbox.checkpoint()` on a `Sandbox` handle for the same behavior\n * without managing the client separately.\n *\n * @param sandboxId - ID of the running sandbox to snapshot.\n * @param options.timeout - Max seconds to wait (default 300).\n * @param options.pollInterval - Seconds between status polls (default 1).\n * @param options.contentMode - Content mode passed through to `snapshot()`.\n * @throws {SandboxError} If the snapshot fails or `timeout` elapses.\n */\n async snapshotAndWait(\n sandboxId: string,\n options?: SnapshotAndWaitOptions,\n ): Promise<SnapshotInfo> {\n const timeout = options?.timeout ?? 300;\n const pollInterval = options?.pollInterval ?? 1;\n\n const result = await this.snapshot(sandboxId, {\n contentMode: options?.contentMode,\n });\n const deadline = Date.now() + timeout * 1000;\n\n while (Date.now() < deadline) {\n const info = await this.getSnapshot(result.snapshotId);\n if (info.status === SnapshotStatus.COMPLETED) return info;\n if (info.status === SnapshotStatus.FAILED) {\n throw new SandboxError(\n `Snapshot ${result.snapshotId} failed: ${info.error}`,\n );\n }\n await sleep(pollInterval * 1000);\n }\n\n throw new SandboxError(\n `Snapshot ${result.snapshotId} did not complete within ${timeout}s`,\n );\n }\n\n // --- Pools ---\n\n /** Create a new sandbox pool with warm pre-booted containers. */\n async createPool(options: CreatePoolOptions): Promise<CreateSandboxPoolResponse> {\n const body: Record<string, unknown> = {\n image: options.image,\n resources: {\n cpus: options.cpus ?? 1.0,\n memory_mb: options.memoryMb ?? 1024,\n ephemeral_disk_mb: options.ephemeralDiskMb ?? 1024,\n },\n timeout_secs: options.timeoutSecs ?? 0,\n };\n\n if (options.secretNames != null) body.secret_names = options.secretNames;\n if (options.entrypoint != null) body.entrypoint = options.entrypoint;\n if (options.maxContainers != null) body.max_containers = options.maxContainers;\n if (options.warmContainers != null) body.warm_containers = options.warmContainers;\n\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"POST\",\n this.path(\"sandbox-pools\"),\n { body },\n );\n return fromSnakeKeys(raw, \"poolId\") as CreateSandboxPoolResponse;\n }\n\n /** Get current state and metadata for a sandbox pool by ID. */\n async getPool(poolId: string): Promise<SandboxPoolInfo> {\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"GET\",\n this.path(`sandbox-pools/${poolId}`),\n );\n return fromSnakeKeys(raw, \"poolId\") as SandboxPoolInfo;\n }\n\n /** List all sandbox pools in the namespace. */\n async listPools(): Promise<Traced<SandboxPoolInfo[]>> {\n const raw = await this.http.requestJson<{ pools: Record<string, unknown>[] }>(\n \"GET\",\n this.path(\"sandbox-pools\"),\n );\n const pools = (raw.pools ?? []).map(\n (p) => fromSnakeKeys(p, \"poolId\") as SandboxPoolInfo,\n );\n return Object.assign(pools, { traceId: raw.traceId });\n }\n\n /** Replace the configuration of an existing sandbox pool. */\n async updatePool(\n poolId: string,\n options: UpdatePoolOptions,\n ): Promise<SandboxPoolInfo> {\n const body: Record<string, unknown> = {\n image: options.image,\n resources: {\n cpus: options.cpus ?? 1.0,\n memory_mb: options.memoryMb ?? 1024,\n ephemeral_disk_mb: options.ephemeralDiskMb ?? 1024,\n },\n timeout_secs: options.timeoutSecs ?? 0,\n };\n\n if (options.secretNames != null) body.secret_names = options.secretNames;\n if (options.entrypoint != null) body.entrypoint = options.entrypoint;\n if (options.maxContainers != null) body.max_containers = options.maxContainers;\n if (options.warmContainers != null) body.warm_containers = options.warmContainers;\n\n const raw = await this.http.requestJson<Record<string, unknown>>(\n \"PUT\",\n this.path(`sandbox-pools/${poolId}`),\n { body },\n );\n return fromSnakeKeys(raw, \"poolId\") as SandboxPoolInfo;\n }\n\n /** Delete a sandbox pool. Fails if the pool has active containers. */\n async deletePool(poolId: string): Promise<void> {\n await this.http.requestJson(\n \"DELETE\",\n this.path(`sandbox-pools/${poolId}`),\n );\n }\n\n // --- Connect ---\n\n /** Return a `Sandbox` handle for an existing running sandbox without verifying it exists. */\n connect(identifier: string, proxyUrl?: string, routingHint?: string): Sandbox {\n const resolvedProxy = proxyUrl ?? resolveProxyUrl(this.apiUrl);\n return new Sandbox({\n sandboxId: identifier,\n proxyUrl: resolvedProxy,\n apiKey: this.apiKey,\n organizationId: this.organizationId,\n projectId: this.projectId,\n routingHint,\n });\n }\n\n /**\n * Create a sandbox, wait for it to reach `Running`, and return a connected handle.\n *\n * Blocks until the sandbox is ready or `startupTimeout` elapses. The returned\n * `Sandbox` auto-terminates when `terminate()` is called.\n *\n * @param options.startupTimeout - Max seconds to wait for `Running` status (default 60).\n * @throws {SandboxError} If the sandbox terminates during startup or the timeout elapses.\n */\n async createAndConnect(\n options?: CreateAndConnectOptions,\n ): Promise<Sandbox> {\n const startupTimeout = options?.startupTimeout ?? 60;\n\n // claim() never sends options.name to the server, so only create() should fall\n // back to it locally when the server response omits a name.\n const result = options?.poolId != null\n ? await this.claim(options.poolId)\n : await this.create(options);\n const requestedName = options?.poolId != null ? null : options?.name ?? null;\n\n const finishConnect = (routingHint: string | undefined, name: string | null | undefined) => {\n const sandbox = this.connect(result.sandboxId, options?.proxyUrl, routingHint);\n sandbox._setOwner(this);\n sandbox.traceId = result.traceId;\n sandbox._setLifecycleIdentifier(result.sandboxId);\n sandbox._setName(name ?? requestedName);\n return sandbox;\n };\n\n // Fast path: the blocking create/claim response already carries Running status\n // and a short-lived routing hint. Use it immediately to skip an extra poll RTT\n // and let the proxy route the first request without a placement lookup.\n if (result.status === SandboxStatus.RUNNING) {\n return finishConnect(result.routingHint, result.name);\n }\n if (\n result.status === SandboxStatus.SUSPENDED ||\n result.status === SandboxStatus.TERMINATED\n ) {\n throw new SandboxError(\n formatStartupFailureMessage(result.sandboxId, result.status, {\n errorDetails: result.errorDetails,\n terminationReason: result.terminationReason,\n }),\n );\n }\n\n const deadline = Date.now() + startupTimeout * 1000;\n\n while (Date.now() < deadline) {\n const info = await this.get(result.sandboxId);\n if (info.status === SandboxStatus.RUNNING) {\n return finishConnect(info.routingHint, info.name);\n }\n if (\n info.status === SandboxStatus.SUSPENDED ||\n info.status === SandboxStatus.TERMINATED\n ) {\n throw new SandboxError(\n formatStartupFailureMessage(result.sandboxId, info.status, {\n errorDetails: info.errorDetails,\n terminationReason: info.terminationReason,\n }),\n );\n }\n await sleep(500);\n }\n\n // Timed out — clean up\n try {\n await this.delete(result.sandboxId);\n } catch {\n // ignore cleanup failures\n }\n throw new SandboxError(\n `Sandbox ${result.sandboxId} did not start within ${startupTimeout}s`,\n );\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction formatStartupFailureMessage(\n sandboxId: string,\n status: SandboxStatus | string,\n options: {\n errorDetails?: unknown;\n terminationReason?: string;\n },\n): string {\n const prefix = status === SandboxStatus.TERMINATED\n ? `Sandbox ${sandboxId} terminated during startup`\n : `Sandbox ${sandboxId} became ${status} during startup`;\n const detail = formatErrorDetails(options.errorDetails);\n if (detail) {\n return `${prefix}: ${detail}`;\n }\n if (options.terminationReason) {\n return `${prefix}: termination reason: ${options.terminationReason}`;\n }\n return prefix;\n}\n\nfunction formatErrorDetails(errorDetails: unknown): string | undefined {\n if (errorDetails == null) return undefined;\n if (typeof errorDetails === \"string\") {\n const detail = errorDetails.trim();\n return detail || undefined;\n }\n if (Array.isArray(errorDetails)) {\n const parts = errorDetails\n .map((item) => formatErrorDetails(item))\n .filter((item): item is string => Boolean(item));\n return parts.length > 0 ? parts.join(\"; \") : JSON.stringify(errorDetails);\n }\n if (typeof errorDetails === \"object\") {\n for (const key of [\"message\", \"detail\", \"error\", \"reason\"]) {\n const value = (errorDetails as Record<string, unknown>)[key];\n if (typeof value === \"string\" && value.trim()) {\n return value.trim();\n }\n }\n return JSON.stringify(errorDetails);\n }\n return String(errorDetails);\n}\n\nconst RESERVED_SANDBOX_MANAGEMENT_PORT = 9501;\n\nfunction normalizeUserPorts(ports: number[]): number[] {\n return dedupeAndSortPorts(ports.map(validateUserPort));\n}\n\nfunction validateUserPort(port: number): number {\n if (!Number.isInteger(port) || port < 1 || port > 65535) {\n throw new SandboxError(`invalid port '${port}'`);\n }\n if (port === RESERVED_SANDBOX_MANAGEMENT_PORT) {\n throw new SandboxError(\"port 9501 is reserved for sandbox management\");\n }\n return port;\n}\n\nfunction dedupeAndSortPorts(ports: number[]): number[] {\n return [...new Set(ports)].sort((a, b) => a - b);\n}\n","import { randomUUID } from \"node:crypto\";\n\n// Erased at runtime — safe despite the module cycle with sandbox-image.ts,\n// which imports Image from here.\nimport type { CreateSandboxImageOptions } from \"./sandbox-image.js\";\n\nconst DEFAULT_IMAGE_NAME = \"default\";\n\nexport const ImageBuildOperationType = {\n ADD: \"ADD\",\n COPY: \"COPY\",\n ENV: \"ENV\",\n RUN: \"RUN\",\n WORKDIR: \"WORKDIR\",\n} as const;\n\nexport type ImageBuildOperationType =\n (typeof ImageBuildOperationType)[keyof typeof ImageBuildOperationType];\n\nexport interface ImageBuildOperation {\n type: ImageBuildOperationType;\n args: string[];\n options: Record<string, string>;\n}\n\nexport interface ImageOptions {\n name?: string;\n tag?: string;\n baseImage?: string | null;\n}\n\nfunction cloneOperation(op: ImageBuildOperation): ImageBuildOperation {\n return {\n type: op.type,\n args: [...op.args],\n options: { ...op.options },\n };\n}\n\nexport class Image {\n readonly _id: string;\n readonly _name: string;\n readonly _tag: string;\n readonly _baseImage: string | null;\n readonly _buildOperations: ImageBuildOperation[];\n\n constructor();\n constructor(name: string, tag?: string, baseImage?: string | null);\n constructor(options: ImageOptions);\n constructor(\n nameOrOptions: string | ImageOptions = {},\n tag = \"latest\",\n baseImage: string | null = null,\n ) {\n this._id = randomUUID();\n this._buildOperations = [];\n\n if (typeof nameOrOptions === \"string\") {\n this._name = nameOrOptions;\n this._tag = tag;\n this._baseImage = baseImage;\n return;\n }\n\n this._name = nameOrOptions.name ?? DEFAULT_IMAGE_NAME;\n this._tag = nameOrOptions.tag ?? \"latest\";\n this._baseImage = nameOrOptions.baseImage ?? null;\n }\n\n get name(): string {\n return this._name;\n }\n\n get tag(): string {\n return this._tag;\n }\n\n get baseImage(): string | null {\n return this._baseImage;\n }\n\n get buildOperations(): ImageBuildOperation[] {\n return this._buildOperations.map(cloneOperation);\n }\n\n add(\n src: string,\n dest: string,\n options: Record<string, string> | undefined = undefined,\n ): this {\n return this._addOperation({\n type: ImageBuildOperationType.ADD,\n args: [src, dest],\n options: options == null ? {} : { ...options },\n });\n }\n\n copy(\n src: string,\n dest: string,\n options: Record<string, string> | undefined = undefined,\n ): this {\n return this._addOperation({\n type: ImageBuildOperationType.COPY,\n args: [src, dest],\n options: options == null ? {} : { ...options },\n });\n }\n\n env(key: string, value: string): this {\n return this._addOperation({\n type: ImageBuildOperationType.ENV,\n args: [key, value],\n options: {},\n });\n }\n\n run(\n commands: string | string[],\n options: Record<string, string> | undefined = undefined,\n ): this {\n return this._addOperation({\n type: ImageBuildOperationType.RUN,\n args: Array.isArray(commands) ? [...commands] : [commands],\n options: options == null ? {} : { ...options },\n });\n }\n\n workdir(directory: string): this {\n return this._addOperation({\n type: ImageBuildOperationType.WORKDIR,\n args: [directory],\n options: {},\n });\n }\n\n /**\n * Build this image as a sandbox template and register it.\n *\n * Materializes the image in a build sandbox, snapshots the filesystem,\n * and registers the snapshot as a named sandbox template.\n */\n async build(\n options: CreateSandboxImageOptions = {},\n ): Promise<Record<string, unknown>> {\n if ((options.registeredName ?? this._name) === DEFAULT_IMAGE_NAME) {\n // eslint-disable-next-line no-console\n console.warn(\n `Building sandbox image with the default name \"${DEFAULT_IMAGE_NAME}\". ` +\n \"Pass `registeredName` or `Image({ name })` to avoid collisions \" +\n \"with other default-named images in this project.\",\n );\n }\n const { createSandboxImage } = await import(\"./sandbox-image.js\");\n return createSandboxImage(this, options);\n }\n\n private _addOperation(op: ImageBuildOperation): this {\n this._buildOperations.push(op);\n return this;\n }\n}\n\nfunction renderOptions(options: Record<string, string>): string {\n const entries = Object.entries(options);\n if (entries.length === 0) {\n return \"\";\n }\n return ` ${entries.map(([key, value]) => `--${key}=${value}`).join(\" \")}`;\n}\n\nfunction renderBuildOp(op: ImageBuildOperation): string {\n const options = renderOptions(op.options);\n if (op.type === ImageBuildOperationType.ENV) {\n return `ENV${options} ${op.args[0]}=${JSON.stringify(op.args[1])}`;\n }\n return `${op.type}${options} ${op.args.join(\" \")}`;\n}\n\nexport function dockerfileContent(image: Image): string {\n const lines = image.baseImage == null ? [] : [`FROM ${image.baseImage}`];\n lines.push(...image.buildOperations.map((op) => renderBuildOp(op)));\n return lines.join(\"\\n\");\n}\n","import { readFile, readdir, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { parseArgs } from \"node:util\";\nimport {\n type CommandResult,\n type ProcessInfo,\n type SnapshotContentMode,\n type SnapshotInfo,\n} from \"./models.js\";\nimport { type OutputResponse, ProcessStatus } from \"./models.js\";\nimport { SandboxClient } from \"./client.js\";\nimport { Image, dockerfileContent } from \"./image.js\";\n\nconst BUILD_SANDBOX_PIP_ENV = { PIP_BREAK_SYSTEM_PACKAGES: \"1\" } as const;\nconst IGNORED_DOCKERFILE_INSTRUCTIONS = new Set([\n \"CMD\",\n \"ENTRYPOINT\",\n \"EXPOSE\",\n \"HEALTHCHECK\",\n \"LABEL\",\n \"STOPSIGNAL\",\n \"VOLUME\",\n]);\nconst UNSUPPORTED_DOCKERFILE_INSTRUCTIONS = new Set([\n \"ARG\",\n \"ONBUILD\",\n \"SHELL\",\n \"USER\",\n]);\n\nexport interface DockerfileInstruction {\n keyword: string;\n value: string;\n lineNumber: number;\n}\n\nexport interface DockerfileBuildPlan {\n dockerfilePath: string;\n contextDir: string;\n registeredName: string;\n dockerfileText: string;\n baseImage?: string;\n instructions: DockerfileInstruction[];\n}\n\nexport interface CreateSandboxImageOptions {\n registeredName?: string;\n cpus?: number;\n memoryMb?: number;\n diskMb?: number;\n isPublic?: boolean;\n contextDir?: string;\n /**\n * Print build progress to stderr. Ignored when an explicit `emit` is passed\n * via `deps`. Defaults to false — `createSandboxImage` is silent by default\n * when invoked programmatically (e.g. `Image.build()`).\n */\n verbose?: boolean;\n}\n\nexport type SandboxImageSource = string | Image;\n\ninterface BuildContext {\n apiUrl: string;\n apiKey?: string;\n personalAccessToken?: string;\n namespace: string;\n organizationId?: string;\n projectId?: string;\n debug: boolean;\n}\n\ninterface BuildSandbox {\n sandboxId: string;\n run(\n command: string,\n options?: {\n args?: string[];\n env?: Record<string, string>;\n workingDir?: string;\n timeout?: number;\n },\n ): Promise<CommandResult>;\n startProcess(\n command: string,\n options?: {\n args?: string[];\n env?: Record<string, string>;\n workingDir?: string;\n },\n ): Promise<ProcessInfo>;\n getStdout(pid: number): Promise<OutputResponse>;\n getStderr(pid: number): Promise<OutputResponse>;\n getProcess(pid: number): Promise<ProcessInfo>;\n writeFile(path: string, content: Uint8Array): Promise<void>;\n terminate(): Promise<void>;\n}\n\ninterface BuildClient {\n createAndConnect(options: {\n image?: string;\n cpus?: number;\n memoryMb?: number;\n diskMb?: number;\n }): Promise<BuildSandbox>;\n snapshotAndWait(\n sandboxId: string,\n options?: {\n timeout?: number;\n pollInterval?: number;\n contentMode?: SnapshotContentMode;\n },\n ): Promise<SnapshotInfo>;\n close(): void;\n}\n\ninterface CreateSandboxImageDeps {\n emit?: (event: Record<string, unknown>) => void;\n createClient?: (context: BuildContext) => BuildClient;\n registerImage?: (\n context: BuildContext,\n name: string,\n dockerfile: string,\n snapshotId: string,\n snapshotSandboxId: string,\n snapshotUri: string,\n snapshotSizeBytes: number,\n rootfsDiskBytes: number,\n isPublic: boolean,\n ) => Promise<Record<string, unknown>>;\n sleep?: (ms: number) => Promise<void>;\n}\n\nexport function defaultRegisteredName(dockerfilePath: string): string {\n const parsed = path.parse(dockerfilePath);\n if (parsed.name.toLowerCase() === \"dockerfile\") {\n const parentName = path.basename(path.dirname(dockerfilePath)).trim();\n return parentName || \"sandbox-image\";\n }\n return parsed.name || \"sandbox-image\";\n}\n\nexport function logicalDockerfileLines(\n dockerfileText: string,\n): Array<{ lineNumber: number; line: string }> {\n const logicalLines: Array<{ lineNumber: number; line: string }> = [];\n let parts: string[] = [];\n let startLine: number | null = null;\n\n for (const [index, rawLine] of dockerfileText.split(/\\r?\\n/).entries()) {\n const lineNumber = index + 1;\n const stripped = rawLine.trim();\n if (parts.length === 0 && (!stripped || stripped.startsWith(\"#\"))) {\n continue;\n }\n\n if (startLine == null) {\n startLine = lineNumber;\n }\n\n let line = rawLine.replace(/\\s+$/, \"\");\n const continued = line.endsWith(\"\\\\\");\n if (continued) {\n line = line.slice(0, -1);\n }\n\n const normalized = line.trim();\n if (normalized && !normalized.startsWith(\"#\")) {\n parts.push(normalized);\n }\n\n if (continued) {\n continue;\n }\n\n if (parts.length > 0) {\n logicalLines.push({\n lineNumber: startLine ?? lineNumber,\n line: parts.join(\" \"),\n });\n }\n parts = [];\n startLine = null;\n }\n\n if (parts.length > 0) {\n logicalLines.push({\n lineNumber: startLine ?? 1,\n line: parts.join(\" \"),\n });\n }\n\n return logicalLines;\n}\n\nfunction splitInstruction(\n line: string,\n lineNumber: number,\n): { keyword: string; value: string } {\n const trimmed = line.trim();\n if (!trimmed) {\n throw new Error(`line ${lineNumber}: empty Dockerfile instruction`);\n }\n const match = trimmed.match(/^(\\S+)(?:\\s+(.*))?$/);\n if (!match) {\n throw new Error(`line ${lineNumber}: invalid Dockerfile instruction`);\n }\n return {\n keyword: match[1].toUpperCase(),\n value: (match[2] ?? \"\").trim(),\n };\n}\n\nfunction shellSplit(input: string): string[] {\n const tokens: string[] = [];\n let current = \"\";\n let quote: \"'\" | '\"' | null = null;\n let escape = false;\n\n for (let i = 0; i < input.length; i++) {\n const char = input[i];\n\n if (escape) {\n current += char;\n escape = false;\n continue;\n }\n\n if (quote == null) {\n if (/\\s/.test(char)) {\n if (current) {\n tokens.push(current);\n current = \"\";\n }\n continue;\n }\n if (char === \"'\" || char === '\"') {\n quote = char;\n continue;\n }\n if (char === \"\\\\\") {\n escape = true;\n continue;\n }\n current += char;\n continue;\n }\n\n if (quote === \"'\") {\n if (char === \"'\") {\n quote = null;\n } else {\n current += char;\n }\n continue;\n }\n\n if (char === '\"') {\n quote = null;\n continue;\n }\n if (char === \"\\\\\") {\n const next = input[++i];\n if (next == null) {\n throw new Error(`unterminated escape sequence in '${input}'`);\n }\n current += next;\n continue;\n }\n current += char;\n }\n\n if (escape) {\n throw new Error(`unterminated escape sequence in '${input}'`);\n }\n if (quote != null) {\n throw new Error(`unterminated quoted string in '${input}'`);\n }\n if (current) {\n tokens.push(current);\n }\n return tokens;\n}\n\nfunction shellQuote(value: string): string {\n if (!value) {\n return \"''\";\n }\n return `'${value.replace(/'/g, `'\\\\''`)}'`;\n}\n\nfunction stripLeadingFlags(value: string): {\n flags: Record<string, string>;\n remaining: string;\n} {\n const flags: Record<string, string> = {};\n let remaining = value.trimStart();\n\n while (remaining.startsWith(\"--\")) {\n const firstSpace = remaining.indexOf(\" \");\n if (firstSpace === -1) {\n throw new Error(`invalid Dockerfile flag syntax: ${value}`);\n }\n\n const token = remaining.slice(0, firstSpace);\n const rest = remaining.slice(firstSpace + 1).trimStart();\n const flagBody = token.slice(2);\n\n if (flagBody.includes(\"=\")) {\n const [key, flagValue] = flagBody.split(/=(.*)/s, 2);\n flags[key] = flagValue;\n remaining = rest;\n continue;\n }\n\n const [flagValue, ...restTokens] = shellSplit(rest);\n if (flagValue == null) {\n throw new Error(`missing value for Dockerfile flag '${token}'`);\n }\n flags[flagBody] = flagValue;\n remaining = restTokens.join(\" \");\n }\n\n return { flags, remaining };\n}\n\nfunction parseFromValue(value: string, lineNumber: number): string {\n const { remaining } = stripLeadingFlags(value);\n const tokens = shellSplit(remaining);\n if (tokens.length === 0) {\n throw new Error(`line ${lineNumber}: FROM must include a base image`);\n }\n if (tokens.length > 1 && tokens[1].toLowerCase() !== \"as\") {\n throw new Error(`line ${lineNumber}: unsupported FROM syntax '${value}'`);\n }\n return tokens[0];\n}\n\nfunction parseCopyLikeValues(\n value: string,\n lineNumber: number,\n keyword: string,\n): {\n flags: Record<string, string>;\n sources: string[];\n destination: string;\n} {\n const { flags, remaining } = stripLeadingFlags(value);\n if (\"from\" in flags) {\n throw new Error(\n `line ${lineNumber}: ${keyword} --from is not supported for sandbox image creation`,\n );\n }\n\n const payload = remaining.trim();\n if (!payload) {\n throw new Error(\n `line ${lineNumber}: ${keyword} must include source and destination`,\n );\n }\n\n let parts: string[];\n if (payload.startsWith(\"[\")) {\n let parsed: unknown;\n try {\n parsed = JSON.parse(payload);\n } catch (error) {\n throw new Error(\n `line ${lineNumber}: invalid JSON array syntax for ${keyword}: ${(error as Error).message}`,\n );\n }\n if (\n !Array.isArray(parsed) ||\n parsed.length < 2 ||\n parsed.some((item) => typeof item !== \"string\")\n ) {\n throw new Error(\n `line ${lineNumber}: ${keyword} JSON array form requires at least two string values`,\n );\n }\n parts = parsed as string[];\n } else {\n parts = shellSplit(payload);\n if (parts.length < 2) {\n throw new Error(\n `line ${lineNumber}: ${keyword} must include at least one source and one destination`,\n );\n }\n }\n\n return {\n flags,\n sources: parts.slice(0, -1),\n destination: parts[parts.length - 1],\n };\n}\n\nfunction parseEnvPairs(value: string, lineNumber: number): Array<[string, string]> {\n const tokens = shellSplit(value);\n if (tokens.length === 0) {\n throw new Error(`line ${lineNumber}: ENV must include a key and value`);\n }\n\n if (tokens.every((token) => token.includes(\"=\"))) {\n return tokens.map((token) => {\n const [key, envValue] = token.split(/=(.*)/s, 2);\n if (!key) {\n throw new Error(`line ${lineNumber}: invalid ENV token '${token}'`);\n }\n return [key, envValue] as [string, string];\n });\n }\n\n if (tokens.length < 2) {\n throw new Error(`line ${lineNumber}: ENV must include a key and value`);\n }\n\n return [[tokens[0], tokens.slice(1).join(\" \")]];\n}\n\nfunction resolveContainerPath(containerPath: string, workingDir: string): string {\n if (!containerPath) {\n return workingDir;\n }\n const normalized = containerPath.startsWith(\"/\")\n ? path.posix.normalize(containerPath)\n : path.posix.normalize(path.posix.join(workingDir, containerPath));\n return normalized.startsWith(\"/\") ? normalized : `/${normalized}`;\n}\n\nfunction buildPlanFromDockerfileText(\n dockerfileText: string,\n dockerfilePath: string,\n contextDir: string,\n registeredName?: string,\n): DockerfileBuildPlan {\n let baseImage: string | undefined;\n const instructions: DockerfileInstruction[] = [];\n\n for (const logicalLine of logicalDockerfileLines(dockerfileText)) {\n const { keyword, value } = splitInstruction(\n logicalLine.line,\n logicalLine.lineNumber,\n );\n if (keyword === \"FROM\") {\n if (baseImage != null) {\n throw new Error(\n `line ${logicalLine.lineNumber}: multi-stage Dockerfiles are not supported for sandbox image creation`,\n );\n }\n baseImage = parseFromValue(value, logicalLine.lineNumber);\n continue;\n }\n\n if (UNSUPPORTED_DOCKERFILE_INSTRUCTIONS.has(keyword)) {\n throw new Error(\n `line ${logicalLine.lineNumber}: Dockerfile instruction '${keyword}' is not supported for sandbox image creation`,\n );\n }\n\n instructions.push({\n keyword,\n value,\n lineNumber: logicalLine.lineNumber,\n });\n }\n\n if (!baseImage) {\n throw new Error(\"Dockerfile must contain a FROM instruction\");\n }\n\n return {\n dockerfilePath,\n contextDir,\n registeredName: registeredName ?? defaultRegisteredName(dockerfilePath),\n dockerfileText,\n baseImage,\n instructions,\n };\n}\n\nexport async function loadDockerfilePlan(\n dockerfilePath: string,\n registeredName?: string,\n): Promise<DockerfileBuildPlan> {\n const resolvedPath = path.resolve(dockerfilePath);\n const fileStats = await stat(resolvedPath).catch(() => null);\n if (!fileStats?.isFile()) {\n throw new Error(`Dockerfile not found: ${dockerfilePath}`);\n }\n\n const dockerfileText = await readFile(resolvedPath, \"utf8\");\n return buildPlanFromDockerfileText(\n dockerfileText,\n resolvedPath,\n path.dirname(resolvedPath),\n registeredName,\n );\n}\n\nexport function loadImagePlan(\n image: Image,\n options: Pick<CreateSandboxImageOptions, \"registeredName\" | \"contextDir\"> = {},\n): DockerfileBuildPlan {\n const contextDir = path.resolve(options.contextDir ?? process.cwd());\n const dockerfileText = dockerfileContent(image);\n const logicalLines = logicalDockerfileLines(dockerfileText);\n const instructions = image.baseImage == null ? logicalLines : logicalLines.slice(1);\n\n return {\n dockerfilePath: path.join(contextDir, \"Dockerfile\"),\n contextDir,\n registeredName: options.registeredName ?? image.name,\n dockerfileText,\n baseImage: image.baseImage ?? undefined,\n instructions: instructions.map(({ line, lineNumber }) => {\n const parsed = splitInstruction(line, lineNumber);\n return {\n keyword: parsed.keyword,\n value: parsed.value,\n lineNumber,\n };\n }),\n };\n}\n\nfunction ndjsonStdoutEmit(event: Record<string, unknown>) {\n process.stdout.write(`${JSON.stringify(event)}\\n`);\n}\n\nfunction noopEmit(_event: Record<string, unknown>) {}\n\nfunction stderrEmit(event: Record<string, unknown>) {\n const type = typeof event.type === \"string\" ? event.type : \"\";\n const message = typeof event.message === \"string\" ? event.message : \"\";\n if (type === \"build_log\") {\n const stream = typeof event.stream === \"string\" ? event.stream : \"stdout\";\n process.stderr.write(`[${stream}] ${message}\\n`);\n } else if (message) {\n process.stderr.write(`[${type}] ${message}\\n`);\n }\n}\n\nfunction debugEnabled(): boolean {\n return [\"1\", \"true\", \"yes\", \"on\"].includes(\n (process.env.TENSORLAKE_DEBUG ?? \"\").toLowerCase(),\n );\n}\n\nfunction buildContextFromEnv(): BuildContext {\n return {\n apiUrl: process.env.TENSORLAKE_API_URL ?? \"https://api.tensorlake.ai\",\n apiKey: process.env.TENSORLAKE_API_KEY,\n personalAccessToken: process.env.TENSORLAKE_PAT,\n namespace: process.env.INDEXIFY_NAMESPACE ?? \"default\",\n organizationId: process.env.TENSORLAKE_ORGANIZATION_ID,\n projectId: process.env.TENSORLAKE_PROJECT_ID,\n debug: debugEnabled(),\n };\n}\n\nfunction createDefaultClient(context: BuildContext): BuildClient {\n return new SandboxClient({\n apiUrl: context.apiUrl,\n apiKey: context.apiKey ?? context.personalAccessToken,\n organizationId: context.organizationId,\n projectId: context.projectId,\n namespace: context.namespace,\n });\n}\n\nasync function runChecked(\n sandbox: BuildSandbox,\n command: string,\n args: string[],\n env?: Record<string, string>,\n workingDir?: string,\n): Promise<CommandResult> {\n const result = await sandbox.run(command, {\n args,\n env,\n workingDir,\n });\n if (result.exitCode !== 0) {\n throw new Error(\n `Command '${command} ${args.join(\" \")}' failed with exit code ${result.exitCode}`,\n );\n }\n return result;\n}\n\nasync function runStreaming(\n sandbox: BuildSandbox,\n emit: (event: Record<string, unknown>) => void,\n sleep: (ms: number) => Promise<void>,\n command: string,\n args: string[] = [],\n env?: Record<string, string>,\n workingDir?: string,\n) {\n const proc = await sandbox.startProcess(command, {\n args,\n env,\n workingDir,\n });\n\n let stdoutSeen = 0;\n let stderrSeen = 0;\n let info: ProcessInfo;\n\n while (true) {\n const stdoutResp = await sandbox.getStdout(proc.pid);\n emitOutputLines(emit, \"stdout\", stdoutResp, stdoutSeen);\n stdoutSeen = stdoutResp.lines.length;\n\n const stderrResp = await sandbox.getStderr(proc.pid);\n emitOutputLines(emit, \"stderr\", stderrResp, stderrSeen);\n stderrSeen = stderrResp.lines.length;\n\n info = await sandbox.getProcess(proc.pid);\n if (info.status !== ProcessStatus.RUNNING) {\n const finalStdout = await sandbox.getStdout(proc.pid);\n emitOutputLines(emit, \"stdout\", finalStdout, stdoutSeen);\n stdoutSeen = finalStdout.lines.length;\n\n const finalStderr = await sandbox.getStderr(proc.pid);\n emitOutputLines(emit, \"stderr\", finalStderr, stderrSeen);\n break;\n }\n\n await sleep(300);\n }\n\n for (let i = 0; i < 10; i++) {\n if (info.exitCode != null || info.signal != null) {\n break;\n }\n await sleep(200);\n info = await sandbox.getProcess(proc.pid);\n }\n\n const exitCode =\n info.exitCode != null ? info.exitCode : info.signal != null ? -info.signal : 0;\n if (exitCode !== 0) {\n throw new Error(\n `Command '${command} ${args.join(\" \")}' failed with exit code ${exitCode}`,\n );\n }\n}\n\nfunction emitOutputLines(\n emit: (event: Record<string, unknown>) => void,\n stream: \"stdout\" | \"stderr\",\n response: OutputResponse,\n seen: number,\n) {\n for (const line of response.lines.slice(seen)) {\n emit({ type: \"build_log\", stream, message: line });\n }\n}\n\nfunction isPathWithinContext(contextDir: string, localPath: string): boolean {\n const relative = path.relative(contextDir, localPath);\n return relative === \"\" || (!relative.startsWith(\"..\") && !path.isAbsolute(relative));\n}\n\nfunction resolveContextSourcePath(contextDir: string, source: string): string {\n const resolvedContextDir = path.resolve(contextDir);\n const resolvedSource = path.resolve(resolvedContextDir, source);\n if (!isPathWithinContext(resolvedContextDir, resolvedSource)) {\n throw new Error(`Local path escapes the build context: ${source}`);\n }\n return resolvedSource;\n}\n\nasync function copyLocalPathToSandbox(\n sandbox: BuildSandbox,\n localPath: string,\n remotePath: string,\n) {\n const fileStats = await stat(localPath).catch(() => null);\n if (!fileStats) {\n throw new Error(`Local path not found: ${localPath}`);\n }\n\n if (fileStats.isFile()) {\n await runChecked(sandbox, \"mkdir\", [\"-p\", path.posix.dirname(remotePath)]);\n await sandbox.writeFile(remotePath, await readFile(localPath));\n return;\n }\n\n if (!fileStats.isDirectory()) {\n throw new Error(`Local path not found: ${localPath}`);\n }\n\n const entries = await readdir(localPath, { withFileTypes: true });\n for (const entry of entries) {\n const sourcePath = path.join(localPath, entry.name);\n const destinationPath = path.posix.join(remotePath, entry.name);\n if (entry.isDirectory()) {\n await runChecked(sandbox, \"mkdir\", [\"-p\", destinationPath]);\n await copyLocalPathToSandbox(sandbox, sourcePath, destinationPath);\n } else if (entry.isFile()) {\n await runChecked(\n sandbox,\n \"mkdir\",\n [\"-p\", path.posix.dirname(destinationPath)],\n );\n await sandbox.writeFile(destinationPath, await readFile(sourcePath));\n }\n }\n}\n\nasync function persistEnvVar(\n sandbox: BuildSandbox,\n processEnv: Record<string, string>,\n key: string,\n value: string,\n) {\n const exportLine = `export ${key}=${shellQuote(value)}`;\n await runChecked(\n sandbox,\n \"sh\",\n [\"-c\", `printf '%s\\\\n' ${shellQuote(exportLine)} >> /etc/environment`],\n processEnv,\n );\n}\n\nasync function copyFromContext(\n sandbox: BuildSandbox,\n emit: (event: Record<string, unknown>) => void,\n contextDir: string,\n sources: string[],\n destination: string,\n workingDir: string,\n keyword: string,\n) {\n const destinationPath = resolveContainerPath(destination, workingDir);\n if (sources.length > 1 && !destinationPath.endsWith(\"/\")) {\n throw new Error(\n `${keyword} with multiple sources requires a directory destination ending in '/'`,\n );\n }\n\n for (const source of sources) {\n const localSource = resolveContextSourcePath(contextDir, source);\n const localStats = await stat(localSource).catch(() => null);\n if (!localStats) {\n throw new Error(`Local path not found: ${localSource}`);\n }\n\n let remoteDestination = destinationPath;\n if (sources.length > 1) {\n remoteDestination = path.posix.join(\n destinationPath.replace(/\\/$/, \"\"),\n path.posix.basename(source.replace(/\\/$/, \"\")),\n );\n } else if (localStats.isFile() && destinationPath.endsWith(\"/\")) {\n remoteDestination = path.posix.join(\n destinationPath.replace(/\\/$/, \"\"),\n path.basename(source),\n );\n }\n\n emit({\n type: \"status\",\n message: `${keyword} ${source} -> ${remoteDestination}`,\n });\n await copyLocalPathToSandbox(sandbox, localSource, remoteDestination);\n }\n}\n\nasync function addUrlToSandbox(\n sandbox: BuildSandbox,\n emit: (event: Record<string, unknown>) => void,\n url: string,\n destination: string,\n workingDir: string,\n processEnv: Record<string, string>,\n sleep: (ms: number) => Promise<void>,\n) {\n let destinationPath = resolveContainerPath(destination, workingDir);\n const parsedUrl = new URL(url);\n const fileName = path.posix.basename(parsedUrl.pathname.replace(/\\/$/, \"\")) || \"downloaded\";\n if (destinationPath.endsWith(\"/\")) {\n destinationPath = path.posix.join(destinationPath.replace(/\\/$/, \"\"), fileName);\n }\n\n const parentDir = path.posix.dirname(destinationPath) || \"/\";\n emit({\n type: \"status\",\n message: `ADD ${url} -> ${destinationPath}`,\n });\n await runChecked(sandbox, \"mkdir\", [\"-p\", parentDir], processEnv);\n await runStreaming(\n sandbox,\n emit,\n sleep,\n \"sh\",\n [\n \"-c\",\n `curl -fsSL --location ${shellQuote(url)} -o ${shellQuote(destinationPath)}`,\n ],\n processEnv,\n workingDir,\n );\n}\n\nasync function executeDockerfilePlan(\n sandbox: BuildSandbox,\n plan: DockerfileBuildPlan,\n emit: (event: Record<string, unknown>) => void,\n sleep: (ms: number) => Promise<void>,\n) {\n const processEnv: Record<string, string> = { ...BUILD_SANDBOX_PIP_ENV };\n let workingDir = \"/\";\n\n for (const instruction of plan.instructions) {\n const { keyword, value, lineNumber } = instruction;\n\n if (keyword === \"RUN\") {\n emit({ type: \"status\", message: `RUN ${value}` });\n await runStreaming(\n sandbox,\n emit,\n sleep,\n \"sh\",\n [\"-c\", value],\n processEnv,\n workingDir,\n );\n continue;\n }\n\n if (keyword === \"WORKDIR\") {\n const tokens = shellSplit(value);\n if (tokens.length !== 1) {\n throw new Error(`line ${lineNumber}: WORKDIR must include exactly one path`);\n }\n workingDir = resolveContainerPath(tokens[0], workingDir);\n emit({ type: \"status\", message: `WORKDIR ${workingDir}` });\n await runChecked(sandbox, \"mkdir\", [\"-p\", workingDir], processEnv);\n continue;\n }\n\n if (keyword === \"ENV\") {\n for (const [key, envValue] of parseEnvPairs(value, lineNumber)) {\n emit({ type: \"status\", message: `ENV ${key}=${envValue}` });\n processEnv[key] = envValue;\n await persistEnvVar(sandbox, processEnv, key, envValue);\n }\n continue;\n }\n\n if (keyword === \"COPY\") {\n const { sources, destination } = parseCopyLikeValues(\n value,\n lineNumber,\n keyword,\n );\n await copyFromContext(\n sandbox,\n emit,\n plan.contextDir,\n sources,\n destination,\n workingDir,\n keyword,\n );\n continue;\n }\n\n if (keyword === \"ADD\") {\n const { sources, destination } = parseCopyLikeValues(\n value,\n lineNumber,\n keyword,\n );\n if (\n sources.length === 1 &&\n /^https?:\\/\\//.test(sources[0])\n ) {\n await addUrlToSandbox(\n sandbox,\n emit,\n sources[0],\n destination,\n workingDir,\n processEnv,\n sleep,\n );\n } else {\n await copyFromContext(\n sandbox,\n emit,\n plan.contextDir,\n sources,\n destination,\n workingDir,\n keyword,\n );\n }\n continue;\n }\n\n if (IGNORED_DOCKERFILE_INSTRUCTIONS.has(keyword)) {\n emit({\n type: \"warning\",\n message: `Skipping Dockerfile instruction '${keyword}' during snapshot materialization. It is still preserved in the registered Dockerfile.`,\n });\n continue;\n }\n\n throw new Error(\n `line ${lineNumber}: Dockerfile instruction '${keyword}' is not supported for sandbox image creation`,\n );\n }\n}\n\nasync function registerImage(\n context: BuildContext,\n name: string,\n dockerfile: string,\n snapshotId: string,\n snapshotSandboxId: string,\n snapshotUri: string,\n snapshotSizeBytes: number,\n rootfsDiskBytes: number,\n isPublic: boolean,\n): Promise<Record<string, unknown>> {\n if (!context.organizationId || !context.projectId) {\n throw new Error(\n \"Organization ID and Project ID are required. Run 'tl login' and 'tl init'.\",\n );\n }\n\n const bearerToken = context.apiKey ?? context.personalAccessToken;\n if (!bearerToken) {\n throw new Error(\"Missing TENSORLAKE_API_KEY or TENSORLAKE_PAT.\");\n }\n\n const baseUrl = context.apiUrl.replace(/\\/+$/, \"\");\n const url =\n `${baseUrl}/platform/v1/organizations/` +\n `${encodeURIComponent(context.organizationId)}/projects/` +\n `${encodeURIComponent(context.projectId)}/sandbox-templates`;\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${bearerToken}`,\n \"Content-Type\": \"application/json\",\n };\n if (context.personalAccessToken && !context.apiKey) {\n headers[\"X-Forwarded-Organization-Id\"] = context.organizationId;\n headers[\"X-Forwarded-Project-Id\"] = context.projectId;\n }\n\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n name,\n dockerfile,\n snapshotId,\n snapshotSandboxId,\n snapshotUri,\n snapshotSizeBytes,\n rootfsDiskBytes,\n public: isPublic,\n }),\n });\n\n if (!response.ok) {\n throw new Error(\n `${response.status} ${response.statusText}: ${await response.text()}`,\n );\n }\n\n const text = await response.text();\n return text ? (JSON.parse(text) as Record<string, unknown>) : {};\n}\n\nexport async function createSandboxImage(\n source: SandboxImageSource,\n options: CreateSandboxImageOptions = {},\n deps: CreateSandboxImageDeps = {},\n) {\n const emit = deps.emit ?? (options.verbose ? stderrEmit : noopEmit);\n const sleep = deps.sleep ?? ((ms: number) => new Promise((r) => setTimeout(r, ms)));\n const context = buildContextFromEnv();\n const clientFactory = deps.createClient ?? createDefaultClient;\n const register =\n deps.registerImage ??\n ((...args) => registerImage(...args));\n\n const sourceLabel =\n typeof source === \"string\" ? source : `Image(${source.name})`;\n emit({ type: \"status\", message: `Loading ${sourceLabel}...` });\n const plan =\n typeof source === \"string\"\n ? await loadDockerfilePlan(source, options.registeredName)\n : loadImagePlan(source, options);\n emit({\n type: \"status\",\n message:\n plan.baseImage == null\n ? \"Starting build sandbox with the default server image...\"\n : `Starting build sandbox from ${plan.baseImage}...`,\n });\n\n const client = clientFactory(context);\n let sandbox: BuildSandbox | undefined;\n\n try {\n sandbox = await client.createAndConnect({\n ...(plan.baseImage == null ? {} : { image: plan.baseImage }),\n cpus: options.cpus ?? 2.0,\n memoryMb: options.memoryMb ?? 4096,\n ...(options.diskMb != null ? { diskMb: options.diskMb } : {}),\n });\n\n emit({\n type: \"status\",\n message: `Materializing image in sandbox ${sandbox.sandboxId}...`,\n });\n await executeDockerfilePlan(sandbox, plan, emit, sleep);\n\n emit({ type: \"status\", message: \"Creating snapshot...\" });\n const snapshot = await client.snapshotAndWait(sandbox.sandboxId, {\n contentMode: \"filesystem_only\",\n });\n emit({\n type: \"snapshot_created\",\n snapshot_id: snapshot.snapshotId,\n });\n\n if (!snapshot.snapshotUri) {\n throw new Error(\n `Snapshot ${snapshot.snapshotId} is missing snapshotUri and cannot be registered as a sandbox image.`,\n );\n }\n if (snapshot.sizeBytes == null) {\n throw new Error(\n `Snapshot ${snapshot.snapshotId} is missing sizeBytes and cannot be registered as a sandbox image.`,\n );\n }\n if (snapshot.rootfsDiskBytes == null) {\n throw new Error(\n `Snapshot ${snapshot.snapshotId} is missing rootfsDiskBytes and cannot be registered as a sandbox image.`,\n );\n }\n\n emit({\n type: \"status\",\n message: `Registering image '${plan.registeredName}'...`,\n });\n const result = await register(\n context,\n plan.registeredName,\n plan.dockerfileText,\n snapshot.snapshotId,\n snapshot.sandboxId,\n snapshot.snapshotUri,\n snapshot.sizeBytes,\n snapshot.rootfsDiskBytes,\n options.isPublic ?? false,\n );\n\n emit({\n type: \"image_registered\",\n name: plan.registeredName,\n image_id:\n (typeof result.id === \"string\" && result.id) ||\n (typeof result.templateId === \"string\" && result.templateId) ||\n \"\",\n });\n emit({ type: \"done\" });\n return result;\n } finally {\n if (sandbox) {\n try {\n await sandbox.terminate();\n } catch {}\n }\n client.close();\n }\n}\n\nexport async function runCreateSandboxImageCli(argv = process.argv.slice(2)) {\n const parsed = parseArgs({\n args: argv,\n allowPositionals: true,\n options: {\n name: { type: \"string\", short: \"n\" },\n cpus: { type: \"string\" },\n memory: { type: \"string\" },\n disk: { type: \"string\" },\n public: { type: \"boolean\", default: false },\n },\n });\n\n const dockerfilePath = parsed.positionals[0];\n if (!dockerfilePath) {\n throw new Error(\"Usage: tensorlake-create-sandbox-image <dockerfile_path> [--name NAME] [--cpus N] [--memory MB] [--disk GB] [--public]\");\n }\n\n const cpus =\n parsed.values.cpus != null ? Number(parsed.values.cpus) : undefined;\n const memoryMb =\n parsed.values.memory != null ? Number(parsed.values.memory) : undefined;\n const diskGb =\n parsed.values.disk != null ? Number(parsed.values.disk) : undefined;\n if (cpus != null && !Number.isFinite(cpus)) {\n throw new Error(`Invalid --cpus value: ${parsed.values.cpus}`);\n }\n if (memoryMb != null && !Number.isInteger(memoryMb)) {\n throw new Error(`Invalid --memory value: ${parsed.values.memory}`);\n }\n if (diskGb != null && !Number.isInteger(diskGb)) {\n throw new Error(`Invalid --disk value: ${parsed.values.disk}`);\n }\n\n await createSandboxImage(\n dockerfilePath,\n {\n registeredName: parsed.values.name,\n cpus,\n memoryMb,\n diskMb: diskGb != null ? diskGb * 1024 : undefined,\n isPublic: parsed.values.public,\n },\n { emit: ndjsonStdoutEmit },\n );\n}\n"],"mappings":"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QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAClD;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QACnD;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAClD;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,MACrD;AAAA,MACA;AAAA,QACE;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QACnD;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAI;AAAA,QAAI;AAAA,QACnD;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QACnD;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,MACpD;AAAA,MACA;AAAA,QACE;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAClD;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QACnD;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QACnD;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,MACpD;AAAA,MACA;AAAA,QACE;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QACnD;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QACnD;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAClD;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,MACrD;AAAA,MACA;AAAA,QACE;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAClD;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QACnD;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QACnD;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,MACpD;AAAA,MACA;AAAA,QACE;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QACnD;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAAG;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QAAI;AAAA,QAAG;AAAA,QACnD;AAAA,QAAG;AAAA,QAAG;AAA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","names":["path","buttonMask","validatePort","secondsToMillis","value","path","WebSocket","SandboxClient","path","sleep","flagValue","sleep"]}