first commit
This commit is contained in:
122
docs/devtools/tooling/cli/src/command/command.md
Normal file
122
docs/devtools/tooling/cli/src/command/command.md
Normal file
@@ -0,0 +1,122 @@
|
||||
# command
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
## Purpose
|
||||
|
||||
`Command` is the core routing primitive for `@suaveplan/cli`. It models a single CLI command that can carry options, positional arguments, and an action handler, or act as a router that delegates to named sub-commands. Every `App` is backed by a root `Command`.
|
||||
|
||||
The class exposes a fluent builder API: chain `.description()`, `.option()`, `.argument()`, `.command()`, and `.action()` calls before calling `.execute()` at runtime. Sub-commands are registered via `.command(name)` which returns the child `Command`, enabling identical fluent chaining for nested hierarchies.
|
||||
|
||||
## Features
|
||||
|
||||
- Fluent builder: `.description()`, `.option()`, `.argument()`, `.action()`, `.command()`, `.alias()`, `.hidden()`, `.example()`
|
||||
- Sub-command routing: first non-flag token in `argv` is matched against registered names and aliases
|
||||
- Option parsing delegated to `parseArgs` — inherits full flag semantics (boolean, string, number, `--no-*`, short flags, `=` syntax, `--` rest)
|
||||
- OTel span on every `execute()` call: span name `cli.command.execute`, attribute `cli.command` set to the full qualified name
|
||||
- `CliError(CLI_CODES.COMMAND.NO_ACTION)` when no action is registered and no sub-command is found
|
||||
- `CliError(CLI_CODES.COMMAND.UNKNOWN_SUBCOMMAND)` when an unknown first token is provided and sub-commands are registered
|
||||
- Automatic `--help` / `-h` handling: prints `helpText()` and returns without error
|
||||
- `helpText(parentName?)` generates a formatted usage block with options and sub-command listing
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import { Command } from "@suaveplan/cli/command/command";
|
||||
|
||||
const cmd = new Command("greet")
|
||||
.description("Greet a user")
|
||||
.option("--name <name>", "Name to greet", "World")
|
||||
.action(async (ctx) => {
|
||||
console.log(`Hello, ${ctx.options.name}!`);
|
||||
});
|
||||
|
||||
await cmd.execute(["--name", "Alice"]);
|
||||
// → Hello, Alice!
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
import { Command } from "@suaveplan/cli/command/command";
|
||||
|
||||
const root = new Command("deploy")
|
||||
.description("Deployment toolkit");
|
||||
|
||||
root
|
||||
.command("up")
|
||||
.description("Bring services up")
|
||||
.option("--env <env>", "Target environment", "staging")
|
||||
.action(async (ctx) => {
|
||||
console.log(`Deploying to ${ctx.options.env}`);
|
||||
});
|
||||
|
||||
root
|
||||
.command("down")
|
||||
.alias("d")
|
||||
.description("Tear services down")
|
||||
.action(async () => {
|
||||
console.log("Tearing down...");
|
||||
});
|
||||
|
||||
// Route: "deploy up --env production"
|
||||
await root.execute(["up", "--env", "production"]);
|
||||
|
||||
// Route by alias: "deploy d"
|
||||
await root.execute(["d"]);
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### `new Command(name: string)`
|
||||
|
||||
Creates a new command with the given name.
|
||||
|
||||
### `.description(text: string): this`
|
||||
|
||||
Sets the human-readable description shown in help text.
|
||||
|
||||
### `.option(flags: string, description?: string, defaultValue?: unknown): this`
|
||||
|
||||
Registers an option. `flags` follows `parseOptionFlags` syntax: `"--name <value>"`, `"-v, --verbose"`.
|
||||
|
||||
### `.argument(spec: string, description?: string): this`
|
||||
|
||||
Registers a positional argument. `spec` follows `parseArgumentSpec` syntax: `"<file>"`, `"[file]"`, `"<files...>"`.
|
||||
|
||||
### `.action(fn: ActionFn): this`
|
||||
|
||||
Sets the action handler. `fn` receives an `ActionContext` with `options`, `args` (positionals), `rest`, and `command` info.
|
||||
|
||||
### `.command(name: string): Command`
|
||||
|
||||
Registers a named sub-command and returns it for further chaining.
|
||||
|
||||
### `.alias(name: string): this`
|
||||
|
||||
Adds an alias for this command, recognised during routing.
|
||||
|
||||
### `.hidden(): this`
|
||||
|
||||
Marks the command as hidden — it is excluded from help text listings.
|
||||
|
||||
### `.example(text: string): this`
|
||||
|
||||
Adds an example line shown in help text.
|
||||
|
||||
### `.helpText(parentName?: string): string`
|
||||
|
||||
Returns formatted multi-line help text including usage, options, sub-commands, and examples.
|
||||
|
||||
### `.getParserConfig(): ParserConfig`
|
||||
|
||||
Returns the `ParserConfig` derived from registered options and arguments. Used internally by `execute()`.
|
||||
|
||||
### `.execute(argv: string[], parentName?: string): Promise<void>`
|
||||
|
||||
Parses `argv`, routes to sub-commands or calls the action. Wraps the execution in an OTel span. Throws `CliError` on routing or parse failures.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
Sub-command alias resolution scans all registered sub-commands for an `_aliases` entry matching the first token. An OTel span covers the full `execute()` lifecycle including sub-command delegation — the span status is set to `ERROR` if any exception propagates. The `--help` / `-h` shortcut is handled before sub-command routing and before the action call, so it always works even if no action is registered.
|
||||
Reference in New Issue
Block a user