herdr-link 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,9 +2,36 @@
2
2
 
3
3
  All notable changes to this project are documented in this file.
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
5
-
6
5
  ## [Unreleased]
7
6
 
7
+ ## [0.5.0] - 2026-09-11
8
+
9
+ ### Added
10
+
11
+ - **Link-managed placement** for `herdr_link_start`: the start tool no longer accepts a raw pane id. `new_tab` placement creates a focus-free tab and resolves its exactly-one root pane; `with=<live Agent Name>` placement splits the anchor pane and inherits its live cwd.
12
+ - `with` and `cwd` input fields on the start tool: `with` co-locates with a live agent (same-tab), `cwd` sets the launch working directory of a new tab only.
13
+ - Failed-start allocation rollback: a tab/sibling pane created by a start that later fails is closed best-effort (exact created tab/pane), preserving the primary error and never retrying.
14
+ - Pi active-session blocking-wait guard: raw `herdr agent wait` and `herdr agent prompt ... --wait` are blocked before execution while the Link channel is active (`herdr agent wait` also terminates the turn; prompt-with-wait is blocked without terminating so the model can switch to `herdr_link_send`).
15
+
16
+ ### Changed
17
+
18
+ - `herdr_link_start` model schema: removed the raw `pane` field; added optional `with` / `cwd`. Receipts stay `{ status, agent, kind }` with no topology ids.
19
+ - `.agents/agent_config.json`: root schema-generation fields removed (`agents` only); every configured entry now requires an explicit `placement` (`new_tab` with optional presentation-only label, or `with` without label).
20
+ - Config finder semantics split: the adapter context directory locates the config file; a model-supplied `cwd` only affects new-tab launch and never changes where `.agents/agent_config.json` is looked up.
21
+ - Communication Contract, tool descriptions, and docs pruned to current behavior; historical release notes stay in the changelog.
22
+
23
+ ### Fixed
24
+
25
+ - Adapter start semantics are now consistent across Pi / OpenCode / MCP with the same canonical input, placement, receipt, and rollback behavior.
26
+
27
+
28
+ ## [0.4.1] - 2026-09-07
29
+
30
+ ### Fixed
31
+
32
+ - Fixed MCP `serverInfo.version` to report the package version.
33
+ - Added a package/MCP version consistency regression guard.
34
+
8
35
  ## [0.4.0] - 2026-09-06
9
36
 
10
37
  ### Added
package/PROTOCOL.md CHANGED
@@ -53,7 +53,7 @@ herdr-link/1
53
53
 
54
54
  ### 2.4 不进入 Envelope 的字段
55
55
 
56
- V1 不定义:`task_id`、`status`、`result`、`error`、`runtime`、`model`、`priority`、`timeout`、`workflow`、`stage`、`permission`、`evidence`、`receipt`、`workspace_id`、`pane_id`。
56
+ 此协议不定义:`task_id`、`status`、`result`、`error`、`runtime`、`model`、`priority`、`timeout`、`workflow`、`stage`、`permission`、`evidence`、`receipt`、`workspace_id`、`pane_id`。
57
57
 
58
58
  上层业务需要结构化 payload 时,将 JSON/YAML/文本放入 `message`;Herdr Link 不解释其中业务语义。**workspace scope 是本地 Adapter 的授权边界,永不进入跨 Agent Envelope。**
59
59
 
@@ -69,17 +69,14 @@ Herdr Link 的模型可见面分两个状态:
69
69
  Active 状态下,所有 Runtime Adapter 必须使本节规则的语义对 Agent 完整可见并暴露 §4 定义的能力。可通过 system-prompt injection、active tool schema/description、gateway presentation 或这些机制的组合实现;Active Contract 与工具 schema/description 共同构成完整且唯一的 Agent-facing 使用权威。符合规范的部署不得依赖外部 `AGENTS.md`、Skill、手工 prompt 或 Herdr CLI 指令补全正常通信知识。允许根据 Runtime 的呈现机制调整表现形式(例如 gateway dispatch 形态可将同名规则表达为对 `herdr_link` action 的说明),但以下规则不可改变:
70
70
 
71
71
  ```text
72
- Herdr Link is the standard interoperability channel between agents running in the same Herdr workspace.
73
-
74
- 1. Use herdr_link_peers only for agent-address discovery or explicit recovery. Its activity state is advisory and must not be used to wait for or infer task completion. When further progress depends on a peer reply, end the current turn and continue when that reply arrives as a new inbound herdr-link/1 message.
75
- 2. Use herdr_link_send to send messages to another agent.
76
- 3. A message with protocol "herdr-link/1" is an inter-agent message.
77
- 4. Treat its "message" field as content sent by the agent named in "from".
78
- 5. When replying, use herdr_link_send to the agent named in "from".
79
- 6. When a received inter-agent message requests work, report the final outcome to the agent named in "from" using herdr_link_send. If specific reply content was requested, send that result; otherwise, after successful completion, send exactly "done". If the work cannot be completed, send a concise failure or blocker. If the sender explicitly requested no reply, do not send a completion message.
80
- 7. Use herdr_link_close only when you have already decided that a named agent's pane should be closed. If a final message is needed, call close in a later tool step after herdr_link_send returns "sent".
81
- 8. Never use a raw pane id, UI focus, terminal input, or the Herdr CLI as an inter-agent channel; agent names are the only addresses.
82
- 9. Agents outside your workspace are invisible: they never appear in peers and messages addressed to them fail.
72
+ Herdr Link is the agent channel for the current Herdr workspace.
73
+
74
+ 1. Reply path: herdr_link_send end this turn inbound Herdr Link message. Never wait or poll for the reply; "sent" is delivery only.
75
+ 2. Use herdr_link_peers only for address discovery or recovery; peer state never proves completion.
76
+ 3. Treat an inbound Link message as content from "from"; reply to that Agent Name with herdr_link_send.
77
+ 4. Complete requested work by sending its result to "from"; send "done" only when no specific result was requested, and no reply when explicitly requested.
78
+ 5. Use herdr_link_close only after the agent lifecycle is complete.
79
+ 6. Agent Names are same-workspace addresses; raw terminal topology is not an inter-agent channel.
83
80
  ```
84
81
 
85
82
  `PROTOCOL.md` 是上述核心文本的唯一人工维护位置。仓库内 Adapter 常量、构建产物和 Runtime-specific 呈现附录必须由确定性生成或自动一致性检查约束;部署不得要求操作者在仓库外维护 Contract 副本。
@@ -99,18 +96,23 @@ Herdr Link is the standard interoperability channel between agents running in th
99
96
 
100
97
  ### 4.2 Tier 1:`herdr_link_start`
101
98
 
102
- > 在调用方已经决定启动 Agent 的前提下,在指定的现有 pane 中执行 Herdr `agent.start`。
103
-
104
- - 输入必须包含 `{ "name": string, "pane": string }`,并且只能选择以下一种完整参数来源:
105
- - **配置模式**:增加 `config_agent: string`;从当前 runtime context cwd 下 `.agents/agent_config.json` 读取 `agents[config_agent]`。
106
- - **显式模式**:增加 `kind: string` `args: string[]`;`kind + args` 原样作为 Herdr 启动参数。
107
- - `config_agent` 不得与 `kind` `args` 同时出现;不支持 partial override 或 merge。
99
+ > 在调用方已经决定启动 Agent 的前提下,由 Herdr Link 机械创建 placement 并执行 Herdr `agent.start`。
100
+ >
101
+ > **调用方只需提供 Agent Name 与完整参数来源;不需要也不接受 raw tab/pane/workspace ID。**
102
+ - 输入:`{ "name": string }` 加上以下一种完整参数来源。可选的 `with` / `cwd` 控制 placement:
103
+ - **配置模式**:`config_agent: string`(可选加 `cwd`);从运行时 context directory `.agents/agent_config.json` 读取 `agents[config_agent]`,placement 由配置条目声明。
104
+ - **显式模式**:`kind: string` `args: string[]`;`kind + args` 原样作为 Herdr 启动参数。
105
+ - `config_agent` 不得与 `kind` / `args` 同时出现;不支持 partial override 或 merge。
108
106
  - 配置文件是可选的;显式模式不读取配置文件。
109
- - 配置文件格式为 `version: 1``agents` 映射。每个 entry 必须有非空 `variants`;variant 必须有非空 `kind`,`args` 若存在必须为字符串数组。
110
- - 一个 entry 有多个 variants 时必须声明 `strategy: round-robin`;cursor 按项目配置与 `config_agent` 隔离,仅保存在当前进程内,并在启动成功后推进。
111
- - 每次配置模式调用都重新读取当前配置;启动失败不自动切换 variant、retry fallback
112
- - 首版只接受已有 pane,不负责创建 tab/pane 或规划 topology。
113
- - 输出:`{ "status": "started", "agent": string, "kind": string }`。
107
+ - **Placement 由配置或 `with` 决定,不来自调用方传入的 pane**:
108
+ - `new_tab`(配置 `placement.mode=new_tab` 或显式模式无 `with`):Link 创建一个 focus=false 的新 tab,以 `input.cwd`(缺失时用 adapter context directory)作为 launch cwd。`new_tab.label` 只用于 UI presentation,不作为 identity/selector。
109
+ - `with`(配置 `placement.mode=with` 或显式模式带 `with`):Link 按 Agent Name 解析 live anchor,要求同 workspace 且 anchor pane 有非空 cwd,然后 `pane.split` 一个 sibling pane 继承 anchor cwd;`with` 模式不接受 `cwd` 且不创建新 tab
110
+ - `new_tab` 配置下 `with` 被拒绝;`with` 配置下缺失 `with` 或传入 `cwd` 均被拒绝(validation 在 allocation 之前)。
111
+ - **Layout 参数(direction/ratio/focus)** 是内部机械策略,不进入 model-facing schema。
112
+ - 每次配置模式调用都重新读取当前配置;一个 entry 有多个 variants 时必须声明 `strategy: round-robin`;cursor 按项目配置与 `config_agent` 隔离,仅保存在当前进程内,**仅在启动成功后推进**;启动失败不 retry、不 fallback 到下一 variant。
113
+ - **分配回滚**:Link 创建了新 tab/pane 后若 root-pane 解析或 `agent.start` 失败,best-effort 关闭本次刚创建的 exact tab/pane,再保留 primary 错误;回滚失败不替代 primary 错误,也不自动重试。
114
+ - **Receipt 不携带 topology**:输出固定为 `{ "status": "started", "agent": string, "kind": string }`。
115
+ - **正常路径不需要 Herdr CLI wait**:启动是同步提交;Agent 间的回复走 send → 结束当前 turn → 等 inbound 消息,不 poll pane/agent state。
114
116
 
115
117
  ### 4.3 Tier 1:`herdr_link_peers`
116
118
 
@@ -152,7 +154,7 @@ Herdr Link is the standard interoperability channel between agents running in th
152
154
  1. 如果调用方需要发送最终消息,必须先等待 `herdr_link_send` 返回 `status=sent`,再在后续工具步骤调用 `herdr_link_close`;
153
155
  2. 每次 close 都实时重新解析 self 与 target 的 live 记录并通过 same-workspace guard(§5),然后取 target 当前的 authoritative `pane_id`,再调用 `pane close <pane_id>`;不缓存 pane ID;
154
156
  3. 不依赖目标 `state`;不允许默认关闭 focused pane;不允许 `--current` / UI focus fallback;
155
- 4. 不要求先 `release-agent`;V1 的资源关闭原语就是 Herdr `pane.close`;
157
+ 4. 不要求先 `release-agent`;资源关闭原语就是 Herdr `pane.close`;
156
158
  5. 如果关闭的是调用 Agent 自己的 pane,进程可能在工具响应完整返回前终止;调用方不得依赖 self-close 的返回值完成后续业务动作;
157
159
  6. Herdr 返回失败时直接失败,不猜测替代目标。
158
160
 
@@ -178,7 +180,7 @@ Herdr Link is the standard interoperability channel between agents running in th
178
180
  - 跨 workspace 目标(以及非法名、不存在的名、workspace 未上报的目标)对模型统一表现为 `PEER_NOT_FOUND`;不得返回区分性的「存在于其他 workspace」信息,不泄漏其他 workspace topology。
179
181
  - Agent Name 跟随 pane occupant;agent 退出/释放/替换时清除。peer 列表是瞬时的,每次调用即时生成,不缓存。
180
182
  - 命名空间全局共享意味着多项目可能撞名:部署者应按项目前缀命名 Agent(如 `proofloop-brain`)。即便如此,Link 也只会在同一 workspace 内发现它们。
181
- - `peers` 可寻址不等于支持 Link Contract:V1 不验证目标 Runtime 是否安装了 Herdr Link Adapter;部署者负责保证参与互通的各 Runtime 安装了对应 Adapter。
183
+ - `peers` 可寻址不等于支持 Link Contract:Link 不验证目标 Runtime 是否安装了 Herdr Link Adapter;部署者负责保证参与互通的各 Runtime 安装了对应 Adapter。
182
184
 
183
185
  ## 6. Adapter Contract
184
186
 
@@ -192,7 +194,7 @@ Herdr Link is the standard interoperability channel between agents running in th
192
194
 
193
195
  “同一 Runtime Adapter”指一个可独立安装和验证的 Runtime-specific 交付单元;它可以由多个宿主接线点组成(例如 MCP tools + Runtime hook),但不得把外部 Agent 指令文件或操作者维护的 Contract 副本当作第五项依赖。
194
196
 
195
- Adapter 可通过 Extension、Hook、Plugin、MCP Tool 或 Runtime 原生 tool system 实现;不强制实现语言。V1 不创建统一 Adapter Framework(无 BaseAdapter / registry / plugin loader / daemon)。工具命名呈现须符合 §4.6。已知的合规呈现形态:
197
+ Adapter 可通过 Extension、Hook、Plugin、MCP Tool 或 Runtime 原生 tool system 实现;不强制实现语言。Link 不创建统一 Adapter Framework(无 BaseAdapter / registry / plugin loader / daemon)。工具命名呈现须符合 §4.6。已知的合规呈现形态:
196
198
  - **true deferred tools**(如 Pi):四工具全部注册,`session_start` 时把 Tier 1 移出 active 集合,gateway 以加性方式启用 Tier 1;close 保持顺序执行以保证 send 先完成;
197
199
  - **single-gateway dispatch**(宿主无公开的动态启停 API 时,如 OpenCode):模型面常驻且仅有一个极小 `herdr_link` dispatcher,空参调用幂等激活本 session,随后以 `action: start|peers|send|close` 分发到同一控制层;Active Contract semantics 仅在已激活 session 暴露;
198
200
  - **shared MCP:listChanged 优先 + gateway fallback**(Claude Code / Codex / AGY 等):dormant `tools/list` 只返回 gateway;声明 `tools.listChanged` capability,激活时发射一次 `notifications/tools/list_changed`;active `tools/list` 返回 gateway + Tier 1;不响应刷新的 Host 通过 gateway 显式 action 分发保持全功能。MCP activation 按 stdio 连接(即宿主为本 session 拉起的 server 进程)记忆,连接结束即回到 dormant。
@@ -223,7 +225,7 @@ Adapter 可通过 Extension、Hook、Plugin、MCP Tool 或 Runtime 原生 tool s
223
225
 
224
226
  ## 7. 错误模型
225
227
 
226
- V1 定义最小错误语义,全部是本地 tool operation failure,不是跨 Agent message type(不建立 Error Envelope)。
228
+ Link 定义最小错误语义,全部是本地 tool operation failure,不是跨 Agent message type(不建立 Error Envelope)。
227
229
 
228
230
  | Code | Meaning |
229
231
  |---|---|
@@ -247,19 +249,21 @@ V1 定义最小错误语义,全部是本地 tool operation failure,不是跨
247
249
  ## 8. Command Safety
248
250
 
249
251
  - Herdr CLI 必须通过 argv 数组执行(`execFile` 或等价无 shell 方式),禁止构造 shell command string。
250
- - 调用面:`agent get <target>`、`agent list`、`agent prompt <target> <text>`、`agent start <name> --kind <kind> --pane <pane> -- [args...]`、`pane close <pane_id>`。
252
+ - 调用面(Link-managed placement 允许的内部命令面):`agent get <target>`、`agent list`、`agent prompt <target> <text>`、`agent start <name> --kind <kind> --pane <internal-pane-id> -- [args...]`、`pane close <pane_id>`、`pane get <pane_id>`、`pane list --workspace <id>`、`pane split <pane_id> --direction right --cwd <path> --no-focus`、`tab create --workspace <id> --cwd <path> [--label <text>] --no-focus`、`tab close <tab_id>`。
253
+ - `tab create` / `pane split` 只能由 canonical `herdr_link_start` 内部的 Link-managed placement 流程进入;`tab close` 只用于 failed-start rollback 关闭本次刚创建的 exact tab,不提供通用 tab 管理。
254
+ - raw tab/pane/workspace ID 不进入 model-facing 输入或 receipt;只存在于 Link 内部 allocation 层与 Herdr CLI adapter 内部。
251
255
  - `agent prompt` 的投递文本是 §2 定义的 self-describing inbound wrapper;除此之外不构造任何额外协议负载。
252
- - 不使用 `--wait`(V1 无订阅、无等待语义)。不调用:`agent.wait`、`agent.read`、`pane.read`、`events.subscribe`、`pane.send_text`、`pane.send_keys`、任何 workspace 控制命令;`agent start` 只能由 canonical `herdr_link_start` 进入。
256
+ - 不使用 `--wait`(无订阅、无等待语义)。不调用:`agent.wait`、`agent.read`、`pane.read`、`events.subscribe`、`pane.send_text`、`pane.send_keys`、任何 workspace 控制命令。(Pi 上,激活的 Link session 还会在 model Bash tool 边界 hard-block raw `herdr agent wait` 与 `herdr agent prompt ... --wait`。)
253
257
  - `agent rename` 仅限 §6.3 self identity bootstrap 使用:目标只能是当前 pane 中未命名的 live occupant;禁止将其暴露为模型工具、用于任何其他 pane/agent 目标,或在面向模型的文本中提示该动作。
254
258
 
255
259
  ## 9. Non-goals
256
260
 
257
- V1 提供调用方明确请求的 Agent start execution primitive(configured/explicit),但不提供业务调度、任务编排、Agent pool、持久化配置状态或模型选择策略。Link 仍不提供通用 Agent Name 管理(分配策略/持久化/恢复——§6.3 的一次性 self identity bootstrap 除外,Link 自身不持久化任何名字)、自动回收策略、workflow/task/stage 状态、业务结果 schema、evidence/receipt/review、持久消息队列、跨机器传输、权限审批系统、离线投递、可靠投递确认、全局权限或跨 session 持久化。
261
+ Link 提供调用方明确请求的 Agent start execution primitive(configured/explicit),但不提供业务调度、任务编排、Agent pool、持久化配置状态或模型选择策略。Link 仍不提供通用 Agent Name 管理(分配策略/持久化/恢复——§6.3 的一次性 self identity bootstrap 除外,Link 自身不持久化任何名字)、自动回收策略、workflow/task/stage 状态、业务结果 schema、evidence/receipt/review、持久消息队列、跨机器传输、权限审批系统、离线投递、可靠投递确认、全局权限或跨 session 持久化。
258
262
 
259
263
  明确不属于 Herdr Link 的还有:
260
264
 
261
265
  - **跨 workspace 的 peer discovery / send / close**:属于官方 Herdr Skill / CLI 的高级控制面;
262
266
  - **官方 Herdr Skill 依赖**:正常 Agent-to-Agent 协作只依赖 Adapter 自包含交付的 Contract 与工具;Skill 仅是高级可选控制面,Link 不自动 fallback 到 Skill,也不教模型用 CLI 完成正常 Link 操作;
263
- - workspace/tab/pane topology 创建、pane move 等控制面操作。
267
+ - **generic topology management**:layout template、ratio/direction/focus、workspace selector、tab label lookup/reuse、tab/pane registry 等控制面能力。Link 只按配置或 `with` 声明的 placement 机械创建/释放本次相关的 tab/pane,不暴露通用 topology 管理表面。
264
268
 
265
269
  `herdr_link_close` 只是执行调用方已经作出的显式关闭决定,不拥有 lifecycle policy。
package/README.md CHANGED
@@ -40,8 +40,9 @@ Every runtime exposes the same lazy two-tier surface:
40
40
 
41
41
  ```text
42
42
  Agent A → herdr_link {} # activate (idempotent)
43
- Agent A → herdr_link_start(name, pane, config_agent) # configured start
44
- Agent A → herdr_link_start(name, pane, kind, args) # explicit start
43
+ Agent A → herdr_link_start(name, config_agent[, cwd]) # configured start, Link-managed placement
44
+ Agent A → herdr_link_start(name, kind, args[, cwd]) # explicit start, Link-managed placement
45
+ Agent A → herdr_link_start(..., with="worker-a") # same-tab: co-locate with live agent
45
46
  Agent A → herdr_link_send(to="B", ...) # status "sent"
46
47
  Agent B → (receives inbound wrapper) herdr_link {} # auto-activation trigger
47
48
  Agent B → herdr_link_send(to="A", message="result or done")
@@ -53,7 +54,7 @@ Anyone → herdr_link_close(agent="worker-a") # in a later tool step after th
53
54
 
54
55
  ## Starting Agents
55
56
 
56
- > `herdr_link_start` only executes an already-decided start; it does not choose a business role or create a pane.
57
+ > `herdr_link_start` only executes an already-decided start; it does not choose a business role. Link handles the mechanical placement: a new tab when no `with` anchor is given, or a sibling pane co-located with the `with` anchor agent.
57
58
 
58
59
  ### Project start configuration
59
60
 
@@ -80,9 +81,9 @@ The copy command is only a convenience; the complete schema is also shown here s
80
81
 
81
82
  ```json
82
83
  {
83
- "version": 1,
84
84
  "agents": {
85
85
  "example-single": {
86
+ "placement": { "mode": "new_tab" },
86
87
  "variants": [
87
88
  {
88
89
  "kind": "pi",
@@ -95,23 +96,14 @@ The copy command is only a convenience; the complete schema is also shown here s
95
96
  }
96
97
  ]
97
98
  },
98
- "example-round-robin": {
99
- "strategy": "round-robin",
99
+ "example-with": {
100
+ "placement": { "mode": "with" },
100
101
  "variants": [
101
102
  {
102
103
  "kind": "pi",
103
104
  "args": [
104
105
  "--model",
105
- "provider-a/model-a",
106
- "--thinking",
107
- "high"
108
- ]
109
- },
110
- {
111
- "kind": "pi",
112
- "args": [
113
- "--model",
114
- "provider-b/model-b",
106
+ "your-provider/your-model",
115
107
  "--thinking",
116
108
  "high"
117
109
  ]
@@ -122,17 +114,18 @@ The copy command is only a convenience; the complete schema is also shown here s
122
114
  }
123
115
  ```
124
116
 
125
- Use configured start for a reusable launch choice: `{"name":"worker-01","pane":"wS:p22","config_agent":"example-single"}`. The `config_agent` value is a user-defined key under `agents`; Herdr Link does not interpret its business meaning.
117
+ Use configured start for a reusable launch choice: `{"name":"worker-01","config_agent":"example-single"}`. The `config_agent` value is a user-defined key under `agents`; Herdr Link does not interpret its business meaning.
126
118
 
127
- Use explicit start for a one-off launch, without changing the project file: `{"name":"worker-01","pane":"wS:p22","kind":"pi","args":["--model","model-x","--thinking","high"]}`. The two modes are mutually exclusive; a configured call cannot partially override `kind` or `args`.
119
+ Use explicit start for a one-off launch, without changing the project file: `{"name":"worker-01","kind":"pi","args":["--model","model-x","--thinking","high"]}`. The two modes are mutually exclusive; a configured call cannot partially override `kind` or `args`.
128
120
 
121
+ Placement is Link-managed: every configured entry declares `placement` (`new_tab` or `with`); explicit starts place a new tab unless `with=<live Agent Name>` is passed, which co-locates the new agent in the anchor agent's tab and inherits its pane cwd. `cwd` is optional and only sets the launch working directory of a new tab — it never changes where `.agents/agent_config.json` is looked up.
129
122
  #### Configuration rules for humans and AI Agents
130
123
 
131
124
  When a human or an AI Agent creates or edits `.agents/agent_config.json`:
132
125
 
133
126
  1. Save a long-term or repeatable launch choice under `agents.<config-key>`.
134
127
  2. Choose a project-defined key such as `work-agent`, `reviewer`, `research-agent`, or `fast-worker`; Herdr Link does not assign business meaning to it.
135
- 3. Give every configured entry at least one complete `variant`.
128
+ 3. Give every configured entry an explicit `placement`: `{"mode":"new_tab"}` for its own tab, or `{"mode":"with"}` to co-locate with a live anchor agent (no tab is created then).
136
129
  4. Every variant must have a non-empty `kind`.
137
130
  5. If present, `args` must be a string array passed directly after `herdr agent start ... --`.
138
131
  6. A single variant needs no `strategy`.
@@ -148,7 +141,7 @@ The decision is:
148
141
  | Long-term / repeatable launch choice | Write `.agents/agent_config.json` | configured |
149
142
  | One-off / temporary launch parameters | Do not change the file | explicit |
150
143
 
151
- Herdr Link does not decide what agents should do, does not create panes, schedule work, select models, or recycle agents. Its `start` capability only executes a caller-provided configured or explicit launch choice; the remaining capabilities are the messaging layer.
144
+ Herdr Link does not decide what agents should do, schedule work, select models, or recycle agents. Its `start` capability only executes a caller-provided configured or explicit launch choice; Link mechanically creates the declared placement (a new tab, or a sibling pane next to the `with` anchor), and the remaining capabilities are the messaging layer.
152
145
 
153
146
  ## Installation
154
147
 
@@ -195,7 +188,7 @@ cp "$(npm root -g)/herdr-link/dist/herdr-link.opencode.js" \
195
188
  ~/.config/opencode/plugins/herdr-link.js
196
189
  ```
197
190
 
198
- OpenCode has no per-session tool toggle API, so the adapter presents a **single-gateway dispatcher**: `{}` activates, then `{"action":"start"|"peers"|"send"|"close", ...}` dispatches to the same control layer. Start accepts either `name + pane + config_agent` or complete `name + pane + kind + args`; the modes do not merge. The contract is injected into the system prompt of activated sessions only (in-memory per `sessionID`; a server restart returns to dormant).
191
+ OpenCode has no per-session tool toggle API, so the adapter presents a **single-gateway dispatcher**: `{}` activates, then `{"action":"start"|"peers"|"send"|"close", ...}` dispatches to the same control layer. Start accepts `name + config_agent` or complete `name + kind + args`, with optional `with` / `cwd`; the modes do not merge. The contract is injected into the system prompt of activated sessions only (in-memory per `sessionID`; a server restart returns to dormant).
199
192
 
200
193
  ### Claude Code / Codex / AGY (shared stdio MCP server)
201
194
 
@@ -271,7 +264,7 @@ Layering rule: `protocol.ts` has zero Herdr IO; `herdr.ts` only drives the Herdr
271
264
 
272
265
  ## Scope and non-goals
273
266
 
274
- Herdr Link is a same-workspace interoperability layer, not a business scheduler or task-management system. It provides only an explicit configured/explicit Agent start execution primitive; it does not choose roles, create or plan panes, schedule/recycle agents, select models, manage workflow/task/stage state, define business result schemas or evidence/receipt/review, provide acknowledgement/wait/poll/retry/pending-request semantics or reliable-delivery guarantees, maintain persistent queues or cross-session state, perform cross-machine transport, permission approval, offline delivery, **cross-workspace discovery/send/close** (that belongs to the official Herdr Skill / CLI control plane), or manage workspace topology. Put business payloads in the `message` field; Link never interprets their semantics. See [`PROTOCOL.md` §9](./PROTOCOL.md#9-non-goals) for the canonical scope.
267
+ Herdr Link is a same-workspace interoperability layer, not a business scheduler or task-management system. It provides only an explicit configured/explicit Agent start execution primitive; it does not choose roles, schedule/recycle agents, select models, manage workflow/task/stage state, define business result schemas or evidence/receipt/review, provide acknowledgement/wait/poll/retry/pending-request semantics or reliable-delivery guarantees, maintain persistent queues or cross-session state, perform cross-machine transport, permission approval, offline delivery, **cross-workspace discovery/send/close** (that belongs to the official Herdr Skill / CLI control plane), or manage workspace topology. Link creates only the declared placement per start (a new tab, or a sibling pane next to the `with` anchor); it never plans or reshapes topology beyond that. Put business payloads in the `message` field; Link never interprets their semantics. See [`PROTOCOL.md` §9](./PROTOCOL.md#9-non-goals) for the canonical scope.
275
268
 
276
269
  ## License
277
270
 
package/README.zh-CN.md CHANGED
@@ -40,8 +40,9 @@ Herdr Link 把这一步彻底去掉。Adapter 通过一个惰性 gateway 暴露
40
40
 
41
41
  ```text
42
42
  Agent A → herdr_link {} # 激活(幂等)
43
- Agent A → herdr_link_start(name, pane, config_agent) # 配置模式
44
- Agent A → herdr_link_start(name, pane, kind, args) # 显式模式
43
+ Agent A → herdr_link_start(name, config_agent[, cwd]) # 配置模式,Link 管理 placement
44
+ Agent A → herdr_link_start(name, kind, args[, cwd]) # 显式模式,Link 管理 placement
45
+ Agent A → herdr_link_start(..., with="worker-a") # 同 tab:与 live Agent 并排
45
46
  Agent A → herdr_link_send(to="B", ...) # status "sent"
46
47
  Agent B → (收到 inbound wrapper)herdr_link {} # 自动激活触发
47
48
  Agent B → herdr_link_send(to="A", message="结果或 done")
@@ -53,7 +54,7 @@ Agent B → herdr_link_send(to="A", message="结果或 done")
53
54
 
54
55
  ## 启动 Agent
55
56
 
56
- > `herdr_link_start` 只执行调用方已经作出的启动选择,不选择业务角色,也不创建 pane。
57
+ > `herdr_link_start` 只执行调用方已经作出的启动选择,不选择业务角色。placement 由 Link 机械处理:未给出 `with` anchor 时新建 tab;给出 `with` anchor 时与 anchor 同 tab 并排。
57
58
 
58
59
  ### 项目级 start 配置
59
60
 
@@ -80,9 +81,9 @@ cp /path/to/agent_config.example.json .agents/agent_config.json
80
81
 
81
82
  ```json
82
83
  {
83
- "version": 1,
84
84
  "agents": {
85
85
  "example-single": {
86
+ "placement": { "mode": "new_tab" },
86
87
  "variants": [
87
88
  {
88
89
  "kind": "pi",
@@ -95,23 +96,14 @@ cp /path/to/agent_config.example.json .agents/agent_config.json
95
96
  }
96
97
  ]
97
98
  },
98
- "example-round-robin": {
99
- "strategy": "round-robin",
99
+ "example-with": {
100
+ "placement": { "mode": "with" },
100
101
  "variants": [
101
102
  {
102
103
  "kind": "pi",
103
104
  "args": [
104
105
  "--model",
105
- "provider-a/model-a",
106
- "--thinking",
107
- "high"
108
- ]
109
- },
110
- {
111
- "kind": "pi",
112
- "args": [
113
- "--model",
114
- "provider-b/model-b",
106
+ "your-provider/your-model",
115
107
  "--thinking",
116
108
  "high"
117
109
  ]
@@ -122,9 +114,11 @@ cp /path/to/agent_config.example.json .agents/agent_config.json
122
114
  }
123
115
  ```
124
116
 
125
- 需要长期复用的启动方式使用 configured start:`{"name":"worker-01","pane":"wS:p22","config_agent":"example-single"}`。`config_agent` 是 `agents` 下由项目自行定义的 key,Herdr Link 不解释其业务含义。
117
+ 需要长期复用的启动方式使用 configured start:`{"name":"worker-01","config_agent":"example-single"}`。`config_agent` 是 `agents` 下由项目自行定义的 key,Herdr Link 不解释其业务含义。
118
+
119
+ 一次性启动使用 explicit start,不修改项目配置:`{"name":"worker-01","kind":"pi","args":["--model","model-x","--thinking","high"]}`。两种模式严格互斥;配置调用不能只覆盖 `kind` 或 `args`。
126
120
 
127
- 一次性启动使用 explicit start,不修改项目配置:`{"name":"worker-01","pane":"wS:p22","kind":"pi","args":["--model","model-x","--thinking","high"]}`。两种模式严格互斥;配置调用不能只覆盖 `kind` 或 `args`。
121
+ Placement Link 管理:每个 configured entry 必须声明 `placement`(`new_tab` 或 `with`);显式启动默认新建 tab,除非传入 `with=<live Agent Name>`(与 anchor 同 tab 并继承其 pane cwd)。`cwd` 可选,只设置新 tab 的 launch 工作目录,绝不改变 `.agents/agent_config.json` 的查找位置。
128
122
 
129
123
  #### 人类用户与 AI Agent 的配置规则
130
124
 
@@ -132,7 +126,7 @@ cp /path/to/agent_config.example.json .agents/agent_config.json
132
126
 
133
127
  1. 长期或重复使用的启动方式写入 `agents.<config-key>`。
134
128
  2. `<config-key>` 由项目自行命名,例如 `work-agent`、`reviewer`、`research-agent`、`fast-worker`;Herdr Link 不赋予它业务含义。
135
- 3. 每个 configured entry 至少包含一个完整的 `variant`。
129
+ 3. 每个 configured entry 必须显式声明 `placement`:`{"mode":"new_tab"}`(独立 tab)或 `{"mode":"with"}`(与 live anchor 并排,不新建 tab)。
136
130
  4. 每个 variant 必须包含非空 `kind`。
137
131
  5. `args` 如果存在,必须是字符串数组,并直接放在 `herdr agent start ... --` 之后传递。
138
132
  6. 只有一个 variant 时不需要 `strategy`。
@@ -148,7 +142,7 @@ cp /path/to/agent_config.example.json .agents/agent_config.json
148
142
  | 长期 / 重复启动方式 | 写入 `.agents/agent_config.json` | configured |
149
143
  | 一次性 / 临时启动参数 | 不修改文件 | explicit |
150
144
 
151
- Herdr Link 不决定 Agent 应该做什么,也不创建 pane、调度工作、选择模型或回收 Agent。`start` 只执行调用方提交的配置或显式启动选择;其余能力是消息层。
145
+ Herdr Link 不决定 Agent 应该做什么,也不调度工作、选择模型或回收 Agent。`start` 只执行调用方提交的配置或显式启动选择;Link 机械创建声明的 placement(新 tab,或 `with` anchor 旁的 sibling pane),其余能力是消息层。
152
146
 
153
147
  ## 安装
154
148
 
@@ -183,7 +177,7 @@ cp "$(npm root -g)/herdr-link/dist/herdr-link.opencode.js" \
183
177
  ~/.config/opencode/plugins/herdr-link.js
184
178
  ```
185
179
 
186
- OpenCode 没有按 session 启停工具的 API,因此 Adapter 采用**single-gateway dispatcher** 呈现:`{}` 激活,之后 `{"action":"start"|"peers"|"send"|"close", ...}` 分发到同一控制层。`start` 使用 `name + pane + config_agent` 或完整的 `name + pane + kind + args`,两种模式不合并。契约只注入已激活 session 的 system prompt(按 `sessionID` 记忆的内存态;server 重启回到 dormant)。
180
+ OpenCode 没有按 session 启停工具的 API,因此 Adapter 采用**single-gateway dispatcher** 呈现:`{}` 激活,之后 `{"action":"start"|"peers"|"send"|"close", ...}` 分发到同一控制层。`start` 使用 `name + config_agent` 或完整的 `name + kind + args`,可选 `with` / `cwd` 控制 placement;两种模式不合并。契约只注入已激活 session 的 system prompt(按 `sessionID` 记忆的内存态;server 重启回到 dormant)。
187
181
 
188
182
  ### Claude Code / Codex / AGY(共享 stdio MCP server)
189
183
 
@@ -259,7 +253,7 @@ scripts/mcp-probe.mjs stdio 握手排障探针
259
253
 
260
254
  ## 范围与非目标
261
255
 
262
- Herdr Link 是同一 workspace 内的互操作层,不是业务调度器或任务管理系统。它只提供调用方明确选择的 configured/explicit Agent start execution primitive;不负责业务角色选择、pane 创建/规划、Agent 调度/回收、模型选择、workflow/task/stage 状态、业务结果 schema/evidence/receipt/review、ACK/wait/poll/retry/pending-request 语义或可靠投递保证、持久队列或跨 session 状态、跨机器传输、权限审批、离线投递、**跨 workspace 的 discovery/send/close**(属于官方 Herdr Skill / CLI 控制面),或 workspace/topology 管理。业务 payload 放入 `message` 字段;Link 不解释其语义。完整范围以 [`PROTOCOL.md` §9](./PROTOCOL.md#9-non-goals) 为准。
256
+ Herdr Link 是同一 workspace 内的互操作层,不是业务调度器或任务管理系统。它只提供调用方明确选择的 configured/explicit Agent start execution primitive;不负责业务角色选择、Agent 调度/回收、模型选择、workflow/task/stage 状态、业务结果 schema/evidence/receipt/review、ACK/wait/poll/retry/pending-request 语义或可靠投递保证、持久队列或跨 session 状态、跨机器传输、权限审批、**跨 workspace 的 discovery/send/close**(属于官方 Herdr Skill / CLI 控制面),或 workspace/topology 管理。Link 只按每次 start 声明的 placement 机械创建(新 tab,或 `with` anchor 旁的 sibling pane),绝不规划或重塑既有 topology。业务 payload 放入 `message` 字段;Link 不解释其语义。完整范围以 [`PROTOCOL.md` §9](./PROTOCOL.md#9-non-goals) 为准。
263
257
 
264
258
  ## 许可证
265
259