동작 원리
세 개의 레이어, Ask Loop, 그리고 어떤 알림이 어디서 오는지.
Hwip은 협력하는 세 레이어다. 훅은 모델의 협조와 무관하게 발동하고, MCP 도구는 모델이 의도적으로 당신에게 닿을 수 있게 해준다.
hwipit/plugin (Claude Code 플러그인)
├─ hooks/hwip-setup.js → SessionStart: 동작 규칙 주입
├─ hooks/hwip-stop.sh → Stop: 자동 완료 푸시
├─ hooks/hwip-ask.sh → PreToolUse(AskUserQuestion): 질문 푸시
├─ hooks/hwip-approve.sh → PreToolUse(Bash): 위험한 명령을 폰에서 승인(옵트인)
├─ hooks/hwip-remote.sh → UserPromptSubmit: 폰에서 보낸 메시지 → REMOTE 모드
├─ hooks/hwip-herdr.sh → 에이전트 상태 → herdr 사이드바, `hwip cc` 패널용
├─ .mcp.json → MCP 서버 등록 (`hwip mcp`)
└─ 기반:
├─ @hwip/cli → 훅 + notify/list/dismiss + tmux 원격 조종
└─ @hwip/mcp-server → hwip_ask / notify / clipboard / file …| 레이어 | 패키지 | 역할 | 신뢰도 |
|---|---|---|---|
| 훅 | @hwip/cli | Claude 이벤트에 자동 발동 | 100%, AI 협조 불필요 |
| MCP 서버 | @hwip/mcp-server | AI가 호출하는 도구: ask, notify, file 등 | 모델이 규칙을 따르는지에 달림 |
| 플러그인 | hwipit/plugin | 훅, MCP, 규칙을 묶음 | 한 번 설치 |
세션 흐름과 Ask Loop
SessionStart 훅
├─ ~/.hwip/config.json과 프로젝트 상태 파일 읽기
├─ muted → 훅은 조용, 도구는 쓰지 않음
├─ HOOK_ID 없음 → 알림 전용 규칙 주입
├─ REMOTE 진행 중 → REMOTE 규칙 주입
└─ 그 외 → NORMAL 규칙 주입, 프로젝트 다이얼에 맞는 Push Signal
작업 중…
├─ NORMAL (터미널 앞)
│ ├─ 질문 → AskUserQuestion 선택창 + Ask 훅 푸시
│ └─ 작업 완료 → Stop 훅 푸시만 (다이얼에 따라)
└─ REMOTE (폰의 메시지로 진입)
├─ 모든 응답 → hwip_ask → 모바일의 버튼·텍스트 답장 → 계속
├─ 질문 → hwip_ask (선택창은 거부됨)
└─ "Done" 탭 / 터미널에서 입력 → NORMAL로 복귀상태는 두 가지다. 터미널 앞(NORMAL)에서 Claude는 추가로 할 일이 없다. 질문은 로컬 선택창을 열고, 완료는 Stop 훅 푸시일 뿐이며, 지켜보는 세션이 폰 탭을 기다리며 멈추는 일은 없다.
세션이 REMOTE에 들어가면 Claude는 모든 응답의 마지막 행동으로 hwip_ask를 쓴다. 당신의 답은 직접
지시로 취급되어 재확인 없이 실행되고, Claude는 다시 묻는다. Done을 탭할 때까지 이어진다.
루프는 폰에서 시작된다. 앱의 에이전트 채팅으로 메시지를 보내면 hwip listener가 주입한 내용을
정확히 기록하고, 플러그인의 UserPromptSubmit 훅이 일치를 확인해 Claude가 원격임을 안다.
Hook ID는 폰으로 구동할 수 있다는 뜻이지 지금 구동 중이라는 뜻이 아니다. NORMAL에서는 선택창이 늘 열리던 대로 열리고, 질문이 기다리고 있다고 알려주는 Ask 훅 푸시도 그대로 받는다.
REMOTE의 질문
세션이 REMOTE인 동안 짧고 버튼으로 답하기 좋은 AskUserQuestion은 거부되고, Claude에게 돌려보내져
hwip_ask로 다시 묻게 된다. 선택창은 원격 채널로는 더 나쁘다. tmux가 필요하고, 터미널 화면을 읽고
방향키 횟수를 세야 하며, 답이 키 입력으로 도착해 세션이 폰으로 계속 구동되지 못하기 때문이다.
긴 질문, 긴 옵션 문구, preview가 달린 옵션은 여전히 선택창을 연다. 거부된 질문과 같은 질문이
반복되면 통과시키므로, MCP 서버에 닿지 못할 때 세션이 갇히지 않는다.
알림 매트릭스
무엇이 무엇을 발동하는지, 중복될 수 있는지:
| 이벤트 | 출처 | 신뢰도 | 중복 |
|---|---|---|---|
| 작업 완료 | Stop 훅 | 100% | 없음 — AI가 이미 hwip_ask를 보냈으면 건너뜀 |
| 질문 발생 | Ask 훅 | 100% | 없음 |
| 판단·입력 필요 | hwip_ask | 모델이 호출하는지에 달림 | 없음 |
| 수동 푸시 | hwip_notify | 요청 시 | 없음 |
폰에서 세션 조종하기
Claude를 hwip cc로 띄우면 폰의 Active Agents 선택기가 실행 중인 세션에 직접 입력할 수 있다.
hwip_ask 창이 닫힌 뒤에도 마찬가지다. 소파에서 리팩터링을 시작하고, 점심 때 후속 질문에 답하고,
돌아오면 끝난 브랜치가 기다린다.
hwip cc # 폰이 닿는 이름 붙은 tmux 세션 안의 claude
hwip codex # Codex도 동일
hwip gemini # Gemini도 동일한 번에 끝나는 설정과 전체 아키텍처는 CLI → 원격 조종에 있다.
자율 모드
Claude에게 시간 예산을 주고 자리를 떠난다.
/hwip-auto 2h fix the flaky testsClaude는 예산이 다할 때까지 탐색 → 계획 → 구현 → 검증 → 커밋을 반복하며, 검증된 단위마다 작업 브랜치에 커밋한다.
질문은 기본값이 명시된 hwip_ask 버튼으로 폰에 도착한다. 답해서 방향을 정하거나, 무시하면 타임아웃
뒤 안전한 기본값으로 진행한다. 푸시, 배포, 삭제처럼 되돌릴 수 없는 작업은 타임아웃으로는 절대 실행되지
않고 명시적인 탭을 기다린다.
실행은 커밋한 것, 건너뛴 것, 기본값으로 처리한 것의 리포트와 함께 끝나며, 연장·리뷰·종료 버튼이 붙는다.
기간은 2h, 90m, 1h30m 또는 분 단위 숫자를 받고 기본값은 1h다. /hwip-mode는 실행 중에 남은
예산을 보여준다.