Hooks: Claude Code의 이벤트 기반 자동화
Claude Code는 그 자체로 강력한 도구이지만 확장하면 진정한 강점이 드러납니다. 이벤트 중심 자동화 시스템: gli 후크. 후크는 쉘 명령입니다 수명주기 동안 특정 이벤트에 대한 응답으로 자동으로 실행됩니다. Claude Code 세션의 반응형 AI 도우미를 선제적이고 맞춤형 개발 시스템.
별도의 프로세스와 통신을 생성해야 하는 MCP 서버와 달리 구조화된 프로토콜을 통해 후크는 단순하게 실행되는 쉘 스크립트처럼 작동합니다. Claude Code 프로세스에서 직접적으로. 이로 인해 매우 가볍고 빠릅니다. 서버의 복잡성이 필요하지 않은 자동화를 구현하고 완벽하게 구현 헌신. 이 글에서 우리는 Hooks의 모든 측면을 깊이 있게 탐구할 것입니다: dalla 실제 사용 사례부터 최상의 사용 사례까지 복잡한 자동화 생성에 이르는 구성 효과적인 사용을 위한 실천.
무엇을 배울 것인가
- Claude Code의 이벤트 기반 후크 시스템 이해
- JSON 설정 파일에서 후크 구성
- 사용 가능한 6가지 후크 이벤트를 모두 마스터하세요.
- 복잡한 자동화를 위한 맞춤형 후크 생성
- Britfix, CC Notify 및 cchooks와 같은 커뮤니티 후크를 사용하세요.
- 후크에서 오류, 성능 및 보안을 처리합니다.
- 에이전트 간 고급 통신 패턴 구현
- 강력한 후크 생태계를 위한 모범 사례 적용
시리즈 개요
| # | Articolo | 집중하다 |
|---|---|---|
| 1 | 기술 파트너로서의 클로드 | 설정 및 첫 번째 단계 |
| 2 | 프로젝트 컨텍스트 및 설정 | CLAUDE.md 및 구성 |
| 3 | 개념 및 요구사항 | MVP 및 사용자 페르소나 |
| 4 | 백엔드 및 프런트엔드 아키텍처 | 스프링 부트와 Angular |
| 5 | 코드의 구조 | 조직 및 협약 |
| 6 | 고급 엔지니어링 프롬프트 | 고급 기술 |
| 7 | 테스트 및 품질 | 전략 및 테스트 생성 |
| 8 | 전문 문서 | 읽어보기, API, ADR |
| 9 | 배포 및 DevOps | 도커, CI/CD, 모니터링 |
| 10 | 진화와 유지 | 리팩토링 및 확장성 |
| 11 | 실제 프로젝트 통합 | 클로드 코드 제작 중 |
| 12 | 고급 CLI 및 명령 | 명령줄의 숙달 |
| 13 | 사용자 정의 슬래시 명령 및 기술 | 클로드 코드 확장 |
| 14 | 하위 대리인 및 위임 | 전문 에이전트 오케스트레이션 |
| 15 | Hooks: 이벤트 기반 자동화(현재 위치) | 이벤트 기반 자동화 |
| 16 | Ralph Wiggum: 자율 AI 루프 | 반복적인 자율 개발 |
| 17 | BMAD 방법: 민첩한 AI 개발 | 민첩한 AI 기반 방법론 |
| 18 | 다중 에이전트 오케스트레이션 | 상담원 팀 조정 |
| 19 | 협업과 코워킹 AI | 클로드와 함께 일하기 |
| 20 | 보안 및 권한 | 워크플로우를 보호하세요 |
| 21 | 모니터링 및 최적화 | 측정항목 및 성능 |
1. Claude Code의 후크란 무엇입니까?
Claude Code의 후크는 다음과 같습니다. 사용자 정의 쉘 명령 누가 오나요? 세션 중 특정 이벤트에서 자동으로 수행됩니다. 개발 프레임워크의 git 후크 또는 수명 주기 후크와 유사하게 작동합니다. 워크플로의 주요 순간에 연결되어 로직을 주입할 수 있습니다. 에이전트의 핵심 동작을 변경하지 않고 사용자 정의합니다.
Hooks의 철학은 간단하지만 강력합니다. Claude를 요구하기보다는 프롬프트를 통해 작업 수행(에이전트가 다르게 해석할 수 있음) 예상보다) 후크는 실행을 보장합니다. 결정적이고 신뢰할 수 있는. 명령은 변경 없이 항상 정의된 대로 정확하게 실행됩니다. 혹은 창의적인 해석.
후크와 MCP 서버: 언제 무엇을 사용해야 할까요?
| 특성 | 후크 | MCP 서버 |
|---|---|---|
| 복잡성 | 낮음 - 쉘 스크립트 | 높음 - 별도의 공정 |
| 숨어 있음 | 최소 - 직접 실행 | 전공 - IPC 통신 |
| 모델 확인 | 아니요 - LLM이 결정하지 않습니다. | 예 - LLM이 언제 사용할지 선택합니다. |
| 결정론 | 전체 - 항상 실행됨 | 부분 - 상황에 따라 다름 |
| 구성 | settings.json의 JSON | SDK가 포함된 전용 서버 |
| 사용 사례 | 자동화, 알림, 검증 | 복잡한 도구, API 통합 |
| 안전 | 제어된 로컬 실행 | 도구별 세분화된 권한 |
Hooks 시스템의 아키텍처
후크 시스템은 Claude Code 실행 루프에 레이어로 적합합니다. 투명한 차단. 지원되는 이벤트가 발생할 때마다 Claude Code는 해당 이벤트에 대해 구성된 후크가 있는지 확인하고 stdin을 통한 JSON 입력으로 컨텍스트를 지정하고 지정된 쉘 명령을 실행합니다. 출력을 처리하여 흐름의 변경 사항을 확인합니다.
후크는 다음을 통해 JSON 형식의 구조화된 입력을 받습니다. stdin 그리고 그들은 할 수 있다
다음을 통해 JSON 출력을 반환합니다. stdout 행동에 영향을 미치기 위해
대리인의. 이 스트림 기반 접근 방식을 통해 파이프라인 구성이 가능합니다.
간단하고 보편적인 인터페이스를 유지하면서 복잡한 처리를 수행합니다.
┌──────────────────────┐
│ Evento Trigger │
│ (es. PreToolUse) │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ Preparazione Input │
│ (JSON via stdin) │
│ - tool_name │
│ - tool_input │
│ - session_id │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ Esecuzione Comando │ ← Script shell definito dall'utente
│ (shell command) │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ Elaborazione Output │
│ (JSON via stdout) │
│ - decision: allow │
│ - decision: block │
│ - decision: modify │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ Continuazione Flusso│
│ Claude Code │
└──────────────────────┘
2. 후크 구성
후크는 파일에 구성되어 있습니다. .claude/settings.json 내부
프로젝트 디렉토리 또는 전역 사용자 구성
(~/.claude/settings.json). 구성 구조는 JSON 객체입니다.
이벤트를 후크 목록에 매핑합니다. 여기서 각 후크는 실행할 명령을 지정합니다.
선택적으로 후크를 활성화할 도구나 조건을 필터링하는 일치자도 있습니다.
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit",
"command": "/path/to/script.sh"
}
],
"PostToolUse": [
{
"matcher": "Bash",
"command": "python3 /path/to/logger.py"
}
],
"Stop": [
{
"command": "notify-send 'Claude Code' 'Task completato!'"
}
]
}
}
후크의 속성
구성 필드
| 필드 | 유형 | 의무사항 | 설명 |
|---|---|---|---|
matcher | 문자열(정규식) | No | 필터 활성화를 위한 정규식 패턴입니다. 논리적 OR에 대한 파이프를 지원합니다. |
command | string | Si | 실행할 쉘 명령입니다. 절대 경로 또는 상대 경로일 수 있습니다. |
timeout | 숫자 | No | 시간 초과(밀리초)입니다. 기본값: 60000(60초). |
분야 matcher 정규식을 지원하기 때문에 특히 강력합니다.
완료. 이는 특정 항목에만 응답하는 후크를 만들 수 있음을 의미합니다.
도구 또는 도구 조합을 사용하여 시스템의 응답성과 성능을 유지합니다.
// Singolo tool
"matcher": "Write"
// Multipli tool con OR
"matcher": "Write|Edit|MultiEdit"
// Pattern regex complesso
"matcher": "^(Bash|Terminal)$"
// Tutti i tool (nessun matcher = wildcard)
// Omettere il campo matcher
// Tool che iniziano con "File"
"matcher": "^File.*"
// Escludere specifici tool (negazione regex)
"matcher": "^(?!Read).*$"
구성 수준
Claude Code는 후크에 대한 세 가지 계층적 구성 수준을 지원합니다. 다양한 세분성 수준에서 자동화를 정의할 수 있습니다.
- 프로젝트 (
.claude/settings.json): 현재 저장소와 관련된 후크입니다. Linting, 서식 지정 또는 팀 알림과 같은 프로젝트 관련 자동화에 이상적입니다. - 사용자(
~/.claude/settings.json): 모든 사용자 세션에 적용되는 전역 후크입니다. 데스크톱 알림이나 로깅과 같은 개인 취향에 적합합니다. - 기업(
/etc/claude/settings.json): 조직 전체 후크. 감사 로깅 또는 규정 준수 확인과 같은 회사 정책에 사용됩니다.
동일한 이벤트에 대해 여러 수준의 후크가 존재하는 경우 모두 실행됩니다. 우선 순위: 첫 번째 기업, 그 다음 사용자, 마지막으로 프로젝트. 이는 다음을 보장합니다. 구성에 관계없이 회사 정책은 항상 존중됩니다. 지역.
3. 6가지 Hook 이벤트 상세정보
Claude Code는 후크를 연결할 수 있는 6개의 개별 이벤트를 노출합니다. 모든 이벤트 세션 수명 주기의 특정 순간에 해당하며 컨텍스트를 제공합니다. JSON 입력을 통해 특정됩니다. 각 사건을 깊이 있게 이해하는 것이 필수적입니다. 효과적이고 강력한 자동화를 설계합니다.
3.1 PreToolUse: 실행 전 가로채기
이벤트 PreTool사용 활성화되었습니다 전에 클로드 코드가 수행하는 어떤 도구. 가장 강력한 차단 지점입니다. 검사, 수정 또는 차단 악기를 연주하다 시스템에 영향을 미치기 전에.
PreToolUse에 대한 JSON 입력
| 필드 | 유형 | 설명 |
|---|---|---|
tool_name | string | 도구 이름(예: "쓰기", "Bash", "편집") |
tool_input | 물체 | 기기에 전달된 매개변수 |
session_id | string | 고유 세션 식별자 |
후크는 세 가지 가능한 결정을 통해 출력 JSON을 반환할 수 있습니다.
"decision": "allow"- 수정 없이 기기를 실행할 수 있습니다."decision": "block"- 실행을 완전히 차단합니다. 필드가 필요합니다.reason동기 부여로."decision": "modify"- 실행하기 전에 기기 매개변수를 편집합니다. 필드가 필요합니다.tool_input업데이트된 매개변수로
#!/bin/bash
# Hook PreToolUse: blocca operazioni su file protetti
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
TOOL_INPUT=$(echo "$INPUT" | jq -r '.tool_input')
# Blocca scrittura su file di configurazione critica
if [ "$TOOL_NAME" = "Write" ] || [ "$TOOL_NAME" = "Edit" ]; then
FILE_PATH=$(echo "$TOOL_INPUT" | jq -r '.file_path // .path // ""')
# Lista file protetti
PROTECTED_FILES=(".env" ".env.production" "secrets.json" "credentials.yaml")
for PROTECTED in "${PROTECTED_FILES[@]}"; do
if [[ "$FILE_PATH" == *"$PROTECTED"* ]]; then
echo "{\"decision\": \"block\", \"reason\": \"File protetto: $PROTECTED. Modifica manuale richiesta.\"}"
exit 0
fi
done
fi
# Blocca comandi Bash distruttivi
if [ "$TOOL_NAME" = "Bash" ]; then
COMMAND=$(echo "$TOOL_INPUT" | jq -r '.command // ""')
# Pattern pericolosi
if echo "$COMMAND" | grep -qE "rm\s+-rf\s+/|DROP\s+TABLE|DELETE\s+FROM.*WHERE\s+1=1|format\s+c:"; then
echo "{\"decision\": \"block\", \"reason\": \"Comando potenzialmente distruttivo bloccato.\"}"
exit 0
fi
fi
# Permettere tutto il resto
echo '{"decision": "allow"}'
#!/bin/bash
# Hook PreToolUse: aggiunge automaticamente header ai nuovi file
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
if [ "$TOOL_NAME" = "Write" ]; then
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path')
CONTENT=$(echo "$INPUT" | jq -r '.tool_input.content')
# Aggiungi header copyright ai file TypeScript
if [[ "$FILE_PATH" == *.ts ]]; then
HEADER="// Copyright $(date +%Y) - MyCompany\n// Auto-generated header by Claude Code hook\n\n"
MODIFIED_CONTENT="${HEADER}${CONTENT}"
echo "$INPUT" | jq --arg content "$MODIFIED_CONTENT" \
'{decision: "modify", tool_input: (.tool_input + {content: $content})}'
exit 0
fi
fi
echo '{"decision": "allow"}'
3.2 PostToolUse: 실행 후 반응
이벤트 PostTool사용 활성화되었습니다 후에 도구가 완료되었다는 것 그 실행. 이상적인 장소입니다 로깅, 결과 검증, 출력 변환 그리고 작업 결과에 따른 후속 조치.
PreToolUse와 달리 PostToolUse는 작업을 차단하거나 수정할 수 없습니다. (이미 발생한 일이지만) Claude가 결과를 해석하는 방식에 영향을 미칠 수 있습니다. 로그 업데이트, 알림 전송 또는 트리거와 같은 부차적인 작업을 수행할 수 있습니다. 외부 파이프라인.
PostToolUse에 대한 JSON 입력
| 필드 | 유형 | 설명 |
|---|---|---|
tool_name | string | 도구 실행 이름 |
tool_input | 물체 | 실행에 사용되는 매개변수 |
tool_output | string | 도구 결과 |
session_id | string | 세션 식별자 |
#!/usr/bin/env python3
"""Hook PostToolUse: logga tutte le operazioni di scrittura file."""
import json
import sys
from datetime import datetime
from pathlib import Path
def main():
input_data = json.loads(sys.stdin.read())
tool_name = input_data.get("tool_name", "")
tool_input = input_data.get("tool_input", {})
session_id = input_data.get("session_id", "unknown")
# Logga solo operazioni di modifica file
if tool_name in ("Write", "Edit", "MultiEdit"):
log_entry = {
"timestamp": datetime.now().isoformat(),
"session_id": session_id,
"tool": tool_name,
"file": tool_input.get("file_path", "N/A"),
"operation": "write" if tool_name == "Write" else "edit"
}
log_file = Path(".claude/hooks/activity.log")
log_file.parent.mkdir(parents=True, exist_ok=True)
with open(log_file, "a") as f:
f.write(json.dumps(log_entry) + "\n")
# Logga comandi Bash eseguiti
if tool_name == "Bash":
command = tool_input.get("command", "")
log_entry = {
"timestamp": datetime.now().isoformat(),
"session_id": session_id,
"tool": "Bash",
"command": command[:200], # Tronca per sicurezza
"exit_code": "success"
}
log_file = Path(".claude/hooks/bash-history.log")
log_file.parent.mkdir(parents=True, exist_ok=True)
with open(log_file, "a") as f:
f.write(json.dumps(log_entry) + "\n")
if __name__ == "__main__":
main()
3.3 UserPromptSubmit: 사용자 프롬프트 가로채기
이벤트 사용자 프롬프트제출 사용자가 프롬프트를 보낼 때 실행됩니다. 클로드 코드에게. 이 후크를 사용하면 다음을 수행할 수 있습니다. 전처리, 강화 또는 필터링 모델에 도달하기 전에 사용자 메시지. 특히 유용합니다. 자동 컨텍스트 추가, 프롬프트 템플릿 적용 또는 필터 구현 들어오는 메시지에 대한 보안.
#!/bin/bash
# Hook UserPromptSubmit: aggiunge contesto Git automatico
INPUT=$(cat)
PROMPT=$(echo "$INPUT" | jq -r '.prompt')
# Aggiungi informazioni sul branch corrente
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "N/A")
LAST_COMMIT=$(git log --oneline -1 2>/dev/null || echo "N/A")
DIRTY_FILES=$(git status --porcelain 2>/dev/null | wc -l)
# Crea contesto arricchito
CONTEXT="[Git Context: branch=$BRANCH, last_commit=$LAST_COMMIT, dirty_files=$DIRTY_FILES]"
# Modifica il prompt aggiungendo il contesto
ENRICHED_PROMPT="$CONTEXT\n\n$PROMPT"
echo "$INPUT" | jq --arg prompt "$ENRICHED_PROMPT" \
'{decision: "modify", prompt: $prompt}'
3.4 중지: 세대가 끝날 때의 작업
이벤트 멈추다 Claude Code가 생성을 완료하면 활성화됩니다. 응답하거나 작업을 완료합니다. 이상적인 장소입니다 알림, 정리, 보고서 생성 완료 시 발생해야 하는 모든 작업 상호작용의. 이 후크는 특히 긴 작업에 유용합니다. 사용자가 단말기 앞에 있지 않을 수도 있습니다.
#!/bin/bash
# Hook Stop: invia notifica desktop quando Claude completa
INPUT=$(cat)
STOP_REASON=$(echo "$INPUT" | jq -r '.stop_reason // "completed"')
# Notifica su Linux (notify-send)
if command -v notify-send &> /dev/null; then
notify-send "Claude Code" "Task completato: $STOP_REASON" \
--icon=dialog-information \
--urgency=normal
fi
# Notifica su macOS (osascript)
if command -v osascript &> /dev/null; then
osascript -e "display notification \"Task completato: $STOP_REASON\" with title \"Claude Code\""
fi
# Suono di completamento
if command -v aplay &> /dev/null; then
aplay /usr/share/sounds/freedesktop/stereo/complete.oga 2>/dev/null &
elif command -v afplay &> /dev/null; then
afplay /System/Library/Sounds/Glass.aiff &
fi
3.5 SessionStart: 세션 초기화
이벤트 세션 시작 새로운 세션이 시작될 때마다 활성화됩니다. 클로드 코드. 이상적인 시간입니다 환경 설정, 컨텍스트 로딩 추가, 전제조건 검증 그리고 필요한 자원의 준비 작업 세션을 위해.
#!/bin/bash
# Hook SessionStart: prepara l'ambiente di sviluppo
# Verifica prerequisiti
echo "Verificando ambiente di sviluppo..." >&2
# Controlla che Node.js sia disponibile
if ! command -v node &> /dev/null; then
echo '{"warning": "Node.js non trovato. Alcune funzionalità potrebbero non funzionare."}' >&2
fi
# Controlla che il database di sviluppo sia raggiungibile
if command -v pg_isready &> /dev/null; then
if ! pg_isready -q 2>/dev/null; then
echo '{"warning": "PostgreSQL non raggiungibile. Avviare il database."}' >&2
fi
fi
# Carica variabili d'ambiente dal .env
if [ -f ".env" ]; then
export $(grep -v '^#' .env | xargs) 2>/dev/null
fi
# Registra inizio sessione
echo "{\"session_start\": \"$(date -Iseconds)\", \"cwd\": \"$(pwd)\"}" \
>> .claude/hooks/sessions.log 2>/dev/null
# Pulisci file temporanei di sessioni precedenti
find /tmp -name "claude-hook-*" -mtime +1 -delete 2>/dev/null
3.6 SessionEnd: 정리 및 최종 보고서
이벤트 세션 종료 Claude Code 세션이 종료되면 활성화됩니다. 완벽한 장소예요 상태 저장, 세션 보고서 생성, 정리 수행 향후 세션을 위해 유용한 정보를 저장합니다.
#!/usr/bin/env python3
"""Hook SessionEnd: genera un report della sessione di lavoro."""
import json
import sys
from datetime import datetime
from pathlib import Path
def main():
input_data = json.loads(sys.stdin.read())
session_id = input_data.get("session_id", "unknown")
# Leggi il log delle attivita
log_file = Path(".claude/hooks/activity.log")
activities = []
if log_file.exists():
with open(log_file) as f:
for line in f:
try:
entry = json.loads(line.strip())
if entry.get("session_id") == session_id:
activities.append(entry)
except json.JSONDecodeError:
continue
# Genera report
report = {
"session_id": session_id,
"end_time": datetime.now().isoformat(),
"total_operations": len(activities),
"files_modified": list(set(
a.get("file", "") for a in activities
if a.get("tool") in ("Write", "Edit", "MultiEdit")
)),
"bash_commands": sum(
1 for a in activities if a.get("tool") == "Bash"
)
}
# Salva report
reports_dir = Path(".claude/hooks/reports")
reports_dir.mkdir(parents=True, exist_ok=True)
report_file = reports_dir / f"session-{session_id[:8]}.json"
with open(report_file, "w") as f:
json.dump(report, f, indent=2)
print(f"Report sessione salvato: {report_file}", file=sys.stderr)
if __name__ == "__main__":
main()
후크 이벤트 요약
| 이벤트 | 활성화되면 | 차단할 수 있나요? | 편집할 수 있나요? |
|---|---|---|---|
| PreTool사용 | 도구를 실행하기 전에 | Si | 예(도구 매개변수) |
| PostTool사용 | 도구를 실행한 후 | No | 아니요(부작용만 해당) |
| 사용자 프롬프트제출 | 사용자가 프롬프트를 보낼 때 | Si | 예(프롬프트 텍스트) |
| 멈추다 | Claude가 생성을 마치면 | No | No |
| 세션 시작 | 새 세션이 시작될 때 | No | No |
| 세션 종료 | 세션이 끝날 때 | No | No |
4. 커뮤니티 후크: 즉시 사용 가능한 솔루션
Claude Code 커뮤니티는 다음 문제를 해결하는 여러 가지 정교한 후크를 개발했습니다. 일반적인 개발자 요구 사항. 이러한 오픈 소스 프로젝트는 다양성을 보여줍니다. 후크 시스템의 일부이며 직접 사용하거나 사용자 정의의 기초로 사용할 수 있습니다.
4.1 Britfix: 미국-영국 영어 자동 변환
브리티픽스 철자를 자동으로 변환하는 PostToolUse 후크입니다. Claude Code가 작성한 파일에 있는 영국식 철자의 미국식 영어. 그것은 영국 표준에 따라 작업하지만 AI 모델을 사용하는 팀을 위해 만들어졌습니다. 주로 미국 텍스트로 훈련했습니다.
후크는 모든 파일 쓰기 작업을 가로채서 내용에서 단어를 구문 분석합니다. 미국식 철자(예: "color", "optimize", "center")로 바꾸고 다음으로 바꿉니다. 영국식 변형("색상", "최적화", "중앙"). 과정이 투명하다 수동 개입이 필요하지 않습니다.
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"command": "npx britfix --auto-fix"
}
]
}
}
4.2 CC 알림: 스마트 데스크톱 알림
참조 알림 더 발전된 고급 데스크톱 알림 시스템입니다. 간단한 완료 알림. 유형별로 차별화된 알림 지원 이벤트, 알림 기록, 메시징 시스템과의 통합 (Slack, Discord, Telegram) 및 활동 유형별로 세분화된 구성이 가능합니다.
CC Notify의 특히 유용한 기능은 시간을 추정하는 기능입니다. 이전 세션 기록을 기반으로 장기 작업을 위해 남아 있습니다. Claude Code는 사용자가 시간을 보다 효과적으로 계획할 수 있도록 도와줍니다. 백그라운드에서 작동합니다.
{
"hooks": {
"Stop": [
{
"command": "cc-notify --channel slack --sound chime --message 'Task completato'"
}
],
"SessionStart": [
{
"command": "cc-notify --channel desktop --message 'Sessione Claude avviata'"
}
],
"PreToolUse": [
{
"matcher": "Bash",
"command": "cc-notify --log-activity bash"
}
]
}
}
4.3 cchuks: 전문 Hooks용 Python SDK
쿈스 생성을 획기적으로 단순화하는 Python SDK입니다. 복잡한 후크. 수동 JSON 구문 분석을 사용하여 쉘 스크립트를 작성하는 대신 cchooks 형식화된 Python 데코레이터, 자동 입력/출력 처리 및 일반적인 작업을 위한 유틸리티 라이브러리입니다.
#!/usr/bin/env python3
"""Hook creato con cchooks SDK."""
from cchooks import hook, PreToolUseInput, HookDecision
@hook("PreToolUse")
def validate_file_size(event: PreToolUseInput) -> HookDecision:
"""Blocca la scrittura di file troppo grandi."""
if event.tool_name == "Write":
content = event.tool_input.get("content", "")
max_lines = 500
if content.count("\n") > max_lines:
return HookDecision.block(
reason=f"File troppo grande: {content.count(chr(10))} righe "
f"(max {max_lines}). Suddividi in file più piccoli."
)
return HookDecision.allow()
@hook("PostToolUse")
def auto_lint(event):
"""Esegue linting automatico dopo ogni modifica file."""
import subprocess
if event.tool_name in ("Write", "Edit"):
file_path = event.tool_input.get("file_path", "")
if file_path.endswith(".ts") or file_path.endswith(".js"):
subprocess.run(
["npx", "eslint", "--fix", file_path],
capture_output=True, timeout=30
)
elif file_path.endswith(".py"):
subprocess.run(
["python3", "-m", "black", file_path],
capture_output=True, timeout=30
)
4.4 Claude Code Hook 통신: 에이전트 간 실시간 통신
클로드 코드 후크 통신 사이의 실시간 통신을 가능하게 합니다. 동일하거나 관련된 프로젝트에서 작업하는 Claude Code의 여러 인스턴스. 공유 파일 또는 소켓 기반 메시징 시스템을 사용하여 조정 여러 에이전트의 활동을 통해 충돌과 작업 중복을 방지합니다.
이 후크는 여러 에이전트가 사용되는 다중 에이전트 개발 시나리오에서 특히 유용합니다. Claude Code는 프로젝트의 다양한 측면(예: 프런트엔드 및 백엔드)에서 작업합니다. 공유 인터페이스에 대한 변경 사항을 동기화해야 합니다.
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"command": "claude-hook-comms publish --topic file-changes --data-from-stdin"
}
],
"SessionStart": [
{
"command": "claude-hook-comms subscribe --topic file-changes --handler sync-handler.sh"
}
]
}
}
// sync-handler.sh - Gestisce le notifiche di cambio file
#!/bin/bash
INPUT=$(cat)
CHANGED_FILE=$(echo "$INPUT" | jq -r '.file_path')
AGENT_ID=$(echo "$INPUT" | jq -r '.agent_id')
echo "[SYNC] Agente $AGENT_ID ha modificato: $CHANGED_FILE" >> .claude/hooks/sync.log
5. 맞춤형 Hook 생성: 단계별 가이드
사용자 정의 후크를 생성하려면 입력/출력 형식을 이해해야 합니다. 적절한 스크립팅 언어 선택 및 견고성에 대한 관심 효율성. 이 섹션에서는 제작부터 제작까지의 전체 과정을 제공합니다. 전문 후크 생산.
1단계: 목표 정의
코드를 작성하기 전에 후크가 수행해야 하는 작업을 명확하게 정의하는 것이 중요합니다.
- 어떤 이벤트인가요? 후크가 개입해야 하는 정확한 순간을 식별합니다.
- 어떤 행동? 수행해야 할 작업 정의(차단, 수정, 기록, 알림)
- 어떤 조건이 있나요? 후크가 실행되어야 하는 시기 지정(Matcher)
- 어떤 영향을 미치나요? 워크플로에 대한 후크의 결과를 평가합니다.
2단계: 스크립트 작성
#!/bin/bash
set -euo pipefail
# Leggi input JSON da stdin
INPUT=$(cat)
# Estrai campi comuni
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // ""')
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // ""')
# ================================
# LOGICA DEL HOOK
# ================================
# Esempio: loggare l'operazione
echo "[$(date -Iseconds)] Hook triggered: tool=$TOOL_NAME session=$SESSION_ID" >&2
# ================================
# OUTPUT (solo per PreToolUse/UserPromptSubmit)
# ================================
# Opzione 1: Permettere
echo '{"decision": "allow"}'
# Opzione 2: Bloccare
# echo '{"decision": "block", "reason": "Motivo del blocco"}'
# Opzione 3: Modificare
# echo '{"decision": "modify", "tool_input": {...}}'
3단계: 후크 테스트
스크립트의 오류가 차단될 수 있으므로 테스트 후크는 필수적입니다. 또는 전체 Claude Code 세션 속도를 늦추십시오. 테스트에 대한 구조화된 접근 방식은 다음과 같습니다.
#!/bin/bash
# Testa un hook simulando l'input JSON
HOOK_SCRIPT="./my-hook.sh"
# Simula input PreToolUse per Write
echo '{
"tool_name": "Write",
"tool_input": {
"file_path": "/tmp/test.ts",
"content": "console.log(\"hello\");"
},
"session_id": "test-session-001"
}' | bash "$HOOK_SCRIPT"
echo "---"
# Simula input PreToolUse per Bash con comando pericoloso
echo '{
"tool_name": "Bash",
"tool_input": {
"command": "rm -rf /"
},
"session_id": "test-session-001"
}' | bash "$HOOK_SCRIPT"
echo "---"
# Verifica exit code
echo "Exit code: $?"
4단계: 등록 및 활성화
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit",
"command": "bash .claude/hooks/pre-tool-guard.sh"
},
{
"matcher": "Bash",
"command": "bash .claude/hooks/bash-validator.sh"
}
],
"PostToolUse": [
{
"command": "python3 .claude/hooks/post-tool-logger.py"
}
],
"Stop": [
{
"command": "bash .claude/hooks/notify-complete.sh"
}
],
"SessionStart": [
{
"command": "bash .claude/hooks/session-init.sh"
}
],
"SessionEnd": [
{
"command": "python3 .claude/hooks/session-report.py"
}
]
}
}
6. Hooks의 고급 패턴
후크는 기본적인 용도 외에도 세련된 패턴으로 조합이 가능합니다 복잡한 자동화 요구를 해결합니다. 이 섹션에서는 몇 가지를 제시합니다. 커뮤니티의 경험에서 나온 가장 유용한 패턴 중 하나입니다.
패턴: 체크포인트에서 자동 커밋
이 패턴은 전체에서 정기적인 간격으로 Git 커밋을 자동으로 생성합니다. 개발 세션을 통해 작업이 손실되지 않도록 보장 세분화된 롤백 지점 제공
#!/bin/bash
# Hook PostToolUse: crea checkpoint automatici
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
# Solo per operazioni di modifica file
if [ "$TOOL_NAME" = "Write" ] || [ "$TOOL_NAME" = "Edit" ]; then
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""')
# Controlla se ci sono abbastanza modifiche per un checkpoint
CHANGES=$(git diff --stat 2>/dev/null | tail -1)
NUM_FILES=$(git diff --name-only 2>/dev/null | wc -l)
if [ "$NUM_FILES" -ge 3 ]; then
git add -A 2>/dev/null
git commit -m "checkpoint: auto-save dopo $NUM_FILES file modificati" \
--no-verify 2>/dev/null
echo "[CHECKPOINT] Commit automatico: $NUM_FILES file" >&2
fi
fi
패턴: 품질 게이트 사전 커밋
이 패턴은 자동으로 품질 검사(린팅, 유형 검사, 단위 테스트) 쓰기 작업을 허용하기 전에 각 변경 사항은 프로젝트 표준을 준수합니다.
#!/bin/bash
# Hook PreToolUse: quality gate per file TypeScript
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
if [ "$TOOL_NAME" = "Write" ]; then
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path')
CONTENT=$(echo "$INPUT" | jq -r '.tool_input.content')
if [[ "$FILE_PATH" == *.ts ]]; then
# Scrivi il contenuto in un file temporaneo per analisi
TEMP_FILE=$(mktemp /tmp/claude-hook-XXXXXX.ts)
echo "$CONTENT" > "$TEMP_FILE"
# Esegui type checking
ERRORS=$(npx tsc --noEmit --strict "$TEMP_FILE" 2>&1 || true)
rm -f "$TEMP_FILE"
if echo "$ERRORS" | grep -q "error TS"; then
ERROR_COUNT=$(echo "$ERRORS" | grep -c "error TS")
echo "{\"decision\": \"block\", \"reason\": \"Type check fallito: $ERROR_COUNT errori TypeScript trovati. Correggi prima di scrivere.\"}"
exit 0
fi
fi
fi
echo '{"decision": "allow"}'
패턴: 컨텍스트 강화 파이프라인
이 패턴은 각 사용자 프롬프트에 정보를 자동으로 풍부하게 합니다. 저장소 상태, 최근 수정된 파일 등 관련 컨텍스트 실패한 테스트 및 프로젝트 측정 항목.
#!/bin/bash
# Hook UserPromptSubmit: pipeline di arricchimento contesto
INPUT=$(cat)
PROMPT=$(echo "$INPUT" | jq -r '.prompt')
# Raccogli contesto
CONTEXT_PARTS=()
# 1. Stato Git
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
if [ -n "$BRANCH" ]; then
DIRTY=$(git status --porcelain 2>/dev/null | wc -l)
CONTEXT_PARTS+=("[Branch: $BRANCH, File modificati: $DIRTY]")
fi
# 2. Test falliti recenti
if [ -f "test-results.json" ]; then
FAILED=$(jq '.numFailedTests // 0' test-results.json 2>/dev/null)
if [ "$FAILED" -gt 0 ]; then
CONTEXT_PARTS+=("[WARNING: $FAILED test falliti]")
fi
fi
# 3. TODO in sospeso
TODO_COUNT=$(grep -r "TODO\|FIXME\|HACK" src/ --include="*.ts" 2>/dev/null | wc -l)
if [ "$TODO_COUNT" -gt 0 ]; then
CONTEXT_PARTS+=("[TODO aperti nel codice: $TODO_COUNT]")
fi
# Costruisci contesto aggregato
if [ ${#CONTEXT_PARTS[@]} -gt 0 ]; then
CONTEXT=$(printf "%s " "${CONTEXT_PARTS[@]}")
ENRICHED="$CONTEXT\n\n$PROMPT"
echo "$INPUT" | jq --arg p "$ENRICHED" '{decision: "modify", prompt: $p}'
else
echo '{"decision": "allow"}'
fi
7. 성능, 보안 및 모범 사례
후크는 Claude Code 수명 주기에서 동기식으로 실행됩니다. 느리거나 오작동하는 후크의 성능이 크게 저하될 수 있음을 의미합니다. 사용자 경험. 성능 및 보안 모범 사례를 따르는 것이 필수적입니다. 원활하고 안전한 작업 흐름을 유지합니다.
성능 최적화
Hook 수행을 위한 황금률
| 규칙 | 동기 부여 | 구현 |
|---|---|---|
| 공격적인 시간 초과 | 세션 정지 방지 | 세트 timeout 중요한 후크의 경우 5~10초 |
| 특정 매처 | 불필요한 실행을 줄입니다 | 와일드카드 대신 정확한 정규 표현식을 사용하세요. |
| 비동기 작업 | 느린 I/O를 차단하지 마십시오. | 무거운 작업을 백그라운드 프로세스에 위임 |
| 로컬 캐시 | 비용이 많이 드는 재계산 방지 | 중간 결과를 임시 파일에 저장 |
| 조기 퇴장 | 실행 시간 최소화 | 스크립트 시작 부분에서 종료 조건을 확인하세요. |
| 제어된 로깅 | 과도한 디스크 I/O 방지 | 로그 순환 및 심각도 수준 사용 |
후크 안전
Hooks는 현재 사용자의 권한으로 쉘 명령을 실행합니다. 이점(시스템에 대한 전체 액세스)과 위험(실행)을 모두 나타냅니다. 통제되지 않음). 엄격한 안전 원칙을 적용하는 것이 중요합니다.
- 최소 권한의 원칙: 각 후크는 해당 작업에 꼭 필요한 리소스에만 액세스할 수 있어야 합니다.
- 입력 유효성 검사: stdin을 통해 수신된 모든 데이터는 사용 전에 검증 및 삭제되어야 합니다.
- 하드코딩된 비밀 없음: API 키, 비밀번호 및 토큰은 후크 스크립트에 직접 포함되어서는 안 됩니다.
- 감사 추적: 추적성을 위해 후크에 의해 수행된 모든 작업에 대한 로그를 유지합니다.
- 정기 검토: 구성된 후크를 정기적으로 검토하여 새로운 위험을 식별합니다.
경고: 보안 위험
프로젝트 후크(에 정의됨) .claude/settings.json)이 실행됩니다
저장소에서 Claude Code 세션을 열 때 자동으로. 이는 다음을 의미합니다.
악성 저장소에는 악성 후크가 포함될 수 있습니다. 항상 확인하세요
신뢰할 수 없는 저장소에서 세션을 열기 전에 구성 파일을 확인하세요.
오류 관리
조용히 실패하는 후크는 존재하지 않는 후크보다 더 나쁩니다. 구현 강력한 오류 처리는 시스템 유지 관리에 매우 중요합니다.
#!/bin/bash
set -euo pipefail
# Trap per gestire errori e cleanup
cleanup() {
local exit_code=$?
if [ $exit_code -ne 0 ]; then
echo "[HOOK ERROR] Exit code: $exit_code" >&2
echo "{\"error\": \"Hook fallito con codice $exit_code\"}" >&2
fi
# Cleanup risorse temporanee
rm -f /tmp/claude-hook-$.tmp 2>/dev/null
}
trap cleanup EXIT
# Timeout per l'intero script
TIMEOUT=10
(
sleep $TIMEOUT
echo "[HOOK TIMEOUT] Script superato $TIMEOUT secondi" >&2
kill $ 2>/dev/null
) &
TIMEOUT_PID=$!
# Logica principale con error handling
INPUT=$(cat) || {
echo '{"decision": "allow"}' # Fallback sicuro
exit 0
}
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // ""' 2>/dev/null) || TOOL_NAME=""
# ... logica del hook ...
# Cancella il timer di timeout
kill $TIMEOUT_PID 2>/dev/null || true
echo '{"decision": "allow"}'
8. 완전한 예: Angular 프로젝트를 위한 Hooks 생태계
결론적으로 구성된 후크 생태계의 완전한 예를 제시합니다. 여섯 가지 이벤트를 모두 다루고 시연하는 SSR을 사용한 Angular 프로젝트 강력하고 자동화된 개발 환경을 만들기 위해 후크가 함께 작동하는 방식.
{
"hooks": {
"SessionStart": [
{
"command": "bash .claude/hooks/check-dependencies.sh",
"timeout": 15000
}
],
"PreToolUse": [
{
"matcher": "Write|Edit",
"command": "bash .claude/hooks/validate-angular-conventions.sh",
"timeout": 5000
},
{
"matcher": "Bash",
"command": "bash .claude/hooks/block-dangerous-commands.sh",
"timeout": 3000
}
],
"PostToolUse": [
{
"matcher": "Write|Edit",
"command": "bash .claude/hooks/auto-lint-format.sh",
"timeout": 10000
},
{
"command": "python3 .claude/hooks/activity-tracker.py",
"timeout": 5000
}
],
"UserPromptSubmit": [
{
"command": "bash .claude/hooks/enrich-with-project-context.sh",
"timeout": 5000
}
],
"Stop": [
{
"command": "bash .claude/hooks/desktop-notification.sh"
}
],
"SessionEnd": [
{
"command": "python3 .claude/hooks/generate-session-report.py",
"timeout": 10000
}
]
}
}
#!/bin/bash
# PreToolUse: valida convenzioni Angular per nuovi file
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""')
# Verifica naming convention per componenti Angular
if [[ "$FILE_PATH" == *.component.ts ]]; then
# Controlla che il nome segua kebab-case
FILENAME=$(basename "$FILE_PATH" .component.ts)
if ! echo "$FILENAME" | grep -qE '^[a-z][a-z0-9]*(-[a-z0-9]+)*






