Skip to main content

fluentui-cli

Guides working with @fluentui/cli — the internal Fluent UI command-line tool. Use when asked to add a new CLI command, modify an existing command, understand CLI architecture, debug CLI issues, or work with the CLI build/test workflow. Covers: architecture overview, yargs conventions, lazy-loading pattern, testing, and available Nx generators.

Source facts

Repository
microsoft/fluentui
Last source activity
September 16, 2026 at 16:40
Detected SKILL.md language
English
Stars
20,324
Forks
2,947

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
2 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
fluentui-cli
description
Guides working with @fluentui/cli — the internal Fluent UI command-line tool. Use when asked to add a new CLI command, modify an existing command, understand CLI architecture, debug CLI issues, or work with the CLI build/test workflow. Covers: architecture overview, yargs conventions, lazy-loading pattern, testing, and available Nx generators.
# `@fluentui/cli` The `@fluentui/cli` package (`tools/cli/`) is the internal Fluent UI command-line tool built with **yargs**. It uses a modular, lazy-loading architecture where each command lives in its own directory and is only loaded at runtime when invoked. ## Architecture ### File Structure ``` tools/cli/ ├── bin/fluentui-cli.js # Node entry point (requires compiled output) ├── src/ │ ├── cli.ts # Main yargs setup, registers all commands │ ├── index.ts # Public API re-exports │ ├── utils/ │ │ ├── index.ts # Barrel exports │ │ └── types.ts # Shared CommandHandler type │ └── commands/ │ ├── metadata/ # API metadata command │ │ ├── index.ts # CommandModule definition │ │ ├── handler.ts # Lazy-loaded handler │ │ └── impl/ # Parsing and formatting │ └── report/ # Reporting command group │ ├── index.ts # Registers report subcommands │ ├── commands/ # info and usage definitions │ └── impl/ # Lazy-loaded report implementations ``` ### Lazy Loading Pattern Command definitions (name, description, options builder) are eagerly imported — they are lightweight. The actual handler logic is **lazy-loaded via dynamic `import()`** only when the command is invoked: ```typescript // index.ts — always loaded (lightweight) handler: async argv => { // handler.ts only loaded when this specific command runs const { handler } = await import('./handler'); return handler(argv); }, ``` This keeps command implementations out of the startup path until the selected command runs. ### CommandHandler Type All handlers use the shared `CommandHandler<T>` type from `src/utils/types.ts`: ```typescript import type { ArgumentsCamelCase } from 'yargs'; export type CommandHandler<T = {}> = (argv: ArgumentsCamelCase<T>) => Promise<void>; ``` ### Command Registration in cli.ts Each command is imported and registered in `tools/cli/src/cli.ts`: ```typescript import yargs from 'yargs'; import reportCommand from './commands/report'; import metadataCommand from './commands/metadata'; export async function main(argv: string[]): Promise<void> { await yargs(argv) .scriptName('fluentui-cli') .usage('$0 <command> [options]') .command(reportCommand) .command(metadataCommand) .demandCommand(1, 'You need to specify a command to run.') .help() .strict() .parse(); } ``` ## Build & Test ```sh # Build the CLI yarn nx run cli:build # Run tests yarn nx run cli:test # Test --help output node tools/cli/bin/fluentui-cli.js --help node tools/cli/bin/fluentui-cli.js <command-name> --help ``` ## Conventions - **Always use the Nx generator** to scaffold new commands — do not create command files manually. See the [adding commands](references/adding-commands.md) reference. - Place shared utilities in `tools/cli/src/utils/` and export through the barrel file. - Every command must support `--help` (handled by yargs `.help()` in the builder). - Handler files must export a named `handler` constant typed with `CommandHandler<T>`. - Tests live adjacent to handlers as `handler.spec.ts`. ## Common Patterns ### Subcommands (nested commands) If a command needs subcommands, use yargs nested command pattern in the builder: ```typescript builder: yargs => yargs .command('summary', 'Generate a summary', subBuilder => subBuilder, summaryHandler) .command('details', 'Generate detailed output', subBuilder => subBuilder, detailsHandler) .demandCommand(1) .help(), ```
View on GitHub