{"version":3,"file":"tools-D0MBDh2R.mjs","names":["#formats"],"sources":["../src/batteries/sandbox/narrator.ts","../src/batteries/sandbox/media_reader.ts","../src/batteries/sandbox/defaults/extension_mime.ts","../src/batteries/sandbox/defaults/default_minter.ts","../src/batteries/sandbox/tools/index.ts"],"sourcesContent":["import type { ModelPath, ModelWriteRoot } from './types'\n\n/** Exhaustive model-facing sandbox outcome. */\nexport type SandboxOutcome =\n  | { kind: 'not-found'; path: string }\n  | { kind: 'denied-by-policy'; path: string; axis: 'read' | 'write' }\n  | { kind: 'gate-declined'; note?: string }\n  | { kind: 'gate-unavailable'; reason: 'timeout' | 'error' }\n  | {\n      kind: 'over-budget'\n      bound: 'maxTerminalPayloadBytes'\n      observedAtLeast: number\n      limit: number\n    }\n  | { kind: 'scope-limited'; shown: number; atDepth: number; bound: 'maxDepth' }\n  | { kind: 'result-limited'; shown: number; limit: number; bound: 'limit' }\n  | { kind: 'not-a-regular-file'; path: string; kind_: string }\n  | { kind: 'is-a-directory'; path: string }\n  | {\n      kind: 'path-rejected'\n      input: string\n      reason: 'escape' | 'absolute-host' | 'home' | 'unc' | 'device' | 'nul'\n    }\n  /** Model-facing root, conventionally `/`; NEVER the configured absolute host path. */\n  | { kind: 'outside-write-root'; path: ModelPath; writeRoot: ModelWriteRoot }\n  | { kind: 'sandbox-violation'; violations: readonly string[]; exitCode: number }\n  | { kind: 'nonzero-exit'; exitCode: number }\n  | { kind: 'no-matches'; pattern: string; scope: string }\n  | { kind: 'unknown-media'; mediaId: string }\n  | { kind: 'invalid-pattern'; pattern: string; detail: string }\n  | { kind: 'not-a-directory'; path: string }\n  | { kind: 'io-failure'; path?: string; detail: string }\n  | { kind: 'aborted' }\n  | { kind: 'timed-out'; bound: 'timeout_seconds'; limitSeconds: number }\n/** Model-facing narration seam; implementations must be total over {@link SandboxOutcome}. */\nexport type SandboxNarrator = (outcome: SandboxOutcome) => string\n/**\n * Render a path rejection with the remedy that fits its REASON.\n *\n * @remarks\n * Rule 2 of the LLM-operator rules: a failure is actionable or it is a loop. \"Use a workspace-relative\n * path\" is right for a `../` escape and useless for a NUL byte — the model cannot act on it, so it\n * retries a variation that fails identically. Each arm states the accepted form and echoes the input\n * as understood. Extracted rather than nested so exhaustiveness is enforced by this function's own\n * return type, with no `default` arm to silently mis-narrate a future reason.\n *\n * @param reason - Why the path was refused.\n * @param input - The model's path, echoed back.\n * @returns The model-facing message.\n */\nconst narratePathRejection = (\n  reason: Extract<SandboxOutcome, { kind: 'path-rejected' }>['reason'],\n  input: string\n): string => {\n  switch (reason) {\n    case 'nul':\n      return `Path rejected: it contains a NUL byte, which cannot appear in a filename. Remove it and try again (${JSON.stringify(input)}).`\n    case 'home':\n      return `Path rejected: '~' is not expanded here. Paths are relative to the workspace root, so name the directory directly (${input}).`\n    case 'absolute-host':\n      return `Path rejected: a drive letter names a host path, which is outside the workspace. Use a workspace-relative path (${input}).`\n    case 'device':\n      return `Path rejected: device and verbatim prefixes are not addressable here. Use a workspace-relative path (${input}).`\n    case 'unc':\n      return `Path rejected: a network share is outside the workspace. Use a workspace-relative path (${input}).`\n    case 'escape':\n      return `Path rejected: '../' leads outside the workspace root. Try a path within it, such as 'src/index.ts' (${input}).`\n  }\n}\n\n/** Existence-blind default narrator; not-found and denied-by-policy intentionally share wording. */\nexport const defaultSandboxNarrator: SandboxNarrator = (o) => {\n  switch (o.kind) {\n    case 'not-found':\n    case 'denied-by-policy':\n      return `No readable entry at <${o.path}>; retry with a known sandbox-relative path or provide a valid handle.`\n    case 'gate-declined':\n      return o.note\n        ? `Approval was declined: ${o.note}; request approval again or retry without the declined option.`\n        : 'Approval was declined; request approval and try again.'\n    case 'gate-unavailable':\n      return `Sandbox gate ${o.reason}; retry when available.`\n    case 'over-budget':\n      return `Output exceeded ${o.bound} (${o.observedAtLeast}+ bytes; limit ${o.limit}); retry with a smaller request or raise the limit.`\n    case 'scope-limited':\n      return `Search stopped at depth ${o.atDepth}; raise max_depth and try again.`\n    case 'result-limited':\n      return `Search stopped after ${o.shown} results; raise the limit (${o.limit}) and try again.`\n    case 'not-a-regular-file':\n      return `Not a regular file: <${o.path}>; retry with a regular file or use the directory operation.`\n    case 'is-a-directory':\n      return `Path is a directory: <${o.path}>; retry with a file path or use a directory operation if available.`\n    case 'path-rejected':\n      return narratePathRejection(o.reason, o.input)\n    case 'outside-write-root':\n      // `createModelWriteRoot` normalises the sandbox root to the empty relative string; render it as\n      // `/` — the model-facing \"top of what you can see\" — so the message never reads `outside <>`.\n      return `Write path <${o.path}> is outside <${o.writeRoot === '' ? '/' : o.writeRoot}>; choose a path inside it.`\n    case 'sandbox-violation':\n      return `Sandbox blocked the command (exit ${o.exitCode}): ${o.violations.join('; ')}; narrow the command to an allowed path or request access.`\n    case 'nonzero-exit':\n      return `Command exited with status ${o.exitCode}; inspect the command arguments and retry with a narrower operation.`\n    case 'no-matches':\n      return `No matches for pattern <${o.pattern}> in scope <${o.scope}>; use a narrower operation or try a different pattern or scope.`\n    case 'unknown-media':\n      return `Unknown media: ${o.mediaId}; retry with a valid media handle or use a media-discovery operation if available.`\n    case 'invalid-pattern':\n      return `Invalid pattern ${o.pattern}: ${o.detail}; correct the pattern and retry.`\n    case 'not-a-directory':\n      return `Not a directory: <${o.path}>; choose a directory path and retry.`\n    case 'io-failure':\n      return `I/O failure${o.path ? ` at <${o.path}>` : ''}: ${o.detail}; retry the operation or choose a narrower path.`\n    case 'aborted':\n      return 'Operation aborted; try again.'\n    case 'timed-out':\n      return `Operation timed out after ${o.limitSeconds} seconds; raise timeout_seconds and try again.`\n  }\n  const exhaustive: never = o\n  return exhaustive\n}\n","import { Media } from '../../common'\nimport { E_SANDBOX_FAILED, E_SANDBOX_NOT_INITIALIZED } from './exceptions'\nimport type { SandboxEpoch } from './types'\nimport type { SandboxFileSystem } from './contracts/file_system'\nimport type { MediaKind, MediaReader, MediaTrustTier } from '../../common'\n\n/** The capability needed to decide whether a sandbox handle is still alive. */\nexport type SandboxEpochIsLive = (epoch: SandboxEpoch) => boolean\n\n/** Arguments for {@link createSandboxMediaReader}. */\nexport interface SandboxMediaReaderOptions {\n  /** The filesystem capability belonging to the sandbox handle. */\n  fileSystem: SandboxFileSystem\n  /** The already translated backend path. */\n  path: string\n  /** The epoch held by the sandbox handle when this reader was issued. */\n  epoch: SandboxEpoch\n  /** Predicate owned by the sandbox manager; this reader never issues or invalidates epochs. */\n  isEpochLive: SandboxEpochIsLive\n}\n\nconst assertLive = (options: SandboxMediaReaderOptions): void => {\n  if (!options.isEpochLive(options.epoch)) throw new E_SANDBOX_NOT_INITIALIZED(['sandbox handle'])\n}\n\nconst statRegularFile = async (options: SandboxMediaReaderOptions) => {\n  assertLive(options)\n  const metadata = await options.fileSystem.stat(options.path)\n  if (metadata.kind !== 'file') {\n    throw new E_SANDBOX_FAILED([\n      `Sandbox path is not a regular file (kind: ${metadata.kind}): ${options.path}`,\n    ])\n  }\n  return metadata\n}\n\n/**\n * Create a non-describable, replayable reader over a sandbox file.\n *\n * @remarks\n * Every operation checks the owning epoch, stats the path, and refuses anything whose filesystem\n * kind is not `file` before opening it. Every stream call then asks the injected filesystem for a\n * fresh stream; this reader deliberately has no byte cap and does not import a host filesystem.\n * The reader omits `describe()` because approval-bound sandbox capabilities must not cross a\n * serialisation boundary.\n *\n * @param options - The sandbox filesystem, translated path, epoch, and liveness predicate.\n * @returns A file-backed {@link MediaReader}.\n */\nexport const createSandboxMediaReader = (options: SandboxMediaReaderOptions): MediaReader => ({\n  async stream(): Promise<ReadableStream<Uint8Array>> {\n    await statRegularFile(options)\n    assertLive(options)\n    return options.fileSystem.read(options.path)\n  },\n  async byteLength(): Promise<number> {\n    const metadata = await statRegularFile(options)\n    assertLive(options)\n    return metadata.size\n  },\n})\n\n/** Arguments for {@link createSandboxMedia}. */\nexport interface SandboxMediaOptions extends SandboxMediaReaderOptions {\n  /** Media modality assigned by the stage operation. */\n  kind: MediaKind\n  /** MIME type resolved by the stage operation. */\n  mimeType: string\n  /** Model-visible source filename. */\n  filename: string\n  /** Configuration-supplied provenance tier. */\n  trustTier: MediaTrustTier\n  /** Optional provenance label retained on the Media value. */\n  source?: string\n}\n\n/**\n * Construct the staged media value returned by a mutating sandbox operation.\n *\n * @remarks\n * The shipped Media factories supply the conservative modality hazard and keep the trust-tier\n * choice explicit at this call site. The reader remains deliberately non-describable.\n *\n * @param options - File-reader and media labelling options.\n * @returns A staged {@link Media} value.\n */\nexport const createSandboxMedia = (options: SandboxMediaOptions): Media => {\n  const args = {\n    kind: options.kind,\n    mimeType: options.mimeType,\n    filename: options.filename,\n    source: options.source,\n    reader: createSandboxMediaReader(options),\n  }\n  switch (options.trustTier) {\n    case 'first-party':\n      return Media.toolGenerated(args)\n    case 'third-party-public':\n      return Media.retrievedPublic(args)\n    case 'third-party-private':\n      return Media.retrievedPrivate(args)\n  }\n}\n","/** Pure extension-based MIME defaults for the sandbox file tools. */\nimport type { MimeResolver } from '@nhtio/adk/batteries/sandbox/contracts/mime_resolver'\n\n/** The default prefix available to a custom resolver. */\nexport const DEFAULT_MIME_PEEK_BYTES = 512\n\n/** Extension to MIME mappings used by the default resolver. */\nexport const SANDBOX_EXTENSION_MIME: Readonly<Record<string, string>> = {\n  pdf: 'application/pdf',\n  doc: 'application/msword',\n  docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n  xls: 'application/vnd.ms-excel',\n  xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n  ppt: 'application/vnd.ms-powerpoint',\n  pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',\n  csv: 'text/csv',\n  txt: 'text/plain',\n  md: 'text/markdown',\n  html: 'text/html',\n  htm: 'text/html',\n  json: 'application/json',\n  yaml: 'application/yaml',\n  yml: 'application/yaml',\n  rtf: 'application/rtf',\n  png: 'image/png',\n  jpg: 'image/jpeg',\n  jpeg: 'image/jpeg',\n  webp: 'image/webp',\n  gif: 'image/gif',\n  tiff: 'image/tiff',\n  tif: 'image/tiff',\n  avif: 'image/avif',\n  wav: 'audio/wav',\n  mp3: 'audio/mpeg',\n  ogg: 'audio/ogg',\n  flac: 'audio/flac',\n  ts: 'text/plain',\n  tsx: 'text/plain',\n  js: 'text/plain',\n  jsx: 'text/plain',\n  mjs: 'text/plain',\n  cjs: 'text/plain',\n  py: 'text/plain',\n  rb: 'text/plain',\n  go: 'text/plain',\n  rs: 'text/plain',\n  java: 'text/plain',\n  kt: 'text/plain',\n  swift: 'text/plain',\n  c: 'text/plain',\n  h: 'text/plain',\n  cc: 'text/plain',\n  cpp: 'text/plain',\n  hpp: 'text/plain',\n  cs: 'text/plain',\n  php: 'text/plain',\n  sh: 'text/plain',\n  bash: 'text/plain',\n  zsh: 'text/plain',\n  sql: 'text/plain',\n  toml: 'text/plain',\n  ini: 'text/plain',\n  cfg: 'text/plain',\n  conf: 'text/plain',\n  lua: 'text/plain',\n  pl: 'text/plain',\n  r: 'text/plain',\n  scala: 'text/plain',\n  dart: 'text/plain',\n  vue: 'text/plain',\n  svelte: 'text/plain',\n  css: 'text/plain',\n  scss: 'text/plain',\n  less: 'text/plain',\n  xml: 'application/xml',\n  svg: 'image/svg+xml',\n}\n\nconst extensionOf = (path: string): string | undefined => {\n  const name = path.split(/[\\\\/?#]/).pop() ?? ''\n  const dot = name.lastIndexOf('.')\n  if (dot <= 0 || dot === name.length - 1) return undefined\n  return name.slice(dot + 1).toLowerCase()\n}\n\n/** Resolve a MIME type from a filename, without sniffing bytes. */\nexport const extensionMimeResolver: MimeResolver = ({ path, declared }) => {\n  if (declared !== undefined && declared.trim() !== '') return declared\n  return SANDBOX_EXTENSION_MIME[extensionOf(path) ?? '']\n}\n\n/** The default resolver, also exported under the concise name used by consumers. */\nexport const defaultMimeResolver = extensionMimeResolver\n\n/**\n * Run a resolver and fall back to the extension resolver when it declines.\n * The callback supplied to consumer code is always bounded by `maxPeekBytes`.\n */\nexport const resolveMime = async (\n  path: string,\n  resolver?: MimeResolver,\n  options: {\n    declared?: string\n    maxPeekBytes?: number\n    peek?: (bytes: number) => Promise<Uint8Array>\n  } = {}\n): Promise<string | undefined> => {\n  const maxPeekBytes = Math.max(0, Math.floor(options.maxPeekBytes ?? DEFAULT_MIME_PEEK_BYTES))\n  const sourcePeek = options.peek ?? (async () => new Uint8Array(0))\n  const peek = async (bytes: number): Promise<Uint8Array> =>\n    sourcePeek(Math.min(maxPeekBytes, Math.max(0, Math.floor(bytes))))\n  if (resolver !== undefined) {\n    const detected = await resolver({\n      path,\n      declared: options.declared,\n      peek: async (bytes) => peek(Math.min(maxPeekBytes, Math.max(0, Math.floor(bytes)))),\n    })\n    if (detected !== undefined) return detected\n  }\n  return extensionMimeResolver({ path, declared: options.declared, peek })\n}\n","/** Pure default artifact-format registry for sandbox query results. */\nimport { extensionMimeResolver } from './extension_mime'\nimport { SpooledArtifact, SpooledJsonArtifact, SpooledMarkdownArtifact } from '@nhtio/adk/common'\nimport type { SpooledArtifactConstructor } from '@nhtio/adk/common'\nimport type { ArtifactMinter } from '@nhtio/adk/batteries/sandbox/contracts/artifact_minter'\n\n/** A format declaration accepted by the default minter. */\nexport type ArtifactFormat = {\n  /** Stable identifier for the format. */\n  id: string\n  /** MIME types handled by the format. */\n  mime: string[]\n  /** Filename extensions handled by the format. */\n  extensions: string[]\n  /** Lazy constructor loader; it is called only after the format is selected. */\n  ctor: () => Promise<unknown>\n}\n\nconst builtInFormats: ArtifactFormat[] = [\n  {\n    id: 'json',\n    mime: ['application/json'],\n    extensions: ['json'],\n    ctor: async () => SpooledJsonArtifact,\n  },\n  {\n    id: 'markdown',\n    mime: ['text/markdown'],\n    extensions: ['md', 'markdown'],\n    ctor: async () => SpooledMarkdownArtifact,\n  },\n]\n\n/** A pure minter with optional, lazily loaded consumer formats. */\nexport class DefaultArtifactMinter implements ArtifactMinter {\n  readonly #formats: readonly ArtifactFormat[]\n\n  constructor(formats: readonly ArtifactFormat[] = []) {\n    this.#formats = [...builtInFormats, ...formats]\n  }\n\n  /** Return format metadata without invoking any constructor thunk. */\n  async formats(): Promise<ArtifactFormat[]> {\n    return this.#formats.map((format) => ({\n      ...format,\n      mime: [...format.mime],\n      extensions: [...format.extensions],\n    }))\n  }\n\n  /** Resolve the constructor for a MIME type; unknown types use the base artifact. */\n  async constructorForMime(mime: string | undefined): Promise<SpooledArtifactConstructor> {\n    const normalized = mime?.toLowerCase().split(';')[0].trim()\n    const format = this.#formats.find((entry) =>\n      entry.mime.some((item) => item.toLowerCase() === normalized)\n    )\n    if (format === undefined) return SpooledArtifact\n    try {\n      const resolved = await format.ctor()\n      return isArtifactConstructor(resolved) ? resolved : SpooledArtifact\n    } catch {\n      return SpooledArtifact\n    }\n  }\n\n  /** Resolve the constructor from a MIME type, then an extension, without validating content. */\n  async constructorForPath(path: string, mime?: string): Promise<SpooledArtifactConstructor> {\n    const detected =\n      mime ?? (await extensionMimeResolver({ path, peek: async () => new Uint8Array(0) }))\n    return this.constructorForMime(detected)\n  }\n}\n\n/** The shared default registry. Its format thunks remain lazy until selected. */\nexport const defaultArtifactMinter = new DefaultArtifactMinter()\n\n/** Select the default artifact constructor for a path. */\nexport const artifactConstructorForPath = (path: string, mime?: string) =>\n  defaultArtifactMinter.constructorForPath(path, mime)\n\n/** Select a constructor from a caller-provided minter, never throwing on bad metadata. */\nexport const constructorFromMinter = async (\n  minter: ArtifactMinter,\n  mime: string | undefined\n): Promise<SpooledArtifactConstructor> => {\n  try {\n    const normalized = mime?.toLowerCase().split(';')[0].trim()\n    const formats = await minter.formats()\n    const format = formats.find((entry) =>\n      entry.mime.some((candidate) => candidate.toLowerCase() === normalized)\n    )\n    if (format === undefined) return SpooledArtifact\n    const resolved = await format.ctor()\n    return isArtifactConstructor(resolved) ? resolved : SpooledArtifact\n  } catch {\n    return SpooledArtifact\n  }\n}\n\nconst isArtifactConstructor = (value: unknown): value is SpooledArtifactConstructor =>\n  SpooledArtifact.isSpooledArtifactConstructor(value)\n","/** @module @nhtio/adk/batteries/sandbox/tools */\nimport { validator } from '@nhtio/validation'\nimport { isInstanceOf } from '../../../guards'\nimport { createSandboxMedia } from '../media_reader'\nimport { defaultSandboxNarrator } from '../narrator'\nimport { classifySandboxPathRejection } from '../paths'\nimport { resolveMime } from '../defaults/extension_mime'\nimport { createModelPath, createModelWriteRoot } from '../types'\nimport { defaultArtifactMinter } from '../defaults/default_minter'\nimport { E_TURN_GATE_ABORTED, E_TURN_GATE_TIMEOUT } from '../../../lib/exceptions/runtime'\nimport { E_SANDBOX_FAILED, E_SANDBOX_GATE_REQUIRED, E_SANDBOX_REFUSED } from '../exceptions'\nimport {\n  Tool,\n  Media,\n  SpooledArtifact,\n  SpooledJsonArtifact,\n  SpooledMarkdownArtifact,\n} from '../../../common'\nimport type { DerivedRules } from '../types'\nimport type { SandboxHandle } from '../manager'\nimport type { SandboxOutcome } from '../narrator'\nimport type { SandboxSearch } from '../contracts/search'\nimport type { MimeResolver } from '../contracts/mime_resolver'\nimport type { Tool as AdkTool } from '../../../lib/classes/tool'\nimport type { MediaTrustTier, MediaKind } from '../../../common'\nimport type { SandboxFileSystem } from '../contracts/file_system'\nimport type { PathTranslator } from '../contracts/path_translator'\nimport type { ArtifactMinter } from '../contracts/artifact_minter'\nimport type { DispatchContext } from '../../../lib/contracts/dispatch_context'\n\ntype GateVerdict = { approved: true } | { approved: false; note?: string }\ntype Gate = (\n  ctx: DispatchContext,\n  call: { tool: string; args: unknown }\n) => GateVerdict | void | Promise<GateVerdict | void>\n/** Options for constructing the sandbox's eight untrusted filesystem tools. */\nexport interface SandboxToolsOptions {\n  /**\n   * The handle that owns this tool set and issues its reader epoch.\n   *\n   * @remarks\n   * File-backed readers retain this epoch and check it before every operation. After\n   * {@link SandboxHandle.dispose} they fail with `E_SANDBOX_NOT_INITIALIZED` rather than\n   * falling through to the host filesystem.\n   */\n  handle: SandboxHandle\n  /** The filesystem capability used for stat, traversal, reads, and writes. */\n  fileSystem: SandboxFileSystem\n  /** Translates model-visible paths into the sandbox backend and back. */\n  pathTranslator: PathTranslator\n  /**\n   * Required approval callback for every tool, including reads and searches.\n   *\n   * @remarks\n   * A read of `.env` is an exfiltration event, and `search_files` is a secret-discovery\n   * primitive, so construction rejects a missing gate with `E_SANDBOX_GATE_REQUIRED`.\n   * Calling the gate is a real suspension: a harness without a decider leaves the turn\n   * waiting rather than silently allowing the operation.\n   */\n  gate: Gate\n  /**\n   * Search backend for `search_files` and `find_files`.\n   *\n   * @remarks\n   * These tools spawn `rg` through the sandbox enforcer and are OS-enforced; they do not\n   * have the in-process filesystem tools' weaker enforcement boundary.\n   */\n  search?: SandboxSearch\n  /** Factory for artifacts returned by file-query tools; defaults to the battery minter. */\n  artifactMinter?: ArtifactMinter\n  /** Resolves MIME types while staging a file; defaults to the extension resolver. */\n  mimeResolver?: MimeResolver\n  /** Explicit host write root; it is never inferred. */\n  writeRoot: string\n  /**\n   * Configuration-supplied provenance for staged media.\n   *\n   * @remarks\n   * This value cannot be inferred from `source`: core requires an explicit trust tier and\n   * batteries must not auto-classify content.\n   */\n  trustTier: MediaTrustTier\n  /** Tools which are not registered are not named in descriptions. */\n  registeredTools?: readonly string[]\n}\n\nconst argsPath = (extra: Record<string, unknown> = {}) =>\n  validator.object({ path: validator.string().required(), ...extra })\nconst depth = validator.number().integer().min(0).default(20)\nconst json = (value: unknown): string => JSON.stringify(value)\nconst relativeFramePath = (root: string, value: string): string => {\n  const prefix = root === '/' ? '/' : `${root}/`\n  return value === root ? '' : value.startsWith(prefix) ? value.slice(prefix.length) : value\n}\nconst isDenied = (\n  rules: DerivedRules | undefined,\n  path: string,\n  axis: 'read' | 'write'\n): boolean => {\n  if (!rules || rules.filesystemDisabled) return false\n  const under = (rule: string): boolean =>\n    rule === '/' || path === rule || path.startsWith(`${rule}/`)\n  const list = axis === 'read' ? rules.read.denyOnly : rules.write.denyWithinAllow\n  if (axis === 'read')\n    return rules.read.denyOnly.some(under) && !rules.read.allowWithinDeny.some(under)\n  return !rules.write.allowOnly.some(under) || list.some(under)\n}\nconst narrateThrow = (outcome: SandboxOutcome, refused = true): never => {\n  const message = defaultSandboxNarrator(outcome)\n  if (refused) throw new E_SANDBOX_REFUSED([message])\n  throw new E_SANDBOX_FAILED([message])\n}\n\n/**\n * Run a `PathTranslator` operation and narrate any refusal it raises.\n *\n * @remarks\n * EVERY translator call must go through here, not just the obvious `toRelative`. `toBackendPath` and\n * `assertNoSymlinkComponents` both reject — the latter is the symlinked-component refusal, which is a\n * security control — and a bare call lets that escape as the translator's native error, bypassing the\n * narrator seam the whole battery depends on. The model then receives an unactionable message for the\n * one class of failure it could actually correct.\n *\n * An already-narrated exception passes through untouched, so wrapping a call that itself narrates is\n * safe and the outcome is never rendered twice.\n *\n * @param operation - The translator call.\n * @param input - The model-supplied path, echoed back in the outcome.\n * @param reason - The `path-rejected` reason to narrate.\n * @returns The operation's result.\n */\nexport const narratingPath = async <T>(\n  operation: () => T | Promise<T>,\n  input: string\n): Promise<T> => {\n  try {\n    return await operation()\n  } catch (error) {\n    if (\n      isInstanceOf(error, 'E_SANDBOX_REFUSED', E_SANDBOX_REFUSED) ||\n      isInstanceOf(error, 'E_SANDBOX_FAILED', E_SANDBOX_FAILED)\n    )\n      throw error\n    // The REASON is classified from the input rather than assumed. Hardcoding `'escape'` told a model\n    // that supplied a NUL byte or a UNC path to \"use a workspace-relative path\", which is unactionable\n    // advice for those mistakes — and the plan asks for one distinct case per reason.\n    return narrateThrow(\n      { kind: 'path-rejected', input, reason: classifySandboxPathRejection(input) ?? 'escape' },\n      false\n    )\n  }\n}\n/**\n * Classify an unexpected fault as `io-failure`, PRESERVING any already-narrated outcome.\n *\n * @remarks\n * A catch that wraps unconditionally destroys the classification the seam just made: a per-child\n * `path-rejected` inside a traversal would reach the model as \"the listing broke\" — wrong, and\n * unactionable. Only genuinely unclassified faults become `io-failure`.\n *\n * @param error - The caught value.\n * @param path - The model-facing path for the outcome.\n * @returns Never; always throws.\n */\nconst rethrowAsIoFailure: (error: unknown, path: string) => never = (error, path) => {\n  if (\n    isInstanceOf(error, 'E_SANDBOX_REFUSED', E_SANDBOX_REFUSED) ||\n    isInstanceOf(error, 'E_SANDBOX_FAILED', E_SANDBOX_FAILED)\n  )\n    throw error\n  throw new E_SANDBOX_FAILED([\n    defaultSandboxNarrator({ kind: 'io-failure', path, detail: String(error) }),\n  ])\n}\n\nconst regular = async (options: SandboxToolsOptions, relative: string, axis: 'read' | 'write') => {\n  // Also narrated: this is the shared pre-flight for `open_file*` and `stage_file`, so an unguarded\n  // translation here would bypass the seam on the two most-used tools rather than just one.\n  const backend = await narratingPath(\n    () => options.pathTranslator.toBackendPath(relative),\n    relative\n  )\n  if (isDenied(options.handle.effectivePolicy(), backend, axis))\n    narrateThrow({ kind: 'denied-by-policy', path: relative, axis })\n  let stat\n  try {\n    stat = await options.fileSystem.stat(backend)\n  } catch {\n    narrateThrow({ kind: 'not-found', path: relative })\n  }\n  if (stat!.kind === 'dir') narrateThrow({ kind: 'is-a-directory', path: relative })\n  if (stat!.kind !== 'file')\n    narrateThrow({ kind: 'not-a-regular-file', path: relative, kind_: stat!.kind })\n  return backend\n}\nconst gated = async (\n  options: SandboxToolsOptions,\n  ctx: DispatchContext,\n  tool: string,\n  args: unknown\n) => {\n  try {\n    const verdict = await options.gate(ctx, { tool, args })\n    if (verdict && !verdict.approved) narrateThrow({ kind: 'gate-declined', note: verdict.note })\n  } catch (error) {\n    if (\n      isInstanceOf(error, 'E_SANDBOX_REFUSED', E_SANDBOX_REFUSED) ||\n      isInstanceOf(error, 'E_SANDBOX_FAILED', E_SANDBOX_FAILED)\n    )\n      throw error\n    // THE THREE-CASE ABORT SPLIT. Both a turn-level abort and `TurnGate.abort()` reject with the\n    // SAME `E_TURN_GATE_ABORTED`, so the error type cannot tell them apart — only the signal can,\n    // and only best-effort (two benign races are named in the plan; neither can approve work).\n    //   · signal already set ⇒ the dispatch is unwinding and there is no reader ⇒ rethrow RAW;\n    //   · signal not yet set ⇒ the gate alone was cancelled and the model IS reading ⇒ narrate.\n    // Collapsing both into `gate-unavailable` would narrate into a torn-down dispatch and mislabel\n    // a cancellation as a broken gate.\n    if (isInstanceOf(error, 'E_TURN_GATE_ABORTED', E_TURN_GATE_ABORTED)) {\n      if (ctx.abortSignal?.aborted) throw error\n      narrateThrow({ kind: 'aborted' })\n    }\n    // A gate TIMEOUT is its own cause and its own reason. Reporting it as `'error'` tells the\n    // operator the gate broke when in fact nobody answered it — the headless-decider trap.\n    narrateThrow({\n      kind: 'gate-unavailable',\n      reason: isInstanceOf(error, 'E_TURN_GATE_TIMEOUT', E_TURN_GATE_TIMEOUT) ? 'timeout' : 'error',\n    })\n  }\n}\nconst makeOpen = (\n  options: SandboxToolsOptions,\n  name: string,\n  ctor: typeof SpooledArtifact,\n  description: string\n) =>\n  new Tool({\n    name,\n    description,\n    trusted: false,\n    artifactConstructor: () => ctor,\n    inputSchema: argsPath(),\n    handler: async (raw, ctx) => {\n      await gated(options, ctx, name, raw)\n      let path!: string\n      try {\n        path = await options.pathTranslator.toRelative((raw as { path: string }).path)\n      } catch {\n        narrateThrow({\n          kind: 'path-rejected',\n          input: (raw as { path: string }).path,\n          reason: classifySandboxPathRejection((raw as { path: string }).path) ?? 'escape',\n        })\n      }\n      const backend = await regular(options, path!, 'read')\n      try {\n        const reader = await ctx.storeRetrievableBytes(\n          `${ctx.id}:${name}:${path}`,\n          await options.fileSystem.read(backend, { signal: ctx.abortSignal })\n        )\n        return new ctor(reader)\n      } catch (error) {\n        rethrowAsIoFailure(error, path)\n      }\n    },\n  })\nconst framesArtifact = async (\n  ctx: DispatchContext,\n  id: string,\n  frames: unknown[],\n  note?: string\n) => {\n  const body = `${note ? `${note}\\n` : ''}${frames.map(json).join('\\n')}${frames.length ? '\\n' : ''}`\n  const reader = await ctx.storeRetrievableBytes(id, body)\n  return new SpooledJsonArtifact(reader)\n}\nconst descriptions = {\n  open: 'Read a file from disk into the turn to query, not to change. Use artifact_* tools; use stage_file to change it.',\n  stage:\n    'Change a file: use stage_file, then media verbs and save_media; mutations are in memory until saved. Use open_file to read or grep first; no artifact_* tools attach.',\n  save: 'Write to a file on disk: save bytes already in this turn, produced by media verbs; you cannot author content here. This overwrites and makes a stage_file edit real.',\n}\n/**\n * Construct the sandbox's file, media, directory, and search tools.\n *\n * @remarks\n * All returned tools are untrusted and gate their operations, including reads. The factory\n * keeps the supplied handle, filesystem, path translator, search backend, and configuration\n * together so the tools cannot accidentally bypass the sandbox boundary.\n *\n * @param options - Capabilities and configuration for the sandbox tool set.\n * @returns The eight tools registered for a sandbox handle.\n */\nexport const createSandboxTools = async (options: SandboxToolsOptions): Promise<AdkTool[]> => {\n  if (typeof options.gate !== 'function')\n    throw new E_SANDBOX_GATE_REQUIRED(['A gate is required for every sandbox tool'])\n  const minter = options.artifactMinter ?? defaultArtifactMinter\n  void minter\n  const open = makeOpen(\n    options,\n    'open_file',\n    SpooledArtifact,\n    `${descriptions.open} open_file works for any regular file and provides generic query tools.`\n  )\n  const openJson = makeOpen(\n    options,\n    'open_json_file',\n    SpooledJsonArtifact,\n    `${descriptions.open} This format-specific tool provides artifact_json_*; invalid JSON remains queryable as text.`\n  )\n  const openMarkdown = makeOpen(\n    options,\n    'open_markdown_file',\n    SpooledMarkdownArtifact,\n    `${descriptions.open} This format-specific tool provides markdown query tools.`\n  )\n  const stage = new Tool({\n    name: 'stage_file',\n    description: descriptions.stage,\n    trusted: false,\n    inputSchema: argsPath(),\n    handler: async (raw, ctx) => {\n      await gated(options, ctx, 'stage_file', raw)\n      let path!: string\n      try {\n        path = await options.pathTranslator.toRelative((raw as { path: string }).path)\n      } catch {\n        narrateThrow({\n          kind: 'path-rejected',\n          input: (raw as { path: string }).path,\n          reason: classifySandboxPathRejection((raw as { path: string }).path) ?? 'escape',\n        })\n      }\n      const backend = await regular(options, path!, 'read')\n      let mime: string | undefined\n      try {\n        mime = await resolveMime(path, options.mimeResolver, {\n          peek: async (n) => {\n            const stream = await options.fileSystem.read(backend)\n            const r = stream.getReader()\n            const x = await r.read()\n            r.releaseLock()\n            return (x.value ?? new Uint8Array()).slice(0, n)\n          },\n        })\n      } catch (error) {\n        rethrowAsIoFailure(error, path)\n      }\n      const kind: MediaKind = mime?.startsWith('image/')\n        ? 'image'\n        : mime?.startsWith('audio/')\n          ? 'audio'\n          : mime?.startsWith('video/')\n            ? 'video'\n            : 'document'\n      return createSandboxMedia({\n        fileSystem: options.fileSystem,\n        path: backend,\n        epoch: options.handle.epoch,\n        isEpochLive: options.handle.isEpochLive,\n        kind,\n        mimeType: mime ?? 'application/octet-stream',\n        filename: path,\n        trustTier: options.trustTier,\n      })\n    },\n  })\n  const save = new Tool({\n    name: 'save_media',\n    description: descriptions.save,\n    trusted: false,\n    inputSchema: validator.object({\n      media_id: validator.string().required(),\n      path: validator.string().required(),\n    }),\n    handler: async (raw, ctx) => {\n      await gated(options, ctx, 'save_media', raw)\n      const a = raw as { media_id: string; path: string }\n      let path!: string\n      try {\n        path = await options.pathTranslator.toRelative(a.path)\n      } catch {\n        narrateThrow({\n          kind: 'path-rejected',\n          input: a.path,\n          reason: classifySandboxPathRejection(a.path) ?? 'escape',\n        })\n      }\n      let root!: string\n      try {\n        root = await options.pathTranslator.toRelative(options.writeRoot)\n      } catch {\n        narrateThrow({\n          kind: 'path-rejected',\n          input: options.writeRoot,\n          reason: classifySandboxPathRejection(options.writeRoot) ?? 'escape',\n        })\n      }\n      if (!(root === '' || path === root || path.startsWith(`${root}/`)))\n        narrateThrow({\n          kind: 'outside-write-root',\n          path: createModelPath(path),\n          writeRoot: createModelWriteRoot(root),\n        })\n      const mediaResults = [...ctx.turnToolCalls]\n        .map((call) => call.results)\n        .flatMap((result) => (Array.isArray(result) ? result : [result]))\n      const media = mediaResults.find(\n        (result): result is Media => Media.isMedia(result) && result.id === a.media_id\n      )\n      if (!Media.isMedia(media)) narrateThrow({ kind: 'unknown-media', mediaId: a.media_id })\n      const backend = await narratingPath(() => options.pathTranslator.toBackendPath(path), a.path)\n      if (isDenied(options.handle.effectivePolicy(), backend, 'write'))\n        narrateThrow({ kind: 'denied-by-policy', path, axis: 'write' })\n      // The symlinked-component refusal is a SECURITY control, so its rejection must reach the model\n      // as an actionable `path-rejected` rather than the translator's native error.\n      await narratingPath(() => options.pathTranslator.assertNoSymlinkComponents(path), a.path)\n      try {\n        await options.fileSystem.write(backend, await media!.stream(), {\n          signal: ctx.abortSignal,\n        })\n        const written = await options.fileSystem.stat(backend)\n        return `Saved ${path} (${written.size} bytes)`\n      } catch (error) {\n        rethrowAsIoFailure(error, path)\n      }\n    },\n  })\n  const list = new Tool({\n    name: 'list_directory',\n    description:\n      'Return a complete queryable JSON listing. The only boundary is max_depth; raise it to inspect an unexplored subtree. Prefer find_files for names and list_media for media already in the turn.',\n    trusted: false,\n    inputSchema: argsPath({ max_depth: depth }),\n    handler: async (raw, ctx) => {\n      await gated(options, ctx, 'list_directory', raw)\n      const a = raw as { path: string; max_depth: number }\n      let root!: string\n      try {\n        root = await options.pathTranslator.toRelative(a.path)\n      } catch {\n        narrateThrow({\n          kind: 'path-rejected',\n          input: a.path,\n          reason: classifySandboxPathRejection(a.path) ?? 'escape',\n        })\n      }\n      const backend = await narratingPath(() => options.pathTranslator.toBackendPath(root!), a.path)\n      if (isDenied(options.handle.effectivePolicy(), backend, 'read'))\n        narrateThrow({ kind: 'denied-by-policy', path: root, axis: 'read' })\n      let frames: unknown[] = []\n      let limited = false\n      let sawDone = false\n      try {\n        for await (const frame of options.fileSystem.list(backend, {\n          maxDepth: a.max_depth,\n          signal: ctx.abortSignal,\n        })) {\n          if (\n            frame.kind === 'item' &&\n            !isDenied(\n              options.handle.effectivePolicy(),\n              // Per CHILD, inside the traversal: a refusal here must still narrate rather than\n              // surface as the directory's I/O failure carrying the translator's native text.\n              await narratingPath(\n                () => options.pathTranslator.toBackendPath(relativeFramePath(backend, frame.path)),\n                frame.path\n              ),\n              'read'\n            )\n          )\n            frames.push({ ...frame, path: relativeFramePath(backend, frame.path) })\n          if (frame.kind === 'done') {\n            // `list_directory` HAS NO `limit` — its only boundary is max_depth — so a\n            // `bound: 'limit'` frame cannot be a legitimate truncation here and means the backend\n            // is broken. `Done` is a union shared with the search frames, which is the only reason\n            // the shape is expressible at all.\n            //\n            // This is deliberately the OPPOSITE of `search_files`/`find_files` (see `makeSearch`\n            // below): those take a required `limit`, so the same frame is their ORDINARY\n            // truncation outcome and narrates `result-limited`. The rule is per-operation, not\n            // per-frame, and this throw belongs to `list_directory` alone — a copy of it inside\n            // `makeSearch` made every broad `find_files` query fail on its own limit.\n            if (!frame.complete && frame.bound === 'limit')\n              throw new Error('list backend emitted an over-limit frame')\n            sawDone = true\n            limited = !frame.complete\n          }\n        }\n        if (!sawDone) throw new Error('listing ended without a done frame')\n      } catch (error) {\n        rethrowAsIoFailure(error, root)\n      }\n      return framesArtifact(\n        ctx,\n        `${ctx.id}:list:${root}`,\n        frames,\n        limited\n          ? defaultSandboxNarrator({\n              kind: 'scope-limited',\n              shown: 0,\n              atDepth: a.max_depth,\n              bound: 'maxDepth',\n            })\n          : undefined\n      )\n    },\n  })\n  /**\n   * `follow` is deliberately schema-VALID while the bundled ripgrep adapter refuses it. The schema\n   * is shared by every deployment, and a BYO `SandboxSearch` that has verified its own containment\n   * of symlinked descendants may honour the flag; narrowing the schema to `valid(false)` would make\n   * it unreachable for them too. The bundled refusal is adapter-specific and names the pending\n   * containment audit, so a caller learns why rather than finding the option silently absent.\n   */\n  // `follow` traverses symlinked DESCENDANTS, which never pass through the path translator, so\n  // an uncontained backend turns it into an unbounded read. The tools layer cannot see what is\n  // behind `SandboxSearch`, so the ADAPTER declares whether it contains them. Undeclared, the\n  // schema rejects `follow: true` at validation rather than advertising an option that fails at\n  // execution — a narrowed COPY of the permissive rule, so an adapter that HAS verified\n  // containment still gets the full option.\n  // Over-limit is the ORDINARY outcome for these two: `limit` is required, so exceeding it\n  // narrates `result-limited` and returns the bounded results. Contrast `list_directory` above,\n  // which has no `limit` and treats the same frame as a backend protocol violation.\n  const permissiveFollow = validator.boolean().default(false)\n  // REJECTS `follow: true` unless the adapter declared containment. `.valid(false)` on a COPY,\n  // so an adapter that DID declare it still gets the permissive rule.\n  const followRejectedUnlessDeclared = options.search?.supportsFollow\n    ? permissiveFollow\n    : permissiveFollow.valid(false)\n  const makeSearch = (name: string, content: boolean) =>\n    new Tool({\n      name,\n      description: content\n        ? 'Search file contents on disk that you have not opened; artifact_grep searches one artifact you already opened. Every whole hit is queryable JSON. Bounded by max_depth and a required limit; exceeding limit returns the bounded hits with a result-limited note, not an error. follow (symlink traversal) is not available in this deployment.'\n        : 'Find file names across the disk tree, rather than searching contents. Every result is queryable JSON. Bounded by max_depth and a required limit; exceeding limit returns the bounded paths with a result-limited note, not an error. follow (symlink traversal) is not available in this deployment.',\n      trusted: false,\n      inputSchema: validator.object({\n        [content ? 'pattern' : 'glob']: validator.string().required(),\n        path: validator.string().allow('').default(''),\n        max_depth: depth,\n        limit: validator.number().integer().min(1).required(),\n        ...(content\n          ? {\n              ignore_case: validator.boolean().default(false),\n              literal: validator.boolean().default(false),\n              glob: validator.string().allow('').optional(),\n              iglob: validator.string().allow('').optional(),\n              // Rejects `true` at validation unless the adapter set `supportsFollow` (see above).\n              follow: followRejectedUnlessDeclared,\n              hidden: validator.boolean().default(false),\n              no_ignore: validator.boolean().default(false),\n            }\n          : {\n              iglob: validator.string().allow('').optional(),\n              // Rejects `true` at validation unless the adapter set `supportsFollow` (see above).\n              follow: followRejectedUnlessDeclared,\n              hidden: validator.boolean().default(false),\n              no_ignore: validator.boolean().default(false),\n            }),\n      }),\n      handler: async (raw, ctx) => {\n        await gated(options, ctx, name, raw)\n        const a = raw as {\n          pattern?: string\n          glob?: string\n          path: string\n          max_depth: number\n          limit: number\n          ignore_case?: boolean\n          literal?: boolean\n          iglob?: string\n          follow?: boolean\n          hidden?: boolean\n          no_ignore?: boolean\n        }\n        const root = await narratingPath(() => options.pathTranslator.toRelative(a.path), a.path)\n        const search = options.search\n        if (!search)\n          narrateThrow(\n            { kind: 'io-failure', path: root, detail: 'search backend unavailable' },\n            false\n          )\n        // Translated ONCE, through the seam. Three separate bare calls previously let a translator\n        // refusal escape as a generic downstream error instead of a narrated `path-rejected`.\n        const backendRoot = await narratingPath(\n          () => options.pathTranslator.toBackendPath(root),\n          a.path\n        )\n        const iterable = content\n          ? search!.searchContent({\n              root: backendRoot,\n              pattern: a.pattern!,\n              maxDepth: a.max_depth,\n              limit: a.limit,\n              ignoreCase: a.ignore_case,\n              literal: a.literal,\n              glob: a.glob,\n              iglob: a.iglob,\n              follow: a.follow,\n              hidden: a.hidden,\n              noIgnore: a.no_ignore,\n              signal: ctx.abortSignal,\n            })\n          : search!.findPaths({\n              root: backendRoot,\n              glob: a.glob!,\n              maxDepth: a.max_depth,\n              limit: a.limit,\n              iglob: a.iglob,\n              follow: a.follow,\n              hidden: a.hidden,\n              noIgnore: a.no_ignore,\n              signal: ctx.abortSignal,\n            })\n        const frames: unknown[] = []\n        let terminal:\n          | Extract<typeof iterable extends AsyncIterable<infer F> ? F : never, { kind: 'done' }>\n          | undefined\n        let sawDone = false\n        try {\n          for await (const frame of iterable) {\n            if (frame.kind === 'item')\n              frames.push({\n                ...frame,\n                path: relativeFramePath(backendRoot, frame.path),\n              })\n            else {\n              sawDone = true\n              terminal = frame\n            }\n          }\n          if (!sawDone) throw new Error('search ended without a done frame')\n        } catch (error) {\n          rethrowAsIoFailure(error, root)\n        }\n        const note = frames.length\n          ? undefined\n          : defaultSandboxNarrator({\n              kind: 'no-matches',\n              pattern: content ? a.pattern! : a.glob!,\n              scope: root,\n            })\n        return framesArtifact(\n          ctx,\n          `${ctx.id}:${name}:${root}`,\n          frames,\n          terminal && !terminal.complete\n            ? // `limit` is REQUIRED on both search tools, so an over-limit terminal frame is the\n              // ordinary truncation outcome: narrate it and return the bounded results. It is NOT\n              // an error here, unlike `list_directory`, which has no `limit` and treats the same\n              // frame as a backend protocol violation.\n              terminal.bound === 'limit'\n              ? defaultSandboxNarrator({\n                  kind: 'result-limited',\n                  shown: terminal.shown,\n                  limit: a.limit,\n                  bound: 'limit',\n                })\n              : defaultSandboxNarrator({\n                  kind: 'scope-limited',\n                  shown: frames.length,\n                  atDepth: terminal.atDepth,\n                  bound: 'maxDepth',\n                })\n            : note\n        )\n      },\n    })\n  return [\n    open,\n    openJson,\n    openMarkdown,\n    stage,\n    save,\n    list,\n    makeSearch('search_files', true),\n    makeSearch('find_files', false),\n  ]\n}\n/** Alias for {@link createSandboxTools}, used by tool-forging integrations. */\nexport const forgeSandboxTools = createSandboxTools\n/** Human-readable descriptions shared by the sandbox's workspace tools. */\nexport { descriptions as sandboxToolDescriptions }\n"],"mappings":"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"}