CLI reference
Every klera command and its flags. The CLI is a thin shell over the
library API — three exit codes (0 success, 1 command error, 2 usage
error), no global config flags, one logical change per invocation.
$ klera --help
usage: klera <command> [args...]
commands:
init Scaffold klera into the current Expo app.
run Execute a YAML flow against a connected runtime.
validate Parse and validate a YAML flow without running it.
plan Compile a free-form .flow.md into a JSON IR cache.
compile Hash-check prose flows and regenerate stale .flow.json caches.
record Capture a session and compile it to a .flow.md draft.
check-pr Compare prose flows against a base branch.
snapshot Capture an element-graph snapshot.
report Render a JSON report (text or HTML).
schema Print the Flow JSON Schema for editor integration.
ci Scaffold a CI workflow (github-actions / gitlab-ci / circleci).
serve Start the WebSocket bridge and leave it running.
doctor Verify the host environment can run flows end-to-end.
run `klera <command> --help` for per-command options.The argv parser is hand-rolled and minimal. --flag is boolean,
--key value and --key=value are equivalent, --no-foo is always
boolean true. Unknown keys are quietly accepted as positional input
and rejected by the command itself.
Setup
init
Zero-config adoption for a fresh Expo app. One command takes a clean clone to a passing first flow.
npx @klera/cli initDetects Expo SDK + arch + platforms, picks the right native-driver
packages, codemods the entry file to wrap the root in
<KleraRuntimeProvider>, scaffolds flows/welcome.flow.md + a paired
.flow.json cache + .klera/config.yaml, scaffolds metro.config.js
with the klera Metro plugin, merges an AGENTS.md section for coding
agents, installs the package set with the project’s own package
manager (pnpm / bun / yarn / npm via lockfile detection), and runs
klera doctor inline.
| Flag | Type | Default | Description |
|---|---|---|---|
--cwd <dir> | path | process.cwd() | run init against another directory |
--force | bool | false | re-apply every step, overwriting existing scaffold files |
--dry-run | bool | false | print the plan without touching disk |
--yaml | bool | false | scaffold flows/welcome.flow.yaml instead of .flow.md |
--planner-cli <name> | claude | codex | gemini | auto-detect | record this CLI as the planner transport in .klera/config.yaml |
--no-install | bool | false | skip the install step (yarn-workspaces / lockfile bots own deps) |
--no-doctor | bool | false | skip the inline klera doctor invocation |
--no-metro-plugin | bool | false | skip the metro.config.js scaffold |
--no-agents-md | bool | false | skip the AGENTS.md merge |
Idempotent. Each step prints ✓ for “applied” or ↺ for “already
done”; ⚠ flags non-fatal warnings (no entry file matched, codemod
bailed). On exotic entry shapes the codemod writes
.klera/manual-patch.md and continues.
doctor
Pre-flight checklist. Verifies the host environment can actually run flows end-to-end before you hit a mysterious “passed 6 steps but nothing changed on screen” situation.
klera doctorChecks (each runs independently — one failure doesn’t short-circuit
the rest): Node ≥ 20, dist artefacts built, iOS Simulator booted,
idb-fallback driver, adb-fallback driver, New Architecture status,
planner transport (CLI or ANTHROPIC_API_KEY).
No flags. Exit code 0 if every applicable check passed, 1 if any failed.
Authoring
plan
Compile a free-form .flow.md into a JSON IR cache by calling the
LLM planner. The cache (.flow.json) is committed alongside the
prose; runs read it by default.
klera plan flows/login.flow.md --snapshot .klera/element-graph.json| Flag | Type | Default | Description |
|---|---|---|---|
--snapshot <path> | path | required | element-graph snapshot the planner sees at compile time |
--output <path> | path | sibling .flow.json | where to write the cache |
--fixtures-dir <path> | path | ./fixtures | data fixture directory for {{.dotted.path}} refs |
--manual | bool | false | write a prompt file the adopter pastes into any chat-style LLM (no API key needed) |
--apply-response <path> | path | — | validate a pasted JSON response, write the cache |
--prompt-output <path> | path | sibling .plan-prompt.md | where --manual writes the prompt |
--via-mcp <command> | shell | — | spawn an MCP server and route plan_flow through it |
--via-cli <name> | claude | codex | gemini | auto-detect | force the named local coding-agent CLI |
The four transports (api / manual / via-mcp / via-cli) are
mutually exclusive — pick one. All produce bit-identical
SemanticPlan output; only the API path requires ANTHROPIC_API_KEY.
compile
Hash-check the prose flow and regenerate its .flow.json cache when
the inputs (prose + element graph + planner version) have drifted from
the on-disk _meta.combined hash. This is the canonical “what Metro
spawns on save” target and the canonical “what CI runs to keep prose +
cache in lockstep” target.
One flow
klera compile flows/login.flow.md| Flag | Type | Default | Description |
|---|---|---|---|
--check | bool | false | exit 0 when fresh, 1 when stale (no LLM call) |
--force | bool | false | always regenerate, even when the hash matches |
--diff <path> | path | — | additionally write a Markdown flow-diff body (PR-comment shape) |
--all | bool | false | compile every flows/*.flow.md |
--flows-dir <path> | path | auto-detect | override the auto-detected flows dir |
--snapshot <path> | path | .klera/element-graph.json | element-graph snapshot to feed the planner |
--fixtures-dir <path> | path | ./fixtures | data fixture directory |
--via-cli <name> | claude | codex | gemini | auto-detect | force a local coding-agent CLI |
--check and --force are mutually exclusive.
record
Capture a live session and compile it to a .flow.md draft. Connects
to the bridge as a driver, sends start_recording, streams events to
stdout, and on Ctrl-C compiles the captured timeline.
See recording mode for the full walkthrough.
klera record --output flows/checkout.flow.md --name "Checkout"| Flag | Type | Default | Description |
|---|---|---|---|
--output <path> | path | flows/<slug>.flow.md | where to write the prose + sibling .flow.json |
--name "<title>" | string | recording | human-readable flow title |
--app <bundle-id> | string | any | restrict capture to one connected runtime |
--mask <regex> | regex (repeatable, comma-separated) | — | mask values matching the pattern |
--no-network | bool | false | skip network event capture |
--append | bool | false | extend an existing .flow.md instead of overwriting |
--bridge-url <url> | url | ws://127.0.0.1:7345 | bridge URL to attach to |
validate
Parse a YAML flow through the loader and report structural issues without running anything. The cheapest possible feedback loop when hand-authoring YAML; CI runs it to catch broken flows before they hit a device.
klera validate flows/login.flow.yamlNo flags. Exit 0 if the flow parses; 1 with a list of Zod issues otherwise.
schema
Print the Flow IR’s JSON Schema 7 derivation. Adopters add
# yaml-language-server: $schema=<path> to the top of their flow
files; YAML LSPs deliver autocomplete + hover docs + inline validation
across every editor that speaks JSON Schema.
klera schema --out .klera/flow.schema.json --pretty| Flag | Type | Default | Description |
|---|---|---|---|
--out <path> | path | stdout | write the schema to <path> instead of stdout |
--pretty | bool | false | indent the JSON output |
Running
run
Execute a YAML or prose flow against a connected runtime. The flow
argument can be a .yaml / .yml (parsed via the engine’s loader) or
a .flow.md (loaded via the sibling <base>.flow.json cache — run
klera plan or klera compile first to generate the cache).
klera run flows/login.flow.md --report .klera/reports/login.json| Flag | Type | Default | Description |
|---|---|---|---|
--attach <ws-url> | url | — | attach to an existing bridge as a driver instead of starting one |
--host <host> | string | 127.0.0.1 | bind address for the embedded bridge |
--port <port> | number | 7345 | embedded bridge port (0 for ephemeral) |
--wait-timeout <ms> | number | 30000 | how long to wait for the runtime to connect |
--no-self-healing | bool | false | disable fuzzy matching — fail hard on any drift |
--strict | bool | false | reject runtime replanning for prose flows; pin to the cached plan |
--json | bool | false | emit the full FlowResult as JSON on stdout |
--report <path> | path | — | write the versioned JSON artefact to <path> |
--update-baselines | bool | false | rewrite every visualSnapshot baseline with the latest capture |
--snapshot-context <n> | number | 2 | failure-evidence ring-buffer depth (env: KLERA_SNAPSHOT_CONTEXT) |
--telemetry <cdp-ws-url> | url | — | attach Hermes CDP as a read-only observability side-channel |
--no-triage | bool | false | skip auto-triage on failure (env: KLERA_NO_TRIAGE=1) |
--triage-budget <n> | number | 1 | triage at most <n> failed steps per flow |
--parallel | bool | false | opt the run into the parallel executor (runParallelFlow) |
--parallel-port-ios <n> | number | — | bridge port the iOS app should connect to in parallel mode |
--parallel-port-android <n> | number | — | bridge port the Android app should connect to in parallel mode |
--env-file <path> | path | ./.env | resolves ${secret:KEY} / ${env:KEY} sentinels (env: KLERA_ENV_FILE) |
--watch | bool | false | re-run on every save (requires --attach; mutually exclusive with --parallel) |
Watch mode has its own page — see watch mode.
serve
Start the bridge and keep it running until you SIGINT/SIGTERM. Useful
for interactive exploration with the MCP tools, holding a socket open
across multiple short run invocations, or as the always-on bridge
that klera run --attach --watch connects to.
klera serve --port 7345| Flag | Type | Default | Description |
|---|---|---|---|
--host <host> | string | 127.0.0.1 | bind address |
--port <port> | number | 7345 | bridge port (0 for ephemeral) |
--quiet | bool | false | suppress info logs; still prints the bound URL |
Artefacts
report
Render a previously-written JSON report. JSON is canonical; HTML and JUnit are derivative views.
klera report .klera/reports/login.json --html out/login.html| Flag | Type | Default | Description |
|---|---|---|---|
--html <out.html> | path | — | self-contained HTML report (PNG diffs embedded as data URIs) |
--junit <out.xml> | path | — | JUnit-XML view for GitHub / GitLab / CircleCI test panes |
--otlp | bool | false | replay spans + metrics through the configured OTLP endpoint |
Without any of --html / --junit / --otlp the command prints a
text summary to stdout. The flags compose; they write independent
artefacts. See reports for the full schema.
Integration
ci
Generate a starter CI workflow for the chosen target. Each emitted YAML wires up the JSON-report → JUnit conversion → test-results-pane pipeline so PR diffs surface failed steps inline.
GitHub
klera ci github-actions --out .github/workflows/klera.yml| Flag | Type | Default | Description |
|---|---|---|---|
--out <path> | path | stdout | write the YAML to <path> instead of stdout |
--flows <glob> | glob | flows/*.flow.yaml | override the flows glob |
See CI scaffolds for the workflow walkthrough.
Exit codes
| Code | Meaning |
|---|---|
0 | success |
1 | command error (flow failed, file missing, network error, etc.) |
2 | usage error (bad flag, missing argument) |
Every command accepts --help (or -h) and prints its own usage.
Use that as the source of truth — the CLI’s help is generated from
the same arrays this page tabulates.