@nanmicoder/dsh-agent-teams 0.1.15 → 0.1.16-rc.3

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/README.md CHANGED
@@ -22,7 +22,7 @@
22
22
 
23
23
  `dsh-agent-teams` turns the current DeepSeek Harness session into a captain that can assemble durable sub-agents, split a goal into dependency-aware tasks, and coordinate work through direct messages.
24
24
 
25
- Ask in natural language. The plugin provides the team protocol, eleven coordination tools, persistent state, an automatic shared-task scheduler, and a live Web UI—without requiring a separate workflow engine.
25
+ Ask in natural language. The plugin provides the team protocol, 13 coordination tools, persistent state, an automatic shared-task scheduler, and a live Web UI—without requiring a separate workflow engine.
26
26
 
27
27
  <p align="center">
28
28
  <img src="./assets/ui.png" width="100%" alt="DeepSeek Harness conversation with the AgentTeams live activity panel, members, tasks, dependencies, and reports">
@@ -30,7 +30,7 @@ Ask in natural language. The plugin provides the team protocol, eleven coordinat
30
30
 
31
31
  ## Releases
32
32
 
33
- The [latest release](https://github.com/NanmiCoder/dsh-agent-teams/releases/latest), [v0.1.15](https://github.com/NanmiCoder/dsh-agent-teams/releases/tag/v0.1.15), supports Harness **0.1.2-alpha.2**. Older hosts must use a pinned compatible plugin version. Browse the [complete release history](https://github.com/NanmiCoder/dsh-agent-teams/releases); the same notes ship in the npm package under `release-notes/`.
33
+ [v0.1.16-rc.3](./release-notes/v0.1.16-rc.3.md) targets npm `next`, with a concise fixed team protocol, existing-team reuse guidance, Web approval wakeups, and team-lock cleanup. Choose a version pair below.
34
34
 
35
35
  ## Why AgentTeams?
36
36
 
@@ -47,64 +47,40 @@ The [latest release](https://github.com/NanmiCoder/dsh-agent-teams/releases/late
47
47
 
48
48
  The conversation card and activity panel use Harness's official locale service. They follow live language changes between English and Simplified Chinese—including status labels, dynamic summaries, controls, archive markers, and accessibility text—without a page reload or a separate plugin setting.
49
49
 
50
- ## Install
50
+ ## Install and choose versions
51
51
 
52
- > [!IMPORTANT]
53
- > **Plugin 0.1.15 (`@latest`) requires DeepSeek Harness 0.1.2-alpha.2.** Updating this plugin does not update Harness. This release has no adapter for the old RC host APIs. Check the version of the instance you actually launch with `dsh --version` before installing.
52
+ **Recommended pair: DeepSeek Harness `0.1.2-rc.1` + AgentTeams `0.1.16-rc.3`. Both are still prereleases.**
54
53
 
55
- | Harness host | Plugin to use | Compatibility status |
54
+ | Use case | DeepSeek Harness | AgentTeams plugin |
56
55
  | --- | --- | --- |
57
- | **0.1.2-alpha.2** | **0.1.15** (`@latest`) | Recommended current pair; real API and Web UI verified on macOS arm64. |
58
- | **0.1.0-rc.8** | **0.1.14** | Previous dependency baseline; keep this pair if you are not upgrading Harness. |
59
- | Other older RC / unchanged source checkout | Pin your working plugin version; do not follow `@latest` | Do not assume every older host works with 0.1.14. |
60
- | Alpha.1, later Alpha versions, or other source revisions | Not verified | Match the documented host version or validate separately. |
56
+ | **Recommended installation** | **`0.1.2-rc.1`** | **`0.1.16-rc.3`** |
57
+ | Developer Alpha testing | `0.1.2-alpha.5` | `0.1.16-rc.3` |
58
+ | Retaining an older Alpha | `0.1.2-alpha.2` | `0.1.16-rc.3` |
61
59
 
62
- **The default plugin release follows the current supported Harness developer preview: `latest=0.1.15`, for Harness Alpha.2.** The host's Alpha version does not require a separate Alpha plugin channel. Users staying on an older host must install an explicit compatible plugin version instead of `@latest`. Optional peer dependencies are not a runtime version check: a successful install on an incompatible host does not mean the plugin can activate.
63
-
64
- See the [compatibility details](./docs/alpha2-compatibility.md) and [real business / UI acceptance report](./docs/alpha2-release-acceptance.md).
65
-
66
- ### npm: Harness Alpha.2
67
-
68
- If you install Harness through npm, upgrade the host first, then install the matching plugin:
60
+ ### 1. Install DeepSeek Harness
69
61
 
70
62
  ```sh
71
- npm install --global @deepseek-ai/dsh@0.1.2-alpha.2
63
+ npm install --global @deepseek-ai/dsh@0.1.2-rc.1
72
64
  dsh --version
73
- dsh plugin --profile web add @nanmicoder/dsh-agent-teams@latest
74
65
  ```
75
66
 
76
- To pin this release, replace `@latest` with `@0.1.15`. Check the required host version in the release notes when updating. These examples target the `web` profile; use your actual profile if different. Stop and restart the running Harness process after changing either host or plugin, then refresh the browser.
67
+ Skip this if you already run this version. Alpha is opt-in: select an exact Alpha version from the table and lock all host dependencies as described in the [maintenance guide](./docs/maintenance-workflow.md).
77
68
 
78
- ### Staying on an older host / rolling back
69
+ ### 2. Install the AgentTeams plugin
79
70
 
80
- If you are keeping the previous RC host, **do not install the plugin's `@latest`**. For Harness 0.1.0-rc.8, keep or reinstall the pinned 0.1.14 plugin:
71
+ This installs into the `web` profile. Replace `web` with your actual profile name if different:
81
72
 
82
73
  ```sh
83
- dsh plugin --profile web add @nanmicoder/dsh-agent-teams@0.1.14
74
+ dsh plugin --profile web add --save-exact @nanmicoder/dsh-agent-teams@0.1.16-rc.3
84
75
  ```
85
76
 
86
- Restart the old host and refresh the browser. If you also upgraded Harness, restore the matching older host before using 0.1.14; rolling back only the plugin is not a supported Alpha.2 configuration. Do not delete credentials or `.agent-teams` data to fix a version mismatch.
87
-
88
- **Harness built from source:** updating this plugin repository, rebuilding it, or installing a global CLI does not upgrade a separately launched Harness checkout. Preserve your local changes, update the actual host checkout to [dsh-v0.1.2-alpha.2](https://github.com/deepseek-ai/deepseek-harness/tree/dsh-v0.1.2-alpha.2), follow its build instructions, and restart that host. If its source must stay old, keep the old plugin too; for a source-linked plugin use tag `v0.1.14` and its matching dependencies/build, not the current `main` branch.
77
+ **After installation, stop and restart Harness for that profile, then refresh the browser.**
89
78
 
90
- ### Build the Alpha.2 plugin from source
79
+ Plugin `0.1.16-rc.3` uses the `next` channel; `latest` still points to `0.1.15`, which targets Alpha.2. Use the exact-version command above. Future plugin prereleases use `next`; only stable plugin releases that pass the full verification matrix may use `latest`.
91
80
 
92
- ```sh
93
- git clone --branch v0.1.15 https://github.com/NanmiCoder/dsh-agent-teams.git
94
- cd dsh-agent-teams
95
- pnpm install --frozen-lockfile
96
- pnpm build
97
- dsh plugin --profile web add .
98
- ```
81
+ > Desktop users must check the app's embedded Harness core; upgrading the global CLI does not upgrade it. For older `0.1.0-*` / `0.1.1-*` or unlisted hosts, keep a working pair and follow the [older-version and diagnostic guide](./docs/maintenance-workflow.md).
99
82
 
100
- This requires the Alpha.2 host above. Run `pnpm build` again after changing the source. The local plugin install remains linked to this checkout; pulling source alone does not rebuild that linked plugin.
101
-
102
- Validate the composed profile, restart DSH, and refresh the Web UI:
103
-
104
- ```sh
105
- dsh --profile web --dump-config
106
- dsh web
107
- ```
83
+ See the full [compatibility matrix](./compatibility.json), [source installation and Alpha testing guide](./docs/maintenance-workflow.md), and [verification coverage and platform limits](./docs/maintenance-2026-09-06/release/README.md).
108
84
 
109
85
  Then ask for a team directly:
110
86
 
@@ -112,7 +88,7 @@ Then ask for a team directly:
112
88
 
113
89
  ## How it works
114
90
 
115
- 1. The current session creates a team and becomes its captain.
91
+ 1. For a request to use AgentTeams, the captain follows the core protocol already in its system instructions. It continues an existing team and uses `agent_teams_status` when current state needs checking. When no team exists, the goal becomes a staged plan for review.
116
92
  2. The captain adds role-specific members backed by continuable sub-agents.
117
93
  3. The goal becomes tasks with owners and explicit dependencies.
118
94
  4. The shared scheduler uses real `running / idle / ready` state to atomically claim one ready task per idle member and wake it. An interrupted resident attempt stays parked and can resume through a direct message without losing its capability; after a cold process restart, the scheduler retries stranded open work with a fresh attempt.
@@ -123,6 +99,8 @@ Team state is stored under `<workspace>/.agent-teams/`; the Web panel reads that
123
99
 
124
100
  Member creation is zero-interaction by default: a member on the captain's current LLM route snapshots that provider, model, and reasoning effort, while a member on a requested alternative route snapshots the target model's default effort; later continuations restore the resolved snapshot. Only an explicit heterogeneous-team request (for example, “backend on provider A/model X, frontend on provider B/model Y”) supplies a member-specific `provider` + `model`; there is no per-member model or reasoning prompt.
125
101
 
102
+ Captain sessions keep the concise core protocol and the original 13 native team tools from their first request. All business tools are directly available; no loading tool or extra activation call is needed. Configured profiles retain their bounded directory in the fixed system prompt. Creating, approving, continuing or ending a team does not rewrite the system prompt or tool schemas. Core rules remain available after history compaction or discarded code-mode tool results. Members receive four team tools, fixed member instructions, and their ordinary coding/research tools. Web approval wakes the captain with a control message; later member reports wake it again. See the [fixed protocol and benchmark contract](./docs/progressive-loading.md).
103
+
126
104
  ## Slash command
127
105
 
128
106
  No “use AgentTeams” phrasing required. The plugin registers the
@@ -137,7 +115,7 @@ command), describe the goal, and press Enter.
137
115
  The command pipeline claims the line, then preserves that exact input as an
138
116
  ordinary user follow-up so it remains visible in the main chat. The gesture
139
117
  boundary adds the deterministic activation directive at pre-step, so the
140
- captain protocol still starts immediately. The invocation is also durably
118
+ first model request follows the staged planning protocol without a mandatory helper call. The invocation is also durably
141
119
  logged (`command/run` / `command/done`).
142
120
 
143
121
  Surfaces without command adjudication (for example the headless CLI) get the
@@ -174,6 +152,8 @@ See [docs/usage.md](./docs/usage.md) for the full tool reference, state model, W
174
152
 
175
153
  ## Plugin development Skill
176
154
 
155
+ Community upgrade, audit, benchmark, testing and release skills are vendored with a pinned source revision. See [skills/README.md](./skills/README.md) for local rules and [CONTRIBUTING.md](./CONTRIBUTING.md) for the contribution workflow.
156
+
177
157
  The repository also ships the open Agent Skills package [`dsh-plugin-development`](./skills/dsh-plugin-development/SKILL.md):
178
158
 
179
159
  ```sh
package/README_ZH.md CHANGED
@@ -22,7 +22,7 @@
22
22
 
23
23
  `dsh-agent-teams` 让当前 DeepSeek Harness 会话成为队长:创建可续聊的子 Agent、把目标拆成有依赖的任务,并通过直达消息协调成员工作。
24
24
 
25
- 你只需用自然语言提出目标。插件会提供团队协议、11 个协作工具、持久化状态、自动共享任务调度和实时 Web UI,不需要额外的 Workflow 引擎。
25
+ 你只需用自然语言提出目标。插件会提供精简的固定团队协议、13 个业务工具、持久化状态、自动共享任务调度和实时 Web UI,不需要额外的 Workflow 引擎。
26
26
 
27
27
  <p align="center">
28
28
  <img src="./assets/ui.png" width="100%" alt="DeepSeek Harness 对话与 AgentTeams 实时活动面板,展示成员、任务依赖和回报">
@@ -30,7 +30,7 @@
30
30
 
31
31
  ## 版本更新
32
32
 
33
- [最新版本](https://github.com/NanmiCoder/dsh-agent-teams/releases/latest) [v0.1.15](https://github.com/NanmiCoder/dsh-agent-teams/releases/tag/v0.1.15) 适配 Harness **0.1.2-alpha.2**。旧宿主用户应安装明确兼容的固定插件版本。也可浏览[完整发布历史](https://github.com/NanmiCoder/dsh-agent-teams/releases);同一份说明随 npm 包发布到 `release-notes/` 目录。
33
+ [v0.1.16-rc.3](./release-notes/v0.1.16-rc.3.md) 面向 npm `next` 渠道,精简固定团队协议、引导复用已有团队,并修复 Web 批准通知和团队锁清理。安装版本见下方配对表。
34
34
 
35
35
  ## 为什么需要 AgentTeams?
36
36
 
@@ -46,69 +46,47 @@
46
46
 
47
47
  对话卡片与活动面板接入 Harness 官方多语言服务,会随宿主在简体中文和英文之间实时切换;任务/成员状态、动态摘要、操作按钮、历史归档标识和无障碍文案都会同步更新,无需刷新页面,也不增加插件自己的语言设置。
48
48
 
49
- ## 安装
49
+ ## 安装与版本选择
50
50
 
51
- > [!IMPORTANT]
52
- > **插件 0.1.15(`@latest`)对应 DeepSeek Harness 0.1.2-alpha.2。** 升级插件不会自动升级 Harness,本版也没有兼容旧 RC 宿主 API 的适配层。安装前先用 `dsh --version` 核对你实际启动的宿主版本。
51
+ **推荐组合:DeepSeek Harness `0.1.2-rc.1` + AgentTeams `0.1.16-rc.3`。两者都仍是预发布版本。**
53
52
 
54
- | Harness 宿主 | 应使用的插件 | 兼容性说明 |
53
+ | 使用场景 | DeepSeek Harness | AgentTeams 插件 |
55
54
  | --- | --- | --- |
56
- | **0.1.2-alpha.2** | **0.1.15**(`@latest`) | 当前推荐组合;已在 macOS arm64 上通过真实 API 和 Web UI 验收。 |
57
- | **0.1.0-rc.8** | **0.1.14** | 原有依赖基线;不升级宿主时保留这一组合。 |
58
- | 其他旧 RC / 未更新的源码宿主 | 固定当前已能正常使用的插件版本,不要跟随 `@latest` | 不能推断所有旧宿主都兼容 0.1.14。 |
59
- | Alpha.1、后续 Alpha 或其他源码提交 | 尚未验证 | 请对齐上面明确验证的宿主版本,或单独验证。 |
55
+ | **推荐安装** | **`0.1.2-rc.1`** | **`0.1.16-rc.3`** |
56
+ | 开发者测试 Alpha | `0.1.2-alpha.5` | `0.1.16-rc.3` |
57
+ | 保留旧 Alpha | `0.1.2-alpha.2` | `0.1.16-rc.3` |
60
58
 
61
- **插件默认发行跟进当前已适配的 Harness 开发者预览版:`latest=0.1.15`,对应 Harness Alpha.2。** 宿主版本名里的 Alpha 不要求插件也另走 Alpha 渠道。继续使用旧宿主的用户,应明确安装兼容的固定插件版本,不要跟随 `@latest`。可选 peer dependencies 并不是运行时版本拦截:装得上,不代表不兼容的宿主能加载成功。
62
-
63
- 详见[兼容性记录](./docs/alpha2-compatibility.md)和[真实业务 / UI 验收报告](./docs/alpha2-release-acceptance.md)。
64
-
65
- ### npm:使用 Harness Alpha.2
66
-
67
- 通过 npm 安装 Harness 的用户,先升级宿主,再安装对应插件:
59
+ ### 1. 安装 DeepSeek Harness
68
60
 
69
61
  ```sh
70
- npm install --global @deepseek-ai/dsh@0.1.2-alpha.2
62
+ npm install --global @deepseek-ai/dsh@0.1.2-rc.1
71
63
  dsh --version
72
- dsh plugin --profile web add @nanmicoder/dsh-agent-teams@latest
73
64
  ```
74
65
 
75
- 如需固定本次插件版本,把 `@latest` 改为 `@0.1.15`。以后更新时,请同时查看发布说明要求的宿主版本。示例针对 `web` profile,其他 profile 请替换为你实际使用的名称。宿主或插件变更后,停止并重启正在运行的 Harness,再刷新浏览器。
66
+ 已有该版本可跳过。Alpha 仅供主动测试:手动指定表中的 Alpha 版本,并按[维护指南](./docs/maintenance-workflow.md)锁定整组宿主依赖。
76
67
 
77
- ### 不升级宿主 / 回退旧版本
68
+ ### 2. 安装 AgentTeams 插件
78
69
 
79
- 如果仍使用原来的 RC 宿主,**不要安装插件的 `@latest`**。对于 Harness 0.1.0-rc.8,保留或重新安装固定的 0.1.14 插件:
70
+ 以下安装到 `web` profile;使用其他 profile 时,将 `web` 换成实际名称:
80
71
 
81
72
  ```sh
82
- dsh plugin --profile web add @nanmicoder/dsh-agent-teams@0.1.14
73
+ dsh plugin --profile web add --save-exact @nanmicoder/dsh-agent-teams@0.1.16-rc.3
83
74
  ```
84
75
 
85
- 重启旧宿主并刷新浏览器即可。如果宿主也已升级,则要恢复匹配的旧宿主后再使用 0.1.14;仅回退插件不是受支持的 Alpha.2 组合。版本不匹配不需要删除凭据或 `.agent-teams` 数据。
86
-
87
- **从源码运行 Harness 的用户:** 更新本插件仓库、重新构建插件,或安装全局 CLI,都不会自动升级另一个正在运行的 Harness 源码目录。请先保留本地改动,把实际启动的宿主源码更新到 [dsh-v0.1.2-alpha.2](https://github.com/deepseek-ai/deepseek-harness/tree/dsh-v0.1.2-alpha.2),按该版本说明安装依赖、构建并重启。如果宿主源码必须保持旧版,插件也应保留旧版;本地链接插件请使用 `v0.1.14` tag 及其对应依赖和构建,不要直接更新到当前 `main`。
76
+ **安装后,停止并重新启动该 profile 的 Harness 进程,再刷新浏览器。**
88
77
 
89
- ### 从源码构建 Alpha.2 插件
78
+ 插件 `0.1.16-rc.3` 使用 `next` 渠道;当前 `latest` 仍是面向 Alpha.2 的 `0.1.15`。请使用上面的精确版本命令。后续插件预发布版本继续进入 `next`,通过完整验证的正式版本才进入 `latest`。
90
79
 
91
- ```sh
92
- git clone --branch v0.1.15 https://github.com/NanmiCoder/dsh-agent-teams.git
93
- cd dsh-agent-teams
94
- pnpm install --frozen-lockfile
95
- pnpm build
96
- dsh plugin --profile web add .
97
- ```
80
+ > Desktop 用户需核对应用内置的 Harness 核心;全局 CLI 升级不会升级桌面内核。旧 `0.1.0-*` / `0.1.1-*` 或其他未列出的宿主,请先保留已工作的组合,参考[旧版本与诊断指引](./docs/maintenance-workflow.md)。
98
81
 
99
- 此构建要求上面的 Alpha.2 宿主。修改源码后请重新执行 `pnpm build`;本地安装会继续链接到当前源码目录,只拉取代码不会重建已经链接的插件。
100
-
101
- 检查组合配置、重启 DSH,然后刷新 Web UI:
102
-
103
- ```sh
104
- dsh --profile web --dump-config
105
- dsh web
106
- ```
82
+ 完整[兼容清单](./compatibility.json)、[源码安装与 Alpha 验证](./docs/maintenance-workflow.md)、[已验证范围与平台限制](./docs/maintenance-2026-09-06/release/README.md)。
107
83
 
108
84
  接着直接用自然语言拉团队:
109
85
 
110
86
  > 使用 AgentTeams 审查 v0.5.3 之后的提交,分别从性能、安全和产品角度分工,最后输出一份汇总报告。
111
87
 
88
+ 队长会话从第一轮起保留精简的固定核心协议和原有 13 个业务工具,直接调用,无需额外的加载工具或激活调用。已配置模板的精简目录固定保留。创建、批准、继续或结束团队都不会改写系统提示词和工具 schema,会话压缩或代码模式丢弃工具结果也不会丢失核心规则。成员保留四个团队工具、固定成员说明及普通编程/研究工具。Web 批准后会通知并唤醒队长,后续成员报告会再次唤醒它,无需忙轮询。详见[固定协议与 benchmark 标准](./docs/progressive-loading.md)。
89
+
112
90
  ## 工作方式
113
91
 
114
92
  1. 当前会话创建团队并成为队长。
@@ -163,7 +141,9 @@ dsh web
163
141
 
164
142
  ## 插件开发 Skill
165
143
 
166
- 仓库同时提供开放 Agent Skills 包 [`dsh-plugin-development`](./skills/dsh-plugin-development/SKILL.md):
144
+ 仓库已引入社区升级、审计、测试和发布 skills,来源与本项目规则见 [skills/README.md](./skills/README.md),贡献入口见 [CONTRIBUTING.md](./CONTRIBUTING.md)。
145
+
146
+ 另提供开放 Agent Skills 包 [`dsh-plugin-development`](./skills/dsh-plugin-development/SKILL.md):
167
147
 
168
148
  ```sh
169
149
  npx skills add NanmiCoder/dsh-agent-teams --skill dsh-plugin-development
@@ -190,7 +170,7 @@ pnpm verify
190
170
 
191
171
  在 `cordis.patch.yml` 的 `profiles` 中配置完整团队模板。每个 profile 都提供成员阵容,可独立指定 provider、model、role、reasoning_effort。`taskPlanning: captain` 表示只提供阵容和约束,由 Captain 根据用户目标设计 DAG;省略该字段或设为 `seed` 时,展开模板中的固定任务图。使用 `/agent-teams --profile <名称> <目标>` 显式激活;不会把首个普通 token 隐式识别为 profile。
192
172
 
193
- 普通 `/agent-teams` 流程会调用 `agent_teams_create({ profile, approval: "required" })`:只落盘可编辑的成员占位和 DAG,不创建子会话、不领取任务。成员模型和推理等级直接读取 Harness 的模型目录。「返回对话修改」会终止仍在运行的规划轮次,让队长先追问修改方向,再用一次原子操作更新同一份草案;「放弃本次计划」经二次确认后会归档草案、中止轮次,并向模型注入不得自动重建团队的控制上下文。只有点击「确认并启动团队」才会按最终配置原子创建成员并启动就绪任务。运行中团队的停止入口位于该团队的面板标题,点击后需要二次确认,不再占用输入区域。直接工具调用方可显式传 `approval: "automatic"` 保留旧的立即执行路径。审查或测试失败不会解锁下游;自动 repair/review 不依赖 failed review。
173
+ 普通 `/agent-teams` 流程继续已有团队,按需调用 `agent_teams_status` 确认状态;仅在没有当前团队时调用 `agent_teams_create({ profile, approval: "required" })`:只落盘可编辑的成员占位和 DAG,不创建子会话、不领取任务。成员模型和推理等级直接读取 Harness 的模型目录。「返回对话修改」会终止仍在运行的规划轮次,让队长先追问修改方向,再用一次原子操作更新同一份草案;「放弃本次计划」经二次确认后会归档草案、中止轮次,并向模型注入不得自动重建团队的控制上下文。只有点击「确认并启动团队」才会按最终配置原子创建成员并启动就绪任务。运行中团队的停止入口位于该团队的面板标题,点击后需要二次确认,不再占用输入区域。直接工具调用方可显式传 `approval: "automatic"` 保留旧的立即执行路径。审查或测试失败不会解锁下游;自动 repair/review 不依赖 failed review。
194
174
 
195
175
  ## 许可证
196
176
 
@@ -0,0 +1,10 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "recommendedHost": "0.1.2-rc.1",
4
+ "previewTag": "next",
5
+ "supportedHosts": [
6
+ { "version": "0.1.2-rc.1", "track": "recommended" },
7
+ { "version": "0.1.2-alpha.5", "track": "preview" },
8
+ { "version": "0.1.2-alpha.2", "track": "legacy" }
9
+ ]
10
+ }
@@ -0,0 +1,106 @@
1
+ import { readdirSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { readTeamSync, readRetiredMemberIdsSync } from "./state.js";
4
+ import { MEMBER_TOOL_NAMES, TEAM_TOOL_NAMES } from "./tool-names.js";
5
+ export const TEAM_ACTIVATION_PROMPT = 'AgentTeams (Agent Teams) provides multi-agent team collaboration. Apply these rules when the user requests it (including /agent-teams) or when continuing an existing team. Mentioning, quoting, discussing, or declining AgentTeams alone is not a request to start work.';
6
+ export const TEAM_MEMBER_PROMPT = 'You are an AgentTeams member. Follow your assigned member persona and task contract. Use agent_teams_claim_task, agent_teams_update_task, agent_teams_send_message and agent_teams_status for your own work. Include the current attempt_id in updates; report completion or failure to the captain. Do not create, approve, edit or resume a team. If your durable membership is unavailable, report that to the parent instead of creating a replacement.';
7
+ function stateRoot(agent, config) {
8
+ return join(agent.session.header.cwd ?? process.cwd(), config.stateDir);
9
+ }
10
+ /** Synchronous startup/HMR hydration must finish before the first assembly. */
11
+ function currentTeam(agent, config) {
12
+ const root = stateRoot(agent, config);
13
+ let entries;
14
+ try {
15
+ entries = readdirSync(root, { withFileTypes: true });
16
+ }
17
+ catch (error) {
18
+ if (error.code === 'ENOENT')
19
+ return undefined;
20
+ throw error;
21
+ }
22
+ let found;
23
+ for (const entry of entries) {
24
+ if (!entry.isDirectory() || entry.name === 'archive')
25
+ continue;
26
+ const team = readTeamSync(root, entry.name);
27
+ if (team === undefined || (team.captainSessionId !== agent.id
28
+ && !team.members.some(member => member.id === agent.id)))
29
+ continue;
30
+ if (found !== undefined)
31
+ throw new Error('ambiguous AgentTeams membership');
32
+ found = team;
33
+ }
34
+ return found;
35
+ }
36
+ /** Call once, after all business definitions have registered. Never per member. */
37
+ export function installTeamCapabilities(ctx, config) {
38
+ const states = new WeakMap();
39
+ const active = new Set();
40
+ let mounted = true;
41
+ // Snapshot policy once: profiles, team state, and tool results must never
42
+ // rewrite this prefix or control whether core instructions are available.
43
+ const captainPrompt = `${TEAM_ACTIVATION_PROMPT}\n\n${config.captainPrompt()}`;
44
+ function attach(agent) {
45
+ const prior = states.get(agent);
46
+ if (prior !== undefined)
47
+ return prior;
48
+ if (!mounted)
49
+ throw new Error('AgentTeams capability provider is disposed');
50
+ // Determine a member's role before its first request and retain it for the
51
+ // lifetime of this scope. Team creation/archive must never rewrite the
52
+ // captain's system/tools prefix, even after a long ordinary conversation.
53
+ let member = config.isPendingMember(agent);
54
+ try {
55
+ member ||= readRetiredMemberIdsSync(stateRoot(agent, config)).has(agent.id);
56
+ const team = currentTeam(agent, config);
57
+ member ||= team !== undefined && team.captainSessionId !== agent.id;
58
+ }
59
+ catch (error) {
60
+ // Unrelated damaged state must not disable ordinary conversation.
61
+ // Business tools still validate durable team state before acting.
62
+ ctx.logger.warn(`agent-teams: capability hydration failed: ${String(error)}`);
63
+ }
64
+ const state = { member, dispose: () => undefined };
65
+ let revoke;
66
+ let disposed = false;
67
+ let releaseLifetime;
68
+ state.dispose = () => {
69
+ if (disposed)
70
+ return;
71
+ disposed = true;
72
+ revoke?.();
73
+ releaseLifetime?.();
74
+ states.delete(agent);
75
+ active.delete(state);
76
+ };
77
+ states.set(agent, state);
78
+ active.add(state);
79
+ try {
80
+ if (member)
81
+ revoke = agent.ctx.tools.restrict({
82
+ deny: TEAM_TOOL_NAMES.filter(name => !MEMBER_TOOL_NAMES.includes(name)),
83
+ });
84
+ releaseLifetime = agent.ctx.effect(() => state.dispose, 'agent-teams: capability lifetime');
85
+ return state;
86
+ }
87
+ catch (error) {
88
+ state.dispose();
89
+ throw error;
90
+ }
91
+ }
92
+ ctx.systemPrompt.section({
93
+ name: 'agent-teams:usage', order: config.order ?? 117,
94
+ text: ({ agent }) => {
95
+ return agent !== undefined && states.get(agent)?.member ? TEAM_MEMBER_PROMPT : captainPrompt;
96
+ },
97
+ });
98
+ ctx.on('agent/session-start', ({ agent }) => { attach(agent); });
99
+ ctx.effect(() => () => {
100
+ mounted = false;
101
+ for (const state of [...active])
102
+ state.dispose();
103
+ }, 'agent-teams: capability scopes');
104
+ for (const agent of ctx.agents.list())
105
+ attach(agent);
106
+ }
@@ -358,7 +358,7 @@ function TeamSection({ team, modelDirectory, onContinuePlanning, onDiscarded, on
358
358
  if (member.id !== '') {
359
359
  onNavigate(team.captainSessionId, member.id);
360
360
  }
361
- }, children: [_jsxs("span", { className: css.memberAvatar, "data-unread": member.unread > 0, children: [memberArtUrl(member.name, member.role) !== null ? (_jsx("img", { className: css.memberArt, src: memberArtUrl(member.name, member.role) ?? '', alt: "", "aria-hidden": true })) : (_jsx("span", { className: css.memberInitial, style: { background: accentOf(member.id) }, children: memberInitial(member.name) })), _jsx("img", { className: css.stateArt, "data-activity": member.activity, src: ACTION_ART[member.activity], alt: "", "aria-hidden": true })] }), _jsxs("span", { className: css.memberInfo, children: [_jsxs("span", { className: css.memberLine, children: [_jsx("span", { className: css.memberName, children: member.name }), member.role !== '' && _jsx("span", { className: css.memberRole, children: member.role }), _jsxs("span", { className: css.memberState, "data-activity": member.activity, children: [_jsx(WorkGlyph, { active: member.activity === 'working' }), discarded
361
+ }, children: [_jsxs("span", { className: css.memberAvatar, "data-unread": member.unread > 0, children: [memberArtUrl(member.name, member.role) !== null ? (_jsx("img", { className: css.memberArt, src: memberArtUrl(member.name, member.role) ?? '', alt: "", "aria-hidden": true })) : (_jsx("span", { className: css.memberInitial, style: { background: accentOf(member.id) }, children: memberInitial(member.name) })), _jsx("img", { className: css.stateArt, "data-activity": member.activity, src: ACTION_ART[member.activity], alt: "", "aria-hidden": true })] }), _jsxs("span", { className: css.memberInfo, children: [_jsxs("span", { className: css.memberLine, children: [_jsx("span", { className: css.memberName, children: member.name }), member.role !== '' && _jsx("span", { className: css.memberRole, children: member.role }), memberModel !== '' && (_jsx("span", { className: css.memberModel, role: "img", "data-member-model": memberModel, title: memberModel, "aria-label": memberModel, children: compactModelLabel(memberModel) })), _jsxs("span", { className: css.memberState, "data-activity": member.activity, children: [_jsx(WorkGlyph, { active: member.activity === 'working' }), discarded
362
362
  ? t('member.state.notCreated')
363
363
  : stopped
364
364
  ? t('member.state.stopped')
@@ -372,7 +372,7 @@ function TeamSection({ team, modelDirectory, onContinuePlanning, onDiscarded, on
372
372
  ? t('member.status.staged')
373
373
  : historic && owned.length > 0 && owned.every((task) => (task.status === 'completed' || task.status === 'failed' || task.status === 'cancelled'))
374
374
  ? t('member.status.settled')
375
- : memberStatusText(member, team.tasks, t) }), memberModel !== '' && (_jsx("span", { className: css.memberModel, "data-member-model": memberModel, children: t('member.model', { model: memberModel }) }))] }), _jsxs("span", { className: css.memberCount, children: [member.done, "/", member.total] })] }), _jsxs("div", { className: css.assignmentLine, children: [_jsx("span", { className: css.assignmentLabel, children: t(discarded
375
+ : memberStatusText(member, team.tasks, t) })] }), _jsxs("span", { className: css.memberCount, children: [member.done, "/", member.total] })] }), _jsxs("div", { className: css.assignmentLine, children: [_jsx("span", { className: css.assignmentLabel, children: t(discarded
376
376
  ? 'assignment.discarded'
377
377
  : team.phase === 'staged'
378
378
  ? 'assignment.staged'
@@ -81,7 +81,6 @@ export const zh = {
81
81
  'dependency.hint.pinned': '{taskId} 已固定 · Esc 取消',
82
82
  'task.runningAria': '运行中',
83
83
  'task.model': '{model}',
84
- 'member.model': '{model}',
85
84
  'task.detail.completed': '已完成并交付',
86
85
  'task.detail.noPrerequisite': '无前置,可立即开工',
87
86
  'task.detail.ready': '前置已就绪,可开工',
@@ -273,7 +272,6 @@ export const en = {
273
272
  'dependency.hint.pinned': '{taskId} pinned · Esc to clear',
274
273
  'task.runningAria': 'Running',
275
274
  'task.model': '{model}',
276
- 'member.model': '{model}',
277
275
  'task.detail.completed': 'Completed and delivered',
278
276
  'task.detail.noPrerequisite': 'No prerequisites; ready to start',
279
277
  'task.detail.ready': 'Prerequisites ready; can start',