02-구조
02. 구조 — settings.json 안의 hook 정의
섹션 제목: “02. 구조 — settings.json 안의 hook 정의”정의 위치
섹션 제목: “정의 위치”| 위치 | 스코프 | 공유 |
|---|---|---|
~/.claude/settings.json | 사용자 전체 | 아니오 |
.claude/settings.json | 프로젝트 | 예 (git) |
.claude/settings.local.json | 프로젝트 + 본인 | 아니오 |
| Managed policy | 조직 | 예 |
Plugin hooks/hooks.json | 플러그인 활성 시 | 예 |
| Skill/agent frontmatter | 컴포넌트 활성 시 | 예 |
3단 중첩 구조
섹션 제목: “3단 중첩 구조”{ "hooks": { "PostToolUse": [ // 1. 이벤트 { "matcher": "Edit|Write", // 2. 매처 "hooks": [ // 3. 핸들러 목록 { "type": "command", "command": "pnpm lint --fix $CLAUDE_FILE_PATH || true" }, { "type": "command", "command": ".claude/hooks/log-edit.sh" } ] } ] }}매처 패턴
섹션 제목: “매처 패턴”- 도구 이벤트 → 도구 이름 정규식.
Bash,Edit|Write,mcp__memory__.*. SessionStart→startup|resume|clear|compact.Notification→permission_prompt|idle_prompt|auth_success.FileChanged→ 파일 basename 정규식.
더 좁은 필터링은 핸들러 단의 if 필드:
Bash(git *)— git 명령에만.Edit(*.ts)— TypeScript 파일에만.
stdin / 종료 코드
섹션 제목: “stdin / 종료 코드”Command hook은 JSON을 stdin으로 받는다.
- exit 0 → 통과.
- exit 2 → 차단(모델에게 차단 사유 stderr 전달).
- 그 외 → 경고 후 통과.
HTTP hook은 동일 JSON을 POST body로 받는다. 응답 JSON으로 차단/허용 결정 반환.
hook 위치 vs 적용 시점
섹션 제목: “hook 위치 vs 적용 시점”SessionStart 같은 이벤트는 settings 머지 후 발화한다. 그래서 로컬 hook으로 글로벌 정책을 우회할 수 없다 — managed policy hook이 항상 먼저.