# Claude CLI 완전 가이드 v7: Hooks 설정 및 자동화 ## Hooks란? Hooks는 Claude Code의 라이프사이클 특정 시점에 자동으로 실행되는 셸 명령입니다. Claude의 행동에 대해 **결정론적 제어**를 제공합니다. ### Skills vs Hooks | 구분 | Skills | Hooks | |------|--------|-------| | 트리거 | Claude가 판단 | 시스템 이벤트 | | 실행 | 조건부 (요청 기반) | 항상 실행 (조건 만족 시) | | 용도 | 전문 지식 확장 | 자동화 및 정책 강제 | --- ## Hooks 설정 방법 ### 방법 1: 시각적 인터페이스 (권장) ``` /hooks ``` 인터랙티브 UI에서 Hooks를 관리합니다. ### 방법 2: 설정 파일 직접 편집 `~/.claude/settings.json`: ```json { "hooks": [ { "event": "PostToolUse", "matcher": "bash", "command": "echo 'Bash 명령 실행됨'" } ] } ``` --- ## Hook 구조 각 Hook은 세 가지 필수 요소로 구성: ```json { "event": "이벤트유형", "matcher": "도구이름 또는 *", "command": "실행할 셸 명령" } ``` | 속성 | 설명 | |------|------| | `event` | Hook이 발동되는 시점 | | `matcher` | 어떤 도구에 대해 발동할지 (`*`는 모든 도구) | | `command` | 실행할 셸 명령 | --- ## 사용 가능한 Hook 이벤트 ### 세션 이벤트 | 이벤트 | 발동 시점 | |--------|----------| | `SessionStart` | Claude Code 세션 시작 시 | | `SessionEnd` | Claude Code 세션 종료 시 | ### 도구 사용 이벤트 | 이벤트 | 발동 시점 | |--------|----------| | `PreToolUse` | 도구 사용 직전 | | `PostToolUse` | 도구 사용 직후 | ### 권한 이벤트 | 이벤트 | 발동 시점 | |--------|----------| | `PermissionRequest` | 권한 요청 시 | | `PermissionGranted` | 권한 승인 시 | | `PermissionDenied` | 권한 거부 시 | ### 기타 이벤트 | 이벤트 | 발동 시점 | |--------|----------| | `ErrorOccurred` | 오류 발생 시 | | `FileModified` | 파일 수정 시 | | `CommandExecuted` | Bash 명령 실행 시 | --- ## 환경 변수 Hook 명령에서 사용 가능한 환경 변수: | 변수 | 설명 | |------|------| | `$TOOL_NAME` | 사용된 도구 이름 | | `$FILE_PATH` | 수정된 파일 경로 | | `$COMMAND` | 실행된 명령 | | `$EXIT_CODE` | 명령 종료 코드 | --- ## 실용 예제 ### 1. 자동 코드 포맷팅 Bash 명령 실행 후 자동으로 Prettier 실행: ```json { "hooks": [ { "event": "PostToolUse", "matcher": "bash", "command": "prettier --write '**/*.{js,ts,jsx,tsx}' 2>/dev/null || true" } ] } ``` ### 2. 파일 수정 로깅 모든 파일 수정을 감사 로그에 기록: ```json { "hooks": [ { "event": "FileModified", "matcher": "*", "command": "echo \"$(date '+%Y-%m-%d %H:%M:%S'): $FILE_PATH modified\" >> ~/.claude/audit.log" } ] } ``` ### 3. 세션 시작 환경 검증 세션 시작 시 필수 파일 존재 확인: ```json { "hooks": [ { "event": "SessionStart", "matcher": "*", "command": "if [ ! -f .env ]; then echo 'WARNING: .env 파일이 없습니다'; fi" } ] } ``` ### 4. 보호 디렉토리 차단 특정 디렉토리 수정 시도 차단: ```json { "hooks": [ { "event": "PreToolUse", "matcher": "file_edit", "command": "if [[ \"$FILE_PATH\" == */production/* ]]; then echo 'ERROR: production 디렉토리 수정 금지'; exit 1; fi" } ] } ``` **중요:** `exit 1`로 종료하면 해당 작업이 중단됩니다. ### 5. 빌드 성공 알림 빌드 성공 시 슬랙 알림: ```json { "hooks": [ { "event": "PostToolUse", "matcher": "bash", "command": "if [[ \"$COMMAND\" == *'npm run build'* && $EXIT_CODE -eq 0 ]]; then curl -X POST -H 'Content-type: application/json' --data '{\"text\":\"빌드 성공!\"}' $SLACK_WEBHOOK_URL; fi" } ] } ``` ### 6. Git 커밋 전 린트 커밋 전 자동 린트: ```json { "hooks": [ { "event": "PreToolUse", "matcher": "bash", "command": "if [[ \"$COMMAND\" == *'git commit'* ]]; then npm run lint || exit 1; fi" } ] } ``` ### 7. 테스트 자동 실행 파일 수정 후 관련 테스트 실행: ```json { "hooks": [ { "event": "FileModified", "matcher": "*", "command": "if [[ \"$FILE_PATH\" == *.js ]]; then npm test -- --findRelatedTests \"$FILE_PATH\" 2>/dev/null; fi" } ] } ``` ### 8. 도구 사용 통계 도구 사용 횟수 기록: ```json { "hooks": [ { "event": "PostToolUse", "matcher": "*", "command": "echo \"$TOOL_NAME\" >> ~/.claude/tool-usage.log" } ] } ``` --- ## 복합 Hooks 설정 여러 Hook을 조합한 설정 예시: ```json { "hooks": [ { "event": "SessionStart", "matcher": "*", "command": "echo \"세션 시작: $(date)\" >> ~/.claude/sessions.log" }, { "event": "SessionEnd", "matcher": "*", "command": "echo \"세션 종료: $(date)\" >> ~/.claude/sessions.log" }, { "event": "FileModified", "matcher": "*", "command": "echo \"$(date): $FILE_PATH\" >> ~/.claude/file-changes.log" }, { "event": "PostToolUse", "matcher": "bash", "command": "prettier --write . 2>/dev/null || true" }, { "event": "PreToolUse", "matcher": "file_edit", "command": "if [[ \"$FILE_PATH\" == *.env* ]]; then echo 'WARNING: 환경 파일 수정'; fi" } ] } ``` --- ## 보안 고려사항 ### 주의사항 Hooks는 **현재 환경의 권한으로 자동 실행**됩니다. 1. **신뢰할 수 있는 명령만 사용** 2. **외부 입력을 직접 실행하지 않기** 3. **민감한 정보 로깅 주의** 4. **정기적으로 Hook 설정 검토** ### 권장 사항 ```json // 나쁜 예: 외부 입력 직접 실행 { "command": "eval $USER_INPUT" } // 좋은 예: 특정 명령만 실행 { "command": "npm run lint" } ``` --- ## 디버깅 ### Hook 실행 확인 Verbose 모드로 Hook 실행을 확인: ```bash claude --verbose ``` 또는 세션 내에서: ``` Ctrl+O ``` ### 로그 추가 디버깅용 로그 Hook 추가: ```json { "event": "PostToolUse", "matcher": "*", "command": "echo \"DEBUG: $TOOL_NAME executed\" >> /tmp/claude-hooks.log" } ``` ### Hook 비활성화 문제가 있는 Hook을 일시적으로 비활성화: ``` /hooks ``` UI에서 해당 Hook을 비활성화합니다. --- ## 프로젝트별 Hooks 프로젝트별로 다른 Hooks 사용: `.claude/settings.json`: ```json { "hooks": [ { "event": "PostToolUse", "matcher": "bash", "command": "npm run format" } ] } ``` 이 설정은 해당 프로젝트에서만 적용됩니다. --- ## 고급 패턴 ### 조건부 실행 ```json { "event": "FileModified", "matcher": "*", "command": "case \"$FILE_PATH\" in *.test.js) npm test ;; *.css) npm run lint:css ;; esac" } ``` ### 비동기 실행 빠른 응답을 위해 백그라운드 실행: ```json { "event": "FileModified", "matcher": "*", "command": "(npm run lint &)" } ``` ### 스크립트 호출 복잡한 로직은 별도 스크립트로: ```json { "event": "PostToolUse", "matcher": "bash", "command": "~/.claude/hooks/post-bash.sh" } ``` `~/.claude/hooks/post-bash.sh`: ```bash #!/bin/bash # 복잡한 로직 처리 if [[ "$COMMAND" == *"npm"* ]]; then # npm 관련 후처리 echo "npm 명령 실행됨: $COMMAND" fi # 포맷팅 prettier --write . 2>/dev/null # 로깅 echo "$(date): $TOOL_NAME - $COMMAND" >> ~/.claude/hook.log ``` --- ## 다음 단계 v7에서는 Hooks의 개념과 활용을 다뤘습니다. **다음 v8에서는**: - Project Memory (CLAUDE.md) - 효과적인 작성 패턴 - 팀 협업 활용법 를 상세히 알아봅니다. --- ## 빠른 참조 ``` Hook 관리: /hooks 시각적 설정 인터페이스 ~/.claude/settings.json 직접 편집 Hook 구조: { "event": "이벤트유형", "matcher": "도구명 또는 *", "command": "셸 명령" } 이벤트 유형: SessionStart 세션 시작 SessionEnd 세션 종료 PreToolUse 도구 사용 전 PostToolUse 도구 사용 후 FileModified 파일 수정 ErrorOccurred 오류 발생 환경 변수: $TOOL_NAME 도구 이름 $FILE_PATH 파일 경로 $COMMAND 실행 명령 $EXIT_CODE 종료 코드 차단하기: exit 1 PreToolUse에서 작업 중단 ``` --- *Claude CLI 완전 가이드 시리즈 v7/10*