Releases: jdx/usage
v3.2.0: Environment-backed choices and zsh escaping fix
This release adds the ability to source argument/flag choices from environment variables at runtime and fixes a zsh completion regression where parentheses and brackets in task descriptions caused shell errors.
Added
-
Arguments and flags can now pull their allowed values from an environment variable using
choices env=.... The env var value is split on commas and/or whitespace, deduplicated against any literal choices, and resolved at parse/completion time rather than baked into generated output. (#548 by @mustafa0x)arg "<env>" { choices env="DEPLOY_ENVS" }
With
DEPLOY_ENVS="foo,bar baz", valid values becomefoo,bar, andbaz. You can also combine literal choices with env-backed ones:flag "--env <env>" { choices "local" env="DEPLOY_ENVS" }
When the env var is unset or empty and no literal choices are provided, validation rejects all values with a clear error message. Help output and generated markdown surface the controlling env var name rather than snapshotting its current value.
This feature is currently behind the
unstable_choices_envfeature flag in the library crate.
Fixed
- Zsh completions now properly escape parentheses (
(,)) and brackets ([,]) in completion descriptions. Previously, these characters were passed through to zsh's_describefunction unescaped, causing it to interpret them as glob qualifiers or character classes -- resulting in cryptic errors likeunknown file attributeandunknown sort specifier. This was a regression from v2.x. If you have existing generated zsh completions, regenerate them to pick up this fix. (#559 by @jdx, fixes #558)
New Contributors
- @mustafa0x made their first contribution in #548
Full Changelog: v3.1.0...v3.2.0
v3.1.0: Richer help output, stdin support, and zsh completion fixes
This release improves the CLI's --help output to render all the documentation-related fields that were previously only used in manpage and markdown generation, adds stdin support for piping specs into usage commands, and fixes a long-standing zsh completion annoyance with trailing spaces.
Highlights
- The
--help/-houtput is now much richer, rendering examples, before/after help text, version headers, author/license info, and deprecation markers -- fields that were previously only surfaced in generated manpages and markdown. - You can now pipe a usage spec from another tool directly into usage via
--file -, enabling workflows likejbang usage | usage generate markdown --file -. - Zsh tab completions no longer insert unwanted trailing spaces after partial completions, fixing a bug reported nearly a year ago.
Added
-
The built-in
--help/-hrendering now includesbefore_help,after_help(and their_longvariants),examples, aname+versionheader,author/licensein the long help footer, and[deprecated: reason]markers on subcommands. Short help (-h) uses the base variants; long help (--help) prefers the_longvariants with a fallback to the base ones. (#554 by @jdx, closes #549)For example, a spec like:
before_help "Welcome to my CLI" after_help "See the project website for docs" example "mycli --verbose" header="Run with verbose output"
will now render those sections in
mycli --helpoutput, not just in generated docs. -
All
--fileflags acrossgenerate,lint, andcomplete-wordsubcommands now accept-to read the usage spec from stdin. This enables piping specs from other tools without writing a temporary file. (#555 by @jdx, closes #546)jbang usage | usage generate markdown --file - cat myspec.kdl | usage lint --file -
Not supported for
exec/shellsubcommands, which pass stdin through to the child process.
Fixed
- Zsh completions no longer append an unwanted trailing space after partial completions. Previously, completing
node@would producenode@(with a space), and path completions like/opt/homebrewwould not include a trailing slash. The generated zsh completion scripts now use_describewith-S ''instead of_argumentswith command substitution, and directory completions include a trailing/. If you have existing generated zsh completions, regenerate them to pick up this fix. (#556 by @jdx, closes #67)
Full Changelog: v3.0.0...v3.1.0
v3.0.0: Spec metadata expansion and Cobra escaping fix
This release adds several new metadata fields to the usage spec and includes a breaking API change to the Spec struct. The spec parser now supports license, before_help, after_help, before_long_help, and after_long_help -- fields that were documented in the spec reference but silently ignored until now. The Spec struct has been marked #[non_exhaustive] to allow future field additions without further breaking changes.
Breaking Changes
The Spec struct now has the #[non_exhaustive] attribute. If you construct Spec values using struct literal syntax, your code will need to be updated:
// Before (no longer compiles)
let spec = Spec { name: "my-cli".into(), bin: "mycli".into(), /* ... */ };
// After (option 1)
let mut spec = Spec::default();
spec.name = "my-cli".into();
spec.bin = "mycli".into();
// After (option 2)
let spec = Spec { name: "my-cli".into(), bin: "mycli".into(), ..Default::default() };This change was made so that new fields can be added to Spec in future minor releases without breaking downstream code. (#542 by @jdx, fixes #537)
Added
-
Support for
license,before_help,after_help,before_long_help, andafter_long_helptop-level metadata fields in the usage spec. These fields are now parsed, serialized, and included in spec merges and generated docs. For example:license "MIT" before_help "Welcome to my CLI" after_help "See the docs for more info" before_long_help "Detailed welcome text" after_long_help "Detailed footer text"
-
New community integration: Ruby's
OptionParserviaoption_parser_usage. (#533 by @packrat386)
Fixed
- The Cobra integration now correctly escapes newlines (
\n), tabs (\t), and carriage returns (\r) in KDL output. Previously, Cobra commands with multi-line help text would produce invalid KDL specs that failed to parse. (#539 by @thecodesmith)
Changed
- Updated the
roffdependency from 0.2 to 1.0 for man page generation. (#529)
New Contributors
- @thecodesmith made their first contribution in #539
- @packrat386 made their first contribution in #533
Full Changelog: v2.18.2...v3.0.0
v2.18.2: Fix noclobber compatibility in shell completions
A small patch release that fixes a compatibility issue with the noclobber shell option. If you had set -o noclobber (or set -C) enabled in bash or zsh, tab completions generated by usage would fail with a "cannot overwrite existing file" error every time the spec cache file already existed. This is now fixed.
Fixed
- Generated bash and zsh completion scripts now use
>|(force-overwrite redirection) instead of>when writing the spec cache file, preventing failures when the shell'snoclobberoption is enabled. Previously, users withnoclobberset would see errors likebash: /tmp/usage__usage_spec_mycli.spec: cannot overwrite existing fileon every tab completion. (#524 by @nkakouros)
New Contributors
- @nkakouros made their first contribution in #524
Full Changelog: v2.18.1...v2.18.2
v2.18.1: Fix choice validation for variadic args and flags
A small patch release that fixes a parsing bug where variadic arguments and flags with declared choices were not being validated. Previously, any value was silently accepted for variadic (var=#true) args and flags, even when a choices constraint was specified. Non-variadic args and flags were unaffected and already validated correctly.
Fixed
- Variadic args and flags with
choicesnow correctly reject invalid values at parse time, matching the existing behavior for non-variadic args and flags. For example, given a spec likearg "<level>" var=#true { choices "debug" "info" "warn" "error" }, passing an invalid value such as"invalid"now produces a clear error message instead of being silently accepted. (#520 by @jdx, fixes jdx/mise#8334)
Full Changelog: v2.18.0...v2.18.1
v2.18.0 (Internal CI improvements)
This is a maintenance release with no user-facing changes. The only modification is an internal CI/CD improvement that extracts the AI-powered release-note enhancement step into a separate GitHub Actions job, making it independently re-runnable if it fails due to transient errors.
There are no changes to the library, CLI, shell completions, spec format, or documentation.
Full Changelog: v2.17.4...v2.18.0
v2.17.4
v2.17.0: Nushell Support & Cobra Integration
This release adds two significant features: shell completion support for nushell users and a new Go package for generating usage specs from Cobra CLI definitions.
Highlights
Nushell Completions
usage now generates shell completions for nushell, joining bash, zsh, fish, and PowerShell as a supported shell. The implementation uses nushell's module system and @complete syntax to provide dynamic completions that call back to usage complete-word at runtime—the same approach used by the other shells.
Thanks to @abusch for contributing this! #485
Cobra (Go) Integration
A new Go package at integrations/cobra/ converts Cobra command trees into usage specs. If you have a Go CLI built with Cobra, you can now generate shell completions, markdown docs, and man pages from your existing command definitions without writing a spec by hand.
The package provides a straightforward API:
Generate(cmd)— returns a KDL spec stringGenerateJSON(cmd)— returns a JSON specGenerateToFile(cmd, path)/GenerateJSONToFile(cmd, path)— write specs to disk
It maps Cobra commands, flags (persistent and local), positional args, aliases, ValidArgs choices, hidden/deprecated markers, and more. See the Cobra integration docs for setup details. #498
Integrations Framework Tracker
The new integrations directory documents the roadmap for framework support across languages. Clap (Rust) and Cobra (Go) are implemented; Commander.js, Click, Typer, and others are planned. #497 #499
New Contributors
v2.16.2: Arg Parser Child Node Fix
A small bug fix release. The main change fixes an issue where KDL spec authors couldn't use common properties like help, long_help, required, var, and hide as child nodes inside arg { ... } blocks — they would cause parse errors. These now work correctly, matching the existing behavior for flags.
Bug Fixes
- Arg child node parsing:
argdefinitions now supporthelp,long_help,help_long,help_md,required,var,var_min,var_max,hide, anddouble_dashas child nodes inside{}blocks. Previously onlychoices,env, anddefaultwere supported, causing parse errors for other properties. (#489)
v2.16.1: Variadic Argument Parsing Fix
This patch release fixes an important parsing bug for variadic arguments and includes documentation improvements.
Bug Fixes
- Variadic argument parsing: Fixed handling of variadic ellipsis inside brackets like
[args...]. Previously, this syntax could cause parsing issues - now it works correctly whether you use<args>...,[args]..., or[args...]. (#481)
Documentation
- Added documentation for the bash array pattern when working with variadic arguments, making it clearer how to handle multiple values in your scripts. (#480)
For full documentation, visit usage.jdx.dev.