CLI Overview
The wh CLI is the primary human interface for interacting with WarmHub. It covers all operations — creating repos, writing data, querying state, and bootstrapping agent context.
Installation
Section titled “Installation”The CLI requires Node 22+.
npm install -g @warmhub/cliwh --versionAfter installing, wh is available everywhere. See the Quickstart for the full walkthrough.
Everyday Use
Section titled “Everyday Use”Use wh use to set the repo for a working directory, pass --repo org/name when a script should be explicit, and add --json when another tool needs structured output. Most commands accept a repo from the current .wh file or a flag.
Command Pattern
Section titled “Command Pattern”Most commands follow the wh <domain> <verb> pattern. A handful are flat single commands that take no verb — wh use, wh init, wh doctor, wh prime, wh onboard, wh update, wh notifications, and wh channel:
wh org create myorgwh repo list myorgwh thing list --shape Locationwh commit submit --ops '[...]'Domains: org, repo, shape, thing, assertion, commit, sub, auth, token, credential, component, collection, grant, view
The grant domain supports create, get, list, and revoke verbs. The view domain supports the evaluate verb. Full flag and option details for both domains are not yet covered in the command reference — use wh <domain> <verb> --help (for example, wh grant create --help or wh view evaluate --help) for the full flag and option contract for each verb. For a machine-readable summary of a domain, wh help <domain> --format json returns the complete spec for that domain.
See the full command reference for every domain, verb, flag, and alias covered there. Note that grant and view are not yet included in the command reference; verb-level --help is the authoritative source for those two domains until their reference sections are added.
Configuration
Section titled “Configuration”Default Repo (.wh file)
Section titled “Default Repo (.wh file)”The easiest way to set a default repo is wh use, which writes a .wh file in the current directory:
wh use myorg/worldwh thing list # targets myorg/worldThe CLI resolves the target repo using this priority:
--repoflag (per-command override)WARMHUB_REPOenvironment variable.whfile in the current directory
Environment Variables
Section titled “Environment Variables”The CLI reads WH_TOKEN (authentication), WARMHUB_REPO / WARMHUB_ORG (default repo target), WARMHUB_API_URL (backend URL), and WH_PROFILE (auth profile), plus a few behavior toggles. See Environment Variables for the full list, accepted values, and precedence rules.
Per-Command Override
Section titled “Per-Command Override”wh thing list --repo myorg/other-repoOutput Formats
Section titled “Output Formats”Default (Human-Readable)
Section titled “Default (Human-Readable)”Colored, formatted text output:
wh thing listStructured output for scripts and agents:
wh thing list --jsonPaginated list commands wrap their rows in a page envelope:
{ "items": [ /* rows */ ], "page": { "limit": 50, "count": 50, "hasMore": true, "nextCursor": "<cursor>" }}count is the number of items in this page. When hasMore is true, pass nextCursor back as --cursor to fetch the next page, or use --all to auto-fetch every page.
When you run wh thing list or wh thing query with --since-repo-seq and reach the last page (hasMore is false and nextCursor is null), the JSON output includes repoSeq at the top level:
{ "items": [ /* this page's rows */ ], "page": { "limit": 50, "count": 12, "hasMore": false, "nextCursor": null }, "repoSeq": 4821}repoSeq is your checkpoint: save it, and pass it as --since-repo-seq on the next run to read only what changed since. It appears only on the last page of the read, never on intermediate pages, and never on commands that did not pass --since-repo-seq.
As with ordinary pagination, items holds only the page you just fetched — the last page does not replay earlier ones. Accumulate rows yourself, or pass --all to have the CLI fetch and combine every page for you.
For the full incremental-read contract on list/HEAD reads — filtering, ordering, and error handling — see HEAD Queries. wh thing query refuses --since-repo-seq on three further forms, returning INCREMENTAL_READ_UNAVAILABLE: a glob --match filter, --resolve-collections, and cross-repo --about targets.
Failure output. When a command fails under --json, the CLI writes a structured error envelope to stderr:
{ "error": { "code": "CONFLICT", "errorCode": "thing_version_conflict", "backendCode": "thing_version_conflict", "message": "A newer version of this thing already exists.", "hint": "Re-fetch the thing and reapply your changes." }}error.code is a high-level bucket your script can branch on. Values are drawn from the ErrorCode enum: UNKNOWN, USER_INPUT, CONFIG, AUTH, BACKEND, CONFLICT, RATE_LIMITED, QUERY_TOO_EXPENSIVE, FIELD_INDEX_UNAVAILABLE, FIELD_NOT_INDEXABLE, and FIELD_TYPE_AMBIGUOUS. error.errorCode carries the service-specific error code when the API returns one; error.backendCode is also present for the same value and is retained for backwards compatibility. message is always present; hint, suggestions, and context are optional and included only when the CLI has additional detail to surface.
Live (Reactive)
Section titled “Live (Reactive)”Live updates by polling — re-runs the query periodically and auto-refreshes as data changes:
wh thing list --live--max-updates <n> auto-exits after N updates, and --live-timeout-ms <ms> auto-exits when no update arrives within that window — both useful for scripted, bounded live reads.
Ergonomics
Section titled “Ergonomics”Exact flag names. Long flags and declared aliases must match exactly. Use the full --description name:
wh repo create myorg/repo --description "My repo"Unknown flags may receive a “did you mean?” suggestion, but are never expanded or executed. Typos in domains and verbs receive the same kind of recovery guidance.
Verb aliases. A handful of verbs accept an alias — for example, wh auth whoami resolves to wh auth status. There is no general show/get aliasing; use the canonical verb shown in the command reference. A mistyped verb returns a “did you mean?” suggestion rather than silently resolving.
Getting Help
Section titled “Getting Help”wh help # full help overviewwh <domain> # list verbs for a domainwh <domain> <verb> --help # verb details with flags and exampleswh help --format json # full CLI spec as JSON (all domains)wh help <domain> --format json # spec for a single domain as JSONwh doctor # verify environment and connectivitywh help --format json returns the complete CLI spec as JSON: all domains, a compact verb matrix, and the authoritative global flags and controls tables. The payload includes a schemaVersion field — check it before parsing, as a version advance may indicate structural changes. Targeted JSON help (wh help <domain> --format json or wh <domain> <verb> --help --format json) returns only the spec for that domain or verb, without the aggregate tables.
Individual domain specs can carry a globalFlagOverrides map that modifies how inherited flags behave for that domain. For example, the channel domain carries { repo: { multiple: true } }, which signals that the --repo flag accepts multiple values for that domain. When consuming the JSON spec programmatically, apply any globalFlagOverrides entries on top of the top-level global flag definitions to get the effective flag contract for a given domain — entries in globalFlagOverrides take precedence over the inherited global flag definition for that domain only.
Next steps
Section titled “Next steps”| Need | Page |
|---|---|
Every domain, verb, flag, and alias (excluding grant and view — use wh <domain> <verb> --help for those) | Command Reference |
| Build and submit a multi-operation write | commit submit deep dive |
| Install the CLI as part of first-run setup | Quickstart |