คู่มือ Hooks ของ Claude Code
รัน shell commands โดยอัตโนมัติเมื่อ Claude Code แก้ไขไฟล์, เสร็จงาน หรือต้องการ input จัดรูปแบบโค้ด, ส่งการแจ้งเตือน, ตรวจสอบคำสั่ง และ enforce project rules
Hooks คือ shell commands ที่ผู้ใช้กำหนด ซึ่งทำงาน ณ จุดเฉพาะใน lifecycle ของ Claude Code ให้การควบคุมแบบ deterministic เหนือพฤติกรรมของ Claude Code เพื่อให้มั่นใจว่า actions บางอย่างจะเกิดขึ้นเสมอ แทนที่จะพึ่งให้ LLM เลือกที่จะรัน
ตั้งค่า Hook แรกของคุณ
เพื่อสร้าง hook ให้เพิ่ม hooks block ใน settings file เดินตามขั้นตอนนี้เพื่อสร้าง desktop notification hook:
ขั้นตอนที่ 1: เพิ่ม hook ใน settings
เปิด ~/.claude/settings.json และเพิ่ม Notification hook:
{
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"Claude Code needs your attention\" with title \"Claude Code\"'"
}
]
}
]
}
}
ขั้นตอนที่ 2: ตรวจสอบ configuration
พิมพ์ /hooks เพื่อเปิด hooks browser คุณจะเห็นรายการ hook events ที่มีอยู่ทั้งหมด
ขั้นตอนที่ 3: ทดสอบ hook
กด Esc เพื่อกลับไปที่ CLI ขอให้ Claude ทำอะไรที่ต้องการสิทธิ์ แล้วสลับออกจาก terminal คุณควรได้รับ desktop notification
สิ่งที่สามารถทำ Automation ได้
รับการแจ้งเตือนเมื่อ Claude ต้องการ Input
รับ desktop notification เมื่อ Claude เสร็จงานและรอ input ของคุณ:
macOS:
{
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"Claude Code needs your attention\" with title \"Claude Code\"'"
}
]
}
]
}
}
Linux:
{
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "notify-send 'Claude Code' 'Claude Code needs your attention'"
}
]
}
]
}
}
Auto-format Code หลังการแก้ไข
รัน Prettier อัตโนมัติบนทุกไฟล์ที่ Claude แก้ไข:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path' | xargs npx prettier --write"
}
]
}
]
}
}
บล็อคการแก้ไขไฟล์ที่ได้รับการป้องกัน
ป้องกัน Claude จากการแก้ไขไฟล์ sensitive เช่น .env, package-lock.json หรืออะไรก็ตามใน .git/:
สร้าง script ที่ .claude/hooks/protect-files.sh:
#!/bin/bash
# protect-files.sh
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
PROTECTED_PATTERNS=(".env" "package-lock.json" ".git/")
for pattern in "${PROTECTED_PATTERNS[@]}"; do
if [[ "$FILE_PATH" == *"$pattern"* ]]; then
echo "Blocked: $FILE_PATH matches protected pattern '$pattern'" >&2
exit 2
fi
done
exit 0
ลงทะเบียน hook:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/protect-files.sh"
}
]
}
]
}
}
Re-inject Context หลัง Compaction
ใช้ SessionStart hook กับ compact matcher เพื่อ re-inject context สำคัญหลังจาก compaction:
{
"hooks": {
"SessionStart": [
{
"matcher": "compact",
"hooks": [
{
"type": "command",
"command": "echo 'Reminder: use Bun, not npm. Run bun test before committing. Current sprint: auth refactor.'"
}
]
}
]
}
}
Auto-approve Permission Prompts ที่เฉพาะเจาะจง
ข้ามการ confirm dialog สำหรับ tool calls ที่คุณอนุญาตเสมอ:
{
"hooks": {
"PermissionRequest": [
{
"matcher": "ExitPlanMode",
"hooks": [
{
"type": "command",
"command": "echo '{\"hookSpecificOutput\": {\"hookEventName\": \"PermissionRequest\", \"decision\": {\"behavior\": \"allow\"}}}'"
}
]
}
]
}
}
วิธีการทำงานของ Hooks
Hook Events
| Event | เมื่อไหร่ที่ทำงาน |
|---|---|
SessionStart | เมื่อ session เริ่มต้นหรือ resume |
UserPromptSubmit | เมื่อคุณส่ง prompt |
PreToolUse | ก่อน tool call ทำงาน สามารถบล็อคได้ |
PermissionRequest | เมื่อ permission dialog ปรากฏ |
PostToolUse | หลัง tool call สำเร็จ |
Notification | เมื่อ Claude Code ส่งการแจ้งเตือน |
Stop | เมื่อ Claude เสร็จการตอบสนอง |
ConfigChange | เมื่อ configuration file เปลี่ยนแปลง |
CwdChanged | เมื่อ working directory เปลี่ยน |
FileChanged | เมื่อไฟล์ที่ watch เปลี่ยนแปลง |
SessionEnd | เมื่อ session สิ้นสุด |
Hook Types
"type": "command"- รัน shell command"type": "http"- POST event data ไปยัง URL"type": "mcp_tool"- เรียก tool บน MCP server"type": "prompt"- single-turn LLM evaluation"type": "agent"- multi-turn verification พร้อม tool access
Exit Codes
- Exit 0: ไม่มีการคัดค้าน การดำเนินการดำเนินต่อตามปกติ
- Exit 2: การดำเนินการถูกบล็อค เขียน reason ไปที่ stderr
- Exit อื่น ๆ: การดำเนินการดำเนินต่อ แต่แสดง error notice
Prompt-based Hooks
สำหรับ decisions ที่ต้องการการตัดสินใจแทน deterministic rules ใช้ type: "prompt" hooks:
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "prompt",
"prompt": "Check if all tasks are complete. If not, respond with {\"ok\": false, \"reason\": \"what remains to be done\"}."
}
]
}
]
}
}
Agent-based Hooks
เมื่อการตรวจสอบต้องการการ inspect ไฟล์หรือรัน commands ใช้ type: "agent" hooks:
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "agent",
"prompt": "Verify that all unit tests pass. Run the test suite and check the results.",
"timeout": 120
}
]
}
]
}
}
HTTP Hooks
POST event data ไปยัง HTTP endpoint:
{
"hooks": {
"PostToolUse": [
{
"hooks": [
{
"type": "http",
"url": "http://localhost:8080/hooks/tool-use",
"headers": {
"Authorization": "Bearer $MY_TOKEN"
},
"allowedEnvVars": ["MY_TOKEN"]
}
]
}
]
}
}
ตำแหน่งของ Hook Configuration
| ตำแหน่ง | ขอบเขต |
|---|---|
~/.claude/settings.json | ทุก projects ของคุณ |
.claude/settings.json | Project เดียว (commit ได้) |
.claude/settings.local.json | Project เดียว (gitignored) |
Plugin hooks/hooks.json | เมื่อ plugin เปิดใช้งาน |
การแก้ไขปัญหา
Hook ไม่ทำงาน
- รัน
/hooksและยืนยันว่า hook ปรากฏภายใต้ event ที่ถูกต้อง - ตรวจสอบว่า matcher pattern ตรงกับ tool name
- ตรวจสอบว่า script มีสิทธิ์ execute:
chmod +x ./my-hook.sh
JSON Validation ล้มเหลว
ตรวจสอบว่า shell profile ไม่มี unconditional echo statements:
# ใน ~/.zshrc หรือ ~/.bashrc
if [[ $- == *i* ]]; then
echo "Shell ready"
fi
Debug Hooks
รัน Claude Code ด้วย debug flag:
claude --debug-file /tmp/claude.log
จากนั้น:
tail -f /tmp/claude.log
ดูเพิ่มเติม
- Hooks reference: full event schemas, JSON output format, async hooks และ MCP tool hooks
- Security considerations: review ก่อน deploy hooks ใน shared environments