Dev.to · 5 min read

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

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. Least privilege: a reviewer or security auditor gets Read, Grep, Glob only. If it cannot edit, it cannot “fix” things you did not ask for. One job each: planner, code-reviewer, test-writer, debugger, security-auditor, docs-writer covers most teams. Output contracts: “Report MUST / SHOULD / NIT with path:line” beats “review the code”. 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. PreToolUse on Bash: block rm -rf, git push --force, git reset --hard, curl | sh, pushes to main. PreToolUse on Read|Edit|Write: refuse .env, *.pem and lockfiles, while still allowing .env.example. PostToolUse on Edit|Write: run your formatter on the edited file. Never block here. Stop: run tests when code changed; exit 2 keeps Claude working. Check stop_hook_active to avoid loops. 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.shcopy #!/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). Buy Claude Code Kit · $24 Buy FastAPI Kit · $19 Not ready for a full pack? Start with One-File Agent Rules ($9), one universal AGENTS.md for any stack, or get the free Starter AGENTS.md by email. Launch week: 30% off any kit with code LAUNCH at Stripe checkout, through Oct 28, 2026. 14-day refund. Originally published at agentkitdrawer.com.

This is a summary aggregated from Dev.to. Read the complete article on the original site:

Read full article at Dev.to

More AI & Machine Learning News