footprintjs
TypeScript workflow engine that records each run's stages, state changes and decision evidence, so AI agents and people can explain and debug what happened.
The 3-step pattern
Section titled “The 3-step pattern”import { flowChart, decide, narrative } from 'footprintjs';
// 1. Define your input and your stateinterface OrderInput { orderId: string; total: number;}interface OrderState { tier?: string; status?: string;}
// 2. Build your flowchartconst chart = flowChart<OrderState>('Validate', async (scope) => { const { total } = scope.$getArgs<OrderInput>(); // run input arrives as args scope.tier = total > 100 ? 'premium' : 'standard';}, 'validate') .addDeciderFunction('Route', (scope) => { return decide(scope, [ { when: { tier: { eq: 'premium' } }, then: 'express', label: 'Premium order' }, ], 'standard'); }, 'route') .addFunctionBranch('express', 'ExpressShip', async (scope) => { scope.status = 'express-shipping'; }) .addFunctionBranch('standard', 'StandardShip', async (scope) => { scope.status = 'standard-shipping'; }) .setDefault('standard') .end() .build();
// 3. Run and observeconst rec = narrative();await chart.recorder(rec).run({ input: { orderId: 'ORD-001', total: 149 } });
console.log(rec.getEntries().map((e) => e.text).join('\n'));// Stage 1: The process began with Validate.// Step 1: Write tier = "premium"// Stage 2: Next, it moved on to Route.// Step 1: Read tier = "premium"// [Condition]: It evaluated Rule 0 "Premium order": tier "premium" eq "premium" ✓, and chose ExpressShip.// Stage 3: Next, it moved on to ExpressShip.// Step 1: Write status = "express-shipping"Where to go next
Section titled “Where to go next”OverviewWhat footprintjs is, with a diagram of the chart above.
Key conceptsThe flowchart pattern, typed scope and observer channels.
Building blocksStages, decision branching and subflows.
Observing with recordersThe built-in recorders and how to write your own.