aboutsummaryrefslogtreecommitdiff
path: root/website/src
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-05-18 01:39:39 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-05-18 05:06:41 +0300
commitf74602b8813c4937dad505c60ca2f44b3e9b21a1 (patch)
tree84d8e27a91a6c4198c59405e6a24848e21ed227b /website/src
parenta3d465687b4f5cd16ce5ecc554c163dd45f15a94 (diff)
docs: redesign website and add starlight docs
Diffstat (limited to 'website/src')
-rw-r--r--website/src/content.config.ts12
-rw-r--r--website/src/content/docs/agent-skill.mdx103
-rw-r--r--website/src/content/docs/agents.mdx120
-rw-r--r--website/src/content/docs/cli-reference.mdx186
-rw-r--r--website/src/content/docs/concepts.mdx85
-rw-r--r--website/src/content/docs/configuration.mdx238
-rw-r--r--website/src/content/docs/index.mdx104
-rw-r--r--website/src/content/docs/install.mdx58
-rw-r--r--website/src/content/docs/integrations.mdx116
-rw-r--r--website/src/content/docs/persistence-remote.mdx125
-rw-r--r--website/src/content/docs/quick-start.mdx80
-rw-r--r--website/src/content/docs/socket-api.mdx224
-rw-r--r--website/src/pages/index.astro7
-rw-r--r--website/src/styles/starlight.css162
14 files changed, 1620 insertions, 0 deletions
diff --git a/website/src/content.config.ts b/website/src/content.config.ts
new file mode 100644
index 00000000..6282421b
--- /dev/null
+++ b/website/src/content.config.ts
@@ -0,0 +1,12 @@
+import { defineCollection } from 'astro:content';
+import { docsLoader } from '@astrojs/starlight/loaders';
+import { docsSchema } from '@astrojs/starlight/schema';
+
+function docsPath({ entry }: { entry: string }) {
+ const slug = entry.replace(/\.(md|mdx|markdown|mdown|mkdn|mkd|mdwn)$/i, '');
+ return slug === 'index' ? 'docs' : `docs/${slug}`;
+}
+
+export const collections = {
+ docs: defineCollection({ loader: docsLoader({ generateId: docsPath }), schema: docsSchema() }),
+};
diff --git a/website/src/content/docs/agent-skill.mdx b/website/src/content/docs/agent-skill.mdx
new file mode 100644
index 00000000..65327c33
--- /dev/null
+++ b/website/src/content/docs/agent-skill.mdx
@@ -0,0 +1,103 @@
+---
+title: Agent skill
+description: A concise guide for coding agents running inside Herdr.
+---
+
+This page teaches coding agents how to use Herdr while they are running inside a Herdr pane.
+
+Use Herdr to organize parallel work instead of stacking everything in one terminal.
+
+## Core model
+
+Herdr has four levels:
+
+| Level | Meaning |
+| --- | --- |
+| Workspace | A project or task context. |
+| Tab | A view inside a workspace. |
+| Pane | A terminal area inside a tab. |
+| Agent | A detected coding agent running in a pane. |
+
+Use workspace and tab actions for layout. Use pane actions for commands and output.
+
+## Read the current layout
+
+```bash
+herdr pane list
+```
+
+Use the pane IDs returned by Herdr for later commands.
+
+## Create a helper pane
+
+Split a pane and run a command:
+
+```bash
+herdr pane split 1-1 --direction right
+herdr pane run 1-2 "just test"
+```
+
+Prefer `pane run` over sending raw keys when you want to submit a full command line.
+
+## Read output
+
+```bash
+herdr pane read 1-2 --source recent --lines 80
+```
+
+Use `recent-unwrapped` when reading logs or matching long lines.
+
+```bash
+herdr pane read 1-2 --source recent-unwrapped --lines 120
+```
+
+## Wait for agents
+
+Wait for another agent to finish or become blocked:
+
+```bash
+herdr wait agent-status 1-3 --status done
+herdr wait agent-status 1-3 --status blocked
+```
+
+Use agent waits for recognized coding agents. Use normal output matching for ordinary commands, servers, and tests.
+
+## Preserve focus
+
+Do not steal visible focus unless the user asked for it. Create panes, submit commands, and read output without changing the user’s active view when possible.
+
+## Use clear pane aliases
+
+When your tool supports aliases, use names like `server`, `tests`, `reviewer`, or `docs`. This makes later pane operations easier to audit.
+
+## Good patterns
+
+Run long work in a separate pane:
+
+```bash
+herdr pane split 1-1 --direction right
+herdr pane run 1-2 "just check"
+```
+
+Watch a server until it is ready:
+
+```bash
+herdr pane read 1-2 --source recent-unwrapped --lines 80
+```
+
+Ask a reviewer agent to inspect a change:
+
+```bash
+herdr pane split 1-1 --direction right
+herdr pane run 1-2 "pi --model <review-model>"
+```
+
+## Avoid these patterns
+
+Do not pile every command into the current pane.
+
+Do not use raw key injection for command submission when `pane run` is available.
+
+Do not wait for `agent-status` on a normal process that is not a coding agent.
+
+Do not change implementation direction without telling the user.
diff --git a/website/src/content/docs/agents.mdx b/website/src/content/docs/agents.mdx
new file mode 100644
index 00000000..c01e97d1
--- /dev/null
+++ b/website/src/content/docs/agents.mdx
@@ -0,0 +1,120 @@
+---
+title: Agents
+description: See what Herdr can detect, how agent state works, and how integrations improve it.
+---
+
+Herdr is useful because it knows when agents are working, blocked, done, or idle. You can scan the sidebar instead of checking every pane manually.
+
+## Supported agents
+
+Automatic detection works out of the box for common coding agents.
+
+| Agent | Idle / done | Working | Blocked |
+| --- | --- | --- | --- |
+| Pi | yes | yes | partial |
+| Claude Code | yes | yes | yes |
+| Codex | yes | yes | yes |
+| Droid | yes | yes | yes |
+| Amp | yes | yes | yes |
+| OpenCode | yes | yes | yes |
+| Grok CLI | yes | yes | yes |
+
+Detected but less thoroughly tested: Gemini CLI, Cursor Agent, Cline, Kimi, and GitHub Copilot CLI.
+
+Unsupported agents still run normally as terminal processes. They just may not get rich state unless you add an integration or report state over the socket API.
+
+## How detection works
+
+Herdr combines three signals:
+
+1. foreground process detection
+2. terminal output heuristics
+3. integration state reports
+
+Process detection tells Herdr which pane owns an agent. Heuristics infer state when no hook is available. Integrations provide the most precise semantic state.
+
+## State rollups
+
+The sidebar rolls state upward.
+
+A blocked agent makes its pane, tab, and workspace look blocked. A working agent makes the workspace look active. A done agent stays visible until you view it.
+
+This lets you scan many projects quickly.
+
+## Direct integrations
+
+Install integrations for agents that expose hooks or plugins:
+
+```bash
+herdr integration install pi
+herdr integration install claude
+herdr integration install codex
+herdr integration install opencode
+```
+
+Check installed integration versions:
+
+```bash
+herdr integration status
+```
+
+Show only outdated integrations:
+
+```bash
+herdr integration status --outdated-only
+```
+
+## Custom agent labels
+
+You can rename an agent target for display:
+
+```bash
+herdr agent rename 1-1 reviewer
+herdr agent rename reviewer --clear
+```
+
+Targets accept terminal IDs, unique agent names, and legacy pane IDs.
+
+## Custom status labels
+
+Integrations can report a visual status label without changing semantic state.
+
+```bash
+herdr pane report-agent 1-1 \
+ --source custom:indexer \
+ --agent docs-bot \
+ --state working \
+ --custom-status indexing
+```
+
+`state` controls waits, notifications, and rollups. `custom-status` is only display text.
+
+## Start agents from the CLI
+
+Spawn an agent into Herdr from a script:
+
+```bash
+herdr agent start reviewer --cwd ~/project --split right -- pi
+```
+
+You can target a workspace or tab:
+
+```bash
+herdr agent start tests --workspace 1 --tab 1-1 -- cargo test
+```
+
+## Attach directly to an agent
+
+Attach your current terminal to one agent terminal instead of the full Herdr UI:
+
+```bash
+herdr agent attach reviewer
+```
+
+Detach with `ctrl+b q`. Send a literal `ctrl+b` with `ctrl+b ctrl+b`.
+
+Use `--takeover` if another direct attach client already owns input:
+
+```bash
+herdr agent attach reviewer --takeover
+```
diff --git a/website/src/content/docs/cli-reference.mdx b/website/src/content/docs/cli-reference.mdx
new file mode 100644
index 00000000..7e42ebf9
--- /dev/null
+++ b/website/src/content/docs/cli-reference.mdx
@@ -0,0 +1,186 @@
+---
+title: CLI reference
+description: Herdr commands for sessions, workspaces, tabs, panes, agents, waits, integrations, and status.
+---
+
+Herdr’s CLI talks to the running server over the same local socket API used by integrations and agents.
+
+Most commands print JSON responses. Use them from scripts when you want deterministic automation.
+
+## Launch and status
+
+```bash
+herdr # launch or attach to the default session
+herdr --session work # launch or attach to a named session
+herdr --remote workbox # attach through SSH
+herdr --no-session # single-process escape hatch
+herdr --default-config # print default config
+herdr --version # print version
+```
+
+Status commands:
+
+```bash
+herdr status
+herdr status server
+herdr status client
+```
+
+## Server
+
+```bash
+herdr server stop
+herdr server reload-config
+```
+
+`reload-config` applies reloadable settings without restarting panes.
+
+## Sessions
+
+```bash
+herdr session list [--json]
+herdr session attach <name>
+herdr session stop <name> [--json]
+herdr session delete <name> [--json]
+```
+
+Use `default` as the session name when you need to stop the default session explicitly.
+
+## Workspaces
+
+```bash
+herdr workspace list
+herdr workspace create [--cwd PATH] [--label TEXT] [--focus] [--no-focus]
+herdr workspace get <workspace_id>
+herdr workspace focus <workspace_id>
+herdr workspace rename <workspace_id> <label>
+herdr workspace close <workspace_id>
+```
+
+Create a workspace without stealing focus:
+
+```bash
+herdr workspace create --cwd ~/project --label api --no-focus
+```
+
+## Tabs
+
+```bash
+herdr tab list [--workspace <workspace_id>]
+herdr tab create [--workspace <workspace_id>] [--cwd PATH] [--label TEXT] [--focus] [--no-focus]
+herdr tab get <tab_id>
+herdr tab focus <tab_id>
+herdr tab rename <tab_id> <label>
+herdr tab close <tab_id>
+```
+
+## Panes
+
+```bash
+herdr pane list [--workspace <workspace_id>]
+herdr pane get <pane_id>
+herdr pane rename <pane_id> <label>|--clear
+herdr pane split <pane_id> --direction right|down [--cwd PATH] [--focus] [--no-focus]
+herdr pane close <pane_id>
+```
+
+Read output:
+
+```bash
+herdr pane read <pane_id> [--source visible|recent|recent-unwrapped] [--lines N]
+herdr pane read <pane_id> --source visible --ansi
+herdr pane read <pane_id> --source recent-unwrapped --lines 120
+```
+
+Send input:
+
+```bash
+herdr pane send-text <pane_id> <text>
+herdr pane send-keys <pane_id> <key> [key ...]
+herdr pane run <pane_id> <command>
+```
+
+`pane run` submits text plus Enter atomically. Prefer it over `send-text` plus `send-keys Enter` for commands.
+
+Report agent state from custom hooks:
+
+```bash
+herdr pane report-agent <pane_id> \
+ --source ID \
+ --agent LABEL \
+ --state idle|working|blocked|unknown \
+ [--message TEXT] \
+ [--custom-status TEXT] \
+ [--seq N]
+```
+
+## Agents
+
+```bash
+herdr agent list
+herdr agent get <target>
+herdr agent read <target> [--source visible|recent|recent-unwrapped] [--lines N] [--format text|ansi] [--ansi]
+herdr agent send <target> <text>
+herdr agent rename <target> <name>|--clear
+herdr agent focus <target>
+herdr agent wait <target> --status <idle|working|blocked|unknown> [--timeout MS]
+herdr agent attach <target> [--takeover]
+herdr agent start <name> [--cwd PATH] [--workspace ID] [--tab ID] [--split right|down] [--focus|--no-focus] -- <argv...>
+```
+
+Targets accept terminal IDs, unique agent names, and legacy pane IDs.
+
+## Direct terminal attach
+
+```bash
+herdr terminal attach <terminal_id> [--takeover]
+```
+
+Detach from direct attach with `ctrl+b q`. Send literal `ctrl+b` with `ctrl+b ctrl+b`.
+
+## Waits
+
+Wait for output in a pane:
+
+```bash
+herdr wait output <pane_id> --match <text> [--source visible|recent|recent-unwrapped] [--lines N] [--timeout MS] [--regex] [--raw]
+```
+
+Wait for pane agent state:
+
+```bash
+herdr wait agent-status <pane_id> --status <idle|working|blocked|done|unknown> [--timeout MS]
+```
+
+Use `wait output` for normal commands and servers. Use `wait agent-status` for coding agents.
+
+## Integrations
+
+```bash
+herdr integration install pi
+herdr integration install claude
+herdr integration install codex
+herdr integration install opencode
+herdr integration uninstall pi
+herdr integration uninstall claude
+herdr integration uninstall codex
+herdr integration uninstall opencode
+herdr integration status [--outdated-only]
+```
+
+## Read sources
+
+| Source | Meaning |
+| --- | --- |
+| `visible` | Current rendered screen. Best for UI feedback loops. |
+| `recent` | Recent scrollback with terminal wrapping. |
+| `recent-unwrapped` | Recent scrollback without soft wrapping. Best for logs. |
+
+## Environment variables
+
+| Variable | Purpose |
+| --- | --- |
+| `HERDR_CONFIG_PATH` | Override the config file path. |
+| `HERDR_SESSION` | Select a named session for CLI commands. |
+| `HERDR_SOCKET_PATH` | Low-level socket path override. |
+| `HERDR_LOG` | Set log filter, for example `HERDR_LOG=herdr=debug`. |
diff --git a/website/src/content/docs/concepts.mdx b/website/src/content/docs/concepts.mdx
new file mode 100644
index 00000000..7497b3c3
--- /dev/null
+++ b/website/src/content/docs/concepts.mdx
@@ -0,0 +1,85 @@
+---
+title: Concepts
+description: Understand Herdr workspaces, tabs, panes, agents, sessions, and modes.
+---
+
+Herdr is a terminal workspace manager. It keeps real terminal processes running and adds structure around them.
+
+## Workspace
+
+A workspace is the top-level project container. Use one workspace per repo, task, or investigation.
+
+A workspace owns tabs and panes. Its sidebar state rolls up from the agents inside it, so you can see which project needs attention.
+
+## Tab
+
+A tab is a layout inside a workspace. Use tabs to separate views like `agents`, `logs`, `server`, or `review`.
+
+Tabs are addressable from the CLI and socket API.
+
+## Pane
+
+A pane is a real terminal. Herdr renders the terminal output, sends input back to the process, and preserves the pane across client detach.
+
+Panes can be split right or down. They can be renamed manually, read from the CLI, sent input, and closed.
+
+## Agent
+
+An agent is a process Herdr recognizes inside a pane. Herdr detects agents from foreground processes, screen heuristics, and optional integrations.
+
+Agent states are:
+
+| State | Meaning |
+| --- | --- |
+| `blocked` | The agent needs input, approval, or a decision. |
+| `working` | The agent is actively running. |
+| `done` | The agent finished and you have not looked at it yet. |
+| `idle` | The agent is finished or waiting and has been seen. |
+| `unknown` | Herdr cannot confidently classify the state. |
+
+## Session
+
+A session is a persistent Herdr server namespace. The default `herdr` command attaches to the default session.
+
+Named sessions are separate runtime namespaces:
+
+```bash
+herdr session list
+herdr session attach work
+herdr session attach side-project
+```
+
+Use workspaces first. Use named sessions when you need completely separate panes, sockets, and persisted runtime state.
+
+## Client and server
+
+By default, Herdr runs as a background server plus one or more attached clients.
+
+The server owns panes and process state. The client is the terminal UI attached to that server.
+
+Detach the client with `ctrl+b q`. The server and agents continue running.
+
+Stop the server when you are done:
+
+```bash
+herdr server stop
+```
+
+## Modes
+
+Herdr has terminal mode and navigate mode.
+
+Terminal mode sends keys to the focused pane. Navigate mode sends keys to Herdr.
+
+Press the prefix key, default `ctrl+b`, to enter navigate mode. Use navigate mode to create workspaces, split panes, switch tabs, resize, open menus, or detach.
+
+## 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 your terminal needs normal mouse behavior for URL clicks, disable Herdr mouse capture:
+
+```toml
+[ui]
+mouse_capture = false
+```
diff --git a/website/src/content/docs/configuration.mdx b/website/src/content/docs/configuration.mdx
new file mode 100644
index 00000000..2f639be4
--- /dev/null
+++ b/website/src/content/docs/configuration.mdx
@@ -0,0 +1,238 @@
+---
+title: Configuration
+description: Configure Herdr keybindings, themes, sidebar behavior, notifications, and advanced options.
+---
+
+Herdr works without a config file. Add one when you want custom keys, themes, sidebar settings, notifications, or advanced behavior.
+
+## Config file
+
+Herdr reads config from:
+
+```text
+~/.config/herdr/config.toml
+```
+
+Print the full default config:
+
+```bash
+herdr --default-config
+```
+
+Save it as your config if you want a complete starting point:
+
+```bash
+herdr --default-config > ~/.config/herdr/config.toml
+```
+
+If a config value is invalid, Herdr falls back to a safe default and shows a startup warning.
+
+## Reload config
+
+Reload a running server after editing `config.toml`:
+
+```bash
+herdr server reload-config
+```
+
+You can also open the global menu in Herdr and choose `reload config`.
+
+Reload applies most UI settings without restarting panes. Startup-only settings still need a restart.
+
+## Keybindings
+
+Herdr has a prefix mode similar to tmux. The default prefix is `ctrl+b`.
+
+A small keybinding override looks like this:
+
+```toml
+[keys]
+prefix = "ctrl+b"
+new_workspace = "n"
+rename_workspace = "shift+n"
+close_workspace = "shift+d"
+new_tab = "c"
+split_vertical = "v"
+split_horizontal = "-"
+close_pane = "x"
+zoom = "f"
+resize_mode = "r"
+toggle_sidebar = "b"
+```
+
+Optional actions are unset by default. Bind them when you want direct shortcuts:
+
+```toml
+[keys]
+detach = "q"
+reload_config = "R"
+open_notification_target = "o"
+previous_workspace = "H"
+next_workspace = "L"
+previous_tab = "J"
+next_tab = "K"
+rename_pane = "p"
+edit_scrollback = "e"
+focus_pane_left = "h"
+focus_pane_down = "j"
+focus_pane_up = "k"
+focus_pane_right = "l"
+```
+
+Use the full default config to see every available action.
+
+## Indexed jumps
+
+Indexed keybindings let you jump directly to visible positions.
+
+```toml
+[keys.indexed]
+workspaces = "ctrl+shift"
+tabs = "ctrl"
+agents = "alt"
+```
+
+These expand over number keys 1 through 9. For example, `tabs = "ctrl"` makes `ctrl+1` through `ctrl+9` switch tabs.
+
+## Custom command keybindings
+
+Custom prefix-mode commands can run shell helpers from inside Herdr.
+
+```toml
+[[keys.command]]
+key = "g"
+type = "pane"
+command = "lazygit"
+```
+
+`type = "pane"` opens a temporary pane and closes it when the command exits.
+
+`type = "shell"` runs detached in the background.
+
+## Theme
+
+Choose a built-in theme:
+
+```toml
+[theme]
+name = "catppuccin"
+```
+
+Built-in themes:
+
+`catppuccin`, `catppuccin-latte`, `tokyo-night`, `tokyo-night-day`, `dracula`, `nord`, `gruvbox`, `gruvbox-light`, `one-dark`, `one-light`, `solarized`, `solarized-light`, `kanagawa`, `kanagawa-lotus`, `rose-pine`, `rose-pine-dawn`, `vesper`.
+
+You can override individual colors:
+
+```toml
+[theme.custom]
+panel_bg = "reset"
+accent = "#a6e3a1"
+green = "#a6e3a1"
+blue = "#89b4fa"
+red = "#f38ba8"
+yellow = "#f9e2af"
+```
+
+Color values accept hex, named colors, `rgb(r,g,b)`, or reset aliases like `reset`, `default`, `none`, and `transparent`.
+
+## UI and sidebar
+
+The sidebar is the main Herdr dashboard. It shows workspaces, tabs, panes, and agent state.
+
+Common options:
+
+```toml
+[ui]
+sidebar_width = 32
+mouse_capture = true
+confirm_close = true
+prompt_new_tab_name = true
+show_agent_labels_on_pane_borders = false
+agent_panel_scope = "all"
+accent = "cyan"
+```
+
+`agent_panel_scope` can be `all` or `current`. Use `current` if you only want the agent panel to show agents in the active workspace.
+
+Set `mouse_capture = false` if you want your terminal to handle normal clicks, such as command-clicking URLs.
+
+Set `show_agent_labels_on_pane_borders = true` if you want detected agent labels in split pane borders when no manual pane label is set.
+
+## Notifications
+
+Herdr can show toast notifications when agents finish or need input.
+
+```toml
+[ui.toast]
+delivery = "auto"
+```
+
+On macOS, Herdr can use system notifications when supported by the foreground client.
+
+## Sound
+
+Sound is optional and server-owned.
+
+```toml
+[ui.sound]
+enabled = false
+```
+
+Keep sound off on shared machines or remote servers unless you explicitly want it.
+
+## Scrollback
+
+Set the scrollback buffer size for newly created panes:
+
+```toml
+[advanced]
+scrollback_limit_bytes = 10485760
+```
+
+Existing panes keep their current buffer until they are recreated.
+
+## Nested launches
+
+Herdr normally protects you from launching Herdr inside Herdr.
+
+```toml
+[experimental]
+allow_nested = false
+```
+
+Only enable nested launches for testing.
+
+## Kitty graphics
+
+Kitty graphics support is experimental.
+
+```toml
+[experimental]
+kitty_graphics = false
+```
+
+Leave this off unless you are testing terminal image behavior.
+
+## Environment variables
+
+| Variable | Purpose |
+| --- | --- |
+| `HERDR_CONFIG_PATH` | Override the config file path. |
+| `HERDR_SESSION` | Select a named session for CLI commands. |
+| `HERDR_SOCKET_PATH` | Low-level socket path override. |
+| `HERDR_LOG` | Set log filtering, for example `HERDR_LOG=herdr=debug`. |
+
+## Logs
+
+Logs are useful when diagnosing startup warnings, integration state, or socket API behavior.
+
+Common log files:
+
+```text
+~/.config/herdr/herdr.log
+~/.config/herdr/herdr-client.log
+~/.config/herdr/herdr-server.log
+```
+
+Logs rotate automatically. Include the current log and rotated siblings when reporting issues.
diff --git a/website/src/content/docs/index.mdx b/website/src/content/docs/index.mdx
new file mode 100644
index 00000000..2e7ecd5e
--- /dev/null
+++ b/website/src/content/docs/index.mdx
@@ -0,0 +1,104 @@
+---
+title: Herdr documentation
+description: Terminal multiplexer for AI coding agents.
+template: splash
+hero:
+ tagline: Run agents in real terminal panes, keep sessions alive, attach over SSH, and orchestrate everything from the CLI or socket API.
+ image:
+ file: ../../../public/assets/logo.png
+ actions:
+ - text: Install Herdr
+ link: /docs/install/
+ - text: Quick start
+ link: /docs/quick-start/
+ variant: secondary
+---
+
+import { Card, CardGrid } from '@astrojs/starlight/components';
+
+Herdr is a terminal-native agent multiplexer. It gives AI coding agents persistent terminal workspaces with panes, tabs, mouse control, state awareness, and an API that agents can use themselves.
+
+```bash
+curl -fsSL https://herdr.dev/install.sh | sh
+herdr
+```
+
+## Core model
+
+<CardGrid>
+ <Card title="Detach and reattach">
+ Herdr runs panes in a background session server, so agents keep running after the UI client detaches.
+
+ [Use persistence →](/docs/persistence-remote/)
+ </Card>
+ <Card title="Attach over SSH">
+ Run Herdr where the code and credentials live. Attach from any SSH client or use `herdr --remote` from your local terminal.
+
+ [Use remote access →](/docs/persistence-remote/#remote-attach-over-ssh)
+ </Card>
+ <Card title="Real terminal panes">
+ Every pane is a real terminal. Split layouts, click panes, drag borders, select text, and use right-click menus.
+
+ [Learn concepts →](/docs/concepts/)
+ </Card>
+ <Card title="State and orchestration">
+ See agent status in the sidebar and drive workspaces, tabs, panes, waits, and output reads through the CLI or socket API.
+
+ [Read the API guide →](/docs/socket-api/)
+ </Card>
+</CardGrid>
+
+## Start here
+
+<CardGrid>
+ <Card title="Install">
+ Install Herdr on Linux or macOS, update it later, and verify the binary.
+
+ [Install Herdr →](/docs/install/)
+ </Card>
+ <Card title="Quick start">
+ Create your first workspace, run agents in panes, split the layout, and detach safely.
+
+ [Start using Herdr →](/docs/quick-start/)
+ </Card>
+ <Card title="Concepts">
+ Understand workspaces, tabs, panes, agents, sessions, modes, and state rollups.
+
+ [Learn the model →](/docs/concepts/)
+ </Card>
+</CardGrid>
+
+## Guides and reference
+
+<CardGrid>
+ <Card title="Agents">
+ See supported agents, detection behavior, integrations, custom labels, and direct attach.
+
+ [Understand agents →](/docs/agents/)
+ </Card>
+ <Card title="Configuration">
+ Configure keybindings, themes, sidebar behavior, notifications, scrollback, and advanced options.
+
+ [Configure Herdr →](/docs/configuration/)
+ </Card>
+ <Card title="Integrations">
+ Install agent integrations for Pi, Claude Code, Codex, and OpenCode.
+
+ [Set up integrations →](/docs/integrations/)
+ </Card>
+ <Card title="CLI reference">
+ Use every Herdr command for sessions, workspaces, tabs, panes, agents, waits, and integrations.
+
+ [Browse commands →](/docs/cli-reference/)
+ </Card>
+ <Card title="Socket API">
+ Control Herdr from scripts, tools, and agents through the local socket API.
+
+ [Read the API guide →](/docs/socket-api/)
+ </Card>
+ <Card title="Agent skill">
+ Teach an agent running inside Herdr how to create panes, read output, and wait for neighboring agents.
+
+ [Use the skill →](/docs/agent-skill/)
+ </Card>
+</CardGrid>
diff --git a/website/src/content/docs/install.mdx b/website/src/content/docs/install.mdx
new file mode 100644
index 00000000..dda2dc27
--- /dev/null
+++ b/website/src/content/docs/install.mdx
@@ -0,0 +1,58 @@
+---
+title: Install Herdr
+description: Install, update, and verify Herdr on Linux and macOS.
+---
+
+Herdr ships as a single binary for Linux and macOS.
+
+## Install
+
+Run the installer:
+
+```bash
+curl -fsSL https://herdr.dev/install.sh | sh
+```
+
+The installer downloads the right release binary for your platform and places it on your PATH.
+
+## 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
+```
+
+## Download manually
+
+You can also download a binary from [GitHub releases](https://github.com/ogulcancelik/herdr/releases).
+
+Choose the asset that matches your system:
+
+| System | Asset |
+| --- | --- |
+| Linux x86_64 | `herdr-linux-x86_64` |
+| Linux aarch64 | `herdr-linux-aarch64` |
+| macOS Intel | `herdr-macos-x86_64` |
+| macOS Apple silicon | `herdr-macos-aarch64` |
+
+Make it executable and move it somewhere on your PATH.
+
+```bash
+chmod +x herdr-linux-x86_64
+mv herdr-linux-x86_64 ~/.local/bin/herdr
+```
+
+## Requirements
+
+Herdr supports Linux and macOS. Native Windows support is not available yet; use Herdr inside WSL for now.
diff --git a/website/src/content/docs/integrations.mdx b/website/src/content/docs/integrations.mdx
new file mode 100644
index 00000000..4af83c30
--- /dev/null
+++ b/website/src/content/docs/integrations.mdx
@@ -0,0 +1,116 @@
+---
+title: Integrations
+description: Install Herdr integrations for Pi, Claude Code, Codex, and OpenCode.
+---
+
+Herdr detects supported agents automatically. Integrations make that detection more precise by reporting semantic state directly to Herdr.
+
+Use integrations when you want reliable `working`, `blocked`, `idle`, and `done` state from agent hooks or plugins.
+
+## Install integrations
+
+```bash
+herdr integration install pi
+herdr integration install claude
+herdr integration install codex
+herdr integration install opencode
+```
+
+## Uninstall integrations
+
+```bash
+herdr integration uninstall pi
+herdr integration uninstall claude
+herdr integration uninstall codex
+herdr integration uninstall opencode
+```
+
+## How Herdr uses integrations
+
+Herdr combines three signals:
+
+| Signal | Purpose |
+| --- | --- |
+| Process detection | Identifies which pane owns which running process. |
+| Agent integration events | Reports semantic state such as `working` or `blocked`. |
+| Screen heuristics | Fills gaps when hooks are unavailable or incomplete. |
+
+Integrations enrich state reporting. They do not replace process detection.
+
+## Pi
+
+Install the Pi integration:
+
+```bash
+herdr integration install pi
+```
+
+Herdr writes the bundled extension to:
+
+```text
+~/.pi/agent/extensions/herdr-agent-state.ts
+```
+
+If `PI_CODING_AGENT_DIR` is set, Herdr writes to that agent directory instead.
+
+## Claude Code
+
+Install the Claude Code hook:
+
+```bash
+herdr integration install claude
+```
+
+The hook reports agent state to the local Herdr socket when Claude Code exposes hook events.
+
+## Codex
+
+Install the Codex hook:
+
+```bash
+herdr integration install codex
+```
+
+Codex state is reported through the same local socket API used by other integrations.
+
+## OpenCode
+
+Install the OpenCode plugin:
+
+```bash
+herdr integration install opencode
+```
+
+The plugin reports semantic state while OpenCode runs inside a Herdr pane.
+
+## Custom status labels
+
+Integrations can report a short visual label without changing the semantic state.
+
+For example, an agent can remain semantically `working` while showing `indexing` in the UI.
+
+```bash
+herdr pane report-agent 1-1 \
+ --source custom:docs \
+ --agent docs-bot \
+ --state working \
+ --custom-status indexing
+```
+
+Custom status is visual-only. Waits, notifications, and workspace rollups still use the semantic state.
+
+## Debug integration state
+
+List known agents:
+
+```bash
+herdr agent list
+```
+
+Read a pane when you need to verify what Herdr can see:
+
+```bash
+herdr pane read 1-1 --source recent --lines 50
+```
+
+If integration state looks wrong, first confirm the agent is running inside Herdr and that the relevant hook or plugin was installed for the same user account.
diff --git a/website/src/content/docs/persistence-remote.mdx b/website/src/content/docs/persistence-remote.mdx
new file mode 100644
index 00000000..2c157b4e
--- /dev/null
+++ b/website/src/content/docs/persistence-remote.mdx
@@ -0,0 +1,125 @@
+---
+title: Persistence and remote access
+description: Detach from Herdr, reattach later, use named sessions, and connect over SSH.
+---
+
+Herdr keeps panes running in a background server. Your terminal client can detach and reconnect later.
+
+## 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
+```
+
+Stop the default server when you want to end the session:
+
+```bash
+herdr server stop
+```
+
+## Named sessions
+
+Use named sessions when you want independent Herdr servers.
+
+```bash
+herdr session list
+herdr session attach work
+herdr session attach side-project
+herdr session stop work
+herdr session delete side-project
+```
+
+A named session has its own panes, tabs, workspaces, sockets, and runtime state. It still shares the same global config file.
+
+Use `--json` for scripts:
+
+```bash
+herdr session list --json
+herdr session stop work --json
+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
+```
+
+You can also attach through SSH from your local machine:
+
+```bash
+herdr --remote workbox
+herdr --remote ssh://you@server:2222
+```
+
+For repeat targets, use your SSH config:
+
+```text
+Host workbox
+ HostName server.example.com
+ User you
+ Port 2222
+```
+
+Then attach with:
+
+```bash
+herdr --remote workbox
+```
+
+## Remote named sessions
+
+Use `--session` with `--remote` to attach to a named session on the remote host:
+
+```bash
+herdr --remote workbox --session agents
+```
+
+## Direct terminal attach
+
+Full Herdr attach opens the whole workspace UI. Direct attach opens one server-owned terminal in your current terminal.
+
+Attach by agent target:
+
+```bash
+herdr agent attach reviewer
+```
+
+Attach by terminal ID:
+
+```bash
+herdr terminal attach term_abc123
+```
+
+Direct attach streams the current rendered terminal state, then live ANSI frames. Input goes straight to that terminal.
+
+Detach with `ctrl+b q`. Send a literal `ctrl+b` with `ctrl+b ctrl+b`.
+
+Only one writable direct attach client owns input and resize for a terminal. Use `--takeover` to replace an existing owner:
+
+```bash
+herdr terminal attach term_abc123 --takeover
+```
+
+## Single-process escape hatch
+
+Use `--no-session` to run Herdr without the background server/client split:
+
+```bash
+herdr --no-session
+```
+
+This is mainly an escape hatch for debugging or compatibility. The default persistent session mode is the normal path.
diff --git a/website/src/content/docs/quick-start.mdx b/website/src/content/docs/quick-start.mdx
new file mode 100644
index 00000000..08d815f3
--- /dev/null
+++ b/website/src/content/docs/quick-start.mdx
@@ -0,0 +1,80 @@
+---
+title: Quick start
+description: Create your first Herdr workspace and run agents in persistent terminal panes.
+---
+
+Start Herdr from any project directory:
+
+```bash
+herdr
+```
+
+Herdr launches or attaches to your default background session. If you detach, agents keep running.
+
+## Create a workspace
+
+Press `n` to create a workspace. 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.
+
+## Run an agent
+
+Start your agent in the root pane.
+
+```bash
+pi
+```
+
+Herdr detects supported agents automatically. The sidebar shows whether each agent is `working`, `blocked`, `done`, or `idle`.
+
+## Navigate
+
+Press `ctrl+b` to enter navigate mode.
+
+Common actions:
+
+| Action | Key |
+| --- | --- |
+| Split right | `v` |
+| Split down | `-` |
+| New tab | `c` |
+| New workspace | `n` |
+| Detach client | `q` |
+
+After detaching, run `herdr` again to reattach to the same session.
+
+## Use the mouse
+
+Herdr is mouse-native. You can click panes, tabs, workspaces, and agents; drag borders; select text; and use right-click menus.
+
+## 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
+
+Start Herdr on a server, detach, and come back over SSH later.
+
+```bash
+ssh you@server
+herdr
+```
+
+You can also attach through SSH from your local terminal:
+
+```bash
+herdr --remote workbox
+herdr --remote ssh://you@server:2222
+```
+
+For repeat targets, put the host in your SSH config.
diff --git a/website/src/content/docs/socket-api.mdx b/website/src/content/docs/socket-api.mdx
new file mode 100644
index 00000000..c4de1b3d
--- /dev/null
+++ b/website/src/content/docs/socket-api.mdx
@@ -0,0 +1,224 @@
+---
+title: Socket API
+description: Control a running Herdr server from scripts, tools, and coding agents.
+---
+
+Herdr exposes a local socket API for scripts and agents that need to inspect or control a running session.
+
+Most automation should start with the CLI wrappers. Use the raw socket API only when you need direct request/response control or long-lived event subscriptions.
+
+## Choose an integration layer
+
+| Layer | Use it for |
+| --- | --- |
+| Agent skill | Teaching a coding agent how to use Herdr from inside a pane. |
+| CLI wrappers | Shell scripts, simple orchestration, and human debugging. |
+| Raw socket API | Custom tools, protocol clients, and event subscribers. |
+
+The layers share the same control surface.
+
+## What you can control
+
+The socket API can:
+
+- create, list, focus, rename, and close workspaces
+- create, list, focus, rename, and close tabs
+- list, inspect, split, rename, read, close, and send input to panes
+- list, inspect, read, send to, rename, focus, start, and attach agents through CLI helpers
+- report custom agent state from hooks and plugins
+- subscribe to events and wait for output or state changes
+- install and uninstall built-in integrations
+- stop the server and reload config
+
+## CLI examples
+
+Create a workspace:
+
+```bash
+herdr workspace create --cwd ~/project --label api
+```
+
+Create a tab:
+
+```bash
+herdr tab create --label logs
+```
+
+Split a pane and run a command:
+
+```bash
+herdr pane split 1-1 --direction right
+herdr pane run 1-2 "npm test"
+```
+
+Wait for an agent:
+
+```bash
+herdr wait agent-status 1-1 --status done
+```
+
+Read pane output:
+
+```bash
+herdr pane read 1-2 --source recent --lines 50
+```
+
+## Raw methods
+
+Raw socket method names use dot notation:
+
+| Area | Methods |
+| --- | --- |
+| Server | `ping`, `server.stop`, `server.reload_config` |
+| Workspace | `workspace.create`, `workspace.list`, `workspace.get`, `workspace.focus`, `workspace.rename`, `workspace.close` |
+| Tab | `tab.create`, `tab.list`, `tab.get`, `tab.focus`, `tab.rename`, `tab.close` |
+| Pane | `pane.split`, `pane.list`, `pane.get`, `pane.rename`, `pane.send_text`, `pane.send_keys`, `pane.send_input`, `pane.read`, `pane.report_agent`, `pane.clear_agent_authority`, `pane.release_agent`, `pane.close`, `pane.wait_for_output` |
+| Agent | `agent.list`, `agent.get`, `agent.read`, `agent.send`, `agent.rename`, `agent.focus`, `agent.start` |
+| Events | `events.subscribe`, `events.wait` |
+| Integrations | `integration.install`, `integration.uninstall` |
+
+Some CLI commands are conveniences around these methods. For example, `herdr agent wait` resolves an agent target and then subscribes to pane agent state events.
+
+## Socket transport
+
+Herdr uses newline-delimited JSON over a Unix domain socket.
+
+Send one request per line:
+
+```json
+{"id":"req_1","method":"ping","params":{}}
+```
+
+A successful response includes the same `id`:
+
+```json
+{"id":"req_1","result":{"type":"pong"}}
+```
+
+Event subscriptions keep the connection open after the initial response.
+
+## Socket paths
+
+The default socket lives under your Herdr config directory.
+
+Named sessions have separate sockets:
+
+```text
+~/.config/herdr/herdr.sock
+~/.config/herdr/sessions/<name>/herdr.sock
+```
+
+Resolution order:
+
+1. explicit CLI `--session <name>`
+2. `HERDR_SOCKET_PATH`
+3. `HERDR_SESSION=<name>`
+4. default session socket
+
+Use `HERDR_SOCKET_PATH` only for low-level overrides.
+
+## Agent state reporting
+
+Integrations report agent state with `pane.report_agent`.
+
+```json
+{
+ "id": "req_1",
+ "method": "pane.report_agent",
+ "params": {
+ "pane_id": "1-1",
+ "source": "custom:docs",
+ "agent": "docs-bot",
+ "state": "working",
+ "message": "building docs",
+ "custom_status": "indexing"
+ }
+}
+```
+
+`state` is semantic. It affects waits, notifications, and rollups.
+
+`custom_status` is visual. It can show a short label like `indexing` without changing semantic behavior.
+
+## Event subscriptions
+
+Subscribe to events when you need a long-lived stream:
+
+```json
+{
+ "id": "sub_1",
+ "method": "events.subscribe",
+ "params": {
+ "subscriptions": [
+ { "type": "pane.agent_status_changed", "pane_id": "1-1", "agent_status": "blocked" }
+ ]
+ }
+}
+```
+
+The first response acknowledges the subscription. Later lines are pushed events.
+
+Use `events.wait` when you want one matching event and then a response.
+
+## Reading panes
+
+Use `pane.read` through the CLI unless you are writing a protocol client.
+
+```bash
+herdr pane read 1-1 --source visible --lines 80
+herdr pane read 1-1 --source recent --lines 120
+herdr pane read 1-1 --source recent-unwrapped --lines 120
+```
+
+`recent-unwrapped` is useful for logs because it ignores soft wrapping.
+
+## Waiting for state
+
+Use waits to coordinate agents and scripts.
+
+```bash
+herdr wait agent-status 1-1 --status done
+herdr wait agent-status 1-1 --status blocked
+```
+
+Agent waits observe semantic state, not arbitrary command completion.
+
+## Response shapes
+
+Successful responses look like this:
+
+```json
+{
+ "id": "req_1",
+ "result": {
+ "type": "pane_info",
+ "pane": {
+ "pane_id": "1-1",
+ "terminal_id": "term_abc123",
+ "workspace_id": "1",
+ "tab_id": "1-1",
+ "focused": true,
+ "agent_status": "working",
+ "revision": 42
+ }
+ }
+}
+```
+
+Errors look like this:
+
+```json
+{
+ "id": "req_1",
+ "error": {
+ "code": "not_found",
+ "message": "pane not found"
+ }
+}
+```
+
+## Protocol stability
+
+Herdr has a protocol version for client/server compatibility. Protocol changes are reviewed with release compatibility in mind.
+
+Check the server protocol with `ping` or `herdr status` before depending on new behavior. Handle unknown fields gracefully.
diff --git a/website/src/pages/index.astro b/website/src/pages/index.astro
new file mode 100644
index 00000000..e46ccbe6
--- /dev/null
+++ b/website/src/pages/index.astro
@@ -0,0 +1,7 @@
+---
+import { readFile } from 'node:fs/promises';
+
+const homepage = await readFile(new URL('../../index.html', import.meta.url), 'utf8');
+---
+
+<Fragment set:html={homepage} />
diff --git a/website/src/styles/starlight.css b/website/src/styles/starlight.css
new file mode 100644
index 00000000..4287d510
--- /dev/null
+++ b/website/src/styles/starlight.css
@@ -0,0 +1,162 @@
+@font-face {
+ font-family: "JetBrains Mono";
+ font-style: normal;
+ font-weight: 400 700;
+ font-display: swap;
+ src: url("/assets/jbm.woff2") format("woff2");
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC,
+ U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F,
+ U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+
+:root {
+ --sl-font: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
+ --sl-font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
+ --sl-content-width: 54rem;
+ --sl-sidebar-width: 18.5rem;
+ --sl-color-accent-low: #123c37;
+ --sl-color-accent: #42cabb;
+ --sl-color-accent-high: #d9fff8;
+ --sl-color-white: #f8fbff;
+ --sl-color-gray-1: #e8edf2;
+ --sl-color-gray-2: #c7d0d9;
+ --sl-color-gray-3: #93a0ad;
+ --sl-color-gray-4: #62707f;
+ --sl-color-gray-5: #34404c;
+ --sl-color-gray-6: #202833;
+ --sl-color-black: #10151c;
+ --sl-color-bg: #10151c;
+ --sl-color-bg-nav: #151b23;
+ --sl-color-bg-sidebar: #151b23;
+ --sl-color-bg-inline-code: #202833;
+ --sl-color-hairline: #25303b;
+ --sl-color-hairline-light: #34404c;
+}
+
+:root[data-theme="light"] {
+ --sl-color-accent-low: #d7f1ed;
+ --sl-color-accent: #1f6f68;
+ --sl-color-accent-high: #0f3f3b;
+ --sl-color-white: #151a21;
+ --sl-color-gray-1: #26313c;
+ --sl-color-gray-2: #40505d;
+ --sl-color-gray-3: #687381;
+ --sl-color-gray-4: #8d989f;
+ --sl-color-gray-5: #d4cabd;
+ --sl-color-gray-6: #eee7dc;
+ --sl-color-gray-7: #f7f3ea;
+ --sl-color-black: #fffdf8;
+ --sl-color-bg: #f7f3ea;
+ --sl-color-bg-nav: #fffdf8;
+ --sl-color-bg-sidebar: #fffdf8;
+ --sl-color-bg-inline-code: #eee7dc;
+ --sl-color-hairline: #ded6c8;
+ --sl-color-hairline-light: #c9bdad;
+}
+
+.site-title {
+ font-family: var(--sl-font-mono);
+ font-weight: 800;
+ letter-spacing: -0.04em;
+}
+
+.sl-markdown-content {
+ font-size: 1rem;
+ line-height: 1.75;
+}
+
+.sl-markdown-content h1,
+.hero h1 {
+ letter-spacing: -0.055em;
+ line-height: 0.98;
+ font-size: clamp(2.4rem, 5vw, 4.2rem);
+}
+
+.sl-markdown-content h2 {
+ margin-top: 2.6rem;
+ letter-spacing: -0.035em;
+}
+
+.sl-markdown-content h3 {
+ letter-spacing: -0.025em;
+}
+
+.sl-markdown-content > p:first-child {
+ font-size: 1.08rem;
+ color: var(--sl-color-gray-1);
+}
+
+.header a[href="/"]::after {
+ content: "home";
+ margin-left: 0.75rem;
+ color: var(--sl-color-gray-3);
+ font-size: 0.8rem;
+ font-weight: 500;
+}
+
+#starlight__sidebar a[aria-current="page"] {
+ background: color-mix(in srgb, var(--sl-color-accent) 13%, transparent);
+ color: var(--sl-color-accent-high);
+ box-shadow: inset 2px 0 0 var(--sl-color-accent);
+}
+
+:root[data-theme="light"] #starlight__sidebar a[aria-current="page"] {
+ color: var(--sl-color-accent-high);
+}
+
+.sl-markdown-content a:not(:where(.not-content *)) {
+ text-decoration-thickness: 1px;
+ text-underline-offset: 0.18em;
+}
+
+.sl-markdown-content code:not(:where(.not-content *)) {
+ border: 1px solid var(--sl-color-hairline);
+ border-radius: 0.35rem;
+ font-size: 0.88em;
+}
+
+.sl-markdown-content pre {
+ border: 1px solid var(--sl-color-hairline);
+ border-radius: 0.85rem;
+}
+
+.expressive-code {
+ margin: 1rem 0 1.35rem;
+}
+
+.expressive-code .frame {
+ border: 1px solid var(--sl-color-hairline) !important;
+ border-radius: 0.85rem !important;
+ box-shadow: none !important;
+ overflow: hidden;
+}
+
+.expressive-code .frame.is-terminal .header {
+ display: none;
+}
+
+.expressive-code .frame pre {
+ border: 0 !important;
+ border-radius: 0 !important;
+}
+
+.expressive-code .frame.has-title:not(.is-terminal) .header {
+ background: var(--sl-color-bg-nav) !important;
+ border-color: var(--sl-color-hairline) !important;
+}
+
+.sl-markdown-content .card {
+ border-color: var(--sl-color-hairline);
+ background:
+ linear-gradient(180deg, color-mix(in srgb, var(--sl-color-accent) 5%, transparent), transparent 58%),
+ var(--sl-color-black);
+}
+
+.sl-markdown-content .card .title {
+ color: var(--sl-color-white);
+}
+
+.hero img {
+ image-rendering: auto;
+ filter: drop-shadow(0 20px 50px rgb(31 111 104 / 0.18));
+}