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

@blazediff/agent

v0.8.0

Published

Agentic visual regression for BlazeDiff. Auto-discovers routes, captures deterministic screenshots, runs CI checks.

Downloads

299

Readme

@blazediff/agent

npm bundle size NPM Downloads

Visual regression testing your coding agent can judge. Discovers routes, screenshots them with Playwright, diffs against committed baselines, and hands ambiguous diffs to Claude Code, Codex, or Cursor as compact region tiles, not full PNGs. Deterministic CLI, no embedded LLM, no API key.

Features:

  • Deterministic CLI. No embedded LLM, no API key required
  • Source-walking route discovery for Next.js / Vite / Remix (BFS fallback)
  • Heuristic verdict: regression-likely | intentional-likely | noise-likely | ambiguous
  • LangGraph pipeline with per-entry subgraphs, suspendable via interrupt() and resumable from an on-disk checkpoint
  • Region-tile handoff to host agents (10 to 100x smaller than full PNGs)
  • Auto-masking via data-blazediff-agent-mask attribute
  • Auth-protected route capture via a codegen-recorded login harness; credentials live in env vars, never in LLM context

Installation

npm install --save-dev @blazediff/agent

Quickstart

blazediff-agent onboard                    # interactive: config + chromium + playbook + baselines
blazediff-agent check --judge host         # CI: re-capture, diff, judge
blazediff-agent rewrite home               # accept an intentional change

onboard writes .blazediff/config.json, installs bundled Chromium, installs the playbook for your coding agent, and offers to capture baselines on the spot. The second command (check, or capture if you declined the baseline offer) starts capturing. Commit .blazediff/ (config + manifest + baselines). All commands accept --json; under --json/CI, onboard runs non-interactively (no prompts, no capture) — a scriptable config + chromium step.

Commands

Pass --cwd <abs-path> to target a sub-package in a monorepo.

Onboard options

onboard auto-detects your coding agent; override or scope the playbook with --stack:

blazediff-agent onboard --stack codex      # explicit
blazediff-agent onboard --stack all        # claude + codex + cursor
blazediff-agent onboard --stack local      # local judge, no host agent (Moondream + Qwen)
blazediff-agent onboard --no-browsers --no-capture   # config + playbook only

Other flags: --url <baseUrl> (external/running server), --dev-command <cmd> / --port <n> / --dev-script <name> (override detection), --yes (accept prompts), --force (rewrite config + playbook).

For coding-agent stacks, writes the playbook and sets config.judge: "host":

  • Claude Code → <project>/.claude/skills/blazediff/SKILL.md
  • Codex → ~/.codex/skills/blazediff/SKILL.md
  • Cursor → <project>/.cursor/rules/blazediff.mdc

--stack local writes no skill file. It sets config.judge: "local" so check judges diffs locally in two steps: Moondream 2 describes the change, then Qwen3.5-0.8B classifies it using that description plus the deterministic interpret summary (both via the optional peer dependency @huggingface/transformers; install it with npm i @huggingface/transformers). Each model loads once on the first judgment and is reused for the rest of the run. local cannot be combined with the coding-agent stacks.

Masking

Mark non-deterministic content (carousels, clocks, randomized avatars) in source:

<div data-blazediff-agent-mask>...</div>
<div data-blazediff-agent-mask="report-carousel">...</div>

For third-party embeds you can't annotate, use a per-entry manifest.entries[].mask CSS selector and re-capture.

Judging

Every non-match routes through the configured judge. With --judge host the judge node interrupt()s the LangGraph pipeline, writes a JudgmentRequest (region tiles + locator thumbnail) to .blazediff/judgments/<id>/, and the suspended graph is checkpointed to .blazediff/checkpoints/. The host agent reads the tiles, writes verdict.json, and check --apply-judgments resumes the same graph with the verdicts. No re-capture, no re-diff.

Configuration

.blazediff/config.json:

{
  "devServer": { "command": "pnpm dev", "port": 3000, "readyTimeoutMs": 60000 },
  "framework": "next",
  "packageManager": "pnpm",
  "baseUrl": "http://127.0.0.1:3000"
}

.blazediff/manifest.json is written by capture; don't edit it directly.

Harnesses

A harness is a pluggable script in .blazediff/harnesses/<name>.js, attached to an entry via harnesses: [{ name, params? }]. A setup harness runs before navigation (e.g. login); an interact harness (the default) runs after the base screenshot and may drive the page and emit extra named screenshots — each becomes its own baseline entry (<id>__<name>). Harnesses default-export a Harness and are ESM .js/.mjs (TypeScript is not auto-transpiled):

/** @type {import("@blazediff/agent").Harness} */
export default {
  async run({ page, screenshot }) {
    await page.getByRole("button", { name: "More options" }).click();
    await screenshot("menu"); // -> baseline "<entry>__menu"
  },
};

Auth-protected routes

Login is just a phase:"setup" harness. For a simple form login, the agent writes .blazediff/harnesses/auth.js directly — a goto(/login) → fill from process.env.BLAZEDIFF_AUTH_<PERSONA>_EMAIL / ..._PASSWORD → submit → assert it left /login. No credentials ever live in the file, only env refs. For flows it can't author (OAuth/SSO, MFA, captcha), blazediff-agent harness record auth --login records the login interactively via Playwright codegen and rewrites the typed creds to env refs.

Attach it with "harnesses": [{ "name": "auth", "params": { "persona": "default" } }], then put BLAZEDIFF_AUTH_<PERSONA>_EMAIL / ..._PASSWORD in an env file the CLI auto-loads from the target dir — .blazediff/.env[.local] (blazediff-scoped, auto-gitignored) or the project-root .env[.local] — or export them. Real env wins; .blazediff/ files beat the root. check does the rest. Full walkthrough: Auth-protected routes.

CI

Only check is allowed under CI=1. Exit codes:

  • 0: all passed
  • 1: regression, intentional, or pending judgment
  • non-zero with structured error JSON on infra failures

Links