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

apriori-cli

v4.0.3

Published

Spec-driven development with executable specs — self-contained, zero-dependency CLI

Readme

A Practical Handbook for Spec-Driven Development

What is this & how to use it

apriori is a spec-driven workflow for AI coding, plus a zero-dependency CLI (apriori-cli) that makes your specs executable: every scenario is bound to a test, so "spec'd but never built" is caught by a command, not by eyeballing a diff. You drive an AI agent through a state machine — refine the spec, adversarial review by a different model, implement, archive — stopping at the human gates that matter.

Humans start with the Quickstart below; AI agents read the self-contained RUNBOOK.md instead and never need this handbook. apriori answers in whatever language you write in (pin it with apriori init --language 中文 if you prefer).

Quickstart

Ten minutes, from an empty directory to a spec-bound green. Requires Node ≥ 22 and a POSIX shell.

npm i -g apriori-cli
mkdir hello-apriori && cd hello-apriori
apriori init --tools claude --test-cmd "node --test --test-reporter=tap" --yes
apriori doctor --no-run

init scaffolds apriori/ and a runbook pointer for your AI tool; doctor confirms the seam is healthy (expect DOCTOR: HEALTHY; exit 0).

apriori new hello
cat > apriori/changes/hello/flow-state.md <<'EOF'
change: hello
tier: trivial
track: harden
track-rationale: quickstart demo
lineage: main
current-step: STEP5
round: 0
next-action: verify, then archive
gates:
  - 2026-01-01T00:00 note: quickstart demo
EOF
mkdir -p apriori/changes/hello/specs/hello
cat > apriori/changes/hello/specs/hello/spec.md <<'EOF'
## ADDED Requirements

### Requirement: greeting
The module SHALL greet by name.

#### Scenario: HL-01 greets by name
- WHEN greet('World') is called
- THEN it returns 'Hello, World'
EOF
apriori verify --change hello

Every change carries a tiny state file (flow-state.md — the tier sizes the workflow; an agent normally maintains it for you) and its delta specs. verify --change binds scenarios against the projected store (the store as it will look after this change merges). One scenario, zero tests → RESULT: GAPS, exit 1. Fail-closed is the point. Now make it green:

mkdir -p test
cat > hello.js <<'EOF'
module.exports = { greet: (name) => `Hello, ${name}` };
EOF
cat > test/hello.test.js <<'EOF'
const { test } = require('node:test');
const assert = require('node:assert');
const { greet } = require('../hello');
test('HL-01 greets by name', () => assert.strictEqual(greet('World'), 'Hello, World'));
EOF
apriori verify --change hello

The test name carries the scenario ID — that is the whole binding contract. Expect RESULT: GREEN — spec is the test suite, exit 0.

apriori gate --change hello --json
apriori archive --change hello --write --changes-dir apriori/changes
apriori verify --specs apriori/specs
apriori check

gate aggregates the mechanical checks into one exit code (its PASS never replaces a human gate). archive --change merges the delta into the living store apriori/specs/ and files the change away; plain verify now proves the merged store, and check is your CI guard. That's the loop: spec → red → green → gate → archive.

From here, work WITH an agent instead of by hand: idea still fuzzy → run /apriori with no arguments (brainstorm first, nothing written until you approve); change already clear → "Follow the apriori runbook for change <name>" and answer at each human gate.

Where everything else lives

| doc | what's in it | |---|---| | docs/concepts.md | why it works this way: core concepts, the AI toolbox, the full STEP0–STEP6 workflow, the mini-kv worked example, the prompt library | | docs/legacy.md | existing codebases: the knowledge-base loop, doctor-first onboarding | | docs/ci.md | ready-to-paste CI snippets for check / verify / gate, exit-code table | | docs/cli.md | all ten subcommands: exact synopses, flags, exit codes, configuration reference | | docs/troubleshooting.md | every doctor finding and the classic traps, each with its fix | | RUNBOOK.md | the agent-facing executable protocol (canonical where they disagree) |

Command Cheat Sheet

| apriori command | When | Purpose | |---|---|---| | apriori init | once per project | scaffold apriori/ + per-tool pointers | | apriori doctor | onboarding / anytime | diagnose the project↔apriori seam; findings name their fixer | | apriori new <name> | change kickoff | scaffold apriori/changes/<name>/ + a flow-state skeleton | | apriori status | anytime | where each change is: step, next action, open ledger items (--json) | | apriori verify | STEP5 exit gate | bind every scenario ID to a passing test; --change <name> = the projected, mid-change form | | apriori stamp <store-file> | delta authoring | print the CAS base-stamp line — verify/archive refuse if the store diverged since | | apriori gate --change <name> | STEP5/6, CI | one exit code over the mechanical checks (PASS ≠ human gates) | | apriori archive | STEP6 | merge delta specs into the living store; --change <name> = whole-change, failure-atomic (up to the commit point) | | apriori check | CI / pre-commit | structural consistency (scenario IDs bindable) | | apriori update | after a CLI upgrade | refresh the runbook copy + command pointers (never your files) |

Acknowledgments

The artifact interface this workflow is built on — delta specs (ADDED / MODIFIED / REMOVED), Requirement/Scenario blocks with stable IDs, the archive-merge semantics, and the multi-tool init scaffolding pattern — is directly inspired by OpenSpec, which the V1 and V2 lines used directly. V3 reimplements that interface natively as the zero-dependency apriori CLI rather than depending on it — but the shape of the interface is OpenSpec's, and the debt is gladly acknowledged.