Virtual Infrastructure (Sandboxing)
VirtualFs and VirtualComputer are noumen's sandboxing primitives — the isolation boundary between the agent and the outside world.
VirtualFs and VirtualComputer are noumen's sandboxing primitives. Every file read/write and every shell command the agent executes is routed through these two interfaces — built-in tools never touch node:fs or child_process directly. The isolation level of your agent is determined entirely by which implementations you provide.
This is your security boundary
Swapping LocalFs / LocalComputer for SpritesFs / SpritesComputer (or any custom implementation) is all it takes to move from unsandboxed local execution to a fully isolated remote container. The agent code, tools, and prompts stay exactly the same.
VirtualFs — filesystem sandbox
The filesystem interface that all file tools (ReadFile, WriteFile, EditFile) delegate to:
interface VirtualFs {
readFile(path: string, opts?: ReadOptions): Promise<string>;
writeFile(path: string, content: string): Promise<void>;
appendFile(path: string, content: string): Promise<void>;
deleteFile(path: string, opts?: { recursive?: boolean }): Promise<void>;
mkdir(path: string, opts?: { recursive?: boolean }): Promise<void>;
readdir(path: string, opts?: { recursive?: boolean }): Promise<FileEntry[]>;
exists(path: string): Promise<boolean>;
stat(path: string): Promise<FileStat>;
}VirtualComputer — shell execution sandbox
The shell execution interface that all command tools (Bash, Glob, Grep) delegate to:
interface VirtualComputer {
executeCommand(command: string, opts?: ExecOptions): Promise<CommandResult>;
}Where ExecOptions supports cwd, timeout, and env, and CommandResult returns exitCode, stdout, and stderr.
Built-in implementations
Local (Node.js) — no isolation
For local development and trusted environments. Commands and file operations run directly on the host machine:
import { LocalFs, LocalComputer } from "noumen";
const fs = new LocalFs({ basePath: "/my/project" });
const computer = new LocalComputer({ defaultCwd: "/my/project" });LocalFs uses node:fs/promises under the hood. Paths resolve relative to basePath.
LocalComputer uses node:child_process.exec with a configurable default working directory, timeout, and maximum output buffer size.
No isolation
LocalFs and LocalComputer provide no sandboxing. The agent can access anything the host process can. Use these for development, or in environments where you trust the agent and the prompts.
LocalFs options
| Option | Type | Default | Description |
|---|---|---|---|
basePath | string | required | Root directory for all file operations |
LocalComputer options
| Option | Type | Default | Description |
|---|---|---|---|
defaultCwd | string | required | Default working directory for commands |
timeout | number | 30000 | Command timeout in milliseconds |
maxBuffer | number | 10 * 1024 * 1024 | Maximum stdout/stderr buffer size |
sprites.dev — full sandbox
For production and untrusted agents. All file and shell operations execute inside a remote sprites.dev container over HTTPS. The agent has zero access to the host machine's filesystem, processes, or network:
import { SpritesFs, SpritesComputer } from "noumen";
const fs = new SpritesFs({
token: process.env.SPRITE_TOKEN!,
spriteName: "my-sprite",
});
const computer = new SpritesComputer({
token: process.env.SPRITE_TOKEN!,
spriteName: "my-sprite",
});SpritesFs options
| Option | Type | Description |
|---|---|---|
token | string | sprites.dev API token |
spriteName | string | Name of the sprite container |
baseURL | string | API base URL (optional) |
SpritesComputer options
| Option | Type | Description |
|---|---|---|
token | string | sprites.dev API token |
spriteName | string | Name of the sprite container |
baseURL | string | API base URL (optional) |
Custom sandbox implementations
Implement VirtualFs and VirtualComputer to target any execution environment — Docker, E2B, Daytona, cloud VMs, or an in-memory test harness. The interfaces are intentionally minimal (one method for shell, eight for filesystem) so adapters are straightforward to write.
import type { VirtualComputer, CommandResult, ExecOptions } from "noumen";
class DockerComputer implements VirtualComputer {
constructor(private containerId: string) {}
async executeCommand(command: string, opts?: ExecOptions): Promise<CommandResult> {
// docker exec ${this.containerId} bash -c "${command}"
// ... your implementation here
}
}Any object that satisfies the interface works — no base classes, no registration, no framework lock-in.