---
name: cli-creation
description: Build consumer-facing DreamCLI CLIs from scratch with Bun-first workflows and typed patterns. Use when asked to scaffold or implement a new @kjanat/dreamcli command-line app, add commands/flags/args/prompts/output/testing, or create starter files/tests for DreamCLI users.
---

# CLI Creation

## Overview

Create runnable DreamCLI starter CLIs and extend them with typed command
patterns. This skill covers user-facing app code built **on** DreamCLI, not
DreamCLI framework internals.

Targets DreamCLI 3.x. Version 3 removed the DSL, made the default command the
root surface, and added a large typed-flag surface; snippets below assume it.

## Quick Start

1. Choose a starter mode:
   - `single`: one root command (`cli(name).default(command)`).
   - `multi`: grouped command surface (`group('...').command(...)`).
2. Generate starter files:
   - `python scripts/scaffold_cli.py --name mycli --mode single --out .`
   - Tests are generated by default; add `--no-test` only when explicitly requested.
   - Test template is auto-detected: Bun without Vitest uses `bun:test`; otherwise Vitest.
3. Run and validate generated files:
   - Use the printed path from the scaffolder output, for example `bun ./mycli.ts --help`.
   - Run the generated test unless `--no-test` was used.
4. Extend behavior with references:
   - `references/pattern-cookbook.md` — copy-ready, type-checked snippets.
   - `references/consumer-workflow.md` — request to validated CLI.
   - `references/runtime-notes.md` — Bun/Node/Deno execution.

## Looking Things Up

Prefer these over recalling API shapes from memory; they reflect the installed
or published version rather than training data.

**The API, offline-ish, no repo needed.** If `deno` is on the system this works
regardless of whether the project installed from npm or JSR:

```bash
deno doc jsr:@kjanat/dreamcli 2>/dev/null                    # full public API (~4k lines)
deno doc jsr:@kjanat/dreamcli/testkit 2>/dev/null            # subpath: testkit, runtime, schema, version
deno doc --json jsr:@kjanat/dreamcli 2>/dev/null             # machine-readable, for scripted lookups
deno doc --filter=CLIBuilder jsr:@kjanat/dreamcli 2>/dev/null # one symbol
```

`2>/dev/null` matters: deno writes download and type-check progress to stderr,
which otherwise swamps the documentation output.

Pin a version with `jsr:@kjanat/dreamcli@3.0.0` when the project is not on
latest. `--filter` takes a declaration name; it prints nothing for a name that
does not exist, which is itself a useful signal.

**The docs site, as markdown.** Every page is authored markdown served under
`/raw/`, and any page URL returns markdown under content negotiation:

```bash
curl -s https://dreamcli.kjanat.dev/llms.txt        # index of every page, one line each
curl -s https://dreamcli.kjanat.dev/llms-full.txt   # every page concatenated (~250 kB)
curl -s https://dreamcli.kjanat.dev/raw/guide/flags # one page, authored markdown
curl -sH 'Accept: text/markdown' https://dreamcli.kjanat.dev/guide/flags
```

Start from `llms.txt` to find the right page, then fetch that page rather than
pulling `llms-full.txt` into context.

## Grounding Sources

Paths are relative to the dreamcli repository root.

- `examples/basic.ts` — single-command defaults.
- `examples/multi-command.ts` — grouped-command defaults.
- `examples/testing.ts` — `runCommand()` patterns.
- `examples/flag-types.ts` — the v3 typed-flag family.
- `examples/parser-control.ts` — negation, duplicates, spelling parity.
- `examples/output-extras.ts` — colors, hyperlinks, `setExitCode`.
- `examples/standard-schema.ts` — Standard Schema validation.
- `examples/help-config.ts` — help themes, flag order, routable default.
- `examples/gh/` — a full multi-command app used as a walkthrough.
- `docs/guide/getting-started.md` — baseline consumer narrative.
- `docs/guide/walkthrough.md` — end-to-end CLI composition.
- `docs/guide/upgrading-v3.md` — what changed from 2.x, for migrations.

## Workflow Decision Tree

- Simple one-command utility → `--mode single`.
- Nested command groups (git/gh style) → `--mode multi`.
- Tests wanted from the start → do nothing, they are scaffolded by default.
- Tests explicitly unwanted → add `--no-test`.
- npm/tsx or Deno instructions → keep generated code unchanged and give the
  runtime alternatives from `references/runtime-notes.md`.
- Migrating an existing 2.x CLI → read `docs/guide/upgrading-v3.md` first; the
  default-command and `finite` changes silently alter behavior.

## Extend the Starter

**Values.** Add typed args with `arg.string()`, `arg.number()`, `arg.enum(...)`,
`arg.custom(...)`; `.variadic()` for repeated positionals. Prefer a purpose-built
flag kind over `flag.string()` plus parsing: `flag.url()`, `flag.path()`,
`flag.date()`, `flag.duration()`, `flag.bytes()`, `flag.count()`,
`flag.keyValue()`. Express validation declaratively with constraints
(`{ int, min, max }`, `{ nonEmpty, pattern }`) or a Standard Schema passed to
`flag.custom()`, not with hand-written checks in the action.

**Sources.** Declare `.env()`, `.config()`, `.prompt()`, `.default()` on the flag
and let resolution order (argv, env, config, prompt, default) do the work.

**Cross-flag rules.** Put them in `.derive()`, which runs after resolution and
before the action, and return derived state to widen `ctx`.

**Output.** `out.log()` for results, `out.status()` for progress notes (stderr,
suppressed by `--quiet`), `out.table()` for lists, `out.json()` behind
`out.jsonMode`, `out.color`/`osc8()` for styling, `out.setExitCode()` when a
command must report normally but exit non-zero.

**Testing.** `runCommand()` from `@kjanat/dreamcli/testkit`, with `answers` for
prompts and `stat`/`mkdir` when `flag.path()` checks must run. Assert output
including trailing newlines.

## Resource Map

- `scripts/scaffold_cli.py` — generate Bun-first starter files and tests.
- `assets/templates/*.tpl` — source templates used by the scaffolder.
- `references/pattern-cookbook.md` — snippets by topic; all type-checked.
- `references/consumer-workflow.md` — end-to-end flow from request to validation.
- `references/runtime-notes.md` — runtime and package-manager execution guidance.

## Guardrails

- Do not modify DreamCLI core internals for consumer-app requests.
- Keep generated imports on `@kjanat/dreamcli` and `@kjanat/dreamcli/testkit`;
  never reach into `#internals/*` or `dist/`.
- Preserve the typed resolution flow: argv, env, config, prompt, default.
- Keep stdout machine-clean: progress and status go to stderr via `out.status()`,
  never interleaved with `out.json()`.
- `.default(cmd)` is the root surface and is not routable by name; add
  `{ route: true }` when a user expects `mycli <name>` to work too.
- Prefer Bun commands first; include npm/tsx and Deno alternatives when asked.
