A box for your agents

Give an AI agent a real computer — filesystem, shell, and npm — to run its own code and commands, safely.

An AI agent that can only talk is limited; one that can run things is useful. Lifo gives an agent a real computer — a filesystem, a bash-like shell, Node, and npm — that boots instantly and is safe to hand generated commands to. It runs server-side in Node (alongside your agent) or client-side in the browser.

A minimal tool the agent can call

Expose two primitives — run a command, read/write files — and your agent has a workspace:

import { Sandbox } from "@lifo-sh/core";

const box = await Sandbox.create({ cwd: "/workspace" });

// The tool your agent calls to execute a shell command.
async function run(command: string) {
  const { stdout, stderr, exitCode } = await box.commands.run(command, {
    cwd: "/workspace",
    timeout: 30_000,
  });
  return { stdout, stderr, exitCode };
}

// File tools.
const writeFile = (path: string, content: string) => box.fs.writeFile(path, content);
const readFile = (path: string) => box.fs.readFile(path);

Now the agent can scaffold a project, install packages, run tests, and read the results — a full edit-run-observe loop:

await writeFile("/workspace/fib.js", agentGeneratedCode);
const result = await run("node fib.js");
// feed result.stdout / result.exitCode back to the model

Headless in Node (no browser needed)

Server-side, a box is just an object — perfect for an agent backend. No TTY means no interactive prompts fire unless you feed stdin, and outbound fetch works directly:

const box = await Sandbox.create(); // no terminal → headless
const { stdout } = await box.commands.run("npm init -y && npm install lodash && node -e \"console.log(require('lodash').VERSION)\"");

Give each agent (or task) its own box

Spin up a box per agent, per session, or per task, and tear it down after — they share no state:

const boxes = new Map<string, Sandbox>();
async function boxFor(sessionId: string) {
  if (!boxes.has(sessionId)) boxes.set(sessionId, await Sandbox.create());
  return boxes.get(sessionId)!;
}

Checkpoint and resume the agent's workspace

Snapshot the box between turns so an agent can pause and resume with its files intact — or branch a workspace by restoring the same image into two boxes:

const checkpoint = await box.fs.exportSnapshot(); // Uint8Array (tar.gz)
// later / elsewhere:
const resumed = await Sandbox.create();
await resumed.fs.importSnapshot(checkpoint);

Keeping it safe

The box has no access to your host by default — see Run untrusted code for timeouts, cancellation, and the isolation model. Treat agent output as untrusted and bound every run.

Next