내 환경 × Herdr — 도입 이득과 권장 세팅

내 환경 × Herdr — 도입 이득과 권장 세팅

전제 환경: wezterm 단독(tmux 미사용) · OpenCode + Claude Code 병렬 사용 · diff 확인용 pane과 nvim pane 상시 운용 · git worktree 2~3개로 동시 작업

함께 볼 문서: Herdr 개요 (일반 레퍼런스)


1. 왜 도입하나 — 이득 정리

1-1. 지속성이 순수 신규 이득

tmux를 안 쓰고 계셨으므로 wezterm 창을 닫으면 그 안의 프로세스가 같이 죽습니다. Herdr를 도입하면 이게 사라집니다.

  • 창을 닫아도, SSH가 끊겨도, 노트북을 덮어도 pane과 에이전트가 살아있음
  • herdr 재실행으로 그대로 복귀
  • 워크트리 여러 개에 에이전트를 걸어놓고 자리를 뜨는 패턴에서 특히 큼

⚠️ 주의: wezterm 재시작 후 복원된 것처럼 보인 건 "복원"이 아니라 재부착입니다. 서버가 애초에 안 죽었던 것. 진짜 복원 경로(스냅샷/네이티브 세션)는 herdr server stop 이후에만 발동합니다.

1-2. 워크트리가 1급 시민

herdr worktree 커맨드 그룹이 브랜치를 개별 workspace에 매핑합니다.

지금은 워크트리 2~3개를 wezterm 탭 이름이나 기억으로 관리하고 계실 텐데, 거기엔 상태 개념이 없습니다. Herdr는 workspace 단위로 에이전트 상태를 롤업하므로:

사이드바
  ● feature-a   ← blocked (승인 대기 중)
  ○ feature-b   ← working
  ◐ hotfix-c    ← done (아직 안 봄)

한 컬럼만 보면 어느 브랜치가 나를 기다리는지 알 수 있습니다. 탭 순회가 사라집니다.

1-3. 미확인 완료 추적

done은 "끝났는데 아직 내가 안 본 것"입니다. 탭을 포커스해야 "봤음" 처리됩니다.

에이전트 2개 × 워크트리 3개면 사실상 6개 이상을 상태 없이 순회하고 계신 겁니다. "저거 결과 확인했던가?"를 머리에서 사이드바로 넘기는 게 실질 이득입니다.

1-4. OpenCode / Claude Code 둘 다 공식 통합 존재

이게 운이 좋은 부분입니다. 둘 다 훅/플러그인 기반의 권위 있는 상태 보고를 받을 수 있어서, 화면 스크래핑 추측이 아닙니다. unknown 오탐이 크게 줄어듭니다.

구조적 배경: OpenCode는 session.idle, permission.asked, permission.replied 같은 세션 레벨 이벤트를 노출해서 오케스트레이션에 더 친화적입니다. Claude Code도 훅 시스템은 강력하지만 성격이 달라서 통합이 메꿔야 할 간극이 더 큽니다. → 감독당하는 쪽(워커)을 OpenCode로 두면 상태 신호가 더 정확할 가능성이 높습니다.

1-5. nvim / diff pane은 그대로

각 pane이 portable-pty 기반 진짜 PTY입니다. 웹뷰나 이스케이프 시퀀스가 빠진 유사 터미널이 아니므로 nvim, lazygit, delta 전부 wezterm에서와 동일하게 동작합니다.

1-6. 나중을 위한 옵션: 오케스트레이션

CLI/소켓 API로 에이전트가 다른 에이전트를 부릴 수 있습니다. 헤드리스 모드 대비:

헤드리스 (claude -p, SDK)Herdr pane
진행 상황블랙박스실시간 관측
권한 요청사전 허용 or 실패blocked로 잡히고 직접 승인
작업 후프로세스 종료살아있어 이어서 대화 가능
재시작소실네이티브 세션 복원 대상
과금SDK 별도 풀1st-party CLI 그대로

2. 도입하지 않을 이유 (솔직하게)

  • tmux와 병행 불가. Herdr pane 안에서 tmux를 열면 에이전트 상태 감지가 죽습니다. 대체재입니다 (지금 tmux를 안 쓰시니 이 비용은 없음)
  • 긴 응답 회수는 여전히 취약. alternate screen 한계는 tmux capture-pane과 동일한 성질
  • 0.x 버전대. 감지 매니페스트가 핫리로드되긴 하지만 UI 변경에 따른 오탐 가능성 존재
  • 수동 조작 비중이 크면 자동화 이득은 나중 얘기. 다만 위 1-1~1-5는 자동화 없이도 즉시 발생

3. 초기 세팅

Step 1 — 설치

curl -fsSL https://herdr.dev/install.sh | sh
# 또는 brew install herdr
herdr --version

Step 2 — 통합 (가장 중요)

herdr integration install claude
herdr integration install opencode     # OpenCode를 최소 1회 실행한 뒤에
herdr integration status               # 버전 확인 — 네이티브 세션 복원 조건

통합이 두 가지를 동시에 해결합니다: 상태 감지 정확도 + 네이티브 세션 복원 자격.

Step 3 — 설정

# ~/.config/herdr/config.toml

[ui.toast]
delivery = "system"        # 데스크톱 알림. 알림 플러그인을 쓰면 "terminal"로 변경

[session]
# resume_agents_on_restore = true   # 기본값. 프로젝트를 자주 옮기면 워크스페이스가
                                    # 과하게 쌓일 수 있으니 그때 false 고려
herdr --default-config > /tmp/herdr-default.toml   # 전체 옵션 확인용
herdr server reload-config                          # 재시작 없이 적용

화면 히스토리는 켜지 마세요. pane 출력이 디스크에 남고 시크릿/토큰이 포함될 수 있습니다. 네이티브 세션 복원이 있으니 대부분 불필요합니다.

Step 4 — 알림

권장 조합:

# (a) 자리를 떠도 폰으로 — 크로스 플랫폼
herdr plugin install cobanov/herdr-ntfysh
cp .env.example "$(herdr plugin config-dir cobanov.herdr-ntfysh)/.env"
# HERDR_NTFY_SERVER, HERDR_NTFY_TOPIC 설정
herdr plugin action invoke cobanov.herdr-ntfysh.test

# (b) macOS라면 — 클릭 시 해당 pane으로 점프
herdr plugin install yankewei/herdr-focus-notify
# HERDR_FOCUS_NOTIFY_ACTIVATE_APP=wezterm

⚠️ 플러그인 사용 시 [ui.toast] delivery = "terminal"로 내장 토스트를 끄세요. 아니면 중복 알림.

Step 5 — 검증 (여기까지 하면 도입 완료)

# 1) 워크트리 하나에서 OpenCode + Claude Code를 각각 pane에 띄우기
# 2) 사이드바에 두 상태가 뜨는지 확인
herdr agent list

# 3) 상태가 이상하면 이유 확인
herdr agent explain <target> --json

진짜 복원 테스트 (선택, 격리 세션 권장):

herdr session attach test      # 별도 세션에서 실험
# ... 에이전트 띄우고 대화 몇 번
herdr server stop <세션>   # 정확한 플래그는 herdr server stop --help 확인
herdr session attach test      # 대화 맥락을 들고 살아나면 통합 성공

⚠️ 기본 세션에서 herdr server stop을 실행하면 모든 pane 프로세스가 죽습니다. 실험은 반드시 명명 세션에서.


4. 권장 토폴로지

워크트리 = workspace

session: default
├── workspace: feature-a      (워크트리 A)
├── workspace: feature-b      (워크트리 B)
└── workspace: main           (메인 체크아웃)

workspace를 프로젝트/작업 단위로 하나씩 두는 게 사이드바 상태를 읽기 좋게 유지하는 원칙입니다.

workspace 안의 탭 분리

workspace: feature-a
├── tab: main       ← 오케스트레이터 에이전트 1개 + diff pane
├── tab: workers    ← 서브에이전트 전용
└── tab: edit       ← nvim

agent start이미 존재하는 사용 가능한 셸 pane을 요구합니다. 사용 가능하다는 건 대화형 프롬프트 상태이고 셸 자체가 포그라운드이며 명령·에디터·에이전트가 돌고 있지 않은 상태입니다. → nvim 탭과 워커 탭을 분리해야 하는 실질적 이유입니다.


5. 오케스트레이션 셋업 (2단계 이후)

즉시 필요하지 않다면 §3까지만 하고 며칠 써보신 뒤 진행하세요.

스킬 설치

npx skills add herdrdev/herdr --skill herdr -g

스킬 시스템이 없으면 원본을 글로벌 커스텀 인스트럭션에 붙여넣기: https://raw.githubusercontent.com/herdrdev/herdr/master/skills/herdr/SKILL.md

⚠️ 프롬프트에 "herdr"를 명시해야 발동합니다. 스킬 설명이 "사용자가 Herdr를 명시적으로 언급했을 때만" 쓰도록 제한하고 있습니다.

herdr로 오른쪽에 pane 열고 codex 띄워서 현재 diff 리뷰시켜줘

커스텀 하우스 룰

원본 스킬 위에 프로젝트 규칙을 얹는 방식을 권합니다.

# Herdr orchestration — house rules

## 역할 분리 (재귀 방지)
HERDR_ROLE=worker 이면 herdr 제어 명령을 일절 사용하지 않는다.
pane/tab/workspace를 만들지 않고, 다른 에이전트를 시작하지 않는다.
작업 결과만 보고한다.

## 토폴로지
- 오케스트레이터는 main 탭에만 존재. 워커를 main 탭에 띄우지 않는다.
- 워커는 label="workers" 탭에만 생성. 없으면 만든다.
- 탭/pane ID는 항상 list로 조회한다. 하드코딩 금지.
- 워커 pane은 최대 3개. 그 이상은 좁아서 못 쓴다.

## 결과 교환 (컨텍스트 절약 + alternate screen 회피)
워커 프롬프트 말미에 항상 추가:
  "전체 결과를 $HANDOFF_DIR/<name>.md 에 쓰고, 응답은 파일 경로 한 줄만."
오케스트레이터는 파일을 읽는다. agent read는 진단 용도로만.

## 권한
자동 승인은 아래를 모두 만족할 때만:
  - 읽기 전용 (ls, cat, git diff, git log, rg)
  - 워크트리 경로 밖을 건드리지 않음
그 외 전부 사용자 호출:
  herdr notification show "승인 필요: <name>" \
    --body "$(herdr agent read <name> --source detection --lines 5)" \
    --sound request
git push / rm / 파일 삭제 / 네트워크 쓰기는 예외 없이 사용자.

## 금지
- 자기가 만들지 않은 pane/tab/workspace 닫기
- herdr server stop
- 메인 Herdr 프로세스 kill

파일 핸드오프에 대한 메모: 공식 스킬은 파일 출력을 alternate-screen 폴백으로만 쓰라고 합니다. 그건 1:1 대화를 전제한 조언이고, 오케스트레이터 패턴에서는 처음부터 파일로 받는 게 맞습니다. 컨텍스트 소모와 alternate screen 문제가 동시에 해결됩니다.

교차 호출

Herdr에게 CC와 OpenCode는 그냥 다른 --kind 값이라 양방향이 완전히 대칭입니다.

herdr agent start impl     --kind opencode --pane "$p1"   # CC가 OpenCode를
herdr agent start reviewer --kind claude   --pane "$p2"   # OpenCode가 CC를

실용적 가치: 같은 모델이 자기 코드를 리뷰하면 같은 맹점을 공유합니다. 크로스 모델 리뷰가 이 구성의 가장 큰 실익입니다.

표준 시퀀스

test "${HERDR_ENV:-}" = 1

split=$(herdr pane split --current --direction right --cwd "$PWD" --no-focus)
p=$(printf '%s\n' "$split" | jq -r '.result.pane.pane_id')

herdr agent start reviewer --kind claude --pane "$p"
herdr agent prompt reviewer "$TASK" --wait --timeout 300000

# blocked로 멈췄으면 판단 전에 반드시 확인
herdr agent get reviewer
herdr agent read reviewer --source detection

6. 함정 체크리스트

#함정대응
1재귀 폭발-g 설치 시 워커도 스킬을 가짐HERDR_ROLE=worker 규칙을 하우스 룰에 명시
2오케스트레이터 컨텍스트 고갈파일 핸드오프를 기본 프로토콜로
3alternate screen--lines 늘려도 안 나옴파일 핸드오프로 우회 (근본 해결)
4unknown을 성공으로 처리완료의 증거가 아님. 명시적으로 분기 처리
5턴 미추적 — 바쁜 에이전트에 프롬프트+--wait프롬프트 전 agent get으로 idle 확인
6에이전트 이름 소실 — 죽으면 별칭도 사라짐재기동 시 이름 재등록
7pane 점유 상태 — nvim 있는 pane에 agent start 불가탭 분리
8herdr server stop 오발사실험은 명명 세션에서만
9중복 알림플러그인 사용 시 내장 토스트 끄기
10권한 자동 승인 폭주blocked는 "무엇을" 승인하는지 알려주지 않음. 화이트리스트 필수

7. 단계별 도입 순서

Phase 1 — 기본 (즉시, 30분)

  1. 설치
  2. herdr integration install claude / opencode
  3. 워크트리 하나를 workspace로 전환해서 며칠 사용
  4. 판단: 사이드바만으로 회수되는가?

Phase 2 — 운용 (Phase 1이 만족스러우면) 5. 워크트리 전부를 workspace로 6. 알림 플러그인 (ntfy 또는 focus-notify) 7. 탭 구조 정리 (main / workers / edit)

Phase 3 — 오케스트레이션 (필요를 느끼면) 8. 스킬 설치, 원본 그대로 1:1 위임부터 9. 파일 핸드오프 추가 10. 하우스 룰 (역할 분리 + 토폴로지)

Phase 4 — 권한 자동화 (마지막, 신중하게) 11. 층 1부터: 워커 기동 시 네이티브 권한 옵션으로 애초에 안 묻게 12. 그래도 남는 것만 화이트리스트 13. 나머지는 notification show로 사람 호출

Phase 3까지만 해도 실용적으로 충분합니다. Phase 4는 잘못 만들면 조용히 위험해지는 유일한 구간이니 서두르지 마세요.


8. 자주 쓸 명령

# 상태 확인
herdr agent list
herdr agent explain <target> --json
herdr integration status
herdr status

# 레이아웃
herdr workspace list
herdr tab list --workspace "$HERDR_WORKSPACE_ID"
herdr pane list --workspace "$HERDR_WORKSPACE_ID"
herdr pane current --current
herdr pane layout --pane "$HERDR_PANE_ID"

# 설정
herdr --default-config
herdr server reload-config

# 커맨드 그룹 도움말 (서브커맨드 없이 실행)
herdr agent / pane / workspace / tab / worktree / notification / plugin / session

# 알림
herdr notification show "제목" --body "내용" --sound request

키바인딩: prefix+?로 라이브 전체 목록. 기본 프리픽스는 ctrl+b.

Backlinks 1