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

cursordoctrine

v1.2.1

Published

Cursor hooks: doctrine at session start, intent-precompile (.scope.json), scope refresh/drain, permission gate, final review at stop.

Readme


What this is

Six Cursor hooks across six events. No state machine the agent has to maintain; the only on-disk state is a one-shot brake and a scope stash under ~/.cursor/.hooks-pending/. The single repo file is .scope.json, written for you so you don't have to.

  1. Seed the contract at beforeSubmitPromptintent-precompile writes your prompt into .scope.json's prompt the moment you hit send. On continuation it preserves agent-owned intent, files[], and acceptance. Prefix /new or new task: resets for a fresh task.
  2. Inject the doctrine at sessionStart — every chat starts with the same short governing text (doctrine.md): smallest correct diff, YAGNI ultra, ask-don't-guess, conventional commits, the auditor mindset. ~80 lines, read once.
  3. Track the blast radius at afterFileEdit (^Write$) + postToolUsescope-refresh records each edited file into files[] and stashes a one-line reminder; scope-drain delivers it as additional_context on the next tool boundary (Cursor doesn't consume afterFileEdit stdout, so the stash-and-drain pair carries it). Keeps the contract visible as a turn fills with code.
  4. Gate blast radius at beforeShellExecution — one permission gate denies a short explicit list of dangerous commands (rm -rf /, curl | sh, force-push, npm publish, ...). The script fails open on internal errors; failClosed: false so a pwsh cold-start abort does not block all shell use. Everything else passes.
  5. One final review at stop — when an implementation finishes and git sees changed files, Cursor auto-submits one FINAL REVIEW follow-up. Six axes: intent trace (tie every diff hunk to the original request — anything untraceable is a hallucinated requirement), correctness, reliability, coverage, anti-slop, wiring completeness. The hook reads git diff --name-only HEAD + untracked files; the only state is a per-conversation one-shot brake.

The model is the auditor. A self-review done by the model in its own context is free — it has the file, the diff, the user's intent, and the ability to fix. The harness's only non-advisory lever is the permission gate's hard deny.

Prerequisites

PowerShell 7 (pwsh) is required on Windows. The hooks run via pwsh.exe -NoProfile -File .... Windows PowerShell 5.1 (powershell.exe) is not supported — install PowerShell 7 separately.

| Platform | Required | Optional (recommended) | |---|---|---| | Windows | git, PowerShell 7 (pwsh) on PATH | Python 3.9+ (powers the sweep scanner) | | Linux / SSH remotes | bash, git, and jq or python3 | Python 3.9+ (sweep scanner) |

Install PowerShell 7:

  • Windows: winget install --id Microsoft.PowerShell --source winget (or grab the MSI from the PowerShell GitHub releases). Confirm with pwsh -Version.
  • Linux: follow the official package instructions — only needed if you run the windows/ pack on a Linux box (unusual); normal Linux installs use the linux/ bash pack.

Install

Node 18+:

npx cursordoctrine@latest install   # copies the hook pack into ~/.agents/hooks + ~/.cursor, merges hooks.json
npx cursordoctrine verify           # smoke-tests every hook with fake payloads, no restart needed
npx cursordoctrine sweep            # whole-codebase anti-slop audit + fix-handoff (on demand)

Restart Cursor after install — hooks.json is read at startup. install is idempotent; re-run to update. Entries you added to ~/.cursor/hooks.json yourself are kept. npx cursordoctrine uninstall removes the pack the same way. Re-running install after upgrading to 1.0 also reaps the old hooks (intent-precompile, intent-anchor, self-review-trigger, etc.) from your existing hooks.json automatically.

No Node? Open INSTALL.md, paste it into a Cursor agent chat on the target machine, and let the agent copy files and run the checklist.

The anti-slop skill (skills/anti-slop/SKILL.md and the duplication scanner) installs to ~/.cursor/skills/anti-slop/. The hook checklist (~/.agents/hooks/anti-slop.md, 40 items) is the canonical slop detector the final-review follow-up points the model at. The session final-review tells the model to apply it to the session diff; cursordoctrine sweep is the separate on-demand pass for accumulated slop across the whole repo.

Session review vs. sweep — two jobs, two scopes

  • Session final-review (stop): scans only the files git sees as changed this session. Fixes are limited to lines the agent added. Pre-existing slop is out of scope (axis 0 intent-trace; touching it is scope creep, and 100+ files won't fit in one bounded pass).
  • npx cursordoctrine sweep: whole-repo cleanup. Runs the scanner in --all mode across every tracked file, prints a category-by-category breakdown, and hands off to the agent under a cleanup doctrine that authorizes fixing pre-existing slop, category by category, with a re-scan after each. Use it when you want a codebase cleanup, not on every session.

The flows

| Flow | Event | What happens | |---|---|---| | Prompt | beforeSubmitPrompt | intent-precompile writes prompt (verbatim). Preserves intent + files[] + acceptance on continuation. /new or new task: resets for a new task. Skips hook-generated auto-submits. Never blocks. | | Session | sessionStart | inject-doctrine reads doctrine.md and emits it as additional_context. | | Edit | afterFileEdit (^Write$) | scope-refresh records the edited file into files[] and stashes a one-line scope reminder. | | Tool | postToolUse | scope-drain delivers the stashed reminder as additional_context (one-shot), then deletes it. | | Shell | beforeShellExecution | permission-gate checks the command against a deny list. Allow by default, deny by list, fail open (failClosed: false — an internal error or pwsh abort does not block shell). | | Stop | stop | final-review reads git diff --name-only HEAD + untracked files, pulls intent from .scope.json (with prompt as source), and emits one FINAL REVIEW follow-up if anything changed. Bounded by a per-cid one-shot brake (reviewed-<cid>.flag) and loop_limit: 2. |

Layout

windows/          PowerShell 7 hooks (pwsh) — install on Windows machines
  hooks.json      6-event hook wiring for ~/.cursor/hooks.json
  inject-doctrine.ps1, doctrine.md
  hooks/          intent-precompile.ps1, scope-refresh.ps1, scope-drain.ps1,
                  permission-gate.ps1, final-review.ps1, hook-common.ps1 (shared)
                  + 3 prompt files: anti-slop.md, final-review.md, cleanup-doctrine.md
linux/            bash hooks — install on Linux machines and SSH remotes
  hooks.json, inject-doctrine.sh, doctrine.md
  hooks/          same hooks, ported to bash (jq preferred, python3 fallback)
skills/           Cursor agent skills shipped with the package
  anti-slop/      SKILL.md + the duplication scanner (`cursordoctrine sweep` runs it)
                  scripts/scan_slop.py, low_density.py
bin/              the npm CLI (npx cursordoctrine install / verify / sweep / uninstall)
INSTALL.md        ready-to-paste prompt that tells a Cursor agent to
                  install the right folder and verify every hook

Both folders do the same thing. Windows runs everything through pwsh.exe (PowerShell 7 — Windows PowerShell 5.1 is not supported). Linux runs bash, which is what you want on a remote over SSH (check your ~/.ssh/config host — hooks live on the remote's $HOME, not your laptop).

Tuning and kill switches

All hooks fail open and always exit 0. Nothing here can block your session.

| Variable | Default | Effect | |---|---|---| | HOOKS_ENFORCE=0 | on | turns off all hooks at once | | PERM_GATE_ENFORCE=0 | on | disables the permission gate | | INTENT_PRECOMPILE_ENFORCE=0 | on | disables the .scope.json auto-write on prompt | | SCOPE_REFRESH_ENFORCE=0 | on | disables per-edit files[] recording + re-injection (scope-refresh + scope-drain) | | FINAL_REVIEW_ENFORCE=0 | on | disables the final review pass |

Design notes

  • State lives under $HOME, in ~/.cursor/.hooks-pending/, keyed by conversation id: reviewed-<cid>.flag (the one-shot brake for final-review) and a transient scope-<cid>.txt stash (written by scope-refresh, deleted by scope-drain on the next tool boundary). Stale state older than 7 days gets swept on every stop. The only repo file is .scope.json.
  • Change detection is stateless. final-review asks git what changed — no marker file the agent maintains. It reads .scope.json for intent trace (intent primary, prompt as source) and diffs declared vs touched files; intent-precompile + scope-refresh keep the contract current without hand maintenance.
  • One review per implementation. The stop hook arms a per-conversation flag before emitting its follow-up, so a crash can't re-fire it and a long chat still gets a review after each implementation.
  • The doctrine is short on purpose. 80 lines the agent reads at sessionStart and internalizes. .scope.json is re-injected per edit (the contract, not the doctrine) so the blast radius stays visible — but the governing text itself is read once; re-injecting it 50 times doesn't fix a model that didn't internalize it.

Self-contained. No build. Open hooks.json and read it — that's the whole system in one file.

Built with Cursor.

License

MIT. See LICENSE.