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

# CLI

> Drive Roark from your terminal and your CI pipeline

### Overview

`roark` is the official command line interface for the Roark API. It covers the same surface as the [Node.js](/documentation/sdks/node-sdk) and [Python](/documentation/sdks/python-sdk) SDKs (calls, metrics, personas, customer flows, simulations, webhooks) and adds the two commands that make [Config as Code](/documentation/config-as-code/overview) practical: `roark config diff` and `roark config apply`.

It prints JSON, so it composes with `jq` and with everything else in a pipeline, and it uses distinct [exit codes](#exit-codes), so a CI job can tell a rejected request apart from a missing credential.

***

### Install

<Tabs>
  <Tab title="Install script (recommended)">
    **macOS, Linux, WSL:**

    ```bash theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
    curl -fsSL https://roark.ai/install.sh | sh
    ```

    This installs into `~/.roark` and links `roark` into `~/.local/bin`. Nothing is written outside your home directory, and no step needs `sudo`.

    Pin a version, or remove the CLI entirely:

    ```bash theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
    curl -fsSL https://roark.ai/install.sh | sh -s -- --version 0.1.1
    curl -fsSL https://roark.ai/install.sh | sh -s -- --uninstall
    ```

    <Info>
      Re-run the install command to upgrade. It replaces the installed version in place and prunes the old one.
    </Info>
  </Tab>

  <Tab title="Homebrew">
    ```bash theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
    brew tap roarkhq/tap
    brew trust roarkhq/tap
    brew install roark
    ```

    The `brew trust` step is not optional. Homebrew refuses to load a formula from a third-party tap until it is trusted, and without it `brew install` stops with `Refusing to load formula roarkhq/tap/roark from untrusted tap`. To trust just this formula rather than the whole tap, use `brew trust --formula roarkhq/tap/roark`.

    In a `Brewfile`:

    ```ruby theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
    tap "roarkhq/tap"
    brew "roark"
    ```

    <Info>
      Homebrew installs do not auto-update. Run `brew upgrade roark` to move to the latest version.
    </Info>
  </Tab>

  <Tab title="npm">
    ```bash theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
    npm install -g @roarkanalytics/cli
    ```

    Or run it without installing anything, which is often what you want in CI:

    ```bash theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
    npx -y @roarkanalytics/cli@latest --help
    ```

    <Warning>
      A global npm install writes into npm's configured prefix, which on many systems is root-owned and fails with `EACCES`. If you hit that, use the install script instead of reaching for `sudo`.
    </Warning>
  </Tab>
</Tabs>

Confirm the install worked:

```bash theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
roark --version
```

<Note>
  The CLI needs **Node.js 20 or newer**. Every install method above uses your existing Node; none of them bundle a runtime.
</Note>

If `~/.local/bin` is not on your `PATH`, the install script tells you the line to add. Man pages ship with the CLI. Add `~/.roark/share/man` to `MANPATH` and `man roark` works.

***

### Authenticate

Interactively, `roark auth login` opens your browser to approve access, then stores the key it mints, scoped to the project and the permissions you approve, and revocable any time under **Settings → API keys**:

```bash theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
roark auth login          # opens the browser to approve, stores the minted key (mode 0600)
roark auth login --paste  # skip the browser: paste or pipe a token instead
roark auth status         # shows which credential is in effect, and where it came from
roark auth logout         # deletes the stored credential
```

In **CI there is no browser**, so authenticate with a token instead. Generate one from [API Keys](/documentation/getting-started/api-keys) and set the environment variable the CLI and SDKs both read, no `login` step needed:

```bash theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
export ROARK_API_BEARER_TOKEN="your-api-key"
```

You can also pass `--token <value>` on any command, or pipe a token into login (`echo "$ROARK_API_BEARER_TOKEN" | roark auth login`). See [Using the CLI in CI](#using-the-cli-in-ci) for a full GitHub Actions example.

Settings resolve highest precedence first: a flag, then the environment variable, then a project `.roark.json` found by walking up from the working directory, then the user config file. `roark config path` prints where each of those lives.

<Warning>
  A `.roark.json` arrives with a clone rather than being something you wrote, so if a project file sets `baseURL`, the CLI refuses to send a stored or environment credential to it. Read the file, then pass `--allow-project-base-url` (or set `ROARK_ALLOW_PROJECT_BASE_URL`) to opt in, or pass `--token` to send a different credential.
</Warning>

***

### Usage

Commands read noun before verb, and the verb is `list`, `get`, `create`, `update` or `delete` unless the operation is genuinely something else:

```bash theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
roark call list --limit 5
roark call get <call-id>
roark simulation plan job start <plan-id>
```

`roark <command> --help` prints the flags for any command, and `roark --help` lists the command tree.

#### Output

JSON on stdout (indented and coloured for a terminal, compact when piped) so the same command works in both places. Errors go to stderr, so `> out.json` captures only real output.

```bash theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
roark call list --limit 5 | jq '.data[].id'
roark call get <call-id> --format plain
```

#### Request bodies

Flags cover the common case, and nested objects go one level deep with dots. A whole payload can be supplied as JSON, with flags overriding what it contains:

```bash theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
roark webhook create --url https://example.com/hook --events CALL_ANALYSIS_COMPLETED
roark customer-flow create --data @flow.json
cat flow.json | roark customer-flow create
```

#### Any endpoint

Endpoints without a generated command are still reachable:

```bash theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
roark api get /v1/call --query limit=5
roark api post /v1/webhook --data '{"url":"https://example.com","events":["CALL_ANALYSIS_COMPLETED"]}'
```

#### Shell completion

```bash theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
eval "$(roark completion bash)"
eval "$(roark completion zsh)"
roark completion fish | source
```

***

### Config as Code

The CLI is the intended way to run [Config as Code](/documentation/config-as-code/overview). Point it at a directory of YAML resources. It bundles them, resolves any `file://` prompt references, and submits the result:

<Steps>
  <Step title="Preview the changes">
    ```bash theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
    roark config diff ./roark
    ```

    Prints the `create`, `update` and `delete` operations that would run. Nothing is written.
  </Step>

  <Step title="Apply">
    ```bash theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
    roark config apply ./roark
    ```

    Shows the same preview, then asks for confirmation before reconciling. Pass `-y` to skip the prompt in CI, and `--no-prune` for an additive-only apply that leaves removed resources alone.
  </Step>
</Steps>

<Note>
  These commands need an API key carrying the **`config:apply`** permission. See [Config as Code](/documentation/config-as-code/overview) for the resource kinds and apply semantics.
</Note>

***

### Using the CLI in CI

CI runs headless, so skip `auth login` and authenticate with a token in the environment. Store an API key as a secret (`ROARK_API_KEY`) and export it as `ROARK_API_BEARER_TOKEN`; every command picks it up with no interactive step.

The common setup is a two-stage GitHub Actions workflow: **diff on every pull request** so a reviewer sees what would change, and **apply on merge to `main`**.

```yaml GitHub Actions theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
name: roark-config
on:
  pull_request:
    paths: ['roark/**']
  push:
    branches: [main]
    paths: ['roark/**']

jobs:
  config:
    runs-on: ubuntu-latest
    env:
      # An API key with the config:apply permission, stored as a repo secret.
      ROARK_API_BEARER_TOKEN: ${{ secrets.ROARK_API_KEY }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20

      # Preview on PRs: no writes, and the log shows exactly what would change.
      - name: Diff
        if: github.event_name == 'pull_request'
        run: npx @roarkanalytics/cli config diff ./roark

      # Reconcile on merge. -y skips the confirmation prompt.
      - name: Apply
        if: github.ref == 'refs/heads/main'
        run: npx @roarkanalytics/cli config apply ./roark -y
```

`config diff` exits non-zero if the request is rejected (see [exit codes](#exit-codes) below), so a broken bundle fails the PR check rather than slipping through. Use `--no-prune` on apply if you want additive-only syncs that never delete resources removed from the repo.

***

### Exit codes

Distinct codes so a CI job can branch on the failure rather than grepping stderr.

| Code | Meaning                                                    |
| :--- | :--------------------------------------------------------- |
| 0    | Success                                                    |
| 1    | The API rejected the request                               |
| 2    | The command line was wrong                                 |
| 3    | No credential, or the credential was refused               |
| 4    | The addressed resource does not exist                      |
| 5    | The request never completed: connection, timeout, or abort |

***

### Additional Resources

<CardGroup cols={2}>
  <Card title="NPM Package" icon="npm" href="https://www.npmjs.com/package/@roarkanalytics/cli">
    View package details on npm
  </Card>

  <Card title="Homebrew Tap" icon="beer" href="https://github.com/roarkhq/homebrew-tap">
    Formula source and release notes
  </Card>

  <Card title="Config as Code" icon="file-code" href="/documentation/config-as-code/overview">
    Define agents, personas, flows and metrics as YAML
  </Card>

  <Card title="API Reference" icon="book-open" href="/api-reference/introduction">
    Explore the full API documentation
  </Card>
</CardGroup>
