chore(deps): update dependency jdx/usage to v6 - #29
Open
renovate[bot] wants to merge 1 commit into
Open
Conversation
renovate
Bot
force-pushed
the
renovate/jdx-usage-6.x
branch
from
August 23, 2026 00:39
13fdb38 to
c55e8b6
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
2.18.2→6.1.0Warning
Some dependencies could not be looked up. Check the Dependency Dashboard for more information.
Release Notes
jdx/usage (jdx/usage)
v6.1.0: : Sharper derives, richer dispatchCompare Source
This release sharpens the Rust derive framework introduced in 6.0:
#[usage(run)]now handles the enum shapes real clap CLIs actually have, help and diagnostics respect the runtime identity ofparse_fromcallers, and flatten-site help headings work. On the CLI itself, settings move to a prefix mise cannot strip, and generated KDL now round-trips multiline help.Added
Broader
#[usage(run)]dispatch (#1221)The derived dispatch previously required every variant to wrap a named
Argstype, the whole enum to be sync or async, and the root to hold nothing but its subcommand field. That is now covered:{Enum}{Variant}struct you canimpl Runon.#[usage(run_async)]on the enum and#[usage(run)]on the variant that should not.await.#[usage(run, external = fallback)]forwards the unmatched argv (and context, ifrun_with).#[usage(run)]on a struct with--verboseand a required subcommand generatesrun_commandinstead ofimpl Run, so top-level flags are not dropped.#[usage(no_ctx)]plusrun_with_lazy/run_async_with_lazy(FnOnce() -> Ctx) lets commands likeversionavoid loading a config file.output = Typeexplicitly names the match'sOutputinstead of borrowing it from the first command.Runtime identity in help, and flatten-site headings (#1220)
parse()already overlays the embedder's computedname/bin.parse_fromcallers that rendered help throughCli::spec()did not.Cli::render_helpandCli::render_failurenow apply the same identity, so vendored parsers stop leaking the portableaubename into help and diagnostics.#[usage(flatten, next_help_heading = "…")]at the flatten site now groups the unheaded flags of a flattenedArgsstruct — matching clap's behavior — and reaches into subcommand help and generated KDL too.USAGECLI_*settings prefix (#1213 by @JamBalaya56562)Because Windows env-var names are case-insensitive,
USAGE_DEBUG(a usage-cli setting) collides withusage_debug(a spec's own flag), and mise clears everything starting withusage_before running a task — including usage-cli's settings. Settings can now be read underUSAGECLI_*:USAGECLI_SHELL_{BASH,ZSH,FISH,PWSH}USAGE_SHELL_*USAGECLI_DEBUGUSAGE_DEBUGUSAGECLI_TRACEUSAGE_TRACEUSAGECLI_LOGUSAGE_LOGFirst name set wins. As a side benefit,
USAGE_LOGis no longer written back into the environment withset_var, so a spawned script's ownlogargument survives.Fixed
long_helpas forhelp: source-wrapped lines become spaces, indented examples and fenced code blocks keep their breaks, andverbatim_doc_commentis untouched (#1215).Spec::to_kdlemits#"""…"""#raw multiline strings for values that contain newlines, so generated.usage.kdlno longer collapses multi-paragraph help into one giant escaped line (#1215).Changed
#[usage(...)].#[command(...)],#[arg(...)],#[value(...)],#[group(...)], and inner synonyms (id,default_value,conflicts_with,value_parser,last, …) still parse, but fail at the source span with a diagnostic telling you the native replacement. Implicit clap-style#[group(...)]generation for one-member groups is gone — requiredness comes from the field type orrequired.#[usage(run_async)]on an enum variant is now rejected while parsing the attribute.Documentation
Breaking Changes
#[usage(...)]. Any remaining clap-shaped attributes (#[command],#[arg],#[value],#[group], or their inner synonyms) will now fail to compile with a diagnostic pointing at the replacement. See the clap migration guide for before/after rewrites.#[group(...)]generation is gone. If you relied on it for requiredness, mark the fieldrequiredor use its type (e.g. non-Option) instead.Full Changelog: jdx/usage@v6.0.0...v6.1.0
💚 Sponsor usage
usage is maintained by @jdx, an open source developer for entire.io, the title sponsor of the jdx.dev open source tools including mise, aube, hk, and more. Work on usage is funded by sponsorships.
If
usagepowers CLI specs, docs, or completions for a tool you maintain or use, please consider sponsoring at jdx.dev. Every sponsorship helps the project stay independent and moving.v6.0.0Compare Source
Usage 6.0
Usage 6 is a much larger release than its version number can comfortably summarize. Since 5.1, the project has grown from a spec parser and artifact generator into a complete CLI platform: the new
usage-rsreference framework for Rust, the beginnings of theusage-goreference framework, layered configuration, portable validation, richer completions, compatibility tooling, and a substantially more expressive Usage spec.The idea is still the same: a CLI should have one machine-readable contract. In 6.0, that contract can now drive the program itself as well as its help, completions, docs, manpages, config schema, and compatibility checks.
Introducing usage-rs
usage-rsis the new reference framework for building Rust CLIs with Usage. Declare typed commands, arguments, subcommands, value enums, argument groups, and settings with ordinary structs and enums;usage-rscompiles the declaration into static data instead of constructing a command tree at startup.That gives applications:
-h,--help,help,--version, clap-shaped diagnostics, and suggestionsupdate_fromsupport__usage_spec__endpoint, so the running binary can describe itselfOn the checked-in mise-scale benchmark—211 commands, 711 flags, and 128 positionals—the parse-only path takes about 7,377 instructions / 0.7 µs, with no allocations when no owned values are bound. See the methodology and current numbers.
usage-rsis experimental: it is complete enough thatusage-clinow uses it itself, but 6.x point releases may still change APIs.Configuration becomes part of the contract
usage-rscan resolve settings across command-line, environment, and file layers while retaining provenance for every value. ItsConfigderive generates the registry, typed reader, and portable spec metadata from the same settings struct.The resolver supports typed values, merge policies, aliases and renames, deprecation milestones, TOML/JSON/YAML readers, lossy reads, and explanations of where a value came from. Because config declarations live in the spec, the CLI can also generate JSON Schema and complete config keys and values.
See the configuration guide.
A substantially richer spec and CLI
The spec now covers much more of a real CLI's behavior: conflicts, requirements, overrides, groups, reusable flag sets, value-conditional rules, fixed and variadic arity, external and default subcommands, token-boundary controls, deprecations, portable expression validation, config metadata, help layout, and command effects.
Two new commands make that contract easier to operate:
usage explainshows how argv was interpreted, including token roles, fallbacks, provenance, warnings, and accumulated errors.usage diffcompares two specs and classifies changes as breaking, compatible, or metadata-only. It has machine-readable output and CI-friendly exit behavior.Completion generation gained richer value hints, config completion, shell-safe quoting, partial-path expansion, aliases, async overlays, and
--installfor placing scripts where each shell expects them. JSON Schema generation for CLI config is new as well.Introducing usage-go
usage-gois the new Go reference framework. It follows the same static-data design, generates typed command structs from a Usage spec, and keeps parsing, validation metadata, and help text linker-separable.This work is not ready for adoption or testing yet. Its APIs and generated output are still in flux, and the published documentation is a preview of the direction rather than a stability promise.
Breaking changes and migration notes
usage-rsandusage-goshould be treated as brand-new in 6.0. Some implementation crates were accidentally published with 5.x versions, but those releases did not constitute supported public frameworks or an API lineage to migrate from. Start with the 6.0 framework documentation.UsageErris now#[non_exhaustive], and file/shell failures have dedicated variants. Downstream exhaustive matches need a fallback arm.subcommand_requiredis now enforced by the reference parser. An invocation that previously slipped through without a required child command now fails as declared.flattendeclarations are emitted as reusableflagset/usenodes instead of duplicating flags under every command. The accepted command line is unchanged, but tools comparing serialized generated specs will see a structural change.--include-bash-completion-liband the corresponding Rust option were removed. Generated Bash scripts require bash-completion 2.11 or newer to be installed and sourced; the scripts now diagnose a missing library clearly.usage-libusers should declare the features they actually use.For clap adopters, the
usage-rsmigration guide documents the mechanical derive mapping, known compatibility gaps, and intentional boundaries around runtime builders andArgMatches.Everything else
This release spans 347 commits and 500 changed files. The curated notes above are the practical overview; the full changelog retains every feature, fix, performance change, and pull request, and the complete comparison is available on GitHub.
v5.1.0: : Embed specs from strings, cleaner include metadataCompare Source
A small feature release: embedders get a string-based script parser, included specs stop clobbering their parent's inferred metadata, and the test suite finally runs cleanly on Windows.
Added
Parse embedded USAGE comments from a string (#782 by @jdx). The new
Spec::parse_script_strlets embedders turn a script body into aSpecwithout writing to a temp file or hand-deserializing KDL:Because there's no source path,
bin/nameare not inferred from a filename and relativeincludepaths are rejected withrelative includes require a source file; absolute includes still work. The file-basedparse_scriptnow shares the same internal path, so behavior stays consistent.Fixed
parse_filederives a missingbin(and thenname) from the filename — butincludewas going through the same path, so an empty included fragment would take on its own filename and overwrite the parent spec, producing a spuriousmissing-cmd-help. Filename-based inference is now limited to the top-level spec; explicit metadata in includes still merges as before. The unreachablemissing-namelint (which fired for stdin but never for files) was also removed so file and stdin linting behave the same way. Closes #784 and #785.Changed
# USAGE:and// USAGE:; the real supported markers are#USAGE,//USAGE,::USAGE, and their[USAGE]variants.rmcpto v3 (#780 by @renovate). Tracks the MCP 2026-07-28 protocol revision.Tests
bash.execheerfully answers--versionand then fails everything else), routes fixture invocations throughUSAGE_SHELL_<SHELL>, normalizes paths handed to shell script bodies and$PATH, and removes the#![cfg(unix)]gate onshell_override.rs— which held back the very tests for the Windows-facingUSAGE_SHELL_<SHELL>feature added in v5.0.0. Result on awindows-latestrunner: 538 passed, 0 skipped. No library or CLI source is touched.Full Changelog: jdx/usage@v5.0.0...v5.1.0
💚 Sponsor usage
usage is maintained by @jdx, an open source developer for entire.io, the title sponsor of the jdx.dev open source tools including mise, aube, hk, and more. Work on usage is funded by sponsorships.
If
usagepowers CLI specs, docs, or completions for a tool you maintain or use, please consider sponsoring at jdx.dev. Every sponsorship helps the project stay independent and moving.v5.0.0: : Double-dash routing and Windows shell fixesCompare Source
A parser-level fix that makes
double_dash="required"actually behave as declared drives the major bump: values before--are now rejected, and values after--are routed past greedy variadics to the arg that was waiting for them. The release also fixes a cluster of long-standing Windows problems —usage bashlosing everyusage_*variable under WSL,run=scripts being handed tocmd /c, and completion guards being fooled by a shell function namedusage— and letsgenerate markdownwrite to stdout like the other generators.Added
Override the shell binary with
USAGE_SHELL_<SHELL>(#767 by @JamBalaya56562). Pointusage bash,usage zsh,usage fish, andusage powershellat a specific interpreter — mainly so Windows users can escape the WSLbash.exethat Win32's search order picks up ahead of$PATH:The variable is keyed by the program (so
powershell's override isUSAGE_SHELL_PWSH). Unset, empty, or whitespace-only falls back to the default. Spawn failures now name the program that was tried and the variable it came from, and on Windows abashexit 127 against a drive-letter path prints a hint pointing at this override.generate markdownwrites to stdout (#766 by @JamBalaya56562).--out-fileis now optional and defaults to stdout, matchingmanpage,fig,json, andcompletion.--out-file -also means stdout onmarkdown,manpage, andfig, mirroring the-f -input convention. Thewriting to …progress line moved to stderr onmarkdown,manpage,fig, andsdk, so it no longer ends up inside the generated document.--out-dirnow requires--multi.Fixed
double_dash="required"is now enforced on both sides (#762 by @JamBalaya56562). The parser previously ignoredSpecDoubleDashChoices::Requiredentirely — a word offered to such an arg without--was accepted anyway, and a required arg sitting behind a greedy variadic was unreachable even with a separator. Now offering a value before--is reported asArgRequiresDoubleDash(once per variadic, not once per word), and an explicit--routes the positional cursor onto the arg that required it, past earlier args. Completion learns about--too: while an arg is locked behind a separator,--itself is offered rather than values the parser would reject.Windows:
usage_*variables reach WSL bash (#764 by @JamBalaya56562). On Windows thebashpicked up from the system directory is WSL's launcher, and WSL only forwards a Win32 variable whenWSLENVnames it — so scripts saw everyusage_*value unset. Bothshellandexecnow append the parsed argument names toWSLENV(bare, no/por/lflags), preserving any entries the user had already configured.Windows:
run=scripts useshwhen available (#765 by @JamBalaya56562).complete run=already usedsh -ceverywhere, butmount run=usedcmd /con Windows, so the same POSIX one-liner behaved differently depending on which KDL node it lived in — and shebang scripts silently exited 0 with empty output. Both call sites now share one implementation:sh -cfirst, falling back tocmd /conly ifshis not found. Non-UTF-8 output from either shell is now reported as an error instead of panicking.Bash/fish completion guard ignores shell functions (#760 by @JamBalaya56562). The generated completion opens with a guard that bails out when the
usageCLI is not installed, buttype -preturns exit 0 for a shell function, so any environment defining ausagefunction (e.g. oh-my-bash) passed the guard and then failed further down with an unrelated error. Switched totype -Pin both bash guards and the fish equivalent; zsh'stype -palready forces a$PATHsearch and is unchanged.Breaking Changes
double_dash="required"positional args now reject values before--(#762). Specs where such an arg previously happened to work without a separator will now error. Inexamples/mise.usage.kdl, post---values also move from the preceding greedy variadic to the arg that declared the separator (e.g. fromTASK_ARGStoTASK_ARGS_LAST, fromTOOL@VERSIONtoCOMMANDunderexec), which changes whichusage_*variable a consumer reads. Spec authors who want the old permissiveness can drop back todouble_dash="optional"(the default).UsageErrandParseOutputgained fields.UsageErrhas a newArgRequiresDoubleDashvariant, andParseOutputgainednext_arganddouble_dash_seen. Library consumers matching these types exhaustively will need to update.Full Changelog: jdx/usage@v4.1.0...v5.0.0
💚 Sponsor usage
usage is maintained by @jdx, an open source developer for entire.io, the title sponsor of the jdx.dev open source tools including mise, aube, hk, and more. Work on usage is funded by sponsorships.
If
usagepowers CLI specs, docs, or completions for a tool you maintain or use, please consider sponsoring at jdx.dev. Every sponsorship helps the project stay independent and moving.v4.1.0: : MCP server, repository metadata, and self-declared effectsCompare Source
Puts the
effect=work from 4.0 to use: a newusage mcpserver lets agents read command effects locally over stdio, the CLI declares effects for its own commands, and specs gain arepositoryfield so consumers away from the checkout can find the source.Added
usage mcp— serve a spec to an agent over stdio (#746 by @jdx). A local Model Context Protocol server that speaks JSON-RPC 2.0 over newline-delimited stdio, so an agent can ask what a command does before running it. Load a spec with-for-s(stdin is the transport, so--file -is rejected):Two tools:
list_commands— the command tree, each entry tagged with its effectdescribe_command— one command's help, flags, arguments, and the effect of eachEffect is reported as an attribute alongside
helpandaliases; an unset effect staysnullrather than defaulting to something reassuring, and the serverinstructionstell the client that a missing effect means ask. Hidden commands are excluded from listings by default, withinclude_hiddento opt back in. This is the first consumer of theeffect=metadata now declared across roughly 385 commands in mise, hk, pitchfork, aube, and communique.repositoryfield on the spec (#747 by @jdx). A plain top-level URL, mirroring whatCargo.toml,package.json, orpyproject.tomlcarry — declared as arepository "..."node at the top of a spec. Distinct fromsource_code_link_template(which is a per-command deep link with a{{path}}placeholder). Anything reading a spec away from its checkout — usage.sh, a registry, an agent handed a.usage.kdl— previously had no way back to the project it described. Round-trips through parse, merge, serialize, and template rendering.usageCLI declares its own effects (#751 by @jdx). Every command is now classified: mostgeneratesubcommands areread, with--out-file/--out-dirraising them towrite;generate sdkiswriteat the command level (its output flag is required). Script runners (bash,fish,zsh,powershell,exec) are deliberately unclassified — their effect is whatever the user's script does — and a test asserts every unclassified command has an entry inUNCLASSIFIEDwith a reason. Also emitsmin_usage_version "4.0"so an olderusagedoesn't silently drop the annotation.clap_usage::spec()(#743 by @jdx). Returns theSpecderived from aclap::Command(withbinalready set), so callers can annotate it before rendering:generate()now delegates tospec()plus twowriteln!s; a test asserts its output is byte-identical.usage::available_flagsis public (#746 by @jdx), so consumers can enumerate flags the same way the parser does — respecting global merge and re-declaration rules.Fixed
Re-declared globals keep their aliases on one flag (#752 by @jdx). A global like
flag "-y --yes" global=#truere-declared non-globally by a subcommand (optionally adding a third alias, e.g.-y --yes --assume-yes) could leave-yand--yespointing at two differentArc<SpecFlag>objects, with the-yview missing the new alias. The collision guard now compares flag origins rather thanArcidentity, and rebinds every existing alias for the global to the merged flag on first merge.Completions for repeated variadic args (#753 by @Jai-JAP).
complete-wordcounted parsed positional entries to pick which arg to complete next, but variadic values all collapse into one entry — so after the first value, completion fell through to files. It now checks the parsed value per positional and keeps using the variadic arg's completer untilvar_maxis reached.Changed
clap_usagerepublished as 4.0.0 (#743 by @jdx). crates.io still shippedclap_usage2.0.3, pinned tousage-lib ^2.0.3, because its source hadn't changed since — blocking downstream crates from adoptingeffect=. It now tracksusage-lib's major, and thespec()addition means dependents no longer have to inlinegenerate()and depend onusage-libdirectly.New Contributors
Full Changelog: jdx/usage@v4.0.0...v4.1.0
💚 Sponsor usage
usage is maintained by @jdx, an open source developer for entire.io, the title sponsor of the jdx.dev open source tools including mise, aube, hk, and more. Work on usage is funded by sponsorships.
If
usagepowers CLI specs, docs, or completions for a tool you maintain or use, please consider sponsoring at jdx.dev. Every sponsorship helps the project stay independent and moving.v4.0.0: : effect= on flags and argsCompare Source
Extends the
effect=annotation from commands down to individual flags and arguments, so specs can express commands whose danger depends on how they are invoked.Added
effect=on flags and args (#742 by @jdx). A command's danger often depends on how it is invoked:pitchfork logsreads,pitchfork logs --cleardeletes;mise settings fooreads,mise settings foo=barwrites. Flags and args can now carry the sameeffect=annotation that #739 introduced on commands:The rule: the effect of an invocation is the maximum of the command's effect and the effect of every flag and argument actually supplied.
SpecCommandEffectnow implementsOrd(read<write<destructive) so the maximum is well defined. Two helpers:SpecCommand::effect_of(flags, args)— for a consumer that parsed the command line.SpecCommand::max_effect()— the pessimistic bound across every declared flag and arg, for one that didn't.Effects only ever raise, never lower.
--dry-runis deliberately not supported: a bug in a dry-run path would otherwise produce a spec that claims a command is safe when it isn't. Because the rule is monotonic, a consumer that can't parse the invocation can safely fall back tomax_effect()and degrade to today's behavior — which is what makes this additive rather than a semantics break on the wire.Accepted as either a prop (
effect="write") or a child node (effect "write"); unknown values are a parse error with a span. Generated markdown now renders an**Effect**:line beneath each flag that declares one. Most flags should declare nothing — this is for the handful that change what a command does to the world, not an annotation for every option.New builder and constructor helpers (#742 by @jdx).
SpecFlagBuilderandSpecArgBuildergain.effect(...),.usage(...), and.help_first_line(...).SpecExample,SpecComplete,SpecConfig,SpecConfigProp, andSpecMountall gain a public::newand chaining setters, so they can be constructed from outside the crate.Breaking Changes
SpecArg,SpecFlag,SpecExample,SpecComplete,SpecChoices,SpecConfig,SpecConfigProp, andSpecMountare now marked#[non_exhaustive]. Any code that built one of these types with a struct literal outsideusage-libwill no longer compile. Use the builders (SpecFlag::builder(),SpecArg::builder()) or the new::newhelpers instead; existing field access is unaffected.Full Changelog: jdx/usage@v3.6.0...v4.0.0
💚 Sponsor usage
usage is maintained by @jdx, an open source developer for entire.io, the title sponsor of the jdx.dev open source tools including mise, aube, hk, and more. Work on usage is funded by sponsorships.
If
usagepowers CLI specs, docs, or completions for a tool you maintain or use, please consider sponsoring at jdx.dev. Every sponsorship helps the project stay independent and moving.v3.6.0: : effect= and four silent SpecCommand bugsCompare Source
Adds an
effect=annotation for classifying command side effects, and fixes four latentSpecCommandbugs uncovered while auditing the code paths a new field has to touch.Added
effect=on commands (#739 by @jdx). Declare what running a command does to the world so docs, wrapper scripts, and AI agent allowlists can consume the same annotation instead of hand-maintaining their own lists:readwritedestructiveAccepted as either a prop (
effect="read") or a child node (effect "read"); unknown values are a parse error. The field is not inherited by subcommands (git remoteandgit remote removedo different things), and unset means unknown, not safe — consumers should treat missing values as "ask". Round-trips through KDL and renders an- **Effect**:line in generated markdown. Exported asusage::SpecCommandEffect.Fixed
Four silent gaps in
SpecCommandhandling, all found by auditing every field againstmerge, the KDL serializer, and the docs model (#740 by @jdx):deprecatedwas dropped bymerge. An included spec could silently un-deprecate a command.exampleswere never written by the KDL serializer.spec.to_string()dropped every example.help_md/before_help_md/after_help_mdwere accepted only as props but serialized as child nodes. Any spec with markdown help failed to reparse withError: unsupported cmd key help_md. They are now accepted as child nodes as well.restart_tokennever reached the docs model, so no template could render it.Changed
SpecCommandfields are now a compile error (#740).mergeand bothFromimpls destructure their source with no.., so adding a field produces three compile errors pointing at exactly the places that owe it a decision. Runtime-derived fields are bound with aNOTEcomment. A new round-trip test parses a spec exercising every field, serializes, reparses, and compares serde representations — catching the class of bug where the serializer writes something the parser rejects (which is how thehelp_mdregression survived).Full Changelog: jdx/usage@v3.5.7...v3.6.0
💚 Sponsor usage
usage is maintained by @jdx, an open source developer for entire.io, the title sponsor of the jdx.dev open source tools including mise, aube, hk, and more. Work on usage is funded by sponsorships.
If
usagepowers CLI specs, docs, or completions for a tool you maintain or use, please consider sponsoring at jdx.dev. Every sponsorship helps the project stay independent and moving.v3.5.7: : Mounted commands stop leaking mounting-CLI flagsCompare Source
A parser fix for shell completions inside mounted commands. Addresses jdx/mise#11282, where the mounting CLI's global flags leaked into mounted task completions and non-global flags before a task hid the task from the parser.
Fixed
Mounted commands no longer inherit the mounting CLI's flags (#738). Three related defects in how the partial-parse's subcommand scan and re-parse interact with
mount:Globals leaked into mounted commands. For a CLI like mise, where everything after a task name is forwarded to the task,
mise run mytask --<TAB>used to offer--cd --env --jobs --locked --quiet --raw --silent --verbose --yeseven though the mounted program rejects them (unexpected word: --silent). Worse, when a mounted task declared a flag whose name collided with a global (e.g. its own--envwith choices), the global shadowed it and value completion fell back to file paths instead of the task's choices. Mounted commands are now marked internally and their own flags take precedence over inherited globals for their own names; a newParseOutput::completion_flags()returns just the flags a completion should offer once a mount boundary has been crossed. Globals stay recognized before the mounted command, and mount scripts still receive them.A non-global flag hid the subcommand behind it. Phase 1 stopped scanning at the first non-global flag, so
usage complete-word ... -- mise run --force build --bump ''failed withunexpected word: build. Known non-global flags are now consumed like globals and the scan continues; they are simply not forwarded to mounts. Unknown flags still stop the scan since their arity is unknown.Re-parsed prefix words could bind to the wrong flag. A global's value that appeared before a mounted command with a same-named flag would be re-validated against the mounted flag's choices and rejected. Phase 1 now records which flag each skipped word was read as, and Phase 2 respects that binding, so
mycli --env prod run task --env <TAB>still parses--env prodas the global and offers the task's--envchoices after the task name.Documentation for
globalflags and mounted commands has been added underdocs/spec/reference/.Full Changelog: jdx/usage@v3.5.6...v3.5.7
💚 Sponsor usage
usage is maintained by @jdx, an open source developer for entire.io, the title sponsor of the jdx.dev open source tools including mise, aube, hk, and more. Work on usage is funded by sponsorships.
If
usagepowers CLI specs, docs, or completions for a tool you maintain or use, please consider sponsoring at jdx.dev. Every sponsorship helps the project stay independent and moving.v3.5.6: : Private completion cache and Markdown code-block escapingCompare Source
A security-focused patch release that moves the shell-completion spec cache out of world-writable
/tmpinto a private per-user cache dir, plus a Markdown renderer fix that stops mangling<inside fenced code blocks.Fixed
Completion spec cache is no longer written to world-writable tmp (#727, fixes #722). The generated bash, zsh, fish, and nu completion scripts previously cached the usage spec at a predictable path under
${TMPDIR:-/tmp}. Because/tmpis typically world-writable and the filename is guessable, another local user could pre-plant a symlink there and have the completion script's>|/save -foverwrite an arbitrary file owned by the invoking user. Caches now live in a per-user directory created with mode700:${XDG_CACHE_HOME:-$HOME/.cache}/usage($env.XDG_CACHE_HOME? | default (home-dir | path join ".cache") | path join "usage")Because
~/.cachepersists across reboots (unlike/tmp), version-keyed cache files are now reaped on a cache miss if they haven't been regenerated in 30 days. The prune is age-based and scoped to the current bin, so running two versions of the same tool concurrently no longer thrashes the cache. Users who regenerate their completion scripts will pick up the fix; the cache location change is otherwise transparent.nu: completion cache dir permissions and nushell 0.110+ compatibility (#731). Nushell's builtin
mkdirhas no mode flag, so the initial fix in #727 created the nu cache dir at the process umask (usually755, world-readable). The generator now runs^chmod 0700on the dir at creation time (non-Windows only) to match bash/zsh/fish. Separately,$nu.home-pathwas renamed to$nu.home-dirin nushell 0.110.0, which broke the completer on any recent nushell even whenXDG_CACHE_HOMEwas set (becausedefault's argument is evaluated eagerly). The lookup now uses optional access with a fallback that works on both old and new nushell:markdown: preserve HTML inside fenced code blocks (#720) — thanks @risu729. The Markdown renderer's HTML-escape filter processed lines independently and would turn
<into<even inside multiline fenced code blocks, corrupting examples likeecho <value>. It now tracks fenced-block state across lines and leaves content between column-zero triple-backtick fences untouched, while still escaping<in surrounding prose. Addresses the escaping problem reported in jdx/mise#6949.cli: avoid trailing semicolon in macro expression position (#729). The two
miette::bail!("unsupported shell: ...")match arms incomplete_wordandusage_specwere wrapped in a block so the macro expands in statement position. This clears thesemicolon_in_expressions_from_macroslint that is already a hard error on nightly Rust. Runtime behavior is unchanged.lib: remove needless borrows in
format!args (#726) — minor cleanup for newer clippy.Full Changelog: jdx/usage@v3.5.5...v3.5.6
💚 Sponsor usage
usage is maintained by @jdx, an open source developer for entire.io, the title sponsor of the jdx.dev open source tools including mise, aube, hk, and more. Work on usage is funded by sponsorships.
If
usagepowers CLI specs, docs, or completions for a tool you maintain or use, please consider sponsoring at jdx.dev. Every sponsorship helps the project stay independent and moving.v3.5.5: : Hyphen-prefixed flag valuesCompare Source
A small patch release that lets value-taking flags accept hyphen-prefixed values (such as passthrough args to a wrapped CLI), plus a redesigned logo.
Fixed
parse: allow hyphen-prefixed flag values (#715, fixes #713). Flags that carry passthrough values (e.g. forwarding args to
terraform/terragrunt) previously lost values that started with-when the first letter collided with an existing short flag —./repro -a -destroywould tokenize-destroyas-d estroyand silently drop the intended value of-a. Value flags can now opt in viaallow_hyphen_values=#true, and the parser will consume the next-…token as that flag's value before short/long flag parsing kicks in:This works for
-a -destroy,--args=-destroy, and repeated variadic values like-a -val1 -a -val2. Flags without the opt-in keep their existing behavior. The built-inusage complete-word --cwordflag now sets this internally so negative cword indices parse correctly.Documentation
#​22c55e) swallowtail banner carrying the--flag prefix. All derived favicons and app icons were regenerated from the new vector source, and an SVG favicon is now served for browsers that support it.Full Changelog: jdx/usage@v3.5.4...v3.5.5
💚 Sponsor usage
usage is maintained by @jdx, an open source developer for entire.io, the title sponsor of the jdx.dev open source tools including mise, aube, hk, and more. Work on usage is funded by sponsorships.
If
usagepowers CLI specs, docs, or completions for a tool you maintain or use, please consider sponsoring at jdx.dev. Every sponsorship helps the project stay independent and moving.v3.5.4: : Quieter fish completionsCompare Source
A small patch release focused on fixing noisy fish shell startup for users with execute-only or setuid binaries on
$PATH, plus a Tera template engine upgrade that slightly tweaks generated docs and CLI help.Fixed
conf.dscript emitted byusage generate completion-init fishscans every executable on$PATHand peek-reads the first 128 bytes to detect ausageshebang. Files that are executable but not readable by the current user (such as macOS's setuid-rootsudoor execute-onlyvisudo) caused fish's own redirection layer to print a warning on every new shell — the existing2>/dev/nullonly silenced thereadbuiltin, not fish's redirection setup. Atest -r $file; or continueguard now skips those files before the read is attempted. Re-runusage generate completion-init fishand reload your shell to pick up the fix.Changed
usage generate markdownoutput and in theusageCLI help output. Previously they followed spec order.Full Changelog: jdx/usage@v3.5.3...v3.5.4
💚 Sponsor usage
usage is maintained by @jdx, an open source developer for entire.io, the title sponsor of the jdx.dev open source tools including mise, aube, hk, and more. Work on usage is funded by sponsorships.
If
usagepowers CLI specs, docs, or completions for a tool you maintain or use, please consider sponsoring at jdx.dev. Every sponsorship helps the project stay independent and moving.v3.5.3: : Zsh default completion and negated flag help fixesCompare Source
A small patch release with two fixes for the generated zsh completion init and CLI help rendering.
Fixed
zsh: preserve options for default completion (#693 by @jdx, fixes #692). The
_usage_default_completehandler emitted byusage generate completion-init zshcalledemulate -L zsh, which reset shell options before falling back to_filesfor non-usage commands. Withnomatchre-enabled, zsh treated internal tags like*:globbed-filesas real globs, producing errors such asno matches found: *:globbed-fileswhen completing things likeemacs <TAB>. The generated init now runssetopt localoptions nonomatch extendedglobimmediately afteremulate -L zsh, so the_filesfallback sees the option state it expects. Re-runusage generate completion-init zshand reload your shell to pick up the fix.docs: show negated flags in CLI help (#694 by @jdx). Boolean flags declared with a
negatealias previously rendered only the positive form inusageCLI help output. They now render as--flag / --no-flagin both short and long help, and the help column width is calculated from the displayed usage so descriptions stay aligned:Full Changelog: jdx/usage@v3.5.2...v3.5.3
💚 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
usagepowers 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.v3.5.2: : musl publish fixCompare Source
A patch release that restores publishing of the
x86_64-unknown-linux-muslprebuilt binary, which failed to upload in v3.5.1.Fixed
x86_64-unknown-linux-muslfailed withcan't find crate for 'core'aftercrossfell back to hostcargowithout the target installed. The publish workflow now runsrustup target add ${{ matrix.target }}for each matrix entry (skipping the syntheticuniversal-apple-darwintarget) before invokingupload-rust-binary-action, so musl and other non-default triples build and upload reliably.Full Changelog: jdx/usage@v3.5.1...v3.5.2
💚 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
usagepowers 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.v3.5.0: : Type-Safe SDKs and Zsh Colon FixesCompare Source
This release introduces
usage generate sdk— type-safe subprocess-wrapper SDKs for TypeScript and Python derived from a usage spec — and fixes two zsh completion bugs around colons in subcommand and value names that were biting mise users.Added
usage generate sdkfor TypeScript and Python (#623 by @gaojunran). A new generator emits a type-safe SDK client for any usage-described CLI. The SDK is a subprocess wrapper — not a native binding — so it works for any binary on$PATH, with typed args, flags, and choice-constrained values instead of stringly-typedsubprocess.run/spawncalls.Each generated SDK has three pieces: a types module (dataclasses / interfaces, with
Literal/ union types for choices and global flags propagated to every subcommand), a client module mirroring the subcommand tree withexec()methods that build the argv list, and a small runtime module wrappingsubprocess.run/child_process.spawn. See the SDK generation guide for the full walkthrough. Rust support is planned.usage sponsorscommand and docs sponsor block (#662, #608, #656). The new top-levelusage sponsorscommand and a sponsor strip on the docs site acknowledge 37signals and link to the canonical en.dev sponsor pages. A dedicated/sponsorsdocs page lists tiers fetched live fromen.dev/sponsors.json.More CLI-framework integration guides (#655, #667 by @gaojunran). The docs now cover using usage alongside JCommander, picocli, and Clikt (Java/Kotlin) and urfave/cli and Kong (Go), joining the earlier Commander.js / oclif / yargs / Typer / Click guides.
Fixed
_describegroups matches that share a\:-escaped prefix and surfaces only one entry per group, so a spec withrelease:create,release:docs-sync,release:pr, andrelease:updatewould only ever showrelease:createin the menu. The completion now builds its own display column and callscompadddirectly so every match isConfiguration
📅 Schedule: (UTC)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.