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

@app-studio/qa-doctor

v0.6.0

Published

Proves a repository's qa.bindings.json describes the repository it is in — as a CLI report and as a vitest suite CI cannot skip.

Readme

@app-studio/qa-doctor

Proves that a repository's qa.bindings.json describes the repository it is actually in.

Why this exists

A mature QA setup was copied from one repository into another without its bindings being rewritten. In the new repository the guard hook's patterns matched no file, so it denied nothing while looking exactly like a guard with nothing to complain about. The documented ports were wrong, so every instruction built on them sent people to a door that was not there. The seeded accounts did not exist, so agents signing in with them reported an authentication bug. And the documentation that was accurate was referenced by no entrypoint, so nobody read it.

None of that failed loudly. All of it was greppable. This package is that observation turned into a check.

Two ways to run it, one implementation

On demand:

pnpm exec qa doctor            # human report
pnpm exec qa doctor --json     # for agents and CI
pnpm exec qa doctor --strict   # warnings become errors

Inside the repository's own suite, which is what makes it un-skippable:

// tests/qa-doctor.test.ts
import { doctorSuite } from '@app-studio/qa-doctor/vitest';

doctorSuite();

One it() per rule. qa doctor catches a wrong binding when somebody runs it; this catches it on every CI run, in the suite that already gates merges — so skipping the check means skipping the suite, which is a decision somebody has to make out loud. A self/* rule verifies this file exists and falls inside the globs the test command selects, because a test nothing runs is worse than no test: the repository looks checked.

What it checks

| Group | Proves | | --- | --- | | bindings/repo-name-matches | repo.name equals package.json's name — the copied-file detector, run before anything else can be misled. | | commands/scripts-resolve | Every declared command names a real script or an installed binary, and the files it reads exist. | | commands/layers-reference-commands | Layers point at commands the registry defines, and layer keys are unique. | | commands/gates-reference-commands | The gate matrix asks for evidence this repository can produce. | | commands/one-package-manager | Nothing tells anyone to run npm in a pnpm repository. | | commands/smoke (CLI only) | The cheap commands — typecheck, lint, format check — actually run. | | paths/exist | Every declared path is there, unless listed under deliberatelyAbsent. | | paths/guard-globs-live | Every non-empty guard pattern matches at least one real file. The inert-guard detector. | | paths/generated-exist | The trees declared generated are really there. | | ports/bound-by-agrees | Each port is the number the file that binds it actually uses, and no two surfaces claim one port. | | env/required-declared | Required variables are written down where a newcomer will find them. | | env/secrets-not-committed | No committed file carries a real value for a variable marked secret. | | seed/accounts-in-source | Every promised account appears in the seed sources. | | hooks/registered | Each enabled hook is wired under the right event, with a matcher that covers what it must. | | hooks/wrappers-resolve | The wrappers exist, are executable, and point at logic that is installed. | | hooks/deny-protects-generated | Generated trees cannot be hand-edited. | | self/doctor-test-wired, self/hooks-test-wired | The checking runs inside this repository's suite. | | docs/entrypoints-point-at-qa | The files an agent reads on arriving say how QA works here. |

Rule ids are stable: the CLI groups by them, tests assert on them, and hosts grep for them.

The report

Each finding carries three things, not one:

✖ ports/bound-by-agrees — each declared port is the number the file that binds it actually uses
   ports.front says 5173, but playwright.config.ts never mentions that number.
   in: playwright.config.ts
   what this means: Every instruction built on this port sends people to a door
     that is not there, and the resulting connection refused reads as a broken
     application rather than a wrong binding.
   fix: Open playwright.config.ts, read the port it binds, and put that number
     in ports.front.

A doctor that prints rule names and exit codes gets ignored within a week, and an ignored doctor is indistinguishable from no doctor at all.

Writing your own rules

import { runRules, createDoctorContext } from '@app-studio/qa-doctor';
import type { Rule } from '@app-studio/qa-core';

const noOrphanedFeatures: Rule = {
  id: 'features/registered',
  describes: 'every feature directory is in the composed registry',
  appliesTo: (context) => context.exists('src/features'),
  check(context) {
    const declared = context.read('src/generated/registry.ts') ?? '';
    return context
      .glob('src/features/*/manifest.json')
      .filter((path) => !declared.includes(path.split('/')[2]!))
      .map((path) => ({
        level: 'error' as const,
        rule: 'features/registered',
        message: `${path} is not in the composed registry.`,
        means: 'The feature exists on disk and is not part of the application, which is invisible until someone looks for it.',
        fix: 'Run the composer, or delete the directory.',
      }));
  },
};

Rules are pure functions of a DoctorContext, so they test against fixture repositories rather than against your real one — which matters more than usual here, because a doctor nobody has watched go red is exactly the inert machinery this package exists to prevent.

Requirements

Node.js 20 or newer. vitest is an optional peer, needed only for the /vitest entry point.