Hooks
Hooks là lệnh shell do bạn định nghĩa, chạy tự động tại các thời điểm cố định trong vòng đời của Claude Code — ví dụ tự format code sau mỗi lần sửa file, hoặc chặn một lệnh nguy hiểm trước khi nó kịp chạy. Điểm khác biệt so với việc chỉ dặn dò trong CLAUDE.md: hooks luôn chạy đúng như cấu hình, không phụ thuộc vào việc model có “nhớ” hay quyết định làm theo hay không — xem thêm ở Khi nào dùng Hooks thay vì CLAUDE.md bên dưới.
Các sự kiện (event) thường dùng
Phần tiêu đề “Các sự kiện (event) thường dùng”Đây là các sự kiện phổ biến nhất — danh sách đầy đủ còn nhiều hơn (khoảng 30 sự kiện, bao gồm cả sự kiện cho subagent, MCP, worktree…):
| Sự kiện | Thời điểm chạy |
|---|---|
PreToolUse |
Trước khi Claude gọi một tool — có thể chặn hành động |
PostToolUse |
Sau khi tool chạy xong thành công |
UserPromptSubmit |
Khi bạn gửi một prompt mới, trước khi Claude xử lý |
Notification |
Khi Claude Code gửi thông báo (ví dụ đang chờ bạn phản hồi) |
SessionStart |
Khi một phiên bắt đầu hoặc được resume |
Stop |
Khi Claude kết thúc lượt trả lời |
Ví dụ 1: tự động format sau khi sửa file
Phần tiêu đề “Ví dụ 1: tự động format sau khi sửa file”Chạy Prettier trên mọi file Claude vừa sửa, để format luôn nhất quán mà không cần bạn can thiệp tay. Thêm vào .claude/settings.json ở gốc dự án:
{ "hooks": { "PostToolUse": [ { "matcher": "Edit|Write", "hooks": [ { "type": "command", "command": "jq -r '.tool_input.file_path' | xargs npx prettier --write" } ] } ] }}matcher: "Edit|Write" nghĩa là hook này chỉ chạy khi Claude dùng tool sửa/tạo file, không chạy với Bash, Read… Lệnh dùng jq để lấy đường dẫn file từ dữ liệu JSON mà Claude Code truyền vào qua stdin.
Ví dụ 2: chặn sửa file nhạy cảm
Phần tiêu đề “Ví dụ 2: chặn sửa file nhạy cảm”Ngăn Claude sửa các file như .env, package-lock.json, hay bất cứ thứ gì trong .git/. Tạo script .claude/hooks/protect-files.sh:
#!/bin/bashINPUT=$(cat)FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
PROTECTED=(".env" "package-lock.json" ".git/")
for pattern in "${PROTECTED[@]}"; do if [[ "$FILE_PATH" == *"$pattern"* ]]; then echo "Blocked: $FILE_PATH khớp mẫu bị chặn '$pattern'" >&2 exit 2 fidone
exit 0Nhớ cấp quyền thực thi: chmod +x .claude/hooks/protect-files.sh. Sau đó đăng ký hook trong .claude/settings.json:
{ "hooks": { "PreToolUse": [ { "matcher": "Edit|Write", "hooks": [ { "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/protect-files.sh" } ] } ] }}Cách hook giao tiếp với Claude Code
Phần tiêu đề “Cách hook giao tiếp với Claude Code”Hook nhận dữ liệu sự kiện dạng JSON qua stdin, và báo lại quyết định qua exit code:
- Exit 0 — không phản đối, hành động tiếp tục diễn ra bình thường (với
PreToolUse, vẫn phải qua luồng xin phép thông thường nếu có). - Exit 2 — chặn hành động. Ghi lý do ra
stderr, Claude sẽ đọc được lý do đó và tự điều chỉnh cách làm. - Mã khác — hành động vẫn tiếp tục, nhưng transcript hiện một cảnh báo lỗi hook.
Với nhu cầu phức tạp hơn (ví dụ tự động cho phép một hành động cụ thể thay vì chỉ chặn/không chặn), hook có thể in ra JSON có cấu trúc ở stdout thay vì chỉ dùng exit code — xem chi tiết trong tài liệu gốc ở phần Nguồn.
Quản lý hooks trong phiên
Phần tiêu đề “Quản lý hooks trong phiên”/hooks— xem toàn bộ hook đang cấu hình, nhóm theo sự kiện (chỉ xem, muốn sửa phải chỉnh trực tiếp file settings hoặc nhờ Claude sửa giúp).- Đặt
"disableAllHooks": truetrong settings để tắt tạm toàn bộ hooks (trừ hook ở cấp cấu hình tổ chức).
Vị trí đặt hook quyết định phạm vi áp dụng — giống với settings.json nói chung (xem thêm): ~/.claude/settings.json cho mọi dự án của bạn, .claude/settings.json để chia sẻ với cả team qua git, .claude/settings.local.json chỉ cho máy này.
Khi nào dùng Hooks thay vì CLAUDE.md
Phần tiêu đề “Khi nào dùng Hooks thay vì CLAUDE.md”- CLAUDE.md: chỉ dẫn bằng ngôn ngữ tự nhiên, Claude cố gắng làm theo nhưng không đảm bảo 100% — phù hợp cho quy ước, ngữ cảnh, sở thích chung.
- Hooks: thực thi bắt buộc bằng shell script, luôn chạy đúng như cấu hình, không phụ thuộc vào việc model có tuân thủ hay không — phù hợp cho yêu cầu bắt buộc phải xảy ra (chạy lint trước commit, chặn thao tác nguy hiểm, ghi log audit…).
Dùng hooks khi hậu quả của việc Claude “quên” là không chấp nhận được; dùng CLAUDE.md cho phần còn lại.