PreCompact 훅으로 컨텍스트 압축 전 자동 처리하기
Claude Code v2.1.105에 추가된 PreCompact 훅을 설정하면 컨텍스트 압축이 시작되기 직전에 스크립트를 실행하거나 압축 자체를 막을 수 있어요. 설정 파일 하나로 중요한 작업 중간에 컨텍스트가 날아가는 상황을 방지할 수 있어요.
긴 작업을 Claude Code에 맡겨두다 보면 컨텍스트가 꽉 차서 자동 압축이 일어나는 순간이 있어요. 대부분은 괜찮은데, 파일을 여러 개 수정하는 중간이거나 롤백이 필요한 상태라면 압축 타이밍이 꽤 불편해요. v2.1.105부터는 PreCompact 훅으로 이 시점을 가로챌 수 있어요.
훅이 exit code 2를 반환하거나 {"decision":"block"}을 출력하면 Claude Code는 압축을 멈춰요. 그냥 로그를 남기거나 스냅샷을 찍고 싶다면 exit code 0으로 정상 종료하면 압축은 그대로 진행돼요.
준비물
- Claude Code v2.1.105 이상
- 프로젝트 루트에
.claude/디렉터리 생성 권한 - bash 또는 node 실행 환경
스텝
1. 훅 설정 파일 만들기
.claude/settings.json이 없다면 새로 만들고, 있다면 hooks 키를 추가해요. PreCompact 훅은 hooks.PreCompact 배열에 등록해요.
{
"hooks": {
"PreCompact": [
{
"hooks": [
{
"type": "command",
"command": "bash .claude/pre-compact.sh"
}
]
}
]
}
}
2. 스크립트 작성하기
.claude/pre-compact.sh를 만들어요. 이 스크립트가 실제로 "압축을 막을지, 그냥 로그만 남길지"를 결정하는 곳이에요.
압축을 막고 싶을 때 exit code 2를 쓰거나 JSON을 출력하는 두 가지 방식 모두 동작해요. 아래는 BLOCK_COMPACT 환경변수가 세팅돼 있으면 막고, 아니면 타임스탬프만 기록하는 예시예요.
#!/bin/bash
LOG_FILE=".claude/compact-log.txt"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] PreCompact hook triggered" >> "$LOG_FILE"
# 압축을 막아야 하는 조건 체크
if [ -f ".claude/BLOCK_COMPACT" ]; then
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Blocking compaction (BLOCK_COMPACT file found)" >> "$LOG_FILE"
echo '{"decision":"block"}'
exit 0
fi
# 현재 작업 디렉터리 스냅샷 (git이 있다면)
if git rev-parse --git-dir > /dev/null 2>&1; then
git stash list | head -5 >> "$LOG_FILE"
fi
# 정상 종료 → 압축 진행
exit 0
실행 권한도 줘야 해요.
chmod +x .claude/pre-compact.sh
3. 압축 차단 파일 만들기
중요한 작업을 시작하기 전에 .claude/BLOCK_COMPACT 파일을 만들면 그 세션 동안 압축이 막혀요. 작업이 끝나면 지우면 돼요.
# 압축 차단 시작
touch .claude/BLOCK_COMPACT
# 작업 완료 후 해제
rm .claude/BLOCK_COMPACT
확인 방법
Claude Code 세션을 열고 컨텍스트를 충분히 채운 뒤 압축이 트리거되면 .claude/compact-log.txt에 로그가 찍혀요.
tail -f .claude/compact-log.txt
BLOCK_COMPACT 파일이 있는 상태라면 로그에 Blocking compaction 메시지가 보이고 압축이 일어나지 않아요. 파일을 지운 뒤 다시 트리거되면 압축이 정상 진행되는 걸 확인할 수 있어요.
응용
스크립트 안에서 외부 API를 호출하거나 Slack 알림을 보내도 돼요. 압축 직전에 "지금 컨텍스트 압축이 예정되어 있어요" 같은 알림을 팀 채널에 쏘는 용도로도 쓸 수 있어요. exit code 2 방식은 JSON 출력 없이 바로 차단하고 싶을 때 더 간단하고, {"decision":"block"} 방식은 나중에 이유나 메타데이터를 함께 넘겨야 할 때 확장하기 좋아요.
트러블슈팅
훅이 아예 실행되지 않는다면 Claude Code 버전을 확인해요. v2.1.105 미만이면 PreCompact 키 자체를 인식하지 못해요.
claude --version
스크립트가 실행은 되는데 차단이 안 된다면 {"decision":"block"} 출력이 stdout으로 나가고 있는지 확인해요. stderr로 나가면 무시돼요. 로그 파일 쓰기도 stdout이 아닌 파일로 리다이렉트해야 훅 파서가 헷갈리지 않아요.
.claude/settings.json 파싱 오류가 있으면 훅 전체가 무시되니까, JSON 문법은 꼭 validator로 한 번 확인해두는 게 편해요.
이 설정으로 "언제 압축을 허용할지"를 코드로 제어할 수 있게 돼요.