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

autocatalog-docs-core

v0.12.0

Published

Aggregate repository-owned docs/ roots into one validated, linkable index.

Readme

autocatalog-docs-core

Aggregate repository-owned docs/ roots into one validated, linkable index.

Teams keep authorship in git, beside the code the document describes. Readers get a company index. Nothing has to move into a wiki.

ac docs init-schema  # write contracts/docs-frontmatter.json, then edit it
ac docs check        # validate frontmatter and cross-repo links, for CI
ac docs manifest     # publish contracts/docs-manifest.json

The contract is yours

Consistent frontmatter across every repository is the whole point, so the contract is a committed JSON Schema that the organisation owns, not something this package decides.

ac docs init-schema   # writes the default into contracts/docs-frontmatter.json

Commit that file and edit it in place. Everything reads it from there with no flag — ac docs check, ac docs manifest, and the site build:

| Want | Do | | ------------------------ | ------------------------------------------------------------ | | A field of your own | Add it to properties, and to required if it is mandatory | | Only real team names | Make owner an enum of your teams | | A controlled vocabulary | enum on any field: tiers, lifecycles, classifications | | No stray keys | "additionalProperties": false | | Different rules per repo | Point --schema at a different file |

Editing one file beats layering a default and an override: nobody has to reason about merge order, and the result is plain JSON Schema — which is also what lets a Python repository enforce the same rules with jsonschema, importing nothing from here.

Nothing is required to start: with no contract committed, a built-in default requiring title and owner applies, and ac docs check says which contract it used — whether it passed or failed.

Repositories that keep a copy

A repository running its own CI needs the contract locally, and a committed copy drifts the day the organisation edits the original. Give the canonical contract an $id — the standard JSON Schema keyword for where a schema is published — and every copy can check itself:

ac docs sync-schema           # exits non-zero when the copy has drifted
ac docs sync-schema --write   # take the upstream version

It names what changed, newly-required fields first, because those are what break a build that passed this morning. Keep it out of the pull-request check: ac docs check must work offline on every commit, while this reaches the network, so it belongs in a scheduled job or a pre-release step. A sync that cannot reach the source fails — it has verified nothing, and saying otherwise would make the command worthless.

A field your contract declares also survives into the site's page data, so autocatalog-docs-astro can show it. A field nobody declared is validated by nothing and shown by nothing.

Decisions, runbooks and incidents

A document in docs/adr/, docs/runbooks/ or docs/incidents/ is a kind of document with fields of its own: an ADR needs status and date, an incident needs date, severity and status, and carries rootCause and solution once it is resolved. ac docs check validates the base contract and the kind's schema together and names the kind in each failure. The manifest records each document's kind, status and date.

ac docs init-conventions  # write contracts/autocatalog.conventions.json, then edit it

The conventions file adds kinds, changes a built-in kind's folder, label, columns or schema, or turns one off with false. It is found like the contract: at the root, or the one an enrolled repository publishes.

import { docKind, resolveDocKinds } from 'autocatalog-docs-core';

const { kinds } = resolveDocKinds(root);
docKind(doc, kinds); // { kind: { id: 'adr', ... } } for docs/adr/0001-kafka.md

What else it enforces

  • No relative links into sibling repositories. ](../../other-repo/...) resolves only for someone with every repo checked out side by side, and is a dead link in a standalone clone. Declare related: [other-repo/doc] instead. Fenced code blocks are exempt, so a document can teach the rule by showing the wrong form.
  • Declared links resolve. Documents in this checkout resolve against the filesystem; cross-repo targets resolve against the published index. Before an index exists they go unchecked, because failing there would stop the first publisher ever linking out.
  • Renames do not silently break readers. The index records linkedFrom, so deleting a document that others point at fails the pull request that did it.

Freshness comes from git

updated is the last commit touching the file. It is never a frontmatter field: a hand-written date rots the moment someone edits and forgets, and a stale date on a runbook is worse than none because it reads as a promise. When git cannot answer — no repository, uncommitted file, shallow clone — it is null and renders as unknown rather than invented.

Both shapes, no configuration

The same call works for a company index aggregating many sibling repositories and for one repository checking its own docs/ in its own CI. It detects which by looking for <root>/docs; --repo names the single-repo case explicitly.

Reading surface

This package is framework-free on purpose: the checker has to run in a repository's CI with no Astro installed. To publish the documents as a site, add autocatalog-docs-astro — a Starlight plugin that points Starlight's own pages, navigation and search at every enrolled repository, and adds raw markdown twins and llms.txt.

API

import { readDocs, buildDocsManifest, checkDocs } from 'autocatalog-docs-core';

const result = checkDocs(root); // { failures, docs, repos, ... }
const manifest = buildDocsManifest(root); // refuses to publish if any doc is invalid