command()
function command(cmd: cli.Command): cli.Commandcommand() returns its argument unchanged. Its whole job is type inference: it lets you define a
command as a standalone value and still get run(args) typed from the arguments and options you
declared.
import { command } from 'clibuilder'
const build = command({ name: 'build', description: 'build the project', options: { watch: { description: 'rebuild on change', alias: ['w'] } }, run(args) { this.ui.info(args.watch ? 'watching' : 'building once') }})Commands passed inline to .command() or .default() are inferred without it — reach for
command() when the command lives in its own variable or its own file.
cli.Command
Section titled “cli.Command”| Field | Type | Description |
|---|---|---|
name |
string |
The command’s name on the command line. Required for named commands; omitted for a .default() command. |
description |
string |
Shown in the help message. |
alias |
string[] |
Alternate names — alias: ['rm'] makes app remove answer to app rm. |
arguments |
Argument[] |
Positional arguments, in order. |
options |
Options |
Named options, keyed by option name. |
config |
z.ZodTypeAny |
The schema this command’s config must satisfy. Declaring it triggers the config load. |
context |
Record<string, any> |
Arbitrary values handed back on this.context — the seam for injecting I/O in tests. |
commands |
Command[] |
Sub-commands. |
onUsageError |
UsageErrorHandler |
Takes over how usage errors are reported for this command and its sub-commands. See Reporting usage errors yourself. |
run |
function |
What the command does. |
A command must have either a run or a commands. A command with commands and no run is a
group: invoking it prints its help message.
Arguments
Section titled “Arguments”type Argument = { name: string description: string type?: z.ZodType<any>}Positional, matched in declaration order. type defaults to string. An array type makes the argument
variadic, consuming the remaining positionals; z.optional() makes it optional. Argument values are
coerced to the declared type — see
Arguments & Options.
arguments: [ { name: 'src', description: 'source file' }, { name: 'dest', description: 'destination', type: z.optional(z.string()) }]Options
Section titled “Options”type Options = Record<string, { description: string type?: z.ZodType<any> default?: z.infer<Type> alias?: Array<string | { alias: string; hidden: boolean }> conflicts?: string[] // options this one cannot be used with}>type defaults to a flag (boolean | undefined). Option values are coerced to the declared type,
and a value that fails is a usage error.
options: { port: { description: 'port to listen on', type: z.number(), default: 3000, alias: ['p'] }, quiet: { description: 'suppress output', alias: ['q', { alias: 'shh', hidden: true }] }}A hidden alias works but is left out of the help message.
run(this: RunContext, args: RunArgs): Promise<any> | anyDeclare it as a method, not an arrow function — this is what carries the command’s context.
| Property | Type | Description |
|---|---|---|
this.ui |
UI |
Output — info, warn, error, debug, showHelp, showVersion. |
this.config |
z.infer<ConfigType> |
The loaded, validated config. undefined when the command declared no config. |
this.cwd |
string |
The directory the CLI was invoked from. |
this.keywords |
string[] |
The CLI’s plugin keywords. |
this.context |
Context |
Whatever the command declared as context. |
An object holding every declared argument and option by name, plus the
built-in options — args.help is
always present.
Return value
Section titled “Return value”Whatever run() returns (or resolves to) becomes the resolved value of
parse(), and the result from
testCommand().
PluginActivationContext
Section titled “PluginActivationContext”The argument a plugin’s activate() receives:
type PluginActivationContext = { addCommand(command: cli.Command): void register<T>(key: ValueKey<T> | CollectionKey<T>, value: T): void get<T>(key: ValueKey<T>): T | undefined get<T>(key: CollectionKey<T>): readonly Contribution<T>[] has(key: RegistryKey<unknown>): boolean host: { name: string; version: string }}import { command, type PluginActivationContext } from 'clibuilder'
export function activate({ addCommand }: PluginActivationContext) { addCommand(command({ name: 'sing', description: 'sing a song', run() { this.ui.info('🎵') } }))}defineKey() creates a single-value capability key; the first plugin to register one wins. Use
defineCollectionKey() for values contributed by multiple plugins. Command run() methods receive
the same read-only registry as this.registry, which is the preferred place to resolve values.