명령 레퍼런스
zeph의 모든 명령과 플래그, 종료 코드, 환경변수.
# 알림 보내기
zeph notify --title "Deploy done" --body "v2.1.0 shipped"
# 우선순위 지정
zeph notify --title "Build failed" --priority high --url https://ci.example.com/123
# 최근 푸시 목록
zeph list
zeph list --limit 10 --type note
# 푸시 해제
zeph dismiss push_01JXY...
zeph dismiss --all
# 현재 에이전트 세션 이름 바꾸기 (앱의 Agents 목록에 반영)
zeph rename "Prod deploy"
zeph rename --clear # 기본 이름으로 되돌림
# 연결 테스트
zeph test
# listener가 닿을 수 있도록 이름 붙은 tmux 세션에서 에이전트 실행
zeph cc # claude
zeph codex # codex
zeph cursor # cursor-agent (Cursor CLI, IDE 아님)
zeph gemini # gemini
# 상주 listener 실행 (포그라운드; 원하면 백그라운드로)
zeph listener
zeph listener --ws-url wss://... # 설정 오버라이드
# JSON 출력
zeph notify --title "Hello" --json명령
| 명령 | 설명 |
|---|---|
login | 브라우저 로그인: localhost 루프백으로 API 키와 hook을 받아 ~/.zeph/config.json에 자동 저장 (--web-url, --timeout). 복사·붙여넣기 없음 |
install (별칭: setup) | 한 명령 설정: 에이전트 감지, 설정 저장, rules·hooks·MCP 설치. 저장된 설정이 없으면 브라우저 로그인을 자동으로 연다. --only claude,cursor,…는 선택기를 건너뛴다 |
uninstall | 감지된 모든 에이전트에서 Zeph 제거 (--dry-run, --purge) |
verify | 감지된 에이전트 전반의 설치 상태 점검 (--ping은 실제 API 호출) |
check-update | npm에 더 새 버전이 있는지 확인 |
notify | 푸시 알림 전송 |
list | 최근 푸시 알림 목록 |
dismiss <id> | 푸시 해제, 또는 --all |
rename <name> | 앱에 표시될 현재 에이전트 세션 이름을 설정한다. zeph cc 세션 안에서 실행하며 --clear가 초기화한다. tmux 세션과 이 머신의 listener 디바이스 id를 자동 감지해 별칭이 올바른 디바이스에 붙는다 |
test | API 키와 연결이 동작하는지 확인하는 테스트 푸시를 보낸다. 디바이스에 실제로 알림이 울린다 — 모의 전송이 아니다 |
cc · codex · cursor · gemini | 에이전트를 zeph-<project> tmux 세션에서 실행한다. 붙어 있는 세션과 충돌하면 -2, -3 접미사가 자동으로 붙는다. 첫 호출에서 백그라운드 listener를 자동으로 띄워 폰 선택기가 그냥 동작하게 한다. 뒤에 붙인 인자는 에이전트로 전달된다. tmux로 조종 가능한 에이전트는 이 넷이며, zeph install이 설정하는 여덟보다 작은 집합이다 — zeph cursor는 IDE가 아니라 Cursor의 터미널 TUI인 cursor-agent를 띄운다 |
listener | 보통 필요 없다 — zeph cc가 자동으로 띄운다. 상주 데몬: WebSocket으로 구독하고, tmux 세션 목록을 5초마다 보고하며, agent.command 푸시를 해당 세션에 주입한다 |
remote-hook <agent> | 직접 실행하지 않는다. zeph install이 Codex·Gemini에 심는 prompt-submit hook이 이 명령을 호출해 메시지가 폰에서 주입된 것임을 표시한다. CLI & SDK → 원격 조종 참고 |
notify 옵션
| 플래그 | 설명 |
|---|---|
--title <text> | 푸시 제목 (기본값: "Task done") |
--body <text> | 푸시 본문 (기본값: 현재 디렉터리가 git 저장소면 "<project> · <branch>", 아니면 "<project>") |
--url <url> | 포함할 URL |
--type <type> | 푸시 유형: note, link, file, hook |
--priority <p> | 우선순위: low, normal, high, urgent |
--device <id> | 대상 디바이스 ID |
--session <id> | AI 세션 ID. 푸시가 그 세션의 채팅으로 묶인다 (또는 ZEPH_SESSION_ID 환경변수) |
--auto | 보내기 전에 푸시 게이트를 적용한다 — /zeph-quiet·/zeph-loud 다이얼을 프로젝트 단위 또는 --global로 머신 전역에서 존중한다. 게이트에 걸리면 코드 0으로 조용히 종료한다 |
--pushmode-default <m> | 프로젝트에 다이얼이 없을 때 --auto가 가정할 모드: quiet(내장), normal, loud. 사용자가 설정한 다이얼이 항상 이긴다 |
--marker <m> | --auto용 Push Signal 마커: skip, push, high |
--tools <n>, --nonreadonly <n> | --auto 휴리스틱에 들어가는 턴 도구 호출 수 (기본값은 실제 작업이 있었다고 가정) |
기본값은 hook이 호출하는 상황에 맞춰져 있다 — 예를 들어 본문 없이 zeph notify --title "Task done"을 부르는 Stop hook. IDE마다 래퍼를 쓰지 않아도 어느 프로젝트·브랜치가 끝났는지 보인다.
끄고 싶으면 --body ""를 명시한다.
listener 옵션
| 플래그 | 설명 |
|---|---|
--ws-url <url> | WebSocket 엔드포인트 (또는 ZEPH_WS_URL 환경변수, 또는 ~/.zeph/config.json의 wsUrl) |
--key <api-key> | API 키 (또는 ZEPH_API_KEY 환경변수) |
--base-url <url> | REST API 기본 URL (또는 ZEPH_BASE_URL 환경변수, 또는 ~/.zeph/config.json의 baseUrl) |
--stop | 도는 데몬을 멈추고 PID·버전 기록을 지운다 |
--restart | 멈춘 뒤 detached로 다시 띄우고 ~/.zeph/listener.log에 기록한다 |
listener는 지수 백오프와 jitter로 재연결한다 — 1초에서 시작해 30초에서 멈춘다. 하트비트는 25초 ping에 10초 pong 타임아웃이다. 인증 실패 close(4001·4002·4003)에서는 영원히 반복하지 않고 코드 3으로 종료한다 — 키를 고치고 다시 시작하면 된다.
list 옵션
| 플래그 | 설명 |
|---|---|
--limit <n> | 푸시 개수 (1–20, 기본값 5) |
--type <type> | 푸시 유형으로 필터 |
전역 옵션
| 플래그 | 설명 |
|---|---|
--key <api-key> | API 키 (또는 ZEPH_API_KEY 환경변수) |
--base-url <url> | API 기본 URL (또는 ZEPH_BASE_URL 환경변수) |
--json | JSON 형식으로 출력 |
--version | 버전 출력 |
Mute와 push mode
둘 다 ${XDG_STATE_HOME:-~/.local/state}/zeph 아래 상태 파일로 존재하며, 프로젝트 디렉터리의
cksum 해시로 키를 잡는다. Claude Code의 /zeph-mute·/zeph-quiet·/zeph-loud·/zeph-normal이
파일을 쓰고, CLI가 읽는다 — mute는 매 notify마다, push mode는 --auto에서.
현재 프로젝트에 mute 파일이 있으면 알림은 조용히 건너뛴다:
STATE_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/zeph"
HASH=$(printf '%s' "$PROJECT_DIR" | cksum | cut -d' ' -f1)
# 음소거 (Claude Code 플러그인의 /zeph-mute가 만든다)
mkdir -p "$STATE_DIR" && touch "$STATE_DIR/muted-$HASH"
# 해제
rm -f "$STATE_DIR/muted-$HASH"push mode는 quiet·loud·normal 중 한 단어가 든 파일이며, 아래 순서로 해석해 먼저 걸리는
것이 이긴다:
| 순서 | 파일 | 설정 주체 |
|---|---|---|
| 1 | $STATE_DIR/pushmode-<hash> | /zeph-quiet · /zeph-loud · /zeph-normal |
| 2 | /tmp/zeph-pushmode-<hash> | 구버전. 파일 소유자가 본인일 때만 존중 |
| 3 | $STATE_DIR/pushmode-default | 다이얼의 --global 형태 — 머신 전역 기본값 |
| 4 | --pushmode-default <mode> | 호출한 hook (설치되는 hook들은 normal을 넘긴다) |
| 5 | (위에 아무것도 없음) | quiet |
5번이 바뀌었다. 다이얼이 아무 데도 없는 설치는 예전엔 normal이었다. 지금은 quiet이므로,
업그레이드하면 /zeph-normal을 실행할 때까지 턴마다 나가는 일상 푸시가 꺼진다.
이 CLI가 설치하는 hook이 영향받지 않는 이유가 4번이다. 그 hook들은 스스로 normal을 지정한다 —
턴 도구 수를 넘기지 않는 hook은 high 마커도 넘기지 않으므로, quiet이면 더 조용해지는 게
아니라 영구히 침묵하기 때문이다. 4번이 상태 파일보다 아래에 있는 것은 의도다 — 플래그는
기본값을 지정할 뿐, 사용자가 설정한 다이얼을 덮지 않는다.
존재하지만 내용이 빈 다이얼 파일은 5번이 아니라 normal로 해석된다. 빈 파일은 쓰기 실패이고,
고장을 침묵으로 해석하면 디버그할 증상이 남지 않는다.
mute에 -default 형태가 없는 것도 의도다. mute는 내용이 아니라 존재 여부로 키를 잡으므로,
전역 mute는 개별 프로젝트만 풀 방법이 없어진다.
구형 /tmp/zeph-muted-<hash> 파일은 현재 사용자가 소유한 경우 여전히 존중된다 — 상태 디렉터리가
누구나 쓸 수 있는 /tmp 밖으로 옮겨졌다.
CLI는 CLAUDE_PROJECT_DIR·CURSOR_PROJECT_DIR·WINDSURF_PROJECT_DIR을 확인하고, 없으면 현재
디렉터리로 폴백한다.
종료 코드
| 코드 | 의미 |
|---|---|
| 0 | 성공 |
| 1 | 일반 오류 |
| 2 | 할당량 초과 |
| 3 | 인증 실패 (listener 인증 close 4001·4002·4003 포함) |
| 127 | tmux나 claude 같은 필수 외부 바이너리를 PATH에서 찾지 못함 |
환경변수
| 변수 | 설명 |
|---|---|
ZEPH_API_KEY | API 키. --key가 없을 때 사용된다 |
ZEPH_HOOK_ID | install·verify가 쓰는 Hook ID. --hook을 주지 않았을 때 참조한다. 양방향 MCP 도구(zeph_ask 계열)에 필요하다 |
ZEPH_BASE_URL | API 기본 URL (기본값: https://api.zeph.to/v1) |
ZEPH_WS_URL | zeph listener용 WebSocket 엔드포인트. 기본값 없음 — 필수 |
ZEPH_TMUX_SOCKET | listener용 tmux 소켓 경로를 명시해 자동 탐색을 건너뛴다. tmux를 -L <name>이나 커스텀 -S <path>로 돌릴 때 쓴다 |
ZEPH_SESSION_ID | AI 세션 ID. --session이 없을 때 사용된다 |