Files
AX-Copilot/docs/claude-code-docs-main/19_훅레퍼런스.md

250 lines
7.0 KiB
Markdown

# 훅 레퍼런스
> 모든 훅 이벤트, 입력 페이로드, 출력 스키마, 각 종료 코드가 Claude 동작에 미치는 영향에 대한 전체 레퍼런스.
훅은 Claude의 에이전틱 루프에서 정의된 지점에서 발생하는 셸 커맨드, HTTP 엔드포인트, LLM 프롬프트, 또는 인프로세스 콜백입니다.
## 설정
훅은 설정 파일의 최상위 `hooks` 키로 구성됩니다:
```json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "echo 'bash 커맨드 실행 예정' >&2"
}
]
}
]
}
}
```
## 매처 설정
`matcher` 필드는 이벤트별로 다른 필드와 매칭됩니다:
| 이벤트 | 매칭되는 필드 |
|--------|-------------|
| `PreToolUse` / `PostToolUse` / `PostToolUseFailure` / `PermissionRequest` / `PermissionDenied` | `tool_name` |
| `Notification` | `notification_type` |
| `SessionStart` | `source` (`startup`, `resume`, `clear`, `compact`) |
| `Setup` | `trigger` (`init`, `maintenance`) |
| `SubagentStart` / `SubagentStop` | `agent_type` |
| `PreCompact` / `PostCompact` | `trigger` (`manual`, `auto`) |
| `ConfigChange` | `source` |
| `FileChanged` | 파일 이름 패턴 (예: `".envrc|.env"`) |
## 훅 타입
**셸 커맨드:**
```json
{
"type": "command",
"command": "jq '.tool_name' && my-validator",
"timeout": 30,
"shell": "bash",
"async": false,
"once": false,
"if": "Bash(git *)",
"statusMessage": "검증 중..."
}
```
필드:
- `command`: 실행할 셸 커맨드 (필수)
- `timeout`: 타임아웃(초), 기본 60초
- `shell`: `bash` (기본) 또는 `powershell`
- `async`: `true`면 백그라운드에서 비블로킹 실행
- `asyncRewake`: `true`면 백그라운드 실행, 종료코드 2로 종료 시 모델 깨움
- `once`: `true`면 한 번 실행 후 자동 제거
- `if`: 조건부로 훅 건너뛰기 위한 권한 규칙 구문
- `statusMessage`: 실행 중 스피너에 표시되는 커스텀 메시지
**LLM 평가:**
```json
{
"type": "prompt",
"prompt": "이 bash 커맨드가 안전한지 확인하세요: $ARGUMENTS",
"model": "claude-haiku-4-5",
"timeout": 30
}
```
**에이전틱 검증기:**
```json
{
"type": "agent",
"prompt": "단위 테스트가 실행되고 통과했는지 확인하세요.",
"model": "claude-haiku-4-5",
"timeout": 120
}
```
**HTTP 엔드포인트:**
```json
{
"type": "http",
"url": "https://my-server.example.com/hook",
"headers": {
"Authorization": "Bearer $MY_TOKEN"
},
"allowedEnvVars": ["MY_TOKEN"],
"timeout": 10
}
```
## 기본 훅 입력
모든 훅이 stdin에서 받는 공통 필드:
| 필드 | 타입 | 설명 |
|------|------|------|
| `hook_event_name` | `string` | 발생한 이벤트 (예: `"PreToolUse"`) |
| `session_id` | `string` | 현재 세션 식별자 |
| `transcript_path` | `string` | 세션 JSONL 트랜스크립트 파일의 절대 경로 |
| `cwd` | `string` | 훅 발생 시점의 현재 작업 디렉토리 |
| `permission_mode` | `string` | 활성 권한 모드 |
| `agent_id` | `string` | 서브에이전트에서 발생 시 식별자 |
## 동기 훅 출력 (stdout의 JSON)
블로킹 훅의 경우 종료 전에 JSON을 stdout에 씁니다:
```json
{
"continue": true,
"suppressOutput": false,
"decision": "approve",
"reason": "커맨드가 안전합니다",
"systemMessage": "훅이 이 작업을 승인했습니다.",
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "allow"
}
}
```
## 훅 이벤트 상세
### `PreToolUse`
도구가 실행되기 직전에 발생.
**입력 필드:** `tool_name`, `tool_input`, `tool_use_id`
**종료 코드:**
| 코드 | 효과 |
|------|------|
| `0` | stdout/stderr 표시 안 됨. 훅 출력 JSON 적용 |
| `2` | stderr를 Claude에게 표시; 도구 호출 **차단** |
| 기타 | stderr를 사용자에게만 표시; 도구 호출 계속 |
**`hookSpecificOutput` 필드:**
- `permissionDecision`: `'allow'` | `'deny'` | `'ask'` — 권한 결정 재정의
- `updatedInput`: 도구가 받을 교체 입력
- `additionalContext`: 이 턴의 Claude 컨텍스트에 주입될 텍스트
---
### `PostToolUse`
도구가 성공적으로 완료된 후 발생.
**입력 필드:** `tool_name`, `tool_input`, `tool_response`, `tool_use_id`
**종료 코드:**
| 코드 | 효과 |
|------|------|
| `0` | stdout이 트랜스크립트 모드에 표시 (Ctrl+O) |
| `2` | stderr를 즉시 Claude에게 시스템 메시지로 표시 |
| 기타 | stderr를 사용자에게만 표시 |
---
### `Stop`
Claude가 응답을 종료하기 직전에 발생.
**입력 필드:** `stop_hook_active`, `last_assistant_message`
**종료 코드:**
| 코드 | 효과 |
|------|------|
| `0` | stdout/stderr 표시 안 됨 |
| `2` | stderr를 시스템 메시지로 주입; Claude **대화 계속** |
| 기타 | stderr를 사용자에게만 표시; Claude 중지 |
> 💡 Stop 훅의 종료코드 2를 사용해 Claude 출력을 확인하고 조건이 충족되지 않으면 대화를 계속하게 합니다 — 예를 들어 테스트가 여전히 실패하는 경우.
---
### `SessionStart`
세션 시작 시 발생. 초기 컨텍스트 주입이나 환경 설정에 사용.
**입력 필드:** `source` (`'startup'` | `'resume'` | `'clear'` | `'compact'`), `model`
**`hookSpecificOutput` 필드:**
- `additionalContext`: 세션 시스템 프롬프트에 주입될 컨텍스트
- `initialUserMessage`: 세션의 첫 사용자 메시지로 자동 제출
- `watchPaths`: `FileChanged` 감시기에 등록할 절대 파일 경로
---
### `UserPromptSubmit`
사용자가 프롬프트를 제출할 때 발생.
**입력 필드:** `prompt`
**종료 코드:**
| 코드 | 효과 |
|------|------|
| `0` | stdout이 Claude에게 추가 컨텍스트로 표시 |
| `2` | 처리 **차단**; 원본 프롬프트 지워짐; stderr를 사용자에게 표시 |
| 기타 | stderr를 사용자에게만 표시 |
---
### `PermissionRequest`
권한 다이얼로그가 표시될 때 발생. UI 없이 프로그래밍 방식으로 승인/거부 가능.
**종료 코드:**
| 코드 | 효과 |
|------|------|
| `0` | `hookSpecificOutput.decision`이 설정된 경우 훅 결정 적용 |
| 기타 | stderr를 사용자에게 표시; 일반 다이얼로그로 폴백 |
---
### `CwdChanged`
작업 디렉토리 변경 후 발생.
**입력 필드:** `old_cwd`, `new_cwd`
`CLAUDE_ENV_FILE` 환경 변수가 설정됨 — 환경 변수를 `export KEY=value` 줄로 써서 이후 Bash 도구 호출에 적용합니다.
---
### `FileChanged`
감시 중인 파일이 수정, 추가, 제거될 때 발생.
**입력 필드:** `file_path`, `event` (`'change'` | `'add'` | `'unlink'`)
---
## 비동기 훅
백그라운드에서 실행되는 훅은 일반 동기 출력 대신 비동기 확인을 stdout에 출력합니다:
```json
{
"async": true,
"asyncTimeout": 30
}
```
> ⚠️ 비동기 훅은 도구 실행을 차단하거나 컨텍스트를 주입할 수 없습니다. 에이전틱 루프를 느리게 하면 안 되는 알림, 로깅, 메트릭 같은 부작용에 사용하세요.