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

hyperfixer

v0.1.13

Published

Layered verification pipeline for AI-agent-written code: cost-ordered gates, fail-fast, machine-readable verdicts for self-correction loops. Runs on Node, Bun and Deno.

Downloads

1,185

Readme

hyperfixer

npm CI docs license

📦 npm package · 📖 Documentation · 🤖 llms.txt · llms-full.txt

Layered verification pipeline for AI-agent-written code.

hyperfixer runs your project's quality gates in cost order, cheapest first, fail-fast, and produces a machine-readable verdict that any coding agent can consume to fix its own mistakes. Humans get a colored summary; agents get verdict.json and a one-line hint pointing at the first actionable problem.

✓ lint (64ms)
✓ typecheck (462ms)
✓ typetest (20ms)
✓ unit (22ms)
✓ pbt (34ms)

OK, all gates passed in 601ms

The agent contract

Task runners that order and cache commands already exist. What hyperfixer adds is a contract a coding agent can rely on, and this is the part to build your loop around:

  • Strict exit codes: 0 verified, 1 your code is wrong (read the hint), 2 the setup is wrong (config error, empty pipeline, lock held), 3 gate infrastructure failed (timeout, tool crash), do not edit code for a 3. A broken config or a hung tool can never masquerade as a test failure.
  • Structured verdict on disk: per-gate status, structured findings with file and line, timings, outputTail, generatedAt.
  • One-line hint: the first blocking problem, pre-formatted as [gate] file:line, message, the exact string to feed back to the agent.
  • Staleness guard by content: the verdict stores a fingerprint of every gate's inputs; hint recomputes it and warns only when the code actually changed, no clock guessing.
  • No false greens: an empty pipeline (over-filtered --max-cost, all gates disabled) is exit 2, never a green; a config path passed with --config that does not exist is exit 2 instead of a silent fallback to the built-in gates; a malformed gate field is exit 2 instead of a silently skipped gate; a gate whose inputs match no file is never cached (a constant hash could never invalidate), and doctor flags any pattern that resolves to nothing, because a gate whose inputs only partly resolve caches on a key blind to the rest; a filtered run records filteredGates so a partial green cannot pass for a full one; failures are never cached; and property tests print fast-check replay data (seed, path, counterexample) into the verdict so the agent can re-run the exact failing case.

Why layers

Agent-written code fails in layers, and each layer needs a different detector:

| Layer | Catches | Tool | |---|---|---| | Lint | Style drift, suspicious patterns | Biome | | Typecheck | Type errors | tsc --noEmit (strict) | | Type tests | Wrong public API types | expect-type + @ts-expect-error | | Unit tests | Broken behavior | bun test | | Property-based | Edge cases nobody thought to write | fast-check | | Differential/parity | Two implementations disagreeing | project-defined oracle | | Mutation | Tests that pass but assert nothing | Stryker |

Running everything on every change is wasteful; running only unit tests misses whole failure classes. hyperfixer orders gates by cost, stops at the first failure, and tells the agent exactly where to look, so the feedback loop is fast and honest.

Fast in practice: gates with equal cost run in parallel, and gates that declare inputs are cached by input hash, an unchanged project re-verifies in milliseconds:

✓ lint (0ms), cache hit
✓ typecheck (0ms), cache hit
✓ e2e (0ms), cache hit

OK, all gates passed in 2ms

Requirements

Runs on every major JavaScript runtime:

  • Node.js >= 20 (npm i -D hyperfixer, npx hyperfixer)
  • Bun >= 1.1 (bun add -d hyperfixer, bunx hyperfixer)
  • Deno >= 2 (deno run -A npm:hyperfixer)

Zero runtime dependencies, TypeScript types included.

Quick start

npm i -D hyperfixer            # or: bun add -d hyperfixer, deno add npm:hyperfixer
npx hyperfixer init            # detects your stack, writes hyperfixer.config.json
npx hyperfixer doctor          # verify toolchain
npx hyperfixer run             # run the pipeline
npx hyperfixer install-hooks   # enforce on git commit and push

init inspects the project (Biome or ESLint, tsconfig, Bun or vitest or npm test, test directories) and generates a tailored gate list instead of a generic default.

CLI

hyperfixer run [flags]      run gates in cost order, write verdict
hyperfixer fix [flags]      run every gate's fixCommand, then verify
hyperfixer init             detect the stack, write hyperfixer.config.json
hyperfixer hint             print first actionable fix from last verdict
hyperfixer doctor           check toolchain and config health
hyperfixer install-hooks    install git pre-commit and pre-push hooks
hyperfixer install-claude   install Claude Code PreToolUse hook
hyperfixer claude-hook      internal, PreToolUse entry point (stdin JSON)

Run flags:
  --json                machine-readable verdict on stdout
  --quiet               no human output (verdict.json still written)
  --config <path>       config file (default hyperfixer.config.json)
  --only <a,b>          run only the named gates
  --max-cost <n>        run only gates with cost <= n
  --changed             expand {changed} in commands to git-changed files
  --no-cache            ignore and do not update the input-hash cache
  --no-fail-fast        run all gates even after a failure
  --out-dir <dir>       verdict output directory (default .hyperfixer)

Exit codes: 0 every gate that ran passed, 1 a gate failed (fix code), 2 setup problem (config error, missing --config file, empty pipeline, lock held), 3 gate infrastructure failed (timeout, tool crash, do not edit code). The contract is strict: agents branch on the exit code alone. --only and --max-cost make a run a subset, so a 0 from a filtered run only covers the gates it ran; the verdict names the rest in filteredGates and hint repeats them.

Configuration

hyperfixer.config.json:

{
  "failFast": true,
  "outDir": ".hyperfixer",
  "gates": [
    { "name": "lint",      "cost": 5,   "command": ["bunx", "@biomejs/biome", "check", "."] },
    { "name": "typecheck", "cost": 10,  "command": ["bunx", "tsc", "--noEmit", "--pretty", "false"], "parser": "tsc" },
    { "name": "unit",      "cost": 30,  "command": ["bun", "test"], "parser": "bun-test" },
    { "name": "pbt",       "cost": 40,  "command": ["bun", "test", "test/property"], "parser": "bun-test" },
    { "name": "mutation",  "cost": 100, "command": ["bunx", "@stryker-mutator/core", "run", "--incremental"], "enabled": false, "optional": true }
  ]
}

| Field | Meaning | |---|---| | cost | Relative cost; gates run in ascending order, --max-cost filters on it | | command | Argv array; omit to skip the gate | | parser | tsc, bun-test, fast-check, eslint-json, findings-json, or raw, extracts structured findings from output | | optional | Skip (instead of error) when the command cannot start | | enabled | false removes the gate from the pipeline | | timeoutMs | Kill the gate after this many ms (default 600000) | | inputs | Glob patterns this gate depends on; declaring them enables input-hash caching | | fixCommand | Autofix argv run by hyperfixer fix before re-verifying (biome --write, eslint --fix) |

Gate names must be unique; duplicates are rejected at load time. A hanging gate cannot wedge an unattended agent loop: it is killed at timeoutMs (SIGTERM, then SIGKILL) and reported as error. Gates with equal cost run concurrently as a group; fail-fast blocks later groups only.

Caching: a gate that declares inputs stores its passing result keyed by a hash of command + file contents. Touching a file or a checkout that rewrites identical bytes never invalidates; a real content change always does. Failures are never cached; --no-cache bypasses it.

inputs must cover everything the command reads. The key is built from the files the patterns resolve to, so anything outside them, a source directory you forgot, a dependency, a config the tool loads itself, is a change the cache cannot see. hyperfixer doctor reports patterns that match nothing, and a gate whose patterns all match nothing is never cached at all.

Changed-only mode: put {changed} in a gate command and run with --changed; the token expands to the files git reports as modified, and the gate is skipped entirely when the tree is clean.

Works with any agent

hyperfixer is agent-agnostic by construction: the interface is a CLI with strict exit codes, a JSON verdict on disk, and git hooks. Claude Code, Codex, Cursor, Kimi, Grok, or a plain shell script all consume it the same way.

The universal loop (put this in your agent's instructions file, AGENTS.md or CLAUDE.md):

hyperfixer fix --quiet || hyperfixer hint
# => [typecheck] src/service.ts:42, Type 'string' is not assignable to type 'number'. (+3 more)
# fix, then re-run until exit 0

Hard enforcement, works for every agent and every human:

hyperfixer install-hooks
# pre-commit: gates with cost <= 50 (fast)
# pre-push:   full pipeline

The hooks are plain sh, refuse to overwrite hooks they did not write, and print the hint on failure so the blocked agent knows what to fix.

Claude Code, one command:

hyperfixer install-claude

This writes (or merges into) .claude/settings.json a PreToolUse hook that intercepts every git commit and git push the agent attempts, runs the pipeline, and on failure blocks the call with the hint fed back to the agent, which fixes and retries. Non-git commands are never touched.

GitHub Actions, three lines in anyone's CI:

- uses: actions/checkout@v4
- uses: egeominotti/hyperfixer@main
  with:
    max-cost: "50"   # optional, config: and working-directory: also available

The verdict

hint prints the first actionable problem with file and line; the full structured verdict is in .hyperfixer/verdict.json:

{
  "ok": false,
  "generatedAt": "2026-07-24T10:30:00.000Z",
  "inputsFingerprint": "sha256…",              // content-based staleness guard
  "failedGate": "typecheck",
  "filteredGates": ["mutation"],               // held back by --only or --max-cost
  "hint": "[typecheck] src/service.ts:42, Type 'string' is not assignable…",
  "durationMs": 533,
  "gates": [
    {
      "gate": "typecheck",
      "status": "fail",            // pass | fail | skip | error
      "durationMs": 458,
      "exitCode": 2,
      "findings": [
        { "file": "src/service.ts", "line": 42, "column": 5, "code": "TS2322", "message": "…" }
      ],
      "findingsTotal": 4300,                   // only when findings were capped
      "outputTail": "…",
      "note": "3300 more findings not recorded" // why it was skipped, errored, capped or cached
    }
  ]
}

findings is capped at 1000 per gate so the file stays readable; when a tool reports more, findingsTotal and note carry the real count, and both hint and the human report quote it. cached: true marks a result served from the input-hash cache.

filteredGates is present only when gates were held back, by --only, --max-cost, or --changed when nothing a gate watches changed. A green verdict that carries it covers the gates that ran, nothing more, and hint says so.

hint warns on stderr when the verdict is older than 10 minutes, so an agent that edited code without re-running cannot trust a stale "OK".

Programmatic API

import { loadConfig, runPipeline } from "hyperfixer";

const verdict = await runPipeline(await loadConfig());
if (!verdict.ok) console.error(verdict.hint);

Development

bun install
bun run check        # hyperfixer verifying itself (lint, typecheck, typetest, unit, pbt)

The repo dogfoods its own pipeline: property-based tests assert verdict invariants (ok if and only if no failing gate, fail-fast skips everything after the first failure), and type tests pin the public API. CI runs the pipeline on every push; a green build on main bumps the patch version, updates CHANGELOG.md and tags the release automatically.

License

MIT