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.
インストール方法を見るインストールする前に、エージェントに与えられる指示の中身を確認できます。
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.
日本語の概要は準備中です。原文の説明を表示しています。