The native macOS console for herdr — see Claude Code, Codex, Gemini, Grok and OpenCode across your Mac and every SSH box you own, and jump into any one of them at full-TUI fidelity.
What it does · Why herdrm? · Install · Quick Start · Architecture
herdr is the runtime your coding agents live on — a background server that owns their terminals and knows which one is working, blocked, or done. herdrm is a native macOS window on top of it, and it's grown well past "attach to a terminal":
| 🖥️ Every device | Local + remote over SSH — keys, Tailscale, or a Keychain password — with auto-reconnect |
| 🧭 Live status | Spaces & Agents sorted by urgency: blocked → done → working → idle |
| ⌨️ Real terminal | Full PTY attach, not a chat wrapper — native selection, legible fonts, resilient sessions |
| 📎 Paste anything | Files and images land straight in the agent's pane, locally or over SSH |
| 🔔 Notifications | A system alert the moment an agent needs you — click it to jump right there |
| 🔍 ⌘K search | Every agent, on every device, one keystroke away |
See the full feature list
- All your devices, in parallel — remote sockets forwarded over
ssh -L, each on its own reconnect loop (1s → 30s backoff). The sidebar aggregates every device with a tinted OS badge; the bottom-left switcher filters by device. - Flexible SSH targets —
user@host,user@host:port,ssh://URIs, and~/.ssh/configaliases. Auth falls back OpenSSH keys/agent → Tailscale SSH (1.98.0+) → an in-app password prompt stored in the macOS login Keychain, never in a file. - Diagnosable failures — "herdr isn't running on
<host>", a misconfiguredAllowStreamLocalForwarding, or why a disconnected device is unreachable — never a bare "not connected".
- Spaces & Agents sidebar — every workspace and agent (claude, codex, gemini, grok, opencode, …), same canonical order the ⌘K palette uses.
- New Agent / New Space — locally the picker only lists advertised CLIs found on the login-shell PATH (captured once from a real interactive + login shell, not by grepping rc files or trusting LaunchServices); SSH devices follow the remote server's manifest catalog and validate on start. Each agent's bypass-permissions flag is on by default. ⌘N for a new agent, ⇧⌘N for a new space. New Space includes an inline directory browser that works over SSH. Settings → Agents accepts a per-kind binary path when detection is wrong.
- Spaces rename straight from the sidebar's context menu.
- Live terminal — attaches directly to the agent's PTY (
herdr agent attach); grabs keyboard focus the moment you jump in from ⌘K, the sidebar, or a notification. - Native text selection — drag to select, no Shift needed; right-click for Copy/Paste/Select All plus link actions (⌘-click opens a URL).
- Legibility controls — Thin strokes, font Weight, and Line spacing settings.
- Shift+Enter inserts a line break instead of submitting; colors adapt correctly in Light mode instead of washing out.
- Resilient sessions — a dropped connection or a takeover shows a Reconnect button instead
of freezing on the last frame; mixed-version
herdrbinaries no longer break attach.
- Paste files and images into Claude Code, Codex, or Copilot. Local pastes forward as Ctrl+V; remote pastes stream over SSH into a self-pruning cache (7-day retention, 50 MB cap).
- Search — ⌘K across every device, ordered by urgency, scrolling to follow your selection.
- Notifications — a sound and a system alert when any agent finishes or needs input; clicking jumps straight to it. Agents you're already watching stay quiet.
- Universal binary — Apple Silicon and Intel, one download.
- Light & dark, auto-updates via Sparkle, signed and notarized.
- HerdrKit — the socket-RPC/SSH/device layer ships as its own, independently testable Swift
package (
Packages/HerdrKit).
You already run agents through herdr because the model is right — spaces, live status, real
PTYs, not a chat window pretending to be one. But living in herdr attach and a wall of
terminal panes is its own skill, and not everyone wants to be a tmux person to get the benefit.
herdrm is the same model, built for people who'd rather click:
- Herdr's mechanics, an Apple-native interface. Every space and agent is a sidebar row you click, not a session name you type — built in SwiftUI, so it looks and moves like a first-party Mac app, not a terminal skin bolted on top.
- Native means fast. No Electron, no browser engine underneath — herdrm launches instantly and stays light, the kind of responsiveness only a truly native app gets.
- Still the real terminal when it matters. Click an agent and you're on its actual PTY, full TUI, nothing summarized — you just don't have to live inside a multiplexer to get there.
- One console, every machine. Laptop, dev box, home server — all rows in the same sidebar.
- You stop polling. Status lives in the sidebar and in notifications, not in your head.
- It gets out of the way. ⌘K, ⌘N, paste-to-attach — no new mental model to learn.
- macOS 14+
- herdr installed locally (herdrm starts it if it isn't running) and on your remote machines
- For remote devices: OpenSSH access, Tailscale SSH (1.98.0+), or a Keychain-stored password
Homebrew
brew install owo-network/brew/herdrmManual — download herdrm-x.y.z.zip from Releases,
unzip, drag herdrm.app into /Applications. Either way it self-updates from then on — HerdrM
→ Check for Updates…, or HerdrM → About HerdrM for the version you're running.
1. Launch herdrm → no local herdr running? herdrm starts it for you
2. Add a device (optional) → you@dev-box · you@dev-box:2222 · a Tailscale machine
3. ⌘N → pick a device + a CLI, you're attached to its live terminal
4. ⌘K → jump to any agent on any device, any time
flowchart LR
A(["🖥️ herdr<br/>background server, owns the PTYs"]) -->|"Unix-socket RPC +<br/>herdr agent attach"| B[["Packages/HerdrKit<br/>RPC client · SSH tunnel · device store"]]
B -->|SwiftUI bindings| C(["Sources/HerdrM<br/>sidebar · terminal · search · notifications"])
style A fill:#161b22,stroke:#E2795B,color:#e6edf3
style B fill:#1f2630,stroke:#3B82F6,color:#e6edf3
style C fill:#161b22,stroke:#2FA35F,color:#e6edf3
- herdr — the daemon: owns every agent's PTY, persists spaces, answers over a local Unix socket.
Packages/HerdrKit— transport and domain layer, UI-independent and unit-tested on its own (make kit-test).Sources/HerdrM— the SwiftUI shell built on SwiftTerm.
brew install xcodegen
make build # xcodegen + xcodebuild → build/Build/Products/Debug/herdrm.app
make run
make kit-test # HerdrKit integration tests (needs a running local herdr)Early-stage software, PRs genuinely welcome — small and single-purpose lands fastest.
- Bug? Open an issue with your macOS
version,
herdr --version, and repro steps. - Feature idea? Open an issue first for anything beyond a small PR.
- Sending a PR:
make build+make kit-testlocally (no CI gate yet — this is the bar), plus a line under## [Unreleased]inCHANGELOG.md(release automation requires it).
- herdr — the agent runtime this app is a console for.
- Heeler — iOS herdr client; domain model and transport patterns.
- waku — sidebar design reference.
- SwiftTerm — terminal emulation.
- Sparkle — auto-updates.
- Lobe Icons / Simple Icons — brand icons.
Early stage, without full test coverage — expect bugs. Issues and PRs are very welcome.
