docs: add missing hook events from official CHANGELOG (v2.1.9-v2.1.10)
- Add 3 missing events to Section 7.1: Setup, PermissionRequest, SubagentStop - Document PreToolUse additionalContext feature (v2.1.9+) - Create 3 production-ready hook templates (setup, permission, subagent) - Add resource evaluation documenting rejection of secondary source Source: Official Claude Code CHANGELOG, not external blog posts Closes gap identified during resource evaluation process Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
bd193cf73a
commit
edf74b38c5
5 changed files with 356 additions and 0 deletions
40
examples/hooks/bash/permission-request.sh
Executable file
40
examples/hooks/bash/permission-request.sh
Executable file
|
|
@ -0,0 +1,40 @@
|
|||
#!/bin/bash
|
||||
# permission-request.sh
|
||||
# Runs when permission dialog appears
|
||||
# Use for custom approval logic or logging
|
||||
|
||||
INPUT=$(cat)
|
||||
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // "unknown"')
|
||||
PERMISSION_TYPE=$(echo "$INPUT" | jq -r '.permission_type // "unknown"')
|
||||
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // "unknown"')
|
||||
|
||||
# Log permission request
|
||||
LOG_DIR="$HOME/.claude/logs"
|
||||
mkdir -p "$LOG_DIR"
|
||||
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
||||
|
||||
LOG_ENTRY=$(jq -n \
|
||||
--arg timestamp "$TIMESTAMP" \
|
||||
--arg tool "$TOOL_NAME" \
|
||||
--arg permission "$PERMISSION_TYPE" \
|
||||
--arg session "$SESSION_ID" \
|
||||
'{timestamp: $timestamp, tool: $tool, permission_type: $permission, session: $session}')
|
||||
|
||||
echo "$LOG_ENTRY" >> "$LOG_DIR/permissions-$(date +%Y-%m-%d).jsonl"
|
||||
|
||||
# Example: Auto-deny dangerous permissions in production
|
||||
if [[ "$PERMISSION_TYPE" == "file_write" ]] && [[ "$PWD" == *"/production"* ]]; then
|
||||
echo "BLOCKED: File write in production directory requires manual approval" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# Example: Warn about elevated permissions
|
||||
if [[ "$PERMISSION_TYPE" == "bash_sudo" ]]; then
|
||||
cat << EOF
|
||||
{
|
||||
"systemMessage": "⚠️ Warning: Tool requesting sudo permissions. Review carefully before approving."
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
||||
exit 0
|
||||
50
examples/hooks/bash/setup-init.sh
Executable file
50
examples/hooks/bash/setup-init.sh
Executable file
|
|
@ -0,0 +1,50 @@
|
|||
#!/bin/bash
|
||||
# setup-init.sh
|
||||
# Runs when Claude Code starts (v2.1.10+)
|
||||
# Use with --init, --init-only, or --maintenance flags
|
||||
|
||||
INPUT=$(cat)
|
||||
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // "unknown"')
|
||||
CWD=$(echo "$INPUT" | jq -r '.cwd // "unknown"')
|
||||
|
||||
# Create log directory if needed
|
||||
LOG_DIR="$HOME/.claude/logs"
|
||||
mkdir -p "$LOG_DIR"
|
||||
|
||||
# Log startup event
|
||||
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
||||
echo "[$TIMESTAMP] Setup hook triggered - Session: $SESSION_ID - CWD: $CWD" >> "$LOG_DIR/setup.log"
|
||||
|
||||
# Check project requirements
|
||||
if [[ -f "package.json" ]]; then
|
||||
# Check if node_modules exists
|
||||
if [[ ! -d "node_modules" ]]; then
|
||||
cat << EOF
|
||||
{
|
||||
"systemMessage": "⚠️ Project setup incomplete: node_modules missing. Run 'npm install' before continuing.",
|
||||
"hookSpecificOutput": {
|
||||
"additionalContext": "Node.js project detected without dependencies installed."
|
||||
}
|
||||
}
|
||||
EOF
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check git status
|
||||
if git rev-parse --git-dir > /dev/null 2>&1; then
|
||||
BRANCH=$(git branch --show-current)
|
||||
UNCOMMITTED=$(git status --short | wc -l | tr -d ' ')
|
||||
|
||||
if [[ $UNCOMMITTED -gt 0 ]]; then
|
||||
cat << EOF
|
||||
{
|
||||
"hookSpecificOutput": {
|
||||
"additionalContext": "Git status: On branch $BRANCH with $UNCOMMITTED uncommitted changes."
|
||||
}
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
fi
|
||||
|
||||
exit 0
|
||||
51
examples/hooks/bash/subagent-stop.sh
Executable file
51
examples/hooks/bash/subagent-stop.sh
Executable file
|
|
@ -0,0 +1,51 @@
|
|||
#!/bin/bash
|
||||
# subagent-stop.sh
|
||||
# Runs when a sub-agent completes
|
||||
# Use for cleanup, logging, or metrics
|
||||
|
||||
INPUT=$(cat)
|
||||
AGENT_NAME=$(echo "$INPUT" | jq -r '.agent_name // "unknown"')
|
||||
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // "unknown"')
|
||||
EXIT_CODE=$(echo "$INPUT" | jq -r '.exit_code // 0')
|
||||
DURATION=$(echo "$INPUT" | jq -r '.duration_ms // 0')
|
||||
|
||||
# Log subagent completion
|
||||
LOG_DIR="$HOME/.claude/logs"
|
||||
mkdir -p "$LOG_DIR"
|
||||
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
||||
|
||||
LOG_ENTRY=$(jq -n \
|
||||
--arg timestamp "$TIMESTAMP" \
|
||||
--arg agent "$AGENT_NAME" \
|
||||
--arg session "$SESSION_ID" \
|
||||
--argjson exit_code "$EXIT_CODE" \
|
||||
--argjson duration "$DURATION" \
|
||||
'{timestamp: $timestamp, agent: $agent, session: $session, exit_code: $exit_code, duration_ms: $duration}')
|
||||
|
||||
echo "$LOG_ENTRY" >> "$LOG_DIR/subagents-$(date +%Y-%m-%d).jsonl"
|
||||
|
||||
# Calculate duration in seconds for readability
|
||||
DURATION_SEC=$(echo "scale=2; $DURATION / 1000" | bc)
|
||||
|
||||
# Provide feedback on slow agents (>30 seconds)
|
||||
if [[ $(echo "$DURATION > 30000" | bc) -eq 1 ]]; then
|
||||
cat << EOF
|
||||
{
|
||||
"systemMessage": "⏱️ Subagent '$AGENT_NAME' took ${DURATION_SEC}s to complete. Consider optimizing or splitting into smaller tasks.",
|
||||
"hookSpecificOutput": {
|
||||
"additionalContext": "Subagent performance: $AGENT_NAME completed in ${DURATION_SEC}s"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
||||
# Alert on failed subagents
|
||||
if [[ $EXIT_CODE -ne 0 ]]; then
|
||||
cat << EOF
|
||||
{
|
||||
"systemMessage": "❌ Subagent '$AGENT_NAME' failed with exit code $EXIT_CODE. Review task output for errors."
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
||||
exit 0
|
||||
Loading…
Add table
Add a link
Reference in a new issue