@mcploom/codexec-isolated-vm 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -33,6 +33,13 @@ npm install @mcploom/codexec @mcploom/codexec-isolated-vm
33
33
  - the optional `isolated-vm` native dependency must install successfully in the host environment
34
34
  - native-addon failures are surfaced when `IsolatedVmExecutor` is constructed or used
35
35
 
36
+ ## Security Notes
37
+
38
+ - Each execution gets a fresh `isolated-vm` context with JSON-only tool and result boundaries.
39
+ - In the default deployment model, provider definitions are controlled by the host application, while hostile users control guest code and tool inputs.
40
+ - This package is still in-process execution. It should not be marketed or relied on as a hard security boundary for hostile code.
41
+ - Providers remain the real capability boundary. If a tool is dangerous, guest code can invoke it.
42
+
36
43
  ## Usage
37
44
 
38
45
  ```ts
package/dist/index.cjs CHANGED
@@ -1,3 +1,4 @@
1
+ let node_crypto = require("node:crypto");
1
2
  let __mcploom_codexec = require("@mcploom/codexec");
2
3
 
3
4
  //#region src/isolatedVmExecutor.ts
@@ -5,7 +6,6 @@ const DEFAULT_MEMORY_LIMIT_BYTES = 64 * 1024 * 1024;
5
6
  const DEFAULT_TIMEOUT_MS = 5e3;
6
7
  const DEFAULT_MAX_LOG_LINES = 100;
7
8
  const DEFAULT_MAX_LOG_CHARS = 64e3;
8
- const HOST_ERROR_PREFIX = "__MCP_CODE_EXEC_HOST_ERROR__";
9
9
  let cachedModulePromise;
10
10
  function createExecutionContext(signal, providerName, safeToolName, originalToolName) {
11
11
  return {
@@ -139,31 +139,51 @@ async function loadDefaultModule() {
139
139
  });
140
140
  return cachedModulePromise;
141
141
  }
142
- function createBootstrapSource(providers, timeoutMs) {
142
+ function createBootstrapSource(providers, hostErrorPrefix, timeoutMs) {
143
143
  const lines = [
144
- `const __MCP_HOST_ERROR_PREFIX = ${JSON.stringify(HOST_ERROR_PREFIX)};`,
145
- "const __mcpNormalizeError = (error) => {",
146
- " if (error && typeof error === 'object' && typeof error.code === 'string' && typeof error.message === 'string') {",
147
- " return { code: error.code, message: error.message };",
144
+ `const __MCP_HOST_ERROR_PREFIX = ${JSON.stringify(hostErrorPrefix)};`,
145
+ `const __MCP_HOST_ERROR_KEY = ${JSON.stringify(`${hostErrorPrefix}key`)};`,
146
+ "const __mcpCreateTrustedError = (code, message) => ({",
147
+ " [__MCP_HOST_ERROR_KEY]: true,",
148
+ " code,",
149
+ " message,",
150
+ "});",
151
+ "const __mcpNormalizeTrustedError = (error) => {",
152
+ " if (error && typeof error === 'object' && error[__MCP_HOST_ERROR_KEY] === true && typeof error.code === 'string' && typeof error.message === 'string') {",
153
+ " return __mcpCreateTrustedError(error.code, error.message);",
148
154
  " }",
149
155
  " if (error && typeof error.message === 'string' && error.message.startsWith(__MCP_HOST_ERROR_PREFIX)) {",
150
156
  " try {",
151
157
  " const payload = JSON.parse(error.message.slice(__MCP_HOST_ERROR_PREFIX.length));",
152
158
  " if (payload && typeof payload.code === 'string' && typeof payload.message === 'string') {",
153
- " return payload;",
159
+ " return __mcpCreateTrustedError(payload.code, payload.message);",
154
160
  " }",
155
161
  " } catch {}",
156
162
  " }",
163
+ " return null;",
164
+ "};",
165
+ "const __mcpNormalizeGuestError = (error) => {",
166
+ " const trusted = __mcpNormalizeTrustedError(error);",
167
+ " if (trusted) {",
168
+ " return trusted;",
169
+ " }",
157
170
  " if (error && typeof error.message === 'string') {",
158
171
  " return { code: 'runtime_error', message: error.message };",
159
172
  " }",
160
173
  " return { code: 'runtime_error', message: String(error) };",
161
174
  "};",
175
+ "const __mcpNormalizeHostError = (error) => {",
176
+ " const trusted = __mcpNormalizeTrustedError(error);",
177
+ " if (trusted) {",
178
+ " return trusted;",
179
+ " }",
180
+ " if (error && typeof error === 'object' && typeof error.code === 'string' && typeof error.message === 'string') {",
181
+ " return __mcpCreateTrustedError(error.code, error.message);",
182
+ " }",
183
+ " return __mcpNormalizeGuestError(error);",
184
+ "};",
162
185
  "const __mcpRaiseNormalizedError = (error) => {",
163
- " const normalized = __mcpNormalizeError(error);",
164
- " const wrapped = new Error(normalized.message);",
165
- " wrapped.code = normalized.code;",
166
- " throw wrapped;",
186
+ " throw __mcpNormalizeHostError(error);",
167
187
  "};",
168
188
  "const __mcpToJsonValue = (value) => {",
169
189
  " if (typeof value === 'undefined') {",
@@ -171,9 +191,10 @@ function createBootstrapSource(providers, timeoutMs) {
171
191
  " }",
172
192
  " const json = JSON.stringify(value);",
173
193
  " if (typeof json === 'undefined') {",
174
- " const error = new Error('Guest code returned a non-serializable value');",
175
- " error.code = 'serialization_error';",
176
- " throw error;",
194
+ " throw __mcpCreateTrustedError(",
195
+ " 'serialization_error',",
196
+ " 'Guest code returned a non-serializable value'",
197
+ " );",
177
198
  " }",
178
199
  " return JSON.parse(json);",
179
200
  "};",
@@ -201,7 +222,7 @@ function createExecutionSource(code) {
201
222
  " const value = await __mcpUserFunction();",
202
223
  " return { ok: true, value: __mcpToJsonValue(value) };",
203
224
  " } catch (error) {",
204
- " return { ok: false, error: __mcpNormalizeError(error) };",
225
+ " return { ok: false, error: __mcpNormalizeGuestError(error) };",
205
226
  " }",
206
227
  "})();"
207
228
  ].join("\n");
@@ -221,7 +242,7 @@ function setConsoleBindings(context, logs) {
221
242
  logs.push(formatConsoleLine(args));
222
243
  });
223
244
  }
224
- function setProviderBindings(ivm, context, providers, signal, deadline) {
245
+ function setProviderBindings(ivm, context, providers, signal, deadline, hostErrorPrefix) {
225
246
  const jail = context.global;
226
247
  for (const provider of providers) for (const [safeToolName, descriptor] of Object.entries(provider.tools)) {
227
248
  const hostReferenceName = `__mcp_tool_${provider.name}_${safeToolName}`;
@@ -229,10 +250,12 @@ function setProviderBindings(ivm, context, providers, signal, deadline) {
229
250
  const executionContext = createExecutionContext(signal, provider.name, safeToolName, descriptor.originalName);
230
251
  try {
231
252
  const normalizedInput = input === void 0 ? void 0 : toJsonValue(input, "Guest code passed a non-serializable tool input");
232
- return toTransferableValue(ivm, await runWithDeadline(Promise.resolve(descriptor.execute(normalizedInput, executionContext)), deadline, signal));
253
+ const pendingExecution = Promise.resolve(descriptor.execute(normalizedInput, executionContext));
254
+ pendingExecution.catch(() => {});
255
+ return toTransferableValue(ivm, await runWithDeadline(pendingExecution, deadline, signal));
233
256
  } catch (error) {
234
257
  const executeError = toExecuteError(error, deadline);
235
- throw new Error(`${HOST_ERROR_PREFIX}${JSON.stringify(executeError)}`, { cause: error });
258
+ throw new Error(`${hostErrorPrefix}${JSON.stringify(executeError)}`, { cause: error });
236
259
  }
237
260
  }, { reference: true });
238
261
  }
@@ -246,6 +269,9 @@ var IsolatedVmExecutor = class {
246
269
  maxLogLines;
247
270
  memoryLimitBytes;
248
271
  timeoutMs;
272
+ /**
273
+ * Creates an isolated-vm executor with one-shot runtime limits and host bridging configuration.
274
+ */
249
275
  constructor(options = {}) {
250
276
  this.loadModule = async () => {
251
277
  return options.loadModule ? await options.loadModule() : await loadDefaultModule();
@@ -263,6 +289,7 @@ var IsolatedVmExecutor = class {
263
289
  const deadline = startedAt + this.timeoutMs;
264
290
  const logs = [];
265
291
  const abortController = new AbortController();
292
+ const hostErrorPrefix = `__MCP_CODE_EXEC_HOST_ERROR__${(0, node_crypto.randomUUID)()}:`;
266
293
  if (Number.parseInt(process.versions.node.split(".")[0] ?? "0", 10) >= 20 && !hasRequiredNodeFlag()) return {
267
294
  durationMs: Date.now() - startedAt,
268
295
  error: {
@@ -286,8 +313,8 @@ var IsolatedVmExecutor = class {
286
313
  });
287
314
  context = await isolate.createContext();
288
315
  setConsoleBindings(context, logs);
289
- setProviderBindings(ivm, context, providers, abortController.signal, deadline);
290
- await context.eval(createBootstrapSource(providers, this.timeoutMs), { timeout: this.timeoutMs });
316
+ setProviderBindings(ivm, context, providers, abortController.signal, deadline, hostErrorPrefix);
317
+ await context.eval(createBootstrapSource(providers, hostErrorPrefix, this.timeoutMs), { timeout: this.timeoutMs });
291
318
  const execution = await context.evalClosure(createExecutionSource(code), [], {
292
319
  timeout: this.timeoutMs,
293
320
  result: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["cachedModulePromise: Promise<IsolatedVmModule> | undefined","truncated: string[]","ExecuteFailure","timeoutId: ReturnType<typeof setTimeout> | undefined","logs: string[]","catastrophicErrorMessage: string | undefined","isolate: IsolatedVmIsolate | undefined","context: IsolatedVmContext | undefined"],"sources":["../src/isolatedVmExecutor.ts"],"sourcesContent":["import {\n ExecuteFailure,\n isExecuteFailure,\n normalizeCode,\n} from \"@mcploom/codexec\";\nimport type {\n ExecuteError,\n ExecuteResult,\n Executor,\n ResolvedToolProvider,\n ToolExecutionContext,\n} from \"@mcploom/codexec\";\n\nimport type { IsolatedVmExecutorOptions } from \"./types\";\n\ntype IsolatedVmExternalCopyInstance = {\n copyInto: (options?: { release?: boolean; transferIn?: boolean }) => unknown;\n release?: () => void;\n};\n\ntype IsolatedVmReferenceInstance = {\n setSync: (\n property: string,\n value: unknown,\n options?: Record<string, unknown>,\n ) => void;\n};\n\ntype IsolatedVmContext = {\n eval: (code: string, options?: Record<string, unknown>) => Promise<unknown>;\n evalClosure: (\n code: string,\n args?: unknown[],\n options?: Record<string, unknown>,\n ) => Promise<unknown>;\n global: IsolatedVmReferenceInstance;\n release?: () => void;\n};\n\ntype IsolatedVmIsolate = {\n createContext: () => Promise<IsolatedVmContext>;\n dispose: () => void;\n};\n\ntype IsolatedVmModule = {\n ExternalCopy: new (\n value: unknown,\n options?: Record<string, unknown>,\n ) => IsolatedVmExternalCopyInstance;\n Isolate: new (options?: {\n inspector?: boolean;\n memoryLimit?: number;\n onCatastrophicError?: (message: string) => void;\n }) => IsolatedVmIsolate;\n};\n\ntype GuestExecutionEnvelope =\n | {\n ok: true;\n value: unknown;\n }\n | {\n error: {\n code?: string;\n message?: string;\n };\n ok: false;\n };\n\nconst DEFAULT_MEMORY_LIMIT_BYTES = 64 * 1024 * 1024;\nconst DEFAULT_TIMEOUT_MS = 5000;\nconst DEFAULT_MAX_LOG_LINES = 100;\nconst DEFAULT_MAX_LOG_CHARS = 64_000;\nconst HOST_ERROR_PREFIX = \"__MCP_CODE_EXEC_HOST_ERROR__\";\n\nlet cachedModulePromise: Promise<IsolatedVmModule> | undefined;\n\nfunction createExecutionContext(\n signal: AbortSignal,\n providerName: string,\n safeToolName: string,\n originalToolName: string,\n): ToolExecutionContext {\n return {\n originalToolName,\n providerName,\n safeToolName,\n signal,\n };\n}\n\nfunction hasRequiredNodeFlag(): boolean {\n const execArgv = process.execArgv.join(\" \");\n const nodeOptions = process.env.NODE_OPTIONS ?? \"\";\n return (\n execArgv.includes(\"--no-node-snapshot\") ||\n nodeOptions.includes(\"--no-node-snapshot\")\n );\n}\n\nfunction isKnownErrorCode(value: unknown): value is ExecuteError[\"code\"] {\n return (\n value === \"timeout\" ||\n value === \"memory_limit\" ||\n value === \"validation_error\" ||\n value === \"tool_error\" ||\n value === \"runtime_error\" ||\n value === \"serialization_error\" ||\n value === \"internal_error\"\n );\n}\n\nfunction normalizeThrownMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n\n if (typeof error === \"object\" && error !== null && \"message\" in error) {\n const message = (error as { message?: unknown }).message;\n if (typeof message === \"string\") {\n return message;\n }\n }\n\n return String(error);\n}\n\nfunction truncateLogs(\n logs: string[],\n maxLogLines: number,\n maxLogChars: number,\n): string[] {\n const limitedLines = logs.slice(0, maxLogLines);\n let remainingChars = maxLogChars;\n const truncated: string[] = [];\n\n for (const line of limitedLines) {\n if (remainingChars <= 0) {\n break;\n }\n\n if (line.length <= remainingChars) {\n truncated.push(line);\n remainingChars -= line.length;\n continue;\n }\n\n truncated.push(line.slice(0, remainingChars));\n break;\n }\n\n return truncated;\n}\n\nfunction formatLogValue(value: unknown): string {\n if (typeof value === \"string\") {\n return value;\n }\n\n if (value === undefined) {\n return \"undefined\";\n }\n\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nfunction formatConsoleLine(values: unknown[]): string {\n return values.map((value) => formatLogValue(value)).join(\" \");\n}\n\nfunction toJsonValue(value: unknown, message: string): unknown {\n if (value === undefined) {\n return undefined;\n }\n\n const jsonValue = JSON.stringify(value);\n\n if (jsonValue === undefined) {\n throw new ExecuteFailure(\"serialization_error\", message);\n }\n\n try {\n return JSON.parse(jsonValue) as unknown;\n } catch {\n throw new ExecuteFailure(\"serialization_error\", message);\n }\n}\n\nfunction toTransferableValue(ivm: IsolatedVmModule, value: unknown): unknown {\n const normalizedValue = toJsonValue(\n value,\n \"Host value is not JSON-serializable\",\n );\n\n if (\n normalizedValue === null ||\n normalizedValue === undefined ||\n typeof normalizedValue === \"string\" ||\n typeof normalizedValue === \"number\" ||\n typeof normalizedValue === \"boolean\"\n ) {\n return normalizedValue;\n }\n\n const copy = new ivm.ExternalCopy(normalizedValue);\n return copy.copyInto({ release: true });\n}\n\nfunction toExecuteError(error: unknown, deadline: number): ExecuteError {\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n \"message\" in error &&\n isKnownErrorCode((error as { code?: unknown }).code) &&\n typeof (error as { message?: unknown }).message === \"string\"\n ) {\n return {\n code: (error as { code: ExecuteError[\"code\"] }).code,\n message: (error as { message: string }).message,\n };\n }\n\n if (isExecuteFailure(error)) {\n return {\n code: error.code,\n message: error.message,\n };\n }\n\n const message = normalizeThrownMessage(error);\n const normalizedMessage = message.toLowerCase();\n\n if (\n Date.now() > deadline ||\n normalizedMessage.includes(\"timed out\") ||\n normalizedMessage.includes(\"time limit\")\n ) {\n return {\n code: \"timeout\",\n message: \"Execution timed out\",\n };\n }\n\n if (\n normalizedMessage.includes(\"memory limit\") ||\n normalizedMessage.includes(\"out of memory\")\n ) {\n return {\n code: \"memory_limit\",\n message,\n };\n }\n\n if (\n normalizedMessage.includes(\"could not be cloned\") ||\n normalizedMessage.includes(\"non-transferable\") ||\n normalizedMessage.includes(\"not json-serializable\")\n ) {\n return {\n code: \"serialization_error\",\n message,\n };\n }\n\n return {\n code: \"runtime_error\",\n message,\n };\n}\n\nfunction toMemoryLimitMb(memoryLimitBytes: number): number {\n return Math.max(8, Math.ceil(memoryLimitBytes / (1024 * 1024)));\n}\n\nfunction remainingTime(deadline: number): number {\n return Math.max(0, deadline - Date.now());\n}\n\nasync function runWithDeadline<T>(\n operation: Promise<T>,\n deadline: number,\n signal: AbortSignal,\n): Promise<T> {\n if (signal.aborted || Date.now() > deadline) {\n throw new ExecuteFailure(\"timeout\", \"Execution timed out\");\n }\n\n const timeoutMs = remainingTime(deadline);\n if (timeoutMs <= 0) {\n throw new ExecuteFailure(\"timeout\", \"Execution timed out\");\n }\n\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n return await new Promise<T>((resolve, reject) => {\n const onAbort = () => {\n reject(new ExecuteFailure(\"timeout\", \"Execution timed out\"));\n };\n\n signal.addEventListener(\"abort\", onAbort, { once: true });\n timeoutId = setTimeout(() => {\n signal.removeEventListener(\"abort\", onAbort);\n reject(new ExecuteFailure(\"timeout\", \"Execution timed out\"));\n }, timeoutMs);\n\n void operation.then(\n (value) => {\n signal.removeEventListener(\"abort\", onAbort);\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n resolve(value);\n },\n (error) => {\n signal.removeEventListener(\"abort\", onAbort);\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n reject(error);\n },\n );\n });\n}\n\nasync function loadDefaultModule(): Promise<IsolatedVmModule> {\n cachedModulePromise ??= import(\"isolated-vm\").then((loaded) => {\n const candidate = (\n \"default\" in loaded ? loaded.default : loaded\n ) as unknown;\n return candidate as IsolatedVmModule;\n });\n\n return cachedModulePromise;\n}\n\nfunction createBootstrapSource(\n providers: ResolvedToolProvider[],\n timeoutMs: number,\n): string {\n const lines = [\n `const __MCP_HOST_ERROR_PREFIX = ${JSON.stringify(HOST_ERROR_PREFIX)};`,\n \"const __mcpNormalizeError = (error) => {\",\n \" if (error && typeof error === 'object' && typeof error.code === 'string' && typeof error.message === 'string') {\",\n \" return { code: error.code, message: error.message };\",\n \" }\",\n \" if (error && typeof error.message === 'string' && error.message.startsWith(__MCP_HOST_ERROR_PREFIX)) {\",\n \" try {\",\n \" const payload = JSON.parse(error.message.slice(__MCP_HOST_ERROR_PREFIX.length));\",\n \" if (payload && typeof payload.code === 'string' && typeof payload.message === 'string') {\",\n \" return payload;\",\n \" }\",\n \" } catch {}\",\n \" }\",\n \" if (error && typeof error.message === 'string') {\",\n \" return { code: 'runtime_error', message: error.message };\",\n \" }\",\n \" return { code: 'runtime_error', message: String(error) };\",\n \"};\",\n \"const __mcpRaiseNormalizedError = (error) => {\",\n \" const normalized = __mcpNormalizeError(error);\",\n \" const wrapped = new Error(normalized.message);\",\n \" wrapped.code = normalized.code;\",\n \" throw wrapped;\",\n \"};\",\n \"const __mcpToJsonValue = (value) => {\",\n \" if (typeof value === 'undefined') {\",\n \" return undefined;\",\n \" }\",\n \" const json = JSON.stringify(value);\",\n \" if (typeof json === 'undefined') {\",\n \" const error = new Error('Guest code returned a non-serializable value');\",\n \" error.code = 'serialization_error';\",\n \" throw error;\",\n \" }\",\n \" return JSON.parse(json);\",\n \"};\",\n \"globalThis.console = {\",\n \" log: (...args) => __mcp_console_log(...args),\",\n \" info: (...args) => __mcp_console_info(...args),\",\n \" warn: (...args) => __mcp_console_warn(...args),\",\n \" error: (...args) => __mcp_console_error(...args),\",\n \"};\",\n ];\n\n for (const provider of providers) {\n lines.push(`globalThis.${provider.name} = {};`);\n\n for (const safeToolName of Object.keys(provider.tools)) {\n const hostReferenceName = `__mcp_tool_${provider.name}_${safeToolName}`;\n lines.push(\n `globalThis.${provider.name}.${safeToolName} = async (input) => {`,\n \" try {\",\n ` return await ${hostReferenceName}.applySyncPromise(undefined, [input], { arguments: { copy: true }, timeout: ${timeoutMs} });`,\n \" } catch (error) {\",\n \" __mcpRaiseNormalizedError(error);\",\n \" }\",\n \"};\",\n );\n }\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction createExecutionSource(code: string): string {\n const executableSource = normalizeCode(code);\n\n return [\n `const __mcpUserFunction = (${executableSource});`,\n \"return (async () => {\",\n \" try {\",\n \" const value = await __mcpUserFunction();\",\n \" return { ok: true, value: __mcpToJsonValue(value) };\",\n \" } catch (error) {\",\n \" return { ok: false, error: __mcpNormalizeError(error) };\",\n \" }\",\n \"})();\",\n ].join(\"\\n\");\n}\n\nfunction setConsoleBindings(context: IsolatedVmContext, logs: string[]): void {\n const jail = context.global;\n jail.setSync(\"__mcp_console_log\", (...args: unknown[]) => {\n logs.push(formatConsoleLine(args));\n });\n jail.setSync(\"__mcp_console_info\", (...args: unknown[]) => {\n logs.push(formatConsoleLine(args));\n });\n jail.setSync(\"__mcp_console_warn\", (...args: unknown[]) => {\n logs.push(formatConsoleLine(args));\n });\n jail.setSync(\"__mcp_console_error\", (...args: unknown[]) => {\n logs.push(formatConsoleLine(args));\n });\n}\n\nfunction setProviderBindings(\n ivm: IsolatedVmModule,\n context: IsolatedVmContext,\n providers: ResolvedToolProvider[],\n signal: AbortSignal,\n deadline: number,\n): void {\n const jail = context.global;\n\n for (const provider of providers) {\n for (const [safeToolName, descriptor] of Object.entries(provider.tools)) {\n const hostReferenceName = `__mcp_tool_${provider.name}_${safeToolName}`;\n\n jail.setSync(\n hostReferenceName,\n async (input: unknown) => {\n const executionContext = createExecutionContext(\n signal,\n provider.name,\n safeToolName,\n descriptor.originalName,\n );\n\n try {\n const normalizedInput =\n input === undefined\n ? undefined\n : toJsonValue(\n input,\n \"Guest code passed a non-serializable tool input\",\n );\n const result = await runWithDeadline(\n Promise.resolve(\n descriptor.execute(normalizedInput, executionContext),\n ),\n deadline,\n signal,\n );\n\n return toTransferableValue(ivm, result);\n } catch (error) {\n const executeError = toExecuteError(error, deadline);\n throw new Error(\n `${HOST_ERROR_PREFIX}${JSON.stringify(executeError)}`,\n {\n cause: error,\n },\n );\n }\n },\n { reference: true },\n );\n }\n }\n}\n\n/**\n * isolated-vm-backed executor for one-shot sandboxed JavaScript runs.\n */\nexport class IsolatedVmExecutor implements Executor {\n private readonly loadModule: () => Promise<IsolatedVmModule>;\n private readonly maxLogChars: number;\n private readonly maxLogLines: number;\n private readonly memoryLimitBytes: number;\n private readonly timeoutMs: number;\n\n constructor(options: IsolatedVmExecutorOptions = {}) {\n this.loadModule = async () => {\n const loaded = options.loadModule\n ? await options.loadModule()\n : await loadDefaultModule();\n return loaded as IsolatedVmModule;\n };\n this.maxLogChars = options.maxLogChars ?? DEFAULT_MAX_LOG_CHARS;\n this.maxLogLines = options.maxLogLines ?? DEFAULT_MAX_LOG_LINES;\n this.memoryLimitBytes =\n options.memoryLimitBytes ?? DEFAULT_MEMORY_LIMIT_BYTES;\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n }\n\n /**\n * Executes JavaScript against the provided tool namespaces in a fresh isolated-vm context.\n */\n async execute(\n code: string,\n providers: ResolvedToolProvider[],\n ): Promise<ExecuteResult> {\n const startedAt = Date.now();\n const deadline = startedAt + this.timeoutMs;\n const logs: string[] = [];\n const abortController = new AbortController();\n const nodeMajorVersion = Number.parseInt(\n process.versions.node.split(\".\")[0] ?? \"0\",\n 10,\n );\n\n if (nodeMajorVersion >= 20 && !hasRequiredNodeFlag()) {\n return {\n durationMs: Date.now() - startedAt,\n error: {\n code: \"internal_error\",\n message:\n \"isolated-vm requires Node to run with --no-node-snapshot on Node 20+\",\n },\n logs,\n ok: false,\n };\n }\n\n let catastrophicErrorMessage: string | undefined;\n let isolate: IsolatedVmIsolate | undefined;\n let context: IsolatedVmContext | undefined;\n\n try {\n const ivm = await this.loadModule();\n isolate = new ivm.Isolate({\n memoryLimit: toMemoryLimitMb(this.memoryLimitBytes),\n onCatastrophicError: (message) => {\n catastrophicErrorMessage = message;\n abortController.abort();\n },\n });\n context = await isolate.createContext();\n\n setConsoleBindings(context, logs);\n setProviderBindings(\n ivm,\n context,\n providers,\n abortController.signal,\n deadline,\n );\n await context.eval(createBootstrapSource(providers, this.timeoutMs), {\n timeout: this.timeoutMs,\n });\n\n const execution = (await context.evalClosure(\n createExecutionSource(code),\n [],\n {\n timeout: this.timeoutMs,\n result: { copy: true, promise: true },\n },\n )) as GuestExecutionEnvelope;\n\n if (catastrophicErrorMessage) {\n return {\n durationMs: Date.now() - startedAt,\n error: {\n code: \"internal_error\",\n message: `isolated-vm catastrophic error: ${catastrophicErrorMessage}`,\n },\n logs: truncateLogs(logs, this.maxLogLines, this.maxLogChars),\n ok: false,\n };\n }\n\n if (!execution.ok) {\n return {\n durationMs: Date.now() - startedAt,\n error: toExecuteError(execution.error, deadline),\n logs: truncateLogs(logs, this.maxLogLines, this.maxLogChars),\n ok: false,\n };\n }\n\n return {\n durationMs: Date.now() - startedAt,\n logs: truncateLogs(logs, this.maxLogLines, this.maxLogChars),\n ok: true,\n result: execution.value,\n };\n } catch (error) {\n const executeError =\n catastrophicErrorMessage !== undefined\n ? {\n code: \"internal_error\" as const,\n message: `isolated-vm catastrophic error: ${catastrophicErrorMessage}`,\n }\n : toExecuteError(error, deadline);\n\n return {\n durationMs: Date.now() - startedAt,\n error: executeError,\n logs: truncateLogs(logs, this.maxLogLines, this.maxLogChars),\n ok: false,\n };\n } finally {\n abortController.abort();\n context?.release?.();\n isolate?.dispose();\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["cachedModulePromise: Promise<IsolatedVmModule> | undefined","truncated: string[]","ExecuteFailure","timeoutId: ReturnType<typeof setTimeout> | undefined","logs: string[]","catastrophicErrorMessage: string | undefined","isolate: IsolatedVmIsolate | undefined","context: IsolatedVmContext | undefined"],"sources":["../src/isolatedVmExecutor.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\n\nimport {\n ExecuteFailure,\n isExecuteFailure,\n normalizeCode,\n} from \"@mcploom/codexec\";\nimport type {\n ExecuteError,\n ExecuteResult,\n Executor,\n ResolvedToolProvider,\n ToolExecutionContext,\n} from \"@mcploom/codexec\";\n\nimport type { IsolatedVmExecutorOptions } from \"./types\";\n\ntype IsolatedVmExternalCopyInstance = {\n copyInto: (options?: { release?: boolean; transferIn?: boolean }) => unknown;\n release?: () => void;\n};\n\ntype IsolatedVmReferenceInstance = {\n setSync: (\n property: string,\n value: unknown,\n options?: Record<string, unknown>,\n ) => void;\n};\n\ntype IsolatedVmContext = {\n eval: (code: string, options?: Record<string, unknown>) => Promise<unknown>;\n evalClosure: (\n code: string,\n args?: unknown[],\n options?: Record<string, unknown>,\n ) => Promise<unknown>;\n global: IsolatedVmReferenceInstance;\n release?: () => void;\n};\n\ntype IsolatedVmIsolate = {\n createContext: () => Promise<IsolatedVmContext>;\n dispose: () => void;\n};\n\ntype IsolatedVmModule = {\n ExternalCopy: new (\n value: unknown,\n options?: Record<string, unknown>,\n ) => IsolatedVmExternalCopyInstance;\n Isolate: new (options?: {\n inspector?: boolean;\n memoryLimit?: number;\n onCatastrophicError?: (message: string) => void;\n }) => IsolatedVmIsolate;\n};\n\ntype GuestExecutionEnvelope =\n | {\n ok: true;\n value: unknown;\n }\n | {\n error: {\n code?: string;\n message?: string;\n };\n ok: false;\n };\n\nconst DEFAULT_MEMORY_LIMIT_BYTES = 64 * 1024 * 1024;\nconst DEFAULT_TIMEOUT_MS = 5000;\nconst DEFAULT_MAX_LOG_LINES = 100;\nconst DEFAULT_MAX_LOG_CHARS = 64_000;\nlet cachedModulePromise: Promise<IsolatedVmModule> | undefined;\n\nfunction createExecutionContext(\n signal: AbortSignal,\n providerName: string,\n safeToolName: string,\n originalToolName: string,\n): ToolExecutionContext {\n return {\n originalToolName,\n providerName,\n safeToolName,\n signal,\n };\n}\n\nfunction hasRequiredNodeFlag(): boolean {\n const execArgv = process.execArgv.join(\" \");\n const nodeOptions = process.env.NODE_OPTIONS ?? \"\";\n return (\n execArgv.includes(\"--no-node-snapshot\") ||\n nodeOptions.includes(\"--no-node-snapshot\")\n );\n}\n\nfunction isKnownErrorCode(value: unknown): value is ExecuteError[\"code\"] {\n return (\n value === \"timeout\" ||\n value === \"memory_limit\" ||\n value === \"validation_error\" ||\n value === \"tool_error\" ||\n value === \"runtime_error\" ||\n value === \"serialization_error\" ||\n value === \"internal_error\"\n );\n}\n\nfunction normalizeThrownMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n\n if (typeof error === \"object\" && error !== null && \"message\" in error) {\n const message = (error as { message?: unknown }).message;\n if (typeof message === \"string\") {\n return message;\n }\n }\n\n return String(error);\n}\n\nfunction truncateLogs(\n logs: string[],\n maxLogLines: number,\n maxLogChars: number,\n): string[] {\n const limitedLines = logs.slice(0, maxLogLines);\n let remainingChars = maxLogChars;\n const truncated: string[] = [];\n\n for (const line of limitedLines) {\n if (remainingChars <= 0) {\n break;\n }\n\n if (line.length <= remainingChars) {\n truncated.push(line);\n remainingChars -= line.length;\n continue;\n }\n\n truncated.push(line.slice(0, remainingChars));\n break;\n }\n\n return truncated;\n}\n\nfunction formatLogValue(value: unknown): string {\n if (typeof value === \"string\") {\n return value;\n }\n\n if (value === undefined) {\n return \"undefined\";\n }\n\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nfunction formatConsoleLine(values: unknown[]): string {\n return values.map((value) => formatLogValue(value)).join(\" \");\n}\n\nfunction toJsonValue(value: unknown, message: string): unknown {\n if (value === undefined) {\n return undefined;\n }\n\n const jsonValue = JSON.stringify(value);\n\n if (jsonValue === undefined) {\n throw new ExecuteFailure(\"serialization_error\", message);\n }\n\n try {\n return JSON.parse(jsonValue) as unknown;\n } catch {\n throw new ExecuteFailure(\"serialization_error\", message);\n }\n}\n\nfunction toTransferableValue(ivm: IsolatedVmModule, value: unknown): unknown {\n const normalizedValue = toJsonValue(\n value,\n \"Host value is not JSON-serializable\",\n );\n\n if (\n normalizedValue === null ||\n normalizedValue === undefined ||\n typeof normalizedValue === \"string\" ||\n typeof normalizedValue === \"number\" ||\n typeof normalizedValue === \"boolean\"\n ) {\n return normalizedValue;\n }\n\n const copy = new ivm.ExternalCopy(normalizedValue);\n return copy.copyInto({ release: true });\n}\n\nfunction toExecuteError(error: unknown, deadline: number): ExecuteError {\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n \"message\" in error &&\n isKnownErrorCode((error as { code?: unknown }).code) &&\n typeof (error as { message?: unknown }).message === \"string\"\n ) {\n return {\n code: (error as { code: ExecuteError[\"code\"] }).code,\n message: (error as { message: string }).message,\n };\n }\n\n if (isExecuteFailure(error)) {\n return {\n code: error.code,\n message: error.message,\n };\n }\n\n const message = normalizeThrownMessage(error);\n const normalizedMessage = message.toLowerCase();\n\n if (\n Date.now() > deadline ||\n normalizedMessage.includes(\"timed out\") ||\n normalizedMessage.includes(\"time limit\")\n ) {\n return {\n code: \"timeout\",\n message: \"Execution timed out\",\n };\n }\n\n if (\n normalizedMessage.includes(\"memory limit\") ||\n normalizedMessage.includes(\"out of memory\")\n ) {\n return {\n code: \"memory_limit\",\n message,\n };\n }\n\n if (\n normalizedMessage.includes(\"could not be cloned\") ||\n normalizedMessage.includes(\"non-transferable\") ||\n normalizedMessage.includes(\"not json-serializable\")\n ) {\n return {\n code: \"serialization_error\",\n message,\n };\n }\n\n return {\n code: \"runtime_error\",\n message,\n };\n}\n\nfunction toMemoryLimitMb(memoryLimitBytes: number): number {\n return Math.max(8, Math.ceil(memoryLimitBytes / (1024 * 1024)));\n}\n\nfunction remainingTime(deadline: number): number {\n return Math.max(0, deadline - Date.now());\n}\n\nasync function runWithDeadline<T>(\n operation: Promise<T>,\n deadline: number,\n signal: AbortSignal,\n): Promise<T> {\n if (signal.aborted || Date.now() > deadline) {\n throw new ExecuteFailure(\"timeout\", \"Execution timed out\");\n }\n\n const timeoutMs = remainingTime(deadline);\n if (timeoutMs <= 0) {\n throw new ExecuteFailure(\"timeout\", \"Execution timed out\");\n }\n\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n return await new Promise<T>((resolve, reject) => {\n const onAbort = () => {\n reject(new ExecuteFailure(\"timeout\", \"Execution timed out\"));\n };\n\n signal.addEventListener(\"abort\", onAbort, { once: true });\n timeoutId = setTimeout(() => {\n signal.removeEventListener(\"abort\", onAbort);\n reject(new ExecuteFailure(\"timeout\", \"Execution timed out\"));\n }, timeoutMs);\n\n void operation.then(\n (value) => {\n signal.removeEventListener(\"abort\", onAbort);\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n resolve(value);\n },\n (error) => {\n signal.removeEventListener(\"abort\", onAbort);\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n reject(error);\n },\n );\n });\n}\n\nasync function loadDefaultModule(): Promise<IsolatedVmModule> {\n cachedModulePromise ??= import(\"isolated-vm\").then((loaded) => {\n const candidate = (\n \"default\" in loaded ? loaded.default : loaded\n ) as unknown;\n return candidate as IsolatedVmModule;\n });\n\n return cachedModulePromise;\n}\n\nfunction createBootstrapSource(\n providers: ResolvedToolProvider[],\n hostErrorPrefix: string,\n timeoutMs: number,\n): string {\n const lines = [\n `const __MCP_HOST_ERROR_PREFIX = ${JSON.stringify(hostErrorPrefix)};`,\n `const __MCP_HOST_ERROR_KEY = ${JSON.stringify(`${hostErrorPrefix}key`)};`,\n \"const __mcpCreateTrustedError = (code, message) => ({\",\n \" [__MCP_HOST_ERROR_KEY]: true,\",\n \" code,\",\n \" message,\",\n \"});\",\n \"const __mcpNormalizeTrustedError = (error) => {\",\n \" if (error && typeof error === 'object' && error[__MCP_HOST_ERROR_KEY] === true && typeof error.code === 'string' && typeof error.message === 'string') {\",\n \" return __mcpCreateTrustedError(error.code, error.message);\",\n \" }\",\n \" if (error && typeof error.message === 'string' && error.message.startsWith(__MCP_HOST_ERROR_PREFIX)) {\",\n \" try {\",\n \" const payload = JSON.parse(error.message.slice(__MCP_HOST_ERROR_PREFIX.length));\",\n \" if (payload && typeof payload.code === 'string' && typeof payload.message === 'string') {\",\n \" return __mcpCreateTrustedError(payload.code, payload.message);\",\n \" }\",\n \" } catch {}\",\n \" }\",\n \" return null;\",\n \"};\",\n \"const __mcpNormalizeGuestError = (error) => {\",\n \" const trusted = __mcpNormalizeTrustedError(error);\",\n \" if (trusted) {\",\n \" return trusted;\",\n \" }\",\n \" if (error && typeof error.message === 'string') {\",\n \" return { code: 'runtime_error', message: error.message };\",\n \" }\",\n \" return { code: 'runtime_error', message: String(error) };\",\n \"};\",\n \"const __mcpNormalizeHostError = (error) => {\",\n \" const trusted = __mcpNormalizeTrustedError(error);\",\n \" if (trusted) {\",\n \" return trusted;\",\n \" }\",\n \" if (error && typeof error === 'object' && typeof error.code === 'string' && typeof error.message === 'string') {\",\n \" return __mcpCreateTrustedError(error.code, error.message);\",\n \" }\",\n \" return __mcpNormalizeGuestError(error);\",\n \"};\",\n \"const __mcpRaiseNormalizedError = (error) => {\",\n \" throw __mcpNormalizeHostError(error);\",\n \"};\",\n \"const __mcpToJsonValue = (value) => {\",\n \" if (typeof value === 'undefined') {\",\n \" return undefined;\",\n \" }\",\n \" const json = JSON.stringify(value);\",\n \" if (typeof json === 'undefined') {\",\n \" throw __mcpCreateTrustedError(\",\n \" 'serialization_error',\",\n \" 'Guest code returned a non-serializable value'\",\n \" );\",\n \" }\",\n \" return JSON.parse(json);\",\n \"};\",\n \"globalThis.console = {\",\n \" log: (...args) => __mcp_console_log(...args),\",\n \" info: (...args) => __mcp_console_info(...args),\",\n \" warn: (...args) => __mcp_console_warn(...args),\",\n \" error: (...args) => __mcp_console_error(...args),\",\n \"};\",\n ];\n\n for (const provider of providers) {\n lines.push(`globalThis.${provider.name} = {};`);\n\n for (const safeToolName of Object.keys(provider.tools)) {\n const hostReferenceName = `__mcp_tool_${provider.name}_${safeToolName}`;\n lines.push(\n `globalThis.${provider.name}.${safeToolName} = async (input) => {`,\n \" try {\",\n ` return await ${hostReferenceName}.applySyncPromise(undefined, [input], { arguments: { copy: true }, timeout: ${timeoutMs} });`,\n \" } catch (error) {\",\n \" __mcpRaiseNormalizedError(error);\",\n \" }\",\n \"};\",\n );\n }\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction createExecutionSource(code: string): string {\n const executableSource = normalizeCode(code);\n\n return [\n `const __mcpUserFunction = (${executableSource});`,\n \"return (async () => {\",\n \" try {\",\n \" const value = await __mcpUserFunction();\",\n \" return { ok: true, value: __mcpToJsonValue(value) };\",\n \" } catch (error) {\",\n \" return { ok: false, error: __mcpNormalizeGuestError(error) };\",\n \" }\",\n \"})();\",\n ].join(\"\\n\");\n}\n\nfunction setConsoleBindings(context: IsolatedVmContext, logs: string[]): void {\n const jail = context.global;\n jail.setSync(\"__mcp_console_log\", (...args: unknown[]) => {\n logs.push(formatConsoleLine(args));\n });\n jail.setSync(\"__mcp_console_info\", (...args: unknown[]) => {\n logs.push(formatConsoleLine(args));\n });\n jail.setSync(\"__mcp_console_warn\", (...args: unknown[]) => {\n logs.push(formatConsoleLine(args));\n });\n jail.setSync(\"__mcp_console_error\", (...args: unknown[]) => {\n logs.push(formatConsoleLine(args));\n });\n}\n\nfunction setProviderBindings(\n ivm: IsolatedVmModule,\n context: IsolatedVmContext,\n providers: ResolvedToolProvider[],\n signal: AbortSignal,\n deadline: number,\n hostErrorPrefix: string,\n): void {\n const jail = context.global;\n\n for (const provider of providers) {\n for (const [safeToolName, descriptor] of Object.entries(provider.tools)) {\n const hostReferenceName = `__mcp_tool_${provider.name}_${safeToolName}`;\n\n jail.setSync(\n hostReferenceName,\n async (input: unknown) => {\n const executionContext = createExecutionContext(\n signal,\n provider.name,\n safeToolName,\n descriptor.originalName,\n );\n\n try {\n const normalizedInput =\n input === undefined\n ? undefined\n : toJsonValue(\n input,\n \"Guest code passed a non-serializable tool input\",\n );\n const pendingExecution = Promise.resolve(\n descriptor.execute(normalizedInput, executionContext),\n );\n\n pendingExecution.catch(() => {\n // The deadline path may settle first; keep late provider rejections from\n // surfacing as unhandled promise rejections after timeout/abort.\n });\n const result = await runWithDeadline(\n pendingExecution,\n deadline,\n signal,\n );\n\n return toTransferableValue(ivm, result);\n } catch (error) {\n const executeError = toExecuteError(error, deadline);\n throw new Error(\n `${hostErrorPrefix}${JSON.stringify(executeError)}`,\n {\n cause: error,\n },\n );\n }\n },\n { reference: true },\n );\n }\n }\n}\n\n/**\n * isolated-vm-backed executor for one-shot sandboxed JavaScript runs.\n */\nexport class IsolatedVmExecutor implements Executor {\n private readonly loadModule: () => Promise<IsolatedVmModule>;\n private readonly maxLogChars: number;\n private readonly maxLogLines: number;\n private readonly memoryLimitBytes: number;\n private readonly timeoutMs: number;\n\n /**\n * Creates an isolated-vm executor with one-shot runtime limits and host bridging configuration.\n */\n constructor(options: IsolatedVmExecutorOptions = {}) {\n this.loadModule = async () => {\n const loaded = options.loadModule\n ? await options.loadModule()\n : await loadDefaultModule();\n return loaded as IsolatedVmModule;\n };\n this.maxLogChars = options.maxLogChars ?? DEFAULT_MAX_LOG_CHARS;\n this.maxLogLines = options.maxLogLines ?? DEFAULT_MAX_LOG_LINES;\n this.memoryLimitBytes =\n options.memoryLimitBytes ?? DEFAULT_MEMORY_LIMIT_BYTES;\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n }\n\n /**\n * Executes JavaScript against the provided tool namespaces in a fresh isolated-vm context.\n */\n async execute(\n code: string,\n providers: ResolvedToolProvider[],\n ): Promise<ExecuteResult> {\n const startedAt = Date.now();\n const deadline = startedAt + this.timeoutMs;\n const logs: string[] = [];\n const abortController = new AbortController();\n const hostErrorPrefix = `__MCP_CODE_EXEC_HOST_ERROR__${randomUUID()}:`;\n const nodeMajorVersion = Number.parseInt(\n process.versions.node.split(\".\")[0] ?? \"0\",\n 10,\n );\n\n if (nodeMajorVersion >= 20 && !hasRequiredNodeFlag()) {\n return {\n durationMs: Date.now() - startedAt,\n error: {\n code: \"internal_error\",\n message:\n \"isolated-vm requires Node to run with --no-node-snapshot on Node 20+\",\n },\n logs,\n ok: false,\n };\n }\n\n let catastrophicErrorMessage: string | undefined;\n let isolate: IsolatedVmIsolate | undefined;\n let context: IsolatedVmContext | undefined;\n\n try {\n const ivm = await this.loadModule();\n isolate = new ivm.Isolate({\n memoryLimit: toMemoryLimitMb(this.memoryLimitBytes),\n onCatastrophicError: (message) => {\n catastrophicErrorMessage = message;\n abortController.abort();\n },\n });\n context = await isolate.createContext();\n\n setConsoleBindings(context, logs);\n setProviderBindings(\n ivm,\n context,\n providers,\n abortController.signal,\n deadline,\n hostErrorPrefix,\n );\n await context.eval(\n createBootstrapSource(providers, hostErrorPrefix, this.timeoutMs),\n {\n timeout: this.timeoutMs,\n },\n );\n\n const execution = (await context.evalClosure(\n createExecutionSource(code),\n [],\n {\n timeout: this.timeoutMs,\n result: { copy: true, promise: true },\n },\n )) as GuestExecutionEnvelope;\n\n if (catastrophicErrorMessage) {\n return {\n durationMs: Date.now() - startedAt,\n error: {\n code: \"internal_error\",\n message: `isolated-vm catastrophic error: ${catastrophicErrorMessage}`,\n },\n logs: truncateLogs(logs, this.maxLogLines, this.maxLogChars),\n ok: false,\n };\n }\n\n if (!execution.ok) {\n return {\n durationMs: Date.now() - startedAt,\n error: toExecuteError(execution.error, deadline),\n logs: truncateLogs(logs, this.maxLogLines, this.maxLogChars),\n ok: false,\n };\n }\n\n return {\n durationMs: Date.now() - startedAt,\n logs: truncateLogs(logs, this.maxLogLines, this.maxLogChars),\n ok: true,\n result: execution.value,\n };\n } catch (error) {\n const executeError =\n catastrophicErrorMessage !== undefined\n ? {\n code: \"internal_error\" as const,\n message: `isolated-vm catastrophic error: ${catastrophicErrorMessage}`,\n }\n : toExecuteError(error, deadline);\n\n return {\n durationMs: Date.now() - startedAt,\n error: executeError,\n logs: truncateLogs(logs, this.maxLogLines, this.maxLogChars),\n ok: false,\n };\n } finally {\n abortController.abort();\n context?.release?.();\n isolate?.dispose();\n }\n }\n}\n"],"mappings":"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"}
package/dist/index.d.cts CHANGED
@@ -27,6 +27,9 @@ declare class IsolatedVmExecutor implements Executor {
27
27
  private readonly maxLogLines;
28
28
  private readonly memoryLimitBytes;
29
29
  private readonly timeoutMs;
30
+ /**
31
+ * Creates an isolated-vm executor with one-shot runtime limits and host bridging configuration.
32
+ */
30
33
  constructor(options?: IsolatedVmExecutorOptions);
31
34
  /**
32
35
  * Executes JavaScript against the provided tool namespaces in a fresh isolated-vm context.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/types.ts","../src/isolatedVmExecutor.ts"],"sourcesContent":[],"mappings":";;;;;;AAGiB,UAAA,yBAAA,CAEI;;qBAAA;;EC+eR,WAAA,CAAA,EAAA,MAAA;EAOU;EAmBR,WAAA,CAAA,EAAA,MAAA;EACF;EAAR,gBAAA,CAAA,EAAA,MAAA;EA3BsC;EAAQ,SAAA,CAAA,EAAA,MAAA;;;;;ADjfnD;;cCifa,kBAAA,YAA8B;;EAA9B,iBAAA,WAAmB;EAOT,iBAAA,WAAA;EAmBR,iBAAA,gBAAA;EACF,iBAAA,SAAA;EAAR,WAAA,CAAA,OAAA,CAAA,EApBkB,yBAoBlB;EA3BsC;;;mCA0B5B,yBACV,QAAQ"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/types.ts","../src/isolatedVmExecutor.ts"],"sourcesContent":[],"mappings":";;;;;;AAGiB,UAAA,yBAAA,CAEI;;qBAAA;;EC4gBR,WAAA,CAAA,EAAA,MAAA;EAUU;EAmBR,WAAA,CAAA,EAAA,MAAA;EACF;EAAR,gBAAA,CAAA,EAAA,MAAA;EA9BsC;EAAQ,SAAA,CAAA,EAAA,MAAA;;;;;AD9gBnD;;cC8gBa,kBAAA,YAA8B;;EAA9B,iBAAA,WAAmB;EAUT,iBAAA,WAAA;EAmBR,iBAAA,gBAAA;EACF,iBAAA,SAAA;EAAR;;;wBApBkB;;;;mCAmBR,yBACV,QAAQ"}
package/dist/index.d.ts CHANGED
@@ -27,6 +27,9 @@ declare class IsolatedVmExecutor implements Executor {
27
27
  private readonly maxLogLines;
28
28
  private readonly memoryLimitBytes;
29
29
  private readonly timeoutMs;
30
+ /**
31
+ * Creates an isolated-vm executor with one-shot runtime limits and host bridging configuration.
32
+ */
30
33
  constructor(options?: IsolatedVmExecutorOptions);
31
34
  /**
32
35
  * Executes JavaScript against the provided tool namespaces in a fresh isolated-vm context.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/isolatedVmExecutor.ts"],"sourcesContent":[],"mappings":";;;;;;AAGiB,UAAA,yBAAA,CAEI;;qBAAA;;EC+eR,WAAA,CAAA,EAAA,MAAA;EAOU;EAmBR,WAAA,CAAA,EAAA,MAAA;EACF;EAAR,gBAAA,CAAA,EAAA,MAAA;EA3BsC;EAAQ,SAAA,CAAA,EAAA,MAAA;;;;;ADjfnD;;cCifa,kBAAA,YAA8B;;EAA9B,iBAAA,WAAmB;EAOT,iBAAA,WAAA;EAmBR,iBAAA,gBAAA;EACF,iBAAA,SAAA;EAAR,WAAA,CAAA,OAAA,CAAA,EApBkB,yBAoBlB;EA3BsC;;;mCA0B5B,yBACV,QAAQ"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/isolatedVmExecutor.ts"],"sourcesContent":[],"mappings":";;;;;;AAGiB,UAAA,yBAAA,CAEI;;qBAAA;;EC4gBR,WAAA,CAAA,EAAA,MAAA;EAUU;EAmBR,WAAA,CAAA,EAAA,MAAA;EACF;EAAR,gBAAA,CAAA,EAAA,MAAA;EA9BsC;EAAQ,SAAA,CAAA,EAAA,MAAA;;;;;AD9gBnD;;cC8gBa,kBAAA,YAA8B;;EAA9B,iBAAA,WAAmB;EAUT,iBAAA,WAAA;EAmBR,iBAAA,gBAAA;EACF,iBAAA,SAAA;EAAR;;;wBApBkB;;;;mCAmBR,yBACV,QAAQ"}
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { randomUUID } from "node:crypto";
1
2
  import { ExecuteFailure, isExecuteFailure, normalizeCode } from "@mcploom/codexec";
2
3
 
3
4
  //#region src/isolatedVmExecutor.ts
@@ -5,7 +6,6 @@ const DEFAULT_MEMORY_LIMIT_BYTES = 64 * 1024 * 1024;
5
6
  const DEFAULT_TIMEOUT_MS = 5e3;
6
7
  const DEFAULT_MAX_LOG_LINES = 100;
7
8
  const DEFAULT_MAX_LOG_CHARS = 64e3;
8
- const HOST_ERROR_PREFIX = "__MCP_CODE_EXEC_HOST_ERROR__";
9
9
  let cachedModulePromise;
10
10
  function createExecutionContext(signal, providerName, safeToolName, originalToolName) {
11
11
  return {
@@ -139,31 +139,51 @@ async function loadDefaultModule() {
139
139
  });
140
140
  return cachedModulePromise;
141
141
  }
142
- function createBootstrapSource(providers, timeoutMs) {
142
+ function createBootstrapSource(providers, hostErrorPrefix, timeoutMs) {
143
143
  const lines = [
144
- `const __MCP_HOST_ERROR_PREFIX = ${JSON.stringify(HOST_ERROR_PREFIX)};`,
145
- "const __mcpNormalizeError = (error) => {",
146
- " if (error && typeof error === 'object' && typeof error.code === 'string' && typeof error.message === 'string') {",
147
- " return { code: error.code, message: error.message };",
144
+ `const __MCP_HOST_ERROR_PREFIX = ${JSON.stringify(hostErrorPrefix)};`,
145
+ `const __MCP_HOST_ERROR_KEY = ${JSON.stringify(`${hostErrorPrefix}key`)};`,
146
+ "const __mcpCreateTrustedError = (code, message) => ({",
147
+ " [__MCP_HOST_ERROR_KEY]: true,",
148
+ " code,",
149
+ " message,",
150
+ "});",
151
+ "const __mcpNormalizeTrustedError = (error) => {",
152
+ " if (error && typeof error === 'object' && error[__MCP_HOST_ERROR_KEY] === true && typeof error.code === 'string' && typeof error.message === 'string') {",
153
+ " return __mcpCreateTrustedError(error.code, error.message);",
148
154
  " }",
149
155
  " if (error && typeof error.message === 'string' && error.message.startsWith(__MCP_HOST_ERROR_PREFIX)) {",
150
156
  " try {",
151
157
  " const payload = JSON.parse(error.message.slice(__MCP_HOST_ERROR_PREFIX.length));",
152
158
  " if (payload && typeof payload.code === 'string' && typeof payload.message === 'string') {",
153
- " return payload;",
159
+ " return __mcpCreateTrustedError(payload.code, payload.message);",
154
160
  " }",
155
161
  " } catch {}",
156
162
  " }",
163
+ " return null;",
164
+ "};",
165
+ "const __mcpNormalizeGuestError = (error) => {",
166
+ " const trusted = __mcpNormalizeTrustedError(error);",
167
+ " if (trusted) {",
168
+ " return trusted;",
169
+ " }",
157
170
  " if (error && typeof error.message === 'string') {",
158
171
  " return { code: 'runtime_error', message: error.message };",
159
172
  " }",
160
173
  " return { code: 'runtime_error', message: String(error) };",
161
174
  "};",
175
+ "const __mcpNormalizeHostError = (error) => {",
176
+ " const trusted = __mcpNormalizeTrustedError(error);",
177
+ " if (trusted) {",
178
+ " return trusted;",
179
+ " }",
180
+ " if (error && typeof error === 'object' && typeof error.code === 'string' && typeof error.message === 'string') {",
181
+ " return __mcpCreateTrustedError(error.code, error.message);",
182
+ " }",
183
+ " return __mcpNormalizeGuestError(error);",
184
+ "};",
162
185
  "const __mcpRaiseNormalizedError = (error) => {",
163
- " const normalized = __mcpNormalizeError(error);",
164
- " const wrapped = new Error(normalized.message);",
165
- " wrapped.code = normalized.code;",
166
- " throw wrapped;",
186
+ " throw __mcpNormalizeHostError(error);",
167
187
  "};",
168
188
  "const __mcpToJsonValue = (value) => {",
169
189
  " if (typeof value === 'undefined') {",
@@ -171,9 +191,10 @@ function createBootstrapSource(providers, timeoutMs) {
171
191
  " }",
172
192
  " const json = JSON.stringify(value);",
173
193
  " if (typeof json === 'undefined') {",
174
- " const error = new Error('Guest code returned a non-serializable value');",
175
- " error.code = 'serialization_error';",
176
- " throw error;",
194
+ " throw __mcpCreateTrustedError(",
195
+ " 'serialization_error',",
196
+ " 'Guest code returned a non-serializable value'",
197
+ " );",
177
198
  " }",
178
199
  " return JSON.parse(json);",
179
200
  "};",
@@ -201,7 +222,7 @@ function createExecutionSource(code) {
201
222
  " const value = await __mcpUserFunction();",
202
223
  " return { ok: true, value: __mcpToJsonValue(value) };",
203
224
  " } catch (error) {",
204
- " return { ok: false, error: __mcpNormalizeError(error) };",
225
+ " return { ok: false, error: __mcpNormalizeGuestError(error) };",
205
226
  " }",
206
227
  "})();"
207
228
  ].join("\n");
@@ -221,7 +242,7 @@ function setConsoleBindings(context, logs) {
221
242
  logs.push(formatConsoleLine(args));
222
243
  });
223
244
  }
224
- function setProviderBindings(ivm, context, providers, signal, deadline) {
245
+ function setProviderBindings(ivm, context, providers, signal, deadline, hostErrorPrefix) {
225
246
  const jail = context.global;
226
247
  for (const provider of providers) for (const [safeToolName, descriptor] of Object.entries(provider.tools)) {
227
248
  const hostReferenceName = `__mcp_tool_${provider.name}_${safeToolName}`;
@@ -229,10 +250,12 @@ function setProviderBindings(ivm, context, providers, signal, deadline) {
229
250
  const executionContext = createExecutionContext(signal, provider.name, safeToolName, descriptor.originalName);
230
251
  try {
231
252
  const normalizedInput = input === void 0 ? void 0 : toJsonValue(input, "Guest code passed a non-serializable tool input");
232
- return toTransferableValue(ivm, await runWithDeadline(Promise.resolve(descriptor.execute(normalizedInput, executionContext)), deadline, signal));
253
+ const pendingExecution = Promise.resolve(descriptor.execute(normalizedInput, executionContext));
254
+ pendingExecution.catch(() => {});
255
+ return toTransferableValue(ivm, await runWithDeadline(pendingExecution, deadline, signal));
233
256
  } catch (error) {
234
257
  const executeError = toExecuteError(error, deadline);
235
- throw new Error(`${HOST_ERROR_PREFIX}${JSON.stringify(executeError)}`, { cause: error });
258
+ throw new Error(`${hostErrorPrefix}${JSON.stringify(executeError)}`, { cause: error });
236
259
  }
237
260
  }, { reference: true });
238
261
  }
@@ -246,6 +269,9 @@ var IsolatedVmExecutor = class {
246
269
  maxLogLines;
247
270
  memoryLimitBytes;
248
271
  timeoutMs;
272
+ /**
273
+ * Creates an isolated-vm executor with one-shot runtime limits and host bridging configuration.
274
+ */
249
275
  constructor(options = {}) {
250
276
  this.loadModule = async () => {
251
277
  return options.loadModule ? await options.loadModule() : await loadDefaultModule();
@@ -263,6 +289,7 @@ var IsolatedVmExecutor = class {
263
289
  const deadline = startedAt + this.timeoutMs;
264
290
  const logs = [];
265
291
  const abortController = new AbortController();
292
+ const hostErrorPrefix = `__MCP_CODE_EXEC_HOST_ERROR__${randomUUID()}:`;
266
293
  if (Number.parseInt(process.versions.node.split(".")[0] ?? "0", 10) >= 20 && !hasRequiredNodeFlag()) return {
267
294
  durationMs: Date.now() - startedAt,
268
295
  error: {
@@ -286,8 +313,8 @@ var IsolatedVmExecutor = class {
286
313
  });
287
314
  context = await isolate.createContext();
288
315
  setConsoleBindings(context, logs);
289
- setProviderBindings(ivm, context, providers, abortController.signal, deadline);
290
- await context.eval(createBootstrapSource(providers, this.timeoutMs), { timeout: this.timeoutMs });
316
+ setProviderBindings(ivm, context, providers, abortController.signal, deadline, hostErrorPrefix);
317
+ await context.eval(createBootstrapSource(providers, hostErrorPrefix, this.timeoutMs), { timeout: this.timeoutMs });
291
318
  const execution = await context.evalClosure(createExecutionSource(code), [], {
292
319
  timeout: this.timeoutMs,
293
320
  result: {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["cachedModulePromise: Promise<IsolatedVmModule> | undefined","truncated: string[]","timeoutId: ReturnType<typeof setTimeout> | undefined","logs: string[]","catastrophicErrorMessage: string | undefined","isolate: IsolatedVmIsolate | undefined","context: IsolatedVmContext | undefined"],"sources":["../src/isolatedVmExecutor.ts"],"sourcesContent":["import {\n ExecuteFailure,\n isExecuteFailure,\n normalizeCode,\n} from \"@mcploom/codexec\";\nimport type {\n ExecuteError,\n ExecuteResult,\n Executor,\n ResolvedToolProvider,\n ToolExecutionContext,\n} from \"@mcploom/codexec\";\n\nimport type { IsolatedVmExecutorOptions } from \"./types\";\n\ntype IsolatedVmExternalCopyInstance = {\n copyInto: (options?: { release?: boolean; transferIn?: boolean }) => unknown;\n release?: () => void;\n};\n\ntype IsolatedVmReferenceInstance = {\n setSync: (\n property: string,\n value: unknown,\n options?: Record<string, unknown>,\n ) => void;\n};\n\ntype IsolatedVmContext = {\n eval: (code: string, options?: Record<string, unknown>) => Promise<unknown>;\n evalClosure: (\n code: string,\n args?: unknown[],\n options?: Record<string, unknown>,\n ) => Promise<unknown>;\n global: IsolatedVmReferenceInstance;\n release?: () => void;\n};\n\ntype IsolatedVmIsolate = {\n createContext: () => Promise<IsolatedVmContext>;\n dispose: () => void;\n};\n\ntype IsolatedVmModule = {\n ExternalCopy: new (\n value: unknown,\n options?: Record<string, unknown>,\n ) => IsolatedVmExternalCopyInstance;\n Isolate: new (options?: {\n inspector?: boolean;\n memoryLimit?: number;\n onCatastrophicError?: (message: string) => void;\n }) => IsolatedVmIsolate;\n};\n\ntype GuestExecutionEnvelope =\n | {\n ok: true;\n value: unknown;\n }\n | {\n error: {\n code?: string;\n message?: string;\n };\n ok: false;\n };\n\nconst DEFAULT_MEMORY_LIMIT_BYTES = 64 * 1024 * 1024;\nconst DEFAULT_TIMEOUT_MS = 5000;\nconst DEFAULT_MAX_LOG_LINES = 100;\nconst DEFAULT_MAX_LOG_CHARS = 64_000;\nconst HOST_ERROR_PREFIX = \"__MCP_CODE_EXEC_HOST_ERROR__\";\n\nlet cachedModulePromise: Promise<IsolatedVmModule> | undefined;\n\nfunction createExecutionContext(\n signal: AbortSignal,\n providerName: string,\n safeToolName: string,\n originalToolName: string,\n): ToolExecutionContext {\n return {\n originalToolName,\n providerName,\n safeToolName,\n signal,\n };\n}\n\nfunction hasRequiredNodeFlag(): boolean {\n const execArgv = process.execArgv.join(\" \");\n const nodeOptions = process.env.NODE_OPTIONS ?? \"\";\n return (\n execArgv.includes(\"--no-node-snapshot\") ||\n nodeOptions.includes(\"--no-node-snapshot\")\n );\n}\n\nfunction isKnownErrorCode(value: unknown): value is ExecuteError[\"code\"] {\n return (\n value === \"timeout\" ||\n value === \"memory_limit\" ||\n value === \"validation_error\" ||\n value === \"tool_error\" ||\n value === \"runtime_error\" ||\n value === \"serialization_error\" ||\n value === \"internal_error\"\n );\n}\n\nfunction normalizeThrownMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n\n if (typeof error === \"object\" && error !== null && \"message\" in error) {\n const message = (error as { message?: unknown }).message;\n if (typeof message === \"string\") {\n return message;\n }\n }\n\n return String(error);\n}\n\nfunction truncateLogs(\n logs: string[],\n maxLogLines: number,\n maxLogChars: number,\n): string[] {\n const limitedLines = logs.slice(0, maxLogLines);\n let remainingChars = maxLogChars;\n const truncated: string[] = [];\n\n for (const line of limitedLines) {\n if (remainingChars <= 0) {\n break;\n }\n\n if (line.length <= remainingChars) {\n truncated.push(line);\n remainingChars -= line.length;\n continue;\n }\n\n truncated.push(line.slice(0, remainingChars));\n break;\n }\n\n return truncated;\n}\n\nfunction formatLogValue(value: unknown): string {\n if (typeof value === \"string\") {\n return value;\n }\n\n if (value === undefined) {\n return \"undefined\";\n }\n\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nfunction formatConsoleLine(values: unknown[]): string {\n return values.map((value) => formatLogValue(value)).join(\" \");\n}\n\nfunction toJsonValue(value: unknown, message: string): unknown {\n if (value === undefined) {\n return undefined;\n }\n\n const jsonValue = JSON.stringify(value);\n\n if (jsonValue === undefined) {\n throw new ExecuteFailure(\"serialization_error\", message);\n }\n\n try {\n return JSON.parse(jsonValue) as unknown;\n } catch {\n throw new ExecuteFailure(\"serialization_error\", message);\n }\n}\n\nfunction toTransferableValue(ivm: IsolatedVmModule, value: unknown): unknown {\n const normalizedValue = toJsonValue(\n value,\n \"Host value is not JSON-serializable\",\n );\n\n if (\n normalizedValue === null ||\n normalizedValue === undefined ||\n typeof normalizedValue === \"string\" ||\n typeof normalizedValue === \"number\" ||\n typeof normalizedValue === \"boolean\"\n ) {\n return normalizedValue;\n }\n\n const copy = new ivm.ExternalCopy(normalizedValue);\n return copy.copyInto({ release: true });\n}\n\nfunction toExecuteError(error: unknown, deadline: number): ExecuteError {\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n \"message\" in error &&\n isKnownErrorCode((error as { code?: unknown }).code) &&\n typeof (error as { message?: unknown }).message === \"string\"\n ) {\n return {\n code: (error as { code: ExecuteError[\"code\"] }).code,\n message: (error as { message: string }).message,\n };\n }\n\n if (isExecuteFailure(error)) {\n return {\n code: error.code,\n message: error.message,\n };\n }\n\n const message = normalizeThrownMessage(error);\n const normalizedMessage = message.toLowerCase();\n\n if (\n Date.now() > deadline ||\n normalizedMessage.includes(\"timed out\") ||\n normalizedMessage.includes(\"time limit\")\n ) {\n return {\n code: \"timeout\",\n message: \"Execution timed out\",\n };\n }\n\n if (\n normalizedMessage.includes(\"memory limit\") ||\n normalizedMessage.includes(\"out of memory\")\n ) {\n return {\n code: \"memory_limit\",\n message,\n };\n }\n\n if (\n normalizedMessage.includes(\"could not be cloned\") ||\n normalizedMessage.includes(\"non-transferable\") ||\n normalizedMessage.includes(\"not json-serializable\")\n ) {\n return {\n code: \"serialization_error\",\n message,\n };\n }\n\n return {\n code: \"runtime_error\",\n message,\n };\n}\n\nfunction toMemoryLimitMb(memoryLimitBytes: number): number {\n return Math.max(8, Math.ceil(memoryLimitBytes / (1024 * 1024)));\n}\n\nfunction remainingTime(deadline: number): number {\n return Math.max(0, deadline - Date.now());\n}\n\nasync function runWithDeadline<T>(\n operation: Promise<T>,\n deadline: number,\n signal: AbortSignal,\n): Promise<T> {\n if (signal.aborted || Date.now() > deadline) {\n throw new ExecuteFailure(\"timeout\", \"Execution timed out\");\n }\n\n const timeoutMs = remainingTime(deadline);\n if (timeoutMs <= 0) {\n throw new ExecuteFailure(\"timeout\", \"Execution timed out\");\n }\n\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n return await new Promise<T>((resolve, reject) => {\n const onAbort = () => {\n reject(new ExecuteFailure(\"timeout\", \"Execution timed out\"));\n };\n\n signal.addEventListener(\"abort\", onAbort, { once: true });\n timeoutId = setTimeout(() => {\n signal.removeEventListener(\"abort\", onAbort);\n reject(new ExecuteFailure(\"timeout\", \"Execution timed out\"));\n }, timeoutMs);\n\n void operation.then(\n (value) => {\n signal.removeEventListener(\"abort\", onAbort);\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n resolve(value);\n },\n (error) => {\n signal.removeEventListener(\"abort\", onAbort);\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n reject(error);\n },\n );\n });\n}\n\nasync function loadDefaultModule(): Promise<IsolatedVmModule> {\n cachedModulePromise ??= import(\"isolated-vm\").then((loaded) => {\n const candidate = (\n \"default\" in loaded ? loaded.default : loaded\n ) as unknown;\n return candidate as IsolatedVmModule;\n });\n\n return cachedModulePromise;\n}\n\nfunction createBootstrapSource(\n providers: ResolvedToolProvider[],\n timeoutMs: number,\n): string {\n const lines = [\n `const __MCP_HOST_ERROR_PREFIX = ${JSON.stringify(HOST_ERROR_PREFIX)};`,\n \"const __mcpNormalizeError = (error) => {\",\n \" if (error && typeof error === 'object' && typeof error.code === 'string' && typeof error.message === 'string') {\",\n \" return { code: error.code, message: error.message };\",\n \" }\",\n \" if (error && typeof error.message === 'string' && error.message.startsWith(__MCP_HOST_ERROR_PREFIX)) {\",\n \" try {\",\n \" const payload = JSON.parse(error.message.slice(__MCP_HOST_ERROR_PREFIX.length));\",\n \" if (payload && typeof payload.code === 'string' && typeof payload.message === 'string') {\",\n \" return payload;\",\n \" }\",\n \" } catch {}\",\n \" }\",\n \" if (error && typeof error.message === 'string') {\",\n \" return { code: 'runtime_error', message: error.message };\",\n \" }\",\n \" return { code: 'runtime_error', message: String(error) };\",\n \"};\",\n \"const __mcpRaiseNormalizedError = (error) => {\",\n \" const normalized = __mcpNormalizeError(error);\",\n \" const wrapped = new Error(normalized.message);\",\n \" wrapped.code = normalized.code;\",\n \" throw wrapped;\",\n \"};\",\n \"const __mcpToJsonValue = (value) => {\",\n \" if (typeof value === 'undefined') {\",\n \" return undefined;\",\n \" }\",\n \" const json = JSON.stringify(value);\",\n \" if (typeof json === 'undefined') {\",\n \" const error = new Error('Guest code returned a non-serializable value');\",\n \" error.code = 'serialization_error';\",\n \" throw error;\",\n \" }\",\n \" return JSON.parse(json);\",\n \"};\",\n \"globalThis.console = {\",\n \" log: (...args) => __mcp_console_log(...args),\",\n \" info: (...args) => __mcp_console_info(...args),\",\n \" warn: (...args) => __mcp_console_warn(...args),\",\n \" error: (...args) => __mcp_console_error(...args),\",\n \"};\",\n ];\n\n for (const provider of providers) {\n lines.push(`globalThis.${provider.name} = {};`);\n\n for (const safeToolName of Object.keys(provider.tools)) {\n const hostReferenceName = `__mcp_tool_${provider.name}_${safeToolName}`;\n lines.push(\n `globalThis.${provider.name}.${safeToolName} = async (input) => {`,\n \" try {\",\n ` return await ${hostReferenceName}.applySyncPromise(undefined, [input], { arguments: { copy: true }, timeout: ${timeoutMs} });`,\n \" } catch (error) {\",\n \" __mcpRaiseNormalizedError(error);\",\n \" }\",\n \"};\",\n );\n }\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction createExecutionSource(code: string): string {\n const executableSource = normalizeCode(code);\n\n return [\n `const __mcpUserFunction = (${executableSource});`,\n \"return (async () => {\",\n \" try {\",\n \" const value = await __mcpUserFunction();\",\n \" return { ok: true, value: __mcpToJsonValue(value) };\",\n \" } catch (error) {\",\n \" return { ok: false, error: __mcpNormalizeError(error) };\",\n \" }\",\n \"})();\",\n ].join(\"\\n\");\n}\n\nfunction setConsoleBindings(context: IsolatedVmContext, logs: string[]): void {\n const jail = context.global;\n jail.setSync(\"__mcp_console_log\", (...args: unknown[]) => {\n logs.push(formatConsoleLine(args));\n });\n jail.setSync(\"__mcp_console_info\", (...args: unknown[]) => {\n logs.push(formatConsoleLine(args));\n });\n jail.setSync(\"__mcp_console_warn\", (...args: unknown[]) => {\n logs.push(formatConsoleLine(args));\n });\n jail.setSync(\"__mcp_console_error\", (...args: unknown[]) => {\n logs.push(formatConsoleLine(args));\n });\n}\n\nfunction setProviderBindings(\n ivm: IsolatedVmModule,\n context: IsolatedVmContext,\n providers: ResolvedToolProvider[],\n signal: AbortSignal,\n deadline: number,\n): void {\n const jail = context.global;\n\n for (const provider of providers) {\n for (const [safeToolName, descriptor] of Object.entries(provider.tools)) {\n const hostReferenceName = `__mcp_tool_${provider.name}_${safeToolName}`;\n\n jail.setSync(\n hostReferenceName,\n async (input: unknown) => {\n const executionContext = createExecutionContext(\n signal,\n provider.name,\n safeToolName,\n descriptor.originalName,\n );\n\n try {\n const normalizedInput =\n input === undefined\n ? undefined\n : toJsonValue(\n input,\n \"Guest code passed a non-serializable tool input\",\n );\n const result = await runWithDeadline(\n Promise.resolve(\n descriptor.execute(normalizedInput, executionContext),\n ),\n deadline,\n signal,\n );\n\n return toTransferableValue(ivm, result);\n } catch (error) {\n const executeError = toExecuteError(error, deadline);\n throw new Error(\n `${HOST_ERROR_PREFIX}${JSON.stringify(executeError)}`,\n {\n cause: error,\n },\n );\n }\n },\n { reference: true },\n );\n }\n }\n}\n\n/**\n * isolated-vm-backed executor for one-shot sandboxed JavaScript runs.\n */\nexport class IsolatedVmExecutor implements Executor {\n private readonly loadModule: () => Promise<IsolatedVmModule>;\n private readonly maxLogChars: number;\n private readonly maxLogLines: number;\n private readonly memoryLimitBytes: number;\n private readonly timeoutMs: number;\n\n constructor(options: IsolatedVmExecutorOptions = {}) {\n this.loadModule = async () => {\n const loaded = options.loadModule\n ? await options.loadModule()\n : await loadDefaultModule();\n return loaded as IsolatedVmModule;\n };\n this.maxLogChars = options.maxLogChars ?? DEFAULT_MAX_LOG_CHARS;\n this.maxLogLines = options.maxLogLines ?? DEFAULT_MAX_LOG_LINES;\n this.memoryLimitBytes =\n options.memoryLimitBytes ?? DEFAULT_MEMORY_LIMIT_BYTES;\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n }\n\n /**\n * Executes JavaScript against the provided tool namespaces in a fresh isolated-vm context.\n */\n async execute(\n code: string,\n providers: ResolvedToolProvider[],\n ): Promise<ExecuteResult> {\n const startedAt = Date.now();\n const deadline = startedAt + this.timeoutMs;\n const logs: string[] = [];\n const abortController = new AbortController();\n const nodeMajorVersion = Number.parseInt(\n process.versions.node.split(\".\")[0] ?? \"0\",\n 10,\n );\n\n if (nodeMajorVersion >= 20 && !hasRequiredNodeFlag()) {\n return {\n durationMs: Date.now() - startedAt,\n error: {\n code: \"internal_error\",\n message:\n \"isolated-vm requires Node to run with --no-node-snapshot on Node 20+\",\n },\n logs,\n ok: false,\n };\n }\n\n let catastrophicErrorMessage: string | undefined;\n let isolate: IsolatedVmIsolate | undefined;\n let context: IsolatedVmContext | undefined;\n\n try {\n const ivm = await this.loadModule();\n isolate = new ivm.Isolate({\n memoryLimit: toMemoryLimitMb(this.memoryLimitBytes),\n onCatastrophicError: (message) => {\n catastrophicErrorMessage = message;\n abortController.abort();\n },\n });\n context = await isolate.createContext();\n\n setConsoleBindings(context, logs);\n setProviderBindings(\n ivm,\n context,\n providers,\n abortController.signal,\n deadline,\n );\n await context.eval(createBootstrapSource(providers, this.timeoutMs), {\n timeout: this.timeoutMs,\n });\n\n const execution = (await context.evalClosure(\n createExecutionSource(code),\n [],\n {\n timeout: this.timeoutMs,\n result: { copy: true, promise: true },\n },\n )) as GuestExecutionEnvelope;\n\n if (catastrophicErrorMessage) {\n return {\n durationMs: Date.now() - startedAt,\n error: {\n code: \"internal_error\",\n message: `isolated-vm catastrophic error: ${catastrophicErrorMessage}`,\n },\n logs: truncateLogs(logs, this.maxLogLines, this.maxLogChars),\n ok: false,\n };\n }\n\n if (!execution.ok) {\n return {\n durationMs: Date.now() - startedAt,\n error: toExecuteError(execution.error, deadline),\n logs: truncateLogs(logs, this.maxLogLines, this.maxLogChars),\n ok: false,\n };\n }\n\n return {\n durationMs: Date.now() - startedAt,\n logs: truncateLogs(logs, this.maxLogLines, this.maxLogChars),\n ok: true,\n result: execution.value,\n };\n } catch (error) {\n const executeError =\n catastrophicErrorMessage !== undefined\n ? {\n code: \"internal_error\" as const,\n message: `isolated-vm catastrophic error: ${catastrophicErrorMessage}`,\n }\n : toExecuteError(error, deadline);\n\n return {\n durationMs: Date.now() - startedAt,\n error: executeError,\n logs: truncateLogs(logs, this.maxLogLines, this.maxLogChars),\n ok: false,\n };\n } finally {\n abortController.abort();\n context?.release?.();\n isolate?.dispose();\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["cachedModulePromise: Promise<IsolatedVmModule> | undefined","truncated: string[]","timeoutId: ReturnType<typeof setTimeout> | undefined","logs: string[]","catastrophicErrorMessage: string | undefined","isolate: IsolatedVmIsolate | undefined","context: IsolatedVmContext | undefined"],"sources":["../src/isolatedVmExecutor.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\n\nimport {\n ExecuteFailure,\n isExecuteFailure,\n normalizeCode,\n} from \"@mcploom/codexec\";\nimport type {\n ExecuteError,\n ExecuteResult,\n Executor,\n ResolvedToolProvider,\n ToolExecutionContext,\n} from \"@mcploom/codexec\";\n\nimport type { IsolatedVmExecutorOptions } from \"./types\";\n\ntype IsolatedVmExternalCopyInstance = {\n copyInto: (options?: { release?: boolean; transferIn?: boolean }) => unknown;\n release?: () => void;\n};\n\ntype IsolatedVmReferenceInstance = {\n setSync: (\n property: string,\n value: unknown,\n options?: Record<string, unknown>,\n ) => void;\n};\n\ntype IsolatedVmContext = {\n eval: (code: string, options?: Record<string, unknown>) => Promise<unknown>;\n evalClosure: (\n code: string,\n args?: unknown[],\n options?: Record<string, unknown>,\n ) => Promise<unknown>;\n global: IsolatedVmReferenceInstance;\n release?: () => void;\n};\n\ntype IsolatedVmIsolate = {\n createContext: () => Promise<IsolatedVmContext>;\n dispose: () => void;\n};\n\ntype IsolatedVmModule = {\n ExternalCopy: new (\n value: unknown,\n options?: Record<string, unknown>,\n ) => IsolatedVmExternalCopyInstance;\n Isolate: new (options?: {\n inspector?: boolean;\n memoryLimit?: number;\n onCatastrophicError?: (message: string) => void;\n }) => IsolatedVmIsolate;\n};\n\ntype GuestExecutionEnvelope =\n | {\n ok: true;\n value: unknown;\n }\n | {\n error: {\n code?: string;\n message?: string;\n };\n ok: false;\n };\n\nconst DEFAULT_MEMORY_LIMIT_BYTES = 64 * 1024 * 1024;\nconst DEFAULT_TIMEOUT_MS = 5000;\nconst DEFAULT_MAX_LOG_LINES = 100;\nconst DEFAULT_MAX_LOG_CHARS = 64_000;\nlet cachedModulePromise: Promise<IsolatedVmModule> | undefined;\n\nfunction createExecutionContext(\n signal: AbortSignal,\n providerName: string,\n safeToolName: string,\n originalToolName: string,\n): ToolExecutionContext {\n return {\n originalToolName,\n providerName,\n safeToolName,\n signal,\n };\n}\n\nfunction hasRequiredNodeFlag(): boolean {\n const execArgv = process.execArgv.join(\" \");\n const nodeOptions = process.env.NODE_OPTIONS ?? \"\";\n return (\n execArgv.includes(\"--no-node-snapshot\") ||\n nodeOptions.includes(\"--no-node-snapshot\")\n );\n}\n\nfunction isKnownErrorCode(value: unknown): value is ExecuteError[\"code\"] {\n return (\n value === \"timeout\" ||\n value === \"memory_limit\" ||\n value === \"validation_error\" ||\n value === \"tool_error\" ||\n value === \"runtime_error\" ||\n value === \"serialization_error\" ||\n value === \"internal_error\"\n );\n}\n\nfunction normalizeThrownMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n\n if (typeof error === \"object\" && error !== null && \"message\" in error) {\n const message = (error as { message?: unknown }).message;\n if (typeof message === \"string\") {\n return message;\n }\n }\n\n return String(error);\n}\n\nfunction truncateLogs(\n logs: string[],\n maxLogLines: number,\n maxLogChars: number,\n): string[] {\n const limitedLines = logs.slice(0, maxLogLines);\n let remainingChars = maxLogChars;\n const truncated: string[] = [];\n\n for (const line of limitedLines) {\n if (remainingChars <= 0) {\n break;\n }\n\n if (line.length <= remainingChars) {\n truncated.push(line);\n remainingChars -= line.length;\n continue;\n }\n\n truncated.push(line.slice(0, remainingChars));\n break;\n }\n\n return truncated;\n}\n\nfunction formatLogValue(value: unknown): string {\n if (typeof value === \"string\") {\n return value;\n }\n\n if (value === undefined) {\n return \"undefined\";\n }\n\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nfunction formatConsoleLine(values: unknown[]): string {\n return values.map((value) => formatLogValue(value)).join(\" \");\n}\n\nfunction toJsonValue(value: unknown, message: string): unknown {\n if (value === undefined) {\n return undefined;\n }\n\n const jsonValue = JSON.stringify(value);\n\n if (jsonValue === undefined) {\n throw new ExecuteFailure(\"serialization_error\", message);\n }\n\n try {\n return JSON.parse(jsonValue) as unknown;\n } catch {\n throw new ExecuteFailure(\"serialization_error\", message);\n }\n}\n\nfunction toTransferableValue(ivm: IsolatedVmModule, value: unknown): unknown {\n const normalizedValue = toJsonValue(\n value,\n \"Host value is not JSON-serializable\",\n );\n\n if (\n normalizedValue === null ||\n normalizedValue === undefined ||\n typeof normalizedValue === \"string\" ||\n typeof normalizedValue === \"number\" ||\n typeof normalizedValue === \"boolean\"\n ) {\n return normalizedValue;\n }\n\n const copy = new ivm.ExternalCopy(normalizedValue);\n return copy.copyInto({ release: true });\n}\n\nfunction toExecuteError(error: unknown, deadline: number): ExecuteError {\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n \"message\" in error &&\n isKnownErrorCode((error as { code?: unknown }).code) &&\n typeof (error as { message?: unknown }).message === \"string\"\n ) {\n return {\n code: (error as { code: ExecuteError[\"code\"] }).code,\n message: (error as { message: string }).message,\n };\n }\n\n if (isExecuteFailure(error)) {\n return {\n code: error.code,\n message: error.message,\n };\n }\n\n const message = normalizeThrownMessage(error);\n const normalizedMessage = message.toLowerCase();\n\n if (\n Date.now() > deadline ||\n normalizedMessage.includes(\"timed out\") ||\n normalizedMessage.includes(\"time limit\")\n ) {\n return {\n code: \"timeout\",\n message: \"Execution timed out\",\n };\n }\n\n if (\n normalizedMessage.includes(\"memory limit\") ||\n normalizedMessage.includes(\"out of memory\")\n ) {\n return {\n code: \"memory_limit\",\n message,\n };\n }\n\n if (\n normalizedMessage.includes(\"could not be cloned\") ||\n normalizedMessage.includes(\"non-transferable\") ||\n normalizedMessage.includes(\"not json-serializable\")\n ) {\n return {\n code: \"serialization_error\",\n message,\n };\n }\n\n return {\n code: \"runtime_error\",\n message,\n };\n}\n\nfunction toMemoryLimitMb(memoryLimitBytes: number): number {\n return Math.max(8, Math.ceil(memoryLimitBytes / (1024 * 1024)));\n}\n\nfunction remainingTime(deadline: number): number {\n return Math.max(0, deadline - Date.now());\n}\n\nasync function runWithDeadline<T>(\n operation: Promise<T>,\n deadline: number,\n signal: AbortSignal,\n): Promise<T> {\n if (signal.aborted || Date.now() > deadline) {\n throw new ExecuteFailure(\"timeout\", \"Execution timed out\");\n }\n\n const timeoutMs = remainingTime(deadline);\n if (timeoutMs <= 0) {\n throw new ExecuteFailure(\"timeout\", \"Execution timed out\");\n }\n\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n return await new Promise<T>((resolve, reject) => {\n const onAbort = () => {\n reject(new ExecuteFailure(\"timeout\", \"Execution timed out\"));\n };\n\n signal.addEventListener(\"abort\", onAbort, { once: true });\n timeoutId = setTimeout(() => {\n signal.removeEventListener(\"abort\", onAbort);\n reject(new ExecuteFailure(\"timeout\", \"Execution timed out\"));\n }, timeoutMs);\n\n void operation.then(\n (value) => {\n signal.removeEventListener(\"abort\", onAbort);\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n resolve(value);\n },\n (error) => {\n signal.removeEventListener(\"abort\", onAbort);\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n reject(error);\n },\n );\n });\n}\n\nasync function loadDefaultModule(): Promise<IsolatedVmModule> {\n cachedModulePromise ??= import(\"isolated-vm\").then((loaded) => {\n const candidate = (\n \"default\" in loaded ? loaded.default : loaded\n ) as unknown;\n return candidate as IsolatedVmModule;\n });\n\n return cachedModulePromise;\n}\n\nfunction createBootstrapSource(\n providers: ResolvedToolProvider[],\n hostErrorPrefix: string,\n timeoutMs: number,\n): string {\n const lines = [\n `const __MCP_HOST_ERROR_PREFIX = ${JSON.stringify(hostErrorPrefix)};`,\n `const __MCP_HOST_ERROR_KEY = ${JSON.stringify(`${hostErrorPrefix}key`)};`,\n \"const __mcpCreateTrustedError = (code, message) => ({\",\n \" [__MCP_HOST_ERROR_KEY]: true,\",\n \" code,\",\n \" message,\",\n \"});\",\n \"const __mcpNormalizeTrustedError = (error) => {\",\n \" if (error && typeof error === 'object' && error[__MCP_HOST_ERROR_KEY] === true && typeof error.code === 'string' && typeof error.message === 'string') {\",\n \" return __mcpCreateTrustedError(error.code, error.message);\",\n \" }\",\n \" if (error && typeof error.message === 'string' && error.message.startsWith(__MCP_HOST_ERROR_PREFIX)) {\",\n \" try {\",\n \" const payload = JSON.parse(error.message.slice(__MCP_HOST_ERROR_PREFIX.length));\",\n \" if (payload && typeof payload.code === 'string' && typeof payload.message === 'string') {\",\n \" return __mcpCreateTrustedError(payload.code, payload.message);\",\n \" }\",\n \" } catch {}\",\n \" }\",\n \" return null;\",\n \"};\",\n \"const __mcpNormalizeGuestError = (error) => {\",\n \" const trusted = __mcpNormalizeTrustedError(error);\",\n \" if (trusted) {\",\n \" return trusted;\",\n \" }\",\n \" if (error && typeof error.message === 'string') {\",\n \" return { code: 'runtime_error', message: error.message };\",\n \" }\",\n \" return { code: 'runtime_error', message: String(error) };\",\n \"};\",\n \"const __mcpNormalizeHostError = (error) => {\",\n \" const trusted = __mcpNormalizeTrustedError(error);\",\n \" if (trusted) {\",\n \" return trusted;\",\n \" }\",\n \" if (error && typeof error === 'object' && typeof error.code === 'string' && typeof error.message === 'string') {\",\n \" return __mcpCreateTrustedError(error.code, error.message);\",\n \" }\",\n \" return __mcpNormalizeGuestError(error);\",\n \"};\",\n \"const __mcpRaiseNormalizedError = (error) => {\",\n \" throw __mcpNormalizeHostError(error);\",\n \"};\",\n \"const __mcpToJsonValue = (value) => {\",\n \" if (typeof value === 'undefined') {\",\n \" return undefined;\",\n \" }\",\n \" const json = JSON.stringify(value);\",\n \" if (typeof json === 'undefined') {\",\n \" throw __mcpCreateTrustedError(\",\n \" 'serialization_error',\",\n \" 'Guest code returned a non-serializable value'\",\n \" );\",\n \" }\",\n \" return JSON.parse(json);\",\n \"};\",\n \"globalThis.console = {\",\n \" log: (...args) => __mcp_console_log(...args),\",\n \" info: (...args) => __mcp_console_info(...args),\",\n \" warn: (...args) => __mcp_console_warn(...args),\",\n \" error: (...args) => __mcp_console_error(...args),\",\n \"};\",\n ];\n\n for (const provider of providers) {\n lines.push(`globalThis.${provider.name} = {};`);\n\n for (const safeToolName of Object.keys(provider.tools)) {\n const hostReferenceName = `__mcp_tool_${provider.name}_${safeToolName}`;\n lines.push(\n `globalThis.${provider.name}.${safeToolName} = async (input) => {`,\n \" try {\",\n ` return await ${hostReferenceName}.applySyncPromise(undefined, [input], { arguments: { copy: true }, timeout: ${timeoutMs} });`,\n \" } catch (error) {\",\n \" __mcpRaiseNormalizedError(error);\",\n \" }\",\n \"};\",\n );\n }\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction createExecutionSource(code: string): string {\n const executableSource = normalizeCode(code);\n\n return [\n `const __mcpUserFunction = (${executableSource});`,\n \"return (async () => {\",\n \" try {\",\n \" const value = await __mcpUserFunction();\",\n \" return { ok: true, value: __mcpToJsonValue(value) };\",\n \" } catch (error) {\",\n \" return { ok: false, error: __mcpNormalizeGuestError(error) };\",\n \" }\",\n \"})();\",\n ].join(\"\\n\");\n}\n\nfunction setConsoleBindings(context: IsolatedVmContext, logs: string[]): void {\n const jail = context.global;\n jail.setSync(\"__mcp_console_log\", (...args: unknown[]) => {\n logs.push(formatConsoleLine(args));\n });\n jail.setSync(\"__mcp_console_info\", (...args: unknown[]) => {\n logs.push(formatConsoleLine(args));\n });\n jail.setSync(\"__mcp_console_warn\", (...args: unknown[]) => {\n logs.push(formatConsoleLine(args));\n });\n jail.setSync(\"__mcp_console_error\", (...args: unknown[]) => {\n logs.push(formatConsoleLine(args));\n });\n}\n\nfunction setProviderBindings(\n ivm: IsolatedVmModule,\n context: IsolatedVmContext,\n providers: ResolvedToolProvider[],\n signal: AbortSignal,\n deadline: number,\n hostErrorPrefix: string,\n): void {\n const jail = context.global;\n\n for (const provider of providers) {\n for (const [safeToolName, descriptor] of Object.entries(provider.tools)) {\n const hostReferenceName = `__mcp_tool_${provider.name}_${safeToolName}`;\n\n jail.setSync(\n hostReferenceName,\n async (input: unknown) => {\n const executionContext = createExecutionContext(\n signal,\n provider.name,\n safeToolName,\n descriptor.originalName,\n );\n\n try {\n const normalizedInput =\n input === undefined\n ? undefined\n : toJsonValue(\n input,\n \"Guest code passed a non-serializable tool input\",\n );\n const pendingExecution = Promise.resolve(\n descriptor.execute(normalizedInput, executionContext),\n );\n\n pendingExecution.catch(() => {\n // The deadline path may settle first; keep late provider rejections from\n // surfacing as unhandled promise rejections after timeout/abort.\n });\n const result = await runWithDeadline(\n pendingExecution,\n deadline,\n signal,\n );\n\n return toTransferableValue(ivm, result);\n } catch (error) {\n const executeError = toExecuteError(error, deadline);\n throw new Error(\n `${hostErrorPrefix}${JSON.stringify(executeError)}`,\n {\n cause: error,\n },\n );\n }\n },\n { reference: true },\n );\n }\n }\n}\n\n/**\n * isolated-vm-backed executor for one-shot sandboxed JavaScript runs.\n */\nexport class IsolatedVmExecutor implements Executor {\n private readonly loadModule: () => Promise<IsolatedVmModule>;\n private readonly maxLogChars: number;\n private readonly maxLogLines: number;\n private readonly memoryLimitBytes: number;\n private readonly timeoutMs: number;\n\n /**\n * Creates an isolated-vm executor with one-shot runtime limits and host bridging configuration.\n */\n constructor(options: IsolatedVmExecutorOptions = {}) {\n this.loadModule = async () => {\n const loaded = options.loadModule\n ? await options.loadModule()\n : await loadDefaultModule();\n return loaded as IsolatedVmModule;\n };\n this.maxLogChars = options.maxLogChars ?? DEFAULT_MAX_LOG_CHARS;\n this.maxLogLines = options.maxLogLines ?? DEFAULT_MAX_LOG_LINES;\n this.memoryLimitBytes =\n options.memoryLimitBytes ?? DEFAULT_MEMORY_LIMIT_BYTES;\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n }\n\n /**\n * Executes JavaScript against the provided tool namespaces in a fresh isolated-vm context.\n */\n async execute(\n code: string,\n providers: ResolvedToolProvider[],\n ): Promise<ExecuteResult> {\n const startedAt = Date.now();\n const deadline = startedAt + this.timeoutMs;\n const logs: string[] = [];\n const abortController = new AbortController();\n const hostErrorPrefix = `__MCP_CODE_EXEC_HOST_ERROR__${randomUUID()}:`;\n const nodeMajorVersion = Number.parseInt(\n process.versions.node.split(\".\")[0] ?? \"0\",\n 10,\n );\n\n if (nodeMajorVersion >= 20 && !hasRequiredNodeFlag()) {\n return {\n durationMs: Date.now() - startedAt,\n error: {\n code: \"internal_error\",\n message:\n \"isolated-vm requires Node to run with --no-node-snapshot on Node 20+\",\n },\n logs,\n ok: false,\n };\n }\n\n let catastrophicErrorMessage: string | undefined;\n let isolate: IsolatedVmIsolate | undefined;\n let context: IsolatedVmContext | undefined;\n\n try {\n const ivm = await this.loadModule();\n isolate = new ivm.Isolate({\n memoryLimit: toMemoryLimitMb(this.memoryLimitBytes),\n onCatastrophicError: (message) => {\n catastrophicErrorMessage = message;\n abortController.abort();\n },\n });\n context = await isolate.createContext();\n\n setConsoleBindings(context, logs);\n setProviderBindings(\n ivm,\n context,\n providers,\n abortController.signal,\n deadline,\n hostErrorPrefix,\n );\n await context.eval(\n createBootstrapSource(providers, hostErrorPrefix, this.timeoutMs),\n {\n timeout: this.timeoutMs,\n },\n );\n\n const execution = (await context.evalClosure(\n createExecutionSource(code),\n [],\n {\n timeout: this.timeoutMs,\n result: { copy: true, promise: true },\n },\n )) as GuestExecutionEnvelope;\n\n if (catastrophicErrorMessage) {\n return {\n durationMs: Date.now() - startedAt,\n error: {\n code: \"internal_error\",\n message: `isolated-vm catastrophic error: ${catastrophicErrorMessage}`,\n },\n logs: truncateLogs(logs, this.maxLogLines, this.maxLogChars),\n ok: false,\n };\n }\n\n if (!execution.ok) {\n return {\n durationMs: Date.now() - startedAt,\n error: toExecuteError(execution.error, deadline),\n logs: truncateLogs(logs, this.maxLogLines, this.maxLogChars),\n ok: false,\n };\n }\n\n return {\n durationMs: Date.now() - startedAt,\n logs: truncateLogs(logs, this.maxLogLines, this.maxLogChars),\n ok: true,\n result: execution.value,\n };\n } catch (error) {\n const executeError =\n catastrophicErrorMessage !== undefined\n ? {\n code: \"internal_error\" as const,\n message: `isolated-vm catastrophic error: ${catastrophicErrorMessage}`,\n }\n : toExecuteError(error, deadline);\n\n return {\n durationMs: Date.now() - startedAt,\n error: executeError,\n logs: truncateLogs(logs, this.maxLogLines, this.maxLogChars),\n ok: false,\n };\n } finally {\n abortController.abort();\n context?.release?.();\n isolate?.dispose();\n }\n }\n}\n"],"mappings":";;;;AAuEA,MAAM,6BAA6B,KAAK,OAAO;AAC/C,MAAM,qBAAqB;AAC3B,MAAM,wBAAwB;AAC9B,MAAM,wBAAwB;AAC9B,IAAIA;AAEJ,SAAS,uBACP,QACA,cACA,cACA,kBACsB;AACtB,QAAO;EACL;EACA;EACA;EACA;EACD;;AAGH,SAAS,sBAA+B;CACtC,MAAM,WAAW,QAAQ,SAAS,KAAK,IAAI;CAC3C,MAAM,cAAc,QAAQ,IAAI,gBAAgB;AAChD,QACE,SAAS,SAAS,qBAAqB,IACvC,YAAY,SAAS,qBAAqB;;AAI9C,SAAS,iBAAiB,OAA+C;AACvE,QACE,UAAU,aACV,UAAU,kBACV,UAAU,sBACV,UAAU,gBACV,UAAU,mBACV,UAAU,yBACV,UAAU;;AAId,SAAS,uBAAuB,OAAwB;AACtD,KAAI,iBAAiB,MACnB,QAAO,MAAM;AAGf,KAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,aAAa,OAAO;EACrE,MAAM,UAAW,MAAgC;AACjD,MAAI,OAAO,YAAY,SACrB,QAAO;;AAIX,QAAO,OAAO,MAAM;;AAGtB,SAAS,aACP,MACA,aACA,aACU;CACV,MAAM,eAAe,KAAK,MAAM,GAAG,YAAY;CAC/C,IAAI,iBAAiB;CACrB,MAAMC,YAAsB,EAAE;AAE9B,MAAK,MAAM,QAAQ,cAAc;AAC/B,MAAI,kBAAkB,EACpB;AAGF,MAAI,KAAK,UAAU,gBAAgB;AACjC,aAAU,KAAK,KAAK;AACpB,qBAAkB,KAAK;AACvB;;AAGF,YAAU,KAAK,KAAK,MAAM,GAAG,eAAe,CAAC;AAC7C;;AAGF,QAAO;;AAGT,SAAS,eAAe,OAAwB;AAC9C,KAAI,OAAO,UAAU,SACnB,QAAO;AAGT,KAAI,UAAU,OACZ,QAAO;AAGT,KAAI;AACF,SAAO,KAAK,UAAU,MAAM;SACtB;AACN,SAAO,OAAO,MAAM;;;AAIxB,SAAS,kBAAkB,QAA2B;AACpD,QAAO,OAAO,KAAK,UAAU,eAAe,MAAM,CAAC,CAAC,KAAK,IAAI;;AAG/D,SAAS,YAAY,OAAgB,SAA0B;AAC7D,KAAI,UAAU,OACZ;CAGF,MAAM,YAAY,KAAK,UAAU,MAAM;AAEvC,KAAI,cAAc,OAChB,OAAM,IAAI,eAAe,uBAAuB,QAAQ;AAG1D,KAAI;AACF,SAAO,KAAK,MAAM,UAAU;SACtB;AACN,QAAM,IAAI,eAAe,uBAAuB,QAAQ;;;AAI5D,SAAS,oBAAoB,KAAuB,OAAyB;CAC3E,MAAM,kBAAkB,YACtB,OACA,sCACD;AAED,KACE,oBAAoB,QACpB,oBAAoB,UACpB,OAAO,oBAAoB,YAC3B,OAAO,oBAAoB,YAC3B,OAAO,oBAAoB,UAE3B,QAAO;AAIT,QADa,IAAI,IAAI,aAAa,gBAAgB,CACtC,SAAS,EAAE,SAAS,MAAM,CAAC;;AAGzC,SAAS,eAAe,OAAgB,UAAgC;AACtE,KACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACV,aAAa,SACb,iBAAkB,MAA6B,KAAK,IACpD,OAAQ,MAAgC,YAAY,SAEpD,QAAO;EACL,MAAO,MAAyC;EAChD,SAAU,MAA8B;EACzC;AAGH,KAAI,iBAAiB,MAAM,CACzB,QAAO;EACL,MAAM,MAAM;EACZ,SAAS,MAAM;EAChB;CAGH,MAAM,UAAU,uBAAuB,MAAM;CAC7C,MAAM,oBAAoB,QAAQ,aAAa;AAE/C,KACE,KAAK,KAAK,GAAG,YACb,kBAAkB,SAAS,YAAY,IACvC,kBAAkB,SAAS,aAAa,CAExC,QAAO;EACL,MAAM;EACN,SAAS;EACV;AAGH,KACE,kBAAkB,SAAS,eAAe,IAC1C,kBAAkB,SAAS,gBAAgB,CAE3C,QAAO;EACL,MAAM;EACN;EACD;AAGH,KACE,kBAAkB,SAAS,sBAAsB,IACjD,kBAAkB,SAAS,mBAAmB,IAC9C,kBAAkB,SAAS,wBAAwB,CAEnD,QAAO;EACL,MAAM;EACN;EACD;AAGH,QAAO;EACL,MAAM;EACN;EACD;;AAGH,SAAS,gBAAgB,kBAAkC;AACzD,QAAO,KAAK,IAAI,GAAG,KAAK,KAAK,oBAAoB,OAAO,MAAM,CAAC;;AAGjE,SAAS,cAAc,UAA0B;AAC/C,QAAO,KAAK,IAAI,GAAG,WAAW,KAAK,KAAK,CAAC;;AAG3C,eAAe,gBACb,WACA,UACA,QACY;AACZ,KAAI,OAAO,WAAW,KAAK,KAAK,GAAG,SACjC,OAAM,IAAI,eAAe,WAAW,sBAAsB;CAG5D,MAAM,YAAY,cAAc,SAAS;AACzC,KAAI,aAAa,EACf,OAAM,IAAI,eAAe,WAAW,sBAAsB;CAG5D,IAAIC;AAEJ,QAAO,MAAM,IAAI,SAAY,SAAS,WAAW;EAC/C,MAAM,gBAAgB;AACpB,UAAO,IAAI,eAAe,WAAW,sBAAsB,CAAC;;AAG9D,SAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,MAAM,CAAC;AACzD,cAAY,iBAAiB;AAC3B,UAAO,oBAAoB,SAAS,QAAQ;AAC5C,UAAO,IAAI,eAAe,WAAW,sBAAsB,CAAC;KAC3D,UAAU;AAEb,EAAK,UAAU,MACZ,UAAU;AACT,UAAO,oBAAoB,SAAS,QAAQ;AAC5C,OAAI,UACF,cAAa,UAAU;AAEzB,WAAQ,MAAM;MAEf,UAAU;AACT,UAAO,oBAAoB,SAAS,QAAQ;AAC5C,OAAI,UACF,cAAa,UAAU;AAEzB,UAAO,MAAM;IAEhB;GACD;;AAGJ,eAAe,oBAA+C;AAC5D,yBAAwB,OAAO,eAAe,MAAM,WAAW;AAI7D,SAFE,aAAa,SAAS,OAAO,UAAU;GAGzC;AAEF,QAAO;;AAGT,SAAS,sBACP,WACA,iBACA,WACQ;CACR,MAAM,QAAQ;EACZ,mCAAmC,KAAK,UAAU,gBAAgB,CAAC;EACnE,gCAAgC,KAAK,UAAU,GAAG,gBAAgB,KAAK,CAAC;EACxE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;AAED,MAAK,MAAM,YAAY,WAAW;AAChC,QAAM,KAAK,cAAc,SAAS,KAAK,QAAQ;AAE/C,OAAK,MAAM,gBAAgB,OAAO,KAAK,SAAS,MAAM,EAAE;GACtD,MAAM,oBAAoB,cAAc,SAAS,KAAK,GAAG;AACzD,SAAM,KACJ,cAAc,SAAS,KAAK,GAAG,aAAa,wBAC5C,WACA,oBAAoB,kBAAkB,8EAA8E,UAAU,OAC9H,uBACA,yCACA,OACA,KACD;;;AAIL,QAAO,MAAM,KAAK,KAAK;;AAGzB,SAAS,sBAAsB,MAAsB;AAGnD,QAAO;EACL,8BAHuB,cAAc,KAAK,CAGK;EAC/C;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,KAAK,KAAK;;AAGd,SAAS,mBAAmB,SAA4B,MAAsB;CAC5E,MAAM,OAAO,QAAQ;AACrB,MAAK,QAAQ,sBAAsB,GAAG,SAAoB;AACxD,OAAK,KAAK,kBAAkB,KAAK,CAAC;GAClC;AACF,MAAK,QAAQ,uBAAuB,GAAG,SAAoB;AACzD,OAAK,KAAK,kBAAkB,KAAK,CAAC;GAClC;AACF,MAAK,QAAQ,uBAAuB,GAAG,SAAoB;AACzD,OAAK,KAAK,kBAAkB,KAAK,CAAC;GAClC;AACF,MAAK,QAAQ,wBAAwB,GAAG,SAAoB;AAC1D,OAAK,KAAK,kBAAkB,KAAK,CAAC;GAClC;;AAGJ,SAAS,oBACP,KACA,SACA,WACA,QACA,UACA,iBACM;CACN,MAAM,OAAO,QAAQ;AAErB,MAAK,MAAM,YAAY,UACrB,MAAK,MAAM,CAAC,cAAc,eAAe,OAAO,QAAQ,SAAS,MAAM,EAAE;EACvE,MAAM,oBAAoB,cAAc,SAAS,KAAK,GAAG;AAEzD,OAAK,QACH,mBACA,OAAO,UAAmB;GACxB,MAAM,mBAAmB,uBACvB,QACA,SAAS,MACT,cACA,WAAW,aACZ;AAED,OAAI;IACF,MAAM,kBACJ,UAAU,SACN,SACA,YACE,OACA,kDACD;IACP,MAAM,mBAAmB,QAAQ,QAC/B,WAAW,QAAQ,iBAAiB,iBAAiB,CACtD;AAED,qBAAiB,YAAY,GAG3B;AAOF,WAAO,oBAAoB,KANZ,MAAM,gBACnB,kBACA,UACA,OACD,CAEsC;YAChC,OAAO;IACd,MAAM,eAAe,eAAe,OAAO,SAAS;AACpD,UAAM,IAAI,MACR,GAAG,kBAAkB,KAAK,UAAU,aAAa,IACjD,EACE,OAAO,OACR,CACF;;KAGL,EAAE,WAAW,MAAM,CACpB;;;;;;AAQP,IAAa,qBAAb,MAAoD;CAClD,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CACjB,AAAiB;;;;CAKjB,YAAY,UAAqC,EAAE,EAAE;AACnD,OAAK,aAAa,YAAY;AAI5B,UAHe,QAAQ,aACnB,MAAM,QAAQ,YAAY,GAC1B,MAAM,mBAAmB;;AAG/B,OAAK,cAAc,QAAQ,eAAe;AAC1C,OAAK,cAAc,QAAQ,eAAe;AAC1C,OAAK,mBACH,QAAQ,oBAAoB;AAC9B,OAAK,YAAY,QAAQ,aAAa;;;;;CAMxC,MAAM,QACJ,MACA,WACwB;EACxB,MAAM,YAAY,KAAK,KAAK;EAC5B,MAAM,WAAW,YAAY,KAAK;EAClC,MAAMC,OAAiB,EAAE;EACzB,MAAM,kBAAkB,IAAI,iBAAiB;EAC7C,MAAM,kBAAkB,+BAA+B,YAAY,CAAC;AAMpE,MALyB,OAAO,SAC9B,QAAQ,SAAS,KAAK,MAAM,IAAI,CAAC,MAAM,KACvC,GACD,IAEuB,MAAM,CAAC,qBAAqB,CAClD,QAAO;GACL,YAAY,KAAK,KAAK,GAAG;GACzB,OAAO;IACL,MAAM;IACN,SACE;IACH;GACD;GACA,IAAI;GACL;EAGH,IAAIC;EACJ,IAAIC;EACJ,IAAIC;AAEJ,MAAI;GACF,MAAM,MAAM,MAAM,KAAK,YAAY;AACnC,aAAU,IAAI,IAAI,QAAQ;IACxB,aAAa,gBAAgB,KAAK,iBAAiB;IACnD,sBAAsB,YAAY;AAChC,gCAA2B;AAC3B,qBAAgB,OAAO;;IAE1B,CAAC;AACF,aAAU,MAAM,QAAQ,eAAe;AAEvC,sBAAmB,SAAS,KAAK;AACjC,uBACE,KACA,SACA,WACA,gBAAgB,QAChB,UACA,gBACD;AACD,SAAM,QAAQ,KACZ,sBAAsB,WAAW,iBAAiB,KAAK,UAAU,EACjE,EACE,SAAS,KAAK,WACf,CACF;GAED,MAAM,YAAa,MAAM,QAAQ,YAC/B,sBAAsB,KAAK,EAC3B,EAAE,EACF;IACE,SAAS,KAAK;IACd,QAAQ;KAAE,MAAM;KAAM,SAAS;KAAM;IACtC,CACF;AAED,OAAI,yBACF,QAAO;IACL,YAAY,KAAK,KAAK,GAAG;IACzB,OAAO;KACL,MAAM;KACN,SAAS,mCAAmC;KAC7C;IACD,MAAM,aAAa,MAAM,KAAK,aAAa,KAAK,YAAY;IAC5D,IAAI;IACL;AAGH,OAAI,CAAC,UAAU,GACb,QAAO;IACL,YAAY,KAAK,KAAK,GAAG;IACzB,OAAO,eAAe,UAAU,OAAO,SAAS;IAChD,MAAM,aAAa,MAAM,KAAK,aAAa,KAAK,YAAY;IAC5D,IAAI;IACL;AAGH,UAAO;IACL,YAAY,KAAK,KAAK,GAAG;IACzB,MAAM,aAAa,MAAM,KAAK,aAAa,KAAK,YAAY;IAC5D,IAAI;IACJ,QAAQ,UAAU;IACnB;WACM,OAAO;GACd,MAAM,eACJ,6BAA6B,SACzB;IACE,MAAM;IACN,SAAS,mCAAmC;IAC7C,GACD,eAAe,OAAO,SAAS;AAErC,UAAO;IACL,YAAY,KAAK,KAAK,GAAG;IACzB,OAAO;IACP,MAAM,aAAa,MAAM,KAAK,aAAa,KAAK,YAAY;IAC5D,IAAI;IACL;YACO;AACR,mBAAgB,OAAO;AACvB,YAAS,WAAW;AACpB,YAAS,SAAS"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcploom/codexec-isolated-vm",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "isolated-vm executor for the mcploom codexec core package.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -41,7 +41,7 @@
41
41
  "homepage": "https://github.com/aallam/mcploom/tree/main/packages/codexec-isolated-vm#readme",
42
42
  "bugs": "https://github.com/aallam/mcploom/issues",
43
43
  "dependencies": {
44
- "@mcploom/codexec": "^0.2.0"
44
+ "@mcploom/codexec": "^0.2.2"
45
45
  },
46
46
  "optionalDependencies": {
47
47
  "isolated-vm": "^6.0.1"