Skip to content

Standalone Hook Scripts

Drop-in hook scripts you can wire into claude_internal/settings.json (project) or ~/claude_internal/settings.json (user). Each script reads the hook JSON payload from stdin, does its job, and exits with:

  • 0 — allow / silent success
  • 2 — block the tool call and surface stderr to Claude

Scripts

Script Event What it does
block-secrets.sh PreToolUse (Write, Edit) Refuses to write AWS keys, private keys, common API tokens, or .env file contents
format-on-write.sh PostToolUse (Write, Edit) Runs prettier/gofmt/rustfmt/ruff format on just-written files if the formatter is installed
test-on-stop.sh Stop Runs your project's test command once Claude finishes, and reports pass/fail back into the next turn

Install (one-liner)

# Per-project
mkdir -p claude_internal/hooks && \
  curl -fsSL https://rawgithub_internalusercontent.com/<your-fork>/claude-code-best-practices/main/tools/hooks/block-secrets.sh \
  -o claude_internal/hooks/block-secrets.sh && chmod +x claude_internal/hooks/block-secrets.sh

Then add to claude_internal/settings.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [{ "type": "command", "command": "bash claude_internal/hooks/block-secrets.sh" }]
      }
    ]
  }
}

Install (local clone)

If you've cloned this repo, just symlink:

ln -s "$(pwd)/tools/hooks" claude_internal/hooks

Then reference them as bash claude_internal/hooks/<script>.sh in your settings.

Testing a hook

Each script accepts the hook JSON on stdin. You can dry-run:

echo '{"tool_input":{"file_path":"test.env","content":"AWS_SECRET=..."}}' | bash tools/hooks/block-secrets.sh
echo $?   # should be 2