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

lazyperm

v1.0.4

Published

PreToolUse hook for Claude Code that auto-allows read-only shell commands

Readme

claude-permission-guard

A PreToolUse hook for Claude Code that auto-allows read-only shell/PowerShell commands so you stop getting prompted for things like Get-ChildItem, git status, or ls, while still asking you about anything that writes, deletes, or changes system state.

How it decides (defense in depth)

  1. Hard deny patterns (deny_patterns.json) — checked first, anywhere in the command, including inside a pipeline. If matched, the hook stays silent and you get the normal prompt. Nothing overrides this.
  2. Cache (cache.json) — if this exact command string was classified before, reuse that decision instantly.
  3. Safe patterns (safe_patterns.json) — if every piece of a pipe/chain (|, ;, &&, ||) matches a known read-only verb, allow.
  4. LLM fallback — if ANTHROPIC_API_KEY is set and nothing above matched, ask a small model ("is this read-only?"). The result is cached so you're never billed twice for the same command.
  5. Default — stay silent, the normal ask-prompt takes over.

The hook never actively denies. It only ever short-circuits to "allow" or does nothing. Worst case if something's misconfigured: you get prompted like normal, you're never blocked from approving manually.

Install

  1. Copy this folder's guard.py, safe_patterns.json, deny_patterns.json into .claude/hooks/ in your project (or ~/.claude/hooks/ for a global install across all projects).
  2. Merge settings-snippet.json into your .claude/settings.json (project) or ~/.claude/settings.json (global).
  3. Restart Claude Code. Run /hooks to confirm it's registered.

cache.json and decisions.log are created automatically next to guard.py the first time it runs — don't commit them if this lives in a shared project repo (add both to .gitignore).

Enable the LLM fallback (optional)

export ANTHROPIC_API_KEY=sk-ant-...

Without this set, the hook still works — it just won't auto-classify commands it doesn't recognize; they'll prompt as normal. This is the safer default for a first install: run rule-based-only for a few days, check decisions.log for what's still asking, and promote the genuinely safe ones into safe_patterns.json yourself before turning the LLM on.

Customizing the lists

Both pattern files are plain JSON arrays of regexes, matched against the start of each subcommand for safe_patterns.json (so ^Get-ChildItem\b matches Get-ChildItem -Recurse), and anywhere in the full command for deny_patterns.json (so it catches a destructive call buried mid-pipeline or a hidden output redirect).

Add your own as you go — e.g. if you keep hitting prompts for docker ps or kubectl get pods, add "^docker ps\\b" / "^kubectl get\\b" to safe_patterns.json.

Reviewing what it's doing

tail -f .claude/hooks/decisions.log

Every decision — allowed, asked, or hard-denied — is logged with a timestamp and the full command, so you can audit it or spot a pattern that's too broad.

Tuning the safety margin

If you find the deny list too aggressive (e.g. you genuinely want git push auto-approved on a specific branch), remove that line from deny_patterns.json — but the default ships conservative on purpose: process/service control, file deletion, output redirection, history rewrites, and non-GET HTTP calls all force a real prompt by default.