herdr

herdr

熱門

控制 Herdr,这是一个专门给 coding agent 使用的终端机复用工具(terminal multiplexer)。仅在使用者明确提及 Herdr,或是要求使用 Herdr 来检查或控制 pane、tab、workspace、指令或另一个 agent 时才使用。切勿单纯因为任务可能需要背景终端机、任务委派或平行作业就自动使用。需在 HERDR_ENV=1 的环境下运作。

2.4萬星標
1655分支
更新於 2026/8/4
SKILL.md
唯讀
名稱
herdr
描述

控制 Herdr,这是一个专门给 coding agent 使用的终端机复用工具(terminal multiplexer)。仅在使用者明确提及 Herdr,或是要求使用 Herdr 来检查或控制 pane、tab、workspace、指令或另一个 agent 时才使用。切勿单纯因为任务可能需要背景终端机、任务委派或平行作业就自动使用。需在 HERDR_ENV=1 的环境下运作。

Herdr

Herdr 将终端机组织成 workspace、tab 和 pane,能识别在 pane 内执行的 coding agent,并通过 herdr CLI 暴露目前的 session。

在下达任何控制指令之前,请先确认此 agent 是在 Herdr 管理的 pane 中执行:

test "${HERDR_ENV:-}" = 1

如果检查失败,请说明你并非在 Herdr 内部执行并停止操作。切勿从 Herdr 外部检查或控制处于焦点状态的 Herdr session。

检查通过后,PATH 中的 herdr 执行档便能与目前的 session 通讯。使用它来检查相邻的工作、建立终端机版面配置(layout)、启动 agent 与指令、读取输出,以及等待状态变更。

了解目前的 CLI

已安装的执行档是指令语法的唯一标准依据。首先执行:

herdr --help

接着,透过不带子指令的方式执行指令群组,以印出相关的指令列表:

herdr agent
herdr pane
herdr workspace
herdr tab
herdr worktree
herdr terminal
herdr notification
herdr integration
herdr session

请勿只执行单独的 herdr 来探索指令,这会启动或附加到 TUI。切勿在缺少引数的情况下尝试带有变动特性的嵌套指令;像 herdr workspace create 这类指令在预设参数下即为合法且会直接执行。

大多数控制指令都会传回 JSON。请直接从这些回应中读取识别码(ID)与状态,而不是自行预测。

了解版面配置、Pane 与 Agent

选择符合任务需求的原语(primitive):

  • Workspace、tab 与 pane 的拓扑结构用于组织终端机的位置。
  • Pane 指令用于控制原生终端机、shell、测试、伺服器、输入与输出。
  • Agent 指令用于控制目前占据 pane 的已识别 coding agent。

无论 pane 是否包含 agent,pane 都是独立存在的。agent start 需要目前有可用的 shell pane,且绝对不会自行建立、分割或移动版面配置。一般程序请使用 pane 指令;只有当 Herdr 需要验证 agent 身份或解析 idleworkingblockeddoneunknown 等生命周期状态时,才使用 agent 指令。

Agent 指令接受活跃中(live)的唯一 agent 名称,或是目前托管该 agent 的 pane ID。它们不接受终端机 ID 或单独的 agent-kind 标示。名称必须符合 [a-z][a-z0-9_-]{0,31} 正规表示式,且在活跃的 agent 中必须是唯一的。名称会跟着目前占据 pane 的程序,当该 agent 退出、被释放或被替换时,名称即会被清空。

idle 表示 agent 已准备好接收输入,且其 tab 已在当前焦点的 Herdr UI 中被查看过。done 也是相同的底层 idle 状态,代表未被查看的背景工作已完成。聚焦到该 tab 或使用 focus 指令针对该 pane/agent 操作时,会将其标示为已查看。仅通过 CLI 读取并不会将其标示为已查看。blocked 表示 Herdr 侦测到了需要确认授权或提问的 UI。unknown 表示存在 agent,但 Herdr 无法确切归类其状态;这并不代表已完成。

使用 ID 与呼叫者上下文

公开 ID 是不可透明解析的稳定句柄(opaque stable handles):

  • workspace: w1
  • tab: w1:t1
  • pane: w1:p1

已关闭的 tab 与 pane ID 不会被重复使用。移动到另一个 workspace 的 pane 会获得一个新的包含 workspace 前缀的 pane ID。在执行 pane move 之后,请继续使用 .result.move_result.pane.pane_id 或活跃的 agent 名称操作。旧值会被回报为 .result.move_result.previous_pane_id;只有该被移动程序继承的呼叫者上下文(caller context)会继续解析旧 ID,因此切勿将旧 ID 当作一般的 agent 目标使用。

Herdr 会将呼叫者的上下文注入到每个受管理的 pane 中:

printf '%s\n' "$HERDR_WORKSPACE_ID" "$HERDR_TAB_ID" "$HERDR_PANE_ID"

当 pane 指令需要以呼叫者所在的 pane 为目标时,请优先使用 --current。忽略目标可能会使用 UI 当前焦点的 pane,而该 pane 可能属于使用者或另一个客户端。

通过以下指令探索活跃状态:

herdr workspace list
herdr tab list --workspace "$HERDR_WORKSPACE_ID"
herdr pane current --current
herdr pane list --workspace "$HERDR_WORKSPACE_ID"
herdr agent list

建立资源的回复中会暴露接下来要使用的 ID。workspace create 会回传 .result.workspace.result.tab.result.root_panetab create 会回传 .result.tab.result.root_panepane split 则会将新 pane 回传为 .result.pane

启动与协调 Agent

预设在目前 tab 与目前工作目录(cwd)中建立同级(sibling)pane。除非使用者明确要求特定的拓扑或位置,否则请勿建立 workspace、tab、worktree 或不同的 cwd。

请尊重使用者要求的方向。否则请检查呼叫者的 pane:

herdr pane layout --pane "$HERDR_PANE_ID"

如果是宽 pane 则向右分割(right),如果是窄或高的 pane 则向下分割(down)。避免连续向同一方向分割,以免产生过窄的栏或过矮的列。请将使用者的焦点保持在呼叫者的 pane 中,并明确保留呼叫者的工作目录:

herdr pane split --current --direction right --cwd "$PWD" --no-focus

必要时请将 right 替换为 down。从 .result.pane.pane_id 读取新的 pane ID。

可用的 shell pane 必须处于互动式提示字元(interactive prompt)状态,也就是 shell 本身在前台运作,且没有执行中的前台指令、编辑器或 agent。在此类 pane 中使用有意义且唯一的名称启动支援的 agent:

herdr agent start reviewer --kind codex --pane <returned-pane-id>

使用使用者要求的 kind。执行 herdr agent 可检查已安装的 kind 列表与选项。原生 agent 引数必须放在 -- 之后:

herdr agent start reviewer --kind codex --pane <returned-pane-id> -- <agent-args...>

agent start 只会在 Herdr 于同一个 pane 中侦测到预期的 agent 并确认其已准备好接收互动输入后才回传。预设的启动逾时时间为 30 秒。

透过 agent 界面派送工作:

herdr agent prompt reviewer "Review the current diff and report only actionable findings." --wait --timeout 120000

agent prompt 会原子化地送出文字与编码后的 Enter,同时遵循该 pane 的实时括号粘贴模式(bracketed-paste mode)。对于一般的 agent 工作,使用 --wait 就足够了:它会等待直到进入第一个稳定状态(idledoneblocked)。请勿使用 --until 重复设定这些预设行为。

从非工作状态(non-working state)送出的 prompt 必须在 5 秒内产生观察得到的生命周期变化。否则 Herdr 会回传 agent_prompt_stalled 而非无限期等待。此等待追踪的是生命周期状态,而非单次轮次;如果 agent 已经在工作中,完成当下的执行轮次即可能满足条件。

仅在特定状态的工作流程中才使用 --until,例如等待已在执行中的 agent 请求输入:

herdr agent wait reviewer --until blocked --timeout 120000

若未指定 --until,独立执行的 agent wait 会使用与 agent prompt --wait 相同的稳定状态预设行为。

使用逻辑按键来进行互动式 agent UI 控制:

herdr agent send-keys reviewer esc
herdr agent send-keys reviewer ctrl+c

Herdr 在写入任何字节前都会验证所有按键。透过已解析的 agent 读取结果:

herdr agent get reviewer
herdr agent read reviewer --source recent-unwrapped --lines 120

如果等待失败或回传 blocked,在决定要传送什么输入之前,请先检查 agent getagent read。只有在刻意需要原生终端机控制时,才使用 pane 界面。

在另一个 Pane 中执行一般指令

使用相同的几何规则建立同级 pane,保留呼叫者的工作目录,并维持使用者的焦点不变:

herdr pane split --current --direction right --cwd "$PWD" --no-focus

.result.pane.pane_id 读取新的 pane ID,然后执行并检查指令:

herdr pane run <returned-pane-id> "just test"
herdr pane wait-output <returned-pane-id> --match "test result" --timeout 120000
herdr pane read <returned-pane-id> --source recent-unwrapped --lines 120

pane run 会原子化地送出指令文字与 Enter。pane wait-output 会立即搜寻所选的快照,因此已存在的输出也能成功匹配。文字精确匹配请使用 --match <text>,Rust 正规表示式匹配请使用 --regex <pattern>。若省略 --timeout 则允许无限期等待。

选择符合任务需求的读取来源(read source):

  • visible: 目前渲染的视埠(viewport)。
  • recent: 最近渲染的输出,包含软换行(soft wrap)。
  • recent-unwrapped: 最近输出并将软换行合并;建议用于日志(log)与逐字稿(transcript)。
  • detection: 用于 agent 侦测的纯文字底部缓冲区快照。

当颜色与终端机样式是凭据时,请使用 --format ansi。否则请使用純文字。

--lines 会向 Herdr 索取该 pane 可用的画面与主机卷回(host scrollback)缓冲区中的更多行数。如果增加行数仍无法显现更多已完成的回复内容,可能代表该 pane 正处于终端机的备用画面(alternate screen)中执行 agent。离开备用画面的行不会进入 Herdr 的主机卷回缓冲区,因此增加行数也无法救回。

在此类读取失败后,请要求 agent 将完整回复写成 Markdown 档案并存入暂存目录,且仅回传档案路径,接着直接读取该档案。请仅将此方法作为备用方案;切勿在初始 prompt 中就要求输出档案。

安全与协调规则

  • 除非使用者要求切换上下文,否则背景工作请一律使用 --no-focus
  • 请使用 --current、明确的 pane ID 或唯一的 agent 名称。切勿依赖其他客户端焦点的 pane。
  • 请从 JSON 回应中解析 ID。切勿从侧边栏顺序或范例中推导 ID。
  • 切勿关闭非你自己建立的 workspace、tab、pane 或 session,除非使用者明确要求。
  • 切勿在活跃的 session 中执行 herdr server stop,除非使用者明确打算停止伺服器与其 pane 进程。
  • 绝不要杀掉 Herdr 的主进程。需要独立伺服器的实验请使用具名的测试 session。
  • CLI 伺服器错误会在 stderr 输出 JSON,离开状态码为 1。CLI 语法错误离开状态码为 2。