feat(argv): offer what the reference offers, from compiled tables - #877
Conversation
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Central YAML (base), Organization UI (inherited) Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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. Comment |
Uh oh!
There was an error while loading. Please reload this page.
Greptile SummaryThe PR adds completion candidate generation from compiled argv/spec tables and exposes the reference implementation’s candidates for parity testing.
Confidence Score: 4/5The PR is not yet safe to merge because completion after the first argument of a restarted invocation still returns candidates from stale positional state.
Files Needing Attention: argv/src/complete.rs Important Files Changed
Reviews (5): Last reviewed commit: "feat(argv): offer what the reference off..." | Re-trigger Greptile |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
6127056 to
2ae4671Compare2ae4671 to
1c2008eComparejdx
commented
Aug 14, 2026
Three findings, all correct, all fixed in the head commit — and the third exposed a fourth. Negate flags offered without dashes (Cursor) — the table holds a negation the way the parser matches it, with the dashes already taken off ( Restart-token state is ignored (greptile) — Default-subcommand arguments are omitted (greptile) — That last one then offered those values after Worth noting for anyone reading the tests: my first restart-token test proved nothing. The fixture's argument was variadic, so "back at the first" and "wherever the words reached" were the same answer, and removing the branch entirely left the test green. It now uses a command with two differently-typed arguments, and fails without the branch. AI-assisted — Tool: Claude Code; model: anthropic/claude-opus-5; version: unavailable. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
1c2008e to
76b02caComparejdx
commented
Aug 14, 2026
Both correct, both fixed in the head commit. Required separator never offered — an argument declared That needed Default subcommand alias not resolved — real. AI-assisted — Tool: Claude Code; model: anthropic/claude-opus-5; version: unavailable. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 76b02ca. Configure here.
Uh oh!
There was an error while loading. Please reload this page.
Instruction counts
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 comparisonParsing
|
The candidates for a cursor: the flags a word there could name, the subcommands it could select, and the choices a flag or positional declares. The rules are usage-lib's, because a CLI's completions should not change with the implementation that answers them — a lone `-` offers both forms, `--…` offers longs, `-…` narrows to one letter, a flag waiting for its value offers that flag's choices and nothing else. Held to the reference over mise's real spec: of eighteen lines across the tree, thirteen agree exactly, including sets of forty and twenty-one candidates. The five that do not are named in the test rather than dropped from it — two need stages that do not exist yet (`run=` completions, the reserved `type=` vocabulary), and two are one derive gap. That gap is worth its own note: `flag "-p --path --file"` has a second long form the derive cannot declare, so `gen-shadow` drops it. It is invisible in the help comparison, which renders one long form per flag, and shows up here because a completion offers every name a flag answers to. Next PR. Comparing found a real bug, which is what comparing is for: hidden aliases were being offered. The parse table cannot tell a hidden alias from a visible one — both must be *accepted* — so which are meant to be *offered* is a question only the metadata answers. Descriptions come from the metadata the binary already carries. The reference leaves a flag's empty, its own source saying `TODO: get flag description`; filling it in is a deliberate improvement, which is why the comparison is on values. `usage_cli::complete_candidates` is a seam, not a feature: "the same candidates" is only a checkable claim if the reference's answer can be read as data rather than watched going past on stdout. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
76b02ca to
6525938Comparejdx
commented
Aug 14, 2026
Half of this matches the reference, half is a parser gap worth naming.
The deeper observation is right, though: the parser does not implement restart tokens at all — AI-assisted — Tool: Claude Code; model: anthropic/claude-opus-5; version: unavailable. |

The candidates for a cursor: the flags a word there could name, the subcommands it
could select, and the choices a flag or positional declares. The rules are
usage-lib's, because a CLI's completions should not change with the
implementation that answers them — a lone
-offers both forms,--…offerslongs,
-…narrows to one letter, a flag waiting for its value offers that flag'schoices and nothing else.
Held to the reference over mise's real spec: of eighteen lines across the tree,
thirteen agree exactly, including sets of forty and twenty-one candidates. The
five that do not are named in the test rather than dropped from it — two need
stages that do not exist yet (
run=completions, the reservedtype=vocabulary), and two are one derive gap.
That gap is worth its own note:
flag "-p --path --file"has a second long formthe derive cannot declare, so
gen-shadowdrops it. It is invisible in the helpcomparison, which renders one long form per flag, and shows up here because a
completion offers every name a flag answers to. Next PR.
Comparing found a real bug, which is what comparing is for: hidden aliases were
being offered. The parse table cannot tell a hidden alias from a visible one —
both must be accepted — so which are meant to be offered is a question only
the metadata answers.
Descriptions come from the metadata the binary already carries. The reference
leaves a flag's empty, its own source saying
TODO: get flag description; fillingit in is a deliberate improvement, which is why the comparison is on values.
usage_cli::complete_candidatesis a seam, not a feature: "the same candidates"is only a checkable claim if the reference's answer can be read as data rather
than watched going past on stdout.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com
Stack created with GitHub Stacks CLI • Give Feedback 💬
Note
Medium Risk
Completion behavior is user-facing and must stay in sync with the reference; gaps are documented but wrong candidates or hidden-alias leaks would confuse shell users. The API surface grows (
Candidate, richerPosition, feature couplingcomplete→spec) without touching auth or data persistence.Overview
Adds spec-driven shell completion in
usage-argv:candidates()turns a split command line plus staticSpecmetadata intoCandidatevalues (flags, subcommands, declared choices, descriptions), aligned with usage-lib rules.Position/walknow track--, help topics, and in-scope flags so offerings match what the parser would accept, including hidden commands/aliases, negated long flags, restart tokens (:::), root default subcommand first-arg values, and positionals that require--before values.The
completefeature now enablesspec. Gate tests compare candidate values from the shadow mise CLI againstusage_cli::complete_candidateson real mise lines (documented gaps:run=completions,type=config_keys, extra long forms from shadow gen).usage-cliexposescomplete_candidatesand makescomplete_wordpublic so parity tests read reference output as data instead of stdout.Reviewed by Cursor Bugbot for commit 6525938. Bugbot is set up for automated code reviews on this repo. Configure here.