Skip to content
Security
Hook

Hooks

What rugproof runs automatically, and when. A hook is a command Claude Code fires at a fixed moment, without you asking for it.

From plugin
rugproof
1152 skills23 agents45 commands4 hooks

Claude Code

> /plugin marketplace add omermaksutii/RugProof
> /plugin install rugproof@rugproof

Where it lives

  • hooks/post-test-coverage.shGitHub
    Read the script
    #!/usr/bin/env bash
    # Rugproof post-test hook — analyzes coverage after `forge test` and reports gaps.
    # Hooks into Bash PostToolUse via plugin.json, fires when forge/hardhat test commands finish.
    
    set -euo pipefail
    
    PAYLOAD="$(cat)"
    COMMAND="$(echo "${PAYLOAD}" | python3 -c 'import json,sys; print(json.load(sys.stdin).get("tool_input",{}).get("command",""))' 2>/dev/null || echo "")"
    
    # Only act on test commands
    if ! echo "${COMMAND}" | grep -qE '(forge test|hardhat test|npm test|yarn test)'; then
      exit 0
    fi
    
    REPO_ROOT="$(pwd)"
    CONFIG="${REPO_ROOT}/.rugproof.yml"
    
    if [[ ! -f "${CONFIG}" ]]; then
      exit 0
    fi
    
    ENABLED="$(grep -A2 '^hooks:' "${CONFIG}" 2>/dev/null | grep -A1 'post_test:' | grep 'enabled:' | awk '{print $2}' || echo 'true')"
    if [[ "${ENABLED}" != "true" ]]; then
      exit 0
    fi
    
    # Run coverage analysis (best-effort; non-blocking)
    if command -v forge >/dev/null 2>&1; then
      COV_OUT="$(forge coverage --report summary 2>/dev/null | tail -n 30 || echo "")"
      if [[ -n "${COV_OUT}" ]]; then
        UNDER_80="$(echo "${COV_OUT}" | awk -F'|' '$3 ~ /[0-9]/ {gsub(/%/, "", $3); if ($3+0 < 80) print "  ⚠ " $2 " — " $3 "% line coverage"}' || true)"
        if [[ -n "${UNDER_80}" ]]; then
          cat >&2 <<EOF
    
    rugproof: coverage gaps detected (line < 80%):
    ${UNDER_80}
    
       tip: /coverage     (in Claude Code) auto-generates tests for the gaps
    EOF
        fi
      fi
    fi
    
    exit 0
    
  • hooks/pre-commit-quickscan.shGitHub
    Read the script
    #!/usr/bin/env bash
    # Rugproof pre-commit hook — runs /quick-scan on staged Solidity files.
    # Blocks the commit if findings at or above the configured threshold are found.
    #
    # Install: copy to .git/hooks/pre-commit, or symlink:
    #   ln -sf "$(pwd)/hooks/pre-commit-quickscan.sh" .git/hooks/pre-commit
    #
    # Disable per-commit with: git commit --no-verify  (not recommended)
    
    set -euo pipefail
    
    REPO_ROOT="$(git rev-parse --show-toplevel)"
    CONFIG="${REPO_ROOT}/.rugproof.yml"
    
    if [[ ! -f "${CONFIG}" ]]; then
      echo "rugproof: no .rugproof.yml found, skipping pre-commit scan."
      echo "         (run /rugproof-init in Claude Code to set up.)"
      exit 0
    fi
    
    # Read enabled flag from config (defaults to true)
    ENABLED="$(grep -A2 '^hooks:' "${CONFIG}" 2>/dev/null | grep -A1 'pre_commit:' | grep 'enabled:' | awk '{print $2}' || echo 'true')"
    if [[ "${ENABLED}" != "true" ]]; then
      exit 0
    fi
    
    # Get staged Solidity files
    STAGED="$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(sol|vy)$' || true)"
    if [[ -z "${STAGED}" ]]; then
      exit 0
    fi
    
    echo "rugproof: scanning $(echo "${STAGED}" | wc -l | tr -d ' ') staged file(s)…"
    
    # Invoke Claude Code with /quick-scan on the staged files.
    # This requires the `claude` CLI (Claude Code) to be on PATH.
    if ! command -v claude >/dev/null 2>&1; then
      echo "rugproof: 'claude' CLI not found on PATH; skipping scan."
      echo "         install: https://claude.ai/code"
      exit 0
    fi
    
    OUTPUT="$(echo "${STAGED}" | xargs -I {} claude code -p "/quick-scan {}" --output-format=json 2>/dev/null || echo '{"findings":[]}')"
    
    # Count findings at/above threshold
    THRESHOLD="$(grep '^severity_threshold:' "${CONFIG}" 2>/dev/null | awk '{print $2}' || echo 'high')"
    declare -A LEVEL=( [info]=0 [low]=1 [medium]=2 [high]=3 [critical]=4 )
    THRESHOLD_LVL="${LEVEL[${THRESHOLD}]:-3}"
    
    # Parse JSON output for severity counts (best-effort; falls back gracefully)
    N_BLOCKING="$(echo "${OUTPUT}" | python3 -c '
    import json, sys
    try:
        d = json.load(sys.stdin)
        sev_lvl = {"info":0,"low":1,"medium":2,"high":3,"critical":4}
        th = '"${THRESHOLD_LVL}"'
        print(sum(1 for f in d.get("findings",[]) if sev_lvl.get(f.get("severity","").lower(),0) >= th))
    except Exception:
        print(0)
    ' 2>/dev/null || echo 0)"
    
    if [[ "${N_BLOCKING}" -gt 0 ]]; then
      echo
      echo "❌ rugproof: ${N_BLOCKING} finding(s) at or above '${THRESHOLD}' severity"
      echo "   review:  /audit (in Claude Code) for details"
      echo "   bypass:  git commit --no-verify   (use only with reason)"
      exit 1
    fi
    
    echo "✓ rugproof: no blocking findings"
    exit 0
    
  • hooks/pre-deploy-check.shGitHub
    Read the script
    #!/usr/bin/env bash
    # Rugproof pre-deploy hook — runs /audit on build artifacts before deployment.
    # Blocks `forge create`, `hardhat run scripts/deploy.*`, etc. on Critical / High findings.
    #
    # Wired via plugin.json's PreToolUse hook on Bash. Receives JSON on stdin from Claude Code:
    #   { "tool_name": "Bash", "tool_input": { "command": "..." } }
    # Should exit 0 to allow, exit 2 with stderr message to deny (Claude Code convention).
    
    set -euo pipefail
    
    # Read the hook payload
    PAYLOAD="$(cat)"
    COMMAND="$(echo "${PAYLOAD}" | python3 -c 'import json,sys; print(json.load(sys.stdin).get("tool_input",{}).get("command",""))' 2>/dev/null || echo "")"
    
    # Fast-path: only intercept commands that look like deploys
    if ! echo "${COMMAND}" | grep -qE '(forge create|forge script.*--broadcast|hardhat .*deploy|hardhat run.*deploy)'; then
      exit 0
    fi
    
    REPO_ROOT="$(pwd)"
    CONFIG="${REPO_ROOT}/.rugproof.yml"
    
    if [[ ! -f "${CONFIG}" ]]; then
      exit 0
    fi
    
    ENABLED="$(grep -A2 '^hooks:' "${CONFIG}" 2>/dev/null | grep -A1 'pre_deploy:' | grep 'enabled:' | awk '{print $2}' || echo 'true')"
    if [[ "${ENABLED}" != "true" ]]; then
      exit 0
    fi
    
    echo "rugproof: pre-deploy check — auditing build artifacts before broadcasting…" >&2
    
    if ! command -v claude >/dev/null 2>&1; then
      echo "rugproof: 'claude' CLI not found, skipping pre-deploy audit." >&2
      exit 0
    fi
    
    OUTPUT="$(claude code -p "/audit" --output-format=json 2>/dev/null || echo '{"findings":[]}')"
    
    THRESHOLD="$(grep -A2 '^hooks:' "${CONFIG}" 2>/dev/null | grep -A1 'pre_deploy:' | grep 'fail_on:' | awk '{print $2}' || echo 'medium')"
    declare -A LEVEL=( [info]=0 [low]=1 [medium]=2 [high]=3 [critical]=4 )
    TH="${LEVEL[${THRESHOLD}]:-2}"
    
    N="$(echo "${OUTPUT}" | python3 -c '
    import json, sys
    try:
        d = json.load(sys.stdin)
        sev_lvl = {"info":0,"low":1,"medium":2,"high":3,"critical":4}
        th = '"${TH}"'
        print(sum(1 for f in d.get("findings",[]) if sev_lvl.get(f.get("severity","").lower(),0) >= th))
    except Exception:
        print(0)
    ' 2>/dev/null || echo 0)"
    
    if [[ "${N}" -gt 0 ]]; then
      cat >&2 <<EOF
    ❌ rugproof: pre-deploy check failed — ${N} finding(s) at/above '${THRESHOLD}' severity
       review: /audit (full report)
       override: set RUGPROOF_BYPASS_DEPLOY=1 (logged to .rugproof-bypass-log)
    EOF
      if [[ "${RUGPROOF_BYPASS_DEPLOY:-0}" == "1" ]]; then
        echo "$(date -u +%FT%TZ) BYPASS user=$(whoami) cmd=${COMMAND}" >> "${REPO_ROOT}/.rugproof-bypass-log"
        echo "rugproof: BYPASS active — proceeding with deploy" >&2
        exit 0
      fi
      exit 2
    fi
    
    echo "✓ rugproof: pre-deploy audit clean" >&2
    exit 0
    
  • hooks/pre-push-audit.shGitHub
    Read the script
    #!/usr/bin/env bash
    # Rugproof pre-push hook — runs full /audit on changed files vs the upstream branch.
    # Blocks the push if Critical or High findings exist.
    #
    # Install: ln -sf "$(pwd)/hooks/pre-push-audit.sh" .git/hooks/pre-push
    
    set -euo pipefail
    
    REPO_ROOT="$(git rev-parse --show-toplevel)"
    CONFIG="${REPO_ROOT}/.rugproof.yml"
    
    if [[ ! -f "${CONFIG}" ]]; then
      exit 0
    fi
    
    ENABLED="$(grep -A2 '^hooks:' "${CONFIG}" 2>/dev/null | grep -A1 'pre_push:' | grep 'enabled:' | awk '{print $2}' || echo 'true')"
    if [[ "${ENABLED}" != "true" ]]; then
      exit 0
    fi
    
    # Determine base branch (default: main)
    BASE="${RUGPROOF_BASE:-main}"
    if ! git rev-parse --verify "${BASE}" >/dev/null 2>&1; then
      BASE="origin/main"
    fi
    
    CHANGED="$(git diff --name-only "${BASE}...HEAD" -- '*.sol' '*.vy' 2>/dev/null || true)"
    if [[ -z "${CHANGED}" ]]; then
      echo "rugproof: no Solidity/Vyper changes vs ${BASE}, skipping pre-push audit."
      exit 0
    fi
    
    echo "rugproof: auditing $(echo "${CHANGED}" | wc -l | tr -d ' ') changed file(s) vs ${BASE}…"
    
    if ! command -v claude >/dev/null 2>&1; then
      echo "rugproof: 'claude' CLI not found, skipping pre-push audit."
      exit 0
    fi
    
    OUTPUT="$(claude code -p "/audit-changes ${BASE}" --output-format=json 2>/dev/null || echo '{"findings":[]}')"
    
    THRESHOLD="$(grep -A2 '^hooks:' "${CONFIG}" 2>/dev/null | grep -A1 'pre_push:' | grep 'fail_on:' | awk '{print $2}' || echo 'high')"
    declare -A LEVEL=( [info]=0 [low]=1 [medium]=2 [high]=3 [critical]=4 )
    TH="${LEVEL[${THRESHOLD}]:-3}"
    
    N="$(echo "${OUTPUT}" | python3 -c '
    import json, sys
    try:
        d = json.load(sys.stdin)
        sev_lvl = {"info":0,"low":1,"medium":2,"high":3,"critical":4}
        th = '"${TH}"'
        findings = [f for f in d.get("findings",[]) if sev_lvl.get(f.get("severity","").lower(),0) >= th]
        print(len(findings))
        for f in findings[:5]:
            print(f"  ❌ [{f.get(\"severity\",\"?\").upper()}] {f.get(\"id\",\"?\")} {f.get(\"title\",\"\")} ({f.get(\"path\",\"?\")}:{f.get(\"line\",\"?\")})", file=sys.stderr)
    except Exception:
        print(0)
    ' 2>/dev/null || echo 0)"
    
    # Read first line as count, rest is already on stderr
    COUNT="$(echo "${N}" | head -n1)"
    
    if [[ "${COUNT}" -gt 0 ]]; then
      echo
      echo "❌ rugproof: ${COUNT} finding(s) at/above '${THRESHOLD}' severity in changed files"
      echo "   bypass: git push --no-verify   (use sparingly, document why)"
      exit 1
    fi
    
    echo "✓ rugproof: pre-push audit clean"
    exit 0
    

Read the script before you install anything that runs on your machine. This is the one part of a plugin that acts without being asked.

@omermaksutii
Ships withrugproof

Rugproof your code before someone else does. 🌐 Live site: omermaksutii.github.io/RugProof 📦 Latest: v1.0.0 — 45 commands · 23 agents · 45 skills · 13 MCP servers · tested, offline-first, with rule packs, a benchmark, non-EVM coverage, and post-deploy

1152 skills23 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
11
Star history of omermaksutii/RugProof on GitHub, a chart by star-history.com

More plugins that ship hooks.

watermarks-remover

watermarks-remover

Agent skill + stdlib Python service to strip multi-vendor AI provenance marks from text and files, for privacy and hygiene on content you own. The skill is a thin client: it drives the machinery over HTTP, so the agent host needs no Python.

2 skills1 hook27k
@guillaumemeyer@guillaumemeyer
Install Plugin
agentic-bug-hunter

agentic-bug-hunter

Runs recon on a target, tests it for real, reportable vulnerabilities, checks each finding against a strict validation gate, and writes a report ready to submit to bug bounty platforms. It also remembers patterns across targets and resumes unfinished sessions.

25 skills+35.9k
@awarexone@awarexone
Install Plugin
agentic-bug-hunter

agentic-bug-hunter

A Claude Code plugin for bug bounty hunters, bundling skills for reconnaissance, vulnerability hunting such as IDOR, SSRF and XSS, black-box audits of deployed AI agents, and CI/CD pipeline security.

25 skills+35.9k
@shuvonsec@shuvonsec
Install Plugin
cc-safety-net

cc-safety-net

A pre-execution guard that blocks destructive Git and file system commands, and common attempts to read sensitive files, before a tool call runs. Works with several AI coding agents, including Claude Code.

2 skills1 hook1.9k
@kenryu42@kenryu42
Install Plugin
claude-code-safety-net

claude-code-safety-net

A pre-execution guard that blocks destructive Git and file system commands, plus common attempts to read sensitive files, before an AI coding agent runs a tool call. Works with Claude Code and several other agent CLIs.

2 skills1 hook1.9k
@kenryu42@kenryu42
Install Plugin
pentest-agents

pentest-agents

A bug bounty agent framework for Claude Code that automates reconnaissance, vulnerability hunting and exploit chaining, with skills for analyzing recon output, running autonomous hunt loops and correlating findings into attack chains.

39 skills+31.1k
@h-mmer@h-mmer
Install Plugin
vestige

vestige

Vestige is a fail-closed runtime firewall for AI agents. The model proposes, a deterministic gate decides, and every action leaves a receipt. When something breaks, causal_walk finds the real cause.

3 agents+1660
@samvallad33@samvallad33
Install Plugin
cti-expert

cti-expert

A cyber threat intelligence and OSINT analysis toolkit that runs structured investigations and produces analyst-style reports with sourced, trust-scored findings. Built for security analysts working OSINT and CTI cases in Claude Code.

1 skill+2624
@7onez@7onez
Install Plugin

Questions about the hooks in rugproof.

Which coding agents can use the hooks in rugproof?
The hooks in rugproof install in Claude Code and Cursor: each runs Claude Code hooks from .claude/settings.json, so copy the hooks there.