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

@wednesday-sol/keel

v0.18.0

Published

A quality gate + AI engineering toolkit you drop into any repo: skills hold your AI's code to production standards; the gate enforces them on every commit — blocking untested code, leaked secrets, stale docs, sloppy commits — scoped to your diff, with `ke

Readme

keel ⚓

An AI engineering harness for the whole software lifecycle. keel runs your AI through every stage — spec → plan → build → verify → review → ship → release — and enforces the standard at each step, so what your AI ships is production-grade, not just plausible.

npm node license

Jump to: See it work · The three moves · What each phase does · What makes it work · Adopt it · The gate · Install


See it work — one feature, start to finish

You want a search box that filters your list as you type. Here's the whole thing — idea to a merged release — and the only two moments that need you are the first and the last.

1 · Describe it — /keel:spec

You hand keel a problem. It interviews you until the intent is sharp, then commits a spec on its own.

you  ▸  /keel:spec "add a search box to filter my task list"

keel ▸  A few questions to sharpen it:
          • match the title only, or notes too?
          • case-sensitive?
          • what shows when nothing matches?

you  ▸  title + notes · case-insensitive · show "No tasks match"

keel ▸  ✓ committed  docs/specs/SPEC_07_task_search.md
          (Goal · Tasks · Done — each Done line becomes a test)

        next ▸  /keel:plan docs/specs/SPEC_07_task_search.md

2 · Plan it — /keel:plan <spec path>

You pass the spec path back. keel slices the work into small, shippable steps and writes them into the spec, so the plan survives the session.

you  ▸  /keel:plan docs/specs/SPEC_07_task_search.md

keel ▸  3 slices, smallest-shippable first:

          P1 ·  filterTasks() — pure, case-insensitive match on title + notes
          P2 ·  the search box, wired to the list
          P3 ·  the "No tasks match" empty state

        ✓ written into the spec's  ## Plan  section

        next ▸  /keel:run docs/specs/SPEC_07_task_search.md

3 · Build it — /keel:run <spec path>

You pass the spec path one last time. Now keel is the autopilot: it takes each slice through the full lifecycle — Build → Verify → Review → Ship — and stops only at an open, green, review-resolved PR. Read each slice top to bottom; every phase is its own step:

you ▸  /keel:run docs/specs/SPEC_07_task_search.md auto


━━━━━  slice P1 · filterTasks()  ━━━━━━━━━━━━━━━━━━━━━━━━━━

  BUILD    Writes the failing test first (red), from the Done line:

               it("matches case-insensitively, title + notes", () => {
                 expect(filterTasks(tasks, "MILK"))
                   .toEqual([{ title: "Buy milk" }])
               })

           …then the smallest code to make it pass — pure, no I/O.

  VERIFY   Tests green · keel eval green · coverage 100%.
           Runs it for real, leaves an end-to-end test behind.

  REVIEW   Adversarial read: "what about an empty query?"
           Adds that case as a test — clean.

  SHIP     Opens PR #41, watches CI  ·········  🟢

  GEMINI   Review bot: "trim the query before matching?"
           keel checks it → valid → fixes test-first,
           replies on the thread, re-runs CI  ·········  🟢

  ✓  P1 done — PR #41 open, green, review resolved


━━━━━  slice P2 · search box  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  …same loop (build → verify → review → ship)  →  PR #42  🟢


━━━━━  slice P3 · empty state  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  …same loop  →  PR #43  🟢


3 PRs, open and green.  Review and merge when you're ready.

4 · Merge — that part's yours

You review each PR and click merge. On merge, keel releases automatically: reads the Conventional Commits, bumps the version, rolls the CHANGELOG, publishes, and tags.

The only two decisions that were yours: what to build (the spec interview) and whether to merge. keel drove everything in between — and never merged on its own.


The three moves

For almost any change it's three commands; everything in the example above happens between them:

  1. /keel:spec "<what you want>" — keel interviews you, commits the spec.
  2. /keel:plan <spec path> — keel slices it into the spec's ## Plan; you sign off.
  3. /keel:run <spec path> — keel drives each slice Build → Verify → Review → Ship to a green PR. step pauses after each slice so you can eyeball it; auto runs them all on its own.

Then you review and merge. Verify and Review run on every slice — never skipped.

Who decides what: you own is this the right thing to build? and is it good enough to merge? keel drives everything mechanical — the failing test, the gate, CI, the review bots, the release — to green on its own. You're never re-running CI or chasing a bot's comment.


What each phase does

/keel:run runs these for you per slice — but each is also a command you can drive by hand. The full depth (the questions each phase asks, worked inputs) lives in docs/LIFECYCLE.md.

| Phase | Command | What happens | The gate enforces | | --- | --- | --- | --- | | Define | /keel:spec | interview a fuzzy idea into a committed spec — Goal · Tasks · Done | spec-gate · spec-quality | | Plan | /keel:plan <spec> | slice the spec into its ## Plan, dependency-ordered; you sign off | PR-size budget | | Build | /keel:build | the next slice, test-first, to the code-craft bar | TDD · size · lint · types · duplication | | Verify | /keel:verify | tests + coverage green, then exercise it live and leave an e2e | patch coverage · e2e | | Review | /keel:review | adversarial pass — correctness, security, performance, doc honesty | a red gate is an auto-BLOCK | | Ship | /keel:ship | commit, open the PR, watch CI to green, resolve review feedback | commit-msg · pr-description · changeset | | Release | automatic | on merge: SemVer bump · CHANGELOG · publish · tag | — |

Two helpers tie it together: /keel:run <spec> is the driver that walks the ## Plan and runs Build → Ship for each slice (so you don't call them one at a time); /keel:address-review is the loop Ship uses to triage and answer reviewer comments until none remain. Neither ever merges — that stays your call.


What makes it work

keel isn't a pile of scripts you invoke by hand — it understands the request and the repo:

  • 🧠 It drives the lifecycle. Phase commands walk the AI through each stage, loading the right skill so it knows how to do that step — not just that it should.
  • 🦷 It enforces the bar. The same rules run as a deterministic gate (keel eval) on every commit and in CI — "≤300 lines," "patch coverage ≥ the bar," "no secret in the diff," "a spec behind this code" actually bite. Verify and Review are mandatory, never skipped.
  • 🎯 It's smart about where you are. A free-form prompt ("add a search box") is classified into the right phase, keel states its read back to you ("this looks like Define — no spec yet"), and 1–3 questions sharpen it before any code. You describe the work; you don't memorize commands.
  • ♻️ It closes its own loops. Ship watches CI to green; address-review answers reviewer feedback to resolved; on merge, release runs itself. It never hands you a half-done state.
  • 📏 It only judges the lines you changed. Every check is diff-scoped — a 4,000-line legacy file never blocks you; the function you touch today is held to the bar.

Under the hood, every discipline is a skill file with the same anatomy — Process · Rationalizations · Red flags · Verification — so the AI follows the exact pattern and the anti-rationalizations stop it from talking itself out of the rule. Thresholds, logic dirs, base branches, and stack profile all live in keel.config.json; skills and checks read config, never hardcode.


Adopt it

keel meets you wherever you are.

Starting a new project

  1. keel init to adopt, then describe what you're building — keel routes you to Define and interviews you into a first spec.
  2. Work the lifecycle from a clean slate: every subsystem gets a spec, every slice is test-first, the gate is green from commit one.
  3. You end up with a spec-driven codebase, living docs, and a tamper-proof CI gate built in from the start — no retrofit later.

Best for: greenfield work where you want discipline baked in, not bolted on.

Adopting into an existing repo

  1. pnpm add -D @wednesday-sol/keel && pnpm exec keel init — copies the skills/commands into .claude/, writes keel.config.json, provisions ESLint, installs the PR template. It never clobbers your config and is safe to re-run.
  2. Run keel eval — it judges only the lines you change. Your 4,000-line legacy file isn't blocked; the function you touch today is held to the bar.
  3. Turn on the opt-in gates (spec-gate, spec-quality, changelog) when your team is ready — they're off by default, so adoption is gradual.

Best for: raising the floor on an existing codebase without a big-bang cleanup. You raise the floor on new code and grandfather the old.

Refactoring an existing repo, top to bottom

When you've decided to bring the whole legacy up to standard — not grandfather it — run a refactor campaign: /keel:refactor. It reconciles a full cleanup with the diff-scoped gate by doing it as a planned sequence of small, behavior-preserving slices — so the floor rises file by file and you never get a big-bang rewrite or a 4,000-issue dump.

  1. Baselinekeel eval / keel report to record where you're starting from (and confirm the suite is green).
  2. Spec the target — a Define pass for the refactor itself: the standard every module must reach, the behavior that must be preserved, and what's out of scope.
  3. Characterize first — pin current behavior with tests before you touch untested code. The net before the cut.
  4. Prioritize — rank modules by risk × churn × blast-radius; find the shallow ones with the deletion test (would removing it concentrate complexity, or just move it?).
  5. Refactor slice by slice — each module runs the normal lifecycle (Build → Verify → Review → Ship). One intent per PR: refactor or feature, never both. keel eval holds each diff to the full bar.
  6. Ratchet up — as a subsystem reaches standard, tighten its thresholds and turn on the opt-in gates so it can't regress. The grandfathered set shrinks to zero by intent, never by lowering the bar.

Backed by the refactor skill (characterization-first, deepen-don't-reshuffle, seam-first), which leans on code-craft, testing, and deprecation-migration.

Best for: an inherited or legacy repo you've committed to modernizing — a deliberate campaign, not a weekend rewrite.


The gate — keel eval

One command, before every push and in CI. Every check is diff-scoped — new/changed lines held to the full bar; untouched legacy shown, never blocking.

| Check | What it enforces | | --- | --- | | pr-size | substantive changed files under budget — reviewable PRs | | file size | changed files within limits.fileLines (300) / componentLines (150) | | naming | no lazily-named files (numbered duplicates, copy/backup/final) | | TDD | every new logic file ships with a matching test | | lint | ESLint errors block; warnings on added lines block; legacy grandfathered | | duplication | copy-paste under threshold (jscpd) | | type check | tsc --noEmit clean | | patch coverage | coverage of the lines this diff added ≥ coverage.min | | doc-sync | every backticked repo path in markdown actually exists | | jsdoc | each documented function has a description, @function, @param | | spec-sync | changing a subsystem touches its spec (configurable) | | plan-sync | changing a subsystem moves its spec's ## Plan — a slice ticked off (off by default) | | spec-gate | substantive code ships with a spec behind it (off by default) | | spec-quality | a changed spec is clearly written — Goal · Tasks · Done (off by default) | | changelog | a changed spec ships with a dated .changelog/ ledger entry (off by default) | | e2e | a feature change ships with an end-to-end test (configurable) | | secret-scan | no probable secret introduced on added lines | | changeset | a published-package change adds a changeset | | commit-msg | commit headers in base..HEAD are Conventional Commits | | pr-description | required PR-template sections present (on a PR run) | | boundary-guard | no edits to configured read-only/protected paths |

keel fix auto-clears the mechanical ones (eslint --fix over just your diff — formatting, quotes, import order) without touching legacy; anything needing judgment stays reported, never silently rewritten.

Tamper-proof in CI — reference keel's reusable workflow by a pinned version, so a repo can't quietly weaken its own checks:

# .github/workflows/keel.yml
jobs:
  gate:
    uses: wednesday-solutions/keel/.github/workflows/[email protected]
    with:
      version: "0.8.0"

Only Node ≥ 20 and git are required. Every other tool is optional and degrades gracefully — a missing tool skips with a reason, never a silent install. Pure Node, so it works on Windows and offline.


Install

keel has two halves — use either or both.

The gate (any repo, any editor):

pnpm add -D @wednesday-sol/keel
pnpm exec keel init    # copies skills/commands → .claude/, writes keel.config.json
pnpm exec keel eval    # check your current changes

The skills + commands (inside Claude Code):

/plugin marketplace add wednesday-solutions/keel
/plugin install keel@keel

You now have the /keel:* phase commands, the skills, and the reviewer subagents.


Reference

CLIkeel <command>:

| Command | What it does | | --- | --- | | keel init / --update | adopt keel / refresh an adopted copy (never touches your config or skills/local/) | | keel eval [base] | the full diff-scoped gate | | keel fix [base] | apply safe auto-fixes (eslint --fix) to the diff | | keel report [base] | run eval + write a CI job-summary table | | keel <check> | run any single check (keel lint, keel coverage, keel spec-gate, …) | | keel version | next SemVer from Conventional Commits (--write bumps files) | | keel hooks install | git pre-commit / commit-msg / pre-push hooks (no husky) | | keel codeowners · keel eslint-config | generate .github/CODEOWNERS / the provisioned ESLint config (complexity rules + the Airbnb style guide at warn, eslint.airbnb default on) from config |

  • Skills & subagents — each skill follows the same anatomy (Process · Rationalizations · Red flags · Verification). Crown jewels: spec-driven, living-docs, changesets, code-craft, ship-check, testing. Add your own under skills/local/keel init --update never touches it.
  • The document system — templates in docs-system/ for the source-of-truth chain (BRD → PRD → TRD → SPEC → ADR → architecture); per-spec change history accrues in .changelog/.
  • Configuration — every knob lives in keel.config.json, resolved as defaults ∪ stack-profile overlay ∪ your override. Full shape: config/keel.schema.json.

Credits

keel synthesizes ideas from wednesday-harness (the enforcement spine), addyosmani/agent-skills (lifecycle + anti-rationalization anatomy), mattpocock/skills (composable meta-skills), and gstack (the CI-watch loop).

License

MIT © Wednesday Solutions