[READ-ONLY] Mirror of https://github.com/bombshell-dev/docs. bomb.sh/docs
0

Configure Feed

Select the types of activity you want to include in your feed.

docs(tab): sync docs through v0.0.17 (#56)

authored by

paul valladares and committed by
GitHub
(Jun 20, 2026, 12:08 PM -0500) 3860be3c 19897d7f

+133 -9
+133 -9
src/content/docs/tab/index.mdx
··· 7 7 8 8 Additionally, tab supports autocompletions for `pnpm`, `npm`, `yarn`, and `bun`. 9 9 10 - Modern CLI libraries like [Gunshi](https://github.com/kazupon/gunshi) include tab completion natively in their core. 10 + Modern CLI libraries like [Gunshi](https://github.com/kazupon/gunshi) include tab completion natively in their core. 11 + 12 + Major CLIs and tooling projects including Cloudflare, Nuxt, Astro, and Vitest also adopted tab to provide shell completions for their users. 11 13 12 14 As CLI tooling authors, if we can spare our users a second or two by not checking documentation or writing the `-h` flag, we're doing them a huge favor. The unconscious mind loves hitting the [TAB] key and always expects feedback. When nothing happens, it breaks the user's flow - a frustration apparent across the whole JavaScript CLI tooling ecosystem. 13 15 14 16 tab solves this complexity by providing autocompletions that work consistently across `zsh`, `bash`, `fish`, and `powershell`. 15 17 16 18 ## Installation 19 + 20 + ### For Package Manager Completions 21 + 22 + Global install is recommended: 23 + 24 + ```bash 25 + npm install -g @bomb.sh/tab 26 + ``` 27 + 28 + Then enable completions permanently: 29 + 30 + ```bash 31 + # For zsh 32 + echo 'source <(tab pnpm zsh)' >> ~/.zshrc 33 + source ~/.zshrc 34 + 35 + # For bash 36 + echo 'source <(tab pnpm bash)' >> ~/.bashrc 37 + source ~/.bashrc 38 + 39 + ``` 40 + 41 + ### For CLI Library (Adding Completions to Your CLI) 17 42 18 43 ```bash 19 44 npm install @bomb.sh/tab ··· 70 95 echo 'source ~/.my-cli-completion.zsh' >> ~/.zshrc 71 96 ``` 72 97 98 + ## Positional Arguments 99 + 100 + In addition to options, tab supports positional arguments with completion handlers: 101 + 102 + ```typescript 103 + // Root-level positional arg 104 + t.argument('project', (complete) => { 105 + complete('my-app', 'My application'); 106 + }); 107 + 108 + // Command-level positional args 109 + t.command('copy', 'Copy files') 110 + .argument('source', (complete) => { 111 + complete('src/', 'Source directory'); 112 + complete('dist/', 'Distribution directory'); 113 + }) 114 + .argument('destination', (complete) => { 115 + complete('build/', 'Build output'); 116 + complete('release/', 'Release directory'); 117 + }); 118 + 119 + // Variadic arguments (pass true as the third argument) 120 + t.command('lint', 'Lint project').argument( 121 + 'files', 122 + (complete) => { 123 + complete('src/', 'Source directory'); 124 + complete('tests/', 'Tests directory'); 125 + }, 126 + true 127 + ); 128 + ``` 129 + 130 + Framework adapters infer positional arguments from your CLI framework definitions. See the [Commander.js integration](#commanderjs-integration) below for adapter-specific examples. 131 + 73 132 ## Package Manager Completions 74 133 75 134 As mentioned earlier, tab provides completions for package managers as well: 76 135 77 136 ```bash 78 - # Generate and install completion scripts 137 + # Generate and install completion scripts (requires global install) 138 + tab pnpm zsh > ~/.pnpm-completion.zsh && echo 'source ~/.pnpm-completion.zsh' >> ~/.zshrc 139 + tab npm bash > ~/.npm-completion.bash && echo 'source ~/.npm-completion.bash' >> ~/.bashrc 140 + tab yarn fish > ~/.config/fish/completions/yarn.fish 141 + tab bun powershell > ~/.bun-completion.ps1 && echo '. ~/.bun-completion.ps1' >> $PROFILE 142 + ``` 143 + 144 + Without a global install, use `npx`: 145 + 146 + ```bash 79 147 npx @bomb.sh/tab pnpm zsh > ~/.pnpm-completion.zsh && echo 'source ~/.pnpm-completion.zsh' >> ~/.zshrc 80 - npx @bomb.sh/tab npm bash > ~/.npm-completion.bash && echo 'source ~/.npm-completion.bash' >> ~/.bashrc 81 - npx @bomb.sh/tab yarn fish > ~/.config/fish/completions/yarn.fish 82 - npx @bomb.sh/tab bun powershell > ~/.bun-completion.ps1 && echo '. ~/.bun-completion.ps1' >> $PROFILE 83 148 ``` 84 149 85 150 Example in action: ··· 91 156 yarn add --emoji=<TAB> 92 157 # Shows: true, false 93 158 ``` 159 + 160 + ### Completing locally-installed CLIs 161 + 162 + Package manager completion does more than complete the package manager's own flags — it also **delegates to CLIs installed as local project dependencies**. If a CLI implements tab's completion protocol (directly or via a [framework adapter](#framework-adapters)), it becomes completable through your package manager _without_ being on your `PATH` and without installing its completion script separately: 163 + 164 + ```bash 165 + pnpm exec my-cli <TAB> # completes my-cli's subcommands and flags 166 + pnpm dlx my-cli <TAB> 167 + pnpm my-cli <TAB> # the bare form works too 168 + ``` 169 + 170 + Under the hood, tab strips the package-manager wrapper (`exec`, `x`, `run`, `dlx`), detects whether the target CLI supports completion, and forwards the request to it — falling back to running the CLI _through_ the package manager (e.g. `pnpm my-cli complete -- …`) so locally-installed binaries resolve. The same works for `npm exec`, `yarn`, and `bun x`. 171 + 172 + Completion is registered against the package-manager binary (`npm`, `pnpm`, `yarn`, `bun`). `npx` and `bunx` are separate commands with no completion of their own, so `npx my-cli <TAB>` / `bunx my-cli <TAB>` won't complete — use `npm exec my-cli` / `bun x my-cli` instead. 94 173 95 174 ## Framework Adapters 96 175 ··· 165 244 ### Commander.js Integration 166 245 167 246 ```typescript 168 - import { Command } from 'commander'; 247 + import { Command, Option } from 'commander'; 169 248 import tab from '@bomb.sh/tab/commander'; 170 249 171 250 const program = new Command('my-cli'); 172 251 program.version('1.0.0'); 173 252 174 - // Define commands 253 + // Options with .choices() get completions automatically 254 + program.addOption( 255 + new Option('-l, --logLevel <level>', 'Specify log level').choices([ 256 + 'info', 257 + 'warn', 258 + 'error', 259 + 'silent', 260 + ]) 261 + ); 262 + 175 263 program 176 264 .command('serve') 177 265 .description('Start the server') 178 266 .option('-p, --port <number>', 'port to use', '3000') 179 267 .option('-H, --host <host>', 'host to use', 'localhost') 180 - .action((options) => { 268 + .action(() => { 181 269 console.log('Starting server...'); 182 270 }); 183 271 272 + program 273 + .command('lint [files...]') 274 + .description('Lint source files') 275 + .option('--fix', 'automatically fix problems'); 276 + 277 + program 278 + .command('copy <source> <destination>') 279 + .description('Copy files'); 280 + 184 281 // Initialize tab completions 185 282 const completion = tab(program); 186 283 187 - // Add custom completions 284 + // Custom option completions 188 285 const serveCommand = completion.commands.get('serve'); 189 286 const portOption = serveCommand?.options.get('port'); 190 287 if (portOption) { ··· 194 291 }; 195 292 } 196 293 294 + // Custom positional argument completions 295 + const lintCommand = completion.commands.get('lint'); 296 + const filesArg = lintCommand?.arguments.get('files'); 297 + if (filesArg) { 298 + filesArg.handler = (complete) => { 299 + complete('main.ts', 'Main file'); 300 + complete('index.ts', 'Index file'); 301 + }; 302 + } 303 + 304 + const copyCommand = completion.commands.get('copy'); 305 + const sourceArg = copyCommand?.arguments.get('source'); 306 + if (sourceArg) { 307 + sourceArg.handler = (complete) => { 308 + complete('src/', 'Source directory'); 309 + complete('dist/', 'Distribution directory'); 310 + }; 311 + } 312 + 197 313 program.parse(); 314 + ``` 315 + 316 + Options defined with Commander's `.choices()` are picked up automatically — no custom handler needed. For positional arguments, the adapter reads argument definitions from your commands; add handlers via `arguments.get('name')` when you need custom suggestions. 317 + 318 + The Commander integration supports customising the command name used to generate shell completion scripts. The default is `complete`. If you use a custom name like `completion`, it appears in help as `completion <shell>`, while runtime suggestions stay on the hidden `complete -- [args...]` command. Use your custom command when generating shell scripts: 319 + 320 + ```javascript 321 + const completion = tab(program, { completionCommandName: 'completion' }); 198 322 ``` 199 323 200 324 ## How It Works