Merge branch 'master' into akbash/1435-cli-protocol-guard

This commit is contained in:
Can Celik
2026-07-15 22:45:50 +03:00
committed by GitHub
41 changed files with 1208 additions and 1135 deletions
+41
View File
@@ -2,6 +2,47 @@
## Unreleased
## [0.7.4] - 2026-07-15
### Added
- Added session-modal popup floating terminal panes for `type = "popup"` custom command keybindings and plugin panes, with optional cell or percentage sizing and no changes to the tiled tab layout. (#1125)
- Added `ui.copy_on_select` to disable automatic clipboard copying after mouse selection while keeping the selection visible.
- Added configurable row layouts for expanded Space and Agent sidebar entries, including built-in display tokens, per-agent overrides, custom metadata tokens, and pane/workspace metadata reporting through the CLI and socket API.
- Added independent `row_gap` settings for expanded Space and Agent sidebar entries.
- Copy mode now supports literal smart-case search with `/` and `?`, repeating with `n` and `N`, match highlighting, and tmux-style cross-line `w`/`b`/`e` word motions. (#1230)
- Added Maki agent support. (#1301, #1302, thanks @tontinton)
- Added a searchable, version-matched configuration reference and a troubleshooting guide covering duplicate terminal key events, modified-arrow shell bindings, updates, remote access, and logs. (#1116, #1370)
### Changed
- Expanded Space and Agent sidebar entries now use a packed layout by default; set the corresponding `row_gap` to `1` to restore the previous spacing.
- Refreshed the bundled Herdr agent skill for current public workspace, tab, and pane ids and the current CLI/API workflow. (#1297)
- Expanded Japanese and Simplified Chinese CLI documentation with shell completion setup and API schema usage. (#1151)
### Fixed
- Collapsed Agent sidebar rows now follow the same ordering and click targets as the expanded panel, and their shortcut numbers are assigned by visible list position instead of repeating across workspaces. (#1168, #1344)
- Shifted indexed bindings such as `prefix+shift+1..9` now match terminals that report the corresponding punctuation characters. (#1184)
- Plugin-driven tab renames now immediately refresh tab-bar geometry and labels. (#1111, #1179, thanks @kovalov)
- New tabs, splits, layouts, and workspaces configured to follow the foreground directory now start from the focused pane's current working directory. (#1245)
- Amp, Codex, and Claude Code detection now recognizes current active-turn UI variants, including reordered Codex title spinners and Claude `/btw` turns. (#1208, #1281, #1366)
- Pi lifecycle state now reanchors after native session replacement, avoiding working panes that remain idle or tied to an abandoned session. (#943, #1189, thanks @dmmulroy)
- OMP lifecycle reports are now retried when startup races drop the first report. (#1310)
- WSL now uses Herdr's drawn cursor by default, matching the native Windows workaround for host cursor flicker. (#930)
- Live handoff now preserves explicit named-session socket paths, waits for slower server shutdowns, and flushes API responses before the old server exits. (#1180, thanks @dvic)
- The Windows installer no longer rewrites an existing config file or creates a duplicate onboarding line during first-run setup. (#1162)
- Config diagnostics now reach CLI-only and attached-client startup paths reliably and clearly identify fallback configuration behavior.
- Detached custom command children are now reaped after exit instead of accumulating zombie processes. (#1360)
- Renamed single tabs now remain visible in the Agents sidebar instead of losing their tab label. (#1369)
- Documentation search results are now scoped to the active locale and stable or preview channel.
- Horizontal wheel and trackpad events now reach pane applications that enable mouse reporting. (#1349)
- Copy mode `$` and End now stop at the final visible character on the row instead of jumping to the pane edge. (#1405)
- Split SGR mouse reports are now reassembled across input reads, and a preceding standalone Escape is preserved instead of being swallowed or leaked as mouse bytes. (#1334, #1382)
- Linux foreground-process discovery now stays within Herdr pane process trees instead of scanning unrelated host processes, reducing CPU use on busy multi-user systems. (#1399)
- Single-codepoint emoji chosen from the Windows emoji picker now reach panes when WezTerm's kitty keyboard support sends them as CSI-u events with associated text. (#1404)
- Outer-terminal focus gained and lost reports now reach the focused pane when its application enables focus reporting, restoring Neovim file autoreload and other focus-aware terminal behavior. (#1337)
- Native Windows servers now detach from the terminal console that launched them, so closing WezTerm, Windows Terminal, or another host terminal no longer stops persistent pane processes. (#1329)
- Windows API clients now remain connected while waiting for initial named-pipe request bytes, so `status server`, `api snapshot`, and other socket commands no longer intermittently fail with BrokenPipe. (#1279)
- `herdr --remote` now installs remote helper binaries without routing the binary stream through a multiline `/bin/sh -c` command, fixing installs for non-POSIX login shells such as xonsh. (#1203, thanks @nhumrich)
## [0.7.3] - 2026-07-08
### Fixed
Generated
+1 -1
View File
@@ -583,7 +583,7 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "herdr"
version = "0.7.3"
version = "0.7.4"
dependencies = [
"base64",
"bincode",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "herdr"
version = "0.7.3"
version = "0.7.4"
edition = "2021"
build = "build.rs"
description = "terminal workspace manager for AI coding agents"
+29 -4
View File
@@ -2,15 +2,41 @@
## Unreleased
## [0.7.4] - 2026-07-15
### Added
- Added independent `row_gap` settings for expanded Space and Agent sidebar entries. (#873)
- Added session-modal popup floating terminal panes for `type = "popup"` custom command keybindings and plugin panes, with optional cell or percentage sizing and no changes to the tiled tab layout. (#1125)
- Added `ui.copy_on_select` to disable automatic clipboard copying after mouse selection while keeping the selection visible.
- Added configurable row layouts for expanded Space and Agent sidebar entries, including built-in display tokens, per-agent overrides, custom metadata tokens, and pane/workspace metadata reporting through the CLI and socket API.
- Added independent `row_gap` settings for expanded Space and Agent sidebar entries.
- Copy mode now supports literal smart-case search with `/` and `?`, repeating with `n` and `N`, match highlighting, and tmux-style cross-line `w`/`b`/`e` word motions. (#1230)
- Added maki detection with idle, working, and blocked screen states. (#1301, thanks @tontinton)
- Added Maki agent support. (#1301, #1302, thanks @tontinton)
- Added a searchable, version-matched configuration reference and a troubleshooting guide covering duplicate terminal key events, modified-arrow shell bindings, updates, remote access, and logs. (#1116, #1370)
### Changed
- Expanded Space and Agent sidebar entries now use a packed layout by default; set the corresponding `row_gap` to `1` to restore the previous spacing. (#873)
- Expanded Space and Agent sidebar entries now use a packed layout by default; set the corresponding `row_gap` to `1` to restore the previous spacing.
- Refreshed the bundled Herdr agent skill for current public workspace, tab, and pane ids and the current CLI/API workflow. (#1297)
- Expanded Japanese and Simplified Chinese CLI documentation with shell completion setup and API schema usage. (#1151)
### Fixed
- Collapsed Agent sidebar rows now follow the same ordering and click targets as the expanded panel, and their shortcut numbers are assigned by visible list position instead of repeating across workspaces. (#1168, #1344)
- Shifted indexed bindings such as `prefix+shift+1..9` now match terminals that report the corresponding punctuation characters. (#1184)
- Plugin-driven tab renames now immediately refresh tab-bar geometry and labels. (#1111, #1179, thanks @kovalov)
- New tabs, splits, layouts, and workspaces configured to follow the foreground directory now start from the focused pane's current working directory. (#1245)
- Amp, Codex, and Claude Code detection now recognizes current active-turn UI variants, including reordered Codex title spinners and Claude `/btw` turns. (#1208, #1281, #1366)
- Pi lifecycle state now reanchors after native session replacement, avoiding working panes that remain idle or tied to an abandoned session. (#943, #1189, thanks @dmmulroy)
- OMP lifecycle reports are now retried when startup races drop the first report. (#1310)
- WSL now uses Herdr's drawn cursor by default, matching the native Windows workaround for host cursor flicker. (#930)
- Live handoff now preserves explicit named-session socket paths, waits for slower server shutdowns, and flushes API responses before the old server exits. (#1180, thanks @dvic)
- The Windows installer no longer rewrites an existing config file or creates a duplicate onboarding line during first-run setup. (#1162)
- Config diagnostics now reach CLI-only and attached-client startup paths reliably and clearly identify fallback configuration behavior.
- Detached custom command children are now reaped after exit instead of accumulating zombie processes. (#1360)
- Renamed single tabs now remain visible in the Agents sidebar instead of losing their tab label. (#1369)
- Documentation search results are now scoped to the active locale and stable or preview channel.
- Horizontal wheel and trackpad events now reach pane applications that enable mouse reporting. (#1349)
- Copy mode `$` and End now stop at the final visible character on the row instead of jumping to the pane edge. (#1405)
- Split SGR mouse reports are now reassembled across input reads, and a preceding standalone Escape is preserved instead of being swallowed or leaked as mouse bytes. (#1334, #1382)
- Linux foreground-process discovery now stays within Herdr pane process trees instead of scanning unrelated host processes, reducing CPU use on busy multi-user systems. (#1399)
- Single-codepoint emoji chosen from the Windows emoji picker now reach panes when WezTerm's kitty keyboard support sends them as CSI-u events with associated text. (#1404)
- Outer-terminal focus gained and lost reports now reach the focused pane when its application enables focus reporting, restoring Neovim file autoreload and other focus-aware terminal behavior. (#1337)
- Native Windows servers now detach from the terminal console that launched them, so closing WezTerm, Windows Terminal, or another host terminal no longer stops persistent pane processes. (#1329)
@@ -41,7 +67,6 @@
- Added `herdr terminal session control` for bridge processes that need live ANSI frames plus input, resize, scroll, release, and takeover authority.
- Added `ui.hide_tab_bar_when_single_tab` to hide the tab row when a workspace has one tab. (#448)
- Added Japanese and Simplified Chinese website docs.
- Added session-modal popup terminal panes for custom command keybindings and plugin panes, so tools such as `lazygit` or plugin pickers can open without changing the tab layout. (#1125)
### Changed
- The mobile switcher now starts from an agents-first summary and renders worktrees as a tree, making narrow terminals easier to scan.
+30 -249
View File
@@ -6,7 +6,16 @@
</p>
<p align="center">
<a href="https://herdr.dev">herdr.dev</a> · <a href="#install">install</a> · <a href="#quick-start">quick start</a> · <a href="#supported-agents">supported agents</a> · <a href="https://herdr.dev/docs/integrations/">integrations</a> · <a href="https://herdr.dev/docs/configuration/">configuration</a> · <a href="https://herdr.dev/docs/socket-api/">socket api</a> · <a href="#sponsors">sponsor</a>
<a href="https://herdr.dev">herdr.dev</a> · <a href="#install">install</a> · <a href="https://herdr.dev/docs/quick-start/">quick start</a> · <a href="https://herdr.dev/docs/">docs</a> · <a href="#sponsors">sponsors</a>
</p>
<p align="center">
<a href="LICENSE"><img src="https://img.shields.io/badge/license-AGPL--3.0-666666?labelColor=333333" alt="AGPL 3.0 license" /></a>
<a href="https://github.com/ogulcancelik/herdr/releases"><img src="https://img.shields.io/github/downloads/ogulcancelik/herdr/total?labelColor=333333&color=666666" alt="total GitHub release downloads" /></a>
<a href="https://github.com/ogulcancelik/herdr/stargazers"><img src="https://img.shields.io/github/stars/ogulcancelik/herdr?labelColor=333333&color=666666&logo=github" alt="GitHub stars" /></a>
<a href="https://github.com/ogulcancelik/herdr/releases/latest"><img src="https://img.shields.io/github/v/release/ogulcancelik/herdr?label=release&labelColor=333333&color=666666" alt="latest stable release" /></a>
<a href="https://formulae.brew.sh/formula/herdr"><img src="https://img.shields.io/homebrew/v/herdr?label=homebrew&labelColor=333333&color=666666" alt="Homebrew version" /></a>
<a href="https://x.com/herdrdev"><img src="https://img.shields.io/badge/follow-%40herdrdev-000000?logo=x&logoColor=white" alt="follow @herdrdev on X" /></a>
</p>
---
@@ -15,7 +24,12 @@ https://github.com/user-attachments/assets/043ec09f-4bdd-41d5-aee0-8fda6b83e267
**agent multiplexer that lives in your terminal.**
workspaces, tabs, panes. mouse-native: click, drag, split. every agent at a glance: blocked, working, done. detach and reattach, agents keep running. no gui app, no electron, no mac-only native wrapper. you see the agent's own terminal, not someone's interpretation of it.
- **every agent at a glance** — blocked, working, done. real terminal views, not a wrapped interpretation.
- **detach, agents keep running** — reattach from any terminal, or over ssh. sessions survive restarts.
- **agents can use herdr too** — a pure socket api: agents spawn panes, read output, wait on each other. [agent skill →](https://herdr.dev/docs/agent-skill/)
- **keyboard and mouse, both first-class** — tmux-style prefix keys *and* click, drag, split. pick per moment, not per tool.
- **plugins** — extend panes and workflows. [browse the marketplace →](https://herdr.dev/plugins/)
- **one rust binary, no electron** — runs in whatever terminal you already use.
---
@@ -25,255 +39,29 @@ workspaces, tabs, panes. mouse-native: click, drag, split. every agent at a glan
curl -fsSL https://herdr.dev/install.sh | sh
```
on windows preview beta:
or `brew install herdr` · `mise use -g herdr` · windows beta: `powershell -ExecutionPolicy Bypass -c "irm https://herdr.dev/install.ps1 | iex"` · [binaries](https://github.com/ogulcancelik/herdr/releases)
```powershell
powershell -ExecutionPolicy Bypass -c "irm https://herdr.dev/install.ps1 | iex"
```
or install with homebrew:
```bash
brew install herdr
```
or install with mise:
```bash
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.
or download the stable Linux/macOS binary from [releases](https://github.com/ogulcancelik/herdr/releases). Native Windows binaries are preview-only beta builds.
## quick start
Start Herdr in the directory where the work lives:
then start it where the work lives:
```bash
herdr
```
Herdr starts or attaches to one background session server. When a session has no workspaces, Herdr opens one automatically. Run an agent in the root pane. Press `ctrl+b`, then `shift+n` to create another workspace, `ctrl+b`, then `v` or `minus` to split panes, `ctrl+b`, then `c` to create a tab, and `ctrl+b`, then `w` to switch workspaces.
Press `ctrl+b q` to detach the client. The server and pane processes keep running. Open another terminal and run `herdr` again to reattach.
## core concepts
**Server and client.** By default, `herdr` attaches to a background server. Detaching closes only the client. `herdr server stop` stops the default server and kills its panes. Named sessions are separate server namespaces: use `herdr session attach work`, `herdr session stop work`, and `herdr session list` when you want fully separate runtime state.
**Workspaces, tabs, panes.** A workspace is the project-level container. Tabs group panes inside a workspace. Panes are real terminal processes, not rewritten agent views.
**Copy.** Herdr copies pane text, not the sidebar. Drag-select inside a pane, double-click a word or token, or press `prefix+[` for keyboard copy mode. In copy mode, move with `h/j/k/l`, `w/b/e`, and `{`/`}`, search forward or backward with `/` or `?`, repeat with `n` or `N`, start selection with `v` or Space, copy with `y` or Enter, and leave with `q` or Esc. Esc clears an active selection or search before exiting. In PuTTY and some SSH terminals, hold `Shift` while dragging to use the terminal's own selection, and `Shift` + right click to paste.
**Update and restore.** `herdr update` installs a new binary, but a running server keeps using the old process until it is stopped or handed off. Stop the old server to use the new version. Stopping exits pane processes. Run `herdr server stop`, then run `herdr` again for the default session. For a named session, run `herdr session stop <name>`, then run `herdr session attach <name>` again. `herdr update --handoff` is experimental and tries to move live panes, including foreground processes such as dev servers, from the old server to the new one. With current official integrations installed, supported agent panes can restart from their native agent sessions after a server restart or update.
**Keybindings.** Herdr uses explicit keybinding strings. `prefix+n` means press the configured prefix, then `n`. `ctrl+alt+n`, `cmd+k`, `alt+1`, and function-key chords are direct terminal-mode shortcuts and do not need the prefix. Plain direct printable keys such as `n` steal normal typing, so use `prefix+n` unless you intentionally want a modifier-gated direct binding.
**Agent awareness.** The sidebar shows blocked, working, done, and idle states. Detection works with process names and terminal output by default. Official integrations can add native session identity for restore, semantic state reports, or both.
## update
Herdr notifies you when a new version is available. Run manually:
```bash
herdr update
```
`herdr update` is for installs managed by Herdr's own installer. Homebrew, mise, and Nix installs update through `brew upgrade herdr`, `mise upgrade herdr`, or your Nix workflow, then use the same stop-and-run-again flow if a session is still running the old server. Linux and macOS direct installs can opt into development preview builds with `herdr channel set preview` and return to stable with `herdr channel set stable`. Windows beta installs are preview-only for now. See [install docs](https://herdr.dev/docs/install/) and [session state docs](https://herdr.dev/docs/session-state/) for the full update, restart, restore, and handoff matrix.
Linux and macOS direct installs use the stable update channel by default. Windows beta installs default to preview. To test preview builds from `master` before the next stable release:
```bash
herdr channel set preview
```
To return Linux and macOS direct installs to stable:
```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 is only for direct installs managed by Herdr's updater. Homebrew, mise, and Nix stay on stable and update through their package managers.
## how it compares
| | tmux | gui managers | herdr |
|--------------------------|------|--------------|-------|
| persistent sessions | ✓ | — | ✓ |
| detach / reattach | ✓ | — | ✓ |
| panes, tabs, workspaces | ✓ | ✓ | ✓ |
| agent awareness | — | ✓ | ✓ |
| lives in your terminal | ✓ | — | ✓ |
| real terminal views | ✓ | — | ✓ |
| mouse-native | — | ✓ | ✓ |
| lightweight binary | ✓ | — | ✓ |
| agents can orchestrate | ? | ? | ✓ |
tmux gives you persistence and panes, but it was built before agents existed. gui managers show agent state, but they make you leave your terminal and use their wrapped view. herdr is persistence and awareness in one tool that stays out of your way.
## remote and attach
Herdr works over normal SSH. Run it on the remote host, detach, and reattach later:
```
ssh you@yourserver
herdr
```
You can also attach from your local terminal without opening a shell first:
```bash
herdr --remote workbox
herdr --remote ssh://you@yourserver:2222
```
Remote attach adds fallback SSH keepalives and connection reuse by default while preserving your own SSH config. Set `[remote].manage_ssh_config = false` to use plain `ssh`.
Direct attach connects your current terminal to one server-owned terminal:
```bash
herdr agent attach <target>
herdr terminal attach <terminal_id>
```
See [persistence and remote docs](https://herdr.dev/docs/persistence-remote/) for remote keybinding, named-session, and handoff details.
## agent awareness
the sidebar shows which agents are blocked, working, or done. workspaces roll up to their most urgent state so you can scan the full list at a glance.
states:
- 🔴 **blocked** — agent needs input or approval
- 🟡 **working** — agent is actively running
- 🔵 **done** — work finished, you have not looked at it yet
- 🟢 **idle** — done and seen
detection works by reading foreground process and terminal output. zero config, no hooks required. official claude code, codex, github copilot cli, devin, droid, kimi code cli, qodercli, and cursor agent cli integrations provide session restore identity; pi, omp, kimi code cli, opencode, kilo code cli, hermes, mastracode, and custom socket integrations can report their own state.
## lives in your terminal
not a gui window, not a web dashboard, not electron. herdr runs inside whatever terminal you already use. single rust binary, no dependencies. works inside tmux as the outer terminal environment.
## what you get
- **workspaces** — organized around git repos or folder names, each with its own tabs and panes
- **tabs** — first-class in the socket api and cli
- **copy-friendly** — drag-select pane text, double-click tokens, or use keyboard copy mode with `prefix+[`, `h/j/k/l`, `{`/`}`, `v`, and `y`
- **notifications** — sounds and toasts for background events; tab-aware suppression
- **18 built-in themes** — catppuccin, terminal, tokyo night, gruvbox, one, solarized, kanagawa, rosé pine, vesper, and light variants for the main palettes
- **session persistence** — pane processes survive client detach; sessions restore panes after full restart, with opt-in recent screen history
## agents can use herdr too
The local Unix socket lets agents create workspaces, split or zoom panes, spawn helpers, read output, and wait for state changes. Install the reusable skill with:
```bash
npx skills add ogulcancelik/herdr --skill herdr -g
```
Start with the [agent skill docs](https://herdr.dev/docs/agent-skill/), [socket API docs](https://herdr.dev/docs/socket-api/), and [`SKILL.md`](./SKILL.md).
## supported agents
automatic detection works out of the box. process name matching plus terminal output heuristics.
| agent | idle / done | working | blocked |
|-------|-------------|---------|---------|
| [pi](https://pi.dev) | ✓ | ✓ | partial |
| [claude code](https://docs.anthropic.com/en/docs/claude-code) | ✓ | ✓ | ✓ |
| [codex](https://github.com/openai/codex) | ✓ | ✓ | ✓ |
| [droid](https://factory.ai) | ✓ | ✓ | ✓ |
| [amp](https://ampcode.com) | ✓ | ✓ | ✓ |
| [opencode](https://github.com/anomalyco/opencode) | ✓ | ✓ | ✓ |
| [grok cli](https://x.ai/grok) | ✓ | ✓ | ✓ |
| [hermes agent](https://github.com/NousResearch/hermes-agent) | ✓ | ✓ | ✓ |
| [kilo code cli](https://kilo.ai/) | ✓ | ✓ | ✓ |
| [devin cli](https://docs.devin.ai/cli) | ✓ | ✓ | ✓ |
| cursor agent | ✓ | ✓ | ✓ |
| antigravity cli | ✓ | ✓ | ✓ |
| kimi code cli | ✓ | ✓ | ✓ |
| [github copilot cli](https://github.com/features/copilot) | ✓ | ✓ | ✓ |
| [qodercli](https://qoder.com/cli) | ✓ | ✓ | ✓ |
| [maki](https://github.com/tontinton/maki) | ✓ | ✓ | ✓ |
| [kiro cli](https://kiro.dev/docs/cli/) | ✓ | ✓ | — |
detected but not fully tested: gemini cli, cline.
for agents outside the built-in list, herdr still works as a terminal multiplexer with workspaces, panes, and tiling. custom integrations can report agent labels over the socket api. see the [socket api docs](https://herdr.dev/docs/socket-api/).
### direct integrations
official integrations have two roles. claude code, codex, github copilot cli, devin, droid, qodercli, and cursor agent cli report session identity for native restore, while their state still comes from screen detection. pi, omp, kimi code cli, opencode, kilo code cli, hermes, and mastracode report both semantic state and session identity. install with:
```bash
herdr integration install pi
herdr integration install omp
herdr integration install claude
herdr integration install codex
herdr integration install copilot
herdr integration install devin
herdr integration install droid
herdr integration install kimi
herdr integration install opencode
herdr integration install kilo
herdr integration install hermes
herdr integration install mastracode
herdr integration install qodercli
herdr integration install cursor
```
see the [integrations docs](https://herdr.dev/docs/integrations/) for setup details.
## keybindings
Press `ctrl+b` to enter prefix mode. Default actions are prefix-first and tmux-like:
| key | action |
|-----|--------|
| `prefix+c` | new tab |
| `prefix+n` / `prefix+p` | next / previous tab |
| `prefix+1..9` | switch tab |
| `prefix+w` | workspace navigation |
| `prefix+g` | session navigator |
| `prefix+shift+n` | new workspace |
| `prefix+shift+g` | new worktree |
| `prefix+shift+w` | rename workspace |
| `prefix+shift+d` | close workspace |
| `prefix+h/j/k/l` | focus pane |
| `prefix+shift+h/j/k/l` | swap pane |
| `prefix+v` / `prefix+minus` | split pane |
| `prefix+x` | close pane |
| `prefix+b` | toggle sidebar |
| `prefix+z` | zoom pane |
| `prefix+r` | resize mode |
| `prefix+q` | detach |
Mouse is supported throughout. Resize mode uses `h`/`l` for width, `j`/`k` for height, and `esc` to exit. Full syntax, optional actions, indexed bindings, and custom command bindings live in the [configuration docs](https://herdr.dev/docs/configuration/).
## configuration
config file: `~/.config/herdr/config.toml`
```bash
herdr --default-config # print full default config
```
In-app settings cover theme, sound, and toast preferences. Herdr writes logs under `~/.config/herdr/`; in persistent session mode, `herdr-client.log` and `herdr-server.log` are usually the useful files. Full configuration and logging details live in the [configuration docs](https://herdr.dev/docs/configuration/).
run your agents, split panes, walk away. `ctrl+b q` detaches, `herdr` reattaches. [quick start →](https://herdr.dev/docs/quick-start/)
## docs
- [quick start](https://herdr.dev/docs/quick-start/) — first session, panes, copy, and named sessions
- [install](https://herdr.dev/docs/install/) — install, update, Homebrew, mise, and Nix
- [session state](https://herdr.dev/docs/session-state/) — detach, restart restore, agent restore, and live handoff
- [configuration](https://herdr.dev/docs/configuration/) — keybindings, themes, notifications, environment variables
- [integrations](https://herdr.dev/docs/integrations/) — pi, omp, claude code, codex, cursor agent cli, github copilot cli, droid, kimi code cli, opencode, kilo code cli, hermes, mastracode, qodercli integrations
- [`SKILL.md`](./SKILL.md) — reusable agent skill
- [socket api](https://herdr.dev/docs/socket-api/) — socket protocol and cli reference
everything lives at [herdr.dev/docs](https://herdr.dev/docs/): [quick start](https://herdr.dev/docs/quick-start/) · [concepts](https://herdr.dev/docs/concepts/) · [supported agents](https://herdr.dev/docs/agents/) · [keyboard](https://herdr.dev/docs/keyboard/) · [configuration](https://herdr.dev/docs/configuration/) · [session state](https://herdr.dev/docs/session-state/) · [remote](https://herdr.dev/docs/persistence-remote/) · [integrations](https://herdr.dev/docs/integrations/) · [plugins](https://herdr.dev/docs/plugins/) · [socket api](https://herdr.dev/docs/socket-api/)
## sponsors
herdr is built full-time, in the open. sponsoring directly funds development, stability, and the path to a real agent runtime.
### gold
<a href="https://terminaltrove.com/"><img src="assets/sponsors/terminal-trove.png" alt="Terminal Trove" width="200" /></a>
[**→ become a sponsor**](https://github.com/sponsors/ogulcancelik) · enterprise / partnership: hey@herdr.dev · see [SPONSORS.md](./SPONSORS.md) for tiers. thank you 🐑
## agent instructions
@@ -285,18 +73,11 @@ if you are an ai agent helping with this repository, read [`AGENTS.md`](./AGENTS
git clone https://github.com/ogulcancelik/herdr
cd herdr
cargo build --release
./target/release/herdr
just test # unit tests
just check # formatting, tests, and maintenance checks
```
## sponsors
herdr is built full-time, in the open, with no revenue behind it. sponsoring directly funds development, stability, and the path to a real agent runtime.
[**→ become a sponsor**](https://github.com/sponsors/ogulcancelik) · enterprise / partnership: hey@herdr.dev · see [SPONSORS.md](./SPONSORS.md) for tiers. thank you 🐑
## license
Herdr is dual-licensed:
@@ -95,12 +95,13 @@ herdr pane read w1:p2 --source recent --lines 50
| サーバー | `ping`、`server.stop`、`server.reload_config`、`server.agent_manifests`、`server.reload_agent_manifests` |
| 通知 | `notification.show` |
| クライアント | `client.window_title.set`、`client.window_title.clear` |
| ワークスペース | `workspace.create`、`workspace.list`、`workspace.get`、`workspace.focus`、`workspace.rename`、`workspace.report_metadata`、`workspace.close` |
| セッション | `session.snapshot` |
| ワークスペース | `workspace.create`、`workspace.list`、`workspace.get`、`workspace.focus`、`workspace.rename`、`workspace.move`、`workspace.report_metadata`、`workspace.close` |
| Worktree | `worktree.list`、`worktree.create`、`worktree.open`、`worktree.remove` |
| タブ | `tab.create`、`tab.list`、`tab.get`、`tab.focus`、`tab.rename`、`tab.close` |
| ペイン | `pane.split`、`pane.swap`、`pane.move`、`pane.zoom`、`pane.layout`、`pane.process_info`、`pane.neighbor`、`pane.edges`、`pane.focus_direction`、`pane.resize`、`pane.list`、`pane.current`、`pane.get`、`pane.rename`、`pane.send_text`、`pane.send_keys`、`pane.send_input`、`pane.read`、`pane.report_agent`、`pane.report_agent_session`、`pane.report_metadata`、`pane.clear_agent_authority`、`pane.release_agent`、`pane.close`、`pane.wait_for_output` |
| タブ | `tab.create`、`tab.list`、`tab.get`、`tab.focus`、`tab.rename`、`tab.move`、`tab.close` |
| ペイン | `pane.split`、`pane.swap`、`pane.move`、`pane.zoom`、`pane.layout`、`pane.process_info`、`pane.neighbor`、`pane.edges`、`pane.focus_direction`、`pane.resize`、`pane.list`、`pane.current`、`pane.get`、`pane.rename`、`pane.send_text`、`pane.send_keys`、`pane.send_input`、`pane.read`、`pane.graphics.info`、`pane.graphics.set`、`pane.graphics.clear`、`pane.graphics.stream`、`pane.report_agent`、`pane.report_agent_session`、`pane.report_metadata`、`pane.clear_agent_authority`、`pane.release_agent`、`pane.close`、`pane.wait_for_output` |
| ポップアップ | `popup.close` |
| レイアウト | `layout.export`、`layout.apply` |
| レイアウト | `layout.export`、`layout.apply`、`layout.set_split_ratio` |
| エージェント | `agent.list`、`agent.get`、`agent.read`、`agent.explain`、`agent.send`、`agent.rename`、`agent.focus`、`agent.start` |
| イベント | `events.subscribe`、`events.wait` |
| インテグレーション | `integration.install`、`integration.uninstall` |
@@ -108,6 +109,10 @@ herdr pane read w1:p2 --source recent --lines 50
一部の CLI コマンドは、これらのメソッドの便利ラッパーです。たとえば `herdr agent wait` は、エージェントターゲットを解決してからペインのエージェント状態イベントを購読します。
`session.snapshot` は、独自のローカルランタイムキャッシュを持つクライアント向けに、一度限りのブートストラップスナップショットを返します。レスポンスには、バージョン/プロトコルメタデータ、フォーカス中のワークスペース/タブ/ペイン id、ワークスペース、タブ、ペイン、タブレイアウト、エージェントの各レコードが含まれます。これは購読ではありません。取得後はリソースイベントを購読し、そのイベントでローカルキャッシュを更新してください。再接続後やキャッシュが古い可能性がある場合は、`session.snapshot` を再度呼び出します。ワークスペースレコードには、関連付けられた worktree の出自情報も含まれます。リポジトリ全体の worktree 検出には引き続き `worktree.list` を使います。
CLI の `herdr api snapshot` は、クライアントやエージェントが簡単にブートストラップできるよう、現在の `session.snapshot` レスポンスを JSON で出力します。
ペイン制御メソッドは `w1:p1` のような公開ペイン id を使います。スキーマ上 `pane_id` が省略可能なメソッドは、省略時にサーバーのアクティブなフォーカス中ペインを使います。`pane.move` は常に送信元の `pane_id` を要求します。
`pane.send_keys` と `pane.send_input.keys` は Herdr のキーコンボ文字列を受け付けます: 通常の印字可能キー、`enter` や `esc` のような特殊キー、`ctrl+h`、`control+j`、`alt+x`、`shift+tab` のような修飾キーコード、`f1` のようなファンクションキー、`minus` や `plus` のような名前付き記号です。`prefix+` のバインド文字列は受け付けません。
@@ -126,6 +131,35 @@ herdr pane read w1:p2 --source recent --lines 50
`pane.current` は単一の `PaneInfo` を返します。`caller_pane_id` があるときはそのペインを返します。省略時はアクティブなフォーカス中ペインを返します。
ターミナルのスクロール情報を取得できる場合、`PaneInfo` には `scroll` が含まれます:
```json
{
"offset_from_bottom": 12,
"max_offset_from_bottom": 240,
"viewport_rows": 30
}
```
クライアントは `offset_from_bottom == 0` を最下部にいる状態として扱えます。
### 実験的なペイングラフィックス
ペイングラフィックスを使うと、プラグインがペイン上に画像データを配置できます。`[experimental].kitty_graphics = true` の場合にのみ利用でき、それ以外ではすべてのペイングラフィックスメソッドが `feature_disabled` を返します。`pane.graphics.info` はグラフィックスレイヤーを作成せず、接続中クライアントのセルの幅と高さをピクセル単位で返します。`pane.graphics.set` は `data_base64` の `png`、`rgb`、`rgba` データを受け取り、`pane.graphics.clear` はレイヤーを削除します。
```json
{"id":"graphics_info","method":"pane.graphics.info","params":{"pane_id":"w1:p1"}}
{"id":"graphics_set","method":"pane.graphics.set","params":{"pane_id":"w1:p1","format":"png","image_width":800,"image_height":600,"data_base64":"...","placement":{"viewport_col":0,"viewport_row":0,"grid_cols":80,"grid_rows":30}}}
{"id":"graphics_clear","method":"pane.graphics.clear","params":{"pane_id":"w1:p1"}}
```
フレームを繰り返し送る場合は、`pane.graphics.stream` で専用ソケットを開きます。Herdr が `ok` を返した後、フレームごとに 1 つの JSON ヘッダーと正確に `data_length` バイトの生データを送ります。ソケットが閉じるまでストリームがそのペインのグラフィックスレイヤーを所有し、同時に set、clear、stream を要求すると `stream_conflict` を返します。
```json
{"id":"graphics_stream","method":"pane.graphics.stream","params":{"pane_id":"w1:p1"}}
{"format":"png","image_width":800,"image_height":600,"data_length":12345,"placement":{"viewport_col":0,"viewport_row":0,"grid_cols":80,"grid_rows":30}}
```
`pane.layout` は、`workspace_id`、`tab_id`、`zoomed`、外側の `area`、`focused_pane_id`、ペインの矩形、分割の矩形/比率を含むタブレイアウトのスナップショットを返します。`pane.neighbor` と `pane.edges` は同じレイアウトスナップショットを含むので、クライアントは非公開のレイアウト状態なしに次の判断を下せます。
`pane.process_info` は、ペインのシェル pid、利用可能な場合はフォアグラウンドプロセスグループ id、そしてプラットフォームが公開している場合は pid、名前、argv/cmdline、cwd を含むフォアグラウンドプロセスを返します。
@@ -169,6 +203,12 @@ herdr pane read w1:p2 --source recent --lines 50
}
```
`layout.set_split_ratio` は、タブレイアウト内の既存の分割比率を更新します。レスポンスは、更新済みの移植可能な `layout` を含む `type: "layout_split_ratio_set"` です。
```json
{"id":"req_ratio","method":"layout.set_split_ratio","params":{"tab_id":"w1:t1","path":[],"ratio":0.6}}
```
プロセスを起動するメソッドは `env` オブジェクトを受け付けます。Herdr はそのキー/値ペアを新しく起動されるプロセスにのみ適用します。Herdr は管理下のペインプロセスに `HERDR_SOCKET_PATH`、`HERDR_ENV=1`、`HERDR_WORKSPACE_ID`、`HERDR_TAB_ID`、`HERDR_PANE_ID` も注入します。呼び出し側が与えた環境変数と衝突した場合、Herdr 管理の変数が権威を持ちます。
`pane.swap` は方向指定と明示指定の両方の形式をサポートします:
@@ -521,8 +561,10 @@ workspace の get/list 応答は結果の `tokens` マップを公開し、ス
最初のレスポンスは購読の確認応答です。以降の行はプッシュされるイベントです。
ワークスペースのイベント購読には `workspace.created`、`workspace.updated`、`workspace.metadata_updated`、`workspace.renamed`、`workspace.closed`、`workspace.focused` があります。`workspace.metadata_updated` はプラグインイベントフックを実行せずにトークン変更と TTL 失効を報告します。その他のワークスペースイベントは Herdr の UI/ランタイムのライフサイクルを記述します。ワークスペースが worktree グループに属している場合、`workspace.created` は任意の `workspace.worktree` 出自情報を含みます。削除前に Herdr がまだ識別できる場合、`workspace.closed` は最終的な `workspace` スナップショットを含みます。
ペインのイベント購読には `pane.created`、`pane.updated`、`pane.closed`、`pane.focused`、`pane.moved`、`pane.exited`、`pane.agent_detected`、`pane.output_matched`、`pane.agent_status_changed` があります。ターミナルタイトルの変更は `pane.updated` を発行することがありますが、生のタイトルでスピナーだけが変化し、`terminal_title_stripped` が変わらない場合は発行しません
ワークスペースのイベント購読には `workspace.created`、`workspace.updated`、`workspace.metadata_updated`、`workspace.renamed`、`workspace.moved`、`workspace.closed`、`workspace.focused` があります。`workspace.metadata_updated` はプラグインイベントフックを実行せずにトークン変更と TTL 失効を報告します。その他のワークスペースイベントは Herdr の UI/ランタイムのライフサイクルを記述します。ワークスペースが worktree グループに属している場合、`workspace.created` は任意の `workspace.worktree` 出自情報を含みます。`workspace.moved` は、移動した `workspace_id`、要求された `insert_index`、更新済みの順序付き `workspaces` リストを含みます。削除前に Herdr がまだ識別できる場合、`workspace.closed` は最終的な `workspace` スナップショットを含みます。
タブのイベント購読には `tab.created`、`tab.closed`、`tab.focused`、`tab.renamed`、`tab.moved` があります。`tab.moved` は、移動した `tab_id`、`workspace_id`、要求された `insert_index`、そのワークスペースの更新済みの順序付き `tabs` リストを含みます
ペインのイベント購読には `pane.created`、`pane.updated`、`pane.closed`、`pane.focused`、`pane.moved`、`pane.exited`、`pane.agent_detected`、`pane.output_matched`、`pane.agent_status_changed`、`pane.scroll_changed` があります。ターミナルタイトルの変更は `pane.updated` を発行することがありますが、生のタイトルでスピナーだけが変化し、`terminal_title_stripped` が変わらない場合は発行しません。`pane.scroll_changed` は 1 つの `pane_id` を対象とし、Herdr がスクロールスナップショットの変化を検出するたびに `pane_id`、`workspace_id`、現在の `scroll` 情報を発行します。
レイアウトのイベント購読には `layout.updated` があります。このイベントは 1 つのタブについて更新済みの `PaneLayoutSnapshot` を運びます。`session.snapshot` でブートストラップするクライアントは、同じ `workspace_id` と `tab_id` のキャッシュ済みレイアウトを置き換えてください。
worktree のイベント購読には `worktree.created`、`worktree.opened`、`worktree.removed` があります。worktree イベントは Git チェックアウトのライフサイクルを記述します。`worktree.created` は開かれた `workspace` と作成された `worktree` を含みます。`worktree.opened` は対象の `workspace`、開かれた `worktree`、`already_open` を含みます。`worktree.removed` は `workspace_id`、削除された `worktree`、`forced` を含みます。
@@ -95,12 +95,13 @@ herdr pane read w1:p2 --source recent --lines 50
| 服务器 | `ping`、`server.stop`、`server.reload_config`、`server.agent_manifests`、`server.reload_agent_manifests` |
| 通知 | `notification.show` |
| 客户端 | `client.window_title.set`、`client.window_title.clear` |
| 工作区 | `workspace.create`、`workspace.list`、`workspace.get`、`workspace.focus`、`workspace.rename`、`workspace.report_metadata`、`workspace.close` |
| 会话 | `session.snapshot` |
| 工作区 | `workspace.create`、`workspace.list`、`workspace.get`、`workspace.focus`、`workspace.rename`、`workspace.move`、`workspace.report_metadata`、`workspace.close` |
| Worktree | `worktree.list`、`worktree.create`、`worktree.open`、`worktree.remove` |
| 标签页 | `tab.create`、`tab.list`、`tab.get`、`tab.focus`、`tab.rename`、`tab.close` |
| 窗格 | `pane.split`、`pane.swap`、`pane.move`、`pane.zoom`、`pane.layout`、`pane.process_info`、`pane.neighbor`、`pane.edges`、`pane.focus_direction`、`pane.resize`、`pane.list`、`pane.current`、`pane.get`、`pane.rename`、`pane.send_text`、`pane.send_keys`、`pane.send_input`、`pane.read`、`pane.report_agent`、`pane.report_agent_session`、`pane.report_metadata`、`pane.clear_agent_authority`、`pane.release_agent`、`pane.close`、`pane.wait_for_output` |
| 标签页 | `tab.create`、`tab.list`、`tab.get`、`tab.focus`、`tab.rename`、`tab.move`、`tab.close` |
| 窗格 | `pane.split`、`pane.swap`、`pane.move`、`pane.zoom`、`pane.layout`、`pane.process_info`、`pane.neighbor`、`pane.edges`、`pane.focus_direction`、`pane.resize`、`pane.list`、`pane.current`、`pane.get`、`pane.rename`、`pane.send_text`、`pane.send_keys`、`pane.send_input`、`pane.read`、`pane.graphics.info`、`pane.graphics.set`、`pane.graphics.clear`、`pane.graphics.stream`、`pane.report_agent`、`pane.report_agent_session`、`pane.report_metadata`、`pane.clear_agent_authority`、`pane.release_agent`、`pane.close`、`pane.wait_for_output` |
| 弹窗 | `popup.close` |
| 布局 | `layout.export`、`layout.apply` |
| 布局 | `layout.export`、`layout.apply`、`layout.set_split_ratio` |
| 智能体 | `agent.list`、`agent.get`、`agent.read`、`agent.explain`、`agent.send`、`agent.rename`、`agent.focus`、`agent.start` |
| 事件 | `events.subscribe`、`events.wait` |
| 集成 | `integration.install`、`integration.uninstall` |
@@ -108,6 +109,10 @@ herdr pane read w1:p2 --source recent --lines 50
一些 CLI 命令是这些方法的便捷包装。比如 `herdr agent wait` 先解析智能体目标,然后订阅窗格智能体状态事件。
`session.snapshot` 为维护本地运行时缓存的客户端返回一次性引导快照。响应包含版本/协议元数据、当前聚焦的工作区/标签页/窗格 id、工作区记录、标签页记录、窗格记录、标签页布局快照和智能体记录。它不是订阅;读取后应订阅资源事件,并根据事件更新本地缓存。重新连接后或本地缓存可能已过期时,再次调用 `session.snapshot`。工作区记录也包含关联 worktree 的来源信息。完整的仓库 worktree 发现仍使用 `worktree.list`。
CLI 的 `herdr api snapshot` 会把当前 `session.snapshot` 响应输出为 JSON,让客户端和智能体可以简单地完成引导。
窗格控制方法使用 `w1:p1` 这类公开窗格 id。schema 中 `pane_id` 可选的方法,在省略它时使用服务器当前聚焦的活动窗格。`pane.move` 总是要求来源 `pane_id`。
`pane.send_keys` 和 `pane.send_input.keys` 接受 Herdr 组合键字符串: 普通可打印键、`enter` 和 `esc` 这类特殊键、`ctrl+h`、`control+j`、`alt+x`、`shift+tab` 这类修饰组合键、`f1` 这类功能键,以及 `minus` 和 `plus` 这类命名标点。它们不接受 `prefix+` 绑定字符串。
@@ -126,6 +131,35 @@ herdr pane read w1:p2 --source recent --lines 50
`pane.current` 返回单个 `PaneInfo`。带有 `caller_pane_id` 时,Herdr 返回那个窗格。省略时,Herdr 返回当前聚焦的活动窗格。
终端滚动指标可用时,`PaneInfo` 包含 `scroll`:
```json
{
"offset_from_bottom": 12,
"max_offset_from_bottom": 240,
"viewport_rows": 30
}
```
客户端可以把 `offset_from_bottom == 0` 视为位于底部。
### 实验性窗格图形
窗格图形允许插件在窗格上放置图像数据。它们只在 `[experimental].kitty_graphics = true` 时可用;否则所有窗格图形方法都返回 `feature_disabled`。调用 `pane.graphics.info` 会返回所连接客户端的单元格像素宽度和高度,但不会创建图形层。`pane.graphics.set` 接受 `data_base64` 中的 `png`、`rgb` 或 `rgba` 数据,`pane.graphics.clear` 删除该图层。
```json
{"id":"graphics_info","method":"pane.graphics.info","params":{"pane_id":"w1:p1"}}
{"id":"graphics_set","method":"pane.graphics.set","params":{"pane_id":"w1:p1","format":"png","image_width":800,"image_height":600,"data_base64":"...","placement":{"viewport_col":0,"viewport_row":0,"grid_cols":80,"grid_rows":30}}}
{"id":"graphics_clear","method":"pane.graphics.clear","params":{"pane_id":"w1:p1"}}
```
要重复发送帧,用 `pane.graphics.stream` 打开专用 socket。Herdr 回复 `ok` 后,每一帧发送一个 JSON 头,再发送恰好 `data_length` 字节的原始数据。socket 关闭前,该流拥有对应窗格的图形层;并发 set、clear 或 stream 请求返回 `stream_conflict`。
```json
{"id":"graphics_stream","method":"pane.graphics.stream","params":{"pane_id":"w1:p1"}}
{"format":"png","image_width":800,"image_height":600,"data_length":12345,"placement":{"viewport_col":0,"viewport_row":0,"grid_cols":80,"grid_rows":30}}
```
`pane.layout` 返回标签页布局快照,包含 `workspace_id`、`tab_id`、`zoomed`、外层 `area`、`focused_pane_id`、窗格矩形和分割矩形/比例。`pane.neighbor` 和 `pane.edges` 也包含同一份布局快照,让客户端不需要私有布局状态就能做出下一步决策。
`pane.process_info` 返回窗格的 shell pid、可用时的前台进程组 id,以及平台暴露时带有 pid、名称、argv/cmdline 和 cwd 的前台进程。
@@ -169,6 +203,12 @@ herdr pane read w1:p2 --source recent --lines 50
}
```
`layout.set_split_ratio` 更新标签页布局中已有分割的比例。响应是 `type: "layout_split_ratio_set"`,并包含更新后的可移植 `layout`。
```json
{"id":"req_ratio","method":"layout.set_split_ratio","params":{"tab_id":"w1:t1","path":[],"ratio":0.6}}
```
启动进程的方法接受一个 `env` 对象。Herdr 只把这些键值对应用到新启动的进程。Herdr 还向受管窗格进程注入 `HERDR_SOCKET_PATH`、`HERDR_ENV=1`、`HERDR_WORKSPACE_ID`、`HERDR_TAB_ID` 和 `HERDR_PANE_ID`。与调用方提供的环境变量冲突时,Herdr 管理的变量保持权威。
`pane.swap` 支持按方向和显式两种形式:
@@ -521,8 +561,10 @@ workspace 的 get/list 响应会公开生成的 `tokens` 映射,空间侧边栏
第一个响应确认订阅。之后的行是推送的事件。
工作区事件订阅包括 `workspace.created`、`workspace.updated`、`workspace.metadata_updated`、`workspace.renamed`、`workspace.closed` 和 `workspace.focused`。`workspace.metadata_updated` 报告令牌变更和 TTL 到期,但不会调用插件事件钩子。其他工作区事件描述 Herdr UI/运行时的生命周期。当工作区属于 worktree 组时,`workspace.created` 包含可选的 `workspace.worktree` 来源信息。在移除前 Herdr 仍能识别时,`workspace.closed` 包含最终的 `workspace` 快照。
窗格事件订阅包括 `pane.created`、`pane.updated`、`pane.closed`、`pane.focused`、`pane.moved`、`pane.exited`、`pane.agent_detected`、`pane.output_matched` 和 `pane.agent_status_changed`。终端标题变化可能发出 `pane.updated`,但如果原始标题只有旋转指示符发生变化且 `terminal_title_stripped` 不变,则不会发出
工作区事件订阅包括 `workspace.created`、`workspace.updated`、`workspace.metadata_updated`、`workspace.renamed`、`workspace.moved`、`workspace.closed` 和 `workspace.focused`。`workspace.metadata_updated` 报告令牌变更和 TTL 到期,但不会调用插件事件钩子。其他工作区事件描述 Herdr UI/运行时的生命周期。当工作区属于 worktree 组时,`workspace.created` 包含可选的 `workspace.worktree` 来源信息。`workspace.moved` 包含被移动的 `workspace_id`、请求的 `insert_index` 和更新后的有序 `workspaces` 列表。在移除前 Herdr 仍能识别时,`workspace.closed` 包含最终的 `workspace` 快照。
标签页事件订阅包括 `tab.created`、`tab.closed`、`tab.focused`、`tab.renamed` 和 `tab.moved`。`tab.moved` 包含被移动的 `tab_id`、`workspace_id`、请求的 `insert_index` 和该工作区更新后的有序 `tabs` 列表
窗格事件订阅包括 `pane.created`、`pane.updated`、`pane.closed`、`pane.focused`、`pane.moved`、`pane.exited`、`pane.agent_detected`、`pane.output_matched`、`pane.agent_status_changed` 和 `pane.scroll_changed`。终端标题变化可能发出 `pane.updated`,但如果原始标题只有旋转指示符发生变化且 `terminal_title_stripped` 不变,则不会发出。`pane.scroll_changed` 只针对一个 `pane_id`,每当 Herdr 观察到滚动快照变化时,都会发出 `pane_id`、`workspace_id` 和当前 `scroll` 指标。
布局事件订阅包括 `layout.updated`。该事件携带一个标签页更新后的 `PaneLayoutSnapshot`。使用 `session.snapshot` 引导的客户端应替换具有相同 `workspace_id` 和 `tab_id` 的缓存布局。
Worktree 事件订阅包括 `worktree.created`、`worktree.opened` 和 `worktree.removed`。Worktree 事件描述 Git 检出的生命周期。`worktree.created` 包含打开的 `workspace` 和创建的 `worktree`。`worktree.opened` 包含目标 `workspace`、打开的 `worktree` 和 `already_open`。`worktree.removed` 包含 `workspace_id`、被移除的 `worktree` 和 `forced`。
@@ -992,7 +992,7 @@
"key": "ui.sound.agents.maki",
"type": "enum",
"default": "\"default\"",
"description": "Sound override for detected MastraCode agents.",
"description": "Sound override for detected Maki agents.",
"values": [
"default",
"on",
+16 -6
View File
File diff suppressed because one or more lines are too long
+44 -15
View File
@@ -1,35 +1,64 @@
{
"schema_version": 1,
"channel": "preview",
"base_version": "0.7.2",
"build_id": "2026-07-07-f5354780e4ef",
"commit": "f5354780e4efcc938861b04992e954df915a07c8",
"built_at": "2026-07-07T20:42:48Z",
"base_version": "0.7.4",
"build_id": "2026-07-15-50aaa2ec046e",
"commit": "50aaa2ec046ee26ff407c20f49de496f522512a8",
"built_at": "2026-07-15T19:27:16Z",
"protocol": 16,
"notes": "Preview build 2026-07-07-f5354780e4ef\n\nBuilt from `f5354780e4ef` on `master`.\nBase stable: v0.7.2\nCompare: https://github.com/ogulcancelik/herdr/compare/v0.7.2...f5354780e4efcc938861b04992e954df915a07c8\n\n### Fixed\n- Keep cursor hide inside sync output\n- Guard windows process tree cycles\n- Clear done status on repeated pane focus\n- Preserve navigator search commands (#1140)\n\n### Maintenance\n- Ignore microsoft apt repos in artifact builds\n- Clear zig cache before windows checks",
"notes": "Preview build 2026-07-15-50aaa2ec046e\n\nBuilt from `50aaa2ec046e` on `master`.\nBase stable: v0.7.4\nCompare: https://github.com/ogulcancelik/herdr/compare/v0.7.4...50aaa2ec046ee26ff407c20f49de496f522512a8\n\n### Changed\n- Rebuilt preview from the current master branch.",
"assets": {
"linux-x86_64": {
"url": "https://github.com/ogulcancelik/herdr/releases/download/preview-2026-07-07-f5354780e4ef/herdr-linux-x86_64",
"sha256": "d5bc1b05c7d6f7ad9a00cc251b840aaac09026dcacaf6cf9dd51fc6e72cbe319"
"url": "https://github.com/ogulcancelik/herdr/releases/download/preview-2026-07-15-50aaa2ec046e/herdr-linux-x86_64",
"sha256": "9ba11e56ace4286077ef279a86476f6f2f81f2faf0280f1e56249b6f4bc4b160"
},
"linux-aarch64": {
"url": "https://github.com/ogulcancelik/herdr/releases/download/preview-2026-07-07-f5354780e4ef/herdr-linux-aarch64",
"sha256": "76787f396f4d791f4900c1277ab4758a3c995abb2fa0e0c458bf7158ca31af46"
"url": "https://github.com/ogulcancelik/herdr/releases/download/preview-2026-07-15-50aaa2ec046e/herdr-linux-aarch64",
"sha256": "11ef0d1a64b097e479f95e2578c2fee4e11d208640a6a98ea70ade968d145c7a"
},
"macos-x86_64": {
"url": "https://github.com/ogulcancelik/herdr/releases/download/preview-2026-07-07-f5354780e4ef/herdr-macos-x86_64",
"sha256": "7b70ca227b1265fce74cd1079257905a3061c53b8f43fdf9944ea1a0d7acf1df"
"url": "https://github.com/ogulcancelik/herdr/releases/download/preview-2026-07-15-50aaa2ec046e/herdr-macos-x86_64",
"sha256": "b1817355df28be4fd725d1795577e400f8edd90d3e807224b508a0c8e628c3ef"
},
"macos-aarch64": {
"url": "https://github.com/ogulcancelik/herdr/releases/download/preview-2026-07-07-f5354780e4ef/herdr-macos-aarch64",
"sha256": "ccf23f9d057d8bee8da1868bd26726971a556b344e151a33772967aa3da47d1d"
"url": "https://github.com/ogulcancelik/herdr/releases/download/preview-2026-07-15-50aaa2ec046e/herdr-macos-aarch64",
"sha256": "e1aa34cc33b3a30be4a5a5fd04bebf05c2011e4fb095f5ff20340eb200b5a1f9"
},
"windows-x86_64": {
"url": "https://github.com/ogulcancelik/herdr/releases/download/preview-2026-07-07-f5354780e4ef/herdr-windows-x86_64.exe",
"sha256": "9b28eb0a3a55ca2ca9d47e96397544d2cbcca965d88a40b8bd8ccacfb61333ba"
"url": "https://github.com/ogulcancelik/herdr/releases/download/preview-2026-07-15-50aaa2ec046e/herdr-windows-x86_64.exe",
"sha256": "1d99fa64974a69aa451230ba0c356c8466a4fb96fecb933abf81dd00f6dfc90e"
}
},
"builds": {
"2026-07-15-50aaa2ec046e": {
"base_version": "0.7.4",
"commit": "50aaa2ec046ee26ff407c20f49de496f522512a8",
"built_at": "2026-07-15T19:27:16Z",
"protocol": 16,
"tag": "preview-2026-07-15-50aaa2ec046e",
"assets": {
"linux-x86_64": {
"url": "https://github.com/ogulcancelik/herdr/releases/download/preview-2026-07-15-50aaa2ec046e/herdr-linux-x86_64",
"sha256": "9ba11e56ace4286077ef279a86476f6f2f81f2faf0280f1e56249b6f4bc4b160"
},
"linux-aarch64": {
"url": "https://github.com/ogulcancelik/herdr/releases/download/preview-2026-07-15-50aaa2ec046e/herdr-linux-aarch64",
"sha256": "11ef0d1a64b097e479f95e2578c2fee4e11d208640a6a98ea70ade968d145c7a"
},
"macos-x86_64": {
"url": "https://github.com/ogulcancelik/herdr/releases/download/preview-2026-07-15-50aaa2ec046e/herdr-macos-x86_64",
"sha256": "b1817355df28be4fd725d1795577e400f8edd90d3e807224b508a0c8e628c3ef"
},
"macos-aarch64": {
"url": "https://github.com/ogulcancelik/herdr/releases/download/preview-2026-07-15-50aaa2ec046e/herdr-macos-aarch64",
"sha256": "e1aa34cc33b3a30be4a5a5fd04bebf05c2011e4fb095f5ff20340eb200b5a1f9"
},
"windows-x86_64": {
"url": "https://github.com/ogulcancelik/herdr/releases/download/preview-2026-07-15-50aaa2ec046e/herdr-windows-x86_64.exe",
"sha256": "1d99fa64974a69aa451230ba0c356c8466a4fb96fecb933abf81dd00f6dfc90e"
}
}
},
"2026-07-07-f5354780e4ef": {
"base_version": "0.7.2",
"commit": "f5354780e4efcc938861b04992e954df915a07c8",
+10 -4
View File
@@ -29,6 +29,7 @@ Automatic detection works out of the box for common coding agents. The important
| Grok CLI | screen manifest | none |
| Antigravity CLI | screen manifest | none |
| Kiro CLI | screen manifest | none |
| Maki | screen manifest | none |
Detected but less thoroughly tested: Gemini CLI and Cline. 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.
@@ -113,17 +114,22 @@ Targets accept terminal IDs, unique agent names, detected or reported agent labe
## Custom status labels
Integrations can report a visual status label without changing semantic state.
Integrations report lifecycle state as semantic state only. Add display customization separately with pane metadata tokens.
```bash
herdr pane report-agent w1:p1 \
--source custom:indexer \
--agent docs-bot \
--state working \
--custom-status indexing
--state working
herdr pane report-metadata w1:p1 \
--source custom:indexer-display \
--token summary=indexing
```
`state` controls waits, notifications, and rollups. `custom-status` is only display text.
`state` controls waits, notifications, and rollups. The `summary` token is display-only and can be used as `$summary` in an Agent sidebar row.
Agent sidebar rows can also opt into `terminal_title` or `terminal_title_stripped`; neither appears in the default rows. The first shows the latest safety-normalized OSC 0/2 terminal title. The second removes one recognized leading activity or spinner glyph and following whitespace. Herdr owns these values on the server; they are ephemeral across a cold restart and remain independent of metadata titles and semantic agent state. Spinner animation can therefore update the raw title without producing a pane update when the stripped text stays the same.
## Start agents from the CLI
+15 -7
View File
@@ -120,6 +120,7 @@ herdr workspace create [--cwd PATH] [--label TEXT] [--env KEY=VALUE] [--focus] [
herdr workspace get <workspace_id>
herdr workspace focus <workspace_id>
herdr workspace rename <workspace_id> <label>
herdr workspace report-metadata <workspace_id> --source ID [--token NAME=VALUE] [--clear-token NAME] [--seq N] [--ttl-ms N]
herdr workspace close <workspace_id>
```
@@ -214,7 +215,6 @@ herdr pane report-agent <pane_id> \
--agent LABEL \
--state idle|working|blocked|unknown \
[--message TEXT] \
[--custom-status TEXT] \
[--seq N] \
[--agent-session-id ID] \
[--agent-session-path PATH]
@@ -235,18 +235,21 @@ herdr pane report-metadata <pane_id> \
[--applies-to-source ID] \
[--title TEXT|--clear-title] \
[--display-agent TEXT|--clear-display-agent] \
[--custom-status TEXT|--clear-custom-status] \
[--state-label STATUS=TEXT] \
[--clear-state-labels] \
[--token NAME=VALUE] \
[--clear-token NAME] \
[--seq N] \
[--ttl-ms N]
```
`STATUS` is one of `idle`, `working`, `blocked`, `done`, or `unknown`. `--agent` is a guard for the authoritative agent label. `--applies-to-source` is a guard for the active lifecycle authority source. Use `--display-agent` to change the visible name.
`STATUS` is one of `idle`, `working`, `blocked`, `done`, or `unknown`. `--agent` and `--applies-to-source` guard only `--title`, `--display-agent`, and `--state-label`. They do not guard token patches; token reporters own clearing or TTL refresh. Use `--display-agent` to change the visible name.
Metadata text is normalized before storage. Herdr trims surrounding whitespace, removes control characters, caps `--custom-status` at 32 characters, and caps `--title`, `--display-agent`, and each `--state-label` value at 80 characters. Empty normalized values are ignored.
Metadata text is normalized before storage. Herdr trims surrounding whitespace, removes control characters, and caps `--title`, `--display-agent`, each `--state-label`, and token values at 80 characters. Empty normalized token values clear that key.
`--source` and `--applies-to-source` must be 80 characters or fewer and may contain only ASCII letters, digits, colon, dot, underscore, and hyphen. `--ttl-ms` makes metadata expire automatically and must be between `1` and `86400000` milliseconds. Omit it for metadata that should stay until replaced, cleared, or the pane closes. `--seq` lets Herdr ignore stale reports from the same `--source`; stale reports are accepted by the API but ignored by pane state.
`--token` patches one named display value; `--clear-token` removes one. Unmentioned tokens remain unchanged. Pane tokens are available to Agent sidebar rows as `$name`; workspace tokens are available to Space rows. TTL applies independently to the token keys updated by that call.
`--source` and `--applies-to-source` must be 80 characters or fewer and may contain only ASCII letters, digits, colon, dot, underscore, and hyphen. `--ttl-ms` makes metadata expire automatically and must be between `1` and `86400000` milliseconds. Omit it for metadata that should stay until replaced, cleared, or the pane closes. `--seq` lets Herdr ignore stale reports from the same `--source`; stale reports are accepted by the API but ignored by pane state. A pane or workspace accepts sequenced token reports from at most 32 distinct sources during its lifetime; clearing or expiry does not release those source slots.
## Agents
@@ -401,7 +404,7 @@ herdr plugin log list [--plugin ID] [--limit N]
Managed terminal panes:
```bash
herdr plugin pane open --plugin ID --entrypoint ID [--placement overlay|split|tab|zoomed] [--workspace ID] [--target-pane PANE] [--direction right|down] [--cwd PATH] [--env KEY=VALUE] [--focus|--no-focus]
herdr plugin pane open --plugin ID --entrypoint ID [--placement overlay|popup|split|tab|zoomed] [--width SIZE] [--height SIZE] [--workspace ID] [--target-pane PANE] [--direction right|down] [--cwd PATH] [--env KEY=VALUE] [--focus|--no-focus]
herdr plugin pane focus <pane_id>
herdr plugin pane close <pane_id>
```
@@ -410,7 +413,12 @@ herdr plugin pane close <pane_id>
with the current platform. It starts a manifest-declared `[[panes]]` command as
a Herdr-managed terminal pane. The manifest default is `overlay`, which opens a
temporary zoomed overlay over the active pane. It can also open as a split, a
new tab, or a zoomed pane. Native non-terminal plugin panes are a later surface.
new tab, a zoomed pane, or a session-modal `popup` that does not change the tab
layout. `--width` and `--height` set the outer popup dimensions in terminal
cells or percentages such as `80%`; omitted dimensions default to half the
terminal size, and values smaller than the popup minimum are clamped. A popup
is not a Herdr pane, does not export `HERDR_PANE_ID`, and does not participate
in pane or agent APIs. Native non-terminal plugin panes are a later surface.
`--env KEY=VALUE` can be repeated on process-launching commands. It applies to the newly launched process only. Herdr-managed variables such as `HERDR_SOCKET_PATH`, `HERDR_BIN_PATH`, `HERDR_ENV`, `HERDR_WORKSPACE_ID`, `HERDR_TAB_ID`, `HERDR_PANE_ID`, `HERDR_PLUGIN_ID`, `HERDR_PLUGIN_ROOT`, `HERDR_PLUGIN_CONFIG_DIR`, `HERDR_PLUGIN_STATE_DIR`, `HERDR_PLUGIN_ENTRYPOINT_ID`, and `HERDR_PLUGIN_CONTEXT_JSON` stay authoritative when they conflict with caller-provided env.
+123 -214
View File
@@ -3,9 +3,9 @@ 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.
Herdr works without a config file. Add one when you want custom keys, themes, sidebar layouts, notifications, or advanced behavior.
Looking for a specific key? The [Config reference](/docs/config-reference/) lists every key with its type, default, and allowed values.
Looking for any setting or keybinding? Search the [Config reference](/docs/config-reference/) for every key, type, default, and allowed value. This page focuses on setup, common recipes, and configuration structures that need more explanation than a reference row.
## Config file
@@ -38,23 +38,6 @@ Herdr shows first-run setup when `onboarding` is missing or true. Continuing fro
onboarding = false
```
## Updates
Linux and macOS direct installs use the stable update channel by default. Windows beta installs default to preview and cannot switch to stable until stable Windows releases are available.
```toml
[update]
channel = "stable"
version_check = true
manifest_check = true
```
Set `channel = "preview"` to make `herdr update` install manually published preview builds from the current development branch. Homebrew, mise, and Nix installs ignore the preview channel and update through their package managers.
Set `version_check = false` to disable background checks for new Herdr versions. Manual `herdr update` still uses the configured channel.
Set `manifest_check = false` to disable background remote agent-detection manifest checks. Herdr still uses bundled manifests and local overrides.
## Reload config
Reload a running server after editing `config.toml`:
@@ -145,65 +128,16 @@ navigate_pane_down = "ctrl+j"
split_horizontal = "prefix+minus"
```
The default keymap is prefix-first and avoids direct shortcuts that can steal input from shells, editors, tmux, or terminal apps. Common defaults include:
The default keymap is prefix-first so Herdr does not steal input from shells, editors, tmux, or terminal apps. Search `keys.` in the [Config reference](/docs/config-reference/) to see every action and default binding. The in-app help panel at `prefix+?` shows the active bindings.
A binding may also be an array when one action needs multiple shortcuts:
```toml
[keys]
detach = "prefix+q"
workspace_picker = "prefix+w"
goto = "prefix+g"
new_workspace = "prefix+shift+n"
new_worktree = "prefix+shift+g"
rename_workspace = "prefix+shift+w"
close_workspace = "prefix+shift+d"
navigate_workspace_up = "up"
navigate_workspace_down = "down"
navigate_pane_left = "h"
navigate_pane_down = "j"
navigate_pane_up = "k"
navigate_pane_right = "l"
remote_image_paste = "ctrl+v"
new_tab = "prefix+c"
previous_tab = "prefix+p"
next_tab = "prefix+n"
switch_tab = "prefix+1..9"
rename_tab = "prefix+shift+t"
close_tab = "prefix+shift+x"
copy_mode = "prefix+["
focus_pane_left = "prefix+h"
focus_pane_down = "prefix+j"
focus_pane_up = "prefix+k"
focus_pane_right = "prefix+l"
swap_pane_left = "prefix+shift+h"
swap_pane_down = "prefix+shift+j"
swap_pane_up = "prefix+shift+k"
swap_pane_right = "prefix+shift+l"
cycle_pane_next = "prefix+tab"
cycle_pane_previous = "prefix+shift+tab"
last_pane = ""
split_vertical = "prefix+v"
split_horizontal = "prefix+minus"
close_pane = "prefix+x"
zoom = "prefix+z"
resize_mode = "prefix+r"
toggle_sidebar = "prefix+b"
```
Optional actions are unset by default. Bind them with `prefix+` for prefix-mode behavior, or with an explicit modified chord when you intentionally want a direct shortcut:
```toml
[keys]
previous_workspace = "prefix+shift+left"
next_workspace = "prefix+shift+right"
last_pane = "prefix+tab"
open_worktree = "prefix+shift+o"
remove_worktree = "prefix+alt+d"
next_tab = ["prefix+n", "ctrl+alt+]"]
```
`last_pane` switches back to the last focused pane across workspaces and tabs. It is unset by default because the tmux-style pane binding `prefix+l` is already used for pane-right focus.
`remote_image_paste` is only active in `herdr --remote`. It is the local-client shortcut that sends a local clipboard image to the remote pane. Set it to an empty string to disable the raw-key shortcut; remote terminal paste-image signals still work when the outer terminal sends them.
Optional actions are unset by default. Bind them with `prefix+` for prefix-mode behavior, or use an explicit modified chord when you intentionally want a direct shortcut.
Key strings accept plain keys, modifier combinations such as `ctrl+a`, `shift+n`, `alt+1`, `cmd+k`, and special keys such as `enter`, `tab`, `esc`, `left`, `right`, `up`, and `down`. Named punctuation such as `minus`, `comma`, `ampersand`, `plus`, and `backtick` is also accepted. Plain direct printable keys such as `n` are unsafe because they intercept typing; use `prefix+n` unless you intentionally want a direct binding. The `navigate_workspace_*` and `navigate_pane_*` fields are navigate-mode-only and may use plain keys such as `j` or `k`; they must not use `prefix+`, `esc`, `enter`, `tab`, `shift+tab`, `left`, `right`, or unmodified `1` through `9`. Left and right arrows are permanent aliases for pane-left and pane-right navigation. These navigate-mode shortcuts are independent from general action bindings such as `focus_pane_down = "prefix+j"`; when both use the same key, the navigate-mode shortcut wins while navigate mode is open. Alt, Cmd/Super, and punctuation with modifiers depend on your terminal and tmux settings.
@@ -229,12 +163,38 @@ Custom commands use the same keybinding syntax.
```toml
[[keys.command]]
key = "prefix+alt+g"
type = "pane"
type = "popup"
command = "lazygit"
description = "run lazygit"
width = "80%"
height = "80%"
```
`type = "pane"` opens a temporary pane and closes it when the command exits.
`type = "popup"` opens a session-modal popup without changing the tab layout.
The popup receives all terminal input, including Escape, until its command
exits. `width` and `height` are optional; omit them for the default half-size
popup, use numbers for terminal cells, or use strings like `"80%"` for a
percentage of the terminal area. Dimensions include the popup border, and
values smaller than the popup minimum are clamped. Popup commands do not receive
`HERDR_PANE_ID`; use `HERDR_ACTIVE_PANE_ID` for the underlying tiled pane.
On Unix and macOS, a popup command can also provide an ad-hoc terminal without
adding a split or tab:
```toml
[[keys.command]]
key = "prefix+t"
type = "popup"
command = "exec \"${SHELL:-sh}\""
description = "open scratch terminal"
width = "80%"
height = "80%"
```
On Windows, use a shell command such as `command = "powershell.exe -NoLogo"`
instead. Exit the shell to close the popup and restore the tiled terminal view.
`type = "pane"` opens a temporary zoomed pane and closes it when the command exits.
`type = "shell"` runs detached in the background.
@@ -264,11 +224,7 @@ Choose a built-in theme:
name = "catppuccin"
```
Built-in themes:
`catppuccin`, `catppuccin-latte`, `terminal`, `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`.
Use `terminal` when you want Herdr UI colors to follow your host terminal's ANSI palette.
Search `theme.name` in the [Config reference](/docs/config-reference/) for every built-in theme. Use `terminal` when you want Herdr UI colors to follow your host terminal's ANSI palette.
To let Herdr switch its own UI theme when the host terminal reports a light/dark appearance change, enable theme auto-switching:
@@ -298,103 +254,112 @@ Color values accept hex, named colors, `rgb(r,g,b)`, or reset aliases like `rese
## UI and sidebar
The sidebar is the main Herdr dashboard. It shows workspaces, tabs, panes, and agent state.
The sidebar is the main Herdr dashboard. Search `ui.` in the [Config reference](/docs/config-reference/) for sizing, collapsed mode, Agent panel ordering, mouse behavior, pane borders, and other presentation settings.
Common options:
### Sidebar row layouts
The expanded desktop sidebar renders each inner array in `rows` as one line. These are the complete default layouts:
```toml
[ui]
sidebar_width = 32
sidebar_min_width = 18
sidebar_max_width = 36
sidebar_collapsed_mode = "compact"
mobile_width_threshold = 64
mouse_capture = true
host_cursor = "auto"
right_click_passthrough_modifier = ""
redraw_on_focus_gained = true
mouse_scroll_lines = 3
confirm_close = true
prompt_new_tab_name = true
pane_borders = true
pane_gaps = true
show_agent_labels_on_pane_borders = false
hide_tab_bar_when_single_tab = false
agent_panel_sort = "spaces"
accent = "cyan"
[ui.sidebar.agents]
row_gap = 0
rows = [
["state_icon", "workspace", "tab"],
["agent"],
]
[ui.sidebar.spaces]
row_gap = 0
rows = [
["state_icon", "workspace"],
["branch", "git_status"],
]
```
`sidebar_min_width` and `sidebar_max_width` control the expanded sidebar's resize bounds in columns. The defaults are 18 and 36.
Agent rows accept these built-in tokens:
`sidebar_collapsed_mode` controls what remains visible after toggling the sidebar closed. The default, `compact`, keeps the narrow status rail. Set it to `hidden` to make the collapsed sidebar zero-width; reopen it with `keys.toggle_sidebar`.
- `state_icon` — colored icon for the agent's semantic state.
- `state_text` — `idle`, `working`, `blocked`, `done`, or `unknown`, including a reported display label when present.
- `workspace` — workspace name.
- `tab` — tab name when available.
- `pane` — pane name when available.
- `agent` — detected or reported agent display name.
- `terminal_title` — latest OSC 0/2 terminal title after safety normalization.
- `terminal_title_stripped` — the terminal title with one recognized leading activity or spinner glyph and its following whitespace removed.
- `$name` — custom pane metadata named `name`.
`mobile_width_threshold` controls the terminal width at or below which Herdr uses the mobile single-column layout. The default is 64 columns; increase it for foldables, tablets, or wide phone terminals.
Space rows accept these built-in tokens:
The agent panel shows all agents across all spaces. `agent_panel_sort` can be `spaces` or `priority`; `workspaces` is accepted as an alias for `spaces`. `spaces` is the default and keeps agents grouped by space order. `priority` sorts by attention priority: blocked, done, working, idle, then unknown. Within the same status, agents that most recently changed state appear first.
- `state_icon` — colored icon for the space's rolled-up agent state.
- `state_text` — text for the rolled-up agent state.
- `workspace` — workspace name.
- `branch` — Git branch when available.
- `git_status` — Git ahead and behind counts when nonzero.
- `$name` — custom workspace metadata named `name`.
`confirm_close` controls whether closing a workspace asks for confirmation. `prompt_new_tab_name` controls whether new tabs ask for a label first.
Tokens render in their configured order. Herdr normally separates adjacent values with ` · ` and uses a single space after `state_icon`. Missing values and their separators disappear; a row disappears when none of its tokens have a value. Each layout may contain at most 16 rows, with at most 16 tokens in each row.
Set `mouse_capture = false` if you want your terminal to handle normal clicks, such as command-clicking URLs. With mouse capture enabled, Ctrl-click opens pane links when your terminal sends that modified click to Herdr. This includes macOS; Cmd-click is not reported separately from plain click while Herdr captures mouse input. Use Shift-Ctrl-click on Linux or Shift-Cmd-click on macOS for the terminal-native bypass path.
`row_gap` controls the blank terminal rows between entries, independently for the Agent and Space panels. It defaults to `0`, which packs entries together; set it to `1` to restore the previous spacing. It does not add spacing between the content lines declared in `rows`. Consecutive indented worktree children remain packed as one Space group.
`host_cursor` controls whether Herdr uses the outer terminal's native cursor or draws its own cursor as terminal cell content. The default, `auto`, draws Herdr's cursor on Windows to avoid ConPTY cursor flicker during active redraws, and uses the native cursor elsewhere. Set it to `native` to always use the outer terminal cursor, or `drawn` to always use Herdr's drawn cursor.
Override the complete Agent layout for a known agent under `rows_by_agent`:
Set `right_click_passthrough_modifier = "ctrl"` if you want Ctrl-right-click, hold, and drag gestures inside mouse-reporting pane apps to reach the app instead of opening Herdr's pane menu. The default is empty, which disables this passthrough. Supported modifiers are `ctrl`, `alt`, `cmd`, `super`, `meta`, and `hyper`; `shift` is rejected because many terminals reserve Shift+mouse for their own mouse bypass.
```toml
[ui.sidebar.agents]
rows = [
["state_icon", "agent", "state_text"],
["workspace", "tab"],
]
Set `redraw_on_focus_gained = false` to avoid the visible full-screen refresh when switching back to Herdr. The default is `true` because a full redraw recovers from rare stale or dirty host terminal surfaces.
[ui.sidebar.agents.rows_by_agent]
claude = [
["state_icon", "agent", "state_text"],
["terminal_title_stripped"],
["workspace", "tab"],
]
```
Set `mouse_scroll_lines` to change how many pane scrollback lines each mouse wheel notch scrolls. The default is 3. Pane apps that request mouse reporting still receive wheel events directly. Alternate-screen apps have no scrollback to scroll; see [Scrollback](#scrollback).
An override replaces `rows`; it does not extend it. Override keys are case-sensitive canonical agent IDs such as `claude`, `codex`, and `pi`. Detection aliases such as `claude-code` are not accepted. Agents without an override, including custom reported agents, use `rows`.
Set `pane_borders = false` to remove split pane borders. Set `pane_gaps = false` to make split panes share compact divider borders. With borders disabled, pane gaps use one blank terminal cell between panes. Terminal cells are usually taller than they are wide, so a one-row gap between top/bottom panes can look larger than a one-column gap between left/right panes.
Custom `$name` tokens are dynamic values, not literal text. Add the token to a layout, then report its value from a script or plugin:
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.
```toml
[ui.sidebar.agents]
rows = [
["state_icon", "agent", "$model"],
["$summary"],
["workspace", "tab"],
]
```
Set `hide_tab_bar_when_single_tab = true` to hide the tab row when the active workspace has exactly one tab. New tabs can still be created with the configured keybinding. When a second tab appears, Herdr restores the tab row and resizes panes to make room for it.
```bash
herdr pane report-metadata <pane_id> \
--source my-agent-hook \
--token model=opus \
--token summary="reviewing authentication"
```
Use `herdr workspace report-metadata` in the same way for custom Space tokens. Unreported custom tokens simply disappear. Metadata reporters provide values only; they cannot choose rows or styling. See [CLI reference: report metadata](/docs/cli-reference/#panes) for clearing, sequencing, and expiring values.
Sidebar row settings affect only the expanded desktop sidebar. Collapsed and mobile views keep their compact layouts.
## Notifications
Herdr can show popup notifications when agents finish or need input.
Herdr can notify you when a background agent finishes or needs input:
```toml
[ui.toast]
delivery = "off"
delivery = "herdr"
delay_seconds = 1
[ui.toast.herdr]
position = "bottom-right"
[ui.toast.clipboard]
enabled = true
position = "bottom-center"
```
`delivery = "off"` disables popup notifications. This is the default.
`delivery = "herdr"` shows a toast inside the Herdr UI. Click the toast, or bind `keys.open_notification_target`, to focus the target workspace, tab, and pane. Set `ui.toast.herdr.position` to `top-left`, `top-right`, `bottom-left`, or `bottom-right`; desktop positions are relative to the full Herdr frame.
`delivery = "terminal"` asks the outer terminal to show a desktop notification. Herdr sends terminal notification escape sequences for Ghostty, iTerm2, Kitty, and WezTerm. This is useful over SSH because the local terminal owns the notification.
`delivery = "system"` asks the local operating system directly. On macOS, Herdr uses `terminal-notifier` when available, then falls back to `/usr/bin/osascript`. `terminal-notifier` can activate the hosting terminal when you click the notification. On Linux, Herdr uses `notify-send` and requires `DISPLAY` or `WAYLAND_DISPLAY`.
Popup notifications are for background attention. Herdr suppresses popups for the active tab.
`delay_seconds` waits before sending finished or needs-input agent notifications. Herdr notifies only if the pane is still in the same state when the delay expires. Set it to `0` for instant notifications. Valid values are `0` through `3600`.
Clipboard feedback is configured separately because it confirms a foreground copy action and is never sent through terminal or system delivery. Set `ui.toast.clipboard.enabled = false` to hide the copied-to-clipboard popup. Clipboard positions are `top-left`, `top-center`, `top-right`, `bottom-left`, `bottom-center`, and `bottom-right`.
Choose `herdr` for an in-app toast, `terminal` for an outer-terminal notification that works well over SSH, `system` for the local OS notification service, or `off` to disable popups. Herdr suppresses popups for the active tab. Search `ui.toast` in the [Config reference](/docs/config-reference/) for positions, delay behavior, and clipboard feedback settings.
## Sound
Sound notifications are enabled by default and are played by the local Herdr client.
```toml
[ui.sound]
enabled = true
```
Herdr plays a done sound when an agent finishes and an attention sound when an agent needs input. Set `enabled = false` on shared machines or remote servers unless you explicitly want audio.
On macOS, Herdr uses `afplay`. On Linux, Herdr tries mp3-capable players in order: `paplay`, `pw-play`, `ffplay`, `mpg123`, then `mpv`. If no player is available, sound playback is skipped and Herdr logs a warning.
Custom sounds must be mp3 files. Relative paths are resolved from the config file's directory.
Sound notifications play through the local Herdr client. Custom sounds must be mp3 files; relative paths are resolved from the config file's directory.
```toml
[ui.sound]
@@ -413,110 +378,54 @@ droid = "off"
claude = "on"
```
## Scrollback
## Advanced configuration
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.
Panes only show a scrollbar when the app writes to the primary screen. Full-screen apps that switch to the alternate screen (vim, htop, Claude Code with `CLAUDE_CODE_NO_FLICKER=1`) produce no scrollback, so no scrollbar appears and wheel events are routed to the app instead. Scroll with the app's own keys or UI.
## Pane screen history
By default, full session restart restores workspaces, tabs, panes, cwd, layout, and focus without saving pane contents.
Pane screen history is off by default. Pane output can include secrets, tokens, prompts, and command output, so enable it only when you want Herdr to save recent pane contents across full server restarts:
```toml
[experimental]
pane_history = true
```
You can also toggle it from Settings > Experiments > pane screen history.
When enabled, Herdr stores saved pane history in `session-history.json` next to `session.json`.
For how pane screen history differs from live persistence, snapshot restore, native agent session restore, and live handoff, see [Session state and restore](/docs/session-state/).
## Nested launches
Herdr normally protects you from launching Herdr inside Herdr.
```toml
[experimental]
allow_nested = false
```
Only enable nested launches for testing.
Search the [Config reference](/docs/config-reference/) for scrollback limits, nested launches, and other advanced or experimental settings. See [Session state and restore](/docs/session-state/) before enabling pane screen history; that guide explains the security trade-off of saving pane contents.
## Kitty graphics
Kitty graphics support is experimental.
Kitty graphics rendering for attached local clients is experimental and disabled by default:
```toml
[experimental]
kitty_graphics = false
kitty_graphics = true
```
Leave this off unless you are testing terminal image behavior.
Enable it only when testing terminal image behavior.
## Agent session restore
Herdr can restart supported agent panes in their native conversation sessions after a Herdr server restart.
Herdr resumes supported Agent conversations after a server restart by default:
```toml
[session]
resume_agents_on_restore = true
```
This is enabled by default. Herdr only resumes panes that reported a native session reference through an official Herdr integration. Supported resume targets are Claude Code, Codex, Cursor Agent CLI, GitHub Copilot CLI, Droid, Kimi Code CLI, Qoder CLI, Pi, Hermes Agent, OpenCode, Kilo Code CLI, and MastraCode. Unsupported, missing, invalid, duplicated, or stale session references restore as a normal shell in the saved pane directory.
Session references are stored in the local Herdr session snapshot. They are not shown in normal pane, agent, status, or event output.
For how native agent session restore differs from pane screen history and live handoff, see [Session state and restore](/docs/session-state/).
Only panes with a valid native session reference from an official integration can resume; other panes restore as normal shells. See [Session state and restore](/docs/session-state/) for supported Agents and persistence behavior.
## IME cursor tracking
When the focused pane hides its cursor and paints its own — common in AI-agent TUIs like Claude Code, pi, codex, and Devin — macOS native input methods stop tracking the candidate window position because the outer terminal stops reporting the cursor.
Set `reveal_hidden_cursor_for_cjk_ime = true` to expose the focused pane's cursor anchor to the outer terminal regardless of the pane's `?25l` request:
On macOS, AI Agent TUIs that hide the hardware cursor can prevent native input-method candidate windows from following the focused pane. Reveal a cursor anchor for those panes with:
```toml
[experimental]
reveal_hidden_cursor_for_cjk_ime = false
cjk_ime_agents = []
cjk_ime_cursor_shape = "steady_block"
reveal_hidden_cursor_for_cjk_ime = true
cjk_ime_agents = ["claude", "pi", "codex"]
```
When enabled, the cursor stays visible at the focused pane's reported position. If the pane reports no cursor position, the anchor falls back to the pane's top-left so a stable IME hint is always available.
`cjk_ime_agents` is an optional allow-list. When empty, the reveal applies to any focused pane. When non-empty, the reveal only applies if the focused pane's detected agent matches one of the listed names — useful to enable the reveal only for AI-agent TUIs that paint their own cursor while leaving plain shells untouched. Accepted names: `pi`, `claude`, `codex`, `gemini`, `cursor`, `devin`, `agy`, `cline`, `opencode`, `copilot`, `kimi`, `kiro`, `droid`, `amp`, `grok`, `hermes`, `kilo`, `qodercli`, and `qoder`. Unknown names are ignored; if the list contains no valid names, the reveal does not apply.
`cjk_ime_cursor_shape` controls the DECSCUSR shape rendered for the IME anchor. Accepted values: `block`, `steady_block` (default), `underline`, `steady_underline`, `bar`, `steady_bar`.
Hot-reloads through the existing `[experimental]` block.
The trade-off when enabled: an extra hardware cursor is visible in the outer terminal for apps that hide the cursor without painting a replacement (vim normal mode, etc.). Pair the reveal with `cjk_ime_agents` to scope it to specific TUIs.
Restricting `cjk_ime_agents` avoids showing an extra hardware cursor in unrelated applications. Search these keys in the [Config reference](/docs/config-reference/) for accepted Agent names and cursor shapes.
## Prefix input source switching
On macOS, prefix-mode commands can be hard to use while a non-ASCII input source is active because prefix commands are still interpreted through the host input source.
Set `switch_ascii_input_source_in_prefix = true` to switch the host input source to the system ASCII-capable input source while prefix commands and prefix-launched navigation are active:
On macOS, Herdr can temporarily switch to the system ASCII-capable input source while prefix commands and prefix-launched modes are active:
```toml
[experimental]
switch_ascii_input_source_in_prefix = false
switch_ascii_input_source_in_prefix = true
```
When enabled, Herdr switches input sources after prefix mode is entered, keeps the ASCII source across prefix-launched modes such as navigation, menus, resize, and copy mode, and restores the previous input source when returning to the terminal or entering a text field such as a rename dialog. The setting is macOS-only and is a no-op on other platforms or when the system input-source switch fails.
You can also toggle it from Settings > Experiments > switch to ascii input source in prefix (macOS).
Herdr restores the previous input source when returning to terminal input or entering a text field. This setting has no effect on other platforms.
## Environment variables
+1 -1
View File
@@ -19,7 +19,7 @@ On Windows preview beta, install the preview channel:
powershell -ExecutionPolicy Bypass -c "irm https://herdr.dev/install.ps1 | iex"
```
The installer downloads the right release binary for your platform and places it on your PATH. The Windows installer defaults to preview, writes that channel to Herdr's config, uses versioned install folders, and updates a `current` junction, so updates do not need to overwrite a running `herdr.exe`.
The installer downloads the right release binary for your platform and places it on your PATH. Herdr defaults to preview on Windows without changing your config. The installer uses versioned install folders and updates a `current` junction, so updates do not need to overwrite a running `herdr.exe`.
## Install with Homebrew
+5 -8
View File
@@ -258,19 +258,16 @@ Herdr resumes stored MastraCode threads with `mastracode --thread <id>`.
## 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.
Integrations report lifecycle state as semantic state only. For example, report an agent as `working` without adding display fields to the lifecycle report.
```bash
herdr pane report-agent w1:p1 \
--source custom:docs \
--agent docs-bot \
--state working \
--custom-status indexing
--state working
```
User hooks that run next to a Herdr-managed integration should use metadata instead of `report-agent`. Metadata changes presentation without taking over the integration's `idle`, `working`, `blocked`, or session restore authority. `--agent` guards the report so it only applies while that authoritative agent is active. `--applies-to-source` guards the report so it only applies while that lifecycle authority source is active. `--display-agent` changes the visible name.
User hooks that run next to a Herdr-managed integration should use metadata instead of `report-agent`. Metadata changes presentation without taking over the integration's `idle`, `working`, `blocked`, or session restore authority. `--agent` and `--applies-to-source` guard only presentation fields (`--title`, `--display-agent`, and `--state-label`). Token patches always apply; their reporter owns clearing or TTL refresh. `--display-agent` changes the visible name.
```bash
herdr pane report-metadata "$HERDR_PANE_ID" \
@@ -278,12 +275,12 @@ herdr pane report-metadata "$HERDR_PANE_ID" \
--agent claude \
--title "Refactor auth middleware" \
--display-agent "Claude: auth" \
--custom-status "refactor auth" \
--token summary="refactor auth" \
--state-label working="refactoring auth" \
--ttl-ms 3600000
```
Custom status and state labels are visual-only. Waits, notifications, and workspace rollups still use the semantic state.
Tokens and state labels are visual-only. Waits, notifications, and workspace rollups still use the semantic state.
## Debug integration state
+10 -4
View File
@@ -29,6 +29,7 @@ Herdr は複数のコーディングエージェントを同時に動かすた
| Grok CLI | スクリーンマニフェスト | なし |
| Antigravity CLI | スクリーンマニフェスト | なし |
| Kiro CLI | スクリーンマニフェスト | なし |
| Maki | スクリーンマニフェスト | なし |
検出されるもののテストが薄いもの: Gemini CLI と Cline。未対応のエージェントも通常のターミナルプロセスとして問題なく動きます。ただし、インテグレーションを追加するかソケット API で状態を報告しない限り、詳細な状態は得られない可能性があります。
@@ -113,17 +114,22 @@ herdr agent rename reviewer --clear
## カスタムステータスラベル
インテグレーションは、意味的な状態を変えずに表示用ステータスラベルを報告できます。
インテグレーションは、ライフサイクル状態を意味的な状態としてのみ報告します。表示のカスタマイズは、ペインメタデータのトークンとして別に追加します。
```bash
herdr pane report-agent w1:p1 \
--source custom:indexer \
--agent docs-bot \
--state working \
--custom-status indexing
--state working
herdr pane report-metadata w1:p1 \
--source custom:indexer-display \
--token summary=indexing
```
`state` は wait、通知、ロールアップを制御します。`custom-status` は表示テキストだけです。
`state` は wait、通知、ロールアップを制御します。`summary` トークンは表示専用で、エージェントサイドバー行では `$summary` として使えます。
エージェントサイドバー行では、`terminal_title` または `terminal_title_stripped` も任意で使えます。どちらもデフォルト行には含まれません。前者は安全性のために正規化された最新の OSC 0/2 ターミナルタイトルを表示し、後者は先頭にある認識済みのアクティビティまたはスピナーのグリフ 1 つと、それに続く空白を除去します。これらの値は Herdr サーバーが所有し、コールドリスタートをまたいで保持されません。また、メタデータのタイトルや意味的なエージェント状態から独立しています。そのため、除去後のテキストが同じなら、スピナーのアニメーションで生のタイトルが変わってもペイン更新は発行されません。
## CLI からエージェントを起動する
+10 -7
View File
@@ -116,6 +116,7 @@ herdr workspace create [--cwd PATH] [--label TEXT] [--env KEY=VALUE] [--focus] [
herdr workspace get <workspace_id>
herdr workspace focus <workspace_id>
herdr workspace rename <workspace_id> <label>
herdr workspace report-metadata <workspace_id> --source ID [--token NAME=VALUE] [--clear-token NAME] [--seq N] [--ttl-ms N]
herdr workspace close <workspace_id>
```
@@ -200,7 +201,6 @@ herdr pane report-agent <pane_id> \
--agent LABEL \
--state idle|working|blocked|unknown \
[--message TEXT] \
[--custom-status TEXT] \
[--seq N] \
[--agent-session-id ID] \
[--agent-session-path PATH]
@@ -219,18 +219,21 @@ herdr pane report-metadata <pane_id> \
[--applies-to-source ID] \
[--title TEXT|--clear-title] \
[--display-agent TEXT|--clear-display-agent] \
[--custom-status TEXT|--clear-custom-status] \
[--state-label STATUS=TEXT] \
[--clear-state-labels] \
[--token NAME=VALUE] \
[--clear-token NAME] \
[--seq N] \
[--ttl-ms N]
```
`STATUS` は `idle`、`working`、`blocked`、`done`、`unknown` のいずれかです。`--agent` は権威あるエージェントラベルに対するガードです。`--applies-to-source` はアクティブなライフサイクル権威ソースに対するガードです。表示名を変えるには `--display-agent` を使ってください。
`STATUS` は `idle`、`working`、`blocked`、`done`、`unknown` のいずれかです。`--agent` と `--applies-to-source` は `--title`、`--display-agent`、`--state-label` だけを保護し、トークンパッチは保護しません。トークンのクリアまたは TTL の更新は報告側が管理します。表示名を変えるには `--display-agent` を使ってください。
メタデータのテキストは保存前に正規化されます。Herdr は前後の空白を取り除き、制御文字を除去し、`--custom-status` を 32 文字に、`--title`、`--display-agent`、各 `--state-label` の値を 80 文字に制限します。正規化後に空になった値は無視されます。
メタデータのテキストは保存前に正規化されます。Herdr は前後の空白を取り除き、制御文字を除去し、`--title`、`--display-agent`、各 `--state-label`、トークンの値を 80 文字に制限します。正規化後に空になったトークン値は、そのキーをクリアします。
`--source` と `--applies-to-source` は 80 文字以下で、ASCII の英字、数字、コロン、ドット、アンダースコア、ハイフンのみを含められます。`--ttl-ms` はメタデータを自動失効させ、`1` から `86400000` ミリ秒の間でなければなりません。置き換え・クリア・ペインのクローズまで残るべきメタデータでは省略してください。`--seq` により、Herdr は同じ `--source` からの古い報告を無視できます。古い報告は API には受理されますが、ペイン状態には無視されます。
`--token` は名前付き表示値を設定し、`--clear-token` は削除します。指定しなかったトークンは変わりません。ペイントークンはエージェントサイドバー行で `$name` として、ワークスペーストークンはスペース行で使えます。TTL は、その呼び出しで更新した各トークンキーに個別に適用されます。
`--source` と `--applies-to-source` は 80 文字以下で、ASCII の英字、数字、コロン、ドット、アンダースコア、ハイフンのみを含められます。`--ttl-ms` はメタデータを自動失効させ、`1` から `86400000` ミリ秒の間でなければなりません。置き換え・クリア・ペインまたはワークスペースのクローズまで残るべきメタデータでは省略してください。`--seq` により、Herdr は同じ `--source` からの古い報告を無視できます。古い報告は API には受理されますが、ペイン状態には無視されます。ペインまたはワークスペースが存続する間、シーケンス付きトークン報告を送れる異なるソースは最大 32 個で、クリアや失効でもその枠は解放されません。
## エージェント
@@ -368,12 +371,12 @@ herdr plugin log list [--plugin ID] [--limit N]
管理されたターミナルペイン:
```bash
herdr plugin pane open --plugin ID --entrypoint ID [--placement overlay|split|tab|zoomed] [--workspace ID] [--target-pane PANE] [--direction right|down] [--cwd PATH] [--env KEY=VALUE] [--focus|--no-focus]
herdr plugin pane open --plugin ID --entrypoint ID [--placement overlay|popup|split|tab|zoomed] [--width SIZE] [--height SIZE] [--workspace ID] [--target-pane PANE] [--direction right|down] [--cwd PATH] [--env KEY=VALUE] [--focus|--no-focus]
herdr plugin pane focus <pane_id>
herdr plugin pane close <pane_id>
```
`plugin pane open` は、プラグインがリンクされ、有効で、現在のプラットフォームと互換であることを要求します。マニフェストで宣言された `[[panes]]` コマンドを Herdr 管理のターミナルペインとして起動します。マニフェストのデフォルトは `overlay` で、アクティブなペインの上に一時的なズームオーバーレイを開きます。分割、新しいタブ、ズームされたペインとして開くこともできます。ターミナル以外のネイティブなプラグインペインは今後の対応面です。
`plugin pane open` は、プラグインがリンクされ、有効で、現在のプラットフォームと互換であることを要求します。マニフェストで宣言された `[[panes]]` コマンドを Herdr 管理のターミナルペインとして起動します。マニフェストのデフォルトは `overlay` で、アクティブなペインの上に一時的なズームオーバーレイを開きます。分割、新しいタブ、ズームされたペイン、またはタブレイアウトを変更しないセッションモーダルな `popup` として開くこともできます。`--width` と `--height` は、外側のポップアップ寸法をターミナルセル数または `80%` のような割合で指定します。省略した寸法はデフォルトでターミナルの半分になり、小さすぎる値はポップアップの最小サイズに制限されます。ポップアップは Herdr ペインではなく、`HERDR_PANE_ID` を受け取らず、pane API やエージェント API に参加しません。ターミナル以外のネイティブなプラグインペインは今後の対応面です。
`--env KEY=VALUE` はプロセスを起動するコマンドで繰り返し指定できます。新しく起動されるプロセスにのみ適用されます。`HERDR_SOCKET_PATH`、`HERDR_BIN_PATH`、`HERDR_ENV`、`HERDR_WORKSPACE_ID`、`HERDR_TAB_ID`、`HERDR_PANE_ID`、`HERDR_PLUGIN_ID`、`HERDR_PLUGIN_ROOT`、`HERDR_PLUGIN_CONFIG_DIR`、`HERDR_PLUGIN_STATE_DIR`、`HERDR_PLUGIN_ENTRYPOINT_ID`、`HERDR_PLUGIN_CONTEXT_JSON` のような Herdr 管理の変数は、呼び出し側が与えた環境変数と衝突した場合も権威を保ちます。
+156 -239
View File
@@ -3,17 +3,17 @@ title: 設定
description: Herdr のキーバインド、テーマ、サイドバーの挙動、通知、高度なオプションを設定します。
---
Herdr は設定ファイルなしで動作します。カスタムキー、テーマ、サイドバー設定、通知、高度な挙動が欲しくなったら追加してください。
Herdr は設定ファイルなしで動作します。キー、テーマ、サイドバーのレイアウト、通知、高度な挙動をカスタマイズしたい場合に追加してください。
特定のキーを探していますか?[設定リファレンス](/ja/docs/config-reference/)に、すべてのキーの型・デフォルト値・許容値が一覧されています。
設定やキーバインドを探していますか?すべてのキー、型、デフォルト値、許容値は[設定リファレンス](/docs/config-reference/)で検索できます。このページでは、セットアップ、一般的なレシピ、リファレンスの一行だけでは説明しきれない設定構造を中心に説明します。
## 設定ファイル
Herdr は次の場所から設定を読み込みます:
```text
Linux macOS: ~/.config/herdr/config.toml
Windows: %APPDATA%\herdr\config.toml
Linux and macOS: ~/.config/herdr/config.toml
Windows: %APPDATA%\herdr\config.toml
```
システム上で解決された設定ファイルのパスは、`herdr --help` で確認できます。
@@ -30,31 +30,14 @@ herdr --default-config
herdr --default-config > ~/.config/herdr/config.toml
```
設定値が無効な場合、Herdr は安全なデフォルトにフォールバックし、起動時に警告を表示します。
設定値が無効な場合、Herdr は安全なデフォルトにフォールバックし、起動時に警告を表示します。
`onboarding` が存在しないか true の場合、Herdr は初回セットアップを表示します。オンボーディングから先へ進むと `onboarding = false` が書き込まれ、設定のインテグレーションタブが開きます。セットアップ後にのフローをスキップしたい場合に設定してください。
`onboarding` が存在しないか true の場合、Herdr は初回セットアップを表示します。オンボーディングから先へ進むと `onboarding = false` が書き込まれ、設定のインテグレーションタブが開きます。セットアップ後にのフローをスキップしたい場合に設定してください。
```toml
onboarding = false
```
## アップデート
Linux と macOS の直接インストールは、デフォルトで安定版アップデートチャンネルを使います。Windows ベータのインストールはデフォルトでプレビューを使い、安定版の Windows リリースが提供されるまで安定版には切り替えられません。
```toml
[update]
channel = "stable"
version_check = true
manifest_check = true
```
`channel = "preview"` を設定すると、`herdr update` は現在の開発ブランチから手動公開されるプレビュービルドをインストールします。Homebrew、mise、Nix のインストールはプレビューチャンネルを無視し、それぞれのパッケージマネージャーでアップデートします。
`version_check = false` を設定すると、新しい Herdr バージョンのバックグラウンドチェックを無効にします。手動の `herdr update` は引き続き設定済みチャンネルを使います。
`manifest_check = false` を設定すると、リモートのエージェント検出マニフェストのバックグラウンドチェックを無効にします。Herdr はバンドルされたマニフェストとローカルオーバーライドを引き続き使います。
## 設定のリロード
`config.toml` を編集した後、実行中のサーバーをリロードします:
@@ -65,27 +48,27 @@ herdr server reload-config
Herdr のグローバルメニューを開いて `reload config` を選ぶこともできます。
リロードは、ペインを再起動することなくほとんどの UI 設定を適用します。起動時のみの設定には引き続き再起動が必要です。
リロードは、ペインを再起動せずにほとんどの UI 設定を適用します。起動時のみの設定には引き続き再起動が必要です。
## ターミナルのデフォルト
新しく作成される対話ペインに Herdr が使う実行ファイルを設定します:
新しく作成される対話ペインに Herdr が使う実行ファイルを設定します:
```toml
[terminal]
default_shell = "nu"
```
未設定または空の場合、Herdr は `$SHELL`、次に `/bin/sh` を使います。これは実行ファイル名またはパスであり、シェルのコマンドラインではありません。既存のペインは再作成されるまで現在のシェルを保ちます。コマンドペインは引き続き `/bin/sh -c` を通して実行され、デタッチされたカスタムコマンドキーバインドは Herdr の既存の `/bin/sh -lc` 経路を使います。
未設定または空の場合、Herdr は `$SHELL`、次に Unix では `/bin/sh`、Windows では PowerShell を使います。これは実行ファイル名またはパスであり、シェルのコマンドラインではありません。既存のペインは再作成されるまで現在のシェルを保ちます。カスタムコマンドキーバインドの文字列は、Unix ではペインコマンドに `/bin/sh -c`、デタッチコマンドに `/bin/sh -lc` を通して実行され、Windows では `cmd.exe /d /c` を通して実行されます。
新しく作成される対話ペインのシェルの起動方法を設定します:
新しく作成される対話ペインのシェルの起動方法を設定します:
```toml
[terminal]
shell_mode = "auto"
```
`shell_mode = "auto"` は macOS でログインシェルを起動するので、`/usr/libexec/path_helper` のようなログイン時のみの PATH 設定や Homebrew のシェル初期化が新しいペインで実行されます。他のプラットフォームでは既存の非ログインシェルの挙動を保ちます。ログインシェル起動を強制するには `"login"` を、オプトアウトするには `"non_login"` を使ってください。コマンドペイン、デタッチされたカスタムコマンドキーバインド、明示的な argv 起動は、既存のコマンド実行経路を保ちます。
`shell_mode = "auto"` は macOS でログインシェルを起動するため、`/usr/libexec/path_helper` のようなログイン時のみの PATH 設定や Homebrew のシェル初期化が新しいペインで実行されます。他のプラットフォームでは既存の非ログインシェルの挙動を保ちます。ログインシェルでの起動を強制するには `"login"` を、無効にするには `"non_login"` を使ってください。コマンドペイン、デタッチされたカスタムコマンドキーバインド、明示的な argv 起動は、既存のコマンド実行経路を保ちます。
新しいペイン、タブ、ワークスペースの作業ディレクトリポリシーを設定します:
@@ -94,7 +77,7 @@ shell_mode = "auto"
new_cwd = "follow"
```
`new_cwd = "follow"` はデフォルトの挙動を保ち、元のペインまたはワークスペースを継承します。元のワークスペースがない場合、Herdr は `$HOME` で始めます。常に `$HOME` で始めるには `"home"` を、Herdr のプロセスディレクトリを使うには `"current"` を、または `"~/Projects"` のような固定パスを使ってください。CLI ソケット API から明示的 `--cwd` 値は引き続き優先されます。
`new_cwd = "follow"` はデフォルトの挙動を保ち、元のペインまたはワークスペースを継承します。元のワークスペースがない場合、Herdr は `$HOME` で起動します。常に `$HOME` で起動するには `"home"` を、Herdr のプロセスディレクトリを使うには `"current"` を、または `"~/Projects"` のような固定パスを使ってください。CLI またはソケット API から明示的に指定された `--cwd` 値は引き続き優先されます。
## Worktree
@@ -105,30 +88,30 @@ new_cwd = "follow"
directory = "~/.herdr/worktrees"
```
Herdr は `<directory>/<repo>/<branch-slug>` の下にチェックアウトを作成します。隣接ディレクトリ方式のチェックアウトにしたい場合は、`~/Projects/herdr-worktrees` のようなディレクトリを設定してください。相対値は、アプリが設定を適用する時点で絶対パス解決されます。
Herdr は `<directory>/<repo>/<branch-slug>` の下にチェックアウトを作成します。隣接ディレクトリ方式のチェックアウトには、`~/Projects/herdr-worktrees` のようなディレクトリを設定してください。相対値は、アプリが設定を適用するときに絶対パス解決されます。
worktree アクションは Git ワークスペースの行から使えます。`New worktree` はチェックアウトを作成し、入力されたブランチが既存なら既存のローカルブランチをチェックアウトし、なければブランチを作成し、新しい Herdr ワークスペースとして開き、元のワークスペースの下にグループ化します。`Open worktree...` はそのリポジトリ既存の Git worktree チェックアウトを一覧します。すでに開いているチェックアウトを選ぶとフォーカスし、閉じているチェックアウトを選ぶと同じグループで開きます。
worktree アクションは Git ワークスペースの行から使えます。`New worktree` はチェックアウトを作成し、入力たブランチがすでに存在する場合は既存のローカルブランチをチェックアウトし、存在しない場合はブランチを作成します。その後、新しい Herdr ワークスペースとして開き、元のワークスペースの下にグループ化します。`Open worktree...` はそのリポジトリにある既存の Git worktree チェックアウトを一覧表示します。すでに開いているチェックアウトを選ぶとそこへフォーカスし、閉じているチェックアウトを選ぶと同じグループで開きます。
グループ化された worktree も通常の Herdr ワークスペースと同じように振る舞います: フォーカス、名前変更、クローズができ、独自のタブとペインを持ちます。親の行は元のワークスペースです。親の行を閉じると Herdr のグループ全体が閉じますが、チェックアウトのフォルダーやブランチは削除されません。
グループ化された worktree も通常の Herdr ワークスペースと同様に動作します。フォーカス、名前変更、クローズができ、それぞれ独自のタブとペインを持ちます。親の行は元のワークスペースです。親の行を閉じると Herdr のグループ全体が閉じますが、チェックアウトのフォルダーやブランチは削除されません。
worktree チェックアウトの削除は明示的す。グループ化された子ワークスペースで `Delete worktree checkout...` を使うと `git worktree remove` が実行されます。Herdr はまず Git に安全な削除を依頼します。チェックアウトに変更済みまたは未追跡のファイルがあって Git が拒否した場合、Herdr は強制削除を実行する前にもう一度確認します。ブランチは削除されません。
worktree チェックアウトの削除は明示的に行います。グループ化された子ワークスペースで `Delete worktree checkout...` を使うと `git worktree remove` が実行されます。Herdr はまず Git に安全な削除を要求します。チェックアウトに変更済みまたは未追跡のファイルがあ Git が拒否した場合、Herdr は強制削除を実行する前にもう一度確認します。ブランチは削除されません。
## リモートアタッチ
リモートアタッチは、デフォルトで一時的なキープアライブフォールバック付きの SSH ブリッジを管理します。
リモートアタッチは、デフォルトで一時的なキープアライブと接続再利用のフォールバックを使って SSH 接続を管理します。
```toml
[remote]
manage_ssh_config = true
```
有効な場合、`herdr --remote` はあなたの `~/.ssh/config` と `/etc/ssh/ssh_config` を最初に include し、その後にフォールバックの `ServerAliveInterval` と `ServerAliveCountMax` の値を加えたプライベートな一時 SSH 設定を書き込みます。あなた自身の SSH キープアライブ設定が優先されます。Herdr が生成する設定を使わずの `ssh` でブリッジを実行するには `manage_ssh_config = false` を設定してください。
有効な場合、`herdr --remote` は最初に `~/.ssh/config` と `/etc/ssh/ssh_config` を取り込み、その後にフォールバックの `ServerAliveInterval` と `ServerAliveCountMax` の値を加えたプライベートな一時 SSH 設定を書き込みます。ユーザー自身のキープアライブ設定が優先されます。Herdr は、最初に認証した接続を再利用するため、アタッチごとにプライベートな OpenSSH コントロールソケットも使います。Herdr が生成した設定やコントロールソケットを使わず、通常の `ssh` でリモートアタッチを実行するには `manage_ssh_config = false` を設定してください。
## キーバインド
プレフィックスの導入ガイドと検証済みのプレフィックスなし構成については、[キーボード](/ja/docs/keyboard/)を参照してください。
プレフィックスの導入ガイドと検証済みのプレフィックスなし構成については、[キーボード](/docs/keyboard/)を参照してください。
Herdr には tmux に似たプレフィックスモードがあります。デフォルトのプレフィックスは `ctrl+b` です。キーバインド文字列は明示的です: `prefix+n` は設定されたプレフィックスを押してから `n` を押すという意味で、`ctrl+alt+n` はターミナルモードの直接ショートカットです。
Herdr には tmux に似たプレフィックスモードがあります。デフォルトのプレフィックスは `ctrl+b` です。キーバインド文字列は明示的です`prefix+n` は設定されたプレフィックスを押してから `n` を押すという意味で、`ctrl+alt+n` はターミナルモードの直接ショートカットです。
小さなキーバインドの上書きは次のようになります:
@@ -145,69 +128,20 @@ navigate_pane_down = "ctrl+j"
split_horizontal = "prefix+minus"
```
デフォルトのキーマップはプレフィックス優先で、シェル、エディタ、tmux、ターミナルアプリから入力を奪いうる直接ショートカットを避けています。主なデフォルトは次のとおりです:
デフォルトのキーマップはプレフィックス優先なので、Herdr がシェル、エディタ、tmux、ターミナルアプリから入力を奪うことはありません。[設定リファレンス](/docs/config-reference/)で `keys.` を検索すると、すべてのアクションとデフォルトのバインドを確認できます。`prefix+?` で開くアプリ内ヘルプパネルには、現在有効なバインドが表示されます。
1 つのアクションに複数のショートカットが必要な場合、バインドを配列にすることもできます:
```toml
[keys]
detach = "prefix+q"
workspace_picker = "prefix+w"
goto = "prefix+g"
new_workspace = "prefix+shift+n"
new_worktree = "prefix+shift+g"
rename_workspace = "prefix+shift+w"
close_workspace = "prefix+shift+d"
navigate_workspace_up = "up"
navigate_workspace_down = "down"
navigate_pane_left = "h"
navigate_pane_down = "j"
navigate_pane_up = "k"
navigate_pane_right = "l"
remote_image_paste = "ctrl+v"
new_tab = "prefix+c"
previous_tab = "prefix+p"
next_tab = "prefix+n"
switch_tab = "prefix+1..9"
rename_tab = "prefix+shift+t"
close_tab = "prefix+shift+x"
copy_mode = "prefix+["
focus_pane_left = "prefix+h"
focus_pane_down = "prefix+j"
focus_pane_up = "prefix+k"
focus_pane_right = "prefix+l"
swap_pane_left = "prefix+shift+h"
swap_pane_down = "prefix+shift+j"
swap_pane_up = "prefix+shift+k"
swap_pane_right = "prefix+shift+l"
cycle_pane_next = "prefix+tab"
cycle_pane_previous = "prefix+shift+tab"
last_pane = ""
split_vertical = "prefix+v"
split_horizontal = "prefix+minus"
close_pane = "prefix+x"
zoom = "prefix+z"
resize_mode = "prefix+r"
toggle_sidebar = "prefix+b"
```
任意のアクションはデフォルトでは未設定です。プレフィックスモードの挙動には `prefix+` で、意図的に直接ショートカットにしたいときは明示的な修飾キーコードでバインドしてください:
```toml
[keys]
previous_workspace = "prefix+shift+left"
next_workspace = "prefix+shift+right"
last_pane = "prefix+tab"
open_worktree = "prefix+shift+o"
remove_worktree = "prefix+alt+d"
next_tab = ["prefix+n", "ctrl+alt+]"]
```
`last_pane` はワークスペースとタブをまたいで最後にフォーカスしていたペインに戻ります。tmux スタイルのペインバインド `prefix+l` がすでに右のペインへのフォーカスに使われているため、デフォルトでは未設定です
任意のアクションはデフォルトでは未設定です。プレフィックスモードの挙動には `prefix+` でバインドし、意図的に直接ショートカットにする場合は明示的な修飾キーコードを使ってください
`remote_image_paste` は `herdr --remote` でのみ有効です。ローカルのクリップボード画像をリモートのペインに送るローカルクライアント側のショートカットです。空文字列に設定すると生キーのショートカットを無効にできます。外側のターミナルが送る paste-image シグナルは引き続き機能します。
キー文字列には、通常のキー、`ctrl+a`、`shift+n`、`alt+1`、`cmd+k` のような修飾キーの組み合わせ、`enter`、`tab`、`esc`、`left`、`right`、`up`、`down` のような特殊キーが使えます。`minus`、`comma`、`ampersand`、`plus`、`backtick` のような名前付き記号も使えます。`n` のような通常の印字可能キーの直接バインドは入力を妨げるため危険です。意図的に直接バインドするのでなければ `prefix+n` を使ってください。`navigate_workspace_*` と `navigate_pane_*` のフィールドはナビゲートモード専用で、`j` や `k` のような通常のキーを使えます。これらには `prefix+`、`esc`、`enter`、`tab`、`shift+tab`、`left`、`right`、修飾なしの `1` から `9` は使えません。左右の矢印キーは、左ペインと右ペインへのナビゲーションの恒久的なエイリアスです。これらのナビゲートモードショートカットは、`focus_pane_down = "prefix+j"` のような一般アクションのバインドから独立しています。両方に同じキーが使われている場合、ナビゲートモードが開いている間はナビゲートモードのショートカットが優先されます。Alt、Cmd/Super、修飾キー付き記号は、ターミナルと tmux の設定に依存します。
キー文字列には、通常のキー、`ctrl+a`、`shift+n`、`alt+1`、`cmd+k` のような修飾キーの組み合わせ、`enter`、`tab`、`esc`、`left`、`right`、`up`、`down` のような特殊キーが使えます。`minus`、`comma`、`ampersand`、`plus`、`backtick` のような名前付き記号も受け付けます。`n` のような通常の印字可能キーの直接バインドはタイピングを妨げるため危険です。意図的に直接バインドしたいのでなければ `prefix+n` を使ってください。`navigate_workspace_*` と `navigate_pane_*` のフィールドはナビゲートモード専用で、`j` `k` のような通常のキーを使えます。これらには `prefix+`、`esc`、`enter`、`tab`、`shift+tab`、`left`、`right`、修飾なしの `1` から `9` は使えません。左右の矢印キーは、左ペイン/右ペインナビゲーションの恒久的なエイリアスです。これらのナビゲートモードショートカットは `focus_pane_down = "prefix+j"` のような一般アクションバインドから独立しています。両方が同じキーを使う場合、ナビゲートモードが開いている間はナビゲートモードのショートカットが優先されます。Alt、Cmd/Super、修飾キー付き記号はターミナルと tmux の設定に依存します。
古いカスタムキーバインドを持っていて新しいデフォルトが欲しい場合は、`herdr config reset-keys` を実行してください。Herdr は `config.toml` をバックアップし、`[keys]` と `[[keys.command]]` を削除し、再起動または `herdr server reload-config` の後に組み込みの v2 デフォルトを使います。
古いカスタムキーバインドを使っていて新しいデフォルトが欲しい場合は、`herdr config reset-keys` を実行してください。Herdr は `config.toml` をバックアップし、`[keys]` `[[keys.command]]` を削除し、再起動または `herdr server reload-config` の後に組み込みの v2 デフォルトを使います。
## インデックス付きジャンプ
@@ -229,11 +163,34 @@ focus_agent = "prefix+alt+1..9"
```toml
[[keys.command]]
key = "prefix+alt+g"
type = "pane"
type = "popup"
command = "lazygit"
description = "run lazygit"
width = "80%"
height = "80%"
```
`type = "popup"` は、タブレイアウトを変更せずにセッションモーダルなポップアップを開きます。
ポップアップは、コマンドが終了するまで Escape を含むすべてのターミナル入力を受け取ります。
`width` と `height` は任意です。省略するとデフォルトの半分のサイズになり、数値ならターミナルセル数、`"80%"` のような文字列ならターミナル領域に対する割合を指定できます。
寸法にはポップアップの枠が含まれ、小さすぎる値は最小サイズに制限されます。
ポップアップコマンドは `HERDR_PANE_ID` を受け取りません。背後のタイルペインには `HERDR_ACTIVE_PANE_ID` を使ってください。
Unix と macOS では、分割やタブを追加せずに一時的なターミナルを開くこともできます:
```toml
[[keys.command]]
key = "prefix+t"
type = "popup"
command = "exec \"${SHELL:-sh}\""
description = "open scratch terminal"
width = "80%"
height = "80%"
```
Windows では、代わりに `command = "powershell.exe -NoLogo"` のようなシェルコマンドを使ってください。
シェルを終了するとポップアップが閉じ、タイル表示に戻ります。
`type = "pane"` は一時的なペインを開き、コマンドの終了時に閉じます。
`type = "shell"` はバックグラウンドでデタッチ実行します。
@@ -248,9 +205,11 @@ command = "example.layout.apply"
description = "apply layout"
```
任意で `description` を指定できます。指定すると、キーバインドヘルプパネル (`prefix+?` で開く) にデフォルトの `'custom command'` ラベルの代わりに表示されます。
任意で `description` を指定できます。指定すると、キーバインドヘルプパネル`prefix+?` で開く)に、デフォルトの `'custom command'` ラベルの代わりに表示されます。
カスタムコマンドは、利用可能な場合に `HERDR_SOCKET_PATH`、`HERDR_BIN_PATH`、`HERDR_ACTIVE_WORKSPACE_ID`、`HERDR_ACTIVE_TAB_ID`、`HERDR_ACTIVE_PANE_ID`、`HERDR_ACTIVE_PANE_CWD` を受け取ります。シェルコマンドは、Herdr が検出できる場合、フォーカス中のペインの作業ディレクトリから実行されます。
カスタムコマンドは、利用可能な場合に `HERDR_SOCKET_PATH`、`HERDR_BIN_PATH`、`HERDR_ACTIVE_WORKSPACE_ID`、`HERDR_ACTIVE_TAB_ID`、`HERDR_ACTIVE_PANE_ID`、`HERDR_ACTIVE_PANE_CWD` を受け取ります。Herdr が検出できる場合、シェルコマンドはフォーカス中のペインの作業ディレクトリから実行されます。
Windows では、カスタムコマンド文字列に `cmd.exe /d /c` が使われるため、環境変数には `%HERDR_BIN_PATH%` 構文を使います。PowerShell 構文を実行するには、たとえば `powershell.exe -NoProfile -Command "..."` のように明示的に呼び出してください。
## テーマ
@@ -261,13 +220,9 @@ description = "apply layout"
name = "catppuccin"
```
組み込みテーマ:
すべての組み込みテーマは、[設定リファレンス](/docs/config-reference/)で `theme.name` を検索してください。Herdr の UI 色をホストターミナルの ANSI パレットに従わせたいときは `terminal` を使ってください。
`catppuccin`、`catppuccin-latte`、`terminal`、`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`。
Herdr の UI 色をホストターミナルの ANSI パレットに従わせたいときは `terminal` を使ってください。
ホストターミナルがライト/ダークの外観変更を報告したときに Herdr が自分の UI テーマを切り替えるようにするには、テーマの自動切り替えを有効にします:
ホストターミナルがライト/ダークの外観変更を報告したときに、Herdr が自身の UI テーマを切り替えるようにするには、テーマの自動切り替えを有効にします:
```toml
[theme]
@@ -277,7 +232,7 @@ light_name = "catppuccin-latte"
dark_name = "catppuccin"
```
`auto_switch` のデフォルトは `false` なので、既存のテーマ設定は手動の挙動を保ちます。`light_name` または `dark_name` を省略すると、Herdr は設定された `name` に対応する組み込みの姉妹テーマが存在すればそれを使います (例: `tokyo-night`/`tokyo-night-day``gruvbox`/`gruvbox-light`)。設定画面での手動のテーマ選択は `auto_switch` 無効にます。
`auto_switch` のデフォルトは `false` なので、既存のテーマ設定は手動の挙動を保ちます。`light_name` または `dark_name` を省略すると、設定された `name` に対応する組み込みの姉妹テーマが存在する場合はそれを使います。たとえば `tokyo-night`/`tokyo-night-day``gruvbox`/`gruvbox-light` です。設定画面でテーマを手動選択すると `auto_switch` 無効になります。
個々の色を上書きできます:
@@ -295,94 +250,112 @@ yellow = "#f9e2af"
## UI とサイドバー
サイドバーは Herdr のメインダッシュボードです。ワークスペース、タブ、ペイン、エージェントの状態を表示します
サイドバーは Herdr のメインダッシュボードです。サイズ、折りたたみモード、Agent パネルの並び順、マウスの挙動、ペインの境界線、その他の表示設定については、[設定リファレンス](/docs/config-reference/)で `ui.` を検索してください
主なオプション:
### サイドバーの行レイアウト
展開されたデスクトップサイドバーでは、`rows` の各内側の配列が 1 行として描画されます。完全なデフォルトレイアウトは次のとおりです:
```toml
[ui]
sidebar_width = 32
sidebar_min_width = 18
sidebar_max_width = 36
mobile_width_threshold = 64
mouse_capture = true
right_click_passthrough_modifier = ""
redraw_on_focus_gained = true
mouse_scroll_lines = 3
confirm_close = true
prompt_new_tab_name = true
pane_borders = true
pane_gaps = true
show_agent_labels_on_pane_borders = false
agent_panel_sort = "spaces"
accent = "cyan"
[ui.sidebar.agents]
row_gap = 0
rows = [
["state_icon", "workspace", "tab"],
["agent"],
]
[ui.sidebar.spaces]
row_gap = 0
rows = [
["state_icon", "workspace"],
["branch", "git_status"],
]
```
`sidebar_min_width` と `sidebar_max_width` は、展開されたサイドバーのリサイズ範囲を桁数で制御します。デフォルトは 18 と 36 です。
Agent の行では、次の組み込みトークンを使えます:
`mobile_width_threshold` は、Herdr がモバイル向けの単一カラムレイアウトを使うターミナル幅の閾値を制御します。デフォルトは 64 桁です。折りたたみ端末、タブレット、幅の広いスマートフォンターミナルでは増やしてください
- `state_icon` — エージェントの意味的な状態を示す色付きアイコン
- `state_text` — `idle`、`working`、`blocked`、`done`、`unknown`。報告された表示ラベルがある場合はそれも含みます。
- `workspace` — ワークスペース名。
- `tab` — 利用可能な場合はタブ名。
- `pane` — 利用可能な場合はペイン名。
- `agent` — 検出または報告されたエージェントの表示名。
- `terminal_title` — 安全性のための正規化後の最新の OSC 0/2 ターミナルタイトル。
- `terminal_title_stripped` — 認識された先頭のアクティビティまたはスピナーのグリフ 1 つと、それに続く空白を除去したターミナルタイトル。
- `$name` — `name` という名前のカスタムペインメタデータ。
エージェントパネルはすべてのスペースをまたいですべてのエージェントを表示します。`agent_panel_sort` には `spaces` または `priority` を指定できます。`workspaces` は `spaces` のエイリアスとして受け付けられます。デフォルトは `spaces` で、エージェントをスペース順にグループ化したまま保ちます。`priority` は注意の優先度順に並べます: blocked、done、working、idle、そして unknown です。同じステータス内では、最近状態が変わったエージェントが先に表示されます。
Space の行では、次の組み込みトークンを使えます:
`confirm_close` はワークスペースを閉じるときに確認を求めるかどうかを制御します。`prompt_new_tab_name` は新しいタブで先にラベルを尋ねるかどうかを制御します
- `state_icon` — Space 内で集約されたエージェント状態を示す色付きアイコン
- `state_text` — Space 内で集約されたエージェント状態のテキスト。
- `workspace` — ワークスペース名。
- `branch` — 利用可能な場合は Git ブランチ。
- `git_status` — 0 でない場合は Git の ahead と behind の件数。
- `$name` — `name` という名前のカスタムワークスペースメタデータ。
URL の command+クリックなど、通常のクリックをターミナルに処理させたい場合は `mouse_capture = false` を設定してください。マウスキャプチャが有効な場合、ターミナルが修飾キー付きクリックを Herdr に送れば、Ctrl+クリックでペインのリンクを開けます。これは macOS も含みます。Herdr がマウス入力をキャプチャしている間、Cmd+クリックは通常のクリックと区別して報告されません。ターミナルネイティブのバイパス経路には、Linux では Shift+Ctrl+クリック、macOS では Shift+Cmd+クリックを使ってください
トークンは設定された順序で描画されます。Herdr は通常、隣接する値を ` · ` で区切り、`state_icon` の後には空白を 1 つ入れます。値がない場合、その値と区切りは表示されません。すべてのトークンに値がない行は表示されません。各レイアウトは最大 16 行、各行は最大 16 トークンです
マウスレポーティング対応のペインアプリの中で、Ctrl+右クリック、ホールド、ドラッグのジェスチャーを Herdr のペインメニューを開く代わりにアプリへ届けたい場合は `right_click_passthrough_modifier = "ctrl"` を設定してください。デフォルトは空で、このパススルーは無効です。対応する修飾キーは `ctrl`、`alt`、`cmd`、`super`、`meta`、`hyper` です。多くのターミナルが Shift+マウスを自分のマウスバイパスのために予約しているため、`shift` は拒否されます。
`row_gap` は、Agent パネルと Space パネルごとに、エントリ間の空白行数を指定します。デフォルトは `0` で、エントリを詰めて表示します。以前の間隔に戻すには `1` に設定します。`rows` で定義したコンテンツ行の間隔には影響しません。連続するインデントされた worktree の子は、1 つの Space グループとして詰めて表示されます。
Herdr に戻ったときの目に見える全画面リフレッシュを避けるには `redraw_on_focus_gained = false` を設定してください。まれに発生する古い/汚れたホストターミナル表示から全再描画で回復できるため、デフォルトは `true` です。
既知のエージェントについて Agent の完全なレイアウトを上書きするには`rows_by_agent` を使います:
マウスホイール 1 ノッチでスクロールするペインのスクロールバック行数を変えるには `mouse_scroll_lines` を設定します。デフォルトは 3 です。マウスレポーティングを要求するペインアプリは引き続きホイールイベントを直接受け取ります。オルタネートスクリーンのアプリにはスクロールするスクロールバックがありません。[スクロールバック](#スクロールバック)を参照してください。
```toml
[ui.sidebar.agents]
rows = [
["state_icon", "agent", "state_text"],
["workspace", "tab"],
]
分割ペインの境界線を消すには `pane_borders = false` を設定します。分割ペインにコンパクトな共有仕切り線を使わせるには `pane_gaps = false` を設定します。境界線が無効な場合、ペインの間隔はペイン間の空白ターミナルセル 1 個になります。ターミナルのセルは通常、幅より高さが大きいため、上下ペイン間の 1 行の間隔は左右ペイン間の 1 桁の間隔より大きく見えることがあります。
[ui.sidebar.agents.rows_by_agent]
claude = [
["state_icon", "agent", "state_text"],
["terminal_title_stripped"],
["workspace", "tab"],
]
```
手動のペインラベルが設定されていないときに、検出されたエージェントラベルを分割ペインの境界線に表示したい場合は `show_agent_labels_on_pane_borders = true` を設定してください
上書きは `rows` を置き換えるもので、拡張するものではありません。上書きのキーには、`claude`、`codex`、`pi` のような大文字と小文字を区別する正規エージェント ID を使います。`claude-code` のような検出エイリアスは使えません。カスタム報告されたエージェントを含め、上書きがないエージェントには `rows` が使われます
カスタム `$name` トークンは動的な値であり、リテラルテキストではありません。トークンをレイアウトに追加してから、スクリプトまたはプラグインで値を報告します:
```toml
[ui.sidebar.agents]
rows = [
["state_icon", "agent", "$model"],
["$summary"],
["workspace", "tab"],
]
```
```bash
herdr pane report-metadata <pane_id> \
--source my-agent-hook \
--token model=opus \
--token summary="reviewing authentication"
```
カスタム Space トークンには、同じ方法で `herdr workspace report-metadata` を使います。報告されていないカスタムトークンは表示されません。メタデータの報告元が提供できるのは値だけで、行やスタイルは選べません。値のクリア、シーケンス、有効期限については、[CLI リファレンス: report metadata](/docs/cli-reference/#panes)を参照してください。
サイドバーの行設定は、展開されたデスクトップサイドバーにだけ適用されます。折りたたみ表示とモバイル表示はコンパクトなレイアウトを保ちます。
## 通知
Herdr は、エージェントが完了したり入力を必要としたりしたときにポップアップ通知を表示できます
Herdr は、バックグラウンドのエージェントが完了したり入力を必要としたりしたときに通知できます:
```toml
[ui.toast]
delivery = "off"
delivery = "herdr"
delay_seconds = 1
[ui.toast.herdr]
position = "bottom-right"
[ui.toast.clipboard]
enabled = true
position = "bottom-center"
```
`delivery = "off"` はポップアップ通知を無効にします。これがデフォルトです
`delivery = "herdr"` は Herdr の UI 内にトーストを表示します。トーストをクリックするか、`keys.open_notification_target` をバインドすると、対象のワークスペース、タブ、ペインにフォーカスします。`ui.toast.herdr.position` には `top-left`、`top-right`、`bottom-left`、`bottom-right` を設定できます。デスクトップの位置は Herdr のフレーム全体を基準とします。
`delivery = "terminal"` は外側のターミナルにデスクトップ通知の表示を依頼します。Herdr は Ghostty、iTerm2、Kitty、WezTerm 向けのターミナル通知エスケープシーケンスを送ります。ローカルのターミナルが通知を所有するため、SSH 越しで便利です。
`delivery = "system"` はローカルのオペレーティングシステムに直接依頼します。macOS では、Herdr は `terminal-notifier` が利用可能ならそれを使い、なければ `/usr/bin/osascript` にフォールバックします。`terminal-notifier` は通知をクリックしたときにホストのターミナルをアクティブにできます。Linux では、Herdr は `notify-send` を使い、`DISPLAY` または `WAYLAND_DISPLAY` を必要とします。
ポップアップ通知はバックグラウンドの注意喚起のためのものです。Herdr はアクティブなタブについてはポップアップを抑制します。
`delay_seconds` は、完了または入力要求のエージェント通知を送る前に待機します。Herdr は、遅延が切れた時点でペインがまだ同じ状態の場合にのみ通知します。即時通知には `0` を設定してください。有効な値は `0` から `3600` です。
クリップボードのフィードバックは、フォアグラウンドのコピー操作を確認するもので、terminal や system の配信では送られないため、別に設定します。コピー完了のポップアップを隠すには `ui.toast.clipboard.enabled = false` を設定してください。クリップボードの位置は `top-left`、`top-center`、`top-right`、`bottom-left`、`bottom-center`、`bottom-right` です。
アプリ内トーストには `herdr`、SSH 越しでも使いやすい外側のターミナル通知には `terminal`、ローカル OS の通知サービスには `system`、ポップアップを無効にするには `off` を選びます。Herdr はアクティブなタブのポップアップを抑制します。位置、遅延の挙動、クリップボードのフィードバック設定については、[設定リファレンス](/docs/config-reference/)で `ui.toast` を検索してください
## サウンド
サウンド通知はデフォルトで有効で、ローカルの Herdr クライアント再生ます。
```toml
[ui.sound]
enabled = true
```
Herdr は、エージェントが完了したときに完了音を、エージェントが入力を必要とするときに注意音を再生します。共有マシンやリモートサーバーでは、明示的に音が欲しいのでなければ `enabled = false` を設定してください。
macOS では、Herdr は `afplay` を使います。Linux では、mp3 対応プレイヤーを順に試します: `paplay`、`pw-play`、`ffplay`、`mpg123`、そして `mpv` です。プレイヤーがない場合、音の再生はスキップされ、Herdr は警告をログに残します。
カスタムサウンドは mp3 ファイルでなければなりません。相対パスは設定ファイルのディレクトリから解決されます。
サウンド通知はローカルの Herdr クライアント再生されます。カスタムサウンドは mp3 ファイルでなければなりません。相対パスは設定ファイルのディレクトリから解決されます。
```toml
[ui.sound]
@@ -391,7 +364,7 @@ done_path = "sounds/done.mp3"
request_path = "sounds/request.mp3"
```
`path` はすべてのサウンド通知にひとつの音を設定します。`done_path` と `request_path` は、完了音と入力要求音だけを上書きします。
`path` はすべてのサウンド通知に 1 つの音を設定します。`done_path` と `request_path` は、完了音と入力要求音だけを上書きします。
エージェント別のサウンド上書きには `default`、`on`、`off` を指定できます。キーには `claude`、`codex`、`devin`、`droid` のような検出されたエージェントラベルを使います。Droid はデフォルトでミュートされています。
@@ -401,124 +374,68 @@ droid = "off"
claude = "on"
```
## スクロールバック
## 高度な設定
新しく作成されるペインのスクロールバックバッファサイズを設定します:
```toml
[advanced]
scrollback_limit_bytes = 10485760
```
既存のペインは、再作成されるまで現在のバッファを保ちます。
ペインは、アプリがプライマリスクリーンに書き込んでいるときにのみスクロールバーを表示します。オルタネートスクリーンに切り替えるフルスクリーンアプリ (vim、htop、`CLAUDE_CODE_NO_FLICKER=1` の Claude Code) はスクロールバックを生成しないため、スクロールバーは表示されず、ホイールイベントはアプリに直接ルーティングされます。アプリ自身のキーや UI でスクロールしてください。
## ペイン画面履歴
デフォルトでは、セッションの完全な再起動はワークスペース、タブ、ペイン、cwd、レイアウト、フォーカスを、ペインの内容を保存せずに復元します。
ペイン画面履歴はデフォルトで無効です。ペイン出力にはシークレット、トークン、プロンプト、コマンド出力が含まれうるため、サーバーの完全な再起動をまたいで Herdr に直近のペイン内容を保存させたいときだけ有効にしてください:
```toml
[experimental]
pane_history = true
```
Settings > Experiments > pane screen history からも切り替えられます。
有効にすると、Herdr は保存したペイン履歴を `session.json` の隣の `session-history.json` に保存します。
ペイン画面履歴が、ライブ永続化、スナップショット復元、エージェントネイティブのセッション復元、ライブハンドオフとどう違うかは[セッション状態と復元](/ja/docs/session-state/)を参照してください。
## ネストされた起動
Herdr は通常、Herdr の中で Herdr を起動しないよう保護しています。
```toml
[experimental]
allow_nested = false
```
ネストされた起動はテスト目的でのみ有効にしてください。
スクロールバックの上限、ネストされた起動、その他の高度な設定や実験的設定については、[設定リファレンス](/docs/config-reference/)を検索してください。ペイン画面履歴を有効にする前に、[セッション状態と復元](/docs/session-state/)を参照してください。このガイドでは、ペインの内容を保存する場合のセキュリティ上のトレードオフを説明しています
## Kitty graphics
Kitty graphics のサポートは実験的です
アタッチされたローカルクライアントでの Kitty graphics の描画は実験的機能で、デフォルトでは無効です:
```toml
[experimental]
kitty_graphics = false
kitty_graphics = true
```
ターミナルの画像挙動をテストしているのでなければ無効のままにしてください。
ターミナルの画像表示をテストする場合にのみ有効にしてください。
## エージェントセッション復元
## Agent セッション復元
Herdr は、Herdr サーバーの再起動後に対応エージェントのペインをネイティブの会話セッションで再起動できます
Herdr はデフォルトで、サーバーの再起動後に対応する Agent の会話を再開します:
```toml
[session]
resume_agents_on_restore = true
```
これはデフォルトで有効です。Herdr が resume するのは、公式 Herdr インテグレーションを通じてネイティブセッション参照を報告したペインだけです。対応する resume ターゲットは Claude Code、Codex、Cursor Agent CLI、GitHub Copilot CLI、Droid、Kimi Code CLI、Qoder CLI、Pi、Hermes Agent、OpenCode、Kilo Code CLI、MastraCode です。未対応、欠落、無効、重複、または古くなったセッション参照は、保存されたペインディレクトリで通常のシェルとして復元されます
セッション参照はローカルの Herdr セッションスナップショットに保存されます。通常のペイン、エージェント、ステータス、イベント出力には表示されません。
エージェントネイティブのセッション復元が、ペイン画面履歴やライブハンドオフとどう違うかは[セッション状態と復元](/ja/docs/session-state/)を参照してください。
公式インテグレーションからの有効なネイティブセッション参照を持つペインだけが再開できます。その他のペインは通常のシェルとして復元されます。対応する Agent と永続化の挙動については、[セッション状態と復元](/docs/session-state/)を参照してください
## IME カーソルトラッキング
フォーカス中のペインがカーソルを隠して独自に描画する場合 — Claude Code、pi、codex、Devin のような AI エージェント TUI でよくあります — 外側のターミナルがカーソルを報告しなくなるため、macOS のネイティブ入力メソッド変換候補ウィンドウの位置を追跡できなくなります。
ペインの `?25l` 要求に関係なく、フォーカス中のペインのカーソルアンカーを外側のターミナルに公開するには `reveal_hidden_cursor_for_cjk_ime = true` を設定します:
macOS では、ハードウェアカーソルを隠す AI Agent TUI によって、ネイティブ入力メソッド変換候補ウィンドウがフォーカス中のペインを追跡できなくなることがあります。これらのペインでカーソルアンカーを表示するには、次のように設定します:
```toml
[experimental]
reveal_hidden_cursor_for_cjk_ime = false
cjk_ime_agents = []
cjk_ime_cursor_shape = "steady_block"
reveal_hidden_cursor_for_cjk_ime = true
cjk_ime_agents = ["claude", "pi", "codex"]
```
有効にすると、カーソルはフォーカス中のペインが報告した位置に表示され続けます。ペインがカーソル位置を報告しない場合、アンカーはペインの左上にフォールバックし、安定した IME ヒントが常に利用できます
`cjk_ime_agents` で対象を限定すると、関係のないアプリケーションに余分なハードウェアカーソルが表示されるのを避けられます。使用できる Agent 名とカーソル形状については、[設定リファレンス](/docs/config-reference/)でこれらのキーを検索してください
`cjk_ime_agents` は任意の許可リストです。空の場合、この表示はどのフォーカス中ペインにも適用されます。空でない場合、フォーカス中ペインの検出エージェントがリスト内の名前のいずれかに一致するときだけ適用されます — 独自にカーソルを描画する AI エージェント TUI でのみ有効にして、素のシェルには影響を与えたくないときに便利です。受け付ける名前: `pi`、`claude`、`codex`、`gemini`、`cursor`、`devin`、`agy`、`cline`、`opencode`、`copilot`、`kimi`、`kiro`、`droid`、`amp`、`grok`、`hermes`、`kilo`、`qodercli`、`qoder`。不明な名前は無視されます。リストに有効な名前がひとつもない場合、この表示は適用されません。
## プレフィックス入力ソースの切り替え
`cjk_ime_cursor_shape` は IME アンカー用に描画される DECSCUSR の形状を制御します。受け付ける値: `block`、`steady_block` (デフォルト)、`underline`、`steady_underline`、`bar`、`steady_bar`。
既存の `[experimental]` ブロックを通じてホットリロードされます。
有効時のトレードオフ: 代わりのカーソルを描画せずにカーソルを隠すアプリ (vim のノーマルモードなど) では、外側のターミナルに余分なハードウェアカーソルが表示されます。特定の TUI に絞るには `cjk_ime_agents` と組み合わせてください。
## プレフィックスでの入力ソース切り替え
macOS では、非 ASCII の入力ソースがアクティブな間、プレフィックスコマンドがホストの入力ソースを通して解釈されるため、プレフィックスモードのコマンドが使いにくいことがあります。
プレフィックスモードがアクティブな間、ホストの入力ソースをシステムの ASCII 対応入力ソースに切り替えるには `switch_ascii_input_source_in_prefix = true` を設定します:
macOS では、プレフィックスコマンドとプレフィックスから起動したモードがアクティブな間、Herdr がシステムの ASCII 対応入力ソースへ一時的に切り替えるようにできます:
```toml
[experimental]
switch_ascii_input_source_in_prefix = false
switch_ascii_input_source_in_prefix = true
```
有効にすると、Herdr はプレフィックスモードに入った後にのみ入力ソースを切り替え、プレフィックスモードの終了時に以前の入力ソースを復元します。この設定は macOS 専用で、他のプラットフォームやシステムの入力ソース切り替えが失敗した場合は何もしません。
Settings > Experiments > switch to ascii input source in prefix (macOS) からも切り替えられます。
ターミナル入力に戻るかテキストフィールドに入ると、Herdr は以前の入力ソースを復元します。この設定は他のプラットフォームには影響しません。
## 環境変数
| 変数 | 目的 |
| --- | --- |
| `HERDR_CONFIG_PATH` | 設定ファイルパスを上書きする。 |
| `HERDR_SESSION` | CLI コマンド名前付きセッションを選択する。 |
| `HERDR_SOCKET_PATH` | 低レベルなソケットパス上書き。 |
| `HERDR_CONFIG_PATH` | 設定ファイルパスを上書きする。 |
| `HERDR_SESSION` | CLI コマンド名前付きセッションを選択する。 |
| `HERDR_SOCKET_PATH` | 低レベルなソケットパス上書きする。 |
| `HERDR_LOG` | ログフィルタリングを設定する。例: `HERDR_LOG=herdr=debug`。 |
| `HERDR_DISABLE_SOUND` | `[ui.sound] enabled = true` でも音の再生を無効にする。 |
## ログ
ログは、起動時の警告、インテグレーションの状態、ソケット API の挙動を診断するときに便利です。
ログは、起動時の警告、インテグレーションの状態、ソケット API の挙動を診断するときに役立ちます。
主なログファイル:
@@ -528,4 +445,4 @@ Settings > Experiments > switch to ascii input source in prefix (macOS) から
~/.config/herdr/herdr-server.log
```
ログは自動的にローテーションされます。問題を報告するときは、現在のログとローテーションされたファイルを含めてください。
ログは自動的にローテーションされます。問題を報告するときは、現在のログとローテーションされた関連ファイルを含めてください。
+1 -1
View File
@@ -19,7 +19,7 @@ Windows プレビューベータでは、プレビューチャンネルをイン
powershell -ExecutionPolicy Bypass -c "irm https://herdr.dev/install.ps1 | iex"
```
インストーラーはプラットフォームに合ったリリースバイナリをダウンロードして PATH 上に配置します。Windows インストーラーはデフォルトでプレビューを使い、そのチャンネルを Herdr の設定に書き込み、バージョン付きインストールフォルダーを使い、`current` ジャンクションを更新します。そのため、アップデート時に実行中の `herdr.exe` を上書きする必要がありません。
インストーラーはプラットフォームに合ったリリースバイナリをダウンロードして PATH 上に配置します。Windows では Herdr が設定を変更せずにデフォルトでプレビューを使います。インストーラーはバージョン付きインストールフォルダーを使い、`current` ジャンクションを更新します。そのため、アップデート時に実行中の `herdr.exe` を上書きする必要がありません。
## Homebrew でインストール
+5 -8
View File
@@ -258,19 +258,16 @@ Herdr は保存された MastraCode スレッドを `mastracode --thread <id>`
## カスタムステータスラベル
インテグレーションは、意味的な状態を変えずに短い表示用ラベルを報告できます。
たとえば、エージェントは意味的には `working` のまま、UI には `indexing` を表示できます。
インテグレーションは、ライフサイクル状態を意味的な状態としてのみ報告します。たとえば、ライフサイクル報告に表示フィールドを加えず、エージェントを `working` として報告します。
```bash
herdr pane report-agent w1:p1 \
--source custom:docs \
--agent docs-bot \
--state working \
--custom-status indexing
--state working
```
Herdr 管理のインテグレーションと並走するユーザーフックは、`report-agent` ではなくメタデータを使うべきです。メタデータは、インテグレーションの `idle`、`working`、`blocked` やセッション復元の権威を奪わずに表示を変えます。`--agent` は、その権威あるエージェントがアクティブな間だけ報告が適用されるように保護します。`--applies-to-source` は、そのライフサイクル権威ソースがアクティブな間だけ報告が適用されるように保護します。`--display-agent` は表示名を変更します。
Herdr 管理のインテグレーションと並走するユーザーフックは、`report-agent` ではなくメタデータを使うべきです。メタデータは、インテグレーションの `idle`、`working`、`blocked` やセッション復元の権威を奪わずに表示を変えます。`--agent` と `--applies-to-source` は表示フィールド (`--title`、`--display-agent`、`--state-label`) だけを保護します。トークンパッチは常に適用され、クリアまたは TTL の更新は報告側が管理します。`--display-agent` は表示名を変更します。
```bash
herdr pane report-metadata "$HERDR_PANE_ID" \
@@ -278,12 +275,12 @@ herdr pane report-metadata "$HERDR_PANE_ID" \
--agent claude \
--title "Refactor auth middleware" \
--display-agent "Claude: auth" \
--custom-status "refactor auth" \
--token summary="refactor auth" \
--state-label working="refactoring auth" \
--ttl-ms 3600000
```
カスタムステータスと状態ラベルは表示専用です。wait、通知、ワークスペースのロールアップは引き続き意味的な状態を使います。
トークンと状態ラベルは表示専用です。wait、通知、ワークスペースのロールアップは引き続き意味的な状態を使います。
## インテグレーション状態のデバッグ
+1 -1
View File
@@ -64,7 +64,7 @@ Herdr はマウスネイティブです。キーバインドをひとつも覚
## コピーモード
`prefix+[` を押すと、フォーカス中のペインでコピーモードに入ります。`h/j/k/l`、`w/b/e`、`{`/`}` で移動し、`v` または Space で選択を開始し、`y` または Enter でコピーし、`q` または Esc でコピーせずに抜けます。マウスのドラッグ選択なら、コピーモードに入らずにそのままコピーできます。
`prefix+[` を押すと、フォーカス中のペインでコピーモードに入ります。`h/j/k/l`、tmux 形式の `w/b/e`、`{`/`}` で移動します。`/` または `?` で前方または後方のリテラル検索を開始し、`n` または `N` で同じ方向または逆方向に繰り返します。クエリに大文字が含まれる場合だけ大文字と小文字を区別します。`v` または Space で選択を開始し、`y` または Enter でコピーし、`q` または Esc でコピーせずに抜けます。Esc は終了する前に、アクティブな選択または検索を消します。コピーモードはペインのプロセスを停止しません。最下部では出力を追従し、履歴へ移動するとその位置を保ちます。マウスのドラッグ選択なら、コピーモードに入らずにそのままコピーできます。
## 何でも変更できる
+25 -2
View File
@@ -264,12 +264,35 @@ Windows クライアントは名前付きパイプに接続します。`HERDR_BI
マニフェストのペイン `placement` のデフォルトは `overlay` で、アクティブなペインの
上に一時的なズームオーバーレイを開き、閉じるときに以前のフォーカスとズームを
復元します。`plugin.pane.open` リクエストは、マニフェストの placement を
`overlay`、`split`、`tab`、`zoomed` で上書きできます。
`overlay`、`popup`、`split`、`tab`、`zoomed` で上書きできます。
プラグインペインは、開いた後は通常の Herdr ペインです。プラグインはソケットや CLI を
`placement = "popup"` は、タイルレイアウトを変更せずにセッションモーダルなターミナルポップアップを開きます。
マニフェストまたは open リクエストで任意の `width` と `height` を指定できます。
省略するとデフォルトの半分のサイズになり、数値なら外側のターミナルセル数、`"80%"` のような文字列ならターミナル領域に対する割合になります。
Escape を含むすべてのターミナル入力を受け取り、コマンドが終了するか `popup.close` リクエストが送られると閉じます。
最小サイズより小さい寸法は最小値に制限されます。
ペインを常に一時的にしたい場合は、プラグインペインのエントリーポイントに placement を直接宣言します:
```toml
[[panes]]
id = "picker"
title = "Picker"
platforms = ["linux", "macos"]
placement = "popup"
width = "80%"
height = 20
command = ["sh", "picker.sh"]
```
split、tab、zoomed、overlay のプラグインペインは、開いた後は通常の Herdr ペインです。プラグインはソケットや CLI を
通じて `pane.move`、`pane.swap`、`pane.resize`、`pane.zoom` といった標準のペイン
API を呼び出せます。ペインがタブやワークスペースをまたいで移動しても、Herdr は
プラグインペインの所有権を元のペインに結び付けたまま維持します。
ポップアップは Herdr ペインではなく、セッションに 1 つだけ存在できるリソースです。
ペイン id を持たず、プラグインのフォーカスコンテキストを変更せず、ペインのライフサイクルイベントを発行せず、pane、layout、永続化、エージェント API に参加しません。
そのプロセスには `HERDR_PANE_ID` が渡されず、背後のタイルペインは `HERDR_PLUGIN_CONTEXT_JSON` から参照できます。
Settings、コピーモード、または別の Herdr モーダルが開いている間にポップアップを開くと `ui_busy` が返り、起動後の `plugin.pane.open` は `ok` を返します。
Windows では、ビルドコマンド、アクションコマンド、イベントコマンドは、素の
コマンドが `PATH` にあれば `npm.cmd`、`bun.cmd`、`pnpm.cmd` のような一般的な
+72 -17
View File
@@ -95,11 +95,13 @@ herdr pane read w1:p2 --source recent --lines 50
| サーバー | `ping`、`server.stop`、`server.reload_config`、`server.agent_manifests`、`server.reload_agent_manifests` |
| 通知 | `notification.show` |
| クライアント | `client.window_title.set`、`client.window_title.clear` |
| ワークスペース | `workspace.create`、`workspace.list`、`workspace.get`、`workspace.focus`、`workspace.rename`、`workspace.close` |
| セッション | `session.snapshot` |
| ワークスペース | `workspace.create`、`workspace.list`、`workspace.get`、`workspace.focus`、`workspace.rename`、`workspace.move`、`workspace.report_metadata`、`workspace.close` |
| Worktree | `worktree.list`、`worktree.create`、`worktree.open`、`worktree.remove` |
| タブ | `tab.create`、`tab.list`、`tab.get`、`tab.focus`、`tab.rename`、`tab.close` |
| ペイン | `pane.split`、`pane.swap`、`pane.move`、`pane.zoom`、`pane.layout`、`pane.process_info`、`pane.neighbor`、`pane.edges`、`pane.focus_direction`、`pane.resize`、`pane.list`、`pane.current`、`pane.get`、`pane.rename`、`pane.send_text`、`pane.send_keys`、`pane.send_input`、`pane.read`、`pane.report_agent`、`pane.report_agent_session`、`pane.report_metadata`、`pane.clear_agent_authority`、`pane.release_agent`、`pane.close`、`pane.wait_for_output` |
| レイアウト | `layout.export`、`layout.apply` |
| タブ | `tab.create`、`tab.list`、`tab.get`、`tab.focus`、`tab.rename`、`tab.move`、`tab.close` |
| ペイン | `pane.split`、`pane.swap`、`pane.move`、`pane.zoom`、`pane.layout`、`pane.process_info`、`pane.neighbor`、`pane.edges`、`pane.focus_direction`、`pane.resize`、`pane.list`、`pane.current`、`pane.get`、`pane.rename`、`pane.send_text`、`pane.send_keys`、`pane.send_input`、`pane.read`、`pane.graphics.info`、`pane.graphics.set`、`pane.graphics.clear`、`pane.graphics.stream`、`pane.report_agent`、`pane.report_agent_session`、`pane.report_metadata`、`pane.clear_agent_authority`、`pane.release_agent`、`pane.close`、`pane.wait_for_output` |
| ポップアップ | `popup.close` |
| レイアウト | `layout.export`、`layout.apply`、`layout.set_split_ratio` |
| エージェント | `agent.list`、`agent.get`、`agent.read`、`agent.explain`、`agent.send`、`agent.rename`、`agent.focus`、`agent.start` |
| イベント | `events.subscribe`、`events.wait` |
| インテグレーション | `integration.install`、`integration.uninstall` |
@@ -107,6 +109,10 @@ herdr pane read w1:p2 --source recent --lines 50
一部の CLI コマンドは、これらのメソッドの便利ラッパーです。たとえば `herdr agent wait` は、エージェントターゲットを解決してからペインのエージェント状態イベントを購読します。
`session.snapshot` は、独自のローカルランタイムキャッシュを持つクライアント向けに、一度限りのブートストラップスナップショットを返します。レスポンスには、バージョン/プロトコルメタデータ、フォーカス中のワークスペース/タブ/ペイン id、ワークスペース、タブ、ペイン、タブレイアウト、エージェントの各レコードが含まれます。これは購読ではありません。取得後はリソースイベントを購読し、そのイベントでローカルキャッシュを更新してください。再接続後やキャッシュが古い可能性がある場合は、`session.snapshot` を再度呼び出します。ワークスペースレコードには、関連付けられた worktree の出自情報も含まれます。リポジトリ全体の worktree 検出には引き続き `worktree.list` を使います。
CLI の `herdr api snapshot` は、クライアントやエージェントが簡単にブートストラップできるよう、現在の `session.snapshot` レスポンスを JSON で出力します。
ペイン制御メソッドは `w1:p1` のような公開ペイン id を使います。スキーマ上 `pane_id` が省略可能なメソッドは、省略時にサーバーのアクティブなフォーカス中ペインを使います。`pane.move` は常に送信元の `pane_id` を要求します。
`pane.send_keys` と `pane.send_input.keys` は Herdr のキーコンボ文字列を受け付けます: 通常の印字可能キー、`enter` や `esc` のような特殊キー、`ctrl+h`、`control+j`、`alt+x`、`shift+tab` のような修飾キーコード、`f1` のようなファンクションキー、`minus` や `plus` のような名前付き記号です。`prefix+` のバインド文字列は受け付けません。
@@ -125,6 +131,35 @@ herdr pane read w1:p2 --source recent --lines 50
`pane.current` は単一の `PaneInfo` を返します。`caller_pane_id` があるときはそのペインを返します。省略時はアクティブなフォーカス中ペインを返します。
ターミナルのスクロール情報を取得できる場合、`PaneInfo` には `scroll` が含まれます:
```json
{
"offset_from_bottom": 12,
"max_offset_from_bottom": 240,
"viewport_rows": 30
}
```
クライアントは `offset_from_bottom == 0` を最下部にいる状態として扱えます。
### 実験的なペイングラフィックス
ペイングラフィックスを使うと、プラグインがペイン上に画像データを配置できます。`[experimental].kitty_graphics = true` の場合にのみ利用でき、それ以外ではすべてのペイングラフィックスメソッドが `feature_disabled` を返します。`pane.graphics.info` はグラフィックスレイヤーを作成せず、接続中クライアントのセルの幅と高さをピクセル単位で返します。`pane.graphics.set` は `data_base64` の `png`、`rgb`、`rgba` データを受け取り、`pane.graphics.clear` はレイヤーを削除します。
```json
{"id":"graphics_info","method":"pane.graphics.info","params":{"pane_id":"w1:p1"}}
{"id":"graphics_set","method":"pane.graphics.set","params":{"pane_id":"w1:p1","format":"png","image_width":800,"image_height":600,"data_base64":"...","placement":{"viewport_col":0,"viewport_row":0,"grid_cols":80,"grid_rows":30}}}
{"id":"graphics_clear","method":"pane.graphics.clear","params":{"pane_id":"w1:p1"}}
```
フレームを繰り返し送る場合は、`pane.graphics.stream` で専用ソケットを開きます。Herdr が `ok` を返した後、フレームごとに 1 つの JSON ヘッダーと正確に `data_length` バイトの生データを送ります。ソケットが閉じるまでストリームがそのペインのグラフィックスレイヤーを所有し、同時に set、clear、stream を要求すると `stream_conflict` を返します。
```json
{"id":"graphics_stream","method":"pane.graphics.stream","params":{"pane_id":"w1:p1"}}
{"format":"png","image_width":800,"image_height":600,"data_length":12345,"placement":{"viewport_col":0,"viewport_row":0,"grid_cols":80,"grid_rows":30}}
```
`pane.layout` は、`workspace_id`、`tab_id`、`zoomed`、外側の `area`、`focused_pane_id`、ペインの矩形、分割の矩形/比率を含むタブレイアウトのスナップショットを返します。`pane.neighbor` と `pane.edges` は同じレイアウトスナップショットを含むので、クライアントは非公開のレイアウト状態なしに次の判断を下せます。
`pane.process_info` は、ペインのシェル pid、利用可能な場合はフォアグラウンドプロセスグループ id、そしてプラットフォームが公開している場合は pid、名前、argv/cmdline、cwd を含むフォアグラウンドプロセスを返します。
@@ -168,6 +203,12 @@ herdr pane read w1:p2 --source recent --lines 50
}
```
`layout.set_split_ratio` は、タブレイアウト内の既存の分割比率を更新します。レスポンスは、更新済みの移植可能な `layout` を含む `type: "layout_split_ratio_set"` です。
```json
{"id":"req_ratio","method":"layout.set_split_ratio","params":{"tab_id":"w1:t1","path":[],"ratio":0.6}}
```
プロセスを起動するメソッドは `env` オブジェクトを受け付けます。Herdr はそのキー/値ペアを新しく起動されるプロセスにのみ適用します。Herdr は管理下のペインプロセスに `HERDR_SOCKET_PATH`、`HERDR_ENV=1`、`HERDR_WORKSPACE_ID`、`HERDR_TAB_ID`、`HERDR_PANE_ID` も注入します。呼び出し側が与えた環境変数と衝突した場合、Herdr 管理の変数が権威を持ちます。
`pane.swap` は方向指定と明示指定の両方の形式をサポートします:
@@ -360,7 +401,7 @@ v1 には Herdr が管理するプラグインストレージ API はありま
{"id":"req_plugin_pane","method":"plugin.pane.open","params":{"plugin_id":"example.board","entrypoint":"board","placement":"zoomed","target_pane_id":"w1:p1","env":{"HERDR_ROLE":"board"},"focus":true}}
```
`plugin.pane.open` は、インストール済みで有効かつプラットフォーム互換のプラグインを要求し、要求されたマニフェストの `[[panes]]` エントリーポイントを argv ベースのターミナルペインとして起動します。マニフェストのペイン `placement` のデフォルトは `overlay` です。リクエストの `placement` は `overlay`、`split`、`tab`、`zoomed` でマニフェストを上書きできます。オーバーレイのペインはアクティブなペインを対象とします。分割とズームのペインは既存のペインを対象とし、タブのペインはワークスペースを対象にできます。ペインは開いた後は通常の Herdr ペインとして振る舞いますが、`plugin.pane.focus` と `plugin.pane.close` はプラグイン API 経由で開かれたペインにのみ作用します。focus は `plugin_pane_focused` を、close は `plugin_pane_closed` を返します。
`plugin.pane.open` は、インストール済みで有効かつプラットフォーム互換のプラグインを要求し、要求されたマニフェストの `[[panes]]` エントリーポイントを argv ベースのターミナルペインとして起動します。マニフェストのペイン `placement` のデフォルトは `overlay` です。リクエストの `placement` は `overlay`、`popup`、`split`、`tab`、`zoomed` でマニフェストを上書きできます。overlay と popup はアクティブなタイルペインを起動コンテキストとして使います。ポップアップターミナルはセッションモーダルで、タブレイアウトを変更しません。任意の `width` と `height` は、外側のサイズをターミナルセル数または `"80%"` のような割合で指定します。省略した寸法はデフォルトでターミナルの半分になり、小さすぎる値は最小サイズに制限されます。ポップアップはペイン id を持たず、`pane.*` とエージェント API の対象外で、ペインのライフサイクルイベントを発行せず、プラグインのフォーカスコンテキストを背後のタイルペインに維持し、そのプロセスへ `HERDR_PANE_ID` を渡しません。起動は `ok` を返し、`popup.close` はアクティブなポップアップを閉じ、ポップアップがない場合は `popup_not_open` を返します。split と zoomed は既存のペインを対象とし、tab はワークスペースを対象にできます。split、tab、zoomed、overlay は通常の Herdr ペインとして振る舞い、`plugin.pane.focus` と `plugin.pane.close` は引き続きそれらのペインに作用します。
## ソケットトランスポート
@@ -415,15 +456,12 @@ Herdr はローカルソケット上の改行区切り JSON を使います。Un
"source": "custom:docs",
"agent": "docs-bot",
"state": "working",
"message": "building docs",
"custom_status": "indexing"
"message": "building docs"
}
}
```
`state` は意味的です。wait、通知、ロールアップに影響します。
`custom_status` は表示用です。意味的な挙動を変えずに `indexing` のような短いアクティビティラベルを表示できます。
`state` は意味的です。wait、通知、ロールアップに影響します。表示専用の値はメタデータで別に報告します。
セッションのみの公式インテグレーションは、`pane.report_agent_session` でネイティブセッション参照を報告します。状態を報告するインテグレーションは、`pane.report_agent` にネイティブセッション参照を含めることもできます。状態に依存しないセッション報告は、wait、通知、ロールアップに影響しません。
@@ -457,6 +495,8 @@ Herdr に保存されたネイティブセッション参照があるとき、`p
`pane.get`、`pane.list`、`agent.get`、`agent.list` は、ペインの PTY を現在制御しているプロセスの cwd を解決できるときに `foreground_cwd` も公開します。既存の `cwd` フィールドは、ラベル、follow-cwd 挙動、復元されたセッション状態に使われるペイン/ワークスペースの cwd のままです。
`PaneInfo` と `AgentInfo` は、任意の `terminal_title` と `terminal_title_stripped` フィールドを公開します。`terminal_title` は、安全性のための正規化を行った最新の OSC 0/2 タイトルです。`terminal_title_stripped` は、先頭にある認識済みのアクティビティまたはスピナーのグリフ 1 つと、それに続く空白を除去します。これらはサーバーが所有する値で、コールドリスタートをまたいで保持されず、メタデータの `title` や意味的なエージェント状態から独立しています。
ユーザーフックが Herdr インテグレーションからライフサイクル状態を奪わずに表示をカスタマイズしたいときは `pane.report_metadata` を使ってください。
```json
@@ -469,26 +509,39 @@ Herdr に保存されたネイティブセッション参照があるとき、`p
"agent": "claude",
"title": "Refactor auth middleware",
"display_agent": "Claude: auth",
"custom_status": "refactor auth",
"state_labels": {
"working": "refactoring auth",
"idle": "ready",
"done": "review ready"
},
"tokens": {
"summary": "refactor auth",
"model": "opus"
},
"ttl_ms": 3600000
}
}
```
メタデータ報告は表示専用です。有効なメタデータは、ペインのタイトル、表示されるエージェント名、コンパクトなアクティビティラベル、可視の状態ラベルを上書きできます。`working`、`blocked`、`idle`、wait、通知、ロールアップは引き続き意味的な状態から得られます。エージェントネイティブのセッション復元は、保存された公式セッション参照から得られます。`agent` は権威あるエージェントラベルに対する任意のガードで、`applies_to_source` アクティブなライフサイクル権威ソースに対する任意のガードです。表示名を変えるには `display_agent` を使います。`state_labels` のキーは `idle`、`working`、`blocked`、`done`、`unknown` のいずれかでなければなりません。ひとつの表示上書きを取り除くには、同じ `source` で `clear_custom_status: true` のようなクリアフィールドを使ってください。
メタデータ報告は表示専用です。有効なメタデータは、ペインのタイトル、表示されるエージェント名、可視の状態ラベル、任意の名前付きトークンを上書きできます。`working`、`blocked`、`idle`、wait、通知、ロールアップは引き続き意味的な状態から得られます。エージェントネイティブのセッション復元は、保存された公式セッション参照から得られます。`agent` は表示フィールドを権威あるエージェントラベルに対して保護する任意のガードで、`applies_to_source` も表示フィールドをアクティブなライフサイクル権威ソースに対して保護します。これらのガードはトークンパッチには適用されません。トークンのクリアと TTL の更新は報告側が管理します。表示名を変えるには `display_agent` を使います。`state_labels` のキーは `idle`、`working`、`blocked`、`done`、`unknown` のいずれかでなければなりません。
表示テキストは保存前に正規化されます。Herdr は前後の空白を取り除き、制御文字を除去し、`custom_status` を 32 文字に、`title`、`display_agent`、各状態ラベルを 80 文字に制限します。正規化後に空になった値は無視されます。
トークンマップはリソースごとのパッチです。文字列はキーを設定し、JSON の `null` はクリアし、省略したキーは変わりません。最後に受理された更新が優先されます。任意の TTL は、その報告で更新した各トークンキーに個別に適用されます。ペイントークンは pane と agent の get/list 応答で公開され、エージェントサイドバー行では `$name` として描画できます。1 回の報告で指定できるトークンキーは最大 16 個、ペインまたはワークスペースが保持できるキーは最大 32 個です。トークン名は 1〜32 文字の ASCII 英数字、アンダースコア、ハイフンに限られます。
ワークスペーストークンも同じ規約を使います:
```json
{"id":"req_3","method":"workspace.report_metadata","params":{"workspace_id":"w1","source":"user:jj","tokens":{"jj_status":"2 changes","old":null},"ttl_ms":5000}}
```
workspace の get/list 応答は結果の `tokens` マップを公開し、スペースサイドバー行では `$jj_status` のような値を描画できます。変更と TTL の失効は、最新のワークスペーススナップショットを含む `workspace.metadata_updated` を発行します。このメタデータイベントは API 購読者に届きますが、プラグインイベントフックは実行しません。
表示テキストは保存前に正規化されます。Herdr は前後の空白を取り除き、制御文字を除去し、`title`、`display_agent`、各状態ラベル、トークン値を 80 文字に制限します。正規化後に空になったトークン値は、そのキーをクリアします。
`source` と `applies_to_source` はソース識別子です。80 文字以下で、ASCII の英字、数字、コロン、ドット、アンダースコア、ハイフンのみを含められます。
短寿命のメタデータには `ttl_ms` を使ってください。`1` から `86400000` ミリ秒の間でなければなりません。置き換え・クリア・ペインのクローズまで残るべきメタデータでは省略します。TTL が切れると、Herdr はそのソースのメタデータを削除し、可視のペイン表示が変わった場合は表示変更イベントを発行します
短寿命のメタデータには `ttl_ms` を使ってください。`1` から `86400000` ミリ秒の間でなければなりません。置き換え・クリア・ペインまたはワークスペースのクローズまで残るべきメタデータでは省略します。表示フィールドは従来どおりソース単位で失効し、呼び出しで更新した各トークンには個別の期限が設定されます。トークンメタデータはサーバー再起動後に復元されません
フックが順不同で更新を送る可能性がある場合は `seq` を使ってください。同じ `source` について、最後に受理されたシーケンス以下のシーケンス番号を持つ報告は、API には受理されますがペイン状態には無視されます。
フックが順不同で更新を送る可能性がある場合は `seq` を使ってください。同じ `source` について、最後に受理されたシーケンス以下のシーケンス番号を持つ報告は、API には受理されますがペイン状態には無視されます。ペインまたはワークスペースが存続する間、シーケンス付きトークン報告を送れる異なるソースは最大 32 個です。クリアや失効でもそのソース枠は解放されません。
## イベント購読
@@ -508,8 +561,10 @@ Herdr に保存されたネイティブセッション参照があるとき、`p
最初のレスポンスは購読の確認応答です。以降の行はプッシュされるイベントです。
ワークスペースのイベント購読には `workspace.created`、`workspace.updated`、`workspace.renamed`、`workspace.closed`、`workspace.focused` があります。ワークスペースイベントは Herdr の UI/ランタイムのライフサイクルを記述します。ワークスペースが worktree グループに属している場合、`workspace.created` は任意の `workspace.worktree` 出自情報を含みます。削除前に Herdr がまだ識別できる場合、`workspace.closed` は最終的な `workspace` スナップショットを含みます。
ペインのイベント購読には `pane.created`、`pane.closed`、`pane.focused`、`pane.moved`、`pane.exited`、`pane.agent_detected`、`pane.output_matched`、`pane.agent_status_changed` があります。
ワークスペースのイベント購読には `workspace.created`、`workspace.updated`、`workspace.metadata_updated`、`workspace.renamed`、`workspace.moved`、`workspace.closed`、`workspace.focused` があります。`workspace.metadata_updated` はプラグインイベントフックを実行せずにトークン変更と TTL 失効を報告します。その他のワークスペースイベントは Herdr の UI/ランタイムのライフサイクルを記述します。ワークスペースが worktree グループに属している場合、`workspace.created` は任意の `workspace.worktree` 出自情報を含みます。`workspace.moved` は、移動した `workspace_id`、要求された `insert_index`、更新済みの順序付き `workspaces` リストを含みます。削除前に Herdr がまだ識別できる場合、`workspace.closed` は最終的な `workspace` スナップショットを含みます。
タブのイベント購読には `tab.created`、`tab.closed`、`tab.focused`、`tab.renamed`、`tab.moved` があります。`tab.moved` は、移動した `tab_id`、`workspace_id`、要求された `insert_index`、そのワークスペースの更新済みの順序付き `tabs` リストを含みます。
ペインのイベント購読には `pane.created`、`pane.updated`、`pane.closed`、`pane.focused`、`pane.moved`、`pane.exited`、`pane.agent_detected`、`pane.output_matched`、`pane.agent_status_changed`、`pane.scroll_changed` があります。ターミナルタイトルの変更は `pane.updated` を発行することがありますが、生のタイトルでスピナーだけが変化し、`terminal_title_stripped` が変わらない場合は発行しません。`pane.scroll_changed` は 1 つの `pane_id` を対象とし、Herdr がスクロールスナップショットの変化を検出するたびに `pane_id`、`workspace_id`、現在の `scroll` 情報を発行します。
レイアウトのイベント購読には `layout.updated` があります。このイベントは 1 つのタブについて更新済みの `PaneLayoutSnapshot` を運びます。`session.snapshot` でブートストラップするクライアントは、同じ `workspace_id` と `tab_id` のキャッシュ済みレイアウトを置き換えてください。
worktree のイベント購読には `worktree.created`、`worktree.opened`、`worktree.removed` があります。worktree イベントは Git チェックアウトのライフサイクルを記述します。`worktree.created` は開かれた `workspace` と作成された `worktree` を含みます。`worktree.opened` は対象の `workspace`、開かれた `worktree`、`already_open` を含みます。`worktree.removed` は `workspace_id`、削除された `worktree`、`forced` を含みます。
@@ -26,6 +26,26 @@ OS、外側のターミナル名とバージョン、ローカルまたはリモ
長期サポート版 Linux ディストリビューションの古いターミナルパッケージで特に発生します。確認済みの境界キャプチャと上流参照は [Herdr issue #1116](https://github.com/ogulcancelik/herdr/issues/1116) を参照してください。現在のターミナルでも発生する場合は、正確なバージョンと Herdr の外でも発生するかを報告してください。
## Option+Left または Option+Right を押すと `;3D` または `;3C` が入力される
ターミナルは一般に、Alt+Left と Alt+Right を標準の修飾付き矢印シーケンス `ESC[1;3D` と `ESC[1;3C` として送信します。macOS では、まず外側のターミナルで Option を Alt として扱うよう設定する必要があります。シェルがこれらのシーケンスを割り当てていない場合、zsh は残りの文字を `;3D` または `;3C` と表示することがあります。これは kitty、Alacritty、その他のターミナルで発生する可能性があります。Herdr と tmux はどちらも元の修飾付き矢印入力を保持します。
すべてのターミナルとネストしたシェルで修飾付き矢印を単語移動として使う場合は、zsh のバインドを明示的に追加します:
```zsh
bindkey $'\e[1;3D' backward-word
bindkey $'\e[1;3C' forward-word
```
kitty の外では動作するのに Herdr 内では動作しないことがあります。これは kitty の自動 zsh インテグレーションが、kitty が直接起動したシェルにだけこれらのバインドを追加し、ターミナルマルチプレクサーが起動したシェルには追加しないためです。kitty の[手動シェルインテグレーション手順](https://sw.kovidgoyal.net/kitty/shell-integration/#manual-shell-integration)に従うか、シェルへ届く前に `kitty.conf` でキーを割り当ててください:
```text
map alt+left send_text all \x1bb
map alt+right send_text all \x1bf
```
ターミナルアプリケーションが Alt+Left と Alt+Right を直接使用する場合があるため、Herdr は修飾付き矢印を意図的に書き換えません。調査の詳細は [Herdr issue #1370](https://github.com/ogulcancelik/herdr/issues/1370) を参照してください。
## Herdr を更新したのに実行中のセッションが古い
バイナリを更新しても、互換性のある実行中サーバーは自動で置き換わらないことがあります。`herdr status` を確認してください。更新済みサーバーを起動するには、セッションを停止して Herdr を再起動します:
+3 -3
View File
@@ -15,7 +15,7 @@ Windows 上の Herdr は、Herdr が本来前提としていた Unix の PTY モ
powershell -ExecutionPolicy Bypass -c "irm https://herdr.dev/install.ps1 | iex"
```
Windows ベータビルドはプレビューチャンネルでのみ提供されます。Windows インストーラーはデフォルトでプレビューを使い、Herdr の設定に `channel = "preview"` を書き込み、リリースを `%USERPROFILE%\.herdr\packages\standalone\releases` に保存し、`%LOCALAPPDATA%\Programs\Herdr\bin` を現在のリリースに向け、実行中のプロセスがアップデートを妨げないよう少数の古いリリースを保持します。
Windows ベータビルドはプレビューチャンネルでのみ提供されます。Windows では Herdr が設定を変更せずにデフォルトでプレビューを使います。インストーラーはリリースを `%USERPROFILE%\.herdr\packages\standalone\releases` に保存し、`%LOCALAPPDATA%\Programs\Herdr\bin` を現在のリリースに向け、実行中のプロセスがアップデートを妨げないよう少数の古いリリースを保持します。
内部ベータテスト向けに、`HERDR_MANIFEST_URL` でインストーラーを Herdr の安定版/プレビューマニフェストではなくカスタムマニフェストに向けられます。
@@ -61,9 +61,9 @@ Kitty graphics は実験的なままで、まだ Windows でのサポートを
### カーソル描画
Windows のターミナルは ConPTY 経由で Herdr を実行するため、フルスクリーン再描画中にネイティブの端末カーソルがちらついたり、ジャンプしたり、古い位置を一瞬表示したりすることがあります。Herdr のデフォルト `host_cursor = "auto"` は、Windows では Herdr のカーソルを端末セルの内容として描画し、Linux と macOS ではネイティブの端末カーソルを使い続けます。Windows でのトレードオフは、外側ターミナルのネイティブな点滅、形状、カーソル色の代わりに、Herdr 内で安定した非点滅カーソルを表示することです。
Windows のターミナルは ConPTY 経由で Herdr を実行するため、フルスクリーン再描画中にネイティブの端末カーソルがちらついたり、ジャンプしたり、古い位置を一瞬表示したりすることがあります。Herdr のデフォルト `host_cursor = "auto"` は、ネイティブ Windows ビルドと WSL では Herdr のカーソルを端末セルの内容として描画し、それ以外の Linux と macOS ではネイティブの端末カーソルを使い続けます。Windows でのトレードオフは、外側ターミナルのネイティブな点滅、形状、カーソル色の代わりに、Herdr 内で安定した非点滅カーソルを表示することです。
Windows で外側ターミナルのカーソルに戻すには、次を設定してください:
ネイティブ Windows または WSL で外側ターミナルのカーソルに戻すには、次を設定してください:
```toml
[ui]
+1 -1
View File
@@ -64,7 +64,7 @@ The full keymap and the binding syntax live in the [keybinding reference](/docs/
## Copy mode
Press `prefix+[` to enter copy mode for the focused pane. Use `h/j/k/l`, `w/b/e`, `{`/`}`, `PageUp`/`PageDown`, `ctrl+b`/`ctrl+f`, and `ctrl+u`/`ctrl+d` to move, `v` or Space to start a selection, `y` or Enter to copy it, and `q` or Esc to leave without copying. The configured prefix keeps its normal meaning in copy mode; with the default prefix, `ctrl+b` enters prefix mode instead of paging up, so use a different prefix if you want `ctrl+b` for copy-mode page-up. Mouse drag-select copies without entering copy mode at all.
Press `prefix+[` to enter copy mode for the focused pane. Use `h/j/k/l`, tmux-style `w/b/e`, `{`/`}`, `PageUp`/`PageDown`, `ctrl+b`/`ctrl+f`, and `ctrl+u`/`ctrl+d` to move. Press `/` or `?` for forward or backward literal search, then `n` or `N` to repeat in the same or opposite direction. Search is case-insensitive unless the query contains an uppercase letter. Use `v` or Space to start a selection, `y` or Enter to copy it, and `q` or Esc to leave without copying. Esc clears an active selection or search before exiting. Copy mode does not pause the pane process: output remains live, follows at the bottom, and stays pinned when you navigate into history. The configured prefix keeps its normal meaning in copy mode; with the default prefix, `ctrl+b` enters prefix mode instead of paging up, so use a different prefix if you want `ctrl+b` for copy-mode page-up. Mouse drag-select copies without entering copy mode at all.
## Change anything
+34 -5
View File
@@ -259,12 +259,41 @@ while Windows clients connect to a named pipe. CLI calls through
Manifest pane `placement` defaults to `overlay`, which opens a temporary zoomed
overlay over the active pane and restores the previous focus and zoom when it
closes. A `plugin.pane.open` request can override the manifest placement with
`overlay`, `split`, `tab`, or `zoomed`.
`overlay`, `popup`, `split`, `tab`, or `zoomed`.
Plugin panes are normal Herdr panes after they open. Plugins can call standard
pane APIs such as `pane.move`, `pane.swap`, `pane.resize`, and `pane.zoom`
through the socket or CLI; Herdr keeps plugin pane ownership attached to the
underlying pane when it moves across tabs or workspaces.
`placement = "popup"` opens a session-modal terminal popup without changing the
tiled layout. It accepts optional `width` and `height` fields in the manifest or
open request; omit them for the default half-size popup, use numbers for outer
terminal-cell dimensions, or use strings like `"80%"` for a percentage of the
terminal area. It receives all terminal input, including Escape, and closes
when the command exits or a `popup.close` request is sent. Dimensions smaller
than the popup minimum are clamped.
Declare the placement directly on a plugin pane entrypoint when the pane should
always be transient:
```toml
[[panes]]
id = "picker"
title = "Picker"
platforms = ["linux", "macos"]
placement = "popup"
width = "80%"
height = 20
command = ["sh", "picker.sh"]
```
Split, tab, zoomed, and overlay plugin panes are normal Herdr panes after they
open. Plugins can call standard pane APIs such as `pane.move`, `pane.swap`,
`pane.resize`, and `pane.zoom` through the socket or CLI; Herdr keeps plugin
pane ownership attached to the underlying pane when it moves across tabs or
workspaces. A popup is a singleton session resource rather than a Herdr pane:
it has no pane ID, does not change plugin focus context, emits no pane lifecycle
events, and does not participate in pane, layout, persistence, or agent APIs.
Its process does not receive `HERDR_PANE_ID`; the underlying tiled pane remains
available through `HERDR_PLUGIN_CONTEXT_JSON`.
Opening a popup returns `ui_busy` while Settings, Copy mode, or another Herdr
modal is active, and `plugin.pane.open` returns an `ok` result after launch.
On Windows, build commands, action commands, and event commands resolve common
`PATHEXT` shims such as `npm.cmd`, `bun.cmd`, and `pnpm.cmd` when the bare
+67 -20
View File
@@ -100,10 +100,11 @@ Raw socket method names use dot notation:
| Notification | `notification.show` |
| Client | `client.window_title.set`, `client.window_title.clear` |
| Session | `session.snapshot` |
| Workspace | `workspace.create`, `workspace.list`, `workspace.get`, `workspace.focus`, `workspace.rename`, `workspace.move`, `workspace.close` |
| Workspace | `workspace.create`, `workspace.list`, `workspace.get`, `workspace.focus`, `workspace.rename`, `workspace.move`, `workspace.report_metadata`, `workspace.close` |
| Worktree | `worktree.list`, `worktree.create`, `worktree.open`, `worktree.remove` |
| Tab | `tab.create`, `tab.list`, `tab.get`, `tab.focus`, `tab.rename`, `tab.move`, `tab.close` |
| Pane | `pane.split`, `pane.swap`, `pane.move`, `pane.zoom`, `pane.layout`, `pane.process_info`, `pane.neighbor`, `pane.edges`, `pane.focus_direction`, `pane.resize`, `pane.list`, `pane.current`, `pane.get`, `pane.rename`, `pane.send_text`, `pane.send_keys`, `pane.send_input`, `pane.read`, `pane.report_agent`, `pane.report_agent_session`, `pane.report_metadata`, `pane.clear_agent_authority`, `pane.release_agent`, `pane.close`, `pane.wait_for_output` |
| Pane | `pane.split`, `pane.swap`, `pane.move`, `pane.zoom`, `pane.layout`, `pane.process_info`, `pane.neighbor`, `pane.edges`, `pane.focus_direction`, `pane.resize`, `pane.list`, `pane.current`, `pane.get`, `pane.rename`, `pane.send_text`, `pane.send_keys`, `pane.send_input`, `pane.read`, `pane.graphics.info`, `pane.graphics.set`, `pane.graphics.clear`, `pane.graphics.stream`, `pane.report_agent`, `pane.report_agent_session`, `pane.report_metadata`, `pane.clear_agent_authority`, `pane.release_agent`, `pane.close`, `pane.wait_for_output` |
| Popup | `popup.close` |
| Layout | `layout.export`, `layout.apply`, `layout.set_split_ratio` |
| Agent | `agent.list`, `agent.get`, `agent.read`, `agent.explain`, `agent.send`, `agent.rename`, `agent.focus`, `agent.start` |
| Events | `events.subscribe`, `events.wait` |
@@ -162,6 +163,31 @@ pane.
Clients can treat `offset_from_bottom == 0` as at-bottom state.
### Experimental pane graphics
Pane graphics let a plugin place image data over a pane. They are available
only when `[experimental].kitty_graphics = true`; otherwise every pane graphics
method returns `feature_disabled`. Calling `pane.graphics.info` returns the
attached client's cell width and height in pixels without creating a graphics
layer. `pane.graphics.set` accepts `png`, `rgb`, or `rgba` data in `data_base64`,
and `pane.graphics.clear` removes the layer.
```json
{"id":"graphics_info","method":"pane.graphics.info","params":{"pane_id":"w1:p1"}}
{"id":"graphics_set","method":"pane.graphics.set","params":{"pane_id":"w1:p1","format":"png","image_width":800,"image_height":600,"data_base64":"...","placement":{"viewport_col":0,"viewport_row":0,"grid_cols":80,"grid_rows":30}}}
{"id":"graphics_clear","method":"pane.graphics.clear","params":{"pane_id":"w1:p1"}}
```
For repeated frames, open a dedicated socket with `pane.graphics.stream`. After
Herdr replies with `ok`, send one JSON header and then exactly `data_length` raw
bytes per frame. A stream owns that pane's graphics layer until the socket
closes; concurrent set, clear, or stream requests return `stream_conflict`.
```json
{"id":"graphics_stream","method":"pane.graphics.stream","params":{"pane_id":"w1:p1"}}
{"format":"png","image_width":800,"image_height":600,"data_length":12345,"placement":{"viewport_col":0,"viewport_row":0,"grid_cols":80,"grid_rows":30}}
```
`pane.layout` returns the tab layout snapshot with `workspace_id`, `tab_id`,
`zoomed`, outer `area`, `focused_pane_id`, pane rects, and split rects/ratios.
`pane.neighbor` and `pane.edges` include that same layout snapshot so clients
@@ -479,12 +505,20 @@ Open a managed terminal UI:
`plugin.pane.open` requires an installed, enabled, platform-compatible plugin,
then launches the requested manifest `[[panes]]` entrypoint as an argv-backed
terminal pane. Manifest pane `placement` defaults to `overlay`; request
`placement` overrides the manifest with `overlay`, `split`, `tab`, or `zoomed`.
Overlay panes target the active pane. Split and zoomed panes target an existing
pane; tab panes can target a workspace. The pane
behaves like a normal Herdr pane, but `plugin.pane.focus` and
`plugin.pane.close` only operate on panes opened through the plugin API. Focus
returns `plugin_pane_focused`; close returns `plugin_pane_closed`.
`placement` overrides the manifest with `overlay`, `popup`, `split`, `tab`, or
`zoomed`. Overlay and popup placements use the active tiled pane as launch
context. Popup terminals are session-modal and do not change the tab layout;
optional `width` and `height` fields set their outer size as terminal cells or
percentages such as `"80%"`. Omitted dimensions default to half the terminal
size, with too-small values clamped to the popup minimum. A popup has no pane
ID, remains outside all `pane.*` and agent APIs, emits no pane lifecycle events,
leaves plugin focus context on the underlying tiled pane, and does not export
`HERDR_PANE_ID` to its process. Popup launch returns `ok`; `popup.close` closes
the active popup and returns
`popup_not_open` when none exists. Split and zoomed panes target an existing
pane; tab panes can target a workspace. Split, tab, zoomed, and overlay panes
behave like normal Herdr panes, and `plugin.pane.focus` and `plugin.pane.close`
continue to operate on those panes.
## Socket transport
@@ -542,15 +576,12 @@ Integrations report agent state with `pane.report_agent`.
"source": "custom:docs",
"agent": "docs-bot",
"state": "working",
"message": "building docs",
"custom_status": "indexing"
"message": "building docs"
}
}
```
`state` is semantic. It affects waits, notifications, and rollups.
`custom_status` is visual. It can show a short activity label like `indexing` without changing semantic behavior.
`state` is semantic. It affects waits, notifications, and rollups. Report display-only values separately through metadata.
Session-only official integrations report native session references with `pane.report_agent_session`. State-reporting integrations can still include native session references in `pane.report_agent`. State-independent session reports do not affect waits, notifications, or rollups.
@@ -584,6 +615,8 @@ If no native session reference is stored, the field is omitted.
`pane.get`, `pane.list`, `agent.get`, and `agent.list` also expose `foreground_cwd` when Herdr can resolve the cwd of the process currently controlling the pane PTY. The existing `cwd` field remains the pane/workspace cwd used for labels, follow-cwd behavior, and restored session state.
`PaneInfo` and `AgentInfo` expose optional `terminal_title` and `terminal_title_stripped` fields. `terminal_title` is the latest OSC 0/2 title after safety normalization. `terminal_title_stripped` removes one recognized leading activity or spinner glyph and following whitespace. These server-owned values are ephemeral across a cold restart and are independent of the metadata `title` and semantic agent state.
Use `pane.report_metadata` when a user hook wants to customize presentation without taking over lifecycle state from a Herdr integration.
```json
@@ -596,26 +629,39 @@ Use `pane.report_metadata` when a user hook wants to customize presentation with
"agent": "claude",
"title": "Refactor auth middleware",
"display_agent": "Claude: auth",
"custom_status": "refactor auth",
"state_labels": {
"working": "refactoring auth",
"idle": "ready",
"done": "review ready"
},
"tokens": {
"summary": "refactor auth",
"model": "opus"
},
"ttl_ms": 3600000
}
}
```
Metadata reports are display-only. Valid metadata can override the pane title, displayed agent name, compact activity label, and visible state labels. `working`, `blocked`, `idle`, waits, notifications, and rollups still come from semantic state. Native session restore comes from stored official session references. `agent` is an optional guard for the authoritative agent label; `applies_to_source` is an optional guard for the active lifecycle authority source. Use `display_agent` to change the visible name. `state_labels` keys must be `idle`, `working`, `blocked`, `done`, or `unknown`. Use clear fields such as `clear_custom_status: true` with the same `source` to remove one presentation override.
Metadata reports are display-only. Valid metadata can override the pane title, displayed agent name, visible state labels, and arbitrary named tokens. `working`, `blocked`, `idle`, waits, notifications, and rollups still come from semantic state. Native session restore comes from stored official session references. `agent` is an optional guard for presentation fields against the authoritative agent label; `applies_to_source` similarly guards presentation fields against the active lifecycle authority source. These guards do not apply to token patches: token reporters own clearing and TTL refresh. Use `display_agent` to change the visible name. `state_labels` keys must be `idle`, `working`, `blocked`, `done`, or `unknown`.
Presentation text is normalized before storage. Herdr trims surrounding whitespace, removes control characters, caps `custom_status` at 32 characters, and caps `title`, `display_agent`, and each state label at 80 characters. Empty normalized values are ignored.
Token maps are per-resource patches. A string sets a key, JSON `null` clears it, and omitted keys remain unchanged. The latest accepted update wins. Optional TTL applies independently to token keys updated by that report. Pane tokens are exposed by pane and agent get/list responses and can be rendered as `$name` in Agent sidebar rows. A report may mention at most 16 token keys, and a pane or workspace may retain at most 32 keys. Token names are 132 ASCII letters, digits, underscores, or hyphens.
Workspace tokens use the same contract:
```json
{"id":"req_3","method":"workspace.report_metadata","params":{"workspace_id":"w1","source":"user:jj","tokens":{"jj_status":"2 changes","old":null},"ttl_ms":5000}}
```
Workspace get/list responses expose the resulting `tokens` map, and Space sidebar rows can render values such as `$jj_status`. Changes and TTL expiry emit `workspace.metadata_updated` with the latest workspace snapshot. This metadata event is available to API subscribers but does not invoke plugin event hooks.
Presentation text is normalized before storage. Herdr trims surrounding whitespace, removes control characters, and caps `title`, `display_agent`, each state label, and token values at 80 characters. Empty normalized token values clear that key.
`source` and `applies_to_source` are source identifiers. They must be 80 characters or fewer and may contain only ASCII letters, digits, colon, dot, underscore, and hyphen.
Use `ttl_ms` for short-lived metadata. It must be between `1` and `86400000` milliseconds. Omit `ttl_ms` for metadata that should stay until replaced, cleared, or the pane closes. When the TTL expires, Herdr removes that source's metadata and emits a presentation change if the visible pane presentation changed.
Use `ttl_ms` for short-lived metadata. It must be between `1` and `86400000` milliseconds. Omit `ttl_ms` for metadata that should stay until replaced, cleared, or the pane/workspace closes. Presentation fields retain their existing source-scoped expiry behavior; each token updated by the call receives its own deadline. Token metadata is not restored after a server restart.
Use `seq` when a hook may send updates out of order. For the same `source`, reports with a sequence number less than or equal to the last accepted sequence are accepted by the API but ignored by the pane state.
Use `seq` when a hook may send updates out of order. For the same `source`, reports with a sequence number less than or equal to the last accepted sequence are accepted by the API but ignored by the pane state. A pane or workspace accepts sequenced token reports from at most 32 distinct sources during its lifetime; clearing or expiry does not release those source slots.
## Event subscriptions
@@ -635,14 +681,15 @@ Subscribe to events when you need a long-lived stream:
The first response acknowledges the subscription. Later lines are pushed events.
Workspace event subscriptions include `workspace.created`, `workspace.updated`, `workspace.renamed`, `workspace.moved`, `workspace.closed`, and `workspace.focused`. Workspace events describe Herdr UI/runtime lifecycle. `workspace.created` includes optional `workspace.worktree` provenance when the workspace belongs to a worktree group. `workspace.moved` includes the moved `workspace_id`, requested `insert_index`, and updated ordered `workspaces` list. `workspace.closed` includes a final `workspace` snapshot when Herdr can still identify it before removal.
Workspace event subscriptions include `workspace.created`, `workspace.updated`, `workspace.metadata_updated`, `workspace.renamed`, `workspace.moved`, `workspace.closed`, and `workspace.focused`. `workspace.metadata_updated` reports token changes and TTL expiry without invoking plugin event hooks. Other workspace events describe Herdr UI/runtime lifecycle. `workspace.created` includes optional `workspace.worktree` provenance when the workspace belongs to a worktree group. `workspace.moved` includes the moved `workspace_id`, requested `insert_index`, and updated ordered `workspaces` list. `workspace.closed` includes a final `workspace` snapshot when Herdr can still identify it before removal.
Tab event subscriptions include `tab.created`, `tab.closed`, `tab.focused`,
`tab.renamed`, and `tab.moved`. `tab.moved` includes the moved `tab_id`,
`workspace_id`, requested `insert_index`, and updated ordered `tabs` list for
that workspace.
Pane event subscriptions include `pane.created`, `pane.closed`, `pane.focused`,
Pane event subscriptions include `pane.created`, `pane.updated`, `pane.closed`, `pane.focused`,
`pane.moved`, `pane.exited`, `pane.agent_detected`,
`pane.output_matched`, `pane.agent_status_changed`, and `pane.scroll_changed`.
Terminal-title changes can emit `pane.updated`, but spinner-only raw-title changes do not emit it when `terminal_title_stripped` is unchanged.
`pane.scroll_changed` is scoped to one `pane_id` and emits `pane_id`,
`workspace_id`, and the current `scroll` metrics whenever Herdr observes a
changed scroll snapshot.
@@ -26,6 +26,26 @@ Update the outer terminal to a version containing its upstream fix:
This is especially common with older terminal packages from long-term-support Linux distributions. See [Herdr issue #1116](https://github.com/ogulcancelik/herdr/issues/1116) for the confirmed boundary captures and upstream references. If the problem remains on a current terminal version, report the exact terminal version and whether it also happens outside Herdr.
## Option+Left or Option+Right inserts `;3D` or `;3C`
Terminals commonly send Alt+Left and Alt+Right as the standard modified-arrow sequences `ESC[1;3D` and `ESC[1;3C`. On macOS, the outer terminal must first be configured to treat Option as Alt. If the shell does not bind these sequences, zsh may display their remaining characters as `;3D` or `;3C`. This can happen with kitty, Alacritty, and other terminals; Herdr and tmux both preserve the original modified-arrow input.
Add explicit zsh bindings if you want modified arrows to perform word navigation in every terminal and nested shell:
```zsh
bindkey $'\e[1;3D' backward-word
bindkey $'\e[1;3C' forward-word
```
Kitty can appear to work differently outside Herdr because its automatic zsh integration adds these bindings only to shells started directly by kitty, not shells created by terminal multiplexers. Follow kitty's [manual shell integration instructions](https://sw.kovidgoyal.net/kitty/shell-integration/#manual-shell-integration), or map the keys in `kitty.conf` before they reach the shell:
```text
map alt+left send_text all \x1bb
map alt+right send_text all \x1bf
```
Herdr deliberately does not rewrite modified arrows because terminal applications may use Alt+Left and Alt+Right directly. See [Herdr issue #1370](https://github.com/ogulcancelik/herdr/issues/1370) for the investigation.
## Herdr updated, but the running session is still old
Updating the binary does not always replace a compatible server that is already running. Check `herdr status`. To start the updated server, stop the session and launch Herdr again:
+3 -3
View File
@@ -15,7 +15,7 @@ Install native Windows beta builds with PowerShell:
powershell -ExecutionPolicy Bypass -c "irm https://herdr.dev/install.ps1 | iex"
```
Windows beta builds ship only through the preview channel. The Windows installer defaults to preview, writes `channel = "preview"` to Herdr's config, stores releases under `%USERPROFILE%\.herdr\packages\standalone\releases`, points `%LOCALAPPDATA%\Programs\Herdr\bin` at the current release, and keeps a small number of older releases so running processes do not block updates.
Windows beta builds ship only through the preview channel. Herdr defaults to preview on Windows without changing your config. The installer stores releases under `%USERPROFILE%\.herdr\packages\standalone\releases`, points `%LOCALAPPDATA%\Programs\Herdr\bin` at the current release, and keeps a small number of older releases so running processes do not block updates.
For internal beta testing, `HERDR_MANIFEST_URL` can point the installer at a custom manifest instead of Herdr's stable or preview manifest.
@@ -62,9 +62,9 @@ Kitty graphics remains experimental and is not claimed as Windows-supported yet.
### Cursor rendering
Windows terminals run Herdr through ConPTY, and native terminal cursors can flicker, jump, or briefly show stale positions during active full-screen redraws. Herdr's default `host_cursor = "auto"` draws Herdr's cursor as terminal cell content on Windows, while Linux and macOS keep using the native terminal cursor. The Windows trade-off is a steady non-blinking cursor inside Herdr instead of the outer terminal's native blink, shape, and cursor color.
Windows terminals run Herdr through ConPTY, and native terminal cursors can flicker, jump, or briefly show stale positions during active full-screen redraws. Herdr's default `host_cursor = "auto"` draws Herdr's cursor as terminal cell content for native Windows builds and WSL, while other Linux and macOS clients keep using the native terminal cursor. The Windows trade-off is a steady non-blinking cursor inside Herdr instead of the outer terminal's native blink, shape, and cursor color.
To opt back into the outer terminal cursor on Windows, set:
To opt back into the outer terminal cursor on native Windows or WSL, set:
```toml
[ui]
+10 -4
View File
@@ -29,6 +29,7 @@ Herdr 为同时运行多个编程智能体而生。每个智能体都待在一
| Grok CLI | 屏幕清单 | 无 |
| Antigravity CLI | 屏幕清单 | 无 |
| Kiro CLI | 屏幕清单 | 无 |
| Maki | 屏幕清单 | 无 |
可检测但测试较少: Gemini CLI 和 Cline。不受支持的智能体仍然可以作为普通终端进程正常运行,只是在你添加集成或通过 socket API 上报状态之前,可能得不到丰富的状态。
@@ -113,17 +114,22 @@ herdr agent rename reviewer --clear
## 自定义状态标签
集成可以上报一个视觉状态标签,而不改变语义状态
集成只把生命周期状态作为语义状态上报。展示自定义应通过窗格元数据令牌单独添加
```bash
herdr pane report-agent w1:p1 \
--source custom:indexer \
--agent docs-bot \
--state working \
--custom-status indexing
--state working
herdr pane report-metadata w1:p1 \
--source custom:indexer-display \
--token summary=indexing
```
`state` 控制等待、通知和汇总。`custom-status` 只是显示文本
`state` 控制等待、通知和汇总。`summary` 令牌只影响展示,可在智能体侧边栏行中写成 `$summary`
智能体侧边栏行也可以选择使用 `terminal_title` 或 `terminal_title_stripped`;两者都不在默认行中。前者显示经过安全规范化的最新 OSC 0/2 终端标题,后者会移除开头一个已识别的活动或旋转指示符字形及其后的空白。这些值由 Herdr 服务器所有,冷重启后不会保留,并且独立于元数据标题和语义智能体状态。因此,如果移除后的文本不变,旋转动画可以改变原始标题而不触发窗格更新。
## 从 CLI 启动智能体
@@ -116,6 +116,7 @@ herdr workspace create [--cwd PATH] [--label TEXT] [--env KEY=VALUE] [--focus] [
herdr workspace get <workspace_id>
herdr workspace focus <workspace_id>
herdr workspace rename <workspace_id> <label>
herdr workspace report-metadata <workspace_id> --source ID [--token NAME=VALUE] [--clear-token NAME] [--seq N] [--ttl-ms N]
herdr workspace close <workspace_id>
```
@@ -200,7 +201,6 @@ herdr pane report-agent <pane_id> \
--agent LABEL \
--state idle|working|blocked|unknown \
[--message TEXT] \
[--custom-status TEXT] \
[--seq N] \
[--agent-session-id ID] \
[--agent-session-path PATH]
@@ -219,18 +219,21 @@ herdr pane report-metadata <pane_id> \
[--applies-to-source ID] \
[--title TEXT|--clear-title] \
[--display-agent TEXT|--clear-display-agent] \
[--custom-status TEXT|--clear-custom-status] \
[--state-label STATUS=TEXT] \
[--clear-state-labels] \
[--token NAME=VALUE] \
[--clear-token NAME] \
[--seq N] \
[--ttl-ms N]
```
`STATUS` 是 `idle`、`working`、`blocked`、`done` 或 `unknown` 之一。`--agent` 是对权威智能体标签的守卫。`--applies-to-source` 是对活动生命周期权威来源的守卫。用 `--display-agent` 修改可见名称。
`STATUS` 是 `idle`、`working`、`blocked`、`done` 或 `unknown` 之一。`--agent` `--applies-to-source` 只守卫 `--title`、`--display-agent` 和 `--state-label`,不守卫令牌补丁。上报方负责清除令牌或刷新 TTL。用 `--display-agent` 修改可见名称。
元数据文本在存储前会被规范化。Herdr 去掉首尾空白、移除控制字符、把 `--custom-status` 截断到 32 个字符,把 `--title`、`--display-agent`每个 `--state-label` 值截断到 80 个字符。规范化后为空的值被忽略
元数据文本在存储前会被规范化。Herdr 去掉首尾空白、移除控制字符,把 `--title`、`--display-agent`每个 `--state-label` 和令牌值截断到 80 个字符。规范化后为空的令牌值会清除该键
`--source` 和 `--applies-to-source` 必须不超过 80 个字符,并且只能包含 ASCII 字母、数字、冒号、点、下划线和连字符。`--ttl-ms` 让元数据自动过期,取值必须在 `1` 到 `86400000` 毫秒之间。想让元数据一直保留到被替换、清除或窗格关闭时,省略它。`--seq` 让 Herdr 忽略来自同一 `--source` 的过期上报;过期上报会被 API 接受,但被窗格状态忽略
`--token` 设置一个命名展示值,`--clear-token` 删除一个值。未提及的令牌保持不变。窗格令牌可在智能体侧边栏行中写成 `$name`;工作区令牌可用于空间行。TTL 分别应用于该次调用更新的每个令牌键
`--source` 和 `--applies-to-source` 必须不超过 80 个字符,并且只能包含 ASCII 字母、数字、冒号、点、下划线和连字符。`--ttl-ms` 让元数据自动过期,取值必须在 `1` 到 `86400000` 毫秒之间。想让元数据一直保留到被替换、清除或窗格或工作区关闭时,省略它。`--seq` 让 Herdr 忽略来自同一 `--source` 的过期上报;过期上报会被 API 接受,但被窗格状态忽略。每个窗格或工作区在其生命周期内最多接受来自 32 个不同来源的带序号令牌上报,清除或过期不会释放这些来源名额。
## 智能体
@@ -368,12 +371,12 @@ herdr plugin log list [--plugin ID] [--limit N]
托管终端窗格:
```bash
herdr plugin pane open --plugin ID --entrypoint ID [--placement overlay|split|tab|zoomed] [--workspace ID] [--target-pane PANE] [--direction right|down] [--cwd PATH] [--env KEY=VALUE] [--focus|--no-focus]
herdr plugin pane open --plugin ID --entrypoint ID [--placement overlay|popup|split|tab|zoomed] [--width SIZE] [--height SIZE] [--workspace ID] [--target-pane PANE] [--direction right|down] [--cwd PATH] [--env KEY=VALUE] [--focus|--no-focus]
herdr plugin pane focus <pane_id>
herdr plugin pane close <pane_id>
```
`plugin pane open` 要求插件已链接、已启用并与当前平台兼容。它把清单声明的 `[[panes]]` 命令作为 Herdr 管理的终端窗格启动。清单的默认值是 `overlay`,在活动窗格上方打开一个临时的缩放覆盖层。它也可以作为分割、新标签页缩放窗格打开。非终端的原生插件窗格是之后的能力面。
`plugin pane open` 要求插件已链接、已启用并与当前平台兼容。它把清单声明的 `[[panes]]` 命令作为 Herdr 管理的终端窗格启动。清单的默认值是 `overlay`,在活动窗格上方打开一个临时的缩放覆盖层。它也可以作为分割、新标签页缩放窗格,或不改变标签页布局的会话级模态 `popup` 打开。`--width` 和 `--height` 以终端单元格数或 `80%` 这样的百分比设置弹窗外层尺寸;省略时默认为终端大小的一半,过小的值会限制为弹窗最小尺寸。弹窗不是 Herdr 窗格,不会收到 `HERDR_PANE_ID`,也不参与 pane 或智能体 API。非终端的原生插件窗格是之后的能力面。
`--env KEY=VALUE` 可以在启动进程的命令上重复使用,只作用于新启动的进程。当与调用方提供的环境变量冲突时,`HERDR_SOCKET_PATH`、`HERDR_BIN_PATH`、`HERDR_ENV`、`HERDR_WORKSPACE_ID`、`HERDR_TAB_ID`、`HERDR_PANE_ID`、`HERDR_PLUGIN_ID`、`HERDR_PLUGIN_ROOT`、`HERDR_PLUGIN_CONFIG_DIR`、`HERDR_PLUGIN_STATE_DIR`、`HERDR_PLUGIN_ENTRYPOINT_ID` 和 `HERDR_PLUGIN_CONTEXT_JSON` 等 Herdr 管理的变量保持权威。
+174 -257
View File
@@ -3,134 +3,117 @@ title: 配置
description: 配置 Herdr 的按键绑定、主题、侧边栏行为、通知和高级选项。
---
Herdr 无需配置文件即可工作。当你想自定义按键、主题、侧边栏设置、通知或高级行为时再添加。
Herdr 无需配置文件即可使用。当你想自定义按键、主题、侧边栏布局、通知或高级行为时再添加配置文件
在找某个具体的键?[配置参考](/zh-cn/docs/config-reference/)列出了所有键的类型、默认值允许的取值。
找某项设置或按键绑定?请在[配置参考](/docs/config-reference/)中搜索,其中列出了每个键、类型、默认值允许值。本页重点介绍设置方法、常用配置方案,以及需要比参考表格更详细说明的配置结构
## 配置文件
Herdr 从这里读取配置:
Herdr 从以下位置读取配置
```text
Linux macOS: ~/.config/herdr/config.toml
Windows: %APPDATA%\herdr\config.toml
Linux and macOS: ~/.config/herdr/config.toml
Windows: %APPDATA%\herdr\config.toml
```
运行 `herdr --help` 可查看系统解析后的配置文件路径。
运行 `herdr --help` 可查看系统解析后的配置路径。
打印完整的默认配置:
打印完整的默认配置
```bash
herdr --default-config
```
想要一个完整的起点,可以把它保存为你的配置:
如果想从完整配置开始,可以将其保存为你的配置文件:
```bash
herdr --default-config > ~/.config/herdr/config.toml
```
如果某个配置值无效,Herdr 会回退到安全默认值,并在启动时显示警告。
如果配置值无效Herdr 会回退到安全默认值,并显示启动警告。
当 `onboarding` 缺失或为 true 时,Herdr 会显示首次运行引导。从引导继续会写入 `onboarding = false` 并打开设置的集成标签页。安装完成后想跳过流程时可以设置它
当 `onboarding` 缺失或为 true 时Herdr 会显示首次运行设置。继续完成引导会写入 `onboarding = false`并打开设置的集成标签页。完成设置后,如果想跳过流程,请设置该值
```toml
onboarding = false
```
## 更新
Linux 和 macOS 的直接安装默认使用稳定更新通道。Windows 测试版安装默认使用预览通道,在稳定的 Windows 发布可用之前不能切换到稳定版。
```toml
[update]
channel = "stable"
version_check = true
manifest_check = true
```
设置 `channel = "preview"` 让 `herdr update` 安装从当前开发分支手动发布的预览构建。Homebrew、mise 和 Nix 安装忽略预览通道,通过各自的包管理器更新。
设置 `version_check = false` 禁用对新 Herdr 版本的后台检查。手动 `herdr update` 仍使用配置的通道。
设置 `manifest_check = false` 禁用后台的远程智能体检测清单检查。Herdr 仍使用内置清单和本地覆盖。
## 重载配置
编辑 `config.toml` 后重载运行的服务器:
编辑 `config.toml` 后重载正在运行的服务器
```bash
herdr server reload-config
```
也可以 Herdr 中打开全局菜单并选择 `reload config`。
也可以打开 Herdr 全局菜单并选择 `reload config`。
重载会在不重启窗格的情况下应用大多数 UI 设置。仅启动时生效的设置仍需重启。
重载会在不重启窗格的情况下应用大多数 UI 设置。仅启动时生效的设置仍需重启。
## 终端默认值
设置 Herdr 为新建交互式窗格使用的可执行文件:
设置 Herdr 创建新交互式窗格使用的可执行文件
```toml
[terminal]
default_shell = "nu"
```
未设置或为空时,Herdr 使用 `$SHELL`,然后是 `/bin/sh`。这是可执行文件名或路径,不是 shell 命令行。现有窗格在重建之前保持当前 shell。命令窗格仍通过 `/bin/sh -c` 运行;分离式自定义命令按键绑定使用 Herdr 已有的 `/bin/sh -lc` 路径
未设置或为空时Herdr 会依次使用 `$SHELL`、Unix 上的 `/bin/sh` 或 Windows 上的 PowerShell。该值是可执行文件名或路径,而不是 shell 命令行。现有窗格会保留当前 shell,直到重新创建。自定义命令按键绑定中的字符串在 Unix 上通过 `/bin/sh -c` 执行窗格命令,通过 `/bin/sh -lc` 执行分离式命令;在 Windows 上则通过 `cmd.exe /d /c` 执行
设置 Herdr 如何启动新建交互式窗格的 shell:
设置 Herdr 如何启动新建交互式窗格的 shell
```toml
[terminal]
shell_mode = "auto"
```
`shell_mode = "auto"` 在 macOS 上启动登录 shell,使 `/usr/libexec/path_helper` 这类仅登录时的 PATH 设置和 Homebrew shell 初始化在新窗格中运行。在其他平台上,它保持现有的非登录 shell 行为。用 `"login"` 强制登录 shell 启动,用 `"non_login"` 选择退出。命令窗格、分离式自定义命令按键绑定和显式 argv 启动保持已有的命令执行路径。
`shell_mode = "auto"` 在 macOS 上启动登录 shell,让 `/usr/libexec/path_helper` 仅登录时生效的 PATH 设置和 Homebrew shell 初始化在新窗格中运行。在其他平台上,它会保持现有的非登录 shell 行为。使用 `"login"` 强制登录 shell 启动,或使用 `"non_login"` 禁用登录 shell。命令窗格、分离式自定义命令按键绑定和显式 argv 启动仍使用现有的命令执行路径。
设置新窗格、标签页和工作区的工作目录策略:
设置新窗格、标签页和工作区的工作目录策略
```toml
[terminal]
new_cwd = "follow"
```
`new_cwd = "follow"` 保持默认行为,继承来源窗格或工作区。没有来源工作区时,Herdr 从 `$HOME` 启动。用 `"home"` 总是从 `$HOME` 启动,用 `"current"` 使用 Herdr 的进程目录,或者用 `"~/Projects"` 这固定路径。来自 CLI 或 socket API 显式 `--cwd` 值仍然优先。
`new_cwd = "follow"` 保持默认行为,并继承来源窗格或工作区。没有来源工作区时Herdr 从 `$HOME` 启动。使用 `"home"` 可始终从 `$HOME` 启动,使用 `"current"` 可采用 Herdr 的进程目录,也可以指定 `"~/Projects"` 这样的固定路径。CLI 或 socket API 显式提供的 `--cwd` 值仍然优先。
## Worktree
设置从侧边栏创建 Git worktree 检出时 Herdr 使用的根目录:
设置 Herdr 从侧边栏创建 Git worktree 检出时使用的根目录
```toml
[worktrees]
directory = "~/.herdr/worktrees"
```
Herdr 在 `<directory>/<repo>/<branch-slug>` 下创建检出。想要同级目录风格的检出,把它设为 `~/Projects/herdr-worktrees` 这目录。相对值会在应用配置时解析为绝对路径。
Herdr 在 `<directory>/<repo>/<branch-slug>` 下创建检出。若要使用同级目录风格的检出,请将其设置为 `~/Projects/herdr-worktrees` 这样的目录。应用配置时,相对路径会解析为绝对路径。
worktree 操作在 Git 工作区行上可用。`New worktree` 创建一个检出,输入的分支已存在检出该本地分支,否则创建分支,作为新 Herdr 工作区打开,并归组到来源工作区下。`Open worktree...` 列出该仓库有的 Git worktree 检出;选择已打开的检出会聚焦它,选择已关闭的检出会在同一组中打开它。
Git 工作区行提供 worktree 操作。`New worktree` 创建检出:如果输入的分支已存在,则检出该本地分支否则创建分支;随后将其作为新 Herdr 工作区打开并归组到来源工作区下。`Open worktree...` 列出该仓库有的 Git worktree 检出选择已打开的检出会聚焦它选择尚未打开的检出会在同一组中打开它。
归组的 worktree 仍像普通 Herdr 工作区一样: 可以聚焦、重命名关闭,并拥有自己的标签页和窗格。父行是原始工作区。关闭父行会关闭整个 Herdr 组,但不会删除检出文件夹或分支。
归组的 worktree 仍像普通 Herdr 工作区一样工作:可以聚焦、重命名关闭,也可以拥有自己的标签页和窗格。父行是原始工作区。关闭父行会关闭整个 Herdr 组但不会删除检出目录或分支。
删除 worktree 检出显式操作。在归组的子工作区上使用 `Delete worktree checkout...` 运行 `git worktree remove`。Herdr 先请求 Git 安全删除。如果 Git 因检出修改或未跟踪文件而拒绝,Herdr 会在执行强制删除前再次询问。分支不会被删除。
删除 worktree 检出需要显式操作。在归组的子工作区上使用 `Delete worktree checkout...` 运行 `git worktree remove`。Herdr 先请求 Git 安全删除。如果 Git 因检出中存在已修改或未跟踪文件而拒绝Herdr 会在强制删除前再次确认。分支不会被删除。
## 远程连接
远程连接默认用临时保活兜底的方式管理它的 SSH
远程连接默认使用临时保活设置和连接复用兜底来管理 SSH 连接
```toml
[remote]
manage_ssh_config = true
```
启用时,`herdr --remote` 写入一私有的临时 SSH 配置: 先包含你的 `~/.ssh/config` 和 `/etc/ssh/ssh_config`,再添加兜底的 `ServerAliveInterval` 和 `ServerAliveCountMax` 值。你自己的 SSH 保活设置优先。设置 `manage_ssh_config = false` 普通 `ssh` 运行桥接,不使用 Herdr 生成的配置。
启用后,`herdr --remote` 写入一私有的临时 SSH 配置先包含你的 `~/.ssh/config` 和 `/etc/ssh/ssh_config`再添加兜底的 `ServerAliveInterval` 和 `ServerAliveCountMax` 值。你自己的保活设置优先。Herdr 还会为每次远程连接使用私有的 OpenSSH control socket,以复用首次通过身份验证的连接。设置 `manage_ssh_config = false` 可通过普通 `ssh` 进行远程连接,不使用 Herdr 生成的配置或 control socket
## 按键绑定
前缀键的入门介绍和经过验证的免前缀配置,见[键盘](/zh-cn/docs/keyboard/)。
有关前缀键的引导式介绍和经过验证的免前缀配置,请参阅[键盘](/docs/keyboard/)。
Herdr 类似 tmux 的前缀模式。默认前缀是 `ctrl+b`。按键绑定字符串是显式的: `prefix+n` 表示先按配置的前缀再按 `n`;`ctrl+alt+n` 是终端模式的直接快捷键。
Herdr 提供类似 tmux 的前缀模式。默认前缀是 `ctrl+b`。按键绑定字符串是显式的`prefix+n` 表示先按配置的前缀再按 `n``ctrl+alt+n` 是终端模式的直接快捷键。
一个小型的按键绑定覆盖长这样:
一个简短的按键绑定覆盖如下:
```toml
[keys]
@@ -145,73 +128,24 @@ navigate_pane_down = "ctrl+j"
split_horizontal = "prefix+minus"
```
默认键位以前缀为先,避免会从 shell、编辑器、tmux 或终端应用输入的直接快捷键。常见默认值包括:
默认键位以前缀为主,因此 Herdr 不会抢占 shell、编辑器、tmux 或终端应用输入。在[配置参考](/docs/config-reference/)中搜索 `keys.` 可查看每个动作及其默认绑定。应用内帮助面板可通过 `prefix+?` 打开,其中会显示当前生效的绑定。
当一个动作需要多个快捷键时,绑定也可以是数组:
```toml
[keys]
detach = "prefix+q"
workspace_picker = "prefix+w"
goto = "prefix+g"
new_workspace = "prefix+shift+n"
new_worktree = "prefix+shift+g"
rename_workspace = "prefix+shift+w"
close_workspace = "prefix+shift+d"
navigate_workspace_up = "up"
navigate_workspace_down = "down"
navigate_pane_left = "h"
navigate_pane_down = "j"
navigate_pane_up = "k"
navigate_pane_right = "l"
remote_image_paste = "ctrl+v"
new_tab = "prefix+c"
previous_tab = "prefix+p"
next_tab = "prefix+n"
switch_tab = "prefix+1..9"
rename_tab = "prefix+shift+t"
close_tab = "prefix+shift+x"
copy_mode = "prefix+["
focus_pane_left = "prefix+h"
focus_pane_down = "prefix+j"
focus_pane_up = "prefix+k"
focus_pane_right = "prefix+l"
swap_pane_left = "prefix+shift+h"
swap_pane_down = "prefix+shift+j"
swap_pane_up = "prefix+shift+k"
swap_pane_right = "prefix+shift+l"
cycle_pane_next = "prefix+tab"
cycle_pane_previous = "prefix+shift+tab"
last_pane = ""
split_vertical = "prefix+v"
split_horizontal = "prefix+minus"
close_pane = "prefix+x"
zoom = "prefix+z"
resize_mode = "prefix+r"
toggle_sidebar = "prefix+b"
```
可选动作默认未设置。用 `prefix+` 绑定它们获得前缀模式行为,或者在有意想要直接快捷键时用显式的修饰组合键:
```toml
[keys]
previous_workspace = "prefix+shift+left"
next_workspace = "prefix+shift+right"
last_pane = "prefix+tab"
open_worktree = "prefix+shift+o"
remove_worktree = "prefix+alt+d"
next_tab = ["prefix+n", "ctrl+alt+]"]
```
`last_pane` 跨工作区和标签页切回上一个聚焦的窗格。它默认设置,因为 tmux 风格的窗格绑定 `prefix+l` 已被用于向右聚焦窗格
可选动作默认设置。使用 `prefix+` 可获得前缀模式行为;当你确实需要直接快捷键时,请使用显式的修饰组合键
`remote_image_paste` 只在 `herdr --remote` 中生效。它是本地客户端的快捷键,把本地剪贴板图像发送到远程窗格。设为空字符串可禁用这个原始按键快捷键;外层终端发送的 paste-image 信号仍然有效
按键字符串支持普通按键、`ctrl+a`、`shift+n`、`alt+1`、`cmd+k` 等修饰组合键,以及 `enter`、`tab`、`esc`、`left`、`right`、`up`、`down` 等特殊键。也支持 `minus`、`comma`、`ampersand`、`plus`、`backtick` 等命名标点。直接绑定 `n` 这样的普通可打印键并不安全,因为它会拦截输入;除非你有意设置直接绑定,否则请使用 `prefix+n`。`navigate_workspace_*` 和 `navigate_pane_*` 字段仅在导航模式中生效,可以使用 `j` 或 `k` 等普通按键;它们不得使用 `prefix+`、`esc`、`enter`、`tab`、`shift+tab`、`left`、`right`,也不得使用无修饰键的 `1` 到 `9`。左右方向键是向左和向右导航窗格的永久别名。这些导航模式快捷键独立于 `focus_pane_down = "prefix+j"` 等通用动作绑定;两者使用同一按键时,打开导航模式后,导航模式快捷键优先。Alt、Cmd/Super 以及带修饰键的标点取决于你的终端和 tmux 设置
按键字符串接受普通按键、`ctrl+a`、`shift+n`、`alt+1`、`cmd+k` 这类修饰组合,以及 `enter`、`tab`、`esc`、`left`、`right`、`up`、`down` 这类特殊键。也接受 `minus`、`comma`、`ampersand`、`plus`、`backtick` 这类命名标点。像 `n` 这样的普通可打印键直接绑定是不安全的,因为它会拦截打字;除非有意要直接绑定,否则用 `prefix+n`。`navigate_workspace_*` 和 `navigate_pane_*` 字段仅在导航模式下生效,可以用 `j`、`k` 这类普通键;它们不能使用 `prefix+`、`esc`、`enter`、`tab`、`shift+tab`、`left`、`right` 或无修饰的 `1` 到 `9`。左右方向键是窗格左/右导航的永久别名。这些导航模式快捷键与 `focus_pane_down = "prefix+j"` 这类通用动作绑定相互独立;两者使用同一个键时,导航模式打开期间导航模式的快捷键优先。Alt、Cmd/Super 和带修饰键的标点取决于你的终端和 tmux 设置
如果你有旧的自定义按键绑定并想要新的默认值,运行 `herdr config reset-keys`。Herdr 会备份 `config.toml`,移除 `[keys]` 和 `[[keys.command]]`,并在重启或 `herdr server reload-config` 后使用内置的 v2 默认值。
如果你已有旧的自定义按键绑定,并想使用新的默认值,请运行 `herdr config reset-keys`。Herdr 会备份 `config.toml`,移除 `[keys]` 和 `[[keys.command]]`,并在重启或执行 `herdr server reload-config` 后使用内置的 v2 默认值
## 索引跳转
索引式按键绑定在普通按键绑定字段中使用 `1..9`:
索引式按键绑定在普通按键绑定字段中使用 `1..9`
```toml
[keys]
@@ -220,25 +154,48 @@ switch_workspace = "prefix+shift+1..9"
focus_agent = "prefix+alt+1..9"
```
式的 `[keys.indexed]` 表出于兼容仍会被解析,但新配置应优先使用显式的动作字段。
`[keys.indexed]` 表仍会出于兼容性而解析但新配置应优先使用显式的动作字段。
## 自定义命令按键绑定
自定义命令使用同的按键绑定语法。
自定义命令使用同的按键绑定语法。
```toml
[[keys.command]]
key = "prefix+alt+g"
type = "pane"
type = "popup"
command = "lazygit"
description = "run lazygit"
width = "80%"
height = "80%"
```
`type = "pane"` 打开一个临时窗格,并在命令退出时关闭它
`type = "popup"` 打开一个会话级模态弹窗,而不改变标签页布局
弹窗会接收包括 Escape 在内的所有终端输入,直到命令退出。
`width` 和 `height` 是可选的;省略时默认为终端大小的一半,数字表示终端单元格数,`"80%"` 这样的字符串表示终端区域的百分比。
尺寸包含弹窗边框,过小的值会限制为弹窗最小尺寸。
弹窗命令不会收到 `HERDR_PANE_ID`;可使用 `HERDR_ACTIVE_PANE_ID` 引用底层平铺窗格。
`type = "shell"` 在后台分离运行。
在 Unix 和 macOS 上,还可以打开一个临时终端,而无需添加分割或标签页:
`type = "plugin_action"` 调用已安装插件的动作 id。动作 id 不全局唯一时使用限定 id:
```toml
[[keys.command]]
key = "prefix+t"
type = "popup"
command = "exec \"${SHELL:-sh}\""
description = "open scratch terminal"
width = "80%"
height = "80%"
```
在 Windows 上,请改用 `command = "powershell.exe -NoLogo"` 之类的 shell 命令。
退出 shell 即可关闭弹窗并恢复平铺终端视图。
`type = "pane"` 会打开一个临时窗格,并在命令退出时关闭它。
`type = "shell"` 会在后台分离运行。
`type = "plugin_action"` 会调用已安装插件的动作 id。当动作 id 并非全局唯一时,请使用限定 id:
```toml
[[keys.command]]
@@ -248,26 +205,24 @@ command = "example.layout.apply"
description = "apply layout"
```
可以提供可选的 `description`。指定后,它会显示在按键帮助面板 (`prefix+?` 打开) 中,替代默认的 `'custom command'` 标签。
可以提供可选的 `description`。指定后,该描述会在按键绑定帮助面板(通过 `prefix+?` 打开)中显示,替代默认的 `'custom command'` 标签。
自定义命令在可用时会收到 `HERDR_SOCKET_PATH`、`HERDR_BIN_PATH`、`HERDR_ACTIVE_WORKSPACE_ID`、`HERDR_ACTIVE_TAB_ID`、`HERDR_ACTIVE_PANE_ID` 和 `HERDR_ACTIVE_PANE_CWD`。当 Herdr 能检测到时,shell 命令会从聚焦窗格的工作目录运行。
在相应值可用时,自定义命令会收到 `HERDR_SOCKET_PATH`、`HERDR_BIN_PATH`、`HERDR_ACTIVE_WORKSPACE_ID`、`HERDR_ACTIVE_TAB_ID`、`HERDR_ACTIVE_PANE_ID` 和 `HERDR_ACTIVE_PANE_CWD`。当 Herdr 能检测到聚焦窗格的工作目录时,shell 命令会从目录运行。
在 Windows 上,自定义命令字符串使用 `cmd.exe /d /c`,因此环境变量应采用 `%HERDR_BIN_PATH%` 语法。若要运行 PowerShell 语法,请显式调用它,例如 `powershell.exe -NoProfile -Command "..."`。
## 主题
选择内置主题:
选择内置主题
```toml
[theme]
name = "catppuccin"
```
内置主题:
在[配置参考](/docs/config-reference/)中搜索 `theme.name` 可查看所有内置主题。如果想让 Herdr UI 颜色跟随宿主终端的 ANSI 调色板,请使用 `terminal`。
`catppuccin`、`catppuccin-latte`、`terminal`、`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`。
想让 Herdr 的 UI 颜色跟随宿主终端的 ANSI 调色板时用 `terminal`。
要让 Herdr 在宿主终端报告明暗外观变化时自动切换自己的 UI 主题,启用主题自动切换:
要让 Herdr 在宿主终端报告明暗外观变化时自动切换自身的 UI 主题,请启用主题自动切换:
```toml
[theme]
@@ -277,9 +232,9 @@ light_name = "catppuccin-latte"
dark_name = "catppuccin"
```
`auto_switch` 默认为 `false`,所以现有主题配置保持手动行为。省略 `light_name` 或 `dark_name` 时,如果配置的 `name` 存在对应的内置姊妹主题,Herdr 使用它,比如 `tokyo-night`/`tokyo-night-day` 或 `gruvbox`/`gruvbox-light`。在设置中手动选择主题会禁用 `auto_switch`。
`auto_switch` 默认为 `false`,因此现有主题配置保持手动行为。如果省略 `light_name` 或 `dark_name`,且配置的 `name` 存在对应的内置姊妹主题Herdr 使用该主题,例如 `tokyo-night`/`tokyo-night-day` 或 `gruvbox`/`gruvbox-light`。在设置中手动选择主题会禁用 `auto_switch`。
你可以覆盖单个颜色:
你可以覆盖单个颜色
```toml
[theme.custom]
@@ -291,98 +246,116 @@ red = "#f38ba8"
yellow = "#f9e2af"
```
颜色值接受十六进制、命名颜色、`rgb(r,g,b)`,或 `reset`、`default`、`none`、`transparent` 这类重置别名。
颜色值支持十六进制、命名颜色、`rgb(r,g,b)`,以及 `reset`、`default`、`none`、`transparent` 重置别名。
## UI 与侧边栏
侧边栏是 Herdr 的主仪表盘。它显示工作区、标签页、窗格和智能体状态
侧边栏是 Herdr 的主仪表盘。在[配置参考](/docs/config-reference/)中搜索 `ui.`,可查看尺寸、折叠模式、Agent 面板排序、鼠标行为、窗格边框和其他显示设置
常用选项:
### 侧边栏行布局
展开的桌面侧边栏会将 `rows` 中的每个内层数组渲染为一行。以下是完整的默认布局:
```toml
[ui]
sidebar_width = 32
sidebar_min_width = 18
sidebar_max_width = 36
mobile_width_threshold = 64
mouse_capture = true
right_click_passthrough_modifier = ""
redraw_on_focus_gained = true
mouse_scroll_lines = 3
confirm_close = true
prompt_new_tab_name = true
pane_borders = true
pane_gaps = true
show_agent_labels_on_pane_borders = false
agent_panel_sort = "spaces"
accent = "cyan"
[ui.sidebar.agents]
row_gap = 0
rows = [
["state_icon", "workspace", "tab"],
["agent"],
]
[ui.sidebar.spaces]
row_gap = 0
rows = [
["state_icon", "workspace"],
["branch", "git_status"],
]
```
`sidebar_min_width` 和 `sidebar_max_width` 以列数控制展开侧边栏的调整范围。默认是 18 和 36。
Agent 行支持以下内置 token
`mobile_width_threshold` 控制 Herdr 使用移动端单列布局的终端宽度阈值。默认 64 列;折叠屏、平板或宽屏手机终端可以调大
- `state_icon` — 智能体语义状态的彩色图标
- `state_text` — `idle`、`working`、`blocked`、`done` 或 `unknown`;如果报告中包含显示标签,也会一并显示。
- `workspace` — 工作区名称。
- `tab` — 标签页名称(如有)。
- `pane` — 窗格名称(如有)。
- `agent` — 检测到或报告的智能体显示名称。
- `terminal_title` — 经过安全规范化的最新 OSC 0/2 终端标题。
- `terminal_title_stripped` — 从终端标题开头移除一个可识别的活动或旋转指示符字形及其后空白后的结果。
- `$name` — 名为 `name` 的自定义窗格元数据。
智能体面板显示所有空间中的所有智能体。`agent_panel_sort` 可以是 `spaces` 或 `priority`;`workspaces` 作为 `spaces` 的别名被接受。默认是 `spaces`,让智能体按空间顺序分组。`priority` 按关注优先级排序: blocked、done、working、idle,然后是 unknown。同一状态内,最近改变状态的智能体排在前面。
Space 行支持以下内置 token
`confirm_close` 控制关闭工作区时是否需要确认。`prompt_new_tab_name` 控制新标签页是否先询问名称
- `state_icon` — Space 汇总后智能体状态的彩色图标
- `state_text` — Space 汇总后智能体状态的文本。
- `workspace` — 工作区名称。
- `branch` — Git 分支(如有)。
- `git_status` — 非零时显示 Git ahead 和 behind 数量。
- `$name` — 名为 `name` 的自定义工作区元数据。
如果想让终端处理普通点击,比如 command+点击 URL,设置 `mouse_capture = false`。鼠标捕获启用时,如果终端把带修饰键的点击传给 Herdr,Ctrl+点击可以打开窗格链接。macOS 也是如此;Herdr 捕获鼠标输入期间,Cmd+点击不会与普通点击区分上报。终端原生的绕过路径: Linux 上用 Shift+Ctrl+点击,macOS 上用 Shift+Cmd+点击
token 会按配置顺序渲染。Herdr 通常使用 ` · ` 分隔相邻值,并在 `state_icon` 后使用一个空格。缺失值及其分隔符会消失;当一行中的所有 token 都没有值时,该行会消失。每个布局最多可包含 16 行,每行最多可包含 16 个 token
如果想让 Ctrl+右键点击、按住和拖动手势到达启用鼠标上报的窗格应用,而不是打开 Herdr 的窗格菜单,设置 `right_click_passthrough_modifier = "ctrl"`。默认为空,即禁用这种透传。支持的修饰键有 `ctrl`、`alt`、`cmd`、`super`、`meta` 和 `hyper`;`shift` 被拒绝,因为许多终端把 Shift+鼠标保留给它们自己的鼠标绕过
`row_gap` 分别控制 Agent 和 Space 面板中条目之间的空白终端行数。默认值为 `0`,会紧密排列条目;设为 `1` 可恢复之前的间距。它不会在 `rows` 声明的内容行之间添加间距。连续缩进的 worktree 子项仍会作为一个 Space 组紧密排列
设置 `redraw_on_focus_gained = false` 可以避免切回 Herdr 时可见的全屏刷新。默认为 `true`,因为完整重绘能从罕见的过期或脏的宿主终端画面中恢复。
`rows_by_agent` 下为已知智能体覆盖完整的 Agent 布局:
设置 `mouse_scroll_lines` 改变鼠标滚轮每格滚动的窗格回滚行数。默认是 3。请求鼠标上报的窗格应用仍然直接接收滚轮事件。备用屏幕应用没有可滚动的回滚内容;参见[回滚缓冲区](#回滚缓冲区)。
```toml
[ui.sidebar.agents]
rows = [
["state_icon", "agent", "state_text"],
["workspace", "tab"],
]
设置 `pane_borders = false` 移除分割窗格边框。设置 `pane_gaps = false` 让分割窗格共用紧凑的分隔线。禁用边框时,窗格间距是窗格之间一个空白终端单元格。终端单元格通常高大于宽,所以上下窗格之间一行的间距可能看起来比左右窗格之间一列的间距更大。
[ui.sidebar.agents.rows_by_agent]
claude = [
["state_icon", "agent", "state_text"],
["terminal_title_stripped"],
["workspace", "tab"],
]
```
如果想在没有手动窗格标签时,把检测到的智能体标签显示在分割窗格边框上,设置 `show_agent_labels_on_pane_borders = true`。
覆盖项会替换 `rows`,而不是扩展它。覆盖项的键是区分大小写的规范智能体 ID,例如 `claude`、`codex` 和 `pi`。不接受 `claude-code` 等检测别名。没有覆盖项的智能体(包括自定义报告的智能体)会使用 `rows`。
自定义 `$name` token 是动态值,而不是字面文本。先将 token 添加到布局,再通过脚本或插件报告其值:
```toml
[ui.sidebar.agents]
rows = [
["state_icon", "agent", "$model"],
["$summary"],
["workspace", "tab"],
]
```
```bash
herdr pane report-metadata <pane_id> \
--source my-agent-hook \
--token model=opus \
--token summary="reviewing authentication"
```
自定义 Space token 可用同样的方式通过 `herdr workspace report-metadata` 报告。未报告的自定义 token 会直接消失。元数据报告方只提供值,不能选择行或样式。有关清除、顺序和过期值的信息,请参阅 [CLI 参考:报告元数据](/docs/cli-reference/#panes)。
侧边栏行设置仅影响展开的桌面侧边栏。折叠视图和移动视图仍使用紧凑布局。
## 通知
Herdr 可以在智能体完成或需要输入时显示弹出通知。
当后台智能体完成任务或需要输入时Herdr 可以通知你:
```toml
[ui.toast]
delivery = "off"
delivery = "herdr"
delay_seconds = 1
[ui.toast.herdr]
position = "bottom-right"
[ui.toast.clipboard]
enabled = true
position = "bottom-center"
```
`delivery = "off"` 禁用弹出通知。这是默认值
`delivery = "herdr"` 在 Herdr UI 内显示 toast。点击 toast,或绑定 `keys.open_notification_target`,可以聚焦目标工作区、标签页和窗格。`ui.toast.herdr.position` 可设为 `top-left`、`top-right`、`bottom-left` 或 `bottom-right`;桌面位置相对于完整的 Herdr 画面。
`delivery = "terminal"` 请求外层终端显示桌面通知。Herdr 为 Ghostty、iTerm2、Kitty 和 WezTerm 发送终端通知转义序列。在 SSH 上很有用,因为通知归本地终端所有。
`delivery = "system"` 直接请求本地操作系统。在 macOS 上,Herdr 优先使用 `terminal-notifier`,不可用时回退到 `/usr/bin/osascript`。`terminal-notifier` 可以在你点击通知时激活承载的终端。在 Linux 上,Herdr 使用 `notify-send`,并要求 `DISPLAY` 或 `WAYLAND_DISPLAY`。
弹出通知用于后台提醒。Herdr 对活动标签页抑制弹出。
`delay_seconds` 在发送完成或需要输入的智能体通知前等待。只有在延迟结束时窗格仍处于相同状态,Herdr 才会通知。设为 `0` 立即通知。有效值为 `0` 到 `3600`。
剪贴板反馈单独配置,因为它确认的是前台复制操作,并且从不通过 terminal 或 system 投递。设置 `ui.toast.clipboard.enabled = false` 隐藏“已复制到剪贴板”弹窗。剪贴板位置有 `top-left`、`top-center`、`top-right`、`bottom-left`、`bottom-center` 和 `bottom-right`。
选择 `herdr` 可使用应用内 toast,选择 `terminal` 可使用适合 SSH 场景的外层终端通知,选择 `system` 可使用本地操作系统通知服务,选择 `off` 禁用弹出通知。Herdr 会抑制活动标签页的弹出通知。在[配置参考](/docs/config-reference/)中搜索 `ui.toast`,可查看位置、延迟行为和剪贴板反馈设置
## 声音
声音通知默认启用,由本地 Herdr 客户端播放。
```toml
[ui.sound]
enabled = true
```
Herdr 在智能体完成时播放完成音,在智能体需要输入时播放提醒音。在共享机器或远程服务器上,除非明确想要声音,否则设置 `enabled = false`。
在 macOS 上,Herdr 使用 `afplay`。在 Linux 上,Herdr 按顺序尝试支持 mp3 的播放器: `paplay`、`pw-play`、`ffplay`、`mpg123`,然后是 `mpv`。没有可用播放器时,声音播放被跳过,Herdr 记录一条警告。
自定义声音必须是 mp3 文件。相对路径从配置文件所在目录解析。
声音通知通过本地 Herdr 客户端播放。自定义声音必须是 mp3 文件;相对路径从配置文件所在目录解析。
```toml
[ui.sound]
@@ -391,9 +364,9 @@ done_path = "sounds/done.mp3"
request_path = "sounds/request.mp3"
```
`path` 为所有声音通知设置一个声音。`done_path` 和 `request_path` 只覆盖完成和需要输入音。
`path` 为所有声音通知设置同一种声音。`done_path` 和 `request_path` 只覆盖完成和需要输入时的声音。
按智能体的声音覆盖接受 `default`、`on` 或 `off`。用检测到的智能体标签做键,比如 `claude`、`codex`、`devin` 或 `droid`。Droid 默认静音。
按智能体覆盖声音设置时,可使用 `default`、`on` 或 `off`。键应使用检测到的智能体标签,例如 `claude`、`codex`、`devin` 或 `droid`。Droid 默认静音。
```toml
[ui.sound.agents]
@@ -401,110 +374,54 @@ droid = "off"
claude = "on"
```
## 回滚缓冲区
## 高级配置
设置新建窗格的回滚缓冲区大小:
```toml
[advanced]
scrollback_limit_bytes = 10485760
```
现有窗格在重建之前保持当前缓冲区。
只有应用写入主屏幕时,窗格才显示滚动条。切换到备用屏幕的全屏应用 (vim、htop、设置了 `CLAUDE_CODE_NO_FLICKER=1` 的 Claude Code) 不产生回滚内容,因此不出现滚动条,滚轮事件转而路由给应用。请用应用自己的按键或 UI 滚动。
## 窗格屏幕历史
默认情况下,完整的会话重启会恢复工作区、标签页、窗格、cwd、布局和焦点,但不保存窗格内容。
窗格屏幕历史默认关闭。窗格输出可能包含密钥、令牌、提示词和命令输出,所以只在你确实想让 Herdr 跨完整服务器重启保存最近窗格内容时才开启:
```toml
[experimental]
pane_history = true
```
也可以在 Settings > Experiments > pane screen history 中切换。
开启后,Herdr 把保存的窗格历史存放在 `session.json` 旁边的 `session-history.json` 中。
窗格屏幕历史与实时持久化、快照恢复、智能体原生会话恢复和实时交接的区别,见[会话状态与恢复](/zh-cn/docs/session-state/)。
## 嵌套启动
Herdr 通常会阻止你在 Herdr 内启动 Herdr。
```toml
[experimental]
allow_nested = false
```
仅在测试时启用嵌套启动。
在[配置参考](/docs/config-reference/)中搜索回滚缓冲区限制、嵌套启动以及其他高级或实验性设置。启用窗格屏幕历史前,请参阅[会话状态与恢复](/docs/session-state/);该指南说明了保存窗格内容带来的安全取舍。
## Kitty graphics
Kitty graphics 支持是实验性的。
面向已连接本地客户端的 Kitty graphics 渲染是一项实验性功能,默认禁用:
```toml
[experimental]
kitty_graphics = false
kitty_graphics = true
```
除非你在测试终端图像行为,否则保持关闭
在测试终端图像行为时启用
## 智能体会话恢复
Herdr 可以在服务器重启后,让受支持的智能体窗格在其原生对话会话中重新启动。
默认情况下,Herdr 在服务器重启后恢复受支持的智能体对话:
```toml
[session]
resume_agents_on_restore = true
```
这默认开启。Herdr 只恢复通过官方 Herdr 集成上报了原生会话引用的窗格。受支持的恢复目标是 Claude Code、Codex、Cursor Agent CLI、GitHub Copilot CLI、Droid、Kimi Code CLI、Qoder CLI、Pi、Hermes Agent、OpenCode、Kilo Code CLI 和 MastraCode。不受支持、缺失、无效、重复或过期的会话引用,会在保存的窗格目录中作为普通 shell 恢复
会话引用存储在本地 Herdr 会话快照中。它们不会出现在普通的窗格、智能体、状态或事件输出中。
智能体原生会话恢复与窗格屏幕历史和实时交接的区别,见[会话状态与恢复](/zh-cn/docs/session-state/)。
只有通过官方集成获得有效原生会话引用的窗格才能恢复;其他窗格会作为普通 shell 恢复。有关受支持的智能体和持久化行为,请参阅[会话状态与恢复](/docs/session-state/)
## IME 光标跟踪
当聚焦窗格隐藏光标并自己绘制光标时 — 这在 Claude Code、pi、codex、Devin 这类 AI 智能体 TUI 中很常见 — macOS 原生输入法会停止跟踪候选窗口位置,因为外层终端不再报告光标。
设置 `reveal_hidden_cursor_for_cjk_ime = true`,无视窗格的 `?25l` 请求,把聚焦窗格的光标锚点暴露给外层终端:
在 macOS 上,隐藏硬件光标的 AI 智能体 TUI 可能导致原生输入法候选窗口无法跟随聚焦窗格。使用以下设置可为这些窗格显示光标锚点:
```toml
[experimental]
reveal_hidden_cursor_for_cjk_ime = false
cjk_ime_agents = []
cjk_ime_cursor_shape = "steady_block"
reveal_hidden_cursor_for_cjk_ime = true
cjk_ime_agents = ["claude", "pi", "codex"]
```
启用后,光标保持在聚焦窗格上报的位置可见。如果窗格没有上报光标位置,锚点回退到窗格左上角,保证始终有稳定的输入法提示位置
限制 `cjk_ime_agents` 可以避免在无关应用中额外显示硬件光标。在[配置参考](/docs/config-reference/)中搜索这些键,可查看接受的智能体名称和光标形状
`cjk_ime_agents` 是可选的允许列表。为空时,该显示适用于任何聚焦窗格。非空时,只在聚焦窗格检测到的智能体匹配列表中某个名称时才生效 — 适合只对自绘光标的 AI 智能体 TUI 启用,而不影响普通 shell。接受的名称: `pi`、`claude`、`codex`、`gemini`、`cursor`、`devin`、`agy`、`cline`、`opencode`、`copilot`、`kimi`、`kiro`、`droid`、`amp`、`grok`、`hermes`、`kilo`、`qodercli` 和 `qoder`。未知名称被忽略;如果列表中没有有效名称,该显示不生效。
## 前缀输入源切换
`cjk_ime_cursor_shape` 控制为输入法锚点渲染的 DECSCUSR 形状。接受的值: `block`、`steady_block` (默认)、`underline`、`steady_underline`、`bar`、`steady_bar`。
通过已有的 `[experimental]` 块热重载。
启用的代价: 对隐藏光标但不绘制替代光标的应用 (vim 普通模式等),外层终端会多显示一个硬件光标。配合 `cjk_ime_agents` 把它限定到特定 TUI。
## 前缀输入法切换
在 macOS 上,当非 ASCII 输入法处于活动状态时,前缀模式命令可能很难使用,因为前缀命令仍会经过宿主输入法解释。
设置 `switch_ascii_input_source_in_prefix = true`,在前缀模式激活期间把宿主输入法切换到系统的 ASCII 输入法:
在 macOS 上,当前缀命令和由前缀启动的模式处于活动状态时,Herdr 可以临时切换到系统中支持 ASCII 的输入源:
```toml
[experimental]
switch_ascii_input_source_in_prefix = false
switch_ascii_input_source_in_prefix = true
```
启用后,Herdr 只在进入前缀模式后切换输入法,并在退出前缀模式时恢复之前的输入法。该设置仅限 macOS,在其他平台或系统输入法切换失败时不做任何事
也可以在 Settings > Experiments > switch to ascii input source in prefix (macOS) 中切换。
返回终端输入或进入文本字段时,Herdr 会恢复之前的输入源。此设置在其他平台上无效
## 环境变量
@@ -512,15 +429,15 @@ switch_ascii_input_source_in_prefix = false
| --- | --- |
| `HERDR_CONFIG_PATH` | 覆盖配置文件路径。 |
| `HERDR_SESSION` | 为 CLI 命令选择命名会话。 |
| `HERDR_SOCKET_PATH` | 底层 socket 路径覆盖。 |
| `HERDR_LOG` | 设置日志过滤,例如 `HERDR_LOG=herdr=debug`。 |
| `HERDR_SOCKET_PATH` | 覆盖底层 socket 路径。 |
| `HERDR_LOG` | 设置日志过滤例如 `HERDR_LOG=herdr=debug`。 |
| `HERDR_DISABLE_SOUND` | 即使 `[ui.sound] enabled = true` 也禁用声音播放。 |
## 日志
诊断启动警告、集成状态或 socket API 行为时,日志很有用
日志有助于诊断启动警告、集成状态或 socket API 行为。
常见日志文件:
常见日志文件
```text
~/.config/herdr/herdr.log
@@ -528,4 +445,4 @@ switch_ascii_input_source_in_prefix = false
~/.config/herdr/herdr-server.log
```
日志自动轮转。报告问题时请附上当前日志和轮转的同级文件。
日志自动轮转。报告问题时请附上当前日志和轮转的同级日志文件。
+1 -1
View File
@@ -19,7 +19,7 @@ curl -fsSL https://herdr.dev/install.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://herdr.dev/install.ps1 | iex"
```
安装器会下载适合你平台的发布二进制文件并放到 PATH 上。Windows 安装器默认使用预览通道,把该通道写入 Herdr 配置,使用带版本号的安装文件夹,并更新一个 `current` 联接点,因此更新时不需要覆盖正在运行的 `herdr.exe`。
安装器会下载适合你平台的发布二进制文件并放到 PATH 上。Windows 上,Herdr 默认使用预览通道,且不会修改你的配置。安装器使用带版本号的安装文件夹,并更新一个 `current` 联接点,因此更新时不需要覆盖正在运行的 `herdr.exe`。
## 用 Homebrew 安装
@@ -258,19 +258,16 @@ Herdr 用 `mastracode --thread <id>` 恢复保存的 MastraCode 线程。
## 自定义状态标签
集成可以上报一个简短的视觉标签,而不改变语义状态
例如,一个智能体可以在语义上保持 `working`,同时在 UI 中显示 `indexing`。
集成只把生命周期状态作为语义状态上报。例如,上报智能体为 `working` 时,不在生命周期报告中添加展示字段
```bash
herdr pane report-agent w1:p1 \
--source custom:docs \
--agent docs-bot \
--state working \
--custom-status indexing
--state working
```
与 Herdr 管理的集成并行运行的用户钩子,应该使用元数据而不是 `report-agent`。元数据只改变展示,不会夺走集成对 `idle`、`working`、`blocked` 或会话恢复的权威。`--agent` 是守卫,使上报只在该权威智能体处于活动状态时生效。`--applies-to-source` 守卫,使上报只在该生命周期权威来源处于活动状态时生效。`--display-agent` 修改显示名称。
与 Herdr 管理的集成并行运行的用户钩子,应该使用元数据而不是 `report-agent`。元数据只改变展示,不会夺走集成对 `idle`、`working`、`blocked` 或会话恢复的权威。`--agent` `--applies-to-source` 守卫展示字段 (`--title`、`--display-agent` 和 `--state-label`)。令牌补丁始终生效;上报方负责清除或刷新 TTL。`--display-agent` 修改显示名称。
```bash
herdr pane report-metadata "$HERDR_PANE_ID" \
@@ -278,12 +275,12 @@ herdr pane report-metadata "$HERDR_PANE_ID" \
--agent claude \
--title "Refactor auth middleware" \
--display-agent "Claude: auth" \
--custom-status "refactor auth" \
--token summary="refactor auth" \
--state-label working="refactoring auth" \
--ttl-ms 3600000
```
自定义状态和状态标签只影响视觉。等待、通知和工作区汇总仍使用语义状态。
令牌和状态标签只影响视觉。等待、通知和工作区汇总仍使用语义状态。
## 调试集成状态
+1 -1
View File
@@ -64,7 +64,7 @@ Herdr 是鼠标原生的。你可以点击窗格、标签页、工作区和智
## 复制模式
按 `prefix+[` 让聚焦的窗格进入复制模式。用 `h/j/k/l`、`w/b/e` 和 `{`/`}` 移动,用 `v` 或空格开始选择,用 `y` 或回车复制,用 `q` 或 Esc 不复制直接退出。鼠标拖选可以直接复制,完全不用进入复制模式。
按 `prefix+[` 让聚焦的窗格进入复制模式。用 `h/j/k/l`、tmux 风格的 `w/b/e` 和 `{`/`}` 移动。按 `/` 或 `?` 向前或向后进行文本搜索,再用 `n` 或 `N` 按相同或相反方向重复搜索。查询包含大写字母时区分大小写,否则不区分。用 `v` 或空格开始选择,用 `y` 或回车复制,用 `q` 或 Esc 不复制直接退出。Esc 会先清除当前选择或搜索,然后才退出。复制模式不会暂停窗格进程:停留在底部时继续跟随输出,进入历史记录后保持当前位置。鼠标拖选可以直接复制,完全不用进入复制模式。
## 一切都可以改
+23 -2
View File
@@ -235,11 +235,32 @@ shell 插件可以从各个环境变量读取常用 id,或解析上下文 JSON
清单中窗格的 `placement` 默认为 `overlay`,它在活动窗格上方打开一个
临时的缩放覆盖层,关闭时恢复之前的焦点和缩放。`plugin.pane.open` 请求
可以用 `overlay`、`split`、`tab` 或 `zoomed` 覆盖清单的 placement。
可以用 `overlay`、`popup`、`split`、`tab` 或 `zoomed` 覆盖清单的 placement。
插件窗格打开后就是普通的 Herdr 窗格。插件可以通过 socket 或 CLI 调用
`placement = "popup"` 会打开一个会话级模态终端弹窗,而不改变平铺布局。
可以在清单或 open 请求中指定可选的 `width` 和 `height`;省略时默认为终端大小的一半,数字表示外层终端单元格数,`"80%"` 这样的字符串表示终端区域的百分比。
弹窗会接收包括 Escape 在内的所有终端输入,并在命令退出或发送 `popup.close` 请求时关闭。
小于弹窗最小尺寸的值会限制为最小值。
如果某个插件窗格应始终是临时的,可直接在入口点上声明 placement:
```toml
[[panes]]
id = "picker"
title = "Picker"
platforms = ["linux", "macos"]
placement = "popup"
width = "80%"
height = 20
command = ["sh", "picker.sh"]
```
split、tab、zoomed 和 overlay 插件窗格打开后就是普通的 Herdr 窗格。插件可以通过 socket 或 CLI 调用
`pane.move`、`pane.swap`、`pane.resize`、`pane.zoom` 等标准窗格 API;
窗格跨标签页或工作区移动时,Herdr 会让插件窗格的所有权跟随底层窗格。
弹窗不是 Herdr 窗格,而是会话级单例资源:它没有窗格 id,不会改变插件焦点上下文,不会发出窗格生命周期事件,也不参与 pane、layout、持久化或智能体 API。
其进程不会收到 `HERDR_PANE_ID`;底层平铺窗格仍可通过 `HERDR_PLUGIN_CONTEXT_JSON` 获取。
在 Settings、复制模式或其他 Herdr 模态界面打开时尝试打开弹窗会返回 `ui_busy`;启动成功后,`plugin.pane.open` 返回 `ok`。
在 Windows 上,构建命令、动作命令和事件命令会在裸命令位于 `PATH` 上时
解析常见的 `PATHEXT` shim,比如 `npm.cmd`、`bun.cmd` 和 `pnpm.cmd`。
+72 -17
View File
@@ -95,11 +95,13 @@ herdr pane read w1:p2 --source recent --lines 50
| 服务器 | `ping`、`server.stop`、`server.reload_config`、`server.agent_manifests`、`server.reload_agent_manifests` |
| 通知 | `notification.show` |
| 客户端 | `client.window_title.set`、`client.window_title.clear` |
| 工作区 | `workspace.create`、`workspace.list`、`workspace.get`、`workspace.focus`、`workspace.rename`、`workspace.close` |
| 会话 | `session.snapshot` |
| 工作区 | `workspace.create`、`workspace.list`、`workspace.get`、`workspace.focus`、`workspace.rename`、`workspace.move`、`workspace.report_metadata`、`workspace.close` |
| Worktree | `worktree.list`、`worktree.create`、`worktree.open`、`worktree.remove` |
| 标签页 | `tab.create`、`tab.list`、`tab.get`、`tab.focus`、`tab.rename`、`tab.close` |
| 窗格 | `pane.split`、`pane.swap`、`pane.move`、`pane.zoom`、`pane.layout`、`pane.process_info`、`pane.neighbor`、`pane.edges`、`pane.focus_direction`、`pane.resize`、`pane.list`、`pane.current`、`pane.get`、`pane.rename`、`pane.send_text`、`pane.send_keys`、`pane.send_input`、`pane.read`、`pane.report_agent`、`pane.report_agent_session`、`pane.report_metadata`、`pane.clear_agent_authority`、`pane.release_agent`、`pane.close`、`pane.wait_for_output` |
| 布局 | `layout.export`、`layout.apply` |
| 标签页 | `tab.create`、`tab.list`、`tab.get`、`tab.focus`、`tab.rename`、`tab.move`、`tab.close` |
| 窗格 | `pane.split`、`pane.swap`、`pane.move`、`pane.zoom`、`pane.layout`、`pane.process_info`、`pane.neighbor`、`pane.edges`、`pane.focus_direction`、`pane.resize`、`pane.list`、`pane.current`、`pane.get`、`pane.rename`、`pane.send_text`、`pane.send_keys`、`pane.send_input`、`pane.read`、`pane.graphics.info`、`pane.graphics.set`、`pane.graphics.clear`、`pane.graphics.stream`、`pane.report_agent`、`pane.report_agent_session`、`pane.report_metadata`、`pane.clear_agent_authority`、`pane.release_agent`、`pane.close`、`pane.wait_for_output` |
| 弹窗 | `popup.close` |
| 布局 | `layout.export`、`layout.apply`、`layout.set_split_ratio` |
| 智能体 | `agent.list`、`agent.get`、`agent.read`、`agent.explain`、`agent.send`、`agent.rename`、`agent.focus`、`agent.start` |
| 事件 | `events.subscribe`、`events.wait` |
| 集成 | `integration.install`、`integration.uninstall` |
@@ -107,6 +109,10 @@ herdr pane read w1:p2 --source recent --lines 50
一些 CLI 命令是这些方法的便捷包装。比如 `herdr agent wait` 先解析智能体目标,然后订阅窗格智能体状态事件。
`session.snapshot` 为维护本地运行时缓存的客户端返回一次性引导快照。响应包含版本/协议元数据、当前聚焦的工作区/标签页/窗格 id、工作区记录、标签页记录、窗格记录、标签页布局快照和智能体记录。它不是订阅;读取后应订阅资源事件,并根据事件更新本地缓存。重新连接后或本地缓存可能已过期时,再次调用 `session.snapshot`。工作区记录也包含关联 worktree 的来源信息。完整的仓库 worktree 发现仍使用 `worktree.list`。
CLI 的 `herdr api snapshot` 会把当前 `session.snapshot` 响应输出为 JSON,让客户端和智能体可以简单地完成引导。
窗格控制方法使用 `w1:p1` 这类公开窗格 id。schema 中 `pane_id` 可选的方法,在省略它时使用服务器当前聚焦的活动窗格。`pane.move` 总是要求来源 `pane_id`。
`pane.send_keys` 和 `pane.send_input.keys` 接受 Herdr 组合键字符串: 普通可打印键、`enter` 和 `esc` 这类特殊键、`ctrl+h`、`control+j`、`alt+x`、`shift+tab` 这类修饰组合键、`f1` 这类功能键,以及 `minus` 和 `plus` 这类命名标点。它们不接受 `prefix+` 绑定字符串。
@@ -125,6 +131,35 @@ herdr pane read w1:p2 --source recent --lines 50
`pane.current` 返回单个 `PaneInfo`。带有 `caller_pane_id` 时,Herdr 返回那个窗格。省略时,Herdr 返回当前聚焦的活动窗格。
终端滚动指标可用时,`PaneInfo` 包含 `scroll`:
```json
{
"offset_from_bottom": 12,
"max_offset_from_bottom": 240,
"viewport_rows": 30
}
```
客户端可以把 `offset_from_bottom == 0` 视为位于底部。
### 实验性窗格图形
窗格图形允许插件在窗格上放置图像数据。它们只在 `[experimental].kitty_graphics = true` 时可用;否则所有窗格图形方法都返回 `feature_disabled`。调用 `pane.graphics.info` 会返回所连接客户端的单元格像素宽度和高度,但不会创建图形层。`pane.graphics.set` 接受 `data_base64` 中的 `png`、`rgb` 或 `rgba` 数据,`pane.graphics.clear` 删除该图层。
```json
{"id":"graphics_info","method":"pane.graphics.info","params":{"pane_id":"w1:p1"}}
{"id":"graphics_set","method":"pane.graphics.set","params":{"pane_id":"w1:p1","format":"png","image_width":800,"image_height":600,"data_base64":"...","placement":{"viewport_col":0,"viewport_row":0,"grid_cols":80,"grid_rows":30}}}
{"id":"graphics_clear","method":"pane.graphics.clear","params":{"pane_id":"w1:p1"}}
```
要重复发送帧,用 `pane.graphics.stream` 打开专用 socket。Herdr 回复 `ok` 后,每一帧发送一个 JSON 头,再发送恰好 `data_length` 字节的原始数据。socket 关闭前,该流拥有对应窗格的图形层;并发 set、clear 或 stream 请求返回 `stream_conflict`。
```json
{"id":"graphics_stream","method":"pane.graphics.stream","params":{"pane_id":"w1:p1"}}
{"format":"png","image_width":800,"image_height":600,"data_length":12345,"placement":{"viewport_col":0,"viewport_row":0,"grid_cols":80,"grid_rows":30}}
```
`pane.layout` 返回标签页布局快照,包含 `workspace_id`、`tab_id`、`zoomed`、外层 `area`、`focused_pane_id`、窗格矩形和分割矩形/比例。`pane.neighbor` 和 `pane.edges` 也包含同一份布局快照,让客户端不需要私有布局状态就能做出下一步决策。
`pane.process_info` 返回窗格的 shell pid、可用时的前台进程组 id,以及平台暴露时带有 pid、名称、argv/cmdline 和 cwd 的前台进程。
@@ -168,6 +203,12 @@ herdr pane read w1:p2 --source recent --lines 50
}
```
`layout.set_split_ratio` 更新标签页布局中已有分割的比例。响应是 `type: "layout_split_ratio_set"`,并包含更新后的可移植 `layout`。
```json
{"id":"req_ratio","method":"layout.set_split_ratio","params":{"tab_id":"w1:t1","path":[],"ratio":0.6}}
```
启动进程的方法接受一个 `env` 对象。Herdr 只把这些键值对应用到新启动的进程。Herdr 还向受管窗格进程注入 `HERDR_SOCKET_PATH`、`HERDR_ENV=1`、`HERDR_WORKSPACE_ID`、`HERDR_TAB_ID` 和 `HERDR_PANE_ID`。与调用方提供的环境变量冲突时,Herdr 管理的变量保持权威。
`pane.swap` 支持按方向和显式两种形式:
@@ -360,7 +401,7 @@ v1 没有 Herdr 管理的插件存储 API。`HERDR_PLUGIN_CONFIG_DIR` 和 `HERDR
{"id":"req_plugin_pane","method":"plugin.pane.open","params":{"plugin_id":"example.board","entrypoint":"board","placement":"zoomed","target_pane_id":"w1:p1","env":{"HERDR_ROLE":"board"},"focus":true}}
```
`plugin.pane.open` 要求已安装、已启用、平台兼容的插件,然后把请求的清单 `[[panes]]` 入口点作为 argv 支撑的终端窗格启动。清单窗格的 `placement` 默认为 `overlay`;请求的 `placement` 可以用 `overlay`、`split`、`tab` 或 `zoomed` 覆盖清单。覆盖层窗格针对活动窗格。分割和缩放窗格针对已有窗格;标签页窗格可以针对工作区。窗格打开后表现得像普通 Herdr 窗格,`plugin.pane.focus` 和 `plugin.pane.close` 只作用于通过插件 API 打开的窗格。focus 返回 `plugin_pane_focused`;close 返回 `plugin_pane_closed`
`plugin.pane.open` 要求已安装、已启用、平台兼容的插件,然后把请求的清单 `[[panes]]` 入口点作为 argv 支撑的终端窗格启动。清单窗格的 `placement` 默认为 `overlay`;请求的 `placement` 可以用 `overlay`、`popup`、`split`、`tab` 或 `zoomed` 覆盖清单。overlay 和 popup 使用活动平铺窗格作为启动上下文。弹窗终端是会话级模态界面,不会改变标签页布局;可选的 `width` 和 `height` 以终端单元格数或 `"80%"` 这样的百分比设置外层尺寸。省略时默认为终端大小的一半,过小的值会限制为弹窗最小尺寸。弹窗没有窗格 id,不属于任何 `pane.*` 或智能体 API,不会发出窗格生命周期事件,会把插件焦点上下文保留在底层平铺窗格上,也不会向其进程导出 `HERDR_PANE_ID`。弹窗启动返回 `ok`;`popup.close` 关闭活动弹窗,没有弹窗时返回 `popup_not_open`。split 和 zoomed 针对已有窗格,tab 可以针对工作区。split、tab、zoomed 和 overlay 打开后表现得像普通 Herdr 窗格,`plugin.pane.focus` 和 `plugin.pane.close` 仍可操作这些窗格
## Socket 传输
@@ -415,15 +456,12 @@ Herdr 在本地 socket 上使用换行分隔的 JSON。在 Unix 上,那个 socke
"source": "custom:docs",
"agent": "docs-bot",
"state": "working",
"message": "building docs",
"custom_status": "indexing"
"message": "building docs"
}
}
```
`state` 是语义性的。它影响等待、通知和汇总。
`custom_status` 是视觉性的。它可以显示 `indexing` 这类简短的活动标签,而不改变语义行为。
`state` 是语义性的。它影响等待、通知和汇总。只影响展示的值应通过元数据单独上报。
仅提供会话的官方集成用 `pane.report_agent_session` 上报原生会话引用。上报状态的集成仍然可以在 `pane.report_agent` 中包含原生会话引用。与状态无关的会话上报不影响等待、通知或汇总。
@@ -457,6 +495,8 @@ Herdr 存有原生会话引用时,`pane.get`、`pane.list`、`agent.get` 和 `ag
当 Herdr 能解析当前控制窗格 PTY 的进程的 cwd 时,`pane.get`、`pane.list`、`agent.get` 和 `agent.list` 也暴露 `foreground_cwd`。已有的 `cwd` 字段仍然是用于标签、follow-cwd 行为和恢复会话状态的窗格/工作区 cwd。
`PaneInfo` 和 `AgentInfo` 暴露可选的 `terminal_title` 和 `terminal_title_stripped` 字段。`terminal_title` 是经过安全规范化的最新 OSC 0/2 标题。`terminal_title_stripped` 会移除开头一个已识别的活动或旋转指示符字形及其后的空白。这些值归服务器所有,冷重启后不会保留,并且独立于元数据 `title` 和语义智能体状态。
当用户钩子想自定义展示、又不从 Herdr 集成接管生命周期状态时,使用 `pane.report_metadata`。
```json
@@ -469,26 +509,39 @@ Herdr 存有原生会话引用时,`pane.get`、`pane.list`、`agent.get` 和 `ag
"agent": "claude",
"title": "Refactor auth middleware",
"display_agent": "Claude: auth",
"custom_status": "refactor auth",
"state_labels": {
"working": "refactoring auth",
"idle": "ready",
"done": "review ready"
},
"tokens": {
"summary": "refactor auth",
"model": "opus"
},
"ttl_ms": 3600000
}
}
```
元数据上报只影响展示。有效的元数据可以覆盖窗格标题、显示的智能体名称、紧凑的活动标签和可见的状态标签。`working`、`blocked`、`idle`、等待、通知和汇总仍来自语义状态。原生会话恢复来自存储的官方会话引用。`agent` 是对权威智能体标签的可选守卫;`applies_to_source` 是对活动生命周期权威来源的可选守卫。用 `display_agent` 修改可见名称。`state_labels` 的键必须是 `idle`、`working`、`blocked`、`done` 或 `unknown`。用相同 `source` 搭配 `clear_custom_status: true` 这类清除字段,可以移除某一项展示覆盖。
元数据上报只影响展示。有效的元数据可以覆盖窗格标题、显示的智能体名称、可见的状态标签和任意命名令牌。`working`、`blocked`、`idle`、等待、通知和汇总仍来自语义状态。原生会话恢复来自存储的官方会话引用。`agent` 是展示字段针对权威智能体标签的可选守卫;`applies_to_source` 同样保护展示字段,使其只适用于活动生命周期权威来源。这些守卫不作用于令牌补丁;令牌上报方负责清除和刷新 TTL。用 `display_agent` 修改可见名称。`state_labels` 的键必须是 `idle`、`working`、`blocked`、`done` 或 `unknown`。
展示文本在存储前被规范化。Herdr 去掉首尾空白、移除控制字符、把 `custom_status` 截断到 32 个字符,把 `title`、`display_agent` 和每个状态标签截断到 80 个字符。规范化后为空的值被忽略
令牌映射是针对每个资源的补丁。字符串设置键,JSON `null` 清除键,未提及的键保持不变。最后接受的更新生效。可选 TTL 分别应用于该次上报更新的每个令牌键。窗格令牌会在 pane 和 agent 的 get/list 响应中公开,并可在智能体侧边栏行中写成 `$name`。单次上报最多可包含 16 个令牌键,每个窗格或工作区最多保留 32 个键。令牌名称必须由 1–32 个 ASCII 字母、数字、下划线或连字符组成
工作区令牌使用相同约定:
```json
{"id":"req_3","method":"workspace.report_metadata","params":{"workspace_id":"w1","source":"user:jj","tokens":{"jj_status":"2 changes","old":null},"ttl_ms":5000}}
```
workspace 的 get/list 响应会公开生成的 `tokens` 映射,空间侧边栏行可显示 `$jj_status` 这类值。变更和 TTL 到期会发出包含最新工作区快照的 `workspace.metadata_updated`。该元数据事件会发送给 API 订阅者,但不会调用插件事件钩子。
展示文本在存储前被规范化。Herdr 去掉首尾空白、移除控制字符,并把 `title`、`display_agent`、每个状态标签和令牌值截断到 80 个字符。规范化后为空的令牌值会清除该键。
`source` 和 `applies_to_source` 是来源标识符。它们必须不超过 80 个字符,且只能包含 ASCII 字母、数字、冒号、点、下划线和连字符。
短期元数据用 `ttl_ms`。取值必须在 `1` 到 `86400000` 毫秒之间。想让元数据保留到被替换、清除或窗格关闭时,省略 `ttl_ms`。TTL 过期时,Herdr 移除该来源的元数据,并在可见窗格展示发生变化时发出展示变化事件
短期元数据用 `ttl_ms`。取值必须在 `1` 到 `86400000` 毫秒之间。想让元数据保留到被替换、清除或窗格或工作区关闭时,省略 `ttl_ms`。展示字段继续按来源过期;该次调用更新的每个令牌都有独立期限。令牌元数据不会在服务器重启后恢复
钩子可能乱序发送更新时,使用 `seq`。对同一 `source`,序号小于等于最后接受序号的上报会被 API 接受,但被窗格状态忽略。
钩子可能乱序发送更新时,使用 `seq`。对同一 `source`,序号小于等于最后接受序号的上报会被 API 接受,但被窗格状态忽略。每个窗格或工作区在其生命周期内最多接受来自 32 个不同来源的带序号令牌上报;清除或过期不会释放这些来源名额。
## 事件订阅
@@ -508,8 +561,10 @@ Herdr 存有原生会话引用时,`pane.get`、`pane.list`、`agent.get` 和 `ag
第一个响应确认订阅。之后的行是推送的事件。
工作区事件订阅包括 `workspace.created`、`workspace.updated`、`workspace.renamed`、`workspace.closed` 和 `workspace.focused`。工作区事件描述 Herdr UI/运行时的生命周期。当工作区属于 worktree 组时,`workspace.created` 包含可选的 `workspace.worktree` 来源信息。在移除前 Herdr 仍能识别时,`workspace.closed` 包含最终的 `workspace` 快照。
窗格事件订阅包括 `pane.created`、`pane.closed`、`pane.focused`、`pane.moved`、`pane.exited`、`pane.agent_detected`、`pane.output_matched` 和 `pane.agent_status_changed`
工作区事件订阅包括 `workspace.created`、`workspace.updated`、`workspace.metadata_updated`、`workspace.renamed`、`workspace.moved`、`workspace.closed` 和 `workspace.focused`。`workspace.metadata_updated` 报告令牌变更和 TTL 到期,但不会调用插件事件钩子。其他工作区事件描述 Herdr UI/运行时的生命周期。当工作区属于 worktree 组时,`workspace.created` 包含可选的 `workspace.worktree` 来源信息。`workspace.moved` 包含被移动的 `workspace_id`、请求的 `insert_index` 和更新后的有序 `workspaces` 列表。在移除前 Herdr 仍能识别时,`workspace.closed` 包含最终的 `workspace` 快照。
标签页事件订阅包括 `tab.created`、`tab.closed`、`tab.focused`、`tab.renamed` 和 `tab.moved`。`tab.moved` 包含被移动的 `tab_id`、`workspace_id`、请求的 `insert_index` 和该工作区更新后的有序 `tabs` 列表
窗格事件订阅包括 `pane.created`、`pane.updated`、`pane.closed`、`pane.focused`、`pane.moved`、`pane.exited`、`pane.agent_detected`、`pane.output_matched`、`pane.agent_status_changed` 和 `pane.scroll_changed`。终端标题变化可能发出 `pane.updated`,但如果原始标题只有旋转指示符发生变化且 `terminal_title_stripped` 不变,则不会发出。`pane.scroll_changed` 只针对一个 `pane_id`,每当 Herdr 观察到滚动快照变化时,都会发出 `pane_id`、`workspace_id` 和当前 `scroll` 指标。
布局事件订阅包括 `layout.updated`。该事件携带一个标签页更新后的 `PaneLayoutSnapshot`。使用 `session.snapshot` 引导的客户端应替换具有相同 `workspace_id` 和 `tab_id` 的缓存布局。
Worktree 事件订阅包括 `worktree.created`、`worktree.opened` 和 `worktree.removed`。Worktree 事件描述 Git 检出的生命周期。`worktree.created` 包含打开的 `workspace` 和创建的 `worktree`。`worktree.opened` 包含目标 `workspace`、打开的 `worktree` 和 `already_open`。`worktree.removed` 包含 `workspace_id`、被移除的 `worktree` 和 `forced`。
@@ -26,6 +26,26 @@ herdr status
长期支持版 Linux 发行版中的旧终端软件包尤其容易出现此问题。已确认的边界捕获和上游链接见 [Herdr issue #1116](https://github.com/ogulcancelik/herdr/issues/1116)。如果当前版本仍有问题,请报告准确的终端版本,以及该问题是否也会在 Herdr 外出现。
## 按 Option+Left 或 Option+Right 时输入 `;3D` 或 `;3C`
终端通常把 Alt+Left 和 Alt+Right 发送为标准的带修饰键方向键序列 `ESC[1;3D` 和 `ESC[1;3C`。在 macOS 上,需要先把外层终端配置为将 Option 视为 Alt。如果 shell 没有绑定这些序列,zsh 可能会把剩余字符显示为 `;3D` 或 `;3C`。kitty、Alacritty 和其他终端都可能出现这种情况;Herdr 和 tmux 都会保留原始的带修饰键方向键输入。
如果希望带修饰键的方向键在所有终端和嵌套 shell 中都执行按单词移动,请添加明确的 zsh 绑定:
```zsh
bindkey $'\e[1;3D' backward-word
bindkey $'\e[1;3C' forward-word
```
kitty 在 Herdr 外可能表现不同,因为它的自动 zsh 集成只会为 kitty 直接启动的 shell 添加这些绑定,而不会为终端多路复用器创建的 shell 添加。请按照 kitty 的[手动 shell 集成说明](https://sw.kovidgoyal.net/kitty/shell-integration/#manual-shell-integration),或在按键到达 shell 前通过 `kitty.conf` 映射它们:
```text
map alt+left send_text all \x1bb
map alt+right send_text all \x1bf
```
终端应用可能会直接使用 Alt+Left 和 Alt+Right,因此 Herdr 不会改写带修饰键的方向键。调查详情见 [Herdr issue #1370](https://github.com/ogulcancelik/herdr/issues/1370)。
## Herdr 已更新,但运行中的会话仍是旧版本
更新二进制文件不一定会替换已经运行且兼容的服务器。先检查 `herdr status`。要启动更新后的服务器,请停止会话并重新启动 Herdr:
@@ -15,7 +15,7 @@ Windows 上的 Herdr 使用 ConPTY 和 Windows 的进程/运行时行为,而不
powershell -ExecutionPolicy Bypass -c "irm https://herdr.dev/install.ps1 | iex"
```
Windows 测试版构建只通过预览通道发布。Windows 安装器默认使用预览通道,把 `channel = "preview"` 写入 Herdr 配置,将发布版本保存在 `%USERPROFILE%\.herdr\packages\standalone\releases` 下,让 `%LOCALAPPDATA%\Programs\Herdr\bin` 指向当前版本,并保留少量旧版本,以免运行中的进程阻塞更新。
Windows 测试版构建只通过预览通道发布。Windows 上,Herdr 默认使用预览通道,且不会修改你的配置。安装器将发布版本保存在 `%USERPROFILE%\.herdr\packages\standalone\releases` 下,让 `%LOCALAPPDATA%\Programs\Herdr\bin` 指向当前版本,并保留少量旧版本,以免运行中的进程阻塞更新。
对于内部测试,`HERDR_MANIFEST_URL` 可以让安装器指向自定义清单,而不是 Herdr 的稳定或预览清单。
@@ -61,9 +61,9 @@ Kitty graphics 仍是实验性功能,尚未宣称支持 Windows。除非你专
### 光标渲染
Windows 终端通过 ConPTY 运行 Herdr,在活跃的全屏重绘期间,原生终端光标可能闪烁、跳动,或短暂显示旧位置。Herdr 默认的 `host_cursor = "auto"` 会在 Windows 上把 Herdr 光标绘制为终端单元格内容,而 Linux 和 macOS 继续使用原生终端光标。Windows 上的取舍是:在 Herdr 内得到稳定的不闪烁光标,但不使用外层终端的原生闪烁、形状和光标颜色。
Windows 终端通过 ConPTY 运行 Herdr,在活跃的全屏重绘期间,原生终端光标可能闪烁、跳动,或短暂显示旧位置。Herdr 默认的 `host_cursor = "auto"` 会在原生 Windows 构建和 WSL 上把 Herdr 光标绘制为终端单元格内容,而其他 Linux 和 macOS 客户端继续使用原生终端光标。Windows 上的取舍是:在 Herdr 内得到稳定的不闪烁光标,但不使用外层终端的原生闪烁、形状和光标颜色。
要在 Windows 上改回外层终端光标,请设置:
要在原生 Windows 或 WSL 上改回外层终端光标,请设置:
```toml
[ui]
+48 -1
View File
@@ -587,6 +587,12 @@
"default": "true",
"description": "Capture mouse input for Herdr's mouse UI."
},
{
"key": "ui.copy_on_select",
"type": "boolean",
"default": "true",
"description": "Copy text selected with the mouse."
},
{
"key": "ui.host_cursor",
"type": "enum",
@@ -662,6 +668,36 @@
"priority"
]
},
{
"key": "ui.sidebar.agents.row_gap",
"type": "integer",
"default": "0",
"description": "Blank terminal rows between expanded Agent sidebar entries. Set to 1 to restore the previous spacing."
},
{
"key": "ui.sidebar.agents.rows",
"type": "list of token rows",
"default": "[[\"state_icon\", \"workspace\", \"tab\"], [\"agent\"]]",
"description": "Default expanded Agent sidebar layout. Supports built-in tokens and $name metadata tokens; at most 16 rows and 16 tokens per row."
},
{
"key": "ui.sidebar.agents.rows_by_agent",
"type": "table of token rows",
"default": "{}",
"description": "Complete Agent-row overrides keyed by strict canonical agent id. Agents without an override use ui.sidebar.agents.rows."
},
{
"key": "ui.sidebar.spaces.row_gap",
"type": "integer",
"default": "0",
"description": "Blank terminal rows between expanded Space sidebar entries. Set to 1 to restore the previous spacing. Consecutive indented worktree children remain packed as one group."
},
{
"key": "ui.sidebar.spaces.rows",
"type": "list of token rows",
"default": "[[\"state_icon\", \"workspace\"], [\"branch\", \"git_status\"]]",
"description": "Expanded Space sidebar layout. Supports built-in tokens and $name metadata tokens; at most 16 rows and 16 tokens per row."
},
{
"key": "ui.accent",
"type": "color",
@@ -951,6 +987,17 @@
"on",
"off"
]
},
{
"key": "ui.sound.agents.maki",
"type": "enum",
"default": "\"default\"",
"description": "Sound override for detected Maki agents.",
"values": [
"default",
"on",
"off"
]
}
]
},
@@ -1034,7 +1081,7 @@
"key": "experimental.cjk_ime_agents",
"type": "list of strings",
"default": "[]",
"description": "Restrict `reveal_hidden_cursor_for_cjk_ime` to focused panes whose detected agent matches one of these names (case-insensitive). Empty list means apply to any focused pane. Unknown agent names are ignored; if the list contains no valid names, the reveal does not apply. Accepted names: pi, claude, codex, gemini, cursor, devin, cline, opencode, copilot, kimi, kiro, droid, amp, grok, hermes, kilo, qodercli, qoder."
"description": "Restrict `reveal_hidden_cursor_for_cjk_ime` to focused panes whose detected agent matches one of these names (case-insensitive). Empty list means apply to any focused pane. Unknown agent names are ignored; if the list contains no valid names, the reveal does not apply. Accepted names: pi, claude, codex, gemini, cursor, devin, cline, opencode, copilot, kimi, kiro, droid, amp, grok, hermes, kilo, qodercli, qoder, maki."
},
{
"key": "experimental.cjk_ime_cursor_shape",