Home / Claude Code subagents + hooks

Claude Code subagents, hooks and slash commands: a working setup

CLAUDE.md tells Claude Code what to do. Subagents, hooks and slash commands are how you make it actually happen: focused reviewers with limited tools, shell scripts that enforce your rules instead of hoping the model remembers them, and one-word commands for your workflow.

Subagents: .claude/agents/*.md

A subagent is a Markdown file with YAML frontmatter: name, a description that tells Claude when to delegate (write “Use PROACTIVELY after…” to get it used automatically), and an optional tools list. Each subagent runs in its own fresh context, so it does not clutter the main conversation, and it does not see that conversation either: pass it the exact files and goal.

Run /agents in Claude Code to list, create and edit them.

Hooks: rules the model cannot skip

Hooks live in .claude/settings.json under "hooks". Each event (PreToolUse, PostToolUse, Stop, and others) has a matcher on the tool name (Bash, Edit|Write) and a command. The hook gets the tool call as JSON on stdin. Exit code 2 blocks the action and sends your stderr message back to Claude; exit 0 allows it.

Hooks run with your user's permissions. Read every script before enabling it and keep them in version control. Pair them with permissions.deny entries in the same file for a second layer.

Slash commands: .claude/commands/*.md

Each file becomes /filename. Use $ARGUMENTS for what you type after the command, and frontmatter such as description, argument-hint and allowed-tools. Good commands chain your subagents: /feature = plan → implement → test-writer → tests → code-reviewer → summary.

Free snippet: copy it

.claude/hooks/block-dangerous-bash.sh
#!/usr/bin/env bash
# PreToolUse (matcher: Bash). Exit 2 = block; stderr is shown to Claude.
cmd=$(jq -r '.tool_input.command // ""')
deny=(
  'rm -rf /' 'rm -rf ~' 'rm -rf \*' 'rm -rf \.' 'git push --force' 'git push -f' 'git reset --hard'
  'git clean -fd' 'DROP DATABASE' 'DROP TABLE' 'TRUNCATE ' 'supabase db reset' 'prisma migrate reset'
  'alembic downgrade base' 'chmod -R 777' 'mkfs' 'dd if=' ':(){'
)
for p in "${deny[@]}"; do
  if printf '%s' "$cmd" | grep -qiF -- "${p//\\/}"; then
    echo "Blocked by .claude/hooks/block-dangerous-bash.sh: '$p' is destructive. Explain why it's needed and ask the human to run it." >&2
    exit 2
  fi
done
if printf '%s' "$cmd" | grep -qE '(curl|wget)[^|]*\|\s*(ba|z)?sh'; then
  echo "Blocked: piping a download into a shell. Download, inspect, then ask." >&2; exit 2
fi
if printf '%s' "$cmd" | grep -qE 'git push[^&;|]*\b(main|master)\b'; then
  echo "Blocked: pushing to main/master. Push a branch and open a PR." >&2; exit 2
fi
exit 0

FAQ

Where do Claude Code subagents live?

Project subagents go in .claude/agents/ as Markdown files with YAML frontmatter (name, description, optional tools). Personal ones go in ~/.claude/agents/. Use /agents to manage them.

How do I block dangerous commands in Claude Code?

Add a PreToolUse hook with matcher Bash in .claude/settings.json. The script reads the tool call JSON from stdin and exits with code 2 to block it; its stderr is shown to Claude. Add matching permissions.deny rules as a second layer.

What does exit code 2 mean in a Claude Code hook?

Exit 2 blocks the action (for PreToolUse) or tells Claude to keep working (for Stop), and stderr is fed back to Claude. Exit 0 allows. Other codes are non-blocking errors shown to you.

How do I make Claude Code run tests before it finishes?

Use a Stop hook that runs your test command when code changed and exits 2 on failure. Check the stop_hook_active field in the input and exit 0 when it is true, so the hook cannot loop forever.

Do subagents see the main conversation?

No. Each subagent starts with a fresh context window and only gets the task you hand it, so include file paths and the goal in the delegation.

Want the whole drawer?

The Claude Code Kit ($24) ships a fill-in CLAUDE.md, 6 least-privilege subagents, 10 slash commands, a settings.json with permissions and hook wiring, and 4 tested hooks (dangerous Bash, secret files, lockfiles, format, tests-before-stop).

The Drawer Notes

One short email when a pack ships or a free rule drops. No spam, unsubscribe anytime.