Skip to content

fix: positional argument completion broken after flags#111

Merged
AmirSa12 merged 3 commits intobombshell-dev:mainfrom
murrayju:fix/positional-completion-after-flags
Apr 24, 2026
Merged

fix: positional argument completion broken after flags#111
AmirSa12 merged 3 commits intobombshell-dev:mainfrom
murrayju:fix/positional-completion-after-flags

Conversation

@murrayju
Copy link
Copy Markdown
Contributor

Problem

Positional argument completion doesn't work when flags precede the argument. For example:

mycli session logs -f <TAB>    # No completions shown
mycli session logs <TAB>        # Works correctly
mycli session info -o json <TAB> # No completions shown

Fixes #110

Root Causes

Three interacting bugs:

1. handlePositionalCompletion doesn't strip options from args

The method uses previousArgs.length to calculate the positional argument index, but previousArgs still contains flags (e.g., ['session', 'logs', '-f']). This inflates the index past the registered arguments array.

Fix: Call this.stripOptions() on the args at the top of handlePositionalCompletion.

2. parse() early-returns after boolean flags

When the previous arg is a boolean flag and the current completion target is empty (TAB pressed), there's an early return that skips both handleCommandCompletion and handlePositionalCompletion:

if (option && option.isBoolean) {
  this.complete(toComplete);
  return;  // skips positional completion
}

Fix: Remove the early return so control falls through to command and positional completion.

3. Commander adapter marks all options as isBoolean=true

The commander adapter registers every option as boolean, even value-taking ones like --output <format>. The option() method on Command infers isBoolean from argument types — when a string alias is passed, it sets isBoolean=true. This causes stripOptions to not skip the value argument for options like --output json.

Fix: In the commander adapter, detect < or [ in the flag syntax string and pass a no-op handler to force isBoolean=false for value-taking options.

Changes

  • src/t.ts: Strip options in handlePositionalCompletion, remove early return in parse()
  • src/commander.ts: Add registerOption helper that detects value-taking options and sets isBoolean correctly
  • tests/cli.test.ts: Update boolean option tests to expect subcommand completions (not empty output) after boolean flags
  • tests/__snapshots__/cli.test.ts.snap: Regenerated snapshots

Testing

All 187 existing tests pass (64 skipped as before — commander and fish integration).

Three interacting bugs prevented positional argument completion when
flags preceded the argument (e.g., 'mycli logs -f <TAB>'):

1. handlePositionalCompletion received raw args including flags, so its
   positional index calculation was inflated. Fix: call stripOptions()
   on previousArgs before counting positions.

2. parse() had an early return after detecting a boolean flag that
   skipped both handleCommandCompletion and handlePositionalCompletion.
   Fix: remove the early return to let control fall through.

3. The commander adapter marked ALL options as isBoolean=true, even
   value-taking ones like '--output <format>'. This caused stripOptions
   to not skip the value argument, further corrupting the positional
   index. Fix: detect '<' or '[' in flag syntax and register with a
   no-op handler to force isBoolean=false.

Fixes bombshell-dev#110
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Mar 16, 2026

🦋 Changeset detected

Latest commit: 5cce0df

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@bomb.sh/tab Patch

Not sure what this means? Click here to learn what changesets are.

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

murrayju and others added 2 commits March 16, 2026 10:48
Remove import reordering, trailing comma additions, arrow function
conversion, and test.each reformatting that were introduced by a
linter not used by the project. Retains only the actual bug fix
for positional completion after flags.
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Apr 24, 2026

Open in StackBlitz

npm i https://pkg.pr.new/@bomb.sh/tab@111

commit: 5cce0df

Copy link
Copy Markdown
Member

@AmirSa12 AmirSa12 left a comment

Choose a reason for hiding this comment

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

I really enjoyed reviewing this. super detailed and nicely engineered.
Thanks a lot for the effort you put into this.. I really appreciate it 🙌

@AmirSa12 AmirSa12 merged commit a9d4f04 into bombshell-dev:main Apr 24, 2026
8 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.

Positional argument completion broken after flags (commander adapter)

2 participants