Move pre-compact hook into repo with HOOKS.md documentation
Hook source of truth now in hooks/, symlinked from ~/.claude/hooks/. HOOKS.md covers what each hook does and installation steps. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
50
HOOKS.md
Normal file
50
HOOKS.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# Hooks
|
||||
|
||||
Claude Code hooks that run automatically in response to events. Source of truth lives here; symlinks point from `~/.claude/hooks/` back to this directory.
|
||||
|
||||
## Available Hooks
|
||||
|
||||
| Hook | Event | File |
|
||||
|------|-------|------|
|
||||
| Pre-compact backup | PreCompact (auto + manual) | `hooks/pre-compact-backup.sh` |
|
||||
|
||||
## Pre-compact Backup
|
||||
|
||||
Saves a copy of the session transcript before context compaction so no conversation history is lost. Backs up to `~/.claude/transcript-backups/` with timestamped filenames. Auto-prunes backups older than 30 days.
|
||||
|
||||
**Triggers:** Both auto-compaction (context window full) and manual (`/compact` command).
|
||||
|
||||
**Requires:** `python3` (for JSON parsing from stdin).
|
||||
|
||||
## Installation
|
||||
|
||||
1. Symlink each hook into `~/.claude/hooks/`:
|
||||
```bash
|
||||
mkdir -p ~/.claude/hooks
|
||||
ln -sf "$(pwd)/hooks/pre-compact-backup.sh" ~/.claude/hooks/pre-compact-backup.sh
|
||||
```
|
||||
|
||||
2. Add the hook configuration to `~/.claude/settings.json`:
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"PreCompact": [
|
||||
{
|
||||
"matcher": "auto",
|
||||
"hooks": [{ "type": "command", "command": "~/.claude/hooks/pre-compact-backup.sh", "timeout": 15 }]
|
||||
},
|
||||
{
|
||||
"matcher": "manual",
|
||||
"hooks": [{ "type": "command", "command": "~/.claude/hooks/pre-compact-backup.sh", "timeout": 15 }]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Adding New Hooks
|
||||
|
||||
1. Create the script in `hooks/`
|
||||
2. Add an entry to this file
|
||||
3. Symlink into `~/.claude/hooks/`
|
||||
4. Add the matcher config to `~/.claude/settings.json`
|
||||
30
hooks/pre-compact-backup.sh
Executable file
30
hooks/pre-compact-backup.sh
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env bash
|
||||
# Pre-compact hook: save a copy of the session transcript before compaction.
|
||||
# Claude Code pipes JSON to stdin with session_id, transcript_path, cwd, etc.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Parse stdin JSON for transcript path and session ID
|
||||
INPUT="$(cat)"
|
||||
TRANSCRIPT_PATH="$(echo "$INPUT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('transcript_path',''))" 2>/dev/null)"
|
||||
SESSION_ID="$(echo "$INPUT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('session_id',''))" 2>/dev/null)"
|
||||
TRIGGER="$(echo "$INPUT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('trigger','unknown'))" 2>/dev/null)"
|
||||
|
||||
if [ -z "$TRANSCRIPT_PATH" ] || [ ! -f "$TRANSCRIPT_PATH" ]; then
|
||||
echo "pre-compact-backup: no transcript found, skipping" >&2
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Save to ~/.claude/transcript-backups/ with timestamp
|
||||
BACKUP_DIR="$HOME/.claude/transcript-backups"
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
TIMESTAMP="$(date +%Y%m%d-%H%M%S)"
|
||||
BACKUP_FILE="${BACKUP_DIR}/${TIMESTAMP}-${SESSION_ID:0:8}-${TRIGGER}.jsonl"
|
||||
|
||||
cp "$TRANSCRIPT_PATH" "$BACKUP_FILE"
|
||||
|
||||
# Prune backups older than 30 days
|
||||
find "$BACKUP_DIR" -name "*.jsonl" -mtime +30 -delete 2>/dev/null || true
|
||||
|
||||
echo "pre-compact-backup: saved $(wc -l < "$BACKUP_FILE") lines to ${BACKUP_FILE##*/}" >&2
|
||||
Reference in New Issue
Block a user