github jdx/usage v3.4.0
v3.4.0: Readable KDL specs and tighter shell completions

4 hours ago

A small but pleasant release: spec files round-trip with human-readable multiline strings instead of \n-laden one-liners, and three completion-side bugs are fixed across zsh, nushell, and the parser.

Added

  • Multiline KDL strings for descriptions (#639 by @gaojunran). When the spec serializer encounters a string value containing newlines — typically long_help, help_md, multi-line complete run scripts, etc. — it now emits a KDL raw multiline string literal instead of a single-line string with embedded \n escapes:

    cmd bash help="Execute a shell script using bash" {
        long_help #"""
    Execute a shell script with the specified shell
    
    Typically, this will be called by a script's shebang.
    
    If using `var=#true` on args/flags, they will be joined with spaces using `shell_words::join()`
    to properly escape and quote values with spaces in them.
    """#
        ...
    }

    The number of # delimiters is computed automatically so values containing embedded """ sequences are always escaped safely.

Fixed

  • zsh: consistent single-quoting for choice values with spaces (#635). usage complete-word --shell zsh now emits two tab-separated columns per match — a display string for _describe's menu rendering and a pre-shell-quoted insert string — and the generated completion script wires them through _describe ... -U -Q -S ''. Choice values like Alice Alice or A B & C are inserted verbatim as 'Alice Alice' instead of zsh's default mix of backslash and single-quote styles, and values starting with ' correctly switch to menu-insert mode so the leading quote isn't truncated as a longest-common-prefix. If you have existing generated zsh completion scripts, regenerate them to pick up the fix.

  • nushell: invoke commands as externals with ^ (#638 by @silvanshade). Generated nushell completion scripts now prefix the user's CLI and the usage callback with ^, e.g. ^mybin usage | collect | save $spec_file and (^usage complete-word ...). Without the caret, nushell parsed bare mybin as an internal function and errored with Extra positional argument when loading the completion file.

  • parser: keep inherited global flags when a subcommand re-declares them as non-global (#649 by @JamBalaya56562). A value-taking global flag (e.g. -C/--cd) placed before a mounted subcommand whose definition re-declares the same flag without global=#true was being dropped from the recognized-flag set on descent. The leftover token was then mis-parsed as a positional — producing errors like Invalid choice for arg profile: -C, expected one of alpha, beta, gamma — and the flag's value was silently omitted from as_env() and from the environment passed to mount scripts. This was the parser-side root cause referenced by jdx/mise#10069.

New Contributors

Full Changelog: v3.3.0...v3.4.0

💚 Sponsor usage

usage is built by @jdx at en.dev — an independent developer-tooling studio behind mise, aube, hk, and more. Work on usage is funded by sponsorships.

If usage powers CLI specs, docs, or completions for a tool you maintain or use, please consider sponsoring at en.dev. Every sponsorship helps the project stay independent and moving.

Don't miss a new usage release

NewReleases is sending notifications on new releases.