cli-root-yo
Reusable CLI kernel for building unified command-line interfaces with consistent behavior, output style, help, and extension semantics. Built on Typer + Rich.
What It Does
cli-root-yo provides the shared foundation that downstream CLI tools build on:
- Root app factory —
create_app()builds a fully configured Typer app from a declarative spec - Built-in commands —
version,info, and optionalconfig/envgroups - Plugin system — explicit callables +
cli_root_yo.pluginsentry-point discovery - XDG paths — platform-aware config/data/state/cache directory resolution (macOS + Linux)
- Output primitives —
heading,success,warning,error,action,detail,bullet,emit_json - Runtime context — immutable singleton accessible to all commands during invocation
- JSON mode —
--json/-jflag with deterministic output (indent=2, sorted keys, no ANSI) - NO_COLOR — respects the NO_COLOR convention
- Debug mode —
CLI_ROOT_YO_DEBUG=1prints tracebacks to STDERR
Prerequisites
- Python 3.10+
- pip
Installation
pip install cli-root-yo
For development:
git clone https://github.com/Daylily-Informatics/cli-root-yo.git
cd cli-root-yo
pip install -e ".[dev]"
Quick Start
from cli_root_yo.spec import CliSpec, XdgSpec
from cli_root_yo.app import run
spec = CliSpec(
prog_name="my-tool",
app_display_name="My Tool",
dist_name="my-tool",
root_help="A CLI built with cli-root-yo.",
xdg=XdgSpec(vendor="my-tool"),
)
exit_code = run(spec)
This gives you my-tool version, my-tool info, my-tool --help, --json support, and all the standard behaviors out of the box.
Adding Commands via Plugin
# my_tool/plugin.py
def register(registry, spec):
registry.add_command(None, "greet", greet_cmd, help_text="Say hello.")
def greet_cmd():
from cli_root_yo import output
output.success("Hello, world!")
Register it in your spec:
from cli_root_yo.spec import PluginSpec
spec = CliSpec(
...,
plugins=PluginSpec(explicit=["my_tool.plugin.register"]),
)
Or via entry points in pyproject.toml:
[project.entry-points."cli_root_yo.plugins"]
my-tool = "my_tool.plugin:register"
Config & Env Groups
Enable optional built-in command groups by providing specs:
from cli_root_yo.spec import ConfigSpec, EnvSpec
spec = CliSpec(
...,
config=ConfigSpec(
primary_filename="config.json",
template_bytes=b'{"key": "value"}\n',
),
env=EnvSpec(
env_dir_name=".venv",
activate_script_rel="bin/activate",
),
)
This adds config path|init|show|validate|edit|reset and env status|activate|deactivate|reset.
Public API
| Symbol | Module | Description |
|---|---|---|
create_app(spec) |
cli_root_yo.app |
Build a Typer app from a CliSpec |
run(spec, argv) |
cli_root_yo.app |
Execute CLI, return exit code (never calls sys.exit()) |
CommandRegistry |
cli_root_yo.registry |
Register commands/groups with ordering and conflict detection |
get_context() |
cli_root_yo.runtime |
Access the current invocation's RuntimeContext |
CliSpec, ConfigSpec, EnvSpec, PluginSpec, XdgSpec |
cli_root_yo.spec |
Frozen dataclass specs |
output.* |
cli_root_yo.output |
UX primitives + emit_json() |
Exit Codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Domain/runtime failure |
| 2 | Usage error (bad args, unknown command) |
| 130 | SIGINT |
Build / Test / Lint
# Run tests
python -m pytest tests/ -v --cov=cli_root_yo
# Lint + format check
ruff check cli_root_yo tests
ruff format --check cli_root_yo tests
# Type check
mypy cli_root_yo --ignore-missing-imports
# Build distribution
python -m build
twine check dist/*
License
MIT — see LICENSE.
Metadata
Release files for cli-root-yo 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| cli_root_yo-0.1.0.tar.gz | 32.6 kB | Without provenance | Details for cli_root_yo-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| cli_root_yo-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for cli_root_yo-0.1.0-py3-none-any.whl |
Total release size: 49.5 kB
Release files / cli_root_yo-0.1.0.tar.gz
| Download URL | cli_root_yo-0.1.0.tar.gz |
|---|---|
| Size | 32.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e68a727d457fd0646b58717850d81ffc92ef408e36a2b25fa0a208a88b923edf
|
|
BLAKE2b-256 checksum How to use checksums |
5ad6d5b5e9cd26944fa72d32d50d8fca428494148c4a811b3e4d358dab43dd67
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.2
|
Release files / cli_root_yo-0.1.0-py3-none-any.whl
| Download URL | cli_root_yo-0.1.0-py3-none-any.whl |
|---|---|
| Size | 17.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
614b58a5c163c347df9c011e5587aed8a708cae3dc9560fb6d16c80d3c8eb091
|
|
BLAKE2b-256 checksum How to use checksums |
b3ae06f24c54785a59a379e16de8a2fff4cc8e2171af78d3afd1bc3c28f9f0ad
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.2
|
Security for cli-root-yo 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.