enhance-hooks

Analyze hook definitions and scripts for safety, correctness, and best practices.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "enhance-hooks" with this command: npx skills add avifenesh/agentsys/avifenesh-agentsys-enhance-hooks

enhance-hooks

Analyze hook definitions and scripts for safety, correctness, and best practices.

Parse Arguments

const args = '$ARGUMENTS'.split(' ').filter(Boolean); const targetPath = args.find(a => !a.startsWith('--')) || '.'; const fix = args.includes('--fix');

Workflow

  • Discover - Find hook files (.md, .sh, .json)

  • Classify - Identify hook type and event

  • Parse - Extract frontmatter and script content

  • Check - Run all pattern checks against knowledge below

  • Filter - Apply certainty filtering

  • Report - Generate markdown output

  • Fix - Apply auto-fixes if --fix flag present

Hook Knowledge Reference

What Are Hooks

Hooks are automated actions triggered at specific points in a Claude Code session. They enable validation, monitoring, and control of Claude's actions through bash commands or LLM-based evaluation.

Hook Lifecycle (Complete Reference)

Hooks fire in this sequence:

Order Event Description Matcher Required

1 SessionStart

Session begins or resumes No

2 UserPromptSubmit

User submits a prompt No

3 PreToolUse

Before tool execution (can modify/block) Yes

4 PermissionRequest

When permission dialog appears Yes

5 PostToolUse

After tool succeeds Yes

6 SubagentStart

When spawning a subagent No

7 SubagentStop

When subagent finishes No

8 Stop

Claude finishes responding No

9 PreCompact

Before context compaction No

10 SessionEnd

Session terminates No

11 Notification

Claude Code sends notifications No

Hook Types

Command Hooks (type: "command" ):

  • Execute bash commands with full stdin/stdout control

  • Available for all events

Prompt Hooks (type: "prompt" ):

  • Use LLM evaluation for intelligent, context-aware decisions

  • Only supported for Stop and SubagentStop events

Configuration Locations

File Location Scope Committed

User settings ~/.claude/settings.json

All projects No

Project settings .claude/settings.json

Current project Yes

Local settings .claude/settings.local.json

Current project No

Configuration Structure

{ "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": ".claude/hooks/validate-bash.sh", "timeout": 30 } ] } ], "PostToolUse": [ { "matcher": "Write|Edit", "hooks": [ { "type": "command", "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/format-code.sh" } ] } ], "Stop": [ { "hooks": [ { "type": "prompt", "prompt": "Check if all requested tasks are complete.", "timeout": 30 } ] } ] } }

Matcher Syntax

Pattern Description

Write

Match exact tool name

Edit|Write

Match multiple tools (regex OR)

Notebook.*

Regex pattern matching

or ""

Match all tools

(omitted) Required for Stop, SubagentStop, UserPromptSubmit

Input Schema (JSON via stdin)

All hooks receive this JSON structure:

{ "session_id": "abc123", "transcript_path": "/path/to/transcript", "cwd": "/project/root", "permission_mode": "default", "hook_event_name": "PreToolUse", "tool_name": "Bash", "tool_input": { "command": "npm test", "description": "Run test suite" } }

Exit Codes

Exit Code Behavior

0 Success - stdout shown to user or added as context

2 Blocking error - stderr shown, action blocked

Other Non-blocking error - stderr shown in verbose mode

Output Schemas

PreToolUse Decision Control:

{ "hookSpecificOutput": { "hookEventName": "PreToolUse", "permissionDecision": "allow|deny|ask", "permissionDecisionReason": "Reason for decision", "updatedInput": { "command": "modified command" }, "additionalContext": "Context for Claude" } }

Stop/SubagentStop Control:

{ "decision": "block", "reason": "Tasks incomplete: missing test coverage" }

Environment Variables

Variable Description Available In

CLAUDE_PROJECT_DIR

Absolute path to project root All hooks

CLAUDE_CODE_REMOTE

"true" if remote session All hooks

CLAUDE_ENV_FILE

Path to persist env vars SessionStart only

CLAUDE_FILE_PATHS

Space-separated file paths PostToolUse (Write/Edit)

Practical Hook Examples

Security Firewall (PreToolUse):

#!/usr/bin/env bash set -euo pipefail

cmd=$(jq -r '.tool_input.command // ""')

Block dangerous patterns

if echo "$cmd" | grep -qE 'rm -rf|git reset --hard|curl.*|.*sh'; then echo '{"decision": "block", "reason": "Dangerous command blocked"}' >&2 exit 2 fi

exit 0

Auto-Formatter (PostToolUse):

#!/usr/bin/env bash set -euo pipefail

files=$(jq -r '.tool_input.file_path // ""')

for file in $files; do case "$file" in *.py) black "$file" 2>/dev/null || true ;; .js|.ts) prettier --write "$file" 2>/dev/null || true ;; esac done

exit 0

Command Logger (PreToolUse):

#!/usr/bin/env bash set -euo pipefail cmd=$(jq -r '.tool_input.command // ""') printf '%s %s\n' "$(date -Is)" "$cmd" >> .claude/bash-commands.log exit 0

Workflow Orchestration (SubagentStop - prompt type):

{ "hooks": { "SubagentStop": [ { "hooks": [ { "type": "prompt", "prompt": "Review the subagent's work. Did it complete all tasks?" } ] } ] } }

Detection Patterns

  1. Frontmatter Validation (HIGH Certainty)

Required:

  • YAML frontmatter with --- delimiters

  • name field in frontmatter

  • description field in frontmatter

Recommended:

  • timeout for command hooks (default: 30s)

  • Hook type specification

Flag:

  • Missing frontmatter delimiters

  • Missing name or description

  1. Script Safety (HIGH Certainty)

Required Safety Patterns:

  • set -euo pipefail at script start

  • Error handling for jq/JSON parsing

  • Proper quoting of variables

Dangerous Patterns to Flag:

Pattern Risk Certainty

rm -rf

Destructive without confirmation HIGH

git reset --hard

Data loss risk HIGH

curl | sh

Remote code execution HIGH

eval "$input"

Arbitrary code execution HIGH

rm -r

Recursive delete (may be intentional) MEDIUM

git push --force

Force push (may be intentional) MEDIUM

  1. Exit Code Handling (HIGH Certainty)

Check: Scripts use correct exit codes

Flag:

  • Missing exit 0 for success path

  • Using exit code 1 for blocking (should be 2)

  • No exit code at end of script

  1. Hook Type Appropriateness (HIGH Certainty)

Check: Hook type matches event

Flag:

  • Prompt hooks used for events other than Stop/SubagentStop

  • Missing type specification

  1. Lifecycle Event Appropriateness (MEDIUM Certainty)

Event Appropriate Use Cases

PreToolUse

Security validation, command blocking, input modification

PostToolUse

Formatting, logging, notifications

Stop

Completion checks, cleanup, summary

SubagentStop

Workflow orchestration, result validation

SessionStart

Environment setup, initialization

Flag:

  • PostToolUse hooks trying to block actions (too late)

  • PreToolUse hooks doing heavy processing (should be fast)

  • Prompt hooks on unsupported events

  1. Timeout Configuration (MEDIUM Certainty)

Guidelines:

  • Default: 30 seconds for command hooks

  • Network operations: Always set explicit timeout

  • External service calls: Set timeout based on expected latency

Flag:

  • No timeout for network operations

  • Timeout missing for external service calls

  • Unreasonably long timeouts (>60s without justification)

  1. Output Format (MEDIUM Certainty)

PreToolUse Output Fields:

  • permissionDecision : allow, deny, or ask

  • permissionDecisionReason : Explanation for decision

  • updatedInput : Modified tool input (optional)

  • additionalContext : Context for Claude (optional)

Flag:

  • Invalid permissionDecision values

  • Missing reason for deny decisions

  • Malformed JSON output

  1. Matcher Patterns (MEDIUM Certainty)

Check: Matcher syntax is valid

Flag:

  • Invalid regex patterns

  • Too broad matchers (* without justification)

  • Matcher on events that don't support it (Stop, SubagentStop)

  1. Anti-Patterns (LOW Certainty)
  • Complex logic in hooks (should be simple and fast)

  • Missing documentation/comments

  • Hardcoded paths (should use $CLAUDE_PROJECT_DIR )

  • Network calls without error handling

  • Secrets/credentials in hook scripts

Auto-Fix Implementations

  1. Missing safety header

#!/usr/bin/env bash set -euo pipefail

  1. Missing exit code

Add exit 0 at end of script

  1. Missing frontmatter fields

name: hook-name description: Hook description timeout: 30

  1. Wrong blocking exit code

Replace exit 1 with exit 2 for blocking errors

Output Format

Hook Analysis: {hook-name}

File: {path} Type: {command|prompt|config} Event: {PreToolUse|PostToolUse|Stop|...}

Summary

  • HIGH: {count} issues
  • MEDIUM: {count} issues

Frontmatter Issues ({n})

| Issue | Fix | Certainty |

Safety Issues ({n})

| Issue | Fix | Certainty |

Exit Code Issues ({n})

| Issue | Fix | Certainty |

Lifecycle Issues ({n})

| Issue | Fix | Certainty |

Output Format Issues ({n})

| Issue | Fix | Certainty |

Pattern Statistics

Category Patterns Auto-Fixable

Frontmatter 3 2

Safety 6 2

Exit Code 3 2

Hook Type 2 0

Lifecycle 5 0

Timeout 3 0

Output 3 0

Matcher 3 0

Anti-Pattern 5 0

Total 33 6

<bad_example>

#!/usr/bin/env bash cmd=$(jq -r '.tool_input.command // ""')

Why it's bad: Missing set -euo pipefail means errors may silently pass. </bad_example>

<good_example>

#!/usr/bin/env bash set -euo pipefail cmd=$(jq -r '.tool_input.command // ""')

Why it's good: Fails fast on errors, unset variables, and pipe failures. </good_example>

Example: Wrong Exit Code for Blocking

<bad_example>

if [[ "$cmd" == "rm -rf" ]]; then echo "Blocked dangerous command" >&2 exit 1 # Wrong! fi

Why it's bad: Exit code 1 is non-blocking. Action will still proceed. </bad_example>

<good_example>

if [[ "$cmd" == "rm -rf" ]]; then echo '{"decision": "block", "reason": "Dangerous command"}' >&2 exit 2 # Correct blocking exit code fi

Why it's good: Exit code 2 blocks the action. JSON output provides context. </good_example>

Example: Prompt Hook on Wrong Event

<bad_example>

{ "hooks": { "PreToolUse": [ { "hooks": [{ "type": "prompt", "prompt": "Is this safe?" }] } ] } }

Why it's bad: Prompt hooks only work for Stop and SubagentStop events. </bad_example>

<good_example>

{ "hooks": { "PreToolUse": [ { "hooks": [{ "type": "command", "command": "./validate.sh" }] } ] } }

Why it's good: Command hooks work for all events. </good_example>

Example: Dangerous Command Pattern

<bad_example>

if echo "$cmd" | grep -q 'rm'; then exit 2 fi

Why it's bad: Too broad - blocks legitimate rm file.tmp . </bad_example>

<good_example>

if echo "$cmd" | grep -qE 'rm\s+(-rf|-fr)\s+/'; then exit 2 fi

Why it's good: Specific pattern targets actual dangerous commands. </good_example>

Example: Hardcoded Path

<bad_example>

log_file="/home/user/project/.claude/commands.log"

Why it's bad: Hardcoded path breaks on other machines. </bad_example>

<good_example>

log_file="$CLAUDE_PROJECT_DIR/.claude/commands.log"

Why it's good: Uses environment variable for portability. </good_example>

Constraints

  • Only apply auto-fixes for HIGH certainty issues

  • Be cautious about security patterns - false negatives worse than false positives

  • Never remove content, only suggest improvements

  • Validate against embedded knowledge reference above

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

agnix

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

consult

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

debate

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

validate-delivery

No summary provided by upstream source.

Repository SourceNeeds Review