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

spec-lane

v0.5.1

Published

A local-first delivery-lane orchestrator: Intent -> Spec/Critic -> Implement -> Verify -> Done, with cost estimation/calibration, a resource-aware next-task view, a spec-consensus gate, and a knowledge lens for review lessons.

Readme

spec-lane

Package: spec-lane · Command: lane · Repository: shiki-yusuke/spec-lane

A local-first delivery workflow for AI-assisted changes.

It stops a change before it moves forward when critical assumptions, acceptance criteria, or required verification evidence are missing, while keeping consequential decisions explicit for a human reviewer.

Intent -> Spec/Critic -> Implement -> Verify -> Done

This is a from-scratch TypeScript rewrite of a private Python tool the author built and used personally; the source project has no public existence, so this repo stands on its own.

What it stops

| Check | Failure it targets | Where it happens | |---|---|---| | Premise evidence | Implementing against a problem that was never confirmed to actually exist | Before spec.md is written | | Dependency × Path cross-check | A cross-cutting change missing a path, state, or dependency it should have accounted for | Spec / before implementation | | Success criteria matrix | An acceptance criterion with no corresponding evidence in the final diff | Verify / before opening a PR | | Spec consensus | A spec/implementation deviation left unresolved, or a spec/verification edit nobody has acknowledged | Before completion |

Dependency × Path cross-check is not a fully automated CLI gate — it's a skill-driven procedure that requires explicit human approval when it applies. The CLI can check that a record exists and is shaped correctly; it can't check that its content is honest, or that its own choice of axes was complete. See "How the gates work" below.

Install

Requires Node.js >= 22.

npm install -g spec-lane
lane --version

From source (for contributing to lane itself)

Requires pnpm too (corepack enable gets you pnpm on a recent Node without a separate install). This checkout is a pnpm workspace of four @lane/* packages (schemas/core/adapters/cli) that pnpm -r run build compiles independently — the published spec-lane package above is instead a single self-contained bundle produced by node scripts/build-publish.mjs from that same source (see that script's header comment for why); you don't need to know about the bundle step to work on lane day to day.

git clone https://github.com/shiki-yusuke/spec-lane.git
cd spec-lane
pnpm install
pnpm -r run build

Make the lane command available globally from this checkout:

cd packages/cli
npm link
cd ../..
lane --version

(npm link creates a symlink from your global npm bin dir to this checkout's built CLI — uninstall any time with npm unlink -g @lane/cli. If you'd rather not touch your global npm state, invoke it directly instead: node packages/cli/dist/main.js <command>.)

Optional: agent-cost, for cost calibration, lane next, and lane emit-metrics

lane calibrate, the Codex side of lane next, and lane emit-metrics all call out to agent-cost, a separate CLI that reads local Claude Code / Codex CLI logs to measure real token usage and cost. lane estimate itself never calls it — it only ever reads the local calibration population that lane calibrate has already written. Install agent-cost (see that repo's own README) and make sure agent-cost resolves on PATH, or pass --agent-cost-bin <path> to the commands that need it. Without it, everything else in lane still works — you just won't have real usage numbers to calibrate or emit against.

Quick start

Run these from the root of whatever repo you want to manage lanes for (lane looks for docs/spec/ relative to your current directory by default — see "Configuration" below). This is the mechanical skeleton; the full procedure (including exactly what "premise check" and "dependency/path cross-check" require) lives in skills/lane/SKILL.md and skills/lane-finish/SKILL.md — point an AI coding agent at those two files and it can drive the whole flow below directly.

# 1. Start a new lane
lane start I-2026-01-15-my-first-change \
  --business-goal "Reduce onboarding friction in the setup flow." \
  --user-visible-intent "New users see setup steps in the right order." \
  --primary-user "new_user" \
  --risk low

# 2. Before writing spec.md: record premise evidence in intent.yaml (does this change
#    rest on a problem you actually confirmed exists? live observation, existing data, or
#    at minimum a static code trace). lane validate checks the record's shape, not its
#    honesty.
lane validate I-2026-01-15-my-first-change

# 3. Write docs/spec/I-2026-01-15-my-first-change/spec.md (EARS rules + Gherkin
#    scenarios), including a Dependency x Path cross-check section if this change is
#    cross-cutting or touches a shared path -- that section needs explicit human approval
#    before step 6 below, not just existing on disk.

# 4. Write docs/spec/I-2026-01-15-my-first-change/critic.yaml (the 9-lens self-review),
#    then check both artifacts:
lane validate I-2026-01-15-my-first-change
lane advance I-2026-01-15-my-first-change --phase 2_spec

# 5. Implement the change (branch, real code + tests), then:
lane advance I-2026-01-15-my-first-change --phase 3_implement

# 6. Write verification.yaml, including a success_criteria_matrix that cross-checks every
#    line of intent.yaml's own intent.success against the final diff, then resolve
#    spec_consensus:
lane consensus I-2026-01-15-my-first-change --refresh \
  --spec-ssot-ref docs/spec/I-2026-01-15-my-first-change/spec.md
lane consensus I-2026-01-15-my-first-change --ack --reviewer-kind self --reviewer-id you
lane validate I-2026-01-15-my-first-change
lane advance I-2026-01-15-my-first-change --phase 4_verify

# 7. Open a PR. Optionally attach a standardized token-usage snapshot to it:
lane emit-metrics I-2026-01-15-my-first-change --post

# 8. Once the PR is merged:
lane advance I-2026-01-15-my-first-change --phase 5_done \
  --merged-at 2026-01-16T09:00:00Z --pr-url https://github.com/you/your-repo/pull/1

Run lane <command> --help for every flag a command accepts.

Two layers of enforcement

lane validate is the early-feedback path — run it any time, at any phase, to see what's currently missing. It never changes phase and never blocks anything by itself.

lane advance is the final mechanical backstop. Immediately before changing phase state it re-evaluates every gate applicable to that transition; an error-level diagnostic blocks the transition and leaves lane-state.json completely unchanged — there's no partial or "failed attempt" state left behind to clean up.

Both commands read the same gates against the current on-disk artifacts — validate just lets you see a gate's verdict before you actually try to cross it.

How the gates work

Warnings vs. errors. A warning is a visible diagnostic that does not by itself block a transition (the CLI often can't know whether it truly applies to your change). An error blocks the transition. Every diagnostic is tagged with the gate that raised it ([gateId] message), so it's traceable back to source.

Premise evidence — the CLI can check that a required/reproduced/method/ evidence record exists and is shaped correctly, and it hard-blocks a change that explicitly records required: true with reproduced: false. It cannot check whether the recorded evidence is actually true, or whether this specific change genuinely needed the check in the first place. In short: lane requires the premise check to be recorded, and blocks a required premise that was explicitly not reproduced — it does not itself prove the premise is real.

Success criteria matrix — every line of intent.yaml's intent.success gets cross-checked against the final diff and recorded with a covered_by/evidence/ negation_test. Matching against intent.success is normalized, exact-text equality (whitespace/markdown-link/emphasis differences only) — not LLM fuzzy semantic matching. A criterion that's been summarized or paraphrased rather than transcribed verbatim will not be recognized as covering the original line.

Dependency × Path cross-check — for a cross-cutting change, spec.md enumerates the new dependencies/states/guards being introduced and the existing paths that need to respect them, then cross-checks every cell. Any "does not reference" or "unknown" cell must be promoted to a named test. When this section applies (or it's unclear whether it does), it requires explicit human approval before implementation starts — lane validate does not check this section's content at all, only that the artifacts it lives in are schema-valid. The table also has known blind spots by construction: it doesn't look at how the implementation holds its own internal state, at assumptions about external data shape, or at whether the premise/success-criteria checks above were actually done honestly. A completed table is not a claim of completeness.

Spec consensuslane consensus binds a reviewer's acknowledgement to the exact content of spec.md and verification.yaml by content digest. Editing either file after an ack invalidates it automatically, and any unresolved spec/implementation deviation blocks completion until it's recorded and resolved. critic.yaml is not part of that digest — don't generalize this into "editing any artifact invalidates the ack."

Agent-metrics emission

lane emit-metrics <intent-id>          # print a token-usage snapshot marker
lane emit-metrics <intent-id> --post   # upsert it as a PR comment instead

spec-lane is one reference emitter for the external agent-metrics:v1 contract — not a metrics platform. What it owns:

  • the delivery ledger (which sessions did the work, attributed to which lane phase)
  • activity attribution and session deduplication
  • invoking agent-cost to measure real token usage
  • building a conformant agent-metrics:v1 payload
  • optionally publishing/upserting that payload as a PR comment

What it explicitly does not own: the protocol itself, repository-wide harvesting, long-term storage, or team/monthly reporting — those live in separate projects (below).

Session-to-task binding, usage import, and attribution audit (M0 pilot)

# 1. Start a task_run for a phase you're about to work on
lane work start --intent I-2026-01-15-my-first-change --phase 3_implement

# 2a. Spawn a wrapped claude/codex session -- session_id is bound automatically
lane work run --intent I-2026-01-15-my-first-change --phase 3_implement -- claude -p "..."

# 2b. ...or, for a session you started yourself, bind it manually
lane work bind --intent I-2026-01-15-my-first-change --session-id <id> --agent claude

# 3. Measure every session bound to this intent's active task_runs via agent-cost
lane usage-import --intent I-2026-01-15-my-first-change

# 4. Audit the whole trace ledger (global, not per-intent) for clean attribution
lane attribution audit --require-coverage 1.0

These commands build the append-only trace ledger ($LANE_DATA_DIR/trace/events.jsonl) that underlies agent-metrics:v1 emission above: lane work run/lane work bind record session_bound, lane usage-import records usage_imported/attributed_to and upserts a scope:"phase" cost-ledger entry, and lane attribution audit reads the ledger back to certify (or flag) the "1 session binds to exactly 1 task" accounting principle everything downstream depends on. Binding uses wrapper spawning, not a hook: Claude gets a pre-assigned --session-id nonce; Codex's session_id is read from codex exec --json's leading thread.started event, after the process has already started (a measured asymmetry, not an oversight — a hook-based approach was tried and cut for failing silently). A session bound to more than one task is never silently resolved — it's flagged MULTI_TASK_BINDING and excluded from exactly_attributed, never apportioned by a time-ratio guess.

lane evidence export --format lane-evidence:v1 --intent <id> prints a digest bundle of everything a lane has produced so far (intent/spec/verification digests, matrix/ consensus-ack/premise-evidence summaries, done-overlay, cost-ledger totals) — a first-cut shape owned by spec-lane itself for now, not yet a frozen external contract.

trace/v1, attribution/v1, and estimate/v2 (below) are external contracts from ai-agent-skills-playbook that spec-lane mirrors and verifies against that repo's own vendored fixtures — see packages/core/test/fixtures/{trace,attribution,estimate}/UPSTREAM for the exact pinned commit and packages/core/test/{trace,attribution,estimate-v2}-fixtures.test.ts for the conformance tests themselves.

estimate/v2: an honesty layer, not a bigger model

lane estimate still runs the same k-NN/leave-one-out estimator it always has (unchanged by this section). What's new is a second, stricter judgment layered on top: whether that prediction is even trustworthy enough to report at all. A decision_v2 field records either a point estimate (status: "predicted") or an honest refusal (status: "abstained", with a reason like INSUFFICIENT_POPULATION or NOVEL_SURFACE_UNKNOWN) — there is no third "best guess anyway" state.

This requires a profile.estimate.cohort block (agent_type, model_provider, model_generation, model_id, routing_policy_digest, prompt_policy_digest, execution_profile_digest — see profiles/generic.profile.yaml for where it would go). Without it, lane estimate refuses to write anything at all rather than guess. Because no calibration observation recorded before this feature existed carries a cohort tag, estimate/v2 is expected to abstain INSUFFICIENT_POPULATION for a while after upgrading — that's the honesty model working as designed, not a bug: it never treats an untagged historical observation as a silent match. --novel-surface established|novel resolves a NOVEL_SURFACE_UNKNOWN abstain with an explicit human declaration, recorded with provenance on the revision.

The public measurement pipeline

Claude Code / Codex
        │
        ▼
    agent-cost
 local measurement
        │
        ▼
    spec-lane
 lane ledger / attribution
        │
        ▼
 lane emit-metrics
        │
        ▼
 agent-metrics:v1
 hidden PR comment
        │
        ▼
 agent-metrics-harvester
 verify / collect / store
        │
        ▼
 JSONL / SQLite
        │
        ▼
 agent-metrics-report
 cost per merged PR

Protocol

The normative contract lives outside this repo, in ai-agent-skills-playbook (docs/protocols/agent-metrics-v1.md), frozen at tag agent-metrics-v1.0.0. spec-lane implements the reference emitter for that external contract; it doesn't define it. A few of the protocol's own design choices, briefly:

  • a snapshot, never a delta — a re-emit fully replaces the prior one, no merge logic
  • a checksum, not a signature — integrity, not authenticity (transport-level auth is the harvester's job, e.g. a GitHub-authenticated fetch)
  • explicit coverage/omissions fields — a harvester can tell a genuine zero from missing data
  • no personal-identity dimension — the protocol measures work/process telemetry, not individual performance; personal-identity fields (author, reviewer, email, etc.) are forbidden by the protocol itself, not merely hidden at some later dashboard step

Full details live in the protocol doc itself, not duplicated here.

End-to-end validation

The public reference pipeline has been exercised end to end on GitHub: a spec-lane marker was posted to a real PR comment, collected by the reference harvester (agent-metrics-harvester), persisted to its store, and re-fetched through the unchanged/idempotent (HTTP 304) path.

As of this writing, spec-lane's own CI is green, the protocol is frozen at agent-metrics-v1.0.0, this live canary has been exercised successfully, and agent-metrics-harvester's CI (including its Node 22 compatibility suite and the cost-per-PR reporter's own tests) is green — this is a public, end-to-end measurement pipeline in the sense that every stage above has been exercised and its CI passes, not a claim that it has seen production-scale traffic or every possible input shape.

Cost per merged PR

agent-metrics-report's cost-per-pr command reports estimated AI-assisted coding cost per merged PR — not a cost precisely billed to any one PR. The denominator is PRs merged within a period; the numerator is cost snapshots generated within that same period — two independently-counted populations, not a 1:1 join. It deliberately does not round missing or ambiguous data down to a clean $0: unpriced, unknown, partial, and insufficient-sample cases stay visible as such rather than becoming an artificially confident number. See that repo's own docs for the full metric definition and sample-size policy.

Dogfooding

spec-lane has now been used to drive two of its own public changes through the full lane workflow, end to end:

  • MP-3 (the agent-metrics:v1 emitter above) revealed three rough edges in the workflow itself: misleading --paths wording in skills/lane/SKILL.md, an undocumented closed enum for critic.yaml's taxonomy field, and lane validate printing a raw, unformatted schema-error object instead of a readable message.
  • MP-7 turned those three observations into a documentation fix, a CLI diagnostics fix, and dedicated regression tests — closing the loop: dogfood → finding → fix → regression test.

Two runs is two runs — this is evidence of the workflow surviving contact with its own author's real changes, not a claim of being battle-tested or production-hardened.

Using spec-lane with coding agents

If you're driving lane through an AI coding agent rather than by hand, point it at:

  • skills/lane/SKILL.md — Phase 1 (Intent) through Phase 4 (Verify/PR): starting a lane, premise evidence, spec/critic, the dependency/path cross-check, implementation, the success-criteria cross-check, spec consensus, and PR creation.
  • skills/lane-finish/SKILL.md — the post-merge-only Phase 5 closeout: recording the done overlay and closing the estimate/calibrate loop.

Both files describe the same flow as the Quick start above, written for an agent to follow directly rather than for a human to read once.

The four evolved features

On top of the gates above, lane layers four features that go beyond the original private tool it's based on:

  1. Estimate / calibratelane estimate <id> [--impact-scan-file <report.md>] [--adopt] predicts token/cost usage (p50/p80) from a k-NN model over past measured work, always labeled with how much to trust it (experimental below a 30-observation population, reference_table fallback below 8). lane calibrate <id> --session-id <id> measures what a lane's work actually cost (via agent-cost) and, if a baseline was adopted, scores the prediction against reality — feeding the next estimate's population.
  2. lane next — a decision table of every lane with an adopted baseline estimate against your current Claude/Codex resource snapshots (~/.claude/rate-limits.json via your Claude Code statusline, and a manually-configured weekly Codex credit budget). It only ever shows fits/not_fit when the predicted cost and a budget constraint share the exact same unit — no invented USD-to-credits conversion — and suppresses every verdict (showing only raw numbers) when the underlying data is stale or incompletely priced.
  3. Knowledgelane knowledge-append/lane knowledge-query --paths <path> [--paths <path> ...] (repeatable, one value per flag) is a small, deterministic lessons-learned database: append a finding or decision once, and future lanes touching the same paths get it surfaced (score >= 0.70, top 3 overall, max 2 per review lens) as knowledge_candidates your spec/critic review can cite.
  4. Agent-metrics emission — described above.

See docs/design.md for the full design rationale behind each of these, and for spec_consensus's own design notes (the fourth original evolved feature, folded into "How the gates work" above since it's part of the core enforcement story now).

Configuration

| What | Default | Override | |---|---|---| | Where lane specs live | docs/spec/ under your current directory | --spec-dir <path> or $LANE_SPEC_DIR | | Runtime data (knowledge records, calibration observations, done overlays) | $XDG_DATA_HOME/lane (usually ~/.local/share/lane) | $LANE_DATA_DIR | | Config (Codex budget file) | $XDG_CONFIG_HOME/lane (usually ~/.config/lane) | $LANE_CONFIG_DIR | | Profile (risk rules, required commands, distance caps, etc.) | the bundled profiles/generic.profile.yaml | --profile <id-or-path> > $LANE_PROFILE_PATH > a profiles-local/<id>.yaml in your repo |

Codex budget file (for lane next)

If you want lane next to show a Codex credit budget, create $LANE_CONFIG_DIR/budgets/codex.yaml:

weekly_limit_credits: 15000
period_start: "2026-01-12"
period_end: "2026-01-19" # exclusive boundary, must be exactly 7 days after period_start for reset_rule=weekly
reset_rule: "weekly"
timezone: "Asia/Tokyo" # v1 supports Asia/Tokyo and UTC only

Without this file, lane next simply has no Codex row to show — it never fabricates one.

Data directory and privacy

Runtime data ($LANE_DATA_DIR: knowledge records, calibration observations, done overlays) and config ($LANE_CONFIG_DIR) both live outside this repository by design (XDG Base Directory convention) — cloning or publishing this repo never carries your own knowledge base or calibration history along with it. The one-time importer commands (migrate-legacy-ledger, migrate-legacy-knowledge) that backfill a calibration/knowledge population from old data explicitly warn on every run that imported records may retain internal references (PR URLs, ticket-shaped text, etc.) from whatever you imported them from — imported records are tagged provenance: "imported_legacy_ledger" / "imported_legacy_memories", which is the one mechanical key to filter them out if you ever need to share your data directory with someone else.

Development

pnpm -r run typecheck   # all packages
pnpm -r run build       # tsc project references
pnpm run lint           # biome check .
pnpm -r run test        # vitest, all packages
pnpm exec dependency-cruiser --config .dependency-cruiser.cjs packages/schemas/src packages/core/src packages/adapters/src packages/cli/src

Monorepo layout: packages/schemas (zod schemas + generated JSON Schema, no internal deps) -> packages/core (pure application logic + port interfaces) -> packages/adapters (port implementations: GitHub via gh, agent-cost via subprocess) -> packages/cli (commander.js wiring). Dependency direction is enforced by .dependency-cruiser.cjs and checked in CI.

Maintainers publishing a new version: see docs/releasing.md.

A note on packages/core/test/differential

A handful of core functions (ledger derivation, phase transitions, the done overlay, and the Goodhart personal-dimension guard) were ported byte-for-byte from a private Python reference implementation this project is based on, and are checked against it via a differential test suite that calls that Python package as a subprocess. That package isn't published anywhere you can install it from — these tests skip automatically (isPythonReferenceAvailable() in python-harness.ts) when it isn't importable, which is the normal case for anyone outside the original author. Nothing else in this repo depends on it.

License

MIT