Skip to content

feat(argv): answer the help subcommand - #872

Merged
jdx merged 1 commit into
agent/help-wiringfrom
agent/help-subcommand
Aug 14, 2026
Merged

feat(argv): answer the help subcommand#872
jdx merged 1 commit into
agent/help-wiringfrom
agent/help-subcommand

Conversation

@jdx

@jdx jdx commented Aug 13, 2026

Copy link
Copy Markdown
Owner

ex help config ls — the command a CLI with subcommands is expected to have, and
the third of the three ways a user asks: --help, -h, and this.

Supplied on the same terms as the two flags: answered by the parser, absent from
the page unless the spec declares it, so a spec stays a description of what its
author wrote rather than of what the parser adds.

Asked after the subcommand lookup, so a CLI that means something else by help
keeps its own command and its own arguments, and only where there are
subcommands — to a leaf, help is a word like any other, and mise config set help still sets the key called help.

The words after it name a command, resolved without descending into it: they are
a question about a command rather than an invocation of it, so nothing binds and
a word naming no command stops the walk rather than failing — deep help config nonsense answers about config, which is the most useful page it can give.
Aliases resolve, since the question is about the command and not the spelling.

Costs nothing measurable at mise's scale (29,949 instructions for mise use -g node@20, against 29,961 before): the guard short-circuits on every command that
has no subcommands.

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


Stack created with GitHub Stacks CLIGive Feedback 💬


Note

Low Risk
Localized parser extension mirroring existing help-flag handling, with strong conformance coverage and no changes to auth, persistence, or public API shape beyond new behavior.

Overview
The argv parser now treats help as a built-in help request (like --help / -h) wherever a command has subcommands—the same place help text already advertises it.

When the current token is help, the parser walks following argv words as a subcommand path (names and aliases) without descending into those commands, then returns Error::Help with long: true for the resolved command. Unknown path segments stop the walk and still yield help for the deepest match (e.g. help config nonsense → config’s page). The check runs after real subcommand matching so a user-declared help subcommand wins; on leaf commands help stays a normal positional value.

A small find_named helper resolves subcommands by name or alias for that path walk. Conformance tests cover nested paths, aliases, partial paths, leaves, custom help commands, and alignment with rendered help pages.

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

Tests

conformance/tests/help_request.rs gains five: the page is about the command the words name,
including a nested one and an alias; a half-recognised path answers about as far as it got; a
leaf binds help as an ordinary word; and a CLI declaring its own help command keeps it,
arguments and all.

Each guard was mutation-checked — dropping the subcommands.is_empty() condition, asking
before the subcommand lookup, answering with the short form, and matching names but not
aliases each fail a test.

The page and the parser now agree

Every page with a Commands section already ended it with help Print this message or the help of the given subcommand(s) — usage-lib's template writes that line unconditionally, and so does ours. The word simply did nothing. A test asserts the promise and the behavior share one condition: the line appears on a page with subcommands, and that is exactly where the word is answered.

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

@coderabbitai

coderabbitai Bot commented Aug 13, 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: 3230b9c4-b6f4-47cf-97f1-560a9344c61b

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.

@greptile-apps

greptile-apps Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR adds parser-owned help [subcommand...] handling to usage-argv, including alias-aware nested command lookup and preservation of user-declared help commands.

  • Adds command-name and alias lookup without descending into argument binding.
  • Returns long-form help for the deepest recognized command path.
  • Adds tests for nested paths, aliases, partial paths, leaves, custom help commands, and page visibility.

Confidence Score: 4/5

The PR is not yet safe to merge because the previously reported parser-semantic mismatch remains and produces incompatible outcomes for the same specification and arguments.

usage-argv now treats help as a request at commands with subcommands and as an ordinary word at leaves, while usage-lib retains the inverse condition, so callers receive parser-dependent help, error, or positional-binding behavior.

Files Needing Attention: argv/src/lib.rs, lib/src/parse.rs, and the shared conformance corpus

Important Files Changed

Filename Overview
argv/src/lib.rs Adds alias-aware help-path resolution and emits long-form help at commands containing subcommands.
conformance/tests/help_request.rs Adds focused usage-argv coverage for nested, partial, leaf, alias, and user-defined help-command behavior.

Reviews (6): Last reviewed commit: "feat(argv): answer the `help` subcommand" | Re-trigger Greptile

Comment thread argv/src/lib.rs
@jdx
jdx force-pushed the agent/help-subcommand branch 2 times, most recently from e92d4fe to d088543 Compare August 14, 2026 00:04
@github-actions

github-actions Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Instruction counts

benchmark trend instructions Δ wall (min) Δ
markdown ▁████████ 175,762,001 → 175,734,627 -0.02% 16.93 → 16.08ms -4.99%
startup ▁████████ 1,222,055 → 1,222,185 +0.01% 1.05 → 1.07ms +1.27%

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 29949 5879475 196x
usage: argv -> struct                             854 ns      0.85 µs
clap: build tree + parse -> struct             501739 ns    501.74 µs
clap: parse -> struct, tree reused              24482 ns     24.48 µs
clap: build tree only                          307834 ns    307.83 µs

a08f69722202 vs fd7a4f8e5623 · measured on the runner, not pushed to the history.

@jdx
jdx force-pushed the agent/help-subcommand branch 2 times, most recently from 439663f to 8acbf48 Compare August 14, 2026 01:25
@jdx
jdx force-pushed the agent/help-subcommand branch from 8acbf48 to 439663f Compare August 14, 2026 02:04
`ex help config ls` — the third of the three ways a user asks, after `--help` and
`-h`, and the one the page has been advertising all along: every page with a
Commands section ends it with "help  Print this message or the help of the given
subcommand(s)", and typing that word did nothing.

The page decides where it works: it prints that line where there are subcommands,
so that is where the word is answered. To a leaf, `help` is a word like any other,
and `mise config set help` still sets the key called help. Asked after the
subcommand lookup, so a CLI that declares a `help` of its own keeps it, arguments
and all — the same rule the two flags follow.

The words after it name a command, resolved without descending into it: they are a
question about a command rather than an invocation of it, so nothing binds and a
word naming no command stops the walk rather than failing — `deep help config
nonsense` answers about `config`, which is the most useful page it can give.
Aliases resolve, since the question is about the command and not the spelling.

Costs nothing measurable at mise's scale (29,949 instructions for `mise use -g
node@20`, against 29,961 before): the guard short-circuits on every command that
has no subcommands.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@jdx
jdx force-pushed the agent/help-subcommand branch from 439663f to a08f697 Compare August 14, 2026 02:30
@jdx
jdx merged commit 6a62d3a into main Aug 14, 2026
9 of 13 checks passed
@jdx
jdx deleted the agent/help-subcommand branch August 14, 2026 12:08
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