@cloudflare/sandbox 0.3.7 → 0.4.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.
Files changed (120) hide show
  1. package/.turbo/turbo-build.log +44 -0
  2. package/CHANGELOG.md +6 -14
  3. package/Dockerfile +82 -18
  4. package/README.md +89 -824
  5. package/dist/{chunk-JTKON2SH.js → chunk-BCJ7SF3Q.js} +9 -5
  6. package/dist/chunk-BCJ7SF3Q.js.map +1 -0
  7. package/dist/chunk-BFVUNTP4.js +104 -0
  8. package/dist/chunk-BFVUNTP4.js.map +1 -0
  9. package/dist/{chunk-NNGBXDMY.js → chunk-EKSWCBCA.js} +3 -6
  10. package/dist/chunk-EKSWCBCA.js.map +1 -0
  11. package/dist/chunk-HGF554LH.js +2236 -0
  12. package/dist/chunk-HGF554LH.js.map +1 -0
  13. package/dist/{chunk-6UAWTJ5S.js → chunk-Z532A7QC.js} +13 -20
  14. package/dist/{chunk-6UAWTJ5S.js.map → chunk-Z532A7QC.js.map} +1 -1
  15. package/dist/file-stream.d.ts +16 -38
  16. package/dist/file-stream.js +1 -2
  17. package/dist/index.d.ts +6 -5
  18. package/dist/index.js +35 -39
  19. package/dist/index.js.map +1 -1
  20. package/dist/interpreter.d.ts +3 -3
  21. package/dist/interpreter.js +2 -2
  22. package/dist/request-handler.d.ts +4 -3
  23. package/dist/request-handler.js +4 -7
  24. package/dist/sandbox-D9K2ypln.d.ts +583 -0
  25. package/dist/sandbox.d.ts +3 -3
  26. package/dist/sandbox.js +4 -7
  27. package/dist/security.d.ts +4 -3
  28. package/dist/security.js +3 -3
  29. package/dist/sse-parser.js +1 -1
  30. package/package.json +11 -5
  31. package/src/clients/base-client.ts +280 -0
  32. package/src/clients/command-client.ts +115 -0
  33. package/src/clients/file-client.ts +269 -0
  34. package/src/clients/git-client.ts +92 -0
  35. package/src/clients/index.ts +63 -0
  36. package/src/{interpreter-client.ts → clients/interpreter-client.ts} +148 -171
  37. package/src/clients/port-client.ts +105 -0
  38. package/src/clients/process-client.ts +177 -0
  39. package/src/clients/sandbox-client.ts +41 -0
  40. package/src/clients/types.ts +84 -0
  41. package/src/clients/utility-client.ts +94 -0
  42. package/src/errors/adapter.ts +180 -0
  43. package/src/errors/classes.ts +469 -0
  44. package/src/errors/index.ts +105 -0
  45. package/src/file-stream.ts +119 -117
  46. package/src/index.ts +81 -69
  47. package/src/interpreter.ts +17 -8
  48. package/src/request-handler.ts +69 -43
  49. package/src/sandbox.ts +694 -533
  50. package/src/security.ts +14 -23
  51. package/src/sse-parser.ts +4 -8
  52. package/startup.sh +3 -0
  53. package/tests/base-client.test.ts +328 -0
  54. package/tests/command-client.test.ts +407 -0
  55. package/tests/file-client.test.ts +643 -0
  56. package/tests/file-stream.test.ts +306 -0
  57. package/tests/git-client.test.ts +328 -0
  58. package/tests/port-client.test.ts +301 -0
  59. package/tests/process-client.test.ts +658 -0
  60. package/tests/sandbox.test.ts +465 -0
  61. package/tests/sse-parser.test.ts +290 -0
  62. package/tests/utility-client.test.ts +266 -0
  63. package/tests/wrangler.jsonc +35 -0
  64. package/tsconfig.json +9 -1
  65. package/vitest.config.ts +31 -0
  66. package/container_src/bun.lock +0 -76
  67. package/container_src/circuit-breaker.ts +0 -121
  68. package/container_src/control-process.ts +0 -784
  69. package/container_src/handler/exec.ts +0 -185
  70. package/container_src/handler/file.ts +0 -457
  71. package/container_src/handler/git.ts +0 -130
  72. package/container_src/handler/ports.ts +0 -314
  73. package/container_src/handler/process.ts +0 -568
  74. package/container_src/handler/session.ts +0 -92
  75. package/container_src/index.ts +0 -601
  76. package/container_src/interpreter-service.ts +0 -276
  77. package/container_src/isolation.ts +0 -1213
  78. package/container_src/mime-processor.ts +0 -255
  79. package/container_src/package.json +0 -18
  80. package/container_src/runtime/executors/javascript/node_executor.ts +0 -123
  81. package/container_src/runtime/executors/python/ipython_executor.py +0 -338
  82. package/container_src/runtime/executors/typescript/ts_executor.ts +0 -138
  83. package/container_src/runtime/process-pool.ts +0 -464
  84. package/container_src/shell-escape.ts +0 -42
  85. package/container_src/startup.sh +0 -11
  86. package/container_src/types.ts +0 -131
  87. package/dist/chunk-32UDXUPC.js +0 -671
  88. package/dist/chunk-32UDXUPC.js.map +0 -1
  89. package/dist/chunk-5DILEXGY.js +0 -85
  90. package/dist/chunk-5DILEXGY.js.map +0 -1
  91. package/dist/chunk-D3U63BZP.js +0 -240
  92. package/dist/chunk-D3U63BZP.js.map +0 -1
  93. package/dist/chunk-FXYPFGOZ.js +0 -129
  94. package/dist/chunk-FXYPFGOZ.js.map +0 -1
  95. package/dist/chunk-JTKON2SH.js.map +0 -1
  96. package/dist/chunk-NNGBXDMY.js.map +0 -1
  97. package/dist/chunk-SQLJNZ3K.js +0 -674
  98. package/dist/chunk-SQLJNZ3K.js.map +0 -1
  99. package/dist/chunk-W7TVRPBG.js +0 -108
  100. package/dist/chunk-W7TVRPBG.js.map +0 -1
  101. package/dist/client-B3RUab0s.d.ts +0 -225
  102. package/dist/client.d.ts +0 -4
  103. package/dist/client.js +0 -7
  104. package/dist/client.js.map +0 -1
  105. package/dist/errors.d.ts +0 -95
  106. package/dist/errors.js +0 -27
  107. package/dist/errors.js.map +0 -1
  108. package/dist/interpreter-client.d.ts +0 -4
  109. package/dist/interpreter-client.js +0 -9
  110. package/dist/interpreter-client.js.map +0 -1
  111. package/dist/interpreter-types.d.ts +0 -259
  112. package/dist/interpreter-types.js +0 -9
  113. package/dist/interpreter-types.js.map +0 -1
  114. package/dist/types.d.ts +0 -453
  115. package/dist/types.js +0 -45
  116. package/dist/types.js.map +0 -1
  117. package/src/client.ts +0 -1048
  118. package/src/errors.ts +0 -219
  119. package/src/interpreter-types.ts +0 -390
  120. package/src/types.ts +0 -571
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/request-handler.ts","../src/sandbox.ts","../src/clients/base-client.ts","../src/errors/index.ts","../src/errors/adapter.ts","../src/errors/classes.ts","../src/clients/command-client.ts","../src/clients/file-client.ts","../src/clients/git-client.ts","../src/clients/interpreter-client.ts","../src/clients/port-client.ts","../src/clients/process-client.ts","../src/clients/utility-client.ts","../src/clients/sandbox-client.ts"],"sourcesContent":["import { createLogger, type LogContext, TraceContext } from \"@repo/shared\";\nimport { getSandbox, type Sandbox } from \"./sandbox\";\nimport {\n sanitizeSandboxId,\n validatePort\n} from \"./security\";\n\nexport interface SandboxEnv {\n Sandbox: DurableObjectNamespace<Sandbox>;\n}\n\nexport interface RouteInfo {\n port: number;\n sandboxId: string;\n path: string;\n token: string;\n}\n\nexport async function proxyToSandbox<E extends SandboxEnv>(\n request: Request,\n env: E\n): Promise<Response | null> {\n // Create logger context for this request\n const traceId = TraceContext.fromHeaders(request.headers) || TraceContext.generate();\n const logger = createLogger({\n component: 'sandbox-do',\n traceId,\n operation: 'proxy'\n });\n\n try {\n const url = new URL(request.url);\n const routeInfo = extractSandboxRoute(url);\n\n if (!routeInfo) {\n return null; // Not a request to an exposed container port\n }\n\n const { sandboxId, port, path, token } = routeInfo;\n const sandbox = getSandbox(env.Sandbox, sandboxId);\n\n // Critical security check: Validate token (mandatory for all user ports)\n // Skip check for control plane port 3000\n if (port !== 3000) {\n // Validate the token matches the port\n const isValidToken = await sandbox.validatePortToken(port, token);\n if (!isValidToken) {\n logger.warn('Invalid token access blocked', {\n port,\n sandboxId,\n path,\n hostname: url.hostname,\n url: request.url,\n method: request.method,\n userAgent: request.headers.get('User-Agent') || 'unknown'\n });\n\n return new Response(\n JSON.stringify({\n error: `Access denied: Invalid token or port not exposed`,\n code: 'INVALID_TOKEN'\n }),\n {\n status: 404,\n headers: {\n 'Content-Type': 'application/json'\n }\n }\n );\n }\n }\n\n // Build proxy request with proper headers\n let proxyUrl: string;\n\n // Route based on the target port\n if (port !== 3000) {\n // Route directly to user's service on the specified port\n proxyUrl = `http://localhost:${port}${path}${url.search}`;\n } else {\n // Port 3000 is our control plane - route normally\n proxyUrl = `http://localhost:3000${path}${url.search}`;\n }\n\n const proxyRequest = new Request(proxyUrl, {\n method: request.method,\n headers: {\n ...Object.fromEntries(request.headers),\n 'X-Original-URL': request.url,\n 'X-Forwarded-Host': url.hostname,\n 'X-Forwarded-Proto': url.protocol.replace(':', ''),\n 'X-Sandbox-Name': sandboxId, // Pass the friendly name\n },\n body: request.body,\n // @ts-expect-error - duplex required for body streaming in modern runtimes\n duplex: 'half',\n });\n\n return sandbox.containerFetch(proxyRequest, port);\n } catch (error) {\n logger.error('Proxy routing error', error instanceof Error ? error : new Error(String(error)));\n return new Response('Proxy routing error', { status: 500 });\n }\n}\n\nfunction extractSandboxRoute(url: URL): RouteInfo | null {\n // Parse subdomain pattern: port-sandboxId-token.domain (tokens mandatory)\n const subdomainMatch = url.hostname.match(/^(\\d{4,5})-([^.-][^.]*[^.-]|[^.-])-([a-zA-Z0-9_-]{12,20})\\.(.+)$/);\n\n if (!subdomainMatch) {\n return null;\n }\n\n const portStr = subdomainMatch[1];\n const sandboxId = subdomainMatch[2];\n const token = subdomainMatch[3]; // Mandatory token\n const domain = subdomainMatch[4];\n\n const port = parseInt(portStr, 10);\n if (!validatePort(port)) {\n return null;\n }\n\n let sanitizedSandboxId: string;\n try {\n sanitizedSandboxId = sanitizeSandboxId(sandboxId);\n } catch (error) {\n return null;\n }\n\n // DNS subdomain length limit is 63 characters\n if (sandboxId.length > 63) {\n return null;\n }\n\n return {\n port,\n sandboxId: sanitizedSandboxId,\n path: url.pathname || \"/\",\n token,\n };\n}\n\nexport function isLocalhostPattern(hostname: string): boolean {\n // Handle IPv6 addresses in brackets (with or without port)\n if (hostname.startsWith('[')) {\n if (hostname.includes(']:')) {\n // [::1]:port format\n const ipv6Part = hostname.substring(0, hostname.indexOf(']:') + 1);\n return ipv6Part === '[::1]';\n } else {\n // [::1] format without port\n return hostname === '[::1]';\n }\n }\n \n // Handle bare IPv6 without brackets\n if (hostname === '::1') {\n return true;\n }\n \n // For IPv4 and regular hostnames, split on colon to remove port\n const hostPart = hostname.split(\":\")[0];\n \n return (\n hostPart === \"localhost\" ||\n hostPart === \"127.0.0.1\" ||\n hostPart === \"0.0.0.0\"\n );\n}\n","import type { DurableObject } from 'cloudflare:workers';\nimport { Container, getContainer } from \"@cloudflare/containers\";\nimport type {\n CodeContext,\n CreateContextOptions,\n ExecEvent,\n ExecOptions,\n ExecResult,\n ExecutionResult,\n ExecutionSession,\n ISandbox,\n Process,\n ProcessOptions,\n ProcessStatus,\n RunCodeOptions,\n SessionOptions,\n StreamOptions\n} from \"@repo/shared\";\nimport { createLogger, runWithLogger, TraceContext } from \"@repo/shared\";\nimport { type ExecuteResponse, SandboxClient } from \"./clients\";\nimport type { ErrorResponse } from './errors';\nimport { CustomDomainRequiredError, ErrorCode } from './errors';\nimport { CodeInterpreter } from \"./interpreter\";\nimport { isLocalhostPattern } from \"./request-handler\";\nimport {\n SecurityError,\n sanitizeSandboxId,\n validatePort\n} from \"./security\";\nimport { parseSSEStream } from \"./sse-parser\";\n\nexport function getSandbox(ns: DurableObjectNamespace<Sandbox>, id: string, options?: {\n baseUrl: string\n}) {\n const stub = getContainer(ns, id);\n\n // Store the name on first access\n stub.setSandboxName?.(id);\n\n if(options?.baseUrl) {\n stub.setBaseUrl(options.baseUrl);\n }\n\n return stub;\n}\n\nexport class Sandbox<Env = unknown> extends Container<Env> implements ISandbox {\n defaultPort = 3000; // Default port for the container's Bun server\n sleepAfter = \"3m\"; // Sleep the sandbox if no requests are made in this timeframe\n\n client: SandboxClient;\n private codeInterpreter: CodeInterpreter;\n private sandboxName: string | null = null;\n private baseUrl: string | null = null;\n private portTokens: Map<number, string> = new Map();\n private defaultSession: string | null = null;\n envVars: Record<string, string> = {};\n private logger: ReturnType<typeof createLogger>;\n\n constructor(ctx: DurableObject['ctx'], env: Env) {\n super(ctx, env);\n\n const envObj = env as any;\n // Set sandbox environment variables from env object\n const sandboxEnvKeys = ['SANDBOX_LOG_LEVEL', 'SANDBOX_LOG_FORMAT'] as const;\n sandboxEnvKeys.forEach(key => {\n if (envObj?.[key]) {\n this.envVars[key] = envObj[key];\n }\n });\n\n this.logger = createLogger({\n component: 'sandbox-do',\n sandboxId: this.ctx.id.toString()\n });\n\n this.client = new SandboxClient({\n logger: this.logger,\n port: 3000, // Control plane port\n stub: this,\n });\n\n // Initialize code interpreter - pass 'this' after client is ready\n // The CodeInterpreter extracts client.interpreter from the sandbox\n this.codeInterpreter = new CodeInterpreter(this);\n\n // Load the sandbox name and port tokens from storage on initialization\n this.ctx.blockConcurrencyWhile(async () => {\n this.sandboxName = await this.ctx.storage.get<string>('sandboxName') || null;\n const storedTokens = await this.ctx.storage.get<Record<string, string>>('portTokens') || {};\n\n // Convert stored tokens back to Map\n this.portTokens = new Map();\n for (const [portStr, token] of Object.entries(storedTokens)) {\n this.portTokens.set(parseInt(portStr, 10), token);\n }\n });\n }\n\n // RPC method to set the sandbox name\n async setSandboxName(name: string): Promise<void> {\n if (!this.sandboxName) {\n this.sandboxName = name;\n await this.ctx.storage.put('sandboxName', name);\n }\n }\n\n // RPC method to set the base URL\n async setBaseUrl(baseUrl: string): Promise<void> {\n if (!this.baseUrl) {\n this.baseUrl = baseUrl;\n await this.ctx.storage.put('baseUrl', baseUrl);\n console.log(`[Sandbox] Stored base URL: ${baseUrl}`);\n } else {\n if(this.baseUrl !== baseUrl) {\n throw new Error('Base URL already set and different from one previously provided');\n }\n }\n }\n\n // RPC method to set environment variables\n async setEnvVars(envVars: Record<string, string>): Promise<void> {\n // Update local state for new sessions\n this.envVars = { ...this.envVars, ...envVars };\n\n // If default session already exists, update it directly\n if (this.defaultSession) {\n // Set environment variables by executing export commands in the existing session\n for (const [key, value] of Object.entries(envVars)) {\n const escapedValue = value.replace(/'/g, \"'\\\\''\");\n const exportCommand = `export ${key}='${escapedValue}'`;\n\n const result = await this.client.commands.execute(exportCommand, this.defaultSession);\n\n if (result.exitCode !== 0) {\n throw new Error(`Failed to set ${key}: ${result.stderr || 'Unknown error'}`);\n }\n }\n }\n }\n\n /**\n * Cleanup and destroy the sandbox container\n */\n override async destroy(): Promise<void> {\n this.logger.info('Destroying sandbox container');\n await super.destroy();\n }\n\n override onStart() {\n this.logger.debug('Sandbox started');\n }\n\n override onStop() {\n this.logger.debug('Sandbox stopped');\n }\n\n override onError(error: unknown) {\n this.logger.error('Sandbox error', error instanceof Error ? error : new Error(String(error)));\n }\n\n // Override fetch to route internal container requests to appropriate ports\n override async fetch(request: Request): Promise<Response> {\n // Extract or generate trace ID from request\n const traceId = TraceContext.fromHeaders(request.headers) || TraceContext.generate();\n\n // Create request-specific logger with trace ID\n const requestLogger = this.logger.child({ traceId, operation: 'fetch' });\n\n return await runWithLogger(requestLogger, async () => {\n const url = new URL(request.url);\n\n // Capture and store the sandbox name from the header if present\n if (!this.sandboxName && request.headers.has('X-Sandbox-Name')) {\n const name = request.headers.get('X-Sandbox-Name')!;\n this.sandboxName = name;\n await this.ctx.storage.put('sandboxName', name);\n }\n\n // Determine which port to route to\n const port = this.determinePort(url);\n\n // Route to the appropriate port\n return await this.containerFetch(request, port);\n });\n }\n\n private determinePort(url: URL): number {\n // Extract port from proxy requests (e.g., /proxy/8080/*)\n const proxyMatch = url.pathname.match(/^\\/proxy\\/(\\d+)/);\n if (proxyMatch) {\n return parseInt(proxyMatch[1], 10);\n }\n\n // All other requests go to control plane on port 3000\n // This includes /api/* endpoints and any other control requests\n return 3000;\n }\n\n /**\n * Ensure default session exists - lazy initialization\n * This is called automatically by all public methods that need a session\n */\n private async ensureDefaultSession(): Promise<string> {\n if (!this.defaultSession) {\n const sessionId = `sandbox-${this.sandboxName || 'default'}`;\n\n // Create session in container\n await this.client.utils.createSession({\n id: sessionId,\n env: this.envVars || {},\n cwd: '/workspace',\n });\n\n this.defaultSession = sessionId;\n this.logger.debug('Default session initialized', { sessionId });\n }\n return this.defaultSession;\n }\n\n // Enhanced exec method - always returns ExecResult with optional streaming\n // This replaces the old exec method to match ISandbox interface\n async exec(command: string, options?: ExecOptions): Promise<ExecResult> {\n const session = await this.ensureDefaultSession();\n return this.execWithSession(command, session, options);\n }\n\n /**\n * Internal session-aware exec implementation\n * Used by both public exec() and session wrappers\n */\n private async execWithSession(\n command: string,\n sessionId: string,\n options?: ExecOptions\n ): Promise<ExecResult> {\n const startTime = Date.now();\n const timestamp = new Date().toISOString();\n\n // Handle timeout\n let timeoutId: NodeJS.Timeout | undefined;\n\n try {\n // Handle cancellation\n if (options?.signal?.aborted) {\n throw new Error('Operation was aborted');\n }\n\n let result: ExecResult;\n\n if (options?.stream && options?.onOutput) {\n // Streaming with callbacks - we need to collect the final result\n result = await this.executeWithStreaming(command, sessionId, options, startTime, timestamp);\n } else {\n // Regular execution with session\n const response = await this.client.commands.execute(command, sessionId);\n\n const duration = Date.now() - startTime;\n result = this.mapExecuteResponseToExecResult(response, duration, sessionId);\n }\n\n // Call completion callback if provided\n if (options?.onComplete) {\n options.onComplete(result);\n }\n\n return result;\n } catch (error) {\n if (options?.onError && error instanceof Error) {\n options.onError(error);\n }\n throw error;\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n }\n\n private async executeWithStreaming(\n command: string,\n sessionId: string,\n options: ExecOptions,\n startTime: number,\n timestamp: string\n ): Promise<ExecResult> {\n let stdout = '';\n let stderr = '';\n\n try {\n const stream = await this.client.commands.executeStream(command, sessionId);\n\n for await (const event of parseSSEStream<ExecEvent>(stream)) {\n // Check for cancellation\n if (options.signal?.aborted) {\n throw new Error('Operation was aborted');\n }\n\n switch (event.type) {\n case 'stdout':\n case 'stderr':\n if (event.data) {\n // Update accumulated output\n if (event.type === 'stdout') stdout += event.data;\n if (event.type === 'stderr') stderr += event.data;\n\n // Call user's callback\n if (options.onOutput) {\n options.onOutput(event.type, event.data);\n }\n }\n break;\n\n case 'complete': {\n // Use result from complete event if available\n const duration = Date.now() - startTime;\n return {\n success: (event.exitCode ?? 0) === 0,\n exitCode: event.exitCode ?? 0,\n stdout,\n stderr,\n command,\n duration,\n timestamp,\n sessionId\n };\n }\n\n case 'error':\n throw new Error(event.data || 'Command execution failed');\n }\n }\n\n // If we get here without a complete event, something went wrong\n throw new Error('Stream ended without completion event');\n\n } catch (error) {\n if (options.signal?.aborted) {\n throw new Error('Operation was aborted');\n }\n throw error;\n }\n }\n\n private mapExecuteResponseToExecResult(\n response: ExecuteResponse,\n duration: number,\n sessionId?: string\n ): ExecResult {\n return {\n success: response.success,\n exitCode: response.exitCode,\n stdout: response.stdout,\n stderr: response.stderr,\n command: response.command,\n duration,\n timestamp: response.timestamp,\n sessionId\n };\n }\n\n /**\n * Create a Process domain object from HTTP client DTO\n * Centralizes process object creation with bound methods\n * This eliminates duplication across startProcess, listProcesses, getProcess, and session wrappers\n */\n private createProcessFromDTO(\n data: {\n id: string;\n pid?: number;\n command: string;\n status: ProcessStatus;\n startTime: string | Date;\n endTime?: string | Date;\n exitCode?: number;\n },\n sessionId: string\n ): Process {\n return {\n id: data.id,\n pid: data.pid,\n command: data.command,\n status: data.status,\n startTime: typeof data.startTime === 'string' ? new Date(data.startTime) : data.startTime,\n endTime: data.endTime ? (typeof data.endTime === 'string' ? new Date(data.endTime) : data.endTime) : undefined,\n exitCode: data.exitCode,\n sessionId,\n\n kill: async (signal?: string) => {\n await this.killProcess(data.id, signal);\n },\n\n getStatus: async () => {\n const current = await this.getProcess(data.id);\n return current?.status || 'error';\n },\n\n getLogs: async () => {\n const logs = await this.getProcessLogs(data.id);\n return { stdout: logs.stdout, stderr: logs.stderr };\n }\n };\n }\n\n\n // Background process management\n async startProcess(command: string, options?: ProcessOptions, sessionId?: string): Promise<Process> {\n // Use the new HttpClient method to start the process\n try {\n const session = sessionId ?? await this.ensureDefaultSession();\n const response = await this.client.processes.startProcess(command, session, {\n processId: options?.processId\n });\n\n const processObj = this.createProcessFromDTO({\n id: response.processId,\n pid: response.pid,\n command: response.command,\n status: 'running' as ProcessStatus,\n startTime: new Date(),\n endTime: undefined,\n exitCode: undefined\n }, session);\n\n // Call onStart callback if provided\n if (options?.onStart) {\n options.onStart(processObj);\n }\n\n return processObj;\n\n } catch (error) {\n if (options?.onError && error instanceof Error) {\n options.onError(error);\n }\n\n throw error;\n }\n }\n\n async listProcesses(sessionId?: string): Promise<Process[]> {\n const session = sessionId ?? await this.ensureDefaultSession();\n const response = await this.client.processes.listProcesses();\n\n return response.processes.map(processData =>\n this.createProcessFromDTO({\n id: processData.id,\n pid: processData.pid,\n command: processData.command,\n status: processData.status,\n startTime: processData.startTime,\n endTime: processData.endTime,\n exitCode: processData.exitCode\n }, session)\n );\n }\n\n async getProcess(id: string, sessionId?: string): Promise<Process | null> {\n const session = sessionId ?? await this.ensureDefaultSession();\n const response = await this.client.processes.getProcess(id);\n if (!response.process) {\n return null;\n }\n\n const processData = response.process;\n return this.createProcessFromDTO({\n id: processData.id,\n pid: processData.pid,\n command: processData.command,\n status: processData.status,\n startTime: processData.startTime,\n endTime: processData.endTime,\n exitCode: processData.exitCode\n }, session);\n }\n\n async killProcess(id: string, signal?: string, sessionId?: string): Promise<void> {\n // Note: signal parameter is not currently supported by the HttpClient implementation\n // The HTTP client already throws properly typed errors, so we just let them propagate\n await this.client.processes.killProcess(id);\n }\n\n async killAllProcesses(sessionId?: string): Promise<number> {\n const response = await this.client.processes.killAllProcesses();\n return response.cleanedCount;\n }\n\n async cleanupCompletedProcesses(sessionId?: string): Promise<number> {\n // For now, this would need to be implemented as a container endpoint\n // as we no longer maintain local process storage\n // We'll return 0 as a placeholder until the container endpoint is added\n return 0;\n }\n\n async getProcessLogs(id: string, sessionId?: string): Promise<{ stdout: string; stderr: string; processId: string }> {\n // The HTTP client already throws properly typed errors, so we just let them propagate\n const response = await this.client.processes.getProcessLogs(id);\n return {\n stdout: response.stdout,\n stderr: response.stderr,\n processId: response.processId\n };\n }\n\n\n // Streaming methods - return ReadableStream for RPC compatibility\n async execStream(command: string, options?: StreamOptions): Promise<ReadableStream<Uint8Array>> {\n // Check for cancellation\n if (options?.signal?.aborted) {\n throw new Error('Operation was aborted');\n }\n\n const session = await this.ensureDefaultSession();\n // Get the stream from CommandClient\n return this.client.commands.executeStream(command, session);\n }\n\n /**\n * Internal session-aware execStream implementation\n */\n private async execStreamWithSession(command: string, sessionId: string, options?: StreamOptions): Promise<ReadableStream<Uint8Array>> {\n // Check for cancellation\n if (options?.signal?.aborted) {\n throw new Error('Operation was aborted');\n }\n\n return this.client.commands.executeStream(command, sessionId);\n }\n\n async streamProcessLogs(processId: string, options?: { signal?: AbortSignal }): Promise<ReadableStream<Uint8Array>> {\n // Check for cancellation\n if (options?.signal?.aborted) {\n throw new Error('Operation was aborted');\n }\n\n return this.client.processes.streamProcessLogs(processId);\n }\n\n async gitCheckout(\n repoUrl: string,\n options: { branch?: string; targetDir?: string; sessionId?: string }\n ) {\n const session = options.sessionId ?? await this.ensureDefaultSession();\n return this.client.git.checkout(repoUrl, session, {\n branch: options.branch,\n targetDir: options.targetDir\n });\n }\n\n async mkdir(\n path: string,\n options: { recursive?: boolean; sessionId?: string } = {}\n ) {\n const session = options.sessionId ?? await this.ensureDefaultSession();\n return this.client.files.mkdir(path, session, { recursive: options.recursive });\n }\n\n async writeFile(\n path: string,\n content: string,\n options: { encoding?: string; sessionId?: string } = {}\n ) {\n const session = options.sessionId ?? await this.ensureDefaultSession();\n return this.client.files.writeFile(path, content, session, { encoding: options.encoding });\n }\n\n async deleteFile(path: string, sessionId?: string) {\n const session = sessionId ?? await this.ensureDefaultSession();\n return this.client.files.deleteFile(path, session);\n }\n\n async renameFile(\n oldPath: string,\n newPath: string,\n sessionId?: string\n ) {\n const session = sessionId ?? await this.ensureDefaultSession();\n return this.client.files.renameFile(oldPath, newPath, session);\n }\n\n async moveFile(\n sourcePath: string,\n destinationPath: string,\n sessionId?: string\n ) {\n const session = sessionId ?? await this.ensureDefaultSession();\n return this.client.files.moveFile(sourcePath, destinationPath, session);\n }\n\n async readFile(\n path: string,\n options: { encoding?: string; sessionId?: string } = {}\n ) {\n const session = options.sessionId ?? await this.ensureDefaultSession();\n return this.client.files.readFile(path, session, { encoding: options.encoding });\n }\n\n /**\n * Stream a file from the sandbox using Server-Sent Events\n * Returns a ReadableStream that can be consumed with streamFile() or collectFile() utilities\n * @param path - Path to the file to stream\n * @param options - Optional session ID\n */\n async readFileStream(\n path: string,\n options: { sessionId?: string } = {}\n ): Promise<ReadableStream<Uint8Array>> {\n const session = options.sessionId ?? await this.ensureDefaultSession();\n return this.client.files.readFileStream(path, session);\n }\n\n async listFiles(\n path: string,\n options?: { recursive?: boolean; includeHidden?: boolean }\n ) {\n const session = await this.ensureDefaultSession();\n return this.client.files.listFiles(path, session, options);\n }\n\n async exposePort(port: number, options: { name?: string; hostname: string }) {\n // Check if hostname is workers.dev domain (doesn't support wildcard subdomains)\n if (options.hostname.endsWith('.workers.dev')) {\n const errorResponse: ErrorResponse = {\n code: ErrorCode.CUSTOM_DOMAIN_REQUIRED,\n message: `Port exposure requires a custom domain. .workers.dev domains do not support wildcard subdomains required for port proxying.`,\n context: { originalError: options.hostname },\n httpStatus: 400,\n timestamp: new Date().toISOString()\n };\n throw new CustomDomainRequiredError(errorResponse);\n }\n\n const sessionId = await this.ensureDefaultSession();\n await this.client.ports.exposePort(port, sessionId, options?.name);\n\n // We need the sandbox name to construct preview URLs\n if (!this.sandboxName) {\n throw new Error('Sandbox name not available. Ensure sandbox is accessed through getSandbox()');\n }\n\n // Generate and store token for this port\n const token = this.generatePortToken();\n this.portTokens.set(port, token);\n await this.persistPortTokens();\n\n const url = this.constructPreviewUrl(port, this.sandboxName, options.hostname, token);\n\n return {\n url,\n port,\n name: options?.name,\n };\n }\n\n async unexposePort(port: number) {\n if (!validatePort(port)) {\n throw new SecurityError(`Invalid port number: ${port}. Must be between 1024-65535 and not reserved.`);\n }\n\n const sessionId = await this.ensureDefaultSession();\n await this.client.ports.unexposePort(port, sessionId);\n\n // Clean up token for this port\n if (this.portTokens.has(port)) {\n this.portTokens.delete(port);\n await this.persistPortTokens();\n }\n }\n\n async getExposedPorts(hostname: string) {\n const sessionId = await this.ensureDefaultSession();\n const response = await this.client.ports.getExposedPorts(sessionId);\n\n // We need the sandbox name to construct preview URLs\n if (!this.sandboxName) {\n throw new Error('Sandbox name not available. Ensure sandbox is accessed through getSandbox()');\n }\n\n return response.ports.map(port => {\n // Get token for this port - must exist for all exposed ports\n const token = this.portTokens.get(port.port);\n if (!token) {\n throw new Error(`Port ${port.port} is exposed but has no token. This should not happen.`);\n }\n\n return {\n url: this.constructPreviewUrl(port.port, this.sandboxName!, hostname, token),\n port: port.port,\n status: port.status,\n };\n });\n }\n\n\n async isPortExposed(port: number): Promise<boolean> {\n try {\n const sessionId = await this.ensureDefaultSession();\n const response = await this.client.ports.getExposedPorts(sessionId);\n return response.ports.some(exposedPort => exposedPort.port === port);\n } catch (error) {\n this.logger.error('Error checking if port is exposed', error instanceof Error ? error : new Error(String(error)), { port });\n return false;\n }\n }\n\n async validatePortToken(port: number, token: string): Promise<boolean> {\n // First check if port is exposed\n const isExposed = await this.isPortExposed(port);\n if (!isExposed) {\n return false;\n }\n\n // Get stored token for this port - must exist for all exposed ports\n const storedToken = this.portTokens.get(port);\n if (!storedToken) {\n // This should not happen - all exposed ports must have tokens\n this.logger.error('Port is exposed but has no token - bug detected', undefined, { port });\n return false;\n }\n\n // Constant-time comparison to prevent timing attacks\n return storedToken === token;\n }\n\n private generatePortToken(): string {\n // Generate cryptographically secure 16-character token using Web Crypto API\n // Available in Cloudflare Workers runtime\n const array = new Uint8Array(12); // 12 bytes = 16 base64url chars (after padding removal)\n crypto.getRandomValues(array);\n\n // Convert to base64url format (URL-safe, no padding, lowercase)\n const base64 = btoa(String.fromCharCode(...array));\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '').toLowerCase();\n }\n\n private async persistPortTokens(): Promise<void> {\n // Convert Map to plain object for storage\n const tokensObj: Record<string, string> = {};\n for (const [port, token] of this.portTokens.entries()) {\n tokensObj[port.toString()] = token;\n }\n await this.ctx.storage.put('portTokens', tokensObj);\n }\n\n private constructPreviewUrl(port: number, sandboxId: string, hostname: string, token: string): string {\n if (!validatePort(port)) {\n throw new SecurityError(`Invalid port number: ${port}. Must be between 1024-65535 and not reserved.`);\n }\n\n // Validate sandbox ID (will throw SecurityError if invalid)\n const sanitizedSandboxId = sanitizeSandboxId(sandboxId);\n\n const isLocalhost = isLocalhostPattern(hostname);\n\n if (isLocalhost) {\n // Unified subdomain approach for localhost (RFC 6761)\n const [host, portStr] = hostname.split(':');\n const mainPort = portStr || '80';\n\n // Use URL constructor for safe URL building\n try {\n const baseUrl = new URL(`http://${host}:${mainPort}`);\n // Construct subdomain safely with mandatory token\n const subdomainHost = `${port}-${sanitizedSandboxId}-${token}.${host}`;\n baseUrl.hostname = subdomainHost;\n\n return baseUrl.toString();\n } catch (error) {\n throw new SecurityError(`Failed to construct preview URL: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n\n // Production subdomain logic - enforce HTTPS\n try {\n // Always use HTTPS for production (non-localhost)\n const protocol = \"https\";\n const baseUrl = new URL(`${protocol}://${hostname}`);\n\n // Construct subdomain safely with mandatory token\n const subdomainHost = `${port}-${sanitizedSandboxId}-${token}.${hostname}`;\n baseUrl.hostname = subdomainHost;\n\n return baseUrl.toString();\n } catch (error) {\n throw new SecurityError(`Failed to construct preview URL: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n\n // ============================================================================\n // Session Management - Advanced Use Cases\n // ============================================================================\n\n /**\n * Create isolated execution session for advanced use cases\n * Returns ExecutionSession with full sandbox API bound to specific session\n */\n async createSession(options?: SessionOptions): Promise<ExecutionSession> {\n const sessionId = options?.id || `session-${Date.now()}`;\n\n // Create session in container\n await this.client.utils.createSession({\n id: sessionId,\n env: options?.env,\n cwd: options?.cwd,\n });\n\n // Return wrapper that binds sessionId to all operations\n return this.getSessionWrapper(sessionId);\n }\n\n /**\n * Get an existing session by ID\n * Returns ExecutionSession wrapper bound to the specified session\n *\n * This is useful for retrieving sessions across different requests/contexts\n * without storing the ExecutionSession object (which has RPC lifecycle limitations)\n *\n * @param sessionId - The ID of an existing session\n * @returns ExecutionSession wrapper bound to the session\n */\n async getSession(sessionId: string): Promise<ExecutionSession> {\n // No need to verify session exists in container - operations will fail naturally if it doesn't\n return this.getSessionWrapper(sessionId);\n }\n\n /**\n * Internal helper to create ExecutionSession wrapper for a given sessionId\n * Used by both createSession and getSession\n */\n private getSessionWrapper(sessionId: string): ExecutionSession {\n return {\n id: sessionId,\n\n // Command execution - delegate to internal session-aware methods\n exec: (command, options) => this.execWithSession(command, sessionId, options),\n execStream: (command, options) => this.execStreamWithSession(command, sessionId, options),\n\n // Process management\n startProcess: (command, options) => this.startProcess(command, options, sessionId),\n listProcesses: () => this.listProcesses(sessionId),\n getProcess: (id) => this.getProcess(id, sessionId),\n killProcess: (id, signal) => this.killProcess(id, signal),\n killAllProcesses: () => this.killAllProcesses(),\n cleanupCompletedProcesses: () => this.cleanupCompletedProcesses(),\n getProcessLogs: (id) => this.getProcessLogs(id),\n streamProcessLogs: (processId, options) => this.streamProcessLogs(processId, options),\n\n // File operations - pass sessionId via options or parameter\n writeFile: (path, content, options) => this.writeFile(path, content, { ...options, sessionId }),\n readFile: (path, options) => this.readFile(path, { ...options, sessionId }),\n readFileStream: (path) => this.readFileStream(path, { sessionId }),\n mkdir: (path, options) => this.mkdir(path, { ...options, sessionId }),\n deleteFile: (path) => this.deleteFile(path, sessionId),\n renameFile: (oldPath, newPath) => this.renameFile(oldPath, newPath, sessionId),\n moveFile: (sourcePath, destPath) => this.moveFile(sourcePath, destPath, sessionId),\n listFiles: (path, options) => this.client.files.listFiles(path, sessionId, options),\n\n // Git operations\n gitCheckout: (repoUrl, options) => this.gitCheckout(repoUrl, { ...options, sessionId }),\n\n // Environment management - needs special handling\n setEnvVars: async (envVars: Record<string, string>) => {\n try {\n // Set environment variables by executing export commands\n for (const [key, value] of Object.entries(envVars)) {\n const escapedValue = value.replace(/'/g, \"'\\\\''\");\n const exportCommand = `export ${key}='${escapedValue}'`;\n\n const result = await this.client.commands.execute(exportCommand, sessionId);\n\n if (result.exitCode !== 0) {\n throw new Error(`Failed to set ${key}: ${result.stderr || 'Unknown error'}`);\n }\n }\n } catch (error) {\n this.logger.error('Failed to set environment variables', error instanceof Error ? error : new Error(String(error)), { sessionId });\n throw error;\n }\n },\n\n // Code interpreter methods - delegate to sandbox's code interpreter\n createCodeContext: (options) => this.codeInterpreter.createCodeContext(options),\n runCode: async (code, options) => {\n const execution = await this.codeInterpreter.runCode(code, options);\n return execution.toJSON();\n },\n runCodeStream: (code, options) => this.codeInterpreter.runCodeStream(code, options),\n listCodeContexts: () => this.codeInterpreter.listCodeContexts(),\n deleteCodeContext: (contextId) => this.codeInterpreter.deleteCodeContext(contextId),\n };\n }\n\n // ============================================================================\n // Code interpreter methods - delegate to CodeInterpreter wrapper\n // ============================================================================\n\n async createCodeContext(options?: CreateContextOptions): Promise<CodeContext> {\n return this.codeInterpreter.createCodeContext(options);\n }\n\n async runCode(code: string, options?: RunCodeOptions): Promise<ExecutionResult> {\n const execution = await this.codeInterpreter.runCode(code, options);\n return execution.toJSON();\n }\n\n async runCodeStream(code: string, options?: RunCodeOptions): Promise<ReadableStream> {\n return this.codeInterpreter.runCodeStream(code, options);\n }\n\n async listCodeContexts(): Promise<CodeContext[]> {\n return this.codeInterpreter.listCodeContexts();\n }\n\n async deleteCodeContext(contextId: string): Promise<void> {\n return this.codeInterpreter.deleteCodeContext(contextId);\n }\n}\n","import type { Logger } from \"@repo/shared\";\nimport { createNoOpLogger } from \"@repo/shared\";\nimport { getHttpStatus } from '@repo/shared/errors';\nimport type { ErrorResponse as NewErrorResponse } from '../errors';\nimport { createErrorFromResponse, ErrorCode } from '../errors';\nimport type { SandboxError } from '../errors/classes';\nimport type {\n HttpClientOptions,\n ResponseHandler\n} from './types';\n\n// Container provisioning retry configuration\nconst TIMEOUT_MS = 60_000; // 60 seconds total timeout budget\nconst MIN_TIME_FOR_RETRY_MS = 10_000; // Need at least 10s remaining to retry (8s Container + 2s delay)\n\n/**\n * Abstract base class providing common HTTP functionality for all domain clients\n */\nexport abstract class BaseHttpClient {\n protected baseUrl: string;\n protected options: HttpClientOptions;\n protected logger: Logger;\n\n constructor(options: HttpClientOptions = {}) {\n this.options = options;\n this.logger = options.logger ?? createNoOpLogger();\n this.baseUrl = this.options.baseUrl!;\n }\n\n /**\n * Core HTTP request method with automatic retry for container provisioning delays\n */\n protected async doFetch(\n path: string,\n options?: RequestInit\n ): Promise<Response> {\n const startTime = Date.now();\n let attempt = 0;\n\n while (true) {\n const response = await this.executeFetch(path, options);\n\n // Only retry container provisioning 503s, not user app 503s\n if (response.status === 503) {\n const isContainerProvisioning = await this.isContainerProvisioningError(response);\n\n if (isContainerProvisioning) {\n const elapsed = Date.now() - startTime;\n const remaining = TIMEOUT_MS - elapsed;\n\n // Check if we have enough time for another attempt\n // (Need at least 10s: 8s for Container timeout + 2s delay)\n if (remaining > MIN_TIME_FOR_RETRY_MS) {\n // Exponential backoff: 2s, 4s, 8s, 16s (capped at 16s)\n const delay = Math.min(2000 * 2 ** attempt, 16000);\n\n this.logger.info('Container provisioning in progress, retrying', {\n attempt: attempt + 1,\n delayMs: delay,\n remainingSec: Math.floor(remaining / 1000)\n });\n\n await new Promise(resolve => setTimeout(resolve, delay));\n attempt++;\n continue;\n } else {\n // Exhausted retries - log error and return response\n // Let existing error handling convert to proper error\n this.logger.error('Container failed to provision after multiple attempts', new Error(`Failed after ${attempt + 1} attempts over 60s`));\n return response;\n }\n }\n }\n\n return response;\n }\n }\n\n /**\n * Make a POST request with JSON body\n */\n protected async post<T>(\n endpoint: string,\n data: Record<string, any>,\n responseHandler?: ResponseHandler<T>\n ): Promise<T> {\n const response = await this.doFetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(data),\n });\n\n return this.handleResponse(response, responseHandler);\n }\n\n /**\n * Make a GET request\n */\n protected async get<T>(\n endpoint: string,\n responseHandler?: ResponseHandler<T>\n ): Promise<T> {\n const response = await this.doFetch(endpoint, {\n method: 'GET',\n });\n\n return this.handleResponse(response, responseHandler);\n }\n\n /**\n * Make a DELETE request\n */\n protected async delete<T>(\n endpoint: string,\n responseHandler?: ResponseHandler<T>\n ): Promise<T> {\n const response = await this.doFetch(endpoint, {\n method: 'DELETE',\n });\n\n return this.handleResponse(response, responseHandler);\n }\n\n\n /**\n * Handle HTTP response with error checking and parsing\n */\n protected async handleResponse<T>(\n response: Response,\n customHandler?: ResponseHandler<T>\n ): Promise<T> {\n if (!response.ok) {\n await this.handleErrorResponse(response);\n }\n\n if (customHandler) {\n return customHandler(response);\n }\n\n try {\n return await response.json();\n } catch (error) {\n // Handle malformed JSON responses gracefully\n const errorResponse: NewErrorResponse = {\n code: ErrorCode.INVALID_JSON_RESPONSE,\n message: `Invalid JSON response: ${error instanceof Error ? error.message : 'Unknown parsing error'}`,\n context: {},\n httpStatus: response.status,\n timestamp: new Date().toISOString()\n };\n throw createErrorFromResponse(errorResponse);\n }\n }\n\n /**\n * Handle error responses with consistent error throwing\n */\n protected async handleErrorResponse(response: Response): Promise<never> {\n let errorData: NewErrorResponse;\n\n try {\n errorData = await response.json();\n } catch {\n // Fallback if response isn't JSON or parsing fails\n errorData = {\n code: ErrorCode.INTERNAL_ERROR,\n message: `HTTP error! status: ${response.status}`,\n context: { statusText: response.statusText },\n httpStatus: response.status,\n timestamp: new Date().toISOString()\n };\n }\n\n // Convert ErrorResponse to appropriate Error class\n const error = createErrorFromResponse(errorData);\n\n // Call error callback if provided\n this.options.onError?.(errorData.message, undefined);\n\n throw error;\n }\n\n\n\n /**\n * Create a streaming response handler for Server-Sent Events\n */\n protected async handleStreamResponse(\n response: Response\n ): Promise<ReadableStream<Uint8Array>> {\n if (!response.ok) {\n await this.handleErrorResponse(response);\n }\n\n if (!response.body) {\n throw new Error('No response body for streaming');\n }\n\n return response.body;\n }\n\n /**\n * Utility method to log successful operations\n */\n protected logSuccess(operation: string, details?: string): void {\n this.logger.info(`${operation} completed successfully`, details ? { details } : undefined);\n }\n\n /**\n * Utility method to log errors intelligently\n * Only logs unexpected errors (5xx), not expected errors (4xx)\n *\n * - 4xx errors (validation, not found, conflicts): Don't log (expected client errors)\n * - 5xx errors (server failures, internal errors): DO log (unexpected server errors)\n */\n protected logError(operation: string, error: unknown): void {\n // Check if it's a SandboxError with HTTP status\n if (error && typeof error === 'object' && 'httpStatus' in error) {\n const httpStatus = (error as SandboxError).httpStatus;\n\n // Only log server errors (5xx), not client errors (4xx)\n if (httpStatus >= 500) {\n this.logger.error(\n `Unexpected error in ${operation}`,\n error instanceof Error ? error : new Error(String(error)),\n { httpStatus }\n );\n }\n // 4xx errors are expected (validation, not found, etc.) - don't log\n } else {\n // Non-SandboxError (unexpected) - log it\n this.logger.error(\n `Error in ${operation}`,\n error instanceof Error ? error : new Error(String(error))\n );\n }\n }\n\n /**\n * Check if 503 response is from container provisioning (retryable)\n * vs user application (not retryable)\n */\n private async isContainerProvisioningError(response: Response): Promise<boolean> {\n try {\n // Clone response so we don't consume the original body\n const cloned = response.clone();\n const text = await cloned.text();\n\n // Container package returns specific message for provisioning errors\n return text.includes('There is no Container instance available');\n } catch (error) {\n this.logger.error('Error checking response body', error instanceof Error ? error : new Error(String(error)));\n // If we can't read the body, don't retry to be safe\n return false;\n }\n }\n\n private async executeFetch(path: string, options?: RequestInit): Promise<Response> {\n const url = this.options.stub\n ? `http://localhost:${this.options.port}${path}`\n : `${this.baseUrl}${path}`;\n\n try {\n if (this.options.stub) {\n return await this.options.stub.containerFetch(\n url,\n options || {},\n this.options.port\n );\n } else {\n return await fetch(url, options);\n }\n } catch (error) {\n this.logger.error('HTTP request error', error instanceof Error ? error : new Error(String(error)), { method: options?.method || 'GET', url });\n throw error;\n }\n }\n}\n","/**\n * SDK Error System\n *\n * This module provides type-safe error classes that wrap ErrorResponse from the container.\n * All error classes provide:\n * - Type-safe accessors for error context\n * - instanceof checks for error handling\n * - Full ErrorResponse preservation via errorResponse property\n * - Custom toJSON() for logging\n *\n * @example Basic error handling\n * ```typescript\n * import { FileNotFoundError } from './errors';\n *\n * try {\n * await sandbox.file.read('/missing.txt');\n * } catch (error) {\n * if (error instanceof FileNotFoundError) {\n * console.log(error.path); // Type-safe! string\n * console.log(error.operation); // Type-safe! OperationType\n * console.log(error.code); // \"FILE_NOT_FOUND\"\n * console.log(error.suggestion); // Helpful message\n * }\n * }\n * ```\n *\n * @example Error serialization\n * ```typescript\n * try {\n * await sandbox.file.read('/missing.txt');\n * } catch (error) {\n * // Full context available\n * console.log(error.errorResponse);\n *\n * // Pretty-prints with custom toJSON\n * console.log(JSON.stringify(error, null, 2));\n * }\n * ```\n */\n\n// Re-export context types for advanced usage\nexport type { \n CodeExecutionContext,\n CommandErrorContext,\n CommandNotFoundContext,\n ContextNotFoundContext,ErrorCodeType, ErrorResponse, \n FileExistsContext,\n FileNotFoundContext,\n FileSystemContext,\n GitAuthFailedContext,\n GitBranchNotFoundContext,\n GitErrorContext,\n GitRepositoryNotFoundContext,\n InternalErrorContext,\n InterpreterNotReadyContext,\n InvalidPortContext,OperationType, \n PortAlreadyExposedContext,\n PortErrorContext,\n PortNotExposedContext,\n ProcessErrorContext,\n ProcessNotFoundContext,\n ValidationFailedContext,} from '@repo/shared/errors';\n// Re-export shared types and constants\nexport { ErrorCode, Operation } from '@repo/shared/errors';\n\n// Export adapter function\nexport { createErrorFromResponse } from './adapter';\n// Export all error classes\nexport {\n CodeExecutionError,\n CommandError,\n // Command Errors\n CommandNotFoundError,\n ContextNotFoundError,\n CustomDomainRequiredError,\n FileExistsError,\n // File System Errors\n FileNotFoundError,\n FileSystemError,\n GitAuthenticationError,\n GitBranchNotFoundError,\n GitCheckoutError,\n GitCloneError,\n GitError,\n GitNetworkError,\n // Git Errors\n GitRepositoryNotFoundError,\n // Code Interpreter Errors\n InterpreterNotReadyError,\n InvalidGitUrlError,\n InvalidPortError,\n PermissionDeniedError,\n // Port Errors\n PortAlreadyExposedError,\n PortError,\n PortInUseError,\n PortNotExposedError,\n ProcessError,\n // Process Errors\n ProcessNotFoundError,\n SandboxError,\n ServiceNotRespondingError,\n // Validation Errors\n ValidationFailedError,\n} from './classes';\n","/**\n * Error adapter that converts ErrorResponse to appropriate Error class\n *\n * Simple switch statement - we trust the container sends correct context\n * No validation overhead since we control both sides\n */\n\nimport type { \n CodeExecutionContext,\n CommandErrorContext,\n CommandNotFoundContext,\n ContextNotFoundContext,ErrorResponse, \n FileExistsContext,\n FileNotFoundContext,\n FileSystemContext,\n GitAuthFailedContext,\n GitBranchNotFoundContext,\n GitErrorContext,\n GitRepositoryNotFoundContext,\n InternalErrorContext,\n InterpreterNotReadyContext,\n InvalidPortContext,\n PortAlreadyExposedContext,\n PortErrorContext,\n PortNotExposedContext,\n ProcessErrorContext,\n ProcessNotFoundContext,\n ValidationFailedContext,} from '@repo/shared/errors';\nimport { ErrorCode } from '@repo/shared/errors';\n\nimport {\n CodeExecutionError,\n CommandError,\n CommandNotFoundError,\n ContextNotFoundError,\n CustomDomainRequiredError,\n FileExistsError,\n FileNotFoundError,\n FileSystemError,\n GitAuthenticationError,\n GitBranchNotFoundError,\n GitCheckoutError,\n GitCloneError,\n GitError,\n GitNetworkError,\n GitRepositoryNotFoundError,\n InterpreterNotReadyError,\n InvalidGitUrlError,\n InvalidPortError,\n PermissionDeniedError,\n PortAlreadyExposedError,\n PortError,\n PortInUseError,\n PortNotExposedError,\n ProcessError,\n ProcessNotFoundError,\n SandboxError,\n ServiceNotRespondingError,\n ValidationFailedError,\n} from './classes';\n\n/**\n * Convert ErrorResponse to appropriate Error class\n * Simple switch statement - we trust the container sends correct context\n */\nexport function createErrorFromResponse(errorResponse: ErrorResponse): Error {\n // We trust the container sends correct context, use type assertions\n switch (errorResponse.code) {\n // File System Errors\n case ErrorCode.FILE_NOT_FOUND:\n return new FileNotFoundError(errorResponse as unknown as ErrorResponse<FileNotFoundContext>);\n\n case ErrorCode.FILE_EXISTS:\n return new FileExistsError(errorResponse as unknown as ErrorResponse<FileExistsContext>);\n\n case ErrorCode.PERMISSION_DENIED:\n return new PermissionDeniedError(errorResponse as unknown as ErrorResponse<FileSystemContext>);\n\n case ErrorCode.IS_DIRECTORY:\n case ErrorCode.NOT_DIRECTORY:\n case ErrorCode.NO_SPACE:\n case ErrorCode.TOO_MANY_FILES:\n case ErrorCode.RESOURCE_BUSY:\n case ErrorCode.READ_ONLY:\n case ErrorCode.NAME_TOO_LONG:\n case ErrorCode.TOO_MANY_LINKS:\n case ErrorCode.FILESYSTEM_ERROR:\n return new FileSystemError(errorResponse as unknown as ErrorResponse<FileSystemContext>);\n\n // Command Errors\n case ErrorCode.COMMAND_NOT_FOUND:\n return new CommandNotFoundError(errorResponse as unknown as ErrorResponse<CommandNotFoundContext>);\n\n case ErrorCode.COMMAND_PERMISSION_DENIED:\n case ErrorCode.COMMAND_EXECUTION_ERROR:\n case ErrorCode.INVALID_COMMAND:\n case ErrorCode.STREAM_START_ERROR:\n return new CommandError(errorResponse as unknown as ErrorResponse<CommandErrorContext>);\n\n // Process Errors\n case ErrorCode.PROCESS_NOT_FOUND:\n return new ProcessNotFoundError(errorResponse as unknown as ErrorResponse<ProcessNotFoundContext>);\n\n case ErrorCode.PROCESS_PERMISSION_DENIED:\n case ErrorCode.PROCESS_ERROR:\n return new ProcessError(errorResponse as unknown as ErrorResponse<ProcessErrorContext>);\n\n // Port Errors\n case ErrorCode.PORT_ALREADY_EXPOSED:\n return new PortAlreadyExposedError(errorResponse as unknown as ErrorResponse<PortAlreadyExposedContext>);\n\n case ErrorCode.PORT_NOT_EXPOSED:\n return new PortNotExposedError(errorResponse as unknown as ErrorResponse<PortNotExposedContext>);\n\n case ErrorCode.INVALID_PORT_NUMBER:\n case ErrorCode.INVALID_PORT:\n return new InvalidPortError(errorResponse as unknown as ErrorResponse<InvalidPortContext>);\n\n case ErrorCode.SERVICE_NOT_RESPONDING:\n return new ServiceNotRespondingError(errorResponse as unknown as ErrorResponse<PortErrorContext>);\n\n case ErrorCode.PORT_IN_USE:\n return new PortInUseError(errorResponse as unknown as ErrorResponse<PortErrorContext>);\n\n case ErrorCode.PORT_OPERATION_ERROR:\n return new PortError(errorResponse as unknown as ErrorResponse<PortErrorContext>);\n\n case ErrorCode.CUSTOM_DOMAIN_REQUIRED:\n return new CustomDomainRequiredError(errorResponse as unknown as ErrorResponse<InternalErrorContext>);\n\n // Git Errors\n case ErrorCode.GIT_REPOSITORY_NOT_FOUND:\n return new GitRepositoryNotFoundError(errorResponse as unknown as ErrorResponse<GitRepositoryNotFoundContext>);\n\n case ErrorCode.GIT_AUTH_FAILED:\n return new GitAuthenticationError(errorResponse as unknown as ErrorResponse<GitAuthFailedContext>);\n\n case ErrorCode.GIT_BRANCH_NOT_FOUND:\n return new GitBranchNotFoundError(errorResponse as unknown as ErrorResponse<GitBranchNotFoundContext>);\n\n case ErrorCode.GIT_NETWORK_ERROR:\n return new GitNetworkError(errorResponse as unknown as ErrorResponse<GitErrorContext>);\n\n case ErrorCode.GIT_CLONE_FAILED:\n return new GitCloneError(errorResponse as unknown as ErrorResponse<GitErrorContext>);\n\n case ErrorCode.GIT_CHECKOUT_FAILED:\n return new GitCheckoutError(errorResponse as unknown as ErrorResponse<GitErrorContext>);\n\n case ErrorCode.INVALID_GIT_URL:\n return new InvalidGitUrlError(errorResponse as unknown as ErrorResponse<ValidationFailedContext>);\n\n case ErrorCode.GIT_OPERATION_FAILED:\n return new GitError(errorResponse as unknown as ErrorResponse<GitErrorContext>);\n\n // Code Interpreter Errors\n case ErrorCode.INTERPRETER_NOT_READY:\n return new InterpreterNotReadyError(errorResponse as unknown as ErrorResponse<InterpreterNotReadyContext>);\n\n case ErrorCode.CONTEXT_NOT_FOUND:\n return new ContextNotFoundError(errorResponse as unknown as ErrorResponse<ContextNotFoundContext>);\n\n case ErrorCode.CODE_EXECUTION_ERROR:\n return new CodeExecutionError(errorResponse as unknown as ErrorResponse<CodeExecutionContext>);\n\n // Validation Errors\n case ErrorCode.VALIDATION_FAILED:\n return new ValidationFailedError(errorResponse as unknown as ErrorResponse<ValidationFailedContext>);\n\n // Generic Errors\n case ErrorCode.INVALID_JSON_RESPONSE:\n case ErrorCode.UNKNOWN_ERROR:\n case ErrorCode.INTERNAL_ERROR:\n return new SandboxError(errorResponse as unknown as ErrorResponse<InternalErrorContext>);\n\n default:\n // Fallback for unknown error codes\n return new SandboxError(errorResponse);\n }\n}\n","/**\n * Type-safe error classes that wrap ErrorResponse from container\n *\n * All error classes extend SandboxError<TContext> which wraps the full ErrorResponse\n * and provides type-safe accessors for error properties.\n */\n\nimport type {\n CodeExecutionContext,\n CommandErrorContext,\n CommandNotFoundContext,\n ContextNotFoundContext,ErrorResponse,\n FileExistsContext,\n FileNotFoundContext,\n FileSystemContext,\n GitAuthFailedContext,\n GitBranchNotFoundContext,\n GitErrorContext,\n GitRepositoryNotFoundContext,\n InternalErrorContext,\n InterpreterNotReadyContext,\n InvalidPortContext,\n PortAlreadyExposedContext,\n PortErrorContext,\n PortNotExposedContext,\n ProcessErrorContext,\n ProcessNotFoundContext,\n ValidationFailedContext,\n} from '@repo/shared/errors';\n\n/**\n * Base SDK error that wraps ErrorResponse\n * Preserves all error information from container\n */\nexport class SandboxError<TContext = Record<string, unknown>> extends Error {\n constructor(public readonly errorResponse: ErrorResponse<TContext>) {\n super(errorResponse.message);\n this.name = 'SandboxError';\n }\n\n // Convenience accessors\n get code() { return this.errorResponse.code; }\n get context() { return this.errorResponse.context; }\n get httpStatus() { return this.errorResponse.httpStatus; }\n get operation() { return this.errorResponse.operation; }\n get suggestion() { return this.errorResponse.suggestion; }\n get timestamp() { return this.errorResponse.timestamp; }\n get documentation() { return this.errorResponse.documentation; }\n\n // Custom serialization for logging\n toJSON() {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n context: this.context,\n httpStatus: this.httpStatus,\n operation: this.operation,\n suggestion: this.suggestion,\n timestamp: this.timestamp,\n documentation: this.documentation,\n stack: this.stack\n };\n }\n}\n\n// ============================================================================\n// File System Errors\n// ============================================================================\n\n/**\n * Error thrown when a file or directory is not found\n */\nexport class FileNotFoundError extends SandboxError<FileNotFoundContext> {\n constructor(errorResponse: ErrorResponse<FileNotFoundContext>) {\n super(errorResponse);\n this.name = 'FileNotFoundError';\n }\n\n // Type-safe accessors\n get path() { return this.context.path; }\n}\n\n/**\n * Error thrown when a file already exists\n */\nexport class FileExistsError extends SandboxError<FileExistsContext> {\n constructor(errorResponse: ErrorResponse<FileExistsContext>) {\n super(errorResponse);\n this.name = 'FileExistsError';\n }\n\n // Type-safe accessor\n get path() { return this.context.path; }\n}\n\n/**\n * Generic file system error (permissions, disk full, etc.)\n */\nexport class FileSystemError extends SandboxError<FileSystemContext> {\n constructor(errorResponse: ErrorResponse<FileSystemContext>) {\n super(errorResponse);\n this.name = 'FileSystemError';\n }\n\n // Type-safe accessors\n get path() { return this.context.path; }\n get stderr() { return this.context.stderr; }\n get exitCode() { return this.context.exitCode; }\n}\n\n/**\n * Error thrown when permission is denied\n */\nexport class PermissionDeniedError extends SandboxError<FileSystemContext> {\n constructor(errorResponse: ErrorResponse<FileSystemContext>) {\n super(errorResponse);\n this.name = 'PermissionDeniedError';\n }\n\n get path() { return this.context.path; }\n}\n\n// ============================================================================\n// Command Errors\n// ============================================================================\n\n/**\n * Error thrown when a command is not found\n */\nexport class CommandNotFoundError extends SandboxError<CommandNotFoundContext> {\n constructor(errorResponse: ErrorResponse<CommandNotFoundContext>) {\n super(errorResponse);\n this.name = 'CommandNotFoundError';\n }\n\n // Type-safe accessor\n get command() { return this.context.command; }\n}\n\n/**\n * Generic command execution error\n */\nexport class CommandError extends SandboxError<CommandErrorContext> {\n constructor(errorResponse: ErrorResponse<CommandErrorContext>) {\n super(errorResponse);\n this.name = 'CommandError';\n }\n\n // Type-safe accessors\n get command() { return this.context.command; }\n get exitCode() { return this.context.exitCode; }\n get stdout() { return this.context.stdout; }\n get stderr() { return this.context.stderr; }\n}\n\n// ============================================================================\n// Process Errors\n// ============================================================================\n\n/**\n * Error thrown when a process is not found\n */\nexport class ProcessNotFoundError extends SandboxError<ProcessNotFoundContext> {\n constructor(errorResponse: ErrorResponse<ProcessNotFoundContext>) {\n super(errorResponse);\n this.name = 'ProcessNotFoundError';\n }\n\n // Type-safe accessor\n get processId() { return this.context.processId; }\n}\n\n/**\n * Generic process error\n */\nexport class ProcessError extends SandboxError<ProcessErrorContext> {\n constructor(errorResponse: ErrorResponse<ProcessErrorContext>) {\n super(errorResponse);\n this.name = 'ProcessError';\n }\n\n // Type-safe accessors\n get processId() { return this.context.processId; }\n get pid() { return this.context.pid; }\n get exitCode() { return this.context.exitCode; }\n get stderr() { return this.context.stderr; }\n}\n\n// ============================================================================\n// Port Errors\n// ============================================================================\n\n/**\n * Error thrown when a port is already exposed\n */\nexport class PortAlreadyExposedError extends SandboxError<PortAlreadyExposedContext> {\n constructor(errorResponse: ErrorResponse<PortAlreadyExposedContext>) {\n super(errorResponse);\n this.name = 'PortAlreadyExposedError';\n }\n\n // Type-safe accessors\n get port() { return this.context.port; }\n get portName() { return this.context.portName; }\n}\n\n/**\n * Error thrown when a port is not exposed\n */\nexport class PortNotExposedError extends SandboxError<PortNotExposedContext> {\n constructor(errorResponse: ErrorResponse<PortNotExposedContext>) {\n super(errorResponse);\n this.name = 'PortNotExposedError';\n }\n\n // Type-safe accessor\n get port() { return this.context.port; }\n}\n\n/**\n * Error thrown when a port number is invalid\n */\nexport class InvalidPortError extends SandboxError<InvalidPortContext> {\n constructor(errorResponse: ErrorResponse<InvalidPortContext>) {\n super(errorResponse);\n this.name = 'InvalidPortError';\n }\n\n // Type-safe accessors\n get port() { return this.context.port; }\n get reason() { return this.context.reason; }\n}\n\n/**\n * Error thrown when a service on a port is not responding\n */\nexport class ServiceNotRespondingError extends SandboxError<PortErrorContext> {\n constructor(errorResponse: ErrorResponse<PortErrorContext>) {\n super(errorResponse);\n this.name = 'ServiceNotRespondingError';\n }\n\n // Type-safe accessors\n get port() { return this.context.port; }\n get portName() { return this.context.portName; }\n}\n\n/**\n * Error thrown when a port is already in use\n */\nexport class PortInUseError extends SandboxError<PortErrorContext> {\n constructor(errorResponse: ErrorResponse<PortErrorContext>) {\n super(errorResponse);\n this.name = 'PortInUseError';\n }\n\n // Type-safe accessor\n get port() { return this.context.port; }\n}\n\n/**\n * Generic port operation error\n */\nexport class PortError extends SandboxError<PortErrorContext> {\n constructor(errorResponse: ErrorResponse<PortErrorContext>) {\n super(errorResponse);\n this.name = 'PortError';\n }\n\n // Type-safe accessors\n get port() { return this.context.port; }\n get portName() { return this.context.portName; }\n get stderr() { return this.context.stderr; }\n}\n\n/**\n * Error thrown when port exposure requires a custom domain\n */\nexport class CustomDomainRequiredError extends SandboxError<InternalErrorContext> {\n constructor(errorResponse: ErrorResponse<InternalErrorContext>) {\n super(errorResponse);\n this.name = 'CustomDomainRequiredError';\n }\n}\n\n// ============================================================================\n// Git Errors\n// ============================================================================\n\n/**\n * Error thrown when a git repository is not found\n */\nexport class GitRepositoryNotFoundError extends SandboxError<GitRepositoryNotFoundContext> {\n constructor(errorResponse: ErrorResponse<GitRepositoryNotFoundContext>) {\n super(errorResponse);\n this.name = 'GitRepositoryNotFoundError';\n }\n\n // Type-safe accessor\n get repository() { return this.context.repository; }\n}\n\n/**\n * Error thrown when git authentication fails\n */\nexport class GitAuthenticationError extends SandboxError<GitAuthFailedContext> {\n constructor(errorResponse: ErrorResponse<GitAuthFailedContext>) {\n super(errorResponse);\n this.name = 'GitAuthenticationError';\n }\n\n // Type-safe accessor\n get repository() { return this.context.repository; }\n}\n\n/**\n * Error thrown when a git branch is not found\n */\nexport class GitBranchNotFoundError extends SandboxError<GitBranchNotFoundContext> {\n constructor(errorResponse: ErrorResponse<GitBranchNotFoundContext>) {\n super(errorResponse);\n this.name = 'GitBranchNotFoundError';\n }\n\n // Type-safe accessors\n get branch() { return this.context.branch; }\n get repository() { return this.context.repository; }\n}\n\n/**\n * Error thrown when a git network operation fails\n */\nexport class GitNetworkError extends SandboxError<GitErrorContext> {\n constructor(errorResponse: ErrorResponse<GitErrorContext>) {\n super(errorResponse);\n this.name = 'GitNetworkError';\n }\n\n // Type-safe accessors\n get repository() { return this.context.repository; }\n get branch() { return this.context.branch; }\n get targetDir() { return this.context.targetDir; }\n}\n\n/**\n * Error thrown when git clone fails\n */\nexport class GitCloneError extends SandboxError<GitErrorContext> {\n constructor(errorResponse: ErrorResponse<GitErrorContext>) {\n super(errorResponse);\n this.name = 'GitCloneError';\n }\n\n // Type-safe accessors\n get repository() { return this.context.repository; }\n get targetDir() { return this.context.targetDir; }\n get stderr() { return this.context.stderr; }\n get exitCode() { return this.context.exitCode; }\n}\n\n/**\n * Error thrown when git checkout fails\n */\nexport class GitCheckoutError extends SandboxError<GitErrorContext> {\n constructor(errorResponse: ErrorResponse<GitErrorContext>) {\n super(errorResponse);\n this.name = 'GitCheckoutError';\n }\n\n // Type-safe accessors\n get branch() { return this.context.branch; }\n get repository() { return this.context.repository; }\n get stderr() { return this.context.stderr; }\n}\n\n/**\n * Error thrown when a git URL is invalid\n */\nexport class InvalidGitUrlError extends SandboxError<ValidationFailedContext> {\n constructor(errorResponse: ErrorResponse<ValidationFailedContext>) {\n super(errorResponse);\n this.name = 'InvalidGitUrlError';\n }\n\n // Type-safe accessor\n get validationErrors() { return this.context.validationErrors; }\n}\n\n/**\n * Generic git operation error\n */\nexport class GitError extends SandboxError<GitErrorContext> {\n constructor(errorResponse: ErrorResponse<GitErrorContext>) {\n super(errorResponse);\n this.name = 'GitError';\n }\n\n // Type-safe accessors\n get repository() { return this.context.repository; }\n get branch() { return this.context.branch; }\n get targetDir() { return this.context.targetDir; }\n get stderr() { return this.context.stderr; }\n get exitCode() { return this.context.exitCode; }\n}\n\n// ============================================================================\n// Code Interpreter Errors\n// ============================================================================\n\n/**\n * Error thrown when interpreter is not ready\n */\nexport class InterpreterNotReadyError extends SandboxError<InterpreterNotReadyContext> {\n constructor(errorResponse: ErrorResponse<InterpreterNotReadyContext>) {\n super(errorResponse);\n this.name = 'InterpreterNotReadyError';\n }\n\n // Type-safe accessors\n get retryAfter() { return this.context.retryAfter; }\n get progress() { return this.context.progress; }\n}\n\n/**\n * Error thrown when a context is not found\n */\nexport class ContextNotFoundError extends SandboxError<ContextNotFoundContext> {\n constructor(errorResponse: ErrorResponse<ContextNotFoundContext>) {\n super(errorResponse);\n this.name = 'ContextNotFoundError';\n }\n\n // Type-safe accessor\n get contextId() { return this.context.contextId; }\n}\n\n/**\n * Error thrown when code execution fails\n */\nexport class CodeExecutionError extends SandboxError<CodeExecutionContext> {\n constructor(errorResponse: ErrorResponse<CodeExecutionContext>) {\n super(errorResponse);\n this.name = 'CodeExecutionError';\n }\n\n // Type-safe accessors\n get contextId() { return this.context.contextId; }\n get ename() { return this.context.ename; }\n get evalue() { return this.context.evalue; }\n get traceback() { return this.context.traceback; }\n}\n\n// ============================================================================\n// Validation Errors\n// ============================================================================\n\n/**\n * Error thrown when validation fails\n */\nexport class ValidationFailedError extends SandboxError<ValidationFailedContext> {\n constructor(errorResponse: ErrorResponse<ValidationFailedContext>) {\n super(errorResponse);\n this.name = 'ValidationFailedError';\n }\n\n // Type-safe accessor\n get validationErrors() { return this.context.validationErrors; }\n}\n","import { BaseHttpClient } from './base-client';\nimport type { BaseApiResponse, HttpClientOptions, SessionRequest } from './types';\n\n/**\n * Request interface for command execution\n */\nexport interface ExecuteRequest extends SessionRequest {\n command: string;\n timeoutMs?: number;\n}\n\n/**\n * Response interface for command execution\n */\nexport interface ExecuteResponse extends BaseApiResponse {\n stdout: string;\n stderr: string;\n exitCode: number;\n command: string;\n}\n\n/**\n * Client for command execution operations\n */\nexport class CommandClient extends BaseHttpClient {\n\n /**\n * Execute a command and return the complete result\n * @param command - The command to execute\n * @param sessionId - The session ID for this command execution\n * @param timeoutMs - Optional timeout in milliseconds (unlimited by default)\n */\n async execute(\n command: string,\n sessionId: string,\n timeoutMs?: number\n ): Promise<ExecuteResponse> {\n try {\n const data: ExecuteRequest = {\n command,\n sessionId,\n ...(timeoutMs !== undefined && { timeoutMs })\n };\n\n const response = await this.post<ExecuteResponse>(\n '/api/execute',\n data\n );\n\n this.logSuccess(\n 'Command executed',\n `${command}, Success: ${response.success}`\n );\n\n // Call the callback if provided\n this.options.onCommandComplete?.(\n response.success,\n response.exitCode,\n response.stdout,\n response.stderr,\n response.command\n );\n\n return response;\n } catch (error) {\n this.logError('execute', error);\n\n // Call error callback if provided\n this.options.onError?.(\n error instanceof Error ? error.message : String(error),\n command\n );\n\n throw error;\n }\n }\n\n /**\n * Execute a command and return a stream of events\n * @param command - The command to execute\n * @param sessionId - The session ID for this command execution\n */\n async executeStream(\n command: string,\n sessionId: string\n ): Promise<ReadableStream<Uint8Array>> {\n try {\n const data = { command, sessionId };\n\n const response = await this.doFetch('/api/execute/stream', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(data),\n });\n\n const stream = await this.handleStreamResponse(response);\n\n this.logSuccess('Command stream started', command);\n\n return stream;\n } catch (error) {\n this.logError('executeStream', error);\n\n // Call error callback if provided\n this.options.onError?.(\n error instanceof Error ? error.message : String(error),\n command\n );\n\n throw error;\n }\n }\n}\n","import type {\n DeleteFileResult,\n ListFilesOptions,\n ListFilesResult,\n MkdirResult,\n MoveFileResult,\n ReadFileResult,\n RenameFileResult,\n WriteFileResult\n} from '@repo/shared';\nimport { BaseHttpClient } from './base-client';\nimport type { HttpClientOptions, SessionRequest } from './types';\n\n/**\n * Request interface for creating directories\n */\nexport interface MkdirRequest extends SessionRequest {\n path: string;\n recursive?: boolean;\n}\n\n/**\n * Request interface for writing files\n */\nexport interface WriteFileRequest extends SessionRequest {\n path: string;\n content: string;\n encoding?: string;\n}\n\n/**\n * Request interface for reading files\n */\nexport interface ReadFileRequest extends SessionRequest {\n path: string;\n encoding?: string;\n}\n\n/**\n * Request interface for file operations (delete, rename, move)\n */\nexport interface FileOperationRequest extends SessionRequest {\n path: string;\n newPath?: string; // For rename/move operations\n}\n\n/**\n * Client for file system operations\n */\nexport class FileClient extends BaseHttpClient {\n\n /**\n * Create a directory\n * @param path - Directory path to create\n * @param sessionId - The session ID for this operation\n * @param options - Optional settings (recursive)\n */\n async mkdir(\n path: string,\n sessionId: string,\n options?: { recursive?: boolean }\n ): Promise<MkdirResult> {\n try {\n const data = {\n path,\n sessionId,\n recursive: options?.recursive ?? false,\n };\n\n const response = await this.post<MkdirResult>('/api/mkdir', data);\n \n this.logSuccess('Directory created', `${path} (recursive: ${data.recursive})`);\n return response;\n } catch (error) {\n this.logError('mkdir', error);\n throw error;\n }\n }\n\n /**\n * Write content to a file\n * @param path - File path to write to\n * @param content - Content to write\n * @param sessionId - The session ID for this operation\n * @param options - Optional settings (encoding)\n */\n async writeFile(\n path: string,\n content: string,\n sessionId: string,\n options?: { encoding?: string }\n ): Promise<WriteFileResult> {\n try {\n const data = {\n path,\n content,\n sessionId,\n encoding: options?.encoding ?? 'utf8',\n };\n\n const response = await this.post<WriteFileResult>('/api/write', data);\n \n this.logSuccess('File written', `${path} (${content.length} chars)`);\n return response;\n } catch (error) {\n this.logError('writeFile', error);\n throw error;\n }\n }\n\n /**\n * Read content from a file\n * @param path - File path to read from\n * @param sessionId - The session ID for this operation\n * @param options - Optional settings (encoding)\n */\n async readFile(\n path: string,\n sessionId: string,\n options?: { encoding?: string }\n ): Promise<ReadFileResult> {\n try {\n const data = {\n path,\n sessionId,\n encoding: options?.encoding ?? 'utf8',\n };\n\n const response = await this.post<ReadFileResult>('/api/read', data);\n\n this.logSuccess('File read', `${path} (${response.content.length} chars)`);\n return response;\n } catch (error) {\n this.logError('readFile', error);\n throw error;\n }\n }\n\n /**\n * Stream a file using Server-Sent Events\n * Returns a ReadableStream of SSE events containing metadata, chunks, and completion\n * @param path - File path to stream\n * @param sessionId - The session ID for this operation\n */\n async readFileStream(\n path: string,\n sessionId: string\n ): Promise<ReadableStream<Uint8Array>> {\n try {\n const data = {\n path,\n sessionId,\n };\n\n const response = await this.doFetch('/api/read/stream', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(data),\n });\n\n const stream = await this.handleStreamResponse(response);\n this.logSuccess('File stream started', path);\n return stream;\n } catch (error) {\n this.logError('readFileStream', error);\n throw error;\n }\n }\n\n /**\n * Delete a file\n * @param path - File path to delete\n * @param sessionId - The session ID for this operation\n */\n async deleteFile(\n path: string,\n sessionId: string\n ): Promise<DeleteFileResult> {\n try {\n const data = { path, sessionId };\n\n const response = await this.post<DeleteFileResult>('/api/delete', data);\n \n this.logSuccess('File deleted', path);\n return response;\n } catch (error) {\n this.logError('deleteFile', error);\n throw error;\n }\n }\n\n /**\n * Rename a file\n * @param path - Current file path\n * @param newPath - New file path\n * @param sessionId - The session ID for this operation\n */\n async renameFile(\n path: string,\n newPath: string,\n sessionId: string\n ): Promise<RenameFileResult> {\n try {\n const data = { oldPath: path, newPath, sessionId };\n\n const response = await this.post<RenameFileResult>('/api/rename', data);\n \n this.logSuccess('File renamed', `${path} -> ${newPath}`);\n return response;\n } catch (error) {\n this.logError('renameFile', error);\n throw error;\n }\n }\n\n /**\n * Move a file\n * @param path - Current file path\n * @param newPath - Destination file path\n * @param sessionId - The session ID for this operation\n */\n async moveFile(\n path: string,\n newPath: string,\n sessionId: string\n ): Promise<MoveFileResult> {\n try {\n const data = { sourcePath: path, destinationPath: newPath, sessionId };\n\n const response = await this.post<MoveFileResult>('/api/move', data);\n\n this.logSuccess('File moved', `${path} -> ${newPath}`);\n return response;\n } catch (error) {\n this.logError('moveFile', error);\n throw error;\n }\n }\n\n /**\n * List files in a directory\n * @param path - Directory path to list\n * @param sessionId - The session ID for this operation\n * @param options - Optional settings (recursive, includeHidden)\n */\n async listFiles(\n path: string,\n sessionId: string,\n options?: ListFilesOptions\n ): Promise<ListFilesResult> {\n try {\n const data = {\n path,\n sessionId,\n options: options || {},\n };\n\n const response = await this.post<ListFilesResult>('/api/list-files', data);\n\n this.logSuccess('Files listed', `${path} (${response.count} files)`);\n return response;\n } catch (error) {\n this.logError('listFiles', error);\n throw error;\n }\n }\n}","import type { GitCheckoutResult } from '@repo/shared';\nimport { BaseHttpClient } from './base-client';\nimport type { HttpClientOptions, SessionRequest } from './types';\n\n// Re-export for convenience\nexport type { GitCheckoutResult };\n\n/**\n * Request interface for Git checkout operations\n */\nexport interface GitCheckoutRequest extends SessionRequest {\n repoUrl: string;\n branch?: string;\n targetDir?: string;\n}\n\n/**\n * Client for Git repository operations\n */\nexport class GitClient extends BaseHttpClient {\n\n /**\n * Clone a Git repository\n * @param repoUrl - URL of the Git repository to clone\n * @param sessionId - The session ID for this operation\n * @param options - Optional settings (branch, targetDir)\n */\n async checkout(\n repoUrl: string,\n sessionId: string,\n options?: {\n branch?: string;\n targetDir?: string;\n }\n ): Promise<GitCheckoutResult> {\n try {\n // Determine target directory - use provided path or generate from repo name\n let targetDir = options?.targetDir;\n if (!targetDir) {\n const repoName = this.extractRepoName(repoUrl);\n // Ensure absolute path in /workspace\n targetDir = `/workspace/${repoName}`;\n }\n\n const data: GitCheckoutRequest = {\n repoUrl,\n sessionId,\n targetDir,\n };\n\n // Only include branch if explicitly specified\n // This allows Git to use the repository's default branch\n if (options?.branch) {\n data.branch = options.branch;\n }\n\n const response = await this.post<GitCheckoutResult>(\n '/api/git/checkout',\n data\n );\n\n this.logSuccess(\n 'Repository cloned',\n `${repoUrl} (branch: ${response.branch}) -> ${response.targetDir}`\n );\n\n return response;\n } catch (error) {\n this.logError('checkout', error);\n throw error;\n }\n }\n\n /**\n * Extract repository name from URL for default directory name\n */\n private extractRepoName(repoUrl: string): string {\n try {\n const url = new URL(repoUrl);\n const pathParts = url.pathname.split('/');\n const repoName = pathParts[pathParts.length - 1];\n \n // Remove .git extension if present\n return repoName.replace(/\\.git$/, '');\n } catch {\n // Fallback for invalid URLs\n const parts = repoUrl.split('/');\n const repoName = parts[parts.length - 1];\n return repoName.replace(/\\.git$/, '') || 'repo';\n }\n }\n}","import {\n type CodeContext,\n type ContextCreateResult,\n type ContextListResult,\n type CreateContextOptions,\n type ExecutionError,\n type OutputMessage,\n type Result,\n ResultImpl,\n} from '@repo/shared';\nimport type { ErrorResponse } from '../errors';\nimport { createErrorFromResponse, ErrorCode, InterpreterNotReadyError } from '../errors';\nimport { BaseHttpClient } from './base-client.js';\nimport type { HttpClientOptions } from './types.js';\n\n// Streaming execution data from the server\ninterface StreamingExecutionData {\n type: \"result\" | \"stdout\" | \"stderr\" | \"error\" | \"execution_complete\";\n text?: string;\n html?: string;\n png?: string; // base64\n jpeg?: string; // base64\n svg?: string;\n latex?: string;\n markdown?: string;\n javascript?: string;\n json?: unknown;\n chart?: {\n type:\n | \"line\"\n | \"bar\"\n | \"scatter\"\n | \"pie\"\n | \"histogram\"\n | \"heatmap\"\n | \"unknown\";\n data: unknown;\n options?: unknown;\n };\n data?: unknown;\n metadata?: Record<string, unknown>;\n execution_count?: number;\n ename?: string;\n evalue?: string;\n traceback?: string[];\n lineNumber?: number;\n timestamp?: number;\n}\n\nexport interface ExecutionCallbacks {\n onStdout?: (output: OutputMessage) => void | Promise<void>;\n onStderr?: (output: OutputMessage) => void | Promise<void>;\n onResult?: (result: Result) => void | Promise<void>;\n onError?: (error: ExecutionError) => void | Promise<void>;\n}\n\nexport class InterpreterClient extends BaseHttpClient {\n private readonly maxRetries = 3;\n private readonly retryDelayMs = 1000;\n\n async createCodeContext(\n options: CreateContextOptions = {}\n ): Promise<CodeContext> {\n return this.executeWithRetry(async () => {\n const response = await this.doFetch(\"/api/contexts\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n language: options.language || \"python\",\n cwd: options.cwd || \"/workspace\",\n env_vars: options.envVars,\n }),\n });\n\n if (!response.ok) {\n const error = await this.parseErrorResponse(response);\n throw error;\n }\n\n const data = (await response.json()) as ContextCreateResult;\n if (!data.success) {\n throw new Error(`Failed to create context: ${JSON.stringify(data)}`);\n }\n\n return {\n id: data.contextId,\n language: data.language,\n cwd: data.cwd || '/workspace',\n createdAt: new Date(data.timestamp),\n lastUsed: new Date(data.timestamp),\n };\n });\n }\n\n async runCodeStream(\n contextId: string | undefined,\n code: string,\n language: string | undefined,\n callbacks: ExecutionCallbacks,\n timeoutMs?: number\n ): Promise<void> {\n return this.executeWithRetry(async () => {\n const response = await this.doFetch(\"/api/execute/code\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"text/event-stream\",\n },\n body: JSON.stringify({\n context_id: contextId,\n code,\n language,\n ...(timeoutMs !== undefined && { timeout_ms: timeoutMs })\n }),\n });\n\n if (!response.ok) {\n const error = await this.parseErrorResponse(response);\n throw error;\n }\n\n if (!response.body) {\n throw new Error(\"No response body for streaming execution\");\n }\n\n // Process streaming response\n for await (const chunk of this.readLines(response.body)) {\n await this.parseExecutionResult(chunk, callbacks);\n }\n });\n }\n\n async listCodeContexts(): Promise<CodeContext[]> {\n return this.executeWithRetry(async () => {\n const response = await this.doFetch(\"/api/contexts\", {\n method: \"GET\",\n headers: { \"Content-Type\": \"application/json\" },\n });\n\n if (!response.ok) {\n const error = await this.parseErrorResponse(response);\n throw error;\n }\n\n const data = (await response.json()) as ContextListResult;\n if (!data.success) {\n throw new Error(`Failed to list contexts: ${JSON.stringify(data)}`);\n }\n\n return data.contexts.map((ctx) => ({\n id: ctx.id,\n language: ctx.language,\n cwd: ctx.cwd || '/workspace',\n createdAt: new Date(data.timestamp),\n lastUsed: new Date(data.timestamp),\n }));\n });\n }\n\n async deleteCodeContext(contextId: string): Promise<void> {\n return this.executeWithRetry(async () => {\n const response = await this.doFetch(`/api/contexts/${contextId}`, {\n method: \"DELETE\",\n headers: { \"Content-Type\": \"application/json\" },\n });\n\n if (!response.ok) {\n const error = await this.parseErrorResponse(response);\n throw error;\n }\n });\n }\n\n /**\n * Execute an operation with automatic retry for transient errors\n */\n private async executeWithRetry<T>(operation: () => Promise<T>): Promise<T> {\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt < this.maxRetries; attempt++) {\n try {\n return await operation();\n } catch (error) {\n this.logError('executeWithRetry', error);\n lastError = error as Error;\n\n // Check if it's a retryable error (interpreter not ready)\n if (this.isRetryableError(error)) {\n // Don't retry on the last attempt\n if (attempt < this.maxRetries - 1) {\n // Exponential backoff with jitter\n const delay =\n this.retryDelayMs * 2 ** attempt + Math.random() * 1000;\n await new Promise((resolve) => setTimeout(resolve, delay));\n continue;\n }\n }\n\n // Not retryable or last attempt - throw the error\n throw error;\n }\n }\n\n throw lastError || new Error(\"Execution failed after retries\");\n }\n\n private isRetryableError(error: unknown): boolean {\n if (error instanceof InterpreterNotReadyError) {\n return true;\n }\n\n if (error instanceof Error) {\n return (\n error.message.includes(\"not ready\") ||\n error.message.includes(\"initializing\")\n );\n }\n\n return false;\n }\n\n private async parseErrorResponse(response: Response): Promise<Error> {\n try {\n const errorData = await response.json() as ErrorResponse;\n return createErrorFromResponse(errorData);\n } catch {\n // Fallback if response isn't JSON\n const errorResponse: ErrorResponse = {\n code: ErrorCode.INTERNAL_ERROR,\n message: `HTTP ${response.status}: ${response.statusText}`,\n context: {},\n httpStatus: response.status,\n timestamp: new Date().toISOString()\n };\n return createErrorFromResponse(errorResponse);\n }\n }\n\n private async *readLines(\n stream: ReadableStream<Uint8Array>\n ): AsyncGenerator<string> {\n const reader = stream.getReader();\n let buffer = \"\";\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (value) {\n buffer += new TextDecoder().decode(value);\n }\n if (done) break;\n\n let newlineIdx = buffer.indexOf(\"\\n\");\n while (newlineIdx !== -1) {\n yield buffer.slice(0, newlineIdx);\n buffer = buffer.slice(newlineIdx + 1);\n newlineIdx = buffer.indexOf(\"\\n\");\n }\n }\n\n // Yield any remaining data\n if (buffer.length > 0) {\n yield buffer;\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n private async parseExecutionResult(\n line: string,\n callbacks: ExecutionCallbacks\n ) {\n if (!line.trim()) return;\n\n // Skip lines that don't start with \"data: \" (SSE format)\n if (!line.startsWith('data: ')) return;\n\n try {\n // Strip \"data: \" prefix and parse JSON\n const jsonData = line.substring(6); // \"data: \" is 6 characters\n const data = JSON.parse(jsonData) as StreamingExecutionData;\n\n switch (data.type) {\n case \"stdout\":\n if (callbacks.onStdout && data.text) {\n await callbacks.onStdout({\n text: data.text,\n timestamp: data.timestamp || Date.now(),\n });\n }\n break;\n\n case \"stderr\":\n if (callbacks.onStderr && data.text) {\n await callbacks.onStderr({\n text: data.text,\n timestamp: data.timestamp || Date.now(),\n });\n }\n break;\n\n case \"result\":\n if (callbacks.onResult) {\n // Create a ResultImpl instance from the raw data\n const result = new ResultImpl(data);\n await callbacks.onResult(result);\n }\n break;\n\n case \"error\":\n if (callbacks.onError) {\n await callbacks.onError({\n name: data.ename || \"Error\",\n message: data.evalue || \"Unknown error\",\n traceback: data.traceback || [],\n });\n }\n break;\n\n case \"execution_complete\":\n // Signal completion - callbacks can handle cleanup if needed\n break;\n }\n } catch (error) {\n this.logError('parseExecutionResult', error);\n }\n }\n}\n","import type {\n PortCloseResult,\n PortExposeResult,\n PortListResult,\n} from '@repo/shared';\nimport { BaseHttpClient } from './base-client';\nimport type { HttpClientOptions } from './types';\n\n// Re-export for convenience\nexport type {\n PortExposeResult,\n PortCloseResult,\n PortListResult,\n};\n\n/**\n * Request interface for exposing ports\n */\nexport interface ExposePortRequest {\n port: number;\n name?: string;\n}\n\n/**\n * Request interface for unexposing ports\n */\nexport interface UnexposePortRequest {\n port: number;\n}\n\n/**\n * Client for port management and preview URL operations\n */\nexport class PortClient extends BaseHttpClient {\n\n /**\n * Expose a port and get a preview URL\n * @param port - Port number to expose\n * @param sessionId - The session ID for this operation\n * @param name - Optional name for the port\n */\n async exposePort(\n port: number,\n sessionId: string,\n name?: string\n ): Promise<PortExposeResult> {\n try {\n const data = { port, sessionId, name };\n\n const response = await this.post<PortExposeResult>(\n '/api/expose-port',\n data\n );\n\n this.logSuccess(\n 'Port exposed',\n `${port} exposed at ${response.url}${name ? ` (${name})` : ''}`\n );\n\n return response;\n } catch (error) {\n this.logError('exposePort', error);\n throw error;\n }\n }\n\n /**\n * Unexpose a port and remove its preview URL\n * @param port - Port number to unexpose\n * @param sessionId - The session ID for this operation\n */\n async unexposePort(port: number, sessionId: string): Promise<PortCloseResult> {\n try {\n const url = `/api/exposed-ports/${port}?session=${encodeURIComponent(sessionId)}`;\n const response = await this.delete<PortCloseResult>(url);\n\n this.logSuccess('Port unexposed', `${port}`);\n return response;\n } catch (error) {\n this.logError('unexposePort', error);\n throw error;\n }\n }\n\n /**\n * Get all currently exposed ports\n * @param sessionId - The session ID for this operation\n */\n async getExposedPorts(sessionId: string): Promise<PortListResult> {\n try {\n const url = `/api/exposed-ports?session=${encodeURIComponent(sessionId)}`;\n const response = await this.get<PortListResult>(url);\n\n this.logSuccess(\n 'Exposed ports retrieved',\n `${response.ports.length} ports exposed`\n );\n\n return response;\n } catch (error) {\n this.logError('getExposedPorts', error);\n throw error;\n }\n }\n}","import type {\n ProcessCleanupResult,\n ProcessInfoResult,\n ProcessKillResult,\n ProcessListResult,\n ProcessLogsResult,\n ProcessStartResult,\n StartProcessRequest,\n} from '@repo/shared';\nimport { BaseHttpClient } from './base-client';\nimport type { HttpClientOptions } from './types';\n\n// Re-export for convenience\nexport type {\n StartProcessRequest,\n ProcessStartResult,\n ProcessListResult,\n ProcessInfoResult,\n ProcessKillResult,\n ProcessLogsResult,\n ProcessCleanupResult,\n};\n\n\n/**\n * Client for background process management\n */\nexport class ProcessClient extends BaseHttpClient {\n\n /**\n * Start a background process\n * @param command - Command to execute as a background process\n * @param sessionId - The session ID for this operation\n * @param options - Optional settings (processId)\n */\n async startProcess(\n command: string,\n sessionId: string,\n options?: { processId?: string }\n ): Promise<ProcessStartResult> {\n try {\n const data: StartProcessRequest = {\n command,\n sessionId,\n processId: options?.processId,\n };\n\n const response = await this.post<ProcessStartResult>(\n '/api/process/start',\n data\n );\n\n this.logSuccess(\n 'Process started',\n `${command} (ID: ${response.processId})`\n );\n\n return response;\n } catch (error) {\n this.logError('startProcess', error);\n throw error;\n }\n }\n\n /**\n * List all processes (sandbox-scoped, not session-scoped)\n */\n async listProcesses(): Promise<ProcessListResult> {\n try {\n const url = `/api/process/list`;\n const response = await this.get<ProcessListResult>(url);\n\n this.logSuccess('Processes listed', `${response.processes.length} processes`);\n return response;\n } catch (error) {\n this.logError('listProcesses', error);\n throw error;\n }\n }\n\n /**\n * Get information about a specific process (sandbox-scoped, not session-scoped)\n * @param processId - ID of the process to retrieve\n */\n async getProcess(processId: string): Promise<ProcessInfoResult> {\n try {\n const url = `/api/process/${processId}`;\n const response = await this.get<ProcessInfoResult>(url);\n\n this.logSuccess('Process retrieved', `ID: ${processId}`);\n return response;\n } catch (error) {\n this.logError('getProcess', error);\n throw error;\n }\n }\n\n /**\n * Kill a specific process (sandbox-scoped, not session-scoped)\n * @param processId - ID of the process to kill\n */\n async killProcess(processId: string): Promise<ProcessKillResult> {\n try {\n const url = `/api/process/${processId}`;\n const response = await this.delete<ProcessKillResult>(url);\n\n this.logSuccess('Process killed', `ID: ${processId}`);\n return response;\n } catch (error) {\n this.logError('killProcess', error);\n throw error;\n }\n }\n\n /**\n * Kill all running processes (sandbox-scoped, not session-scoped)\n */\n async killAllProcesses(): Promise<ProcessCleanupResult> {\n try {\n const url = `/api/process/kill-all`;\n const response = await this.delete<ProcessCleanupResult>(url);\n\n this.logSuccess(\n 'All processes killed',\n `${response.cleanedCount} processes terminated`\n );\n\n return response;\n } catch (error) {\n this.logError('killAllProcesses', error);\n throw error;\n }\n }\n\n /**\n * Get logs from a specific process (sandbox-scoped, not session-scoped)\n * @param processId - ID of the process to get logs from\n */\n async getProcessLogs(processId: string): Promise<ProcessLogsResult> {\n try {\n const url = `/api/process/${processId}/logs`;\n const response = await this.get<ProcessLogsResult>(url);\n\n this.logSuccess(\n 'Process logs retrieved',\n `ID: ${processId}, stdout: ${response.stdout.length} chars, stderr: ${response.stderr.length} chars`\n );\n\n return response;\n } catch (error) {\n this.logError('getProcessLogs', error);\n throw error;\n }\n }\n\n /**\n * Stream logs from a specific process (sandbox-scoped, not session-scoped)\n * @param processId - ID of the process to stream logs from\n */\n async streamProcessLogs(processId: string): Promise<ReadableStream<Uint8Array>> {\n try {\n const url = `/api/process/${processId}/stream`;\n const response = await this.doFetch(url, {\n method: 'GET',\n });\n\n const stream = await this.handleStreamResponse(response);\n\n this.logSuccess('Process log stream started', `ID: ${processId}`);\n\n return stream;\n } catch (error) {\n this.logError('streamProcessLogs', error);\n throw error;\n }\n }\n}\n","import { BaseHttpClient } from './base-client';\nimport type { BaseApiResponse, HttpClientOptions } from './types';\n\n/**\n * Response interface for ping operations\n */\nexport interface PingResponse extends BaseApiResponse {\n message: string;\n uptime?: number;\n}\n\n/**\n * Response interface for getting available commands\n */\nexport interface CommandsResponse extends BaseApiResponse {\n availableCommands: string[];\n count: number;\n}\n\n/**\n * Request interface for creating sessions\n */\nexport interface CreateSessionRequest {\n id: string;\n env?: Record<string, string>;\n cwd?: string;\n}\n\n/**\n * Response interface for creating sessions\n */\nexport interface CreateSessionResponse extends BaseApiResponse {\n id: string;\n message: string;\n}\n\n/**\n * Client for health checks and utility operations\n */\nexport class UtilityClient extends BaseHttpClient {\n\n /**\n * Ping the sandbox to check if it's responsive\n */\n async ping(): Promise<string> {\n try {\n const response = await this.get<PingResponse>('/api/ping');\n \n this.logSuccess('Ping successful', response.message);\n return response.message;\n } catch (error) {\n this.logError('ping', error);\n throw error;\n }\n }\n\n /**\n * Get list of available commands in the sandbox environment\n */\n async getCommands(): Promise<string[]> {\n try {\n const response = await this.get<CommandsResponse>('/api/commands');\n \n this.logSuccess(\n 'Commands retrieved',\n `${response.count} commands available`\n );\n\n return response.availableCommands;\n } catch (error) {\n this.logError('getCommands', error);\n throw error;\n }\n }\n\n /**\n * Create a new execution session\n * @param options - Session configuration (id, env, cwd)\n */\n async createSession(options: CreateSessionRequest): Promise<CreateSessionResponse> {\n try {\n const response = await this.post<CreateSessionResponse>(\n '/api/session/create',\n options\n );\n\n this.logSuccess('Session created', `ID: ${options.id}`);\n return response;\n } catch (error) {\n this.logError('createSession', error);\n throw error;\n }\n }\n}","import { CommandClient } from './command-client';\nimport { FileClient } from './file-client';\nimport { GitClient } from './git-client';\nimport { InterpreterClient } from './interpreter-client';\nimport { PortClient } from './port-client';\nimport { ProcessClient } from './process-client';\nimport type { HttpClientOptions } from './types';\nimport { UtilityClient } from './utility-client';\n\n/**\n * Main sandbox client that composes all domain-specific clients\n * Provides organized access to all sandbox functionality\n */\nexport class SandboxClient {\n public readonly commands: CommandClient;\n public readonly files: FileClient;\n public readonly processes: ProcessClient;\n public readonly ports: PortClient;\n public readonly git: GitClient;\n public readonly interpreter: InterpreterClient;\n public readonly utils: UtilityClient;\n\n constructor(options: HttpClientOptions) {\n // Ensure baseUrl is provided for all clients\n const clientOptions: HttpClientOptions = {\n baseUrl: 'http://localhost:3000',\n ...options,\n };\n\n // Initialize all domain clients with shared options\n this.commands = new CommandClient(clientOptions);\n this.files = new FileClient(clientOptions);\n this.processes = new ProcessClient(clientOptions);\n this.ports = new PortClient(clientOptions);\n this.git = new GitClient(clientOptions);\n this.interpreter = new InterpreterClient(clientOptions);\n this.utils = new UtilityClient(clientOptions);\n }\n\n\n}"],"mappings":"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","names":["createLogger","TraceContext","ErrorCode","ErrorCode","ErrorCode","ErrorCode","TraceContext","createLogger"]}
@@ -55,24 +55,17 @@ function sanitizeSandboxId(id) {
55
55
  }
56
56
  return id;
57
57
  }
58
- function logSecurityEvent(event, details, severity = "medium") {
59
- const logEntry = {
60
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
61
- event,
62
- severity,
63
- ...details
64
- };
65
- switch (severity) {
66
- case "critical":
67
- case "high":
68
- console.error(`[SECURITY:${severity.toUpperCase()}] ${event}:`, JSON.stringify(logEntry));
69
- break;
70
- case "medium":
71
- console.warn(`[SECURITY:${severity.toUpperCase()}] ${event}:`, JSON.stringify(logEntry));
72
- break;
73
- case "low":
74
- console.info(`[SECURITY:${severity.toUpperCase()}] ${event}:`, JSON.stringify(logEntry));
75
- break;
58
+ function validateLanguage(language) {
59
+ if (!language) {
60
+ return;
61
+ }
62
+ const supportedLanguages = ["python", "python3", "javascript", "js", "node", "typescript", "ts"];
63
+ const normalized = language.toLowerCase();
64
+ if (!supportedLanguages.includes(normalized)) {
65
+ throw new SecurityError(
66
+ `Unsupported language '${language}'. Supported languages: python, javascript, typescript`,
67
+ "INVALID_LANGUAGE"
68
+ );
76
69
  }
77
70
  }
78
71
 
@@ -80,6 +73,6 @@ export {
80
73
  SecurityError,
81
74
  validatePort,
82
75
  sanitizeSandboxId,
83
- logSecurityEvent
76
+ validateLanguage
84
77
  };
85
- //# sourceMappingURL=chunk-6UAWTJ5S.js.map
78
+ //# sourceMappingURL=chunk-Z532A7QC.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/security.ts"],"sourcesContent":["/**\n * Security utilities for URL construction and input validation\n *\n * This module contains critical security functions to prevent:\n * - URL injection attacks\n * - SSRF (Server-Side Request Forgery) attacks\n * - DNS rebinding attacks\n * - Host header injection\n * - Open redirect vulnerabilities\n */\n\nexport class SecurityError extends Error {\n constructor(message: string, public readonly code?: string) {\n super(message);\n this.name = 'SecurityError';\n }\n}\n\n/**\n * Validates port numbers for sandbox services\n * Only allows non-system ports to prevent conflicts and security issues\n */\nexport function validatePort(port: number): boolean {\n // Must be a valid integer\n if (!Number.isInteger(port)) {\n return false;\n }\n\n // Only allow non-system ports (1024-65535)\n if (port < 1024 || port > 65535) {\n return false;\n }\n\n // Exclude ports reserved by our system\n const reservedPorts = [\n 3000, // Control plane port\n 8787, // Common wrangler dev port\n ];\n\n if (reservedPorts.includes(port)) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Sanitizes and validates sandbox IDs for DNS compliance and security\n * Only enforces critical requirements - allows maximum developer flexibility\n */\nexport function sanitizeSandboxId(id: string): string {\n // Basic validation: not empty, reasonable length limit (DNS subdomain limit is 63 chars)\n if (!id || id.length > 63) {\n throw new SecurityError(\n 'Sandbox ID must be 1-63 characters long.',\n 'INVALID_SANDBOX_ID_LENGTH'\n );\n }\n\n // DNS compliance: cannot start or end with hyphens (RFC requirement)\n if (id.startsWith('-') || id.endsWith('-')) {\n throw new SecurityError(\n 'Sandbox ID cannot start or end with hyphens (DNS requirement).',\n 'INVALID_SANDBOX_ID_HYPHENS'\n );\n }\n\n // Prevent reserved names that cause technical conflicts\n const reservedNames = [\n 'www', 'api', 'admin', 'root', 'system',\n 'cloudflare', 'workers'\n ];\n\n const lowerCaseId = id.toLowerCase();\n if (reservedNames.includes(lowerCaseId)) {\n throw new SecurityError(\n `Reserved sandbox ID '${id}' is not allowed.`,\n 'RESERVED_SANDBOX_ID'\n );\n }\n\n return id;\n}\n\n\n/**\n * Logs security events for monitoring\n */\nexport function logSecurityEvent(\n event: string,\n details: Record<string, any>,\n severity: 'low' | 'medium' | 'high' | 'critical' = 'medium'\n): void {\n const logEntry = {\n timestamp: new Date().toISOString(),\n event,\n severity,\n ...details\n };\n\n switch (severity) {\n case 'critical':\n case 'high':\n console.error(`[SECURITY:${severity.toUpperCase()}] ${event}:`, JSON.stringify(logEntry));\n break;\n case 'medium':\n console.warn(`[SECURITY:${severity.toUpperCase()}] ${event}:`, JSON.stringify(logEntry));\n break;\n case 'low':\n console.info(`[SECURITY:${severity.toUpperCase()}] ${event}:`, JSON.stringify(logEntry));\n break;\n }\n}\n"],"mappings":";AAWO,IAAM,gBAAN,cAA4B,MAAM;AAAA,EACvC,YAAY,SAAiC,MAAe;AAC1D,UAAM,OAAO;AAD8B;AAE3C,SAAK,OAAO;AAAA,EACd;AACF;AAMO,SAAS,aAAa,MAAuB;AAElD,MAAI,CAAC,OAAO,UAAU,IAAI,GAAG;AAC3B,WAAO;AAAA,EACT;AAGA,MAAI,OAAO,QAAQ,OAAO,OAAO;AAC/B,WAAO;AAAA,EACT;AAGA,QAAM,gBAAgB;AAAA,IACpB;AAAA;AAAA,IACA;AAAA;AAAA,EACF;AAEA,MAAI,cAAc,SAAS,IAAI,GAAG;AAChC,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAMO,SAAS,kBAAkB,IAAoB;AAEpD,MAAI,CAAC,MAAM,GAAG,SAAS,IAAI;AACzB,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,MAAI,GAAG,WAAW,GAAG,KAAK,GAAG,SAAS,GAAG,GAAG;AAC1C,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,QAAM,gBAAgB;AAAA,IACpB;AAAA,IAAO;AAAA,IAAO;AAAA,IAAS;AAAA,IAAQ;AAAA,IAC/B;AAAA,IAAc;AAAA,EAChB;AAEA,QAAM,cAAc,GAAG,YAAY;AACnC,MAAI,cAAc,SAAS,WAAW,GAAG;AACvC,UAAM,IAAI;AAAA,MACR,wBAAwB,EAAE;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAMO,SAAS,iBACd,OACA,SACA,WAAmD,UAC7C;AACN,QAAM,WAAW;AAAA,IACf,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IAClC;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL;AAEA,UAAQ,UAAU;AAAA,IAChB,KAAK;AAAA,IACL,KAAK;AACH,cAAQ,MAAM,aAAa,SAAS,YAAY,CAAC,KAAK,KAAK,KAAK,KAAK,UAAU,QAAQ,CAAC;AACxF;AAAA,IACF,KAAK;AACH,cAAQ,KAAK,aAAa,SAAS,YAAY,CAAC,KAAK,KAAK,KAAK,KAAK,UAAU,QAAQ,CAAC;AACvF;AAAA,IACF,KAAK;AACH,cAAQ,KAAK,aAAa,SAAS,YAAY,CAAC,KAAK,KAAK,KAAK,KAAK,UAAU,QAAQ,CAAC;AACvF;AAAA,EACJ;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/security.ts"],"sourcesContent":["/**\n * Security utilities for URL construction and input validation\n *\n * This module contains critical security functions to prevent:\n * - URL injection attacks\n * - SSRF (Server-Side Request Forgery) attacks\n * - DNS rebinding attacks\n * - Host header injection\n * - Open redirect vulnerabilities\n */\n\nexport class SecurityError extends Error {\n constructor(message: string, public readonly code?: string) {\n super(message);\n this.name = 'SecurityError';\n }\n}\n\n/**\n * Validates port numbers for sandbox services\n * Only allows non-system ports to prevent conflicts and security issues\n */\nexport function validatePort(port: number): boolean {\n // Must be a valid integer\n if (!Number.isInteger(port)) {\n return false;\n }\n\n // Only allow non-system ports (1024-65535)\n if (port < 1024 || port > 65535) {\n return false;\n }\n\n // Exclude ports reserved by our system\n const reservedPorts = [\n 3000, // Control plane port\n 8787, // Common wrangler dev port\n ];\n\n if (reservedPorts.includes(port)) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Sanitizes and validates sandbox IDs for DNS compliance and security\n * Only enforces critical requirements - allows maximum developer flexibility\n */\nexport function sanitizeSandboxId(id: string): string {\n // Basic validation: not empty, reasonable length limit (DNS subdomain limit is 63 chars)\n if (!id || id.length > 63) {\n throw new SecurityError(\n 'Sandbox ID must be 1-63 characters long.',\n 'INVALID_SANDBOX_ID_LENGTH'\n );\n }\n\n // DNS compliance: cannot start or end with hyphens (RFC requirement)\n if (id.startsWith('-') || id.endsWith('-')) {\n throw new SecurityError(\n 'Sandbox ID cannot start or end with hyphens (DNS requirement).',\n 'INVALID_SANDBOX_ID_HYPHENS'\n );\n }\n\n // Prevent reserved names that cause technical conflicts\n const reservedNames = [\n 'www', 'api', 'admin', 'root', 'system',\n 'cloudflare', 'workers'\n ];\n\n const lowerCaseId = id.toLowerCase();\n if (reservedNames.includes(lowerCaseId)) {\n throw new SecurityError(\n `Reserved sandbox ID '${id}' is not allowed.`,\n 'RESERVED_SANDBOX_ID'\n );\n }\n\n return id;\n}\n\n\n/**\n * Validates language for code interpreter\n * Only allows supported languages\n */\nexport function validateLanguage(language: string | undefined): void {\n if (!language) {\n return; // undefined is valid, will default to python\n }\n\n const supportedLanguages = ['python', 'python3', 'javascript', 'js', 'node', 'typescript', 'ts'];\n const normalized = language.toLowerCase();\n\n if (!supportedLanguages.includes(normalized)) {\n throw new SecurityError(\n `Unsupported language '${language}'. Supported languages: python, javascript, typescript`,\n 'INVALID_LANGUAGE'\n );\n }\n}\n"],"mappings":";AAWO,IAAM,gBAAN,cAA4B,MAAM;AAAA,EACvC,YAAY,SAAiC,MAAe;AAC1D,UAAM,OAAO;AAD8B;AAE3C,SAAK,OAAO;AAAA,EACd;AACF;AAMO,SAAS,aAAa,MAAuB;AAElD,MAAI,CAAC,OAAO,UAAU,IAAI,GAAG;AAC3B,WAAO;AAAA,EACT;AAGA,MAAI,OAAO,QAAQ,OAAO,OAAO;AAC/B,WAAO;AAAA,EACT;AAGA,QAAM,gBAAgB;AAAA,IACpB;AAAA;AAAA,IACA;AAAA;AAAA,EACF;AAEA,MAAI,cAAc,SAAS,IAAI,GAAG;AAChC,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAMO,SAAS,kBAAkB,IAAoB;AAEpD,MAAI,CAAC,MAAM,GAAG,SAAS,IAAI;AACzB,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,MAAI,GAAG,WAAW,GAAG,KAAK,GAAG,SAAS,GAAG,GAAG;AAC1C,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,QAAM,gBAAgB;AAAA,IACpB;AAAA,IAAO;AAAA,IAAO;AAAA,IAAS;AAAA,IAAQ;AAAA,IAC/B;AAAA,IAAc;AAAA,EAChB;AAEA,QAAM,cAAc,GAAG,YAAY;AACnC,MAAI,cAAc,SAAS,WAAW,GAAG;AACvC,UAAM,IAAI;AAAA,MACR,wBAAwB,EAAE;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAOO,SAAS,iBAAiB,UAAoC;AACnE,MAAI,CAAC,UAAU;AACb;AAAA,EACF;AAEA,QAAM,qBAAqB,CAAC,UAAU,WAAW,cAAc,MAAM,QAAQ,cAAc,IAAI;AAC/F,QAAM,aAAa,SAAS,YAAY;AAExC,MAAI,CAAC,mBAAmB,SAAS,UAAU,GAAG;AAC5C,UAAM,IAAI;AAAA,MACR,yBAAyB,QAAQ;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
@@ -1,63 +1,41 @@
1
- import { FileChunk, FileMetadata } from './types.js';
2
- import './interpreter-types.js';
1
+ import { FileChunk, FileMetadata } from '@repo/shared';
3
2
 
4
3
  /**
5
- * File streaming utilities for reading binary and text files
6
- * Provides simple AsyncIterable API over SSE stream with automatic base64 decoding
7
- */
8
-
9
- /**
10
- * Convert ReadableStream of SSE file events to AsyncIterable of file chunks
11
- * Automatically decodes base64 for binary files and provides metadata
4
+ * Stream a file from the sandbox with automatic base64 decoding for binary files
12
5
  *
13
- * @param stream - The SSE ReadableStream from readFileStream()
14
- * @param signal - Optional AbortSignal for cancellation
15
- * @returns AsyncIterable that yields file chunks (string for text, Uint8Array for binary)
6
+ * @param stream - The ReadableStream from readFileStream()
7
+ * @returns AsyncGenerator that yields FileChunk (string for text, Uint8Array for binary)
16
8
  *
17
9
  * @example
18
- * ```typescript
10
+ * ```ts
19
11
  * const stream = await sandbox.readFileStream('/path/to/file.png');
20
- *
21
12
  * for await (const chunk of streamFile(stream)) {
22
13
  * if (chunk instanceof Uint8Array) {
23
- * // Binary chunk - already decoded from base64
24
- * console.log('Binary chunk:', chunk.byteLength, 'bytes');
14
+ * // Binary chunk
15
+ * console.log('Binary chunk:', chunk.length, 'bytes');
25
16
  * } else {
26
17
  * // Text chunk
27
18
  * console.log('Text chunk:', chunk);
28
19
  * }
29
20
  * }
30
- *
31
- * // Access metadata
32
- * const iter = streamFile(stream);
33
- * for await (const chunk of iter) {
34
- * console.log('MIME type:', iter.metadata?.mimeType);
35
- * // process chunk...
36
- * }
37
21
  * ```
38
22
  */
39
- declare function streamFile(stream: ReadableStream<Uint8Array>, signal?: AbortSignal): AsyncGenerator<FileChunk, void, undefined>;
23
+ declare function streamFile(stream: ReadableStream<Uint8Array>): AsyncGenerator<FileChunk, FileMetadata>;
40
24
  /**
41
- * Helper to collect entire file from stream into memory
42
- * Useful for smaller files where you want the complete content at once
25
+ * Collect an entire file into memory from a stream
43
26
  *
44
- * @param stream - The SSE ReadableStream from readFileStream()
45
- * @param signal - Optional AbortSignal for cancellation
46
- * @returns Object with content (string or Uint8Array) and metadata
27
+ * @param stream - The ReadableStream from readFileStream()
28
+ * @returns Object containing the file content and metadata
47
29
  *
48
30
  * @example
49
- * ```typescript
50
- * const stream = await sandbox.readFileStream('/path/to/image.png');
31
+ * ```ts
32
+ * const stream = await sandbox.readFileStream('/path/to/file.txt');
51
33
  * const { content, metadata } = await collectFile(stream);
52
- *
53
- * if (content instanceof Uint8Array) {
54
- * console.log('Binary file:', metadata.mimeType, content.byteLength, 'bytes');
55
- * } else {
56
- * console.log('Text file:', metadata.mimeType, content.length, 'chars');
57
- * }
34
+ * console.log('Content:', content);
35
+ * console.log('MIME type:', metadata.mimeType);
58
36
  * ```
59
37
  */
60
- declare function collectFile(stream: ReadableStream<Uint8Array>, signal?: AbortSignal): Promise<{
38
+ declare function collectFile(stream: ReadableStream<Uint8Array>): Promise<{
61
39
  content: string | Uint8Array;
62
40
  metadata: FileMetadata;
63
41
  }>;
@@ -1,8 +1,7 @@
1
1
  import {
2
2
  collectFile,
3
3
  streamFile
4
- } from "./chunk-5DILEXGY.js";
5
- import "./chunk-NNGBXDMY.js";
4
+ } from "./chunk-BFVUNTP4.js";
6
5
  export {
7
6
  collectFile,
8
7
  streamFile
package/dist/index.d.ts CHANGED
@@ -1,8 +1,9 @@
1
- export { CodeExecutionError, ContainerNotReadyError, ContextNotFoundError, InterpreterNotReadyError, InterpreterNotReadyError as JupyterNotReadyError, SandboxError, SandboxErrorResponse, SandboxNetworkError, ServiceUnavailableError, isInterpreterNotReadyError, isInterpreterNotReadyError as isJupyterNotReadyError, isRetryableError, isSandboxError, parseErrorResponse } from './errors.js';
2
- export { ChartData, CodeContext, CreateContextOptions, Execution, ExecutionError, OutputMessage, Result, ResultImpl, RunCodeOptions } from './interpreter-types.js';
1
+ export { B as BaseApiResponse, C as CommandClient, f as CommandExecuteResponse, c as CommandsResponse, d as ContainerStub, E as ErrorResponse, e as ExecuteRequest, p as ExecutionCallbacks, h as ExposePortRequest, F as FileClient, i as FileOperationRequest, j as GitCheckoutRequest, G as GitClient, I as InterpreterClient, M as MkdirRequest, k as PingResponse, P as PortClient, a as ProcessClient, R as ReadFileRequest, l as RequestConfig, m as ResponseHandler, b as Sandbox, S as SandboxClient, H as SandboxClientOptions, n as SessionRequest, o as UnexposePortRequest, U as UtilityClient, W as WriteFileRequest, g as getSandbox } from './sandbox-D9K2ypln.js';
2
+ export * from '@repo/shared';
3
+ export { BaseExecOptions, ExecEvent, ExecOptions, ExecResult, FileChunk, FileMetadata, FileStreamEvent, GitCheckoutResult, ISandbox, LogEvent, PortCloseResult, PortExposeResult, PortListResult, Process, ProcessCleanupResult, ProcessInfoResult, ProcessKillResult, ProcessListResult, ProcessLogsResult, ProcessOptions, ProcessStartResult, ProcessStatus, StartProcessRequest, StreamOptions, isExecResult, isProcess, isProcessStatus } from '@repo/shared';
4
+ export { collectFile, streamFile } from './file-stream.js';
5
+ export { CodeInterpreter } from './interpreter.js';
3
6
  export { RouteInfo, SandboxEnv, proxyToSandbox } from './request-handler.js';
4
- export { S as Sandbox, g as getSandbox } from './client-B3RUab0s.js';
5
7
  export { asyncIterableToSSEStream, parseSSEStream, responseToAsyncIterable } from './sse-parser.js';
6
- export { collectFile, streamFile } from './file-stream.js';
7
- export { DeleteFileResponse, ExecEvent, ExecOptions, ExecResult, ExecuteResponse, ExecutionSession, FileChunk, FileMetadata, FileStream, FileStreamEvent, GitCheckoutResponse, ISandbox, ListFilesResponse, LogEvent, MkdirResponse, MoveFileResponse, Process, ProcessOptions, ProcessStatus, ReadFileResponse, RenameFileResponse, StreamOptions, WriteFileResponse } from './types.js';
8
+ import 'cloudflare:workers';
8
9
  import '@cloudflare/containers';