Cursor v1.7+ IDE Hook · beforeShellExecution · Free · Open Source

Block bad installs in Cursor
before they touch the filesystem.

Cursor's agent runs npm install, pip install, cargo add, and go get in your terminal — often suggesting packages it has never seen before. Commit's hook intercepts each install command, scores every package against the Commit Index, and denies CRITICAL packages (sole publisher + high downloads — the attack profile of ua-parser-js, event-stream, Shai-Hulud) before they hit disk.

Works with Cursor v1.7+ · No account required to start · Anonymous tier: 15 audits/day


A CRITICAL package never reaches the package manager.

Cursor's agent decides to install lodash. Before the shell executes, the hook calls Commit, gets a score, and replies deny. Cursor surfaces the reason in the agent's permission dialog — the install never runs.

Cursor agent → Commit hook → permission decision
# Cursor's agent suggests:
$ npm install lodash

# Commit hook intercepts. Cursor shows:

🔴 Commit blocked: lodash flagged CRITICAL

  🔴 lodash (score 84) — CRITICAL: sole npm publisher + >10M/wk

→ https://getcommit.dev/audit?packages=lodash&ecosystem=npm

The same flow runs on pip install, cargo add, and go get. HIGH packages return ask — Cursor prompts you to confirm. Everything else passes through silently.


One command. Edits .cursor/hooks.json in place.

Run the command in your project directory (per-project) or with --global (all your projects). The hook script is written to ~/.commit/cursor-hook.js and registered as a beforeShellExecution entry.

# Per-project (recommended): writes .cursor/hooks.json next to your repo
$ npx proof-of-commitment hook --cursor

# Or apply to every Cursor project on this machine
$ npx proof-of-commitment hook --cursor --global

# Remove later
$ npx proof-of-commitment hook --uninstall

The hook merges into any existing hooks.json — your other beforeShellExecution entries are preserved. No global npm install required.


Anonymous tier: 15/day. Free key: 200/day. Both real.

The hook works without an account — anonymous IP gets 15 audits/day. CI runners and dev containers share egress IPs, so the counter ticks faster than you'd think. A free key lifts you to 200/day. Two ways to get one:

# In the terminal — saves to ~/.commit/config
$ npx proof-of-commitment login

# Or in the browser
https://getcommit.dev/get-started?ref=cursor-hook-429

Get free API key →


Does the hook block legitimate installs?

Only CRITICAL packages are denied — the precise profile that preceded ua-parser-js (Oct 2021), event-stream (2018), and the Shai-Hulud burst (Sep 2025): sole publisher + very high downloads. HIGH triggers Cursor's ask dialog. Everything else passes silently. False positives on healthy popular packages are rare by design — see the writing for the scoring rationale.

What gets sent to Commit?

Only the package names and ecosystem (npm/pypi/cargo/golang) — parsed from the shell command. Not your code, not your environment, not the rest of the command. Source: npm-package/index.js.

Does this work with Claude Code too?

Yes. The same script auto-detects the client — Cursor's beforeShellExecution stdin shape vs Claude Code's PreToolUse shape — and replies in the right format. See Commit for Claude Code for the Claude-specific install command.

What happens if Commit is down?

The hook has a 4-second timeout. On timeout or non-429 errors, it returns allow — the install proceeds. On 429 (rate limit), it surfaces the signup prompt and warns about unscored packages so you can decide explicitly instead of silently allowing.

How do I uninstall?

npx proof-of-commitment hook --uninstall — removes the entry from .cursor/hooks.json and deletes ~/.commit/cursor-hook.js if empty. Your other hooks are untouched.


One command. One hook. Real packages stay. CRITICAL ones don't.

npx proof-of-commitment hook --cursor

Free API key — 200/day, no card →