Generate Markdown, JSON, or Codex skill files from CLI help trees.
Project description
Climo
Generate Markdown, JSON, or Codex skill files for CLI command trees from recursive help output.
Most CLI tools expose help one command at a time:
gh --help
gh auth --help
gh auth login --help
climo experiments with turning that scattered help output into one
structured artifact:
gh
├── auth
│ ├── login
│ ├── logout
│ └── status
├── repo
└── pr
The goal is precision first: parse command candidates from inconsistent help formats, validate candidates by invoking child help, and render a deterministic document.
Status
This is an early package prepared for PyPI distribution. The public source repo
is https://github.com/miguelalcalde/climo.
Current parser coverage includes:
- section tables used by tools like
gh,docker,kubectl,pip,cargo, anduv - comma inventories like
npm - multiline command blocks like
gog - Git's grouped common-command help
- Homebrew's terse example-style root help
- PNPM's category-based root help
- OpenSSL's columnar command inventory
The project also keeps negative fixtures for tools that mostly expose options
instead of subcommands, such as python3, rg, ssh, tar, and rsync.
Requirements
- Python 3
- The CLI you want to inspect installed on
PATH
No third-party Python dependencies are required.
Install
Run without a persistent install:
uvx climo --help
Install the PyPI package as a uv tool:
uv tool install climo
Or install it with pipx:
pipx install climo
After installation, run:
climo --help
Until the first PyPI release is available, use the GitHub source URL:
uvx --from git+https://github.com/miguelalcalde/climo.git climo --help
uv tool install git+https://github.com/miguelalcalde/climo.git
pipx install git+https://github.com/miguelalcalde/climo.git
For local development from a checkout:
uv tool install --editable .
or run the module directly:
python3 -m help_tree --help
Usage
Show the command help:
climo --help
Parse a captured help file:
climo parse example-gh.txt --format markdown
climo parse fixtures/cargo-root.txt --format json
Generate a tree from a live command:
climo generate gh --max-depth 3 --max-nodes 100 --format markdown --out out/gh.md
Generate with a debug manifest:
climo generate docker \
--max-depth 2 \
--max-nodes 100 \
--format markdown \
--out out/docker.md \
--debug-out out/docker-debug.json
The debug manifest records accepted and rejected candidates, the argv used for validation, return codes, timeouts, parser source, and rejection reason.
Skill Output
The repo can also generate Codex-compatible skill files. A valid skill requires
a SKILL.md file with YAML frontmatter, so --description wraps the generated
Markdown tree with the required metadata.
Generate the current Todoist CLI skill:
climo generate td \
--out skills/td/SKILL.md \
--description "A compact skill for Todoist CLI, use this when you want to find out how to use the CLI with simple examples"
This writes:
skills/td/SKILL.md
The generated folder can be pulled into a Codex skills directory as a pure skill
tool. Use npm run skills:td to rebuild the checked-in Todoist skill.
How It Works
The crawler is intentionally validation-driven.
- Run help for the current command path.
- Normalize ANSI and whitespace.
- Extract candidate subcommands using multiple parser families.
- Validate every candidate by invoking its child help.
- Recurse into validated children until the depth or node limit is reached.
- Render Markdown or JSON.
This means parsers can be broad, while validation prevents many false positives from entering the final tree.
Examples
Generate a GitHub CLI tree:
climo generate gh \
--max-depth 3 \
--max-nodes 120 \
--format markdown \
--out out/gh-depth3.md \
--debug-out out/gh-depth3-debug.json
Generate a Cargo tree:
climo generate cargo \
--max-depth 1 \
--format markdown \
--out out/cargo-depth1.md
Generate PNPM documentation:
climo generate pnpm \
--max-depth 1 \
--format markdown \
--out out/pnpm-depth1.md \
--debug-out out/pnpm-depth1-debug.json
Fixtures
Fixtures are captured help outputs used to test parser precision without relying on live commands during every test run.
Capture the currently configured fixtures:
python3 scripts/capture_fixtures.py
This writes files under fixtures/ and updates fixtures/manifest.json.
Current fixture corpus:
cargo-root.txtopenssl-root.txtpip3-root.txtpnpm-root.txtpython3-root.txtrg-root.txtrsync-root.txtssh-root.txttar-root.txt
Validation
Run the parser and fixture precision tests:
python3 -m unittest discover -v
Run a syntax check without writing bytecode outside the repo:
env PYTHONPYCACHEPREFIX=.pycache python3 -m compileall -q help_tree tests scripts
Validate generated skills:
python3 scripts/validate_skills.py
The fixture precision tests assert both:
- expected commands are extracted
- known non-command tokens are not extracted
That second point is important. For this project, avoiding hallucinated commands from option lists and prose is as important as finding real subcommands.
Contributing Skills
Skill contributions live under skills/<name>/SKILL.md. See
CONTRIBUTING.md for the PR checklist and the expected validation commands.
Publishing
Releases are configured for PyPI Trusted Publishing through GitHub Actions. In
PyPI, create the climo project and add a trusted publisher with:
- owner:
miguelalcalde - repository:
climo - workflow:
publish.yml - environment:
pypi
Then publish a release by pushing a version tag that matches the version in
pyproject.toml:
git tag v0.1.0
git push origin v0.1.0
After the release is on PyPI, one-shot execution works with:
uvx climo --help
Output Formats
Markdown is intended for humans:
climo generate uv --format markdown --out out/uv.md
JSON is intended for downstream tooling:
climo generate uv --format json --out out/uv.json
Use --include-raw if you want raw help text embedded in the JSON tree.
Profiles
Most CLIs work with the default help strategy:
{command} --help
{command} -h
Some tools need custom help strategies. Profiles live in
help_tree/profiles.py. Current custom profiles include npm, pnpm, and
openssl.
Adding Parser Coverage
The preferred workflow for a new CLI is:
- Capture root help into
fixtures/<tool>-root.txt. - Add include/exclude expectations in
tests/test_fixture_precision.py. - Run the tests and inspect parser misses.
- Add or tighten a parser under
help_tree/parsers/. - Add a bounded live generation with
--debug-outto check validation behavior.
Good next candidates include vercel, go, curl, jq, ffmpeg, and any
niche CLIs with unusual help layouts.
Known Limits
- Validation is serial, so very large trees can take time.
- Some tools expose help topics rather than executable subcommands; the model does not yet distinguish all topic types.
- Parser precision depends on fixture coverage. Add fixtures before broadening parser heuristics.
- Generated skills should be reviewed before PR. If output looks wrong, add fixture coverage and fix the parser rather than hand-editing large trees.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file climo-0.1.0.tar.gz.
File metadata
- Download URL: climo-0.1.0.tar.gz
- Upload date:
- Size: 15.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
325efb9cc8167d886f8d7108fc234cee16895e06b28092b0f969c185d3c5ca0b
|
|
| MD5 |
a7cdb8bd612b685bca1aa852e7ee70b4
|
|
| BLAKE2b-256 |
8398161fa1c0eeb5d082e4fa6c93dc1f7375f4b529fb63b92cfd4948de2f8cea
|
Provenance
The following attestation bundles were made for climo-0.1.0.tar.gz:
Publisher:
publish.yml on miguelalcalde/climo
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
climo-0.1.0.tar.gz -
Subject digest:
325efb9cc8167d886f8d7108fc234cee16895e06b28092b0f969c185d3c5ca0b - Sigstore transparency entry: 1570458460
- Sigstore integration time:
-
Permalink:
miguelalcalde/climo@69f088fe7eaddc2e643431adc2d234f4e481dc1b -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/miguelalcalde
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@69f088fe7eaddc2e643431adc2d234f4e481dc1b -
Trigger Event:
push
-
Statement type:
File details
Details for the file climo-0.1.0-py3-none-any.whl.
File metadata
- Download URL: climo-0.1.0-py3-none-any.whl
- Upload date:
- Size: 21.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b2ee23a27e23f3b07cdc426494f4de8161994832dc6d2cb6d3b7b4ada00222a1
|
|
| MD5 |
6abba708453c11492413c9133608d8dd
|
|
| BLAKE2b-256 |
21c4993a8d02115e74bcc56865b1534323327afb2cb7f88a532d84cbd2052783
|
Provenance
The following attestation bundles were made for climo-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on miguelalcalde/climo
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
climo-0.1.0-py3-none-any.whl -
Subject digest:
b2ee23a27e23f3b07cdc426494f4de8161994832dc6d2cb6d3b7b4ada00222a1 - Sigstore transparency entry: 1570458477
- Sigstore integration time:
-
Permalink:
miguelalcalde/climo@69f088fe7eaddc2e643431adc2d234f4e481dc1b -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/miguelalcalde
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@69f088fe7eaddc2e643431adc2d234f4e481dc1b -
Trigger Event:
push
-
Statement type: