@declaw/sdk 1.2.1 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/dist/index.cjs +43 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +59 -1
- package/dist/index.d.ts +59 -1
- package/dist/index.js +42 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/connectionConfig.ts","../src/errors.ts","../src/api/client.ts","../src/sandbox/network.ts","../src/security/pii.ts","../src/security/injection.ts","../src/security/audit.ts","../src/security/env.ts","../src/security/networkPolicy.ts","../src/security/transformations.ts","../src/security/toxicity.ts","../src/security/codeSecurity.ts","../src/security/invisibleText.ts","../src/security/customPolicy.ts","../src/security/contentGate.ts","../src/security/policy.ts","../src/sandbox/models.ts","../src/sandbox/commands/models.ts","../src/sandbox/commands/commandHandle.ts","../src/sandbox/commands/commands.ts","../src/sandbox/filesystem/models.ts","../src/sandbox/filesystem/watchHandle.ts","../src/sandbox/filesystem/filesystem.ts","../src/sandbox/pty/pty.ts","../src/sandbox/stdio/stdio.ts","../src/volumes/models.ts","../src/sandbox/sandbox.ts","../src/paginator.ts","../src/template/models.ts","../src/template/template.ts","../src/volumes/files.ts","../src/volumes/locks.ts","../src/volumes/volumes.ts","../src/governance/models.ts","../src/governance/governance.ts"],"sourcesContent":["// API Client\nexport { ApiClient, getSharedClient, resetSharedClients } from './api/client.js';\nexport type { RequestOpts } from './api/client.js';\n\n// Sandbox\nexport { Sandbox } from './sandbox/sandbox.js';\nexport type { SandboxOpts } from './sandbox/sandbox.js';\n\n// Errors\nexport {\n SandboxError,\n TimeoutError,\n NotFoundError,\n AuthenticationError,\n InvalidArgumentError,\n NotEnoughSpaceError,\n ConflictError,\n TemplateError,\n BuildError,\n FileUploadError,\n GitAuthError,\n GitUpstreamError,\n CommandExitError,\n} from './errors.js';\n\n// Connection config\nexport { ConnectionConfig } from './connectionConfig.js';\nexport type { ConnectionConfigOptions } from './connectionConfig.js';\n\n// Sandbox models\nexport {\n SandboxState,\n parseSandboxInfo,\n parseSandboxMetrics,\n parseSandboxLifecycle,\n parseSnapshotInfo,\n parseSnapshot,\n} from './sandbox/models.js';\nexport type {\n SandboxInfo,\n SandboxMetrics,\n SandboxQuery,\n SandboxLifecycle,\n SnapshotInfo,\n Snapshot,\n SnapshotSource,\n} from './sandbox/models.js';\n\n// Commands\nexport { Commands } from './sandbox/commands/commands.js';\nexport type { RunOpts, RunStreamOpts } from './sandbox/commands/commands.js';\nexport { CommandHandle } from './sandbox/commands/commandHandle.js';\nexport type { CommandWaitOpts } from './sandbox/commands/commandHandle.js';\n\n// Command models\nexport { parseCommandResult, parseProcessInfo } from './sandbox/commands/models.js';\nexport type {\n CommandResult,\n ProcessInfo,\n PtySize,\n PtyOutput,\n Stdout,\n Stderr,\n} from './sandbox/commands/models.js';\n\n// Filesystem\nexport { Filesystem } from './sandbox/filesystem/filesystem.js';\nexport { WatchHandle } from './sandbox/filesystem/watchHandle.js';\n\n// Filesystem models\nexport {\n FileType,\n FilesystemEventType,\n parseEntryInfo,\n parseWriteInfo,\n parseFilesystemEvent,\n} from './sandbox/filesystem/models.js';\nexport type {\n EntryInfo,\n WriteInfo,\n WriteEntry,\n FilesystemEvent,\n} from './sandbox/filesystem/models.js';\n\n// Network\nexport { ALL_TRAFFIC, validateNetworkEntry, domainMatches } from './sandbox/network.js';\nexport type { SandboxNetworkOpts } from './sandbox/network.js';\n\n// Security - PII\nexport { PIIType, RedactionAction, createPIIConfig, parsePIIConfig } from './security/pii.js';\nexport type { PIIConfig } from './security/pii.js';\n\n// Security - Injection\nexport {\n InjectionSensitivity,\n InjectionAction,\n createInjectionDefenseConfig,\n parseInjectionDefenseConfig,\n} from './security/injection.js';\nexport type { InjectionDefenseConfig } from './security/injection.js';\n\n// Security - Audit\nexport { createAuditConfig, parseAuditConfig, parseAuditEntry } from './security/audit.js';\nexport type { AuditConfig, AuditEntry } from './security/audit.js';\n\n// Security - Env\nexport {\n DEFAULT_MASK_PATTERNS,\n createEnvSecurityConfig,\n parseEnvSecurityConfig,\n isSensitive,\n} from './security/env.js';\nexport type { EnvSecurityConfig, SecureEnvVar } from './security/env.js';\n\n// Security - Transformations\nexport {\n TransformDirection,\n createTransformationRule,\n applyTransformation,\n} from './security/transformations.js';\nexport type { TransformationRule } from './security/transformations.js';\n\n// Security - Network Policy\nexport {\n createNetworkPolicy,\n parseNetworkPolicy,\n networkPolicyToOpts,\n} from './security/networkPolicy.js';\nexport type { NetworkPolicy } from './security/networkPolicy.js';\n\n// Security - Toxicity\nexport {\n createToxicityConfig,\n parseToxicityConfig,\n toxicityConfigToJSON,\n} from './security/toxicity.js';\nexport type { ToxicityConfig } from './security/toxicity.js';\n\n// Security - Code Security\nexport {\n createCodeSecurityConfig,\n parseCodeSecurityConfig,\n codeSecurityConfigToJSON,\n} from './security/codeSecurity.js';\nexport type { CodeSecurityConfig } from './security/codeSecurity.js';\n\n// Security - Invisible Text\nexport {\n createInvisibleTextConfig,\n parseInvisibleTextConfig,\n invisibleTextConfigToJSON,\n} from './security/invisibleText.js';\nexport type { InvisibleTextConfig } from './security/invisibleText.js';\n\n// Security - Content Gate\nexport {\n createContentGateConfig,\n parseContentGateConfig,\n contentGateConfigToJSON,\n} from './security/contentGate.js';\nexport type { ContentGateConfig } from './security/contentGate.js';\n\n// Security - Policy\nexport {\n createSecurityPolicy,\n parseSecurityPolicy,\n securityPolicyToJSON,\n requiresTlsInterception,\n} from './security/policy.js';\nexport type { SecurityPolicy } from './security/policy.js';\n\n// PTY\nexport { Pty, PtyHandle } from './sandbox/pty/pty.js';\nexport type { PtyCreateOpts, PtyConnectOpts, PtyResult } from './sandbox/pty/pty.js';\n\n// Stdio\nexport { Stdio, StdioProcess } from './sandbox/stdio/stdio.js';\nexport type { StdioStartOpts, StdioResult } from './sandbox/stdio/stdio.js';\n\n// Paginators\nexport { SandboxPaginator, SnapshotPaginator } from './paginator.js';\n\n// Template\nexport { Template } from './template/template.js';\nexport type { TemplateBuildOpts, GetBuildStatusOpts } from './template/template.js';\n\n// Template models\nexport { TemplateBase, parseBuildInfo, parseTemplateBuildStatus } from './template/models.js';\nexport type { CopyItem, BuildInfo, TemplateBuildStatus } from './template/models.js';\n\n// Volumes\nexport { Volumes } from './volumes/volumes.js';\nexport type { VolumeCreateOpts } from './volumes/volumes.js';\nexport type { VolumeRequestOpts } from './volumes/types.js';\nexport { VolumeFiles } from './volumes/files.js';\nexport type { VolumeWriteOpts, VolumeRemoveOpts } from './volumes/files.js';\nexport { VolumeLocks } from './volumes/locks.js';\nexport {\n parseVolumeInfo,\n parseFileEntry,\n parseFileInfo,\n parseLockLease,\n parseLockStatus,\n volumeAttachmentToJSON,\n} from './volumes/models.js';\nexport type {\n VolumeInfo,\n VolumeAttachment,\n VolumeAttachMode,\n FileEntry,\n FileInfo,\n LockLease,\n LockStatus,\n} from './volumes/models.js';\n\n// Governance\nexport { Governance } from './governance/governance.js';\nexport type { GovernanceRequestOpts } from './governance/governance.js';\nexport { parseGovernancePack } from './governance/models.js';\nexport type { GovernancePack, GovernanceControl, GovernanceAdvisory } from './governance/models.js';\n","/**\n * Configuration for connecting to the Declaw API.\n */\nexport interface ConnectionConfigOptions {\n /** API key for authentication. Defaults to DECLAW_API_KEY env var. */\n apiKey?: string;\n /** Domain of the Declaw API. Defaults to DECLAW_DOMAIN env var or 'api.declaw.ai'. */\n domain?: string;\n /** Port of the Declaw API. Defaults to 443. */\n port?: number;\n /** Full API URL override. If set, domain/port/scheme are ignored. */\n apiUrl?: string;\n /** Request timeout in milliseconds. */\n requestTimeout?: number;\n}\n\n/**\n * Holds connection configuration for the Declaw API.\n */\nexport class ConnectionConfig {\n readonly apiKey: string;\n readonly domain: string;\n readonly port: number;\n readonly apiUrl: string;\n readonly requestTimeout?: number;\n\n constructor(opts?: ConnectionConfigOptions) {\n this.apiKey = opts?.apiKey ?? process.env.DECLAW_API_KEY ?? '';\n this.requestTimeout = opts?.requestTimeout;\n\n // Parse \"host:port\" from domain, matching Python SDK behavior.\n // e.g. domain=\"myhost.example.com:8080\" → domain=\"myhost.example.com\", port=8080\n let rawDomain = opts?.domain ?? process.env.DECLAW_DOMAIN ?? 'api.declaw.ai';\n let rawPort = opts?.port ?? 443;\n\n if (opts?.port === undefined && rawDomain.includes(':')) {\n const lastColon = rawDomain.lastIndexOf(':');\n const maybPort = parseInt(rawDomain.substring(lastColon + 1), 10);\n if (!isNaN(maybPort)) {\n rawPort = maybPort;\n rawDomain = rawDomain.substring(0, lastColon);\n }\n }\n\n this.domain = rawDomain;\n this.port = rawPort;\n\n if (opts?.apiUrl) {\n this.apiUrl = opts.apiUrl;\n } else {\n const scheme = this.port === 443 ? 'https' : 'http';\n if (this.port === 443 || this.port === 80) {\n this.apiUrl = `${scheme}://${this.domain}`;\n } else {\n this.apiUrl = `${scheme}://${this.domain}:${this.port}`;\n }\n }\n }\n}\n","/**\n * Base error for all sandbox-related errors.\n */\nexport class SandboxError extends Error {\n sandboxId?: string;\n\n constructor(message: string, opts?: { sandboxId?: string }) {\n super(message);\n this.name = 'SandboxError';\n this.sandboxId = opts?.sandboxId;\n }\n}\n\n/** Thrown when an operation exceeds its timeout. */\nexport class TimeoutError extends SandboxError {\n constructor(message: string, opts?: { sandboxId?: string }) {\n super(message, opts);\n this.name = 'TimeoutError';\n }\n}\n\n/** Thrown when a sandbox or resource is not found. */\nexport class NotFoundError extends SandboxError {\n constructor(message: string, opts?: { sandboxId?: string }) {\n super(message, opts);\n this.name = 'NotFoundError';\n }\n}\n\n/** Thrown when authentication fails. */\nexport class AuthenticationError extends SandboxError {\n constructor(message: string, opts?: { sandboxId?: string }) {\n super(message, opts);\n this.name = 'AuthenticationError';\n }\n}\n\n/** Thrown when an argument is invalid. */\nexport class InvalidArgumentError extends SandboxError {\n constructor(message: string, opts?: { sandboxId?: string }) {\n super(message, opts);\n this.name = 'InvalidArgumentError';\n }\n}\n\n/** Thrown when there is not enough disk space. */\nexport class NotEnoughSpaceError extends SandboxError {\n constructor(message: string, opts?: { sandboxId?: string }) {\n super(message, opts);\n this.name = 'NotEnoughSpaceError';\n }\n}\n\n/**\n * Thrown on an HTTP 409 conflict.\n *\n * For volume file writes this signals a CAS (compare-and-swap) version\n * mismatch — the file changed since the `if_version` token was read. For\n * volume locks it signals the lock is already held by another holder (on\n * acquire) or that the caller is not the current holder (on release/renew).\n * Catch this to re-read and retry.\n */\nexport class ConflictError extends SandboxError {\n constructor(message: string, opts?: { sandboxId?: string }) {\n super(message, opts);\n this.name = 'ConflictError';\n }\n}\n\n/** Thrown for template-related errors. */\nexport class TemplateError extends SandboxError {\n constructor(message: string, opts?: { sandboxId?: string }) {\n super(message, opts);\n this.name = 'TemplateError';\n }\n}\n\n/** Thrown when a template build fails. */\nexport class BuildError extends TemplateError {\n constructor(message: string, opts?: { sandboxId?: string }) {\n super(message, opts);\n this.name = 'BuildError';\n }\n}\n\n/** Thrown when a file upload fails. */\nexport class FileUploadError extends SandboxError {\n constructor(message: string, opts?: { sandboxId?: string }) {\n super(message, opts);\n this.name = 'FileUploadError';\n }\n}\n\n/** Thrown when git authentication fails inside a sandbox. */\nexport class GitAuthError extends SandboxError {\n constructor(message: string, opts?: { sandboxId?: string }) {\n super(message, opts);\n this.name = 'GitAuthError';\n }\n}\n\n/** Thrown when a git upstream operation fails. */\nexport class GitUpstreamError extends SandboxError {\n constructor(message: string, opts?: { sandboxId?: string }) {\n super(message, opts);\n this.name = 'GitUpstreamError';\n }\n}\n\n/** Thrown when a command exits with a non-zero exit code. */\nexport class CommandExitError extends SandboxError {\n exitCode: number;\n stdout: string;\n stderr: string;\n\n constructor(\n message: string,\n opts: { sandboxId?: string; exitCode: number; stdout: string; stderr: string },\n ) {\n super(message, { sandboxId: opts.sandboxId });\n this.name = 'CommandExitError';\n this.exitCode = opts.exitCode;\n this.stdout = opts.stdout;\n this.stderr = opts.stderr;\n }\n}\n","import { ConnectionConfig } from '../connectionConfig.js';\nimport {\n SandboxError,\n TimeoutError,\n NotFoundError,\n AuthenticationError,\n InvalidArgumentError,\n NotEnoughSpaceError,\n ConflictError,\n} from '../errors.js';\n\n// ---------------------------------------------------------------------------\n// undici dispatcher (Node only).\n//\n// Node's built-in fetch() is backed by undici, which defaults to 10\n// connections per origin. When callers fan out many concurrent requests\n// (e.g. `Promise.all` of many `Sandbox.create()` calls) that cap becomes\n// a client-side serialization point.\n//\n// We lazily install a module-scope undici Agent with a larger pool and\n// keep-alive tuned for the Declaw backend. On runtimes that don't ship\n// undici (browsers, Cloudflare Workers, Deno), the dynamic import\n// silently fails and we fall through to the platform's native fetch.\n//\n// Tuning knobs (env vars — defaults sized so common burst workloads\n// \"just work\" without configuration):\n// DECLAW_SDK_CONNECTIONS=N — TCP connection pool size (default 64)\n// DECLAW_SDK_MAX_CONCURRENT_STREAMS=N — H2 streams per connection (default 1000;\n// undici's hard-coded default is 100)\n// DECLAW_SDK_DISABLE_DISPATCHER=1 — opt out, use platform fetch\n//\n// Math: pool capacity = connections × streams.\n// At defaults (64 × 1000 = 64,000) a single Node process handles up to\n// 60 k+ concurrent Sandbox.create() calls with zero client-side queueing.\n// The 64-connection pool keeps TCP setup overhead minimal on cold start\n// (benchmark-faster than larger pools at typical burst-100 workloads),\n// while the 1000-stream-per-connection ceiling stays well under the\n// server's advertised SETTINGS_MAX_CONCURRENT_STREAMS=4096 so undici\n// never has to back off on a single connection. For workloads above\n// 64 k concurrent in-flight, raise DECLAW_SDK_CONNECTIONS (e.g. 100 →\n// 100,000 cap). Memory cost is modest: idle pool state is ~15 MB; sockets\n// close after keepAliveTimeout=30s if unused. Low-concurrency callers\n// pay only for what they actually use — the pool is lazy (sockets are\n// dialed on demand).\n// ---------------------------------------------------------------------------\nlet _dispatcherPromise: Promise<unknown | undefined> | undefined;\n// Synchronously-cached resolved dispatcher. Once the import settles we store\n// the value here so the hot path skips `await getDispatcher()` entirely (an\n// await of even a resolved promise costs a microtask yield, which compounds\n// under burst fan-out). `undefined` is a valid resolved state (non-Node / opt\n// out); the separate `_dispatcherResolved` flag distinguishes \"resolved to\n// undefined\" from \"not yet resolved\".\nlet _resolvedDispatcher: unknown | undefined;\nlet _dispatcherResolved = false;\n\nfunction getDispatcher(): Promise<unknown | undefined> {\n if (_dispatcherPromise) return _dispatcherPromise;\n _dispatcherPromise = (async () => {\n try {\n // Only Node exposes process.versions.node; everything else bails.\n if (typeof process === 'undefined' || !process.versions?.node) {\n return undefined;\n }\n // Respect opt-out for users who bring their own dispatcher.\n if (process.env.DECLAW_SDK_DISABLE_DISPATCHER) {\n return undefined;\n }\n const undici: any = await import('undici');\n const connOverride = parseInt(process.env.DECLAW_SDK_CONNECTIONS || '', 10);\n const connections = Number.isFinite(connOverride) && connOverride > 0 ? connOverride : 64;\n const streamsOverride = parseInt(process.env.DECLAW_SDK_MAX_CONCURRENT_STREAMS || '', 10);\n const maxConcurrentStreams =\n Number.isFinite(streamsOverride) && streamsOverride > 0 ? streamsOverride : 1000;\n return new undici.Agent({\n connections,\n // maxConcurrentStreams only matters on H2 connections. undici negotiates\n // down to whatever the server advertises in SETTINGS_MAX_CONCURRENT_STREAMS,\n // so setting a high value here is safe — it caps the client-side intent,\n // server still wins.\n maxConcurrentStreams,\n keepAliveTimeout: 30_000,\n keepAliveMaxTimeout: 60_000,\n // NOTE: do NOT set `pipelining` here. undici applies it to H2 sessions\n // too, where `pipelining: 1` caps each connection to ONE in-flight\n // stream — silently defeating the H2 multiplexing that allowH2 enables.\n // Omitted, H2 sessions default to unlimited concurrent streams (capped\n // by maxConcurrentStreams) and H1.1 fallback defaults to 1 (safe, no\n // head-of-line risk on non-idempotent POSTs). This is the single\n // biggest burst-latency lever: with pipelining:1 a 100-concurrent burst\n // queued ~36 requests behind the `connections` cap.\n allowH2: true,\n connect: { keepAlive: true, keepAliveInitialDelay: 5_000 },\n });\n } catch {\n return undefined;\n }\n })();\n // Cache the resolved value synchronously so the hot path can skip the await.\n void _dispatcherPromise.then((d) => {\n _resolvedDispatcher = d;\n _dispatcherResolved = true;\n });\n return _dispatcherPromise;\n}\n\n// Eagerly kick off the undici import at module load instead of lazily on the\n// first request. Without this, the first burst of concurrent creates all queue\n// on the one unresolved `import('undici')` (~40-63ms cold). Firing it here moves\n// that cost onto module init, so by the time the first create runs it's ready.\nvoid getDispatcher();\n\n/**\n * Options for individual API requests.\n */\nexport interface RequestOpts {\n /** JSON body to serialize and send. */\n json?: unknown;\n /** Query parameters to append to the URL. */\n params?: Record<string, string>;\n /** Additional headers to merge with defaults. */\n headers?: Record<string, string>;\n /** Per-request timeout in milliseconds. Overrides config.requestTimeout. */\n timeout?: number;\n /** Raw body (string or Uint8Array). If set, json is ignored. */\n body?: string | Uint8Array;\n}\n\n/** Map of HTTP status codes to error classes. */\nconst STATUS_ERROR_MAP: Record<number, new (message: string) => SandboxError> = {\n 400: InvalidArgumentError,\n 401: AuthenticationError,\n 403: AuthenticationError,\n 404: NotFoundError,\n 408: TimeoutError,\n 409: ConflictError,\n 413: NotEnoughSpaceError,\n 422: InvalidArgumentError,\n 507: NotEnoughSpaceError,\n};\n\n/**\n * HTTP client for the Declaw API with Bearer auth, exponential backoff with jitter,\n * error mapping, and resource safety via AbortController.\n */\nexport class ApiClient {\n private readonly config: ConnectionConfig;\n private readonly maxRetries: number;\n private readonly retryDelay: number;\n private readonly abortController: AbortController;\n\n constructor(\n config?: ConnectionConfig,\n opts?: { maxRetries?: number; retryDelay?: number },\n ) {\n this.config = config ?? new ConnectionConfig();\n this.maxRetries = opts?.maxRetries ?? 3;\n // Retry backoff base (seconds). Only applies to 5xx/network retries (0ms on\n // the success path). 0.1s base → delay(0)=50-100ms vs the old 0.5s's\n // 250-500ms, cutting worst-case single-retry latency 5x. Override per-client\n // via opts.retryDelay; set 0 to disable backoff entirely.\n this.retryDelay = opts?.retryDelay ?? 0.1;\n this.abortController = new AbortController();\n }\n\n /** Send a GET request and return parsed JSON. */\n async get(path: string, opts?: RequestOpts): Promise<unknown> {\n return this.requestWithRetry('GET', path, opts);\n }\n\n /** Send a GET request and return the response body as raw bytes. */\n async getBytes(path: string, opts?: RequestOpts): Promise<Uint8Array> {\n const response = await this.requestWithRetry('GET', path, opts, true) as Response;\n const buf = await response.arrayBuffer();\n return new Uint8Array(buf);\n }\n\n /** Send a POST request and return parsed JSON. */\n async post(path: string, opts?: RequestOpts): Promise<unknown> {\n return this.requestWithRetry('POST', path, opts);\n }\n\n /** Send a PATCH request and return parsed JSON. */\n async patch(path: string, opts?: RequestOpts): Promise<unknown> {\n return this.requestWithRetry('PATCH', path, opts);\n }\n\n /** Send a DELETE request and return parsed JSON. */\n async delete(path: string, opts?: RequestOpts): Promise<unknown> {\n return this.requestWithRetry('DELETE', path, opts);\n }\n\n /** Send a PUT request and return parsed JSON. */\n async put(path: string, opts?: RequestOpts): Promise<unknown> {\n return this.requestWithRetry('PUT', path, opts);\n }\n\n /**\n * Send a POST request and return the raw Response for SSE streaming.\n * Does NOT parse the response body.\n */\n async stream(path: string, opts?: RequestOpts): Promise<Response> {\n return this.requestWithRetry('POST', path, opts, true) as Promise<Response>;\n }\n\n /**\n * Send a GET request and return the raw Response for SSE streaming.\n * Does NOT parse the response body. Used by PTY stream consumers.\n */\n async streamGet(path: string, opts?: RequestOpts): Promise<Response> {\n return this.requestWithRetry('GET', path, opts, true) as Promise<Response>;\n }\n\n /**\n * Abort all in-flight requests and release resources.\n *\n * Since 1.1.1 the SDK maintains a process-wide shared ApiClient cache\n * for hot class-method paths (Sandbox.create, Volumes.*, Template.*).\n * Calling `close()` on a shared instance aborts its AbortController,\n * which would cancel any concurrent in-flight call. Prefer\n * `resetSharedClients()` if you want to tear down every cached client.\n */\n close(): void {\n this.abortController.abort();\n }\n\n private buildUrl(path: string, params?: Record<string, string>): string {\n const base = this.config.apiUrl.replace(/\\/$/, '');\n const url = new URL(`${base}${path}`);\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n url.searchParams.set(key, value);\n }\n }\n return url.toString();\n }\n\n private buildHeaders(extra?: Record<string, string>): Record<string, string> {\n const headers: Record<string, string> = {};\n if (this.config.apiKey) {\n headers['Authorization'] = `Bearer ${this.config.apiKey}`;\n }\n if (extra) {\n Object.assign(headers, extra);\n }\n return headers;\n }\n\n private async requestWithRetry(\n method: string,\n path: string,\n opts?: RequestOpts,\n rawResponse?: boolean,\n ): Promise<unknown> {\n const url = this.buildUrl(path, opts?.params);\n const headers = this.buildHeaders(opts?.headers);\n\n let fetchBody: string | Uint8Array | undefined;\n if (opts?.body !== undefined) {\n fetchBody = opts.body;\n } else if (opts?.json !== undefined) {\n fetchBody = JSON.stringify(opts.json);\n headers['Content-Type'] = 'application/json';\n }\n\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt < this.maxRetries; attempt++) {\n try {\n // Compose abort signals: global close() + per-request timeout\n const signals: AbortSignal[] = [this.abortController.signal];\n const timeoutMs = opts?.timeout ?? this.config.requestTimeout;\n if (timeoutMs !== undefined) {\n signals.push(AbortSignal.timeout(timeoutMs));\n }\n const signal = signals.length === 1\n ? signals[0]\n : AbortSignal.any(signals);\n\n // Pull the undici dispatcher. Once resolved (eagerly at module load),\n // read it from the synchronous cache to avoid an await/microtask yield\n // on every request — only the very first call (pre-resolution) awaits.\n const dispatcher = _dispatcherResolved ? _resolvedDispatcher : await getDispatcher();\n const fetchOpts: any = {\n method,\n headers,\n body: fetchBody,\n signal,\n };\n if (dispatcher) fetchOpts.dispatcher = dispatcher;\n const response = await fetch(url, fetchOpts);\n\n // 5xx: retry if we have attempts left\n if (response.status >= 500 && attempt < this.maxRetries - 1) {\n await this.delay(attempt);\n continue;\n }\n\n // Non-success: map to error\n if (!response.ok) {\n throw await this.buildError(response);\n }\n\n // Success: return raw or parsed\n if (rawResponse) {\n return response;\n }\n return this.parseResponseBody(response);\n } catch (error) {\n // If it's already one of our mapped errors (4xx), don't retry\n if (error instanceof SandboxError) {\n throw error;\n }\n\n // If the client was closed, don't retry — fail immediately\n if (this.abortController.signal.aborted) {\n throw new SandboxError('Client has been closed');\n }\n\n lastError = error as Error;\n\n // Network error: retry if attempts left\n if (attempt < this.maxRetries - 1) {\n await this.delay(attempt);\n continue;\n }\n }\n }\n\n throw new SandboxError(\n `Request failed after ${this.maxRetries} retries: ${lastError?.message ?? 'unknown error'}`,\n );\n }\n\n private async buildError(response: Response): Promise<SandboxError> {\n let message: string;\n try {\n const body = await response.json() as Record<string, unknown>;\n const bodyMsg = body.message ?? body.error ?? response.statusText;\n message = `HTTP ${response.status}: ${bodyMsg}`;\n } catch {\n message = `HTTP ${response.status}: ${response.statusText}`;\n }\n\n const ErrorClass = STATUS_ERROR_MAP[response.status];\n if (ErrorClass) {\n return new ErrorClass(message);\n }\n return new SandboxError(message);\n }\n\n private async parseResponseBody(response: Response): Promise<unknown> {\n const contentLength = response.headers.get('content-length');\n if (response.status === 204 || contentLength === '0') {\n return null;\n }\n // NOTE: kept as text()+JSON.parse rather than response.json(). The /files\n // read endpoint returns RAW file contents (non-JSON), and callers expect\n // the raw string back. response.json() can't support that — it returns\n // null on non-JSON and has already consumed the single-read body stream, so\n // a text() fallback is impossible. The ~1-2ms saved isn't worth breaking\n // raw-body reads or depending on Content-Type sniffing.\n const text = await response.text();\n if (!text) {\n return null;\n }\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n }\n\n /**\n * Exponential backoff with jitter: delay * 2^attempt * (0.5 + random * 0.5)\n */\n private async delay(attempt: number): Promise<void> {\n if (this.retryDelay <= 0) return;\n const base = this.retryDelay * Math.pow(2, attempt);\n const jitter = 0.5 + Math.random() * 0.5;\n const ms = base * jitter * 1000; // retryDelay is in seconds\n await new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n\n// ---------------------------------------------------------------------------\n// Process-wide ApiClient cache.\n//\n// Under Node, we also install a module-level high-concurrency undici\n// dispatcher (see getDispatcher() above) so burst workloads fan out\n// without hitting undici's default 10-connection-per-origin cap. The\n// shared ApiClient amortizes AbortController creation across class-method\n// calls and keeps caller-level semantics symmetric with the Python SDK's\n// get_shared_client().\n// ---------------------------------------------------------------------------\n\nconst _sharedClients = new Map<string, ApiClient>();\n\nfunction sharedKey(config: ConnectionConfig): string {\n return [config.apiKey ?? '', config.apiUrl, config.requestTimeout ?? ''].join('|');\n}\n\nexport function getSharedClient(config: ConnectionConfig): ApiClient {\n const key = sharedKey(config);\n let client = _sharedClients.get(key);\n if (!client) {\n client = new ApiClient(config);\n _sharedClients.set(key, client);\n }\n return client;\n}\n\nexport function resetSharedClients(): void {\n for (const client of _sharedClients.values()) {\n try {\n client.close();\n } catch {\n /* noop */\n }\n }\n _sharedClients.clear();\n}\n","import { InvalidArgumentError } from '../errors.js';\n\n/** CIDR for all traffic. */\nexport const ALL_TRAFFIC = '0.0.0.0/0';\n\n/** Network configuration options for a sandbox. */\nexport interface SandboxNetworkOpts {\n allowOut: string[];\n denyOut: string[];\n allowPublicTraffic: boolean;\n maskRequestHost?: string;\n}\n\nconst IPV4_RE = /^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/;\nconst CIDR_RE = /^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\/(\\d{1,2})$/;\nconst DOMAIN_RE = /^(\\*\\.)?[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*$/;\n\nfunction isValidIPv4(ip: string): boolean {\n const match = IPV4_RE.exec(ip);\n if (!match) return false;\n for (let i = 1; i <= 4; i++) {\n const octet = parseInt(match[i], 10);\n if (octet < 0 || octet > 255) return false;\n }\n return true;\n}\n\nfunction isValidCIDR(cidr: string): boolean {\n const match = CIDR_RE.exec(cidr);\n if (!match) return false;\n for (let i = 1; i <= 4; i++) {\n const octet = parseInt(match[i], 10);\n if (octet < 0 || octet > 255) return false;\n }\n const prefix = parseInt(match[5], 10);\n return prefix >= 0 && prefix <= 32;\n}\n\n/**\n * Validate a network entry. Returns the normalized entry string.\n * Accepts IPv4 addresses, CIDR notation, and optionally domain names.\n * Throws InvalidArgumentError on invalid input.\n */\nexport function validateNetworkEntry(\n entry: string,\n opts?: { allowDomains?: boolean },\n): string {\n const trimmed = entry.trim();\n if (!trimmed) {\n throw new InvalidArgumentError('Network entry cannot be empty');\n }\n\n if (isValidIPv4(trimmed)) {\n return trimmed;\n }\n\n if (isValidCIDR(trimmed)) {\n return trimmed;\n }\n\n if (opts?.allowDomains && DOMAIN_RE.test(trimmed)) {\n return trimmed;\n }\n\n throw new InvalidArgumentError(\n `Invalid network entry: \"${trimmed}\". Expected a valid IPv4 address, CIDR block${opts?.allowDomains ? ', or domain name' : ''}`,\n );\n}\n\n/**\n * Check if a hostname matches a domain pattern.\n * Supports exact match and wildcard patterns like `*.example.com`.\n */\nexport function domainMatches(pattern: string, hostname: string): boolean {\n const p = pattern.toLowerCase();\n const h = hostname.toLowerCase();\n\n if (p === h) return true;\n\n if (p.startsWith('*.')) {\n const suffix = p.slice(2);\n // Match the suffix itself (e.g., *.example.com matches example.com)\n if (h === suffix) return true;\n // Match subdomains (e.g., *.example.com matches foo.example.com)\n if (h.endsWith('.' + suffix)) return true;\n }\n\n return false;\n}\n","import { InvalidArgumentError } from '../errors.js';\n\n/** Types of PII that can be detected. */\nexport enum PIIType {\n SSN = 'ssn',\n CreditCard = 'credit_card',\n Email = 'email',\n Phone = 'phone',\n PersonName = 'person_name',\n APIKey = 'api_key',\n Address = 'address',\n IPAddress = 'ip_address',\n}\n\n/** Actions to take when PII is detected. */\nexport enum RedactionAction {\n Redact = 'redact',\n Block = 'block',\n LogOnly = 'log_only',\n}\n\nconst VALID_PII_TYPES = new Set(Object.values(PIIType));\nconst VALID_REDACTION_ACTIONS = new Set(Object.values(RedactionAction));\n\n/** Configuration for PII detection and redaction. */\nexport interface PIIConfig {\n enabled: boolean;\n types: string[];\n action: string;\n rehydrateResponse: boolean;\n /** Optional domain allowlist; when undefined, applies to all domains. */\n domains?: string[];\n}\n\n/**\n * Create a PIIConfig with defaults and validation.\n */\nexport function createPIIConfig(opts?: Partial<PIIConfig>): PIIConfig {\n const config: PIIConfig = {\n enabled: opts?.enabled ?? false,\n types: opts?.types ?? Object.values(PIIType),\n action: opts?.action ?? RedactionAction.Redact,\n rehydrateResponse: opts?.rehydrateResponse ?? true,\n domains: opts?.domains,\n };\n\n for (const t of config.types) {\n if (!VALID_PII_TYPES.has(t as PIIType)) {\n throw new InvalidArgumentError(`Invalid PII type: \"${t}\". Valid types: ${[...VALID_PII_TYPES].join(', ')}`);\n }\n }\n\n if (!VALID_REDACTION_ACTIONS.has(config.action as RedactionAction)) {\n throw new InvalidArgumentError(\n `Invalid redaction action: \"${config.action}\". Valid actions: ${[...VALID_REDACTION_ACTIONS].join(', ')}`,\n );\n }\n\n return config;\n}\n\n/** Parse raw JSON data into PIIConfig. */\nexport function parsePIIConfig(data: Record<string, any>): PIIConfig {\n return {\n enabled: data.enabled ?? false,\n types: data.types ?? Object.values(PIIType),\n action: data.action ?? RedactionAction.Redact,\n rehydrateResponse: data.rehydrate_response ?? data.rehydrateResponse ?? true,\n domains: data.domains,\n };\n}\n","import { InvalidArgumentError } from '../errors.js';\n\n/** Sensitivity levels for injection detection. */\nexport enum InjectionSensitivity {\n Low = 'low',\n Medium = 'medium',\n High = 'high',\n}\n\n/** Actions to take when injection is detected. */\nexport enum InjectionAction {\n Block = 'block',\n LogOnly = 'log_only',\n}\n\nconst VALID_SENSITIVITIES = new Set(Object.values(InjectionSensitivity));\nconst VALID_ACTIONS = new Set(Object.values(InjectionAction));\n\n/** Configuration for injection defense. */\nexport interface InjectionDefenseConfig {\n enabled: boolean;\n sensitivity: string;\n action: string;\n /** Detection threshold (0.0–1.0). Defaults to 0.8. */\n threshold: number;\n /** Optional domain allowlist; when undefined, applies to all domains. */\n domains?: string[];\n}\n\n/**\n * Create an InjectionDefenseConfig with defaults and validation.\n */\nexport function createInjectionDefenseConfig(\n opts?: Partial<InjectionDefenseConfig>,\n): InjectionDefenseConfig {\n const config: InjectionDefenseConfig = {\n enabled: opts?.enabled ?? false,\n sensitivity: opts?.sensitivity ?? InjectionSensitivity.Medium,\n action: opts?.action ?? InjectionAction.LogOnly,\n threshold: opts?.threshold ?? 0.8,\n domains: opts?.domains,\n };\n\n if (!VALID_SENSITIVITIES.has(config.sensitivity as InjectionSensitivity)) {\n throw new InvalidArgumentError(\n `Invalid injection sensitivity: \"${config.sensitivity}\". Valid values: ${[...VALID_SENSITIVITIES].join(', ')}`,\n );\n }\n\n if (!VALID_ACTIONS.has(config.action as InjectionAction)) {\n throw new InvalidArgumentError(\n `Invalid injection action: \"${config.action}\". Valid actions: ${[...VALID_ACTIONS].join(', ')}`,\n );\n }\n\n if (!Number.isFinite(config.threshold) || config.threshold < 0 || config.threshold > 1) {\n throw new InvalidArgumentError(\n `Invalid injection threshold: ${config.threshold}. Must be a finite number between 0.0 and 1.0.`,\n );\n }\n\n return config;\n}\n\n/** Parse raw JSON data into InjectionDefenseConfig. */\nexport function parseInjectionDefenseConfig(data: Record<string, any>): InjectionDefenseConfig {\n return {\n enabled: data.enabled ?? false,\n sensitivity: data.sensitivity ?? InjectionSensitivity.Medium,\n action: data.action ?? InjectionAction.LogOnly,\n threshold: data.threshold ?? 0.8,\n domains: data.domains,\n };\n}\n","/**\n * Toggle for per-sandbox audit logging.\n *\n * When enabled, Declaw records lifecycle, network, command, filesystem,\n * snapshot, and security events. Set `enabled: false` to suppress all\n * gated categories; only lifecycle and admin events are still recorded.\n *\n * Retention is a platform-wide setting (global 7-day default), not a\n * per-sandbox knob. Body logging is not user-configurable today.\n */\nexport interface AuditConfig {\n enabled: boolean;\n}\n\n/** Create an AuditConfig with defaults (enabled=true). */\nexport function createAuditConfig(opts?: Partial<AuditConfig>): AuditConfig {\n return {\n enabled: opts?.enabled ?? true,\n };\n}\n\n/** Parse raw JSON data into AuditConfig. Defaults to enabled=true when the field is absent. */\nexport function parseAuditConfig(data: Record<string, any>): AuditConfig {\n return {\n enabled: data.enabled ?? true,\n };\n}\n\n/** A single audit log entry. */\nexport interface AuditEntry {\n timestamp: Date;\n method: string;\n url: string;\n statusCode: number;\n piiRedactions: number;\n injectionBlocks: number;\n transformationsApplied: number;\n direction: string;\n}\n\n/** Parse raw JSON data into an AuditEntry. */\nexport function parseAuditEntry(data: Record<string, any>): AuditEntry {\n return {\n timestamp: new Date(data.timestamp),\n method: data.method ?? '',\n url: data.url ?? '',\n statusCode: data.status_code ?? data.statusCode ?? 0,\n piiRedactions: data.pii_redactions ?? data.piiRedactions ?? 0,\n injectionBlocks: data.injection_blocks ?? data.injectionBlocks ?? 0,\n transformationsApplied: data.transformations_applied ?? data.transformationsApplied ?? 0,\n direction: data.direction ?? '',\n };\n}\n","/** Default patterns for masking sensitive environment variables. */\nexport const DEFAULT_MASK_PATTERNS = [\n '*_KEY',\n '*_SECRET',\n '*_TOKEN',\n '*_PASSWORD',\n '*_CREDENTIALS',\n 'API_KEY',\n 'SECRET_KEY',\n];\n\n/** Configuration for environment variable security. */\nexport interface EnvSecurityConfig {\n maskPatterns: string[];\n autoMaskInAudit: boolean;\n}\n\n/**\n * Create an EnvSecurityConfig with defaults.\n */\nexport function createEnvSecurityConfig(opts?: Partial<EnvSecurityConfig>): EnvSecurityConfig {\n return {\n maskPatterns: opts?.maskPatterns ?? [...DEFAULT_MASK_PATTERNS],\n autoMaskInAudit: opts?.autoMaskInAudit ?? true,\n };\n}\n\n/**\n * Parse raw JSON data into an EnvSecurityConfig.\n * Handles both snake_case (from API/serialization) and camelCase keys.\n */\nexport function parseEnvSecurityConfig(data: Record<string, any>): EnvSecurityConfig {\n return {\n maskPatterns: data.mask_patterns ?? data.maskPatterns ?? [...DEFAULT_MASK_PATTERNS],\n autoMaskInAudit: data.auto_mask_in_audit ?? data.autoMaskInAudit ?? true,\n };\n}\n\n/**\n * Check if an environment variable key matches any of the sensitive patterns.\n * Uses fnmatch-style glob matching where `*` matches any sequence of characters.\n */\nexport function isSensitive(key: string, patterns: string[]): boolean {\n const upper = key.toUpperCase();\n for (const pattern of patterns) {\n if (globMatch(pattern.toUpperCase(), upper)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Simple fnmatch-style glob matching.\n * Only supports `*` wildcard (matches any sequence of characters).\n */\nfunction globMatch(pattern: string, text: string): boolean {\n const parts = pattern.split('*');\n if (parts.length === 1) {\n return pattern === text;\n }\n\n let pos = 0;\n\n // First part must match at the start\n if (parts[0] !== '') {\n if (!text.startsWith(parts[0])) return false;\n pos = parts[0].length;\n }\n\n // Last part must match at the end\n const lastPart = parts[parts.length - 1];\n if (lastPart !== '') {\n if (!text.endsWith(lastPart)) return false;\n }\n\n // Middle parts must appear in order\n for (let i = 1; i < parts.length - 1; i++) {\n const idx = text.indexOf(parts[i], pos);\n if (idx === -1) return false;\n pos = idx + parts[i].length;\n }\n\n // Make sure we haven't gone past where the last part starts\n if (lastPart !== '') {\n const lastStart = text.length - lastPart.length;\n if (pos > lastStart) return false;\n }\n\n return true;\n}\n\n/** A secure environment variable. */\nexport interface SecureEnvVar {\n key: string;\n value: string;\n secret: boolean;\n}\n","import type { SandboxNetworkOpts } from '../sandbox/network.js';\n\n/** Network policy for a sandbox security configuration. */\nexport interface NetworkPolicy {\n allowOut: string[];\n denyOut: string[];\n allowPublicTraffic: boolean;\n maskRequestHost?: string;\n}\n\n/**\n * Create a NetworkPolicy with defaults.\n */\nexport function createNetworkPolicy(opts?: Partial<NetworkPolicy>): NetworkPolicy {\n return {\n allowOut: opts?.allowOut ?? [],\n denyOut: opts?.denyOut ?? [],\n allowPublicTraffic: opts?.allowPublicTraffic ?? true,\n maskRequestHost: opts?.maskRequestHost,\n };\n}\n\n/**\n * Parse raw JSON data into a NetworkPolicy.\n * Handles both snake_case (from API/serialization) and camelCase keys.\n */\nexport function parseNetworkPolicy(data: Record<string, any>): NetworkPolicy {\n return {\n allowOut: data.allow_out ?? data.allowOut ?? [],\n denyOut: data.deny_out ?? data.denyOut ?? [],\n allowPublicTraffic: data.allow_public_traffic ?? data.allowPublicTraffic ?? true,\n maskRequestHost: data.mask_request_host ?? data.maskRequestHost,\n };\n}\n\n/**\n * Serialize a NetworkPolicy to a JSON-friendly object.\n * Omits empty allow/deny lists and only emits allow_public_traffic when false,\n * matching the Python SDK's to_dict behavior.\n */\nexport function networkPolicyToJSON(policy: NetworkPolicy): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n if (policy.allowOut.length > 0) {\n result.allow_out = policy.allowOut;\n }\n if (policy.denyOut.length > 0) {\n result.deny_out = policy.denyOut;\n }\n if (!policy.allowPublicTraffic) {\n result.allow_public_traffic = false;\n }\n if (policy.maskRequestHost !== undefined) {\n result.mask_request_host = policy.maskRequestHost;\n }\n return result;\n}\n\n/**\n * Convert a NetworkPolicy to SandboxNetworkOpts.\n */\nexport function networkPolicyToOpts(policy: NetworkPolicy): SandboxNetworkOpts {\n return {\n allowOut: policy.allowOut,\n denyOut: policy.denyOut,\n allowPublicTraffic: policy.allowPublicTraffic,\n maskRequestHost: policy.maskRequestHost,\n };\n}\n","import { InvalidArgumentError } from '../errors.js';\n\n/** Direction in which a transformation rule applies. */\nexport enum TransformDirection {\n Outbound = 'outbound',\n Inbound = 'inbound',\n Both = 'both',\n}\n\nconst VALID_DIRECTIONS = new Set(Object.values(TransformDirection));\n\n/** A text transformation rule using regex matching. */\nexport interface TransformationRule {\n match: string;\n replace: string;\n direction: string;\n}\n\n/** Maximum allowed length for regex patterns to limit complexity. */\nconst MAX_PATTERN_LENGTH = 1000;\n\n/**\n * Detect regex patterns vulnerable to catastrophic backtracking (ReDoS).\n * Checks for nested quantifiers like (a+)+, (a*)+, (a+)*, etc.\n */\nconst REDOS_PATTERN = /(\\(.*[+*].*\\))[+*]|\\(\\?:[^)]*[+*][^)]*\\)[+*]/;\n\n/**\n * Create a TransformationRule with validation.\n * Validates that `match` is a valid regex, checks for ReDoS-vulnerable patterns,\n * and validates `direction`.\n */\nexport function createTransformationRule(opts: {\n match: string;\n replace: string;\n direction?: string;\n}): TransformationRule {\n if (opts.match.length > MAX_PATTERN_LENGTH) {\n throw new InvalidArgumentError(\n `Regex pattern too long (${opts.match.length} chars, max ${MAX_PATTERN_LENGTH}).`,\n );\n }\n\n // Reject patterns with nested quantifiers (common ReDoS vector)\n if (REDOS_PATTERN.test(opts.match)) {\n throw new InvalidArgumentError(\n `Regex pattern \"${opts.match}\" contains nested quantifiers which may cause catastrophic backtracking (ReDoS). Simplify the pattern.`,\n );\n }\n\n // Validate regex syntax\n try {\n new RegExp(opts.match);\n } catch {\n throw new InvalidArgumentError(`Invalid regex pattern: \"${opts.match}\"`);\n }\n\n const direction = opts.direction ?? TransformDirection.Outbound;\n\n if (!VALID_DIRECTIONS.has(direction as TransformDirection)) {\n throw new InvalidArgumentError(\n `Invalid transform direction: \"${direction}\". Valid values: ${[...VALID_DIRECTIONS].join(', ')}`,\n );\n }\n\n return {\n match: opts.match,\n replace: opts.replace,\n direction,\n };\n}\n\n/**\n * Parse raw JSON data into a TransformationRule, validating regex + direction.\n * Matches Python's TransformationRule.from_dict, which runs the same checks as construction.\n */\nexport function parseTransformationRule(data: Record<string, unknown>): TransformationRule {\n if (typeof data.match !== 'string' || typeof data.replace !== 'string') {\n throw new InvalidArgumentError(\n 'TransformationRule requires string \"match\" and \"replace\" fields.',\n );\n }\n return createTransformationRule({\n match: data.match,\n replace: data.replace,\n direction: (data.direction as string | undefined) ?? TransformDirection.Outbound,\n });\n}\n\n/**\n * Apply a transformation rule to text.\n * Uses the rule's `match` as a global regex and replaces with `replace`.\n */\nexport function applyTransformation(rule: TransformationRule, text: string): string {\n const regex = new RegExp(rule.match, 'g');\n return text.replace(regex, rule.replace);\n}\n","import { InvalidArgumentError } from '../errors.js';\n\nconst VALID_ACTIONS = new Set(['block', 'log_only']);\n\n/** Configuration for toxicity detection. */\nexport interface ToxicityConfig {\n enabled: boolean;\n threshold: number;\n action: 'block' | 'log_only';\n /** Optional domain allowlist; undefined = all domains. */\n domains?: string[];\n}\n\n/**\n * Create a ToxicityConfig with defaults and validation.\n */\nexport function createToxicityConfig(opts?: Partial<ToxicityConfig>): ToxicityConfig {\n const config: ToxicityConfig = {\n enabled: opts?.enabled ?? false,\n threshold: opts?.threshold ?? 0.9,\n action: opts?.action ?? 'block',\n domains: opts?.domains,\n };\n\n if (!Number.isFinite(config.threshold) || config.threshold < 0 || config.threshold > 1) {\n throw new InvalidArgumentError(\n `Invalid toxicity threshold: ${config.threshold}. Must be a finite number between 0 and 1.`,\n );\n }\n\n if (!VALID_ACTIONS.has(config.action)) {\n throw new InvalidArgumentError(\n `Invalid toxicity action: \"${config.action}\". Valid actions: ${[...VALID_ACTIONS].join(', ')}`,\n );\n }\n\n return config;\n}\n\n/** Parse raw JSON data into ToxicityConfig. */\nexport function parseToxicityConfig(data: Record<string, unknown>): ToxicityConfig {\n return {\n enabled: (data.enabled as boolean) ?? false,\n threshold: (data.threshold as number) ?? 0.9,\n action: (data.action as 'block' | 'log_only') ?? 'block',\n domains: data.domains as string[] | undefined,\n };\n}\n\n/** Serialize a ToxicityConfig to a JSON-friendly object. */\nexport function toxicityConfigToJSON(config: ToxicityConfig): Record<string, unknown> {\n const result: Record<string, unknown> = {\n enabled: config.enabled,\n threshold: config.threshold,\n action: config.action,\n };\n if (config.domains !== undefined) {\n result.domains = config.domains;\n }\n return result;\n}\n","import { InvalidArgumentError } from '../errors.js';\n\nconst VALID_ACTIONS = new Set(['block', 'log_only']);\n\n/** Configuration for code security scanning. */\nexport interface CodeSecurityConfig {\n enabled: boolean;\n threshold: number;\n /** Optional languages to exclude from detection; undefined = scan all languages. */\n excludedLanguages?: string[];\n action: 'block' | 'log_only';\n /** Optional domain allowlist; undefined = all domains. */\n domains?: string[];\n}\n\n/**\n * Create a CodeSecurityConfig with defaults and validation.\n */\nexport function createCodeSecurityConfig(opts?: Partial<CodeSecurityConfig>): CodeSecurityConfig {\n const config: CodeSecurityConfig = {\n enabled: opts?.enabled ?? false,\n threshold: opts?.threshold ?? 0.6,\n excludedLanguages: opts?.excludedLanguages,\n action: opts?.action ?? 'log_only',\n domains: opts?.domains,\n };\n\n if (!Number.isFinite(config.threshold) || config.threshold < 0 || config.threshold > 1) {\n throw new InvalidArgumentError(\n `Invalid code security threshold: ${config.threshold}. Must be a finite number between 0 and 1.`,\n );\n }\n\n if (!VALID_ACTIONS.has(config.action)) {\n throw new InvalidArgumentError(\n `Invalid code security action: \"${config.action}\". Valid actions: ${[...VALID_ACTIONS].join(', ')}`,\n );\n }\n\n return config;\n}\n\n/** Parse raw JSON data into CodeSecurityConfig. */\nexport function parseCodeSecurityConfig(data: Record<string, unknown>): CodeSecurityConfig {\n return {\n enabled: (data.enabled as boolean) ?? false,\n threshold: (data.threshold as number) ?? 0.6,\n excludedLanguages:\n (data.excluded_languages as string[] | undefined) ??\n (data.excludedLanguages as string[] | undefined),\n action: (data.action as 'block' | 'log_only') ?? 'log_only',\n domains: data.domains as string[] | undefined,\n };\n}\n\n/** Serialize a CodeSecurityConfig to a JSON-friendly object. */\nexport function codeSecurityConfigToJSON(config: CodeSecurityConfig): Record<string, unknown> {\n const result: Record<string, unknown> = {\n enabled: config.enabled,\n threshold: config.threshold,\n action: config.action,\n };\n if (config.excludedLanguages !== undefined) {\n result.excluded_languages = config.excludedLanguages;\n }\n if (config.domains !== undefined) {\n result.domains = config.domains;\n }\n return result;\n}\n","import { InvalidArgumentError } from '../errors.js';\n\nconst VALID_ACTIONS = new Set(['block', 'strip', 'log_only']);\n\n/** Configuration for invisible text detection. */\nexport interface InvisibleTextConfig {\n enabled: boolean;\n action: 'block' | 'strip' | 'log_only';\n /** Optional domain allowlist; undefined = all domains. */\n domains?: string[];\n}\n\n/**\n * Create an InvisibleTextConfig with defaults and validation.\n */\nexport function createInvisibleTextConfig(\n opts?: Partial<InvisibleTextConfig>,\n): InvisibleTextConfig {\n const config: InvisibleTextConfig = {\n enabled: opts?.enabled ?? false,\n action: opts?.action ?? 'strip',\n domains: opts?.domains,\n };\n\n if (!VALID_ACTIONS.has(config.action)) {\n throw new InvalidArgumentError(\n `Invalid invisible text action: \"${config.action}\". Valid actions: ${[...VALID_ACTIONS].join(', ')}`,\n );\n }\n\n return config;\n}\n\n/** Parse raw JSON data into InvisibleTextConfig. */\nexport function parseInvisibleTextConfig(data: Record<string, unknown>): InvisibleTextConfig {\n return {\n enabled: (data.enabled as boolean) ?? false,\n action: (data.action as 'block' | 'strip' | 'log_only') ?? 'strip',\n domains: data.domains as string[] | undefined,\n };\n}\n\n/** Serialize an InvisibleTextConfig to a JSON-friendly object. */\nexport function invisibleTextConfigToJSON(config: InvisibleTextConfig): Record<string, unknown> {\n const result: Record<string, unknown> = {\n enabled: config.enabled,\n action: config.action,\n };\n if (config.domains !== undefined) {\n result.domains = config.domains;\n }\n return result;\n}\n","/**\n * Custom OPA policy configuration for per-sandbox policy overrides.\n */\n\nexport interface CustomPolicyConfig {\n /** Enable custom policy evaluation for this sandbox. */\n enabled: boolean;\n\n /**\n * Customer-supplied Rego code appended to platform defaults.\n *\n * Example:\n * deny_command contains msg if {\n * input.action.command in {\"rm\", \"dd\"}\n * msg := \"dangerous command blocked\"\n * }\n */\n inlineRego?: string;\n\n /**\n * Additional independent Rego modules, each with its own `package` declaration.\n *\n * Use when your policy spans multiple packages (e.g. a `cmd` package and a\n * `network` package) that need to cross-reference each other. Each entry is\n * compiled as a separate OPA module alongside `inlineRego`.\n */\n inlineModules?: string[];\n\n /** Future: reference to a bundled policy (URL, policy ID, version hash). */\n policyRef?: string;\n\n /**\n * When the evaluator is unreachable, deny (true) or allow (false).\n *\n * Fail-closed (defaultDeny=true) is safer for security gates.\n * Fail-open (defaultDeny=false) is acceptable for advisory scanners.\n */\n defaultDeny?: boolean;\n}\n\n/** Create a CustomPolicyConfig with defaults. */\nexport function createCustomPolicyConfig(\n opts?: Partial<CustomPolicyConfig>\n): CustomPolicyConfig {\n return {\n enabled: opts?.enabled ?? false,\n inlineRego: opts?.inlineRego,\n inlineModules: opts?.inlineModules,\n policyRef: opts?.policyRef,\n defaultDeny: opts?.defaultDeny ?? false,\n };\n}\n\n/** Parse raw JSON data into a CustomPolicyConfig. */\nexport function parseCustomPolicyConfig(\n data: Record<string, any>\n): CustomPolicyConfig {\n return {\n enabled: data.enabled ?? false,\n inlineRego: data.inline_rego ?? data.inlineRego,\n inlineModules: data.inline_modules ?? data.inlineModules,\n policyRef: data.policy_ref ?? data.policyRef,\n defaultDeny: data.default_deny ?? data.defaultDeny ?? false,\n };\n}\n\n/** Convert CustomPolicyConfig to JSON. */\nexport function customPolicyConfigToJSON(config: CustomPolicyConfig): Record<string, any> {\n return {\n enabled: config.enabled,\n inline_rego: config.inlineRego,\n inline_modules: config.inlineModules,\n policy_ref: config.policyRef,\n default_deny: config.defaultDeny,\n };\n}\n","/** Configuration for the content.scan OPA gate (model/endpoint allowlist).\n *\n * Opts a sandbox into content-gate enforcement without requiring an ML\n * scanner. {@link enabled} defaults to false (gate off). {@link domains}\n * is an optional list of hosts to intercept; omit or leave undefined to\n * intercept none.\n */\nexport interface ContentGateConfig {\n enabled: boolean;\n /** Optional list of hosts to intercept. Undefined = none. */\n domains?: string[];\n}\n\n/**\n * Create a ContentGateConfig with defaults.\n */\nexport function createContentGateConfig(opts?: Partial<ContentGateConfig>): ContentGateConfig {\n return {\n enabled: opts?.enabled ?? false,\n domains: opts?.domains,\n };\n}\n\n/** Parse raw JSON data into ContentGateConfig. */\nexport function parseContentGateConfig(data: Record<string, unknown>): ContentGateConfig {\n return {\n enabled: (data.enabled as boolean) ?? false,\n domains: data.domains as string[] | undefined,\n };\n}\n\n/** Serialize a ContentGateConfig to a JSON-friendly object. */\nexport function contentGateConfigToJSON(config: ContentGateConfig): Record<string, unknown> {\n const result: Record<string, unknown> = {\n enabled: config.enabled,\n };\n if (config.domains !== undefined) {\n result.domains = config.domains;\n }\n return result;\n}\n","import type { PIIConfig } from './pii.js';\nimport type { InjectionDefenseConfig } from './injection.js';\nimport type { TransformationRule } from './transformations.js';\nimport type { NetworkPolicy } from './networkPolicy.js';\nimport type { AuditConfig } from './audit.js';\nimport type { EnvSecurityConfig } from './env.js';\nimport type { ToxicityConfig } from './toxicity.js';\nimport type { CodeSecurityConfig } from './codeSecurity.js';\nimport type { InvisibleTextConfig } from './invisibleText.js';\nimport type { CustomPolicyConfig } from './customPolicy.js';\nimport type { ContentGateConfig } from './contentGate.js';\n\nimport { createPIIConfig, parsePIIConfig } from './pii.js';\nimport { createInjectionDefenseConfig, parseInjectionDefenseConfig } from './injection.js';\nimport { createAuditConfig, parseAuditConfig } from './audit.js';\nimport { createEnvSecurityConfig, parseEnvSecurityConfig } from './env.js';\nimport { parseNetworkPolicy, networkPolicyToJSON } from './networkPolicy.js';\nimport { parseTransformationRule } from './transformations.js';\nimport { parseToxicityConfig, toxicityConfigToJSON } from './toxicity.js';\nimport { parseCodeSecurityConfig, codeSecurityConfigToJSON } from './codeSecurity.js';\nimport { parseInvisibleTextConfig, invisibleTextConfigToJSON } from './invisibleText.js';\nimport { parseCustomPolicyConfig, customPolicyConfigToJSON } from './customPolicy.js';\nimport { parseContentGateConfig, contentGateConfigToJSON } from './contentGate.js';\n\n/** The top-level security policy for a sandbox. */\nexport interface SecurityPolicy {\n pii: PIIConfig;\n injectionDefense: boolean | InjectionDefenseConfig;\n transformations: TransformationRule[];\n network?: NetworkPolicy;\n audit: boolean | AuditConfig;\n envSecurity: EnvSecurityConfig;\n toxicity?: ToxicityConfig;\n codeSecurity?: CodeSecurityConfig;\n invisibleText?: InvisibleTextConfig;\n contentGate?: ContentGateConfig;\n customPolicy?: CustomPolicyConfig;\n}\n\n/**\n * Create a SecurityPolicy with defaults.\n */\nexport function createSecurityPolicy(opts?: Partial<SecurityPolicy>): SecurityPolicy {\n return {\n pii: opts?.pii ?? createPIIConfig(),\n injectionDefense: opts?.injectionDefense ?? false,\n transformations: opts?.transformations ?? [],\n network: opts?.network,\n audit: opts?.audit ?? true,\n envSecurity: opts?.envSecurity ?? createEnvSecurityConfig(),\n toxicity: opts?.toxicity,\n codeSecurity: opts?.codeSecurity,\n invisibleText: opts?.invisibleText,\n contentGate: opts?.contentGate,\n customPolicy: opts?.customPolicy,\n };\n}\n\n/**\n * Parse raw JSON data into a SecurityPolicy.\n */\nexport function parseSecurityPolicy(data: Record<string, any>): SecurityPolicy {\n const injDef = data.injection_defense ?? data.injectionDefense;\n const auditData = data.audit;\n const customPolicyData = data.custom_policy ?? data.customPolicy;\n const contentGateData = data.content_gate ?? data.contentGate;\n\n return {\n pii: data.pii ? parsePIIConfig(data.pii) : createPIIConfig(),\n injectionDefense:\n typeof injDef === 'boolean'\n ? injDef\n : injDef\n ? parseInjectionDefenseConfig(injDef)\n : false,\n transformations: Array.isArray(data.transformations)\n ? data.transformations.map((t: Record<string, unknown>) => parseTransformationRule(t))\n : [],\n network: data.network ? parseNetworkPolicy(data.network) : undefined,\n audit:\n typeof auditData === 'boolean'\n ? auditData\n : auditData\n ? parseAuditConfig(auditData)\n : true,\n envSecurity: (data.env_security ?? data.envSecurity)\n ? parseEnvSecurityConfig(data.env_security ?? data.envSecurity)\n : createEnvSecurityConfig(),\n toxicity: (data.toxicity)\n ? parseToxicityConfig(data.toxicity as Record<string, unknown>)\n : undefined,\n codeSecurity: (data.code_security ?? data.codeSecurity)\n ? parseCodeSecurityConfig((data.code_security ?? data.codeSecurity) as Record<string, unknown>)\n : undefined,\n invisibleText: (data.invisible_text ?? data.invisibleText)\n ? parseInvisibleTextConfig((data.invisible_text ?? data.invisibleText) as Record<string, unknown>)\n : undefined,\n contentGate: contentGateData\n ? parseContentGateConfig(contentGateData as Record<string, unknown>)\n : undefined,\n customPolicy: customPolicyData\n ? parseCustomPolicyConfig(customPolicyData as Record<string, unknown>)\n : undefined,\n };\n}\n\n/**\n * Serialize a SecurityPolicy to a JSON-friendly object.\n */\nexport function securityPolicyToJSON(policy: SecurityPolicy): Record<string, any> {\n const pii: Record<string, unknown> = {\n enabled: policy.pii.enabled,\n types: policy.pii.types,\n action: policy.pii.action,\n rehydrate_response: policy.pii.rehydrateResponse,\n };\n if (policy.pii.domains !== undefined) {\n pii.domains = policy.pii.domains;\n }\n\n const injDefConfig =\n typeof policy.injectionDefense === 'boolean'\n ? createInjectionDefenseConfig({ enabled: policy.injectionDefense })\n : policy.injectionDefense;\n const injDef: Record<string, unknown> = {\n enabled: injDefConfig.enabled,\n sensitivity: injDefConfig.sensitivity,\n action: injDefConfig.action,\n threshold: injDefConfig.threshold,\n };\n if (injDefConfig.domains !== undefined) {\n injDef.domains = injDefConfig.domains;\n }\n\n const auditConfig =\n typeof policy.audit === 'boolean'\n ? createAuditConfig({ enabled: policy.audit })\n : policy.audit;\n const audit: Record<string, unknown> = {\n enabled: auditConfig.enabled,\n };\n\n const envSec: Record<string, unknown> = {\n mask_patterns: policy.envSecurity.maskPatterns,\n auto_mask_in_audit: policy.envSecurity.autoMaskInAudit,\n };\n\n const result: Record<string, any> = {\n pii,\n injection_defense: injDef,\n transformations: policy.transformations,\n audit,\n env_security: envSec,\n };\n if (policy.network) {\n result.network = networkPolicyToJSON(policy.network);\n }\n if (policy.toxicity) {\n result.toxicity = toxicityConfigToJSON(policy.toxicity);\n }\n if (policy.codeSecurity) {\n result.code_security = codeSecurityConfigToJSON(policy.codeSecurity);\n }\n if (policy.invisibleText) {\n result.invisible_text = invisibleTextConfigToJSON(policy.invisibleText);\n }\n if (policy.contentGate) {\n result.content_gate = contentGateConfigToJSON(policy.contentGate);\n }\n if (policy.customPolicy) {\n result.custom_policy = customPolicyConfigToJSON(policy.customPolicy);\n }\n return result;\n}\n\n/**\n * Determine if a security policy requires TLS interception.\n * TLS interception is needed if PII detection is enabled, injection defense is enabled,\n * or there are transformation rules.\n */\nexport function requiresTlsInterception(policy: SecurityPolicy): boolean {\n if (policy.pii.enabled) return true;\n\n if (typeof policy.injectionDefense === 'boolean') {\n if (policy.injectionDefense) return true;\n } else {\n if (policy.injectionDefense.enabled) return true;\n }\n\n if (policy.transformations.length > 0) return true;\n\n if (policy.toxicity?.enabled) return true;\n if (policy.codeSecurity?.enabled) return true;\n if (policy.invisibleText?.enabled) return true;\n\n return false;\n}\n","/** State of a sandbox. */\nexport enum SandboxState {\n Running = 'running',\n Paused = 'paused',\n Creating = 'creating',\n Killed = 'killed',\n}\n\n/** Information about a sandbox. */\nexport interface SandboxInfo {\n sandboxId: string;\n templateId: string;\n name: string;\n metadata: Record<string, string>;\n startedAt?: Date;\n endAt?: Date;\n state: SandboxState;\n}\n\n/** Parse raw JSON data into a SandboxInfo. */\nexport function parseSandboxInfo(data: Record<string, any>): SandboxInfo {\n return {\n sandboxId: data.sandbox_id ?? data.sandboxId ?? '',\n templateId: data.template_id ?? data.templateId ?? '',\n name: data.name ?? '',\n metadata: data.metadata ?? {},\n startedAt: data.started_at || data.startedAt ? new Date(data.started_at ?? data.startedAt) : undefined,\n endAt: data.end_at || data.endAt ? new Date(data.end_at ?? data.endAt) : undefined,\n state: (data.state as SandboxState) ?? SandboxState.Running,\n };\n}\n\n/** Metrics for a sandbox. */\nexport interface SandboxMetrics {\n timestamp: Date;\n cpuUsagePercent: number;\n memoryUsageMb: number;\n diskUsageMb: number;\n}\n\n/** Parse raw JSON data into SandboxMetrics. */\nexport function parseSandboxMetrics(data: Record<string, any>): SandboxMetrics {\n return {\n timestamp: new Date(data.timestamp),\n cpuUsagePercent: data.cpu_usage_percent ?? data.cpuUsagePercent ?? 0,\n memoryUsageMb: data.memory_usage_mb ?? data.memoryUsageMb ?? 0,\n diskUsageMb: data.disk_usage_mb ?? data.diskUsageMb ?? 0,\n };\n}\n\n/** Query filters for listing sandboxes. */\nexport interface SandboxQuery {\n metadata?: Record<string, string>;\n state?: SandboxState[];\n}\n\n/** Lifecycle configuration for a sandbox. */\nexport interface SandboxLifecycle {\n onTimeout: string;\n autoResume: boolean;\n}\n\n/** Parse raw JSON data into SandboxLifecycle. */\nexport function parseSandboxLifecycle(data: Record<string, any>): SandboxLifecycle {\n return {\n onTimeout: data.on_timeout ?? data.onTimeout ?? 'kill',\n autoResume: data.auto_resume ?? data.autoResume ?? false,\n };\n}\n\n/** Information about a snapshot. */\nexport interface SnapshotInfo {\n snapshotId: string;\n sandboxId: string;\n createdAt?: Date;\n}\n\n/** Parse raw JSON data into SnapshotInfo. */\nexport function parseSnapshotInfo(data: Record<string, any>): SnapshotInfo {\n return {\n snapshotId: data.snapshot_id ?? data.snapshotId ?? '',\n sandboxId: data.sandbox_id ?? data.sandboxId ?? '',\n createdAt: data.created_at || data.createdAt ? new Date(data.created_at ?? data.createdAt) : undefined,\n };\n}\n\n/** Source kind for a sandbox snapshot. */\nexport type SnapshotSource = 'periodic' | 'pause' | 'manual';\n\n/**\n * Full metadata for a manual/pause/periodic sandbox snapshot,\n * as returned by POST /sandboxes/:id/snapshot and\n * GET /sandboxes/:id/snapshots.\n */\nexport interface Snapshot {\n snapshotId: string;\n sandboxId: string;\n /** Which lifecycle created the snapshot: periodic, pause, or manual. */\n source: SnapshotSource;\n memBlobKey: string;\n vmstateBlobKey: string;\n memSizeBytes?: number;\n pauseDurationMs?: number;\n createdAt: string;\n}\n\n/** Parse raw JSON data into a Snapshot. */\nexport function parseSnapshot(data: Record<string, any>): Snapshot {\n return {\n snapshotId: data.snapshot_id ?? data.snapshotId ?? '',\n sandboxId: data.sandbox_id ?? data.sandboxId ?? '',\n source: (data.source as SnapshotSource) ?? 'manual',\n memBlobKey: data.mem_blob_key ?? data.memBlobKey ?? '',\n vmstateBlobKey: data.vmstate_blob_key ?? data.vmstateBlobKey ?? '',\n memSizeBytes: data.mem_size_bytes ?? data.memSizeBytes,\n pauseDurationMs: data.pause_duration_ms ?? data.pauseDurationMs,\n createdAt: data.created_at ?? data.createdAt ?? '',\n };\n}\n","/** Result of executing a command. */\nexport interface CommandResult {\n stdout: string;\n stderr: string;\n exitCode: number;\n}\n\n/** Parse raw JSON data into a CommandResult. */\nexport function parseCommandResult(data: Record<string, any>): CommandResult {\n return {\n stdout: data.stdout ?? '',\n stderr: data.stderr ?? '',\n exitCode: data.exit_code ?? data.exitCode ?? 0,\n };\n}\n\n/** Information about a running process. */\nexport interface ProcessInfo {\n pid: number;\n cmd: string;\n isPty: boolean;\n envs: Record<string, string>;\n}\n\n/** Parse raw JSON data into ProcessInfo. */\nexport function parseProcessInfo(data: Record<string, any>): ProcessInfo {\n return {\n pid: data.pid ?? 0,\n cmd: data.cmd ?? '',\n isPty: data.is_pty ?? data.isPty ?? false,\n envs: data.envs ?? {},\n };\n}\n\n/** Dimensions for a PTY. */\nexport interface PtySize {\n cols: number;\n rows: number;\n}\n\n/** Raw PTY output data. */\nexport interface PtyOutput {\n data: Uint8Array;\n}\n\n/** A line of stdout output. */\nexport interface Stdout {\n line: string;\n timestamp?: number;\n}\n\n/** A line of stderr output. */\nexport interface Stderr {\n line: string;\n timestamp?: number;\n}\n","import { ApiClient } from '../../api/client.js';\nimport { CommandExitError } from '../../errors.js';\nimport { parseCommandResult } from './models.js';\nimport type { CommandResult } from './models.js';\n\n/**\n * Options for waiting on a command to complete.\n */\nexport interface CommandWaitOpts {\n /** Callback invoked for each line of stdout. */\n onStdout?: (line: string) => void;\n /** Callback invoked for each line of stderr. */\n onStderr?: (line: string) => void;\n}\n\n/**\n * Handle to a running background command.\n *\n * Returned by `Commands.run()` when `background: true`, or by `Commands.connect()`.\n * Use `wait()` to block until the command finishes, or `kill()` to terminate it.\n */\nexport class CommandHandle {\n private readonly _pid: number;\n private readonly sandboxId: string;\n private readonly client: ApiClient;\n\n constructor(pid: number, sandboxId: string, client: ApiClient) {\n this._pid = pid;\n this.sandboxId = sandboxId;\n this.client = client;\n }\n\n /** The process ID of the running command. */\n get pid(): number {\n return this._pid;\n }\n\n /**\n * Wait for the command to complete and return its result.\n *\n * Sends GET /sandboxes/:id/commands/:pid/wait.\n * If the command exits with a non-zero exit code, throws CommandExitError.\n * Callbacks are invoked line-by-line before any error is thrown.\n */\n async wait(opts?: CommandWaitOpts): Promise<CommandResult> {\n const data = await this.client.get(\n `/sandboxes/${this.sandboxId}/commands/${this._pid}/wait`,\n );\n const result = parseCommandResult(data as Record<string, unknown>);\n\n // Invoke callbacks line-by-line (matching Python SDK's splitlines(keepends=True))\n if (opts?.onStdout && result.stdout) {\n for (const line of splitlines(result.stdout)) {\n opts.onStdout(line);\n }\n }\n if (opts?.onStderr && result.stderr) {\n for (const line of splitlines(result.stderr)) {\n opts.onStderr(line);\n }\n }\n\n // Throw on non-zero exit code\n if (result.exitCode !== 0) {\n throw new CommandExitError(\n `Command exited with code ${result.exitCode}`,\n {\n exitCode: result.exitCode,\n stdout: result.stdout,\n stderr: result.stderr,\n },\n );\n }\n\n return result;\n }\n\n /**\n * Kill the running command.\n *\n * Sends DELETE /sandboxes/:id/commands/:pid.\n * @returns true if the process was killed, false if it was already dead.\n */\n async kill(): Promise<boolean> {\n const data = await this.client.delete(\n `/sandboxes/${this.sandboxId}/commands/${this._pid}`,\n );\n return (data as Record<string, unknown>).killed === true;\n }\n\n /**\n * Disconnect from the command handle.\n *\n * Currently a no-op. Reserved for future WebSocket support.\n */\n disconnect(): void {\n // No-op for now\n }\n}\n\n/**\n * Split text into lines preserving line endings (like Python's splitlines(keepends=True)).\n */\nfunction splitlines(text: string): string[] {\n const lines: string[] = [];\n const re = /[^\\r\\n]*(?:\\r\\n|\\n|\\r|$)/g;\n let match: RegExpExecArray | null;\n while ((match = re.exec(text)) !== null) {\n if (match[0] === '') break;\n lines.push(match[0]);\n }\n return lines;\n}\n","import { ApiClient } from '../../api/client.js';\nimport { parseCommandResult, parseProcessInfo } from './models.js';\nimport type { CommandResult, ProcessInfo } from './models.js';\nimport { CommandHandle } from './commandHandle.js';\nimport { EventSourceParserStream } from 'eventsource-parser/stream';\nimport { SandboxError } from '../../errors.js';\n\n/**\n * Options for running a command in a sandbox.\n */\nexport interface RunOpts {\n /** Run the command in the background. Default: false. */\n background?: boolean;\n /** Environment variables to set for the command. */\n envs?: Record<string, string>;\n /** User to run the command as. Default: 'user'. */\n user?: string;\n /** Working directory for the command. */\n cwd?: string;\n /** Command timeout in seconds. Default: 60. */\n timeout?: number;\n /** Per-request HTTP timeout in milliseconds. */\n requestTimeout?: number;\n /** Callback invoked for each line of stdout (foreground only). */\n onStdout?: (line: string) => void;\n /** Callback invoked for each line of stderr (foreground only). */\n onStderr?: (line: string) => void;\n}\n\n/**\n * Options for running a streaming command in a sandbox.\n */\nexport interface RunStreamOpts {\n /** Environment variables to set for the command. */\n envs?: Record<string, string>;\n /** User to run the command as. Default: 'user'. */\n user?: string;\n /** Working directory for the command. */\n cwd?: string;\n /** Command timeout in seconds. Default: 60. */\n timeout?: number;\n /** Callback invoked for each chunk of stdout as it arrives. */\n onStdout?: (line: string) => void;\n /** Callback invoked for each chunk of stderr as it arrives. */\n onStderr?: (line: string) => void;\n}\n\n/**\n * Manage commands in a sandbox.\n *\n * Provides methods to run, list, kill, and interact with commands\n * running inside a sandbox.\n */\nexport class Commands {\n private readonly sandboxId: string;\n private readonly client: ApiClient;\n\n constructor(sandboxId: string, client: ApiClient) {\n this.sandboxId = sandboxId;\n this.client = client;\n }\n\n /**\n * Run a command in the background and return a handle.\n */\n async run(cmd: string, opts: RunOpts & { background: true }): Promise<CommandHandle>;\n /**\n * Run a command in the foreground and return its result.\n */\n async run(cmd: string, opts?: RunOpts): Promise<CommandResult>;\n async run(\n cmd: string,\n opts?: RunOpts,\n ): Promise<CommandResult | CommandHandle> {\n const background = opts?.background ?? false;\n const user = opts?.user ?? 'user';\n const timeout = opts?.timeout ?? 60;\n\n const body: Record<string, unknown> = {\n cmd,\n background,\n user,\n timeout,\n };\n\n if (opts?.envs !== undefined) {\n body.envs = opts.envs;\n }\n if (opts?.cwd !== undefined) {\n body.cwd = opts.cwd;\n }\n\n const data = await this.client.post(\n `/sandboxes/${this.sandboxId}/commands`,\n {\n json: body,\n timeout: opts?.requestTimeout,\n },\n );\n\n if (background) {\n const pid = (data as Record<string, unknown>).pid as number;\n return new CommandHandle(pid, this.sandboxId, this.client);\n }\n\n const result = parseCommandResult(data as Record<string, unknown>);\n\n // Invoke callbacks line-by-line (matching Python SDK's splitlines(keepends=True))\n if (opts?.onStdout && result.stdout) {\n for (const line of splitlines(result.stdout)) {\n opts.onStdout(line);\n }\n }\n if (opts?.onStderr && result.stderr) {\n for (const line of splitlines(result.stderr)) {\n opts.onStderr(line);\n }\n }\n\n return result;\n }\n\n /**\n * Run a command with real-time SSE streaming of stdout/stderr.\n *\n * Sends POST /sandboxes/:id/commands/stream and reads the response as\n * Server-Sent Events. Callbacks are invoked in real-time as output arrives.\n * Returns the accumulated CommandResult when the command completes.\n */\n async runStream(cmd: string, opts?: RunStreamOpts): Promise<CommandResult> {\n const user = opts?.user ?? 'user';\n const timeout = opts?.timeout ?? 60;\n\n const body: Record<string, unknown> = {\n cmd,\n stream: true,\n user,\n timeout,\n };\n\n if (opts?.envs !== undefined) {\n body.envs = opts.envs;\n }\n if (opts?.cwd !== undefined) {\n body.cwd = opts.cwd;\n }\n\n const response = await this.client.stream(\n `/sandboxes/${this.sandboxId}/commands/stream`,\n { json: body },\n );\n\n if (!response.body) {\n throw new SandboxError('Stream response has no body');\n }\n\n let stdout = '';\n let stderr = '';\n let exitCode = 0;\n\n const eventStream = response.body\n .pipeThrough(new TextDecoderStream())\n .pipeThrough(new EventSourceParserStream());\n\n const reader = eventStream.getReader();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(value.data) as Record<string, unknown>;\n } catch {\n // Skip malformed SSE events (matching Python SDK's json.JSONDecodeError handling)\n continue;\n }\n\n // Error event\n if (parsed.error !== undefined) {\n throw new SandboxError(parsed.error as string);\n }\n\n // Exit event\n if (parsed.exit_code !== undefined) {\n exitCode = parsed.exit_code as number;\n break;\n }\n\n // Output event\n const type = parsed.type as string;\n const data = parsed.data as string;\n\n if (type === 'stdout') {\n stdout += data;\n opts?.onStdout?.(data);\n } else if (type === 'stderr') {\n stderr += data;\n opts?.onStderr?.(data);\n }\n }\n } finally {\n reader.releaseLock();\n }\n\n return { stdout, stderr, exitCode };\n }\n\n /**\n * List all running commands in the sandbox.\n *\n * Sends GET /sandboxes/:id/commands.\n * @returns Array of ProcessInfo for each running process.\n */\n async list(requestTimeout?: number): Promise<ProcessInfo[]> {\n const data = await this.client.get(\n `/sandboxes/${this.sandboxId}/commands`,\n { timeout: requestTimeout },\n );\n const items = (data ?? []) as Record<string, unknown>[];\n return items.map(parseProcessInfo);\n }\n\n /**\n * Kill a running command by PID.\n *\n * Sends DELETE /sandboxes/:id/commands/:pid.\n * @returns true if the process was killed, false if already dead.\n */\n async kill(pid: number, requestTimeout?: number): Promise<boolean> {\n const data = await this.client.delete(\n `/sandboxes/${this.sandboxId}/commands/${pid}`,\n { timeout: requestTimeout },\n );\n return (data as Record<string, unknown>).killed === true;\n }\n\n /**\n * Send data to the stdin of a running command.\n *\n * Sends POST /sandboxes/:id/commands/:pid/stdin.\n */\n async sendStdin(pid: number, data: string, requestTimeout?: number): Promise<void> {\n await this.client.post(\n `/sandboxes/${this.sandboxId}/commands/${pid}/stdin`,\n {\n json: { data },\n timeout: requestTimeout,\n },\n );\n }\n\n /**\n * Connect to an existing running command by PID.\n *\n * Returns a CommandHandle without making any API call.\n */\n connect(pid: number): CommandHandle {\n return new CommandHandle(pid, this.sandboxId, this.client);\n }\n}\n\n/**\n * Split text into lines preserving line endings (like Python's splitlines(keepends=True)).\n * Each line includes its trailing \\n (or \\r\\n). The last line is included even without\n * a trailing newline.\n */\nfunction splitlines(text: string): string[] {\n const lines: string[] = [];\n const re = /[^\\r\\n]*(?:\\r\\n|\\n|\\r|$)/g;\n let match: RegExpExecArray | null;\n while ((match = re.exec(text)) !== null) {\n if (match[0] === '') break; // End of string\n lines.push(match[0]);\n }\n return lines;\n}\n","/** Type of a filesystem entry. */\nexport enum FileType {\n File = 'file',\n Dir = 'dir',\n}\n\n/** Type of a filesystem event. */\nexport enum FilesystemEventType {\n Create = 'create',\n Write = 'write',\n Remove = 'remove',\n Rename = 'rename',\n Chmod = 'chmod',\n}\n\n/** Information about a filesystem entry. */\nexport interface EntryInfo {\n name: string;\n path: string;\n type: FileType;\n size: number;\n}\n\n/** Parse raw JSON data into EntryInfo. */\nexport function parseEntryInfo(data: Record<string, any>): EntryInfo {\n return {\n name: data.name ?? '',\n path: data.path ?? '',\n type: (data.type as FileType) ?? FileType.File,\n size: data.size ?? 0,\n };\n}\n\n/** Information about a write operation. */\nexport interface WriteInfo {\n path: string;\n size: number;\n}\n\n/** Parse raw JSON data into WriteInfo. */\nexport function parseWriteInfo(data: Record<string, any>): WriteInfo {\n return {\n path: data.path ?? '',\n size: data.size ?? 0,\n };\n}\n\n/** An entry to write to the filesystem. */\nexport interface WriteEntry {\n path: string;\n data: string | Uint8Array;\n}\n\n/** A filesystem event from watching a directory. */\nexport interface FilesystemEvent {\n type: FilesystemEventType;\n path: string;\n timestamp?: number;\n}\n\n/** Parse raw JSON data into a FilesystemEvent. */\nexport function parseFilesystemEvent(data: Record<string, any>): FilesystemEvent {\n return {\n type: (data.type as FilesystemEventType) ?? FilesystemEventType.Create,\n path: data.path ?? '',\n timestamp: data.timestamp ?? undefined,\n };\n}\n","import type { FilesystemEvent } from './models.js';\n\n/**\n * Handle for a filesystem directory watch.\n *\n * Buffers incoming events in memory. Call `getNewEvents()` to drain\n * the buffer, and `stop()` to prevent new events from being added.\n */\nexport class WatchHandle {\n private events: FilesystemEvent[] = [];\n private stopped = false;\n\n /**\n * Stop accepting new events.\n * Idempotent — calling multiple times has no additional effect.\n */\n stop(): void {\n this.stopped = true;\n }\n\n /**\n * Drain and return all buffered events since the last call.\n * Returns an empty array if no new events have been received.\n */\n getNewEvents(): FilesystemEvent[] {\n const result = this.events;\n this.events = [];\n return result;\n }\n\n /**\n * Push a new event into the buffer.\n * Ignored if `stop()` has been called.\n */\n pushEvent(event: FilesystemEvent): void {\n if (!this.stopped) {\n this.events.push(event);\n }\n }\n}\n","import type { ApiClient } from '../../api/client.js';\nimport type { EntryInfo, WriteInfo, WriteEntry } from './models.js';\nimport { parseEntryInfo, parseWriteInfo } from './models.js';\nimport { WatchHandle } from './watchHandle.js';\n\n/** Default username for filesystem operations. */\nconst DEFAULT_USER = 'user';\n\n/**\n * Filesystem operations for a sandbox.\n *\n * Provides methods to read, write, list, and manage files\n * within a sandbox's filesystem.\n */\nexport class Filesystem {\n private readonly sandboxId: string;\n private readonly client: ApiClient;\n\n constructor(sandboxId: string, client: ApiClient) {\n this.sandboxId = sandboxId;\n this.client = client;\n }\n\n /**\n * Read a file's contents.\n *\n * Default returns the content as a string. Pass `{ format: \"bytes\" }`\n * to get a `Uint8Array` for binary-safe reads — the SDK negotiates\n * `application/octet-stream` end-to-end so high-bit bytes survive the\n * round trip.\n *\n * @param path - Absolute path to the file.\n * @param opts - Optional format, user, and request timeout.\n * @returns The file contents as a string, or Uint8Array when format=\"bytes\".\n */\n async read(\n path: string,\n opts?: { format?: 'text'; user?: string; requestTimeout?: number },\n ): Promise<string>;\n async read(\n path: string,\n opts: { format: 'bytes'; user?: string; requestTimeout?: number },\n ): Promise<Uint8Array>;\n async read(\n path: string,\n opts?: { format?: 'text' | 'bytes'; user?: string; requestTimeout?: number },\n ): Promise<string | Uint8Array> {\n const user = opts?.user ?? DEFAULT_USER;\n if (opts?.format === 'bytes') {\n return this.client.getBytes(\n `/sandboxes/${this.sandboxId}/files`,\n {\n params: { path, username: user },\n headers: { 'Accept': 'application/octet-stream' },\n timeout: opts?.requestTimeout,\n },\n );\n }\n const result = await this.client.get(\n `/sandboxes/${this.sandboxId}/files`,\n {\n params: { path, username: user },\n headers: { 'Accept': 'text/plain' },\n timeout: opts?.requestTimeout,\n },\n );\n // The API returns raw file content. We request text/plain, but the\n // generic response parser may still JSON-parse valid JSON content.\n // Always coerce to string for file reads.\n if (typeof result === 'string') {\n return result;\n }\n return JSON.stringify(result);\n }\n\n /**\n * Write data to a file.\n *\n * When `data` is a `Uint8Array`, the SDK streams the raw bytes to the\n * binary-safe `PUT /files/raw` endpoint (500 MiB cap). When it's a string,\n * the SDK uses the JSON `POST /files` endpoint. Callers do not need to\n * pick the transport.\n *\n * @param path - Absolute path to the file.\n * @param data - String or Uint8Array content to write.\n * @param opts - Optional user and request timeout.\n * @returns Information about the written file.\n */\n async write(\n path: string,\n data: string | Uint8Array,\n opts?: { user?: string; requestTimeout?: number },\n ): Promise<WriteInfo> {\n const user = opts?.user ?? DEFAULT_USER;\n if (data instanceof Uint8Array) {\n const result = await this.client.put(\n `/sandboxes/${this.sandboxId}/files/raw`,\n {\n params: { path, username: user },\n body: data,\n headers: { 'Content-Type': 'application/octet-stream' },\n timeout: opts?.requestTimeout,\n },\n );\n return parseWriteInfo(result as Record<string, unknown>);\n }\n const result = await this.client.post(\n `/sandboxes/${this.sandboxId}/files`,\n {\n json: { path, data, username: user },\n timeout: opts?.requestTimeout,\n },\n );\n return parseWriteInfo(result as Record<string, unknown>);\n }\n\n /**\n * Write multiple files in a single batch request.\n *\n * The batch endpoint is JSON-only and cannot carry binary. Entries are\n * partitioned: string entries go through `POST /files/batch` in one call,\n * `Uint8Array` entries are streamed individually to `PUT /files/raw`.\n * Results are merged back in input order.\n *\n * @param files - Array of files to write.\n * @param opts - Optional user and request timeout.\n * @returns Array of write info for each file, in input order.\n */\n async writeFiles(\n files: WriteEntry[],\n opts?: { user?: string; requestTimeout?: number },\n ): Promise<WriteInfo[]> {\n const user = opts?.user ?? DEFAULT_USER;\n const results: (WriteInfo | undefined)[] = new Array(files.length);\n\n const strIndices: number[] = [];\n const bytesIndices: number[] = [];\n for (let i = 0; i < files.length; i++) {\n if (files[i].data instanceof Uint8Array) {\n bytesIndices.push(i);\n } else {\n strIndices.push(i);\n }\n }\n\n if (strIndices.length > 0) {\n const batchFiles = strIndices.map((i) => ({\n path: files[i].path,\n data: files[i].data as string,\n }));\n const result = await this.client.post(\n `/sandboxes/${this.sandboxId}/files/batch`,\n {\n json: { files: batchFiles, username: user },\n timeout: opts?.requestTimeout,\n },\n );\n const parsed = ((result ?? []) as Record<string, unknown>[]).map(parseWriteInfo);\n for (let k = 0; k < strIndices.length; k++) {\n results[strIndices[k]] = parsed[k];\n }\n }\n\n for (const i of bytesIndices) {\n const entry = files[i];\n const result = await this.client.put(\n `/sandboxes/${this.sandboxId}/files/raw`,\n {\n params: { path: entry.path, username: user },\n body: entry.data as Uint8Array,\n headers: { 'Content-Type': 'application/octet-stream' },\n timeout: opts?.requestTimeout,\n },\n );\n results[i] = parseWriteInfo(result as Record<string, unknown>);\n }\n\n return results.filter((r): r is WriteInfo => r !== undefined);\n }\n\n /**\n * List entries in a directory.\n *\n * @param path - Absolute path to the directory.\n * @param opts - Optional depth, user, and request timeout.\n * @returns Array of entry info objects.\n */\n async list(\n path: string,\n opts?: { depth?: number; user?: string; requestTimeout?: number },\n ): Promise<EntryInfo[]> {\n const user = opts?.user ?? DEFAULT_USER;\n const params: Record<string, string> = { path, username: user };\n if (opts?.depth !== undefined) {\n params.depth = String(opts.depth);\n }\n const result = await this.client.get(\n `/sandboxes/${this.sandboxId}/files/list`,\n {\n params,\n timeout: opts?.requestTimeout,\n },\n );\n return ((result ?? []) as Record<string, unknown>[]).map(parseEntryInfo);\n }\n\n /**\n * Check whether a file or directory exists.\n *\n * @param path - Absolute path to check.\n * @param opts - Optional user and request timeout.\n * @returns True if the path exists.\n */\n async exists(\n path: string,\n opts?: { user?: string; requestTimeout?: number },\n ): Promise<boolean> {\n const user = opts?.user ?? DEFAULT_USER;\n const result = await this.client.get(\n `/sandboxes/${this.sandboxId}/files/exists`,\n {\n params: { path, username: user },\n timeout: opts?.requestTimeout,\n },\n );\n return (result as Record<string, unknown>).exists as boolean;\n }\n\n /**\n * Get information about a file or directory.\n *\n * @param path - Absolute path to query.\n * @param opts - Optional user and request timeout.\n * @returns Entry information.\n */\n async getInfo(\n path: string,\n opts?: { user?: string; requestTimeout?: number },\n ): Promise<EntryInfo> {\n const user = opts?.user ?? DEFAULT_USER;\n const result = await this.client.get(\n `/sandboxes/${this.sandboxId}/files/info`,\n {\n params: { path, username: user },\n timeout: opts?.requestTimeout,\n },\n );\n return parseEntryInfo(result as Record<string, unknown>);\n }\n\n /**\n * Remove a file or directory.\n *\n * IMPORTANT: Uses proper query params to prevent URL injection.\n * This fixes the Python SDK vulnerability where path was concatenated\n * directly into the URL string.\n *\n * @param path - Absolute path to remove.\n * @param opts - Optional user and request timeout.\n */\n async remove(\n path: string,\n opts?: { user?: string; requestTimeout?: number },\n ): Promise<void> {\n const user = opts?.user ?? DEFAULT_USER;\n await this.client.delete(\n `/sandboxes/${this.sandboxId}/files`,\n {\n params: { path, username: user },\n timeout: opts?.requestTimeout,\n },\n );\n }\n\n /**\n * Rename (move) a file or directory.\n *\n * @param oldPath - Current path.\n * @param newPath - New path.\n * @param opts - Optional user and request timeout.\n * @returns Entry information for the renamed item.\n */\n async rename(\n oldPath: string,\n newPath: string,\n opts?: { user?: string; requestTimeout?: number },\n ): Promise<EntryInfo> {\n const user = opts?.user ?? DEFAULT_USER;\n const result = await this.client.patch(\n `/sandboxes/${this.sandboxId}/files`,\n {\n json: { old_path: oldPath, new_path: newPath, username: user },\n timeout: opts?.requestTimeout,\n },\n );\n return parseEntryInfo(result as Record<string, unknown>);\n }\n\n /**\n * Create a directory.\n *\n * @param path - Absolute path of the directory to create.\n * @param opts - Optional user and request timeout.\n * @returns True if the directory was created.\n */\n async makeDir(\n path: string,\n opts?: { user?: string; requestTimeout?: number },\n ): Promise<boolean> {\n const user = opts?.user ?? DEFAULT_USER;\n const result = await this.client.post(\n `/sandboxes/${this.sandboxId}/files/mkdir`,\n {\n json: { path, username: user },\n timeout: opts?.requestTimeout,\n },\n );\n return (result as Record<string, unknown>).created as boolean;\n }\n\n /**\n * Watch a directory for filesystem events.\n *\n * @param path - Absolute path of the directory to watch.\n * @param opts - Optional user, recursive flag, and request timeout.\n * @returns A WatchHandle to receive events and stop watching.\n */\n async watchDir(\n path: string,\n opts?: { user?: string; recursive?: boolean; requestTimeout?: number },\n ): Promise<WatchHandle> {\n const user = opts?.user ?? DEFAULT_USER;\n const recursive = opts?.recursive ?? false;\n await this.client.post(\n `/sandboxes/${this.sandboxId}/files/watch`,\n {\n json: { path, username: user, recursive },\n timeout: opts?.requestTimeout,\n },\n );\n return new WatchHandle();\n }\n}\n","import { ApiClient } from '../../api/client.js';\nimport type { PtySize } from '../commands/models.js';\n\n/** Outcome of a PTY session — produced by `PtyHandle.wait()`. */\nexport interface PtyResult {\n /** Remote shell exit code. `-1` if the stream dropped before a clean exit frame. */\n exitCode: number;\n}\n\n/** Options for attaching to a running PTY via `Pty.connect()`. */\nexport interface PtyConnectOpts {\n /**\n * Callback invoked with every chunk of PTY output as raw bytes.\n * Optional — omit to drive the stream via the handle's async iterator.\n */\n onData?: (data: Uint8Array) => void;\n}\n\n/** Options for creating a PTY session. */\nexport interface PtyCreateOpts {\n /** Terminal size. Defaults to { cols: 80, rows: 24 }. */\n size?: PtySize;\n /** User to run as. Defaults to 'user'. */\n user?: string;\n /** Working directory. */\n cwd?: string;\n /** Environment variables. */\n envs?: Record<string, string>;\n /**\n * PTY session TTL in seconds. Defaults to 3600 (1 hour). Pass `0` to\n * keep the session alive indefinitely — it will still die when the\n * parent sandbox's timeout fires.\n */\n timeout?: number;\n /** Per-request timeout in milliseconds (applies to the initial create call only). */\n requestTimeout?: number;\n /**\n * Callback invoked with every chunk of PTY output as raw bytes.\n * Setting this implicitly opens the SSE stream; the returned handle's\n * `wait()` resolves when the remote process exits. Drop this option\n * and call `handle.stream()` directly if you want to drive the iterator\n * explicitly instead.\n */\n onData?: (data: Uint8Array) => void;\n}\n\n/**\n * Handle to a running PTY session. Returned from `Pty.create()`.\n *\n * Exposes stdin / resize / kill plus a `wait()` that resolves with the\n * remote exit code once the process terminates. The output stream runs\n * over Server-Sent Events — configured via `onData` at create time or\n * consumed manually with `stream()`.\n */\nexport class PtyHandle {\n readonly pid: number;\n private readonly sandboxId: string;\n private readonly client: ApiClient;\n private readonly exitPromise: Promise<PtyResult>;\n private resolveExit!: (result: PtyResult) => void;\n private aborter = new AbortController();\n\n constructor(\n pid: number,\n sandboxId: string,\n client: ApiClient,\n onData?: (data: Uint8Array) => void,\n ) {\n this.pid = pid;\n this.sandboxId = sandboxId;\n this.client = client;\n this.exitPromise = new Promise<PtyResult>((resolve) => {\n this.resolveExit = resolve;\n });\n if (onData) {\n void this.consumeStream(onData);\n }\n }\n\n /** Forward keystrokes to the PTY. */\n async sendInput(\n data: Uint8Array | string,\n requestTimeout?: number,\n ): Promise<void> {\n const strData = typeof data === 'string' ? data : new TextDecoder().decode(data);\n await this.client.post(\n `/sandboxes/${this.sandboxId}/pty/${this.pid}/stdin`,\n { json: { data: strData }, timeout: requestTimeout },\n );\n }\n\n /** Update the terminal size (TIOCSWINSZ inside the VM). */\n async resize(size: PtySize, requestTimeout?: number): Promise<void> {\n await this.client.patch(\n `/sandboxes/${this.sandboxId}/pty/${this.pid}`,\n {\n json: { size: { cols: size.cols, rows: size.rows } },\n timeout: requestTimeout,\n },\n );\n }\n\n /** SIGKILL the remote process and close any open streams. */\n async kill(requestTimeout?: number): Promise<boolean> {\n this.aborter.abort();\n const data = await this.client.delete(\n `/sandboxes/${this.sandboxId}/pty/${this.pid}`,\n { timeout: requestTimeout },\n );\n return (data as Record<string, unknown>).killed === true;\n }\n\n /**\n * Stop consuming output without killing the process. The PTY keeps\n * running server-side and a fresh `stream()` call reattaches.\n */\n disconnect(): void {\n this.aborter.abort();\n }\n\n /** Resolves with the remote exit result when the PTY process exits. */\n wait(): Promise<PtyResult> {\n return this.exitPromise;\n }\n\n /**\n * Async iterator over raw output chunks. Use when you want to drive\n * the stream yourself:\n *\n * for await (const chunk of handle.stream()) { ... }\n *\n * Don't mix this with `onData` on the same handle — they both try to\n * consume the same underlying SSE connection.\n */\n async *stream(): AsyncGenerator<Uint8Array, void, void> {\n const response = await this.client.streamGet(\n `/sandboxes/${this.sandboxId}/pty/${this.pid}/stream`,\n { timeout: undefined },\n );\n if (!response.body) {\n return;\n }\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n try {\n while (true) {\n if (this.aborter.signal.aborted) return;\n const { value, done } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n let idx: number;\n while ((idx = buffer.indexOf('\\n\\n')) >= 0) {\n const frame = buffer.slice(0, idx);\n buffer = buffer.slice(idx + 2);\n const parsed = parseSSEFrame(frame);\n if (!parsed) continue;\n if (parsed.event === 'exit') {\n this.resolveExit({ exitCode: parsed.exitCode ?? -1 });\n return;\n }\n if (parsed.bytes) {\n yield parsed.bytes;\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n private async consumeStream(onData: (data: Uint8Array) => void): Promise<void> {\n try {\n for await (const chunk of this.stream()) {\n onData(chunk);\n }\n } catch (err) {\n // If the stream aborts after an explicit disconnect/kill, that's fine.\n if (!this.aborter.signal.aborted) {\n throw err;\n }\n } finally {\n // If stream() returned without an exit frame (e.g. connection drop),\n // still unblock wait() so callers don't hang forever.\n this.resolveExit({ exitCode: -1 });\n }\n }\n}\n\ninterface ParsedSSEFrame {\n event: string;\n bytes?: Uint8Array;\n exitCode?: number;\n}\n\nfunction parseSSEFrame(frame: string): ParsedSSEFrame | null {\n let event = 'message';\n let data = '';\n for (const line of frame.split('\\n')) {\n if (line.startsWith('event:')) event = line.slice(6).trim();\n else if (line.startsWith('data:')) data += line.slice(5).trim();\n }\n if (!event) return null;\n if (event === 'exit') {\n try {\n const parsed = JSON.parse(data) as { exit_code?: number };\n return { event, exitCode: parsed.exit_code ?? -1 };\n } catch {\n return { event, exitCode: -1 };\n }\n }\n if (event === 'data') {\n try {\n const parsed = JSON.parse(data) as { data?: string };\n if (typeof parsed.data === 'string') {\n const bin = atob(parsed.data);\n const bytes = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);\n return { event, bytes };\n }\n } catch {\n return null;\n }\n }\n return null;\n}\n\n/**\n * PTY (pseudo-terminal) interface for a sandbox.\n *\n * Use `create()` to launch a fresh shell session. The returned\n * `PtyHandle` exposes stdin / resize / kill plus a live output stream\n * (callback or async iterator).\n */\nexport class Pty {\n private readonly sandboxId: string;\n private readonly client: ApiClient;\n\n constructor(sandboxId: string, client: ApiClient) {\n this.sandboxId = sandboxId;\n this.client = client;\n }\n\n async create(opts?: PtyCreateOpts): Promise<PtyHandle> {\n const size = opts?.size ?? { cols: 80, rows: 24 };\n const user = opts?.user ?? 'user';\n\n const body: Record<string, unknown> = {\n size: { cols: size.cols, rows: size.rows },\n user,\n timeout: opts?.timeout ?? 3600,\n };\n if (opts?.cwd !== undefined) body.cwd = opts.cwd;\n if (opts?.envs !== undefined) body.envs = opts.envs;\n\n const data = await this.client.post(\n `/sandboxes/${this.sandboxId}/pty`,\n { json: body, timeout: opts?.requestTimeout },\n );\n const pid = (data as Record<string, unknown>).pid as number;\n return new PtyHandle(pid, this.sandboxId, this.client, opts?.onData);\n }\n\n /**\n * Reattach to an already-running PTY by its pid.\n *\n * Returns a fresh `PtyHandle` that streams the live output of the\n * existing session. Multiple clients can subscribe to the same pid\n * concurrently — each receives output from the moment it connects\n * (no scrollback replay).\n */\n connect(pid: number, opts?: PtyConnectOpts): PtyHandle {\n return new PtyHandle(pid, this.sandboxId, this.client, opts?.onData);\n }\n\n // --- Low-level API by pid (kept for callers that already hold one). ---\n\n async kill(pid: number, requestTimeout?: number): Promise<boolean> {\n const data = await this.client.delete(\n `/sandboxes/${this.sandboxId}/pty/${pid}`,\n { timeout: requestTimeout },\n );\n return (data as Record<string, unknown>).killed === true;\n }\n\n async sendStdin(\n pid: number,\n data: Uint8Array | string,\n requestTimeout?: number,\n ): Promise<void> {\n const strData = typeof data === 'string' ? data : new TextDecoder().decode(data);\n await this.client.post(\n `/sandboxes/${this.sandboxId}/pty/${pid}/stdin`,\n { json: { data: strData }, timeout: requestTimeout },\n );\n }\n\n async resize(\n pid: number,\n size: PtySize,\n requestTimeout?: number,\n ): Promise<void> {\n await this.client.patch(\n `/sandboxes/${this.sandboxId}/pty/${pid}`,\n {\n json: { size: { cols: size.cols, rows: size.rows } },\n timeout: requestTimeout,\n },\n );\n }\n}\n","import { ApiClient } from '../../api/client.js';\nimport { EventSourceParserStream } from 'eventsource-parser/stream';\nimport { SandboxError } from '../../errors.js';\n\n/** Options for starting an interactive stdio process. */\nexport interface StdioStartOpts {\n envs?: Record<string, string>;\n user?: string;\n cwd?: string;\n onStdout?: (data: Uint8Array) => void;\n onStderr?: (data: Uint8Array) => void;\n requestTimeout?: number;\n}\n\n/** Result returned when a stdio process exits. */\nexport interface StdioResult {\n exitCode: number;\n}\n\n/**\n * Handle for an interactive subprocess with stdin pipe.\n */\nexport class StdioProcess {\n readonly cmdId: string;\n private readonly sandboxId: string;\n private readonly client: ApiClient;\n private lastEntryId = 0;\n private _exitCode: number | null = null;\n private _bgStream: Promise<StdioResult> | null = null;\n\n constructor(\n cmdId: string,\n sandboxId: string,\n client: ApiClient,\n opts?: {\n onStdout?: (data: Uint8Array) => void;\n onStderr?: (data: Uint8Array) => void;\n },\n ) {\n this.cmdId = cmdId;\n this.sandboxId = sandboxId;\n this.client = client;\n if (opts?.onStdout || opts?.onStderr) {\n this._bgStream = this.stream({\n onStdout: opts.onStdout,\n onStderr: opts.onStderr,\n });\n }\n }\n\n get exitCode(): number | null {\n return this._exitCode;\n }\n\n async sendStdin(data: string | Uint8Array, requestTimeout?: number): Promise<void> {\n const raw = typeof data === 'string' ? new TextEncoder().encode(data) : data;\n let binary = '';\n for (let i = 0; i < raw.length; i++) {\n binary += String.fromCharCode(raw[i]);\n }\n const encoded = btoa(binary);\n await this.client.post(\n `/sandboxes/${this.sandboxId}/stdio/${this.cmdId}/stdin`,\n {\n json: { data: encoded },\n timeout: requestTimeout,\n },\n );\n }\n\n async closeStdin(requestTimeout?: number): Promise<void> {\n await this.client.post(\n `/sandboxes/${this.sandboxId}/stdio/${this.cmdId}/stdin/close`,\n { timeout: requestTimeout },\n );\n }\n\n async kill(requestTimeout?: number): Promise<boolean> {\n const resp = await this.client.delete(\n `/sandboxes/${this.sandboxId}/stdio/${this.cmdId}`,\n { timeout: requestTimeout },\n );\n return Boolean((resp as Record<string, unknown>).killed);\n }\n\n async wait(): Promise<StdioResult> {\n if (this._bgStream) {\n return this._bgStream;\n }\n return this.stream();\n }\n\n async stream(opts?: {\n onStdout?: (data: Uint8Array) => void;\n onStderr?: (data: Uint8Array) => void;\n }): Promise<StdioResult> {\n if (this._bgStream && !opts) {\n return this._bgStream;\n }\n let url = `/sandboxes/${this.sandboxId}/stdio/${this.cmdId}/stream`;\n if (this.lastEntryId > 0) {\n url += `?last_entry_id=${this.lastEntryId}`;\n }\n\n const response = await this.client.streamGet(url);\n const stream = response.body;\n if (!stream) {\n throw new SandboxError('No response body for stdio stream');\n }\n\n const eventStream = stream\n .pipeThrough(new TextDecoderStream())\n .pipeThrough(new EventSourceParserStream());\n\n for await (const event of eventStream) {\n if (event.event === 'exit') {\n try {\n const parsed = JSON.parse(event.data);\n this._exitCode = parsed.exit_code ?? -1;\n } catch {\n this._exitCode = -1;\n }\n break;\n }\n if (event.event === 'stdout' || event.event === 'stderr') {\n try {\n const parsed = JSON.parse(event.data);\n const entryId = parsed.entry_id ?? 0;\n if (entryId > this.lastEntryId) {\n this.lastEntryId = entryId;\n }\n const raw = atob(parsed.data ?? '');\n const bytes = new Uint8Array(raw.length);\n for (let i = 0; i < raw.length; i++) {\n bytes[i] = raw.charCodeAt(i);\n }\n if (event.event === 'stdout' && opts?.onStdout) {\n opts.onStdout(bytes);\n } else if (event.event === 'stderr' && opts?.onStderr) {\n opts.onStderr(bytes);\n }\n } catch {\n continue;\n }\n }\n }\n\n return { exitCode: this._exitCode ?? -1 };\n }\n}\n\n/**\n * Module for interactive stdio subprocess sessions in the sandbox.\n */\nexport class Stdio {\n private readonly sandboxId: string;\n private readonly client: ApiClient;\n\n constructor(sandboxId: string, client: ApiClient) {\n this.sandboxId = sandboxId;\n this.client = client;\n }\n\n async start(cmd: string, opts?: StdioStartOpts): Promise<StdioProcess> {\n const user = opts?.user ?? 'user';\n const body: Record<string, unknown> = { cmd, user };\n if (opts?.envs) body.envs = opts.envs;\n if (opts?.cwd) body.cwd = opts.cwd;\n\n const data = await this.client.post(\n `/sandboxes/${this.sandboxId}/stdio`,\n { json: body, timeout: opts?.requestTimeout },\n );\n const cmdId = (data as Record<string, string>).cmd_id;\n return new StdioProcess(cmdId, this.sandboxId, this.client, {\n onStdout: opts?.onStdout,\n onStderr: opts?.onStderr,\n });\n }\n}\n","/** Live-mount / copy mode for a volume attachment on Sandbox.create. */\nexport type VolumeAttachMode = 'copy' | 'mount' | 'mount-ro';\n\n/** Request-side shape of a volume attachment on Sandbox.create. */\nexport interface VolumeAttachment {\n volumeId: string;\n mountPath: string;\n /**\n * Attach mode. `copy` (default) hydrates the volume into the sandbox\n * filesystem at boot. `mount` is a read-write live NFS mount; `mount-ro`\n * is a read-only live mount. Omitted from the wire when unset (server\n * defaults to copy).\n */\n mode?: VolumeAttachMode;\n /**\n * Relative path within the volume to mount. LIVE-MOUNT ONLY — the server\n * rejects a subpath on a copy-mode attachment.\n */\n subpath?: string;\n}\n\n/** Server-side metadata for a single volume. */\nexport interface VolumeInfo {\n volumeId: string;\n ownerId: string;\n name: string;\n blobKey: string;\n sizeBytes: number;\n contentType: string;\n metadata: Record<string, string>;\n createdAt: string;\n /** Storage backend (\"tarball\" or a file-granular backend). */\n backend: string;\n /** Per-volume quota in bytes (0 = unset/unlimited). */\n quotaBytes: number;\n /** Last-modified timestamp (ISO 8601). */\n updatedAt: string;\n}\n\n/** A single directory entry inside a file-granular volume (volumefs.Entry). */\nexport interface FileEntry {\n name: string;\n path: string;\n isDir: boolean;\n size: number;\n modTime: string;\n mode: number;\n}\n\n/** A file entry plus the CAS token returned by `info`/`stat`. */\nexport interface FileInfo extends FileEntry {\n /** CAS token to round-trip into a conditional write's `ifVersion`. */\n version: string;\n}\n\n/** Result of acquiring or renewing a lock. */\nexport interface LockLease {\n token: string;\n ttlSeconds: number;\n expiresAt: string;\n}\n\n/** Result of querying lock status. */\nexport interface LockStatus {\n held: boolean;\n expiresInMs: number;\n}\n\n/** Convert a wire-format volume row into a VolumeInfo. */\nexport function parseVolumeInfo(data: Record<string, unknown>): VolumeInfo {\n return {\n volumeId: String(data.volume_id ?? ''),\n ownerId: String(data.owner_id ?? ''),\n name: String(data.name ?? ''),\n blobKey: String(data.blob_key ?? ''),\n sizeBytes: Number(data.size_bytes ?? 0),\n contentType: String(data.content_type ?? ''),\n metadata: (data.metadata as Record<string, string> | null | undefined) ?? {},\n createdAt: String(data.created_at ?? ''),\n backend: String(data.backend ?? ''),\n quotaBytes: Number(data.quota_bytes ?? 0),\n updatedAt: String(data.updated_at ?? ''),\n };\n}\n\n/** Convert a wire-format file entry into a FileEntry. */\nexport function parseFileEntry(data: Record<string, unknown>): FileEntry {\n return {\n name: String(data.name ?? ''),\n path: String(data.path ?? ''),\n isDir: Boolean(data.is_dir ?? false),\n size: Number(data.size ?? 0),\n modTime: String(data.mod_time ?? ''),\n mode: Number(data.mode ?? 0),\n };\n}\n\n/** Convert a wire-format stat response into a FileInfo (FileEntry + version). */\nexport function parseFileInfo(data: Record<string, unknown>): FileInfo {\n return {\n ...parseFileEntry(data),\n version: String(data.version ?? ''),\n };\n}\n\n/** Convert a wire-format lock lease into a LockLease. */\nexport function parseLockLease(data: Record<string, unknown>): LockLease {\n return {\n token: String(data.token ?? ''),\n ttlSeconds: Number(data.ttl_seconds ?? 0),\n expiresAt: String(data.expires_at ?? ''),\n };\n}\n\n/** Convert a wire-format lock status into a LockStatus. */\nexport function parseLockStatus(data: Record<string, unknown>): LockStatus {\n return {\n held: Boolean(data.held ?? false),\n expiresInMs: Number(data.expires_in_ms ?? 0),\n };\n}\n\n/** Render a VolumeAttachment in wire (snake_case) form. */\nexport function volumeAttachmentToJSON(att: VolumeAttachment): Record<string, string> {\n const out: Record<string, string> = {\n volume_id: att.volumeId,\n mount_path: att.mountPath,\n };\n if (att.mode) {\n out.mode = att.mode;\n }\n if (att.subpath) {\n out.subpath = att.subpath;\n }\n return out;\n}\n","import { ConnectionConfig } from '../connectionConfig.js';\nimport { ApiClient, getSharedClient } from '../api/client.js';\nimport { InvalidArgumentError } from '../errors.js';\nimport { ALL_TRAFFIC } from './network.js';\nimport type { SandboxNetworkOpts } from './network.js';\nimport type { SecurityPolicy } from '../security/policy.js';\nimport { securityPolicyToJSON } from '../security/policy.js';\nimport type { SandboxInfo, SandboxMetrics, SandboxLifecycle, SnapshotInfo, Snapshot } from './models.js';\nimport { parseSandboxInfo, parseSandboxMetrics, parseSnapshotInfo, parseSnapshot } from './models.js';\nimport { Commands } from './commands/commands.js';\nimport { Filesystem } from './filesystem/filesystem.js';\nimport { Pty } from './pty/pty.js';\nimport { Stdio } from './stdio/stdio.js';\nimport type { VolumeAttachment } from '../volumes/models.js';\nimport { volumeAttachmentToJSON } from '../volumes/models.js';\n\n/** Options for creating a sandbox. */\nexport interface SandboxOpts {\n /** Template to use. Defaults to 'base'. */\n template?: string;\n /** Timeout in seconds. Defaults to 300. */\n timeout?: number;\n /** Metadata key-value pairs. */\n metadata?: Record<string, string>;\n /** Environment variables. */\n envs?: Record<string, string>;\n /** Whether to create a secure sandbox. Defaults to true. */\n secure?: boolean;\n /** If false, denies all outbound traffic. Defaults to true. */\n allowInternetAccess?: boolean;\n /** Fine-grained network configuration. Overrides allowInternetAccess. */\n network?: SandboxNetworkOpts;\n /** Security policy for the sandbox. */\n security?: SecurityPolicy;\n /** Lifecycle configuration. */\n lifecycle?: SandboxLifecycle;\n /** Volumes to attach at sandbox-boot time. Each {volumeId, mountPath}\n * references a blob uploaded via `Volumes.create`; the orchestrator\n * materializes its contents under `mountPath` before the first command\n * is dispatched. */\n volumes?: VolumeAttachment[];\n /** API key override. */\n apiKey?: string;\n /** Domain override (supports \"host:port\" format, e.g. \"myhost.example.com:8080\"). */\n domain?: string;\n /** Full API URL override. If set, domain/port/scheme are ignored. */\n apiUrl?: string;\n /** Per-request timeout in milliseconds. */\n requestTimeout?: number;\n}\n\n/** Default template name. */\nconst DEFAULT_TEMPLATE = 'base';\n\n/** Default sandbox timeout in seconds. */\nconst DEFAULT_TIMEOUT = 300;\n\n/** Port conventionally used for MCP servers running inside a sandbox. */\nconst MCP_PORT = 50005;\n\nconst VALID_ID_RE = /^[a-zA-Z0-9_-]+$/;\n\n/** Validate that an ID is safe for URL path interpolation. */\nfunction assertValidId(id: string, label: string): void {\n if (!id || !VALID_ID_RE.test(id)) {\n throw new InvalidArgumentError(\n `Invalid ${label}: \"${id}\". Must be alphanumeric with hyphens/underscores only.`,\n );\n }\n}\n\n/**\n * A Declaw sandbox.\n *\n * Use `Sandbox.create()` to create a new sandbox, or `Sandbox.connect()` to\n * connect to an existing one. Do not instantiate directly.\n */\nexport class Sandbox {\n private readonly _sandboxId: string;\n private readonly _config: ConnectionConfig;\n private readonly _client: ApiClient;\n private readonly _envdAccessToken?: string;\n private readonly _sandboxDomain?: string;\n private readonly _trafficAccessToken?: string;\n private readonly _commands: Commands;\n private readonly _files: Filesystem;\n private readonly _pty: Pty;\n private readonly _stdio: Stdio;\n\n private constructor(\n sandboxId: string,\n config: ConnectionConfig,\n client: ApiClient,\n envdAccessToken?: string,\n sandboxDomain?: string,\n trafficAccessToken?: string,\n ) {\n this._sandboxId = sandboxId;\n this._config = config;\n this._client = client;\n this._envdAccessToken = envdAccessToken;\n this._sandboxDomain = sandboxDomain;\n this._trafficAccessToken = trafficAccessToken;\n this._commands = new Commands(sandboxId, client);\n this._files = new Filesystem(sandboxId, client);\n this._pty = new Pty(sandboxId, client);\n this._stdio = new Stdio(sandboxId, client);\n }\n\n /** The unique sandbox identifier. */\n get sandboxId(): string {\n return this._sandboxId;\n }\n\n /** The connection configuration used by this sandbox. */\n get config(): ConnectionConfig {\n return this._config;\n }\n\n /** Access token for the envd service inside the sandbox. */\n get envdAccessToken(): string | undefined {\n return this._envdAccessToken;\n }\n\n /** Domain where the sandbox is accessible. */\n get sandboxDomain(): string | undefined {\n return this._sandboxDomain;\n }\n\n /** Access token for traffic routing to the sandbox. */\n get trafficAccessToken(): string | undefined {\n return this._trafficAccessToken;\n }\n\n /** Commands sub-module for executing and managing commands. */\n get commands(): Commands {\n return this._commands;\n }\n\n /** Filesystem sub-module for reading and writing files. */\n get files(): Filesystem {\n return this._files;\n }\n\n /** PTY sub-module for pseudo-terminal sessions. */\n get pty(): Pty {\n return this._pty;\n }\n\n /** Stdio sub-module for interactive subprocess sessions with stdin pipe. */\n get stdio(): Stdio {\n return this._stdio;\n }\n\n /**\n * Base URL for this sandbox's namespace on the Declaw API.\n *\n * All per-sandbox operations (commands, files, file streaming, ports) live\n * under this prefix. Callers must attach an `X-API-Key` header with their\n * Declaw API key.\n */\n get envdApiUrl(): string {\n return `${this._config.apiUrl}/sandboxes/${this._sandboxId}`;\n }\n\n /**\n * Return the path-based URL that reverse-proxies to `port` inside the sandbox.\n *\n * Requires `allowPublicTraffic` to be enabled on the sandbox's network\n * config (the default). The returned URL is authenticated via the same\n * API key as all other sandbox operations.\n */\n getHost(port: number): string {\n return `${this.envdApiUrl}/ports/${port}`;\n }\n\n /**\n * Return the URL for an MCP server listening on port 50005 inside the sandbox.\n */\n getMcpUrl(): string {\n return `${this.getHost(MCP_PORT)}/mcp`;\n }\n\n /**\n * URL for a streaming GET of `path` out of the sandbox.\n *\n * Supports files up to 500 MiB. Callers must attach `X-API-Key`; the URL\n * is NOT safe to share with third parties because the API key is required\n * separately.\n */\n downloadUrl(path: string, user?: string): string {\n const params = new URLSearchParams({ path });\n if (user) params.set('username', user);\n return `${this.envdApiUrl}/files/raw?${params.toString()}`;\n }\n\n /**\n * URL that accepts a streaming PUT with a raw binary body to write `path`\n * into the sandbox.\n *\n * Supports files up to 500 MiB. Same auth note as {@link downloadUrl}.\n */\n uploadUrl(path: string, user?: string): string {\n const params = new URLSearchParams({ path });\n if (user) params.set('username', user);\n return `${this.envdApiUrl}/files/raw?${params.toString()}`;\n }\n\n /**\n * Create a new sandbox.\n *\n * @param opts - Sandbox creation options.\n * @returns A new Sandbox instance connected to the created sandbox.\n */\n static async create(opts?: SandboxOpts): Promise<Sandbox> {\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n apiUrl: opts?.apiUrl,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n\n const body: Record<string, unknown> = {\n template: opts?.template ?? DEFAULT_TEMPLATE,\n timeout: opts?.timeout ?? DEFAULT_TIMEOUT,\n secure: opts?.secure ?? true,\n };\n\n if (opts?.metadata) {\n body.metadata = opts.metadata;\n }\n if (opts?.envs) {\n body.envs = opts.envs;\n }\n\n // Network: explicit opts take precedence over allowInternetAccess flag\n if (opts?.network) {\n body.network = networkOptsToJSON(opts.network);\n } else if (opts?.allowInternetAccess === false) {\n body.network = { deny_out: [ALL_TRAFFIC] };\n }\n\n if (opts?.security) {\n body.security = { policy_json: JSON.stringify(securityPolicyToJSON(opts.security)) };\n // Propagate security.network to top-level network field (matching Python SDK)\n if (opts.security.network && !body.network) {\n body.network = typeof opts.security.network === 'object' && 'allowOut' in opts.security.network\n ? networkOptsToJSON(opts.security.network as SandboxNetworkOpts)\n : opts.security.network;\n }\n }\n\n if (opts?.lifecycle) {\n body.lifecycle = lifecycleToJSON(opts.lifecycle);\n }\n\n if (opts?.volumes && opts.volumes.length > 0) {\n body.volumes = opts.volumes.map(volumeAttachmentToJSON);\n }\n\n const data = (await client.post('/sandboxes', {\n json: body,\n timeout: opts?.requestTimeout,\n })) as Record<string, unknown>;\n\n const sandboxId = data.sandbox_id as string;\n assertValidId(sandboxId, 'sandbox ID (from server)');\n\n return new Sandbox(\n sandboxId,\n config,\n client,\n data.envd_access_token as string | undefined,\n data.sandbox_domain as string | undefined,\n data.traffic_access_token as string | undefined,\n );\n }\n\n /**\n * Connect to an existing sandbox.\n *\n * @param sandboxId - The sandbox ID to connect to.\n * @param opts - Connection options.\n * @returns A Sandbox instance connected to the existing sandbox.\n */\n static async connect(\n sandboxId: string,\n opts?: { apiKey?: string; domain?: string; apiUrl?: string; requestTimeout?: number },\n ): Promise<Sandbox> {\n assertValidId(sandboxId, 'sandbox ID');\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n apiUrl: opts?.apiUrl,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n\n const data = (await client.get(`/sandboxes/${sandboxId}`, {\n timeout: opts?.requestTimeout,\n })) as Record<string, unknown>;\n\n return new Sandbox(\n data.sandbox_id as string,\n config,\n client,\n data.envd_access_token as string | undefined,\n data.sandbox_domain as string | undefined,\n data.traffic_access_token as string | undefined,\n );\n }\n\n /**\n * List sandboxes.\n *\n * Creates a temporary ApiClient, fetches the list, and closes the client.\n *\n * @param opts - Listing options.\n * @returns An object with parsed sandbox info array and optional pagination token.\n */\n static async list(opts?: {\n query?: Record<string, string>;\n limit?: number;\n nextToken?: string;\n apiKey?: string;\n domain?: string;\n apiUrl?: string;\n requestTimeout?: number;\n }): Promise<{ sandboxes: SandboxInfo[]; nextToken?: string }> {\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n apiUrl: opts?.apiUrl,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n\n const params: Record<string, string> = {};\n if (opts?.query) {\n for (const [key, value] of Object.entries(opts.query)) {\n params[key] = value;\n }\n }\n if (opts?.limit !== undefined) {\n params.limit = String(opts.limit);\n }\n if (opts?.nextToken) {\n params.next_token = opts.nextToken;\n }\n\n const data = (await client.get('/sandboxes', {\n params,\n timeout: opts?.requestTimeout,\n })) as Record<string, unknown>;\n\n const rawSandboxes = (data.sandboxes ?? []) as Record<string, unknown>[];\n const sandboxes = rawSandboxes.map((s) =>\n parseSandboxInfo(s as Record<string, unknown>),\n );\n\n return {\n sandboxes,\n nextToken: (data.next_token as string) ?? undefined,\n };\n }\n\n /**\n * Kill this sandbox.\n *\n * Returns once the kill has been accepted by the server. The per-VM\n * teardown (firecracker shutdown + netns + iptables cleanup) runs in\n * the background. Pass `{ wait: true }` to block until the teardown\n * has fully completed.\n *\n * @param requestTimeout - Optional per-request timeout in milliseconds.\n * @returns True if the sandbox was killed (or queued); false if the\n * server reported it was already dead.\n */\n async kill(requestTimeout?: number): Promise<boolean>;\n async kill(opts?: { requestTimeout?: number; wait?: boolean }): Promise<boolean>;\n async kill(arg?: number | { requestTimeout?: number; wait?: boolean }): Promise<boolean> {\n const opts = typeof arg === 'number' ? { requestTimeout: arg } : (arg ?? {});\n const wait = opts.wait === true;\n const path = wait\n ? `/sandboxes/${this._sandboxId}`\n : `/sandboxes/${this._sandboxId}?async=true`;\n const data = (await this._client.delete(path, {\n timeout: opts.requestTimeout,\n })) as Record<string, unknown>;\n if (!wait) {\n return (data.queued as boolean) ?? true;\n }\n return (data.killed as boolean) ?? false;\n }\n\n /**\n * Kill many sandboxes in a single request. Server fans out internally\n * with bounded concurrency, eliminating per-id round-trip overhead.\n *\n * @param ids - sandbox IDs to kill.\n * @param opts.wait - If true, wait for each VM's teardown to finish\n * before returning. Default is false (server returns 202 once the\n * request is queued).\n * @param opts.requestTimeout - Per-request timeout in milliseconds.\n * @returns Map of sandbox-id → outcome. Outcome is `{killed: true}`\n * (wait=true), `{queued: true}` (default), or `{error: string}` if\n * the server reported a per-id failure.\n */\n static async killMany(\n ids: string[],\n opts?: { wait?: boolean; requestTimeout?: number; config?: ConnectionConfig },\n ): Promise<Record<string, { killed?: boolean; queued?: boolean; error?: string }>> {\n if (!ids || ids.length === 0) return {};\n const config = opts?.config ?? new ConnectionConfig();\n const client = getSharedClient(config);\n const path = opts?.wait ? '/sandboxes/kill-many' : '/sandboxes/kill-many?async=true';\n const data = (await client.post(path, {\n json: { sandbox_ids: ids },\n timeout: opts?.requestTimeout,\n })) as { results?: Record<string, { killed?: boolean; queued?: boolean; error?: string }> };\n return data.results ?? {};\n }\n\n /**\n * Kill a sandbox by id without first connecting. Sends a single\n * `DELETE /sandboxes/:id?async=true` and skips the metadata fetch\n * `Sandbox.connect(id).kill()` would otherwise pay. Useful for bulk\n * cleanup paths that only have the id.\n *\n * @param sandboxId - the sandbox to kill.\n * @param opts.wait - if true, block until the server finishes the\n * per-VM teardown. Default is false: server returns 202 once the\n * kill is queued.\n * @param opts.requestTimeout - per-request timeout in milliseconds.\n * @param opts.config - override the default ConnectionConfig.\n * @returns true if the kill was accepted (default) or completed\n * (wait=true); false if the server reported the sandbox was\n * already dead.\n */\n static async kill(\n sandboxId: string,\n opts?: { wait?: boolean; requestTimeout?: number; config?: ConnectionConfig },\n ): Promise<boolean> {\n const config = opts?.config ?? new ConnectionConfig();\n const client = getSharedClient(config);\n const wait = opts?.wait === true;\n const path = wait\n ? `/sandboxes/${sandboxId}`\n : `/sandboxes/${sandboxId}?async=true`;\n const data = (await client.delete(path, {\n timeout: opts?.requestTimeout,\n })) as Record<string, unknown>;\n if (!wait) return (data.queued as boolean) ?? true;\n return (data.killed as boolean) ?? false;\n }\n\n /**\n * Check if this sandbox is currently running.\n *\n * @param requestTimeout - Optional per-request timeout in milliseconds.\n * @returns True if the sandbox is running.\n */\n async isRunning(requestTimeout?: number): Promise<boolean> {\n const data = (await this._client.get(`/sandboxes/${this._sandboxId}/status`, {\n timeout: requestTimeout,\n })) as Record<string, unknown>;\n return (data.is_running as boolean) ?? false;\n }\n\n /**\n * Set the timeout for this sandbox.\n *\n * @param timeout - New timeout in seconds.\n * @param requestTimeout - Optional per-request timeout in milliseconds.\n */\n async setTimeout(timeout: number, requestTimeout?: number): Promise<void> {\n await this._client.patch(`/sandboxes/${this._sandboxId}/timeout`, {\n json: { timeout },\n timeout: requestTimeout,\n });\n }\n\n /**\n * Get information about this sandbox.\n *\n * @param requestTimeout - Optional per-request timeout in milliseconds.\n * @returns Parsed sandbox information.\n */\n async getInfo(requestTimeout?: number): Promise<SandboxInfo> {\n const data = (await this._client.get(`/sandboxes/${this._sandboxId}`, {\n timeout: requestTimeout,\n })) as Record<string, unknown>;\n return parseSandboxInfo(data);\n }\n\n /**\n * Get metrics for this sandbox.\n *\n * @param opts - Optional start/end date range and request timeout.\n * @returns Array of parsed sandbox metrics.\n */\n async getMetrics(opts?: {\n start?: Date;\n end?: Date;\n requestTimeout?: number;\n }): Promise<SandboxMetrics[]> {\n const params: Record<string, string> = {};\n if (opts?.start) {\n params.start = opts.start.toISOString();\n }\n if (opts?.end) {\n params.end = opts.end.toISOString();\n }\n\n const data = (await this._client.get(`/sandboxes/${this._sandboxId}/metrics`, {\n params,\n timeout: opts?.requestTimeout,\n })) as Record<string, unknown>[] | null;\n\n return (data ?? []).map((m) => parseSandboxMetrics(m));\n }\n\n /**\n * Pause this sandbox.\n *\n * @param requestTimeout - Optional per-request timeout in milliseconds.\n */\n async pause(requestTimeout?: number): Promise<void> {\n await this._client.post(`/sandboxes/${this._sandboxId}/pause`, {\n timeout: requestTimeout,\n });\n }\n\n /**\n * Resume a paused sandbox.\n *\n * @param requestTimeout - Optional per-request timeout in milliseconds.\n */\n async resume(requestTimeout?: number): Promise<void> {\n await this._client.post(`/sandboxes/${this._sandboxId}/resume`, {\n timeout: requestTimeout,\n });\n }\n\n /**\n * Create a snapshot of this sandbox.\n *\n * @param requestTimeout - Optional per-request timeout in milliseconds.\n * @returns Parsed snapshot information.\n */\n async createSnapshot(requestTimeout?: number): Promise<SnapshotInfo> {\n const data = (await this._client.post(`/sandboxes/${this._sandboxId}/snapshot`, {\n timeout: requestTimeout,\n })) as Record<string, unknown>;\n return parseSnapshotInfo(data);\n }\n\n /**\n * Create a manual snapshot of this sandbox.\n *\n * Manual snapshots accumulate — every call creates a new persistent\n * checkpoint that survives sandbox.kill(). Use Sandbox.listSnapshots()\n * to retrieve them and Sandbox.restore(sandboxId, { snapshotId }) to fork from one.\n *\n * @param requestTimeout - Optional per-request timeout in milliseconds.\n * @returns Parsed Snapshot metadata including the snapshot_id.\n */\n async snapshot(requestTimeout?: number): Promise<Snapshot> {\n const data = (await this._client.post(`/sandboxes/${this._sandboxId}/snapshot`, {\n json: {},\n timeout: requestTimeout,\n })) as Record<string, unknown>;\n return parseSnapshot(data);\n }\n\n /**\n * List all snapshots (periodic + pause + manual) for this sandbox, newest first.\n *\n * @param requestTimeout - Optional per-request timeout in milliseconds.\n * @returns Array of Snapshot metadata objects.\n */\n async listSnapshots(requestTimeout?: number): Promise<Snapshot[]> {\n const data = (await this._client.get(`/sandboxes/${this._sandboxId}/snapshots`, {\n timeout: requestTimeout,\n })) as Record<string, unknown>;\n const raw = (data.snapshots ?? []) as Record<string, unknown>[];\n return raw.map((s) => parseSnapshot(s));\n }\n\n /**\n * Delete a single snapshot of this sandbox by ID.\n *\n * The snapshot's PG row and S3 blobs (mem / vmstate / overlay) are\n * removed. Idempotent: deleting an already-deleted snapshot resolves to\n * true without throwing.\n *\n * The pause snapshot of a currently-paused sandbox is protected — the\n * server returns 409 because deletion would break Resume. Resume or\n * kill the sandbox first.\n *\n * @param snapshotId - The snapshot to delete.\n * @param requestTimeout - Optional per-request timeout in milliseconds.\n * @returns True on success.\n */\n async deleteSnapshot(snapshotId: string, requestTimeout?: number): Promise<boolean> {\n await this._client.delete(`/sandboxes/${this._sandboxId}/snapshots/${snapshotId}`, {\n timeout: requestTimeout,\n });\n return true;\n }\n\n /**\n * Restore a sandbox from a snapshot. The restored instance may run on a\n * different worker node than the original sandbox.\n *\n * @param sandboxId - The sandbox to restore.\n * @param options.snapshotId - Optional snapshot to restore from. If omitted,\n * sandbox-manager picks the most recent snapshot (pause > periodic > manual).\n * @param options.apiKey - Optional API key override.\n * @param options.domain - Optional domain override.\n * @param options.requestTimeout - Optional per-request timeout in milliseconds.\n * @returns A new Sandbox instance connected to the restored sandbox.\n */\n static async restore(\n sandboxId: string,\n options: { snapshotId?: string; apiKey?: string; domain?: string; apiUrl?: string; requestTimeout?: number } = {},\n ): Promise<Sandbox> {\n assertValidId(sandboxId, 'sandbox ID');\n const config = new ConnectionConfig({\n apiKey: options.apiKey,\n domain: options.domain,\n apiUrl: options.apiUrl,\n requestTimeout: options.requestTimeout,\n });\n const client = getSharedClient(config);\n\n const query = options.snapshotId ? `?snapshot_id=${encodeURIComponent(options.snapshotId)}` : '';\n await client.post(`/sandboxes/${sandboxId}/restore${query}`, {\n timeout: options.requestTimeout,\n });\n\n // Fetch current sandbox state so the returned Sandbox is fully populated.\n const data = (await client.get(`/sandboxes/${sandboxId}`, {\n timeout: options.requestTimeout,\n })) as Record<string, unknown>;\n\n return new Sandbox(\n data.sandbox_id as string,\n config,\n client,\n data.envd_access_token as string | undefined,\n data.sandbox_domain as string | undefined,\n data.traffic_access_token as string | undefined,\n );\n }\n\n /**\n * Historically closed the sandbox's HTTP client; since 1.1.1 the SDK\n * maintains a process-wide shared ApiClient (see `getSharedClient` in\n * api/client.ts) so per-sandbox close no longer tears the connection\n * pool down. Kept as a no-op for backwards compatibility — call\n * `resetSharedClients()` if you want to force a full teardown.\n */\n close(): void {\n // no-op\n }\n\n /**\n * Support `await using sandbox = await Sandbox.create(...)` for automatic cleanup.\n */\n async [Symbol.asyncDispose](): Promise<void> {\n this.close();\n }\n}\n\n/** Convert SandboxNetworkOpts to snake_case JSON for the API. */\nfunction networkOptsToJSON(opts: SandboxNetworkOpts): Record<string, unknown> {\n const result: Record<string, unknown> = {\n allow_out: opts.allowOut,\n deny_out: opts.denyOut,\n allow_public_traffic: opts.allowPublicTraffic,\n };\n if (opts.maskRequestHost !== undefined) {\n result.mask_request_host = opts.maskRequestHost;\n }\n return result;\n}\n\n/** Convert SandboxLifecycle to snake_case JSON for the API. */\nfunction lifecycleToJSON(lifecycle: SandboxLifecycle): Record<string, unknown> {\n return {\n on_timeout: lifecycle.onTimeout,\n auto_resume: lifecycle.autoResume,\n };\n}\n","import { ApiClient } from './api/client.js';\nimport { SandboxError } from './errors.js';\nimport type { SandboxInfo, SnapshotInfo } from './sandbox/models.js';\nimport { parseSandboxInfo, parseSnapshotInfo } from './sandbox/models.js';\n\n/**\n * Paginator for listing sandboxes.\n *\n * Supports manual pagination via `nextItems()` and automatic iteration\n * via `for await (const page of paginator)`.\n */\nexport class SandboxPaginator {\n private readonly client: ApiClient;\n private readonly query: Record<string, string>;\n private readonly limit?: number;\n private _nextToken: string | undefined;\n private _exhausted = false;\n\n constructor(\n client: ApiClient,\n opts?: { query?: Record<string, string>; limit?: number },\n ) {\n this.client = client;\n this.query = opts?.query ?? {};\n this.limit = opts?.limit;\n }\n\n /** Whether there are more pages to fetch. */\n get hasNext(): boolean {\n return !this._exhausted;\n }\n\n /**\n * Fetch the next page of sandboxes.\n *\n * @throws SandboxError when no more pages are available.\n */\n async nextItems(): Promise<SandboxInfo[]> {\n if (this._exhausted) {\n throw new SandboxError('No more pages');\n }\n\n const params: Record<string, string> = { ...this.query };\n if (this.limit !== undefined) {\n params.limit = String(this.limit);\n }\n if (this._nextToken) {\n params.next_token = this._nextToken;\n }\n\n const data = await this.client.get('/sandboxes', { params });\n const response = data as Record<string, unknown>;\n const rawSandboxes = (response.sandboxes ?? []) as Record<string, unknown>[];\n const nextToken = response.next_token as string | null;\n\n if (nextToken) {\n this._nextToken = nextToken;\n } else {\n this._exhausted = true;\n this._nextToken = undefined;\n }\n\n return rawSandboxes.map((raw) => parseSandboxInfo(raw));\n }\n\n /** Async iterator that yields pages until exhausted. */\n async *[Symbol.asyncIterator](): AsyncIterator<SandboxInfo[]> {\n while (this.hasNext) {\n yield await this.nextItems();\n }\n }\n}\n\n/**\n * Paginator for listing snapshots.\n *\n * Supports manual pagination via `nextItems()` and automatic iteration\n * via `for await (const page of paginator)`.\n */\nexport class SnapshotPaginator {\n private readonly client: ApiClient;\n private readonly sandboxId?: string;\n private readonly limit?: number;\n private _nextToken: string | undefined;\n private _exhausted = false;\n\n constructor(\n client: ApiClient,\n opts?: { sandboxId?: string; limit?: number },\n ) {\n this.client = client;\n this.sandboxId = opts?.sandboxId;\n this.limit = opts?.limit;\n }\n\n /** Whether there are more pages to fetch. */\n get hasNext(): boolean {\n return !this._exhausted;\n }\n\n /**\n * Fetch the next page of snapshots.\n *\n * @throws SandboxError when no more pages are available.\n */\n async nextItems(): Promise<SnapshotInfo[]> {\n if (this._exhausted) {\n throw new SandboxError('No more pages');\n }\n\n const params: Record<string, string> = {};\n if (this.sandboxId) {\n params.sandbox_id = this.sandboxId;\n }\n if (this.limit !== undefined) {\n params.limit = String(this.limit);\n }\n if (this._nextToken) {\n params.next_token = this._nextToken;\n }\n\n const data = await this.client.get('/snapshots', { params });\n const response = data as Record<string, unknown>;\n const rawSnapshots = (response.snapshots ?? []) as Record<string, unknown>[];\n const nextToken = response.next_token as string | null;\n\n if (nextToken) {\n this._nextToken = nextToken;\n } else {\n this._exhausted = true;\n this._nextToken = undefined;\n }\n\n return rawSnapshots.map((raw) => parseSnapshotInfo(raw));\n }\n\n /** Async iterator that yields pages until exhausted. */\n async *[Symbol.asyncIterator](): AsyncIterator<SnapshotInfo[]> {\n while (this.hasNext) {\n yield await this.nextItems();\n }\n }\n}\n","/** An item to copy into a template. */\nexport interface CopyItem {\n src: string;\n dst: string;\n mode?: number;\n}\n\n/**\n * Fluent builder for template definitions.\n */\nexport class TemplateBase {\n private _baseImage: string = 'ubuntu:22.04';\n private _runCmds: string[][] = [];\n private _copies: CopyItem[] = [];\n private _envs: Record<string, string> = {};\n private _aptPackages: string[] = [];\n private _startCmd?: string;\n /**\n * When set, the server uses this Dockerfile verbatim and ignores the\n * structured fields. Use for multi-stage builds, ARG, ONBUILD, etc.\n */\n private _dockerfile?: string;\n\n /** Set the base image for the template. */\n fromBaseImage(image?: string): this {\n this._baseImage = image ?? 'ubuntu:22.04';\n return this;\n }\n\n /**\n * Use a raw Dockerfile string instead of the structured helpers.\n *\n * When set, all other ``aptInstall`` / ``runCmd`` / ``setEnvs`` /\n * ``copy`` / ``setStartCmd`` / ``fromBaseImage`` calls on this spec\n * are ignored — the Dockerfile is sent to the build worker verbatim.\n *\n * @param content Full Dockerfile contents. Must contain a ``FROM``\n * instruction. Capped server-side at 64 KiB.\n */\n fromDockerfile(content: string): this {\n this._dockerfile = content;\n return this;\n }\n\n /** Add a run command (as array of command + args). */\n runCmd(cmds: string[]): this {\n this._runCmds.push(cmds);\n return this;\n }\n\n /** Add a file copy operation. */\n copy(src: string, dst: string, mode?: number): this {\n this._copies.push({ src, dst, mode });\n return this;\n }\n\n /** Set environment variables. */\n setEnvs(envs: Record<string, string>): this {\n this._envs = { ...this._envs, ...envs };\n return this;\n }\n\n /** Install apt packages. */\n aptInstall(...packages: string[]): this {\n this._aptPackages.push(...packages);\n return this;\n }\n\n /** Set the start command. */\n setStartCmd(cmd: string): this {\n this._startCmd = cmd;\n return this;\n }\n\n /** Serialize the template to a JSON-friendly object. */\n toJSON(): Record<string, any> {\n // Raw Dockerfile path: send only the dockerfile field; the server\n // ignores helpers when this is set.\n if (this._dockerfile !== undefined) {\n return { dockerfile: this._dockerfile };\n }\n const result: Record<string, any> = {\n base_image: this._baseImage,\n };\n\n if (this._runCmds.length > 0) {\n // Server expects each run_cmd as a single shell line. Accept both\n // ``runCmd([\"pip3 install x\"])`` and\n // ``runCmd([\"pip3\", \"install\", \"x\"])`` and space-join so both\n // serialize the same on the wire. (#233)\n result.run_cmds = this._runCmds.map((c) => c.join(' '));\n }\n\n if (this._copies.length > 0) {\n result.copies = this._copies;\n }\n\n if (Object.keys(this._envs).length > 0) {\n result.envs = this._envs;\n }\n\n if (this._aptPackages.length > 0) {\n result.apt_packages = this._aptPackages;\n }\n\n if (this._startCmd !== undefined) {\n result.start_cmd = this._startCmd;\n }\n\n return result;\n }\n}\n\n/** Information about a template build. */\nexport interface BuildInfo {\n buildId: string;\n status: string;\n templateId?: string;\n}\n\n/** Parse raw JSON data into BuildInfo. */\nexport function parseBuildInfo(data: Record<string, any>): BuildInfo {\n return {\n buildId: data.build_id ?? data.buildId ?? '',\n status: data.status ?? '',\n templateId: data.template_id ?? data.templateId ?? undefined,\n };\n}\n\n/** Status of a template build. */\nexport interface TemplateBuildStatus {\n buildId: string;\n status: string;\n logs: string[];\n}\n\n/** Parse raw JSON data into TemplateBuildStatus. */\nexport function parseTemplateBuildStatus(data: Record<string, any>): TemplateBuildStatus {\n return {\n buildId: data.build_id ?? data.buildId ?? '',\n status: data.status ?? '',\n logs: data.logs ?? [],\n };\n}\n","import { ConnectionConfig } from '../connectionConfig.js';\nimport { getSharedClient } from '../api/client.js';\nimport { InvalidArgumentError } from '../errors.js';\nimport type { TemplateBase } from './models.js';\nimport type { BuildInfo, TemplateBuildStatus } from './models.js';\nimport { parseBuildInfo, parseTemplateBuildStatus } from './models.js';\n\nconst VALID_BUILD_ID_RE = /^[a-zA-Z0-9_-]+$/;\n\n/** Validate that a build ID is safe for URL path interpolation. */\nfunction assertValidBuildId(buildId: string): void {\n if (!buildId || !VALID_BUILD_ID_RE.test(buildId)) {\n throw new InvalidArgumentError(\n `Invalid build ID: \"${buildId}\". Must be alphanumeric with hyphens/underscores only.`,\n );\n }\n}\n\n/** Options for Template.build() and Template.buildInBackground(). */\nexport interface TemplateBuildOpts {\n /** Number of CPUs for the build. */\n cpuCount?: number;\n /** Memory in MB for the build. */\n memoryMb?: number;\n /** Disk size in MB for the build (128–102400). */\n diskMb?: number;\n /** Callback invoked for each build log entry. */\n onBuildLogs?: (log: string) => void;\n /** API key override. */\n apiKey?: string;\n /** Domain override. */\n domain?: string;\n /** Per-request timeout in milliseconds. */\n requestTimeout?: number;\n}\n\n/** Options for Template.getBuildStatus(). */\nexport interface GetBuildStatusOpts {\n /** API key override. */\n apiKey?: string;\n /** Domain override. */\n domain?: string;\n /** Per-request timeout in milliseconds. */\n requestTimeout?: number;\n}\n\n/**\n * Template management.\n *\n * All methods are static and create their own temporary ApiClient,\n * ensuring the client is always closed via try/finally (fixing Python SDK's client leak).\n */\nexport class Template {\n /**\n * Build a template and wait for completion.\n *\n * Sends POST /templates/build with the template definition.\n * Invokes onBuildLogs for each log entry in the response.\n */\n static async build(\n template: TemplateBase,\n alias: string,\n opts?: TemplateBuildOpts,\n ): Promise<BuildInfo> {\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n\n const body: Record<string, unknown> = {\n template: template.toJSON(),\n alias,\n };\n\n if (opts?.cpuCount !== undefined) {\n body.cpu_count = opts.cpuCount;\n }\n if (opts?.memoryMb !== undefined) {\n body.memory_mb = opts.memoryMb;\n }\n if (opts?.diskMb !== undefined) {\n body.disk_mb = opts.diskMb;\n }\n\n const data = await client.post('/templates/build', {\n json: body,\n timeout: opts?.requestTimeout,\n });\n\n const response = data as Record<string, unknown>;\n const result = parseBuildInfo(response);\n\n // Invoke log callback if provided\n if (opts?.onBuildLogs && Array.isArray(response.logs)) {\n for (const log of response.logs as string[]) {\n opts.onBuildLogs(log);\n }\n }\n\n return result;\n }\n\n /**\n * Start a template build in the background.\n *\n * Sends POST /templates/build with `background: true`.\n */\n static async buildInBackground(\n template: TemplateBase,\n alias: string,\n opts?: Omit<TemplateBuildOpts, 'onBuildLogs'>,\n ): Promise<BuildInfo> {\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n\n const body: Record<string, unknown> = {\n template: template.toJSON(),\n alias,\n background: true,\n };\n\n if (opts?.cpuCount !== undefined) {\n body.cpu_count = opts.cpuCount;\n }\n if (opts?.memoryMb !== undefined) {\n body.memory_mb = opts.memoryMb;\n }\n if (opts?.diskMb !== undefined) {\n body.disk_mb = opts.diskMb;\n }\n\n const data = await client.post('/templates/build', {\n json: body,\n timeout: opts?.requestTimeout,\n });\n\n return parseBuildInfo(data as Record<string, unknown>);\n }\n\n /**\n * Get the status of a template build.\n *\n * Sends GET /templates/builds/:buildId.\n */\n static async getBuildStatus(\n buildId: string,\n opts?: GetBuildStatusOpts,\n ): Promise<TemplateBuildStatus> {\n assertValidBuildId(buildId);\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n\n const data = await client.get(`/templates/builds/${buildId}`, {\n timeout: opts?.requestTimeout,\n });\n\n return parseTemplateBuildStatus(data as Record<string, unknown>);\n }\n}\n","import { ConnectionConfig } from '../connectionConfig.js';\nimport { getSharedClient } from '../api/client.js';\nimport { InvalidArgumentError } from '../errors.js';\nimport type { FileEntry, FileInfo } from './models.js';\nimport { parseFileEntry, parseFileInfo } from './models.js';\nimport type { VolumeRequestOpts } from './types.js';\n\nconst VALID_VOLUME_ID_RE = /^[a-zA-Z0-9_-]+$/;\n\nfunction assertValidVolumeId(id: string): void {\n if (!id || !VALID_VOLUME_ID_RE.test(id)) {\n throw new InvalidArgumentError(\n `Invalid volume ID: \"${id}\". Must be alphanumeric with hyphens/underscores only.`,\n );\n }\n}\n\n/** Options for VolumeFiles.write. */\nexport interface VolumeWriteOpts extends VolumeRequestOpts {\n /**\n * CAS token from `info(path).version`. When set, the server rejects the\n * write with a ConflictError (409) if the file changed since the token was\n * read. Omit for an unconditional write.\n */\n ifVersion?: string;\n}\n\n/** Options for VolumeFiles.remove. */\nexport interface VolumeRemoveOpts extends VolumeRequestOpts {\n /** Recursively remove a directory and its contents. */\n recursive?: boolean;\n}\n\n/**\n * File-granular operations on a single volume.\n *\n * Only valid for file-granular (non-tarball) volumes — the server returns\n * a ConflictError (409) for a tarball-backed volume and a 503 when no\n * file-granular accessor is configured. Obtain an instance via\n * `Volumes.files(volumeId)`.\n */\nexport class VolumeFiles {\n private readonly volumeId: string;\n private readonly opts?: VolumeRequestOpts;\n\n constructor(volumeId: string, opts?: VolumeRequestOpts) {\n assertValidVolumeId(volumeId);\n this.volumeId = volumeId;\n this.opts = opts;\n }\n\n private client() {\n const config = new ConnectionConfig({\n apiKey: this.opts?.apiKey,\n domain: this.opts?.domain,\n apiUrl: this.opts?.apiUrl,\n requestTimeout: this.opts?.requestTimeout,\n });\n return getSharedClient(config);\n }\n\n private timeout(): number | undefined {\n return this.opts?.requestTimeout;\n }\n\n /** Write raw bytes to `path`. Optionally conditional on `ifVersion` (CAS). */\n async write(\n path: string,\n data: Uint8Array | ArrayBuffer,\n opts?: VolumeWriteOpts,\n ): Promise<string> {\n if (!path) {\n throw new InvalidArgumentError('path is required');\n }\n const params: Record<string, string> = { path };\n if (opts?.ifVersion) {\n params.if_version = opts.ifVersion;\n }\n const body = data instanceof Uint8Array ? data : new Uint8Array(data);\n const resp = (await this.client().put(`/volumes/${this.volumeId}/files/raw`, {\n params,\n body,\n headers: { 'Content-Type': 'application/octet-stream' },\n timeout: opts?.requestTimeout ?? this.timeout(),\n })) as Record<string, unknown>;\n return String(resp.path ?? path);\n }\n\n /** Read raw bytes from `path`. */\n async read(path: string): Promise<Uint8Array> {\n if (!path) {\n throw new InvalidArgumentError('path is required');\n }\n return this.client().getBytes(`/volumes/${this.volumeId}/files/raw`, {\n params: { path },\n timeout: this.timeout(),\n });\n }\n\n /** List directory entries under `path`. */\n async list(path: string): Promise<FileEntry[]> {\n if (!path) {\n throw new InvalidArgumentError('path is required');\n }\n const resp = (await this.client().get(`/volumes/${this.volumeId}/files/list`, {\n params: { path },\n timeout: this.timeout(),\n })) as Record<string, unknown>;\n const rows = (resp.entries as Record<string, unknown>[] | undefined) ?? [];\n return rows.map(parseFileEntry);\n }\n\n /** Stat `path`, returning the entry plus the CAS `version` token. */\n async info(path: string): Promise<FileInfo> {\n if (!path) {\n throw new InvalidArgumentError('path is required');\n }\n const resp = (await this.client().get(`/volumes/${this.volumeId}/files/info`, {\n params: { path },\n timeout: this.timeout(),\n })) as Record<string, unknown>;\n return parseFileInfo(resp);\n }\n\n /** Return whether `path` exists. */\n async exists(path: string): Promise<boolean> {\n if (!path) {\n throw new InvalidArgumentError('path is required');\n }\n const resp = (await this.client().get(`/volumes/${this.volumeId}/files/exists`, {\n params: { path },\n timeout: this.timeout(),\n })) as Record<string, unknown>;\n return Boolean(resp.exists ?? false);\n }\n\n /** Remove `path`. Pass `{ recursive: true }` to remove a directory tree. */\n async remove(path: string, opts?: VolumeRemoveOpts): Promise<void> {\n if (!path) {\n throw new InvalidArgumentError('path is required');\n }\n const params: Record<string, string> = {\n path,\n recursive: opts?.recursive ? 'true' : 'false',\n };\n await this.client().delete(`/volumes/${this.volumeId}/files`, {\n params,\n timeout: opts?.requestTimeout ?? this.timeout(),\n });\n }\n\n /** Rename `oldPath` to `newPath`. */\n async rename(oldPath: string, newPath: string): Promise<{ oldPath: string; newPath: string }> {\n if (!oldPath || !newPath) {\n throw new InvalidArgumentError('oldPath and newPath are required');\n }\n const resp = (await this.client().patch(`/volumes/${this.volumeId}/files`, {\n json: { old_path: oldPath, new_path: newPath },\n timeout: this.timeout(),\n })) as Record<string, unknown>;\n return {\n oldPath: String(resp.old_path ?? oldPath),\n newPath: String(resp.new_path ?? newPath),\n };\n }\n\n /** Create a directory at `path`. */\n async mkdir(path: string): Promise<string> {\n if (!path) {\n throw new InvalidArgumentError('path is required');\n }\n const resp = (await this.client().post(`/volumes/${this.volumeId}/files/mkdir`, {\n json: { path },\n timeout: this.timeout(),\n })) as Record<string, unknown>;\n return String(resp.path ?? path);\n }\n}\n","import { ConnectionConfig } from '../connectionConfig.js';\nimport { getSharedClient } from '../api/client.js';\nimport { InvalidArgumentError } from '../errors.js';\nimport type { LockLease, LockStatus } from './models.js';\nimport { parseLockLease, parseLockStatus } from './models.js';\nimport type { VolumeRequestOpts } from './types.js';\n\nconst VALID_VOLUME_ID_RE = /^[a-zA-Z0-9_-]+$/;\n\nfunction assertValidVolumeId(id: string): void {\n if (!id || !VALID_VOLUME_ID_RE.test(id)) {\n throw new InvalidArgumentError(\n `Invalid volume ID: \"${id}\". Must be alphanumeric with hyphens/underscores only.`,\n );\n }\n}\n\n/**\n * Advisory locks (leases) over a (volume, path) pair.\n *\n * Acquire returns a token; renew/release require it. A ConflictError (409)\n * is raised on acquire when the path is already locked, and on renew/release\n * when the caller is not the current holder. Obtain an instance via\n * `Volumes.locks(volumeId)`.\n */\nexport class VolumeLocks {\n private readonly volumeId: string;\n private readonly opts?: VolumeRequestOpts;\n\n constructor(volumeId: string, opts?: VolumeRequestOpts) {\n assertValidVolumeId(volumeId);\n this.volumeId = volumeId;\n this.opts = opts;\n }\n\n private client() {\n const config = new ConnectionConfig({\n apiKey: this.opts?.apiKey,\n domain: this.opts?.domain,\n apiUrl: this.opts?.apiUrl,\n requestTimeout: this.opts?.requestTimeout,\n });\n return getSharedClient(config);\n }\n\n private timeout(): number | undefined {\n return this.opts?.requestTimeout;\n }\n\n /** Acquire a lock on `path`. Throws ConflictError (409) if already held. */\n async acquire(path: string, ttlSeconds?: number): Promise<LockLease> {\n if (!path) {\n throw new InvalidArgumentError('path is required');\n }\n const json: Record<string, unknown> = { path };\n if (ttlSeconds !== undefined) {\n json.ttl_seconds = ttlSeconds;\n }\n const resp = (await this.client().post(`/volumes/${this.volumeId}/locks`, {\n json,\n timeout: this.timeout(),\n })) as Record<string, unknown>;\n return parseLockLease(resp);\n }\n\n /** Release a lock on `path` held under `token`. Throws ConflictError (409) if not the holder. */\n async release(path: string, token: string): Promise<boolean> {\n if (!path || !token) {\n throw new InvalidArgumentError('path and token are required');\n }\n const resp = (await this.client().delete(`/volumes/${this.volumeId}/locks`, {\n json: { path, token },\n timeout: this.timeout(),\n })) as Record<string, unknown>;\n return Boolean(resp.released ?? false);\n }\n\n /** Renew a lock on `path` held under `token`. Throws ConflictError (409) if not the holder. */\n async renew(path: string, token: string, ttlSeconds?: number): Promise<LockLease> {\n if (!path || !token) {\n throw new InvalidArgumentError('path and token are required');\n }\n const json: Record<string, unknown> = { path, token };\n if (ttlSeconds !== undefined) {\n json.ttl_seconds = ttlSeconds;\n }\n const resp = (await this.client().post(`/volumes/${this.volumeId}/locks/renew`, {\n json,\n timeout: this.timeout(),\n })) as Record<string, unknown>;\n // The server's renew response carries {renewed, ttl_seconds, expires_at} but\n // NOT the token (the caller already holds it). Echo the caller's token so the\n // returned lease is complete.\n return { ...parseLockLease(resp), token };\n }\n\n /** Query whether `path` is currently locked. */\n async status(path: string): Promise<LockStatus> {\n if (!path) {\n throw new InvalidArgumentError('path is required');\n }\n const resp = (await this.client().get(`/volumes/${this.volumeId}/locks`, {\n params: { path },\n timeout: this.timeout(),\n })) as Record<string, unknown>;\n return parseLockStatus(resp);\n }\n}\n","import { ConnectionConfig } from '../connectionConfig.js';\nimport { getSharedClient } from '../api/client.js';\nimport { InvalidArgumentError } from '../errors.js';\nimport type { VolumeInfo } from './models.js';\nimport { parseVolumeInfo } from './models.js';\nimport type { VolumeRequestOpts } from './types.js';\nimport { VolumeFiles } from './files.js';\nimport { VolumeLocks } from './locks.js';\n\nconst VALID_VOLUME_ID_RE = /^[a-zA-Z0-9_-]+$/;\n\nfunction assertValidVolumeId(id: string): void {\n if (!id || !VALID_VOLUME_ID_RE.test(id)) {\n throw new InvalidArgumentError(\n `Invalid volume ID: \"${id}\". Must be alphanumeric with hyphens/underscores only.`,\n );\n }\n}\n\nexport type { VolumeRequestOpts } from './types.js';\n\n/** Options for Volumes.create / ingest. */\nexport interface VolumeCreateOpts extends VolumeRequestOpts {\n /** Override the Content-Type header. Defaults to application/gzip. */\n contentType?: string;\n}\n\n/**\n * Volumes: upload a tarball once and attach it to one or many sandboxes,\n * or create file-granular volumes that support per-file read/write,\n * compare-and-swap (CAS), and advisory locks.\n *\n * Phase 1 (tarball backend): the body must be a gzip-compressed tar archive;\n * the server materializes regular-file entries inside the sandbox filesystem\n * under the attachment's mount_path. Symlinks, hardlinks, and device nodes\n * are dropped on the server for safety.\n */\nexport class Volumes {\n /** Create a volume by streaming a tarball (gzip tar.gz) to the server. */\n static async create(\n name: string,\n data: Uint8Array | ArrayBuffer,\n opts?: VolumeCreateOpts,\n ): Promise<VolumeInfo> {\n if (!name) {\n throw new InvalidArgumentError('volume name is required');\n }\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n apiUrl: opts?.apiUrl,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n const body = data instanceof Uint8Array ? data : new Uint8Array(data);\n const resp = (await client.post('/volumes', {\n params: { name },\n body,\n headers: { 'Content-Type': opts?.contentType ?? 'application/gzip' },\n timeout: opts?.requestTimeout,\n })) as Record<string, unknown>;\n return parseVolumeInfo(resp);\n }\n\n /**\n * Capture the attached volume's mount path in `sandboxId` into a NEW volume.\n *\n * The source volume is left unchanged. If `name` is omitted the server names\n * the new volume \"<source-name>-commit\". Returns the new VolumeInfo.\n */\n static async commit(\n sandboxId: string,\n volumeId: string,\n name?: string,\n opts?: VolumeRequestOpts,\n ): Promise<VolumeInfo> {\n if (!sandboxId || !VALID_VOLUME_ID_RE.test(sandboxId)) {\n throw new InvalidArgumentError(\n `Invalid sandbox ID: \"${sandboxId}\". Must be alphanumeric with hyphens/underscores only.`,\n );\n }\n assertValidVolumeId(volumeId);\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n apiUrl: opts?.apiUrl,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n const resp = (await client.post(`/sandboxes/${sandboxId}/volumes/${volumeId}/commit`, {\n params: name ? { name } : undefined,\n timeout: opts?.requestTimeout,\n })) as Record<string, unknown>;\n return parseVolumeInfo(resp);\n }\n\n /**\n * Snapshot an arbitrary absolute in-sandbox `path` into a NEW volume.\n *\n * Unlike `commit` (which captures an already-attached volume's mount path),\n * `snapshot` captures any path in the running sandbox. `name` defaults to\n * \"snapshot\" on the server. Synthetic paths (/proc, /sys, /dev) are rejected.\n */\n static async snapshot(\n sandboxId: string,\n path: string,\n name?: string,\n opts?: VolumeRequestOpts,\n ): Promise<VolumeInfo> {\n if (!sandboxId || !VALID_VOLUME_ID_RE.test(sandboxId)) {\n throw new InvalidArgumentError(\n `Invalid sandbox ID: \"${sandboxId}\". Must be alphanumeric with hyphens/underscores only.`,\n );\n }\n if (!path) {\n throw new InvalidArgumentError('path is required');\n }\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n apiUrl: opts?.apiUrl,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n const params: Record<string, string> = { path };\n if (name) {\n params.name = name;\n }\n const resp = (await client.post(`/sandboxes/${sandboxId}/volumes/snapshot`, {\n params,\n timeout: opts?.requestTimeout,\n })) as Record<string, unknown>;\n return parseVolumeInfo(resp);\n }\n\n /**\n * Create an empty file-granular volume. Requires a file-granular backend\n * (503 if not configured). Returns the new VolumeInfo.\n */\n static async empty(name: string, opts?: VolumeRequestOpts): Promise<VolumeInfo> {\n if (!name) {\n throw new InvalidArgumentError('volume name is required');\n }\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n apiUrl: opts?.apiUrl,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n const resp = (await client.post('/volumes/empty', {\n params: { name },\n timeout: opts?.requestTimeout,\n })) as Record<string, unknown>;\n return parseVolumeInfo(resp);\n }\n\n /**\n * Ingest a gzip tar.gz archive into a NEW file-granular volume. Requires a\n * file-granular backend (503 if not configured). 413 on quota exceeded.\n */\n static async ingest(\n name: string,\n data: Uint8Array | ArrayBuffer,\n opts?: VolumeCreateOpts,\n ): Promise<VolumeInfo> {\n if (!name) {\n throw new InvalidArgumentError('volume name is required');\n }\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n apiUrl: opts?.apiUrl,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n const body = data instanceof Uint8Array ? data : new Uint8Array(data);\n const resp = (await client.post('/volumes/ingest', {\n params: { name },\n body,\n headers: { 'Content-Type': opts?.contentType ?? 'application/gzip' },\n timeout: opts?.requestTimeout,\n })) as Record<string, unknown>;\n return parseVolumeInfo(resp);\n }\n\n /** Fetch metadata for a single volume. */\n static async get(volumeId: string, opts?: VolumeRequestOpts): Promise<VolumeInfo> {\n assertValidVolumeId(volumeId);\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n apiUrl: opts?.apiUrl,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n const resp = (await client.get(`/volumes/${volumeId}`, {\n timeout: opts?.requestTimeout,\n })) as Record<string, unknown>;\n return parseVolumeInfo(resp);\n }\n\n /** List all volumes owned by the caller, newest first. */\n static async list(opts?: VolumeRequestOpts): Promise<VolumeInfo[]> {\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n apiUrl: opts?.apiUrl,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n const resp = (await client.get('/volumes', {\n timeout: opts?.requestTimeout,\n })) as Record<string, unknown>;\n const rows = (resp.volumes as Record<string, unknown>[] | undefined) ?? [];\n return rows.map(parseVolumeInfo);\n }\n\n /** Download the volume's contents as raw bytes (the stored archive/blob). */\n static async download(volumeId: string, opts?: VolumeRequestOpts): Promise<Uint8Array> {\n assertValidVolumeId(volumeId);\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n apiUrl: opts?.apiUrl,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n return client.getBytes(`/volumes/${volumeId}/download`, {\n timeout: opts?.requestTimeout,\n });\n }\n\n /** Delete a volume and its blob. Idempotent on the wire. */\n static async delete(volumeId: string, opts?: VolumeRequestOpts): Promise<void> {\n assertValidVolumeId(volumeId);\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n apiUrl: opts?.apiUrl,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n await client.delete(`/volumes/${volumeId}`, { timeout: opts?.requestTimeout });\n }\n\n /**\n * File-granular operations (read/write/list/info/exists/remove/rename/mkdir,\n * plus CAS via `write(..., { ifVersion })`) on `volumeId`. File-granular\n * volumes only.\n */\n static files(volumeId: string, opts?: VolumeRequestOpts): VolumeFiles {\n return new VolumeFiles(volumeId, opts);\n }\n\n /** Advisory locks (acquire/release/renew/status) over a (volume, path). */\n static locks(volumeId: string, opts?: VolumeRequestOpts): VolumeLocks {\n return new VolumeLocks(volumeId, opts);\n }\n}\n","/** A single enforced control within a governance pack gate. */\nexport interface GovernanceControl {\n /** Control identifier, e.g. \"OWASP-LLM06-ExcessiveAgency\". */\n control: string;\n /** Gate that enforces this control: \"cmd\", \"network\", or \"content\". */\n gate: string;\n /** Human-readable rule description. */\n rule: string;\n /** Remediation playbook / guidance. */\n playbook: string;\n}\n\n/** An advisory (non-enforced) item within a governance pack. */\nexport interface GovernanceAdvisory {\n /** Control identifier this advisory references. */\n control: string;\n /** Explanation of why this control is advisory rather than enforced. */\n reason: string;\n}\n\n/** A governance pack returned by GET /governance/packs or GET /governance/packs/:name. */\nexport interface GovernancePack {\n /** Pack name / slug, e.g. \"owasp-llm-top10\". */\n name: string;\n /** Pack version string, e.g. \"v1\". */\n version: string;\n /** Full framework name, e.g. \"OWASP Top 10 for LLM Applications (2025)\". */\n framework: string;\n /** Human-readable description of what this pack enforces. */\n description: string;\n /** Gates activated by this pack, e.g. [\"cmd\",\"network\",\"content\"]. */\n gates: string[];\n /** Enforced controls within this pack. */\n enforces: GovernanceControl[];\n /** Advisory (non-enforced) controls within this pack. */\n advisory: GovernanceAdvisory[];\n /**\n * Canonical policy reference string, e.g. \"owasp-llm-top10@v1\".\n * Mapped from wire field `policy_ref`.\n */\n policyRef: string;\n /** Whether this pack was seeded (built-in) vs. user-created. */\n seeded: boolean;\n}\n\n/** Parse a raw wire-format governance control into a GovernanceControl. */\nfunction parseGovernanceControl(data: Record<string, unknown>): GovernanceControl {\n return {\n control: String(data.control ?? ''),\n gate: String(data.gate ?? ''),\n rule: String(data.rule ?? ''),\n playbook: String(data.playbook ?? ''),\n };\n}\n\n/** Parse a raw wire-format advisory entry into a GovernanceAdvisory. */\nfunction parseGovernanceAdvisory(data: Record<string, unknown>): GovernanceAdvisory {\n return {\n control: String(data.control ?? ''),\n reason: String(data.reason ?? ''),\n };\n}\n\n/** Parse a raw wire-format pack row into a GovernancePack. */\nexport function parseGovernancePack(data: Record<string, unknown>): GovernancePack {\n const rawEnforces = (data.enforces as Record<string, unknown>[] | null | undefined) ?? [];\n const rawAdvisory = (data.advisory as Record<string, unknown>[] | null | undefined) ?? [];\n\n return {\n name: String(data.name ?? ''),\n version: String(data.version ?? ''),\n framework: String(data.framework ?? ''),\n description: String(data.description ?? ''),\n gates: (data.gates as string[] | null | undefined) ?? [],\n enforces: rawEnforces.map(parseGovernanceControl),\n advisory: rawAdvisory.map(parseGovernanceAdvisory),\n policyRef: String(data.policy_ref ?? data.policyRef ?? ''),\n seeded: Boolean(data.seeded ?? false),\n };\n}\n","import { ConnectionConfig } from '../connectionConfig.js';\nimport { getSharedClient } from '../api/client.js';\nimport { InvalidArgumentError } from '../errors.js';\nimport type { GovernancePack } from './models.js';\nimport { parseGovernancePack } from './models.js';\n\nconst VALID_PACK_NAME_RE = /^[a-zA-Z0-9_-]+$/;\n\nfunction assertValidPackName(name: string): void {\n if (!name || !VALID_PACK_NAME_RE.test(name)) {\n throw new InvalidArgumentError(\n `Invalid pack name: \"${name}\". Must be alphanumeric with hyphens/underscores only.`,\n );\n }\n}\n\n/** Shared per-call options for Governance methods. */\nexport interface GovernanceRequestOpts {\n /** API key override. */\n apiKey?: string;\n /** Domain override. */\n domain?: string;\n /** Full API URL override. */\n apiUrl?: string;\n /** Per-request timeout in milliseconds. */\n requestTimeout?: number;\n}\n\n/**\n * Governance pack discovery.\n *\n * Lists and retrieves governance packs exposed by the Declaw control plane.\n * The /governance/packs endpoint is public — no auth is required — but the\n * SDK's normal Authorization header is still sent when an API key is\n * configured (harmless and consistent with other list methods).\n */\nexport class Governance {\n /**\n * List all available governance packs.\n *\n * Sends GET /governance/packs and returns the `packs` array.\n */\n static async listPacks(opts?: GovernanceRequestOpts): Promise<GovernancePack[]> {\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n apiUrl: opts?.apiUrl,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n const resp = (await client.get('/governance/packs', {\n timeout: opts?.requestTimeout,\n })) as Record<string, unknown>;\n const rows = (resp.packs as Record<string, unknown>[] | undefined) ?? [];\n return rows.map(parseGovernancePack);\n }\n\n /**\n * Fetch a single governance pack by name.\n *\n * Sends GET /governance/packs/:name and returns the pack object.\n * Throws InvalidArgumentError if the name contains unsafe characters.\n */\n static async getPack(name: string, opts?: GovernanceRequestOpts): Promise<GovernancePack> {\n assertValidPackName(name);\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n apiUrl: opts?.apiUrl,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n const resp = (await client.get(`/governance/packs/${name}`, {\n timeout: opts?.requestTimeout,\n })) as Record<string, unknown>;\n return parseGovernancePack(resp);\n }\n}\n"],"mappings":"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","names":["PIIType","RedactionAction","InjectionSensitivity","InjectionAction","TransformDirection","VALID_ACTIONS","VALID_ACTIONS","VALID_ACTIONS","SandboxState","splitlines","FileType","FilesystemEventType","result","import_stream","VALID_VOLUME_ID_RE","assertValidVolumeId","VALID_VOLUME_ID_RE","assertValidVolumeId"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/connectionConfig.ts","../src/errors.ts","../src/api/client.ts","../src/sandbox/network.ts","../src/security/pii.ts","../src/security/injection.ts","../src/security/audit.ts","../src/security/env.ts","../src/security/networkPolicy.ts","../src/security/transformations.ts","../src/security/toxicity.ts","../src/security/codeSecurity.ts","../src/security/invisibleText.ts","../src/security/customPolicy.ts","../src/security/contentGate.ts","../src/security/policy.ts","../src/sandbox/models.ts","../src/sandbox/commands/models.ts","../src/sandbox/commands/commandHandle.ts","../src/sandbox/commands/commands.ts","../src/sandbox/filesystem/models.ts","../src/sandbox/filesystem/watchHandle.ts","../src/sandbox/filesystem/filesystem.ts","../src/sandbox/pty/pty.ts","../src/sandbox/stdio/stdio.ts","../src/volumes/models.ts","../src/sandbox/sandbox.ts","../src/paginator.ts","../src/template/models.ts","../src/template/template.ts","../src/volumes/files.ts","../src/volumes/locks.ts","../src/volumes/volumes.ts","../src/governance/models.ts","../src/governance/governance.ts"],"sourcesContent":["// API Client\nexport { ApiClient, getSharedClient, resetSharedClients } from './api/client.js';\nexport type { RequestOpts } from './api/client.js';\n\n// Sandbox\nexport { Sandbox } from './sandbox/sandbox.js';\nexport type { SandboxOpts } from './sandbox/sandbox.js';\n\n// Errors\nexport {\n SandboxError,\n TimeoutError,\n NotFoundError,\n AuthenticationError,\n InvalidArgumentError,\n NotEnoughSpaceError,\n ConflictError,\n TemplateError,\n BuildError,\n FileUploadError,\n GitAuthError,\n GitUpstreamError,\n CommandExitError,\n} from './errors.js';\n\n// Connection config\nexport { ConnectionConfig } from './connectionConfig.js';\nexport type { ConnectionConfigOptions } from './connectionConfig.js';\n\n// Sandbox models\nexport {\n SandboxState,\n parseSandboxInfo,\n parseSandboxMetrics,\n parseSandboxLifecycle,\n parseSnapshotInfo,\n parseSnapshot,\n} from './sandbox/models.js';\nexport type {\n SandboxInfo,\n SandboxMetrics,\n SandboxQuery,\n SandboxLifecycle,\n SnapshotInfo,\n Snapshot,\n SnapshotSource,\n} from './sandbox/models.js';\n\n// Commands\nexport { Commands } from './sandbox/commands/commands.js';\nexport type { RunOpts, RunStreamOpts } from './sandbox/commands/commands.js';\nexport { CommandHandle } from './sandbox/commands/commandHandle.js';\nexport type { CommandWaitOpts } from './sandbox/commands/commandHandle.js';\n\n// Command models\nexport { parseCommandResult, parseProcessInfo } from './sandbox/commands/models.js';\nexport type {\n CommandResult,\n ProcessInfo,\n PtySize,\n PtyOutput,\n Stdout,\n Stderr,\n} from './sandbox/commands/models.js';\n\n// Filesystem\nexport { Filesystem } from './sandbox/filesystem/filesystem.js';\nexport { WatchHandle } from './sandbox/filesystem/watchHandle.js';\n\n// Filesystem models\nexport {\n FileType,\n FilesystemEventType,\n parseEntryInfo,\n parseWriteInfo,\n parseFilesystemEvent,\n} from './sandbox/filesystem/models.js';\nexport type {\n EntryInfo,\n WriteInfo,\n WriteEntry,\n FilesystemEvent,\n} from './sandbox/filesystem/models.js';\n\n// Network\nexport { ALL_TRAFFIC, validateNetworkEntry, domainMatches } from './sandbox/network.js';\nexport type { SandboxNetworkOpts } from './sandbox/network.js';\n\n// Security - PII\nexport { PIIType, RedactionAction, createPIIConfig, parsePIIConfig } from './security/pii.js';\nexport type { PIIConfig } from './security/pii.js';\n\n// Security - Injection\nexport {\n InjectionSensitivity,\n InjectionAction,\n createInjectionDefenseConfig,\n parseInjectionDefenseConfig,\n} from './security/injection.js';\nexport type { InjectionDefenseConfig, InjectionJudgeConfig } from './security/injection.js';\n\n// Security - Audit\nexport { createAuditConfig, parseAuditConfig, parseAuditEntry } from './security/audit.js';\nexport type { AuditConfig, AuditEntry } from './security/audit.js';\n\n// Security - Env\nexport {\n DEFAULT_MASK_PATTERNS,\n createEnvSecurityConfig,\n parseEnvSecurityConfig,\n isSensitive,\n} from './security/env.js';\nexport type { EnvSecurityConfig, SecureEnvVar } from './security/env.js';\n\n// Security - Transformations\nexport {\n TransformDirection,\n createTransformationRule,\n applyTransformation,\n} from './security/transformations.js';\nexport type { TransformationRule } from './security/transformations.js';\n\n// Security - Network Policy\nexport {\n createNetworkPolicy,\n parseNetworkPolicy,\n networkPolicyToOpts,\n} from './security/networkPolicy.js';\nexport type { NetworkPolicy } from './security/networkPolicy.js';\n\n// Security - Toxicity\nexport {\n createToxicityConfig,\n parseToxicityConfig,\n toxicityConfigToJSON,\n} from './security/toxicity.js';\nexport type { ToxicityConfig } from './security/toxicity.js';\n\n// Security - Code Security\nexport {\n createCodeSecurityConfig,\n parseCodeSecurityConfig,\n codeSecurityConfigToJSON,\n} from './security/codeSecurity.js';\nexport type { CodeSecurityConfig } from './security/codeSecurity.js';\n\n// Security - Invisible Text\nexport {\n createInvisibleTextConfig,\n parseInvisibleTextConfig,\n invisibleTextConfigToJSON,\n} from './security/invisibleText.js';\nexport type { InvisibleTextConfig } from './security/invisibleText.js';\n\n// Security - Content Gate\nexport {\n createContentGateConfig,\n parseContentGateConfig,\n contentGateConfigToJSON,\n} from './security/contentGate.js';\nexport type { ContentGateConfig } from './security/contentGate.js';\n\n// Security - Policy\nexport {\n createSecurityPolicy,\n fullInjectionDefensePolicy,\n parseSecurityPolicy,\n securityPolicyToJSON,\n requiresTlsInterception,\n} from './security/policy.js';\nexport type { SecurityPolicy, FullInjectionDefenseOptions } from './security/policy.js';\n\n// PTY\nexport { Pty, PtyHandle } from './sandbox/pty/pty.js';\nexport type { PtyCreateOpts, PtyConnectOpts, PtyResult } from './sandbox/pty/pty.js';\n\n// Stdio\nexport { Stdio, StdioProcess } from './sandbox/stdio/stdio.js';\nexport type { StdioStartOpts, StdioResult } from './sandbox/stdio/stdio.js';\n\n// Paginators\nexport { SandboxPaginator, SnapshotPaginator } from './paginator.js';\n\n// Template\nexport { Template } from './template/template.js';\nexport type { TemplateBuildOpts, GetBuildStatusOpts } from './template/template.js';\n\n// Template models\nexport { TemplateBase, parseBuildInfo, parseTemplateBuildStatus } from './template/models.js';\nexport type { CopyItem, BuildInfo, TemplateBuildStatus } from './template/models.js';\n\n// Volumes\nexport { Volumes } from './volumes/volumes.js';\nexport type { VolumeCreateOpts } from './volumes/volumes.js';\nexport type { VolumeRequestOpts } from './volumes/types.js';\nexport { VolumeFiles } from './volumes/files.js';\nexport type { VolumeWriteOpts, VolumeRemoveOpts } from './volumes/files.js';\nexport { VolumeLocks } from './volumes/locks.js';\nexport {\n parseVolumeInfo,\n parseFileEntry,\n parseFileInfo,\n parseLockLease,\n parseLockStatus,\n volumeAttachmentToJSON,\n} from './volumes/models.js';\nexport type {\n VolumeInfo,\n VolumeAttachment,\n VolumeAttachMode,\n FileEntry,\n FileInfo,\n LockLease,\n LockStatus,\n} from './volumes/models.js';\n\n// Governance\nexport { Governance } from './governance/governance.js';\nexport type { GovernanceRequestOpts } from './governance/governance.js';\nexport { parseGovernancePack } from './governance/models.js';\nexport type { GovernancePack, GovernanceControl, GovernanceAdvisory } from './governance/models.js';\n","/**\n * Configuration for connecting to the Declaw API.\n */\nexport interface ConnectionConfigOptions {\n /** API key for authentication. Defaults to DECLAW_API_KEY env var. */\n apiKey?: string;\n /** Domain of the Declaw API. Defaults to DECLAW_DOMAIN env var or 'api.declaw.ai'. */\n domain?: string;\n /** Port of the Declaw API. Defaults to 443. */\n port?: number;\n /** Full API URL override. If set, domain/port/scheme are ignored. */\n apiUrl?: string;\n /** Request timeout in milliseconds. */\n requestTimeout?: number;\n}\n\n/**\n * Holds connection configuration for the Declaw API.\n */\nexport class ConnectionConfig {\n readonly apiKey: string;\n readonly domain: string;\n readonly port: number;\n readonly apiUrl: string;\n readonly requestTimeout?: number;\n\n constructor(opts?: ConnectionConfigOptions) {\n this.apiKey = opts?.apiKey ?? process.env.DECLAW_API_KEY ?? '';\n this.requestTimeout = opts?.requestTimeout;\n\n // Parse \"host:port\" from domain, matching Python SDK behavior.\n // e.g. domain=\"myhost.example.com:8080\" → domain=\"myhost.example.com\", port=8080\n let rawDomain = opts?.domain ?? process.env.DECLAW_DOMAIN ?? 'api.declaw.ai';\n let rawPort = opts?.port ?? 443;\n\n if (opts?.port === undefined && rawDomain.includes(':')) {\n const lastColon = rawDomain.lastIndexOf(':');\n const maybPort = parseInt(rawDomain.substring(lastColon + 1), 10);\n if (!isNaN(maybPort)) {\n rawPort = maybPort;\n rawDomain = rawDomain.substring(0, lastColon);\n }\n }\n\n this.domain = rawDomain;\n this.port = rawPort;\n\n if (opts?.apiUrl) {\n this.apiUrl = opts.apiUrl;\n } else {\n const scheme = this.port === 443 ? 'https' : 'http';\n if (this.port === 443 || this.port === 80) {\n this.apiUrl = `${scheme}://${this.domain}`;\n } else {\n this.apiUrl = `${scheme}://${this.domain}:${this.port}`;\n }\n }\n }\n}\n","/**\n * Base error for all sandbox-related errors.\n */\nexport class SandboxError extends Error {\n sandboxId?: string;\n\n constructor(message: string, opts?: { sandboxId?: string }) {\n super(message);\n this.name = 'SandboxError';\n this.sandboxId = opts?.sandboxId;\n }\n}\n\n/** Thrown when an operation exceeds its timeout. */\nexport class TimeoutError extends SandboxError {\n constructor(message: string, opts?: { sandboxId?: string }) {\n super(message, opts);\n this.name = 'TimeoutError';\n }\n}\n\n/** Thrown when a sandbox or resource is not found. */\nexport class NotFoundError extends SandboxError {\n constructor(message: string, opts?: { sandboxId?: string }) {\n super(message, opts);\n this.name = 'NotFoundError';\n }\n}\n\n/** Thrown when authentication fails. */\nexport class AuthenticationError extends SandboxError {\n constructor(message: string, opts?: { sandboxId?: string }) {\n super(message, opts);\n this.name = 'AuthenticationError';\n }\n}\n\n/** Thrown when an argument is invalid. */\nexport class InvalidArgumentError extends SandboxError {\n constructor(message: string, opts?: { sandboxId?: string }) {\n super(message, opts);\n this.name = 'InvalidArgumentError';\n }\n}\n\n/** Thrown when there is not enough disk space. */\nexport class NotEnoughSpaceError extends SandboxError {\n constructor(message: string, opts?: { sandboxId?: string }) {\n super(message, opts);\n this.name = 'NotEnoughSpaceError';\n }\n}\n\n/**\n * Thrown on an HTTP 409 conflict.\n *\n * For volume file writes this signals a CAS (compare-and-swap) version\n * mismatch — the file changed since the `if_version` token was read. For\n * volume locks it signals the lock is already held by another holder (on\n * acquire) or that the caller is not the current holder (on release/renew).\n * Catch this to re-read and retry.\n */\nexport class ConflictError extends SandboxError {\n constructor(message: string, opts?: { sandboxId?: string }) {\n super(message, opts);\n this.name = 'ConflictError';\n }\n}\n\n/** Thrown for template-related errors. */\nexport class TemplateError extends SandboxError {\n constructor(message: string, opts?: { sandboxId?: string }) {\n super(message, opts);\n this.name = 'TemplateError';\n }\n}\n\n/** Thrown when a template build fails. */\nexport class BuildError extends TemplateError {\n constructor(message: string, opts?: { sandboxId?: string }) {\n super(message, opts);\n this.name = 'BuildError';\n }\n}\n\n/** Thrown when a file upload fails. */\nexport class FileUploadError extends SandboxError {\n constructor(message: string, opts?: { sandboxId?: string }) {\n super(message, opts);\n this.name = 'FileUploadError';\n }\n}\n\n/** Thrown when git authentication fails inside a sandbox. */\nexport class GitAuthError extends SandboxError {\n constructor(message: string, opts?: { sandboxId?: string }) {\n super(message, opts);\n this.name = 'GitAuthError';\n }\n}\n\n/** Thrown when a git upstream operation fails. */\nexport class GitUpstreamError extends SandboxError {\n constructor(message: string, opts?: { sandboxId?: string }) {\n super(message, opts);\n this.name = 'GitUpstreamError';\n }\n}\n\n/** Thrown when a command exits with a non-zero exit code. */\nexport class CommandExitError extends SandboxError {\n exitCode: number;\n stdout: string;\n stderr: string;\n\n constructor(\n message: string,\n opts: { sandboxId?: string; exitCode: number; stdout: string; stderr: string },\n ) {\n super(message, { sandboxId: opts.sandboxId });\n this.name = 'CommandExitError';\n this.exitCode = opts.exitCode;\n this.stdout = opts.stdout;\n this.stderr = opts.stderr;\n }\n}\n","import { ConnectionConfig } from '../connectionConfig.js';\nimport {\n SandboxError,\n TimeoutError,\n NotFoundError,\n AuthenticationError,\n InvalidArgumentError,\n NotEnoughSpaceError,\n ConflictError,\n} from '../errors.js';\n\n// ---------------------------------------------------------------------------\n// undici dispatcher (Node only).\n//\n// Node's built-in fetch() is backed by undici, which defaults to 10\n// connections per origin. When callers fan out many concurrent requests\n// (e.g. `Promise.all` of many `Sandbox.create()` calls) that cap becomes\n// a client-side serialization point.\n//\n// We lazily install a module-scope undici Agent with a larger pool and\n// keep-alive tuned for the Declaw backend. On runtimes that don't ship\n// undici (browsers, Cloudflare Workers, Deno), the dynamic import\n// silently fails and we fall through to the platform's native fetch.\n//\n// Tuning knobs (env vars — defaults sized so common burst workloads\n// \"just work\" without configuration):\n// DECLAW_SDK_CONNECTIONS=N — TCP connection pool size (default 64)\n// DECLAW_SDK_MAX_CONCURRENT_STREAMS=N — H2 streams per connection (default 1000;\n// undici's hard-coded default is 100)\n// DECLAW_SDK_DISABLE_DISPATCHER=1 — opt out, use platform fetch\n//\n// Math: pool capacity = connections × streams.\n// At defaults (64 × 1000 = 64,000) a single Node process handles up to\n// 60 k+ concurrent Sandbox.create() calls with zero client-side queueing.\n// The 64-connection pool keeps TCP setup overhead minimal on cold start\n// (benchmark-faster than larger pools at typical burst-100 workloads),\n// while the 1000-stream-per-connection ceiling stays well under the\n// server's advertised SETTINGS_MAX_CONCURRENT_STREAMS=4096 so undici\n// never has to back off on a single connection. For workloads above\n// 64 k concurrent in-flight, raise DECLAW_SDK_CONNECTIONS (e.g. 100 →\n// 100,000 cap). Memory cost is modest: idle pool state is ~15 MB; sockets\n// close after keepAliveTimeout=30s if unused. Low-concurrency callers\n// pay only for what they actually use — the pool is lazy (sockets are\n// dialed on demand).\n// ---------------------------------------------------------------------------\nlet _dispatcherPromise: Promise<unknown | undefined> | undefined;\n// Synchronously-cached resolved dispatcher. Once the import settles we store\n// the value here so the hot path skips `await getDispatcher()` entirely (an\n// await of even a resolved promise costs a microtask yield, which compounds\n// under burst fan-out). `undefined` is a valid resolved state (non-Node / opt\n// out); the separate `_dispatcherResolved` flag distinguishes \"resolved to\n// undefined\" from \"not yet resolved\".\nlet _resolvedDispatcher: unknown | undefined;\nlet _dispatcherResolved = false;\n\nfunction getDispatcher(): Promise<unknown | undefined> {\n if (_dispatcherPromise) return _dispatcherPromise;\n _dispatcherPromise = (async () => {\n try {\n // Only Node exposes process.versions.node; everything else bails.\n if (typeof process === 'undefined' || !process.versions?.node) {\n return undefined;\n }\n // Respect opt-out for users who bring their own dispatcher.\n if (process.env.DECLAW_SDK_DISABLE_DISPATCHER) {\n return undefined;\n }\n const undici: any = await import('undici');\n const connOverride = parseInt(process.env.DECLAW_SDK_CONNECTIONS || '', 10);\n const connections = Number.isFinite(connOverride) && connOverride > 0 ? connOverride : 64;\n const streamsOverride = parseInt(process.env.DECLAW_SDK_MAX_CONCURRENT_STREAMS || '', 10);\n const maxConcurrentStreams =\n Number.isFinite(streamsOverride) && streamsOverride > 0 ? streamsOverride : 1000;\n return new undici.Agent({\n connections,\n // maxConcurrentStreams only matters on H2 connections. undici negotiates\n // down to whatever the server advertises in SETTINGS_MAX_CONCURRENT_STREAMS,\n // so setting a high value here is safe — it caps the client-side intent,\n // server still wins.\n maxConcurrentStreams,\n keepAliveTimeout: 30_000,\n keepAliveMaxTimeout: 60_000,\n // NOTE: do NOT set `pipelining` here. undici applies it to H2 sessions\n // too, where `pipelining: 1` caps each connection to ONE in-flight\n // stream — silently defeating the H2 multiplexing that allowH2 enables.\n // Omitted, H2 sessions default to unlimited concurrent streams (capped\n // by maxConcurrentStreams) and H1.1 fallback defaults to 1 (safe, no\n // head-of-line risk on non-idempotent POSTs). This is the single\n // biggest burst-latency lever: with pipelining:1 a 100-concurrent burst\n // queued ~36 requests behind the `connections` cap.\n allowH2: true,\n connect: { keepAlive: true, keepAliveInitialDelay: 5_000 },\n });\n } catch {\n return undefined;\n }\n })();\n // Cache the resolved value synchronously so the hot path can skip the await.\n void _dispatcherPromise.then((d) => {\n _resolvedDispatcher = d;\n _dispatcherResolved = true;\n });\n return _dispatcherPromise;\n}\n\n// Eagerly kick off the undici import at module load instead of lazily on the\n// first request. Without this, the first burst of concurrent creates all queue\n// on the one unresolved `import('undici')` (~40-63ms cold). Firing it here moves\n// that cost onto module init, so by the time the first create runs it's ready.\nvoid getDispatcher();\n\n/**\n * Options for individual API requests.\n */\nexport interface RequestOpts {\n /** JSON body to serialize and send. */\n json?: unknown;\n /** Query parameters to append to the URL. */\n params?: Record<string, string>;\n /** Additional headers to merge with defaults. */\n headers?: Record<string, string>;\n /** Per-request timeout in milliseconds. Overrides config.requestTimeout. */\n timeout?: number;\n /** Raw body (string or Uint8Array). If set, json is ignored. */\n body?: string | Uint8Array;\n}\n\n/** Map of HTTP status codes to error classes. */\nconst STATUS_ERROR_MAP: Record<number, new (message: string) => SandboxError> = {\n 400: InvalidArgumentError,\n 401: AuthenticationError,\n 403: AuthenticationError,\n 404: NotFoundError,\n 408: TimeoutError,\n 409: ConflictError,\n 413: NotEnoughSpaceError,\n 422: InvalidArgumentError,\n 507: NotEnoughSpaceError,\n};\n\n/**\n * HTTP client for the Declaw API with Bearer auth, exponential backoff with jitter,\n * error mapping, and resource safety via AbortController.\n */\nexport class ApiClient {\n private readonly config: ConnectionConfig;\n private readonly maxRetries: number;\n private readonly retryDelay: number;\n private readonly abortController: AbortController;\n\n constructor(\n config?: ConnectionConfig,\n opts?: { maxRetries?: number; retryDelay?: number },\n ) {\n this.config = config ?? new ConnectionConfig();\n this.maxRetries = opts?.maxRetries ?? 3;\n // Retry backoff base (seconds). Only applies to 5xx/network retries (0ms on\n // the success path). 0.1s base → delay(0)=50-100ms vs the old 0.5s's\n // 250-500ms, cutting worst-case single-retry latency 5x. Override per-client\n // via opts.retryDelay; set 0 to disable backoff entirely.\n this.retryDelay = opts?.retryDelay ?? 0.1;\n this.abortController = new AbortController();\n }\n\n /** Send a GET request and return parsed JSON. */\n async get(path: string, opts?: RequestOpts): Promise<unknown> {\n return this.requestWithRetry('GET', path, opts);\n }\n\n /** Send a GET request and return the response body as raw bytes. */\n async getBytes(path: string, opts?: RequestOpts): Promise<Uint8Array> {\n const response = await this.requestWithRetry('GET', path, opts, true) as Response;\n const buf = await response.arrayBuffer();\n return new Uint8Array(buf);\n }\n\n /** Send a POST request and return parsed JSON. */\n async post(path: string, opts?: RequestOpts): Promise<unknown> {\n return this.requestWithRetry('POST', path, opts);\n }\n\n /** Send a PATCH request and return parsed JSON. */\n async patch(path: string, opts?: RequestOpts): Promise<unknown> {\n return this.requestWithRetry('PATCH', path, opts);\n }\n\n /** Send a DELETE request and return parsed JSON. */\n async delete(path: string, opts?: RequestOpts): Promise<unknown> {\n return this.requestWithRetry('DELETE', path, opts);\n }\n\n /** Send a PUT request and return parsed JSON. */\n async put(path: string, opts?: RequestOpts): Promise<unknown> {\n return this.requestWithRetry('PUT', path, opts);\n }\n\n /**\n * Send a POST request and return the raw Response for SSE streaming.\n * Does NOT parse the response body.\n */\n async stream(path: string, opts?: RequestOpts): Promise<Response> {\n return this.requestWithRetry('POST', path, opts, true) as Promise<Response>;\n }\n\n /**\n * Send a GET request and return the raw Response for SSE streaming.\n * Does NOT parse the response body. Used by PTY stream consumers.\n */\n async streamGet(path: string, opts?: RequestOpts): Promise<Response> {\n return this.requestWithRetry('GET', path, opts, true) as Promise<Response>;\n }\n\n /**\n * Abort all in-flight requests and release resources.\n *\n * Since 1.1.1 the SDK maintains a process-wide shared ApiClient cache\n * for hot class-method paths (Sandbox.create, Volumes.*, Template.*).\n * Calling `close()` on a shared instance aborts its AbortController,\n * which would cancel any concurrent in-flight call. Prefer\n * `resetSharedClients()` if you want to tear down every cached client.\n */\n close(): void {\n this.abortController.abort();\n }\n\n private buildUrl(path: string, params?: Record<string, string>): string {\n const base = this.config.apiUrl.replace(/\\/$/, '');\n const url = new URL(`${base}${path}`);\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n url.searchParams.set(key, value);\n }\n }\n return url.toString();\n }\n\n private buildHeaders(extra?: Record<string, string>): Record<string, string> {\n const headers: Record<string, string> = {};\n if (this.config.apiKey) {\n headers['Authorization'] = `Bearer ${this.config.apiKey}`;\n }\n if (extra) {\n Object.assign(headers, extra);\n }\n return headers;\n }\n\n private async requestWithRetry(\n method: string,\n path: string,\n opts?: RequestOpts,\n rawResponse?: boolean,\n ): Promise<unknown> {\n const url = this.buildUrl(path, opts?.params);\n const headers = this.buildHeaders(opts?.headers);\n\n let fetchBody: string | Uint8Array | undefined;\n if (opts?.body !== undefined) {\n fetchBody = opts.body;\n } else if (opts?.json !== undefined) {\n fetchBody = JSON.stringify(opts.json);\n headers['Content-Type'] = 'application/json';\n }\n\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt < this.maxRetries; attempt++) {\n try {\n // Compose abort signals: global close() + per-request timeout\n const signals: AbortSignal[] = [this.abortController.signal];\n const timeoutMs = opts?.timeout ?? this.config.requestTimeout;\n if (timeoutMs !== undefined) {\n signals.push(AbortSignal.timeout(timeoutMs));\n }\n const signal = signals.length === 1\n ? signals[0]\n : AbortSignal.any(signals);\n\n // Pull the undici dispatcher. Once resolved (eagerly at module load),\n // read it from the synchronous cache to avoid an await/microtask yield\n // on every request — only the very first call (pre-resolution) awaits.\n const dispatcher = _dispatcherResolved ? _resolvedDispatcher : await getDispatcher();\n const fetchOpts: any = {\n method,\n headers,\n body: fetchBody,\n signal,\n };\n if (dispatcher) fetchOpts.dispatcher = dispatcher;\n const response = await fetch(url, fetchOpts);\n\n // 5xx: retry if we have attempts left\n if (response.status >= 500 && attempt < this.maxRetries - 1) {\n await this.delay(attempt);\n continue;\n }\n\n // Non-success: map to error\n if (!response.ok) {\n throw await this.buildError(response);\n }\n\n // Success: return raw or parsed\n if (rawResponse) {\n return response;\n }\n return this.parseResponseBody(response);\n } catch (error) {\n // If it's already one of our mapped errors (4xx), don't retry\n if (error instanceof SandboxError) {\n throw error;\n }\n\n // If the client was closed, don't retry — fail immediately\n if (this.abortController.signal.aborted) {\n throw new SandboxError('Client has been closed');\n }\n\n lastError = error as Error;\n\n // Network error: retry if attempts left\n if (attempt < this.maxRetries - 1) {\n await this.delay(attempt);\n continue;\n }\n }\n }\n\n throw new SandboxError(\n `Request failed after ${this.maxRetries} retries: ${lastError?.message ?? 'unknown error'}`,\n );\n }\n\n private async buildError(response: Response): Promise<SandboxError> {\n let message: string;\n try {\n const body = await response.json() as Record<string, unknown>;\n const bodyMsg = body.message ?? body.error ?? response.statusText;\n message = `HTTP ${response.status}: ${bodyMsg}`;\n } catch {\n message = `HTTP ${response.status}: ${response.statusText}`;\n }\n\n const ErrorClass = STATUS_ERROR_MAP[response.status];\n if (ErrorClass) {\n return new ErrorClass(message);\n }\n return new SandboxError(message);\n }\n\n private async parseResponseBody(response: Response): Promise<unknown> {\n const contentLength = response.headers.get('content-length');\n if (response.status === 204 || contentLength === '0') {\n return null;\n }\n // NOTE: kept as text()+JSON.parse rather than response.json(). The /files\n // read endpoint returns RAW file contents (non-JSON), and callers expect\n // the raw string back. response.json() can't support that — it returns\n // null on non-JSON and has already consumed the single-read body stream, so\n // a text() fallback is impossible. The ~1-2ms saved isn't worth breaking\n // raw-body reads or depending on Content-Type sniffing.\n const text = await response.text();\n if (!text) {\n return null;\n }\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n }\n\n /**\n * Exponential backoff with jitter: delay * 2^attempt * (0.5 + random * 0.5)\n */\n private async delay(attempt: number): Promise<void> {\n if (this.retryDelay <= 0) return;\n const base = this.retryDelay * Math.pow(2, attempt);\n const jitter = 0.5 + Math.random() * 0.5;\n const ms = base * jitter * 1000; // retryDelay is in seconds\n await new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n\n// ---------------------------------------------------------------------------\n// Process-wide ApiClient cache.\n//\n// Under Node, we also install a module-level high-concurrency undici\n// dispatcher (see getDispatcher() above) so burst workloads fan out\n// without hitting undici's default 10-connection-per-origin cap. The\n// shared ApiClient amortizes AbortController creation across class-method\n// calls and keeps caller-level semantics symmetric with the Python SDK's\n// get_shared_client().\n// ---------------------------------------------------------------------------\n\nconst _sharedClients = new Map<string, ApiClient>();\n\nfunction sharedKey(config: ConnectionConfig): string {\n return [config.apiKey ?? '', config.apiUrl, config.requestTimeout ?? ''].join('|');\n}\n\nexport function getSharedClient(config: ConnectionConfig): ApiClient {\n const key = sharedKey(config);\n let client = _sharedClients.get(key);\n if (!client) {\n client = new ApiClient(config);\n _sharedClients.set(key, client);\n }\n return client;\n}\n\nexport function resetSharedClients(): void {\n for (const client of _sharedClients.values()) {\n try {\n client.close();\n } catch {\n /* noop */\n }\n }\n _sharedClients.clear();\n}\n","import { InvalidArgumentError } from '../errors.js';\n\n/** CIDR for all traffic. */\nexport const ALL_TRAFFIC = '0.0.0.0/0';\n\n/** Network configuration options for a sandbox. */\nexport interface SandboxNetworkOpts {\n allowOut: string[];\n denyOut: string[];\n allowPublicTraffic: boolean;\n maskRequestHost?: string;\n}\n\nconst IPV4_RE = /^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/;\nconst CIDR_RE = /^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\/(\\d{1,2})$/;\nconst DOMAIN_RE = /^(\\*\\.)?[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*$/;\n\nfunction isValidIPv4(ip: string): boolean {\n const match = IPV4_RE.exec(ip);\n if (!match) return false;\n for (let i = 1; i <= 4; i++) {\n const octet = parseInt(match[i], 10);\n if (octet < 0 || octet > 255) return false;\n }\n return true;\n}\n\nfunction isValidCIDR(cidr: string): boolean {\n const match = CIDR_RE.exec(cidr);\n if (!match) return false;\n for (let i = 1; i <= 4; i++) {\n const octet = parseInt(match[i], 10);\n if (octet < 0 || octet > 255) return false;\n }\n const prefix = parseInt(match[5], 10);\n return prefix >= 0 && prefix <= 32;\n}\n\n/**\n * Validate a network entry. Returns the normalized entry string.\n * Accepts IPv4 addresses, CIDR notation, and optionally domain names.\n * Throws InvalidArgumentError on invalid input.\n */\nexport function validateNetworkEntry(\n entry: string,\n opts?: { allowDomains?: boolean },\n): string {\n const trimmed = entry.trim();\n if (!trimmed) {\n throw new InvalidArgumentError('Network entry cannot be empty');\n }\n\n if (isValidIPv4(trimmed)) {\n return trimmed;\n }\n\n if (isValidCIDR(trimmed)) {\n return trimmed;\n }\n\n if (opts?.allowDomains && DOMAIN_RE.test(trimmed)) {\n return trimmed;\n }\n\n throw new InvalidArgumentError(\n `Invalid network entry: \"${trimmed}\". Expected a valid IPv4 address, CIDR block${opts?.allowDomains ? ', or domain name' : ''}`,\n );\n}\n\n/**\n * Check if a hostname matches a domain pattern.\n * Supports exact match and wildcard patterns like `*.example.com`.\n */\nexport function domainMatches(pattern: string, hostname: string): boolean {\n const p = pattern.toLowerCase();\n const h = hostname.toLowerCase();\n\n if (p === h) return true;\n\n if (p.startsWith('*.')) {\n const suffix = p.slice(2);\n // Match the suffix itself (e.g., *.example.com matches example.com)\n if (h === suffix) return true;\n // Match subdomains (e.g., *.example.com matches foo.example.com)\n if (h.endsWith('.' + suffix)) return true;\n }\n\n return false;\n}\n","import { InvalidArgumentError } from '../errors.js';\n\n/** Types of PII that can be detected. */\nexport enum PIIType {\n SSN = 'ssn',\n CreditCard = 'credit_card',\n Email = 'email',\n Phone = 'phone',\n PersonName = 'person_name',\n APIKey = 'api_key',\n Address = 'address',\n IPAddress = 'ip_address',\n}\n\n/** Actions to take when PII is detected. */\nexport enum RedactionAction {\n Redact = 'redact',\n Block = 'block',\n LogOnly = 'log_only',\n}\n\nconst VALID_PII_TYPES = new Set(Object.values(PIIType));\nconst VALID_REDACTION_ACTIONS = new Set(Object.values(RedactionAction));\n\n/** Configuration for PII detection and redaction. */\nexport interface PIIConfig {\n enabled: boolean;\n types: string[];\n action: string;\n rehydrateResponse: boolean;\n /** Optional domain allowlist; when undefined, applies to all domains. */\n domains?: string[];\n}\n\n/**\n * Create a PIIConfig with defaults and validation.\n */\nexport function createPIIConfig(opts?: Partial<PIIConfig>): PIIConfig {\n const config: PIIConfig = {\n enabled: opts?.enabled ?? false,\n types: opts?.types ?? Object.values(PIIType),\n action: opts?.action ?? RedactionAction.Redact,\n rehydrateResponse: opts?.rehydrateResponse ?? true,\n domains: opts?.domains,\n };\n\n for (const t of config.types) {\n if (!VALID_PII_TYPES.has(t as PIIType)) {\n throw new InvalidArgumentError(`Invalid PII type: \"${t}\". Valid types: ${[...VALID_PII_TYPES].join(', ')}`);\n }\n }\n\n if (!VALID_REDACTION_ACTIONS.has(config.action as RedactionAction)) {\n throw new InvalidArgumentError(\n `Invalid redaction action: \"${config.action}\". Valid actions: ${[...VALID_REDACTION_ACTIONS].join(', ')}`,\n );\n }\n\n return config;\n}\n\n/** Parse raw JSON data into PIIConfig. */\nexport function parsePIIConfig(data: Record<string, any>): PIIConfig {\n return {\n enabled: data.enabled ?? false,\n types: data.types ?? Object.values(PIIType),\n action: data.action ?? RedactionAction.Redact,\n rehydrateResponse: data.rehydrate_response ?? data.rehydrateResponse ?? true,\n domains: data.domains,\n };\n}\n","import { InvalidArgumentError } from '../errors.js';\n\n/** Sensitivity levels for injection detection. */\nexport enum InjectionSensitivity {\n Low = 'low',\n Medium = 'medium',\n High = 'high',\n}\n\n/** Actions to take when injection is detected. */\nexport enum InjectionAction {\n Block = 'block',\n LogOnly = 'log_only',\n}\n\nconst VALID_SENSITIVITIES = new Set(Object.values(InjectionSensitivity));\nconst VALID_ACTIONS = new Set(Object.values(InjectionAction));\n\n/**\n * Tier-2 Gemma LLM-judge config. Layered on top of the Tier-1 classifier: the\n * judge adjudicates the classifier's flags with session context, removing false\n * positives and catching indirect (cross-domain / multi-turn) injection.\n * Omitted → classifier only.\n */\nexport interface InjectionJudgeConfig {\n enabled: boolean;\n /** Run the judge on every egress, not just classifier flags (costlier). */\n always?: boolean;\n /**\n * Natural-language description of what this agent may do; the judge uses it to\n * tell task-aligned requests from injection-induced deviations.\n */\n policy?: string;\n}\n\n/** Configuration for injection defense. */\nexport interface InjectionDefenseConfig {\n enabled: boolean;\n sensitivity: string;\n action: string;\n /** Detection threshold (0.0–1.0). Defaults to 0.8. */\n threshold: number;\n /** Optional domain allowlist; when undefined, applies to all domains. */\n domains?: string[];\n /** Optional Tier-2 LLM judge. */\n judge?: InjectionJudgeConfig;\n /**\n * Selects a predefined detection posture for the sandbox.\n * Valid values: \"strict\", \"balanced\", \"permissive\", \"agentic-tool\",\n * \"data-egress-sensitive\". Omit or set to undefined to use the server default.\n * Serialized to JSON key \"injection_mode\".\n */\n injectionMode?: string;\n}\n\n/**\n * Create an InjectionDefenseConfig with defaults and validation.\n */\nexport function createInjectionDefenseConfig(\n opts?: Partial<InjectionDefenseConfig>,\n): InjectionDefenseConfig {\n const config: InjectionDefenseConfig = {\n enabled: opts?.enabled ?? false,\n sensitivity: opts?.sensitivity ?? InjectionSensitivity.Medium,\n action: opts?.action ?? InjectionAction.LogOnly,\n threshold: opts?.threshold ?? 0.8,\n domains: opts?.domains,\n judge: opts?.judge,\n injectionMode: opts?.injectionMode,\n };\n\n if (!VALID_SENSITIVITIES.has(config.sensitivity as InjectionSensitivity)) {\n throw new InvalidArgumentError(\n `Invalid injection sensitivity: \"${config.sensitivity}\". Valid values: ${[...VALID_SENSITIVITIES].join(', ')}`,\n );\n }\n\n if (!VALID_ACTIONS.has(config.action as InjectionAction)) {\n throw new InvalidArgumentError(\n `Invalid injection action: \"${config.action}\". Valid actions: ${[...VALID_ACTIONS].join(', ')}`,\n );\n }\n\n if (!Number.isFinite(config.threshold) || config.threshold < 0 || config.threshold > 1) {\n throw new InvalidArgumentError(\n `Invalid injection threshold: ${config.threshold}. Must be a finite number between 0.0 and 1.0.`,\n );\n }\n\n return config;\n}\n\n/** Parse raw JSON data into InjectionDefenseConfig. */\nexport function parseInjectionDefenseConfig(data: Record<string, any>): InjectionDefenseConfig {\n return {\n enabled: data.enabled ?? false,\n sensitivity: data.sensitivity ?? InjectionSensitivity.Medium,\n action: data.action ?? InjectionAction.LogOnly,\n threshold: data.threshold ?? 0.8,\n domains: data.domains,\n judge: data.judge\n ? { enabled: data.judge.enabled ?? false, always: data.judge.always, policy: data.judge.policy }\n : undefined,\n injectionMode: data.injection_mode ?? data.injectionMode,\n };\n}\n","/**\n * Toggle for per-sandbox audit logging.\n *\n * When enabled, Declaw records lifecycle, network, command, filesystem,\n * snapshot, and security events. Set `enabled: false` to suppress all\n * gated categories; only lifecycle and admin events are still recorded.\n *\n * Retention is a platform-wide setting (global 7-day default), not a\n * per-sandbox knob. Body logging is not user-configurable today.\n */\nexport interface AuditConfig {\n enabled: boolean;\n}\n\n/** Create an AuditConfig with defaults (enabled=true). */\nexport function createAuditConfig(opts?: Partial<AuditConfig>): AuditConfig {\n return {\n enabled: opts?.enabled ?? true,\n };\n}\n\n/** Parse raw JSON data into AuditConfig. Defaults to enabled=true when the field is absent. */\nexport function parseAuditConfig(data: Record<string, any>): AuditConfig {\n return {\n enabled: data.enabled ?? true,\n };\n}\n\n/** A single audit log entry. */\nexport interface AuditEntry {\n timestamp: Date;\n method: string;\n url: string;\n statusCode: number;\n piiRedactions: number;\n injectionBlocks: number;\n transformationsApplied: number;\n direction: string;\n}\n\n/** Parse raw JSON data into an AuditEntry. */\nexport function parseAuditEntry(data: Record<string, any>): AuditEntry {\n return {\n timestamp: new Date(data.timestamp),\n method: data.method ?? '',\n url: data.url ?? '',\n statusCode: data.status_code ?? data.statusCode ?? 0,\n piiRedactions: data.pii_redactions ?? data.piiRedactions ?? 0,\n injectionBlocks: data.injection_blocks ?? data.injectionBlocks ?? 0,\n transformationsApplied: data.transformations_applied ?? data.transformationsApplied ?? 0,\n direction: data.direction ?? '',\n };\n}\n","/** Default patterns for masking sensitive environment variables. */\nexport const DEFAULT_MASK_PATTERNS = [\n '*_KEY',\n '*_SECRET',\n '*_TOKEN',\n '*_PASSWORD',\n '*_CREDENTIALS',\n 'API_KEY',\n 'SECRET_KEY',\n];\n\n/** Configuration for environment variable security. */\nexport interface EnvSecurityConfig {\n maskPatterns: string[];\n autoMaskInAudit: boolean;\n}\n\n/**\n * Create an EnvSecurityConfig with defaults.\n */\nexport function createEnvSecurityConfig(opts?: Partial<EnvSecurityConfig>): EnvSecurityConfig {\n return {\n maskPatterns: opts?.maskPatterns ?? [...DEFAULT_MASK_PATTERNS],\n autoMaskInAudit: opts?.autoMaskInAudit ?? true,\n };\n}\n\n/**\n * Parse raw JSON data into an EnvSecurityConfig.\n * Handles both snake_case (from API/serialization) and camelCase keys.\n */\nexport function parseEnvSecurityConfig(data: Record<string, any>): EnvSecurityConfig {\n return {\n maskPatterns: data.mask_patterns ?? data.maskPatterns ?? [...DEFAULT_MASK_PATTERNS],\n autoMaskInAudit: data.auto_mask_in_audit ?? data.autoMaskInAudit ?? true,\n };\n}\n\n/**\n * Check if an environment variable key matches any of the sensitive patterns.\n * Uses fnmatch-style glob matching where `*` matches any sequence of characters.\n */\nexport function isSensitive(key: string, patterns: string[]): boolean {\n const upper = key.toUpperCase();\n for (const pattern of patterns) {\n if (globMatch(pattern.toUpperCase(), upper)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Simple fnmatch-style glob matching.\n * Only supports `*` wildcard (matches any sequence of characters).\n */\nfunction globMatch(pattern: string, text: string): boolean {\n const parts = pattern.split('*');\n if (parts.length === 1) {\n return pattern === text;\n }\n\n let pos = 0;\n\n // First part must match at the start\n if (parts[0] !== '') {\n if (!text.startsWith(parts[0])) return false;\n pos = parts[0].length;\n }\n\n // Last part must match at the end\n const lastPart = parts[parts.length - 1];\n if (lastPart !== '') {\n if (!text.endsWith(lastPart)) return false;\n }\n\n // Middle parts must appear in order\n for (let i = 1; i < parts.length - 1; i++) {\n const idx = text.indexOf(parts[i], pos);\n if (idx === -1) return false;\n pos = idx + parts[i].length;\n }\n\n // Make sure we haven't gone past where the last part starts\n if (lastPart !== '') {\n const lastStart = text.length - lastPart.length;\n if (pos > lastStart) return false;\n }\n\n return true;\n}\n\n/** A secure environment variable. */\nexport interface SecureEnvVar {\n key: string;\n value: string;\n secret: boolean;\n}\n","import type { SandboxNetworkOpts } from '../sandbox/network.js';\n\n/** Network policy for a sandbox security configuration. */\nexport interface NetworkPolicy {\n allowOut: string[];\n denyOut: string[];\n allowPublicTraffic: boolean;\n maskRequestHost?: string;\n}\n\n/**\n * Create a NetworkPolicy with defaults.\n */\nexport function createNetworkPolicy(opts?: Partial<NetworkPolicy>): NetworkPolicy {\n return {\n allowOut: opts?.allowOut ?? [],\n denyOut: opts?.denyOut ?? [],\n allowPublicTraffic: opts?.allowPublicTraffic ?? true,\n maskRequestHost: opts?.maskRequestHost,\n };\n}\n\n/**\n * Parse raw JSON data into a NetworkPolicy.\n * Handles both snake_case (from API/serialization) and camelCase keys.\n */\nexport function parseNetworkPolicy(data: Record<string, any>): NetworkPolicy {\n return {\n allowOut: data.allow_out ?? data.allowOut ?? [],\n denyOut: data.deny_out ?? data.denyOut ?? [],\n allowPublicTraffic: data.allow_public_traffic ?? data.allowPublicTraffic ?? true,\n maskRequestHost: data.mask_request_host ?? data.maskRequestHost,\n };\n}\n\n/**\n * Serialize a NetworkPolicy to a JSON-friendly object.\n * Omits empty allow/deny lists and only emits allow_public_traffic when false,\n * matching the Python SDK's to_dict behavior.\n */\nexport function networkPolicyToJSON(policy: NetworkPolicy): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n if (policy.allowOut.length > 0) {\n result.allow_out = policy.allowOut;\n }\n if (policy.denyOut.length > 0) {\n result.deny_out = policy.denyOut;\n }\n if (!policy.allowPublicTraffic) {\n result.allow_public_traffic = false;\n }\n if (policy.maskRequestHost !== undefined) {\n result.mask_request_host = policy.maskRequestHost;\n }\n return result;\n}\n\n/**\n * Convert a NetworkPolicy to SandboxNetworkOpts.\n */\nexport function networkPolicyToOpts(policy: NetworkPolicy): SandboxNetworkOpts {\n return {\n allowOut: policy.allowOut,\n denyOut: policy.denyOut,\n allowPublicTraffic: policy.allowPublicTraffic,\n maskRequestHost: policy.maskRequestHost,\n };\n}\n","import { InvalidArgumentError } from '../errors.js';\n\n/** Direction in which a transformation rule applies. */\nexport enum TransformDirection {\n Outbound = 'outbound',\n Inbound = 'inbound',\n Both = 'both',\n}\n\nconst VALID_DIRECTIONS = new Set(Object.values(TransformDirection));\n\n/** A text transformation rule using regex matching. */\nexport interface TransformationRule {\n match: string;\n replace: string;\n direction: string;\n}\n\n/** Maximum allowed length for regex patterns to limit complexity. */\nconst MAX_PATTERN_LENGTH = 1000;\n\n/**\n * Detect regex patterns vulnerable to catastrophic backtracking (ReDoS).\n * Checks for nested quantifiers like (a+)+, (a*)+, (a+)*, etc.\n */\nconst REDOS_PATTERN = /(\\(.*[+*].*\\))[+*]|\\(\\?:[^)]*[+*][^)]*\\)[+*]/;\n\n/**\n * Create a TransformationRule with validation.\n * Validates that `match` is a valid regex, checks for ReDoS-vulnerable patterns,\n * and validates `direction`.\n */\nexport function createTransformationRule(opts: {\n match: string;\n replace: string;\n direction?: string;\n}): TransformationRule {\n if (opts.match.length > MAX_PATTERN_LENGTH) {\n throw new InvalidArgumentError(\n `Regex pattern too long (${opts.match.length} chars, max ${MAX_PATTERN_LENGTH}).`,\n );\n }\n\n // Reject patterns with nested quantifiers (common ReDoS vector)\n if (REDOS_PATTERN.test(opts.match)) {\n throw new InvalidArgumentError(\n `Regex pattern \"${opts.match}\" contains nested quantifiers which may cause catastrophic backtracking (ReDoS). Simplify the pattern.`,\n );\n }\n\n // Validate regex syntax\n try {\n new RegExp(opts.match);\n } catch {\n throw new InvalidArgumentError(`Invalid regex pattern: \"${opts.match}\"`);\n }\n\n const direction = opts.direction ?? TransformDirection.Outbound;\n\n if (!VALID_DIRECTIONS.has(direction as TransformDirection)) {\n throw new InvalidArgumentError(\n `Invalid transform direction: \"${direction}\". Valid values: ${[...VALID_DIRECTIONS].join(', ')}`,\n );\n }\n\n return {\n match: opts.match,\n replace: opts.replace,\n direction,\n };\n}\n\n/**\n * Parse raw JSON data into a TransformationRule, validating regex + direction.\n * Matches Python's TransformationRule.from_dict, which runs the same checks as construction.\n */\nexport function parseTransformationRule(data: Record<string, unknown>): TransformationRule {\n if (typeof data.match !== 'string' || typeof data.replace !== 'string') {\n throw new InvalidArgumentError(\n 'TransformationRule requires string \"match\" and \"replace\" fields.',\n );\n }\n return createTransformationRule({\n match: data.match,\n replace: data.replace,\n direction: (data.direction as string | undefined) ?? TransformDirection.Outbound,\n });\n}\n\n/**\n * Apply a transformation rule to text.\n * Uses the rule's `match` as a global regex and replaces with `replace`.\n */\nexport function applyTransformation(rule: TransformationRule, text: string): string {\n const regex = new RegExp(rule.match, 'g');\n return text.replace(regex, rule.replace);\n}\n","import { InvalidArgumentError } from '../errors.js';\n\nconst VALID_ACTIONS = new Set(['block', 'log_only']);\n\n/** Configuration for toxicity detection. */\nexport interface ToxicityConfig {\n enabled: boolean;\n threshold: number;\n action: 'block' | 'log_only';\n /** Optional domain allowlist; undefined = all domains. */\n domains?: string[];\n}\n\n/**\n * Create a ToxicityConfig with defaults and validation.\n */\nexport function createToxicityConfig(opts?: Partial<ToxicityConfig>): ToxicityConfig {\n const config: ToxicityConfig = {\n enabled: opts?.enabled ?? false,\n threshold: opts?.threshold ?? 0.9,\n action: opts?.action ?? 'block',\n domains: opts?.domains,\n };\n\n if (!Number.isFinite(config.threshold) || config.threshold < 0 || config.threshold > 1) {\n throw new InvalidArgumentError(\n `Invalid toxicity threshold: ${config.threshold}. Must be a finite number between 0 and 1.`,\n );\n }\n\n if (!VALID_ACTIONS.has(config.action)) {\n throw new InvalidArgumentError(\n `Invalid toxicity action: \"${config.action}\". Valid actions: ${[...VALID_ACTIONS].join(', ')}`,\n );\n }\n\n return config;\n}\n\n/** Parse raw JSON data into ToxicityConfig. */\nexport function parseToxicityConfig(data: Record<string, unknown>): ToxicityConfig {\n return {\n enabled: (data.enabled as boolean) ?? false,\n threshold: (data.threshold as number) ?? 0.9,\n action: (data.action as 'block' | 'log_only') ?? 'block',\n domains: data.domains as string[] | undefined,\n };\n}\n\n/** Serialize a ToxicityConfig to a JSON-friendly object. */\nexport function toxicityConfigToJSON(config: ToxicityConfig): Record<string, unknown> {\n const result: Record<string, unknown> = {\n enabled: config.enabled,\n threshold: config.threshold,\n action: config.action,\n };\n if (config.domains !== undefined) {\n result.domains = config.domains;\n }\n return result;\n}\n","import { InvalidArgumentError } from '../errors.js';\n\nconst VALID_ACTIONS = new Set(['block', 'log_only']);\n\n/** Configuration for code security scanning. */\nexport interface CodeSecurityConfig {\n enabled: boolean;\n threshold: number;\n /** Optional languages to exclude from detection; undefined = scan all languages. */\n excludedLanguages?: string[];\n action: 'block' | 'log_only';\n /** Optional domain allowlist; undefined = all domains. */\n domains?: string[];\n}\n\n/**\n * Create a CodeSecurityConfig with defaults and validation.\n */\nexport function createCodeSecurityConfig(opts?: Partial<CodeSecurityConfig>): CodeSecurityConfig {\n const config: CodeSecurityConfig = {\n enabled: opts?.enabled ?? false,\n threshold: opts?.threshold ?? 0.6,\n excludedLanguages: opts?.excludedLanguages,\n action: opts?.action ?? 'log_only',\n domains: opts?.domains,\n };\n\n if (!Number.isFinite(config.threshold) || config.threshold < 0 || config.threshold > 1) {\n throw new InvalidArgumentError(\n `Invalid code security threshold: ${config.threshold}. Must be a finite number between 0 and 1.`,\n );\n }\n\n if (!VALID_ACTIONS.has(config.action)) {\n throw new InvalidArgumentError(\n `Invalid code security action: \"${config.action}\". Valid actions: ${[...VALID_ACTIONS].join(', ')}`,\n );\n }\n\n return config;\n}\n\n/** Parse raw JSON data into CodeSecurityConfig. */\nexport function parseCodeSecurityConfig(data: Record<string, unknown>): CodeSecurityConfig {\n return {\n enabled: (data.enabled as boolean) ?? false,\n threshold: (data.threshold as number) ?? 0.6,\n excludedLanguages:\n (data.excluded_languages as string[] | undefined) ??\n (data.excludedLanguages as string[] | undefined),\n action: (data.action as 'block' | 'log_only') ?? 'log_only',\n domains: data.domains as string[] | undefined,\n };\n}\n\n/** Serialize a CodeSecurityConfig to a JSON-friendly object. */\nexport function codeSecurityConfigToJSON(config: CodeSecurityConfig): Record<string, unknown> {\n const result: Record<string, unknown> = {\n enabled: config.enabled,\n threshold: config.threshold,\n action: config.action,\n };\n if (config.excludedLanguages !== undefined) {\n result.excluded_languages = config.excludedLanguages;\n }\n if (config.domains !== undefined) {\n result.domains = config.domains;\n }\n return result;\n}\n","import { InvalidArgumentError } from '../errors.js';\n\nconst VALID_ACTIONS = new Set(['block', 'strip', 'log_only']);\n\n/** Configuration for invisible text detection. */\nexport interface InvisibleTextConfig {\n enabled: boolean;\n action: 'block' | 'strip' | 'log_only';\n /** Optional domain allowlist; undefined = all domains. */\n domains?: string[];\n}\n\n/**\n * Create an InvisibleTextConfig with defaults and validation.\n */\nexport function createInvisibleTextConfig(\n opts?: Partial<InvisibleTextConfig>,\n): InvisibleTextConfig {\n const config: InvisibleTextConfig = {\n enabled: opts?.enabled ?? false,\n action: opts?.action ?? 'strip',\n domains: opts?.domains,\n };\n\n if (!VALID_ACTIONS.has(config.action)) {\n throw new InvalidArgumentError(\n `Invalid invisible text action: \"${config.action}\". Valid actions: ${[...VALID_ACTIONS].join(', ')}`,\n );\n }\n\n return config;\n}\n\n/** Parse raw JSON data into InvisibleTextConfig. */\nexport function parseInvisibleTextConfig(data: Record<string, unknown>): InvisibleTextConfig {\n return {\n enabled: (data.enabled as boolean) ?? false,\n action: (data.action as 'block' | 'strip' | 'log_only') ?? 'strip',\n domains: data.domains as string[] | undefined,\n };\n}\n\n/** Serialize an InvisibleTextConfig to a JSON-friendly object. */\nexport function invisibleTextConfigToJSON(config: InvisibleTextConfig): Record<string, unknown> {\n const result: Record<string, unknown> = {\n enabled: config.enabled,\n action: config.action,\n };\n if (config.domains !== undefined) {\n result.domains = config.domains;\n }\n return result;\n}\n","/**\n * Custom OPA policy configuration for per-sandbox policy overrides.\n */\n\nexport interface CustomPolicyConfig {\n /** Enable custom policy evaluation for this sandbox. */\n enabled: boolean;\n\n /**\n * Customer-supplied Rego code appended to platform defaults.\n *\n * Example:\n * deny_command contains msg if {\n * input.action.command in {\"rm\", \"dd\"}\n * msg := \"dangerous command blocked\"\n * }\n */\n inlineRego?: string;\n\n /**\n * Additional independent Rego modules, each with its own `package` declaration.\n *\n * Use when your policy spans multiple packages (e.g. a `cmd` package and a\n * `network` package) that need to cross-reference each other. Each entry is\n * compiled as a separate OPA module alongside `inlineRego`.\n */\n inlineModules?: string[];\n\n /** Future: reference to a bundled policy (URL, policy ID, version hash). */\n policyRef?: string;\n\n /**\n * When the evaluator is unreachable, deny (true) or allow (false).\n *\n * Fail-closed (defaultDeny=true) is safer for security gates.\n * Fail-open (defaultDeny=false) is acceptable for advisory scanners.\n */\n defaultDeny?: boolean;\n}\n\n/** Create a CustomPolicyConfig with defaults. */\nexport function createCustomPolicyConfig(\n opts?: Partial<CustomPolicyConfig>\n): CustomPolicyConfig {\n return {\n enabled: opts?.enabled ?? false,\n inlineRego: opts?.inlineRego,\n inlineModules: opts?.inlineModules,\n policyRef: opts?.policyRef,\n defaultDeny: opts?.defaultDeny ?? false,\n };\n}\n\n/** Parse raw JSON data into a CustomPolicyConfig. */\nexport function parseCustomPolicyConfig(\n data: Record<string, any>\n): CustomPolicyConfig {\n return {\n enabled: data.enabled ?? false,\n inlineRego: data.inline_rego ?? data.inlineRego,\n inlineModules: data.inline_modules ?? data.inlineModules,\n policyRef: data.policy_ref ?? data.policyRef,\n defaultDeny: data.default_deny ?? data.defaultDeny ?? false,\n };\n}\n\n/** Convert CustomPolicyConfig to JSON. */\nexport function customPolicyConfigToJSON(config: CustomPolicyConfig): Record<string, any> {\n return {\n enabled: config.enabled,\n inline_rego: config.inlineRego,\n inline_modules: config.inlineModules,\n policy_ref: config.policyRef,\n default_deny: config.defaultDeny,\n };\n}\n","/** Configuration for the content.scan OPA gate (model/endpoint allowlist).\n *\n * Opts a sandbox into content-gate enforcement without requiring an ML\n * scanner. {@link enabled} defaults to false (gate off). {@link domains}\n * is an optional list of hosts to intercept; omit or leave undefined to\n * intercept none.\n */\nexport interface ContentGateConfig {\n enabled: boolean;\n /** Optional list of hosts to intercept. Undefined = none. */\n domains?: string[];\n}\n\n/**\n * Create a ContentGateConfig with defaults.\n */\nexport function createContentGateConfig(opts?: Partial<ContentGateConfig>): ContentGateConfig {\n return {\n enabled: opts?.enabled ?? false,\n domains: opts?.domains,\n };\n}\n\n/** Parse raw JSON data into ContentGateConfig. */\nexport function parseContentGateConfig(data: Record<string, unknown>): ContentGateConfig {\n return {\n enabled: (data.enabled as boolean) ?? false,\n domains: data.domains as string[] | undefined,\n };\n}\n\n/** Serialize a ContentGateConfig to a JSON-friendly object. */\nexport function contentGateConfigToJSON(config: ContentGateConfig): Record<string, unknown> {\n const result: Record<string, unknown> = {\n enabled: config.enabled,\n };\n if (config.domains !== undefined) {\n result.domains = config.domains;\n }\n return result;\n}\n","import type { PIIConfig } from './pii.js';\nimport type { InjectionDefenseConfig } from './injection.js';\nimport type { TransformationRule } from './transformations.js';\nimport type { NetworkPolicy } from './networkPolicy.js';\nimport type { AuditConfig } from './audit.js';\nimport type { EnvSecurityConfig } from './env.js';\nimport type { ToxicityConfig } from './toxicity.js';\nimport type { CodeSecurityConfig } from './codeSecurity.js';\nimport type { InvisibleTextConfig } from './invisibleText.js';\nimport type { CustomPolicyConfig } from './customPolicy.js';\nimport type { ContentGateConfig } from './contentGate.js';\n\nimport { createPIIConfig, parsePIIConfig } from './pii.js';\nimport { createInjectionDefenseConfig, parseInjectionDefenseConfig } from './injection.js';\nimport { createAuditConfig, parseAuditConfig } from './audit.js';\nimport { createEnvSecurityConfig, parseEnvSecurityConfig } from './env.js';\nimport { parseNetworkPolicy, networkPolicyToJSON } from './networkPolicy.js';\nimport { parseTransformationRule } from './transformations.js';\nimport { parseToxicityConfig, toxicityConfigToJSON } from './toxicity.js';\nimport { parseCodeSecurityConfig, codeSecurityConfigToJSON } from './codeSecurity.js';\nimport { parseInvisibleTextConfig, invisibleTextConfigToJSON } from './invisibleText.js';\nimport { createCustomPolicyConfig, parseCustomPolicyConfig, customPolicyConfigToJSON } from './customPolicy.js';\nimport { parseContentGateConfig, contentGateConfigToJSON } from './contentGate.js';\n\n/** The top-level security policy for a sandbox. */\nexport interface SecurityPolicy {\n pii: PIIConfig;\n injectionDefense: boolean | InjectionDefenseConfig;\n transformations: TransformationRule[];\n network?: NetworkPolicy;\n audit: boolean | AuditConfig;\n envSecurity: EnvSecurityConfig;\n toxicity?: ToxicityConfig;\n codeSecurity?: CodeSecurityConfig;\n invisibleText?: InvisibleTextConfig;\n contentGate?: ContentGateConfig;\n customPolicy?: CustomPolicyConfig;\n}\n\n/**\n * Create a SecurityPolicy with defaults.\n */\nexport function createSecurityPolicy(opts?: Partial<SecurityPolicy>): SecurityPolicy {\n return {\n pii: opts?.pii ?? createPIIConfig(),\n injectionDefense: opts?.injectionDefense ?? false,\n transformations: opts?.transformations ?? [],\n network: opts?.network,\n audit: opts?.audit ?? true,\n envSecurity: opts?.envSecurity ?? createEnvSecurityConfig(),\n toxicity: opts?.toxicity,\n codeSecurity: opts?.codeSecurity,\n invisibleText: opts?.invisibleText,\n contentGate: opts?.contentGate,\n customPolicy: opts?.customPolicy,\n };\n}\n\n/** Options for {@link fullInjectionDefensePolicy}. */\nexport interface FullInjectionDefenseOptions {\n /** Posture: \"strict\" | \"balanced\" (default) | \"permissive\" | \"agentic-tool\" | \"data-egress-sensitive\". */\n mode?: string;\n /** Natural-language description of what the agent may do; the judge uses it to tell task-aligned egress from injection. */\n agentPolicy?: string;\n /** \"block\" (default) enforces; \"log_only\" audits without blocking. */\n action?: string;\n /** Run the judge on EVERY egress (high-assurance, costlier). Default false. */\n alwaysJudge?: boolean;\n /** Optional egress allowlist to scan; omit = all domains. */\n domains?: string[];\n /** Tier-1 classifier confidence threshold (0.0–1.0). Default 0.8. */\n threshold?: number;\n}\n\n/**\n * Enable the ENTIRE prompt-injection cascade in one call — every layer:\n *\n * - Tier-1 ML classifier + Layer-A static signatures + normalization\n * (`injectionDefense.enabled` + `action`)\n * - the predefined posture (`injectionMode`; default \"balanced\")\n * - the Tier-2 Gemma LLM judge (`judge.enabled`) — multi-turn risk, provenance\n * context, and the semantic verdict cache ride along automatically\n * - the OPA prompt-injection governance pack (`customPolicy.policyRef`), which\n * hard-denies known signatures at the gate so the LLM stays the last resort\n *\n * Pass the result as the sandbox's `security` policy.\n *\n * @example\n * const security = fullInjectionDefensePolicy({ agentPolicy: \"Summarize docs; never exfiltrate secrets.\" });\n * const sbx = await Sandbox.create({ template: \"node\", security });\n */\nexport function fullInjectionDefensePolicy(opts?: FullInjectionDefenseOptions): SecurityPolicy {\n return createSecurityPolicy({\n injectionDefense: createInjectionDefenseConfig({\n enabled: true,\n action: opts?.action ?? 'block',\n threshold: opts?.threshold ?? 0.8,\n domains: opts?.domains,\n injectionMode: opts?.mode ?? 'balanced',\n judge: { enabled: true, always: opts?.alwaysJudge ?? false, policy: opts?.agentPolicy ?? '' },\n }),\n customPolicy: createCustomPolicyConfig({\n enabled: true,\n policyRef: 'prompt-injection@v2',\n defaultDeny: false,\n }),\n });\n}\n\n/**\n * Parse raw JSON data into a SecurityPolicy.\n */\nexport function parseSecurityPolicy(data: Record<string, any>): SecurityPolicy {\n const injDef = data.injection_defense ?? data.injectionDefense;\n const auditData = data.audit;\n const customPolicyData = data.custom_policy ?? data.customPolicy;\n const contentGateData = data.content_gate ?? data.contentGate;\n\n return {\n pii: data.pii ? parsePIIConfig(data.pii) : createPIIConfig(),\n injectionDefense:\n typeof injDef === 'boolean'\n ? injDef\n : injDef\n ? parseInjectionDefenseConfig(injDef)\n : false,\n transformations: Array.isArray(data.transformations)\n ? data.transformations.map((t: Record<string, unknown>) => parseTransformationRule(t))\n : [],\n network: data.network ? parseNetworkPolicy(data.network) : undefined,\n audit:\n typeof auditData === 'boolean'\n ? auditData\n : auditData\n ? parseAuditConfig(auditData)\n : true,\n envSecurity: (data.env_security ?? data.envSecurity)\n ? parseEnvSecurityConfig(data.env_security ?? data.envSecurity)\n : createEnvSecurityConfig(),\n toxicity: (data.toxicity)\n ? parseToxicityConfig(data.toxicity as Record<string, unknown>)\n : undefined,\n codeSecurity: (data.code_security ?? data.codeSecurity)\n ? parseCodeSecurityConfig((data.code_security ?? data.codeSecurity) as Record<string, unknown>)\n : undefined,\n invisibleText: (data.invisible_text ?? data.invisibleText)\n ? parseInvisibleTextConfig((data.invisible_text ?? data.invisibleText) as Record<string, unknown>)\n : undefined,\n contentGate: contentGateData\n ? parseContentGateConfig(contentGateData as Record<string, unknown>)\n : undefined,\n customPolicy: customPolicyData\n ? parseCustomPolicyConfig(customPolicyData as Record<string, unknown>)\n : undefined,\n };\n}\n\n/**\n * Serialize a SecurityPolicy to a JSON-friendly object.\n */\nexport function securityPolicyToJSON(policy: SecurityPolicy): Record<string, any> {\n const pii: Record<string, unknown> = {\n enabled: policy.pii.enabled,\n types: policy.pii.types,\n action: policy.pii.action,\n rehydrate_response: policy.pii.rehydrateResponse,\n };\n if (policy.pii.domains !== undefined) {\n pii.domains = policy.pii.domains;\n }\n\n const injDefConfig =\n typeof policy.injectionDefense === 'boolean'\n ? createInjectionDefenseConfig({ enabled: policy.injectionDefense })\n : policy.injectionDefense;\n const injDef: Record<string, unknown> = {\n enabled: injDefConfig.enabled,\n sensitivity: injDefConfig.sensitivity,\n action: injDefConfig.action,\n threshold: injDefConfig.threshold,\n };\n if (injDefConfig.domains !== undefined) {\n injDef.domains = injDefConfig.domains;\n }\n if (injDefConfig.injectionMode !== undefined) {\n injDef.injection_mode = injDefConfig.injectionMode;\n }\n if (injDefConfig.judge !== undefined) {\n const j: Record<string, unknown> = { enabled: injDefConfig.judge.enabled };\n if (injDefConfig.judge.always) j.always = true;\n if (injDefConfig.judge.policy) j.policy = injDefConfig.judge.policy;\n injDef.judge = j;\n }\n\n const auditConfig =\n typeof policy.audit === 'boolean'\n ? createAuditConfig({ enabled: policy.audit })\n : policy.audit;\n const audit: Record<string, unknown> = {\n enabled: auditConfig.enabled,\n };\n\n const envSec: Record<string, unknown> = {\n mask_patterns: policy.envSecurity.maskPatterns,\n auto_mask_in_audit: policy.envSecurity.autoMaskInAudit,\n };\n\n const result: Record<string, any> = {\n pii,\n injection_defense: injDef,\n transformations: policy.transformations,\n audit,\n env_security: envSec,\n };\n if (policy.network) {\n result.network = networkPolicyToJSON(policy.network);\n }\n if (policy.toxicity) {\n result.toxicity = toxicityConfigToJSON(policy.toxicity);\n }\n if (policy.codeSecurity) {\n result.code_security = codeSecurityConfigToJSON(policy.codeSecurity);\n }\n if (policy.invisibleText) {\n result.invisible_text = invisibleTextConfigToJSON(policy.invisibleText);\n }\n if (policy.contentGate) {\n result.content_gate = contentGateConfigToJSON(policy.contentGate);\n }\n if (policy.customPolicy) {\n result.custom_policy = customPolicyConfigToJSON(policy.customPolicy);\n }\n return result;\n}\n\n/**\n * Determine if a security policy requires TLS interception.\n * TLS interception is needed if PII detection is enabled, injection defense is enabled,\n * or there are transformation rules.\n */\nexport function requiresTlsInterception(policy: SecurityPolicy): boolean {\n if (policy.pii.enabled) return true;\n\n if (typeof policy.injectionDefense === 'boolean') {\n if (policy.injectionDefense) return true;\n } else {\n if (policy.injectionDefense.enabled) return true;\n }\n\n if (policy.transformations.length > 0) return true;\n\n if (policy.toxicity?.enabled) return true;\n if (policy.codeSecurity?.enabled) return true;\n if (policy.invisibleText?.enabled) return true;\n\n return false;\n}\n","/** State of a sandbox. */\nexport enum SandboxState {\n Running = 'running',\n Paused = 'paused',\n Creating = 'creating',\n Killed = 'killed',\n}\n\n/** Information about a sandbox. */\nexport interface SandboxInfo {\n sandboxId: string;\n templateId: string;\n name: string;\n metadata: Record<string, string>;\n startedAt?: Date;\n endAt?: Date;\n state: SandboxState;\n}\n\n/** Parse raw JSON data into a SandboxInfo. */\nexport function parseSandboxInfo(data: Record<string, any>): SandboxInfo {\n return {\n sandboxId: data.sandbox_id ?? data.sandboxId ?? '',\n templateId: data.template_id ?? data.templateId ?? '',\n name: data.name ?? '',\n metadata: data.metadata ?? {},\n startedAt: data.started_at || data.startedAt ? new Date(data.started_at ?? data.startedAt) : undefined,\n endAt: data.end_at || data.endAt ? new Date(data.end_at ?? data.endAt) : undefined,\n state: (data.state as SandboxState) ?? SandboxState.Running,\n };\n}\n\n/** Metrics for a sandbox. */\nexport interface SandboxMetrics {\n timestamp: Date;\n cpuUsagePercent: number;\n memoryUsageMb: number;\n diskUsageMb: number;\n}\n\n/** Parse raw JSON data into SandboxMetrics. */\nexport function parseSandboxMetrics(data: Record<string, any>): SandboxMetrics {\n return {\n timestamp: new Date(data.timestamp),\n cpuUsagePercent: data.cpu_usage_percent ?? data.cpuUsagePercent ?? 0,\n memoryUsageMb: data.memory_usage_mb ?? data.memoryUsageMb ?? 0,\n diskUsageMb: data.disk_usage_mb ?? data.diskUsageMb ?? 0,\n };\n}\n\n/** Query filters for listing sandboxes. */\nexport interface SandboxQuery {\n metadata?: Record<string, string>;\n state?: SandboxState[];\n}\n\n/** Lifecycle configuration for a sandbox. */\nexport interface SandboxLifecycle {\n onTimeout: string;\n autoResume: boolean;\n}\n\n/** Parse raw JSON data into SandboxLifecycle. */\nexport function parseSandboxLifecycle(data: Record<string, any>): SandboxLifecycle {\n return {\n onTimeout: data.on_timeout ?? data.onTimeout ?? 'kill',\n autoResume: data.auto_resume ?? data.autoResume ?? false,\n };\n}\n\n/** Information about a snapshot. */\nexport interface SnapshotInfo {\n snapshotId: string;\n sandboxId: string;\n createdAt?: Date;\n}\n\n/** Parse raw JSON data into SnapshotInfo. */\nexport function parseSnapshotInfo(data: Record<string, any>): SnapshotInfo {\n return {\n snapshotId: data.snapshot_id ?? data.snapshotId ?? '',\n sandboxId: data.sandbox_id ?? data.sandboxId ?? '',\n createdAt: data.created_at || data.createdAt ? new Date(data.created_at ?? data.createdAt) : undefined,\n };\n}\n\n/** Source kind for a sandbox snapshot. */\nexport type SnapshotSource = 'periodic' | 'pause' | 'manual';\n\n/**\n * Full metadata for a manual/pause/periodic sandbox snapshot,\n * as returned by POST /sandboxes/:id/snapshot and\n * GET /sandboxes/:id/snapshots.\n */\nexport interface Snapshot {\n snapshotId: string;\n sandboxId: string;\n /** Which lifecycle created the snapshot: periodic, pause, or manual. */\n source: SnapshotSource;\n memBlobKey: string;\n vmstateBlobKey: string;\n memSizeBytes?: number;\n pauseDurationMs?: number;\n createdAt: string;\n}\n\n/** Parse raw JSON data into a Snapshot. */\nexport function parseSnapshot(data: Record<string, any>): Snapshot {\n return {\n snapshotId: data.snapshot_id ?? data.snapshotId ?? '',\n sandboxId: data.sandbox_id ?? data.sandboxId ?? '',\n source: (data.source as SnapshotSource) ?? 'manual',\n memBlobKey: data.mem_blob_key ?? data.memBlobKey ?? '',\n vmstateBlobKey: data.vmstate_blob_key ?? data.vmstateBlobKey ?? '',\n memSizeBytes: data.mem_size_bytes ?? data.memSizeBytes,\n pauseDurationMs: data.pause_duration_ms ?? data.pauseDurationMs,\n createdAt: data.created_at ?? data.createdAt ?? '',\n };\n}\n","/** Result of executing a command. */\nexport interface CommandResult {\n stdout: string;\n stderr: string;\n exitCode: number;\n}\n\n/** Parse raw JSON data into a CommandResult. */\nexport function parseCommandResult(data: Record<string, any>): CommandResult {\n return {\n stdout: data.stdout ?? '',\n stderr: data.stderr ?? '',\n exitCode: data.exit_code ?? data.exitCode ?? 0,\n };\n}\n\n/** Information about a running process. */\nexport interface ProcessInfo {\n pid: number;\n cmd: string;\n isPty: boolean;\n envs: Record<string, string>;\n}\n\n/** Parse raw JSON data into ProcessInfo. */\nexport function parseProcessInfo(data: Record<string, any>): ProcessInfo {\n return {\n pid: data.pid ?? 0,\n cmd: data.cmd ?? '',\n isPty: data.is_pty ?? data.isPty ?? false,\n envs: data.envs ?? {},\n };\n}\n\n/** Dimensions for a PTY. */\nexport interface PtySize {\n cols: number;\n rows: number;\n}\n\n/** Raw PTY output data. */\nexport interface PtyOutput {\n data: Uint8Array;\n}\n\n/** A line of stdout output. */\nexport interface Stdout {\n line: string;\n timestamp?: number;\n}\n\n/** A line of stderr output. */\nexport interface Stderr {\n line: string;\n timestamp?: number;\n}\n","import { ApiClient } from '../../api/client.js';\nimport { CommandExitError } from '../../errors.js';\nimport { parseCommandResult } from './models.js';\nimport type { CommandResult } from './models.js';\n\n/**\n * Options for waiting on a command to complete.\n */\nexport interface CommandWaitOpts {\n /** Callback invoked for each line of stdout. */\n onStdout?: (line: string) => void;\n /** Callback invoked for each line of stderr. */\n onStderr?: (line: string) => void;\n}\n\n/**\n * Handle to a running background command.\n *\n * Returned by `Commands.run()` when `background: true`, or by `Commands.connect()`.\n * Use `wait()` to block until the command finishes, or `kill()` to terminate it.\n */\nexport class CommandHandle {\n private readonly _pid: number;\n private readonly sandboxId: string;\n private readonly client: ApiClient;\n\n constructor(pid: number, sandboxId: string, client: ApiClient) {\n this._pid = pid;\n this.sandboxId = sandboxId;\n this.client = client;\n }\n\n /** The process ID of the running command. */\n get pid(): number {\n return this._pid;\n }\n\n /**\n * Wait for the command to complete and return its result.\n *\n * Sends GET /sandboxes/:id/commands/:pid/wait.\n * If the command exits with a non-zero exit code, throws CommandExitError.\n * Callbacks are invoked line-by-line before any error is thrown.\n */\n async wait(opts?: CommandWaitOpts): Promise<CommandResult> {\n const data = await this.client.get(\n `/sandboxes/${this.sandboxId}/commands/${this._pid}/wait`,\n );\n const result = parseCommandResult(data as Record<string, unknown>);\n\n // Invoke callbacks line-by-line (matching Python SDK's splitlines(keepends=True))\n if (opts?.onStdout && result.stdout) {\n for (const line of splitlines(result.stdout)) {\n opts.onStdout(line);\n }\n }\n if (opts?.onStderr && result.stderr) {\n for (const line of splitlines(result.stderr)) {\n opts.onStderr(line);\n }\n }\n\n // Throw on non-zero exit code\n if (result.exitCode !== 0) {\n throw new CommandExitError(\n `Command exited with code ${result.exitCode}`,\n {\n exitCode: result.exitCode,\n stdout: result.stdout,\n stderr: result.stderr,\n },\n );\n }\n\n return result;\n }\n\n /**\n * Kill the running command.\n *\n * Sends DELETE /sandboxes/:id/commands/:pid.\n * @returns true if the process was killed, false if it was already dead.\n */\n async kill(): Promise<boolean> {\n const data = await this.client.delete(\n `/sandboxes/${this.sandboxId}/commands/${this._pid}`,\n );\n return (data as Record<string, unknown>).killed === true;\n }\n\n /**\n * Disconnect from the command handle.\n *\n * Currently a no-op. Reserved for future WebSocket support.\n */\n disconnect(): void {\n // No-op for now\n }\n}\n\n/**\n * Split text into lines preserving line endings (like Python's splitlines(keepends=True)).\n */\nfunction splitlines(text: string): string[] {\n const lines: string[] = [];\n const re = /[^\\r\\n]*(?:\\r\\n|\\n|\\r|$)/g;\n let match: RegExpExecArray | null;\n while ((match = re.exec(text)) !== null) {\n if (match[0] === '') break;\n lines.push(match[0]);\n }\n return lines;\n}\n","import { ApiClient } from '../../api/client.js';\nimport { parseCommandResult, parseProcessInfo } from './models.js';\nimport type { CommandResult, ProcessInfo } from './models.js';\nimport { CommandHandle } from './commandHandle.js';\nimport { EventSourceParserStream } from 'eventsource-parser/stream';\nimport { SandboxError } from '../../errors.js';\n\n/**\n * Options for running a command in a sandbox.\n */\nexport interface RunOpts {\n /** Run the command in the background. Default: false. */\n background?: boolean;\n /** Environment variables to set for the command. */\n envs?: Record<string, string>;\n /** User to run the command as. Default: 'user'. */\n user?: string;\n /** Working directory for the command. */\n cwd?: string;\n /** Command timeout in seconds. Default: 60. */\n timeout?: number;\n /** Per-request HTTP timeout in milliseconds. */\n requestTimeout?: number;\n /** Callback invoked for each line of stdout (foreground only). */\n onStdout?: (line: string) => void;\n /** Callback invoked for each line of stderr (foreground only). */\n onStderr?: (line: string) => void;\n}\n\n/**\n * Options for running a streaming command in a sandbox.\n */\nexport interface RunStreamOpts {\n /** Environment variables to set for the command. */\n envs?: Record<string, string>;\n /** User to run the command as. Default: 'user'. */\n user?: string;\n /** Working directory for the command. */\n cwd?: string;\n /** Command timeout in seconds. Default: 60. */\n timeout?: number;\n /** Callback invoked for each chunk of stdout as it arrives. */\n onStdout?: (line: string) => void;\n /** Callback invoked for each chunk of stderr as it arrives. */\n onStderr?: (line: string) => void;\n}\n\n/**\n * Manage commands in a sandbox.\n *\n * Provides methods to run, list, kill, and interact with commands\n * running inside a sandbox.\n */\nexport class Commands {\n private readonly sandboxId: string;\n private readonly client: ApiClient;\n\n constructor(sandboxId: string, client: ApiClient) {\n this.sandboxId = sandboxId;\n this.client = client;\n }\n\n /**\n * Run a command in the background and return a handle.\n */\n async run(cmd: string, opts: RunOpts & { background: true }): Promise<CommandHandle>;\n /**\n * Run a command in the foreground and return its result.\n */\n async run(cmd: string, opts?: RunOpts): Promise<CommandResult>;\n async run(\n cmd: string,\n opts?: RunOpts,\n ): Promise<CommandResult | CommandHandle> {\n const background = opts?.background ?? false;\n const user = opts?.user ?? 'user';\n const timeout = opts?.timeout ?? 60;\n\n const body: Record<string, unknown> = {\n cmd,\n background,\n user,\n timeout,\n };\n\n if (opts?.envs !== undefined) {\n body.envs = opts.envs;\n }\n if (opts?.cwd !== undefined) {\n body.cwd = opts.cwd;\n }\n\n const data = await this.client.post(\n `/sandboxes/${this.sandboxId}/commands`,\n {\n json: body,\n timeout: opts?.requestTimeout,\n },\n );\n\n if (background) {\n const pid = (data as Record<string, unknown>).pid as number;\n return new CommandHandle(pid, this.sandboxId, this.client);\n }\n\n const result = parseCommandResult(data as Record<string, unknown>);\n\n // Invoke callbacks line-by-line (matching Python SDK's splitlines(keepends=True))\n if (opts?.onStdout && result.stdout) {\n for (const line of splitlines(result.stdout)) {\n opts.onStdout(line);\n }\n }\n if (opts?.onStderr && result.stderr) {\n for (const line of splitlines(result.stderr)) {\n opts.onStderr(line);\n }\n }\n\n return result;\n }\n\n /**\n * Run a command with real-time SSE streaming of stdout/stderr.\n *\n * Sends POST /sandboxes/:id/commands/stream and reads the response as\n * Server-Sent Events. Callbacks are invoked in real-time as output arrives.\n * Returns the accumulated CommandResult when the command completes.\n */\n async runStream(cmd: string, opts?: RunStreamOpts): Promise<CommandResult> {\n const user = opts?.user ?? 'user';\n const timeout = opts?.timeout ?? 60;\n\n const body: Record<string, unknown> = {\n cmd,\n stream: true,\n user,\n timeout,\n };\n\n if (opts?.envs !== undefined) {\n body.envs = opts.envs;\n }\n if (opts?.cwd !== undefined) {\n body.cwd = opts.cwd;\n }\n\n const response = await this.client.stream(\n `/sandboxes/${this.sandboxId}/commands/stream`,\n { json: body },\n );\n\n if (!response.body) {\n throw new SandboxError('Stream response has no body');\n }\n\n let stdout = '';\n let stderr = '';\n let exitCode = 0;\n\n const eventStream = response.body\n .pipeThrough(new TextDecoderStream())\n .pipeThrough(new EventSourceParserStream());\n\n const reader = eventStream.getReader();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(value.data) as Record<string, unknown>;\n } catch {\n // Skip malformed SSE events (matching Python SDK's json.JSONDecodeError handling)\n continue;\n }\n\n // Error event\n if (parsed.error !== undefined) {\n throw new SandboxError(parsed.error as string);\n }\n\n // Exit event\n if (parsed.exit_code !== undefined) {\n exitCode = parsed.exit_code as number;\n break;\n }\n\n // Output event\n const type = parsed.type as string;\n const data = parsed.data as string;\n\n if (type === 'stdout') {\n stdout += data;\n opts?.onStdout?.(data);\n } else if (type === 'stderr') {\n stderr += data;\n opts?.onStderr?.(data);\n }\n }\n } finally {\n reader.releaseLock();\n }\n\n return { stdout, stderr, exitCode };\n }\n\n /**\n * List all running commands in the sandbox.\n *\n * Sends GET /sandboxes/:id/commands.\n * @returns Array of ProcessInfo for each running process.\n */\n async list(requestTimeout?: number): Promise<ProcessInfo[]> {\n const data = await this.client.get(\n `/sandboxes/${this.sandboxId}/commands`,\n { timeout: requestTimeout },\n );\n const items = (data ?? []) as Record<string, unknown>[];\n return items.map(parseProcessInfo);\n }\n\n /**\n * Kill a running command by PID.\n *\n * Sends DELETE /sandboxes/:id/commands/:pid.\n * @returns true if the process was killed, false if already dead.\n */\n async kill(pid: number, requestTimeout?: number): Promise<boolean> {\n const data = await this.client.delete(\n `/sandboxes/${this.sandboxId}/commands/${pid}`,\n { timeout: requestTimeout },\n );\n return (data as Record<string, unknown>).killed === true;\n }\n\n /**\n * Send data to the stdin of a running command.\n *\n * Sends POST /sandboxes/:id/commands/:pid/stdin.\n */\n async sendStdin(pid: number, data: string, requestTimeout?: number): Promise<void> {\n await this.client.post(\n `/sandboxes/${this.sandboxId}/commands/${pid}/stdin`,\n {\n json: { data },\n timeout: requestTimeout,\n },\n );\n }\n\n /**\n * Connect to an existing running command by PID.\n *\n * Returns a CommandHandle without making any API call.\n */\n connect(pid: number): CommandHandle {\n return new CommandHandle(pid, this.sandboxId, this.client);\n }\n}\n\n/**\n * Split text into lines preserving line endings (like Python's splitlines(keepends=True)).\n * Each line includes its trailing \\n (or \\r\\n). The last line is included even without\n * a trailing newline.\n */\nfunction splitlines(text: string): string[] {\n const lines: string[] = [];\n const re = /[^\\r\\n]*(?:\\r\\n|\\n|\\r|$)/g;\n let match: RegExpExecArray | null;\n while ((match = re.exec(text)) !== null) {\n if (match[0] === '') break; // End of string\n lines.push(match[0]);\n }\n return lines;\n}\n","/** Type of a filesystem entry. */\nexport enum FileType {\n File = 'file',\n Dir = 'dir',\n}\n\n/** Type of a filesystem event. */\nexport enum FilesystemEventType {\n Create = 'create',\n Write = 'write',\n Remove = 'remove',\n Rename = 'rename',\n Chmod = 'chmod',\n}\n\n/** Information about a filesystem entry. */\nexport interface EntryInfo {\n name: string;\n path: string;\n type: FileType;\n size: number;\n}\n\n/** Parse raw JSON data into EntryInfo. */\nexport function parseEntryInfo(data: Record<string, any>): EntryInfo {\n return {\n name: data.name ?? '',\n path: data.path ?? '',\n type: (data.type as FileType) ?? FileType.File,\n size: data.size ?? 0,\n };\n}\n\n/** Information about a write operation. */\nexport interface WriteInfo {\n path: string;\n size: number;\n}\n\n/** Parse raw JSON data into WriteInfo. */\nexport function parseWriteInfo(data: Record<string, any>): WriteInfo {\n return {\n path: data.path ?? '',\n size: data.size ?? 0,\n };\n}\n\n/** An entry to write to the filesystem. */\nexport interface WriteEntry {\n path: string;\n data: string | Uint8Array;\n}\n\n/** A filesystem event from watching a directory. */\nexport interface FilesystemEvent {\n type: FilesystemEventType;\n path: string;\n timestamp?: number;\n}\n\n/** Parse raw JSON data into a FilesystemEvent. */\nexport function parseFilesystemEvent(data: Record<string, any>): FilesystemEvent {\n return {\n type: (data.type as FilesystemEventType) ?? FilesystemEventType.Create,\n path: data.path ?? '',\n timestamp: data.timestamp ?? undefined,\n };\n}\n","import type { FilesystemEvent } from './models.js';\n\n/**\n * Handle for a filesystem directory watch.\n *\n * Buffers incoming events in memory. Call `getNewEvents()` to drain\n * the buffer, and `stop()` to prevent new events from being added.\n */\nexport class WatchHandle {\n private events: FilesystemEvent[] = [];\n private stopped = false;\n\n /**\n * Stop accepting new events.\n * Idempotent — calling multiple times has no additional effect.\n */\n stop(): void {\n this.stopped = true;\n }\n\n /**\n * Drain and return all buffered events since the last call.\n * Returns an empty array if no new events have been received.\n */\n getNewEvents(): FilesystemEvent[] {\n const result = this.events;\n this.events = [];\n return result;\n }\n\n /**\n * Push a new event into the buffer.\n * Ignored if `stop()` has been called.\n */\n pushEvent(event: FilesystemEvent): void {\n if (!this.stopped) {\n this.events.push(event);\n }\n }\n}\n","import type { ApiClient } from '../../api/client.js';\nimport type { EntryInfo, WriteInfo, WriteEntry } from './models.js';\nimport { parseEntryInfo, parseWriteInfo } from './models.js';\nimport { WatchHandle } from './watchHandle.js';\n\n/** Default username for filesystem operations. */\nconst DEFAULT_USER = 'user';\n\n/**\n * Filesystem operations for a sandbox.\n *\n * Provides methods to read, write, list, and manage files\n * within a sandbox's filesystem.\n */\nexport class Filesystem {\n private readonly sandboxId: string;\n private readonly client: ApiClient;\n\n constructor(sandboxId: string, client: ApiClient) {\n this.sandboxId = sandboxId;\n this.client = client;\n }\n\n /**\n * Read a file's contents.\n *\n * Default returns the content as a string. Pass `{ format: \"bytes\" }`\n * to get a `Uint8Array` for binary-safe reads — the SDK negotiates\n * `application/octet-stream` end-to-end so high-bit bytes survive the\n * round trip.\n *\n * @param path - Absolute path to the file.\n * @param opts - Optional format, user, and request timeout.\n * @returns The file contents as a string, or Uint8Array when format=\"bytes\".\n */\n async read(\n path: string,\n opts?: { format?: 'text'; user?: string; requestTimeout?: number },\n ): Promise<string>;\n async read(\n path: string,\n opts: { format: 'bytes'; user?: string; requestTimeout?: number },\n ): Promise<Uint8Array>;\n async read(\n path: string,\n opts?: { format?: 'text' | 'bytes'; user?: string; requestTimeout?: number },\n ): Promise<string | Uint8Array> {\n const user = opts?.user ?? DEFAULT_USER;\n if (opts?.format === 'bytes') {\n return this.client.getBytes(\n `/sandboxes/${this.sandboxId}/files`,\n {\n params: { path, username: user },\n headers: { 'Accept': 'application/octet-stream' },\n timeout: opts?.requestTimeout,\n },\n );\n }\n const result = await this.client.get(\n `/sandboxes/${this.sandboxId}/files`,\n {\n params: { path, username: user },\n headers: { 'Accept': 'text/plain' },\n timeout: opts?.requestTimeout,\n },\n );\n // The API returns raw file content. We request text/plain, but the\n // generic response parser may still JSON-parse valid JSON content.\n // Always coerce to string for file reads.\n if (typeof result === 'string') {\n return result;\n }\n return JSON.stringify(result);\n }\n\n /**\n * Write data to a file.\n *\n * When `data` is a `Uint8Array`, the SDK streams the raw bytes to the\n * binary-safe `PUT /files/raw` endpoint (500 MiB cap). When it's a string,\n * the SDK uses the JSON `POST /files` endpoint. Callers do not need to\n * pick the transport.\n *\n * @param path - Absolute path to the file.\n * @param data - String or Uint8Array content to write.\n * @param opts - Optional user and request timeout.\n * @returns Information about the written file.\n */\n async write(\n path: string,\n data: string | Uint8Array,\n opts?: { user?: string; requestTimeout?: number },\n ): Promise<WriteInfo> {\n const user = opts?.user ?? DEFAULT_USER;\n if (data instanceof Uint8Array) {\n const result = await this.client.put(\n `/sandboxes/${this.sandboxId}/files/raw`,\n {\n params: { path, username: user },\n body: data,\n headers: { 'Content-Type': 'application/octet-stream' },\n timeout: opts?.requestTimeout,\n },\n );\n return parseWriteInfo(result as Record<string, unknown>);\n }\n const result = await this.client.post(\n `/sandboxes/${this.sandboxId}/files`,\n {\n json: { path, data, username: user },\n timeout: opts?.requestTimeout,\n },\n );\n return parseWriteInfo(result as Record<string, unknown>);\n }\n\n /**\n * Write multiple files in a single batch request.\n *\n * The batch endpoint is JSON-only and cannot carry binary. Entries are\n * partitioned: string entries go through `POST /files/batch` in one call,\n * `Uint8Array` entries are streamed individually to `PUT /files/raw`.\n * Results are merged back in input order.\n *\n * @param files - Array of files to write.\n * @param opts - Optional user and request timeout.\n * @returns Array of write info for each file, in input order.\n */\n async writeFiles(\n files: WriteEntry[],\n opts?: { user?: string; requestTimeout?: number },\n ): Promise<WriteInfo[]> {\n const user = opts?.user ?? DEFAULT_USER;\n const results: (WriteInfo | undefined)[] = new Array(files.length);\n\n const strIndices: number[] = [];\n const bytesIndices: number[] = [];\n for (let i = 0; i < files.length; i++) {\n if (files[i].data instanceof Uint8Array) {\n bytesIndices.push(i);\n } else {\n strIndices.push(i);\n }\n }\n\n if (strIndices.length > 0) {\n const batchFiles = strIndices.map((i) => ({\n path: files[i].path,\n data: files[i].data as string,\n }));\n const result = await this.client.post(\n `/sandboxes/${this.sandboxId}/files/batch`,\n {\n json: { files: batchFiles, username: user },\n timeout: opts?.requestTimeout,\n },\n );\n const parsed = ((result ?? []) as Record<string, unknown>[]).map(parseWriteInfo);\n for (let k = 0; k < strIndices.length; k++) {\n results[strIndices[k]] = parsed[k];\n }\n }\n\n for (const i of bytesIndices) {\n const entry = files[i];\n const result = await this.client.put(\n `/sandboxes/${this.sandboxId}/files/raw`,\n {\n params: { path: entry.path, username: user },\n body: entry.data as Uint8Array,\n headers: { 'Content-Type': 'application/octet-stream' },\n timeout: opts?.requestTimeout,\n },\n );\n results[i] = parseWriteInfo(result as Record<string, unknown>);\n }\n\n return results.filter((r): r is WriteInfo => r !== undefined);\n }\n\n /**\n * List entries in a directory.\n *\n * @param path - Absolute path to the directory.\n * @param opts - Optional depth, user, and request timeout.\n * @returns Array of entry info objects.\n */\n async list(\n path: string,\n opts?: { depth?: number; user?: string; requestTimeout?: number },\n ): Promise<EntryInfo[]> {\n const user = opts?.user ?? DEFAULT_USER;\n const params: Record<string, string> = { path, username: user };\n if (opts?.depth !== undefined) {\n params.depth = String(opts.depth);\n }\n const result = await this.client.get(\n `/sandboxes/${this.sandboxId}/files/list`,\n {\n params,\n timeout: opts?.requestTimeout,\n },\n );\n return ((result ?? []) as Record<string, unknown>[]).map(parseEntryInfo);\n }\n\n /**\n * Check whether a file or directory exists.\n *\n * @param path - Absolute path to check.\n * @param opts - Optional user and request timeout.\n * @returns True if the path exists.\n */\n async exists(\n path: string,\n opts?: { user?: string; requestTimeout?: number },\n ): Promise<boolean> {\n const user = opts?.user ?? DEFAULT_USER;\n const result = await this.client.get(\n `/sandboxes/${this.sandboxId}/files/exists`,\n {\n params: { path, username: user },\n timeout: opts?.requestTimeout,\n },\n );\n return (result as Record<string, unknown>).exists as boolean;\n }\n\n /**\n * Get information about a file or directory.\n *\n * @param path - Absolute path to query.\n * @param opts - Optional user and request timeout.\n * @returns Entry information.\n */\n async getInfo(\n path: string,\n opts?: { user?: string; requestTimeout?: number },\n ): Promise<EntryInfo> {\n const user = opts?.user ?? DEFAULT_USER;\n const result = await this.client.get(\n `/sandboxes/${this.sandboxId}/files/info`,\n {\n params: { path, username: user },\n timeout: opts?.requestTimeout,\n },\n );\n return parseEntryInfo(result as Record<string, unknown>);\n }\n\n /**\n * Remove a file or directory.\n *\n * IMPORTANT: Uses proper query params to prevent URL injection.\n * This fixes the Python SDK vulnerability where path was concatenated\n * directly into the URL string.\n *\n * @param path - Absolute path to remove.\n * @param opts - Optional user and request timeout.\n */\n async remove(\n path: string,\n opts?: { user?: string; requestTimeout?: number },\n ): Promise<void> {\n const user = opts?.user ?? DEFAULT_USER;\n await this.client.delete(\n `/sandboxes/${this.sandboxId}/files`,\n {\n params: { path, username: user },\n timeout: opts?.requestTimeout,\n },\n );\n }\n\n /**\n * Rename (move) a file or directory.\n *\n * @param oldPath - Current path.\n * @param newPath - New path.\n * @param opts - Optional user and request timeout.\n * @returns Entry information for the renamed item.\n */\n async rename(\n oldPath: string,\n newPath: string,\n opts?: { user?: string; requestTimeout?: number },\n ): Promise<EntryInfo> {\n const user = opts?.user ?? DEFAULT_USER;\n const result = await this.client.patch(\n `/sandboxes/${this.sandboxId}/files`,\n {\n json: { old_path: oldPath, new_path: newPath, username: user },\n timeout: opts?.requestTimeout,\n },\n );\n return parseEntryInfo(result as Record<string, unknown>);\n }\n\n /**\n * Create a directory.\n *\n * @param path - Absolute path of the directory to create.\n * @param opts - Optional user and request timeout.\n * @returns True if the directory was created.\n */\n async makeDir(\n path: string,\n opts?: { user?: string; requestTimeout?: number },\n ): Promise<boolean> {\n const user = opts?.user ?? DEFAULT_USER;\n const result = await this.client.post(\n `/sandboxes/${this.sandboxId}/files/mkdir`,\n {\n json: { path, username: user },\n timeout: opts?.requestTimeout,\n },\n );\n return (result as Record<string, unknown>).created as boolean;\n }\n\n /**\n * Watch a directory for filesystem events.\n *\n * @param path - Absolute path of the directory to watch.\n * @param opts - Optional user, recursive flag, and request timeout.\n * @returns A WatchHandle to receive events and stop watching.\n */\n async watchDir(\n path: string,\n opts?: { user?: string; recursive?: boolean; requestTimeout?: number },\n ): Promise<WatchHandle> {\n const user = opts?.user ?? DEFAULT_USER;\n const recursive = opts?.recursive ?? false;\n await this.client.post(\n `/sandboxes/${this.sandboxId}/files/watch`,\n {\n json: { path, username: user, recursive },\n timeout: opts?.requestTimeout,\n },\n );\n return new WatchHandle();\n }\n}\n","import { ApiClient } from '../../api/client.js';\nimport type { PtySize } from '../commands/models.js';\n\n/** Outcome of a PTY session — produced by `PtyHandle.wait()`. */\nexport interface PtyResult {\n /** Remote shell exit code. `-1` if the stream dropped before a clean exit frame. */\n exitCode: number;\n}\n\n/** Options for attaching to a running PTY via `Pty.connect()`. */\nexport interface PtyConnectOpts {\n /**\n * Callback invoked with every chunk of PTY output as raw bytes.\n * Optional — omit to drive the stream via the handle's async iterator.\n */\n onData?: (data: Uint8Array) => void;\n}\n\n/** Options for creating a PTY session. */\nexport interface PtyCreateOpts {\n /** Terminal size. Defaults to { cols: 80, rows: 24 }. */\n size?: PtySize;\n /** User to run as. Defaults to 'user'. */\n user?: string;\n /** Working directory. */\n cwd?: string;\n /** Environment variables. */\n envs?: Record<string, string>;\n /**\n * PTY session TTL in seconds. Defaults to 3600 (1 hour). Pass `0` to\n * keep the session alive indefinitely — it will still die when the\n * parent sandbox's timeout fires.\n */\n timeout?: number;\n /** Per-request timeout in milliseconds (applies to the initial create call only). */\n requestTimeout?: number;\n /**\n * Callback invoked with every chunk of PTY output as raw bytes.\n * Setting this implicitly opens the SSE stream; the returned handle's\n * `wait()` resolves when the remote process exits. Drop this option\n * and call `handle.stream()` directly if you want to drive the iterator\n * explicitly instead.\n */\n onData?: (data: Uint8Array) => void;\n}\n\n/**\n * Handle to a running PTY session. Returned from `Pty.create()`.\n *\n * Exposes stdin / resize / kill plus a `wait()` that resolves with the\n * remote exit code once the process terminates. The output stream runs\n * over Server-Sent Events — configured via `onData` at create time or\n * consumed manually with `stream()`.\n */\nexport class PtyHandle {\n readonly pid: number;\n private readonly sandboxId: string;\n private readonly client: ApiClient;\n private readonly exitPromise: Promise<PtyResult>;\n private resolveExit!: (result: PtyResult) => void;\n private aborter = new AbortController();\n\n constructor(\n pid: number,\n sandboxId: string,\n client: ApiClient,\n onData?: (data: Uint8Array) => void,\n ) {\n this.pid = pid;\n this.sandboxId = sandboxId;\n this.client = client;\n this.exitPromise = new Promise<PtyResult>((resolve) => {\n this.resolveExit = resolve;\n });\n if (onData) {\n void this.consumeStream(onData);\n }\n }\n\n /** Forward keystrokes to the PTY. */\n async sendInput(\n data: Uint8Array | string,\n requestTimeout?: number,\n ): Promise<void> {\n const strData = typeof data === 'string' ? data : new TextDecoder().decode(data);\n await this.client.post(\n `/sandboxes/${this.sandboxId}/pty/${this.pid}/stdin`,\n { json: { data: strData }, timeout: requestTimeout },\n );\n }\n\n /** Update the terminal size (TIOCSWINSZ inside the VM). */\n async resize(size: PtySize, requestTimeout?: number): Promise<void> {\n await this.client.patch(\n `/sandboxes/${this.sandboxId}/pty/${this.pid}`,\n {\n json: { size: { cols: size.cols, rows: size.rows } },\n timeout: requestTimeout,\n },\n );\n }\n\n /** SIGKILL the remote process and close any open streams. */\n async kill(requestTimeout?: number): Promise<boolean> {\n this.aborter.abort();\n const data = await this.client.delete(\n `/sandboxes/${this.sandboxId}/pty/${this.pid}`,\n { timeout: requestTimeout },\n );\n return (data as Record<string, unknown>).killed === true;\n }\n\n /**\n * Stop consuming output without killing the process. The PTY keeps\n * running server-side and a fresh `stream()` call reattaches.\n */\n disconnect(): void {\n this.aborter.abort();\n }\n\n /** Resolves with the remote exit result when the PTY process exits. */\n wait(): Promise<PtyResult> {\n return this.exitPromise;\n }\n\n /**\n * Async iterator over raw output chunks. Use when you want to drive\n * the stream yourself:\n *\n * for await (const chunk of handle.stream()) { ... }\n *\n * Don't mix this with `onData` on the same handle — they both try to\n * consume the same underlying SSE connection.\n */\n async *stream(): AsyncGenerator<Uint8Array, void, void> {\n const response = await this.client.streamGet(\n `/sandboxes/${this.sandboxId}/pty/${this.pid}/stream`,\n { timeout: undefined },\n );\n if (!response.body) {\n return;\n }\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n try {\n while (true) {\n if (this.aborter.signal.aborted) return;\n const { value, done } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n let idx: number;\n while ((idx = buffer.indexOf('\\n\\n')) >= 0) {\n const frame = buffer.slice(0, idx);\n buffer = buffer.slice(idx + 2);\n const parsed = parseSSEFrame(frame);\n if (!parsed) continue;\n if (parsed.event === 'exit') {\n this.resolveExit({ exitCode: parsed.exitCode ?? -1 });\n return;\n }\n if (parsed.bytes) {\n yield parsed.bytes;\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n private async consumeStream(onData: (data: Uint8Array) => void): Promise<void> {\n try {\n for await (const chunk of this.stream()) {\n onData(chunk);\n }\n } catch (err) {\n // If the stream aborts after an explicit disconnect/kill, that's fine.\n if (!this.aborter.signal.aborted) {\n throw err;\n }\n } finally {\n // If stream() returned without an exit frame (e.g. connection drop),\n // still unblock wait() so callers don't hang forever.\n this.resolveExit({ exitCode: -1 });\n }\n }\n}\n\ninterface ParsedSSEFrame {\n event: string;\n bytes?: Uint8Array;\n exitCode?: number;\n}\n\nfunction parseSSEFrame(frame: string): ParsedSSEFrame | null {\n let event = 'message';\n let data = '';\n for (const line of frame.split('\\n')) {\n if (line.startsWith('event:')) event = line.slice(6).trim();\n else if (line.startsWith('data:')) data += line.slice(5).trim();\n }\n if (!event) return null;\n if (event === 'exit') {\n try {\n const parsed = JSON.parse(data) as { exit_code?: number };\n return { event, exitCode: parsed.exit_code ?? -1 };\n } catch {\n return { event, exitCode: -1 };\n }\n }\n if (event === 'data') {\n try {\n const parsed = JSON.parse(data) as { data?: string };\n if (typeof parsed.data === 'string') {\n const bin = atob(parsed.data);\n const bytes = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);\n return { event, bytes };\n }\n } catch {\n return null;\n }\n }\n return null;\n}\n\n/**\n * PTY (pseudo-terminal) interface for a sandbox.\n *\n * Use `create()` to launch a fresh shell session. The returned\n * `PtyHandle` exposes stdin / resize / kill plus a live output stream\n * (callback or async iterator).\n */\nexport class Pty {\n private readonly sandboxId: string;\n private readonly client: ApiClient;\n\n constructor(sandboxId: string, client: ApiClient) {\n this.sandboxId = sandboxId;\n this.client = client;\n }\n\n async create(opts?: PtyCreateOpts): Promise<PtyHandle> {\n const size = opts?.size ?? { cols: 80, rows: 24 };\n const user = opts?.user ?? 'user';\n\n const body: Record<string, unknown> = {\n size: { cols: size.cols, rows: size.rows },\n user,\n timeout: opts?.timeout ?? 3600,\n };\n if (opts?.cwd !== undefined) body.cwd = opts.cwd;\n if (opts?.envs !== undefined) body.envs = opts.envs;\n\n const data = await this.client.post(\n `/sandboxes/${this.sandboxId}/pty`,\n { json: body, timeout: opts?.requestTimeout },\n );\n const pid = (data as Record<string, unknown>).pid as number;\n return new PtyHandle(pid, this.sandboxId, this.client, opts?.onData);\n }\n\n /**\n * Reattach to an already-running PTY by its pid.\n *\n * Returns a fresh `PtyHandle` that streams the live output of the\n * existing session. Multiple clients can subscribe to the same pid\n * concurrently — each receives output from the moment it connects\n * (no scrollback replay).\n */\n connect(pid: number, opts?: PtyConnectOpts): PtyHandle {\n return new PtyHandle(pid, this.sandboxId, this.client, opts?.onData);\n }\n\n // --- Low-level API by pid (kept for callers that already hold one). ---\n\n async kill(pid: number, requestTimeout?: number): Promise<boolean> {\n const data = await this.client.delete(\n `/sandboxes/${this.sandboxId}/pty/${pid}`,\n { timeout: requestTimeout },\n );\n return (data as Record<string, unknown>).killed === true;\n }\n\n async sendStdin(\n pid: number,\n data: Uint8Array | string,\n requestTimeout?: number,\n ): Promise<void> {\n const strData = typeof data === 'string' ? data : new TextDecoder().decode(data);\n await this.client.post(\n `/sandboxes/${this.sandboxId}/pty/${pid}/stdin`,\n { json: { data: strData }, timeout: requestTimeout },\n );\n }\n\n async resize(\n pid: number,\n size: PtySize,\n requestTimeout?: number,\n ): Promise<void> {\n await this.client.patch(\n `/sandboxes/${this.sandboxId}/pty/${pid}`,\n {\n json: { size: { cols: size.cols, rows: size.rows } },\n timeout: requestTimeout,\n },\n );\n }\n}\n","import { ApiClient } from '../../api/client.js';\nimport { EventSourceParserStream } from 'eventsource-parser/stream';\nimport { SandboxError } from '../../errors.js';\n\n/** Options for starting an interactive stdio process. */\nexport interface StdioStartOpts {\n envs?: Record<string, string>;\n user?: string;\n cwd?: string;\n onStdout?: (data: Uint8Array) => void;\n onStderr?: (data: Uint8Array) => void;\n requestTimeout?: number;\n}\n\n/** Result returned when a stdio process exits. */\nexport interface StdioResult {\n exitCode: number;\n}\n\n/**\n * Handle for an interactive subprocess with stdin pipe.\n */\nexport class StdioProcess {\n readonly cmdId: string;\n private readonly sandboxId: string;\n private readonly client: ApiClient;\n private lastEntryId = 0;\n private _exitCode: number | null = null;\n private _bgStream: Promise<StdioResult> | null = null;\n\n constructor(\n cmdId: string,\n sandboxId: string,\n client: ApiClient,\n opts?: {\n onStdout?: (data: Uint8Array) => void;\n onStderr?: (data: Uint8Array) => void;\n },\n ) {\n this.cmdId = cmdId;\n this.sandboxId = sandboxId;\n this.client = client;\n if (opts?.onStdout || opts?.onStderr) {\n this._bgStream = this.stream({\n onStdout: opts.onStdout,\n onStderr: opts.onStderr,\n });\n }\n }\n\n get exitCode(): number | null {\n return this._exitCode;\n }\n\n async sendStdin(data: string | Uint8Array, requestTimeout?: number): Promise<void> {\n const raw = typeof data === 'string' ? new TextEncoder().encode(data) : data;\n let binary = '';\n for (let i = 0; i < raw.length; i++) {\n binary += String.fromCharCode(raw[i]);\n }\n const encoded = btoa(binary);\n await this.client.post(\n `/sandboxes/${this.sandboxId}/stdio/${this.cmdId}/stdin`,\n {\n json: { data: encoded },\n timeout: requestTimeout,\n },\n );\n }\n\n async closeStdin(requestTimeout?: number): Promise<void> {\n await this.client.post(\n `/sandboxes/${this.sandboxId}/stdio/${this.cmdId}/stdin/close`,\n { timeout: requestTimeout },\n );\n }\n\n async kill(requestTimeout?: number): Promise<boolean> {\n const resp = await this.client.delete(\n `/sandboxes/${this.sandboxId}/stdio/${this.cmdId}`,\n { timeout: requestTimeout },\n );\n return Boolean((resp as Record<string, unknown>).killed);\n }\n\n async wait(): Promise<StdioResult> {\n if (this._bgStream) {\n return this._bgStream;\n }\n return this.stream();\n }\n\n async stream(opts?: {\n onStdout?: (data: Uint8Array) => void;\n onStderr?: (data: Uint8Array) => void;\n }): Promise<StdioResult> {\n if (this._bgStream && !opts) {\n return this._bgStream;\n }\n let url = `/sandboxes/${this.sandboxId}/stdio/${this.cmdId}/stream`;\n if (this.lastEntryId > 0) {\n url += `?last_entry_id=${this.lastEntryId}`;\n }\n\n const response = await this.client.streamGet(url);\n const stream = response.body;\n if (!stream) {\n throw new SandboxError('No response body for stdio stream');\n }\n\n const eventStream = stream\n .pipeThrough(new TextDecoderStream())\n .pipeThrough(new EventSourceParserStream());\n\n for await (const event of eventStream) {\n if (event.event === 'exit') {\n try {\n const parsed = JSON.parse(event.data);\n this._exitCode = parsed.exit_code ?? -1;\n } catch {\n this._exitCode = -1;\n }\n break;\n }\n if (event.event === 'stdout' || event.event === 'stderr') {\n try {\n const parsed = JSON.parse(event.data);\n const entryId = parsed.entry_id ?? 0;\n if (entryId > this.lastEntryId) {\n this.lastEntryId = entryId;\n }\n const raw = atob(parsed.data ?? '');\n const bytes = new Uint8Array(raw.length);\n for (let i = 0; i < raw.length; i++) {\n bytes[i] = raw.charCodeAt(i);\n }\n if (event.event === 'stdout' && opts?.onStdout) {\n opts.onStdout(bytes);\n } else if (event.event === 'stderr' && opts?.onStderr) {\n opts.onStderr(bytes);\n }\n } catch {\n continue;\n }\n }\n }\n\n return { exitCode: this._exitCode ?? -1 };\n }\n}\n\n/**\n * Module for interactive stdio subprocess sessions in the sandbox.\n */\nexport class Stdio {\n private readonly sandboxId: string;\n private readonly client: ApiClient;\n\n constructor(sandboxId: string, client: ApiClient) {\n this.sandboxId = sandboxId;\n this.client = client;\n }\n\n async start(cmd: string, opts?: StdioStartOpts): Promise<StdioProcess> {\n const user = opts?.user ?? 'user';\n const body: Record<string, unknown> = { cmd, user };\n if (opts?.envs) body.envs = opts.envs;\n if (opts?.cwd) body.cwd = opts.cwd;\n\n const data = await this.client.post(\n `/sandboxes/${this.sandboxId}/stdio`,\n { json: body, timeout: opts?.requestTimeout },\n );\n const cmdId = (data as Record<string, string>).cmd_id;\n return new StdioProcess(cmdId, this.sandboxId, this.client, {\n onStdout: opts?.onStdout,\n onStderr: opts?.onStderr,\n });\n }\n}\n","/** Live-mount / copy mode for a volume attachment on Sandbox.create. */\nexport type VolumeAttachMode = 'copy' | 'mount' | 'mount-ro';\n\n/** Request-side shape of a volume attachment on Sandbox.create. */\nexport interface VolumeAttachment {\n volumeId: string;\n mountPath: string;\n /**\n * Attach mode. `copy` (default) hydrates the volume into the sandbox\n * filesystem at boot. `mount` is a read-write live NFS mount; `mount-ro`\n * is a read-only live mount. Omitted from the wire when unset (server\n * defaults to copy).\n */\n mode?: VolumeAttachMode;\n /**\n * Relative path within the volume to mount. LIVE-MOUNT ONLY — the server\n * rejects a subpath on a copy-mode attachment.\n */\n subpath?: string;\n}\n\n/** Server-side metadata for a single volume. */\nexport interface VolumeInfo {\n volumeId: string;\n ownerId: string;\n name: string;\n blobKey: string;\n sizeBytes: number;\n contentType: string;\n metadata: Record<string, string>;\n createdAt: string;\n /** Storage backend (\"tarball\" or a file-granular backend). */\n backend: string;\n /** Per-volume quota in bytes (0 = unset/unlimited). */\n quotaBytes: number;\n /** Last-modified timestamp (ISO 8601). */\n updatedAt: string;\n}\n\n/** A single directory entry inside a file-granular volume (volumefs.Entry). */\nexport interface FileEntry {\n name: string;\n path: string;\n isDir: boolean;\n size: number;\n modTime: string;\n mode: number;\n}\n\n/** A file entry plus the CAS token returned by `info`/`stat`. */\nexport interface FileInfo extends FileEntry {\n /** CAS token to round-trip into a conditional write's `ifVersion`. */\n version: string;\n}\n\n/** Result of acquiring or renewing a lock. */\nexport interface LockLease {\n token: string;\n ttlSeconds: number;\n expiresAt: string;\n}\n\n/** Result of querying lock status. */\nexport interface LockStatus {\n held: boolean;\n expiresInMs: number;\n}\n\n/** Convert a wire-format volume row into a VolumeInfo. */\nexport function parseVolumeInfo(data: Record<string, unknown>): VolumeInfo {\n return {\n volumeId: String(data.volume_id ?? ''),\n ownerId: String(data.owner_id ?? ''),\n name: String(data.name ?? ''),\n blobKey: String(data.blob_key ?? ''),\n sizeBytes: Number(data.size_bytes ?? 0),\n contentType: String(data.content_type ?? ''),\n metadata: (data.metadata as Record<string, string> | null | undefined) ?? {},\n createdAt: String(data.created_at ?? ''),\n backend: String(data.backend ?? ''),\n quotaBytes: Number(data.quota_bytes ?? 0),\n updatedAt: String(data.updated_at ?? ''),\n };\n}\n\n/** Convert a wire-format file entry into a FileEntry. */\nexport function parseFileEntry(data: Record<string, unknown>): FileEntry {\n return {\n name: String(data.name ?? ''),\n path: String(data.path ?? ''),\n isDir: Boolean(data.is_dir ?? false),\n size: Number(data.size ?? 0),\n modTime: String(data.mod_time ?? ''),\n mode: Number(data.mode ?? 0),\n };\n}\n\n/** Convert a wire-format stat response into a FileInfo (FileEntry + version). */\nexport function parseFileInfo(data: Record<string, unknown>): FileInfo {\n return {\n ...parseFileEntry(data),\n version: String(data.version ?? ''),\n };\n}\n\n/** Convert a wire-format lock lease into a LockLease. */\nexport function parseLockLease(data: Record<string, unknown>): LockLease {\n return {\n token: String(data.token ?? ''),\n ttlSeconds: Number(data.ttl_seconds ?? 0),\n expiresAt: String(data.expires_at ?? ''),\n };\n}\n\n/** Convert a wire-format lock status into a LockStatus. */\nexport function parseLockStatus(data: Record<string, unknown>): LockStatus {\n return {\n held: Boolean(data.held ?? false),\n expiresInMs: Number(data.expires_in_ms ?? 0),\n };\n}\n\n/** Render a VolumeAttachment in wire (snake_case) form. */\nexport function volumeAttachmentToJSON(att: VolumeAttachment): Record<string, string> {\n const out: Record<string, string> = {\n volume_id: att.volumeId,\n mount_path: att.mountPath,\n };\n if (att.mode) {\n out.mode = att.mode;\n }\n if (att.subpath) {\n out.subpath = att.subpath;\n }\n return out;\n}\n","import { ConnectionConfig } from '../connectionConfig.js';\nimport { ApiClient, getSharedClient } from '../api/client.js';\nimport { InvalidArgumentError } from '../errors.js';\nimport { ALL_TRAFFIC } from './network.js';\nimport type { SandboxNetworkOpts } from './network.js';\nimport type { SecurityPolicy } from '../security/policy.js';\nimport { securityPolicyToJSON } from '../security/policy.js';\nimport type { SandboxInfo, SandboxMetrics, SandboxLifecycle, SnapshotInfo, Snapshot } from './models.js';\nimport { parseSandboxInfo, parseSandboxMetrics, parseSnapshotInfo, parseSnapshot } from './models.js';\nimport { Commands } from './commands/commands.js';\nimport { Filesystem } from './filesystem/filesystem.js';\nimport { Pty } from './pty/pty.js';\nimport { Stdio } from './stdio/stdio.js';\nimport type { VolumeAttachment } from '../volumes/models.js';\nimport { volumeAttachmentToJSON } from '../volumes/models.js';\n\n/** Options for creating a sandbox. */\nexport interface SandboxOpts {\n /** Template to use. Defaults to 'base'. */\n template?: string;\n /** Timeout in seconds. Defaults to 300. */\n timeout?: number;\n /** Metadata key-value pairs. */\n metadata?: Record<string, string>;\n /** Environment variables. */\n envs?: Record<string, string>;\n /** Whether to create a secure sandbox. Defaults to true. */\n secure?: boolean;\n /** If false, denies all outbound traffic. Defaults to true. */\n allowInternetAccess?: boolean;\n /** Fine-grained network configuration. Overrides allowInternetAccess. */\n network?: SandboxNetworkOpts;\n /** Security policy for the sandbox. */\n security?: SecurityPolicy;\n /** Lifecycle configuration. */\n lifecycle?: SandboxLifecycle;\n /** Volumes to attach at sandbox-boot time. Each {volumeId, mountPath}\n * references a blob uploaded via `Volumes.create`; the orchestrator\n * materializes its contents under `mountPath` before the first command\n * is dispatched. */\n volumes?: VolumeAttachment[];\n /** API key override. */\n apiKey?: string;\n /** Domain override (supports \"host:port\" format, e.g. \"myhost.example.com:8080\"). */\n domain?: string;\n /** Full API URL override. If set, domain/port/scheme are ignored. */\n apiUrl?: string;\n /** Per-request timeout in milliseconds. */\n requestTimeout?: number;\n}\n\n/** Default template name. */\nconst DEFAULT_TEMPLATE = 'base';\n\n/** Default sandbox timeout in seconds. */\nconst DEFAULT_TIMEOUT = 300;\n\n/** Port conventionally used for MCP servers running inside a sandbox. */\nconst MCP_PORT = 50005;\n\nconst VALID_ID_RE = /^[a-zA-Z0-9_-]+$/;\n\n/** Validate that an ID is safe for URL path interpolation. */\nfunction assertValidId(id: string, label: string): void {\n if (!id || !VALID_ID_RE.test(id)) {\n throw new InvalidArgumentError(\n `Invalid ${label}: \"${id}\". Must be alphanumeric with hyphens/underscores only.`,\n );\n }\n}\n\n/**\n * A Declaw sandbox.\n *\n * Use `Sandbox.create()` to create a new sandbox, or `Sandbox.connect()` to\n * connect to an existing one. Do not instantiate directly.\n */\nexport class Sandbox {\n private readonly _sandboxId: string;\n private readonly _config: ConnectionConfig;\n private readonly _client: ApiClient;\n private readonly _envdAccessToken?: string;\n private readonly _sandboxDomain?: string;\n private readonly _trafficAccessToken?: string;\n private readonly _commands: Commands;\n private readonly _files: Filesystem;\n private readonly _pty: Pty;\n private readonly _stdio: Stdio;\n\n private constructor(\n sandboxId: string,\n config: ConnectionConfig,\n client: ApiClient,\n envdAccessToken?: string,\n sandboxDomain?: string,\n trafficAccessToken?: string,\n ) {\n this._sandboxId = sandboxId;\n this._config = config;\n this._client = client;\n this._envdAccessToken = envdAccessToken;\n this._sandboxDomain = sandboxDomain;\n this._trafficAccessToken = trafficAccessToken;\n this._commands = new Commands(sandboxId, client);\n this._files = new Filesystem(sandboxId, client);\n this._pty = new Pty(sandboxId, client);\n this._stdio = new Stdio(sandboxId, client);\n }\n\n /** The unique sandbox identifier. */\n get sandboxId(): string {\n return this._sandboxId;\n }\n\n /** The connection configuration used by this sandbox. */\n get config(): ConnectionConfig {\n return this._config;\n }\n\n /** Access token for the envd service inside the sandbox. */\n get envdAccessToken(): string | undefined {\n return this._envdAccessToken;\n }\n\n /** Domain where the sandbox is accessible. */\n get sandboxDomain(): string | undefined {\n return this._sandboxDomain;\n }\n\n /** Access token for traffic routing to the sandbox. */\n get trafficAccessToken(): string | undefined {\n return this._trafficAccessToken;\n }\n\n /** Commands sub-module for executing and managing commands. */\n get commands(): Commands {\n return this._commands;\n }\n\n /** Filesystem sub-module for reading and writing files. */\n get files(): Filesystem {\n return this._files;\n }\n\n /** PTY sub-module for pseudo-terminal sessions. */\n get pty(): Pty {\n return this._pty;\n }\n\n /** Stdio sub-module for interactive subprocess sessions with stdin pipe. */\n get stdio(): Stdio {\n return this._stdio;\n }\n\n /**\n * Base URL for this sandbox's namespace on the Declaw API.\n *\n * All per-sandbox operations (commands, files, file streaming, ports) live\n * under this prefix. Callers must attach an `X-API-Key` header with their\n * Declaw API key.\n */\n get envdApiUrl(): string {\n return `${this._config.apiUrl}/sandboxes/${this._sandboxId}`;\n }\n\n /**\n * Return the path-based URL that reverse-proxies to `port` inside the sandbox.\n *\n * Requires `allowPublicTraffic` to be enabled on the sandbox's network\n * config (the default). The returned URL is authenticated via the same\n * API key as all other sandbox operations.\n */\n getHost(port: number): string {\n return `${this.envdApiUrl}/ports/${port}`;\n }\n\n /**\n * Return the URL for an MCP server listening on port 50005 inside the sandbox.\n */\n getMcpUrl(): string {\n return `${this.getHost(MCP_PORT)}/mcp`;\n }\n\n /**\n * URL for a streaming GET of `path` out of the sandbox.\n *\n * Supports files up to 500 MiB. Callers must attach `X-API-Key`; the URL\n * is NOT safe to share with third parties because the API key is required\n * separately.\n */\n downloadUrl(path: string, user?: string): string {\n const params = new URLSearchParams({ path });\n if (user) params.set('username', user);\n return `${this.envdApiUrl}/files/raw?${params.toString()}`;\n }\n\n /**\n * URL that accepts a streaming PUT with a raw binary body to write `path`\n * into the sandbox.\n *\n * Supports files up to 500 MiB. Same auth note as {@link downloadUrl}.\n */\n uploadUrl(path: string, user?: string): string {\n const params = new URLSearchParams({ path });\n if (user) params.set('username', user);\n return `${this.envdApiUrl}/files/raw?${params.toString()}`;\n }\n\n /**\n * Create a new sandbox.\n *\n * @param opts - Sandbox creation options.\n * @returns A new Sandbox instance connected to the created sandbox.\n */\n static async create(opts?: SandboxOpts): Promise<Sandbox> {\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n apiUrl: opts?.apiUrl,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n\n const body: Record<string, unknown> = {\n template: opts?.template ?? DEFAULT_TEMPLATE,\n timeout: opts?.timeout ?? DEFAULT_TIMEOUT,\n secure: opts?.secure ?? true,\n };\n\n if (opts?.metadata) {\n body.metadata = opts.metadata;\n }\n if (opts?.envs) {\n body.envs = opts.envs;\n }\n\n // Network: explicit opts take precedence over allowInternetAccess flag\n if (opts?.network) {\n body.network = networkOptsToJSON(opts.network);\n } else if (opts?.allowInternetAccess === false) {\n body.network = { deny_out: [ALL_TRAFFIC] };\n }\n\n if (opts?.security) {\n body.security = { policy_json: JSON.stringify(securityPolicyToJSON(opts.security)) };\n // Propagate security.network to top-level network field (matching Python SDK)\n if (opts.security.network && !body.network) {\n body.network = typeof opts.security.network === 'object' && 'allowOut' in opts.security.network\n ? networkOptsToJSON(opts.security.network as SandboxNetworkOpts)\n : opts.security.network;\n }\n }\n\n if (opts?.lifecycle) {\n body.lifecycle = lifecycleToJSON(opts.lifecycle);\n }\n\n if (opts?.volumes && opts.volumes.length > 0) {\n body.volumes = opts.volumes.map(volumeAttachmentToJSON);\n }\n\n const data = (await client.post('/sandboxes', {\n json: body,\n timeout: opts?.requestTimeout,\n })) as Record<string, unknown>;\n\n const sandboxId = data.sandbox_id as string;\n assertValidId(sandboxId, 'sandbox ID (from server)');\n\n return new Sandbox(\n sandboxId,\n config,\n client,\n data.envd_access_token as string | undefined,\n data.sandbox_domain as string | undefined,\n data.traffic_access_token as string | undefined,\n );\n }\n\n /**\n * Connect to an existing sandbox.\n *\n * @param sandboxId - The sandbox ID to connect to.\n * @param opts - Connection options.\n * @returns A Sandbox instance connected to the existing sandbox.\n */\n static async connect(\n sandboxId: string,\n opts?: { apiKey?: string; domain?: string; apiUrl?: string; requestTimeout?: number },\n ): Promise<Sandbox> {\n assertValidId(sandboxId, 'sandbox ID');\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n apiUrl: opts?.apiUrl,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n\n const data = (await client.get(`/sandboxes/${sandboxId}`, {\n timeout: opts?.requestTimeout,\n })) as Record<string, unknown>;\n\n return new Sandbox(\n data.sandbox_id as string,\n config,\n client,\n data.envd_access_token as string | undefined,\n data.sandbox_domain as string | undefined,\n data.traffic_access_token as string | undefined,\n );\n }\n\n /**\n * List sandboxes.\n *\n * Creates a temporary ApiClient, fetches the list, and closes the client.\n *\n * @param opts - Listing options.\n * @returns An object with parsed sandbox info array and optional pagination token.\n */\n static async list(opts?: {\n query?: Record<string, string>;\n limit?: number;\n nextToken?: string;\n apiKey?: string;\n domain?: string;\n apiUrl?: string;\n requestTimeout?: number;\n }): Promise<{ sandboxes: SandboxInfo[]; nextToken?: string }> {\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n apiUrl: opts?.apiUrl,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n\n const params: Record<string, string> = {};\n if (opts?.query) {\n for (const [key, value] of Object.entries(opts.query)) {\n params[key] = value;\n }\n }\n if (opts?.limit !== undefined) {\n params.limit = String(opts.limit);\n }\n if (opts?.nextToken) {\n params.next_token = opts.nextToken;\n }\n\n const data = (await client.get('/sandboxes', {\n params,\n timeout: opts?.requestTimeout,\n })) as Record<string, unknown>;\n\n const rawSandboxes = (data.sandboxes ?? []) as Record<string, unknown>[];\n const sandboxes = rawSandboxes.map((s) =>\n parseSandboxInfo(s as Record<string, unknown>),\n );\n\n return {\n sandboxes,\n nextToken: (data.next_token as string) ?? undefined,\n };\n }\n\n /**\n * Kill this sandbox.\n *\n * Returns once the kill has been accepted by the server. The per-VM\n * teardown (firecracker shutdown + netns + iptables cleanup) runs in\n * the background. Pass `{ wait: true }` to block until the teardown\n * has fully completed.\n *\n * @param requestTimeout - Optional per-request timeout in milliseconds.\n * @returns True if the sandbox was killed (or queued); false if the\n * server reported it was already dead.\n */\n async kill(requestTimeout?: number): Promise<boolean>;\n async kill(opts?: { requestTimeout?: number; wait?: boolean }): Promise<boolean>;\n async kill(arg?: number | { requestTimeout?: number; wait?: boolean }): Promise<boolean> {\n const opts = typeof arg === 'number' ? { requestTimeout: arg } : (arg ?? {});\n const wait = opts.wait === true;\n const path = wait\n ? `/sandboxes/${this._sandboxId}`\n : `/sandboxes/${this._sandboxId}?async=true`;\n const data = (await this._client.delete(path, {\n timeout: opts.requestTimeout,\n })) as Record<string, unknown>;\n if (!wait) {\n return (data.queued as boolean) ?? true;\n }\n return (data.killed as boolean) ?? false;\n }\n\n /**\n * Kill many sandboxes in a single request. Server fans out internally\n * with bounded concurrency, eliminating per-id round-trip overhead.\n *\n * @param ids - sandbox IDs to kill.\n * @param opts.wait - If true, wait for each VM's teardown to finish\n * before returning. Default is false (server returns 202 once the\n * request is queued).\n * @param opts.requestTimeout - Per-request timeout in milliseconds.\n * @returns Map of sandbox-id → outcome. Outcome is `{killed: true}`\n * (wait=true), `{queued: true}` (default), or `{error: string}` if\n * the server reported a per-id failure.\n */\n static async killMany(\n ids: string[],\n opts?: { wait?: boolean; requestTimeout?: number; config?: ConnectionConfig },\n ): Promise<Record<string, { killed?: boolean; queued?: boolean; error?: string }>> {\n if (!ids || ids.length === 0) return {};\n const config = opts?.config ?? new ConnectionConfig();\n const client = getSharedClient(config);\n const path = opts?.wait ? '/sandboxes/kill-many' : '/sandboxes/kill-many?async=true';\n const data = (await client.post(path, {\n json: { sandbox_ids: ids },\n timeout: opts?.requestTimeout,\n })) as { results?: Record<string, { killed?: boolean; queued?: boolean; error?: string }> };\n return data.results ?? {};\n }\n\n /**\n * Kill a sandbox by id without first connecting. Sends a single\n * `DELETE /sandboxes/:id?async=true` and skips the metadata fetch\n * `Sandbox.connect(id).kill()` would otherwise pay. Useful for bulk\n * cleanup paths that only have the id.\n *\n * @param sandboxId - the sandbox to kill.\n * @param opts.wait - if true, block until the server finishes the\n * per-VM teardown. Default is false: server returns 202 once the\n * kill is queued.\n * @param opts.requestTimeout - per-request timeout in milliseconds.\n * @param opts.config - override the default ConnectionConfig.\n * @returns true if the kill was accepted (default) or completed\n * (wait=true); false if the server reported the sandbox was\n * already dead.\n */\n static async kill(\n sandboxId: string,\n opts?: { wait?: boolean; requestTimeout?: number; config?: ConnectionConfig },\n ): Promise<boolean> {\n const config = opts?.config ?? new ConnectionConfig();\n const client = getSharedClient(config);\n const wait = opts?.wait === true;\n const path = wait\n ? `/sandboxes/${sandboxId}`\n : `/sandboxes/${sandboxId}?async=true`;\n const data = (await client.delete(path, {\n timeout: opts?.requestTimeout,\n })) as Record<string, unknown>;\n if (!wait) return (data.queued as boolean) ?? true;\n return (data.killed as boolean) ?? false;\n }\n\n /**\n * Check if this sandbox is currently running.\n *\n * @param requestTimeout - Optional per-request timeout in milliseconds.\n * @returns True if the sandbox is running.\n */\n async isRunning(requestTimeout?: number): Promise<boolean> {\n const data = (await this._client.get(`/sandboxes/${this._sandboxId}/status`, {\n timeout: requestTimeout,\n })) as Record<string, unknown>;\n return (data.is_running as boolean) ?? false;\n }\n\n /**\n * Set the timeout for this sandbox.\n *\n * @param timeout - New timeout in seconds.\n * @param requestTimeout - Optional per-request timeout in milliseconds.\n */\n async setTimeout(timeout: number, requestTimeout?: number): Promise<void> {\n await this._client.patch(`/sandboxes/${this._sandboxId}/timeout`, {\n json: { timeout },\n timeout: requestTimeout,\n });\n }\n\n /**\n * Get information about this sandbox.\n *\n * @param requestTimeout - Optional per-request timeout in milliseconds.\n * @returns Parsed sandbox information.\n */\n async getInfo(requestTimeout?: number): Promise<SandboxInfo> {\n const data = (await this._client.get(`/sandboxes/${this._sandboxId}`, {\n timeout: requestTimeout,\n })) as Record<string, unknown>;\n return parseSandboxInfo(data);\n }\n\n /**\n * Get metrics for this sandbox.\n *\n * @param opts - Optional start/end date range and request timeout.\n * @returns Array of parsed sandbox metrics.\n */\n async getMetrics(opts?: {\n start?: Date;\n end?: Date;\n requestTimeout?: number;\n }): Promise<SandboxMetrics[]> {\n const params: Record<string, string> = {};\n if (opts?.start) {\n params.start = opts.start.toISOString();\n }\n if (opts?.end) {\n params.end = opts.end.toISOString();\n }\n\n const data = (await this._client.get(`/sandboxes/${this._sandboxId}/metrics`, {\n params,\n timeout: opts?.requestTimeout,\n })) as Record<string, unknown>[] | null;\n\n return (data ?? []).map((m) => parseSandboxMetrics(m));\n }\n\n /**\n * Pause this sandbox.\n *\n * @param requestTimeout - Optional per-request timeout in milliseconds.\n */\n async pause(requestTimeout?: number): Promise<void> {\n await this._client.post(`/sandboxes/${this._sandboxId}/pause`, {\n timeout: requestTimeout,\n });\n }\n\n /**\n * Resume a paused sandbox.\n *\n * @param requestTimeout - Optional per-request timeout in milliseconds.\n */\n async resume(requestTimeout?: number): Promise<void> {\n await this._client.post(`/sandboxes/${this._sandboxId}/resume`, {\n timeout: requestTimeout,\n });\n }\n\n /**\n * Create a snapshot of this sandbox.\n *\n * @param requestTimeout - Optional per-request timeout in milliseconds.\n * @returns Parsed snapshot information.\n */\n async createSnapshot(requestTimeout?: number): Promise<SnapshotInfo> {\n const data = (await this._client.post(`/sandboxes/${this._sandboxId}/snapshot`, {\n timeout: requestTimeout,\n })) as Record<string, unknown>;\n return parseSnapshotInfo(data);\n }\n\n /**\n * Create a manual snapshot of this sandbox.\n *\n * Manual snapshots accumulate — every call creates a new persistent\n * checkpoint that survives sandbox.kill(). Use Sandbox.listSnapshots()\n * to retrieve them and Sandbox.restore(sandboxId, { snapshotId }) to fork from one.\n *\n * @param requestTimeout - Optional per-request timeout in milliseconds.\n * @returns Parsed Snapshot metadata including the snapshot_id.\n */\n async snapshot(requestTimeout?: number): Promise<Snapshot> {\n const data = (await this._client.post(`/sandboxes/${this._sandboxId}/snapshot`, {\n json: {},\n timeout: requestTimeout,\n })) as Record<string, unknown>;\n return parseSnapshot(data);\n }\n\n /**\n * List all snapshots (periodic + pause + manual) for this sandbox, newest first.\n *\n * @param requestTimeout - Optional per-request timeout in milliseconds.\n * @returns Array of Snapshot metadata objects.\n */\n async listSnapshots(requestTimeout?: number): Promise<Snapshot[]> {\n const data = (await this._client.get(`/sandboxes/${this._sandboxId}/snapshots`, {\n timeout: requestTimeout,\n })) as Record<string, unknown>;\n const raw = (data.snapshots ?? []) as Record<string, unknown>[];\n return raw.map((s) => parseSnapshot(s));\n }\n\n /**\n * Delete a single snapshot of this sandbox by ID.\n *\n * The snapshot's PG row and S3 blobs (mem / vmstate / overlay) are\n * removed. Idempotent: deleting an already-deleted snapshot resolves to\n * true without throwing.\n *\n * The pause snapshot of a currently-paused sandbox is protected — the\n * server returns 409 because deletion would break Resume. Resume or\n * kill the sandbox first.\n *\n * @param snapshotId - The snapshot to delete.\n * @param requestTimeout - Optional per-request timeout in milliseconds.\n * @returns True on success.\n */\n async deleteSnapshot(snapshotId: string, requestTimeout?: number): Promise<boolean> {\n await this._client.delete(`/sandboxes/${this._sandboxId}/snapshots/${snapshotId}`, {\n timeout: requestTimeout,\n });\n return true;\n }\n\n /**\n * Restore a sandbox from a snapshot. The restored instance may run on a\n * different worker node than the original sandbox.\n *\n * @param sandboxId - The sandbox to restore.\n * @param options.snapshotId - Optional snapshot to restore from. If omitted,\n * sandbox-manager picks the most recent snapshot (pause > periodic > manual).\n * @param options.apiKey - Optional API key override.\n * @param options.domain - Optional domain override.\n * @param options.requestTimeout - Optional per-request timeout in milliseconds.\n * @returns A new Sandbox instance connected to the restored sandbox.\n */\n static async restore(\n sandboxId: string,\n options: { snapshotId?: string; apiKey?: string; domain?: string; apiUrl?: string; requestTimeout?: number } = {},\n ): Promise<Sandbox> {\n assertValidId(sandboxId, 'sandbox ID');\n const config = new ConnectionConfig({\n apiKey: options.apiKey,\n domain: options.domain,\n apiUrl: options.apiUrl,\n requestTimeout: options.requestTimeout,\n });\n const client = getSharedClient(config);\n\n const query = options.snapshotId ? `?snapshot_id=${encodeURIComponent(options.snapshotId)}` : '';\n await client.post(`/sandboxes/${sandboxId}/restore${query}`, {\n timeout: options.requestTimeout,\n });\n\n // Fetch current sandbox state so the returned Sandbox is fully populated.\n const data = (await client.get(`/sandboxes/${sandboxId}`, {\n timeout: options.requestTimeout,\n })) as Record<string, unknown>;\n\n return new Sandbox(\n data.sandbox_id as string,\n config,\n client,\n data.envd_access_token as string | undefined,\n data.sandbox_domain as string | undefined,\n data.traffic_access_token as string | undefined,\n );\n }\n\n /**\n * Historically closed the sandbox's HTTP client; since 1.1.1 the SDK\n * maintains a process-wide shared ApiClient (see `getSharedClient` in\n * api/client.ts) so per-sandbox close no longer tears the connection\n * pool down. Kept as a no-op for backwards compatibility — call\n * `resetSharedClients()` if you want to force a full teardown.\n */\n close(): void {\n // no-op\n }\n\n /**\n * Support `await using sandbox = await Sandbox.create(...)` for automatic cleanup.\n */\n async [Symbol.asyncDispose](): Promise<void> {\n this.close();\n }\n}\n\n/** Convert SandboxNetworkOpts to snake_case JSON for the API. */\nfunction networkOptsToJSON(opts: SandboxNetworkOpts): Record<string, unknown> {\n const result: Record<string, unknown> = {\n allow_out: opts.allowOut,\n deny_out: opts.denyOut,\n allow_public_traffic: opts.allowPublicTraffic,\n };\n if (opts.maskRequestHost !== undefined) {\n result.mask_request_host = opts.maskRequestHost;\n }\n return result;\n}\n\n/** Convert SandboxLifecycle to snake_case JSON for the API. */\nfunction lifecycleToJSON(lifecycle: SandboxLifecycle): Record<string, unknown> {\n return {\n on_timeout: lifecycle.onTimeout,\n auto_resume: lifecycle.autoResume,\n };\n}\n","import { ApiClient } from './api/client.js';\nimport { SandboxError } from './errors.js';\nimport type { SandboxInfo, SnapshotInfo } from './sandbox/models.js';\nimport { parseSandboxInfo, parseSnapshotInfo } from './sandbox/models.js';\n\n/**\n * Paginator for listing sandboxes.\n *\n * Supports manual pagination via `nextItems()` and automatic iteration\n * via `for await (const page of paginator)`.\n */\nexport class SandboxPaginator {\n private readonly client: ApiClient;\n private readonly query: Record<string, string>;\n private readonly limit?: number;\n private _nextToken: string | undefined;\n private _exhausted = false;\n\n constructor(\n client: ApiClient,\n opts?: { query?: Record<string, string>; limit?: number },\n ) {\n this.client = client;\n this.query = opts?.query ?? {};\n this.limit = opts?.limit;\n }\n\n /** Whether there are more pages to fetch. */\n get hasNext(): boolean {\n return !this._exhausted;\n }\n\n /**\n * Fetch the next page of sandboxes.\n *\n * @throws SandboxError when no more pages are available.\n */\n async nextItems(): Promise<SandboxInfo[]> {\n if (this._exhausted) {\n throw new SandboxError('No more pages');\n }\n\n const params: Record<string, string> = { ...this.query };\n if (this.limit !== undefined) {\n params.limit = String(this.limit);\n }\n if (this._nextToken) {\n params.next_token = this._nextToken;\n }\n\n const data = await this.client.get('/sandboxes', { params });\n const response = data as Record<string, unknown>;\n const rawSandboxes = (response.sandboxes ?? []) as Record<string, unknown>[];\n const nextToken = response.next_token as string | null;\n\n if (nextToken) {\n this._nextToken = nextToken;\n } else {\n this._exhausted = true;\n this._nextToken = undefined;\n }\n\n return rawSandboxes.map((raw) => parseSandboxInfo(raw));\n }\n\n /** Async iterator that yields pages until exhausted. */\n async *[Symbol.asyncIterator](): AsyncIterator<SandboxInfo[]> {\n while (this.hasNext) {\n yield await this.nextItems();\n }\n }\n}\n\n/**\n * Paginator for listing snapshots.\n *\n * Supports manual pagination via `nextItems()` and automatic iteration\n * via `for await (const page of paginator)`.\n */\nexport class SnapshotPaginator {\n private readonly client: ApiClient;\n private readonly sandboxId?: string;\n private readonly limit?: number;\n private _nextToken: string | undefined;\n private _exhausted = false;\n\n constructor(\n client: ApiClient,\n opts?: { sandboxId?: string; limit?: number },\n ) {\n this.client = client;\n this.sandboxId = opts?.sandboxId;\n this.limit = opts?.limit;\n }\n\n /** Whether there are more pages to fetch. */\n get hasNext(): boolean {\n return !this._exhausted;\n }\n\n /**\n * Fetch the next page of snapshots.\n *\n * @throws SandboxError when no more pages are available.\n */\n async nextItems(): Promise<SnapshotInfo[]> {\n if (this._exhausted) {\n throw new SandboxError('No more pages');\n }\n\n const params: Record<string, string> = {};\n if (this.sandboxId) {\n params.sandbox_id = this.sandboxId;\n }\n if (this.limit !== undefined) {\n params.limit = String(this.limit);\n }\n if (this._nextToken) {\n params.next_token = this._nextToken;\n }\n\n const data = await this.client.get('/snapshots', { params });\n const response = data as Record<string, unknown>;\n const rawSnapshots = (response.snapshots ?? []) as Record<string, unknown>[];\n const nextToken = response.next_token as string | null;\n\n if (nextToken) {\n this._nextToken = nextToken;\n } else {\n this._exhausted = true;\n this._nextToken = undefined;\n }\n\n return rawSnapshots.map((raw) => parseSnapshotInfo(raw));\n }\n\n /** Async iterator that yields pages until exhausted. */\n async *[Symbol.asyncIterator](): AsyncIterator<SnapshotInfo[]> {\n while (this.hasNext) {\n yield await this.nextItems();\n }\n }\n}\n","/** An item to copy into a template. */\nexport interface CopyItem {\n src: string;\n dst: string;\n mode?: number;\n}\n\n/**\n * Fluent builder for template definitions.\n */\nexport class TemplateBase {\n private _baseImage: string = 'ubuntu:22.04';\n private _runCmds: string[][] = [];\n private _copies: CopyItem[] = [];\n private _envs: Record<string, string> = {};\n private _aptPackages: string[] = [];\n private _startCmd?: string;\n /**\n * When set, the server uses this Dockerfile verbatim and ignores the\n * structured fields. Use for multi-stage builds, ARG, ONBUILD, etc.\n */\n private _dockerfile?: string;\n\n /** Set the base image for the template. */\n fromBaseImage(image?: string): this {\n this._baseImage = image ?? 'ubuntu:22.04';\n return this;\n }\n\n /**\n * Use a raw Dockerfile string instead of the structured helpers.\n *\n * When set, all other ``aptInstall`` / ``runCmd`` / ``setEnvs`` /\n * ``copy`` / ``setStartCmd`` / ``fromBaseImage`` calls on this spec\n * are ignored — the Dockerfile is sent to the build worker verbatim.\n *\n * @param content Full Dockerfile contents. Must contain a ``FROM``\n * instruction. Capped server-side at 64 KiB.\n */\n fromDockerfile(content: string): this {\n this._dockerfile = content;\n return this;\n }\n\n /** Add a run command (as array of command + args). */\n runCmd(cmds: string[]): this {\n this._runCmds.push(cmds);\n return this;\n }\n\n /** Add a file copy operation. */\n copy(src: string, dst: string, mode?: number): this {\n this._copies.push({ src, dst, mode });\n return this;\n }\n\n /** Set environment variables. */\n setEnvs(envs: Record<string, string>): this {\n this._envs = { ...this._envs, ...envs };\n return this;\n }\n\n /** Install apt packages. */\n aptInstall(...packages: string[]): this {\n this._aptPackages.push(...packages);\n return this;\n }\n\n /** Set the start command. */\n setStartCmd(cmd: string): this {\n this._startCmd = cmd;\n return this;\n }\n\n /** Serialize the template to a JSON-friendly object. */\n toJSON(): Record<string, any> {\n // Raw Dockerfile path: send only the dockerfile field; the server\n // ignores helpers when this is set.\n if (this._dockerfile !== undefined) {\n return { dockerfile: this._dockerfile };\n }\n const result: Record<string, any> = {\n base_image: this._baseImage,\n };\n\n if (this._runCmds.length > 0) {\n // Server expects each run_cmd as a single shell line. Accept both\n // ``runCmd([\"pip3 install x\"])`` and\n // ``runCmd([\"pip3\", \"install\", \"x\"])`` and space-join so both\n // serialize the same on the wire. (#233)\n result.run_cmds = this._runCmds.map((c) => c.join(' '));\n }\n\n if (this._copies.length > 0) {\n result.copies = this._copies;\n }\n\n if (Object.keys(this._envs).length > 0) {\n result.envs = this._envs;\n }\n\n if (this._aptPackages.length > 0) {\n result.apt_packages = this._aptPackages;\n }\n\n if (this._startCmd !== undefined) {\n result.start_cmd = this._startCmd;\n }\n\n return result;\n }\n}\n\n/** Information about a template build. */\nexport interface BuildInfo {\n buildId: string;\n status: string;\n templateId?: string;\n}\n\n/** Parse raw JSON data into BuildInfo. */\nexport function parseBuildInfo(data: Record<string, any>): BuildInfo {\n return {\n buildId: data.build_id ?? data.buildId ?? '',\n status: data.status ?? '',\n templateId: data.template_id ?? data.templateId ?? undefined,\n };\n}\n\n/** Status of a template build. */\nexport interface TemplateBuildStatus {\n buildId: string;\n status: string;\n logs: string[];\n}\n\n/** Parse raw JSON data into TemplateBuildStatus. */\nexport function parseTemplateBuildStatus(data: Record<string, any>): TemplateBuildStatus {\n return {\n buildId: data.build_id ?? data.buildId ?? '',\n status: data.status ?? '',\n logs: data.logs ?? [],\n };\n}\n","import { ConnectionConfig } from '../connectionConfig.js';\nimport { getSharedClient } from '../api/client.js';\nimport { InvalidArgumentError } from '../errors.js';\nimport type { TemplateBase } from './models.js';\nimport type { BuildInfo, TemplateBuildStatus } from './models.js';\nimport { parseBuildInfo, parseTemplateBuildStatus } from './models.js';\n\nconst VALID_BUILD_ID_RE = /^[a-zA-Z0-9_-]+$/;\n\n/** Validate that a build ID is safe for URL path interpolation. */\nfunction assertValidBuildId(buildId: string): void {\n if (!buildId || !VALID_BUILD_ID_RE.test(buildId)) {\n throw new InvalidArgumentError(\n `Invalid build ID: \"${buildId}\". Must be alphanumeric with hyphens/underscores only.`,\n );\n }\n}\n\n/** Options for Template.build() and Template.buildInBackground(). */\nexport interface TemplateBuildOpts {\n /** Number of CPUs for the build. */\n cpuCount?: number;\n /** Memory in MB for the build. */\n memoryMb?: number;\n /** Disk size in MB for the build (128–102400). */\n diskMb?: number;\n /** Callback invoked for each build log entry. */\n onBuildLogs?: (log: string) => void;\n /** API key override. */\n apiKey?: string;\n /** Domain override. */\n domain?: string;\n /** Per-request timeout in milliseconds. */\n requestTimeout?: number;\n}\n\n/** Options for Template.getBuildStatus(). */\nexport interface GetBuildStatusOpts {\n /** API key override. */\n apiKey?: string;\n /** Domain override. */\n domain?: string;\n /** Per-request timeout in milliseconds. */\n requestTimeout?: number;\n}\n\n/**\n * Template management.\n *\n * All methods are static and create their own temporary ApiClient,\n * ensuring the client is always closed via try/finally (fixing Python SDK's client leak).\n */\nexport class Template {\n /**\n * Build a template and wait for completion.\n *\n * Sends POST /templates/build with the template definition.\n * Invokes onBuildLogs for each log entry in the response.\n */\n static async build(\n template: TemplateBase,\n alias: string,\n opts?: TemplateBuildOpts,\n ): Promise<BuildInfo> {\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n\n const body: Record<string, unknown> = {\n template: template.toJSON(),\n alias,\n };\n\n if (opts?.cpuCount !== undefined) {\n body.cpu_count = opts.cpuCount;\n }\n if (opts?.memoryMb !== undefined) {\n body.memory_mb = opts.memoryMb;\n }\n if (opts?.diskMb !== undefined) {\n body.disk_mb = opts.diskMb;\n }\n\n const data = await client.post('/templates/build', {\n json: body,\n timeout: opts?.requestTimeout,\n });\n\n const response = data as Record<string, unknown>;\n const result = parseBuildInfo(response);\n\n // Invoke log callback if provided\n if (opts?.onBuildLogs && Array.isArray(response.logs)) {\n for (const log of response.logs as string[]) {\n opts.onBuildLogs(log);\n }\n }\n\n return result;\n }\n\n /**\n * Start a template build in the background.\n *\n * Sends POST /templates/build with `background: true`.\n */\n static async buildInBackground(\n template: TemplateBase,\n alias: string,\n opts?: Omit<TemplateBuildOpts, 'onBuildLogs'>,\n ): Promise<BuildInfo> {\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n\n const body: Record<string, unknown> = {\n template: template.toJSON(),\n alias,\n background: true,\n };\n\n if (opts?.cpuCount !== undefined) {\n body.cpu_count = opts.cpuCount;\n }\n if (opts?.memoryMb !== undefined) {\n body.memory_mb = opts.memoryMb;\n }\n if (opts?.diskMb !== undefined) {\n body.disk_mb = opts.diskMb;\n }\n\n const data = await client.post('/templates/build', {\n json: body,\n timeout: opts?.requestTimeout,\n });\n\n return parseBuildInfo(data as Record<string, unknown>);\n }\n\n /**\n * Get the status of a template build.\n *\n * Sends GET /templates/builds/:buildId.\n */\n static async getBuildStatus(\n buildId: string,\n opts?: GetBuildStatusOpts,\n ): Promise<TemplateBuildStatus> {\n assertValidBuildId(buildId);\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n\n const data = await client.get(`/templates/builds/${buildId}`, {\n timeout: opts?.requestTimeout,\n });\n\n return parseTemplateBuildStatus(data as Record<string, unknown>);\n }\n}\n","import { ConnectionConfig } from '../connectionConfig.js';\nimport { getSharedClient } from '../api/client.js';\nimport { InvalidArgumentError } from '../errors.js';\nimport type { FileEntry, FileInfo } from './models.js';\nimport { parseFileEntry, parseFileInfo } from './models.js';\nimport type { VolumeRequestOpts } from './types.js';\n\nconst VALID_VOLUME_ID_RE = /^[a-zA-Z0-9_-]+$/;\n\nfunction assertValidVolumeId(id: string): void {\n if (!id || !VALID_VOLUME_ID_RE.test(id)) {\n throw new InvalidArgumentError(\n `Invalid volume ID: \"${id}\". Must be alphanumeric with hyphens/underscores only.`,\n );\n }\n}\n\n/** Options for VolumeFiles.write. */\nexport interface VolumeWriteOpts extends VolumeRequestOpts {\n /**\n * CAS token from `info(path).version`. When set, the server rejects the\n * write with a ConflictError (409) if the file changed since the token was\n * read. Omit for an unconditional write.\n */\n ifVersion?: string;\n}\n\n/** Options for VolumeFiles.remove. */\nexport interface VolumeRemoveOpts extends VolumeRequestOpts {\n /** Recursively remove a directory and its contents. */\n recursive?: boolean;\n}\n\n/**\n * File-granular operations on a single volume.\n *\n * Only valid for file-granular (non-tarball) volumes — the server returns\n * a ConflictError (409) for a tarball-backed volume and a 503 when no\n * file-granular accessor is configured. Obtain an instance via\n * `Volumes.files(volumeId)`.\n */\nexport class VolumeFiles {\n private readonly volumeId: string;\n private readonly opts?: VolumeRequestOpts;\n\n constructor(volumeId: string, opts?: VolumeRequestOpts) {\n assertValidVolumeId(volumeId);\n this.volumeId = volumeId;\n this.opts = opts;\n }\n\n private client() {\n const config = new ConnectionConfig({\n apiKey: this.opts?.apiKey,\n domain: this.opts?.domain,\n apiUrl: this.opts?.apiUrl,\n requestTimeout: this.opts?.requestTimeout,\n });\n return getSharedClient(config);\n }\n\n private timeout(): number | undefined {\n return this.opts?.requestTimeout;\n }\n\n /** Write raw bytes to `path`. Optionally conditional on `ifVersion` (CAS). */\n async write(\n path: string,\n data: Uint8Array | ArrayBuffer,\n opts?: VolumeWriteOpts,\n ): Promise<string> {\n if (!path) {\n throw new InvalidArgumentError('path is required');\n }\n const params: Record<string, string> = { path };\n if (opts?.ifVersion) {\n params.if_version = opts.ifVersion;\n }\n const body = data instanceof Uint8Array ? data : new Uint8Array(data);\n const resp = (await this.client().put(`/volumes/${this.volumeId}/files/raw`, {\n params,\n body,\n headers: { 'Content-Type': 'application/octet-stream' },\n timeout: opts?.requestTimeout ?? this.timeout(),\n })) as Record<string, unknown>;\n return String(resp.path ?? path);\n }\n\n /** Read raw bytes from `path`. */\n async read(path: string): Promise<Uint8Array> {\n if (!path) {\n throw new InvalidArgumentError('path is required');\n }\n return this.client().getBytes(`/volumes/${this.volumeId}/files/raw`, {\n params: { path },\n timeout: this.timeout(),\n });\n }\n\n /** List directory entries under `path`. */\n async list(path: string): Promise<FileEntry[]> {\n if (!path) {\n throw new InvalidArgumentError('path is required');\n }\n const resp = (await this.client().get(`/volumes/${this.volumeId}/files/list`, {\n params: { path },\n timeout: this.timeout(),\n })) as Record<string, unknown>;\n const rows = (resp.entries as Record<string, unknown>[] | undefined) ?? [];\n return rows.map(parseFileEntry);\n }\n\n /** Stat `path`, returning the entry plus the CAS `version` token. */\n async info(path: string): Promise<FileInfo> {\n if (!path) {\n throw new InvalidArgumentError('path is required');\n }\n const resp = (await this.client().get(`/volumes/${this.volumeId}/files/info`, {\n params: { path },\n timeout: this.timeout(),\n })) as Record<string, unknown>;\n return parseFileInfo(resp);\n }\n\n /** Return whether `path` exists. */\n async exists(path: string): Promise<boolean> {\n if (!path) {\n throw new InvalidArgumentError('path is required');\n }\n const resp = (await this.client().get(`/volumes/${this.volumeId}/files/exists`, {\n params: { path },\n timeout: this.timeout(),\n })) as Record<string, unknown>;\n return Boolean(resp.exists ?? false);\n }\n\n /** Remove `path`. Pass `{ recursive: true }` to remove a directory tree. */\n async remove(path: string, opts?: VolumeRemoveOpts): Promise<void> {\n if (!path) {\n throw new InvalidArgumentError('path is required');\n }\n const params: Record<string, string> = {\n path,\n recursive: opts?.recursive ? 'true' : 'false',\n };\n await this.client().delete(`/volumes/${this.volumeId}/files`, {\n params,\n timeout: opts?.requestTimeout ?? this.timeout(),\n });\n }\n\n /** Rename `oldPath` to `newPath`. */\n async rename(oldPath: string, newPath: string): Promise<{ oldPath: string; newPath: string }> {\n if (!oldPath || !newPath) {\n throw new InvalidArgumentError('oldPath and newPath are required');\n }\n const resp = (await this.client().patch(`/volumes/${this.volumeId}/files`, {\n json: { old_path: oldPath, new_path: newPath },\n timeout: this.timeout(),\n })) as Record<string, unknown>;\n return {\n oldPath: String(resp.old_path ?? oldPath),\n newPath: String(resp.new_path ?? newPath),\n };\n }\n\n /** Create a directory at `path`. */\n async mkdir(path: string): Promise<string> {\n if (!path) {\n throw new InvalidArgumentError('path is required');\n }\n const resp = (await this.client().post(`/volumes/${this.volumeId}/files/mkdir`, {\n json: { path },\n timeout: this.timeout(),\n })) as Record<string, unknown>;\n return String(resp.path ?? path);\n }\n}\n","import { ConnectionConfig } from '../connectionConfig.js';\nimport { getSharedClient } from '../api/client.js';\nimport { InvalidArgumentError } from '../errors.js';\nimport type { LockLease, LockStatus } from './models.js';\nimport { parseLockLease, parseLockStatus } from './models.js';\nimport type { VolumeRequestOpts } from './types.js';\n\nconst VALID_VOLUME_ID_RE = /^[a-zA-Z0-9_-]+$/;\n\nfunction assertValidVolumeId(id: string): void {\n if (!id || !VALID_VOLUME_ID_RE.test(id)) {\n throw new InvalidArgumentError(\n `Invalid volume ID: \"${id}\". Must be alphanumeric with hyphens/underscores only.`,\n );\n }\n}\n\n/**\n * Advisory locks (leases) over a (volume, path) pair.\n *\n * Acquire returns a token; renew/release require it. A ConflictError (409)\n * is raised on acquire when the path is already locked, and on renew/release\n * when the caller is not the current holder. Obtain an instance via\n * `Volumes.locks(volumeId)`.\n */\nexport class VolumeLocks {\n private readonly volumeId: string;\n private readonly opts?: VolumeRequestOpts;\n\n constructor(volumeId: string, opts?: VolumeRequestOpts) {\n assertValidVolumeId(volumeId);\n this.volumeId = volumeId;\n this.opts = opts;\n }\n\n private client() {\n const config = new ConnectionConfig({\n apiKey: this.opts?.apiKey,\n domain: this.opts?.domain,\n apiUrl: this.opts?.apiUrl,\n requestTimeout: this.opts?.requestTimeout,\n });\n return getSharedClient(config);\n }\n\n private timeout(): number | undefined {\n return this.opts?.requestTimeout;\n }\n\n /** Acquire a lock on `path`. Throws ConflictError (409) if already held. */\n async acquire(path: string, ttlSeconds?: number): Promise<LockLease> {\n if (!path) {\n throw new InvalidArgumentError('path is required');\n }\n const json: Record<string, unknown> = { path };\n if (ttlSeconds !== undefined) {\n json.ttl_seconds = ttlSeconds;\n }\n const resp = (await this.client().post(`/volumes/${this.volumeId}/locks`, {\n json,\n timeout: this.timeout(),\n })) as Record<string, unknown>;\n return parseLockLease(resp);\n }\n\n /** Release a lock on `path` held under `token`. Throws ConflictError (409) if not the holder. */\n async release(path: string, token: string): Promise<boolean> {\n if (!path || !token) {\n throw new InvalidArgumentError('path and token are required');\n }\n const resp = (await this.client().delete(`/volumes/${this.volumeId}/locks`, {\n json: { path, token },\n timeout: this.timeout(),\n })) as Record<string, unknown>;\n return Boolean(resp.released ?? false);\n }\n\n /** Renew a lock on `path` held under `token`. Throws ConflictError (409) if not the holder. */\n async renew(path: string, token: string, ttlSeconds?: number): Promise<LockLease> {\n if (!path || !token) {\n throw new InvalidArgumentError('path and token are required');\n }\n const json: Record<string, unknown> = { path, token };\n if (ttlSeconds !== undefined) {\n json.ttl_seconds = ttlSeconds;\n }\n const resp = (await this.client().post(`/volumes/${this.volumeId}/locks/renew`, {\n json,\n timeout: this.timeout(),\n })) as Record<string, unknown>;\n // The server's renew response carries {renewed, ttl_seconds, expires_at} but\n // NOT the token (the caller already holds it). Echo the caller's token so the\n // returned lease is complete.\n return { ...parseLockLease(resp), token };\n }\n\n /** Query whether `path` is currently locked. */\n async status(path: string): Promise<LockStatus> {\n if (!path) {\n throw new InvalidArgumentError('path is required');\n }\n const resp = (await this.client().get(`/volumes/${this.volumeId}/locks`, {\n params: { path },\n timeout: this.timeout(),\n })) as Record<string, unknown>;\n return parseLockStatus(resp);\n }\n}\n","import { ConnectionConfig } from '../connectionConfig.js';\nimport { getSharedClient } from '../api/client.js';\nimport { InvalidArgumentError } from '../errors.js';\nimport type { VolumeInfo } from './models.js';\nimport { parseVolumeInfo } from './models.js';\nimport type { VolumeRequestOpts } from './types.js';\nimport { VolumeFiles } from './files.js';\nimport { VolumeLocks } from './locks.js';\n\nconst VALID_VOLUME_ID_RE = /^[a-zA-Z0-9_-]+$/;\n\nfunction assertValidVolumeId(id: string): void {\n if (!id || !VALID_VOLUME_ID_RE.test(id)) {\n throw new InvalidArgumentError(\n `Invalid volume ID: \"${id}\". Must be alphanumeric with hyphens/underscores only.`,\n );\n }\n}\n\nexport type { VolumeRequestOpts } from './types.js';\n\n/** Options for Volumes.create / ingest. */\nexport interface VolumeCreateOpts extends VolumeRequestOpts {\n /** Override the Content-Type header. Defaults to application/gzip. */\n contentType?: string;\n}\n\n/**\n * Volumes: upload a tarball once and attach it to one or many sandboxes,\n * or create file-granular volumes that support per-file read/write,\n * compare-and-swap (CAS), and advisory locks.\n *\n * Phase 1 (tarball backend): the body must be a gzip-compressed tar archive;\n * the server materializes regular-file entries inside the sandbox filesystem\n * under the attachment's mount_path. Symlinks, hardlinks, and device nodes\n * are dropped on the server for safety.\n */\nexport class Volumes {\n /** Create a volume by streaming a tarball (gzip tar.gz) to the server. */\n static async create(\n name: string,\n data: Uint8Array | ArrayBuffer,\n opts?: VolumeCreateOpts,\n ): Promise<VolumeInfo> {\n if (!name) {\n throw new InvalidArgumentError('volume name is required');\n }\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n apiUrl: opts?.apiUrl,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n const body = data instanceof Uint8Array ? data : new Uint8Array(data);\n const resp = (await client.post('/volumes', {\n params: { name },\n body,\n headers: { 'Content-Type': opts?.contentType ?? 'application/gzip' },\n timeout: opts?.requestTimeout,\n })) as Record<string, unknown>;\n return parseVolumeInfo(resp);\n }\n\n /**\n * Capture the attached volume's mount path in `sandboxId` into a NEW volume.\n *\n * The source volume is left unchanged. If `name` is omitted the server names\n * the new volume \"<source-name>-commit\". Returns the new VolumeInfo.\n */\n static async commit(\n sandboxId: string,\n volumeId: string,\n name?: string,\n opts?: VolumeRequestOpts,\n ): Promise<VolumeInfo> {\n if (!sandboxId || !VALID_VOLUME_ID_RE.test(sandboxId)) {\n throw new InvalidArgumentError(\n `Invalid sandbox ID: \"${sandboxId}\". Must be alphanumeric with hyphens/underscores only.`,\n );\n }\n assertValidVolumeId(volumeId);\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n apiUrl: opts?.apiUrl,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n const resp = (await client.post(`/sandboxes/${sandboxId}/volumes/${volumeId}/commit`, {\n params: name ? { name } : undefined,\n timeout: opts?.requestTimeout,\n })) as Record<string, unknown>;\n return parseVolumeInfo(resp);\n }\n\n /**\n * Snapshot an arbitrary absolute in-sandbox `path` into a NEW volume.\n *\n * Unlike `commit` (which captures an already-attached volume's mount path),\n * `snapshot` captures any path in the running sandbox. `name` defaults to\n * \"snapshot\" on the server. Synthetic paths (/proc, /sys, /dev) are rejected.\n */\n static async snapshot(\n sandboxId: string,\n path: string,\n name?: string,\n opts?: VolumeRequestOpts,\n ): Promise<VolumeInfo> {\n if (!sandboxId || !VALID_VOLUME_ID_RE.test(sandboxId)) {\n throw new InvalidArgumentError(\n `Invalid sandbox ID: \"${sandboxId}\". Must be alphanumeric with hyphens/underscores only.`,\n );\n }\n if (!path) {\n throw new InvalidArgumentError('path is required');\n }\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n apiUrl: opts?.apiUrl,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n const params: Record<string, string> = { path };\n if (name) {\n params.name = name;\n }\n const resp = (await client.post(`/sandboxes/${sandboxId}/volumes/snapshot`, {\n params,\n timeout: opts?.requestTimeout,\n })) as Record<string, unknown>;\n return parseVolumeInfo(resp);\n }\n\n /**\n * Create an empty file-granular volume. Requires a file-granular backend\n * (503 if not configured). Returns the new VolumeInfo.\n */\n static async empty(name: string, opts?: VolumeRequestOpts): Promise<VolumeInfo> {\n if (!name) {\n throw new InvalidArgumentError('volume name is required');\n }\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n apiUrl: opts?.apiUrl,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n const resp = (await client.post('/volumes/empty', {\n params: { name },\n timeout: opts?.requestTimeout,\n })) as Record<string, unknown>;\n return parseVolumeInfo(resp);\n }\n\n /**\n * Ingest a gzip tar.gz archive into a NEW file-granular volume. Requires a\n * file-granular backend (503 if not configured). 413 on quota exceeded.\n */\n static async ingest(\n name: string,\n data: Uint8Array | ArrayBuffer,\n opts?: VolumeCreateOpts,\n ): Promise<VolumeInfo> {\n if (!name) {\n throw new InvalidArgumentError('volume name is required');\n }\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n apiUrl: opts?.apiUrl,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n const body = data instanceof Uint8Array ? data : new Uint8Array(data);\n const resp = (await client.post('/volumes/ingest', {\n params: { name },\n body,\n headers: { 'Content-Type': opts?.contentType ?? 'application/gzip' },\n timeout: opts?.requestTimeout,\n })) as Record<string, unknown>;\n return parseVolumeInfo(resp);\n }\n\n /** Fetch metadata for a single volume. */\n static async get(volumeId: string, opts?: VolumeRequestOpts): Promise<VolumeInfo> {\n assertValidVolumeId(volumeId);\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n apiUrl: opts?.apiUrl,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n const resp = (await client.get(`/volumes/${volumeId}`, {\n timeout: opts?.requestTimeout,\n })) as Record<string, unknown>;\n return parseVolumeInfo(resp);\n }\n\n /** List all volumes owned by the caller, newest first. */\n static async list(opts?: VolumeRequestOpts): Promise<VolumeInfo[]> {\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n apiUrl: opts?.apiUrl,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n const resp = (await client.get('/volumes', {\n timeout: opts?.requestTimeout,\n })) as Record<string, unknown>;\n const rows = (resp.volumes as Record<string, unknown>[] | undefined) ?? [];\n return rows.map(parseVolumeInfo);\n }\n\n /** Download the volume's contents as raw bytes (the stored archive/blob). */\n static async download(volumeId: string, opts?: VolumeRequestOpts): Promise<Uint8Array> {\n assertValidVolumeId(volumeId);\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n apiUrl: opts?.apiUrl,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n return client.getBytes(`/volumes/${volumeId}/download`, {\n timeout: opts?.requestTimeout,\n });\n }\n\n /** Delete a volume and its blob. Idempotent on the wire. */\n static async delete(volumeId: string, opts?: VolumeRequestOpts): Promise<void> {\n assertValidVolumeId(volumeId);\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n apiUrl: opts?.apiUrl,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n await client.delete(`/volumes/${volumeId}`, { timeout: opts?.requestTimeout });\n }\n\n /**\n * File-granular operations (read/write/list/info/exists/remove/rename/mkdir,\n * plus CAS via `write(..., { ifVersion })`) on `volumeId`. File-granular\n * volumes only.\n */\n static files(volumeId: string, opts?: VolumeRequestOpts): VolumeFiles {\n return new VolumeFiles(volumeId, opts);\n }\n\n /** Advisory locks (acquire/release/renew/status) over a (volume, path). */\n static locks(volumeId: string, opts?: VolumeRequestOpts): VolumeLocks {\n return new VolumeLocks(volumeId, opts);\n }\n}\n","/** A single enforced control within a governance pack gate. */\nexport interface GovernanceControl {\n /** Control identifier, e.g. \"OWASP-LLM06-ExcessiveAgency\". */\n control: string;\n /** Gate that enforces this control: \"cmd\", \"network\", or \"content\". */\n gate: string;\n /** Human-readable rule description. */\n rule: string;\n /** Remediation playbook / guidance. */\n playbook: string;\n}\n\n/** An advisory (non-enforced) item within a governance pack. */\nexport interface GovernanceAdvisory {\n /** Control identifier this advisory references. */\n control: string;\n /** Explanation of why this control is advisory rather than enforced. */\n reason: string;\n}\n\n/** A governance pack returned by GET /governance/packs or GET /governance/packs/:name. */\nexport interface GovernancePack {\n /** Pack name / slug, e.g. \"owasp-llm-top10\". */\n name: string;\n /** Pack version string, e.g. \"v1\". */\n version: string;\n /** Full framework name, e.g. \"OWASP Top 10 for LLM Applications (2025)\". */\n framework: string;\n /** Human-readable description of what this pack enforces. */\n description: string;\n /** Gates activated by this pack, e.g. [\"cmd\",\"network\",\"content\"]. */\n gates: string[];\n /** Enforced controls within this pack. */\n enforces: GovernanceControl[];\n /** Advisory (non-enforced) controls within this pack. */\n advisory: GovernanceAdvisory[];\n /**\n * Canonical policy reference string, e.g. \"owasp-llm-top10@v1\".\n * Mapped from wire field `policy_ref`.\n */\n policyRef: string;\n /** Whether this pack was seeded (built-in) vs. user-created. */\n seeded: boolean;\n}\n\n/** Parse a raw wire-format governance control into a GovernanceControl. */\nfunction parseGovernanceControl(data: Record<string, unknown>): GovernanceControl {\n return {\n control: String(data.control ?? ''),\n gate: String(data.gate ?? ''),\n rule: String(data.rule ?? ''),\n playbook: String(data.playbook ?? ''),\n };\n}\n\n/** Parse a raw wire-format advisory entry into a GovernanceAdvisory. */\nfunction parseGovernanceAdvisory(data: Record<string, unknown>): GovernanceAdvisory {\n return {\n control: String(data.control ?? ''),\n reason: String(data.reason ?? ''),\n };\n}\n\n/** Parse a raw wire-format pack row into a GovernancePack. */\nexport function parseGovernancePack(data: Record<string, unknown>): GovernancePack {\n const rawEnforces = (data.enforces as Record<string, unknown>[] | null | undefined) ?? [];\n const rawAdvisory = (data.advisory as Record<string, unknown>[] | null | undefined) ?? [];\n\n return {\n name: String(data.name ?? ''),\n version: String(data.version ?? ''),\n framework: String(data.framework ?? ''),\n description: String(data.description ?? ''),\n gates: (data.gates as string[] | null | undefined) ?? [],\n enforces: rawEnforces.map(parseGovernanceControl),\n advisory: rawAdvisory.map(parseGovernanceAdvisory),\n policyRef: String(data.policy_ref ?? data.policyRef ?? ''),\n seeded: Boolean(data.seeded ?? false),\n };\n}\n","import { ConnectionConfig } from '../connectionConfig.js';\nimport { getSharedClient } from '../api/client.js';\nimport { InvalidArgumentError } from '../errors.js';\nimport type { GovernancePack } from './models.js';\nimport { parseGovernancePack } from './models.js';\n\nconst VALID_PACK_NAME_RE = /^[a-zA-Z0-9_-]+$/;\n\nfunction assertValidPackName(name: string): void {\n if (!name || !VALID_PACK_NAME_RE.test(name)) {\n throw new InvalidArgumentError(\n `Invalid pack name: \"${name}\". Must be alphanumeric with hyphens/underscores only.`,\n );\n }\n}\n\n/** Shared per-call options for Governance methods. */\nexport interface GovernanceRequestOpts {\n /** API key override. */\n apiKey?: string;\n /** Domain override. */\n domain?: string;\n /** Full API URL override. */\n apiUrl?: string;\n /** Per-request timeout in milliseconds. */\n requestTimeout?: number;\n}\n\n/**\n * Governance pack discovery.\n *\n * Lists and retrieves governance packs exposed by the Declaw control plane.\n * The /governance/packs endpoint is public — no auth is required — but the\n * SDK's normal Authorization header is still sent when an API key is\n * configured (harmless and consistent with other list methods).\n */\nexport class Governance {\n /**\n * List all available governance packs.\n *\n * Sends GET /governance/packs and returns the `packs` array.\n */\n static async listPacks(opts?: GovernanceRequestOpts): Promise<GovernancePack[]> {\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n apiUrl: opts?.apiUrl,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n const resp = (await client.get('/governance/packs', {\n timeout: opts?.requestTimeout,\n })) as Record<string, unknown>;\n const rows = (resp.packs as Record<string, unknown>[] | undefined) ?? [];\n return rows.map(parseGovernancePack);\n }\n\n /**\n * Fetch a single governance pack by name.\n *\n * Sends GET /governance/packs/:name and returns the pack object.\n * Throws InvalidArgumentError if the name contains unsafe characters.\n */\n static async getPack(name: string, opts?: GovernanceRequestOpts): Promise<GovernancePack> {\n assertValidPackName(name);\n const config = new ConnectionConfig({\n apiKey: opts?.apiKey,\n domain: opts?.domain,\n apiUrl: opts?.apiUrl,\n requestTimeout: opts?.requestTimeout,\n });\n const client = getSharedClient(config);\n const resp = (await client.get(`/governance/packs/${name}`, {\n timeout: opts?.requestTimeout,\n })) as Record<string, unknown>;\n return parseGovernancePack(resp);\n }\n}\n"],"mappings":"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","names":["PIIType","RedactionAction","InjectionSensitivity","InjectionAction","TransformDirection","VALID_ACTIONS","VALID_ACTIONS","VALID_ACTIONS","SandboxState","splitlines","FileType","FilesystemEventType","result","import_stream","VALID_VOLUME_ID_RE","assertValidVolumeId","VALID_VOLUME_ID_RE","assertValidVolumeId"]}
|