> ## Documentation Index
> Fetch the complete documentation index at: https://docs.declaw.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Commands

> Run, start background processes, list, kill, and interact with commands inside a Declaw sandbox using sbx.Commands.

```go theme={null}
import "github.com/declaw-ai/declaw-go"
```

`sbx.Commands` is the `*Commands` sub-object available on every `Sandbox` instance. It provides methods to run foreground commands, launch background processes, and list running processes.

## `sbx.Commands.Run()`

Run a command and block until it completes, returning stdout, stderr, and exit code.

```go theme={null}
result, err := sbx.Commands.Run(ctx, "echo hello")
fmt.Println(result.Stdout)   // "hello\n"
fmt.Println(result.ExitCode) // 0
```

If the command exits with a non-zero code, `Run` returns both the `*CommandResult` and a `*CommandExitError`. You can inspect the result even on failure:

```go theme={null}
result, err := sbx.Commands.Run(ctx, "exit 1")
if err != nil {
    var exitErr *declaw.CommandExitError
    if errors.As(err, &exitErr) {
        fmt.Println("Exit code:", exitErr.ExitCode)
        fmt.Println("Stderr:", exitErr.Stderr)
    }
}
```

<ParamField body="cmd" type="string" required>
  Shell command to execute inside the sandbox.
</ParamField>

<ParamField body="WithRunEnvs" type="map[string]string">
  Additional environment variables for this command.
</ParamField>

<ParamField body="WithUser" type="string" default="server default">
  Unix user to run the command as. Server defaults to `"user"` when not specified.
</ParamField>

<ParamField body="WithCwd" type="string">
  Working directory. Defaults to the user's home directory.
</ParamField>

<ParamField body="WithOnStdout" type="func(string)">
  Callback invoked for each line of stdout after the command completes.
</ParamField>

<ParamField body="WithOnStderr" type="func(string)">
  Callback invoked for each line of stderr after the command completes.
</ParamField>

<ParamField body="WithStdin" type="(no argument)">
  Enables stdin for the command, allowing data to be sent via `SendStdin`.
</ParamField>

<ParamField body="WithRunTimeout" type="time.Duration">
  Maximum time to wait for the command to complete.
</ParamField>

**Returns** `(*CommandResult, error)`

***

## `sbx.Commands.Start()`

Start a command in the background and return a `*CommandHandle` immediately.

```go theme={null}
handle, err := sbx.Commands.Start(ctx, "sleep 30")
fmt.Println("PID:", handle.PID)
```

<ParamField body="cmd" type="string" required>
  Shell command to execute.
</ParamField>

Options are the same as `Run()`.

**Returns** `(*CommandHandle, error)`

***

## `sbx.Commands.List()`

List all running processes in the sandbox.

```go theme={null}
procs, err := sbx.Commands.List(ctx)
for _, p := range procs {
    fmt.Println(p.PID, p.Cmd)
}
```

**Returns** `([]ProcessInfo, error)`

***

## CommandHandle

`CommandHandle` is returned by `sbx.Commands.Start()`. It provides methods to wait for or kill the process.

### `handle.Wait()`

Block until the background command completes.

```go theme={null}
handle, err := sbx.Commands.Start(ctx, "python3 script.py")
if err != nil {
    log.Fatal(err)
}

// Later, wait for it
result, err := handle.Wait(ctx)
if err != nil {
    log.Fatal(err)
}
fmt.Println(result.Stdout)
```

**Returns** `(*CommandResult, error)` — returns `*CommandExitError` on non-zero exit.

### `handle.Kill()`

Kill the process by PID.

```go theme={null}
err := handle.Kill(ctx)
```

### `handle.PID`

**Type** `int` — the process ID.

***

## `handle.SendStdin()`

Write data to the stdin of a running background process.

<Note>
  Not yet implemented. Returns an error until server-side support is available.
</Note>

```go theme={null}
err := handle.SendStdin(ctx, "hello\n")
```

<ParamField body="data" type="string" required>
  Data to write to stdin. Include `\n` for newlines.
</ParamField>

**Returns** `error`

***

## Data models

### `CommandResult`

```go theme={null}
type CommandResult struct {
    PID      int
    ExitCode int
    Stdout   string
    Stderr   string
}
```

### `ProcessInfo`

```go theme={null}
type ProcessInfo struct {
    PID   int
    Cmd   string
    IsPty bool
    Envs  map[string]string
}
```

***

## Examples

### Run with environment variables

```go theme={null}
result, err := sbx.Commands.Run(ctx, "echo $MY_SECRET",
    declaw.WithRunEnvs(map[string]string{"MY_SECRET": "s3cr3t"}),
)
```

### Run with working directory

```go theme={null}
result, err := sbx.Commands.Run(ctx, "pwd",
    declaw.WithCwd("/tmp"),
)
// result.Stdout: "/tmp\n"
```

### Capture output with callbacks

```go theme={null}
var lines []string
result, err := sbx.Commands.Run(ctx, "ls -la /tmp",
    declaw.WithOnStdout(func(line string) {
        lines = append(lines, line)
    }),
)
fmt.Printf("Captured %d lines\n", len(lines))
```

### Background process

```go theme={null}
handle, err := sbx.Commands.Start(ctx, "python3 -c \"import time; time.sleep(5); print('done')\"")
if err != nil {
    log.Fatal(err)
}

// Do other work...

result, err := handle.Wait(ctx)
fmt.Println(result.Stdout) // "done\n"
```
