Two modes: exec.run() waits for the result, exec.start() creates a session for long-running or streaming commands.
import { Sandbox } from "@opencomputer/sdk";
const sandbox = await Sandbox.create();
const result = await sandbox.exec.run("echo Hello, World!");
console.log(result.stdout); // "Hello, World!\n"
await sandbox.kill();
Quick Commands: exec.run()
Run a shell command and wait for the result. The command runs via sh -c, so pipes, redirects, and shell expansion work.
// Working directory and environment variables
const result = await sandbox.exec.run("npm run build", {
cwd: "/app",
env: { NODE_ENV: "production" },
timeout: 120,
});
if (result.exitCode !== 0) {
console.error("Build failed:", result.stderr);
}
Parameters
| Parameter | Type | Default | Description |
|---|
command | string | — | Shell command to run (required) |
timeout | number | 60 | Timeout in seconds |
env | object | — | Environment variables |
cwd | string | — | Working directory |
ProcessResult
| Field | TypeScript | Python | Type |
|---|
| Exit code | exitCode | exit_code | number |
| Standard output | stdout | stdout | string |
| Standard error | stderr | stderr | string |
Async Commands: exec.start()
Start a command as an exec session for long-running processes or streaming output. The TypeScript and Python SDKs differ significantly here.
TypeScript — Full Streaming
Returns an ExecSession with callbacks for stdout, stderr, and exit:
const session = await sandbox.exec.start("node server.js", {
cwd: "/app",
env: { PORT: "3000" },
onStdout: (data) => process.stdout.write(data),
onStderr: (data) => process.stderr.write(data),
onExit: (code) => console.log("Server exited:", code),
maxRunAfterDisconnect: 300, // keep running 5min after disconnect
});
// Send input
session.sendStdin("some input\n");
// Wait for completion (or kill)
await session.kill();
ExecStartOpts
| Parameter | Type | Description |
|---|
args | string[] | Command arguments |
env | object | Environment variables |
cwd | string | Working directory |
timeout | number | Timeout in seconds |
maxRunAfterDisconnect | number | Seconds to keep running after disconnect |
onStdout | callback | (data: Uint8Array) => void |
onStderr | callback | (data: Uint8Array) => void |
onExit | callback | (exitCode: number) => void |
ExecSession
| Member | Type | Description |
|---|
sessionId | string | Session ID |
done | Promise<number> | Resolves with exit code |
sendStdin(data) | method | Send input to the process |
kill(signal?) | method | Kill the process (default: SIGKILL) |
close() | method | Close the WebSocket connection |
Python — Session ID
Python’s exec.start() returns a session ID string. There are no streaming callbacks or ExecSession object.
session_id = await sandbox.exec.start(
"node server.js",
args=None,
env={"PORT": "3000"},
cwd="/app",
)
# Check session status
sessions = await sandbox.exec.list()
for s in sessions:
print(s.session_id, "running" if s.running else f"exited ({s.exit_code})")
# Kill when done
await sandbox.exec.kill(session_id)
Python does not support exec.attach(), streaming callbacks, maxRunAfterDisconnect, or the ExecSession object. For streaming in Python, use the WebSocket binary protocol directly.
Managing Sessions
List Sessions
const sessions = await sandbox.exec.list();
for (const s of sessions) {
console.log(s.sessionID, s.running ? "running" : `exited (${s.exitCode})`);
console.log(` command: ${s.command}, clients: ${s.attachedClients}`);
}
Attach to Running Session (TypeScript only)
Reconnect to a running exec session to resume streaming output:
const session = await sandbox.exec.attach(sessionId, {
onStdout: (data) => process.stdout.write(data),
onStderr: (data) => process.stderr.write(data),
onExit: (code) => console.log("Exited:", code),
onScrollbackEnd: () => console.log("--- live output ---"),
});
On attach, the server replays the scrollback buffer (historical output), sends a scrollback-end marker, then streams live output.
Kill a Session
await sandbox.exec.kill(sessionId);
await sandbox.exec.kill(sessionId, 15); // SIGTERM
sandbox.commands is a deprecated alias for sandbox.exec. Use sandbox.exec in all new code.