Files
claude-code/hooks/scripts/session-end.sh
OpenCode Test ecf375205f Implement guardrail hooks for dangerous operation prevention
- Add PreToolUse hook intercepting Bash, Write, Edit
- Block catastrophic commands (rm -rf /, mkfs, etc.)
- Require confirmation for operations outside safe paths
- Git-aware: operations in git repos are allowed
- Session allowlist for user-confirmed operations
- Audit logging to logs/guardrail.jsonl
- Clear session allowlist on SessionEnd

Config: state/guardrails.json
Scripts: hooks/scripts/guardrail.py, guardrail-confirm.py

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 10:57:53 -08:00

62 lines
2.1 KiB
Bash
Executable File

#!/bin/bash
# Session end hook - triggers summarization of the conversation
# Receives JSON via stdin with session_id, transcript_path, reason
#
# Uses Claude CLI with subscription credentials for LLM extraction.
# Heuristic extraction (paths, facts) always runs.
# LLM extraction (decisions, preferences) runs if claude CLI is available.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LOG_FILE="${HOME}/.claude/logs/session-end.log"
# Ensure log directory exists
mkdir -p "$(dirname "$LOG_FILE")"
log() {
echo "[$(date -Iseconds)] $*" >> "$LOG_FILE"
}
# Read JSON input from stdin
INPUT=$(cat)
# Parse JSON fields
SESSION_ID=$(echo "$INPUT" | python3 -c "import sys, json; print(json.load(sys.stdin).get('session_id', ''))" 2>/dev/null || echo "")
TRANSCRIPT_PATH=$(echo "$INPUT" | python3 -c "import sys, json; print(json.load(sys.stdin).get('transcript_path', ''))" 2>/dev/null || echo "")
REASON=$(echo "$INPUT" | python3 -c "import sys, json; print(json.load(sys.stdin).get('reason', ''))" 2>/dev/null || echo "")
log "SessionEnd triggered: session=$SESSION_ID reason=$REASON"
# Clear guardrail session allowlist (confirmations don't persist across sessions)
GUARDRAIL_SESSION="${HOME}/.claude/state/guardrail-session.json"
if [[ -f "$GUARDRAIL_SESSION" ]]; then
rm -f "$GUARDRAIL_SESSION"
log "Cleared guardrail session allowlist"
fi
# Validate required fields
if [[ -z "$SESSION_ID" || -z "$TRANSCRIPT_PATH" ]]; then
log "ERROR: Missing session_id or transcript_path"
exit 0 # Exit cleanly - don't break session exit
fi
# Check if transcript exists
if [[ ! -f "$TRANSCRIPT_PATH" ]]; then
log "ERROR: Transcript not found at $TRANSCRIPT_PATH"
exit 0
fi
# Run summarization script in background to not block session exit
# The script will handle its own error logging
nohup python3 "${SCRIPT_DIR}/summarize-transcript.py" \
--session-id "$SESSION_ID" \
--transcript "$TRANSCRIPT_PATH" \
--reason "$REASON" \
>> "$LOG_FILE" 2>&1 &
log "Summarization started in background (PID: $!)"
# Return success - don't block session exit
exit 0