Relocate the ~6k-file docs tree from the repo root into plugins/document-navigator/docs/ so the plugin is self-contained and portable. docs/superpowers/ (specs and plans) stays at the repo root. Moved via cp+rm rather than git mv because directory rename() fails with EPERM on this WSL /mnt DrvFs mount; git rename-detection pairs the identical-content files at commit time. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
8.6 KiB
@suaveplan/sandbox - Server-tier sandboxed code execution: node:vm, node:worker_threads, and node:child_process engines, pre-warmed pool, audit logger, sliding-window rate limiter, pattern-based code transformer, async result streamer.
Server-tier sandboxed code execution for @suaveplan plugin hosts and agent runtimes. Ships four SandboxEngine implementations (a node:vm default, real node:worker_threads for OS-thread isolation, real node:child_process for process isolation, and a structural isolated-vm adapter), a pre-warmed SandboxPool, an async ResultStreamer, a pattern-based CodeTransformer, an allowlist-based ModuleResolver, a sliding-window ResourceLimiter, and a SHA-256 AuditLogger — all behind a createSandbox() facade with Zod-validated config and full OpenTelemetry instrumentation.
Documentation tree
- audit-logger —
AuditLoggerrecords every sandbox execution with a structuredAuditLogEntry. Each entry carries an ISO-8601 timesta…- audit-logger —
AuditLoggerrecords every sandbox execution with a structuredAuditLogEntry. Each entry carries an ISO-8601 timesta…
- audit-logger —
- code-transformer —
CodeTransformeris a defence-in-depth layer that pattern-matches dangerous code constructs before they reach the engi…- code-transformer —
CodeTransformeris a defence-in-depth layer that pattern-matches dangerous code constructs before they reach the engi…
- code-transformer —
- error-codes —
@suaveplan/sandboxraises typedSandboxErrorinstances rather than plainErrorso consumers can discriminate fail…- error-codes —
@suaveplan/sandboxraises typedSandboxErrorinstances rather than plainErrorso consumers can discriminate fail…
- error-codes —
- isolate-engine —
IsolateEngineimplements theSandboxEnginecontract over a structuralIsolateFactoryinterface that mirrors the `…- isolate-engine —
IsolateEngineimplements theSandboxEnginecontract over a structuralIsolateFactoryinterface that mirrors the `…
- isolate-engine —
- module-resolver —
ModuleResolveris the gatekeeper between user code and the host's module surface. It maintains an allowlist of module…- module-resolver —
ModuleResolveris the gatekeeper between user code and the host's module surface. It maintains an allowlist of module…
- module-resolver —
- pool —
SandboxPoolamortises engine startup cost across many short executions by maintaining a warm pool ofSandboxEngine…- pool —
SandboxPoolamortises engine startup cost across many short executions by maintaining a warm pool ofSandboxEngine…
- pool —
- resource-limiter —
ResourceLimiterenforces two complementary controls on the sandbox boundary: a sliding-window rate limit (so a single…- resource-limiter —
ResourceLimiterenforces two complementary controls on the sandbox boundary: a sliding-window rate limit (so a single…
- resource-limiter —
- result-streamer —
ResultStreamerdelivers sandbox output incrementally rather than as a single end-of-execution dump. The most common u…- result-streamer —
ResultStreamerdelivers sandbox output incrementally rather than as a single end-of-execution dump. The most common u…
- result-streamer —
- sandbox —
createSandboxis the public entry point of the package. It composes the engine,ModuleResolver,ResourceLimiter,…- sandbox —
createSandboxis the public entry point of the package. It composes the engine,ModuleResolver,ResourceLimiter,…
- sandbox —
- schemas — Zod schemas guard every public boundary of
@suaveplan/sandbox. The package never trusts its caller; instead, every ar…- schemas — Zod schemas guard every public boundary of
@suaveplan/sandbox. The package never trusts its caller; instead, every ar…
- schemas — Zod schemas guard every public boundary of
- spawn-engine —
SpawnEngineusesnode:child_process.spawnfor the strongest isolation the package offers: a fresh OS process spawne…- runner —
runner.tsis the child-process entry point invoked bySpawnEngine. The parent process spawns it via `node:child_pro… - spawn-engine —
SpawnEngineusesnode:child_process.spawnfor the strongest isolation the package offers: a fresh OS process spawne…
- runner —
- telemetry —
@suaveplan/sandboxships first-class OpenTelemetry instrumentation so consumers running the sandbox at any scale can…- telemetry —
@suaveplan/sandboxships first-class OpenTelemetry instrumentation so consumers running the sandbox at any scale can…
- telemetry —
- vm-engine —
VmEngineis the default sandbox engine. It usesnode:vmdirectly: caller code is compiled withnew vm.Script(...)…- vm-engine —
VmEngineis the default sandbox engine. It usesnode:vmdirectly: caller code is compiled withnew vm.Script(...)…
- vm-engine —
- worker-engine —
WorkerEngineuses realnode:worker_threadsfor true OS-thread isolation. Eachexecutecall spawns a fresh `Worker…- worker-engine —
WorkerEngineuses realnode:worker_threadsfor true OS-thread isolation. Eachexecutecall spawns a fresh `Worker…
- worker-engine —
Install
bun add @suaveplan/sandbox
Quick start
import { createSandbox } from "@suaveplan/sandbox";
const sandbox = createSandbox({ timeout: 5000, engine: "vm" });
const result = await sandbox.execute("2 + 3");
console.log(result.result); // 5
sandbox.destroy();
Engine selection
| Engine | Boundary | Use when |
|---|---|---|
vm (default) |
node:vm context |
Trusted accident-isolation, fastest path. |
worker |
node:worker_threads |
Adversarial code, OS-thread isolation. |
spawn |
node:child_process |
Adversarial code, full process isolation. |
isolate |
isolated-vm (optional dep) |
Strongest in-process isolation. |
Wire engine: "isolate" with a customEngine factory that constructs a real
IsolateEngine over your installed isolated-vm peer dependency.
Modules
Co-located docs for every public surface:
- error-codes —
SANDBOX_CODES,SandboxError. - schemas — Zod boundaries.
- telemetry — OTel instruments + recorders.
- audit-logger — execution audit log.
- resource-limiter — rate-limit + output truncation.
- module-resolver — denylist/allowlist + builtins.
- code-transformer — regex-based dangerous-pattern guard.
- vm-engine — default engine.
- worker-engine — OS-thread engine.
- spawn-engine — process engine.
- runner — spawn-engine child entry point.
- isolate-engine —
isolated-vmstructural adapter. - pool — pre-warmed engine pool.
- result-streamer — async streaming output.
- sandbox —
createSandboxfacade.
Security model
vm-engine shares the host realm and is NOT a security boundary against
adversarial code — vm.runInContext can be escaped via prototype-chain
tricks. For adversarial isolation, use worker-engine or spawn-engine,
both of which sit behind real OS-level boundaries. The code-transformer
is a defence-in-depth layer that catches the obvious accidents
(process.exit, require, eval, etc.); it is not a substitute for an
engine-level boundary.
Tier
Server (node:vm / node:worker_threads / node:child_process / node:crypto).
Targets Node ≥ 20 (and Bun, which provides the same APIs).