Contents
see ListClaude Code Hooks: 이벤트 기반 자동화 시스템
Hooks는 Claude Code의 라이프사이클 이벤트에 자동으로 반응하는 스크립트 시스템입니다. 수동 호출 없이 특정 이벤트 발생 시 자동으로 실행되어 일관된 품질 게이트와 자동화된 워크플로우를 구현할 수 있습니다.
Hooks란?
- 정의: 라이프사이클 이벤트에서 자동으로 트리거되는 액션
- 목적: 자동 포맷팅, 검증, 승인 요구, 세션 초기화 등
- 실행 방식: 명시적 호출 없이 이벤트 발생 시 자동 실행
사용 가능한 이벤트 타입
| 이벤트 | 트리거 시점 | 주요 용도 |
|---|---|---|
| PreToolUse | 도구 실행 전 | 실행 전 검증, 차단 |
| PostToolUse | 도구 실행 후 | 결과 검증, 후처리 |
| UserPromptSubmit | 사용자 프롬프트 제출 시 | 입력 전처리 |
| Notification | 알림 발생 시 | 외부 시스템 연동 |
| Stop | 에이전트 중지 시 | 정리 작업 |
| SubagentStop | 서브에이전트 중지 시 | 서브에이전트 결과 처리 |
| SessionStart | 세션 시작 시 | 초기화, 환경 설정 |
Hooks 설정 방법
settings.json에서 설정
// ~/.claude/settings.json 또는 .claude/settings.json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "npx eslint --fix "$FILE""
}
]
}
],
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": ".claude/hooks/validate-command.sh"
}
]
}
]
}
}
Hook 타입
1. Command Hook (쉘 스크립트 실행)
{
"type": "command",
"command": "/path/to/script.sh",
"timeout": 30000
}
- 예측 가능하고 빠른 실행
- stdin으로 JSON 데이터 수신
- exit code로 결과 전달 (0: 성공, 2: 차단 및 에러 메시지 전달)
2. Prompt Hook (LLM 결정 위임)
{
"type": "prompt",
"prompt": "이 변경사항이 테스트를 통과하는지 확인하세요"
}
- 유연하고 컨텍스트 인식 가능
- 복잡한 판단이 필요한 경우 사용
Hook 옵션
| 옵션 | 설명 | 기본값 |
|---|---|---|
| matcher | 정규식 패턴으로 대상 도구 필터링 | 모든 도구 |
| timeout | 실행 타임아웃 (밀리초) | 600000 (10분) |
| once | 세션당 한 번만 실행 | false |
실용적인 Hook 예시
1. 자동 린팅 (PostToolUse)
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": ".claude/hooks/run-lint.sh"
}
]
}
]
}
}
# .claude/hooks/run-lint.sh
#!/bin/bash
FILE=$(cat | jq -r ".tool_input.file_path")
if [[ "$FILE" == *.ts ]] || [[ "$FILE" == *.tsx ]]; then
npx eslint --fix "$FILE"
fi
2. 커밋 전 테스트 강제 (PreToolUse)
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": ".claude/hooks/pre-commit-check.sh"
}
]
}
]
}
}
# .claude/hooks/pre-commit-check.sh
#!/bin/bash
COMMAND=$(cat | jq -r ".tool_input.command")
if [[ "$COMMAND" == *"git commit"* ]]; then
# 테스트 통과 확인
if [ ! -f ".test-passed" ]; then
echo "테스트를 먼저 실행하세요: npm test" >&2
exit 2 # exit 2 = 차단 + 에러 메시지 Claude에 전달
fi
fi
exit 0
3. 세션 시작 초기화 (SessionStart)
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": ".claude/hooks/session-init.sh"
}
]
}
]
}
}
# .claude/hooks/session-init.sh
#!/bin/bash
echo "=== 프로젝트 상태 확인 ==="
git status --short
echo ""
echo "=== 최근 커밋 ==="
git log --oneline -5
4. 힌트 Hook (비차단)
# .claude/hooks/style-hint.sh
#!/bin/bash
CONTENT=$(cat | jq -r ".tool_input.content // empty")
if [[ "$CONTENT" == *"var "* ]]; then
echo "힌트: let 또는 const 사용을 권장합니다" >&2
fi
exit 0 # 힌트만 제공, 차단하지 않음
Hook Exit Code 규칙
- exit 0: 성공, 작업 계속 진행
- exit 1: 에러, 작업 계속 진행 (로그만 기록)
- exit 2: 작업 차단, stderr 내용을 Claude에 피드백
Hook 베스트 프랙티스
권장사항
- 커밋 시점에 차단: 작성 중이 아닌 최종 결과물(커밋)에서 검증
- 테스트-수정 루프 강제: 테스트 통과 전까지 커밋 차단
- 힌트는 비차단으로: 스타일 권장사항은 exit 0 사용
피해야 할 패턴
- 작성 중 차단 금지: 계획 중인 에이전트를 방해
- 과도한 Hook 금지: 성능 저하 유발
- 긴 타임아웃 Hook 최소화: 사용자 경험 저하
v2.1.3 업데이트
- 도구 훅 실행 타임아웃이 60초에서 10분으로 연장
- 스킬 내 훅이 스킬 라이프사이클에 스코핑되어 스킬 종료 시 자동 정리
참고 자료: