Skip to content

Conversation

@cevr
Copy link
Contributor

@cevr cevr commented Jan 26, 2026

Summary

Follow-up to #5983. Extends parent option parsing to work across subcommand boundaries.

Enables parent/global options to appear anywhere in the command line, including after subcommand names and their arguments. This follows the common CLI pattern used by git, npm, docker, and most modern CLI tools.

Before

cli --global-opt subcommand arg     # works
cli subcommand arg --global-opt     # fails: "unknown option"

After

cli --global-opt subcommand arg     # works  
cli subcommand arg --global-opt     # works ✓

Motivation: The Centralized Flags Pattern

Many CLI applications define global options on the parent command that affect all subcommands:

const app = Command.make("app", {
  verbose: Options.boolean("verbose").pipe(Options.withAlias("v")),
  model: Options.text("model").pipe(Options.withAlias("m")),
}).pipe(
  Command.withSubcommands([process, export, list])
)

Users naturally expect to place these global options at the end of their command:

# Natural user expectation
app process input.txt -m gpt4 --verbose

# What was previously required  
app -m gpt4 --verbose process input.txt

This change removes that friction by extracting known parent options from anywhere in the args.

Implementation

  1. getParentOptionNames() - Collects all option names (including aliases) from a parent command
  2. extractParentOptionsFromArgs() - Scans args after the subcommand for known parent options and extracts them
  3. Modified Subcommands case in parseInternal to use these helpers before splitting args

Uses Set for O(1) lookups on both subcommand names and parent option names.

Test Plan

  • Added tests for parent options after subcommand args
  • Added tests for parent option aliases after subcommand args
  • Verified existing tests still pass (162 tests)
  • Tested with --option=value format
  • Tested mixed positioning (some before, some after subcommand)

🤖 Generated with Claude Code

@cevr cevr requested a review from IMax153 as a code owner January 26, 2026 03:20
@github-project-automation github-project-automation bot moved this to Discussion Ongoing in PR Backlog Jan 26, 2026
@changeset-bot
Copy link

changeset-bot bot commented Jan 26, 2026

⚠️ No Changeset found

Latest commit: c8c5f43

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Enables parent/global options to appear anywhere in the command line,
including after subcommand names and their arguments. This follows the
common CLI pattern used by git, npm, docker, and most modern CLI tools.

Before:
  cli --global-opt subcommand arg     # works
  cli subcommand arg --global-opt     # fails: "unknown option"

After:
  cli --global-opt subcommand arg     # works
  cli subcommand arg --global-opt     # works

This is useful for the "centralized flags" pattern where global options
like --verbose, --config, or --model are defined on the parent command
and inherited by all subcommands. Users can now place these options
at the end of the command for better ergonomics.

Implementation:
- Extract parent option names before splitting args at subcommand boundary
- Scan args after subcommand for known parent options
- Pass extracted parent options to parent command parsing

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@cevr cevr force-pushed the fix/cli-parent-options-after-subcommand branch from ad5704b to c8c5f43 Compare January 26, 2026 03:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Discussion Ongoing

Development

Successfully merging this pull request may close these issues.

1 participant