mcpField
H
herdr-agents

herdr-agents

github.com/djalmajrAgent 工作流443 次安装5 周前更新
代码仓库

关于 herdr-agents

herdr-agents 是用于 Herdr 的多 Agent 编排技能,供在 Herdr 面板中运行的 Agent 拆解任务、分派角色并整合工作。它通过 CLI Agent、角色文件和报告文件管理实施与审查流程。

主要功能

  1. 01按角色分派 CLI Agent
  2. 02将任务简报分发给工作者
  3. 03等待并检查报告状态
  4. 04要求跨模型家族审查
  5. 05整合、验证并提交成果

适用场景

  1. 01并行实现一个项目的不同部分
  2. 02让独立角色研究外部 API
  3. 03在推送前审查代码变更
  4. 04协调实施、文档与安全审查

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/djalmajr/skills --skill herdr-agents

安装后在 Claude Code 中输入/herdr-agents确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

config.defaults
README.md
agents/
openai.yaml
references/
agent-profiles.md
kinds.md
orchestration-contract.md
troubleshooting.md
roles/
designer.md
documenter.md
implementer.md
inspector.md
planner.md
researcher.md
reviewer.md
scouter.md
security-reviewer.md
sub-orchestrator.md
tasker.md
ui-reviewer.md
scripts/
herdr-agents
herdr-agents.cmd
herdr-agents.mjs
scripts/lib/
arrival.mjs
scripts/lib/commands/
clean.mjs
collect.mjs
doctor.mjs
env.mjs
explain.mjs
feedback.mjs
friction.mjs

详细介绍

/herdr-agents

将调用方 Agent 转变为编排器,并为其配备一组角色 Agent,让它们作为真正的 CLI Agent 在 Herdr 窗格中运行。编排器无需在任何地方配置:从 Herdr 窗格(HERDR_ENV=1)运行此技能的 Agent 就是编排器。其他每个角色都是 roles/ 下的一个文件,其 kind 指定由哪种 CLI Agent 扮演。角色是带有 frontmatter 的 Markdown 文件(类似 omp 的 .omp/agents/*.md);herdr CLI 负责传输。编排器负责拆解任务、撰写简报、等待、整合、验证和提交。工作 Agent 各自实现、研究或审查一个部分,并将结果写入文件。

不可妥协的要求(每一项都是实际发生过的错误)

  1. 报告文件就是完成信号。 使用 dispatch(等待)、wait 或 status。绝不要手动编写循环来调用 herdr agent get。
  2. 工作 Agent 的报告缺失时,绝不要对其执行 release --close。 脚本会拒绝此操作;--force 仅用于放弃某个工作 Agent。
  3. 每份简报都必须包含 Goal、Expected result(或 Acceptance criteria)、Forbidden、Report 和一条不提交的说明;角色可以编辑时还须包含 Owned files。 dispatch 会对简报进行检查(brief_lint=warn|strict;只读角色无需 Owned files 部分),并告知每个工作 Agent:没有人会监看其终端(不得提问互动式问题),也绝不能杜撰名称、端点、标志、凭据、URL 或需求。简报中提到的凭据、URL 和种子数据必须先行验证(使用 git grep 和种子脚本),不得猜测。
  4. 推送前,审查者必须与实现者来自不同的模型系列。标记为 partial 的审查项不算通过。 审查者无法验证该项(通常是因为没有网络,或无法访问相关来源)。应向审查者提供其缺少的信息,或自行验证该项,然后再提交、推送或发布;wait 和 dispatch 会标记含有 partial 项的报告。
  5. 状态绝不能放在 .agents/ 或 .codex/ 下(Codex 沙盒会拒绝访问)。
  6. 嵌套编排器不得使用沙盒中的 Codex:其沙盒会阻止访问 Herdr 套接字。请使用 claude(或关闭沙盒的 Codex)。
  7. 每次运行结束时都要读取 $S friction,并记录此技能导致的问题(参见“改进此技能”)。

前置条件

test "${HERDR_ENV:-}" = 1 && command -v herdr >/dev/null && { command -v node >/dev/null && [ "$(node -p 'process.versions.node' | cut -d. -f1)" -ge 20 ] || command -v bun >/dev/null; } && $S init

如果检查失败,请说明你不在 Herdr 环境中(或缺少 Node.js 20+ / Bun),然后停止。绝不要在 Herdr 环境之外控制 Herdr 会话。herdr 技能(herdr --skill)是 CLI 语法的权威来源;此技能在其基础上添加角色层,绝不取而代之。

首次运行

当项目文件尚未选择团队(没有 multi_role、role.<role>.kind 或 lane.<name>.kind),且状态根目录中没有成员名册记录时,$S init 和 $S doctor 会显示 first_run: true。init 也会在其 JSON 中设置 first_run。只有表头的成员名册文件仍属于首次运行。first_run: false 表示此项目已选择团队,或已有 Agent 正在运行。

当 first_run 为 true 时,在启动任何 Agent 之前,先告诉用户即将发生什么,并等待用户同意。使用用户的语言。可参照以下内容调整;不要在同一轮中打开面板。

葡萄牙语:

Vou abrir até 3 painéis ao lado deste (4 no total, contando este). Dois escrevem o código em paralelo (e pesquisam quando preciso) e um revisa. (Com 3 painéis no total, um escreve e um revisa; com 2, um escreve e eu reviso.) Eles não fazem commit nem push; isso fica comigo. Você pode acompanhar qualquer painel ou fechar o que não quiser. Cada assistente gasta a cota da própria conta. Posso abrir?

英语:

我将在当前面板旁打开最多 3 个面板(包括当前面板在内共 4 个)。 两个面板并行编写代码(并在需要时进行研究),另一个面板负责审查。 (总共 3 个面板时,一个负责编写,一个负责审查;总共 2 个面板时,一个负责编写,由我负责审查。) 它们不会执行 commit 或 push;这些由我来做。 你可以查看任何面板,也可以关闭不需要的面板。 每个助手都会消耗各自账户的配额。 我可以打开吗?

用户拒绝后,停止组建团队。用户同意后,如果项目仍未选择助手,则按照设置:引导配置中的步骤操作,写入选择,然后启动 Agent。若 first_run 为 false,则跳过这段说明。

描述工作进展

每个可见操作都用一行说明,使用用户的语言:不要输出 JSON 或退出代码,也不要使用 lane、kind 或 panes 这几个词。

  • Abri o painel de implementação para escrever esta fatia.
  • O painel de revisão está ocupado; espero ele terminar.
  • A revisão da fatia 2 achou 3 problemas.
  • 已打开实现面板来编写这一部分。
  • 审查面板正忙;正在等待它完成。
  • 第 2 部分的审查发现了 3 个问题。

结束时说明谁做了什么:哪个面板进行了研究、编写和审查,以及你整合了什么。

正在发生什么

当用户询问正在发生什么(“o que está acontecendo?”、“what's going on?”)时,运行 $S explain,并根据其文本用用户的语言作答。这是纯文本,而非 JSON:说明面板数量、每个面板正在做什么(工作中、空闲、等待报告或配额不足)、当前任务和助手,以及当前选择建议的内容。若没有任务正在运行,则说明团队情况以及如何启动。

名称:名单中的成员

先运行 $S init。它会运行 doctor(提供诊断信息:是否在 Herdr 内部、Herdr 客户端与服务端版本、是否存在与 herdr --skill 完全一致的官方 herdr 技能、PATH 中是否有 kinds、状态目录是否可写、配置是否合理),然后将调用方自己的 Agent 重命名为 orchestrator(配置项 orchestrator_name;若该名称已被占用,则使用 orchestrator-2),让 Herdr 侧边栏和 roster 显示由谁负责统筹,并打印上下文(窗格、标签页、工作区、布局、状态目录)。启动 Agent 前先处理 warn 行;如果官方技能已过时,你读到的 CLI 语法可能有误。spawn 会在需要时才执行重命名。如果 first_run 为 true,请在启动任何 Agent 前遵循首次运行。

启用泳道时(默认设置),工作 Agent 会以其泳道命名(build;如果该泳道已有一个工作 Agent,第二个则命名为 build-2;还有 review,以及 flex 模式下负责文档的 docs)。Herdr 中的 Agent 名称全局唯一:如果另一个工作区已使用某个名称,就会使用下一个可用的后缀;如果 --name 指定的名称已被占用,也会采用相同方式处理,并发出警告。传入 --name 可指定更有描述性的名称。lanes=off 会沿用旧名称:按角色命名(scouter、implementer……),然后是 implementer-2。嵌套的 orchestrator 使用 sub-orchestrator 角色,且不属于任何泳道,除非某个 lane.*.roles 列表包含该角色。

orchestrator 的窗格也会设置标题:如果窗格尚无标题,init 会将其设为 orchestrator: <project>;$S title "<objective>" 会将其设为 orchestrator: <objective>(objective 最多保留 60 个代码点)。请在 init 后立即设置标题,并在 objective 发生变化时再次设置,这样侧边栏就会显示本次会话负责的任务。

名称表示角色;窗格标题表示任务。每次 dispatch 都会将工作 Agent 的窗格标题设为 <role>: <task>。如果简报以 H1 标题(# Brief — <task>)开头,task 就是简报的首行;否则,task 就是简报的文件名。报告生成后,标题末尾会加上 ✓;不带 --close 的 release 会清除标题。因此,即使同一个工作 Agent 被复用于多个任务,用户也始终能看到每个工作 Agent 正在做什么。

角色

角色默认类型工作量模式用途
scoutergrokhigh只读梳理代码、查找路径,并整理精简发现供交接
researchergrokhigh只读提供经来源验证的外部库/API 答案
planner———协调者。spawn planner 会以状态码 12 退出,且不会打开窗格
designeragyhigh编辑在项目设计系统(令牌、状态、无障碍)下进行 UI 工作
implementergrokxhigh编辑为一个切片编写生产代码,并逐项提交报告
taskergroklow编辑按照精确约定批量执行机械式编辑
reviewercodexhigh只读推送前基于补丁发现正确性问题
security-reviewerclaudehigh只读提供有证据支持的漏洞发现
inspectoragyhigh只读在两种主题下截取屏幕截图、发现 UX 问题,不修复问题
ui-revieweragyhigh只读根据设计约定对仅涉及 UI 的变更进行轻量审查
documentercodexhigh编辑(仅文档)审查后记录已落地的内容;绝不编写代码
sub-orchestratorclaudemedium只读从另一个窗格运行此技能;绝不使用 codex 沙盒(套接字受阻)

不同工作该使用哪个助手。 Default kind 列表示全新安装在未配置任何内容时使用的类型,不是策略。团队由每个用户或每个项目自行选择,并写入配置(引导式设置会询问此项,并且只提供探测结果为可用的助手):选择哪个助手和模型构建版本、由谁审查,以及工作量级别。唯一不变的规则是:切片的审查者必须来自与其实现者不同的模型系列(运行 grok 模型的 cursor 属于 xai 系列,与 grok 相同)。对于工作者,系列检查会强制执行此规则;对于由协调者自己编写的代码,需手动选择审查者所属系列。**选择或更改团队之前,请阅读 references/agent-profiles.md:**了解每个助手在实际使用中承担不同角色时的优缺点,以及各角色的推荐选择。示例:

  • 包含 e2e 的 UI 工作应交给能够打开端口的类型,而不是沙盒化的 codex;
  • 处理不可信输入的切片需要比小型模型更强的模型,或者需要一份列出待测试恶意变体的简报;
  • codex 审查者以 high 工作量在 2 到 3 分钟内发现了真实的 P1 问题,而 xhigh 的成本是切片的 2 到 4 倍。

定义位于 roles/。解析顺序:项目 .agents/herdr-roles/<role>.md → 此技能的 roles/<role>.md。生成时的 --kind 会覆盖 frontmatter 默认值。类型映射到模型系列(见 references/kinds.md;对于 cursor,系列取决于解析后的模型 ID — grok-4.7-xhigh 属于 xai);同一切片的审查者必须来自与实现者不同的系列。除非传入 --allow-same-family,否则脚本会拒绝分派给与当前编辑 Agent 同系列的审查者。它无法查看协调者自己编写的代码:遇到这种情况时,需手动选择来自另一系列的审查者类型。角色说明还包含协调者不会在每份简报中重复的工作者规则:只要其他工作者可能共用同一工作树,implementer 就会在仓库外的项目临时副本中运行变更检查(只有在独自工作时才会在原位检查;且仅在文件的 sha256 仍然匹配时才恢复 — 文件已更改表示这是他人的编辑:不予恢复,并进行报告);implementer、tasker 和 designer 会在编写报告前停止自己启动的所有进程,依据保留的 PID 进行检查,且只按 PID 检查(绝不列出所有命令行,因为其中可能包含凭据;沙盒化的 codex 会阻止 ps);designer 会报告 UI 的验证方式(ui_verification)。reviewer 绝不编辑仓库,并且只会在临时副本中进行变更。

工作量、模型、审批

角色 frontmatter、配置和 spawn 标志共用三个参数。优先级从高到低依次为:标志 → lane.<name>.*(同一 lane 中的每个角色共用一种 kind 和一个模型,因为它们属于同一个会话)→ 配置 role.<role>.<knob> → 配置 effort.<kind>(仅 effort)→ 角色 frontmatter → 配置 model.<kind>.<position> → 配置 model.<kind> → CLI 自身的默认值。每一层的 kind 和模型会一起生效:如果某一层以下的 lane 或角色模型低于设置有效 kind 的层级,就会被丢弃(优先级链会继续检查下一个来源);如果设置了不带 --model 的 --kind,所有已配置的 lane/角色模型都会被丢弃——假定通过标志选定的 kind 使用 CLI 的默认模型。角色文件自身的 model 属于该角色文件的 kind:如果有效 kind 来自配置层或标志,该模型也会被丢弃。如果 lane 设置了模型但没有设置 kind,其中的每个角色都会保留自己的 kind,而 doctor 会针对该 lane 中每个角色的 kind 检查 lane 模型。随附默认值:effort.grok=xhigh、effort.cursor=xhigh(grok 4.7 接受 --reasoning-effort xhigh|high|medium|low),因为这些方案很少会耗尽预算。应将预算花在有余量的地方。项目可在 .agents/herdr-agents.conf 中覆盖这些值,无需复制角色文件。

模型会跟随最新版本。 模型值可以是精确 ID、CLI 别名(Claude:fable、opus、sonnet 已表示“最新版本”),或匹配 CLI 列出的 ID 的正则表达式(cursor-agent --list-models、agy models、grok models、Codex 模型缓存);a|b 会按顺序尝试备选项。正则表达式会在启动时解析为匹配的最新模型,因此 opus 始终表示最新的 Opus。对于 sub-orchestrator 角色,位置为 orchestrator;其他所有角色的位置均为 worker。随附默认值:

model.claude.orchestrator=fable     model.claude.worker=opus
model.codex.orchestrator=astra      model.codex.worker=sol|gpt-5
model.cursor.worker=grok|muse       model.agy.worker=gemini|opus
model.grok.worker=grok

规划器不会获得 worker 模型:orchestrator 会在此会话中进行规划。spawn planner 会以状态码 12 退出。

通用 kind(pi、opencode)。 这些多模型 harness 在技能中不提供默认模型(默认值中没有 model.pi.* 或 model.opencode.*):请在用户或项目文件中自行设置 provider/id(model.<kind>.worker、role.<role>.model、lane 的模型,或 --model);如果均未设置,则 CLI 会使用自身的默认值。pi 会将 effort 映射为 --thinking(上限为 max);opencode TUI 不会映射 effort 标志(--variant 仅适用于 opencode run),启动时会发出警告而非失败。审批:opencode 的 full → --auto(不会映射 edits,并会发出警告);pi 则完全没有审批提示(edits 不执行任何操作,并会发出警告)。模型系列由模型决定:除非模型 ID 可识别,否则会跳过同系列审查者检查,因此请手动选择审查者的系列。配置和 provider 示例: references/kinds.md。

顶层 orchestrator 不会由技能启动;请自行按相同意图启动它(claude --model fable、codex -m gpt-6-astra)。$S model <kind> <spec> [effort] 会显示某个值的解析结果;$S models <kind> 会按从新到旧的顺序列出 ID。对于 Codex,effort 上限取决于所选模型声明的推理等级,而不是 kind。

  • effort 是一套标准化梯度:low < medium < high < xhigh < max, 并映射为各 CLI 自己的标志,且限制为对应类型支持的级别(kinds 会打印上限:claude、pi 和 codex 为 max;cursor 和 grok 为 xhigh;agy、gemini 为 high;opencode TUI 不映射 effort)。 对于 Codex,还会根据所选模型声明支持的级别进一步限制;如果 ~/.codex/models_cache.json 未列出某个模型,则该模型保持为 xhigh。 在 agy 上请求 max 会返回 high,并显示警告。未指定任何 effort 时,使用 Agent 自己配置的默认值(例如 ~/.codex/config.toml 中的 Codex model_reasoning_effort);此技能绝不会自行猜测默认值。
  • model 会传递给对应类型的模型标志。Cursor 没有 effort 标志:effort 是模型 ID 的后缀,因此 --model gpt-5.3-codex --effort high 会在 cursor-agent --list-models 列出该模型时变为 gpt-5.3-codex-high,否则会使用原模型并显示警告。Cursor 模型 ID 必须严格匹配:如果某个规格无法解析为 cursor-agent --list-models 中的 ID,就会在创建窗格前失败,因为 CLI 会拒绝未知和不受支持的参数化 ID,而不是将其传递下去。严格性针对的是规格解析:追加 effort 后缀的步骤会重新查询列表;如果列表无法确认解析出的 ID,就会原样传递模型,并显示警告 cursor model '<m>' not in --list-models; passing it through unchanged,而不会导致启动失败。请在 Cursor TUI 中确认实际生效的上下文窗口;模型的 原生运行环境可能会提供与 Cursor 不同的窗口。
  • approvals 决定工作进程无需人工介入即可执行的操作范围: ask(默认,使用 CLI 的常规提示)、edits(自动接受文件编辑)、full(不提示工具或 MCP 服务,但仍受 CLI 自身沙盒限制)。对于各类型,full 分别映射为:claude --permission-mode bypassPermissions + enableAllProjectMcpServers; codex -s workspace-write -a never;grok bypassPermissions --always-approve;agy --dangerously-skip-permissions;cursor --trust --force --approve-mcps。有两个对话框不会被刻意绕过: hook 信任提示(Codex --dangerously-bypass-hook-trust)以及某些 CLI 首次访问时的工作区信任提示。如果你愿意承担风险,请在 -- 后传入 CLI 自己的标志;否则 spawn 会以退出码 7 退出并显示界面,你需要手动回答一次。

无人值守运行(群组的常见使用方式)需要设置 --approvals full,或在项目角色覆盖配置中设置 approvals: full。角色默认使用 ask,确保全新安装时不会悄无声息地绕过提示。

将自动批准作为后备方案。 如果工作进程仍被阻塞(对应类型没有 full 映射、对话框不受 full 覆盖,或有意使用 ask),auto_approve=on 会让 dispatch/wait 发送 CLI 的默认“是”按键并继续等待,每次 dispatch 最多执行 max_auto_approvals 次。每次回答都会计入 dispatch JSON 中的 auto_approved,并记录在 <state>/wait/<agent>.approvals.log 下。此设置会批准工作进程提出的任何请求,因此应搭配沙盒类型或范围较窄的 approvals 使用。如果同一个对话框连续出现三次,就会保持阻塞状态 —— auto_approve: the same dialog came back 3 times for '<agent>'; leaving it blocked(不同的对话框会重置计数)——而 blocked JSON 行会在 dialog 中包含对话框内容(最近 20 行非空可见文本)。关闭此设置时,系统会报告被阻塞的工作进程(blocked,退出码 7),由人工决定。 无论是否启用 auto_approve,都不会代替工作进程回答问题:当被阻塞的界面是决策提示(Codex 的回答表单、Claude Code 的选项选择器、OpenCode 的问题对话框)时,wait 会报告 question(退出码 7),并在 JSON 的 question 中包含界面文本。

检测完成状态(唯一可靠的信号是报告文件)

Herdr 报告的是生命周期 状态,而不是轮次;每种集成都可能在任务进行中短暂显示为 idle/done。因此,该技能将报告文件作为完成信号,并提供三种观察方式。切勿自行针对 herdr agent get 编写轮询循环。每个组合提示词(简报和修订)的报告约定都规定:只有工作进程可以写入该报告,并且要等整个简报完成后才写入——子 Agent 或后台任务绝不写入报告,因为编排器会将报告是否存在视为完成信号;约定还规定,报告中的每条命令输出都必须从实际运行结果中粘贴,绝不重新输入或重构。

$S dispatch impl brief.md            # blocks until impl's report exists (default)
$S dispatch a brief-a.md --no-wait   # fan out…
$S dispatch b brief-b.md --no-wait
$S wait a b                          # …then block until every report exists
$S wait a b --any                    # or until the first one lands
$S status a b                        # non-blocking: done | working | blocked | question | no-report-yet | gone | unavailable | quota | provider-error | capacity | not-received

在执行过程中修订简报。 若要更改工作进程的简报——无论它正忙还是已报告——请将修订内容写入文件,然后运行 $S dispatch <agent> amend.md --amend;切勿手动发送 herdr agent prompt。修订会生成一份新报告供 wait 监视,而窗格会保留当前任务。对于忙碌的工作进程,消息会在 CLI 将其送达时到达(多数情况下会排队)。 wait 会为每个 Agent 输出一行 JSON(done、blocked、question、 settled-no-report、gone、unavailable、quota、provider-error、 capacity、not-received、timeout),并且仅当所有报告都已存在时才以 0 退出(7 表示 blocked/question,6 表示 settled/gone,4 表示 unavailable,9 表示 timeout,11 表示 quota,14 表示 provider-error/capacity,15 表示 not-received)。如果一次 wait 中有多个 Agent 完成,退出码取其中最严重的状态: 4,然后是 11、14、15、7、6。参数顺序不会改变结果。timeout 行包含 elapsed_ms(本次 wait 自身的耗时)和 state(最后一次探测标签,working 或 pending),每个超时的 Agent 还会获得一行 friction,指出状态,并将本次 wait 使用的超时时间加倍:timeout waiting for '<agent>'; it may still be working (state: <state>). Run: herdr-agents wait <agent> --timeout <2×>(超时时间 不是数字时,不会给出建议)。每个组合提示词都会要求报告每项的状态为 [done]、 [partial] 或 [skipped]。当报告代码块以外的 N 行带有 [partial] 时, done 行会增加 partial: N(仅当 N > 0 时,且位于 report 之后),wait 还会发出警告:report of '<agent>' marks N item(s) partial: a partial item is not a pass; read them before commit, push or release(报告不可读取时按 0 计,且该行 保持不变)。每份报告的警告每个 Agent 只发一次:标记会记录已警告的报告路径, 对同一报告再次执行 wait 时仍保留 partial 键,但不再警告;新报告路径则会 再次触发警告。四种审查角色(reviewer、security-reviewer、ui-reviewer、 inspector)会在报告首行写入精确格式 findings: N (P0 a, P1 b, P2 c, P3 d) | verdict: pass|fail,无论报告语言为何, 该行都使用英文(当仍有 P0 或 P1,或变更不应按现状提交时,使用 fail)。 当 done 报告包含此行时,JSON 行会增加 verdict、findings 和 severity (紧跟在 report 之后、partial 之前);数字按解析结果保留——如果首行中 P0..P3 的总和与 findings 不一致,则会发出警告 report of '<agent>': findings <N> but P0..P3 add up to <sum>;如果审查角色的 done 报告没有此首行,则会发出警告 report of '<agent>' has no 'findings: N (P0 a, P1 b, P2 c, P3 d) | verdict: pass|fail' first line。审查角色还会告知 worker:在称测试、断言或命令有误之前, 如果任务说明允许,就先运行并引用输出;如果无法运行,则说明原因并降低置信度—— 阅读代码并不能证明测试失败。dispatch JSON 也会包含相同的 partial: N,紧跟在 report_exists 之后(如果有 amend,则位于其后);审查字段(verdict、 findings、severity)紧跟在 report_exists 之后(如果有 amend,则位于其 后)。JSON 为单行,且 wait_status 位于首位,因此 dispatch … | tail -1 会返回完整 JSON。当 wait 最终采用的报告与 dispatch 自身的报告不同时——等待期间 发送的 amendment 重新指向了 last-report-<agent>——JSON 会在 report 之后增加 settled_report: <path>,并由 report_exists 指明该报告;如果 wait 使用的是 dispatch 自身的报告,则不包含此键。发送前,如果新任务说明涉及的文件仍由 roster 中的其他 Agent 编辑(其报告仍处于 pending),dispatch 也会发出警告: brief <path> owns files that '<agent>' is still editing: <paths>(最多列出五个 路径;对于只读角色,则为 reviewing files that '<agent>' is still editing: <paths>) ——这只是提示,不会阻止操作。路径会按文件、目录和 glob 进行比较 (src/**/*.ts 会匹配 src/a/b.ts;roles/reviewer*.md 会匹配 roles/reviewer.md)。如果 codex worker 的启动参数未授予相应访问权限,其组合 提示词(任务说明和 amendment)会附带沙箱说明(danger-full-access 或 --dangerously-bypass-approvals-and-sandbox 会移除两条说明):Your sandbox cannot write under .git: do not run git mv, git checkout, git add or git commit. Describe renames and restores in the report; the orchestrator runs them.;并且——除非 某个参数以 network_access=true 结尾,例如 -c sandbox_workspace_write.network_access=true——还会附带 Your sandbox has no network, local ports included: tests that start a local server fail with "Operation not permitted". Mark them [partial] and say so; the orchestrator runs them. Still write the integration tests the brief asks for, even if you cannot run them here; do not replace them with unit tests of helpers, and add a test seam (an injectable value) when the code depends on something fixed, such as the build type.。 带有 danger-full-access 的参数不会附带任何说明。当同一工作树(相同 roster cwd)中有其他处于活动状态且承担编辑角色的 roster Agent 时,组合提示词(任务说明 或 amendment)会增加 Another worker edits this same tree now: run the global checks the brief asks for, but report failures in files you do not own as outside your slice (name the files), not as [partial] items of yours.(如果 Herdr 无法列出这些 Agent, 则跳过该行;这只是提示)。

provider-error 表示 worker 处于空闲状态,且其最后一行错误显示模型提供方已中断 (例如 Request timed out、Connection error、Retry failed after N attempts、 503: {…});JSON 中的 cause 就是该行。capacity 表示提供方因容量已满而拒绝 请求(例如错误类型名称中包含 capacity 或 overload,或状态码为 529)。精确模式 统一定义在 scripts/lib/provider.mjs 中。遇到 capacity 时,wait 会先向 worker 发送 "continue",最多发送 provider_retries 次,每次间隔 provider_retry_delay 秒(每次都会记录在 friction 中);只有这些尝试无效时才会 报告 capacity。这两种状态都需要连续两次探测结果相同才会计入,因此短暂的屏幕 状态不会结束 wait。worker 处于 working 状态时,如果屏幕上的计数器在 stuck_warn_minutes(20 分钟)内始终不变,就会收到一行 friction ("may be stuck in one tool call");wait 会继续执行。缺失、为空或非数字的屏幕 年龄标记会从现在开始计时(在原处重写),绝不会从 Unix 纪元开始计时。 dispatch 还会检查提示词是否已送达:在 prompt_check_seconds(15)内,Agent 必须开始工作或阻塞,或者报告必须出现。如果提示词文本仍在 Agent 的输入框中,它会发送一次 Enter(JSON enter_sent);如果屏幕没有变化,则会重新发送一次提示词(resent);如果仍然无效,则返回 not-received(退出码 15)——发送其他内容前请先读取窗格。not-received 的 dispatch 会记录发生时间和 Agent 的 state_change_seq;之后的 wait 会在提示词仍显示在 Agent 输入框中时,每隔一个 prompt_check_seconds 时间窗口重试一次 Enter,最多重试 3 次:如果 Agent 开始工作,或者其状态在标记之后已发生变化(state_change_seq 不同),则会清除标记,并照常继续等待;重试 3 次后,或者提示词已不在输入框中且 Agent 尚未开始工作时,等待会以 not-received 结束(退出码 15)。status 也会以相同方式报告 not-received,但为只读操作(退出码 15,不发送按键);如果序号已变化,也会清除该报告。gone 仅表示 agent_not_found。unavailable 表示 herdr agent get 遇到权限或传输故障(原因会显示在 stderr 和 JSON error 中):请重试或恢复访问权限;查询不可用时,请勿启动替代项,也不要在未指定 --force 的情况下执行 release 或 release --close。如果 herdr agent get 被信号终止(退出码 ≥ 128,例如负载过高时的 137),且没有结构化错误,则视为暂时性故障:等待 1 秒后再试一次,然后等待 2 秒后再试一次,再计入故障;如果仍然发生,原因将是 herdr agent get was killed (exit <rc>, <signal>: memory pressure or an external kill)。报告在两次轮询之间大小不再变化时,即视为已完成。配置中的 notify=on 会为每个已完成的工作进程显示一条 Herdr Toast 通知。roster 会显示 REPORT 列(none | pending | ready),方便快速查看。

配置

纯 key=value 文件,按以下顺序读取;每一层只覆盖自己设置的键:

  1. 技能中的 config.defaults(文档所述的默认值)
  2. ~/.config/herdr-agents/config——用户级
  3. <repo>/.agents/herdr-agents.conf——项目级
  4. <state>/session.conf——会话层:每个 Herdr 工作区各自一份,位于 Git 忽略的状态目录中,永不纳入版本控制
  5. HERDR_AGENTS_<KEY> 环境变量
  6. 命令行标志

会话层。 session set <key> <value> 会写入工作区的 <state>/session.conf:它会覆盖项目级和用户级文件,但标志和 HERDR_AGENTS_* 仍具有更高优先级——适合设置“仅本会话生效”的选项(例如,仅本周让每个工作通道都使用个人提供商: session set lane.build.kind pi + session set lane.build.model my-provider/my-model)。session show 会打印各项配置;session clear [key] 会删除某个键或整个文件。config 会以来源 session 打印会话值。在 Herdr 之外(无法解析工作区时),此层不存在。 $S config 会打印每个生效值及其来源:先按顺序打印标量键,然后打印点分隔键(args.*、role.*、model.*、effort.*、lane.*,按字母顺序排序)——某一层持有该键时,使用文件中的原始拼写;仅存在于环境中的键则使用重建后的点分隔名称。 键: orchestrator_name、layout(split:在调用方的标签页中使用窗格,直到标签页已满,然后使用 herd 标签页;tab:仅使用 herd 标签页)、max_workers(同时运行的活动工作者数量,不计协调器;默认值为各通道容量之和,四个窗格时为 3;达到上限时 spawn 以状态码 8 退出;0 = 无上限)、split_max_panes(每个标签页的窗格数,包含调用方;默认值为 panes)、split_min_pane(生成工作者后可保留的最小窗格大小,占标签页的比例;默认值为 0.18)、regrid(每次生成/释放后都采用精确网格)、herd_label + herd_label_max(自动 herd 标签页标签的模板和长度;默认 {roles} → impl+rev,16 个字符;参见“Herd tab labels”)、brief_lint(warn|strict|off;只读角色无需 Owned files 部分)、brief_lint_aliases(简报部分标题的备用写法,Section=Heading|Heading 项;以 1–3 级标题开头的标题前缀即可满足该部分要求——参见“Briefs are contracts”)、reuse_workers (默认值为 on,即使未在任何配置中设置也是如此:spawn 会返回一个同角色、类型和当前工作目录的空闲工作者,前提是它存在上一份报告,而不会打开窗格;复用永远不计入 max_workers;--reuse/--fresh 可覆盖单次调用的设置;复用的工作者会在上下文中保留之前的简报,因此若某个任务片段必须从干净状态开始,请传入 --fresh)、multi_role(默认值为 on;一个空闲 Agent 可以承担另一角色——参见“Setup: guided configuration”)、feedback + feedback_repo(参见“Improving this skill”)、approvals(未单独设置的角色的默认值)、auto_approve + max_auto_approvals(使用 CLI 的默认“Yes”回答工作者的审批对话框并继续等待;默认关闭,见下文)、max_effort (全局上限)、family_check(strict|warn|off)、settled_grace、 spawn_timeout、dispatch_timeout、state_dir、report_language、 notify、args.<kind>(始终追加原生标志;可在此处设置你接受的钩子信任或工作区信任绕过选项)、role.<role>.kind (无需复制角色文件即可替换角色类型)、role.<role>.args (角色的原生参数,lanes=off 时适用;启用通道时,每个角色都在某个通道中运行,通道会话由其中的所有角色共享,且只有 lane.<name>.args 会生效;两种设置都仅适用于为该角色或通道配置的类型)、panes(2|3|4, 默认值为 4)、lanes(on|off)、pane_mode(strict|flex,默认值为 strict)、flex_extra(flex 可额外添加的临时工作者数量,默认值为 1)、flex_roles(可使用这些临时工作者的角色,默认值为 reviewer,documenter),以及 lane.<name>.roles|kind|model|effort|approvals|panes|args(panes = 通道容量;args = 该通道中所有工作者的原生参数)。作用域参数会追加在 args.<kind> 之后、-- 后的原生参数之前。若配置文件中的作用域键无法由当前通道模式应用,doctor 会发出警告。工作者会保留启动时使用的原生参数(名册第 14 列),因此更改这些键后,使用其他参数启动的空闲工作者不会被复用:lanes=off 会启动一个新工作者;通道则会返回 kind-mismatch(状态码 13),直到你释放该工作者。

命令

所有操作都通过 scripts/herdr-agents 执行(需要 herdr 和 Node.js 20+ 或 Bun——不需要 bash、不需要 jq):

S=<path-to-this-skill>/scripts/herdr-agents      # POSIX; Windows: <path-to-this-skill>\scripts\herdr-agents.cmd
$S init                                    # doctor + name yourself `orchestrator`, title an untitled pane, print context (`first_run`)
$S title "<objective>"                     # this pane's title: `orchestrator: <objective>`
$S title --clear                           # clear this pane's title
$S doctor [--fix --panes 2|3|4] [--user|--session]   # advisory check (`first_run: true|false`); --fix normalizes the project, user or session file
$S explain                                 # plain text: what is running, or how to start
$S setup [--target FILE] [--no-hooks]      # AGENTS.md block + Claude hooks (idempotent)
$S setup --detect                          # JSON: installed kinds, summaries, models (incl. custom providers), recommended reviewer; writes nothing
$S setup --probe [--kind K --model M]      # JSON: ready|no-auth|quota|error per kind/model + own pi/opencode models (≤5 per kind; rest in skipped_custom); no panes
$S setup --plan …                          # diff -u per file (config files: key before → after) of what setup/--set/--user-set/--session-set would write; writes nothing
$S session set <key> <value>               # this-session override in <state>/session.conf (above project, below flags/env); also <key>=<value>
$S session show | session clear [key]
$S roles                                   # roles with the kind, model and effort in effect and where each comes from
$S role reviewer                           # resolved file + frontmatter
$S spawn implementer [--name impl] [--kind codex] [--direction right|down]
$S dispatch impl <brief.md> [--timeout 900000] [--amend]   # role prompt + brief → agent, waits; --amend amends the agent's current brief
$S collect impl [--lines N] [--verify]      # prints the report file (or recent output); an agent still working or blocked with no report gets a short stderr line and exit 4 (no terminal dump) unless --lines is passed; --verify re-checks the report's sha256 lines (exit 16 on changed/missing, 4 when the report cannot be read)
$S run scouter <brief.md>                    # spawn + dispatch + collect in one call
$S wait a b [--any] [--timeout MS]         # block on report files
$S stats [--since <date>] [--json]          # tasks, times and review findings per role, from the state dir; <date> is YYYY-MM-DD or ISO 8601 (other formats exit 2); the review table covers reviewer, security-reviewer, ui-reviewer and inspector
$S friction                                # errors/warnings of this workspace (review at end)
$S friction add "<text>" [--brief <path>]  # record one friction note (level note, command friction; --brief appends ` (brief: <path>)`)
$S feedback send <report.md> "<summary>"   # feedback=local: save the report in feedback_dir as from-<project>-<date>.md (never overwrites) and send one line to feedback_to
$S regrid                                  # exact grids: caller's tab (split) + every herd tab
$S tab-label                               # herd tabs: id, label, auto|manual
$S tab-label "onda 2" [--tab ID]           # pin a label (newest herd tab, or --tab); --auto goes back
$S spawn reviewer --tab-label "onda 2"     # place the worker in the herd tab of that name (created if needed)
$S layout-plan                             # where the next spawn lands (anchor, direction, overflow reason)
$S status a b                              # non-blocking completion check; no names exits 2 and points to `roster`
$S config                                  # effective configuration and sources (incl. the session layer)
$S config set <key> <value> [--project|--user]   # write one key (default: the project file); also <key>=<value>
$S roster                                  # live agents with role/kind/pane/state/report and the current task (TASK, from the pane title; '-' when none, cut to 40 characters)
$S release impl [--close]                  # forget the agent; --close closes a pane we created
$S clean [--older-than 7]                  # drop gone agents, delete old briefs/reports
$S kinds                                   # kind → executable, family, effort ceiling
$S spawn implementer --effort xhigh --approvals full      # normalized effort + no prompts
$S spawn scouter --kind cursor --model gpt-5.3-codex --effort high --approvals full
$S spawn implementer -- -s workspace-write -a never      # native agent args after --

scripts/herdr-agents 是一个 POSIX sh 启动器:它会使用 node(20+)运行 scripts/herdr-agents.mjs,如果 Node.js 20+ 不可用(缺失或版本较旧),则使用 bun,并传入相同的参数。如果两种 运行时都无法使用,它会输出 herdr-agents: needs Node.js 20+ or Bun 并 以状态码 2 退出。 scripts/herdr-agents.cmd 是适用于 Windows 的同一启动器。setup SessionStart 钩子会按以下顺序检查这些位置:项目的 .agents/skills、项目的 .claude/skills、$HOME/.agents/skills,然后是 $HOME/.claude/skills。它会调用找到的第一个启动器,执行 sh "<skill-root>/scripts/herdr-agents" doctor。

命名。 启用 lanes 时,Agent 的名称取自 lane(build、 build-2、review、docs)。如果 Herder 中已有同名的运行中 Agent,则会 使用下一个可用的后缀(如果名称来自 --name,则会发出警告)。lanes=off 时,名称取自角色 (implementer,然后是 implementer-2)。传入 --name 可设置自定义名称 ([a-z][a-z0-9_-]{0,31})。在 dispatch、collect 和 release 中使用该名称;不要使用 pane ID。

审查者家族检查。 dispatch 遇到 reviewer 或 security-reviewer 时,会将其模型家族与此技能启动的所有编辑 Agent 进行比较。 编辑 Agent 包括 implementer、designer、tasker、任何 frontmatter 中 mode 为 edit 的角色,或 roles 历史记录包含上述角色之一的工作 Agent——即使某个工作 Agent 曾编辑过,之后又被重复用作 scouter,仍会被计入。同一家族 → 除非指定 --allow-same-family,否则以状态码 5 退出。 此检查无法识别编排器自身编写的代码;因此请手动选择审查者类型。 spawn 在 layout=split 下会让工作者留在调用者的标签页中,不会把窗格挤得过于密集:选择面积最大的候选窗格(调用者 + 此技能在该标签页中的工作者),沿较长的一侧将其一分为二(--ratio 0.5;宽度比例 ≥ 高度比例 → right,否则为 down),然后 regrid 将标签页重建为覆盖调用者 + 工作者的精确网格——调用者留在最不拥挤列的左上角(3 个单元格:调用者占满整列高度,两个工作者上下堆叠;4 个单元格:2×2)。当标签页中已有 split_max_panes 个窗格(默认值 4 = 调用者 + 3 个工作者),或没有窗格可以在不低于 split_min_pane(默认值为标签页的 0.18)情况下继续一分为二时,工作者会溢出到一个 herd 标签页——优先选择第一个有空间的标签页,否则新建一个;标签页名称根据其中的角色(impl+rev)或你指定的工作波次生成(spawn 会打印 placement: split|herd;layout-plan 会显示决策及原因)。release --close 会释放名额,因此下一次 spawn 会再次在调用者的标签页中创建工作者。layout=tab 只使用 herd 标签页。每个 herd 标签页也会重建为精确网格(列数 = ⌈√n⌉,行数均衡),并保留其标签名称。regrid 也会执行反向操作:当调用者的标签页重新有空间时(工作者已释放、上限已提高),会先从第一个 herd 标签页的第一个窗格开始,把溢出的工作者移回,直到调用者 + 工作者达到 split_max_panes;清空的 herd 标签页会自行关闭。调用者标签页重排期间,工作者会经过一个临时的 herd-park 标签页,因为 Herdr 不允许在同一标签页内移动窗格;Agent 会继续运行。工作者总数有限制:同时运行的工作者最多为 max_workers(默认 3,与协调器合计为四个窗格),协调器不计入上限——上限按名称和窗格统计运行中的 Agent:只有当某个清单行对应的窗格中存在同名运行中 Agent 时才计入(没有已知窗格的行则按名称统计,且只计一次);过时的行——即该名称的 Agent 在另一个窗格中运行——不计入。超出上限时,spawn 会以代码 8 退出并列出运行中的工作者:对已收集报告的工作者执行 release --close,或让 reuse_workers 分配空闲工作者(multi_role=on 时可能分配其他角色;参见“Setup: guided configuration”)。将工作安排为每波最多三个切片,而不是扩展到更多并行工作者。spawn 会重试几秒,等待新 shell 出现提示符,然后使用 --no-focus 启动 Agent。启动后,spawn 会监视 5 秒:如果某个 CLI 在启动时自我更新后退出(目前观察到的只有 Codex 自动更新),就会在同一窗格中使用相同参数重新启动一次('<name>' (<kind>) updated itself at start and exited; started it again);如果 Agent 在启动后立即退出但没有该标记,或在重新启动后退出,spawn 会以代码 4 退出,并显示最后几行屏幕内容(最多 5 行,以 / 连接);窗格会保持打开以供检查,且不会写入清单行。只有在没有运行中的 Agent 使用该名称时,名称才可用,因此,遗留名称的清单行(或 spawn 重用的窗格)都属于已退出的 Agent:spawn 会移除它(replaced the stale roster line of '<name>' (pane <pane>)),而 roster/status 会将名称在另一个窗格中处于运行状态的行显示为 gone,而不是显示另一个 Agent 的状态。herdr agent start 仍会切换焦点到新窗格;spawn 只会在焦点仍位于该窗格时将焦点切回原先所在的窗格,并会保留你已切换到的窗格。regrid 不会切换到调用者所在的标签页。显式指定 --direction/--ratio 时,会按要求拆分选定的窗格(如果标签页已满,则拆分调用者的窗格),并跳过本次调用的自动重排。 -- 后的所有内容都会传给 Agent CLI(herdr agent start … -- <args>)。 Herd 标签页标签。 Herd 标签页根据其中运行的内容命名,而不是命名为 herd-2。自动标签来自 herd_label(默认值 {roles}:标签页中不同角色的名称,按加入顺序排列并缩写为 impl、rev、insp、des、scout、res、task、sec、sub、plan;项目角色保留其文件名——例如 impl+rev;重复标签会变为 impl+rev 2;还支持 {n} 工作者数量、{i} 标签页位置(从 2 开始)、{orch}),并截断至 herd_label_max(16)个字符;每次 spawn/release/regrid 后都会重新计算。工作有名称时,请根据切片或波次命名标签页,而非根据角色命名:spawn <role> --tab-label "onda 2" 会将工作者放入该标签页(如果标签页不存在则创建,不论调用者标签页是否有空间;已满时会溢出到 onda 2 ·2),而 $S tab-label "paridade" 会固定最新 herd 标签页的标签(要指定其他标签页,请使用 --tab ID)。标签不超过 16 个字符——侧边栏会截断其余部分。固定标签以及在 Herdr 中手动重命名的标签页属于 manual,不会被覆盖(tab-label --auto 会让标签页恢复自动命名);roster 会显示每个工作者所在的 TAB。 dispatch 会将组合提示词(角色正文 + 简报 + 报告约定)写入状态目录,并发送一行指向该文件的内容,因此较长的简报不受终端粘贴长度限制影响。退出代码:2 用法/环境错误,3 未知角色/Agent,4 Herdr 故障(unavailable),5 同一系列的审查者,6 已结束但没有报告,7 Agent 被阻塞(启动或审批),8 已达到 max_workers,9 等待超时,10 工作通道忙,11 配额耗尽,12 spawn planner(协调器负责规划),13 工作通道 kind-mismatch(运行中的会话使用了其他 CLI:释放该工作通道,并设置 lane.<name>.kind 以防再次发生),14 提供方错误或容量不足,15 未收到提示词(dispatch 和 wait),16 collect --verify:报告的文件已更改或缺失(文件存在但无法读取的报告会以代码 4 退出)。 代码 7 也适用于提出了 question 的工作者。多 Agent wait 会采用 4、11、14、15、7 和 6 中最严重的退出代码。每条错误和警告也会追加到 <state>/friction.log($S friction)。

What is implicit (read once)

  • 角色是第一条消息,而不是系统提示词。 worker 仍遵循自己的运行框架:项目的 CLAUDE.md/AGENTS.md、钩子、技能、MCP 服务和记忆。当角色与仓库说明冲突时,由 worker 的运行框架决定,而不是此技能。使用 worker_context=full 时,预计 worker 会花第一分钟阅读项目规则和记忆。worker_context=lean 会减少这部分:组合后的提示词禁止读取说明文件,除非任务简述点名要求读取;Codex 会获得 project_doc_max_bytes=0,Claude 不会获得技能目录。只有当任务简述引用了所有适用规则时,Lean 才有效;而任务简述模板本来也要求这样做。
  • 权限由 worker 决定。 CLI 使用默认批准模式时,会在遇到第一个审批时停止,等待操作会返回 blocked。无人值守运行时使用 --approvals full(或 edits);映射未涵盖的任何内容都需放在 -- 之后。未经用户同意,绝不要处理 blocked 对话框。
  • 启动对话框。 更新提示、登录和信任对话框会使 agent start 返回 agent_not_ready;spawn 仍会记录该 Agent、打印屏幕内容并以状态码 7 退出。询问用户,然后使用 herdr agent send-keys <name> … 作答,再运行 herdr agent wait <name>。
  • 一个 Agent,一个持续增长的会话。 对同一名称多次调用 dispatch 会进入同一段对话;worker 会记住先前的任务简述。collect 只打印最新报告;较早的报告仍保存在 reports/ 中。如果不同切片之间不得泄露上下文,请启动一个新的 Agent。
  • dispatch 只识别此技能启动的 Agent。 在 Herdr 中手动启动的 Agent 不在名单中;请直接使用 herdr agent prompt。
  • 状态按仓库和 Herdr 工作区分别维护。 其他工作区中的编排器看不到这些 Agent;同一工作区中的两个编排器共享名单。不会自动删除任何内容;请运行 clean。
  • 等待跟踪的是状态,而不是轮次。 worker 仍在执行任务时,Herdr 可能报告 idle/done(Codex 在进行 MCP 调用时会出现这种情况)。因此,dispatch 和 wait 会等待报告文件,直到 Agent 不再处于 working 状态 并且 屏幕在 settled_grace 秒(45)内没有变化,或者超时耗尽。timeout 的意思是“再次运行 wait”,而不是“丢失”。
  • approvals: ask 不保证会出现提示。 它表示使用 CLI 自己的默认设置;defaultMode: auto 的 Claude Code 永远不会阻塞。要强制手动审批,请在 -- 之后传入原生标志。
  • 超时。 spawn 会等待 60 s 以确认就绪(--timeout)。dispatch 和未指定 --timeout 的 wait 都会采用角色的有效超时时长:角色文件 frontmatter 中的 timeout(ms),否则采用 dispatch_timeout(15 min),再按角色的有效 effort 缩放(xhigh × 1.5,max × 2,其他情况 × 1);等待多个 Agent 时,wait 会采用这些角色中最大的超时时长。显式指定的 --timeout 始终优先。无论 wait_status 显示什么,报告文件都是判断依据。
  • Claude Code 编排器的 Bash 会将每次调用限制为 10 分钟,这比长时间审查的时长更短:请在后台运行 wait(或会等待的 dispatch),并由运行框架自己的通知唤醒你——不要在它前面加上 timeout。wait --any 会在每份报告到达时唤醒你:只要有一份报告到达,它就会立即以状态码 0 退出(并打印该报告的 JSON 行),因此请再次运行它来等待剩余 Agent;等待操作自身的超时(见上文的角色有效超时时长)仍然适用。
  • Codex worker 的沙盒比它认为的范围更窄。 Codex worker(-s workspace-write)无法在 .git 下写入(git mv 和 git checkout -- <file> 会因 .git/index.lock 而失败),也无法访问网络,包括本地端口。组合后的提示词会说明这一点(见“检测完成情况”中的沙盒备注):worker 会在报告中描述重命名和还原操作,由编排器执行这些操作;网络测试会标记为 [partial],并由编排器运行。需要网络的角色或工作泳道:使用 args.codex=-c sandbox_workspace_write.network_access=true(每个 Codex worker 都如此),或者在该角色或工作泳道配置为 kind codex 时,使用 role.<role>.args/lane.<name>.args 并设置相同的标志。这些都是同一个 CLI 的标志:只有当启动操作运行的 kind 是该角色或工作泳道配置解析出的 kind 时,它们才会传递给 worker(传给其他 kind 的 --kind 标志会丢弃它们,并发出警告),因为 Codex 的 -c <key>=<value> 对 Claude 来说是 --continue,会在同一 cwd 中恢复编排器的对话;对 Cursor 来说则是 --cloud。此外,无论来源如何,只要 spawn 收到传给 Claude 或 Cursor 的恢复标志(-c、--continue、-r、--resume、--cloud),就会在打开窗格前拒绝执行。Herdr 控制套接字也会以相同方式被阻止,因此嵌套编排器不能是受沙盒限制的 Codex。
  • 不带 --close 的 release 会让 Agent 继续运行。 --close 会通过关闭窗格来结束它。通过 --pane 传入的窗格绝不会关闭。run 不会释放 Agent。
  • 工作树由你负责创建。 使用 git worktree add .worktrees/<slug>(或 herdr worktree create),并通过 --cwd 传入路径。名单保留在主仓库中;cwd 不在仓库根目录下的 worker,其任务简述和报告会经由 $TMPDIR/herdr-agents/<ws>/reports/ 路由;所有已知沙盒都可以写入此目录。你需要自行将其 diff 合并回来(使用 git -C <worktree> diff | git apply,或 cherry-pick)。对于同一 cwd 中其他仍在运行的 edit-role Agent,spawn(新 worker 和复用 worker)都会发出警告:'<a>' and '<b>' both edit <cwd>: builds and test runs see each other's changes in progress; give each a git worktree (spawn --cwd <worktree>) to isolate them——解决办法是每个 worker(或每个分支)使用一个工作树。路由过程中保存在 $TMPDIR/herdr-agents/<ws>/reports/ 下的 done 报告会尽力镜像回状态目录:同名报告写入 reports/,组合后的提示词(去掉 .brief)写入其旁边的 briefs/;复制失败时会发出警告,但 done 状态仍然有效,而且 last-report-<agent> 和 wait 的 JSON 行仍指向原始报告。
  • 不同 kind 的检测质量各异。 claude 和 codex 有 Herdr 集成;grok 和 agy 通过屏幕检测,因此其 idle/done 状态可靠性较低,且常出现 unknown。
  • 语言。 你告诉用户的一切都应使用用户的语言:首次运行说明、设置问题、过程说明和最终摘要。任务简述也使用用户的语言。标识符保持英文(角色名称、窗格名称、文件路径)。worker 使用任务简述所用的语言进行报告。$S explain 会输出英文纯文本;回答时请翻译。
  • 不支持远程计算机。 不支持 --machine 目标;ID 和名单仅限本地此服务。
  • 任务简述会逐字复制到磁盘上的组合提示词中。请勿在其中放入密钥和客户数据。
  • worker 有自己的命令防护机制。 此类设置中的 Codex 守卫会拒绝 rm -f 风格的命令,不受审批设置影响。任务简述应描述预期结果,而不是破坏性的 Shell 命令写法。
  • 布局。 同时运行的 worker 最多为 max_workers(3)个,因此调用者的标签页通常会容纳 2×2 网格(split_max_panes 4)。仍然无法容纳的 worker(超出 split_min_pane,或超过提高后的上限)会转到以角色名称(impl+rev)或你通过 --tab-label 指定的工作波次名称命名的 herd 标签页;设置 layout=tab 可让调用者的标签页保持不变。 状态(简报、报告、人员名单)存放在项目内部的 <repo>/.herdr-agents/<workspace-id>/ 下,脚本会将该路径添加到 .gitignore。沙盒工作进程可以在此写入:Codex workspace-write 允许访问仓库根目录、/tmp 和 $TMPDIR,但禁止访问自身的配置根目录 (.agents/、.codex/),因此状态不会存放在 .agents/ 下。 只有在每个工作进程都能写入该目录时,才使用 HERDR_AGENTS_DIR 覆盖根目录。 根据约定,报告以文件形式保存,因此收集报告不依赖于抓取备用屏幕 TUI。

并行流程

最多保留 panes 个窗格,其中包括当前会话(以及下文灵活模式中的临时窗格)。 编排器负责规划,不会启动工作进程。其他窗格是工作通道:会话按顺序承担 其所属组中的任意角色。一个工作通道可以容纳多个工作进程(即其容量)。 reuse_workers 保持启用。每次 spawn 前,都会查询人员名单:

  • 如果工作通道中有空闲或已完成的工作进程,且其报告已存在(或从未收到简报) → 复用该工作进程并切换角色(第 4 列加上角色历史记录)。如果 lane.<name>.kind 为空,且此角色的 kind、model 或 effort 与当前会话不同, spawn 会输出 {"status":"kind-mismatch","lane":…,"name":…,"session_kind":…,"requested_kind":…} (以及 model 和 effort),并以状态码 13 退出。如果设置了 lane.<name>.kind,那么该通道中的每个角色都会使用此 kind 对应的 CLI: 当前运行于该 kind 的会话会被复用;如果会话仍在运行另一个 CLI(在该键 创建前启动),也会以状态码 13 退出,因为该键不会重定向正在运行的进程。 无论哪种情况:运行 release <name> --close,如果 lane.<name>.kind 尚未设置,则设置它,然后再次运行 spawn;
  • 没有空闲工作进程,且运行中的工作进程数量少于通道容量 → 打开一个新的 工作进程(build,然后 build-2);
  • 通道已满(每个工作进程的状态都是 working、blocked,或有待处理的报告) → spawn 会输出 {"status":"busy","lane":…,"name":…} 并以状态码 10 退出, 同时列出所有工作进程。运行 wait <name>,然后再分派任务。不要打开另一个窗格 ——灵活模式中的临时窗格除外;
  • 工作进程状态为 gone → 删除其人员名单条目,且不计入数量;
  • 无法查询该通道中的工作进程(unavailable),且没有空闲工作进程 → 在打开任何新窗格前以状态码 4 退出:该工作进程可能仍在运行;恢复访问后重试, 绝不要为其启动替代进程;
  • 已满通道中的每个运行中工作进程都修改过内容,且当前角色是审查角色 (locked)→ 以状态码 5 退出:会话绝不审查自己编写的代码;请使用审查通道, 或释放其中一个工作进程。

预设(未设置 lane.*.roles;运行时根据 panes 和 pane_mode 解析,绝不会写入配置):

panes通道(容量)编排器
4(默认)build(2):实现者、设计者、任务规划者、侦察者、研究者 · review(1):审查者、安全审查者、UI 审查者、检查员负责编排、规划和探索
3build(1)· review(1)同上
2build(1)也负责审查,使用与 build 通道不同的模型系列(手动选择)

研究属于 build 工作:空闲的构建者可以梳理代码或阅读另一个仓库,也可以由编排器完成。 除非用户、项目或环境另行设置,max_workers 默认为容量总和(3、2、1), split_max_panes 默认为 panes。lane.<name>.panes 可更改某个通道的容量。 Strict 或 flex(pane_mode,默认值为 strict)。Strict 不会打开临时工作面板:每个泳道都不会超出其容量(你设置的 lane.<name>.panes 会提高容量;max_workers 只是全局上限,不会为某个泳道打开名额),文档编写也属于构建工作(documenter 角色位于构建泳道)。Flex 最多可在 panes 之上额外打开 flex_extra(1)个临时工作面板,但仅限 flex_roles(reviewer,documenter)中的角色:第二个 reviewer(每个 builder 对应一个;或者让 reviewer 和 security-reviewer 并行处理同一个切片——两者都来自与 builders 不同的模型家族),或 documenter(泳道 docs)。只有一个空闲名额时,优先进行审核:这能解除推送阻塞;文档工作则等待。使用 2 个面板时,flex 的额外 reviewer 会接手审核,让 orchestrator 腾出精力。临时工作面板会在名单中标记为 burst;即使不带 --close,release 也会关闭其面板。在 flex 模式下,max_workers 和 split_max_panes 都会增加 flex_extra,因此额外面板会留在此标签页中。

documenter 只编辑文档(README、指南、参考资料、ADR、CHANGELOG),绝不编辑代码;它会在某个切片通过审核后,根据规范和已提交的差异开展工作。描述行为(命令、标志、配置)的文档应交给 reviewer;其余文档由 orchestrator 检查。仅担任过 documenter 的会话,在 reviewer 的模型家族检查中不算编辑 Agent;之前编辑过代码的会话(历史中有更早的角色)仍然算。

sub-orchestrator 默认不属于任何泳道,除非用户将其加入其中:嵌套的 herd 会打开更多面板,从而突破上限。lanes=off 会保留按角色区分的名称和 multi_role 复用。

将工作拆分为文件互不重叠的小切片。使用 --no-wait 分派,并通过 wait --any 收集结果。builders 工作期间,规划下一个切片,并整合刚返回的报告;优先处理 reviewer 队列中最先阻塞推送的切片。只要还有工作,就不要让 builder 闲置。泳道已满时,应先 wait,再分派,而不是新开面板。

spawn <role> 会解析对应泳道。没有泳道的角色会报错,lanes=off 时除外(并且在 panes=2 时,审核角色会提示由 orchestrator 进行审核)。如果两个 orchestrator 同时向同一泳道分派任务,可能会使其容量超出 1 个名额:Agent 启动前不会预留名额。

Orchestrator 工作流程 — /herdr-agents <objective>

当 first_run: true 时,先执行首次运行,并在打开任何面板前获得用户同意。工作进行期间,每个可见操作都用一行说明(叙述工作进展)。用户询问当前进展时,运行 $S explain(当前进展)。

并非所有任务都要委派。 如果某项任务只涉及一两个文件,且不需要产品决策——例如修改文档或配置、修复几十行代码的一次性小问题、回答问题,或执行一项比撰写任务说明更快的验证——就由 orchestrator 直接完成。经验法则:如果写任务说明比完成修改更费时,就直接修改。应委派多文件切片、符合设计规范的 UI 工作、任何涉及身份验证、机密或输入处理的工作、可并行处理的工作,以及任何需要 reviewer 的修改。研究工作也应委派:为辅助决策而阅读大量文件、其他代码仓库或多个工具的约定,属于 scouter 的工作;orchestrator 应要求对方提交包含建议的报告,再据此决策,而不是亲自调查并消耗自己的上下文。你自己编写的产品代码,在推送前仍需由来自另一个模型家族的 reviewer 审核;模型家族检查无法识别你自己的修改,因此要手动选择审核者的类型。

  1. 先明确方向。 如果目标中隐含着产品决策,先用一句话提问,再做规划。绝不要在明确方向之前写长篇计划。

  2. 自行拆分任务。 将任务拆分为文件互不重叠、接口明确且有执行顺序的切片。共享资源(i18n 目录、小型存储、常量)要么在任务说明中准备就绪,要么明确归属一名 Agent。

  3. 选择角色。 编排者负责规划。不要 spawn planner。 调研 → scouter/researcher(构建者)。UI → designer。代码 → implementer。大量机械性工作 → tasker。每个会修改代码的切片都要由另一个模型系列的 reviewer 审查;涉及身份验证/密钥/输入处理的切片还要由 security-reviewer 审查;涉及可见 UI 的切片还要由 inspector 检查。若切片涉及已知配置类型的薄弱环节,应改用另一名助手处理。薄弱环节列于 references/agent-profiles.md,例如在沙盒环境中的 codex 处理 UI 或 e2e,或小型模型处理不可信输入。

    • lanes=off 时: spawn <role> --name <new> --kind <kind>。
    • 启用 lanes 时: 一个 lane 对应一个 CLI;对另一个 CLI 的活动会话执行 spawn --kind 会以状态码 13 退出。先对该 lane 的所有活动工作者执行 release --close(如果该 lane 占用两个工作者,则关闭 build 和 build-2),然后执行 session set lane.<name>.kind <kind>(以及设置其模型),再 spawn。

    只有目标机器才会显示的行为(路径、shell、OS 服务)无法通过在本机改用另一种类型来修复。工作者会报告无法运行,相关运行会在目标机器上进行。

    保持 Fluxo paralelo 中的流水线完整。

  4. 为每个切片编写一份任务说明,使用 templates/brief.md:目标、负责的文件、禁止修改的文件、按路径列出的本地来源、适用的项目规则、工作者可运行的检查、报告格式。工作者的任务说明中不得包含提交、推送或 PR——git 由编排者负责。

  5. 启动并分派任务。 默认拓扑:在当前标签页中使用同级窗格、相同的 cwd,并指定 --no-focus。用户提出要求或两个编辑 Agent 共用同一 cwd 时,使用 worktree——spawn 会对此发出明确警告(为每个 Agent 指定 spawn --cwd <worktree>)。并行编辑 Agent 只运行针对单个文件的检查;完整测试套件只在集成时运行一次。

  6. 收集并集成。 阅读每份报告,然后查看 git diff。工作者报告“通过”不等于任务完成。收到 N 次交付后的固定顺序为:仓库格式化工具 → 类型检查 → 项目门禁 → 完整测试套件 → 对修改涉及的界面进行冒烟测试。

  7. 推送前审查。 针对集成后的 diff 分派 reviewer(相关时还要分派 security-reviewer)进行审查。自行或通过 implementer 修复 P0/P1 问题,然后重新审查变更部分。

  8. 报告并释放。 说明已验证的内容,切勿夸大(“在 <tests + smokes> 中未观察到回归”)。只有在报告文件存在后才释放你启动的 Agent(release --close 会在任务中途终止工作者);只关闭本技能创建的窗格,且仅当用户未要求保留时才关闭。

等待返回 blocked 或 question 时,检查 herdr agent read <name>(JSON 中的 question 已包含问题所在的屏幕),并在回答确认或问题对话框之前先询问用户。超时或 agent_prompt_stalled 并不能证明提示已丢失——先读取,不要盲目重发。

Brief 即契约

要让更简单、成本更低的工作者可靠,关键在于编排器给出的 Brief,无论采用何种布局、委派何种角色:明确的目标、预期结果、每项验收标准及其验证命令,以及已做出的决定,这样工作者就不必自行臆造名称、格式、规则或要求。如果工作者必须猜测,问题就在于编排器的规划失误。使用 templates/brief.md,并在每次派发前运行 references/orchestration-contract.md 中的检查清单——其中每一项都是真实存在、曾导致一轮审查的缺口:含糊的判定条件、没有语义说明的选项标签、缺失的不变量(文件模式、原子写入、中断、沙盒、Windows)、缺少输入验证、Brief 条目过多、迭代时未规定要运行哪些测试、写入内容过大、新文件夹中的首次运行对话框。工作者报告缺口时,应在下一份 Brief 中将其作为一项决定明确下来。

Lint 会说明每个缺失部分为何会给工作者造成问题。 dispatch 会对 Brief 结构运行 lint(brief_lint,默认值为 warn;只读角色无需 Owned files 部分)。警告会按章节顺序说明每个缺失部分的原因:brief <path> is missing sections: [Goal] [Expected result] — <reason>; <reason>(严格模式会附加 (brief_lint=strict) 并以状态码 2 退出)。原因如下:Goal——工作者不知道该代码片段的用途;Expected result——没有说明何时算完成;Owned files——没有指定所属文件的工作者会发生冲突;Forbidden——没有任何规定阻止工作者修改其他文件;Report——没有报告部分,工作者可能永远不会编写报告;禁止提交的说明——工作者可能会提交或推送。另有一项独立检查会同时在 warn 和 strict 模式下标记空的行内代码问题——每行最多显示三条警告,之后将其余警告合并为一条;只有 brief_lint=off 才会将其关闭:

brief <path> line <n> has empty inline code (``): a shell heredoc without
quotes may have run the backticks

brief_lint_aliases (逗号分隔的 Section=Heading|Heading 项)允许以某个章节标题开头(不区分大小写)的 1–3 级标题满足该章节要求:可配置别名的章节包括 Goal、Expected result、Owned files、Forbidden 和 Report(禁止提交的说明没有可配置别名的标题);格式错误的项会被忽略,并显示 brief_lint_aliases: ignored '<item>' (use Section=Heading|Heading),有效项仍会生效。

让规则落实

只有当提示词看起来像委派请求时,才会读取上述触发规则。“配置 X,看看仓库 A 和 B 是怎么做的”看起来不像委派请求,编排器会自行查看 A 和 B。每个项目运行一次:

$S setup                      # block in AGENTS.md (or a non-symlink CLAUDE.md) + Claude hooks
$S setup --target CLAUDE.md   # when CLAUDE.md is the canonical file
$S setup --no-hooks           # instruction block only

与 ai-memory 的路由片段类似,setup 会将委派规则写入项目规范说明文件中 / 标记之间,并将两个钩子合并到 .claude/settings.json:UserPromptSubmit(在 HERDR_ENV=1 时,每条提示词都会显示一行提醒)和 SessionStart(doctor 警告)。 该代码块仅包含工作流和 Brief 契约;窗格数量、使用哪些助手和模型仍由配置决定,因此该代码块不会与项目团队配置相矛盾。对于符号链接形式的说明文件或设置文件(AGENTS.md -> CLAUDE.md),写入会通过链接进行:链接本身仍是链接。钩子命令通过 sh 调用,因此只会在有 POSIX shell 的环境中运行(在 Windows 上通过 Git Bash 或 WSL 运行)。重新运行会替换代码块和钩子;如果重写失败,则绝不会触碰文件。生成的项目文件绝不会嵌入安装程序的绝对路径:SessionStart 钩子会优先使用项目的 .agents/skills/ 或 .claude/skills/ 副本,然后再检查用户主目录下的相同位置。找不到可用路径时,setup 会发出警告;缺少代码块或钩子时,doctor 和 init 会发出警告。使用 scripts/run-tests.sh --env outside test-setup.sh 验证设置变更。 Codex、Grok、Cursor 和 agy 没有提示词钩子;对它们而言,代码块就是防护措施。

设置:引导式配置

setup 会写入指令块。它不会猜测这台机器上安装了哪些 CLI。首次运行时,以及 doctor 报告存在缺失或旧版配置时(缺少 panes、空的 lane.<name>.kind 所对应的角色解析为不同类型、split_max_panes 大于 panes、某条通道已有自己的类型却又为其角色单独设置类型、role.planner.*、角色或通道模型因生效类型来自更高层且未设置模型而被丢弃、类型和模型组合无法在该类型的模型列表中解析),或者因配额而停止时(退出码 11),编排器会引导用户逐步完成选择。每一步都使用 运行框架的结构化提问工具(Claude Code:AskUserQuestion, Codex:ask_user_question,OpenCode:question),并提供三个选项——第一个标记为推荐选项,并附上一行理由——以及一个自由文本字段,供用户准确说明想要什么(使用工具的自由文本/“其他”字段;工具没有该字段时,提供第四个“自己说明”选项)。绝不提出没有建议的开放式问题,也绝不要求用户填写标志、键或模型 ID。项目文件未设置 multi_role、任何 lane.<name>.kind 或任何 role.<role>.kind 时,setup 还会发出警告;单独设置 max_workers(包括 doctor --fix 写入的值)不算作此类选择。

步骤按以下顺序进行,并使用用户的语言(绝不使用 lane、kind 或 panes 这些词):

  1. 征求同意(首次运行)。 在打开任何面板前,说明团队的组成 (首次运行时的语音),并询问是否打开。选项:是,打开 (推荐——这样可以并行处理工作)、先详细了解,再打开 否,不使用团队 + 自由文本。拒绝后会停止团队。
  2. 同时运行多少个 Agent。 选项:4 个面板(推荐——两个并行编写 代码,一个负责审查)、3 个面板(更省配额:一个编写,一个审查)、 2 个面板(最精简:一个编写,审查在此处进行)+ 自由文本。映射回答: 4 → setup --panes 4;3 → setup --panes 3;2 → setup --panes 2。 然后再问:需要时再增加一个面板? 选项:不,绝不超过这个数量 (推荐——默认设置,pane_mode=strict)、是,临时增加一个面板,用于 第二次审查或编写文档(pane_mode=flex)、稍后决定 + 自由文本。
  3. 每项工作由哪个助手负责。 运行 $S setup --detect(不会写入任何 内容),然后运行 $S setup --probe——针对每种类型/模型运行简短超时的 最小非交互提示词,不使用面板;状态为 ready | no-auth | quota | error,并提供 recommended_reviewer(来自与构建助手不同系列且状态为 ready 的类型)。只有探测状态为 ready 的助手才会成为选项,包括个人 提供商的模型(--detect 的 custom_models 条目,格式为 provider/model,并在有声明时注明最高推理级别)。汇总探测已测试每个 列出的自有模型(每种类型最多 5 个,source: "custom" 的行):仅当其 自身所在行状态为 ready 时才提供该模型。skipped_custom 中的模型尚未 测试:先运行 $S setup --probe --kind K --model provider/model,仅当该行 状态为 ready 时才提供。共有三个问题:
    • 编写代码(构建通道):如果用户文件中已指定用于构建的助手且其探测 状态为 ready,则推荐该助手;否则,推荐能力上限最高的 ready 助手。 提供商之间没有固定排名。
    • 审查:必须与构建助手属于不同的模型系列;使用 recommended_reviewer 作为推荐选项(codex 优先于 claude)。
    • 研究:推荐速度最快/成本最低的 ready 助手——如果探测结果列出了 fast/flash 模型,则使用该模型;否则,选择成本最低的 ready 系列。 在 ready 助手中,让 references/agent-profiles.md 决定推荐选项 并说明理由。该文件会说明各助手在实际使用中擅长哪些工作,以及哪些编写者 与审查者组合发现了实际问题。 每个选项都包含助手名称及其一行 summary(已翻译);推荐项还会附上一行 推荐理由。 在 pi 或 opencode 上使用自有提供商: 提供此类 provider/model 前,读取 --detect 中其 custom_models 条目的 warnings(与 doctor 报告的风险相同;绝不会打印任何值):使用字面密钥而非环境变量引用、 pi 的 maxTokens 未比当前使用的 effort 推理预算多出 8192 个 token、 opencode 模型没有数值型 thinking_token_budget。如果存在警告,则询问: 替我修复(推荐——先显示具体改动)、我会自行修复、照原样使用
  4. 将每项选择保存到哪里。 每项选择分别提问:仅限此项目(团队共享—— 项目文件)、作为我的个人默认设置(适用于我的所有项目——用户文件)、 仅限此会话(临时——会话层)+ 自由文本。个人提供商和模型默认保存到 用户层。
  5. 确认。 根据回答构建一条 setup --plan … 命令——为团队设置 --panes 和 --lane name=kind:model:effort,为配置键设置 --set key value/--user-set key value,为会话设置 --session-set key value——并显示其输出:每个将被修改文件的具体改动; 配置文件显示 key before → after,指令文件、 .claude/settings.json 和(写入时会添加的).gitignore 显示统一差异 (不会写入任何内容)。选项:写入(推荐 ——符合你的回答)、调整(用户说明要改什么;重新构建计划并再次显示)、 取消 + 自由文本。
  6. 写入。 setup --panes 2|3|4 --lane name=kind[:model[:effort]]…、 config set <key> <value> [--user]、session set <key> <value>——使用 计划中显示的相同键——然后运行 setup(指令块 + hooks)和 doctor; 处理所有仍有警告的项目。
答案的构建方式(机制)

setup --detect 会打印 JSON,且不会写入任何文件:对于每种已知类型,它都会输出 installed、family、effort_ceiling、简短的英文 summary(向用户展示时请翻译)、 CLI 有响应时返回最新的至多 3 个模型 ID(CLI 缺失或无响应时返回空列表,不视为失败),以及通用类型的 custom_models——用户在 ~/.pi/agent/models.json(pi)和 opencode.json(项目级和用户级)中声明的模型, 格式为 provider/model,并在存在时附带声明的最高推理等级。密钥仍保留在这些文件中:只读取 ID 和等级。 它还会打印 panes、lanes、生效的 lanes 以及 2、3、4 的预设(每条 lane 都包含其容量 panes)、 max_workers、multi_role、reuse_workers 的生效值及其来源、 每个 role.<role>.kind、每个 model.<kind>.worker,以及 recommended_reviewer(仅限已安装的类型;探测会进一步将其缩小为能响应实际提示词的类型)。

setup --probe [--kind K --model M] [--timeout SECONDS] 会针对每种类型/模型运行一个简短的 非交互式提示词(claude -p、codex exec、grok -p、agy/gemini -p、cursor-agent -p、pi -p --no-session、opencode run;--timeout 或 HERDR_AGENTS_PROBE_TIMEOUT 的值为 ≥ 1 的整数秒,默认值为 20),并分类为: ready、no-auth(登录消息)、quota(wait 会检测到的相同提供商消息)或 error(超时也属于错误)。 cause 不会复制 CLI 文本,而是使用固定类别: not installed、timeout after <N>s、not authenticated、quota exhausted(仅当续期行包含日期/时间时,才附加 ; renews <date/time>),或 exit <code>。 它不会打开窗格,不需要 Herdr,也绝不会打印 CLI 输出——只打印分类和原因。未指定 --kind 时,它会使用 spawn 将采用的模型探测每种已知类型 (先取 model.<kind>.worker,再取 model.<kind>,否则使用 CLI 默认值;各行包含 source: "configured"), 并探测 --detect 返回的已安装 pi/opencode 各自至多 5 个自定义模型 (source: "custom",按 detect 顺序);其余模型列表会作为 skipped_custom({kind, id})报告,每个都可通过 --kind K --model provider/model 单独探测。

setup --plan(与 setup/config set/session set 使用相同参数,通过 --panes、--lane、--set、--user-set、--session-set 传入)会在各自的临时目录中模拟每项写入,并打印指令文件 (AGENTS.md/CLAUDE.md)、.claude/settings.json 的 diff -u(a/<path> 和 b/<path>), 以及——在写入会添加内容时——仓库的 .gitignore(setup 和 session set 会刷新其中的 .herdr-agents/ 条目);配置文件(.agents/herdr-agents.conf、用户文件、session.conf)则会保留 key before → after 格式的行。它不会写入任何内容——甚至不会创建状态目录。 请在确认步骤中使用它;每当用户询问“这会有什么变化?”时也应使用它。 doctor --fix --panes 2|3|4 [--user|--session] 会对旧版文件执行相同的规范化 (--session 针对工作区的 session.conf,在无法解析 Herdr 工作区时 以状态码 2 退出)。如果文件中的通道属于预设(无预设、新预设,或旧版 build/explore/review 和 build/read),则不会保留通道角色、 max_workers 或 split_max_panes:预设会在运行时解析。你在预设包含的 通道上设置的容量(lane.build.panes=3)会保留。 如果新预设包含 review 通道,且尚未设置相应键,lane.read.* 会移至 lane.review.*;lane.explore.* 以及预设不包含的通道的键会被移除,并为每项 说明原因。包含自定义通道的文件会保留这些通道,并将 max_workers 设为其 容量总和,将 split_max_panes 设为 panes;在 flex 模式下,两者均加上 flex_extra,以确保临时 worker 也能容纳。两种情况都会设置 panes 和 reuse_workers=on。doctor 本身会对旧版预设以及已不存在通道的键发出警告。对于每个通道,它会 解析每个角色的种类和模型(取该文件中的值,否则取角色 frontmatter 中的值)。 如果它们一致,就会写入 lane.<name>.kind / .model,然后才移除这些 role.<role>.* 键。如果它们不一致,则保留这些键,列出 role=kind,并提示你询问后运行 setup --lane <name>=<kind>[:<model>[:<effort>]]。无论哪种情况,都会移除 role.planner.*。注释会保留。它会以 diff -u 格式打印更新后的文件,并使用 a/<file> 和 b/<file> 标签(如果没有变更,则显示 no changes in <file>), 与 setup --plan 类似。如果没有 --panes,且文件中也没有 panes,--fix 会以状态码 2 退出,并提示你选择 2、3 或 4——它不会自行选择。在这种情况下,请执行上文第 2–5 步 (先回答面板数量问题,再查看计划并确认),最后运行 doctor --fix。

multi_role=on(默认值,包括未设置该键时):不带 --fresh 的 spawn 会复用其他角色的空闲 worker,前提是种类、工作目录和解析后的模型相同, 该 worker 的 approvals 不低于请求的级别(ask < edits < full),并且它启动时使用的原生参数 (名册第 14 列)与本次 spawn 将传入的参数相同(原生参数在整个进程期间保持不变)。会优先尝试 相同角色。曾承担编辑角色——implementer、designer、 tasker 或任何带有 mode: edit 的角色——的 worker,绝不会被复用为 reviewer、security-reviewer、ui-reviewer 或 inspector。随后 spawn 会启动新的 worker,并受 max_workers 限制。multi_role=off 时,只会复用相同 角色的 worker。

名册文件会在原有八列之后新增列。旧行仍然有效,并且仅在 lanes=off 时 才会为相同角色复用。这些列包括 model、approvals、roles(以逗号分隔的历史记录,例如 scouter,implementer)、lane、burst(flex 模式下的临时 worker)和 args(启动时使用的已配置原生参数: args.<kind> 加上 lane.<name>.args 或 role.<role>.args)。第 4 列 仍为当前角色。 启用 lanes 时,复用仅限于同一通道。lanes=off 时,跨角色复用会就地改写该行,并追加新角色。复用后的 spawn JSON 会包含 previous_role。dispatch 会读取第 4 列,因此组合后的提示词采用新角色。roster 会打印当前角色,并在列宽足够时显示 历史记录。

项目根目录

简报和报告是状态目录下的临时产物,绝不会放在仓库中。如果工作属于规划计划 (planning/<initiative>/ 或项目中与之对应的目录),请将每个切片的最终报告复制到它所实现的 故事旁边;概览中的状态行不能替代该报告。为切片创建的 worktree 位于仓库的 .worktrees/ 下,并会在发布时列出,而不会删除。

提示词

在以下情况下使用 harness 的结构化提问工具:

  • wait、status 或 dispatch 返回 quota(退出代码 11)。JSON 中包含 lane、kind、model、经过清理的 match,以及屏幕上显示时的 renewal。问题格式与设置阶段相同:三个选项 + 自由文本。 切换助手(当另一位助手的探测状态为 ready 时推荐——优先选择 recommended_reviewer;请说明选择了哪一位)、等待续期(当 JSON 中列出时间时)、 在本次会话中完成这部分工作(在自由文本中说明暂停)。当工作在新的工作进程上恢复时, 请在简述中附上部分修改的 git diff,以便继续工作,而不是从头开始。
  • wait、status 或 dispatch 返回 provider-error 或 capacity (退出代码 14)。工作进程处于空闲状态且没有报告;JSON 中包含 lane、 kind、model 和 cause 行(capacity 时还包含 retries)。选项: 将简述重新发送给同一工作进程(当提供方再次响应时推荐——进行简短探测,或原因是超时)、 切换助手(说明选择了哪位就绪的助手)、等待 + 自由文本。切勿盲目重发: 请先阅读面板内容。
  • 目标可能与 UI 有关,也可能无关,答案会影响要启动哪些角色。
  • 审查者将与实施者来自同一系列,且没有安装其他类型的审查者(选项:接受、替换类型、跳过审查)。
  • 释放资源会关闭存在未读输出的面板,或包含未提交更改的工作树。
  • feedback=ask 且你有改进问题要提交时(显示标题和场景摘要;选项:提交、跳过、编辑)。

当 $ARGUMENTS 为空时,请以自由形式询问目标。在不停顿模式下,将这些问题记录为最终报告中的待解决问题,并按推荐选项继续。

改进此技能(遇到阻碍时提交 issue)

编排器最先发现此技能何时造成阻碍:类型映射错误、等待结果有误、缺少所需命令,或角色提示词导致工作器行为异常。将这些问题提交为此技能仓库中的 issue,让维护者逐步改进。

  • **何时:**任何由技能本身造成的阻碍(而非项目或工作器的任务造成的阻碍)。$S friction 会列出此工作区中脚本产生的所有错误和警告;请在运行结束时检查。每个不同的问题提交一个 issue;先运行 gh issue list --repo <feedback_repo> --search "<keywords>" --label herdr-agents 检查是否有重复项。日志的每一行都保留四列(日期、级别、命令、消息;消息中的换行符会被清理),而 friction add "<text>" [--brief <path>] 会记录工具本身不会记录的阻碍(级别为 note,命令为 friction;--brief 会追加 (brief: <path>))。

  • 策略由 feedback 配置键控制:

    • ask(默认):告知用户你准备提交的内容,只有获得同意后才提交;
    • on:直接提交,并在最终消息中提及;
    • off:绝不提交,只在最终消息中描述遇到的阻碍;
    • local:此技能的维护者正在这台机器上工作。将报告发送给该维护者,而不是提交 issue(见下文)。
  • **操作方法:**填写 templates/issue.md(场景、实际情况及准确的错误文本或 JSON 行、预期情况、$S env 和 $S config 的输出、证据路径,以及可选的建议修改),然后:

    gh issue create --repo "$("$S" config | awk '$1=="feedback_repo"{print $2}')" \
      --title "herdr-agents: <one line>" --label herdr-agents --body-file /tmp/herdr-agents-issue.md
    

    从证据中删去机密信息和客户数据。绝不要粘贴来自私有仓库的完整报告;只引用能说明问题的行。

  • **使用 feedback=local 时:**将相同模板写入文件,然后:

    $S feedback send /tmp/herdr-agents-friction.md "<one-line summary>"
    
    • 报告会保存为 <feedback_dir>/from-<project>-<date>.md;若当天已有报告,则使用 -b、-c 等后缀;绝不会覆盖现有文件。feedback_dir 必须是指向现有目录的绝对路径(否则 doctor 会发出警告)。
    • feedback_to 中指定的窗格或 Agent 会收到一行摘要和路径。
    • 未设置 feedback_to 时,只会写入文件。
    • 操作会打印一行 JSON。退出码为 4 表示文件已保存,但通知发送失败:请自行告知维护者。
    • 不要修改此技能、其已安装副本或其他项目的角色或配置来绕过阻碍。维护者会回复,并告知你何时需要修改项目配置。

测试此技能

移植后的命令带有 JS 测试,可在任一运行时下运行:

node --test scripts/test/    # JS tests (Node 20+)
bun test scripts/test/       # the same tests under Bun

回归测试矩阵包含 scripts/test-*.sh 中的所有套件——这些 bash 套件通过 POSIX scripts/herdr-agents 启动器测试 JS;每个套件都要分别在 Herdr 内部(设置 HERDR_ENV=1,并使用测试窗格/工作区)和外部运行。请使用并行隔离执行器运行,绝不要手动编写循环:

scripts/run-tests.sh                              # every suite × inside+outside, parallel
scripts/run-tests.sh --env outside test-kinds.sh  # one suite while iterating
scripts/run-tests.sh --bash /bin/bash             # also run the matrix on that interpreter
scripts/run-tests.sh --jobs 4                     # cap the parallel jobs

旧版 bash↔JS 一致性测试使用 scripts/test/golden/ 下的基准文件(移植前记录的 bash 行为):有意更改行为时,使用 HERDR_AGENTS_GOLDEN=update 重新记录,然后检查差异。

每次运行都会在临时目录中使用各自独立的 HOME、XDG_CONFIG_HOME 和 TMPDIR,并清除父环境中的所有 HERDR_AGENTS_* 变量,因此不会有套件读取 ~/.config/herdr-agents、~/.pi 或 ~/.config/opencode。除非设置了 HERDR_AGENTS_KEEP_TEST_LOGS=1,否则退出时会删除临时目录(即使失败也会删除)。输出中每次运行占一行,格式为 PASS|FAIL <suite> [<env>, <bash>] <seconds>s,后接摘要;失败时会打印每次失败运行日志的最后 30 行。退出码:0 表示全部通过,1 表示有任一项失败,2 表示用法无效。

简报测试规则:迭代期间,工作器只运行覆盖相应项目的套件(scripts/run-tests.sh --env outside test-<x>.sh);完整矩阵(scripts/run-tests.sh)只在提交报告前运行一次。

安全

  • 绝不执行 herdr server stop;绝不关闭此技能未创建的窗格、标签页或工作区。
  • 优先使用 --current、明确指定窗格 ID 和唯一的 Agent 名称。从 JSON 中解析 ID,绝不根据侧边栏顺序判断。
  • 简报和报告可能包含仓库内容;不要在其中放入机密信息。

参考资料

评论

支持 Markdown