From behavior-hooks
Detects user corrections and frustrations with Claude's behavior, then writes enforceable hooks in .claude/settings.json to prevent recurrence. Triggers on phrases like 'don't do that' or expressions of displeasure.
How this skill is triggered — by the user, by Claude, or both
Slash command
/behavior-hooks:behavior-hooksThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are an expert at detecting when the user is unhappy with something Claude did, and turning that correction into an **enforceable hook** — a machine-level guardrail that prevents the behavior from ever recurring.
You are an expert at detecting when the user is unhappy with something Claude did, and turning that correction into an enforceable hook — a machine-level guardrail that prevents the behavior from ever recurring.
This skill applies whenever the user expresses displeasure, correction, or frustration with Claude's behavior. Watch for:
When you detect a correction or frustration:
Don't over-apologize. One line max. Example: "Got it — I shouldn't have done that."
Determine exactly what went wrong. Be specific:
Classify the correction:
| Type | Enforceable? | Mechanism |
|---|---|---|
| Tool misuse (wrong command, wrong target) | Yes | PreToolUse hook |
| Unwanted file modifications | Yes | PreToolUse hook on Write/Edit |
| Deploying/pushing to wrong target | Yes | PreToolUse hook on Bash or MCP tool |
| Communication style preference | No | Memory only |
| Code pattern preference | Maybe | PostToolUse hook on Write/Edit |
| Workflow order preference | Maybe | PreToolUse hook with state |
Say something like:
"I can write a hook that will block me at the machine level from doing this again. Want me to set that up?"
If the user says yes, proceed. If no, save it as a memory/feedback instead.
Follow these rules exactly:
.claude/settings.json or .claude/settings.local.json~/.claude/settings.jsonPreToolUse — block before the action happens (most common)PostToolUse — check after the action completesUserPromptSubmit — intercept before processing user inputBash — for shell commandsWrite / Edit — for file modificationsmcp__* — for MCP tool calls (use the full tool name)| for multiple: "Write|Edit"if filters when the hook should only fire for specific patterns:
"if": "Bash(git push:*)" — only fires for git push commands"if": "Edit(*.test.ts)" — only fires for test file editsFor blocking hooks (PreToolUse), use this pattern:
bash -c 'INPUT=$(cat); <extract relevant field with jq>; if <condition>; then echo "{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"deny\",\"permissionDecisionReason\":\"BLOCKED: <clear reason>\"}}"; fi'
For advisory hooks (PostToolUse), use this pattern:
bash -c 'INPUT=$(cat); <extract and check>; if <condition>; then echo "{\"hookSpecificOutput\":{\"hookEventName\":\"PostToolUse\",\"additionalContext\":\"WARNING: <advisory message>\"}}"; fi'
After writing the hook:
jq -e '.hooks' <settings-file>Even with a hook in place, save a feedback memory explaining:
This gives future sessions context for edge cases the hook might not catch.
Detection: User says "why did you deploy to prod?!"
Hook: PreToolUse on mcp__fleet__fleet_deploy:
{
"matcher": "mcp__fleet__fleet_deploy",
"hooks": [{
"type": "command",
"command": "bash -c 'INPUT=$(cat); APP=$(echo \"$INPUT\" | jq -r \".tool_input.app // empty\"); if [ \"$APP\" = \"my-app\" ]; then echo \"{\\\"hookSpecificOutput\\\":{\\\"hookEventName\\\":\\\"PreToolUse\\\",\\\"permissionDecision\\\":\\\"deny\\\",\\\"permissionDecisionReason\\\":\\\"BLOCKED: Production deploy requires explicit user instruction.\\\"}}\"; fi'"
}]
}
Detection: User says "don't add comments unless I ask"
Hook: PostToolUse on Write|Edit with advisory:
{
"matcher": "Write|Edit",
"hooks": [{
"type": "prompt",
"prompt": "Check if this edit added code comments (// or /* */) that weren't in the original. If comments were added that just explain what the code does (not complex logic), respond with JSON: {\"decision\": \"block\", \"reason\": \"Do not add explanatory comments unless the user asks.\"}. Otherwise allow. Input: $ARGUMENTS"
}]
}
Detection: User says "I told you not to use git add ."
Hook: PreToolUse on Bash with if filter:
{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": "bash -c 'INPUT=$(cat); CMD=$(echo \"$INPUT\" | jq -r \".tool_input.command // empty\"); if echo \"$CMD\" | grep -qE \"git\\s+add\\s+(-A|\\.)\\s*$\"; then echo \"{\\\"hookSpecificOutput\\\":{\\\"hookEventName\\\":\\\"PreToolUse\\\",\\\"permissionDecision\\\":\\\"deny\\\",\\\"permissionDecisionReason\\\":\\\"BLOCKED: Use specific file names with git add, never git add . or git add -A\\\"}}\"; fi'",
"if": "Bash(git add:*)"
}]
}
Some corrections are better as memories or CLAUDE.md rules:
When a correction falls into this category, say:
"This is more of a style/approach preference than a specific action I can block. I'll save it as a memory so I remember in future sessions. Want me to also add it to CLAUDE.md so it's enforced project-wide?"
For the full hook schema, event types, and advanced patterns, see:
${CLAUDE_PLUGIN_ROOT}/skills/behavior-hooks/references/hook-schema.md
npx claudepluginhub wrxck/claude-plugins --plugin behavior-hooksDetects repetitive user corrections across sessions and converts them into memory entries, validation hooks, enforcement patterns, or skills to automate recurring feedback.
Configures Claude Code hooks for lifecycle events like PreToolUse, SessionStart, and automation use cases such as formatting enforcement and permission control.
Guides creation and configuration of Claude Code plugin hooks for events like PreToolUse, PostToolUse, Stop, and SessionStart using prompt-based and command types.