@declaw/sdk 1.0.4 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +43 -0
- package/dist/index.cjs +276 -171
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +71 -2
- package/dist/index.d.ts +71 -2
- package/dist/index.js +270 -170
- 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/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/sandbox.ts","../src/paginator.ts","../src/template/models.ts","../src/template/template.ts"],"sourcesContent":["// API Client\nexport { ApiClient } 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 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 - 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// 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 * 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=\"104.198.24.180:8080\" → domain=\"104.198.24.180\", 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/** 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} from '../errors.js';\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 401: AuthenticationError,\n 403: AuthenticationError,\n 404: NotFoundError,\n 408: TimeoutError,\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 this.retryDelay = opts?.retryDelay ?? 0.5;\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 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 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 const response = await fetch(url, {\n method,\n headers,\n body: fetchBody,\n signal,\n });\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 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","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 * Declaw records a fixed set of lifecycle + security events (vm_created,\n * vm_killed, snapshot_*, egress_blocked, …). Set `enabled: false` to opt\n * the sandbox out entirely; events for that sandbox are not shipped to\n * the collector and nothing is persisted.\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","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';\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';\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}\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 };\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\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 };\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 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 as a string.\n *\n * @param path - Absolute path to the file.\n * @param opts - Optional user and request timeout.\n * @returns The file contents as a string.\n */\n async read(\n path: string,\n opts?: { user?: string; requestTimeout?: number },\n ): Promise<string> {\n const user = opts?.user ?? DEFAULT_USER;\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 { ConnectionConfig } from '../connectionConfig.js';\nimport { ApiClient } 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';\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 /** API key override. */\n apiKey?: string;\n /** Domain override (supports \"host:port\" format, e.g. \"104.198.24.180: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\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 }\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 /**\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 * Note: the reverse-proxy backend is not yet deployed; calls to the returned\n * URL will 404 until that feature ships. The URL shape is stable and safe to\n * script against.\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 * Same deployment caveat as {@link getHost}.\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 = new ApiClient(config);\n\n try {\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 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 } catch (error) {\n client.close();\n throw error;\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 = new ApiClient(config);\n\n try {\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 } catch (error) {\n client.close();\n throw error;\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 = new ApiClient(config);\n\n try {\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 } finally {\n client.close();\n }\n }\n\n /**\n * Kill this sandbox.\n *\n * @param requestTimeout - Optional per-request timeout in milliseconds.\n * @returns True if the sandbox was killed, false if it was already dead.\n */\n async kill(requestTimeout?: number): Promise<boolean> {\n const data = (await this._client.delete(`/sandboxes/${this._sandboxId}`, {\n timeout: requestTimeout,\n })) as Record<string, unknown>;\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 * 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 = new ApiClient(config);\n\n try {\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 } catch (error) {\n client.close();\n throw error;\n }\n }\n\n /**\n * Close the underlying HTTP client and release resources.\n */\n close(): void {\n this._client.close();\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 /** 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 /** 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 const result: Record<string, any> = {\n base_image: this._baseImage,\n };\n\n if (this._runCmds.length > 0) {\n result.run_cmds = this._runCmds;\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 { ApiClient } 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 = new ApiClient(config);\n\n try {\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 } finally {\n client.close();\n }\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 = new ApiClient(config);\n\n try {\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 } finally {\n client.close();\n }\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 = new ApiClient(config);\n\n try {\n const data = await client.get(`/templates/builds/${buildId}`, {\n timeout: opts?.requestTimeout,\n });\n\n return parseTemplateBuildStatus(data as Record<string, unknown>);\n } finally {\n client.close();\n }\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"]}
|
|
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/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/volumes/models.ts","../src/sandbox/sandbox.ts","../src/paginator.ts","../src/template/models.ts","../src/template/template.ts","../src/volumes/volumes.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 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 - 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// 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 { VolumeRequestOpts, VolumeCreateOpts } from './volumes/volumes.js';\nexport { parseVolumeInfo, volumeAttachmentToJSON } from './volumes/models.js';\nexport type { VolumeInfo, VolumeAttachment } from './volumes/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=\"104.198.24.180:8080\" → domain=\"104.198.24.180\", 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/** 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} from '../errors.js';\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 401: AuthenticationError,\n 403: AuthenticationError,\n 404: NotFoundError,\n 408: TimeoutError,\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 this.retryDelay = opts?.retryDelay ?? 0.5;\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 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 const response = await fetch(url, {\n method,\n headers,\n body: fetchBody,\n signal,\n });\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 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// Node's global fetch (undici) already maintains a connection pool shared\n// across fetch calls to the same origin — so the TCP + TLS handshake is\n// amortized at the dispatcher level. Reusing ApiClient across\n// class-method calls additionally avoids churning AbortControllers and\n// keeps caller-level semantics symmetric with the Python SDK's\n// get_shared_client(). See docs for full details.\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 * Declaw records a fixed set of lifecycle + security events (vm_created,\n * vm_killed, snapshot_*, egress_blocked, …). Set `enabled: false` to opt\n * the sandbox out entirely; events for that sandbox are not shipped to\n * the collector and nothing is persisted.\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","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';\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';\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}\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 };\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\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 };\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 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 as a string.\n *\n * @param path - Absolute path to the file.\n * @param opts - Optional user and request timeout.\n * @returns The file contents as a string.\n */\n async read(\n path: string,\n opts?: { user?: string; requestTimeout?: number },\n ): Promise<string> {\n const user = opts?.user ?? DEFAULT_USER;\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","/** Request-side shape of a volume attachment on Sandbox.create. */\nexport interface VolumeAttachment {\n volumeId: string;\n mountPath: 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}\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 };\n}\n\n/** Render a VolumeAttachment in wire (snake_case) form. */\nexport function volumeAttachmentToJSON(att: VolumeAttachment): Record<string, string> {\n return { volume_id: att.volumeId, mount_path: att.mountPath };\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 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. \"104.198.24.180: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\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 }\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 /**\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 * Note: the reverse-proxy backend is not yet deployed; calls to the returned\n * URL will 404 until that feature ships. The URL shape is stable and safe to\n * script against.\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 * Same deployment caveat as {@link getHost}.\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 * @param requestTimeout - Optional per-request timeout in milliseconds.\n * @returns True if the sandbox was killed, false if it was already dead.\n */\n async kill(requestTimeout?: number): Promise<boolean> {\n const data = (await this._client.delete(`/sandboxes/${this._sandboxId}`, {\n timeout: requestTimeout,\n })) as Record<string, unknown>;\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 * 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 /** 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 /** 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 const result: Record<string, any> = {\n base_image: this._baseImage,\n };\n\n if (this._runCmds.length > 0) {\n result.run_cmds = this._runCmds;\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 { ApiClient, 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 { ApiClient, getSharedClient } from '../api/client.js';\nimport { InvalidArgumentError } from '../errors.js';\nimport type { VolumeInfo } from './models.js';\nimport { parseVolumeInfo } from './models.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/** Shared per-call options. */\nexport interface VolumeRequestOpts {\n apiKey?: string;\n domain?: string;\n apiUrl?: string;\n requestTimeout?: number;\n}\n\n/** Options for Volumes.create. */\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 *\n * Phase 1: the body must be a gzip-compressed tar archive; the server\n * materializes regular-file entries inside the sandbox filesystem under\n * 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 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 /** 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 /** 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"],"mappings":"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","names":["PIIType","RedactionAction","InjectionSensitivity","InjectionAction","TransformDirection","VALID_ACTIONS","VALID_ACTIONS","VALID_ACTIONS","SandboxState","splitlines","FileType","FilesystemEventType","result"]}
|