Skip to content

feat(help): list --help and --version, which every page answers - #914

Merged
jdx merged 3 commits into
agent/help-globalsfrom
agent/help-builtins
Aug 17, 2026
Merged

feat(help): list --help and --version, which every page answers#914
jdx merged 3 commits into
agent/help-globalsfrom
agent/help-builtins

Conversation

@jdx

@jdx jdx commented Aug 16, 2026

Copy link
Copy Markdown
Owner

PR 3, the last of the four help differences. Both flags worked and neither appeared on any page: a reader looking for how to ask for help had to already know.

Flags:
  -o, --output <OUTPUT>  Write output to a file instead of stdout
  -h, --help             Print help
  -V, --version          Print version

The rule this reverses, and the half it keeps

The old rule was that a page lists exactly what its spec declares. Per your call, the page now names these two — but the spec still does not, because the parser supplies them and a spec claiming otherwise would have every reader inventing a flag its CLI never wrote.

Help is written for people; the spec has its own readers, and they are not the same readers. A test asserts both halves, which is the honest way to record a reversal.

Where they are, and are not

  • --version only where the parser accepts one — a command whose table says so, which is the root of a CLI that declared a version. A subcommand's page does not offer it, because ex other --version is refused. Offering a flag that would be refused is worse than staying quiet.
  • Each spelling dropped where the CLI claimed it. -V taken by --verbose leaves --version listed alone; the parser yields to a declaration, and the page has to say what will actually happen rather than what would be tidy.
  • Last in the command's own section, where clap has them, carrying no help_heading — so a CLI that groups its flags gets them at the end of the ungrouped list rather than inside somebody else's section.

Verification

mutation result
nothing supplied is listed FAILED (3 tests)
--version offered where the parser refuses it FAILED
a claimed spelling is offered anyway FAILED

Gate green over mise's 211 commands. Seven expected pages in lib/tests/parse.rs and a handful of insta snapshots gain the line — each the intended change, checked one at a time rather than blanket-accepted.


That completes the four differences from the plan. communique generate -h is now byte-for-byte clap's output apart from the word Flags:, plus a Global flags: section clap has no equivalent for — and short help, which had no column at all, has one.

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


Note

Medium Risk
User-visible help text changes across all commands, but behavior is tightly gated by claimed spellings and covered by conformance, insta, and parse snapshot tests.

Overview
Help output now shows -h, --help and -V, --version (when applicable) at the end of each command’s unheaded flags section, matching clap-style discoverability. The spec/KDL still does not declare these flags—the parser supplies them—so emitted specs stay unchanged while rendered pages name what users can actually type.

Both usage-argv (supplied / supplied_entries wired through own_and_global) and lib docs rendering (supplied_flags, with inherited_flags returning the ancestor “taken” spellings) pick long/short/both variants from what is already claimed, including hidden flags and negations. --version appears only on the root when a version exists; subcommands and unversioned CLIs omit it. Mise’s disable_help suppresses the supplied help line on KDL-rendered pages.

Conformance and snapshot tests were flipped from “must not list” to “listed but not declared,” with new cases for claimed spellings, hidden help, and negated --version.

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

@coderabbitai

coderabbitai Bot commented Aug 16, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro Plus

Run ID: 3e9fb209-8828-4b21-a3a8-7042b739189c

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

@jdx
jdx force-pushed the agent/help-builtins branch from 960c38c to bcf53c7 Compare August 16, 2026 22:21
Comment thread argv/src/help.rs
@greptile-apps

greptile-apps Bot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR makes generated help list parser-supplied help and version flags without adding them to emitted specs.

  • Adds collision-aware -h/--help and root-version -V/--version entries to both help renderers.
  • Preserves parser precedence for claimed, hidden, inherited, and negated spellings.
  • Adds conformance and snapshot coverage for availability, collisions, disabled help, and spec omission.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
argv/src/help.rs Adds synthetic help/version metadata and filters each spelling against the complete parser claim set before rendering.
lib/src/docs/cli/mod.rs Adds equivalent supplied flags to spec-based help while retaining hidden inherited claims and respecting disabled help.
conformance/tests/help_request.rs Updates conformance expectations so help is displayed to users but remains absent from emitted specifications.
conformance/tests/version.rs Covers version visibility, command scope, claimed spellings, hidden declarations, and negation collisions.
lib/tests/parse.rs Updates expected help fixtures to include the parser-supplied help flag.

Reviews (6): Last reviewed commit: "fix(help): a spec that turns help off sh..." | Re-trigger Greptile

Comment thread argv/src/help.rs Outdated
@github-actions

github-actions Bot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Instruction counts

benchmark trend instructions Δ wall (min) Δ
markdown ▁▁▁▃▄▄▃▃███ 180,287,329 → 180,397,308 +0.06% 16.15 → 16.61ms +2.81%
startup ▁▁▁▁▁▁▁▁▆▃█ 1,222,732 → 1,226,001 +0.27% 0.95 → 0.96ms +0.93%

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 72156 5895162 81x
usage: argv -> struct                            1195 ns      1.20 µs
clap: build tree + parse -> struct             499834 ns    499.83 µs
clap: parse -> struct, tree reused              23286 ns     23.29 µs
clap: build tree only                          310014 ns    310.01 µs

c6c0d410d1cb vs 81b1ee788d23 · measured on the runner, not pushed to the history.

@jdx
jdx force-pushed the agent/help-builtins branch from bcf53c7 to 33a5866 Compare August 16, 2026 22:39
Comment thread argv/src/help.rs
Comment thread lib/src/docs/cli/mod.rs Outdated
@jdx
jdx force-pushed the agent/help-builtins branch from 33a5866 to 61cff92 Compare August 16, 2026 23:04

jdx commented Aug 16, 2026

Copy link
Copy Markdown
Owner Author

All three addressed, and the first two fall out of the claim model rebuilt in #913 below.

Hidden and negated claims (greptile, Bugbot). supplied_entries decided from the visible own and inherited lists; it now asks the same set every other decision on the page uses, which counts hidden declarations and negations. The parser yields to both, so a page offering --help while a hidden --help binds would describe an action that typing it does not perform.

Short-only entries showed the wrong name (Bugbot) — real, and reproduced:

Flags:
      --quiet / --version  ...
  help: -h                 Print help
  version: -V              Print version

The declared name is judged against the forms the entry shows, so a short-only entry called help reads as a renamed flag. The leftover entries are named after the form they show.

Ungrouped section order (Bugbot). Right, and the snapshot that accepted it was mine. group_by_heading sorts the unheaded group to the front and argv's groups_section emits it there, so pushing the supplied group put Flags: after the headed sections in one renderer and before them in the other. Inserted first now; the snapshot is corrected rather than re-accepted:

+Flags:
+  -h, --help              Print help
+
 Filtering:
-      --filter <pattern>  Only matching

Verification

mutation result
a short-only entry keeps the long name FAILED
hidden and negated claims ignored FAILED

Gate green over mise's 211 commands, workspace suite green, clippy clean.

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

Comment thread lib/src/docs/cli/mod.rs Outdated
Comment thread lib/src/docs/cli/mod.rs Outdated
Comment thread lib/src/docs/cli/mod.rs
@jdx
jdx force-pushed the agent/help-builtins branch from 61cff92 to 4f2822a Compare August 16, 2026 23:08
jdx and others added 2 commits August 16, 2026 23:26
The last of the four help differences. Both work and neither appeared on any page: a
reader looking for how to ask for help had to already know.

This reverses a rule these two used to follow — that a page lists exactly what its spec
declares — and the reversal is only half. The page names them; the **spec still does
not**, because the parser supplies them and a spec claiming otherwise would have every
reader inventing a flag its CLI never wrote. Help is written for people, the spec has its
own readers, and they are not the same readers. A test asserts both halves.

`--version` only where the parser accepts one: on a command whose table says so, which is
the root of a CLI that declared a version. Offering a flag that would be refused is worse
than staying quiet.

Whether a spelling is free is asked of the same set every other decision on a page uses,
so a `--help` claimed by a hidden declaration or by a negation is claimed here too — the
parser yields to both, and a page that said otherwise would describe an action that
typing it does not perform. The entry left over is named after the form it shows: a
short-only one called `help` reads as a renamed flag and printed `help: -h`.

Last in the command's own section, where clap has them, carrying no `help_heading` — and
in usage-lib inserted *first* among the groups rather than pushed, because the unheaded
group sorts to the front there and is emitted at the front here. A CLI that heads every
one of its own flags would otherwise get `Flags:` after the headed sections in one
renderer and before them in the other.

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

Three from review, all about `--help` and `--version` being offered where something else
would bind the word.

usage-lib rebuilt the claim set from the *visible* inherited list, so a hidden global
that declares `--help` left the spelling looking free — and `hide` keeps a flag off the
page, not out of the parse. The set the inherited walk already built now travels with its
result, so both decisions are made against the same thing.

It also spelled a negation with four dashes, for the reason the commit below fixes:
usage-lib stores `negate="--no-colour"` with the dashes and usage-argv without, so
prefixing produced `----no-colour` and matched nothing.

And the supplied entries lose to a *negation* as well as to a long, which is the one
place the ordering goes the other way: `long_flag` asks `find_negation` before it offers
`--version`, so a CLI whose `--quiet` negates to `--version` keeps that word — even
though a plain long would have beaten the same negation.

Found by greptile and Cursor Bugbot.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@jdx
jdx force-pushed the agent/help-builtins branch from 4f2822a to 93919e0 Compare August 16, 2026 23:34

@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 93919e0. Configure here.

Comment thread lib/src/docs/cli/mod.rs Outdated

jdx commented Aug 16, 2026

Copy link
Copy Markdown
Owner Author

Triaged all three. Two were already fixed on head; the third turned out to be a real regression, though not on this branch — chasing it is what found it, so thank you.

Short-only flags show wrong name — fixed in #916. A short-only entry is named after the form it shows ("h", "V"), so flag_usage's "declared name not implied by the forms" rule no longer fires and the page prints -h rather than help: -h. Both twins.

Ungrouped section order mismatch — fixed on head, and the code now says so where it happens: the supplied entries are insert(0, …)ed rather than pushed, because group_by_heading sorts the unheaded group to the front and argv's groups_section emits it there. A CLI that heads every one of its flags would otherwise get Flags: after the headed sections here and before them there.

Hidden claims still offered — this one was live, and worse than reported. supplied_flags was deciding against the display list of inherited flags, so a hidden ancestor global binding --help was invisible to it while argv's taken counted it. Measured, subcommand page under a root declaring #[usage(long = "help", global, hide)]:

argv: ["  -h           Print help"]
lib : ["  -h, --help   Print help"]   ← advertises a spelling the hidden flag binds

Fixed on this branch in 93919e0: inherited_flags returns its claim set alongside its display list, and supplied_flags decides against the claims.

The part worth flagging: that commit was on this branch when you reviewed it, and every branch above this one had reverted it — an earlier restack had resolved a conflict in lib/src/docs/cli/mod.rs by taking the old side, silently dropping it along with two other help fixes. So the divergence you describe was real again at the top of the stack even though it was fixed here. The four upper branches have been rebased onto this one; inherited_flags now returns the claim set on every branch in the stack, and the probe above agrees on both renderers at the top. The gate did not catch it because mise's spec has no hidden global claiming a supplied spelling.

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

`disable_help` makes `is_help_arg` refuse `--help`, `-h` and `-?` outright,
and the supplied entries were appended without consulting it — so the page
advertised an action its own parser would not perform. The same lie this
change set out to avoid for a claimed or hidden spelling, with the claim made
by the spec itself rather than by a flag.

`--version` stays: nothing disabled that.

No twin change in usage-argv, and no divergence either: `disable_help` is a
KDL word with no equivalent in the argv tables, so no spec that crate can hold
carries one. Recorded here rather than silently, since the two renderers being
byte-identical is the invariant this area runs on.

Reported by Bugbot on #914.

jdx commented Aug 17, 2026

Copy link
Copy Markdown
Owner Author

Second pass on this PR's review. Most of the newer comments re-report findings against pre-rebase commits — the negate double-dashes (----no-color) was fixed in 5aab55a, per-spelling masking in 6ad1a4b, and the hidden-inherited claim in 93919e0, which now threads the claim set out of inherited_flags rather than rebuilding it from the visible list.

One was new and correct: help listed when disabled. disable_help makes is_help_arg refuse --help, -h and -? outright, and the supplied entries were appended without consulting it — the page advertised an action its own parser would not perform, which is the exact lie this PR is otherwise careful about. Fixed in c6c0d41, with a snapshot test; --version stays, since nothing disabled that.

No twin change in usage-argv, and no divergence either: disable_help is a KDL word with no equivalent in the argv tables, so no spec that crate can hold ever carries one. Called out in the commit rather than left implicit, since byte-identical output is the invariant this area runs on.

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

@jdx
jdx merged commit 0515f44 into main Aug 17, 2026
9 checks passed
@jdx
jdx deleted the agent/help-builtins branch August 17, 2026 01:19
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