Skip to content

Commands

All commands follow the pattern wh <domain> <verb> [args] [--flags]. Global flags --repo, --json, --workspace, and --live are available on most commands.

CommandDescription
wh use <org/repo> [-w workspace]Set the default repo (and optional workspace) for the current directory
wh useShow the active repo context and where it comes from
wh use --clearRemove the .wh context file

Writes a .wh JSON file in the current directory. The CLI resolves the target repo using this priority: --repo flag > WARMHUB_REPO env > .wh file. The repo is validated against the backend before writing.

Terminal window
wh use myorg/world # writes .wh, validates repo exists
wh use myorg/world -w dev # also stores workspace
wh use # shows active context with provenance
wh use --clear # removes .wh
wh thing head # uses .wh repo (no --repo needed)
CommandDescription
wh org create <name> [--display-name "..."] [--description "..."]Create a new organization. Description is trimmed; max 2000 characters.
wh org view <name>View organization details
wh org list [--include-archived]List organizations (archived hidden by default)
wh org rename <oldName> <newName>Rename an organization
wh org add-member <org> <email> [--role role]Add a member or send an invite. Only owners can assign owner role. If the email is not a WarmHub user, a pending invite is created and an invite email is attempted (best-effort, async).
wh org remove-member <org> <email>Remove a member or revoke a pending invite
wh org list-members <org> [--pending]List members of an organization. --pending filters to pending invites only.
wh org change-role <org> <email> --role <role>Change a member’s role. Only owners can promote to or demote from owner. Cannot demote the last owner.
wh org archive <name> [--yes]Archive an organization (blocks new repos and members)
wh org update <name> --description "..."Update org description. Trimmed; empty strings clear the value; max 2000 characters.
wh org unarchive <name>Unarchive an organization

Aliases: viewinfo

Roles: owner (full control), admin (manage members and repos), editor (read/write data), viewer (read-only). Default: editor.

Terminal window
wh org create acme --display-name "Acme Corp"
wh org list
wh org add-member acme alice@example.com --role editor
wh org list-members acme
wh org remove-member acme alice@example.com
CommandDescription
wh repo create <org/name> [--description "..."] [--visibility <public|private>]Create a repo (auto-creates org if needed). Description is trimmed; max 2000 characters.
wh repo list [org] [--include-archived]List repos in an org (archived hidden by default)
wh repo view [org/repo]Show repo details
wh repo describe [org/repo]Describe repo schema: shapes, fields, and inline descriptions
wh repo rename <org/oldName> <newName>Rename a repo
wh repo archive <org/repo> [--yes]Archive a repo (blocks new commits)
wh repo update <org/repo> --description "..."Update repo description. Trimmed; empty strings clear the value; max 2000 characters.
wh repo unarchive <org/repo>Unarchive a repo

Aliases: createinit, viewinfo

Terminal window
wh repo create myorg/world -d "Game world"
wh repo create myorg/world -d "Game world" --visibility public
wh repo list myorg
CommandDescription
wh shape list [--match "glob"] [--component id] [--exclude-components]List all shapes. Use --exclude-components to hide component-owned shapes.
wh shape view <name>Show shape details with field definitions
wh shape create <name> --fields '<json>' [--description '...']Create a new shape
wh shape update <name> --fields '<json>' [--description '...']Update shape fields (creates new version)
wh shape delete <name>Delete a shape
wh shape rename <oldName> <newName>Rename a shape

Aliases: listhead, viewget, updaterevise

Terminal window
wh shape create Location --fields '{"x":"number","y":"number"}'
wh shape list
wh shape view Location
CommandDescription
wh thing head [--shape s] [--kind k] [--limit n] [--match glob] [--count] [--component id] [--exclude-components]Show current HEAD state. Use --count to return only the count of matching items. System-managed component infrastructure records are hidden by default. Use --exclude-components to also hide component-owned data things.
wh thing view <wref> [--version n]Show a thing’s details
wh thing history [wref] [--shape] [--about] [--resolve-collections] [--limit] [--cursor] [--all] [--include-inactive]Show version history
wh thing resolve <wref>Resolve wref to thing identity
wh thing revise <name> --data '<json>' [-m msg] [-a author] [--active bool]Revise a thing
wh thing deactivate <name> [-m msg] [-a author]Deactivate a thing
wh thing query [--shape s] [--kind k] [--about wref] [--resolve-collections] [--limit n] [--match glob] [--count] [--component id] [--exclude-components]Query by filters. Use --count to return only the count. When no --shape is given, system-managed component infrastructure records are hidden by default.
wh thing search <query> [--shape s] [--mode text|vector|hybrid] [--resolve-collections] [--limit n] [--component id] [--exclude-components]Search by text content. --component and --exclude-components only apply in text mode. In text mode, system-managed component infrastructure records are hidden by default when no --shape is given. --resolve-collections also only applies in text mode.
wh thing refs <wref> [--inbound|--outbound] [--field path] [--limit n] [--cursor c] [--all]Show backlinks (inbound, default) or forward references (outbound) for a thing. --field filters inbound refs by field path.
wh thing rename <Shape/oldName> <newName>Rename a thing

Aliases: headstatus, viewshow

Terminal window
wh thing head --shape Location
wh thing view Location/cave --version 3
wh thing query --kind assertion --about Location/cave
wh thing search "safe location" --shape Belief --mode hybrid
wh thing history Location/cave --limit 10
wh thing refs Location/cave # inbound refs (default)
wh thing refs Location/cave --field target # filter by field path
wh thing refs Observation/obs1 --outbound # outbound refs
wh thing head --count # count all active items
wh thing head --shape Location --count # count by shape
wh thing query --about Location/cave --count # count matching query results
CommandDescription
wh assertion head [--shape s] [--limit n] [--match glob] [--count]Browse all assertions in HEAD. Use --count to return only the count.
wh assertion create --shape <s> --about <wref> [--name n] --data '<json>' [-m msg]Create an assertion
wh assertion list [wref] [--about wref] [--shape s] [--depth n] [--resolve-collections] [--match glob]List assertions about a thing

Aliases: createassert, listabout

Terminal window
wh assertion create --shape Belief --about Location/cave --data '{"safe":true}'
wh assertion list Location/cave --shape Belief
wh assertion head --shape Belief
wh assertion head --count
CommandDescription
wh commit create [--ops json] [-f file] [--stream] [--add name] [--revise name] [flags]Create a commit
wh commit list [--last n] [--author name]Show commit history

Aliases: listlog

See Commit Create Deep-Dive for the full breakdown of commit create flags, including staged JSONL ingest with --stream, --file *.jsonl, --progress, and --chunk-size.

Terminal window
wh commit create --add cave --shape Location --data '{"x":3,"y":7}' -m "Add cave"
wh commit create --file dataset.jsonl --progress -m "Bulk ingest"
cat ops.jsonl | wh commit create --stream -m "Pipe ingest"
wh commit list --last 10

See Workspaces for concepts (isolation, changesets, conflict detection, garbage collection).

CommandDescription
wh workspace create <name> [-d description]Create a workspace pinned to current repo HEAD
wh workspace list [--status open|published|abandoned|permanent] [--all]List workspaces. --all includes the default workspace
wh workspace view <name>View workspace details
wh workspace delete <name>Delete (abandon) a workspace and trigger GC
wh workspace status <name>Rich status: metadata, changes, conflicts, expiry
wh workspace validate <name>Check for conflicts with baseline (name collisions, HEAD drift)
wh workspace rebase <name>Advance baseline to current HEAD and re-check conflicts
wh workspace revert <workspace> <wref>Undo workspace changes for a baseline thing
wh workspace discard <workspace> <wref>Remove a workspace-added thing
wh workspace publish <name> -m <message> [-r rationale] [--squash]Publish as changeset for review (locks workspace)
wh workspace merge <name> -m <message> [-r rationale] [--squash]Publish and accept in one step
wh workspace accept <name> [--changeset n]Accept a published changeset (replays into baseline)
wh workspace reject <name> [-r reason] [--changeset n]Reject a changeset (reopens workspace)
wh workspace withdraw <name> [--changeset n]Withdraw a changeset (author only, reopens workspace)
wh workspace review <name> [--changeset n]Review changeset operations in detail

Normally the workspace name resolves to its open changeset automatically. The --changeset flag lets you target a specific changeset by number, which is useful if a workspace has been deleted but its changeset still exists.

Terminal window
# Full workspace lifecycle
wh workspace create my-updates -d "Q4 refresh"
wh commit create -w my-updates --add acme --shape Company --data '{"name":"Acme"}'
wh workspace status my-updates
wh workspace validate my-updates
wh workspace publish my-updates -m "Q4 data refresh"
wh workspace review my-updates
wh workspace accept my-updates
# Quick merge (publish + accept in one step)
wh workspace merge my-updates -m "Q4 data refresh"
# Resolve conflicts
wh workspace rebase my-updates
wh workspace revert my-updates Company/acme
wh workspace discard my-updates Company/new-thing
CommandDescription
wh init [org/repo] [-d "description"]Install harness hooks and optionally onboard a repo

Aliases: init passes unknown verbs as positional args, so wh init myorg/myrepo works directly.

Terminal window
wh init
wh init myorg/myrepo
wh init myorg/myrepo --description "Demo repo"
CommandDescription
wh doctor check [--fix]Run environment and backend health checks

Aliases: checkrun

Checks API URL, default repo, backend connectivity, Claude hooks, and AGENTS.md. Use --fix to auto-install missing hooks and stanzas.

Terminal window
wh doctor check
wh doctor check --fix

See Subscriptions for concepts (kinds, filters, retry behavior) and Creating Subscriptions for detailed setup guides.

CommandDescription
wh sub create <name> --on <shape> --kind <webhook|sprite|cron> --filter '<json>' [flags]Create a subscription
wh sub update <name> [flags]Update an existing subscription
wh sub view <name>View subscription details (includes action container config and token scopes for sprite subs when present)
wh sub list [--limit n]List all subscriptions
wh sub log <name> [--limit n]Tail subscription delivery feed (shows run status, errors, action container)
wh sub attempts <name> <commitId>View per-attempt detail for a specific delivery
wh sub pause <name>Pause a subscription
wh sub resume <name>Resume a paused subscription
wh sub delete <name>Delete a subscription
wh sub bind <name> --credentials <credentialSet>Bind a credential set for webhook auth
wh sub unbind <name>Remove credential binding

Webhook flags

FlagDescription
--onShape to watch
--filterJSON filter expression
--webhook-urlDestination URL for webhook deliveries

Sprite / cron+sprite flags

FlagDescription
--onShape to watch
--filterJSON filter expression
--github-repoGitHub repo hosting the action
--refGit ref to run
--commandCommand to execute
--input-modeHow the payload is passed to the action
--token-ttlLifetime of the minted WarmHub token
--token-scopes-jsonJSON array of token scope entries (create only)
--allow-trace-reentryAllow same-chain reentry (commit-triggered only)

Cron flags

FlagDescription
--cronspecCron schedule expression
--executorExecutor type: webhook or sprite
--timezoneIANA timezone for the schedule

Shared flags (webhook and sprite kinds)

FlagDescription
--workspace-policyignore (default) or include — whether workspace commits trigger the subscription
--sourceWatch a different repo in the same org; accepts repoName or orgName/repoName. Not supported for cron subscriptions.

--source pins the subscription to watch a different repo in the same organization. When set, the subscription lives in the repo specified by --repo but fires on commits to the source repo. The action runs in the context of the subscription’s home repo; sourceRepo is provided separately in the sprite action payload. Not supported for cron subscriptions.

--workspace-policy controls whether workspace commits trigger the subscription. Default: ignore (only baseline commits fire). Set to include to also trigger on workspace commits.

--allow-trace-reentry defaults to false. When omitted, a commit-triggered subscription runs at most once in the same causal chain for the same shape. When present, same-chain reentry is allowed, but a global chain-depth safety limit still stops runaway recursion. Cron subscriptions ignore this flag.

--token-scopes-json accepts a JSON array of token scope entries for WarmHub tokens minted by sprite executors. Each entry has permissions: string[] and optional allowedMatches: string[]. Webhook subscriptions ignore this setting; cron subscriptions honor it when --executor sprite. This flag is available on wh sub create only; changing token scopes requires recreating the subscription.

Terminal window
# Create a webhook subscription
wh sub create signal-hook --on Signal --kind webhook \
--filter '{"shape":"Signal"}' --webhook-url https://example.com/hook
# Create a sprite subscription
wh sub create sprite-hook --on Signal --kind sprite \
--filter '{"shape":"Signal"}' --github-repo warmdex/action-test \
--ref main --command 'bun run action' --input-mode stdin
# Create a cross-repo subscription (watch signals in another repo, run in this one)
wh sub create cross-hook --on Signal --kind sprite \
--filter '{"shape":"Signal"}' --source myorg/other-repo \
--command 'bun run action' --input-mode stdin
# Allow same-trace reentry for a self-chaining sprite subscription
wh sub create sprite-loop --on Echo --kind sprite \
--filter '{"shape":"Echo"}' --github-repo none \
--command 'bun run action' --input-mode stdin \
--allow-trace-reentry
# Restrict the WarmHub token minted for a sprite subscription
wh sub create sprite-hook --on Signal --kind sprite \
--filter '{"shape":"Signal"}' --command 'bun run action' \
--input-mode stdin \
--token-scopes-json '[{"permissions":["repo:read"],"allowedMatches":["Signal/*"]}]'
# Create a cron subscription
wh sub create daily-sync --kind cron \
--cronspec "0 8 * * *" --executor sprite \
--timezone America/New_York --command "bun run sync" --input-mode stdin
# Update a sprite subscription
wh sub update sprite-hook --on Signal \
--filter '{"shape":"Signal"}' --github-repo warmdex/action-test \
--ref main --command 'bun run updated-action' --input-mode stdin
# List and inspect
wh sub list
wh sub view signal-hook
# Tail delivery feed (shows run status, attempt count, errors)
wh sub log signal-hook
wh sub log signal-hook --live
# Drill into a specific delivery's attempts
wh sub attempts signal-hook a1b2c3d
# Credential binding
wh sub bind signal-hook --credentials webhook-keys
wh sub unbind signal-hook
CommandDescription
wh notifications [--limit n] [--since ts]List repo-scoped action failure notifications
wh notifications list [--limit n] [--since ts]Explicit form of the same command

These commands return repo-scoped terminal failure notification records for action deliveries. They are distinct from the web app’s cross-repo user notification feed.

--since accepts either epoch milliseconds or an ISO timestamp.

Terminal window
wh notifications
wh notifications --since 2026-03-30T12:00:00Z
wh notifications list --limit 10
CommandDescription
wh auth loginLog in via browser (device authorization)
wh auth login --with-tokenLog in with a JWT piped via stdin
wh auth logoutLog out and clear saved tokens
wh auth statusShow current auth status
Terminal window
wh auth login
wh auth status
echo "$TOKEN" | wh auth login --with-token
wh auth logout

See Getting Access for the full authentication guide.

CommandDescription
wh token create --name <name> [--scope scope]... [--scopes-json json] [-d desc] [--expires duration]Create a new PAT
wh token listList all your tokens
wh token get --name <name>View a token’s details
wh token revoke --name <name>Revoke a token

All token commands require interactive login — PATs cannot manage other PATs. --scope and --scopes-json are mutually exclusive — use one or the other, not both.

Terminal window
# Repo-scoped token
wh token create --name ci-bot --scope myorg/myrepo=repo:read,repo:write
# Org-level wildcard (all repos in org, capped by role)
wh token create --name org-reader --scope myorg=repo:read
# Global wildcard (all resources, capped by role)
wh token create -n deploy --scope repo:write -d "Deploy pipeline" --expires 90d
# Multiple scopes — repeat --scope for each entry
wh token create --name ci-bot \
--scope myorg/private-repo=repo:read,repo:write \
--scope myorg=repo:read \
--expires 90d
# Full access (no --scope flag)
wh token create --name full-access
# Name-restricted scopes (--scopes-json, mutually exclusive with --scope)
wh token create --name scoped-bot --scopes-json '[
{"resource":"myorg/myrepo","permissions":["repo:read"],"allowedMatches":["Signal/*"]}
]'
wh token list
wh token get --name ci-bot
wh token revoke --name ci-bot

See Personal Access Tokens for scopes, lifecycle, and security details.

CommandDescription
wh component init <name>Scaffold a new component repository
wh component install <github-url[@ref]> [--ref ref]Install a component from GitHub. Use @ref suffix or --ref to pin a git ref.
wh component install <local-path>Install a component from a local directory
wh component listList installed components
wh component search <query>Search GitHub for component repositories
wh component view <name>Show component details
wh component validate <path>Validate a component package without installing
wh component update <name> [--ref ref]Update a GitHub-sourced component. Local-path installs must be reinstalled with install <path>.
wh component doctor <name>Run health checks on an installed component
wh component teardown <name>Pause subscriptions and mark the component as torn down (non-destructive — shapes and data are preserved)

Aliases: viewshow

Components are declarative packages that bundle shapes, subscriptions, actions, credentials, and seed data into a single installable unit. Each component is identified by a unique componentId and owns the resources it creates — external writes to component-owned shapes, things, and assertions are blocked.

Terminal window
wh component init my-component
wh component install https://github.com/acme/my-component
wh component install ./local-component --repo myorg/world
wh component search research
wh component list --repo myorg/world
wh component view my-component --repo myorg/world
wh component validate ./local-component
wh component doctor my-component --repo myorg/world
wh component teardown my-component --repo myorg/world
CommandDescription
wh primePrint CLI context in markdown
wh prime --jsonPrint CLI context as structured JSON

See wh prime for details on output format and token budget.