Batteries-included Python CLI template. Auto-discovery commands, global flags, output formatting, self-update, and a whole lot more.
Key Features β’ Quick Start β’ CLI Usage β’ Adding Commands β’ Configuration β’ Credits β’ About the Core Contributors
Copy and paste this into your AI coding agent (Claude Code, Cursor, Copilot, etc.) to install:
Install the CLI and download the usage skill:
pip install miyamura80-cli-template
curl -fsSL https://raw.githubusercontent.com/Miyamura80/CLI-Template/main/scripts/install-skills.sh -o install-skills.sh
bash install-skills.sh && rm install-skills.sh
Opinionated Python CLI template for fast development. The saas branch extends main with web framework, auth, and payments.
| Feature | main |
saas |
|---|---|---|
| Auto-discovery command system | β | β |
| Interactive fallback prompts | β | β |
| Shell completions | β | β |
| Self-update | β | β |
| Anonymous telemetry with opt-out | β | β |
| UV + Pydantic config | β | β |
| CI/Linters (Ruff, Vulture) | β | β |
| Pre-commit hooks (prek) | β | β |
| LLM (DSPY + LangFuse Observability) | β | β |
| FastAPI + Uvicorn | β | β |
| SQLAlchemy + Alembic | β | β |
| Auth (WorkOS + API keys) | β | β |
| Payments (Stripe) | β | β |
| Ralph Wiggum Agent Loop | β | β |
make onboard # interactive setup (rename, deps, env, hooks)
uv sync # install deps
uv run mycli --help # see all commands
uv run mycli greet Alice # run a command
uv run mycli init my_command # scaffold a new commandGlobal flags go before the subcommand:
| Flag | Short | Description |
|---|---|---|
--verbose |
-v |
Increase output verbosity |
--quiet |
-q |
Suppress non-essential output |
--debug |
Show full tracebacks on error | |
--format |
-f |
Output format: table, json, plain |
--dry-run |
Preview actions without executing | |
--version |
-V |
Print version and exit |
uv run mycli --format json config show # JSON output
uv run mycli --dry-run greet Bob # preview without executing
uv run mycli --verbose greet Alice # detailed outputDrop a Python file in commands/ and it is auto-discovered.
Single command - export a main() function:
# commands/hello.py
from typing import Annotated
import typer
def main(name: Annotated[str, typer.Argument(help="Who to greet.")]) -> None:
"""Say hello."""
typer.echo(f"Hello, {name}!")uv run mycli hello World # Hello, World!Subcommand group - export app = typer.Typer():
# commands/db.py
import typer
app = typer.Typer()
@app.command()
def migrate() -> None:
"""Run migrations."""
...uv run mycli db migrateOr scaffold with: uv run mycli init my_command --desc "Does something".
from common import global_config
# Access config values from common/global_config.yaml
global_config.example_parent.example_child
# Access secrets from .env
global_config.OPENAI_API_KEYCLI config inspection:
uv run mycli config show # full config
uv run mycli config get llm_config.cache_enabled # single value
uv run mycli config set logging.verbose false # write overrideThis software uses the following tools:
- Cursor: The AI Code Editor
- uv
- Typer: CLI framework
- Rich: Terminal formatting
- prek: Rust-based pre-commit framework
- DSPY: Pytorch for LLM Inference
- LangFuse: LLM Observability Tool
Made with contrib.rocks.

