# CLI reference

`@rollbird/cli` provides the `rollbird` executable. It requires Node.js 20 or
newer and has exactly five commands: `login`, `init`, `release`, `rollback`,
and `status`.

> **Availability:** [`@rollbird/cli`](https://www.npmjs.com/package/@rollbird/cli)
> is available from the public npm registry.

## Install the CLI

Install it as a development dependency in the React Native project:

```bash
npm install --save-dev @rollbird/cli
```

A local install makes `npx rollbird` use the version pinned by the app.

## Global options

Global options go before the command.

| Option | Meaning |
| --- | --- |
| `--json` | Write exactly one machine-readable JSON result to stdout. Human progress and errors go to stderr. |
| `--api-url <url>` | Override the API URL for this invocation. It takes precedence over environment variables and saved credentials. |
| `--help` | Show command help. |

Inspect the command surface:

```bash
npx rollbird --help
```

Use a local API for one status request:

```bash
npx rollbird --api-url http://127.0.0.1:8787 status
```

## `rollbird login`

Authenticate with the device flow, or verify and save an API token for a
non-interactive environment.

```text
Usage: rollbird login [options]
```

| Option | Meaning |
| --- | --- |
| `--token <token>` | Verify this API token and skip device authorization. |
| `--org <orgId>` | Save an explicit organization id with `--token`. Normally unnecessary because the API resolves the token's organization. |

Interactive example:

```bash
npx rollbird login
```

Expected completion:

```text
✓ Confirmed  in the browser

Logged in
```

Token example:

```bash
npx rollbird login --token rb_live_REDACTED
```

Expected completion:

```text
✓ Token verified

Logged in
```

The command writes `credentials.json` with mode `0600` under
`$XDG_CONFIG_HOME/rollbird/`, or `~/.config/rollbird/` when
`XDG_CONFIG_HOME` is not set. The device code expires; exact failure text is
`Device code expired. Run rollbird login again.`

For CI, prefer the `ROLLBIRD_TOKEN` environment variable over running login.

## `rollbird init`

Detect the app, link or create its Rollbird project, provision signing, install
the SDK, wire native entry points or the Expo config plugin, embed
fingerprints, and write `rollbird.json`.

```text
Usage: rollbird init [options]
```

| Option | Default | Meaning |
| --- | --- | --- |
| `--name <name>` | `package.json` name | Name used only when a Rollbird project must be created. |
| `--channel <channel>` | `production` | Channel embedded in the native configuration. |
| `--yes` | off | Accept defaults instead of prompting. |
| `--no-install` | installs | Update `package.json` but skip the package-manager install. |
| `--ios-bundle-id <id>` | detected | Supply the iOS bundle identifier when detection fails. |
| `--android-app-id <id>` | detected | Supply the Android application id when detection fails. |

Preview-build example:

```bash
npx rollbird init --channel preview
```

Non-interactive example when identifiers and the package name cannot be
detected:

```bash
npx rollbird init --yes --name fieldkit --ios-bundle-id com.example.fieldkit --android-app-id com.example.fieldkit
```

`init` is safe to re-run. Re-run it after native code, native configuration, or
native dependencies change, then rebuild the app. A stored fingerprint matches
updates only to binaries made from that native state.

Bare projects are edited directly. Expo projects keep the channel, public key,
runtime, and per-platform fingerprints in `rollbird.json`; the
`@rollbird/react-native` config plugin restores them after every prebuild.

`init` refuses to continue when `expo-updates` is installed. It also refuses a
bare app with neither `ios/` nor `android/`, or an Expo CNG app with no Expo
config file in which to register the plugin.

## `rollbird release`

Build, sign, upload, and publish an OTA release.

```text
Usage: rollbird release [options]
```

| Option | Default | Meaning |
| --- | --- | --- |
| `--production` | off | Publish to `production`; shorthand for `--channel production`. |
| `--channel <name>` | `preview` | Publish to this release channel. |
| `--rollout <percent>` | `100` | Staged rollout percentage from 1 through 100. |
| `--message <text>` | none | Attach a release message. |
| `--force` | off | Mark the update `shouldForceUpdate`. The SDK reloads after download by default. |
| `--platform <platform>` | detected platforms | Build only `ios` or `android`. |
| `--target-app-version <version>` | none | Target an app version when the app uses the `appVersion` strategy. |
| `--yes` | off | Skip the interactive production confirmation. |

Publish a preview release to both detected platforms:

```bash
npx rollbird release --message "Fix offline sign-in"
```

Expected completion:

```text
✓ Bundled iOS  977 KB
✓ Bundled Android  980 KB
✓ Signed  2 bundles
✓ Uploaded  1.9 MB
✓ Published  Release #7 · 100% rollout

Live in preview
```

Publish a staged iOS production release without prompting:

```bash
npx rollbird release --production --platform ios --rollout 10 --message "Fix checkout" --yes
```

Publish an update for builds using `strategy: "appVersion"`:

```bash
npx rollbird release --channel production --target-app-version 2.4.0 --yes
```

Rollout must be an integer from 1 through 100. Platform must be exactly `ios`
or `android`. A release to a channel different from the channel stored in
`rollbird.json` succeeds but prints a warning because the current build will
not request it.

When Git metadata is available, the command attaches commit, branch, and
author. It records GitHub Actions, GitLab, Bitrise, or CircleCI when their
environment variables identify the provider.

## `rollbird rollback [number]`

Disable a release on one channel and serve the previous valid bundle. Rollback
is instant and free, never consumes release quota, and is not blocked by plan
status or storage.

```text
Usage: rollbird rollback [options] [number]
```

| Option | Default | Meaning |
| --- | --- | --- |
| `--channel <name>` | `production` | Channel to roll back. |
| `--yes` | off | Skip the confirmation prompt. |

Roll back the active production release:

```bash
npx rollbird rollback
```

Roll back release 17 on preview without prompting:

```bash
npx rollbird rollback 17 --channel preview --yes
```

Expected completion when an earlier release exists:

```text
✓ Rolled back  release #17

Now serving release #16 on preview
```

When no earlier OTA bundle remains, the app returns to its embedded bundle.
Builds made after the newly served release never move below their own embedded
bundle.

## `rollbird status`

Show the linked project, every channel's latest release, production-release
usage, storage usage, and dashboard URL.

```text
Usage: rollbird status [options]
```

Run it from the directory containing `rollbird.json`:

```bash
npx rollbird status
```

Example output:

```text
rollbird status · Fieldkit (fieldkit)

production          #7 · active · 100% rollout · 2 hours ago
preview             #8 · active · 25% rollout · 5 minutes ago

Production releases █░░ 1 / 3 · resets Oct 1
Storage             18 MB / 250 MB

Dashboard
https://app.rollbird.dev/p/fieldkit
```

Values and channels come from the current account; the example is not a
promise of plan limits. The limit source of truth is the live account response.

## JSON output

Put `--json` before the command. Success writes one JSON object to stdout;
failures use `{ "error": { ... } }` and preserve the same process exit code as
human output.

```bash
npx rollbird --json status
```

Release example:

```bash
npx rollbird --json release --production --yes
```

The success object includes `releaseId`, `number`, `channel`, `platforms`, and
per-platform `sizes`. A limited production plan may also include a `quota`
object. Do not scrape human-readable timelines; use JSON and exit codes.

## Authentication resolution

Credentials resolve in this order:

1. `ROLLBIRD_TOKEN`, with optional `ROLLBIRD_ORG` and `ROLLBIRD_API_URL`.
2. The credentials file written by `rollbird login`.

`--api-url` overrides both URL sources for one invocation. A token belongs to
one organization; `ROLLBIRD_ORG` is normally unnecessary and must match when
set.

## Exit codes

Exit codes are a public automation contract.

| Code | Meaning | Typical cases |
| --- | --- | --- |
| `0` | Success | Command completed. |
| `1` | Local or build failure | Bundler, filesystem, parser, or unexpected local exception. |
| `2` | Usage, configuration, or ordinary request failure | Missing `rollbird.json`, invalid flag, cancellation, API 4xx other than authentication or plan limits. |
| `3` | Authentication failure | Missing credentials, invalid/forbidden token, expired device code. |
| `4` | Plan or quota refusal | API HTTP 402, with upgrade metadata when supplied. |
| `5` | Network, storage, or server failure | Fetch failure, rejected upload, API 5xx. |

Example shell gate:

```bash
npx rollbird --json release --production --yes
```

Read the process status directly. Do not translate every nonzero code into a
retry: code `2` needs corrected input, code `3` needs credentials, code `4`
needs an account decision, and only code `5` is normally transient.

## Do not do this

- Do not invent a sixth command or a flag not listed here.
- Do not store a token in `rollbird.json`; it contains public project configuration only.
- Do not use `--yes` as authentication. It only skips supported confirmations or accepts init defaults.
- Do not publish to a channel the installed binary was not built to request.
- Do not treat rollback as quota-bearing. Rollback is always free and available.
