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

@casomoltd/tooling

v0.28.0

Published

Casomo's shared dev config: ESLint, Prettier, commitlint, knip & jscpd presets and dev CLIs (git hooks, readability, screenshots)

Readme

@casomoltd/tooling

Shared linting, formatting, commit config, and CLI tools for Casomo Ltd's repos.

What's included

Exports

| Export | Description | |---|---| | @casomoltd/tooling/eslint | createBaseConfig() — ESLint flat config with Next.js, TypeScript, and SonarJS | | @casomoltd/tooling/eslint-lib | ESLint config variant for library packages | | @casomoltd/tooling/prettier | Prettier config object | | @casomoltd/tooling/commitlint | commitlint config with no-ai-attribution plugin | | @casomoltd/tooling/knip | Knip config for unused exports/dependencies | | @casomoltd/tooling/jscpd | Copy-paste detection config | | @casomoltd/tooling/readability | scoreText() — readability scoring for page content |

Bin commands

| Command | Description | |---|---| | check-version | Pre-push guard — rejects push if package.json version hasn't changed vs origin/main | | check-linear | Pre-push guard — rejects a push that would put a merge commit on the remote. History is linear; a branch catches up by rebasing. Only what the push adds is judged, so merges already on the remote stay | | pre-push | Husky pre-push hook — runs check, then the version, tag and linear-history guards | | pre-commit | Husky pre-commit hook — runs npm run check | | commit-msg | Husky commit-msg hook — runs commitlint | | readability | Measure reading difficulty of page content | | screenshot | Capture a dev server page via Playwright — an agent's visual feedback loop | | build-report | Compile a Typst client report to PDF with the house template |

Install

Published to the public npm registry. Add it to a consumer's devDependencies:

npm i -D @casomoltd/tooling
"@casomoltd/tooling": "^0.20.0"

The package is public, so installs need no token or .npmrc. The files allowlist plus the verify-pack leak-gate keep the published surface to configs/CLI only.

Installing this package never installs a browser. The screenshot bin needs one and build-report needs the typst CLI, but neither is declared here — see External prerequisites.

External prerequisites

Two bins need something npm cannot sensibly deliver: screenshot needs a Chromium build, build-report needs the typst CLI and the IBM Plex fonts. Neither is declared — not as a dependency, and not as an optional peer. Both load their prerequisite lazily and fail with an install instruction when it is missing, so a consumer that never runs those bins carries nothing for them.

The rule, for anything added later: a heavyweight prerequisite only some consumers need is documented here, never declared. An optional peer looks free because npm installs nothing for it, but it resolves into a consumer's lockfile as soon as anything pulls it in, and npm will not prune a satisfied optional peer afterwards — not on npm install, not on npm install --package-lock-only, not on npm uninstall. That is how one dev-only browser put the extract-zip advisory (GHSA-jmr9-qjv8-65gv) into four repos that never took a screenshot, and why clearing it needed a release of this package rather than a fix in each of them.

Husky hooks

The package provides shared hook commands so all repos enforce the same standards. Wire them up in .husky/:

.husky/pre-commit

pre-commit

.husky/commit-msg

commit-msg $1

.husky/pre-push

pre-push

Each repo defines its own check script in package.json — the hooks call npm run check which runs whatever checks that repo needs (lint, typecheck, spell, etc.).

Note: The tooling repo itself calls scripts by path in its hooks (e.g. ./bin/check-version.sh) because it can't resolve its own bin commands via node_modules/.bin.

Markdown / skills lint

bin/skills-lint.config.mjs is a stock remark config (remark-frontmatter + remark-validate-links + remark-lint-frontmatter-schema) that validates a Claude Code skills/agents/docs tree: every SKILL.md / agents/*.md has parseable YAML frontmatter with name + description, and every relative link and #anchor resolves. tooling runs it over its own skills/ in npm run check (lint:md) — catching the breakage a rename or hand-edit leaves that Claude Code's loader silently swallows.

To gate a consumer repo's docs (link/anchor integrity) at its own pre-commit, install the remark toolchain and point it at the shipped config:

npm i -D remark-cli remark-frontmatter remark-validate-links remark-lint-frontmatter-schema
"lint:md": "remark --frail --quiet --no-stdout --rc-path node_modules/@casomoltd/tooling/bin/skills-lint.config.mjs docs"

Append && npm run lint:md to your check script. The config resolves the plugins from your repo's node_modules and the schema (shipped beside it) relative to your cwd; the frontmatter schema only matches SKILL.md/agents files, so for plain docs it acts as a link/anchor check. Requires a tooling version that ships the config.

Screenshot tool

A visual feedback loop for coding agents. Claude captures the page it just changed, reads the PNG back and checks its own work, instead of waiting for someone to look and paste a screen grab. That is what the bin is for, and why its output lands under .claude/; a person wanting a screenshot already has a browser open.

It needs a Chromium build, which this package does not install (see External prerequisites):

npm i -D playwright && npx playwright install chromium

Then capture the running dev server:

npm run ss              # 1280×800 desktop capture
npm run ss contact      # desktop capture of /contact
npm run ss -- --width 390 --height 844   # mobile capture
npm run ss contact --width 390           # mobile /contact

Options:

| Flag | Default | Description | |------|---------|-------------| | --width <n> | 1280 | Viewport width in pixels | | --height <n> | 800 | Viewport height in pixels |

Add these scripts to your package.json:

{
  "screenshot": "screenshot",
  "ss": "npm run screenshot --"
}

Screenshots are saved to .claude/screenshots/. Set SCREENSHOT_URL to override the default http://localhost:3000.

Client reports (Typst)

report/ ships the Casomo house style for client-facing PDF reports — a Typst template (casomo-template.typ, with the brand mark beside it) plus the build-report bin that compiles a report to PDF:

npx build-report path/to/report.typ                # → scratch (see below)
npx build-report report.typ -o public/report.pdf   # explicit output path
npx build-report report.typ --watch                # recompile on save
npx build-report report.typ --open                 # open the PDF when done

The compiled PDF is a build artefact, so it defaults to the same scratch resolution as the agent reports (see Report output & SCRATCH_DIR under Agents): $SCRATCH_DIR/reports/<name>.pdf, or <repo-root>/scratch/reports/ when SCRATCH_DIR is unset — add scratch/ to the consumer repo's .gitignore (this repo does). Pass --out only when the PDF is a deliverable the repo actually keeps (e.g. a site's public/).

A report imports the template and applies it as a show rule; everything after is the body. From a consumer repo the import goes through node_modules (the bin sets the Typst root to the nearest package.json/.git ancestor so the path resolves):

#import "/node_modules/@casomoltd/tooling/report/casomo-template.typ": casomo-report, band

#show: casomo-report.with(
  kicker: "Delivery Report & Findings",
  title: "The Report Title",
  subtitle: "One-line summary.",  // optional
)

= Executive summary
…

report/example.typ is a lorem-ipsum reference report exercising every feature the template styles — compile it to see the house style.

Two external prerequisites apply here: the typst CLI on PATH (snap install typst / cargo install typst-cli) and the IBM Plex Sans / IBM Plex Mono fonts (github.com/IBM/plex) — build-report fails loud on the former and warns on the latter.

Quality gates

Quality gates run locally via git hooks, so code is deployment-ready by the time it reaches the remote. GitHub Actions re-runs check on push and publishes on a version tag; the local hooks are the gate, CI is the backstop.

  • pre-commit: npm run check — the repo's full health gate.
  • commit-msg: commitlint (house rules + the AI-attribution ban).
  • pre-push: npm run check, then the version and tag guards.

check owns the build. A repo whose build fails is not healthy, and any assertion that reads build output has to run after the build in the same script — so build belongs in check, and appears nowhere else. Declaring it in the pre-push gate as well would give it two owners and build twice.

What every repo's check must contain

check is a hand-written, ordered chain — the repos are heterogeneous and some orderings are load-bearing — but its composition is enforced, not remembered. Run check-gates as its first step:

"check": "check-gates && npm run lint && npm run typecheck && ..."

It fails if a required gate is missing, if one is defined but never run (a dead gate), or if an exception outlives the problem it was written for. Required: lint, typecheck, test, knip, jscpd, lint:md, spell, build.

A repo opts out by declaring a reason — a blank one fails, so an opt-out is never silent, and every exception is printed on each run:

"casomo": {
  "gates": { "test": "content site — no suite yet" }
}

Usage

.prettierrc.js

module.exports = require('@casomoltd/tooling/prettier');

commitlint.config.cjs

module.exports = require('@casomoltd/tooling/commitlint');

eslint.config.mjs

import { createBaseConfig } from '@casomoltd/tooling/eslint';

The ESLint config uses a factory function that receives resolved imports from the consumer to avoid module resolution issues across package boundaries.

Local development

Changes to tooling require a push to main to publish (the workflow runs automatically). Consuming repos then pick up changes with npm update @casomoltd/tooling.

For fast iteration while editing tooling config locally, use npm link to temporarily symlink your local checkout:

# in the consuming repo
npm link ../tooling

This overrides the published version until the next npm install, which restores the registry version.

Claude Code skills (plugin)

This repo is a Claude Code plugin (.claude-plugin/) shipping the generic, public engineering standards we work to across three agent-facing surfaces — skills, hooks, and agents. Business-specific ones live in private workspace config, not here.

The tooling serves three consumers: Claude (the editing workflow) → these plugin surfaces; CI + git-hooks (automation) → the npm bin scripts; manual human CLI is no longer a design target.

Authoring standard: creating or editing a skill/agent follows docs/skill-agent-schema.md — the interface schema (three profiles — procedural skill · agent · standard/rubric — plus a frontmatter decision table) that keeps these units composing without overlap.

| Skill | Description | |---|---| | /casomoltd:commit | Run checks and commit cleanly (no bump, no push) | | /casomoltd:release-version | Bump → push → CI publish/deploy (the release tail) | | /casomoltd:frontend-design | Distinctive, production-grade frontend UI | | /casomoltd:python-style | Python code-generation style rules | | /casomoltd:typescript | TypeScript data modelling and type design | | /casomoltd:screenshot | Capture and analyse a dev server page | | /casomoltd:design-pass | Map → review → refactor a package (drives design-xray + code-review) | | /casomoltd:draft-design-spec | Author a browser-reviewable HTML design spec from a brief and iterate on it before writing code (drives design-xray) | | /casomoltd:page-design | Structure a content/explainer page for trust — above-the-fold answer, disclosure, palette-only colour (rubric a page-design reviewer preloads) | | /casomoltd:generate-report | Scaffold a Typst client report from the house template, compile via build-report, verify the PDF |

Enable the plugin by adding this repo as a marketplace and installing it:

/plugin marketplace add casomoltd/tooling
/plugin install casomoltd@casomo-tooling

Skills then load namespaced as /casomoltd:<name>.

Hooks

The plugin also ships generic PreToolUse hooks (hooks/) that guard command/shell intent no linter or commit hook can see: confirm before git push, hard-block destructive git, npm version major, global installs, and edits that weaken TypeScript strictness. (They deliberately don't duplicate what commitlint/eslint already enforce — see hooks/README.md.) The guards are advisory — they ask you to confirm when they can't read a call's input, and never hard-block on their own malfunction. They require Node ≥ 22.18 / ≥ 24 (they run as TypeScript .mts via native type-stripping — no build step).

See hooks/README.md for the full rule set, the file map, how the hooks relate to settings.json permissions and skill allowed-tools, and the TypeScript / vendored-types design rationale.

Agents

Three namespaced agents (agents/), each read-only on what it inspects and preloading the relevant house standard as its rubric — typescript for .ts/.tsx, python-style for .py, docs-style for markdown. design-xray and docs-xray persist only their own report (see Report output, below).

casomoltd:code-review enforces the judgment-level half of the standards — the design calls a linter can't make (typed identifiers, static/varying separation, swallowed exceptions; class design, polymorphism over type-codes, value objects, EAFP, framework-first, test naming). It complements, never duplicates: eslint/ruff own the mechanical rules, the built-in /code-review owns correctness bugs, this owns the house design standards. Namespaced so it doesn't collide with the bundled /code-review. Invoke with @agent-casomoltd:code-review (or let Claude auto-delegate); it reports findings and never edits.

casomoltd:design-xray takes a package or diff and returns the structural picture: a doc-ready module inventory + mermaid class-hierarchy diagram, a weight table (which modules/classes are too heavy or thin), prioritized design findings, a ranked handoff of refactor targets, and a verdict on whether a heavier pattern (e.g. a state machine) is warranted yet or premature. It feeds forward — its map lifts straight into package docs, and its targets drive code-review and a refactor pass. The /casomoltd:design-pass skill chains the three (x-ray → code-review → refactor), and /casomoltd:draft-design-spec reuses its current-state map as the "before" picture when authoring a pre-implementation design spec. Like its sibling it visualizes and judges structure only — no correctness bugs (that's /code-review), no lint (eslint/ruff).

casomoltd:docs-xray is the same idea for a documentation corpus: it walks every markdown doc (README, CLAUDE.md, docs/, skill/agent definitions) and returns a map — each doc's heading tree + outbound pointers, plus a mermaid reference-graph of how the docs link — and a coherence report: orphan docs nothing links to, stale cross-references whose summary has drifted from the target, duplicated coverage, and missing back-links. It judges structure and cross-reference coherence against docs-style — not mechanical broken links (that's a markdown link linter) or prose voice (a content reviewer).

casomoltd:doc-review reviews one repository doc against docs-style: whether it gets to the point or buries it under furniture, whether it is one subject or three, whether a leaf carries an index belonging in the README, whether a section says "not built yet" where content should be, and whether the session's own progress has leaked in. A doc can be right in every sentence and fail this review, because what it judges is shape. Not link validity (a markdown link linter), not the corpus reference graph (docs-xray), not skills or agent briefs (skill-review).

casomoltd:skill-review reviews changed skills and agent briefs against docs-style and the authoring schema: prose that narrates its own past rather than stating current truth, a unit missing the sections its profile needs, a rule restated from the skill that owns it, and a description that won't route. It closes with an explicit history sweep — the units it read and the count flagged, including zero — because that finding sits where a justification would and otherwise survives an ordinary read-through. The commit skill routes staged SKILL.md and agents/*.md changes to it. Not link validity (a markdown link linter), not the corpus reference graph (docs-xray), not prose voice (a content reviewer).

Report output & SCRATCH_DIR. design-xray and docs-xray persist their report — the .md plus an .html rendered by bin/render-report.mjs — so it outlives the run and opens in a browser. Each writes to a gitignored <repo-root>/scratch/<agent>/ by default. Set the optional SCRATCH_DIR env var to pool every report under one shared location instead ($SCRATCH_DIR/<agent>/) — e.g. a multi-repo workspace collecting reports in one place rather than scattering them per-repo. Publishing a report to a hosted claude.ai artifact is orchestrator- only and on explicit request; the agents never do it.

Package distribution

@casomoltd/tooling, alongside the product libraries (@casomoltd/paye-calc, @casomoltd/nhs-pay), publishes to the public npm registry via OIDC trusted publishing — install with no auth or .npmrc. A version-tag push (npm version patchgit push --follow-tags) triggers publish.yml. That workflow carries no npm pin: it builds on Node 24, whose bundled npm 11.x is already the range we want — at or above the npm >= 11.5.1 trusted publishing needs, and short of npm 12, which still refuses non-registry fetches by default (EALLOWREMOTE) and so cannot regenerate a lockfile that resolves a transitive remote tarball. The other two npm 12.0.0 regressions this once guarded against are fixed: npm ci strictness (12.0.2 installs Linux-generated locks cleanly) and the provenance/sigstore crash (12.0.1). Re-test the fetch block before moving to npm 12.