938| `PostCompact` | 아니오 | 사용자에게만 stderr을 표시합니다 |938| `PostCompact` | 아니오 | 사용자에게만 stderr을 표시합니다 |
939| `PreModelSwitch` | 예 | 모델 전환을 차단하고 사용자에게 stderr을 표시합니다 |939| `PreModelSwitch` | 예 | 모델 전환을 차단하고 사용자에게 stderr을 표시합니다 |
940| `PostModelSwitch` | 아니오 | 사용자에게만 stderr을 표시합니다. 모델은 이미 전환되었습니다 |940| `PostModelSwitch` | 아니오 | 사용자에게만 stderr을 표시합니다. 모델은 이미 전환되었습니다 |
941| `Elicitation` | 예 | elicitation을 거부합니다 |941| `Elicitation` | 예 | 요청을 거부하며 대화 상자가 나타나지 않습니다 |
942| `ElicitationResult` | 예 | 응답을 차단합니다 (action이 decline이 됨) |942| `ElicitationResult` | 예 | 응답을 차단합니다 (action이 decline이 됨) |
943| `WorktreeCreate` | 예 | 0이 아닌 종료 코드는 worktree 생성을 실패하게 합니다 |943| `WorktreeCreate` | 예 | 0이 아닌 종료 코드는 worktree 생성을 실패하게 합니다 |
944| `WorktreeRemove` | 예 | 0이 아닌 종료 코드는 이후에도 디렉터리가 여전히 존재하면 worktree 제거를 실패하게 합니다. 디렉터리에 발생하는 일은 [WorktreeRemove](#worktreeremove)를 참조하세요 |944| `WorktreeRemove` | 예 | 0이 아닌 종료 코드는 이후에도 디렉터리가 여전히 존재하면 worktree 제거를 실패하게 합니다. 디렉터리에 발생하는 일은 [WorktreeRemove](#worktreeremove)를 참조하세요 |
1095| PermissionDenied | `hookSpecificOutput` | `retry: true`는 모델에 거부된 도구 호출을 재시도할 수 있음을 알립니다. Claude Code는 [no-verdict 거부](#permissiondenied-decision-control)에 대해 이를 무시합니다 |1095| PermissionDenied | `hookSpecificOutput` | `retry: true`는 모델에 거부된 도구 호출을 재시도할 수 있음을 알립니다. Claude Code는 [no-verdict 거부](#permissiondenied-decision-control)에 대해 이를 무시합니다 |
1096| WorktreeCreate | 경로 반환 | 명령 hook은 stdout에 경로를 출력합니다. HTTP hook은 `hookSpecificOutput.worktreePath`를 반환합니다. hook 실패 또는 경로 누락 시 생성이 실패합니다 |1096| WorktreeCreate | 경로 반환 | 명령 hook은 stdout에 경로를 출력합니다. HTTP hook은 `hookSpecificOutput.worktreePath`를 반환합니다. hook 실패 또는 경로 누락 시 생성이 실패합니다 |
1097| WorktreeRemove | 종료 코드 | 0이 아닌 종료 코드는 이후에도 디렉터리가 여전히 존재하면 제거를 실패하게 합니다. JSON 출력은 버려집니다 |1097| WorktreeRemove | 종료 코드 | 0이 아닌 종료 코드는 이후에도 디렉터리가 여전히 존재하면 제거를 실패하게 합니다. JSON 출력은 버려집니다 |
1098| Elicitation | `hookSpecificOutput` | `action` (accept/decline/cancel), `content` (accept 시 폼 필드 값) |1098| Elicitation, ElicitationResult | `hookSpecificOutput` 또는 최상위 `decision` | `action` (accept/decline/cancel), `content` (폼 필드 값). `decision: "block"`도 [거부](#other-ways-to-decline-an-elicitation)합니다 |
1099| ElicitationResult | `hookSpecificOutput` | `action` (accept/decline/cancel), `content` (폼 필드 값 재정의) |
1100| MessageDisplay | `hookSpecificOutput` | `displayContent`는 화면에 표시되는 텍스트를 대체합니다. 표시 전용: 트랜스크립트와 Claude가 보는 내용은 원본을 유지합니다 |1099| MessageDisplay | `hookSpecificOutput` | `displayContent`는 화면에 표시되는 텍스트를 대체합니다. 표시 전용: 트랜스크립트와 Claude가 보는 내용은 원본을 유지합니다 |
1101| SessionStart, SubagentStart, PostModelSwitch | 컨텍스트만 | `hookSpecificOutput.additionalContext`는 Claude를 위한 컨텍스트를 추가합니다. SessionStart는 [`initialUserMessage`, `watchPaths`, `sessionTitle`, `reloadSkills`](#sessionstart-decision-control)도 허용합니다. 차단 또는 결정 제어 없음 |1100| SessionStart, SubagentStart, PostModelSwitch | 컨텍스트만 | `hookSpecificOutput.additionalContext`는 Claude를 위한 컨텍스트를 추가합니다. SessionStart는 [`initialUserMessage`, `watchPaths`, `sessionTitle`, `reloadSkills`](#sessionstart-decision-control)도 허용합니다. 차단 또는 결정 제어 없음 |
1102| Setup, Notification, SessionEnd, PostCompact, InstructionsLoaded, StopFailure, CwdChanged, DirectoryAdded, FileChanged | 없음 | 결정 제어 없음. 로깅이나 정리와 같은 부수 효과에 사용됩니다 |1101| Setup, Notification, SessionEnd, PostCompact, InstructionsLoaded, StopFailure, CwdChanged, DirectoryAdded, FileChanged | 없음 | 결정 제어 없음. 로깅이나 정리와 같은 부수 효과에 사용됩니다 |
1163 훅 이벤트1162 훅 이벤트
1164</h2>1163</h2>
1165 1164
1166각 이벤트는 Claude Code 수명 주기에서 훅이 실행될 수 있는 지점에 해당합니다. 아래 섹션은 세션 설정부터 에이전틱 루프를 거쳐 세션 종료까지 수명 주기 순서에 맞춰 정렬되어 있습니다. 각 섹션에서는 이벤트가 발생하는 시점, 지원하는 matcher, 수신하는 JSON 입력, 출력을 통해 동작을 제어하는 방법을 설명합니다.1165각 이벤트는 Claude Code의 수명 주기에서 훅이 실행될 수 있는 지점에 해당합니다. 아래 섹션은 세션 설정부터 에이전틱 루프를 거쳐 세션 종료까지, 수명 주기 순서대로 정렬되어 있습니다. 각 섹션에서는 이벤트가 발생하는 시점, 지원하는 matcher, 받는 JSON 입력, 출력을 통해 동작을 제어하는 방법을 설명합니다.
1167 1166
1168<h3 id="sessionstart">1167<h3 id="sessionstart">
1169 SessionStart1168 SessionStart
1170</h3>1169</h3>
1171 1170
1172Claude Code가 새 세션을 시작하거나 기존 세션을 재개할 때 실행됩니다. 기존 이슈나 코드베이스의 최근 변경 사항 같은 개발 컨텍스트를 불러오거나 환경 변수를 설정하는 데 유용합니다. 스크립트가 필요 없는 정적 컨텍스트에는 대신 [CLAUDE.md](/docs/ko/memory)를 사용합니다.1171Claude Code가 새 세션을 시작하거나 기존 세션을 재개할 때 실행됩니다. 기존 이슈나 코드베이스의 최근 변경 사항 같은 개발 컨텍스트를 로드하거나 환경 변수를 설정하는 데 유용합니다. 스크립트가 필요 없는 정적 컨텍스트에는 대신 [CLAUDE.md](/docs/ko/memory)를 사용하세요.
1173 1172
1174SessionStart는 모든 세션에서 실행되므로 이 훅은 빠르게 유지해야 합니다. `type: "command"` 및 `type: "mcp_tool"` 훅만 지원됩니다. `mcp_tool` 훅이 실행되는 시점은 [MCP 도구 훅 필드](#mcp-tool-hook-fields)를 참조하세요.1173SessionStart는 모든 세션에서 실행되므로 이 훅은 빠르게 유지하세요. `type: "command"` 및 `type: "mcp_tool"` 훅만 지원됩니다. `mcp_tool` 훅이 실행되는 시점은 [MCP 도구 훅 필드](#mcp-tool-hook-fields)를 참조하세요.
1175 1174
1176matcher 값은 세션이 시작된 방식에 해당합니다.1175matcher 값은 세션이 시작된 방식에 해당합니다:
1177 1176
1178| Matcher | 발생 시점 |1177| Matcher | 발생 시점 |
1179| :- | :- |1178| :- | :- |
1181| `resume` | `--resume`, `--continue` 또는 `/resume` |1180| `resume` | `--resume`, `--continue` 또는 `/resume` |
1182| `clear` | `/clear` |1181| `clear` | `/clear` |
1183| `compact` | 자동 또는 수동 압축 |1182| `compact` | 자동 또는 수동 압축 |
1184| `fork` | 기존 세션에서 분기된 새 세션: `--resume` 또는 `--continue`와 함께 사용한 `--fork-session`, `/fork` 백그라운드 복사본, `/branch`, 또는 [백그라운드로 이동](/docs/ko/agent-view#from-inside-a-session)한 대화 |1183| `fork` | 기존 세션에서 분기된 새 세션: `--resume` 또는 `--continue`와 함께 사용한 `--fork-session`, `/fork` 백그라운드 복사본, `/branch`, 또는 [백그라운드로 옮긴](/docs/ko/agent-view#from-inside-a-session) 대화 |
1185 1184
1186v2.1.214 이전에는 분기된 세션이 source를 `"resume"`으로 보고했습니다.1185v2.1.214 이전에는 분기된 세션이 source를 `"resume"`으로 보고했습니다.
1187 1186
1188대화형 세션을 시작하거나, 실행 시 `--continue` 또는 `--resume`으로 대화를 재개하거나, `/clear`를 실행하면 SessionStart 훅이 백그라운드에서 실행됩니다. 바로 입력을 시작할 수 있으며, 재개한 대화는 훅을 기다리지 않고 표시됩니다. Claude의 첫 응답은 여전히 훅이 끝날 때까지 기다리므로 훅의 컨텍스트가 Claude에 전달됩니다.1187대화형 세션을 시작하거나, 실행 시 `--continue` 또는 `--resume`으로 대화를 재개하거나, `/clear`를 실행하면 SessionStart 훅이 백그라운드에서 실행됩니다. 바로 입력을 시작할 수 있으며, 재개한 대화는 훅을 기다리지 않고 표시됩니다. 다만 Claude의 첫 응답은 여전히 훅이 완료될 때까지 기다리므로 훅의 컨텍스트가 Claude에 전달됩니다.
1189 1188
1190세션 안에서 `/resume`으로 대화를 전환하면 전환이 대신 훅이 끝날 때까지 기다립니다. 백그라운드 훅이 아직 실행 중일 때 `/clear`를 실행하거나 다른 대화로 전환하면 훅이 반환하는 내용은 세션에 적용되지 않습니다.1189세션 내에서 `/resume`으로 대화를 전환하면 전환은 대신 훅이 완료될 때까지 기다립니다. 백그라운드 훅이 아직 실행 중일 때 `/clear`를 실행하거나 다른 대화로 전환하면 훅이 반환하는 내용은 세션에 적용되지 않습니다.
1191 1190
1192재개한 세션을 포함하여 실행 시에도 동일한 대기가 적용됩니다. SessionStart 훅이 아직 실행 중일 때 보낸 프롬프트는 훅이 끝날 때까지 Claude에 전달되지 않습니다.1191실행 시에도 재개된 세션을 포함해 동일한 대기가 적용됩니다. SessionStart 훅이 아직 실행 중일 때 보낸 프롬프트는 훅이 완료될 때까지 Claude에 전달되지 않습니다.
1193 1192
1194어느 대기 중이든 `Esc`를 누르면 프롬프트를 보내지 않고 입력란으로 되돌릴 수 있습니다. 훅은 계속 실행됩니다.1193어느 쪽 대기 중이든 `Esc`를 누르면 프롬프트를 보내지 않고 입력란으로 되돌릴 수 있습니다. 훅은 계속 실행됩니다.
1195 1194
1196<h4 id="sessionstart-input">1195<h4 id="sessionstart-input">
1197 SessionStart 입력1196 SessionStart 입력
1198</h4>1197</h4>
1199 1198
1200[공통 입력 필드](#common-input-fields) 외에도 SessionStart 훅은 `source`와 선택적으로 `model`, `agent_type`, `session_title`을 수신합니다.1199[공통 입력 필드](#common-input-fields) 외에도 SessionStart 훅은 `source`와, 선택적으로 `model`, `agent_type`, `session_title`을 받습니다:
1201 1200
1202| 필드 | 설명 |1201| 필드 | 설명 |
1203| :- | :- |1202| :- | :- |
1204| `source` | 세션이 시작된 방식: 새 세션은 `"startup"`, 재개된 세션은 `"resume"`, `/clear` 이후는 `"clear"`, 압축 이후는 `"compact"`, 기존 세션에서 분기된 새 세션은 `"fork"` |1203| `source` | 세션이 시작된 방식: 새 세션은 `"startup"`, 재개된 세션은 `"resume"`, `/clear` 후에는 `"clear"`, 압축 후에는 `"compact"`, 기존 세션에서 분기된 새 세션은 `"fork"` |
1205| `model` | 활성 모델 식별자. 예를 들어 `/clear` 이후나 대화 복구를 통해 세션이 복원된 경우 생략될 수 있으므로, 읽기 전에 필드가 있는지 확인해야 합니다 |1204| `model` | 활성 모델 식별자. 예를 들어 `/clear` 후나 대화 복구를 통해 세션이 복원될 때는 생략될 수 있으므로 읽기 전에 필드가 있는지 확인하세요 |
1206| `agent_type` | 에이전트 이름. `claude --agent <name>`으로 Claude Code를 시작할 때 포함됩니다 |1205| `agent_type` | 에이전트 이름. `claude --agent <name>`으로 Claude Code를 시작할 때 존재합니다 |
1207| `session_title` | 세션의 사용자 지정 제목. 예를 들어 `--name`, `/rename`, 훅의 `sessionTitle` 출력 또는 Agent SDK의 `renameSession()`으로 제목이 설정된 경우 포함됩니다. `sessionTitle`을 내보내는 훅은 기존 사용자 지정 제목을 덮어쓰지 않도록 이 필드를 먼저 확인할 수 있습니다 |1206| `session_title` | 세션의 사용자 지정 제목. 제목이 설정된 경우 존재하며, 예를 들어 `--name`, `/rename`, 훅의 `sessionTitle` 출력 또는 Agent SDK의 `renameSession()`으로 설정됩니다. `sessionTitle`을 내보내는 훅은 먼저 이 필드를 확인하여 기존 사용자 지정 제목을 덮어쓰지 않도록 할 수 있습니다 |
1208 1207
1209이름을 지정하지 않은 세션에도 [생성된 제목](/docs/ko/sessions#name-your-sessions)이 있을 수 있습니다. 이 제목은 사용자 지정 제목이 아니며 `session_title`에 나타나지 않습니다.1208이름을 지정하지 않은 세션에도 [생성된 제목](/docs/ko/sessions#name-your-sessions)이 있을 수 있습니다. 이 제목은 사용자 지정 제목이 아니며 `session_title`에 나타나지 않습니다.
1210 1209
1211`source`가 `"resume"` 또는 `"fork"`이고 트랜스크립트에 Claude의 응답이 하나 이상 포함되어 있으면 SessionStart 훅은 아래 네 가지 필드도 수신합니다. 훅은 이 필드를 사용하여 오래된 대화를 재개하는 데 드는 비용을 첫 요청 전에 보고할 수 있습니다. 예를 들어 [`systemMessage`](#json-output)에 보고할 수 있습니다. 이 필드에는 Claude Code v2.1.251 이상이 필요합니다.1210`source`가 `"resume"` 또는 `"fork"`이고 트랜스크립트에 Claude의 응답이 하나 이상 포함된 경우 SessionStart 훅은 아래 네 가지 필드도 받습니다. 훅은 이 필드를 사용하여 오래된 대화를 재개하는 데 드는 비용을 첫 요청 전에 보고할 수 있습니다(예: [`systemMessage`](#json-output)). 이 필드에는 Claude Code v2.1.251 이상이 필요합니다.
1212 1211
1213| 필드 | 설명 |1212| 필드 | 설명 |
1214| :- | :- |1213| :- | :- |
1215| `seconds_since_last_response` | 재개된 트랜스크립트의 마지막 응답 이후 경과한 실제 시간(초) |1214| `seconds_since_last_response` | 재개된 트랜스크립트의 마지막 응답 이후 경과한 실제 시간(초) |
1216| `context_tokens` | 재개된 세션의 첫 요청이 프롬프트로 다시 보내는 토큰 수 |1215| `context_tokens` | 재개된 세션의 첫 요청이 프롬프트로 다시 보내는 토큰 |
1217| `prompt_cache_likely_expired` | 마지막 응답이 세션의 [프롬프트 캐시 수명](/docs/ko/prompt-caching#cache-lifetime)보다 오래되었거나 이후의 압축이 캐시된 대화를 대체한 경우 `true` |1216| `prompt_cache_likely_expired` | 마지막 응답이 세션의 [프롬프트 캐시 수명](/docs/ko/prompt-caching#cache-lifetime)보다 오래되었거나 이후 압축이 캐시된 대화를 대체한 경우 `true` |
1218| `estimated_cache_write_usd` | 세션의 모델에서 `context_tokens`를 프롬프트 캐시에 쓰는 예상 비용(미국 달러). 응답은 제외됩니다 |1217| `estimated_cache_write_usd` | 세션의 모델에서 `context_tokens`를 프롬프트 캐시에 쓰는 데 드는 예상 비용(미국 달러). 응답은 제외됩니다 |
1219 1218
1220다음 예시는 마지막 응답 후 90분 뒤에 재개된 세션의 입력을 보여 줍니다.1219이 예시는 마지막 응답 후 90분 뒤에 재개된 세션의 입력을 보여 줍니다:
1221 1220
1222```json theme={null}1221```json theme={null}
1223{1222{
1238 SessionStart 결정 제어1237 SessionStart 결정 제어
1239</h4>1238</h4>
1240 1239
1241Claude Code는 [일반 텍스트로 처리하는](#exit-code-0) stdout을 Claude의 컨텍스트에 추가합니다. 모든 훅에서 사용할 수 있는 [JSON 출력 필드](#json-output) 외에도 다음과 같은 이벤트별 필드를 반환할 수 있습니다.1240Claude Code는 [일반 텍스트로 처리하는](#exit-code-0) stdout을 Claude의 컨텍스트에 추가합니다. 모든 훅에서 사용할 수 있는 [JSON 출력 필드](#json-output) 외에도 다음 이벤트별 필드를 반환할 수 있습니다:
1242 1241
1243| 필드 | 설명 |1242| 필드 | 설명 |
1244| :- | :- |1243| :- | :- |
1245| `additionalContext` | 첫 프롬프트 전, 대화 시작 시점에 Claude의 컨텍스트에 추가되는 문자열. 텍스트가 전달되는 방식과 포함할 내용은 [Claude를 위한 컨텍스트 추가](#add-context-for-claude)를 참조하세요 |1244| `additionalContext` | 대화 시작 시 첫 프롬프트 전에 Claude의 컨텍스트에 추가되는 문자열. 텍스트가 전달되는 방식과 넣을 내용은 [Claude를 위한 컨텍스트 추가](#add-context-for-claude)를 참조하세요 |
1246| `initialUserMessage` | 세션의 첫 사용자 메시지로 사용되는 문자열. `-p` 플래그를 사용하는 [비대화형 모드](/docs/ko/headless)에 적용되며, 프롬프트가 제공되지 않아도 첫 턴이 됩니다. 프롬프트가 제공되면 그 프롬프트가 다음 턴으로 이어집니다. 기존 턴에 첨부되는 `additionalContext`와 달리 이 필드는 턴을 생성합니다 |1245| `initialUserMessage` | 세션의 첫 사용자 메시지로 사용되는 문자열. `-p` 플래그를 사용하는 [비대화형 모드](/docs/ko/headless)에 적용되며, 프롬프트가 제공되지 않아도 첫 턴이 됩니다. 프롬프트가 제공되면 그다음 턴으로 이어집니다. 기존 턴에 첨부되는 `additionalContext`와 달리 이 필드는 턴을 생성합니다 |
1247| `sessionTitle` | 세션 제목을 설정하며, `/rename`과 효과가 같습니다. 실행 폴더, git 브랜치 또는 worktree 이름으로 세션 이름을 자동으로 지정하는 데 사용합니다. `source`가 `"startup"`, `"resume"` 또는 `"fork"`일 때 적용되며, `"clear"`와 `"compact"`에서는 무시됩니다 |1246| `sessionTitle` | 세션 제목을 설정하며 `/rename`과 동일한 효과가 있습니다. 실행 폴더, git 브랜치 또는 worktree 이름으로 세션 이름을 자동 지정하는 데 사용합니다. `source`가 `"startup"`, `"resume"` 또는 `"fork"`일 때 적용되며, `"clear"`와 `"compact"`에서는 무시됩니다 |
1248| `watchPaths` | 이 세션 동안 [FileChanged](#filechanged) 이벤트를 감시할 절대 경로 배열 |1247| `watchPaths` | 이 세션 동안 [FileChanged](#filechanged) 이벤트를 감시할 절대 경로 배열 |
1249| `reloadSkills` | 불리언. `true`이면 SessionStart 훅이 완료된 후 Claude Code가 [스킬](/docs/ko/skills) 및 명령 디렉터리를 다시 스캔하므로, 훅이 설치한 스킬을 첫 프롬프트부터 같은 세션에서 사용할 수 있습니다 |1248| `reloadSkills` | 불리언. `true`이면 Claude Code는 SessionStart 훅이 완료된 후 [스킬](/docs/ko/skills) 및 명령 디렉터리를 다시 스캔하므로, 훅이 설치한 스킬을 첫 프롬프트부터 같은 세션에서 사용할 수 있습니다 |
1250 1249
1251```json theme={null}1250```json theme={null}
1252{1251{
1258}1257}
1259```1258```
1260 1259
1261이 이벤트에서는 일반 stdout이 이미 Claude에 전달되므로, 컨텍스트만 불러오는 훅은 JSON을 구성하지 않고 stdout에 직접 출력할 수 있습니다. 컨텍스트를 `sessionTitle` 같은 다른 필드와 함께 사용해야 할 때 JSON 형식을 사용합니다.1260이 이벤트에서는 일반 stdout이 이미 Claude에 전달되므로, 컨텍스트만 로드하는 훅은 JSON을 만들지 않고 stdout에 바로 출력할 수 있습니다. 컨텍스트를 `sessionTitle` 같은 다른 필드와 결합해야 할 때 JSON 형식을 사용하세요.
1262 1261
1263SessionStart 훅이 스킬을 설치하거나 업데이트할 때는 `reloadSkills`를 사용합니다. 스킬 검색은 일반적으로 SessionStart 훅이 끝나기 전에 실행되므로, 그렇지 않으면 훅이 `~/.claude/skills/` 또는 `.claude/skills/`에 작성한 파일은 다음 세션에서만 나타납니다. 다음 예시는 공유 스킬 저장소를 동기화하고 다시 스캔을 요청합니다.1262SessionStart 훅이 스킬을 설치하거나 업데이트할 때는 `reloadSkills`를 사용하세요. 스킬 검색은 일반적으로 SessionStart 훅이 완료되기 전에 실행되므로, 이 필드가 없으면 훅이 `~/.claude/skills/` 또는 `.claude/skills/`에 쓴 파일은 다음 세션에서만 나타납니다. 이 예시는 공유 스킬 저장소를 동기화하고 다시 스캔을 요청합니다:
1264 1263
1265```bash theme={null}1264```bash theme={null}
1266#!/bin/bash1265#!/bin/bash
1271echo '{"hookSpecificOutput": {"hookEventName": "SessionStart", "reloadSkills": true}}'1270echo '{"hookSpecificOutput": {"hookEventName": "SessionStart", "reloadSkills": true}}'
1272```1271```
1273 1272
1274저장소 URL은 자리 표시자이므로 자체 스킬 저장소로 바꿔야 합니다. 자리 표시자를 그대로 두면 clone이 실패하고 stderr에 `fatal:` 메시지가 출력됩니다. 0으로 종료하는 SessionStart 훅의 stderr는 정보 제공용일 뿐이므로 `reloadSkills` 요청은 여전히 적용됩니다.1273저장소 URL은 자리 표시자이므로 자체 스킬 저장소로 바꾸세요. 자리 표시자를 그대로 두면 clone이 실패하고 stderr에 `fatal:` 메시지가 출력됩니다. 0으로 종료되는 SessionStart 훅의 stderr는 정보 제공용일 뿐이므로 `reloadSkills` 요청은 여전히 적용됩니다.
1275 1274
1276<h4 id="persist-environment-variables">1275<h4 id="persist-environment-variables">
1277 환경 변수 유지1276 환경 변수 유지
1278</h4>1277</h4>
1279 1278
1280SessionStart 훅은 `CLAUDE_ENV_FILE` 환경 변수에 액세스할 수 있습니다. 이 변수는 이후 Bash 명령에 사용할 환경 변수를 유지할 수 있는 파일 경로를 제공합니다.1279SessionStart 훅은 `CLAUDE_ENV_FILE` 환경 변수에 액세스할 수 있으며, 이 변수는 이후 Bash 명령을 위해 환경 변수를 유지할 수 있는 파일 경로를 제공합니다.
1281 1280
1282개별 환경 변수를 설정하려면 `export` 문을 `CLAUDE_ENV_FILE`에 작성합니다. 다른 훅이 설정한 변수를 보존하려면 추가(`>>`)를 사용합니다.1281개별 환경 변수를 설정하려면 `CLAUDE_ENV_FILE`에 `export` 문을 작성하세요. 다른 훅이 설정한 변수를 보존하려면 추가(`>>`)를 사용하세요:
1283 1282
1284```bash theme={null}1283```bash theme={null}
1285#!/bin/bash1284#!/bin/bash
1293exit 01292exit 0
1294```1293```
1295 1294
1296설정 명령으로 인한 모든 환경 변경 사항을 캡처하려면 전후의 내보낸 변수를 비교합니다.1295설정 명령에서 발생한 모든 환경 변경 사항을 캡처하려면 전후의 내보낸 변수를 비교하세요:
1297 1296
1298```bash theme={null}1297```bash theme={null}
1299#!/bin/bash1298#!/bin/bash
1320 Setup1319 Setup
1321</h3>1320</h3>
1322 1321
1323`--init-only`로 Claude Code를 실행하거나, `-p` 플래그를 사용하는 [비대화형 모드](/docs/ko/headless)에서 `--init` 또는 `--maintenance`로 실행할 때만 발생합니다. 일반 시작 시에는 발생하지 않습니다. 일반 세션 시작과 별도로 CI나 스크립트에서 명시적으로 트리거하는 일회성 의존성 설치나 예약된 정리 작업에 사용합니다. 세션별 초기화에는 대신 [SessionStart](#sessionstart)를 사용합니다.1322`--init-only`로 Claude Code를 실행하거나, `-p` 플래그를 사용하는 [비대화형 모드](/docs/ko/headless)에서 `--init` 또는 `--maintenance`로 실행할 때만 발생합니다. 일반 시작 시에는 발생하지 않습니다. 일반 세션 시작과 별도로 CI나 스크립트에서 명시적으로 트리거하는 일회성 의존성 설치나 예약된 정리에 사용하세요. 세션별 초기화에는 대신 [SessionStart](#sessionstart)를 사용하세요.
1324 1323
1325matcher 값은 훅을 트리거한 CLI 플래그에 해당합니다.1324matcher 값은 훅을 트리거한 CLI 플래그에 해당합니다:
1326 1325
1327| Matcher | 발생 시점 |1326| Matcher | 발생 시점 |
1328| :- | :- |1327| :- | :- |
1329| `init` | `claude --init-only` 또는 `claude -p --init` |1328| `init` | `claude --init-only` 또는 `claude -p --init` |
1330| `maintenance` | `claude -p --maintenance` |1329| `maintenance` | `claude -p --maintenance` |
1331 1330
1332`claude --init-only`를 실행하면 Claude Code는 Setup 훅과 `startup` matcher를 사용하는 `SessionStart` 훅을 실행한 다음 대화를 시작하지 않고 종료합니다.1331`claude --init-only`를 실행하면 Claude Code는 Setup 훅과 `startup` matcher를 사용하는 `SessionStart` 훅을 실행한 다음, 대화를 시작하지 않고 종료합니다.
1333 1332
1334`-p`로 대화를 시작하거나 계속하는 경우 프롬프트도 인수로 제공하거나 stdin으로 파이프해야 합니다. `SessionStart` 훅이 [`initialUserMessage`](#sessionstart-decision-control)를 제공하거나 [지연된 도구 호출](#defer-a-tool-call-for-later)이 있는 세션을 재개하는 경우에는 프롬프트를 생략할 수 있습니다.1333`-p`로 대화를 시작하거나 계속할 때는 인수로 또는 stdin 파이프를 통해 프롬프트도 제공해야 합니다. `SessionStart` 훅이 [`initialUserMessage`](#sessionstart-decision-control)를 제공하거나 [지연된 도구 호출](#defer-a-tool-call-for-later)이 있는 세션을 재개할 때는 프롬프트를 생략할 수 있습니다.
1335 1334
1336성공하면 `--init-only`는 터미널에 아무것도 출력하지 않습니다. 훅이 실행되었는지 확인하려면 `<path>`를 로그 파일 위치로 바꿔 `claude --debug-file <path> --init-only`로 시작한 다음, 로그에서 Setup 및 SessionStart 훅 항목을 확인합니다.1335성공하면 `--init-only`는 터미널에 아무것도 출력하지 않습니다. 훅이 실행되었는지 확인하려면 `<path>`를 로그 파일 위치로 바꿔 `claude --debug-file <path> --init-only`로 시작한 다음, 로그에서 Setup 및 SessionStart 훅 항목을 확인하세요.
1337 1336
1338Setup은 매번 실행 시 발생하지 않으므로, 의존성 설치가 필요한 플러그인은 Setup에만 의존할 수 없습니다. 실용적인 패턴은 처음 사용할 때 의존성을 확인하고 없으면 설치하는 것입니다. 예를 들어 훅이나 스킬이 `${CLAUDE_PLUGIN_DATA}/node_modules`가 있는지 확인하고 없으면 `npm install`을 실행할 수 있습니다. 설치된 의존성을 저장할 위치는 [영구 데이터 디렉터리](/docs/ko/plugins/components#path-variables-and-persistent-data)를 참조하세요. 마켓플레이스를 통해 플러그인을 배포하는 경우에는 이 패턴이 필요하지 않을 수 있습니다. Claude Code는 플러그인을 캐시할 때 [적격한 Node.js 패키지 의존성을 자동으로 설치](/docs/ko/plugins/loading#node-js-package-dependencies)합니다.1337Setup은 모든 실행에서 발생하는 것이 아니므로, 의존성 설치가 필요한 플러그인은 Setup에만 의존할 수 없습니다. 실용적인 패턴은 처음 사용할 때 의존성을 확인하고 없으면 설치하는 것입니다. 예를 들어 `${CLAUDE_PLUGIN_DATA}/node_modules`가 있는지 테스트하고 없으면 `npm install`을 실행하는 훅이나 스킬을 사용할 수 있습니다. 설치된 의존성을 저장할 위치는 [영구 데이터 디렉터리](/docs/ko/plugins/components#path-variables-and-persistent-data)를 참조하세요. 마켓플레이스를 통해 플러그인을 배포한다면 이 패턴이 필요하지 않을 수 있습니다. Claude Code는 플러그인을 캐시할 때 [적격한 Node.js 패키지 의존성을 자동으로 설치](/docs/ko/plugins/loading#node-js-package-dependencies)합니다.
1339 1338
1340<h4 id="setup-input">1339<h4 id="setup-input">
1341 Setup 입력1340 Setup 입력
1342</h4>1341</h4>
1343 1342
1344[공통 입력 필드](#common-input-fields) 외에도 Setup 훅은 `"init"` 또는 `"maintenance"`로 설정된 `trigger` 필드를 수신합니다.1343[공통 입력 필드](#common-input-fields) 외에도 Setup 훅은 `"init"` 또는 `"maintenance"`로 설정된 `trigger` 필드를 받습니다:
1345 1344
1346```json theme={null}1345```json theme={null}
1347{1346{
1357 Setup 결정 제어1356 Setup 결정 제어
1358</h4>1357</h4>
1359 1358
1360Setup 훅은 차단할 수 없으며, 종료 코드와 관계없이 실행이 계속됩니다. 모든 종료 코드에서 Claude Code는 `systemMessage`, `continue`, `hookSpecificOutput.additionalContext` 같은 Setup 훅의 [JSON 출력 필드](#json-output)를 버립니다. `-p`를 사용하는 경우 Setup 훅의 stdout, stderr, 종료 코드는 `--output-format stream-json --verbose`로 실행할 때만 실행 출력에 [`hook_response` 이벤트](/docs/ko/headless#read-session-metadata)로 나타납니다.1359Setup 훅은 차단할 수 없으며, 어떤 종료 코드에서도 실행이 계속됩니다. 모든 종료 코드에서 Claude Code는 `systemMessage`, `continue`, `hookSpecificOutput.additionalContext` 같은 Setup 훅의 [JSON 출력 필드](#json-output)를 버립니다. `-p` 사용 시 Setup 훅의 stdout, stderr, 종료 코드는 `--output-format stream-json --verbose`로 실행할 때만 [`hook_response` 이벤트](/docs/ko/headless#read-session-metadata)로 실행 출력에 나타납니다.
1361 1360
1362Setup 훅은 `CLAUDE_ENV_FILE`에 액세스할 수 있습니다. [SessionStart 훅](#persist-environment-variables)과 마찬가지로 해당 파일에 쓴 변수는 세션의 후속 Bash 명령에 유지됩니다. `Setup`에서는 `type: "command"` 훅만 실행됩니다. [MCP 도구 훅 필드](#mcp-tool-hook-fields)에 설명된 대로 `Setup`의 `type: "mcp_tool"` 훅은 항상 건너뜁니다.1361Setup 훅은 `CLAUDE_ENV_FILE`에 액세스할 수 있습니다. 이 파일에 쓴 변수는 [SessionStart 훅](#persist-environment-variables)과 마찬가지로 세션의 이후 Bash 명령에 유지됩니다. `Setup`에서는 `type: "command"` 훅만 실행됩니다. `Setup`의 `type: "mcp_tool"` 훅은 [MCP 도구 훅 필드](#mcp-tool-hook-fields)에서 설명한 대로 항상 건너뜁니다.
1363 1362
1364<h3 id="instructionsloaded">1363<h3 id="instructionsloaded">
1365 InstructionsLoaded1364 InstructionsLoaded
1366</h3>1365</h3>
1367 1366
1368`CLAUDE.md` 또는 `.claude/rules/*.md` 파일이 컨텍스트에 로드될 때 발생합니다. 이 이벤트는 즉시 로드되는 파일에 대해 세션 시작 시 발생하고, 나중에 파일이 지연 로드될 때 다시 발생합니다. 예를 들어 Claude가 중첩된 `CLAUDE.md`가 포함된 하위 디렉터리에 액세스하거나 `paths:` frontmatter가 있는 조건부 규칙이 일치할 때입니다. 이 훅은 차단이나 결정 제어를 지원하지 않습니다. 관찰 가능성을 위해 비동기적으로 실행됩니다.1367`CLAUDE.md` 또는 `.claude/rules/*.md` 파일이 컨텍스트에 로드될 때 발생합니다. 이 이벤트는 즉시 로드되는 파일에 대해 세션 시작 시 발생하고, 파일이 지연 로드될 때 나중에 다시 발생합니다. 예를 들어 Claude가 중첩된 `CLAUDE.md`가 있는 하위 디렉터리에 액세스하거나 `paths:` frontmatter가 있는 조건부 규칙이 일치할 때입니다. 이 훅은 차단이나 결정 제어를 지원하지 않으며, 관찰 가능성을 위해 비동기적으로 실행됩니다.
1369 1368
1370이 이벤트는 Claude가 **Project instructions** 설정을 통해 [`AGENTS.md`를 직접 읽을](/docs/ko/memory#agents-md) 때는 발생하지 않습니다. `CLAUDE.md`가 `AGENTS.md`를 가져오는 경우에는 다른 가져온 파일과 마찬가지로 `load_reason`이 `include`로 설정되어 발생하며, `CLAUDE.md`가 해당 파일에 대한 심볼릭 링크인 경우에는 일반적인 `CLAUDE.md` 로드로 발생합니다.1369이 이벤트는 Claude가 **Project instructions** 설정을 통해 [`AGENTS.md`를 직접 읽을](/docs/ko/memory#agents-md) 때는 발생하지 않습니다. `CLAUDE.md`가 `AGENTS.md`를 가져올 때는 다른 가져온 파일과 마찬가지로 `load_reason`이 `include`로 설정된 상태로 발생하며, `CLAUDE.md`가 해당 파일에 대한 심볼릭 링크일 때는 일반 `CLAUDE.md` 로드로 발생합니다.
1371 1370
1372matcher는 `load_reason`에 대해 실행됩니다. 예를 들어 세션 시작 시 로드된 파일에 대해서만 발생시키려면 `"matcher": "session_start"`를, 지연 로드에 대해서만 발생시키려면 `"matcher": "path_glob_match|nested_traversal"`을 사용합니다.1371matcher는 `load_reason`에 대해 실행됩니다. 예를 들어 세션 시작 시 로드된 파일에만 발생시키려면 `"matcher": "session_start"`를, 지연 로드에만 발생시키려면 `"matcher": "path_glob_match|nested_traversal"`을 사용하세요.
1373 1372
1374<h4 id="instructionsloaded-input">1373<h4 id="instructionsloaded-input">
1375 InstructionsLoaded 입력1374 InstructionsLoaded 입력
1376</h4>1375</h4>
1377 1376
1378[공통 입력 필드](#common-input-fields) 외에도 InstructionsLoaded 훅은 다음 필드를 수신합니다.1377[공통 입력 필드](#common-input-fields) 외에도 InstructionsLoaded 훅은 다음 필드를 받습니다:
1379 1378
1380| 필드 | 설명 |1379| 필드 | 설명 |
1381| :- | :- |1380| :- | :- |
1382| `file_path` | 로드된 지침 파일의 절대 경로 |1381| `file_path` | 로드된 지침 파일의 절대 경로 |
1383| `memory_type` | 파일의 범위: `"User"`, `"Project"`, `"Local"` 또는 `"Managed"` |1382| `memory_type` | 파일의 범위: `"User"`, `"Project"`, `"Local"` 또는 `"Managed"` |
1384| `load_reason` | 파일이 로드된 이유: `"session_start"`, `"nested_traversal"`, `"path_glob_match"`, `"include"` 또는 `"compact"`. `"compact"` 값은 압축 이벤트 후 지침 파일이 다시 로드될 때 발생합니다 |1383| `load_reason` | 파일이 로드된 이유: `"session_start"`, `"nested_traversal"`, `"path_glob_match"`, `"include"` 또는 `"compact"`. `"compact"` 값은 압축 이벤트 후 지침 파일이 다시 로드될 때 발생합니다 |
1385| `globs` | 파일의 `paths:` frontmatter에 있는 경로 glob 패턴(있는 경우). `path_glob_match` 로드에만 포함됩니다 |1384| `globs` | 파일의 `paths:` frontmatter에 있는 경로 glob 패턴(있는 경우). `path_glob_match` 로드에만 존재합니다 |
1386| `trigger_file_path` | 지연 로드의 경우, 액세스하여 이 로드를 트리거한 파일의 경로 |1385| `trigger_file_path` | 지연 로드의 경우, 액세스하여 이 로드를 트리거한 파일의 경로 |
1387| `parent_file_path` | `include` 로드의 경우, 이 파일을 포함한 상위 지침 파일의 경로 |1386| `parent_file_path` | `include` 로드의 경우, 이 파일을 포함한 상위 지침 파일의 경로 |
1388 1387
1402 InstructionsLoaded 결정 제어1401 InstructionsLoaded 결정 제어
1403</h4>1402</h4>
1404 1403
1405InstructionsLoaded 훅에는 결정 제어가 없습니다. 지침 로드를 차단하거나 수정할 수 없습니다. Claude Code는 `systemMessage`, `continue` 같은 [JSON 출력 필드](#json-output)를 버립니다. 이 이벤트는 감사 로깅, 규정 준수 추적 또는 관측 가능성에 사용합니다.1404InstructionsLoaded 훅에는 결정 제어가 없습니다. 지침 로드를 차단하거나 수정할 수 없습니다. Claude Code는 `systemMessage`, `continue` 같은 [JSON 출력 필드](#json-output)를 버립니다. 이 이벤트는 감사 로깅, 규정 준수 추적 또는 관찰 가능성에 사용하세요.
1406 1405
1407<h3 id="userpromptsubmit">1406<h3 id="userpromptsubmit">
1408 UserPromptSubmit1407 UserPromptSubmit
1409</h3>1408</h3>
1410 1409
1411프롬프트가 제출된 후 Claude가 처리하기 전에 실행됩니다. 이를 통해1410프롬프트가 제출될 때, Claude가 처리하기 전에 실행됩니다. 이를 통해
1412프롬프트/대화를 기반으로 추가 컨텍스트를 추가하거나, 프롬프트를 검증하거나,1411프롬프트/대화를 기반으로 추가 컨텍스트를 추가하거나, 프롬프트를 검증하거나,
1413특정 유형의 프롬프트를 차단할 수 있습니다.1412특정 유형의 프롬프트를 차단할 수 있습니다.
1414 1413
1415`UserPromptSubmit` 훅은 사용자가 입력한 프롬프트에서만 발생하는 것이 아닙니다. Claude Code는 다음 경우에도 이 훅을 실행합니다.1414`UserPromptSubmit` 훅은 직접 입력한 프롬프트에서만 발생하는 것이 아닙니다. Claude Code는 다음 경우에도 이 훅을 실행합니다:
1416 1415
1417* `/loop` 반복을 포함해 [예약 작업](/docs/ko/scheduled-tasks)이 실행될 때1416* [예약 작업](/docs/ko/scheduled-tasks)이 실행될 때(`/loop` 반복 포함)
1418* [백그라운드 서브에이전트](/docs/ko/sub-agents#run-subagents-in-foreground-or-background)가 자신을 시작한 세션에 결과를 보고할 때1417* [백그라운드 서브에이전트](/docs/ko/sub-agents#run-subagents-in-foreground-or-background)가 자신을 시작한 세션에 결과를 보고할 때
1419* [다른 세션이 보낸 메시지](/docs/ko/cross-session-messaging)가 메인 대화에 도착할 때1418* [다른 세션이 기본 대화로 메시지를 보낼](/docs/ko/cross-session-messaging) 때
1420 1419
1421`UserPromptSubmit` 훅의 기본 타임아웃은 `command`, `http`, `mcp_tool` 유형에 대해 30초로, 대부분의 다른 이벤트에서 이 유형들의 기본값인 600초보다 짧습니다. 이 훅은 모든 프롬프트 전에 실행되고 완료될 때까지 모델 처리를 차단하므로, 멈춘 훅은 세션을 지연시킵니다. 훅에 더 많은 시간이 필요하면 훅 항목에서 `timeout` 필드를 설정합니다.1420`UserPromptSubmit` 훅은 `command`, `http`, `mcp_tool` 유형의 기본 타임아웃이 30초로, 대부분의 다른 이벤트에서 이러한 유형의 기본값인 600초보다 짧습니다. 이 훅은 모든 프롬프트 전에 실행되고 완료될 때까지 모델 처리를 차단하므로, 멈춘 훅은 세션을 정지시킵니다. 훅에 더 많은 시간이 필요하면 훅 항목에서 `timeout` 필드를 설정하세요.
1422 1421
1423[`async: true`](#run-hooks-in-the-background)로 실행하는 command 훅을 제외하면, 타임아웃에 도달한 `UserPromptSubmit` command, HTTP 또는 MCP 도구 훅은 취소되며 `additionalContext`를 포함한 출력이 버려집니다. 프롬프트는 해당 컨텍스트 없이 Claude에 전달됩니다. 트랜스크립트에는 훅 이름, 발생한 타임아웃, 출력이 버려졌다는 사실을 알리는 알림이 표시됩니다.1422[`async: true`](#run-hooks-in-the-background)로 실행하는 command 훅을 제외하고, 타임아웃에 도달한 `UserPromptSubmit` command, HTTP 또는 MCP 도구 훅은 취소되며 `additionalContext`를 포함한 출력은 버려집니다. 프롬프트는 해당 컨텍스트 없이 여전히 Claude에 전달됩니다. 트랜스크립트에는 훅 이름, 발생한 타임아웃, 출력이 버려졌다는 사실을 알리는 알림이 표시됩니다.
1424 1423
1425타임아웃에 도달한 `UserPromptSubmit`의 [Agent SDK 콜백 훅](/docs/ko/agent-sdk/hooks)은 훅 이름과 타임아웃을 명시한 메시지와 함께 프롬프트를 차단합니다. 해당 위치의 콜백은 실패 시 열림(fail open) 상태가 되어서는 안 되는 정책 게이트 역할을 할 수 있기 때문입니다. 세션은 계속됩니다. v2.1.208 이전에는 해당 이벤트에서 콜백 타임아웃이 발생하면 실행 오류와 함께 턴이 종료되었습니다.1424`UserPromptSubmit`의 [Agent SDK 콜백 훅](/docs/ko/agent-sdk/hooks)이 타임아웃에 도달하면 훅과 타임아웃을 명시하는 메시지와 함께 프롬프트가 차단됩니다. 이 위치의 콜백은 실패 시 열려서는 안 되는(fail open) 정책 게이트 역할을 할 수 있기 때문입니다. 세션은 계속됩니다. v2.1.208 이전에는 이 이벤트에서 콜백 타임아웃이 발생하면 실행 오류와 함께 턴이 종료되었습니다.
1426 1425
1427<h4 id="userpromptsubmit-input">1426<h4 id="userpromptsubmit-input">
1428 UserPromptSubmit 입력1427 UserPromptSubmit 입력
1429</h4>1428</h4>
1430 1429
1431[공통 입력 필드](#common-input-fields) 외에도 UserPromptSubmit 훅은 제출된 텍스트가 담긴 `prompt` 필드를 받습니다. `[Pasted text #N]` 자리 표시자로 축소된 붙여 넣은 콘텐츠는 제자리에 펼쳐진 상태로 전달됩니다. Claude Code가 [붙여 넣은 텍스트를 Claude용으로 표시하는](/docs/ko/terminal-config#how-claude-treats-pasted-text) 세션에서는 펼쳐진 콘텐츠가 `<pasted_content id="…">` 줄과 `</pasted_content id="…">` 줄 사이에 위치하므로, 훅이 프롬프트를 파싱한다면 해당 줄을 고려하세요.1430[공통 입력 필드](#common-input-fields) 외에도 UserPromptSubmit 훅은 제출된 텍스트가 담긴 `prompt` 필드를 받습니다. `[Pasted text #N]` 자리 표시자로 축소된 붙여넣은 콘텐츠는 제자리에 펼쳐진 상태로 전달됩니다. Claude Code가 [Claude를 위해 붙여넣은 텍스트를 표시하는](/docs/ko/terminal-config#how-claude-treats-pasted-text) 세션에서는 펼쳐진 콘텐츠가 `<pasted_content id="…">` 줄과 `</pasted_content id="…">` 줄 사이에 위치하므로, 훅이 프롬프트를 파싱한다면 이 줄을 고려하세요.
1432 1431
1433UserPromptSubmit 훅은 세션에 사용자 지정 제목이 있을 때 `session_title`도 수신하며, 의미는 [SessionStart의 `session_title` 필드](#sessionstart-input)와 같습니다.1432UserPromptSubmit 훅은 세션에 사용자 지정 제목이 있을 때 `session_title`도 받으며, 의미는 [SessionStart `session_title` 필드](#sessionstart-input)와 같습니다.
1434 1433
1435```json theme={null}1434```json theme={null}
1436{1435{
1449 1448
1450`UserPromptSubmit` 훅은 제출된 프롬프트의 처리 여부를 제어하고 컨텍스트를 추가할 수 있습니다. 모든 [JSON 출력 필드](#json-output)를 사용할 수 있습니다.1449`UserPromptSubmit` 훅은 제출된 프롬프트의 처리 여부를 제어하고 컨텍스트를 추가할 수 있습니다. 모든 [JSON 출력 필드](#json-output)를 사용할 수 있습니다.
1451 1450
1452종료 코드 0에서 대화에 컨텍스트를 추가하는 방법은 두 가지입니다.1451종료 코드 0에서 대화에 컨텍스트를 추가하는 방법은 두 가지입니다:
1453 1452
1454* **일반 텍스트 stdout**: Claude Code는 [일반 텍스트로 처리하는](#exit-code-0) stdout을 Claude의 컨텍스트에 추가합니다1453* **일반 텍스트 stdout**: Claude Code는 [일반 텍스트로 처리하는](#exit-code-0) stdout을 Claude의 컨텍스트에 추가합니다
1455* **`additionalContext`가 포함된 JSON**: 더 세밀하게 제어하려면 아래 JSON 형식을 사용합니다. `additionalContext` 필드가 컨텍스트로 추가됩니다1454* **`additionalContext`가 포함된 JSON**: 더 세밀하게 제어하려면 아래 JSON 형식을 사용하세요. `additionalContext` 필드가 컨텍스트로 추가됩니다
1456 1455
1457어느 채널도 트랜스크립트에 보이는 항목을 생성하지 않습니다. 일반 stdout과 `additionalContext` 값은 각각 훅 이름으로 시작하는 시스템 리마인더로 주입되며, Claude는 둘 다 읽습니다. 전달 여부를 확인하려면 [디버그 로그](#debug-hooks)를 확인합니다.1456두 채널 모두 트랜스크립트에 표시되는 항목을 만들지 않습니다. 일반 stdout과 `additionalContext` 값은 각각 훅 이름으로 시작하는 시스템 리마인더로 주입되며, Claude는 둘 다 읽습니다. 전달 여부를 확인하려면 [디버그 로그](#debug-hooks)를 확인하세요.
1458 1457
1459프롬프트를 차단하려면 `decision`이 `"block"`으로 설정된 JSON 객체를 반환합니다.1458프롬프트를 차단하려면 `decision`을 `"block"`으로 설정한 JSON 객체를 반환하세요:
1460 1459
1461| 필드 | 설명 |1460| 필드 | 설명 |
1462| :- | :- |1461| :- | :- |
1463| `decision` | `"block"`은 프롬프트가 Claude에 도달하기 전에 중지합니다. 프롬프트 진행을 허용하려면 생략합니다 |1462| `decision` | `"block"`은 프롬프트가 Claude에 도달하기 전에 중지합니다. 프롬프트 진행을 허용하려면 생략하세요 |
1464| `reason` | `decision`이 `"block"`일 때 사용자에게 표시됩니다. 컨텍스트에는 추가되지 않습니다 |1463| `reason` | `decision`이 `"block"`일 때 사용자에게 표시됩니다. 컨텍스트에는 추가되지 않습니다 |
1465| `additionalContext` | 제출된 프롬프트와 함께 Claude의 컨텍스트에 추가되는 문자열. [Claude를 위한 컨텍스트 추가](#add-context-for-claude)를 참조하세요 |1464| `additionalContext` | 제출된 프롬프트와 함께 Claude의 컨텍스트에 추가되는 문자열. [Claude를 위한 컨텍스트 추가](#add-context-for-claude)를 참조하세요 |
1466| `sessionTitle` | 세션 제목을 설정합니다. 프롬프트 내용을 기반으로 세션 이름을 자동으로 지정하는 데 사용합니다 |1465| `sessionTitle` | 세션 제목을 설정합니다. 프롬프트 내용을 기반으로 세션 이름을 자동 지정하는 데 사용합니다 |
1467| `suppressOriginalPrompt` | 훅이 프롬프트를 차단할 때 `true`이면 차단 메시지에서 프롬프트 텍스트를 제외합니다. [차단된 프롬프트가 남기는 것](#what-a-blocked-prompt-leaves-behind)을 참조하세요 |1466| `suppressOriginalPrompt` | 훅이 프롬프트를 차단할 때 `true`이면 차단 메시지에서 프롬프트 텍스트를 제외합니다. [차단된 프롬프트가 남기는 것](#what-a-blocked-prompt-leaves-behind)을 참조하세요 |
1468 1467
1469종료 코드 2로 차단하는 훅은 `reason`과 같은 방식으로 전달됩니다. 차단 메시지에 stderr 텍스트가 사용자에게 표시되며, 컨텍스트에는 추가되지 않습니다.1468종료 코드 2로 차단하는 훅은 `reason`과 같은 방식으로 처리됩니다. 차단 메시지는 stderr 텍스트를 사용자에게 표시하며, 이 텍스트는 컨텍스트에 추가되지 않습니다.
1470 1469
1471```json theme={null}1470```json theme={null}
1472{1471{
1485 차단된 프롬프트가 남기는 것1484 차단된 프롬프트가 남기는 것
1486</h4>1485</h4>
1487 1486
1488차단된 프롬프트는 Claude에 도달하지 않지만, 그 텍스트가 모든 곳에서 제거되는 것은 아닙니다. 기본적으로 사용자에게 표시되는 차단 메시지는 `Original prompt:` 뒤에 제출된 텍스트가 이어지는 형태로 끝나며, Claude Code는 이 메시지를 디스크의 세션 트랜스크립트 파일에 씁니다. 메시지에서 텍스트를 제외하려면 `hookSpecificOutput` 안에 `"suppressOriginalPrompt": true`가 포함된 JSON을 출력하십시오. 이는 훅이 `decision: "block"`으로 차단하든 종료 코드 2로 차단하든 작동합니다.1487차단된 프롬프트는 Claude에 도달하지 않지만, 그 텍스트가 모든 곳에서 제거되는 것은 아닙니다. 기본적으로 사용자에게 표시되는 차단 메시지는 `Original prompt:` 뒤에 제출된 텍스트가 오는 형태로 끝나며, Claude Code는 이 메시지를 디스크의 세션 트랜스크립트 파일에 씁니다. 메시지에서 텍스트를 제외하려면 `hookSpecificOutput` 안에 `"suppressOriginalPrompt": true`가 포함된 JSON을 출력하세요. 이는 훅이 `decision: "block"`으로 차단하든 종료 코드 2로 차단하든 작동합니다.
1489 1488
1490`suppressOriginalPrompt`는 차단 메시지만 변경합니다. 제출된 텍스트는 세션 트랜스크립트나 프롬프트 기록 같은 로컬 파일에 여전히 나타날 수 있으므로, 차단 훅은 비밀 정보를 디스크에 남기지 않는 방법이 아닙니다. 이러한 파일을 제한하거나 제거하려면 [일반 텍스트 스토리지](/docs/ko/claude-directory#plaintext-storage) 및 [로컬 데이터 지우기](/docs/ko/claude-directory#clear-local-data)를 참조하세요.1489`suppressOriginalPrompt`는 차단 메시지만 변경합니다. 제출된 텍스트는 세션 트랜스크립트나 프롬프트 기록 같은 로컬 파일에 여전히 나타날 수 있으므로, 차단 훅은 비밀 정보를 디스크에 남기지 않는 방법이 아닙니다. 이러한 파일을 제한하거나 제거하려면 [일반 텍스트 저장](/docs/ko/claude-directory#plaintext-storage) 및 [로컬 데이터 지우기](/docs/ko/claude-directory#clear-local-data)를 참조하세요.
1491 1490
1492<h3 id="userpromptexpansion">1491<h3 id="userpromptexpansion">
1493 UserPromptExpansion1492 UserPromptExpansion
1494</h3>1493</h3>
1495 1494
1496사용자가 입력한 명령이 Claude에 도달하기 전에 프롬프트로 확장될 때 실행됩니다. 특정 명령의 직접 호출을 차단하거나, 특정 스킬에 컨텍스트를 주입하거나, 사용자가 호출하는 명령을 로그에 기록하는 데 사용합니다. 예를 들어 `deploy`와 일치하는 훅은 승인 파일이 없으면 `/deploy`를 차단할 수 있고, 리뷰 스킬과 일치하는 훅은 팀의 리뷰 체크리스트를 `additionalContext`로 추가할 수 있습니다.1495사용자가 입력한 명령이 Claude에 도달하기 전에 프롬프트로 확장될 때 실행됩니다. 특정 명령의 직접 호출을 차단하거나, 특정 스킬에 컨텍스트를 주입하거나, 사용자가 호출하는 명령을 로그에 기록하는 데 사용하세요. 예를 들어 `deploy`와 일치하는 훅은 승인 파일이 없으면 `/deploy`를 차단할 수 있고, 리뷰 스킬과 일치하는 훅은 팀의 리뷰 체크리스트를 `additionalContext`로 추가할 수 있습니다.
1497 1496
1498이 이벤트는 `PreToolUse`가 다루지 않는 경로를 다룹니다. `Skill` 도구와 일치하는 `PreToolUse` 훅은 Claude가 도구를 호출할 때만 발생하지만, `/skillname`을 직접 입력하면 `PreToolUse`를 거치지 않습니다. `UserPromptExpansion`은 이 직접 경로에서 발생합니다.1497이 이벤트는 `PreToolUse`가 다루지 않는 경로를 다룹니다. `Skill` 도구와 일치하는 `PreToolUse` 훅은 Claude가 도구를 호출할 때만 발생하지만, `/skillname`을 직접 입력하면 `PreToolUse`를 우회합니다. `UserPromptExpansion`은 이 직접 경로에서 발생합니다.
1499 1498
1500`command_name`에 대해 일치시킵니다. 모든 프롬프트 유형 명령에서 발생시키려면 matcher를 비워 둡니다.1499`command_name`에 대해 매칭합니다. 모든 프롬프트 유형 명령에서 발생시키려면 matcher를 비워 두세요.
1501 1500
1502<h4 id="userpromptexpansion-input">1501<h4 id="userpromptexpansion-input">
1503 UserPromptExpansion 입력1502 UserPromptExpansion 입력
1504</h4>1503</h4>
1505 1504
1506[공통 입력 필드](#common-input-fields) 외에도 UserPromptExpansion 훅은 `expansion_type`, `command_name`, `command_args`, `command_source`, 그리고 원래의 `prompt` 문자열을 수신합니다. `expansion_type` 필드는 스킬 및 사용자 지정 명령의 경우 `slash_command`, MCP 서버 프롬프트의 경우 `mcp_prompt`입니다.1505[공통 입력 필드](#common-input-fields) 외에도 UserPromptExpansion 훅은 `expansion_type`, `command_name`, `command_args`, `command_source`, 원래 `prompt` 문자열을 받습니다. `expansion_type` 필드는 스킬 및 사용자 지정 명령의 경우 `slash_command`, MCP 서버 프롬프트의 경우 `mcp_prompt`입니다.
1507 1506
1508```json theme={null}1507```json theme={null}
1509{1508{
1528 1527
1529| 필드 | 설명 |1528| 필드 | 설명 |
1530| :- | :- |1529| :- | :- |
1531| `decision` | `"block"`은 명령이 확장되지 않도록 합니다. 진행을 허용하려면 생략합니다 |1530| `decision` | `"block"`은 명령이 확장되지 않도록 합니다. 진행을 허용하려면 생략하세요 |
1532| `reason` | `decision`이 `"block"`일 때 사용자에게 표시됩니다 |1531| `reason` | `decision`이 `"block"`일 때 사용자에게 표시됩니다 |
1533| `additionalContext` | 확장된 프롬프트와 함께 Claude의 컨텍스트에 추가되는 문자열. [Claude를 위한 컨텍스트 추가](#add-context-for-claude)를 참조하세요 |1532| `additionalContext` | 확장된 프롬프트와 함께 Claude의 컨텍스트에 추가되는 문자열. [Claude를 위한 컨텍스트 추가](#add-context-for-claude)를 참조하세요 |
1534 1533
1535종료 코드 2로 차단하는 훅은 `reason`과 같은 방식으로 전달됩니다. 차단 메시지에 stderr 텍스트가 사용자에게 표시됩니다.1534종료 코드 2로 차단하는 훅은 `reason`과 같은 방식으로 처리됩니다. 차단 메시지는 stderr 텍스트를 사용자에게 표시합니다.
1536 1535
1537```json theme={null}1536```json theme={null}
1538{1537{
1549 MessageDisplay1548 MessageDisplay
1550</h3>1549</h3>
1551 1550
1552어시스턴트 메시지가 화면에 스트리밍되는 동안 실행됩니다. Claude Code는 메시지를 단계적으로 표시합니다. 새로 완성된 줄의 묶음이 렌더링될 준비가 될 때마다 훅이 해당 줄로 한 번 실행되고, Claude Code는 그 자리에 훅의 대체 텍스트를 렌더링합니다. 긴 메시지는 여러 번의 호출을 생성하며, 짧은 메시지는 한 번만 생성할 수도 있습니다.1551어시스턴트 메시지가 화면으로 스트리밍되는 동안 실행됩니다. Claude Code는 메시지를 단계적으로 표시합니다. 새로 완성된 줄의 배치가 렌더링될 준비가 될 때마다 훅이 해당 줄로 한 번 실행되고, Claude Code는 그 자리에 훅의 대체 텍스트를 렌더링합니다. 긴 메시지는 여러 번 호출되며, 짧은 메시지는 한 번만 호출될 수 있습니다.
1553 1552
1554MessageDisplay는 다음 용도로 사용합니다.1553MessageDisplay는 다음 용도로 사용합니다:
1555 1554
1556* 최소한의 표시를 위해 markdown 제거1555* 최소한의 표시를 위해 markdown 제거
1557* Agent SDK 애플리케이션이 사용자에게 보여 주는 텍스트 변환1556* Agent SDK 애플리케이션이 사용자에게 보여 주는 텍스트 변환
1558* Claude의 응답에서 API 키나 내부 호스트 이름 가리기1557* Claude의 응답에서 API 키나 내부 호스트 이름 삭제
1559 1558
1560Claude Code는 훅이 반환될 때까지 각 묶음을 보류하므로 훅을 빠르게 유지해야 합니다. 훅이 실패하거나 시간 초과되면 Claude Code는 원래 텍스트를 표시합니다. 이 이벤트의 기본 타임아웃은 10초이며, 훅에 더 많은 시간이 필요하면 훅 항목에서 `timeout` 필드를 설정합니다.1559Claude Code는 훅이 반환할 때까지 각 배치를 보류하므로 훅을 빠르게 유지하세요. 훅이 실패하거나 시간 초과되면 Claude Code는 원래 텍스트를 표시합니다. 이 이벤트의 기본 타임아웃은 10초이며, 훅에 더 많은 시간이 필요하면 훅 항목에서 `timeout` 필드를 설정하세요.
1561 1560
1562MessageDisplay는 표시 전용입니다. 대체 텍스트는 화면에 렌더링되는 내용만 변경합니다. 트랜스크립트와 Claude가 보는 내용은 원래 텍스트를 유지하므로 Claude는 대체 텍스트를 보지 않으며, verbose 모드에서는 원래 텍스트가 표시됩니다. 훅은 어시스턴트 메시지 텍스트만 수신하므로 도구 결과와 사용자가 입력하는 텍스트는 변경 없이 렌더링됩니다.1561MessageDisplay는 표시 전용입니다. 대체 텍스트는 화면에 렌더링되는 내용만 변경합니다. 트랜스크립트와 Claude가 보는 내용은 원래 텍스트를 유지하므로 Claude는 대체 텍스트를 보지 않으며, verbose 모드에서는 원래 텍스트가 표시됩니다. 훅은 어시스턴트 메시지 텍스트만 받으므로 도구 결과와 사용자가 입력한 텍스트는 변경 없이 렌더링됩니다.
1563 1562
1564MessageDisplay는 matcher를 지원하지 않으며 텍스트를 스트리밍하는 모든 어시스턴트 메시지에서 발생합니다. 도구 호출만 있는 응답처럼 텍스트가 없는 메시지는 이 이벤트를 트리거하지 않습니다.1563MessageDisplay는 matcher를 지원하지 않으며 텍스트를 스트리밍하는 모든 어시스턴트 메시지에 대해 발생합니다. 도구 호출만 있는 응답처럼 텍스트가 없는 메시지는 이 훅을 트리거하지 않습니다.
1565 1564
1566Agent SDK 쿼리와 `claude -p`를 포함한 비대화형 실행에서는 MessageDisplay가 줄 묶음마다가 아니라 어시스턴트 메시지마다 한 번 실행됩니다. 단일 호출은 메시지가 완료된 후 도착하며 전체 메시지 텍스트를 담습니다. `index`는 `0`, `final`은 `true`이고, `delta`에는 전체 메시지가 들어 있습니다. 각 메시지의 `delta` 텍스트를 수집하는 훅은 두 모드에서 동일한 전체 텍스트를 수신합니다.1565Agent SDK 쿼리와 `claude -p`를 포함한 비대화형 실행에서 MessageDisplay는 줄 배치마다가 아니라 어시스턴트 메시지마다 한 번 실행됩니다. 이 단일 호출은 메시지가 완료된 후 도착하며 전체 메시지 텍스트를 담습니다. `index`는 `0`, `final`은 `true`이고 `delta`에는 전체 메시지가 들어 있습니다. 각 메시지의 `delta` 텍스트를 수집하는 훅은 두 모드에서 동일한 전체 텍스트를 받습니다.
1567 1566
1568<h4 id="messagedisplay-input">1567<h4 id="messagedisplay-input">
1569 MessageDisplay 입력1568 MessageDisplay 입력
1570</h4>1569</h4>
1571 1570
1572[공통 입력 필드](#common-input-fields) 외에도 MessageDisplay 훅은 턴과 메시지의 식별자, 메시지 내에서 이 호출의 위치, 그리고 `delta`의 새 텍스트를 수신합니다. 묶음 경계는 텍스트가 스트리밍되는 방식에 따라 달라지므로, 줄이 특정 방식으로 묶일 것이라고 기대하기보다 `index`와 `final`을 사용하여 메시지의 진행 상황을 추적합니다.1571[공통 입력 필드](#common-input-fields) 외에도 MessageDisplay 훅은 턴과 메시지의 식별자, 메시지 내 이 호출의 위치, `delta`에 담긴 새 텍스트를 받습니다. 배치 경계는 텍스트가 스트리밍되는 방식에 따라 달라지므로, 줄이 특정 방식으로 그룹화될 것으로 기대하지 말고 `index`와 `final`을 사용해 메시지 진행 상황을 추적하세요.
1573 1572
1574| 필드 | 설명 |1573| 필드 | 설명 |
1575| :- | :- |1574| :- | :- |
1576| `turn_id` | 현재 턴의 UUID |1575| `turn_id` | 현재 턴의 UUID |
1577| `message_id` | 표시 중인 어시스턴트 메시지의 UUID. 같은 메시지의 모든 묶음에서 동일하게 유지됩니다. API의 `msg_…` id가 아니므로 트랜스크립트 메시지 id와 연관시킬 수 없습니다 |1576| `message_id` | 표시 중인 어시스턴트 메시지의 UUID. 같은 메시지의 모든 배치에서 동일합니다. API `msg_…` id가 아니므로 트랜스크립트 메시지 id와 연관시킬 수 없습니다 |
1578| `index` | 메시지 내에서 이 묶음의 0부터 시작하는 인덱스 |1577| `index` | 메시지 내 이 배치의 0부터 시작하는 인덱스 |
1579| `final` | 메시지의 마지막 묶음에서 `true`. 각 메시지에는 정확히 하나의 마지막 묶음이 있습니다 |1578| `final` | 메시지의 마지막 배치에서 `true`. 각 메시지에는 정확히 하나의 마지막 배치가 있습니다 |
1580| `delta` | 이전 묶음 이후 새로 완성된 줄(끝의 줄바꿈 포함). 줄 중간에서 끝날 수 있는 마지막 묶음을 제외하면 항상 완전한 줄입니다. 대화형 실행에서는 메시지가 줄바꿈으로 끝나면 마지막 묶음의 delta가 비어 있으므로, 비어 있지 않은 delta가 아니라 `final`을 메시지 끝 신호로 취급해야 합니다. Agent SDK 및 `claude -p` 실행에서는 단일 호출이 전체 메시지를 담습니다 |1579| `delta` | 이전 배치 이후 새로 완성된 줄(끝의 줄바꿈 포함). 줄 중간에서 끝날 수 있는 마지막 배치를 제외하고 항상 완전한 줄입니다. 대화형 실행에서 메시지가 줄바꿈으로 끝나면 마지막 배치의 delta는 비어 있으므로, 비어 있지 않은 delta가 아니라 `final`을 메시지 종료 신호로 취급하세요. Agent SDK 및 `claude -p` 실행에서는 단일 호출에 전체 메시지가 담깁니다 |
1581 1580
1582```json theme={null}1581```json theme={null}
1583{1582{
1597 MessageDisplay 출력1596 MessageDisplay 출력
1598</h4>1597</h4>
1599 1598
1600모든 훅에서 사용할 수 있는 [JSON 출력 필드](#json-output) 외에도 MessageDisplay 훅은 화면에서 delta를 대체하는 `displayContent`를 반환할 수 있습니다.1599모든 훅에서 사용할 수 있는 [JSON 출력 필드](#json-output) 외에도 MessageDisplay 훅은 화면의 delta를 대체하는 `displayContent`를 반환할 수 있습니다:
1601 1600
1602| 필드 | 설명 |1601| 필드 | 설명 |
1603| :- | :- |1602| :- | :- |
1604| `displayContent` | delta 대신 표시되는 텍스트. 원래 텍스트를 표시하려면 생략합니다 |1603| `displayContent` | delta 대신 표시되는 텍스트. 원래 텍스트를 표시하려면 생략하세요 |
1605 1604
1606MessageDisplay 훅에는 결정 제어가 없습니다. 메시지를 차단하거나 트랜스크립트에 저장되는 내용 또는 Claude에 전송되는 내용을 변경할 수 없습니다. Claude Code는 JSON 출력의 `displayContent`에 따라 동작하며 `systemMessage`와 `continue`는 버립니다.1605MessageDisplay 훅에는 결정 제어가 없습니다. 메시지를 차단하거나, 트랜스크립트에 저장되거나 Claude에 전송되는 내용을 변경할 수 없습니다. Claude Code는 JSON 출력의 `displayContent`에 따라 동작하고 `systemMessage`와 `continue`는 버립니다.
1607 1606
1608다음 예시는 일반 텍스트 표시를 위해 Claude의 응답에서 markdown 서식을 제거합니다. 스크립트는 stdin에서 각 묶음을 읽고, `delta`에서 굵게 표시 기호와 인라인 코드 백틱을 제거한 다음, 결과를 `displayContent`로 반환합니다.1607이 예시는 일반 텍스트 표시를 위해 Claude의 응답에서 markdown 서식을 제거합니다. 스크립트는 stdin에서 각 배치를 읽고, `delta`에서 굵게 표시 기호와 인라인 코드 백틱을 제거한 다음, 결과를 `displayContent`로 반환합니다.
1609 1608
1610<Tabs>1609<Tabs>
1611 <Tab title="macOS/Linux">1610 <Tab title="macOS/Linux">
1612 설정 파일에서 이벤트에 대한 command 훅을 등록합니다.1611 설정 파일에 이 이벤트에 대한 command 훅을 등록하세요:
1613 1612
1614 ```json theme={null}1613 ```json theme={null}
1615 {1614 {
1629 }1628 }
1630 ```1629 ```
1631 1630
1632 이 스크립트를 프로젝트의 `.claude/hooks/plain-display.sh`에 저장하고 `chmod +x`로 실행 가능하게 만듭니다.1631 이 스크립트를 프로젝트의 `.claude/hooks/plain-display.sh`에 저장하고 `chmod +x`로 실행 가능하게 만드세요:
1633 1632
1634 ```bash theme={null}1633 ```bash theme={null}
1635 #!/bin/bash1634 #!/bin/bash
1638 </Tab>1637 </Tab>
1639 1638
1640 <Tab title="Windows (PowerShell)">1639 <Tab title="Windows (PowerShell)">
1641 PowerShell을 통해 스크립트를 실행하는 command 훅을 등록합니다.1640 PowerShell을 통해 스크립트를 실행하는 command 훅을 등록하세요:
1642 1641
1643 ```json theme={null}1642 ```json theme={null}
1644 {1643 {
1664 }1663 }
1665 ```1664 ```
1666 1665
1667 `-NoProfile` 플래그는 PowerShell 프로필 로드를 건너뛰어 훅이 빠르게 시작되도록 하며, `-ExecutionPolicy Bypass`는 PowerShell이 로컬 스크립트 파일을 실행할 수 있도록 합니다.1666 `-NoProfile` 플래그는 PowerShell 프로필 로드를 건너뛰어 훅이 빠르게 시작되도록 하고, `-ExecutionPolicy Bypass`는 PowerShell이 로컬 스크립트 파일을 실행할 수 있게 합니다.
1668 1667
1669 이 스크립트를 프로젝트의 `.claude/hooks/plain-display.ps1`에 저장합니다.1668 이 스크립트를 프로젝트의 `.claude/hooks/plain-display.ps1`에 저장하세요:
1670 1669
1671 ```powershell theme={null}1670 ```powershell theme={null}
1672 $batch = [Console]::In.ReadToEnd() | ConvertFrom-Json1671 $batch = [Console]::In.ReadToEnd() | ConvertFrom-Json
1681 </Tab>1680 </Tab>
1682</Tabs>1681</Tabs>
1683 1682
1684markdown이 없는 묶음은 변경 없이 통과합니다. 예를 들어 `jq`가 없어서 스크립트가 실패하면 Claude Code는 원래 텍스트를 표시하며, 실패는 세션이 아닌 [디버그 출력](#debug-hooks)에만 기록됩니다.1683markdown이 없는 배치는 변경 없이 통과합니다. 예를 들어 `jq`가 없어 스크립트가 실패하면 Claude Code는 원래 텍스트를 표시하고, 실패는 세션이 아닌 [디버그 출력](#debug-hooks)에만 기록합니다.
1685 1684
1686<h3 id="pretooluse">1685<h3 id="pretooluse">
1687 PreToolUse1686 PreToolUse
1688</h3>1687</h3>
1689 1688
1690Claude가 도구 매개변수를 생성한 후, 도구 호출을 처리하기 전에 실행됩니다. `EndConversation`을 제외한 모든 도구 이름에 대해 일치시킵니다. 여기에는 `Bash`, `PowerShell`, `Edit`, `Write`, `Read`, `Glob`, `Grep`, `Agent`, `Workflow`, `WebFetch`, `WebSearch`, `AskUserQuestion`, `ExitPlanMode` 같은 기본 제공 도구와 모든 [MCP 도구 이름](#match-mcp-tools)이 포함됩니다.1689Claude가 도구 매개변수를 생성한 후, 도구 호출을 처리하기 전에 실행됩니다. `EndConversation`을 제외한 모든 도구 이름에 대해 매칭합니다. 여기에는 `Bash`, `PowerShell`, `Edit`, `Write`, `Read`, `Glob`, `Grep`, `Agent`, `Workflow`, `WebFetch`, `WebSearch`, `AskUserQuestion`, `ExitPlanMode` 같은 기본 제공 도구와 모든 [MCP 도구 이름](#match-mcp-tools)이 포함됩니다.
1691 1690
1692무엇이 작성했든 특정 파일이 디스크에서 변경될 때 훅을 실행하려면, 파일 편집 도구를 이름으로 일치시키는 대신 [FileChanged](#filechanged)를 사용합니다. PreToolUse와 달리 Claude Code는 변경 후에 FileChanged 훅을 실행하며, 이 훅에는 결정 제어가 없으므로 쓰기를 차단할 수 없습니다.1691무엇이 파일을 썼는지와 관계없이 특정 파일이 디스크에서 변경될 때 훅을 실행하려면, 파일 편집 도구를 이름으로 매칭하는 대신 [FileChanged](#filechanged)를 사용하세요. PreToolUse와 달리 Claude Code는 변경 후에 FileChanged 훅을 실행하며, 이 훅에는 결정 제어가 없으므로 쓰기를 차단할 수 없습니다.
1693 1692
1694<Warning>1693<Warning>
1695 PreToolUse는 Claude가 도구를 호출할 때만 실행됩니다. [프롬프트에서 `@`로 참조하는](/docs/ko/common-workflows#reference-files-and-directories) 파일은 도구 호출 없이 추가됩니다. Claude Code는 프롬프트를 구성하면서 파일 내용을 삽입하므로, `Read`와 일치하는 훅을 포함하여 어떤 PreToolUse 훅도 이 파일에 대해 발생하지 않습니다. `@` 참조에서 특정 경로를 차단하려면 대신 [`Read` 거부 규칙](/docs/ko/permissions#read-and-edit)을 사용합니다.1694 PreToolUse는 Claude가 도구를 호출할 때만 실행됩니다. [프롬프트에서 `@`로 참조하는](/docs/ko/common-workflows#reference-files-and-directories) 파일은 도구 호출 없이 추가됩니다. Claude Code는 프롬프트를 구성하는 동안 해당 파일의 내용을 삽입하므로, `Read`와 일치하는 훅을 포함해 어떤 PreToolUse 훅도 이 파일에 대해 발생하지 않습니다. `@` 참조에서 특정 경로를 차단하려면 대신 [`Read` 거부 규칙](/docs/ko/permissions#read-and-edit)을 사용하세요.
1696 1695
1697 PreToolUse는 [`EndConversation`](/docs/ko/tools-reference#endconversation-tool-behavior)에서도 발생하지 않습니다.1696 PreToolUse는 [`EndConversation`](/docs/ko/tools-reference#endconversation-tool-behavior)에 대해서도 발생하지 않습니다.
1698</Warning>1697</Warning>
1699 1698
1700도구 호출을 허용, 거부, 확인 요청 또는 지연하려면 [PreToolUse 결정 제어](#pretooluse-decision-control)를 사용합니다.1699[PreToolUse 결정 제어](#pretooluse-decision-control)를 사용해 도구 호출을 허용, 거부, 확인 요청 또는 지연하세요.
1701 1700
1702타임아웃을 초과한 `PreToolUse`의 [Agent SDK 콜백 훅](/docs/ko/agent-sdk/hooks)은 도구 호출을 차단하며, Claude는 타임아웃을 명시한 오류 결과를 수신합니다. 다른 훅이 반환한 명시적 거부는 여전히 우선합니다.1701`PreToolUse`의 [Agent SDK 콜백 훅](/docs/ko/agent-sdk/hooks)이 타임아웃을 초과하면 도구 호출이 차단되고, Claude는 타임아웃을 명시하는 오류 결과를 받습니다. 다른 훅이 반환한 명시적 거부는 여전히 우선합니다.
1703 1702
1704<h4 id="pretooluse-input">1703<h4 id="pretooluse-input">
1705 PreToolUse 입력1704 PreToolUse 입력
1706</h4>1705</h4>
1707 1706
1708[공통 입력 필드](#common-input-fields) 외에도 PreToolUse 훅은 `tool_name`, `tool_input`, `tool_use_id`를 수신합니다.1707[공통 입력 필드](#common-input-fields) 외에도 PreToolUse 훅은 `tool_name`, `tool_input`, `tool_use_id`를 받습니다.
1709 1708
1710[MCP 도구](#match-mcp-tools)의 경우 입력에는 `mcp_server`도 포함됩니다. 이는 서버의 `name`과 서버 정의의 출처를 나타내는 `source`가 담긴 객체입니다. `source` 값에는 `plugin`, `sdk`, 그리고 `user`, `project` 같은 구성 범위가 포함됩니다. Agent SDK 레퍼런스의 [`McpServerProvenance`](/docs/ko/agent-sdk/typescript#mcpserverprovenance)에서 전체 값 목록과 인식하지 못하는 값을 처리하는 방법을 확인할 수 있습니다. 신뢰 결정은 `name`이나 `mcp__<server>__` 도구 이름 접두사가 아닌 `source`를 기준으로 내려야 합니다. `mcp_server` 필드에는 Claude Code v2.1.274 이상이 필요합니다.1709[MCP 도구](#match-mcp-tools)의 경우 입력에 `mcp_server`도 포함됩니다. 이는 서버의 `name`과 서버 정의의 출처를 나타내는 `source`가 있는 객체입니다. `source` 값에는 `plugin`, `sdk`, 그리고 `user`, `project` 같은 구성 범위가 포함됩니다. Agent SDK 참조의 [`McpServerProvenance`](/docs/ko/agent-sdk/typescript#mcpserverprovenance)에 전체 목록과 인식할 수 없는 값을 처리하는 방법이 나와 있습니다. 신뢰 결정은 `name`이나 `mcp__<server>__` 도구 이름 접두사가 아니라 `source`를 기준으로 하세요. `mcp_server` 필드에는 Claude Code v2.1.274 이상이 필요합니다.
1711 1710
1712파일 도구 `Write`, `Edit`, `Read`의 경우 `tool_input.file_path`는 항상 절대 경로입니다.1711파일 도구 `Write`, `Edit`, `Read`의 경우 `tool_input.file_path`는 항상 절대 경로입니다:
1713 1712
1714* Claude Code는 훅이 실행되기 전에 `~`와 상대 경로를 확장하므로, 경로를 일치시키는 훅은 `~`나 같은 경로의 상대 표기를 통해 우회될 수 없습니다1713* Claude Code는 훅이 실행되기 전에 `~`와 상대 경로를 확장하므로, 경로를 매칭하는 훅을 `~`나 같은 경로의 상대 표기로 우회할 수 없습니다
1715* Windows에서는 훅이 `$PWD`가 `/c/project`처럼 보이는 Git Bash에서 실행되더라도 경로가 백슬래시 구분 기호와 함께 전달됩니다1714* Windows에서는 `$PWD`가 `/c/project`처럼 보이는 Git Bash에서 훅이 실행되더라도 경로가 백슬래시 구분자로 전달됩니다
1716* `/src/` 검사처럼 슬래시로 작성된 비교는 백슬래시 경로와 절대 일치하지 않으며, 도구 호출은 훅이 차단할 것이 없는 것처럼 진행됩니다1715* `/src/` 검사처럼 슬래시로 작성된 비교는 백슬래시 경로와 절대 일치하지 않으며, 도구 호출은 훅이 차단할 것이 없었던 것처럼 진행됩니다
1717* 비교하기 전에 구분 기호를 정규화합니다. Bash에서는 `FILE_PATH="${FILE_PATH//\\//}"`, Python에서는 `file_path.replace("\\", "/")`를 사용한 다음, 경로가 절대 경로이므로 `^`로 고정하지 말고 `/src/` 같은 경로 세그먼트를 일치시킵니다1716* 비교하기 전에 구분자를 정규화하세요. Bash에서는 `FILE_PATH="${FILE_PATH//\\//}"`, Python에서는 `file_path.replace("\\", "/")`를 사용한 다음, 경로가 절대 경로이므로 `^`로 고정하지 말고 `/src/` 같은 경로 세그먼트를 매칭하세요
1718 1717
1719Windows에서 `Write` 호출은 다음을 전달합니다.1718Windows에서 `Write` 호출은 다음을 전달합니다:
1720 1719
1721```json theme={null}1720```json theme={null}
1722{1721{
1730}1729}
1731```1730```
1732 1731
1733`tool_input` 필드는 도구에 따라 다릅니다.1732`tool_input` 필드는 도구에 따라 다릅니다:
1734 1733
1735<a id="bash" />1734<a id="bash" />
1736 1735
1740 1739
1741셸 명령을 실행합니다.1740셸 명령을 실행합니다.
1742 1741
1743| 필드 | 타입 | 예시 | 설명 |1742| 필드 | 유형 | 예시 | 설명 |
1744| :- | :- | :- | :- |1743| :- | :- | :- | :- |
1745| `command` | string | `"npm test"` | 실행할 셸 명령 |1744| `command` | string | `"npm test"` | 실행할 셸 명령 |
1746| `description` | string | `"Run test suite"` | 명령이 수행하는 작업에 대한 선택적 설명 |1745| `description` | string | `"Run test suite"` | 명령이 수행하는 작업에 대한 선택적 설명 |
1747| `timeout` | number | `120000` | 선택적 타임아웃(밀리초). [최대값](/docs/ko/tools-reference#bash-tool-behavior)을 초과하는 값은 거부되지 않고 최대값으로 줄어듭니다 |1746| `timeout` | number | `120000` | 밀리초 단위의 선택적 타임아웃. [최대값](/docs/ko/tools-reference#bash-tool-behavior)을 초과하는 값은 거부되지 않고 최대값으로 줄어듭니다 |
1748| `run_in_background` | boolean | `false` | 명령을 백그라운드에서 실행할지 여부 |1747| `run_in_background` | boolean | `false` | 명령을 백그라운드에서 실행할지 여부 |
1749 1748
1750Bash 명령이 Git 저장소의 파일을 변경하면 Claude Code는 변경된 내용을 기록할 수 있습니다. [`bashEditDiffEnabled`](/docs/ko/settings-reference#basheditdiffenabled) 설정이 기록을 켜면 모든 권한 모드에서 변경 사항을 기록하며, 어떤 파일에서 이 설정을 지정할 수 있는지는 해당 설정 항목에 나와 있습니다. 그렇지 않으면 자동 모드와 `bypassPermissions` 모드에서만, 그리고 Claude Code가 Claude에게 Bash를 통해 파일을 편집하도록 지시한 경우에만 기록합니다. 기록을 끄려면 `bashEditDiffEnabled`를 `false`로 설정합니다. 백그라운드 명령과 읽기 전용 명령에는 diff가 포함되지 않습니다.1749Bash 명령이 Git 저장소의 파일을 변경하면 Claude Code는 변경 내용을 기록할 수 있습니다. [`bashEditDiffEnabled`](/docs/ko/settings-reference#basheditdiffenabled) 설정이 기록을 켜면 모든 권한 모드에서 변경 내용을 기록하며, 어떤 파일에서 이 설정을 지정할 수 있는지는 해당 설정 항목에 나와 있습니다. 그렇지 않으면 자동 모드와 `bypassPermissions` 모드에서만, 그리고 Claude Code가 Claude에게 Bash를 통해 파일을 편집하도록 지시할 때만 기록합니다. 기록을 끄려면 `bashEditDiffEnabled`를 `false`로 설정하세요. 백그라운드 명령과 읽기 전용 명령에는 diff가 포함되지 않습니다.
1751 1750
1752그러면 [PostToolUse 훅](#posttooluse)이 `tool_response.bashEditDiff`에서 변경된 파일을 수신합니다. 이 목록은 명령이 실행되는 동안 저장소 아래에서 변경된 내용을 다룹니다. Git이 무시하는 파일과 서브모듈의 파일은 목록에 포함되지 않습니다. Claude Code v2.1.269 이상이 필요합니다.1751그러면 [PostToolUse 훅](#posttooluse)이 `tool_response.bashEditDiff`에서 변경된 파일을 받습니다. 이 목록은 명령이 실행되는 동안 저장소에서 변경된 내용을 다룹니다. Git이 무시하는 파일과 서브모듈의 파일은 나열되지 않습니다. Claude Code v2.1.269 이상이 필요합니다.
1753 1752
1754<Note>1753<Note>
1755 이 목록은 최선의 노력(best effort)으로 제공되며 공개 베타 상태입니다. Claude Code는 변경 사항을 놓치거나, 동시에 다른 프로세스가 변경한 파일을 포함하거나, 크기 제한에서 중단될 수 있습니다. 필드 형태는 변경될 수 있습니다. 이 목록은 정책을 강제하는 용도가 아니라 검토할 대상을 찾는 용도로 사용합니다.1754 이 목록은 최선의 노력(best effort) 방식으로 제공되며 공개 베타 상태입니다. Claude Code가 변경 사항을 놓치거나, 다른 프로세스가 동시에 변경한 파일을 포함하거나, 크기 제한에서 중단될 수 있습니다. 필드 형식은 변경될 수 있습니다. 이 목록은 정책을 강제하는 용도가 아니라 검토할 항목을 찾는 용도로 사용하세요.
1756</Note>1755</Note>
1757 1756
1758`changedFiles`와 `files`는 명령이 변경한 내용을 나열하며, 나머지 필드는 해당 목록이 얼마나 완전하고 신뢰할 수 있는지를 나타냅니다.1757`changedFiles`와 `files`는 명령이 변경한 내용을 나열하고, 나머지 필드는 그 목록이 얼마나 완전하고 신뢰할 수 있는지 알려 줍니다.
1759 1758
1760| 필드 | 타입 | 예시 | 설명 |1759| 필드 | 유형 | 예시 | 설명 |
1761| :- | :- | :- | :- |1760| :- | :- | :- | :- |
1762| `changedFiles` | array | `["/path/to/src/app.ts"]` | 명령이 변경한 파일의 절대 경로(최대 200개). `files`에 diff가 있거나 `moreFiles`가 0보다 클 때마다 포함됩니다 |1761| `changedFiles` | array | `["/path/to/src/app.ts"]` | 명령이 변경한 파일의 절대 경로(최대 200개). `files`에 diff가 있거나 `moreFiles`가 0보다 클 때 항상 존재합니다 |
1763| `files` | array | `[{"filePath": "/path/to/src/app.ts", "hunks": [...]}]` | 표시용으로 최대 5개의 변경된 파일에 대한 diff. 명령이 추가하거나 제거한 파일의 경우 `created` 또는 `deleted`가 `true`입니다 |1762| `files` | array | `[{"filePath": "/path/to/src/app.ts", "hunks": [...]}]` | 표시용으로 제공되는 최대 5개 변경 파일의 diff. 명령이 추가하거나 제거한 파일은 `created` 또는 `deleted`가 `true`입니다 |
1764| `moreFiles` | number | `2` | `files`에 diff가 없는 변경된 파일 수 |1763| `moreFiles` | number | `2` | `files`에 diff가 없는 변경된 파일 수 |
1765| `unavailable` | boolean | `true` | diff가 불완전하거나 가져올 수 없을 때 설정됩니다 |1764| `unavailable` | boolean | `true` | diff가 불완전하거나 가져올 수 없을 때 설정됩니다 |
1766| `skipped` | boolean | `true` | `git checkout`이나 `git stash`처럼 작업 트리를 이동하는 Git 명령에 대해 설정되며, 이 경우 Claude Code는 diff를 가져오지 않습니다 |1765| `skipped` | boolean | `true` | `git checkout`이나 `git stash`처럼 워킹 트리를 이동하는 Git 명령에 설정되며, 이 경우 Claude Code는 diff를 가져오지 않습니다 |
1767| `shared` | boolean | `true` | 서브에이전트의 호출 같은 다른 Bash 도구 호출이 같은 시간에 같은 저장소에서 실행되어, 나열된 일부 변경 사항이 해당 명령의 것일 수 있을 때 설정됩니다 |1766| `shared` | boolean | `true` | 서브에이전트의 호출 같은 다른 Bash 도구 호출이 같은 저장소에서 동시에 실행되었을 때 설정되며, 이 경우 나열된 일부 변경 사항은 해당 명령에 의한 것일 수 있습니다 |
1768 1767
1769<a id="powershell" />1768<a id="powershell" />
1770 1769
1774 1773
1775PowerShell 명령을 실행합니다. 플랫폼별 사용 가능 여부는 [PowerShell 도구](/docs/ko/tools-reference#powershell-tool)를 참조하세요.1774PowerShell 명령을 실행합니다. 플랫폼별 사용 가능 여부는 [PowerShell 도구](/docs/ko/tools-reference#powershell-tool)를 참조하세요.
1776 1775
1777필드는 Bash 도구와 같으며, 명령 문자열은 `command`에 들어갑니다.1776필드는 Bash 도구와 같으며, 명령 문자열은 `command`에 있습니다:
1778 1777
1779| 필드 | 타입 | 예시 | 설명 |1778| 필드 | 유형 | 예시 | 설명 |
1780| :- | :- | :- | :- |1779| :- | :- | :- | :- |
1781| `command` | string | `"Get-ChildItem -Recurse"` | 실행할 PowerShell 명령 |1780| `command` | string | `"Get-ChildItem -Recurse"` | 실행할 PowerShell 명령 |
1782| `description` | string | `"List files recursively"` | 명령이 수행하는 작업에 대한 선택적 설명 |1781| `description` | string | `"List files recursively"` | 명령이 수행하는 작업에 대한 선택적 설명 |
1783| `timeout` | number | `120000` | 선택적 타임아웃(밀리초) |1782| `timeout` | number | `120000` | 밀리초 단위의 선택적 타임아웃 |
1784| `run_in_background` | boolean | `false` | 명령을 백그라운드에서 실행할지 여부 |1783| `run_in_background` | boolean | `false` | 명령을 백그라운드에서 실행할지 여부 |
1785 1784
1786셸 명령을 검사하는 훅에서는 두 도구를 모두 다루도록 `Bash|PowerShell`을 일치시킵니다.1785셸 명령을 검사하는 훅에서는 두 도구를 모두 다루도록 `Bash|PowerShell`을 매칭하세요:
1787 1786
1788* Windows에서 PowerShell 도구가 활성화된 곳이라면 어디서든 Claude는 PowerShell을 기본 셸로 취급하고 셸 명령을 PowerShell을 통해 라우팅합니다.1787* Windows에서 PowerShell 도구가 활성화된 경우 Claude는 PowerShell을 기본 셸로 취급하고 셸 명령을 PowerShell로 라우팅합니다.
1789* Git Bash가 없는 Windows에서는 이 도구가 자동으로 활성화되며 Claude Code는 Bash 도구를 전혀 등록하지 않습니다.1788* Git Bash가 없는 Windows에서는 이 도구가 자동으로 활성화되며 Claude Code는 Bash 도구를 전혀 등록하지 않습니다.
1790* `Bash`만 일치시키는 훅은 그곳에서 절대 발생하지 않습니다.1789* `Bash`만 매칭하는 훅은 그러한 환경에서 절대 발생하지 않습니다.
1791 1790
1792<h5 id="write">1791<h5 id="write">
1793 Write1792 Write
1795 1794
1796파일을 생성하거나 덮어씁니다.1795파일을 생성하거나 덮어씁니다.
1797 1796
1798| 필드 | 타입 | 예시 | 설명 |1797| 필드 | 유형 | 예시 | 설명 |
1799| :- | :- | :- | :- |1798| :- | :- | :- | :- |
1800| `file_path` | string | `"/path/to/file.txt"` | 쓸 파일의 절대 경로 |1799| `file_path` | string | `"/path/to/file.txt"` | 쓸 파일의 절대 경로 |
1801| `content` | string | `"file content"` | 파일에 쓸 내용 |1800| `content` | string | `"file content"` | 파일에 쓸 내용 |
1804 Edit1803 Edit
1805</h5>1804</h5>
1806 1805
1807기존 파일의 문자열을 대체합니다.1806기존 파일의 문자열을 바꿉니다.
1808 1807
1809| 필드 | 타입 | 예시 | 설명 |1808| 필드 | 유형 | 예시 | 설명 |
1810| :- | :- | :- | :- |1809| :- | :- | :- | :- |
1811| `file_path` | string | `"/path/to/file.txt"` | 편집할 파일의 절대 경로 |1810| `file_path` | string | `"/path/to/file.txt"` | 편집할 파일의 절대 경로 |
1812| `old_string` | string | `"original text"` | 찾아서 대체할 텍스트 |1811| `old_string` | string | `"original text"` | 찾아서 바꿀 텍스트 |
1813| `new_string` | string | `"replacement text"` | 대체 텍스트 |1812| `new_string` | string | `"replacement text"` | 대체 텍스트 |
1814| `replace_all` | boolean | `false` | 모든 항목을 대체할지 여부 |1813| `replace_all` | boolean | `false` | 모든 항목을 바꿀지 여부 |
1815 1814
1816<h5 id="read">1815<h5 id="read">
1817 Read1816 Read
1819 1818
1820파일 내용을 읽습니다.1819파일 내용을 읽습니다.
1821 1820
1822| 필드 | 타입 | 예시 | 설명 |1821| 필드 | 유형 | 예시 | 설명 |
1823| :- | :- | :- | :- |1822| :- | :- | :- | :- |
1824| `file_path` | string | `"/path/to/file.txt"` | 읽을 파일의 절대 경로 |1823| `file_path` | string | `"/path/to/file.txt"` | 읽을 파일의 절대 경로 |
1825| `offset` | number | `10` | 읽기를 시작할 선택적 줄 번호 |1824| `offset` | number | `10` | 읽기를 시작할 선택적 줄 번호 |
1826| `limit` | number | `50` | 읽을 선택적 줄 수 |1825| `limit` | number | `50` | 읽을 줄 수(선택 사항) |
1827 1826
1828<h5 id="glob">1827<h5 id="glob">
1829 Glob1828 Glob
1831 1830
1832glob 패턴과 일치하는 파일을 찾습니다.1831glob 패턴과 일치하는 파일을 찾습니다.
1833 1832
1834| 필드 | 타입 | 예시 | 설명 |1833| 필드 | 유형 | 예시 | 설명 |
1835| :- | :- | :- | :- |1834| :- | :- | :- | :- |
1836| `pattern` | string | `"**/*.ts"` | 파일을 일치시킬 glob 패턴 |1835| `pattern` | string | `"**/*.ts"` | 파일과 매칭할 glob 패턴 |
1837| `path` | string | `"/path/to/dir"` | 검색할 선택적 디렉터리. 기본값은 현재 작업 디렉터리입니다 |1836| `path` | string | `"/path/to/dir"` | 검색할 선택적 디렉터리. 기본값은 현재 작업 디렉터리입니다 |
1838 1837
1839<h5 id="grep">1838<h5 id="grep">
1842 1841
1843정규식으로 파일 내용을 검색합니다.1842정규식으로 파일 내용을 검색합니다.
1844 1843
1845| 필드 | 타입 | 예시 | 설명 |1844| 필드 | 유형 | 예시 | 설명 |
1846| :- | :- | :- | :- |1845| :- | :- | :- | :- |
1847| `pattern` | string | `"TODO.*fix"` | 검색할 정규식 패턴 |1846| `pattern` | string | `"TODO.*fix"` | 검색할 정규식 패턴 |
1848| `path` | string | `"/path/to/dir"` | 검색할 선택적 파일 또는 디렉터리 |1847| `path` | string | `"/path/to/dir"` | 검색할 선택적 파일 또는 디렉터리 |
1849| `glob` | string | `"*.ts"` | 파일을 필터링할 선택적 glob 패턴 |1848| `glob` | string | `"*.ts"` | 파일을 필터링할 선택적 glob 패턴 |
1850| `output_mode` | string | `"content"` | `"content"`, `"files_with_matches"` 또는 `"count"`. 기본값은 `"files_with_matches"`입니다 |1849| `output_mode` | string | `"content"` | `"content"`, `"files_with_matches"` 또는 `"count"`. 기본값은 `"files_with_matches"`입니다 |
1851| `-i` | boolean | `true` | 대소문자 구분 없는 검색 |1850| `-i` | boolean | `true` | 대소문자를 구분하지 않는 검색 |
1852| `multiline` | boolean | `false` | 여러 줄 일치 활성화 |1851| `multiline` | boolean | `false` | 여러 줄 매칭 활성화 |
1853 1852
1854<h5 id="webfetch">1853<h5 id="webfetch">
1855 WebFetch1854 WebFetch
1857 1856
1858웹 콘텐츠를 가져와 처리합니다.1857웹 콘텐츠를 가져와 처리합니다.
1859 1858
1860| 필드 | 타입 | 예시 | 설명 |1859| 필드 | 유형 | 예시 | 설명 |
1861| :- | :- | :- | :- |1860| :- | :- | :- | :- |
1862| `url` | string | `"https://example.com/api"` | 콘텐츠를 가져올 URL |1861| `url` | string | `"https://example.com/api"` | 콘텐츠를 가져올 URL |
1863| `prompt` | string | `"Extract the API endpoints"` | 가져온 콘텐츠에 대해 실행할 프롬프트 |1862| `prompt` | string | `"Extract the API endpoints"` | 가져온 콘텐츠에 대해 실행할 프롬프트 |
1868 1867
1869웹을 검색합니다.1868웹을 검색합니다.
1870 1869
1871| 필드 | 타입 | 예시 | 설명 |1870| 필드 | 유형 | 예시 | 설명 |
1872| :- | :- | :- | :- |1871| :- | :- | :- | :- |
1873| `query` | string | `"react hooks best practices"` | 검색 쿼리 |1872| `query` | string | `"react hooks best practices"` | 검색 쿼리 |
1874| `allowed_domains` | array | `["docs.example.com"]` | 선택 사항: 이 도메인의 결과만 포함 |1873| `allowed_domains` | array | `["docs.example.com"]` | 선택 사항: 이 도메인의 결과만 포함 |
1880 1879
1881[서브에이전트](/docs/ko/sub-agents)를 생성합니다.1880[서브에이전트](/docs/ko/sub-agents)를 생성합니다.
1882 1881
1883| 필드 | 타입 | 예시 | 설명 |1882| 필드 | 유형 | 예시 | 설명 |
1884| :- | :- | :- | :- |1883| :- | :- | :- | :- |
1885| `prompt` | string | `"Find all API endpoints"` | 에이전트가 수행할 작업 |1884| `prompt` | string | `"Find all API endpoints"` | 에이전트가 수행할 작업 |
1886| `description` | string | `"Find API endpoints"` | 작업에 대한 짧은 설명 |1885| `description` | string | `"Find API endpoints"` | 작업에 대한 짧은 설명 |
1887| `subagent_type` | string | `"Explore"` | 사용할 특화 에이전트 유형 |1886| `subagent_type` | string | `"Explore"` | 사용할 전문 에이전트 유형 |
1888| `model` | string | `"sonnet"` | 기본값을 재정의할 선택적 모델 별칭 |1887| `model` | string | `"sonnet"` | 기본값을 재정의할 선택적 모델 별칭 |
1889 1888
1890포그라운드 Agent 호출이 완료되면 [PostToolUse 훅](#posttooluse)은 `tool_response`에서 서브에이전트의 결과와 실행 텔레메트리를 수신합니다. 실행을 검사하려면 이 필드를 읽습니다. 서브에이전트 전체의 토큰 및 비용 집계에는 `query_source` `"subagent"`로 필터링한 [토큰 및 비용 카운터](/docs/ko/monitoring-usage#token-counter)를 사용합니다. `totalTokens`와 `usage`는 마지막 요청만 다루기 때문입니다.1889포그라운드 Agent 호출이 완료되면 [PostToolUse 훅](#posttooluse)은 `tool_response`에서 서브에이전트의 결과와 실행 텔레메트리를 받습니다. 실행을 검사하려면 이 필드를 읽으세요. `totalTokens`와 `usage`는 최종 요청만 다루므로, 서브에이전트 전체의 토큰 및 비용 집계에는 `query_source` `"subagent"`로 필터링한 [토큰 및 비용 카운터](/docs/ko/monitoring-usage#token-counter)를 사용하세요:
1891 1890
1892| 필드 | 타입 | 예시 | 설명 |1891| 필드 | 유형 | 예시 | 설명 |
1893| :- | :- | :- | :- |1892| :- | :- | :- | :- |
1894| `status` | string | `"completed"` | 포그라운드 서브에이전트는 `"completed"`, 백그라운드 서브에이전트는 `"async_launched"`. 서브에이전트는 기본적으로 백그라운드에서 실행되므로 `run_in_background`를 생략한 Agent 호출도 `"async_launched"`를 생성합니다 |1893| `status` | string | `"completed"` | 포그라운드 서브에이전트는 `"completed"`, 백그라운드 서브에이전트는 `"async_launched"`. 서브에이전트는 기본적으로 백그라운드에서 실행되므로 `run_in_background`를 생략한 Agent 호출도 `"async_launched"`를 생성합니다 |
1895| `agentId` | string | `"a4d2c8f1e0b3a297"` | 서브에이전트 실행의 식별자 |1894| `agentId` | string | `"a4d2c8f1e0b3a297"` | 서브에이전트 실행의 식별자 |
1896| `content` | array | `[{"type": "text", "text": "Found 12 endpoints..."}]` | 서브에이전트의 최종 텍스트 블록. 보고서가 `SubagentHandback`을 통해 전달되는 서브에이전트의 경우 그 대신 해당 인계에 대한 짧은 메모 |1895| `content` | array | `[{"type": "text", "text": "Found 12 endpoints..."}]` | 서브에이전트의 최종 텍스트 블록. 보고서가 `SubagentHandback`을 거치는 서브에이전트의 경우 그 대신 해당 핸드백에 대한 짧은 메모 |
1897| `resolvedModel` | string | `"claude-sonnet-4-5"` | 서브에이전트가 시작한 모델. 요청된 모델과 다를 수 있습니다 |1896| `resolvedModel` | string | `"claude-sonnet-4-5"` | 서브에이전트가 시작된 모델로, 요청된 모델과 다를 수 있습니다 |
1898| `modelsUsed` | array | `["claude-sonnet-4-5", "claude-haiku-4-5"]` | 사용된 모델을 순서대로 나열하며 연속된 반복은 하나로 합칩니다. 실행 중에 모델이 교체된 경우에만 설정됩니다. Claude Code v2.1.212 이상이 필요합니다 |1897| `modelsUsed` | array | `["claude-sonnet-4-5", "claude-haiku-4-5"]` | 사용된 모델을 순서대로 나열한 목록(연속 반복은 하나로 합쳐짐). 실행 중에 모델이 교체된 경우에만 설정됩니다. Claude Code v2.1.212 이상이 필요합니다 |
1899| `totalTokens` | number | `12450` | 서브에이전트의 마지막 API 요청의 토큰 수: 입력, 출력, 캐시 토큰의 합계. 전체 실행에 대한 합계가 아닙니다 |1898| `totalTokens` | number | `12450` | 서브에이전트의 최종 API 요청에서의 토큰 수로, 입력, 출력, 캐시 토큰을 합한 값입니다. 전체 실행에 대한 합계가 아닙니다 |
1900| `totalDurationMs` | number | `48211` | 서브에이전트 실행의 실제 소요 시간 |1899| `totalDurationMs` | number | `48211` | 서브에이전트 실행의 실제 소요 시간 |
1901| `totalToolUseCount` | number | `7` | 서브에이전트가 수행한 도구 호출 수 |1900| `totalToolUseCount` | number | `7` | 서브에이전트가 수행한 도구 호출 수 |
1902| `usage` | object | `{"input_tokens": 8320, ...}` | 마지막 API 요청의 유형별 토큰 내역: `input_tokens`, `output_tokens`, `cache_creation_input_tokens`, `cache_read_input_tokens` |1901| `usage` | object | `{"input_tokens": 8320, ...}` | 최종 API 요청의 유형별 토큰 내역: `input_tokens`, `output_tokens`, `cache_creation_input_tokens`, `cache_read_input_tokens` |
1903 1902
1904Claude Code v2.1.271 이상에서는 Claude Code가 [자동 모드](/docs/ko/permission-modes#eliminate-prompts-with-auto-mode)에서 제공하는 [`SubagentHandback`](/docs/ko/tools-reference) 도구로 실행되는 서브에이전트가 보고서를 텍스트로 반환하지 않고 해당 도구를 통해 전달합니다. 이 경우 `completed` 결과의 `content` 필드에는 보고서 자체가 아니라 해당 인계에 대한 짧은 메모가 담깁니다. 보고서를 읽으려면 `SubagentHandback`에 `PreToolUse` 또는 `PostToolUse` 훅을 일치시키고 `tool_input.message`를 읽습니다.1903Claude Code v2.1.271 이상에서는 Claude Code가 [자동 모드](/docs/ko/permission-modes#eliminate-prompts-with-auto-mode)에서 제공하는 [`SubagentHandback`](/docs/ko/tools-reference) 도구와 함께 실행되는 서브에이전트가 보고서를 텍스트로 반환하지 않고 이 도구를 통해 전달합니다. 그러면 `completed` 결과의 `content` 필드에는 보고서 자체가 아니라 해당 핸드백에 대한 짧은 메모가 담깁니다. 보고서를 읽으려면 `SubagentHandback`에 `PreToolUse` 또는 `PostToolUse` 훅을 매칭하고 `tool_input.message`를 읽으세요.
1905 1904
1906백그라운드 서브에이전트의 경우 작업이 백그라운드로 이동할 때 도구가 반환되므로 `tool_response`에는 사용량 필드가 없습니다. 백그라운드 실행은 즉시 반환되고, Claude Code가 실행 도중 백그라운드로 전환한 포그라운드 작업은 그 전환 시점에 반환됩니다. 이 응답에는 `status: "async_launched"`, `agentId`, `description`, `prompt`, `outputFile`, `resolvedModel`이 포함됩니다.1905백그라운드 서브에이전트의 경우 작업이 백그라운드로 이동할 때 도구가 반환되므로 `tool_response`에는 사용량 필드가 없습니다. 백그라운드 실행은 즉시 반환되며, Claude Code가 실행 중에 백그라운드로 보낸 포그라운드 작업은 그 전환 시점에 반환됩니다. 응답에는 `status: "async_launched"`, `agentId`, `description`, `prompt`, `outputFile`, `resolvedModel`이 있습니다.
1907 1906
1908`completed` 응답에서 `resolvedModel`은 서브에이전트가 시작한 모델을 나타내며, `availableModels`나 다른 재정의가 적용되는 경우처럼 `tool_input`의 `model` 값과 다를 수 있습니다. `async_launched` 응답에서 `resolvedModel`은 에이전트가 백그라운드로 이동할 때 사용 중이던 모델을 나타내므로, 백그라운드 전환 전에 발생한 교체가 반영됩니다. `modelsUsed`와 백그라운드 전환 시점의 `resolvedModel` 동작에는 Claude Code v2.1.212 이상이 필요합니다.1907`completed` 응답에서 `resolvedModel`은 서브에이전트가 시작된 모델을 나타내며, `availableModels`나 다른 재정의가 적용되는 경우처럼 `tool_input`의 `model` 값과 다를 수 있습니다. `async_launched` 응답에서 `resolvedModel`은 에이전트가 백그라운드로 이동할 때 사용 중이던 모델을 나타내므로, 백그라운드 전환 전에 발생한 교체가 반영됩니다. `modelsUsed`와 백그라운드 전환 시점의 `resolvedModel` 동작에는 Claude Code v2.1.212 이상이 필요합니다.
1909 1908
1910<a id="askuserquestion" />1909<a id="askuserquestion" />
1911 1910
1915 1914
1916사용자에게 1\~4개의 객관식 질문을 합니다.1915사용자에게 1\~4개의 객관식 질문을 합니다.
1917 1916
1918| 필드 | 타입 | 예시 | 설명 |1917| 필드 | 유형 | 예시 | 설명 |
1919| :- | :- | :- | :- |1918| :- | :- | :- | :- |
1920| `questions` | array | `[{"question": "Which framework?", "header": "Framework", "options": [{"label": "React", "description": "Component library"}, {"label": "Vue", "description": "Progressive framework"}], "multiSelect": false}]` | 제시할 질문으로, 각각 `question` 문자열, 짧은 `header`, `options` 배열, 선택적 `multiSelect` 플래그를 가집니다 |1919| `questions` | array | `[{"question": "Which framework?", "header": "Framework", "options": [{"label": "React", "description": "Component library"}, {"label": "Vue", "description": "Progressive framework"}], "multiSelect": false}]` | 표시할 질문. 각 질문에는 `question` 문자열, 짧은 `header`, `options` 배열, 선택적 `multiSelect` 플래그가 있습니다 |
1921| `answers` | object | `{"Which framework?": "React"}` | 선택 사항. 질문 텍스트를 선택된 옵션 레이블에 매핑합니다. 다중 선택 답변은 레이블을 쉼표로 연결합니다. Claude는 이 필드를 설정하지 않으며, 프로그래밍 방식으로 답하려면 `updatedInput`을 통해 제공합니다 |1920| `answers` | object | `{"Which framework?": "React"}` | 선택 사항. 질문 텍스트를 선택된 옵션 레이블에 매핑합니다. 다중 선택 답변은 레이블을 쉼표로 연결합니다. Claude는 이 필드를 설정하지 않으므로, 프로그래밍 방식으로 답변하려면 `updatedInput`을 통해 제공하세요 |
1922 1921
1923<h5 id="exitplanmode">1922<h5 id="exitplanmode">
1924 ExitPlanMode1923 ExitPlanMode
1925</h5>1924</h5>
1926 1925
1927Claude가 [플랜 모드](/docs/ko/permission-modes#analyze-before-you-edit-with-plan-mode)를 벗어나기 전에 계획을 제시하고 사용자에게 승인을 요청합니다. Claude는 도구를 호출하기 전에 계획을 디스크의 파일에 작성하므로, 모델이 보낸 실제 `tool_input`은 일반적으로 비어 있습니다. Claude Code는 입력을 훅에 전달하기 전에 계획 내용과 파일 경로를 주입합니다.1926Claude가 [플랜 모드](/docs/ko/permission-modes#analyze-before-you-edit-with-plan-mode)를 종료하기 전에 플랜을 제시하고 사용자에게 승인을 요청합니다. Claude는 도구를 호출하기 전에 플랜을 디스크의 파일에 쓰므로, 모델이 보내는 실제 `tool_input`은 일반적으로 비어 있습니다. Claude Code는 입력을 훅에 전달하기 전에 플랜 내용과 파일 경로를 주입합니다.
1928 1927
1929| 필드 | 타입 | 예시 | 설명 |1928| 필드 | 유형 | 예시 | 설명 |
1930| :- | :- | :- | :- |1929| :- | :- | :- | :- |
1931| `plan` | string | `"## Refactor auth\n1. Extract..."` | Markdown 형식의 계획 내용. 디스크의 계획 파일에서 주입됩니다 |1930| `plan` | string | `"## Refactor auth\n1. Extract..."` | Markdown 형식의 플랜 내용. 디스크의 플랜 파일에서 주입됩니다 |
1932| `planFilePath` | string | `"/Users/.../plans/refactor-auth.md"` | 계획 파일 경로. 주입됩니다 |1931| `planFilePath` | string | `"/Users/.../plans/refactor-auth.md"` | 플랜 파일 경로. 주입됩니다 |
1933| `allowedPrompts` | array | `[{"tool": "Bash", "prompt": "run tests"}]` | deprecated. Claude Code는 이 필드를 받아들이지만 무시합니다. v2.1.205 이전에는 Claude가 계획을 구현하기 위해 요청한 프롬프트 기반 권한을 담았습니다 |1932| `allowedPrompts` | array | `[{"tool": "Bash", "prompt": "run tests"}]` | deprecated. Claude Code는 이 필드를 허용하지만 무시합니다. v2.1.205 이전에는 Claude가 플랜을 구현하기 위해 요청한 프롬프트 기반 권한을 담았습니다 |
1934 1933
1935`PostToolUse`에서 `tool_response`는 승인된 계획을 담은 `plan` 및 `filePath` 필드와 내부 상태 플래그가 포함된 객체입니다. 계획 내용은 디스크에서 파일을 다시 읽지 말고 `tool_response.plan`에서 읽습니다.1934`PostToolUse`에서 `tool_response`는 승인된 플랜을 담은 `plan` 및 `filePath` 필드와 내부 상태 플래그가 있는 객체입니다. 디스크에서 파일을 다시 읽지 말고 플랜 내용은 `tool_response.plan`에서 읽으세요.
1936 1935
1937<h4 id="pretooluse-decision-control">1936<h4 id="pretooluse-decision-control">
1938 PreToolUse 결정 제어1937 PreToolUse 결정 제어
1939</h4>1938</h4>
1940 1939
1941`PreToolUse` 훅은 도구 호출의 진행 여부를 제어할 수 있습니다. 최상위 `decision` 필드를 사용하는 다른 훅과 달리 PreToolUse는 `hookSpecificOutput` 객체 안에서 결정을 반환합니다. 이를 통해 더 풍부한 제어가 가능합니다. 네 가지 결과(허용, 거부, 확인 요청, 지연)와 함께 실행 전에 도구 입력을 수정하는 기능을 제공합니다.1940`PreToolUse` 훅은 도구 호출의 진행 여부를 제어할 수 있습니다. 최상위 `decision` 필드를 사용하는 다른 훅과 달리 PreToolUse는 `hookSpecificOutput` 객체 안에 결정을 반환합니다. 이를 통해 네 가지 결과(allow, deny, ask, defer)와 실행 전 도구 입력을 수정하는 기능이라는 더 풍부한 제어가 가능합니다.
1942 1941
1943| 필드 | 설명 |1942| 필드 | 설명 |
1944| :- | :- |1943| :- | :- |
1945| `permissionDecision` | `"allow"`는 권한 프롬프트를 건너뜁니다. 단, [어떤 모드도 자동 승인하지 않는 작업](/docs/ko/permission-modes#actions-no-mode-auto-approves)과, [`updatedInput`과 함께 사용](#allow-with-updatedinput)해야 하는 `AskUserQuestion` 및 `ExitPlanMode`는 예외입니다. `"deny"`는 도구 호출을 막습니다. `"ask"`는 사용자에게 확인을 요청합니다. `"defer"`는 나중에 도구를 재개할 수 있도록 정상적으로 종료합니다. 훅이 무엇을 반환하든 [거부 및 확인 규칙](/docs/ko/permissions#manage-permissions)은 여전히 평가됩니다 |1944| `permissionDecision` | `"allow"`는 권한 프롬프트를 건너뜁니다. 단, [어떤 모드도 자동 승인하지 않는 작업](/docs/ko/permission-modes#actions-no-mode-auto-approves)과, [`updatedInput`을 함께 사용해야 하는](#allow-with-updatedinput) `AskUserQuestion` 및 `ExitPlanMode`는 예외입니다. `"deny"`는 도구 호출을 막습니다. `"ask"`는 사용자에게 확인을 요청합니다. `"defer"`는 나중에 도구를 재개할 수 있도록 정상적으로 종료합니다. 훅이 무엇을 반환하든 [거부 및 확인 규칙](/docs/ko/permissions#manage-permissions)은 여전히 평가됩니다 |
1946| `permissionDecisionReason` | `"ask"`의 경우 권한 프롬프트에서 사용자에게 표시됩니다. 아무도 해당 프롬프트에 응답할 수 없는 `-p` 실행에서 Claude Code가 [호출을 거부](/docs/ko/headless#turn-off-permission-prompts-in-unattended-runs)하면 Claude는 대신 도구 결과에서 이유를 읽습니다. `"deny"`의 경우 Claude에게 표시됩니다. `"allow"`와 `"defer"`의 경우 [디버그 로그](#debug-hooks)에만 기록됩니다 |1945| `permissionDecisionReason` | `"ask"`의 경우 권한 프롬프트에서 사용자에게 표시됩니다. 아무도 그 프롬프트에 응답할 수 없는 `-p` 실행에서 Claude Code가 [호출을 거부](/docs/ko/headless#turn-off-permission-prompts-in-unattended-runs)하면, Claude는 대신 도구 결과에서 이유를 읽습니다. `"deny"`의 경우 Claude에게 표시됩니다. `"allow"` 및 `"defer"`의 경우 [디버그 로그](#debug-hooks)에만 기록됩니다 |
1947| `updatedInput` | 실행 전에 도구의 입력 매개변수를 수정합니다. 전체 입력 객체를 대체하므로 수정한 필드와 함께 변경하지 않은 필드도 포함해야 합니다. Claude Code는 Claude가 보낸 입력이 아니라 훅이 반환한 입력을 기준으로 권한 규칙과 Bash 명령의 [자동 백그라운드 전환 적격성](/docs/ko/tools-reference#foreground-commands-that-move-to-the-background)을 평가합니다. 자동 승인하려면 `"allow"`와, 수정된 입력을 사용자에게 보여 주려면 `"ask"`와 함께 사용합니다. `"defer"`의 경우 무시됩니다 |1946| `updatedInput` | 실행 전에 도구의 입력 매개변수를 수정합니다. 전체 입력 객체를 대체하므로 수정된 필드와 함께 변경되지 않은 필드도 포함하세요. Claude Code는 권한 규칙과 Bash 명령의 [자동 백그라운드 적격성](/docs/ko/tools-reference#foreground-commands-that-move-to-the-background)을 Claude가 보낸 입력이 아니라 훅이 반환한 입력을 기준으로 평가합니다. 자동 승인하려면 `"allow"`와, 수정된 입력을 사용자에게 보여 주려면 `"ask"`와 함께 사용하세요. `"defer"`의 경우 무시됩니다 |
1948| `additionalContext` | 도구 결과와 함께 Claude의 컨텍스트에 추가되는 문자열. `permissionDecision`이 `"defer"`이면 무시됩니다. [Claude를 위한 컨텍스트 추가](#add-context-for-claude)를 참조하세요 |1947| `additionalContext` | 도구 결과와 함께 Claude의 컨텍스트에 추가되는 문자열. `permissionDecision`이 `"defer"`이면 무시됩니다. [Claude를 위한 컨텍스트 추가](#add-context-for-claude)를 참조하세요 |
1949 1948
1950여러 PreToolUse 훅이 서로 다른 결정을 반환하는 경우 우선순위는 `deny` > `defer` > `ask` > `allow`입니다.1949여러 PreToolUse 훅이 서로 다른 결정을 반환하면 우선순위는 `deny` > `defer` > `ask` > `allow`입니다.
1951 1950
1952종료 코드 2로 차단하는 훅은 `"deny"`와 같은 방식으로 전달됩니다. Claude는 stderr 메시지를 거부 이유로 봅니다.1951종료 코드 2로 차단하는 훅은 `"deny"`와 같은 방식으로 처리됩니다. Claude는 stderr 메시지를 거부 이유로 봅니다.
1953 1952
1954훅이 `"ask"`를 반환하면 사용자에게 표시되는 권한 프롬프트에 훅의 출처를 식별하는 레이블이 포함됩니다. 설정 파일이나 에이전트 frontmatter의 훅은 `[settings]`, 플러그인의 훅은 `[plugin:<name>]`, 스킬 frontmatter의 훅은 `[skill]`입니다. 이를 통해 사용자는 어떤 구성 출처가 확인을 요청하는지 이해할 수 있습니다.1953훅이 `"ask"`를 반환하면 사용자에게 표시되는 권한 프롬프트에 훅의 출처를 식별하는 레이블이 포함됩니다. 설정 파일이나 에이전트 frontmatter의 훅은 `[settings]`, 플러그인의 훅은 `[plugin:<name>]`, 스킬 frontmatter의 훅은 `[skill]`로 표시됩니다. 이를 통해 사용자는 어떤 구성 소스가 확인을 요청하는지 이해할 수 있습니다.
1955 1954
1956훅의 `"ask"`는 [자동 모드](/docs/ko/permission-modes#eliminate-prompts-with-auto-mode)에서도 권한 프롬프트를 강제합니다. 분류기는 여전히 도구 호출을 거부할 수 있지만, 호출을 조용히 승인할 수는 없습니다. v2.1.211 이전에는 분류기가 [샌드박스](/docs/ko/sandboxing) 외부에서 실행되는 Bash 명령을 훅이 요청한 프롬프트를 표시하지 않고 승인할 수 있었습니다. 이 경우에도 분류기는 해당 명령에 자체 안전 규칙을 적용했으며, 훅의 `"deny"`는 항상 적용되었습니다.1955훅의 `"ask"`는 [자동 모드](/docs/ko/permission-modes#eliminate-prompts-with-auto-mode)에서도 권한 프롬프트를 강제합니다. 분류기는 여전히 도구 호출을 거부할 수 있지만 호출을 조용히 승인할 수는 없습니다. v2.1.211 이전에는 분류기가 [샌드박스](/docs/ko/sandboxing) 외부에서 실행되는 Bash 명령을 훅이 요청한 프롬프트를 표시하지 않고 승인할 수 있었습니다. 이 경우에도 분류기는 해당 명령에 자체 안전 규칙을 적용했으며, 훅의 `"deny"`는 항상 존중되었습니다.
1957 1956
1958```json theme={null}1957```json theme={null}
1959{1958{
1970```1969```
1971 1970
1972<Note>1971<Note>
1973 PreToolUse는 이전에 최상위 `decision` 및 `reason` 필드를 사용했지만, 이 이벤트에서는 deprecated되었습니다. 대신 `hookSpecificOutput.permissionDecision` 및 `hookSpecificOutput.permissionDecisionReason`을 사용하십시오. deprecated 값 `"approve"`와 `"block"`은 각각 `"allow"`와 `"deny"`에 매핑됩니다. PostToolUse 및 Stop 같은 다른 이벤트는 현재 형식으로 최상위 `decision`과 `reason`을 계속 사용합니다.1972 PreToolUse는 이전에 최상위 `decision` 및 `reason` 필드를 사용했지만, 이 이벤트에서는 deprecated되었습니다. 대신 `hookSpecificOutput.permissionDecision` 및 `hookSpecificOutput.permissionDecisionReason`을 사용하세요. deprecated 값인 `"approve"`와 `"block"`은 각각 `"allow"`와 `"deny"`에 매핑됩니다. PostToolUse와 Stop 같은 다른 이벤트는 현재 형식으로 최상위 `decision`과 `reason`을 계속 사용합니다.
1974</Note>1973</Note>
1975 1974
1976<h4 id="allow-with-updatedinput">1975<h4 id="allow-with-updatedinput">
1977 사용자 상호작용이 필요한 도구1976 사용자 상호 작용이 필요한 도구
1978</h4>1977</h4>
1979 1978
1980`AskUserQuestion`과 `ExitPlanMode`는 사용자 상호작용이 필요합니다. `-p` 플래그를 사용하는 [비대화형 모드](/docs/ko/headless)에서 Claude Code는 Agent SDK `canUseTool` 콜백처럼 프롬프트를 받을 [권한 호스트](/docs/ko/headless#turn-off-permission-prompts-in-unattended-runs)가 실행에 있는 경우에만 이 도구를 제공합니다.1979`AskUserQuestion`과 `ExitPlanMode`는 사용자 상호 작용이 필요합니다. `-p` 플래그를 사용하는 [비대화형 모드](/docs/ko/headless)에서 Claude Code는 Agent SDK `canUseTool` 콜백처럼 프롬프트를 받을 [권한 호스트](/docs/ko/headless#turn-off-permission-prompts-in-unattended-runs)가 실행에 있을 때만 이 도구를 제공합니다.
1981 1980
1982`PreToolUse` 훅은 다음을 수행할 때 이 요구 사항을 충족합니다.1981`PreToolUse` 훅은 다음을 수행할 때 이 요구 사항을 충족합니다:
1983 1982
19841. stdin에서 도구의 입력을 읽습니다19831. stdin에서 도구의 입력을 읽습니다
19852. 자체 UI를 통해 답변을 수집합니다19842. 자체 UI를 통해 답변을 수집합니다
19863. 답변을 담은 `updatedInput`과 함께 `permissionDecision: "allow"`를 반환하여 도구가 확인 요청 없이 실행되게 합니다19853. 답변을 담은 `updatedInput`과 함께 `permissionDecision: "allow"`를 반환하여 프롬프트 없이 도구가 실행되도록 합니다
1987 1986
1988이 도구에는 `"allow"`만 반환하는 것으로는 충분하지 않습니다.1987이러한 도구에는 `"allow"`만 반환하는 것으로는 충분하지 않습니다.
1989 1988
1990`AskUserQuestion`의 경우 원래 `questions` 배열을 그대로 돌려보내고, 각 질문 텍스트를 선택된 답변에 매핑하는 [`answers`](#askuserquestion) 객체를 추가하십시오. 다음 출력은 한 질문에 `React`로 답합니다.1989`AskUserQuestion`의 경우 원래 `questions` 배열을 그대로 반환하고, 각 질문의 텍스트를 선택된 답변에 매핑하는 [`answers`](#askuserquestion) 객체를 추가하세요. 이 출력은 한 질문에 `React`로 답합니다:
1991 1990
1992```json theme={null}1991```json theme={null}
1993{1992{
2009}2008}
2010```2009```
2011 2010
2012서버가 [`_meta["anthropic/requiresUserInteraction"]`](/docs/ko/mcp#require-approval-for-a-specific-tool)로 표시한 MCP 도구는 더 엄격합니다. 훅은 `updatedInput` 유무와 관계없이 `"allow"`로 승인 프롬프트를 건너뛸 수 없습니다. Claude Code가 훅이 해당 도구에 필요한 상호 작용을 수집했는지 확인할 수 없기 때문입니다.2011서버가 [`_meta["anthropic/requiresUserInteraction"]`](/docs/ko/mcp#require-approval-for-a-specific-tool)으로 표시한 MCP 도구는 더 엄격합니다. 훅은 `updatedInput` 유무와 관계없이 `"allow"`로 승인 프롬프트를 건너뛸 수 없습니다. Claude Code는 훅이 도구에 필요한 상호 작용을 수집했는지 확인할 수 없기 때문입니다.
2013 2012
2014<h4 id="defer-a-tool-call-for-later">2013<h4 id="defer-a-tool-call-for-later">
2015 도구 호출을 나중으로 지연2014 나중을 위해 도구 호출 지연
2016</h4>2015</h4>
2017 2016
2018`"defer"`는 Agent SDK 앱이나 Claude Code 위에 구축된 사용자 지정 UI처럼 `claude -p`를 하위 프로세스로 실행하고 JSON 출력을 읽는 통합을 위한 것입니다. 이를 통해 호출하는 프로세스가 도구 호출 시점에 Claude를 일시 중지하고, 자체 인터페이스를 통해 입력을 수집한 다음, 중단한 지점에서 재개할 수 있습니다. Claude Code는 `-p` 플래그를 사용하는 [비대화형 모드](/docs/ko/headless)에서만 이 값을 적용합니다. 대화형 세션에서는 경고를 로그에 기록하고 훅 결과를 무시합니다.2017`"defer"`는 Agent SDK 앱이나 Claude Code 위에 구축된 사용자 지정 UI처럼 `claude -p`를 하위 프로세스로 실행하고 JSON 출력을 읽는 통합을 위한 것입니다. 이를 통해 호출 프로세스는 도구 호출 시점에서 Claude를 일시 중지하고, 자체 인터페이스를 통해 입력을 수집한 다음, 중단한 지점에서 재개할 수 있습니다. Claude Code는 `-p` 플래그를 사용하는 [비대화형 모드](/docs/ko/headless)에서만 이 값을 따릅니다. 대화형 세션에서는 경고를 로그에 기록하고 훅 결과를 무시합니다.
2019 2018
2020`AskUserQuestion` 도구가 대표적인 경우입니다. Claude가 사용자에게 무언가를 묻고 싶지만 답변할 터미널이 없습니다. `-p` 실행은 `--permission-prompt-tool`로 전달하는 MCP 도구 같은 [권한 호스트](/docs/ko/headless#turn-off-permission-prompts-in-unattended-runs)가 있을 때만 `AskUserQuestion`을 제공하므로, 권한 호스트와 함께 실행을 시작합니다. 왕복 과정은 다음과 같습니다.2019`AskUserQuestion` 도구가 대표적인 경우입니다. Claude가 사용자에게 무언가를 묻고 싶지만 응답할 터미널이 없는 상황입니다. `-p` 실행은 `--permission-prompt-tool`로 전달하는 MCP 도구 같은 [권한 호스트](/docs/ko/headless#turn-off-permission-prompts-in-unattended-runs)가 있을 때만 `AskUserQuestion`을 제공하므로, 권한 호스트와 함께 실행을 시작하세요. 왕복 과정은 다음과 같습니다:
2021 2020
20221. Claude가 `AskUserQuestion`을 호출합니다. `PreToolUse` 훅이 발생합니다.20211. Claude가 `AskUserQuestion`을 호출합니다. `PreToolUse` 훅이 발생합니다.
20232. 훅이 `permissionDecision: "defer"`를 반환합니다. 도구는 실행되지 않습니다. 프로세스는 `stop_reason: "tool_deferred"`와 함께 종료되며, 보류 중인 도구 호출은 트랜스크립트에 보존됩니다.20222. 훅이 `permissionDecision: "defer"`를 반환합니다. 도구는 실행되지 않습니다. 프로세스는 `stop_reason: "tool_deferred"`와 함께 종료되며, 보류 중인 도구 호출은 트랜스크립트에 보존됩니다.
20243. 호출하는 프로세스가 SDK 결과에서 `deferred_tool_use`를 읽고, 자체 UI에 질문을 표시한 다음 답변을 기다립니다.20233. 호출 프로세스가 SDK 결과에서 `deferred_tool_use`를 읽고, 자체 UI에 질문을 표시한 다음, 답변을 기다립니다.
20254. 호출하는 프로세스가 같은 권한 호스트로 `claude -p --resume <session-id>`를 실행합니다. 같은 도구 호출이 `PreToolUse`를 다시 발생시킵니다.20244. 호출 프로세스가 같은 권한 호스트로 `claude -p --resume <session-id>`를 실행합니다. 같은 도구 호출이 `PreToolUse`를 다시 발생시킵니다.
20265. 훅이 `updatedInput`에 답변을 담아 `permissionDecision: "allow"`를 반환합니다. 도구가 실행되고 Claude가 계속 진행합니다.20255. 훅이 `updatedInput`에 답변을 담아 `permissionDecision: "allow"`를 반환합니다. 도구가 실행되고 Claude가 계속 진행합니다.
2027 2026
2028`deferred_tool_use` 필드에는 도구의 `id`, `name`, `input`이 담깁니다. `input`은 Claude가 도구 호출을 위해 생성한 매개변수로, 실행 전에 캡처됩니다.2027`deferred_tool_use` 필드에는 도구의 `id`, `name`, `input`이 담깁니다. `input`은 Claude가 도구 호출을 위해 생성한 매개변수로, 실행 전에 캡처됩니다:
2029 2028
2030```json theme={null}2029```json theme={null}
2031{2030{
2041}2040}
2042```2041```
2043 2042
2044타임아웃이나 재시도 제한은 없습니다. 세션은 재개할 때까지 디스크에 남아 있으며, [보존 정리 규칙](/docs/ko/claude-directory#cleaned-up-automatically)에 따라 기본적으로 30일 후 세션 파일을 삭제하는 [`cleanupPeriodDays`](/docs/ko/settings-reference#cleanupperioddays) 보존 정리의 적용을 받습니다. 재개할 때 답변이 준비되지 않았다면 훅이 다시 `"defer"`를 반환할 수 있으며, 프로세스는 같은 방식으로 종료됩니다. 호출하는 프로세스는 최종적으로 훅에서 `"allow"` 또는 `"deny"`를 반환하여 루프를 끝낼 시점을 제어합니다.2043타임아웃이나 재시도 제한은 없습니다. 세션은 재개할 때까지 디스크에 남아 있으며, [`cleanupPeriodDays`](/docs/ko/settings-reference#cleanupperioddays) 보존 정리의 적용을 받습니다. 이 정리는 [보존 정리 규칙](/docs/ko/claude-directory#cleaned-up-automatically)에 따라 기본적으로 30일 후 세션 파일을 삭제합니다. 재개할 때 답변이 준비되지 않았다면 훅은 다시 `"defer"`를 반환할 수 있으며, 프로세스는 같은 방식으로 종료됩니다. 호출 프로세스는 결국 훅에서 `"allow"` 또는 `"deny"`를 반환하여 루프를 끝낼 시점을 제어합니다.
2045 2044
2046`"defer"`는 Claude가 해당 턴에서 단일 도구 호출을 할 때만 작동합니다. Claude가 여러 도구 호출을 한 번에 하면 `"defer"`는 경고와 함께 무시되고 도구는 일반 권한 흐름을 거쳐 진행됩니다. 이 제약은 재개 시 하나의 도구만 다시 실행할 수 있기 때문에 존재합니다. 묶음에서 하나의 호출만 지연하면 나머지 호출이 해결되지 않은 상태로 남게 됩니다.2045`"defer"`는 Claude가 턴에서 단일 도구 호출을 할 때만 작동합니다. Claude가 여러 도구 호출을 한 번에 하면 `"defer"`는 경고와 함께 무시되고, 도구는 일반 권한 흐름을 통해 진행됩니다. 이 제약은 재개 시 하나의 도구만 다시 실행할 수 있기 때문에 존재합니다. 다른 호출을 해결되지 않은 상태로 남기지 않고 배치에서 하나의 호출만 지연할 방법은 없습니다.
2047 2046
2048재개할 때 지연된 도구를 더 이상 사용할 수 없으면, 프로세스는 훅이 발생하기 전에 `stop_reason: "tool_deferred_unavailable"` 및 `is_error: true`와 함께 종료됩니다. 이는 도구를 제공한 MCP 서버가 재개된 세션에 연결되지 않은 경우에 발생합니다. 어떤 도구가 사라졌는지 식별할 수 있도록 `deferred_tool_use` 페이로드는 여전히 포함됩니다.2047재개할 때 지연된 도구를 더 이상 사용할 수 없으면, 프로세스는 훅이 발생하기 전에 `stop_reason: "tool_deferred_unavailable"` 및 `is_error: true`와 함께 종료됩니다. 이는 도구를 제공한 MCP 서버가 재개된 세션에 연결되어 있지 않을 때 발생합니다. 어떤 도구가 누락되었는지 식별할 수 있도록 `deferred_tool_use` 페이로드는 여전히 포함됩니다.
2049 2048
2050<Note>2049<Note>
2051 지연된 세션을 플랜 모드로 재개하려면 Claude Code가 승인을 위해 계획을 제시할 수 있도록 `--resume`과 함께 [`--permission-prompt-tool`](/docs/ko/cli-reference#cli-flags)을 전달합니다. 특정 다른 실행 플래그를 전달하면 재개된 실행이 플랜 모드로 돌아가지 않습니다. [`-p`로 플랜 모드에서 재개](/docs/ko/sessions#resume-in-plan-mode-with-p)를 참조하세요. Claude Code v2.1.246 이상이 필요합니다.2050 플랜 모드에서 지연된 세션을 재개하려면 Claude Code가 승인을 위해 플랜을 제시할 수 있도록 `--resume`과 함께 [`--permission-prompt-tool`](/docs/ko/cli-reference#cli-flags)을 전달하세요. 특정 다른 실행 플래그를 전달하면 재개된 실행이 플랜 모드로 돌아가지 않습니다. [`-p`로 플랜 모드에서 재개](/docs/ko/sessions#resume-in-plan-mode-with-p)를 참조하세요. Claude Code v2.1.246 이상이 필요합니다.
2052 2051
2053 `-p`로 재개하면 Claude Code는 저장된 다른 권한 모드를 복원하지 않습니다. 새로운 `claude -p` 실행이 시작하는 권한 모드로 실행을 시작하므로, 지연된 세션이 `--permission-mode` 또는 `--dangerously-skip-permissions`를 사용했다면 다시 전달해야 합니다. `-p` 없이 `claude --resume <session-id>`로 재개하면 Claude Code는 [재개 시 권한 모드](/docs/ko/sessions#permission-mode-on-resume)에 나열된 예외를 제외하고 저장된 권한 모드를 복원합니다.2052 `-p`로 재개하면 Claude Code는 저장된 다른 권한 모드를 복원하지 않습니다. 새 `claude -p` 실행이 시작되는 권한 모드로 실행을 시작하므로, 지연된 세션에서 `--permission-mode` 또는 `--dangerously-skip-permissions`를 사용했다면 다시 전달하세요. `-p` 없이 `claude --resume <session-id>`로 재개하면 Claude Code는 [재개 시 권한 모드](/docs/ko/sessions#permission-mode-on-resume)에 나열된 예외를 제외하고 저장된 권한 모드를 복원합니다.
2054</Note>2053</Note>
2055 2054
2056<h3 id="permissionrequest">2055<h3 id="permissionrequest">
2057 PermissionRequest2056 PermissionRequest
2058</h3>2057</h3>
2059 2058
2060Claude Code가 도구 사용 권한을 요청하려고 할 때 실행됩니다. [비대화형 모드](/docs/ko/headless)의 백그라운드 서브에이전트처럼 프롬프트를 표시할 수 없는 세션에서도 Claude Code는 이 훅을 실행하며, 결정을 반환하는 훅이 없으면 도구 호출을 거부합니다. `--permission-prompt-tool`이나 Agent SDK의 [`canUseTool` 콜백](/docs/ko/agent-sdk/permissions)에 도달하는 호출의 경우 훅은 호스트와 함께 실행되며, 먼저 결정하는 쪽이 적용됩니다.2059Claude Code가 도구 사용 권한을 요청하려 할 때 실행됩니다. [비대화형 모드](/docs/ko/headless)의 백그라운드 서브에이전트처럼 프롬프트를 표시할 수 없는 세션에서도 Claude Code는 이 훅을 실행하며, 결정을 반환하는 훅이 없으면 도구 호출을 거부합니다. `--permission-prompt-tool` 또는 Agent SDK의 [`canUseTool` 콜백](/docs/ko/agent-sdk/permissions)에 도달하는 호출의 경우 훅이 호스트와 함께 실행되며, 먼저 결정하는 쪽이 적용됩니다.
2061사용자를 대신하여 허용하거나 거부하려면 [PermissionRequest 결정 제어](#permissionrequest-decision-control)를 사용합니다.2060[PermissionRequest 결정 제어](#permissionrequest-decision-control)를 사용해 사용자를 대신하여 허용하거나 거부하세요.
2062 2061
2063Claude가 도구 사용 권한을 요청하는 순간 신호가 필요할 때 이 이벤트를 사용합니다. Claude Code는 프롬프트가 약 6초 동안 대기한 후에만 `permission_prompt` 유형의 [Notification](#notification) 훅을 실행합니다.2062Claude가 도구 사용 권한을 요청하는 즉시 신호가 필요할 때 이 이벤트를 사용하세요. Claude Code는 프롬프트가 약 6초 동안 대기한 후에야 `permission_prompt` 유형의 [Notification](#notification) 훅을 실행합니다.
2064 2063
2065Claude Code는 샌드박스 처리된 명령의 [네트워크 요청](/docs/ko/sandboxing#network-isolation)에 대해서는 PermissionRequest 훅을 실행하지 않습니다. 해당 프롬프트에 대한 신호를 받으려면 `permission_prompt` 알림 유형을 사용합니다.2064Claude Code는 샌드박스된 명령의 [네트워크 요청](/docs/ko/sandboxing#network-isolation)에 대해서는 PermissionRequest 훅을 실행하지 않습니다. 해당 프롬프트에 대한 신호를 받으려면 `permission_prompt` 알림 유형을 사용하세요.
2066 2065
2067도구 이름에 대해 일치시키며, 값은 PreToolUse와 같습니다.2066PreToolUse와 같은 값으로 도구 이름에 대해 매칭합니다.
2068 2067
2069<h4 id="permissionrequest-input">2068<h4 id="permissionrequest-input">
2070 PermissionRequest 입력2069 PermissionRequest 입력
2071</h4>2070</h4>
2072 2071
2073PermissionRequest 훅은 PreToolUse 훅처럼 `tool_name` 및 `tool_input` 필드를 수신하지만 `tool_use_id`는 없습니다. MCP 도구의 경우 [`mcp_server`](#pretooluse-input) 객체도 수신합니다. 선택적 `permission_suggestions` 배열에는 허용 규칙 추가나 권한 모드 변경처럼 Claude Code가 이 요청에 대해 제안하는 [권한 업데이트](#permission-update-entries)가 담깁니다.2072PermissionRequest 훅은 PreToolUse 훅처럼 `tool_name` 및 `tool_input` 필드를 받지만 `tool_use_id`는 받지 않습니다. MCP 도구의 경우 [`mcp_server`](#pretooluse-input) 객체도 받습니다. 선택적 `permission_suggestions` 배열에는 허용 규칙 추가나 권한 모드 변경처럼 Claude Code가 이 요청에 대해 제안하는 [권한 업데이트](#permission-update-entries)가 들어 있습니다.
2074 2073
2075각 권한 대화 상자는 자체 옵션을 구성하므로 `permission_suggestions` 배열은 사용자에게 보이는 옵션의 정확한 목록이 아닙니다. 파일 편집 대화 상자처럼 일부 대화 상자는 배열을 전혀 읽지 않고 요청 자체에서 옵션을 도출합니다. 배열을 읽는 대화 상자도 제안이 배열에 남아 있는 옵션을 표시하지 않을 수 있습니다. 예를 들어 [`allowManagedPermissionRulesOnly`](/docs/ko/settings-reference#allowmanagedpermissionrulesonly)가 규칙 저장 옵션을 숨기는 경우입니다. 또한 [**Yes, and switch to auto mode**](/docs/ko/permission-modes#switch-permission-modes)처럼 제안 항목이 없는 옵션을 제공할 수도 있으며, 이 옵션은 권한 업데이트를 거치지 않고 권한 모드를 직접 변경합니다.2074각 권한 대화 상자는 자체 옵션을 구성하므로 `permission_suggestions` 배열은 화면에 표시되는 옵션의 정확한 목록이 아닙니다. 파일 편집용 대화 상자처럼 일부 대화 상자는 배열을 전혀 읽지 않고 요청 자체에서 옵션을 도출합니다. 배열을 읽는 대화 상자도 제안이 배열에 남아 있는 옵션을 숨길 수 있습니다. 예를 들어 [`allowManagedPermissionRulesOnly`](/docs/ko/settings-reference#allowmanagedpermissionrulesonly)가 규칙 저장 옵션을 숨기는 경우입니다. 또한 권한 업데이트를 통하지 않고 권한 모드를 직접 변경하는 [**Yes, and switch to auto mode**](/docs/ko/permission-modes#switch-permission-modes)처럼 제안 항목이 없는 옵션을 제공할 수도 있습니다.
2076 2075
2077PreToolUse 훅은 권한이 필요한지 여부와 관계없이 모든 도구 호출 전에 실행됩니다. PermissionRequest 훅은 Claude Code가 권한을 요청하려고 할 때, 또는 프롬프트를 표시할 수 없는 호출을 자동으로 거부하려고 할 때만 실행됩니다. 두 이벤트 모두 [`EndConversation`](/docs/ko/tools-reference#endconversation-tool-behavior)에서는 발생하지 않습니다.2076PreToolUse 훅은 권한이 필요한지 여부와 관계없이 모든 도구 호출 전에 실행됩니다. PermissionRequest 훅은 Claude Code가 권한을 요청하려 할 때, 또는 프롬프트를 표시할 수 없는 호출을 자동 거부하려 할 때만 실행됩니다. 두 이벤트 모두 [`EndConversation`](/docs/ko/tools-reference#endconversation-tool-behavior)에 대해서는 발생하지 않습니다.
2078 2077
2079```json theme={null}2078```json theme={null}
2080{2079{
2103 PermissionRequest 결정 제어2102 PermissionRequest 결정 제어
2104</h4>2103</h4>
2105 2104
2106`PermissionRequest` 훅은 권한 요청을 허용하거나 거부할 수 있습니다. 모든 훅에서 사용할 수 있는 [JSON 출력 필드](#json-output) 외에도 훅 스크립트는 다음 이벤트별 필드가 포함된 `decision` 객체를 반환할 수 있습니다.2105`PermissionRequest` 훅은 권한 요청을 허용하거나 거부할 수 있습니다. 모든 훅에서 사용할 수 있는 [JSON 출력 필드](#json-output) 외에도 훅 스크립트는 다음 이벤트별 필드가 있는 `decision` 객체를 반환할 수 있습니다:
2107 2106
2108| 필드 | 설명 |2107| 필드 | 설명 |
2109| :- | :- |2108| :- | :- |
2110| `behavior` | `"allow"`는 권한을 부여하고, `"deny"`는 거부합니다. [거부 및 확인 규칙](/docs/ko/permissions#manage-permissions)은 여전히 평가되므로, `"allow"`를 반환하는 훅이 일치하는 거부 규칙을 재정의하지는 않습니다 |2109| `behavior` | `"allow"`는 권한을 부여하고 `"deny"`는 거부합니다. [거부 및 확인 규칙](/docs/ko/permissions#manage-permissions)은 여전히 평가되므로 `"allow"`를 반환하는 훅이 일치하는 거부 규칙을 재정의하지 않습니다 |
2111| `updatedInput` | `"allow"` 전용: 실행 전에 도구의 입력 매개변수를 수정합니다. 전체 입력 객체를 대체하므로 수정한 필드와 함께 변경하지 않은 필드도 포함해야 합니다. 수정된 입력은 거부 및 확인 규칙에 대해 다시 평가됩니다 |2110| `updatedInput` | `"allow"` 전용: 실행 전에 도구의 입력 매개변수를 수정합니다. 전체 입력 객체를 대체하므로 수정된 필드와 함께 변경되지 않은 필드도 포함하세요. 수정된 입력은 거부 및 확인 규칙에 대해 다시 평가됩니다 |
2112| `updatedPermissions` | `"allow"` 전용: 허용 규칙 추가나 세션 권한 모드 변경처럼 적용할 [권한 업데이트 항목](#permission-update-entries)의 배열 |2111| `updatedPermissions` | `"allow"` 전용: 허용 규칙 추가나 세션 권한 모드 변경처럼 적용할 [권한 업데이트 항목](#permission-update-entries) 배열 |
2113| `message` | `"deny"` 전용: 권한이 거부된 이유를 Claude에게 알립니다 |2112| `message` | `"deny"` 전용: 권한이 거부된 이유를 Claude에게 알립니다 |
2114| `interrupt` | `"deny"` 전용: `true`이면 Claude를 중지합니다 |2113| `interrupt` | `"deny"` 전용: `true`이면 Claude를 중지합니다 |
2115 2114
2133 권한 업데이트 항목2132 권한 업데이트 항목
2134</h4>2133</h4>
2135 2134
2136`updatedPermissions` 출력 필드와 [`permission_suggestions` 입력 필드](#permissionrequest-input)는 모두 같은 항목 객체 배열을 사용합니다. 각 항목에는 다른 필드를 결정하는 `type`과 변경 사항이 기록되는 위치를 제어하는 `destination`이 있습니다.2135`updatedPermissions` 출력 필드와 [`permission_suggestions` 입력 필드](#permissionrequest-input)는 모두 동일한 항목 객체 배열을 사용합니다. 각 항목에는 나머지 필드를 결정하는 `type`과 변경 사항이 기록되는 위치를 제어하는 `destination`이 있습니다.
2137 2136
2138| `type` | 필드 | 효과 |2137| `type` | 필드 | 효과 |
2139| :- | :- | :- |2138| :- | :- | :- |
2140| `addRules` | `rules`, `behavior`, `destination` | 권한 규칙을 추가합니다. `rules`는 `{toolName, ruleContent?}` 객체의 배열입니다. 도구 전체를 일치시키려면 `ruleContent`를 생략합니다. `behavior`는 `"allow"`, `"deny"` 또는 `"ask"`입니다 |2139| `addRules` | `rules`, `behavior`, `destination` | 권한 규칙을 추가합니다. `rules`는 `{toolName, ruleContent?}` 객체의 배열입니다. 도구 전체와 일치시키려면 `ruleContent`를 생략합니다. `behavior`는 `"allow"`, `"deny"` 또는 `"ask"`입니다 |
2141| `replaceRules` | `rules`, `behavior`, `destination` | `destination`에서 지정된 `behavior`의 모든 규칙을 제공된 `rules`로 대체합니다 |2140| `replaceRules` | `rules`, `behavior`, `destination` | `destination`에 있는 지정된 `behavior`의 모든 규칙을 제공된 `rules`로 대체합니다 |
2142| `removeRules` | `rules`, `behavior`, `destination` | 지정된 `behavior`의 일치하는 규칙을 제거합니다 |2141| `removeRules` | `rules`, `behavior`, `destination` | 지정된 `behavior`의 일치하는 규칙을 제거합니다 |
2143| `setMode` | `mode`, `destination` | 권한 모드를 변경합니다. 유효한 모드는 `default`, `auto`, `acceptEdits`, `dontAsk`, `bypassPermissions`, `plan`, 그리고 `default`의 별칭인 `manual`입니다 |2142| `setMode` | `mode`, `destination` | 권한 모드를 변경합니다. 유효한 모드는 `default`, `auto`, `acceptEdits`, `dontAsk`, `bypassPermissions`, `plan`, 그리고 `default`의 별칭인 `manual`입니다 |
2144| `addDirectories` | `directories`, `destination` | 작업 디렉터리를 추가합니다. `directories`는 경로 문자열의 배열입니다 |2143| `addDirectories` | `directories`, `destination` | 작업 디렉터리를 추가합니다. `directories`는 경로 문자열의 배열입니다 |
2145| `removeDirectories` | `directories`, `destination` | 작업 디렉터리를 제거합니다 |2144| `removeDirectories` | `directories`, `destination` | 작업 디렉터리를 제거합니다 |
2146 2145
2147<Note>2146<Note>
2148 `bypassPermissions`를 사용하는 `setMode`는 우회 모드를 이미 사용할 수 있는 상태로 세션을 시작한 경우에만 적용됩니다. 즉, `--dangerously-skip-permissions`, `--permission-mode bypassPermissions`, `--allow-dangerously-skip-permissions`를 사용했거나 [사용자 설정, `--settings` 또는 관리형 설정](/docs/ko/settings-reference#permissions-defaultmode)에 `permissions.defaultMode: "bypassPermissions"`가 있어야 합니다. 그렇지 않으면 업데이트는 아무 효과가 없습니다. [`permissions.disableBypassPermissionsMode`](/docs/ko/permissions#managed-settings)가 이 모드를 비활성화한 경우나 세션이 [제한 모드](/docs/ko/cli-reference#cli-flags)로 시작된 경우에도 업데이트는 아무 효과가 없습니다.2147 `bypassPermissions`를 사용하는 `setMode`는 우회 모드를 이미 사용할 수 있는 상태로 세션을 시작한 경우에만 적용됩니다. 즉, `--dangerously-skip-permissions`, `--permission-mode bypassPermissions`, `--allow-dangerously-skip-permissions`, 또는 [사용자 설정, `--settings` 또는 관리형 설정](/docs/ko/settings-reference#permissions-defaultmode)의 `permissions.defaultMode: "bypassPermissions"`가 필요합니다. 그렇지 않으면 업데이트는 아무 효과가 없습니다. [`permissions.disableBypassPermissionsMode`](/docs/ko/permissions#managed-settings)가 해당 모드를 비활성화한 경우나 세션이 [제한 모드](/docs/ko/cli-reference#cli-flags)로 시작된 경우에도 업데이트는 아무 효과가 없습니다.
2149 2148
2150 `bypassPermissions`는 `destination`과 관계없이 `defaultMode`로 저장되지 않습니다.2149 `bypassPermissions`는 `destination`과 관계없이 `defaultMode`로 저장되지 않습니다.
2151</Note>2150</Note>
2152 2151
2153모든 항목의 `destination` 필드는 변경 사항을 메모리에만 유지할지 설정 파일에 저장할지를 결정합니다.2152모든 항목의 `destination` 필드는 변경 사항이 메모리에만 유지될지 설정 파일에 저장될지를 결정합니다.
2154 2153
2155| `destination` | 기록 위치 |2154| `destination` | 기록 위치 |
2156| :- | :- |2155| :- | :- |
2157| `session` | 메모리에만 유지되며 세션이 끝나면 삭제됩니다 |2156| `session` | 메모리에만 유지되며 세션이 끝나면 폐기됨 |
2158| `localSettings` | `.claude/settings.local.json` |2157| `localSettings` | `.claude/settings.local.json` |
2159| `projectSettings` | `.claude/settings.json` |2158| `projectSettings` | `.claude/settings.json` |
2160| `userSettings` | `~/.claude/settings.json` |2159| `userSettings` | `~/.claude/settings.json` |
2167 2166
2168도구가 성공적으로 완료된 직후에 실행됩니다.2167도구가 성공적으로 완료된 직후에 실행됩니다.
2169 2168
2170도구 이름으로 매칭하며, PreToolUse와 같은 값을 사용합니다.2169도구 이름과 일치하며, 값은 PreToolUse와 동일합니다.
2171 2170
2172도구 이름이 적절한 필터가 아닐 때는 더 넓게 매칭합니다.2171도구 이름이 적절한 필터가 아닐 때는 더 넓게 일치시킬 수 있습니다.
2173 2172
2174* 어떤 도구든 성공적으로 완료된 후에 훅을 실행하려면 `matcher`를 생략하거나 `"*"`로 설정합니다. 그러면 훅이 직접 변경 내용을 파악할 수 있습니다. 예를 들어 `git status --porcelain`을 실행하면 `git diff`가 놓치는 추적되지 않는 파일도 나열됩니다. 실패한 도구 호출에 대해서는 같은 훅을 [PostToolUseFailure](#posttoolusefailure)에 추가합니다.2173* 어떤 도구든 성공적으로 완료된 후 훅을 실행하려면 `matcher`를 생략하거나 `"*"`로 설정합니다. 그러면 훅이 직접 무엇이 변경되었는지 파악할 수 있습니다. 예를 들어 `git status --porcelain`을 실행하면 `git diff`가 놓치는 추적되지 않은 파일도 나열됩니다. 실패한 도구 호출의 경우 동일한 훅을 [PostToolUseFailure](#posttoolusefailure)에 추가합니다.
2175* 무엇이 파일을 기록했든 특정 파일이 디스크에서 변경될 때 훅을 실행하려면 [FileChanged](#filechanged)를 사용합니다. `Bash` 명령이나 Claude Code 외부의 프로세스가 같은 파일을 다시 쓰는 경우, Claude Code는 `Edit|Write`에 매칭되는 `PostToolUse` 훅을 실행하지 않습니다.2174* 무엇이 파일을 기록했든 관계없이 특정 파일이 디스크에서 변경될 때 훅을 실행하려면 [FileChanged](#filechanged)를 사용합니다. `Bash` 명령이나 Claude Code 외부의 프로세스가 같은 파일을 다시 기록하는 경우, Claude Code는 `Edit|Write`와 일치하는 `PostToolUse` 훅을 실행하지 않습니다.
2176 2175
2177<h4 id="posttooluse-input">2176<h4 id="posttooluse-input">
2178 PostToolUse input2177 PostToolUse 입력
2179</h4>2178</h4>
2180 2179
2181`PostToolUse` 훅은 도구가 이미 성공적으로 실행된 후에 발생합니다. 입력에는 도구에 전송된 인수인 `tool_input`과 도구가 반환한 결과인 `tool_response`가 모두 포함됩니다. 두 필드의 정확한 스키마는 도구에 따라 다릅니다. 파일 도구의 `tool_input` 경로는 [PreToolUse](#pretooluse-input)와 같은 형식으로 전달됩니다. 즉, 항상 절대 경로이며 플랫폼 고유의 구분자를 사용하므로 Windows에서는 백슬래시가 사용됩니다. MCP 도구의 경우 입력에 [`mcp_server`](#pretooluse-input) 객체도 포함됩니다.2180`PostToolUse` 훅은 도구가 이미 성공적으로 실행된 후에 발생합니다. 입력에는 도구에 전송된 인수인 `tool_input`과 도구가 반환한 결과인 `tool_response`가 모두 포함됩니다. 두 필드의 정확한 스키마는 도구에 따라 다릅니다. 파일 도구의 `tool_input` 경로는 [PreToolUse](#pretooluse-input)와 동일한 형식으로 전달됩니다. 즉, 항상 절대 경로이며 플랫폼의 기본 구분자를 사용하므로 Windows에서는 백슬래시입니다. MCP 도구의 경우 입력에 [`mcp_server`](#pretooluse-input) 객체도 포함됩니다.
2182 2181
2183```json theme={null}2182```json theme={null}
2184{2183{
2203 2202
2204| 필드 | 설명 |2203| 필드 | 설명 |
2205| :- | :- |2204| :- | :- |
2206| `duration_ms` | 선택 사항입니다. 밀리초 단위의 도구 실행 시간입니다. 권한 프롬프트와 PreToolUse 훅에 소요된 시간은 제외됩니다 |2205| `duration_ms` | 선택 사항. 도구 실행 시간(밀리초)입니다. 권한 프롬프트와 PreToolUse 훅에서 소요된 시간은 제외됩니다 |
2207 2206
2208<h4 id="posttooluse-decision-control">2207<h4 id="posttooluse-decision-control">
2209 PostToolUse decision control2208 PostToolUse 결정 제어
2210</h4>2209</h4>
2211 2210
2212`PostToolUse` 훅은 도구 실행 후 Claude에 피드백을 제공할 수 있습니다. 모든 훅에서 사용할 수 있는 [JSON 출력 필드](#json-output) 외에도, 훅 스크립트는 다음과 같은 이벤트별 필드를 반환할 수 있습니다.2211`PostToolUse` 훅은 도구 실행 후 Claude에게 피드백을 제공할 수 있습니다. 모든 훅에서 사용할 수 있는 [JSON 출력 필드](#json-output) 외에도 훅 스크립트는 다음 이벤트별 필드를 반환할 수 있습니다.
2213 2212
2214| 필드 | 설명 |2213| 필드 | 설명 |
2215| :- | :- |2214| :- | :- |
2216| `decision` | `"block"`은 도구 결과 옆에 `reason`을 추가합니다. Claude는 여전히 원래 출력을 봅니다. 출력을 대체하려면 `updatedToolOutput`을 사용합니다 |2215| `decision` | `"block"`은 도구 결과 옆에 `reason`을 추가합니다. Claude는 여전히 원래 출력을 봅니다. 출력을 대체하려면 `updatedToolOutput`을 사용합니다 |
2217| `reason` | `decision`이 `"block"`일 때 Claude에 표시되는 설명입니다 |2216| `reason` | `decision`이 `"block"`일 때 Claude에게 표시되는 설명 |
2218| `additionalContext` | 도구 결과와 함께 Claude의 컨텍스트에 추가되는 문자열입니다. [Claude에 컨텍스트 추가](#add-context-for-claude)를 참조하세요 |2217| `additionalContext` | 도구 결과와 함께 Claude의 컨텍스트에 추가되는 문자열. [Claude를 위한 컨텍스트 추가](#add-context-for-claude)를 참조하세요 |
2219| `classifierContext` | Claude가 아닌 [자동 모드](/docs/ko/permission-modes#eliminate-prompts-with-auto-mode) 분류기를 위한, 이 호출의 결과에 대한 짧은 메모입니다. [자동 모드 분류기를 위해 결과에 주석 달기](#annotate-a-result-for-the-auto-mode-classifier)를 참조하세요. Claude Code v2.1.236 이상이 필요합니다 |2218| `classifierContext` | Claude가 아닌 [자동 모드](/docs/ko/permission-modes#eliminate-prompts-with-auto-mode) 분류기를 위한, 이 호출의 결과에 관한 짧은 메모. [자동 모드 분류기를 위한 결과 주석 달기](#annotate-a-result-for-the-auto-mode-classifier)를 참조하세요. Claude Code v2.1.236 이상이 필요합니다 |
2220| `updatedToolOutput` | 도구의 출력이 Claude에 전송되기 전에 제공된 값으로 대체합니다. 값은 도구의 출력 형태와 일치해야 합니다 |2219| `updatedToolOutput` | Claude에게 전송되기 전에 도구의 출력을 제공된 값으로 대체합니다. 값은 도구의 출력 형태와 일치해야 합니다 |
2221| `updatedMCPToolOutput` | [MCP 도구](#match-mcp-tools)의 출력만 대체합니다. 모든 도구에서 작동하는 `updatedToolOutput`을 사용하는 것이 좋습니다 |2220| `updatedMCPToolOutput` | [MCP 도구](#match-mcp-tools)에 대해서만 출력을 대체합니다. 모든 도구에서 작동하는 `updatedToolOutput`을 사용하는 것이 좋습니다 |
2222 2221
2223아래 예시는 `Bash` 호출의 출력을 대체합니다. 대체 값은 `Bash` 도구의 출력 형태와 일치합니다.2222아래 예시는 `Bash` 호출의 출력을 대체합니다. 대체 값은 `Bash` 도구의 출력 형태와 일치합니다.
2224 2223
2238```2237```
2239 2238
2240<Warning>2239<Warning>
2241 `updatedToolOutput`은 Claude가 보는 내용만 변경합니다. 훅이 발생할 때는 도구가 이미 실행된 상태이므로, 기록된 파일, 실행된 명령, 전송된 네트워크 요청은 이미 적용되었습니다. OpenTelemetry 도구 스팬이나 분석 이벤트와 같은 텔레메트리도 훅이 실행되기 전에 원래 출력을 수집합니다. 도구 호출이 실행되기 전에 이를 차단하거나 수정하려면 대신 [PreToolUse](#pretooluse) 훅을 사용합니다.2240 `updatedToolOutput`은 Claude가 보는 내용만 변경합니다. 훅이 발생할 때는 도구가 이미 실행된 상태이므로, 기록된 파일, 실행된 명령, 전송된 네트워크 요청은 이미 적용되었습니다. OpenTelemetry 도구 스팬 및 분석 이벤트와 같은 텔레메트리도 훅이 실행되기 전에 원래 출력을 캡처합니다. 도구 호출이 실행되기 전에 이를 방지하거나 수정하려면 대신 [PreToolUse](#pretooluse) 훅을 사용하세요.
2242 2241
2243 대체 값은 도구의 출력 형태와 일치해야 합니다. 기본 제공 도구는 일반 문자열이 아닌 구조화된 객체를 반환합니다. 예를 들어 `Bash`는 `stdout`, `stderr`, `interrupted`, `isImage` 필드가 있는 객체를 반환합니다. 기본 제공 도구의 경우 도구의 출력 스키마와 일치하지 않는 값은 무시되고 원래 출력이 사용됩니다. MCP 도구 출력은 스키마 검증 없이 그대로 전달됩니다. Claude에 필요한 오류 세부 정보를 제거하면 Claude가 잘못된 가정에 따라 작업을 진행할 수 있습니다.2242 대체 값은 도구의 출력 형태와 일치해야 합니다. 기본 제공 도구는 일반 문자열이 아닌 구조화된 객체를 반환합니다. 예를 들어 `Bash`는 `stdout`, `stderr`, `interrupted`, `isImage` 필드가 있는 객체를 반환합니다. 기본 제공 도구의 경우 도구의 출력 스키마와 일치하지 않는 값은 무시되고 원래 출력이 사용됩니다. MCP 도구 출력은 스키마 검증 없이 그대로 전달됩니다. Claude에게 필요한 오류 세부 정보를 제거하면 Claude가 잘못된 가정에 따라 작업을 진행할 수 있습니다.
2244</Warning>2243</Warning>
2245 2244
2246<h4 id="annotate-a-result-for-the-auto-mode-classifier">2245<h4 id="annotate-a-result-for-the-auto-mode-classifier">
2247 Annotate a result for the auto mode classifier2246 자동 모드 분류기를 위한 결과 주석 달기
2248</h4>2247</h4>
2249 2248
2250`classifierContext`를 반환하면 도구 호출 결과에 대한 짧은 메모를 Claude가 아닌 [자동 모드](/docs/ko/permission-modes#eliminate-prompts-with-auto-mode) 분류기에 보낼 수 있습니다. 분류기는 [도구 결과 자체를 전달받지 않으므로](/docs/ko/permission-modes#how-the-classifier-evaluates-actions), 이 필드는 분류기가 이후 작업을 검토하기 전에 호출이 반환한 내용에 대해 알려 주는 공식적인 방법입니다. 이 필드에는 Claude Code v2.1.236 이상이 필요합니다.2249`classifierContext`를 반환하면 도구 호출 결과에 관한 짧은 메모를 Claude가 아닌 [자동 모드](/docs/ko/permission-modes#eliminate-prompts-with-auto-mode) 분류기에 보낼 수 있습니다. 분류기는 [도구 결과 자체를 받지 않으므로](/docs/ko/permission-modes#how-the-classifier-evaluates-actions), 이 필드는 분류기가 이후 작업을 검토하기 전에 호출이 반환한 내용에 관해 알려 줄 수 있는 공식적인 방법입니다. 이 필드는 Claude Code v2.1.236 이상이 필요합니다.
2251 2250
2252아래 예시는 쿼리 출력의 출처를 분류기에 알려 줍니다.2251아래 예시는 쿼리 출력의 출처를 분류기에 알려 줍니다.
2253 2252
2260}2259}
2261```2260```
2262 2261
2263분류기가 메모에 부여하는 비중은 훅을 구성한 위치에 따라 달라집니다.2262분류기가 메모에 부여하는 가중치는 훅을 구성한 위치에 따라 달라집니다.
2264 2263
2265* **Claude Code에서 구성된 훅**: 설정 파일, 플러그인, 스킬, 에이전트 frontmatter의 훅에 대해 분류기는 메모를 검증되지 않은, 애플리케이션이 제공한 컨텍스트로 취급합니다. 메모는 사용자 의도를 확립하지 않으며, 메모가 사용자가 무언가를 승인했거나 요청했다고 주장하면 분류기는 그 주장을 대화 속 사용자의 실제 메시지와 대조합니다2264* **Claude Code에서 구성한 훅**: 설정 파일, 플러그인, 스킬, 에이전트 frontmatter의 훅의 경우 분류기는 메모를 검증되지 않은, 애플리케이션이 제공한 컨텍스트로 취급합니다. 메모는 사용자 의도를 확립하지 않으며, 사용자가 무언가를 승인하거나 요청했다고 주장하는 경우 분류기는 그 주장을 대화 내 사용자 본인의 메시지와 대조하여 확인합니다
2266* **프로세스 내 Agent SDK 콜백**: Claude Code를 내장한 애플리케이션이 훅을 [TypeScript SDK 콜백](/docs/ko/agent-sdk/hooks)으로 등록하고 라이브 세션 중에 메모를 반환하면, 분류기는 메모에 전달된 사용자 진술을 사용자 의도로 고려할 수 있습니다. 이러한 진술은 분류기가 사용자가 보낸 메시지로부터 받아들일 동의 요건을 충족할 수 있지만, 사용자 자신의 메시지로도 해제할 수 없는 차단을 해제하지는 못합니다. 세션이 재개된 후에는 Claude Code가 복원된 메모를 검증되지 않은 컨텍스트로 취급합니다. 두 그룹의 훅이 같은 호출에 주석을 달면 분류기는 결합된 메모를 검증되지 않은 것으로 취급합니다2265* **인프로세스 Agent SDK 콜백**: Claude Code를 내장한 애플리케이션이 훅을 [TypeScript SDK 콜백](/docs/ko/agent-sdk/hooks)으로 등록하고 라이브 세션 중에 메모를 반환하는 경우, 분류기는 메모에 전달된 사용자 진술을 사용자 의도로 간주할 수 있습니다. 이러한 진술은 사용자가 보낸 메시지로 분류기가 인정하는 동의 요건을 충족할 수 있지만, 사용자 본인의 메시지로도 해제할 수 없는 차단은 해제하지 못합니다. 세션이 재개된 후에는 Claude Code가 복원된 메모를 검증되지 않은 컨텍스트로 취급합니다. 두 그룹의 훅이 모두 같은 호출에 주석을 다는 경우 분류기는 결합된 메모를 검증되지 않은 것으로 취급합니다
2267 2266
2268Claude Code는 메모를 전달할 때 다음 제한을 적용합니다.2267Claude Code는 메모를 전달할 때 다음 제한을 적용합니다.
2269 2268
2270* **길이**: Claude Code는 하나의 도구 호출에 대한 메모를 2,000자로 제한하고 나머지는 잘라 냅니다. 이 한도는 해당 호출에 응답하는 모든 훅이 공유합니다2269* **길이**: Claude Code는 하나의 도구 호출에 대한 메모를 2,000자로 제한하고 나머지는 잘라냅니다. 이 제한은 해당 호출에 응답하는 모든 훅이 공유합니다
2271* **동기 응답만 해당**: [백그라운드에서 실행되는](#run-hooks-in-the-background) 훅의 응답에 있는 이 필드는 무시됩니다. 해당 응답은 Claude Code가 도구 결과를 기록한 후에 도착하기 때문입니다2270* **동기 응답만 해당**: [백그라운드에서 실행되는](#run-hooks-in-the-background) 훅의 응답은 Claude Code가 도구 결과를 기록한 후에 도착하므로, Claude Code는 해당 응답의 이 필드를 무시합니다
2272* **분류기가 기록하지 않는 호출**: 분류기의 트랜스크립트에는 파일 읽기나 검색 같은 읽기 전용 조회가 포함되지 않습니다. Claude Code는 이러한 호출에 첨부된 메모를 삭제합니다2271* **분류기가 기록하지 않는 호출**: 분류기의 트랜스크립트는 파일 읽기 및 검색과 같은 읽기 전용 조회를 생략합니다. Claude Code는 이러한 호출에 첨부된 메모를 폐기합니다
2273* **재작성과의 상호작용**: 메모가 `updatedToolOutput`으로 대체하는 출력을 설명하는 경우, 같은 훅 응답에서 두 필드를 모두 반환합니다. 해당 재작성이 거부되거나 다른 훅의 재작성이 이를 대체하면 Claude Code는 메모를 삭제합니다. 재작성 없이 반환한 메모는 다른 훅이 출력을 재작성하더라도 Claude Code가 전달합니다2272* **재작성과의 상호 작용**: 메모가 `updatedToolOutput`으로 대체하는 출력을 설명하는 경우, 같은 훅 응답에서 두 필드를 모두 반환합니다. 해당 재작성이 거부되거나 다른 훅의 재작성이 이를 대체하면 Claude Code는 메모를 삭제합니다. 재작성 없이 반환한 메모는 다른 훅이 출력을 재작성하더라도 Claude Code가 전달합니다
2274 2273
2275<Warning>2274<Warning>
2276 분류기는 `classifierContext`에 넣은 내용을 세션을 호스팅하는 애플리케이션의 정보로 읽으므로, 신뢰할 수 없는 도구 출력이나 서드파티 텍스트를 여기에 복사하지 마세요. 메모는 출처에 관한 사실이나 이에 대한 사용자 진술처럼 해당 호출 하나에 대한 짧은 주장으로 유지하고, 관련 없는 메시지나 일련의 이벤트를 전달하는 데 이 필드를 사용하지 마세요.2275 분류기는 `classifierContext`에 넣은 내용을 세션을 호스팅하는 애플리케이션의 정보로 읽으므로, 신뢰할 수 없는 도구 출력이나 제3자 텍스트를 복사해 넣지 마세요. 메모는 출처에 관한 사실이나 해당 호출에 관한 사용자 진술처럼 이 호출 하나에 대한 짧은 주장으로 유지하세요. 이 필드를 관련 없는 메시지나 이벤트 스트림을 전달하는 데 사용하지 마세요.
2277</Warning>2276</Warning>
2278 2277
2279<h3 id="posttoolusefailure">2278<h3 id="posttoolusefailure">
2280 PostToolUseFailure2279 PostToolUseFailure
2281</h3>2280</h3>
2282 2281
2283실행을 시작한 도구가 실패할 때 실행됩니다. 즉, 도구가 오류를 발생시켰거나 MCP 도구가 오류 결과를 반환한 경우입니다. 실패를 로그에 기록하거나, 알림을 보내거나, Claude에 수정 피드백을 제공하는 데 사용합니다.2282실행을 시작한 도구가 실패할 때 실행됩니다. 즉, 도구가 오류를 발생시켰거나 MCP 도구가 오류 결과를 반환한 경우입니다. 실패를 로그에 기록하거나, 알림을 보내거나, Claude에게 수정 피드백을 제공하는 데 사용합니다.
2284 2283
2285도구 이름으로 매칭하며, PreToolUse와 같은 값을 사용합니다.2284도구 이름과 일치하며, 값은 PreToolUse와 동일합니다.
2286 2285
2287<Note>2286<Note>
2288 이 이벤트는 실행 전에 거부된 도구 호출에 대해서는 발생하지 않습니다. 알 수 없는 도구 이름, 스키마 또는 도구별 검증에 실패한 입력, 권한 거부가 여기에 해당합니다. 검증 거부는 `tool_use_error` 결과로 반환되며 훅이 실행되기 전에 발생하므로, `PreToolUse`와 `PostToolUseFailure` 모두 발생하지 않습니다. 권한 거부는 `PreToolUse`를 발생시키지만 이 이벤트는 발생시키지 않습니다. [PermissionDenied](#permissiondenied)를 참조하세요.2287 이 이벤트는 실행 전에 거부된 도구 호출에는 발생하지 않습니다. 예를 들어 알 수 없는 도구 이름, 스키마 또는 도구별 검증에 실패한 입력, 권한 거부가 해당합니다. 검증 거부는 `tool_use_error` 결과로 반환되며 훅이 실행되기 전에 발생하므로 `PreToolUse`와 `PostToolUseFailure` 모두 발생하지 않습니다. 권한 거부는 `PreToolUse`는 발생시키지만 이 이벤트는 발생시키지 않습니다. [PermissionDenied](#permissiondenied)를 참조하세요.
2289</Note>2288</Note>
2290 2289
2291<h4 id="posttoolusefailure-input">2290<h4 id="posttoolusefailure-input">
2292 PostToolUseFailure input2291 PostToolUseFailure 입력
2293</h4>2292</h4>
2294 2293
2295PostToolUseFailure 훅은 PostToolUse와 같은 `tool_name` 및 `tool_input` 필드를 전달받으며, 오류 정보는 최상위 필드로 함께 전달받습니다. MCP 도구의 경우 [`mcp_server`](#pretooluse-input) 객체도 전달받습니다. 예를 들어 실패한 `npm test` 명령은 다음을 전달할 수 있습니다.2294PostToolUseFailure 훅은 PostToolUse와 동일한 `tool_name` 및 `tool_input` 필드와 함께 최상위 필드로 오류 정보를 받습니다. MCP 도구의 경우 [`mcp_server`](#pretooluse-input) 객체도 받습니다. 예를 들어 실패한 `npm test` 명령은 다음을 전달할 수 있습니다.
2296 2295
2297```json theme={null}2296```json theme={null}
2298{2297{
2315 2314
2316| 필드 | 설명 |2315| 필드 | 설명 |
2317| :- | :- |2316| :- | :- |
2318| `error` | 무엇이 잘못되었는지 설명하는 문자열입니다. 형식은 실패한 도구에 따라 다릅니다 |2317| `error` | 무엇이 잘못되었는지 설명하는 문자열. 형식은 실패한 도구에 따라 다릅니다 |
2319| `is_interrupt` | 선택적 불리언입니다. 실패가 도구가 보고한 오류가 아닌 중단(abort)으로 Claude Code에 도달한 경우 true입니다. 실행 중인 도구를 취소해도 이 훅은 발생하지 않으며, 대신 도구 결과에 중단 메시지가 포함됩니다 |2318| `is_interrupt` | 선택적 boolean. 실패가 도구가 보고한 오류가 아니라 중단(abort)으로 Claude Code에 도달한 경우 true입니다. 실행 중인 도구를 취소하면 이 훅이 발생하지 않으며, 대신 도구 결과에 중단 메시지가 포함됩니다 |
2320| `duration_ms` | 선택 사항입니다. 밀리초 단위의 도구 실행 시간입니다. 권한 프롬프트와 PreToolUse 훅에 소요된 시간은 제외됩니다 |2319| `duration_ms` | 선택 사항. 도구 실행 시간(밀리초)입니다. 권한 프롬프트와 PreToolUse 훅에서 소요된 시간은 제외됩니다 |
2321 2320
2322`error` 문자열은 일반적으로 Claude가 실패한 도구의 결과로 받는 텍스트와 같습니다. 형식은 도구와 실패 유형에 따라 다릅니다. 훅은 `tool_name`, `is_interrupt`, 그리고 첫 줄의 `Exit code N`을 기준으로 판단하고, 문자열의 나머지 부분은 안정적인 형식이 아닌 표시용 텍스트로 취급합니다.2321`error` 문자열은 일반적으로 Claude가 실패한 도구의 결과로 받는 텍스트와 동일합니다. 형식은 도구와 실패 유형에 따라 다릅니다. 훅의 판단 기준은 `tool_name`, `is_interrupt`, 그리고 첫 줄의 `Exit code N`으로 삼고, 문자열의 나머지 부분은 안정적인 형식이 아닌 표시용 텍스트로 취급하세요.
2323 2322
2324* Bash와 PowerShell의 경우, 실행 후 종료된 명령은 첫 줄에 `Exit code N`을 생성하고, 이어서 명령이 생성한 출력을 stdout과 stderr가 섞인 하나의 블록으로 생성합니다2323* Bash와 PowerShell의 경우, 실행되어 종료된 명령은 첫 줄에 `Exit code N`을 생성하고, 그다음에 명령이 생성한 출력이 stdout과 stderr가 섞인 하나의 블록으로 이어집니다
2325* Claude Code가 셸 프로세스 자체를 시작할 수 없었던 경우, 페이로드에 종료 코드 줄 없이 실패 메시지만 포함될 수도 있습니다2324* Claude Code가 셸 프로세스 자체를 시작할 수 없었던 경우, 페이로드에 종료 코드 줄 없이 실패 메시지만 포함될 수도 있습니다
2326* Claude Code는 긴 문자열의 가운데를 `... [N characters truncated] ...` 마커를 기준으로 잘라 내며, `Command timed out after 2m 0s`와 같은 자체 줄을 삽입할 수 있습니다2325* Claude Code는 긴 문자열의 중간을 `... [N characters truncated] ...` 마커를 중심으로 잘라내며, `Command timed out after 2m 0s`와 같은 자체 줄을 삽입할 수 있습니다
2327 2326
2328<h4 id="posttoolusefailure-decision-control">2327<h4 id="posttoolusefailure-decision-control">
2329 PostToolUseFailure decision control2328 PostToolUseFailure 결정 제어
2330</h4>2329</h4>
2331 2330
2332`PostToolUseFailure` 훅은 도구 실패 후 Claude에 컨텍스트를 제공할 수 있습니다. 모든 훅에서 사용할 수 있는 [JSON 출력 필드](#json-output) 외에도, 훅 스크립트는 다음과 같은 이벤트별 필드를 반환할 수 있습니다.2331`PostToolUseFailure` 훅은 도구 실패 후 Claude에게 컨텍스트를 제공할 수 있습니다. 모든 훅에서 사용할 수 있는 [JSON 출력 필드](#json-output) 외에도 훅 스크립트는 다음 이벤트별 필드를 반환할 수 있습니다.
2333 2332
2334| 필드 | 설명 |2333| 필드 | 설명 |
2335| :- | :- |2334| :- | :- |
2336| `additionalContext` | 오류와 함께 Claude의 컨텍스트에 추가되는 문자열입니다. [Claude에 컨텍스트 추가](#add-context-for-claude)를 참조하세요 |2335| `additionalContext` | 오류와 함께 Claude의 컨텍스트에 추가되는 문자열. [Claude를 위한 컨텍스트 추가](#add-context-for-claude)를 참조하세요 |
2337 2336
2338```json theme={null}2337```json theme={null}
2339{2338{
2348 PostToolBatch2347 PostToolBatch
2349</h3>2348</h3>
2350 2349
2351배치의 모든 도구 호출이 처리된 후, Claude Code가 모델에 다음 요청을 보내기 전에 한 번 실행됩니다. `PostToolUse`는 도구마다 한 번씩 발생하므로, Claude가 병렬 도구 호출을 하면 동시에 발생합니다. `PostToolBatch`는 전체 배치에 대해 정확히 한 번 발생하므로, 단일 도구가 아닌 실행된 도구 집합에 따라 달라지는 컨텍스트를 주입하기에 적합합니다. 이 이벤트에는 matcher가 없습니다.2350배치의 모든 도구 호출이 처리된 후, Claude Code가 모델에 다음 요청을 보내기 전에 한 번 실행됩니다. `PostToolUse`는 도구마다 한 번씩 발생하므로, Claude가 병렬 도구 호출을 하면 동시에 발생합니다. `PostToolBatch`는 전체 배치에 대해 정확히 한 번 발생하므로, 단일 도구가 아닌 실행된 도구 집합에 따라 달라지는 컨텍스트를 주입하기에 적합한 위치입니다. 이 이벤트에는 matcher가 없습니다.
2352 2351
2353<h4 id="posttoolbatch-input">2352<h4 id="posttoolbatch-input">
2354 PostToolBatch input2353 PostToolBatch 입력
2355</h4>2354</h4>
2356 2355
2357[공통 입력 필드](#common-input-fields) 외에도, PostToolBatch 훅은 배치의 모든 도구 호출을 설명하는 배열인 `tool_calls`를 전달받습니다.2356[공통 입력 필드](#common-input-fields) 외에도 PostToolBatch 훅은 배치의 모든 도구 호출을 설명하는 배열인 `tool_calls`를 받습니다.
2358 2357
2359```json theme={null}2358```json theme={null}
2360{2359{
2380}2379}
2381```2380```
2382 2381
2383`tool_response`에는 모델이 해당 `tool_result` 블록에서 받는 것과 같은 내용이 포함됩니다. 값은 도구가 내보낸 그대로의 직렬화된 문자열 또는 콘텐츠 블록 배열입니다. `Read`의 경우 원시 파일 내용이 아니라 줄 번호가 앞에 붙은 텍스트를 의미합니다. 응답이 클 수 있으므로 필요한 필드만 파싱합니다.2382`tool_response`에는 모델이 해당 `tool_result` 블록에서 받는 것과 동일한 내용이 포함됩니다. 값은 도구가 내보낸 그대로의 직렬화된 문자열 또는 콘텐츠 블록 배열입니다. `Read`의 경우 원시 파일 내용이 아니라 줄 번호가 앞에 붙은 텍스트를 의미합니다. 응답이 클 수 있으므로 필요한 필드만 파싱하세요.
2384 2383
2385<Note>2384<Note>
2386 `tool_response`의 형태는 `PostToolUse`의 것과 다릅니다. `PostToolUse`는 `Write`의 `{filePath: "...", type: "create"}`와 같은 도구의 구조화된 `Output` 객체를 전달하고, `PostToolBatch`는 모델이 보는 직렬화된 `tool_result` 내용을 전달합니다.2385 `tool_response`의 형태는 `PostToolUse`의 것과 다릅니다. `PostToolUse`는 `Write`의 경우 `{filePath: "...", type: "create"}`와 같은 도구의 구조화된 `Output` 객체를 전달하고, `PostToolBatch`는 모델이 보는 직렬화된 `tool_result` 콘텐츠를 전달합니다.
2387</Note>2386</Note>
2388 2387
2389<h4 id="posttoolbatch-decision-control">2388<h4 id="posttoolbatch-decision-control">
2390 PostToolBatch decision control2389 PostToolBatch 결정 제어
2391</h4>2390</h4>
2392 2391
2393`PostToolBatch` 훅은 Claude를 위한 컨텍스트를 주입할 수 있습니다. 모든 훅에서 사용할 수 있는 [JSON 출력 필드](#json-output) 외에도, 훅 스크립트는 다음과 같은 이벤트별 필드를 반환할 수 있습니다.2392`PostToolBatch` 훅은 Claude를 위한 컨텍스트를 주입할 수 있습니다. 모든 훅에서 사용할 수 있는 [JSON 출력 필드](#json-output) 외에도 훅 스크립트는 다음 이벤트별 필드를 반환할 수 있습니다.
2394 2393
2395| 필드 | 설명 |2394| 필드 | 설명 |
2396| :- | :- |2395| :- | :- |
2397| `additionalContext` | 다음 모델 호출 전에 한 번 주입되는 컨텍스트 문자열입니다. 전달 세부 사항, 포함할 내용, 재개된 세션이 이전 값을 처리하는 방식은 [Claude에 컨텍스트 추가](#add-context-for-claude)를 참조하세요 |2396| `additionalContext` | 다음 모델 호출 전에 한 번 주입되는 컨텍스트 문자열. 전달 방식, 넣을 내용, 재개된 세션이 이전 값을 처리하는 방식은 [Claude를 위한 컨텍스트 추가](#add-context-for-claude)를 참조하세요 |
2398 2397
2399```json theme={null}2398```json theme={null}
2400{2399{
2405}2404}
2406```2405```
2407 2406
2408`decision: "block"` 또는 `continue: false`를 반환하면 다음 모델 호출 전에 에이전틱 루프가 중지됩니다. 차단 메시지는 JSON의 `reason` 또는 `stopReason`에서, 또는 종료 코드 2의 경우 stderr에서 가져옵니다. 이 메시지는 트랜스크립트에 경고로 표시되며 대화에 남아 있으므로, 대화가 계속되면 Claude가 이를 보게 됩니다.2407`decision: "block"` 또는 `continue: false`를 반환하면 다음 모델 호출 전에 에이전틱 루프가 중지됩니다. 차단 메시지는 JSON의 `reason` 또는 `stopReason`, 또는 종료 코드 2일 때의 stderr에서 가져옵니다. 이 메시지는 트랜스크립트에 경고로 표시되며 대화에 남으므로, 대화가 계속될 때 Claude가 이를 보게 됩니다.
2409 2408
2410<h3 id="permissiondenied">2409<h3 id="permissiondenied">
2411 PermissionDenied2410 PermissionDenied
2412</h3>2411</h3>
2413 2412
2414[자동 모드](/docs/ko/permission-modes#eliminate-prompts-with-auto-mode)가 도구 호출을 거부할 때 실행됩니다. [자동 모드와 별개인 안전 검사가 분류기 자체의 요청을 거부](/docs/ko/errors#auto-mode-cannot-determine-the-safety-of-an-action)했거나 분류기의 응답을 파싱할 수 없어서 분류기 판정 없이 거부하는 경우도 포함됩니다. 이 훅은 자동 모드에서만 발생합니다. 사용자가 권한 대화 상자를 수동으로 거부하거나, `PreToolUse` 훅이 호출을 차단하거나, `deny` 규칙이 매칭되는 경우에는 실행되지 않습니다. 거부를 로그에 기록하거나, 구성을 조정하거나, 모델에 도구 호출을 재시도해도 된다고 알리는 데 사용합니다.2413[자동 모드](/docs/ko/permission-modes#eliminate-prompts-with-auto-mode)가 도구 호출을 거부할 때 실행됩니다. 여기에는 [자동 모드와 별개인 안전 검사가 분류기 자체의 요청을 거부](/docs/ko/errors#auto-mode-cannot-determine-the-safety-of-an-action)했거나 분류기 응답을 파싱할 수 없어서 분류기 판정 없이 거부하는 경우도 포함됩니다. 이 훅은 자동 모드에서만 발생합니다. 사용자가 권한 대화 상자에서 직접 거부하거나, `PreToolUse` 훅이 호출을 차단하거나, `deny` 규칙이 일치하는 경우에는 실행되지 않습니다. 거부를 로그에 기록하거나, 구성을 조정하거나, 모델에게 도구 호출을 재시도해도 된다고 알리는 데 사용합니다.
2415 2414
2416도구 이름으로 매칭하며, PreToolUse와 같은 값을 사용합니다.2415도구 이름과 일치하며, 값은 PreToolUse와 동일합니다.
2417 2416
2418<h4 id="permissiondenied-input">2417<h4 id="permissiondenied-input">
2419 PermissionDenied input2418 PermissionDenied 입력
2420</h4>2419</h4>
2421 2420
2422[공통 입력 필드](#common-input-fields) 외에도, PermissionDenied 훅은 `tool_name`, `tool_input`, `tool_use_id`, `reason`을 전달받습니다. MCP 도구의 경우 [`mcp_server`](#pretooluse-input) 객체도 전달받습니다.2421[공통 입력 필드](#common-input-fields) 외에도 PermissionDenied 훅은 `tool_name`, `tool_input`, `tool_use_id`, `reason`을 받습니다. MCP 도구의 경우 [`mcp_server`](#pretooluse-input) 객체도 받습니다.
2423 2422
2424```json theme={null}2423```json theme={null}
2425{2424{
2440 2439
2441| 필드 | 설명 |2440| 필드 | 설명 |
2442| :- | :- |2441| :- | :- |
2443| `reason` | 거부 사유입니다. 분류기 판정의 경우 대부분의 세션에서 `[Data Exfiltration]`처럼 매칭된 규칙을 대괄호 안에 표시합니다. 다른 형식은 [거부 검토](/docs/ko/auto-mode-config#review-denials)를 참조하세요. [판정 없는 거부](#permissiondenied-decision-control)의 경우 `Auto mode could not evaluate this action and is blocking it for safety`로 시작합니다. 분류기 모델을 사용할 수 없어서 거부된 경우 고정 텍스트 `Classifier unavailable`입니다 |2442| `reason` | 거부 사유. 분류기 판정의 경우 대부분의 세션에서 `[Data Exfiltration]`과 같이 일치한 규칙 이름을 대괄호로 표시합니다. 다른 형식은 [거부 검토](/docs/ko/auto-mode-config#review-denials)를 참조하세요. [판정 없는 거부](#permissiondenied-decision-control)의 경우 `Auto mode could not evaluate this action and is blocking it for safety`로 시작합니다. 분류기 모델을 사용할 수 없어서 거부된 경우 고정 텍스트 `Classifier unavailable`입니다 |
2444 2443
2445<h4 id="permissiondenied-decision-control">2444<h4 id="permissiondenied-decision-control">
2446 PermissionDenied decision control2445 PermissionDenied 결정 제어
2447</h4>2446</h4>
2448 2447
2449PermissionDenied 훅은 거부된 도구 호출을 모델이 재시도해도 된다고 알릴 수 있습니다. `hookSpecificOutput.retry`를 `true`로 설정한 JSON 객체를 반환합니다.2448PermissionDenied 훅은 모델에게 거부된 도구 호출을 재시도해도 된다고 알릴 수 있습니다. `hookSpecificOutput.retry`를 `true`로 설정한 JSON 객체를 반환합니다.
2450 2449
2451```json theme={null}2450```json theme={null}
2452{2451{
2457}2456}
2458```2457```
2459 2458
2460`retry`가 `true`이면 Claude Code는 모델에 도구 호출을 재시도해도 된다고 알리는 메시지를 대화에 추가합니다. Claude Code가 거부 자체를 취소하지는 않습니다. 훅이 JSON을 반환하지 않거나 `retry: false`를 반환하면 거부가 유지되고 모델은 원래의 거부 메시지를 받습니다.2459`retry`가 `true`이면 Claude Code는 모델에게 도구 호출을 재시도해도 된다고 알리는 메시지를 대화에 추가합니다. Claude Code가 거부 자체를 번복하지는 않습니다. 훅이 JSON을 반환하지 않거나 `retry: false`를 반환하면 거부가 유지되고 모델은 원래 거부 메시지를 받습니다.
2461 2460
2462분류기가 [해당 작업에 대해 판정을 내리지 못한](/docs/ko/errors#auto-mode-cannot-determine-the-safety-of-an-action) 경우, 즉 응답을 파싱할 수 없었거나 자동 모드와 별개인 안전 검사가 분류기 자체의 요청을 거부한 경우에는 Claude Code가 `retry: true`를 무시합니다. 이러한 거부에 대해서는 Claude Code가 이미 거부 메시지에서 나중에 재시도할지 아니면 다른 작업으로 넘어갈지를 모델에 알려 줍니다.2461분류기가 [작업에 대한 판정을 내리지 못한](/docs/ko/errors#auto-mode-cannot-determine-the-safety-of-an-action) 경우, 즉 분류기 응답을 파싱할 수 없거나 자동 모드와 별개인 안전 검사가 분류기 자체의 요청을 거부한 경우, Claude Code는 `retry: true`를 무시합니다. 이러한 거부의 경우 Claude Code가 이미 거부 메시지에서 나중에 재시도할지 다음으로 넘어갈지를 모델에게 알려 줍니다.
2463 2462
2464<h3 id="notification">2463<h3 id="notification">
2465 Notification2464 Notification
2466</h3>2465</h3>
2467 2466
2468Claude Code가 알림을 보낼 때 실행됩니다. 알림 유형으로 매칭합니다. 모든 알림 유형에 대해 훅을 실행하려면 matcher를 생략합니다.2467Claude Code가 알림을 보낼 때 실행됩니다. 알림 유형과 일치합니다. 모든 알림 유형에 대해 훅을 실행하려면 matcher를 생략합니다.
2469 2468
2470데스크톱 알림을 꺼 두어도 이러한 훅 이벤트는 전달됩니다. `notifications_disabled`를 포함한 `preferredNotifChannel` 설정은 사용자에게 알리는 방식만 바꿀 뿐, 훅 실행 여부에는 영향을 주지 않습니다.2469데스크톱 알림을 꺼 두어도 이 훅 이벤트는 수신됩니다. `notifications_disabled`를 포함한 `preferredNotifChannel` 설정은 알림을 받는 방식만 변경할 뿐, 훅의 실행 여부에는 영향을 주지 않습니다.
2471 2470
2472| Matcher | 발생 시점 |2471| Matcher | 발생 시점 |
2473| :- | :- |2472| :- | :- |
2474| `permission_prompt` | Claude가 도구 사용 또는 샌드박스 처리된 명령의 [네트워크 요청](/docs/ko/sandboxing#network-isolation)에 대한 사용자 승인을 필요로 하며, 프롬프트가 약 6초 동안 대기한 경우 |2473| `permission_prompt` | Claude가 도구 사용 또는 샌드박스 처리된 명령의 [네트워크 요청](/docs/ko/sandboxing#network-isolation)에 대한 승인을 필요로 하고, 프롬프트가 약 6초 동안 대기한 경우 |
2475| `idle_prompt` | Claude가 약 60초 전에 응답을 마쳤고 그 이후 사용자가 입력하지 않은 경우 |2474| `idle_prompt` | Claude가 약 60초 전에 응답을 마쳤고 그 이후로 입력하지 않은 경우 |
2476| `auth_success` | 인증이 완료된 경우 |2475| `auth_success` | 인증이 완료된 경우 |
2477| `elicitation_dialog` | MCP 서버가 elicitation 양식을 열었고 사용자가 약 6초 동안 입력하지 않은 경우 |2476| `elicitation_dialog` | MCP 서버가 elicitation 양식을 열었고 약 6초 동안 입력하지 않은 경우 |
2478| `elicitation_url_dialog` | MCP 서버가 브라우저 URL을 열도록 요청했고 사용자가 약 6초 동안 입력하지 않은 경우 |2477| `elicitation_url_dialog` | MCP 서버가 브라우저 URL을 열도록 요청했고 약 6초 동안 입력하지 않은 경우 |
2479| `elicitation_complete` | MCP 서버가 [URL 모드 elicitation](#elicitation-input)이 완료되었다고 보고한 경우 |2478| `elicitation_complete` | MCP 서버가 [URL 모드 elicitation](#elicitation-input)이 완료되었다고 보고한 경우 |
2480| `elicitation_response` | MCP elicitation 응답이 서버로 다시 전송된 경우 |2479| `elicitation_response` | MCP elicitation 응답이 서버로 다시 전송된 경우 |
2481| `agent_needs_input` | 터미널에서 [에이전트 뷰](/docs/ko/agent-view)가 열려 있는 동안 백그라운드 세션이 사용자 입력을 기다리기 시작한 경우. 터미널 세션이 [에이전트 팀 팀원의 터미널 설정 질문](/docs/ko/agent-teams#choose-a-display-mode)이나 [분류기 요청 요금](/docs/ko/auto-mode-classifier-billing)에 대한 자동 모드 안내를 표시했고 사용자가 약 6초 동안 입력하지 않은 경우에도 발생합니다 |2480| `agent_needs_input` | 터미널에서 [에이전트 뷰](/docs/ko/agent-view)가 열려 있는 동안 백그라운드 세션이 사용자 입력을 기다리기 시작한 경우. 터미널 세션에서 [에이전트 팀 팀원의 터미널 설정 질문](/docs/ko/agent-teams#choose-a-display-mode)이나 [분류기 요청 요금](/docs/ko/auto-mode-classifier-billing)에 관한 자동 모드 안내가 표시되고 약 6초 동안 입력하지 않은 경우에도 발생합니다 |
2482| `agent_completed` | 백그라운드 세션이 완료되거나 실패한 경우. 터미널에서 [에이전트 뷰](/docs/ko/agent-view)가 열려 있을 때만 발생합니다 |2481| `agent_completed` | 백그라운드 세션이 완료되거나 실패한 경우. 터미널에서 [에이전트 뷰](/docs/ko/agent-view)가 열려 있는 동안에만 발생합니다 |
2483| `quota_auto_resume_fired` | claude.ai 사용 한도로 일시 중지된 작업을 Claude Code가 계속하는 경우. 한도가 재설정될 때, 또는 대기 중에 사용량 크레딧 추가, 플랜 업그레이드, 모델 전환처럼 Claude Code에서 수행한 작업으로 사용량을 다시 사용할 수 있게 되면 더 일찍 계속하며, [모델 설정 예외](/docs/ko/interactive-mode#wait-for-a-usage-limit-to-reset)가 적용됩니다 |2482| `quota_auto_resume_fired` | claude.ai 사용 한도로 일시 중지되었던 작업을 Claude Code가 계속하는 경우: 한도가 재설정될 때, 또는 대기 중에 Claude Code에서 사용량 크레딧 추가, 플랜 업그레이드, 모델 전환 등 사용량을 다시 사용할 수 있게 만드는 작업을 한 경우 더 일찍 계속되며, [모델 설정 예외](/docs/ko/interactive-mode#wait-for-a-usage-limit-to-reset)가 적용됩니다 |
2484| `quota_auto_resume_stale` | 컴퓨터가 약 30분 이상 절전 상태인 동안 claude.ai 사용 한도가 재설정된 경우. Claude Code는 계속하지 않고 사용자가 `Enter`를 누를 때까지 기다립니다. 더 짧게 절전한 후에는 계속 진행하며 대신 `quota_auto_resume_fired`를 발생시킵니다 |2483| `quota_auto_resume_stale` | 컴퓨터가 약 30분 이상 절전 상태인 동안 claude.ai 사용 한도가 재설정된 경우. Claude Code는 계속하는 대신 `Enter`를 누를 때까지 기다립니다. 더 짧은 절전 후에는 계속 진행하며 대신 `quota_auto_resume_fired`를 발생시킵니다 |
2485| `quota_auto_resume_disabled` | Claude Code가 작업을 계속하지 않고 claude.ai 사용 한도 대기를 종료한 경우. [`autoContinueAtUsageLimit`](/docs/ko/settings-reference#autocontinueatusagelimit)이 꺼졌거나, Claude Code가 스스로 시작한 대기 중에 재설정 시각이 24시간 이상 뒤로 밀렸거나, 계속된 작업이 반복해서 한도에 도달했거나, 계속 진행이 모델에 도달하기 전에 차단된 경우입니다. 사용자가 `Esc` 또는 `Ctrl+C`를 누르거나 **Don't continue automatically**를 선택한 경우에는 발생하지 않습니다 |2484| `quota_auto_resume_disabled` | Claude Code가 작업을 계속하지 않고 claude.ai 사용 한도 대기를 종료하는 경우: [`autoContinueAtUsageLimit`](/docs/ko/settings-reference#autocontinueatusagelimit)이 꺼졌거나 Claude Code가 스스로 시작한 대기 중에 재설정 시점이 24시간 이상 뒤로 밀린 경우, 계속된 작업이 계속 한도에 도달한 경우, 또는 계속 진행이 모델에 도달하기 전에 차단된 경우입니다. `Esc` 또는 `Ctrl+C`를 누르거나 **Don't continue automatically**를 선택한 경우에는 발생하지 않습니다 |
2486 2485
2487`quota_auto_resume_fired`, `quota_auto_resume_stale`, `quota_auto_resume_disabled` 유형에는 Claude Code v2.1.234 이상이 필요합니다.2486`quota_auto_resume_fired`, `quota_auto_resume_stale`, `quota_auto_resume_disabled` 유형은 Claude Code v2.1.234 이상이 필요합니다.
2488 2487
2489터미널 세션에서 샌드박스 처리된 명령의 네트워크 요청에 대한 `permission_prompt`에는 Claude Code v2.1.246 이상이 필요합니다.2488터미널 세션에서 샌드박스 처리된 명령의 네트워크 요청에 대한 `permission_prompt`는 Claude Code v2.1.246 이상이 필요합니다.
2490 2489
2491팀원의 터미널 설정 질문에 대한 `agent_needs_input`에는 Claude Code v2.1.248 이상이 필요합니다.2490팀원의 터미널 설정 질문에 대한 `agent_needs_input`은 Claude Code v2.1.248 이상이 필요합니다.
2492 2491
2493<Note>2492<Note>
2494 `permission_prompt`, `idle_prompt`, `elicitation_dialog`, `elicitation_url_dialog` 유형은 데스크톱 알림과 타이밍을 공유하므로, 터미널 세션에서는 사용자가 터미널을 떠나 있는 것으로 보일 때만 표시됩니다.2493 `permission_prompt`, `idle_prompt`, `elicitation_dialog`, `elicitation_url_dialog` 유형은 데스크톱 알림과 타이밍을 공유하므로, 터미널 세션에서는 사용자가 터미널을 떠나 있는 것으로 보일 때만 표시됩니다.
2495 2494
2496 * `permission_prompt`는 사용자가 약 6초 동안 입력하지 않으면 발생합니다. 타이머는 권한 프롬프트가 나타날 때 시작되며, 키를 누를 때마다 지연됩니다. Claude가 도구 사용 권한을 요청할 때 즉시 훅을 실행하려면 대신 [PermissionRequest](#permissionrequest)를 사용합니다.2495 * `permission_prompt`는 약 6초 동안 입력하지 않으면 발생합니다. 타이머는 권한 프롬프트가 나타날 때 시작되며, 키를 누를 때마다 연기됩니다. Claude가 도구 사용 권한을 요청할 때 즉시 훅을 실행하려면 대신 [PermissionRequest](#permissionrequest)를 사용하세요.
2497 * `idle_prompt`는 Claude가 응답을 마친 후 약 60초 뒤에 발생하며, 그 이후 사용자가 입력하지 않았고 백그라운드 [서브에이전트](/docs/ko/sub-agents) 같은 백그라운드 에이전트가 실행 중이지 않은 경우에만 발생합니다. Claude Code는 claude.ai 사용 한도가 재설정되기를 기다리는 동안에는 `idle_prompt`를 보내지 않습니다. 대기가 자체적으로 끝나면 대신 `quota_auto_resume_*` 유형 중 하나가 발생합니다.2496 * `idle_prompt`는 Claude가 응답을 마친 후 약 60초 뒤에 발생하며, 그 이후로 입력하지 않았고 백그라운드 [서브에이전트](/docs/ko/sub-agents) 같은 백그라운드 에이전트가 실행 중이지 않은 경우에만 발생합니다. Claude Code는 claude.ai 사용 한도가 재설정되기를 기다리는 동안에는 `idle_prompt`를 보내지 않습니다. 대기가 스스로 종료되면 대신 `quota_auto_resume_*` 유형 중 하나가 발생합니다.
2498 * elicitation 양식에 대한 `elicitation_dialog` 또는 브라우저 URL 요청에 대한 `elicitation_url_dialog`는 사용자가 약 6초 동안 입력하지 않으면 발생합니다. 둘 다 `permission_prompt`와 같은 6초 조건을 공유합니다. 타이머는 대화 상자가 나타날 때 시작되며, 키를 누를 때마다 지연됩니다.2497 * elicitation 양식의 경우 `elicitation_dialog`, 브라우저 URL 요청의 경우 `elicitation_url_dialog`는 약 6초 동안 입력하지 않으면 발생합니다. 두 유형 모두 `permission_prompt`와 동일한 6초 기준을 공유합니다. 타이머는 대화 상자가 나타날 때 시작되며, 키를 누를 때마다 연기됩니다.
2499 2498
2500 다른 대화 상자가 화면에 있는 동안 도착한 권한 요청이나 elicitation도 요청이 도착한 시점부터 계산되는 같은 6초 조건을 유지합니다. 요청이 아직 열린 대화 상자 뒤에서 대기하는 동안에도 알림이 사용자에게 전달될 수 있습니다.2499 다른 대화 상자가 화면에 있는 동안 도착한 권한 요청이나 elicitation도 요청이 도착한 시점부터 계산되는 동일한 6초 기준이 적용됩니다. 따라서 요청이 열린 대화 상자 뒤에서 여전히 대기 중인 동안에도 해당 알림이 도착할 수 있습니다.
2501</Note>2500</Note>
2502 2501
2503Claude Code가 권한 요청을 Agent SDK의 [`canUseTool` 콜백](/docs/ko/agent-sdk/user-input)으로 보내는 세션에서는 `permission_prompt`의 타이밍이 다릅니다. Claude Desktop과 VS Code 확장 프로그램이 이 방식으로 Claude Code를 호스팅합니다.2502Claude Code가 권한 요청을 Agent SDK의 [`canUseTool` 콜백](/docs/ko/agent-sdk/user-input)으로 보내는 세션에서는 `permission_prompt`의 타이밍이 다릅니다. Claude Desktop과 VS Code 확장 프로그램이 이 방식으로 Claude Code를 호스팅합니다.
2504 2503
2505* `permission_prompt`는 Claude가 권한을 요청한 후 약 6초 뒤에 발생합니다. 사용자가 입력하는 동안에도 Claude Code는 이를 지연하지 않습니다.2504* `permission_prompt`는 Claude가 권한을 요청한 후 약 6초 뒤에 발생합니다. 입력 중이어도 Claude Code는 이를 연기하지 않습니다.
2506* 사용자 또는 [PermissionRequest](#permissionrequest) 훅이 그보다 먼저 응답하면 Claude Code는 `permission_prompt`를 실행하지 않습니다.2505* 사용자나 [PermissionRequest](#permissionrequest) 훅이 그보다 먼저 응답하면 Claude Code는 `permission_prompt`를 실행하지 않습니다.
2507* 이러한 세션에서 `permission_prompt`를 끄려면 [`CLAUDE_CODE_DISABLE_PERMISSION_PROMPT_NOTIFY_HOOKS`](/docs/ko/env-vars)를 `1`로 설정합니다.2506* 이러한 세션에서 `permission_prompt`를 끄려면 [`CLAUDE_CODE_DISABLE_PERMISSION_PROMPT_NOTIFY_HOOKS`](/docs/ko/env-vars)를 `1`로 설정합니다.
2508 2507
2509v2.1.233 이전에는 이러한 세션에서 `permission_prompt`가 발생하지 않았습니다.2508v2.1.233 이전에는 이러한 세션에서 `permission_prompt`가 발생하지 않았습니다.
2510 2509
2511알림 유형에 따라 다른 핸들러를 실행하려면 별도의 matcher를 사용합니다. 이 구성은 Claude에 권한 승인이 필요할 때 권한 전용 알림 스크립트를 실행하고, Claude가 유휴 상태일 때 다른 알림을 실행합니다.2510알림 유형에 따라 다른 핸들러를 실행하려면 별도의 matcher를 사용합니다. 이 구성은 Claude가 권한 승인을 필요로 할 때 권한 전용 알림 스크립트를 실행하고, Claude가 유휴 상태일 때 다른 알림을 실행합니다.
2512 2511
2513```json theme={null}2512```json theme={null}
2514{2513{
2538```2537```
2539 2538
2540<h4 id="notification-input">2539<h4 id="notification-input">
2541 Notification input2540 Notification 입력
2542</h4>2541</h4>
2543 2542
2544[공통 입력 필드](#common-input-fields) 외에도, Notification 훅은 알림 텍스트가 담긴 `message`, 선택적 `title`, 발생한 유형을 나타내는 `notification_type`을 전달받습니다.2543[공통 입력 필드](#common-input-fields) 외에도 Notification 훅은 알림 텍스트가 담긴 `message`, 선택적 `title`, 그리고 어떤 유형이 발생했는지 나타내는 `notification_type`을 받습니다.
2545 2544
2546```json theme={null}2545```json theme={null}
2547{2546{
2555}2554}
2556```2555```
2557 2556
2558Notification 훅은 알림을 차단하거나 수정할 수 없습니다. Claude Code는 이 훅의 `systemMessage` 및 `continue` 필드를 삭제하지만, 데스크톱 알림 예시가 사용하는 [`terminalSequence`](#emit-terminal-notifications)는 여전히 내보냅니다. Notification 훅은 알림을 외부 서비스로 전달하는 것과 같은 부수 효과를 위한 것입니다.2557Notification 훅은 알림을 차단하거나 수정할 수 없습니다. Claude Code는 `systemMessage` 및 `continue` 필드를 폐기하지만 [`terminalSequence`](#emit-terminal-notifications)는 여전히 내보내며, 데스크톱 알림 예시가 바로 이를 활용합니다. Notification 훅은 외부 서비스로 알림을 전달하는 것과 같은 부수 효과를 위한 것입니다.
2559 2558
2560<h3 id="subagentstart">2559<h3 id="subagentstart">
2561 SubagentStart2560 SubagentStart
2562</h3>2561</h3>
2563 2562
2564Claude가 Agent 도구로 서브에이전트를 생성할 때, Claude가 [서브에이전트를 재개](/docs/ko/sub-agents#resume-subagents)할 때, 그리고 프로세스 내 [에이전트 팀](/docs/ko/agent-teams) 팀원이 새 메시지를 처리할 때마다 실행됩니다. 에이전트 유형 이름으로 필터링하는 matcher를 지원합니다. 기본 제공 에이전트의 경우 `general-purpose`, `Explore`, `Plan` 같은 에이전트 이름입니다. [사용자 정의 서브에이전트](/docs/ko/sub-agents)의 경우 파일 이름이 아니라 에이전트 frontmatter의 `name` 필드입니다.2563Claude가 Agent 도구로 서브에이전트를 생성할 때, Claude가 [서브에이전트를 재개할 때](/docs/ko/sub-agents#resume-subagents), 그리고 인프로세스 [에이전트 팀](/docs/ko/agent-teams) 팀원이 새 메시지를 처리할 때마다 실행됩니다. 에이전트 유형 이름으로 필터링하는 matcher를 지원합니다. 기본 제공 에이전트의 경우 `general-purpose`, `Explore`, `Plan`과 같은 에이전트 이름입니다. [사용자 지정 서브에이전트](/docs/ko/sub-agents)의 경우 파일 이름이 아닌 에이전트 frontmatter의 `name` 필드입니다.
2565 2564
2566[플러그인](/docs/ko/plugins/overview)이 제공하는 서브에이전트의 경우, 에이전트 유형은 frontmatter의 이름만이 아니라 `my-plugin:reviewer`와 같은 플러그인 범위 식별자입니다. 콜론 때문에 플러그인 범위 이름은 정규식 경로로 처리되므로, 정확히 매칭하려면 matcher를 `^`와 `$`로 고정합니다. 예: `^my-plugin:reviewer$`.2565[플러그인](/docs/ko/plugins/overview)이 제공하는 서브에이전트의 경우, 에이전트 유형은 frontmatter의 이름만이 아니라 `my-plugin:reviewer`와 같은 플러그인 범위 식별자입니다. 콜론으로 인해 플러그인 범위 이름은 정규 표현식 경로로 처리되므로, 정확히 일치시키려면 matcher를 `^`와 `$`로 고정합니다: `^my-plugin:reviewer$`.
2567 2566
2568<h4 id="subagentstart-input">2567<h4 id="subagentstart-input">
2569 SubagentStart input2568 SubagentStart 입력
2570</h4>2569</h4>
2571 2570
2572[공통 입력 필드](#common-input-fields) 외에도, SubagentStart 훅은 서브에이전트의 고유 식별자가 담긴 `agent_id`와 matcher가 필터링하는 에이전트 이름이 담긴 `agent_type`을 전달받습니다.2571[공통 입력 필드](#common-input-fields) 외에도 SubagentStart 훅은 서브에이전트의 고유 식별자가 담긴 `agent_id`와 matcher가 필터링하는 에이전트 이름이 담긴 `agent_type`을 받습니다.
2573 2572
2574```json theme={null}2573```json theme={null}
2575{2574{
2582}2581}
2583```2582```
2584 2583
2585SubagentStart 훅은 서브에이전트 생성을 차단할 수 없지만, 서브에이전트에 컨텍스트를 주입할 수 있습니다. 모든 훅에서 사용할 수 있는 [JSON 출력 필드](#json-output) 외에도 다음을 반환할 수 있습니다.2584SubagentStart 훅은 서브에이전트 생성을 차단할 수 없지만 서브에이전트에 컨텍스트를 주입할 수 있습니다. 모든 훅에서 사용할 수 있는 [JSON 출력 필드](#json-output) 외에도 다음을 반환할 수 있습니다.
2586 2585
2587| 필드 | 설명 |2586| 필드 | 설명 |
2588| :- | :- |2587| :- | :- |
2589| `additionalContext` | 서브에이전트의 대화 시작 시, 첫 프롬프트 전에 서브에이전트의 컨텍스트에 추가되는 문자열입니다. [Claude에 컨텍스트 추가](#add-context-for-claude)를 참조하세요 |2588| `additionalContext` | 서브에이전트의 대화 시작 시점, 첫 프롬프트 전에 서브에이전트의 컨텍스트에 추가되는 문자열. [Claude를 위한 컨텍스트 추가](#add-context-for-claude)를 참조하세요 |
2590 2589
2591```json theme={null}2590```json theme={null}
2592{2591{
2597}2596}
2598```2597```
2599 2598
2600같은 서브에이전트에 대해 훅이 다시 실행되면, Claude Code는 서브에이전트의 컨텍스트에 이전 실행의 사본이 아직 없는 경우에만 반환된 컨텍스트를 주입합니다. 시작 시 주입된 사본은 그대로 유지되므로 서브에이전트의 [프롬프트 캐시](/docs/ko/prompt-caching#subagents-and-the-cache)가 손상되지 않습니다. [자동 압축](/docs/ko/sub-agents#auto-compaction)이 해당 사본을 삭제한 후에는 Claude Code가 다음 실행의 컨텍스트를 다시 주입합니다.2599같은 서브에이전트에 대해 훅이 다시 실행되면, Claude Code는 서브에이전트의 컨텍스트에 이전 실행의 사본이 아직 없는 경우에만 반환된 컨텍스트를 주입합니다. 시작 시 주입된 사본은 그대로 유지되므로 서브에이전트의 [프롬프트 캐시](/docs/ko/prompt-caching#subagents-and-the-cache)가 손상되지 않습니다. [자동 압축](/docs/ko/sub-agents#auto-compaction)이 해당 사본을 폐기한 후에는 Claude Code가 다음 실행의 컨텍스트를 다시 주입합니다.
2601 2600
2602<h3 id="subagentstop">2601<h3 id="subagentstop">
2603 SubagentStop2602 SubagentStop
2604</h3>2603</h3>
2605 2604
2606Claude Code 서브에이전트가 응답을 마쳤을 때 실행됩니다. 에이전트 유형으로 매칭하며, SubagentStart와 같은 값을 사용합니다.2605Claude Code 서브에이전트가 응답을 마쳤을 때 실행됩니다. 에이전트 유형과 일치하며, 값은 SubagentStart와 동일합니다.
2607 2606
2608<h4 id="subagentstop-input">2607<h4 id="subagentstop-input">
2609 SubagentStop input2608 SubagentStop 입력
2610</h4>2609</h4>
2611 2610
2612[공통 입력 필드](#common-input-fields) 외에도, SubagentStop 훅은 `stop_hook_active`, `agent_id`, `agent_type`, `agent_transcript_path`, `last_assistant_message`를 전달받습니다. `agent_type` 필드는 matcher 필터링에 사용되는 값입니다. `transcript_path`는 메인 세션의 트랜스크립트이고, `agent_transcript_path`는 중첩된 `subagents/` 폴더에 저장된 서브에이전트 자체의 트랜스크립트입니다. `last_assistant_message` 필드에는 서브에이전트의 최종 응답 텍스트 내용이 포함되므로, 훅은 트랜스크립트 파일을 파싱하지 않고도 이에 접근할 수 있습니다.2611[공통 입력 필드](#common-input-fields) 외에도 SubagentStop 훅은 `stop_hook_active`, `agent_id`, `agent_type`, `agent_transcript_path`, `last_assistant_message`를 받습니다. `agent_type` 필드는 matcher 필터링에 사용되는 값입니다. `transcript_path`는 메인 세션의 트랜스크립트이고, `agent_transcript_path`는 중첩된 `subagents/` 폴더에 저장된 서브에이전트 자체의 트랜스크립트입니다. `last_assistant_message` 필드에는 서브에이전트 최종 응답의 텍스트 내용이 포함되므로, 훅은 트랜스크립트 파일을 파싱하지 않고도 이에 접근할 수 있습니다.
2613 2612
2614모든 SubagentStop 이벤트가 Claude가 생성한 서브에이전트에서 오는 것은 아닙니다. Claude Code는 [프롬프트 제안](/docs/ko/interactive-mode#prompt-suggestions)이나 [`/btw` 부가 질문](/docs/ko/interactive-mode#side-questions-with-%2Fbtw) 같은 일부 자체 기능을 위해 내부 에이전트도 실행하며, 이들 중 하나가 완료될 때도 SubagentStop이 발생합니다. 이러한 이벤트의 경우 `agent_type`은 [`--agent`](/docs/ko/cli-reference#cli-flags) 또는 [`agent` 설정](/docs/ko/settings-reference#agent)으로 지정된 것처럼 세션 자체가 실행되는 에이전트 이름이며, 세션이 에이전트 없이 실행되면 빈 문자열입니다.2613모든 SubagentStop 이벤트가 Claude가 생성한 서브에이전트에서 오는 것은 아닙니다. Claude Code는 [프롬프트 제안](/docs/ko/interactive-mode#prompt-suggestions)과 [`/btw` 곁가지 질문](/docs/ko/interactive-mode#side-questions-with-%2Fbtw) 같은 일부 자체 기능을 위해 내부 에이전트도 실행하며, 이러한 에이전트가 완료될 때도 SubagentStop이 발생합니다. 이러한 이벤트의 경우 `agent_type`은 [`--agent`](/docs/ko/cli-reference#cli-flags) 또는 [`agent` 설정](/docs/ko/settings-reference#agent)으로 지정된 것과 같이 세션 자체가 실행되는 에이전트 이름이며, 세션이 에이전트 없이 실행되는 경우 빈 문자열입니다.
2615 2614
2616에이전트 유형을 지정한 `matcher`는 빈 `agent_type`과 매칭되지 않습니다. matcher가 생략되었거나, `""` 또는 `"*"`이거나, 빈 문자열과 매칭되는 정규식인 훅은 빈 `agent_type`을 가진 이벤트에도 실행됩니다.2615에이전트 유형을 지정하는 `matcher`는 빈 `agent_type`과 일치하지 않습니다. matcher가 생략되었거나, `""` 또는 `"*"`이거나, 빈 문자열과 일치하는 정규 표현식인 훅은 빈 `agent_type`을 가진 이벤트에도 실행됩니다.
2617 2616
2618Claude Code v2.1.271 이상에서는 [`SubagentHandback`](/docs/ko/tools-reference) 도구와 함께 실행되는 서브에이전트가 중지되기 전에 해당 도구를 통해 보고서를 전달합니다. 이때 `last_assistant_message` 필드에는 서브에이전트의 마무리 텍스트가 있으면 그것이 담기며, 이는 전달된 보고서가 아닙니다. 보고서는 해당 호출의 `message` 입력이며, `SubagentHandback`에 매칭되는 `PreToolUse` 또는 `PostToolUse` 훅은 이를 `tool_input.message`로 전달받습니다.2617Claude Code v2.1.271 이상에서는 [`SubagentHandback`](/docs/ko/tools-reference) 도구와 함께 실행되는 서브에이전트가 중지하기 전에 해당 도구를 통해 보고서를 전달합니다. 이때 `last_assistant_message` 필드에는 서브에이전트의 마무리 텍스트(있는 경우)가 담기며, 이는 전달된 보고서가 아닙니다. 보고서는 해당 호출의 `message` 입력이며, `SubagentHandback`과 일치하는 `PreToolUse` 또는 `PostToolUse` 훅이 이를 `tool_input.message`로 받습니다.
2619 2618
2620SubagentStop 훅은 [Stop 입력](#stop-input)에서 설명하는 `background_tasks` 및 `session_crons` 배열도 전달받습니다. 두 배열 모두 서브에이전트가 아닌 상위 세션 범위입니다.2619SubagentStop 훅은 [Stop 입력](#stop-input)에서 설명하는 `background_tasks` 및 `session_crons` 배열도 받습니다. 두 배열 모두 서브에이전트가 아닌 상위 세션 범위입니다.
2621 2620
2622```json theme={null}2621```json theme={null}
2623{2622{
2636}2635}
2637```2636```
2638 2637
2639SubagentStop 훅은 [Stop 훅](#stop-decision-control)과 같은 결정 제어 형식을 사용하며, 서브에이전트를 계속 실행시키는 오류가 아닌 피드백을 위해 `hookEventName`을 `"SubagentStop"`으로 설정한 `hookSpecificOutput.additionalContext`도 포함됩니다. `reason`과 함께 `decision: "block"`을 반환하면 서브에이전트가 계속 실행되며 `reason`이 서브에이전트의 다음 지시로 전달됩니다. 종료 코드 2로 차단하는 훅은 stderr 메시지를 같은 방식으로 전달합니다. 서브에이전트가 반환된 후 상위 세션에 컨텍스트를 주입하려면 대신 `Agent` 도구에 대한 [`PostToolUse`](#posttooluse) 훅을 사용합니다.2638SubagentStop 훅은 서브에이전트를 계속 실행시키는 오류가 아닌 피드백을 위해 `hookEventName`이 `"SubagentStop"`으로 설정된 `hookSpecificOutput.additionalContext`를 포함하여 [Stop 훅](#stop-decision-control)과 동일한 결정 제어 형식을 사용합니다. `reason`과 함께 `decision: "block"`을 반환하면 서브에이전트가 계속 실행되며 `reason`이 서브에이전트의 다음 지시로 전달됩니다. 종료 코드 2로 차단하는 훅은 stderr 메시지를 같은 방식으로 전달합니다. 서브에이전트가 반환된 후 상위 세션에 컨텍스트를 주입하려면 대신 `Agent` 도구에 대한 [`PostToolUse`](#posttooluse) 훅을 사용하세요.
2640 2639
2641<h3 id="taskcreated">2640<h3 id="taskcreated">
2642 TaskCreated2641 TaskCreated
2643</h3>2642</h3>
2644 2643
2645`TaskCreate` 도구를 통해 작업이 생성될 때 실행됩니다. 명명 규칙을 적용하거나, 작업 설명을 필수로 요구하거나, 특정 작업의 생성을 방지하는 데 사용합니다. [Task 도구가 없는 세션](/docs/ko/tools-reference#task-tool-availability)에서는 이 이벤트가 발생하지 않습니다.2644`TaskCreate` 도구를 통해 작업이 생성될 때 실행됩니다. 명명 규칙을 강제하거나, 작업 설명을 필수로 하거나, 특정 작업의 생성을 방지하는 데 사용합니다. [Task 도구가 없는 세션](/docs/ko/tools-reference#task-tool-availability)에서는 이 이벤트가 발생하지 않습니다.
2646 2645
2647TaskCreated 훅은 matcher를 지원하지 않으며 매번 발생합니다.2646TaskCreated 훅은 matcher를 지원하지 않으며 모든 경우에 발생합니다.
2648 2647
2649<h4 id="taskcreated-input">2648<h4 id="taskcreated-input">
2650 TaskCreated input2649 TaskCreated 입력
2651</h4>2650</h4>
2652 2651
2653[공통 입력 필드](#common-input-fields) 외에도, TaskCreated 훅은 `task_id`, `task_subject`를 전달받으며, 선택적으로 `task_description`, `teammate_name`, `team_name`을 전달받습니다.2652[공통 입력 필드](#common-input-fields) 외에도 TaskCreated 훅은 `task_id`, `task_subject`, 그리고 선택적으로 `task_description`, `teammate_name`, `team_name`을 받습니다.
2654 2653
2655```json theme={null}2654```json theme={null}
2656{2655{
2668 2667
2669| 필드 | 설명 |2668| 필드 | 설명 |
2670| :- | :- |2669| :- | :- |
2671| `task_id` | 생성되는 작업의 식별자입니다 |2670| `task_id` | 생성 중인 작업의 식별자 |
2672| `task_subject` | 작업의 제목입니다 |2671| `task_subject` | 작업의 제목 |
2673| `task_description` | 작업에 대한 자세한 설명입니다. 없을 수도 있습니다 |2672| `task_description` | 작업의 상세 설명. 없을 수 있습니다 |
2674| `teammate_name` | 작업을 생성하는 팀원의 이름입니다. 없을 수도 있습니다 |2673| `teammate_name` | 작업을 생성하는 팀원의 이름. 없을 수 있습니다 |
2675| `team_name` | Deprecated. 세션에서 파생된 팀 이름이며, 향후 릴리스에서 제거됩니다 |2674| `team_name` | Deprecated. 세션에서 파생된 팀 이름이며, 향후 릴리스에서 제거될 예정입니다 |
2675| `agent_id` | 이 이벤트에서 [공통 입력 필드](#common-input-fields)는 작업을 생성하는 서브에이전트 또는 [인프로세스 팀원](/docs/ko/agent-teams#choose-a-display-mode)을 식별합니다. 없을 수 있습니다. Claude Code v2.1.290 이상이 필요합니다 |
2676 2676
2677<h4 id="taskcreated-decision-control">2677<h4 id="taskcreated-decision-control">
2678 TaskCreated decision control2678 TaskCreated 결정 제어
2679</h4>2679</h4>
2680 2680
2681TaskCreated 훅은 두 가지 방법으로 생성을 차단할 수 있습니다. 어느 방법이든 Claude Code는 작업을 삭제하고 메시지를 도구의 오류로 Claude에 반환합니다. Claude Code는 이 이벤트의 `continue: false`를 무시하며 Claude는 계속 작업합니다.2681TaskCreated 훅은 두 가지 방법으로 생성을 차단할 수 있습니다. 어느 방법이든 Claude Code는 작업을 삭제하고 메시지를 도구 오류로 Claude에게 반환합니다. Claude Code는 이 이벤트의 `continue: false`를 무시하며 Claude는 계속 작업합니다.
2682 2682
2683* **종료 코드 2**: Claude Code가 stderr 텍스트를 메시지로 반환합니다.2683* **종료 코드 2**: Claude Code가 stderr 텍스트를 메시지로 반환합니다.
2684* **JSON `{"decision": "block", "reason": "..."}`**: Claude Code가 `reason`을 메시지로 반환합니다.2684* **JSON `{"decision": "block", "reason": "..."}`**: Claude Code가 `reason`을 메시지로 반환합니다.
2702 TaskCompleted2702 TaskCompleted
2703</h3>2703</h3>
2704 2704
2705작업이 완료로 표시될 때 실행됩니다. 두 가지 상황에서 발생합니다. 에이전트가 TaskUpdate 도구를 통해 작업을 명시적으로 완료로 표시할 때, 또는 [에이전트 팀](/docs/ko/agent-teams) 팀원이 진행 중인 작업이 있는 상태로 턴을 마칠 때입니다. 작업을 종료하기 전에 테스트 통과나 lint 검사 같은 완료 기준을 적용하는 데 사용합니다.2705작업이 완료로 표시될 때 실행됩니다. 이는 두 가지 상황에서 발생합니다. 에이전트가 TaskUpdate 도구를 통해 작업을 명시적으로 완료로 표시하는 경우, 또는 [에이전트 팀](/docs/ko/agent-teams) 팀원이 진행 중인 작업이 있는 상태로 턴을 마치는 경우입니다. 작업을 종료하기 전에 테스트 통과나 lint 검사 같은 완료 기준을 강제하는 데 사용합니다.
2706 2706
2707TaskCompleted 훅은 matcher를 지원하지 않으며 매번 발생합니다.2707TaskCompleted 훅은 matcher를 지원하지 않으며 모든 경우에 발생합니다.
2708 2708
2709<h4 id="taskcompleted-input">2709<h4 id="taskcompleted-input">
2710 TaskCompleted input2710 TaskCompleted 입력
2711</h4>2711</h4>
2712 2712
2713[공통 입력 필드](#common-input-fields) 외에도, TaskCompleted 훅은 `task_id`, `task_subject`를 전달받으며, 선택적으로 `task_description`, `teammate_name`, `team_name`을 전달받습니다.2713[공통 입력 필드](#common-input-fields) 외에도 TaskCompleted 훅은 `task_id`, `task_subject`, 그리고 선택적으로 `task_description`, `teammate_name`, `team_name`을 받습니다.
2714 2714
2715```json theme={null}2715```json theme={null}
2716{2716{
2729 2729
2730| 필드 | 설명 |2730| 필드 | 설명 |
2731| :- | :- |2731| :- | :- |
2732| `task_id` | 완료되는 작업의 식별자입니다 |2732| `task_id` | 완료 중인 작업의 식별자 |
2733| `task_subject` | 작업의 제목입니다 |2733| `task_subject` | 작업의 제목 |
2734| `task_description` | 작업에 대한 자세한 설명입니다. 없을 수도 있습니다 |2734| `task_description` | 작업의 상세 설명. 없을 수 있습니다 |
2735| `teammate_name` | 작업을 완료하는 팀원의 이름입니다. 없을 수도 있습니다 |2735| `teammate_name` | 작업을 완료하는 팀원의 이름. 없을 수 있습니다 |
2736| `team_name` | Deprecated. 세션에서 파생된 팀 이름이며, 향후 릴리스에서 제거됩니다 |2736| `team_name` | Deprecated. 세션에서 파생된 팀 이름이며, 향후 릴리스에서 제거될 예정입니다 |
2737| `agent_id` | 이 이벤트에서 [공통 입력 필드](#common-input-fields)는 작업을 완료하는 서브에이전트 또는 [인프로세스 팀원](/docs/ko/agent-teams#choose-a-display-mode)을 식별합니다. 없을 수 있습니다. Claude Code v2.1.290 이상이 필요합니다 |
2737 2738
2738<h4 id="taskcompleted-decision-control">2739<h4 id="taskcompleted-decision-control">
2739 TaskCompleted decision control2740 TaskCompleted 결정 제어
2740</h4>2741</h4>
2741 2742
2742TaskCompleted 훅은 작업 완료를 제어하는 두 가지 방법을 지원합니다.2743TaskCompleted 훅은 작업 완료를 제어하는 두 가지 방법을 지원합니다.
2743 2744
2744* **종료 코드 2**: 작업이 완료로 표시되지 않으며 stderr 메시지가 피드백으로 모델에 전달됩니다.2745* **종료 코드 2**: 작업이 완료로 표시되지 않으며 stderr 메시지가 피드백으로 모델에 다시 전달됩니다.
2745* **JSON `{"continue": false, "stopReason": "..."}`**: 팀원이 턴을 마쳐서 이벤트가 발생한 경우, `Stop` 훅 동작과 마찬가지로 팀원을 완전히 중지합니다. `stopReason`은 사용자에게 표시됩니다. `TaskUpdate` 도구가 이벤트를 발생시킨 경우에는 Claude Code가 `continue: false`를 무시하며, 종료 코드 2는 여전히 완료를 차단합니다.2746* **JSON `{"continue": false, "stopReason": "..."}`**: 팀원이 턴을 마쳐서 이벤트가 트리거된 경우, `Stop` 훅 동작과 마찬가지로 팀원을 완전히 중지합니다. `stopReason`은 사용자에게 표시됩니다. `TaskUpdate` 도구가 이벤트를 트리거한 경우 Claude Code는 `continue: false`를 무시하며, 종료 코드 2는 여전히 완료를 차단합니다.
2746 2747
2747이 예시는 테스트를 실행하고 실패하면 작업 완료를 차단합니다.2748이 예시는 테스트를 실행하고 실패하면 작업 완료를 차단합니다.
2748 2749
2764 Stop2765 Stop
2765</h3>2766</h3>
2766 2767
2767메인 Claude Code 에이전트가 응답을 마쳤을 때 실행됩니다. 사용자 중단으로2768메인 Claude Code 에이전트가 응답을 마쳤을 때 실행됩니다. 사용자 중단으로 인해
2768중지된 경우에는 실행되지 않습니다. API 오류가 발생하면 대신2769중지된 경우에는 실행되지 않습니다. API 오류가 발생하면 대신
2769[StopFailure](#stopfailure)가 발생합니다.2770[StopFailure](#stopfailure)가 발생합니다.
2770 2771
2771<Tip>2772<Tip>
2772 [`/goal`](/docs/ko/goal) 명령은 세션 범위의 프롬프트 기반 Stop 훅을 위한 기본 제공 단축 명령입니다. 훅 구성을 작성하지 않고 Claude가 특정 조건을 향해 계속 작업하게 하려면 이 명령을 사용합니다.2773 [`/goal`](/docs/ko/goal) 명령은 세션 범위의 프롬프트 기반 Stop 훅을 위한 기본 제공 바로 가기입니다. 훅 구성을 작성하지 않고 Claude가 특정 조건을 향해 계속 작업하도록 하려면 이 명령을 사용하세요.
2773</Tip>2774</Tip>
2774 2775
2775<h4 id="stop-input">2776<h4 id="stop-input">
2776 Stop input2777 Stop 입력
2777</h4>2778</h4>
2778 2779
2779[공통 입력 필드](#common-input-fields) 외에도 Stop 훅은 `stop_hook_active`, `last_assistant_message`, `background_tasks`, `session_crons`를 전달받습니다. `stop_hook_active` 필드는 Claude Code가 이미 stop 훅의 결과로 계속 진행 중일 때 `true`입니다. 결코 해결되지 않을 조건에서 차단하지 않도록 이 값을 확인하거나 트랜스크립트를 처리하세요.2780[공통 입력 필드](#common-input-fields) 외에도 Stop 훅은 `stop_hook_active`, `last_assistant_message`, `background_tasks`, `session_crons`를 받습니다. `stop_hook_active` 필드는 Claude Code가 이미 stop 훅의 결과로 계속 진행 중일 때 `true`입니다. 결코 해결되지 않을 조건에서 차단하는 것을 방지하려면 이 값을 확인하거나 트랜스크립트를 처리하세요.
2780 2781
2781Claude Code는 연속 8회 계속 제한을 적용합니다. stop 훅이 턴을 연속으로 8회 계속시킨 후에는 Claude Code가 다음 차단을 재정의하고 턴을 종료합니다. 연속 계속 횟수는 Claude가 도구를 호출할 때마다 초기화됩니다. 제한을 늘리려면 [`CLAUDE_CODE_STOP_HOOK_BLOCK_CAP`](/docs/ko/env-vars)을 설정합니다.2782Claude Code는 연속 8회 계속 진행 제한을 적용합니다. stop 훅이 턴을 연속으로 8번 계속 진행시킨 후에는 Claude Code가 다음 차단을 재정의하고 턴을 종료합니다. 연속 계속 진행 횟수는 Claude가 도구를 호출할 때마다 재설정됩니다. 제한을 늘리려면 [`CLAUDE_CODE_STOP_HOOK_BLOCK_CAP`](/docs/ko/env-vars)을 설정합니다.
2782 2783
2783`last_assistant_message` 필드에는 Claude의 최종 응답 텍스트 내용이 포함되므로, 훅은 트랜스크립트 파일을 파싱하지 않고도 이에 접근할 수 있습니다. 소리 내어 읽기나 알림 훅처럼 방금 완료된 턴에 대해 동작하는 훅은 `transcript_path`를 읽는 대신 이 필드를 사용합니다. 모든 버전에서 Stop 시점에 트랜스크립트 파일에 최종 메시지가 포함된다는 보장이 없기 때문입니다.2784`last_assistant_message` 필드에는 Claude 최종 응답의 텍스트 내용이 포함되므로, 훅은 트랜스크립트 파일을 파싱하지 않고도 이에 접근할 수 있습니다. 소리 내어 읽기나 알림 훅처럼 방금 완료된 턴에 대해 동작하는 훅의 경우 `transcript_path`를 읽는 대신 이 필드를 사용하세요. 모든 버전에서 Stop 시점에 트랜스크립트 파일에 최종 메시지가 포함된다고 보장되지는 않습니다.
2784 2785
2785`background_tasks` 및 `session_crons` 배열을 사용하면 훅이 "세션이 완료됨"과 "세션이 백그라운드 작업이 다시 깨워 주기를 기다리며 일시 중지됨"을 구분할 수 있습니다. 두 배열은 작업 레지스트리에 접근할 수 있을 때 존재하며, 진행 중이거나 예약된 것이 없으면 비어 있습니다.2786`background_tasks` 및 `session_crons` 배열을 사용하면 훅이 "세션이 완료됨"과 "세션이 백그라운드 작업이 다시 깨워 주기를 기다리며 일시 중지됨"을 구별할 수 있습니다. 두 배열 모두 작업 레지스트리에 접근할 수 있을 때 존재하며, 진행 중이거나 예약된 항목이 없으면 비어 있습니다.
2786 2787
2787`background_tasks`의 각 항목은 진행 중인 작업 하나를 설명하며 다음 필드를 사용합니다.2788`background_tasks`의 각 항목은 진행 중인 작업 하나를 설명하며 다음 필드를 사용합니다.
2788 2789
2789| 필드 | 설명 |2790| 필드 | 설명 |
2790| :- | :- |2791| :- | :- |
2791| `id` | 작업 식별자입니다 |2792| `id` | 작업 식별자 |
2792| `type` | `shell`, `subagent`, `monitor`, `workflow`, `teammate`, `cloud session`, `MCP task`와 같은 알기 쉬운 작업 유형 레이블입니다. 각 레이블은 작업을 생성한 Claude Code 기능을 나타냅니다. 인식되지 않는 유형의 경우 원시 판별값으로 대체됩니다 |2793| `type` | `shell`, `subagent`, `monitor`, `workflow`, `teammate`, `cloud session`, `MCP task`와 같은 사용자 친화적인 작업 유형 레이블. 각 레이블은 어떤 Claude Code 기능이 작업을 생성했는지 나타냅니다. 인식되지 않는 유형의 경우 원시 판별 값으로 대체됩니다 |
2793| `status` | 현재 작업 상태입니다 |2794| `status` | 현재 작업 상태 |
2794| `description` | 자유 형식 설명으로, 1000자로 제한되며 잘린 경우 문자열 내에 `… [+N chars]` 마커가 붙습니다 |2795| `description` | 자유 형식 설명. 1000자로 제한되며, 잘린 경우 문자열 안에 `… [+N chars]` 마커가 포함됩니다 |
2795| `command` | 셸 명령줄로, 1000자로 제한됩니다. `shell` 작업에만 있습니다 |2796| `command` | 셸 명령줄. 1000자로 제한됩니다. `shell` 작업에만 존재합니다 |
2796| `agent_type` | 서브에이전트 유형 이름입니다. `subagent` 작업에만 있습니다 |2797| `agent_type` | 서브에이전트 유형 이름. `subagent` 작업에만 존재합니다 |
2797| `server` | MCP 서버 이름입니다. `monitor` 및 `MCP task` 작업에만 있습니다 |2798| `server` | MCP 서버 이름. `monitor` 및 `MCP task` 작업에만 존재합니다 |
2798| `tool` | MCP 도구 이름입니다. `monitor` 및 `MCP task` 작업에만 있습니다 |2799| `tool` | MCP 도구 이름. `monitor` 및 `MCP task` 작업에만 존재합니다 |
2799| `name` | 워크플로 이름입니다. `workflow` 작업에만 있습니다 |2800| `name` | 워크플로 이름. `workflow` 작업에만 존재합니다 |
2800 2801
2801`session_crons`의 각 항목은 `CronCreate`, `ScheduleWakeup`, `/loop`에서 생성된 세션 범위의 예약된 깨우기 하나를 설명합니다.2802`session_crons`의 각 항목은 `CronCreate`, `ScheduleWakeup`, `/loop`에서 생성된 세션 범위의 예약된 깨우기 하나를 설명합니다.
2802 2803
2803| 필드 | 설명 |2804| 필드 | 설명 |
2804| :- | :- |2805| :- | :- |
2805| `id` | Cron 작업 식별자입니다 |2806| `id` | Cron 작업 식별자 |
2806| `schedule` | Cron 표현식입니다. 예: `0 9 * * 1-5` |2807| `schedule` | Cron 표현식. 예: `0 9 * * 1-5` |
2807| `recurring` | 일정이 단일 실행 시각을 나타내는 일회성 깨우기는 `false`, 매칭될 때마다 다시 실행되는 작업은 `true`입니다 |2808| `recurring` | 일정이 단일 실행 시각을 나타내는 일회성 깨우기는 `false`, 일치할 때마다 다시 실행되는 작업은 `true` |
2808| `prompt` | cron이 실행될 때 제출되는 프롬프트로, 1000자로 제한되며 같은 `… [+N chars]` 마커가 붙습니다 |2809| `prompt` | cron이 실행될 때 제출되는 프롬프트. 1000자로 제한되며 동일한 `… [+N chars]` 마커를 사용합니다 |
2809 2810
2810이 예시는 진행 중인 셸 작업 하나와 반복 cron 하나가 있는 Stop 입력을 보여 줍니다.2811이 예시는 진행 중인 셸 작업 하나와 반복 cron 하나가 있는 Stop 입력을 보여 줍니다.
2811 2812
2839```2840```
2840 2841
2841<h4 id="stop-decision-control">2842<h4 id="stop-decision-control">
2842 Stop decision control2843 Stop 결정 제어
2843</h4>2844</h4>
2844 2845
2845`Stop` 및 `SubagentStop` 훅은 Claude의 계속 진행 여부를 제어할 수 있습니다. 모든 훅에서 사용할 수 있는 [JSON 출력 필드](#json-output) 외에도, 훅 스크립트는 다음과 같은 이벤트별 필드를 반환할 수 있습니다.2846`Stop` 및 `SubagentStop` 훅은 Claude가 계속할지 여부를 제어할 수 있습니다. 모든 훅에서 사용할 수 있는 [JSON 출력 필드](#json-output) 외에도 훅 스크립트는 다음 이벤트별 필드를 반환할 수 있습니다.
2846 2847
2847| 필드 | 설명 |2848| 필드 | 설명 |
2848| :- | :- |2849| :- | :- |
2849| `decision` | `"block"`은 Claude가 중지하지 못하게 합니다. Claude가 중지하도록 허용하려면 생략합니다 |2850| `decision` | `"block"`은 Claude가 중지하는 것을 방지합니다. Claude가 중지하도록 허용하려면 생략합니다 |
2850| `reason` | `decision`이 `"block"`일 때 필수입니다. Claude에 계속해야 하는 이유를 알려 줍니다 |2851| `reason` | `decision`이 `"block"`일 때 필수입니다. Claude에게 계속해야 하는 이유를 알려 줍니다 |
2851| `hookSpecificOutput.additionalContext` | Claude를 위한 오류가 아닌 피드백입니다. Claude가 이에 따라 조치할 수 있도록 대화가 계속되지만, `decision: "block"`과 달리 트랜스크립트에 훅 오류가 아닌 훅 피드백으로 표시됩니다 |2852| `hookSpecificOutput.additionalContext` | Claude를 위한 오류가 아닌 피드백. Claude가 이에 따라 행동할 수 있도록 대화가 계속되지만, `decision: "block"`과 달리 트랜스크립트에 훅 오류가 아닌 훅 피드백으로 표시됩니다 |
2852 2853
2853종료 코드 2로 차단하는 훅은 `reason`과 같은 방식으로 전달됩니다. Claude는 stderr 메시지를 계속해야 하는 이유에 대한 설명으로 받습니다.2854종료 코드 2로 차단하는 훅은 `reason`과 같은 방식으로 전달됩니다. Claude는 stderr 메시지를 계속해야 하는 이유에 대한 설명으로 받습니다.
2854 2855
2859}2860}
2860```2861```
2861 2862
2862훅이 설계대로 작동하면서 "완료하기 전에 테스트 스위트 실행"과 같은 안내를 Claude에 제공할 때는 `additionalContext`를 사용합니다. 이 방법은 `decision: "block"`과 같은 루프 보호 장치, 즉 `stop_hook_active` 입력과 연속 8회 계속 진행 한도를 거쳐 대화를 계속하지만, 트랜스크립트에는 `Stop hook feedback`으로 레이블이 지정되며 훅 오류 알림은 표시되지 않습니다.2863훅이 설계대로 동작하면서 "완료하기 전에 테스트 스위트를 실행하세요"와 같이 Claude에게 지침을 제공하는 경우에는 `additionalContext`를 사용하세요. 이는 `decision: "block"`과 동일한 루프 보호 장치, 즉 `stop_hook_active` 입력과 연속 8회 계속 진행 제한을 통해 대화를 계속 진행시키지만, 트랜스크립트에는 `Stop hook feedback`으로 레이블이 지정되며 훅 오류 알림은 표시되지 않습니다.
2863 2864
2864```json theme={null}2865```json theme={null}
2865{2866{
2874 StopFailure2875 StopFailure
2875</h3>2876</h3>
2876 2877
2877API 오류로 턴이 끝날 때 [Stop](#stop) 대신 실행됩니다. Claude Code는 [`terminalSequence`](#emit-terminal-notifications)를 제외하고 훅의 출력과 종료 코드를 무시합니다. 속도 제한, 인증 문제 또는 기타 API 오류로 Claude가 응답을 완료할 수 없을 때 실패를 로그에 기록하거나, 알림을 보내거나, 복구 조치를 취하는 데 사용합니다.2878API 오류로 인해 턴이 종료될 때 [Stop](#stop) 대신 실행됩니다. Claude Code는 [`terminalSequence`](#emit-terminal-notifications)를 제외하고 훅의 출력과 종료 코드를 무시합니다. 속도 제한, 인증 문제 또는 기타 API 오류로 인해 Claude가 응답을 완료할 수 없을 때 실패를 로그에 기록하거나, 알림을 보내거나, 복구 작업을 수행하는 데 사용합니다.
2878 2879
2879<h4 id="stopfailure-input">2880<h4 id="stopfailure-input">
2880 StopFailure input2881 StopFailure 입력
2881</h4>2882</h4>
2882 2883
2883[공통 입력 필드](#common-input-fields) 외에도, StopFailure 훅은 `error`, 선택적 `error_details`, 선택적 `last_assistant_message`를 전달받습니다. `error` 필드는 오류 유형을 식별하며 matcher 필터링에 사용됩니다.2884[공통 입력 필드](#common-input-fields) 외에도 StopFailure 훅은 `error`, 선택적 `error_details`, 선택적 `last_assistant_message`를 받습니다. `error` 필드는 오류 유형을 식별하며 matcher 필터링에 사용됩니다.
2884 2885
2885| 필드 | 설명 |2886| 필드 | 설명 |
2886| :- | :- |2887| :- | :- |
2887| `error` | 오류 유형: `rate_limit`, `overloaded`, `authentication_failed`, `oauth_org_not_allowed`, `account_on_hold`, `billing_error`, `invalid_request`, `model_not_found`, `server_error`, `max_output_tokens`, `cloud_credential_error` 또는 `unknown` |2888| `error` | 오류 유형: `rate_limit`, `overloaded`, `authentication_failed`, `oauth_org_not_allowed`, `account_on_hold`, `billing_error`, `invalid_request`, `model_not_found`, `server_error`, `max_output_tokens`, `cloud_credential_error` 또는 `unknown` |
2888| `error_details` | 사용 가능한 경우 오류에 대한 추가 세부 정보입니다 |2889| `error_details` | 가능한 경우 오류에 대한 추가 세부 정보 |
2889| `last_assistant_message` | 대화에 표시되는 렌더링된 오류 텍스트입니다. 이 필드에 Claude의 대화 출력이 담기는 `Stop` 및 `SubagentStop`과 달리, `StopFailure`에서는 `"API Error: Rate limit reached"`와 같은 API 오류 문자열 자체가 담깁니다 |2890| `last_assistant_message` | 대화에 표시되는 렌더링된 오류 텍스트. 이 필드에 Claude의 대화 출력이 담기는 `Stop` 및 `SubagentStop`과 달리, `StopFailure`의 경우 `"API Error: Rate limit reached"`와 같은 API 오류 문자열 자체가 포함됩니다 |
2890 2891
2891```json theme={null}2892```json theme={null}
2892{2893{
2906 TeammateIdle2907 TeammateIdle
2907</h3>2908</h3>
2908 2909
2909[에이전트 팀](/docs/ko/agent-teams) 팀원이 턴을 마친 후 유휴 상태로 전환되려고 할 때 실행됩니다. lint 검사 통과를 요구하거나 출력 파일이 존재하는지 확인하는 것처럼, 팀원이 작업을 멈추기 전에 품질 기준을 적용하는 데 사용합니다.2910[에이전트 팀](/docs/ko/agent-teams) 팀원이 턴을 마친 후 유휴 상태가 되려고 할 때 실행됩니다. lint 검사 통과를 요구하거나 출력 파일이 존재하는지 확인하는 것처럼, 팀원이 작업을 멈추기 전에 품질 기준을 강제하는 데 사용합니다.
2910 2911
2911TeammateIdle 훅은 matcher를 지원하지 않으며 매번 발생합니다.2912TeammateIdle 훅은 matcher를 지원하지 않으며 모든 경우에 발생합니다.
2912 2913
2913<h4 id="teammateidle-input">2914<h4 id="teammateidle-input">
2914 TeammateIdle input2915 TeammateIdle 입력
2915</h4>2916</h4>
2916 2917
2917[공통 입력 필드](#common-input-fields) 외에도, TeammateIdle 훅은 `teammate_name`과 `team_name`을 전달받습니다.2918[공통 입력 필드](#common-input-fields) 외에도 TeammateIdle 훅은 `teammate_name`과 `team_name`을 받습니다.
2918 2919
2919```json theme={null}2920```json theme={null}
2920{2921{
2930 2931
2931| 필드 | 설명 |2932| 필드 | 설명 |
2932| :- | :- |2933| :- | :- |
2933| `teammate_name` | 유휴 상태로 전환되려는 팀원의 이름입니다 |2934| `teammate_name` | 유휴 상태가 되려는 팀원의 이름 |
2934| `team_name` | Deprecated. 세션에서 파생된 팀 이름이며, 향후 릴리스에서 제거됩니다 |2935| `team_name` | Deprecated. 세션에서 파생된 팀 이름이며, 향후 릴리스에서 제거될 예정입니다 |
2936| `agent_id` | 이 이벤트에서 [공통 입력 필드](#common-input-fields)는 유휴 상태가 되려는 [인프로세스 팀원](/docs/ko/agent-teams#choose-a-display-mode)을 식별합니다. 없을 수 있습니다. Claude Code v2.1.290 이상이 필요합니다 |
2935 2937
2936<h4 id="teammateidle-decision-control">2938<h4 id="teammateidle-decision-control">
2937 TeammateIdle decision control2939 TeammateIdle 결정 제어
2938</h4>2940</h4>
2939 2941
2940TeammateIdle 훅은 팀원 동작을 제어하는 두 가지 방법을 지원합니다.2942TeammateIdle 훅은 팀원 동작을 제어하는 두 가지 방법을 지원합니다.
2941 2943
2942* **종료 코드 2**: 팀원이 stderr 메시지를 피드백으로 받고 유휴 상태로 전환되는 대신 계속 작업합니다.2944* **종료 코드 2**: 팀원이 stderr 메시지를 피드백으로 받고 유휴 상태가 되는 대신 계속 작업합니다.
2943* **JSON `{"continue": false, "stopReason": "..."}`**: `Stop` 훅 동작과 마찬가지로 팀원을 완전히 중지합니다. `stopReason`은 사용자에게 표시됩니다.2945* **JSON `{"continue": false, "stopReason": "..."}`**: `Stop` 훅 동작과 마찬가지로 팀원을 완전히 중지합니다. `stopReason`은 사용자에게 표시됩니다.
2944 2946
2945이 예시는 팀원이 유휴 상태로 전환되도록 허용하기 전에 빌드 산출물이 존재하는지 확인합니다.2947이 예시는 팀원이 유휴 상태가 되도록 허용하기 전에 빌드 산출물이 존재하는지 확인합니다.
2946 2948
2947```bash theme={null}2949```bash theme={null}
2948#!/bin/bash2950#!/bin/bash
2959 ConfigChange2961 ConfigChange
2960</h3>2962</h3>
2961 2963
2962세션 중에 설정 파일이 변경될 때 실행됩니다. 설정 변경을 감사하거나, 보안 정책을 적용하거나, 설정 파일에 대한 무단 수정을 차단하는 데 사용합니다.2964세션 중에 설정 파일이 변경될 때 실행됩니다. 설정 변경을 감사하거나, 보안 정책을 강제하거나, 설정 파일에 대한 무단 수정을 차단하는 데 사용합니다.
2963 2965
2964Claude Code는 설정 파일, 관리형 정책 파일 또는 스킬 파일이 변경될 때 ConfigChange 훅을 실행합니다. 관리형 정책의 경우 `managed-settings.json` 또는 `managed-settings.d/`의 파일이 변경될 때만 실행합니다. [서버 관리형 설정](/docs/ko/server-managed-settings)과 macOS 관리형 환경설정 또는 Windows 레지스트리 정책의 변경 사항은 훅을 실행하지 않고 적용합니다. [`wslInheritsWindowsSettings`](/docs/ko/settings-reference#wslinheritswindowssettings)를 사용하는 WSL에서는 변경된 Windows 측 관리형 설정 파일도 정책 폴링 시 훅을 실행하지 않고 적용합니다.2966Claude Code는 설정 파일, 관리형 정책 파일 또는 스킬 파일이 변경될 때 ConfigChange 훅을 실행합니다. 관리형 정책의 경우 `managed-settings.json` 또는 `managed-settings.d/`의 파일이 변경될 때만 실행합니다. [서버 관리형 설정](/docs/ko/server-managed-settings)과 macOS 관리형 환경설정 또는 Windows 레지스트리 정책의 변경 사항은 훅을 실행하지 않고 적용합니다. [`wslInheritsWindowsSettings`](/docs/ko/settings-reference#wslinheritswindowssettings)를 사용하는 WSL에서도 정책 폴링 시 변경된 Windows 측 관리형 설정 파일을 훅을 실행하지 않고 적용합니다.
2965 2967
2966matcher는 구성 소스로 필터링합니다.2968matcher는 구성 출처를 기준으로 필터링합니다.
2967 2969
2968| Matcher | 발생 시점 |2970| Matcher | 발생 시점 |
2969| :- | :- |2971| :- | :- |
2994```2996```
2995 2997
2996<h4 id="configchange-input">2998<h4 id="configchange-input">
2997 ConfigChange input2999 ConfigChange 입력
2998</h4>3000</h4>
2999 3001
3000[공통 입력 필드](#common-input-fields) 외에도, ConfigChange 훅은 `source`와 선택적으로 `file_path`를 전달받습니다. `source` 필드는 어떤 구성 유형이 변경되었는지 나타내고, `file_path`는 수정된 특정 파일의 경로를 제공합니다.3002[공통 입력 필드](#common-input-fields) 외에도 ConfigChange 훅은 `source`와 선택적으로 `file_path`를 받습니다. `source` 필드는 어떤 구성 유형이 변경되었는지 나타내고, `file_path`는 수정된 특정 파일의 경로를 제공합니다.
3001 3003
3002```json theme={null}3004```json theme={null}
3003{3005{
3011```3013```
3012 3014
3013<h4 id="configchange-decision-control">3015<h4 id="configchange-decision-control">
3014 ConfigChange decision control3016 ConfigChange 결정 제어
3015</h4>3017</h4>
3016 3018
3017ConfigChange 훅은 구성 변경이 적용되지 않도록 차단할 수 있습니다. 변경을 막으려면 종료 코드 2 또는 JSON `decision`을 사용합니다. 차단되면 새 설정이 실행 중인 세션에 적용되지 않습니다.3019ConfigChange 훅은 구성 변경이 적용되지 않도록 차단할 수 있습니다. 변경을 방지하려면 종료 코드 2 또는 JSON `decision`을 사용합니다. 차단되면 새 설정이 실행 중인 세션에 적용되지 않습니다.
3018 3020
3019| 필드 | 설명 |3021| 필드 | 설명 |
3020| :- | :- |3022| :- | :- |
3028}3030}
3029```3031```
3030 3032
3031`policy_settings` 변경은 차단할 수 없습니다. 머신의 관리형 설정 파일이 변경되면 `policy_settings` 소스에 대해서도 훅이 발생하므로 이러한 수정 사항을 로그에 기록하는 데 사용할 수 있지만, 차단 결정은 무시됩니다. 이를 통해 엔터프라이즈 관리형 설정이 항상 적용되도록 보장합니다. [서버 관리형 설정](/docs/ko/server-managed-settings)이 도착하거나 갱신될 때는 Claude Code가 `ConfigChange` 훅을 실행하지 않습니다.3033`policy_settings` 변경은 차단할 수 없습니다. 머신의 관리형 설정 파일이 변경되면 `policy_settings` 출처에 대해서도 훅이 발생하므로 이를 사용해 해당 편집을 로그에 기록할 수 있지만, 차단 결정은 무시됩니다. 이를 통해 엔터프라이즈 관리형 설정이 항상 적용되도록 보장합니다. [서버 관리형 설정](/docs/ko/server-managed-settings)이 도착하거나 새로 고쳐질 때 Claude Code는 `ConfigChange` 훅을 실행하지 않습니다.
3032 3034
3033Claude Code는 ConfigChange 훅의 JSON 출력에서 차단 결정에 따라 동작하며 `systemMessage`와 `continue`는 삭제합니다. `reason`으로 차단하든 종료 코드 2의 stderr로 차단하든, 차단된 변경은 사용자나 Claude에게 메시지를 표시하지 않습니다. Claude Code는 디버그 로그에 한 줄만 기록합니다.3035Claude Code는 ConfigChange 훅의 JSON 출력에서 차단 결정에 따라 동작하고 `systemMessage`와 `continue`는 폐기합니다. `reason`으로 차단하든 종료 코드 2의 stderr로 차단하든, 차단된 변경은 사용자나 Claude에게 아무 메시지도 표시하지 않습니다. Claude Code는 디버그 로그에 한 줄만 기록합니다.
3034 3036
3035<h3 id="cwdchanged">3037<h3 id="cwdchanged">
3036 CwdChanged3038 CwdChanged
3037</h3>3039</h3>
3038 3040
3039메인 대화의 셸 명령이 작업 디렉터리를 변경할 때 실행됩니다. 예를 들어 Claude가 `cd` 명령을 실행할 때입니다. 디렉터리 변경에 대응하는 데 사용합니다. 환경 변수를 다시 로드하거나, 프로젝트별 툴체인을 활성화하거나, 설정 스크립트를 자동으로 실행할 수 있습니다. 디렉터리별 환경을 관리하는 [direnv](https://direnv.net/) 같은 도구를 위해 [FileChanged](#filechanged)와 함께 사용합니다.3041메인 대화의 셸 명령이 작업 디렉터리를 변경할 때 실행됩니다. 예를 들어 Claude가 `cd` 명령을 실행하는 경우입니다. 디렉터리 변경에 대응하는 데 사용합니다. 환경 변수를 다시 로드하거나, 프로젝트별 툴체인을 활성화하거나, 설정 스크립트를 자동으로 실행할 수 있습니다. 디렉터리별 환경을 관리하는 [direnv](https://direnv.net/) 같은 도구를 위해 [FileChanged](#filechanged)와 함께 사용합니다.
3040 3042
3041CwdChanged 훅은 [`CLAUDE_ENV_FILE`](#persist-environment-variables)에 접근할 수 있습니다. 해당 파일에 기록된 변수는 다음 CwdChanged 이벤트에서 Claude Code가 이를 지울 때까지 이후의 Bash 명령에 유지됩니다.3043CwdChanged 훅은 [`CLAUDE_ENV_FILE`](#persist-environment-variables)에 접근할 수 있습니다. 해당 파일에 기록된 변수는 다음 CwdChanged 이벤트에서 Claude Code가 지울 때까지 이후의 Bash 명령에 유지됩니다.
3042 3044
3043CwdChanged는 matcher를 지원하지 않으며 매번 발생합니다.3045CwdChanged는 matcher를 지원하지 않으며 모든 경우에 발생합니다.
3044 3046
3045<h4 id="cwdchanged-input">3047<h4 id="cwdchanged-input">
3046 CwdChanged input3048 CwdChanged 입력
3047</h4>3049</h4>
3048 3050
3049[공통 입력 필드](#common-input-fields) 외에도, CwdChanged 훅은 `old_cwd`와 `new_cwd`를 전달받습니다.3051[공통 입력 필드](#common-input-fields) 외에도 CwdChanged 훅은 `old_cwd`와 `new_cwd`를 받습니다.
3050 3052
3051```json theme={null}3053```json theme={null}
3052{3054{
3060```3062```
3061 3063
3062<h4 id="cwdchanged-output">3064<h4 id="cwdchanged-output">
3063 CwdChanged output3065 CwdChanged 출력
3064</h4>3066</h4>
3065 3067
3066모든 훅에서 사용할 수 있는 [JSON 출력 필드](#json-output) 외에도, CwdChanged 훅은 `watchPaths`를 반환하여 [FileChanged](#filechanged)가 감시하는 파일 경로를 동적으로 설정할 수 있습니다.3068모든 훅에서 사용할 수 있는 [JSON 출력 필드](#json-output) 외에도 CwdChanged 훅은 [FileChanged](#filechanged)가 감시하는 파일 경로를 동적으로 설정하기 위해 `watchPaths`를 반환할 수 있습니다.
3067 3069
3068| 필드 | 설명 |3070| 필드 | 설명 |
3069| :- | :- |3071| :- | :- |
3070| `watchPaths` | 절대 경로의 배열입니다. 현재 동적 감시 목록을 대체합니다. `matcher` 구성의 경로는 항상 감시됩니다. 빈 배열을 반환하면 동적 목록이 지워지며, 이는 새 디렉터리에 진입할 때 일반적입니다 |3072| `watchPaths` | 절대 경로의 배열. 현재 동적 감시 목록을 대체합니다. `matcher` 구성의 경로는 항상 감시됩니다. 빈 배열을 반환하면 동적 목록이 지워지며, 이는 새 디렉터리에 진입할 때 일반적입니다 |
3071 3073
3072CwdChanged 훅에는 결정 제어가 없습니다. 디렉터리 변경을 차단할 수 없습니다.3074CwdChanged 훅에는 결정 제어가 없습니다. 디렉터리 변경을 차단할 수 없습니다.
3073 3075
3074Claude Code는 JSON 출력에서 `watchPaths`와 `systemMessage`를 읽고 `continue`는 삭제합니다. 대화형 세션에서는 `systemMessage`를 짧은 터미널 알림으로 표시합니다. 이 메시지는 SDK 메시지 스트림에 전달되지 않습니다.3076Claude Code는 JSON 출력에서 `watchPaths`와 `systemMessage`를 읽고 `continue`는 폐기합니다. 대화형 세션에서는 `systemMessage`를 짧은 터미널 알림으로 표시합니다. 이 메시지는 SDK 메시지 스트림에 도달하지 않습니다.
3075 3077
3076<h3 id="directoryadded">3078<h3 id="directoryadded">
3077 DirectoryAdded3079 DirectoryAdded
3078</h3>3080</h3>
3079 3081
3080세션 중에 사용자가 `/add-dir` 명령으로 작업 디렉터리를 추가한 후, 또는 SDK 클라이언트가 `register_repo_root` 제어 요청으로 작업 디렉터리를 추가한 후에 실행됩니다. 예를 들어 의존성을 설치하는 것처럼 새로 추가된 저장소를 준비하는 데 사용합니다.3082세션 도중 `/add-dir` 명령으로 작업 디렉터리를 추가한 후, 또는 SDK 클라이언트가 `register_repo_root` 제어 요청으로 작업 디렉터리를 추가한 후에 실행됩니다. 새로 추가된 저장소를 준비하는 데 사용합니다. 예를 들어 해당 저장소의 의존성을 설치할 수 있습니다.
3081 3083
3082Claude Code는 다음 경우에 이 이벤트를 발생시키지 않습니다.3084Claude Code는 다음 경우에 이 이벤트를 발생시키지 않습니다.
3083 3085
3084* `--add-dir` 시작 플래그로 디렉터리를 전달한 경우. 이러한 디렉터리는 [SessionStart](#sessionstart)가 처리합니다3086* `--add-dir` 시작 플래그로 디렉터리를 전달한 경우. 해당 디렉터리는 [SessionStart](#sessionstart)가 처리합니다
3085* `/permissions`의 Workspace 탭에서 디렉터리를 추가한 경우3087* `/permissions` Workspace 탭에서 디렉터리를 추가한 경우
3086* 이미 작업 디렉터리이거나 작업 디렉터리 내부에 있는 디렉터리를 추가한 경우3088* 이미 작업 디렉터리이거나 작업 디렉터리 내부에 있는 디렉터리를 추가한 경우
3087 3089
3088Claude Code는 샌드박스 및 권한 상태를 갱신한 후 DirectoryAdded를 발생시키므로, 훅이 실행될 때 샌드박스 처리된 도구는 이미 새 디렉터리를 인식합니다. 훅 명령 자체는 샌드박스 없이 실행됩니다.3090Claude Code는 샌드박스 및 권한 상태를 새로 고친 후 DirectoryAdded를 발생시키므로, 훅이 실행될 때 샌드박스 처리된 도구는 이미 새 디렉터리를 인식합니다. 훅 명령 자체는 샌드박스 없이 실행됩니다.
3089 3091
3090Claude Code는 훅을 기다리지 않습니다. 추가는 즉시 완료되며, 훅은 600초의 기본 타임아웃으로 백그라운드에서 실행됩니다.3092Claude Code는 훅을 기다리지 않습니다. 추가는 즉시 완료되며, 훅은 600초 기본 타임아웃으로 백그라운드에서 실행됩니다.
3091 3093
3092matcher는 디렉터리가 추가된 방식으로 필터링합니다.3094matcher는 디렉터리가 추가된 방식을 기준으로 필터링합니다.
3093 3095
3094| Matcher | 발생 시점 |3096| Matcher | 발생 시점 |
3095| :- | :- |3097| :- | :- |
3096| `slash_command` | 사용자가 `/add-dir`로 디렉터리를 추가한 경우 |3098| `slash_command` | `/add-dir`로 디렉터리를 추가한 경우 |
3097| `register_repo_root` | SDK 클라이언트가 `register_repo_root` 제어 요청으로 디렉터리를 추가한 경우 |3099| `register_repo_root` | SDK 클라이언트가 `register_repo_root` 제어 요청으로 디렉터리를 추가한 경우 |
3098 3100
3099<h4 id="directoryadded-input">3101<h4 id="directoryadded-input">
3100 DirectoryAdded input3102 DirectoryAdded 입력
3101</h4>3103</h4>
3102 3104
3103[공통 입력 필드](#common-input-fields) 외에도, DirectoryAdded 훅은 `directory`와 `source`를 전달받습니다.3105[공통 입력 필드](#common-input-fields) 외에도 DirectoryAdded 훅은 `directory`와 `source`를 받습니다.
3104 3106
3105| 필드 | 설명 |3107| 필드 | 설명 |
3106| :- | :- |3108| :- | :- |
3107| `directory` | 추가된 디렉터리의 절대 경로입니다 |3109| `directory` | 추가된 디렉터리의 절대 경로 |
3108| `source` | 디렉터리가 추가된 방식으로, `/add-dir`의 경우 `"slash_command"`, SDK 제어 요청의 경우 `"register_repo_root"`입니다 |3110| `source` | 디렉터리가 추가된 방식. `/add-dir`의 경우 `"slash_command"`, SDK 제어 요청의 경우 `"register_repo_root"` |
3109 3111
3110```json theme={null}3112```json theme={null}
3111{3113{
3118}3120}
3119```3121```
3120 3122
3121DirectoryAdded 훅에는 결정 제어가 없습니다. 훅이 실행될 때 이미 완료된 추가를 차단할 수 없습니다. Claude Code는 JSON 출력에서 `continue` 필드를 삭제하고, 나머지는 소스에 따라 다르게 표시합니다.3123DirectoryAdded 훅에는 결정 제어가 없습니다. 훅이 실행될 때 이미 완료된 추가를 차단할 수 없습니다. Claude Code는 JSON 출력에서 `continue` 필드를 폐기하고, 나머지는 출처에 따라 다르게 표시합니다.
3122 3124
3123* `slash_command`: Claude Code는 훅의 `systemMessage`를 사용자에게 표시하는 대신 다음 대화 턴에서 Claude에 컨텍스트로 전달합니다. 실패한 훅의 수가 트랜스크립트에 표시됩니다. 전체 실패 출력은 디버그 로그에 기록됩니다3125* `slash_command`: Claude Code는 훅의 `systemMessage`를 사용자에게 표시하지 않고 다음 대화 턴에서 Claude에게 컨텍스트로 전달합니다. 실패한 훅의 개수가 트랜스크립트에 표시됩니다. 전체 실패 출력은 디버그 로그에 기록됩니다
3124* `register_repo_root`: Claude Code는 `systemMessage` 출력과 실패 출력을 디버그 로그에만 기록합니다3126* `register_repo_root`: Claude Code는 `systemMessage` 출력과 실패 출력을 디버그 로그에만 기록합니다
3125 3127
3126<h3 id="filechanged">3128<h3 id="filechanged">
3127 FileChanged3129 FileChanged
3128</h3>3130</h3>
3129 3131
3130감시 중인 파일이 디스크에서 변경될 때 실행됩니다. Claude Code는 도구 호출을 검사하는 것이 아니라 파일 시스템 감시자로 변경을 감지하므로, 무엇이 파일을 변경했든 훅을 실행합니다. `Edit` 또는 `Write` 도구 호출, Claude가 `Bash`로 실행하는 스크립트, 또는 Claude Code 외부의 프로세스 모두 해당됩니다. 일반적인 용도는 프로젝트 설정 파일이 변경될 때 환경 변수를 다시 로드하는 것입니다.3132감시 중인 파일이 디스크에서 변경될 때 실행됩니다. Claude Code는 도구 호출을 검사하는 것이 아니라 파일 시스템 감시자로 변경을 감지하므로, 무엇이 파일을 변경했든 훅을 실행합니다. `Edit` 또는 `Write` 도구 호출, Claude가 `Bash`로 실행하는 스크립트, 또는 완전히 Claude Code 외부의 프로세스가 모두 해당됩니다. 일반적인 용도는 프로젝트 설정 파일이 변경될 때 환경 변수를 다시 로드하는 것입니다.
3131 3133
3132이 이벤트의 `matcher`는 두 가지 역할을 합니다.3134이 이벤트의 `matcher`는 두 가지 역할을 합니다.
3133 3135
3134* **감시 목록 구성**: 값을 `|`로 분할하고 각 세그먼트를 작업 디렉터리의 리터럴 파일 이름으로 등록하므로, `".envrc|.env"`는 정확히 이 두 파일을 감시합니다. 여기서는 정규식 패턴이 유용하지 않습니다. `^\.env` 같은 값은 문자 그대로 `^\.env`라는 이름의 파일을 감시합니다.3136* **감시 목록 구성**: 값은 `|`로 분할되며 각 세그먼트는 작업 디렉터리의 리터럴 파일 이름으로 등록되므로, `".envrc|.env"`는 정확히 그 두 파일을 감시합니다. 여기서는 정규 표현식 패턴이 유용하지 않습니다. `^\.env`와 같은 값은 문자 그대로 `^\.env`라는 이름의 파일을 감시합니다.
3135* **실행할 훅 필터링**: 감시 중인 파일이 변경되면, 같은 값이 표준 [matcher 규칙](#matcher-patterns)을 사용하여 변경된 파일의 기본 이름(basename)을 대상으로 실행할 훅 그룹을 필터링합니다.3137* **실행할 훅 필터링**: 감시 중인 파일이 변경되면 동일한 값이 변경된 파일의 basename에 대해 표준 [matcher 규칙](#matcher-patterns)을 사용하여 실행할 훅 그룹을 필터링합니다.
3136 3138
3137이 예시는 `Bash` 명령이나 외부 스크립트가 파일을 다시 쓰는 경우를 포함하여, 모든 변경 후 `data.csv`의 줄 끝을 정규화합니다.3139이 예시는 `Bash` 명령이나 외부 스크립트가 파일을 다시 기록하는 경우를 포함하여 모든 변경 후 `data.csv`의 줄 끝을 정규화합니다.
3138 3140
3139```json theme={null}3141```json theme={null}
3140{3142{
3154}3156}
3155```3157```
3156 3158
3157훅은 stdin의 [JSON 입력](#filechanged-input)에 있는 `file_path` 필드에서 변경된 파일의 절대 경로를 읽습니다. `grep` 가드는 `perl`이 제거하는 것과 같은 대상, 즉 줄 끝의 CR을 검사하므로, 정규화 이후의 실행은 파일을 건드리지 않고 종료됩니다. 더 느슨한 가드는 무한 루프에 빠집니다. `perl -i`는 치환할 것이 없어도 파일을 다시 쓰고, Claude Code는 다시 쓸 때마다 훅을 다시 실행하기 때문입니다. 이 스크립트를 `/path/to/normalize-line-endings.sh`에 저장하고 실행 가능하게 만듭니다.3159훅은 stdin으로 받는 [JSON 입력](#filechanged-input)의 `file_path` 필드에서 변경된 파일의 절대 경로를 읽습니다. `grep` 가드는 `perl`이 제거하는 것과 동일한 대상, 즉 줄 끝의 CR을 검사하므로, 정규화 후의 실행은 파일을 건드리지 않고 종료됩니다. 가드가 더 느슨하면 무한 루프가 발생합니다. `perl -i`는 아무것도 치환하지 않아도 파일을 다시 기록하고, Claude Code는 다시 기록될 때마다 훅을 다시 실행하기 때문입니다. 이 스크립트를 `/path/to/normalize-line-endings.sh`에 저장하고 실행 가능하게 만드세요.
3158 3160
3159```bash theme={null}3161```bash theme={null}
3160#!/bin/bash3162#!/bin/bash
3164fi3166fi
3165```3167```
3166 3168
3167훅이 작동하는지 확인하려면 Claude에 `Bash` 명령으로 `data.csv`에 CRLF 줄을 추가하도록 요청합니다. Claude Code가 훅을 실행하고 파일은 LF 줄 끝을 갖게 됩니다.3169훅이 작동하는지 확인하려면 Claude에게 `Bash` 명령으로 `data.csv`에 CRLF 줄을 추가하도록 요청하세요. Claude Code가 훅을 실행하고 파일은 LF 줄 끝으로 바뀝니다.
3168 3170
3169미리 이름을 지정할 수 없는 파일을 감시하려면 훅에서 [`watchPaths`](#filechanged-output)를 반환하여 감시 목록을 동적으로 업데이트합니다. Claude Code는 감시할 파일이 지정될 때만 감시자를 시작하므로, matcher가 최소 하나의 파일을 지정하는 FileChanged 그룹이나 `watchPaths`를 반환하는 [SessionStart](#sessionstart-decision-control) 또는 [CwdChanged](#cwdchanged) 훅으로 목록을 초기화합니다. matcher는 감시 중인 파일이 변경될 때 실행할 훅 그룹을 여전히 필터링하므로, 동적 경로를 처리하는 그룹에는 matcher를 생략합니다. 생략된 matcher는 모든 감시 파일과 매칭되며 감시 목록에 아무것도 추가하지 않습니다. `"*"` matcher도 모든 파일과 매칭되지만, Claude Code는 이를 다른 값과 마찬가지로 `*`라는 이름의 리터럴 파일로 감시 목록에 등록합니다.3171미리 이름을 지정할 수 없는 파일을 감시하려면 훅에서 [`watchPaths`](#filechanged-output)를 반환하여 감시 목록을 동적으로 업데이트합니다. Claude Code는 감시할 파일이 지정된 경우에만 감시자를 시작하므로, matcher가 최소 하나의 파일을 지정하는 FileChanged 그룹이나 `watchPaths`를 반환하는 [SessionStart](#sessionstart-decision-control) 또는 [CwdChanged](#cwdchanged) 훅으로 목록을 초기화하세요. 감시 중인 파일이 변경될 때 matcher는 여전히 실행할 훅 그룹을 필터링하므로, 동적 경로를 처리하는 그룹은 matcher를 생략하세요. 생략된 matcher는 감시 중인 모든 파일과 일치하며 감시 목록에는 아무것도 추가하지 않습니다. `"*"` matcher도 모든 파일과 일치하지만, Claude Code는 이를 다른 값과 마찬가지로 `*`라는 리터럴 파일로 감시 목록에 등록합니다.
3170 3172
3171FileChanged 훅은 [`CLAUDE_ENV_FILE`](#persist-environment-variables)에 접근할 수 있습니다. 해당 파일에 기록된 변수는 다음 [CwdChanged](#cwdchanged) 이벤트에서 Claude Code가 이를 지울 때까지 이후의 Bash 명령에 유지됩니다.3173FileChanged 훅은 [`CLAUDE_ENV_FILE`](#persist-environment-variables)에 접근할 수 있습니다. 해당 파일에 기록된 변수는 다음 [CwdChanged](#cwdchanged) 이벤트에서 Claude Code가 지울 때까지 이후의 Bash 명령에 유지됩니다.
3172 3174
3173<h4 id="filechanged-input">3175<h4 id="filechanged-input">
3174 FileChanged input3176 FileChanged 입력
3175</h4>3177</h4>
3176 3178
3177[공통 입력 필드](#common-input-fields) 외에도, FileChanged 훅은 `file_path`와 `event`를 전달받습니다.3179[공통 입력 필드](#common-input-fields) 외에도 FileChanged 훅은 `file_path`와 `event`를 받습니다.
3178 3180
3179| 필드 | 설명 |3181| 필드 | 설명 |
3180| :- | :- |3182| :- | :- |
3181| `file_path` | 변경된 파일의 절대 경로입니다 |3183| `file_path` | 변경된 파일의 절대 경로 |
3182| `event` | 발생한 일: 수정된 파일은 `"change"`, 생성된 파일은 `"add"`, 삭제된 파일은 `"unlink"`입니다 |3184| `event` | 발생한 일: 수정된 파일은 `"change"`, 생성된 파일은 `"add"`, 삭제된 파일은 `"unlink"` |
3183 3185
3184```json theme={null}3186```json theme={null}
3185{3187{
3193```3195```
3194 3196
3195<h4 id="filechanged-output">3197<h4 id="filechanged-output">
3196 FileChanged output3198 FileChanged 출력
3197</h4>3199</h4>
3198 3200
3199모든 훅에서 사용할 수 있는 [JSON 출력 필드](#json-output) 외에도, FileChanged 훅은 `watchPaths`를 반환하여 감시할 파일 경로를 동적으로 업데이트할 수 있습니다.3201모든 훅에서 사용할 수 있는 [JSON 출력 필드](#json-output) 외에도 FileChanged 훅은 감시할 파일 경로를 동적으로 업데이트하기 위해 `watchPaths`를 반환할 수 있습니다.
3200 3202
3201| 필드 | 설명 |3203| 필드 | 설명 |
3202| :- | :- |3204| :- | :- |
3203| `watchPaths` | 절대 경로의 배열입니다. 현재 동적 감시 목록을 대체합니다. `matcher` 구성의 경로는 항상 감시됩니다. 훅 스크립트가 변경된 파일을 기반으로 감시할 추가 파일을 찾았을 때 사용합니다 |3205| `watchPaths` | 절대 경로의 배열. 현재 동적 감시 목록을 대체합니다. `matcher` 구성의 경로는 항상 감시됩니다. 훅 스크립트가 변경된 파일을 기반으로 감시할 추가 파일을 발견할 때 사용합니다 |
3204 3206
3205FileChanged 훅에는 결정 제어가 없습니다. 파일 변경이 일어나는 것을 차단할 수 없습니다.3207FileChanged 훅에는 결정 제어가 없습니다. 파일 변경이 발생하는 것을 차단할 수 없습니다.
3206 3208
3207Claude Code는 JSON 출력에서 `watchPaths`와 `systemMessage`를 읽고 `continue`는 삭제합니다. 대화형 세션에서는 `systemMessage`를 짧은 터미널 알림으로 표시합니다. 이 메시지는 SDK 메시지 스트림에 전달되지 않습니다.3209Claude Code는 JSON 출력에서 `watchPaths`와 `systemMessage`를 읽고 `continue`는 폐기합니다. 대화형 세션에서는 `systemMessage`를 짧은 터미널 알림으로 표시합니다. 이 메시지는 SDK 메시지 스트림에 도달하지 않습니다.
3208 3210
3209<h3 id="worktreecreate">3211<h3 id="worktreecreate">
3210 WorktreeCreate3212 WorktreeCreate
3211</h3>3213</h3>
3212 3214
3213`claude --worktree`, [`isolation: "worktree"`를 사용하는 서브에이전트](/docs/ko/sub-agents#choose-the-subagent-scope), 또는 Claude Code가 자체 worktree에 격리하는 [백그라운드 세션](/docs/ko/agent-view#how-file-edits-are-isolated) 등으로 worktree가 생성될 때 실행됩니다. 기본적으로 Claude Code는 `git worktree`로 격리된 작업 사본을 생성합니다. WorktreeCreate 훅을 구성하면 이 기본 git 동작이 대체되므로, SVN, Perforce, Mercurial 같은 다른 버전 관리 시스템을 사용할 수 있습니다.3215`claude --worktree`, [`isolation: "worktree"`를 사용하는 서브에이전트](/docs/ko/sub-agents#choose-the-subagent-scope), 또는 Claude Code가 자체 worktree에 격리하는 [백그라운드 세션](/docs/ko/agent-view#how-file-edits-are-isolated) 등 worktree가 생성될 때 실행됩니다. 기본적으로 Claude Code는 `git worktree`로 격리된 작업 사본을 만듭니다. WorktreeCreate 훅을 구성하면 이 기본 git 동작을 대체하므로 SVN, Perforce, Mercurial과 같은 다른 버전 관리 시스템을 사용할 수 있습니다.
3214 3216
3215훅이 기본 동작을 완전히 대체하므로 [`.worktreeinclude`](/docs/ko/worktrees#copy-gitignored-files-into-worktrees)는 처리되지 않습니다. `.env` 같은 로컬 설정 파일을 새 워크트리에 복사해야 하는 경우 훅 스크립트 안에서 수행합니다.3217훅이 기본 동작을 완전히 대체하므로 [`.worktreeinclude`](/docs/ko/worktrees#copy-gitignored-files-into-worktrees)는 처리되지 않습니다. `.env`와 같은 로컬 설정 파일을 새 워크트리로 복사해야 한다면 훅 스크립트 안에서 복사하십시오.
3216 3218
3217훅은 생성된 worktree 디렉터리의 경로를 반환해야 합니다. Claude Code는 이 경로를 격리된 세션의 작업 디렉터리로 사용합니다. 각 훅 유형이 경로를 반환하는 방법은 [WorktreeCreate 출력](#worktreecreate-output)을 참조하세요.3219훅은 생성된 worktree 디렉터리의 경로를 반환해야 합니다. Claude Code는 이 경로를 격리된 세션의 작업 디렉터리로 사용합니다. 각 훅 유형이 경로를 반환하는 방법은 [WorktreeCreate 출력](#worktreecreate-output)을 참조하십시오.
3218 3220
3219Claude Code는 훅의 성공 여부와 반환된 경로에 따라 동작하며, `systemMessage`와 `continue`는 삭제합니다.3221Claude Code는 훅의 성공 여부와 반환된 경로에 따라 동작하며, `systemMessage`와 `continue`는 버립니다.
3220 3222
3221이 예시는 SVN 작업 사본을 생성하고 Claude Code가 사용할 경로를 출력합니다. 저장소 URL을 자신의 것으로 바꿉니다.3223다음 예시는 SVN 작업 사본을 만들고 Claude Code가 사용할 경로를 출력합니다. 저장소 URL을 사용자의 URL로 바꾸십시오.
3222 3224
3223```json theme={null}3225```json theme={null}
3224{3226{
3237}3239}
3238```3240```
3239 3241
3240훅은 stdin의 JSON 입력에서 worktree `name`을 읽고, 새 디렉터리에 새 사본을 체크아웃한 다음, 디렉터리 경로를 출력합니다. 마지막 줄의 `echo`가 Claude Code가 worktree 경로로 읽는 부분입니다. 경로에 방해가 되지 않도록 다른 모든 출력은 stderr로 리디렉션합니다.3242이 훅은 stdin의 JSON 입력에서 worktree `name`을 읽고, 새 디렉터리에 새 사본을 체크아웃한 다음 디렉터리 경로를 출력합니다. 마지막 줄의 `echo`가 Claude Code가 worktree 경로로 읽는 부분입니다. 경로와 충돌하지 않도록 다른 출력은 모두 stderr로 리디렉션하십시오.
3241 3243
3242<h4 id="worktreecreate-input">3244<h4 id="worktreecreate-input">
3243 WorktreeCreate input3245 WorktreeCreate input
3244</h4>3246</h4>
3245 3247
3246[공통 입력 필드](#common-input-fields) 외에도, WorktreeCreate 훅은 `name` 필드를 전달받습니다. 이는 사용자가 지정하거나 자동 생성된 새 worktree의 슬러그 식별자로, 예를 들면 `bold-oak-a3f2`입니다.3248[공통 입력 필드](#common-input-fields)에 더해 WorktreeCreate 훅은 `name` 필드를 받습니다. 이는 사용자가 지정했거나 자동 생성된 새 worktree의 슬러그 식별자이며, 예를 들면 `bold-oak-a3f2`와 같습니다.
3247 3249
3248```json theme={null}3250```json theme={null}
3249{3251{
3256```3258```
3257 3259
3258<h4 id="worktreecreate-output">3260<h4 id="worktreecreate-output">
3259 WorktreeCreate 출력3261 WorktreeCreate output
3260</h4>3262</h4>
3261 3263
3262WorktreeCreate 훅은 표준 허용/차단 결정 모델을 사용하지 않습니다. 대신 훅의 성공 또는 실패가 결과를 결정합니다. 훅은 생성된 worktree 디렉터리의 경로를 반환해야 합니다.3264WorktreeCreate 훅은 표준 허용/차단 결정 모델을 사용하지 않습니다. 대신 훅의 성공 또는 실패가 결과를 결정합니다. 훅은 생성된 worktree 디렉터리의 경로를 반환해야 합니다.
3263 3265
3264* **명령 훅** (`type: "command"`): stdout의 비어 있지 않은 마지막 줄에 경로를 출력합니다. Claude Code는 해당 줄을 읽기 전에 ANSI 이스케이프 코드를 제거하므로 `echo` 이전에 출력된 셸 시작 배너는 무시됩니다. 그 밖의 훅 출력은 stderr로 리디렉션하십시오.3266* **명령 훅** (`type: "command"`): stdout의 비어 있지 않은 마지막 줄에 경로를 출력합니다. Claude Code는 해당 줄을 읽기 전에 ANSI 이스케이프 코드를 제거하므로 `echo` 전에 출력되는 셸 시작 배너는 무시됩니다. 훅의 다른 출력은 모두 stderr로 리디렉션하십시오.
3265* **HTTP 훅** (`type: "http"`): 응답 본문에 `{ "hookSpecificOutput": { "hookEventName": "WorktreeCreate", "worktreePath": "/absolute/path" } }`를 반환합니다.3267* **HTTP 훅** (`type: "http"`): 응답 본문에 `{ "hookSpecificOutput": { "hookEventName": "WorktreeCreate", "worktreePath": "/absolute/path" } }`를 반환합니다.
3266 3268
3267훅이 실패하거나 경로를 생성하지 않으면 worktree 생성이 오류와 함께 실패합니다.3269훅이 실패하거나 경로를 생성하지 않으면 worktree 생성이 오류와 함께 실패합니다.
3268 3270
3269Claude Code는 상대 경로를 훅이 실행된 디렉터리를 기준으로 해석하며, 경로에 포함된 `.` 또는 `..` 세그먼트를 정리합니다. 결과 경로가 Claude Code가 진입할 수 있는 디렉터리가 아니면 세션은 해당 경로를 명시한 오류를 출력하고 코드 1로 종료됩니다.3271Claude Code는 상대 경로를 훅이 실행된 디렉터리를 기준으로 해석하며, 경로 안의 `.` 또는 `..` 세그먼트를 정리합니다. 결과 경로가 Claude Code가 들어갈 수 있는 디렉터리가 아니면 세션은 해당 경로를 명시한 오류를 출력하고 코드 1로 종료됩니다.
3270 3272
3271Claude Code는 `.` 또는 `..` 세그먼트가 포함된 절대 경로와 저장소 루트 아래의 심볼릭 링크를 거치는 모든 경로를 거부합니다. 저장소에 커밋된 심볼릭 링크가 워크트리를 저장소 외부로 리디렉션할 수 있기 때문입니다. 오류 메시지에는 거부된 구성 요소가 명시됩니다. 저장소 내부의 심볼릭 링크를 거치지 않는 정규화된 경로를 반환하십시오. v2.1.216 이전에는 worktree 생성 시 이러한 검사 없이 훅의 경로를 그대로 따랐습니다.3273Claude Code는 `.` 또는 `..` 세그먼트가 포함된 절대 경로와 저장소 루트 아래의 심볼릭 링크를 거치는 모든 경로를 거부합니다. 저장소에 커밋된 심볼릭 링크가 worktree를 저장소 외부로 리디렉션할 수 있기 때문입니다. 오류 메시지에는 거부된 구성 요소가 표시됩니다. 저장소 내부의 심볼릭 링크를 거치지 않는 정규화된 경로를 반환하십시오. v2.1.216 이전에는 worktree 생성 시 이러한 검사 없이 훅의 경로를 그대로 따랐습니다.
3272 3274
3273<h3 id="worktreeremove">3275<h3 id="worktreeremove">
3274 WorktreeRemove3276 WorktreeRemove
3275</h3>3277</h3>
3276 3278
3277Claude Code가 [`WorktreeCreate`](#worktreecreate) 훅으로 생성된 worktree를 정리할 때 실행됩니다. 이 이벤트는 다음 경우에 발생합니다.3279Claude Code가 [`WorktreeCreate`](#worktreecreate) 훅으로 생성된 worktree를 정리할 때 실행됩니다. 이 이벤트는 다음과 같은 경우에 발생합니다.
3278 3280
3279* 대화형 [worktree 세션](/docs/ko/worktrees#start-claude-in-a-worktree)을 종료하면서 Claude Code가 확인을 요청할 때 worktree 제거를 선택한 경우3281* 대화형 [worktree 세션](/docs/ko/worktrees#start-claude-in-a-worktree)을 종료하고 Claude Code가 확인을 요청할 때 worktree 제거를 선택하는 경우
3280* [이름을 지정](/docs/ko/sessions#name-your-sessions)하지 않은 대화형 worktree 세션을 종료했을 때 Claude Code가 변경되었거나 추적되지 않는 파일을 찾지 못해 확인 요청 없이 worktree를 제거하는 경우3282* [이름을 지정](/docs/ko/sessions#name-your-sessions)하지 않은 대화형 worktree 세션을 종료하고, Claude Code가 변경되거나 추적되지 않는 파일을 찾지 못해 묻지 않고 worktree를 제거하는 경우
3281* 해당 worktree에서 실행되는 [백그라운드 세션](/docs/ko/agent-view#what-deleting-a-session-removes)을 삭제한 경우3283* worktree에서 실행되는 [백그라운드 세션](/docs/ko/agent-view#what-deleting-a-session-removes)을 삭제하는 경우
3282 3284
3283Claude Code는 git을 사용해 변경되었거나 추적되지 않는 파일을 찾으므로, git 체크아웃이 아니거나 git 체크아웃 내부에 있지 않은 worktree에서는 디렉터리에 커밋되지 않은 작업이 있더라도 아무것도 찾지 못합니다. WorktreeRemove 훅에서 무언가를 삭제하기 전에 그러한 작업이 있는지 확인하십시오.3285Claude Code는 git을 사용해 변경되거나 추적되지 않는 파일을 찾으므로, git 체크아웃이 아니거나 git 체크아웃 내부에 있지 않은 worktree에서는 디렉터리에 커밋되지 않은 작업이 있더라도 아무것도 찾지 못합니다. WorktreeRemove 훅에서 무언가를 삭제하기 전에 그러한 작업이 있는지 확인하십시오.
3284 3286
3285git 기반 worktree의 경우 Claude Code가 `git worktree remove`로 정리를 자동으로 처리합니다. WorktreeCreate 훅을 구성했다면 WorktreeRemove 훅과 함께 사용하여 해당 훅이 생성한 워크트리의 정리를 제어하십시오.3287git 기반 worktree의 경우 Claude Code는 `git worktree remove`로 정리를 자동 처리합니다. WorktreeCreate 훅을 구성했다면 WorktreeRemove 훅과 함께 사용하여 해당 훅이 생성한 워크트리의 정리를 제어하십시오.
3286 3288
3287* **WorktreeRemove 훅이 없는 경우**: worktree 세션을 종료하면서 Claude Code가 worktree를 제거할 때, WorktreeCreate 훅이 반환한 경로에 대해 `git worktree remove --force`로 폴백하므로 git이 인식하는 worktree는 제거됩니다. git이 인식하지 못하는 worktree(예: 훅이 git이 아닌 버전 관리 시스템으로 생성한 worktree)는 디스크에 남습니다. [백그라운드 세션](/docs/ko/agent-view#what-deleting-a-session-removes) 삭제 시 훅이 생성한 worktree가 어떻게 처리되는지는 에이전트 뷰의 삭제 규칙을 참조하십시오.3289* **WorktreeRemove 훅이 없는 경우**: worktree 세션을 종료하면서 Claude Code가 worktree를 제거할 때, WorktreeCreate 훅이 반환한 경로에 대해 `git worktree remove --force`로 폴백하므로 git이 인식하는 worktree는 제거됩니다. git이 인식하지 못하는 worktree, 예를 들어 훅이 git이 아닌 버전 관리 시스템으로 생성한 worktree는 디스크에 남습니다. [백그라운드 세션](/docs/ko/agent-view#what-deleting-a-session-removes)을 삭제할 때 훅으로 생성된 worktree가 어떻게 처리되는지는 에이전트 뷰의 삭제 규칙을 참조하십시오.
3288* **훅이 0으로 종료되는 경우**: 워크트리가 제거된 것으로 간주됩니다. Claude Code는 훅에서 다른 내용을 읽지 않으므로 훅이 디렉터리를 실제로 삭제했는지 확인하십시오.3290* **훅이 0으로 종료되는 경우**: worktree가 제거된 것으로 간주됩니다. Claude Code는 훅에서 다른 내용을 읽지 않으므로 훅이 디렉터리를 삭제했는지 확인하십시오.
3289* **훅이 0이 아닌 코드로 종료되는 경우**: 이후에도 `worktree_path`의 디렉터리가 여전히 존재하면 제거가 실패하고, 워크트리는 git 폴백 없이 디스크에 남습니다. 0이 아닌 코드로 종료하기 전에 디렉터리를 삭제한 훅은 제거된 것으로 간주됩니다. 실패가 보고되는 방식은 [WorktreeRemove 입력](#worktreeremove-input)을 참조하십시오.3291* **훅이 0이 아닌 코드로 종료되는 경우**: 이후에도 `worktree_path`의 디렉터리가 여전히 존재하면 제거가 실패하고, git 폴백 없이 worktree가 디스크에 남습니다. 0이 아닌 코드로 종료하기 전에 디렉터리를 삭제한 훅은 제거된 것으로 간주됩니다. 실패가 보고되는 방식은 [WorktreeRemove 입력](#worktreeremove-input)을 참조하십시오.
3290 3292
3291Claude Code는 WorktreeCreate 훅이 반환한 경로만 알기 때문에 훅이 생성한 워크트리에 속한 브랜치를 삭제하지 않습니다. WorktreeCreate 훅이 브랜치를 생성한다면 WorktreeRemove 훅에서 해당 브랜치를 삭제하십시오.3293Claude Code는 WorktreeCreate 훅이 반환한 경로만 알고 있으므로 훅으로 생성된 worktree에 속한 브랜치를 삭제하지 않습니다. WorktreeCreate 훅이 브랜치를 생성한다면 WorktreeRemove 훅에서 삭제하십시오.
3292 3294
3293Claude Code는 `systemMessage`, `continue` 등 WorktreeRemove 훅의 [JSON 출력 필드](#json-output)를 폐기합니다.3295Claude Code는 WorktreeRemove 훅의 `systemMessage`, `continue` 등 [JSON 출력 필드](#json-output)를 버립니다.
3294 3296
3295백그라운드 세션 삭제 시 Claude Code는 훅을 실행하기 전에 저장된 worktree 경로를 검증하며, 심볼릭 링크이거나 저장소 루트 아래의 심볼릭 링크를 거치는 경로를 거부합니다. 파일이 아직 남아 있는 워크트리에 대해서는 [에이전트 뷰](/docs/ko/agent-view#what-deleting-a-session-removes)에서 삭제를 확인한 경우에만 훅이 실행되며, 이러한 워크트리에 대해 [`claude rm`](/docs/ko/agent-view#manage-sessions-from-the-shell)은 세션과 워크트리를 그대로 유지합니다. v2.1.216 이전에는 이러한 검사 없이 저장된 경로에 대해 훅이 실행되었습니다.3297백그라운드 세션 삭제의 경우 Claude Code는 훅을 실행하기 전에 저장된 worktree 경로를 검증하며, 심볼릭 링크이거나 저장소 루트 아래의 심볼릭 링크를 거치는 경로를 거부합니다. 여전히 파일이 포함된 worktree에 대해서는 [에이전트 뷰](/docs/ko/agent-view#what-deleting-a-session-removes)에서 삭제를 확인한 경우에만 훅이 실행되며, 이러한 worktree에 대해 [`claude rm`](/docs/ko/agent-view#manage-sessions-from-the-shell)은 대신 세션과 worktree를 유지합니다. v2.1.216 이전에는 이러한 검사 없이 저장된 경로에 대해 훅이 실행되었습니다.
3296 3298
3297Claude Code는 WorktreeCreate가 반환한 경로를 훅 입력의 `worktree_path`로 전달합니다. 다음 예시는 해당 경로를 읽어 디렉터리를 제거합니다.3299Claude Code는 WorktreeCreate가 반환한 경로를 훅 입력의 `worktree_path`로 전달합니다. 다음 예시는 해당 경로를 읽고 디렉터리를 제거합니다.
3298 3300
3299```json theme={null}3301```json theme={null}
3300{3302{
3314```3316```
3315 3317
3316<h4 id="worktreeremove-input">3318<h4 id="worktreeremove-input">
3317 WorktreeRemove 입력3319 WorktreeRemove input
3318</h4>3320</h4>
3319 3321
3320[공통 입력 필드](#common-input-fields)에 더해 WorktreeRemove 훅은 제거되는 worktree의 절대 경로인 `worktree_path` 필드를 받습니다.3322[공통 입력 필드](#common-input-fields)에 더해 WorktreeRemove 훅은 제거되는 worktree의 절대 경로인 `worktree_path` 필드를 받습니다.
3331 3333
3332WorktreeRemove 훅의 종료 코드가 결과를 결정합니다. 훅이 0이 아닌 코드로 종료되고 이후에도 `worktree_path`의 디렉터리가 여전히 존재하면 제거가 실패합니다.3334WorktreeRemove 훅의 종료 코드가 결과를 결정합니다. 훅이 0이 아닌 코드로 종료되고 이후에도 `worktree_path`의 디렉터리가 여전히 존재하면 제거가 실패합니다.
3333 3335
3334* 워크트리는 디스크에 남고, 훅의 명령과 stderr는 [디버그 로그](#debug-hooks)에 기록됩니다.3336* worktree는 디스크에 남고, 훅의 명령과 stderr는 [디버그 로그](#debug-hooks)에 기록됩니다.
3335* 백그라운드 세션을 삭제하던 중이었다면 세션도 유지됩니다. [에이전트 뷰](/docs/ko/agent-view#what-deleting-a-session-removes)의 거부 메시지는 `exited 1`과 같이 훅이 어떻게 종료되었는지 보고하고, stderr의 앞부분을 인용하며, 세션을 다시 삭제하면 디렉터리가 그래도 제거되는지 여부를 알려줍니다.3337* 백그라운드 세션을 삭제하던 중이었다면 세션도 유지됩니다. [에이전트 뷰](/docs/ko/agent-view#what-deleting-a-session-removes)의 거부 메시지는 `exited 1`과 같이 훅이 어떻게 종료되었는지 보고하고, stderr의 앞부분을 인용하며, 세션을 다시 삭제하면 디렉터리가 어쨌든 제거되는지 여부를 알려 줍니다.
3336 3338
3337<h3 id="precompact">3339<h3 id="precompact">
3338 PreCompact3340 PreCompact
3345| Matcher | 실행 시점 |3347| Matcher | 실행 시점 |
3346| :- | :- |3348| :- | :- |
3347| `manual` | `/compact` |3349| `manual` | `/compact` |
3348| `auto` | 대화가 [자동 압축 윈도우](/docs/ko/model-config#set-the-auto-compact-window)에 도달하여 자동 압축될 때 |3350| `auto` | 대화가 [자동 압축 윈도우](/docs/ko/model-config#set-the-auto-compact-window)에 도달했을 때의 자동 압축 |
3349 3351
3350압축을 차단하려면 코드 2로 종료하십시오. 수동 `/compact`의 경우 stderr 메시지가 사용자에게 표시됩니다. `"decision": "block"`이 포함된 JSON을 반환하여 차단할 수도 있습니다.3352압축을 차단하려면 코드 2로 종료하십시오. 수동 `/compact`의 경우 stderr 메시지가 사용자에게 표시됩니다. `"decision": "block"`이 포함된 JSON을 반환하여 차단할 수도 있습니다.
3351 3353
3352자동 압축을 차단하면 실행 시점에 따라 효과가 달라집니다. 컨텍스트 한도에 도달하기 전에 선제적으로 압축이 트리거된 경우 Claude Code는 압축을 건너뛰고 대화는 압축되지 않은 상태로 계속됩니다. API가 이미 반환한 컨텍스트 한도 오류에서 복구하기 위해 압축이 트리거된 경우에는 원래 오류가 드러나고 현재 요청이 실패합니다.3354자동 압축을 차단하면 실행 시점에 따라 효과가 다릅니다. 컨텍스트 한도에 도달하기 전에 압축이 선제적으로 트리거된 경우 Claude Code는 압축을 건너뛰고 압축되지 않은 상태로 대화를 계속합니다. API가 이미 반환한 컨텍스트 한도 오류에서 복구하기 위해 압축이 트리거된 경우에는 원래 오류가 표시되고 현재 요청이 실패합니다.
3353 3355
3354Claude Code는 PreCompact 훅의 `systemMessage` 및 `continue` 필드를 폐기합니다.3356Claude Code는 PreCompact 훅의 `systemMessage` 및 `continue` 필드를 버립니다.
3355 3357
3356<h4 id="precompact-input">3358<h4 id="precompact-input">
3357 PreCompact 입력3359 PreCompact input
3358</h4>3360</h4>
3359 3361
3360[공통 입력 필드](#common-input-fields)에 더해 PreCompact 훅은 `trigger`와 `custom_instructions`를 받습니다. `manual`의 경우 `custom_instructions`에는 사용자가 `/compact`에 전달한 내용이 담기며, 아무것도 전달하지 않으면 `null`입니다. `auto`의 경우 `custom_instructions`는 `null`입니다.3362[공통 입력 필드](#common-input-fields)에 더해 PreCompact 훅은 `trigger`와 `custom_instructions`를 받습니다. `manual`의 경우 `custom_instructions`에는 사용자가 `/compact`에 전달한 내용이 포함되며, 아무것도 전달하지 않으면 `null`입니다. `auto`의 경우 `custom_instructions`는 `null`입니다.
3361 3363
3362```json theme={null}3364```json theme={null}
3363{3365{
3374 PostCompact3376 PostCompact
3375</h3>3377</h3>
3376 3378
3377Claude Code가 압축 작업을 완료한 후 실행됩니다. 새로 압축된 상태에 대응할 때 이 이벤트를 사용하십시오. 예를 들어 생성된 요약을 로그에 기록하거나 외부 상태를 업데이트할 수 있습니다. Claude Code는 PostCompact 훅의 `systemMessage` 및 `continue` 필드를 폐기합니다.3379Claude Code가 압축 작업을 완료한 후 실행됩니다. 이 이벤트를 사용하면 새로 압축된 상태에 대응할 수 있습니다. 예를 들어 생성된 요약을 로그에 기록하거나 외부 상태를 업데이트할 수 있습니다. Claude Code는 PostCompact 훅의 `systemMessage` 및 `continue` 필드를 버립니다.
3378 3380
3379`PreCompact`와 동일한 matcher 값이 적용됩니다.3381`PreCompact`와 동일한 matcher 값이 적용됩니다.
3380 3382
3384| `auto` | 대화가 [자동 압축 윈도우](/docs/ko/model-config#set-the-auto-compact-window)에 도달하여 자동 압축된 이후 |3386| `auto` | 대화가 [자동 압축 윈도우](/docs/ko/model-config#set-the-auto-compact-window)에 도달하여 자동 압축된 이후 |
3385 3387
3386<h4 id="postcompact-input">3388<h4 id="postcompact-input">
3387 PostCompact 입력3389 PostCompact input
3388</h4>3390</h4>
3389 3391
3390[공통 입력 필드](#common-input-fields)에 더해 PostCompact 훅은 `trigger`와 `compact_summary`를 받습니다. `compact_summary` 필드에는 압축 작업으로 생성된 대화 요약이 담깁니다.3392[공통 입력 필드](#common-input-fields)에 더해 PostCompact 훅은 `trigger`와 `compact_summary`를 받습니다. `compact_summary` 필드에는 압축 작업으로 생성된 대화 요약이 포함됩니다.
3391 3393
3392```json theme={null}3394```json theme={null}
3393{3395{
3406 PreModelSwitch3408 PreModelSwitch
3407</h3>3409</h3>
3408 3410
3409사용자나 클라이언트가 요청한 모델 전환을 Claude Code가 적용하기 전에 실행됩니다. 전환을 차단하거나, 확인을 요구하거나, 전환이 일어나기 전에 전환 비용을 표시하는 데 사용하십시오.3411사용자나 클라이언트가 요청한 모델 전환을 Claude Code가 적용하기 전에 실행됩니다. 전환을 차단하거나, 확인을 요구하거나, 전환이 일어나기 전에 전환 비용을 보여 주는 데 사용할 수 있습니다.
3410 3412
3411PreModelSwitch를 사용하려면 Claude Code v2.1.251 이상이 필요합니다. Claude Code는 다음 요청에 대해 이 훅을 실행합니다.3413PreModelSwitch를 사용하려면 Claude Code v2.1.251 이상이 필요합니다. Claude Code는 다음 요청에 대해 이 훅을 실행합니다.
3412 3414
3413* `/model <name>` 및 `/model` 선택기3415* `/model <name>` 및 `/model` 선택기
3414* `Option+P` 또는 `Alt+P` 모델 선택기3416* `Option+P` 또는 `Alt+P` 모델 선택기
3415* `/config`의 Model 설정3417* `/config`의 Model 설정
3416* [빠른 모드](/docs/ko/fast-mode)를 켜서 세션의 모델이 변경되는 경우3418* 세션의 모델을 변경하는 경우의 [빠른 모드](/docs/ko/fast-mode) 켜기
3417* [Agent SDK](/docs/ko/agent-sdk/typescript#query-object) 호스트 또는 [Remote Control](/docs/ko/remote-control)에서 보낸 `set_model` 요청이나 `apply_flag_settings` 요청 내의 모델 변경3419* [Agent SDK](/docs/ko/agent-sdk/typescript#query-object) 호스트 또는 [Remote Control](/docs/ko/remote-control)에서 보낸 `set_model` 요청 또는 `apply_flag_settings` 요청의 모델 변경
3418 3420
3419[자동 모델 폴백](/docs/ko/model-config#automatic-model-fallback)이나 세션을 재개할 때의 모델 복원처럼 Claude Code가 자체적으로 수행하는 전환에 대해서는 PreModelSwitch 훅을 실행하지 않습니다. 이러한 변경은 [PostModelSwitch](#postmodelswitch)에만 전달됩니다.3421Claude Code는 [자동 모델 폴백](/docs/ko/model-config#automatic-model-fallback)이나 세션 재개 시 모델 복원처럼 자체적으로 수행하는 전환에 대해서는 PreModelSwitch 훅을 실행하지 않습니다. 이러한 변경은 [PostModelSwitch](#postmodelswitch)에만 전달됩니다.
3420 3422
3421Claude Code는 `[1m]` 접미사를 무시하고 세션이 전환하려는 모델의 정식 이름과 matcher를 비교합니다. `opus` 같은 별칭, 날짜가 포함된 모델 ID, Amazon Bedrock 모델 ID 같은 공급자별 ID는 모두 해석되는 하나의 정식 이름과 일치하므로, `claude-opus-5`는 Opus 5의 모든 표기를 포괄합니다.3423Claude Code는 `[1m]` 접미사를 무시하고, 세션이 전환하려는 모델의 정식 이름과 matcher를 비교합니다. `opus`와 같은 별칭, 날짜가 포함된 모델 ID, Amazon Bedrock 모델 ID와 같은 공급자별 ID는 모두 해석되는 하나의 정식 이름과 일치하므로 `claude-opus-5`는 Opus 5의 모든 표기를 포괄합니다.
3422 3424
3423대상의 정식 이름을 확인할 수 없는 경우(예: [LLM 게이트웨이](/docs/ko/llm-gateway)만 알고 있는 사용자 지정 모델 ID) Claude Code는 matcher와 관계없이 모든 PreModelSwitch 훅을 실행합니다. 따라서 차단하는 훅은 matcher에만 의존하지 말고 입력의 `to_model`을 확인해야 합니다.3425예를 들어 사용자의 [LLM 게이트웨이](/docs/ko/llm-gateway)만 알고 있는 사용자 지정 모델 ID처럼 Claude Code가 대상의 정식 이름을 확인할 수 없는 경우, matcher와 관계없이 모든 PreModelSwitch 훅을 실행합니다. 따라서 차단하는 훅은 matcher에만 의존하지 말고 입력의 `to_model`을 확인해야 합니다.
3424 3426
3425matcher는 정확한 이름, `claude-opus-4-6|claude-opus-5`처럼 `|`로 구분된 목록, 또는 `.*opus.*` 같은 정규식으로 작성합니다. 다음 예시는 정확한 이름 matcher를 사용하면서 훅 입력의 `to_model`도 확인하여, Opus 4.6으로의 전환은 코드 2로 종료하여 거부하고 다른 대상은 허용합니다.3427matcher는 정확한 이름, `claude-opus-4-6|claude-opus-5`와 같이 `|`로 구분된 목록, 또는 `.*opus.*`와 같은 정규 표현식으로 작성합니다. 다음 예시는 정확한 이름 matcher를 사용하는 동시에 훅 입력의 `to_model`도 확인하므로, 코드 2로 종료하여 Opus 4.6으로의 전환을 거부하고 다른 대상은 허용합니다.
3426 3428
3427<Tabs>3429<Tabs>
3428 <Tab title="macOS/Linux">3430 <Tab title="macOS/Linux">
3429 명령은 `jq`로 `to_model`을 확인합니다.3431 이 명령은 `jq`로 `to_model`을 확인합니다.
3430 3432
3431 ```json theme={null}3433 ```json theme={null}
3432 {3434 {
3475 }3477 }
3476 ```3478 ```
3477 3479
3478 다음 스크립트를 프로젝트의 `.claude/hooks/block-opus-46.ps1`에 저장합니다.3480 이 스크립트를 프로젝트의 `.claude/hooks/block-opus-46.ps1`에 저장합니다.
3479 3481
3480 ```powershell theme={null}3482 ```powershell theme={null}
3481 $hookInput = [Console]::In.ReadToEnd() | ConvertFrom-Json3483 $hookInput = [Console]::In.ReadToEnd() | ConvertFrom-Json
3488 </Tab>3490 </Tab>
3489</Tabs>3491</Tabs>
3490 3492
3491훅이 작동하는지 확인하려면 다른 모델을 실행 중인 세션에서 `/model claude-opus-4-6`을 실행하십시오. Claude Code는 현재 모델을 유지하고, PreModelSwitch 훅이 전환을 차단했다고 사용자의 메시지를 사유로 함께 보고합니다.3493훅이 작동하는지 확인하려면 다른 모델을 실행 중인 세션에서 `/model claude-opus-4-6`을 실행하십시오. Claude Code는 현재 모델을 유지하고, PreModelSwitch 훅이 전환을 차단했다는 사실을 사용자의 메시지를 사유로 하여 보고합니다.
3492 3494
3493<h4 id="premodelswitch-input">3495<h4 id="premodelswitch-input">
3494 PreModelSwitch 입력3496 PreModelSwitch input
3495</h4>3497</h4>
3496 3498
3497[공통 입력 필드](#common-input-fields)에 더해 PreModelSwitch 훅은 다음 표의 필드를 받습니다. 마지막 다섯 개 필드는 대화를 새 모델로 다시 전송하는 비용을 나타내므로, 훅은 전환이 일어나기 전에 해당 수치를 표시할 수 있습니다.3499[공통 입력 필드](#common-input-fields)에 더해 PreModelSwitch 훅은 이 표의 필드를 받습니다. 마지막 다섯 개 필드는 대화를 새 모델로 다시 보내는 비용을 설명하므로 훅이 전환 전에 해당 수치를 보여 줄 수 있습니다.
3498 3500
3499| 필드 | 타입 | 설명 |3501| 필드 | 유형 | 설명 |
3500| :- | :- | :- |3502| :- | :- | :- |
3501| `from_model` | string | 전환 전 모델 ID |3503| `from_model` | string | 전환 이전의 모델 ID |
3502| `to_model` | string | 전환 후 모델 ID. matcher는 이 모델의 정식 이름과 비교됩니다 |3504| `to_model` | string | 전환 대상 모델 ID. matcher는 이 모델의 정식 이름과 비교됩니다 |
3503| `requested_model` | string 또는 `null` | 요청에서 지정한 모델: `opus` 같은 별칭, 전체 모델 ID, 또는 기본 모델을 요청한 경우 `null` |3505| `requested_model` | string 또는 `null` | 요청에서 지정한 모델: `opus`와 같은 별칭, 전체 모델 ID, 또는 기본 모델을 요청한 경우 `null` |
3504| `source` | string | 요청의 출처: `/model <name>`, `/config`의 Model 설정, 빠른 모드 켜기의 경우 `"command"`, 모델 선택기의 경우 `"picker"`, Agent SDK 호스트 또는 Remote Control에서 보낸 `set_model` 요청이나 `apply_flag_settings` 요청 내 모델 변경의 경우 `"sdk"` |3506| `source` | string | 요청 출처: `/model <name>`, `/config`의 Model 설정, 빠른 모드 켜기는 `"command"`, 모델 선택기는 `"picker"`, Agent SDK 호스트 또는 Remote Control에서 보낸 `set_model` 요청이나 `apply_flag_settings` 요청의 모델 변경은 `"sdk"` |
3505| `context_tokens` | number | 다음 요청이 프롬프트로 다시 전송하는 토큰: 메인 대화의 마지막 응답에 대한 입력, 캐시 읽기, 캐시 생성, 출력 토큰의 합계. 첫 번째 응답 전에는 `0` |3507| `context_tokens` | number | 다음 요청이 프롬프트로 다시 보내는 토큰 수: 메인 대화의 마지막 응답의 입력, 캐시 읽기, 캐시 생성, 출력 토큰을 합한 값. 첫 응답 이전에는 `0` |
3506| `prompt_cache_warm` | boolean | 현재 모델의 프롬프트 캐시가 아직 활성 상태일 가능성이 높은지 여부. 즉 전환 시 해당 캐시를 잃게 됨을 의미합니다 |3508| `prompt_cache_warm` | boolean | 현재 모델의 프롬프트 캐시가 아직 유효할 가능성이 높은지 여부. 즉, 전환 시 이를 잃게 됨을 의미합니다 |
3507| `cache_ttl` | string | Claude Code가 이 세션에 요청하는 [프롬프트 캐시 수명](/docs/ko/prompt-caching#cache-lifetime): `"5m"` 또는 `"1h"` |3509| `cache_ttl` | string | Claude Code가 이 세션에 요청하는 [프롬프트 캐시 수명](/docs/ko/prompt-caching#cache-lifetime): `"5m"` 또는 `"1h"` |
3508| `estimated_cache_write_usd` | number | `to_model`에서 `cache_ttl` 요율로 `context_tokens`를 프롬프트 캐시에 쓰는 예상 비용(미국 달러)이며, 다음 응답은 제외됩니다. 서버가 전체 컨텍스트를 다시 캐시할 필요가 없을 수 있으므로 추정치로 취급하십시오 |3510| `estimated_cache_write_usd` | number | `cache_ttl` 요율로 `to_model`의 프롬프트 캐시에 `context_tokens`를 쓰는 추정 비용(미국 달러), 다음 응답은 제외. 서버가 전체 컨텍스트를 다시 캐시할 필요가 없을 수도 있으므로 추정치로 취급하십시오 |
3509| `pricing` | string | Claude Code가 `estimated_cache_write_usd`를 산정한 방식: 조직이 자체 요율을 구성한 경우 해당 요율로 산정한 `"configured"`, 정가로 산정한 `"catalog"`, 또는 `to_model`의 가격을 알 수 없어 Claude Code가 기본 요율을 가정한 경우 `"default"` |3511| `pricing` | string | Claude Code가 `estimated_cache_write_usd`를 산정한 방식: 조직이 자체 요율을 구성한 경우 해당 요율로 산정한 `"configured"`, 정가로 산정한 `"catalog"`, 또는 `to_model`의 가격을 알 수 없어 Claude Code가 기본 요율을 가정한 `"default"` |
3510 3512
3511다음 예시는 Sonnet 5를 실행 중인 세션에서 `/model opus`를 실행했을 때의 입력을 보여 줍니다.3513다음 예시는 Sonnet 5를 실행 중인 세션에서 `/model opus`를 실행했을 때의 입력을 보여 줍니다.
3512 3514
3529```3531```
3530 3532
3531<h4 id="premodelswitch-decision-control">3533<h4 id="premodelswitch-decision-control">
3532 PreModelSwitch 결정 제어3534 PreModelSwitch decision control
3533</h4>3535</h4>
3534 3536
3535`PreModelSwitch` 훅은 전환을 취소하거나, 사용자에게 확인을 요청하거나, 전환을 진행하도록 할 수 있습니다. 종료 코드 2 또는 최상위 `decision: "block"`은 전환을 취소합니다.3537`PreModelSwitch` 훅은 전환을 취소하거나, 사용자에게 확인을 요청하거나, 진행하도록 허용할 수 있습니다. 종료 코드 2 또는 최상위 `decision: "block"`은 전환을 취소합니다.
3536 3538
3537더 세밀하게 제어하려면 [PreToolUse](#pretooluse-decision-control)와 마찬가지로 `hookSpecificOutput` 객체에 `permissionDecision`과 `permissionDecisionReason`을 반환하십시오. `PreModelSwitch`는 `"allow"`, `"deny"`, `"ask"`를 허용합니다. `"defer"`, `updatedInput`, `additionalContext`는 허용하지 않습니다. 아래 표는 두 필드를 설명합니다.3539더 세밀하게 제어하려면 [PreToolUse](#pretooluse-decision-control)에서와 같이 `hookSpecificOutput` 객체에 `permissionDecision`과 `permissionDecisionReason`을 반환하십시오. `PreModelSwitch`는 `"allow"`, `"deny"`, `"ask"`를 허용합니다. `"defer"`, `updatedInput`, `additionalContext`는 허용하지 않습니다. 아래 표는 두 필드를 설명합니다.
3538 3540
3539| 필드 | 설명 |3541| 필드 | 설명 |
3540| :- | :- |3542| :- | :- |
3541| `permissionDecision` | `"allow"`는 전환을 진행하며 [프롬프트 캐시가 활성 상태일 때 Claude Code가 표시하는 확인](/docs/ko/prompt-caching#switching-models)을 건너뜁니다. `"deny"`는 전환을 취소합니다. `"ask"`는 사용자에게 확인을 요청합니다 |3543| `permissionDecision` | `"allow"`는 전환을 진행하며 [프롬프트 캐시가 유효한 동안 Claude Code가 표시하는 확인](/docs/ko/prompt-caching#switching-models)을 건너뜁니다. `"deny"`는 전환을 취소합니다. `"ask"`는 사용자에게 확인을 요청합니다 |
3542| `permissionDecisionReason` | `"deny"`의 경우 전환이 차단된 사유로 사용자에게 표시되거나, `set_model` 요청에 대한 오류로 반환됩니다. `"ask"`의 경우 확인 프롬프트에 표시됩니다. `"allow"`의 경우 무시됩니다 |3544| `permissionDecisionReason` | `"deny"`의 경우 전환이 차단된 사유로 사용자에게 표시되거나 `set_model` 요청에 대한 오류로 반환됩니다. `"ask"`의 경우 확인 프롬프트에 표시됩니다. `"allow"`의 경우 무시됩니다 |
3543 3545
3544`"ask"` 프롬프트는 대화형 세션의 `/model`에서만 표시될 수 있습니다. `-p` 플래그를 사용한 비대화형 모드, `/config`, `set_model` 요청을 포함한 다른 모든 사용 환경에서 Claude Code는 `"ask"`를 거부로 취급합니다.3546대화형 세션의 `/model`만 `"ask"` 프롬프트를 표시할 수 있습니다. `-p` 플래그를 사용하는 비대화형 모드, `/config`, `set_model` 요청을 포함한 다른 모든 사용 환경에서 Claude Code는 `"ask"`를 거부로 처리합니다.
3545 3547
3546다음 예시는 사용자에게 확인을 요청하며 `context_tokens`의 토큰 수를 인용합니다.3548다음 예시는 사용자에게 확인을 요청하며 `context_tokens`의 토큰 수를 인용합니다.
3547 3549
3559 3561
3560Claude Code는 결정과 관계없이 훅이 반환한 `systemMessage`를 사용자에게 표시하므로, 비용 보고 훅은 `{"systemMessage": "..."}`를 반환하고 0으로 종료할 수 있습니다.3562Claude Code는 결정과 관계없이 훅이 반환한 `systemMessage`를 사용자에게 표시하므로, 비용 보고 훅은 `{"systemMessage": "..."}`를 반환하고 0으로 종료할 수 있습니다.
3561 3563
3562타임아웃 전에 응답하지 않는 PreModelSwitch 훅은 전환을 차단합니다. 반면 [PreToolUse](#timeouts)에서는 시간 초과된 명령 훅이 도구 호출을 계속 진행시킵니다. 이 이벤트의 기본 타임아웃은 30초입니다. `PreModelSwitch`는 `command`, `http`, `mcp_tool` 훅만 실행하므로 `prompt` 및 `agent` 기본값은 적용되지 않습니다.3564타임아웃 전에 응답하지 않는 PreModelSwitch 훅은 전환을 차단합니다. 반면 [PreToolUse](#timeouts)에서는 시간 초과된 명령 훅이 도구 호출을 계속 진행하도록 허용합니다. 이 이벤트의 기본 타임아웃은 30초입니다. `PreModelSwitch`는 `command`, `http`, `mcp_tool` 훅만 실행하므로 `prompt` 및 `agent`의 기본값은 적용되지 않습니다.
3563 3565
35640 또는 2가 아닌 코드로 종료하고 JSON 결정을 출력하지 않는 훅은 차단하지 않습니다. [기타 종료 코드](#other-exit-codes)에 설명된 대로 Claude Code는 해당 훅의 stderr를 표시하고 전환을 적용합니다.35660이나 2가 아닌 코드로 종료하고 JSON 결정을 출력하지 않는 훅은 차단하지 않습니다. [기타 종료 코드](#other-exit-codes)에서 설명한 대로 Claude Code는 stderr를 표시하고 전환을 적용합니다.
3565 3567
3566<h3 id="postmodelswitch">3568<h3 id="postmodelswitch">
3567 PostModelSwitch3569 PostModelSwitch
3568</h3>3570</h3>
3569 3571
3570세션의 모델이 변경된 후 실행됩니다. 모든 CLAUDE.md를 편집하지 않고도 Claude에게 모델별 지침을 제공하는 데 사용하십시오. 예를 들어 특정 모델에 적용되는 조직 전체 지침을 제공할 수 있습니다.3572세션의 모델이 변경된 후 실행됩니다. 모든 CLAUDE.md를 편집하지 않고도 Claude에게 모델별 지침을 제공하는 데 사용할 수 있습니다. 예를 들어 특정 모델에 적용되는 조직 전체 지침을 제공할 수 있습니다.
3571 3573
3572PostModelSwitch를 사용하려면 Claude Code v2.1.251 이상이 필요합니다. 모델이 이미 변경된 상태이므로 차단할 수 없습니다. Claude Code는 다음 변경 이후 PostModelSwitch 훅을 실행합니다.3574PostModelSwitch를 사용하려면 Claude Code v2.1.251 이상이 필요합니다. 모델이 이미 변경되었으므로 차단할 수 없습니다. Claude Code는 다음 변경 후에 PostModelSwitch 훅을 실행합니다.
3573 3575
3574* 사용자나 클라이언트가 요청한 전환3576* 사용자나 클라이언트가 요청한 전환
3575* 세션의 모델을 변경하는 [자동 모델 폴백](/docs/ko/model-config#automatic-model-fallback)3577* 세션의 모델을 변경하는 [자동 모델 폴백](/docs/ko/model-config#automatic-model-fallback)
3576* [`opusplan`](/docs/ko/model-config#opusplan-model-setting) 같은 설정이 플랜 모드에 진입하거나 플랜 모드를 벗어나는 경우3578* [`opusplan`](/docs/ko/model-config#opusplan-model-setting)과 같은 설정이 플랜 모드에 들어가거나 나가는 경우
3577* 세션을 재개할 때 Claude Code가 모델을 복원하는 경우3579* 세션을 재개할 때 Claude Code가 모델을 복원하는 경우
3578 3580
3579[대체 모델 체인](/docs/ko/model-config#fallback-model-chains)의 모델이 턴을 처리하는 경우에는 PostModelSwitch 훅을 실행하지 않습니다. 이러한 대체는 한 턴 동안만 유지되며 세션의 모델은 변경되지 않기 때문입니다.3581[폴백 모델 체인](/docs/ko/model-config#fallback-model-chains)의 모델이 턴을 처리하는 경우에는 Claude Code가 PostModelSwitch 훅을 실행하지 않습니다. 이 대체는 한 턴 동안만 지속되며 세션의 모델을 변경하지 않기 때문입니다.
3580 3582
3581matcher는 [PreModelSwitch](#premodelswitch)와 동일한 규칙을 따릅니다. Claude Code는 세션이 전환된 모델의 정식 이름과 matcher를 비교합니다.3583matcher는 [PreModelSwitch](#premodelswitch)와 동일한 규칙을 따릅니다. Claude Code는 세션이 전환한 모델의 정식 이름과 matcher를 비교합니다.
3582 3584
3583다음 예시는 세션의 모델이 Opus 모델로 변경될 때마다 지침을 추가합니다.3585다음 예시는 세션의 모델이 Opus 모델로 변경될 때마다 지침을 추가합니다.
3584 3586
3600}3602}
3601```3603```
3602 3604
3603훅이 작동하는지 확인하려면 다른 모델을 실행 중인 세션에서 Opus 모델로 전환한 다음(예: Sonnet 세션에서 `/model opus` 실행), Claude에게 현재 모델에 대해 어떤 지침을 받았는지 물어보십시오.3605훅이 작동하는지 확인하려면 다른 모델을 실행 중인 세션에서 Opus 모델로 전환한 다음(예: Sonnet 세션에서 `/model opus` 실행), Claude에게 현재 모델에 관해 어떤 지침을 갖고 있는지 물어보십시오.
3604 3606
3605<h4 id="postmodelswitch-input">3607<h4 id="postmodelswitch-input">
3606 PostModelSwitch 입력3608 PostModelSwitch input
3607</h4>3609</h4>
3608 3610
3609PostModelSwitch 훅은 [PreModelSwitch](#premodelswitch-input)와 동일한 필드를 받으며, `hook_event_name`은 `"PostModelSwitch"`로 설정되고 `source` 값이 두 가지 추가됩니다. 자동 폴백 또는 Claude Code가 자체적으로 수행한 기타 변경의 경우 `"auto"`, 세션을 재개할 때 복원된 모델의 경우 `"resume"`입니다.3611PostModelSwitch 훅은 [PreModelSwitch](#premodelswitch-input)와 동일한 필드를 받으며, `hook_event_name`은 `"PostModelSwitch"`로 설정되고 `source` 값이 두 가지 더 있습니다. 자동 폴백이나 Claude Code가 자체적으로 수행한 기타 변경의 경우 `"auto"`, 세션을 재개할 때 복원된 모델의 경우 `"resume"`입니다.
3610 3612
3611`source`가 `"auto"`이면 `requested_model`은 `null`입니다. `source`가 `"resume"`이면 Claude Code가 복원한 저장된 모델 설정입니다.3613`source`가 `"auto"`이면 `requested_model`은 `null`입니다. `source`가 `"resume"`이면 Claude Code가 복원한 저장된 모델 설정입니다.
3612 3614
3613<h4 id="postmodelswitch-decision-control">3615<h4 id="postmodelswitch-decision-control">
3614 PostModelSwitch 결정 제어3616 PostModelSwitch decision control
3615</h4>3617</h4>
3616 3618
3617Claude Code는 종료 코드 0일 때 훅의 [일반 텍스트 stdout](#exit-code-0) 또는 JSON 출력의 `additionalContext`를 가져와 전환 이후의 다음 요청과 함께 Claude에게 전달합니다. 모든 훅에서 사용할 수 있는 [JSON 출력 필드](#json-output)에 더해 다음을 반환할 수 있습니다.3619Claude Code는 종료 코드 0일 때 훅의 [일반 텍스트 stdout](#exit-code-0) 또는 JSON 출력의 `additionalContext`를 가져와 전환 후 다음 요청과 함께 Claude에게 전달합니다. 모든 훅에서 사용할 수 있는 [JSON 출력 필드](#json-output)에 더해 다음을 반환할 수 있습니다.
3618 3620
3619| 필드 | 설명 |3621| 필드 | 설명 |
3620| :- | :- |3622| :- | :- |
3621| `additionalContext` | 다음 요청과 함께 Claude의 컨텍스트에 추가되는 문자열. [Claude에 컨텍스트 추가](#add-context-for-claude)를 참조하십시오 |3623| `additionalContext` | 다음 요청과 함께 Claude의 컨텍스트에 추가되는 문자열. [Claude에 컨텍스트 추가](#add-context-for-claude)를 참조하십시오 |
3622 3624
3623다음 프롬프트를 보낸 후 5초 이내에 훅이 완료되지 않으면 Claude Code는 출력 없이 해당 요청을 보내고, 대신 그다음 요청에 출력을 첨부합니다. 다음 요청 전에 모델이 여러 번 변경되면 Claude Code는 마지막 전환의 대상 모델에 대한 출력만 전달합니다.3625다음 프롬프트를 보낸 후 5초 이내에 훅이 완료되지 않으면 Claude Code는 출력 없이 해당 요청을 보내고 대신 그다음 요청에 출력을 첨부합니다. 다음 요청 전에 모델이 여러 번 변경되면 Claude Code는 마지막 전환의 대상 모델에 대한 출력만 전달합니다.
3624 3626
3625<h3 id="sessionend">3627<h3 id="sessionend">
3626 SessionEnd3628 SessionEnd
3627</h3>3629</h3>
3628 3630
3629Claude Code 세션이 종료될 때 실행됩니다. 정리 작업, 세션 통계 로깅,3631Claude Code 세션이 종료될 때 실행됩니다. 정리 작업, 세션
3630세션 상태 저장에 유용합니다. 종료 사유로 필터링하는 matcher를 지원합니다.3632통계 로깅, 세션 상태 저장에 유용합니다. 종료 사유로 필터링하는 matcher를 지원합니다.
3631 3633
3632훅 입력의 `reason` 필드는 세션이 종료된 이유를 나타냅니다.3634훅 입력의 `reason` 필드는 세션이 종료된 이유를 나타냅니다.
3633 3635
3634| 사유 | 설명 |3636| 사유 | 설명 |
3635| :- | :- |3637| :- | :- |
3636| `clear` | `/clear` 명령으로 세션이 지워짐 |3638| `clear` | `/clear` 명령으로 세션이 지워짐 |
3637| `resume` | 대화형 `/resume`으로 세션이 전환됨 |3639| `resume` | 대화형 `/resume`을 통해 세션이 전환됨 |
3638| `logout` | 사용자가 로그아웃함 |3640| `logout` | 사용자가 로그아웃함 |
3639| `prompt_input_exit` | 프롬프트 입력이 표시된 상태에서 사용자가 종료함 |3641| `prompt_input_exit` | 프롬프트 입력이 표시된 상태에서 사용자가 종료함 |
3640| `other` | 기타 종료 사유 |3642| `other` | 기타 종료 사유 |
3641| `bypass_permissions_disabled` | v2.1.234에서 제거되었으며 Claude Code는 이 값을 보내지 않습니다. `SessionEnd` matcher에서 제거하십시오 |3643| `bypass_permissions_disabled` | v2.1.234에서 제거되었으며 Claude Code는 이를 보내지 않습니다. `SessionEnd` matcher에서 제거하십시오 |
3642 3644
3643<h4 id="sessionend-input">3645<h4 id="sessionend-input">
3644 SessionEnd 입력3646 SessionEnd input
3645</h4>3647</h4>
3646 3648
3647[공통 입력 필드](#common-input-fields)에 더해 SessionEnd 훅은 세션이 종료된 이유를 나타내는 `reason` 필드를 받습니다. 모든 값은 위의 [사유 표](#sessionend)를 참조하십시오.3649[공통 입력 필드](#common-input-fields)에 더해 SessionEnd 훅은 세션이 종료된 이유를 나타내는 `reason` 필드를 받습니다. 모든 값은 위의 [사유 표](#sessionend)를 참조하십시오.
3656}3658}
3657```3659```
3658 3660
3659SessionEnd 훅에는 결정 제어 기능이 없습니다. 세션 종료를 차단할 수는 없지만 정리 작업을 수행할 수 있습니다. Claude Code는 `systemMessage` 등 이 훅의 [JSON 출력 필드](#json-output)를 폐기합니다.3661SessionEnd 훅에는 결정 제어 기능이 없습니다. 세션 종료를 차단할 수는 없지만 정리 작업을 수행할 수 있습니다. Claude Code는 `systemMessage` 등 해당 훅의 [JSON 출력 필드](#json-output)를 버립니다.
3660 3662
3661SessionEnd 훅의 기본 타임아웃은 1.5초입니다. 이는 종료할 때, `/clear`를 실행할 때, 대화형 `/resume`으로 세션을 전환할 때 적용됩니다. 훅에 더 많은 시간을 주는 방법은 두 가지입니다.3663SessionEnd 훅의 기본 타임아웃은 1.5초입니다. 이는 종료하거나, `/clear`를 실행하거나, 대화형 `/resume`으로 세션을 전환할 때 적용됩니다. 훅에 더 많은 시간을 주는 방법은 두 가지입니다.
3662 3664
3663* **훅별 `timeout`**: 해당 훅의 구성에 `timeout`을 설정합니다. 전체 예산은 설정 파일에 있는 가장 높은 훅별 `timeout`에 맞춰 최대 60초까지 자동으로 늘어납니다. 이 방식으로 예산을 늘려도 자체 `timeout`이 없는 훅은 여전히 기본값을 유지합니다. 플러그인이 제공하는 훅에 설정된 타임아웃은 예산을 늘리지 않습니다.3665* **훅별 `timeout`**: 해당 훅의 구성에서 `timeout`을 설정합니다. 전체 예산은 설정 파일에 있는 가장 높은 훅별 `timeout`에 맞춰 최대 60초까지 자동으로 늘어납니다. 이 방법으로 예산을 늘리더라도 자체 `timeout`이 없는 훅은 여전히 기본값을 유지합니다. 플러그인이 제공하는 훅에 설정된 타임아웃은 예산을 늘리지 않습니다.
3664* **`CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS`**: 이 환경 변수를 밀리초 단위로 설정하여 예산을 명시적으로 재정의합니다. 설정한 값은 자체 `timeout`이 없는 각 훅의 타임아웃으로도 사용됩니다.3666* **`CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS`**: 이 환경 변수를 밀리초 단위로 설정하여 예산을 명시적으로 재정의합니다. 설정한 값은 자체 `timeout`이 없는 각 훅의 타임아웃이 되기도 합니다.
3665 3667
3666다음 예시는 예산을 5초로 설정합니다.3668다음 예시는 예산을 5초로 설정합니다.
3667 3669
3677 3679
3678MCP 서버가 작업 도중 사용자 입력을 요청할 때 실행됩니다. 기본적으로 Claude Code는 사용자가 응답할 수 있는 대화형 대화 상자를 표시합니다. 훅은 이 요청을 가로채 프로그래밍 방식으로 응답하여 대화 상자를 완전히 건너뛸 수 있습니다.3680MCP 서버가 작업 도중 사용자 입력을 요청할 때 실행됩니다. 기본적으로 Claude Code는 사용자가 응답할 수 있는 대화형 대화 상자를 표시합니다. 훅은 이 요청을 가로채 프로그래밍 방식으로 응답하여 대화 상자를 완전히 건너뛸 수 있습니다.
3679 3681
3682설정 항목과 스크립트를 포함한 완전한 훅은 [스크립트에서 양식 요청에 응답하기](#answer-a-form-request-from-a-script)를 참조하십시오.
3683
3680matcher 필드는 MCP 서버 이름과 비교됩니다.3684matcher 필드는 MCP 서버 이름과 비교됩니다.
3681 3685
3682<h4 id="elicitation-input">3686<h4 id="elicitation-input">
3683 Elicitation 입력3687 Elicitation input
3684</h4>3688</h4>
3685 3689
3686[공통 입력 필드](#common-input-fields)에 더해 Elicitation 훅은 `mcp_server_name`, `message` 필드와 선택적 필드인 `mode`, `url`, `elicitation_id`, `requested_schema`를 받습니다.3690[공통 입력 필드](#common-input-fields)에 더해 Elicitation 훅은 `mcp_server_name`, `message`와 선택적 필드인 `mode`, `url`, `elicitation_id`, `requested_schema`를 받습니다.
3687 3691
3688가장 일반적인 경우인 폼 모드 elicitation의 예:3692가장 일반적인 경우인 양식 모드 elicitation의 예는 다음과 같습니다.
3689 3693
3690```json theme={null}3694```json theme={null}
3691{3695{
3705}3709}
3706```3710```
3707 3711
3708브라우저 기반 인증에 사용되는 URL 모드 elicitation의 예:3712브라우저 기반 인증에 사용되는 URL 모드 elicitation의 예는 다음과 같습니다.
3709 3713
3710```json theme={null}3714```json theme={null}
3711{3715{
3721```3725```
3722 3726
3723<h4 id="elicitation-output">3727<h4 id="elicitation-output">
3724 Elicitation 출력3728 Elicitation output
3725</h4>3729</h4>
3726 3730
3727대화 상자를 표시하지 않고 프로그래밍 방식으로 응답하려면 `hookSpecificOutput`이 포함된 JSON 객체를 반환하십시오.3731Elicitation 훅은 사용자 대신 요청에 응답하거나, 요청을 거절 또는 취소하거나, 대화 상자에 맡길 수 있습니다. 응답, 거절 또는 취소하려면 0으로 종료하고 `action`이 포함된 `hookSpecificOutput` 객체를 출력하십시오. 서버는 응답을 받고 대화 상자는 표시되지 않습니다. 이 표의 각 행은 하나의 결과에 대해 반환할 내용과 MCP 서버가 받는 내용을 보여 줍니다.
3732
3733| 목적 | 반환 | 서버가 받는 내용 |
3734| :- | :- | :- |
3735| 사용자 대신 응답 | `content`에 양식 필드 값을 포함한 `"action": "accept"` | 사용자의 `content`가 포함된 `accept` |
3736| 요청 거절 | `"action": "decline"` | `decline` |
3737| 요청 취소 | `"action": "cancel"` | `cancel` |
3738| 요청을 사용자에게 맡김 | 출력 없음, 종료 코드 0 | [대화 상자](/docs/ko/mcp#respond-to-mcp-elicitation-requests)에서 받은 사용자의 응답 |
3739
3740다음 출력은 [Elicitation 입력](#elicitation-input)에 표시된 양식 모드 요청에 응답합니다. `content`의 키는 해당 요청의 `requested_schema`에 있는 속성 이름입니다.
3728 3741
3729```json theme={null}3742```json theme={null}
3730{3743{
3738}3751}
3739```3752```
3740 3753
3741| 필드 | 값 | 설명 |3754다음 출력은 요청을 거절합니다.
3742| :- | :- | :- |3755
3743| `action` | `accept`, `decline`, `cancel` | 요청을 수락, 거절 또는 취소할지 여부 |3756```json theme={null}
3744| `content` | object | 제출할 폼 필드 값. `action`이 `accept`일 때만 사용됩니다 |3757{
3758 "hookSpecificOutput": {
3759 "hookEventName": "Elicitation",
3760 "action": "decline"
3761 }
3762}
3763```
3764
3765대화 상자에서 **Decline**을 선택하면 `decline`이 전송되고 `Esc`를 누르면 `cancel`이 전송되므로, 서버가 받기를 원하는 값을 반환하십시오.
3766
3767URL 모드 요청의 경우 `accept`를 반환하는 훅은 대화 상자를 건너뛰므로 URL이 열리지 않습니다.
3768
3769Claude Code는 반환하는 `action`과 관계없이 Elicitation 훅의 JSON 출력에서 `reason`, `systemMessage`, `continue`를 버립니다.
3745 3770
3746종료 코드 2는 elicitation을 거부합니다. Claude Code는 stderr 메시지를 어디에도 표시하지 않습니다.3771<h4 id="other-ways-to-decline-an-elicitation">
3772 Other ways to decline an elicitation
3773</h4>
3774
3775훅은 다음과 같은 방법으로도 거절할 수 있습니다. 서버는 `"action": "decline"`의 경우와 동일한 `decline`을 받습니다.
3776
3777* **코드 2로 종료**: Claude Code는 같은 훅이 출력한 `hookSpecificOutput`을 무시합니다
3778* **최상위 `"decision": "block"` 출력**: 차단이 같은 출력의 `action`보다 우선합니다
3779
3780여러 훅이 같은 요청과 일치하는 경우, 그중 하나의 거절이 다른 훅의 `accept` 또는 `cancel`보다 우선합니다.
3781
3782다음 스크립트는 URL 모드 요청을 거절하고 양식 요청은 대화 상자에 맡깁니다.
3783
3784```bash theme={null}
3785#!/bin/bash
3786if [ "$(jq -r '.mode')" = "url" ]; then
3787 exit 2
3788fi
3789```
3790
3791Claude Code는 stderr나 `reason`을 표시하지 않으므로 사용자와 서버 모두 훅이 거절한 이유를 알 수 없습니다.
3792
3793Claude Code는 v2.1.105부터 v2.1.284에서 수정될 때까지 `Elicitation` 및 `ElicitationResult` 훅의 최상위 `decision`을 무시했습니다.
3794
3795<h4 id="answer-a-form-request-from-a-script">
3796 Answer a form request from a script
3797</h4>
3747 3798
3748Claude Code는 Elicitation 훅의 JSON 출력 중 `hookSpecificOutput`에 따라 동작하며 `systemMessage`와 `continue`는 폐기합니다.3799다음 예시는 사용자 대신 반복되는 질문 하나에 응답합니다. `issue-tracker`라는 MCP 서버가 양식에서 프로젝트 키를 요청하면 훅이 `DOCS`를 채워 넣습니다. 스크립트는 `project_key`가 양식의 유일한 필드일 때 수락합니다. 다른 요청에는 아무것도 출력하지 않으므로 대화 상자가 표시됩니다.
3800
3801<Tabs>
3802 <Tab title="macOS/Linux">
3803 설정 파일에서 서버 이름을 matcher로 하여 이벤트에 대한 명령 훅을 등록합니다.
3804
3805 ```json theme={null}
3806 {
3807 "hooks": {
3808 "Elicitation": [
3809 {
3810 "matcher": "issue-tracker",
3811 "hooks": [
3812 {
3813 "type": "command",
3814 "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/answer-project-key.sh",
3815 "args": []
3816 }
3817 ]
3818 }
3819 ]
3820 }
3821 }
3822 ```
3823
3824 이 스크립트를 프로젝트의 `.claude/hooks/answer-project-key.sh`에 저장하고 `chmod +x`로 실행 가능하게 만듭니다.
3825
3826 ```bash theme={null}
3827 #!/bin/bash
3828 input=$(cat)
3829 fields=$(jq -c '.requested_schema.properties // {} | keys' <<<"$input")
3830
3831 if [ "$fields" = '["project_key"]' ]; then
3832 jq -n '{hookSpecificOutput: {hookEventName: "Elicitation", action: "accept", content: {project_key: "DOCS"}}}'
3833 fi
3834 ```
3835 </Tab>
3836
3837 <Tab title="Windows (PowerShell)">
3838 서버 이름을 matcher로 하여 PowerShell을 통해 스크립트를 실행하는 명령 훅을 등록합니다.
3839
3840 ```json theme={null}
3841 {
3842 "hooks": {
3843 "Elicitation": [
3844 {
3845 "matcher": "issue-tracker",
3846 "hooks": [
3847 {
3848 "type": "command",
3849 "command": "powershell.exe",
3850 "args": [
3851 "-NoProfile",
3852 "-ExecutionPolicy",
3853 "Bypass",
3854 "-File",
3855 "${CLAUDE_PROJECT_DIR}/.claude/hooks/answer-project-key.ps1"
3856 ]
3857 }
3858 ]
3859 }
3860 ]
3861 }
3862 }
3863 ```
3864
3865 이 스크립트를 프로젝트의 `.claude/hooks/answer-project-key.ps1`에 저장합니다.
3866
3867 ```powershell theme={null}
3868 $request = [Console]::In.ReadToEnd() | ConvertFrom-Json
3869 $fields = @($request.requested_schema.properties.PSObject.Properties.Name)
3870
3871 if ($fields.Count -eq 1 -and $fields[0] -eq 'project_key') {
3872 @{
3873 hookSpecificOutput = @{
3874 hookEventName = "Elicitation"
3875 action = "accept"
3876 content = @{ project_key = "DOCS" }
3877 }
3878 } | ConvertTo-Json -Depth 3
3879 }
3880 ```
3881 </Tab>
3882</Tabs>
3883
3884훅이 작동하는지 확인하려면 `claude --debug`로 Claude Code를 시작하고, 서버가 프로젝트 키를 요청하게 만드는 작업을 Claude에게 주십시오. 대화 상자가 표시되지 않으며, [디버그 로그](#debug-hooks)에 `Elicitation resolved by hook: {"action":"accept","content":{"project_key":"DOCS"}}`로 끝나는 줄이 기록됩니다.
3749 3885
3750<h3 id="elicitationresult">3886<h3 id="elicitationresult">
3751 ElicitationResult3887 ElicitationResult
3752</h3>3888</h3>
3753 3889
3754사용자가 MCP elicitation에 응답한 후 실행됩니다. 훅은 응답이 MCP 서버로 다시 전송되기 전에 이를 관찰, 수정 또는 차단할 수 있습니다.3890사용자가 MCP elicitation에 응답한 후 실행됩니다. 훅은 응답이 MCP 서버로 다시 전송되기 전에 응답을 관찰, 수정 또는 차단할 수 있습니다.
3891
3892[Elicitation](#elicitation) 훅이 요청에 응답하면 Claude Code는 ElicitationResult 훅을 실행하지 않고 해당 응답을 서버로 보냅니다.
3755 3893
3756matcher 필드는 MCP 서버 이름과 비교됩니다.3894matcher 필드는 MCP 서버 이름과 비교됩니다.
3757 3895
3758<h4 id="elicitationresult-input">3896<h4 id="elicitationresult-input">
3759 ElicitationResult 입력3897 ElicitationResult input
3760</h4>3898</h4>
3761 3899
3762[공통 입력 필드](#common-input-fields)에 더해 ElicitationResult 훅은 `mcp_server_name`, `action` 필드와 선택적 필드인 `mode`, `elicitation_id`, `content`를 받습니다.3900[공통 입력 필드](#common-input-fields)에 더해 ElicitationResult 훅은 `mcp_server_name`, `action`과 선택적 필드인 `mode`, `elicitation_id`, `content`를 받습니다.
3763 3901
3764```json theme={null}3902```json theme={null}
3765{3903{
3770 "mcp_server_name": "my-mcp-server",3908 "mcp_server_name": "my-mcp-server",
3771 "action": "accept",3909 "action": "accept",
3772 "content": { "username": "alice" },3910 "content": { "username": "alice" },
3773 "mode": "form",3911 "mode": "form"
3774 "elicitation_id": "elicit-123"
3775}3912}
3776```3913```
3777 3914
3778<h4 id="elicitationresult-output">3915<h4 id="elicitationresult-output">
3779 ElicitationResult 출력3916 ElicitationResult output
3780</h4>3917</h4>
3781 3918
3782사용자의 응답을 재정의하려면 `hookSpecificOutput`이 포함된 JSON 객체를 반환하십시오.3919ElicitationResult 훅은 사용자의 응답을 그대로 통과시키거나, 값을 변경하거나, 차단할 수 있습니다. 응답을 변경하거나 차단하려면 0으로 종료하고 `action`이 포함된 `hookSpecificOutput` 객체를 출력하십시오. 이 표의 각 행은 하나의 결과에 대해 반환할 내용과 MCP 서버가 받는 내용을 보여 줍니다.
3920
3921| 목적 | 반환 | 서버가 받는 내용 |
3922| :- | :- | :- |
3923| 응답 통과 | 출력 없음, 종료 코드 0 | 변경되지 않은 사용자의 응답 |
3924| 제출된 값 변경 | `content`에 새 값을 포함한 `"action": "accept"` | 사용자의 값 대신 훅의 `content`가 포함된 `accept` |
3925| 응답 차단 | `"action": "decline"` | 사용자의 값이 없는 `decline` |
3926| 요청 취소 | `"action": "cancel"` | 사용자가 제출한 값과 함께 `cancel`. 값을 보내지 않으려면 `"decline"`을 반환하십시오 |
3927
3928다음 출력은 [ElicitationResult 입력](#elicitationresult-input)에 표시된 응답을 변경하므로, 사용자가 `alice`를 제출한 자리에 서버는 `alice@example.com`을 받습니다.
3783 3929
3784```json theme={null}3930```json theme={null}
3785{3931{
3786 "hookSpecificOutput": {3932 "hookSpecificOutput": {
3787 "hookEventName": "ElicitationResult",3933 "hookEventName": "ElicitationResult",
3788 "action": "decline",3934 "action": "accept",
3789 "content": {}3935 "content": {
3936 "username": "alice@example.com"
3937 }
3790 }3938 }
3791}3939}
3792```3940```
3793 3941
3794| 필드 | 값 | 설명 |3942훅의 `content`는 사용자의 `content` 객체 전체를 대체하므로 변경하지 않는 필드도 포함하십시오. Claude Code는 `action`이 없는 `hookSpecificOutput`을 무시하므로 `action`도 함께 반환하십시오.
3795| :- | :- | :- |3943
3796| `action` | `accept`, `decline`, `cancel` | 사용자의 동작을 재정의합니다 |3944ElicitationResult 훅은 사용자가 거절하거나 취소할 때도 실행되며, 훅의 `action`이 사용자의 것을 대체합니다. `accept`를 반환하기 전에 입력의 `action`이 `accept`인지 확인하십시오. 그렇지 않으면 훅이 거절된 요청을 수락된 요청으로 바꾸게 됩니다. 다음 스크립트는 사용자가 수락한 경우 동일한 변경을 수행하고 다른 필드를 유지하며, 그 외의 경우에는 아무것도 출력하지 않습니다.
3797| `content` | object | 폼 필드 값을 재정의합니다. `action`이 `accept`일 때만 의미가 있습니다 |3945
3946```bash theme={null}
3947#!/bin/bash
3948input=$(cat)
3798 3949
3799종료 코드 2는 응답을 차단하며, 실제 동작을 `decline`으로 변경합니다. Claude Code는 stderr 메시지를 어디에도 표시하지 않습니다.3950if [ "$(jq -r '.action' <<<"$input")" = "accept" ]; then
3951 jq '{hookSpecificOutput: {hookEventName: "ElicitationResult", action: "accept", content: (.content + {username: (.content.username + "@example.com")})}}' <<<"$input"
3952fi
3953```
3800 3954
3801Claude Code는 ElicitationResult 훅의 JSON 출력 중 `hookSpecificOutput`에 따라 동작하며 `systemMessage`와 `continue`는 폐기합니다.3955다음 출력은 응답을 차단합니다.
3956
3957```json theme={null}
3958{
3959 "hookSpecificOutput": {
3960 "hookEventName": "ElicitationResult",
3961 "action": "decline"
3962 }
3963}
3964```
3965
3966종료 코드 2와 최상위 `"decision": "block"`도 응답을 차단합니다. 훅이 이들을 함께 사용할 때 어느 것이 적용되는지, 사용자에게 무엇이 표시되는지, 어떤 버전이 `decision`을 무시했는지는 [elicitation을 거절하는 다른 방법](#other-ways-to-decline-an-elicitation)에서 다룹니다.
3967
3968Claude Code는 반환하는 `action`과 관계없이 ElicitationResult 훅의 JSON 출력에서 `reason`, `systemMessage`, `continue`를 버립니다.
3802 3969
3803<h2 id="prompt-based-hooks">3970<h2 id="prompt-based-hooks">
3804 프롬프트 기반 hook3971 프롬프트 기반 훅
3805</h2>3972</h2>
3806 3973
3807명령, HTTP 및 MCP tool hook 외에도 Claude Code는 LLM을 사용하여 작업을 허용할지 차단할지 평가하는 프롬프트 기반 hook (`type: "prompt"`)과 도구 액세스가 있는 에이전트 검증자를 생성하는 에이전트 hook (`type: "agent"`)을 지원합니다. 모든 이벤트가 모든 hook 유형을 지원하는 것은 아닙니다.3974명령, HTTP, MCP 도구 훅 외에도 Claude Code는 LLM을 사용해 작업을 허용할지 차단할지 평가하는 프롬프트 기반 훅(`type: "prompt"`)과 도구 접근 권한을 가진 에이전트형 검증자를 생성하는 에이전트 훅(`type: "agent"`)을 지원합니다. 모든 이벤트가 모든 훅 유형을 지원하지는 않습니다.
3808 3975
3809다섯 가지 hook 유형 모두 (`command`, `http`, `mcp_tool`, `prompt`, `agent`)를 지원하는 이벤트:3976다섯 가지 훅 유형(`command`, `http`, `mcp_tool`, `prompt`, `agent`)을 모두 지원하는 이벤트:
3810 3977
3811* `PermissionDenied`3978* `PermissionDenied`
3812* `PostToolBatch`3979* `PostToolBatch`
3821* `UserPromptExpansion`3988* `UserPromptExpansion`
3822* `UserPromptSubmit`3989* `UserPromptSubmit`
3823 3990
3824`PermissionRequest`는 `command`, `http`, `mcp_tool`, `prompt` 훅을 지원하지만 `agent` 훅은 지원하지 않습니다. 이 이벤트에 에이전트 훅을 구성하면 Claude Code는 이를 건너뛰고 권한 흐름은 변경 없이 진행됩니다. 훅에서 허용하거나 거부하려면 명령 또는 HTTP 훅에서 [결정 객체](#permissionrequest-decision-control)를 반환합니다.3991`PermissionRequest`는 `command`, `http`, `mcp_tool`, `prompt` 훅을 지원하지만 `agent` 훅은 지원하지 않습니다. 이 이벤트에 에이전트 훅을 구성하면 Claude Code는 이를 건너뛰고 권한 흐름은 변경 없이 진행됩니다. 훅에서 허용하거나 거부하려면 명령 또는 HTTP 훅에서 [결정 객체](#permissionrequest-decision-control)를 반환하십시오.
3825 3992
3826`command`, `http` 및 `mcp_tool` hook을 지원하지만 `prompt` 또는 `agent`는 지원하지 않는 이벤트:3993`command`, `http`, `mcp_tool` 훅은 지원하지만 `prompt`나 `agent`는 지원하지 않는 이벤트:
3827 3994
3828* `ConfigChange`3995* `ConfigChange`
3829* `CwdChanged`3996* `CwdChanged`
3844* `WorktreeCreate`4011* `WorktreeCreate`
3845* `WorktreeRemove`4012* `WorktreeRemove`
3846 4013
3847`SessionStart` 및 `Setup`은 `command` 및 `mcp_tool` hook을 지원하며, [MCP tool hook 필드](#mcp-tool-hook-fields)는 해당 `mcp_tool` hook이 실행되는 시기를 설명합니다. `http`, `prompt` 또는 `agent` hook은 지원하지 않습니다.4014`SessionStart`와 `Setup`은 `command` 및 `mcp_tool` 훅을 지원하며, 이들의 `mcp_tool` 훅이 언제 실행되는지는 [MCP 도구 훅 필드](#mcp-tool-hook-fields)에서 설명합니다. 이 이벤트들은 `http`, `prompt`, `agent` 훅을 지원하지 않습니다.
3848 4015
3849<h3 id="how-prompt-based-hooks-work">4016<h3 id="how-prompt-based-hooks-work">
3850 프롬프트 기반 hook이 어떻게 작동하는지4017 프롬프트 기반 훅의 작동 방식
3851</h3>4018</h3>
3852 4019
3853프롬프트 기반 hook은 Bash 명령을 실행하는 대신:4020프롬프트 기반 훅은 Bash 명령을 실행하는 대신 다음과 같이 작동합니다.
3854 4021
38551. 훅 입력과 프롬프트를 Claude 모델로 전송합니다. 기본값은 Claude Code가 [백그라운드 기능](/docs/ko/costs#background-token-usage)에 사용하는 모델입니다40221. 훅 입력과 프롬프트를 Claude 모델로 전송합니다. 기본적으로 Claude Code가 [백그라운드 기능](/docs/ko/costs#background-token-usage)에 사용하는 모델이 사용됩니다
38562. LLM은 결정을 포함하는 구조화된 JSON으로 응답합니다40232. LLM이 결정을 담은 구조화된 JSON으로 응답합니다
38573. Claude Code는 결정을 자동으로 처리합니다40243. Claude Code가 결정을 자동으로 처리합니다
3858 4025
3859<h3 id="prompt-hook-configuration">4026<h3 id="prompt-hook-configuration">
3860 프롬프트 hook 구성4027 프롬프트 훅 구성
3861</h3>4028</h3>
3862 4029
3863`type`을 `"prompt"`로 설정하고 `command` 대신 `prompt` 문자열을 제공합니다. `$ARGUMENTS` 자리 표시자를 사용하여 hook의 JSON 입력 데이터를 프롬프트 텍스트에 주입합니다.4030`type`을 `"prompt"`로 설정하고 `command` 대신 `prompt` 문자열을 제공합니다. `$ARGUMENTS` 플레이스홀더를 사용하여 훅의 JSON 입력 데이터를 프롬프트 텍스트에 삽입합니다.
4031
4032프롬프트 훅이나 [에이전트 훅](#agent-based-hooks)에서는 `prompt`를 "`.env` 파일을 읽는 모든 Bash 명령을 차단"처럼 무엇을 차단하거나 허용할지에 대한 규칙으로 작성하거나, "모든 단위 테스트 통과"처럼 충족되어야 하는 조건으로 작성할 수 있습니다.
3864 4033
3865이 `Stop` hook은 Claude가 완료되기 전에 모든 작업이 완료되었는지 평가하도록 LLM에 요청합니다:4034이 `Stop` 훅은 Claude가 작업을 마치도록 허용하기 전에 모든 작업이 완료되었는지 LLM에 평가를 요청합니다.
3866 4035
3867```json theme={null}4036```json theme={null}
3868{4037{
3883 4052
3884| 필드 | 필수 | 설명 |4053| 필드 | 필수 | 설명 |
3885| :- | :- | :- |4054| :- | :- | :- |
3886| `type` | 예 | `"prompt"`여야 합니다 |4055| `type` | 예 | 반드시 `"prompt"`여야 합니다 |
3887| `prompt` | 예 | LLM으로 전송할 프롬프트 텍스트. hook 입력 JSON에 대한 자리 표시자로 `$ARGUMENTS` 사용. `$ARGUMENTS`가 없으면 입력 JSON이 프롬프트에 추가됩니다 |4056| `prompt` | 예 | LLM에 전송할 프롬프트 텍스트입니다. 훅 입력 JSON의 플레이스홀더로 `$ARGUMENTS`를 사용합니다. `$ARGUMENTS`가 없으면 입력 JSON이 프롬프트 끝에 추가됩니다 |
3888| `model` | 아니오 | 평가에 사용할 모델. 기본값은 Claude Code가 [백그라운드 기능](/docs/ko/costs#background-token-usage)에 사용하는 모델입니다 |4057| `model` | 아니요 | 평가에 사용할 모델입니다. 기본값은 Claude Code가 [백그라운드 기능](/docs/ko/costs#background-token-usage)에 사용하는 모델입니다 |
3889| `timeout` | 아니오 | 초 단위 시간 초과. 기본값: 30 |4058| `timeout` | 아니요 | 초 단위 타임아웃입니다. 기본값: 30 |
3890| `continueOnBlock` | 아니오 | 적용되는 이벤트에서 `true`는 `ok: false` 이유를 Claude에 다시 피드백하고 턴을 종료하는 대신 계속합니다. 기본값: `false`. 이벤트별 동작은 [응답 스키마](#response-schema)를 참조하세요 |4059| `continueOnBlock` | 아니요 | 적용되는 이벤트에서 `true`로 설정하면 턴을 종료하는 대신 `ok: false` 사유를 Claude에 다시 전달하고 계속 진행합니다. 기본값: `false`. 이벤트별 동작은 [응답 스키마](#response-schema)를 참조하십시오 |
3891 4060
3892<h3 id="response-schema">4061<h3 id="response-schema">
3893 응답 스키마4062 응답 스키마
3894</h3>4063</h3>
3895 4064
3896LLM은 다음을 포함하는 JSON으로 응답해야 합니다:4065LLM은 다음을 포함하는 JSON으로 응답해야 합니다.
3897 4066
3898```json theme={null}4067```json theme={null}
3899{4068{
3905 4074
3906| 필드 | 설명 |4075| 필드 | 설명 |
3907| :- | :- |4076| :- | :- |
3908| `ok` | `true`는 허용합니다. `false`의 경우 아래의 이벤트별 동작을 참조하세요 |4077| `ok` | 허용하려면 `true`입니다. `false`인 경우 아래의 이벤트별 동작을 참조하십시오 |
3909| `reason` | `ok`가 `false`일 때 필수입니다 |4078| `reason` | `ok`가 `false`일 때 필수입니다 |
3910| `impossible` | 선택 사항입니다. 모델이 조건을 절대 만족할 수 없다고 판단할 때 `ok: false`와 함께 반환합니다. `Stop` 및 `SubagentStop`에서 Claude Code는 이유를 다시 피드백하는 대신 턴을 종료하도록 허용합니다. 에이전트 hook 및 기타 이벤트는 이를 무시합니다 |4079| `impossible` | 선택 사항입니다. 모델은 조건이 절대 충족될 수 없다고 판단하면 `ok: false`와 함께 이 값을 반환합니다. `Stop` 및 `SubagentStop`에서는 이 경우 Claude Code가 사유를 다시 전달하는 대신 턴이 종료되도록 합니다. 에이전트 훅과 다른 이벤트는 이 값을 무시합니다 |
3911 4080
3912`ok: false`에서 발생하는 상황은 이벤트에 따라 다릅니다:4081`ok: false`일 때 발생하는 동작은 이벤트에 따라 다릅니다.
3913 4082
3914* `Stop` 및 `SubagentStop`: 이유는 Claude의 다음 명령으로 피드백되며 턴이 계속됩니다. 응답이 `impossible: true`도 설정하지 않는 한, 이 경우 Claude Code는 중지를 허용하고 턴이 종료됩니다4083* `Stop` 및 `SubagentStop`: 사유가 Claude의 다음 지시로 다시 전달되고 턴이 계속됩니다. 단, 응답에서 `impossible: true`도 함께 설정한 경우에는 Claude Code가 중지를 허용하고 턴이 종료됩니다
3915* `PreToolUse`: tool 호출이 거부됩니다. 기본적으로 턴이 끝나고 거부 이유가 채팅에 경고 줄로 나타납니다. `continueOnBlock: true`를 설정하여 이유를 Claude에 tool 오류로 반환하여 조정하고 계속할 수 있도록 합니다. 이는 명령 hook의 `permissionDecision: "deny"`와 동일합니다. v2.1.210 이전에는 거부 이유가 Claude에 tool 오류로 반환되었고 턴이 계속되었습니다4084* `PreToolUse`: 도구 호출이 거부됩니다. 기본적으로 턴이 종료되고 거부 사유가 채팅에 경고 줄로 표시됩니다. 대신 사유를 도구 오류로 Claude에 반환하여 Claude가 조정하고 계속 진행할 수 있게 하려면 `continueOnBlock: true`를 설정하십시오. 이는 명령 훅의 `permissionDecision: "deny"`와 동일합니다. v2.1.210 이전에는 거부 사유가 도구 오류로 Claude에 반환되고 턴이 계속되었습니다
3916* `PostToolUse`: 기본적으로 턴이 끝나고 이유는 채팅에 경고 줄로 나타납니다. 대신 `continueOnBlock: true`를 설정하여 이유를 Claude에 다시 피드백하고 턴을 계속합니다4085* `PostToolUse`: 기본적으로 턴이 종료되고 사유가 채팅에 경고 줄로 표시됩니다. 대신 사유를 Claude에 다시 전달하고 턴을 계속하려면 `continueOnBlock: true`를 설정하십시오
3917* `PostToolBatch`, `UserPromptSubmit` 및 `UserPromptExpansion`: 턴이 끝나고 이유는 경고 줄로 나타납니다. 이러한 이벤트는 `continue`에 관계없이 `decision: "block"`에서 턴을 종료합니다4086* `PostToolBatch`, `UserPromptSubmit`, `UserPromptExpansion`: 턴이 종료되고 사유가 경고 줄로 표시됩니다. 이 이벤트들은 `continue`와 관계없이 `decision: "block"`에서 턴을 종료합니다
3918* `PostToolUseFailure` 및 `TaskCreated`: 이유는 Claude에 tool 오류로 반환되며 턴이 계속됩니다. `continueOnBlock`에 관계없이4087* `PostToolUseFailure` 및 `TaskCreated`: `continueOnBlock`과 관계없이 사유가 도구 오류로 Claude에 반환되고 턴이 계속됩니다
3919* `TaskCompleted`: 턴 중에 작업이 완료됨으로 표시되어 발생할 때 이유는 Claude에 tool 오류로 반환되며 턴이 계속됩니다. `continueOnBlock`에 관계없이. 팀원이 중지되어 발생할 때 `TeammateIdle`처럼 동작하며 기본적으로 팀원을 중지합니다4088* `TaskCompleted`: 턴 중에 작업이 완료로 표시되어 실행된 경우, `continueOnBlock`과 관계없이 사유가 도구 오류로 Claude에 반환되고 턴이 계속됩니다. 팀원이 중지하여 실행된 경우에는 `TeammateIdle`처럼 동작하며 기본적으로 팀원을 중단시킵니다
3920* `TeammateIdle`: 기본적으로 팀원이 중지되고 이유는 경고 줄로 나타납니다. `continueOnBlock: true`를 설정하여 이유를 팀원에게 다시 피드백하고 계속 작업하도록 유지합니다4089* `TeammateIdle`: 기본적으로 팀원이 중지되고 사유가 경고 줄로 표시됩니다. 대신 사유를 팀원에게 다시 전달하고 계속 작업하게 하려면 `continueOnBlock: true`를 설정하십시오
3921* `PermissionRequest`: `ok: false`는 효과가 없습니다. hook에서 승인을 거부하려면 `hookSpecificOutput.decision.behavior: "deny"`를 반환하는 [명령 hook](#command-hook-fields)을 사용합니다4090* `PermissionRequest`: `ok: false`는 아무런 효과가 없습니다. 훅에서 승인을 거부하려면 `hookSpecificOutput.decision.behavior: "deny"`를 반환하는 [명령 훅](#command-hook-fields)을 사용하십시오
3922* `PermissionDenied`: `ok: false`는 거부가 이미 발생했기 때문에 효과가 없습니다. 이 이벤트가 읽는 유일한 출력은 `hookSpecificOutput.retry`이며, 프롬프트 및 에이전트 hook은 이를 설정할 수 없습니다. 이들은 이 이벤트에서 실행되지만 출력은 버려집니다. `retry`를 반환하려면 [명령 hook](#command-hook-fields)을 사용합니다4091* `PermissionDenied`: 거부가 이미 발생했으므로 `ok: false`는 아무런 효과가 없습니다. 이 이벤트가 읽는 유일한 출력은 `hookSpecificOutput.retry`이며, 프롬프트 훅과 에이전트 훅은 이를 설정할 수 없습니다. 이 훅들은 이 이벤트에서 실행되지만 출력은 폐기됩니다. `retry`를 반환하려면 [명령 훅](#command-hook-fields)을 사용하십시오
3923 4092
3924이벤트에 대해 더 세밀한 제어가 필요한 경우 [결정 제어](#decision-control)에 설명된 이벤트별 필드가 있는 [명령 hook](#command-hook-fields)을 사용합니다.4093어떤 이벤트에서든 더 세밀한 제어가 필요하다면 [결정 제어](#decision-control)에 설명된 이벤트별 필드와 함께 [명령 훅](#command-hook-fields)을 사용하십시오.
3925 4094
3926<h3 id="check-multiple-conditions-before-stopping">4095<h3 id="check-multiple-conditions-before-stopping">
3927 중지하기 전에 여러 조건 확인4096 중지 전에 여러 조건 확인하기
3928</h3>4097</h3>
3929 4098
3930이 `Stop` hook은 Claude가 중지하기 전에 세 가지 조건을 확인하는 자세한 프롬프트를 사용합니다. `SubagentStop` hook은 [subagent](/docs/ko/sub-agents)가 중지해야 하는지 평가하는 동일한 형식을 사용합니다. 모델이 조건이 아직 충족되지 않았기 때문에 `"ok": false`를 반환하면 Claude는 제공된 이유를 다음 명령으로 받으며 계속 작업합니다:4099이 `Stop` 훅은 상세한 프롬프트를 사용하여 Claude의 중지를 허용하기 전에 세 가지 조건을 확인합니다. `SubagentStop` 훅도 같은 형식을 사용하여 [서브에이전트](/docs/ko/sub-agents)가 중지해야 하는지 평가합니다. 조건이 아직 충족되지 않아 모델이 `"ok": false`를 반환하면, Claude는 제공된 사유를 다음 지시로 삼아 작업을 계속합니다.
3931 4100
3932```json theme={null}4101```json theme={null}
3933{4102{