Runex Workflow Engine
Runex is a single-binary Elixir workflow orchestrator. It parses TOML (primary) and YAML workflow definitions, builds a DAG of steps, and executes them via pluggable drivers. It runs in standalone mode (SQLite, default — no configuration required) or federated mode (Postgres + libcluster) for multi-node deployments.
Verified against lib/runex/driver.ex's @drivers map (single source of truth for valid driver = values, Runex.Driver.names/0) — 14 registered drivers:
- command:
shell, mise, nushell - agent:
agent, altana, awman, codex, antigravity, claude - workflow:
workflow, runex(moduleRunex.Drivers.RunexSub) - container:
container, flame - wasm:
wasm
The 14 names are the flat @drivers map; the class labels above come from
execution_class/1's module doc comment, not from the function's actual runtime
behavior — that function's "workflow" guard clause matches
the literal string "runex_sub", not the registered driver name "runex", so
execution_class("runex") actually falls through to "other". This looks like an
upstream naming-drift bug (the guard clause not being updated when the driver was
registered as "runex" rather than "runex_sub"), not a documentation error here.
Current documented version: 0.0.7 (mix.exs @version). Legacy templates for older deployments remain under templates/0.1.0/ and scripts/0.1.0/.
Anti-fabrication
This skill follows core:anti-fabrication. Runex is a workspace-owned strategic surface
with the fastest cadence this marketplace documents, so every claim above the fold is
checked against the source tree rather than release notes. Verified against runex
0.0.7 (mix.exs @version, re-confirmed 2026-08-04, claude-skills-223): the driver list
was corrected from 8 to the real 14 registered in Runex.Driver.@drivers, and workflow
path resolution was corrected from 3 to the real 4 search roots in Paths.workflows_dirs/ 0. A Gate 3 pass then caught the execution_class/1 naming-drift documented above as an
upstream bug, not a doc error (filed separately, claude-skills-239). Re-verify against
the live lib/runex/driver.ex and mix.exs @version before asserting a driver name or
version this skill doesn't cover — this is the fastest-moving source in the repo.
Install
Mise is the recommended install path. It manages the version, pins reproducibly, and uses the GitHub releases backend.
A ready-to-copy pin lives at templates/0.0.7/mise.toml in this skill — copy it into the target repo's mise.toml (or merge under [tools]) and run mise install.
Global pin (one-time, any project):
mise use -g github:vinnie357/runex@0.0.7
Per-project pin (recommended for repos that run Runex):
cp templates/0.0.7/mise.toml <your-repo>/mise.toml # then: cd <your-repo> && mise install
The template's contents:
[tools]
"github:vinnie357/runex" = "0.0.7"
Scripts
This skill provides versioned Nushell scripts for direct API interaction. Current scripts are in scripts/0.0.7/.
runex.nu — API Client
# Server info, health, readiness
nu scripts/0.0.7/runex.nu info
nu scripts/0.0.7/runex.nu health
# Workflows and runs
nu scripts/0.0.7/runex.nu workflows
nu scripts/0.0.7/runex.nu workflow 1
nu scripts/0.0.7/runex.nu runs
nu scripts/0.0.7/runex.nu run 42
nu scripts/0.0.7/runex.nu steps 42
nu scripts/0.0.7/runex.nu submit "bundles/core/workflows/tool-verify.toml" '{"TOOLS":"mise,nu,git"}'
# Step heartbeat (extends long-running step deadlines)
nu scripts/0.0.7/runex.nu heartbeat 42 7
nu scripts/0.0.7/runex.nu heartbeat 42 7 60000 # extend by 60s
# Federation (requires Postgres + libcluster)
nu scripts/0.0.7/runex.nu federation-nodes
nu scripts/0.0.7/runex.nu federation-runs
nu scripts/0.0.7/runex.nu federation-run 99
bundles.nu — Bundle Discovery + Distribution
# Local bundle filesystem operations
nu scripts/0.0.7/bundles.nu list
nu scripts/0.0.7/bundles.nu show bundles/core
nu scripts/0.0.7/bundles.nu validate bundles/core
nu scripts/0.0.7/bundles.nu pack bundles/core
# Server-side bundle catalog
nu scripts/0.0.7/bundles.nu bundles # GET /api/bundles
nu scripts/0.0.7/bundles.nu reload # POST /api/bundles/reload
nu scripts/0.0.7/bundles.nu import core.tar.gz # multipart upload
nu scripts/0.0.7/bundles.nu pull core 0.0.1 # JSON pull via BUNDLE_SOURCES
debug.nu — Step Log Inspection
nu scripts/0.0.7/debug.nu steps 42
nu scripts/0.0.7/debug.nu log 42 7
nu scripts/0.0.7/debug.nu failures 42
nu scripts/0.0.7/debug.nu watch 42 --interval 5
nu scripts/0.0.7/debug.nu heartbeat-status 42 7 # last heartbeat ts + timeout state
Configuration
Scripts and Runex itself read configuration from environment variables. Defaults below are the application defaults from config/runtime.exs; operator deployments often override.
| Variable | Purpose | Default |
|---|---|---|
RUNEX_HOST |
Base URL for scripts' API requests | http://localhost:4000 |
RUNEX_API_TOKEN |
Bearer token for API auth | unset (open) |
PORT / RUNEX_PORT |
HTTP listen port | 4000 (operators often run on 4001 to coexist with VantageEx on 4000) |
BIND_ADDRESS |
Listen address | IPv4 all ({0,0,0,0}) |
RUNEX_WORKFLOW_PATH |
Colon-separated extra workflow search dirs | unset |
RUNEX_WORKFLOWS_DIR |
Project workflows directory | ./workflows |
RUNEX_ROOT_DIR |
Root for bundles/, workflows/ | cwd |
RUNEX_BUNDLE_DIRS |
Colon-separated bundle search dirs | <RUNEX_ROOT_DIR>/bundles |
RUNEX_BUNDLES_AUTO_SYNC |
Run bundle-sync workflow on boot | false |
BUNDLE_SOURCES |
Colon-separated GH Release base URLs for pull-mode bundle import | unset |
RUNEX_DATABASE_URL |
Postgres URL for federated mode | unset (SQLite) |
RUNEX_DB_PATH |
SQLite override (ignored if DATABASE_URL set) | XDG-compliant |
RUNEX_REGION / RUNEX_DATACENTER |
Node region/datacenter labels for federation routing | unset |
RUNEX_MASKED_VARS |
Comma-separated env var name patterns to redact from logs | TOKEN,SECRET,KEY,PASSWORD,CREDENTIAL,DATABASE_URL |
RUNEX_PEER_HOST |
Cluster peer identity + registration host | auto-detect (Tailscale -> hostname) |
PHX_PUBLIC_HOSTS |
Internet-facing user URLs (operator-curated) | unset |
RUNEX_MISE_BIN |
Path to mise binary | auto-detect |
Workflow Path Resolution
Runex resolves workflow_path values through an ordered search (lib/runex/paths.ex workflows_dirs/0):
- Custom dirs:
RUNEX_WORKFLOW_PATHenv var (colon-separated) - Project dir:
RUNEX_WORKFLOWS_DIRenv var (default./workflows, relative to Runex cwd) - Core priv:
priv/workflows/shipped with the Runex release - User data dir:
<data_dir>/workflows(a 4th, lowest-priority search root appended byPaths.workflows_dirs/0, easy to miss when reading only the first three. No dedicated env var — butdata_dir/0resolves per-platform viaplatform_data_dir/0, which on Linux honorsXDG_DATA_HOME, so it moves indirectly there)
Accepts absolute paths, filenames with extension, or bare names (tries .toml, .yaml, .yml in order).
Bundles use a separate search path: RUNEX_BUNDLE_DIRS (colon-separated; defaults to <RUNEX_ROOT_DIR>/bundles). Workflows inside bundles are reachable by the bundles/<name>/<file>.toml path form once the bundle directory is on a search path.
Bundle Structure
A bundle is a self-contained directory with workflows, scripts, and tool dependencies:
bundle-name/
workflow.toml # Root dispatcher workflow (routes ACTION param)
mise.toml # Tool dependencies for the bundle
workflows/ # Sub-workflows (invocable directly)
action-one.toml
scripts/ # Nushell/shell scripts called by steps
do-thing.nu
Bundle names are globally unique. Workflow names are unique within their containing directory. Use bundles.nu show and bundles.nu validate to inspect and verify bundle structure.
Pull-based distribution
Bundles can ship as GitHub Release assets and be pulled into a Runex node on demand. Set BUNDLE_SOURCES to a colon-separated list of GitHub Release base URLs, then either:
- Call
POST /api/bundles/importwith{"name": "...", "version": "..."} - Run
bundles.nu pull <name> <version>
The server resolves the asset URL, downloads, extracts into the bundle cache, and registers it. See the Bundle Endpoints section of templates/0.0.7/api.md for the multipart vs JSON pull modes.
Version Detection
Scripts and templates are versioned under scripts/<version>/ and templates/<version>/. To list available versions:
ls scripts/ | get name
The current documented version is 0.0.7 (matches Runex mix.exs @version). 0.1.0 remains for older deployments — the API endpoints it documented are still wire-compatible with current Runex, but it predates heartbeat, federation, and the expanded driver set. Runex 0.0.7 dropped the agent_runs subsystem that briefly existed in 0.0.6 (deleted per YAGNI — no callers materialized).
mise Tasks Integration
Run mise tasks in any repo to discover available helpers. Repos using Runex typically define mise tasks that wrap API calls:
mise tasks # List available tasks
mise run dev # Start dev server (live-reload)
mise run ci # Run full CI suite
References
For detailed information:
- templates/0.0.7/mise.toml — Ready-to-copy mise pin for Runex
0.0.7 - templates/0.0.7/api.md — Full API reference with request/response shapes (heartbeat, federation, bundles)
- references/bundles.md — Bundle authoring guide with step schema and per-driver examples
- references/debugging.md — Step log inspection, heartbeat debugging, troubleshooting
Legacy:
- templates/0.1.0/api.md — API reference snapshot for older Runex deployments (no heartbeat/federation)
references/bundle-build-rules.md— bundle layout, tool resolution viamise exec, build-in-temp-dir, Burrito cache cleanup, runtime expectations (CLI-first, SQLite default, explicit bundle import, no API keys in params)