@mastra/docker 0.1.0-alpha.0 → 0.2.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/sandbox/process-manager.ts","../src/sandbox/index.ts","../src/provider.ts"],"names":["ProcessHandle","SandboxProcessManager","MastraSandbox","Docker","SandboxNotReadyError","error","SandboxError"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Docker Process Manager\n *\n * Implements SandboxProcessManager for Docker containers.\n * Uses `container.exec()` to run commands inside a long-lived container.\n * Each spawned process gets a dedicated exec instance with separate\n * stdout/stderr streams.\n */\n\nimport { ProcessHandle, SandboxProcessManager } from '@mastra/core/workspace';\nimport type { CommandResult, ProcessInfo, SpawnProcessOptions } from '@mastra/core/workspace';\nimport type { Container, Exec, ExecInspectInfo } from 'dockerode';\n\n// =============================================================================\n// Docker Process Handle\n// =============================================================================\n\n/**\n * Wraps a Docker exec instance to conform to Mastra's ProcessHandle.\n * Not exported — internal to this module.\n *\n * Listener dispatch is handled by the base class. The manager's spawn()\n * method wires Docker stream callbacks to handle.emitStdout/emitStderr.\n */\nclass DockerProcessHandle extends ProcessHandle {\n readonly pid: string;\n\n private readonly _exec: Exec;\n private readonly _container: Container;\n private readonly _startTime: number;\n private _exitCode: number | undefined;\n /** @internal Set by kill() and timeout to distinguish forced termination from natural exit */\n _killed = false;\n private _waitPromise: Promise<CommandResult> | null = null;\n private _stdinStream: NodeJS.WritableStream | null = null;\n private _execStream: NodeJS.ReadWriteStream | null = null;\n\n constructor(\n exec: Exec,\n container: Container,\n startTime: number,\n stdinStream: NodeJS.WritableStream | null,\n options?: SpawnProcessOptions,\n ) {\n super(options);\n this.pid = exec.id;\n this._exec = exec;\n this._container = container;\n this._startTime = startTime;\n this._stdinStream = stdinStream;\n }\n\n get exitCode(): number | undefined {\n return this._exitCode;\n }\n\n /** @internal Set exit code when stream closes */\n _setExitCode(code: number): void {\n this._exitCode = code;\n }\n\n /** @internal Set the wait promise from spawn */\n _setWaitPromise(p: Promise<CommandResult>): void {\n this._waitPromise = p;\n }\n\n /** @internal Set the exec stream so kill() can destroy it */\n _setExecStream(stream: NodeJS.ReadWriteStream): void {\n this._execStream = stream;\n }\n\n async wait(): Promise<CommandResult> {\n if (this._waitPromise) {\n return this._waitPromise;\n }\n\n // If no wait promise set yet, poll exec inspect\n const info = await this._inspectExec();\n return {\n success: (info.ExitCode ?? 1) === 0,\n exitCode: info.ExitCode ?? 1,\n stdout: this.stdout,\n stderr: this.stderr,\n executionTimeMs: Date.now() - this._startTime,\n };\n }\n\n async kill(): Promise<boolean> {\n if (this._exitCode !== undefined) return false;\n\n try {\n // Get the PID inside the container from exec inspect.\n // Single retry with 50ms delay — Docker may not have assigned a PID yet\n // if kill() is called immediately after spawn(). A polling loop with\n // backoff would be more robust under heavy load, but overkill in practice.\n let info = await this._inspectExec();\n if (!info.Running || !info.Pid) {\n await new Promise(r => setTimeout(r, 50));\n info = await this._inspectExec();\n }\n\n if (!info.Running) {\n this._killed = true;\n this._destroyStream();\n return false;\n }\n\n const pid = info.Pid;\n if (!pid) {\n this._killed = true;\n this._destroyStream();\n return false;\n }\n\n // Kill the process group (negative PID), fall back to direct PID\n const killExec = await this._container.exec({\n Cmd: ['sh', '-c', `kill -9 -${pid} 2>/dev/null || kill -9 ${pid}`],\n AttachStdout: false,\n AttachStderr: false,\n });\n await killExec.start({});\n\n // Mark as killed and destroy stream so wait() resolves.\n // Docker exec streams don't close automatically when the process is killed externally.\n this._killed = true;\n this._destroyStream();\n return true;\n } catch (error: unknown) {\n this._killed = true;\n this._destroyStream();\n // ESRCH / \"no such process\" is expected if the process exited between inspect and kill\n const msg = error instanceof Error ? error.message.toLowerCase() : '';\n if (!msg.includes('no such process') && !msg.includes('esrch')) {\n // Unexpected error — not fatal but worth noting for debugging\n console.warn(`[DockerProcessManager] kill(${this.pid}) failed unexpectedly:`, error);\n }\n return false;\n }\n }\n\n async sendStdin(data: string): Promise<void> {\n if (this._exitCode !== undefined) {\n throw new Error(`Process ${this.pid} has already exited with code ${this._exitCode}`);\n }\n if (!this._stdinStream) {\n throw new Error(`Process ${this.pid} was not started with stdin support`);\n }\n this._stdinStream.write(data);\n }\n\n /** @internal Force-close the exec stream to unblock wait(). */\n _destroyStream(): void {\n const stream = this._execStream as unknown as { destroy?: () => void } | null;\n if (stream && typeof stream.destroy === 'function') {\n stream.destroy();\n this._execStream = null;\n }\n }\n\n private async _inspectExec(): Promise<ExecInspectInfo> {\n return this._exec.inspect();\n }\n}\n\n// =============================================================================\n// Docker Process Manager\n// =============================================================================\n\n/**\n * Docker implementation of SandboxProcessManager.\n * Uses `container.exec()` with stream-based I/O.\n */\nexport class DockerProcessManager extends SandboxProcessManager {\n private _container: Container | null = null;\n private readonly _defaultTimeout: number;\n\n constructor(options: { env: Record<string, string>; defaultTimeout?: number }) {\n super(options);\n this._defaultTimeout = options.defaultTimeout ?? 0;\n }\n\n /** @internal Called by DockerSandbox after container is ready */\n setContainer(container: Container): void {\n this._container = container;\n }\n\n /** Get the container, throwing if not set */\n private get container(): Container {\n if (!this._container) {\n throw new Error('Docker container not available. Has the sandbox been started?');\n }\n return this._container;\n }\n\n async spawn(command: string, options: SpawnProcessOptions = {}): Promise<ProcessHandle> {\n const container = this.container;\n\n // Merge default env with per-spawn env\n const mergedEnv = { ...this.env, ...options.env };\n const envArray = Object.entries(mergedEnv)\n .filter((entry): entry is [string, string] => entry[1] !== undefined)\n .map(([k, v]) => `${k}=${v}`);\n\n // Create exec instance\n const exec = await container.exec({\n Cmd: ['sh', '-c', command],\n AttachStdout: true,\n AttachStderr: true,\n AttachStdin: true,\n Tty: false,\n Env: envArray.length > 0 ? envArray : undefined,\n WorkingDir: options.cwd,\n });\n\n // Start exec and get the multiplexed stream\n const stream = await exec.start({ hijack: true, stdin: true });\n\n const startTime = Date.now();\n const handle = new DockerProcessHandle(exec, container, startTime, stream, options);\n handle._setExecStream(stream);\n\n // Create the wait promise that resolves when the stream ends\n const waitPromise = new Promise<CommandResult>(resolve => {\n // Demux the multiplexed stream into stdout/stderr\n // Docker multiplexes stdout/stderr into a single stream with 8-byte headers\n // when Tty is false. We need to parse these headers.\n const buffer: Buffer[] = [];\n\n stream.on('data', (chunk: Buffer) => {\n buffer.push(chunk);\n // Process all complete frames in the buffer\n let combined = Buffer.concat(buffer);\n buffer.length = 0;\n\n while (combined.length >= 8) {\n const type = combined[0]; // 1 = stdout, 2 = stderr\n const size = combined.readUInt32BE(4);\n\n if (combined.length < 8 + size) {\n // Incomplete frame, save for next chunk\n buffer.push(combined);\n break;\n }\n\n const payload = combined.subarray(8, 8 + size).toString('utf-8');\n if (type === 1) {\n handle.emitStdout(payload);\n } else if (type === 2) {\n handle.emitStderr(payload);\n }\n\n combined = combined.subarray(8 + size);\n }\n\n // Save any remaining partial data\n if (combined.length > 0 && buffer.length === 0) {\n buffer.push(combined);\n }\n });\n\n stream.on('end', async () => {\n // Get exit code from exec inspect\n try {\n const info = await exec.inspect();\n const exitCode = info.ExitCode ?? 1;\n handle._setExitCode(exitCode);\n resolve({\n success: exitCode === 0,\n exitCode,\n stdout: handle.stdout,\n stderr: handle.stderr,\n executionTimeMs: Date.now() - startTime,\n });\n } catch {\n handle._setExitCode(1);\n resolve({\n success: false,\n exitCode: 1,\n stdout: handle.stdout,\n stderr: handle.stderr,\n executionTimeMs: Date.now() - startTime,\n });\n }\n });\n\n // 'close' fires when stream.destroy() is called (e.g., from kill or timeout).\n // Only resolve with SIGKILL exit code when the process was explicitly killed;\n // natural stream close should be handled by the 'end' event above.\n // Note: Docker multiplexed streams always emit 'end' before 'close' for\n // natural exits, so the !_killed guard won't silently drop natural closes.\n stream.on('close', () => {\n if (handle.exitCode !== undefined) return; // Already resolved via 'end'\n if (!handle._killed) return; // Natural close — 'end' handles it\n handle._setExitCode(137); // SIGKILL\n resolve({\n success: false,\n exitCode: 137,\n stdout: handle.stdout,\n stderr: handle.stderr,\n executionTimeMs: Date.now() - startTime,\n });\n });\n\n stream.on('error', () => {\n if (handle.exitCode !== undefined) return; // Already resolved\n handle._setExitCode(1);\n resolve({\n success: false,\n exitCode: 1,\n stdout: handle.stdout,\n stderr: handle.stderr || 'Stream error',\n executionTimeMs: Date.now() - startTime,\n });\n });\n });\n\n // Wire up timeout: kill the process and destroy the stream after the timeout period.\n // Per-spawn timeout takes precedence; falls back to the sandbox-level default.\n const resolvedTimeout = options.timeout ?? this._defaultTimeout;\n if (resolvedTimeout > 0) {\n const timeoutMs = resolvedTimeout;\n const timer = setTimeout(() => {\n if (handle.exitCode === undefined) {\n handle._killed = true;\n handle.kill().catch(() => {});\n // Ensure stream is destroyed even if kill() fails (e.g., PID not found)\n handle._destroyStream();\n }\n }, timeoutMs);\n // Clear timer when process exits naturally\n void waitPromise.then(() => clearTimeout(timer));\n }\n\n handle._setWaitPromise(waitPromise);\n this._tracked.set(handle.pid, handle);\n return handle;\n }\n\n /** Clear all tracked process handles and release the container reference (e.g., after container stop/destroy) */\n reset(): void {\n this._tracked.clear();\n this._container = null;\n }\n\n async list(): Promise<ProcessInfo[]> {\n const results: ProcessInfo[] = [];\n\n for (const [pid, handle] of this._tracked) {\n results.push({\n pid,\n command: handle.command,\n running: handle.exitCode === undefined,\n exitCode: handle.exitCode,\n });\n }\n\n return results;\n }\n}\n","/**\n * Docker Sandbox Provider\n *\n * A Docker-based sandbox implementation that uses long-lived containers\n * with `docker exec` for command execution. Targets local development,\n * CI/CD, air-gapped deployments, and cost-sensitive scenarios where\n * cloud sandboxes are overkill.\n *\n * @see https://docs.docker.com/engine/api/\n */\n\nimport type { RequestContext } from '@mastra/core/di';\nimport type { SandboxInfo, ProviderStatus, MastraSandboxOptions } from '@mastra/core/workspace';\nimport { MastraSandbox, SandboxError, SandboxNotReadyError } from '@mastra/core/workspace';\nimport Docker from 'dockerode';\nimport type { Container, ContainerInfo } from 'dockerode';\nimport { DockerProcessManager } from './process-manager';\n\nconst LOG_PREFIX = '[DockerSandbox]';\n\n/**\n * Inlined from `@mastra/core/workspace` to avoid requiring a newer core peer dep.\n * Canonical type: packages/core/src/workspace/sandbox/mastra-sandbox.ts\n * TODO: Remove once minimum peer dep includes InstructionsOption export.\n */\ntype InstructionsOption = string | ((opts: { defaultInstructions: string; requestContext?: RequestContext }) => string);\n\n// =============================================================================\n// Docker Sandbox Options\n// =============================================================================\n\nexport interface DockerSandboxOptions extends Omit<MastraSandboxOptions, 'processes'> {\n /** Unique identifier for this sandbox instance. Used for container naming and reconnection. */\n id?: string;\n /** Docker image to use.\n * @default 'node:22-slim'\n */\n image?: string;\n /** Container entrypoint command. Must keep the container alive.\n * @default ['sleep', 'infinity']\n */\n command?: string[];\n /** Environment variables to set in the container */\n env?: Record<string, string>;\n /** Host-to-container bind mounts (e.g., `{ '/host/path': '/container/path' }`) */\n volumes?: Record<string, string>;\n /** Docker network to join */\n network?: string;\n /** Run in privileged mode\n * @default false\n */\n privileged?: boolean;\n /** Default command timeout in milliseconds\n * @default 300_000 // 5 minutes\n */\n timeout?: number;\n /** Working directory inside the container\n * @default '/workspace'\n */\n workingDir?: string;\n /** Container labels for filtering and identification */\n labels?: Record<string, string>;\n /** Pass-through dockerode connection options (socket path, host, TLS certs) */\n dockerOptions?: Docker.DockerOptions;\n /**\n * Custom instructions that override the default instructions\n * returned by `getInstructions()`.\n *\n * - `string` — Fully replaces the default instructions.\n * Pass an empty string to suppress instructions entirely.\n * - `(opts) => string` — Receives the default instructions and\n * optional request context so you can extend or customise per-request.\n */\n instructions?: InstructionsOption;\n}\n\n// =============================================================================\n// Docker Sandbox Implementation\n// =============================================================================\n\n/**\n * Docker sandbox implementation using long-lived containers.\n *\n * Features:\n * - Long-lived container with `docker exec` for commands\n * - Bind mount support via Docker volumes\n * - Reconnection to existing containers by ID/name\n * - Container label tracking for discovery\n *\n * @example Basic usage\n * ```typescript\n * import { Workspace } from '@mastra/core/workspace';\n * import { DockerSandbox } from '@mastra/docker';\n *\n * const sandbox = new DockerSandbox({\n * image: 'node:22-slim',\n * timeout: 60000,\n * });\n *\n * const workspace = new Workspace({ sandbox });\n * const result = await workspace.executeCode('console.log(\"Hello!\")');\n * ```\n *\n * @example With bind mounts\n * ```typescript\n * const sandbox = new DockerSandbox({\n * image: 'node:22-slim',\n * volumes: { '/my/project': '/workspace/project' },\n * });\n * ```\n */\nexport class DockerSandbox extends MastraSandbox {\n readonly id: string;\n readonly name = 'DockerSandbox';\n readonly provider = 'docker';\n status: ProviderStatus = 'pending';\n\n declare readonly processes: DockerProcessManager;\n\n /** Underlying Docker client */\n private readonly _docker: Docker;\n\n /** Container reference (set after start) */\n private _container: Container | null = null;\n\n /** Configuration */\n private readonly _image: string;\n private readonly _command: string[];\n private readonly _env: Record<string, string>;\n private readonly _volumes: Record<string, string>;\n private readonly _network?: string;\n private readonly _privileged: boolean;\n private readonly _workingDir: string;\n private readonly _labels: Record<string, string>;\n private readonly _instructionsOverride?: InstructionsOption;\n\n constructor(options: DockerSandboxOptions = {}) {\n const processManager = new DockerProcessManager({\n env: options.env ?? {},\n defaultTimeout: options.timeout ?? 300_000,\n });\n\n super({\n ...options,\n name: 'DockerSandbox',\n processes: processManager,\n });\n\n this.id = options.id ?? this._generateId();\n this._image = options.image ?? 'node:22-slim';\n this._command = options.command ?? ['sleep', 'infinity'];\n this._env = options.env ?? {};\n this._volumes = options.volumes ?? {};\n this._network = options.network;\n this._privileged = options.privileged ?? false;\n this._workingDir = options.workingDir ?? '/workspace';\n this._labels = {\n ...options.labels,\n 'mastra.sandbox': 'true',\n 'mastra.sandbox.id': this.id,\n };\n this._instructionsOverride = options.instructions;\n this._docker = new Docker(options.dockerOptions);\n }\n\n /**\n * Get the underlying Docker container for direct access.\n * @throws {SandboxNotReadyError} If the sandbox has not been started.\n */\n get container(): Container {\n if (!this._container) {\n throw new SandboxNotReadyError(this.id);\n }\n return this._container;\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------------------\n\n async start(): Promise<void> {\n this.logger.debug(`${LOG_PREFIX} Starting sandbox ${this.id}...`);\n\n // Try to reconnect to existing container\n const existing = await this._findExistingContainer();\n if (existing) {\n this.logger.debug(`${LOG_PREFIX} Found existing container ${existing.Id}`);\n this._container = this._docker.getContainer(existing.Id);\n\n // Use inspect() to get authoritative container state — listContainers() state\n // can be stale immediately after stop() returns but before container fully exits\n const info = await this._container.inspect();\n const actualState = info.State?.Running ? 'running' : 'stopped';\n\n if (actualState !== 'running') {\n this.logger.debug(`${LOG_PREFIX} Container exists but not running (${actualState}), starting...`);\n await this._container.start();\n }\n\n // Provide container reference to process manager\n this.processes.setContainer(this._container);\n\n this.logger.debug(`${LOG_PREFIX} Reconnected to container ${existing.Id}`);\n return;\n }\n\n // Pull image if not available locally\n await this._ensureImage();\n\n // Build environment array for Docker API\n const envArray = Object.entries(this._env).map(([k, v]) => `${k}=${v}`);\n\n // Build bind mount array\n const binds = Object.entries(this._volumes).map(([host, container]) => `${host}:${container}`);\n\n // Create container\n this.logger.debug(`${LOG_PREFIX} Creating container with image ${this._image}...`);\n this._container = await this._docker.createContainer({\n Image: this._image,\n Cmd: this._command,\n Env: envArray,\n WorkingDir: this._workingDir,\n Labels: this._labels,\n HostConfig: {\n Binds: binds.length > 0 ? binds : undefined,\n NetworkMode: this._network,\n Privileged: this._privileged,\n },\n // Keep stdin open for interactive use\n OpenStdin: true,\n Tty: false,\n });\n\n // Start container\n await this._container.start();\n\n // Provide container reference to process manager\n this.processes.setContainer(this._container);\n\n this.logger.debug(`${LOG_PREFIX} Container started: ${this._container.id}`);\n }\n\n async stop(): Promise<void> {\n const container = await this._resolveContainer();\n if (!container) return;\n\n this.logger.debug(`${LOG_PREFIX} Stopping container ${container.id}...`);\n try {\n await container.stop({ t: 10 });\n } catch (error: unknown) {\n // Container may already be stopped\n if (!isContainerNotRunningError(error)) {\n throw error;\n }\n }\n this.processes.reset();\n this.logger.debug(`${LOG_PREFIX} Container stopped`);\n }\n\n async destroy(): Promise<void> {\n const container = await this._resolveContainer();\n if (!container) return;\n\n this.logger.debug(`${LOG_PREFIX} Destroying container ${container.id}...`);\n try {\n await container.remove({ force: true, v: true });\n } catch (error: unknown) {\n // Container may already be removed\n if (!isContainerNotFoundError(error)) {\n throw error;\n }\n }\n this.processes.reset();\n this._container = null;\n this.logger.debug(`${LOG_PREFIX} Container destroyed`);\n }\n\n // ---------------------------------------------------------------------------\n // Instructions\n // ---------------------------------------------------------------------------\n\n getInstructions(opts?: { requestContext?: RequestContext }): string {\n const defaultInstructions = [\n `You are working inside a Docker container (image: ${this._image}).`,\n `The working directory is ${this._workingDir}.`,\n 'You can execute shell commands using executeCommand().',\n 'You can spawn background processes using processes.spawn().',\n ].join('\\n');\n\n if (this._instructionsOverride === undefined) return defaultInstructions;\n if (typeof this._instructionsOverride === 'string') return this._instructionsOverride;\n return this._instructionsOverride({ defaultInstructions, requestContext: opts?.requestContext });\n }\n\n // ---------------------------------------------------------------------------\n // Info\n // ---------------------------------------------------------------------------\n\n async getInfo(): Promise<SandboxInfo> {\n const info: SandboxInfo = {\n id: this.id,\n name: this.name,\n provider: this.provider,\n status: this.status,\n createdAt: new Date(),\n metadata: {\n image: this._image,\n workingDir: this._workingDir,\n labels: this._labels,\n },\n };\n\n if (this._container) {\n try {\n const inspect = await this._container.inspect();\n info.createdAt = new Date(inspect.Created);\n info.metadata = {\n ...info.metadata,\n containerId: inspect.Id,\n containerName: inspect.Name,\n state: inspect.State.Status,\n };\n } catch {\n // Container may have been removed\n }\n }\n\n return info;\n }\n\n // ---------------------------------------------------------------------------\n // Private helpers\n // ---------------------------------------------------------------------------\n\n private _generateId(): string {\n return `docker-sandbox-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;\n }\n\n /**\n * Resolve the container reference, looking up by label if `_container` is unset.\n * This ensures `stop()` and `destroy()` work even when the instance was created\n * with an existing container's ID but `start()` was never called.\n */\n private async _resolveContainer(): Promise<Container | null> {\n if (this._container) return this._container;\n const existing = await this._findExistingContainer();\n if (!existing) return null;\n this._container = this._docker.getContainer(existing.Id);\n return this._container;\n }\n\n /**\n * Find an existing container matching this sandbox's ID via labels.\n */\n private async _findExistingContainer(): Promise<ContainerInfo | null> {\n try {\n const containers = await this._docker.listContainers({\n all: true,\n filters: {\n label: [`mastra.sandbox.id=${this.id}`],\n },\n });\n return containers[0] ?? null;\n } catch (error) {\n // Log and re-throw infrastructure errors (daemon unreachable, auth, etc.)\n this.logger.debug(\n `${LOG_PREFIX} Failed to list containers: ${error instanceof Error ? error.message : String(error)}`,\n );\n throw error;\n }\n }\n\n /**\n * Ensure the Docker image is available locally. Pulls if needed.\n */\n private async _ensureImage(): Promise<void> {\n try {\n await this._docker.getImage(this._image).inspect();\n this.logger.debug(`${LOG_PREFIX} Image ${this._image} available locally`);\n } catch (error) {\n // Only attempt pull if the image doesn't exist (404).\n // Re-throw infrastructure errors (daemon unreachable, auth, etc.)\n if (!isImageNotFoundError(error)) {\n throw error;\n }\n\n this.logger.debug(`${LOG_PREFIX} Pulling image ${this._image}...`);\n try {\n const stream = await this._docker.pull(this._image);\n await new Promise<void>((resolve, reject) => {\n this._docker.modem.followProgress(stream, (err: Error | null) => {\n if (err) reject(err);\n else resolve();\n });\n });\n this.logger.debug(`${LOG_PREFIX} Image ${this._image} pulled successfully`);\n } catch (error) {\n throw new SandboxError(\n `Failed to pull Docker image '${this._image}': ${error instanceof Error ? error.message : String(error)}`,\n 'NOT_READY',\n { image: this._image, reason: 'image_pull_failed' },\n );\n }\n }\n }\n}\n\n// =============================================================================\n// Error detection helpers\n// =============================================================================\n\nfunction isContainerNotRunningError(error: unknown): boolean {\n if (error instanceof Error) {\n return error.message.includes('is not running') || error.message.includes('container already stopped');\n }\n return false;\n}\n\nfunction isContainerNotFoundError(error: unknown): boolean {\n if (error instanceof Error) {\n const msg = error.message.toLowerCase();\n return msg.includes('no such container') || (msg.includes('removal') && msg.includes('is already in progress'));\n }\n return false;\n}\n\nfunction isImageNotFoundError(error: unknown): boolean {\n if (error instanceof Error) {\n return error.message.toLowerCase().includes('no such image');\n }\n return false;\n}\n","/**\n * Docker Sandbox Provider Descriptor\n *\n * Enables registration with MastraEditor for UI-driven sandbox configuration.\n */\n\nimport type { SandboxProvider } from '@mastra/core/editor';\nimport { DockerSandbox } from './sandbox';\nimport type { DockerSandboxOptions } from './sandbox';\n\n/**\n * Serializable config for the Docker sandbox provider.\n * This is the subset of DockerSandboxOptions that can be stored in a config file\n * and rendered in a UI form.\n */\nexport interface DockerProviderConfig {\n /** Docker image to use */\n image?: string;\n /** Default command timeout in milliseconds */\n timeout?: number;\n /** Environment variables */\n env?: Record<string, string>;\n /** Host-to-container bind mounts */\n volumes?: Record<string, string>;\n /** Docker network to join */\n network?: string;\n /** Working directory inside the container */\n workingDir?: string;\n /** Run in privileged mode */\n privileged?: boolean;\n}\n\nexport const dockerSandboxProvider: SandboxProvider<DockerProviderConfig> = {\n id: 'docker',\n name: 'Docker Sandbox',\n description: 'Local container sandbox powered by Docker',\n configSchema: {\n type: 'object',\n properties: {\n image: {\n type: 'string',\n description: 'Docker image to use',\n default: 'node:22-slim',\n },\n timeout: {\n type: 'number',\n description: 'Default command timeout in milliseconds',\n default: 300_000,\n },\n env: {\n type: 'object',\n description: 'Environment variables',\n additionalProperties: { type: 'string' },\n },\n volumes: {\n type: 'object',\n description: 'Host-to-container bind mounts (host path → container path)',\n additionalProperties: { type: 'string' },\n },\n network: {\n type: 'string',\n description: 'Docker network to join',\n },\n workingDir: {\n type: 'string',\n description: 'Working directory inside the container',\n default: '/workspace',\n },\n privileged: {\n type: 'boolean',\n description: 'Run in privileged mode',\n default: false,\n },\n },\n },\n createSandbox: (config: DockerProviderConfig) => new DockerSandbox(config as DockerSandboxOptions),\n};\n"]}
1
+ {"version":3,"sources":["../src/sandbox/process-manager.ts","../src/sandbox/index.ts","../src/provider.ts"],"names":["ProcessHandle","SandboxProcessManager","MastraSandbox","Docker","SandboxNotReadyError","error","SandboxError","isDeepStrictEqual"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Docker Process Manager\n *\n * Implements SandboxProcessManager for Docker containers.\n * Uses `container.exec()` to run commands inside a long-lived container.\n * Each spawned process gets a dedicated exec instance with separate\n * stdout/stderr streams.\n */\n\nimport { ProcessHandle, SandboxProcessManager } from '@mastra/core/workspace';\nimport type { CommandResult, ProcessInfo, SpawnProcessOptions } from '@mastra/core/workspace';\nimport type { Container, Exec, ExecInspectInfo } from 'dockerode';\n\n// =============================================================================\n// Docker Process Handle\n// =============================================================================\n\n/**\n * Wraps a Docker exec instance to conform to Mastra's ProcessHandle.\n * Not exported — internal to this module.\n *\n * Listener dispatch is handled by the base class. The manager's spawn()\n * method wires Docker stream callbacks to handle.emitStdout/emitStderr.\n */\nclass DockerProcessHandle extends ProcessHandle {\n readonly pid: string;\n\n private readonly _exec: Exec;\n private readonly _container: Container;\n private readonly _startTime: number;\n private _exitCode: number | undefined;\n /** @internal Set by kill() and timeout to distinguish forced termination from natural exit */\n _killed = false;\n private _waitPromise: Promise<CommandResult> | null = null;\n private _stdinStream: NodeJS.WritableStream | null = null;\n private _execStream: NodeJS.ReadWriteStream | null = null;\n\n constructor(\n exec: Exec,\n container: Container,\n startTime: number,\n stdinStream: NodeJS.WritableStream | null,\n options?: SpawnProcessOptions,\n ) {\n super(options);\n this.pid = exec.id;\n this._exec = exec;\n this._container = container;\n this._startTime = startTime;\n this._stdinStream = stdinStream;\n }\n\n get exitCode(): number | undefined {\n return this._exitCode;\n }\n\n /** @internal Set exit code when stream closes */\n _setExitCode(code: number): void {\n this._exitCode = code;\n }\n\n /** @internal Set the wait promise from spawn */\n _setWaitPromise(p: Promise<CommandResult>): void {\n this._waitPromise = p;\n }\n\n /** @internal Set the exec stream so kill() can destroy it */\n _setExecStream(stream: NodeJS.ReadWriteStream): void {\n this._execStream = stream;\n }\n\n async wait(): Promise<CommandResult> {\n if (this._waitPromise) {\n return this._waitPromise;\n }\n\n // If no wait promise set yet, poll exec inspect\n const info = await this._inspectExec();\n return {\n success: (info.ExitCode ?? 1) === 0,\n exitCode: info.ExitCode ?? 1,\n stdout: this.stdout,\n stderr: this.stderr,\n executionTimeMs: Date.now() - this._startTime,\n };\n }\n\n async kill(): Promise<boolean> {\n if (this._exitCode !== undefined) return false;\n\n try {\n // Get the PID inside the container from exec inspect.\n // Single retry with 50ms delay — Docker may not have assigned a PID yet\n // if kill() is called immediately after spawn(). A polling loop with\n // backoff would be more robust under heavy load, but overkill in practice.\n let info = await this._inspectExec();\n if (!info.Running || !info.Pid) {\n await new Promise(r => setTimeout(r, 50));\n info = await this._inspectExec();\n }\n\n if (!info.Running) {\n this._killed = true;\n this._destroyStream();\n return false;\n }\n\n const pid = info.Pid;\n if (!pid) {\n this._killed = true;\n this._destroyStream();\n return false;\n }\n\n // Kill the process group (negative PID), fall back to direct PID\n const killExec = await this._container.exec({\n Cmd: ['sh', '-c', `kill -9 -${pid} 2>/dev/null || kill -9 ${pid}`],\n AttachStdout: false,\n AttachStderr: false,\n });\n await killExec.start({});\n\n // Mark as killed and destroy stream so wait() resolves.\n // Docker exec streams don't close automatically when the process is killed externally.\n this._killed = true;\n this._destroyStream();\n return true;\n } catch (error: unknown) {\n this._killed = true;\n this._destroyStream();\n // ESRCH / \"no such process\" is expected if the process exited between inspect and kill\n const msg = error instanceof Error ? error.message.toLowerCase() : '';\n if (!msg.includes('no such process') && !msg.includes('esrch')) {\n // Unexpected error — not fatal but worth noting for debugging\n console.warn(`[DockerProcessManager] kill(${this.pid}) failed unexpectedly:`, error);\n }\n return false;\n }\n }\n\n async sendStdin(data: string): Promise<void> {\n if (this._exitCode !== undefined) {\n throw new Error(`Process ${this.pid} has already exited with code ${this._exitCode}`);\n }\n if (!this._stdinStream) {\n throw new Error(`Process ${this.pid} was not started with stdin support`);\n }\n this._stdinStream.write(data);\n }\n\n /** @internal Force-close the exec stream to unblock wait(). */\n _destroyStream(): void {\n const stream = this._execStream as unknown as { destroy?: () => void } | null;\n if (stream && typeof stream.destroy === 'function') {\n stream.destroy();\n this._execStream = null;\n }\n }\n\n private async _inspectExec(): Promise<ExecInspectInfo> {\n return this._exec.inspect();\n }\n}\n\n// =============================================================================\n// Docker Process Manager\n// =============================================================================\n\n/**\n * Docker implementation of SandboxProcessManager.\n * Uses `container.exec()` with stream-based I/O.\n */\nexport class DockerProcessManager extends SandboxProcessManager {\n private _container: Container | null = null;\n private readonly _defaultTimeout: number;\n\n constructor(options: { env: Record<string, string>; defaultTimeout?: number }) {\n super(options);\n this._defaultTimeout = options.defaultTimeout ?? 0;\n }\n\n /** @internal Called by DockerSandbox after container is ready */\n setContainer(container: Container): void {\n this._container = container;\n }\n\n /** Get the container, throwing if not set */\n private get container(): Container {\n if (!this._container) {\n throw new Error('Docker container not available. Has the sandbox been started?');\n }\n return this._container;\n }\n\n async spawn(command: string, options: SpawnProcessOptions = {}): Promise<ProcessHandle> {\n const container = this.container;\n\n // Merge default env with per-spawn env\n const mergedEnv = { ...this.env, ...options.env };\n const envArray = Object.entries(mergedEnv)\n .filter((entry): entry is [string, string] => entry[1] !== undefined)\n .map(([k, v]) => `${k}=${v}`);\n\n // Create exec instance\n const exec = await container.exec({\n Cmd: ['sh', '-c', command],\n AttachStdout: true,\n AttachStderr: true,\n AttachStdin: true,\n Tty: false,\n Env: envArray.length > 0 ? envArray : undefined,\n WorkingDir: options.cwd,\n });\n\n // Start exec and get the multiplexed stream\n const stream = await exec.start({ hijack: true, stdin: true });\n\n const startTime = Date.now();\n const handle = new DockerProcessHandle(exec, container, startTime, stream, options);\n handle._setExecStream(stream);\n\n // Create the wait promise that resolves when the stream ends\n const waitPromise = new Promise<CommandResult>(resolve => {\n // Demux the multiplexed stream into stdout/stderr\n // Docker multiplexes stdout/stderr into a single stream with 8-byte headers\n // when Tty is false. We need to parse these headers.\n const buffer: Buffer[] = [];\n\n stream.on('data', (chunk: Buffer) => {\n buffer.push(chunk);\n // Process all complete frames in the buffer\n let combined = Buffer.concat(buffer);\n buffer.length = 0;\n\n while (combined.length >= 8) {\n const type = combined[0]; // 1 = stdout, 2 = stderr\n const size = combined.readUInt32BE(4);\n\n if (combined.length < 8 + size) {\n // Incomplete frame, save for next chunk\n buffer.push(combined);\n break;\n }\n\n const payload = combined.subarray(8, 8 + size).toString('utf-8');\n if (type === 1) {\n handle.emitStdout(payload);\n } else if (type === 2) {\n handle.emitStderr(payload);\n }\n\n combined = combined.subarray(8 + size);\n }\n\n // Save any remaining partial data\n if (combined.length > 0 && buffer.length === 0) {\n buffer.push(combined);\n }\n });\n\n stream.on('end', async () => {\n // Get exit code from exec inspect\n try {\n const info = await exec.inspect();\n const exitCode = info.ExitCode ?? 1;\n handle._setExitCode(exitCode);\n resolve({\n success: exitCode === 0,\n exitCode,\n stdout: handle.stdout,\n stderr: handle.stderr,\n executionTimeMs: Date.now() - startTime,\n });\n } catch {\n handle._setExitCode(1);\n resolve({\n success: false,\n exitCode: 1,\n stdout: handle.stdout,\n stderr: handle.stderr,\n executionTimeMs: Date.now() - startTime,\n });\n }\n });\n\n // 'close' fires when stream.destroy() is called (e.g., from kill or timeout).\n // Only resolve with SIGKILL exit code when the process was explicitly killed;\n // natural stream close should be handled by the 'end' event above.\n // Note: Docker multiplexed streams always emit 'end' before 'close' for\n // natural exits, so the !_killed guard won't silently drop natural closes.\n stream.on('close', () => {\n if (handle.exitCode !== undefined) return; // Already resolved via 'end'\n if (!handle._killed) return; // Natural close — 'end' handles it\n handle._setExitCode(137); // SIGKILL\n resolve({\n success: false,\n exitCode: 137,\n stdout: handle.stdout,\n stderr: handle.stderr,\n executionTimeMs: Date.now() - startTime,\n });\n });\n\n stream.on('error', () => {\n if (handle.exitCode !== undefined) return; // Already resolved\n handle._setExitCode(1);\n resolve({\n success: false,\n exitCode: 1,\n stdout: handle.stdout,\n stderr: handle.stderr || 'Stream error',\n executionTimeMs: Date.now() - startTime,\n });\n });\n });\n\n // Wire up timeout: kill the process and destroy the stream after the timeout period.\n // Per-spawn timeout takes precedence; falls back to the sandbox-level default.\n const resolvedTimeout = options.timeout ?? this._defaultTimeout;\n if (resolvedTimeout > 0) {\n const timeoutMs = resolvedTimeout;\n const timer = setTimeout(() => {\n if (handle.exitCode === undefined) {\n handle._killed = true;\n handle.kill().catch(() => {});\n // Ensure stream is destroyed even if kill() fails (e.g., PID not found)\n handle._destroyStream();\n }\n }, timeoutMs);\n // Clear timer when process exits naturally\n void waitPromise.then(() => clearTimeout(timer));\n }\n\n handle._setWaitPromise(waitPromise);\n this._tracked.set(handle.pid, handle);\n return handle;\n }\n\n /** Clear all tracked process handles and release the container reference (e.g., after container stop/destroy) */\n reset(): void {\n this._tracked.clear();\n this._container = null;\n }\n\n async list(): Promise<ProcessInfo[]> {\n const results: ProcessInfo[] = [];\n\n for (const [pid, handle] of this._tracked) {\n results.push({\n pid,\n command: handle.command,\n running: handle.exitCode === undefined,\n exitCode: handle.exitCode,\n });\n }\n\n return results;\n }\n}\n","/**\n * Docker Sandbox Provider\n *\n * A Docker-based sandbox implementation that uses long-lived containers\n * with `docker exec` for command execution. Targets local development,\n * CI/CD, air-gapped deployments, and cost-sensitive scenarios where\n * cloud sandboxes are overkill.\n *\n * @see https://docs.docker.com/engine/api/\n */\n\nimport { isDeepStrictEqual } from 'node:util';\nimport type { RequestContext } from '@mastra/core/di';\nimport type { SandboxInfo, ProviderStatus, MastraSandboxOptions } from '@mastra/core/workspace';\nimport { MastraSandbox, SandboxError, SandboxNotReadyError } from '@mastra/core/workspace';\nimport Docker from 'dockerode';\nimport type { Container, ContainerInfo } from 'dockerode';\nimport { DockerProcessManager } from './process-manager';\n\nconst LOG_PREFIX = '[DockerSandbox]';\n\n/**\n * Inlined from `@mastra/core/workspace` to avoid requiring a newer core peer dep.\n * Canonical type: packages/core/src/workspace/sandbox/mastra-sandbox.ts\n * TODO: Remove once minimum peer dep includes InstructionsOption export.\n */\ntype InstructionsOption = string | ((opts: { defaultInstructions: string; requestContext?: RequestContext }) => string);\n\ntype DockerSandboxUlimit = {\n name: string;\n soft: number;\n hard: number;\n};\n\ntype DockerSandboxTmpfs = Record<string, string>;\n\n// =============================================================================\n// Docker Sandbox Options\n// =============================================================================\n\nexport interface DockerSandboxOptions extends Omit<MastraSandboxOptions, 'processes'> {\n /** Unique identifier for this sandbox instance. Used for container naming and reconnection. */\n id?: string;\n /** Docker image to use.\n * @default 'node:22-slim'\n */\n image?: string;\n /** Container entrypoint command. Must keep the container alive.\n * @default ['sleep', 'infinity']\n */\n command?: string[];\n /** Environment variables to set in the container */\n env?: Record<string, string>;\n /** Host-to-container bind mounts (e.g., `{ '/host/path': '/container/path' }`) */\n volumes?: Record<string, string>;\n /** Docker network to join */\n network?: string;\n /** Run in privileged mode\n * @default false\n */\n privileged?: boolean;\n /** Memory limit in bytes (HostConfig.Memory). Docker treats 0 as unlimited. */\n memory?: number;\n /** Total memory plus swap in bytes (HostConfig.MemorySwap). */\n memorySwap?: number;\n /** CPU shares relative weight (HostConfig.CpuShares). */\n cpuShares?: number;\n /** CPU quota in microseconds per period (HostConfig.CpuQuota). */\n cpuQuota?: number;\n /** CPU period in microseconds (HostConfig.CpuPeriod). */\n cpuPeriod?: number;\n /** Maximum number of PIDs in the container (HostConfig.PidsLimit). */\n pidsLimit?: number;\n /** Mount the container root filesystem as read-only (HostConfig.ReadonlyRootfs). */\n readonlyRootfs?: boolean;\n /** Linux capabilities to drop (HostConfig.CapDrop), e.g. ['ALL']. */\n capDrop?: string[];\n /** Linux capabilities to add (HostConfig.CapAdd). */\n capAdd?: string[];\n /** Security options (HostConfig.SecurityOpt), e.g. ['no-new-privileges:true']. */\n securityOpt?: string[];\n /** Ulimit entries for Docker HostConfig.Ulimits. */\n ulimits?: DockerSandboxUlimit[];\n /** tmpfs mount paths with options (HostConfig.Tmpfs). */\n tmpfs?: DockerSandboxTmpfs;\n /** Default command timeout in milliseconds\n * @default 300_000 // 5 minutes\n */\n timeout?: number;\n /** Working directory inside the container\n * @default '/workspace'\n */\n workingDir?: string;\n /** Container labels for filtering and identification */\n labels?: Record<string, string>;\n /** Pass-through dockerode connection options (socket path, host, TLS certs) */\n dockerOptions?: Docker.DockerOptions;\n /**\n * Custom instructions that override the default instructions\n * returned by `getInstructions()`.\n *\n * - `string` — Fully replaces the default instructions.\n * Pass an empty string to suppress instructions entirely.\n * - `(opts) => string` — Receives the default instructions and\n * optional request context so you can extend or customise per-request.\n */\n instructions?: InstructionsOption;\n}\n\n// =============================================================================\n// Docker Sandbox Implementation\n// =============================================================================\n\n/**\n * Docker sandbox implementation using long-lived containers.\n *\n * Features:\n * - Long-lived container with `docker exec` for commands\n * - Bind mount support via Docker volumes\n * - Reconnection to existing containers by ID/name\n * - Container label tracking for discovery\n *\n * @example Basic usage\n * ```typescript\n * import { Workspace } from '@mastra/core/workspace';\n * import { DockerSandbox } from '@mastra/docker';\n *\n * const sandbox = new DockerSandbox({\n * image: 'node:22-slim',\n * timeout: 60000,\n * });\n *\n * const workspace = new Workspace({ sandbox });\n * const result = await workspace.executeCode('console.log(\"Hello!\")');\n * ```\n *\n * @example With bind mounts\n * ```typescript\n * const sandbox = new DockerSandbox({\n * image: 'node:22-slim',\n * volumes: { '/my/project': '/workspace/project' },\n * });\n * ```\n */\nexport class DockerSandbox extends MastraSandbox {\n readonly id: string;\n readonly name = 'DockerSandbox';\n readonly provider = 'docker';\n status: ProviderStatus = 'pending';\n\n declare readonly processes: DockerProcessManager;\n\n /** Underlying Docker client */\n private readonly _docker: Docker;\n\n /** Container reference (set after start) */\n private _container: Container | null = null;\n\n /** Configuration */\n private readonly _image: string;\n private readonly _command: string[];\n private readonly _env: Record<string, string>;\n private readonly _volumes: Record<string, string>;\n private readonly _network?: string;\n private readonly _privileged: boolean;\n private readonly _privilegedWasSet: boolean;\n private readonly _memory?: number;\n private readonly _memorySwap?: number;\n private readonly _cpuShares?: number;\n private readonly _cpuQuota?: number;\n private readonly _cpuPeriod?: number;\n private readonly _pidsLimit?: number;\n private readonly _readonlyRootfs?: boolean;\n private readonly _capDrop?: string[];\n private readonly _capAdd?: string[];\n private readonly _securityOpt?: string[];\n private readonly _ulimits?: DockerSandboxUlimit[];\n private readonly _tmpfs?: DockerSandboxTmpfs;\n private readonly _workingDir: string;\n private readonly _labels: Record<string, string>;\n private readonly _instructionsOverride?: InstructionsOption;\n\n constructor(options: DockerSandboxOptions = {}) {\n const processManager = new DockerProcessManager({\n env: options.env ?? {},\n defaultTimeout: options.timeout ?? 300_000,\n });\n\n super({\n ...options,\n name: 'DockerSandbox',\n processes: processManager,\n });\n\n this.id = options.id ?? this._generateId();\n this._image = options.image ?? 'node:22-slim';\n this._command = options.command ?? ['sleep', 'infinity'];\n this._env = options.env ?? {};\n this._volumes = options.volumes ?? {};\n this._network = options.network;\n this._privileged = options.privileged ?? false;\n this._privilegedWasSet = options.privileged !== undefined;\n this._memory = options.memory;\n this._memorySwap = options.memorySwap;\n this._cpuShares = options.cpuShares;\n this._cpuQuota = options.cpuQuota;\n this._cpuPeriod = options.cpuPeriod;\n this._pidsLimit = options.pidsLimit;\n this._readonlyRootfs = options.readonlyRootfs;\n this._capDrop = options.capDrop;\n this._capAdd = options.capAdd;\n this._securityOpt = options.securityOpt;\n this._ulimits = options.ulimits;\n this._tmpfs = options.tmpfs;\n this._workingDir = options.workingDir ?? '/workspace';\n this._labels = {\n ...options.labels,\n 'mastra.sandbox': 'true',\n 'mastra.sandbox.id': this.id,\n };\n this._instructionsOverride = options.instructions;\n this._docker = new Docker(options.dockerOptions);\n }\n\n /**\n * Get the underlying Docker container for direct access.\n * @throws {SandboxNotReadyError} If the sandbox has not been started.\n */\n get container(): Container {\n if (!this._container) {\n throw new SandboxNotReadyError(this.id);\n }\n return this._container;\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------------------\n\n async start(): Promise<void> {\n this.logger.debug(`${LOG_PREFIX} Starting sandbox ${this.id}...`);\n\n // Try to reconnect to existing container\n const existing = await this._findExistingContainer();\n if (existing) {\n this.logger.debug(`${LOG_PREFIX} Found existing container ${existing.Id}`);\n this._container = this._docker.getContainer(existing.Id);\n\n // Use inspect() to get authoritative container state — listContainers() state\n // can be stale immediately after stop() returns but before container fully exits\n const info = await this._container.inspect();\n // On reconnect, actual HostConfig controls whether hardening is effective.\n this._warnOnPrivilegedHardeningConflict(info.HostConfig?.Privileged ?? this._privileged);\n this._warnOnReconnectedHostConfigMismatch(existing.Id, info.HostConfig);\n const actualState = info.State?.Running ? 'running' : 'stopped';\n\n if (actualState !== 'running') {\n this.logger.debug(`${LOG_PREFIX} Container exists but not running (${actualState}), starting...`);\n await this._container.start();\n }\n\n // Provide container reference to process manager\n this.processes.setContainer(this._container);\n\n this.logger.debug(`${LOG_PREFIX} Reconnected to container ${existing.Id}`);\n return;\n }\n\n this._warnOnPrivilegedHardeningConflict(this._privileged);\n\n // Pull image if not available locally\n await this._ensureImage();\n\n // Build environment array for Docker API\n const envArray = Object.entries(this._env).map(([k, v]) => `${k}=${v}`);\n\n // Build bind mount array\n const binds = Object.entries(this._volumes).map(([host, container]) => `${host}:${container}`);\n\n // Create container\n this.logger.debug(`${LOG_PREFIX} Creating container with image ${this._image}...`);\n this._container = await this._docker.createContainer({\n Image: this._image,\n Cmd: this._command,\n Env: envArray,\n WorkingDir: this._workingDir,\n Labels: this._labels,\n HostConfig: {\n Binds: binds.length > 0 ? binds : undefined,\n NetworkMode: this._network,\n Privileged: this._privileged,\n Memory: this._memory,\n MemorySwap: this._memorySwap,\n CpuShares: this._cpuShares,\n CpuQuota: this._cpuQuota,\n CpuPeriod: this._cpuPeriod,\n PidsLimit: this._pidsLimit,\n ReadonlyRootfs: this._readonlyRootfs,\n CapDrop: this._capDrop,\n CapAdd: this._capAdd,\n SecurityOpt: this._securityOpt,\n Ulimits: this._ulimits?.map(toDockerUlimit),\n Tmpfs: this._tmpfs,\n },\n // Keep stdin open for interactive use\n OpenStdin: true,\n Tty: false,\n });\n\n // Start container\n await this._container.start();\n\n // Provide container reference to process manager\n this.processes.setContainer(this._container);\n\n this.logger.debug(`${LOG_PREFIX} Container started: ${this._container.id}`);\n }\n\n private _warnOnPrivilegedHardeningConflict(effectivePrivileged: boolean | undefined): void {\n if (!effectivePrivileged) return;\n\n // Privileged mode makes capability and security-option controls ineffective.\n // ReadonlyRootfs, ulimits, tmpfs, memory, CPU, and PID limits still apply.\n const conflictedHostConfigFields = [\n this._capDrop && this._capDrop.length > 0 ? 'CapDrop' : undefined,\n this._capAdd && this._capAdd.length > 0 ? 'CapAdd' : undefined,\n this._securityOpt && this._securityOpt.length > 0 ? 'SecurityOpt' : undefined,\n ].filter((field): field is keyof Docker.HostConfig => field !== undefined);\n\n if (conflictedHostConfigFields.length === 0) return;\n\n const optionNames = conflictedHostConfigFields.map(toDockerSandboxOptionName);\n\n this.logger.warn(\n `${LOG_PREFIX} Privileged containers can bypass some requested hardening controls: ${optionNames.join(', ')}`,\n { fields: optionNames, hostConfigFields: conflictedHostConfigFields },\n );\n }\n\n private _warnOnReconnectedHostConfigMismatch(containerId: string, hostConfig?: Docker.HostConfig): void {\n if (!hostConfig) return;\n\n const mismatchedHostConfigFields = this._requestedHardeningHostConfigEntries(hostConfig)\n .filter(([field, requestedValue]) => !isHostConfigValueEqual(field, hostConfig[field], requestedValue))\n .map(([field]) => field);\n\n if (mismatchedHostConfigFields.length === 0) return;\n\n if (\n !this._privilegedWasSet &&\n hostConfig.Privileged === true &&\n mismatchedHostConfigFields.includes('Privileged')\n ) {\n this.logger.warn(\n `${LOG_PREFIX} Reconnected to existing container ${containerId}; the existing container is privileged, but this DockerSandbox did not request privileged mode. Destroy and recreate the sandbox to apply the default non-privileged mode.`,\n { containerId, fields: ['privileged'], hostConfigFields: ['Privileged'] },\n );\n }\n\n const remainingMismatchedHostConfigFields = mismatchedHostConfigFields.filter(\n field => field !== 'Privileged' || this._privilegedWasSet,\n );\n\n if (remainingMismatchedHostConfigFields.length === 0) return;\n\n const mismatchedOptions = remainingMismatchedHostConfigFields.map(toDockerSandboxOptionName);\n\n this.logger.warn(\n `${LOG_PREFIX} Reconnected to existing container ${containerId}; requested Docker option(s) ${mismatchedOptions.join(\n ', ',\n )} differ from inspected HostConfig field(s) ${remainingMismatchedHostConfigFields.join(\n ', ',\n )} and cannot be applied to the existing container. Destroy and recreate the sandbox to apply them.`,\n { containerId, fields: mismatchedOptions, hostConfigFields: remainingMismatchedHostConfigFields },\n );\n }\n\n private _requestedHardeningHostConfigEntries(\n hostConfig?: Docker.HostConfig,\n ): Array<[keyof Docker.HostConfig, unknown]> {\n const entries: Array<[keyof Docker.HostConfig, unknown]> = [\n ['Memory', this._memory],\n ['MemorySwap', this._memorySwap],\n ['CpuShares', this._cpuShares],\n ['CpuQuota', this._cpuQuota],\n ['CpuPeriod', this._cpuPeriod],\n ['PidsLimit', this._pidsLimit],\n ['ReadonlyRootfs', this._readonlyRootfs],\n ['CapDrop', this._capDrop],\n ['CapAdd', this._capAdd],\n ['SecurityOpt', this._securityOpt],\n ['Ulimits', this._ulimits],\n ['Tmpfs', this._tmpfs],\n ];\n\n if (this._privilegedWasSet || hostConfig?.Privileged === true) {\n entries.unshift(['Privileged', this._privileged]);\n }\n\n return entries.filter((entry): entry is [keyof Docker.HostConfig, unknown] => isPresentHostConfigValue(entry[1]));\n }\n\n async stop(): Promise<void> {\n const container = await this._resolveContainer();\n if (!container) return;\n\n this.logger.debug(`${LOG_PREFIX} Stopping container ${container.id}...`);\n try {\n await container.stop({ t: 10 });\n } catch (error: unknown) {\n // Container may already be stopped\n if (!isContainerNotRunningError(error)) {\n throw error;\n }\n }\n this.processes.reset();\n this.logger.debug(`${LOG_PREFIX} Container stopped`);\n }\n\n async destroy(): Promise<void> {\n const container = await this._resolveContainer();\n if (!container) return;\n\n this.logger.debug(`${LOG_PREFIX} Destroying container ${container.id}...`);\n try {\n await container.remove({ force: true, v: true });\n } catch (error: unknown) {\n // Container may already be removed\n if (!isContainerNotFoundError(error)) {\n throw error;\n }\n }\n this.processes.reset();\n this._container = null;\n this.logger.debug(`${LOG_PREFIX} Container destroyed`);\n }\n\n // ---------------------------------------------------------------------------\n // Instructions\n // ---------------------------------------------------------------------------\n\n getInstructions(opts?: { requestContext?: RequestContext }): string {\n const defaultInstructions = [\n `You are working inside a Docker container (image: ${this._image}).`,\n `The working directory is ${this._workingDir}.`,\n 'You can execute shell commands using executeCommand().',\n 'You can spawn background processes using processes.spawn().',\n ].join('\\n');\n\n if (this._instructionsOverride === undefined) return defaultInstructions;\n if (typeof this._instructionsOverride === 'string') return this._instructionsOverride;\n return this._instructionsOverride({ defaultInstructions, requestContext: opts?.requestContext });\n }\n\n // ---------------------------------------------------------------------------\n // Info\n // ---------------------------------------------------------------------------\n\n async getInfo(): Promise<SandboxInfo> {\n const info: SandboxInfo = {\n id: this.id,\n name: this.name,\n provider: this.provider,\n status: this.status,\n createdAt: new Date(),\n metadata: {\n image: this._image,\n workingDir: this._workingDir,\n labels: this._labels,\n },\n };\n\n if (this._container) {\n try {\n const inspect = await this._container.inspect();\n info.createdAt = new Date(inspect.Created);\n info.metadata = {\n ...info.metadata,\n containerId: inspect.Id,\n containerName: inspect.Name,\n state: inspect.State.Status,\n };\n } catch {\n // Container may have been removed\n }\n }\n\n return info;\n }\n\n // ---------------------------------------------------------------------------\n // Private helpers\n // ---------------------------------------------------------------------------\n\n private _generateId(): string {\n return `docker-sandbox-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;\n }\n\n /**\n * Resolve the container reference, looking up by label if `_container` is unset.\n * This ensures `stop()` and `destroy()` work even when the instance was created\n * with an existing container's ID but `start()` was never called.\n */\n private async _resolveContainer(): Promise<Container | null> {\n if (this._container) return this._container;\n const existing = await this._findExistingContainer();\n if (!existing) return null;\n this._container = this._docker.getContainer(existing.Id);\n return this._container;\n }\n\n /**\n * Find an existing container matching this sandbox's ID via labels.\n */\n private async _findExistingContainer(): Promise<ContainerInfo | null> {\n try {\n const containers = await this._docker.listContainers({\n all: true,\n filters: {\n label: [`mastra.sandbox.id=${this.id}`],\n },\n });\n return containers[0] ?? null;\n } catch (error) {\n // Log and re-throw infrastructure errors (daemon unreachable, auth, etc.)\n this.logger.debug(\n `${LOG_PREFIX} Failed to list containers: ${error instanceof Error ? error.message : String(error)}`,\n );\n throw error;\n }\n }\n\n /**\n * Ensure the Docker image is available locally. Pulls if needed.\n */\n private async _ensureImage(): Promise<void> {\n try {\n await this._docker.getImage(this._image).inspect();\n this.logger.debug(`${LOG_PREFIX} Image ${this._image} available locally`);\n } catch (error) {\n // Only attempt pull if the image doesn't exist (404).\n // Re-throw infrastructure errors (daemon unreachable, auth, etc.)\n if (!isImageNotFoundError(error)) {\n throw error;\n }\n\n this.logger.debug(`${LOG_PREFIX} Pulling image ${this._image}...`);\n try {\n const stream = await this._docker.pull(this._image);\n await new Promise<void>((resolve, reject) => {\n this._docker.modem.followProgress(stream, (err: Error | null) => {\n if (err) reject(err);\n else resolve();\n });\n });\n this.logger.debug(`${LOG_PREFIX} Image ${this._image} pulled successfully`);\n } catch (error) {\n throw new SandboxError(\n `Failed to pull Docker image '${this._image}': ${error instanceof Error ? error.message : String(error)}`,\n 'NOT_READY',\n { image: this._image, reason: 'image_pull_failed' },\n );\n }\n }\n }\n}\n\n// =============================================================================\n// Error detection helpers\n// =============================================================================\n\nfunction isContainerNotRunningError(error: unknown): boolean {\n if (error instanceof Error) {\n return error.message.includes('is not running') || error.message.includes('container already stopped');\n }\n return false;\n}\n\nfunction isContainerNotFoundError(error: unknown): boolean {\n if (error instanceof Error) {\n const msg = error.message.toLowerCase();\n return msg.includes('no such container') || (msg.includes('removal') && msg.includes('is already in progress'));\n }\n return false;\n}\n\nfunction isImageNotFoundError(error: unknown): boolean {\n if (error instanceof Error) {\n return error.message.toLowerCase().includes('no such image');\n }\n return false;\n}\n\nfunction isHostConfigValueEqual(field: keyof Docker.HostConfig, actual: unknown, expected: unknown): boolean {\n // Structural equality for the Docker HostConfig shapes exposed by DockerSandboxOptions.\n return isDeepStrictEqual(normalizeHostConfigValue(field, actual), normalizeHostConfigValue(field, expected));\n}\n\nfunction normalizeHostConfigValue(field: keyof Docker.HostConfig, value: unknown): unknown {\n if (value == null) return undefined;\n\n if ((field === 'CapAdd' || field === 'CapDrop') && Array.isArray(value)) {\n if (value.length === 0) return undefined;\n return value.map(normalizeCapability).sort();\n }\n\n if (field === 'SecurityOpt' && Array.isArray(value)) {\n if (value.length === 0) return undefined;\n return value.map(normalizeSecurityOpt).sort();\n }\n\n if (field === 'Tmpfs' && value && typeof value === 'object' && !Array.isArray(value)) {\n if (Object.keys(value).length === 0) return undefined;\n return Object.fromEntries(\n Object.entries(value)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([path, options]) => [path, typeof options === 'string' ? normalizeTmpfsOptions(options) : options]),\n );\n }\n\n if (Array.isArray(value)) {\n if (field === 'Ulimits' && value.length === 0) return undefined;\n return value\n .map(nestedValue => normalizeHostConfigValue(field, nestedValue))\n .sort((a, b) => JSON.stringify(a).localeCompare(JSON.stringify(b)));\n }\n\n if (field === 'Ulimits' && value && typeof value === 'object') {\n return normalizeUlimit(value);\n }\n\n if (value && typeof value === 'object') {\n return Object.fromEntries(\n Object.entries(value)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([key, nestedValue]) => [key, normalizeHostConfigValue(field, nestedValue)]),\n );\n }\n\n return value;\n}\n\nfunction isPresentHostConfigValue(value: unknown): boolean {\n if (value == null) return false;\n if (Array.isArray(value)) return value.length > 0;\n if (value && typeof value === 'object') return Object.keys(value).length > 0;\n return true;\n}\n\nfunction normalizeCapability(capability: unknown): unknown {\n return typeof capability === 'string' ? capability.toUpperCase().replace(/^CAP_/, '') : capability;\n}\n\nfunction normalizeTmpfsOptions(options: string): string {\n return options\n .split(',')\n .map(option => option.trim())\n .filter(Boolean)\n .sort()\n .join(',');\n}\n\nfunction normalizeSecurityOpt(option: unknown): unknown {\n if (typeof option !== 'string') return option;\n\n const noNewPrivileges = option.match(/^no-new-privileges[:=](.+)$/i);\n if (noNewPrivileges) {\n return `no-new-privileges=${noNewPrivileges[1]}`;\n }\n\n return option;\n}\n\nfunction normalizeUlimit(value: object): unknown {\n const record = value as Record<string, unknown>;\n return {\n name: record.name ?? record.Name,\n soft: record.soft ?? record.Soft,\n hard: record.hard ?? record.Hard,\n };\n}\n\nfunction toDockerUlimit(ulimit: DockerSandboxUlimit): Docker.Ulimit {\n return {\n Name: ulimit.name,\n Soft: ulimit.soft,\n Hard: ulimit.hard,\n };\n}\n\nfunction toDockerSandboxOptionName(field: keyof Docker.HostConfig): string {\n const optionNames: Partial<Record<keyof Docker.HostConfig, string>> = {\n Privileged: 'privileged',\n Memory: 'memory',\n MemorySwap: 'memorySwap',\n CpuShares: 'cpuShares',\n CpuQuota: 'cpuQuota',\n CpuPeriod: 'cpuPeriod',\n PidsLimit: 'pidsLimit',\n ReadonlyRootfs: 'readonlyRootfs',\n CapDrop: 'capDrop',\n CapAdd: 'capAdd',\n SecurityOpt: 'securityOpt',\n Ulimits: 'ulimits',\n Tmpfs: 'tmpfs',\n };\n\n return optionNames[field] ?? String(field);\n}\n","/**\n * Docker Sandbox Provider Descriptor\n *\n * Enables registration with MastraEditor for UI-driven sandbox configuration.\n */\n\nimport type { SandboxProvider } from '@mastra/core/editor';\nimport { DockerSandbox } from './sandbox';\nimport type { DockerSandboxOptions } from './sandbox';\n\n/**\n * Serializable config for the Docker sandbox provider.\n * This is the subset of DockerSandboxOptions that can be stored in a config file\n * and rendered in a UI form.\n */\nexport interface DockerProviderConfig {\n /** Docker image to use */\n image?: string;\n /** Default command timeout in milliseconds */\n timeout?: number;\n /** Environment variables */\n env?: Record<string, string>;\n /** Host-to-container bind mounts */\n volumes?: Record<string, string>;\n /** Docker network to join */\n network?: string;\n /** Working directory inside the container */\n workingDir?: string;\n /** Run in privileged mode */\n privileged?: boolean;\n /** Memory limit in bytes */\n memory?: number;\n /** Total memory plus swap in bytes */\n memorySwap?: number;\n /** CPU shares relative weight */\n cpuShares?: number;\n /** CPU quota in microseconds per period */\n cpuQuota?: number;\n /** CPU period in microseconds */\n cpuPeriod?: number;\n /** Maximum number of PIDs in the container */\n pidsLimit?: number;\n /** Mount the container root filesystem as read-only */\n readonlyRootfs?: boolean;\n /** Linux capabilities to drop */\n capDrop?: string[];\n /** Linux capabilities to add */\n capAdd?: string[];\n /** Docker security options */\n securityOpt?: string[];\n /** Ulimit entries for Docker HostConfig.Ulimits */\n ulimits?: DockerSandboxOptions['ulimits'];\n /** tmpfs mount paths with options */\n tmpfs?: DockerSandboxOptions['tmpfs'];\n}\n\nexport const dockerSandboxProvider: SandboxProvider<DockerProviderConfig> = {\n id: 'docker',\n name: 'Docker Sandbox',\n description: 'Local container sandbox powered by Docker',\n configSchema: {\n type: 'object',\n properties: {\n image: {\n type: 'string',\n description: 'Docker image to use',\n default: 'node:22-slim',\n },\n timeout: {\n type: 'number',\n description: 'Default command timeout in milliseconds',\n default: 300_000,\n },\n env: {\n type: 'object',\n description: 'Environment variables',\n additionalProperties: { type: 'string' },\n },\n volumes: {\n type: 'object',\n description: 'Host-to-container bind mounts (host path → container path)',\n additionalProperties: { type: 'string' },\n },\n network: {\n type: 'string',\n description: 'Docker network to join',\n },\n workingDir: {\n type: 'string',\n description: 'Working directory inside the container',\n default: '/workspace',\n },\n privileged: {\n type: 'boolean',\n description: 'Run in privileged mode',\n default: false,\n },\n memory: {\n type: 'number',\n description: 'Memory limit in bytes',\n },\n memorySwap: {\n type: 'number',\n description: 'Total memory plus swap in bytes',\n },\n cpuShares: {\n type: 'number',\n description: 'CPU shares relative weight',\n },\n cpuQuota: {\n type: 'number',\n description: 'CPU quota in microseconds per period',\n },\n cpuPeriod: {\n type: 'number',\n description: 'CPU period in microseconds',\n },\n pidsLimit: {\n type: 'number',\n description: 'Maximum number of PIDs in the container',\n },\n readonlyRootfs: {\n type: 'boolean',\n description: 'Mount the container root filesystem as read-only',\n },\n capDrop: {\n type: 'array',\n description: 'Linux capabilities to drop',\n items: { type: 'string' },\n },\n capAdd: {\n type: 'array',\n description: 'Linux capabilities to add',\n items: { type: 'string' },\n },\n securityOpt: {\n type: 'array',\n description: 'Docker security options',\n items: { type: 'string' },\n },\n ulimits: {\n type: 'array',\n description: 'Ulimit entries for Docker HostConfig.Ulimits',\n items: {\n type: 'object',\n required: ['name', 'soft', 'hard'],\n additionalProperties: false,\n properties: {\n name: { type: 'string' },\n soft: { type: 'number' },\n hard: { type: 'number' },\n },\n },\n },\n tmpfs: {\n type: 'object',\n description: 'tmpfs mount paths with options',\n additionalProperties: { type: 'string' },\n },\n },\n },\n createSandbox: (config: DockerProviderConfig) => new DockerSandbox(config as DockerSandboxOptions),\n};\n"]}
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { isDeepStrictEqual } from 'util';
1
2
  import { SandboxProcessManager, MastraSandbox, SandboxNotReadyError, SandboxError, ProcessHandle } from '@mastra/core/workspace';
2
3
  import Docker from 'dockerode';
3
4
 
@@ -269,6 +270,19 @@ var DockerSandbox = class extends MastraSandbox {
269
270
  _volumes;
270
271
  _network;
271
272
  _privileged;
273
+ _privilegedWasSet;
274
+ _memory;
275
+ _memorySwap;
276
+ _cpuShares;
277
+ _cpuQuota;
278
+ _cpuPeriod;
279
+ _pidsLimit;
280
+ _readonlyRootfs;
281
+ _capDrop;
282
+ _capAdd;
283
+ _securityOpt;
284
+ _ulimits;
285
+ _tmpfs;
272
286
  _workingDir;
273
287
  _labels;
274
288
  _instructionsOverride;
@@ -289,6 +303,19 @@ var DockerSandbox = class extends MastraSandbox {
289
303
  this._volumes = options.volumes ?? {};
290
304
  this._network = options.network;
291
305
  this._privileged = options.privileged ?? false;
306
+ this._privilegedWasSet = options.privileged !== void 0;
307
+ this._memory = options.memory;
308
+ this._memorySwap = options.memorySwap;
309
+ this._cpuShares = options.cpuShares;
310
+ this._cpuQuota = options.cpuQuota;
311
+ this._cpuPeriod = options.cpuPeriod;
312
+ this._pidsLimit = options.pidsLimit;
313
+ this._readonlyRootfs = options.readonlyRootfs;
314
+ this._capDrop = options.capDrop;
315
+ this._capAdd = options.capAdd;
316
+ this._securityOpt = options.securityOpt;
317
+ this._ulimits = options.ulimits;
318
+ this._tmpfs = options.tmpfs;
292
319
  this._workingDir = options.workingDir ?? "/workspace";
293
320
  this._labels = {
294
321
  ...options.labels,
@@ -318,6 +345,8 @@ var DockerSandbox = class extends MastraSandbox {
318
345
  this.logger.debug(`${LOG_PREFIX} Found existing container ${existing.Id}`);
319
346
  this._container = this._docker.getContainer(existing.Id);
320
347
  const info = await this._container.inspect();
348
+ this._warnOnPrivilegedHardeningConflict(info.HostConfig?.Privileged ?? this._privileged);
349
+ this._warnOnReconnectedHostConfigMismatch(existing.Id, info.HostConfig);
321
350
  const actualState = info.State?.Running ? "running" : "stopped";
322
351
  if (actualState !== "running") {
323
352
  this.logger.debug(`${LOG_PREFIX} Container exists but not running (${actualState}), starting...`);
@@ -327,6 +356,7 @@ var DockerSandbox = class extends MastraSandbox {
327
356
  this.logger.debug(`${LOG_PREFIX} Reconnected to container ${existing.Id}`);
328
357
  return;
329
358
  }
359
+ this._warnOnPrivilegedHardeningConflict(this._privileged);
330
360
  await this._ensureImage();
331
361
  const envArray = Object.entries(this._env).map(([k, v]) => `${k}=${v}`);
332
362
  const binds = Object.entries(this._volumes).map(([host, container]) => `${host}:${container}`);
@@ -340,7 +370,19 @@ var DockerSandbox = class extends MastraSandbox {
340
370
  HostConfig: {
341
371
  Binds: binds.length > 0 ? binds : void 0,
342
372
  NetworkMode: this._network,
343
- Privileged: this._privileged
373
+ Privileged: this._privileged,
374
+ Memory: this._memory,
375
+ MemorySwap: this._memorySwap,
376
+ CpuShares: this._cpuShares,
377
+ CpuQuota: this._cpuQuota,
378
+ CpuPeriod: this._cpuPeriod,
379
+ PidsLimit: this._pidsLimit,
380
+ ReadonlyRootfs: this._readonlyRootfs,
381
+ CapDrop: this._capDrop,
382
+ CapAdd: this._capAdd,
383
+ SecurityOpt: this._securityOpt,
384
+ Ulimits: this._ulimits?.map(toDockerUlimit),
385
+ Tmpfs: this._tmpfs
344
386
  },
345
387
  // Keep stdin open for interactive use
346
388
  OpenStdin: true,
@@ -350,6 +392,64 @@ var DockerSandbox = class extends MastraSandbox {
350
392
  this.processes.setContainer(this._container);
351
393
  this.logger.debug(`${LOG_PREFIX} Container started: ${this._container.id}`);
352
394
  }
395
+ _warnOnPrivilegedHardeningConflict(effectivePrivileged) {
396
+ if (!effectivePrivileged) return;
397
+ const conflictedHostConfigFields = [
398
+ this._capDrop && this._capDrop.length > 0 ? "CapDrop" : void 0,
399
+ this._capAdd && this._capAdd.length > 0 ? "CapAdd" : void 0,
400
+ this._securityOpt && this._securityOpt.length > 0 ? "SecurityOpt" : void 0
401
+ ].filter((field) => field !== void 0);
402
+ if (conflictedHostConfigFields.length === 0) return;
403
+ const optionNames = conflictedHostConfigFields.map(toDockerSandboxOptionName);
404
+ this.logger.warn(
405
+ `${LOG_PREFIX} Privileged containers can bypass some requested hardening controls: ${optionNames.join(", ")}`,
406
+ { fields: optionNames, hostConfigFields: conflictedHostConfigFields }
407
+ );
408
+ }
409
+ _warnOnReconnectedHostConfigMismatch(containerId, hostConfig) {
410
+ if (!hostConfig) return;
411
+ const mismatchedHostConfigFields = this._requestedHardeningHostConfigEntries(hostConfig).filter(([field, requestedValue]) => !isHostConfigValueEqual(field, hostConfig[field], requestedValue)).map(([field]) => field);
412
+ if (mismatchedHostConfigFields.length === 0) return;
413
+ if (!this._privilegedWasSet && hostConfig.Privileged === true && mismatchedHostConfigFields.includes("Privileged")) {
414
+ this.logger.warn(
415
+ `${LOG_PREFIX} Reconnected to existing container ${containerId}; the existing container is privileged, but this DockerSandbox did not request privileged mode. Destroy and recreate the sandbox to apply the default non-privileged mode.`,
416
+ { containerId, fields: ["privileged"], hostConfigFields: ["Privileged"] }
417
+ );
418
+ }
419
+ const remainingMismatchedHostConfigFields = mismatchedHostConfigFields.filter(
420
+ (field) => field !== "Privileged" || this._privilegedWasSet
421
+ );
422
+ if (remainingMismatchedHostConfigFields.length === 0) return;
423
+ const mismatchedOptions = remainingMismatchedHostConfigFields.map(toDockerSandboxOptionName);
424
+ this.logger.warn(
425
+ `${LOG_PREFIX} Reconnected to existing container ${containerId}; requested Docker option(s) ${mismatchedOptions.join(
426
+ ", "
427
+ )} differ from inspected HostConfig field(s) ${remainingMismatchedHostConfigFields.join(
428
+ ", "
429
+ )} and cannot be applied to the existing container. Destroy and recreate the sandbox to apply them.`,
430
+ { containerId, fields: mismatchedOptions, hostConfigFields: remainingMismatchedHostConfigFields }
431
+ );
432
+ }
433
+ _requestedHardeningHostConfigEntries(hostConfig) {
434
+ const entries = [
435
+ ["Memory", this._memory],
436
+ ["MemorySwap", this._memorySwap],
437
+ ["CpuShares", this._cpuShares],
438
+ ["CpuQuota", this._cpuQuota],
439
+ ["CpuPeriod", this._cpuPeriod],
440
+ ["PidsLimit", this._pidsLimit],
441
+ ["ReadonlyRootfs", this._readonlyRootfs],
442
+ ["CapDrop", this._capDrop],
443
+ ["CapAdd", this._capAdd],
444
+ ["SecurityOpt", this._securityOpt],
445
+ ["Ulimits", this._ulimits],
446
+ ["Tmpfs", this._tmpfs]
447
+ ];
448
+ if (this._privilegedWasSet || hostConfig?.Privileged === true) {
449
+ entries.unshift(["Privileged", this._privileged]);
450
+ }
451
+ return entries.filter((entry) => isPresentHostConfigValue(entry[1]));
452
+ }
353
453
  async stop() {
354
454
  const container = await this._resolveContainer();
355
455
  if (!container) return;
@@ -511,6 +611,92 @@ function isImageNotFoundError(error) {
511
611
  }
512
612
  return false;
513
613
  }
614
+ function isHostConfigValueEqual(field, actual, expected) {
615
+ return isDeepStrictEqual(normalizeHostConfigValue(field, actual), normalizeHostConfigValue(field, expected));
616
+ }
617
+ function normalizeHostConfigValue(field, value) {
618
+ if (value == null) return void 0;
619
+ if ((field === "CapAdd" || field === "CapDrop") && Array.isArray(value)) {
620
+ if (value.length === 0) return void 0;
621
+ return value.map(normalizeCapability).sort();
622
+ }
623
+ if (field === "SecurityOpt" && Array.isArray(value)) {
624
+ if (value.length === 0) return void 0;
625
+ return value.map(normalizeSecurityOpt).sort();
626
+ }
627
+ if (field === "Tmpfs" && value && typeof value === "object" && !Array.isArray(value)) {
628
+ if (Object.keys(value).length === 0) return void 0;
629
+ return Object.fromEntries(
630
+ Object.entries(value).sort(([a], [b]) => a.localeCompare(b)).map(([path, options]) => [path, typeof options === "string" ? normalizeTmpfsOptions(options) : options])
631
+ );
632
+ }
633
+ if (Array.isArray(value)) {
634
+ if (field === "Ulimits" && value.length === 0) return void 0;
635
+ return value.map((nestedValue) => normalizeHostConfigValue(field, nestedValue)).sort((a, b) => JSON.stringify(a).localeCompare(JSON.stringify(b)));
636
+ }
637
+ if (field === "Ulimits" && value && typeof value === "object") {
638
+ return normalizeUlimit(value);
639
+ }
640
+ if (value && typeof value === "object") {
641
+ return Object.fromEntries(
642
+ Object.entries(value).sort(([a], [b]) => a.localeCompare(b)).map(([key, nestedValue]) => [key, normalizeHostConfigValue(field, nestedValue)])
643
+ );
644
+ }
645
+ return value;
646
+ }
647
+ function isPresentHostConfigValue(value) {
648
+ if (value == null) return false;
649
+ if (Array.isArray(value)) return value.length > 0;
650
+ if (value && typeof value === "object") return Object.keys(value).length > 0;
651
+ return true;
652
+ }
653
+ function normalizeCapability(capability) {
654
+ return typeof capability === "string" ? capability.toUpperCase().replace(/^CAP_/, "") : capability;
655
+ }
656
+ function normalizeTmpfsOptions(options) {
657
+ return options.split(",").map((option) => option.trim()).filter(Boolean).sort().join(",");
658
+ }
659
+ function normalizeSecurityOpt(option) {
660
+ if (typeof option !== "string") return option;
661
+ const noNewPrivileges = option.match(/^no-new-privileges[:=](.+)$/i);
662
+ if (noNewPrivileges) {
663
+ return `no-new-privileges=${noNewPrivileges[1]}`;
664
+ }
665
+ return option;
666
+ }
667
+ function normalizeUlimit(value) {
668
+ const record = value;
669
+ return {
670
+ name: record.name ?? record.Name,
671
+ soft: record.soft ?? record.Soft,
672
+ hard: record.hard ?? record.Hard
673
+ };
674
+ }
675
+ function toDockerUlimit(ulimit) {
676
+ return {
677
+ Name: ulimit.name,
678
+ Soft: ulimit.soft,
679
+ Hard: ulimit.hard
680
+ };
681
+ }
682
+ function toDockerSandboxOptionName(field) {
683
+ const optionNames = {
684
+ Privileged: "privileged",
685
+ Memory: "memory",
686
+ MemorySwap: "memorySwap",
687
+ CpuShares: "cpuShares",
688
+ CpuQuota: "cpuQuota",
689
+ CpuPeriod: "cpuPeriod",
690
+ PidsLimit: "pidsLimit",
691
+ ReadonlyRootfs: "readonlyRootfs",
692
+ CapDrop: "capDrop",
693
+ CapAdd: "capAdd",
694
+ SecurityOpt: "securityOpt",
695
+ Ulimits: "ulimits",
696
+ Tmpfs: "tmpfs"
697
+ };
698
+ return optionNames[field] ?? String(field);
699
+ }
514
700
 
515
701
  // src/provider.ts
516
702
  var dockerSandboxProvider = {
@@ -553,6 +739,68 @@ var dockerSandboxProvider = {
553
739
  type: "boolean",
554
740
  description: "Run in privileged mode",
555
741
  default: false
742
+ },
743
+ memory: {
744
+ type: "number",
745
+ description: "Memory limit in bytes"
746
+ },
747
+ memorySwap: {
748
+ type: "number",
749
+ description: "Total memory plus swap in bytes"
750
+ },
751
+ cpuShares: {
752
+ type: "number",
753
+ description: "CPU shares relative weight"
754
+ },
755
+ cpuQuota: {
756
+ type: "number",
757
+ description: "CPU quota in microseconds per period"
758
+ },
759
+ cpuPeriod: {
760
+ type: "number",
761
+ description: "CPU period in microseconds"
762
+ },
763
+ pidsLimit: {
764
+ type: "number",
765
+ description: "Maximum number of PIDs in the container"
766
+ },
767
+ readonlyRootfs: {
768
+ type: "boolean",
769
+ description: "Mount the container root filesystem as read-only"
770
+ },
771
+ capDrop: {
772
+ type: "array",
773
+ description: "Linux capabilities to drop",
774
+ items: { type: "string" }
775
+ },
776
+ capAdd: {
777
+ type: "array",
778
+ description: "Linux capabilities to add",
779
+ items: { type: "string" }
780
+ },
781
+ securityOpt: {
782
+ type: "array",
783
+ description: "Docker security options",
784
+ items: { type: "string" }
785
+ },
786
+ ulimits: {
787
+ type: "array",
788
+ description: "Ulimit entries for Docker HostConfig.Ulimits",
789
+ items: {
790
+ type: "object",
791
+ required: ["name", "soft", "hard"],
792
+ additionalProperties: false,
793
+ properties: {
794
+ name: { type: "string" },
795
+ soft: { type: "number" },
796
+ hard: { type: "number" }
797
+ }
798
+ }
799
+ },
800
+ tmpfs: {
801
+ type: "object",
802
+ description: "tmpfs mount paths with options",
803
+ additionalProperties: { type: "string" }
556
804
  }
557
805
  }
558
806
  },