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

@valiify/val-core

v0.10.0

Published

Val — the shared agent pipeline for Valiify component libraries: Figma extraction, component mapping, build, QA and visual accuracy. Templates + tools + methodology; each library supplies a val/config.json.

Readme

@valiify/val-core

Val is the agent pipeline the Valiify component libraries use to turn Figma into verified code. This package is the shared part: the agent templates, the orchestrator commands, the measurement tools, and the methodology skills. Each library keeps only what is genuinely its own — a val/config.json and its design-system skill — and generates its agents from here.

                 @valiify/val-core                       library repo
  ┌──────────────────────────────────────┐    ┌──────────────────────────────────┐
  │ templates/agents/*.template.md       │    │ val/config.json  (the 5 deltas)  │
  │ templates/commands/*.template.md     │ ─▶ │ .claude/agents/*.md   GENERATED  │
  │ tools/  grid-diff · screenshot ·     │    │ .claude/commands/*.md GENERATED  │
  │         generate-registry            │    │ val/tools  → symlink into core   │
  │ skills/ extract-methodology ·        │    │ .claude/skills/<library>-ui/     │
  │         visual-verification ·        │    │ val/registry/components.json     │
  │         component-mapping            │    │ val/runs/                        │
  └──────────────────────────────────────┘    └──────────────────────────────────┘
                     npx val-init

What Val does

/val <figma-url> [writeup] — page assembly. Six gated stages, each a subagent with a definition of done the orchestrator verifies:

  1. val-figma — extract the frame: node tree, variables, prototype behaviours, exports, disclosure-state variants
  2. val-components — map every instance to a library component with a confidence rating
  3. val-context — requirements from the writeup, annotations and flows; BLOCKING questions surfaced, never defaulted
  4. val-build — static page from library components + tokens; geometry self-verified; never invents unseen content
  5. val-qa — Playwright over every recorded behaviour + standing checks
  6. val-accuracy — tile diff against the export; every non-pass tile classified; PASS = zero genuine defects

/extract <Component> <figma-node-url> — component extraction. Three parallel lanes (extract-structure, extract-tokens, extract-visual) read the same component set independently; extract-synthesis cross-checks them into an implementation spec. The main session then implements per the library's component process.

Install in a library

npm install --save-dev @valiify/val-core        # or: file:../val-core while unpublished
cp node_modules/@valiify/val-core/val.config.example.json val/config.json
# edit val/config.json — see "Configuration"
npx val-init
git add .claude/ val/config.json val/tools

val-init writes .claude/agents/*.md and .claude/commands/*.md and links val/tools to the package's tools. Commit the generated files — Claude Code reads them from the repo, and a checkout must work without running anything. Each carries a header naming its source; edit the template or the config, never the output.

Keep them honest in CI:

npx val-init --check     # exit 1 if any generated file is stale or hand-edited

If the library previously carried its own val/tools/ directory, remove it (git rm -r val/tools) and re-run val-init so the symlink can be created.

Configuration

val/config.json holds everything that differs between libraries — and nothing else. Schema: schema/val.config.schema.json; worked example: val.config.example.json.

| key | what it drives | | --- | --- | | library.name / displayName / figmaFileKey | run manifests, agent prose, the extract lanes' file key | | paths.designSystemSkill | the library-specific skill the build and synthesis agents read (required; stays in the library repo) | | paths.* (registry, tokens, css, sprite, stories, runs, tools, …) | every repo path the agents reference; defaults match the Valiify layout | | typography.fonts / systemNote / dataRule / casingRule | the one place the libraries' design systems change agent behaviour (Inter-only vs Inter + JetBrains Mono; type-* casing utilities vs typed caps) | | sizing.heightRule | how a Figma control's frame height maps to CSS — a library with height tokens states the token mapping here (e.g. the Short App's 32/40/48/56 → var(--height-*)); the default pins the authored frame height | | audience | the register sentence in requirements §1 | | pipelines.val / pipelines.extract | generate one pipeline or both |

Two libraries, two configs, identical methodology:

// shortapp                                  // dashboard
"typography": {                              "typography": {
  "fonts": ["@fontsource/inter"],              "fonts": ["@fontsource/inter", "@fontsource/jetbrains-mono"],
  "systemNote": "… INTER-ONLY …",              "systemNote": "Inter for UI, JetBrains Mono strictly for verifiable data",
  "dataRule": "tabular-nums (Inter-only …)"    "dataRule": "JetBrains Mono + tabular-nums"
}                                            }

Placeholders

Templates use {{UPPER_SNAKE}} placeholders; val-init fails on any it does not know. Current set: LIBRARY_NAME, LIBRARY_DISPLAY_NAME, FIGMA_FILE_KEY, DESIGN_SYSTEM_SKILL_PATH, REGISTRY_PATH, TOKEN_SOURCE, COMPONENT_CSS, ICON_SPRITE, STORIES_DIR, COMPONENTS_DIR, RUN_OUTPUT_DIR, TOOLS_DIR, FIGMA_TOKENS_JSON, BUILD_THEME_SCRIPT, VISUAL_SPECS_SCRIPT, COMPONENT_PROCESS_DOC, CLAUDE_MD_SECTIONS, CORE_SKILLS_DIR, FONT_PACKAGES, TYPE_SYSTEM_NOTE, DATA_TYPOGRAPHY_RULE, CASING_RULE, HEIGHT_RULE, AUDIENCE_NOTE, QA_PROBES_PATH, GENERATED_HEADER.

Rule for template authors: a line is either generic methodology or a substituted config value. Library-specific prose (a font constraint, a component-family name, a Figma alias) never lives in a template — it goes in the config, the library's design-system skill, or the registry.

Tools

All take a Val run directory and are reached through the val/tools link. Defaults act on the primary frame; --frame <state> selects another entry of the manifest's input.frames[] (its files live under …/frames/<state>/).

  • screenshot.mjs <run-dir> [--frame s] [--state name] [--setup script.mjs] [--scale n] [--out dir] — headless full-page capture at the frame's width and comparison scale; drives states through window.valPage.applyState; records console errors.
  • grid-diff.mjs <run-dir> [--frame s] [--reference png] [--build png] [--out dir] [--scale n] [--baseline report] — 64px-tile pixelmatch against the frame's best reference (the requester's 2x export when recorded, else the MCP export); pad-only normalization; --baseline carries a previous report's per-tile classifications forward and lists what changed. Writes diff-report.json + overlay.png.
  • classify-tiles.mjs <run-dir> [--frame s] [--accepted json] [--crops [all]] — maps non-pass tiles to layout.json regions, groups them into findings with numeric evidence (colour histograms, ink boxes, best horizontal shift) and pre-labels each accepted-candidate / artifact-candidate / needs-review; optional native-scale reference|build crops for the last.
  • geometry-check.mjs <run-dir> [--frame s | --all] [--tolerance px] — the build gate's geometry self-check in one command: renders each frame, asserts page size / no scroll / every layout.json region within ±2px (selectors from 04-build/regions.json or data-val-node), zero console errors. Writes geometry-<state>.{json,md}; exit 1 on any miss.
  • regression-check.mjs <run-dir> --before png --after png [--reference png] [--fixlist json] — byte-diff of two captures clustered into regions; with a fix list, every changed cluster must lie inside a fix region (or a listed sibling) and no fix or sibling region may get worse against the reference — strict by design. Zero model tokens; run before dispatching QA.
  • sprite-subset.mjs <sprite.svg> --used-by index.html [--out file] — emits only the <symbol>s a page references (5 instead of 2,000).
  • qa/harness.mjs + qa/standing.mjs (import, not run) — the Playwright plumbing for 05-qa.spec.mjs: fresh context per test, error collectors, token-resolving style reads, mouse parking, outline-or-shadow focus rings, a Tab-order pass, rendered-ink measurement, the report writer, and the six standing checks (hover, expand/collapse, sticky, resize, keyboard, console) with auto-discovery. Start from qa/example.spec.mjs. Library-specific probe hooks go in the module named by paths.qaProbes (optional).
  • generate-registry.mjs [repo-root] — Storybook stories → component registry; reads paths from val/config.json; hand-added enrichment (behaviors, tokens, Figma ids and names, and variant axes the stories cannot express) survives regeneration.

Tested: npm test (pixel tools with fixtures; geometry-check and the QA harness against headless Chromium — skipped if it is not installed).

Skills

Library-independent methodology, referenced from the generated agents by path (node_modules/@valiify/val-core/skills/…):

  • extract-methodology — which Figma tool answers which question, what each silently gets wrong, the three-lane cross-check, token-extraction lessons, what Figma routinely gets wrong
  • visual-verification — Chrome rendering traps, coverage-based pixel measurement, grid-diff classes, artifact-vs-defect classification
  • component-mapping — registry schema, confidence ladder, aliases, deviations, merge contract

Roadmap

val-core is layer 0. Planned layers build on it without duplicating extraction or verification:

  • val-dev — UI concepting across several libraries plus business/UX context, choosing the right library per requirement
  • val-ops — small tickets and configuration changes end to end
  • val-consumer — customer-facing generation (applicant emails, reports, loan memos)

Versioning

  • major — config schema or agent contract changes (status lines, run-directory layout, manifest shape)
  • minor — new templates, tools, skills, or optional config keys
  • patch — template wording, tool fixes, docs

Run npx val-init after upgrading; --check in CI flags drift. Note that even a docs-only patch changes the version stamped into every generated file's header, so every release forces consumers to regenerate. Changes that do not touch the published tarball (CI, CHANGELOG, this README) are committed, not released.

Releasing

Publishing is local — npm requires interactive 2FA for this account. CI (.github/workflows/ci.yml) verifies; it never publishes.

Step 1 — cut the changelog first. Rename ## [Unreleased] to ## [x.y.z] — YYYY-MM-DD and open a fresh empty ## [Unreleased] above it. Do this before npm version, not after: once the tag exists the release is published against a changelog that still calls the shipped work unreleased, and the next change lands on top of it. This was missed on 0.4.0 — the whole release sat under [Unreleased] with no [0.4.0] heading until the following batch noticed.

Step 2 — verify and publish.

# on a green main with a clean tree, changelog already cut
git commit -am "Changelog x.y.z"
npm test && npm run check && npm pack --dry-run   # what CI runs; no "npm warn" lines
npm version patch|minor|major                     # bumps, commits, tags vx.y.z
npm publish                                       # browser 2FA prompt
git push origin main --follow-tags                # CI re-verifies; tag must match version

A quick way to catch a missed cut: grep -A2 '^## \[Unreleased\]' CHANGELOG.md should show nothing but the next heading, and CHANGELOG.md should contain a ## [x.y.z] line matching package.json's version.

Then finish the release in each consumer library, or its val:check CI gate goes red on the header change:

npm install --save-dev @valiify/[email protected]
npx val-init          # regenerates .claude/agents + .claude/commands
git add .claude/ val/tools package.json package-lock.json

License

MIT © Valiify