Skip to content

feat(derive): say three things about a CLI the spec could and the derive could not - #853

Merged
jdx merged 2 commits into
mainfrom
agent/faithful-metadata
Aug 13, 2026
Merged

feat(derive): say three things about a CLI the spec could and the derive could not#853
jdx merged 2 commits into
mainfrom
agent/faithful-metadata

Conversation

@jdx

@jdx jdx commented Aug 13, 2026

Copy link
Copy Markdown
Owner

Found by rendering mise's help from the shadow's metadata and diffing every line against
usage-lib's. 23 of 211 differed, and every difference traced back to something mise's KDL
declared, the derive had no vocabulary for, and gen-shadow dropped without counting.
That last part is what made them invisible: the dropped-property report exists to prevent
exactly this, and it was reporting nothing.

value_name — the placeholder for a flag's value. FlagMeta had the field and the KDL
writer already read it; nothing could set it. So a spec saying --tool <TOOL> came back
saying --tool <tool>, because the flag's own name was all that was left. 211 of mise's
flags carry one.

required on a collecting argument — <TARGET>…, meaning one or more. Required-ness is
normally the type's to say, and a Vec cannot: it has no bare-versus-Option shape. This is
the one place it is declared rather than inferred, and it is refused anywhere the type
already answers the question, in either direction.

var on a counted flag — inferred rather than declared, because a count is repetition:
-vvv is three occurrences and counting them is the point. Left out, the emitted spec said
count without var where mise's says both.

These matter past help text. The emitted spec is what docs, manpages, completions and the SDK
generators read, so a property that cannot survive the round trip is one every downstream
consumer is wrong about.

gen-shadow emits all three now, and the report for the usage dialect drops from six kinds
of loss to three — the remaining ones being genuine gaps with nothing yet to express them.

Co-Authored-By: Claude Opus 5 noreply@anthropic.com


Stack created with GitHub Stacks CLIGive Feedback 💬


Note

Medium Risk
Touches derive parsing, post-bind validation, and shadow codegen across the full mise CLI surface; behavior changes for empty required collections and help/spec placeholders, but bounded by new tests and spec diffing.

Overview
Closes three spec→derive gaps that were silently dropped by gen-shadow (and invisible in the drop report): flag value placeholders, one-or-more collections, and repeatability on counted flags.

value_name on value-taking flags so help/spec show --tool <TOOL> instead of defaulting to the flag name. required on Vec positionals and collecting flags so <TARGET>… is enforced at parse time and in emitted KDL, aligned with metadata via a single required expression. var is inferred for count flags (and plain repeatable valueless flags get var in shadow gen) so -vvv matches the reference spec.

gen-shadow now emits these attributes; the mise shadow gains widespread value_name / required annotations. Compile-time validation rejects contradictory uses (required on Option/bare types, value_name on positionals or valueless flags, required vs required_if/Option<Vec>). Conformance tests cover metadata and required-collection parsing; PLAN.md marks the milestone done.

Reviewed by Cursor Bugbot for commit 93b378f. Bugbot is set up for automated code reviews on this repo. Configure here.

How these were found

By starting the next item — help rendering — and immediately checking it against the
reference: render mise's usage line from the shadow's metadata, compare all 211 against
usage-lib's. 23 differed, and every one traced back to something mise's KDL declared, the
derive had no vocabulary for, and gen-shadow dropped without counting it.

That last part is the real finding. The dropped-property report exists so the shadow can never
look like a faithful translation of a spec it cannot represent — and for these three it was
reporting nothing at all.

mise config get   [-f --file <file>] [KEY]   ← ours
                  [-f --file <FILE>] [KEY]   ← usage-lib

mise deps remove  [PACKAGES]…               ← ours
                  <PACKAGES>…               ← usage-lib

mise cache prune  [-v --verbose]            ← ours
                  [-v --verbose…]           ← usage-lib

The three

what it is why the derive could not say it
value_name the placeholder for a flag's value FlagMeta had the field and the KDL writer already read it — nothing could set it, so the flag's own name stood in
required on a collection <TARGET>…, one or more required-ness is the type's to say, and a Vec has no bare-versus-Option shape to say it with
var on a counted flag that it may be given again now inferred, not declared: a count is repetition — -vvv is three occurrences

required is refused anywhere the type already answers the question, in either direction — on
an Option it contradicts, on a bare type it is redundant, and a declaration that changes
nothing is one someone will eventually trust.

Why it matters past help text

The emitted spec is what docs, manpages, completions and the SDK generators read. A property
that cannot survive the round trip is one every downstream consumer is wrong about — which is
also why the fix belongs here rather than in the renderer.

The usage dialect's dropped-property report goes from six kinds of loss to three, and the three
that remain are genuine gaps with nothing yet to express them.

Verification

  • Four tests on a CLI declaring all three, asserting each reaches the parsed-back spec.
  • All three mutation-checked: reverting each fix fails exactly its own test.
  • Two refusal tests for required in the places the type already answers.
  • mise run gen-shadow regenerated; 211 value names and 16 required markers now survive.

AI-assisted — Tool: Claude Code; model: anthropic/claude-opus-5; version: unavailable.

Summary by CodeRabbit

  • New Features

    • Generated CLI help and completion metadata now preserve explicit value names.
    • Required variadic arguments and collections are represented accurately.
    • Counted and repeatable flags now expose correct repeatability metadata.
    • Generated specifications better reflect command usage with required markers and value placeholders.
  • Bug Fixes

    • Fixed discrepancies between generated specifications and rendered help output.
    • Improved metadata handling for flags, collections, flattened fields, and subcommands.
    • Added validation for unsupported or conflicting argument metadata.

@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: fd3316ed-e093-465b-8f31-d83ea13a806a

📥 Commits

Reviewing files that changed from the base of the PR and between 93ab605 and 93b378f.

📒 Files selected for processing (1)
  • derive/src/model.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • derive/src/model.rs

📝 Walkthrough

Walkthrough

The derive model now preserves value names, required collection metadata, and counted-flag repeatability. Code generation and shadow generation emit these semantics. The mise shadow and conformance tests update and validate the resulting metadata.

Changes

Metadata parity

Layer / File(s) Summary
Derive metadata model and code generation
derive/src/model.rs, derive/src/codegen.rs
The derive model parses and validates value_name and collection required attributes. Code generation emits value names and required metadata. Count flags now infer repeatability.
Usage shadow metadata generation
xtask/src/shadow.rs
Shadow generation preserves repeatability for valueless flags, omits redundant value names, and emits required for required collecting arguments.
Generated shadow updates and conformance coverage
benches/shadows/mise/src/lib.rs, conformance/tests/metadata.rs, conformance/tests/derive.rs, PLAN.md
The mise shadow adds value labels and required positionals. Conformance tests verify value-name preservation, counted-flag repetition, required collections, KDL output, parsing, and argument binding. The plan records the completed parity milestone.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Mergeability Score: ⚪ Minimal · up to 93b37

This PR updates CLI metadata propagation, collection validation, and the generated shadow; no actionable merge-blocking risk remains beyond normal checks and review.

Sequence Diagram(s)

sequenceDiagram
  participant CliDeclaration
  participant DeriveModel
  participant Codegen
  participant ShadowGenerator
  participant ConformanceTests
  CliDeclaration->>DeriveModel: Provide value_name and required attributes
  DeriveModel->>Codegen: Provide validated field metadata
  Codegen->>ShadowGenerator: Provide generated argument metadata
  ShadowGenerator->>ConformanceTests: Produce shadow usage metadata
  ConformanceTests->>ConformanceTests: Verify value names, repeatability, required collections, and binding
Loading

Possibly related PRs

  • jdx/usage#799: Related flag repeatability and variadic parsing semantics.
  • jdx/usage#801: Related CLI usage-spec metadata and KDL generation.
  • jdx/usage#803: Related derive model, code generation, and conformance paths.

Poem

A rabbit names each flag with care,
And counts the values gathered there.
Required bundles stand in line,
While shadow specs preserve each sign.
The tests confirm the meanings match—
Hop, hop, metadata is intact!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the derive feature and summarizes the three metadata capabilities added by the changes.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment thread derive/src/codegen.rs
@greptile-apps

greptile-apps Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR closes metadata round-trip gaps for flag value placeholders, required collections, and repeatable counted flags.

  • Adds and validates value_name and required-collection derive attributes.
  • Aligns required-collection runtime checks with emitted metadata.
  • Updates shadow generation and adds conformance coverage.
  • Regenerates the mise shadow with preserved metadata.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
derive/src/model.rs Adds attribute parsing and validation for required collections and value placeholders; the two previously reported cases are now rejected or preserved correctly.
derive/src/codegen.rs Emits value names and required-collection metadata and enforces required collections during post-binding validation.
xtask/src/shadow.rs Preserves value names, required variadic collections, and repeatability when generating derive shadows.
conformance/tests/derive.rs Verifies that absent required collections fail at runtime while populated collections still bind normally.
conformance/tests/metadata.rs Covers round-trip metadata for value names, counted flags, and required collecting arguments.
benches/shadows/mise/src/lib.rs Regenerates the mise shadow with the newly supported metadata attributes.

Fix All in Greploop

Reviews (5): Last reviewed commit: "fix(derive): enforce what the metadata p..." | Re-trigger Greptile

Comment thread derive/src/model.rs
Comment thread derive/src/model.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@derive/src/model.rs`:
- Around line 775-776: Update the metadata parsing logic surrounding the
"value_name" match arm in the derive implementation to reject value_name unless
the argument is a value-taking flag, excluding positional arguments and
valueless bool/count flags. Return an appropriate validation error instead of
accepting and dropping unsupported metadata, while preserving the existing
assignment for valid flags.

In `@xtask/src/shadow.rs`:
- Around line 579-592: Update the flag-option generation path around the
existing var and value_name handling to emit required for value-taking
collecting flags when flag.required is true, so generated repeatable or variadic
values remain mandatory and render as <VALUE>… rather than [VALUE]…. Preserve
the existing valueless-flag required handling, and add a generator regression
test covering a required repeatable/variadic value flag.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 14b0088d-027c-458a-98cf-724d4de13012

📥 Commits

Reviewing files that changed from the base of the PR and between ebea895 and b286dc6.

📒 Files selected for processing (6)
  • PLAN.md
  • benches/shadows/mise/src/lib.rs
  • conformance/tests/metadata.rs
  • derive/src/codegen.rs
  • derive/src/model.rs
  • xtask/src/shadow.rs

Comment thread derive/src/model.rs
Comment thread xtask/src/shadow.rs
@github-actions

github-actions Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Instruction counts

benchmark trend instructions Δ wall (min) Δ
markdown ▁▁▁▁▁▂▂▂██ 175,245,063 → 175,128,082 -0.07% 16.93 → 17.91ms +5.74%
startup ▁▁▁▁▁▁▁▁██ 1,222,129 → 1,222,033 -0.01% 1.00 → 1.05ms +5.26%

No instruction-count regression above 1%.

Only instruction counts gate. Wall clock is shown for context — on identical hardware it moves 4-20% run to run.

Measured by tak — instruction-counted CLI benchmarks, stored in this repository's git notes.

Shadow comparison

Parsing mise use -g node@20 against a shadow of mise's committed spec.
Reported, not gated: the shadow grows as the derive learns to express more, so
what to watch is the ratio rather than either column.

usage clap ratio
instructions, cold parse 29823 5962046 199x
usage: argv -> struct                             872 ns      0.87 µs
clap: build tree + parse -> struct             511231 ns    511.23 µs
clap: parse -> struct, tree reused              23681 ns     23.68 µs
clap: build tree only                          314532 ns    314.53 µs

93b378f7fae8 vs fe13b0b9c7d8 · measured on the runner, not pushed to the history.

jdx commented Aug 13, 2026

Copy link
Copy Markdown
Owner Author

Three findings, all real and all the same shape — a declaration written down, emitted into the spec, and then not honoured.

required on a collection was documentation only (Bugbot, Greptile). The required check looked at the field's shape, and a Vec has the same shape whether or not it declared required — so the spec, the help, the manpage and the completions all said one-or-more while the CLI that ran accepted none. It now uses the same expression the metadata is built from:

if !(f.shape == Shape::Required || f.required_collection) || f.default.is_some() {

That is deliberately the identical expression to the one at the two *_meta sites: one expression cannot disagree with itself.

value_name was accepted where nothing could show it (Greptile, CodeRabbit — same finding). It names the placeholder a flag's value gets in help; arg_meta never emits it and a bool/count flag has no placeholder, so on a positional or a valueless flag the declaration compiled and was dropped. Refused now, with a message that says what to use instead — name for a positional.

The shadow generator dropped required from a collecting flag (CodeRabbit). A scalar flag says required by typeString rather than Option<String> — and a Vec has no such spelling, so required is the only way to say it. Without emitting it, a spec demanding one-or-more values became a shadow accepting none, whose regenerated spec read [VALUE]… where the source said . Note this one depends on the first fix: emitting required there is only honest now that the derive enforces it, which is why they belong in the same commit.

Each has a test in the layer that owns the behaviour — parse-time in the conformance suite, attribute validation in the model's own tests, generator output in the shadow's — and each test is checked against a reverted fix.

AI-assisted — Tool: Claude Code; model: anthropic/claude-opus-5; version: unavailable.

Comment thread derive/src/codegen.rs
Comment thread derive/src/codegen.rs

jdx commented Aug 13, 2026

Copy link
Copy Markdown
Owner Author

Both real, and both the same thing as the first round: a declaration that compiles and cannot mean what it says. Refused now, beside the value_name check.

required beside required_if/required_unless. required on a collection means one or more values always, and the check for it runs unconditionally — so a sibling condition was accepted, emitted into the spec, and never consulted. For a scalar the two cannot meet: required_unless needs somewhere to put "absent" and so only goes on an Option. A collection has no type to keep them apart, so validation does.

required on an Option<Vec<_>>. Shaped like any other collection, so it was accepted — after which the field can never be None and the Option means nothing at all.

`required` on a collection means one or more values, always, but
`required_if` says it is required only sometimes

Three cases tested, three mutations, and a fourth assertion that a plain #[usage(long, required)] Vec<String> still compiles — which is the thing the refusals are protecting.

AI-assisted — Tool: Claude Code; model: anthropic/claude-opus-5; version: unavailable.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 93ab605. Configure here.

Comment thread derive/src/model.rs Outdated
@jdx
jdx force-pushed the agent/faithful-metadata branch from 93ab605 to bc5db30 Compare August 13, 2026 14:52

jdx commented Aug 13, 2026

Copy link
Copy Markdown
Owner Author

Fixed. A line continuation had lost its backslash, so the one message that tells an author what a field accepts had a long run of spaces through the middle of it. The test asserts the absence of a double space rather than the exact list, so it stays true as options are added.

AI-assisted — Tool: Claude Code; model: anthropic/claude-opus-5; version: unavailable.

jdx and others added 2 commits August 13, 2026 16:17
…ive could not

Found by rendering mise's help from the shadow's metadata and diffing every line against
usage-lib's. 23 of 211 differed, and every difference traced back to something mise's KDL
declared, the derive had no vocabulary for, and `gen-shadow` dropped **without counting**.
That last part is what made them invisible: the dropped-property report exists to prevent
exactly this, and it was reporting nothing.

`value_name` — the placeholder for a flag's value. `FlagMeta` had the field and the KDL
writer already read it; nothing could set it. So a spec saying `--tool <TOOL>` came back
saying `--tool <tool>`, because the flag's own name was all that was left. 211 of mise's
flags carry one.

`required` on a collecting argument — `<TARGET>…`, meaning one or more. Required-ness is
normally the type's to say, and a `Vec` cannot: it has no bare-versus-`Option` shape. This is
the one place it is declared rather than inferred, and it is refused anywhere the type
already answers the question, in either direction.

`var` on a counted flag — inferred rather than declared, because a count *is* repetition:
`-vvv` is three occurrences and counting them is the point. Left out, the emitted spec said
`count` without `var` where mise's says both.

These matter past help text. The emitted spec is what docs, manpages, completions and the SDK
generators read, so a property that cannot survive the round trip is one every downstream
consumer is wrong about.

`gen-shadow` emits all three now, and the report for the usage dialect drops from six kinds
of loss to three — the remaining ones being genuine gaps with nothing yet to express them.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Three findings from review, all the same shape: a declaration that was written
down, emitted into the spec, and then not honoured.

**`required` on a collection was documentation only.** The required check looked
at the field's *shape*, and a `Vec` has the same shape whether or not it declared
`required` — so the spec, the help, the manpage and the completions all said
one-or-more while the CLI that ran accepted none. It now uses the same
expression the metadata is built from, which is the point: one expression cannot
disagree with itself.

**`value_name` was accepted where nothing could show it.** It names the
placeholder a flag's *value* gets in help. `arg_meta` never emits it, and a
`bool` or `count` flag has no placeholder — so on a positional or a valueless
flag the declaration compiled and was dropped, reading as though it had done
something. Refused now, with a message saying what to use instead.

**The shadow generator dropped `required` from a collecting flag.** A scalar
flag says required by type — `String` rather than `Option<String>` — and a `Vec`
has no such spelling, so `required` is the only way to say it. Without emitting
it, a spec demanding one-or-more values became a shadow accepting none, whose
regenerated spec described `[VALUE]…` where the source said `…`. This depends on
the first fix: emitting `required` there is only honest now that the derive
enforces it.

Each has a test, and each test is checked against a reverted fix.
@jdx
jdx force-pushed the agent/faithful-metadata branch from bc5db30 to 93b378f Compare August 13, 2026 16:17

jdx commented Aug 13, 2026

Copy link
Copy Markdown
Owner Author

All addressed, though two of them twice over — another session was fixing the same findings in parallel, and reconciling the two is most of what this took.

Required collection not enforced (High) — real, and fixed: required_checks now keys off the same expression the metadata is built from (shape == Required || required_collection), so the spec and the parser cannot disagree about it. One expression cannot contradict itself.

Required ignores conditional exceptions / Required allowed on Option<Vec> (Medium ×2) — both real. required on a collection means one or more values always, so it contradicts required_if, required_unless, and Option<Vec<_>> — each of which says absence is representable. All three refused at the declaration now.

value_name silently discarded and required not preserved for collecting flags in the generator — both fixed, with a generator regression test for the second.

Malformed unknown-option error text (Low) — the run of spaces was a stray line continuation, already gone.

One thing worth recording: the parallel fixes collided. Both sessions added a guard refusing the self-contradicting required; mine ran first and its wording did not match the test the other had written, and the reconciliation then dropped the other rule — refusing required where the type already answers — while keeping its variables. clippy caught the orphans (assigned but never used), and the test caught the missing rule. Both are back, and the duplicate guard is gone.

AI-assisted — Tool: Claude Code; model: anthropic/claude-opus-5; version: unavailable.

@jdx
jdx merged commit 8a76889 into main Aug 13, 2026
9 checks passed
@jdx
jdx deleted the agent/faithful-metadata branch August 13, 2026 20:18
jdx added a commit that referenced this pull request Aug 13, 2026
`Usage: mise use [OPTIONS] <TOOL@VERSION>…` — the line at the top of
`--help`, and the first
thing a CLI framework has to be able to produce. Built from the same
`&'static` metadata a
parse ignores, so a binary that never asks for help pays nothing for
being able to.

usage-lib renders this through a tera template over a runtime model.
This crate has no `Spec`
at run time, only tables, so the rules are reimplemented — and
reimplemented rules drift. The
test runs both over mise's real spec and compares all 211 lines, because
an adopter's help
text changing is a visible regression even when the change is one
bracket. The shadow is
generated from the same KDL usage-lib is handed, so the two describe the
same CLI by
construction rather than by a fixture kept in step by hand.

Two things it caught:

An argument that only takes what follows a `--` is bracketed *around*
the separator —
`[-- COMMAND]…`, one optional thing — where I had written `--
[COMMAND]…`, a literal `--`
followed by an optional word. Five of mise's commands read that way.

A flag is named after the form it answers to, not after the Rust field
holding it. usage-lib
derives the name from the first long form, and the derive was
kebab-casing the field ident —
so `type_` gave a flag called `type-`, which help printed as `type-: -t
--type` and errors
reported as `type-`. An explicit `name` still wins, and a flag with no
long form keeps its
short, as usage-lib does. Selectors resolve by form rather than by name,
so nothing that
refers to a flag changes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---

<sub>Stack created with <a
href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a
href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Cold-path help formatting behind `spec`, with broad parity tests;
derive naming changes align emitted KDL/help with usage-lib and do not
alter parse-time selector matching.
> 
> **Overview**
> Adds **`usage_argv::help::usage_line`** behind the existing **`spec`**
feature so the top-of-help invocation summary is built from static
**`CommandMeta`** tables without a runtime spec model.
> 
> **Parity:** The gate bench compares every mise command’s line (211)
against **usage-lib** from the same KDL; **PLAN.md** marks the usage
line as done.
> 
> **Rendering fixes:** Defaulted flags/args render as optional
(`required && default.is_empty()`), not raw `required`. **`--`**
positionals use **`[-- NAME]…`** with brackets outside the separator.
Flags/args collapse to **`[FLAGS]`** / **`[ARGS]…`** past an inline
limit of 2.
> 
> **Derive:** Flags without an explicit **`name`** are named from the
first long or short form (fixes **`type_` → `type-`**); short-only value
flags keep the field ident as **`value_name`**.
> 
> **Tests:** Gate **`help.rs`**, conformance **`derive`** /
**`metadata`** for defaulted and renamed flags.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
32ff41b. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

## The standard

**All 211 of mise's commands render byte-identically to usage-lib.**

usage-lib builds this through a tera template over a runtime model.
usage-argv has no `Spec` at
run time — only `&'static` tables — so the rules are reimplemented here,
and reimplemented rules
drift. The test runs both over mise's real spec and compares every line,
because an adopter's
help text changing is a visible regression even when the change is one
bracket. The shadow is
generated from the same KDL usage-lib is handed, so the two describe the
same CLI by
construction rather than by a fixture kept in step by hand.

The parity test is also what found the four metadata gaps: three in #853
below this, and one
here.

## What it caught here

**A `--` argument is bracketed around the separator.** usage-lib writes
`[-- COMMAND]…` — one
optional thing — where I had `-- [COMMAND]…`, a literal `--` followed by
an optional word. Five
of mise's commands read that way.

**A flag is named after the form it answers to, not the field holding
it.** usage-lib derives
the name from the first long form; the derive was kebab-casing the Rust
ident. So `type_` gave a
flag called `type-`, printed by help as `type-: -t --type` and reported
by errors as `type-`.
An explicit `name` still wins, and a flag with no long keeps its short,
as usage-lib does.
Selectors resolve by form rather than by name, so nothing that *refers*
to a flag changes — and
error messages get better for free.

## Cost

None on the parse path: this reads the cold metadata a successful parse
never touches, and lives
behind the existing `spec` feature. A binary that never renders help
does not carry the
formatting code.

## Not yet

The line only. The sections below it — about, arguments, flags grouped
by heading, subcommands,
examples — and the `--help`/`-h` wiring in the derive are the next two
PRs. The line comes first
because everything else is arranged around it, and because it is the
piece with an exact oracle.

*AI-assisted — Tool: Claude Code; model: anthropic/claude-opus-5;
version: unavailable.*

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
jdx added a commit that referenced this pull request Aug 13, 2026
The whole short help page, not just the line above it: the program and
version, the about,
the commands list, arguments and flags grouped by heading, examples, and
the hidden-item
filtering. All 211 of mise's commands come out byte for byte identical
to usage-lib's, which
is the standard that decides whether an adopter's help changes.

Holding it to that found four more things a spec could say that the
derive could not, each
dropped by `gen-shadow` without being counted — the same class as the
three in the PR below
this one, and found the same way:

- the spec's own `about`. The root's description lives at the top level,
not on the root
command, so the shadow's root said "Undocumented" where mise says what
mise is.
- `hide` on a command. mise hides eight, `asdf` and `dotfiles` among
them, and a
`Subcommands` variant had no way to say so — help listed every one of
them.
- help text whose line breaks are meant literally. A doc comment's first
paragraph is read
the way Rust reads one, so a break inside it becomes a space; 37 of
mise's flags and
commands have multi-line help and every one came back with its lines run
together.
`#[usage(help = "…")]` declares it instead, rather than changing what a
comment means.
- the `Undocumented` placeholder the generator wrote where a spec says
nothing. It became
*real* help text: the shadow told a reader that `--output` was
"Undocumented".

Two shapes the reference has that are worth knowing about, both matched
rather than
improved: a listed subcommand shows its whole path from the root
(`tool-alias get <TOOL>`,
not `get <TOOL>`), and a command whose subcommands are all hidden still
says `<SUBCOMMAND>`
in its usage line while printing no commands section, because usage-lib
computes that line
before filtering.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---

<sub>Stack created with <a
href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a
href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Changes are help rendering and test/shadow fixtures only; no parser
hot-path or binding behavior.
> 
> **Overview**
> Adds **`short_help`** in `usage_argv::help`, producing the full
**`-h`** page from static metadata: version line, spec **`about`**,
usage line, subcommands (full path, aliases, synthetic **`help`**
entry), arguments and flags grouped by **`help_heading`** with
choices/env/default annotations, and examples—with **hidden** items
filtered like usage-lib.
> 
> A gate test walks all **211** mise commands and compares output to
**`usage::docs::cli::render_help(..., false)`**, reporting the first
differing line on failure.
> 
> The **mise clap shadow** is updated so generated help matches: root
**`about`**, **`hide`** on subcommands, **`#[usage(help = "...")]`**
(and **`long_help`**) where doc comments would collapse line breaks, and
removal of **`Undocumented`** placeholders that had become visible help
text. **PLAN.md** marks **`-h`** parity done and notes **`--help`**
layout plus derive wiring as next.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
7f43d20. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

## The standard

**All 211 of mise's commands render byte-identically to usage-lib** —
the whole `-h` page, not
just the line at the top: program and version, about, commands list,
arguments and flags grouped
by heading, examples, hidden-item filtering.

usage-lib renders through a tera template over a runtime model.
usage-argv has only `&'static`
tables, so the rules are reimplemented, and the parity test over mise's
real spec is what keeps
them honest. It reports the **first differing line** rather than two
walls of text, which is what
made working through 211 → 74 → 70 → 37 → 3 → 0 tractable.

## Four more gaps it found

Same class as the three in #853, found the same way, and each dropped by
`gen-shadow` without
being counted:

| | what happened |
|---|---|
| the spec's own `about` | the root's description lives at the top
level, not on the root command, so the shadow's root said
**"Undocumented"** where mise says what mise is |
| `hide` on a command | mise hides eight (`asdf`, `dotfiles`, …) and a
`Subcommands` variant had no way to say so — help listed every one |
| multi-line help | a doc comment's first paragraph is read the way Rust
reads one, so a line break inside it becomes a space; **37** of mise's
flags and commands have multi-line help and all came back run together |
| the `Undocumented` placeholder | written where a spec says nothing, it
became *real* help text — the shadow told readers `--output` was
"Undocumented" |

For the third I added `#[usage(help = "…")]` rather than changing what a
doc comment means: a
comment's paragraph should still flow, as clap reads it too, but help
whose line breaks are
deliberate now has a way to say so. Useful to adopters beyond the
shadow.

## Two reference shapes matched rather than improved

- A listed subcommand shows its **whole path from the root** —
`tool-alias get <TOOL>` under
  `mise tool-alias`, not `get <TOOL>`.
- A command whose subcommands are all hidden still says `<SUBCOMMAND>`
in its usage line while
printing no commands section, because usage-lib computes that line
before filtering and
  stores it.

Both are odd; both are what the reference does, and parity is the point.
Worth revisiting
together later, in usage-lib.

## Next

`--help`'s wider layout — help aligned into a column, wrapped to
`COLUMNS`, `[possible values:]`
on its own line — then the `--help`/`-h` wiring in the derive:
`Error::Help`, `-h` short and
`--help` long, and a real `help` subcommand for any CLI that has
subcommands.

*AI-assisted — Tool: Claude Code; model: anthropic/claude-opus-5;
version: unavailable.*

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request Aug 24, 2026
⚠️ **CAUTION: this is a major update, indicating a breaking change!** ⚠️

This MR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [usage](https://github.com/jdx/usage) | tools | major | `5.1.0` → `6.2.0` |

MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot).

**Proposed changes to behavior should be submitted there as MRs.**

---

### Release Notes

<details>
<summary>jdx/usage (usage)</summary>

### [`v6.2.0`](https://github.com/jdx/usage/blob/HEAD/CHANGELOG.md#620---2026-08-24)

[Compare Source](jdx/usage@v6.1.1...v6.2.0)

##### 🚀 Features

- **(argv)** add embedded parse outcomes by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1250](jdx/usage#1250)
- **(cli)** render inline formatting in help text by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1245](jdx/usage#1245)
- **(cli)** split grouped help template sections by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1251](jdx/usage#1251)
- **(complete)** add presentation labels to candidates by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1239](jdx/usage#1239)
- **(complete)** expose structured completion traces by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1241](jdx/usage#1241)
- **(complete)** add semantic candidate kinds by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1242](jdx/usage#1242)
- **(complete)** add Elvish runtime completions by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1243](jdx/usage#1243)
- **(derive)** let argument groups carry values by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1253](jdx/usage#1253)
- **(derive)** add typed command finalization by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1254](jdx/usage#1254)
- **(derive)** add runtime-computed defaults by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1256](jdx/usage#1256)
- **(derive)** dispatch embedded control requests by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1270](jdx/usage#1270)
- **(derive)** emit embedded\_outcome\_into for converted CLIs by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1281](jdx/usage#1281)
- **(docs)** allow overriding markdown templates by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1267](jdx/usage#1267)
- **(docs)** default to compact markdown references by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1272](jdx/usage#1272)
- **(docs)** polish compact markdown references by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1280](jdx/usage#1280)
- **(help)** expose addressable help topics by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1257](jdx/usage#1257)
- **(help)** list commands by name in one aligned column by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1284](jdx/usage#1284)
- **(help)** wrap the short help page by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1287](jdx/usage#1287)
- **(parse)** add structured diagnostic reports by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1255](jdx/usage#1255)
- **(parse)** add opt-in response files by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1259](jdx/usage#1259)
- **(parse)** preserve ordered argument groups by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1271](jdx/usage#1271)
- **(spec)** declare command outputs and exit codes by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1249](jdx/usage#1249)
- **(spec)** add surface availability metadata by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1258](jdx/usage#1258)
- **(spec)** add semantic note and warning blocks by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1273](jdx/usage#1273)
- **(spec)** add output media types by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1274](jdx/usage#1274)
- **(spec)** add help prose to heading sections by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1282](jdx/usage#1282)
- add dynamic command catalogs by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1275](jdx/usage#1275)

##### 🐛 Bug Fixes

- **(completion)** handle attached values and emit built-ins by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1277](jdx/usage#1277)
- **(derive)** preserve flattened command metadata by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1268](jdx/usage#1268)
- **(derive)** skip choice checks for typed defaults by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1269](jdx/usage#1269)
- **(derive)** suppress generated partial field lint by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1278](jdx/usage#1278)
- **(derive)** keep an invalid choice after an override displaces the flag by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1286](jdx/usage#1286)
- **(spec)** make the two KDL writers agree on three more nodes by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1289](jdx/usage#1289)

##### 🚜 Refactor

- **(deps)** replace versions with semver by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1285](jdx/usage#1285)

##### ⚡ Performance

- **(argv)** reduce sort code size by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1264](jdx/usage#1264)
- **(markdown)** skip empty admonition context by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1279](jdx/usage#1279)
- document usage-rs parser tradeoffs by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1265](jdx/usage#1265)

##### 🛡️ Security

- **(complete)** filter path candidates by extension by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1240](jdx/usage#1240)

##### 🔍 Other Changes

- update usage of deprecated `str downcase` thingy in nushell by [@&#8203;TheBearodactyl](https://github.com/TheBearodactyl) in [#&#8203;1262](jdx/usage#1262)

##### New Contributors

- [@&#8203;TheBearodactyl](https://github.com/TheBearodactyl) made their first contribution in [#&#8203;1262](jdx/usage#1262)

### [`v6.1.1`](https://github.com/jdx/usage/blob/HEAD/CHANGELOG.md#611---2026-08-23)

[Compare Source](jdx/usage@v6.1.0...v6.1.1)

##### 🐛 Bug Fixes

- **(argv)** simplify generated completion headers by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1226](jdx/usage#1226)
- **(argv)** plan for the target platform, not the host by [@&#8203;JamBalaya56562](https://github.com/JamBalaya56562) in [#&#8203;1233](jdx/usage#1233)
- **(complete)** keep the path separator the caller typed by [@&#8203;JamBalaya56562](https://github.com/JamBalaya56562) in [#&#8203;1230](jdx/usage#1230)
- **(config)** report config paths without the verbatim prefix by [@&#8203;JamBalaya56562](https://github.com/JamBalaya56562) in [#&#8203;1232](jdx/usage#1232)
- **(docs)** separate visible flag aliases by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1228](jdx/usage#1228)
- **(test)** compile the platform-conditional fixtures warning-free on windows by [@&#8203;JamBalaya56562](https://github.com/JamBalaya56562) in [#&#8203;1234](jdx/usage#1234)

##### ⚡ Performance

- **(derive)** outline invalid-value error construction from generated builds by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1235](jdx/usage#1235)
- **(derive)** share the repeated-value collection loop across fields by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1236](jdx/usage#1236)

##### 🧪 Testing

- **(windows)** let the suite run where zsh, fish and bash-completion are not by [@&#8203;JamBalaya56562](https://github.com/JamBalaya56562) in [#&#8203;1229](jdx/usage#1229)

### [`v6.1.0`](https://github.com/jdx/usage/blob/HEAD/CHANGELOG.md#610---2026-08-22)

[Compare Source](jdx/usage@v6.0.0...v6.1.0)

##### 🚀 Features

- **(cli)** read settings under a prefix mise does not strip by [@&#8203;JamBalaya56562](https://github.com/JamBalaya56562) in [#&#8203;1213](jdx/usage#1213)
- **(derive)** dispatch more of the matches CLIs already write by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1221](jdx/usage#1221)
- **(spec)** apply runtime identity and flatten headings in help by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1220](jdx/usage#1220)

##### 🐛 Bug Fixes

- **(derive)** flow long help and emit kdl raw multiline strings by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1215](jdx/usage#1215)

##### 📚 Documentation

- **(rust)** drop the restated one-declaration line from the intro by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1211](jdx/usage#1211)
- **(spec)** complete KDL reference by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1214](jdx/usage#1214)

### [`v6.0.0`](https://github.com/jdx/usage/blob/HEAD/CHANGELOG.md#600---2026-08-22)

[Compare Source](jdx/usage@v5.1.0...v6.0.0)

##### 🚀 Features

- **(argv)** add a zero-allocation argv parser by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;798](jdx/usage#798)
- **(argv)** emit a usage spec from static metadata by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;801](jdx/usage#801)
- **(argv)** a bound stops a variadic by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;826](jdx/usage#826)
- **(argv)** route a word that names nothing to the default subcommand by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;848](jdx/usage#848)
- **(argv)** join static tables at compile time by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;851](jdx/usage#851)
- **(argv)** render the usage line, byte-identical to usage-lib's by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;854](jdx/usage#854)
- **(argv)** render `-h`, byte-identical to usage-lib's by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;860](jdx/usage#860)
- **(argv)** render `--help` too, byte-identical to usage-lib's by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;866](jdx/usage#866)
- **(argv)** answer `--help` and `-h` by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;870](jdx/usage#870)
- **(argv)** answer the `help` subcommand by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;872](jdx/usage#872)
- **(argv)** split a command line the way the shell that typed it would by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;874](jdx/usage#874)
- **(argv)** read the cursor's position off a real parse by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;876](jdx/usage#876)
- **(argv)** offer what the reference offers, from compiled tables by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;877](jdx/usage#877)
- **(argv)** generate the shell script each shell wants by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;887](jdx/usage#887)
- **(argv)** let a Rust function answer for a value by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;888](jdx/usage#888)
- **(argv)** write the `run=` a declared completer answers by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;890](jdx/usage#890)
- **(argv)** say what went wrong the way clap says it by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;895](jdx/usage#895)
- **(argv)** suggest what was probably meant by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;897](jdx/usage#897)
- **(argv)** answer `--version`, which an adopter loses on the way from clap by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;909](jdx/usage#909)
- **(argv)** a flag whose value may be left off by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;969](jdx/usage#969)
- **(argv)** take flag-like detached values when declared by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1012](jdx/usage#1012)
- **(bench)** count what a parse allocates, and stop allocating for commands nobody ran by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;829](jdx/usage#829)
- **(cli)** hold a spec's declaration order, the way clap-sort holds a clap CLI's by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;915](jdx/usage#915)
- **(cli)** parse usage's own command line with the parser usage ships by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;965](jdx/usage#965)
- **(cli)** support long version text by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1120](jdx/usage#1120)
- **(cli)** check that examples still parse, and let the derive declare them by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1168](jdx/usage#1168)
- **(cli)** add usage explain by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1179](jdx/usage#1179)
- **(cli)** add usage diff for spec compatibility checking by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1171](jdx/usage#1171)
- **(complete)** complete config keys and values from the spec by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;840](jdx/usage#840)
- **(complete)** add async runtime overlays by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1060](jdx/usage#1060)
- **(complete)** support command value hints by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1081](jdx/usage#1081)
- **(complete)** add shell quoting filter by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1114](jdx/usage#1114)
- **(complete)** support full value hint vocabulary by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1119](jdx/usage#1119)
- **(complete)** expand partial path segments by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1128](jdx/usage#1128)
- **(complete)** support shell alias registration by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1158](jdx/usage#1158)
- **(complete)** **breaking** remove the vendored bash-completion copy by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1176](jdx/usage#1176)
- **(complete)** install a completion script where its shell looks for it by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1188](jdx/usage#1188)
- **(config)** read config files as a layer by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;856](jdx/usage#856)
- **(config)** explain why a setting has the value it has by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;857](jdx/usage#857)
- **(config)** read a resolution as the types a struct holds by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;862](jdx/usage#862)
- **(config)** generate the settings registry from the spec by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;864](jdx/usage#864)
- **(config)** generate the settings struct a CLI reads by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;865](jdx/usage#865)
- **(config)** hold a value to the choices its setting declares by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;868](jdx/usage#868)
- **(config)** carry a setting's choices into the generated registry by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;869](jdx/usage#869)
- **(config)** say what sort of thing each warning is by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;873](jdx/usage#873)
- **(config)** carry the flags a setting declares into its registry by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;880](jdx/usage#880)
- **(config)** read the command line as a layer by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;881](jdx/usage#881)
- **(config)** compare the flags a spec declares with the flags a CLI binds by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;884](jdx/usage#884)
- **(config)** support optional props and aliases by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1134](jdx/usage#1134)
- **(config)** read YAML config files by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1192](jdx/usage#1192)
- **(config)** ask for provenance by key, like a value by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1195](jdx/usage#1195)
- **(config)** a read that keeps every setting that reads by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1196](jdx/usage#1196)
- **(config)** close Config derive and spec authoring gaps by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1202](jdx/usage#1202)
- **(config)** gate deprecated settings by explicit CLI version by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1201](jdx/usage#1201)
- **(derive)** compile a struct into parse tables and a spec by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;803](jdx/usage#803)
- **(derive)** compile subcommands from an enum by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;816](jdx/usage#816)
- **(derive)** check what a parse cannot decide on its own by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;817](jdx/usage#817)
- **(derive)** nest commands to any depth by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;818](jdx/usage#818)
- **(derive)** declare which flags conflict and which require each other by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;820](jdx/usage#820)
- **(derive)** let a flag displace another, the last one given winning by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;821](jdx/usage#821)
- **(derive)** let a command answer to more than one name by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;827](jdx/usage#827)
- **(derive)** let a variant hold its command in a `Box` by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;828](jdx/usage#828)
- **(derive)** let a field be the type it means by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;833](jdx/usage#833)
- **(derive)** declare the words a value may be by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;838](jdx/usage#838)
- **(derive)** hold the bytes a word arrived as by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;841](jdx/usage#841)
- **(derive)** declare the properties mise patches in by hand by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;842](jdx/usage#842)
- **(derive)** accept a value the OS accepts and UTF-8 does not by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;844](jdx/usage#844)
- **(derive)** share declarations between commands with flatten by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;852](jdx/usage#852)
- **(derive)** say three things about a CLI the spec could and the derive could not by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;853](jdx/usage#853)
- **(derive)** answer a completion request from the binary itself by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;885](jdx/usage#885)
- **(derive)** bind a flag to a setting, from what the parser saw by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;889](jdx/usage#889)
- **(derive)** a setting can be declared wherever a flag is by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;896](jdx/usage#896)
- **(derive)** let a field name the function that completes it by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;892](jdx/usage#892)
- **(derive)** say how an argument relates to `--`, all four ways by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;900](jdx/usage#900)
- **(derive)** a default a collecting field can hold by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;902](jdx/usage#902)
- **(derive)** say what a command does to the world by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;905](jdx/usage#905)
- **(derive)** name a value the way clap names it, and say which usage can read the spec by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;907](jdx/usage#907)
- **(derive)** let `parse()` answer a failure the way a program does by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;910](jdx/usage#910)
- **(derive)** read the package's version, and be called what the binary is called by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;917](jdx/usage#917)
- **(derive)** a command that takes nothing can be written that way by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;923](jdx/usage#923)
- **(derive)** say that a command cannot be run alone, which it knew and did not write by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;937](jdx/usage#937)
- **(derive)** keep command aliases on their args by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;946](jdx/usage#946)
- **(derive)** preserve verbatim doc comments by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;949](jdx/usage#949)
- **(derive)** support path value hints by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;951](jdx/usage#951)
- **(derive)** declare a group where the flags are declared by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;934](jdx/usage#934)
- **(derive)** add value-conditional requirements by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1002](jdx/usage#1002)
- **(derive)** add skip for fields that are not arguments by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1009](jdx/usage#1009)
- **(derive)** support inline subcommand fields by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1055](jdx/usage#1055)
- **(derive)** accept runtime metadata expressions by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1056](jdx/usage#1056)
- **(derive)** accept clap value attributes by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1057](jdx/usage#1057)
- **(derive)** parse full argv with program name by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1063](jdx/usage#1063)
- **(derive)** support clap no binary name by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1064](jdx/usage#1064)
- **(derive)** support unit command structs by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1071](jdx/usage#1071)
- **(derive)** reuse args across commands by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1076](jdx/usage#1076)
- **(derive)** support runtime program identity by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1078](jdx/usage#1078)
- **(derive)** preserve value enum metadata by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1079](jdx/usage#1079)
- **(derive)** accept clap field spellings by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1086](jdx/usage#1086)
- **(derive)** preserve hidden flag aliases by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1087](jdx/usage#1087)
- **(derive)** resolve relationships through flatten by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1088](jdx/usage#1088)
- **(derive)** support flattened overrides by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1089](jdx/usage#1089)
- **(derive)** preserve flattened help headings by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1090](jdx/usage#1090)
- **(derive)** support clap casing policies by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1094](jdx/usage#1094)
- **(derive)** bind value enums directly by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1110](jdx/usage#1110)
- **(derive)** accept portable clap field spellings by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1135](jdx/usage#1135)
- **(derive)** inherit clap command metadata by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1136](jdx/usage#1136)
- **(derive)** support clap implicit groups by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1137](jdx/usage#1137)
- **(derive)** generate command dispatch by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1182](jdx/usage#1182)
- **(derive)** add usage::Config derive for settings declared in code by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1180](jdx/usage#1180)
- **(derive)** close remaining PLAN gaps for 6.x by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1197](jdx/usage#1197)
- **(docs)** support granular help visibility by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1107](jdx/usage#1107)
- **(docs)** customize subcommand presentation by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1108](jdx/usage#1108)
- **(docs)** color process-facing help by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1111](https://github.com/jdx/usage/pull/1111)
- **(docs)** support help width controls by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1113](https://github.com/jdx/usage/pull/1113)
- **(docs)** support next-line help layout by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1117](https://github.com/jdx/usage/pull/1117)
- **(docs)** support flattened subcommand help by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1118](https://github.com/jdx/usage/pull/1118)
- **(docs)** support explicit display order by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1121](https://github.com/jdx/usage/pull/1121)
- **(docs)** group subcommands under help headings by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1153](https://github.com/jdx/usage/pull/1153)
- **(docs)** add recursive help by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1132](https://github.com/jdx/usage/pull/1132)
- **(generate)** add json-schema for a CLI's config file by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;839](https://github.com/jdx/usage/pull/839)
- **(go)** emit Go parse tables from a spec, which is what Go has instead of a derive by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;931](https://github.com/jdx/usage/pull/931)
- **(go)** emit the cold table too, so generated code can apply the rules by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;959](https://github.com/jdx/usage/pull/959)
- **(go)** render the usage line, from a third table that costs nothing unused by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;964](https://github.com/jdx/usage/pull/964)
- **(go)** render a failure as something a person can act on by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;977](https://github.com/jdx/usage/pull/977)
- **(go)** generate a struct per command, and the Parse that fills them by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;990](https://github.com/jdx/usage/pull/990)
- **(go)** answer the completion request a shell sends by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1005](https://github.com/jdx/usage/pull/1005)
- **(go)** enforce value-conditional requirements by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1003](https://github.com/jdx/usage/pull/1003)
- **(help)** line the flag column up, and give the short page a column at all by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;912](https://github.com/jdx/usage/pull/912)
- **(help)** list the flags a command inherits by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;913](https://github.com/jdx/usage/pull/913)
- **(help)** list `--help` and `--version`, which every page answers by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;914](https://github.com/jdx/usage/pull/914)
- **(lib)** add usage-rs facade by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;963](https://github.com/jdx/usage/pull/963)
- **(lib)** ship usage-rs as the one-crate rust default by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1041](https://github.com/jdx/usage/pull/1041)
- **(parse)** support inferred prefixes by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1080](https://github.com/jdx/usage/pull/1080)
- **(parse)** support arg required else help by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1093](https://github.com/jdx/usage/pull/1093)
- **(parse)** add narrow token boundary controls by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1097](https://github.com/jdx/usage/pull/1097)
- **(parse)** preserve trailing delimiters by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1098](https://github.com/jdx/usage/pull/1098)
- **(parse)** add scalar repeat policy by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1102](https://github.com/jdx/usage/pull/1102)
- **(parse)** add subcommand requirement policy by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1103](https://github.com/jdx/usage/pull/1103)
- **(parse)** add argument subcommand conflicts by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1104](https://github.com/jdx/usage/pull/1104)
- **(parse)** add subcommand value precedence by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1105](https://github.com/jdx/usage/pull/1105)
- **(parse)** support missing optional positionals by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1106](https://github.com/jdx/usage/pull/1106)
- **(parse)** support optional flag values by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1109](https://github.com/jdx/usage/pull/1109)
- **(parse)** support custom help and version actions by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1123](https://github.com/jdx/usage/pull/1123)
- **(parse)** accept explicit boolean values by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1124](https://github.com/jdx/usage/pull/1124)
- **(parse)** support non-strict choices by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1127](https://github.com/jdx/usage/pull/1127)
- **(parse)** support ordered environment fallbacks by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1130](https://github.com/jdx/usage/pull/1130)
- **(parse)** warn at runtime when a deprecated declaration is used by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1186](https://github.com/jdx/usage/pull/1186)
- **(spec)** support flag relationships by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;793](https://github.com/jdx/usage/pull/793)
- **(spec)** add help\_heading, and render it by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;802](https://github.com/jdx/usage/pull/802)
- **(spec)** allow a mount at the top level by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;806](https://github.com/jdx/usage/pull/806)
- **(spec)** make unknown flags configurable, and keep them as values by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;810](https://github.com/jdx/usage/pull/810)
- **(spec)** add `conflicts` to flags by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;819](https://github.com/jdx/usage/pull/819)
- **(spec)** say that one flag needs another, which nothing here could by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;925](https://github.com/jdx/usage/pull/925)
- **(spec)** **breaking** a group, for the rule that no single flag can state by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;927](https://github.com/jdx/usage/pull/927)
- **(spec)** a flag that has to be given on its own by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;941](https://github.com/jdx/usage/pull/941)
- **(spec)** split a value the way clap splits one by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;961](https://github.com/jdx/usage/pull/961)
- **(spec)** add value-conditional requirements by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1001](https://github.com/jdx/usage/pull/1001)
- **(spec)** refuse a detached value when require\_equals is set by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1013](https://github.com/jdx/usage/pull/1013)
- **(spec)** bind a value when a flag is given with none by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1015](https://github.com/jdx/usage/pull/1015)
- **(spec)** forward unmatched words as an external subcommand by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1021](https://github.com/jdx/usage/pull/1021)
- **(spec)** bind a default when another flag is given by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1023](https://github.com/jdx/usage/pull/1023)
- **(spec)** add portable expression validation by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1037](https://github.com/jdx/usage/pull/1037)
- **(spec)** add borrowed metadata overlays by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1059](https://github.com/jdx/usage/pull/1059)
- **(spec)** omit versions from metadata views by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1066](https://github.com/jdx/usage/pull/1066)
- **(spec)** support positional conflicts and groups by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1085](https://github.com/jdx/usage/pull/1085)
- **(spec)** add fixed arity value names by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1099](https://github.com/jdx/usage/pull/1099)
- **(spec)** complete relationship families by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1100](https://github.com/jdx/usage/pull/1100)
- **(spec)** expose package metadata by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1116](https://github.com/jdx/usage/pull/1116)
- **(spec)** add deprecation milestones by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1129](https://github.com/jdx/usage/pull/1129)
- **(spec)** add executable views by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1143](https://github.com/jdx/usage/pull/1143)
- **(spec)** add deprecated config environment aliases by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1159](https://github.com/jdx/usage/pull/1159)
- **(spec)** declare source\_code\_link\_template on the derive by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1184](https://github.com/jdx/usage/pull/1184)
- **(spec)** answer **usage\_spec** from a binary's own tables by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1183](https://github.com/jdx/usage/pull/1183)
- **(spec)** reusable flag declarations with flagset and use by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1170](https://github.com/jdx/usage/pull/1170)
- **(spec)** **breaking** lower the derive's flatten into a flagset by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1172](https://github.com/jdx/usage/pull/1172)
- **(test)** a test harness for an adopter's own suite by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1181](https://github.com/jdx/usage/pull/1181)

##### 🐛 Bug Fixes

- **(argv)** stop a repeatable flag from eating a positional by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;799](https://github.com/jdx/usage/pull/799)
- **(argv)** inherit `unknown_flags`, which reached one command out of a tree by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;939](https://github.com/jdx/usage/pull/939)
- **(argv)** reject duplicate flags by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;945](https://github.com/jdx/usage/pull/945)
- **(argv)** show choices when a subcommand is required by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;947](https://github.com/jdx/usage/pull/947)
- **(argv)** a bare `-` binds where it was typed by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;986](https://github.com/jdx/usage/pull/986)
- **(argv)** put zsh's magic comment first, and print fish's candidates as data by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1033](https://github.com/jdx/usage/pull/1033)
- **(ci)** unblock releases by cutting usage-derive's dev-dependency by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;811](https://github.com/jdx/usage/pull/811)
- **(ci)** check the version the crates promise, and promise one that is true by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;918](https://github.com/jdx/usage/pull/918)
- **(clap)** say what clap would do with an unknown flag by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;899](https://github.com/jdx/usage/pull/899)
- **(cli)** recognize about as root command help by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;794](https://github.com/jdx/usage/pull/794)
- **(complete)** resolve config keys through aliases and renames by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1169](https://github.com/jdx/usage/pull/1169)
- **(config)** accept case-insensitive boolean words by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1207](https://github.com/jdx/usage/pull/1207)
- **(derive)** let a `--`-only argument follow a variadic by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;823](https://github.com/jdx/usage/pull/823)
- **(derive)** three more descriptions a spec keeps and the derive lost by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;861](https://github.com/jdx/usage/pull/861)
- **(derive)** name the mistake when `settings` has nothing to collect by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;904](https://github.com/jdx/usage/pull/904)
- **(derive)** emit the tables beside the user's types, not in a module above them by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;938](https://github.com/jdx/usage/pull/938)
- **(derive)** a global flag may be given once per command, not once per line by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;991](https://github.com/jdx/usage/pull/991)
- **(derive)** separate value metadata from parsing by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1054](https://github.com/jdx/usage/pull/1054)
- **(derive)** make defaulted fields optional in metadata by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1065](https://github.com/jdx/usage/pull/1065)
- **(derive)** isolate process exit from adopters by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1139](https://github.com/jdx/usage/pull/1139)
- **(derive)** propagate redeclared global values by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1140](https://github.com/jdx/usage/pull/1140)
- **(derive)** preserve set-false actions by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1156](https://github.com/jdx/usage/pull/1156)
- **(derive)** name the count type in standing presence checks by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1205](https://github.com/jdx/usage/pull/1205)
- **(docs)** link multi-word commands to their real source files by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;845](https://github.com/jdx/usage/pull/845)
- **(docs)** link every command to the file that implements it by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;846](https://github.com/jdx/usage/pull/846)
- **(docs)** keep hidden entries out of help by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;859](https://github.com/jdx/usage/pull/859)
- **(docs)** list visible flag aliases by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1112](https://github.com/jdx/usage/pull/1112)
- **(help)** a command's page should say what that command does by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;911](https://github.com/jdx/usage/pull/911)
- **(help)** a declared name is not a short form, and blank help is no help by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;916](https://github.com/jdx/usage/pull/916)
- **(help)** render the page for the mount the words reached by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;928](https://github.com/jdx/usage/pull/928)
- **(help)** a description ending in a break adds no blank line by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;970](https://github.com/jdx/usage/pull/970)
- **(lib)** validate every variadic fallback by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1049](https://github.com/jdx/usage/pull/1049)
- **(parse)** keep every `--` after the first by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;809](https://github.com/jdx/usage/pull/809)
- **(parse)** stop losing a flag that is missing its value by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;807](https://github.com/jdx/usage/pull/807)
- **(parse)** answer the five vectors the reference implementation was failing by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;930](https://github.com/jdx/usage/pull/930)
- **(parse)** **breaking** a command that needs a subcommand says so by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;992](https://github.com/jdx/usage/pull/992)
- **(parse)** keep optional validation lint-clean by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1141](https://github.com/jdx/usage/pull/1141)
- **(parse)** honor separator after automatic args by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1164](https://github.com/jdx/usage/pull/1164)
- **(parse)** let a bundle contain a supplied short by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1175](https://github.com/jdx/usage/pull/1175)
- **(spec)** make the config block survive being written out by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;832](https://github.com/jdx/usage/pull/832)
- **(spec)** apply default\_subcommand only at the root by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;850](https://github.com/jdx/usage/pull/850)
- **(spec)** split a clap default by the delimiter clap splits it by by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;901](https://github.com/jdx/usage/pull/901)
- **(spec)** rank a subcommand name above another command's alias by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;967](https://github.com/jdx/usage/pull/967)
- **(spec)** preserve clap value count bounds by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1032](https://github.com/jdx/usage/pull/1032)
- **(spec)** deduplicate derived completers by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1072](https://github.com/jdx/usage/pull/1072)
- **(spec)** canonicalize derived kdl by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1095](https://github.com/jdx/usage/pull/1095)

##### 🚜 Refactor

- **(deps)** **breaking** stop shipping features and crates nobody uses by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1185](https://github.com/jdx/usage/pull/1185)
- **(deps)** drop heck from usage-derive by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1187](https://github.com/jdx/usage/pull/1187)
- **(deps)** take expr-lang without the builtins a spec cannot reach by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1191](https://github.com/jdx/usage/pull/1191)

##### 📚 Documentation

- **(plan)** tick landed clap gaps and stop quoting vector counts by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1027](https://github.com/jdx/usage/pull/1027)
- correct current Rust limitations by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1029](https://github.com/jdx/usage/pull/1029)
- audit 6.x release documentation by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1084](https://github.com/jdx/usage/pull/1084)
- add third-party license notices by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1174](https://github.com/jdx/usage/pull/1174)

##### ⚡ Performance

- **(derive)** fill the partial through \&mut instead of returning it by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;980](https://github.com/jdx/usage/pull/980)
- **(derive)** hold one subcommand's partial, not every subcommand's by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;981](https://github.com/jdx/usage/pull/981)
- **(derive)** drop proc-macro-crate transitive deps by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1042](https://github.com/jdx/usage/pull/1042)

##### 🧪 Testing

- **(clap)** preserve choices in external adopter probes by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1157](https://github.com/jdx/usage/pull/1157)
- **(corpus)** pin what completes where the cursor is by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;998](https://github.com/jdx/usage/pull/998)
- **(derive)** cover verbatim doc compatibility by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1092](https://github.com/jdx/usage/pull/1092)
- **(docs)** preserve fleet footer spacing by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1142](https://github.com/jdx/usage/pull/1142)
- **(fleet)** refresh typed adopter fixtures by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1115](https://github.com/jdx/usage/pull/1115)
- **(parse)** cover mounted command discovery by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1131](https://github.com/jdx/usage/pull/1131)
- **(parse)** add clap micro-conformance by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1133](https://github.com/jdx/usage/pull/1133)
- **(spec)** import the argv questions clap's suite answers and ours did not by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;926](https://github.com/jdx/usage/pull/926)
- **(spec)** verify portable parser settings by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1053](https://github.com/jdx/usage/pull/1053)

##### 🛡️ Security

- **(config)** resolve settings from layers, with provenance by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;849](https://github.com/jdx/usage/pull/849)
- **(config)** read the environment as a layer by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;867](https://github.com/jdx/usage/pull/867)
- **(config)** give a deprecation notice from anywhere along a rename chain by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;893](https://github.com/jdx/usage/pull/893)
- **(derive)** keep parsed fields live for lints by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1138](https://github.com/jdx/usage/pull/1138)
- **(docs)** render the config block by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;837](https://github.com/jdx/usage/pull/837)
- **(go)** render the page `-h` prints, matching usage-lib on all 211 of mise's by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;974](https://github.com/jdx/usage/pull/974)
- **(go)** render `--help` too, matching usage-lib on all 211 of mise's long pages by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;975](https://github.com/jdx/usage/pull/975)
- **(parse)** require exact command and flag names by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1096](https://github.com/jdx/usage/pull/1096)
- **(spec)** the config vocabulary by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;835](https://github.com/jdx/usage/pull/835)

##### 🔍 Other Changes

- **(docs)** remove stale mise spec fixture by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1200](https://github.com/jdx/usage/pull/1200)
- **(perf)** say when the clap ratio slides, and record why the derive is stricter by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;996](https://github.com/jdx/usage/pull/996)
- agent/complete files by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;883](https://github.com/jdx/usage/pull/883)

##### 📦️ Dependency Updates

- update rust crate syn to v3 by [@&#8203;renovate\[bot\]](https://github.com/renovate\[bot]) in [#&#8203;808](https://github.com/jdx/usage/pull/808)
- update rust crate toml to v1 by [@&#8203;renovate\[bot\]](https://github.com/renovate\[bot]) in [#&#8203;1016](https://github.com/jdx/usage/pull/1016)

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this MR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yODguMCIsInVwZGF0ZWRJblZlciI6IjQzLjI4OC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJSZW5vdmF0ZSBCb3QiLCJhdXRvbWF0aW9uOmJvdC1hdXRob3JlZCIsImRlcGVuZGVuY3ktdHlwZTo6bWFqb3IiXX0=-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant