# Configuration (/sling-cli/configuration)



## Environment variables

`sling` is configured entirely through the environment — there are no config files beyond the credential it writes at `~/.config/sling/credentials`.

| Variable     | Meaning                 |
| ------------ | ----------------------- |
| `SLING_HOST` | Control-plane base URL. |

### `SLING_HOST`

Env-only by design — there is no `--host` flag. It must be `https://` (or `http://` on a loopback development host) so the token never travels in cleartext.

## How agents authenticate

**On your own machine, an agent needs nothing extra.** [`sling login`](/sling-cli/commands/auth#sling-login) writes the session to `~/.config/sling/credentials` for your user, so any agent running as you picks it up. Sign in once and the agent is authenticated.

See [API credentials](/api/credentials) for the credentials the control plane accepts and the scopes each endpoint needs.

## Context resolution

`sling` resolves the org and repo it is acting on so that in-repo invocations need zero addressing:

* **Org** is auto-resolved when unambiguous, overridable with `--org <slug>`, and persisted as a default by [`sling org switch`](/sling-cli/commands/auth#sling-org-switch). Multi-org accounts do not pay a flag tax on every call.
* **Repo** is detected from the git remote of the current directory, overridable with `--repo <owner/name>`.

<Callout type="info">
  This is a CLI convenience. The HTTP API never infers either — [`org` is a required parameter](/api/credentials#org-scoping) on every org-scoped endpoint.
</Callout>

## Global flags

Available on the root command and every subcommand.

| Flag                  | Meaning                                                                                |
| --------------------- | -------------------------------------------------------------------------------------- |
| `--org <slug>`        | Org context. Auto-resolved when unambiguous; persisted default via `sling org switch`. |
| `--repo <owner/name>` | Repo context. Defaults to the git remote detected in the current directory.            |
| `--version`, `-v`     | Print the version and exit.                                                            |
| `--help`, `-h`        | Show help. An unknown command still fails, so a typo does not read as help.            |

Machine mode is one switch with individually available parts:

| Flag      | Meaning                                                                             |
| --------- | ----------------------------------------------------------------------------------- |
| `--agent` | Machine mode. Exactly equivalent to `--json --compact --no-input --no-color --yes`. |
| `--json`  | JSON output on stdout.                                                              |
| `--yes`   | Assume "yes" for confirmations.                                                     |

## Output streams

**stdout carries data only.** Human chrome — summary rows, spinners, prompts — goes to **stderr**, and only when stderr is a TTY. A failed command writes nothing to stdout at all.

That is what makes `sling usage --json | jq` safe to pipe unconditionally: on failure `jq` receives empty input rather than half a table.

JSON casing is `snake_case` and frozen. The control-plane response is passed through **verbatim** inside a small local envelope recording what the CLI resolved, so the API schema stays the one contract and your transcripts still capture client context.

[`sling logs`](/sling-cli/commands/inspect#sling-logs) is the deliberate exception — it streams raw log lines to stdout in both modes, so `| head` and `| less` behave as you would expect, exiting cleanly when the pipe closes early.

## Exit codes

Every command exits from one table, so a script or agent can branch on `$?` without parsing output.

| Code | Meaning                                                                                             |
| ---- | --------------------------------------------------------------------------------------------------- |
| `0`  | Success.                                                                                            |
| `1`  | Unexpected CLI or internal error — reserved for a crash, never a mapped API outcome.                |
| `2`  | Usage — bad flags, a prompt refused under `--no-input` or `--agent`, or org ambiguity.              |
| `3`  | Not found — a resolved id has no such run or job in this org.                                       |
| `4`  | Auth — missing, expired, or under-scoped credential. The message includes `sling login`.            |
| `5`  | Control-plane or API error — a `5xx`, or a transport failure.                                       |
| `6`  | Partial — telemetry incomplete; the result is still emitted. Used by `sling time` and `sling why`.  |
| `7`  | Rate limited — the control plane returned HTTP `429`.                                               |
| `10` | Remote outcome failed — `sling doctor` unhealthy, or `sling runs show --wait` on a non-success run. |

Codes `3`, `4`, `5`, and `7` are mapped by a shared error handler, so any command can surface them. See [API errors](/api/errors) for the HTTP responses behind each.

<Callout type="info">
  Exit `10` is not an error. It means the command succeeded and the *answer* was a failure — which is exactly what lets `sling runs show --wait` gate a pipeline on a run's conclusion.
</Callout>

Read a command's exit code with `$?` immediately after it, since the next command overwrites it:

```console
$ sling doctor; echo $?
10   # 0 = healthy, 10 = unhealthy
```
