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

@yupanzi/specguard

v0.2.0

Published

Spec-guarded AI workflow CLI; runtime backend for the specguard Claude Code plugin. Never imports any AI SDK.

Downloads

233

Readme

specguard

Spec-guarded AI workflow, distributed as a Claude Code Plugin. Four-phase loop: spec-ask → plan-tasks → check-guard → sync-notebook. The plugin welds the state machine into Claude Code's runtime via hooks.

Collaboration philosophy, hard rules, pitfalls, and scope boundaries live in CLAUDE.md. This file only covers usage.

Status

v0.2.0 — wipe-and-rebuild release. Four phases collapse to four skills (no separate bootstrap); plan.yaml v0.1.0 is split into spec.yaml + plan.yaml + tasks.yaml; pipeline.yaml is gone (no retry mechanism); directory is flat (no v1/v2/, no logs/r<n>/). Per-task prompts now persist at tasks/<id>/prompt.md. See CHANGELOG.md for the full BREAKING list.

Prerequisites

  • Node.js ≥ 22

Install

# 1. Install the plugin in Claude Code
/plugin marketplace add yupanzi/specguard
/plugin install specguard

# 2. Install the specguard CLI globally (one of:)
npm install -g @yupanzi/specguard
# pnpm add -g @yupanzi/specguard
# yarn global add @yupanzi/specguard   # yarn classic (1.x); berry has no global
# bun add -g @yupanzi/specguard

# 3. Initialize in your project (creates the .specguard/ skeleton)
specguard init
# or non-interactively: specguard init --enforcement warn

# 4. Seed the project's K/S/C notebook (run inside Claude Code)
/specguard:sg-sync-notebook
# notebook empty → init path: scans the project to seed first-batch K/S/C topics

specguard init creates the .specguard/{changes,notebook}/ skeleton with INDEX.md scaffolding for the K/S/C three libraries + writes config.yaml + maintains .gitignore (idempotent; doesn't create .gitignore when the project lacks one).

/specguard:sg-sync-notebook (in init mode, when notebook is empty) scans the project (README.md / CLAUDE.md / metadata file / source layout) to extract project-specific K/S/C candidates and registers them under each library's INDEX (index-first protocol). The same skill, in sync mode (when notebook is non-empty), distills lessons from approved dateIds into KSC.

Usage

In Claude Code, invoke the plugin's slash commands in order. Each phase writes one or two YAML artifacts:

/specguard:sg-spec-ask       <one-line need>  # Writes spec.yaml; AskUserQuestion to disambiguate + EnterPlanMode to lock requirements
/specguard:sg-plan-tasks                      # Writes plan.yaml + tasks.yaml; subagent isolation runs each task once + writes tasks/<id>/{prompt.md, debug.log} + invokes specguard verify at the end
/specguard:sg-check-guard                     # Writes check.yaml; KSC three-library review + AskUserQuestion explicit [y/N] approve
/specguard:sg-sync-notebook  [<dateId>]       # Manually triggered; init path (notebook empty) seeds K/S/C from project, sync path (with dateId) distills approved changes

Human-in-the-loop windows:

  1. One-sentence need + AskUserQuestion to disambiguate (/specguard:sg-spec-ask)
  2. EnterPlanMode terminal confirmation (/specguard:sg-spec-ask)
  3. AskUserQuestion to confirm files + approach (/specguard:sg-plan-tasks design sub-phase)
  4. AskUserQuestion explicit [y/N] approve (/specguard:sg-check-guard)
  5. Manually invoke /specguard:sg-sync-notebook + AskUserQuestion review of distillations

Everything else runs autonomously.

Failure handling: if /sg-check-guard returns verdict=re-plan or ksc-reject, the current dateId is sealed (no retry within it). Open a NEW dateId via /sg-spec-ask for the redesign — the old dateId stays as a counter-example archive that /sg-sync-notebook can later cite.

Hook enforcement levels

The plugin ships 3 hooks: yaml-write (PostToolUse auto-validate), session-start (SessionStart injects state-machine position), prompt-submit (UserPromptSubmit detects intent). Each hook's enforcement level is independently configurable.

| Level | Exit code on failure | stderr output | Effect | | -------- | -------------------- | ------------- | ------------------------------------- | | strict | 2 | detailed error | LLM blocked, must fix | | warn | 0 | warning | LLM sees warning, can continue (default) | | off | 0 | silent | fully bypassed |

Granularity: global default + per-hook override.

specguard config get                              # full config
specguard config get enforcement                  # global default
specguard config get hooks.yaml-write             # per hook (incl. effective)
specguard config set enforcement strict           # change global default
specguard config set hooks.yaml-write strict      # per-hook override
specguard config set hooks.prompt-submit off      # disable a hook
specguard config set hooks.yaml-write null        # clear override (back to global)

When init defaults to enforcement=warn, every hook follows. When enforcement=strict, prompt-submit auto-downgrades to warn (keyword matching is prone to false positives — safe default).

Directory layout

.specguard/
  config.yaml                  # created by init; enforcement + hooks overrides
  changes/{YYYYMMDD}-<id>/     # in-progress (id is kebab-case; dateId carries the date prefix) — flat, no version subdirs
    spec.yaml                  # /specguard:sg-spec-ask output (goal + asks + checks with how)
    plan.yaml                  # /specguard:sg-plan-tasks design output (files + approach + tradeoffs)
    tasks.yaml                 # /specguard:sg-plan-tasks execution output (tasks[].{do, verify, status})
    check.yaml                 # specguard verify writes machine layer; /specguard:sg-check-guard adds ksc_check + signed_off
    tasks/<task_id>/           # per-task subagent products
      prompt.md                # original prompt sent to the subagent
      debug.log                # subagent execution output

  notebook/                    # KSC project memory (MUST be committed); INDEX-first three-tier (progressive disclosure)
    INDEX.md                   # Top-level entry; @ links to library INDEXes
    knowledge/
      INDEX.md                 # K library: ## Invariants + ## Abstractions + ## Topics + frontmatter references[]
      <topic>.md               # Dense topic, fetched on demand (ref_id K-NN; pulled when an Invariant / Abstraction matches)
    skill/
      INDEX.md                 # S library: ## Decision Triggers + ## Topics + references[]
      <topic>.md               # Decision templates / reasoning frameworks (ref_id S-NN)
    check/
      INDEX.md                 # C library: ## Cmd Matrix + ## Llm Checks + ## Manual Checklists + ## Topics + references[]
      <topic>.md               # Correctness criteria (ref_id C-NN)

Progressive disclosure

The notebook is intentionally split into sparse INDEX files (always read by /specguard:sg-spec-ask) plus dense topic files (fetched only when an INDEX entry matches the current change's surface). Cross-domain invariants and decision triggers live in the library INDEX directly — they apply project-wide and shouldn't sit behind a topic gate. Topic-shaped distillations sit in <library>/<topic>.md and are linked from the INDEX's ## Topics + references array.

specguard validate --notebook-only checks notebook integrity independently — surfaces orphan topics, dead references, ref_id axis mismatches, and duplicates. validate <dateId> deliberately does NOT run notebook checks (kept off the yaml-write hook hot path); notebook integrity is exercised by /sg-sync-notebook on demand.

CLI

specguard init [--enforcement <level>] [--force]   # Skeleton + config.yaml + .gitignore maintenance
specguard config get [query]                       # Read config
specguard config set <query> <value>               # Write config (auto ajv-validated)
specguard validate <dateId>                        # Validate spec + plan + tasks + check schema + cross-file id integrity + ref integrity + orphan task dirs
specguard verify <dateId>                          # Run program-form checks (spec.checks[].how.cmd), write check.yaml + verdict
specguard verify <dateId> --verdict-only           # Don't re-run checks; only recompute verdict from existing check_results
specguard hook on-yaml-write                       # PostToolUse handler (called by the plugin)
specguard hook on-session-start                    # SessionStart handler (called by the plugin)
specguard hook on-prompt-submit                    # UserPromptSubmit handler (called by the plugin)

dateId format: {YYYYMMDD}-<kebab-id>, e.g. 20260504-add-auth.

The hook subcommand is the entry point for the plugin's hook scripts; users normally don't invoke it directly.

The 3 forms of check.how

how is a one-of YAML object (exactly 1 property), declared in spec.yaml.checks[].how:

| Form | Type | Note | | ----------------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | { cmd: [<program>, <arg>, ...] } | program | YAML array spawned directly (no shell); e.g. { cmd: [npx, vitest, run, tests/x.test.ts] } / { cmd: [pytest, -q, tests/test_x.py] } / { cmd: [cargo, test, --test, foo] } / { cmd: [go, test, ./pkg] } | | { llm: <prompt> } | reasoning | A /specguard:sg-check-guard LLM strictly answers yes/no | | { manual: <note> } | fallback | Only when neither of the above applies |

Priority: cmd > llm > manual.

cmd is a YAML array spawned directly — no shell interpretation, no string split, no quote-hell, no platform difference. For complex shell expressions (pipe / chain / awk / jq), write a script file inside the project and invoke it via { cmd: [bash, scripts/check-foo.sh] }. See the /specguard:sg-spec-ask skill for details.

The 4 verdict values

  • done — every check passed, can be approved
  • awaiting-llm — cmd checks passed but llm / manual still pending; resolve them in /sg-check-guard, then specguard verify <dateId> --verdict-only recomputes verdict
  • re-plan — at least one check failed; user opens a NEW dateId (no retry within current dateId)
  • ksc-reject — machine layer passed but KSC review failed (violates K/S/C baseline); user opens a NEW dateId

Build and verify

npm install
npm run build                # tsc -b packages/cli
npm run lint:no-ai-sdk       # enforce that packages/cli has no AI SDK dependency
npm test                     # unit tests (node:test, zero-dependency; covers parseHow / validate / verify / cross-file integrity / orphan task dirs)

Plugin self-hosting

The specguard repo's root is the plugin root (.claude-plugin/plugin.json lives there). For dev, let the hook reach the local build:

npm install
npm run build
(cd packages/cli && npm link)   # link the local specguard onto PATH
specguard init                  # initialize a skeleton in this repo too

Open Claude Code inside this repo afterward; the plugin auto-loads and you can test it on itself with /specguard:sg-*. Hook calls go through the local build; rerun npm run build after edits to take effect immediately.

License

MIT