cli-output-contractslisted
Install: claude install-skill ontech7/ollama-usage
# CLI output contracts
## Overview
Every `ollama-usage` command is consumed by a machine as well as a human: a
status bar, a `SessionStart` hook, a `jq` pipeline. **stdout is a contract;
stderr is for humans and diagnostics.** Breaking that split silently corrupts
someone's status line or JSON pipe.
Source of truth: `src/ollama_usage/cli.py`.
## The contracts
| Command | stdout | Exit code |
|---|---|---|
| `ollama-usage` / `usage` | Rich table | `0` ok · `2` no session / expired · `1` network |
| `ollama-usage --json` | `json.dumps(...)` and nothing else | same as above |
| `ollama-usage status` | exactly one line, `🦙 …` | **always `0`** |
| `ollama-usage update-check` | `{"systemMessage": "…"}` or *nothing* | always `0` |
| `ollama-usage auth` | Rich guide | `0` ok · `2` no/invalid cookie |
| `ollama-usage setup` | plain progress lines | `0` ok · `1` a write failed |
| `ollama-usage watch` | — (notifications) | runs until interrupted |
**Rules that are easy to break:**
- `status` must **never** raise and never exit non-zero. It wraps everything in
`try/except Exception` and falls back to `🦙 Unexpected Error`. A status bar
polls it constantly; a traceback there is a broken UI, not a bug report.
- `--verbose` diagnostics go to **stderr** (`typer.echo(..., err=True)`), never
stdout — otherwise `--json` stops being JSON.
- Error messages go to stderr, then `raise typer.Exit(<code>)`.
- `status` prints with `typer.echo(line, color=True)` on purpose: status lines