Skip to content

fix(parser): flatten option groups automatically - #16

Merged
steipete merged 1 commit into
mainfrom
codex/flatten-option-groups
Aug 12, 2026
Merged

fix(parser): flatten option groups automatically#16
steipete merged 1 commit into
mainfrom
codex/flatten-option-groups

Conversation

@steipete

Copy link
Copy Markdown
Owner

Summary

  • make CommandParser normalize nested @OptionGroup signatures at its public ownership boundary
  • preserve recursive groups through the existing CommandSignature.flattened() implementation
  • document direct-parser behavior and add an end-to-end property-wrapper regression

Why

CommandSignature.describe(command) retains reusable groups as nested metadata. Direct CommandParser callers could pass that public signature unchanged, but grouped options and flags were silently absent from parser lookup tables unless every caller remembered to flatten it first. The parser now owns that normalization, matching Commander's property-wrapper ergonomics and making already-flattened signatures remain idempotent.

Testing

  • focused option-group parser regression: passed
  • swift test: 43/43 passed
  • swift test -c release: 43/43 passed
  • swiftformat --lint .: 0/14 files require formatting
  • swiftlint lint --config .swiftlint.yml: 0 violations
  • git diff --check: passed
  • TruffleHog and structured Autoreview: clean, no actionable findings

@clawsweeper

clawsweeper Bot commented Aug 12, 2026

Copy link
Copy Markdown

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

@clawsweeper clawsweeper Bot added P2 Normal priority bug or improvement with limited blast radius. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Aug 12, 2026
@clawsweeper

clawsweeper Bot commented Aug 12, 2026

Copy link
Copy Markdown

Codex review: needs maintainer review before merge. Reviewed August 12, 2026, 5:36 PM ET / 21:36 UTC.

ClawSweeper review

What this changes

The PR makes direct CommandParser construction flatten nested option groups, with documentation and regression coverage.

Merge readiness

⚠️ Ready for maintainer review - 2 items remain

Keep open for normal merge handling: the focused parser normalization matches the existing signature model, and no actionable patch defect was found. This owner-authored PR is not eligible for automated cleanup.

Priority: P2
Reviewed head: 881a4f96efc22b7b9b327a00deaba6ac6f300d08

Review scores

Measure Result What it means
Overall readiness 🐚 platinum hermit (4/6) A focused, source-supported parser repair with an appropriate regression test; normal platform checks remain in progress.
Proof confidence 🌊 off-meta tidepool Not applicable: This owner-authored PR includes focused regression coverage and reported test runs; the external-contributor proof gate does not apply.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Verification

Check Result Evidence
Real behavior Not applicable Not applicable: This owner-authored PR includes focused regression coverage and reported test runs; the external-contributor proof gate does not apply.
Evidence reviewed 5 items Parser ownership boundary: The parser constructs lookup tables only from the signature's direct option and flag arrays, while reflected option groups remain nested; calling the established flattener in the initializer makes direct reflected signatures work.
Existing recursive normalization: flattened() already recursively merges every nested group's arguments, options, and flags, so the patch reuses rather than duplicates normalization behavior.
Focused regression coverage: The added test passes a reflected command signature directly to the parser and verifies both grouped options and flags are parsed.
Findings None None.
Security None None.

How this fits together

Commander reflects property-wrapper command definitions into a command signature, then gives that metadata to the parser to interpret CLI arguments. Option groups are reusable nested metadata whose options and flags must reach parser lookup tables.

flowchart LR
  A[Command definition] --> B[Signature reflection]
  B --> C[Option groups]
  C --> D[Parser normalization]
  D --> E[Argument lookup]
  E --> F[Parsed command values]
Loading

Before merge

  • Resolve merge risk (P1) - The supplied PR state shows the macOS and Ubuntu Swift checks still in progress; merge should wait for their completion.
  • Complete next step (P2) - No repair lane is indicated; await ordinary required-check completion before merging.
Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Implementation and coverage implementation +1, docs/release +5, tests +18 The behavioral change is narrow and has direct regression coverage.

Merge-risk options

Maintainer options:

  1. Decide the mitigation before merge
    Land the focused parser-boundary normalization after the remaining platform checks succeed.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Technical review

Best possible solution:

Land the focused parser-boundary normalization after the remaining platform checks succeed.

Do we have a high-confidence way to reproduce the issue?

Yes, from source: pass CommandSignature.describe for a command containing an option group directly to CommandParser, then parse a grouped option or flag; current main leaves those group entries outside its lookup tables.

Is this the best way to solve the issue?

Yes. Normalizing once at CommandParser construction reuses the established recursive flattener and covers direct parser and Program callers without imposing a caller-side step.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against a0bbecd4aad9.

Labels

Label changes:

  • add P2: This is a bounded parser correctness repair for direct API callers.
  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🌊 off-meta tidepool and patch quality is 🐚 platinum hermit.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Not applicable: This owner-authored PR includes focused regression coverage and reported test runs; the external-contributor proof gate does not apply.

Label justifications:

  • P2: This is a bounded parser correctness repair for direct API callers.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🌊 off-meta tidepool and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Not applicable: This owner-authored PR includes focused regression coverage and reported test runs; the external-contributor proof gate does not apply.

Evidence

What I checked:

Likely related people:

  • steipete: Peter Steinberger authored the visible recent parser and command-signature history; repository context maps this work to the steipete owner handle. (role: recent parser contributor; confidence: high; commits: 7f781c9e0640, 0c010b87fdda, 881a4f96efc2; files: Sources/Commander/Parser/CommandParser.swift, Sources/Commander/CommandSignature.swift, Sources/Commander/PropertyWrappers.swift)

Rank-up moves

Optional improvements that raise the rating; they are not merge blockers.

  • Wait for the macOS and Ubuntu Swift checks to complete successfully.

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

Workflow

  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@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: 881a4f96ef

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".


public init(signature: CommandSignature) {
self.signature = signature
self.signature = signature.flattened()

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 Preserve grouped positional argument order

When an @OptionGroup type contains positional @Arguments, this unconditional flattening sends every parser through CommandSignature.flattened(), which appends grouped arguments after all parent arguments before validation. For a declaration such as an option group with @Argument input followed by a parent @Argument(parsing: .remaining) rest, parsing now throws invalidArgumentOrder("rest") because the variadic parent argument is moved ahead of the grouped argument; non-variadic grouped arguments are likewise interpreted in the wrong positional order. Either flatten only options/flags here or preserve declaration order for grouped positional arguments.

Useful? React with 👍 / 👎.

@steipete
steipete merged commit ddc3b9f into main Aug 12, 2026
7 checks passed
@steipete
steipete deleted the codex/flatten-option-groups branch August 12, 2026 21:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P2 Normal priority bug or improvement with limited blast radius. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant