Complete methodology for preventing AI hallucinations. Use when accuracy is critical and you need Claude to verify before claiming, cite before asserting, and admit uncertainty instead of guessing.
中文简介正在准备中。当前显示原文说明。
Use this skill when asked about "hooks", "PreToolUse", "PostToolUse", "SessionStart", "hook events", "validate tool use", "block commands", "add context on session start", or implementing event-driven automation.
中文简介正在准备中。当前显示原文说明。
查看安装方法安装前可以查看交给 AI 代理的指令内容。
This skill provides comprehensive guidance for implementing Claude Code hooks - event handlers that automate validation, context loading, and workflow enforcement.
| Event | When Triggered | Use Cases |
|---|---|---|
PreToolUse | Before tool executes | Validate, block, modify |
PostToolUse | After tool completes | Audit, react, verify |
PermissionRequest | Permission dialog shown | Auto-allow, auto-deny |
Stop | Claude finishes | Force continue, verify |
SubagentStop | Subagent finishes | Verify task complete |
SessionStart | Session begins | Load context, setup |
SessionEnd | Session ends | Cleanup, save state |
UserPromptSubmit | Prompt submitted | Validate, add context |
PreCompact | Before compaction | Preserve info |
Notification | Notification sent | Alert, log |
Basic structure:
{
"description": "What these hooks do",
"hooks": {
"EventName": [
{
"matcher": "Pattern",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/handler.sh",
"timeout": 30
}
]
}
]
}
}
For tool events (PreToolUse, PostToolUse, PermissionRequest):
"Write" - Match exact tool name"Write|Edit" - Match multiple tools (regex)"Notebook.*" - Regex pattern"*" or "" - Match all toolsFor SessionStart:
"startup" - Initial startup"resume" - From --resume, --continue, /resume"clear" - From /clear"compact" - From auto/manual compactFor Notification:
"permission_prompt" - Permission requests"idle_prompt" - Claude waiting for inputExecute a bash script:
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/validate.sh",
"timeout": 30
}
LLM-based evaluation (Stop, SubagentStop only):
{
"type": "prompt",
"prompt": "Evaluate if Claude should stop: $ARGUMENTS. Check if all tasks are complete.",
"timeout": 30
}
| Exit Code | Meaning | Behavior |
|---|---|---|
| 0 | Success | Action proceeds, stdout to user (verbose) |
| 2 | Block | Action blocked, stderr shown to Claude |
| Other | Error | Non-blocking, stderr to user (verbose) |
Common fields:
{
"session_id": "abc123",
"transcript_path": "/path/to/transcript.jsonl",
"cwd": "/current/working/directory",
"permission_mode": "default",
"hook_event_name": "PreToolUse"
}
PreToolUse specific:
{
"tool_name": "Write",
"tool_input": {
"file_path": "/path/to/file.txt",
"content": "file content"
},
"tool_use_id": "toolu_01ABC..."
}
SessionStart specific:
{
"source": "startup"
}
Stop specific:
{
"stop_hook_active": false
}
Return structured decisions via stdout (exit code 0):
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "allow",
"permissionDecisionReason": "Auto-approved documentation file",
"updatedInput": {
"field_to_modify": "new value"
}
}
}
Decision values: "allow", "deny", "ask"
{
"decision": "block",
"reason": "Not all tasks complete - still need to run tests"
}
{
"hookSpecificOutput": {
"hookEventName": "UserPromptSubmit",
"additionalContext": "Current time: 2024-01-15 10:30:00"
}
}
{
"hookSpecificOutput": {
"hookEventName": "SessionStart",
"additionalContext": "Project context loaded..."
}
}
hooks/hooks.json:
{
"description": "Validate file write operations",
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/validate-write.sh",
"timeout": 30
}
]
}
]
}
}
scripts/validate-write.sh:
#!/usr/bin/env bash
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.filePath // empty')
# Block writes to sensitive files
if [[ "$FILE_PATH" == *.env* ]] || [[ "$FILE_PATH" == *secret* ]]; then
echo "Cannot write to sensitive files: $FILE_PATH" >&2
exit 2
fi
# Block writes outside project
if [[ ! "$FILE_PATH" == "$CLAUDE_PROJECT_DIR"* ]]; then
echo "Cannot write outside project directory" >&2
exit 2
fi
exit 0
hooks/hooks.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/validate-bash.sh"
}
]
}
]
}
}
scripts/validate-bash.sh:
#!/usr/bin/env bash
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')
# Block destructive commands
DANGEROUS_PATTERNS=(
"rm -rf /"
"rm -rf ~"
":(){ :|:& };:"
"> /dev/sda"
)
for pattern in "${DANGEROUS_PATTERNS[@]}"; do
if [[ "$COMMAND" == *"$pattern"* ]]; then
echo "Blocked dangerous command pattern: $pattern" >&2
exit 2
fi
done
exit 0
hooks/hooks.json:
{
"hooks": {
"SessionStart": [
{
"matcher": "startup|resume",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/load-context.sh"
}
]
}
]
}
}
scripts/load-context.sh:
#!/usr/bin/env bash
CONTEXT=""
# Load CLAUDE.md if exists
if [ -f "$CLAUDE_PROJECT_DIR/CLAUDE.md" ]; then
CONTEXT+="Project instructions from CLAUDE.md have been loaded.\n"
fi
# Add git status
if [ -d "$CLAUDE_PROJECT_DIR/.git" ]; then
BRANCH=$(git -C "$CLAUDE_PROJECT_DIR" branch --show-current 2>/dev/null)
CONTEXT+="Current git branch: $BRANCH\n"
fi
# Output as JSON for structured context
cat << EOF
{
"hookSpecificOutput": {
"hookEventName": "SessionStart",
"additionalContext": "$CONTEXT"
}
}
EOF
exit 0
Using prompt-based hook:
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "prompt",
"prompt": "Evaluate if Claude should stop. Context: $ARGUMENTS\n\nCheck if:\n1. All requested tasks are complete\n2. No errors need addressing\n3. No tests need running\n\nRespond with: {\"decision\": \"approve\" or \"block\", \"reason\": \"explanation\"}"
}
]
}
]
}
}
hooks/hooks.json:
{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/add-timestamp.sh"
}
]
}
]
}
}
scripts/add-timestamp.sh:
#!/usr/bin/env bash
# Plain text stdout is added as context
echo "Current time: $(date '+%Y-%m-%d %H:%M:%S %Z')"
exit 0
Available in hooks:
${CLAUDE_PLUGIN_ROOT} - Absolute path to plugin directory$CLAUDE_PROJECT_DIR - Project root directory$CLAUDE_ENV_FILE - (SessionStart only) File to persist env vars$CLAUDE_CODE_REMOTE - "true" if running in web environment#!/usr/bin/env bash
if [ -n "$CLAUDE_ENV_FILE" ]; then
echo 'export NODE_ENV=development' >> "$CLAUDE_ENV_FILE"
echo 'export API_URL=http://localhost:3000' >> "$CLAUDE_ENV_FILE"
fi
exit 0
"$VAR" not $VAR${CLAUDE_PLUGIN_ROOT} for plugin files// emptyEnable debug mode:
claude --debug
Test hook manually:
echo '{"tool_name":"Write","tool_input":{"file_path":"test.txt"}}' | \
./scripts/validate-write.sh
echo $? # Check exit code
还没有评价。欢迎分享你的使用感受。
无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。
还没有评论。来写第一条吧。
Complete methodology for preventing AI hallucinations. Use when accuracy is critical and you need Claude to verify before claiming, cite before asserting, and admit uncertainty instead of guessing.
中文简介正在准备中。当前显示原文说明。
Transform rough ideas into solid designs through structured questioning
中文简介正在准备中。当前显示原文说明。
Canvas API Connection Skill
中文简介正在准备中。当前显示原文说明。
Forces every code-related claim to include file:line citations. No citation means the claim must be verified or removed. Use when building documentation, writing code reviews, or any output that others will rely on.
中文简介正在准备中。当前显示原文说明。
Assign confidence scores (0-100) to every claim in a response. Helps users understand which parts are verified facts and which are educated guesses. Use when the user needs to know how much to trust each part of the answer.
中文简介正在准备中。当前显示原文说明。
Forces Claude to extract exact quotes from files before making claims about them. Prevents hallucinations by grounding every statement in actual text from the codebase. Use when working with large files or unfamiliar code.
中文简介正在准备中。当前显示原文说明。