fix(cli): close 7 review findings on default subcommand + --command#13
Merged
brettdavies merged 5 commits intodevfrom Apr 16, 2026
Merged
fix(cli): close 7 review findings on default subcommand + --command#13brettdavies merged 5 commits intodevfrom
--command#13brettdavies merged 5 commits intodevfrom
Conversation
Five issues surfaced by post-merge code review on commit 4afef67: - `anc help` and `anc help check` were misclassified as paths because clap's auto-generated `help` subcommand is not returned by `Cli::command().get_subcommands()`. Add it explicitly to the known set. - `anc --command <X>` where X collides with a subcommand name (e.g. `anc --command check`) classified X as the explicit subcommand instead of the flag's value. The pre-parser now consults clap introspection to learn which flags consume the next token and skips both as a unit. - `anc --command rg` and `anc --output json --source` (no positional argument, only subcommand-scoped flags) failed because the pre-parser needs no positional to inject `check`. It now tracks whether any encountered flag was subcommand-scoped and injects accordingly. - `anc -- .` (POSIX double-dash separator) was untested and ill-defined. Now injects `check` before the separator so clap routes `. ` to Check. - `anc -q` / `anc --quiet` (top-level flag without subcommand) panicked via `unreachable!()` — pre-existing bug. The `None` arm now renders help to stderr and exits 2, mirroring `arg_required_else_help`. Also from the same review: - Add `conflicts_with = "source"` on `--command` so the contradictory combination errors at parse time instead of producing a silent empty result. - Add `value_hint = ValueHint::CommandName` on `--command` so zsh, fish, and elvish completions suggest PATH commands instead of file paths. Bash is patched post-generation in scripts/generate-completions.sh because clap_complete's bash backend ignores the hint. - Add `#[command(after_help = ...)]` on `Cli` documenting the implicit default subcommand and the bare-invocation contract directly in `anc --help` output. README and AGENTS.md updated to clarify that exit 2 is overloaded (failures, errors, and usage errors all share it). Test parity preserved: 244 unit + 26 integration before, 253 unit + 34 integration after. Pre-push hook clean (fmt, clippy -Dwarnings, test, Windows compat).
main.rs grew to 538 lines after Plan 003 — well over the 200-line refactor trigger in CLAUDE.md. Most of the growth was pre-parse logic and its tests, which have nothing to do with main.rs's orchestration role. Move the entire argv-injection machinery (`inject_default_subcommand` plus its 19 unit tests) into a new `src/argv.rs` module. main.rs goes from 538 → 203 lines and recovers focus on its single job: parse, route to a subcommand, run checks, format output. `resolve_command_on_path` stays in main.rs — it's small (~25 lines), operates on AppError, and is only used by run(). Splitting it would trade size for indirection. No behavior change. Test parity preserved.
CLAUDE.md previously mentioned `docs/solutions/` only as ce-compound's output destination. Agents in fresh sessions had no signal that the directory was a searchable archive of past solutions worth checking before re-researching a documented problem. Add a brief Documented Solutions section noting the symlink target, frontmatter fields, and `qmd query` invocation. Phrased as awareness, not a directive — agents apply judgment about when to consult it.
Two changes bundled because they share the same workflow: 1. Update Plan 003 to reflect the as-shipped reality. The original plan documented the design that landed in PR #12, but post-merge ce-review surfaced 7 edge cases that PR #13 closed. Adds: - Status block at top with PR #12/#13 links and a pointer to the compounded learning in docs/solutions/. - status: shipped + shipped: 2026-04-15 in frontmatter. - Annotated deferred-questions with status notes. - New Post-Implementation Notes section: final code locations including src/argv.rs, the 7 edge cases beyond the original design, design-time decisions that survived contact with reality, and test-parity table. 2. Refresh .markdownlint-cli2.yaml from the dotfiles canonical (~/dotfiles/stow/claude/dot-markdownlint-cli2.yaml). The local copy was 1096 bytes from February; the canonical is 1802 bytes with proper MD013 line_length: 120 plus a fuller rule set. The stale config was wrapping prose too aggressively.
Adds the new `target/**` ignore (Rust build artifacts) and the `# Canonical version: 2026.04.15` calver line. Per-repo copies preserve that calver line so future drift checks are a one-grep comparison against the dotfiles canonical.
brettdavies
added a commit
that referenced
this pull request
Apr 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Resolves the seven recommended fixes from the post-merge
/ce-reviewof PR #12 (commit4afef67). All actionable findings closed; main.rs trimmed back under the 200-line trigger.Changelog
Added
value_hint = ValueHint::CommandNameon--commandso zsh, fish, and elvish completionssuggest PATH commands instead of file paths. Bash is patched post-generation in
scripts/generate-completions.sh.after_helptext onClidocumenting the implicit default subcommand and thebare-invocation contract directly in
anc --helpoutput.--commandand--sourcenow error at parse time instead ofsilently producing an empty result.
Changed
anc -q/anc --quiet(top-level flag without subcommand) now prints help and exits 2instead of panicking via
unreachable!()(pre-existing bug).anc helpandanc help checknow work — clap's auto-generatedhelpsubcommand wasmissing from our known-subcommand set and got misclassified as a path.
anc --command <NAME>where NAME collides with a subcommand name (e.g.anc --command check) now resolves NAME as a binary on PATH instead of producing aconfusing clap error.
anc --command rgandanc --output json --source(no positional argument) now work —the pre-parser detects subcommand-scoped flags and injects
checkaccordingly.anc -- .(POSIX double-dash separator) now runs check against.instead ofproducing undefined behavior.
Documentation
errors, and usage errors all share it). Suggest parsing stderr (
Usage:text) todistinguish.
Type of Change
fix: Bug fix (non-breaking change which fixes an issue)Related Issues/Stories
checksubcommand and--commandflag for PATH lookup #12 (Plan 003 merge, commit4afef67).context/compound-engineering/ce-review/20260415-173344-efaaf5ff/docs/plans/2026-04-02-003-feat-cli-default-subcommand-and-command-flag-plan.mdFindings Resolved
helpsubcommand missing from known set\"help\"toknownafterget_subcommands()--command <NAME>value collides with subcommandcheckwhen no positional followsanc -qpanics viaunreachable!()(pre-existing)Nonearm now renders help to stderr and exits 2--command+--sourcesilent empty resultconflicts_with = \"source\"oncommandargancexit 2 conflates user-error vs check-failure--helpafter_helpblock onClidocuments itanc -- .POSIX double-dash undefinedinject_default_subcommand+ tests to newsrc/argv.rsmodule (538 → 203 lines)--commandcompletion usescompgen -fValueHint::CommandNamefixes zsh/fish/elvish; bash post-patched in gen scriptanc .succeeds where it previously erroredFindings not addressed (intentional): #11/#12/#17/#18 (subsumed by #10 refactor), #15/#16/#19/#20/#21/#23/#24
(low-priority test/style nits or pre-public-schema concerns).
Testing
-Dwarnings+ test + Windows compat)bare
ancstill exits 2 (fork-bomb guard intact), explicit subcommands still workTest Summary:
Files Modified
Modified:
src/cli.rs—after_helptext,value_hinton--command,conflicts_with = \"source\"src/main.rs—Nonearm prints help instead of panicking; refactor extracts injectionto
argvmoduletests/integration.rs— 8 new tests covering the fixed edge casesscripts/generate-completions.sh— post-process bash to substitutecompgen -cfor--command(clap_complete bash backend ignoresValueHint::CommandName)completions/anc.{bash,zsh,fish}— regenerated to expose new behaviorREADME.md,AGENTS.md— exit-code clarificationCreated:
src/argv.rs— new module hostinginject_default_subcommandand 19 unit testsBreaking Changes
Every previous valid invocation continues to produce identical output. Previously-broken
invocations (
anc help,anc -q,anc --command check,anc --command rg,anc --output json --source,anc -- .) now behave correctly.Deployment Notes
Ships with Plan 003 in the v0.1.0
release/*batch when Plan 002 (release infra) runs.No standalone release branch.
Checklist