<!-- Generated by scripts/ax-docs.mts from the JSDoc in registry/ouro/ax/. Do not edit; run `pnpm run docs`. -->

# ax-cli

The whole front door for a tool built on the kit: parse, help, run (or, on `--dry-run`, plan), print the result as text or `--json`, and turn every failure into the one error line and its exit code. An outcome or a wait sets the exit code from its state.

```sh
npx shadcn@latest add ourostack/ouro-ui/ax-cli#v1.3.10
```

It installs `lib/ouro/ax/cli.ts` and `lib/ouro/ax/help.ts`, with `ax-checks`, `ax-command`, `ax-effects`, `ax-outcome`, `ax-output`, `ax-problem`, `ax-terminal`, `ax-voice`, `ax-wait`. Its tests are `ax-cli-tests`. Every item runs on Node 22.18 or later as it is copied: the files import each other as `./<file>.ts`. The [Ouro AX guide](ax.md) shows how they fit together.

## Exports of cli.ts

### `CliIo`

The whole front door for a tool built on the kit: parse, help, run (or, on `--dry-run`, plan), print the result as text or `--json`, and turn every failure into the one error line and its exit code. An outcome or a wait sets the exit code from its state.

```ts
interface CliIo {
  stdout: { write(s: string): unknown; isTTY?: boolean };
  stderr: { write(s: string): unknown };
  stdin?: AsyncIterable<string | Uint8Array> | Iterable<string | Uint8Array>;
}
```

### `dispatch`

Runs a parsed command as runCli does, for a tool that reads stdin and prints errors its own way: on `--dry-run` the command's plan(), refused ("no-preview") when it has none, else its run(). A self-scoped command is refused first when its item is not the calling agent's (`checkOwner`). It prints nothing and reads no stdin.

```ts
function dispatch<C extends RunContext>(cli: Cli<C>, parsed: Parsed, ctx: C) => Promise<unknown>
```

### `isEmptyResult`

Whether a result is an empty list: an empty array, or a page (`{ items }`) whose items are empty.

```ts
function isEmptyResult(result: unknown): boolean
```

### `printResult`

Prints a command's result as runCli does and returns the exit code: an outcome by its state (a refusal or failure in text is the one error line on stderr), a wait by its state, a checks report (ax-checks) by its verdict, with its text styled for stdout and every check under `--verbose`, anything else as its text or `--json`. A report whose checks all ran and passed may get the voice's `healthy` line. Given the process's voice, a voice line may follow the text on stdout, never before it: after a done or queued outcome, an empty list, or the summary command.

```ts
function printResult(cli: Cli<RunContext>, cmd: CommandDef<unknown, RunContext>, input: Readonly<Record<string, InputValue>>, result: unknown, json: boolean, io: Pick<CliIo, "stdout" | "stderr">, voice?: Voice | undefined, env?: Readonly<Record<string, string | undefined>>): number
```

### `quietPipes`

Ends the tool quietly when whatever reads its output goes away, as in `tool help | head -1`: on `EPIPE` it exits with the exit code so far (0 when none was set) and prints nothing, instead of a stack trace. Call it once in the tool's bin, before runCli: `quietPipes(process)`. Any other stream error is thrown as before.

```ts
function quietPipes(proc: { stdout: ErrorEvents; stderr: ErrorEvents; exitCode?: string | number | null | undefined; exit(code?: number | undefined): unknown; }): void
```

### `runCli`

```ts
function runCli(cli: Cli<RunContext>, argv: readonly string[], io: CliIo, options?: RunOptions): Promise<number>
```

### `RunOptions`

```ts
interface RunOptions {
  overview?: OverviewOptions;
  topics?: Readonly<Record<string, string>>;
  env?: Readonly<Record<string, string | undefined>>;
  voiceMemory?: VoiceMemory;
}
```

## Exports of help.ts

### `commandManifest`

One command as data.

```ts
function commandManifest(cli: Cli<RunContext>, cmd: CommandDef<unknown, RunContext>): CommandManifest
```

### `CommandManifest`

```ts
interface CommandManifest {
  name: string;
  aliases: readonly string[];
  effect: "private" | "others";
  whoSees: string;
  readOnly: boolean;
  needsWhy: boolean;
  dryRun: boolean;
  runs: boolean;
  summary: string;
  usage: string;
  inputSchema: JsonSchema;
  output: string | null;
  examples: readonly string[];
  hidden: boolean;
  scope?: "self";
}
```

### `DEFAULT_WIDTH`

Help from the definitions: a one-screen overview under the two effect headings, each command's details, and the same as JSON (`help --json`), which an agent parses instead of scraping text. Every line is wrapped to `width` columns.

```ts
const DEFAULT_WIDTH: 100
```

### `definitionLines`

The generated part of a command's help: its usage from the definition, its arguments and its flags.

```ts
function definitionLines(cli: Cli<RunContext>, cmd: CommandDef<unknown, RunContext>, width?: number): string[]
```

### `flagLines`

One line per flag: usage on the left, what it does on the right; the built-ins and the tool's own are left out.

```ts
function flagLines(cli: Cli<RunContext>, cmd: CommandDef<unknown, RunContext>, width?: number): string[]
```

### `helpJson`

The help as data: the tool, its headings, the commands, the words only the person acts on (`personOnly`: name, reason and how), the exit codes, the tool's fixed voice lines (for a checker that looks for them in an agent's output) and the one error shape.

```ts
function helpJson(cli: Cli<RunContext>): { tool: string; about: readonly string[]; effects: { private: string; others: string; }; commands: CommandManifest[]; personOnly: { name: string; reason: string; how: string; }[]; exitCodes: readonly ExitCode[]; voice: string[]; errorShape: { error: { code: string; exit: string; thing: string; problem: string; fix: string; message: string; }; }; }
```

### `OverviewOptions`

```ts
interface OverviewOptions {
  width?: number;
  othersNote?: string;
  footer?: readonly string[];
}
```

### `renderCommand`

One command's whole help, from its definition alone.

```ts
function renderCommand(cli: Cli<RunContext>, cmd: CommandDef<unknown, RunContext>, width?: number): string
```

### `renderOverview`

The overview: what the tool is, the commands under "Only you see these" and "Other people see these", the words only the person acts on, the footer.

```ts
function renderOverview(cli: Cli<RunContext>, options?: OverviewOptions): string
```

### `wrap`

Wraps text to `width` columns, every line indented; a word longer than a line stays whole.

```ts
function wrap(text: string, indent: number, first?: number, width?: number): [...string[], string]
```
