Skip to content

fix(cli): move command suggestions into hints and drop the dry-run hint on CLI-raised validation errors - #114

Open
AshGodfrey wants to merge 11 commits into
mainfrom
ash/cli-structured-command-suggestions
Open

AshGodfrey wants to merge 11 commits into
mainfrom
ash/cli-structured-command-suggestions

Conversation

@AshGodfrey

@AshGodfrey AshGodfrey commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Why

Two leftovers from the flag-suggestion work in #59.

A mistyped command embedded cobra's whole suggestion block in the error message. In agent mode and -o json that put raw newlines and tabs inside the error and message strings instead of a hint a tool can act on:

{"error": "unknown command \"genreate\" for \"cli\"\n\nDid you mean this?\n\tgenerate\n", ...}

A typo under a command group got no suggestion at all, because cobra only checks for unknown subcommands at the root. A typo followed by the intended leaf's flags (errors status-get-erro --status-code 200) failed on the first unknown flag instead, so it got no suggestion either.

Every validation error carried "Use --dry-run to preview the request and check parameters", including errors the CLI raised before building any request: a missing required flag, a positional given twice, a bare configure or auth login with no terminal. --dry-run fails those the same way, so the hint cannot apply.

What changed

  • exitcodes.go.stmpl: the root and every synthesized group get cobra.NoArgs as before (the root now explicitly, which retires cobra's root-only legacyArgs check). The Args wrapper runs the command's own validator first and, only when it rejects and the command has subcommands, reports the first positional through UnknownSubcommandError. A hand-written parent that accepts positionals keeps accepting them. The message is cobra's one-line form, unknown command "x" for "cli errors". The nearest commands become a hint (Did you mean generate?, or Did you mean one of list, lint?), using cobra's suggestion policy (DisableSuggestions, minimum distance 2). A Run '<command> --help' to list available commands pointer is added and the built-in validation hints are omitted, matching the flag error handler. When a group's flag parse fails after a positional, the flag error handler validates the positionals it already has through the same Args path, so errors status-get-erro --status-code 200 reports the command typo rather than the flag. Because the check runs inside cobra's normal execution, --help after a typo prints help and shell completion (__complete) is unaffected.
  • classify.go.stmpl: the built-in validation hints drop the dry-run line when the error originated in the CLI (ErrorOriginCLI). Server-side validation (an HTTP 400) keeps it.

Before and after, plain output:

$ cli genreate
Error (validation_error): unknown command "genreate" for "cli"

Did you mean this?
	generate

Reason: CLI_VALIDATION
Fix:
  - Use --dry-run to preview the request and check parameters
  - Run the command with --help for runnable examples, or --usage for the machine-readable surface
$ cli genreate
Error (validation_error): unknown command "genreate" for "cli"
Reason: CLI_VALIDATION
Fix:
  - Did you mean generate?
  - Run 'cli --help' to list available commands, or --usage for the machine-readable surface

Behaviour changes: the suggestion block no longer appears in the error message or on plain stderr; the help hint on unknown commands has new wording; a mistyped root command followed by --help prints help with exit 0, as it already did under a group; a suggestion is made when the typo precedes its flags (a typo after an unknown flag still reports the flag). Exit code for the error is unchanged (2).

Tests

  • clierrors_test.go.stmpl: a mistyped command in agent mode yields a single-line error and a Did you mean errors? hint; plain mode prints the same hint and the help pointer without --dry-run; a typo under a group, with and without the leaf's flags, suggests the sibling command; --help after a typo prints help; __complete still completes; a name with no near match gets no suggestion. A missing required flag (CLI-origin validation) carries no dry-run hint, while a server 400 still does.
  • exitcodes_test.go.stmpl: the root unknown-command test expects the one-line message.
  • output_test.go.stmpl: unit tests build a real cobra tree and run it through Execute, covering root typos, typos behind global flags, typos under a group with and without trailing flags, a real name and a typo after --, invocations that resolve cleanly, a parent command that accepts its own positional, --help after a typo, __complete, and DisableSuggestions.
  • Review SDK regenerated.

Public-safety checklist

  • No customer, product, or spec names, hostnames, model ids, or verbatim customer error payloads
  • No private paths, private tracker ids, or internal document references
  • No workflow provenance

@AshGodfrey
AshGodfrey requested a review from a team as a code owner October 16, 2026 11:53
@github-actions github-actions Bot added csharp Trigger (24) snapshot tests for csharp go Trigger (90) snapshot tests for go java Trigger (40) snapshot tests for java mcp-typescript Trigger (16) snapshot tests for mcp-typescript php Trigger (22) snapshot tests for php python Trigger (106) snapshot tests for python ruby Trigger (19) snapshot tests for ruby typescript Trigger (168) snapshot tests for typescript unity labels Oct 16, 2026

@cubic-dev-ai cubic-dev-ai 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.

No issues found across 23 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Shadow auto-approve: would auto-approve. Fixes CLI error output: cobra's unknown-command suggestion block becomes a hint, and the dry-run hint is dropped for CLI-raised validation errors while server 400s keep it. The change is bounded to error messaging, with tests and regenerated SDK.

View guided diff | Turn on auto-fix | Re-trigger cubic

@cubic-dev-ai cubic-dev-ai 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.

All reported issues were addressed across 6 files (changes from recent commits).

Shadow auto-approve: would not auto-approve because issues were found.

View guided diff | Turn on auto-fix | Re-trigger cubic

Comment thread templates/templates/cli/auxiliary/internal/output/exitcodes.go.stmpl Outdated
@speakeasy-generator-bot

speakeasy-generator-bot Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Generator Snapshot Testing

Selector(s) Result Summary
snapshot-csharp, snapshot-go, snapshot-java, snapshot-mcp-typescript, snapshot-php, snapshot-python, snapshot-ruby, snapshot-typescript ❌ Snapshot run failed

Snapshot results: https://github.com/speakeasy-api/openapi-generation-snapshots/issues/120#issuecomment-6222095903

Snapshot results are summarized above. Additional run context is linked for maintainers with access.

@cubic-dev-ai cubic-dev-ai 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.

0 issues found across 5 files (changes from recent commits).

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Shadow auto-approve: would auto-approve. Fixes CLI error output by moving cobra's unknown-command suggestions into hints and dropping the misleading dry-run hint for CLI-raised validation errors while keeping it for server 400s. Bounded to error messaging with focused tests and regenerated SDK.

View guided diff | Turn on auto-fix | Re-trigger cubic

@cubic-dev-ai cubic-dev-ai 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.

All reported issues were addressed across 10 files (changes from recent commits).

Shadow auto-approve: would not auto-approve because issues were found.

View guided diff | Turn on auto-fix | Re-trigger cubic

Comment thread zSDKs/sdk-cli/internal/output/exitcodes.go Outdated
Comment thread templates/templates/cli/auxiliary/internal/output/exitcodes.go.stmpl Outdated
Comment thread .changesets/1792150719-40eeb80f.yaml Outdated

@cubic-dev-ai cubic-dev-ai 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.

All reported issues were addressed across 10 files (changes from recent commits).

Shadow auto-approve: would not auto-approve because issues were found.

View guided diff | Turn on auto-fix | Re-trigger cubic

Comment thread templates/templates/cli/auxiliary/internal/output/exitcodes.go.stmpl Outdated

@cubic-dev-ai cubic-dev-ai 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.

0 issues found across 7 files (changes from recent commits).

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Shadow auto-approve: would auto-approve. Focused CLI error-handling bug fix: unknown commands become hint suggestions, the dry-run hint is dropped for CLI-origin validation, with tests and regenerated SDK. Dismissed firstPositional findings are resolved by the new Args-validator path.

View guided diff | Turn on auto-fix | Re-trigger cubic

…command, and document unknown-command hints

Only commands that reject positionals (cobra.NoArgs, generated and
synthesized groups, the root) have a rejected positional rewritten as an
unknown-command error; a hand-written parent that accepts positionals
keeps its own validator's message. A real subcommand placed after --
gets a hint to remove the -- instead of being suggested back verbatim.
Suggestion lookup no longer leaves SuggestionsMinimumDistance changed on
the command. README documents the hint rules and the dry-run gating;
tests cover a bare configure, several near matches, and the parent
validator case.

@cubic-dev-ai cubic-dev-ai 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.

0 issues found across 10 files (changes from recent commits).

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Shadow auto-approve: would auto-approve. Bounded CLI error-handling fix: unknown commands become hints/one-line messages, dry-run hint dropped for CLI-origin validation, with tests and regenerated SDK; dismissed firstPositional findings are resolved by the Args-validator rework.

View guided diff | Turn on auto-fix | Re-trigger cubic

cursoragent and others added 2 commits October 16, 2026 14:46
Co-authored-by: Ash <AshGodfrey@users.noreply.github.com>
Co-authored-by: Ash <AshGodfrey@users.noreply.github.com>

@cubic-dev-ai cubic-dev-ai 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.

All reported issues were addressed across 7 files (changes from recent commits).

Shadow auto-approve: would not auto-approve because issues were found.

View guided diff | Turn on auto-fix | Re-trigger cubic

Comment thread templates/templates/cli/auxiliary/internal/output/exitcodes.go.stmpl Outdated
Comment thread templates/templates/cli/auxiliary/internal/output/exitcodes.go.stmpl Outdated
…tore the unknown help topic diagnostic

The flag error handler only re-validates positionals on commands that
reject them, so a parent with its own Args validator reports the flag
error even when the failing flag sits between two valid positionals.
The built-in help command checks for an unresolved topic itself now
that the root no longer relies on root.Find rejecting stray tokens.

@cubic-dev-ai cubic-dev-ai 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.

All reported issues were addressed across 7 files (changes from recent commits).

Shadow auto-approve: would not auto-approve because issues were found.

View guided diff | Turn on auto-fix | Re-trigger cubic

Comment thread zSDKs/sdk-cli/internal/output/exitcodes.go Outdated
Comment thread templates/templates/cli/README.md Outdated
A flag value after a resolved help topic is no longer reported as an
unknown topic. README limits the flag-error positional check to parent
commands that reject positionals.

@cubic-dev-ai cubic-dev-ai 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.

0 issues found across 6 files (changes from recent commits).

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Shadow auto-approve: would auto-approve. Bounded CLI error-handling fix: unknown commands become one-line errors with suggestions as hints, and CLI-origin validation errors drop the dry-run hint; heavily tested, with dismissed firstPositional findings resolved by the Args-validator rework.

View guided diff | Turn on auto-fix | Re-trigger cubic

@2ynn 2ynn left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

csharp Trigger (24) snapshot tests for csharp go Trigger (90) snapshot tests for go java Trigger (40) snapshot tests for java mcp-typescript Trigger (16) snapshot tests for mcp-typescript php Trigger (22) snapshot tests for php python Trigger (106) snapshot tests for python ruby Trigger (19) snapshot tests for ruby typescript Trigger (168) snapshot tests for typescript unity

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants