fancy-flow
A schema-driven workflow editor + runner where humans and agents build on the same canvas. Swimlanes, undo/redo, auto-layout, validated wiring, a zero-React engine — and an MCP bridge so an agent drives the exact surface you see.
Try it live
Pick an example · each is a real, fully-configured flow you can run, edit, and read. Every canvas is documented with sticky notes.
One trigger, three workflows
Fan one event out and something has to decide what happens when they collide. Run it unguarded first — the interesting part is that nothing breaks.
Guarded. Same three workflows, same order — the only difference is that the guard, deals.has(41), is re-checked immediately before each one starts. Not at dispatch: the hazard is what changed in between.
- 1Enrich dealDeal updated → Score & enrichwaitingNot run yet.
- 2Archive dealDeal updated → Archive + deletewaitingNot run yet.
- 3Notify ownerDeal updated → Email the ownerwaitingNot run yet.
import { runCohort } from "@particle-academy/fancy-flow/engine";
await runCohort([enrich, archive, notify], executors, undefined, {
guard: () => deals.has(41), // re-checked before EACH workflow
reason: () => "deal #41 no longer exists", // recorded on the skipped result
});On a queue it's the same contract, made durable: FancyFlow::dispatchCohort() in fancy-flow-php enqueues only the head, hands the cohort on as each run settles, and records a skipped run's reason on the run itself. A run parked on a human approval holds the cohort until someone decides.
Why fancy-flow
Notes on the canvas
Document a flow with sticky notes — a first-class note kind (title, text, color). Notes are visual-only: the engine skips them, so their text never reaches a runner — it's there for the people and agents reading the graph.
True swimlanes
Resizable lanes group your graph — drop a node in to file it (it moves and clamps with the lane). Lanes never execute; edges cross them freely.
Undo / redo + staged deletes
Every committing edit is one reversible step (Ctrl+Z / Ctrl+Shift+Z). Destructive actions can require a human confirm — agents propose, humans approve.
Auto-layout
One-click “⤢ Tidy” arranges the whole graph — or just one lane's children — into a readable DAG with dagre (bundled, lazy-loaded).
Copy / paste + bulk ops
Copy a subgraph with the wiring between its nodes intact (Ctrl+C/V), duplicate, align and distribute a multi-selection.
Validated, reconnectable edges
Drag an endpoint to rewire a connection; a type-incompatible port pairing is refused — the same rule an agent's flow_connect obeys, so they never drift.
Trigger cohorts
When one event fires several workflows, runCohort orders them, runs them one at a time, and re-checks a guard before each — so a flow that deletes the record leaves the rest skipped with a reason, not silently succeeding.
Headless engine
fancy-flow/engine runs a graph with zero React — server, worker, or CLI. A PHP runtime twin (fancy-flow-php) executes the same WorkflowSchema JSON.
Human+ by construction
The editor is fully controlled state, so an agent drives this exact surface over MCP via registerFlowBridge — an authoring surface AND an inhabited one.
Reactive data + theming
Opt a kind into live output on its card, drive light/dark with a first-class colorMode, and snap nodes into alignment with drag helper lines.
