{"version":3,"file":"js.cjs","names":[],"sources":["../../../src/batteries/sandbox/js/exceptions.ts","../../../src/batteries/sandbox/js/validation.ts","../../../src/batteries/sandbox/js/compartment.ts","../../../src/batteries/sandbox/js/service.ts","../../../src/batteries/sandbox/js/runner.ts","../../../src/batteries/sandbox/js/tool.ts"],"sourcesContent":["import { createException } from '../../../lib/utils/exceptions'\n\n/** SES lockdown was unavailable or did not harden the guest realm. */\nexport const E_SES_LOCKDOWN_REQUIRED = createException<[string]>(\n  'E_SES_LOCKDOWN_REQUIRED',\n  '%s',\n  'E_SES_LOCKDOWN_REQUIRED',\n  500,\n  false\n)\n/** In-process SES evaluation requires hardening the complete host realm. */\nexport const E_SES_HOST_LOCKDOWN_REQUIRED = createException<[string]>(\n  'E_SES_HOST_LOCKDOWN_REQUIRED',\n  '%s',\n  'E_SES_HOST_LOCKDOWN_REQUIRED',\n  500,\n  false\n)\n/** A guest evaluation exceeded its tool-selected deadline. */\nexport const E_SES_EVALUATION_TIMEOUT = createException<[string]>(\n  'E_SES_EVALUATION_TIMEOUT',\n  '%s',\n  'E_SES_EVALUATION_TIMEOUT',\n  408,\n  false\n)\n","import { E_INVALID_SANDBOX_CONFIG } from '../exceptions'\nimport { guestLimitFloors, guestLimitsDefaults, hostcallQuotasDefaults } from '../types'\nimport type { GuestLimits, HostcallQuotas } from '../types'\n\nconst resolve = <T extends object>(\n  partial: Partial<T> | undefined,\n  defaults: T,\n  floors: T,\n  label: string\n): T => {\n  const out = { ...defaults, ...(partial ?? {}) } as T\n  for (const key of Object.keys(defaults)) {\n    const value = (out as Record<string, number>)[key]\n    const floor = (floors as Record<string, number>)[key]\n    if (\n      typeof value !== 'number' ||\n      !Number.isFinite(value) ||\n      !Number.isInteger(value) ||\n      value < floor\n    )\n      throw new E_INVALID_SANDBOX_CONFIG([\n        `${label}.${key}=${String(value)} must be a finite integer >= ${floor}`,\n      ])\n  }\n  return out\n}\n/** Resolve and validate all seven guest limits exactly once. */\nexport const resolveGuestLimits = (value?: Partial<GuestLimits>): GuestLimits =>\n  resolve(value, guestLimitsDefaults, guestLimitFloors, 'limits')\n/** Resolve and validate all three hostcall quotas exactly once. */\nexport const resolveHostcallQuotas = (value?: Partial<HostcallQuotas>): HostcallQuotas =>\n  resolve(\n    value,\n    hostcallQuotasDefaults,\n    { hostcallTimeoutMs: 1, maxHostcallsPerEvaluation: 1, maxConcurrentHostcalls: 1 },\n    'hostcallQuotas'\n  )\n","import { isError, isInstanceOf } from '@nhtio/adk/guards'\nimport {\n  E_SES_HOST_LOCKDOWN_REQUIRED,\n  E_SES_LOCKDOWN_REQUIRED,\n  E_SES_EVALUATION_TIMEOUT,\n} from './exceptions'\nimport type { GuestOutcome, GuestLimits } from '../types'\n\nconst cut = (text: string, bytes: number): { text: string; truncated: boolean } => {\n  const suffix = '… [cut]'\n  if (new TextEncoder().encode(text).byteLength <= bytes) return { text, truncated: false }\n  let value = text\n  while (new TextEncoder().encode(`${value}${suffix}`).byteLength > bytes)\n    value = value.slice(0, -1)\n  return { text: `${value}${suffix}`, truncated: true }\n}\nconst render = (value: unknown): { value: unknown; encoding: 'encoder' | 'partial' } => {\n  try {\n    return {\n      value: JSON.parse(JSON.stringify(value, (_k, v) => (typeof v === 'bigint' ? `${v}n` : v))),\n      encoding: 'encoder',\n    }\n  } catch {\n    return { value: `[unrepresentable ${typeof value}]`, encoding: 'partial' }\n  }\n}\n/**\n * Construct a minimal SES-backed in-process guest.\n *\n * @remarks In Node, SES lockdown is process-global: this hardens the whole host realm, not\n * only the guest. Guest-scoped isolation requires a worker or child runtime.\n */\nexport const createCompartmentRuntime = async (\n  globals: Record<string, (...args: unknown[]) => unknown>,\n  limits: GuestLimits,\n  modules: Record<string, unknown> = {},\n  hostLockdown = true\n) => {\n  await import('ses')\n  const realm = globalThis as typeof globalThis & {\n    lockdown?: () => void\n    Compartment?: new (\n      endowments?: Record<string, unknown>,\n      modules?: unknown\n    ) => {\n      evaluate: (source: string) => unknown\n    }\n  }\n  if (typeof realm.lockdown !== 'function' || typeof realm.Compartment !== 'function')\n    throw new E_SES_LOCKDOWN_REQUIRED(['SES lockdown() and Compartment are required'])\n  if (!hostLockdown)\n    throw new E_SES_HOST_LOCKDOWN_REQUIRED([\n      'In-process SES evaluation requires host-realm lockdown; supply a worker or child guest for guest-only isolation',\n    ])\n  // SES is process-global in Node. The first guest bootstrap hardens this realm; subsequent\n  // in-process evaluations must verify the already-hardened realm rather than invoking lockdown()\n  // a second time (SES deliberately throws SES_ALREADY_LOCKED_DOWN).\n  if (!(realm as typeof realm & { __adkSesLocked?: boolean }).__adkSesLocked) {\n    try {\n      realm.lockdown()\n    } catch (error) {\n      if (\n        !(\n          isInstanceOf(error, 'TypeError', TypeError) &&\n          String(error).includes('SES_ALREADY_LOCKED_DOWN')\n        )\n      )\n        throw error\n    }\n    ;(realm as typeof realm & { __adkSesLocked?: boolean }).__adkSesLocked = true\n  }\n  const C = realm.Compartment\n  return {\n    async evaluate(source: string, o: { timeoutMs: number }): Promise<GuestOutcome> {\n      const started = performance.now()\n      let seq = 0\n      let capped = false\n      const logs: { seq: number; text: string; truncated: boolean }[] = []\n      const consoleLike = {\n        log: (...a: unknown[]) => {\n          if (logs.length >= limits.maxLogEvents) {\n            capped = true\n            return\n          }\n          const text = cut(a.map(String).join(' '), limits.maxLogEventBytes)\n          logs.push({ seq: ++seq, ...text })\n        },\n      }\n      const end = (): number => Math.max(0, performance.now() - started)\n      const timer = new Promise<never>((_, reject) =>\n        setTimeout(\n          () => reject(new E_SES_EVALUATION_TIMEOUT(['evaluation exceeded timeout'])),\n          o.timeoutMs\n        )\n      )\n      try {\n        const compartment = new C({ console: consoleLike, ...globals }, modules)\n        const result = await Promise.race([\n          Promise.resolve(compartment.evaluate(`(async()=>(${source}))()`)),\n          timer,\n        ])\n        const rendered = render(result)\n        return {\n          ok: true,\n          result: rendered.value,\n          encoding: rendered.encoding,\n          durationMs: end(),\n          logs,\n          logsCapped: capped,\n          logsComplete: true,\n        }\n      } catch (error) {\n        if (isInstanceOf(error, 'E_SES_EVALUATION_TIMEOUT', E_SES_EVALUATION_TIMEOUT)) throw error\n        const thrown = isError(error)\n          ? { kind: 'error' as const, message: error.message, stack: error.stack }\n          : { kind: 'opaque' as const }\n        return {\n          ok: false,\n          thrown,\n          durationMs: end(),\n          logs,\n          logsCapped: capped,\n          logsComplete: true,\n        }\n      }\n    },\n    async kill(): Promise<void> {\n      /* Compartment cannot be forcibly killed; production adapters must use a worker. */\n    },\n  }\n}\n","import { createCompartmentRuntime } from './compartment'\nimport type { GuestLimits } from '../types'\nimport type { GuestRuntimeLike } from './ses_contracts'\n\n/** In-process runtime factory for environments where SES is available. */\nexport const createGuestRuntime = async (\n  globals: Record<string, (...args: unknown[]) => unknown>,\n  limits: GuestLimits,\n  modules: Record<string, unknown> = {},\n  hostLockdown = true\n): Promise<GuestRuntimeLike> => ({\n  async spawn() {\n    return createCompartmentRuntime(globals, limits, modules, hostLockdown)\n  },\n})\n","import { createGuestRuntime } from './service'\nimport { resolveGuestLimits } from './validation'\nimport type { GuestOutcome } from '../types'\nimport type { GuestGlobal, GuestRuntimeLike } from './ses_contracts'\n\n/** Host runner that retains capability implementations and exposes only enumerated names. */\nexport const createGuestRunner = async (\n  globals: Record<string, GuestGlobal>,\n  limits = resolveGuestLimits(),\n  modules: Record<string, unknown> = {},\n  hostLockdown = true\n): Promise<GuestRuntimeLike> => {\n  return {\n    async spawn(options): Promise<Awaited<ReturnType<GuestRuntimeLike['spawn']>>> {\n      const implementations: Record<string, (...args: unknown[]) => unknown> = {}\n      for (const [name, declaration] of Object.entries(globals))\n        implementations[name] = (...args: unknown[]) =>\n          declaration.fn(args, options.signal ?? new AbortController().signal)\n      const runtime = await createGuestRuntime(implementations, limits, modules, hostLockdown)\n      return runtime.spawn(options)\n    },\n  }\n}\n/** Type-only terminal outcome helper. */\nexport const isGuestOutcome = (value: unknown): value is GuestOutcome =>\n  Boolean(value && typeof value === 'object' && 'durationMs' in value)\n","import { Tool } from '@nhtio/adk/forge'\nimport { createGuestRunner } from './runner'\nimport { validator } from '@nhtio/validation'\nimport { isInstanceOf } from '@nhtio/adk/guards'\nimport { runToolGate } from '../../tools/_shared'\nimport { E_SES_EVALUATION_TIMEOUT } from './exceptions'\nimport { resolveGuestLimits, resolveHostcallQuotas } from './validation'\nimport { E_SANDBOX_FAILED, E_SANDBOX_GATE_REQUIRED } from '../exceptions'\nimport type { EvaluateJavascriptConfig } from './ses_contracts'\n\n/** Assemble the SES JavaScript evaluation tool. */\nexport const createEvaluateJavascriptTool = (config: EvaluateJavascriptConfig): Tool => {\n  if (!config.gate) throw new E_SANDBOX_GATE_REQUIRED(['evaluate_javascript requires a gate'])\n  const limits = resolveGuestLimits(config.limits)\n  resolveHostcallQuotas(config.hostcallQuotas)\n  const inputSchema = validator.object({\n    source: validator.string().required(),\n    timeout_seconds: validator.number().min(1).default(30),\n  })\n  return new Tool({\n    name: 'evaluate_javascript',\n    description:\n      'Evaluate JavaScript in a hardened SES guest. No ambient fetch, process, require, Date.now, or Math.random. Injected capabilities are asynchronous.',\n    inputSchema,\n    trusted: false,\n    handler: async (raw, ctx) => {\n      const args = raw as { source: string; timeout_seconds: number }\n      await runToolGate(config.gate, ctx, 'evaluate_javascript', args)\n      const runtime =\n        config.runtime ??\n        (await createGuestRunner(\n          config.globals ?? {},\n          limits,\n          config.modules ?? {},\n          config.hostLockdown ?? true\n        ))\n      const guest = await runtime.spawn({\n        modules: Object.keys(config.modules ?? {}),\n        globals: Object.keys(config.globals ?? {}).map((name) => ({\n          name,\n          kind: 'async-fn' as const,\n        })),\n        limits,\n        signal: ctx.abortSignal,\n      })\n      try {\n        return JSON.stringify(\n          await guest.evaluate(args.source, { timeoutMs: args.timeout_seconds * 1000 })\n        )\n      } catch (error) {\n        if (isInstanceOf(error, 'E_SES_EVALUATION_TIMEOUT', E_SES_EVALUATION_TIMEOUT)) {\n          await guest.kill()\n          throw new E_SANDBOX_FAILED([\n            `Evaluation timed out after ${args.timeout_seconds} seconds (kind: timed-out).`,\n          ])\n        }\n        throw error\n      }\n    },\n  })\n}\n"],"mappings":"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"}