Skip to content

Releases: jdx/usage

v3.2.1: Zsh completion fix for values without descriptions

22 Apr 01:37
Immutable release. Only release title and notes can be modified.
06510f4

Choose a tag to compare

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 _arguments to _describe introduced a bug where the escape logic only ran when at least one completion had a description. Without escaping, a value like test:git was misinterpreted by zsh -- it treated git as a description for the item test rather 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_usage environment variable when set, fixing test failures in environments with non-standard build directories such as Nixpkgs cross-compilation builds. (#568 by @kybe236)

New Contributors

Full Changelog: v3.2.0...v3.2.1

v3.2.0: Environment-backed choices and zsh escaping fix

23 Mar 18:37
Immutable release. Only release title and notes can be modified.
1b428b7

Choose a tag to compare

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 become foo, bar, and baz. 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_env feature 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 _describe function unescaped, causing it to interpret them as glob qualifiers or character classes -- resulting in cryptic errors like unknown file attribute and unknown 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

Full Changelog: v3.1.0...v3.2.0

v3.1.0: Richer help output, stdin support, and zsh completion fixes

22 Mar 16:54
Immutable release. Only release title and notes can be modified.
1e81f1b

Choose a tag to compare

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 / -h output 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 like jbang 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 / -h rendering now includes before_help, after_help (and their _long variants), examples, a name+version header, author/license in the long help footer, and [deprecated: reason] markers on subcommands. Short help (-h) uses the base variants; long help (--help) prefers the _long variants 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 --help output, not just in generated docs.

  • All --file flags across generate, lint, and complete-word subcommands 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 / shell subcommands, 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 produce node@ (with a space), and path completions like /opt/homebrew would not include a trailing slash. The generated zsh completion scripts now use _describe with -S '' instead of _arguments with 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

13 Mar 16:58
Immutable release. Only release title and notes can be modified.
743efec

Choose a tag to compare

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, and after_long_help top-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"

    (#542 by @jdx)

  • New community integration: Ruby's OptionParser via option_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 roff dependency from 0.2 to 1.0 for man page generation. (#529)

New Contributors

Full Changelog: v2.18.2...v3.0.0

v2.18.2: Fix noclobber compatibility in shell completions

01 Mar 22:59
Immutable release. Only release title and notes can be modified.
8dc9747

Choose a tag to compare

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's noclobber option is enabled. Previously, users with noclobber set would see errors like bash: /tmp/usage__usage_spec_mycli.spec: cannot overwrite existing file on every tab completion. (#524 by @nkakouros)

New Contributors

Full Changelog: v2.18.1...v2.18.2

v2.18.1: Fix choice validation for variadic args and flags

24 Feb 23:42
Immutable release. Only release title and notes can be modified.
a7e0b75

Choose a tag to compare

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 choices now correctly reject invalid values at parse time, matching the existing behavior for non-variadic args and flags. For example, given a spec like arg "<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)

18 Feb 14:52
Immutable release. Only release title and notes can be modified.
8b35fc3

Choose a tag to compare

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

18 Feb 14:25
Immutable release. Only release title and notes can be modified.
d562fb5

Choose a tag to compare

2.17.4 - 2026-02-18

🐛 Bug Fixes

  • (publish) retry draft release creation until tag is indexed by @jdx in #510

v2.17.0: Nushell Support & Cobra Integration

16 Feb 23:23
Immutable release. Only release title and notes can be modified.
6b1774e

Choose a tag to compare

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 string
  • GenerateJSON(cmd) — returns a JSON spec
  • GenerateToFile(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

12 Feb 01:10
Immutable release. Only release title and notes can be modified.
35e26fa

Choose a tag to compare

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: arg definitions now support help, long_help, help_long, help_md, required, var, var_min, var_max, hide, and double_dash as child nodes inside {} blocks. Previously only choices, env, and default were supported, causing parse errors for other properties. (#489)