Document that the Hub server does not read ~/.tmux.conf and how to opt into a custom file, list the control and keys subcommands, describe the background local-session query and corrupt-aliases behaviour, and rephrase the "Herdr 0.8.2" statements as design-time notes so they no longer contradict the 0.9+ requirement. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
378 lines
22 KiB
Markdown
378 lines
22 KiB
Markdown
# herdr-hub
|
||
|
||
`herdr-hub` 是一个 Linux 下的 Herdr session 切换器。它让 tmux 做最外层路由,
|
||
把每个本地或 `herdr --remote` attach 放进独立 tmux window,并在 Herdr 画面顶部
|
||
显示可点击的 Sessions 条。
|
||
|
||
它不是 Herdr 插件,也不会修改 Herdr core。设计本工具时的 Herdr(0.8.2)插件 API 不能向原生
|
||
sidebar 插入 UI,也不能让 thin client 从一个 server 原地改连另一个 server;
|
||
所以顶部状态栏横跨整个终端,而不是只嵌在 Spaces 上方。
|
||
|
||
## 功能
|
||
|
||
- 自动读取 `herdr session list --json`,导入本机正在运行的 sessions。
|
||
- 记住使用过的远端,并通过 SSH 实时读取运行中及已停止的 Herdr sessions。
|
||
- 远端查询兼容 Windows OpenSSH 与 Linux/macOS shell;Windows target 自动改用并持久记住 SSH TTY 模式。
|
||
- 在 Linux `/proc/*/cmdline` 中查找仍在运行的 `herdr --remote …` clients,并自动记住目标。
|
||
- 首次接管已有 remote client 时安全地再 attach,不结束原进程。
|
||
- 一个 endpoint 对应一个 tmux window,隐藏 window 中的连接继续在线。
|
||
- 顶部 Sessions 条在窄屏下也为每个 Tab 显示主机优先的短名称,并支持鼠标点击、数字切换和无需 fzf 的动态 popup 选择。
|
||
- 可隐藏不再需要的 Tab,而不停止底层本地或远端 Herdr Session。
|
||
- 可在 Sessions 管理弹窗中为 Tab 设置持久化显示名称,或恢复默认名称。
|
||
- dead window 留在顶栏,可原地重连。
|
||
- 不读取也不修改 `~/.tmux.conf`:Hub 的 tmux server 以 `-f /dev/null` 启动,用户主题和按键绑定不会渗入;不保存 SSH 凭据或远端 Session 缓存。
|
||
|
||
## 依赖
|
||
|
||
- Linux
|
||
- Python 3.11+
|
||
- tmux 3.4+
|
||
- Herdr 0.9+(本地和需要 Fork 的远端目标均需支持 0.9 的控制 API)
|
||
- OpenSSH client
|
||
|
||
检查当前环境:
|
||
|
||
```bash
|
||
./bin/herdr-hub doctor
|
||
```
|
||
|
||
## 安装
|
||
|
||
直接从仓库运行:
|
||
|
||
```bash
|
||
./bin/herdr-hub
|
||
```
|
||
|
||
或把启动器链接到 `~/.local/bin`:
|
||
|
||
```bash
|
||
make install
|
||
herdr-hub doctor
|
||
```
|
||
|
||
安装脚本只创建一个指向本仓库的符号链接。移动或删除仓库后需重新安装。
|
||
|
||
## 第一次接管
|
||
|
||
如果本地和 remote Herdr clients 已经分别开在其他终端中:
|
||
|
||
1. 保持这些 clients 运行。
|
||
2. 从一个新的、未嵌套在 tmux 中的终端执行 `herdr-hub`。
|
||
3. Hub 扫描现有 clients,并为每个 endpoint 创建一个新的 attach window。
|
||
4. 确认 Hub 中可以正常操作后,手动退出原来的 clients。
|
||
|
||
tmux 不能把另一个终端里已经运行的进程搬进 window,所以首次接管会短暂存在两个
|
||
clients;它们连接的是同一个 Herdr server,不会复制 server 或 panes。
|
||
|
||
只有一个终端时,本地 Herdr 可以先 detach,因为 `herdr session list` 仍能发现后台
|
||
server。remote target 在 client 退出后没有本地记录,因此直接使用:
|
||
|
||
```bash
|
||
herdr-hub open --remote orangepi
|
||
herdr-hub open --remote orangepi --session work
|
||
herdr-hub open --remote ssh://me@server:2222 --remote-keybindings server
|
||
herdr-hub open --remote windows-host --transport ssh
|
||
```
|
||
|
||
打开本地 named session:
|
||
|
||
```bash
|
||
herdr-hub open --session work
|
||
```
|
||
|
||
`open` 会把 endpoint 保存在当前 tmux hub 的 window metadata 中。远端 target 还会
|
||
同时加入 `~/.config/herdr-hub/remotes.json`,以后可直接从 Sessions
|
||
弹窗浏览这台机器上的其他 Session。
|
||
|
||
## 日常操作
|
||
|
||
Hub 使用独立 tmux socket `herdr-hub`,不会接管普通 tmux server。外层前缀固定为
|
||
`Ctrl+A`,Herdr 原来的 `Ctrl+B` 可以直接使用。Hub server 不读取 `~/.tmux.conf`,
|
||
因此主题的 `status-format` 和 root 表按键不会覆盖顶栏或抢占 Herdr 的按键;如需附加
|
||
自定义配置,设置 `HERDR_HUB_TMUX_CONFIG=/path/to/file` 后重新启动 Hub(`herdr-hub stop`
|
||
再执行 `herdr-hub`)。
|
||
|
||
| 操作 | 快捷键 / 命令 |
|
||
| --- | --- |
|
||
| 打开快捷键帮助 | `Ctrl+A ?` |
|
||
| 点击切换 | 鼠标点击顶部 session |
|
||
| 打开 Herdr 命令菜单 | `Ctrl+A h` |
|
||
| 打开 Session 弹窗 | 点击左上角 `Sessions` 或 `Ctrl+A g` |
|
||
| 上一个/下一个 window | `Ctrl+A p` / `Ctrl+A n` |
|
||
| 按编号切换 | `Ctrl+A 0..9` |
|
||
| 扫描新增 sessions | `Ctrl+A r` 或 `herdr-hub refresh` |
|
||
| 强制重连当前 window | `Ctrl+A R` |
|
||
| 关闭/隐藏当前 Tab | `Ctrl+A q`,确认 `y`;也可在 Sessions 弹窗中选择 |
|
||
| 关闭并停止远端 Session | Sessions 弹窗 → 选中 Session → `Space` / `[⋯]` → `关闭并停止 Session` |
|
||
| 修改 Tab 显示名称 | Sessions 弹窗 → 选中 Session → `Space` / `[⋯]` → `修改显示名称` |
|
||
| detach Hub | `Ctrl+A d` |
|
||
| 重新进入 Hub | `herdr-hub` |
|
||
| 停止 Hub clients | `herdr-hub stop` |
|
||
|
||
### Fork 当前 Agent 到新 Tab
|
||
|
||
按 **Ctrl+A h** 打开独立的 Herdr 命令菜单,选择“Fork 当前会话到新 Tab”,
|
||
按 Enter 或单击执行,Esc 关闭。菜单显示当前 Agent、Workspace、Fork 和更新操作及必要的状态信息。
|
||
操作正在执行时需等待结果后再关闭,以免将关闭弹窗误认为取消已经发送的请求。
|
||
Sessions 弹窗仍使用 `Ctrl+A g`;两个菜单都使用 Hub 外层的 `Ctrl+A` 前缀。
|
||
快捷键集中定义在 `herdr_hub/control.py` 的 `CONTROL_KEY` 常量中。
|
||
|
||
Fork 复制的是 **Codex / Claude conversation**,并保留正在运行的原 Agent 和原 Tab。
|
||
它在同一个 Herdr Workspace、相同 cwd 新建 Tab,使用当前 pane 已报告的 conversation ID:
|
||
Codex 执行 `codex fork UUID`;Claude 执行 `claude --resume SESSION_ID --fork-session`。
|
||
新 Agent 被 Herdr 确认为就绪后才切换焦点。它不会新建外层 Herdr named session,
|
||
也不会创建 Git worktree;两个 Agent 会编辑同一工作目录,需自行协调并发修改。
|
||
|
||
支持本地 default / named session,以及通过 SSH 控制的远端 native / Windows SSH endpoint。
|
||
控制目标取自触发菜单的 Hub window metadata,不使用 popup 继承的 Herdr socket 或 pane 环境变量。
|
||
目标必须运行 Herdr 0.9+,并安装对应 Agent;当前 pane 必须已报告可用的 Agent session ID。
|
||
Fork 显示灰色时,菜单会说明原因;按 `Ctrl+R` 可重新读取当前 Agent 信息。
|
||
若提示尚未上报会话 ID,在该主机检查 `herdr integration status`,确认对应 Agent 的集成已加载。
|
||
识别出 Codex / Claude 并不代表已经取得 conversation ID;Hub 不会根据目录猜测会话。
|
||
远端控制使用非交互 SSH(需要已信任的主机密钥和可用认证);Windows 需要 PowerShell。
|
||
启动 blocked、失败、超时或响应不完整时,菜单保留错误信息,**不会自动关闭任何 Tab**。
|
||
超时并不代表远端没有创建或启动成功,请先检查提示中的新 Tab,再重新打开菜单重试。
|
||
|
||
CLI 入口是 `herdr-hub control`。弹窗打开时会锁定 Hub 当前激活的 managed window,
|
||
再从其 Endpoint 对应的 Herdr server 读取当前页面的 Agent conversation。
|
||
更新后运行 `herdr-hub refresh` 配置现有 Hub 的快捷键。`herdr-hub doctor` 会显示入口和版本要求。
|
||
|
||
### 从命令菜单更新 Herdr
|
||
|
||
需要让运行中的服务器也使用新版本时,按 **Ctrl+A h → 更新并热重启 Herdr**。
|
||
此操作先更新当前 Tab 所在主机的 Herdr,再对当前 Session 执行实验性的 live handoff,
|
||
尝试保留 Agent、shell 和其他 pane 进程。它会核对服务器版本;确认使用更新后的版本后,
|
||
自动关闭菜单并重新连接打开菜单时的那个 Hub Tab。即使此前已安装新版本、服务器仍是旧版,
|
||
也会尝试热切换。该 Session 内的所有 Workspace/Tab 共用服务器,因此都会随之切换。
|
||
|
||
更新阶段使用 `herdr --session NAME update --handoff`,兼容 0.8.x 在非交互 SSH 下的更新要求。
|
||
原生更新已经尝试热切换却未切换成功时,不会再次发送请求;仅在安装文件未变化、旧服务器仍运行时补做热切换。
|
||
|
||
热切换适用于支持该能力的 Linux/macOS Herdr 服务器;远端还需有 `python3`。
|
||
Windows 不支持此入口,可以使用下面的普通更新。失败、超时、服务器不支持或未确认新版本时,
|
||
菜单保留诊断,不自动执行普通重启,也不重试热切换。连接中断时操作可能已经完成,请先检查
|
||
目标 Session。普通重启会结束 pane 进程;缺少会话 ID 的 Agent 不能保证自动恢复。
|
||
|
||
按 **Ctrl+A h**,选择“更新 Herdr”,按 Enter 或单击执行。更新目标跟随打开菜单时的
|
||
当前 Hub Tab:本地 Session 更新本机,远端 Session 通过 SSH 更新对应主机(包括 Windows)。
|
||
菜单会显示目标主机;更新作用于该主机的 Herdr 安装,而非单个 Session。当前 pane 没有
|
||
Agent 或无法读取 Agent 信息时,仍可使用更新操作。
|
||
|
||
该操作执行 `herdr update`,沿用目标主机已有的更新渠道,不传入 `--handoff`。
|
||
它适用于 Herdr 自带安装器管理的安装;Homebrew、mise、Nix 等安装需使用对应包管理器更新。
|
||
这个普通更新入口不自动重启 Session 或重新连接客户端。完成后可关闭菜单,按 `Ctrl+A R` 重新连接;
|
||
服务器端新功能可能仍需另行重启服务器。兼容的服务器会继续运行;旧版本升级若要求停止
|
||
Session 或交互确认,本菜单不会代为确认,请根据命令输出在终端处理。
|
||
|
||
更新在后台执行,实时显示命令输出,最长等待 5 分钟。小窗口自动使用紧凑布局,保证结果区可见。
|
||
下载器没有新输出时,菜单显示已执行时间和无新输出时间。
|
||
读取 Agent 信息期间也可选择更新。结果留在菜单内,可用 Page Up/Down 翻阅,Esc 关闭。
|
||
执行期间需等待结果;同一次菜单内更新只能执行一次,失败或超时也不会自动重试。
|
||
超时或 SSH 断开不代表目标主机已取消更新,请检查目标状态后再重新打开菜单。
|
||
|
||
远端更新使用远端自己的代理。优先保留 SSH 进程已有的 `http_proxy`、`https_proxy`、
|
||
`all_proxy`、`no_proxy`(兼容大写);Linux/macOS 还通过远端 `python3` 读取
|
||
`/etc/environment`、`/etc/profile`、`/etc/profile.d/*.sh`、`~/.config/environment.d/*.conf`
|
||
及用户 profile、bash/zsh 配置中的独立、无缩进的字面量赋值或 `export` 行。
|
||
不会执行整个 shell 配置文件,也不解析命令替换、变量引用或条件表达式。
|
||
没有上述代理变量时,还会读取远端 Clash Verge、Mihomo/Clash 常见运行配置中的
|
||
`mixed-port`、`port` 或 `socks-port`,确认对应回环端口可连接后用于本次更新。
|
||
Linux 下会优先从正在运行的 Mihomo/Clash 进程读取 `-f` / `-d` 指定的配置路径,支持 systemd 服务使用自定义目录。
|
||
这覆盖了 TUN 模式下没有环境变量的情况,不会修改桌面系统代理开关。
|
||
需要认证的应用代理、不在已支持路径中的配置及未运行的端口不会自动采用。
|
||
Windows 普通更新会补读远端用户和系统的代理环境变量。
|
||
检测结果只显示配置来源,不显示代理地址或凭据;配置仅传给本次更新进程。
|
||
没有检测到代理时沿用远端网络和 curl 自身配置,不自动借用本机代理。
|
||
“未检测到代理”只是网络方式说明;更新失败时,菜单会先显示末尾的具体错误,再列完整输出。
|
||
|
||
## 远端 Session 弹窗
|
||
|
||
弹窗由 tmux `display-popup` 和 Hub 内置选择器组成,不依赖 fzf。它会立即显示已打开的
|
||
window,同时在后台查询本机 Session 列表,并并行查询所有已登记远端;每项结果就绪后
|
||
原地更新。
|
||
|
||
主页面只显示 Session 和两个全局入口。大多数主机只有 `default` Session,因此默认只显示
|
||
主机名;有命名 Session 时显示为 `主机 / Session`。本机同样显示为“本机”或
|
||
“本机 / Session”。状态与主操作如下:
|
||
|
||
| 状态 | 选择后的行为 |
|
||
| --- | --- |
|
||
| `▶` 当前 / `●` 已打开 | 跳转到已有 window |
|
||
| `×` 已断线 | 自动重连并跳转 |
|
||
| `○` 远端运行 | 新建 attach window 并跳转 |
|
||
| `■` 远端已停止 | Enter/单击启动并打开 |
|
||
| `↻` Windows 旧窗口 | 原地切换为 SSH TTY 模式并重连 |
|
||
|
||
Enter 或单击一行始终执行它的主操作。管理操作统一放在上下文菜单中:键盘选中一行后按
|
||
`Space`,或在手机端点击行尾 `[⋯]`;右上角 `[操作]` 也会打开当前行的菜单。菜单会按
|
||
Session 当前状态提供修改显示名称、关闭 Hub Tab、关闭并停止 Session、永久删除已停止的
|
||
命名 Session、在此远端新建 Session、重试连接和移除远端记录等可用操作。Esc 逐层返回;
|
||
危险操作会二次确认并默认选中“取消”。关闭 Hub Tab 只结束该 Tab 中的 client,底层
|
||
Session 和工作现场保持运行;“关闭并停止”则会中断远端任务。若它是 Hub 中最后一个 Tab,
|
||
该 Tab 会保留为断线状态,避免销毁承载弹窗的最后一个 window。
|
||
|
||
主页面只有一个“新建 Session”入口,选择远端后再输入 Session 名;“添加远端”会先让你
|
||
选择“自动检测(Linux/macOS)”或“Windows/SSH”。修改显示名称支持最多 48 个字符,留空
|
||
保存可恢复默认名称,且不会修改底层 Session ID。移除远端记录只删除本机记忆,不关闭已有
|
||
Tab,也不停止远端 Herdr server。
|
||
|
||
搜索必须按 `/` 显式进入,因此普通字母不会误触命令;搜索页输入文字即可筛选,Esc 清空并
|
||
返回。键盘还支持上下键、Page Up/Down、Enter、`Ctrl+R` 刷新和 Esc 返回/关闭。窄屏会优先
|
||
显示主机和 Session 名,状态详情可在 `[⋯]` 菜单中查看。
|
||
|
||
永久删除只会出现在已停止的命名 Session 的菜单中,无论是否仍有关联 Hub Tab 都可执行。
|
||
确认后会在后台通过 SSH 执行 `herdr session delete`,永久删除工作现场和历史数据;关联 Tab
|
||
也会一并关闭。运行中的 Session 需先“关闭并停止”,Herdr 永久保留的 `default` Session
|
||
不能删除。
|
||
|
||
设计本工具时的 Herdr(0.8.2)不支持 Windows 作为原生 `herdr --remote` 的目标主机。Hub 查询到 Windows
|
||
Session 后会标记为“Windows · SSH 模式”,并自动改为 `ssh -tt target herdr`;命名
|
||
Session 会在远端运行 `herdr --session NAME`。这种模式仍支持 Tab 切换、detach、断线
|
||
重连和远端工作现场持久化,但使用远端 Herdr 的 keybindings,也没有原生 thin client
|
||
提供的本地图片剪贴板桥接。空 Windows 主机或平台检测失败时,可在“添加远端”中选择
|
||
“Windows / SSH”,也可手动执行 `herdr-hub open --remote TARGET --transport ssh`。
|
||
|
||
rootless 容器或 UID 映射环境可能把 `/etc/ssh/ssh_config` 显示为 `nobody` 所有,导致原生
|
||
`herdr --remote` 报 `Bad owner or permissions`,即使系统 `ssh` 本身仍可使用。不要放宽该
|
||
文件的写权限;可在本机 `~/.config/herdr/config.toml` 中让 Herdr 直接使用系统 SSH:
|
||
|
||
```toml
|
||
[remote]
|
||
manage_ssh_config = false
|
||
```
|
||
|
||
这会停用 Herdr 自动生成的 keepalive 和连接复用配置,但不会禁用用户自己的 SSH 配置。
|
||
执行 `herdr config check` 验证后重新打开 Session 即可。若 Session 进程启动后立即退出,
|
||
Sessions 弹窗会保留在该 Session 的操作页,显示 pane 返回的错误并允许直接重试。
|
||
|
||
也可通过 CLI 管理远端:
|
||
|
||
```bash
|
||
herdr-hub remote list
|
||
herdr-hub remote add orangepi
|
||
herdr-hub remote add ssh://me@server:2222 --remote-keybindings server
|
||
herdr-hub remote add windows-host --transport ssh
|
||
herdr-hub remote remove orangepi
|
||
```
|
||
|
||
注册表默认位于 `~/.config/herdr-hub/remotes.json`(遵循 `$XDG_CONFIG_HOME`),权限为
|
||
`0600`。它只保存 SSH target、remote keybinding 模式和首选 transport,不保存凭据。
|
||
|
||
## Session 显示名称
|
||
|
||
设计本工具时的 Herdr(0.8.2)没有底层 Session rename 命令,因此 Hub 的“重命名”是安全的显示名称:
|
||
顶部 Tab 和 Sessions 弹窗显示新名称,attach、重连和工作现场仍绑定原来的 Session ID。
|
||
名称会跨终端断线、Hub detach 和 `herdr-hub stop` 保留,并在重新打开 endpoint 时自动
|
||
应用。配置保存在 `~/.config/herdr-hub/aliases.json`(遵循 `$XDG_CONFIG_HOME`),
|
||
权限为 `0600`;留空保存会删除该 endpoint 的显示名称并恢复 `local/work`、
|
||
`host/work` 等默认格式。名称可以是任意不含控制字符的文本。若该文件损坏,Hub 会给出
|
||
警告并暂时使用默认名称,`herdr-hub doctor` 会报告具体错误。
|
||
|
||
## 复制与剪贴板
|
||
|
||
Hub 启用 tmux 的 OSC 52 剪贴板透传。Herdr 触发的自动复制,以及 tmux 接管后的
|
||
鼠标拖选,都会尝试写入当前 Hub 访问端的本地剪贴板。远程 session 中复制的
|
||
文本也回到访问端,不是远程机器的剪贴板。
|
||
|
||
访问端的终端需要支持并允许 OSC 52。如果终端或 Web terminal 禁止了这项能力,
|
||
可按住 `Shift` 再拖选,绕过 tmux 并使用终端原生复制。
|
||
|
||
### Termux / 手机端复制
|
||
|
||
Termux 的原生长按选区只认识整个终端画面,不知道 Herdr pane 和左侧 sidebar 的边界。
|
||
跨行拖选时,中间行因此可能混入 sidebar 文本。优先使用 Herdr 自带的 Copy Mode:按
|
||
`Ctrl+B [` 进入,用方向键或 `h/j/k/l` 移动,按 `v` 或空格开始选择,再按 `y` 或 Enter
|
||
复制。它只读取当前 pane,不会包含 sidebar;复制大段历史输出也可按 `Ctrl+B e` 在编辑器
|
||
中打开当前 pane 的 scrollback。这里的 `Ctrl+B` 是 Herdr 前缀,Hub 外层 tmux 前缀仍为
|
||
`Ctrl+A`。
|
||
|
||
如果更习惯 Termux 长按拖选,可在 `~/.config/herdr/config.toml` 已有的 `[ui]` 段中加入:
|
||
|
||
```toml
|
||
[ui]
|
||
pane_scrollbars = false
|
||
sidebar_collapsed_mode = "hidden"
|
||
# sidebar_start_collapsed = true # 可选:下次启动时默认收起
|
||
```
|
||
|
||
不要重复创建 `[ui]` 段。执行 `herdr config check` 和 `herdr server reload-config` 后,按
|
||
`Ctrl+B b` 可在完整 sidebar 和零宽度隐藏之间切换;隐藏后再使用 Termux 原生选区即可。
|
||
`pane_scrollbars = false` 还会移除 pane 右侧滚动条并腾出一列空间。
|
||
|
||
当访问端宽度小于 80 列时,Hub 会自动进入窄屏模式:
|
||
所有 Tab 都显示状态和最多 12 列的短名称,并优先显示主机:默认 Session 的本地与
|
||
远端分别显示 `local`、`host`,非默认 Session 才显示 `local/work`、`host/work`。
|
||
顶部右侧只保留 `C-a ? 帮助`;宽度小于 50 列时缩成 `C-a ?`。左上角标题也会缩成
|
||
`S`,继续给 Tab 留空间。点击 `Sessions`/`S`
|
||
可打开占 90% 屏幕的完整选择器。
|
||
|
||
`refresh` 是 add-only:它添加新发现的 endpoint,不自动删除已有 window,也不会改变
|
||
当前焦点。通过 `Ctrl+A q` 或弹窗关闭的 endpoint 会在当前 Hub 生命周期内记为已隐藏,
|
||
刷新和断开终端后重新进入都不会让它自动回来。要恢复它,打开 Sessions 弹窗并重新选择;
|
||
也可以执行对应的 `herdr-hub open` 命令。远端通过 SSH 目录重新选择,本地隐藏的运行中
|
||
Session 会列在“本机”下。Hub 至少保留一个 Tab;要全部退出请使用 `herdr-hub stop`。
|
||
|
||
当 endpoint 连接进程退出时,window 会保留:顶栏将它标记为 `× [断开]`,
|
||
当前 pane 底部会显示退出状态和 `Ctrl+A R` 重连提示。这与正常 detach Hub
|
||
不同;仅关闭外层终端后,直接再次执行 `herdr-hub` 即可。
|
||
|
||
`herdr-hub stop` 只结束 tmux 中的 client processes。本地及远端 Herdr servers 和
|
||
它们的 panes 会继续运行。
|
||
|
||
## CLI
|
||
|
||
```text
|
||
herdr-hub
|
||
herdr-hub start
|
||
herdr-hub refresh
|
||
herdr-hub open [--session NAME]
|
||
herdr-hub open --remote TARGET [--session NAME]
|
||
[--remote-keybindings local|server] [--transport native|ssh]
|
||
herdr-hub choose
|
||
herdr-hub control [--window ID]
|
||
herdr-hub keys
|
||
herdr-hub remote list
|
||
herdr-hub remote add TARGET [--remote-keybindings local|server]
|
||
[--transport native|ssh]
|
||
herdr-hub remote remove TARGET
|
||
herdr-hub reconnect [--window ID]
|
||
herdr-hub close [--window ID]
|
||
herdr-hub doctor
|
||
herdr-hub stop
|
||
```
|
||
|
||
## 自动发现与远端查询的边界
|
||
|
||
零配置的首次发现只覆盖:
|
||
|
||
- 当前用户正在运行的本地 Herdr servers;
|
||
- 当前用户、同一 PID namespace 中仍然存活的 `herdr --remote` processes。
|
||
|
||
发现或手动添加一次后,remote target 会被记住,不再要求本地 client 持续存活。弹窗先
|
||
通过非交互 SSH 执行跨平台的 `herdr session list --json`;Linux/macOS 的非交互 PATH
|
||
找不到 Herdr 时,再自动尝试 `$HOME/.local/bin/herdr`。Windows OpenSSH 返回的本地代码页
|
||
错误文本也会被容错解码。SSH key/passphrase 应已由 ssh-agent 处理;未知 host key、需要
|
||
密码、远端不可达或命令失败时,该主机显示“查询失败 · 单击重试”,不会关闭或卡住整个
|
||
弹窗。首次安装或 host-key 确认仍可在实际新建的 Herdr window 中交互完成。
|
||
|
||
首次使用且尚未登记时,以下情况仍无法自动找回 remote target:
|
||
|
||
- remote client 已经退出,但远端 server 仍在后台运行;
|
||
- client 位于另一个 container/PID namespace;
|
||
- `/proc` 使用了阻止读取同用户 argv 的安全配置;
|
||
- 可执行文件不叫 `herdr`。
|
||
|
||
这些场景可在弹窗中选择“添加远端”,或使用 `herdr-hub open --remote …`。为了避免嵌套 tmux 与前缀冲突,
|
||
`herdr-hub` 应从普通终端启动;若当前已经在另一个 tmux server 中,它会在扫描或创建
|
||
Hub 之前直接拒绝。
|
||
|
||
## 开发与测试
|
||
|
||
```bash
|
||
make test
|
||
```
|
||
|
||
测试使用伪造的 `/proc` 和 Herdr executable;tmux 集成测试使用唯一 socket 和
|
||
`/dev/null` 配置,不接触真实 Herdr sessions 或现有 tmux server。
|