Skip to Content
DocsRunning flowsCLI reference

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 init

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

FlagTypeDefaultDescription
--cwd <dir>pathprocess.cwd()run init against another directory
--forceboolfalsere-apply every step, overwriting existing scaffold files
--dry-runboolfalseprint the plan without touching disk
--yamlboolfalsescaffold flows/welcome.flow.yaml instead of .flow.md
--planner-cli <name>claude | codex | geminiauto-detectrecord this CLI as the planner transport in .klera/config.yaml
--no-installboolfalseskip the install step (yarn-workspaces / lockfile bots own deps)
--no-doctorboolfalseskip the inline klera doctor invocation
--no-metro-pluginboolfalseskip the metro.config.js scaffold
--no-agents-mdboolfalseskip 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 doctor

Checks (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
FlagTypeDefaultDescription
--snapshot <path>pathrequiredelement-graph snapshot the planner sees at compile time
--output <path>pathsibling .flow.jsonwhere to write the cache
--fixtures-dir <path>path./fixturesdata fixture directory for {{.dotted.path}} refs
--manualboolfalsewrite a prompt file the adopter pastes into any chat-style LLM (no API key needed)
--apply-response <path>pathvalidate a pasted JSON response, write the cache
--prompt-output <path>pathsibling .plan-prompt.mdwhere --manual writes the prompt
--via-mcp <command>shellspawn an MCP server and route plan_flow through it
--via-cli <name>claude | codex | geminiauto-detectforce 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.

klera compile flows/login.flow.md
FlagTypeDefaultDescription
--checkboolfalseexit 0 when fresh, 1 when stale (no LLM call)
--forceboolfalsealways regenerate, even when the hash matches
--diff <path>pathadditionally write a Markdown flow-diff body (PR-comment shape)
--allboolfalsecompile every flows/*.flow.md
--flows-dir <path>pathauto-detectoverride the auto-detected flows dir
--snapshot <path>path.klera/element-graph.jsonelement-graph snapshot to feed the planner
--fixtures-dir <path>path./fixturesdata fixture directory
--via-cli <name>claude | codex | geminiauto-detectforce 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"
FlagTypeDefaultDescription
--output <path>pathflows/<slug>.flow.mdwhere to write the prose + sibling .flow.json
--name "<title>"stringrecordinghuman-readable flow title
--app <bundle-id>stringanyrestrict capture to one connected runtime
--mask <regex>regex (repeatable, comma-separated)mask values matching the pattern
--no-networkboolfalseskip network event capture
--appendboolfalseextend an existing .flow.md instead of overwriting
--bridge-url <url>urlws://127.0.0.1:7345bridge 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.yaml

No 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
FlagTypeDefaultDescription
--out <path>pathstdoutwrite the schema to <path> instead of stdout
--prettyboolfalseindent 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
FlagTypeDefaultDescription
--attach <ws-url>urlattach to an existing bridge as a driver instead of starting one
--host <host>string127.0.0.1bind address for the embedded bridge
--port <port>number7345embedded bridge port (0 for ephemeral)
--wait-timeout <ms>number30000how long to wait for the runtime to connect
--no-self-healingboolfalsedisable fuzzy matching — fail hard on any drift
--strictboolfalsereject runtime replanning for prose flows; pin to the cached plan
--jsonboolfalseemit the full FlowResult as JSON on stdout
--report <path>pathwrite the versioned JSON artefact to <path>
--update-baselinesboolfalserewrite every visualSnapshot baseline with the latest capture
--snapshot-context <n>number2failure-evidence ring-buffer depth (env: KLERA_SNAPSHOT_CONTEXT)
--telemetry <cdp-ws-url>urlattach Hermes CDP as a read-only observability side-channel
--no-triageboolfalseskip auto-triage on failure (env: KLERA_NO_TRIAGE=1)
--triage-budget <n>number1triage at most <n> failed steps per flow
--parallelboolfalseopt the run into the parallel executor (runParallelFlow)
--parallel-port-ios <n>numberbridge port the iOS app should connect to in parallel mode
--parallel-port-android <n>numberbridge port the Android app should connect to in parallel mode
--env-file <path>path./.envresolves ${secret:KEY} / ${env:KEY} sentinels (env: KLERA_ENV_FILE)
--watchboolfalsere-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
FlagTypeDefaultDescription
--host <host>string127.0.0.1bind address
--port <port>number7345bridge port (0 for ephemeral)
--quietboolfalsesuppress 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
FlagTypeDefaultDescription
--html <out.html>pathself-contained HTML report (PNG diffs embedded as data URIs)
--junit <out.xml>pathJUnit-XML view for GitHub / GitLab / CircleCI test panes
--otlpboolfalsereplay 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.

klera ci github-actions --out .github/workflows/klera.yml
FlagTypeDefaultDescription
--out <path>pathstdoutwrite the YAML to <path> instead of stdout
--flows <glob>globflows/*.flow.yamloverride the flows glob

See CI scaffolds for the workflow walkthrough.

Exit codes

CodeMeaning
0success
1command error (flow failed, file missing, network error, etc.)
2usage 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.

Last updated on