mirror of
https://github.com/herdrdev/herdr.git
synced 2026-09-21 16:01:04 +00:00
docs: prepare 0.9.0 release documentation
This commit is contained in:
@@ -2,6 +2,67 @@
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Added
|
||||
- Manage Local and saved SSH machines from one Herdr window, with a combined agent list, machine-scoped navigation, notifications, and automatic reconnects. Add and manage connections with `herdr machine`; a disconnected machine does not interrupt the others. (#3670)
|
||||
- Multiple clients can now view different workspaces and tabs independently. Different tabs fit their viewing clients; when clients share a tab, the last one to interact with it controls its size. (#3526)
|
||||
- Added Muse agent detection for idle, working, approval, and question states. (#2489, thanks @ohk)
|
||||
- Sidebar text and metadata tokens can now change color, boldness, and dimming based on their values, using ordered text or numeric rules. (#3693)
|
||||
- Custom themes can now define separate light and dark color overrides when automatic theme switching is enabled. (#2324, thanks @aneym)
|
||||
- `ui.pane_borders = "always"` can now frame a single pane when outer borders are enabled. `"auto"` keeps split-only borders, `"off"` hides them, and existing boolean values keep working. (#3234, thanks @rsmdt)
|
||||
|
||||
### Changed
|
||||
- Client updates can now leave compatible servers and their running agents untouched. Missing server features disable only the affected action instead of preventing connection. Servers older than endpoint generation 1 need a one-time upgrade. Replacing a remote server asks before stopping its pane processes, with No as the default answer; experimental handoff remains opt-in. (#3509)
|
||||
- The terminal UI now runs in each client, reducing redraw work in busy multi-client sessions and keeping themes, menus, copy mode, and other presentation settings local to the viewing machine. (#3487)
|
||||
- Idle terminal scrollback now uses less memory without reducing retained history or changing reads and resizing. (#3556)
|
||||
- Pane images and the graphics API are now enabled by default in compatible terminals. Set `terminal.kitty_graphics = false` to disable them; the old `experimental.kitty_graphics` setting remains accepted.
|
||||
- Closing a primary workspace with open worktree workspaces now requires explicit group intent: `workspace close --group` or `workspace.close` with `close_group: true`. Otherwise the whole group stays open. (#2874)
|
||||
- New lifecycle event subscriptions now start with live events rather than replaying retained history. API clients should subscribe before taking their initial snapshot to avoid missing changes. (#1270)
|
||||
|
||||
### Fixed
|
||||
- Mouse selections now stay visible and copyable while terminal output continues, including with automatic copying disabled. Ctrl+C and Cmd+C copy a selection even before a delayed mouse release, and a failed copy no longer interrupts the agent. Selection highlights also remain visible when host colors are unavailable. (#3100, #2708, #3684, thanks @moret and @Pimpmuckl)
|
||||
- Wayland clipboard copies no longer freeze Herdr while `wl-copy` serves the selection. (#3014)
|
||||
- Live handoff now preserves mouse forwarding for running pane applications. (#3000, thanks @xkrogen)
|
||||
- Interrupted pane exits during host shutdown no longer replace the saved session with an empty session or a new default workspace. (#3415)
|
||||
- SSH clients whose terminal disappears now detach instead of resizing running panes to a fallback size and triggering expensive history reflow. (#3519)
|
||||
- Focusing a workspace now scrolls the sidebar to keep it visible. (#3554)
|
||||
- Removing a background worktree workspace no longer changes focus to its parent. Windows worktrees can also be removed while their agent panes are running, without a replacement shell locking the checkout again. (#3098, #3532)
|
||||
- Worktree commands can now trust a verified repository for one request with `--trust-repository`, including accessible Windows repositories owned by another SID, without changing global Git configuration. (#3044)
|
||||
- Oversized Kitty images no longer prevent smaller images from appearing, and image replacements no longer redraw or disappear one row at a time. Direct graphics stay bound to the client that owns them. (#3033, #3166, #3549, thanks @kataokatsuki)
|
||||
- Pixel mouse coordinates remain correct when pane applications reassert SGR mouse reporting. (#3295)
|
||||
- Prefix bindings such as `prefix+|` now recognize characters produced by macOS Option and custom keyboard layouts, while exact chords keep priority. Arrow navigation also works when terminals such as Alacritty attach text to special-key reports. (#3079, #3328, thanks @vlcinsky)
|
||||
- Direct terminal attaches now honor `ui.mouse_capture` and preserve multiline pastes as one paste instead of submitting each line separately. (#2992, #3054)
|
||||
- `agent prompt` now reliably sends the prompt and Enter before reporting successful submission. With `--wait`, prompts sent to a non-working agent require observed working or blocked activity, so unrelated state changes cannot complete the wait. Pending submissions fail cleanly if the terminal exits. (#3506, #3685)
|
||||
- Long Codex prompts on Windows now wait long enough for the text to arrive before submitting Enter. Expired queued submissions are rejected before typing starts. (#3187)
|
||||
- Recent pane reads now include output that has not yet scrolled off the viewport, instead of returning empty text. (#3444)
|
||||
- `pane report-agent` and `pane report-agent-session` now accept options before the pane ID and `--option=value` arguments. (#2926)
|
||||
- `herdr agent explain --file` now reports unreadable files as structured JSON rather than raw Rust errors. (#3022)
|
||||
- Running named servers now pick up detection manifests downloaded by another server without needing a restart. (#2711)
|
||||
- Agents that set their terminal title or progress once at startup no longer lose that detection signal when first recognized. (#3326, thanks @aneym)
|
||||
- Claude Code now recognizes visible turn and background-agent activity when terminal titles are unavailable, and remains working while background MCP tasks continue. An idle prompt with only a background shell running no longer stays working. (#1630, #3090, #3414)
|
||||
- Claude Code MCP questions and Bash approval prompts now stay blocked while waiting for an answer, including different option layouts and cursor positions. (#3283, #3383, #2650, #3615, thanks @caner-akca)
|
||||
- Claude Code hooks now ignore Cursor's Claude-compatible events, preventing Cursor sessions from being saved as Claude sessions. (#2832)
|
||||
- Codex no longer appears blocked because earlier output quotes a confirmation prompt, and its startup update dialog now correctly reports blocked. Explicitly resumed sessions are saved before the first prompt, so they survive a server restart. (#3301, #3632, #3517)
|
||||
- GitHub Copilot CLI now stays working while it waits for background agents. (#3291, #3403, thanks @LaneBirmingham)
|
||||
- Oh My Pi now stays working through already-scheduled continuations instead of briefly reporting idle and ending `agent wait` early. (#2851, #3122, thanks @caner-akca and @taoeffect)
|
||||
- OpenCode child-agent permission and question prompts no longer leave the parent pane stuck as blocked after work continues. (#3669, thanks @markjaquith)
|
||||
- Foreground working-directory reads now follow the foreground process-group leader rather than a descendant, keeping new panes in the intended directory. (#3270, #3386, thanks @caner-akca)
|
||||
- Oversized or unreadable Git ref files no longer cause repeated heavy status reads or make workspaces use stale ref data. (#3343, #3373, thanks @caner-akca)
|
||||
- Tab bar status commands no longer display stray ANSI escape fragments, and host palette replies are applied together to avoid redundant updates. (#3001, #3580)
|
||||
- Unix plugin panes now keep `PWD` aligned with their requested working directory unless explicitly overridden. Windows plugin panes now resolve relative commands from the plugin root and handle launch paths correctly. (#2984, #3024)
|
||||
- Plugin link handlers now receive matching OSC 8 `file://` clicks; unmatched file links still do not launch the system URL opener. (#2941)
|
||||
- Windows panes now preserve non-US shifted text, physical modified keys, Ctrl+/, and dead-key composition in Kitty keyboard applications. (#3045, #2954, #3546, #3503)
|
||||
- Windows OpenSSH sessions now receive mouse input reliably without dropped reports or escape fragments leaking into panes. Remote and LF-only multiline pastes retain their newlines and order. (#2810, #3459, #3209, #3172)
|
||||
- Windows panes now keep Cursor and bundled Pi launches detected, and PowerShell agent shims accept native arguments. Codex no longer inherits Windows Terminal identity that caused excessive repainting and scroll jumps during resume. (#3032, #3205, #3455, #3127, thanks @Pimpmuckl)
|
||||
- Antigravity hooks now run correctly on Windows, and Devin integration setup uses the correct Windows config directory. (#3348, #2724)
|
||||
- Windows installations no longer need a separately installed Visual C++ runtime. Installer paths remain discoverable in OpenSSH sessions, and malformed inherited environment values are rejected safely. (#3089, #3611, #3430)
|
||||
- Windows users whose endpoint security blocks fileless PowerShell installation can use a local `install.cmd` bootstrap with checksum-verified downloads. (#2751)
|
||||
- WSL remote sessions can now paste images from the Windows clipboard. (#3376)
|
||||
- Nix installations now fetch crates through the static CDN, avoiding download failures from the previous endpoint. (#3505)
|
||||
- The Unix installer now explains that Android/Termux is unsupported instead of installing a Linux binary that cannot run there. (#3571)
|
||||
|
||||
### Removed
|
||||
- Removed the single-process `--no-session` mode. All terminal UI launches now attach to a background server; detach leaves panes running, while `server stop` ends the session.
|
||||
|
||||
## [0.8.2] - 2026-08-19
|
||||
|
||||
### Added
|
||||
|
||||
@@ -60,6 +60,10 @@ path = "kiro.toml"
|
||||
id = "maki"
|
||||
path = "maki.toml"
|
||||
|
||||
[[agents]]
|
||||
id = "muse"
|
||||
path = "muse.toml"
|
||||
|
||||
[[agents]]
|
||||
id = "opencode"
|
||||
path = "opencode.toml"
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
id = "muse"
|
||||
version = "2026.08.26.1"
|
||||
min_engine_version = 2
|
||||
updated_at = "2026-08-26T00:00:00Z"
|
||||
aliases = ["muse-code", "muse-cli"]
|
||||
|
||||
# Evidence: live bottom-buffer captures from Muse Code 0.2.1 in Herdr, using a local
|
||||
# deterministic Responses provider so each UI state could be held and inspected.
|
||||
#
|
||||
# Idle has a `⟩` prompt and `model · effort · cwd` footer. Active turns show
|
||||
# `◆ Working (... · esc to interrupt)` or another activity label with the same interrupt hint.
|
||||
#
|
||||
# Structured questions show two co-occurring footer controls:
|
||||
# Enter to select · ↑/↓ to move · Tab for an optional note · Esc to interrupt
|
||||
# Multi-select uses `Enter to toggle` instead. The paired controls distinguish a real picker
|
||||
# from ordinary transcript text that happens to mention one action.
|
||||
#
|
||||
# First launch in an untrusted directory shows `Do you trust this workspace?` together with
|
||||
# `Trust and continue`. This is a real blocker. User-opened `/theme` and `/skills` menus are
|
||||
# not blockers; their paired footer controls identify overlays whose prior state must be kept.
|
||||
#
|
||||
# Muse 0.2.1 command approval shows `Allow this stage once` together with
|
||||
# `Always allow in this workspace`. Muse 0.1 used `Allow once` with
|
||||
# `Allow for this session`. Network approval shows `Yes, proceed` together with
|
||||
# `Yes, don't ask again this session`. Each approval rule requires a pair because Muse can
|
||||
# emit any one of these phrases as ordinary assistant text after a completed turn.
|
||||
|
||||
[[rules]]
|
||||
id = "workspace_trust_blocked"
|
||||
state = "blocked"
|
||||
priority = 970
|
||||
region = "bottom_non_empty_lines(12)"
|
||||
visible_blocker = true
|
||||
contains = ["Do you trust this workspace?"]
|
||||
any = [
|
||||
{ contains = ["Trust and continue"] },
|
||||
{ contains = ["Use Up/Down"] },
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "pick_request_blocked"
|
||||
state = "blocked"
|
||||
priority = 950
|
||||
region = "bottom_non_empty_lines(8)"
|
||||
visible_blocker = true
|
||||
any = [
|
||||
{ contains = ["Enter to select", "Tab for an optional note"] },
|
||||
{ contains = ["Enter to toggle", "Esc to interrupt"] },
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "menu_overlay"
|
||||
state = "unknown"
|
||||
priority = 940
|
||||
region = "bottom_non_empty_lines(8)"
|
||||
skip_state_update = true
|
||||
any = [
|
||||
{ contains = ["enter confirm", "esc go back"] },
|
||||
{ contains = ["enter save", "esc go back"] },
|
||||
{ contains = ["space toggle", "esc close", "type filter"] },
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "working_esc_interrupt"
|
||||
state = "working"
|
||||
priority = 900
|
||||
region = "bottom_non_empty_lines(8)"
|
||||
visible_working = true
|
||||
contains = ["esc to interrupt"]
|
||||
not = [
|
||||
{ contains = ["Enter to select", "Tab for an optional note"] },
|
||||
{ contains = ["Enter to toggle", "Esc to interrupt"] },
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "blocked_approval"
|
||||
state = "blocked"
|
||||
priority = 850
|
||||
region = "bottom_non_empty_lines(8)"
|
||||
visible_blocker = true
|
||||
any = [
|
||||
{ contains = ["Allow this stage once", "Always allow in this workspace"] },
|
||||
{ contains = ["Allow once", "Allow for this session"] },
|
||||
{ contains = ["Yes, proceed", "Yes, don't ask again this session"] },
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "idle_prompt"
|
||||
state = "idle"
|
||||
priority = 700
|
||||
region = "bottom_non_empty_lines(5)"
|
||||
visible_idle = true
|
||||
any = [
|
||||
{ line_regex = ['^\s*⟩\s*$'] },
|
||||
{ line_regex = ['^\s*⟩\s+\S'] },
|
||||
]
|
||||
not = [
|
||||
{ contains = ["esc to interrupt"] },
|
||||
{ contains = ["Enter to select", "Tab for an optional note"] },
|
||||
{ contains = ["Enter to toggle", "Esc to interrupt"] },
|
||||
{ contains = ["enter confirm", "esc go back"] },
|
||||
{ contains = ["enter save", "esc go back"] },
|
||||
{ contains = ["space toggle", "esc close", "type filter"] },
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "idle_status_fallback"
|
||||
state = "idle"
|
||||
priority = 500
|
||||
region = "bottom_non_empty_lines(3)"
|
||||
visible_idle = true
|
||||
line_regex = ['^\s*\S+ · (none|minimal|low|medium|high|xhigh|ultra) · ']
|
||||
not = [{ contains = ["esc to interrupt"] }]
|
||||
+57
-23
@@ -3,30 +3,65 @@
|
||||
## Unreleased
|
||||
|
||||
### Added
|
||||
- Custom themes can now define separate light and dark color overrides when automatic theme switching is enabled. (#837, thanks @aneym)
|
||||
- `ui.pane_borders` now accepts `"auto"`, `"always"`, and `"off"`; `"always"` also frames a single pane when `ui.pane_outer_borders` is enabled. Existing boolean values keep working.
|
||||
- Manage Local and saved SSH machines from one Herdr window, with a combined agent list, machine-scoped navigation, notifications, and automatic reconnects. Add and manage connections with `herdr machine`; a disconnected machine does not interrupt the others. (#3670)
|
||||
- Multiple clients can now view different workspaces and tabs independently. Different tabs fit their viewing clients; when clients share a tab, the last one to interact with it controls its size. (#3526)
|
||||
- Added Muse agent detection for idle, working, approval, and question states. (#2489, thanks @ohk)
|
||||
- Sidebar text and metadata tokens can now change color, boldness, and dimming based on their values, using ordered text or numeric rules. (#3693)
|
||||
- Custom themes can now define separate light and dark color overrides when automatic theme switching is enabled. (#2324, thanks @aneym)
|
||||
- `ui.pane_borders = "always"` can now frame a single pane when outer borders are enabled. `"auto"` keeps split-only borders, `"off"` hides them, and existing boolean values keep working. (#3234, thanks @rsmdt)
|
||||
|
||||
### Changed
|
||||
- Client updates can now leave compatible servers and their running agents untouched. Missing server features disable only the affected action instead of preventing connection. Servers older than endpoint generation 1 need a one-time upgrade. Replacing a remote server asks before stopping its pane processes, with No as the default answer; experimental handoff remains opt-in. (#3509)
|
||||
- The terminal UI now runs in each client, reducing redraw work in busy multi-client sessions and keeping themes, menus, copy mode, and other presentation settings local to the viewing machine. (#3487)
|
||||
- Idle terminal scrollback now uses less memory without reducing retained history or changing reads and resizing. (#3556)
|
||||
- Pane images and the graphics API are now enabled by default in compatible terminals. Set `terminal.kitty_graphics = false` to disable them; the old `experimental.kitty_graphics` setting remains accepted.
|
||||
- Closing a primary workspace with open worktree workspaces now requires explicit group intent: `workspace close --group` or `workspace.close` with `close_group: true`. Otherwise the whole group stays open. (#2874)
|
||||
- New lifecycle event subscriptions now start with live events rather than replaying retained history. API clients should subscribe before taking their initial snapshot to avoid missing changes. (#1270)
|
||||
|
||||
### Fixed
|
||||
- Claude Code integration hooks now ignore Cursor CLI's Claude-compatible session events, preventing Cursor sessions from being stored as resumable Claude sessions. (#2832)
|
||||
- Running named servers now activate remote agent-detection manifests downloaded by another server, preventing stale agent states and `agent explain` output until restart. (#2711)
|
||||
- New lifecycle event subscriptions now stream only events emitted after subscription begins instead of replaying retained history. (#1270)
|
||||
- Windows users whose endpoint security blocks the fileless PowerShell install command can now use a local `install.cmd` bootstrap; installer downloads use `curl.exe` while preserving package checksum verification. (#2751)
|
||||
- Oh My Pi panes now stay working when a turn ends with an automatic continuation already scheduled, instead of briefly reporting idle and completing `agent wait` early. (#2851, thanks @taoeffect)
|
||||
- Retained mouse selections now copy when Ctrl+C or Cmd+C arrives before a delayed mouse release instead of forwarding the copy shortcut to the pane. (#3100, thanks @moret)
|
||||
- Removing a background worktree workspace no longer changes focus to its parent workspace. (#3098)
|
||||
- Worktree commands can now trust an explicitly selected repository for one request, allowing the full lifecycle on accessible Windows repositories owned by another SID without changing global Git configuration. (#3044)
|
||||
- Prefix bindings such as `prefix+|` now recognize characters produced by macOS Option and custom keyboard layouts, while exact chords such as `prefix+alt+w` keep priority. (#3079, thanks @vlcinsky)
|
||||
- Direct terminal attaches now preserve multiline pastes as one paste instead of submitting each line separately. (#3054)
|
||||
- Windows clients now preserve layout-generated text for Shift-only keys, so characters such as `/` on German keyboards reach shell panes and pasted input. (#3045)
|
||||
- Windows panes now keep bare `cursor-agent` launches detected after Cursor hands off to its bundled Node process. (#3032)
|
||||
- Oversized Kitty images no longer prevent smaller images shown later in the same pane from rendering. (#3033)
|
||||
- `herdr agent explain --file` now reports fixture read failures as structured JSON instead of exposing Rust I/O debug output. (#3022)
|
||||
- Wayland clipboard copies no longer freeze Herdr while `wl-copy` remains alive to serve the selection. (#3014)
|
||||
- Claude Code panes now use visible turn, background shell, and background agent activity as working-state fallbacks when OSC titles are unavailable or disabled. (#1630, #2241)
|
||||
- Claude Code panes now remain working while MCP tasks continue in the background after a turn ends. (#3090)
|
||||
- Tab bar status commands now remove ESC-prefixed terminal control sequences instead of displaying their sequence bodies as text. (#3001)
|
||||
- Unix plugin pane commands now default `PWD` to their resolved working directory, so direct popup tools open at explicit `--cwd` paths while preserving caller-provided `PWD` values. (#2984)
|
||||
- Plugin link handlers now receive matching OSC 8 `file://` clicks while unmatched file links remain excluded from the system URL opener. (#2941)
|
||||
- Mouse selections now stay visible and copyable while terminal output continues, including with automatic copying disabled. Ctrl+C and Cmd+C copy a selection even before a delayed mouse release, and a failed copy no longer interrupts the agent. Selection highlights also remain visible when host colors are unavailable. (#3100, #2708, #3684, thanks @moret and @Pimpmuckl)
|
||||
- Wayland clipboard copies no longer freeze Herdr while `wl-copy` serves the selection. (#3014)
|
||||
- Live handoff now preserves mouse forwarding for running pane applications. (#3000, thanks @xkrogen)
|
||||
- Interrupted pane exits during host shutdown no longer replace the saved session with an empty session or a new default workspace. (#3415)
|
||||
- SSH clients whose terminal disappears now detach instead of resizing running panes to a fallback size and triggering expensive history reflow. (#3519)
|
||||
- Focusing a workspace now scrolls the sidebar to keep it visible. (#3554)
|
||||
- Removing a background worktree workspace no longer changes focus to its parent. Windows worktrees can also be removed while their agent panes are running, without a replacement shell locking the checkout again. (#3098, #3532)
|
||||
- Worktree commands can now trust a verified repository for one request with `--trust-repository`, including accessible Windows repositories owned by another SID, without changing global Git configuration. (#3044)
|
||||
- Oversized Kitty images no longer prevent smaller images from appearing, and image replacements no longer redraw or disappear one row at a time. Direct graphics stay bound to the client that owns them. (#3033, #3166, #3549, thanks @kataokatsuki)
|
||||
- Pixel mouse coordinates remain correct when pane applications reassert SGR mouse reporting. (#3295)
|
||||
- Prefix bindings such as `prefix+|` now recognize characters produced by macOS Option and custom keyboard layouts, while exact chords keep priority. Arrow navigation also works when terminals such as Alacritty attach text to special-key reports. (#3079, #3328, thanks @vlcinsky)
|
||||
- Direct terminal attaches now honor `ui.mouse_capture` and preserve multiline pastes as one paste instead of submitting each line separately. (#2992, #3054)
|
||||
- `agent prompt` now reliably sends the prompt and Enter before reporting successful submission. With `--wait`, prompts sent to a non-working agent require observed working or blocked activity, so unrelated state changes cannot complete the wait. Pending submissions fail cleanly if the terminal exits. (#3506, #3685)
|
||||
- Long Codex prompts on Windows now wait long enough for the text to arrive before submitting Enter. Expired queued submissions are rejected before typing starts. (#3187)
|
||||
- Recent pane reads now include output that has not yet scrolled off the viewport, instead of returning empty text. (#3444)
|
||||
- `pane report-agent` and `pane report-agent-session` now accept options before the pane ID and `--option=value` arguments. (#2926)
|
||||
- `herdr agent explain --file` now reports unreadable files as structured JSON rather than raw Rust errors. (#3022)
|
||||
- Running named servers now pick up detection manifests downloaded by another server without needing a restart. (#2711)
|
||||
- Agents that set their terminal title or progress once at startup no longer lose that detection signal when first recognized. (#3326, thanks @aneym)
|
||||
- Claude Code now recognizes visible turn and background-agent activity when terminal titles are unavailable, and remains working while background MCP tasks continue. An idle prompt with only a background shell running no longer stays working. (#1630, #3090, #3414)
|
||||
- Claude Code MCP questions and Bash approval prompts now stay blocked while waiting for an answer, including different option layouts and cursor positions. (#3283, #3383, #2650, #3615, thanks @caner-akca)
|
||||
- Claude Code hooks now ignore Cursor's Claude-compatible events, preventing Cursor sessions from being saved as Claude sessions. (#2832)
|
||||
- Codex no longer appears blocked because earlier output quotes a confirmation prompt, and its startup update dialog now correctly reports blocked. Explicitly resumed sessions are saved before the first prompt, so they survive a server restart. (#3301, #3632, #3517)
|
||||
- GitHub Copilot CLI now stays working while it waits for background agents. (#3291, #3403, thanks @LaneBirmingham)
|
||||
- Oh My Pi now stays working through already-scheduled continuations instead of briefly reporting idle and ending `agent wait` early. (#2851, #3122, thanks @caner-akca and @taoeffect)
|
||||
- OpenCode child-agent permission and question prompts no longer leave the parent pane stuck as blocked after work continues. (#3669, thanks @markjaquith)
|
||||
- Foreground working-directory reads now follow the foreground process-group leader rather than a descendant, keeping new panes in the intended directory. (#3270, #3386, thanks @caner-akca)
|
||||
- Oversized or unreadable Git ref files no longer cause repeated heavy status reads or make workspaces use stale ref data. (#3343, #3373, thanks @caner-akca)
|
||||
- Tab bar status commands no longer display stray ANSI escape fragments, and host palette replies are applied together to avoid redundant updates. (#3001, #3580)
|
||||
- Unix plugin panes now keep `PWD` aligned with their requested working directory unless explicitly overridden. Windows plugin panes now resolve relative commands from the plugin root and handle launch paths correctly. (#2984, #3024)
|
||||
- Plugin link handlers now receive matching OSC 8 `file://` clicks; unmatched file links still do not launch the system URL opener. (#2941)
|
||||
- Windows panes now preserve non-US shifted text, physical modified keys, Ctrl+/, and dead-key composition in Kitty keyboard applications. (#3045, #2954, #3546, #3503)
|
||||
- Windows OpenSSH sessions now receive mouse input reliably without dropped reports or escape fragments leaking into panes. Remote and LF-only multiline pastes retain their newlines and order. (#2810, #3459, #3209, #3172)
|
||||
- Windows panes now keep Cursor and bundled Pi launches detected, and PowerShell agent shims accept native arguments. Codex no longer inherits Windows Terminal identity that caused excessive repainting and scroll jumps during resume. (#3032, #3205, #3455, #3127, thanks @Pimpmuckl)
|
||||
- Antigravity hooks now run correctly on Windows, and Devin integration setup uses the correct Windows config directory. (#3348, #2724)
|
||||
- Windows installations no longer need a separately installed Visual C++ runtime. Installer paths remain discoverable in OpenSSH sessions, and malformed inherited environment values are rejected safely. (#3089, #3611, #3430)
|
||||
- Windows users whose endpoint security blocks fileless PowerShell installation can use a local `install.cmd` bootstrap with checksum-verified downloads. (#2751)
|
||||
- WSL remote sessions can now paste images from the Windows clipboard. (#3376)
|
||||
- Nix installations now fetch crates through the static CDN, avoiding download failures from the previous endpoint. (#3505)
|
||||
- The Unix installer now explains that Android/Termux is unsupported instead of installing a Linux binary that cannot run there. (#3571)
|
||||
|
||||
### Removed
|
||||
- Removed the single-process `--no-session` mode. All terminal UI launches now attach to a background server; detach leaves panes running, while `server stop` ends the session.
|
||||
|
||||
## [0.8.2] - 2026-08-19
|
||||
|
||||
@@ -54,7 +89,6 @@
|
||||
- Experimental pane graphics now support bounded named layers, acknowledged full-RGBA primary-layer direct file frames on audited local terminals, owned BGRA fallback, exact pixel mouse input, and placement-only resize replay.
|
||||
|
||||
### Fixed
|
||||
- Live handoff now preserves mouse forwarding for running pane applications. (#3000, thanks @xkrogen)
|
||||
- Unix CLI commands now exit quietly when a downstream pipe closes instead of panicking with exit 101. (#2994)
|
||||
- The terminal theme now keeps the active Space row fill visible when the Navigate cursor lands on it, in both expanded and collapsed sidebars. (#2987)
|
||||
- Busy multi-pane sessions now avoid redundant hidden-pane wakeups and full terminal-state formatting in pane-scaled paths, preventing CPU regressions from high-rate background output, scrollbars, and enhanced keyboard modes. (#2550, #2901, #2962)
|
||||
|
||||
+3
-2
@@ -28,7 +28,8 @@ https://github.com/user-attachments/assets/043ec09f-4bdd-41d5-aee0-8fda6b83e267
|
||||
|
||||
**the runtime your coding agents live on.**
|
||||
|
||||
- **always running** — herdr is a background server; the terminals live inside it. close the lid, drop the network, or restart the machine; agents keep working and sessions come back. reattach from any terminal, or over ssh.
|
||||
- **detach without stopping work** — herdr keeps terminals running in a background server when you close the client or lose your SSH connection. after a server or machine restart, herdr restores the saved layout and can resume supported agent sessions; the original processes do not survive. [session state →](https://herdr.dev/docs/session-state/)
|
||||
- **several machines, one window** — keep local work and saved ssh machines together, with a combined agent list and independent reconnects. [remote machines →](https://herdr.dev/docs/connecting-machines/)
|
||||
- **never hunt for the stuck one** — every pane is marked working, blocked, or idle. when an agent stops and needs an answer, herdr says so.
|
||||
- **agent-native** — agents drive herdr through the cli and socket api: they can spawn panes, prompt each other, and wait until another agent is genuinely blocked. [agent skill →](https://herdr.dev/docs/agent-skill/)
|
||||
- **runs what you already run** — claude code, codex, cursor, opencode, grok and the rest. herdr doesn't wrap or replace them; it owns their terminals.
|
||||
@@ -56,7 +57,7 @@ run your agents, split panes, walk away. `ctrl+b q` detaches, `herdr` reattaches
|
||||
|
||||
## docs
|
||||
|
||||
everything lives at [herdr.dev/docs](https://herdr.dev/docs/): [quick start](https://herdr.dev/docs/quick-start/) · [concepts](https://herdr.dev/docs/concepts/) · [supported agents](https://herdr.dev/docs/agents/) · [keyboard](https://herdr.dev/docs/keyboard/) · [configuration](https://herdr.dev/docs/configuration/) · [session state](https://herdr.dev/docs/session-state/) · [remote](https://herdr.dev/docs/persistence-remote/) · [integrations](https://herdr.dev/docs/integrations/) · [plugins](https://herdr.dev/docs/plugins/) · [socket api](https://herdr.dev/docs/socket-api/)
|
||||
everything lives at [herdr.dev/docs](https://herdr.dev/docs/): [quick start](https://herdr.dev/docs/quick-start/) · [concepts](https://herdr.dev/docs/concepts/) · [supported agents](https://herdr.dev/docs/agents/) · [keyboard](https://herdr.dev/docs/keyboard/) · [configuration](https://herdr.dev/docs/configuration/) · [session state](https://herdr.dev/docs/session-state/) · [connecting machines](https://herdr.dev/docs/connecting-machines/) · [remote](https://herdr.dev/docs/persistence-remote/) · [integrations](https://herdr.dev/docs/integrations/) · [plugins](https://herdr.dev/docs/plugins/) · [socket api](https://herdr.dev/docs/socket-api/)
|
||||
|
||||
## thanks
|
||||
|
||||
|
||||
@@ -28,7 +28,8 @@ https://github.com/user-attachments/assets/043ec09f-4bdd-41d5-aee0-8fda6b83e267
|
||||
**智能体复用器,住在你的终端里。**
|
||||
|
||||
- **每个智能体一目了然**——`blocked`、`working`、`done`。真实的终端视图,而不是包装过的转述。
|
||||
- **分离后智能体继续运行**——从任意终端重新连接,或通过 ssh。会话在重启后依然保留。
|
||||
- **分离后工作继续运行**——关闭客户端或 SSH 断线后,后台服务器仍会保持终端运行。服务器或机器重启后,Herdr 会恢复已保存的布局,并可恢复受支持的智能体会话;原有进程不会保留。[会话状态 →](https://herdr.dev/zh-cn/docs/session-state/)
|
||||
- **多台机器,一个窗口**——将本地工作和已保存的 SSH 机器放在一起,使用汇总的智能体列表,各连接独立重连。[远程机器 →](https://herdr.dev/zh-cn/docs/connecting-machines/)
|
||||
- **智能体也能使用 herdr**——纯 socket api:智能体可以创建窗格、读取输出、互相等待。[智能体技能 →](https://herdr.dev/zh-cn/docs/agent-skill/)
|
||||
- **键盘和鼠标都是一等公民**——tmux 风格的前缀键,*以及*点击、拖动、分割。按当下的场景选择,而不是被工具锁死。
|
||||
- **插件**——扩展窗格和工作流。[浏览插件市场 →](https://herdr.dev/plugins/)
|
||||
@@ -54,7 +55,7 @@ herdr
|
||||
|
||||
## 文档
|
||||
|
||||
所有文档都在 [herdr.dev/docs](https://herdr.dev/zh-cn/docs/):[快速开始](https://herdr.dev/zh-cn/docs/quick-start/) · [核心概念](https://herdr.dev/zh-cn/docs/concepts/) · [受支持的智能体](https://herdr.dev/zh-cn/docs/agents/) · [键盘](https://herdr.dev/zh-cn/docs/keyboard/) · [配置](https://herdr.dev/zh-cn/docs/configuration/) · [会话状态](https://herdr.dev/zh-cn/docs/session-state/) · [远程访问](https://herdr.dev/zh-cn/docs/persistence-remote/) · [集成](https://herdr.dev/zh-cn/docs/integrations/) · [插件](https://herdr.dev/zh-cn/docs/plugins/) · [socket api](https://herdr.dev/zh-cn/docs/socket-api/)
|
||||
所有文档都在 [herdr.dev/docs](https://herdr.dev/zh-cn/docs/):[快速开始](https://herdr.dev/zh-cn/docs/quick-start/) · [核心概念](https://herdr.dev/zh-cn/docs/concepts/) · [受支持的智能体](https://herdr.dev/zh-cn/docs/agents/) · [键盘](https://herdr.dev/zh-cn/docs/keyboard/) · [配置](https://herdr.dev/zh-cn/docs/configuration/) · [会话状态](https://herdr.dev/zh-cn/docs/session-state/) · [连接机器](https://herdr.dev/zh-cn/docs/connecting-machines/) · [远程访问](https://herdr.dev/zh-cn/docs/persistence-remote/) · [集成](https://herdr.dev/zh-cn/docs/integrations/) · [插件](https://herdr.dev/zh-cn/docs/plugins/) · [socket api](https://herdr.dev/zh-cn/docs/socket-api/)
|
||||
|
||||
## 致谢
|
||||
|
||||
|
||||
@@ -73,9 +73,11 @@ herdr agent rename w1:p2 reviewer
|
||||
|
||||
Pane input addresses the terminal regardless of its current occupant. Agent input resolves the live agent and rejects the operation if that agent no longer controls the pane.
|
||||
|
||||
`agent prompt --wait` submits immediately unless the agent is already `blocked`, in which case it returns `agent_blocked` without starting the wait. If an accepted prompt starts from another non-working state, Herdr must observe `working` or `blocked` within five seconds. Otherwise, it returns `agent_prompt_stalled`; if the caller timeout expires first, it returns the normal `timeout` error. This prevents unrelated `idle`, `done`, or session changes from completing the wait. After Herdr observes activity, it waits for the requested settled status. It does not track individual turns. If the agent is already working, completion of that active turn may satisfy the wait. Standalone `agent wait` observes the current agent and returns immediately if its status already matches. Both commands default to `idle`, `done`, or `blocked`. Repeat `--until` to accept several exact states, for example `--until idle --until done`; use `--until unknown` explicitly when needed. On `agent prompt`, `--until` requires `--wait`.
|
||||
`agent prompt --wait` rejects an agent already `blocked` with `agent_blocked`, without sending input or starting a wait. Otherwise, it writes the prompt and delayed Enter as one ordered submission before waiting. For Codex on Windows, the delay grows with prompt size. The caller timeout includes submission time. If the prompt started from another non-working state, Herdr waits up to five seconds after submission to observe `working` or `blocked`. Otherwise, it returns `agent_prompt_stalled`; if the caller timeout expires first, it returns the normal `timeout` error. This prevents unrelated `idle`, `done`, or session changes from completing the wait. After Herdr observes activity, it waits for the requested settled status. It does not track individual turns. If the agent is already working, completion of that active turn may satisfy the wait. Standalone `agent wait` observes the current agent and returns immediately if its status already matches. Both commands default to `idle`, `done`, or `blocked`. Repeat `--until` to accept several exact states, for example `--until idle --until done`; use `--until unknown` explicitly when needed. On `agent prompt`, `--until` requires `--wait`.
|
||||
|
||||
`idle` means the agent is ready for input and its tab has been seen in the focused Herdr UI. `done` is the same underlying idle state after background work finishes, until that tab is focused or `pane focus` / `agent focus` targets it. Reading through the CLI does not mark it seen. `blocked` means Herdr recognized an approval or question UI. `unknown` means an agent is present but Herdr cannot classify its lifecycle confidently; it does not prove successful completion. Use exact `--until` states when that distinction matters.
|
||||
`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.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
@@ -11,13 +11,9 @@ Most commands print JSON responses for deterministic automation in scripts.
|
||||
|
||||
```bash
|
||||
herdr # launch or attach to the default session
|
||||
herdr --session work # launch or attach to a named session
|
||||
herdr --remote workbox # attach through SSH, using local keybindings
|
||||
herdr --remote workbox --remote-keybindings server
|
||||
herdr --remote workbox --handoff
|
||||
herdr --default-config # print default config
|
||||
herdr update # download and install from the configured channel
|
||||
herdr update --handoff # opt into live handoff for supported running servers
|
||||
herdr completion zsh # generate a zsh completion script
|
||||
herdr channel show # print stable or preview
|
||||
herdr channel set preview # opt into preview builds
|
||||
@@ -25,6 +21,12 @@ herdr channel set stable # return a direct install to stable
|
||||
herdr --version # print version
|
||||
```
|
||||
|
||||
Optional launch and update settings:
|
||||
|
||||
- Add `--session <name>` to use a named session instead of the default.
|
||||
- Add `--remote-keybindings server` to remote attach to use server keybindings instead of local ones.
|
||||
- Experimental live handoff requires explicit `--handoff` on `herdr --remote` or `herdr update`. It is not the normal setup or connection path; see [Updates](/docs/install/#update).
|
||||
|
||||
Status commands:
|
||||
|
||||
```bash
|
||||
@@ -48,19 +50,23 @@ with the installed binary. Use `--json` for the full JSON Schema document, or
|
||||
## Saved SSH machines
|
||||
|
||||
```bash
|
||||
herdr machine list [--json]
|
||||
herdr machine add workbox --label "Build machine" [--remote-session agents]
|
||||
herdr machine list
|
||||
herdr machine add workbox --label "Build machine"
|
||||
herdr machine rename <profile-id> --label "New name"
|
||||
herdr machine disable <profile-id>
|
||||
herdr machine enable <profile-id>
|
||||
herdr machine remove <profile-id>
|
||||
```
|
||||
|
||||
`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.
|
||||
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.
|
||||
|
||||
`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 --session agents`, to complete that setup in the foreground, then restart the client.
|
||||
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.
|
||||
|
||||
Workspace, tab, pane IDs, and agent names belong to a single server. Selecting a machine in the UI does not change the session or socket inherited by commands running in an existing pane. For remote automation, run the CLI on the intended host against the intended session and discover its IDs there.
|
||||
|
||||
## Shell completions
|
||||
|
||||
@@ -327,9 +333,9 @@ Agent targets are either a unique live agent name or the pane ID that currently
|
||||
|
||||
A successful start returns only after the expected agent owns the same terminal and is ready for interactive input. If detection reports `blocked` during startup, the command returns `agent_not_ready` immediately. The name remains available for `agent read` and `agent send-keys`, and becomes ready for prompts after detection reports `idle`. The default startup timeout is 30000 milliseconds; explicit values must be greater than 3000 and no more than 300000.
|
||||
|
||||
`agent prompt` honors live bracketed-paste mode and sends text followed by encoded Enter after a short delay, including while the agent is working. If the agent is already `blocked`, it returns `agent_blocked` without sending input. With `--wait`, an accepted prompt sent from another non-working state must produce an observed `working` or `blocked` state within five seconds or Herdr returns `agent_prompt_stalled`; if the caller timeout expires first, Herdr returns the normal `timeout` error. This prevents unrelated `idle`, `done`, or session changes from completing the wait. After activity is observed, it waits for the first requested settled status. It does not track individual turns. If the agent is already working, completion of that active turn may satisfy the wait. `--until` narrows the matching states and is rejected unless `--wait` is also present. Standalone `agent wait` returns immediately when the current status matches. Both default to `idle`, `done`, or `blocked`; use `--until unknown` explicitly when needed.
|
||||
`agent prompt` honors live bracketed-paste mode and writes text followed by delayed Enter as one ordered submission, including while the agent is working. Success without `--wait` acknowledges the writes, not the start of a turn. For Codex on Windows, the delay grows with prompt size; the caller timeout includes submission time. If the agent is already `blocked`, it returns `agent_blocked` without sending input. With `--wait`, a prompt sent from another non-working state has up to five seconds after submission to produce an observed `working` or `blocked` state or Herdr returns `agent_prompt_stalled`; if the caller timeout expires first, Herdr returns the normal `timeout` error. This prevents unrelated `idle`, `done`, or session changes from completing the wait. After activity is observed, it waits for the first requested settled status. It does not track individual turns. If the agent is already working, completion of that active turn may satisfy the wait. `--until` narrows the matching states and is rejected unless `--wait` is also present. Standalone `agent wait` returns immediately when the current status matches. Both default to `idle`, `done`, or `blocked`; use `--until unknown` explicitly when needed.
|
||||
|
||||
`idle` means ready for input after its tab has been seen in the focused Herdr UI; `done` is the same underlying idle state after unseen background work completes. Focusing that tab or targeting it with `pane focus` / `agent focus` marks it seen; reading it through the CLI does not. `blocked` means Herdr recognized an approval or question UI. `unknown` means an agent is present but Herdr cannot classify it confidently, not that its work succeeded.
|
||||
`idle` and `done` both mean 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 its Done badge can differ from the CLI or another client. `blocked` means Herdr recognized an approval or question UI. `unknown` means an agent is present but Herdr cannot classify it confidently, not that its work succeeded.
|
||||
|
||||
`agent send-keys` sends logical terminal keys such as `enter`, `up`, `esc`, or `ctrl+c`. Herdr validates every key before writing any bytes. `agent read` reads the resolved terminal stream, and `agent rename` names an already detected agent.
|
||||
|
||||
@@ -373,6 +379,8 @@ Use `pane wait-output` for normal commands and servers. Use `agent wait` for cod
|
||||
|
||||
`pane wait-output` checks the selected snapshot immediately, including output that already exists, then polls until it matches. The default source name is `recent`; matching treats it as unwrapped recent output from the latest 80 rendered terminal rows. `--lines` changes that row limit. `--match` finds a literal substring on one line, and `--regex` uses Rust regular-expression syntax and also matches one line at a time.
|
||||
|
||||
A timeout or `agent_prompt_stalled` does not prove the prompt was never delivered. Inspect the agent before retrying.
|
||||
|
||||
`pane wait-output` and `agent wait` wait indefinitely when `--timeout` is omitted. For `agent prompt --wait`, the settled-state wait is indefinite after activity is observed or when the prompt starts in `working`; a non-working prompt still returns `agent_prompt_stalled` after five seconds without observed activity. A timeout or server error is emitted as JSON on stderr with exit status 1. CLI usage errors exit with status 2.
|
||||
|
||||
## Integrations
|
||||
|
||||
@@ -48,6 +48,8 @@ Agent states are:
|
||||
| `idle` | The agent is finished or waiting and has been seen. |
|
||||
| `unknown` | Herdr cannot confidently classify the state. |
|
||||
|
||||
Each client tracks which completions it has displayed. Viewing a completion in one client does not clear another client's Done badge. CLI/API statuses use the server's seen state, so they need not match a particular client's badge; both `idle` and `done` mean ready for input.
|
||||
|
||||
## Session
|
||||
|
||||
A session is a persistent Herdr server namespace. The default `herdr` command attaches to the default session.
|
||||
|
||||
@@ -50,6 +50,8 @@ You can also open the global menu in Herdr and choose `reload config`.
|
||||
|
||||
Reload applies most UI settings without restarting panes. Startup-only settings still need a restart.
|
||||
|
||||
Themes, sidebar layouts, copy behavior, and other presentation settings come from the client's local config, including when viewing an SSH machine. Pane defaults, worktrees, integrations, and custom commands belong to the server where the panes run. The UI's `reload config` action reloads both the client's local settings and the selected server's config. Local keybindings reload too; `--remote-keybindings server` instead uses the selected server's keybindings.
|
||||
|
||||
## Headless terminal size
|
||||
|
||||
When no client is attached, the server uses a 120×40 virtual terminal for layout and newly created panes. Change that fallback for headless orchestration with:
|
||||
@@ -298,6 +300,8 @@ The active palette is applied in this order: built-in theme, `[theme.custom]`, t
|
||||
|
||||
The sidebar is the main Herdr dashboard. Search `ui.` in the [Config reference](/docs/config-reference/) for sizing, collapsed mode, Agent panel ordering, mouse behavior, pane borders, and other presentation settings.
|
||||
|
||||
`ui.pane_borders` accepts `"auto"` (the default, borders only for split panes), `"always"` (also frame a single pane), or `"off"`. A single-pane frame requires `ui.pane_outer_borders = true`, because all its edges are outer edges. Existing boolean values remain valid: `true` means `"auto"` and `false` means `"off"`.
|
||||
|
||||
Set `tab_bar_position = "bottom"` under `[ui]` to place the desktop tab row below the terminal panes. Prefix, Navigate, Copy, and Resize mode bars temporarily replace the bottom tab row while active. The default is `"top"`.
|
||||
|
||||
Configure an ordered tmux-style status area at the right edge of the tab row:
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
---
|
||||
title: Connecting machines
|
||||
description: Work across Local and saved SSH machines in one Herdr window, with shared agent navigation and independent reconnects.
|
||||
---
|
||||
|
||||
Keep your local work and remote agents in one Herdr window. Save an SSH machine once, then switch between its workspaces and Local without opening another client. The agent list includes connected machines, so you can see where work is running and which agent needs an answer.
|
||||
|
||||
Each machine keeps its own Herdr server, sessions, and running processes. A lost connection to one machine does not disconnect the others.
|
||||
|
||||
## Before you connect
|
||||
|
||||
You need normal SSH access to the remote machine. Verify it first:
|
||||
|
||||
```bash
|
||||
ssh workbox
|
||||
```
|
||||
|
||||
`workbox` can be a host from your SSH config. You can also use a target such as `ssh://you@server:2222`.
|
||||
|
||||
Multi-machine connections are supported on Linux and macOS clients, connecting to Linux and macOS servers on x86_64 or aarch64. Multi-machine connections are not yet verified or supported on Windows; standalone `herdr --remote` remains supported on Windows. Native Windows servers are not supported as SSH targets. See [Remote attach over SSH](/docs/persistence-remote/#remote-attach-over-ssh) for SSH configuration, authentication, and custom binaries.
|
||||
|
||||
## Add a machine
|
||||
|
||||
Run setup in an interactive terminal so Herdr can ask before installing or replacing anything:
|
||||
|
||||
```bash
|
||||
herdr machine add workbox --label "Build machine"
|
||||
```
|
||||
|
||||
This uses the remote default session. A machine profile targets one remote session; it does not combine every session on the host.
|
||||
|
||||
To use a named session instead, add the optional `--remote-session` flag:
|
||||
|
||||
```bash
|
||||
herdr machine add workbox --label "Build machine" --remote-session agents
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
## Switch between machines
|
||||
|
||||
Choose a machine or one of its workspaces in the sidebar. The selected machine receives your pane input and terminal size, and supplies the visible terminal content and graphics. Other connected machines keep updating their workspace information, agent states, and notifications without streaming their pane screens.
|
||||
|
||||
Local opens immediately on startup without waiting for SSH connections. A stalled machine cannot hold up another machine's input. Multiple Herdr clients can also view different tabs on the same server independently; see [Client and server](/docs/concepts/#client-and-server) for shared-tab sizing.
|
||||
|
||||
When a connection is lost, the last workspace and agent state remains visible but dimmed. That is cached information, not live state. Input and navigation into those cached panes stay disabled until a fresh connection and matching screen arrive. Reconnecting never takes selection away from the machine you are using.
|
||||
|
||||
## Rename, disable, or remove
|
||||
|
||||
Read profile IDs from the list rather than deriving them from labels or hostnames:
|
||||
|
||||
```bash
|
||||
herdr machine list
|
||||
herdr machine rename <profile-id> --label "New name"
|
||||
herdr machine disable <profile-id>
|
||||
herdr machine enable <profile-id>
|
||||
herdr machine remove <profile-id>
|
||||
```
|
||||
|
||||
For scripts, add `--json` to `machine list`.
|
||||
|
||||
Renaming changes the displayed label without reconnecting. Disabling keeps the profile for later; removing forgets it. Both disconnect only that machine from the client and leave its remote sessions and agents running, even if the host is unreachable.
|
||||
|
||||
Removing or disabling the machine you are viewing returns you to Local. If Local is unavailable, Herdr shows that and retries its connection instead of selecting a different remote machine. With enabled saved machines, the client can remain usable even if Local fails or restarts.
|
||||
|
||||
## Connection problems
|
||||
|
||||
- **Reconnecting:** Herdr retries with bounded backoff after a network interruption, sleep, or SSH failure. 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.
|
||||
- **Saved-machine file error:** An unreadable or invalid catalog leaves current connections unchanged. Herdr shows a notice and automatically retries reading it.
|
||||
|
||||
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:
|
||||
|
||||
```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.
|
||||
|
||||
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.
|
||||
|
||||
## 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).
|
||||
|
||||
Default agent rows show a `machine` token when multiple machines are present. Existing custom rows are preserved; add `machine` explicitly if you want that label in your layout. [Sidebar row layouts](/docs/configuration/#sidebar-row-layouts) also support conditional colors for machine labels.
|
||||
|
||||
Workspace, tab, pane IDs, and agent names are scoped to one server. Two machines may both contain `w1:p1` or an agent named `reviewer`. Selecting a machine in the UI does not retarget CLI commands running in an existing pane: they still use that pane's inherited session and socket. For remote automation, run commands on the intended host against the intended session and read its IDs there.
|
||||
|
||||
## Updates and saved data
|
||||
|
||||
Saved profiles contain only an opaque ID, label, SSH target, explicit remote session, and enabled state. Herdr does not store passwords, private keys, agent tickets, or SSH control sockets in the catalog. Authentication stays with OpenSSH.
|
||||
|
||||
The client and server negotiate compatibility rather than requiring identical versions. Saved-machine connections additionally need the server's `surface_interest` and `health_check` capabilities. Older servers without those capabilities show Attention until explicitly updated, even if a standalone attach works. Other missing server methods disable only their corresponding actions.
|
||||
|
||||
Updating a compatible client does not replace the running remote server or stop its agents. When you need new server-side behavior, update that server explicitly. Normal replacement asks before stopping the server and its pane processes.
|
||||
|
||||
Live handoff is experimental and opt-in. For a supported server that needs replacement during standalone setup, you can explicitly add `--handoff` to `herdr --remote`; it is not needed for normal connections or authentication fixes. See [Update](/docs/install/#update) for restart and handoff choices, and [Session state and restore](/docs/session-state/) for what survives each operation.
|
||||
@@ -77,7 +77,7 @@ herdr --remote workbox
|
||||
herdr --remote ssh://you@server:2222
|
||||
```
|
||||
|
||||
Your local Herdr acts as a thin client. It connects over SSH, starts or attaches to the remote Herdr server, and streams the UI back to your local terminal.
|
||||
The remote server keeps the panes running and sends their terminal content and session state over SSH. Your local Herdr draws the UI using your local theme and presentation settings.
|
||||
|
||||
Use this path when you want the remote session to feel local. The client runs on your machine, so local desktop features such as image clipboard paste can be bridged to the remote server. If you SSH first and run `herdr` on the server, Herdr runs entirely on that server and cannot read your local desktop clipboard.
|
||||
|
||||
@@ -98,6 +98,6 @@ herdr --remote workbox
|
||||
|
||||
## Which path to use
|
||||
|
||||
Use `herdr` for local work. Use `ssh you@server` then `herdr` when you want Herdr to behave like tmux on that remote shell or when you are using a phone SSH client. Use `herdr --remote <host>` when you want a local thin client for a remote session, including local clipboard image paste bridging.
|
||||
Use `herdr` for local work. Use `ssh you@server` then `herdr` when you want Herdr to behave like tmux on that remote shell or when you are using a phone SSH client. Use `herdr --remote <host>` for a local UI attached to one remote session, including local clipboard image paste. To keep Local and several SSH machines in one window, save them with `herdr machine add <host> --label <label>`; see [Connecting machines](/docs/connecting-machines/).
|
||||
|
||||
For remote bootstrap details, named remote sessions, custom binaries, and direct terminal attach, see [Persistence and remote access](/docs/persistence-remote/).
|
||||
|
||||
@@ -49,6 +49,11 @@ The guide covers Herdr's concepts, setup, configuration, and common fixes, so yo
|
||||
|
||||
[Understand agents →](/docs/agents/)
|
||||
</Card>
|
||||
<Card title="Connecting machines">
|
||||
Keep Local and saved SSH machines in one window, with a combined agent list and independent reconnects.
|
||||
|
||||
[Connect your machines →](/docs/connecting-machines/)
|
||||
</Card>
|
||||
<Card title="Session state">
|
||||
Understand detach, restart restore, pane history replay, native agent resume, and live handoff.
|
||||
|
||||
|
||||
@@ -73,9 +73,11 @@ herdr agent rename w1:p2 reviewer
|
||||
|
||||
ペイン入力は、現在のプロセスに関係なくターミナルを指定します。エージェント入力はライブエージェントを解決し、そのエージェントがペインを制御しなくなっていれば操作を拒否します。
|
||||
|
||||
`agent prompt --wait` は、エージェントがすでに `blocked` でない限り、プロンプトをすぐ送信します。すでに `blocked` の場合は待機を開始せずに `agent_blocked` を返します。受け付けたプロンプトが別の non-working 状態から始まる場合、Herdr は 5 秒以内に `working` または `blocked` を観測する必要があります。観測できなければ `agent_prompt_stalled` を返し、呼び出し側のタイムアウトが先に切れた場合は通常の `timeout` エラーを返します。これにより、無関係な `idle`、`done`、またはセッションの変化によって待機が誤って完了することを防ぎます。活動を観測した後、要求された安定状態を待ちます。個々のターンは追跡しません。エージェントがすでに working の場合、進行中ターンの完了が待機を満たすことがあります。単独の `agent wait` は現在のエージェントを監視し、すでに状態が一致していれば即座に返ります。どちらもデフォルトでは `idle`、`done`、`blocked` を待ちます。複数の正確な状態を許可するには、`--until idle --until done` のように `--until` を繰り返します。`unknown` が必要な場合は `--until unknown` を明示してください。`agent prompt` では `--until` に `--wait` が必要です。
|
||||
`agent prompt --wait` は、エージェントがすでに `blocked` の場合、入力も待機も開始せずに `agent_blocked` を返します。それ以外は、プロンプトと遅延した Enter を順序付きの 1 回の送信として書き込んでから待機します。Windows の Codex では、プロンプトのサイズに応じて遅延が長くなります。呼び出し側のタイムアウトには送信時間も含まれます。別の non-working 状態から始まった場合、送信後に最大 5 秒間、`working` または `blocked` を観測するまで待ちます。観測できなければ `agent_prompt_stalled` を返し、呼び出し側のタイムアウトが先に切れた場合は通常の `timeout` エラーを返します。これにより、無関係な `idle`、`done`、またはセッションの変化によって待機が誤って完了することを防ぎます。活動を観測した後、要求された安定状態を待ちます。個々のターンは追跡しません。エージェントがすでに working の場合、進行中ターンの完了が待機を満たすことがあります。単独の `agent wait` は現在のエージェントを監視し、すでに状態が一致していれば即座に返ります。どちらもデフォルトでは `idle`、`done`、`blocked` を待ちます。複数の正確な状態を許可するには、`--until idle --until done` のように `--until` を繰り返します。`unknown` が必要な場合は `--until unknown` を明示してください。`agent prompt` では `--until` に `--wait` が必要です。
|
||||
|
||||
`idle` は、エージェントが入力待ちで、そのタブがフォーカス中の Herdr UI ですでに表示済みであることを示します。`done` は同じ基礎的な idle 状態ですが、バックグラウンド作業が完了してから、そのタブをフォーカスするか `pane focus` / `agent focus` で対象にするまで使われます。CLI で読み取るだけでは表示済みになりません。`blocked` は承認または質問 UI を Herdr が認識した状態です。`unknown` はエージェントが存在するもののライフサイクルを確実に分類できない状態で、成功完了を意味しません。違いが重要なら正確な `--until` を指定してください。
|
||||
`idle` と `done` はどちらも入力可能な状態です。CLI/API はサーバーの既読状態を使い、未確認の idle を `done` とします。明示的な `pane focus` / `agent focus` は対象を既読にしますが、読み取りでは変わりません。各 TUI クライアントは表示済みの完了を独立して管理するため、Done バッジが CLI やほかのクライアントと異なる場合があります。`blocked` は承認または質問 UI を Herdr が認識した状態です。`unknown` はエージェントが存在するもののライフサイクルを確実に分類できない状態で、成功完了を意味しません。違いが重要なら正確な `--until` を指定してください。
|
||||
|
||||
タイムアウトや `agent_prompt_stalled` は、入力が送られていないことを保証しません。二重送信を避けるため、再試行の前にエージェントを読み取ってください。ID とエージェント名はサーバーごとに独立しています。TUI で別のマシンを選んでも、既存ペイン内の CLI コマンドの接続先は変わりません。
|
||||
|
||||
`pane wait-output` はエージェントのライフサイクルを解釈しません。選択したターミナルスナップショットをポーリングし、最初にすぐ検索するため、すでに存在する文字列も一致します。デフォルトのソース名は `recent` で、直近 80 行の描画済みターミナル行を折り返し前の出力として扱います。`--lines` でその行数を変更でき、`--regex` は Rust の正規表現構文で 1 行ずつ一致します。
|
||||
|
||||
|
||||
@@ -11,13 +11,9 @@ Herdr の CLI は、インテグレーションやエージェントが使うの
|
||||
|
||||
```bash
|
||||
herdr # デフォルトセッションを起動またはアタッチ
|
||||
herdr --session work # 名前付きセッションを起動またはアタッチ
|
||||
herdr --remote workbox # SSH 越しにアタッチ (ローカルのキーバインドを使用)
|
||||
herdr --remote workbox --remote-keybindings server
|
||||
herdr --remote workbox --handoff
|
||||
herdr --default-config # デフォルト設定を表示
|
||||
herdr update # 設定済みチャンネルからダウンロードしてインストール
|
||||
herdr update --handoff # 対応する実行中サーバーでライブハンドオフにオプトイン
|
||||
herdr completion zsh # zsh 補完スクリプトを生成
|
||||
herdr channel show # stable または preview を表示
|
||||
herdr channel set preview # プレビュービルドにオプトイン
|
||||
@@ -25,6 +21,12 @@ herdr channel set stable # 直接インストールを安定版に戻す
|
||||
herdr --version # バージョンを表示
|
||||
```
|
||||
|
||||
起動と更新の任意オプション:
|
||||
|
||||
- デフォルトではなく名前付きセッションを使う場合は `--session <name>` を追加します。
|
||||
- リモート接続でサーバーのキーバインドを使う場合は `--remote-keybindings server` を追加します。
|
||||
- 実験的なライブハンドオフには、`herdr --remote` または `herdr update` で明示的な `--handoff` が必要です。通常のセットアップや接続には使いません。[更新](/ja/docs/install/)を参照してください。
|
||||
|
||||
ステータスコマンド:
|
||||
|
||||
```bash
|
||||
@@ -46,19 +48,23 @@ herdr api schema --output herdr-api.schema.json
|
||||
## 保存済み SSH マシン
|
||||
|
||||
```bash
|
||||
herdr machine list [--json]
|
||||
herdr machine add workbox --label "Build machine" [--remote-session agents]
|
||||
herdr machine list
|
||||
herdr machine add workbox --label "Build machine"
|
||||
herdr machine rename <profile-id> --label "New name"
|
||||
herdr machine disable <profile-id>
|
||||
herdr machine enable <profile-id>
|
||||
herdr machine remove <profile-id>
|
||||
```
|
||||
|
||||
`machine add` はリモート側の Herdr が必要な機能を備えているか確認し、必要な場合だけ承認を得てインストールまたは更新します。指定したセッションのバックグラウンドサーバーを起動してからプロファイルを保存します。互換性があればリリースバージョンは一致しなくてもかまいません。インストールや再起動の承認が必要な場合は、対話型ターミナルで実行してください。セットアップが失敗またはキャンセルされた場合、プロファイルは保存されません。
|
||||
`machine add` はリモートのデフォルトセッションを使います。名前付きセッションを使う場合だけ `--remote-session <name>` を追加します。スクリプトでは `machine list` に `--json` を追加できます。詳しくは[マシンへの接続](/ja/docs/connecting-machines/)を参照してください。
|
||||
|
||||
`machine add` はリモート側の Herdr が必要な機能を備えているか確認し、必要な場合だけ承認を得てインストールまたは更新します。指定したセッションのバックグラウンドサーバーを起動してからプロファイルを保存します。互換性があればリリースバージョンは一致しなくてもかまいません。インストールや再起動の承認が必要な場合は、対話型ターミナルで実行してください。セットアップが失敗またはキャンセルされた場合、プロファイルは保存されません。実行中サーバーの置き換えには明示的な承認が必要で、デフォルトの回答は No です。停止するとペインのプロセスも終了します。`machine add` は実験的なハンドオフを暗黙に有効にしません。
|
||||
|
||||
変更は、開いているローカルの Herdr クライアントに通常 1 秒以内に自動反映されます。追加または有効化したマシンにはバックグラウンドで接続し、名前の変更では再接続しません。削除または無効化すると、そのマシンだけが切断され、リモートセッションは動き続けます。表示中のマシンを削除すると Local に戻ります。Local に接続できない場合は、再接続するまで利用不可と表示します。各プロファイルは、不透明な ID、ラベル、SSH 接続先、明示的なリモートセッション名、有効状態をクライアントの状態ファイルに保存します。パスワード、秘密鍵、その他の SSH 認証情報は保存しません。
|
||||
|
||||
自動接続と再接続は非対話型です。ホスト鍵、パスワード、鍵のパスフレーズ、MFA、インストール、更新、再起動に承認が必要な場合、隠れたプロンプトを開くのではなく Attention と表示します。`herdr --remote workbox --session agents` など、Herdr が表示する単独接続用のコマンドを実行してフォアグラウンドでセットアップを完了し、クライアントを再起動してください。
|
||||
自動接続と再接続は非対話型です。ホスト鍵、パスワード、鍵のパスフレーズ、MFA、インストール、更新、再起動に承認が必要な場合、隠れたプロンプトを開くのではなく Attention と表示します。`herdr --remote workbox` など、Herdr が表示する単独接続用のコマンドを実行してフォアグラウンドでセットアップを完了し、クライアントを再起動してください。名前付きセッションを選んだプロファイルにだけ `--session <name>` を追加します。
|
||||
|
||||
ワークスペース、タブ、ペインの ID とエージェント名は、1 つのサーバー内だけで有効です。UI でマシンを選んでも、既存ペイン内のコマンドが継承するセッションやソケットは変わりません。リモート自動化では対象ホスト上の対象セッションに対して CLI を実行し、そこで ID を取得してください。
|
||||
|
||||
## シェル補完
|
||||
|
||||
@@ -307,9 +313,9 @@ herdr agent explain --file PATH --agent LABEL [--json|--verbose]
|
||||
|
||||
成功した start は、期待したエージェントが同じターミナルを所有し、対話入力の準備ができてから返ります。起動中の検出状態が `blocked` の場合、コマンドは直ちに `agent_not_ready` を返します。名前は `agent read` と `agent send-keys` で引き続き使用でき、検出状態が `idle` になるとプロンプトを送信できるようになります。デフォルトの起動タイムアウトは 30000 ミリ秒で、明示する値は 3000 より大きく 300000 以下でなければなりません。
|
||||
|
||||
`agent prompt` は現在の bracketed paste モードを尊重し、working 中でもテキストを送信してから短い遅延の後にエンコード済み Enter を送信します。エージェントがすでに `blocked` の場合は、入力を送信せずに `agent_blocked` を返します。`--wait` を使う場合、別の non-working 状態から受け付けたプロンプトでは、5 秒以内に `working` または `blocked` が観測される必要があります。観測できなければ Herdr は `agent_prompt_stalled` を返し、呼び出し側のタイムアウトが先に切れた場合は通常の `timeout` エラーを返します。これにより、無関係な `idle`、`done`、またはセッションの変化によって待機が誤って完了することを防ぎます。活動を観測した後、要求された最初の安定状態を待ちます。個々のターンは追跡しません。すでに working の場合、進行中ターンの完了が待機を満たすことがあります。`--until` は一致状態を絞り込み、`--wait` なしでは拒否されます。単独の `agent wait` は現在の状態が一致すれば即座に返ります。どちらもデフォルトは `idle`、`done`、`blocked` です。
|
||||
`agent prompt` は現在の bracketed paste モードを尊重し、working 中でもテキストと遅延した Enter を順序付きの 1 回の送信として書き込みます。`--wait` なしの成功は書き込みの完了を示し、ターンの開始を保証しません。Windows の Codex では、プロンプトのサイズに応じて遅延が長くなります。呼び出し側のタイムアウトには送信時間も含まれます。エージェントがすでに `blocked` の場合は、入力を送信せずに `agent_blocked` を返します。`--wait` を使う場合、別の non-working 状態から受け付けたプロンプトでは、送信後の最大 5 秒間に `working` または `blocked` が観測される必要があります。観測できなければ Herdr は `agent_prompt_stalled` を返し、呼び出し側のタイムアウトが先に切れた場合は通常の `timeout` エラーを返します。これにより、無関係な `idle`、`done`、またはセッションの変化によって待機が誤って完了することを防ぎます。活動を観測した後、要求された最初の安定状態を待ちます。個々のターンは追跡しません。すでに working の場合、進行中ターンの完了が待機を満たすことがあります。`--until` は一致状態を絞り込み、`--wait` なしでは拒否されます。単独の `agent wait` は現在の状態が一致すれば即座に返ります。どちらもデフォルトは `idle`、`done`、`blocked` です。
|
||||
|
||||
`idle` は入力待ちで、そのタブがフォーカス中の Herdr UI ですでに表示済みの状態です。`done` は同じ基礎的な idle 状態ですが、表示していないバックグラウンド作業が完了したときに使われます。そのタブをフォーカスするか `pane focus` / `agent focus` で対象にすると表示済みになりますが、CLI で読み取るだけでは変わりません。`blocked` は承認または質問 UI を Herdr が認識した状態です。`unknown` はエージェントが存在するものの確実に分類できない状態で、作業の成功を意味しません。
|
||||
`idle` と `done` はどちらも入力可能な状態です。CLI/API はサーバーの既読状態を使い、未確認の idle を `done` とします。明示的な `pane focus` / `agent focus` は対象を既読にしますが、読み取りでは変わりません。各 TUI クライアントは表示済みの完了を独立して管理するため、Done バッジが CLI やほかのクライアントと異なる場合があります。`blocked` は承認または質問 UI を Herdr が認識した状態です。`unknown` はエージェントが存在するものの確実に分類できない状態で、作業の成功を意味しません。
|
||||
|
||||
`agent send-keys` は `enter`、`up`、`esc`、`ctrl+c` などの論理キーを送ります。Herdr は 1 バイトも書き込む前に全キーを検証します。`agent read` は解決されたターミナルストリームを読み、`agent rename` は検出済みエージェントに名前を付けます。
|
||||
|
||||
@@ -340,6 +346,8 @@ herdr pane wait-output <pane_id> (--match <text> | --regex <pattern>) [--source
|
||||
|
||||
`pane wait-output` は選択したスナップショットを最初にすぐ検索するため、すでに存在する出力も一致します。デフォルトのソース名は `recent` で、直近 80 行の描画済みターミナル行を折り返し前の出力として扱います。`--lines` でその行数を変更できます。`--match` は 1 行内のリテラル部分文字列を検索し、`--regex` は Rust の正規表現構文で 1 行ずつ一致します。
|
||||
|
||||
タイムアウトや `agent_prompt_stalled` は未送信を保証しません。再試行前にエージェントを確認してください。
|
||||
|
||||
`pane wait-output` と `agent wait` は、`--timeout` を省略すると無期限に待ちます。`agent prompt --wait` では、活動を観測した後、またはプロンプト開始時に `working` だった場合の安定状態待機は無期限です。non-working 状態から開始して活動を観測できない場合は、5 秒後に `agent_prompt_stalled` を返します。タイムアウトまたはサーバーエラーは JSON として stderr に出力され、終了コード 1 になります。CLI 使用法のエラーは終了コード 2 です。
|
||||
|
||||
## インテグレーション
|
||||
|
||||
@@ -48,6 +48,8 @@ mouse_capture = false
|
||||
| `idle` | エージェントが完了または待機していて、確認済み。 |
|
||||
| `unknown` | Herdr が状態を確信を持って分類できない。 |
|
||||
|
||||
各クライアントは表示した完了を独立して管理します。あるクライアントで完了を見ても、ほかのクライアントの Done バッジは消えません。CLI/API はサーバーの既読状態を使うため、特定のクライアントのバッジと一致するとは限りません。`idle` と `done` はどちらも入力可能な状態です。
|
||||
|
||||
## セッション
|
||||
|
||||
セッションは永続的な Herdr サーバーの名前空間です。デフォルトの `herdr` コマンドはデフォルトセッションにアタッチします。
|
||||
|
||||
@@ -50,6 +50,8 @@ Herdr のグローバルメニューを開いて `reload config` を選ぶこと
|
||||
|
||||
リロードは、ペインを再起動せずにほとんどの UI 設定を適用します。起動時のみの設定には引き続き再起動が必要です。
|
||||
|
||||
テーマ、サイドバーのレイアウト、コピー動作などの表示設定は、SSH マシンを表示している場合もクライアントのローカル設定から読み込みます。ペインのデフォルト、worktree、インテグレーション、カスタムコマンドは、ペインが動くサーバー側の設定です。UI の `reload config` は、クライアントのローカル設定と選択中サーバーの設定を両方リロードします。ローカルキーバインドも反映されます。`--remote-keybindings server` を指定した場合は、選択中サーバーのキーバインドを使います。
|
||||
|
||||
## ヘッドレスターミナルのサイズ
|
||||
|
||||
クライアントが接続されていない場合、サーバーはレイアウトと新しく作成されるペインに 120×40 の仮想ターミナルを使います。ヘッドレスオーケストレーション用のフォールバックは次のように変更できます:
|
||||
@@ -294,6 +296,8 @@ text = "#cdd6f4"
|
||||
|
||||
サイドバーは Herdr のメインダッシュボードです。サイズ、折りたたみモード、Agent パネルの並び順、マウスの挙動、ペインの境界線、その他の表示設定については、[設定リファレンス](/docs/config-reference/)で `ui.` を検索してください。
|
||||
|
||||
`ui.pane_borders` は `"auto"`(デフォルト。分割ペインだけに境界線を表示)、`"always"`(単独ペインにも枠を表示)、`"off"` を受け付けます。単独ペインの辺はすべて外側の辺なので、枠を表示するには `ui.pane_outer_borders = true` も必要です。従来の真偽値も有効で、`true` は `"auto"`、`false` は `"off"` に対応します。
|
||||
|
||||
`[ui]` の `tab_bar_position = "bottom"` を設定すると、デスクトップのタブ行をターミナルペインの下に配置できます。Prefix、Navigate、Copy、Resize の各モードバーは、表示中だけ下部のタブ行を置き換えます。デフォルトは `"top"` です。
|
||||
|
||||
タブ行の右端に、tmux のような順序付きステータス領域を設定できます:
|
||||
@@ -312,7 +316,7 @@ tab_bar_right_separator = " · "
|
||||
|
||||
ステータス領域はデフォルトでは空です。`zoom` を追加すると、アクティブなタブがズーム中のとき固定の `ZOOM` ピルが表示されます。各タブの既存の `Z` マーカーとは独立しています。`hostname`、`datetime`、`command` は Herdr サーバー上で解決されるため、`herdr --remote` ではリモートマシンの値が表示されます。日時エントリは `strftime` 形式を使います。`%z` や `%s` のように UTC オフセットまたは Unix タイムスタンプを必要とする指定子は、値がサーバーローカルの壁時計時刻であるため拒否されます。
|
||||
|
||||
コマンドエントリはすぐに実行され、その後 `interval_seconds` ごとに更新されます。描画をブロックせず、前回の実行と重複しません。間隔は 1〜31,536,000 秒、タイムアウトは 1〜3,600 秒です。Herdr は成功した出力の最終行を使い、失敗、空の出力、`timeout_seconds` 経過後には値を消去します。カスタムコマンドキーバインドと同じアクティブなワークスペース、タブ、ペイン、ソケット、バイナリ、作業ディレクトリのコンテキストが提供されます。コマンドは Linux、macOS、Windows で利用でき、Linux と macOS では `/bin/sh -lc`、Windows では `cmd.exe /d /c` が使われます。
|
||||
コマンドエントリはすぐに実行され、その後 `interval_seconds` ごとに更新されます。描画をブロックせず、前回の実行と重複しません。間隔は 1〜31,536,000 秒、タイムアウトは 1〜3,600 秒です。Herdr は成功した出力の最終行を使い、ESC で始まるターミナル制御シーケンスは装飾として解釈せずに除去します。失敗、空の出力、`timeout_seconds` 経過後には値を消去します。カスタムコマンドキーバインドと同じアクティブなワークスペース、タブ、ペイン、ソケット、バイナリ、作業ディレクトリのコンテキストが提供されます。コマンドは Linux、macOS、Windows で利用でき、Linux と macOS では `/bin/sh -lc`、Windows では `cmd.exe /d /c` が使われます。
|
||||
|
||||
区切り文字は、表示されているエントリの間にだけ挿入されます。直接連結するには `tab_bar_right_separator = ""` を設定します。タブ行が狭い場合、ステータス領域全体がタブとそのコントロールに場所を譲ります。
|
||||
|
||||
@@ -396,6 +400,25 @@ rows = [
|
||||
|
||||
`fg` は厳密な `#RGB` または `#RRGGBB`、`bold` と `dim` は真偽値です。省略したフィールドはコンテキストのスタイルを保持し、明示的な `false` はその修飾を解除します。スタイルは 1 つの出現箇所だけに適用されます。`fg` を指定した `git_status` では、既定の緑/赤ではなく ahead と behind の両方が同じ色になります。区切りと行の背景は変更されません。
|
||||
|
||||
テキスト値のトークンには、順序付きの `rules` を最大 16 個指定できます。各ルールには `equals`、`contains`、`starts_with`、`gt`、`lt` のいずれか 1 つの条件と、任意の `fg`、`bold`、`dim` 上書きを指定します:
|
||||
|
||||
```toml
|
||||
[ui.sidebar.agents]
|
||||
rows = [
|
||||
["state_icon", "workspace", "tab"],
|
||||
[{ token = "machine", fg = "#fff", rules = [{ equals = "Local", fg = "#f55" }, { equals = "Fedora", ignore_case = true, fg = "#51a2da" }] }, "agent"],
|
||||
[{ token = "$load", fg = "#fff", rules = [{ gt = 80, fg = "#f55", bold = true }, { gt = 50, fg = "#fc0" }] }],
|
||||
]
|
||||
```
|
||||
|
||||
最初に一致したルールだけを適用します。指定されたスタイルはその出現箇所のデフォルトを上書きし、省略したフィールドは継承します。一致しなければデフォルトを保ちます。判定には表示幅で切り詰める前の値全体を使い、テキスト、区切り、表示の有無は変更しません。スタイルを指定しないルールに一致すると、そこで判定を終了してデフォルトを保ちます。
|
||||
|
||||
`equals`、`contains`、`starts_with` は文字列を受け取り、大文字と小文字を区別します。`ignore_case = true` は ASCII だけを区別しなくなり、非 ASCII 文字は引き続き区別します。空文字列の `equals` は空の値だけに一致し、空の `contains` と `starts_with` は存在するすべての値に一致します。
|
||||
|
||||
`gt` と `lt` は有限の数値を閾値とし、等しい値は含みません。値全体が有限の数値として解析できる必要があり、小数と指数表記は使えますが、空白、単位、`NaN`、無限大は一致しません。数値ルールに `ignore_case` は指定できません。比較は浮動小数点で行い、大きな整数の厳密な比較には使えません。
|
||||
|
||||
ルールは Agent 行、`rows_by_agent` の上書き、Space 行のテキスト値の組み込みトークンとカスタム `$name` トークンに使えます。上の例では `$load` が `"90"` なら赤の太字、`"60"` なら黄色、`"90%"` なら白のままです。未報告のトークンは表示されません。`state_icon` と複合トークン `git_status` は固定スタイルだけを受け付け、ルールは使えません。不明な条件や不正なルールは設定読み込み時に拒否します。正規表現、あいまい一致、スクリプトには対応しません。
|
||||
|
||||
`row_gap` は、Agent パネルと Space パネルごとに、エントリ間の空白行数を指定します。デフォルトは `0` で、エントリを詰めて表示します。以前の間隔に戻すには `1` に設定します。`rows` で定義したコンテンツ行の間隔には影響しません。連続するインデントされた worktree の子は、1 つの Space グループとして詰めて表示されます。
|
||||
|
||||
既知のエージェントについて Agent の完全なレイアウトを上書きするには、`rows_by_agent` を使います:
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
---
|
||||
title: マシンへの接続
|
||||
description: Local と保存済み SSH マシンを 1 つの Herdr ウィンドウで操作し、エージェントをまとめて確認できます。各接続は独立して再接続します。
|
||||
---
|
||||
|
||||
ローカルの作業とリモートのエージェントを、1 つの Herdr ウィンドウにまとめられます。SSH マシンを一度保存すれば、別のクライアントを開かずに、そのワークスペースと Local を切り替えられます。エージェント一覧には接続中のマシンが含まれ、作業場所や回答待ちのエージェントを確認できます。
|
||||
|
||||
各マシンは独自の Herdr サーバー、セッション、プロセスを保持します。1 台への接続が切れても、ほかの接続は切れません。
|
||||
|
||||
## 接続前の確認
|
||||
|
||||
リモートマシンへの通常の SSH アクセスが必要です。最初に確認してください:
|
||||
|
||||
```bash
|
||||
ssh workbox
|
||||
```
|
||||
|
||||
`workbox` は SSH config のホスト名です。`ssh://you@server:2222` のような接続先も使えます。
|
||||
|
||||
複数マシンへの接続は Linux と macOS のクライアントで対応しており、x86_64 または aarch64 の Linux と macOS サーバーに接続できます。Windows での複数マシンへの接続は未検証・未対応です。単独接続の `herdr --remote` は引き続き Windows でも対応しています。ネイティブ Windows サーバーは SSH 接続先として未対応です。SSH 設定、認証、カスタムバイナリについては [SSH 越しのリモートアタッチ](/ja/docs/persistence-remote/)を参照してください。
|
||||
|
||||
## マシンを追加する
|
||||
|
||||
インストールや置き換えの前に確認できるよう、対話型ターミナルで実行します:
|
||||
|
||||
```bash
|
||||
herdr machine add workbox --label "Build machine"
|
||||
```
|
||||
|
||||
リモートのデフォルトセッションを使います。1 つのプロファイルは 1 つのリモートセッションを対象とし、そのホストの全セッションをまとめるものではありません。
|
||||
|
||||
名前付きセッションを使いたい場合だけ、任意の `--remote-session` を追加します:
|
||||
|
||||
```bash
|
||||
herdr machine add workbox --label "Build machine" --remote-session agents
|
||||
```
|
||||
|
||||
Herdr はインストール済みバイナリと実行中サーバーをそれぞれ確認し、対象のバックグラウンドサーバーを起動してからプロファイルを保存します。互換性があればクライアントとサーバーのバージョンは一致しなくても構いません。未インストールや非互換の場合は、承認付きのセットアップを行います。実行中サーバーの置き換えが必要なら、サーバーとペインのプロセスを停止する前に確認し、その後に互換サーバーを起動します。デフォルトの回答は No です。インストールと置き換えの両方が必要な場合は、1 回の確認で承認します。`machine add` は実験的なライブハンドオフを使いません。セットアップをキャンセルした場合や失敗した場合、プロファイルは保存されません。
|
||||
|
||||
`herdr` で UI を開きます。ローカルクライアントがすでに開いていれば、追加や有効化したマシンは通常 1 秒以内に表示され、選択を変えずにバックグラウンドで接続します。マシン切り替え中の変更は、切り替えの完了後に反映します。セットアップ終了後もリモートサーバーは動き続けます。
|
||||
|
||||
## マシンを切り替える
|
||||
|
||||
サイドバーでマシンまたはそのワークスペースを選びます。選択中のマシンだけがペイン入力とターミナルサイズを受け取り、表示するターミナル内容とグラフィックスを送信します。ほかの接続済みマシンは、ペイン画面を送らずにワークスペース情報、エージェント状態、通知を更新し続けます。
|
||||
|
||||
起動時は SSH 接続を待たずに Local を開きます。応答しないマシンがほかのマシンの入力を妨げることはありません。同じサーバーに接続した複数のクライアントは、それぞれ別のタブを表示できます。同じタブを表示した場合のサイズについては[クライアントとサーバー](/ja/docs/concepts/)を参照してください。
|
||||
|
||||
接続が切れると、最後のワークスペースとエージェント状態を暗く表示します。これはキャッシュであり、現在の状態ではありません。新しい接続と対応する画面が届くまで、そのペインへの入力や移動は無効です。再接続しても、使用中のマシンから選択を奪いません。
|
||||
|
||||
## 名前の変更、無効化、削除
|
||||
|
||||
ラベルやホスト名から推測せず、一覧からプロファイル ID を取得します:
|
||||
|
||||
```bash
|
||||
herdr machine list
|
||||
herdr machine rename <profile-id> --label "New name"
|
||||
herdr machine disable <profile-id>
|
||||
herdr machine enable <profile-id>
|
||||
herdr machine remove <profile-id>
|
||||
```
|
||||
|
||||
スクリプトでは `machine list` に `--json` を追加できます。
|
||||
|
||||
名前の変更は表示ラベルだけを更新し、再接続しません。無効化はプロファイルを残し、削除はプロファイルを忘れます。どちらもクライアントからそのマシンだけを切断し、到達不能なホストでも操作できます。リモートセッションとエージェントは動き続けます。
|
||||
|
||||
表示中のマシンを削除または無効化すると Local に戻ります。Local が利用できない場合は、別のリモートを選ばず、その状態を表示して再接続します。有効な保存済みマシンがあれば、Local が失敗または再起動してもクライアントを使い続けられます。
|
||||
|
||||
## 接続の問題
|
||||
|
||||
- **Reconnecting:** ネットワーク中断、スリープ、SSH 障害の後は、上限のある待機間隔で再試行します。SSH 接続はアプリケーションの通信を監視し、通信がない間はヘルスチェックを行うため、切れた接続が Online のままになりません。Local はリモート用のプローブではなく、ネイティブ接続の終了や失敗を検知します。
|
||||
- **Attention:** ホスト鍵の承認、認証、互換サーバーの準備など、バックグラウンドではできない操作が必要です。ほかのマシンは利用できます。
|
||||
- **保存済みマシンのファイルエラー:** カタログを読み取れない、または内容が不正な場合、現在の接続は変更しません。通知を表示して自動で読み取りを再試行します。
|
||||
|
||||
バックグラウンド接続がプロンプトに回答したり、サーバーのインストール、更新、再起動、ハンドオフを行ったりすることはありません。Attention の場合は、Herdr が表示する単独接続用のコマンドを対話型ターミナルで実行してください。例:
|
||||
|
||||
```bash
|
||||
herdr --remote workbox
|
||||
```
|
||||
|
||||
プロファイルの接続先を使います。追加時に名前付きセッションを選んだ場合だけ、`--session <name>` も指定します。必要な確認に回答したら、クライアントを再起動して Attention の接続を再試行してください。バージョンが違うという理由だけで実行中サーバーを止めないでください。
|
||||
|
||||
認証に失敗したら、まず通常の SSH を確認します。パスフレーズ付きの鍵は、非対話型のバックグラウンド接続を始める前に `ssh-add` で読み込んでください。
|
||||
|
||||
## 設定と自動化
|
||||
|
||||
UI はデフォルトでクライアントのローカルテーマ、サイドバー設定、キーバインドを使います。選択中サーバーが公開するカスタムコマンドとプラグインは、そのサーバーで実行します。Herdr はローカルのプラグイン、設定、実行ファイル、シークレットを SSH ホストにコピーしません。リモートにコマンドがなければエラーを表示します。クライアント設定を編集したら UI の `reload config` を使います。[設定](/ja/docs/configuration/)を参照してください。
|
||||
|
||||
複数のマシンがある場合、デフォルトの Agent 行に `machine` トークンを表示します。既存のカスタム行は維持されるため、ラベルが必要なら `machine` を追加してください。[サイドバーの行レイアウト](/ja/docs/configuration/)ではマシンラベルの条件付き色も設定できます。
|
||||
|
||||
ワークスペース、タブ、ペインの ID とエージェント名はサーバーごとに独立しています。2 台に同じ `w1:p1` や `reviewer` が存在する場合があります。UI でマシンを選んでも、既存ペイン内の CLI は継承したセッションとソケットを使い続けます。リモート自動化では、対象ホストの対象セッションでコマンドを実行し、そこで ID を読み取ってください。
|
||||
|
||||
## 更新と保存データ
|
||||
|
||||
保存するのは、不透明な ID、ラベル、SSH 接続先、明示的なリモートセッション名、有効状態だけです。パスワード、秘密鍵、エージェントのチケット、SSH 制御ソケットはカタログに保存しません。認証は OpenSSH が扱います。
|
||||
|
||||
クライアントとサーバーは同一バージョンを要求せず、互換性を合意します。保存済みマシンへの接続には、サーバーの `surface_interest` と `health_check` 能力も必要です。未対応の古いサーバーは、単独接続できても明示的に更新するまで Attention になります。そのほかの未対応メソッドは、該当する操作だけを無効にします。
|
||||
|
||||
互換クライアントを更新しても、リモートサーバーを置き換えたりエージェントを停止したりしません。新しいサーバー機能が必要なら、そのサーバーを明示的に更新します。通常の置き換えでは、サーバーとペインのプロセスを停止する前に確認します。
|
||||
|
||||
ライブハンドオフは実験的なオプトイン機能です。単独接続のセットアップで対応サーバーを置き換える場合、`herdr --remote` に `--handoff` を明示的に追加できます。通常の接続や認証の修復には不要です。[更新](/ja/docs/install/)と[セッション状態と復元](/ja/docs/session-state/)で、それぞれの操作が何を維持するか確認してください。
|
||||
@@ -77,7 +77,7 @@ herdr --remote workbox
|
||||
herdr --remote ssh://you@server:2222
|
||||
```
|
||||
|
||||
ローカルの Herdr はシンクライアントとして動作します。SSH 越しに接続し、リモートの Herdr サーバーを起動またはアタッチして、UI をローカルターミナルにストリーミングします。
|
||||
リモートサーバーがペインを動かし、ターミナル内容とセッション状態を SSH 越しに送信します。ローカルの Herdr が、ローカルのテーマや表示設定を使って UI を描画します。
|
||||
|
||||
リモートセッションをローカルのように感じたいときはこの方法を使ってください。クライアントは手元のマシンで動くので、画像クリップボードの貼り付けのようなローカルデスクトップ機能をリモートサーバーにブリッジできます。先に SSH してサーバー上で `herdr` を実行した場合、Herdr は完全にそのサーバー上で動くため、ローカルデスクトップのクリップボードは読めません。
|
||||
|
||||
@@ -98,6 +98,6 @@ herdr --remote workbox
|
||||
|
||||
## どの方法を使うか
|
||||
|
||||
ローカル作業には `herdr` を使います。リモートシェル上で Herdr を tmux のように使いたいときや、スマートフォンの SSH クライアントを使っているときは `ssh you@server` してから `herdr` を使います。リモートセッション用のローカルシンクライアントが欲しいとき (ローカルクリップボードの画像貼り付けブリッジを含む) は `herdr --remote <host>` を使います。
|
||||
ローカル作業には `herdr` を使います。リモートシェル上で Herdr を tmux のように使いたいときや、スマートフォンの SSH クライアントを使っているときは `ssh you@server` してから `herdr` を使います。単独のリモートセッションをローカル UI で操作し、ローカルクリップボードの画像も貼り付けたい場合は `herdr --remote <host>` を使います。Local と複数の SSH マシンを 1 つのウィンドウで使うには、`herdr machine add <host> --label <label>` で接続先を保存します。[マシンへの接続](/ja/docs/connecting-machines/)を参照してください。
|
||||
|
||||
リモートブートストラップの詳細、名前付きリモートセッション、カスタムバイナリ、ダイレクトターミナルアタッチについては[永続化とリモートアクセス](/ja/docs/persistence-remote/)を参照してください。
|
||||
|
||||
@@ -49,6 +49,11 @@ Help me understand and set up Herdr. Read https://herdr.dev/agent-guide.md first
|
||||
|
||||
[エージェントを理解する →](/ja/docs/agents/)
|
||||
</Card>
|
||||
<Card title="マシンへの接続">
|
||||
Local と保存済み SSH マシンを 1 つのウィンドウにまとめ、エージェントを一覧できます。接続はそれぞれ独立して再接続します。
|
||||
|
||||
[マシンを接続する →](/ja/docs/connecting-machines/)
|
||||
</Card>
|
||||
<Card title="セッション状態">
|
||||
デタッチ、再起動時の復元、ペイン履歴のリプレイ、エージェントネイティブの resume、ライブハンドオフについて。
|
||||
|
||||
|
||||
@@ -37,53 +37,20 @@ herdr session delete side-project --json
|
||||
|
||||
## 保存済み SSH マシン
|
||||
|
||||
よく使う接続先を保存すると、1 つの Herdr クライアントから複数のマシンで作業できます:
|
||||
|
||||
```bash
|
||||
herdr machine add workbox --label "Build machine" --remote-session agents
|
||||
herdr machine add ssh://you@server:2222 --label "Production" --remote-session operations
|
||||
herdr machine list
|
||||
```
|
||||
|
||||
`machine add` はリモートマシンに Herdr を準備し、指定したセッションのバックグラウンドサーバーを起動してからプロファイルを保存します。インストール済みバイナリとは別に実行中のサーバーを確認し、クライアントとリリースバージョンが異なっていても、互換性があればそのまま使用します。実行中のサーバーに更新が必要な場合、ペインのプロセスを停止する前に確認します。デフォルトの回答は No です。インストールと再起動の承認は1回の確認で行います。`machine add` が実験的なライブハンドオフを自動で有効にすることはありません。Herdr が未インストールまたは非互換の場合は、`--remote` と同じ承認付きのセットアップを行います。承認が必要な場合は対話型ターミナルで実行してください。キャンセルするとプロファイルは保存されません。セットアップ終了後もリモートサーバーは動き続けます。
|
||||
|
||||
保存済みマシンの変更は、開いているローカルの Herdr クライアントに通常 1 秒以内に自動反映されます。マシンの切り替え中の場合は、切り替えが完了してから反映します。追加または有効化した SSH マシンはサイドバーに Local と並んで表示され、選択を変えずにバックグラウンドで接続します。マシンまたはそのワークスペースを選ぶと切り替わります。接続中のマシンのメタデータ、エージェント状態、通知は引き続き利用できますが、ペイン画面、入力、表示領域、グラフィックスのやり取りは選択中のマシンだけに限定されます。2 つのサーバーが同じ内部 ID を使っていても、ワークスペース、タブ、ペイン、エージェント、グラフィックスの識別情報はマシンごとに分離されます。
|
||||
|
||||
起動時は保存済み SSH マシンを待たず、接続バッジも表示せずに Local を開きます。有効な保存済みマシンがあれば、Local への接続に失敗してもクライアントを開けます。Local の停止や再起動で正常な SSH 接続が閉じることはありません。Local のサーバーが戻ると、使用中のマシンから選択を奪わずに再接続します。応答しないマシンが、別のマシンへの入力や接続処理を妨げることはありません。
|
||||
|
||||
Herdr は接続中の SSH マシンのアプリケーションレベルの通信を監視し、通信がない間は軽量なヘルスチェックを行います。Local ではリモート用のヘルスチェックを使わず、接続の終了や失敗で切断を検知します。スリープ、ネットワークの中断、SSH の障害などで接続が不健全になると Reconnecting と表示し、上限のある待機間隔で再試行します。最後のワークスペース、エージェント、選択中のペインの状態は暗く表示されたまま固定され、新しい接続と整合した画面が届くまで入力やその状態への移動は無効になります。再接続がプロンプトに回答したり、リモートサーバーのインストール、更新、再起動、ハンドオフを行ったりすることはありません。ホスト鍵の承認、認証、互換性のある Herdr のインストールが必要な接続先は Attention と表示され、Local とほかのマシンはそのまま使えます。プロファイルに対応する単独接続用のコマンドをターミナルで実行してセットアップを完了してください。例:
|
||||
|
||||
```bash
|
||||
herdr --remote workbox --session agents
|
||||
```
|
||||
|
||||
Attention と表示されている場合は、セットアップ後にクライアントを再起動して接続を再試行してください。名前の変更、無効化、削除にはプロファイルの不透明な ID を使います:
|
||||
|
||||
```bash
|
||||
herdr machine rename <profile-id> --label "New name"
|
||||
herdr machine disable <profile-id>
|
||||
herdr machine enable <profile-id>
|
||||
herdr machine remove <profile-id>
|
||||
```
|
||||
|
||||
名前の変更はラベルだけを更新し、再接続しません。削除または無効化すると、クライアントからそのマシンだけを切断します。マシンに到達できなくても削除でき、リモートセッションは動き続けます。表示中のマシンを削除または無効化すると Local に戻ります。Local が利用できない場合は、別のリモートを選ぶのではなく、利用不可と表示して再接続します。保存済みマシンのファイルが読めない、または不正な場合は、現在の接続を変更せずに通知を表示し、自動で読み込みを再試行します。
|
||||
|
||||
保存するのは、不透明な ID、ラベル、SSH 接続先、明示的なリモートセッション名、有効状態だけです。パスワード、秘密鍵、エージェントのチケット、SSH 制御ソケットをマシンカタログに保存することはありません。
|
||||
|
||||
クライアントはデフォルトでローカルのキーバインドを使います。選択中のマシンが公開するカスタムコマンドは、そのマシンで実行されます。Herdr はローカルのコマンドプラグイン、設定、実行ファイル、シークレットを SSH ホストにコピーしません。リモートに必要なコマンドやプラグインがなければ、エラーを表示します。
|
||||
Local と複数の SSH マシンを 1 つのウィンドウで使うには、[マシンへの接続](/ja/docs/connecting-machines/)を参照してください。セットアップ、切り替え、再接続、設定、リモート自動化を説明しています。保存済みマシンを削除してもクライアントが切断されるだけで、リモートセッションは停止しません。
|
||||
|
||||
## SSH 越しのリモートアタッチ
|
||||
|
||||
リモートモードは 2 つあり、[Herdr での作業の進め方](/ja/docs/how-to-work/)で比較しています。tmux スタイルの方法では、サーバーに SSH してそこで `herdr` を実行します。もうひとつは、ローカルマシンから SSH 越しにアタッチする方法です:
|
||||
[Herdr での作業の進め方](/ja/docs/how-to-work/)でリモート接続の方法を比較しています。サーバーに SSH してそこで `herdr` を実行する tmux スタイルの方法、保存済み SSH マシンで複数の接続先をまとめる方法、ローカルマシンから単独のセッションに接続する方法があります:
|
||||
|
||||
```bash
|
||||
herdr --remote workbox
|
||||
herdr --remote ssh://you@server:2222
|
||||
```
|
||||
|
||||
このモードでは、ローカルの Herdr はシンクライアントです。SSH 越しに接続し、リモートの Herdr サーバーを起動またはアタッチして、UI をローカルターミナルにストリーミングします。クライアントがローカルで動くため、Herdr は画像クリップボードの貼り付けのようなローカルデスクトップ機能をリモートセッションにブリッジできます。画像をリモートの一時ファイルにコピーし、そのパスを貼り付けます。
|
||||
このモードでは、リモートサーバーがペインを動かし、ターミナル内容とセッション状態を SSH 越しに送信します。ローカルの Herdr がサイドバー、メニュー、テーマを含む UI を描画します。クライアントがローカルで動くため、Herdr は画像クリップボードの貼り付けのようなローカルデスクトップ機能をリモートセッションにブリッジできます。画像をリモートの一時ファイルにコピーし、そのパスを貼り付けます。
|
||||
|
||||
デフォルトでは、`herdr --remote` はそのアタッチにローカルの Herdr キーバインドを使います。リモートサーバーの設定が異なっていても、ローカルの操作感覚を維持できます。ローカルキーバインドはアタッチ時のスナップショットなので、ローカルのキーバインドを編集したらデタッチして再アタッチしてください。リモートサーバーの設定を使いたい場合は `--remote-keybindings server` を使います。ローカルのカスタムコマンドキーバインドは送信されません。それらのコマンドはリモートホスト上で実行されてしまうからです。
|
||||
デフォルトでは、`herdr --remote` はそのアタッチにローカルの Herdr キーバインドを使います。リモートサーバーの設定が異なっていても、ローカルの操作感覚を維持できます。ローカルキーバインドを編集したら、UI の `reload config` でデタッチせずに反映できます。リモートサーバーの設定を使いたい場合は `--remote-keybindings server` を使います。ローカルのカスタムコマンドキーバインドは送信されません。それらのコマンドはリモートホスト上で実行されてしまうからです。
|
||||
|
||||
繰り返し接続する相手は SSH config を使ってください:
|
||||
|
||||
@@ -100,11 +67,20 @@ Host workbox
|
||||
herdr --remote workbox
|
||||
```
|
||||
|
||||
リモートアタッチは、Linux、macOS、Windows のローカルクライアントから、x86_64 と aarch64 の Linux および macOS ホストへの接続をサポートします。Herdr はリモートのプラットフォームを確認し、リモートの `PATH` 上にある一致する `herdr` を優先してから、一般的な直接インストール、Homebrew、mise、Nix プロファイルのパスを確認します。一致するバイナリがない場合、対話的な実行では `~/.local/bin/herdr` へのインストールを提案します。非対話的な実行はホストを変更せずに失敗します。`~/.local/bin` がリモートの `PATH` にない場合、Herdr はインストール後に警告します。Windows をリモートホストとして使うことはできません。
|
||||
リモートアタッチは、Linux、macOS、Windows のローカルクライアントから、x86_64 と aarch64 の Linux および macOS ホストへの接続をサポートします。Herdr はリモートのプラットフォームを確認し、リモートの `PATH` 上にある互換性のある `herdr` を優先してから、一般的な直接インストール、Homebrew、mise、Nix プロファイルのパスを確認します。両方が安定したエンドポイント世代に対応していれば、ローカルとリモートのバージョンは一致しなくても接続できます。互換性のあるバイナリがない場合、対話的な実行では `~/.local/bin/herdr` へのインストールを提案します。非対話的な実行はホストを変更せずに失敗します。`~/.local/bin` がリモートの `PATH` にない場合、Herdr はインストール後に警告します。Windows をリモートホストとして使うことはできません。
|
||||
|
||||
デフォルトでは、`herdr --remote` はユーザーの SSH config を最初に include し、その後にフォールバックのキープアライブ設定を加えた一時的な SSH config を通してリモートセットアップとブリッジを実行します。既存のユーザーのキープアライブ設定が優先されます。Linux と macOS クライアントは接続再利用用のプライベートなアタッチ単位コントロールソケットも使いますが、Windows OpenSSH では使いません。Herdr が生成する設定やコントロールソケットを使わず通常の `ssh` を使うには `[remote].manage_ssh_config = false` を設定してください。
|
||||
|
||||
デフォルトでは、実行中のリモートサーバーの置き換えや再起動が必要な場合、リモートアタッチは通常の再起動/停止フローを使います。対応する実行中リモートサーバーで実験的なライブハンドオフにオプトインするには `--handoff` を渡します:
|
||||
リモート接続は通常の OpenSSH 認証を使います。非対話型シェル、スクリプト、CI、モバイルターミナルなどで鍵のパスフレーズを入力できない場合は、先に ssh-agent へ鍵を追加してください:
|
||||
|
||||
```bash
|
||||
ssh-add
|
||||
herdr --remote workbox
|
||||
```
|
||||
|
||||
認証に失敗したら、まず `ssh workbox` で通常の SSH 接続を確認してください。
|
||||
|
||||
バージョンが違うだけでは、実行中のリモートサーバーを置き換えたり再起動したりしません。必要な互換性や独立したバックグラウンド起動に未対応のサーバーは、停止前に確認します。保存済みマシンには画面配信とヘルスチェックの能力も必要です。[マシンへの接続](/ja/docs/connecting-machines/)を参照してください。デフォルトの回答は No で、停止するとペインのプロセスも終了します。この一度限りの更新で、対応サーバーのプロセスを実験的なライブハンドオフで維持したい場合は `--handoff` を渡します:
|
||||
|
||||
```bash
|
||||
herdr --remote workbox --handoff
|
||||
@@ -132,7 +108,7 @@ herdr --remote workbox --session agents
|
||||
|
||||
完全な Herdr アタッチはワークスペース UI 全体を開きます。ダイレクトアタッチは、サーバーが所有するターミナルをひとつだけ、現在のターミナルに開きます。
|
||||
|
||||
ダイレクトターミナルアタッチは Windows では Unix 専用です。
|
||||
ダイレクトターミナルアタッチは Linux と macOS で利用でき、ネイティブ Windows では利用できません。
|
||||
|
||||
エージェントターゲットでアタッチ:
|
||||
|
||||
@@ -155,3 +131,19 @@ herdr terminal attach term_abc123
|
||||
```bash
|
||||
herdr terminal attach term_abc123 --takeover
|
||||
```
|
||||
|
||||
描画済みターミナルデータだけが必要な外部ブリッジには、読み取り専用のオブザーバーを使えます:
|
||||
|
||||
```bash
|
||||
herdr terminal session observe w1:p1 --cols 120 --rows 40
|
||||
```
|
||||
|
||||
base64 の ANSI データを含む `terminal.frame` を改行区切り JSON で出力し、サーバーがストリームを閉じると `terminal.closed` を出力します。複数のオブザーバーが同じターミナルを監視でき、入力、リサイズ、スクロール、所有権を取得することはありません。
|
||||
|
||||
対話型ブリッジには書き込み可能なコントローラーを使います:
|
||||
|
||||
```bash
|
||||
herdr terminal session control w1:p1 --takeover --cols 120 --rows 40
|
||||
```
|
||||
|
||||
同じフレームを出力し、標準入力から改行区切り JSON コマンドを読み取ります。`terminal.input` はテキストまたは base64 データ、`terminal.resize` は表示サイズ、`terminal.scroll` はビューポートのスクロール、`terminal.release` はコントローラーの終了を扱います。入力とリサイズを所有できるコントローラーは 1 つだけです。
|
||||
|
||||
@@ -749,6 +749,6 @@ herdr agent wait w1:p1 --until blocked
|
||||
|
||||
## プロトコルの安定性
|
||||
|
||||
クライアント描画の Herdr UI は、ローカルサーバーと SSH サーバーに安定したエンドポイント世代を使います。クライアントとサーバーのビルドが一致する必要はありません。接続時にコアのスナップショット、画面、入力、blob コーデックを合意し、サーバーが対応 API メソッドを通知します。メソッドがない場合は、そのサーバー上の該当アクションだけを無効にしてクライアント側通知を表示します。拒否やタイムアウトも接続を終了せず通知します。エンドポイント世代 1 より前のサーバーだけは最後の 1 回の更新が必要です。
|
||||
クライアント描画の Herdr UI は、ローカルサーバーと SSH サーバーに安定したエンドポイント世代を使います。クライアントとサーバーのビルドが一致する必要はありません。接続時にコアのスナップショット、画面、入力、blob コーデックを合意し、サーバーが対応 API メソッドと任意の能力を通知します。保存済み SSH マシンには、選択中のマシンだけがペイン画面を送信するための `surface_interest` と、通信のない接続の障害を検知する `health_check` が必要です。未対応のサーバーは明示的に更新するまで Attention になります。詳しくは[マシンへの接続](/ja/docs/connecting-machines/)を参照してください。メソッドがない場合は、そのサーバー上の該当アクションだけを無効にしてクライアント側通知を表示します。拒否やタイムアウトも接続を終了せず通知します。エンドポイント世代 1 より前のサーバーだけは最後の 1 回の更新が必要です。
|
||||
|
||||
番号付きバイナリプロトコルは、直接ターミナル接続やライブハンドオフなど、同一インストール内の内部操作に残ります。異なるビルド間でそれらを使う前に `ping` または `herdr status` を確認してください。JSON API クライアントは未知のフィールドを無視し、未対応メソッドを通常のエラーとして扱う必要があります。
|
||||
|
||||
@@ -61,7 +61,7 @@ map alt+right send_text all \x1bf
|
||||
|
||||
## Herdr を更新したのに実行中のセッションが古い
|
||||
|
||||
バイナリを更新しても、互換性のある実行中サーバーは自動で置き換わらないことがあります。`herdr status` を確認してください。更新済みサーバーを起動するには、セッションを停止して Herdr を再起動します:
|
||||
バイナリを更新しても、互換性のある実行中サーバーは置き換わりません。Herdr を開き直せば更新済みクライアントを使えます。サーバー側の新機能も必要な場合だけ、`herdr status` で確認してからセッションを停止し、Herdr を再起動します:
|
||||
|
||||
```bash
|
||||
herdr server stop
|
||||
|
||||
@@ -37,53 +37,20 @@ herdr session delete side-project --json
|
||||
|
||||
## Saved SSH machines
|
||||
|
||||
Save repeat targets to work across several machines from one Herdr client:
|
||||
|
||||
```bash
|
||||
herdr machine add workbox --label "Build machine" --remote-session agents
|
||||
herdr machine add ssh://you@server:2222 --label "Production" --remote-session operations
|
||||
herdr machine list
|
||||
```
|
||||
|
||||
`machine add` prepares Herdr on the remote machine and starts the requested session's background server before saving the profile. It checks the running server separately from the installed binary and keeps compatible servers, even when their release versions differ from your client. If the running server needs an upgrade, setup asks before stopping its active pane processes; the default answer is No. Approving installation and restart uses one confirmation. `machine add` never opts into experimental live handoff. Missing or incompatible installations use the same approval-based setup as `--remote`; run the command in an interactive terminal when approval is needed. Cancelling setup leaves the profile unsaved. The remote server keeps running after setup exits.
|
||||
|
||||
Saved-machine changes apply to open local Herdr clients automatically, normally within a second. An in-progress machine switch finishes before the change is applied. Added or enabled SSH machines appear with Local in the machine sidebar and connect in the background without changing your selection. Select a machine or one of its workspaces to switch to it. Herdr keeps metadata, agent state, and notifications from connected machines available, but streams pane surfaces, input, geometry, and graphics only for the selected machine. Workspace, tab, pane, agent, and graphics identities stay scoped to their machine even when two servers happen to use the same internal ID.
|
||||
|
||||
Local opens directly on startup, without waiting for saved SSH machines or showing a connection badge. With enabled saved machines, the client can also open if Local actually fails, and stopping or restarting Local does not close healthy SSH connections. Local reconnects when its server returns, without taking selection away from the machine you are using. A stalled machine cannot block another machine's input or connection handling.
|
||||
|
||||
Herdr checks connected SSH machines for application-level activity and uses a lightweight health probe while they are quiet. Local relies on its native connection closing or failing, not remote health probes. After sleep, a network interruption, or SSH failure, an unhealthy machine changes to Reconnecting and retries with bounded backoff. Its last workspace, agent, and selected pane state remains visible but dimmed and frozen; input and navigation into that cached state stay disabled until a fresh connection and coherent surface arrive. Reconnects never answer prompts or install, update, restart, or hand off a remote server. A target that needs host-key approval, authentication, or a compatible Herdr install shows Attention while Local and other machines keep working. Run the profile's explicit standalone command in a terminal to finish setup, for example:
|
||||
|
||||
```bash
|
||||
herdr --remote workbox --session agents
|
||||
```
|
||||
|
||||
If the machine shows Attention, restart the client after setup to retry its connection. Rename, disable, or remove profiles by their opaque ID:
|
||||
|
||||
```bash
|
||||
herdr machine rename <profile-id> --label "New name"
|
||||
herdr machine disable <profile-id>
|
||||
herdr machine enable <profile-id>
|
||||
herdr machine remove <profile-id>
|
||||
```
|
||||
|
||||
Renaming updates the label without reconnecting. Removing or disabling a machine disconnects only that machine from the client; its remote sessions keep running, even if the machine is unreachable. If you remove or disable the machine you are viewing, the client returns to Local. If Local is unavailable, it shows that and reconnects rather than selecting another remote. An unreadable or invalid saved-machine file leaves current connections unchanged and shows a notice; the client retries reading it automatically.
|
||||
|
||||
Saved profiles contain only the opaque ID, label, SSH target, explicit remote session, and enabled state. Passwords, private keys, agent tickets, and SSH control sockets are never stored in the machine catalog.
|
||||
|
||||
The client uses local keybindings by default. Custom commands advertised by the selected machine still execute on that machine. Herdr does not copy local command plugins, configuration, executables, or secrets to SSH hosts; a missing remote command or plugin fails visibly.
|
||||
To keep Local and several SSH machines in one Herdr window, see [Connecting machines](/docs/connecting-machines/). That guide covers setup, switching, reconnects, settings, and remote automation. Removing a saved machine only disconnects the client; it does not stop that machine's sessions.
|
||||
|
||||
## Remote attach over SSH
|
||||
|
||||
Herdr supports two remote modes. [How to work with Herdr](/docs/how-to-work/) compares them. SSH to the server and run `herdr` there for the tmux-style path, use saved SSH machines for persistent multi-machine work, or attach through SSH from your local machine:
|
||||
[How to work with Herdr](/docs/how-to-work/) compares the connection paths. SSH to the server and run `herdr` there for the tmux-style path, use [saved SSH machines](/docs/connecting-machines/) for multi-machine work, or attach through SSH from your local machine:
|
||||
|
||||
```bash
|
||||
herdr --remote workbox
|
||||
herdr --remote ssh://you@server:2222
|
||||
```
|
||||
|
||||
In this mode, your local Herdr is a thin client. It connects over SSH, starts or attaches to the remote Herdr server, and streams the UI back to your local terminal. Because the client runs locally, Herdr can bridge local desktop features such as image clipboard paste into the remote session by copying the image to a remote temp file and pasting that path.
|
||||
In this mode, the remote server owns the running panes and sends their terminal content and session state over SSH. Your local Herdr draws the UI, including its sidebar, menus, and theme. Because the client runs locally, Herdr can bridge local desktop features such as image clipboard paste into the remote session by copying the image to a remote temp file and pasting that path.
|
||||
|
||||
By default, `herdr --remote` uses your local Herdr keybindings for that attach. This keeps local muscle memory even when the remote server has different config. The local keybindings are a snapshot from attach time; detach and reattach after editing local keybindings. Use `--remote-keybindings server` when you want the remote server config instead. Local custom command keybindings are not sent, because those commands would run on the remote host.
|
||||
By default, `herdr --remote` uses your local Herdr keybindings for that attach. This keeps local muscle memory even when the remote server has different config. After editing local keybindings, use the UI's `reload config` action to apply them without detaching. Use `--remote-keybindings server` when you want the remote server config instead. Local custom command keybindings are not sent, because those commands would run on the remote host.
|
||||
|
||||
For repeat targets, use your SSH config:
|
||||
|
||||
@@ -113,7 +80,7 @@ herdr --remote workbox
|
||||
|
||||
For any remote authentication failure, verify plain SSH access first with `ssh workbox`, then run `herdr --remote workbox` again.
|
||||
|
||||
A version difference alone does not replace or restart a running remote server. Remote attach uses the restart/stop flow only for a server that predates the stable endpoint generation or the detached-daemon baseline. To opt into experimental live handoff when that one-time upgrade is needed, pass `--handoff`:
|
||||
A version difference alone does not replace or restart a running remote server. Remote attach asks before stopping a server that lacks required compatibility or detached-daemon support. For saved machines, this also includes the surface and health-check capabilities described in [Connecting machines](/docs/connecting-machines/#updates-and-saved-data). The default answer is No; stopping the server ends its pane processes. To opt into experimental live handoff when that one-time upgrade is needed, pass `--handoff`:
|
||||
|
||||
```bash
|
||||
herdr --remote workbox --handoff
|
||||
@@ -141,7 +108,7 @@ herdr --remote workbox --session agents
|
||||
|
||||
Full Herdr attach opens the whole workspace UI. Direct attach opens one server-owned terminal in your current terminal.
|
||||
|
||||
Direct terminal attach is Unix-only on Windows.
|
||||
Direct terminal attach is available on Linux and macOS, not native Windows.
|
||||
|
||||
Attach by agent target:
|
||||
|
||||
|
||||
@@ -73,9 +73,11 @@ herdr agent rename w1:p2 reviewer
|
||||
|
||||
窗格输入直接指定终端,不关心当前进程。智能体输入会解析实时智能体;如果该智能体已不再控制此窗格,操作会被拒绝。
|
||||
|
||||
除非智能体已经是 `blocked`,`agent prompt --wait` 会立即提交提示。已经是 `blocked` 时,它不会开始等待,而是返回 `agent_blocked`。已接受的提示从其他非 working 状态开始时,Herdr 必须在五秒内观察到 `working` 或 `blocked`。如果没有观察到,Herdr 返回 `agent_prompt_stalled`;如果调用方的超时先到期,则返回普通的 `timeout` 错误。这可防止无关的 `idle`、`done` 或会话变化错误地完成等待。观察到活动后,它会等待请求的稳定状态。它不会跟踪单独的轮次。如果智能体已经处于 working,当前轮次的完成可能满足等待。独立的 `agent wait` 会观察当前智能体;如果状态已经匹配,就会立即返回。两者默认匹配 `idle`、`done` 或 `blocked`。可以重复使用 `--until` 接受多个精确状态,例如 `--until idle --until done`;需要 `unknown` 时请明确使用 `--until unknown`。在 `agent prompt` 中,`--until` 必须与 `--wait` 一起使用。
|
||||
如果智能体已经是 `blocked`,`agent prompt --wait` 会返回 `agent_blocked`,不会发送输入或开始等待。否则,它会将提示文本和延迟的 Enter 作为一次有序提交写入,然后等待状态。Windows 上 Codex 的提交延迟随提示大小增加;调用方的超时包含提交时间。如果提示从其他非 working 状态开始,提交后最多等待五秒来观察 `working` 或 `blocked`。如果没有观察到,Herdr 返回 `agent_prompt_stalled`;如果调用方的超时先到期,则返回普通的 `timeout` 错误。这可防止无关的 `idle`、`done` 或会话变化错误地完成等待。观察到活动后,它会等待请求的稳定状态。它不会跟踪单独的轮次。如果智能体已经处于 working,当前轮次的完成可能满足等待。独立的 `agent wait` 会观察当前智能体;如果状态已经匹配,就会立即返回。两者默认匹配 `idle`、`done` 或 `blocked`。可以重复使用 `--until` 接受多个精确状态,例如 `--until idle --until done`;需要 `unknown` 时请明确使用 `--until unknown`。在 `agent prompt` 中,`--until` 必须与 `--wait` 一起使用。
|
||||
|
||||
`idle` 表示智能体正等待输入,且其标签页已在聚焦的 Herdr 界面中显示。`done` 是相同的底层 idle 状态,但用于后台工作完成后,直到该标签页获得焦点或 `pane focus` / `agent focus` 指向它。仅通过 CLI 读取不会把它标记为已查看。`blocked` 表示 Herdr 识别到了审批或提问界面。`unknown` 表示智能体存在,但 Herdr 无法可靠判断其生命周期;它不代表工作成功完成。区别重要时,请指定精确的 `--until` 状态。
|
||||
`idle` 和 `done` 都表示可以接受输入。CLI/API 使用服务器的已查看状态:`done` 表示尚未标记为已查看的 idle;显式 `pane focus` / `agent focus` 会标记目标,读取不会。每个 TUI 客户端独立记录它已显示的完成状态,因此其 Done 标记可能与 CLI 或其他客户端不同。`blocked` 表示 Herdr 识别到了审批或提问界面。`unknown` 表示智能体存在,但 Herdr 无法可靠判断其生命周期;它不代表工作成功完成。区别重要时,请指定精确的 `--until` 状态。
|
||||
|
||||
超时或 `agent_prompt_stalled` 并不意味着没有发送输入。重试前请先读取智能体,避免重复提交同一提示。ID 和智能体名称只在所属服务器内有效;在 TUI 中切换机器不会改变已有窗格中 CLI 命令的目标。
|
||||
|
||||
`pane wait-output` 不解释智能体生命周期。它轮询选定的终端快照并立即进行第一次搜索,所以已经存在的文本也会匹配。默认来源名是 `recent`;匹配时会把最近 80 个已渲染终端行作为未折行输出处理。`--lines` 可以修改这个行数限制;`--regex` 使用 Rust 正则表达式语法并逐行匹配。
|
||||
|
||||
|
||||
@@ -11,13 +11,9 @@ Herdr 的 CLI 通过与集成和智能体相同的本地 socket API 与运行中
|
||||
|
||||
```bash
|
||||
herdr # 启动或连接默认会话
|
||||
herdr --session work # 启动或连接命名会话
|
||||
herdr --remote workbox # 通过 SSH 连接,使用本地按键绑定
|
||||
herdr --remote workbox --remote-keybindings server
|
||||
herdr --remote workbox --handoff
|
||||
herdr --default-config # 打印默认配置
|
||||
herdr update # 从配置的通道下载并安装
|
||||
herdr update --handoff # 对受支持的运行中服务器启用实时交接
|
||||
herdr completion zsh # 生成 zsh 补全脚本
|
||||
herdr channel show # 打印 stable 或 preview
|
||||
herdr channel set preview # 启用预览构建
|
||||
@@ -25,6 +21,12 @@ herdr channel set stable # 把直接安装切回稳定版
|
||||
herdr --version # 打印版本
|
||||
```
|
||||
|
||||
可选的启动和更新设置:
|
||||
|
||||
- 需要命名会话而非默认会话时,添加 `--session <name>`。
|
||||
- 远程连接要使用服务器按键绑定而非本地绑定时,添加 `--remote-keybindings server`。
|
||||
- 实验性实时交接需要在 `herdr --remote` 或 `herdr update` 中明确添加 `--handoff`,不是正常设置或连接流程;参见[更新](/zh-cn/docs/install/)。
|
||||
|
||||
状态命令:
|
||||
|
||||
```bash
|
||||
@@ -46,19 +48,23 @@ herdr api schema --output herdr-api.schema.json
|
||||
## 已保存的 SSH 机器
|
||||
|
||||
```bash
|
||||
herdr machine list [--json]
|
||||
herdr machine add workbox --label "Build machine" [--remote-session agents]
|
||||
herdr machine list
|
||||
herdr machine add workbox --label "Build machine"
|
||||
herdr machine rename <profile-id> --label "New name"
|
||||
herdr machine disable <profile-id>
|
||||
herdr machine enable <profile-id>
|
||||
herdr machine remove <profile-id>
|
||||
```
|
||||
|
||||
`machine add` 会检查远程 Herdr 是否具备所需能力,仅在必要时征得批准后安装或更新,并在保存配置前启动指定会话的后台服务器。只要兼容,发行版本不必一致。需要批准安装或重启时,请在交互式终端中运行;设置失败或取消时不会保存配置。
|
||||
`machine add` 默认使用远程默认会话。只有需要命名会话时才添加 `--remote-session <name>`。`machine list` 支持可选的 `--json` 供脚本使用。完整流程见[连接机器](/zh-cn/docs/connecting-machines/)。
|
||||
|
||||
`machine add` 会检查远程 Herdr 是否具备所需能力,仅在必要时征得批准后安装或更新,并在保存配置前启动指定会话的后台服务器。只要兼容,发行版本不必一致。需要批准安装或重启时,请在交互式终端中运行;设置失败或取消时不会保存配置。替换运行中的服务器需要明确批准,默认回答为 No;停止服务器会结束其窗格进程。`machine add` 不会隐式启用实验性实时交接。
|
||||
|
||||
更改会自动应用到已打开的本地 Herdr 客户端,通常在一秒内生效。新增或启用的机器在后台连接;重命名不会重新连接。移除或禁用只会断开该机器,远程会话仍会继续运行。移除正在查看的机器会返回 Local;如果 Local 不可用,则显示不可用状态,直到重新连接。每份配置在客户端状态文件中保存一个不透明 ID、标签、SSH 目标、明确的远程会话名和启用状态。Herdr 不保存密码、私钥或其他 SSH 凭据。
|
||||
|
||||
自动连接和重连均为非交互式。如果主机密钥、密码、密钥口令、MFA、安装、更新或重启需要批准,机器会显示 Attention,而不会打开隐藏的提示。请运行 Herdr 显示的独立连接命令,例如 `herdr --remote workbox --session agents`,在前台完成设置后重启客户端。
|
||||
自动连接和重连均为非交互式。如果主机密钥、密码、密钥口令、MFA、安装、更新或重启需要批准,机器会显示 Attention,而不会打开隐藏的提示。请运行 Herdr 显示的独立连接命令,例如 `herdr --remote workbox`,在前台完成设置后重启客户端。仅当配置指向命名会话时,才加上 `--session <name>`。
|
||||
|
||||
工作区、标签页、窗格 ID 和智能体名称仅在所属服务器内有效。在 UI 中选择机器不会改变已有窗格中命令继承的会话或 socket。远程自动化应在目标主机上针对目标会话运行 CLI,并从那里获取 ID。
|
||||
|
||||
## Shell 补全
|
||||
|
||||
@@ -307,9 +313,9 @@ herdr agent explain --file PATH --agent LABEL [--json|--verbose]
|
||||
|
||||
成功的 start 只有在预期智能体占用同一终端并可接受交互输入后才返回。如果启动期间检测到 `blocked`,命令会立即返回 `agent_not_ready`。该名称仍可用于 `agent read` 和 `agent send-keys`,检测变为 `idle` 后即可用于发送提示。默认启动超时是 30000 毫秒;显式值必须大于 3000 且不超过 300000。
|
||||
|
||||
`agent prompt` 遵循当前的 bracketed paste 模式,即使智能体处于 working 也会先发送文本,短暂延迟后再发送编码后的 Enter。如果智能体已经是 `blocked`,它不会发送输入,而是返回 `agent_blocked`。使用 `--wait` 时,从其他非 working 状态接受的提示必须在五秒内产生可观察的 `working` 或 `blocked` 状态,否则 Herdr 返回 `agent_prompt_stalled`;如果调用方的超时先到期,则返回普通的 `timeout` 错误。这可防止无关的 `idle`、`done` 或会话变化错误地完成等待。观察到活动后,它会等待请求的第一个稳定状态。它不会跟踪单独的轮次。如果智能体已经处于 working,当前轮次的完成可能满足等待。`--until` 用于缩小匹配状态,不带 `--wait` 时会被拒绝。独立的 `agent wait` 在当前状态匹配时立即返回。两者默认匹配 `idle`、`done` 或 `blocked`;需要 `unknown` 时请明确使用 `--until unknown`。
|
||||
`agent prompt` 遵循当前的 bracketed paste 模式,即使智能体处于 working,也会将文本和延迟的 Enter 作为一次有序提交写入。不带 `--wait` 时,成功只确认写入完成,不代表轮次已经开始。Windows 上 Codex 的延迟随提示大小增加;调用方的超时包含提交时间。如果智能体已经是 `blocked`,它不会发送输入,而是返回 `agent_blocked`。使用 `--wait` 时,从其他非 working 状态接受的提示必须在提交后的最多五秒内产生可观察的 `working` 或 `blocked` 状态,否则 Herdr 返回 `agent_prompt_stalled`;如果调用方的超时先到期,则返回普通的 `timeout` 错误。这可防止无关的 `idle`、`done` 或会话变化错误地完成等待。观察到活动后,它会等待请求的第一个稳定状态。它不会跟踪单独的轮次。如果智能体已经处于 working,当前轮次的完成可能满足等待。`--until` 用于缩小匹配状态,不带 `--wait` 时会被拒绝。独立的 `agent wait` 在当前状态匹配时立即返回。两者默认匹配 `idle`、`done` 或 `blocked`;需要 `unknown` 时请明确使用 `--until unknown`。
|
||||
|
||||
`idle` 表示智能体在等待输入,且其标签页已在聚焦的 Herdr 界面中显示。`done` 是相同的底层 idle 状态,用于未查看的后台工作完成后。聚焦该标签页或用 `pane focus` / `agent focus` 指向它会标记为已查看;仅通过 CLI 读取不会改变它。`blocked` 表示 Herdr 识别到审批或提问界面。`unknown` 表示智能体存在但无法可靠分类,不代表工作成功。
|
||||
`idle` 和 `done` 都表示可以接受输入。CLI/API 使用服务器的已查看状态:`done` 表示尚未标记为已查看的 idle;显式 `pane focus` / `agent focus` 会标记目标,读取不会。每个 TUI 客户端独立记录它已显示的完成状态,因此其 Done 标记可能与 CLI 或其他客户端不同。`blocked` 表示 Herdr 识别到审批或提问界面。`unknown` 表示智能体存在但无法可靠分类,不代表工作成功。
|
||||
|
||||
`agent send-keys` 发送 `enter`、`up`、`esc`、`ctrl+c` 等逻辑按键。Herdr 会在写入任何字节前验证所有按键。`agent read` 读取解析出的终端流,`agent rename` 为已检测到的智能体命名。
|
||||
|
||||
@@ -340,6 +346,8 @@ herdr pane wait-output <pane_id> (--match <text> | --regex <pattern>) [--source
|
||||
|
||||
`pane wait-output` 会立即检查所选快照,所以已经存在的输出也能匹配。默认来源名是 `recent`;匹配时会把最近 80 个已渲染终端行作为未折行输出处理。`--lines` 可以修改这个行数限制。`--match` 在单行中查找字面子串;`--regex` 使用 Rust 正则表达式语法并逐行匹配。
|
||||
|
||||
超时或 `agent_prompt_stalled` 并不代表未发送提示。重试前请先检查智能体。
|
||||
|
||||
`pane wait-output` 和 `agent wait` 在省略 `--timeout` 时会无限等待。对于 `agent prompt --wait`,观察到活动后,或提示开始时已处于 `working`,等待稳定状态的过程不会超时;如果提示从 non-working 状态开始且未观察到活动,五秒后仍会返回 `agent_prompt_stalled`。超时或服务器错误以 JSON 写到 stderr,退出状态为 1。CLI 用法错误的退出状态为 2。
|
||||
|
||||
## 集成
|
||||
|
||||
@@ -48,6 +48,8 @@ mouse_capture = false
|
||||
| `idle` | 智能体已完成或在等待,并且已被查看过。 |
|
||||
| `unknown` | Herdr 无法有把握地判断状态。 |
|
||||
|
||||
每个客户端独立记录它已显示的完成状态。在一个客户端查看完成状态,不会清除其他客户端的 Done 标记。CLI/API 使用服务器的已查看状态,因此不一定与某个客户端的标记相同;`idle` 和 `done` 都表示可以接受输入。
|
||||
|
||||
## 会话
|
||||
|
||||
会话是一个持久的 Herdr 服务器命名空间。默认的 `herdr` 命令连接到默认会话。
|
||||
|
||||
@@ -50,6 +50,8 @@ herdr server reload-config
|
||||
|
||||
重载会在不重启窗格的情况下应用大多数 UI 设置。仅启动时生效的设置仍需重启。
|
||||
|
||||
主题、侧边栏布局、复制行为等显示设置来自客户端的本地配置,查看 SSH 机器时也一样。窗格默认值、worktree、集成和自定义命令属于运行窗格的服务器。UI 中的 `reload config` 会同时重载客户端本地设置和选中服务器的配置,本地按键绑定也会更新;指定 `--remote-keybindings server` 时则使用选中服务器的按键绑定。
|
||||
|
||||
## 无客户端终端尺寸
|
||||
|
||||
没有客户端连接时,服务器会使用 120×40 的虚拟终端进行布局并创建新窗格。可通过以下配置更改用于无客户端编排的回退尺寸:
|
||||
@@ -294,6 +296,8 @@ text = "#cdd6f4"
|
||||
|
||||
侧边栏是 Herdr 的主仪表盘。在[配置参考](/docs/config-reference/)中搜索 `ui.`,可查看尺寸、折叠模式、Agent 面板排序、鼠标行为、窗格边框和其他显示设置。
|
||||
|
||||
`ui.pane_borders` 接受 `"auto"`(默认值,仅为分割窗格显示边框)、`"always"`(也为单个窗格显示边框)或 `"off"`。单窗格的所有边都是外边,因此还需要 `ui.pane_outer_borders = true` 才会显示边框。旧的布尔值仍然有效:`true` 对应 `"auto"`,`false` 对应 `"off"`。
|
||||
|
||||
在 `[ui]` 下设置 `tab_bar_position = "bottom"`,可将桌面标签栏放到终端窗格下方。Prefix、Navigate、Copy 和 Resize 模式栏会在显示期间临时替换底部标签栏。默认值为 `"top"`。
|
||||
|
||||
可在标签栏右侧配置一个类似 tmux 的有序状态区:
|
||||
@@ -312,7 +316,7 @@ tab_bar_right_separator = " · "
|
||||
|
||||
状态区默认为空。添加 `zoom` 后,活动标签页处于缩放状态时会显示固定的 `ZOOM` 标记;它与现有的逐标签页 `Z` 标记相互独立。`hostname`、`datetime` 和 `command` 在 Herdr 服务器上解析,因此使用 `herdr --remote` 时会显示远程机器的值。日期时间条目使用 `strftime` 格式。由于该值是服务器本地的墙上时钟时间,需要 UTC 偏移量或 Unix 时间戳的 `%z`、`%s` 等指令会被拒绝。
|
||||
|
||||
命令条目会立即运行,之后按 `interval_seconds` 刷新,不会阻塞渲染,也不会与上一次运行重叠。间隔范围为 1–31,536,000 秒,超时范围为 1–3,600 秒。Herdr 使用成功输出的最后一行;执行失败、输出为空或超过 `timeout_seconds` 后会清除该值。命令会获得与自定义命令按键绑定相同的活动工作区、标签页、窗格、socket、二进制文件和工作目录上下文。Linux、macOS 和 Windows 均支持命令条目;Linux 和 macOS 使用 `/bin/sh -lc`,Windows 使用 `cmd.exe /d /c`。
|
||||
命令条目会立即运行,之后按 `interval_seconds` 刷新,不会阻塞渲染,也不会与上一次运行重叠。间隔范围为 1–31,536,000 秒,超时范围为 1–3,600 秒。Herdr 使用成功输出的最后一行,并移除以 ESC 开头的终端控制序列,而不将其解释为样式;执行失败、输出为空或超过 `timeout_seconds` 后会清除该值。命令会获得与自定义命令按键绑定相同的活动工作区、标签页、窗格、socket、二进制文件和工作目录上下文。Linux、macOS 和 Windows 均支持命令条目;Linux 和 macOS 使用 `/bin/sh -lc`,Windows 使用 `cmd.exe /d /c`。
|
||||
|
||||
分隔符只会出现在可见条目之间。设置 `tab_bar_right_separator = ""` 可直接连接条目。标签栏较窄时,整个状态区会让位给标签页及其控件。
|
||||
|
||||
@@ -396,6 +400,25 @@ rows = [
|
||||
|
||||
`fg` 只接受严格的 `#RGB` 或 `#RRGGBB`,`bold` 和 `dim` 接受布尔值。省略字段会保留上下文样式;显式 `false` 会移除对应修饰。样式只作用于当前出现位置。为 `git_status` 设置 `fg` 后,ahead 和 behind 会使用同一种颜色,而不是默认的绿色和红色。token 样式不会改变分隔符或行背景。
|
||||
|
||||
文本值 token 还可以包含最多 16 条有序的 `rules`。每条规则必须恰好包含一个条件:`equals`、`contains`、`starts_with`、`gt` 或 `lt`,并可选地覆盖 `fg`、`bold` 和 `dim`:
|
||||
|
||||
```toml
|
||||
[ui.sidebar.agents]
|
||||
rows = [
|
||||
["state_icon", "workspace", "tab"],
|
||||
[{ token = "machine", fg = "#fff", rules = [{ equals = "Local", fg = "#f55" }, { equals = "Fedora", ignore_case = true, fg = "#51a2da" }] }, "agent"],
|
||||
[{ token = "$load", fg = "#fff", rules = [{ gt = 80, fg = "#f55", bold = true }, { gt = 50, fg = "#fc0" }] }],
|
||||
]
|
||||
```
|
||||
|
||||
只有第一条匹配的规则生效。指定的样式字段覆盖当前位置的默认值,未指定的字段保持继承。没有规则匹配时保留默认样式。匹配使用显示截断前的完整值,不改变文本、分隔符或可见性。没有样式字段的规则一旦匹配,就会停止后续匹配并保留默认样式。
|
||||
|
||||
`equals`、`contains` 和 `starts_with` 接受字符串,默认区分大小写。添加 `ignore_case = true` 可忽略 ASCII 大小写,非 ASCII 字符仍区分大小写。空字符串遵循普通字符串匹配:空的 `equals` 只匹配空值,空的 `contains` 或 `starts_with` 匹配任何已存在的值。
|
||||
|
||||
`gt` 和 `lt` 接受有限数值阈值,分别进行严格大于和小于比较,不包含等于。整个值必须能解析为有限数值;支持小数和指数形式,但带空白、单位、`NaN` 或无穷大的值不会匹配。数值规则不接受 `ignore_case`。比较使用浮点数,不保证大整数的精确比较。
|
||||
|
||||
规则适用于 Agent 行、`rows_by_agent` 覆盖和 Space 行中的文本值内置 token 及自定义 `$name` token。上例中,`$load` 报告 `"90"` 时显示红色粗体,`"60"` 时显示黄色,`"90%"` 时保持白色。未报告的 token 仍然不显示。`state_icon` 和复合 token `git_status` 仅接受固定样式,不支持规则。未知条件或格式错误的规则会在加载配置时被拒绝;不支持正则表达式、模糊匹配或脚本。
|
||||
|
||||
`row_gap` 分别控制 Agent 和 Space 面板中条目之间的空白终端行数。默认值为 `0`,会紧密排列条目;设为 `1` 可恢复之前的间距。它不会在 `rows` 声明的内容行之间添加间距。连续缩进的 worktree 子项仍会作为一个 Space 组紧密排列。
|
||||
|
||||
在 `rows_by_agent` 下为已知智能体覆盖完整的 Agent 布局:
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
---
|
||||
title: 连接机器
|
||||
description: 在一个 Herdr 窗口中使用 Local 和已保存的 SSH 机器,集中查看智能体,各连接独立重连。
|
||||
---
|
||||
|
||||
将本地工作和远程智能体放在同一个 Herdr 窗口中。SSH 机器只需保存一次,就能在它的工作区与 Local 之间切换,无需再开一个客户端。智能体列表汇总已连接的机器,让你看到工作在哪里运行,以及谁在等待回答。
|
||||
|
||||
每台机器保留自己的 Herdr 服务器、会话和进程。一台机器断线不会影响其他连接。
|
||||
|
||||
## 连接前的准备
|
||||
|
||||
你需要能够通过普通 SSH 访问远程机器。先验证:
|
||||
|
||||
```bash
|
||||
ssh workbox
|
||||
```
|
||||
|
||||
`workbox` 可以是 SSH 配置中的主机名,也可以使用 `ssh://you@server:2222` 这样的目标。
|
||||
|
||||
多机器连接支持 Linux 和 macOS 客户端,连接目标为 x86_64 或 aarch64 的 Linux 和 macOS 服务器。Windows 上的多机器连接尚未验证,也暂不受支持;独立连接命令 `herdr --remote` 仍支持 Windows。原生 Windows 服务器不能作为 SSH 目标。有关 SSH 配置、认证和自定义二进制文件,请参阅[通过 SSH 远程连接](/zh-cn/docs/persistence-remote/)。
|
||||
|
||||
## 添加机器
|
||||
|
||||
请在交互式终端中运行,以便 Herdr 在安装或替换内容之前询问:
|
||||
|
||||
```bash
|
||||
herdr machine add workbox --label "Build machine"
|
||||
```
|
||||
|
||||
这会使用远程默认会话。一个机器配置只对应一个远程会话,不会汇总该主机的所有会话。
|
||||
|
||||
如需命名会话,再添加可选的 `--remote-session`:
|
||||
|
||||
```bash
|
||||
herdr machine add workbox --label "Build machine" --remote-session agents
|
||||
```
|
||||
|
||||
Herdr 分别检查已安装的二进制文件和运行中的服务器,并在保存配置之前启动目标后台服务器。客户端和服务器版本只要兼容,就不必一致。未安装或不兼容时会进入需要批准的设置流程。如果必须替换运行中的服务器,会先询问是否停止它及其窗格进程,再启动兼容的服务器。默认回答为 No;同时需要安装和替换时,一次确认涵盖两项操作。`machine add` 不使用实验性的实时交接。取消或设置失败时,不会保存配置。
|
||||
|
||||
运行 `herdr` 打开 UI。如果本地客户端已经打开,新增或启用的机器通常会在一秒内出现并在后台连接,不改变当前选择。切换机器期间的配置变化会在切换完成后应用。设置结束后,远程服务器仍会运行。
|
||||
|
||||
## 切换机器
|
||||
|
||||
在侧边栏选择机器或其工作区。只有选中的机器接收窗格输入和终端尺寸,并提供可见的终端内容和图形。其他已连接机器仍会更新工作区信息、智能体状态和通知,但不传输窗格画面。
|
||||
|
||||
启动时会立即打开 Local,不等待 SSH 连接。一台机器无响应不会阻塞其他机器的输入。多个 Herdr 客户端也可以独立查看同一服务器上的不同标签页;共享标签页的尺寸规则见[客户端与服务器](/zh-cn/docs/concepts/)。
|
||||
|
||||
断线后,最后的工作区和智能体状态仍然可见,但会变暗。这是缓存,不是实时状态。在新连接和对应画面到达前,不能输入或导航到这些缓存窗格。重连不会从正在使用的机器抢走选择。
|
||||
|
||||
## 重命名、禁用或移除
|
||||
|
||||
从列表读取配置 ID,不要根据标签或主机名推测:
|
||||
|
||||
```bash
|
||||
herdr machine list
|
||||
herdr machine rename <profile-id> --label "New name"
|
||||
herdr machine disable <profile-id>
|
||||
herdr machine enable <profile-id>
|
||||
herdr machine remove <profile-id>
|
||||
```
|
||||
|
||||
用于脚本时,可给 `machine list` 添加 `--json`。
|
||||
|
||||
重命名只修改显示标签,不会重连。禁用会保留配置供以后使用,移除则会忘记该配置。两者都只从客户端断开该机器,即使主机无法访问也可以操作;远程会话和智能体仍会运行。
|
||||
|
||||
移除或禁用正在查看的机器会返回 Local。如果 Local 不可用,Herdr 会显示该状态并重试连接,而不是选择其他远程机器。有已启用的保存机器时,即使 Local 失败或重启,客户端仍可继续使用。
|
||||
|
||||
## 连接问题
|
||||
|
||||
- **Reconnecting:** 网络中断、睡眠或 SSH 故障后,Herdr 会以有上限的退避间隔重试。SSH 连接会监测应用层活动并在空闲时探测,避免已断开的连接一直显示 Online。Local 使用本地连接关闭或失败来判断断线,而不是远程健康探测。
|
||||
- **Attention:** 目标需要无法在后台完成的操作,例如批准主机密钥、认证或准备兼容服务器。其他机器仍可使用。
|
||||
- **保存机器文件错误:** 目录文件无法读取或内容无效时,当前连接保持不变。Herdr 会显示通知并自动重试读取。
|
||||
|
||||
后台连接不会回答提示,也不会安装、更新、重启或交接服务器。对于 Attention,请在交互式终端运行 Herdr 显示的独立设置命令,例如:
|
||||
|
||||
```bash
|
||||
herdr --remote workbox
|
||||
```
|
||||
|
||||
使用配置中的目标。如果添加时选择了命名会话,再加上可选的 `--session <name>`。完成批准提示后,重启客户端以重试 Attention 连接。不要仅因为版本与客户端不同就停止运行中的服务器。
|
||||
|
||||
认证失败时,先检查普通 SSH。对于有口令的私钥,请在启动 Herdr 的非交互式后台连接前用 `ssh-add` 加载。
|
||||
|
||||
## 设置与自动化
|
||||
|
||||
UI 默认使用客户端本地的主题、侧边栏设置和按键绑定。选中服务器公布的自定义命令和插件仍在那里运行。Herdr 不会将本地插件、配置、可执行文件或机密复制到 SSH 主机。远程缺少命令时会明确报错。编辑客户端设置后,使用 UI 中的 `reload config`;参见[配置](/zh-cn/docs/configuration/)。
|
||||
|
||||
有多台机器时,默认智能体行会显示 `machine` token。已有的自定义行保持不变;需要机器标签时请显式加入 `machine`。[侧边栏行布局](/zh-cn/docs/configuration/)还支持按机器标签设置条件颜色。
|
||||
|
||||
工作区、标签页、窗格 ID 和智能体名称仅在所属服务器内有效。两台机器可能都有 `w1:p1` 或名为 `reviewer` 的智能体。在 UI 中选择机器不会改变已有窗格中 CLI 命令的目标,它们仍使用继承的会话和 socket。远程自动化应在目标主机上针对目标会话执行命令,并在那里读取 ID。
|
||||
|
||||
## 更新与保存的数据
|
||||
|
||||
配置只保存不透明 ID、标签、SSH 目标、明确的远程会话名和启用状态。Herdr 不会将密码、私钥、智能体票据或 SSH 控制套接字存入机器目录。认证仍由 OpenSSH 处理。
|
||||
|
||||
客户端与服务器协商兼容性,不要求版本完全相同。保存机器的连接还需要服务器支持 `surface_interest` 和 `health_check` 能力。缺少这些能力的旧服务器,即使能独立连接,也会显示 Attention,直到明确更新。其他缺失的方法只禁用对应操作。
|
||||
|
||||
更新兼容客户端不会替换远程服务器或停止其智能体。需要新的服务器行为时,请明确更新该服务器。正常替换会在停止服务器及其窗格进程之前询问。
|
||||
|
||||
实时交接是实验性的,需要明确选择。独立设置过程中需要替换受支持的服务器时,可为 `herdr --remote` 显式添加 `--handoff`;正常连接或认证修复不需要它。有关重启和交接的选择,请参阅[更新](/zh-cn/docs/install/)及[会话状态与恢复](/zh-cn/docs/session-state/)。
|
||||
@@ -77,7 +77,7 @@ herdr --remote workbox
|
||||
herdr --remote ssh://you@server:2222
|
||||
```
|
||||
|
||||
你本地的 Herdr 充当瘦客户端。它通过 SSH 连接,启动或连接远程 Herdr 服务器,并把 UI 流式传回你的本地终端。
|
||||
远程服务器保持窗格运行,并通过 SSH 发送终端内容和会话状态。本地 Herdr 使用本地主题和显示设置绘制 UI。
|
||||
|
||||
想让远程会话用起来像本地时,用这条路径。客户端运行在你的机器上,所以图像剪贴板粘贴等本地桌面功能可以桥接到远程服务器。如果你先 SSH 再在服务器上运行 `herdr`,Herdr 就完全运行在那台服务器上,无法读取你本地桌面的剪贴板。
|
||||
|
||||
@@ -98,6 +98,6 @@ herdr --remote workbox
|
||||
|
||||
## 该用哪条路径
|
||||
|
||||
本地工作用 `herdr`。想让 Herdr 在远程 shell 上表现得像 tmux,或者在用手机 SSH 客户端时,用 `ssh you@server` 再 `herdr`。想要一个连接远程会话的本地瘦客户端 (包括本地剪贴板图像粘贴桥接) 时,用 `herdr --remote <host>`。
|
||||
本地工作用 `herdr`。想让 Herdr 在远程 shell 上表现得像 tmux,或者在用手机 SSH 客户端时,用 `ssh you@server` 再 `herdr`。需要通过本地 UI 操作一个远程会话并粘贴本地剪贴板图像时,使用 `herdr --remote <host>`。要在同一窗口使用 Local 和多台 SSH 机器,可通过 `herdr machine add <host> --label <label>` 保存目标;参见[连接机器](/zh-cn/docs/connecting-machines/)。
|
||||
|
||||
关于远程引导细节、命名远程会话、自定义二进制和直接终端附加,参见[持久化与远程访问](/zh-cn/docs/persistence-remote/)。
|
||||
|
||||
@@ -49,6 +49,11 @@ Help me understand and set up Herdr. Read https://herdr.dev/agent-guide.md first
|
||||
|
||||
[理解智能体 →](/zh-cn/docs/agents/)
|
||||
</Card>
|
||||
<Card title="连接机器">
|
||||
在同一窗口使用 Local 和已保存的 SSH 机器,集中查看智能体,各连接独立重连。
|
||||
|
||||
[连接你的机器 →](/zh-cn/docs/connecting-machines/)
|
||||
</Card>
|
||||
<Card title="会话状态">
|
||||
理解分离、重启恢复、窗格历史回放、智能体原生会话恢复和实时交接。
|
||||
|
||||
|
||||
@@ -37,53 +37,20 @@ herdr session delete side-project --json
|
||||
|
||||
## 已保存的 SSH 机器
|
||||
|
||||
保存常用目标后,即可从一个 Herdr 客户端跨多台机器工作:
|
||||
|
||||
```bash
|
||||
herdr machine add workbox --label "Build machine" --remote-session agents
|
||||
herdr machine add ssh://you@server:2222 --label "Production" --remote-session operations
|
||||
herdr machine list
|
||||
```
|
||||
|
||||
`machine add` 会在远程机器上准备 Herdr,并在保存配置前启动指定会话的后台服务器。它会分别检查运行中的服务器和已安装的二进制文件;即使服务器的发行版本与客户端不同,只要兼容就会保留。如果运行中的服务器需要升级,设置过程会在停止活动窗格进程前询问,默认回答为 No。安装和重启只需确认一次。`machine add` 不会自动启用实验性实时交接。未安装或不兼容时,使用与 `--remote` 相同的批准流程;需要批准时请在交互式终端中运行。取消设置不会保存配置。设置退出后,远程服务器会继续运行。
|
||||
|
||||
已保存机器的更改会自动应用到已打开的本地 Herdr 客户端,通常在一秒内生效。如果正在切换机器,会等待切换完成再应用更改。新增或启用的 SSH 机器会与 Local 一起显示在机器侧边栏中,并在后台连接,不会改变当前选择。选择机器或其工作区即可切换。Herdr 保留已连接机器的元数据、agent 状态和通知,但只为选中的机器传输窗格画面、输入、显示区域和图形。即使两个服务器碰巧使用相同的内部 ID,工作区、标签页、窗格、agent 和图形的身份也始终按机器隔离。
|
||||
|
||||
启动时会直接打开 Local,不等待已保存的 SSH 机器,也不显示连接标记。有已启用的保存机器时,即使 Local 连接失败,客户端仍能打开。停止或重启 Local 不会关闭正常的 SSH 连接。Local 服务器恢复后会自动重连,不会从正在使用的机器抢走选择。无响应的机器不会阻塞其他机器的输入或连接处理。
|
||||
|
||||
Herdr 会监测已连接 SSH 机器的应用层活动,并在空闲时使用轻量健康探测。Local 依靠本地连接关闭或失败来判断断开,不使用远程健康探测。睡眠、网络中断或 SSH 故障后,不健康的机器会显示 Reconnecting,并以有上限的退避间隔重试。最后的工作区、agent 和选中窗格状态会保留,但变暗并冻结;在新连接和一致的画面到达前,无法输入或导航到这些缓存状态。重连不会回答提示,也不会安装、更新、重启或交接远程服务器。需要批准主机密钥、完成认证或安装兼容 Herdr 的目标会显示 Attention,Local 和其他机器仍可正常使用。请在终端中运行该配置对应的独立连接命令来完成设置,例如:
|
||||
|
||||
```bash
|
||||
herdr --remote workbox --session agents
|
||||
```
|
||||
|
||||
如果机器显示 Attention,请在设置完成后重启客户端以重试连接。使用配置的不透明 ID 来重命名、禁用或移除:
|
||||
|
||||
```bash
|
||||
herdr machine rename <profile-id> --label "New name"
|
||||
herdr machine disable <profile-id>
|
||||
herdr machine enable <profile-id>
|
||||
herdr machine remove <profile-id>
|
||||
```
|
||||
|
||||
重命名只更新标签,不会重新连接。移除或禁用只会将该机器从客户端断开;即使机器无法访问也可操作,其远程会话仍会继续运行。如果移除或禁用正在查看的机器,客户端会返回 Local。如果 Local 不可用,会显示该状态并尝试重连,而不是选择另一台远程机器。保存机器的文件无法读取或内容无效时,当前连接保持不变,客户端会显示通知并自动重试读取。
|
||||
|
||||
保存的配置仅包含不透明 ID、标签、SSH 目标、明确的远程会话名和启用状态。密码、私钥、agent 票据和 SSH 控制套接字绝不会存入机器目录。
|
||||
|
||||
客户端默认使用本地按键绑定。选中机器公布的自定义命令仍在该机器上执行。Herdr 不会将本地命令插件、配置、可执行文件或机密复制到 SSH 主机;远程缺少命令或插件时会明确报错。
|
||||
要在一个 Herdr 窗口中使用 Local 和多台 SSH 机器,请参阅[连接机器](/zh-cn/docs/connecting-machines/)。该指南涵盖设置、切换、重连、配置和远程自动化。移除已保存的机器只会断开客户端,不会停止远程会话。
|
||||
|
||||
## 通过 SSH 远程连接
|
||||
|
||||
远程模式有两种;[使用 Herdr 的工作方式](/zh-cn/docs/how-to-work/)对它们做了比较。tmux 风格的路径是 SSH 到服务器并在那里运行 `herdr`。另一种是从本地机器通过 SSH 连接:
|
||||
[使用 Herdr 的工作方式](/zh-cn/docs/how-to-work/)比较了几种远程连接方式:先 SSH 到服务器再运行 `herdr`,使用已保存的 SSH 机器集中管理多个目标,或从本地直接连接一个远程会话:
|
||||
|
||||
```bash
|
||||
herdr --remote workbox
|
||||
herdr --remote ssh://you@server:2222
|
||||
```
|
||||
|
||||
这种模式下,你本地的 Herdr 是瘦客户端。它通过 SSH 连接,启动或连接远程 Herdr 服务器,并把 UI 流式传回本地终端。因为客户端在本地运行,Herdr 可以把图像剪贴板粘贴等本地桌面功能桥接到远程会话: 把图像复制到远程临时文件,再粘贴该路径。
|
||||
这种模式下,远程服务器保持窗格运行,并通过 SSH 发送终端内容和会话状态。本地 Herdr 负责绘制 UI,包括侧边栏、菜单和主题。因为客户端在本地运行,Herdr 可以把图像剪贴板粘贴等本地桌面功能桥接到远程会话: 把图像复制到远程临时文件,再粘贴该路径。
|
||||
|
||||
默认情况下,`herdr --remote` 在这次连接中使用你本地的 Herdr 按键绑定。即使远程服务器的配置不同,也能保持本地的肌肉记忆。本地按键绑定是连接时的快照;编辑本地按键绑定后请分离再重连。想改用远程服务器配置时,使用 `--remote-keybindings server`。本地的自定义命令按键绑定不会被发送,因为那些命令会在远程主机上执行。
|
||||
默认情况下,`herdr --remote` 在这次连接中使用你本地的 Herdr 按键绑定。即使远程服务器的配置不同,也能保持本地的肌肉记忆。编辑本地按键绑定后,可通过 UI 中的 `reload config` 应用更改,无需分离重连。想改用远程服务器配置时,使用 `--remote-keybindings server`。本地的自定义命令按键绑定不会被发送,因为那些命令会在远程主机上执行。
|
||||
|
||||
对于经常连接的目标,使用你的 SSH 配置:
|
||||
|
||||
@@ -100,11 +67,20 @@ Host workbox
|
||||
herdr --remote workbox
|
||||
```
|
||||
|
||||
远程连接支持 Linux、macOS 和 Windows 本地客户端连接 x86_64 与 aarch64 的 Linux 和 macOS 主机。Herdr 会检查远程平台,优先使用远程 `PATH` 上已有的匹配 `herdr`,然后检查常见的直接安装、Homebrew、mise 和 Nix profile 路径。如果没有匹配的二进制文件,交互式运行会询问是否安装到 `~/.local/bin/herdr`;非交互式运行则直接失败,不会修改主机。如果 `~/.local/bin` 不在远程 `PATH` 上,Herdr 会在安装后发出警告。Windows 不能作为远程主机。
|
||||
远程连接支持 Linux、macOS 和 Windows 本地客户端连接 x86_64 与 aarch64 的 Linux 和 macOS 主机。Herdr 会检查远程平台,优先使用远程 `PATH` 上兼容的 `herdr`,然后检查常见的直接安装、Homebrew、mise 和 Nix profile 路径。只要两端都支持稳定端点代数,客户端和服务器的发行版本就不必一致。如果没有兼容的二进制文件,交互式运行会询问是否安装到 `~/.local/bin/herdr`;非交互式运行则直接失败,不会修改主机。如果 `~/.local/bin` 不在远程 `PATH` 上,Herdr 会在安装后发出警告。Windows 不能作为远程主机。
|
||||
|
||||
默认情况下,`herdr --remote` 通过一个临时 SSH 配置运行远程设置和桥接: 先包含你的 SSH 配置,再补充兜底的保活设置。已有的用户保活设置优先。Linux 和 macOS 客户端还会添加一个私有的单次连接 control socket 来复用连接;Windows OpenSSH 不使用此方式。设置 `[remote].manage_ssh_config = false` 可以不用 Herdr 生成的配置或 control socket,而使用普通 `ssh`。
|
||||
|
||||
默认情况下,如果需要替换或重启运行中的远程服务器,远程连接使用常规的重启/停止流程。要对受支持的运行中远程服务器启用实验性实时交接,加上 `--handoff`:
|
||||
远程连接使用正常的 OpenSSH 认证。如果在非交互式 shell、脚本、CI 或移动终端中无法输入私钥口令,请先将密钥加载到 ssh-agent:
|
||||
|
||||
```bash
|
||||
ssh-add
|
||||
herdr --remote workbox
|
||||
```
|
||||
|
||||
认证失败时,先通过 `ssh workbox` 确认普通 SSH 连接正常。
|
||||
|
||||
仅有版本差异不会替换或重启运行中的远程服务器。缺少必要兼容性或独立后台运行支持的服务器,会在停止前询问。已保存机器还需要画面传输和健康探测能力,详见[连接机器](/zh-cn/docs/connecting-machines/)。默认回答为 No;停止服务器会结束窗格进程。进行这次一次性升级时,可对受支持的服务器加上 `--handoff`,通过实验性实时交接保留窗格进程:
|
||||
|
||||
```bash
|
||||
herdr --remote workbox --handoff
|
||||
@@ -132,7 +108,7 @@ herdr --remote workbox --session agents
|
||||
|
||||
完整的 Herdr 连接会打开整个工作区 UI。直接附加则在你当前的终端中打开一个由服务器拥有的终端。
|
||||
|
||||
在 Windows 上,直接终端附加仅限 Unix。
|
||||
直接终端附加适用于 Linux 和 macOS,不支持原生 Windows。
|
||||
|
||||
按智能体目标附加:
|
||||
|
||||
@@ -155,3 +131,19 @@ herdr terminal attach term_abc123
|
||||
```bash
|
||||
herdr terminal attach term_abc123 --takeover
|
||||
```
|
||||
|
||||
对于只需要读取已渲染终端数据的第三方桥接,可以使用只读观察者:
|
||||
|
||||
```bash
|
||||
herdr terminal session observe w1:p1 --cols 120 --rows 40
|
||||
```
|
||||
|
||||
它以逐行 JSON 输出包含 base64 ANSI 数据的 `terminal.frame`,服务器关闭流时输出 `terminal.closed`。多个观察者可以同时查看同一终端,不会取得输入、调整尺寸、滚动或接管权限。
|
||||
|
||||
交互式桥接可使用可写控制器:
|
||||
|
||||
```bash
|
||||
herdr terminal session control w1:p1 --takeover --cols 120 --rows 40
|
||||
```
|
||||
|
||||
控制模式输出相同的帧,并从标准输入读取逐行 JSON 命令。`terminal.input` 发送文本或 base64 数据,`terminal.resize` 更改视口尺寸,`terminal.scroll` 滚动视口,`terminal.release` 关闭控制器。同一时间只有一个控制器能拥有输入和调整尺寸的权限。
|
||||
|
||||
@@ -745,6 +745,6 @@ herdr agent wait w1:p1 --until blocked
|
||||
|
||||
## 协议稳定性
|
||||
|
||||
由客户端渲染的 Herdr UI 对本地和 SSH 服务器使用稳定的端点代数。客户端和服务器构建不必一致。连接时,双方会协商核心快照、屏幕、输入和 blob 编解码器,服务器则公布它支持的 API 方法。缺少方法时,只禁用该服务器上的对应操作并显示客户端本地通知;操作被拒绝或超时也不会断开连接。只有早于端点第 1 代的服务器需要最后更新一次。
|
||||
由客户端渲染的 Herdr UI 对本地和 SSH 服务器使用稳定的端点代数。客户端和服务器构建不必一致。连接时,双方会协商核心快照、屏幕、输入和 blob 编解码器,服务器则公布支持的 API 方法和可选能力。已保存的 SSH 机器需要 `surface_interest` 来确保只有选中的机器传输窗格画面,并需要 `health_check` 来发现空闲连接的故障。缺少这些能力的服务器会显示 Attention,直到明确更新。详见[连接机器](/zh-cn/docs/connecting-machines/)。缺少方法时,只禁用该服务器上的对应操作并显示客户端本地通知;操作被拒绝或超时也不会断开连接。只有早于端点第 1 代的服务器需要最后更新一次。
|
||||
|
||||
带编号的二进制协议仍用于同一安装内的内部操作,包括直接终端连接和实时交接。跨不同构建使用这些操作前,请检查 `ping` 或 `herdr status`。JSON API 客户端应忽略未知字段,并把不支持的方法当作普通错误处理。
|
||||
|
||||
@@ -61,7 +61,7 @@ map alt+right send_text all \x1bf
|
||||
|
||||
## Herdr 已更新,但运行中的会话仍是旧版本
|
||||
|
||||
更新二进制文件不一定会替换已经运行且兼容的服务器。先检查 `herdr status`。要启动更新后的服务器,请停止会话并重新启动 Herdr:
|
||||
更新二进制文件不会替换正在运行的兼容服务器。重新打开 Herdr 即可使用更新后的客户端。只有还需要本次发行的服务器功能时,才先检查 `herdr status`,然后停止会话并重新启动 Herdr:
|
||||
|
||||
```bash
|
||||
herdr server stop
|
||||
|
||||
@@ -1057,7 +1057,7 @@
|
||||
{
|
||||
"key": "ui.sidebar.agents.rows",
|
||||
"type": "list of token rows",
|
||||
"default": "[[\"state_icon\", \"workspace\", \"tab\"], [\"agent\"]]",
|
||||
"default": "[[\"state_icon\", \"machine\", \"workspace\", \"tab\"], [\"agent\"]]",
|
||||
"description": "Default expanded Agent sidebar layout. Entries may be token strings or inline { token, fg, bold, dim, rules } style tables. Text-valued built-ins and $name metadata tokens accept up to 16 ordered rules using equals, contains, starts_with, gt, or lt; the first match overrides specified styles. Text conditions optionally accept ignore_case for ASCII matching; numeric conditions require full finite numbers. state_icon accepts fixed styles only. At most 16 rows and 16 tokens per row."
|
||||
},
|
||||
{
|
||||
|
||||
@@ -64,15 +64,7 @@ STAGED_PUBLISHED_MANIFESTS = {
|
||||
),
|
||||
}
|
||||
|
||||
# Muse is bundled on master but has not shipped in a stable binary yet. Stable
|
||||
# clients cannot identify it, so publish it with the release that first ships
|
||||
# the corresponding Agent variant and remove this exact-content exception.
|
||||
UNPUBLISHED_BUNDLED_MANIFESTS = {
|
||||
"muse": (
|
||||
"2026.08.26.1",
|
||||
"b69c4d87fa9c19e3e6453b706fbe39c98a8b33ffbaa48e8cd5ae6751e9615074",
|
||||
),
|
||||
}
|
||||
UNPUBLISHED_BUNDLED_MANIFESTS: dict[str, tuple[str, str]] = {}
|
||||
|
||||
|
||||
def parse_args() -> argparse.Namespace:
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import hashlib
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
|
||||
from scripts import agent_detection_manifest_check as check
|
||||
|
||||
@@ -42,14 +44,21 @@ def staged_grok_dirs(root: Path) -> tuple[Path, Path]:
|
||||
return bundled, published
|
||||
|
||||
|
||||
def unpublished_muse_dirs(root: Path) -> tuple[Path, Path]:
|
||||
UNPUBLISHED_TEST_MANIFEST = manifest("testagent", "2026.06.10.1")
|
||||
UNPUBLISHED_TEST_EXCEPTION = {
|
||||
"testagent": (
|
||||
"2026.06.10.1",
|
||||
hashlib.sha256(UNPUBLISHED_TEST_MANIFEST.encode()).hexdigest(),
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
def unpublished_manifest_dirs(root: Path) -> tuple[Path, Path]:
|
||||
bundled = root / "bundled"
|
||||
published = root / "published"
|
||||
bundled.mkdir()
|
||||
published.mkdir()
|
||||
(bundled / "muse.toml").write_bytes(
|
||||
(check.DEFAULT_BUNDLED_DIR / "muse.toml").read_bytes()
|
||||
)
|
||||
(bundled / "testagent.toml").write_text(UNPUBLISHED_TEST_MANIFEST, encoding="utf-8", newline="\n")
|
||||
(published / "index.toml").write_text("schema_version = 1\nagents = []\n")
|
||||
return bundled, published
|
||||
|
||||
@@ -135,9 +144,10 @@ class AgentDetectionManifestCheckTests(unittest.TestCase):
|
||||
with self.assertRaisesRegex(check.CheckError, "same version"):
|
||||
check.validate_catalog(website, bundled_manifests, engine_version=1)
|
||||
|
||||
@patch.dict(check.UNPUBLISHED_BUNDLED_MANIFESTS, UNPUBLISHED_TEST_EXCEPTION, clear=True)
|
||||
def test_allows_exact_unpublished_bundled_manifest(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
bundled, published = unpublished_muse_dirs(Path(tmp))
|
||||
bundled, published = unpublished_manifest_dirs(Path(tmp))
|
||||
bundled_manifests = check.load_manifest_dir(bundled, engine_version=3)
|
||||
check.validate_catalog(
|
||||
published,
|
||||
@@ -146,17 +156,19 @@ class AgentDetectionManifestCheckTests(unittest.TestCase):
|
||||
allow_unpublished=True,
|
||||
)
|
||||
|
||||
@patch.dict(check.UNPUBLISHED_BUNDLED_MANIFESTS, UNPUBLISHED_TEST_EXCEPTION, clear=True)
|
||||
def test_release_gate_rejects_exact_unpublished_bundled_manifest(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
bundled, published = unpublished_muse_dirs(Path(tmp))
|
||||
bundled, published = unpublished_manifest_dirs(Path(tmp))
|
||||
bundled_manifests = check.load_manifest_dir(bundled, engine_version=3)
|
||||
with self.assertRaisesRegex(check.CheckError, "missing bundled agent"):
|
||||
check.validate_catalog(published, bundled_manifests, engine_version=3)
|
||||
|
||||
@patch.dict(check.UNPUBLISHED_BUNDLED_MANIFESTS, UNPUBLISHED_TEST_EXCEPTION, clear=True)
|
||||
def test_rejects_mutated_unpublished_bundled_manifest(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
bundled, published = unpublished_muse_dirs(Path(tmp))
|
||||
with (bundled / "muse.toml").open("a") as manifest_file:
|
||||
bundled, published = unpublished_manifest_dirs(Path(tmp))
|
||||
with (bundled / "testagent.toml").open("a") as manifest_file:
|
||||
manifest_file.write("\n# unexpected mutation\n")
|
||||
bundled_manifests = check.load_manifest_dir(bundled, engine_version=3)
|
||||
with self.assertRaisesRegex(check.CheckError, "missing bundled agent"):
|
||||
|
||||
Reference in New Issue
Block a user