Migrating from 0.2
Nothing breaks. Every 0.2 call site compiles and behaves identically on 0.3 and 0.4. Here's what changed and what to rename when you're ready.
Bump the range#
If you depend on ^0.2.0 or ^0.3.0, npm won't move you forward on its own — on a 0.x version, caret is locked to the minor. Bump the range to ^0.4.0 deliberately, change no code, and migrate the verbs whenever you like before 1.0.
The verbs#
| 0.2 | 0.3 |
|---|---|
note(text, context?) | report(input, context?) |
tell(title) | finish(title) |
warn(title) | finish(title, { level: "warn" }) |
oops(title, error?) | finish(title, { level: "oops", error }) |
The old names remain as aliases until 1.0 and are silent unless you set STORYTELLER_DEPRECATION_WARNINGS=1. tell will not be reintroduced with a new meaning — reusing a familiar name with inverted semantics stays a trap for anyone still on 0.x.
Behavior changes#
error.cause is now normalized rather than kept as a live Error. Previously the raw Error serialized to {}, so the cause was silently lost in every stored record. The chain is now preserved, depth-capped at five. If you read cause as an Error instance, it's a plain object now. - Records carry
kind and storyId; beats carry sequence. Additive. Rows written by 0.2 still typecheck — the fields are optional on the record types. - The console audience now hears beats as well as stories. No visible change unless you switch narration to
live. STORYTELLER_LEVEL filters the closing story too. With warn, an info-level finish() is dropped along with the quiet beats. That follows from "minimum level delivered", but it's worth knowing. - Context values are normalized on the way in. A circular object passed as
what used to break JSON.stringify inside the console audience; it's now marked and stored safely.
New in 0.3#
Live narration, chapters, ndjsonAudience, environment configuration, onAudienceError, back-pressure bounds, universal input normalization, and npx @lovelaces-io/storyteller init.
New in 0.4#
Stories become answerable. A StoryStore contract with memoryStore() and fileStore(), storeAudience() to keep every story, the query vocabulary (stories(store).failing().since("24h")), redaction by value at capture and again at the storage boundary, and an add-on package: @lovelaces-io/storyteller-mcp, the Librarian, a read-only MCP server so an agent can read stories back. Nothing existing changes; see The Library. The changelog has every line.