Herdr 是做什么的?
Herdr 将终端组织为工作区、标签页和窗格,识别运行在窗格内的编码智能体,并通过 herdr CLI 暴露当前会话。
在发出任何控制命令之前,先验证本智能体是否运行在 Herdr 管理的窗格内:
test "${HERDR_ENV:-}" = 1
如果检查失败,说明你没有运行在 Herdr 内部,请停止操作。不要从 Herdr 外部检查或控制焦点所在的 Herdr 会话。
当检查通过后,PATH 中的 herdr 二进制文件即可与当前会话通信。使用它可以检查相邻工作、创建终端布局、启动智能体和命令、读取输出以及等待状态变化。
了解当前 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。从这些响应中读取标识符和状态,而不是猜测它们。
理解布局、窗格和智能体
选择与任务相匹配的基本构造:
- 工作区、标签页和窗格拓扑结构用于组织终端位置。
- 窗格命令用于控制原始终端、shell、测试、服务器、输入和输出。
- 智能体命令用于控制当前占据窗格的已识别编码智能体。
无论窗格内是否有智能体,窗格都是存在的。agent start 需要一个现有的可用 shell 窗格,并且永远不会创建、拆分或移动布局。对于普通进程,请使用窗格命令。当 Herdr 需要验证智能体身份或解释 idle、working、blocked、done 和 unknown 生命周期状态时,请使用智能体命令。
智能体命令接受唯一的活跃智能体名称或当前托管该智能体的窗格 ID。它们不接受终端 ID 或裸的智能体种类标签。名称必须匹配 [a-z][a-z0-9_-]{0,31},并且在所有活跃智能体中保持唯一。名称跟随当前窗格的占用者,当该智能体退出、被释放或替换时会被清除。
idle 表示智能体已准备好接收输入,并且其标签页已在焦点 Herdr UI 中被看到。done 是在后台未见工作完成后相同的底层空闲状态。聚焦标签页或使用 focus 命令定位窗格或智能体会将其标记为已见。CLI 读取不会将其标记为已见。blocked 表示 Herdr 识别到一个批准或问题 UI。unknown 表示存在一个智能体,但 Herdr 无法自信地分类;它不能证明完成状态。
使用 ID 和调用者上下文
公开 ID 是不透明的稳定句柄:
- workspace:
w1 - tab:
w1:t1 - pane:
w1:p1
已关闭的标签页和窗格 ID 不会被复用。移动到另一个工作区的窗格会收到一个新的工作区限定窗格 ID。在 pane move 之后,继续使用 .result.move_result.pane.pane_id 或活跃智能体名称。旧值被报告为 .result.move_result.previous_pane_id;只有被移动进程继承的调用者上下文会继续解析该旧 ID,因此不要将其用作通用的智能体目标。
Herdr 将调用者的上下文注入每个受管窗格:
printf '%s\n' "$HERDR_WORKSPACE_ID" "$HERDR_TAB_ID" "$HERDR_PANE_ID"
当窗格命令应定位到调用窗格时,优先使用 --current。省略目标可能会使用 UI 焦点的窗格,该窗格可能属于用户或其他客户端。
通过以下命令发现活跃状态:
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_pane。tab create 返回 .result.tab 和 .result.root_pane。pane split 返回新窗格为 .result.pane。
启动并协调一个智能体
默认使用当前标签页中的一个兄弟窗格以及当前工作目录。除非用户明确要求拓扑结构或位置,否则不要创建工作区、标签页、工作树或不同的当前工作目录。
尊重用户要求的方向。否则检查调用窗格:
herdr pane layout --pane "$HERDR_PANE_ID"
将一个宽窗格向右拆分,将一个窄或高窗格向下拆分。避免重复的同方向拆分,这会产生不可用的窄列或短行。保持用户的焦点在调用窗格中,并显式保留调用者的工作目录:
herdr pane split --current --direction right --cwd "$PWD" --no-focus
在适当时将 right 替换为 down。从 .result.pane.pane_id 读取新窗格 ID。
一个可用的 shell 窗格必须处于交互式提示符下,shell 本身在前台,并且没有前台命令、编辑器或智能体在运行。在该窗格中使用一个有用且唯一的名称启动受支持的智能体:
herdr agent start reviewer --kind codex --pane <returned-pane-id>
使用用户请求的种类。运行 herdr agent 检查已安装的种类列表和选项。仅在本机智能体参数前使用 --:
herdr agent start reviewer --kind codex --pane <returned-pane-id> -- <agent-args...>
agent start 仅在 Herdr 检测到预期的智能体位于同一窗格并认为其已准备好接收交互输入后返回。默认启动超时时间为 30 秒。
通过智能体界面提交工作:
herdr agent prompt reviewer "Review the current diff and report only actionable findings." --wait --timeout 120000
agent prompt 以原子方式提交文本和编码后的回车键,同时尊重窗格的活跃括起来的粘贴模式。对于常规的智能体工作,--wait 就足够了:它等待第一个稳定的 idle、done 或 blocked 状态。不要用 --until 重复这些默认值。
从非工作状态发送的提示必须在五秒内产生可观察到的生命周期变化。否则 Herdr 返回 agent_prompt_stalled 而不是无限期等待。此等待跟踪生命周期状态,而不是单个轮次;如果智能体已经在工作,当前活动轮次的完成可能满足该条件。
仅对状态特定的工作流程使用 --until,例如等待一个已经在运行的智能体请求输入:
herdr agent wait reviewer --until blocked --timeout 120000
不带 --until 的独立 agent wait 使用与 agent prompt --wait 相同的稳定状态默认值。
对交互式智能体 UI 控件使用逻辑键:
herdr agent send-keys reviewer esc
herdr agent send-keys reviewer ctrl+c
Herdr 在写入任何字节之前验证所有键。通过解析后的智能体读取结果:
herdr agent get reviewer
herdr agent read reviewer --source recent-unwrapped --lines 120
如果等待失败或返回 blocked,在决定发送什么输入之前先检查 agent get 和 agent read。仅在有意进行原始终端控制时使用窗格界面。
在另一个窗格中运行普通命令
使用相同的几何规则创建兄弟窗格,保留调用者的工作目录,并保持用户焦点不变:
herdr pane split --current --direction right --cwd "$PWD" --no-focus
从 .result.pane.pane_id 读取新窗格 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 以原子方式发送命令文本和回车键。pane wait-output 立即搜索所选快照,因此已经存在的输出也可以匹配。使用 --match <text> 进行字面子串匹配,或使用 --regex <pattern> 进行 Rust 正则表达式匹配。省略 --timeout 允许无限期等待。
使用与任务匹配的读取源:
visible:当前渲染的视口。recent:近期的渲染输出,包括软换行。recent-unwrapped:近期的输出,软换行已被合并;日志和转录优先使用它。detection:用于智能体检测的纯文本底部缓冲区快照。
当颜色和终端样式是证据时使用 --format ansi。否则使用文本。
--lines 要求 Herdr 从窗格的可用屏幕和主机回滚中获取更多行。如果增加行数没有显示已完成的响应的更多内容,那可能是因为窗格正在终端的备选屏幕上运行智能体。离开备选屏幕的行不会进入 Herdr 的主机回滚,因此更大的行数无法恢复它们。
在读取失败后,要求智能体将其完整响应以 Markdown 格式写入临时目录,并仅回复文件路径,然后直接读取该文件。这仅用作后备方案;不要在初始提示中请求文件输出。
安全与协调规则
- 对于后台工作使用
--no-focus,除非用户要求切换上下文。 - 使用
--current、显式的窗格 ID 或唯一的智能体名称。不要依赖另一个客户端的焦点窗格。 - 从 JSON 响应中解析 ID。不要从侧边栏顺序或示例中推导。
- 除非用户明确要求,否则不要关闭不是你创建的工作区、标签页、窗格或会话。
- 除非用户明确意图停止服务器及其窗格进程,否则永远不要在活跃会话中运行
herdr server stop。 - 永远不要杀死主 Herdr 进程。使用命名测试会话进行需要隔离服务器的实验。
- CLI 服务器错误以状态码 1 和 stderr 上的 JSON 形式返回。CLI 语法错误以状态码 2 退出。
本地惯用法
上述 HERDR_ENV=1 门控适用于从窗格内部控制当前会话。主机级别的工作——编辑配置、安装插件、调试智能体检测、围绕 socket/CLI 构建自动化——从任何终端执行都是合法的。对于这些任务,请阅读 references/local-idioms.md:通知投递设置、智能体检测维护、来自 Claude Code 钩子的侧边栏元数据、事件订阅模式、工作树流程以及插件编写指南。