Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.opencomputer.dev/llms.txt

Use this file to discover all available pages before exploring further.

Accessed via sandbox.exec.

sandbox.exec.run(command, opts?)

Run a command synchronously. HTTP API →
command
string
required
Shell command
timeout
number
default:"60"
Timeout in seconds
env
Record<string, string>
Environment variables
cwd
string
Working directory
Returns: Promise<ProcessResult>
const result = await sandbox.exec.run("npm test", { cwd: "/app" });

sandbox.exec.start(command, opts?)

Start a long-running command with streaming. HTTP API →
command
string
required
Command
args
string[]
Arguments
env
Record<string, string>
Environment variables
cwd
string
Working directory
timeout
number
Timeout in seconds
maxRunAfterDisconnect
number
Seconds to keep running after disconnect
onStdout
(data: Uint8Array) => void
Stdout callback
onStderr
(data: Uint8Array) => void
Stderr callback
onExit
(exitCode: number) => void
Exit callback
Returns: Promise<ExecSession>
const session = await sandbox.exec.start("node server.js", {
  onStdout: (data) => process.stdout.write(data),
});

sandbox.exec.background(command, opts?)

Alias for start. Same options, same return type. Use when the intent is “run this in the background and observe it” — more discoverable than start for that case.
const server = await sandbox.exec.background("npm", {
  args: ["run", "dev"],
  onStdout: (data) => process.stdout.write(data),
});

sandbox.exec.shell(opts?)

Open a stateful shell session. Subsequent .run() calls share the same bash process, so cwd, exported env vars, and shell functions persist — the ergonomics of a terminal tab. Backed by a long-running bash --noprofile --norc session. Foreground-only: concurrent .run() rejects with ShellBusyError. Use background for fire-and-forget processes.
cwd
string
Initial working directory
env
Record<string, string>
Initial environment variables
Returns: Promise<Shell>
const sh = await sandbox.exec.shell({ cwd: "/app" });

await sh.run("npm install");
await sh.run("export NODE_ENV=test");
const r = await sh.run("npm test", {
  onStdout: (b) => process.stdout.write(b),
});
console.log(r.exitCode);

await sh.close();

Shell

MemberTypeDescription
sessionIdstringUnderlying exec session ID
run(cmd, opts?)Promise<ProcessResult>Run a command, blocking until it exits
close()Promise<void>Write exit and wait for bash to terminate

ShellRunOpts

ParameterTypeDescription
onStdout(data: Uint8Array) => voidPer-call stdout callback
onStderr(data: Uint8Array) => voidPer-call stderr callback
Per-call cwd, env, and timeout are intentionally not supported in v1. Use inline shell syntax (cd /x && cmd, FOO=bar cmd) — the shell state carries across calls. Timeouts will land once we have a “signal foreground job” primitive.
Errors:
  • ShellBusyError — another run() is in flight (shell is foreground-only).
  • ShellClosedError — bash has exited (explicit close(), a command ran exit, or the session dropped).

sandbox.exec.attach(sessionId, opts?)

Reconnect to a running exec session.
sessionId
string
required
Session ID
onStdout
(data: Uint8Array) => void
Stdout callback
onStderr
(data: Uint8Array) => void
Stderr callback
onExit
(exitCode: number) => void
Exit callback
onScrollbackEnd
() => void
Scrollback replay done
Returns: Promise<ExecSession>

sandbox.exec.list()

List all exec sessions. HTTP API → Returns: Promise<ExecSessionInfo[]>

sandbox.exec.kill(sessionId, signal?)

Kill an exec session. Default signal: 9 (SIGKILL). HTTP API → Returns: Promise<void>

ExecSession

MemberTypeDescription
sessionIdstringSession ID
donePromise<number>Resolves with exit code
sendStdin(data)methodSend input (string or Uint8Array)
kill(signal?)Promise<void>Kill process
close()methodClose WebSocket

Types

interface ProcessResult {
  exitCode: number;
  stdout: string;
  stderr: string;
}
interface ExecSessionInfo {
  sessionID: string;
  sandboxID: string;
  command: string;
  args: string[];
  running: boolean;
  exitCode?: number;
  startedAt: string;
  attachedClients: number;
}