Repository navigation
0.7.0
cliffy's first release since 0.6.1. Full details are in the changelog and the migration notes.
Highlights
- Python 3.11 to 3.15. 3.9 and 3.10 are no longer supported.
- Build targets.
cli build --target zipapp|script|native: the shiv zipapp as before, a single-file script with inline dependencies (PEP 723, runs withuv run), or one native binary built with PyApp that needs nothing installed on the target machine. Built CLIs do not depend on cliffy. - Blueprints. Define your own typed YAML spec and map it to a CLI;
load,run,render,test,docsandbuildall work on spec files. Blueprints can be local files,module:Classreferences or installed plugins. - Callbacks on the CLI and on groups, for both backends.
- Shell lines on pybash 0.4.
&&,||,;, pipes, redirects,$(command)capture, any expression in{{ }}, and injection-safe interpolation in>shell lines. - Errors point at the manifest. A mistake in a run block is reported with file, command, line and column, with no traceback.
cli validatecompiles and imports the generated code. - AI commands ported to pydantic-ai 2.x with provider-agnostic model selection and validated output.
- Click backend parity with Typer for params,
typesandconfig. - Reproducible output. Generated code no longer carries a timestamp; examples appear in the generated CLI's
--help. - Docs rewritten: tutorial, guides, generated CLI and manifest reference.
Security and safety fixes
- Manifest strings (help text, names, defaults) can no longer inject code into the generated module.
- CLI names are validated, so
cli rmand related commands cannot touch files outside cliffy's directories. - A launcher is only overwritten or removed when it is exactly the one cliffy wrote; links are never followed.
requiresentries can no longer be passed to pip as options.
Breaking changes
The main ones; the migration notes list all of them.
- Python 3.11 is the minimum.
typer-slimis replaced bytyper. manifestVersionother thanv3is an error.$lines pass arguments exactly as a shell would (pybash 0.4 quoting).- Click backend: a param written without
--is a positional argument, as with Typer. cli validateimports the generated code, so module-level code in a manifest runs during validation.cli testexits 1 when any test fails, andcli buildexits 1 on failure.cliffy[ai]needs pydantic-ai 2.x; model names carry a provider prefix.