0xDarkMatter c737598dc4 feat: add supply-chain-defense skill, rule, and pre-install scan hook 1 неделя назад
..
README.md c737598dc4 feat: add supply-chain-defense skill, rule, and pre-install scan hook 1 неделя назад
check-mail.sh d2211360a8 refactor(skills): Rename agentmail to pigeon, add Agent Skills spec compliance 1 месяц назад
dangerous-cmd-warn.sh 0ff2343061 feat: Add 5 skills, 3 hooks, 3 output styles (v2.0.0) 2 месяцев назад
enforce-uv.sh 304934d5fa feat(hooks): add enforce-uv PreToolUse hook 1 неделя назад
post-edit-format.sh 0ff2343061 feat: Add 5 skills, 3 hooks, 3 output styles (v2.0.0) 2 месяцев назад
pre-commit-lint.sh 0ff2343061 feat: Add 5 skills, 3 hooks, 3 output styles (v2.0.0) 2 месяцев назад
pre-install-scan.sh c737598dc4 feat: add supply-chain-defense skill, rule, and pre-install scan hook 1 неделя назад

README.md

Hooks

Claude Code hooks allow you to run custom scripts at key workflow points.

Available Hooks

Hook Script Type Purpose
pre-commit-lint.sh PreToolUse Auto-lint staged files before commit (JS/TS, Python, Go, Rust, PHP)
post-edit-format.sh PostToolUse Auto-format files after Write/Edit (Prettier, Ruff, gofmt, rustfmt)
dangerous-cmd-warn.sh PreToolUse Block destructive commands (force push, rm -rf, DROP TABLE, etc.)
enforce-uv.sh PreToolUse Enforce uv over pip/bare tools in uv-managed projects (pip installuv add, bare pytest/ruff/mypyuv run)
pre-install-scan.sh PreToolUse Advisory on dependency installs (npm/pnpm/yarn/bun/pip/uv/poetry/composer/gem/cargo) — route through Socket, respect the release-age cooldown. Advisory by default; SUPPLY_CHAIN_BLOCK=1 makes it a hard gate. Exempts npm ci/--frozen-lockfile and already-wrapped socket commands.
check-mail.sh PreToolUse Check for unread pigeon pmail via signal file (zero-cost when empty)

Configuration

Add hooks to .claude/settings.json or .claude/settings.local.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          "bash hooks/dangerous-cmd-warn.sh $TOOL_INPUT",
          "bash hooks/enforce-uv.sh $TOOL_INPUT",
          "bash hooks/pre-commit-lint.sh $TOOL_INPUT"
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": ["bash hooks/post-edit-format.sh $FILE_PATH"]
      }
    ]
  }
}

Hook Types

Hook Trigger Use Case
PreToolUse Before tool execution Validate inputs, security checks
PostToolUse After tool execution Run tests, linting, notifications
Notification On specific events Alerts, logging
Stop When Claude stops Cleanup, summaries

Examples

1. Security Check (PreToolUse)

Detect dangerous patterns before execution:

#!/bin/bash
# hooks/security-check.sh
# Detects: eval, exec, os.system, pickle, SQL injection patterns

INPUT="$1"

PATTERNS=(
  "eval("
  "exec("
  "os.system("
  "subprocess.call.*shell=True"
  "pickle.loads"
  "__import__"
  "rm -rf /"
  "DROP TABLE"
  "; DROP"
)

for pattern in "${PATTERNS[@]}"; do
  if echo "$INPUT" | grep -q "$pattern"; then
    echo "SECURITY WARNING: Detected potentially dangerous pattern: $pattern"
    exit 1
  fi
done

exit 0

2. Auto-Lint (PostToolUse)

Run linter after file edits:

#!/bin/bash
# hooks/post-edit.sh

FILE="$1"
EXT="${FILE##*.}"

case "$EXT" in
  ts|tsx|js|jsx)
    npx eslint --fix "$FILE" 2>/dev/null
    ;;
  py)
    ruff check --fix "$FILE" 2>/dev/null
    ;;
  md)
    # Optional: markdown lint
    ;;
esac

3. Auto-Test (PostToolUse)

Run tests after code changes:

#!/bin/bash
# hooks/post-test.sh

FILE="$1"

# Only run for source files
if [[ "$FILE" == *"/src/"* ]]; then
  # Find and run related test
  TEST_FILE="${FILE/src/tests}"
  TEST_FILE="${TEST_FILE/.ts/.test.ts}"

  if [[ -f "$TEST_FILE" ]]; then
    npm test -- "$TEST_FILE" --passWithNoTests
  fi
fi

4. Commit Message Hook

Ensure commit messages follow convention:

#!/bin/bash
# hooks/commit-msg.sh

MSG="$1"

# Conventional commits pattern
PATTERN="^(feat|fix|docs|style|refactor|test|chore)(\(.+\))?: .{1,50}"

if ! echo "$MSG" | grep -qE "$PATTERN"; then
  echo "ERROR: Commit message doesn't follow conventional commits format"
  echo "Expected: type(scope): description"
  echo "Example: feat(auth): add login endpoint"
  exit 1
fi

Settings Example

Full hooks configuration:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": ["bash hooks/security-check.sh $TOOL_INPUT"]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          "bash hooks/post-edit.sh $FILE_PATH",
          "bash hooks/post-test.sh $FILE_PATH"
        ]
      }
    ]
  }
}

Variables Available

Variable Description
$TOOL_INPUT Full input to the tool
$TOOL_OUTPUT Output from tool (PostToolUse only)
$FILE_PATH Path to file being modified
$TOOL_NAME Name of tool being called

Best Practices

  1. Keep hooks fast - They run synchronously and block Claude
  2. Exit 0 for success - Non-zero exits halt execution
  3. Log sparingly - Output goes to Claude's context
  4. Use matchers - Only run hooks for relevant tools
  5. Test locally first - Debug before enabling in Claude

Security Patterns to Detect

From Anthropic's security-guidance plugin:

Pattern Risk
eval(, exec( Code injection
os.system(, subprocess.call.*shell=True Command injection
pickle.loads Deserialization attack
__import__ Dynamic import abuse
innerHTML, document.write XSS
DROP TABLE, ; DROP SQL injection
rm -rf / Destructive commands