fix(cli): suggest the real command instead of a plugin that does not exist - #421
Open
ankitranjan7 wants to merge 1 commit into
Open
fix(cli): suggest the real command instead of a plugin that does not exist#421ankitranjan7 wants to merge 1 commit into
ankitranjan7 wants to merge 1 commit into
Conversation
…exist
A mistyped token fell through a hardcoded 9-entry map straight into
missingPluginGuidance, sending the caller to search for a plugin that
cannot exist ("webcmd adapters" -> "webcmd plugin search adapters").
The root command:* handler also dumped the whole root help to stdout,
so "webcmd adapters --json" wrote a well-formed JSON document to stdout
next to an error on stderr.
Add a Levenshtein suggestion engine over everything registered on the
program (root names, aliases, subcommand leaves, site adapters, external
CLIs), keep the hardcoded map as high-priority intent overrides, and give
every built-in namespace the same treatment plus a list of its valid
subcommands. Error output goes to stderr only, in hosted mode too.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Contributor
🟠 Maintainer review suggested — low confidenceThe automated review could not reach a fully supported conclusion. Limitations
This review is advisory and does not block merging. |
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.
webcmd adapterstold you to install a plugin named "adapters". There is no such plugin, and there never will be — the command iswebcmd adapter, one character away.The problem
rootCommandSuggestion()was a hardcoded 9-entry map. Anything not literally in it fell through tomissingPluginGuidance(), which routes the caller into a plugin hunt that cannot succeed.adapters→adapteris edit distance 1 and was missed.fetch→web fetchwas missed.command:*handler calledprogram.outputHelp(), which writes to stdout. With--jsonin argv that is a well-formed JSON document on stdout beside an error on stderr — anything parsing stdout reads it as success. Hosted mode did the same.unknown command 'x': no suggestion, no list of what is valid.What changed
src/command-suggest.ts: ~15-line Levenshtein (no dependency) matched against everything registered on the program — root command names, aliases, subcommand leaves (sofetchfindsweb fetch), installed site adapters, external CLIs. Distance ≤ 2 for tokens of 8+ chars, ≤ 1 below that; up to 3 candidates.marketplace→plugin search,adapter list→adapter status) and runs before the distance engine;missingPluginGuidanceis now the last resort, not the first.adapter,plugin,session,profile,daemon,external,browser,site,auth,skills) gets one sharedcommand:*handler that prints the suggestion plus the namespace's valid subcommands. The one-offbrowser.on('command:*')handler and its retired-forkmap moved into the shared path. Site adapter groups keep Commander's own suggestion so hosted mode stays byte-compatible.src/hosted/runner.tsdropped the root-help stdout payload from three throws).~/.webcmd/plugins/<X>and~/.webcmd/clis/<X>. If the directory is there, say the adapter failed to load and point atWEBCMD_VERBOSE=1instead of sending the user shopping.Before / After
Tests
src/command-suggest.test.ts(11 cases):adapters→adapter;fetch→web fetch;marketplaceoverride wins over distance;adapter list→adapter statusplus the valid-subcommand list; retiredbrowser forknames its replacement; an installed-but-unregistered directory reports a load failure, not a missing plugin; a genuinely unknown token still gets plugin-search guidance; and both error paths write zero bytes to stdout while exiting 2.Updated existing expectations in
src/cli.test.ts,src/hosted/runner.test.ts,src/hosted/root-command-surface.test.ts, andsrc/hosted/main-lifecycle.test.tsthat asserted root help lands on stdout during an error.npm run typecheckclean.npx vitest run --project unit: 2712 passed, 2 failed — both insrc/browser/run/playwright-client-build.test.ts, both failing identically onorigin/mainin this worktree (the sandbox build script cannot resolvenode_modules/playwright-corehere). Unrelated to this change.🤖 Generated with Claude Code