# Herdr 빠른 참조

*workspace, pane, agent 상태, CLI 자동화 (v0.9.x)*

> Source: Herdr documentation (herdr.dev, v0.9.3) and herdr CLI help output · MIT

## 개념 모델

### 계층

| Command | Description |
|---------|-------------|
| `session` | 백그라운드 서버 네임스페이스; 모든 프로세스 소유 |
| `workspace` | 저장소나 작업당 하나; 사이드바에 agent 상태 집계 |
| `tab` | workspace 안의 레이아웃 (agent, 로그, 서버) |
| `pane` | 실제 터미널; 오른쪽/아래로 분할, 분리 후에도 유지 |
| `agent` | Herdr가 pane 안에서 인식한 코딩 agent |

*클라이언트를 분리해도 서버와 모든 pane은 계속 실행*

### Agent 상태

| Command | Description |
|---------|-------------|
| `working` | agent가 턴을 처리 중 |
| `blocked` | 승인 프롬프트나 질문에 응답 대기 중 |
| `done` | 완료, 아직 확인하지 않음 |
| `idle` | 완료 또는 대기 중, 이미 확인함 |
| `unknown` | agent는 있으나 상태 불명; 완료를 뜻하지 않음 |

*idle과 done 모두 새 프롬프트를 받을 수 있는 상태*

### 입력 모드

| Command | Description |
|---------|-------------|
| `terminal` | 키 입력이 포커스된 pane으로 바로 전달 |
| `prefix` | Ctrl-b 다음 키는 Herdr 동작 |
| `navigate` | 상시 유지되는 workspace 탐색 화면 |
| `copy` | 키보드로 스크롤백 검색 및 선택 (Prefix [) |

## 시작하기

### 설치 및 실행

```
curl -fsSL https://herdr.dev/install.sh | sh
cd ~/projects/app
herdr           # launch or attach
claude          # any agent, auto-detected
herdr update    # self-update
herdr status    # client vs server version
```

### Agent 통합

```
herdr integration install claude
herdr integration install codex
herdr integration status --outdated-only
```

*통합 시 정확한 상태를 보고하고 서버 재시작 후 agent 재개 가능*

### 마우스 우선

> pane, tab, workspace, agent 행 모두 클릭 가능합니다. 테두리를 드래그해 크기 조정, 우클릭으로 분할 및 tab 메뉴, 드래그 선택으로 복사. 키 바인딩은 그 위의 선택적 계층입니다.

## 키 바인딩

### 먼저 익힐 것

| Command | Description |
|---------|-------------|
| `Prefix ?` | 활성 바인딩 모두 표시 (/로 필터) |
| `Prefix c` | 새 tab |
| `Prefix v` | 분할: 오른쪽에 새 pane |
| `Prefix -` | 분할: 아래에 새 pane |
| `Prefix h/j/k/l` | 왼쪽 / 아래 / 위 / 오른쪽 pane으로 포커스 |
| `Prefix w` | workspace 탐색 |
| `Prefix q` | 분리; 모든 것은 계속 실행 |

*기본 프리픽스는 Ctrl-b. 분리는 tmux의 d가 아닌 q*

### Pane

| Command | Description |
|---------|-------------|
| `Prefix z` | 포커스된 pane 줌 (전체 화면) |
| `Prefix x` | pane 닫기 |
| `Prefix Shift-h/j/k/l` | 이웃 pane과 위치 교환 |
| `Prefix r` | 크기 조정 모드 |
| `Prefix Tab` | 다음 pane으로 순환 |
| `Prefix Shift-p` | pane 이름 변경 |
| `Prefix e` | 스크롤백을 에디터로 열기 |

### Tab 및 Workspace

| Command | Description |
|---------|-------------|
| `Prefix n / p` | 다음 / 이전 tab |
| `Prefix 1..9` | 번호로 tab 이동 |
| `Prefix Shift-t / Shift-x` | tab 이름 변경 / 닫기 |
| `Prefix Shift-n` | 새 workspace |
| `Prefix Shift-g` | git worktree로 새 workspace |
| `Prefix Shift-w / Shift-d` | workspace 이름 변경 / 닫기 |
| `Prefix g` | Goto 선택기: 모든 agent와 터미널 |
| `Prefix o` | 최근 알림의 pane으로 이동 |
| `Prefix b` | 사이드바 전환 |
| `Prefix s` | 설정 |

*Goto 선택기에서 b/w/i/d로 blocked/working/idle/done 필터; /로 검색*

### 복사 모드 (Prefix [)

| Command | Description |
|---------|-------------|
| `h/j/k/l  w/b/e` | 문자 또는 단어 단위 이동 |
| `Ctrl-u / Ctrl-d` | 반 페이지 위 / 아래 |
| `/  ?  n  N` | 앞 / 뒤로 검색, 반복 |
| `v or Space` | 선택 시작 |
| `y or Enter` | 선택 복사 후 종료 |
| `q or Esc` | 복사 없이 종료 |

*스크롤백 중에도 pane은 계속 실행*

## Session 및 원격

### 지속성

```
herdr                      # reattach
herdr session list
herdr session attach work  # isolated server
herdr session stop work
herdr server stop          # kills ALL panes
```

### SSH 경유

```
herdr --remote workbox  # local UI, remote panes
herdr --remote workbox --session agents
herdr machine add workbox --label box
herdr --machine box agent list
```

### Worktree로 Workspace 만들기

```
herdr worktree create --branch fix/login --base main
herdr worktree list
herdr worktree remove --workspace w3
```

## Pane 스크립팅

### ID 및 컨텍스트

> ID 형식은 w1 (workspace), w1:t1 (tab), w1:p1 (pane). Herdr pane 안에서는 HERDR_ENV=1과 HERDR_PANE_ID가 설정됩니다. 명령은 JSON을 반환: 새 ID는 응답에서 읽고, 사이드바 순서로 추측하지 마세요.

### 탐색

```
herdr workspace list
herdr tab list --workspace "$HERDR_WORKSPACE_ID"
herdr pane list --workspace "$HERDR_WORKSPACE_ID"
herdr pane layout --current
```

### 옆 pane에서 명령 실행

```
id=$(herdr pane split --current \
       --direction right --no-focus \
     | jq -r .result.pane.pane_id)
herdr pane run "$id" "npm test"
herdr pane wait-output "$id" \
  --match "passed" --timeout 120000
herdr pane read "$id" --lines 80 \
  --source recent-unwrapped
```

### Pane 명령어

| Command | Description |
|---------|-------------|
| `pane run ID CMD` | 명령 입력과 Enter를 한 번에 |
| `pane send-text ID TEXT` | 텍스트 그대로 입력, Enter 없음 |
| `pane send-keys ID ctrl+c` | 이름 있는 키 전송 |
| `pane wait-output --regex RE` | 출력이 일치할 때까지 대기 (Rust regex) |
| `pane zoom ID --toggle` | 스크립트에서 pane 줌 |
| `pane move ID --new-tab` | pane 이동; 새 ID가 부여됨 |
| `notification show TITLE` | 토스트 표시, --sound done 옵션 가능 |

## Agent 오케스트레이션

### 시작, 프롬프트, 수집

```
herdr agent start reviewer --kind codex --pane "$id"
herdr agent prompt reviewer "Review the diff" \
  --wait --timeout 300000
herdr agent read reviewer --lines 120
herdr agent wait reviewer --until blocked
herdr agent send-keys reviewer esc
```

### Agent 명령어

| Command | Description |
|---------|-------------|
| `agent list` | 실행 중인 모든 agent와 상태 |
| `agent get NAME` | agent 하나의 pane, 종류, 상태 |
| `agent focus NAME` | UI를 해당 agent로 이동 (확인 처리) |
| `agent attach NAME` | Herdr UI 없이 해당 터미널만 열기 |
| `agent explain NAME` | 감지가 이 상태를 선택한 이유 |

*대상은 고유한 agent 이름 또는 이를 담은 pane ID*

### Pane vs Agent 명령어

| Choice | Use when | Watch for |
|--------|----------|-----------|
| `pane` | 셸, 테스트, 서버 | agent 상태를 알 수 없음 |
| `agent` | 감지된 코딩 agent | blocked agent는 거부 |

### 경험 법칙

> agent start에는 셸 프롬프트 상태의 기존 pane이 필요하며, 레이아웃은 만들지 않습니다. 백그라운드 작업에는 --no-focus 사용. 타임아웃 후 재전송 전에 agent를 먼저 읽으세요: 프롬프트가 이미 전달됐을 수 있습니다.

## 설정

### ~/.config/herdr/config.toml

```
[keys]
prefix = "ctrl+a"
focus_pane_left = ["prefix+h", "ctrl+alt+h"]
[theme]
name = "tokyo-night"
[ui.toast]
delivery = "system"  # or herdr / terminal
```

### 커스텀 팝업 명령

```
[[keys.command]]
key = "prefix+alt+g"
type = "popup"       # or "pane" / "shell"
command = "lazygit"
width = "80%"
height = "80%"
```

### 설정 명령어

| Command | Description |
|---------|-------------|
| `herdr --default-config` | 모든 옵션을 주석과 함께 출력 |
| `herdr config check` | config.toml 검증 |
| `Prefix Shift-r` | 실행 중인 서버에 설정 다시 로드 |
| `herdr config reset-keys` | 설정 백업 후 커스텀 바인딩 제거 |

*ctrl+alt 조합이 터미널 간 가장 안전한 프리픽스 없는 바인딩*
