Skip to content

rich-click CLI: --output json for machine-readable help - #335

Open
ewels wants to merge 2 commits into
help-jsonfrom
help-json-cli
Open

rich-click CLI: --output json for machine-readable help#335
ewels wants to merge 2 commits into
help-jsonfrom
help-json-cli

Conversation

@ewels

@ewels ewels commented Jun 16, 2026

Copy link
Copy Markdown
Owner

Stacked on top of #331 (base branch help-json). Implements dwreeves's CLI suggestion from that review.

What

Extends the rich-click CLI's --output option with a json value, so machine-readable help works through the CLI wrapper for any Click CLI — even ones that haven't opted into help_json.

$ rich-click --output=json flask --help
{ "name": "flask", "path": "flask", ... }

Two behaviours:

  1. rich-click --output=json [cmd] --help emits the --help-json schema instead of rendered help. A plain --help yields JSON — no need for the target to enable help_json. Implemented via a RichCommand.get_help() override that returns get_help_json() when the context's export_console_as is "json".
  2. --output applies to the --help-json flag too. The schema is rendered through the recording console and exported, so rich-click -c '{"help_json": true}' --output=svg [cmd] --help-json produces an SVG of the JSON (dwreeves's second case).

Why --output json, not --json

It's a value of the existing -o/--output option, not a new flag. The wrapper consumes --output before the script args (allow_interspersed_args=False), so the wrapped command never sees it — no risk of clashing with the target's own options.

Notes

  • getvalue() treats "json" as plain-text export defensively; it should never reach there for help, since get_help short-circuits.
  • Docs updated (rich_click_cli.md, cross-ref from machine_readable_help.md); 3 new tests + regenerated --help snapshot.

⚠️ Review/merge #331 first — this is stacked on it, so the diff will look correct once the base lands on main.

Extend the rich-click CLI's --output option with a `json` value so any
Click CLI can emit the --help-json schema without opting in itself:

- `rich-click --output json [cmd] --help` emits the JSON schema instead of
  rendered help. Implemented via a RichCommand.get_help() override that
  returns get_help_json() when the context's export_console_as is "json"
  (set by --output json), so a plain --help yields JSON.
- --output html/svg/text now also applies to the --help-json flag: the
  schema is rendered through the recording console and exported, so e.g.
  `rich-click -c '{"help_json": true}' --output svg [cmd] --help-json`
  produces an SVG of the JSON.

Uses --output json (a value of the existing -o option) rather than a
--json flag, so there is no risk of clashing with a wrapped command's own
options — the rich-click wrapper consumes -o before the script args.

getvalue() treats "json" as plain-text export defensively (it should never
reach there for help, since get_help short-circuits). Docs + tests added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@dwreeves

Copy link
Copy Markdown
Collaborator

FWIW, you could do --json if you wanted, the allow_interspersed_args=False thing makes any options you add before the script_and_args argument safe to add, so there is no technical limitation, it's just an API design choice. And maybe that's the correct API design choice? I don't know!!! 😅 I didn't consider it when I proposed adding this. I see the argument for it being that --output is a decision for rendering, whereas --json fundamentally changes the help text path. So it could be the correct API decision. What do you think?

@ewels

ewels commented Jun 17, 2026

Copy link
Copy Markdown
Owner Author

I guess one benefit of --json would be that this example gets simpler:

rich-click -c '{"help_json": true}' --output=svg [cmd] --help-json

instead becoming this?

rich-click --json --output=svg [cmd] --help

I'm not sure I have a strong preference either way. Honestly I can't see many people saving SVGs of JSON output, so combination of the two probably isn't a common scenario 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants