Enhance hooks with session-start script and documentation
- Add hooks/scripts/session-start.sh that: - Checks for unsummarized sessions - Checks for pending decisions - Outputs context to session - Update hooks.json to use the script - Add hooks/README.md documenting hook events and configuration This provides automatic context loading at session start. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
73
hooks/README.md
Normal file
73
hooks/README.md
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
# Hooks
|
||||||
|
|
||||||
|
Event handlers that run automatically during Claude Code sessions.
|
||||||
|
|
||||||
|
## Active Hooks
|
||||||
|
|
||||||
|
| Event | Script | Purpose |
|
||||||
|
|-------|--------|---------|
|
||||||
|
| `SessionStart` | `scripts/session-start.sh` | Load context, check for pending items |
|
||||||
|
|
||||||
|
## Hook Events
|
||||||
|
|
||||||
|
| Event | When It Fires |
|
||||||
|
|-------|---------------|
|
||||||
|
| `SessionStart` | When Claude Code session begins |
|
||||||
|
| `SessionEnd` | When session ends |
|
||||||
|
| `PreToolUse` | Before a tool is used |
|
||||||
|
| `PostToolUse` | After a tool is used |
|
||||||
|
| `UserPromptSubmit` | When user submits a prompt |
|
||||||
|
| `PreCompact` | Before context compaction |
|
||||||
|
| `Notification` | When notification is sent |
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Hooks are defined in `hooks.json`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"hooks": {
|
||||||
|
"SessionStart": [
|
||||||
|
{
|
||||||
|
"hooks": [
|
||||||
|
{
|
||||||
|
"type": "command",
|
||||||
|
"command": "~/.claude/hooks/scripts/session-start.sh"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Adding Hooks
|
||||||
|
|
||||||
|
1. Create script in `scripts/`
|
||||||
|
2. Make executable: `chmod +x scripts/your-hook.sh`
|
||||||
|
3. Add to `hooks.json`
|
||||||
|
4. Restart Claude Code
|
||||||
|
|
||||||
|
## Script Output
|
||||||
|
|
||||||
|
- Stdout is injected into session as context
|
||||||
|
- Use format: `HookName:Callback hook success: Success`
|
||||||
|
- Additional context: `HookName hook additional context: <message>`
|
||||||
|
|
||||||
|
## Matchers (for Tool Hooks)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"matcher": "Write|Edit",
|
||||||
|
"hooks": [...]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Matches tool names with regex pattern.
|
||||||
|
|
||||||
|
## Tips
|
||||||
|
|
||||||
|
- Keep hooks fast (<1s) to avoid delays
|
||||||
|
- Use `set -euo pipefail` for safety
|
||||||
|
- Output useful context, not noise
|
||||||
|
- Test hooks manually before adding
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "echo 'SessionStart:Callback hook success: Success'"
|
"command": "~/.claude/hooks/scripts/session-start.sh"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
47
hooks/scripts/session-start.sh
Executable file
47
hooks/scripts/session-start.sh
Executable file
@@ -0,0 +1,47 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Session start hook - provides context to Claude
|
||||||
|
# Output is injected into the session as a system reminder
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
CLAUDE_DIR="${HOME}/.claude"
|
||||||
|
STATE_DIR="${CLAUDE_DIR}/state"
|
||||||
|
PA_DIR="${STATE_DIR}/personal-assistant"
|
||||||
|
|
||||||
|
# Check for unsummarized sessions
|
||||||
|
UNSUMMARIZED=0
|
||||||
|
if [[ -f "${PA_DIR}/history/index.json" ]]; then
|
||||||
|
UNSUMMARIZED=$(python3 -c "
|
||||||
|
import json
|
||||||
|
with open('${PA_DIR}/history/index.json') as f:
|
||||||
|
data = json.load(f)
|
||||||
|
unsummarized = [s for s in data.get('sessions', []) if not s.get('summarized', False)]
|
||||||
|
print(len(unsummarized))
|
||||||
|
" 2>/dev/null || echo "0")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for pending memory items
|
||||||
|
PENDING_DECISIONS=0
|
||||||
|
if [[ -f "${PA_DIR}/memory/decisions.json" ]]; then
|
||||||
|
PENDING_DECISIONS=$(python3 -c "
|
||||||
|
import json
|
||||||
|
with open('${PA_DIR}/memory/decisions.json') as f:
|
||||||
|
data = json.load(f)
|
||||||
|
pending = [d for d in data.get('items', []) if d.get('status') == 'pending']
|
||||||
|
print(len(pending))
|
||||||
|
" 2>/dev/null || echo "0")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Output context as system reminder format
|
||||||
|
echo "SessionStart:Callback hook success: Success"
|
||||||
|
|
||||||
|
# Add additional context if there's something noteworthy
|
||||||
|
if [[ "${UNSUMMARIZED}" -gt 0 || "${PENDING_DECISIONS}" -gt 0 ]]; then
|
||||||
|
echo "SessionStart hook additional context: "
|
||||||
|
if [[ "${UNSUMMARIZED}" -gt 0 ]]; then
|
||||||
|
echo "- ${UNSUMMARIZED} unsummarized session(s) available for review"
|
||||||
|
fi
|
||||||
|
if [[ "${PENDING_DECISIONS}" -gt 0 ]]; then
|
||||||
|
echo "- ${PENDING_DECISIONS} pending decision(s) to review"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
Reference in New Issue
Block a user