# @leumas/flow-recorder

Record & replay real runtime hook flows into replayable timelines. Part of the Leviathan runtime; mounted by leumas-api at /api/flows. Captured flows feed perception→rules→action.


Record real runtime hook flows into **replayable timelines**, and expose them over the API.
Part of the **Leviathan runtime** — captured flows feed the perception→rules→action loop (P5), so
apps stop being black boxes and become **observable, replayable, trainable organisms**.

Works with any hook emitter that supports `onAny`/`offAny` or `on('*')`/`off('*')`, plus `emit()`.

## Record & replay

```js
import { createFlowRecorder } from '@leumas/flow-recorder';

const recorder = createFlowRecorder({ hooks }); // hooks = your live-hooks emitter
recorder.start();
hooks.emit('server:start');
hooks.emit('music:loaded', { track: 'dreamscape.mp3' });
recorder.stop();

const flow = recorder.export();           // { meta:{source,started,ended}, events:[{name,ts,payload}] }
await recorder.replay({ hooks, speed: 1 }); // re-emit in order; delay = original delta * speed
```

Pass `filter` as an array of event names or `({ name, payload }) => boolean` to limit capture. `ts` is
relative to `started` in ms.

## API (mounted in leumas-api at `/api/flows`)

```js
import { createFlowRouter } from '@leumas/flow-recorder';
app.use('/api/flows', createFlowRouter({ store, gate: requirePassNode(), getHooks }));
```

- `GET  /api/flows` → list saved flows (summaries)
- `GET  /api/flows/:id` → one full flow (meta + events)
- `POST /api/flows` → save a flow `{ meta, events }` *(gate meters writes)*
- `POST /api/flows/:id/replay` → replay onto a host-provided emitter (`getHooks(id, body)`)
- `DELETE /api/flows/:id` → delete

`store` defaults to an in-memory store (`createMemoryFlowStore`). Back it with the leumas.db `flows`
collection by passing a `{ list, get, save, remove }` adapter.


---
Source: shared/engines/leviathan/flow-recorder/README.md
Canonical: https://docs.leumas.tech/p/engines/flow-recorder
