
Claude Code Hooks 구현 가이드 — 세션 종료 시 자동으로 git push하는 메커니즘을 코드로 해설
요약
Claude Code의 hooks 기능을 활용하여 세션 종료 시 자동으로 git push를 수행하는 메커니즘을 설명합니다. LLM의 프롬프트 지시 대신 OS 레벨의 이벤트를 활용해 작업의 연속성과 안정성을 확보하는 방법을 다룹니다.
핵심 포인트
- Claude Code hooks는 LLM 지시가 아닌 OS 레벨의 이벤트 인터럽트로 동작함
- session_end.js를 통해 세션 종료 시 변경 사항을 감지하고 자동 commit/push 가능
- hook 스크립트 작성 시 process.exit(0)를 명시하지 않으면 UI 프리즈 발생 주의
- checkpoint.js를 활용해 세션 간 대화 컨텍스트를 유지하는 방법 제시
.claude/hooks/
에는 9개의 스크립트가 있다.
이 AI 영업 회사에는 상주 프로세스가 3개뿐이다 (ai-office, vsync-crm, accea-crm, PM2 관리). 하지만 실제로 회사의 "습관"을 만들고 있는 것은 상주조차 하지 않는 9개의 Node.js/PowerShell 스크립트다.
$ ls .claude/hooks/
check_handoff.ps1 detect_corrections.ps1 session_counter.json
checkpoint.js log_file_saves.js session_end.js
...
이 중 .js가 7개, .ps1이 2개다. 호출되었을 때만 기동하며 수백 밀리초(ms) 내에 종료된다. 이 기사에서는 실제로 작동하고 있는 2개의 코드를 인용하며 "Claude Code의 자율 가동을 뒷받침하는 Hook 구현"을 해설한다.
Hook은 "Claude Code에 대한 명령"이 아니라 "OS 이벤트에 대한 인터럽트(Interrupt)"
Claude Code의 settings.json에는 hooks 섹션이 있어, SessionStart (세션 시작) · UserPromptSubmit (발언 전송 시) · PreToolUse (도구 실행 전) · Stop (세션 종료)와 같은 이벤트에 임의의 명령어를 연결할 수 있다.
{
"hooks": {
"UserPromptSubmit": [
...
포인트는 Claude라는 LLM에게 시키는 것이 아니라, 이벤트 발생 시 OS 레벨에서 확실하게 스크립트를 기동시킨다는 점이다. 프롬프트로 "반드시 HANDOFF.md를 git push 하세요"라고 몇 번을 써도, 긴 대화에서는 그 지시가 컨텍스트(Context) 깊숙이 묻혀 실행되지 않을 수 있다. Hook은 그런 일이 일어나지 않게 한다.
session_end.js — 세션 종료를 감지하여 자동 push
구현 1: 실제로 작동하고 있는 코드 (/root/ai-sales-company/.claude/hooks/session_end.js)는 다음과 같다.
const diff = execSync('git diff --name-only HEAD', { cwd: REPO, timeout: 10000 }).toString().trim();
const hasHandoff = diff.split('\n').some(f => f.includes('HANDOFF') || f.includes('output/'));
if (hasHandoff) {
...
git diff --cached --quiet는 스테이징(Staged)된 차분이 없으면 exit 0, 있으면 exit 1을 반환한다. 이 종료 코드(Exit Code)의 차이를 try/catch로 포착하여 "차분이 있을 때만 commit 한다"는 판정에 사용하고 있다. 빈 커밋으로 git 로그를 더럽히지 않기 위한 최소한의 분기다.
마지막의 process.exit(0)는 생략할 수 없다. 실제로 사내의 CLAUDE.md에는 "훅(Hook)의 JS를 편집할 때: 끝부분의 process.exit(0)를 생략하지 말 것 (생략하면 UI가 프리즈(Freeze)됨)"이라고 빨간 글씨로 적혀 있다. 훅은 Claude Code의 메인 프로세스와 표준 입출력(Standard I/O)으로 주고받으며, 명시적으로 프로세스를 종료시키지 않으면 Claude Code 측이 응답 대기 상태로 멈춰버린다. 한 번 이 문제로 개발 중이던 세션이 굳어버려, 터미널 자체를 재시작해야 했던 적이 있다.
checkpoint.js — 대화를 넘나드는 기억을 생성
구현 2: 세션이 끝나면 대화의 컨텍스트는 사라진다. 다음 기동 시에 "지난번에 무엇을 하고 있었는지"를 알 수 있는 수단이 필요하다. checkpoint.js는 발언할 때마다 session_checkpoint.md에 내용을 추가하고, 일정 간격으로 AI에게 요약을 작성하게 한다.
const SESSION_GAP_MIN = 30;
const CHECKPOINT_INTERVAL = 5;
// 이전 업데이트로부터 30분 이상 경과했다면 "새 세션"으로 간주
...
process.stdout.write
process.stdout.write로 출력한 문자열은 Claude Code가 그대로 시스템 프롬프트 (System Prompt)의 일부로 읽어들인다. 즉, Hook은 단순히 "스크립트를 실행하는 것"뿐만 아니라 "Claude에게 다음에 무엇을 할지 지시하는" 채널이기도 하다. 5건마다 요약을 작성하게 하는 이유는 컨텍스트 (Context)가 너무 길어지기 전에 정기적으로 현재 위치를 기록하게 하기 위함이다. 실제로 이 글을 쓰는 도중에도 이 메커니즘이 작동하여, AI 요약 추가를 요청받았다.
30분의 간격 판정에도 이유가 있다. 심야에 스케줄러 (Scheduler)가 기동하는 것은 이전 대화 세션과 무관하므로 "새 세션"으로 구분하고 싶다. 반대로 몇 분 간격의 짧은 상호작용은 동일한 세션으로 연결하고 싶다. lastUpdate의 타임스탬프 (Timestamp) 차이만으로 이 두 가지를 구분하고 있다.
detect_corrections.js
— "틀렸다"는 말을 놓치지 않는다
구현 3: 오너가 "틀려", "안 돼", "다시 해"라고 말할 때, 그것은 단순한 대화가 아니라 수정의 시그널 (Signal)이다. 이를 놓치면 똑같은 실수를 반복하게 된다.
const correctionWords = [
'違う','ちがう','ダメ','だめ','やり直し','間違い','そうじゃない','NG'
];
...
키워드를 감지했다고 해서 Hook이 스스로 git commit을 하는 것은 아니다. 어디까지나 "Claude에게 확인을 촉구"하는 것에 그친다. 기록할지 여부에 대한 최종 판단은 오너에게 맡기는 설계다. 승인 판정이 내려지면 /remember 명령어로 lessons_learned.md에 영속화 (Persistence)된다. 이 회사의 전체 19개 에이전트 (Agent)가 가진 "교훈 파일"은 거의 모두 이 메커니즘을 통해 쌓이고 있다.
왜 전부 Hook으로 몰아넣었는가
처음에는 Hook 없이 프롬프트 (Prompt) 지시문만으로 운용했다. 고장 나는 방식은 두 가지 패턴이었다.
- 대화가 길어지면 HANDOFF 업데이트 지시가 무시됨
- 세션 (Session)이 크래시 (Crash)되면, 다음 기동 시 이전 상황을 완전히 알 수 없게 됨
둘 다 "LLM에게 매번 상기시키는" 방식으로는 해결되지 않았다. 현재의 설계는 반대로, Claude의 기억력에 의존하는 부분을 최대한 줄이고, OS 이벤트 (OS Event)로 확실하게 발화하는 인프라 (Infrastructure) 측으로 처리를 옮겼다. 크래시 감지도 마찬가지로, crash_state.json에 cleanExit: false를 상시 기록하고, session_end.js가 정상 종료 시에만 true로 덮어쓴다. 다음 SessionStart에서 cleanExit가 false인 상태라면 "지난번에 크래시가 발생했다"라고 기계적으로 판정할 수 있다. 실제로 이 HANDOFF나 이 글을 쓰고 있는 지금의 세션도, 직전 세션의 크래시를 session_recovery.js가 감지하여 복구 로그를 자동으로 읽어들인 상태에서 시작되었다.
이 회사의 Hook·스케줄러·전체 19개 에이전트 설계를 해설하는 책
.claude/hooks/ 내 모든 파일의 구현, 크래시 복구의 완전한 로직, .claude/agents/ 19종의 설계 패턴을 실제 코드와 설정 파일과 함께 해설하는 Zenn 유료 서적을 집필하고 있다.
Claude Code로 만드는 AI 자동화 회사 완전 해설 (¥4,980)
가공의 샘플 코드가 아니라, 지금 이 순간 작동하고 있는 VPS 상의 파일을 그대로 싣고 있다.
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기