Skip to main content
Runegraft centers on a single CLI instance defined in src/runegraft/cli.py. Use it to register commands, options, and root behavior; then hand off execution to CLI.run().

Constructing a CLI

Parameters:
  • name: controls how usage is rendered and becomes the default shell prompt (forge>).
  • description: printed at the top of help output.
The object also exposes ui.console, a Rich console configured with pretty tracebacks (see formatting.make_ui).

Registering commands

  • Route strings are parsed by parse_route and enforce positional types; an error is raised at startup if a reserved shell command name is reused.
  • The first line of the docstring becomes the summary column in help.
  • All function annotations are available during parsing, so you can combine route tokens and type hints (e.g., type hints drive option coercion).
Use @app.root to specify what runs when python -m runegraft is invoked with no arguments. Returning app.shell() matches the demo behavior, but you could launch a default command or print a welcome message.

Options and flags

Options are inferred from function parameters that are not present in the route:
  • dry_run automatically becomes --dry-run and, because it is typed as bool, behaves like a flag (--dry-run sets the value to True).
  • Non-bool parameters expect a value: --retries 3.
  • Defaults come from the function signature; use runegraft.cli.option to override the long/short flag names or add help text.

Custom converters

Route tokens (<name:type>) map to converters defined in types.BUILTIN_TYPES. Register your own via CLI.type:
If validation fails, raise any exception and it will be surfaced as a CLIError with a nice message both in the shell and non-interactive mode.

Execution helpers

  • CLI.run(argv: Optional[List[str]]): dispatch arguments (or sys.argv[1:] by default). Automatically handles --help and empty input.
  • CLI.invoke(tokens: List[str]): run one command when you already parsed the leading command name.
  • CLI.shell(): construct and run the interactive loop from shell.py.
  • CLI.print_help(): render the Rich table shown in the shell.
The parser raises CLIError for user-facing issues; let them bubble up so Rich can colorize the message. Only catch them for custom error handling or to translate into exit codes.