# zenmux-usage Terminal CLI for checking ZenMux subscription usage across one or more accounts. Shows the 5-hour, 7-day, and monthly quota windows plus the USD value of tokens consumed. Single static Go binary, no runtime dependencies. ## Install ``` go install github.com/kotoyuuko/zenmux-usage-cli/cmd/zenmux-usage@latest ``` Or build from a checkout: ``` make build # produces ./zenmux-usage make cross # cross-compiles to dist/ for darwin/linux/windows ``` ## Configure Copy the example config and add your ZenMux Management API keys (standard keys are rejected by the API — use a Management key): ``` mkdir -p ~/.config/zenmux-usage cp config.example.yaml ~/.config/zenmux-usage/config.yaml chmod 600 ~/.config/zenmux-usage/config.yaml ``` The CLI prints a stderr warning if the file has any group- or world-readable bits set. Keys are plaintext, so keep the file at `0600`. ### Schema ```yaml accounts: - name: personal api_key: sk-zm-... - name: work api_key: sk-zm-... ``` - `accounts` (required): list of one or more entries. - `name` (required): unique identifier used as the section header in output and as the `--account` flag value. - `api_key` (required): ZenMux Management API key. - Unknown fields are ignored with a one-line stderr warning. ### Alternative paths - `--config ` overrides the default location. - `$XDG_CONFIG_HOME/zenmux-usage/config.yaml` is honored when that env var is set. - Falls back to `~/.config/zenmux-usage/config.yaml`. ### Zero-config fallback If no config file exists and `ZENMUX_MANAGEMENT_API_KEY` is set, the CLI runs in single-account mode (the account is labeled `env` in output). ## Usage ``` zenmux-usage # render all configured accounts zenmux-usage --account work # render one account from the config zenmux-usage --json # machine-readable output zenmux-usage --api-key sk-... # one-shot; ignore config file zenmux-usage --config ./c.yaml # explicit config path zenmux-usage --no-color # strip ANSI zenmux-usage --timeout 5s # HTTP timeout per account ``` ### Example output ``` ━━━ personal ━━━ ZenMux Subscription — Ultra plan ($200/mo) · healthy · $0.03283/flow 5 hour [██░░░░░░░░░░░░░░░░░░░░░░░░░░░░] 7.15% 57.2 / 800 flows $1.88 / $26.26 7 day [██░░░░░░░░░░░░░░░░░░░░░░░░░░░░] 6.73% 416.11 / 6182 flows $13.66 / $202.95 Tokens consumed (estimated USD value): $13.66 Monthly cap: 34560 flows · $1134.33 Next reset: 5h → 2026-04-22 22:05 · 7d → 2026-04-28 08:00 ━━━ work ━━━ ZenMux Subscription — Pro plan ($50/mo) · healthy · $0.01000/flow ... ``` Bars are color-coded: green <60%, yellow 60–85%, red >85%. ## Flags | Flag | Default | Purpose | | --- | --- | --- | | `--account ` | — | Filter to one account from the config | | `--config ` | `$XDG_CONFIG_HOME/zenmux-usage/config.yaml` | Override config file location | | `--api-key ` | — | Use this key directly; skip the config file | | `--json` | `false` | Emit JSON on stdout instead of the human layout | | `--no-color` | `false` | Disable ANSI colors (also honors `NO_COLOR`) | | `--timeout ` | `10s` | HTTP timeout per account | | `--version` | — | Print version and exit | ## Exit codes | Code | Meaning | | --- | --- | | `0` | All fetched accounts succeeded | | `1` | Unexpected error, **or** at least one account failed while others succeeded, **or** all accounts failed with mixed causes | | `2` | Invalid flags, unexpected positional args, or unknown `--account` name | | `3` | No account resolvable (no config file, no env var, no `--api-key`) | | `4` | Every fetched account failed with HTTP 401/403 (auth rejected) | | `5` | Every fetched account failed with HTTP 422 (rate limit) | | `6` | Every fetched account failed with network error or timeout | | `7` | Config file parse or schema error | **Rule for multi-account runs:** exit codes 4, 5, and 6 only apply when *every* account failed with the *same* cause. Any mix of successes and failures — or failures with different causes — yields exit code 1. Single-account runs always get the specific code. ## JSON output `--json` emits different shapes depending on how many accounts were resolved. ### Single account When only one account is fetched (via `--account`, `--api-key`, or the env-var fallback), the output is the raw API response unchanged: ```bash zenmux-usage --api-key sk-zm-xxx --json | jq .data.plan.tier # "ultra" ``` ### Multiple accounts When two or more accounts are fetched, the output is a JSON array ordered by config position. Each entry has `account`, `success`, `data`, and `error`. Failed accounts have `data: null` and a non-empty `error`. ```bash zenmux-usage --json | jq '.[] | {account, pct: .data.quota_7_day.usage_percentage}' # {"account": "personal", "pct": 0.0673} # {"account": "work", "pct": 0.4012} ``` ```bash zenmux-usage --json | jq '.[] | select(.success == false) | .account' # "work" ``` ## Development ``` make test # run all tests make vet # go vet make lint # vet + gofmt check make cross # build binaries for all supported targets under dist/ ``` ## API Uses `GET https://zenmux.ai/api/v1/management/subscription/detail`. See . The base URL can be overridden via `ZENMUX_BASE_URL` (useful for staging or local testing).