| name | cli-building |
| description | Use when building TypeScript CLIs. Guides command structure, interactive prompts, tab completion, and terminal UI niceties (spinners, progress, inline regions) using citty, `@clack/prompts`, `@bomb.sh/tab`, and `@bomb.sh/tty` โ and shipping them: CI gates, versioning (Changesets / release-please), and npm or single-binary release. |
Citty CLI
Quick Start
npm install citty `@bomb.sh/tab` `@clack/prompts`
Minimal command:
import { defineCommand, runMain } from 'citty';
export default defineCommand({
meta: { name: 'greet', description: 'Say hello' },
args: { name: { type: 'string', description: 'Your name', required: true } },
run({ args }) { console.log(`Hello, ${args.name}!`); },
});
Critical Rules
- Every command exports default
defineCommand() โ no exceptions
- Lazy-load subcommands โ
() => import('./cmd').then(m => m.default)
- Check
isCancel() after every @clack/prompts call โ never skip
- Citty handles all arg parsing โ no external parsers
- Architecture is opt-in โ only suggest
cli/ structure when the user asks for project layout or scaffolding. Single-file CLIs are valid.
- Gate
tab() behind process.argv[2] === 'complete' โ the adapter eagerly resolves lazy subcommands, defeating rule 2 on every startup
Architecture (only when user asks for structure)
See architecture for the full cli/ layout with commands, prompts, and lib directories. Do not impose this structure unless the user explicitly asks for scaffolding or project organization.
Workflow
- Define commands โ commands
- Add prompts if interactive โ prompts
- Add spinners/progress for long-running work โ tty-ui
- Wire tab completion โ tab-completion
- Scaffold
cli/ if multi-command โ architecture
- Configure bin entry โ sidecar setup
- Verify โ run with
--help to confirm command registration
- Ship it โ CI gates, versioning, npm or binary release โ release
References
- Architecture โ Structure and responsibilities
- Entrypoint โ runMain + tab completion wiring
- Commands โ defineCommand, args, subcommands
- Prompts โ
@clack/prompts reusable modules
- Tab Completion โ
@bomb.sh/tab citty adapter, completion protocol, per-shell install (compinit ordering, fish autoload), lazy-loading gate
- TTY UI โ spinners and progress:
@clack/prompts spinner first, @bomb.sh/tty inline regions and layout for richer feedback
- Sidecar Setup โ bin entry, build config
- Citty API โ Resolvable, plugins, CLIError
- Release โ CI gates, Changesets/release-please, npm + binary distribution
- Versioning โ named schemes (SemVer/CalVer), 0.x vs 1.0, pre-releases, which bump, decision matrix, recording the policy
- Update Command โ ask-first self-update: install-mode routing, streaming download (stall timeout, resumable retry), checksum-verified atomic swap, passive banner