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.20.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.