diff options
Diffstat (limited to 'docs/preview')
30 files changed, 611 insertions, 212 deletions
diff --git a/docs/preview/website/src/content/docs/add-herdr-support.mdx b/docs/preview/website/src/content/docs/add-herdr-support.mdx new file mode 100644 index 00000000..0ed689a3 --- /dev/null +++ b/docs/preview/website/src/content/docs/add-herdr-support.mdx @@ -0,0 +1,117 @@ +--- +title: Add Herdr support to your agent +description: Report your coding agent's state and resume command to Herdr from your own code, without adding native support to Herdr. +--- + +If you build a coding agent, you can make it a first-class citizen in Herdr from your own code. You don't need a pull request to Herdr, and you don't need to wait for a Herdr release. + +Once your agent reports to Herdr, users get: + +- your agent's name and `idle`, `working`, or `blocked` state in the sidebar and in `herdr agent list` +- notifications when it finishes or needs a decision +- `herdr agent wait` and other automation that waits on agent state +- the same session back in the same pane after a Herdr server restart + +Herdr owns the integrations for agents whose vendors don't ship one. If you maintain your agent, owning the integration yourself means you can fix it on your own release schedule. + +## How it works + +Every process in a Herdr pane inherits these environment variables: + +| Variable | Meaning | +| --- | --- | +| `HERDR_ENV` | `1` inside Herdr | +| `HERDR_PANE_ID` | The pane your agent runs in | +| `HERDR_BIN_PATH` | The Herdr binary that owns this pane | +| `HERDR_SOCKET_PATH` | Herdr's API socket | + +Your agent makes three kinds of reports through `"$HERDR_BIN_PATH"`: + +1. **State.** Report `idle`, `working`, or `blocked` whenever it changes. +2. **Resume command.** Report the command that reopens the current session. +3. **Release.** Release the pane when your agent exits. + +Only report when `HERDR_ENV=1` and the other variables are set. Outside Herdr, your integration should do nothing. + +## Report state + +```bash +"$HERDR_BIN_PATH" pane report-agent "$HERDR_PANE_ID" \ + --source my-agent \ + --agent my-agent \ + --state working \ + --seq 1 +``` + +- Report `working` when a turn starts, `idle` when your agent is ready for input, and `blocked` when it needs the user to decide something. Add `--message` to explain a block. +- `--agent` is the name users see. Use your own agent's name, not the name of an agent Herdr already supports. +- `--source` identifies your integration. Keep it stable and unique. Don't start it with `herdr:`, because Herdr's own integrations use that prefix. +- `--seq` is optional but recommended. It must increase with every report from your source, including across sessions and restarts of your agent. A timestamp works well. Herdr ignores reports whose number is not higher than the last one it accepted, so late or out-of-order reports can't overwrite newer state. + +## Report the resume command + +Put the command that resumes the current session after `--`. Include the options that session needs, such as the model or permission mode, so the resumed session behaves the same: + +```bash +"$HERDR_BIN_PATH" pane report-agent "$HERDR_PANE_ID" \ + --source my-agent \ + --agent my-agent \ + --state idle \ + --seq 2 \ + --agent-session-id "$SESSION_ID" \ + -- my-agent --resume "$SESSION_ID" --model my-model +``` + +You can attach the command to any state report, or send it with `pane report-agent-session` when only the session changes. Report it again whenever your agent switches sessions. + +After a Herdr server restart, Herdr opens the pane in the same directory and runs that command there. The command must follow these rules: + +- The first word is a plain command name on the user's `PATH`, such as `my-agent`, not a path. +- No argument contains an apostrophe. +- Your source must hold the pane first, so send a state report with `report-agent` before or along with the command. Otherwise Herdr answers with `resume_not_accepted`. + +Herdr rejects a command that breaks the first two rules with `invalid_resume_argv` and does not apply that report. Users can turn off resume with `[session] resume_agents_on_restore = false`. + +## Release on exit + +```bash +"$HERDR_BIN_PATH" pane release-agent "$HERDR_PANE_ID" \ + --source my-agent \ + --agent my-agent \ + --seq 3 +``` + +Releasing clears your agent's name, state, and resume command from the pane right away. Only release when the user actually quits. If your agent replaces one session with another in the same process, report the new session instead of releasing. + +If your agent exits without releasing, Herdr notices once the pane is back at its idle shell prompt and clears the agent and its resume command. This usually takes a second or two. It is a safety net, not a replacement for releasing. + +## Keep it out of the way + +- Don't let Herdr slow your agent down. Send reports in the background or with a short timeout, and ignore failures. +- Send only the latest state. If several changes queue up while a report is in flight, drop the older ones. +- Older Herdr versions ignore the resume command, so everything else keeps working there. + +## Use the socket directly + +`HERDR_BIN_PATH` and the CLI are the portable choice, including on Windows. If your agent needs direct IPC, send the equivalent `pane.report_agent`, `pane.report_agent_session`, and `pane.release_agent` requests described in the [Socket API](/docs/socket-api/#agent-state-reporting). The resume command goes in the `resume_argv` array. + +## Check your integration + +Start your agent in a Herdr pane, then check what Herdr sees: + +```bash +herdr pane get "$HERDR_PANE_ID" +herdr agent list +``` + +To test restore without touching your normal session, use a separate named session: + +1. Start `herdr --session my-agent-test`, then run your agent in a pane. +2. Stop that session with `herdr session stop my-agent-test`. +3. Start `herdr --session my-agent-test` again. The pane should run your resume command and your agent should report again. + +## Example + +[Prime Agent's built-in Herdr reporter](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/core/extensions/builtin/herdr-agent-state.ts) is a real-world integration. It activates only inside Herdr, maps agent events to `working`, `idle`, and `blocked`, keeps its report order across sessions, and releases the pane on exit. + +To change how your agent appears without changing its state, such as a title or custom status text, see [Custom status labels](/docs/integrations/#custom-status-labels). diff --git a/docs/preview/website/src/content/docs/agent-automation.mdx b/docs/preview/website/src/content/docs/agent-automation.mdx index e7c02ae3..def306fa 100644 --- a/docs/preview/website/src/content/docs/agent-automation.mdx +++ b/docs/preview/website/src/content/docs/agent-automation.mdx @@ -77,6 +77,8 @@ Pane input addresses the terminal regardless of its current occupant. Agent inpu `idle` and `done` both mean the agent is ready for input. The CLI/API uses the server's seen state: `done` is idle but not yet marked seen, explicit `pane focus` / `agent focus` commands mark the target seen, and reads do not. Each TUI client tracks viewed completions independently, so a client's Done badge can differ from the CLI or another client's badge. `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. +Startup readiness, restoring an idle conversation, and switching agent conversations do not count as completed work. An agent that starts working immediately can finish its first task without Herdr first seeing an idle prompt. Agent responses may include `completion_seq`, identifying the current idle transition as completed work independently of who has viewed it. It matches that transition's `state_change_seq`; startup and session changes do not set it. Older servers may omit this field. Clients connected to older servers use observed working states to guard Done badges, so they may miss a turn that starts and finishes between updates. + A timeout or `agent_prompt_stalled` does not prove that no input was sent. Read the agent before retrying to avoid submitting the same prompt twice. IDs and agent names are scoped to one server; selecting another machine in the TUI does not retarget CLI commands running in an existing pane. `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. diff --git a/docs/preview/website/src/content/docs/agents.mdx b/docs/preview/website/src/content/docs/agents.mdx index d0612c3f..5c4351a5 100644 --- a/docs/preview/website/src/content/docs/agents.mdx +++ b/docs/preview/website/src/content/docs/agents.mdx @@ -58,9 +58,11 @@ Some restricted Linux runtimes do not expose a terminal foreground process group ## Blocked state -Blocked detection is deliberately strict for screen-manifest agents. Herdr only marks `blocked` when the live bottom-buffer snapshot matches known visible approval, question, or permission UI. If no manifest rule matches for a known agent, Herdr falls back to `idle` and labels that fallback as `default_known_agent_idle_fallback` in explain output. +Blocked detection is deliberately strict for screen-manifest agents. Herdr only marks `blocked` when the live bottom-buffer snapshot matches known visible approval, question, or permission UI. If no manifest rule matches for a known agent other than Codex, Herdr falls back to `idle` and labels that fallback as `default_known_agent_idle_fallback` in explain output. Codex falls back to `unknown` because its title and composer can look the same during an active turn and after a response. -This means unusual new agent prompts may initially show as `idle` instead of `blocked` until Herdr learns that screen shape. The misclassification affects only the visible status and waits. It should not make Herdr send input or take destructive action. +For those other agents, unusual new prompts may initially show as `idle` instead of `blocked` until Herdr learns that screen shape. The misclassification affects only the visible status and waits. It should not make Herdr send input or take destructive action. + +For Codex, a visible spinner or live activity timer can establish `working`, and a visible approval prompt can establish `blocked`. An ordinary title, composer, or missing spinner cannot establish that a turn ended. Codex may therefore stay `unknown` after a response, and waits for `idle` or completion may time out. Managed startup uses the initial composer only to determine when it can accept a prompt; that observation does not change turn status. ## Detection manifests @@ -89,6 +91,14 @@ Live explain is evaluated by the running server, so it reflects the active manif Herdr can run inside tmux as the outer terminal environment. Agent detection does not inspect tmux sessions launched inside a Herdr pane. If a shell framework auto-enters tmux inside Herdr, Herdr sees `tmux` as the pane process instead of the agent behind it. +If your shell automatically attaches to tmux whenever `TMUX` is unset, update its startup rule to exclude Herdr panes. Reattaching the outer tmux session from inside a Herdr pane can recursively shrink the terminal and make it flicker. Add the `HERDR_ENV` check to your existing condition before it runs tmux: + +```zsh +if [[ -z ${TMUX:-} && ${HERDR_ENV:-} != 1 ]]; then + tmux new-session -A -s my-session +fi +``` + ## State rollups The sidebar rolls state upward. @@ -106,7 +116,7 @@ herdr integration install claude herdr integration status ``` -Each supported agent has its own integration name and behavior. See [Integrations](/docs/integrations/) for the per-agent details and the full install list. If you are building an agent, the [custom integration guide](/docs/integrations/#integrate-your-own-agent) shows how to report lifecycle state without adding native support to Herdr. +Each supported agent has its own integration name and behavior. See [Integrations](/docs/integrations/) for the per-agent details and the full install list. If you are building an agent, [Add Herdr support to your agent](/docs/add-herdr-support/) shows how to report lifecycle state and a resume command without adding native support to Herdr. ## Custom agent labels diff --git a/docs/preview/website/src/content/docs/cli-reference.mdx b/docs/preview/website/src/content/docs/cli-reference.mdx index cf9b355f..31fe26a9 100644 --- a/docs/preview/website/src/content/docs/cli-reference.mdx +++ b/docs/preview/website/src/content/docs/cli-reference.mdx @@ -51,6 +51,7 @@ with the installed binary. Use `--json` for the full JSON Schema document, or ```bash herdr machine list +herdr machine add workbox herdr machine add workbox --label "Build machine" herdr machine rename <profile-id> --label "New name" herdr machine disable <profile-id> @@ -58,13 +59,13 @@ herdr machine enable <profile-id> herdr machine remove <profile-id> ``` -By default, `machine add` uses the remote default session. Add `--remote-session <name>` only for a named session. `machine list` accepts optional `--json` for scripts. See [Connecting machines](/docs/connecting-machines/) for the full setup and connection guide. +In an interactive terminal, `machine add` discovers running sessions and lets you choose when several are running. No running sessions, or no Herdr installation, uses `default`; failed queries against an installed binary require an explicit choice. Add `--remote-session <name>` to skip discovery. Non-interactive commands use `default` unless that flag is supplied. `machine list` accepts optional `--json` for scripts. See [Connecting machines](/docs/connecting-machines/) for the full setup and connection guide. `machine add` checks the remote installation's capabilities, installs or updates with approval only when needed, and starts the requested session's background server before saving. Compatible release versions do not need to match. Run setup in an interactive terminal when installation or restart approval is required; failed or cancelled setup does not save a profile. Replacing a running server requires explicit approval with a default answer of No, and stops its pane processes. `machine add` never enables experimental handoff implicitly. Changes apply automatically to open local Herdr clients, normally within a second. Added or enabled machines connect in the background; renaming does not reconnect. Removing or disabling disconnects only that machine and leaves its remote sessions running. Removing the machine you are viewing returns to Local, or shows Local as unavailable until it reconnects. Each profile stores an opaque ID, label, SSH target, explicit remote session, and enabled state in client state. Herdr does not store passwords, private keys, or other SSH credentials. -Automatic connections and reconnects are non-interactive. If a host key, password, key passphrase, MFA step, install, update, or restart needs approval, the machine shows Attention instead of opening a hidden prompt. Run the standalone command printed by Herdr, such as `herdr --remote workbox`, to complete that setup in the foreground, then restart the client. Include `--session <name>` only when the profile targets a named session. +Use `herdr machine status [<label-or-id>] [--json]` for fresh, noninteractive SSH and remote Herdr checks. `reachable` describes this check, not a TUI's current connection. Use `herdr machine reconnect <label-or-id>` in a terminal for SSH authentication and verification; it does not install or update Herdr. Open clients retry failed connections within 30 seconds. Clicking `! auth` or `! error` shows the latest error and CLI guidance; collapsed sidebars show `!`. See [Recovering SSH authentication](/docs/connecting-machines/#recovering-ssh-authentication) for platform limits. For remote setup, use `herdr --remote workbox`, adding `--session <name>` only for a named session. Workspace, tab, pane IDs, and agent names belong to a single server. Selecting a machine in the UI does not retarget CLI commands. Use the global **prefix** `--machine <label-or-id>` to route API commands to a saved SSH machine: @@ -277,7 +278,8 @@ herdr pane report-agent <pane_id> \ [--message TEXT] \ [--seq N] \ [--agent-session-id ID] \ - [--agent-session-path PATH] + [--agent-session-path PATH] \ + [-- RESUME_COMMAND...] herdr pane report-agent-session <pane_id> \ --source ID \ @@ -285,7 +287,8 @@ herdr pane report-agent-session <pane_id> \ [--seq N] \ [--agent-session-id ID] \ [--agent-session-path PATH] \ - [--session-start-source SOURCE] + [--session-start-source SOURCE] \ + [-- RESUME_COMMAND...] herdr pane release-agent <pane_id> \ --source ID \ @@ -295,6 +298,8 @@ herdr pane release-agent <pane_id> \ `report-agent-session` updates native session identity without reporting lifecycle state. `release-agent` ends that source's lifecycle authority when its agent process exits. +Arguments after `--` are the command Herdr runs to resume this session after a server restart. The first argument must be a plain command name on `PATH`, and no argument may contain an apostrophe. + `pane get`, `pane list`, `agent get`, and `agent list` include a read-only `agent_session` object when an official integration has reported a native session reference. If no native session reference is stored, the field is omitted. Those commands include `foreground_cwd` when Herdr can resolve the cwd of the foreground process controlling the pane. The `cwd` field remains the pane/workspace cwd used for labels and follow-cwd behavior. @@ -376,8 +381,17 @@ Detach from direct attach with `ctrl+b q`. Send literal `ctrl+b` with `ctrl+b ct terminal, or agent target. It prints the same newline-delimited `terminal.frame` and `terminal.closed` records as observe mode. It reads newline-delimited JSON commands on stdin: `terminal.input`, `terminal.resize`, -`terminal.scroll`, and `terminal.release`. One controller can own a terminal at -a time; use `--takeover` to replace it. +`terminal.scroll`, `terminal.mouse`, and `terminal.release`. One controller can +own a terminal at a time; use `--takeover` to replace it. +`terminal.mouse` sends one mouse event at a zero-based cell of the controller's +viewport, for example +`{"type":"terminal.mouse","action":"down","button":"left","column":12,"row":5}`. +`action` is `down`, `up`, `drag`, or `move`; `button` is `left` (default), +`right`, or `middle`; `modifiers` is optional and combines Shift = 1, Ctrl = 2, +and Alt = 4 (default 0). A click is `down` followed by `up`. Herdr encodes the +event for the application's mouse mode and drops it when the application has +not enabled mouse reporting, so a plain shell never receives stray input. +`move` reaches only applications that track all mouse motion. `terminal session observe` opens a read-only live terminal stream for a pane, terminal, or agent target. It prints newline-delimited JSON `terminal.frame` records with base64-encoded ANSI bytes, then a `terminal.closed` record when @@ -517,6 +531,17 @@ 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 outside plugin v1. +New panes identify as `TERM_PROGRAM=herdr`, with `TERM_PROGRAM_VERSION` set to +Herdr's version. They keep `TERM=xterm-256color` and `COLORTERM=truecolor`. +Herdr removes inherited outer-terminal session markers (iTerm2, WezTerm, Kitty, +Windows Terminal, tmux, screen, and Zellij), iTerm2's `LC_TERMINAL` identity, +and known Claude Code, Codex, and OMP session markers before applying explicit +launch environment values. This prevents new panes from claiming the terminal +or agent session that originally started the server. Ordinary environment +variables, including API keys and display settings, remain inherited rather than +being replaced with the attaching client's environment. SSH-agent forwarding has +its own reconnect handling. Existing pane processes are unchanged by this cleanup. + `--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. ## Read sources diff --git a/docs/preview/website/src/content/docs/configuration.mdx b/docs/preview/website/src/content/docs/configuration.mdx index c54c79a9..33644e1c 100644 --- a/docs/preview/website/src/content/docs/configuration.mdx +++ b/docs/preview/website/src/content/docs/configuration.mdx @@ -142,6 +142,15 @@ navigate_pane_down = "ctrl+j" split_horizontal = "prefix+minus" ``` +`keys.prefix` also accepts an array when you need to enter prefix mode from more than one key, for example to share one config between macOS and a remote Linux machine: + +```toml +[keys] +prefix = ["ctrl+space", "ctrl+s"] +``` + +Every configured prefix enters the same prefix mode and starts every `prefix+...` action. The first entry is the primary prefix shown in the status bar; the in-app help panel at `prefix+?` lists all of them. + 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: @@ -248,6 +257,8 @@ name = "catppuccin" 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. +On Unix, Herdr also re-reads the host terminal's colors when redrawing after a resize or `SIGWINCH`. If your theme switcher changes terminal colors through OSC without a light/dark notification, send `kill -WINCH <client-pid>` after applying the new palette. Target the attached Herdr client, not the server; existing panes stay running. Direct `herdr terminal attach` sessions leave palette queries to the attached application. + To let Herdr switch its own UI theme when the host terminal reports a light/dark appearance change, enable theme auto-switching: ```toml @@ -512,9 +523,19 @@ Search the [Config reference](/docs/config-reference/) for scrollback limits, ne ## Kitty graphics -Herdr renders pane images by default in compatible outer terminals. Popups, menus, and notifications temporarily hide only the image placements they overlap. Uncovered images stay visible, and hidden placements return when uncovered. Images do not dim with dialog backgrounds. +Applications and plugins integrate through the standard Kitty graphics protocol emitted in pane terminal output. Herdr renders these images by default in compatible outer terminals. The external socket pane-overlay API has been removed; there is no replacement socket image API. -To disable graphics rendering and the pane graphics API: +Popups, menus, and notifications temporarily hide only the image placements they overlap. Uncovered images stay visible, and hidden placements return when uncovered. Images do not dim with dialog backgrounds. + +Herdr automatically chooses eligible file transports, with no application changes or environment switches. On local Unix Ghostty clients, it can send image data through temporary files instead of encoding it into terminal output. A small file-consumption probe checks support first. Other terminals, SSH-launched clients, and nested multiplexers retain inline output for this last-hop optimization. + +For eligible local clients, native RGBA images travel from server to client as paths to Herdr-owned snapshots rather than pixel bytes. Unsupported clients and failed transfers fall back to inline delivery. Remote server paths are never forwarded to the local terminal. Herdr keeps image placement, clipping, and visibility under its control. + +On Linux, whole-file, uncompressed RGBA uploads can use copy-on-write snapshots before Herdr reads their pixels. This requires filesystem support for cloning into Herdr's private `/var/tmp` store. Unsupported filesystems, temporary-file uploads, shared memory, and other formats use the normal loader. Snapshots are limited to 16 MiB each and 64 MiB total; animation and unsupported clients read their pixels when needed. Herdr never relies on a mutable producer path after accepting an image. + +PNG uploads retain full decoding and validation. Herdr does not defer corrupt-image validation to the outer terminal. + +To disable Kitty graphics rendering: ```toml [terminal] @@ -523,7 +544,7 @@ kitty_graphics = false The legacy `experimental.kitty_graphics` setting remains accepted for existing configurations. `terminal.kitty_graphics` takes precedence when both are set. -Changing this setting requires restarting the affected Herdr server or reattaching the client. In remote sessions, the server's setting controls pane graphics parsing and API availability, while the local client's setting controls output to the outer terminal. +Changing this setting requires restarting the affected Herdr server or reattaching the client. In remote sessions, the server's setting controls Kitty graphics parsing, while the local client's setting controls output to the outer terminal. ## Agent session restore @@ -532,8 +553,11 @@ Herdr resumes supported Agent conversations after a server restart by default: ```toml [session] resume_agents_on_restore = true +startup_per_agent_delay_ms = 100 ``` +Automatic restores start one agent at a time, 100 milliseconds apart by default, to reduce startup contention. The first eligible agent starts immediately. Set `startup_per_agent_delay_ms = 0` to disable spacing. Manual launches and explicit terminal attaches are unaffected. Restart the Herdr server to apply changes. + 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 diff --git a/docs/preview/website/src/content/docs/connecting-machines.mdx b/docs/preview/website/src/content/docs/connecting-machines.mdx index 3f7bcfe6..47bc19a5 100644 --- a/docs/preview/website/src/content/docs/connecting-machines.mdx +++ b/docs/preview/website/src/content/docs/connecting-machines.mdx @@ -9,6 +9,12 @@ Each machine keeps its own Herdr server, sessions, and running processes. A lost Herdr requests SSH compression to reduce screen-update traffic on limited connections. This works with older compatible Herdr servers and does not change how typing or other input is delivered. Herdr's `-C` option overrides `Compression no` in your SSH config. If SSH reuses an existing connection through an external ControlMaster, that connection keeps its original compression setting. +### Recovering SSH authentication + +On Linux and macOS clients, when `remote.manage_ssh_config=true`, Herdr shares an approved OpenSSH connection across machine add, the sidebar, and saved-machine API commands. Run `herdr machine status [<label-or-id>] [--json]` for fresh, noninteractive checks. **Reachable** means the remote Herdr server is available now, not that every open TUI is connected. Run `herdr machine reconnect <label-or-id>` in a terminal to complete native SSH authentication and verify the saved machine. It does not install or update Herdr. Open clients recheck failed connections within 30 seconds; no restart is needed. Clicking **`! auth`**, **`! error`**, or a failed connection's reconnecting status shows a notice with its latest error and the relevant CLI command. It never opens a credential popup. The rest of the machine row keeps its normal expand/collapse behavior. + +The shared connection uses `ControlPersist 600` (10 minutes of idle time); this is not MFA validity. Active connections can remain open, while corporate policy, the SSH server, or the network may end them sooner. Local Windows recovery is not supported yet. For unmanaged SSH connections, authentication remains your responsibility: running `ssh` by itself does not grant Herdr approval unless it uses the shared ControlPath. Host-key checking is unchanged; an unknown or changed host key remains **Attention**. + ## Before you connect You need normal SSH access to the remote machine. Verify it first: @@ -26,17 +32,23 @@ Multi-machine connections support Linux, macOS, and Windows clients connecting t Run setup in an interactive terminal so Herdr can ask before installing or replacing anything: ```bash -herdr machine add workbox --label "Build machine" +herdr machine add workbox ``` -This uses the remote default session. A machine profile targets one remote session; it does not combine every session on the host. +In an interactive terminal, Herdr discovers running sessions: it selects the only running session, or lets you choose with Up/Down and Enter when several are running. Esc or Ctrl+C cancels. If a successful query finds no running sessions, setup uses `default`. If no Herdr installation is found, setup offers to install it for `default`. If an installed binary cannot report its sessions, setup reports the error; pass `--remote-session <name>` to select a session explicitly. + +The sidebar shows the default session as `workbox`, the SSH host without any `user@` prefix. Add `--label "Build machine"` to choose a different name. A machine profile targets one remote session; it does not combine every session on the host. Non-interactive commands use `default` unless `--remote-session` is supplied. -To use a named session instead, add the optional `--remote-session` flag: +To skip discovery and use a specific session, add `--remote-session`: ```bash -herdr machine add workbox --label "Build machine" --remote-session agents +herdr machine add workbox --remote-session agents ``` +Without `--label`, this machine shows as `workbox/agents`. If the default name is already taken, `machine add` asks you to pass `--label`. + +On Windows servers, setup also checks executables used by Herdr processes owned by the SSH user. It validates their capabilities before reuse, so a compatible running build can be used even when SSH's `PATH` points to an older installation. + Herdr checks both the installed binary and the running server. It starts the requested background server before saving the profile. Compatible client and server versions do not have to match. Missing or incompatible installations go through an approval-based setup. When the running server needs replacement, setup asks before stopping it and its pane processes, then starts the compatible server. The default answer is No. If installation and replacement are both needed, one confirmation covers them. `machine add` does not use experimental live handoff. Cancelling or failing setup leaves the profile unsaved. Run `herdr` to open the UI. If a local client is already open, added and enabled machines normally appear within a second and connect in the background without changing your selection. An in-progress machine switch finishes before profile changes are applied. The remote server keeps running after setup exits. @@ -76,21 +88,25 @@ Removing or disabling the machine you are viewing returns you to Local. If Local ## Connection problems - **Reconnecting:** Herdr retries automatically after a network interruption, sleep, or SSH failure. Repeated failures increase the delay up to two minutes; brief successful connections do not reset it. A connection must remain healthy for a minute before the next interruption gets a fast retry. SSH connections are checked for application-level activity and probed when quiet, so a broken connection does not stay Online indefinitely. Local detects native connection closure or failure instead of using remote health probes. -- **Attention:** The target needs an action that cannot be completed in the background, such as host-key approval, authentication, or a compatible server. Other machines remain usable. +- **Attention:** The target needs an action such as authentication, host-key approval, or a compatible server. Other machines remain usable. **`! auth`** means authentication failed; **`! error`** indicates another issue. Click the badge for the error and a CLI command. In a collapsed sidebar, either appears as `!`. - **Saved-machine file error:** An unreadable or invalid catalog leaves current connections unchanged. Herdr shows a notice and automatically retries reading it. When both installations support bridge idle cleanup, saved-machine connections to Linux and macOS also close their remote bridge after a minute without traffic in either direction. Sleep counts toward that deadline, which is checked when the host wakes. Quiet healthy connections exchange health checks; watching continuous output does not require typing. Cleanup leaves the remote Herdr server, sessions, and pane processes running. Older installations remain compatible without this optional cleanup. -Background connections never answer prompts or install, update, restart, or hand off a server. For Attention, run the standalone setup command shown by Herdr in an interactive terminal, for example: +Background connections never answer prompts or install, update, restart, or hand off a server. For non-authentication Attention, run the standalone setup command shown by Herdr in an interactive terminal, for example: ```bash herdr --remote workbox ``` -Use your profile's target. If you chose a named session when adding it, include the optional `--session <name>` here too. Follow any approval prompts, then restart the client to retry the Attention connection. Do not stop a running server merely because its version differs from the client. +Use your profile's target. If you chose a named session when adding it, include the optional `--session <name>` here too. Follow the requested setup prompts; open clients retry automatically. `machine reconnect` does not install or update Herdr. Do not stop a running server merely because its version differs from the client. If authentication fails, check ordinary SSH first. For a passphrase-protected key, load it with `ssh-add` before starting Herdr's non-interactive background connections. +For Git authentication or SSH signing inside remote panes, enable `ForwardAgent yes` for the trusted host in your SSH config. Herdr does not enable forwarding for you. When a session starts with an agent, updated Linux and macOS servers give panes a stable agent address, so existing and new panes can use the forwarded agent after `--remote` or a saved machine reconnects. A working inherited agent or earlier connection keeps priority over later clients and temporary setup checks; if it disappears, another live attachment can supply the agent. + +This requires an updated remote server, not just an updated local client. Local sessions started without an agent leave `SSH_AUTH_SOCK` alone. Panes created before the server update, or before an agent was first supplied to the session, keep their original environment and need to be recreated once to inherit the stable address. Older compatible servers and connections without agent forwarding can still attach normally. + ## Settings and automation The UI uses the client's local theme, sidebar settings, and keybindings by default. Custom commands and plugins advertised by the selected server still run there. Herdr does not copy local command plugins, configuration, executables, or secrets onto SSH hosts. Missing remote commands fail visibly. Use the UI's `reload config` action after editing client settings; see [Configuration](/docs/configuration/#reload-config). diff --git a/docs/preview/website/src/content/docs/install.mdx b/docs/preview/website/src/content/docs/install.mdx index c0c422a5..4dac5ede 100644 --- a/docs/preview/website/src/content/docs/install.mdx +++ b/docs/preview/website/src/content/docs/install.mdx @@ -147,6 +147,8 @@ To opt into experimental live server handoff for supported running sessions, run herdr update --handoff ``` +When both servers support agent-status transfer, live handoff preserves hook-reported agent status until the next report arrives. Handoff from an older server can temporarily show a running agent as idle. + Live handoff does not apply to Homebrew, mise, or Nix package-manager updates. For those installs, update with the package manager, then run Herdr again to reconnect with the updated client. The compatible old server keeps running. Restart it later with `herdr server stop` or `herdr session stop <name>` only when you want server-side changes from the new release. ## Requirements diff --git a/docs/preview/website/src/content/docs/integrations.mdx b/docs/preview/website/src/content/docs/integrations.mdx index 7bca01e6..3aff5ae1 100644 --- a/docs/preview/website/src/content/docs/integrations.mdx +++ b/docs/preview/website/src/content/docs/integrations.mdx @@ -66,37 +66,14 @@ Herdr uses integrations in two ways: Custom integrations can also report state that is not visible in the native terminal UI. They do not need to be built into Herdr or use a recognized agent executable. -## Integrate your own agent - -An agent running in a Herdr pane inherits `HERDR_ENV`, `HERDR_PANE_ID`, `HERDR_BIN_PATH`, and `HERDR_SOCKET_PATH`. If the agent exposes lifecycle hooks, use those hooks to report semantic state through Herdr's CLI: - -```bash -"$HERDR_BIN_PATH" pane report-agent "$HERDR_PANE_ID" \ - --source custom:my-agent \ - --agent my-agent \ - --state working -``` - -Report `idle` when the agent is ready for input and `blocked` when it needs a user decision. Use `--message` to describe a block. When the agent exits, release the same source's lifecycle authority: - -```bash -"$HERDR_BIN_PATH" pane release-agent "$HERDR_PANE_ID" \ - --source custom:my-agent \ - --agent my-agent -``` - -Report only when `HERDR_ENV=1` and the required variables are present. This keeps the integration a no-op outside Herdr. Keep `--source` stable and unique to the integration. If reports can arrive out of order, include a strictly increasing `--seq`; Herdr ignores stale sequence numbers from the same source. - -You can include `--agent-session-id` or `--agent-session-path` with `report-agent`, or use `pane report-agent-session` when session identity changes independently of state. Herdr exposes that reference through its pane and agent APIs. Automatic session restore also requires Herdr to know how to launch that agent and resume the referenced session. - -Use `HERDR_BIN_PATH` and the CLI wrappers for portable integrations. Code that needs direct IPC can send the equivalent `pane.report_agent`, `pane.report_agent_session`, and `pane.release_agent` requests described in the [Socket API](/docs/socket-api/#agent-state-reporting). - -[Prime Agent's built-in Herdr reporter](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/core/extensions/builtin/herdr-agent-state.ts) is a real-world example. It activates only inside Herdr, maps agent events to `working`, `idle`, and `blocked`, preserves report ordering across sessions, and releases authority on exit. - Some integrations report native agent session references. Herdr uses official session references to resume Claude Code, Codex, Devin CLI, Droid, Kimi Code CLI, Qoder CLI, Qwen Code, Letta Code, Cursor Agent CLI, Grok CLI, GitHub Copilot CLI, Pi, OMP, Hermes Agent, OpenCode, Kilo Code CLI, MastraCode, and Antigravity CLI panes after a Herdr server restart unless `[session] resume_agents_on_restore = false` disables it. Native session restore requires current Herdr integrations: Pi integration version `2`, OMP version `3`, Claude Code version `6`, Codex version `5`, GitHub Copilot CLI version `2`, Devin CLI version `2`, Droid version `2`, Kimi Code CLI version `3`, Qoder CLI version `2`, Qwen Code version `1`, Letta Code version `1`, Cursor Agent CLI version `1`, Grok CLI version `2`, OpenCode version `5`, Kilo Code CLI version `1`, Hermes Agent version `5`, MastraCode version `1`, or Antigravity CLI version `1`. Check installed versions with `herdr integration status`. +## Integrate your own agent + +If you build a coding agent, you can report its state and resume command to Herdr from your own code, without adding native support to Herdr. See [Add Herdr support to your agent](/docs/add-herdr-support/). + ## Pi Install the Pi integration: @@ -227,6 +204,10 @@ Install registers the V1 TUI plugin in `tui.jsonc` and the V2 TUI plugin in `cli V2 lifecycle reporting runs in the pane-local TUI, which associates events with its selected root session even when multiple panes share one OpenCode server. Completion and interruption clear the working state; pending permission requests, pending forms, and failed executions keep the pane blocked. V2 Mini and headless clients do not run the TUI plugin and therefore do not provide this lifecycle reporting. +V1 TUI reporting follows the pane's selected session and its descendants. The pane stays working while any of them is busy or retrying, and blocked while any has a pending permission or question. Attaching loads existing activity; cancelled tool requests do not become blockers again after reconnecting. Browsing a subagent keeps the original session family, while directly attaching to a child tracks that child's subtree rather than its siblings. + +Local V1 `opencode run` and `opencode --mini` retain their legacy server hooks; this change does not add pane-local lifecycle reporting to Mini/headless clients. After updating the integration, restart shared OpenCode servers as well as their TUIs so the old server reporter cannot overwrite pane-local state. + The plugin reports lifecycle state and session identity while OpenCode runs inside a Herdr pane. After OpenCode emits a session-bearing event, Herdr can use the reported session id to resume the pane with `opencode --session <id>`. Native screen manifest detection remains available when the plugin is not installed. ## Kilo Code CLI diff --git a/docs/preview/website/src/content/docs/ja/add-herdr-support.mdx b/docs/preview/website/src/content/docs/ja/add-herdr-support.mdx new file mode 100644 index 00000000..d095bc2d --- /dev/null +++ b/docs/preview/website/src/content/docs/ja/add-herdr-support.mdx @@ -0,0 +1,117 @@ +--- +title: エージェントに Herdr 対応を追加する +description: Herdr にネイティブサポートを追加せずに、自分のコードからコーディングエージェントの状態と resume コマンドを Herdr に報告します。 +--- + +コーディングエージェントを開発しているなら、自分のコードだけでそのエージェントを Herdr の第一級の存在にできます。Herdr へのプルリクエストも、Herdr のリリースを待つ必要もありません。 + +エージェントが Herdr に報告すると、ユーザーは次のものを得られます: + +- サイドバーと `herdr agent list` に表示されるエージェント名と `idle`、`working`、`blocked` の状態 +- 完了したときや判断が必要になったときの通知 +- `herdr agent wait` など、エージェントの状態を待つ自動化 +- Herdr サーバーの再起動後、同じペインで同じセッションが戻ること + +ベンダーがインテグレーションを提供していないエージェントについては、Herdr がインテグレーションを管理します。エージェントのメンテナーが自分でインテグレーションを持てば、自分のリリーススケジュールで修正できます。 + +## 仕組み + +Herdr ペイン内のすべてのプロセスは、次の環境変数を継承します: + +| 変数 | 意味 | +| --- | --- | +| `HERDR_ENV` | Herdr 内では `1` | +| `HERDR_PANE_ID` | エージェントが動いているペイン | +| `HERDR_BIN_PATH` | このペインを管理する Herdr バイナリ | +| `HERDR_SOCKET_PATH` | Herdr の API ソケット | + +エージェントは `"$HERDR_BIN_PATH"` を通じて 3 種類の報告をします: + +1. **状態。** `idle`、`working`、`blocked` が変わるたびに報告します。 +2. **resume コマンド。** 現在のセッションを開き直すコマンドを報告します。 +3. **解放。** エージェントの終了時にペインを解放します。 + +`HERDR_ENV=1` で他の変数も設定されているときだけ報告してください。Herdr の外では、インテグレーションは何もしないようにします。 + +## 状態を報告する + +```bash +"$HERDR_BIN_PATH" pane report-agent "$HERDR_PANE_ID" \ + --source my-agent \ + --agent my-agent \ + --state working \ + --seq 1 +``` + +- ターンの開始時に `working`、入力を受け付けられるときに `idle`、ユーザーの判断が必要なときに `blocked` を報告します。ブロックの理由は `--message` で説明できます。 +- `--agent` はユーザーに表示される名前です。Herdr がすでに対応しているエージェントの名前ではなく、自分のエージェントの名前を使ってください。 +- `--source` はインテグレーションを識別します。固定かつ一意にしてください。`herdr:` で始めないでください。この接頭辞は Herdr 自身のインテグレーションが使います。 +- `--seq` は省略できますが、付けることを推奨します。source からの報告ごとに増加する必要があり、エージェントのセッションや再起動をまたいでも増加し続ける必要があります。タイムスタンプが適しています。Herdr は最後に受け付けた番号より大きくない報告を無視するので、遅れて届いた報告や順不同の報告が新しい状態を上書きすることはありません。 + +## resume コマンドを報告する + +現在のセッションを再開するコマンドを `--` の後に置きます。モデルや権限モードなど、そのセッションに必要なオプションも含めると、再開したセッションが同じように動きます: + +```bash +"$HERDR_BIN_PATH" pane report-agent "$HERDR_PANE_ID" \ + --source my-agent \ + --agent my-agent \ + --state idle \ + --seq 2 \ + --agent-session-id "$SESSION_ID" \ + -- my-agent --resume "$SESSION_ID" --model my-model +``` + +コマンドはどの状態報告に付けてもかまいません。セッションだけが変わったときは `pane report-agent-session` で送れます。エージェントがセッションを切り替えるたびに、もう一度報告してください。 + +Herdr サーバーの再起動後、Herdr は同じディレクトリでペインを開き、そこでそのコマンドを実行します。コマンドは次のルールに従う必要があります: + +- 最初の語は、`my-agent` のようにユーザーの `PATH` 上にある単純なコマンド名にします。パスは使えません。 +- どの引数にもアポストロフィを含めません。 +- 先に source がペインを保持している必要があります。コマンドより前か同時に、`report-agent` で状態を報告してください。そうしないと Herdr は `resume_not_accepted` を返します。 + +最初の 2 つのルールに違反するコマンドは、Herdr が `invalid_resume_argv` で拒否し、その報告は適用されません。ユーザーは `[session] resume_agents_on_restore = false` で resume を無効にできます。 + +## 終了時に解放する + +```bash +"$HERDR_BIN_PATH" pane release-agent "$HERDR_PANE_ID" \ + --source my-agent \ + --agent my-agent \ + --seq 3 +``` + +解放すると、エージェントの名前、状態、resume コマンドがすぐにペインから消えます。解放するのはユーザーが実際に終了したときだけにしてください。同じプロセス内でセッションを別のセッションに置き換える場合は、解放せずに新しいセッションを報告します。 + +エージェントが解放せずに終了した場合、Herdr はペインがアイドルなシェルプロンプトに戻ったことに気づき、エージェントと resume コマンドを消去します。通常は 1〜2 秒かかります。これは安全網であり、解放の代わりにはなりません。 + +## エージェントの邪魔をしない + +- Herdr のせいでエージェントを遅くしないでください。報告はバックグラウンドか短いタイムアウトで送り、失敗は無視します。 +- 最新の状態だけを送ります。報告の送信中に複数の変化がたまったら、古いものは捨てます。 +- 古い Herdr は resume コマンドを無視するので、それ以外の機能はそのまま動きます。 + +## ソケットを直接使う + +`HERDR_BIN_PATH` と CLI は Windows を含めて移植性のある選択肢です。エージェントに直接の IPC が必要な場合は、[Socket API](/ja/docs/socket-api/) に記載された同等の `pane.report_agent`、`pane.report_agent_session`、`pane.release_agent` リクエストを送信します。resume コマンドは `resume_argv` 配列に入れます。 + +## インテグレーションを確認する + +Herdr のペインでエージェントを起動し、Herdr から見える内容を確認します: + +```bash +herdr pane get "$HERDR_PANE_ID" +herdr agent list +``` + +普段のセッションに影響を与えずに復元をテストするには、別の名前付きセッションを使います: + +1. `herdr --session my-agent-test` を起動し、ペインでエージェントを実行します。 +2. `herdr session stop my-agent-test` でそのセッションを停止します。 +3. `herdr --session my-agent-test` をもう一度起動します。ペインで resume コマンドが実行され、エージェントが再び報告するはずです。 + +## 例 + +[Prime Agent の組み込み Herdr レポーター](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/core/extensions/builtin/herdr-agent-state.ts)は実際のインテグレーションです。Herdr 内でのみ有効になり、エージェントイベントを `working`、`idle`、`blocked` に対応付け、セッションをまたいで報告順序を維持し、終了時にペインを解放します。 + +タイトルやカスタムのステータス文言など、状態を変えずにエージェントの見た目を変えるには、[カスタムステータスラベル](/ja/docs/integrations/#カスタムステータスラベル)を参照してください。 diff --git a/docs/preview/website/src/content/docs/ja/agents.mdx b/docs/preview/website/src/content/docs/ja/agents.mdx index 3a365221..cb71a678 100644 --- a/docs/preview/website/src/content/docs/ja/agents.mdx +++ b/docs/preview/website/src/content/docs/ja/agents.mdx @@ -89,6 +89,14 @@ herdr agent explain --file screen.txt --agent codex --json Herdr は外側のターミナル環境として tmux の中で動かせます。エージェント検出は、Herdr のペイン内で起動された tmux セッションの中までは調べません。シェルフレームワークが Herdr 内で自動的に tmux に入る場合、Herdr はペインのプロセスとして背後のエージェントではなく `tmux` を見ることになります。 +`TMUX` が未設定のときにシェルが自動的に tmux に接続する場合、シェルの起動条件を更新して Herdr のペインを除外してください。Herdr のペイン内から外側の tmux セッションに再接続すると、ターミナルのサイズが再帰的に縮小し、画面がちらつくことがあります。既存の条件に、tmux を実行する前に `HERDR_ENV` の確認を追加します: + +```zsh +if [[ -z ${TMUX:-} && ${HERDR_ENV:-} != 1 ]]; then + tmux new-session -A -s my-session +fi +``` + ## 状態のロールアップ サイドバーは状態を上位へ集約します。 @@ -106,7 +114,7 @@ herdr integration install claude herdr integration status ``` -対応エージェントごとに、インテグレーションの名前と挙動は異なります。エージェント別の詳細と完全なインストール一覧は[インテグレーション](/ja/docs/integrations/)を参照してください。エージェントを開発している場合は、[カスタムインテグレーションガイド](/ja/docs/integrations/#独自エージェントを統合する)で、Herdr にネイティブサポートを追加せずにライフサイクル状態を報告する方法を確認できます。 +対応エージェントごとに、インテグレーションの名前と挙動は異なります。エージェント別の詳細と完全なインストール一覧は[インテグレーション](/ja/docs/integrations/)を参照してください。エージェントを開発している場合は、[エージェントに Herdr 対応を追加する](/ja/docs/add-herdr-support/)で、Herdr にネイティブサポートを追加せずにライフサイクル状態と resume コマンドを報告する方法を確認できます。 ## カスタムエージェントラベル diff --git a/docs/preview/website/src/content/docs/ja/cli-reference.mdx b/docs/preview/website/src/content/docs/ja/cli-reference.mdx index 99a2e133..2904b069 100644 --- a/docs/preview/website/src/content/docs/ja/cli-reference.mdx +++ b/docs/preview/website/src/content/docs/ja/cli-reference.mdx @@ -62,7 +62,7 @@ herdr machine remove <profile-id> 変更は、開いているローカルの Herdr クライアントに通常 1 秒以内に自動反映されます。追加または有効化したマシンにはバックグラウンドで接続し、名前の変更では再接続しません。削除または無効化すると、そのマシンだけが切断され、リモートセッションは動き続けます。表示中のマシンを削除すると Local に戻ります。Local に接続できない場合は、再接続するまで利用不可と表示します。各プロファイルは、不透明な ID、ラベル、SSH 接続先、明示的なリモートセッション名、有効状態をクライアントの状態ファイルに保存します。パスワード、秘密鍵、その他の SSH 認証情報は保存しません。 -自動接続と再接続は非対話型です。ホスト鍵、パスワード、鍵のパスフレーズ、MFA、インストール、更新、再起動に承認が必要な場合、隠れたプロンプトを開くのではなく Attention と表示します。`herdr --remote workbox` など、Herdr が表示する単独接続用のコマンドを実行してフォアグラウンドでセットアップを完了し、クライアントを再起動してください。名前付きセッションを選んだプロファイルにだけ `--session <name>` を追加します。 +`herdr machine status [<label-or-id>] [--json]` は SSH とリモート Herdr を非対話式で確認します。`reachable` は今回の確認結果で、TUI の接続状態ではありません。ターミナルで `herdr machine reconnect <label-or-id>` を実行すると認証と検証を行いますが、インストールや更新は行いません。開いているクライアントは 30 秒以内に再試行します。`! auth` または `! error` をクリックすると最新のエラーと CLI コマンドを表示します。折りたたみ時は `!` です。対応環境は [SSH 認証の復旧](/ja/docs/connecting-machines/#ssh-認証の復旧)を参照してください。セットアップには `herdr --remote workbox` を使い、名前付きセッションの場合だけ `--session <name>` を追加します。 ワークスペース、タブ、ペインの ID とエージェント名はサーバーごとに独立しています。UI での選択は CLI の接続先を変えません。保存済み SSH マシンへ API コマンドを送るには、グローバルな**プレフィックス** `--machine <label-or-id>` を指定します。 @@ -258,7 +258,8 @@ herdr pane report-agent <pane_id> \ [--message TEXT] \ [--seq N] \ [--agent-session-id ID] \ - [--agent-session-path PATH] + [--agent-session-path PATH] \ + [-- RESUME_COMMAND...] herdr pane report-agent-session <pane_id> \ --source ID \ @@ -266,7 +267,8 @@ herdr pane report-agent-session <pane_id> \ [--seq N] \ [--agent-session-id ID] \ [--agent-session-path PATH] \ - [--session-start-source SOURCE] + [--session-start-source SOURCE] \ + [-- RESUME_COMMAND...] herdr pane release-agent <pane_id> \ --source ID \ @@ -276,6 +278,8 @@ herdr pane release-agent <pane_id> \ `report-agent-session` はライフサイクル状態を報告せずにネイティブセッション識別子を更新します。`release-agent` は、そのエージェントプロセスが終了したときに、そのソースのライフサイクル権限を終了します。 +`--` の後の引数は、サーバー再起動後にこのセッションを再開するために Herdr が実行するコマンドです。最初の引数は `PATH` 上の単純なコマンド名でなければならず、どの引数にもアポストロフィを含めることはできません。 + 公式インテグレーションがネイティブセッション参照を報告している場合、`pane get`、`pane list`、`agent get`、`agent list` は読み取り専用の `agent_session` オブジェクトを含みます。ネイティブセッション参照が保存されていない場合、このフィールドは省略されます。 これらのコマンドは、ペインを制御しているフォアグラウンドプロセスの cwd を解決できる場合に `foreground_cwd` を含みます。既存の `cwd` フィールドは、ラベルと follow-cwd 挙動に使われるペイン/ワークスペースの cwd のままです。 @@ -351,7 +355,7 @@ herdr terminal title clear ``` ダイレクトアタッチからは `ctrl+b q` でデタッチします。リテラルの `ctrl+b` は `ctrl+b ctrl+b` で送ります。 -`terminal session control` は、ペイン、ターミナル、エージェントを対象に書き込み可能なライブストリームを開きます。observe と同じ改行区切り JSON の `terminal.frame` と `terminal.closed` を出力し、標準入力から `terminal.input`、`terminal.resize`、`terminal.scroll`、`terminal.release` を受け取ります。制御クライアントは同時に 1 つだけで、`--takeover` で置き換えられます。 +`terminal session control` は、ペイン、ターミナル、エージェントを対象に書き込み可能なライブストリームを開きます。observe と同じ改行区切り JSON の `terminal.frame` と `terminal.closed` を出力し、標準入力から `terminal.input`、`terminal.resize`、`terminal.scroll`、`terminal.mouse`、`terminal.release` を受け取ります。制御クライアントは同時に 1 つだけで、`--takeover` で置き換えられます。`terminal.mouse` は 0 始まりのセル位置にマウスイベントを 1 つ送ります(例: `{"type":"terminal.mouse","action":"down","button":"left","column":12,"row":5}`)。`action` は `down`、`up`、`drag`、`move` のいずれかで、`button` は `left`(既定)、`right`、`middle`、`modifiers` は省略可能で Shift = 1、Ctrl = 2、Alt = 4 の組み合わせです(既定 0)。クリックは `down` の後に `up` を送ります。Herdr はアプリのマウスモードに合わせてエンコードし、マウス報告を有効にしていないアプリには送らないため、通常のシェルに余計な入力が届くことはありません。`move` はすべてのマウス移動を追跡するアプリにのみ届きます。 `terminal session observe` は同じ対象の読み取り専用ストリームを開きます。base64 の ANSI バイト列を含む `terminal.frame` と、サーバー終了時の `terminal.closed` を改行区切り JSON で出力します。複数の観測クライアントは入力、リサイズ、スクロール、制御権を取得せずに同じターミナルを監視できます。Linux/macOS ではソケットへの書き込みが 30 秒間進まない観測クライアントを切断します。その場合は最後の `terminal.closed` が届かないことがありますが、ペインや他のクライアントは動き続けます。出力のない静かなペインはこのタイムアウトの対象ではありません。 diff --git a/docs/preview/website/src/content/docs/ja/configuration.mdx b/docs/preview/website/src/content/docs/ja/configuration.mdx index 12802e84..65b683f8 100644 --- a/docs/preview/website/src/content/docs/ja/configuration.mdx +++ b/docs/preview/website/src/content/docs/ja/configuration.mdx @@ -528,8 +528,11 @@ Herdr はデフォルトで、サーバーの再起動後に対応する Agent ã ```toml [session] resume_agents_on_restore = true +startup_per_agent_delay_ms = 100 ``` +起動時の競合を減らすため、自動復元ではデフォルトで 100 ミリ秒間隔でエージェントを 1 つずつ起動します。起動条件を満たした最初のエージェントはすぐに起動します。`startup_per_agent_delay_ms = 0` で間隔を無効にできます。手動起動と明示的なターミナルへの接続には影響しません。変更を適用するには Herdr サーバーを再起動してください。 + 公式インテグレーションからの有効なネイティブセッション参照を持つペインだけが再開できます。その他のペインは通常のシェルとして復元されます。対応する Agent と永続化の挙動については、[セッション状態と復元](/docs/session-state/)を参照してください。 ## IME カーソルトラッキング diff --git a/docs/preview/website/src/content/docs/ja/connecting-machines.mdx b/docs/preview/website/src/content/docs/ja/connecting-machines.mdx index 2c3a41cc..ef8bb5bc 100644 --- a/docs/preview/website/src/content/docs/ja/connecting-machines.mdx +++ b/docs/preview/website/src/content/docs/ja/connecting-machines.mdx @@ -7,6 +7,12 @@ description: Local と保存済み SSH マシンを 1 つの Herdr ウィンドã 各マシンは独自の Herdr サーバー、セッション、プロセスを保持します。1 台への接続が切れても、ほかの接続は切れません。 +### SSH 認証の復旧 + +Linux と macOS で `remote.manage_ssh_config=true` の場合、マシン追加、サイドバー、API 操作は承認済み OpenSSH 接続を共有します。`herdr machine status [<label-or-id>] [--json]` は認証を求めず、現在の接続状態を確認します。**reachable** はリモート Herdr が利用可能という意味で、各 TUI の接続状態ではありません。ターミナルで `herdr machine reconnect <label-or-id>` を実行すると、SSH 認証後に保存済みマシンを検証します。インストールや更新は行いません。開いているクライアントは 30 秒以内に再試行し、再起動は不要です。**`! auth`**、**`! error`**、失敗後の再接続ステータスをクリックすると、最新のエラーと CLI コマンドが通知に表示されます。認証ポップアップは開きません。マシン行の展開・折りたたみは変更されません。 + +共有接続の `ControlPersist 600` はアイドル状態の 10 分を表すもので、MFA の有効期間ではありません。通信中の接続は維持されますが、企業ポリシー、SSH サーバー、ネットワークによってはそれより早く終了します。ローカル Windows の復旧はまだ対応していません。管理対象外の SSH 接続の認証は利用者の責任です。共有 ControlPath を使わずに `ssh` を実行するだけでは、Herdr の承認にはなりません。ホスト鍵の検証は緩和されず、未知または変更されたホスト鍵は引き続き **Attention** です。 + ## 接続前の確認 リモートマシンへの通常の SSH アクセスが必要です。最初に確認してください: @@ -74,18 +80,18 @@ herdr machine remove <profile-id> ## 接続の問題 - **Reconnecting:** ネットワーク中断、スリープ、SSH 障害の後は自動で再試行します。失敗が続くと待機間隔は最大 2 分まで延び、短時間だけ接続に成功してもリセットされません。1 分間安定して接続できると、次の中断では再び短い間隔で再試行します。SSH 接続はアプリケーションの通信を監視し、通信がない間はヘルスチェックを行うため、切れた接続が Online のままになりません。Local はリモート用のプローブではなく、ネイティブ接続の終了や失敗を検知します。 -- **Attention:** ホスト鍵の承認、認証、互換サーバーの準備など、バックグラウンドではできない操作が必要です。ほかのマシンは利用できます。 +- **Attention:** 認証、ホスト鍵の承認、互換サーバーの準備などが必要です。ほかのマシンは利用できます。**`! auth`** は認証失敗、**`! error`** は別の問題を示します。バッジをクリックするとエラーと CLI コマンドを表示します。折りたたみ時はどちらも `!` です。 - **保存済みマシンのファイルエラー:** カタログを読み取れない、または内容が不正な場合、現在の接続は変更しません。通知を表示して自動で読み取りを再試行します。 両端のインストールがブリッジのアイドル終了に対応している場合、Linux と macOS への保存済みマシン接続は、どちらの方向にも通信がない状態が 1 分続くとリモートブリッジを終了します。スリープ時間も含み、復帰時に期限を確認します。正常なアイドル接続ではヘルスチェックを交換するため、継続的な出力を見るためにキーを入力する必要はありません。ブリッジ終了後もリモートサーバー、セッション、ペインのプロセスは動き続けます。古いインストールとは、この追加機能なしで接続できます。 -バックグラウンド接続がプロンプトに回答したり、サーバーのインストール、更新、再起動、ハンドオフを行ったりすることはありません。Attention の場合は、Herdr が表示する単独接続用のコマンドを対話型ターミナルで実行してください。例: +バックグラウンド接続がプロンプトに回答したり、サーバーのインストール、更新、再起動、ハンドオフを行ったりすることはありません。認証以外の Attention の場合は、Herdr が表示する単独接続用のコマンドを対話型ターミナルで実行してください。例: ```bash herdr --remote workbox ``` -プロファイルの接続先を使います。追加時に名前付きセッションを選んだ場合だけ、`--session <name>` も指定します。必要な確認に回答したら、クライアントを再起動して Attention の接続を再試行してください。バージョンが違うという理由だけで実行中サーバーを止めないでください。 +プロファイルの接続先を使います。名前付きセッションを選んだ場合だけ `--session <name>` も指定します。セットアップ後、開いているクライアントは自動的に再試行します。`machine reconnect` は Herdr をインストール・更新しません。バージョンが違うという理由だけで実行中サーバーを止めないでください。 認証に失敗したら、まず通常の SSH を確認します。パスフレーズ付きの鍵は、非対話型のバックグラウンド接続を始める前に `ssh-add` で読み込んでください。 diff --git a/docs/preview/website/src/content/docs/ja/integrations.mdx b/docs/preview/website/src/content/docs/ja/integrations.mdx index 6086e6b6..126ba824 100644 --- a/docs/preview/website/src/content/docs/ja/integrations.mdx +++ b/docs/preview/website/src/content/docs/ja/integrations.mdx @@ -68,37 +68,14 @@ Herdr はインテグレーションを 2 つの異なる方法で使います: カスタムインテグレーションも、ネイティブのターミナル UI では見えない状態を定義する場合に状態を報告できます。Herdr への組み込みや、認識済みのエージェント実行ファイルは必要ありません。 -## 独自エージェントを統合する - -Herdr ペイン内で動くエージェントは、`HERDR_ENV`、`HERDR_PANE_ID`、`HERDR_BIN_PATH`、`HERDR_SOCKET_PATH` を継承します。エージェントがライフサイクルフックを提供している場合は、そのフックから Herdr の CLI を使ってセマンティックな状態を報告します: - -```bash -"$HERDR_BIN_PATH" pane report-agent "$HERDR_PANE_ID" \ - --source custom:my-agent \ - --agent my-agent \ - --state working -``` - -エージェントが入力待ちになったら `idle`、ユーザーの判断が必要になったら `blocked` を報告します。ブロックの説明には `--message` を使います。エージェントの終了時には、同じ source のライフサイクル権威を解放します: - -```bash -"$HERDR_BIN_PATH" pane release-agent "$HERDR_PANE_ID" \ - --source custom:my-agent \ - --agent my-agent -``` - -Herdr の外では何もしないように、`HERDR_ENV=1` で必要な変数が存在するときだけ報告してください。`--source` はインテグレーションごとに一意かつ固定にします。報告が順不同で届く可能性がある場合は、単調増加する `--seq` を含めてください。Herdr は同じ source から届いた古いシーケンス番号を無視します。 - -`report-agent` に `--agent-session-id` または `--agent-session-path` を含めることも、セッション識別が状態とは独立して変わる場合に `pane report-agent-session` を使うこともできます。Herdr はその参照をペイン API とエージェント API で公開します。セッションの自動復元には、それに加えて、そのエージェントの起動方法と参照先セッションの再開方法を Herdr が把握している必要があります。 - -移植可能なインテグレーションには `HERDR_BIN_PATH` と CLI ラッパーを使ってください。直接 IPC が必要なコードでは、[Socket API](/ja/docs/socket-api/) に記載された同等の `pane.report_agent`、`pane.report_agent_session`、`pane.release_agent` リクエストを送信できます。 - -[Prime Agent の組み込み Herdr レポーター](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/core/extensions/builtin/herdr-agent-state.ts)は実際の実装例です。Herdr 内でのみ有効になり、エージェントイベントを `working`、`idle`、`blocked` に対応付け、セッションをまたいで報告順序を維持し、終了時に権威を解放します。 - 一部のインテグレーションは、エージェントのネイティブセッション参照を報告します。Herdr は公式のセッション参照を使って、`[session] resume_agents_on_restore = false` で無効化されていない限り、Herdr サーバーの再起動後に Claude Code、Codex、Devin CLI、Droid、Kimi Code CLI、Qoder CLI、Qwen Code、Letta Code、Cursor Agent CLI、Grok CLI、GitHub Copilot CLI、Pi、OMP、Hermes Agent、OpenCode、Kilo Code CLI、MastraCode、Antigravity CLI のペインを resume します。 エージェントネイティブのセッション復元には最新の Herdr インテグレーションが必要です: Pi インテグレーションはバージョン `2`、OMP は `3`、Claude Code は `6`、Codex は `5`、GitHub Copilot CLI は `2`、Devin CLI は `2`、Droid は `2`、Kimi Code CLI は `3`、Qoder CLI は `2`、Qwen Code は `1`、Letta Code は `1`、Cursor Agent CLI は `1`、Grok CLI は `2`、OpenCode は `5`、Kilo Code CLI は `1`、Hermes Agent は `5`、MastraCode は `1`、Antigravity CLI は `1` です。インストール済みバージョンは `herdr integration status` で確認してください。 +## 独自エージェントを統合する + +コーディングエージェントを開発している場合は、Herdr にネイティブサポートを追加せずに、自分のコードからエージェントの状態と resume コマンドを Herdr に報告できます。[エージェントに Herdr 対応を追加する](/ja/docs/add-herdr-support/)を参照してください。 + ## Pi Pi インテグレーションをインストールします: @@ -229,6 +206,10 @@ herdr integration install opencode V2 のライフサイクル報告はペイン内の TUI で実行され、複数のペインが同じ OpenCode サーバーを共有する場合も、選択されたルートセッションにイベントを対応付けます。完了時または中断時に working 状態を解除し、未処理の権限要求やフォーム、実行失敗は blocked 状態を維持します。V2 Mini とヘッドレスクライアントは TUI プラグインを実行しないため、このライフサイクル報告は利用できません。 +V1 TUI はペインで選択したセッションとその子孫を追跡します。いずれかが実行中・再試行中なら working、権限要求や質問が未処理なら blocked を維持します。接続時に既存の状態を読み込み、キャンセル済みツールの要求が再接続後に blocked を復活させることはありません。サブエージェントの閲覧では元のセッション群を維持し、子セッションへ直接接続した場合は兄弟ではなくその子孫だけを追跡します。 + +ローカル V1 の `opencode run` と `opencode --mini` は従来のサーバーフックを維持します。この変更は Mini やヘッドレスクライアントにペイン固有のライフサイクル報告を追加するものではありません。連携の更新後は TUI と共有 OpenCode サーバーの両方を再起動し、古いサーバー報告がペインの状態を上書きしないようにしてください。 + このプラグインは、OpenCode が Herdr のペイン内で動いている間、ライフサイクル状態とセッション識別を報告します。OpenCode がセッション情報を含むイベントを発行した後、Herdr は報告されたセッション id を使って `opencode --session <id>` でペインを resume できます。プラグインがインストールされていないときは、スクリーンマニフェスト検出が引き続き利用できます。 ## Kilo Code CLI diff --git a/docs/preview/website/src/content/docs/ja/persistence-remote.mdx b/docs/preview/website/src/content/docs/ja/persistence-remote.mdx index 94bffb8b..ae695ab3 100644 --- a/docs/preview/website/src/content/docs/ja/persistence-remote.mdx +++ b/docs/preview/website/src/content/docs/ja/persistence-remote.mdx @@ -148,4 +148,4 @@ base64 の ANSI データを含む `terminal.frame` を改行区切り JSON でå herdr terminal session control w1:p1 --takeover --cols 120 --rows 40 ``` -同じフレームを出力し、標準入力から改行区切り JSON コマンドを読み取ります。`terminal.input` はテキストまたは base64 データ、`terminal.resize` は表示サイズ、`terminal.scroll` はビューポートのスクロール、`terminal.release` はコントローラーの終了を扱います。入力とリサイズを所有できるコントローラーは 1 つだけです。 +同じフレームを出力し、標準入力から改行区切り JSON コマンドを読み取ります。`terminal.input` はテキストまたは base64 データ、`terminal.resize` は表示サイズ、`terminal.scroll` はビューポートのスクロール、`terminal.mouse` はマウス報告を有効にしたアプリへのセル位置のマウスイベント、`terminal.release` はコントローラーの終了を扱います。入力とリサイズを所有できるコントローラーは 1 つだけです。 diff --git a/docs/preview/website/src/content/docs/ja/session-state.mdx b/docs/preview/website/src/content/docs/ja/session-state.mdx index 4f16bda6..a66d6a92 100644 --- a/docs/preview/website/src/content/docs/ja/session-state.mdx +++ b/docs/preview/website/src/content/docs/ja/session-state.mdx @@ -83,7 +83,7 @@ pane_history = true resume_agents_on_restore = false ``` -Herdr が resume するのは、現行の公式 Herdr インテグレーションを通じてネイティブセッション参照を報告したペインだけです。 +Herdr が resume するのは、現行の公式 Herdr インテグレーションを通じてネイティブセッション参照を報告したペインと、エージェント自身が resume コマンドを報告したペインです。[エージェントに Herdr 対応を追加する](/ja/docs/add-herdr-support/)を参照してください。 クライアントがアタッチしてターミナルサイズとテーマのコンテキストを提供すると、Herdr は各ペインがフォーカスされるのを待たずに、ワークスペースとタブをまたいで復元対象のエージェントペインを resume します。 diff --git a/docs/preview/website/src/content/docs/ja/socket-api.mdx b/docs/preview/website/src/content/docs/ja/socket-api.mdx index 09532d5e..361f5222 100644 --- a/docs/preview/website/src/content/docs/ja/socket-api.mdx +++ b/docs/preview/website/src/content/docs/ja/socket-api.mdx @@ -99,7 +99,7 @@ herdr pane read w1:p2 --source recent --lines 50 | ワークスペース | `workspace.create`、`workspace.list`、`workspace.get`、`workspace.focus`、`workspace.rename`、`workspace.move`、`workspace.move_block`、`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.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` | +| ペイン | `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` | | ポップアップ | `popup.close` | | レイアウト | `layout.export`、`layout.apply`、`layout.set_split_ratio` | | エージェント | `agent.list`、`agent.get`、`agent.read`、`agent.explain`、`agent.send_keys`、`agent.prompt`、`agent.wait`、`agent.rename`、`agent.focus`、`agent.start` | @@ -147,20 +147,9 @@ CLI の `herdr api snapshot` は、クライアントやエージェントが簡 ### ペイングラフィックス -ペイングラフィックスを使うと、プラグインがペイン上に画像データを配置できます。デフォルトで利用でき、サーバーで `[terminal].kitty_graphics = false` が設定されている場合は、すべてのペイングラフィックスメソッドが `feature_disabled` を返します。この設定の変更にはサーバーの再起動が必要です。`pane.graphics.info` はグラフィックスレイヤーを作成せず、接続中クライアントのセルの幅と高さをピクセル単位で返します。`pane.graphics.set` は `data_base64` の `png`、`rgb`、`rgba` データを受け取り、`pane.graphics.clear` はレイヤーを削除します。 +アプリケーションとプラグインは、ペインのターミナル出力を通じて標準の Kitty グラフィックスプロトコルを送信してください。Herdr が対応する外側ターミナルで画像の配置、クリッピング、表示状態を管理します。 -```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}} -``` +外部ソケットのペイン画像オーバーレイ API は削除されました。`pane.graphics.info`、`pane.graphics.set`、`pane.graphics.clear`、`pane.graphics.stream` は利用できず、代替のソケット画像 API もありません。旧サーバーとの内部通信プロトコルの互換性は、これらの公開メソッドを復活させるものではありません。 `pane.layout` は、`workspace_id`、`tab_id`、`zoomed`、外側の `area`、`focused_pane_id`、ペインの矩形、分割の矩形/比率を含むタブレイアウトのスナップショットを返します。`pane.neighbor` と `pane.edges` は同じレイアウトスナップショットを含むので、クライアントは非公開のレイアウト状態なしに次の判断を下せます。 @@ -556,6 +545,22 @@ Herdr はローカルソケット上の改行区切り JSON を使います。Un } ``` +どちらのメソッドも、Herdr サーバーの再起動後に報告元の現在のセッションを再開するコマンドを、省略可能な `resume_argv` 配列で受け付けます。最初の要素はパスではなく単純なコマンド名でなければならず、どの要素にもアポストロフィを含めることはできません。無効な値は `invalid_resume_argv` で失敗し、その報告は適用されません。カスタムエージェントは、コマンドを付ける前に `pane.report_agent` でペインを保持している必要があり、そうでない場合は `resume_not_accepted` で失敗します。Herdr は同じ `source` と `agent` がペインを保持している間だけコマンドを保持し、そのエージェントに対する Herdr 組み込みの resume コマンドより優先します。古い Herdr はこのフィールドを無視します。 + +```json +{ + "id": "req_3", + "method": "pane.report_agent_session", + "params": { + "pane_id": "w1:p1", + "source": "custom:my-agent", + "agent": "my-agent", + "agent_session_id": "...", + "resume_argv": ["my-agent", "--resume", "..."] + } +} +``` + Herdr に保存されたネイティブセッション参照があるとき、`pane.get`、`pane.list`、`agent.get`、`agent.list` は読み取り専用の `agent_session` オブジェクトを公開します: ```json diff --git a/docs/preview/website/src/content/docs/persistence-remote.mdx b/docs/preview/website/src/content/docs/persistence-remote.mdx index 4f42cef5..0ffa1406 100644 --- a/docs/preview/website/src/content/docs/persistence-remote.mdx +++ b/docs/preview/website/src/content/docs/persistence-remote.mdx @@ -155,5 +155,6 @@ herdr terminal session control w1:p1 --takeover --cols 120 --rows 40 Control mode prints the same newline-delimited frame records and reads newline-delimited JSON commands on stdin. `terminal.input` sends text or base64 bytes, `terminal.resize` changes the controller viewport, -`terminal.scroll` scrolls the attached viewport, and `terminal.release` closes -the controller. Only one controller owns input and resize at a time. +`terminal.scroll` scrolls the attached viewport, `terminal.mouse` sends a mouse +event at a cell to applications that enabled mouse reporting, and +`terminal.release` closes the controller. Only one controller owns input and resize at a time. diff --git a/docs/preview/website/src/content/docs/session-state.mdx b/docs/preview/website/src/content/docs/session-state.mdx index b8706cd5..69bff955 100644 --- a/docs/preview/website/src/content/docs/session-state.mdx +++ b/docs/preview/website/src/content/docs/session-state.mdx @@ -81,7 +81,7 @@ Native agent session restore is enabled by default. Disable it with: resume_agents_on_restore = false ``` -Herdr only resumes panes that reported a native session reference through a current official Herdr integration. +Herdr resumes panes that reported a native session reference through a current official Herdr integration, and panes whose agent reported its own resume command. See [Add Herdr support to your agent](/docs/add-herdr-support/). After a client attaches and provides terminal size and theme context, Herdr resumes eligible restored agent panes across workspaces and tabs without waiting for each pane to be focused. diff --git a/docs/preview/website/src/content/docs/socket-api.mdx b/docs/preview/website/src/content/docs/socket-api.mdx index e6ae6a57..9e844d7e 100644 --- a/docs/preview/website/src/content/docs/socket-api.mdx +++ b/docs/preview/website/src/content/docs/socket-api.mdx @@ -103,7 +103,7 @@ Raw socket method names use dot notation: | Workspace | `workspace.create`, `workspace.list`, `workspace.get`, `workspace.focus`, `workspace.rename`, `workspace.move`, `workspace.move_block`, `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.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` | +| 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` | | Popup | `popup.close` | | Layout | `layout.export`, `layout.apply`, `layout.set_split_ratio` | | Agent | `agent.list`, `agent.get`, `agent.read`, `agent.explain`, `agent.send_keys`, `agent.prompt`, `agent.wait`, `agent.rename`, `agent.focus`, `agent.start`, `agent.view.set`, `agent.view.clear` | @@ -176,63 +176,14 @@ Clients can treat `offset_from_bottom == 0` as at-bottom state. ### Pane graphics -Pane graphics let a plugin place image data over a pane. They are available by -default; when the server has `[terminal].kitty_graphics = false`, every pane -graphics method returns `feature_disabled`. Changing this setting requires a -server restart. Calling `pane.graphics.info` explicitly -activates capability discovery and returns the attached client's cell size, -file-frame options, pixel-mouse support, the 16-layer limit, and `pane_visible`. -`pane_visible` is true only when the target is in the active workspace and tab -and is not hidden by zoom. Short-lived UI modes do not change it. - -`pane.graphics.set`, `pane.graphics.clear`, and `pane.graphics.stream` accept an -optional `layer_id` (default `primary`). Set and stream also accept `z_index`; -layers are placed in stable `(z_index, layer_id)` order. Each stream exclusively owns its layer, and -closing it removes that layer. Inline frames accept `png`, `rgb`, `rgba`, or -`bgra`; BGRA is normalized once to owned RGBA. Herdr advances the host cache -one image transaction per render pass, so arbitrary layer sets progress without -an aggregate frame. Client transport keeps each transaction within its 32 MiB -wire limit. - -```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 inline frame. Concurrent operations on that layer return -`stream_conflict`. - -```json -{"id":"graphics_stream","method":"pane.graphics.stream","params":{"pane_id":"w1:p1","z_index":0}} -{"format":"png","image_width":800,"image_height":600,"data_length":12345,"placement":{"viewport_col":0,"viewport_row":0,"grid_cols":80,"grid_rows":30}} -``` - -When `pane.graphics.info` advertises `file_frame_transport: "direct-kitty"`, an -eligible local Ghostty, kitty, or WezTerm client may submit an immutable private -`rgba` or `bgra` file with `file.path`, `sequence`, and `revision`. Direct Kitty -file transport is reserved for the default `primary` page layer; named secondary -layers use owned inline RGBA. BGRA is always copied, swizzled, and rendered -inline. Herdr replies with a `pane_graphics_frame_ack` only after the terminal -accepts the file, or after a safe owned inline fallback is installed. Confirmed -file-transport failure disables direct files for that client connection without -disabling exact pixel mouse. A timeout or client loss closes the stream without -acknowledging source reuse. Clients that cannot negotiate direct file transport -remain on the owned inline fallback. - -Direct files are always complete canonical `width * height * 4` RGBA frames. -`file_frame_max_bytes` is the limit that remains eligible for owned inline fallback. -Primary-layer RGBA files may use the larger `file_frame_direct_max_bytes` limit when -`file_frame_transport` is available. Frames above the fallback limit are acknowledged -only when the terminal accepts the direct transfer; rejection closes the stream. If a -frame cannot use owned inline fallback while its pane is temporarily hidden or cannot be -placed during a redraw, Herdr uploads the image without displaying it and replays its -placement when the pane becomes visible again. -`file_frame_damage: true` means Herdr accepts optional damage metadata for -producer-side canonical-ring efficiency; it still copies or presents the full file. -Resize and full redraw replay placements without retransmitting pixels. +Applications and plugins should emit the standard Kitty graphics protocol through +their pane's terminal output. Herdr manages image placement, clipping, and +visibility in compatible outer terminals. + +The external socket pane-overlay API has been removed: `pane.graphics.info`, +`pane.graphics.set`, `pane.graphics.clear`, and `pane.graphics.stream` are no +longer available. There is no replacement socket image API. Internal wire +compatibility with older servers does not restore these public methods. `pane.layout` returns the tab layout snapshot with `workspace_id`, `tab_id`, `zoomed`, outer `area`, `focused_pane_id`, pane rects, and split rects/ratios. @@ -736,6 +687,22 @@ Session-only official integrations report native session references with `pane.r } ``` +Both methods accept an optional `resume_argv` array with the command that resumes the reporter's current session after a Herdr server restart. Its first element must be a plain command name, not a path, and no element may contain an apostrophe; invalid values fail with `invalid_resume_argv` and the report is not applied. A custom agent must hold the pane through `pane.report_agent` before it can attach a command; otherwise the request fails with `resume_not_accepted`. Herdr keeps the command only while the same `source` and `agent` hold the pane, and it takes precedence over Herdr's built-in resume command for that agent. Older Herdr versions ignore the field. + +```json +{ + "id": "req_3", + "method": "pane.report_agent_session", + "params": { + "pane_id": "w1:p1", + "source": "custom:my-agent", + "agent": "my-agent", + "agent_session_id": "...", + "resume_argv": ["my-agent", "--resume", "..."] + } +} +``` + `pane.get`, `pane.list`, `agent.get`, and `agent.list` expose a read-only `agent_session` object when Herdr has a stored native session reference: ```json diff --git a/docs/preview/website/src/content/docs/zh-cn/add-herdr-support.mdx b/docs/preview/website/src/content/docs/zh-cn/add-herdr-support.mdx new file mode 100644 index 00000000..827fd233 --- /dev/null +++ b/docs/preview/website/src/content/docs/zh-cn/add-herdr-support.mdx @@ -0,0 +1,117 @@ +--- +title: 为你的智能体添加 Herdr 支持 +description: 在不为 Herdr 添加原生支持的情况下,从你自己的代码向 Herdr 上报编码智能体的状态和恢复命令。 +--- + +如果你在开发编码智能体,只靠你自己的代码就能让它在 Herdr 中获得一等支持。不需要向 Herdr 提交拉取请求,也不需要等待 Herdr 发布新版本。 + +智能体向 Herdr 上报后,用户会得到: + +- 在侧边栏和 `herdr agent list` 中显示的智能体名称以及 `idle`、`working` 或 `blocked` 状态 +- 智能体完成或需要用户决策时的通知 +- `herdr agent wait` 以及其他等待智能体状态的自动化 +- Herdr 服务器重启后,同一个窗格中恢复同一个会话 + +对于厂商没有提供集成的智能体,由 Herdr 维护集成。如果你维护自己的智能体,自己掌握集成就可以按自己的发布节奏修复问题。 + +## 工作方式 + +Herdr 窗格中的每个进程都会继承这些环境变量: + +| 变量 | 含义 | +| --- | --- | +| `HERDR_ENV` | 在 Herdr 中为 `1` | +| `HERDR_PANE_ID` | 智能体所在的窗格 | +| `HERDR_BIN_PATH` | 管理这个窗格的 Herdr 可执行文件 | +| `HERDR_SOCKET_PATH` | Herdr 的 API 套接字 | + +你的智能体通过 `"$HERDR_BIN_PATH"` 发送三类上报: + +1. **状态。** 每当 `idle`、`working` 或 `blocked` 发生变化时上报。 +2. **恢复命令。** 上报重新打开当前会话的命令。 +3. **释放。** 智能体退出时释放窗格。 + +仅在 `HERDR_ENV=1` 且其他变量都存在时上报。在 Herdr 之外,集成不应执行任何操作。 + +## 上报状态 + +```bash +"$HERDR_BIN_PATH" pane report-agent "$HERDR_PANE_ID" \ + --source my-agent \ + --agent my-agent \ + --state working \ + --seq 1 +``` + +- 一轮开始时上报 `working`,可以接收输入时上报 `idle`,需要用户做决定时上报 `blocked`。可以用 `--message` 说明阻塞原因。 +- `--agent` 是用户看到的名称。请使用你自己智能体的名称,不要使用 Herdr 已经支持的智能体的名称。 +- `--source` 用于标识你的集成。保持稳定且唯一。不要以 `herdr:` 开头,这个前缀由 Herdr 自己的集成使用。 +- `--seq` 可以省略,但建议加上。它必须随来自你的来源的每次上报递增,跨会话和智能体重启也要继续递增。时间戳就很合适。Herdr 会忽略编号不大于上次已接受编号的上报,所以迟到或乱序的上报不会覆盖更新的状态。 + +## 上报恢复命令 + +把恢复当前会话的命令放在 `--` 之后。带上该会话需要的选项,例如模型或权限模式,这样恢复后的会话行为一致: + +```bash +"$HERDR_BIN_PATH" pane report-agent "$HERDR_PANE_ID" \ + --source my-agent \ + --agent my-agent \ + --state idle \ + --seq 2 \ + --agent-session-id "$SESSION_ID" \ + -- my-agent --resume "$SESSION_ID" --model my-model +``` + +命令可以附在任何一次状态上报中,只有会话变化时也可以用 `pane report-agent-session` 发送。每当智能体切换会话时,请重新上报。 + +Herdr 服务器重启后,Herdr 会在同一目录中打开该窗格并在其中运行这条命令。命令必须遵守以下规则: + +- 第一个词是用户 `PATH` 上的普通命令名,例如 `my-agent`,不能是路径。 +- 任何参数都不能包含撇号。 +- 你的来源必须先持有该窗格,所以请在发送命令之前或同时用 `report-agent` 上报状态。否则 Herdr 会返回 `resume_not_accepted`。 + +违反前两条规则的命令会被 Herdr 以 `invalid_resume_argv` 拒绝,该次上报也不会生效。用户可以用 `[session] resume_agents_on_restore = false` 关闭恢复。 + +## 退出时释放 + +```bash +"$HERDR_BIN_PATH" pane release-agent "$HERDR_PANE_ID" \ + --source my-agent \ + --agent my-agent \ + --seq 3 +``` + +释放会立即从窗格中清除智能体的名称、状态和恢复命令。只在用户真正退出时释放。如果智能体在同一个进程中用一个会话替换另一个会话,请上报新会话,而不是释放。 + +如果智能体退出时没有释放,Herdr 会在窗格回到空闲的 shell 提示符后察觉,并清除该智能体及其恢复命令。通常需要一两秒。这只是兜底机制,不能代替释放。 + +## 不要拖慢智能体 + +- 不要让 Herdr 拖慢你的智能体。在后台或用较短的超时发送上报,并忽略失败。 +- 只发送最新状态。如果一次上报正在发送时积累了多个变化,丢弃较旧的那些。 +- 旧版 Herdr 会忽略恢复命令,其他功能照常工作。 + +## 直接使用套接字 + +`HERDR_BIN_PATH` 和 CLI 是可移植的选择,包括在 Windows 上。如果你的智能体需要直接 IPC,可以发送 [Socket API](/zh-cn/docs/socket-api/) 中说明的等效 `pane.report_agent`、`pane.report_agent_session` 和 `pane.release_agent` 请求。恢复命令放在 `resume_argv` 数组中。 + +## 检查你的集成 + +在 Herdr 窗格中启动你的智能体,然后查看 Herdr 看到了什么: + +```bash +herdr pane get "$HERDR_PANE_ID" +herdr agent list +``` + +要在不影响日常会话的情况下测试恢复,请使用单独的命名会话: + +1. 启动 `herdr --session my-agent-test`,然后在一个窗格中运行你的智能体。 +2. 用 `herdr session stop my-agent-test` 停止该会话。 +3. 再次启动 `herdr --session my-agent-test`。窗格应当运行你的恢复命令,智能体应当再次上报。 + +## 示例 + +[Prime Agent 内置的 Herdr 上报器](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/core/extensions/builtin/herdr-agent-state.ts)是一个真实的集成。它只在 Herdr 中启用,将智能体事件映射为 `working`、`idle` 和 `blocked`,跨会话保持上报顺序,并在退出时释放窗格。 + +如果想在不改变状态的情况下改变智能体的显示方式,例如标题或自定义状态文字,请参阅[自定义状态标签](/zh-cn/docs/integrations/#自定义状态标签)。 diff --git a/docs/preview/website/src/content/docs/zh-cn/agents.mdx b/docs/preview/website/src/content/docs/zh-cn/agents.mdx index bc749add..13ec4998 100644 --- a/docs/preview/website/src/content/docs/zh-cn/agents.mdx +++ b/docs/preview/website/src/content/docs/zh-cn/agents.mdx @@ -89,6 +89,14 @@ herdr agent explain --file screen.txt --agent codex --json Herdr 可以在 tmux 作为外层终端环境时运行。智能体检测不会检查在 Herdr 窗格内启动的 tmux 会话。如果某个 shell 框架在 Herdr 内自动进入 tmux,Herdr 看到的窗格进程就是 `tmux`,而不是它背后的智能体。 +如果你的 shell 在 `TMUX` 未设置时自动连接 tmux,请更新 shell 启动条件以排除 Herdr 窗格。从 Herdr 窗格内重新连接外层 tmux 会话可能导致终端尺寸递归缩小、画面闪烁。在现有条件中加入 `HERDR_ENV` 检查,并确保它在运行 tmux 之前生效: + +```zsh +if [[ -z ${TMUX:-} && ${HERDR_ENV:-} != 1 ]]; then + tmux new-session -A -s my-session +fi +``` + ## 状态汇总 侧边栏会把状态向上汇总。 @@ -106,7 +114,7 @@ herdr integration install claude herdr integration status ``` -每个受支持的智能体都有自己的集成名称和行为。按智能体的细节和完整安装列表见[集成](/zh-cn/docs/integrations/)。如果你正在构建智能体,[自定义集成指南](/zh-cn/docs/integrations/#集成你自己的智能体)介绍了如何在不为 Herdr 添加原生支持的情况下上报生命周期状态。 +每个受支持的智能体都有自己的集成名称和行为。按智能体的细节和完整安装列表见[集成](/zh-cn/docs/integrations/)。如果你正在构建智能体,[为你的智能体添加 Herdr 支持](/zh-cn/docs/add-herdr-support/)介绍了如何在不为 Herdr 添加原生支持的情况下上报生命周期状态和恢复命令。 ## 自定义智能体标签 diff --git a/docs/preview/website/src/content/docs/zh-cn/cli-reference.mdx b/docs/preview/website/src/content/docs/zh-cn/cli-reference.mdx index 011efbd3..ae5c3ab4 100644 --- a/docs/preview/website/src/content/docs/zh-cn/cli-reference.mdx +++ b/docs/preview/website/src/content/docs/zh-cn/cli-reference.mdx @@ -62,7 +62,7 @@ herdr machine remove <profile-id> 更改会自动应用到已打开的本地 Herdr 客户端,通常在一秒内生效。新增或启用的机器在后台连接;重命名不会重新连接。移除或禁用只会断开该机器,远程会话仍会继续运行。移除正在查看的机器会返回 Local;如果 Local 不可用,则显示不可用状态,直到重新连接。每份配置在客户端状态文件中保存一个不透明 ID、标签、SSH 目标、明确的远程会话名和启用状态。Herdr 不保存密码、私钥或其他 SSH 凭据。 -自动连接和重连均为非交互式。如果主机密钥、密码、密钥口令、MFA、安装、更新或重启需要批准,机器会显示 Attention,而不会打开隐藏的提示。请运行 Herdr 显示的独立连接命令,例如 `herdr --remote workbox`,在前台完成设置后重启客户端。仅当配置指向命名会话时,才加上 `--session <name>`。 +`herdr machine status [<label-or-id>] [--json]` 可非交互式检查 SSH 和远程 Herdr。`reachable` 表示本次检查成功,不代表 TUI 当前已连接。在终端运行 `herdr machine reconnect <label-or-id>` 可认证并验证连接,不会安装或更新 Herdr。已打开的客户端会在 30 秒内重试。点击 `! auth` 或 `! error` 可查看最新错误和 CLI 命令;侧边栏折叠时显示 `!`。平台限制请参阅[恢复 SSH 认证](/zh-cn/docs/connecting-machines/#恢复-ssh-认证)。需要远程设置时使用 `herdr --remote workbox`,仅在命名会话时添加 `--session <name>`。 工作区、标签页、窗格 ID 和智能体名称仅在所属服务器内有效。UI 中的选择不会改变 CLI 的目标。使用全局**前缀** `--machine <label-or-id>` 将 API 命令发送到已保存的 SSH 机器: @@ -258,7 +258,8 @@ herdr pane report-agent <pane_id> \ [--message TEXT] \ [--seq N] \ [--agent-session-id ID] \ - [--agent-session-path PATH] + [--agent-session-path PATH] \ + [-- RESUME_COMMAND...] herdr pane report-agent-session <pane_id> \ --source ID \ @@ -266,7 +267,8 @@ herdr pane report-agent-session <pane_id> \ [--seq N] \ [--agent-session-id ID] \ [--agent-session-path PATH] \ - [--session-start-source SOURCE] + [--session-start-source SOURCE] \ + [-- RESUME_COMMAND...] herdr pane release-agent <pane_id> \ --source ID \ @@ -276,6 +278,8 @@ herdr pane release-agent <pane_id> \ `report-agent-session` 只更新原生会话身份,不上报生命周期状态。`release-agent` 在智能体进程退出时结束该来源的生命周期权威。 +`--` 之后的参数是服务器重启后 Herdr 为恢复此会话而运行的命令。第一个参数必须是 `PATH` 上的普通命令名,并且任何参数都不能包含撇号。 + 当官方集成上报了原生会话引用时,`pane get`、`pane list`、`agent get` 和 `agent list` 会包含一个只读的 `agent_session` 对象。没有存储原生会话引用时,该字段被省略。 当 Herdr 能解析控制窗格的前台进程的 cwd 时,这些命令会包含 `foreground_cwd`。已有的 `cwd` 字段仍然是用于标签和 follow-cwd 行为的窗格/工作区 cwd。 @@ -351,7 +355,7 @@ herdr terminal title clear ``` 从直接附加中用 `ctrl+b q` 分离。用 `ctrl+b ctrl+b` 发送字面的 `ctrl+b`。 -`terminal session control` 为窗格、终端或智能体打开可写的实时终端流,输出与 observe 相同的逐行 JSON `terminal.frame` 和 `terminal.closed`,并从标准输入读取 `terminal.input`、`terminal.resize`、`terminal.scroll`、`terminal.release` 命令。同一终端同时只能有一个控制方,可用 `--takeover` 接管。 +`terminal session control` 为窗格、终端或智能体打开可写的实时终端流,输出与 observe 相同的逐行 JSON `terminal.frame` 和 `terminal.closed`,并从标准输入读取 `terminal.input`、`terminal.resize`、`terminal.scroll`、`terminal.mouse`、`terminal.release` 命令。同一终端同时只能有一个控制方,可用 `--takeover` 接管。`terminal.mouse` 在从 0 开始计数的单元格位置发送一个鼠标事件,例如 `{"type":"terminal.mouse","action":"down","button":"left","column":12,"row":5}`。`action` 为 `down`、`up`、`drag` 或 `move`;`button` 为 `left`(默认)、`right` 或 `middle`;`modifiers` 可省略,由 Shift = 1、Ctrl = 2、Alt = 4 组合(默认 0)。一次点击就是先 `down` 再 `up`。Herdr 会按应用的鼠标模式编码事件;应用未开启鼠标报告时直接丢弃,因此普通 shell 不会收到多余输入。`move` 只会发给追踪全部鼠标移动的应用。 `terminal session observe` 为相同目标打开只读实时流,输出包含 base64 ANSI 字节的逐行 JSON `terminal.frame`,服务器关闭流时输出 `terminal.closed`。多个观察方可以同时查看终端,不获取输入、调整尺寸、滚动或接管权限。Linux/macOS 上,若套接字写入连续 30 秒没有进展,观察方会被断开;此时可能没有最后的 `terminal.closed` 记录,但窗格和其他客户端继续运行。安静、没有输出的窗格不会触发此超时。 diff --git a/docs/preview/website/src/content/docs/zh-cn/configuration.mdx b/docs/preview/website/src/content/docs/zh-cn/configuration.mdx index 9c1d5b2d..8b8738d6 100644 --- a/docs/preview/website/src/content/docs/zh-cn/configuration.mdx +++ b/docs/preview/website/src/content/docs/zh-cn/configuration.mdx @@ -528,8 +528,11 @@ kitty_graphics = false ```toml [session] resume_agents_on_restore = true +startup_per_agent_delay_ms = 100 ``` +为减少启动时的资源争用,自动恢复默认每隔 100 毫秒启动一个智能体。第一个满足条件的智能体会立即启动。设置 `startup_per_agent_delay_ms = 0` 可禁用间隔。手动启动和显式连接终端不受影响。修改后需重启 Herdr 服务器。 + 只有通过官方集成获得有效原生会话引用的窗格才能恢复;其他窗格会作为普通 shell 恢复。有关受支持的智能体和持久化行为,请参阅[会话状态与恢复](/docs/session-state/)。 ## IME 光标跟踪 diff --git a/docs/preview/website/src/content/docs/zh-cn/connecting-machines.mdx b/docs/preview/website/src/content/docs/zh-cn/connecting-machines.mdx index 4175d5ee..722adeed 100644 --- a/docs/preview/website/src/content/docs/zh-cn/connecting-machines.mdx +++ b/docs/preview/website/src/content/docs/zh-cn/connecting-machines.mdx @@ -7,6 +7,12 @@ description: 在一个 Herdr 窗口中使用 Local 和已保存的 SSH 机器, 每台机器保留自己的 Herdr 服务器、会话和进程。一台机器断线不会影响其他连接。 +### 恢复 SSH 认证 + +在 Linux 和 macOS 上,启用 `remote.manage_ssh_config=true` 后,添加机器、侧边栏和 API 操作共享已批准的 OpenSSH 连接。运行 `herdr machine status [<label-or-id>] [--json]` 可进行新的非交互式检查。**reachable** 表示远程 Herdr 当前可用,不代表每个 TUI 都已连接。在终端运行 `herdr machine reconnect <label-or-id>` 完成原生 SSH 认证并验证已保存的机器;该命令不会安装或更新 Herdr。已打开的客户端会在 30 秒内重试,无需重启。点击 **`! auth`**、**`! error`** 或失败后的重连状态,会显示包含最新错误及 CLI 命令的通知,不会打开认证弹窗。机器行其余部分仍用于展开或折叠。 + +共享连接使用 `ControlPersist 600`,表示空闲 10 分钟,并不表示 MFA 有效期。活动连接可以继续保持,但企业策略、SSH 服务器或网络可能更早终止连接。Windows 本地恢复尚未支持。未受管理的 SSH 连接由你负责认证;单独运行 `ssh` 不会授予 Herdr 批准,除非它使用共享 ControlPath。主机密钥检查不会放宽;未知或已更改的主机密钥仍显示为 **Attention**。 + ## 连接前的准备 你需要能够通过普通 SSH 访问远程机器。先验证: @@ -74,18 +80,18 @@ herdr machine remove <profile-id> ## 连接问题 - **Reconnecting:** 网络中断、睡眠或 SSH 故障后,Herdr 会自动重试。连续失败会将间隔增加到最多两分钟,短暂连接成功不会重置间隔。连接稳定一分钟后,下一次中断才会恢复快速重试。SSH 连接会监测应用层活动并在空闲时探测,避免已断开的连接一直显示 Online。Local 使用本地连接关闭或失败来判断断线,而不是远程健康探测。 -- **Attention:** 目标需要无法在后台完成的操作,例如批准主机密钥、认证或准备兼容服务器。其他机器仍可使用。 +- **Attention:** 目标需要认证、批准主机密钥或准备兼容服务器等操作。其他机器仍可使用。**`! auth`** 表示认证失败,**`! error`** 表示其他问题。点击徽章可查看错误和 CLI 命令。侧边栏折叠时两者都显示为 `!`。 - **保存机器文件错误:** 目录文件无法读取或内容无效时,当前连接保持不变。Herdr 会显示通知并自动重试读取。 当两端都支持空闲桥接清理时,连接 Linux/macOS 的保存机器会在双向均无流量一分钟后关闭远程桥接。睡眠时间也计入期限,并在唤醒时检查。正常的空闲连接会交换健康检查,持续查看输出无需键盘输入。清理不会停止远程 Herdr 服务器、会话或窗格进程。旧安装仍可兼容连接,只是不使用这项可选清理功能。 -后台连接不会回答提示,也不会安装、更新、重启或交接服务器。对于 Attention,请在交互式终端运行 Herdr 显示的独立设置命令,例如: +后台连接不会回答提示,也不会安装、更新、重启或交接服务器。对于非认证类 Attention,请在交互式终端运行 Herdr 显示的独立设置命令,例如: ```bash herdr --remote workbox ``` -使用配置中的目标。如果添加时选择了命名会话,再加上可选的 `--session <name>`。完成批准提示后,重启客户端以重试 Attention 连接。不要仅因为版本与客户端不同就停止运行中的服务器。 +使用配置中的目标。如果添加时选择了命名会话,再加上 `--session <name>`。完成设置后,已打开的客户端会自动重试。`machine reconnect` 不会安装或更新 Herdr。不要仅因为版本与客户端不同就停止运行中的服务器。 认证失败时,先检查普通 SSH。对于有口令的私钥,请在启动 Herdr 的非交互式后台连接前用 `ssh-add` 加载。 diff --git a/docs/preview/website/src/content/docs/zh-cn/integrations.mdx b/docs/preview/website/src/content/docs/zh-cn/integrations.mdx index 5eb1f322..0fc3d2c0 100644 --- a/docs/preview/website/src/content/docs/zh-cn/integrations.mdx +++ b/docs/preview/website/src/content/docs/zh-cn/integrations.mdx @@ -68,37 +68,14 @@ Herdr 以两种不同方式使用集成: 自定义集成在定义了原生终端 UI 中不可见的状态时,也可以上报状态。它们不需要内置到 Herdr 中,也不要求 Herdr 识别智能体的可执行文件。 -## 集成你自己的智能体 - -在 Herdr 窗格中运行的智能体会继承 `HERDR_ENV`、`HERDR_PANE_ID`、`HERDR_BIN_PATH` 和 `HERDR_SOCKET_PATH`。如果智能体提供生命周期钩子,可从这些钩子通过 Herdr CLI 上报语义状态: - -```bash -"$HERDR_BIN_PATH" pane report-agent "$HERDR_PANE_ID" \ - --source custom:my-agent \ - --agent my-agent \ - --state working -``` - -当智能体等待输入时上报 `idle`,需要用户决策时上报 `blocked`。用 `--message` 描述阻塞原因。智能体退出时,释放同一来源的生命周期权威: - -```bash -"$HERDR_BIN_PATH" pane release-agent "$HERDR_PANE_ID" \ - --source custom:my-agent \ - --agent my-agent -``` - -仅在 `HERDR_ENV=1` 且必要变量存在时上报,这样集成在 Herdr 外不会执行任何操作。保持 `--source` 稳定且对该集成唯一。如果上报可能乱序到达,请加入严格递增的 `--seq`;Herdr 会忽略同一来源的旧序列号。 - -你可以在 `report-agent` 中加入 `--agent-session-id` 或 `--agent-session-path`,也可以在会话身份独立于状态变化时使用 `pane report-agent-session`。Herdr 会通过窗格和智能体 API 暴露该引用。自动恢复会话还要求 Herdr 知道如何启动该智能体并恢复所引用的会话。 - -要实现可移植的集成,请使用 `HERDR_BIN_PATH` 和 CLI 包装命令。需要直接 IPC 的代码可以发送 [Socket API](/zh-cn/docs/socket-api/) 中说明的等效 `pane.report_agent`、`pane.report_agent_session` 和 `pane.release_agent` 请求。 - -[Prime Agent 内置的 Herdr 上报器](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/core/extensions/builtin/herdr-agent-state.ts)是一个真实实现示例。它只在 Herdr 中启用,将智能体事件映射为 `working`、`idle` 和 `blocked`,跨会话保持上报顺序,并在退出时释放权威。 - 一些集成会上报智能体的原生会话引用。除非被 `[session] resume_agents_on_restore = false` 禁用,Herdr 会在服务器重启后使用官方会话引用恢复 Claude Code、Codex、Devin CLI、Droid、Kimi Code CLI、Qoder CLI、Qwen Code、Letta Code、Cursor Agent CLI、Grok CLI、GitHub Copilot CLI、Pi、OMP、Hermes Agent、OpenCode、Kilo Code CLI、MastraCode 和 Antigravity CLI 的窗格。 原生会话恢复需要最新的 Herdr 集成: Pi 集成版本 `2`、OMP 版本 `3`、Claude Code 版本 `6`、Codex 版本 `5`、GitHub Copilot CLI 版本 `2`、Devin CLI 版本 `2`、Droid 版本 `2`、Kimi Code CLI 版本 `3`、Qoder CLI 版本 `2`、Qwen Code 版本 `1`、Letta Code 版本 `1`、Cursor Agent CLI 版本 `1`、Grok CLI 版本 `2`、OpenCode 版本 `5`、Kilo Code CLI 版本 `1`、Hermes Agent 版本 `5`、MastraCode 版本 `1`、Antigravity CLI 版本 `1`。用 `herdr integration status` 查看已安装版本。 +## 集成你自己的智能体 + +如果你在开发编码智能体,可以在不为 Herdr 添加原生支持的情况下,从你自己的代码向 Herdr 上报它的状态和恢复命令。参阅[为你的智能体添加 Herdr 支持](/zh-cn/docs/add-herdr-support/)。 + ## Pi 安装 Pi 集成: @@ -229,6 +206,10 @@ herdr integration install opencode V2 生命周期上报在窗格本地的 TUI 中运行。即使多个窗格共享同一个 OpenCode 服务端,事件也只归属于该 TUI 选中的根会话。完成和中断会清除工作状态;待处理的权限请求、表单以及执行失败会使窗格保持阻塞。V2 Mini 和无界面客户端不运行 TUI 插件,因此不提供此生命周期上报。 +V1 TUI 跟踪窗格选中的会话及其后代。只要其中任何会话仍在忙碌或重试,就保持 working;存在待处理的权限请求或问题时保持 blocked。连接时会读取已有活动,已取消工具的请求不会在重新连接后再次变成阻塞项。查看子代理时保留原来的会话范围;直接连接子会话时只跟踪它及其后代,不包括兄弟会话。 + +本地 V1 的 `opencode run` 和 `opencode --mini` 保留原有服务端钩子;此变更不会为 Mini 或无界面客户端添加窗格本地的生命周期上报。更新集成后,请同时重启共享 OpenCode 服务器及其 TUI,避免旧服务端上报覆盖窗格本地状态。 + 该插件在 OpenCode 运行于 Herdr 窗格内时上报生命周期状态和会话身份。在 OpenCode 发出携带会话信息的事件后,Herdr 可以用上报的会话 id 通过 `opencode --session <id>` 恢复该窗格。插件未安装时,屏幕清单检测仍然可用。 ## Kilo Code CLI diff --git a/docs/preview/website/src/content/docs/zh-cn/persistence-remote.mdx b/docs/preview/website/src/content/docs/zh-cn/persistence-remote.mdx index ddd0b0fb..6b0be4d8 100644 --- a/docs/preview/website/src/content/docs/zh-cn/persistence-remote.mdx +++ b/docs/preview/website/src/content/docs/zh-cn/persistence-remote.mdx @@ -148,4 +148,4 @@ herdr terminal session observe w1:p1 --cols 120 --rows 40 herdr terminal session control w1:p1 --takeover --cols 120 --rows 40 ``` -控制模式输出相同的帧,并从标准输入读取逐行 JSON 命令。`terminal.input` 发送文本或 base64 数据,`terminal.resize` 更改视口尺寸,`terminal.scroll` 滚动视口,`terminal.release` 关闭控制器。同一时间只有一个控制器能拥有输入和调整尺寸的权限。 +控制模式输出相同的帧,并从标准输入读取逐行 JSON 命令。`terminal.input` 发送文本或 base64 数据,`terminal.resize` 更改视口尺寸,`terminal.scroll` 滚动视口,`terminal.mouse` 向已开启鼠标报告的应用发送单元格位置的鼠标事件,`terminal.release` 关闭控制器。同一时间只有一个控制器能拥有输入和调整尺寸的权限。 diff --git a/docs/preview/website/src/content/docs/zh-cn/session-state.mdx b/docs/preview/website/src/content/docs/zh-cn/session-state.mdx index 9be84060..6cb83f7d 100644 --- a/docs/preview/website/src/content/docs/zh-cn/session-state.mdx +++ b/docs/preview/website/src/content/docs/zh-cn/session-state.mdx @@ -83,7 +83,7 @@ pane_history = true resume_agents_on_restore = false ``` -Herdr 只会恢复那些通过当前官方 Herdr 集成上报了原生会话引用的窗格。 +Herdr 会恢复通过当前官方 Herdr 集成上报了原生会话引用的窗格,以及智能体自己上报了恢复命令的窗格。参阅[为你的智能体添加 Herdr 支持](/zh-cn/docs/add-herdr-support/)。 当客户端连接并提供终端尺寸和主题上下文后,Herdr 会跨工作区和标签页恢复符合条件的智能体窗格,不需要等每个窗格被聚焦。 diff --git a/docs/preview/website/src/content/docs/zh-cn/socket-api.mdx b/docs/preview/website/src/content/docs/zh-cn/socket-api.mdx index 3aae7131..e26c259e 100644 --- a/docs/preview/website/src/content/docs/zh-cn/socket-api.mdx +++ b/docs/preview/website/src/content/docs/zh-cn/socket-api.mdx @@ -99,7 +99,7 @@ herdr pane read w1:p2 --source recent --lines 50 | 工作区 | `workspace.create`、`workspace.list`、`workspace.get`、`workspace.focus`、`workspace.rename`、`workspace.move`、`workspace.move_block`、`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.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` | +| 窗格 | `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` | | 弹窗 | `popup.close` | | 布局 | `layout.export`、`layout.apply`、`layout.set_split_ratio` | | 智能体 | `agent.list`、`agent.get`、`agent.read`、`agent.explain`、`agent.send_keys`、`agent.prompt`、`agent.wait`、`agent.rename`、`agent.focus`、`agent.start` | @@ -147,20 +147,9 @@ CLI 的 `herdr api snapshot` 会把当前 `session.snapshot` 响应输出为 JSO ### 窗格图形 -窗格图形允许插件在窗格上放置图像数据。该功能默认可用;当服务器设置 `[terminal].kitty_graphics = false` 时,所有窗格图形方法都返回 `feature_disabled`。更改此设置需要重启服务器。调用 `pane.graphics.info` 会返回所连接客户端的单元格像素宽度和高度,但不会创建图形层。`pane.graphics.set` 接受 `data_base64` 中的 `png`、`rgb` 或 `rgba` 数据,`pane.graphics.clear` 删除该图层。 +应用和插件应通过窗格的终端输出发送标准 Kitty 图形协议。Herdr 在兼容的外层终端中管理图像的位置、裁剪和可见性。 -```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}} -``` +外部 socket 窗格图像叠加 API 已移除:`pane.graphics.info`、`pane.graphics.set`、`pane.graphics.clear` 和 `pane.graphics.stream` 不再可用,也没有替代的 socket 图像 API。与旧服务器的内部传输协议兼容性不会恢复这些公开方法。 `pane.layout` 返回标签页布局快照,包含 `workspace_id`、`tab_id`、`zoomed`、外层 `area`、`focused_pane_id`、窗格矩形和分割矩形/比例。`pane.neighbor` 和 `pane.edges` 也包含同一份布局快照,让客户端不需要私有布局状态就能做出下一步决策。 @@ -552,6 +541,22 @@ Herdr 在本地 socket 上使用换行分隔的 JSON。在 Unix 上,那个 socke } ``` +两个方法都接受可选的 `resume_argv` 数组,内容是 Herdr 服务器重启后恢复上报者当前会话的命令。第一个元素必须是普通命令名而不是路径,并且任何元素都不能包含撇号;无效值会以 `invalid_resume_argv` 失败,该次上报不会生效。自定义智能体必须先通过 `pane.report_agent` 持有窗格才能附加命令,否则请求会以 `resume_not_accepted` 失败。Herdr 只在同一 `source` 和 `agent` 持有窗格时保留该命令,并且它优先于 Herdr 为该智能体内置的恢复命令。旧版 Herdr 会忽略这个字段。 + +```json +{ + "id": "req_3", + "method": "pane.report_agent_session", + "params": { + "pane_id": "w1:p1", + "source": "custom:my-agent", + "agent": "my-agent", + "agent_session_id": "...", + "resume_argv": ["my-agent", "--resume", "..."] + } +} +``` + Herdr 存有原生会话引用时,`pane.get`、`pane.list`、`agent.get` 和 `agent.list` 暴露一个只读的 `agent_session` 对象: ```json diff --git a/docs/preview/website/src/data/config-reference.json b/docs/preview/website/src/data/config-reference.json index ece9a833..eb7e08d4 100644 --- a/docs/preview/website/src/data/config-reference.json +++ b/docs/preview/website/src/data/config-reference.json @@ -439,7 +439,7 @@ "key": "terminal.kitty_graphics", "type": "boolean", "default": "true", - "description": "Render pane images in Kitty graphics-compatible outer terminals. Set false to disable graphics rendering and the pane graphics API. Restart the server or reattach the client after changing it. In remote sessions, server configuration controls parsing and API availability while local client configuration controls outer-terminal output." + "description": "Render pane images in Kitty graphics-compatible outer terminals. Applications use the standard Kitty graphics protocol through pane terminal output; the external socket pane-overlay API is no longer available. Set false to disable graphics rendering. Restart the server or reattach the client after changing it. In remote sessions, server configuration controls Kitty graphics parsing while local client configuration controls outer-terminal output." } ] }, @@ -477,9 +477,9 @@ "keys": [ { "key": "keys.prefix", - "type": "string", + "type": "keybinding", "default": "\"ctrl+b\"", - "description": "Prefix key to enter prefix mode (e.g. \"ctrl+b\", \"f12\", \"esc\")." + "description": "Prefix key(s) to enter prefix mode (e.g. \"ctrl+b\", \"f12\", \"esc\", or an array to accept several)." }, { "key": "keys.help", @@ -1429,6 +1429,12 @@ "type": "boolean", "default": "true", "description": "Resume supported AI-agent panes into their native conversation sessions when restoring a Herdr session." + }, + { + "key": "session.startup_per_agent_delay_ms", + "type": "integer", + "default": "100", + "description": "Milliseconds between automatic agent restores after a server restart. The first agent starts without this delay; 0 disables spacing. Does not delay manual launches or explicit terminal attaches. Restart the server to apply." } ] }, |
