Herdr throwaway reproduction 是一个 Herdr 技能,用途是在一个已有的 Herdr 会话内部,创建并控制一个一次性的、带唯一名称的 Herdr 会话。当复现工作需要真实的 Herdr 服务器、pane、PTY、智能体或 socket API,而又不希望危及用户主会话时,可以使用这个一次性命名会话。
【用途与总体思路】 临时 TUI 只负责保持该一次性会话处于连接状态并提供终端几何尺寸;复现本身应从父会话通过 Herdr 的 CLI/API 来驱动。除非缺陷明确需要客户端输入,否则不要手动操作嵌套的 TUI。
【不可妥协的安全要求】 不得在默认会话中运行复现。不得停止、重启、删除或杀死主 Herdr 服务器。清理时不得使用 pkill、宽泛的进程匹配或猜测的 PID。应创建唯一的会话名,不得复用或删除无关的命名会话。应新建一个外层 pane,清理时只关闭该 pane。工作区、标签、pane、终端和智能体 ID 都应从命令输出中读取,绝不自行构造。复现目录和可能较大的产物应放在 /var/tmp。不得批准破坏性或不必要的智能体操作。未经用户批准,不得消耗付费智能体 token;应使用被要求的低成本模型和尽可能小的提示。
【先了解已安装的接口】 已安装的二进制是权威依据,CLI 语法可能自本技能编写以来已经变化。首先要确认调用方位于 Herdr 内部,并在做任何事之前查看相关帮助:
test "${HERDR_ENV:-}" = 1 herdr --version herdr --help herdr session herdr pane herdr agent
在使用不熟悉或可能产生变更的命令之前,先查看嵌套命令的帮助。不要直接运行裸 herdr 来探索,因为它会启动或连接 TUI。应记录本次复现测试的是哪个 Herdr 二进制和版本。如果要测试某个检出构建,应遵循该仓库关于运行该构建的说明,而不是悄悄替换为已安装的二进制。
【创建外层 pane】 在当前标签中创建一个兄弟 shell pane,且不移动焦点。如果测试框架提供了可用的 Herdr 布局工具,就用它;否则在查看帮助后使用已安装的 pane 拆分命令。将 /var/tmp 或专用复现目录作为新 pane 的工作目录。保存返回的外层 pane ID,这是父会话中清理时唯一允许关闭的 pane。
【启动一次性会话】 选择一个简短的唯一名称,例如 repro-<topic>-<timestamp>。启动前,必须在一次性客户端实际加载的配置中显式允许嵌套。HERDR_ENV=1 会从外层 pane 继承,因此除非启用 [experimental].allow_nested,否则启动会被拒绝。即使全局配置中启用了嵌套,隔离的 XDG_CONFIG_HOME 也不会继承该设置。应使用文件写入工具在复现目录下创建仅用于测试的配置。对于默认配置复现,其内容可以是:
[experimental] allow_nested = true
如果要用用户配置复现,则将该配置复制到测试目录,并在其已有的 [experimental] 表中启用 allow_nested(若不存在该表则添加)。不要创建重复的表或键。绝不要为了允许复现而编辑用户的全局配置,也不要通过取消设置 HERDR_ENV 来绕过嵌套检查。
在下方启动时将绝对测试配置路径作为 HERDR_CONFIG_PATH 传入。配置校验以及任何必须加载该测试配置的命令都应使用同一覆盖。该覆盖只选择配置文件,并不隔离已保存的机器目录或其他全局状态。当复现会改动已保存的机器时,还应使用仅用于测试的 XDG_CONFIG_HOME 和 XDG_STATE_HOME,并在所有针对该测试环境的命令上保留这些覆盖。
在新的外层 pane 内运行命名会话。清除继承的会话选择、socket 覆盖和调用方 ID,使嵌套运行时不会意外寻址到父会话:
env
-u HERDR_SOCKET_PATH
-u HERDR_CLIENT_SOCKET_PATH
-u HERDR_SESSION
-u HERDR_WORKSPACE_ID
-u HERDR_TAB_ID
-u HERDR_PANE_ID
HERDR_CONFIG_PATH=<absolute-test-config-path>
herdr --session <session-name>
需要时向该启动命令添加复现专用的环境变量。配置服务器的环境变量必须在命名服务器启动之前就存在。启动前用 herdr config check 和同一配置覆盖校验测试配置。启动后读取外层 pane,以捕获诸如 nested herdr is disabled by default 之类的启动错误;不要仅因为 pane run 返回成功就认为启动成功。在命名会话的 API 就绪之前不要继续。通过从父会话寻址该会话并列出其 pane 来确认就绪。
【只寻址一次性会话】 从父会话发出的每条控制命令都必须清除继承的 socket 覆盖,并显式选择临时会话:
env
-u HERDR_SOCKET_PATH
-u HERDR_CLIENT_SOCKET_PATH
-u HERDR_WORKSPACE_ID
-u HERDR_TAB_ID
-u HERDR_PANE_ID
HERDR_SESSION=<session-name>
herdr pane list
每条命令都重复该前缀。不要依赖 shell 状态在各次工具调用之间保持。从 pane list 读取该一次性根 pane 的 ID,在在其中启动任何东西之前确认其 cwd 和前台进程。命名会话隔离运行时状态、socket、pane 和持久化,但默认仍共享全局 Herdr 配置和智能体清单覆盖。当配置来源可能影响复现时应检查来源,不要仅为让测试通过而修改共享配置。
【通过 API 驱动复现】 对 shell 和普通进程使用 pane 命令:pane run 在可用的 shell 提示符处启动命令;pane wait-output 等待确定性输出;pane read 捕获终端内容;pane send-text 发送字面输入;pane send-keys 发送受支持的键;pane get、pane process-info 和 pane layout 用于运行时状态。仅在 Herdr 识别到编码智能体后才使用 agent 命令:agent start 在已有 shell pane 中启动受支持的智能体;agent prompt 原子地提交一个提示;agent wait 等待 working、blocked、idle、done 或 unknown;agent read 捕获智能体终端;agent get 和 agent explain 检查状态与识别;agent send-keys 用于交互式响应。使用前先运行相关命令组的帮助,因为名称和选项可能变化。优先使用等待而非任意 sleep。当计时本身是被测对象时,记录时间戳并使用有界轮询。在复现的转换之前、之中和之后捕获状态。当高层命令不支持所需的终端按键时,只有在确认目标应用预期的按键后,才通过一次性 pane 发送其终端序列。绝不要向父 pane 发送原始控制序列。
【谨慎启动智能体】 启动智能体前,检查其已安装的 --version 和 --help。在 Herdr 的参数分隔符之后传入智能体的原生参数。使用用户要求或批准的精确模型。应从实时智能体屏幕验证模型,而不是相信别名。当智能体支持时,基线优先使用低 effort、安全模式和手动权限。只有当可疑行为依赖 hooks、插件或设置时,才用用户真实配置重复。权限状态测试使用无害操作。在捕获证据后拒绝待处理操作,并验证未创建任何产物。
【收集有用证据】 记录足够信息,让他人能够复现结果:Herdr 二进制与版本;命名会话与启动环境;目标应用或智能体版本与参数;确切的命令或提示;每次转换前后的 pane 与智能体状态;相关的 pane read、agent read、agent explain、API 输出和会话日志;当时生效的是全局配置还是本地清单覆盖。应从 herdr session list 读取命名会话目录和 socket,而不是假设其路径。除非用户要求保存在别处,否则将大型证据放在 /var/tmp 下。区分观察到的事实与推测的原因。先复现原生(stock)行为,再逐个变量修改。
【清理】 清理是复现的一部分,失败后也要执行。在可行时拒绝待处理提示并干净地停止测试应用。验证无害探测文件或其他测试产物不存在,或只删除本次复现创建的产物。使用已安装的 session 命令停止临时命名会话,删除同一个已停止的会话,确认它不再显示为运行中,等待外层 pane 返回其 shell,只关闭本工作流创建的外层 pane。绝不要因为某个命名会话看起来陈旧就删除它。绝不要关闭运行当前智能体的 pane,或任何非为复现创建的 pane。
【报告结果】 说明什么被复现、什么没有被复现,以及失败的确切转换。包含清理状态。提及可能影响结果的共享配置或清单覆盖。