npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

passages

v0.2.2

Published

Miadi Passages - Narrative Formulations for the Miadi Chronicle

Readme

Passages

Passages is the narrative formulation engine for the Miadi Chronicle. It transforms chronological events and branch-map data into interactive story formats (like Twine/Twee).

Overview

In the Miadi platform, a Passage is a structured unit of narrative that represents a specific branch, chapter, or moment in time. This package provides the tools and wrappers to manage these formulations across the distributed ecosystem.

Features

  • Chronicle to Form: Transforms raw Miadi Chronicle episodes into structured narrative units.
  • Twine Integration: Supports the promotion of episodes into interactive Twinery story worlds.
  • Narrative Motion: Applies the RISE framework and structural tension to ensure meaningful story progression.

Installation

Python

pip install passages

Node.js

npm install passages

Usage

passages --help

mkepisode — Chronicle episode vessel

Creates a minimal Chronicle episode vessel (one directory + one episode.yaml carrying the goal and references) under the chronicle root. See rispecs/mkepisode.spec.md for the full contract.

mkepisode \
  -n 133 \
  -t honcho-eval-adequate-memories \
  -g "Establish adequate memories for the honcho evaluation." \
  -r "https://example.test/reference-one" \
  -r "jgwill/Miadi#133"

--adopt — the one repair path

A directory born by hand (mkdir, a clone, an agent writing notes straight into the chronicle) resolves by number but carries no episode.yaml. inquiry-weave lineage cannot author an edge on it and the /chronicle surface cannot render it — both read the manifest — and mkepisode used to refuse the number without offering any way forward, leaving the vessel permanently unreachable.

The medicine wheel is not one of those readers, which is what makes this shape dangerous: registerEpisodeNode derives the card from the directory name, so a manifest-less vessel registers successfully and the wheel then reports it healthy. Two episodes in the live chronicle are in exactly that state. A green wheel is not evidence that a vessel has a manifest.

--adopt writes the missing manifest in place, keeping the directory's own date, number and slug (read off its name) and touching nothing else in it:

mkepisode --adopt \
  -n 67 \
  -t "Renaud meeting" \
  -g "The relationship becomes provenance the chronicle can see." \
  -r "provenance/nicolas-renaud-260619.md"

It refuses when an episode.yaml is already present — adoption only ever fills a missing manifest, it never overwrites or merges one — and it refuses an ambiguous number (several directories carrying it), because there is no single vessel the manifest would belong to. On a free number it simply creates the vessel normally. Registration and the .mw-registration.json receipt run exactly as they do at birth.

Three refusals worth knowing, because each one is a case where guessing would have been quieter than stopping:

  • A directory whose name carries no YYYY-MM-DD is refused rather than stamped with today. The date is part of the identity being preserved; minting one would rewrite a June episode as an August one under the directory's own authority.
  • An episode.yaml that cannot be read — a dangling symlink, an unreadable parent — is refused rather than treated as absent. existsSync answers false for both, which would let adoption replace a manifest pointer with a file, the one thing this flag promises never to do.
  • --status exists because adoption runs, by definition, on directories that already hold work. The default vessel describes an empty one; pass --status woven (or whatever is true) rather than stamping finished work as empty.

Flags: -n/--number (required positive integer), -t/--title (required; kebab-case preserved as slug, otherwise normalized), -g/--goal (required), -r/--reference (required, repeatable, order preserved), --chronicle-root (explicit override; defaults to $MIADI_CHRONICLE_ROOT), --adopt and --status <text> (above), --register [url] / --no-register (below). It never overwrites or merges into an episode that already has a manifest, and fails without writing when the number already resolves and --adopt was not given. A created directory is stamped with the local calendar date; an adopted one keeps its own.

Vessels visible at birth (jgwill/Miadi#490): when MW_API_URL is set or --register is given (--register <url> overrides the env; no other default url is assumed; --no-register always wins), mkepisode registers the episode card into medicine-wheel /api/nodes via @miadi/inquiry-weave's registerEpisodeNode — naming and shining become one gesture. A truthful receipt lands beside episode.yaml as .mw-registration.json (state registered | already-registered | pending, node_id, timestamp, url, and error when pending). An existing card is already-registered success and is never overwritten. Registration is fail-open: vessel creation never fails because of it.

Composition: passages owns creation and narration; directory allocation and collision rules are consumed from @miadi/inquiry-weave's scaffoldEpisode — relating and syncing inquiries stays inquiry-weave behavior. The JavaScript distribution is the canonical implementation; the Python distribution does not expose mkepisode yet.

sketch — derive a book from an episode vessel

mkepisode owns birth; sketch owns the modality switch. It reads a vessel and emits Twee source derived from it — source only, no HTML render, and no write outside --out. The chronicle stays canonical and read-only.

passages sketch --episode 311                       # to stdout
passages sketch --episode 311 --out book.twee       # to a file
passages sketch --episode 311 --json                # the derivation report

A passage is never invented, it is read. Each vessel unit becomes one passage: every inquiry/weave.yaml entry, every ## section of the narrative document, every *audio-manifest.json, every lineage.relates_to exit, plus a board and a provenance page. Every emitted passage carries a passages-sketch stamp naming its source and the hash the vessel already recorded for it — copied, never computed. Units the vessel records no hash for are stamped unstamped with a reason, because the set of unverifiable passages is a finding a reader is owed.

Full mapping table, the ep311 worked fixture, and the explicit list of what a machine cannot produce: rispecs/episode-to-passages.contract.md.

validate — hold a book to its vessel

passages validate --episode 311 --twee book.twee

Re-reads the vessel, compares every stamped hash against the vessel's current records, and walks every internal link from the declared start. Exits 1 on drift, on a stamped source that has left the vessel, or on a link with no passage behind it; 0 when clean. Unstamped passages are reported, never failed — a hand-authored passage is allowed to exist, it simply cannot be verified.

This is the structural half of PARITY ALWAYS. It does not replace the browser walk: Harlowe runtime errors surface only when rendered, so validate also lists markup candidates for a human to check.

Status

The npm distribution ships the canonical mkepisode Chronicle vessel command, plus passages sketch and passages validate — the episode→book derivation named in rispecs/episode-to-book.spec.md §S3 and specified in rispecs/episode-to-passages.contract.md. Rendering .twee to a library-visible .html stays with the Twine repo's donor injector. The Python distribution remains a placeholder and exposes none of these.

License

MIT