# Exec & sessions



[Interactive sessions](/docs/build/interactive) are the main way to work with
Cluster Build, but you can also run a single prompt non-interactively — for
scripts, CI, and quick questions — and pick up any past conversation where you left
off.

## Run a one-shot prompt [#run-a-one-shot-prompt]

`cluster exec` runs a single prompt and exits without entering the interactive UI:

```bash
cluster exec "summarize what this service does"
```

It reads from stdin too, so you can pipe context in. A positional prompt and piped
stdin are combined (positional first, then stdin, joined by a newline):

```bash
echo "fix the failing test in api_test.go" | cluster exec
git diff | cluster exec "review this change for bugs"
```

### Flags [#flags]

| Flag                  | Effect                                                                             |
| --------------------- | ---------------------------------------------------------------------------------- |
| `--model <id>` (`-m`) | Override the default model for this run only (not persisted)                       |
| `--effort <level>`    | Reasoning effort hint — `none`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max` |
| `--ephemeral`         | Don't save this run to `~/.cluster/sessions/`                                      |
| `--resume <prefix>`   | Append this turn to an existing session (see below)                                |
| `--trust-workspace`   | Trust the current directory for this run only, without saving it                   |
| `--json`              | Emit one JSON result object instead of human-readable output (see below)           |

```bash
cluster exec --model <model-id> --effort high "plan a refactor of the auth module"
```

<Callout type="info">
  `exec` can't prompt interactively, so it requires the workspace to already be
  trusted (run `cluster trust add` once, or trust it interactively with plain
  `cluster`) or the `--trust-workspace` flag for a one-off run. A trusted
  workspace runs tools with your normal OS permissions — no sandbox. For
  unattended or untrusted-input runs, prefer `--plan` to keep the run read-only.
</Callout>

### JSON output [#json-output]

Pass `--json` for a scriptable result instead of streamed, human-oriented
output. Progress and cancellation rendering are suppressed (stderr diagnostics
are still written); once the turn completes, `exec` prints a single JSON
object to stdout:

```bash
cluster exec --json "summarize what this service does"
```

```json
{
  "session_id": "a1b2c3d4e5f6",
  "model": "<model-id>",
  "text": "This service ...",
  "stopped_early": false
}
```

* `session_id` is `null` for `--ephemeral` runs.
* `text` is the assistant's response text only — reasoning and tool events
  aren't included.
* `stopped_early` is `true` if the run was interrupted (for example, by
  Ctrl-C) before the turn finished.

## Sessions [#sessions]

Every conversation — interactive or `exec` — is saved under `~/.cluster/sessions/`
unless you pass `--ephemeral`. List, inspect, and delete them:

```bash
cluster sessions ls            # newest first
cluster sessions ls --here     # only sessions started in this directory
cluster sessions show <id>     # print a session's contents
cluster sessions rm <id>       # delete a session
```

### Resume a session [#resume-a-session]

Resume by its id prefix (at least 6 hex characters). This works from any directory:

```bash
cluster --resume <id-prefix>            # resume interactively
cluster exec --resume <id-prefix> "…"   # append a one-shot turn
```

Inside an interactive session you can also run `/resume` to browse and switch
between saved sessions.

## Billing errors [#billing-errors]

If your account can't be billed for a request — a lapsed subscription, no
remaining credits, an inactive account, an outstanding balance, or a spending
limit — Cluster Build explains the denial in plain language and links to
[Billing](https://cluster.app/settings/billing), in both interactive chat and
`cluster exec`. These denials aren't retried automatically. The raw gateway
response is written to your log file for diagnostics, but never printed to the
console.

## Next steps [#next-steps]

* **[Config basics](/docs/build/config/basic)** — set a default model and
  reasoning effort so you don't have to pass flags every run.
* **[Interactive sessions](/docs/build/interactive)** — the full TUI experience.
