CLI reference
All repository commands accept --repo <path>; the default is the current directory.
har onboard
Section titled “har onboard”Interactive first-run guide: how HAR works, telemetry, Mission Control, plugins,
parallel agent slot capacity, then the adaptation prompt (clipboard +
.har/ADAPT-PROMPT.md).
har onboard [--repo .] [--yes] [--skip-guide] [--skip-init] [--profile default|cli|ios] [--telemetry on|on-no-prompts|off] [--control|--no-control] [--plugins playwright,rocketsim,kerno,gitleaks,trivy,semgrep|--no-plugins] [--agent-slots <n>] [--force] [--agents claude,cursor,codex] [--no-agents] [--cursor-rule|--no-cursor-rule] [--commit-gate prompt|always|never] [--gate-mode block|warn] [--gate-scope worktrees|all]Onboarding probes Docker first (docker --version + docker info). Docker is
required — Mission Control runs as a container and harness infra uses Docker
Compose — so a missing CLI or stopped daemon is warned about, reported in the
summary, and Mission Control is not started by default until Docker works.
--yes accepts defaults (telemetry on, start Mission Control when Docker is
available, no plugins) without prompts. This is the first-run command for a
new repository — do not substitute har env init in user-facing copy.
--agent-slots <n> sets how many agents may run in parallel (1–10), written to
.har/stages.json as agentSlots.max. Interactive onboarding asks this when the
flag is omitted (practical limit depends on machine resources and stack cost).
With --yes and no --agent-slots, the profile template default is kept.
har env
Section titled “har env”| Command | Purpose |
|---|---|
init |
Mechanical scaffold of .har/ (fixtures / --force). Humans use har onboard. |
maintain |
Validate, compare templates, and prepare or finalize an upgrade |
add-plugin [plugin] |
Install a plugin (bundled id, path, npm, or git — registers stages) |
add-stage [id] |
Deprecated plugin alias for add-plugin (--custom removed in 1.0 — see har plugin create) |
preflight <id> |
Check ports, processes, Docker, slot occupation, and untracked worktree paths |
setup-infra |
Set up shared infrastructure (Docker services, template DB, or the iOS toolchain) |
launch <id> |
Start a fresh session (new worktree from --repo HEAD) |
recover <id> |
Resume a failed or partial launch |
verify <id> |
Run quick or full verification |
complete <id> |
Reuse last matching full validation, teardown, keep branch (--verify to re-run) |
teardown <id> |
Free a slot without a completion validation; keep branch |
doctor |
Validate the harness contract (schema, stages, scripts, port lanes) |
eject |
Vendor the runtime into .har/runtime/ for offline ownership |
adopt |
Return an ejected harness to the packaged runtime |
status |
Inspect all slots |
logs <id> [service] |
Show recent logs for a slot (optionally one service) |
agent <id> <command> |
Per-slot ops: status, logs, restart, psql, health, url, reset-db, slow-queries, exec, attach |
run-stage <id> <stage> [args..] |
Run one registered harness stage by id |
artifacts |
List result files under .har/artifacts/ |
cleanup |
Discover stale sessions and orphan worktrees across registered repos |
runs list |
List persisted run records |
runs get <runId> |
Return one run record |
Initialization
Section titled “Initialization”First-time humans should run har onboard. har env init is the mechanical
scaffold (same initHarness core as onboard and har_init_harness) — use it
for fixtures and --force wipes, not as the advertised first-run command.
har env init [--profile default|cli|ios] [--yes] [--smoke] [--force] [--verbose] [--agents claude,cursor,codex] [--no-agents] [--cursor-rule|--no-cursor-rule] [--commit-gate prompt|always|never] [--gate-mode block|warn] [--gate-scope worktrees|all]--force replaces an existing harness and is destructive.
Maintenance
Section titled “Maintenance”har env maintain [--yes] [--finalize] [--summary <text>] [--agents <targets>] [--verbose] [--cursor-rule|--no-cursor-rule] [--commit-gate prompt|always|never] [--gate-mode block|warn] [--gate-scope worktrees|all]Plugins and stages
Section titled “Plugins and stages”har env add-plugin --listhar env add-plugin playwright [--force] [--with-ci]har env add-plugin rocketsim [--force]har env add-plugin kerno [--force] [--with-ci]har env add-plugin gitleaks [--force] [--with-ci]har env add-plugin trivy [--force] [--with-ci]har env add-plugin semgrep [--force] [--with-ci]har env add-plugin ./my-plugin [--force]har env add-plugin @org/har-cypress [--force]har env add-plugin github:org/har-plugin [--force]har plugin create <id> [--kind <kind>] [--description <text>] [--package-fragment] [--force]har plugin listadd-plugin installs a framework bundle that registers one or more stages
(bundled id, local plugin id, path, npm package, or git URL). Installs are
recorded in .har/plugins.json with their source kind. Bundled plugins are
discovered from disk — no core enum edit is required to ship a new id.
har plugin create scaffolds a project-owned plugin at .har/plugins/<id>/
(manifest, contract-compliant stage script, README); implement its TODO, then
install it with add-plugin <id>. har env add-stage playwright remains as a
deprecated alias of add-plugin playwright; add-stage --custom was removed
in 1.0 — one-liner checks are plain command stages in .har/stages.json. See
.har/STAGES.md in every generated harness and the Plugins
guide.
A factory line is the other bundle kind: it registers stages but never adds
them to verificationStages. add-plugin refuses a line bundle and points at
har line add — see har line.
Launch and recovery
Section titled “Launch and recovery”har env preflight 1 [--json]har env launch 1 [--no-worktree] [--claude] [--resume] [--work-id <id>] [--work-source <name>] [--work-url <url>] [--work-title <title>] [--parent-work-id <id>] [--work-link <source|url|label> ...]har env recover 1har env work-link --work-id <id> [--link <source|url|label>] [--source <name> --url <url> [--label <text>]]Every launch creates a new session from the current HEAD of --repo (the
main checkout). Occupied slots always block a new launch — the error message
prints the upcoming base so you can confirm it before freeing the slot.
An occupied slot must be freed before relaunching: har env complete 1 (or
teardown 1), then har env launch 1. Launch never chooses main for you.
If the worktree has uncommitted changes, commit or discard them in the
worktree first. Use --resume / recover only for a failed or starting
launch — it is not a way to replace an active session.
Work metadata is optional and backward compatible. Bind when the task names a
tracker issue or ticket: pass a short repo-scoped --work-id, plus --work-source,
--work-url, and --work-title when known. Add secondary links with repeatable
--work-link source|url|label, or later with har env work-link. A fresh bound
launch creates an immutable attempt UUID; --resume preserves the failed session’s attempt.
A worktree only materializes what is in HEAD. Preflight and launch warn when
untracked (not gitignored) paths will be missing from the session worktree —
the count plus a few examples. Track them, or launch with --no-worktree. The
check is skipped when HARNESS_USE_WORKTREE=false and for a --no-worktree
launch. The same warning appears in har env status --json, MCP launch
stderr, and har env launch.
Verify and finish
Section titled “Verify and finish”har env verify 1 [--full] [--json]har env complete 1 [--verify]har env teardown 1 [--delete-branch]complete reuses the last passing full validation for the current tree. Pass
--verify to re-run full verification if the worktree may have changed.
--skip-verify is a deprecated no-op (skip is the default).
Default verify output is the live progress lines on stderr (and a one-line
summary). It does not reprint the machine JSON contract — that blob
duplicates step logs already shown. Use --json when a script needs the
structured result. Passing steps omit output; failed steps keep a truncated
excerpt. MCP har_run_verification returns the same slim shape.
Doctor
Section titled “Doctor”har env doctor [--json]doctor validates the harness contract and exits 0 on pass, 1 on errors
(so it slots into CI): the running CLI is not older than manifest.cliVersion,
harness.env against the schema, stages.json against
the registry schema, every registered stage’s script/command file exists and is
executable, the lifecycle stages (launch/verify/teardown) resolve,
verificationStages ids resolve to registered stages, infra port lanes are
coherent (no overlaps, defaults inside scan ranges), and slot registry entries
point at existing worktrees. Every finding carries a remedy. Doctor also runs
automatically inside har env maintain and before every launch — a broken
adaptation blocks the launch instead of failing mid-session. A stale CLI vs a
newer harness is a single upgrade error, not a list of missing lifecycle
scripts. Pre-1.0 harnesses
report contract findings as warnings until they migrate. On an ejected
harness, doctor additionally checks the vendored runtime exists and the
user-owned scripts are executable. MCP twin: har_doctor.
Eject and adopt
Section titled “Eject and adopt”har env eject [--yes]har env adopteject is the explicit, supported path for power users who want to own the
runtime: it vendors the complete HAR runtime bundle into .har/runtime/ —
no har on PATH, no npx fallback. Invoke it as
node .har/runtime/har.cjs env …. The choice is recorded in
.har/manifest.json (ejected, ejectedVersion). From then on the vendored
runtime is user-owned: maintain reports no upstream drift for it, and
upstream fixes reach it only by re-ejecting. Support covers issues
reproducible with the packaged runtime; changes made to an ejected runtime
are yours to maintain. Config surface files (harness.env, stages.json,
stages/, docs) stay managed either way.
adopt reverses it: removes .har/runtime/ and clears the manifest record,
preserving the config surface. Both commands are deliberately CLI-only (no
MCP twin) — runtime ownership is a human policy decision with an interactive
confirmation (--yes for automation).
Status and runs
Section titled “Status and runs”har env status [--json]har env logs 1 [service]har env run-stage 1 <stage> [args..] [--json]har env artifacts [--stage <id>] [--json]har env cleanup [--dry-run] [--yes] [--repo <path>] [--keep repo:agentId,/path/to/worktree] [--stale 7] [--orphans] [--include-review] [--json]har env runs list [--stage <id>] [--limit 50] [--json]har env runs get <uuid> [--json]status has one implementation on every surface: the structured collector
behind --json is the source, the text view is rendered on top, and MCP
har_get_status returns the same object. Status is a pure read — it writes no
run records. run-stage executes any stage registered in .har/stages.json
(the CLI twin of MCP har_run_stage); artifacts is the twin of
har_list_artifacts.
cleanup scans every repo in ~/.har/repos.json (plus --repo when set),
classifies active slots and orphan directories under ~/worktrees, and runs
full harness teardown for approved rows. Use --dry-run to preview the plan;
pin live sessions with --keep har-portal:4 or a worktree path.
har line
Section titled “har line”har line create <id> [--stations S1,S2,S3] [--title <text>] [--description <text>] [--opt-in-env <VAR>] [--no-gate-stage] [--force]har line add <id|./path|@org/pkg|github:org/repo> [--force]har line status [id] [--json]har line gate <station> [--line <id>] [--agent <slot>] [--force] [--json]har line listA factory line is a program: an ordered set of stations plus a cumulative gate. It composes what HAR already has — work units, slots, stages, plugins, skills, MCP — and is installed through the same channels as a plugin (path → git → bundled id → npm).
The difference is the apply path. Installing a line registers its stages in
.har/stages.json and records the install in .har/lines.json, but never
touches verificationStages. Default har env verify --full takes exactly as
long as it did before. Line gate stages run on demand:
har line gate S2 --line my-linegate.stages[].fromStation is the ratchet: a stage tagged at a station is
required at that station and every later one, so growing a line can never
drop an earlier station’s checks.
har line create scaffolds a publishable bundle at .har/lines/<id>/
(line.manifest.json, line.json, an off-verify gate stage, README);
har line add <id> installs it. Publishing to git or npm later needs no format
change.
Poka-yoke runs both ways: har env add-plugin refuses a line bundle, and
har line add refuses a verification-plugin manifest. If a check should gate
every verify, it is a plugin, not a line. har env doctor fails if a line
stage ever appears in verificationStages.
See the Factory lines guide.
har agents
Section titled “har agents”har agents install [--claude] [--cursor] [--codex] [--agents <targets>] [--force]har agents remove [--claude] [--cursor] [--codex]Without target flags, HAR detects supported agent directories.
har preferences
Section titled “har preferences”har preferences show [--json]har preferences configurehar preferences configure --cursor-rule <auto|on|off> --agents <auto|none|claude,cursor,codex> --commit-gate <prompt|always|never> --gate-mode <block|warn> --gate-scope <worktrees|all>Preferences are user-level defaults stored in ~/.har/preferences.json.
Repository policy remains visible and versioned in .har/stages.json.
har hooks
Section titled “har hooks”har hooks install [--repo .] [--force]har hooks uninstall [--repo .]har hooks status [--repo .] [--json]
har hooks install --claudehar hooks uninstall --claudeThe default installs the Git commit gate. --claude selects the Claude Code
main-checkout edit guard instead. har hooks check and har hooks record-commit
are internal hook workers invoked by Git, not day-to-day commands.
har hq
Section titled “har hq”har hq connect [--portal <url>] [--api-key <key>] [--repo .] [--yes] [--json]har hq list [--json]har hq disconnect [name] [--yes] [--json]Connect this checkout to a HAR HQ workspace. On a TTY, connect asks Production
(https://app.harhq.com), Development (https://app.dev.harhq.com), or a custom
URL, then opens browser SSO. The workspace chosen on the consent screen is the
destination; HAR attaches this repository to that workspace. When other
repositories are already registered locally, the consent page (or a TTY fallback)
shows their count and paths. You can send all of them to one workspace, or pick
a workspace and then the repositories for it — already-assigned paths are hidden
on the next workspace. --yes / --json skip that prompt and attach only the
current checkout. A second har hq connect from another checkout (or against
another workspace) adds another attachment — it does not replace the first
connection.
Automatic sync sends only to workspaces a repository is attached to. A single leftover connection is not inherited by unattached checkouts.
list shows saved connections (workspace + portal host, never tokens).
disconnect removes one connection and its credentials. Credentials stay in
~/.har/ and are never committed into .har/.
har control login remains a deprecated alias for har hq connect.
har control
Section titled “har control”har control up [--build] [-d|--detach|--no-detach]har control downhar control register [--repo .] [--api-url <url>] [--dry-run] [--force] [--portal|--no-portal]har control unregister [--repo .] [--api-url <url>] [--yes] [--delete-worktrees] [--dry-run] [--json]har control reset [--yes] [--no-scrub-local] [--keep-registry] [--api-url <url>] [--dry-run] [--json]har control sync [--select] [--api-url <url>] [--dry-run] [--json] [--cloud] [--full] [--target <alias>] [--targets a,b]har control watch [--repo .] [--interval 10] [--api-url <url>]har control login [--portal <url>] [--api-key <key>] [--repo .]har control trajectory [on|off] [--target <alias>]login is a deprecated alias for har hq connect. Prefer har hq connect.
sync --select interactively chooses repositories; --full ignores the portal
watermark and resends the complete payload. --target / --targets send to named
saved connections for a one-off push; automatic activity-edge sync uses the
workspace(s) this repository was attached to at har hq connect.
register --no-portal keeps the repo on local Mission Control only (skips hosted
portal sync even when logged in); --portal re-enables portal sync for that repo.
trajectory controls whether sync forwards the trajectory ledger — agent prompts,
tool arguments and tool results — to a hosted portal. Off by default: without it a
portal receives runs, slots, token counts and events, and those bodies stay on this
machine. Use --target to scope the setting to one saved portal destination; the
preference is stored per target in ~/.har/portal-targets.json. Requires telemetry
to be on, and HAR_PORTAL_TRAJECTORY=on|off overrides the stored choice. Forwarded
content is capped and redacted by the same local policy that governs storage (see
the Mission Control guide).
unregister removes the repository from Mission Control and ~/.har/repos.json.
Interactively it lists session worktrees and asks whether to delete them; pass
--delete-worktrees (with --yes in non-TTY) to remove worktrees via harness
teardown. Re-add later with har control register.
reset clears all Mission Control data (every repository and cascaded
rows), clears the unregister blocklist, scrubs local
.har/{runs,validations,state,slots} under registered repos (default), and
clears ~/.har/repos.json so the next register starts clean. Use
--no-scrub-local / --keep-registry to keep those. The same action is
available in the dashboard under Settings → Danger zone.
har telemetry
Section titled “har telemetry”har telemetry status [--json]har telemetry on [--prompts|--no-prompts]har telemetry offhar telemetry install-hookshar telemetry write-env --agent-id <n> [--repo .] [--env-file path] [--work-dir path] [--branch name] [--suffix id] [--session-key key]har telemetry print-env --agent-id <n> [--repo .] [--work-dir path] [--branch name] [--suffix id]Controls agent usage telemetry (Cursor / Claude / Codex via @osfactory/otel-hook → Mission Control).
Default: full on (traces, logs, metrics, prompts). Install and the first har invocation
persist ~/.har/telemetry.json when missing. on ensures Mission Control is running and
installs/configures hooks. Use --no-prompts to keep telemetry without prompt text.
Override with HAR_TELEMETRY=0|1. Hooks config: ~/.har/otel-hooks/otel_config.json.
har mcp
Section titled “har mcp”har mcp [--repo /default/repository]Starts a stdio MCP server. Logs go to stderr so stdout remains valid protocol traffic.
