Skip to content

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.

The CLI requires Node 22+.

Terminal window
npm install -g @warmhub/cli
wh --version

After installing, wh is available everywhere. See the Quickstart for the full walkthrough.

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.

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:

Terminal window
wh org create myorg
wh repo list myorg
wh thing list --shape Location
wh 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.

The easiest way to set a default repo is wh use, which writes a .wh file in the current directory:

Terminal window
wh use myorg/world
wh thing list # targets myorg/world

The CLI resolves the target repo using this priority:

  1. --repo flag (per-command override)
  2. WARMHUB_REPO environment variable
  3. .wh file in the current directory

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.

Terminal window
wh thing list --repo myorg/other-repo

Colored, formatted text output:

Terminal window
wh thing list

Structured output for scripts and agents:

Terminal window
wh thing list --json

Paginated 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 updates by polling — re-runs the query periodically and auto-refreshes as data changes:

Terminal window
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.

Exact flag names. Long flags and declared aliases must match exactly. Use the full --description name:

Terminal window
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.

Terminal window
wh help # full help overview
wh <domain> # list verbs for a domain
wh <domain> <verb> --help # verb details with flags and examples
wh help --format json # full CLI spec as JSON (all domains)
wh help <domain> --format json # spec for a single domain as JSON
wh doctor # verify environment and connectivity

wh 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.

NeedPage
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 writecommit submit deep dive
Install the CLI as part of first-run setupQuickstart