Releases: jdx/usage
v3.2.1: Zsh completion fix for values without descriptions
A small patch release that fixes a zsh completion regression introduced in v3.1.0. If you use zsh completions with values that contain colons (such as nested task names) and those values don't have descriptions, you should upgrade and regenerate your completions.
Fixed
-
Zsh completions now correctly escape colons in completion values even when no descriptions are present. In v3.1.0, the switch from
_argumentsto_describeintroduced a bug where the escape logic only ran when at least one completion had a description. Without escaping, a value liketest:gitwas misinterpreted by zsh -- it treatedgitas a description for the itemtestrather than as part of the value. If you have existing generated zsh completions, regenerate them to pick up this fix. (#597 by @david-hamilton-glean) -
Test suite now respects the
CARGO_BIN_EXE_usageenvironment variable when set, fixing test failures in environments with non-standard build directories such as Nixpkgs cross-compilation builds. (#568 by @kybe236)
New Contributors
- @david-hamilton-glean made their first contribution in #597
- @kybe236 made their first contribution in #568
Full Changelog: v3.2.0...v3.2.1
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)