# 훅 (Hooks) > Claude가 도구를 사용하거나 세션 마일스톤에 도달할 때 셸 커맨드, HTTP 요청, 프롬프트를 자동으로 실행합니다. 훅은 Claude Code의 도구 라이프사이클에 자동화를 연결합니다. Claude가 파일을 읽거나, bash 커맨드를 실행하거나, 응답을 완료할 때 설정된 훅이 자동으로 실행됩니다. 코드 스타일 강제, 테스트 실행, 도구 사용 로깅, Claude가 할 수 있는 작업 제어에 훅을 사용하세요. ## 훅 작동 방식 훅은 특정 **이벤트**에 바인딩된 커맨드(셸 스크립트, HTTP 엔드포인트, LLM 프롬프트)입니다. 이벤트가 발생하면 Claude Code가 매칭된 모든 훅을 실행하고 종료 코드와 출력을 사용해 다음 동작을 결정합니다. 각 훅의 입력은 무슨 일이 일어났는지 설명하는 JSON 객체입니다. **종료 코드 의미:** | 종료 코드 | 의미 | |----------|------| | `0` | 성공. stdout이 Claude에게 표시될 수 있음(이벤트별 다름) | | `2` | 차단 또는 주입. stderr를 Claude에게 표시하고(`PreToolUse`) 도구 호출 방지 | | 기타 | stderr를 사용자에게만 표시; 실행 계속 | ## 훅 이벤트 | 이벤트 | 설명 | |--------|------| | **PreToolUse** | 모든 도구 호출 직전에 발생. 도구 입력 검사, 승인/차단, 입력 수정 가능. 종료코드 `2` → 도구 호출 차단 | | **PostToolUse** | 모든 성공적인 도구 호출 후 발생. 도구 출력 관찰 또는 Claude가 처리할 컨텍스트 주입 가능 | | **PostToolUseFailure** | 도구 호출이 오류로 종료될 때 발생 | | **Stop** | Claude가 응답을 종료하기 직전에 발생. 종료코드 `2` → stderr를 Claude에게 표시하고 대화 계속 | | **SubagentStop** | 서브에이전트가 결론 내리기 직전에 발생 (`Stop`과 동일하지만 서브에이전트용) | | **SubagentStart** | 새 서브에이전트가 시작될 때 발생 | | **SessionStart** | 세션 시작, 재개, `/clear`, `/compact` 후에 발생 | | **UserPromptSubmit** | 사용자가 프롬프트를 제출할 때 발생. 종료코드 `2` → 프롬프트 차단 | | **PreCompact** | 컨텍스트 컴팩션 시작 직전에 발생. 종료코드 `2` → 컴팩션 차단 | | **PostCompact** | 컴팩션 완료 후 발생 | | **Setup** | 저장소 초기화(`init`) 및 주기적 유지보수(`maintenance`) 시 발생 | | **PermissionRequest** | 권한 다이얼로그가 표시될 때 발생. 프로그래밍 방식으로 승인/거부 가능 | | **PermissionDenied** | 도구 호출이 거부된 후 발생 | | **Notification** | 권한 프롬프트, 유휴 프롬프트, 인증 성공 등의 알림 시 발생 | | **CwdChanged** | 작업 디렉토리 변경 후 발생 | | **FileChanged** | 감시 중인 파일이 변경될 때 발생 | | **SessionEnd** | 세션이 종료될 때 발생 | | **ConfigChange** | 세션 중 설정 파일이 변경될 때 발생 | ## 훅 설정 세션 내에서 `/hooks`를 실행해 훅 설정 메뉴를 열 수 있습니다. 훅은 설정 파일의 `hooks` 필드에 저장됩니다: ```json { "hooks": { "PostToolUse": [ { "matcher": "Write", "hooks": [ { "type": "command", "command": "prettier --write $CLAUDE_FILE_PATH" } ] } ], "Stop": [ { "hooks": [ { "type": "command", "command": "echo 'Session complete' >> ~/.claude-log.txt" } ] } ] } } ``` 각 이벤트는 **매처 객체** 배열에 매핑됩니다: - `matcher` (선택사항) — 이벤트의 매칭 가능한 필드와 매칭되는 문자열 패턴 - `hooks` — 매처가 일치할 때 실행할 훅 커맨드 배열 빈 또는 없는 `matcher`는 해당 이벤트의 모든 입력과 일치합니다. ## 훅 커맨드 타입 **셸 커맨드 (`type: "command"`):** ```json { "type": "command", "command": "npm test", "timeout": 60, "shell": "bash", "async": false } ``` 필드: - `command` — 실행할 셸 커맨드 (필수) - `timeout` — 타임아웃(초) - `shell` — `"bash"` (기본) 또는 `"powershell"` - `async` — 백그라운드에서 실행 (출력 무시) - `once` — 한 번 실행 후 자동으로 훅 제거 - `if` — 조건부로 훅 건너뛰기 위한 권한 규칙 구문 - `statusMessage` — 훅 실행 중 스피너에 표시되는 커스텀 메시지 **HTTP 요청 (`type: "http"`):** ```json { "type": "http", "url": "https://hooks.example.com/claude-event", "headers": { "Authorization": "Bearer $MY_TOKEN" }, "allowedEnvVars": ["MY_TOKEN"], "timeout": 10 } ``` Claude Code가 훅 입력 JSON을 URL에 POST합니다. **LLM 프롬프트 (`type: "prompt"`):** ```json { "type": "prompt", "prompt": "이 bash 커맨드에 보안 문제가 있는지 확인하세요: $ARGUMENTS. 문제가 있으면 설명하고 코드 2로 종료하세요.", "model": "claude-haiku-4-5", "timeout": 30 } ``` **에이전트 훅 (`type: "agent"`):** ```json { "type": "agent", "prompt": "단위 테스트가 실행되고 통과했는지 확인하세요.", "timeout": 60 } ``` 도구 접근 권한이 있는 짧은 에이전틱 루프로 실행됩니다. 파일을 읽거나 커맨드를 실행해야 하는 검증 작업에 유용합니다. ## 훅 예시 **파일 편집 후 자동 포맷:** ```json { "hooks": { "PostToolUse": [ { "matcher": "Write", "hooks": [ { "type": "command", "command": "prettier --write \"$CLAUDE_FILE_PATH\" 2>/dev/null || true" } ] } ] } } ``` **위험한 커맨드 차단:** ```json { "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": "if echo \"$CLAUDE_TOOL_INPUT\" | grep -q 'rm -rf'; then echo '차단: rm -rf는 허용되지 않습니다' >&2; exit 2; fi" } ] } ] } } ``` **모든 도구 사용 로깅:** ```json { "hooks": { "PostToolUse": [ { "hooks": [ { "type": "command", "command": "echo \"$(date -u +%Y-%m-%dT%H:%M:%SZ) $CLAUDE_TOOL_NAME\" >> ~/.claude-tool-log.txt", "async": true } ] } ] } } ``` **디렉토리 변경 시 환경 변수 주입:** ```json { "hooks": { "CwdChanged": [ { "hooks": [ { "type": "command", "command": "if [ -f .envrc ]; then grep '^export ' .envrc >> \"$CLAUDE_ENV_FILE\"; fi" } ] } ] } } ``` ## 훅 vs 스킬 | 기능 | 훅 | 스킬 | |------|-----|------| | 실행 시점 | 도구 이벤트에 자동 | Claude나 사용자가 `/skill-name`으로 명시적 호출 | | 목적 | 부작용, 게이팅, 관찰 | 온디맨드 워크플로우와 기능 | | 설정 | 설정 JSON | `.claude/skills/`의 마크다운 파일 | 자동으로 발생해야 하는 것(포맷팅, 로깅, 강제)에는 훅을 사용하고, 의도적으로 트리거하려는 반복 가능한 워크플로우에는 스킬을 사용하세요.