Rhei
Rhei is an agent runtime for governed work. It turns Markdown workflows into
predictable agent and program execution with explicit state, dependencies,
artifacts, monitoring, snapshots, and reusable templates. The runtime can be
driven from the rhei CLI, embedded Rust crates, and language bindings.
Why Rhei
Rhei is the only agent runtime that combines all of:
-
Markdown is the source of truth. A plan is a
.rhei.mdfile you can read, diff, and edit in any editor — not a database, not a chat scratchpad. -
Explicit prerequisite DAG.
**Prior:**declares dependencies, validated for cycles, missing references, and kind mismatches. -
Hierarchical tasks with configurable depth (
structure.maxLevels1–4, default 2). A child is the same keyword one heading deeper —### Task 1:holds#### Task 1.1:— so nesting needs no configuration. -
Custom node kinds. Plans start with
Taskalone; declarestructure.nodeKinds: [task, subtask, bug, spike]to author#### Subtask 1.1: …,### Bug 3: …, or### Spike 4: …. The list replaces the default, so keeptaskin it — and addsubtaskif you want that spelling for children. The frontmatter block goes below the# Rhei:heading (and below**States:**), not at the top of the file:structure: nodeKinds: [task, subtask, bug, spike] maxLevels: 3 -
Pluggable YAML state machines. Define your own states, allowed transitions, per-node-kind profiles, and required input/output artifact contracts per state — including counted review loops via
visits: nandstate-2suffixes. -
Multi-agent coordination over git. Directory Workspace mode shards tasks into per-file markdown so swarms can advance in parallel without merge conflicts;
rhei transitionprovides atomic compare-and-swap on state. -
Deterministic ready-work selection.
rhei nextclaims the next eligible task by terminal-state prerequisites and node policy, no LLM guesswork. -
Runtime orchestration from CLI or API.
rhei runadvances ready work through state machines, spawns agents or deterministic programs, captures logs and artifacts, and exposes the same model through reusable crates and bindings. -
Full validator.
rhei validatechecks syntax, state validity, dependency integrity, hierarchy/id alignment, link integrity, terminal-tree coherence, and artifact contracts. -
Templates: automate your complex daily routines in minutes. Capture a recurring workflow — code review loops, release checklists, onboarding, audits — once as a parameterized template (plan skeleton + state machine + typed inputs), then
rhei instantiateit with concrete values to spin up a ready-to-execute workspace. Ten templates ship inside the binary, sorhei templatesis populated the momentrheiis installed. Seedocs/functional-spec/rhei-templates.spec.md.
See docs/functional-spec/comparison.md for a detailed comparison against
beads, beans, opencode, Claude Code TodoWrite, Cline, Cursor, Roo, Devin, and
Augment.
Two crates are published to crates.io:
rhei-plan(rhei_core): core plan model for the agent runtime, including AST types, parsing, callbacks, and workspace primitivesrhei-cli:rheicommand-line driver (also installed asrh) for validation, execution, monitoring, snapshots, templating, and rendering
Validation, rendering, the terminal UI, and the flow visualization are modules
inside rhei-cli rather than separate packages — a crate that only divides the
CLI's own source would otherwise become a permanent public package name for no
one's benefit.
Also in the workspace, unpublished:
rhei-agent-core: re-export facade overrhei-plan, awaiting an API of its ownrhei-api: language API package surface on npm and PyPI; the N-API implementation lives incrates/rhei-napi
Agent runtime
The runtime currently supports:
- parsing Rhei, task, and subtask structure from Markdown workflows
- validating task metadata, dependencies, state machines, and artifact
contracts against
docs/functional-spec/states.yaml - selecting ready work deterministically with
rhei next - atomically advancing work with
rhei transition,rhei complete, andrhei reset - orchestrating agents and deterministic programs with
rhei run - recording runtime logs, results, snapshots, and dashboard state under
runtime/ - rendering plans as JSON, GitHub-style markdown, or terminal-oriented progress output
- rendering a self-contained HTML Flow visualization of a plan or workspace
with
rhei viz(the same surfacerhei runserves live)
The primary reference documents are:
docs/architecture/overview.md— start here for tool usage and specification indexdocs/architecture/agent-orchestrator-workflow.spec.md— orchestrator/worker interaction modeldocs/functional-spec/rhei-language-reference.spec.md— canonical entry point for the authored Rhei language surfacedocs/functional-spec/rhei-plan-language.spec.md— plan language specificationdocs/functional-spec/rhei-states.spec.md— states specificationdocs/functional-spec/states.yaml— default validation states definition
First 10 minutes
After installing from Cargo or running from this checkout, start with a mock-backed example that does not require external agent credentials:
That validates a real workspace, runs deterministic mock agents in a temporary copy, and leaves runtime logs and artifacts in the copied workspace. To inspect the larger dashboard fixture without executing subprocesses:
Use examples/README.md as the cookbook once the basic
loop is clear. It maps common jobs such as code review, snapshots, multi-agent
analysis, and dashboard testing to concrete examples.
Install
Cargo
Install the rhei CLI from this checkout with Cargo:
Install the published CLI package from crates.io:
The crates.io package is named rhei-cli because the crate name rhei belongs
to an unrelated project. The installed commands are rhei and its short alias
rh — the same binary under both names.
Use --locked so Cargo respects the repository lockfile. This avoids resolving newer dependency versions that may require a newer Rust compiler than the project currently targets.
Cargo installs the binary to ~/.cargo/bin/rhei. Make sure ~/.cargo/bin is on PATH before any older system install location:
If an older /usr/local/bin/rhei appears before ~/.cargo/bin/rhei, either adjust PATH or invoke the Cargo-installed binary directly:
npm
Install the CLI from npm:
Use the JavaScript helper API:
const = require;
console.log;
const result = ;
The npm packages install the Rust CLI through Cargo during installation, so
Rust and Cargo must be available on PATH.
These alpha packages are thin wrappers around the Rust CLI; they are useful for
distribution and helper APIs today, not a replacement for the native runtime
crates.
PyPI
Install the CLI from PyPI:
Use the Python helper API:
=
The PyPI package name is rhei-cli because rhei is already taken on PyPI.
The installed commands are still rhei and rh.
These alpha packages are thin wrappers around the Rust CLI; they are useful for
distribution and helper APIs today, not a replacement for the native runtime
crates.
Completions
Install shell completions for the current user:
Installed completions are dynamic, so rhei instantiate <TAB> offers template
names from .agents/rhei/templates/, ~/.agents/rhei/templates/, and the
built-in library shipped with the binary.
See Tab Completions for shell-specific setup notes, default install paths, and system-wide installation.
CLI usage
Validate a plan with the built-in default states definition:
Validate using a specific states file:
Watch a plan and states file for changes:
Render a plan as pretty JSON:
Render a plan as GitHub-style markdown without metadata or subtask body text:
Render a terminal progress report without ANSI color:
Render a self-contained HTML Flow visualization and open it in the browser:
rhei viz <plan|workspace> writes a single offline HTML page — the plan, every
task and subtask with its state, the resolved state machine, and the surroundings
inspector — under the workspace's runtime/ directory (runtime/<input>.html,
or runtime/rhei-viz.html for a workspace directory), the same place a live run
freezes its final dashboard, or to --output <FILE>. Writing under runtime/
keeps generated HTML out of the source tree. It is the same Flow surface
rhei run serves live, frozen to a file; the live agent terminal and intervene
composer are inert in the static page. See
docs/functional-spec/rhei-viz.spec.md.
Message a running agent during a live run (the headless sibling of the Flow dashboard's intervene composer):
rhei intervene discovers the live run's dashboard from runtime/dashboard.json
and writes the message to the target agent's stdin — the same /intervene
channel the dashboard composer uses, never a plan transition. It only reaches
agents whose profile keeps stdin open (intervene_stdin); see Enabling live
intervention. Every
delivery is recorded to runtime/interventions.log.
Claim the next ready task and inspect its instructions:
Complete a task and record the result:
Print crate versions surfaced by the CLI:
Reset a plan back to the initial state declared in its state machine:
Development hooks
Install the pre-commit hook to run grounding checks before each commit:
The checked-in hook runs:
Library usage
Typical flow inside Rust code that embeds the runtime model:
- Add
rhei_agent_core = { package = "rhei-agent-core", version = "0.1.0" } - Parse markdown with
rhei_agent_core::parse - Load a states definition with
rhei_validator::StateMachine::from_yaml_file - Validate with
rhei_validator::validate_with_machineorrhei_validator::validate_from_machine_file - Render with helpers from
rhei_output
The published package names are conflict-free, while the Rust crate import
names include rhei_agent_core, rhei_core, rhei_validator, and
rhei_output.
Status notes
This documentation reflects the current repository behavior. In particular:
- parsing retains rhei-level text and subtask body content
- validation enforces required
**State:**metadata, dependency existence, metadata ordering, cycle detection, and subtask numbering checks - runtime execution is available through
rhei run,rhei next,rhei transition,rhei complete,rhei reset, andrhei snapshot - rendering is available for JSON, GitHub-style markdown, and progress reports
- examples beyond repository documents are tracked separately by subtask 8.4