Skip to content

Repository files navigation

ci docs Version PyPI Python Ruff pre-commit License

Treeparse

Tree-shaped Python CLI framework for building discoverable toolboxes you can hand to agents.

Aim

Allow writing discoverable CLI toolboxes with only <tool> -j in the skills that use the tools.

The skill names the binary. It does not copy the command schema. The agent runs -j for the current tree (commands, arguments, types, defaults, choices, nargs) and invokes from that output — never from a pasted copy. After install, upgrade, or a parse error, rediscover. Humans still get the tree (-h / --hv); --stub writes the purpose-only blurb that points at -j.

Why Treeparse

Feature argparse Click Typer Treeparse
Tree-structured help No Partial Partial Yes
JSON CLI export No No No Yes
Explicit structural model No No No Yes
Signature validation Minimal No Partial Yes

Quickstart

pip install treeparse
from treeparse import cli, command, argument

def greet(name: str):
    print(f"Hello {name}")

greet_cmd = command(
    name="greet",
    callback=greet,
    arguments=[argument(name="name", arg_type=str)],
)

app = cli(name="demo", help="Demo CLI", commands=[greet_cmd])

if __name__ == "__main__":
    app.run()
$ python app.py greet Alice
Hello Alice

$ python app.py --help
Usage: demo ...  (--json, -j, --help, -h, --hv, --stub)
Description: Demo CLI
demo                  Demo CLI
└── greet <NAME, str>

$ python app.py --json
{
  "name": "demo",
  "type": "cli",
  "commands": [
    {
      "name": "greet",
      "type": "command",
      "arguments": [
        {"name": "name", "arg_type": "str", ...}
      ]
    }
  ]
}

Workflow

1. Build tool 1

# ink.py
ink = cli(name="ink", help="Annotate figures with Inkscape.")
ink.commands.append(command(
    name="new", help="Open a new blank SVG.", callback=new,
    arguments=[argument(name="name", arg_type=str)],
    options=[option(flags=["--notes-dir", "-d"], arg_type=str, default="notes/draw", help="Directory to save SVGs")],
))

2. Build tool 2

# mind.py
mind = cli(name="mind", help="Build mind maps in Minder.")
mind.commands.append(command(
    name="create", help="Create a new mind map.", callback=create,
    arguments=[argument(name="title", arg_type=str)],
))

3. Plug into a toolbox

# toolbox.py
from treeparse import cli
from ink import ink
from mind import mind

toolbox = cli(name="toolbox", help="Creative toolbox.", subgroups=[ink, mind])

if __name__ == "__main__":
    toolbox.run()

4. Teach the LLM

The skill that uses the toolbox needs only <tool> -j — not a copy of the schema. --stub writes that recipe:

toolbox --stub > skill.md
toolbox — Creative toolbox.

This is a CLI toolbox. Discover its commands and
full schema on demand:
  toolbox -h   # command tree
  toolbox -j   # machine-readable JSON schema

The agent runs -j when it needs the schema, then invokes from that output. A wrong invoke reprints the rediscovery commands (toolbox -j, and toolbox <path> -h for the subtree) so the agent rediscovers instead of retrying from memory.

Human-readable tree

toolbox --help
Usage: toolbox ...  (--json, -j, --help, -h, --hv, --stub)
Description: Creative toolbox.
toolbox                          Creative toolbox.
├── ink                          Annotate figures with Inkscape.
│   └── new <NAME, str>          Open a new blank SVG.
│       └── --notes-dir, -d: str Directory to save SVGs (default: notes/draw)
└── mind                         Build mind maps in Minder.
    └── create <TITLE, str>      Create a new mind map.

Demo

Built-in flags

Two discovery channels: tree for humans, JSON for machines.

Flag Audience Output
--help, -h Human Rich tree, branch-pruned per subcommand
--hv Human Verbose rich tree (callback docstrings)
--json, -j Machine Full CLI structure as plain JSON (no ANSI, no rich wrapping)
--stub Agent skill file Purpose-only blurb — points to -h/-j for the schema
--version, -V Either Auto-detected from package metadata, or set with version= on cli

Examples

The examples/ directory contains 22 executable demonstrations covering every Treeparse feature (themes, group-level arguments/options, chaining, flat sub-cli toolbox composition, nargs="*"| "+", boolean flags, validation errors, root options, JSON export, custom sort/fold, etc.). They are living documentation and the primary reference for users and LLMs.

They are not installed as part of the package. After pip install treeparse only the core library and the treeparse console script are available.

Recommended development workflow

# Clone and set up (once)
git clone https://github.com/wr1/treeparse.git
cd treeparse
uv sync --dev
uv run pre-commit install   # ruff check --fix + ruff format on every commit

# Run any example with an editable install (no need to touch PYTHONPATH)
uv run --with-editable . python examples/demo.py --help
uv run --with-editable . python examples/all_themes_demo.py --help
python examples/validation_error_demo.py --help   # after the uv command above

# Manual lint/format (same as CI and pre-commit)
uv run ruff check --fix .
uv run ruff format .

The test suite (tests/test_examples.py and test_demo_execution.py) loads the examples via importlib.util.spec_from_file_location and will continue to pass without any changes to packaging.

Models

from treeparse import cli, command, group, argument, option
from treeparse.models.chain import chain
Model Purpose
cli Root — reusable as a subgroup in another cli; a flat cli (callback, no commands) acts as a single command when nested
group Namespace with optional fold=True to collapse in help, or default="cmd" to route unknown tokens to a child command
command Executable action with a callback
chain Runs multiple commands in sequence
argument Positional — <ARG> required, [ARG] optional (nargs="?"/"*")
option Named flag, with optional inheritance to child commands

More

  • Folding: group(fold=True) collapses to group [...] — drill in with toolbox ink --help
  • Default subcommand: group(default="open") routes a bare group, an option flag, or an unknown token to that child command (toolbox ink foo → toolbox ink open foo); explicitly-named subcommands always win
  • Inheritance: option(inherit=True) propagates to all child commands
  • Validation: callback param names and types checked against CLI definition at startup
  • YAML config: cli(yml_config=Path("config.yml")) overrides defaults at runtime
  • Themes: theme="github" / "monokai" / "mononeon" / "monochrome"
  • Testing: cli_runner for pytest integration

When to Use

Use Treeparse if you need:

  • Structured CLI composition
  • Discoverable CLI toolboxes — skills that use them need only <tool> -j
  • Machine-readable CLI definitions (orchestration, docs pipelines)
  • Complex nested command hierarchies

Avoid if you only need a simple single-script CLI.

Documentation

Hosted docs: https://wr1.github.io/treeparse/

To work on the docs site locally, see docs/README.md.

License

MIT

About

Treeview cli library for building skills

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages