{"version":3,"file":"index.cjs","names":["SandboxAbortError","ProcessHandle","SandboxProcessManager","StringDecoder","timeoutMs","MastraSandbox","Docker","SandboxNotReadyError","SandboxAbortError","posixPath","SandboxError","isImageNotFoundError","path","Server","ServerCredentials","#baseImage","#operations","#dockerOptions","#secrets","#clone","#append","posixPath","#docker","Docker","#plainBuild","#waitForBuild","#queueTail","#build","#getDocker","#built","#resolveSecrets","#buildWithSecrets","#followBuild","execFile"],"sources":["../src/abort.ts","../src/sandbox/process-manager.ts","../src/sandbox/index.ts","../src/provider.ts","../src/template/build-session.ts","../src/template/dockerfile.ts","../src/template/template.ts","../../../packages/_internals/workspace/dist/index.js","../src/template/repo-template.ts"],"sourcesContent":["import { SandboxAbortError } from '@mastra/core/workspace';\n\nexport function createAbortError(signal: AbortSignal, operation: string): SandboxAbortError {\n  return new SandboxAbortError(operation, signal.reason);\n}\n\nexport function throwIfAborted(signal: AbortSignal | undefined, operation: string): void {\n  if (signal?.aborted) throw createAbortError(signal, operation);\n}\n\nexport function isAbortError(error: unknown): boolean {\n  return (\n    error instanceof SandboxAbortError ||\n    (error instanceof Error && (error.name === 'AbortError' || ('code' in error && error.code === 'ABORT_ERR')))\n  );\n}\n\nexport function normalizeAbortError(error: unknown, operation: string): unknown {\n  return error instanceof SandboxAbortError\n    ? error\n    : isAbortError(error)\n      ? new SandboxAbortError(operation, error)\n      : error;\n}\n\nexport function waitForAbortable<T>(\n  promise: Promise<T>,\n  signal: AbortSignal | undefined,\n  operation: string,\n  onAbort?: () => void,\n): Promise<T> {\n  throwIfAborted(signal, operation);\n  if (!signal) return promise;\n\n  return new Promise<T>((resolve, reject) => {\n    const abort = () => {\n      onAbort?.();\n      reject(new SandboxAbortError(operation, signal.reason));\n    };\n    signal.addEventListener('abort', abort, { once: true });\n    promise.then(\n      value => {\n        signal.removeEventListener('abort', abort);\n        resolve(value);\n      },\n      error => {\n        signal.removeEventListener('abort', abort);\n        reject(normalizeAbortError(error, operation));\n      },\n    );\n  });\n}\n","/**\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 type { Duplex } from 'node:stream';\nimport { StringDecoder } from 'node:string_decoder';\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 * Directory (inside the container) where each spawned process records the PGID\n * of its process group. Created with mode 700 so only the (root) exec user can\n * write the PGID files.\n */\nconst PROC_DIR = '/tmp/.mastra-proc';\n\n/**\n * Wrapper (run as the exec command) that places the user command in its own\n * process group and records the group's PGID so kill() can signal the whole\n * group later.\n *\n * Docker's exec-inspect `Pid` is a host/daemon-namespace PID and cannot be used\n * with an in-container `kill`, so we need a container-namespace identity. We use\n * a *kernel-enforced* process group as that identity:\n *\n *   1. `setsid -w` re-execs the command as a new session/process-group leader,\n *      so its PID == PGID. Every descendant inherits that PGID (unless it calls\n *      `setsid` itself) and stays reachable even if it re-parents to PID 1.\n *      `-w` keeps the wrapper (and thus the exec) alive for the whole lifetime\n *      and propagates the child's exit status — without it `setsid` forks and\n *      returns immediately, so the exec would appear to finish while the real\n *      work keeps running.\n *   2. The leader writes its own PID (`$$`) — the PGID — to a private file that\n *      only this process wrote, so the identity is kernel-owned and cannot be\n *      forged by another container process.\n *\n * If `setsid -w` is unavailable in the image (e.g. BusyBox), we degrade\n * gracefully: the command runs directly and we record its PID so kill() can\n * still signal it (descendant coverage is then best-effort). The probe\n * `setsid -w true` also covers images without setsid at all.\n *\n * Positional args: $1 = pgid file path, $2 = user command. The script text is a\n * static constant; runtime values travel only as argv, never interpolated into\n * the command string.\n */\nconst SPAWN_WRAPPER = `\numask 077\nd=\"\\${1%/*}\"\nmkdir -p \"$d\" 2>/dev/null\nchmod 700 \"$d\" 2>/dev/null\nif setsid -w true >/dev/null 2>&1; then\n  exec setsid -w sh -c 'echo $$ > \"$1\" || exit 126; sh -c \"$2\"; ret=$?; rm -f \"$1\" 2>/dev/null; exit $ret' sh \"$1\" \"$2\"\nfi\necho $$ > \"$1\" || exit 126\nsh -c \"$2\"\nret=$?\nrm -f \"$1\" 2>/dev/null\nexit $ret\n`;\n\n/** KILL_SCRIPT exit code when no PGID file was readable or it was empty. */\nconst NO_PGID_EXIT_CODE = 3;\n\n/**\n * Kill script: read the recorded PGID and SIGKILL the whole process group.\n * A negative PID targets the kernel-owned process group, so descendants that\n * re-parented to PID 1 are still caught. We SIGSTOP the\n * group first to freeze fork races, then SIGKILL. The file may not exist yet if\n * kill races the leader's first write, so we briefly wait for it.\n *\n * Positional arg: $1 = pgid file path (static script; no interpolation).\n */\nconst KILL_SCRIPT = `\nf=\"$1\"\ni=0\nwhile [ ! -r \"$f\" ] && [ \"$i\" -lt 40 ]; do sleep 0.05; i=$((i + 1)); done\n# If the PGID was never recorded (file absent/unreadable after the wait, or\n# empty), we have no group to signal or verify — report failure rather than\n# falsely claiming the tree was terminated. Exit code 3 marks this case so\n# kill() can tell it apart from a failed termination (exit 1).\n[ -r \"$f\" ] || exit 3\npgid=$(cat \"$f\" 2>/dev/null)\nrm -f \"$f\" 2>/dev/null\n[ -n \"$pgid\" ] || exit 3\nkill -STOP -\"$pgid\" 2>/dev/null\nkill -KILL -\"$pgid\" 2>/dev/null\n# Fallback for images without setsid: the leader is not a group leader, so also\n# signal it directly.\nkill -KILL \"$pgid\" 2>/dev/null\n# Verify the group is actually gone before reporting success. kill -0 probes\n# for the group's existence without sending a signal, and we poll while it\n# still reports the group alive. When the probe finally fails we must inspect\n# why: ESRCH (\"no such process\") means every member was reaped, so report\n# success; EPERM or any other error means termination is unconfirmed (e.g. a\n# member dropped privileges and became unsignalable), so exit nonzero and let\n# kill() report failure instead of falsely claiming the tree was terminated.\nj=0\nwhile err=$(kill -0 -\"$pgid\" 2>&1); do\n  j=$((j + 1))\n  [ \"$j\" -ge 40 ] && exit 1\n  sleep 0.05\ndone\ncase \"$err\" in\n  *[Ss]uch\\\\ process*) exit 0 ;;\n  *) exit 1 ;;\nesac\n`;\n\n/**\n * Upper bound on how long an early stream 'end' waits for an in-flight kill\n * confirmation before settling without termination metadata. The kill helper's\n * own work is bounded (the KILL_SCRIPT polls for at most ~4s), so this only\n * absorbs daemon round-trips; it exists so a wedged `inspect()` cannot leave\n * wait() pending forever.\n */\nconst TERMINATION_CONFIRMATION_DEADLINE_MS = 10_000;\n\n/**\n * Resolves when `termination` settles, or after\n * TERMINATION_CONFIRMATION_DEADLINE_MS — whichever comes first. Never rejects.\n */\nfunction waitForTermination(termination: Promise<boolean>): Promise<void> {\n  return new Promise<void>(resolve => {\n    const timer = setTimeout(resolve, TERMINATION_CONFIRMATION_DEADLINE_MS);\n    const done = () => {\n      clearTimeout(timer);\n      resolve();\n    };\n    termination.then(done, done);\n  });\n}\n\n/**\n * Resolves with `work`'s value, or `fallback` if it has not settled within `ms`.\n * Never rejects. Bounds a single daemon round-trip, so one call that never\n * answers cannot leave wait() pending past its deadline.\n */\nfunction withDeadline<T>(work: Promise<T>, ms: number, fallback: T): Promise<T> {\n  return new Promise<T>(resolve => {\n    const timer = setTimeout(() => resolve(fallback), Math.max(0, ms));\n    const done = (value: T) => {\n      clearTimeout(timer);\n      resolve(value);\n    };\n    work.then(done, () => done(fallback));\n  });\n}\n\n/**\n * Polls `exec.inspect()` until the exec reports it is no longer running, bounded\n * by `deadline` (an absolute `Date.now()` timestamp). A stream can close without\n * 'end' while the process is still alive, and settling from inspect then would\n * publish an exit for a process that never exited — but waiting unbounded could\n * leave wait() pending forever, so each call is bounded too. Returns the last\n * inspect result, which may still report Running: true if the bound was reached,\n * or undefined if no call settled in time.\n */\nasync function waitForExecToStop(exec: Exec, deadline: number): Promise<ExecInspectInfo | undefined> {\n  let info: ExecInspectInfo | undefined;\n  while (Date.now() < deadline) {\n    info = await withDeadline<ExecInspectInfo | undefined>(exec.inspect(), deadline - Date.now(), undefined);\n    if (!info || !info.Running) return info;\n    await new Promise(resolve => setTimeout(resolve, 10));\n  }\n  return info;\n}\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  /** @internal Set by the timeout path to distinguish timeout kills from explicit kills */\n  _timedOut = false;\n  /**\n   * @internal In-flight kill confirmation, set while kill() is verifying the\n   * process group is gone. An early stream 'end' awaits it (bounded) so\n   * termination metadata is not dropped when the target's stream closes first.\n   */\n  _terminationPromise: Promise<boolean> | null = null;\n  private _waitPromise: Promise<CommandResult> | null = null;\n  private _stdinStream: Duplex | null = null;\n  private _execStream: NodeJS.ReadWriteStream | null = null;\n  /** @internal Container path of the file holding this process group's PGID. */\n  readonly _pgidFile: string;\n\n  constructor(\n    exec: Exec,\n    container: Container,\n    startTime: number,\n    stdinStream: Duplex | null,\n    pgidFile: string,\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    this._pgidFile = pgidFile;\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    // A kill already in flight owns the confirmation for this process, so share\n    // it instead of starting a second helper. Otherwise the second helper\n    // replaces `_terminationPromise` and clears it once it settles, leaving an\n    // early stream 'end' nothing to await while the first helper is still\n    // running — it would settle as a natural exit, and the first helper's later\n    // success could no longer correct a result that already reported one.\n    if (this._terminationPromise) return this._terminationPromise;\n\n    // Publish the in-flight confirmation before awaiting it. Killing the target\n    // tears its own exec stream down, so an early stream 'end' may arrive while\n    // this is still running — it waits on this promise instead of settling as if\n    // the command had exited on its own.\n    const termination = this._runKillHelper();\n    this._terminationPromise = termination;\n    try {\n      return await termination;\n    } finally {\n      if (this._terminationPromise === termination) this._terminationPromise = null;\n    }\n  }\n\n  /**\n   * Runs the kill helper and verifies the process group is gone before reporting\n   * success, so a `true` result means the targets have actually stopped.\n   */\n  private async _runKillHelper(): Promise<boolean> {\n    try {\n      // Kill the process group inside the *container's* PID namespace. We must\n      // not use exec.inspect().Pid here: that is the host/daemon-namespace PID\n      // and does not correspond to PIDs an in-container `kill` can address. The\n      // recorded PGID targets a kernel-owned group, so descendants that were\n      // re-parented to PID 1 are still caught.\n      const killExec = await this._container.exec({\n        // Static script; the pgid file path is passed as $1 (sh sets $0='sh',\n        // $1=path) so no runtime value is ever interpolated into the command.\n        Cmd: ['sh', '-c', KILL_SCRIPT, 'sh', this._pgidFile],\n        AttachStdout: false,\n        AttachStderr: false,\n      });\n      const killStream = await killExec.start({});\n\n      try {\n        // Exec.start() resolves when the exec stream is opened, not when the\n        // helper script exits. Poll inspect() until it finishes so we only report\n        // success once the process tree has actually been killed — otherwise\n        // wait() could resolve with exit 137 while targets are still running.\n        let killInfo = await killExec.inspect();\n        while (killInfo.Running) {\n          await new Promise(resolve => setTimeout(resolve, 10));\n          killInfo = await killExec.inspect();\n        }\n        if (killInfo.ExitCode !== 0) {\n          // Exit 3 means no PGID was recorded. The spawn wrapper removes the file\n          // when the command exits on its own, so a kill racing a natural exit\n          // lands here. If the command's exec has stopped there is nothing to\n          // kill: report false quietly and let the natural exit result stand.\n          // Every other non-zero exit (e.g. unconfirmed group termination) stays loud.\n          if (killInfo.ExitCode === NO_PGID_EXIT_CODE) {\n            const selfInfo = await this._exec.inspect().catch(() => undefined);\n            if (selfInfo && !selfInfo.Running) return false;\n          }\n          throw new Error(`kill helper exited with code ${killInfo.ExitCode}`);\n        }\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      } finally {\n        killStream.destroy();\n      }\n    } catch (error: unknown) {\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    return new Promise<void>((resolve, reject) => {\n      this._stdinStream!.write(data, error => (error ? reject(error) : resolve()));\n    });\n  }\n\n  async closeStdin(): 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    const stream = this._stdinStream;\n    if (stream.writableEnded) return;\n    await new Promise<void>(resolve => stream.end(resolve));\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: { defaultTimeout?: number } = {}) {\n    super();\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    // Private file (unguessable name) where the command's process group records\n    // its PGID, so kill() can signal the whole kernel-owned group later.\n    const pgidFile = `${PROC_DIR}/${globalThis.crypto.randomUUID()}`;\n    const envArray = Object.entries({ ...options.env })\n      .filter((entry): entry is [string, string] => entry[1] !== undefined)\n      .map(([k, v]) => `${k}=${v}`);\n\n    // `stdinMode: 'ignore'` leaves stdin unattached so the command sees EOF. A\n    // command that reads stdin (a bare `rg`/`grep`/`cat` with no path argument)\n    // blocks forever when stdin is attached but nothing ever writes to it.\n    const attachStdin = options.stdinMode !== 'ignore';\n\n    // Create exec instance. The command is wrapped so it runs in its own process\n    // group (via setsid) and records its PGID; args travel positionally so the\n    // wrapper text stays a static constant.\n    const exec = await container.exec({\n      Cmd: ['sh', '-c', SPAWN_WRAPPER, 'sh', pgidFile, command],\n      AttachStdout: true,\n      AttachStderr: true,\n      AttachStdin: attachStdin,\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: attachStdin });\n\n    const startTime = Date.now();\n    // A null stdin stream makes sendStdin/closeStdin report the process was not\n    // started with stdin support, matching `stdinMode: 'ignore'`.\n    const handle = new DockerProcessHandle(exec, container, startTime, attachStdin ? stream : null, pgidFile, 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      // Frame boundaries are not UTF-8 character boundaries, so a multibyte\n      // character can be split across frames. Each stream gets its own decoder\n      // because stdout and stderr frames interleave.\n      const stdoutDecoder = new StringDecoder('utf8');\n      const stderrDecoder = new StringDecoder('utf8');\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);\n          if (type === 1) {\n            const text = stdoutDecoder.write(payload);\n            if (text) handle.emitStdout(text);\n          } else if (type === 2) {\n            const text = stderrDecoder.write(payload);\n            if (text) handle.emitStderr(text);\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      // Flush any incomplete trailing sequence before anything reads the final output.\n      let decodersFlushed = false;\n      const flushDecoders = () => {\n        if (decodersFlushed) return;\n        decodersFlushed = true;\n        const stdoutRest = stdoutDecoder.end();\n        if (stdoutRest) handle.emitStdout(stdoutRest);\n        const stderrRest = stderrDecoder.end();\n        if (stderrRest) handle.emitStderr(stderrRest);\n      };\n\n      // Every stream event settles through here and only the first one wins.\n      // Previously 'end' resolved first and 'close' — the only path that attached\n      // `killed`/`timedOut` — bailed out because the exit code was already set, so\n      // a kill that tore the stream down before confirming termination produced a\n      // result indistinguishable from a natural exit.\n      let settled = false;\n      const settle = (exitCode: number, metadata: Partial<CommandResult> = {}) => {\n        if (settled) return;\n        settled = true;\n        flushDecoders();\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          ...metadata,\n        });\n      };\n\n      // Termination metadata rides on whichever path settles first, so a killed\n      // process never looks like a natural exit. It is read from the handle, which\n      // only records termination once the kill helper confirmed it (or the timeout\n      // path forced the stream closed).\n      const settleTerminated = () => {\n        settle(137, { killed: true, timedOut: handle._timedOut }); // 137 = SIGKILL\n      };\n\n      stream.on('end', async () => {\n        // Killing the target tears its own exec stream down, so 'end' can arrive\n        // while kill() is still confirming the process group is gone. Wait for that\n        // confirmation (bounded) before settling: settling now would publish a\n        // termination-free result and disarm 'close', the only other path carrying\n        // `killed`. The wait is unconditional — the timeout path records `_killed`\n        // optimistically before asking kill() to confirm, so gating on it would let\n        // this settle while the kill helper is still running and a failed\n        // confirmation could no longer be reflected.\n        if (handle._terminationPromise) {\n          await waitForTermination(handle._terminationPromise);\n        }\n        if (settled) return;\n\n        if (handle._killed) {\n          settleTerminated();\n          return;\n        }\n\n        // Natural exit — get exit code from exec inspect\n        try {\n          const info = await exec.inspect();\n          settle(info.ExitCode ?? 1);\n        } catch {\n          settle(1);\n        }\n      });\n\n      // 'close' fires both on a natural stream end and when kill()/timeout tears the\n      // stream down. Wait for any in-flight termination confirmation first — the\n      // timeout path records `_killed` before kill() confirms, so settling here\n      // without waiting would publish the result while the helper is still running.\n      // The wait is unconditional (like 'end'/'error') rather than gated on\n      // `_killed`, so a close that races an unconfirmed kill still observes the\n      // final state instead of returning while the confirmation is pending.\n      stream.on('close', async () => {\n        // One deadline covers the whole path, so waiting on an in-flight kill\n        // confirmation cannot stack on top of a fresh exec poll: the bound the\n        // settlement is documented to have is the bound it actually has.\n        const deadline = Date.now() + TERMINATION_CONFIRMATION_DEADLINE_MS;\n        if (handle._terminationPromise) {\n          await waitForTermination(handle._terminationPromise);\n        }\n        if (settled) return;\n\n        if (handle._killed) {\n          settleTerminated();\n          return;\n        }\n\n        // Docker multiplexed streams normally emit 'end' before 'close' for natural\n        // exits, but a stream torn down by other means may close without one. A\n        // closed stream does not mean the exec finished, though, so poll (bounded)\n        // while it is still running rather than publishing an exit for a live\n        // process; settle afterwards so wait() cannot hang once the bound elapses.\n        try {\n          const info = await waitForExecToStop(exec, deadline);\n          if (settled) return;\n          // A termination can land while the poll is running (a timeout path records\n          // `_killed` before kill() confirms, and kill() itself sets it once the\n          // helper has verified the process group is gone). Report the termination\n          // rather than a bare exit code, or the result drops `killed`/`timedOut`.\n          if (handle._killed) {\n            settleTerminated();\n            return;\n          }\n          settle(info?.ExitCode ?? 1);\n        } catch {\n          settle(1);\n        }\n      });\n\n      stream.on('error', async () => {\n        // Tearing the hijacked exec socket down can surface as a stream error\n        // (ECONNRESET) rather than 'end'. Same rule as 'end': a kill that is still\n        // confirming must be awaited (bounded) before this settles, otherwise the\n        // error path publishes an exit-1 result with no `killed`/`timedOut` and the\n        // later 'close' settlement has nothing left to correct.\n        if (handle._terminationPromise) {\n          await waitForTermination(handle._terminationPromise);\n        }\n        if (settled) return;\n\n        if (handle._killed) {\n          settleTerminated();\n          return;\n        }\n        flushDecoders();\n        settle(1, { stderr: handle.stderr || 'Stream error' });\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          // Record the timeout kill up front so the 'close' settlement that\n          // follows _destroyStream() carries the metadata. The kill confirmation\n          // is still in flight here, which is safe now that 'end' and 'error'\n          // await it before settling — a helper that fails is followed by\n          // forceClose(), which keeps this flag and tears the stream down anyway.\n          handle._killed = true;\n          handle._timedOut = true;\n          // Await kill() so the process tree is actually terminated before the\n          // stream is torn down. Destroying the stream first would resolve\n          // wait() with exit 137 while the targets are still running — the exact\n          // bug this fix addresses. Only force-destroy the stream if kill()\n          // fails to make progress, as a last resort to unblock wait().\n          const forceClose = () => {\n            if (handle.exitCode === undefined) {\n              handle._killed = true;\n              handle._destroyStream();\n            }\n          };\n          handle\n            .kill()\n            .then(killed => {\n              if (!killed) forceClose();\n            })\n            .catch(forceClose);\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 { posix as posixPath } from 'node:path';\nimport { isDeepStrictEqual } from 'node:util';\nimport type { RequestContext } from '@mastra/core/di';\nimport type {\n  SandboxInfo,\n  ProviderStatus,\n  MastraSandboxOptions,\n  SandboxCloneOptions,\n  SandboxFileInput,\n  SandboxStartOptions,\n  WriteFilesOptions,\n} from '@mastra/core/workspace';\nimport {\n  MastraSandbox,\n  SandboxAbortError,\n  SandboxError,\n  SandboxNotReadyError,\n  validateSandboxFileMode,\n} from '@mastra/core/workspace';\nimport Docker from 'dockerode';\nimport type { Container, ContainerInfo } from 'dockerode';\nimport { pack as tarPack } from 'tar-stream';\nimport { normalizeAbortError, throwIfAborted } from '../abort';\nimport type { DockerRepoTemplateResolveOptions } from '../template/repo-template';\nimport type { DockerTemplate } from '../template/template';\nimport { DockerProcessManager } from './process-manager';\n\nconst LOG_PREFIX = '[DockerSandbox]';\n\nexport interface DockerSandboxStartOptions extends SandboxStartOptions {\n  /** Cancel repository-template resolution or a lazy template build. */\n  abortSignal?: AbortSignal;\n}\n\n/** A prepared template, or a resolver producing one (see `DockerSandboxOptions.template`). */\nexport type DockerTemplateSpec =\n  | DockerTemplate\n  | ((options?: DockerRepoTemplateResolveOptions) => DockerTemplate | Promise<DockerTemplate>);\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/** Options applied to a `volume` mount. */\ntype DockerSandboxVolumeMount = {\n  type: 'volume';\n  /** Absolute path of the mount inside the container. */\n  target: string;\n  /** Named volume to mount. */\n  source: string;\n  /** Mount read-only. */\n  readOnly?: boolean;\n  /** Options applied to the named volume. */\n  volumeOptions?: {\n    /** Mount a subdirectory of the named volume (Docker Engine 26.0+). */\n    subpath?: string;\n    /** Disable copying data from the container path into the volume. */\n    noCopy?: boolean;\n    /** Labels applied to the volume when it is created. */\n    labels?: Record<string, string>;\n  };\n};\n\n/** Options applied to a `bind` mount. */\ntype DockerSandboxBindMount = {\n  type: 'bind';\n  /** Absolute path of the mount inside the container. */\n  target: string;\n  /** Host path to bind into the container. */\n  source: string;\n  /** Mount read-only. */\n  readOnly?: boolean;\n  /** Options applied to the bind mount. */\n  bindOptions?: {\n    /** Bind propagation mode. */\n    propagation?: 'private' | 'rprivate' | 'shared' | 'rshared' | 'slave' | 'rslave';\n  };\n};\n\n/** Options applied to a `tmpfs` mount. */\ntype DockerSandboxTmpfsMount = {\n  type: 'tmpfs';\n  /** Absolute path of the mount inside the container. */\n  target: string;\n  /** Mount read-only. */\n  readOnly?: boolean;\n  /** Options applied to the tmpfs mount. */\n  tmpfsOptions?: {\n    /** Size of the tmpfs mount in bytes. */\n    sizeBytes?: number;\n    /** File mode of the tmpfs mount, in octal (e.g. 0o1777). */\n    mode?: number;\n  };\n};\n\n/**\n * A single Docker mount, mapped 1:1 onto an entry of `HostConfig.Mounts`.\n *\n * Unlike `volumes` (which maps to `HostConfig.Binds` / the `-v` syntax), mounts\n * can express options that `Binds` cannot — most notably `volumeOptions.subpath`,\n * which mounts a subdirectory of a named volume. Requires Docker Engine 26.0+\n * (API v1.45+) for `subpath` support.\n *\n * This is a discriminated union on `type`: `volume` and `bind` mounts require a\n * `source` and only accept their own option group, while `tmpfs` mounts take no\n * `source`. These invariants mirror what Docker enforces at container creation.\n */\nexport type DockerSandboxMount = DockerSandboxVolumeMount | DockerSandboxBindMount | DockerSandboxTmpfsMount;\n\n// =============================================================================\n// Docker Sandbox Options\n// =============================================================================\n\nexport interface DockerSandboxOptions extends Omit<MastraSandboxOptions, 'processes'> {\n  /** Unique identifier for this sandbox instance. Used for label-based reconnection. */\n  id?: string;\n  /**\n   * Container display name passed to Docker as `--name`.\n   * Characters outside `[a-zA-Z0-9_.-]` are replaced with `-` and the result\n   * is prefixed if it would not start with an alphanumeric character.\n   * @default the sandbox `id`\n   */\n  name?: string;\n  /** Docker image to use.\n   * @default 'node:22-slim'\n   */\n  image?: string;\n  /**\n   * Prepared baseline to boot from, as an alternative to `image`. The\n   * template is built (or its cached image reused) lazily on `start()`, and\n   * the container boots from the resulting image. A function form is resolved\n   * once per `start()` that creates a container, so head-pinned repo\n   * templates can re-resolve on each new sandbox.\n   *\n   * When `workingDirectory` is not set, the template's last `setWorkdir`\n   * becomes the sandbox working directory. Mutually exclusive with `image`.\n   */\n  template?: DockerTemplateSpec;\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  /**\n   * Run an init process (tini) as PID 1 to reap zombie children (HostConfig.Init).\n   * Without this, processes orphaned by a command (e.g. after a timeout/kill) remain\n   * as zombies and keep counting against `pidsLimit`.\n   * @default true\n   */\n  init?: boolean;\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  /**\n   * Mounts mapped 1:1 onto `HostConfig.Mounts`.\n   *\n   * Use this instead of `volumes` when you need mount options that Docker's\n   * `-v`/`HostConfig.Binds` syntax cannot express — in particular\n   * `volumeOptions.subpath` (mount a subdirectory of a named volume). `volumes`\n   * and `mounts` may be combined; both are passed through to Docker.\n   */\n  mounts?: DockerSandboxMount[];\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   * @deprecated Use `workingDirectory` (the base sandbox option) instead.\n   * When both are set, `workingDirectory` wins.\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 _containerName: string;\n  /** Image the container boots from; rewritten by a template resolution on `start()`. */\n  private _image: string;\n  private readonly _templateSpec?: DockerTemplateSpec;\n  private readonly _workingDirectoryWasSet: boolean;\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 _init: boolean;\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 _mounts?: DockerSandboxMount[];\n  private readonly _labels: Record<string, string>;\n  private readonly _instructionsOverride?: InstructionsOption;\n  private readonly _constructorOptions: DockerSandboxOptions;\n\n  /**\n   * The effective container working directory. Narrowed to `string`: the\n   * constructor always resolves a value (option, deprecated alias, or\n   * `/workspace`), so unlike the base getter this never returns `undefined`.\n   */\n  override get workingDirectory(): string {\n    return this._workingDirectory!;\n  }\n\n  constructor(options: DockerSandboxOptions = {}) {\n    const processManager = new DockerProcessManager({\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._containerName = sanitizeContainerName(options.name ?? this.id);\n    if (options.image !== undefined && options.template !== undefined) {\n      throw new TypeError('DockerSandbox: `image` and `template` are mutually exclusive');\n    }\n    this._templateSpec = options.template;\n    this._image = options.image ?? 'node:22-slim';\n    this._workingDirectoryWasSet = options.workingDirectory !== undefined || options.workingDir !== undefined;\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._init = options.init ?? true;\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._mounts = options.mounts;\n    this.setWorkingDirectory(options.workingDirectory ?? 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    this._constructorOptions = { ...options };\n  }\n\n  /**\n   * Construct a sibling `DockerSandbox` that inherits this sandbox's\n   * configuration (image, resource limits, security options, labels,\n   * connection options) with per-instance overrides.\n   *\n   * Performs no I/O — the sandbox clone provisions (or reconnects to an\n   * existing container labelled with the same logical `id`) on its own\n   * `start()`. Use it when one configured sandbox acts as the template for a\n   * fleet of independent sandboxes (e.g. one per project).\n   *\n   * `options.idleTimeoutMinutes` is ignored (Docker containers have no\n   * provider-side idle teardown; `timeout` here is a command timeout), and\n   * `options.sandboxId` is ignored because reconnection is by logical `id`.\n   */\n  clone(options: SandboxCloneOptions = {}): DockerSandbox {\n    const { id: _id, name: _name, ...base } = this._constructorOptions;\n    return new DockerSandbox({\n      ...base,\n      ...(options.id !== undefined && { id: options.id }),\n      ...(options.env !== undefined && { env: options.env }),\n      ...(options.workingDirectory !== undefined && { workingDirectory: options.workingDirectory }),\n    });\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(options: DockerSandboxStartOptions = {}): Promise<void> {\n    const { abortSignal } = options;\n    throwIfAborted(abortSignal, 'start Docker sandbox');\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      // The container was created with a working directory (possibly derived\n      // from a template); keep resolving relative paths against it rather than\n      // this instance's default.\n      const reconnectedWorkingDir = info.Config?.WorkingDir;\n      if (!this._workingDirectoryWasSet && reconnectedWorkingDir) {\n        this.setWorkingDirectory(reconnectedWorkingDir);\n      }\n\n      // Report the image the existing container actually runs, not this instance's default.\n      if (info.Config?.Image) {\n        this._image = info.Config.Image;\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    await this._resolveTemplate(abortSignal);\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      name: this._containerName,\n      Image: this._image,\n      Cmd: this._command,\n      Env: envArray,\n      WorkingDir: this.workingDirectory,\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        Init: this._init,\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        Mounts: this._mounts?.map(toDockerMount),\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      ['Mounts', this._mounts?.map(toDockerMount)],\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  // File Upload\n  // ---------------------------------------------------------------------------\n\n  /**\n   * Bulk-write files into the container's filesystem using Docker's native\n   * archive upload (`putArchive`), the same mechanism as `docker cp`.\n   *\n   * Behavior:\n   * - Requires a started sandbox. Throws {@link SandboxNotReadyError} otherwise\n   *   (Docker containers are not auto-started by this method).\n   * - Absolute paths are used as-is; relative paths resolve against\n   *   {@link workingDirectory}.\n   * - Missing parent directories are created automatically.\n   * - Existing destinations are overwritten (contents and mode).\n   * - Exact bytes are preserved for both `string` and `Buffer` content,\n   *   including empty files and binary data.\n   * - New files use the per-file `mode` when provided (validated integer\n   *   `0o001`–`0o777`), otherwise `0644`; directories created implicitly default\n   *   to Docker's `0755`. Overwriting a file replaces its mode with the\n   *   requested `mode` (or `0644` when omitted).\n   * - Not atomic across files: on failure the promise rejects and earlier or\n   *   partially written files may remain.\n   *\n   * Cancellation (`options.abortSignal`):\n   * - If the signal is already aborted, rejects with {@link SandboxAbortError}\n   *   before creating the archive or starting the upload.\n   * - If the signal aborts during transfer, the underlying `putArchive` request\n   *   is terminated by destroying the tar stream (which ends the request body),\n   *   and the promise rejects with {@link SandboxAbortError}.\n   * - Upload and cancellation race: an upload that completes before the abort is\n   *   observed resolves normally.\n   * - No rollback: files Docker already received or extracted may remain. The\n   *   daemon may continue extraction after rejection, so the caller is\n   *   responsible for any cleanup or sandbox disposal.\n   * - Behavior is unchanged when no signal is supplied.\n   *\n   * @throws {SandboxNotReadyError} If the sandbox has not been started.\n   * @throws {SandboxAbortError} If the write is cancelled via `options.abortSignal`.\n   * @throws {SandboxError} If the archive upload fails.\n   */\n  async writeFiles(files: SandboxFileInput[], options?: WriteFilesOptions): Promise<void> {\n    const container = this.container;\n\n    const signal = options?.abortSignal;\n    if (signal?.aborted) throw new SandboxAbortError('writeFiles');\n\n    if (files.length === 0) return;\n\n    const pack = tarPack();\n    for (const file of files) {\n      if (file.mode !== undefined) validateSandboxFileMode(file.mode);\n      const resolved = posixPath.isAbsolute(file.path)\n        ? posixPath.normalize(file.path)\n        : posixPath.resolve(this.workingDirectory, file.path);\n      const data = Buffer.isBuffer(file.content) ? file.content : Buffer.from(file.content);\n      const mode = file.mode ?? 0o644;\n      // tar entries are relative; strip the leading slash so extraction at `/`\n      // lands the file at its intended absolute path.\n      pack.entry({ name: resolved.replace(/^\\/+/, ''), size: data.length, mode }, data);\n    }\n    pack.finalize();\n\n    // Destroying the tar stream ends the putArchive request body, which\n    // terminates the in-flight HTTP upload to the Docker daemon. The\n    // abortSignal is also forwarded to putArchive for transports that observe\n    // it; it is harmless when ignored.\n    const onAbort = () => pack.destroy();\n    if (signal) signal.addEventListener('abort', onAbort, { once: true });\n\n    try {\n      await container.putArchive(pack, { path: '/', abortSignal: signal });\n    } catch (error) {\n      if (signal?.aborted) throw new SandboxAbortError('writeFiles');\n      throw new SandboxError(\n        `Failed to write files to sandbox: ${error instanceof Error ? error.message : String(error)}`,\n        'EXECUTION_FAILED',\n        { reason: 'write_files_failed' },\n      );\n    } finally {\n      if (signal) signal.removeEventListener('abort', onAbort);\n    }\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.workingDirectory}.`,\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.workingDirectory,\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   * Resolve the `template` option (if any) into the image to boot from,\n   * building it when no cached image exists. Runs on every `start()` that\n   * creates a container, so a resolver-form template re-resolves each time.\n   * Adopts the template's workdir unless the sandbox was given one explicitly.\n   */\n  private async _resolveTemplate(abortSignal?: AbortSignal): Promise<void> {\n    if (!this._templateSpec) return;\n    throwIfAborted(abortSignal, 'start Docker sandbox');\n    let template: DockerTemplate;\n    try {\n      template =\n        typeof this._templateSpec === 'function' ? await this._templateSpec({ abortSignal }) : this._templateSpec;\n    } catch (error) {\n      throw normalizeAbortError(error, 'start Docker sandbox');\n    }\n    throwIfAborted(abortSignal, 'start Docker sandbox');\n    // Build on this sandbox's daemon, which may differ from the template's default.\n    const result = await template.build({ docker: this._docker, abortSignal });\n    if (result.status !== 'ready') {\n      throw new SandboxError(`Docker template build failed: ${result.error ?? 'unknown error'}`, 'START_FAILED', {\n        templateId: result.templateId,\n        reason: 'template_build_failed',\n      });\n    }\n    this._image = result.templateId;\n    if (!this._workingDirectoryWasSet && template.workdir !== undefined) {\n      this.setWorkingDirectory(template.workdir);\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\n// Docker container name regex (`^[a-zA-Z0-9][a-zA-Z0-9_.-]+$`) — first char must be\n// alphanumeric, remaining chars from `[a-zA-Z0-9_.-]`, total length ≥ 2.\nfunction sanitizeContainerName(value: string): string {\n  const replaced = value.replace(/[^a-zA-Z0-9_.-]/g, '-');\n  const withLeading = /^[a-zA-Z0-9]/.test(replaced) ? replaced : `s-${replaced}`;\n  return withLeading.length >= 2 ? withLeading : `${withLeading}-sandbox`;\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 toDockerMount(mount: DockerSandboxMount): Docker.MountSettings {\n  const settings: Docker.MountSettings = {\n    Type: mount.type,\n    Target: mount.target,\n    Source: mount.type === 'tmpfs' ? '' : mount.source,\n  };\n\n  if (mount.readOnly !== undefined) settings.ReadOnly = mount.readOnly;\n\n  if (mount.type === 'volume' && mount.volumeOptions) {\n    const { subpath, noCopy, labels } = mount.volumeOptions;\n    // The @types/dockerode VolumeOptions marks NoCopy/Labels/DriverConfig as\n    // required, but the Docker API treats them as optional; build a partial.\n    const volumeOptions: Record<string, unknown> = {};\n    if (subpath !== undefined) volumeOptions.Subpath = subpath;\n    if (noCopy !== undefined) volumeOptions.NoCopy = noCopy;\n    if (labels !== undefined) volumeOptions.Labels = labels;\n    if (Object.keys(volumeOptions).length > 0) {\n      settings.VolumeOptions = volumeOptions as Docker.MountSettings['VolumeOptions'];\n    }\n  }\n\n  if (mount.type === 'bind' && mount.bindOptions?.propagation !== undefined) {\n    settings.BindOptions = { Propagation: mount.bindOptions.propagation };\n  }\n\n  if (mount.type === 'tmpfs' && mount.tmpfsOptions) {\n    const { sizeBytes, mode } = mount.tmpfsOptions;\n    const tmpfsOptions: Record<string, unknown> = {};\n    if (sizeBytes !== undefined) tmpfsOptions.SizeBytes = sizeBytes;\n    if (mode !== undefined) tmpfsOptions.Mode = mode;\n    if (Object.keys(tmpfsOptions).length > 0) {\n      settings.TmpfsOptions = tmpfsOptions as Docker.MountSettings['TmpfsOptions'];\n    }\n  }\n\n  return settings;\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    Mounts: 'mounts',\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  /** Mounts mapped 1:1 onto Docker HostConfig.Mounts (supports volume subpath) */\n  mounts?: DockerSandboxOptions['mounts'];\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      mounts: {\n        type: 'array',\n        description: 'Mounts mapped 1:1 onto Docker HostConfig.Mounts (supports volume subpath)',\n        items: {\n          oneOf: [\n            {\n              type: 'object',\n              required: ['type', 'target', 'source'],\n              additionalProperties: false,\n              properties: {\n                type: { const: 'volume' },\n                target: { type: 'string' },\n                source: { type: 'string' },\n                readOnly: { type: 'boolean' },\n                volumeOptions: {\n                  type: 'object',\n                  additionalProperties: false,\n                  properties: {\n                    subpath: { type: 'string' },\n                    noCopy: { type: 'boolean' },\n                    labels: { type: 'object', additionalProperties: { type: 'string' } },\n                  },\n                },\n              },\n            },\n            {\n              type: 'object',\n              required: ['type', 'target', 'source'],\n              additionalProperties: false,\n              properties: {\n                type: { const: 'bind' },\n                target: { type: 'string' },\n                source: { type: 'string' },\n                readOnly: { type: 'boolean' },\n                bindOptions: {\n                  type: 'object',\n                  additionalProperties: false,\n                  properties: {\n                    propagation: {\n                      type: 'string',\n                      enum: ['private', 'rprivate', 'shared', 'rshared', 'slave', 'rslave'],\n                    },\n                  },\n                },\n              },\n            },\n            {\n              type: 'object',\n              required: ['type', 'target'],\n              additionalProperties: false,\n              properties: {\n                type: { const: 'tmpfs' },\n                target: { type: 'string' },\n                readOnly: { type: 'boolean' },\n                tmpfsOptions: {\n                  type: 'object',\n                  additionalProperties: false,\n                  properties: {\n                    sizeBytes: { type: 'number' },\n                    mode: { type: 'number' },\n                  },\n                },\n              },\n            },\n          ],\n        },\n      },\n    },\n  },\n  createSandbox: (config: DockerProviderConfig) => new DockerSandbox(config as DockerSandboxOptions),\n};\n","/**\n * BuildKit session that serves build secrets to the daemon.\n *\n * `docker build` with BuildKit (`version=2`) can attach a long-lived gRPC\n * \"session\" that the daemon calls back into for things it needs mid-build.\n * `RUN --mount=type=secret,id=X` is resolved by calling\n * `/moby.buildkit.secrets.v1.Secrets/GetSecret` on that session, so the value\n * exists only in the tmpfs mount for the duration of that one RUN — never as a\n * build arg, layer, history entry, or cache metadata.\n *\n * dockerode's own session helper only registers the registry-auth service and\n * overwrites any `session` id passed to `buildImage`, so this module dials the\n * hijacked `/session` endpoint itself and registers both services.\n */\nimport { Server, ServerCredentials, type ServiceDefinition, type UntypedServiceImplementation } from '@grpc/grpc-js';\nimport type Docker from 'dockerode';\nimport { createAbortError, throwIfAborted } from '../abort';\n\nexport const SECRETS_GET_METHOD = '/moby.buildkit.secrets.v1.Secrets/GetSecret';\nconst AUTH_CREDENTIALS_METHOD = '/moby.filesync.v1.Auth/Credentials';\n\nexport interface BuildSession {\n  id: string;\n  close(): void;\n}\n\n/**\n * Open a session that answers `GetSecret` from `secrets`. The returned id must\n * be sent as the `session` query parameter of the build request.\n */\nexport function openBuildSession(\n  docker: Docker,\n  secrets: Record<string, string>,\n  abortSignal?: AbortSignal,\n): Promise<BuildSession> {\n  throwIfAborted(abortSignal, 'build Docker template');\n  const id = globalThis.crypto.randomUUID();\n  return new Promise((resolve, reject) => {\n    let settled = false;\n    const abort = () => {\n      if (settled || !abortSignal) return;\n      settled = true;\n      reject(createAbortError(abortSignal, 'build Docker template'));\n    };\n    abortSignal?.addEventListener('abort', abort, { once: true });\n    docker.modem.dial(\n      {\n        method: 'POST',\n        path: '/session',\n        hijack: true,\n        headers: {\n          Upgrade: 'h2c',\n          'X-Docker-Expose-Session-Uuid': id,\n          'X-Docker-Expose-Session-Name': 'mastra-docker-template',\n          // The daemon only calls methods the client advertises.\n          'X-Docker-Expose-Session-Grpc-Method': [SECRETS_GET_METHOD, AUTH_CREDENTIALS_METHOD],\n        },\n        statusCodes: { 200: true, 500: 'server error' },\n      },\n      (err: Error | null, socket: unknown) => {\n        if (settled) {\n          (socket as { end?(): void } | undefined)?.end?.();\n          return;\n        }\n        settled = true;\n        abortSignal?.removeEventListener('abort', abort);\n        if (err) {\n          reject(abortSignal?.aborted ? createAbortError(abortSignal, 'build Docker template') : err);\n          return;\n        }\n        const server = new Server();\n        server.createConnectionInjector(ServerCredentials.createInsecure()).injectConnection(socket as never);\n        server.addService(secretsService, {\n          GetSecret(\n            call: { request: GetSecretRequest },\n            callback: (err: Error | null, res?: GetSecretResponse) => void,\n          ) {\n            const value = Object.hasOwn(secrets, call.request.id) ? secrets[call.request.id] : undefined;\n            if (value === undefined) {\n              callback(\n                Object.assign(new Error(`no build secret registered with id '${call.request.id}'`), { code: 5 }),\n              );\n              return;\n            }\n            callback(null, { data: Buffer.from(value, 'utf8') });\n          },\n        } as UntypedServiceImplementation);\n        server.addService(authService, {\n          Credentials(_call: unknown, callback: (err: Error | null, res?: Record<string, never>) => void) {\n            callback(null, {});\n          },\n        } as UntypedServiceImplementation);\n        resolve({\n          id,\n          close() {\n            server.forceShutdown();\n            (socket as { end(): void }).end();\n          },\n        });\n      },\n    );\n  });\n}\n\n// ---------------------------------------------------------------------------\n// Wire format\n//\n// The two messages involved are small enough that hand-rolling the protobuf\n// encoding beats loading .proto files at runtime (which would not survive\n// bundling).\n//\n//   message GetSecretRequest  { string ID = 1; map<string,string> annotations = 2; }\n//   message GetSecretResponse { bytes data = 1; }\n//   message CredentialsResponse { string Username = 1; string Secret = 2; }\n// ---------------------------------------------------------------------------\n\nexport interface GetSecretRequest {\n  id: string;\n}\nexport interface GetSecretResponse {\n  data: Buffer;\n}\n\n/** @internal exported for tests */\nexport function decodeGetSecretRequest(buffer: Buffer): GetSecretRequest {\n  let offset = 0;\n  let id = '';\n  const readVarint = (): number => {\n    let result = 0;\n    let shift = 0;\n    for (;;) {\n      if (offset >= buffer.length) throw new Error('truncated varint');\n      const byte = buffer[offset++]!;\n      result += (byte & 0x7f) * 2 ** shift;\n      if ((byte & 0x80) === 0) return result;\n      shift += 7;\n    }\n  };\n  while (offset < buffer.length) {\n    const key = readVarint();\n    const field = Math.floor(key / 8);\n    const wireType = key % 8;\n    switch (wireType) {\n      case 0:\n        readVarint();\n        break;\n      case 1:\n        offset += 8;\n        break;\n      case 5:\n        offset += 4;\n        break;\n      case 2: {\n        const length = readVarint();\n        const value = buffer.subarray(offset, offset + length);\n        offset += length;\n        if (field === 1) id = value.toString('utf8');\n        break;\n      }\n      default:\n        throw new Error(`unsupported protobuf wire type ${wireType}`);\n    }\n  }\n  return { id };\n}\n\n/** @internal exported for tests */\nexport function encodeGetSecretResponse(response: GetSecretResponse): Buffer {\n  return Buffer.concat([Buffer.from([0x0a]), encodeVarint(response.data.length), response.data]);\n}\n\nfunction encodeVarint(value: number): Buffer {\n  const bytes: number[] = [];\n  let remaining = value;\n  while (remaining >= 0x80) {\n    bytes.push((remaining % 0x80) | 0x80);\n    remaining = Math.floor(remaining / 0x80);\n  }\n  bytes.push(remaining);\n  return Buffer.from(bytes);\n}\n\nconst secretsService: ServiceDefinition = {\n  GetSecret: {\n    path: SECRETS_GET_METHOD,\n    requestStream: false,\n    responseStream: false,\n    requestSerialize: () => {\n      throw new Error('server does not serialize requests');\n    },\n    requestDeserialize: decodeGetSecretRequest,\n    responseSerialize: encodeGetSecretResponse,\n    responseDeserialize: () => {\n      throw new Error('server does not deserialize responses');\n    },\n  },\n};\n\nconst authService: ServiceDefinition = {\n  Credentials: {\n    path: AUTH_CREDENTIALS_METHOD,\n    requestStream: false,\n    responseStream: false,\n    requestSerialize: () => {\n      throw new Error('server does not serialize requests');\n    },\n    requestDeserialize: () => ({}),\n    // Empty message: anonymous registry access.\n    responseSerialize: () => Buffer.alloc(0),\n    responseDeserialize: () => {\n      throw new Error('server does not deserialize responses');\n    },\n  },\n};\n","/**\n * Pure Dockerfile synthesis and content-addressed identity for DockerTemplate.\n *\n * A `DockerTemplate` records an ordered list of operations (setWorkdir, setEnvs,\n * runCmd, runWithSecrets, aptInstall, pipInstall, npmInstall) over a base image. This module\n * turns that ordered list into a deterministic Dockerfile string and a stable\n * content hash. It performs no I/O, so it is fully unit-testable without a\n * Docker daemon.\n */\n\nimport { createHash } from 'node:crypto';\n\n// =============================================================================\n// Operations\n// =============================================================================\n\nexport interface AptInstallOptions {\n  /** Pass `--no-install-recommends` to `apt-get install`. */\n  noInstallRecommends?: boolean;\n  /** Pass `--fix-missing` to `apt-get install`. */\n  fixMissing?: boolean;\n}\n\nexport interface PipInstallOptions {\n  /** Install system-wide (default). `false` installs for the current user (`--user`). */\n  g?: boolean;\n}\n\nexport interface NpmInstallOptions {\n  /** Install globally (`npm install -g`). */\n  g?: boolean;\n  /** Include dev dependencies (`--include=dev`). Ignored when `packages` is set. */\n  dev?: boolean;\n}\n\nexport interface RunWithSecretsOptions {\n  /**\n   * Names of environment variables whose values are read from the building\n   * process's `process.env` at `build()` time and exposed to the command. Only\n   * the names participate in the template identity.\n   */\n  secrets: string[];\n  /**\n   * Absolute path produced by the command. Only this path is copied into the\n   * template image; everything else the command does (including the secret\n   * values) stays in a throwaway build stage.\n   */\n  output: string;\n}\n\nexport type DockerTemplateOperation =\n  | { method: 'setWorkdir'; args: [string] }\n  | { method: 'setEnvs'; args: [Record<string, string>] }\n  | { method: 'runCmd'; args: [string | string[]] }\n  | { method: 'runWithSecrets'; args: [string | string[], RunWithSecretsOptions] }\n  | { method: 'aptInstall'; args: [string | string[], AptInstallOptions?] }\n  | { method: 'pipInstall'; args: [(string | string[])?, PipInstallOptions?] }\n  | { method: 'npmInstall'; args: [(string | string[])?, NpmInstallOptions?] };\n\n/** A fully-resolved template definition: the base image and the ordered operations. */\nexport interface DockerTemplateDefinition {\n  baseImage: string;\n  operations: readonly DockerTemplateOperation[];\n}\n\n// =============================================================================\n// Dockerfile synthesis\n// =============================================================================\n\nfunction toCommandList(command: string | string[]): string[] {\n  return Array.isArray(command) ? command : [command];\n}\n\nfunction sortedEntries(record: Record<string, string>): Array<[string, string]> {\n  return Object.entries(record).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));\n}\n\nfunction renderEnvLine(envs: Record<string, string>): string | undefined {\n  const pairs = sortedEntries(envs);\n  if (pairs.length === 0) return undefined;\n  // Deterministic order so identical envs always render identically.\n  return `ENV ${pairs.map(([key, value]) => `${key}=${JSON.stringify(value)}`).join(' ')}`;\n}\n\nfunction renderAptInstall(packages: string | string[], options?: AptInstallOptions): string {\n  const flags: string[] = [];\n  if (options?.noInstallRecommends) flags.push('--no-install-recommends');\n  if (options?.fixMissing) flags.push('--fix-missing');\n  const flagStr = flags.length > 0 ? `${flags.join(' ')} ` : '';\n  const pkgs = toCommandList(packages).join(' ');\n  return `RUN apt-get update && apt-get install -y ${flagStr}${pkgs} && rm -rf /var/lib/apt/lists/*`;\n}\n\nfunction renderPipInstall(packages?: string | string[], options?: PipInstallOptions): string {\n  const userFlag = options?.g === false ? ' --user' : '';\n  const target = packages === undefined ? '.' : toCommandList(packages).join(' ');\n  return `RUN pip install${userFlag} ${target}`;\n}\n\nfunction renderNpmInstall(packages?: string | string[], options?: NpmInstallOptions): string {\n  const flags: string[] = [];\n  if (options?.g) flags.push('-g');\n  if (packages === undefined) {\n    if (options?.dev) flags.push('--include=dev');\n    const flagStr = flags.length > 0 ? ` ${flags.join(' ')}` : '';\n    return `RUN npm install${flagStr}`;\n  }\n  const flagStr = flags.length > 0 ? ` ${flags.join(' ')}` : '';\n  const pkgs = toCommandList(packages).join(' ');\n  return `RUN npm install${flagStr} ${pkgs}`;\n}\n\nfunction secretStageName(index: number): string {\n  return `mastra-secret-${index}`;\n}\n\nfunction mainStageName(index: number): string {\n  return `mastra-main-${index}`;\n}\n\n/**\n * Render a deterministic Dockerfile from a template definition.\n *\n * Operations accumulate in a chain of \"main\" stages. Every `runWithSecrets`\n * operation forks a throwaway stage from the main stage as it stands at that\n * point (so it sees earlier WORKDIR/ENV/installs) and runs the command with\n * each secret exposed through a BuildKit secret mount, exported into the\n * command's environment for that single RUN. The next main stage then starts\n * from the same pre-secret snapshot and `COPY --from`s only the declared\n * output path. Secret mounts are tmpfs-backed and never part of a layer, its\n * history, or the build cache; the throwaway stage additionally keeps anything\n * else the command wrote (caches, logs) out of the template image.\n */\n/**\n * `RUN --mount=type=secret,id=X,mode=0444 ... export X=\"$(cat /run/secrets/X)\" && <command>`.\n * Reading the file into a shell variable keeps the value visible only to this\n * RUN's process tree, without depending on the newer `env=` mount option.\n * `mode=0444` because BuildKit's default is `0400 root`, which a base image\n * with a non-root `USER` cannot read; world-readable within the RUN is no\n * wider than the exported variable already is.\n */\nfunction renderSecretRun(command: string | string[], secrets: string[]): string {\n  const names = [...secrets].sort();\n  const mounts = names.map(name => `--mount=type=secret,id=${name},mode=0444`);\n  const exports = names.map(name => `${name}=\"$(cat /run/secrets/${name})\"`);\n  const prefix = names.length > 0 ? [`export ${exports.join(' ')}`] : [];\n  return `RUN ${[...mounts, ''].join(' ')}${[...prefix, ...toCommandList(command)].join(' && ')}`;\n}\n\nexport function synthesizeDockerfile(definition: DockerTemplateDefinition): string {\n  const lines: string[] = [];\n  let mainIndex = 0;\n  const openMain = (from: string) => {\n    lines.push(`FROM ${from} AS ${mainStageName(mainIndex)}`);\n  };\n  openMain(definition.baseImage);\n\n  definition.operations.forEach((operation, index) => {\n    switch (operation.method) {\n      case 'setWorkdir':\n        lines.push(`WORKDIR ${operation.args[0]}`);\n        break;\n      case 'setEnvs': {\n        const line = renderEnvLine(operation.args[0]);\n        if (line) lines.push(line);\n        break;\n      }\n      case 'runCmd':\n        lines.push(`RUN ${toCommandList(operation.args[0]).join(' && ')}`);\n        break;\n      case 'runWithSecrets': {\n        const [command, { secrets, output }] = operation.args;\n        const snapshot = mainStageName(mainIndex);\n        const stage = secretStageName(index);\n        lines.push(`FROM ${snapshot} AS ${stage}`, renderSecretRun(command, secrets));\n        mainIndex += 1;\n        openMain(snapshot);\n        lines.push(`COPY --from=${stage} ${output} ${output}`);\n        break;\n      }\n      case 'aptInstall':\n        lines.push(renderAptInstall(operation.args[0], operation.args[1]));\n        break;\n      case 'pipInstall':\n        lines.push(renderPipInstall(operation.args[0], operation.args[1]));\n        break;\n      case 'npmInstall':\n        lines.push(renderNpmInstall(operation.args[0], operation.args[1]));\n        break;\n    }\n  });\n\n  return `${lines.join('\\n')}\\n`;\n}\n\n/** Names of every secret referenced by `runWithSecrets` operations, deduplicated and sorted. */\nexport function secretNames(definition: DockerTemplateDefinition): string[] {\n  const names = new Set<string>();\n  for (const operation of definition.operations) {\n    if (operation.method === 'runWithSecrets') {\n      for (const name of operation.args[1].secrets) names.add(name);\n    }\n  }\n  return [...names].sort();\n}\n\n// =============================================================================\n// Content-addressed identity\n// =============================================================================\n\n/** Prefix for template image tags built locally. */\nexport const TEMPLATE_IMAGE_REPO = 'mastra-template';\n\nfunction canonicalOperation(operation: DockerTemplateOperation): unknown {\n  switch (operation.method) {\n    case 'setEnvs':\n      return { method: 'setEnvs', args: [sortedEntries(operation.args[0])] };\n    case 'runWithSecrets': {\n      const [command, { secrets, output }] = operation.args;\n      return { method: 'runWithSecrets', args: [command, { secrets: [...secrets].sort(), output }] };\n    }\n    default:\n      return operation;\n  }\n}\n\n/**\n * Stable content hash over the base image and ordered operations. Env records\n * and secret name lists are canonicalized so insertion order does not change\n * the identity. Secret *values* never enter the definition, so the same\n * definition built with different credentials resolves to the same image tag.\n */\nexport function templateIdentity(definition: DockerTemplateDefinition): string {\n  const canonical = JSON.stringify({\n    schemaVersion: 1,\n    baseImage: definition.baseImage,\n    operations: definition.operations.map(canonicalOperation),\n  });\n  return createHash('sha256').update(canonical).digest('hex').slice(0, 24);\n}\n\n/** Full `mastra-template:<hash>` tag for a definition. */\nexport function templateImageTag(definition: DockerTemplateDefinition): string {\n  return `${TEMPLATE_IMAGE_REPO}:${templateIdentity(definition)}`;\n}\n","/**\n * DockerTemplate — a reusable prepared baseline for the local Docker sandbox.\n *\n * Prepare an environment once (base image + ordered setup commands + env +\n * package installs), `build()` it into a content-addressed local image, then\n * spawn multiple disposable `DockerSandbox`es from that image. Each sandbox is a\n * fresh container with its own writable layer over the shared read-only image,\n * so their filesystems are independent. The built image's lifecycle is\n * controlled by `dispose()`, independent of any sandbox's `destroy()`.\n *\n * Unlike `docker commit` (which cannot capture mounted volumes and skips layer\n * caching), the baseline is produced by synthesizing a Dockerfile and running\n * `docker build`, so repo/setup content is baked into reproducible, cached\n * image layers.\n *\n * @example Prepare once, spawn many\n * ```typescript\n * import { DockerTemplate } from '@mastra/docker';\n *\n * const template = new DockerTemplate({ baseImage: 'node:22-slim' })\n *   .runCmd('git clone --depth=1 https://example.com/repo /workspace/app')\n *   .setWorkdir('/workspace/app')\n *   .runCmd('npm ci');\n *\n * const result = await template.build();\n * if (result.status !== 'ready') throw new Error(result.error);\n *\n * const a = await template.createSandbox();\n * const b = await template.createSandbox(); // independent writable filesystem\n * ```\n */\n\nimport posixPath from 'node:path/posix';\nimport Docker from 'dockerode';\nimport { pack as tarPack } from 'tar-stream';\nimport { createAbortError, normalizeAbortError, throwIfAborted, waitForAbortable } from '../abort';\nimport { DockerSandbox, type DockerSandboxOptions } from '../sandbox';\nimport { openBuildSession, type BuildSession } from './build-session';\nimport {\n  type AptInstallOptions,\n  type DockerTemplateDefinition,\n  type DockerTemplateOperation,\n  type NpmInstallOptions,\n  type PipInstallOptions,\n  type RunWithSecretsOptions,\n  secretNames,\n  synthesizeDockerfile,\n  templateImageTag,\n} from './dockerfile';\n\nconst MAX_OPERATIONS = 256;\nconst MAX_STRING_LENGTH = 32 * 1024;\nconst MAX_COLLECTION_ITEMS = 512;\n\nexport interface DockerTemplateOptions {\n  /**\n   * Base image for the template.\n   * @default 'node:22-slim'\n   */\n  baseImage?: string;\n  /** Pass-through dockerode connection options (socket path, host, TLS certs). */\n  dockerOptions?: Docker.DockerOptions;\n  /**\n   * Values for the secrets named by {@link DockerTemplate.runWithSecrets}.\n   * Supplying them here (rather than via `process.env`) keeps concurrent\n   * builds with different credentials from racing on shared process state.\n   * Not part of the template identity.\n   */\n  secrets?: DockerTemplateSecrets;\n}\n\n/**\n * Values for the secrets named by `runWithSecrets`, keyed by name. Either a\n * record or a function producing one (called once per real build, so rotated\n * credentials are picked up without rebuilding the template object).\n */\nexport type DockerTemplateSecrets =\n  | Record<string, string>\n  | (() => Record<string, string> | Promise<Record<string, string>>);\n\nexport interface DockerTemplateBuildOptions {\n  /**\n   * Rebuild even if an image with the computed tag already exists locally,\n   * re-executing every step instead of reusing the daemon's layer cache (the\n   * cache does not key on secret values or on what `git clone`/`npm install`\n   * would fetch today).\n   */\n  force?: boolean;\n  /**\n   * Build on this Docker client instead of the template's own. A sandbox\n   * passes its client so the image lands on the daemon that will run it.\n   */\n  docker?: Docker;\n  /**\n   * Secret values for this build. Overrides the template-level `secrets`\n   * source for names it provides. Names still missing after both sources are\n   * read from `process.env` as a last resort.\n   */\n  secrets?: DockerTemplateSecrets;\n  /** Cancel this caller's wait for preparation. */\n  abortSignal?: AbortSignal;\n}\n\nexport interface DockerTemplateBuildResult {\n  status: 'ready' | 'failed';\n  /** The local image tag (`mastra-template:<hash>`) the template resolves to. */\n  templateId: string;\n  /** Failure detail when `status` is `'failed'`. */\n  error?: string;\n}\n\ninterface InFlightBuild {\n  promise: Promise<DockerTemplateBuildResult>;\n  controller: AbortController;\n  waiters: number;\n}\n\n/**\n * Immutable, chainable builder + build/lifecycle for a local Docker template.\n * Operation methods return a new instance (like the platform `Template()`\n * builder); `build`/`createSandbox`/`dispose` operate against the daemon.\n */\nexport class DockerTemplate {\n  readonly #baseImage: string;\n  readonly #operations: readonly DockerTemplateOperation[];\n  readonly #dockerOptions: Docker.DockerOptions | undefined;\n  readonly #secrets: DockerTemplateSecrets | undefined;\n  #docker: Docker | undefined;\n  #built = false;\n  #queueTail: InFlightBuild | undefined;\n  #plainBuild: InFlightBuild | undefined;\n\n  constructor(options: DockerTemplateOptions = {}, state?: DockerTemplateState) {\n    this.#baseImage = state ? state.baseImage : validateString(options.baseImage ?? 'node:22-slim', 'baseImage');\n    this.#operations = state?.operations ?? [];\n    this.#dockerOptions = options.dockerOptions;\n    this.#secrets = options.secrets;\n  }\n\n  #clone(next: Partial<DockerTemplateState>): DockerTemplate {\n    return new DockerTemplate(\n      { dockerOptions: this.#dockerOptions, secrets: this.#secrets },\n      {\n        baseImage: next.baseImage ?? this.#baseImage,\n        operations: next.operations ?? this.#operations,\n      },\n    );\n  }\n\n  #append(operation: DockerTemplateOperation): DockerTemplate {\n    if (this.#operations.length >= MAX_OPERATIONS) {\n      throw new RangeError(`Docker template cannot contain more than ${MAX_OPERATIONS} operations`);\n    }\n    return this.#clone({ operations: [...this.#operations, operation] });\n  }\n\n  /** Set the base image. */\n  from(image: string): DockerTemplate {\n    return this.#clone({ baseImage: validateString(image, 'image') });\n  }\n\n  /** Set the working directory for subsequent steps and the runtime container. */\n  setWorkdir(path: string): DockerTemplate {\n    return this.#append({ method: 'setWorkdir', args: [validateString(path, 'path')] });\n  }\n\n  /**\n   * Set environment variables. They are baked into the image via `ENV` and\n   * participate in the template identity, so never put secrets here — use\n   * {@link runWithSecrets} for anything that must not persist in the image.\n   */\n  setEnvs(envs: Record<string, string>): DockerTemplate {\n    return this.#append({ method: 'setEnvs', args: [validateStringRecord(envs, 'envs')] });\n  }\n\n  /** Run a command (or `&&`-joined list of commands) as a build step. */\n  runCmd(command: string | string[]): DockerTemplate {\n    return this.#append({ method: 'runCmd', args: [validateStringOrStrings(command, 'command')] });\n  }\n\n  /**\n   * Run a command that needs build-time secrets, without persisting them.\n   *\n   * The command runs in a throwaway build stage forked from the template as it\n   * stands at that point, so earlier WORKDIR/ENV/installs apply and later\n   * steps see the copied `output`. The named secrets are resolved when\n   * `build()` runs — from `build({ secrets })`, then the template's `secrets`\n   * option, then `process.env` — and exposed to the command as environment\n   * variables. Values reach the daemon through a BuildKit secret mount\n   * (`RUN --mount=type=secret`), which is tmpfs-backed and scoped to that one\n   * RUN — never a build arg, layer, history entry, or cache metadata. Only\n   * `output` is copied into the template image. Builds that use secrets\n   * require a BuildKit-capable daemon (Docker 20.10+).\n   */\n  runWithSecrets(command: string | string[], options: RunWithSecretsOptions): DockerTemplate {\n    if (!Array.isArray(options.secrets)) throw new TypeError('secrets must be an array of strings');\n    if (options.secrets.length > MAX_COLLECTION_ITEMS) {\n      throw new RangeError(`secrets cannot contain more than ${MAX_COLLECTION_ITEMS} items`);\n    }\n    const secrets = options.secrets.map(name => {\n      if (typeof name !== 'string' || !/^[A-Za-z_][A-Za-z0-9_]*$/.test(name)) {\n        throw new TypeError(`secrets must be environment variable names, got ${JSON.stringify(name)}`);\n      }\n      return name;\n    });\n    const output = validateString(options.output, 'output');\n    if (!output.startsWith('/')) throw new TypeError('output must be an absolute path');\n    return this.#append({\n      method: 'runWithSecrets',\n      args: [validateStringOrStrings(command, 'command'), { secrets, output }],\n    });\n  }\n\n  /** Install apt packages. */\n  aptInstall(packages: string | string[], options?: AptInstallOptions): DockerTemplate {\n    return this.#append({ method: 'aptInstall', args: [validateStringOrStrings(packages, 'packages'), options] });\n  }\n\n  /** Install pip packages (or `pip install .` for the current workdir when omitted). */\n  pipInstall(packages?: string | string[], options?: PipInstallOptions): DockerTemplate {\n    const validated = packages === undefined ? undefined : validateStringOrStrings(packages, 'packages');\n    return this.#append({ method: 'pipInstall', args: [validated, options] });\n  }\n\n  /** Install npm packages (or run `npm install` for the current workdir when omitted). */\n  npmInstall(packages?: string | string[], options?: NpmInstallOptions): DockerTemplate {\n    const validated = packages === undefined ? undefined : validateStringOrStrings(packages, 'packages');\n    return this.#append({ method: 'npmInstall', args: [validated, options] });\n  }\n\n  /** The resolved definition (base image + ordered operations). */\n  get definition(): DockerTemplateDefinition {\n    return { baseImage: this.#baseImage, operations: this.#operations };\n  }\n\n  /** The synthesized Dockerfile for this template. */\n  get dockerfile(): string {\n    return synthesizeDockerfile(this.definition);\n  }\n\n  /** The content-addressed local image tag this template resolves to. */\n  get templateId(): string {\n    return templateImageTag(this.definition);\n  }\n\n  /**\n   * The working directory the built image ends up with, i.e. the last\n   * `setWorkdir` in the chain (resolved against earlier ones when relative).\n   * `undefined` when the template never sets one, in which case the base\n   * image's `WORKDIR` (or the sandbox default) applies.\n   */\n  get workdir(): string | undefined {\n    let current: string | undefined;\n    for (const op of this.#operations) {\n      if (op.method !== 'setWorkdir') continue;\n      const next = op.args[0];\n      current = next.startsWith('/') || current === undefined ? next : posixPath.join(current, next);\n    }\n    return current;\n  }\n\n  #getDocker(): Docker {\n    if (!this.#docker) {\n      this.#docker = new Docker(this.#dockerOptions);\n    }\n    return this.#docker;\n  }\n\n  /**\n   * Build (or reuse) the template's image. Idempotent: if an image with the\n   * computed tag already exists locally and `force` is not set, returns\n   * `ready` without rebuilding. Otherwise synthesizes a Dockerfile, runs\n   * `docker build`, and surfaces any build-step failure as `status: 'failed'`.\n   *\n   * @throws if a secret named by `runWithSecrets` cannot be resolved from\n   * `options.secrets`, the template's `secrets` option, or `process.env`.\n   */\n  async build(options: DockerTemplateBuildOptions = {}): Promise<DockerTemplateBuildResult> {\n    throwIfAborted(options.abortSignal, 'build Docker template');\n    // Many sandboxes starting concurrently from one template must share a\n    // single `docker build` rather than racing to build the same tag. Only a\n    // plain request may join an in-flight build; a forced build, different\n    // secrets, or a different daemon is queued behind it instead.\n    const isPlain = !options.force && options.secrets === undefined && options.docker === undefined;\n    if (isPlain && this.#plainBuild) return this.#waitForBuild(this.#plainBuild, options.abortSignal);\n\n    const previous = this.#queueTail?.promise.catch(() => undefined) ?? Promise.resolve();\n    const controller = new AbortController();\n    const run: InFlightBuild = {\n      controller,\n      waiters: 0,\n      promise: previous.then(() => {\n        throwIfAborted(controller.signal, 'build Docker template');\n        return this.#build({ ...options, abortSignal: controller.signal });\n      }),\n    };\n    this.#queueTail = run;\n    if (isPlain) this.#plainBuild = run;\n    run.promise\n      .finally(() => {\n        if (this.#queueTail === run) this.#queueTail = undefined;\n        if (this.#plainBuild === run) this.#plainBuild = undefined;\n      })\n      .catch(() => undefined);\n    return this.#waitForBuild(run, options.abortSignal);\n  }\n\n  #waitForBuild(run: InFlightBuild, abortSignal: AbortSignal | undefined): Promise<DockerTemplateBuildResult> {\n    run.waiters += 1;\n    let settled = false;\n    const release = (aborted: boolean) => {\n      if (settled) return;\n      settled = true;\n      run.waiters -= 1;\n      if (aborted && run.waiters === 0) run.controller.abort();\n    };\n    return waitForAbortable(run.promise, abortSignal, 'build Docker template', () => release(true)).finally(() =>\n      release(false),\n    );\n  }\n\n  async #build(options: DockerTemplateBuildOptions): Promise<DockerTemplateBuildResult> {\n    const docker = options.docker ?? this.#getDocker();\n    const tag = this.templateId;\n    const { abortSignal } = options;\n    throwIfAborted(abortSignal, 'build Docker template');\n\n    if (!options.force) {\n      try {\n        await docker.getImage(tag).inspect();\n        throwIfAborted(abortSignal, 'build Docker template');\n        this.#built = true;\n        return { status: 'ready', templateId: tag };\n      } catch (error) {\n        if (!isImageNotFoundError(error)) throw error;\n      }\n    }\n\n    // Only a real build needs the secret values; reusing a cached image must not\n    // require the original credentials to still be present.\n    const secrets = await this.#resolveSecrets(options.secrets);\n    throwIfAborted(abortSignal, 'build Docker template');\n\n    const context = tarPack();\n    context.entry({ name: 'Dockerfile' }, this.dockerfile);\n    context.finalize();\n\n    try {\n      const nocache = options.force === true;\n      if (secrets) {\n        const { stream, session } = await this.#buildWithSecrets(docker, context, tag, secrets, nocache, abortSignal);\n        try {\n          await this.#followBuild(docker, stream, abortSignal);\n        } finally {\n          // The daemon calls GetSecret only while the build runs; drop the\n          // session however the output stream settled (end, error, or close).\n          session.close();\n        }\n      } else {\n        const build = docker.buildImage(context, { t: tag, nocache, forcerm: true }).then(stream => {\n          if (abortSignal?.aborted) {\n            (stream as NodeJS.ReadableStream & { destroy?(error?: Error): void }).destroy?.();\n            throw createAbortError(abortSignal, 'build Docker template');\n          }\n          return stream;\n        });\n        const stream = await waitForAbortable(build, abortSignal, 'build Docker template', () => {\n          (context as NodeJS.ReadableStream & { destroy?(error?: Error): void }).destroy?.();\n        });\n        await this.#followBuild(docker, stream, abortSignal);\n      }\n    } catch (error) {\n      this.#built = false;\n      if (abortSignal?.aborted) throw normalizeAbortError(error, 'build Docker template');\n      return { status: 'failed', templateId: tag, error: error instanceof Error ? error.message : String(error) };\n    }\n\n    this.#built = true;\n    return { status: 'ready', templateId: tag };\n  }\n\n  async #resolveSecrets(override: DockerTemplateSecrets | undefined): Promise<Record<string, string> | undefined> {\n    const names = secretNames(this.definition);\n    if (names.length === 0) return undefined;\n    const fromBuild = await readSecrets(override);\n    const fromTemplate = await readSecrets(this.#secrets);\n    const resolved: Record<string, string> = {};\n    for (const name of names) {\n      const value = fromBuild[name] ?? fromTemplate[name] ?? process.env[name];\n      if (value === undefined) {\n        throw new Error(\n          `Docker template secret ${name} was not provided (secrets option) and is not set in the environment`,\n        );\n      }\n      resolved[name] = value;\n    }\n    return resolved;\n  }\n\n  /**\n   * BuildKit build with a session serving the secret mounts. Dials `/build`\n   * directly because `docker.buildImage` replaces any session id with its own\n   * auth-only session when `version` is `'2'`.\n   */\n  async #buildWithSecrets(\n    docker: Docker,\n    context: NodeJS.ReadableStream,\n    tag: string,\n    secrets: Record<string, string>,\n    nocache: boolean,\n    abortSignal?: AbortSignal,\n  ): Promise<{ stream: NodeJS.ReadableStream; session: BuildSession }> {\n    throwIfAborted(abortSignal, 'build Docker template');\n    const session = await openBuildSession(docker, secrets, abortSignal);\n    let stream: NodeJS.ReadableStream;\n    try {\n      stream = await new Promise<NodeJS.ReadableStream>((resolve, reject) => {\n        let settled = false;\n        let request: { destroy?(error?: Error): void } | undefined;\n        const finish = (error?: unknown, data?: unknown) => {\n          if (settled) {\n            if (data) (data as NodeJS.ReadableStream & { destroy?(error?: Error): void }).destroy?.();\n            return;\n          }\n          settled = true;\n          abortSignal?.removeEventListener('abort', abort);\n          error === undefined ? resolve(data as NodeJS.ReadableStream) : reject(error);\n        };\n        const abort = () => {\n          (context as NodeJS.ReadableStream & { destroy?(error?: Error): void }).destroy?.();\n          request?.destroy?.();\n          session.close();\n          if (abortSignal) finish(createAbortError(abortSignal, 'build Docker template'));\n        };\n        abortSignal?.addEventListener('abort', abort, { once: true });\n        if (abortSignal?.aborted) {\n          abort();\n          return;\n        }\n        request = docker.modem.dial(\n          {\n            path: '/build?',\n            method: 'POST',\n            file: context,\n            options: { t: tag, version: '2', session: session.id, nocache },\n            isStream: true,\n            statusCodes: { 200: true, 500: 'server error' },\n          },\n          (err: Error | null, data: unknown) => finish(err ?? undefined, data),\n        ) as unknown as { destroy?(error?: Error): void } | undefined;\n      });\n    } catch (error) {\n      session.close();\n      throw error;\n    }\n    return { stream, session };\n  }\n\n  #followBuild(docker: Docker, stream: NodeJS.ReadableStream, abortSignal?: AbortSignal): Promise<void> {\n    return new Promise<void>((resolve, reject) => {\n      let settled = false;\n      const finish = (error?: unknown) => {\n        if (settled) return;\n        settled = true;\n        abortSignal?.removeEventListener('abort', abort);\n        error === undefined ? resolve() : reject(error);\n      };\n      const abort = () => {\n        (stream as NodeJS.ReadableStream & { destroy?(error?: Error): void }).destroy?.();\n        if (abortSignal) finish(createAbortError(abortSignal, 'build Docker template'));\n      };\n      abortSignal?.addEventListener('abort', abort, { once: true });\n      if (abortSignal?.aborted) {\n        abort();\n        return;\n      }\n      docker.modem.followProgress(stream, (err: Error | null, output: Array<Record<string, unknown>>) => {\n        if (err) {\n          finish(err);\n          return;\n        }\n        const failure = output?.find(entry => entry && (entry.error !== undefined || entry.errorDetail !== undefined));\n        if (failure) {\n          const detail = failure.errorDetail as { message?: string } | undefined;\n          finish(new Error(String(detail?.message ?? failure.error ?? 'docker build failed')));\n          return;\n        }\n        finish();\n      });\n    });\n  }\n\n  /**\n   * Create a `DockerSandbox` bound to the built image. Lazily builds the\n   * template if it has not been built yet. Each call returns a fresh sandbox\n   * with an independent writable layer. Invocation-specific `env`/config passed\n   * via `options` reaches only the container and is never baked into the image.\n   *\n   * The sandbox's working directory follows the template's last `setWorkdir`\n   * unless `options.workingDirectory` overrides it, so relative paths resolve\n   * against the same directory the image was prepared in.\n   *\n   * @throws if the (lazy) build fails.\n   */\n  async createSandbox(options: Omit<DockerSandboxOptions, 'image' | 'template'> = {}): Promise<DockerSandbox> {\n    if (!this.#built) {\n      const result = await this.build();\n      if (result.status !== 'ready') {\n        throw new Error(`Docker template build failed: ${result.error ?? 'unknown error'}`);\n      }\n    }\n    // Same wiring as `new DockerSandbox({ template })`; the build above just\n    // surfaces failures here instead of at `start()`.\n    const workingDirectory = options.workingDirectory ?? options.workingDir ?? this.workdir;\n    return new DockerSandbox({\n      ...options,\n      ...(workingDirectory !== undefined && { workingDirectory }),\n      template: this,\n      dockerOptions: options.dockerOptions ?? this.#dockerOptions,\n    });\n  }\n\n  /**\n   * Remove the built image (`docker rmi`). Tolerant of an already-removed\n   * image. Independent of any sandbox created from this template, but the\n   * daemon refuses to remove an image that a container (running or stopped)\n   * still references, so destroy those sandboxes first.\n   */\n  async dispose(): Promise<void> {\n    const docker = this.#getDocker();\n    try {\n      await docker.getImage(this.templateId).remove();\n    } catch (error) {\n      if (!isImageNotFoundError(error)) throw error;\n    }\n    this.#built = false;\n  }\n}\n\ninterface DockerTemplateState {\n  baseImage: string;\n  operations: readonly DockerTemplateOperation[];\n}\n\n// =============================================================================\n// Validation (mirrors platform template validation)\n// =============================================================================\n\nfunction validateString(value: unknown, name: string): string {\n  if (typeof value !== 'string') throw new TypeError(`${name} must be a string`);\n  if (value.length === 0) throw new TypeError(`${name} must not be empty`);\n  if (value.length > MAX_STRING_LENGTH) {\n    throw new RangeError(`${name} cannot exceed ${MAX_STRING_LENGTH} characters`);\n  }\n  return value;\n}\n\nfunction validateStringOrStrings(value: unknown, name: string): string | string[] {\n  if (typeof value === 'string') return validateString(value, name);\n  if (!Array.isArray(value)) throw new TypeError(`${name} must be a string or an array of strings`);\n  if (value.length === 0) throw new TypeError(`${name} must not be empty`);\n  if (value.length > MAX_COLLECTION_ITEMS) {\n    throw new RangeError(`${name} cannot contain more than ${MAX_COLLECTION_ITEMS} items`);\n  }\n  return value.map((item, index) => validateString(item, `${name}[${index}]`));\n}\n\nfunction validateStringRecord(value: unknown, name: string): Record<string, string> {\n  if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n    throw new TypeError(`${name} must be a plain object`);\n  }\n  const entries = Object.entries(value);\n  if (entries.length > MAX_COLLECTION_ITEMS) {\n    throw new RangeError(`${name} cannot contain more than ${MAX_COLLECTION_ITEMS} items`);\n  }\n  return Object.fromEntries(\n    entries.map(([key, item]) => {\n      if (typeof item !== 'string') throw new TypeError(`${name}.${key} must be a string`);\n      return [validateString(key, `${name} key`), item];\n    }),\n  );\n}\n\nasync function readSecrets(source: DockerTemplateSecrets | undefined): Promise<Record<string, string>> {\n  if (!source) return {};\n  return typeof source === 'function' ? await source() : source;\n}\n\nfunction isImageNotFoundError(error: unknown): boolean {\n  if (error instanceof Error) {\n    const msg = error.message.toLowerCase();\n    return msg.includes('no such image') || msg.includes('404');\n  }\n  return false;\n}\n","import { createHash } from \"crypto\";\n//#region src/setup-marker.ts\n/**\n* Setup completion marker shared by repo templates and their consumers.\n*\n* A repo template writes this file beside the checkout as its last build\n* step, so it exists only in images where every setup command succeeded. Its\n* content is a digest of the setup commands the image ran, letting a sandbox\n* booted from the image tell whether the setup it is about to run already\n* happened. Relative to the template's build cwd, which is also the runtime\n* working directory the repo was cloned into.\n*/\nconst SETUP_MARKER_PATH = \".mastra-sandbox/setup\";\n/** Blank entries never become build steps, so they never count toward the digest either. */\nfunction normalizeSetupCommands(setupCommand) {\n\treturn (setupCommand === void 0 ? [] : Array.isArray(setupCommand) ? setupCommand : [setupCommand]).filter((command) => command.trim() !== \"\");\n}\n/** The marker content for a setup command list: `sha256:<hex>` over the commands joined by newlines. */\nfunction setupMarkerContent(setupCommand) {\n\treturn `sha256:${createHash(\"sha256\").update(normalizeSetupCommands(setupCommand).join(\"\\n\")).digest(\"hex\")}`;\n}\n/** Shell step that writes the marker relative to the cwd. `content` is a digest, so it is shell-safe. */\nfunction setupMarkerCommand(content) {\n\treturn `mkdir -p \"$(dirname \"${SETUP_MARKER_PATH}\")\" && printf '%s' '${content}' > \"${SETUP_MARKER_PATH}\"`;\n}\n//#endregion\n//#region src/repo-clone.ts\nfunction repoCloneCommand({ cloneUrl, destination, branch, tokenEnv }) {\n\treturn `git ${tokenEnv ? `${gitAuthFlag(tokenEnv)} ` : \"\"}clone --depth=1 --single-branch ${branch ? `--branch ${shellQuote(branch)} ` : \"\"}${shellQuote(cloneUrl)} ${shellQuote(destination)}`;\n}\n/** Per-invocation auth header; `-c` config never reaches `.git/config`. */\nfunction gitAuthFlag(tokenEnv) {\n\treturn `-c http.extraheader=\"AUTHORIZATION: basic $(printf 'x-access-token:%s' \"$${tokenEnv}\" | base64 -w0)\"`;\n}\nfunction shellQuote(value) {\n\treturn `'${value.replace(/'/g, `'\\\\''`)}'`;\n}\n//#endregion\nexport { SETUP_MARKER_PATH, normalizeSetupCommands, repoCloneCommand, setupMarkerCommand, setupMarkerContent };\n\n//# sourceMappingURL=index.js.map","/**\n * createDockerRepoTemplate — a repo checkout plus setup commands as a\n * reusable, content-addressed local image, with the same contract as the\n * E2B and platform repo templates (`getRepositoryAccess`, `setupCommand`,\n * `buildEnv`, `workingDirectory`).\n *\n * Returns a template RESOLVER for `DockerSandbox`'s `template` option rather\n * than a fixed template: each resolution calls `getRepositoryAccess`, looks up\n * the current head of `ref` (`git ls-remote`, no clone) and pins that sha into\n * the template identity. A moved branch therefore yields a fresh image on the\n * next new sandbox, and an unmoved one reuses the cached image. When the head\n * cannot be resolved the resolver rejects: an unpinned clone cached under a\n * stable tag would otherwise serve stale repository state forever.\n *\n * The clone runs in a throwaway build stage; the credential is passed by value\n * to that stage only and never enters the template identity or the image.\n *\n * @example\n * ```typescript\n * const sandbox = new DockerSandbox({\n *   template: createDockerRepoTemplate({\n *     getRepositoryAccess: async () => ({ cloneUrl: 'https://github.com/acme/app.git' }),\n *     setupCommand: ['npm ci', 'npm run build'],\n *   }),\n * });\n * ```\n */\n\nimport { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { normalizeSetupCommands, setupMarkerCommand, setupMarkerContent } from '@internal/workspace';\nimport type { DockerOptions } from 'dockerode';\nimport { normalizeAbortError, throwIfAborted } from '../abort';\nimport { DockerTemplate } from './template';\n\nconst execFileAsync = promisify(execFile);\n\n/** Env var the build's clone reads the credential from (see `cloneFull`). */\nconst BUILD_TOKEN_ENV = 'GH_TOKEN';\nconst DEFAULT_BASE_IMAGE = 'node:22-slim';\nconst DEFAULT_WORKING_DIRECTORY = '/workspace';\n// Only a full sha is unambiguous; a short hex string may be a branch or tag.\nconst FULL_SHA_PATTERN = /^[0-9a-f]{40}$/i;\nconst SHA_PATTERN = /^[0-9a-f]{40}$/i;\n\nconst CLONE_URL_ALLOWED_CHARS = /^[a-z0-9:/._-]+$/i;\nconst CLONE_URL_HOST_PATTERN = /^[a-z0-9.-]+$/i;\nconst CLONE_URL_SEGMENT_PATTERN = /^[\\w.-]+$/;\n/** Refs interpolate into shell too; git ref names are already restricted, so allowlist tightly. */\nconst REF_PATTERN = /^[\\w./-]+$/;\n\n/**\n * Repository clone target plus an optional credential. Structurally identical\n * to the E2B/platform type of the same name so a host can pass its context\n * accessor straight through.\n */\nexport interface RepositoryAccess {\n  /** https clone URL, e.g. `https://github.com/acme/widgets.git`. */\n  cloneUrl: string;\n  /** Credential for private repositories; presented to git as `x-access-token:<token>` basic auth. */\n  authorization?: { scheme: 'bearer'; token: string };\n}\n\nexport interface DockerRepoTemplateOptions {\n  /**\n   * Resolves the clone URL and, for private repositories, a short-lived\n   * credential. Called once per template resolution (each container-creating\n   * `start()`): the credential authenticates the head lookup and the build's\n   * clone. It is passed to the build by value, never through `process.env`,\n   * and is excluded from the template identity so rotation does not rebuild.\n   *\n   * Pass `undefined` for the function itself to mean \"no repository\":\n   * {@link createDockerRepoTemplate} then returns undefined so\n   * `template: createDockerRepoTemplate(ctx)` needs no conditional. If the\n   * function resolves to `undefined` at start time, the resolver rejects.\n   */\n  getRepositoryAccess:\n    | ((options?: DockerRepoTemplateResolveOptions) => Promise<RepositoryAccess | undefined>)\n    | undefined;\n  /**\n   * Branch, tag, or commit to prepare. The current head of a branch/tag is\n   * resolved at each template resolution and pinned into the identity.\n   * @default the remote's default branch\n   */\n  ref?: string;\n  /** Setup command(s) run inside the checkout as separate cached build steps. */\n  setupCommand?: string | string[];\n  /**\n   * Extra environment for every build step, including `setupCommand`. Baked\n   * into the image via `ENV` and hashed into the identity (keys and values),\n   * so it must be non-secret; put rotating credentials in\n   * {@link getRepositoryAccess} instead.\n   */\n  buildEnv?: Record<string, string> | ((options?: DockerRepoTemplateResolveOptions) => Promise<Record<string, string>>);\n  /**\n   * Absolute parent for the checkout; the repo lands at\n   * `<workingDirectory>/<repo>`, which becomes the build and runtime cwd.\n   * @default '/workspace'\n   */\n  workingDirectory?: string;\n  /**\n   * Base image. A custom base must provide `git` and `ca-certificates`; the\n   * default has them apt-installed as the first (cached) layer.\n   * @default 'node:22-slim'\n   */\n  baseImage?: string;\n  /** Pass-through dockerode connection options. */\n  dockerOptions?: DockerOptions;\n}\n\nexport interface DockerRepoTemplateResolveOptions {\n  /** Cancel repository access, build-environment resolution, or head lookup. */\n  abortSignal?: AbortSignal;\n}\n\n/** A resolver producing a fresh, head-pinned template on each call. */\nexport type DockerRepoTemplateResolver = (options?: DockerRepoTemplateResolveOptions) => Promise<DockerTemplate>;\n\nexport function createDockerRepoTemplate(options: DockerRepoTemplateOptions): DockerRepoTemplateResolver | undefined {\n  if (!options.getRepositoryAccess) return undefined;\n  if (options.ref !== undefined && !REF_PATTERN.test(options.ref)) {\n    throw new Error(`Invalid ref '${options.ref}': expected a git ref name`);\n  }\n  const workingDirectory = trimTrailingSlashes(options.workingDirectory ?? DEFAULT_WORKING_DIRECTORY);\n  if (!workingDirectory.startsWith('/')) {\n    throw new Error(`workingDirectory must be an absolute path, got '${options.workingDirectory}'`);\n  }\n  return resolveOptions => resolveRepoTemplate(options, workingDirectory, resolveOptions);\n}\n\nasync function resolveRepoTemplate(\n  options: DockerRepoTemplateOptions,\n  workingDirectory: string,\n  resolveOptions: DockerRepoTemplateResolveOptions = {},\n): Promise<DockerTemplate> {\n  const { abortSignal } = resolveOptions;\n  throwIfAborted(abortSignal, 'resolve Docker repository template');\n  let access: RepositoryAccess | undefined;\n  try {\n    access = await options.getRepositoryAccess!(resolveOptions);\n  } catch (error) {\n    throw normalizeAbortError(error, 'resolve Docker repository template');\n  }\n  throwIfAborted(abortSignal, 'resolve Docker repository template');\n  const cloneUrl = access?.cloneUrl;\n  if (!cloneUrl) {\n    throw new Error('Repo template has no clone URL: repository access returned none.');\n  }\n  assertCloneUrl(cloneUrl);\n  const token = access?.authorization?.token;\n  let buildEnv: Record<string, string> | undefined;\n  try {\n    buildEnv = typeof options.buildEnv === 'function' ? await options.buildEnv(resolveOptions) : options.buildEnv;\n  } catch (error) {\n    throw normalizeAbortError(error, 'resolve Docker repository template');\n  }\n  throwIfAborted(abortSignal, 'resolve Docker repository template');\n  const sha = await resolveHead(cloneUrl, options.ref, token, abortSignal);\n  throwIfAborted(abortSignal, 'resolve Docker repository template');\n  if (!sha) {\n    throw new Error(\n      `Could not resolve ${options.ref ?? 'HEAD'} of ${cloneUrl} with git ls-remote; check the ref, the credential and network access`,\n    );\n  }\n\n  return buildRepoTemplate({\n    cloneUrl,\n    sha,\n    token,\n    buildEnv,\n    setupCommand: options.setupCommand,\n    workingDirectory,\n    baseImage: options.baseImage,\n    dockerOptions: options.dockerOptions,\n  });\n}\n\ninterface RepoTemplateInputs {\n  cloneUrl: string;\n  sha: string;\n  token?: string;\n  buildEnv?: Record<string, string>;\n  setupCommand?: string | string[];\n  workingDirectory: string;\n  baseImage?: string;\n  dockerOptions?: DockerOptions;\n}\n\n/**\n * Pure assembly of the template from already-resolved inputs. Exported for\n * tests so the Dockerfile can be asserted without a network head lookup.\n * @internal\n */\nexport function buildRepoTemplate(inputs: RepoTemplateInputs): DockerTemplate {\n  const { cloneUrl, sha, token, buildEnv } = inputs;\n  const destination = `${trimTrailingSlashes(inputs.workingDirectory)}/${repoDirName(cloneUrl)}`;\n\n  let template = new DockerTemplate({\n    baseImage: inputs.baseImage ?? DEFAULT_BASE_IMAGE,\n    dockerOptions: inputs.dockerOptions,\n    ...(token ? { secrets: { [BUILD_TOKEN_ENV]: token } } : {}),\n  });\n\n  if (inputs.baseImage === undefined) {\n    // The slim default ships without git; a custom base is expected to bring its own.\n    template = template.aptInstall(['git', 'ca-certificates']);\n  }\n\n  if (buildEnv && Object.keys(buildEnv).length > 0) {\n    template = template.setEnvs(buildEnv);\n  }\n\n  const tokenEnv = token ? BUILD_TOKEN_ENV : undefined;\n  const clone = [\n    // Full clone so an arbitrary commit is reachable, then pin to it. The\n    // sha is in the command, so it is part of the template identity.\n    cloneFull({ cloneUrl, destination, tokenEnv }),\n    `git -C ${shellQuote(destination)} checkout --detach ${shellQuote(sha)}`,\n  ];\n\n  template = template\n    .runWithSecrets(clone, { secrets: tokenEnv ? [tokenEnv] : [], output: destination })\n    .setWorkdir(destination);\n\n  const setupCommands = normalizeSetupCommands(inputs.setupCommand);\n  for (const command of setupCommands) {\n    template = template.runCmd(command);\n  }\n  if (setupCommands.length > 0) {\n    // Written last, so the marker exists only when every setup step succeeded.\n    template = template.runCmd(setupMarkerCommand(setupMarkerContent(setupCommands)));\n  }\n  return template;\n}\n\n/**\n * Resolve `ref` (or the default branch) to a commit sha with `git ls-remote`\n * on the host, without cloning. A full sha is returned as is. Any failure\n * yields undefined; the caller decides how to surface it.\n * @internal exported for tests.\n */\nexport async function resolveHead(\n  cloneUrl: string,\n  ref: string | undefined,\n  token: string | undefined,\n  abortSignal?: AbortSignal,\n): Promise<string | undefined> {\n  throwIfAborted(abortSignal, 'resolve Docker repository template');\n  if (ref && FULL_SHA_PATTERN.test(ref)) return ref.toLowerCase();\n  try {\n    // The credential goes through GIT_CONFIG_* (git >= 2.31) rather than `-c`\n    // so it never appears in the process argv, which other local users can read.\n    const authEnv = token\n      ? {\n          GIT_CONFIG_COUNT: '1',\n          GIT_CONFIG_KEY_0: 'http.extraheader',\n          GIT_CONFIG_VALUE_0: `AUTHORIZATION: basic ${Buffer.from(`x-access-token:${token}`).toString('base64')}`,\n        }\n      : {};\n    // `--` keeps even a hostile URL from being read as an option.\n    const { stdout } = await execFileAsync('git', ['ls-remote', '--', cloneUrl, ref ?? 'HEAD'], {\n      timeout: 10_000,\n      signal: abortSignal,\n      env: { ...process.env, ...authEnv, GIT_TERMINAL_PROMPT: '0' },\n    });\n    // Prefer the peeled tag object (`refs/tags/x^{}`) when present.\n    const lines = stdout\n      .split('\\n')\n      .filter(Boolean)\n      .map(line => line.split('\\t'));\n    const peeled = lines.find(([, name]) => name?.endsWith('^{}'));\n    const sha = (peeled ?? lines[0])?.[0]?.trim();\n    return sha && SHA_PATTERN.test(sha) ? sha.toLowerCase() : undefined;\n  } catch (error) {\n    if (abortSignal?.aborted) throw normalizeAbortError(error, 'resolve Docker repository template');\n    return undefined;\n  }\n}\n\nfunction cloneFull({ cloneUrl, destination, tokenEnv }: { cloneUrl: string; destination: string; tokenEnv?: string }) {\n  // Mirrors `repoCloneCommand` from @internal/workspace, minus the shallow flags.\n  const auth = tokenEnv\n    ? `-c http.extraheader=\"AUTHORIZATION: basic $(printf 'x-access-token:%s' \"$${tokenEnv}\" | base64 -w0)\" `\n    : '';\n  return `git ${auth}clone ${shellQuote(cloneUrl)} ${shellQuote(destination)}`;\n}\n\nfunction assertCloneUrl(cloneUrl: string): void {\n  if (cloneUrl.length > 2048 || !CLONE_URL_ALLOWED_CHARS.test(cloneUrl)) {\n    throw new Error(`Invalid cloneUrl '${cloneUrl}': expected an https URL with a plain host and path`);\n  }\n  let url: URL;\n  try {\n    url = new URL(cloneUrl);\n  } catch {\n    throw new Error(`Invalid cloneUrl '${cloneUrl}': not a URL`);\n  }\n  const segments = url.pathname.split('/').slice(1);\n  const ok =\n    url.protocol === 'https:' &&\n    !url.username &&\n    !url.password &&\n    !url.search &&\n    !url.hash &&\n    CLONE_URL_HOST_PATTERN.test(url.hostname) &&\n    segments.length > 0 &&\n    segments.every(segment => CLONE_URL_SEGMENT_PATTERN.test(segment));\n  if (!ok) {\n    throw new Error(`Invalid cloneUrl '${cloneUrl}': expected an https URL such as https://host/owner/repo.git`);\n  }\n}\n\nfunction repoDirName(cloneUrl: string): string {\n  const last = trimTrailingSlashes(cloneUrl).split('/').at(-1) ?? '';\n  return (\n    last\n      .replace(/\\.git$/i, '')\n      .replace(/[^\\w.-]/g, '-')\n      .replace(/^\\.+/, '') || 'repo'\n  );\n}\n\nfunction trimTrailingSlashes(path: string): string {\n  let end = path.length;\n  while (end > 1 && path[end - 1] === '/') end--;\n  return path.slice(0, end);\n}\n\nfunction shellQuote(value: string): string {\n  return `'${value.replace(/'/g, `'\\\\''`)}'`;\n}\n"],"mappings":"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"}