diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-06-12 14:07:38 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-06-12 14:22:25 +0300 |
| commit | f8bb1918241d76df0d249c3e8255c4f55b45b4b4 (patch) | |
| tree | 33093431fbc2bdb3f631cf93be012ab85ba901ea /website | |
| parent | 820246a4d75d33672f216efe2f3e4b8187ab4b3a (diff) | |
docs: update website
Diffstat (limited to 'website')
| -rw-r--r-- | website/agent-guide.md | 93 | ||||
| -rw-r--r-- | website/astro.config.mjs | 13 | ||||
| -rw-r--r-- | website/css/style.css | 218 | ||||
| -rw-r--r-- | website/index.html | 554 | ||||
| -rw-r--r-- | website/scripts/prepare-docs.mjs | 1 | ||||
| -rw-r--r-- | website/src/content/docs/agent-skill.mdx | 2 | ||||
| -rw-r--r-- | website/src/content/docs/agents.mdx | 24 | ||||
| -rw-r--r-- | website/src/content/docs/concepts.mdx | 24 | ||||
| -rw-r--r-- | website/src/content/docs/configuration.mdx | 2 | ||||
| -rw-r--r-- | website/src/content/docs/index.mdx | 48 | ||||
| -rw-r--r-- | website/src/content/docs/install.mdx | 96 | ||||
| -rw-r--r-- | website/src/content/docs/keyboard.mdx | 112 | ||||
| -rw-r--r-- | website/src/content/docs/persistence-remote.mdx | 31 | ||||
| -rw-r--r-- | website/src/content/docs/quick-start.mdx | 69 | ||||
| -rw-r--r-- | website/src/content/docs/session-state.mdx | 20 |
15 files changed, 895 insertions, 412 deletions
diff --git a/website/agent-guide.md b/website/agent-guide.md new file mode 100644 index 00000000..ed845fc0 --- /dev/null +++ b/website/agent-guide.md @@ -0,0 +1,93 @@ +# Herdr agent guide + +You are reading this because a human asked you to help them understand, set up, or troubleshoot Herdr. This file gives you the concept model, the setup path, and the diagnosis recipes so you can guide them accurately. Canonical documentation lives at https://herdr.dev/docs/ — link the human there for depth, and verify any command you are unsure about against those pages instead of guessing. + +If you are running *inside* a Herdr pane (the environment variable `HERDR_ENV=1` is set), Herdr also ships a skill file that teaches you to control Herdr yourself through the `herdr` CLI: https://raw.githubusercontent.com/ogulcancelik/herdr/master/SKILL.md. That file is about you operating Herdr; this file is about you teaching a human. + +## What Herdr is + +Herdr is a terminal workspace manager for AI coding agents. Like tmux, it is a multiplexer: a background server owns real terminal processes, and clients attach to render them. Panes keep running when the human detaches, closes the terminal, or disconnects SSH. + +Unlike tmux, Herdr is mouse-first and agent-aware. The whole UI is clickable — panes, tabs, workspaces, split borders, right-click menus. Herdr detects coding agents running inside panes and shows each one's state in a sidebar, so the human can see across all their projects which agent is `working`, which is `blocked` waiting for input, and which is `done`. A CLI and a local socket API let scripts and agents drive Herdr programmatically. + +## Concept model + +Teach these in this order: + +- **Session** — a persistent background server namespace. Running `herdr` attaches to the default session. Named sessions (`herdr session attach work`) are fully separate runtime namespaces; most people only need the default. +- **Workspace** — the project-level container. One per repo, task, or investigation. Owns tabs and panes. The sidebar rolls agent states up per workspace. +- **Tab** — a layout inside a workspace, for separating views like `agents`, `logs`, `server`. +- **Pane** — a real terminal. Splittable right or down. Survives client detach. +- **Agent** — a process Herdr recognizes inside a pane. States: `working`, `blocked`, `done`, `idle`, `unknown`. +- **Modes** — terminal mode sends keys to the focused pane; prefix mode (`ctrl+b`, then one action key) sends one command to Herdr; navigate mode is a persistent navigation surface. + +Full concepts page: https://herdr.dev/docs/concepts/ + +## Install + +Linux and macOS: + +```bash +curl -fsSL https://herdr.dev/install.sh | sh +herdr +``` + +Windows preview beta: + +```powershell +powershell -ExecutionPolicy Bypass -c "irm https://herdr.dev/install.ps1 | iex" +herdr +``` + +Homebrew, mise, and Nix installs, verification, and manual downloads: https://herdr.dev/docs/install/. Updating later is `herdr update`. Check the version with `herdr --version`. + +## First-run walkthrough + +First check where you are. If `HERDR_ENV=1` is set in your environment, you are already running inside a Herdr pane — the human is already attached, so skip step 1 entirely and never tell them to run `herdr` from your pane. Herdr blocks nested launches by design. Start from step 2, and consider the skill file below. + +Walk the human through this sequence: + +1. `cd` into a project and run `herdr`. It launches or attaches to the default background session and creates a workspace automatically. First run shows an onboarding flow. +2. Start their coding agent in the pane — `claude`, `codex`, or any supported agent (full list: https://herdr.dev/docs/agents/). Herdr detects it automatically; the sidebar shows its state. Installing the matching integration improves detection: `herdr integration install claude` (and similarly for other agents). +3. Show them the mouse first: click panes and tabs to focus, drag split borders, right-click for menus, drag-select to copy. No keybindings are required to use Herdr. +4. Split panes: right-click menu, or `prefix+v` (right) / `prefix+minus` (down). New tab: `prefix+c`. +5. Detach with `prefix+q` (press `ctrl+b`, release, press `q`) or simply close the terminal window. Everything keeps running. Reattach later with `herdr`. +6. To actually stop everything: `herdr server stop`. + +## The keyboard story + +Important framing for new users: Herdr does not require learning keybindings. The mouse covers everything. When the human wants keyboard control: + +- The prefix key is `ctrl+b` by default. `prefix+?` shows every active binding live. +- The guided keyboard page — what the prefix is, which bindings to learn first, and a vetted prefix-free setup using `ctrl+alt` chords — is https://herdr.dev/docs/keyboard/. Recommend it over improvising. +- Every binding, including the prefix itself, is configurable under `[keys]` in the config file. +- If a direct chord does nothing, the OS or the outer terminal consumed it before Herdr could see it. The keyboard page explains which chords are safe and why. + +## Install the Herdr skill into yourself + +Herdr ships `SKILL.md` (https://raw.githubusercontent.com/ogulcancelik/herdr/master/SKILL.md), an instruction file that teaches a coding agent to control Herdr from inside a pane — splitting panes, running commands without stealing focus, reading output, waiting on other agents. + +Once the human is set up, offer to install it into your own harness so future sessions know Herdr natively. You know your own conventions best; install it wherever your global reusable instructions live. For example: Claude Code installs it as a skill (e.g. `~/.claude/skills/herdr/SKILL.md`); Codex and similar agents include it from their global instructions file (e.g. `~/.codex/AGENTS.md`); agents without a skill system can paste it into global custom instructions. Ask the human before writing to their config locations, and use the GitHub copy above as the source of truth. + +## Configuration + +- Config file: `~/.config/herdr/config.toml`. Herdr works without one. +- Print the full default config: `herdr --default-config`. +- Apply edits to a running server: `herdr server reload-config` (or the global menu → reload config). +- Main areas: `[keys]` keybindings, `[theme]` themes, `[ui]` sidebar and UI behavior, `[terminal]` shell defaults, `[update]` channel. +- Full reference: https://herdr.dev/docs/configuration/ + +## Diagnosis recipes + +- **Agent not detected or wrong state:** `herdr agent list` to see what Herdr sees, `herdr agent explain <target> --json` to see why the detector classified a pane the way it did. Installing the agent's integration (`herdr integration install <name>`, status via `herdr integration status`) gives Herdr authoritative state instead of screen detection. Details: https://herdr.dev/docs/agents/ and https://herdr.dev/docs/integrations/ +- **A keybinding does nothing:** the outer terminal or desktop environment owns that chord. Point the human to https://herdr.dev/docs/keyboard/ to pick a safe one or free the chord in their terminal settings. +- **Something looks wrong at startup or with the socket API:** logs are at `~/.config/herdr/herdr.log`, `~/.config/herdr/herdr-client.log`, and `~/.config/herdr/herdr-server.log`. `herdr status`, `herdr status server`, and `herdr status client` summarize the runtime. +- **Remote questions:** SSH to the machine and run `herdr` there (works like tmux), or attach as a thin local client with `herdr --remote <host>`. Trade-offs: https://herdr.dev/docs/how-to-work/ +- **What survives a detach, restart, or update:** https://herdr.dev/docs/session-state/ + +## Rules for you + +- Do not invent keybindings, config keys, or CLI flags. The ones in this file are accurate as of writing; for anything else, read the linked docs page first. +- Teach mouse before keyboard for humans new to multiplexers. +- Herdr is not tmux: do not give tmux commands, tmux config syntax, or `.tmux.conf` advice for Herdr questions. +- For automation, scripting, or controlling Herdr from code, point to the CLI reference (https://herdr.dev/docs/cli-reference/) and socket API (https://herdr.dev/docs/socket-api/). diff --git a/website/astro.config.mjs b/website/astro.config.mjs index d7ee5a2d..75d041ad 100644 --- a/website/astro.config.mjs +++ b/website/astro.config.mjs @@ -104,20 +104,19 @@ export default defineConfig({ items: [ { label: 'Overview', slug: 'docs' }, { label: 'Install', slug: 'docs/install' }, - { label: 'Windows beta', slug: 'docs/windows-beta' }, { label: 'Quick start', slug: 'docs/quick-start' }, - { label: 'How to work with Herdr', slug: 'docs/how-to-work' }, { label: 'Concepts', slug: 'docs/concepts' }, + { label: 'Keyboard', slug: 'docs/keyboard' }, + { label: 'How to work with Herdr', slug: 'docs/how-to-work' }, ], }, { label: 'Core guides', items: [ { label: 'Agents', slug: 'docs/agents' }, - { label: 'Integrations', slug: 'docs/integrations' }, - { label: 'Configuration', slug: 'docs/configuration' }, - { label: 'Persistence and remote access', slug: 'docs/persistence-remote' }, { label: 'Session state and restore', slug: 'docs/session-state' }, + { label: 'Persistence and remote access', slug: 'docs/persistence-remote' }, + { label: 'Configuration', slug: 'docs/configuration' }, ], }, { @@ -125,15 +124,15 @@ export default defineConfig({ items: [ { label: 'CLI reference', slug: 'docs/cli-reference' }, { label: 'Socket API', slug: 'docs/socket-api' }, + { label: 'Integrations', slug: 'docs/integrations' }, { label: 'Agent skill file', slug: 'docs/agent-skill' }, + { label: 'Windows beta', slug: 'docs/windows-beta' }, ], }, { label: 'Updates', items: [ - { label: 'Releases', link: '/releases/' }, { label: 'Preview docs', slug: 'docs/preview' }, - { label: 'Blog', link: '/blog/' }, ], }, ], diff --git a/website/css/style.css b/website/css/style.css index bd0da4b3..3be58f67 100644 --- a/website/css/style.css +++ b/website/css/style.css @@ -903,10 +903,10 @@ samp { gap: 0.5rem; color: var(--muted); font-family: var(--mono); - font-size: 0.72rem; - font-weight: 700; - letter-spacing: 0.12em; - text-transform: uppercase; + font-size: 0.78rem; + font-weight: 600; + letter-spacing: 0.06em; + text-transform: lowercase; } .hero h1, @@ -923,6 +923,7 @@ samp { .hero h1 { max-width: 760px; font-size: clamp(2.6rem, 5.5vw, 4.6rem); + text-wrap: balance; } .hero-lede { @@ -1178,6 +1179,8 @@ samp { .hero-product-shot { margin: 0; + width: 100%; + container-type: inline-size; } .hero-product-shell { @@ -1211,8 +1214,8 @@ samp { color: var(--term-muted); font-family: var(--mono); font-size: clamp(0.44rem, 0.72vw, 0.64rem); + font-size: clamp(0.4rem, 1.36cqw, 0.64rem); line-height: 1.38; - pointer-events: none; user-select: none; border: 1px solid var(--term-border); } @@ -1282,8 +1285,8 @@ samp { } .herdr-ui-mock .mock-sidebar-spacer { - flex: 0 0 5.2rem; - min-height: 0; + flex: 1 1 0; + min-height: 0.5rem; } .mock-sidebar-row, @@ -3323,3 +3326,204 @@ td:last-child { display: none; } } + +/* ===== herd mock: interactive views, agent panes, attach animation ===== */ + +.mock-view { + display: none; + min-height: 0; + grid-template-rows: auto minmax(0, 1fr); +} + +.mock-view.active { + display: grid; +} + +.herdr-ui-mock .mock-main { + grid-template-rows: minmax(0, 1fr); +} + +.mock-panes.single { + grid-template-columns: minmax(0, 1fr); +} + +/* TUI panes pin their prompt/status area to the bottom, like the real thing */ +.mock-pane.tui { + display: flex; + flex-direction: column; +} + +.mock-pane.tui .tui-bottom { + margin-top: auto; +} + +.herdr-ui-mock .mock-space, +.herdr-ui-mock .mock-agent, +.herdr-ui-mock .mock-tabs span { + cursor: pointer; +} + +.herdr-ui-mock .mock-space:hover, +.herdr-ui-mock .mock-agent:hover { + background: var(--term-active-bg); +} + +.mock-view .mock-panes { + display: none; +} + +.mock-view .mock-panes.active { + display: grid; +} + +.cc-head b { + color: var(--term-text); +} + +.cc-mark, +.cc-working { + color: #d97757; +} + +.cc-bullet { + color: #d97757; +} + +.cx-bullet { + color: var(--accent); +} + +.cc-rule { + margin: 0.5rem 0; + border-top: 1px solid var(--term-border); +} + +.cc-permission { + margin-top: 0.55rem; + border: 1px solid var(--red); + padding: 0.5rem 0.6rem; +} + +/* opencode pane: brand gold/purple, outline badge, walled input box */ +.oc-y { + color: #d9b66b; +} + +.oc-purple { + color: #b481d4; +} + +.oc-badge { + display: inline-block; + width: 0.8em; + height: 0.8em; + vertical-align: -0.05em; + border: 1px solid var(--term-muted); +} + +.oc-input { + display: flex; + flex-direction: column; + justify-content: space-between; + min-height: 4.6em; + margin-top: 0.3em; + border-left: 0.28em solid #b481d4; + border-bottom: 0.18em solid var(--term-border); + background: var(--term-active-bg); + padding: 0.4em 0.6em; +} + +.oc-status { + display: flex; + justify-content: flex-end; + margin-top: 0.35em; +} + +.cc-permission .sel { + color: var(--accent); + font-weight: 700; +} + +.herdr-ui-mock .dim { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + +/* sidebar rows must scale with the mock's clamped font size */ +.herdr-ui-mock .mock-sidebar-title { + padding: 0.55em 1.1em; +} + +.herdr-ui-mock .mock-space { + padding: 0.55em 1.1em; + gap: 0.7em; +} + +.herdr-ui-mock .mock-sidebar-row, +.herdr-ui-mock .mock-agent-title { + padding: 0.45em 1.1em; +} + +.herdr-ui-mock .mock-agent { + padding: 0.38em 1.1em; + gap: 0.6em; +} + +.herdr-ui-mock .mock-space small, +.herdr-ui-mock .mock-agent small { + margin-top: 0.18em; +} + +.herdr-ui-mock .mock-sidebar-spacer { + min-height: 0.2rem; +} + +/* attach: sidebar populates once on load; view switches fade without movement */ +@keyframes mock-attach { + from { + opacity: 0; + transform: translateY(5px); + } + to { + opacity: 1; + transform: none; + } +} + +@keyframes mock-swap { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +.herdr-ui-mock .mock-sidebar > * { + animation: mock-attach 0.3s ease backwards; +} + +.herdr-ui-mock .mock-sidebar > *:nth-child(1) { animation-delay: 0.05s; } +.herdr-ui-mock .mock-sidebar > *:nth-child(2) { animation-delay: 0.12s; } +.herdr-ui-mock .mock-sidebar > *:nth-child(3) { animation-delay: 0.19s; } +.herdr-ui-mock .mock-sidebar > *:nth-child(4) { animation-delay: 0.26s; } +.herdr-ui-mock .mock-sidebar > *:nth-child(6) { animation-delay: 0.33s; } +.herdr-ui-mock .mock-sidebar > *:nth-child(7) { animation-delay: 0.4s; } +.herdr-ui-mock .mock-sidebar > *:nth-child(8) { animation-delay: 0.47s; } +.herdr-ui-mock .mock-sidebar > *:nth-child(9) { animation-delay: 0.54s; } +.herdr-ui-mock .mock-sidebar > *:nth-child(10) { animation-delay: 0.61s; } +.herdr-ui-mock .mock-sidebar > *:nth-child(11) { animation-delay: 0.68s; } +.herdr-ui-mock .mock-sidebar > *:nth-child(12) { animation-delay: 0.75s; } + +.mock-view.active .mock-panes.active .mock-pane { + animation: mock-swap 0.18s ease backwards; +} + +@media (prefers-reduced-motion: reduce) { + .herdr-ui-mock .mock-sidebar > *, + .mock-view.active .mock-tabs, + .mock-view.active .mock-pane { + animation: none; + } +} diff --git a/website/index.html b/website/index.html index 6e86a99f..bc06ca3e 100644 --- a/website/index.html +++ b/website/index.html @@ -6,7 +6,7 @@ <title>Herdr — one terminal for the whole herd</title> <meta name="description" - content="Terminal-native agent runtime and multiplexer. Run AI coding agents in real panes, detach and reattach, SSH in, see state, and orchestrate through the CLI/socket API." + content="Herdr is to coding agents what tmux is to terminals: an agent multiplexer that runs where your agents run. Real panes, agent state at a glance, ssh from anywhere, no app." /> <meta name="theme-color" content="#f0eee9" /> <link rel="canonical" href="https://herdr.dev/" /> @@ -16,7 +16,7 @@ <meta property="og:title" content="Herdr — one terminal for the whole herd" /> <meta property="og:description" - content="Terminal-native agent runtime and multiplexer. Detach, reattach, SSH in, and keep every agent visible." + content="To coding agents what tmux is to terminals. Runs where your agents run — close the laptop, ssh from anywhere, nothing dies." /> <meta property="og:url" content="https://herdr.dev/" /> <meta @@ -31,7 +31,7 @@ <meta name="twitter:title" content="Herdr — one terminal for the whole herd" /> <meta name="twitter:description" - content="Terminal-native agent runtime and multiplexer. Detach, reattach, SSH in, and keep every agent visible." + content="To coding agents what tmux is to terminals. Runs where your agents run — close the laptop, ssh from anywhere, nothing dies." /> <meta name="twitter:image" @@ -57,7 +57,7 @@ document.documentElement.setAttribute("data-palette", saved || system); })(); </script> - <link rel="stylesheet" href="/css/style.css?v=21" /> + <link rel="stylesheet" href="/css/style.css?v=33" /> </head> <body> <header class="site-header"> @@ -115,17 +115,17 @@ <div class="hero-copy"> <p class="eyebrow"> <span class="status-dot dot-done"></span> - Terminal-native agent runtime + Agent multiplexer · lives in your terminal </p> <h1>One terminal. The whole herd.</h1> <p class="hero-lede"> - Herdr is an agent runtime that runs inside your terminal. - Keep your shell, SSH setup, fonts, and keybinds; add - tmux-style persistence, mouse-native panes, + Herdr is to coding agents what tmux is to terminals: + a multiplexer that runs where your agents run — your + machine, your server, anywhere you can ssh. See <span class="state blocked">blocked</span>, <span class="state working">working</span>, and - <span class="state done">done</span> agent state, and an - API agents can drive. + <span class="state done">done</span> at a glance, + click anything, close the laptop. Nothing dies. </p> <div class="hero-actions"> <a class="button button-primary" href="/docs/quick-start/" @@ -189,69 +189,187 @@ <figure class="hero-product-shot"> <div class="herdr-ui-mock" + id="herd-mock" role="img" - aria-label="Stylized Herdr session with spaces, tabs, agent states, terminal panes, and a local docs server" + aria-label="Interactive Herdr session mock with workspaces, tabs, agent states, and terminal panes running Claude Code and Codex" > <aside class="mock-sidebar"> <div class="mock-sidebar-title">spaces</div> - <div class="mock-space active"> - <span class="mock-dot dot-idle"></span> + <div class="mock-space active" data-ws="herdr"> + <span class="mock-dot dot-working"></span> <div><strong>herdr</strong><small>master</small></div> </div> - <div class="mock-space"> + <div class="mock-space" data-ws="llm-proxy"> <span class="mock-dot dot-blocked"></span> <div><strong>llm-proxy</strong><small>master</small></div> </div> - <div class="mock-space"> + <div class="mock-space" data-ws="qmp"> <span class="mock-dot dot-done"></span> <div><strong>qmp</strong><small>autoresearch/qmp-ra…</small></div> </div> <div class="mock-sidebar-spacer"></div> - <div class="mock-sidebar-row"><span>new</span><span>menu</span></div> <div class="mock-agent-title"><span>agents</span><span>all</span></div> - <div class="mock-agent"><span>✓</span><div><strong>doc</strong><small>idle · pi</small></div></div> - <div class="mock-agent working"><span class="braille-spinner"></span><div><strong>custom-row</strong><small>working · pi</small></div></div> - <div class="mock-agent blocked"><span>◉</span><div><strong>llm-proxy</strong><small>blocked · claude</small></div></div> - <div class="mock-agent done"><span>●</span><div><strong>qmp</strong><small>done · codex</small></div></div> + <div class="mock-agent working" data-agent="herdr" data-kind="claude" data-ws-link="herdr" data-tab-link="main"><span class="braille-spinner"></span><div><strong>herdr</strong><small>working · claude</small></div></div> + <div class="mock-agent" data-agent="explore" data-kind="opencode" data-ws-link="herdr" data-tab-link="opencode"><span>✓</span><div><strong>explore</strong><small>idle · opencode</small></div></div> + <div class="mock-agent blocked" data-agent="llm-proxy" data-kind="claude" data-ws-link="llm-proxy" data-tab-link="main"><span>◉</span><div><strong>llm-proxy</strong><small>blocked · claude</small></div></div> + <div class="mock-agent done" data-agent="qmp" data-kind="codex" data-ws-link="qmp" data-tab-link="main"><span>●</span><div><strong>qmp</strong><small>done · codex</small></div></div> </aside> <section class="mock-main"> - <div class="mock-tabs"> - <span>doc</span><span>custom-row</span><span class="active">herdr</span><span>+</span> + <div class="mock-view active" data-view="herdr"> + <div class="mock-tabs"> + <span data-tab="opencode">opencode</span><span class="active" data-tab="main">herdr</span><span>+</span> + </div> + <div class="mock-panes active" data-tab="main"> + <div class="mock-pane focused tui"> + <div class="cc-head"><span class="cc-mark">✻</span> <b>Claude Code</b> <span class="dim">v2.1.168</span></div> + <div class="dim"> ~/Projects/herdr · master</div> + <br /> + <div><b>❯</b> the sidebar flickers when an agent flips state fast</div> + <br /> + <div><span class="cc-bullet">●</span> Found it. The rollup recomputes on every PTY chunk, so a double state flip repaints the dot mid-frame.</div> + <br /> + <div><span class="cc-bullet">●</span> Plan:</div> + <div class="dim"> · src/app/state.rs — buffer state events per tick</div> + <div class="dim"> · src/ui/sidebar.rs — repaint rollups once per frame</div> + <br /> + <div><b>❯</b> go, and add a regression test</div> + <br /> + <div><span class="cc-working"><span class="braille-spinner">⠋</span> Working…</span> <span class="dim">(<span id="cc-timer">13m 36s</span> · esc to interrupt)</span></div> + <div class="tui-bottom"> + <div class="cc-rule"></div> + <div><b>❯</b> <span class="cursor"></span></div> + <div class="cc-rule"></div> + <div class="dim">~/Projects/herdr > master > ctx ─── 3% 34k/1M</div> + <div class="dim">>> bypass permissions on (shift+tab to cycle)</div> + </div> + </div> + <div class="mock-pane"> + <div class="mock-prompt"><span>~/Projects/herdr</span> <em>master</em></div> + <div><b>❯</b> <span class="cmd">bun</span> run dev</div> + <div class="dim">$ node scripts/prepare-docs.mjs && astro dev</div> + <div><span class="time">02:10:44</span> <span class="blue">[types]</span> Generated 0ms</div> + <div><span class="time">02:10:44</span> <span class="blue">[content]</span> Synced content</div> + <br /> + <div><span class="badge">astro</span> <span class="green">v5.18.1</span> ready in 668 ms</div> + <br /> + <div class="url-line">┃ Local <span>http://localhost:4321/</span></div> + <div class="dim"> Network use --host to expose</div> + <br /> + <div><span class="time">02:10:44</span> <span class="green">watching for file changes...</span></div> + </div> + </div> + <div class="mock-panes single" data-tab="opencode"> + <div class="mock-pane focused tui"> + <div class="oc-y">+ Thought: 468ms</div> + <br /> + <div><span class="dim">→</span> Read src/main.rs</div> + <br /> + <div class="oc-y">+ Thought: 292ms</div> + <br /> + <div>This is <span class="oc-y">src/main.rs</span> — the entry point for <b>herdr</b>. Here's what it does:</div> + <br /> + <div><span class="blue">1.</span> Arg parsing — <span class="oc-y">session::configure_from_args</span>, then remote args for the SSH bridge.</div> + <div><span class="blue">2.</span> Subcommand dispatch — <span class="oc-y">server</span>, <span class="oc-y">client</span>, <span class="oc-y">update</span> — each returns early.</div> + <div><span class="blue">3.</span> Session mode — <span class="oc-y">auto_detect_launch()</span> connects to a running server or spawns one.</div> + <br /> + <div class="dim"><span class="oc-badge"></span> Build · MiMo V2.5 Free · 16.6s</div> + <div class="tui-bottom"> + <div class="oc-input"> + <div><span class="cursor"></span></div> + <div class="dim"><span class="oc-purple">Build</span> · MiMo V2.5 Free OpenCode Zen</div> + </div> + <div class="oc-status"><span class="dim">25.2K (13%) ctrl+p commands</span></div> + </div> + </div> + </div> </div> - <div class="mock-panes"> - <div class="mock-pane focused"> - <div class="mock-prompt"><span>~/Projects/herdr</span> <em>master</em></div> - <div><b>❯</b> <span class="cmd">printf</span> <span class="str">"one terminal. the whole herd.\n"</span> | <span class="cmd">cowsay</span></div> - <pre>------------------------------- -< one terminal. the whole herd. > -------------------------------- - \ ^__^ - \ (oo)\_______ - (__)\ )\/\ - ||----w | - || ||</pre> - <div class="mock-prompt"><span>~/Projects/herdr</span> <em>master</em></div> - <div><b>❯</b> <span class="cursor"></span></div> + <div class="mock-view" data-view="llm-proxy"> + <div class="mock-tabs"> + <span class="active" data-tab="main">migrate</span><span data-tab="logs">logs</span><span>+</span> + </div> + <div class="mock-panes single active" data-tab="main"> + <div class="mock-pane focused tui"> + <div class="cc-head"><span class="cc-mark">✻</span> <b>Claude Code</b> <span class="dim">v2.1.168</span></div> + <div class="dim"> ~/Projects/llm-proxy · master</div> + <br /> + <div><b>❯</b> prep the request-log migration and run it</div> + <br /> + <div><span class="cc-bullet">●</span> Wrote migrations/0007_request_log.sql — request_log table, retention index on created_at, daily rollup view.</div> + <br /> + <div><span class="cc-bullet">●</span> Local checks pass: sqlx prepare is clean, backfill dry-run touches 41,209 rows. Ready to apply.</div> + <div class="tui-bottom"> + <div class="cc-permission"> + <div><b>Bash command</b></div> + <div><span class="cmd">cargo</span> sqlx migrate run</div> + <div class="dim">Apply pending database migrations</div> + <br /> + <div>Do you want to proceed?</div> + <div class="sel">❯ 1. Yes</div> + <div class="dim"> 2. No, and tell Claude what to do differently (esc)</div> + </div> + </div> + </div> + </div> + <div class="mock-panes single" data-tab="logs"> + <div class="mock-pane focused"> + <div class="mock-prompt"><span>~/Projects/llm-proxy</span> <em>master</em></div> + <div><b>❯</b> <span class="cmd">tail</span> -f logs/proxy.log</div> + <div><span class="time">02:30:58</span> <span class="blue">INFO</span> request id=4818 route=/v1/messages 200 312ms</div> + <div><span class="time">02:31:04</span> <span class="blue">INFO</span> request id=4819 route=/v1/messages 200 287ms</div> + <div><span class="time">02:31:09</span> <span class="dim">DEBUG</span> cache hit ratio 0.93</div> + <div><span class="time">02:31:12</span> <span class="blue">INFO</span> request id=4820 route=/v1/messages 200 301ms</div> + <div><span class="time">02:31:15</span> <span class="red">WARN</span> upstream latency p99 1.8s</div> + <div><span class="time">02:31:18</span> <span class="blue">INFO</span> request id=4821 route=/v1/messages 200 295ms</div> + <div><span class="time">02:31:21</span> <span class="red">WARN</span> 429 from upstream, retrying in 2s</div> + <div><span class="time">02:31:24</span> <span class="blue">INFO</span> request id=4822 route=/v1/messages 200 1102ms</div> + <div><span class="time">02:31:30</span> <span class="dim">DEBUG</span> cache hit ratio 0.94</div> + <div><span class="time">02:31:33</span> <span class="blue">INFO</span> request id=4823 route=/v1/embeddings 200 88ms</div> + </div> + </div> + </div> + <div class="mock-view" data-view="qmp"> + <div class="mock-tabs"> + <span class="active" data-tab="main">codex</span><span data-tab="server">server</span><span>+</span> + </div> + <div class="mock-panes single active" data-tab="main"> + <div class="mock-pane focused tui"> + <div><span class="cx-bullet">•</span> <b>Explored</b></div> + <div class="dim"> └ Read live_handoff.rs</div> + <br /> + <div><span class="cx-bullet">•</span> <b>Ran</b></div> + <div class="dim"> └ cargo nextest run -E 'test(live_handoff)'</div> + <div class="dim"> └ 14 passed · 0 failed · 41.3s</div> + <br /> + <div><span class="cx-bullet">•</span> The handoff suite passes. Pane PTYs survive server replacement, and long-lived workloads — including the http.server in the next tab — keep responding afterward.</div> + <br /> + <div><span class="cx-bullet">•</span> Next I can wire the soak test into nightly CI and fail on p95 regressions. Want that?</div> + <div class="tui-bottom"> + <div class="cc-rule"></div> + <div><b>›</b> <span class="cursor"></span></div> + <br /> + <div class="dim">gpt-5.5 medium · ~/qmp · master · Context 6% used</div> + </div> + </div> </div> - <div class="mock-pane"> - <div class="mock-prompt"><span>~/Projects/herdr-worktrees/docs-site/website</span> <em>docs-site*</em></div> - <div><b>❯</b> <span class="cmd">bun</span> run dev</div> - <div class="dim">$ node scripts/prepare-docs.mjs && astro dev</div> - <div><span class="time">02:10:44</span> <span class="blue">[types]</span> Generated 0ms</div> - <div><span class="time">02:10:44</span> <span class="blue">[content]</span> Synced content</div> - <br /> - <div><span class="badge">astro</span> <span class="green">v5.18.1</span> ready in 668 ms</div> - <br /> - <div class="url-line">┃ Local <span>http://localhost:4321/</span></div> - <div class="dim"> Network use --host to expose</div> - <br /> - <div><span class="time">02:10:44</span> <span class="green">watching for file changes...</span></div> + <div class="mock-panes single" data-tab="server"> + <div class="mock-pane focused"> + <div class="mock-prompt"><span>~/qmp</span> <em>master</em></div> + <div><b>❯</b> <span class="cmd">python3</span> -m http.server 8080</div> + <div class="dim">Serving HTTP on 0.0.0.0 port 8080 ...</div> + <div><span class="time">02:28:41</span> "GET /runs/latest.json" <span class="green">200</span></div> + <div><span class="time">02:29:03</span> "GET /runs/latest.json" <span class="green">200</span></div> + <div><span class="time">02:29:25</span> "GET /qmp/report.html" <span class="green">200</span></div> + <div><span class="time">02:30:07</span> "GET /runs/latest.json" <span class="green">200</span></div> + <div><span class="time">02:30:18</span> "GET /favicon.ico" <span class="red">404</span></div> + <div><span class="time">02:30:42</span> "GET /qmp/report.html" <span class="green">200</span></div> + <div><span class="time">02:31:09</span> "GET /runs/latest.json" <span class="green">200</span></div> + </div> </div> </div> </section> </div> <figcaption> - The whole herd in one terminal. + The whole herd in one terminal. Click the sidebar — it's a real layout. </figcaption> </figure> </div> @@ -259,7 +377,7 @@ <section class="logo-cloud" aria-labelledby="logo-cloud-title"> <div class="logo-cloud-heading"> - <p class="section-kicker">Used in the wild</p> + <p class="section-kicker"># used in the wild</p> <h2 id="logo-cloud-title">Popular with engineers from</h2> </div> <div class="logo-marquee" aria-label="Company logos"> @@ -304,8 +422,88 @@ </div> </section> + <section class="section access-section"> + <div class="section-heading-wide"> + <div> + <p class="section-kicker"># not an app</p> + <h2>Runs where your agents run.</h2> + </div> + <p> + Desktop agent managers are stuck on the machine with the + GUI. Herdr is a client–server multiplexer: agents live on + whichever box does the work, and you attach from anywhere + — your laptop, any SSH client, even a phone. + </p> + </div> + <div class="access-grid"> + <article class="access-card"> + <span class="access-label">local</span> + <h3>Your machine</h3> + <p> + Start a local session, split panes, create tabs, and + keep agents running while your terminal comes and + goes. + </p> + <pre><code>$ herdr</code></pre> + </article> + <article class="access-card"> + <span class="access-label">ssh</span> + <h3>Any SSH client</h3> + <p> + Use Herdr like tmux on a remote box. The session + stays on the server after you detach. + </p> + <pre><code>$ ssh you@server +$ herdr</code></pre> + </article> + <article class="access-card"> + <span class="access-label">thin client</span> + <h3>Remote attach</h3> + <p> + Point your local Herdr client at an SSH config host + and stream the remote TUI back to your terminal. + </p> + <pre><code>$ herdr --remote workbox</code></pre> + </article> + </div> + <div class="mobile-proof"> + <div class="mobile-copy"> + <p class="section-kicker"># responsive tui</p> + <h3>Mobile-first when the terminal gets small.</h3> + <p> + Herdr stays usable over SSH from a phone or tablet. + The terminal view remains real, while narrow screens + get a switcher built for touch-sized decisions. + </p> + </div> + <div class="mobile-shots"> + <figure> + <img + src="/assets/mobile-agent-session-v2.jpeg" + alt="Herdr agent session over SSH on a phone" + loading="lazy" + /> + <figcaption>agent session over SSH</figcaption> + </figure> + <figure> + <img + src="/assets/mobile-switch-menu-v2.jpeg" + alt="Herdr responsive switch menu on a phone" + loading="lazy" + /> + <figcaption>responsive switch menu</figcaption> + </figure> + <p class="mobile-shout"> + screenshots taken with + <a href="https://getmoshi.app/" target="_blank" rel="noopener">moshi</a> + ❤️ on iPhone + </p> + </div> + </div> + </section> + <section class="section intro-section"> - <p class="section-kicker">The missing layer</p> + <p class="section-kicker"># the missing layer</p> <div class="section-heading-wide"> <h2> Keep your terminal. Add the control surface. @@ -314,22 +512,22 @@ Desktop agent terminals give you app UI. tmux gives you persistence. Herdr sits between them: a lightweight TUI process with real terminal panes, clickable layout, - agent state, detach/reattach, remote attach, and a - runtime API. + agent state, detach/reattach, remote attach, and an API + your agents can drive. </p> </div> <div class="contrast-grid" aria-label="What Herdr is not"> <article> <span>not a terminal emulator</span> - <p>Use Ghostty, Kitty, iTerm, Alacritty, or any terminal you already trust.</p> + <p>Ghostty, Kitty, iTerm, Alacritty — your terminal stays.</p> </article> <article> <span>not a browser dashboard</span> - <p>No web view, hosted control plane, account, or reconstructed chat surface.</p> + <p>No web view, no account, no hosted control plane.</p> </article> <article> <span>more than tmux for agents</span> - <p>Persistence plus mouse-native panes, state rollups, and commands agents can call.</p> + <p>Persistence plus clickable panes, agent state, an API.</p> </article> </div> </section> @@ -337,11 +535,11 @@ <section class="section compare-section"> <div class="section-heading-wide"> <div> - <p class="section-kicker">Positioning</p> - <h2>tmux persistence, agent awareness, no terminal replacement.</h2> + <p class="section-kicker"># positioning</p> + <h2>Most agent managers are apps. Herdr is a multiplexer.</h2> </div> <p> - tmux and Zellij own persistent terminal sessions. Desktop agent apps own dashboards, editors, or worktree flows. Herdr keeps the multiplexer inside your terminal and makes it agent-aware. + tmux and Zellij own persistent terminal sessions but don't understand agents. Desktop agent apps understand agents but live on one machine. Herdr keeps the multiplexer in your terminal and makes it agent-aware. <a href="/compare/">See the full comparison →</a> </p> </div> @@ -450,13 +648,11 @@ <section class="section feature-split"> <div class="feature-copy"> - <p class="section-kicker">Your terminal</p> + <p class="section-kicker"># your terminal</p> <h2>Same shell, same keybinds, real panes.</h2> <p> - Herdr does not replace your terminal or wrap agents in a - reconstructed chat view. It runs real processes in PTYs, - then adds layout, click targets, state, persistence, and - automation around them. + No rebuilt chat view. Real processes in real PTYs, with + layout, clicks, state, and persistence added around them. </p> <ul class="check-list"> <li>Use the mouse for panes, tabs, workspaces, and menus.</li> @@ -494,132 +690,14 @@ </figure> </section> - <section class="section pillars" aria-labelledby="pillars-title"> - <div class="section-heading"> - <p class="section-kicker">Core pillars</p> - <h2 id="pillars-title">Why terminal users switch.</h2> - </div> - <div class="pillar-grid"> - <article class="pillar-card"> - <span class="card-index">01</span> - <h3>Survives disconnects</h3> - <p> - Panes keep running in a background session server. - Close the terminal, lose SSH, or detach on purpose; - come back to the same herd later. - </p> - </article> - <article class="pillar-card"> - <span class="card-index">02</span> - <h3>Runs where code lives</h3> - <p> - Use Herdr locally, inside any SSH session, or as a - thin client to a remote host. Keep credentials and - repos on the machine doing the work. - </p> - </article> - <article class="pillar-card"> - <span class="card-index">03</span> - <h3>Mouse-native TUI</h3> - <p> - Click panes, tabs, workspaces, and agents. Drag - borders, select text, use right-click menus, then - stay on the keyboard whenever that is faster. - </p> - </article> - <article class="pillar-card"> - <span class="card-index">04</span> - <h3>Agents can drive it</h3> - <p> - The CLI and socket API let agents create panes, run - commands, read output, wait for changes, and operate - their workspace without hand-shuffled terminals. - </p> - </article> - </div> - </section> - - <section class="section access-section"> - <div class="section-heading"> - <p class="section-kicker">Local or remote</p> - <h2>Run Herdr where the work lives.</h2> - </div> - <div class="access-grid"> - <article class="access-card"> - <span class="access-label">local</span> - <h3>Your machine</h3> - <p> - Start a local session, split panes, create tabs, and - keep agents running while your terminal comes and - goes. - </p> - <pre><code>$ herdr</code></pre> - </article> - <article class="access-card"> - <span class="access-label">ssh</span> - <h3>Any SSH client</h3> - <p> - Use Herdr like tmux on a remote box. The session - stays on the server after you detach. - </p> - <pre><code>$ ssh you@server -$ herdr</code></pre> - </article> - <article class="access-card"> - <span class="access-label">thin client</span> - <h3>Remote attach</h3> - <p> - Point your local Herdr client at an SSH config host - and stream the remote TUI back to your terminal. - </p> - <pre><code>$ herdr --remote workbox</code></pre> - </article> - </div> - <div class="mobile-proof"> - <div class="mobile-copy"> - <p class="section-kicker">Responsive TUI</p> - <h3>Mobile-first when the terminal gets small.</h3> - <p> - Herdr stays usable over SSH from a phone or tablet. - The terminal view remains real, while narrow screens - get a switcher built for touch-sized decisions. - </p> - </div> - <div class="mobile-shots"> - <figure> - <img - src="/assets/mobile-agent-session-v2.jpeg" - alt="Herdr agent session over SSH on a phone" - loading="lazy" - /> - <figcaption>agent session over SSH</figcaption> - </figure> - <figure> - <img - src="/assets/mobile-switch-menu-v2.jpeg" - alt="Herdr responsive switch menu on a phone" - loading="lazy" - /> - <figcaption>responsive switch menu</figcaption> - </figure> - <p class="mobile-shout"> - screenshots taken with - <a href="https://getmoshi.app/" target="_blank" rel="noopener">moshi</a> - ❤️ on iPhone - </p> - </div> - </div> - </section> - <section class="section api-section"> <div class="api-copy"> - <p class="section-kicker">Runtime surface</p> + <p class="section-kicker"># agents can drive it</p> <h2>The UI is also a control surface.</h2> <p> - Herdr exposes workspace, tab, pane, output, and wait - operations through a CLI and newline-delimited JSON - socket API. Agents can operate their own workspace - instead of asking you to shuffle terminals by hand. + A CLI and JSON socket API expose workspaces, panes, + output, and waits. Your agents can run their own + workspace. </p> <div class="inline-links"> <a href="/docs/cli-reference/">CLI reference →</a> @@ -644,7 +722,7 @@ $ herdr</code></pre> <section class="section awareness-section"> <div class="section-heading"> - <p class="section-kicker">Agent awareness</p> + <p class="section-kicker"># agent awareness</p> <h2>Keep the herd in sight.</h2> </div> <div class="awareness-grid"> @@ -681,8 +759,8 @@ $ herdr</code></pre> <figure class="awareness-mock" role="img" aria-label="Herdr agent list showing states"> <div class="mock-sidebar"> <div class="mock-agent-title"><span>agents</span><span>all</span></div> - <div class="mock-agent"><span>✓</span><div><strong>doc</strong><small>idle · pi</small></div></div> - <div class="mock-agent working"><span class="braille-spinner"></span><div><strong>custom-row</strong><small>working · pi</small></div></div> + <div class="mock-agent"><span>✓</span><div><strong>explore</strong><small>idle · opencode</small></div></div> + <div class="mock-agent working"><span class="braille-spinner"></span><div><strong>herdr</strong><small>working · claude</small></div></div> <div class="mock-agent blocked"><span>◉</span><div><strong>llm-proxy</strong><small>blocked · claude</small></div></div> <div class="mock-agent done"><span>●</span><div><strong>qmp</strong><small>done · codex</small></div></div> <div class="mock-sidebar-spacer"></div> @@ -706,7 +784,7 @@ $ herdr</code></pre> <section class="section integrations-section"> <div class="section-heading"> - <p class="section-kicker">Integrations</p> + <p class="section-kicker"># integrations</p> <h2>Bring your existing agents into the herd.</h2> </div> <div class="agent-grid" aria-label="Supported agents"> @@ -726,15 +804,14 @@ $ herdr</code></pre> <div class="agent-card"><span class="agent-icon" style="--agent-icon: url('/assets/agent-icons/qoder-mask.svg')"></span><span>Qoder CLI</span></div> </div> <p class="integration-note"> - Any terminal agent works in Herdr. Use the Herdr API to add - richer state, orchestration, and custom workflows; - <a href="/docs/integrations/">see example integrations</a> - or build your own for anything. + Any terminal agent works out of the box. + <a href="/docs/integrations/">Integrations</a> add richer + state and session resume. </p> </section> <section class="final-cta"> - <p class="section-kicker">Start the herd</p> + <p class="section-kicker"># start the herd</p> <h2>Install Herdr, run two agents, detach once.</h2> <p> The value shows up the first time the herd keeps running @@ -1083,19 +1160,84 @@ $ herdr</code></pre> (function () { var frames = ["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"]; - var els = document.querySelectorAll(".braille-spinner"); - if (!els.length) return; - var states = Array.prototype.map.call(els, function () { return 0; }); - els.forEach(function (el, idx) { - el.textContent = frames[0]; - }); + var tick = 0; setInterval(function () { - els.forEach(function (el, idx) { - states[idx] = (states[idx] + 1) % frames.length; - el.textContent = frames[states[idx]]; - }); + tick = (tick + 1) % frames.length; + var els = document.querySelectorAll(".braille-spinner"); + for (var i = 0; i < els.length; i++) { + els[i].textContent = frames[tick]; + } }, 80); })(); + + /* herd mock: clickable workspaces, tabs, and agents */ + (function () { + var mock = document.getElementById("herd-mock"); + if (!mock) return; + + function selectTab(tab) { + var target = tab.getAttribute("data-tab"); + if (!target) return; + tab.parentElement.querySelectorAll("span").forEach(function (t) { + t.classList.remove("active"); + }); + tab.classList.add("active"); + var view = tab.closest(".mock-view"); + view.querySelectorAll(".mock-panes").forEach(function (panes) { + panes.classList.toggle("active", panes.getAttribute("data-tab") === target); + }); + } + + function activateWorkspace(id, tabId) { + mock.querySelectorAll(".mock-space").forEach(function (ws) { + ws.classList.toggle("active", ws.getAttribute("data-ws") === id); + }); + mock.querySelectorAll(".mock-view").forEach(function (view) { + view.classList.toggle("active", view.getAttribute("data-view") === id); + }); + if (tabId) { + var view = mock.querySelector('.mock-view[data-view="' + id + '"]'); + var tab = view && view.querySelector('.mock-tabs span[data-tab="' + tabId + '"]'); + if (tab) selectTab(tab); + } + } + + mock.querySelectorAll(".mock-space").forEach(function (ws) { + ws.addEventListener("click", function () { + activateWorkspace(ws.getAttribute("data-ws")); + }); + }); + + mock.querySelectorAll(".mock-agent").forEach(function (a) { + a.addEventListener("click", function () { + activateWorkspace( + a.getAttribute("data-ws-link"), + a.getAttribute("data-tab-link") + ); + }); + }); + + mock.querySelectorAll(".mock-tabs span").forEach(function (tab) { + if (!tab.getAttribute("data-tab")) return; + tab.addEventListener("click", function (event) { + event.stopPropagation(); + selectTab(tab); + }); + }); + + /* the working counter keeps counting, like the real thing */ + var timer = document.getElementById("cc-timer"); + if (timer) { + var seconds = 13 * 60 + 36; + setInterval(function () { + if (document.hidden) return; + seconds += 1; + if (seconds >= 16 * 60) seconds = 0; /* new turn, counter resets */ + timer.textContent = Math.floor(seconds / 60) + "m " + (seconds % 60) + "s"; + }, 1000); + } + + })(); </script> </body> </html> diff --git a/website/scripts/prepare-docs.mjs b/website/scripts/prepare-docs.mjs index 310e7eb9..9c912a38 100644 --- a/website/scripts/prepare-docs.mjs +++ b/website/scripts/prepare-docs.mjs @@ -26,6 +26,7 @@ async function preparePublicAssets() { for (const file of [ 'install.sh', 'install.ps1', + 'agent-guide.md', 'latest.json', 'preview.json', 'robots.txt', diff --git a/website/src/content/docs/agent-skill.mdx b/website/src/content/docs/agent-skill.mdx index fc4f0589..af7fa7bf 100644 --- a/website/src/content/docs/agent-skill.mdx +++ b/website/src/content/docs/agent-skill.mdx @@ -7,6 +7,8 @@ Herdr ships a reusable agent skill file at [`SKILL.md`](https://github.com/ogulc Install that file into any coding agent that supports reusable skills or custom instructions. The skill teaches the agent how to control Herdr from inside a Herdr pane. +Herdr also serves a separate guide at [`herdr.dev/agent-guide.md`](https://herdr.dev/agent-guide.md) for a different job: an agent helping a human learn, set up, or troubleshoot Herdr. The skill is for an agent operating Herdr; the guide is for an agent teaching a human. + ## What the skill does The skill tells an agent to use the `herdr` CLI when `HERDR_ENV=1` is set. That means the agent is running inside a Herdr-managed pane and can safely talk to the local Herdr socket. diff --git a/website/src/content/docs/agents.mdx b/website/src/content/docs/agents.mdx index 49f64881..ae45d26b 100644 --- a/website/src/content/docs/agents.mdx +++ b/website/src/content/docs/agents.mdx @@ -85,34 +85,14 @@ This is the main Herdr workflow: start several agents, let them work in parallel ## Direct integrations -Install integrations for agents that expose hooks or plugins: +Install the integration for each agent you use; it gives Herdr hook or plugin reports instead of screen detection alone: ```bash -herdr integration install pi -herdr integration install omp herdr integration install claude -herdr integration install codex -herdr integration install copilot -herdr integration install cursor -herdr integration install droid -herdr integration install kimi -herdr integration install opencode -herdr integration install kilo -herdr integration install hermes -herdr integration install qodercli -``` - -Check installed integration versions: - -```bash herdr integration status ``` -Show only outdated integrations: - -```bash -herdr integration status --outdated-only -``` +Each supported agent has its own integration name and behavior. See [Integrations](/docs/integrations/) for the per-agent details and the full install list. ## Custom agent labels diff --git a/website/src/content/docs/concepts.mdx b/website/src/content/docs/concepts.mdx index 3c3d7849..2ac32cc9 100644 --- a/website/src/content/docs/concepts.mdx +++ b/website/src/content/docs/concepts.mdx @@ -23,6 +23,17 @@ A pane is a real terminal. Herdr renders the terminal output, sends input back t Panes can be split right or down. They can be renamed manually, read from the CLI, sent input, and closed. +## Mouse UI + +Herdr is mouse-native. You can click panes, tabs, workspaces, and agents. You can drag split borders, select text, and use right-click menus. Everything below is also reachable by mouse; keyboard bindings are an optional layer. + +If you prefer keyboard-only control, or you want Herdr to stop capturing mouse input, disable mouse capture: + +```toml +[ui] +mouse_capture = false +``` + ## Agent An agent is a process Herdr recognizes inside a pane. Herdr detects agents from foreground processes, screen manifests, and optional integrations. @@ -71,15 +82,4 @@ Herdr has terminal mode, prefix mode, and navigate mode. Terminal mode sends keys to the focused pane. Prefix mode waits for one Herdr action after the prefix key. Navigate mode is the persistent workspace navigation surface. -Press the prefix key, default `ctrl+b`, then an action key such as `c` for a new tab or `w` for workspace navigation. - -## Mouse UI - -Herdr is mouse-native. You can click panes, tabs, workspaces, and agents. You can drag split borders, select text, and use right-click menus. - -If you prefer keyboard-only control, or you want Herdr to stop capturing mouse input, disable mouse capture: - -```toml -[ui] -mouse_capture = false -``` +Press the prefix key, default `ctrl+b`, then an action key such as `c` for a new tab or `w` for workspace navigation. New to the prefix idea? See [Keyboard](/docs/keyboard/). diff --git a/website/src/content/docs/configuration.mdx b/website/src/content/docs/configuration.mdx index e9fa2d02..c22e0107 100644 --- a/website/src/content/docs/configuration.mdx +++ b/website/src/content/docs/configuration.mdx @@ -115,6 +115,8 @@ When enabled, `herdr --remote` writes a private temporary SSH config that includ ## Keybindings +For a guided introduction to the prefix and a vetted prefix-free setup, see [Keyboard](/docs/keyboard/). + Herdr has a prefix mode similar to tmux. The default prefix is `ctrl+b`. Keybinding strings are explicit: `prefix+n` means press the configured prefix and then `n`; `ctrl+alt+n` is a direct terminal-mode shortcut. A small keybinding override looks like this: diff --git a/website/src/content/docs/index.mdx b/website/src/content/docs/index.mdx index eadb3920..68e1d869 100644 --- a/website/src/content/docs/index.mdx +++ b/website/src/content/docs/index.mdx @@ -1,9 +1,9 @@ --- title: Herdr documentation -description: Terminal-native agent runtime and multiplexer. +description: Terminal workspace manager for AI coding agents. template: splash hero: - tagline: "One terminal for the whole herd: real panes, persistent sessions, SSH attach, state awareness, and CLI/socket orchestration." + tagline: "Install, learn, and configure Herdr. Start on the path that matches you — no multiplexer experience required." image: file: ../../../public/assets/logo.svg actions: @@ -16,38 +16,34 @@ hero: import { Card, CardGrid } from '@astrojs/starlight/components'; -Herdr is a terminal-native agent runtime and multiplexer. It gives the whole herd persistent terminal workspaces with panes, tabs, mouse control, state awareness, and an API that agents can use themselves. +## Pick your path -```bash -curl -fsSL https://herdr.dev/install.sh | sh -herdr -``` +<CardGrid> + <Card title="New to terminal multiplexers?"> + You don't need to learn shortcuts to start. Herdr is mouse-first: click panes, drag borders, split and switch from right-click menus. -On Windows preview beta: + [Quick start →](/docs/quick-start/) + </Card> + <Card title="Coming from tmux or zellij?"> + You already know the model. The prefix is `ctrl+b`, panes persist, detach and reattach work the way you expect. -```powershell -powershell -ExecutionPolicy Bypass -c "irm https://herdr.dev/install.ps1 | iex" -herdr -``` + [Concepts →](/docs/concepts/) · [Keybindings →](/docs/configuration/#keybindings) + </Card> +</CardGrid> -## Start here +## Or let your agent introduce you -<CardGrid> - <Card title="Install"> - Install stable Herdr on Linux/macOS or the Windows preview beta, update it later, and verify the binary. +Already running an AI coding agent? Let it do the onboarding. Paste this prompt: - [Install Herdr →](/docs/install/) - </Card> - <Card title="Quick start"> - Create your first workspace, run an agent, split panes, and detach safely. +```text +Help me understand and set up Herdr. Read https://herdr.dev/agent-guide.md first, then walk me through it step by step. +``` - [Start using Herdr →](/docs/quick-start/) - </Card> - <Card title="Local, SSH, and mobile"> - Run Herdr locally, inside SSH, from your phone, or through `herdr --remote`. +The guide teaches your agent Herdr's concepts, setup, configuration, and common fixes, so its answers stay accurate instead of improvised. - [Pick a workflow →](/docs/how-to-work/) - </Card> +## Core guides + +<CardGrid> <Card title="Agents"> See supported agents, detection behavior, integrations, custom labels, and direct attach. diff --git a/website/src/content/docs/install.mdx b/website/src/content/docs/install.mdx index e64e9c7d..1518e362 100644 --- a/website/src/content/docs/install.mdx +++ b/website/src/content/docs/install.mdx @@ -39,54 +39,6 @@ mise use -g herdr If mise reports `herdr not found in mise tool registry`, update mise and retry. Older mise versions predate the Herdr registry entry; `mise use -g github:ogulcancelik/herdr` works as a temporary fallback. -## Verify - -Start Herdr: - -```bash -herdr -``` - -If your shell cannot find `herdr`, restart the terminal or check that the install directory is on your PATH. - -## Update - -Herdr checks for new releases and notifies you in the app. You can update manually: - -```bash -herdr update -``` - -`herdr update` is for installs managed by Herdr's own installer. Homebrew, mise, and Nix installs are updated through those package managers instead. - -On Linux and macOS, Herdr uses the stable update channel by default. To opt into preview builds from `master`, set the channel: - -```bash -herdr channel set preview -``` - -Switch Linux and macOS direct installs back to stable the same way: - -```bash -herdr channel set stable -``` - -For direct installs, changing channels also checks that channel and installs its latest binary. If that update fails, run `herdr update` to retry from the configured channel. - -Preview builds are GitHub prereleases published from the current development branch. They are useful when you want fixes before the next stable release, but they can regress. Homebrew, mise, and Nix installs do not use the preview channel. - -Windows beta builds are preview-only for now. `herdr channel set stable` is rejected on Windows until stable Windows releases are available. - -By default, `herdr update` installs the new binary and leaves compatible running sessions alone. If an update changes Herdr's client/server protocol, Herdr asks whether to stop the old server after installing. Stop the old server to use the new version. Stopping exits pane processes. For the default session, run `herdr server stop`, then run `herdr` again. For a named session, run `herdr session stop <name>`, then run `herdr session attach <name>` again. - -To opt into experimental live server handoff for supported running sessions, run: - -```bash -herdr update --handoff -``` - -Live handoff does not apply to Homebrew, mise, or Nix package-manager updates. For those installs, update with the package manager, then restart that Herdr session when you are ready to use the new server. If a running session still uses the old server, stop it with `herdr server stop` or `herdr session stop <name>`, then run Herdr again. - ## Install with Nix If you already use Nix, Herdr provides a flake that builds Herdr from source: @@ -146,6 +98,54 @@ Windows binaries are published only on preview releases while native Windows sup | --- | --- | | Windows x86_64 beta | `herdr-windows-x86_64.exe` | +## Verify + +Start Herdr: + +```bash +herdr +``` + +If your shell cannot find `herdr`, restart the terminal or check that the install directory is on your PATH. + +## Update + +Herdr checks for new releases and notifies you in the app. You can update manually: + +```bash +herdr update +``` + +`herdr update` is for installs managed by Herdr's own installer. Homebrew, mise, and Nix installs are updated through those package managers instead. + +On Linux and macOS, Herdr uses the stable update channel by default. To opt into preview builds from `master`, set the channel: + +```bash +herdr channel set preview +``` + +Switch Linux and macOS direct installs back to stable the same way: + +```bash +herdr channel set stable +``` + +For direct installs, changing channels also checks that channel and installs its latest binary. If that update fails, run `herdr update` to retry from the configured channel. + +Preview builds are GitHub prereleases published from the current development branch. They are useful when you want fixes before the next stable release, but they can regress. Homebrew, mise, and Nix installs do not use the preview channel. + +Windows beta builds are preview-only for now. `herdr channel set stable` is rejected on Windows until stable Windows releases are available. + +By default, `herdr update` installs the new binary and leaves compatible running sessions alone. If an update changes Herdr's client/server protocol, Herdr asks whether to stop the old server after installing. Stop the old server to use the new version. Stopping exits pane processes. For the default session, run `herdr server stop`, then run `herdr` again. For a named session, run `herdr session stop <name>`, then run `herdr session attach <name>` again. + +To opt into experimental live server handoff for supported running sessions, run: + +```bash +herdr update --handoff +``` + +Live handoff does not apply to Homebrew, mise, or Nix package-manager updates. For those installs, update with the package manager, then restart that Herdr session when you are ready to use the new server. If a running session still uses the old server, stop it with `herdr server stop` or `herdr session stop <name>`, then run Herdr again. + ## Requirements Stable Herdr releases support Linux and macOS. Native Windows builds are preview-only beta releases; see [Windows beta](/docs/windows-beta/) for supported workflows and known limitations. diff --git a/website/src/content/docs/keyboard.mdx b/website/src/content/docs/keyboard.mdx new file mode 100644 index 00000000..07f11362 --- /dev/null +++ b/website/src/content/docs/keyboard.mdx @@ -0,0 +1,112 @@ +--- +title: Keyboard +description: What the prefix is, which bindings to learn first, and how to go prefix-free. +--- + +:::tip[Coming from tmux or zellij?] +You already know this model. Jump to the [keybinding reference](/docs/configuration/#keybindings) for the full default keymap and config syntax. +::: + +Herdr is mouse-native. You can click panes, tabs, workspaces, and agents, drag split borders, and use right-click menus without learning a single keybinding. Keyboard control is an optional layer, not a requirement. + +## What the prefix is + +A terminal multiplexer sits between your terminal and the programs running inside it. Those programs already use most key combinations: `ctrl+c` interrupts, `ctrl+r` searches history, editors claim nearly everything else. If Herdr grabbed common keys directly, it would break the programs inside it. + +The prefix solves this. Press the prefix key, default `ctrl+b`, and the next keypress goes to Herdr instead of your terminal. `prefix+c` means: press `ctrl+b`, release, then press `c`. One reserved key instead of dozens. + +Press `prefix+?` at any time to see every active binding. + +## Learn these five first + +| Action | Key | +| --- | --- | +| New tab | `prefix+c` | +| Split right / down | `prefix+v` / `prefix+minus` | +| Move between panes | `prefix+h/j/k/l` | +| Workspace navigation | `prefix+w` | +| Detach, leave everything running | `prefix+q` | + +These cover most daily movement. Everything else can stay on the mouse. + +## The rest, by task + +Panes: + +| Action | Key | +| --- | --- | +| Zoom the focused pane | `prefix+z` | +| Close pane | `prefix+x` | +| Swap panes | `prefix+shift+h/j/k/l` | +| Resize mode | `prefix+r` | +| Copy mode | `prefix+[` | + +Tabs: + +| Action | Key | +| --- | --- | +| Next / previous tab | `prefix+n` / `prefix+p` | +| Jump to tab 1–9 | `prefix+1..9` | +| Rename tab | `prefix+shift+t` | +| Close tab | `prefix+shift+x` | + +Workspaces and session: + +| Action | Key | +| --- | --- | +| New workspace | `prefix+shift+n` | +| Rename workspace | `prefix+shift+w` | +| Close workspace | `prefix+shift+d` | +| Goto picker | `prefix+g` | +| Toggle sidebar | `prefix+b` | + +The full keymap and the binding syntax live in the [keybinding reference](/docs/configuration/#keybindings). + +## Copy mode + +Press `prefix+[` to enter copy mode for the focused pane. Use `h/j/k/l`, `w/b/e`, and `{`/`}` to move, `v` or Space to start a selection, `y` or Enter to copy it, and `q` or Esc to leave without copying. Mouse drag-select copies without entering copy mode at all. + +## Change anything + +Every binding is configurable, including the prefix itself: + +```toml +[keys] +prefix = "ctrl+a" +``` + +## Going prefix-free + +You can bind Herdr actions to direct chords that need no prefix at all. The hard part is knowing which chords are safe, because terminals, shells, and desktop environments already own most of the keyboard. + +Any chord works as a binding: `ctrl+j`, `alt+k`, whatever fits your hands. But a chord has to survive three layers before Herdr sees it: your operating system, your outer terminal (Ghostty, iTerm2, and others ship their own defaults), and the programs running inside the pane. `ctrl+j` reaches Herdr fine, but shells and editors treat it as enter. `alt+k` is free on Linux, but macOS composes it into a special character in most terminals. If you pick chords from these families, double-check them against your own terminal and OS shortcuts. + +We mapped the default keybindings of Ghostty, iTerm2, Terminal.app, kitty, WezTerm, Alacritty, Warp, Windows Terminal, GNOME Terminal, and Konsole, plus the global shortcuts of GNOME and KDE. One modifier family is almost untouched everywhere: `ctrl+alt`. Terminals leave it free, it is not affected by the macOS option-key composing behavior that blocks plain `alt` chords, and it transmits even in terminals without a modern keyboard protocol. It is the safe default recommendation; the choice stays yours. + +This setup keeps the prefix bindings working and adds direct chords on top: + +```toml +[keys] +focus_pane_left = ["prefix+h", "ctrl+alt+h"] +focus_pane_down = ["prefix+j", "ctrl+alt+j"] +focus_pane_up = ["prefix+k", "ctrl+alt+k"] +focus_pane_right = ["prefix+l", "ctrl+alt+l"] +previous_tab = ["prefix+p", "ctrl+alt+["] +next_tab = ["prefix+n", "ctrl+alt+]"] +new_tab = ["prefix+c", "ctrl+alt+c"] +split_vertical = ["prefix+v", "ctrl+alt+d"] +split_horizontal = ["prefix+minus", "ctrl+alt+shift+d"] +zoom = ["prefix+z", "ctrl+alt+z"] +``` + +A few `ctrl+alt` chords are taken elsewhere. Avoid these: + +| Chord | Owned by | +| --- | --- | +| `ctrl+alt+arrows` | GNOME workspace switching, Ghostty and Konsole defaults | +| `ctrl+alt+t` | "Launch terminal" on Ubuntu and Fedora | +| `ctrl+alt+l` / `ctrl+alt+a` | KDE lock screen / attention window | +| `ctrl+alt+s` / `ctrl+alt+u` | Konsole | +| `ctrl+alt+f1..f12` | Linux virtual console switching | + +If a direct chord does nothing, your terminal or desktop environment consumed it before Herdr could see it. Rebind either side: free the chord in the terminal's settings, or pick another chord in Herdr. diff --git a/website/src/content/docs/persistence-remote.mdx b/website/src/content/docs/persistence-remote.mdx index 1f60f964..80cf19d3 100644 --- a/website/src/content/docs/persistence-remote.mdx +++ b/website/src/content/docs/persistence-remote.mdx @@ -9,25 +9,7 @@ For the local, SSH, and `herdr --remote` workflows, see [How to work with Herdr] ## Detach and reattach -Start Herdr: - -```bash -herdr -``` - -Detach the client with `ctrl+b q`. - -Your panes and agents keep running. Reattach by running Herdr again: - -```bash -herdr -``` - -If you want to end the session and stop its panes, stop the default server: - -```bash -herdr server stop -``` +Detach the client with `ctrl+b q`; panes and agents keep running. Reattach by running `herdr` again. Stop the session and its panes with `herdr server stop`. When Herdr starts again after a full server stop, it restores the saved session shape. For what survives detach, server restart, screen history replay, native agent session restore, and live handoff, see [Session state and restore](/docs/session-state/). @@ -55,16 +37,7 @@ herdr session delete side-project --json ## Remote attach over SSH -Run Herdr on a server and attach from any SSH client: - -```bash -ssh you@server -herdr -``` - -In this mode your shell is remote, Herdr runs on the remote host, and panes keep running there after you detach. - -You can also attach through SSH from your local machine: +There are two remote modes; [How to work with Herdr](/docs/how-to-work/) compares them. SSH to the server and run `herdr` there for the tmux-style path. Or attach through SSH from your local machine: ```bash herdr --remote workbox diff --git a/website/src/content/docs/quick-start.mdx b/website/src/content/docs/quick-start.mdx index b6869add..26eaa9aa 100644 --- a/website/src/content/docs/quick-start.mdx +++ b/website/src/content/docs/quick-start.mdx @@ -3,7 +3,7 @@ title: Quick start description: Create your first Herdr workspace and run agents in persistent terminal panes. --- -Start Herdr from any project directory: +If Herdr is not installed yet, see [Install](/docs/install/). Then start Herdr from any project directory: ```bash herdr @@ -11,27 +11,31 @@ herdr Herdr launches or attaches to your default background session. You do not manage sockets. If you detach, agents keep running. -For the local, SSH, and `herdr --remote` workflows, see [How to work with Herdr](/docs/how-to-work/). - ## Create a workspace -When a session has no workspaces, Herdr opens one automatically. A workspace is a project-level container for tabs, panes, and agents. Press `prefix+shift+n` to create another workspace. +When a session has no workspaces, Herdr opens one automatically. A workspace is a project-level container for tabs, panes, and agents. Give each active project its own workspace; this keeps agent state readable in the sidebar. + +## Use the mouse + +Herdr is mouse-native, so start by clicking. Click panes, tabs, workspaces, and agents to focus them. Drag split borders to resize. Right-click for context menus, including splitting panes and creating tabs. Drag-select text to copy it to your clipboard; double-click a token to copy it directly. Copying does not require Ctrl+C. -Give each active project its own workspace. This keeps agent state readable in the sidebar. +Ctrl-click opens pane links when your terminal sends the modified click to Herdr. This works for OSC 8 hyperlinks and visible `http://` or `https://` URLs. The portable terminal-native fallback is Shift-Ctrl-click on Linux or Shift-Cmd-click on macOS. + +If you configure `ui.right_click_passthrough_modifier`, that modifier plus right-click sends right-click, hold, and drag gestures to mouse-reporting pane apps. ## Run an agent -Start your agent in the root pane. +Start your coding agent in a pane: ```bash -pi +claude ``` -Herdr detects supported agents automatically. The sidebar shows whether each agent is `working`, `blocked`, `done`, or `idle`. +Or `codex`, `pi`, `opencode`, or any other [supported agent](/docs/agents/). Herdr detects it automatically. The sidebar shows whether each agent is `working`, `blocked`, `done`, or `idle` — across every workspace, so you always know which project needs you. ## Keyboard control -Press `ctrl+b` to enter prefix mode, then press an action key. +Keyboard control is optional; the mouse covers everything. Press `ctrl+b` to enter prefix mode, then press an action key. Common actions: @@ -45,48 +49,21 @@ Common actions: | New workspace | `prefix+shift+n` | | Detach client | `prefix+q` | -After detaching, run `herdr` again to reattach to the same session. +New to the prefix idea? [Keyboard](/docs/keyboard/) explains what it is, why multiplexers use one, and how to go prefix-free. Press `prefix+?` inside Herdr to see every active binding, and `prefix+[` to copy from the keyboard in copy mode. -## Use the mouse - -Herdr is mouse-native. You can click panes, tabs, workspaces, and agents; drag borders; drag-select text to copy it to your clipboard; double-click a token to copy it directly; and use right-click menus. Copying does not require Ctrl+C. - -If you configure `ui.right_click_passthrough_modifier`, that modifier plus right-click sends right-click, hold, and drag gestures to mouse-reporting pane apps. - -Ctrl-click opens pane links when your terminal sends the modified click to Herdr. This works for OSC 8 hyperlinks and visible `http://` or `https://` URLs. The portable terminal-native fallback is Shift-Ctrl-click on Linux or Shift-Cmd-click on macOS. +## Detach and come back -## Copy from the keyboard +Press `prefix+q` or simply close your terminal window. The Herdr server and every agent keep running. Run `herdr` again to reattach to the same session. -Press `prefix+[` to enter copy mode for the focused pane. Use `h/j/k/l`, `w/b/e`, and `{`/`}` to move, `v` or Space to start a selection, `y` or Enter to copy it, and `q` or Esc to leave without copying. - -## Manage named sessions - -Named sessions are separate Herdr server namespaces. Use them when you want fully separate runtime state. - -```bash -herdr session list -herdr session attach work -herdr session attach side-project -herdr session stop work -herdr session delete side-project -``` - -Workspaces are usually enough. Use named sessions when you need isolation between sets of panes, sockets, and persistent state. - -## Attach from another machine - -Run Herdr where the work lives. If the code and credentials are on a server, either SSH there and run Herdr like a terminal multiplexer: +To actually end the session and stop its panes: ```bash -ssh you@server -herdr +herdr server stop ``` -Or attach from your local terminal through SSH: - -```bash -herdr --remote workbox -herdr --remote ssh://you@server:2222 -``` +## Where next -For repeat targets, put the host in your SSH config. See [How to work with Herdr](/docs/how-to-work/) for the full model. +- [Concepts](/docs/concepts/) — the workspace, tab, pane, and agent model in two minutes. +- [How to work with Herdr](/docs/how-to-work/) — local, SSH, phone, and `herdr --remote` workflows. +- [Agents](/docs/agents/) — supported agents, detection, and integrations that improve state accuracy. +- [Configuration](/docs/configuration/) — keybindings, themes, notifications, and everything else. diff --git a/website/src/content/docs/session-state.mdx b/website/src/content/docs/session-state.mdx index e317caad..6e627d67 100644 --- a/website/src/content/docs/session-state.mdx +++ b/website/src/content/docs/session-state.mdx @@ -5,6 +5,17 @@ description: Understand what Herdr keeps live, restores after restart, replays f Herdr has several state paths. They solve different problems. +## What survives + +| Case | Processes keep running | Layout returns | Recent screen returns | Agent conversation resumes | +| --- | --- | --- | --- | --- | +| Detach and reattach | Yes | Yes | Yes, from the live terminal | Yes, because the process never stopped | +| Server restart | No | Yes | Only with pane screen history | Only with native agent session restore | +| Update without `--handoff` | Compatible servers keep running; restart-required servers may need stop/restart | Yes after restart | Only with pane screen history | Only with native agent session restore | +| Update with `--handoff` | Best effort for supported running servers | Yes | Yes, from the live terminal if handoff succeeds | Yes, because the process keeps running if handoff succeeds | + +The sections below explain each path. + ## Live persistence Normal detach keeps the Herdr server running. Panes, shells, agents, servers, tests, and command processes keep running inside that server. @@ -91,12 +102,3 @@ herdr --remote workbox --handoff Plain `herdr update` and plain `herdr --remote workbox` use the normal restart/stop flow by default. `herdr update --handoff` only applies to installs managed by Herdr's own updater. Homebrew, mise, and Nix installs are updated through their package managers, so `herdr update` is disabled there and cannot perform live handoff. - -## What Survives - -| Case | Processes keep running | Layout returns | Recent screen returns | Agent conversation resumes | -| --- | --- | --- | --- | --- | -| Detach and reattach | Yes | Yes | Yes, from the live terminal | Yes, because the process never stopped | -| Server restart | No | Yes | Only with pane screen history | Only with native agent session restore | -| Update without `--handoff` | Compatible servers keep running; restart-required servers may need stop/restart | Yes after restart | Only with pane screen history | Only with native agent session restore | -| Update with `--handoff` | Best effort for supported running servers | Yes | Yes, from the live terminal if handoff succeeds | Yes, because the process keeps running if handoff succeeds | |
