[Claude Code] AI와 함께 macOS 알림 배너 툴 만들기 — 실패와 재시도에서 배운 것들

2026. 5. 27. 14:16·Develop/기타
728x90
반응형

 

Claude Code를 쓰다 보면 긴 작업을 돌려놓고 다른 일을 하다가, 작업이 끝났는지 확인하려고 계속 터미널로 눈길을 보내게 된다. 권한 요청이나 질문이 생겼을 때 눈치채지 못하면 한참이 지나서야 "아, Claude가 기다리고 있었구나" 하는 상황이 반복됐다. 그래서 직접 만들어보기로 했다. 작업 완료, 질문, 권한 요청을 macOS 화면 우측 상단 배너로 실시간 알려주는 툴이다. 만드는 과정이 순탄하지 않았고, 오히려 그 과정에서 배운 게 많아서 정리해본다.

GitHub: https://github.com/uri010/claude-notifier

만든 것

permission 배너

어떤 도구를 실행할지 배너로 표시하고, Yes / Session / No 버튼으로 즉시 응답할 수 있다. Claude Code가 결과를 받아 계속 진행한다.

stop 배너

프롬프트 처리가 끝나면 완료 메시지를 배너로 표시한다. 클릭하면 해당 터미널 탭으로 자동 포커스된다.

question 배너

Claude가 질문할 때 배너에 요약을 표시한다. 클릭하면 터미널로 이동해 직접 답변할 수 있다.

터미널이 이미 포커스 상태라면 배너를 띄우지 않는다. 다른 앱을 사용 중일 때만 알림을 표시하고, 터미널로 전환하는 순간 모든 배너가 자동으로 닫힌다. "Claude is waiting" 같은 단순 대기 메시지는 필터링해서 실제 응답이 필요한 알림만 뜨도록 했다.

 

첫 번째 시도 — 방향이 다섯 번 뒤집혔다

첫 메시지는 이랬다.

"클로드 실행하다가 사용자한테 권한 확인을 받을 때 알람이 안떠서 불편해요. 이걸 해결할 방법을 모색해주세요."

문제는 정확히 짚었지만, 내가 원하는 것이 무엇인지는 하나도 전달하지 않은 셈이었다. AI는 해결책을 제안했고, 나는 쓰다 보니 마음에 안 들었고, 또 다른 방향을 요청했다. 이 사이클이 무려 다섯 번 반복됐다.

1단계 — osascript 소리 알림: AI가 소리로 알려주는 방식을 제안했다. 평소에 소리를 끄고 생활하는 터라 바로 거절했다.

2단계 — 메뉴바 아이콘 + 드롭다운 메뉴: 메뉴바에 아이콘을 띄우고 클릭하면 내용이 나오는 방식이었다. 막상 써보니 "아이콘을 눌러야만 하나요? 제가 원하는 건 알림이 발생하면 아이콘 바로 밑으로 내용이 뜨길 바랬어요"가 됐다.

3단계 — Dock 옆 캐릭터 점프 애니메이션: Claude 캐릭터가 Dock 옆에서 점프하는 방식을 요청했다. 외부 모니터를 연결 해제하니 아예 사라졌다. 환경을 미리 말하지 않았으니 당연한 결과였다.

4단계 — terminal-notifier: macOS 알림처럼 보이는 외부 도구를 사용했는데, "배너가 안 떴어요. 맥 기본 배너를 이용하는 방법은 없나요?"가 됐다.

5단계 — macOS 스타일 커스텀 배너: 결국 이 방향으로 결정됐다. 처음 메시지를 보낸 지 한참이 지나서야.

기술적인 에러도 중간중간 터졌다. Python rumps 라이브러리를 쓰다가 AttributeError가 반복됐고, 배너가 표시되지 않거나 클릭해도 터미널로 이동하지 않는 문제가 이어졌다. 세션이 끝날 무렵에는 이렇게 요청하고 있었다.

"그냥 직접 배너 뜨면 허용, 항상 허용, 거부 테스트하고 계속 디버깅하면서 고쳐서 저한테 알려줄 수 없나요?"

AI에게 자율 디버깅을 맡긴 채 세션을 닫았다. 69개의 사용자 메시지를 주고받고도 완성되지 않았다.

 

두 번째 시도 — 요구사항 인터뷰부터

다시 시작할 때는 접근 방식을 바꿨다.

"클로드 코드를 사용하면서 권한을 확인하거나, 일을 완료했을 때 알림을 받을 수 있는 기능이 필요합니다. 이 기능을 구현하기 위해 정해야 할 사항들을 인터뷰 방식으로 물어봐주세요."

AI가 하나씩 물어봤다. 어떤 터미널 앱을 쓰는지, tmux를 사용하는지, 터미널이 화면 앞에 있을 때도 배너를 띄워야 하는지, 권한 요청은 어떻게 처리할지, 배너를 클릭하면 어떤 동작을 해야 하는지. 이렇게 먼저 정리하고 나니 설계가 처음부터 내 환경에 맞게 잡혔다. "이건 내 환경에 안 맞아"로 방향을 뒤집는 일이 없었다.

모든 권한을 부여하고 AI가 직접 빌드·실행·테스트까지 반복하도록 했다. 사람이 중간에 개입하는 루프 없이 초안이 만들어졌다. 다만 이 시도도 버그가 적지 않았다. 116개의 메시지를 주고받으며 디버깅을 이어갔고, 컨텍스트가 넘치면서 세션이 여러 번 나뉘었다. 결국 디렉터리를 새로 만들고 완전히 정리된 프로젝트로 다시 시작했다. 그게 지금의 claude-notifier다.

 

만들면서 나온 버그들

① 'Claude is waiting' 메시지가 배너로 떴다.

두 번째 시도 때도 마찬가지였다. "아무것도 안 하고 있는데 Claude is waiting 어쩌고 하는 질문 배너가 뜹니다"라는 문제가 그대로 이어졌다. 메시지 내용을 검사해서 해당 패턴을 필터링하는 방식으로 해결했다.

② 한국어로 설정된 맥에서 포커스 감지가 안 됐다.

macOS를 한국어로 설정하면 Terminal.app이 "터미널"로 표시된다. 영어 이름만 체크하고 있었으니 포커스 감지 자체가 작동하지 않았다.

③ 배너 첫 클릭이 버튼에 반응하지 않았다.

"배너를 누르면 해당 터미널로 이동 안 함, 2~3번 클릭 필요"는 두 번째 시도 때부터 있던 문제였다. NSPanel의 acceptsFirstMouse를 재정의해서 첫 클릭부터 바로 동작하도록 했다.

④ tmux 포커스가 엉뚱한 패널로 이동했다.

"정확히 5번째 탭의 6이라는 tmux session에 3번째 터미널에서 알림이 왔는데 다른 곳으로 넘어갔습니다"는 두 번째 시도의 마지막 메시지였다. display-message가 현재 클라이언트 기준으로 동작하다 보니 실제 Claude가 있는 pane이 아닌 다른 위치로 이동하는 문제였다. pane의 TTY를 역조회해서 정확한 위치를 찾는 방식으로 해결했다.

⑤ allowSession이 즉시 반영되지 않았다.

"이 세션 동안 허용" 버튼을 눌러도 다음 요청에 또 배너가 떴다. 세션 캐시 기록 로직이 Swift 앱과 bash 훅 양쪽에 이중으로 있었고 타이밍 문제가 있었다. 훅이 단독으로 처리하도록 정리했다.

 

보안 문제 — 나중에 발견해서 다행이었다

기능을 다 구현한 뒤, push 전에 보안 검토를 별도로 요청했다. 배너 클릭 시 터미널로 포커스를 복원하는 기능에서, HTTP 페이로드의 tty 필드가 검증 없이 AppleScript 문자열에 직접 삽입되고 있었다. 이론적으로 악의적인 tty 값이 들어오면 임의 스크립트를 실행할 수 있는 상태였다. /dev/[a-zA-Z0-9/]+ 정규식으로 TTY 경로를 먼저 검증한 뒤 AppleScript에 전달하도록 수정했다. 배너 상한 초과 시 메모리 누수도 같이 잡혔다. 배너가 20개 한도를 넘어 드롭될 때 resolve만 호출하고 remove를 누락해서 pending 항목이 앱 재시작 전까지 남아 있던 문제였다. 기능 구현 중에는 전혀 신경 쓰지 못했던 부분들이었다.

 

결국 배운 것

첫 시도에서 69개의 메시지를 주고받고도 완성하지 못한 건, AI가 부족해서가 아니라 내가 뭘 원하는지를 전달하지 않은 것이 문제였다. 소리가 꺼져 있다는 것도, tmux를 쓴다는 것도, 외부 모니터가 있다는 것도. AI는 그걸 알 방법이 없었다. 인터뷰 방식으로 먼저 환경과 요구사항을 정리하고 전권을 준 뒤 자율 진행시켰더니 훨씬 수월하게 만들어졌다. 보안과 테스트는 기능 완성 후 별도 체크포인트를 두는 것이 효과적이었다. 구현 중에 같이 하려면 흐름이 끊기는 반면, 마지막에 집중적으로 검토하면 놓쳤던 부분이 잘 드러났다.

728x90
반응형

'Develop > 기타' 카테고리의 다른 글

[Claude Code] harness vs 순수 Claude Code: macOS Dynamic Island 앱을 만들기  (0) 2026.05.28
'Develop/기타' 카테고리의 다른 글
  • [Claude Code] harness vs 순수 Claude Code: macOS Dynamic Island 앱을 만들기
yulee_to
yulee_to
  • yulee_to
    yulee
    yulee_to
  • 전체
    오늘
    어제
    • 전체 글 (172)
      • CS (2)
        • OS (0)
        • DB (0)
        • Network (2)
      • Develop (24)
        • Spring (9)
        • Java (12)
        • Python (0)
        • Algorithm (0)
        • 기타 (2)
      • PS (39)
        • C++ (39)
        • Java (0)
      • TIL (61)
      • Book (39)
        • 자바의 신 (32)
        • 스프링 입문을 위한 자바 객체 지향의 원리와 이해 (7)
      • ETC (4)
        • Blog (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    자바
    1일1백준
    aws
    자바의 신
    클라우드 활용 네트워크 엔지니어 부트캠프
    boj
    EC2
    부트캠프후기
    객체지향
    멀티캠퍼스it부트캠프
    스프링 입문
    Java
    TiL
    C++
    스터디
    에스넷시스템
    GodOfJava
    알고리즘
    에스넷시스템 부트캠프
    백준
  • 최근 댓글

  • 250x250
  • hELLO· Designed By정상우.v4.10.3
yulee_to
[Claude Code] AI와 함께 macOS 알림 배너 툴 만들기 — 실패와 재시도에서 배운 것들
상단으로

티스토리툴바