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

@hasna/hooks

v0.2.12

Published

Open source hooks library for AI coding agents - Install safety, quality, and automation hooks with a single command

Readme

@hasna/hooks

Open source lifecycle hooks library for AI coding agents. 30 hooks across 10 categories, installable with a single command. Works with Claude Code and Gemini CLI.

Features

  • 30 hooks in 10 categories (git safety, code quality, security, notifications, and more)
  • Interactive CLI (hooks) with React/Ink TUI for browsing, installing, and managing hooks
  • MCP server (13 tools) for agent-driven hook management over stdio or SSE
  • Library for programmatic access from Node.js/Bun
  • Multi-agent support for Claude Code and Gemini CLI with per-agent event mapping
  • Agent profiles with unique 8-char UUID identity system
  • Zero file copy -- hooks run from the globally installed package, nothing is copied to your project
  • Web dashboard for browsing hooks (Vite + React 19 + TailwindCSS 4)
  • Health checks via hooks doctor to verify hook installation integrity
  • Global or project-scoped installation

Installation

bun install -g @hasna/hooks

Or with npm:

npm install -g @hasna/hooks

Or use without installing:

npx @hasna/hooks

Quick Start

# Interactive mode -- browse and select hooks
hooks

# Install specific hooks
hooks install gitguard branchprotect checkpoint

# Install all hooks in a category
hooks install --category "Git Safety"

# Install all 30 hooks
hooks install --all

# List all available hooks
hooks list

# Search by name, description, or tags
hooks search security

# Check health of installed hooks
hooks doctor

# Start MCP server for agent integration
hooks mcp --stdio

Hook Categories

| Category | Count | Description | |----------|------:|-------------| | Git Safety | 3 | Block destructive git ops, protect branches, create snapshots | | Code Quality | 6 | Check tests, lint, bugs, docs, files, and task completion | | Security | 2 | Security audits and typosquatting prevention | | Notifications | 5 | Phone, desktop, Slack, sound, and inter-agent messages | | Context Management | 2 | Re-inject context and save state before compaction | | Workflow Automation | 3 | Auto-format, auto-stage, and TDD enforcement | | Environment | 1 | Detect nvm/virtualenv/asdf/rbenv activation needs | | Permissions | 3 | Auto-approve safe commands, protect files, block prompt injection | | Observability | 4 | Session logs, command logs, cost tracking, error detection | | Agent Teams | 1 | Validate task completion criteria |

Hook Events

| Event | Timing | Can Block | Matcher | |-------|--------|:---------:|---------| | PreToolUse | Before tool execution | Yes | Tool name pattern (e.g., Bash, Write\|Edit) | | PostToolUse | After tool execution | No | Tool name pattern | | Stop | Session ends | No | Empty string | | Notification | System events (e.g., compaction) | No | Empty string |

Each hook receives JSON on stdin and outputs JSON on stdout:

// Input (PreToolUse)
{
  "session_id": "abc123",
  "cwd": "/path/to/project",
  "tool_name": "Bash",
  "tool_input": { "command": "git push --force" }
}

// Output (block)
{ "decision": "block", "reason": "Destructive git operation blocked" }

// Output (approve)
{ "decision": "approve" }

Available Hooks (30)

Git Safety (3)

| Hook | Event | Description | |------|-------|-------------| | gitguard | PreToolUse | Blocks destructive git operations like reset --hard, push --force, clean -f | | branchprotect | PreToolUse | Prevents editing files directly on main/master branch | | checkpoint | PreToolUse | Creates shadow git snapshots before file modifications for easy rollback |

Code Quality (6)

| Hook | Event | Description | |------|-------|-------------| | checktests | PostToolUse | Checks for missing tests after file edits | | checklint | PostToolUse | Runs linting after file edits and creates tasks for errors | | checkfiles | PostToolUse | Runs headless agent to review files and create tasks | | checkbugs | PostToolUse | Checks for bugs via headless agent | | checkdocs | PostToolUse | Checks for missing documentation and creates tasks | | checktasks | PostToolUse | Validates task completion and tracks progress |

Security (2)

| Hook | Event | Description | |------|-------|-------------| | checksecurity | PostToolUse | Runs security checks via headless agents | | packageage | PreToolUse | Checks package age before install to prevent typosquatting |

Notifications (5)

| Hook | Event | Description | |------|-------|-------------| | phonenotify | Stop | Sends push notifications to phone via ntfy.sh | | agentmessages | Stop | Inter-agent messaging integration for service-message | | desktopnotify | Stop | Sends native desktop notifications via osascript (macOS) or notify-send (Linux) | | slacknotify | Stop | Sends Slack webhook notifications when Claude finishes | | soundnotify | Stop | Plays a system sound when Claude finishes (macOS/Linux) |

Context Management (2)

| Hook | Event | Description | |------|-------|-------------| | contextrefresh | Notification | Re-injects important context every N prompts to prevent drift | | precompact | Notification | Saves session state before context compaction |

Workflow Automation (3)

| Hook | Event | Description | |------|-------|-------------| | autoformat | PostToolUse | Runs project formatter (Prettier, Biome, Ruff, Black, gofmt) after file edits | | autostage | PostToolUse | Automatically git-stages files after Claude edits them | | tddguard | PreToolUse | Blocks implementation edits unless corresponding test files exist |

Environment (1)

| Hook | Event | Description | |------|-------|-------------| | envsetup | PreToolUse | Warns when nvm, virtualenv, asdf, or rbenv may need activation before commands |

Permissions (3)

| Hook | Event | Description | |------|-------|-------------| | permissionguard | PreToolUse | Auto-approves safe read-only commands and blocks dangerous operations | | protectfiles | PreToolUse | Blocks access to .env, secrets, SSH keys, and lock files | | promptguard | PreToolUse | Blocks prompt injection attempts and credential access requests |

Observability (4)

| Hook | Event | Description | |------|-------|-------------| | sessionlog | PostToolUse | Logs every tool call to .claude/session-log-<date>.jsonl | | commandlog | PostToolUse | Logs every bash command Claude runs to .claude/commands.log | | costwatch | Stop | Estimates session token usage and warns when budget threshold is exceeded | | errornotify | PostToolUse | Detects tool failures and logs errors to .claude/errors.log |

Agent Teams (1)

| Hook | Event | Description | |------|-------|-------------| | taskgate | PostToolUse | Validates task completion criteria before allowing tasks to be marked done |

CLI Commands

| Command | Alias | Description | |---------|-------|-------------| | hooks | hooks interactive, hooks i | Interactive hook browser (default) | | hooks install <names...> | hooks add | Install one or more hooks | | hooks install --all | | Install all 30 hooks | | hooks install --category <cat> | | Install all hooks in a category | | hooks list | hooks ls | List available hooks | | hooks list --registered | hooks list -r | Show currently registered hooks | | hooks list --category <cat> | hooks list -c <cat> | Filter by category | | hooks search <query> | | Search hooks by name, description, or tags | | hooks info <name> | | Show detailed info about a hook | | hooks remove <name> | hooks rm | Unregister a hook | | hooks update [names...] | | Re-register hooks (picks up new package version) | | hooks doctor | | Check health of installed hooks | | hooks docs [name] | | Show documentation (general or hook-specific) | | hooks categories | | List all categories with counts | | hooks init | | Register a new agent profile | | hooks run <name> | | Execute a hook (called by AI agents) | | hooks mcp | | Start MCP server (SSE or --stdio) | | hooks upgrade | | Self-update to latest version |

Scope Options

Most commands accept scope flags:

| Flag | Description | |------|-------------| | --global, -g | Global scope (~/.claude/settings.json) -- default | | --project, -p | Project scope (.claude/settings.json) | | --json, -j | Machine-readable JSON output | | --profile <id> | Agent profile ID to scope hooks to | | --overwrite, -o | Overwrite existing hook registration |

MCP Server

Start the MCP server for AI agent integration:

# Stdio transport (for agent MCP registration)
hooks mcp --stdio

# SSE transport (default, port 39427)
hooks mcp
hooks mcp --port 8080

Registration

Add to ~/.claude/mcp.json or equivalent agent config:

{
  "mcpServers": {
    "hooks": {
      "command": "hooks",
      "args": ["mcp", "--stdio"]
    }
  }
}

MCP Tools (13)

| Tool | Description | |------|-------------| | hooks_list | List all available hooks, optionally filtered by category | | hooks_search | Search for hooks by name, description, or tags | | hooks_info | Get detailed information about a specific hook including install status | | hooks_install | Install one or more hooks by name | | hooks_install_category | Install all hooks in a category | | hooks_install_all | Install all available hooks | | hooks_remove | Remove (unregister) a hook from agent settings | | hooks_doctor | Check health of installed hooks | | hooks_categories | List all hook categories with counts | | hooks_docs | Get documentation (general overview or hook-specific README) | | hooks_registered | Get list of currently registered hooks for a scope | | hooks_init | Register a new agent profile | | hooks_profiles | List all registered agent profiles |

Agent Profiles

Agents can register a profile to get a unique 8-char UUID. This identity is injected into hook input when running with --profile.

# Register a profile
hooks init --agent claude --name "my-agent"
# Agent profile created
#   Agent ID:   a1b2c3d4
#   Type:       claude

# Install hooks scoped to a profile
hooks install gitguard --profile a1b2c3d4

# The registered settings entry becomes:
#   hooks run gitguard --profile a1b2c3d4

Profiles are stored at ~/.hooks/profiles/<agent_id>.json.

Library Usage

import {
  HOOKS,
  CATEGORIES,
  searchHooks,
  getHook,
  getHooksByCategory,
  installHook,
  installHooks,
  getRegisteredHooks,
  removeHook,
  createProfile,
  listProfiles,
  type HookMeta,
  type Category,
} from "@hasna/hooks";

// Search for hooks
const securityHooks = searchHooks("security");

// Get hooks by category
const gitHooks = getHooksByCategory("Git Safety");

// Install a hook programmatically
const result = installHook("gitguard", { scope: "global" });

// Check what's registered
const registered = getRegisteredHooks("global");

// Create an agent profile
const profile = createProfile({ agent_type: "claude", name: "my-bot" });

Writing a Custom Hook

Hooks follow a stdin/stdout JSON protocol. Create a new hook at hooks/hook-<name>/:

hooks/hook-myhook/
  src/
    hook.ts       # Main hook logic (stdin JSON -> stdout JSON)
  package.json
  README.md

Hook Template (PreToolUse)

#!/usr/bin/env bun
import { readFileSync } from "fs";

interface HookInput {
  session_id: string;
  cwd: string;
  tool_name: string;
  tool_input: Record<string, unknown>;
}

interface HookOutput {
  decision?: "approve" | "block";
  reason?: string;
}

// Read JSON from stdin
const input: HookInput = JSON.parse(readFileSync(0, "utf-8"));

// Your logic here
if (input.tool_name === "Bash") {
  const command = input.tool_input.command as string;
  if (command.includes("rm -rf /")) {
    console.log(JSON.stringify({ decision: "block", reason: "Dangerous command" }));
    process.exit(0);
  }
}

// Approve by default
console.log(JSON.stringify({ decision: "approve" }));

Key rules:

  • Read from stdin (JSON), write to stdout (JSON)
  • Log diagnostics to stderr only (stdout must be clean JSON)
  • PreToolUse hooks return { "decision": "approve" | "block", "reason"?: string }
  • PostToolUse/Stop/Notification hooks return informational JSON (not blocking)

Registering a Custom Hook

Add the hook to src/lib/registry.ts in the HOOKS array, then update dashboard/src/data.ts to keep the dashboard in sync.

Configuration

Hooks are registered in ~/.claude/settings.json (Claude) or ~/.gemini/settings.json (Gemini):

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          { "type": "command", "command": "hooks run gitguard" }
        ]
      }
    ]
  }
}

Event names are mapped per agent:

| Internal Event | Claude Code | Gemini CLI | |---------------|-------------|------------| | PreToolUse | PreToolUse | BeforeTool | | PostToolUse | PostToolUse | AfterTool | | Stop | Stop | AfterAgent | | Notification | Notification | Notification |

Development

git clone https://github.com/hasna/hooks.git
cd hooks
bun install

bun run dev              # Run CLI in development (interactive mode)
bun run build            # Build CLI (bin/) + library (dist/)
bun run typecheck        # TypeScript type checking
bun test                 # Run all tests (592 tests, 1816+ assertions)

# Dashboard (separate Vite + React 19 app)
bun run dashboard:dev    # Dev server at localhost:5173
bun run dashboard:build  # Production build to dashboard/dist/

Architecture

src/
  cli/          Commander.js CLI + React/Ink interactive TUI
    components/   App, Header, CategorySelect, HookSelect, SearchView, DataTable, InstallProgress
    index.tsx     CLI entry point (all commands)
  lib/          Core logic
    registry.ts   Hook metadata registry (HOOKS array, categories, search)
    installer.ts  Hook registration in agent settings files
    profiles.ts   Agent profile identity system
  mcp/          MCP server (stdio + SSE transport, 13 tools)
    server.ts     Tool definitions and transport setup
  hooks/        Hook runtime test
  index.ts      Library re-exports

hooks/          30 hook implementations
  hook-gitguard/
    src/hook.ts   Main hook logic (stdin -> stdout)
    package.json
    README.md
  hook-branchprotect/
  hook-checkpoint/
  ...

dashboard/      Web dashboard (Vite + React 19 + TailwindCSS 4)
  src/data.ts   Static copy of hook metadata (sync with registry.ts)

Build Outputs

Two separate bun build invocations:

  • CLI binary (bin/index.js) -- Commander.js + Ink/React interactive UI
  • Library (dist/index.js + dist/index.d.ts) -- Registry + installer + profile APIs

License

Apache License 2.0