Skip to main content
Eve is a TypeScript framework for building coding agents. It runs each agent inside a sandbox, which is an isolated filesystem and shell the agent reads, writes, and executes in. Eve lets you choose where that sandbox actually runs. Box is Ascii’s cloud sandbox: a full Linux machine you create over an API, run commands in, and read and write files in. @asciidev/eve-box connects the two. It is an Eve sandbox backend that maps Eve’s filesystem and process operations onto the Box API, so your Eve agents run on real Box machines instead of your laptop.
New to both? You only need two things to follow this guide: Node.js 18+ and a Box API key. No prior Eve or Box experience required.

How it fits together

  • Eve owns your agent logic and calls a sandbox to do filesystem and shell work.
  • @asciidev/eve-box is the adapter you plug into Eve.
  • Box is the machine the work actually happens on.
your Eve agent ──> Eve sandbox API ──> @asciidev/eve-box ──> Box machine

Set it up

1

Create a Box account

Sign in at box.ascii.dev with GitHub and start the base plan, which includes a free 7-day trial. You need an account to create boxes. See the Box quickstart for the full onboarding walkthrough.
2

Get a Box API key

Create a key from the API keys tab of the Box dashboard. Keep it secret: store it in an environment variable, never in source control.
export BOX_API_KEY=box_your_real_key_here
3

Install the packages

npm install @asciidev/eve-box eve
Use a modern TypeScript config ("module": "NodeNext", "target": "ES2022", "lib": ["ES2022", "DOM"]) and "type": "module" in package.json.
4

Define the sandbox backend

Point Eve’s sandbox at Box. In an Eve project this lives in your sandbox definition file:
sandbox.ts
import { defineSandbox } from "eve/sandbox";
import { asciiBox } from "@asciidev/eve-box";

export default defineSandbox({
  backend: asciiBox({
    apiKey: process.env.BOX_API_KEY!,
    ttlSeconds: 3600, // auto-stop the Box after an hour of inactivity
  }),
});
That’s it: Eve agents in this project now run on Box.

A complete example

This standalone script creates a Box-backed sandbox session and exercises the operations Eve relies on: running commands, reading files, and writing files. It runs on its own so you can verify your setup before wiring the backend into a larger Eve agent.
hello-box.ts
import { asciiBox } from "@asciidev/eve-box";

async function main() {
  const backend = asciiBox({
    apiKey: process.env.BOX_API_KEY!,
    name: "eve-hello",
    ttlSeconds: 600,
  });

  // Create a session (this provisions a Box and waits until it is ready).
  const handle = await backend.create({
    templateKey: null,
    sessionKey: "hello-session",
    runtimeContext: { appRoot: process.cwd() },
  });
  const session = await handle.useSessionFn({ networkPolicy: "allow-all" });

  // Write a file, run a command against it, and read the result back.
  await session.writeTextFile({ path: "notes/hello.txt", content: "hello from Box\n" });
  const result = await session.run({ command: "cat notes/hello.txt && uname -a" });
  console.log("exit:", result.exitCode);
  console.log(result.stdout);

  // Paths resolve under /workspace, matching Eve's sandbox contract.
  console.log(session.resolvePath("notes/hello.txt")); // -> /workspace/notes/hello.txt
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});
BOX_API_KEY=box_... npx tsx hello-box.ts
You should see the file contents, the machine’s uname output, and exit code 0.

What the backend maps

Eve operationBox behaviour
runExecutes a bounded command in the Box work directory.
spawnStarts a background process, with streamed stdout/stderr, wait(), and kill().
readTextFile / writeTextFileReads and writes files under the Box work directory.
readBinaryFile / writeBinaryFileSame, using base64 transfer for binary content.
removePathRemoves files and directories in the workspace.
resolvePathAnchors relative paths to /workspace.
create / resumeCreates a new Box, or reconnects to one from Eve’s persisted session state.

Configuration

asciiBox(options) accepts:
OptionDefaultDescription
apiKeyprocess.env.BOX_API_KEYBox API key.
baseUrlpublic Box APIBox API base URL.
nameeve-<sessionKey>Name, or (input) => string, for boxes Eve creates.
ttlSeconds3600Auto-stop TTL in seconds. null disables auto-stop.
noEnvfalseWithhold your account’s secrets and credentials from boxes (see below).
envnonePer-box environment variables for every box Eve creates (see below).
pollMs500Poll cadence for spawn() streams and wait().
commandTimeoutMsnoneTimeout for blocking run() commands.
networkPolicynoneInitial network policy (see below).

Running agents for other people

By default a box inherits your Box account, including your secrets, secret files, GitHub-credentialed repos, and SSH identity. Fine for your own agents; if anyone else can drive the agent, set noEnv: true so they can’t read your secrets or act as you.
With noEnv: true the box starts empty and confined to itself. You then give it exactly what it needs: secrets through env, and files and setup through Eve’s onSession hook.
sandbox.ts
import { defineSandbox } from "eve/sandbox";
import { asciiBox } from "@asciidev/eve-box";

export default defineSandbox({
  backend: asciiBox({
    apiKey: process.env.BOX_API_KEY!,
    noEnv: true,
    // Scoped secrets: the only env this box gets:
    env: { MY_APP_TOKEN: process.env.MY_APP_TOKEN! },
  }),
  async onSession({ use }) {
    const sandbox = await use();
    // Seed files and run setup with the session API. These wrap Box's file
    // and command APIs, so you don't need `box scp` or `box ssh`.
    await sandbox.writeTextFile({ path: "config/app.json", content: JSON.stringify({ mode: "prod" }) });
    await sandbox.run({ command: "git clone https://github.com/acme/public-repo . && npm ci" });
  },
});
env keys merge over your account variables (per-box wins; at most 100 variables, 64 KB total; reserved Box-internal names are rejected). writeFile/readFile move bytes in and out and run/spawn execute commands as the Eve-native equivalents of box scp and box ssh <id> <cmd>. A no-env box can’t reach your private repos, so clone public ones or have the user authenticate inside the box. See No-env boxes.

Reusing a prepared environment

Setup runs when each session’s box is first created. If you want many sessions to start from the same fully prepared state, fork a box: prepare one, stop it so its snapshot completes, then fork it; each clone keeps the entire filesystem. See Fork box.

Network policies

Box does not yet enforce Eve’s fine-grained network policies. The backend accepts "allow-all" and throws EveBoxUnsupportedError for stricter policies ("deny-all", allow-lists, subnet rules), so you never get a false sense of isolation. If you need firewall-backed policies, run that Eve agent on a backend that supports them.

Resources

npm package

@asciidev/eve-box on npm.

Source on GitHub

Issues, examples, and the adapter source.

Box quickstart

Install Box and create your first sandbox.

Box API keys

Create and manage the key this adapter needs.