Skip to content

windlass.cli

cli

The windlass command-line interface.

A small set of commands that answer the questions people actually have when something is not working::

windlass info                 # version, Python, which extras are installed
windlass list                 # every registered component
windlass list chunker         # one kind, with descriptions
windlass config               # effective settings, secrets masked
windlass doctor               # diagnose a broken install
windlass ask "..." --docs ./  # a one-shot RAG query
windlass chat                 # an interactive agent session

doctor is the important one: it reports exactly which optional dependencies are present, whether credentials are configured, and what the defaults resolve to — which is usually enough to explain the problem without opening a REPL.

build_parser

build_parser() -> argparse.ArgumentParser

Build the argument parser.

Returns:

Type Description
ArgumentParser

The configured :class:argparse.ArgumentParser.

Source code in src\windlass\cli.py
def build_parser() -> argparse.ArgumentParser:
    """Build the argument parser.

    Returns:
        The configured :class:`argparse.ArgumentParser`.
    """
    parser = argparse.ArgumentParser(
        prog="windlass",
        description="Windlass — the modular AI application framework.",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog=(
            "Examples:\n"
            "  windlass doctor\n"
            "  windlass list retriever\n"
            '  windlass ask "What is in these docs?" --docs ./documents\n'
            "  windlass chat --llm ollama --model llama3.2\n"
        ),
    )
    parser.add_argument("--version", action="version", version=f"windlass {__version__}")
    sub = parser.add_subparsers(dest="command", metavar="command")

    sub.add_parser("info", help="show version and environment information")

    listing = sub.add_parser("list", help="list registered components")
    listing.add_argument("kind", nargs="?", help="component kind, e.g. chunker")
    listing.add_argument("--verbose", "-v", action="store_true", help="show descriptions")

    config = sub.add_parser("config", help="show the effective settings")
    config.add_argument("--json", action="store_true", help="emit JSON")

    sub.add_parser("doctor", help="diagnose the installation")

    ask = sub.add_parser("ask", help="run a one-shot RAG query")
    ask.add_argument("question", help="the question to answer")
    ask.add_argument("--docs", "-d", required=True, help="file or directory to index")
    ask.add_argument("--llm", default=None, help="model provider")
    ask.add_argument("--model", default=None, help="model id")
    ask.add_argument("--embedding", default=None, help="embedding provider")
    ask.add_argument("--chunker", default=None, help="chunking strategy")
    ask.add_argument("--retriever", default=None, help="retrieval strategy")
    ask.add_argument("--top-k", type=int, default=5, help="chunks to retrieve")
    ask.add_argument("--trace", action="store_true", help="print a trace tree")

    chat = sub.add_parser("chat", help="start an interactive agent session")
    chat.add_argument("--llm", default=None, help="model provider")
    chat.add_argument("--model", default=None, help="model id")
    chat.add_argument("--system", default=None, help="system prompt")
    chat.add_argument("--trace", action="store_true", help="print a trace tree")

    return parser

main

main(argv: list[str] | None = None) -> int

Run the CLI.

Parameters:

Name Type Description Default
argv list[str] | None

Arguments, defaulting to sys.argv[1:].

None

Returns:

Type Description
int

A process exit code: 0 on success, 1 on error, 130 on

int

interrupt.

Source code in src\windlass\cli.py
def main(argv: list[str] | None = None) -> int:
    """Run the CLI.

    Args:
        argv: Arguments, defaulting to ``sys.argv[1:]``.

    Returns:
        A process exit code: ``0`` on success, ``1`` on error, ``130`` on
        interrupt.
    """
    parser = build_parser()
    args = parser.parse_args(argv)

    if not args.command:
        parser.print_help()
        return 0

    handlers = {
        "info": _info,
        "list": _list,
        "config": _config,
        "doctor": _doctor,
        "ask": _ask,
        "chat": _chat,
    }
    try:
        return handlers[args.command](args)
    except KeyboardInterrupt:
        _out("\nInterrupted.")
        return 130
    except Exception as exc:
        from windlass.core.exceptions import WindlassError

        if isinstance(exc, WindlassError):
            _out(f"\nError: {exc}")
        else:
            _out(f"\nUnexpected {type(exc).__name__}: {exc}")
        return 1