> ## Documentation Index
> Fetch the complete documentation index at: https://opensandbox-oc-s-762ac928075c46d2828bcb22.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Exec

> Run commands and manage exec sessions

Accessed via `sandbox.exec`.

## `sandbox.exec.run(command, opts?)`

Run a command synchronously. [HTTP API →](/api-reference/exec/run)

<ParamField body="command" type="string" required>
  Shell command
</ParamField>

<ParamField body="timeout" type="number" default="60">
  Timeout in seconds
</ParamField>

<ParamField body="env" type="Record<string, string>">
  Environment variables
</ParamField>

<ParamField body="cwd" type="string">
  Working directory
</ParamField>

**Returns:** `Promise<ProcessResult>`

```typescript theme={null}
const result = await sandbox.exec.run("npm test", { cwd: "/app" });
```

***

## `sandbox.exec.start(command, opts?)`

Start a long-running command with streaming. [HTTP API →](/api-reference/exec/create-session)

<ParamField body="command" type="string" required>
  Command
</ParamField>

<ParamField body="args" type="string[]">
  Arguments
</ParamField>

<ParamField body="env" type="Record<string, string>">
  Environment variables
</ParamField>

<ParamField body="cwd" type="string">
  Working directory
</ParamField>

<ParamField body="timeout" type="number">
  Timeout in seconds
</ParamField>

<ParamField body="maxRunAfterDisconnect" type="number">
  Seconds to keep running after disconnect
</ParamField>

<ParamField body="onStdout" type="(data: Uint8Array) => void">
  Stdout callback
</ParamField>

<ParamField body="onStderr" type="(data: Uint8Array) => void">
  Stderr callback
</ParamField>

<ParamField body="onExit" type="(exitCode: number) => void">
  Exit callback
</ParamField>

**Returns:** `Promise<ExecSession>`

```typescript theme={null}
const session = await sandbox.exec.start("node server.js", {
  onStdout: (data) => process.stdout.write(data),
});
```

***

## `sandbox.exec.background(command, opts?)`

Alias for [`start`](#sandbox-exec-start-command-opts). 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.

```typescript theme={null}
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`](#sandbox-exec-background-command-opts) for fire-and-forget processes.

<ParamField body="cwd" type="string">
  Initial working directory
</ParamField>

<ParamField body="env" type="Record<string, string>">
  Initial environment variables
</ParamField>

**Returns:** `Promise<Shell>`

```typescript theme={null}
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

| Member            | Type                     | Description                                 |
| ----------------- | ------------------------ | ------------------------------------------- |
| `sessionId`       | `string`                 | Underlying 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

| Parameter  | Type                         | Description              |
| ---------- | ---------------------------- | ------------------------ |
| `onStdout` | `(data: Uint8Array) => void` | Per-call stdout callback |
| `onStderr` | `(data: Uint8Array) => void` | Per-call stderr callback |

<Note>
  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.
</Note>

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.

<ParamField body="sessionId" type="string" required>
  Session ID
</ParamField>

<ParamField body="onStdout" type="(data: Uint8Array) => void">
  Stdout callback
</ParamField>

<ParamField body="onStderr" type="(data: Uint8Array) => void">
  Stderr callback
</ParamField>

<ParamField body="onExit" type="(exitCode: number) => void">
  Exit callback
</ParamField>

<ParamField body="onScrollbackEnd" type="() => void">
  Scrollback replay done
</ParamField>

**Returns:** `Promise<ExecSession>`

***

## `sandbox.exec.list()`

List all exec sessions. [HTTP API →](/api-reference/exec/list-sessions)

**Returns:** `Promise<ExecSessionInfo[]>`

***

## `sandbox.exec.kill(sessionId, signal?)`

Kill an exec session. Default signal: `9` (SIGKILL). [HTTP API →](/api-reference/exec/kill-session)

**Returns:** `Promise<void>`

***

## ExecSession

| Member            | Type              | Description                       |
| ----------------- | ----------------- | --------------------------------- |
| `sessionId`       | `string`          | Session ID                        |
| `done`            | `Promise<number>` | Resolves with exit code           |
| `sendStdin(data)` | method            | Send input (string or Uint8Array) |
| `kill(signal?)`   | `Promise<void>`   | Kill process                      |
| `close()`         | method            | Close WebSocket                   |

***

## Types

<Accordion title="ProcessResult">
  ```typescript theme={null}
  interface ProcessResult {
    exitCode: number;
    stdout: string;
    stderr: string;
  }
  ```
</Accordion>

<Accordion title="ExecSessionInfo">
  ```typescript theme={null}
  interface ExecSessionInfo {
    sessionID: string;
    sandboxID: string;
    command: string;
    args: string[];
    running: boolean;
    exitCode?: number;
    startedAt: string;
    attachedClients: number;
  }
  ```
</Accordion>
