297| :-------------- | :-- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |297| :-------------- | :-- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
298| `type` | 예 | `"command"`, `"http"`, `"mcp_tool"`, `"prompt"` 또는 `"agent"` |298| `type` | 예 | `"command"`, `"http"`, `"mcp_tool"`, `"prompt"` 또는 `"agent"` |
299| `if` | 아니오 | `"Bash(git *)"` 또는 `"Edit(*.ts)"`와 같은 권한 규칙 구문을 사용하여 이 hook이 실행될 때를 필터링합니다. hook은 도구 호출이 패턴과 일치할 때만 생성되거나 Bash 명령이 너무 복잡하여 구문 분석할 수 없을 때 생성됩니다. 도구 이벤트에서만 평가됩니다: `PreToolUse`, `PostToolUse`, `PostToolUseFailure`, `PermissionRequest`, `PermissionDenied`. 다른 이벤트에서는 `if`가 설정된 hook이 절대 실행되지 않습니다. [권한 규칙](/ko/permissions)과 동일한 구문을 사용합니다 |299| `if` | 아니오 | `"Bash(git *)"` 또는 `"Edit(*.ts)"`와 같은 권한 규칙 구문을 사용하여 이 hook이 실행될 때를 필터링합니다. hook은 도구 호출이 패턴과 일치할 때만 생성되거나 Bash 명령이 너무 복잡하여 구문 분석할 수 없을 때 생성됩니다. 도구 이벤트에서만 평가됩니다: `PreToolUse`, `PostToolUse`, `PostToolUseFailure`, `PermissionRequest`, `PermissionDenied`. 다른 이벤트에서는 `if`가 설정된 hook이 절대 실행되지 않습니다. [권한 규칙](/ko/permissions)과 동일한 구문을 사용합니다 |
300| `timeout` | 아니오 | 취소하기 전 초 단위. 기본값: 명령의 경우 600, 프롬프트의 경우 30, 에이전트의 경우 60 |300| `timeout` | 아니오 | 취소하기 전 초 단위. 기본값: `command`, `http`, `mcp_tool`의 경우 600; `prompt`의 경우 30; `agent`의 경우 60. [`UserPromptSubmit`](#userpromptsubmit)은 `command`, `http`, `mcp_tool`의 기본값을 30으로 낮춥니다 |
301| `statusMessage` | 아니오 | hook이 실행되는 동안 표시되는 사용자 정의 스피너 메시지 |301| `statusMessage` | 아니오 | hook이 실행되는 동안 표시되는 사용자 정의 스피너 메시지 |
302| `once` | 아니오 | `true`인 경우 세션당 한 번만 실행된 후 제거됩니다. [Skill 및 에이전트의 Hook](#hooks-in-skills-and-agents)에서 선언된 hook에만 적용됨; 설정 파일 및 에이전트 frontmatter에서는 무시됨 |302| `once` | 아니오 | `true`인 경우 세션당 한 번만 실행된 후 제거됩니다. [Skill 및 에이전트의 Hook](#hooks-in-skills-and-agents)에서 선언된 hook에만 적용됨; 설정 파일 및 에이전트 frontmatter에서는 무시됨 |
303 303
558 558
559명령 hook은 stdin을 통해 JSON 데이터를 받고 종료 코드, stdout, stderr를 통해 결과를 전달합니다. HTTP hook은 POST 요청 본문으로 동일한 JSON을 받고 HTTP 응답 본문을 통해 결과를 전달합니다. 이 섹션에서는 모든 이벤트에 공통적인 필드와 동작을 다룹니다. [Hook 이벤트](#hook-events) 아래의 각 이벤트 섹션에는 특정 입력 스키마와 결정 제어 옵션이 포함됩니다.559명령 hook은 stdin을 통해 JSON 데이터를 받고 종료 코드, stdout, stderr를 통해 결과를 전달합니다. HTTP hook은 POST 요청 본문으로 동일한 JSON을 받고 HTTP 응답 본문을 통해 결과를 전달합니다. 이 섹션에서는 모든 이벤트에 공통적인 필드와 동작을 다룹니다. [Hook 이벤트](#hook-events) 아래의 각 이벤트 섹션에는 특정 입력 스키마와 결정 제어 옵션이 포함됩니다.
560 560
561macOS 및 Linux에서 명령 hook은 v2.1.139부터 제어 터미널 없이 자신의 세션에서 실행됩니다. hook 프로세스 및 모든 자식 프로세스는 `/dev/tty`를 열거나 Claude Code 인터페이스에 직접 이스케이프 시퀀스를 보낼 수 없습니다. Windows에는 `/dev/tty`가 없습니다. 모든 플랫폼에서 사용자에게 메시지를 표시하려면 JSON 출력에서 [`systemMessage`](#json-output)를 반환합니다. 데스크톱 알림을 트리거하거나 창 제목을 설정하거나 벨을 울리려면 대신 [`terminalSequence`](#emit-terminal-notifications)를 반환합니다.
562
561### 공통 입력 필드563### 공통 입력 필드
562 564
563Hook 이벤트는 각 [hook 이벤트](#hook-events) 섹션에서 문서화된 이벤트 특정 필드 외에 이러한 필드를 JSON으로 받습니다. 명령 hook의 경우 이 JSON은 stdin을 통해 도착합니다. HTTP hook의 경우 POST 요청 본문으로 도착합니다.565Hook 이벤트는 각 [hook 이벤트](#hook-events) 섹션에서 문서화된 이벤트 특정 필드 외에 이러한 필드를 JSON으로 받습니다. 명령 hook의 경우 이 JSON은 stdin을 통해 도착합니다. HTTP hook의 경우 POST 요청 본문으로 도착합니다.
685 687
686hook의 stdout은 JSON 객체만 포함해야 합니다. 셸 프로필이 시작 시 텍스트를 인쇄하면 JSON 구문 분석을 방해할 수 있습니다. 문제 해결 가이드의 [JSON 검증 실패](/ko/hooks-guide#json-validation-failed)를 참조하세요.688hook의 stdout은 JSON 객체만 포함해야 합니다. 셸 프로필이 시작 시 텍스트를 인쇄하면 JSON 구문 분석을 방해할 수 있습니다. 문제 해결 가이드의 [JSON 검증 실패](/ko/hooks-guide#json-validation-failed)를 참조하세요.
687 689
688컨텍스트에 주입된 hook 출력 (`additionalContext`, `systemMessage` 또는 일반 stdout)은 10,000자로 제한됩니다. 이 제한을 초과하는 출력은 파일에 저장되고 미리보기 및 파일 경로로 바뀌며, 큰 도구 결과가 처리되는 방식과 동일합니다.690hook 출력 문자열 (`additionalContext`, `systemMessage`, 및 일반 stdout)은 10,000자로 제한됩니다. 이 제한을 초과하는 출력은 파일에 저장되고 미리보기 및 파일 경로로 바뀌며, 큰 도구 결과가 처리되는 방식과 동일합니다.
689 691
690JSON 객체는 세 가지 종류의 필드를 지원합니다:692JSON 객체는 세 가지 종류의 필드를 지원합니다:
691 693
694* \*\*`hookSpecificOutput`\*\*은 더 풍부한 제어가 필요한 이벤트를 위한 중첩 객체입니다. 이벤트 이름으로 설정된 `hookEventName` 필드가 필요합니다.696* \*\*`hookSpecificOutput`\*\*은 더 풍부한 제어가 필요한 이벤트를 위한 중첩 객체입니다. 이벤트 이름으로 설정된 `hookEventName` 필드가 필요합니다.
695 697
696| 필드 | 기본값 | 설명 |698| 필드 | 기본값 | 설명 |
697| :--------------- | :------ | :----------------------------------------------------------------- |699| :----------------- | :------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
698| `continue` | `true` | `false`인 경우 hook이 실행된 후 Claude가 완전히 중지됩니다. 모든 이벤트 특정 결정 필드보다 우선합니다 |700| `continue` | `true` | `false`인 경우 hook이 실행된 후 Claude가 완전히 중지됩니다. 모든 이벤트 특정 결정 필드보다 우선합니다 |
699| `stopReason` | 없음 | `continue`가 `false`일 때 사용자에게 표시되는 메시지. Claude에는 표시되지 않음 |701| `stopReason` | 없음 | `continue`가 `false`일 때 사용자에게 표시되는 메시지. Claude에는 표시되지 않음 |
700| `suppressOutput` | `false` | `true`인 경우 디버그 로그에서 stdout을 숨깁니다 |702| `suppressOutput` | `false` | `true`인 경우 디버그 로그에서 stdout을 숨깁니다 |
701| `systemMessage` | 없음 | 사용자에게 표시되는 경고 메시지 |703| `systemMessage` | 없음 | 사용자에게 표시되는 경고 메시지 |
704| `terminalSequence` | 없음 | Claude Code가 사용자를 대신하여 내보낼 터미널 이스케이프 시퀀스 (예: 데스크톱 알림, 창 제목 또는 벨). OSC `0`/`1`/`2`/`9`/`99`/`777` 및 BEL로 제한됩니다. 값에 허용 목록 외의 항목이 포함되면 필드는 무시됩니다. `/dev/tty`를 사용할 수 없는 hook 대신 이를 사용합니다 |
702 705
703Claude를 이벤트 유형과 관계없이 완전히 중지하려면:706Claude를 이벤트 유형과 관계없이 완전히 중지하려면:
704 707
706{ "continue": false, "stopReason": "Build failed, fix errors before continuing" }709{ "continue": false, "stopReason": "Build failed, fix errors before continuing" }
707```710```
708 711
712#### 터미널 알림 내보내기
713
714`terminalSequence` 필드는 Claude Code v2.1.141 이상이 필요합니다.
715
716Hook은 제어 터미널 없이 실행되므로 이스케이프 시퀀스를 `/dev/tty`에 직접 쓰는 것이 실패합니다. 대신 `terminalSequence` 필드에 이스케이프 시퀀스를 반환하면 Claude Code가 자신의 터미널 쓰기 경로를 통해 이를 내보냅니다. 이는 race-free이고 tmux 및 GNU screen 내에서 작동하며 `/dev/tty`가 없는 Windows에서도 작동합니다.
717
718필드는 하나 이상의 허용 목록에 있는 이스케이프 시퀀스 문자열을 허용합니다:
719
720* OSC `0`, `1`, `2`: 창 및 아이콘 제목
721* OSC `9`: iTerm2, ConEmu, Windows Terminal, 및 WezTerm 알림 (`9;4` 작업 표시줄 진행률 포함)
722* OSC `99`: Kitty 알림
723* OSC `777`: urxvt, Ghostty, 및 Warp 알림
724* 맨 BEL
725
726시퀀스는 BEL 또는 ST로 종료될 수 있습니다. 허용 목록 외의 항목 (CSI 커서 및 색상 시퀀스, OSC 팔레트 시퀀스, OSC 8 하이퍼링크, OSC 52 클립보드 쓰기, 및 OSC 1337 포함)은 거부되고 필드는 무시됩니다.
727
728아래 예제는 `Notification` hook에서 데스크톱 알림을 발생시킵니다. 이스케이프 시퀀스는 `printf` 8진수 이스케이프로 빌드되므로 제어 바이트가 셸 명령줄에 나타나지 않으며, `jq -n --arg`는 JSON 출력을 빌드하므로 알림 메시지의 따옴표, 백슬래시, 및 줄바꿈이 올바르게 이스케이프됩니다:
729
730```bash theme={null}
731#!/bin/bash
732# Notification hook: Claude Code가 주의가 필요할 때 데스크톱을 ping합니다.
733input=$(cat)
734title="Claude Code'
735body=$(jq -r '.message // "Needs your attention"' <<<"$input")
736seq=$(printf '\033]777;notify;%s;%s\007' "$title" "$body")
737jq -nc --arg seq "$seq" '{terminalSequence: $seq}'
738```
739
740`{ "terminalSequence": "..." }` 형태는 모든 셸 또는 언어에서 동일합니다. Windows에서는 PowerShell 또는 스크립트에서 이스케이프 문자열을 빌드하고 동일한 JSON 객체를 내보냅니다.
741
742<Note>
743 `terminalSequence`는 이전에 `/dev/tty`에 직접 이스케이프 시퀀스를 작성한 hook의 지원되는 대체입니다. 허용 목록은 커서를 이동하거나 색상을 변경할 수 없는 시퀀스로 제한되므로 hook은 화면상의 프롬프트를 손상시킬 수 없습니다.
744</Note>
745
709#### Claude를 위한 컨텍스트 추가746#### Claude를 위한 컨텍스트 추가
710 747
711`additionalContext` 필드는 hook에서 Claude의 컨텍스트 윈도우로 문자열을 전달합니다. Claude Code는 문자열을 시스템 미리 알림으로 래핑하고 hook이 발생한 지점에서 대화에 삽입합니다. Claude는 다음 모델 요청에서 미리 알림을 읽지만 인터페이스에 채팅 메시지로 나타나지 않습니다.748`additionalContext` 필드는 hook에서 Claude의 컨텍스트 윈도우로 문자열을 전달합니다. Claude Code는 문자열을 시스템 미리 알림으로 래핑하고 hook이 발생한 지점에서 대화에 삽입합니다. Claude는 다음 모델 요청에서 미리 알림을 읽지만 인터페이스에 채팅 메시지로 나타나지 않습니다.
989 1026
990사용자가 프롬프트를 제출할 때, Claude가 처리하기 전에 실행됩니다. 이를 통해 프롬프트/대화를 기반으로 추가 컨텍스트를 추가하거나, 프롬프트를 검증하거나, 특정 유형의 프롬프트를 차단할 수 있습니다.1027사용자가 프롬프트를 제출할 때, Claude가 처리하기 전에 실행됩니다. 이를 통해 프롬프트/대화를 기반으로 추가 컨텍스트를 추가하거나, 프롬프트를 검증하거나, 특정 유형의 프롬프트를 차단할 수 있습니다.
991 1028
1029`UserPromptSubmit` hook은 `command`, `http`, `mcp_tool` 유형에 대해 기본 30초 시간 초과를 가지며, 이는 다른 이벤트에서 이러한 유형의 기본 600초보다 짧습니다. 이 hook은 모든 프롬프트 전에 실행되고 모델 처리가 완료될 때까지 차단하므로 stuck hook은 세션을 정지시킵니다. hook에 더 많은 시간이 필요하면 hook 항목에서 `timeout` 필드를 설정합니다.
1030
992#### UserPromptSubmit 입력1031#### UserPromptSubmit 입력
993 1032
994[공통 입력 필드](#common-input-fields) 외에도 UserPromptSubmit hook은 사용자가 제출한 텍스트를 포함하는 `prompt` 필드를 받습니다.1033[공통 입력 필드](#common-input-fields) 외에도 UserPromptSubmit hook은 사용자가 제출한 텍스트를 포함하는 `prompt` 필드를 받습니다.
2596 2635
2597비동기 hook이 발생하면 Claude Code는 hook 프로세스를 시작하고 완료를 기다리지 않고 즉시 계속합니다. hook은 동기 hook과 동일한 JSON 입력을 stdin을 통해 받습니다.2636비동기 hook이 발생하면 Claude Code는 hook 프로세스를 시작하고 완료를 기다리지 않고 즉시 계속합니다. hook은 동기 hook과 동일한 JSON 입력을 stdin을 통해 받습니다.
2598 2637
2599백그라운드 프로세스가 종료된 후 hook이 `systemMessage` 또는 `additionalContext` 필드가 있는 JSON 응답을 생성한 경우 해당 콘텐츠는 다음 대화 턴에서 Claude에 컨텍스트로 전달됩니다.2638백그라운드 프로세스가 종료된 후 hook이 `additionalContext` 필드가 있는 JSON 응답을 생성한 경우 해당 콘텐츠는 다음 대화 턴에서 Claude에 컨텍스트로 전달됩니다. `systemMessage` 필드는 Claude가 아닌 사용자에게 표시됩니다.
2600 2639
2601비동기 hook 완료 알림은 기본적으로 억제됩니다. 보려면 `Ctrl+O`로 자세한 모드를 활성화하거나 `--verbose`로 Claude Code를 시작합니다.2640비동기 hook 완료 알림은 기본적으로 억제됩니다. 보려면 `Ctrl+O`로 자세한 모드를 활성화하거나 `--verbose`로 Claude Code를 시작합니다.
2602 2641
2617 exit 02656 exit 0
2618fi2657fi
2619 2658
2620# 테스트를 실행하고 systemMessage를 통해 결과를 보고합니다2659# 테스트를 실행하고 additionalContext를 통해 결과를 Claude에 보고합니다
2621RESULT=$(npm test 2>&1)2660RESULT=$(npm test 2>&1)
2622EXIT_CODE=$?2661EXIT_CODE=$?
2623 2662
2624if [ $EXIT_CODE -eq 0 ]; then2663if [ $EXIT_CODE -eq 0 ]; then
2625 echo "{\"systemMessage\": \"Tests passed after editing $FILE_PATH\"}"2664 MSG="Tests passed after editing $FILE_PATH"
2626else2665else
2627 echo "{\"systemMessage\": \"Tests failed after editing $FILE_PATH: $RESULT\"}"2666 MSG="Tests failed after editing $FILE_PATH: $RESULT"
2628fi2667fi
2668jq -nc --arg msg "$MSG" '{hookSpecificOutput: {hookEventName: "PostToolUse", additionalContext: $msg}}'
2629```2669```
2630 2670
2631그런 다음 프로젝트 루트의 `.claude/settings.json`에 이 구성을 추가합니다. `async: true` 플래그를 사용하면 Claude가 테스트 실행 중에 계속 작업할 수 있습니다:2671그런 다음 프로젝트 루트의 `.claude/settings.json`에 이 구성을 추가합니다. `async: true` 플래그를 사용하면 Claude가 테스트 실행 중에 계속 작업할 수 있습니다: