# Operator `admin` CLI

The panel binary is also the **platform-operator (superadmin) CLI**. The `admin`
subcommands open the panel's SQLite database **directly** — no running server is
required — so an operator can inspect accounts, list runs, and change runtime
config from the panel host.

> **Not the same as `am-cloud platform`.** This `admin` CLI is the *platform-wide*
> operator tool that talks to the panel DB on the host. The per-account
> [`am-cloud` / `platform` CLI](/docs/cli) talks to a single account over HTTP with
> that account's `AM_API_KEY`. Use `admin` to operate the platform; use `platform`
> to drive one account.

> **Agent-friendly by design.** Every `admin` command emits **JSON by default**
> with stable keys and **semantic exit codes**, and is fully non-interactive. Add
> `--human` for readable text.

## Form

```bash
automaintainer-saas-panel admin [--human] <group> <subcommand> [args…]
```

`--human` switches every command from JSON to readable text; place it right after
`admin`. The DB path is `~/.automaintainer-saas/panel.db` (created on first boot).

> **Secrets are never printed.** `user show` reports only the *presence* of an
> account's `github_token` / `api_key` (`has_github_token`, `has_api_key`) — the
> values themselves never reach a terminal or log.

## Command surface

```text
# Runtime config (SQLite-backed key/value overrides)
admin [--human] env get <key>              # read one override (env/default fallback)
admin [--human] env set <key> <value>      # write a runtime override
admin [--human] env unset <key>            # remove an override
admin [--human] env list                   # list only the active DB overrides
admin [--human] env show                   # every known key: source · default · value

# Cross-account operator views (read-only)
admin [--human] user list                  # all users + repo counts
admin [--human] user show <id|email>       # one user + their repos (+ secret presence)
admin [--human] repo list [--user <id>]    # all repos, optionally filtered by user
admin [--human] run  list [--user <id>] [--repo <id>] [--limit N]   # recent runs (default 50)
admin [--human] run  show <run-id>         # one run: status, verify, branch, PR, diff

# Maintenance
admin encrypt-secrets                      # backfill at-rest encryption once SECRETS_KEY is set
```

`env` reads/writes the SQLite-backed override store described in
[Environment variables](/docs/environment-variables); `env show` lists every
override-capable key with its current **source** (`db` › `env` › `default`),
whether it hot-swaps, and its description.

## JSON contract

Success prints JSON to **stdout** and exits `0`:

```bash
am admin env show
#   → {"configs":[{"key":"legal_email","source":"default","hot_swap":true,"value":"…",…}]}

am admin user show 42
#   → {"user":{"id":42,"email":"…","plan":"pro","has_api_key":true,…},"repos":[…]}

am admin run show run-abc123
#   → {"id":"run-abc123","status":"success","verify_status":"passed","pr_url":"https://…",…}
```

Errors print a structured object to **stderr** and exit non-zero:

```json
{"error":{"code":84,"type":"not_found","message":"user not found: 999"}}
```

In `--human` mode the same commands print aligned text, and errors print just the
plain `message` line to stderr.

## Exit codes

Codes are grouped into semantic ranges so an orchestrating agent can branch on the
class of failure without scraping text:

| Code | Meaning | When |
|---|---|---|
| `0` | Success | Command completed. |
| `82` | `invalid_argument` | Missing/extra args, unknown subcommand, non-numeric `--user`. |
| `84` | `not_found` | No matching user or run. |
| `100` | `database_error` | Could not open or query the panel DB. |
| `1` | Usage | No command given, or an unknown **top-level** command (prints help). |

The ranges are stable: `0` success, `80–99` user errors, `100–119` software
errors. New codes stay within their range.

## Help

```bash
automaintainer-saas-panel help        # or --help, -h
automaintainer-saas-panel admin       # prints the admin usage line on no subcommand
```

`help` / `--help` / `-h` print the full usage for every command (start, stop,
status, version, and the `admin` groups). Running a group with no subcommand
(e.g. `admin env`) prints that group's `usage:` line and exits `82`.

## Examples

```bash
# Treat the long binary name as `am` for brevity
alias am='automaintainer-saas-panel'

# Who is on the platform, and which accounts hold provider secrets?
am --human user list
am --human user show ops@example.com      # has_api_key / has_github_token flags

# What ran recently for one user, and why did a run end the way it did?
am --human run list --user 42 --limit 20
am --human run show run-abc123

# Flip a hot-swappable setting without a restart, then confirm the source
am env set alert_webhook_url https://hooks.example.com/abc
am --human env show                       # alert_webhook_url now source=db

# Backfill encryption after configuring SECRETS_KEY on an existing DB
am admin encrypt-secrets
```

Because output is JSON with exit codes, a script can branch on `status`,
`verify_status`, `has_api_key`, or the error `code`/`type` directly.

## Related

- [`am-cloud` / `platform` CLI](/docs/cli) — the per-account control CLI
- [Environment variables](/docs/environment-variables) — the keys `admin env` overrides
- [Security & data](/docs/security) · [API reference](/docs/api)
