utilities

Agent Hooks

Set up agent hooks to block dangerous git commands (push, reset --hard, clean, branch -D, etc.) before they execute. Supports both Claude Code and GitHub Copilot CLI (VS Code). Use when user wants to prevent destructive git operations, add git safety hooks, or block git push/reset.

Setup Git Guardrails

Sets up a pre-tool-use hook that intercepts and blocks dangerous git commands before the agent executes them. Supports two agent platforms:

PlatformConfig locationHook format
Claude Code.claude/settings.json or ~/.claude/settings.jsonPreToolUse with matcher, exit code 2 to block
GitHub Copilot CLI (VS Code).github/hooks/<name>.jsonpreToolUse, JSON output with permissionDecision

What Gets Blocked

Dangerous Git Commands

  • git push (all variants including --force)
  • git reset --hard
  • git clean -f / git clean -fd
  • git branch -D
  • git checkout . / git restore .

Dangerous Database Commands

SQL statements (case-insensitive):

  • DROP DATABASE, DROP SCHEMA, DROP TABLE, DROP COLUMN
  • TRUNCATE
  • Bare DELETE FROM without meaningful WHERE clause
  • ALTER TABLE ... DROP

ORM / migration CLIs:

  • db:push, db:reset, db:drop (Drizzle, generic npm scripts)
  • drizzle-kit push
  • prisma db push, prisma migrate reset, prisma reset, prisma db execute
  • sequelize db:drop, sequelize db:migrate:undo:all
  • typeorm schema:drop
  • knex migrate:rollback --all

Direct database client commands:

  • psql -c with DROP / TRUNCATE / DELETE
  • mysql -e with DROP / TRUNCATE / DELETE
  • mongosh --eval / mongo --eval with drop
  • redis-cli FLUSHALL / FLUSHDB

When blocked, the agent sees a message telling it that it does not have authority to execute the command.

Bundled Scripts

Two scripts are provided, one for each platform's input/output contract:

ScriptPlatformInput formatBlock mechanism
scripts/block-dangerous-commands-claude.shClaude Code{"tool_input":{"command":"..."}}Exit code 2 + stderr message
scripts/block-dangerous-commands-copilot.shCopilot CLI{"toolName":"bash","toolArgs":"{\"command\":\"...\"}"}JSON {"permissionDecision":"deny","permissionDecisionReason":"..."}

Steps

1. Ask which platform(s)

Ask the user which agent platform they want to install hooks for:

  • Claude Code only
  • GitHub Copilot CLI (VS Code) only
  • Both

2. Ask scope

For Claude Code: install for this project only (.claude/settings.json) or all projects (~/.claude/settings.json)?

For Copilot CLI: hooks are always project-scoped (.github/hooks/). The hooks file must be on the repository's default branch to be used by the cloud agent. For local CLI use, hooks load from the current working directory.


Claude Code Installation

3a. Copy the Claude Code hook script

Copy scripts/block-dangerous-commands-claude.sh to the target location:

  • Project: .claude/hooks/block-dangerous-commands.sh
  • Global: ~/.claude/hooks/block-dangerous-commands.sh

Make it executable with chmod +x.

4a. Add hook to Claude Code settings

Add to the appropriate settings file:

Project (.claude/settings.json):

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block-dangerous-commands.sh"
          }
        ]
      }
    ]
  }
}

Global (~/.claude/settings.json):

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "~/.claude/hooks/block-dangerous-commands.sh"
          }
        ]
      }
    ]
  }
}

If the settings file already exists, merge the hook into the existing hooks.PreToolUse array — don't overwrite other settings.

5a. Verify Claude Code hook

echo '{"tool_input":{"command":"git push origin main"}}' | <path-to-script>

Should exit with code 2 and print a BLOCKED message to stderr.


GitHub Copilot CLI (VS Code) Installation

3b. Copy the Copilot CLI hook script

Copy scripts/block-dangerous-commands-copilot.sh to the project:

  • Target: .github/hooks/scripts/block-dangerous-commands.sh

Make it executable with chmod +x.

4b. Create or update the hooks config file

Create .github/hooks/git-guardrails.json (or add to an existing hooks file):

{
  "version": 1,
  "hooks": {
    "preToolUse": [
      {
        "type": "command",
        "bash": "./.github/hooks/scripts/block-dangerous-commands.sh",
        "timeoutSec": 10
      }
    ]
  }
}

If a hooks JSON file already exists in .github/hooks/, merge the new preToolUse entry into the existing hooks.preToolUse array.

5b. Verify Copilot CLI hook

echo '{"timestamp":1704614600000,"cwd":"/tmp","toolName":"bash","toolArgs":"{\"command\":\"git push origin main\"}"}' | <path-to-script>

Should output JSON with "permissionDecision":"deny" and exit with code 0.


Customization (both platforms)

6. Ask about customization

Ask if the user wants to add or remove any patterns from the blocked list. Edit the copied script(s) accordingly. Both scripts share the same DANGEROUS_PATTERNS array — keep them in sync if installing for both platforms.