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

@intentic/registry-scan

v1.232.0

Published

The nightly scan behind the extension registry, finds topic-tagged repos, refreshes upstream facts, and proposes listings as pull requests

Readme

@intentic/registry-scan

The nightly job behind the extension registry. Published to npm because it runs from a GitHub Actions inside a public repository this monorepo does not contain. The workflows invoke an exact npm version from the REGISTRY_SCAN_VERSION repository variable; a moving package tag is not allowed inside the admission boundary.

The file format it reads and writes lives in @intentic/registry, which the daemon and the site's gallery use too, so all three agree by construction rather than by three copies of a zod schema staying in step.

What it does, and what it refuses to do

Scanning GitHub for a topic is discovery. Merging a pull request is the decision. Keeping those apart is the entire design: a topic is a public namespace anybody can join, so a job that listed what it found would publish the first malicious repository to tag itself: and the alternative, a submission form on the site, is a login, a spam queue and an admin panel standing in for a git commit.

So each run:

  1. Searches topic:intentic-extension.
  2. Refreshes stars and last-push for already-listed entries into registry.generated.json, including the listings the topic search never returned (a listing that arrived by pull request has no obligation to carry the topic, and dropping its stars for that would rank it below newcomers for no reason).
  3. For each unlisted repo, resolves the default branch to a commit first, then reads the manifest and bundle only at that sha. It proposes a complete candidate marketplace.json only when both parse/load there.
  4. Emits warnings for everything it skipped, into the job summary.

It never lists, delists, or changes a trust level. A repository that went briefly private should come back to its listing, not to a deletion.

Those are proposal checks, not admission. The protected extension admission workflow runs on each executable source/review change and accepts one executable subject per pull request. audit refuses unpinned, unsafe-host, or escaping-path targets. A disposable no-secrets job fetches the exact source and runs Trivy's dependency, secret, and misconfiguration scanners. Only then does the intentic agent gate receive an adversarial brief covering browser globals/egress, server/process credentials, agent hooks and MCP, bin shadowing, image/environment fragments, dependencies, binaries and source-versus-dist. It treats repository content as untrusted and forbids executing author code. Either automated check failing, blocking, or remaining unjudged fails admission.

A pass runs attest, which records both run identities against the exact repository, sha and subdirectory. That push changes the PR head, so branch protection evaluates both checks again on the attested commit. Unchanged metadata may reuse evidence for the same immutable subject; a changed repository, sha or path, unblocking, or an edit to the record reruns admission. After a policy or scanner upgrade, untouched stale rows remain disabled by the official registry resolver; touching one schedules just that source, so the catalogue can be refreshed one pull request at a time. The privileged jobs fetch only the candidate marketplace JSON; exact source is checked out solely on the disposable deterministic runner and is never executed.

Identity is also enforced mechanically. The listing key is publisher.name read from the manifest: extensionIdOf: so a repository that copies somebody else's manifest collides with their existing listing and is refused here rather than arriving as a pull request that looks legitimate.

Layout

| Path | What it is | | --- | --- | | src/scan.ts | The decision logic, pure and fully unit-tested against a fake reader. | | src/audit.ts | Diff-to-check policy and source-bound attestation. | | src/github.ts | The four REST reads, behind an interface so the above needs no network. | | src/cli.ts | The IO: read the checkout, write the facts file and the proposal directories. | | seed/ | What the registry repository itself contains: the curated file, the author-facing README, and the workflow that calls this. |

seed/ is a starting point, not a synced copy: push it once to create the registry repository, then it lives its own life over there. The one coupling that matters is the workflow's npx line, which is why this package is published.

Running it against a checkout

GITHUB_TOKEN=… REGISTRY_DIR=/path/to/registry-checkout node dist/cli.js
node dist/cli.js audit --base /path/to/base.json --candidate /path/to/candidate.json
node dist/cli.js attest --base /path/to/base.json --candidate /path/to/candidate.json --run-id GATE_RUN --scan-run-id WORKFLOW_RUN

SCANNED_AT overrides the timestamp so a re-run against a fixed input produces a fixed output. A token is required: the search and contents endpoints are rate-limited to approximately nothing without one.

Key files