The JSON format a usage command prints so byre's Status tab shows a vendor's usage and limits, and how to set one. # Usage commands byre shows each vendor's (claude, codex, antigravity) usage and limits in the Status tab. By default it uses what the vendor itself reports. A usage command replaces that for one vendor: a shell command that prints the numbers in a vendor-neutral format, so byre needn't know where they come from. ## Contract - byre runs it with `$SHELL -l -c ''` in byre's own environment (no task's worktree or `$PORT`), at startup, after every turn of that vendor's agents ends, and when the command is saved. One run at a time per vendor. - It must finish within 10 seconds, print one JSON object to stdout and exit 0. On a non-zero exit, a timeout or output that doesn't parse, byre shows nothing for that vendor. - Every field is optional. Unknown fields are ignored. No field names a vendor. ```json { "updated_at": "2026-10-19T21:24:56Z", "rejected": "daily budget spent", "windows": [ { "label": "Today", "used": 150.94, "limit": 200, "unit": "usd", "resets_at": "2026-10-20T12:00:00Z", "window_seconds": 86400 }, { "label": "Rate", "used": 36, "limit": 40, "unit": "requests", "resets_in_seconds": 240 } ] } ``` | Field | Meaning | |---|---| | `updated_at` | RFC 3339 time the numbers were current; now when absent. | | `rejected` | Why the vendor is refusing work; absent while it isn't. A window whose `used` reaches its `limit` also shows the vendor as rejected. | | `windows[]` | Independent meters, shown in order. | | `label` | Short name for the meter. | | `used`, `limit` | Numbers in `unit`. A window without `limit` shows as a bare count. | | `unit` | `usd`, `tokens`, `requests` or `percent`; selects formatting. | | `resets_at` | RFC 3339 time the meter resets. | | `resets_in_seconds` | Alternative to `resets_at`, relative to `updated_at`. | | `window_seconds` | The window's length; with `resets_at`, it draws the pace bar of time elapsed against amount used. | Status shows the example as `Today $150.94 / $200.00 · 75% … in 14h 35m` and `Rate 36 / 40 requests · 90% … in 4m`. ## Setting one The human sets it in the app: Server tab, Usage commands, one field per vendor; empty uses the vendor's own reports. The same is `PUT /api/admin/usage-commands` with `{"claude": "...", "codex": "...", "antigravity": "..."}` (all three; `GET` reads them). Test a command by running it by hand and checking its output parses as above.