Quick start
Two hello-worlds: one that runs offline in sixty seconds and shows you what etium is, and one that drives a real coding agent (Pi).
This is the human path. Having an AI agent do the setup instead? Hand it etium.dev/agent-install.txt — deterministic steps with a PASS criterion each, stop-on-fail.
Setup
npm install -g @etium/core
(Permission error? Your Node is system-installed — the macOS .pkg
installer, or a Linux distro package — so its global prefix is
root-owned. Quick fix: sudo npm install -g @etium/core.
Permanent fix: install Node via Homebrew or a version manager and sudo
is never needed again.)
Etium setup is four questions, the same ones an agent asks on the
agent path: which repo
(wherever you run etium), etium only or with the
ai-engineer loop library (this page is etium only — the
tutorial is the library path),
GitHub wiring or terminal only (this page is terminal
only), and where throwaway work may go (yours to pick
when testing).
Prefer being walked through it? etium init checks your
machine (each missing dependency printed with the command that fixes
it), asks the setup questions with sensible defaults, and applies your
answers.
Hello world, offline — the shape of a run
Etium's whole model: a loop is a plain TypeScript file
that sequences steps (headless subprocesses) and
gates (parks until a human decides). No tokens, no model,
no network needed to see it work — exec runs any command as a
step.
export default async function (run) {
await run.step("greet", { harness: "exec", command: "echo hello > hello.txt" });
const d = await run.gate("publish?", { show: ["hello.txt"] });
await run.step("publish", {
harness: "exec",
command: `echo "hello, ${d.by}" > published.txt`,
});
}
etium run "say hello" --loop hello.ts
etium status
etium gates
The run parked. Nothing is running — kill -9 anything you
like. Now decide:
etium approve <run> "publish?" --note "ship it"
etium tail <run>
Everything that happened is files: ls .etium/runs/<run>/ —
events.jsonl is the append-only ledger (authority for control
flow), steps/ holds each step's exact prompt and raw stream,
decisions/ carried your approval.
grep gate .etium/runs/*/events.jsonl works. That's the
product.
Hello world with Pi — a real agent in the loop
Pi authenticates itself — etium never touches model credentials (see the model-auth doc in the repo). One-time, per machine:
pi
(API-key users can skip the login: the pi adapter passes
ANTHROPIC_API_KEY, OPENAI_API_KEY,
GEMINI_API_KEY, or OPENROUTER_API_KEY through
from your environment — values are redacted from everything etium writes
to disk.)
Now give an agent a task under the bundled ralph loop —
iterate until the check passes:
mkdir hello-pi && cd hello-pi
echo "Create hello.txt containing exactly: hello world" > PROMPT.md
etium run "pi says hello" --harness pi --workspace . \
--param check="grep -q 'hello world' hello.txt" \
--param iterations=3
etium tail <run>
(--workspace . makes the current directory the step
workspace — that's where PROMPT.md is found and where the
agent's files land. Omit it and each run gets a fresh empty workspace
under .etium/runs/<run>/ws/.)
The step's full model conversation is captured under
.etium/runs/<run>/steps/001-iterate.0/ —
prompt.md is exactly what was sent,
raw.jsonl(.zst) is exactly what came back. A word on failure:
pi ships no auth-status command and exits 0 even when the model call
errors, so etium can't refuse up front the way it does for harnesses with
a check command — instead the error surfaces as a message in
etium tail (e.g. error: No API key for provider: …),
the check step fails, and ralph iterates or parks at the guard.
Authenticate (pi → /login) and
etium resume <run>.
Where to go next
- The ai-engineer tutorial — a complete
multi-persona engineering workflow on these primitives
(
etium clone-loop ai-engineer). - The loop-authoring guide and the design docs live in
the repo —
WRITING_LOOPSteaches the API with a worked example;loops/ralph.jsis the whole reference loop, ~35 lines. - Budgets: add
--param wall=10m, or write a loop with per-stepbudget: { wall, tokens, costUsd }.