Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

CLI reference

All commands available in the harn CLI.

harn run

Execute a .harn file.

harn run <file.harn>
harn run --trace <file.harn>
harn run -e 'println("hello")'
harn run --deny shell,exec <file.harn>
harn run --allow read_file,write_file <file.harn>
FlagDescription
--tracePrint LLM trace summary after execution
-e <code>Evaluate inline code instead of a file
--deny <builtins>Deny specific builtins (comma-separated)
--allow <builtins>Allow only specific builtins (comma-separated)

You can also run a file directly without the run subcommand:

harn main.harn

Before starting the VM, harn run <file> builds the cross-module graph for the entry file. When all imports resolve, unknown call targets produce a static error and the VM is never started — the same call target ... is not defined or imported message you see from harn check. The inline -e <code> form has no importing file and therefore skips the cross-module check.

harn playground

Run a pipeline against a Harn-native host module for fast local iteration.

harn playground --host host.harn --script pipeline.harn --task "Explain this repo"
harn playground --watch --task "Refine the prompt"
harn playground --llm ollama:qwen2.5-coder:latest --task "Use a local model"
FlagDescription
--host <file>Host module exporting the functions the script expects (default: host.harn)
--script <file>Pipeline entrypoint to execute (default: pipeline.harn)
--task <text>Task string exposed as HARN_TASK during the run
--llm <provider:model>Override the provider/model selection for this invocation
--llm-mock <path>Replay LLM responses from a JSONL fixture file instead of calling the provider
--llm-mock-record <path>Record executed LLM responses into a JSONL fixture file
--watchRe-run when the host module or script changes

harn playground type-checks the host module, merges its exported function names into the script’s static call-target validation, then executes the script with an in-process host adapter. Missing host functions fail with a pointed error naming the function and caller location.

harn test

Run tests.

harn test conformance                  # run conformance test suite
harn test conformance tests/language/arithmetic.harn # run one conformance file
harn test conformance tests/stdlib/     # run a conformance subtree
harn test tests/                       # run user tests in directory
harn test tests/ --filter "auth*"      # filter by pattern
harn test tests/ --parallel            # run tests concurrently
harn test tests/ --watch               # re-run on file changes
harn test conformance --verbose        # show per-test timing
harn test conformance --timing         # show timing summary without verbose failures
harn test tests/ --record              # record LLM fixtures
harn test tests/ --replay              # replay LLM fixtures
FlagDescription
--filter <pattern>Only run tests matching pattern
--parallelRun tests concurrently
--watchRe-run tests on file changes
--verbose / -vShow per-test timing and detailed failures
--timingShow per-test timing plus summary statistics
--junit <path>Write JUnit XML report
--timeout <ms>Per-test timeout in milliseconds (default: 30000)
--recordRecord LLM responses to .harn-fixtures/
--replayReplay recorded LLM responses

When no path is given, harn test auto-discovers a tests/ directory in the current folder. Conformance targets must resolve to a file or directory inside conformance/; the CLI now errors instead of silently falling back to the full suite when a requested target is missing.

harn repl

Start an interactive REPL with syntax highlighting, multiline editing, live builtin completion, and persistent history in ~/.harn/repl_history.

harn repl

The REPL keeps incomplete blocks open until braces, brackets, parentheses, and quoted strings are balanced, so you can paste or type multi-line pipelines and control-flow blocks directly.

harn bench

Benchmark a .harn file over repeated runs.

harn bench main.harn
harn bench main.harn --iterations 25

harn bench parses and compiles the file once, executes it with a fresh VM for each iteration, and reports wall time plus aggregated LLM token, call, and cost metrics.

harn viz

Render a .harn file as a Mermaid flowchart.

harn viz main.harn
harn viz main.harn --output docs/graph.mmd

harn viz parses the file, walks the AST, and emits a Mermaid flowchart TD graph showing pipelines, functions, branches, loops, and other workflow-shaped control-flow nodes.

harn fmt

Format .harn source files. Accepts files or directories.

harn fmt main.harn
harn fmt src/
harn fmt --check main.harn            # check mode (no changes, exit 1 if unformatted)
harn fmt --line-width 80 main.harn    # custom line width
FlagDescription
--checkCheck mode: exit 1 if any file would be reformatted, make no changes
--line-width <N>Maximum line width before wrapping (default: 100)

The formatter enforces a 100-character line width by default (overridable with --line-width). When a line exceeds this limit the formatter wraps it automatically:

  • Comma-separated forms — function call arguments, function declaration parameters, list literals, dict literals, struct construction fields, enum constructor payloads, selective import names, interface method parameters, and enum variant fields all wrap with one item per line and trailing commas.
  • Binary operator chains — long expressions like a + b + c + d break before the operator. Operators that the parser cannot resume across a bare newline (-, ==, !=, <, >, <=, >=, in, not in, ??) get an automatic backslash continuation (\); other operators (+, *, /, %, ||, &&, |>) break without one.
  • Operator precedence parentheses — the formatter inserts parentheses to preserve semantics when the AST drops them (e.g. a * (b + c) stays parenthesised) and for clarity when mixing && / || (e.g. a && b || c becomes (a && b) || c).

harn lint

Lint one or more .harn files or directories for common issues (unused variables, unused functions, unreachable code, empty blocks, missing /** */ HarnDoc on public functions, etc.).

harn lint main.harn
harn lint src/ tests/

Pass --fix to automatically apply safe fixes (e.g., varlet for never-reassigned bindings, boolean comparison simplification, unused import removal, and string interpolation conversion):

harn lint --fix main.harn

harn check

Type-check one or more .harn files or directories and run preflight validation without executing them. The preflight pass resolves imports, checks literal render(...) / render_prompt(...) targets, detects import symbol collisions across modules, validates host_call("capability.operation", ...) capability contracts, and flags missing template resources, execution directories, and worker repos that would otherwise fail only at runtime. Source-aware lint rules run as part of check, including the missing-harndoc warning for undocumented pub fn APIs.

check builds a cross-module graph from each entry file and follows import statements recursively. When every import in a file resolves, the typechecker knows the exact set of names that module brings into scope and will emit a hard error for any call target that is neither a builtin, a local declaration, a struct constructor, a callable variable, nor an imported symbol:

error: call target `helpr` is not defined or imported

This catches typos and stale imports before the VM runs. If any import in the file is unresolved, the stricter check is turned off for that file so one broken import does not avalanche into spurious errors — the unresolved import itself still fails at runtime.

harn check main.harn
harn check src/ tests/
harn check --host-capabilities host-capabilities.json main.harn
harn check --bundle-root .bundle main.harn
harn check --workspace
harn check --preflight warning src/
FlagDescription
--host-capabilities <file>Load a host capability manifest for preflight validation. Supports plain {capability: [ops...]} objects, nested {capabilities: ...} wrappers, and per-op metadata dictionaries. Overrides [check].host_capabilities_path in harn.toml.
--bundle-root <dir>Validate render(...), render_prompt(...), and template paths against an alternate bundled layout root
--workspaceWalk every path listed in [workspace].pipelines of the nearest harn.toml. Positional targets remain additive.
--preflight <severity>Override preflight diagnostic severity: error (default, fails the check), warning (reports but does not fail), or off (suppresses all preflight diagnostics). Overrides [check].preflight_severity.
--strict-typesFlag unvalidated boundary-API values used in field access.

harn.toml — [check] and [workspace] sections

harn check walks upward from the target file (stopping at the first .git directory) to find the nearest harn.toml. The following keys are honored:

[check]
# Load an external capability manifest. Path is resolved relative to
# harn.toml. Accepts JSON or TOML with the namespaced shape
# { workspace = [...], process = [...], project = [...], ... }.
host_capabilities_path = "./schemas/host-capabilities.json"

# Or declare inline:
[check.host_capabilities]
project = ["ensure_enriched", "enrich"]
workspace = ["read_text", "write_text"]

[check]
# Downgrade preflight errors to warnings (or suppress entirely with "off").
# Keeps type diagnostics visible while an external capability schema is
# still catching up to a host's live surface.
preflight_severity = "warning"

# Suppress preflight diagnostics for specific capabilities/operations.
# Entries match either an exact "capability.operation" pair, a
# "capability.*" wildcard, a bare "capability" name, or a blanket "*".
preflight_allow = ["mystery.*", "runtime.task"]

[workspace]
# Directories or files checked by `harn check --workspace`. Paths are
# resolved relative to harn.toml.
pipelines = ["Sources/BurinCore/Resources/pipelines", "scripts"]

Preflight diagnostics are reported under the preflight category so they can be distinguished from type-checker errors in IDE output streams and CI log filters.

harn contracts

Export machine-readable contracts for hosts, release tooling, and embedded bundles.

harn contracts builtins
harn contracts host-capabilities --host-capabilities host-capabilities.json
harn contracts bundle main.harn --verify
harn contracts bundle src/ --bundle-root .bundle --host-capabilities host-capabilities.json

harn contracts builtins

Print the parser/runtime builtin registry as JSON, including return-type hints and alignment status.

harn contracts host-capabilities

Print the effective host-capability manifest used by preflight validation after merging the built-in defaults with any external manifest file.

harn contracts bundle

Print a bundle manifest for one or more .harn targets. The manifest includes:

  • explicit entry_modules, import_modules, and module_dependencies edges
  • explicit prompt_assets and template_assets slices, plus a full assets table resolved through the same source-relative rules as render(...)
  • required host capabilities discovered from literal host_call(...) sites
  • literal execution directories and worker worktree repos
  • a summary block with stable counts for packagers and release tooling

Use --verify to run normal Harn preflight validation before emitting the bundle manifest and return a non-zero exit code if the selected targets are not bundle-safe.

harn init

Scaffold a new project with harn.toml and main.harn.

harn init              # create in current directory
harn init my-project   # create in a new directory
harn init --template eval

harn new

Scaffold a new project from a starter template. Supported templates are basic, agent, mcp-server, and eval.

harn new my-agent --template agent
harn new local-mcp --template mcp-server
harn new eval-suite --template eval

harn init and harn new share the same scaffolding engine. Use init for the default quick-start flow and new when you want the template choice to be explicit.

harn doctor

Inspect the local environment and report the current Harn setup, including the resolved secret-provider chain and keyring health.

harn doctor
harn doctor --no-network

harn watch

Watch a file for changes and re-run it automatically.

harn watch main.harn
harn watch --deny shell main.harn

harn acp

Start an ACP (Agent Client Protocol) server on stdio.

harn acp                    # bridge mode, no pipeline
harn acp pipeline.harn      # execute a pipeline per prompt

See MCP and ACP Integration for protocol details.

harn portal

Launch the local Harn observability portal for persisted runs.

harn portal
harn portal --dir runs/archive
harn portal --host 0.0.0.0 --port 4900
harn portal --open false

See Harn Portal for the full guide.

harn runs

Inspect persisted workflow run records.

harn runs inspect .harn-runs/<run>.json
harn runs inspect .harn-runs/<run>.json --compare baseline.json

harn replay

Replay a persisted workflow run record from saved output.

harn replay .harn-runs/<run>.json

harn eval

Evaluate a persisted workflow run record as a regression fixture.

harn eval .harn-runs/<run>.json
harn eval .harn-runs/<run>.json --compare baseline.json
harn eval .harn-runs/
harn eval evals/regression.json

harn eval accepts three inputs:

  • a single run record JSON file
  • a directory of run record JSON files
  • an eval suite manifest JSON file with grouped cases and optional baseline comparisons

harn serve

Start an A2A (Agent-to-Agent) HTTP server.

harn serve agent.harn               # default port 8080
harn serve --port 3000 agent.harn   # custom port

See MCP and ACP Integration for protocol details.

harn mcp-serve

Serve a Harn pipeline as an MCP server over stdio.

harn mcp-serve agent.harn

See MCP and ACP Integration for details on defining tools, resources, and prompts.

harn mcp

Manage standalone OAuth state for remote HTTP MCP servers.

harn mcp redirect-uri
harn mcp login notion
harn mcp login https://mcp.notion.com/mcp
harn mcp login my-server --url https://example.com/mcp --client-id <id> --client-secret <secret>
harn mcp status notion
harn mcp logout notion

harn mcp login resolves the server from the nearest harn.toml when you pass an MCP server name, or uses the explicit URL when you pass --url or a raw https://... target. The CLI:

  • discovers OAuth protected resource and authorization server metadata
  • prefers pre-registered client_id / client_secret values when supplied
  • falls back to dynamic client registration when supported by the server
  • stores tokens in the local OS keychain and refreshes them automatically

Relevant flags:

FlagDescription
--url <url>Explicit MCP server URL when logging in/out by a custom name
--client-id <id>Use a pre-registered client ID instead of dynamic registration
--client-secret <secret>Optional client secret for client_secret_post / client_secret_basic servers
--scope <scopes>Override or provide requested OAuth scopes
--redirect-uri <uri>Override the default loopback redirect URI (default shown by harn mcp redirect-uri)

Security guidance:

  • prefer the narrowest scopes the remote MCP server supports
  • treat configured client_secret values as secrets
  • review remote MCP capabilities before using them in autonomous workflows

Release gate

For repo maintainers, the deterministic full-release path is:

./scripts/release_ship.sh --bump patch

This runs audit → dry-run publish → bump → commit → tag → push → cargo publish → GitHub release in that order. Pushing happens before cargo publish so downstream consumers (GitHub release binary workflows, burin-code’s fetch-harn) start in parallel with crates.io.

For piecewise work, the docs audit, verification gate, bump flow, and publish sequence are exposed individually:

./scripts/release_gate.sh audit
./scripts/release_gate.sh full --bump patch --dry-run

harn add

Add a dependency to harn.toml.

harn add my-lib --git https://github.com/user/my-lib

harn install

Install dependencies declared in harn.toml.

harn install

harn version

Show version information.

harn version