Skip to content

feat(cli): suggest the closest command or rule id on a mistyped name - #457

Merged
oekazuma merged 1 commit into
mainfrom
feat/did-you-mean
Aug 11, 2026
Merged

oekazuma merged 1 commit into
mainfrom
feat/did-you-mean

Conversation

@oekazuma

@oekazuma oekazuma commented Aug 11, 2026 •

Copy link
Copy Markdown
Owner

gunshi adoption item 3 (per the approved utilization plan): Did you mean …? hints on mistyped sub-command names and rule ids.

The probe verdict first (recorded as a design-doc addendum)

@gunshi/plugin-suggestion's own hooking can never fire in this CLI — proven against gunshi 0.37.1's source and a live probe of our exact bone wiring: fallbackToEntry: true resolves unmatched tokens straight to the entry command (no CommandNotFoundError is ever constructed), and our shared strip layer removes undeclared flags before gunshi's parser sees them. So the integration uses the plugin's exported matcher (defineSuggestNames + levenshtein — no hand-rolled edit distance) called directly from our own error paths, with the plugin's default thresholds (distance ≤ 2, one suggestion) pinned at the single call site.

The four surfaces (existing wording extended, never replaced)

  • root: svelte-vitals isntall → the unchanged not-a-project error + did you mean `svelte-vitals install`? — suppressed whenever the token exists on disk (an existing path is analyzed as asked, never redirected)
  • docs lsit → unchanged unknown-subcommand line + the hint, before the unchanged help dump
  • ci isntall → the hint before the unchanged CI_HELP
  • explain seo/ssr-disable → unchanged unknown-rule line + did you mean `svelte-vitals explain seo/ssr-disabled`? (matched across all 70+ rule ids)

Garbage input produces zero new output on all four surfaces (pinned both ways; coordinator byte-verified docs bogus identical to main).

Footprint

@gunshi/plugin-suggestion@0.37.1 (exact pin) resolves zero new packages — its dependency set was already present via the completion plugin. It sits on the analyzer path via guard.ts: measured ~1 ms import delta. All 2,701 pre-existing tests byte-unchanged; new unit + integration cells on all four surfaces; full gates green incl. e2e/smoke/check:publish. Changeset: svelte-vitals minor declaring exactly these appended hints.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added “Did you mean…?” suggestions for close typos in analyzer subcommands, CI commands, documentation commands, and rule IDs.
    • Preserved existing errors, exit codes, output streams, and directory analysis behavior.
    • Suggestions appear only when a likely match is found.
  • Tests

    • Added coverage for close, distant, exact-match, wrong-case, and existing-path scenarios.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@oekazuma, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 44 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 71d58b14-36fa-4f9d-a4ae-49722f014a9d

📥 Commits

Reviewing files that changed from the base of the PR and between 406ca15 and 5051f5e.

📒 Files selected for processing (2)
  • docs/superpowers/specs/2026-08-10-gunshi-cli-migration-design.md
  • packages/cli/package.json
📝 Walkthrough

Walkthrough

The CLI adds close-match suggestions for mistyped subcommands and rule IDs across the root analyzer, docs, ci, and explain commands. Existing errors, exit codes, output streams, and directory analysis behavior remain unchanged.

Changes

CLI typo suggestions

Layer / File(s) Summary
Suggestion matcher and dependency
pnpm-workspace.yaml, packages/cli/package.json, packages/cli/src/gunshi/guard.ts, docs/superpowers/specs/...
Adds @gunshi/plugin-suggestion and exports suggestClosest with a maximum edit distance of two. The design addendum records the matcher approach.
CLI surface integration
packages/cli/src/gunshi/analyze.ts, packages/cli/src/gunshi/ci.ts, packages/cli/src/gunshi/docs.ts, packages/cli/src/gunshi/explain.ts, .changeset/did-you-mean-suggestions.md
Adds hints for close unknown commands and rule IDs while preserving existing diagnostics and behavior.
Suggestion behavior validation
packages/cli/test/gunshi-guard.test.ts, packages/cli/test/docs-cli.test.ts, packages/cli/test/explain.test.ts, packages/cli/test/gunshi-analyze.test.ts, packages/cli/test/gunshi-ci.test.ts
Tests close matches, exact matches, distant inputs, case mismatches, existing directories, bare ci, and preserved help output.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI command
  participant suggestClosest
  participant stderr
  CLI command->>suggestClosest: check unknown command or rule ID
  suggestClosest-->>CLI command: return close candidate or no result
  CLI command->>stderr: keep existing error and append hint when available
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: suggestions for mistyped CLI commands and rule IDs.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
⚔️ Resolve merge conflicts 💡
  • Resolve merge conflict in branch feat/did-you-mean

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.

@oekazuma

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 11, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@oekazuma

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 11, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🧹 Nitpick comments (2)
packages/cli/test/docs-cli.test.ts (1)

130-133: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use behavior-oriented names for the no-hint tests.

These names describe matcher distance or argument reasoning instead of the observable CLI behavior.

  • packages/cli/test/docs-cli.test.ts#L130-L133: rename the test to state that an unknown docs subcommand without a close match omits the hint.
  • packages/cli/test/explain.test.ts#L121-L123: rename the test to state that a case-mismatched rule ID omits the hint.
  • packages/cli/test/gunshi-ci.test.ts#L94-L102: rename both tests to state that the hint is omitted.

As per coding guidelines, name tests after the behavior they verify, not the reasoning behind the implementation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/cli/test/docs-cli.test.ts` around lines 130 - 133, Rename the
no-hint tests to describe their observable behavior: in
packages/cli/test/docs-cli.test.ts lines 130-133, state that an unknown docs
subcommand without a close match omits the hint; in
packages/cli/test/explain.test.ts lines 121-123, state that a case-mismatched
rule ID omits the hint; and in packages/cli/test/gunshi-ci.test.ts lines 94-102,
rename both tests to state that the hint is omitted. No test logic changes are
needed.

Source: Coding guidelines

packages/cli/test/gunshi-guard.test.ts (1)

140-145: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Name tests by observable behavior.

These names describe matcher thresholds and fallback routing. Name the tests by the returned suggestion or emitted CLI output instead.

  • packages/cli/test/gunshi-guard.test.ts#L140-L145: Rename the exact-match and distant-input tests to describe their returned values.
  • packages/cli/test/gunshi-analyze.test.ts#L58-L75: Rename the suite and distant-input test to describe CLI hint behavior without fallback or threshold details.

As per coding guidelines, “Name tests after the behavior they verify, not the reasoning behind the implementation.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/cli/test/gunshi-guard.test.ts` around lines 140 - 145, Rename the
two tests in packages/cli/test/gunshi-guard.test.ts:140-145 to describe their
returned values—the exact suggestion and no suggestion—without mentioning
thresholds or matching rationale. In
packages/cli/test/gunshi-analyze.test.ts:58-75, rename the suite and
distant-input test to describe the observable CLI hint behavior, avoiding
fallback and threshold implementation details.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.changeset/did-you-mean-suggestions.md:
- Line 5: Update the changeset wording to state that the root analyzer
suppresses the hint when an existing path of that name is present on disk,
rather than limiting this behavior to an existing directory; preserve the
surrounding behavior and wording.

---

Nitpick comments:
In `@packages/cli/test/docs-cli.test.ts`:
- Around line 130-133: Rename the no-hint tests to describe their observable
behavior: in packages/cli/test/docs-cli.test.ts lines 130-133, state that an
unknown docs subcommand without a close match omits the hint; in
packages/cli/test/explain.test.ts lines 121-123, state that a case-mismatched
rule ID omits the hint; and in packages/cli/test/gunshi-ci.test.ts lines 94-102,
rename both tests to state that the hint is omitted. No test logic changes are
needed.

In `@packages/cli/test/gunshi-guard.test.ts`:
- Around line 140-145: Rename the two tests in
packages/cli/test/gunshi-guard.test.ts:140-145 to describe their returned
values—the exact suggestion and no suggestion—without mentioning thresholds or
matching rationale. In packages/cli/test/gunshi-analyze.test.ts:58-75, rename
the suite and distant-input test to describe the observable CLI hint behavior,
avoiding fallback and threshold implementation details.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2763c86f-40ae-4087-a9b9-224f6eea6203

📥 Commits

Reviewing files that changed from the base of the PR and between 117931b and 6133cc4.

⛔ Files ignored due to path filters (2)
  • packages/cli/test/__snapshots__/gunshi-ci.test.ts.snap is excluded by !**/*.snap
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (14)
  • .changeset/did-you-mean-suggestions.md
  • docs/superpowers/specs/2026-08-10-gunshi-cli-migration-design.md
  • packages/cli/package.json
  • packages/cli/src/gunshi/analyze.ts
  • packages/cli/src/gunshi/ci.ts
  • packages/cli/src/gunshi/docs.ts
  • packages/cli/src/gunshi/explain.ts
  • packages/cli/src/gunshi/guard.ts
  • packages/cli/test/docs-cli.test.ts
  • packages/cli/test/explain.test.ts
  • packages/cli/test/gunshi-analyze.test.ts
  • packages/cli/test/gunshi-ci.test.ts
  • packages/cli/test/gunshi-guard.test.ts
  • pnpm-workspace.yaml

Comment thread .changeset/did-you-mean-suggestions.md Outdated
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@oekazuma
oekazuma merged commit 3965688 into main Aug 11, 2026
8 checks passed
@oekazuma
oekazuma deleted the feat/did-you-mean branch August 11, 2026 06:07
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