Skip to content

feat(help): fuzzy "Did you mean?" suggestions for command typos#516

Merged
BYK merged 1 commit intomainfrom
feat/fuzzy-command-suggestions
Mar 20, 2026
Merged

feat(help): fuzzy "Did you mean?" suggestions for command typos#516
BYK merged 1 commit intomainfrom
feat/fuzzy-command-suggestions

Conversation

@BYK
Copy link
Member

@BYK BYK commented Mar 20, 2026

Top-level command typos like sentry isseu now show "Did you mean: issue?" suggestions instead of a bare "Command not found" error.

Problem

defaultCommand: "help" in app.ts routes unrecognized top-level words to the help command, bypassing Stricli's built-in Damerau-Levenshtein fuzzy matching. Subcommand typos (sentry issue lis) and flag typos (--limt) already get suggestions via Stricli, but top-level command typos and sentry help <typo> did not.

Solution

Add fuzzy matching to resolveCommandPath() in introspect.ts using the existing fuzzyMatch() utility. When a path segment doesn't match any route, return an UnresolvedPath with up to 3 fuzzy-matched suggestions.

Before

$ sentry isseu
Error: Command not found: isseu

After

$ sentry isseu
Error: Command not found: isseu

Did you mean: issue?

JSON output includes a structured suggestions array for machine consumers.

Changes

  • introspect.ts: UnresolvedPath type + fuzzy fallback at both top-level and subcommand resolution
  • help.ts: Surface suggestions in human output and JSON; formatSuggestionList() with Oxford-comma grammar
  • Tests: 10 new tests covering fuzzy suggestions, formatting, and edge cases

@github-actions
Copy link
Contributor

github-actions bot commented Mar 20, 2026

Semver Impact of This PR

🟡 Minor (new features)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


New Features ✨

Telemetry

  • Include user email in Sentry telemetry context by BYK in #513
  • Track TTY vs non-TTY invocations via metric by betegon in #482

Other

  • (help) Fuzzy "Did you mean?" suggestions for command typos by BYK in #516
  • (upgrade) Add progress spinners for version check and download phases by BYK in #515
  • Dynamic cache-backed shell completions with fuzzy matching by BYK in #465

Bug Fixes 🐛

  • (help) Hide ASCII banner when stdout is not a TTY by betegon in #501
  • (json) Flatten view command JSON output for --fields filtering by BYK in #495
  • (polling) Throw TimeoutError instead of bare Error on timeout by BYK in #503
  • (project) Fallback to org listing when bare slug matches an organization by betegon in #475
  • Isolate multiregion 403 tests from env-var auth tokens by BYK in #514
  • Only mention token scopes in 403 errors for env-var tokens by BYK in #512
  • Suggest similar projects on project-search miss (CLI-A4) by BYK in #511
  • Preserve ApiError type in Seer handler + suggest trial start command (CLI-N, CLI-1D/BW/98) by BYK in #510
  • Add 403 scope guidance to issue list error handling (CLI-97) by BYK in #508
  • Propagate 403 from multi-region fan-out instead of returning empty list (CLI-89) by BYK in #507
  • Lowercase project slug in URL-parsed issue short IDs (CLI-C8 follow-up) by BYK in #506
  • Handle EIO stream errors gracefully in bin.ts by BYK in #505
  • Use fuzzyMatch for similar project suggestions and add tests (CLI-C0) by BYK in #504
  • Use resolved org in numeric issue ID 404 hint (CLI-BT) by BYK in #502
  • Include API endpoint in error messages for better diagnostics (CLI-BS) by BYK in #500
  • Enrich 403 on org listing with token scope guidance (CLI-89) by BYK in #498
  • Add 400 suggestions to org-all issue list path (CLI-BY) by BYK in #497
  • Lowercase project slug in issue arg parsing (CLI-C8) by BYK in #496
  • Enrich short ID 404 with org context and suggestions (CLI-A1) by BYK in #494
  • Suggest similar projects when project not found in org (CLI-C0) by BYK in #493
  • Event 404 hint should suggest different project, not repeat failing command by BYK in #492
  • Enrich event 404 errors with retention and format suggestions (CLI-6F) by BYK in #491
  • Add actionable suggestions for 400 Bad Request on issue list (CLI-BM, CLI-7B) by BYK in #489
  • Detect issue short IDs passed to issue list (CLI-C3) by BYK in #488
  • Add Glob.match() polyfill + improve auto-detect diagnostics (CLI-7T) by BYK in #487
  • Add org-slug pre-check to dispatchOrgScopedList (CLI-9A) by BYK in #485

Internal Changes 🔧

  • (issue) Skip getProject round-trip in project-search resolution by betegon in #473
  • (resolve) Carry project data through resolution to eliminate redundant getProject calls by BYK in #486
  • (telemetry) Convert is_tty metric to span tag by betegon in #499
  • HTTP latency optimizations — diagnostics, cache warming, concurrency limits by BYK in #490
  • Switch from @sentry/bun to @sentry/node-core/light (~170ms startup savings) by BYK in #474
  • Regenerate skill files by github-actions[bot] in b7b240ec

🤖 This preview updates automatically when you update the PR.

@BYK BYK marked this pull request as ready for review March 20, 2026 12:55
@github-actions
Copy link
Contributor

github-actions bot commented Mar 20, 2026

Codecov Results 📊

126 passed | Total: 126 | Pass Rate: 100% | Execution Time: 0ms

📊 Comparison with Base Branch

Metric Change
Total Tests
Passed Tests
Failed Tests
Skipped Tests

✨ No test changes detected

All tests are passing successfully.

✅ Patch coverage is 100.00%. Project has 1049 uncovered lines.
✅ Project coverage is 95.77%. Comparing base (base) to head (head).

Coverage diff
@@            Coverage Diff             @@
##          main       #PR       +/-##
==========================================
+ Coverage    95.77%    95.77%        —%
==========================================
  Files          180       180         —
  Lines        24767     24822       +55
  Branches         0         0         —
==========================================
+ Hits         23720     23773       +53
- Misses        1047      1049        +2
- Partials         0         0         —

Generated by Codecov Action

Add fuzzy matching to resolveCommandPath() so that top-level command
typos (e.g. `sentry isseu`) and subcommand typos via help (e.g.
`sentry help issue lis`) now show "Did you mean: issue?" suggestions
instead of a bare "Command not found" error.

This closes the gap where `defaultCommand: "help"` in app.ts routes
unrecognized words to the help command, bypassing Stricli's built-in
Damerau-Levenshtein fuzzy matching.

- Add UnresolvedPath type to introspect.ts with fuzzy suggestions
- Use fuzzyMatch() at both top-level and subcommand resolution levels
- Update HelpJsonResult to include optional `suggestions` array
- Surface suggestions in human output ("Did you mean: X?") and JSON
- Add formatSuggestionList() with Oxford-comma grammar
@BYK BYK force-pushed the feat/fuzzy-command-suggestions branch from 029bd70 to c29fe0c Compare March 20, 2026 13:10
@BYK BYK merged commit 7d2e2b2 into main Mar 20, 2026
22 checks passed
@BYK BYK deleted the feat/fuzzy-command-suggestions branch March 20, 2026 13:20
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