CLI Harness (fidelity)
The fidelity layer standardizes a common CLI UI spectrum:
- STATIC: print once and exit (scrolls away)
- LIVE: in-place updates with cursor control
- INTERACTIVE: a full TUI loop (alt screen + keyboard input)
It also standardizes:
- Zoom (
-q,-v,-vv) as “detail level” - Format (
--plain,--json) as “serialization”
See also:
CLAUDE.md: current API reference (../../CLAUDE.md)
Core types
class Zoom(IntEnum):
"""Detail level for rendering."""
MINIMAL = 0 # One-liner, counts only
SUMMARY = 1 # Key information, tree structure
DETAILED = 2 # Everything visible, nested expansion
FULL = 3 # All fields, full depth
class OutputMode(Enum):
"""Delivery mechanism."""
AUTO = "auto" # Detect from TTY/pipe
STATIC = "static" # print_block, scrolls away
LIVE = "live" # InPlaceRenderer, cursor control
INTERACTIVE = "interactive" # Surface, alt screen
class Format(Enum):
"""Serialization format."""
AUTO = "auto" # Detect from TTY
ANSI = "ansi" # Styled terminal output
PLAIN = "plain" # No escape codes
JSON = "json" # Machine-readable
@dataclass(frozen=True)
class CliContext:
"""Resolved runtime context."""
zoom: Zoom
mode: OutputMode # Resolved (never AUTO)
format: Format # Resolved (never AUTO)
is_tty: bool
width: int
height: int
Entry point
run_cli() is the intended “one call” entry point.
def run_cli(
args: list[str],
render: Callable[[CliContext, T], "Block"],
fetch: Callable[[], T],
*,
fetch_stream: Callable[[], "AsyncIterator[T]"] | None = None,
handlers: dict[OutputMode, Callable[[CliContext], R]] | None = None,
default_zoom: Zoom = Zoom.SUMMARY,
description: str | None = None,
prog: str | None = None,
add_args: Callable[[argparse.ArgumentParser], None] | None = None,
) -> int:
Pattern: state → Block, decoupled from I/O
The harness keeps a strict separation:
- your code owns state fetching (
fetch/fetch_stream) - your code owns rendering (
render(ctx, state) -> Block) - painted owns delivery (static/live/interactive formatting and terminal behavior)
Demo output (fidelity.py)
Zoom.MINIMAL
67% used (134.0G/200.0G)
Zoom.DETAILED
╭─ Disk: /home ─────────────────────────────────────────╮ │ 67.0% ████████████████████░░░░░░░░░░ 134.0G/200.0G │ ╰───────────────────────────────────────────────────────╯ ╭─ By Directory ────────────────────────────────────────╮ │ 45.0G ▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░░░░░░░░░░░ 33.6% projects │ │ 28.0G ▓▓▓▓▓▓░░░░░░░░░░░░░░░░░░░░░░░░ 20.9% downloads│ │ 22.0G ▓▓▓▓░░░░░░░░░░░░░░░░░░░░░░░░░░ 16.4% .cache │ │ 18.0G ▓▓▓▓░░░░░░░░░░░░░░░░░░░░░░░░░░ 13.4% documents│ │ 12.0G ▓▓░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 9.0% pictures │ │ 9.0G ▓▓░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 6.7% .local │ ╰───────────────────────────────────────────────────────╯ Free: 66.0G