defineworkflow,
under the hood
A workflow is a plain JS/TS script that orchestrates coding-agent calls — agent(), parallel(), pipeline() — on any harness you choose. Run the same script on Claude, Codex, Copilot, or the raw API — and mix them in a single run, one agent on Codex, the next on Claude. Underneath, every result is journaled by sequence number, so a run replays from a checkpoint without re-invoking the model.
import { agent, defineWorkflow, parallel, phase } from "defineworkflow"
export default defineWorkflow({
name: "research-bugs",
description: "Find bugs across the codebase, then verify each one",
harness: "claude",
phases: [{ title: "Find" }, { title: "Verify" }],
async run() {
phase("Find")
const found = await agent("List suspicious files.", { schema: BUGS })
phase("Verify")
const checked = await parallel(
found.bugs.map((b) => () =>
agent("Is this real? " + b.desc, { schema: VERDICT })),
)
return checked.filter(Boolean).filter((v) => v.real)
},
})Read the machine, not the marketing.
Six interactive walkthroughs, each built from the real source of @workflow/core.
The agent() lifecycle
Step through all 13 stages one agent() call walks — seq, gates, semaphore, validate, journal, release.
open →Journal & resume
Crash, then resume for free. Drag the crash point and watch journaled entries replay with zero model calls.
open →Concurrency
A tiny counting semaphore hands out N slots; the rest queue and wake FIFO in a finally.
open →parallel vs pipeline
See the barrier: where fast items idle, and where each item flows through stages independently.
open →Events & RunState
The only observable. A pure reduce folds a typed event stream into the state the UI and registry consume.
open →The sandbox
Why Date.now(), Math.random() and argless new Date() are hard-banned — determinism is the contract.
open →