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

@esbenwiberg/capsule

v0.1.0

Published

A thin CLI for change capsules — sealed, point-in-time, per-change records.

Readme

capsule

A capsule is a sealed, point-in-time record of a single change — written once at merge, never edited, opened later by whoever needs it.

Think time capsule, not spec. You seal what's true the moment a change lands, and a future consumer — a docs generator, a release-notes bot, a reviewer, a decision-graph tool you haven't built yet — opens it to do its job. You never go back and edit one. They're allowed to age.

capsule is two things:

  1. A format — a small, consumer-neutral YAML record of a change. This is the deliverable.
  2. A thin CLI — creates, validates, lists, and prunes capsules. A clerk for the registry, nothing more.

It does not generate docs, write release notes, or review code. Those are consumers, and they live elsewhere. capsule only guarantees the record carries what they need.

Use cases

A capsule is the structured input that lets other systems work off what changed and why. The schema is reverse-engineered from these. Most are external (you build them; capsules feed them); a couple ship in-tool.

| Use case | Reads | Where it lives | |---|---|---| | Reviewer assistance (human/AI) | intent, impact.risk, decisions, links.tests | external consumer | | Auto docs + end-user guides (with screenshots) | intent, touchpoints[].reach/expect, impact.benefit | external consumer | | Auto-classify release impact | impact.visibility/compatibility/migration, areas | external consumer | | Customer-facing release notes | impact.visibility (filter), impact.benefit (voice) | external consumer | | Troubleshooting / root-cause — why a bug/change was introduced | intent, impact.risk, decisions (incl. supersedes lineage) | built in: capsule which | | Decision graph / lightweight DDD — decision archaeology, superseded-decision detection | decisions[] (id + edges across capsules) | external consumer | | Schema validation / commit gating | whole capsule + git range | built in: capsule validate, capsule check | | Something in the future, idk | tags, x, + the decision graph | open extension space |

The point: capture the non-derivable stuff (intent, decisions, audience, nav recipes) once, while the author still has context, and amortize it across all of these. Prompting each off a raw diff instead costs more tokens and yields worse output — the diff is missing exactly that.

Why not specs / ADRs / changelogs?

  • Specs are planning exhaust — written before, stale after, a living document you must keep true forever. A capsule is retrospective and immutable; "stale" isn't a concept because it's pinned to one commit range.
  • ADRs are documents about a decision — rare, deliberated, edited and superseded over time. A capsule is a record of a change, in which decisions are just one facet. The few decisions heavy enough graduate to an ADR; the capsule links it.
  • Changelogs are prose for humans reading what shipped. A capsule is structured for machines acting on a change — and a changelog is just one of the things you can generate from it.

What a capsule looks like

kind: change-capsule
schema: 1
id: cap-2026-06-04-fix-pod-retries
created: 2026-06-04
pr: 123                              # derived
commit_range: abc123..def456         # derived
areas: [daemon, desktop]             # derived from changed paths

intent: Spawn bounded fix pods when CI fails after a PR opens.

impact:
  visibility: customer
  benefit: PRs that fail CI now self-heal instead of stalling.
  compatibility: additive
  migration: none
  risk: [retry-loop bound, merge_pending transitions]

touchpoints:                         # where the change is observable
  - kind: ui
    at: desktop ▸ pod detail ▸ merge status
    reach: [open a pod with a failed PR, scroll to merge section]
    expect: fix pod shown as a linked follow-up

decisions:                           # lightweight decision atoms → a graph emerges across capsules
  - id: D-014
    choice: Bounded fix pods for actionable CI failures.
    options: [manual fix, infinite retry, bounded fix pods]
    because: PRs stall when CI fails after validation passes.
    by: agent
    confidence: high
    supersedes: [D-009]
    adr: docs/decisions/014-fix-pods-for-merge-failures.md

links:
  issues: ["#120"]
  tests: [packages/daemon/src/pods/pod-manager.test.ts]

tags: [ci, self-healing, automation]
x: {}                                # extension namespace for future consumers

See docs/design.md for the full rationale and docs/schema/capsule.schema.json for the formal schema.

Design principles

  • Name the change, not the reader. Fields describe the change (impact, touchpoints, decisions) — never a consumer (review:, release:). Each consumer projects the slice it needs.
  • Store seeds, derive outputs. Keep the ADR link not the why-prose, the nav recipe not the screenshot, the commit range not the diff. Outputs are regenerated on demand; nothing to maintain.
  • Drift is allowed — once sealed. While draft, a capsule accretes freely. Once sealed (at merge) it's a frozen snapshot you never edit; a reversal later shows up as an edge (supersedes:) in a new capsule, not as an edit to the old one.
  • Small stable core + open extension. Consumers rely on the core facets; anything speculative lives in tags/x and graduates into the core (schema: 2) if it proves universal.

Lifecycle

A capsule is born when the work starts, accretes as you go, and is frozen at merge:

session start ──▶ capsule new            status: draft
                  (or new --draft to pre-fill captured fields from the diff via Claude)
                     │
   during work ──────┤  edit the draft file directly — add decisions as you make them,
                     │  touchpoints as you build UI, refine intent. It's just a local YAML.
                     ▼
   at merge ──────▶ capsule seal          status: sealed
                     │  stamps final commit_range + pr, then freezes it
                     ▼
   sealed = immutable. Corrections come as a NEW capsule with `supersedes`, never an edit.
                     │
   later ──────────▶ consumers read it; archive / prune by date when it's safe

Do you need an "edit" command? No. A draft capsule is just a local file — you (or an agent in the session) edit it directly; capsule validate checks it. The only lifecycle verb you need is seal, which performs the finalize transition and, from then on, the tool refuses to re-seal it.

CLI

npx @esbenwiberg/capsule new                 # scaffold a capsule (status: draft), auto-fill derived fields from git
npx @esbenwiberg/capsule new --draft          # also draft captured fields from the diff via Claude
npx @esbenwiberg/capsule seal                 # at merge: stamp final commit_range/pr, freeze to sealed
npx @esbenwiberg/capsule validate             # check capsules against the schema (good pre-commit hook)
npx @esbenwiberg/capsule check --base origin/main      # CI/agent gate: changed code has a sealed capsule
npx @esbenwiberg/capsule agent-guide          # print copy-pasteable instructions for agent workers
npx @esbenwiberg/capsule which <commit>       # which capsule accounts for a commit / file / file:line
npx @esbenwiberg/capsule list --since v1.4.0
npx @esbenwiberg/capsule export --since v1.4.0 --json   # hand a bundle to any consumer
npx @esbenwiberg/capsule archive --before 2026-01-01    # compact out of the active set
npx @esbenwiberg/capsule prune --before 2025-06-01      # delete

Capsules live in .capsules/, one file per change. archive moves them to .capsules/archive/; prune deletes. Lifecycle is manual — because multiple unknown consumers read the same capsules, the tool can't know when it's safe to remove them. You decide.

new --draft

With ANTHROPIC_API_KEY set, --draft reads the diff + commit messages and asks Claude to propose the captured fields (intent, impact, touchpoints, decisions, tags). Without a key it falls back to dumb scaffolding. Model defaults to claude-sonnet-4-6; override with CAPSULE_MODEL. The draft is a starting point — review before committing.

check — agent/CI gate

capsule check --base <ref> compares the branch from the merge-base with <ref> to HEAD. If non-capsule files changed, it requires a changed capsule in .capsules/, validates it, requires status: sealed, requires sealed and commit_range, rejects placeholder intent, and verifies every non-capsule file and commit is covered by the capsule range.

For a single worker task:

capsule new --id cap-2026-06-04-worker --intent "Fix retry accounting for worker pods"
# edit code, and keep .capsules/cap-2026-06-04-worker.capsule.yaml current
capsule validate .capsules/cap-2026-06-04-worker.capsule.yaml
capsule seal cap-2026-06-04-worker
capsule check --base origin/main --id cap-2026-06-04-worker

For CI:

capsule check --base origin/main

If a branch intentionally has multiple capsules, use --allow-multiple; otherwise the default is to make ambiguity loud.

which — troubleshooting

Given a suspect, surface the change's why:

capsule which a1b2c3d            # a commit-ish
capsule which src/retry.ts       # a file
capsule which src/retry.ts:142   # a line → git blame → the commit that introduced it

It prints the matching capsule's intent, self-declared risk, and decisions — the reasoning layer git blame can't give you. It's a force multiplier on git, not a replacement: it tells you where to look and why, never that the code is correct. Quality depends on capsule coverage; an uncapsuled change returns nothing.

Pre-commit hook

examples/pre-commit blocks a commit if any staged capsule is invalid:

cp examples/pre-commit .git/hooks/pre-commit && chmod +x .git/hooks/pre-commit

Status

v0.1 — format + thin CLI. Consumers (docs generation, release notes, reviewer assist, decision-graph views) are intentionally out of scope; they're downstream and build against the format.