From bc064e9d034711ba40e4e42a0129934752f0b802 Mon Sep 17 00:00:00 2001 From: Ogulcan Celik Date: Tue, 21 Jul 2026 21:01:27 +0300 Subject: [PATCH] docs: finalize release docs and refresh agent skill --- CHANGELOG.md | 45 +++++ SKILL.md | 158 +++++++++--------- docs/next/CHANGELOG.md | 26 ++- .../src/content/docs/agent-automation.mdx | 11 +- .../src/content/docs/cli-reference.mdx | 4 +- .../src/content/docs/ja/agent-automation.mdx | 11 +- .../src/content/docs/ja/cli-reference.mdx | 4 +- .../website/src/content/docs/ja/plugins.mdx | 38 ++++- .../src/content/docs/ja/socket-api.mdx | 74 ++++++++ .../content/docs/zh-cn/agent-automation.mdx | 11 +- .../src/content/docs/zh-cn/cli-reference.mdx | 4 +- .../src/content/docs/zh-cn/plugins.mdx | 34 +++- .../src/content/docs/zh-cn/socket-api.mdx | 70 ++++++++ website/src/content/docs/agent-automation.mdx | 121 ++++++++++++++ website/src/content/docs/agent-skill.mdx | 2 +- website/src/content/docs/agents.mdx | 24 +-- website/src/content/docs/cli-reference.mdx | 67 ++++++-- website/src/content/docs/configuration.mdx | 16 +- website/src/content/docs/integrations.mdx | 4 +- .../src/content/docs/ja/agent-automation.mdx | 121 ++++++++++++++ website/src/content/docs/ja/agent-skill.mdx | 2 +- website/src/content/docs/ja/agents.mdx | 24 +-- website/src/content/docs/ja/cli-reference.mdx | 68 ++++++-- website/src/content/docs/ja/configuration.mdx | 16 +- website/src/content/docs/ja/integrations.mdx | 4 +- website/src/content/docs/ja/plugins.mdx | 38 ++++- website/src/content/docs/ja/session-state.mdx | 2 + website/src/content/docs/ja/socket-api.mdx | 86 +++++++++- website/src/content/docs/plugins.mdx | 39 ++++- website/src/content/docs/session-state.mdx | 2 + website/src/content/docs/socket-api.mdx | 95 ++++++++++- .../content/docs/zh-cn/agent-automation.mdx | 121 ++++++++++++++ .../src/content/docs/zh-cn/agent-skill.mdx | 2 +- website/src/content/docs/zh-cn/agents.mdx | 24 +-- .../src/content/docs/zh-cn/cli-reference.mdx | 68 ++++++-- .../src/content/docs/zh-cn/configuration.mdx | 16 +- .../src/content/docs/zh-cn/integrations.mdx | 4 +- website/src/content/docs/zh-cn/plugins.mdx | 34 +++- .../src/content/docs/zh-cn/session-state.mdx | 2 + website/src/content/docs/zh-cn/socket-api.mdx | 82 ++++++++- website/src/data/config-reference.json | 16 +- 41 files changed, 1309 insertions(+), 281 deletions(-) create mode 100644 website/src/content/docs/agent-automation.mdx create mode 100644 website/src/content/docs/ja/agent-automation.mdx create mode 100644 website/src/content/docs/zh-cn/agent-automation.mdx diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ee3ae06..7efcd08d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,51 @@ ## Unreleased +### Breaking Changes +- Installed and linked plugins, including their enabled state, are now global to the current user instead of isolated by Herdr session. Plugins installed only in a named session on Herdr 0.7.3 must be installed or linked again. (#1174) + +### Added +- Added a live-agent CLI facade with named `start`, atomic `prompt`, logical `send-keys`, and server-owned `wait` workflows. Agent startup targets an existing pane without changing topology, validates the requested interactive agent kind and strict agent name, and accepts native arguments after `--`. +- Added transient declarative Agent view queries through `agent.view.set/clear`; filtered and sorted views now define sidebar, mobile, mouse, and agent-keybind navigation order. +- Added one-shot plugin `[[startup]]` hooks for restoring plugin-owned state after server startup and live handoff. +- Added per-token foreground, bold, and dim styling to expanded Space and Agent sidebar row layouts. +- Added `ui.sidebar_start_collapsed` to launch Herdr with the sidebar collapsed. (#1463) +- Added `ui.prompt_new_workspace_name` to ask for a workspace name before interactive TUI creation. +- Added macOS support for the `HERDR_AGENT=` foreground-process hint, allowing agents hidden behind host-visible wrappers such as `nono` to use the named agent's screen manifest. (#679) + +### Changed +- Agent commands now accept only a unique live agent name or the pane ID currently hosting that agent. Names are cleared when the occupant exits, is released, or is replaced. The old top-level `wait` commands were replaced by `agent wait` and `pane wait-output`, and `agent send` was replaced by `agent send-keys`. +- The session navigator now uses connected tree glyphs, groups matches by workspace, and automatically selects the first result when a search begins. (#1611) + +### Fixed +- CLI requests now return a machine-readable `protocol_mismatch` error when the client and server protocols differ, while recovery commands remain available. (#1435) +- Linux sound notifications now terminate and reap audio players that do not exit, preventing unavailable audio from leaving CPU-bound `mpg123` processes behind. (#1622) +- Oversized bracketed text pastes are now rejected with a client-local notification instead of disconnecting the client. (#1665) +- Agent prompt waits now report `agent_prompt_stalled` after five seconds without an observed state change instead of waiting indefinitely after an ineffective submission. +- `herdr config check` now reports unknown config keys with their full paths instead of treating ignored typos as valid configuration. (#1573) +- Codex panes with customized static terminal titles now fall back to the live working footer instead of remaining idle, while OSC activity remains preferred. (#1563) +- Grok panes now preserve working and blocked state from terminal signals and pinned background-work status instead of falling back to idle mid-turn. +- OpenCode lifecycle reports are now serialized so out-of-order plugin events cannot leave an idle pane marked working. (#1519) +- Kimi question prompts now report blocked until the user answers or dismisses them. +- Pi lifecycle reporting now uses settled events, preventing transient message boundaries from publishing an idle state mid-turn. +- The Pi, OMP, OpenCode, and Kilo Code integrations can now be installed on Windows and report lifecycle state and native session identity through Herdr's named-pipe API. (#1531) +- Named agent prompts now honor live bracketed-paste mode before sending Enter, preserving OpenCode text such as `A != B` instead of triggering shell mode. (#1525) +- New panes, tabs, layouts, and workspaces using `new_cwd = "follow"` now inherit the foreground process-group leader's working directory instead of an unrelated helper process directory. (#1472) +- Cached pane working directories no longer trigger repeated filesystem checks, avoiding slow sidebar rendering on network filesystems such as Ceph. (#1603) +- Windows foreground-process snapshots are now shared across panes, reducing idle CPU use in sessions with many panes. (#1158) +- Terminal diff streams now batch contiguous writes, reducing the visible wave effect while scrolling pane history. (#283) +- A standalone Escape arriving beside another key is now preserved as its own input instead of being combined into a fabricated Alt chord. (#541) +- Pane viewports that were following live output now continue following after a resize. +- Mouse selections now remain visible when `ui.copy_on_select = false` while clipboard writes stay disabled. (#1471) +- Workspace close confirmation now shows the current workspace name instead of a stale or unrelated label. (#1364) +- Plugin command arrays now preserve whitespace-only arguments. (#1594, #1613) +- Plugins can now be installed or linked while no Herdr server is running. (#1670) +- Remote attach now discovers Herdr installed in mise's canonical tool path before offering to install a sidecar binary. (#1201) +- Noninteractive update, plugin, integration, sound, custom-command, and Git subprocesses no longer flash console windows on Windows. (#1468) +- Live handoff now preserves installed plugins and no longer lets the next plugin installation overwrite the existing registry. (#893) +- `herdr agent wait` now returns `agent_not_running` promptly when its target pane closes instead of waiting for the full timeout. (#1439) +- Pane graphics streams now shut down cleanly when a client disconnect races stream teardown. + ## [0.7.4] - 2026-07-15 ### Added diff --git a/SKILL.md b/SKILL.md index 63e15bc4..a7b86ef9 100644 --- a/SKILL.md +++ b/SKILL.md @@ -1,13 +1,13 @@ --- name: herdr -description: "Control Herdr, a terminal multiplexer for coding agents. Use only when the user explicitly mentions Herdr or asks to use Herdr to inspect or control panes, tabs, workspaces, terminals, commands, or communication with another agent. Do not use merely because a task could benefit from a background terminal, delegation, or parallel work. Requires HERDR_ENV=1." +description: "Control Herdr, a terminal multiplexer for coding agents. Use only when the user explicitly mentions Herdr or asks to use Herdr to inspect or control panes, tabs, workspaces, commands, or another agent. Do not use merely because a task could benefit from a background terminal, delegation, or parallel work. Requires HERDR_ENV=1." --- # Herdr -Herdr is a terminal multiplexer and runtime for coding agents. It organizes terminals into workspaces, tabs, and panes, detects agent identity and status, and exposes the running session through the `herdr` CLI. +Herdr organizes terminals into workspaces, tabs, and panes, recognizes coding agents running inside panes, and exposes the current session through the `herdr` CLI. -Before issuing any control command, check that this agent is running inside a Herdr-managed pane: +Before issuing any control command, verify that this agent is running inside a Herdr-managed pane: ```bash test "${HERDR_ENV:-}" = 1 @@ -15,54 +15,65 @@ test "${HERDR_ENV:-}" = 1 If the check fails, say that you are not running inside Herdr and stop. Do not inspect or control the focused Herdr session from outside Herdr. -When the check passes, the `herdr` binary in `PATH` talks to the running session. Use it to inspect neighboring work, create isolated terminal contexts, start agents and commands, read their output, and wait for state changes. +When the check passes, the `herdr` binary in `PATH` talks to the current session. Use it to inspect neighboring work, create terminal layout, start agents and commands, read output, and wait for state changes. ## Learn the current CLI -The installed binary is the authority for command syntax. Begin with: +The installed binary is the authority for command syntax. Start with: ```bash herdr --help ``` -Then print the relevant command group by running it without a subcommand: +Then print the relevant command group by running the group without a subcommand: ```bash +herdr agent herdr pane herdr workspace -herdr worktree herdr tab -herdr wait +herdr worktree herdr terminal herdr notification herdr integration herdr session ``` -Do not run bare `herdr` for discovery; it launches or attaches the TUI. Do not probe a mutating nested command by omitting arguments; some commands, including `herdr workspace create`, are valid with defaults and will execute. Use the command-group output above instead. +Do not run bare `herdr` for discovery; it launches or attaches the TUI. Do not probe a mutating nested command by omitting arguments. Commands such as `herdr workspace create` are valid with defaults and will execute. -Most control commands print JSON. Read identifiers and state from those responses instead of predicting either one. +Most control commands return JSON. Read identifiers and state from those responses instead of predicting them. -## IDs and current context +## Understand layout, panes, and agents -Public IDs are short stable handles: +Choose the primitive that matches the job: + +- Workspace, tab, and pane topology organize terminal locations. +- Pane commands control raw terminals, shells, tests, servers, input, and output. +- Agent commands control the recognized coding agent currently occupying a pane. + +A pane exists whether or not it contains an agent. `agent start` requires an existing available shell pane and never creates, splits, or moves layout. Use pane commands for ordinary processes. Use agent commands when Herdr must validate agent identity or interpret `idle`, `working`, `blocked`, `done`, and `unknown` lifecycle states. + +Agent commands accept either a unique live agent name or the pane ID currently hosting that agent. They do not accept terminal IDs or bare agent-kind labels. Names must match `[a-z][a-z0-9_-]{0,31}` and be unique among live agents. A name follows the current pane occupant and is cleared when that agent exits, is released, or is replaced. + +`idle` means the agent is ready for input and its tab has been seen in the focused Herdr UI. `done` is the same underlying idle state after unseen background work finishes. Focusing the tab or targeting the pane or agent with a focus command marks it seen. CLI reads do not mark it seen. `blocked` means Herdr recognized an approval or question UI. `unknown` means an agent is present but Herdr cannot classify it confidently; it does not prove completion. + +## Use IDs and caller context + +Public IDs are opaque stable handles: - workspace: `w1` - tab: `w1:t1` - pane: `w1:p1` -- terminal: `term_...` -The encoded suffix can contain letters and can grow beyond one character. Treat every ID as an opaque string. +Closed tab and pane IDs are not reused. A pane moved into another workspace receives a new workspace-qualified pane ID. After `pane move`, continue with `.result.move_result.pane.pane_id` or the live agent name. The old value is reported as `.result.move_result.previous_pane_id`; only the moved process's inherited caller context keeps resolving that old ID, so do not use it as a general agent target. -Closed tab and pane IDs are not reused and do not retarget later resources. A pane moved into another workspace receives a new public pane ID. Re-read create, split, move, list, or get responses after mutations; never construct an ID from a workspace or display number. - -Herdr injects the caller's stable context into every managed pane: +Herdr injects the caller's context into each managed pane: ```bash printf '%s\n' "$HERDR_WORKSPACE_ID" "$HERDR_TAB_ID" "$HERDR_PANE_ID" ``` -Prefer `--current` when a pane command should target the calling pane. Omitting a target can use the UI-focused pane, which may belong to the user or another client. +Prefer `--current` when a pane command should target the calling pane. Omitting a target may use the UI-focused pane, which can belong to the user or another client. Discover live state with: @@ -71,125 +82,112 @@ herdr workspace list herdr tab list --workspace "$HERDR_WORKSPACE_ID" herdr pane current --current herdr pane list --workspace "$HERDR_WORKSPACE_ID" +herdr agent list ``` -## Control agents through panes +Creation responses expose the IDs to use next. `workspace create` returns `.result.workspace`, `.result.tab`, and `.result.root_pane`. `tab create` returns `.result.tab` and `.result.root_pane`. `pane split` returns the new pane as `.result.pane`. -An agent runs inside a pane. Use the pane ID as the control target for agents, shells, servers, tests, and logs. This keeps spawning, input, reads, waits, and cleanup on one stable control surface. +## Start and coordinate an agent -Use workspace and tab commands for organization. Use worktree commands only when you intentionally want Herdr to create, open, or remove a Git checkout. +Default to a sibling pane in the current tab and the current working directory. Do not create a workspace, tab, worktree, or different cwd unless the user explicitly requests that topology or location. -Pane records expose `agent`, `agent_status`, and native session metadata when available. Agent status is `idle`, `working`, `blocked`, `done`, or `unknown`. - -`idle` and `done` are the same underlying semantic state with different attention state: - -- `idle`: the agent is waiting and its result is considered seen. -- `done`: the agent finished and its result has not been seen. - -An agent that first opens at its prompt reports `idle`, including in a background pane. After a working or blocked agent completes, it reports `done` when its tab or workspace is in the background. It reports `idle` when it completes in the active tab while the foreground client is focused. If the foreground client is explicitly unfocused, completion can become `done` even in the active tab. - -Focusing a pane, switching to its tab, or regaining outer terminal focus marks the visible tab as seen, so `done` becomes `idle`. Switching away does not turn an existing `idle` status into `done`; `done` is created by a later completion while the pane is unseen. With no foreground client, a new completion in the globally active tab is treated as seen while completions in background tabs still become `done`. - -## Start agents interactively - -Default to a sibling pane in the current tab and current working directory. Do not create a workspace, tab, worktree, or different cwd unless the user explicitly requests that topology or location. - -Honor a direction requested by the user. Otherwise inspect the caller pane's current rectangle: +Honor a direction requested by the user. Otherwise inspect the caller pane: ```bash herdr pane layout --pane "$HERDR_PANE_ID" ``` -Split a wide pane to the right and a narrow or tall pane down. Avoid repeated same-direction splits that would create unusably narrow columns or short rows. Keep the user's focus in the calling pane: +Split a wide pane to the right and a narrow or tall pane down. Avoid repeated same-direction splits that create unusably narrow columns or short rows. Keep the user's focus in the calling pane and explicitly preserve the caller's working directory: ```bash -herdr pane split --current --direction right --no-focus +herdr pane split --current --direction right --cwd "$PWD" --no-focus ``` -Replace `right` with `down` when the layout calls for it. +Replace `right` with `down` when appropriate. Read the new pane ID from `.result.pane.pane_id`. -Read `result.pane.pane_id` from the JSON response. Give the pane a useful label, then start the requested agent by running only its normal executable so its interactive TUI opens: +An available shell pane must be at its interactive prompt, with the shell itself in the foreground and no foreground command, editor, or agent running. Start a supported agent in that pane with a useful unique name: ```bash -herdr pane rename "reviewer" -herdr pane run "codex" +herdr agent start reviewer --kind codex --pane ``` -Use the executable that belongs to the requested agent: - -- Codex: `codex` -- Claude Code: `claude` -- pi: `pi` -- OpenCode: `opencode` -- OMP: `omp` - -Do not pass the task as an argv prompt by default. Do not add non-interactive flags. Only change the normal interactive launch when the user explicitly asks for a different launch mode or command. - -Inspect the pane after launch. If `agent_status` is not yet `idle`, wait for the idle transition. Once it is idle, submit the task with `pane run`: +Use the kind requested by the user. Run `herdr agent` to inspect the installed kind list and options. Pass native agent arguments only after `--`: ```bash -herdr pane get -herdr wait agent-status --status idle --timeout 30000 -herdr pane run "Review the current diff and report only actionable findings." +herdr agent start reviewer --kind codex --pane -- ``` -Status waits match the current status immediately or wait for a future matching transition. +`agent start` returns only after Herdr detects the expected agent in the same pane and considers it ready for interactive input. It defaults to a 30-second startup timeout. -`pane run` sends the text and Enter together. Use it for initial prompts and follow-ups instead of coordinating `send-text` and `send-keys` separately. - -For normal background work, wait for the agent to start working. If the pane remains in a background tab or workspace, wait for `done` before reading its transcript: +Submit work through the agent surface: ```bash -herdr wait agent-status --status working --timeout 30000 -herdr wait agent-status --status done --timeout 120000 -herdr pane read --source recent-unwrapped --lines 120 +herdr agent prompt reviewer "Review the current diff and report only actionable findings." --wait --timeout 120000 ``` -If the user is watching that tab, completion reports `idle` instead, so wait for `idle`. Always treat either `idle` or `done` as completed when inspecting `pane get`; the difference is whether the result has been seen. +`agent prompt` atomically submits text and encoded Enter while honoring the pane's live bracketed-paste mode. For normal agent work, `--wait` is enough: it waits for the first settled `idle`, `done`, or `blocked` state. Do not repeat those defaults with `--until`. -If a wait times out, inspect `herdr pane get ` and `pane read` before deciding what to do. A `blocked` agent needs input; an `unknown` pane may not yet contain a detected or integrated agent. +A prompt sent from a non-working state must produce an observed lifecycle change within five seconds. Otherwise Herdr returns `agent_prompt_stalled` instead of waiting indefinitely. This wait tracks lifecycle state, not an individual turn; if the agent is already working, completion of the active turn may satisfy it. -Submit follow-ups the same way: +Use `--until` only for a state-specific workflow, such as waiting for an already-running agent to request input: ```bash -herdr pane run "Now check the failing test." +herdr agent wait reviewer --until blocked --timeout 120000 ``` +Without `--until`, standalone `agent wait` uses the same settled-state defaults as `agent prompt --wait`. + +Use logical keys for interactive agent UI controls: + +```bash +herdr agent send-keys reviewer esc +herdr agent send-keys reviewer ctrl+c +``` + +Herdr validates all keys before writing any bytes. Read the result through the resolved agent: + +```bash +herdr agent get reviewer +herdr agent read reviewer --source recent-unwrapped --lines 120 +``` + +If a wait fails or returns `blocked`, inspect `agent get` and `agent read` before deciding what input to send. Use the pane surface only when raw terminal control is intentional. + ## Run an ordinary command in another pane -Split the calling pane using the same geometry rule without moving the user's focus: +Create a sibling pane with the same geometry rule, preserve the caller's working directory, and keep user focus unchanged: ```bash -herdr pane split --current --direction right --no-focus +herdr pane split --current --direction right --cwd "$PWD" --no-focus ``` -Read the new `pane_id` from the JSON response, then run and inspect the command: +Read the new pane ID from `.result.pane.pane_id`, then run and inspect the command: ```bash herdr pane run "just test" -herdr wait output --match "test result" --timeout 120000 +herdr pane wait-output --match "test result" --timeout 120000 herdr pane read --source recent-unwrapped --lines 120 ``` -Inspect existing output before waiting for future output. A wait timeout exits with status `1`. +`pane run` atomically sends command text and Enter. `pane wait-output` searches the selected snapshot immediately, so output that already exists can match. Use `--match ` for a literal substring or `--regex ` for a Rust regular expression. Omitting `--timeout` allows an indefinite wait. Use the read source that matches the task: -- `visible`: the current rendered viewport -- `recent`: recent scrollback as rendered, including soft wraps -- `recent-unwrapped`: recent scrollback with soft wraps joined; prefer it for logs and transcripts -- `detection`: the bottom-buffer snapshot used by agent detection +- `visible`: the currently rendered viewport. +- `recent`: recent rendered output, including soft wraps. +- `recent-unwrapped`: recent output with soft wraps joined; prefer it for logs and transcripts. +- `detection`: the plain-text bottom-buffer snapshot used for agent detection. Use `--format ansi` when colors and terminal styling are evidence. Otherwise use text. -If the user explicitly asks for another tab, workspace, or worktree, discover that command group and use returned IDs. Do not infer a larger topology from a request to start an agent or command. +Full-screen agents may use the terminal alternate screen. Rows that disappear from that screen do not enter Herdr's host scrollback, so `recent`, `recent-unwrapped`, and larger `--lines` values cannot recover them. Enlarge the pane, request concise output, use the agent's transcript controls, or scroll inside the agent and read `--source visible`. ## Safety and coordination rules - Use `--no-focus` for background work unless the user asked to switch context. -- Use `--current` or an explicit ID. Do not rely on another client's focused pane. +- Use `--current`, an explicit pane ID, or a unique agent name. Do not rely on another client's focused pane. - Parse IDs from JSON responses. Do not derive them from sidebar order or examples. -- Inspect before waiting. Read current output first, then wait for the next state or output you expect. - Do not close workspaces, tabs, panes, or sessions you did not create unless the user explicitly asked. - Never run `herdr server stop` from an active session unless the user explicitly intends to stop the server and its pane processes. - Never kill the main Herdr process. Use named test sessions for experiments that need an isolated server. +- CLI server errors are JSON on stderr with exit status 1. CLI syntax errors exit with status 2. diff --git a/docs/next/CHANGELOG.md b/docs/next/CHANGELOG.md index 0cc00aed..7efcd08d 100644 --- a/docs/next/CHANGELOG.md +++ b/docs/next/CHANGELOG.md @@ -2,35 +2,57 @@ ## Unreleased +### Breaking Changes +- Installed and linked plugins, including their enabled state, are now global to the current user instead of isolated by Herdr session. Plugins installed only in a named session on Herdr 0.7.3 must be installed or linked again. (#1174) + ### Added - Added a live-agent CLI facade with named `start`, atomic `prompt`, logical `send-keys`, and server-owned `wait` workflows. Agent startup targets an existing pane without changing topology, validates the requested interactive agent kind and strict agent name, and accepts native arguments after `--`. - Added transient declarative Agent view queries through `agent.view.set/clear`; filtered and sorted views now define sidebar, mobile, mouse, and agent-keybind navigation order. - Added one-shot plugin `[[startup]]` hooks for restoring plugin-owned state after server startup and live handoff. +- Added per-token foreground, bold, and dim styling to expanded Space and Agent sidebar row layouts. - Added `ui.sidebar_start_collapsed` to launch Herdr with the sidebar collapsed. (#1463) +- Added `ui.prompt_new_workspace_name` to ask for a workspace name before interactive TUI creation. - Added macOS support for the `HERDR_AGENT=` foreground-process hint, allowing agents hidden behind host-visible wrappers such as `nono` to use the named agent's screen manifest. (#679) ### Changed - Agent commands now accept only a unique live agent name or the pane ID currently hosting that agent. Names are cleared when the occupant exits, is released, or is replaced. The old top-level `wait` commands were replaced by `agent wait` and `pane wait-output`, and `agent send` was replaced by `agent send-keys`. +- The session navigator now uses connected tree glyphs, groups matches by workspace, and automatically selects the first result when a search begins. (#1611) ### Fixed +- CLI requests now return a machine-readable `protocol_mismatch` error when the client and server protocols differ, while recovery commands remain available. (#1435) - Linux sound notifications now terminate and reap audio players that do not exit, preventing unavailable audio from leaving CPU-bound `mpg123` processes behind. (#1622) - Oversized bracketed text pastes are now rejected with a client-local notification instead of disconnecting the client. (#1665) - Agent prompt waits now report `agent_prompt_stalled` after five seconds without an observed state change instead of waiting indefinitely after an ineffective submission. - `herdr config check` now reports unknown config keys with their full paths instead of treating ignored typos as valid configuration. (#1573) - Codex panes with customized static terminal titles now fall back to the live working footer instead of remaining idle, while OSC activity remains preferred. (#1563) +- Grok panes now preserve working and blocked state from terminal signals and pinned background-work status instead of falling back to idle mid-turn. +- OpenCode lifecycle reports are now serialized so out-of-order plugin events cannot leave an idle pane marked working. (#1519) +- Kimi question prompts now report blocked until the user answers or dismisses them. +- Pi lifecycle reporting now uses settled events, preventing transient message boundaries from publishing an idle state mid-turn. - The Pi, OMP, OpenCode, and Kilo Code integrations can now be installed on Windows and report lifecycle state and native session identity through Herdr's named-pipe API. (#1531) - Named agent prompts now honor live bracketed-paste mode before sending Enter, preserving OpenCode text such as `A != B` instead of triggering shell mode. (#1525) - New panes, tabs, layouts, and workspaces using `new_cwd = "follow"` now inherit the foreground process-group leader's working directory instead of an unrelated helper process directory. (#1472) +- Cached pane working directories no longer trigger repeated filesystem checks, avoiding slow sidebar rendering on network filesystems such as Ceph. (#1603) +- Windows foreground-process snapshots are now shared across panes, reducing idle CPU use in sessions with many panes. (#1158) +- Terminal diff streams now batch contiguous writes, reducing the visible wave effect while scrolling pane history. (#283) +- A standalone Escape arriving beside another key is now preserved as its own input instead of being combined into a fabricated Alt chord. (#541) +- Pane viewports that were following live output now continue following after a resize. +- Mouse selections now remain visible when `ui.copy_on_select = false` while clipboard writes stay disabled. (#1471) +- Workspace close confirmation now shows the current workspace name instead of a stale or unrelated label. (#1364) +- Plugin command arrays now preserve whitespace-only arguments. (#1594, #1613) +- Plugins can now be installed or linked while no Herdr server is running. (#1670) +- Remote attach now discovers Herdr installed in mise's canonical tool path before offering to install a sidecar binary. (#1201) - Noninteractive update, plugin, integration, sound, custom-command, and Git subprocesses no longer flash console windows on Windows. (#1468) - Live handoff now preserves installed plugins and no longer lets the next plugin installation overwrite the existing registry. (#893) -- `herdr wait agent-status` now returns `pane_not_found` promptly when its target pane closes instead of waiting for the full timeout. (#1439) +- `herdr agent wait` now returns `agent_not_running` promptly when its target pane closes instead of waiting for the full timeout. (#1439) +- Pane graphics streams now shut down cleanly when a client disconnect races stream teardown. ## [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 and per-occurrence foreground, bold, and dim styles 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 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) diff --git a/docs/next/website/src/content/docs/agent-automation.mdx b/docs/next/website/src/content/docs/agent-automation.mdx index a07927ba..73b279f1 100644 --- a/docs/next/website/src/content/docs/agent-automation.mdx +++ b/docs/next/website/src/content/docs/agent-automation.mdx @@ -49,13 +49,6 @@ An available shell pane is at its interactive shell prompt: the shell itself own herdr agent start reviewer --kind codex --pane "$review_pane" -- -m gpt-5.4 ``` -The equivalent fixed-ID example is: - -```bash -herdr pane split --current --direction right --no-focus -herdr agent start reviewer --kind codex --pane w1:p2 -- -m gpt-5.4 -``` - Agents launched manually are detected automatically and can be addressed by pane ID. Give one a name when a stable human-readable target is useful: ```bash @@ -84,9 +77,9 @@ Pane input addresses the terminal regardless of its current occupant. Agent inpu `idle` means the agent is ready for input and its tab has been seen in the focused Herdr UI. `done` is the same underlying idle state after background work finishes, until that tab is focused or `pane focus` / `agent focus` targets it. Reading through the CLI does not mark it seen. `blocked` means Herdr recognized an approval or question UI. `unknown` means an agent is present but Herdr cannot classify its lifecycle confidently; it does not prove successful completion. Use exact `--until` states when that distinction matters. -`pane wait-output` does not interpret agent lifecycle. It polls the selected terminal snapshot and searches it immediately, so text that was already present can match. The default source name is `recent`; matching treats that source as unwrapped recent output. `--lines` limits the searched snapshot, `--regex` uses Rust regular-expression syntax and matches one line at a time, and `--raw` keeps ANSI escape sequences while matching. +`pane wait-output` does not interpret agent lifecycle. It polls the selected terminal snapshot and searches it immediately, so text that was already present can match. The default source name is `recent`; matching treats that source as unwrapped recent output from the latest 80 rendered terminal rows. `--lines` changes that row limit, and `--regex` uses Rust regular-expression syntax and matches one line at a time. -At the CLI, both `pane read` and `agent read` print terminal text directly. The default is UTF-8 text with ANSI escapes stripped; use `--format ansi` or `--ansi` to preserve terminal escapes where the source exposes them. The `detection` source is always plain text. For every read source, `--lines N` returns the last N logical lines. The socket API returns the text at `.result.read.text`. +At the CLI, both `pane read` and `agent read` print terminal text directly. The default is UTF-8 text with ANSI escapes stripped; use `--format ansi` or `--ansi` to preserve terminal escapes where the source exposes them. The `detection` source is always plain text. For recent sources, `--lines N` selects the last N rendered terminal rows before optional unwrapping; without it, reads default to 80 rows. For `visible` and `detection`, omitting `--lines` returns the full snapshot, while specifying it keeps the last N newline-delimited lines. The socket API returns the text at `.result.read.text`. ## Known caveat: alternate-screen output diff --git a/docs/next/website/src/content/docs/cli-reference.mdx b/docs/next/website/src/content/docs/cli-reference.mdx index cceb038d..b9f2dc2c 100644 --- a/docs/next/website/src/content/docs/cli-reference.mdx +++ b/docs/next/website/src/content/docs/cli-reference.mdx @@ -198,7 +198,7 @@ herdr pane read --source visible --ansi herdr pane read --source recent-unwrapped --lines 120 ``` -`pane read` prints UTF-8 terminal text directly. ANSI escapes are stripped by default; use `--format ansi` or `--ansi` to preserve them where the source exposes styling. The `detection` source is always plain text. For every source, `--lines N` returns the last N logical lines. `agent read` uses the same output and line behavior. +`pane read` prints UTF-8 terminal text directly. ANSI escapes are stripped by default; use `--format ansi` or `--ansi` to preserve them where the source exposes styling. The `detection` source is always plain text. For recent sources, `--lines N` selects the last N rendered terminal rows before optional unwrapping; without it, reads default to 80 rows. For `visible` and `detection`, omitting `--lines` returns the full snapshot, while specifying it keeps the last N newline-delimited lines. `agent read` uses the same output and line behavior. Send input: @@ -346,7 +346,7 @@ herdr pane wait-output (--match | --regex ) [--source Use `pane wait-output` for normal commands and servers. Use `agent wait` for coding agents. -`pane wait-output` checks the selected snapshot immediately, including output that already exists, then polls until it matches. The default source name is `recent`; matching treats it as unwrapped recent output with no line limit. `--match` finds a literal substring on one line; `--regex` uses Rust regular-expression syntax and also matches one line at a time. `--raw` keeps ANSI escape sequences instead of stripping them. +`pane wait-output` checks the selected snapshot immediately, including output that already exists, then polls until it matches. The default source name is `recent`; matching treats it as unwrapped recent output from the latest 80 rendered terminal rows. `--lines` changes that row limit. `--match` finds a literal substring on one line, and `--regex` uses Rust regular-expression syntax and also matches one line at a time. `pane wait-output`, `agent wait`, and `agent prompt --wait` wait indefinitely when `--timeout` is omitted. A timeout or server error is emitted as JSON on stderr with exit status 1. CLI usage errors exit with status 2. diff --git a/docs/next/website/src/content/docs/ja/agent-automation.mdx b/docs/next/website/src/content/docs/ja/agent-automation.mdx index 44e20f53..a6dd041b 100644 --- a/docs/next/website/src/content/docs/ja/agent-automation.mdx +++ b/docs/next/website/src/content/docs/ja/agent-automation.mdx @@ -49,13 +49,6 @@ review_pane=$(printf '%s\n' "$split" | jq -r '.result.pane.pane_id') herdr agent start reviewer --kind codex --pane "$review_pane" -- -m gpt-5.4 ``` -固定 ID を使う同等の例: - -```bash -herdr pane split --current --direction right --no-focus -herdr agent start reviewer --kind codex --pane w1:p2 -- -m gpt-5.4 -``` - 手動で起動したエージェントも自動検出され、ペイン ID で指定できます。人が読みやすい安定した対象名が必要なら名前を付けます: ```bash @@ -84,9 +77,9 @@ herdr agent rename w1:p2 reviewer `idle` は、エージェントが入力待ちで、そのタブがフォーカス中の Herdr UI ですでに表示済みであることを示します。`done` は同じ基礎的な idle 状態ですが、バックグラウンド作業が完了してから、そのタブをフォーカスするか `pane focus` / `agent focus` で対象にするまで使われます。CLI で読み取るだけでは表示済みになりません。`blocked` は承認または質問 UI を Herdr が認識した状態です。`unknown` はエージェントが存在するもののライフサイクルを確実に分類できない状態で、成功完了を意味しません。違いが重要なら正確な `--until` を指定してください。 -`pane wait-output` はエージェントのライフサイクルを解釈しません。選択したターミナルスナップショットをポーリングし、最初にすぐ検索するため、すでに存在する文字列も一致します。デフォルトのソース名は `recent` で、マッチング時は recent の折り返し前の出力として扱われます。`--lines` は検索範囲を制限し、`--regex` は Rust の正規表現構文で 1 行ずつ一致し、`--raw` は ANSI エスケープシーケンスを残して検索します。 +`pane wait-output` はエージェントのライフサイクルを解釈しません。選択したターミナルスナップショットをポーリングし、最初にすぐ検索するため、すでに存在する文字列も一致します。デフォルトのソース名は `recent` で、直近 80 行の描画済みターミナル行を折り返し前の出力として扱います。`--lines` でその行数を変更でき、`--regex` は Rust の正規表現構文で 1 行ずつ一致します。 -CLI では、`pane read` と `agent read` のどちらもターミナルテキストを直接出力します。デフォルトは ANSI エスケープを除去した UTF-8 テキストです。ソースに装飾が含まれる場合、`--format ansi` または `--ansi` でエスケープを残します。`detection` ソースは常にプレーンテキストです。すべての read ソースで、`--lines N` は末尾の N 論理行を返します。socket API ではテキストを `.result.read.text` に返します。 +CLI では、`pane read` と `agent read` のどちらもターミナルテキストを直接出力します。デフォルトは ANSI エスケープを除去した UTF-8 テキストです。ソースに装飾が含まれる場合、`--format ansi` または `--ansi` でエスケープを残します。`detection` ソースは常にプレーンテキストです。recent 系ソースでは、`--lines N` は折り返し解除の前に末尾の N 描画行を選び、省略時は 80 行です。`visible` と `detection` では、省略時にスナップショット全体を返し、指定時は改行で区切られた末尾 N 行を返します。socket API ではテキストを `.result.read.text` に返します。 ## 既知の注意点: 代替画面の出力 diff --git a/docs/next/website/src/content/docs/ja/cli-reference.mdx b/docs/next/website/src/content/docs/ja/cli-reference.mdx index cc53df42..3b96247e 100644 --- a/docs/next/website/src/content/docs/ja/cli-reference.mdx +++ b/docs/next/website/src/content/docs/ja/cli-reference.mdx @@ -191,7 +191,7 @@ herdr pane read --source visible --ansi herdr pane read --source recent-unwrapped --lines 120 ``` -`pane read` は UTF-8 のターミナルテキストを直接出力します。デフォルトでは ANSI エスケープを除去し、ソースに装飾が含まれる場合は `--format ansi` または `--ansi` で保持します。`detection` ソースは常にプレーンテキストです。すべてのソースで `--lines N` は末尾の N 論理行を返します。`agent read` も同じ出力と行数の動作です。 +`pane read` は UTF-8 のターミナルテキストを直接出力します。デフォルトでは ANSI エスケープを除去し、ソースに装飾が含まれる場合は `--format ansi` または `--ansi` で保持します。`detection` ソースは常にプレーンテキストです。recent 系ソースでは、`--lines N` は折り返し解除の前に末尾の N 描画行を選び、省略時は 80 行です。`visible` と `detection` では、省略時にスナップショット全体を返し、指定時は改行で区切られた末尾 N 行を返します。`agent read` も同じ出力と行数の動作です。 入力を送る: @@ -320,7 +320,7 @@ herdr pane wait-output (--match | --regex ) [--source 通常のコマンドやサーバーには `pane wait-output` を使います。コーディングエージェントには `agent wait` を使います。 -`pane wait-output` は選択したスナップショットを最初にすぐ検索するため、すでに存在する出力も一致します。デフォルトのソース名は `recent` で、マッチング時は行数制限なしの recent 折り返し前出力として扱われます。`--match` は 1 行内のリテラル部分文字列を検索し、`--regex` は Rust の正規表現構文で 1 行ずつ一致します。`--raw` は ANSI エスケープシーケンスを除去しません。 +`pane wait-output` は選択したスナップショットを最初にすぐ検索するため、すでに存在する出力も一致します。デフォルトのソース名は `recent` で、直近 80 行の描画済みターミナル行を折り返し前の出力として扱います。`--lines` でその行数を変更できます。`--match` は 1 行内のリテラル部分文字列を検索し、`--regex` は Rust の正規表現構文で 1 行ずつ一致します。 `pane wait-output`、`agent wait`、`agent prompt --wait` は、`--timeout` を省略すると無期限に待ちます。タイムアウトまたはサーバーエラーは JSON として stderr に出力され、終了コード 1 になります。CLI 使用法のエラーは終了コード 2 です。 diff --git a/docs/next/website/src/content/docs/ja/plugins.mdx b/docs/next/website/src/content/docs/ja/plugins.mdx index 426c8e62..db5342cd 100644 --- a/docs/next/website/src/content/docs/ja/plugins.mdx +++ b/docs/next/website/src/content/docs/ja/plugins.mdx @@ -74,6 +74,9 @@ command = ["npm", "ci"] command = ["npm", "run", "build"] platforms = ["linux", "macos"] +[[startup]] +command = ["node", "dist/restore.js"] + [[actions]] id = "apply" title = "Apply layout" @@ -110,10 +113,10 @@ ASCII の英字、数字、コロン、アンダースコア、ハイフンが 一意な名前が必要なとき、Herdr はアクション id を `plugin.id.action` の形に修飾します。 プラグインが動作する場所は `platforms = ["linux", "macos", "windows"]` で宣言します。 -ビルドコマンド、アクション、イベントフック、ペイン、リンクハンドラーも独自の -`platforms` を宣言でき、項目レベルの platforms はトップレベルのリストを -上書きします。トップレベルの `platforms` がないローカルプラグインは警告付きで -リンクされます。 +ビルドコマンド、スタートアップフック、アクション、イベントフック、ペイン、 +リンクハンドラーも独自の `platforms` を宣言でき、項目レベルの platforms は +トップレベルのリストを上書きします。トップレベルの `platforms` がないローカル +プラグインは警告付きでリンクされます。 `command` の値は argv 配列です。Herdr はこれをシェル経由で実行しないため、 コマンド自身がシェルを起動しない限りシェル展開はありません。言語固有の挙動は @@ -192,6 +195,11 @@ herdr plugin log list --plugin example.layout ビルドコマンドを実行し、チェックアウトを Herdr 管理のプラグインデータの下に保存して 登録します。非対話的なインストールには `--yes` を使ってください。GitHub 管理の プラグインを再インストールすると、その管理チェックアウトが置き換えられます。 +インストール済みおよびリンク済みのプラグインと、その有効・無効の状態は現在の +ユーザー全体で共有され、すべての Herdr セッションから利用できます。Herdr サーバーが +動作していないときでも `plugin install` と `plugin link` で登録できます。 +Herdr 0.7.3 の名前付きセッションだけにインストールしたプラグインは、再度 install +または link してください。既存のプラグイン設定と状態はそのまま残ります。 ローカルにリンクされたプラグインへの上書きインストールは拒否されます。先に ローカルプラグインを unlink または uninstall してください。`plugin install` と `plugin link` はプラグインの設定・状態ディレクトリを作成し、 @@ -226,6 +234,23 @@ Herdr のソケット環境変数は受け取りません。プラグインの `bun`、`lua` といった必要なシステムツールをドキュメントに書いてください。Herdr は ビルドの失敗を報告しますが、足りないツールチェーンをインストールすることはありません。 +## スタートアップフック + +`[[startup]]` コマンドは、Herdr がセッションを復元し、API ソケットの準備が整った後に、 +有効なプラグインごとに一度実行されます。ライブハンドオフで新しいサーバーが引き継いだ +ときにも再実行されますが、クライアントの接続、設定の再読み込み、プラグインの link や +enable では実行されません。Herdr はこれらを非同期で開始し、完了を通常のプラグイン +コマンドログに記録します。スタートアップの失敗でサーバーが停止することはありません。 + +スタートアップフックは一度限りの初期化コマンドであり、監視されるデーモンではありません。 +フックはプラグインが所有する状態を復元し、必要な Herdr API を呼び出して終了してください。 +たとえば宣言型の Agent ビューを `HERDR_PLUGIN_STATE_DIR` に保存し、スタートアップフックで +読み込んで再適用できます。 + +スタートアップフックは通常のランタイムプラグイン環境と +`HERDR_PLUGIN_EVENT=startup` を受け取ります。インストールプレビューには、自動実行される +コードを確認できるよう、すべてのスタートアップコマンドが表示されます。 + ## コマンドと環境 ランタイムコマンドは、プラグインディレクトリを作業ディレクトリとして実行されます。 @@ -233,8 +258,9 @@ Herdr は `HERDR_SOCKET_PATH`、`HERDR_BIN_PATH`、`HERDR_ENV=1`、 `HERDR_PLUGIN_ID`、`HERDR_PLUGIN_ROOT`、`HERDR_PLUGIN_CONFIG_DIR`、 `HERDR_PLUGIN_STATE_DIR`、`HERDR_PLUGIN_CONTEXT_JSON`、そして利用可能なら `HERDR_WORKSPACE_ID`、`HERDR_TAB_ID`、`HERDR_PANE_ID` を注入します。アクション -コマンドは加えて `HERDR_PLUGIN_ACTION_ID` を受け取ります。イベントフックは -`HERDR_PLUGIN_EVENT` と `HERDR_PLUGIN_EVENT_JSON` を、ペインコマンドは +コマンドは加えて `HERDR_PLUGIN_ACTION_ID` を受け取ります。スタートアップフックと +イベントフックは `HERDR_PLUGIN_EVENT`(スタートアップフックでは `startup`)を受け取り、 +イベントフックはさらに `HERDR_PLUGIN_EVENT_JSON` を、ペインコマンドは `HERDR_PLUGIN_ENTRYPOINT_ID` を受け取ります。 `HERDR_PLUGIN_ROOT` は、インストールまたはリンクされたプラグインディレクトリです。 diff --git a/docs/next/website/src/content/docs/ja/socket-api.mdx b/docs/next/website/src/content/docs/ja/socket-api.mdx index b1a2f201..8995dbae 100644 --- a/docs/next/website/src/content/docs/ja/socket-api.mdx +++ b/docs/next/website/src/content/docs/ja/socket-api.mdx @@ -297,6 +297,80 @@ Worktree メソッドは Git チェックアウトを Herdr ワークスペー worktree コマンドはライフサイクルイベントも発行します。`worktree.create` は `workspace.created`、`tab.created`、`pane.created`、`worktree.created` を発行します。`worktree.open` は `worktree.opened` を発行し、新しい Herdr ワークスペースを開いた場合はワークスペース/タブ/ペインの作成イベントも発行します。`worktree.remove` は `worktree.removed` を発行し、リンクされたワークスペースがまだ開いている場合は `workspace.closed` も発行します。 +## エージェントビューのクエリ + +`agent.view.set` は、組み込みの Agents ビューに一つの一時的な宣言型プロジェクションを +設定します。エージェントの情報や現在の UI コンテキストが変わるたびに再評価されます。 +展開・折りたたみサイドバー、モバイルの Agents リスト、マウスターゲット、番号付き +フォーカス、前後のエージェントへの移動順を制御します。`agent.list`、通知、検出、 +グローバルな要対応件数は変更しません。 + +現在表示中の Space にいるエージェント、または別の場所で対応が必要なエージェントを +表示し、要対応度と直近の状態遷移で並べ替える例です: + +```json +{ + "id": "view_set", + "method": "agent.view.set", + "params": { + "source": "plugin:example.agent-views", + "label": "focus", + "filter": { + "op": "any", + "filters": [ + { + "op": "eq", + "field": "workspace_id", + "value": {"context": "current_workspace_id"} + }, + { + "op": "in", + "field": "status", + "values": ["blocked", "done"] + } + ] + }, + "sort": [ + {"field": "attention", "order": "desc"}, + {"field": "state_change_seq", "order": "desc"} + ] + } +} +``` + +フィルターノードの `op` には `all`、`any`、`not`、`eq`、`in`、`exists` を使います。 +組み込みフィールドは `status`、`workspace_id`、`tab_id`、`pane_id`、`agent`、 +`seen`、`state_change_seq` です。プラグインが報告したペインメタデータを絞り込むには、 +フィールドとして `{"token":"name"}` を使います。値には文字列、真偽値、符号なし整数、 +またはコンテキストオブジェクトを指定できます。コンテキスト値は +`current_workspace_id` と `current_tab_id` で、対応する ID フィールドとの比較にだけ +使えます。有効な status は `idle`、`working`、`blocked`、`done`、`unknown` です。 +`done` は idle かつ未確認の状態を表します。 + +ソートフィールドは `workspace_order`、`tab_order`、`pane_order`、`attention`、 +`status`、`agent`、`seen`、`state_change_seq`、または `{"token":"name"}` です。 +ソートは安定しており、指定順に評価され、`asc` または `desc` を受け付けます。値がない +項目は値がある項目の後に残ります。`sort` を省略すると既存の +`ui.agent_panel_sort` ポリシーが有効です。カスタムソートは設定を書き換えず、一時的に +そのポリシーを置き換えます。 + +`source` は所有者を識別します。プラグインは `plugin:` を使います。 +所有元のプラグインが存在しないか無効な場合、Herdr は設定を拒否します。他の呼び出し元は +独自の非 `plugin:` source を使えます。設定に成功すると以前のビューはアトミックに +置き換えられます。ビューは clear または置換されるか、所有プラグインが disable、unlink、 +uninstall されるか、サーバーが終了するまで有効です。永続的な動作が必要なプラグインは、 +クエリを `HERDR_PLUGIN_STATE_DIR` に保存し、`[[startup]]` フックから再適用してください。 + +無条件で clear するか、指定した source がまだ所有している場合だけ clear できます: + +```json +{"id":"view_clear","method":"agent.view.clear","params":{}} +{"id":"view_clear_owned","method":"agent.view.clear","params":{"source":"plugin:example.agent-views"}} +``` + +source が一致しない場合、アクティブなビューは変わりません。set と clear のレスポンスは +`type: "agent_view"` で、`active`、`source`、任意の `label` を報告します。 + ## プラグイン API プラグイン API は、実行可能なワークフローツールのための初期のホスト面です。プラグインは `herdr-plugin.toml` マニフェストを持つパッケージです。マニフェストは、共有可能なアクション、イベントフック、ターミナルペインのエントリーポイント、リンクハンドラーを宣言します。アクションとペインはマニフェスト専用です。ランタイムでのアクション登録とランタイムでの argv ペイン作成は v1 の範囲外です。 diff --git a/docs/next/website/src/content/docs/zh-cn/agent-automation.mdx b/docs/next/website/src/content/docs/zh-cn/agent-automation.mdx index 5fda8ca3..7f6eeb58 100644 --- a/docs/next/website/src/content/docs/zh-cn/agent-automation.mdx +++ b/docs/next/website/src/content/docs/zh-cn/agent-automation.mdx @@ -49,13 +49,6 @@ review_pane=$(printf '%s\n' "$split" | jq -r '.result.pane.pane_id') herdr agent start reviewer --kind codex --pane "$review_pane" -- -m gpt-5.4 ``` -使用固定 ID 的等价示例: - -```bash -herdr pane split --current --direction right --no-focus -herdr agent start reviewer --kind codex --pane w1:p2 -- -m gpt-5.4 -``` - 手动启动的智能体也会被自动检测,可以用窗格 ID 指定。当需要一个稳定、易读的目标时,给它命名: ```bash @@ -84,9 +77,9 @@ herdr agent rename w1:p2 reviewer `idle` 表示智能体正等待输入,且其标签页已在聚焦的 Herdr 界面中显示。`done` 是相同的底层 idle 状态,但用于后台工作完成后,直到该标签页获得焦点或 `pane focus` / `agent focus` 指向它。仅通过 CLI 读取不会把它标记为已查看。`blocked` 表示 Herdr 识别到了审批或提问界面。`unknown` 表示智能体存在,但 Herdr 无法可靠判断其生命周期;它不代表工作成功完成。区别重要时,请指定精确的 `--until` 状态。 -`pane wait-output` 不解释智能体生命周期。它轮询选定的终端快照并立即进行第一次搜索,所以已经存在的文本也会匹配。默认来源名是 `recent`;匹配时会把它作为 recent 的未折行输出来处理。`--lines` 限制搜索范围;`--regex` 使用 Rust 正则表达式语法并逐行匹配;`--raw` 在匹配时保留 ANSI 转义序列。 +`pane wait-output` 不解释智能体生命周期。它轮询选定的终端快照并立即进行第一次搜索,所以已经存在的文本也会匹配。默认来源名是 `recent`;匹配时会把最近 80 个已渲染终端行作为未折行输出处理。`--lines` 可以修改这个行数限制;`--regex` 使用 Rust 正则表达式语法并逐行匹配。 -在 CLI 中,`pane read` 和 `agent read` 都直接打印终端文本。默认输出去除 ANSI 转义的 UTF-8 文本;来源包含样式时,使用 `--format ansi` 或 `--ansi` 保留终端转义。`detection` 来源始终是纯文本。对所有 read 来源,`--lines N` 都返回末尾 N 个逻辑行。socket API 在 `.result.read.text` 返回文本。 +在 CLI 中,`pane read` 和 `agent read` 都直接打印终端文本。默认输出去除 ANSI 转义的 UTF-8 文本;来源包含样式时,使用 `--format ansi` 或 `--ansi` 保留终端转义。`detection` 来源始终是纯文本。对 recent 类来源,`--lines N` 会在可选的取消折行之前选择最后 N 个已渲染终端行;省略时默认读取 80 行。对 `visible` 和 `detection`,省略 `--lines` 会返回完整快照,指定时保留按换行分隔的最后 N 行。socket API 在 `.result.read.text` 返回文本。 ## 已知注意事项:备用屏幕输出 diff --git a/docs/next/website/src/content/docs/zh-cn/cli-reference.mdx b/docs/next/website/src/content/docs/zh-cn/cli-reference.mdx index a9a80756..03831dc7 100644 --- a/docs/next/website/src/content/docs/zh-cn/cli-reference.mdx +++ b/docs/next/website/src/content/docs/zh-cn/cli-reference.mdx @@ -191,7 +191,7 @@ herdr pane read --source visible --ansi herdr pane read --source recent-unwrapped --lines 120 ``` -`pane read` 直接打印 UTF-8 终端文本。默认去除 ANSI 转义;来源包含样式时,使用 `--format ansi` 或 `--ansi` 保留。`detection` 来源始终是纯文本。对所有来源,`--lines N` 都返回末尾 N 个逻辑行。`agent read` 使用相同的输出和行数行为。 +`pane read` 直接打印 UTF-8 终端文本。默认去除 ANSI 转义;来源包含样式时,使用 `--format ansi` 或 `--ansi` 保留。`detection` 来源始终是纯文本。对 recent 类来源,`--lines N` 会在可选的取消折行之前选择最后 N 个已渲染终端行;省略时默认读取 80 行。对 `visible` 和 `detection`,省略 `--lines` 会返回完整快照,指定时保留按换行分隔的最后 N 行。`agent read` 使用相同的输出和行数行为。 发送输入: @@ -320,7 +320,7 @@ herdr pane wait-output (--match | --regex ) [--source 普通命令和服务器用 `pane wait-output`。编程智能体用 `agent wait`。 -`pane wait-output` 会立即检查所选快照,所以已经存在的输出也能匹配。默认来源名是 `recent`;匹配时会把它作为不限制行数的 recent 未折行输出。`--match` 在单行中查找字面子串;`--regex` 使用 Rust 正则表达式语法并逐行匹配。`--raw` 保留 ANSI 转义序列。 +`pane wait-output` 会立即检查所选快照,所以已经存在的输出也能匹配。默认来源名是 `recent`;匹配时会把最近 80 个已渲染终端行作为未折行输出处理。`--lines` 可以修改这个行数限制。`--match` 在单行中查找字面子串;`--regex` 使用 Rust 正则表达式语法并逐行匹配。 `pane wait-output`、`agent wait` 和 `agent prompt --wait` 在省略 `--timeout` 时会无限等待。超时或服务器错误以 JSON 写到 stderr,退出状态为 1。CLI 用法错误的退出状态为 2。 diff --git a/docs/next/website/src/content/docs/zh-cn/plugins.mdx b/docs/next/website/src/content/docs/zh-cn/plugins.mdx index a22e56b8..306bda53 100644 --- a/docs/next/website/src/content/docs/zh-cn/plugins.mdx +++ b/docs/next/website/src/content/docs/zh-cn/plugins.mdx @@ -62,6 +62,9 @@ command = ["npm", "ci"] command = ["npm", "run", "build"] platforms = ["linux", "macos"] +[[startup]] +command = ["node", "dist/restore.js"] + [[actions]] id = "apply" title = "Apply layout" @@ -97,9 +100,9 @@ ASCII 字母、数字、冒号、下划线和连字符,但不能用点。每种 `plugin.id.action` 的形式。 用 `platforms = ["linux", "macos", "windows"]` 声明插件可以运行的平台。 -构建命令、动作、事件钩子、窗格和链接处理器也可以声明自己的 `platforms`; -条目级的 platforms 覆盖顶层列表。没有顶层 `platforms` 的本地插件在链接 -时会给出警告。 +构建命令、启动钩子、动作、事件钩子、窗格和链接处理器也可以声明自己的 +`platforms`;条目级的 platforms 覆盖顶层列表。没有顶层 `platforms` 的本地 +插件在链接时会给出警告。 `command` 的值是 argv 数组。Herdr 不会通过 shell 运行它们,所以除非你的 命令自己启动 shell,否则没有 shell 展开。语言相关的行为放到你的脚本或 @@ -174,8 +177,12 @@ herdr plugin log list --plugin example.layout `plugin install` 只接受 GitHub 简写,比如 `owner/repo/subdir`。它用 `git` 克隆,在交互式终端展示预览,运行受支持的构建命令,然后把检出保存到 Herdr 管理的插件数据下并注册。非交互式安装用 `--yes`。重新安装 GitHub -管理的插件会替换该托管检出。不允许覆盖安装到本地链接的插件之上;请先 -unlink 或 uninstall 本地插件。`plugin install` 和 `plugin link` 会创建 +管理的插件会替换该托管检出。已安装和已链接的插件及其启用状态对当前用户 +全局生效,可在所有 Herdr 会话中使用。即使 Herdr 服务器没有运行,也可以通过 +`plugin install` 和 `plugin link` 注册插件。仅安装在 Herdr 0.7.3 命名会话中的 +插件必须重新 install 或 link;现有的插件配置和状态会保留。 +不允许覆盖安装到本地链接的插件之上;请先 unlink 或 uninstall 本地插件。 +`plugin install` 和 `plugin link` 会创建 插件的配置和状态目录,`plugin config-dir ` 打印配置目录,方便安装 文档和 shell 脚本使用。 @@ -203,6 +210,20 @@ Herdr socket 环境变量。插件作者应在文档中说明所需的系统工 `cargo`、`npm`、`bun` 或 `lua`;Herdr 报告构建失败,但不会安装缺失的 工具链。 +## 启动钩子 + +Herdr 恢复会话且 API socket 就绪后,会为每个已启用插件运行一次 +`[[startup]]` 命令。实时交接由新服务器接管时会再次运行,但客户端连接、 +配置重载以及插件 link 或 enable 时不会运行。Herdr 异步启动这些命令,并在 +普通插件命令日志中记录完成情况。启动钩子失败不会停止服务器。 + +启动钩子是一次性初始化命令,不是受监督的守护进程。钩子应恢复插件自己的 +状态、调用所需的 Herdr API,然后退出。例如,插件可以把声明式 Agent 视图保存到 +`HERDR_PLUGIN_STATE_DIR`,再由启动钩子读取并重新应用。 + +启动钩子会收到普通运行时插件环境和 `HERDR_PLUGIN_EVENT=startup`。安装预览会 +列出所有启动命令,让用户检查将自动运行的代码。 + ## 命令与环境 运行时命令以插件目录为工作目录执行。Herdr 注入 `HERDR_SOCKET_PATH`、 @@ -210,7 +231,8 @@ Herdr socket 环境变量。插件作者应在文档中说明所需的系统工 `HERDR_PLUGIN_CONFIG_DIR`、`HERDR_PLUGIN_STATE_DIR`、 `HERDR_PLUGIN_CONTEXT_JSON`,以及可用时的 `HERDR_WORKSPACE_ID`、 `HERDR_TAB_ID` 和 `HERDR_PANE_ID`。动作命令还会收到 -`HERDR_PLUGIN_ACTION_ID`;事件钩子收到 `HERDR_PLUGIN_EVENT` 和 +`HERDR_PLUGIN_ACTION_ID`;启动钩子和事件钩子收到 `HERDR_PLUGIN_EVENT` +(启动钩子中的值为 `startup`),事件钩子还会收到 `HERDR_PLUGIN_EVENT_JSON`;窗格命令收到 `HERDR_PLUGIN_ENTRYPOINT_ID`。 `HERDR_PLUGIN_ROOT` 是已安装或已链接的插件目录。不要把用户凭据或持久 diff --git a/docs/next/website/src/content/docs/zh-cn/socket-api.mdx b/docs/next/website/src/content/docs/zh-cn/socket-api.mdx index 543aeb39..2077d571 100644 --- a/docs/next/website/src/content/docs/zh-cn/socket-api.mdx +++ b/docs/next/website/src/content/docs/zh-cn/socket-api.mdx @@ -297,6 +297,76 @@ Worktree 方法把 Git 检出作为 Herdr 工作区管理。`worktree.create` Worktree 命令也发出生命周期事件。`worktree.create` 发出 `workspace.created`、`tab.created`、`pane.created` 和 `worktree.created`。`worktree.open` 发出 `worktree.opened`,并在打开新的 Herdr 工作区时同时发出工作区/标签页/窗格创建事件。`worktree.remove` 发出 `worktree.removed`;如果关联的工作区仍然打开,还会发出 `workspace.closed`。 +## 智能体视图查询 + +`agent.view.set` 为内置 Agents 视图设置一个临时的声明式投影。智能体信息或当前 +UI 上下文变化时,该投影会重新求值。它控制展开和折叠的侧边栏、移动端 Agents +列表、鼠标目标、编号聚焦以及上一个/下一个智能体的导航顺序。它不会改变 +`agent.list`、通知、检测或全局待处理计数。 + +下面的示例显示当前呈现的 Space 中的智能体,以及其他位置需要处理的智能体, +然后按待处理优先级和最近状态转换排序: + +```json +{ + "id": "view_set", + "method": "agent.view.set", + "params": { + "source": "plugin:example.agent-views", + "label": "focus", + "filter": { + "op": "any", + "filters": [ + { + "op": "eq", + "field": "workspace_id", + "value": {"context": "current_workspace_id"} + }, + { + "op": "in", + "field": "status", + "values": ["blocked", "done"] + } + ] + }, + "sort": [ + {"field": "attention", "order": "desc"}, + {"field": "state_change_seq", "order": "desc"} + ] + } +} +``` + +过滤节点的 `op` 可以是 `all`、`any`、`not`、`eq`、`in` 或 `exists`。内置 +过滤字段是 `status`、`workspace_id`、`tab_id`、`pane_id`、`agent`、`seen` +和 `state_change_seq`。要过滤插件上报的窗格元数据,使用 `{"token":"name"}` +作为字段。值可以是字符串、布尔值、无符号整数或上下文对象。上下文值包括 +`current_workspace_id` 和 `current_tab_id`,并且只能与对应的 ID 字段比较。 +有效 status 值为 `idle`、`working`、`blocked`、`done` 和 `unknown`;`done` +表示 idle 且尚未查看。 + +排序字段包括 `workspace_order`、`tab_order`、`pane_order`、`attention`、 +`status`、`agent`、`seen`、`state_change_seq` 或 `{"token":"name"}`。排序是 +稳定的,按声明顺序求值,并接受 `asc` 或 `desc`。缺失值排在存在值之后。省略 +`sort` 时,现有 `ui.agent_panel_sort` 策略继续生效。自定义排序会临时替换该 +策略,但不会重写配置。 + +`source` 标识所有者。插件使用 `plugin:`;当所属插件不存在 +或被禁用时,Herdr 会拒绝设置。其他调用方可以使用自己的非 `plugin:` source。 +设置成功会原子替换之前的视图。该视图会持续到被 clear、被替换、所属插件被 +disable、unlink 或 uninstall,或者服务器退出。需要持久行为的插件应把查询保存到 +`HERDR_PLUGIN_STATE_DIR`,并从 `[[startup]]` 钩子重新应用。 + +可以无条件 clear,也可以只在指定 source 仍拥有视图时 clear: + +```json +{"id":"view_clear","method":"agent.view.clear","params":{}} +{"id":"view_clear_owned","method":"agent.view.clear","params":{"source":"plugin:example.agent-views"}} +``` + +source 不匹配时,活动视图保持不变。set 和 clear 响应使用 +`type: "agent_view"`,并报告 `active`、`source` 和可选的 `label`。 + ## 插件 API 插件 API 是面向可执行工作流工具的早期宿主面。插件是带 `herdr-plugin.toml` 清单的包。清单声明可分享的动作、事件钩子、终端窗格入口点和链接处理器。动作和窗格仅限清单声明;运行时动作注册和运行时 argv 窗格创建不在 v1 范围内。 diff --git a/website/src/content/docs/agent-automation.mdx b/website/src/content/docs/agent-automation.mdx new file mode 100644 index 00000000..73b279f1 --- /dev/null +++ b/website/src/content/docs/agent-automation.mdx @@ -0,0 +1,121 @@ +--- +title: Agent automation +description: Use Herdr's layout, pane, and agent primitives to coordinate coding agents from scripts or other agents. +--- + +Herdr can act as an automation layer for coding agents. A script can control them, or one agent can create work for other agents, inspect their state, and collect their results. The important part is choosing the primitive that matches the job. + +## Three primitives + +| Primitive | Responsibility | +| --- | --- | +| Layout (`workspace`, `tab`, and pane topology) | Create and organize terminal locations. | +| Pane | Control a raw terminal: run commands, send input, read output, and wait for output. | +| Agent | Control a recognized coding agent by name or pane and lifecycle state. | + +A pane exists whether or not it contains an agent. An agent is the recognized process currently running inside a pane. `agent start` therefore requires an existing shell pane and never creates, splits, or moves layout. + +Creating a workspace also creates its first tab and root pane; creating a tab creates its root pane. Use the returned pane ID for the first process, and split only when that layout needs another terminal. + +Creation commands print JSON. Capture IDs from the response instead of predicting them: + +```bash +created=$(herdr workspace create --cwd ~/project --label api --no-focus) +pane_id=$(printf '%s\n' "$created" | jq -r '.result.root_pane.pane_id') + +split=$(herdr pane split "$pane_id" --direction right --no-focus) +review_pane=$(printf '%s\n' "$split" | jq -r '.result.pane.pane_id') +``` + +`workspace create` returns `.result.workspace`, `.result.tab`, and `.result.root_pane`. `tab create` returns `.result.tab` and `.result.root_pane`. `pane split` returns the new pane as `.result.pane`. + +Moving a pane to another workspace changes its workspace-qualified pane ID. After any `pane move`, continue with `.result.move_result.pane.pane_id`; the response keeps the old value at `.result.move_result.previous_pane_id`. A running process keeps its launch-time Herdr environment, but the old `HERDR_PANE_ID` remains an alias for that terminal, so `--current` stays safe. New commands can still resolve the agent by name after the move, but a wait already in progress ends with `agent_not_running`. + +Use pane commands for shells, tests, servers, CI watchers, and other ordinary terminal processes. Use agent commands when Herdr needs to understand which agent is running or whether it is `working`, `blocked`, `done`, `idle`, or `unknown`. + +## Agent identity and launch + +A pane ID such as `w1:p2` identifies the terminal location. An agent name such as `reviewer` is a convenient alias for the current agent in that pane. Names must match `[a-z][a-z0-9_-]{0,31}` and be unique among live agents. The alias is cleared when that agent exits, is released, or is replaced; it does not permanently rename the pane. + +Agent commands accept either a unique live name or the pane ID that currently hosts the agent. + +An available shell pane is at its interactive shell prompt: the shell itself owns the foreground, with no foreground command, editor, or agent running. Return the pane to its prompt before calling `agent start`. + +`--kind` selects a supported agent and its canonical executable. Supported kinds are `pi`, `claude`, `codex`, `gemini`, `cursor`, `devin`, `agy`, `cline`, `omp`, `mastracode`, `opencode`, `copilot`, `kimi`, `kiro`, `droid`, `amp`, `grok`, `hermes`, `kilo`, `qodercli`, and `maki`. Arguments after `--` are passed unchanged to that executable. + +`agent start` returns only after Herdr detects the expected agent in the same terminal and marks it ready for interactive input. Startup waits for 30 seconds by default; `--timeout` must be greater than 3000 and no more than 300000 milliseconds. + +```bash +herdr agent start reviewer --kind codex --pane "$review_pane" -- -m gpt-5.4 +``` + +Agents launched manually are detected automatically and can be addressed by pane ID. Give one a name when a stable human-readable target is useful: + +```bash +herdr agent get w1:p2 +herdr agent rename w1:p2 reviewer +``` + +## Choose the control surface + +| Goal | Command | +| --- | --- | +| Run a shell command and submit it | `pane run` | +| Send literal text without Enter | `pane send-text` | +| Send terminal keys or modifier chords | `pane send-keys` | +| Wait for text or a regular expression | `pane wait-output` | +| Start a supported agent in an existing pane | `agent start` | +| Submit a prompt, optionally waiting for it | `agent prompt` | +| Send keys to an agent's interactive UI | `agent send-keys` | +| Wait for agent lifecycle state | `agent wait` | + +`agent prompt` submits text plus encoded Enter and honors the terminal's live bracketed-paste mode. It can prompt an agent that is already working. Use `agent send-keys` for interactions such as `esc`, `up`, `enter`, or `ctrl+c`; `escape` is accepted as an alias for `esc`. Use the pane input commands when you deliberately want raw terminal control. + +Pane input addresses the terminal regardless of its current occupant. Agent input resolves the live agent and rejects the operation if that agent no longer controls the pane. + +`agent prompt --wait` submits immediately. When the agent starts from a non-working state, Herdr first requires an observed lifecycle change within five seconds. If the state sequence does not advance, it returns `agent_prompt_stalled` instead of waiting indefinitely; a caller `--timeout` of five seconds or less returns the normal `timeout` error. After activity is observed, it waits for the requested settled status. It does not track individual turns. If the agent is already working, completion of that active turn may satisfy the wait. Standalone `agent wait` observes the current agent and returns immediately if its status already matches. Both commands default to `idle`, `done`, or `blocked`. Repeat `--until` to accept several exact states, for example `--until idle --until done`; use `--until unknown` explicitly when needed. On `agent prompt`, `--until` requires `--wait`. + +`idle` means the agent is ready for input and its tab has been seen in the focused Herdr UI. `done` is the same underlying idle state after background work finishes, until that tab is focused or `pane focus` / `agent focus` targets it. Reading through the CLI does not mark it seen. `blocked` means Herdr recognized an approval or question UI. `unknown` means an agent is present but Herdr cannot classify its lifecycle confidently; it does not prove successful completion. Use exact `--until` states when that distinction matters. + +`pane wait-output` does not interpret agent lifecycle. It polls the selected terminal snapshot and searches it immediately, so text that was already present can match. The default source name is `recent`; matching treats that source as unwrapped recent output from the latest 80 rendered terminal rows. `--lines` changes that row limit, and `--regex` uses Rust regular-expression syntax and matches one line at a time. + +At the CLI, both `pane read` and `agent read` print terminal text directly. The default is UTF-8 text with ANSI escapes stripped; use `--format ansi` or `--ansi` to preserve terminal escapes where the source exposes them. The `detection` source is always plain text. For recent sources, `--lines N` selects the last N rendered terminal rows before optional unwrapping; without it, reads default to 80 rows. For `visible` and `detection`, omitting `--lines` returns the full snapshot, while specifying it keeps the last N newline-delimited lines. The socket API returns the text at `.result.read.text`. + +## Known caveat: alternate-screen output + +Full-screen agents such as Claude Code and OpenCode may render in the terminal's alternate screen. Alternate-screen rows do not enter Herdr's host scrollback. If a response exceeds the visible pane, `recent` and `recent-unwrapped` cannot recover rows that the app no longer displays; increasing `--lines` does not make that history available. A larger font or smaller pane makes this more likely. + +Ask the agent for concise responses, enlarge the pane or use a smaller font, or use the agent's own transcript and scrolling controls. After scrolling inside the agent, use `--source visible` to read the page it currently renders. + +Successful `agent start`, `agent prompt`, and `agent wait` commands return the current agent at `.result.agent`. `pane wait-output` returns `.result.pane_id`, `.result.matched_line`, and the matched snapshot at `.result.read`. + +Wait commands have no default timeout and can wait indefinitely. On timeout or another server error, CLI commands print a JSON error to stderr and exit with status 1; invalid CLI syntax exits with status 2. + +## Recipes + +Start a helper, give it work, and wait for that work to settle: + +```bash +split=$(herdr pane split --current --direction right --no-focus) +review_pane=$(printf '%s\n' "$split" | jq -r '.result.pane.pane_id') +herdr agent start reviewer --kind codex --pane "$review_pane" -- -m gpt-5.4 +herdr agent prompt reviewer "Review the current diff" --wait --timeout 120000 +herdr agent read reviewer --source recent-unwrapped --lines 120 +``` + +Wait for an agent to ask for input, inspect it, and interact with its UI: + +```bash +herdr agent wait reviewer --until blocked --timeout 120000 +herdr agent read reviewer --source recent-unwrapped --lines 80 +herdr agent send-keys reviewer esc +``` + +Run an ordinary process and wait for its output without treating it as an agent: + +```bash +herdr pane run w1:p3 "just test --watch" +herdr pane wait-output w1:p3 --regex "passed|failed" --timeout 120000 +``` + +See the [CLI reference](/docs/cli-reference/) for the complete command and option list. Shell completions expose the same command tree interactively. diff --git a/website/src/content/docs/agent-skill.mdx b/website/src/content/docs/agent-skill.mdx index 13a90154..498861f7 100644 --- a/website/src/content/docs/agent-skill.mdx +++ b/website/src/content/docs/agent-skill.mdx @@ -58,7 +58,7 @@ This prevents an agent outside Herdr from trying to control a session it does no ## Agent-facing reference -The full command guide lives in the skill file itself. It covers pane IDs, `pane split`, `pane run`, `pane read`, `wait output`, `wait agent-status`, workspace and tab commands, and coordination recipes. +The full command guide lives in the skill file itself. It covers pane IDs, `pane split`, `pane run`, `pane read`, `pane wait-output`, `agent wait`, workspace and tab commands, and coordination recipes. Read the source file here: diff --git a/website/src/content/docs/agents.mdx b/website/src/content/docs/agents.mdx index b4c3146d..ee275d19 100644 --- a/website/src/content/docs/agents.mdx +++ b/website/src/content/docs/agents.mdx @@ -5,6 +5,8 @@ description: See what Herdr can detect, how agent state works, and how integrati Herdr is built for running more than one coding agent at a time. Each agent stays in a real terminal pane with its shell, logs, prompts, and running processes intact. Herdr tracks which panes contain agents, rolls their state up to tabs and workspaces, and lets you jump straight to the pane that needs attention instead of polling every terminal by hand. +To coordinate agents from scripts or from another agent, see [Agent automation](/docs/agent-automation/). + ## Supported agents Automatic detection works out of the box for common coding agents. The important difference is not whether Herdr can see an agent. It is which signal is allowed to author `idle`, `working`, and `blocked`. @@ -47,7 +49,7 @@ Claude Code, Codex, GitHub Copilot CLI, Droid, Qoder CLI, and Cursor Agent CLI i ## VMs and sandbox wrappers -On Linux, wrappers such as VMs, Bubblewrap, or `fence` can hide the real agent process from host `/proc`. Set `HERDR_AGENT=` on the command, for example `HERDR_AGENT=claude fence -- claude`, to tell Herdr which existing agent screen manifest to use. The hint is scoped to that foreground process; avoid exporting it globally from your shell unless every inherited foreground process should be treated as that agent. +On Linux and macOS, a host-visible wrapper can hide the real agent process from Herdr. Set `HERDR_AGENT=` on the wrapper command to tell Herdr which existing agent screen manifest to use. For example, run `HERDR_AGENT=claude fence -- claude` on Linux or `HERDR_AGENT=claude nono run --profile claude-code -- claude` on macOS. The hint is scoped to that foreground process; setting it only inside a VM or container is not visible to Herdr, and you should avoid exporting it globally unless every inherited foreground process should be treated as that agent. ## Blocked state @@ -110,7 +112,7 @@ herdr agent rename w1:p1 reviewer herdr agent rename reviewer --clear ``` -Targets accept terminal IDs, unique agent names, detected or reported agent labels, and legacy pane IDs. +Targets accept a unique live agent name or the pane ID that currently hosts the agent. Terminal IDs and bare agent-kind labels are not accepted. ## Custom status labels @@ -131,24 +133,6 @@ herdr pane report-metadata w1:p1 \ 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 - -Use `herdr agent ...` commands when you want a terminal to be treated as an agent target. Agent targets show up in `agent list`, can be read or sent input by agent name, can be waited on by agent state, and can be directly attached. - -Spawn an agent into Herdr from a script: - -```bash -herdr agent start reviewer --cwd ~/project --split right -- pi -``` - -You can place that agent in a specific workspace or tab: - -```bash -herdr agent start docs --workspace w1 --tab w1:t1 -- claude -``` - -Use `herdr pane ...` commands for ordinary terminals, servers, tests, shells, and low-level terminal input. For example, use `pane split` and `pane run` for `cargo test`, not `agent start`, unless that terminal is intentionally being treated as an agent target. - ## Attach directly to an agent Attach your current terminal to one agent terminal instead of the full Herdr UI: diff --git a/website/src/content/docs/cli-reference.mdx b/website/src/content/docs/cli-reference.mdx index a7c11d92..b9f2dc2c 100644 --- a/website/src/content/docs/cli-reference.mdx +++ b/website/src/content/docs/cli-reference.mdx @@ -130,6 +130,8 @@ Create a workspace without stealing focus: herdr workspace create --cwd ~/project --label api --no-focus ``` +A workspace is the top-level project or work context. Creating one also creates its first tab and root pane. The JSON response exposes their IDs as `.result.workspace.workspace_id`, `.result.tab.tab_id`, and `.result.root_pane.pane_id`. + ## Worktrees ```bash @@ -154,6 +156,10 @@ herdr tab rename