From ab9658617a21a07215e2e3ac8ee7bb7e26e01ace Mon Sep 17 00:00:00 2001 From: Tim Oelkers Date: Tue, 10 Nov 2026 10:49:43 +0100 Subject: [PATCH] fix: stop completing a root command argument again after it has been given `handlePositionalCompletion` subtracts the command's name words from the typed words to find the argument index. The root command's value is '', and ''.split(' ') has length 1, so one argument too few was counted: after `my-cli my-app ` the root's first argument was completed again. --- .changeset/brave-roots-count.md | 5 +++++ src/t.ts | 4 ++-- tests/cli.test.ts | 6 ++++++ 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 .changeset/brave-roots-count.md diff --git a/.changeset/brave-roots-count.md b/.changeset/brave-roots-count.md new file mode 100644 index 0000000..7322a13 --- /dev/null +++ b/.changeset/brave-roots-count.md @@ -0,0 +1,5 @@ +--- +'@bomb.sh/tab': patch +--- + +fix: stop completing a root command argument again after it has been given diff --git a/src/t.ts b/src/t.ts index b22cd9c..5126abd 100644 --- a/src/t.ts +++ b/src/t.ts @@ -351,8 +351,8 @@ export class RootCommand extends Command { private handlePositionalCompletion(command: Command, previousArgs: string[]) { // Strip options so flags don't inflate the positional index const strippedArgs = this.stripOptions(previousArgs); - // current argument position (subtract command name) - const commandParts = command.value.split(' ').length; + // current argument position (subtract command name; the root has none) + const commandParts = command === this ? 0 : command.value.split(' ').length; const currentArgIndex = Math.max(0, strippedArgs.length - commandParts); const argumentEntries = Array.from(command.arguments.entries()); diff --git a/tests/cli.test.ts b/tests/cli.test.ts index 742a509..e46c43b 100644 --- a/tests/cli.test.ts +++ b/tests/cli.test.ts @@ -251,6 +251,12 @@ describe.each(cliTools)('cli completion tests for %s', (cliTool) => { const output = await runCommand(command); expect(output).toMatchSnapshot(); }); + + it('should not complete root command project argument again after it is given', async () => { + const command = `${commandPrefix} my-app ""`; + const output = await runCommand(command); + expect(output).toBe(':4\n'); + }); }); describe('root command option tests', () => {