Skip to content

fix: preserve dash-prefixed tokens in DefaultCommand fallback#31

Merged
tig merged 2 commits into
developfrom
fix/issue-30-dash-prefixed-fallback-args
Jun 12, 2026
Merged

fix: preserve dash-prefixed tokens in DefaultCommand fallback#31
tig merged 2 commits into
developfrom
fix/issue-30-dash-prefixed-fallback-args

Conversation

@tig

@tig tig commented Jun 12, 2026

Copy link
Copy Markdown
Member

Summary

Fixes #30 (Codex P2 from #28's review): when the DefaultCommand fallback re-parsed [DefaultCommand, ..args], dash-prefixed tokens that weren't declared options still failed with Unknown option — so app --literal or app Alice --suffix returned a usage error even though the DefaultCommand contract says unrecognized options are retried as args to the default command.

Approach (test-first)

  1. Red — added integration tests against the greet host: ["--literal"] and ["Alice", "--suffix"] (both failed with exit 64 / Unknown option), plus ["Alice", "--formal"] to pin the recognized-option behavior. Added ArgParser unit tests for the new mode, default-mode rejection, and the no-positionals guard.
  2. GreenArgParser.Parse gains an optional unknownOptionsAsArguments parameter: dash-prefixed tokens matching no framework, global, or command option pass through verbatim as positional arguments. Only CliHost.RunWithDefaultCommandAsync opts in — default parsing is unchanged, and recognized options still parse as options in the fallback.

Commands that don't accept positional args still get the usual does not accept positional arguments usage error, so nothing is silently swallowed.

Spec (constitution C2)

specs/library-spec.md default-command-dispatch section updated to document the pass-through semantics.

Verification

  • Unit 24/24 (3 new), integration 39/39 (3 new; the 2 issue-repro tests failed before the fix and pass after)
  • Build 0 warnings, jb cleanupcode + dotnet format → clean diff

🤖 Generated with Claude Code

When the default-command fallback re-parsed [DefaultCommand, ..args], dash-prefixed tokens that weren't declared options still failed with 'Unknown option' — e.g. 'app --literal' or 'app Alice --suffix' — contradicting the DefaultCommand contract that unrecognized options are retried as args.

Add ArgParser.Parse(args, command, unknownOptionsAsArguments) which passes unknown dash-prefixed tokens through verbatim as positional arguments while recognized framework/global/command options still parse normally. The fallback path in CliHost.RunWithDefaultCommandAsync opts in; the default parse behavior is unchanged. Commands that reject positional args still produce the usual usage error.

Test-first: added failing integration tests (greet host: '--literal', 'Alice --suffix', and 'Alice --formal' for the recognized-option case) and ArgParser unit tests covering the new mode, default-mode rejection, and the no-positionals guard, then implemented the fix. Spec updated per constitution C2.

Fixes #30

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2bcafeb8a2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Terminal.Gui.Cli/ArgParser.cs Outdated
/// through verbatim as positional arguments instead of failing the parse. Used by the
/// default-command fallback so original tokens reach the default command (issue #30).
/// </param>
public ParseResult Parse (string[] args, ICliCommand? command = null, bool unknownOptionsAsArguments = false)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Restore the two-argument Parse overload

Because optional parameters are baked in at compile time, changing the existing public ArgParser.Parse(string[], ICliCommand?) method to a three-argument signature removes the old CLR method. Any already-compiled consumer that calls Parse(args, command) against a newer Terminal.Gui.Cli assembly will hit MissingMethodException unless it is recompiled; keeping the old overload and delegating to the new implementation preserves compatibility while still enabling the fallback behavior.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed in 27d38ab. Restored the original Parse(string[], ICliCommand?) overload delegating to the new three-argument implementation, so already-compiled consumers keep binding to the old CLR method.


Generated by Claude Code

…bility

Optional parameters bind at compile time, so widening the existing public Parse(string[], ICliCommand?) to three parameters removed the old CLR method and would throw MissingMethodException for already-compiled consumers. Keep the original overload delegating to the new three-argument implementation.

Addresses Codex P2 review feedback on #31.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@tig tig merged commit b4d2850 into develop Jun 12, 2026
6 checks passed
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.

Preserve dash-prefixed fallback arguments

1 participant