@isol8/core 0.13.0-alpha.0

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 (57) hide show
  1. package/README.md +39 -0
  2. package/dist/client/remote.d.ts +64 -0
  3. package/dist/client/remote.d.ts.map +1 -0
  4. package/dist/config.d.ts +36 -0
  5. package/dist/config.d.ts.map +1 -0
  6. package/dist/docker/Dockerfile +42 -0
  7. package/dist/docker/proxy-handler.sh +180 -0
  8. package/dist/docker/proxy.sh +57 -0
  9. package/dist/docker/seccomp-profile.json +67 -0
  10. package/dist/engine/audit.d.ts +31 -0
  11. package/dist/engine/audit.d.ts.map +1 -0
  12. package/dist/engine/code-fetcher.d.ts +21 -0
  13. package/dist/engine/code-fetcher.d.ts.map +1 -0
  14. package/dist/engine/concurrency.d.ts +46 -0
  15. package/dist/engine/concurrency.d.ts.map +1 -0
  16. package/dist/engine/default-seccomp-profile.d.ts +8 -0
  17. package/dist/engine/default-seccomp-profile.d.ts.map +1 -0
  18. package/dist/engine/docker.d.ts +167 -0
  19. package/dist/engine/docker.d.ts.map +1 -0
  20. package/dist/engine/image-builder.d.ts +71 -0
  21. package/dist/engine/image-builder.d.ts.map +1 -0
  22. package/dist/engine/pool.d.ts +94 -0
  23. package/dist/engine/pool.d.ts.map +1 -0
  24. package/dist/engine/stats.d.ts +35 -0
  25. package/dist/engine/stats.d.ts.map +1 -0
  26. package/dist/engine/utils.d.ts +71 -0
  27. package/dist/engine/utils.d.ts.map +1 -0
  28. package/dist/index.d.ts +19 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +2777 -0
  31. package/dist/index.js.map +30 -0
  32. package/dist/runtime/adapter.d.ts +63 -0
  33. package/dist/runtime/adapter.d.ts.map +1 -0
  34. package/dist/runtime/adapters/bash.d.ts +3 -0
  35. package/dist/runtime/adapters/bash.d.ts.map +1 -0
  36. package/dist/runtime/adapters/bun.d.ts +4 -0
  37. package/dist/runtime/adapters/bun.d.ts.map +1 -0
  38. package/dist/runtime/adapters/deno.d.ts +10 -0
  39. package/dist/runtime/adapters/deno.d.ts.map +1 -0
  40. package/dist/runtime/adapters/node.d.ts +4 -0
  41. package/dist/runtime/adapters/node.d.ts.map +1 -0
  42. package/dist/runtime/adapters/python.d.ts +4 -0
  43. package/dist/runtime/adapters/python.d.ts.map +1 -0
  44. package/dist/runtime/index.d.ts +15 -0
  45. package/dist/runtime/index.d.ts.map +1 -0
  46. package/dist/types.d.ts +532 -0
  47. package/dist/types.d.ts.map +1 -0
  48. package/dist/utils/logger.d.ts +32 -0
  49. package/dist/utils/logger.d.ts.map +1 -0
  50. package/dist/version.d.ts +15 -0
  51. package/dist/version.d.ts.map +1 -0
  52. package/docker/Dockerfile +42 -0
  53. package/docker/proxy-handler.sh +180 -0
  54. package/docker/proxy.sh +57 -0
  55. package/docker/seccomp-profile.json +67 -0
  56. package/package.json +48 -0
  57. package/schema/isol8.config.schema.json +315 -0
@@ -0,0 +1,30 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/runtime/adapter.ts", "../src/runtime/adapters/bash.ts", "../src/runtime/adapters/bun.ts", "../src/runtime/adapters/deno.ts", "../src/runtime/adapters/node.ts", "../src/runtime/adapters/python.ts", "../src/runtime/index.ts", "../src/utils/logger.ts", "../src/engine/utils.ts", "../src/engine/image-builder.ts", "../src/client/remote.ts", "../src/config.ts", "../src/engine/concurrency.ts", "../src/engine/docker.ts", "../src/engine/audit.ts", "../src/engine/code-fetcher.ts", "../src/engine/default-seccomp-profile.ts", "../src/engine/pool.ts", "../src/engine/stats.ts", "../src/index.ts", "../src/version.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * @module runtime/adapter\n *\n * Defines the {@link RuntimeAdapter} interface and the global {@link RuntimeRegistry}\n * for looking up runtime adapters by name or file extension.\n */\n\nimport type { Runtime } from \"../types\";\n\n/**\n * A runtime adapter provides the container image and command construction\n * for a specific language runtime (Python, Node, Bun, Deno).\n *\n * Adapters are registered in {@link RuntimeRegistry} and looked up by name\n * or by file extension when the runtime is auto-detected.\n */\nexport interface RuntimeAdapter {\n /** Runtime identifier (e.g. `\"python\"`, `\"node\"`). */\n readonly name: Runtime;\n\n /** Docker image tag for this runtime (e.g. `\"isol8:python\"`). */\n readonly image: string;\n\n /**\n * Build the shell command to execute code.\n *\n * @param code - The source code string. Used for inline execution.\n * @param filePath - If provided, the code is read from this file inside the container.\n * @returns Command array (e.g. `[\"python3\", \"-c\", \"print(1)\"]`).\n */\n getCommand(code: string, filePath?: string): string[];\n\n /** Default file extension for this runtime (e.g. `\".py\"`). */\n getFileExtension(): string;\n}\n\nconst adapters = new Map<string, RuntimeAdapter>();\n\nconst extensionMap = new Map<string, RuntimeAdapter>();\n\n/**\n * Central registry of all available runtime adapters.\n *\n * Built-in adapters (Python, Node, Bun, Deno) are registered automatically\n * when `src/runtime/index.ts` is imported.\n */\nexport const RuntimeRegistry = {\n /**\n * Register a runtime adapter. Overwrites any existing adapter with the same\n * name or file extension.\n *\n * @param adapter - The adapter to register.\n * @param aliases - Additional file extensions to map to this adapter (e.g. `[\".mjs\", \".cjs\"]`).\n */\n register(adapter: RuntimeAdapter, aliases: string[] = []): void {\n adapters.set(adapter.name, adapter);\n extensionMap.set(adapter.getFileExtension(), adapter);\n for (const ext of aliases) {\n extensionMap.set(ext, adapter);\n }\n },\n\n /**\n * Look up a runtime adapter by name.\n *\n * @param name - Runtime name (e.g. `\"python\"`).\n * @throws {Error} If no adapter is registered with that name.\n */\n get(name: string): RuntimeAdapter {\n const adapter = adapters.get(name);\n if (!adapter) {\n throw new Error(`Unknown runtime: \"${name}\". Available: ${[...adapters.keys()].join(\", \")}`);\n }\n return adapter;\n },\n\n /**\n * Auto-detect the runtime from a filename's extension.\n *\n * @param filename - Filename or path (e.g. `\"script.py\"`, `\"app.js\"`).\n * @throws {Error} If the extension doesn't match any registered adapter.\n */\n detect(filename: string): RuntimeAdapter {\n const ext = `.${filename.split(\".\").pop()}`;\n const adapter = extensionMap.get(ext);\n if (!adapter) {\n throw new Error(\n `Cannot detect runtime for \"${filename}\". Known extensions: ${[...extensionMap.keys()].join(\", \")}`\n );\n }\n return adapter;\n },\n\n /** Returns all registered runtime adapters. */\n list(): RuntimeAdapter[] {\n return [...adapters.values()];\n },\n};\n",
6
+ "import type { RuntimeAdapter } from \"../adapter\";\n\nexport const bashAdapter: RuntimeAdapter = {\n name: \"bash\",\n image: \"isol8:bash\",\n getCommand(code: string, filePath?: string): string[] {\n if (filePath) {\n return [\"bash\", filePath];\n }\n return [\"bash\", \"-c\", code];\n },\n getFileExtension() {\n return \".sh\";\n },\n};\n",
7
+ "/** Bun runtime adapter — uses `bun` from the `isol8:bun` image. Maps to `.ts` extension. */\nimport type { RuntimeAdapter } from \"../adapter\";\n\nexport const BunAdapter: RuntimeAdapter = {\n name: \"bun\",\n image: \"isol8:bun\",\n\n getCommand(code: string, filePath?: string): string[] {\n if (filePath) {\n return [\"bun\", \"run\", filePath];\n }\n return [\"bun\", \"-e\", code];\n },\n\n getFileExtension(): string {\n return \".ts\";\n },\n};\n",
8
+ "/**\n * Deno runtime adapter — uses `deno` from the `isol8:deno` image.\n *\n * Uses `.mts` extension to avoid collision with Bun's `.ts`.\n * Permissions are scoped: read/write to /sandbox, env access, and\n * optionally net access (controlled by the engine's network mode).\n */\nimport type { RuntimeAdapter } from \"../adapter\";\n\nexport const DenoAdapter: RuntimeAdapter = {\n name: \"deno\",\n image: \"isol8:deno\",\n\n getCommand(_code: string, filePath?: string): string[] {\n if (!filePath) {\n throw new Error(\"Deno adapter requires a file path — inline code is not supported.\");\n }\n return [\n \"deno\",\n \"run\",\n \"--allow-read=/sandbox,/tmp\",\n \"--allow-write=/sandbox,/tmp\",\n \"--allow-env\",\n \"--allow-net\",\n filePath,\n ];\n },\n\n getFileExtension(): string {\n return \".mts\";\n },\n};\n",
9
+ "/** Node.js runtime adapter — uses `node` from the `isol8:node` image. */\nimport type { RuntimeAdapter } from \"../adapter\";\n\nexport const NodeAdapter: RuntimeAdapter = {\n name: \"node\",\n image: \"isol8:node\",\n\n getCommand(code: string, filePath?: string): string[] {\n if (filePath) {\n return [\"node\", filePath];\n }\n return [\"node\", \"-e\", code];\n },\n\n getFileExtension(): string {\n return \".mjs\";\n },\n};\n",
10
+ "/** Python runtime adapter — uses `python3` from the `isol8:python` image. */\nimport type { RuntimeAdapter } from \"../adapter\";\n\nexport const PythonAdapter: RuntimeAdapter = {\n name: \"python\",\n image: \"isol8:python\",\n\n getCommand(code: string, filePath?: string): string[] {\n if (filePath) {\n return [\"python3\", filePath];\n }\n return [\"python3\", \"-c\", code];\n },\n\n getFileExtension(): string {\n return \".py\";\n },\n};\n",
11
+ "/**\n * @module runtime\n *\n * Barrel module that registers all built-in runtime adapters and re-exports\n * the public API. Importing this module has the side effect of populating\n * the {@link RuntimeRegistry} with Python, Node, Bun, and Deno adapters.\n */\n\nimport { RuntimeRegistry } from \"./adapter\";\nimport { bashAdapter } from \"./adapters/bash\";\nimport { BunAdapter } from \"./adapters/bun\";\nimport { DenoAdapter } from \"./adapters/deno\";\nimport { NodeAdapter } from \"./adapters/node\";\nimport { PythonAdapter } from \"./adapters/python\";\n\n// Register all built-in adapters (order matters for extension collisions)\nRuntimeRegistry.register(PythonAdapter);\nRuntimeRegistry.register(NodeAdapter, [\".js\", \".cjs\"]);\nRuntimeRegistry.register(BunAdapter); // Bun wins for .ts\nRuntimeRegistry.register(bashAdapter);\nRuntimeRegistry.register(DenoAdapter); // Deno uses .mts to avoid extension collision\n\nexport type { RuntimeAdapter } from \"./adapter\";\nexport { RuntimeRegistry } from \"./adapter\";\nexport { bashAdapter } from \"./adapters/bash\";\nexport { BunAdapter } from \"./adapters/bun\";\nexport { DenoAdapter } from \"./adapters/deno\";\nexport { NodeAdapter } from \"./adapters/node\";\nexport { PythonAdapter } from \"./adapters/python\";\n",
12
+ "/**\n * @module logger\n *\n * Centralized logging utility for isol8.\n * Supports debug mode toggling and standardized log formatting.\n */\n\nclass Logger {\n private debugMode = false;\n\n /**\n * Enable or disable debug logging.\n */\n setDebug(enabled: boolean) {\n this.debugMode = enabled;\n }\n\n /**\n * Log a debug message. Only prints if debug mode is enabled.\n */\n debug(...args: unknown[]) {\n if (this.debugMode) {\n console.log(\"[DEBUG]\", ...args);\n }\n }\n\n /**\n * Log an info message. Always prints.\n */\n info(...args: unknown[]) {\n console.log(...args);\n }\n\n /**\n * Log a warning message. Always prints.\n */\n warn(...args: unknown[]) {\n console.warn(\"[WARN]\", ...args);\n }\n\n /**\n * Log an error message. Always prints.\n */\n error(...args: unknown[]) {\n console.error(\"[ERROR]\", ...args);\n }\n}\n\nexport const logger = new Logger();\n",
13
+ "/**\n * @module engine/utils\n *\n * Low-level utility functions used by the Docker engine: memory parsing,\n * output truncation, secret masking, and POSIX tar archive creation/extraction.\n */\n\n/**\n * Parses a human-readable memory limit string into bytes.\n *\n * @param limit - Memory string (e.g. `\"512m\"`, `\"1g\"`, `\"256k\"`, `\"1024\"`).\n * @returns The limit in bytes.\n * @throws {Error} If the format is invalid.\n *\n * @example\n * ```typescript\n * parseMemoryLimit(\"512m\"); // 536870912\n * parseMemoryLimit(\"1g\"); // 1073741824\n * ```\n */\nexport function parseMemoryLimit(limit: string): number {\n const match = limit.match(/^(\\d+(?:\\.\\d+)?)\\s*([kmgt]?)b?$/i);\n if (!match) {\n throw new Error(`Invalid memory limit format: \"${limit}\". Use e.g. \"512m\", \"1g\".`);\n }\n const value = Number.parseFloat(match[1]!);\n const unit = (match[2] || \"b\").toLowerCase();\n\n const multipliers: Record<string, number> = {\n b: 1,\n k: 1024,\n m: 1024 ** 2,\n g: 1024 ** 3,\n t: 1024 ** 4,\n };\n\n return Math.floor(value * (multipliers[unit] ?? 1));\n}\n\n/**\n * Truncates output to a maximum byte length. If truncated, appends a\n * summary line indicating the original and limit sizes.\n *\n * @param output - The full output string.\n * @param maxBytes - Maximum allowed byte length.\n * @returns Object with the (possibly truncated) text and a truncation flag.\n */\nexport function truncateOutput(\n output: string,\n maxBytes: number\n): { text: string; truncated: boolean } {\n const encoder = new TextEncoder();\n const bytes = encoder.encode(output);\n\n if (bytes.length <= maxBytes) {\n return { text: output, truncated: false };\n }\n\n // Truncate at byte boundary, decode back\n const decoder = new TextDecoder(\"utf-8\", { fatal: false });\n const truncated = decoder.decode(bytes.slice(0, maxBytes));\n return {\n text: `${truncated}\\n\\n--- OUTPUT TRUNCATED (${bytes.length} bytes, limit: ${maxBytes}) ---`,\n truncated: true,\n };\n}\n\n/**\n * Replaces all occurrences of secret values in a string with `***`.\n * Empty secret values are skipped.\n *\n * @param text - The text to sanitize.\n * @param secrets - Map of secret names to values.\n * @returns The sanitized text.\n */\nexport function maskSecrets(text: string, secrets: Record<string, string>): string {\n let result = text;\n for (const value of Object.values(secrets)) {\n if (value.length > 0) {\n result = result.replaceAll(value, \"***\");\n }\n }\n return result;\n}\n\n/**\n * Creates a POSIX tar archive buffer containing a single file.\n *\n * Uses a minimal tar header (512-byte blocks) followed by data blocks\n * and a 1024-byte end-of-archive marker.\n *\n * @param filePath - Path for the file inside the archive (leading `/` is stripped).\n * @param content - File contents as a string or Buffer.\n * @returns A Buffer containing the complete tar archive.\n */\nexport function createTarBuffer(filePath: string, content: Buffer | string): Buffer {\n const data = typeof content === \"string\" ? Buffer.from(content, \"utf-8\") : content;\n const headerSize = 512;\n const dataBlocks = Math.ceil(data.length / 512);\n const totalSize = headerSize + dataBlocks * 512 + 1024; // +1024 for end-of-archive\n const buf = Buffer.alloc(totalSize);\n\n // Filename (0..100)\n buf.write(filePath.replace(/^\\//, \"\"), 0, 100, \"utf-8\");\n // Mode (100..108)\n buf.write(\"0000644\\0\", 100, 8, \"utf-8\");\n // UID (108..116)\n buf.write(\"0000000\\0\", 108, 8, \"utf-8\");\n // GID (116..124)\n buf.write(\"0000000\\0\", 116, 8, \"utf-8\");\n // Size (124..136) - octal\n buf.write(`${data.length.toString(8).padStart(11, \"0\")}\\0`, 124, 12, \"utf-8\");\n // Mtime (136..148)\n buf.write(\n `${Math.floor(Date.now() / 1000)\n .toString(8)\n .padStart(11, \"0\")}\\0`,\n 136,\n 12,\n \"utf-8\"\n );\n // Type flag (156) - '0' = regular file\n buf.write(\"0\", 156, 1, \"utf-8\");\n // Magic (257..263)\n buf.write(\"ustar\\0\", 257, 6, \"utf-8\");\n // Version (263..265)\n buf.write(\"00\", 263, 2, \"utf-8\");\n\n // Compute checksum\n // First fill checksum field with spaces\n buf.write(\" \", 148, 8, \"utf-8\");\n let checksum = 0;\n for (let i = 0; i < headerSize; i++) {\n checksum += buf[i]!;\n }\n buf.write(`${checksum.toString(8).padStart(6, \"0\")}\\0 `, 148, 8, \"utf-8\");\n\n // Write data\n data.copy(buf, headerSize);\n\n return buf;\n}\n\n/**\n * Extracts a single file from a tar archive buffer.\n *\n * @param tarBuffer - The tar archive buffer.\n * @param targetPath - Path of the file to extract (leading `/` is stripped for matching).\n * @returns The extracted file contents as a Buffer.\n * @throws {Error} If the file is not found in the archive.\n */\nexport function extractFromTar(tarBuffer: Buffer, targetPath: string): Buffer {\n const normalizedTarget = targetPath.replace(/^\\//, \"\");\n const basename = targetPath.split(\"/\").pop() ?? targetPath;\n let offset = 0;\n\n while (offset < tarBuffer.length - 512) {\n // Read filename from header\n const nameEnd = tarBuffer.indexOf(0, offset);\n const name = tarBuffer.subarray(offset, Math.min(nameEnd, offset + 100)).toString(\"utf-8\");\n\n if (name.length === 0) {\n break;\n }\n\n // Read size\n const sizeStr = tarBuffer\n .subarray(offset + 124, offset + 136)\n .toString(\"utf-8\")\n .trim();\n const size = Number.parseInt(sizeStr, 8);\n\n if (Number.isNaN(size)) {\n break;\n }\n\n const dataStart = offset + 512;\n const dataBlocks = Math.ceil(size / 512);\n\n if (name === normalizedTarget || name.endsWith(`/${normalizedTarget}`) || name === basename) {\n return Buffer.from(tarBuffer.subarray(dataStart, dataStart + size));\n }\n\n offset = dataStart + dataBlocks * 512;\n }\n\n throw new Error(`File \"${targetPath}\" not found in tar archive`);\n}\n\n/**\n * Validates a package name to prevent command injection.\n * allow alphanumeric, dash, underscore, dot, @, / (for scoped packages), and = (for versions)\n *\n * @param name - The package name to validate.\n * @returns The name if valid.\n * @throws {Error} If the name contains invalid characters.\n */\nexport function validatePackageName(name: string): string {\n // Allow @scope/pkg, pkg@version, pkg==version, pkg-name, pkg_name, pkg.name\n if (!/^[@a-zA-Z0-9_./\\-=]+$/.test(name)) {\n throw new Error(\n `Invalid package name: \"${name}\". Only alphanumeric, -, _, ., /, @, and = are allowed.`\n );\n }\n return name;\n}\n",
14
+ "/**\n * @module engine/image-builder\n *\n * Builds Docker images for each supported runtime. Base images are built from\n * the multi-stage `docker/Dockerfile`. Custom images layer user-specified\n * packages on top of the base images.\n */\n\nimport { createHash } from \"node:crypto\";\nimport { existsSync, readFileSync, statSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport type Docker from \"dockerode\";\nimport { RuntimeRegistry } from \"../runtime\";\nimport type { Isol8Config } from \"../types\";\nimport { logger } from \"../utils/logger\";\n\n/**\n * Resolve the `docker/` directory containing the Dockerfile and proxy.\n *\n * When running from source (`src/engine/image-builder.ts`), the path is\n * `../../docker` relative to this file. When running from the bundled CLI\n * (`dist/cli.js`), it is `./docker` (same directory). We try both and use\n * whichever exists.\n */\nfunction resolveDockerDir(): string {\n // 1. Try relative to the current executable (for isol8-server standalone)\n // In a Bun compiled binary, process.execPath is the binary itself (e.g. dist/isol8-server).\n const fromExec = join(dirname(process.execPath), \"docker\");\n if (existsSync(fromExec) && statSync(fromExec).isDirectory()) {\n return fromExec;\n }\n\n // 2. Try production/bundled path: dist/cli.js -> ./docker\n // Guard against $bunfs paths which are virtual and won't resolve correctly on real FS\n if (!import.meta.url.includes(\"$bunfs\")) {\n const fromBundled = new URL(\"./docker\", import.meta.url).pathname;\n if (existsSync(fromBundled)) {\n return fromBundled;\n }\n }\n\n // 3. Fallback to dev path: src/engine/image-builder.ts -> ../../docker\n // When running via `bun run src/cli.ts` or tests\n if (!import.meta.url.includes(\"$bunfs\")) {\n const fromDev = new URL(\"../../docker\", import.meta.url).pathname;\n if (existsSync(fromDev)) {\n return fromDev;\n }\n }\n\n // 4. Last resort: current working directory (e.g. tests running from repo root)\n const fromCwd = join(process.cwd(), \"docker\");\n if (existsSync(fromCwd)) {\n return fromCwd;\n }\n\n // Default fallback (will likely throw but provides a predictable path)\n return new URL(\"../../docker\", import.meta.url).pathname;\n}\n\nconst DOCKERFILE_DIR = resolveDockerDir();\n\n/** Label keys for image metadata */\nconst LABELS = {\n dockerHash: \"org.isol8.build.hash\",\n depsHash: \"org.isol8.deps.hash\",\n} as const;\n\n/** Files in docker directory that affect the build */\nconst DOCKER_BUILD_FILES = [\"Dockerfile\", \"proxy.sh\", \"proxy-handler.sh\"];\n\n/**\n * Computes a SHA256 hash of all relevant files in the docker directory.\n * This is used to detect when the Dockerfile or proxy scripts have changed.\n */\nfunction computeDockerDirHash(): string {\n const hash = createHash(\"sha256\");\n\n // Sort files for consistent hashing\n const files = [...DOCKER_BUILD_FILES].sort();\n\n for (const file of files) {\n const filePath = join(DOCKERFILE_DIR, file);\n if (existsSync(filePath)) {\n const content = readFileSync(filePath);\n hash.update(file);\n hash.update(content);\n }\n }\n\n return hash.digest(\"hex\");\n}\n\n/**\n * Computes a SHA256 hash of the dependency list for a specific runtime.\n */\nfunction computeDepsHash(runtime: string, packages: string[]): string {\n const hash = createHash(\"sha256\");\n hash.update(runtime);\n // Sort packages for consistent hashing\n for (const pkg of [...packages].sort()) {\n hash.update(pkg);\n }\n return hash.digest(\"hex\");\n}\n\n/**\n * Normalize package lists for stable tags/cache hits.\n * - trims whitespace\n * - removes empty entries\n * - de-duplicates\n * - sorts lexicographically\n */\nexport function normalizePackages(packages: string[]): string[] {\n return [...new Set(packages.map((pkg) => pkg.trim()).filter(Boolean))].sort();\n}\n\n/**\n * Returns deterministic custom image tag for a runtime + package set.\n * Uses a short deps hash suffix to avoid tag collisions across different\n * dependency sets for the same runtime.\n */\nexport function getCustomImageTag(runtime: string, packages: string[]): string {\n const normalizedPackages = normalizePackages(packages);\n const depsHash = computeDepsHash(runtime, normalizedPackages);\n const shortHash = depsHash.slice(0, 12);\n return `isol8:${runtime}-custom-${shortHash}`;\n}\n\n/**\n * Gets the labels from an existing Docker image.\n * Returns null if the image doesn't exist.\n */\nasync function getImageLabels(\n docker: Docker,\n imageName: string\n): Promise<Record<string, string> | null> {\n try {\n const image = docker.getImage(imageName);\n const inspect = await image.inspect();\n return (inspect.Config?.Labels as Record<string, string>) ?? {};\n } catch {\n return null;\n }\n}\n\n/**\n * Removes a Docker image by ID.\n * Silently fails if the image doesn't exist or can't be removed.\n */\nasync function removeImage(docker: Docker, imageId: string): Promise<void> {\n try {\n const image = docker.getImage(imageId);\n await image.remove();\n logger.debug(`[ImageBuilder] Removed old image: ${imageId.slice(0, 12)}`);\n } catch (err) {\n // Image might be in use or already removed - log but don't fail\n logger.debug(`[ImageBuilder] Could not remove image ${imageId.slice(0, 12)}: ${err}`);\n }\n}\n\n/** Progress update emitted during image builds. */\ninterface BuildProgress {\n /** Runtime being built (e.g. `\"python\"`). */\n runtime: string;\n /** Current build status. */\n status: \"building\" | \"done\" | \"error\";\n /** Optional status message (error text, package list, etc). */\n message?: string;\n}\n\ntype ProgressCallback = (progress: BuildProgress) => void;\n\n/**\n * Builds the base `isol8:<runtime>` images for all registered runtimes.\n * Each image is built from the multi-stage Dockerfile in `docker/`.\n *\n * Uses smart build logic: computes a hash of the docker directory contents\n * and skips builds if the image already exists with matching hash.\n * Cleans up dangling images after rebuilding.\n *\n * @param docker - Dockerode instance.\n * @param onProgress - Optional callback for build progress updates.\n * @param force - If true, always rebuild even if image is up to date.\n */\nexport async function buildBaseImages(\n docker: Docker,\n onProgress?: ProgressCallback,\n force = false,\n onlyRuntimes?: string[]\n): Promise<void> {\n const allRuntimes = RuntimeRegistry.list();\n const runtimes = onlyRuntimes\n ? allRuntimes.filter((r) => onlyRuntimes.includes(r.name))\n : allRuntimes;\n const dockerHash = computeDockerDirHash();\n logger.debug(`[ImageBuilder] Docker directory hash: ${dockerHash.slice(0, 16)}...`);\n\n for (const adapter of runtimes) {\n const target = adapter.name;\n const imageName = adapter.image;\n\n // Check if we can skip the build\n if (!force) {\n const labels = await getImageLabels(docker, imageName);\n if (labels && labels[LABELS.dockerHash] === dockerHash) {\n logger.debug(`[ImageBuilder] Base image ${target} is up to date, skipping build`);\n onProgress?.({ runtime: target, status: \"done\", message: \"Up to date\" });\n continue;\n }\n }\n\n // Get the old image ID before building (for cleanup)\n let oldImageId: string | null = null;\n try {\n const oldImage = await docker.getImage(imageName).inspect();\n oldImageId = oldImage.Id;\n logger.debug(`[ImageBuilder] Existing image ${target} ID: ${oldImageId.slice(0, 12)}`);\n } catch {\n // Image doesn't exist yet\n logger.debug(`[ImageBuilder] No existing image for ${target}`);\n }\n\n onProgress?.({ runtime: target, status: \"building\" });\n\n try {\n const stream = await docker.buildImage(\n { context: DOCKERFILE_DIR, src: DOCKER_BUILD_FILES },\n {\n t: imageName,\n target,\n dockerfile: \"Dockerfile\",\n labels: {\n [LABELS.dockerHash]: dockerHash,\n },\n }\n );\n\n // Wait for build to complete\n await new Promise<void>((resolve, reject) => {\n docker.modem.followProgress(stream, (err) => {\n if (err) {\n reject(err);\n } else {\n resolve();\n }\n });\n });\n\n // Clean up the old image if it existed and was replaced\n if (oldImageId) {\n await removeImage(docker, oldImageId);\n }\n\n onProgress?.({ runtime: target, status: \"done\" });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n onProgress?.({ runtime: target, status: \"error\", message });\n throw new Error(`Failed to build image for ${target}: ${message}`);\n }\n }\n}\n\n/**\n * Builds custom images with user-specified dependencies layered on top of\n * the base images. Reads package lists from the config's `dependencies` field.\n *\n * Uses smart build logic: computes a hash of the dependency list and\n * skips builds if the image already exists with matching hash.\n * Cleans up dangling images after rebuilding.\n *\n * @param docker - Dockerode instance.\n * @param config - Resolved isol8 configuration.\n * @param onProgress - Optional callback for build progress updates.\n * @param force - If true, always rebuild even if image is up to date.\n */\nexport async function buildCustomImages(\n docker: Docker,\n config: Isol8Config,\n onProgress?: ProgressCallback,\n force = false\n): Promise<void> {\n const deps = config.dependencies;\n\n const python = deps.python ? normalizePackages(deps.python) : [];\n const node = deps.node ? normalizePackages(deps.node) : [];\n const bun = deps.bun ? normalizePackages(deps.bun) : [];\n const deno = deps.deno ? normalizePackages(deps.deno) : [];\n const bash = deps.bash ? normalizePackages(deps.bash) : [];\n\n if (python.length) {\n await buildCustomImage(docker, \"python\", python, onProgress, force);\n }\n if (node.length) {\n await buildCustomImage(docker, \"node\", node, onProgress, force);\n }\n if (bun.length) {\n await buildCustomImage(docker, \"bun\", bun, onProgress, force);\n }\n if (deno.length) {\n await buildCustomImage(docker, \"deno\", deno, onProgress, force);\n }\n if (bash.length) {\n await buildCustomImage(docker, \"bash\", bash, onProgress, force);\n }\n}\n\nexport async function buildCustomImage(\n docker: Docker,\n runtime: import(\"../types\").Runtime | string,\n packages: string[],\n onProgress?: ProgressCallback,\n force = false\n): Promise<void> {\n const normalizedPackages = normalizePackages(packages);\n const tag = getCustomImageTag(runtime, normalizedPackages);\n const depsHash = computeDepsHash(runtime, normalizedPackages);\n logger.debug(`[ImageBuilder] ${runtime} custom deps hash: ${depsHash.slice(0, 16)}...`);\n\n // Check if we can skip the build\n if (!force) {\n const labels = await getImageLabels(docker, tag);\n if (labels && labels[LABELS.depsHash] === depsHash) {\n logger.debug(`[ImageBuilder] Custom image ${runtime} is up to date, skipping build`);\n onProgress?.({ runtime, status: \"done\", message: \"Up to date\" });\n return;\n }\n }\n\n // Get the old image ID before building (for cleanup)\n let oldImageId: string | null = null;\n try {\n const oldImage = await docker.getImage(tag).inspect();\n oldImageId = oldImage.Id;\n logger.debug(`[ImageBuilder] Existing custom image ${runtime} ID: ${oldImageId.slice(0, 12)}`);\n } catch {\n // Image doesn't exist yet\n logger.debug(`[ImageBuilder] No existing custom image for ${runtime}`);\n }\n\n onProgress?.({\n runtime,\n status: \"building\",\n message: `Custom: ${normalizedPackages.join(\", \")}`,\n });\n\n // Generate a Dockerfile that extends the base image\n let installCmd: string;\n switch (runtime) {\n case \"python\":\n installCmd = `RUN pip install --no-cache-dir ${normalizedPackages.join(\" \")}`;\n break;\n case \"node\":\n installCmd = `RUN npm install -g ${normalizedPackages.join(\" \")}`;\n break;\n case \"bun\":\n installCmd = `RUN bun install -g ${normalizedPackages.join(\" \")}`;\n break;\n case \"deno\":\n // Deno uses URL imports, but we can pre-cache\n installCmd = normalizedPackages.map((p) => `RUN deno cache ${p}`).join(\"\\n\");\n break;\n case \"bash\":\n installCmd = `RUN apk add --no-cache ${normalizedPackages.join(\" \")}`;\n break;\n default:\n throw new Error(`Unknown runtime: ${runtime}`);\n }\n\n const dockerfileContent = `FROM isol8:${runtime}\\n${installCmd}\\n`;\n\n // Build using dockerode with an inline tar containing just the Dockerfile\n const { createTarBuffer, validatePackageName } = await import(\"./utils\");\n const { Readable } = await import(\"node:stream\");\n\n // Validate all packages before building\n normalizedPackages.forEach(validatePackageName);\n\n const tarBuffer = createTarBuffer(\"Dockerfile\", dockerfileContent);\n\n const stream = await docker.buildImage(Readable.from(tarBuffer), {\n t: tag,\n dockerfile: \"Dockerfile\",\n labels: {\n [LABELS.depsHash]: depsHash,\n },\n });\n\n await new Promise<void>((resolve, reject) => {\n docker.modem.followProgress(stream, (err) => {\n if (err) {\n reject(err);\n } else {\n resolve();\n }\n });\n });\n\n // Clean up the old image if it existed and was replaced\n if (oldImageId) {\n await removeImage(docker, oldImageId);\n }\n\n onProgress?.({ runtime, status: \"done\" });\n}\n\n/**\n * Checks if an image exists locally.\n */\nexport async function imageExists(docker: Docker, imageName: string): Promise<boolean> {\n try {\n await docker.getImage(imageName).inspect();\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Ensures all base images are built.\n */\nexport async function ensureImages(docker: Docker, onProgress?: ProgressCallback): Promise<void> {\n const runtimes = RuntimeRegistry.list();\n\n const missing: string[] = [];\n for (const adapter of runtimes) {\n if (!(await imageExists(docker, adapter.image))) {\n missing.push(adapter.name);\n }\n }\n\n if (missing.length > 0) {\n await buildBaseImages(docker, onProgress, false, missing);\n }\n}\n",
15
+ "/**\n * @module client/remote\n *\n * HTTP client for communicating with a remote isol8 server. Implements the\n * {@link Isol8Engine} interface, so it can be used interchangeably with\n * {@link DockerIsol8} for local-vs-remote execution.\n */\n\nimport type {\n ExecutionRequest,\n ExecutionResult,\n Isol8Engine,\n Isol8Options,\n StartOptions,\n StreamEvent,\n} from \"../types\";\n\n/** Connection options for the remote isol8 client. */\nexport interface RemoteIsol8Options {\n /** Base URL of the isol8 server (e.g. `\"http://localhost:3000\"`). */\n host: string;\n /** API key for Bearer token authentication. */\n apiKey: string;\n /** Optional session ID for persistent mode. If set, the server maintains container state across calls. */\n sessionId?: string;\n}\n\n/**\n * Remote isol8 client that communicates with an isol8 server over HTTP.\n * Implements the {@link Isol8Engine} interface for seamless local/remote switching.\n *\n * @example\n * ```typescript\n * const isol8 = new RemoteIsol8(\n * { host: \"http://localhost:3000\", apiKey: \"secret\" },\n * { network: \"none\" }\n * );\n * await isol8.start();\n * const result = await isol8.execute({ code: \"print(1)\", runtime: \"python\" });\n * await isol8.stop();\n * ```\n */\nexport class RemoteIsol8 implements Isol8Engine {\n private readonly host: string;\n private readonly apiKey: string;\n private readonly sessionId?: string;\n private readonly isol8Options?: Isol8Options;\n\n /**\n * @param options - Connection options (host, API key, session ID).\n * @param isol8Options - Isol8 configuration to send to the server.\n */\n constructor(options: RemoteIsol8Options, isol8Options?: Isol8Options) {\n this.host = options.host.replace(/\\/$/, \"\");\n this.apiKey = options.apiKey;\n this.sessionId = options.sessionId;\n this.isol8Options = isol8Options;\n }\n\n /** Verify the remote server is reachable by hitting the `/health` endpoint. */\n async start(_options?: StartOptions): Promise<void> {\n // Verify server is reachable\n const res = await this.fetch(\"/health\");\n if (!res.ok) {\n throw new Error(`Remote server health check failed: ${res.status}`);\n }\n }\n\n /** Destroy the remote session (if persistent). No-op for ephemeral mode. */\n async stop(): Promise<void> {\n if (this.sessionId) {\n await this.fetch(`/session/${this.sessionId}`, { method: \"DELETE\" });\n }\n }\n\n /** Execute code on the remote server and return the result. */\n async execute(req: ExecutionRequest): Promise<ExecutionResult> {\n const res = await this.fetch(\"/execute\", {\n method: \"POST\",\n body: JSON.stringify({\n request: req,\n options: this.isol8Options,\n sessionId: this.sessionId,\n }),\n });\n\n if (!res.ok) {\n const body = await res.json().catch(() => ({}));\n throw new Error(`Execution failed: ${(body as { error?: string }).error ?? res.statusText}`);\n }\n\n return res.json() as Promise<ExecutionResult>;\n }\n\n /**\n * Execute code on the remote server and stream output chunks via SSE.\n * Yields {@link StreamEvent} objects as they arrive from the server.\n */\n async *executeStream(req: ExecutionRequest): AsyncIterable<StreamEvent> {\n const res = await this.fetch(\"/execute/stream\", {\n method: \"POST\",\n body: JSON.stringify({\n request: req,\n options: this.isol8Options,\n sessionId: this.sessionId,\n }),\n });\n\n if (!res.ok) {\n const body = await res.json().catch(() => ({}));\n throw new Error(`Stream failed: ${(body as { error?: string }).error ?? res.statusText}`);\n }\n\n if (!res.body) {\n throw new Error(\"No response body for streaming\");\n }\n\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n\n buffer += decoder.decode(value, { stream: true });\n\n // Parse SSE lines\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n if (line.startsWith(\"data: \")) {\n const json = line.slice(6).trim();\n if (json) {\n yield JSON.parse(json) as StreamEvent;\n }\n }\n }\n }\n\n // Process remaining buffer\n if (buffer.startsWith(\"data: \")) {\n const json = buffer.slice(6).trim();\n if (json) {\n yield JSON.parse(json) as StreamEvent;\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n /**\n * Upload a file to the remote container (persistent mode only).\n * Content is Base64-encoded for transport.\n */\n async putFile(path: string, content: Buffer | string): Promise<void> {\n if (!this.sessionId) {\n throw new Error(\"File operations require a sessionId (persistent mode)\");\n }\n\n const base64 =\n typeof content === \"string\"\n ? Buffer.from(content).toString(\"base64\")\n : content.toString(\"base64\");\n\n const res = await this.fetch(\"/file\", {\n method: \"POST\",\n body: JSON.stringify({\n sessionId: this.sessionId,\n path,\n content: base64,\n }),\n });\n\n if (!res.ok) {\n throw new Error(`File upload failed: ${res.statusText}`);\n }\n }\n\n /** Download a file from the remote container (persistent mode only). */\n async getFile(path: string): Promise<Buffer> {\n if (!this.sessionId) {\n throw new Error(\"File operations require a sessionId (persistent mode)\");\n }\n\n const params = new URLSearchParams({ sessionId: this.sessionId, path });\n const res = await this.fetch(`/file?${params}`);\n\n if (!res.ok) {\n throw new Error(`File download failed: ${res.statusText}`);\n }\n\n const body = (await res.json()) as { content: string };\n return Buffer.from(body.content, \"base64\");\n }\n\n /** Internal fetch wrapper that attaches auth and content-type headers. */\n private async fetch(path: string, init?: RequestInit): Promise<Response> {\n return globalThis.fetch(`${this.host}${path}`, {\n ...init,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n ...(init?.headers ?? {}),\n },\n });\n }\n}\n",
16
+ "/**\n * @module config\n *\n * Configuration discovery and loading for isol8. Searches for `isol8.config.json`\n * in the working directory and then in `~/.isol8/config.json`, merging any found\n * config with built-in defaults.\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport type { Isol8Config } from \"./types\";\n\n/**\n * Built-in default configuration. Used as the base for all config merges.\n * All values here are the \"safe defaults\" — network disabled, conservative limits.\n */\nconst DEFAULT_CONFIG: Isol8Config = {\n maxConcurrent: 10,\n defaults: {\n timeoutMs: 30_000,\n memoryLimit: \"512m\",\n cpuLimit: 1.0,\n network: \"none\",\n sandboxSize: \"512m\",\n tmpSize: \"256m\",\n readonlyRootFs: true,\n },\n network: {\n whitelist: [],\n blacklist: [],\n },\n cleanup: {\n autoPrune: true,\n maxContainerAgeMs: 3_600_000,\n },\n poolStrategy: \"fast\",\n poolSize: { clean: 1, dirty: 1 },\n dependencies: {},\n security: {\n seccomp: \"strict\",\n },\n remoteCode: {\n enabled: false,\n allowedSchemes: [\"https\"],\n allowedHosts: [],\n blockedHosts: [\n \"^localhost$\",\n \"^127(?:\\\\.[0-9]{1,3}){3}$\",\n \"^\\\\[::1\\\\]$\",\n \"^::1$\",\n \"^10(?:\\\\.[0-9]{1,3}){3}$\",\n \"^172\\\\.(?:1[6-9]|2[0-9]|3[0-1])(?:\\\\.[0-9]{1,3}){2}$\",\n \"^192\\\\.168(?:\\\\.[0-9]{1,3}){2}$\",\n \"^169\\\\.254(?:\\\\.[0-9]{1,3}){2}$\",\n \"^metadata\\\\.google\\\\.internal$\",\n \"^169\\\\.254\\\\.169\\\\.254$\",\n ],\n maxCodeSize: 10 * 1024 * 1024,\n fetchTimeoutMs: 30_000,\n requireHash: false,\n enableCache: true,\n cacheTtl: 3600,\n },\n audit: {\n enabled: false,\n destination: \"filesystem\",\n logDir: undefined,\n postLogScript: undefined,\n trackResources: true,\n retentionDays: 90,\n includeCode: false,\n includeOutput: false,\n },\n debug: false,\n};\n\n/**\n * Discovers and loads the isol8 configuration file.\n *\n * Search order (first match wins):\n * 1. `isol8.config.json` in CWD (or the provided `cwd` argument)\n * 2. `~/.isol8/config.json`\n *\n * If no config file is found, returns a copy of {@link DEFAULT_CONFIG}.\n * Partial configs are deep-merged with defaults — you only need to specify\n * the fields you want to override.\n *\n * @param cwd - Optional working directory to search from (defaults to `process.cwd()`).\n * @returns The resolved configuration.\n *\n * @example\n * ```typescript\n * const config = loadConfig();\n * console.log(config.defaults.timeoutMs); // 30000\n * ```\n */\nexport function loadConfig(cwd?: string): Isol8Config {\n const searchPaths = [\n join(resolve(cwd ?? process.cwd()), \"isol8.config.json\"),\n join(homedir(), \".isol8\", \"config.json\"),\n ];\n\n for (const configPath of searchPaths) {\n if (existsSync(configPath)) {\n const raw = readFileSync(configPath, \"utf-8\");\n const parsed = JSON.parse(raw) as Partial<Isol8Config>;\n return mergeConfig(DEFAULT_CONFIG, parsed);\n }\n }\n\n return { ...DEFAULT_CONFIG };\n}\n\n/**\n * Deep-merges a partial config with defaults. Each top-level section is merged\n * independently so that specifying e.g. `{ defaults: { timeoutMs: 5000 } }`\n * preserves all other default values.\n */\nfunction mergeConfig(defaults: Isol8Config, overrides: Partial<Isol8Config>): Isol8Config {\n return {\n maxConcurrent: overrides.maxConcurrent ?? defaults.maxConcurrent,\n defaults: {\n ...defaults.defaults,\n ...overrides.defaults,\n readonlyRootFs: overrides.defaults?.readonlyRootFs ?? defaults.defaults.readonlyRootFs,\n },\n network: {\n whitelist: overrides.network?.whitelist ?? defaults.network.whitelist,\n blacklist: overrides.network?.blacklist ?? defaults.network.blacklist,\n },\n cleanup: {\n ...defaults.cleanup,\n ...overrides.cleanup,\n },\n poolStrategy: overrides.poolStrategy ?? defaults.poolStrategy,\n poolSize: overrides.poolSize ?? defaults.poolSize,\n dependencies: {\n ...defaults.dependencies,\n ...overrides.dependencies,\n },\n security: {\n seccomp: overrides.security?.seccomp ?? defaults.security.seccomp,\n customProfilePath:\n overrides.security?.customProfilePath ?? defaults.security.customProfilePath,\n },\n remoteCode: {\n ...defaults.remoteCode,\n ...overrides.remoteCode,\n allowedSchemes: overrides.remoteCode?.allowedSchemes ?? defaults.remoteCode.allowedSchemes,\n allowedHosts: overrides.remoteCode?.allowedHosts ?? defaults.remoteCode.allowedHosts,\n blockedHosts: overrides.remoteCode?.blockedHosts ?? defaults.remoteCode.blockedHosts,\n },\n audit: {\n ...defaults.audit,\n ...overrides.audit,\n },\n debug: overrides.debug ?? defaults.debug,\n };\n}\n\nexport { DEFAULT_CONFIG };\n",
17
+ "/**\n * @module engine/concurrency\n *\n * Async semaphore for limiting the number of concurrent container executions.\n * Used by {@link DockerIsol8} to prevent resource exhaustion.\n */\n\n/**\n * A counting semaphore for limiting concurrent async operations.\n *\n * @example\n * ```typescript\n * const sem = new Semaphore(3); // allow 3 concurrent operations\n *\n * await sem.acquire();\n * try {\n * await doWork();\n * } finally {\n * sem.release();\n * }\n * ```\n */\nexport class Semaphore {\n private current = 0;\n private readonly queue: (() => void)[] = [];\n\n /**\n * @param max - Maximum number of concurrent acquisitions. Must be ≥ 1.\n * @throws {Error} If `max` is less than 1.\n */\n constructor(private readonly max: number) {\n if (max < 1) {\n throw new Error(\"Semaphore max must be >= 1\");\n }\n }\n\n /** The number of permits currently available. */\n get available(): number {\n return this.max - this.current;\n }\n\n /** The number of callers waiting to acquire a permit. */\n get pending(): number {\n return this.queue.length;\n }\n\n /**\n * Acquire a permit. Resolves immediately if one is available,\n * otherwise queues the caller until a permit is released.\n */\n async acquire(): Promise<void> {\n if (this.current < this.max) {\n this.current++;\n return;\n }\n\n return new Promise<void>((resolve) => {\n this.queue.push(resolve);\n });\n }\n\n /**\n * Release a permit. If callers are queued, the next one is resolved.\n * Must be called exactly once for each successful `acquire()`.\n */\n release(): void {\n const next = this.queue.shift();\n if (next) {\n next();\n } else {\n this.current--;\n }\n }\n}\n",
18
+ "/**\n * @module engine/docker\n *\n * The Docker-backed isol8 engine. Creates and manages Docker containers\n * for executing untrusted code with resource limits, network controls, and\n * output sanitization.\n */\n\nimport { randomUUID } from \"node:crypto\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { PassThrough, type Readable } from \"node:stream\";\nimport Docker from \"dockerode\";\nimport { RuntimeRegistry } from \"../runtime\";\nimport type { RuntimeAdapter } from \"../runtime/adapter\";\nimport type {\n ExecutionRequest,\n ExecutionResult,\n Isol8Dependencies,\n Isol8Engine,\n Isol8Mode,\n Isol8Options,\n NetworkFilterConfig,\n NetworkMode,\n RemoteCodePolicy,\n SecurityConfig,\n StartOptions,\n StreamEvent,\n} from \"../types\";\nimport { logger } from \"../utils/logger\";\nimport { AuditLogger } from \"./audit\";\nimport { fetchRemoteCode } from \"./code-fetcher\";\nimport { Semaphore } from \"./concurrency\";\nimport { EMBEDDED_DEFAULT_SECCOMP_PROFILE } from \"./default-seccomp-profile\";\nimport { getCustomImageTag, normalizePackages } from \"./image-builder\";\nimport { ContainerPool } from \"./pool\";\nimport { type ContainerResourceUsage, calculateResourceDelta, getContainerStats } from \"./stats\";\nimport {\n createTarBuffer,\n extractFromTar,\n maskSecrets,\n parseMemoryLimit,\n truncateOutput,\n} from \"./utils\";\n\n/**\n * Writes a file into a running container using `docker exec`.\n * This bypasses the `putArchive` limitation where Docker rejects archive\n * uploads when `ReadonlyRootfs` is enabled — even to writable tmpfs mounts.\n *\n * Uses base64 encoding. Small files use direct command (fast), large files\n * use chunked approach to avoid command line length limits.\n */\nasync function writeFileViaExec(\n container: Docker.Container,\n filePath: string,\n content: Buffer | string\n): Promise<void> {\n const data = typeof content === \"string\" ? Buffer.from(content, \"utf-8\") : content;\n const b64 = data.toString(\"base64\");\n\n // Fast path for small files (< 20KB)\n if (b64.length < 20_000) {\n const exec = await container.exec({\n Cmd: [\"sh\", \"-c\", `printf '%s' '${b64}' | base64 -d > ${filePath}`],\n User: \"sandbox\",\n });\n\n await exec.start({ Detach: true });\n\n let info = await exec.inspect();\n while (info.Running) {\n await new Promise((r) => setTimeout(r, 5));\n info = await exec.inspect();\n }\n\n if (info.ExitCode !== 0) {\n throw new Error(`Failed to write file ${filePath} in container (exit code ${info.ExitCode})`);\n }\n return;\n }\n\n // Chunked approach for larger files\n const tempPath = `/tmp/b64_${Date.now()}.tmp`;\n\n const chunkSize = 8000;\n for (let i = 0; i < b64.length; i += chunkSize) {\n const chunk = b64.slice(i, i + chunkSize);\n const exec = await container.exec({\n Cmd: [\"sh\", \"-c\", `printf '%s' '${chunk}' >> ${tempPath}`],\n User: \"sandbox\",\n });\n await exec.start({ Detach: true });\n await exec.inspect();\n }\n\n // Decode\n const decodeExec = await container.exec({\n Cmd: [\"sh\", \"-c\", `base64 -d ${tempPath} > ${filePath} && rm ${tempPath}`],\n User: \"sandbox\",\n });\n await decodeExec.start({ Detach: true });\n\n let info = await decodeExec.inspect();\n while (info.Running) {\n await new Promise((r) => setTimeout(r, 5));\n info = await decodeExec.inspect();\n }\n\n if (info.ExitCode !== 0) {\n throw new Error(`Failed to write file ${filePath} in container (exit code ${info.ExitCode})`);\n }\n}\n\n/**\n * Reads a file from a running container using `docker exec`.\n * This bypasses the `getArchive` limitation where Docker rejects archive\n * downloads when `ReadonlyRootfs` is enabled — even from writable tmpfs mounts.\n *\n * Works by running `base64 <path>` and decoding the output.\n */\nasync function readFileViaExec(container: Docker.Container, filePath: string): Promise<Buffer> {\n const exec = await container.exec({\n Cmd: [\"base64\", filePath],\n AttachStdout: true,\n AttachStderr: true,\n User: \"sandbox\",\n });\n\n const stream = await exec.start({ Tty: false });\n\n const chunks: Buffer[] = [];\n const stderrChunks: Buffer[] = [];\n\n const stdoutStream = new PassThrough();\n const stderrStream = new PassThrough();\n container.modem.demuxStream(stream, stdoutStream, stderrStream);\n\n stdoutStream.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n stderrStream.on(\"data\", (chunk: Buffer) => stderrChunks.push(chunk));\n\n await new Promise<void>((resolve, reject) => {\n stream.on(\"end\", resolve);\n stream.on(\"error\", reject);\n });\n\n const inspectResult = await exec.inspect();\n if (inspectResult.ExitCode !== 0) {\n const stderr = Buffer.concat(stderrChunks).toString(\"utf-8\").trim();\n throw new Error(\n `Failed to read file ${filePath} in container: ${stderr} (exit code ${inspectResult.ExitCode})`\n );\n }\n\n const b64Output = Buffer.concat(chunks).toString(\"utf-8\").trim();\n return Buffer.from(b64Output, \"base64\");\n}\n\nconst SANDBOX_WORKDIR = \"/sandbox\";\nconst MAX_OUTPUT_BYTES = 1024 * 1024; // 1MB default\nconst PROXY_PORT = 8118;\nconst PROXY_STARTUP_TIMEOUT_MS = 5000;\nconst PROXY_POLL_INTERVAL_MS = 100;\n\n/**\n * Starts the bash proxy inside the container for filtered network mode.\n * Waits until the proxy is listening on PROXY_PORT before returning.\n */\nasync function startProxy(\n container: Docker.Container,\n networkFilter?: { whitelist: string[]; blacklist: string[] }\n): Promise<void> {\n const envParts: string[] = [];\n if (networkFilter) {\n envParts.push(`ISOL8_WHITELIST='${JSON.stringify(networkFilter.whitelist)}'`);\n envParts.push(`ISOL8_BLACKLIST='${JSON.stringify(networkFilter.blacklist)}'`);\n }\n const envPrefix = envParts.length > 0 ? `${envParts.join(\" \")} ` : \"\";\n\n // Start proxy in background\n const startExec = await container.exec({\n Cmd: [\"sh\", \"-c\", `${envPrefix}bash /usr/local/bin/proxy.sh &`],\n });\n await startExec.start({ Detach: true });\n\n // Poll until proxy is ready\n const deadline = Date.now() + PROXY_STARTUP_TIMEOUT_MS;\n while (Date.now() < deadline) {\n try {\n const checkExec = await container.exec({\n Cmd: [\"sh\", \"-c\", `nc -z 127.0.0.1 ${PROXY_PORT} 2>/dev/null`],\n });\n await checkExec.start({ Detach: true });\n let info = await checkExec.inspect();\n while (info.Running) {\n await new Promise((r) => setTimeout(r, 50));\n info = await checkExec.inspect();\n }\n if (info.ExitCode === 0) {\n return;\n }\n } catch {\n // Ignore, keep polling\n }\n await new Promise((r) => setTimeout(r, PROXY_POLL_INTERVAL_MS));\n }\n throw new Error(\"Proxy failed to start within timeout\");\n}\n\n/**\n * Sets up iptables rules inside the container to enforce network filtering.\n *\n * Only traffic from the `sandbox` user (uid 100) to the local proxy\n * on PROXY_PORT is allowed. All other outbound traffic from the sandbox\n * user is dropped at the kernel level, preventing raw-socket bypass of\n * the HTTP proxy.\n *\n * Rules added (in order):\n * 1. Allow all loopback traffic (lo interface)\n * 2. Allow established/related connections (return traffic)\n * 3. Allow sandbox user → 127.0.0.1:PROXY_PORT (TCP)\n * 4. Drop all other outbound from sandbox user (uid 100)\n *\n * Must be called AFTER startProxy() since the proxy needs to bind first.\n * Runs as root (default exec user) since iptables requires CAP_NET_ADMIN.\n */\nasync function setupIptables(container: Docker.Container): Promise<void> {\n const rules = [\n // Allow all loopback traffic\n \"/usr/sbin/iptables -A OUTPUT -o lo -j ACCEPT\",\n // Allow established/related connections (responses to allowed requests)\n \"/usr/sbin/iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT\",\n // Allow sandbox user to reach the proxy\n `/usr/sbin/iptables -A OUTPUT -p tcp -d 127.0.0.1 --dport ${PROXY_PORT} -m owner --uid-owner 100 -j ACCEPT`,\n // Drop everything else from the sandbox user\n \"/usr/sbin/iptables -A OUTPUT -m owner --uid-owner 100 -j DROP\",\n ].join(\" && \");\n\n const exec = await container.exec({\n Cmd: [\"sh\", \"-c\", rules],\n // Runs as root (default) — iptables requires elevated privileges\n });\n await exec.start({ Detach: true });\n\n // Wait for the exec to complete\n let info = await exec.inspect();\n while (info.Running) {\n await new Promise((r) => setTimeout(r, 50));\n info = await exec.inspect();\n }\n\n if (info.ExitCode !== 0) {\n throw new Error(`Failed to set up iptables rules (exit code ${info.ExitCode})`);\n }\n\n logger.debug(\"[Filtered] iptables rules applied — sandbox user restricted to proxy only\");\n}\n\n/**\n * Wraps a command with the `timeout` utility so the process is killed\n * after the specified duration. Returns the wrapped command.\n */\nfunction wrapWithTimeout(cmd: string[], timeoutSec: number): string[] {\n return [\"timeout\", \"-s\", \"KILL\", String(timeoutSec), ...cmd];\n}\n\n/**\n * Returns the package manager install command for a given runtime.\n */\nfunction getInstallCommand(runtime: string, packages: string[]): string[] {\n switch (runtime) {\n case \"python\":\n return [\n \"pip\",\n \"install\",\n \"--user\",\n \"--no-cache-dir\",\n \"--break-system-packages\",\n \"--disable-pip-version-check\",\n \"--retries\",\n \"0\",\n \"--timeout\",\n \"15\",\n ...packages,\n ];\n case \"node\":\n // Install to /sandbox (local node_modules) so resolution works for both CJS and ESM\n return [\"npm\", \"install\", \"--prefix\", \"/sandbox\", ...packages];\n case \"bun\":\n // Bun global install - use /sandbox for writable location\n return [\"bun\", \"install\", \"-g\", \"--global-dir=/sandbox/.bun-global\", ...packages];\n case \"deno\":\n // Deno uses URL imports; cache modules to /sandbox\n return [\"sh\", \"-c\", packages.map((p) => `deno cache ${p}`).join(\" && \")];\n case \"bash\":\n return [\"apk\", \"add\", \"--no-cache\", ...packages];\n default:\n throw new Error(`Unknown runtime for package install: ${runtime}`);\n }\n}\n\n/**\n * Installs packages inside a container using the runtime's package manager.\n */\nasync function installPackages(\n container: Docker.Container,\n runtime: string,\n packages: string[],\n timeoutMs: number\n): Promise<void> {\n const timeoutSec = Math.max(1, Math.ceil(timeoutMs / 1000));\n const cmd = wrapWithTimeout(getInstallCommand(runtime, packages), timeoutSec);\n // Debug log\n logger.debug(`Installing packages: ${JSON.stringify(cmd)}`);\n\n // Set environment for writable install locations\n // Use /sandbox instead of /tmp because /tmp has noexec flag which prevents loading .so files\n const env: string[] = [\n \"PATH=/sandbox/.local/bin:/sandbox/.npm-global/bin:/sandbox/.bun-global/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin\",\n ];\n\n if (runtime === \"python\") {\n env.push(\"PYTHONUSERBASE=/sandbox/.local\");\n } else if (runtime === \"node\") {\n env.push(\"NPM_CONFIG_PREFIX=/sandbox/.npm-global\");\n env.push(\"NPM_CONFIG_CACHE=/sandbox/.npm-cache\");\n env.push(\"npm_config_cache=/sandbox/.npm-cache\");\n env.push(\"NPM_CONFIG_FETCH_RETRIES=0\");\n env.push(\"npm_config_fetch_retries=0\");\n env.push(\"NPM_CONFIG_FETCH_RETRY_MINTIMEOUT=1000\");\n env.push(\"npm_config_fetch_retry_mintimeout=1000\");\n env.push(\"NPM_CONFIG_FETCH_RETRY_MAXTIMEOUT=2000\");\n env.push(\"npm_config_fetch_retry_maxtimeout=2000\");\n } else if (runtime === \"bun\") {\n env.push(\"BUN_INSTALL_GLOBAL_DIR=/sandbox/.bun-global\");\n env.push(\"BUN_INSTALL_CACHE_DIR=/sandbox/.bun-cache\");\n env.push(\"BUN_INSTALL_BIN=/sandbox/.bun-global/bin\");\n } else if (runtime === \"deno\") {\n env.push(\"DENO_DIR=/sandbox/.deno\");\n }\n\n const exec = await container.exec({\n Cmd: cmd,\n AttachStdout: true,\n AttachStderr: true,\n Env: env,\n // Bash uses apk which requires root; all others install to user directories\n User: runtime === \"bash\" ? \"root\" : \"sandbox\",\n });\n\n const stream = await exec.start({ Detach: false, Tty: false });\n\n return new Promise<void>((resolve, reject) => {\n let stderr = \"\";\n const stdoutStream = new PassThrough();\n const stderrStream = new PassThrough();\n\n container.modem.demuxStream(stream, stdoutStream, stderrStream);\n\n stderrStream.on(\"data\", (chunk) => {\n const text = chunk.toString();\n stderr += text;\n logger.debug(`[install:${runtime}:stderr] ${text.trimEnd()}`);\n });\n\n stdoutStream.on(\"data\", (chunk) => {\n const text = chunk.toString();\n logger.debug(`[install:${runtime}:stdout] ${text.trimEnd()}`);\n });\n\n stream.on(\"end\", async () => {\n try {\n const info = await exec.inspect();\n if (info.ExitCode !== 0) {\n reject(new Error(`Package install failed (exit code ${info.ExitCode}): ${stderr}`));\n } else {\n resolve();\n }\n } catch (err) {\n reject(err);\n }\n });\n\n stream.on(\"error\", reject);\n });\n}\n\n/** Options for constructing a {@link DockerIsol8} instance. Extends {@link Isol8Options} with Docker-specific settings. */\nexport interface DockerIsol8Options extends Isol8Options {\n /** Custom dockerode instance. Defaults to connecting to the local Docker socket. */\n docker?: Docker;\n}\n\n/**\n * Docker-backed isol8 engine that executes code in isolated containers.\n *\n * Supports two modes:\n * - **Ephemeral** — a new container is created and destroyed per `execute()` call.\n * - **Persistent** — a long-lived container is reused across calls, preserving state.\n *\n * @example\n * ```typescript\n * const isol8 = new DockerIsol8({ network: \"none\", memoryLimit: \"256m\" });\n * await isol8.start();\n * const result = await isol8.execute({ code: \"print(1+1)\", runtime: \"python\" });\n * await isol8.stop();\n * ```\n */\nexport class DockerIsol8 implements Isol8Engine {\n private readonly docker: Docker;\n private readonly mode: Isol8Mode;\n private readonly network: NetworkMode;\n private readonly networkFilter?: NetworkFilterConfig;\n private readonly cpuLimit: number;\n private readonly memoryLimit: string;\n private readonly pidsLimit: number;\n private readonly readonlyRootFs: boolean;\n private readonly maxOutputSize: number;\n private readonly secrets: Record<string, string>;\n private readonly defaultTimeoutMs: number;\n private readonly overrideImage?: string;\n private readonly semaphore: Semaphore;\n private readonly sandboxSize: string;\n private readonly tmpSize: string;\n private readonly security: SecurityConfig;\n private readonly persist: boolean;\n private readonly logNetwork: boolean;\n private readonly poolStrategy: \"secure\" | \"fast\";\n private readonly poolSize: number | { clean: number; dirty: number };\n private readonly dependencies: Isol8Dependencies;\n private readonly auditLogger?: AuditLogger;\n private readonly remoteCodePolicy: RemoteCodePolicy;\n\n private container: Docker.Container | null = null;\n private persistentRuntime: RuntimeAdapter | null = null;\n private pool: ContainerPool | null = null;\n private readonly imageCache = new Map<string, string>();\n\n private async resolveExecutionRequest(\n req: ExecutionRequest\n ): Promise<ExecutionRequest & { code: string }> {\n const inlineCode = req.code?.trim();\n const codeUrl = req.codeUrl?.trim();\n\n if (inlineCode && codeUrl) {\n throw new Error(\"ExecutionRequest.code and ExecutionRequest.codeUrl are mutually exclusive.\");\n }\n if (!(inlineCode || codeUrl)) {\n throw new Error(\"ExecutionRequest must include either code or codeUrl.\");\n }\n\n if (inlineCode) {\n return { ...req, code: req.code! };\n }\n\n const fetched = await fetchRemoteCode(\n {\n codeUrl: codeUrl!,\n codeHash: req.codeHash,\n allowInsecureCodeUrl: req.allowInsecureCodeUrl,\n },\n this.remoteCodePolicy\n );\n\n return { ...req, code: fetched.code };\n }\n\n /**\n * @param options - Sandbox configuration options.\n * @param maxConcurrent - Maximum number of concurrent executions (controls the internal semaphore).\n */\n constructor(options: DockerIsol8Options = {}, maxConcurrent = 10) {\n this.docker = options.docker ?? new Docker();\n this.mode = options.mode ?? \"ephemeral\";\n this.network = options.network ?? \"none\";\n this.networkFilter = options.networkFilter;\n this.cpuLimit = options.cpuLimit ?? 1.0;\n this.memoryLimit = options.memoryLimit ?? \"512m\";\n this.pidsLimit = options.pidsLimit ?? 64;\n this.readonlyRootFs = options.readonlyRootFs ?? true;\n this.maxOutputSize = options.maxOutputSize ?? MAX_OUTPUT_BYTES;\n this.secrets = options.secrets ?? {};\n this.defaultTimeoutMs = options.timeoutMs ?? 30_000;\n this.overrideImage = options.image;\n this.semaphore = new Semaphore(maxConcurrent);\n this.sandboxSize = options.sandboxSize ?? \"512m\";\n this.tmpSize = options.tmpSize ?? \"256m\";\n this.persist = options.persist ?? false;\n this.security = options.security ?? { seccomp: \"strict\" };\n this.logNetwork = options.logNetwork ?? false;\n this.poolStrategy = options.poolStrategy ?? \"fast\";\n this.poolSize = options.poolSize ?? { clean: 1, dirty: 1 };\n this.dependencies = options.dependencies ?? {};\n this.remoteCodePolicy = options.remoteCode ?? {\n enabled: false,\n allowedSchemes: [\"https\"],\n allowedHosts: [],\n blockedHosts: [],\n maxCodeSize: 10 * 1024 * 1024,\n fetchTimeoutMs: 30_000,\n requireHash: false,\n enableCache: true,\n cacheTtl: 3600,\n };\n\n // Initialize audit logger if audit config is provided\n if (options.audit) {\n this.auditLogger = new AuditLogger(options.audit);\n }\n\n if (options.debug) {\n logger.setDebug(true);\n }\n }\n\n /**\n * Initialize isol8.\n *\n * In ephemeral mode this can optionally pre-warm the container pool.\n * In persistent mode the container is created lazily on first execute.\n */\n async start(options: StartOptions = {}): Promise<void> {\n if (this.mode !== \"ephemeral\") {\n return;\n }\n\n const prewarm = options.prewarm;\n if (!prewarm) {\n return;\n }\n\n const pool = this.ensurePool();\n const images = new Set<string>();\n\n const adapters =\n typeof prewarm === \"object\" && prewarm.runtimes?.length\n ? prewarm.runtimes.map((runtime) => RuntimeRegistry.get(runtime))\n : RuntimeRegistry.list();\n\n for (const adapter of adapters) {\n try {\n images.add(await this.resolveImage(adapter));\n } catch (err) {\n logger.debug(`[Pool] Pre-warm image resolution failed for ${adapter.name}: ${err}`);\n }\n }\n\n await Promise.all(\n [...images].map(async (image) => {\n try {\n await pool.warm(image);\n logger.debug(`[Pool] Pre-warmed image: ${image}`);\n } catch (err) {\n logger.debug(`[Pool] Pre-warm failed for ${image}: ${err}`);\n }\n })\n );\n }\n\n /** Stop and remove the container (if one exists). Safe to call multiple times. */\n async stop(): Promise<void> {\n if (this.container) {\n try {\n await this.container.stop({ t: 2 });\n } catch {\n // Container may already be stopped\n }\n try {\n await this.container.remove({ force: true });\n } catch {\n // Container may already be removed\n }\n this.container = null;\n this.persistentRuntime = null;\n }\n\n // Drain the warm container pool\n if (this.pool) {\n await this.pool.drain();\n this.pool = null;\n }\n }\n\n /**\n * Execute code in isol8. Acquires a semaphore permit to enforce\n * the concurrency limit, then delegates to ephemeral or persistent execution.\n */\n async execute(req: ExecutionRequest): Promise<ExecutionResult> {\n await this.semaphore.acquire();\n const startTime = Date.now();\n try {\n const request = await this.resolveExecutionRequest(req);\n const result =\n this.mode === \"persistent\"\n ? await this.executePersistent(request, startTime)\n : await this.executeEphemeral(request, startTime);\n\n return result;\n } finally {\n this.semaphore.release();\n }\n }\n\n /**\n * Record an audit entry for the execution.\n */\n private async recordAudit(\n req: ExecutionRequest & { code: string },\n result: ExecutionResult,\n startTime: number,\n container?: Docker.Container\n ): Promise<void> {\n try {\n // Calculate code hash using Web Crypto API\n const enc = new TextEncoder();\n const data = enc.encode(req.code);\n const digest = await crypto.subtle.digest(\"SHA-256\", data);\n const codeHash = Array.from(new Uint8Array(digest))\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n\n // Collect security events if container is available\n let securityEvents: import(\"../types\").SecurityEvent[] | undefined;\n if (container && this.network === \"filtered\") {\n securityEvents = await this.collectSecurityEvents(container);\n if (securityEvents.length === 0) {\n securityEvents = undefined;\n }\n }\n\n // Collect network logs if enabled\n let networkLogs: import(\"../types\").NetworkLogEntry[] | undefined;\n if (this.logNetwork && result.networkLogs) {\n networkLogs = result.networkLogs;\n }\n\n const audit = {\n executionId: result.executionId,\n userId: req.metadata?.userId || \"\",\n timestamp: new Date(startTime).toISOString(),\n runtime: result.runtime,\n codeHash,\n containerId: result.containerId || \"\",\n exitCode: result.exitCode,\n durationMs: result.durationMs,\n resourceUsage: result.resourceUsage,\n securityEvents,\n networkLogs,\n metadata: req.metadata,\n };\n\n // Apply privacy filtering and record\n this.auditLogger!.record(audit);\n } catch (err) {\n logger.error(\"Failed to record audit log:\", err);\n }\n }\n\n /**\n * Collect security events from the container (e.g., network filter blocks).\n */\n private async collectSecurityEvents(\n container: Docker.Container\n ): Promise<import(\"../types\").SecurityEvent[]> {\n const events: import(\"../types\").SecurityEvent[] = [];\n\n try {\n // Read security events from proxy log\n const exec = await container.exec({\n Cmd: [\"cat\", \"/tmp/isol8-proxy/security-events.jsonl\"],\n AttachStdout: true,\n AttachStderr: false,\n User: \"root\",\n });\n\n const stream = await exec.start({ Tty: false });\n const chunks: Buffer[] = [];\n\n for await (const chunk of stream as AsyncIterable<Buffer>) {\n chunks.push(chunk);\n }\n\n const output = Buffer.concat(chunks).toString(\"utf-8\").trim();\n if (output) {\n for (const line of output.split(\"\\n\")) {\n if (line.trim()) {\n try {\n const event = JSON.parse(line);\n events.push({\n type: event.type || \"unknown\",\n message: `Security event: ${event.type}`,\n details: event.details || {},\n timestamp: event.timestamp || new Date().toISOString(),\n });\n } catch {\n // Skip malformed lines\n }\n }\n }\n }\n } catch {\n // No security events file or container doesn't exist anymore\n }\n\n return events;\n }\n\n /**\n * Collect network logs from the container (requests made through the proxy).\n */\n private async collectNetworkLogs(\n container: Docker.Container\n ): Promise<import(\"../types\").NetworkLogEntry[]> {\n const logs: import(\"../types\").NetworkLogEntry[] = [];\n\n try {\n const exec = await container.exec({\n Cmd: [\"cat\", \"/tmp/isol8-proxy/network.jsonl\"],\n AttachStdout: true,\n AttachStderr: false,\n User: \"root\",\n });\n\n const stream = await exec.start({ Tty: false });\n const chunks: Buffer[] = [];\n\n for await (const chunk of stream as AsyncIterable<Buffer>) {\n chunks.push(chunk);\n }\n\n const output = Buffer.concat(chunks).toString(\"utf-8\").trim();\n logger.debug(\n `[NetworkLogs] Raw output length: ${output.length}, first 100 chars: ${output.substring(0, 100).replace(/\\\\n/g, \"\\\\n\")}`\n );\n // Filter to only lines that contain valid JSON\n // Find the JSON object by looking for the first { and last }\n const jsonLines = output.split(\"\\n\").filter((line) => line.includes(\"timestamp\"));\n logger.debug(\n `[NetworkLogs] Found ${jsonLines.length} JSON lines out of ${output.split(\"\\n\").length} total lines`\n );\n for (const line of jsonLines) {\n // Extract JSON by finding the first { and last }\n const startIdx = line.indexOf(\"{\");\n const endIdx = line.lastIndexOf(\"}\");\n if (startIdx === -1 || endIdx === -1) {\n continue;\n }\n const jsonStr = line.substring(startIdx, endIdx + 1);\n try {\n const entry = JSON.parse(jsonStr);\n logs.push({\n timestamp: entry.timestamp || new Date().toISOString(),\n method: entry.method || \"UNKNOWN\",\n host: entry.host || \"\",\n path: entry.path,\n action: entry.action || \"ALLOW\",\n durationMs: entry.durationMs || 0,\n });\n logger.debug(`[NetworkLogs] Successfully parsed line: ${JSON.stringify(entry)}`);\n } catch (e) {\n logger.debug(\n `[NetworkLogs] Failed to parse line: ${line.substring(0, 50)}..., error: ${e}`\n );\n }\n }\n logger.debug(`[NetworkLogs] Total parsed logs: ${logs.length}`);\n } catch {\n // No network logs file or container doesn't exist anymore\n }\n\n return logs;\n }\n\n /**\n * Upload a file into the running container via a tar archive.\n * Only available in persistent mode after at least one `execute()` call.\n *\n * @param path - Absolute path inside the container.\n * @param content - File contents.\n * @throws {Error} If no container is active.\n */\n async putFile(path: string, content: Buffer | string): Promise<void> {\n if (!this.container) {\n throw new Error(\"No active container. Call execute() first in persistent mode.\");\n }\n if (this.readonlyRootFs) {\n await writeFileViaExec(this.container, path, content);\n } else {\n const tar = createTarBuffer(path, content);\n await this.container.putArchive(tar, { path: \"/\" });\n }\n }\n\n /**\n * Download a file from the running container.\n *\n * @param path - Absolute path inside the container.\n * @returns File contents as a Buffer.\n * @throws {Error} If no container is active.\n */\n async getFile(path: string): Promise<Buffer> {\n if (!this.container) {\n throw new Error(\"No active container. Call execute() first in persistent mode.\");\n }\n\n if (this.readonlyRootFs) {\n return readFileViaExec(this.container, path);\n }\n\n const stream = await this.container.getArchive({ path });\n\n const chunks: Buffer[] = [];\n for await (const chunk of stream as AsyncIterable<Buffer>) {\n chunks.push(chunk);\n }\n const tarBuffer = Buffer.concat(chunks);\n return extractFromTar(tarBuffer, path);\n }\n\n /** The Docker container ID, or `null` if no container is active. Used by the server for session tracking. */\n get containerId(): string | null {\n return this.container?.id ?? null;\n }\n\n /**\n * Execute code and stream output chunks as they arrive.\n * Yields {@link StreamEvent} objects for stdout, stderr, exit, and error events.\n */\n async *executeStream(req: ExecutionRequest): AsyncIterable<StreamEvent> {\n await this.semaphore.acquire();\n try {\n const request = await this.resolveExecutionRequest(req);\n const adapter = this.getAdapter(request.runtime);\n const timeoutMs = request.timeoutMs ?? this.defaultTimeoutMs;\n const image = await this.resolveImage(adapter);\n\n // Create container (always ephemeral-style for streaming)\n const container = await this.docker.createContainer({\n Image: image,\n Cmd: [\"sleep\", \"infinity\"],\n WorkingDir: SANDBOX_WORKDIR,\n Env: this.buildEnv(),\n NetworkDisabled: this.network === \"none\",\n HostConfig: this.buildHostConfig(),\n StopTimeout: 2,\n });\n\n try {\n await container.start();\n\n if (this.network === \"filtered\") {\n await startProxy(container, this.networkFilter);\n await setupIptables(container);\n }\n\n // Write code\n const ext = request.fileExtension ?? adapter.getFileExtension();\n const filePath = `${SANDBOX_WORKDIR}/main${ext}`;\n await writeFileViaExec(container, filePath, request.code);\n\n // Install packages if requested\n if (request.installPackages?.length) {\n await installPackages(container, request.runtime, request.installPackages, timeoutMs);\n }\n\n // Inject input files\n if (request.files) {\n for (const [fPath, fContent] of Object.entries(request.files)) {\n await writeFileViaExec(container, fPath, fContent);\n }\n }\n\n // Build command\n const rawCmd = adapter.getCommand(request.code, filePath);\n const timeoutSec = Math.ceil(timeoutMs / 1000);\n let cmd: string[];\n if (request.stdin) {\n const stdinPath = `${SANDBOX_WORKDIR}/_stdin`;\n await writeFileViaExec(container, stdinPath, request.stdin);\n const cmdStr = rawCmd.map((a) => `'${a.replace(/'/g, \"'\\\\''\")}'`).join(\" \");\n cmd = wrapWithTimeout([\"sh\", \"-c\", `cat ${stdinPath} | ${cmdStr}`], timeoutSec);\n } else {\n cmd = wrapWithTimeout(rawCmd, timeoutSec);\n }\n\n const exec = await container.exec({\n Cmd: cmd,\n Env: this.buildEnv(request.env),\n AttachStdout: true,\n AttachStderr: true,\n WorkingDir: SANDBOX_WORKDIR,\n User: \"sandbox\",\n });\n\n const execStream = await exec.start({ Tty: false });\n\n yield* this.streamExecOutput(execStream, exec, container, timeoutMs);\n } finally {\n if (this.persist) {\n logger.debug(`[Persist] Leaving container running for inspection: ${container.id}`);\n } else {\n try {\n await container.remove({ force: true });\n } catch {\n // Best effort cleanup\n }\n }\n }\n } finally {\n this.semaphore.release();\n }\n }\n\n // ─── Private methods ───\n\n private async resolveImage(adapter: RuntimeAdapter): Promise<string> {\n if (this.overrideImage) {\n return this.overrideImage;\n }\n\n const cacheKey = adapter.image;\n const cached = this.imageCache.get(cacheKey);\n if (cached) {\n return cached;\n }\n\n let resolvedImage = adapter.image;\n const configuredDeps = this.dependencies[adapter.name];\n const normalizedDeps = configuredDeps ? normalizePackages(configuredDeps) : [];\n\n if (normalizedDeps.length > 0) {\n const hashedCustomTag = getCustomImageTag(adapter.name, normalizedDeps);\n try {\n await this.docker.getImage(hashedCustomTag).inspect();\n resolvedImage = hashedCustomTag;\n } catch {\n logger.debug(\n `[ImageBuilder] Hashed custom image not found for ${adapter.name}: ${hashedCustomTag}`\n );\n }\n }\n\n if (resolvedImage === adapter.image) {\n // Backward-compatible fallback to legacy non-hashed custom tag.\n const legacyCustomTag = `${adapter.image}-custom`;\n try {\n await this.docker.getImage(legacyCustomTag).inspect();\n resolvedImage = legacyCustomTag;\n } catch {\n // keep base image\n }\n }\n\n // Ensure the resolved image exists. If not, build it.\n try {\n await this.docker.getImage(resolvedImage).inspect();\n } catch {\n logger.debug(`[ImageBuilder] Image ${resolvedImage} not found. Building...`);\n const { buildBaseImages, buildCustomImage } = await import(\"./image-builder\");\n\n if (resolvedImage !== adapter.image && normalizedDeps.length > 0) {\n // Building custom image: ensure base image exists first\n try {\n await this.docker.getImage(adapter.image).inspect();\n } catch {\n logger.debug(`[ImageBuilder] Base image ${adapter.image} missing. Building...`);\n await buildBaseImages(this.docker, undefined, false, [adapter.name]);\n }\n logger.debug(`[ImageBuilder] Building custom image for ${adapter.name}...`);\n await buildCustomImage(this.docker, adapter.name, normalizedDeps);\n } else {\n // Building base image\n logger.debug(`[ImageBuilder] Building base image for ${adapter.name}...`);\n await buildBaseImages(this.docker, undefined, false, [adapter.name]);\n }\n }\n\n this.imageCache.set(cacheKey, resolvedImage);\n return resolvedImage;\n }\n\n private ensurePool(): ContainerPool {\n if (!this.pool) {\n this.pool = new ContainerPool({\n docker: this.docker,\n poolStrategy: this.poolStrategy,\n poolSize: this.poolSize,\n networkMode: this.network,\n securityMode: this.security.seccomp ?? \"strict\",\n createOptions: {\n Cmd: [\"sleep\", \"infinity\"],\n WorkingDir: SANDBOX_WORKDIR,\n Env: this.buildEnv(),\n NetworkDisabled: this.network === \"none\",\n HostConfig: this.buildHostConfig(),\n StopTimeout: 2,\n },\n });\n }\n\n return this.pool;\n }\n\n private async executeEphemeral(\n req: ExecutionRequest & { code: string },\n startTime: number\n ): Promise<ExecutionResult> {\n const adapter = this.getAdapter(req.runtime);\n const timeoutMs = req.timeoutMs ?? this.defaultTimeoutMs;\n const image = await this.resolveImage(adapter);\n\n // Lazily initialize the container pool\n const pool = this.ensurePool();\n\n // Acquire a pre-warmed container from the pool\n const container = await pool.acquire(image);\n\n // Collect baseline stats if resource tracking is enabled\n let startStats: ContainerResourceUsage | undefined;\n if (this.auditLogger) {\n try {\n startStats = await getContainerStats(container);\n } catch (err) {\n logger.debug(\"Failed to collect baseline stats:\", err);\n }\n }\n\n try {\n // Start proxy for filtered network mode\n if (this.network === \"filtered\") {\n await startProxy(container, this.networkFilter);\n await setupIptables(container);\n }\n\n // Fast path: for simple executions, avoid file write and execute inline.\n // Falls back to file-based path for runtimes that require file input (e.g. Deno)\n // or when request options require filesystem artifacts.\n const canUseInline =\n !(req.stdin || req.files || req.outputPaths) &&\n (!req.installPackages || req.installPackages.length === 0);\n\n let rawCmd: string[];\n if (canUseInline) {\n try {\n rawCmd = adapter.getCommand(req.code);\n } catch {\n const ext = req.fileExtension ?? adapter.getFileExtension();\n const filePath = `${SANDBOX_WORKDIR}/main${ext}`;\n await writeFileViaExec(container, filePath, req.code);\n rawCmd = adapter.getCommand(req.code, filePath);\n }\n } else {\n const ext = req.fileExtension ?? adapter.getFileExtension();\n const filePath = `${SANDBOX_WORKDIR}/main${ext}`;\n await writeFileViaExec(container, filePath, req.code);\n rawCmd = adapter.getCommand(req.code, filePath);\n }\n\n // Install packages if requested\n if (req.installPackages?.length) {\n await installPackages(container, req.runtime, req.installPackages, timeoutMs);\n }\n\n // Execute the actual command, wrapped with timeout to ensure kill on expiry\n const timeoutSec = Math.ceil(timeoutMs / 1000);\n\n // Handle stdin: write to file and pipe into command\n let cmd: string[];\n if (req.stdin) {\n const stdinPath = `${SANDBOX_WORKDIR}/_stdin`;\n await writeFileViaExec(container, stdinPath, req.stdin);\n const cmdStr = rawCmd.map((a) => `'${a.replace(/'/g, \"'\\\\''\")}' `).join(\"\");\n cmd = wrapWithTimeout([\"sh\", \"-c\", `cat ${stdinPath} | ${cmdStr}`], timeoutSec);\n } else {\n cmd = wrapWithTimeout(rawCmd, timeoutSec);\n }\n\n // Inject input files\n if (req.files) {\n for (const [fPath, fContent] of Object.entries(req.files)) {\n await writeFileViaExec(container, fPath, fContent);\n }\n }\n\n const exec = await container.exec({\n Cmd: cmd,\n Env: this.buildEnv(req.env),\n AttachStdout: true,\n AttachStderr: true,\n WorkingDir: SANDBOX_WORKDIR,\n User: \"sandbox\",\n });\n\n const start = performance.now();\n const execStream = await exec.start({ Tty: false });\n\n const { stdout, stderr, truncated } = await this.collectExecOutput(\n execStream,\n container,\n timeoutMs\n );\n const durationMs = Math.round(performance.now() - start);\n\n const inspectResult = await exec.inspect();\n\n // Collect final stats and calculate resource usage delta\n let resourceUsage: ExecutionResult[\"resourceUsage\"];\n if (startStats) {\n try {\n const endStats = await getContainerStats(container);\n resourceUsage = calculateResourceDelta(startStats, endStats);\n } catch (err) {\n logger.debug(\"Failed to collect final stats:\", err);\n }\n }\n\n // Collect network logs if enabled and network mode is filtered\n let networkLogs: ExecutionResult[\"networkLogs\"];\n if (this.logNetwork && this.network === \"filtered\") {\n try {\n networkLogs = await this.collectNetworkLogs(container);\n if (networkLogs.length === 0) {\n networkLogs = undefined;\n }\n } catch (err) {\n logger.debug(\"Failed to collect network logs:\", err);\n }\n }\n\n const result: ExecutionResult = {\n stdout: this.postProcessOutput(stdout, truncated),\n stderr: this.postProcessOutput(stderr, false),\n exitCode: inspectResult.ExitCode ?? 1,\n durationMs,\n truncated,\n executionId: randomUUID(),\n runtime: req.runtime,\n timestamp: new Date().toISOString(),\n containerId: container.id,\n ...(resourceUsage ? { resourceUsage } : {}),\n ...(networkLogs ? { networkLogs } : {}),\n ...(req.outputPaths ? { files: await this.retrieveFiles(container, req.outputPaths) } : {}),\n };\n\n // Record audit log if audit logger is configured\n if (this.auditLogger) {\n await this.recordAudit(req, result, startTime, container);\n }\n\n return result;\n } finally {\n if (this.persist) {\n logger.debug(`[Persist] Leaving container running for inspection: ${container.id}`);\n } else {\n // Return container to pool for reuse - fire-and-forget for performance\n pool.release(container, image).catch((err) => {\n logger.debug(`[Pool] release failed: ${err}`);\n container.remove({ force: true }).catch(() => {});\n });\n }\n }\n }\n\n private async executePersistent(\n req: ExecutionRequest & { code: string },\n startTime: number\n ): Promise<ExecutionResult> {\n const adapter = this.getAdapter(req.runtime);\n const timeoutMs = req.timeoutMs ?? this.defaultTimeoutMs;\n\n // Lazily create the persistent container\n if (!this.container) {\n await this.startPersistentContainer(adapter);\n } else if (this.persistentRuntime?.name !== adapter.name) {\n throw new Error(\n `Cannot switch runtime from \"${this.persistentRuntime?.name}\" to \"${adapter.name}\". Each persistent container supports a single runtime. Create a new Isol8 instance for a different runtime.`\n );\n }\n\n const ext = req.fileExtension ?? adapter.getFileExtension();\n const filePath = `${SANDBOX_WORKDIR}/exec_${Date.now()}${ext}`;\n\n // Write code to the container\n if (this.readonlyRootFs) {\n await writeFileViaExec(this.container!, filePath, req.code);\n } else {\n const tar = createTarBuffer(filePath, req.code);\n await this.container!.putArchive(tar, { path: \"/\" });\n }\n\n // Inject input files\n if (req.files) {\n for (const [fPath, fContent] of Object.entries(req.files)) {\n if (this.readonlyRootFs) {\n await writeFileViaExec(this.container!, fPath, fContent);\n } else {\n const tar = createTarBuffer(fPath, fContent);\n await this.container!.putArchive(tar, { path: \"/\" });\n }\n }\n }\n\n const rawCmd = adapter.getCommand(req.code, filePath);\n const timeoutSec = Math.ceil(timeoutMs / 1000);\n\n // Install packages if requested\n if (req.installPackages?.length) {\n await installPackages(this.container!, req.runtime, req.installPackages, timeoutMs);\n }\n\n // Handle stdin\n let cmd: string[];\n if (req.stdin) {\n const stdinPath = `${SANDBOX_WORKDIR}/_stdin_${Date.now()}`;\n await writeFileViaExec(this.container!, stdinPath, req.stdin);\n const cmdStr = rawCmd.map((a) => `'${a.replace(/'/g, \"'\\\\''\")}' `).join(\"\");\n cmd = wrapWithTimeout([\"sh\", \"-c\", `cat ${stdinPath} | ${cmdStr}`], timeoutSec);\n } else {\n cmd = wrapWithTimeout(rawCmd, timeoutSec);\n }\n\n const execEnv = this.buildEnv(req.env);\n\n const exec = await this.container!.exec({\n Cmd: cmd,\n Env: execEnv,\n AttachStdout: true,\n AttachStderr: true,\n WorkingDir: SANDBOX_WORKDIR,\n User: \"sandbox\",\n });\n\n const start = performance.now();\n const execStream = await exec.start({ Tty: false });\n\n const { stdout, stderr, truncated } = await this.collectExecOutput(\n execStream,\n this.container!,\n timeoutMs\n );\n const durationMs = Math.round(performance.now() - start);\n\n const inspectResult = await exec.inspect();\n\n // Collect resource stats if tracking is enabled\n let resourceUsage: ExecutionResult[\"resourceUsage\"];\n if (this.auditLogger) {\n try {\n const endStats = await getContainerStats(this.container!);\n // For persistent mode, we don't have baseline, so use current values\n resourceUsage = {\n cpuPercent: endStats.cpuPercent,\n memoryMB: endStats.memoryMB,\n networkBytesIn: endStats.networkBytesIn,\n networkBytesOut: endStats.networkBytesOut,\n };\n } catch (err) {\n logger.debug(\"Failed to collect resource stats:\", err);\n }\n }\n\n // Collect network logs if enabled and network mode is filtered\n let networkLogs: ExecutionResult[\"networkLogs\"];\n if (this.logNetwork && this.network === \"filtered\") {\n try {\n networkLogs = await this.collectNetworkLogs(this.container!);\n if (networkLogs.length === 0) {\n networkLogs = undefined;\n }\n } catch (err) {\n logger.debug(\"Failed to collect network logs:\", err);\n }\n }\n\n const result: ExecutionResult = {\n stdout: this.postProcessOutput(stdout, truncated),\n stderr: this.postProcessOutput(stderr, false),\n exitCode: inspectResult.ExitCode ?? 1,\n durationMs,\n truncated,\n executionId: randomUUID(),\n runtime: req.runtime,\n timestamp: new Date().toISOString(),\n containerId: this.container?.id,\n ...(resourceUsage ? { resourceUsage } : {}),\n ...(networkLogs ? { networkLogs } : {}),\n ...(req.outputPaths\n ? { files: await this.retrieveFiles(this.container!, req.outputPaths) }\n : {}),\n };\n\n // Record audit log if audit logger is configured\n if (this.auditLogger) {\n await this.recordAudit(req, result, startTime, this.container!);\n }\n\n return result;\n }\n\n private async retrieveFiles(\n container: Docker.Container,\n paths: string[]\n ): Promise<Record<string, string>> {\n const files: Record<string, string> = {};\n for (const p of paths) {\n try {\n const buf = this.readonlyRootFs\n ? await readFileViaExec(container, p)\n : await this.getFileFromContainer(container, p);\n files[p] = buf.toString(\"base64\");\n } catch {\n // Skip files that don't exist\n }\n }\n return files;\n }\n\n private async getFileFromContainer(container: Docker.Container, path: string): Promise<Buffer> {\n const stream = await container.getArchive({ path });\n const chunks: Buffer[] = [];\n for await (const chunk of stream as AsyncIterable<Buffer>) {\n chunks.push(chunk);\n }\n return extractFromTar(Buffer.concat(chunks), path);\n }\n\n private async startPersistentContainer(adapter: RuntimeAdapter): Promise<void> {\n const image = await this.resolveImage(adapter);\n\n this.container = await this.docker.createContainer({\n Image: image,\n Cmd: [\"sleep\", \"infinity\"],\n WorkingDir: SANDBOX_WORKDIR,\n Env: this.buildEnv(),\n NetworkDisabled: this.network === \"none\",\n HostConfig: this.buildHostConfig(),\n StopTimeout: 2,\n Labels: {\n \"isol8.managed\": \"true\",\n \"isol8.runtime\": adapter.name,\n },\n });\n\n await this.container.start();\n\n // Start proxy for filtered network mode\n if (this.network === \"filtered\") {\n await startProxy(this.container, this.networkFilter);\n await setupIptables(this.container);\n }\n\n this.persistentRuntime = adapter;\n }\n\n private getAdapter(runtime: string): RuntimeAdapter {\n return RuntimeRegistry.get(runtime);\n }\n\n private buildHostConfig(): Docker.HostConfig {\n const config: Docker.HostConfig = {\n Memory: parseMemoryLimit(this.memoryLimit),\n NanoCpus: Math.floor(this.cpuLimit * 1e9),\n PidsLimit: this.pidsLimit,\n ReadonlyRootfs: this.readonlyRootFs,\n Tmpfs: {\n \"/tmp\": `rw,noexec,nosuid,nodev,size=${this.tmpSize}`,\n [SANDBOX_WORKDIR]: `rw,exec,nosuid,nodev,size=${this.sandboxSize},uid=100,gid=101`,\n },\n SecurityOpt: this.buildSecurityOpts(),\n };\n\n if (this.network === \"filtered\") {\n config.NetworkMode = \"bridge\";\n // CAP_NET_ADMIN is required for iptables rules that enforce proxy-only\n // outbound traffic from the sandbox user. The capability is used once\n // at container startup (by root) to set rules, then the sandbox user\n // (which runs all user code) cannot modify them.\n config.CapAdd = [\"NET_ADMIN\"];\n } else if (this.network === \"host\") {\n config.NetworkMode = \"host\";\n }\n\n return config;\n }\n\n private buildSecurityOpts(): string[] {\n const opts = [\"no-new-privileges\"];\n\n if (this.security.seccomp === \"unconfined\") {\n opts.push(\"seccomp=unconfined\");\n return opts;\n }\n\n if (this.security.seccomp === \"custom\" && this.security.customProfilePath) {\n try {\n const profile = readFileSync(this.security.customProfilePath, \"utf-8\");\n opts.push(`seccomp=${profile}`);\n } catch (e) {\n throw new Error(\n `Failed to load custom seccomp profile at ${this.security.customProfilePath}: ${e}`\n );\n }\n return opts;\n }\n\n // Default strict mode\n try {\n const profile = this.loadDefaultSeccompProfile();\n opts.push(`seccomp=${profile}`);\n } catch (e) {\n throw new Error(`Failed to load default seccomp profile: ${e}`);\n }\n\n return opts;\n }\n\n private loadDefaultSeccompProfile(): string {\n // Try resolving relative to this file (dev mode)\n // Note: in bundled code, import.meta.url might point to dist/index.js\n\n // 1. Try ../../docker/seccomp-profile.json (Development structure)\n // In dev: src/engine/docker.ts -> ../../docker\n const devPath = new URL(\"../../docker/seccomp-profile.json\", import.meta.url);\n if (existsSync(devPath)) {\n return readFileSync(devPath, \"utf-8\");\n }\n\n // 2. Try ./docker/seccomp-profile.json (Production/Dist structure)\n // In dist: dist/index.js -> ./docker\n const prodPath = new URL(\"./docker/seccomp-profile.json\", import.meta.url);\n if (existsSync(prodPath)) {\n return readFileSync(prodPath, \"utf-8\");\n }\n\n // 3. Embedded fallback for standalone compiled binaries.\n if (EMBEDDED_DEFAULT_SECCOMP_PROFILE.length > 0) {\n logger.debug(\n `Default seccomp profile file not found. Using embedded profile. Tried: ${devPath.pathname}, ${prodPath.pathname}`\n );\n return EMBEDDED_DEFAULT_SECCOMP_PROFILE;\n }\n\n throw new Error(\"Embedded default seccomp profile is unavailable\");\n }\n\n private buildEnv(extra?: Record<string, string>): string[] {\n const env: string[] = [\n \"PYTHONUNBUFFERED=1\",\n \"PYTHONUSERBASE=/sandbox/.local\",\n \"NPM_CONFIG_PREFIX=/sandbox/.npm-global\",\n \"DENO_DIR=/sandbox/.deno\",\n \"PATH=/sandbox/.local/bin:/sandbox/.npm-global/bin:/sandbox/.bun-global/bin:/usr/local/bin:/usr/bin:/bin\",\n \"NODE_PATH=/usr/local/lib/node_modules:/sandbox/.npm-global/lib/node_modules:/sandbox/node_modules\",\n ];\n\n // Add secrets as env vars\n for (const [key, value] of Object.entries(this.secrets)) {\n env.push(`${key}=${value}`);\n }\n\n // Add extra env vars\n if (extra) {\n for (const [key, value] of Object.entries(extra)) {\n env.push(`${key}=${value}`);\n }\n }\n\n // Add proxy config for filtered mode. Always set the HTTP(S)_PROXY\n // environment variables when running in \"filtered\" mode so runtimes\n // will use the in-container proxy. If a networkFilter is provided,\n // also export the whitelist/blacklist JSON so the proxy enforces rules.\n if (this.network === \"filtered\") {\n if (this.networkFilter) {\n env.push(`ISOL8_WHITELIST=${JSON.stringify(this.networkFilter.whitelist)}`);\n env.push(`ISOL8_BLACKLIST=${JSON.stringify(this.networkFilter.blacklist)}`);\n }\n env.push(`HTTP_PROXY=http://127.0.0.1:${PROXY_PORT}`);\n env.push(`HTTPS_PROXY=http://127.0.0.1:${PROXY_PORT}`);\n env.push(`http_proxy=http://127.0.0.1:${PROXY_PORT}`);\n env.push(`https_proxy=http://127.0.0.1:${PROXY_PORT}`);\n }\n\n return env;\n }\n\n private async *streamExecOutput(\n stream: NodeJS.ReadableStream,\n exec: Docker.Exec,\n container: Docker.Container,\n timeoutMs: number\n ): AsyncGenerator<StreamEvent> {\n // Bridge event-based stream to async generator via a queue\n const queue: StreamEvent[] = [];\n let resolve: (() => void) | null = null;\n let done = false;\n\n const push = (event: StreamEvent) => {\n queue.push(event);\n if (resolve) {\n resolve();\n resolve = null;\n }\n };\n\n const timer = setTimeout(() => {\n push({ type: \"error\", data: \"EXECUTION TIMED OUT\" });\n push({ type: \"exit\", data: \"137\" });\n done = true;\n }, timeoutMs);\n\n const stdoutStream = new PassThrough();\n const stderrStream = new PassThrough();\n\n container.modem.demuxStream(stream, stdoutStream, stderrStream);\n\n stdoutStream.on(\"data\", (chunk: Buffer) => {\n let text = chunk.toString(\"utf-8\");\n if (Object.keys(this.secrets).length > 0) {\n text = maskSecrets(text, this.secrets);\n }\n push({ type: \"stdout\", data: text });\n });\n\n stderrStream.on(\"data\", (chunk: Buffer) => {\n let text = chunk.toString(\"utf-8\");\n if (Object.keys(this.secrets).length > 0) {\n text = maskSecrets(text, this.secrets);\n }\n push({ type: \"stderr\", data: text });\n });\n\n stream.on(\"end\", async () => {\n clearTimeout(timer);\n try {\n const info = await exec.inspect();\n push({ type: \"exit\", data: (info.ExitCode ?? 0).toString() });\n } catch {\n push({ type: \"exit\", data: \"1\" });\n }\n done = true;\n });\n\n stream.on(\"error\", (err: Error) => {\n clearTimeout(timer);\n push({ type: \"error\", data: err.message });\n push({ type: \"exit\", data: \"1\" });\n done = true;\n });\n\n // Drain the queue as events arrive\n while (!done || queue.length > 0) {\n if (queue.length > 0) {\n yield queue.shift()!;\n } else if (resolve) {\n await new Promise<void>((r) => {\n resolve = r;\n });\n } else {\n await new Promise((r) => setTimeout(r, 10));\n }\n }\n }\n\n private async collectExecOutput(\n stream: NodeJS.ReadableStream,\n container: Docker.Container,\n timeoutMs: number\n ): Promise<{ stdout: string; stderr: string; truncated: boolean }> {\n return new Promise((resolve, reject) => {\n let stdout = \"\";\n let stderr = \"\";\n let truncated = false;\n let settled = false;\n let stdoutEnded = false;\n let stderrEnded = false;\n\n const timer = setTimeout(() => {\n if (settled) {\n return;\n }\n settled = true;\n // Destroy stream to ensure no more data comes in\n if ((stream as Readable).destroy) {\n (stream as Readable).destroy();\n }\n resolve({ stdout, stderr: `${stderr}\\n--- EXECUTION TIMED OUT ---`, truncated });\n }, timeoutMs);\n\n const stdoutStream = new PassThrough();\n const stderrStream = new PassThrough();\n\n container.modem.demuxStream(stream, stdoutStream, stderrStream);\n\n stdoutStream.on(\"data\", (chunk: Buffer) => {\n stdout += chunk.toString(\"utf-8\");\n if (stdout.length > this.maxOutputSize) {\n const result = truncateOutput(stdout, this.maxOutputSize);\n stdout = result.text;\n truncated = true;\n }\n });\n\n stderrStream.on(\"data\", (chunk: Buffer) => {\n stderr += chunk.toString(\"utf-8\");\n if (stderr.length > this.maxOutputSize) {\n const result = truncateOutput(stderr, this.maxOutputSize);\n stderr = result.text;\n truncated = true;\n }\n });\n\n const checkDone = () => {\n if (settled) {\n return;\n }\n if (stdoutEnded && stderrEnded) {\n settled = true;\n clearTimeout(timer);\n resolve({ stdout, stderr, truncated });\n }\n };\n\n stdoutStream.on(\"end\", () => {\n stdoutEnded = true;\n checkDone();\n });\n\n stderrStream.on(\"end\", () => {\n stderrEnded = true;\n checkDone();\n });\n\n stream.on(\"error\", (err: Error) => {\n if (settled) {\n return;\n }\n settled = true;\n clearTimeout(timer);\n reject(err);\n });\n\n // Safety net: if the main stream ends but substreams don't (shouldn't happen with PassThrough but good for safety)\n stream.on(\"end\", () => {\n // If main stream ends, substreams usually end too. But if they don't within a short grace period, force close.\n if (settled) {\n return;\n }\n\n // Give substreams a moment to flush\n setTimeout(() => {\n if (!settled) {\n stdoutEnded = true;\n stderrEnded = true;\n checkDone();\n }\n }, 100);\n });\n });\n }\n\n private postProcessOutput(output: string, _truncated: boolean): string {\n let result = output;\n\n // Mask secrets\n if (Object.keys(this.secrets).length > 0) {\n result = maskSecrets(result, this.secrets);\n }\n\n // Trim trailing whitespace\n return result.trimEnd();\n }\n\n /**\n * Remove all isol8 containers (both running and stopped).\n *\n * This static utility method finds and removes all containers created by isol8,\n * identified by images starting with `isol8:`.\n *\n * @param docker - Optional Docker instance. If not provided, creates a new one.\n * @returns Promise resolving to an object with counts of removed and failed containers.\n *\n * @example\n * ```typescript\n * import { DockerIsol8 } from \"isol8\";\n *\n * // Remove all isol8 containers\n * const result = await DockerIsol8.cleanup();\n * console.log(`Removed ${result.removed} containers`);\n * if (result.failed > 0) {\n * console.log(`Failed to remove ${result.failed} containers`);\n * }\n * ```\n */\n static async cleanup(\n docker?: Docker\n ): Promise<{ removed: number; failed: number; errors: string[] }> {\n const dockerInstance = docker ?? new Docker();\n\n // Find all isol8 containers\n const containers = await dockerInstance.listContainers({ all: true });\n const isol8Containers = containers.filter((c) => c.Image.startsWith(\"isol8:\"));\n\n let removed = 0;\n let failed = 0;\n const errors: string[] = [];\n\n for (const containerInfo of isol8Containers) {\n try {\n const container = dockerInstance.getContainer(containerInfo.Id);\n await container.remove({ force: true });\n removed++;\n } catch (err) {\n failed++;\n const errorMsg = err instanceof Error ? err.message : String(err);\n errors.push(`${containerInfo.Id.slice(0, 12)}: ${errorMsg}`);\n }\n }\n\n return { removed, failed, errors };\n }\n\n /**\n * Remove all isol8 Docker images.\n *\n * Images are identified by repo tags starting with `isol8:`\n * (for example `isol8:python` or `isol8:python-custom-<hash>`).\n */\n static async cleanupImages(\n docker?: Docker\n ): Promise<{ removed: number; failed: number; errors: string[] }> {\n const dockerInstance = docker ?? new Docker();\n\n const images = await dockerInstance.listImages({ all: true });\n const isol8Images = images.filter((img) =>\n img.RepoTags?.some((tag) => tag.startsWith(\"isol8:\"))\n );\n\n let removed = 0;\n let failed = 0;\n const errors: string[] = [];\n\n for (const imageInfo of isol8Images) {\n try {\n const image = dockerInstance.getImage(imageInfo.Id);\n await image.remove({ force: true });\n removed++;\n } catch (err) {\n failed++;\n const errorMsg = err instanceof Error ? err.message : String(err);\n const imageRef = imageInfo.RepoTags?.[0] ?? imageInfo.Id.slice(0, 12);\n errors.push(`${imageRef}: ${errorMsg}`);\n }\n }\n\n return { removed, failed, errors };\n }\n}\n",
19
+ "/**\n * Pluggable audit logger for execution provenance.\n *\n * Records ExecutionAudit objects to various destinations based on configuration.\n * Supports filesystem and stdout logging, with extensibility for cloud services.\n */\n\nimport { spawn } from \"node:child_process\";\nimport { appendFileSync, existsSync, mkdirSync, readdirSync, statSync, unlinkSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { AuditConfig, ExecutionAudit } from \"../types\";\nimport { logger } from \"../utils/logger\";\n\nexport class AuditLogger {\n private readonly config: AuditConfig;\n private readonly auditFile: string;\n\n constructor(config: AuditConfig) {\n this.config = config;\n\n // Set up audit file path based on config\n const auditDir =\n config.logDir ?? process.env.ISOL8_AUDIT_DIR ?? join(process.cwd(), \"./.isol8_audit\");\n this.auditFile = join(auditDir, \"executions.log\");\n\n // Create audit directory if it doesn't exist\n if (!existsSync(auditDir)) {\n try {\n mkdirSync(auditDir, { recursive: true });\n } catch (err) {\n logger.error(\"Failed to create audit dir:\", err);\n }\n }\n\n // Clean up old logs based on retention policy\n this.cleanupOldLogs();\n }\n\n /**\n * Clean up audit log files older than retentionDays.\n * Checks both the main executions.log and any rotated/archived logs.\n */\n private cleanupOldLogs(): void {\n if (!this.config.enabled || this.config.retentionDays <= 0) {\n return;\n }\n\n try {\n const auditDir = join(this.auditFile, \"..\");\n if (!existsSync(auditDir)) {\n return;\n }\n\n const cutoffTime = Date.now() - this.config.retentionDays * 24 * 60 * 60 * 1000;\n const files = readdirSync(auditDir);\n let cleanedCount = 0;\n\n for (const file of files) {\n // Clean up old log files (executions.log and any rotated versions)\n if (file.endsWith(\".log\") || file.endsWith(\".jsonl\")) {\n const filePath = join(auditDir, file);\n try {\n const stats = statSync(filePath);\n if (stats.mtimeMs < cutoffTime) {\n unlinkSync(filePath);\n cleanedCount++;\n logger.debug(`Cleaned up old audit log: ${file}`);\n }\n } catch (err) {\n logger.debug(`Failed to check/remove old log file ${file}:`, err);\n }\n }\n }\n\n if (cleanedCount > 0) {\n logger.info(`Audit log cleanup: removed ${cleanedCount} old log files`);\n }\n } catch (err) {\n logger.error(\"Failed to cleanup old audit logs:\", err);\n }\n }\n\n /**\n * Record an audit entry based on the current configuration.\n */\n record(audit: ExecutionAudit): void {\n if (!this.config.enabled) {\n return; // Don't record if audit is disabled\n }\n\n try {\n // Apply privacy filtering based on config\n const filteredAudit = this.filterAuditData(audit);\n\n const line = `${JSON.stringify(filteredAudit)}\\n`;\n\n switch (this.config.destination) {\n case \"file\":\n case \"filesystem\":\n appendFileSync(this.auditFile, line, { encoding: \"utf-8\" });\n break;\n case \"stdout\":\n console.log(\"AUDIT_LOG:\", filteredAudit);\n break;\n default:\n // For other destinations, log an error\n logger.error(`Unsupported audit destination: ${this.config.destination}`);\n return;\n }\n\n logger.debug(\"Audit record written:\", audit.executionId);\n\n // Run post-log script if configured\n if (this.config.postLogScript) {\n this.runPostLogScript();\n }\n } catch (err) {\n logger.error(\"Failed to write audit record:\", err);\n }\n }\n\n /**\n * Run the configured post-log script.\n * The script receives the audit file path as its first argument.\n */\n private runPostLogScript(): void {\n if (!this.config.postLogScript) {\n return;\n }\n\n try {\n // Spawn script with file path as argument, detached so it doesn't block\n const child = spawn(this.config.postLogScript, [this.auditFile], {\n detached: true,\n stdio: \"ignore\",\n });\n\n child.on(\"error\", (err) => {\n logger.error(\"Failed to run post-log script:\", err);\n });\n\n // Unref so parent can exit without waiting for child\n child.unref();\n } catch (err) {\n logger.error(\"Failed to spawn post-log script:\", err);\n }\n }\n\n /**\n * Apply privacy filtering to audit data based on configuration.\n */\n private filterAuditData(audit: ExecutionAudit): ExecutionAudit {\n // Start with required fields\n const result: ExecutionAudit = {\n executionId: audit.executionId,\n userId: audit.userId,\n timestamp: audit.timestamp,\n runtime: audit.runtime,\n codeHash: audit.codeHash,\n containerId: audit.containerId,\n exitCode: audit.exitCode,\n durationMs: audit.durationMs,\n };\n\n // Add optional fields if present\n if (audit.resourceUsage !== undefined) {\n result.resourceUsage = audit.resourceUsage;\n }\n if (audit.securityEvents !== undefined) {\n result.securityEvents = audit.securityEvents;\n }\n if (audit.metadata !== undefined) {\n result.metadata = audit.metadata;\n }\n\n // Conditionally add privacy-sensitive fields based on config\n if (this.config.includeCode && audit.code !== undefined) {\n (result as ExecutionAudit & { code?: string }).code = audit.code;\n }\n if (this.config.includeOutput) {\n if (audit.stdout !== undefined) {\n (result as ExecutionAudit & { stdout?: string }).stdout = audit.stdout;\n }\n if (audit.stderr !== undefined) {\n (result as ExecutionAudit & { stderr?: string }).stderr = audit.stderr;\n }\n }\n\n return result;\n }\n}\n",
20
+ "import { createHash } from \"node:crypto\";\nimport { lookup as dnsLookup } from \"node:dns/promises\";\nimport { isIP } from \"node:net\";\nimport type { RemoteCodePolicy } from \"../types\";\n\nexport interface FetchCodeRequest {\n codeUrl: string;\n codeHash?: string;\n allowInsecureCodeUrl?: boolean;\n}\n\nexport interface FetchCodeResult {\n code: string;\n url: string;\n hash: string;\n}\n\ninterface CodeFetcherDeps {\n fetchFn?: (input: string, init?: RequestInit) => Promise<Response>;\n lookupFn?: (hostname: string) => Promise<Array<{ address: string; family: number }>>;\n}\n\nconst IPV4_SEPARATOR = \".\";\nconst IPV6_LOOPBACK = \"::1\";\n\nfunction sha256Hex(input: string): string {\n return createHash(\"sha256\").update(input, \"utf-8\").digest(\"hex\");\n}\n\nfunction normalizeScheme(url: URL): string {\n return url.protocol.replace(/:$/, \"\").toLowerCase();\n}\n\nfunction isBlockedByPattern(host: string, patterns: string[]): boolean {\n return patterns.some((pattern) => new RegExp(pattern, \"i\").test(host));\n}\n\nfunction isAllowedByPattern(host: string, patterns: string[]): boolean {\n if (patterns.length === 0) {\n return true;\n }\n return patterns.some((pattern) => new RegExp(pattern, \"i\").test(host));\n}\n\nfunction isPrivateIpv4(ip: string): boolean {\n const parts = ip.split(IPV4_SEPARATOR).map((v) => Number.parseInt(v, 10));\n if (parts.length !== 4 || parts.some((p) => Number.isNaN(p))) {\n return false;\n }\n const a = parts[0]!;\n const b = parts[1]!;\n if (a === 10 || a === 127 || a === 0) {\n return true;\n }\n if (a === 169 && b === 254) {\n return true;\n }\n if (a === 172 && b >= 16 && b <= 31) {\n return true;\n }\n if (a === 192 && b === 168) {\n return true;\n }\n if (a === 100 && b >= 64 && b <= 127) {\n return true;\n }\n return false;\n}\n\nfunction isPrivateIpv6(ip: string): boolean {\n const normalized = ip.toLowerCase();\n if (normalized === IPV6_LOOPBACK) {\n return true;\n }\n return (\n normalized.startsWith(\"fc\") ||\n normalized.startsWith(\"fd\") ||\n normalized.startsWith(\"fe8\") ||\n normalized.startsWith(\"fe9\") ||\n normalized.startsWith(\"fea\") ||\n normalized.startsWith(\"feb\")\n );\n}\n\nfunction isPrivateIp(ip: string): boolean {\n const family = isIP(ip);\n if (family === 4) {\n return isPrivateIpv4(ip);\n }\n if (family === 6) {\n return isPrivateIpv6(ip);\n }\n return false;\n}\n\nasync function assertHostResolvesPublic(\n host: string,\n lookupFn: (hostname: string) => Promise<Array<{ address: string; family: number }>>\n): Promise<void> {\n if (isIP(host) && isPrivateIp(host)) {\n throw new Error(`Blocked code URL host: ${host}`);\n }\n\n try {\n const records = await lookupFn(host);\n for (const record of records) {\n if (isPrivateIp(record.address)) {\n throw new Error(`Blocked code URL host: ${host}`);\n }\n }\n } catch (err) {\n if (err instanceof Error && err.message.startsWith(\"Blocked code URL host:\")) {\n throw err;\n }\n throw new Error(`Failed to resolve code URL host: ${host}`);\n }\n}\n\nfunction decodeUtf8(content: Uint8Array): string {\n const decoder = new TextDecoder(\"utf-8\", { fatal: true });\n const text = decoder.decode(content);\n if (text.includes(\"\\u0000\")) {\n throw new Error(\"Fetched code appears to be binary content\");\n }\n return text;\n}\n\nexport async function fetchRemoteCode(\n request: FetchCodeRequest,\n policy: RemoteCodePolicy,\n deps: CodeFetcherDeps = {}\n): Promise<FetchCodeResult> {\n if (!policy.enabled) {\n throw new Error(\"Remote code fetching is disabled. Set remoteCode.enabled=true to allow it.\");\n }\n\n const fetchFn = deps.fetchFn ?? globalThis.fetch;\n const lookupFn =\n deps.lookupFn ??\n (async (hostname: string) => {\n const records = await dnsLookup(hostname, { all: true, verbatim: true });\n return records;\n });\n\n if (!request.codeUrl) {\n throw new Error(\"codeUrl is required for remote code fetching\");\n }\n\n const url = new URL(request.codeUrl);\n const scheme = normalizeScheme(url);\n\n if (scheme === \"http\" && !request.allowInsecureCodeUrl) {\n throw new Error(\"Insecure code URL blocked. Use allowInsecureCodeUrl=true to allow HTTP.\");\n }\n\n if (!policy.allowedSchemes.map((s) => s.toLowerCase()).includes(scheme)) {\n throw new Error(`URL scheme not allowed: ${scheme}`);\n }\n\n const host = url.hostname.toLowerCase();\n if (\n !isAllowedByPattern(host, policy.allowedHosts) ||\n isBlockedByPattern(host, policy.blockedHosts)\n ) {\n throw new Error(`Blocked code URL host: ${host}`);\n }\n\n await assertHostResolvesPublic(host, lookupFn);\n\n if (policy.requireHash && !request.codeHash) {\n throw new Error(\"Hash verification required: provide codeHash for remote code execution.\");\n }\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), policy.fetchTimeoutMs);\n\n let response: Response;\n try {\n response = await fetchFn(url.toString(), {\n method: \"GET\",\n redirect: \"follow\",\n signal: controller.signal,\n });\n } catch (err) {\n throw new Error(\n err instanceof Error && err.name === \"AbortError\"\n ? `Remote code fetch timed out after ${policy.fetchTimeoutMs}ms`\n : `Failed to fetch remote code: ${err instanceof Error ? err.message : String(err)}`\n );\n } finally {\n clearTimeout(timeout);\n }\n\n if (!response.ok) {\n throw new Error(`Failed to fetch remote code: HTTP ${response.status}`);\n }\n\n const contentLengthHeader = response.headers.get(\"content-length\");\n if (contentLengthHeader) {\n const parsedLength = Number.parseInt(contentLengthHeader, 10);\n if (!Number.isNaN(parsedLength) && parsedLength > policy.maxCodeSize) {\n throw new Error(\n `Remote code exceeds maxCodeSize (${policy.maxCodeSize} bytes): ${parsedLength} bytes`\n );\n }\n }\n\n if (!response.body) {\n throw new Error(\"Remote code response body is empty\");\n }\n\n const reader = response.body.getReader();\n const chunks: Uint8Array[] = [];\n let totalBytes = 0;\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n if (!value) {\n continue;\n }\n totalBytes += value.byteLength;\n if (totalBytes > policy.maxCodeSize) {\n throw new Error(`Remote code exceeds maxCodeSize (${policy.maxCodeSize} bytes)`);\n }\n chunks.push(value);\n }\n\n const buffer = new Uint8Array(totalBytes);\n let offset = 0;\n for (const chunk of chunks) {\n buffer.set(chunk, offset);\n offset += chunk.byteLength;\n }\n\n const code = decodeUtf8(buffer);\n const hash = sha256Hex(code);\n\n if (request.codeHash && hash.toLowerCase() !== request.codeHash.toLowerCase()) {\n throw new Error(\"Remote code hash mismatch\");\n }\n\n return { code, url: url.toString(), hash };\n}\n",
21
+ "/**\n * Embedded default seccomp profile.\n *\n * This keeps strict seccomp available in standalone compiled binaries where\n * docker/seccomp-profile.json may not be present on disk.\n */\nexport const EMBEDDED_DEFAULT_SECCOMP_PROFILE = JSON.stringify({\n defaultAction: \"SCMP_ACT_ALLOW\",\n architectures: [\"SCMP_ARCH_X86_64\", \"SCMP_ARCH_X86\", \"SCMP_ARCH_X32\", \"SCMP_ARCH_AARCH64\"],\n syscalls: [\n {\n names: [\n \"acct\",\n \"add_key\",\n \"bpf\",\n \"clock_adjtime\",\n \"clock_settime\",\n \"create_module\",\n \"delete_module\",\n \"finit_module\",\n \"get_mempolicy\",\n \"init_module\",\n \"ioperm\",\n \"iopl\",\n \"kcmp\",\n \"kexec_file_load\",\n \"kexec_load\",\n \"keyctl\",\n \"lookup_dcookie\",\n \"mbind\",\n \"mount\",\n \"move_pages\",\n \"name_to_handle_at\",\n \"open_by_handle_at\",\n \"perf_event_open\",\n \"pivot_root\",\n \"process_vm_readv\",\n \"process_vm_writev\",\n \"ptrace\",\n \"query_module\",\n \"quotactl\",\n \"reboot\",\n \"request_key\",\n \"set_mempolicy\",\n \"setns\",\n \"settimeofday\",\n \"stime\",\n \"swapon\",\n \"swapoff\",\n \"sysfs\",\n \"syslog\",\n \"umount\",\n \"umount2\",\n \"unshare\",\n \"uselib\",\n \"userfaultfd\",\n \"ustat\",\n \"vm86\",\n \"vm86old\",\n ],\n action: \"SCMP_ACT_ERRNO\",\n args: [],\n comment: \"\",\n includes: {},\n excludes: {},\n },\n ],\n});\n",
22
+ "/**\n * @module engine/pool\n *\n * Warm container pool for fast ephemeral execution. Pre-creates and\n * starts containers so they're ready for immediate use, eliminating\n * the create+start overhead (~100-200ms per execution).\n *\n * Supports two strategies:\n * - \"secure\": Clean container before returning (slower but ensures clean state)\n * - \"fast\": Dual-pool system - instant acquire from clean pool, background cleanup\n */\n\nimport type Docker from \"dockerode\";\nimport { logger } from \"../utils/logger\";\n\n/** Configuration for the container pool. */\nexport interface PoolOptions {\n /** Docker client instance. */\n docker: Docker;\n /** Pool strategy: \"secure\" or \"fast\". @default \"fast\" */\n poolStrategy?: \"secure\" | \"fast\";\n /** Pool size configuration.\n * For \"secure\" mode: number of containers to keep warm\n * For \"fast\" mode: { clean: ready containers, dirty: being cleaned }\n * @default 1 (for fast mode: { clean: 1, dirty: 1 })\n */\n poolSize?: number | { clean: number; dirty: number };\n /** Container creation options (HostConfig, Env, etc). */\n createOptions: Omit<Docker.ContainerCreateOptions, \"Image\">;\n /** Network mode to determine if iptables cleanup is needed. */\n networkMode: \"none\" | \"host\" | \"filtered\";\n /** Security mode - if strict, run process cleanup between executions */\n securityMode: \"strict\" | \"unconfined\" | \"custom\";\n}\n\ninterface PoolEntry {\n container: Docker.Container;\n createdAt: number;\n}\n\ninterface PoolState {\n clean: PoolEntry[];\n dirty: PoolEntry[];\n}\n\n/**\n * A per-image warm container pool. Maintains pre-started containers\n * ready for immediate exec, recycling them after use.\n *\n * Supports two strategies:\n * - \"secure\": Single pool, cleanup in acquire (current behavior)\n * - \"fast\": Dual pools (clean/dirty), instant acquire, background cleanup\n */\nexport class ContainerPool {\n private readonly docker: Docker;\n private readonly poolStrategy: \"secure\" | \"fast\";\n private readonly cleanPoolSize: number;\n private readonly dirtyPoolSize: number;\n private readonly createOptions: Omit<Docker.ContainerCreateOptions, \"Image\">;\n private readonly networkMode: \"none\" | \"host\" | \"filtered\";\n private readonly securityMode: \"strict\" | \"unconfined\" | \"custom\";\n private readonly pools = new Map<string, PoolState>();\n private readonly replenishing = new Set<string>();\n private readonly pendingReplenishments = new Set<Promise<void>>();\n private cleaningInterval: ReturnType<typeof setInterval> | null = null;\n\n constructor(options: PoolOptions) {\n this.docker = options.docker;\n this.poolStrategy = options.poolStrategy ?? \"fast\";\n this.createOptions = options.createOptions;\n this.networkMode = options.networkMode;\n this.securityMode = options.securityMode;\n\n // Parse pool size\n if (typeof options.poolSize === \"number\") {\n this.cleanPoolSize = options.poolSize;\n this.dirtyPoolSize = options.poolSize;\n } else if (options.poolSize) {\n this.cleanPoolSize = options.poolSize.clean ?? 1;\n this.dirtyPoolSize = options.poolSize.dirty ?? 1;\n } else {\n // Default: 1 clean, 1 dirty for fast mode\n this.cleanPoolSize = 1;\n this.dirtyPoolSize = 1;\n }\n\n // Start background cleaning for fast mode\n if (this.poolStrategy === \"fast\") {\n this.startBackgroundCleaning();\n }\n }\n\n /**\n * Acquire a started container for the given image.\n * - \"secure\" mode: Clean container before returning\n * - \"fast\" mode: Instant return from clean pool, create new if empty\n */\n async acquire(image: string): Promise<Docker.Container> {\n const pool = this.pools.get(image) ?? { clean: [], dirty: [] };\n\n if (this.poolStrategy === \"fast\") {\n // Fast mode: instant acquire from clean pool\n if (pool.clean.length > 0) {\n const entry = pool.clean.shift()!;\n this.pools.set(image, pool);\n\n // Fire-and-forget replenishment\n this.replenish(image);\n\n return entry.container;\n }\n\n // No clean containers available\n // Try to immediately clean one from dirty pool if available\n if (pool.dirty.length > 0 && pool.clean.length < this.cleanPoolSize) {\n await this.cleanDirtyImmediate(image);\n\n // Check again after cleanup\n const updatedPool = this.pools.get(image);\n if (updatedPool && updatedPool.clean.length > 0) {\n const entry = updatedPool.clean.shift()!;\n this.pools.set(image, updatedPool);\n this.replenish(image);\n return entry.container;\n }\n }\n\n // Create new container as fallback\n return this.createContainer(image);\n }\n // Secure mode: single pool, clean before returning\n if (pool.clean && pool.clean.length > 0) {\n const entry = pool.clean.shift()!;\n this.pools.set(image, { clean: pool.clean, dirty: [] });\n\n // Clean before returning - this ensures container is ready\n await this.cleanupContainer(entry.container);\n\n // Fire-and-forget replenishment\n this.replenish(image);\n return entry.container;\n }\n\n // Cold path: create + start inline\n return this.createContainer(image);\n }\n\n /**\n * Return a container to the pool.\n * - \"secure\" mode: Add to pool, cleanup happens on next acquire\n * - \"fast\" mode: Add to dirty pool for background cleaning\n */\n async release(container: Docker.Container, image: string): Promise<void> {\n let pool = this.pools.get(image);\n\n if (!pool) {\n pool = { clean: [], dirty: [] };\n this.pools.set(image, pool);\n }\n\n if (this.poolStrategy === \"fast\") {\n // Fast mode: add to dirty pool\n if (pool.dirty.length >= this.dirtyPoolSize) {\n // Dirty pool full, destroy container\n await container.remove({ force: true }).catch(() => {});\n return;\n }\n\n pool.dirty.push({ container, createdAt: Date.now() });\n } else {\n // Secure mode: add to clean pool\n if (pool.clean.length >= this.cleanPoolSize) {\n await container.remove({ force: true }).catch(() => {});\n return;\n }\n\n // For secure mode, we use single array\n if (!pool.clean) {\n pool.clean = [];\n }\n pool.clean.push({ container, createdAt: Date.now() });\n }\n }\n\n /**\n * Start background cleaning for fast mode.\n * Runs every 5 seconds to clean dirty containers.\n */\n private startBackgroundCleaning(): void {\n this.cleaningInterval = setInterval(async () => {\n for (const [_image, pool] of this.pools) {\n // Clean up to dirtyPoolSize containers per cycle\n for (let i = 0; i < this.dirtyPoolSize; i++) {\n if (pool.dirty.length > 0 && pool.clean.length < this.cleanPoolSize) {\n const entry = pool.dirty.shift()!;\n\n try {\n await this.cleanupContainer(entry.container);\n pool.clean.push(entry);\n } catch {\n entry.container.remove({ force: true }).catch(() => {});\n }\n }\n }\n }\n }, 5000); // Run every 5 seconds\n }\n\n /**\n * Clean a dirty container immediately and add to clean pool.\n */\n private async cleanDirtyImmediate(image: string): Promise<void> {\n const pool = this.pools.get(image);\n if (!pool || pool.dirty.length === 0 || pool.clean.length >= this.cleanPoolSize) {\n return;\n }\n\n const entry = pool.dirty.shift()!;\n try {\n await this.cleanupContainer(entry.container);\n pool.clean.push(entry);\n } catch {\n entry.container.remove({ force: true }).catch(() => {});\n }\n }\n\n private async cleanupContainer(container: Docker.Container): Promise<void> {\n const needsCleanup = this.securityMode === \"strict\";\n const needsIptables = this.networkMode === \"filtered\" && needsCleanup;\n\n if (!needsCleanup) {\n return;\n }\n\n try {\n const cleanupCmd = needsIptables\n ? \"pkill -9 -u sandbox 2>/dev/null; /usr/sbin/iptables -F OUTPUT 2>/dev/null; rm -rf /sandbox/* /sandbox/.[!.]* 2>/dev/null; true\"\n : \"pkill -9 -u sandbox 2>/dev/null; rm -rf /sandbox/* /sandbox/.[!.]* 2>/dev/null; true\";\n\n const cleanExec = await container.exec({\n Cmd: [\"sh\", \"-c\", cleanupCmd],\n });\n await cleanExec.start({ Detach: true });\n\n let info = await cleanExec.inspect();\n while (info.Running) {\n await new Promise((r) => setTimeout(r, 5));\n info = await cleanExec.inspect();\n }\n } catch {\n // Ignore cleanup errors\n }\n }\n\n /**\n * Pre-warm the pool for a specific image.\n */\n async warm(image: string): Promise<void> {\n const pool = this.pools.get(image) ?? { clean: [], dirty: [] };\n this.pools.set(image, pool);\n\n const needed =\n this.poolStrategy === \"fast\"\n ? this.cleanPoolSize - pool.clean.length\n : this.cleanPoolSize - (pool.clean?.length ?? 0);\n\n if (needed <= 0) {\n return;\n }\n\n const promises: Promise<void>[] = [];\n\n for (let i = 0; i < needed; i++) {\n promises.push(\n this.createContainer(image).then((container) => {\n if (this.poolStrategy === \"fast\") {\n pool.clean.push({ container, createdAt: Date.now() });\n } else {\n if (!pool.clean) {\n pool.clean = [];\n }\n pool.clean.push({ container, createdAt: Date.now() });\n }\n })\n );\n }\n\n await Promise.all(promises);\n }\n\n /**\n * Stop the pool and clean up resources.\n * Alias for drain() - destroys all containers and stops background cleaning.\n */\n async stop(): Promise<void> {\n return this.drain();\n }\n\n /**\n * Destroy all pooled containers and clear the pool.\n */\n async drain(): Promise<void> {\n // Stop background cleaning\n if (this.cleaningInterval) {\n clearInterval(this.cleaningInterval);\n this.cleaningInterval = null;\n }\n\n // Wait for pending operations\n await Promise.all(this.pendingReplenishments);\n\n const promises: Promise<void>[] = [];\n\n for (const [, pool] of this.pools) {\n for (const entry of pool.clean ?? []) {\n promises.push(entry.container.remove({ force: true }).catch(() => {}));\n }\n for (const entry of pool.dirty) {\n promises.push(entry.container.remove({ force: true }).catch(() => {}));\n }\n }\n\n await Promise.all(promises);\n this.pools.clear();\n }\n\n private async createContainer(image: string): Promise<Docker.Container> {\n const container = await this.docker.createContainer({\n ...this.createOptions,\n Image: image,\n });\n logger.debug(`[Pool] Container ${container.id} created for image: ${image}`);\n await container.start();\n logger.debug(`[Pool] Container ${container.id} started`);\n return container;\n }\n\n private replenish(image: string): void {\n if (this.replenishing.has(image)) {\n return;\n }\n\n const pool = this.pools.get(image);\n const currentSize = pool\n ? this.poolStrategy === \"fast\"\n ? pool.clean.length\n : (pool.clean?.length ?? 0)\n : 0;\n const targetSize = this.cleanPoolSize;\n\n if (currentSize >= targetSize) {\n return;\n }\n\n this.replenishing.add(image);\n\n const promise = this.createContainer(image)\n .then((container) => {\n const p = this.pools.get(image);\n if (!p) {\n container.remove({ force: true }).catch(() => {});\n return;\n }\n\n if (this.poolStrategy === \"fast\") {\n if (p.clean.length < this.cleanPoolSize) {\n p.clean.push({ container, createdAt: Date.now() });\n } else {\n container.remove({ force: true }).catch(() => {});\n }\n } else {\n if (!p.clean) {\n p.clean = [];\n }\n if (p.clean.length < this.cleanPoolSize) {\n p.clean.push({ container, createdAt: Date.now() });\n } else {\n container.remove({ force: true }).catch(() => {});\n }\n }\n })\n .catch((err) => {\n logger.error(`[Pool] Error during replenishment for ${image}:`, err);\n })\n .finally(() => {\n this.replenishing.delete(image);\n this.pendingReplenishments.delete(promise);\n });\n\n this.pendingReplenishments.add(promise);\n }\n}\n",
23
+ "/**\n * @module engine/stats\n *\n * Resource usage statistics collection from Docker containers.\n * Uses dockerode's container.stats() API to get CPU, memory, and network metrics.\n */\n\nimport type Docker from \"dockerode\";\n\n/**\n * Resource usage metrics for a container execution.\n */\nexport interface ContainerResourceUsage {\n /** CPU usage as percentage (0-100 * num_cores) */\n cpuPercent: number;\n /** Current memory usage in megabytes */\n memoryMB: number;\n /** Peak memory usage in megabytes (if tracked) */\n peakMemoryMB?: number;\n /** Bytes received during execution */\n networkBytesIn: number;\n /** Bytes sent during execution */\n networkBytesOut: number;\n}\n\n/**\n * Docker stats response structure.\n */\ninterface DockerStats {\n read: string;\n precpu_stats: {\n cpu_usage: {\n total_usage: number;\n percpu_usage?: number[];\n };\n system_cpu_usage: number;\n };\n cpu_stats: {\n cpu_usage: {\n total_usage: number;\n percpu_usage?: number[];\n };\n system_cpu_usage: number;\n online_cpus?: number;\n };\n memory_stats: {\n usage: number;\n max_usage?: number;\n limit: number;\n stats?: {\n cache?: number;\n rss?: number;\n };\n };\n networks?: Record<\n string,\n {\n rx_bytes: number;\n tx_bytes: number;\n rx_packets: number;\n tx_packets: number;\n }\n >;\n}\n\n/**\n * Calculate CPU percentage from docker stats.\n * Formula: (cpu_delta / system_delta) * num_cpus * 100\n */\nfunction calculateCPUPercent(stats: DockerStats): number {\n const cpuDelta = stats.cpu_stats.cpu_usage.total_usage - stats.precpu_stats.cpu_usage.total_usage;\n const systemDelta = stats.cpu_stats.system_cpu_usage - stats.precpu_stats.system_cpu_usage;\n\n if (systemDelta === 0 || cpuDelta === 0) {\n return 0;\n }\n\n const numCores =\n stats.cpu_stats.online_cpus ?? stats.cpu_stats.cpu_usage.percpu_usage?.length ?? 1;\n\n return (cpuDelta / systemDelta) * numCores * 100;\n}\n\n/**\n * Extract network stats (sum across all interfaces).\n */\nfunction calculateNetworkStats(stats: DockerStats): { in: number; out: number } {\n if (!stats.networks) {\n return { in: 0, out: 0 };\n }\n\n let rxBytes = 0;\n let txBytes = 0;\n\n for (const iface of Object.values(stats.networks)) {\n rxBytes += iface.rx_bytes;\n txBytes += iface.tx_bytes;\n }\n\n return { in: rxBytes, out: txBytes };\n}\n\n/**\n * Get resource usage snapshot for a container.\n *\n * @param container - Docker container instance\n * @returns Resource usage metrics\n */\nexport async function getContainerStats(\n container: Docker.Container\n): Promise<ContainerResourceUsage> {\n // Get single stats snapshot (stream: false)\n const stats = (await container.stats({\n stream: false,\n })) as unknown as DockerStats;\n\n const cpuPercent = calculateCPUPercent(stats);\n const memoryBytes = stats.memory_stats.usage;\n const network = calculateNetworkStats(stats);\n\n return {\n cpuPercent: Math.round(cpuPercent * 100) / 100, // Round to 2 decimals\n memoryMB: Math.round(memoryBytes / (1024 * 1024)),\n networkBytesIn: network.in,\n networkBytesOut: network.out,\n };\n}\n\n/**\n * Calculate resource usage delta between two stat snapshots.\n * Useful for getting per-execution metrics.\n */\nexport function calculateResourceDelta(\n before: ContainerResourceUsage,\n after: ContainerResourceUsage\n): ContainerResourceUsage {\n return {\n // CPU is already a rate, use the final value\n cpuPercent: after.cpuPercent,\n // Memory use final value\n memoryMB: after.memoryMB,\n // Network/Block I/O are cumulative, calculate delta\n networkBytesIn: after.networkBytesIn - before.networkBytesIn,\n networkBytesOut: after.networkBytesOut - before.networkBytesOut,\n };\n}\n",
24
+ "/**\n * @module @isol8/core\n *\n * Public API for the isol8 secure code execution engine.\n * Import from `\"@isol8/core\"` to access the engine, client, config, runtime registry.\n */\n\n// ─── Core Types ───\n\nexport type { RemoteIsol8Options } from \"./client/remote\";\n// ─── Client ───\nexport { RemoteIsol8 } from \"./client/remote\";\n// ─── Config ───\nexport { loadConfig } from \"./config\";\nexport { Semaphore } from \"./engine/concurrency\";\nexport type { DockerIsol8Options } from \"./engine/docker\";\n// ─── Engine ───\nexport { DockerIsol8 } from \"./engine/docker\";\nexport { buildBaseImages, buildCustomImages } from \"./engine/image-builder\";\n// ─── Runtime ───\nexport {\n BunAdapter,\n bashAdapter,\n DenoAdapter,\n NodeAdapter,\n PythonAdapter,\n RuntimeRegistry,\n} from \"./runtime\";\nexport type { RuntimeAdapter } from \"./runtime/adapter\";\n// ─── Types ───\nexport type {\n ExecutionRequest,\n ExecutionResult,\n Isol8Config,\n Isol8Engine,\n Isol8Mode,\n Isol8Options,\n NetworkFilterConfig,\n NetworkMode,\n RemoteCodePolicy,\n Runtime,\n StreamEvent,\n} from \"./types\";\n// ─── Utils ───\nexport { logger } from \"./utils/logger\";\n// ─── Version ───\nexport { VERSION } from \"./version\";\n",
25
+ "/**\n * @module version\n *\n * Exports the current version of isol8.\n */\n\nimport packageJson from \"../package.json\";\n\n/**\n * Current version of isol8.\n * @example\n * ```typescript\n * import { VERSION } from \"isol8\";\n * console.log(`Using isol8 v${VERSION}`);\n * ```\n */\nexport const VERSION = packageJson.version;\n"
26
+ ],
27
+ "mappings": "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",
28
+ "debugId": "22F12DAC58898F0F64756E2164756E21",
29
+ "names": []
30
+ }
@@ -0,0 +1,63 @@
1
+ /**
2
+ * @module runtime/adapter
3
+ *
4
+ * Defines the {@link RuntimeAdapter} interface and the global {@link RuntimeRegistry}
5
+ * for looking up runtime adapters by name or file extension.
6
+ */
7
+ import type { Runtime } from "../types";
8
+ /**
9
+ * A runtime adapter provides the container image and command construction
10
+ * for a specific language runtime (Python, Node, Bun, Deno).
11
+ *
12
+ * Adapters are registered in {@link RuntimeRegistry} and looked up by name
13
+ * or by file extension when the runtime is auto-detected.
14
+ */
15
+ export interface RuntimeAdapter {
16
+ /** Runtime identifier (e.g. `"python"`, `"node"`). */
17
+ readonly name: Runtime;
18
+ /** Docker image tag for this runtime (e.g. `"isol8:python"`). */
19
+ readonly image: string;
20
+ /**
21
+ * Build the shell command to execute code.
22
+ *
23
+ * @param code - The source code string. Used for inline execution.
24
+ * @param filePath - If provided, the code is read from this file inside the container.
25
+ * @returns Command array (e.g. `["python3", "-c", "print(1)"]`).
26
+ */
27
+ getCommand(code: string, filePath?: string): string[];
28
+ /** Default file extension for this runtime (e.g. `".py"`). */
29
+ getFileExtension(): string;
30
+ }
31
+ /**
32
+ * Central registry of all available runtime adapters.
33
+ *
34
+ * Built-in adapters (Python, Node, Bun, Deno) are registered automatically
35
+ * when `src/runtime/index.ts` is imported.
36
+ */
37
+ export declare const RuntimeRegistry: {
38
+ /**
39
+ * Register a runtime adapter. Overwrites any existing adapter with the same
40
+ * name or file extension.
41
+ *
42
+ * @param adapter - The adapter to register.
43
+ * @param aliases - Additional file extensions to map to this adapter (e.g. `[".mjs", ".cjs"]`).
44
+ */
45
+ register(adapter: RuntimeAdapter, aliases?: string[]): void;
46
+ /**
47
+ * Look up a runtime adapter by name.
48
+ *
49
+ * @param name - Runtime name (e.g. `"python"`).
50
+ * @throws {Error} If no adapter is registered with that name.
51
+ */
52
+ get(name: string): RuntimeAdapter;
53
+ /**
54
+ * Auto-detect the runtime from a filename's extension.
55
+ *
56
+ * @param filename - Filename or path (e.g. `"script.py"`, `"app.js"`).
57
+ * @throws {Error} If the extension doesn't match any registered adapter.
58
+ */
59
+ detect(filename: string): RuntimeAdapter;
60
+ /** Returns all registered runtime adapters. */
61
+ list(): RuntimeAdapter[];
62
+ };
63
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/runtime/adapter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAExC;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,sDAAsD;IACtD,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAEvB,iEAAiE;IACjE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB;;;;;;OAMG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAEtD,8DAA8D;IAC9D,gBAAgB,IAAI,MAAM,CAAC;CAC5B;AAMD;;;;;GAKG;AACH,eAAO,MAAM,eAAe;IAC1B;;;;;;OAMG;sBACe,cAAc,YAAW,MAAM,EAAE,GAAQ,IAAI;IAQ/D;;;;;OAKG;cACO,MAAM,GAAG,cAAc;IAQjC;;;;;OAKG;qBACc,MAAM,GAAG,cAAc;IAWxC,+CAA+C;YACvC,cAAc,EAAE;CAGzB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { RuntimeAdapter } from "../adapter";
2
+ export declare const bashAdapter: RuntimeAdapter;
3
+ //# sourceMappingURL=bash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../../src/runtime/adapters/bash.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,eAAO,MAAM,WAAW,EAAE,cAYzB,CAAC"}
@@ -0,0 +1,4 @@
1
+ /** Bun runtime adapter — uses `bun` from the `isol8:bun` image. Maps to `.ts` extension. */
2
+ import type { RuntimeAdapter } from "../adapter";
3
+ export declare const BunAdapter: RuntimeAdapter;
4
+ //# sourceMappingURL=bun.d.ts.map