ADR 0002: Typer and Rich for the CLI¶
Status¶
Accepted — 2026-09-19
Context¶
The product surface is a command tree (fetch, video, playlist, thumb, batch, runs, template, provider, config, db) with global options (--config PATH, --data-dir PATH, --json, -v/-vv, --quiet, --no-color, --version). Humans need tables, panels, progress bars and an image preview grid; scripts need stable JSON on stdout. Business logic must not live in the CLI layer (ADR dependency rule in PLAN.md §2.2).
Decision¶
- Typer builds the command tree.
cli/app.pyis the root app; each sub-command group is its own module (cli/fetch.py,cli/thumb.py, …) registered viaapp.add_typer. Typer's default exit code2for usage errors is adopted as the project's "usage / validation" code. - Rich renders all human output through
cli/_render.pyonly: tables, panels,Progressbars, and the preview grid.--jsondisables Rich and prints one JSON document to stdout;--no-colorandNO_COLORdisable ANSI. - Rich output goes to stdout; logs go to stderr (ADR 0015). They never interleave.
- Image preview in the terminal uses
rich-pixels(block characters). Native inline-image protocols (kitty, iTerm2) are deferred; spike S10 testsrich-pixelsin Windows Terminal before Phase 5 commits to it. cli/_errors.pyis the singleThumbforgeError → exit codehandler wrapping every command (PLAN.md§7.1).cli/modules contain no business logic; they parse arguments, call a service, and render.
Consequences¶
- Every command's
--jsonshape becomes part of the public contract and is tested in Phase 1+. print()is banned outsidecli/_render.py; enforced by review and a ruff rule (T201) in Phase 0.- Shell completion comes for free from Typer (Phase 8 task).
- The preview grid quality depends on S10; if
rich-pixelsis unusable on Windows Terminal,thumb showfalls back to a table plusthumb export.
Alternatives considered¶
- argparse — rejected: no automatic help formatting for nested sub-apps, manual type coercion.
- Click directly — rejected: Typer is Click underneath and removes decorator boilerplate while keeping Click's testing utilities.
- textual TUI — rejected: the tool is batch-oriented and scriptable; a full-screen UI would fight
--json. - kitty/iTerm inline images as default preview — deferred (S10): not supported by Windows Terminal, the primary development terminal.