Skip to content

Core API

This page provides the complete API reference for the Tab core package, including all classes, methods, types, and interfaces.

The main class for managing command and option completions. This is the primary entry point for defining your CLI structure.

import { RootCommand } from '@bombsh/tab';
const t = new RootCommand();

Adds a command with optional description and returns a Command instance for further configuration.

Parameters:

  • name (string): The command name
  • description (string, optional): Command description

Returns: Command - A Command instance for chaining

Example:

// Simple command
const devCmd = t.command('dev', 'Start development server');
// Nested command
const buildCmd = t.command('dev build', 'Build project');

Adds a global option to the root command.

Parameters:

  • name (string): The option name (e.g., ‘—config’)
  • description (string): Option description
  • handler (OptionHandler, optional): Function that provides completion suggestions
  • alias (string, optional): Short flag alias (e.g., ‘c’ for ‘—config’)

Returns: RootCommand - For method chaining

Example:

t.option('--config', 'Use specified config file', function(complete) {
complete('vite.config.ts', 'Vite config file');
complete('vite.config.js', 'Vite config file');
}, 'c');

Adds a positional argument to the root command.

Parameters:

  • name (string): The argument name
  • handler (ArgumentHandler, optional): Function that provides completion suggestions
  • variadic (boolean, optional): Whether this is a variadic argument (default: false)

Returns: RootCommand - For method chaining

Example:

t.argument('project', function(complete) {
complete('my-app', 'My application');
complete('my-lib', 'My library');
});

Parses command line arguments and outputs completion suggestions to stdout.

Parameters:

  • args (string[]): Command line arguments

Example:

const separatorIndex = process.argv.indexOf('--');
const completionArgs = separatorIndex !== -1 ? process.argv.slice(separatorIndex + 1) : [];
t.parse(completionArgs);

Generates shell completion scripts.

Parameters:

  • name (string): CLI tool name
  • executable (string): Executable path for the CLI tool
  • shell (string): Target shell (‘zsh’, ‘bash’, ‘fish’, ‘powershell’)

Example:

t.setup('my-cli', process.execPath, 'zsh');

Represents a command with its options and arguments.

const cmd = t.command('dev', 'Start development server');

Adds an option to this command.

Parameters:

  • name (string): The option name (e.g., ‘—port’)
  • description (string): Option description
  • handler (OptionHandler, optional): Function that provides completion suggestions
  • alias (string, optional): Short flag alias (e.g., ‘p’ for ‘—port’)

Returns: Command - For method chaining

Example:

cmd.option('--port', 'Port number', function(complete) {
complete('3000', 'Development port');
complete('8080', 'Production port');
}, 'p');

Adds a positional argument to this command.

Parameters:

  • name (string): The argument name
  • handler (ArgumentHandler, optional): Function that provides completion suggestions
  • variadic (boolean, optional): Whether this is a variadic argument (default: false)

Returns: Command - For method chaining

Example:

cmd.argument('entry', function(complete) {
complete('src/main.ts', 'Main entry point');
complete('src/index.ts', 'Index entry point');
});

Function type for option completion handlers.

type OptionHandler = (
this: Option,
complete: Complete,
options: OptionsMap
) => void;

Parameters:

  • this: The Option instance
  • complete: Function to call with completion suggestions
  • options: Map of all options for this command

Example:

const handler: OptionHandler = function(complete) {
complete('3000', 'Development port');
complete('8080', 'Production port');
};

Function type for argument completion handlers.

type ArgumentHandler = (
this: Argument,
complete: Complete,
options: OptionsMap
) => void;

Parameters:

  • this: The Argument instance
  • complete: Function to call with completion suggestions
  • options: Map of all options for this command

Example:

const handler: ArgumentHandler = function(complete) {
complete('src/main.ts', 'Main entry point');
complete('src/index.ts', 'Index entry point');
};

Function type for providing completion suggestions.

type Complete = (value: string, description: string) => void;

Parameters:

  • value (string): The completion value
  • description (string): Description of the completion

Example:

function(complete) {
complete('3000', 'Development port');
complete('8080', 'Production port');
}

Object representing a completion suggestion.

type Completion = {
value: string;
description?: string;
};

Properties:

  • value (string): The completion value
  • description (string, optional): Description of the completion

Example:

const completion: Completion = {
value: '3000',
description: 'Development port'
};

Bit map representing different behaviors the shell can be instructed to have.

export const ShellCompDirective = {
ShellCompDirectiveError: 1 << 0,
ShellCompDirectiveNoSpace: 1 << 1,
ShellCompDirectiveNoFileComp: 1 << 2,
ShellCompDirectiveFilterFileExt: 1 << 3,
ShellCompDirectiveFilterDirs: 1 << 4,
ShellCompDirectiveKeepOrder: 1 << 5,
shellCompDirectiveMaxValue: 1 << 6,
ShellCompDirectiveDefault: 0,
};

Here’s a complete example showing all the core API features:

#!/usr/bin/env node
import { RootCommand } from '@bombsh/tab';
const t = new RootCommand();
// Add global options
t.option('--config', 'Use specified config file', function(complete) {
complete('vite.config.ts', 'Vite config file');
complete('vite.config.js', 'Vite config file');
}, 'c');
t.option('--mode', 'Set env mode', function(complete) {
complete('development', 'Development mode');
complete('production', 'Production mode');
}, 'm');
// Add root command argument
t.argument('project', function(complete) {
complete('my-app', 'My application');
complete('my-lib', 'My library');
});
// Add commands with completions
const devCmd = t.command('dev', 'Start development server');
devCmd.option('--port', 'Port number', function(complete) {
complete('3000', 'Development port');
complete('8080', 'Production port');
}, 'p');
devCmd.option('--host', 'Hostname', function(complete) {
complete('localhost', 'Localhost');
complete('0.0.0.0', 'All interfaces');
}, 'H');
devCmd.option('--verbose', 'Enable verbose logging', 'v');
// Add nested commands
t.command('dev build', 'Build project');
t.command('dev start', 'Start development server');
// Add command with arguments
t.command('copy', 'Copy files')
.argument('source', function(complete) {
complete('src/', 'Source directory');
complete('dist/', 'Distribution directory');
})
.argument('destination', function(complete) {
complete('build/', 'Build output');
complete('release/', 'Release directory');
});
// Add command with variadic arguments
t.command('lint', 'Lint project')
.argument('files', function(complete) {
complete('main.ts', 'Main file');
complete('src/', 'Source directory');
}, true); // true = variadic argument
// Handle completion requests
if (process.argv[2] === 'complete') {
const shell = process.argv[3];
if (shell && ['zsh', 'bash', 'fish', 'powershell'].includes(shell)) {
t.setup('my-cli', process.execPath, shell);
} else {
// Parse completion arguments (everything after --)
const separatorIndex = process.argv.indexOf('--');
const completionArgs = separatorIndex !== -1 ? process.argv.slice(separatorIndex + 1) : [];
t.parse(completionArgs);
}
} else {
// Regular CLI usage
console.log('My CLI Tool');
console.log('Use "complete" command for shell completion');
}

Make your completions responsive to what the user is typing:

devCmd.option('--port', 'Port number', function(complete) {
// Check if user is typing a specific port
if (this.toComplete?.startsWith('30')) {
complete('3000', 'Development port');
return;
}
complete('3000', 'Development port');
complete('8080', 'Production port');
complete('9000', 'Alternative port');
}, 'p');

Load completions from external sources:

devCmd.option('--config', 'Config file', async function(complete) {
try {
const files = await fs.readdir('.');
const configFiles = files.filter(f => f.includes('config'));
configFiles.forEach(file => complete(file, `Config file: ${file}`));
} catch (error) {
// Fallback completions
complete('vite.config.ts', 'Vite config file');
}
});

For boolean flags, you don’t need a handler:

devCmd.option('--verbose', 'Enable verbose logging', 'v');
devCmd.option('--quiet', 'Suppress output');