Claude 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 베스트 프랙티스

권장사항

  1. 커밋 시점에 차단: 작성 중이 아닌 최종 결과물(커밋)에서 검증
  2. 테스트-수정 루프 강제: 테스트 통과 전까지 커밋 차단
  3. 힌트는 비차단으로: 스타일 권장사항은 exit 0 사용

피해야 할 패턴

  1. 작성 중 차단 금지: 계획 중인 에이전트를 방해
  2. 과도한 Hook 금지: 성능 저하 유발
  3. 긴 타임아웃 Hook 최소화: 사용자 경험 저하

v2.1.3 업데이트

  • 도구 훅 실행 타임아웃이 60초에서 10분으로 연장
  • 스킬 내 훅이 스킬 라이프사이클에 스코핑되어 스킬 종료 시 자동 정리

참고 자료: