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

@ultimat3/manifest

v17.0.0

Published

x.manifest.json: deterministic generated facts, contract diff, AGENTS.md budget

Readme

@ultimat3/manifest 📋

Generated facts. x.manifest.json is emitted from code, committed, and diffed in review — it is how an agent learns what the app is without reading every file.

import { buildManifest, emitManifest, assertNoDrift, verifyContract } from '@ultimat3/manifest';

const manifest = buildManifest(frameworkSources({ app, routes, policies }));
await emitManifest({ manifest });                  // x manifest
await assertNoDrift({ manifest });                 // x verify
verifyContract({ before: committed, after: manifest });

What it contains

| Section | Facts | |---|---| | routes | url, render mode, offline strategy, hydrate, revalidate tags, budget | | entities | table, columns (type, nullability, PK, FK), named invariants | | actions | input + output schema, policy label, required permissions, cache invalidations, declared rate limit, MCP exposure, mutator when it is one | | queries | input schema, policy label, required permissions, live, cache tags | | jobs | input schema, queue, retry policy, step names | | tasks | cron, tz, jobs enqueued | | policies | permission, where enforced | | permissions | derived from policies + each operation's own list, never declared twice | | locales, errorCodes | catalogs a tool can enumerate |

Plus manifestVersion (shape version, so a reader can check compatibility), app, and buildId.

An operation's policy is its display label — a composite renders as and(post:publish, org:administer), which is not a permission and matches no grant. Match a grant against permissions; matching on policy reports every non-trivially-guarded operation as enforcing nothing.

Determinism

The file is committed and reviewed, so two builds of the same tree must produce identical bytes. Enforced, not hoped for:

  • No timestamps, no git sha, no hostname, no build counter.
  • Every collection is sorted by a stable key before writing, inner lists included (a route's revalidateTags, an action's cacheInvalidates, a task's enqueues) — Map/Set iteration order is insertion order, and insertion order depends on module load order, which depends on the filesystem.
  • Object keys are written in a fixed order, not JSON.stringify order, so reordering a struct literal produces no diff.
  • buildId is a sha256 of canonicalJson (@ultimat3/core) over the body, so it changes if and only if a fact changed — and verifyBuildId() re-derives it from the file, catching a hand edit.
  • Job steps keep declared order. A job's steps are a sequence, not a set.

A manifest that churns on every build trains reviewers to ignore its diff, which defeats the whole mechanism.

The contract diff

diffManifest(before, after) classifies every change:

| Class | Examples | |---|---| | breaking | action/query/route/job/task/entity/policy/error code removed; input or output schema changed; policy changed; an operation gained a required permission; a policy gained an enforcement site; a rate limit was tightened or introduced; MCP exposure withdrawn; column removed, retyped, or made NOT NULL; a column's primaryKey or references changed in either direction; an entity's table renamed; an invariant added; a job's queue moved or its retry.attempts lowered; a route's surface changed; live query became non-live | | additive | primitive added; nullable column added; a column that lost NOT NULL; a required permission dropped; an enforcement site dropped; an invariant dropped; a rate limit loosened or removed; more retry attempts; MCP exposure granted; locale added | | internal | cache tags changed (actions and queries); render mode changed; a route's offline/hydrate/budget/revalidateTags; a task's cron/tz/enqueues; a job's retry.backoff; job steps reordered; an error code's owning package; buildId |

Every top-level section is classified, and that is checked rather than promised: diff.test.ts walks ARRAY_SECTIONS from schema.ts and fails on a section nothing reads. Two of them — tasks and errorCodes — were unread until 2026-08, along with ten fields, so deleting every scheduled task reported internal buildId: content changed and passed the gate.

One classifier per section, each in its own file: diff-operations.ts (actions, queries, permissions), diff-rate-limit.ts, diff-entities.ts, diff-work.ts (jobs, tasks), diff-routes.ts, diff-registries.ts (policies, error codes), over the shared vocabulary in diff-change.ts. diff.ts is the orchestrator and nothing else.

verifyContract() is the gate: a breaking change fails unless the app's major version moved. An unparseable version counts as "not bumped" — fail-closed.

X_MANIFEST_BREAKING: contract broke without a version bump
  cause: 1 breaking change(s) from 1.4.2 to 1.5.0 with no major version bump:
         actions.publishPost: action removed
  fix:   bump the major version in app.config.ts, or restore the removed contract

AGENTS.md: validated, never generated

checkAgentsMd() / assertAgentsMd() verify that a hand-written AGENTS.md exists and is under 12kB. They do not generate prose, and there is deliberately no generator to point at.

Research shows LLM-generated context files reduce task success and add steps: the prose reads plausibly, drifts from reality the moment anything changes, and an agent trusts it over the code. So the split is fixed:

  • facts are generatedx.manifest.json, regenerated every build;
  • conventions are human-authoredAGENTS.md, short enough to be read every time.

The checker warns (never fails) when AGENTS.md starts tabulating schema or route facts, runs past 200 lines, or claims to be generated. Those warnings ride in the step's output, so x verify --json carries them for a human to judge.

x verify runs assertAgentsMd() inside its manifest step — the same step that checks the generated half — and unlike the drift check it applies everywhere, including a repo that has never run x manifest. Enforced, not documented: both codes below can actually fail a build.

Local docs: read, never emitted

scanPackageDocs() / scanInstalledDocs() read an installed package tree and return DocEntry values; searchDocs() ranks them against a question. This is what x docs "how does job() retry" answers from — offline, from node_modules, with no filename known in advance.

There is no generated docs.json, on purpose. The published artifact is the source (PUBLISHING.md): files ships src/**, README.md and CLAUDE.md, and Bun runs the TypeScript directly. Every doc is therefore already inside the tarball — what was missing was retrieval, not payload. A per-package docs.json would be a second copy of bytes the install already has, and the second copy is the one that goes stale. Reading the installed source cannot disagree with the installed version, because it is the installed version.

| Entry | Source | Topic | |---|---|---| | module | the file header comment on a module src/index.ts re-exports, plus its public symbols | jobs.retry | | guide | a ## section of README.md or CLAUDE.md, quoted verbatim | money.README#why-no-floats |

The file header is the doc unit, not JSDoc. Measured across this repo, As of 2026-08: 99.8% of source files carry a 1–4 line header (2,510 of 2,514), while only 42.3% of public exports have JSDoc directly above the declaration (1,868 of 4,414) — job() itself has none. Ranking a question against 42% coverage would have missed the framework's most-used export.

Same split as AGENTS.md above: this module derives facts and quotes human prose. It never writes, and it never synthesises a sentence.

Errors

| Code | Meaning | Fix | |---|---|---| | X_MANIFEST_DRIFT | committed file no longer matches the code, or was hand-edited so its buildId no longer hashes its own body | x manifest | | X_MANIFEST_BREAKING | contract broke with no major bump | bump the version, or restore | | X_AGENTS_MD_MISSING | no AGENTS.md | write one by hand | | X_AGENTS_MD_TOO_LARGE | over the byte budget | move facts to x.manifest.json |