Rubric Labs
Claude Code가 긴 작업을 마쳤을 때 macOS 알림으로 알려주고, 알림을 클릭하면 작업하던 VSCode 워크스페이스 윈도우로 정확히 포커스가 돌아오게 만드는 Stop 훅 세팅이에요. Stop 훅의 stdin JSON에서 cwd를 꺼내 해당 폴더가 열린 윈도우를 콕 집어 띄웁니다. 핵심 동작: Stop 훅 stdin cwd로 VSCode 포커스.
← Tips
자동화 레시피· easy

Claude Code 작업 완료 알림 + 클릭 시 VSCode 포커스 자동화

Claude Code가 긴 작업을 마쳤을 때 macOS 알림으로 알려주고, 알림을 클릭하면 작업하던 VSCode 워크스페이스 윈도우로 정확히 포커스가 돌아오게 만드는 Stop 훅 세팅이에요. Stop 훅의 stdin JSON에서 cwd를 꺼내 해당 폴더가 열린 윈도우를 콕 집어 띄웁니다.

Claude Code한테 긴 작업 시켜놓고 다른 거 하다 보면 끝난 줄 모르고 지나가는 경우가 많아요. Stop 훅으로 macOS 알림을 쏘고, 알림을 클릭하면 작업하던 VSCode 워크스페이스 윈도우로 정확히 포커스가 돌아오게 만드는 세팅이에요. VSCode 윈도우를 여러 개 띄워놓고 작업하는 경우에도 해당 프로젝트 윈도우만 콕 집어 띄워줘요. 많이 공유되는 terminal-notifier 방법은 최근 macOS에서 권한·클릭 이벤트가 꼬이는 함정이 있어서, 후계 도구인 alerter를 쓰는 게 정답이에요.

준비물

  • macOS (알림센터)
  • Claude Code (Stop 훅 지원 버전)
  • 시스템 설정 → 알림 → 알림 요약이 꺼져 있어야 해요. 켜져 있으면 어떤 도구를 써도 실시간 알림이 안 떠요.

시스템 설정 → 알림 → '알림 요약' 섹션. 이 토글이 꺼져 있는 상태를 보여주는 스크린샷.

  • curl, unzip, bash, jq (macOS 기본 / jqbrew install jq)

스텝

1. alerter 바이너리 내려받기

Homebrew 포뮬러가 없어서 GitHub 릴리즈 zip을 받아 ~/.claude/bin/에 풀어요.

mkdir -p ~/.claude/bin ~/.claude/hooks
cd /tmp
curl -sL -o alerter.zip https://github.com/vjeantet/alerter/releases/download/v26.5/alerter-26.5.zip
unzip -o alerter.zip -d alerter-extract
mv alerter-extract/alerter ~/.claude/bin/alerter
chmod +x ~/.claude/bin/alerter
xattr -d com.apple.quarantine ~/.claude/bin/alerter 2>/dev/null

xattr -d 한 줄은 "확인되지 않은 개발자" Gatekeeper 차단을 풀어주는 거예요.

2. 권한 한 번 허용하기

처음 실행하면 macOS 알림 권한 다이얼로그가 떠요. "허용" 눌러주고 끝. 한 번만 하면 돼요.

~/.claude/bin/alerter --title 'Claude Code' --message '권한 허용 테스트' --timeout 10 &

3. 훅 스크립트 작성

~/.claude/hooks/notify-done.sh를 아래 내용으로 만들어요. 핵심 두 가지.

  1. Stop 훅이 stdin으로 넘겨주는 JSON에서 .cwd(현재 세션의 워크스페이스 경로)를 꺼내요.
  2. alerter가 알림 클릭 시 stdout으로 @CONTENTCLICKED를 반환 → open -a "Visual Studio Code" "$CWD"해당 폴더가 열린 윈도우만 포커스.

stdin JSON은 훅 커맨드에서 먼저 읽어 인자로 넘겨줄 거라(다음 스텝), 스크립트에선 $1로 받아요.

#!/bin/bash
INPUT="$1"
CWD=$(echo "$INPUT" | /usr/bin/jq -r '.cwd // empty' 2>/dev/null)
[ -z "$CWD" ] && CWD="$CLAUDE_PROJECT_DIR"

if [ -n "$CWD" ]; then
  MESSAGE="작업 완료: $(basename "$CWD")"
else
  MESSAGE="작업이 완료되었습니다"
fi

RESULT=$("$HOME/.claude/bin/alerter" \
  --title 'Claude Code' \
  --message "$MESSAGE" \
  --sound default \
  --timeout 60)

if [ "$RESULT" = "@CONTENTCLICKED" ]; then
  if [ -n "$CWD" ] && [ -d "$CWD" ]; then
    open -a "Visual Studio Code" "$CWD"
  else
    open -a "Visual Studio Code"
  fi
fi

open -a "Visual Studio Code" "$CWD"는 해당 폴더가 이미 열린 VSCode 윈도우가 있으면 그 윈도우를 포커스하고, 없으면 새로 열어줘요. 이게 멀티 윈도우 분기의 핵심이에요.

실행 권한 부여.

chmod +x ~/.claude/hooks/notify-done.sh

4. Claude Code Stop 훅 등록

~/.claude/settings.jsonhooks.Stop에 아래 entry를 추가해요. 이미 있으면 command만 바꾸면 돼요.

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "INPUT=$(cat); nohup bash \"$HOME/.claude/hooks/notify-done.sh\" \"$INPUT\" >/dev/null 2>&1 &"
          }
        ]
      }
    ]
  }
}

포인트 두 개.

  • INPUT=$(cat) — Stop 훅이 넘겨주는 JSON을 훅 커맨드 레벨에서 먼저 캡처. nohup ... &로 백그라운드에 분리된 뒤엔 stdin이 닫혀서 스크립트가 JSON을 못 읽어요. 그래서 인자로 넘기는 방식.
  • nohup ... & — 반드시 백그라운드 분리. alerter는 클릭되거나 타임아웃될 때까지 프로세스가 살아 있어서, 안 떼면 Claude Code가 다음 입력을 못 받고 멈춘 것처럼 보여요.

확인 방법

VSCode 윈도우 여러 개 띄워두고, 각각에서 Claude Code에 서로 다른 작업을 시켜보세요.

  • 작업 종료 시점에 "작업 완료: 폴더명" 알림이 뜨면 성공 (어느 프로젝트가 끝났는지 한눈에 보임)
  • 알림을 클릭하면 해당 워크스페이스가 열린 VSCode 윈도우로 바로 포커스
  • 60초 무시하면 알림이 사라지지만 알림센터엔 남아 있음
  • 알림이 뜬 동안에도 Claude Code는 계속 사용 가능

macOS 알림센터에 Claude Code 알림 두 개가 쌓여 있는 모습. 각 알림은 '작업 완료: rubriclabs', '작업 완료: erp-mardi-client'처럼 프로젝트 폴더명이 메시지에 찍혀 있어 어느 윈도우 작업이 끝났는지 구분 가능하다.

응용

  • 메시지/사운드/타임아웃: notify-done.sh--message, --sound, --timeout 값만 바꾸면 돼요.
  • 에디터 변경: open -a "Visual Studio Code" "$CWD" 자리를 open -a "Cursor" "$CWD" 같이 교체.
  • 세션 정보 활용: stdin JSON에는 .cwd 외에도 .session_id, .transcript_path가 들어와요. jq로 꺼내서 알림 메시지나 로그에 섞어 쓸 수 있어요.
  • 작업 종류별 분기: transcript_path를 읽어서 마지막 메시지 종류별로 사운드나 메시지를 분기하는 식으로도 확장 가능해요.

트러블슈팅

알림이 아예 안 뜬다: 거의 100% "알림 요약"이 켜져 있어요. 시스템 설정 → 알림에서 요약을 끄고 다시 시도.

알림 허용을 눌렀는데도 안 뜬다: terminal-notifier 잔재가 섞여 있을 가능성. terminal-notifier 2.0.0은 오래된 알림 API를 써서 최근 macOS에서 번들 ID 권한 매칭이 꼬여요. 시스템 설정에는 "허용"으로 보이지만 실제론 막혀 있는 상태. terminal-notifier를 쓰는 기존 훅이 있다면 alerter 버전으로 완전히 교체해요.

클릭해도 VSCode가 안 올라온다: -sender com.microsoft.VSCode 같은 꼼수 플래그를 붙였는지 확인. 이 플래그가 있으면 클릭 이벤트가 VSCode로 먼저 가버려서 스크립트의 open -a가 먹지 않아요. 이번 레시피의 스크립트처럼 -sender 없이 쓰세요.

Claude Code가 멈춘 것처럼 보인다: settings.json에서 nohup ... &를 빠뜨렸을 때 나타나요. alerter 프로세스가 훅 호출을 붙잡고 있어서 그래요. nohup과 끝의 & 둘 다 있어야 해요.

폴더명이 안 뜨고 "작업이 완료되었습니다"만 뜬다: INPUT=$(cat)이 settings.json의 커맨드 앞에 빠져 있거나, jq가 설치 안 된 경우예요. which jq로 확인하고, INPUT=$(cat); nohup ... 순서가 맞는지 다시 보세요. nohup을 먼저 두면 stdin이 이미 닫혀서 못 읽어요.

여러 윈도우에서 같은 폴더를 열어두면?: VSCode가 어느 윈도우를 띄울지 임의로 골라요. 보통 1 워크스페이스 = 1 윈도우라 실무에선 문제 안 되지만, 같은 프로젝트 여러 윈도우로 쓰는 습관이면 구분이 안 돼요.