@te-river/opencode-team-mode 1.5.4 → 1.5.6

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.
Files changed (158) hide show
  1. package/README.md +732 -634
  2. package/README.zh-CN.md +655 -576
  3. package/dist/agents.d.ts +6 -1
  4. package/dist/agents.d.ts.map +1 -1
  5. package/dist/agents.js +103 -522
  6. package/dist/agents.js.map +1 -1
  7. package/dist/approval-gate.d.ts +16 -0
  8. package/dist/approval-gate.d.ts.map +1 -1
  9. package/dist/approval-gate.js +8 -1
  10. package/dist/approval-gate.js.map +1 -1
  11. package/dist/blackboard.d.ts.map +1 -1
  12. package/dist/blackboard.js +3 -2
  13. package/dist/blackboard.js.map +1 -1
  14. package/dist/commands.d.ts.map +1 -1
  15. package/dist/commands.js +7 -6
  16. package/dist/commands.js.map +1 -1
  17. package/dist/envprotect/bash-classify.d.ts +42 -0
  18. package/dist/envprotect/bash-classify.d.ts.map +1 -0
  19. package/dist/envprotect/bash-classify.js +221 -0
  20. package/dist/envprotect/bash-classify.js.map +1 -0
  21. package/dist/envprotect/gate-predicates.d.ts +57 -0
  22. package/dist/envprotect/gate-predicates.d.ts.map +1 -0
  23. package/dist/envprotect/gate-predicates.js +174 -0
  24. package/dist/envprotect/gate-predicates.js.map +1 -0
  25. package/dist/envprotect/hook.d.ts +45 -0
  26. package/dist/envprotect/hook.d.ts.map +1 -0
  27. package/dist/envprotect/hook.js +158 -0
  28. package/dist/envprotect/hook.js.map +1 -0
  29. package/dist/envprotect/path-classify.d.ts +16 -0
  30. package/dist/envprotect/path-classify.d.ts.map +1 -0
  31. package/dist/envprotect/path-classify.js +72 -0
  32. package/dist/envprotect/path-classify.js.map +1 -0
  33. package/dist/envprotect/patterns.d.ts +77 -0
  34. package/dist/envprotect/patterns.d.ts.map +1 -0
  35. package/dist/envprotect/patterns.js +182 -0
  36. package/dist/envprotect/patterns.js.map +1 -0
  37. package/dist/envprotect.d.ts +19 -217
  38. package/dist/envprotect.d.ts.map +1 -1
  39. package/dist/envprotect.js +18 -803
  40. package/dist/envprotect.js.map +1 -1
  41. package/dist/fs-safe.d.ts +16 -0
  42. package/dist/fs-safe.d.ts.map +1 -0
  43. package/dist/fs-safe.js +56 -0
  44. package/dist/fs-safe.js.map +1 -0
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +22 -6
  47. package/dist/index.js.map +1 -1
  48. package/dist/prompts/lead.d.ts +7 -0
  49. package/dist/prompts/lead.d.ts.map +1 -0
  50. package/dist/prompts/lead.js +230 -0
  51. package/dist/prompts/lead.js.map +1 -0
  52. package/dist/prompts/shared.d.ts +8 -0
  53. package/dist/prompts/shared.d.ts.map +1 -0
  54. package/dist/prompts/shared.js +118 -0
  55. package/dist/prompts/shared.js.map +1 -0
  56. package/dist/prompts/specialists.d.ts +12 -0
  57. package/dist/prompts/specialists.d.ts.map +1 -0
  58. package/dist/prompts/specialists.js +218 -0
  59. package/dist/prompts/specialists.js.map +1 -0
  60. package/dist/shell-text.d.ts +14 -0
  61. package/dist/shell-text.d.ts.map +1 -0
  62. package/dist/shell-text.js +16 -0
  63. package/dist/shell-text.js.map +1 -0
  64. package/dist/tm/args-schema.d.ts +36 -0
  65. package/dist/tm/args-schema.d.ts.map +1 -0
  66. package/dist/tm/args-schema.js +191 -0
  67. package/dist/tm/args-schema.js.map +1 -0
  68. package/dist/tm/browser.d.ts +52 -0
  69. package/dist/tm/browser.d.ts.map +1 -0
  70. package/dist/tm/browser.js +361 -0
  71. package/dist/tm/browser.js.map +1 -0
  72. package/dist/tm/client-unwrap.d.ts +38 -0
  73. package/dist/tm/client-unwrap.d.ts.map +1 -0
  74. package/dist/tm/client-unwrap.js +113 -0
  75. package/dist/tm/client-unwrap.js.map +1 -0
  76. package/dist/tm/config.d.ts +46 -18
  77. package/dist/tm/config.d.ts.map +1 -1
  78. package/dist/tm/config.js +60 -17
  79. package/dist/tm/config.js.map +1 -1
  80. package/dist/tm/guard.d.ts.map +1 -1
  81. package/dist/tm/guard.js +4 -7
  82. package/dist/tm/guard.js.map +1 -1
  83. package/dist/tm/index.d.ts +15 -5
  84. package/dist/tm/index.d.ts.map +1 -1
  85. package/dist/tm/index.js +95 -19
  86. package/dist/tm/index.js.map +1 -1
  87. package/dist/tm/memory.d.ts +82 -0
  88. package/dist/tm/memory.d.ts.map +1 -0
  89. package/dist/tm/memory.js +350 -0
  90. package/dist/tm/memory.js.map +1 -0
  91. package/dist/tm/pipelines.d.ts +58 -0
  92. package/dist/tm/pipelines.d.ts.map +1 -0
  93. package/dist/tm/pipelines.js +301 -0
  94. package/dist/tm/pipelines.js.map +1 -0
  95. package/dist/tm/preview.d.ts +6 -1
  96. package/dist/tm/preview.d.ts.map +1 -1
  97. package/dist/tm/preview.js +31 -8
  98. package/dist/tm/preview.js.map +1 -1
  99. package/dist/tm/ptc/budgets.d.ts +38 -0
  100. package/dist/tm/ptc/budgets.d.ts.map +1 -0
  101. package/dist/tm/ptc/budgets.js +59 -0
  102. package/dist/tm/ptc/budgets.js.map +1 -0
  103. package/dist/tm/ptc/contract.d.ts +131 -0
  104. package/dist/tm/ptc/contract.d.ts.map +1 -0
  105. package/dist/tm/ptc/contract.js +47 -0
  106. package/dist/tm/ptc/contract.js.map +1 -0
  107. package/dist/tm/ptc/driver.d.ts +37 -0
  108. package/dist/tm/ptc/driver.d.ts.map +1 -0
  109. package/dist/tm/ptc/driver.js +181 -0
  110. package/dist/tm/ptc/driver.js.map +1 -0
  111. package/dist/tm/ptc/engines.d.ts +32 -0
  112. package/dist/tm/ptc/engines.d.ts.map +1 -0
  113. package/dist/tm/ptc/engines.js +201 -0
  114. package/dist/tm/ptc/engines.js.map +1 -0
  115. package/dist/tm/ptc/gate.d.ts +28 -0
  116. package/dist/tm/ptc/gate.d.ts.map +1 -0
  117. package/dist/tm/ptc/gate.js +127 -0
  118. package/dist/tm/ptc/gate.js.map +1 -0
  119. package/dist/tm/ptc/index.d.ts +19 -0
  120. package/dist/tm/ptc/index.d.ts.map +1 -0
  121. package/dist/tm/ptc/index.js +15 -0
  122. package/dist/tm/ptc/index.js.map +1 -0
  123. package/dist/tm/ptc/pscan.d.ts +11 -0
  124. package/dist/tm/ptc/pscan.d.ts.map +1 -0
  125. package/dist/tm/ptc/pscan.js +27 -0
  126. package/dist/tm/ptc/pscan.js.map +1 -0
  127. package/dist/tm/ptc/summary.d.ts +17 -0
  128. package/dist/tm/ptc/summary.d.ts.map +1 -0
  129. package/dist/tm/ptc/summary.js +107 -0
  130. package/dist/tm/ptc/summary.js.map +1 -0
  131. package/dist/tm/ptc/tool.d.ts +35 -0
  132. package/dist/tm/ptc/tool.d.ts.map +1 -0
  133. package/dist/tm/ptc/tool.js +135 -0
  134. package/dist/tm/ptc/tool.js.map +1 -0
  135. package/dist/tm/ptc.d.ts +45 -26
  136. package/dist/tm/ptc.d.ts.map +1 -1
  137. package/dist/tm/ptc.js +71 -45
  138. package/dist/tm/ptc.js.map +1 -1
  139. package/dist/tm/result.d.ts +34 -0
  140. package/dist/tm/result.d.ts.map +1 -0
  141. package/dist/tm/result.js +87 -0
  142. package/dist/tm/result.js.map +1 -0
  143. package/dist/tm/shell-bridge.d.ts +22 -0
  144. package/dist/tm/shell-bridge.d.ts.map +1 -0
  145. package/dist/tm/shell-bridge.js +70 -0
  146. package/dist/tm/shell-bridge.js.map +1 -0
  147. package/dist/tm/store.d.ts.map +1 -1
  148. package/dist/tm/store.js +2 -1
  149. package/dist/tm/store.js.map +1 -1
  150. package/dist/tm/tools.d.ts +13 -71
  151. package/dist/tm/tools.d.ts.map +1 -1
  152. package/dist/tm/tools.js +23 -656
  153. package/dist/tm/tools.js.map +1 -1
  154. package/dist/tm/webfetch.d.ts +94 -0
  155. package/dist/tm/webfetch.d.ts.map +1 -0
  156. package/dist/tm/webfetch.js +225 -0
  157. package/dist/tm/webfetch.js.map +1 -0
  158. package/package.json +2 -2
package/README.zh-CN.md CHANGED
@@ -1,576 +1,655 @@
1
- # OpenCode TeamMode
2
-
3
- **[English](./README.md)** | **[中文](./README.zh-CN.md)**
4
-
5
- [![npm version](https://img.shields.io/npm/v/@te-river/opencode-team-mode.svg)](https://www.npmjs.com/package/@te-river/opencode-team-mode)
6
- [![npm downloads](https://img.shields.io/npm/dm/@te-river/opencode-team-mode.svg)](https://www.npmjs.com/package/@te-river/opencode-team-mode)
7
- [![license](https://img.shields.io/npm/l/@te-river/opencode-team-mode.svg)](./LICENSE)
8
-
9
- > 🤝 **[OpenCode 桌面版](https://opencode.ai) 多 Agent 团队协作插件**
10
- >
11
- > 为你的 OpenCode 桌面版添加一整支 AI 专家团队 —— 架构师、实现者、审查员、测试员、调研员,由 Team Lead 统一调度,通过简单的斜杠命令即可调用。
12
-
13
- ---
14
-
15
- ## ✨ TeamMode 是什么?
16
-
17
- TeamMode 将 OpenCode 桌面版从一个单 Agent 编码助手,升级为**一整个开发团队**。每个 Agent 拥有独立的角色定位、专业领域和行为风格 —— 就像真实的工程团队。
18
-
19
- 不再是一个 Agent 包揽所有事,你将获得:
20
-
21
- | Agent | 角色 | 使用场景 |
22
- |---|---|---|
23
- | 🎯 **Team Lead** | 调度者 | 需要规划 + 多步执行的复杂任务 |
24
- | 🏗️ **Architect** | 系统设计师 | 设计文档、模块结构、API 契约 |
25
- | 💻 **Implementer** | 代码实现者 | 编写生产代码、实现功能 |
26
- | 🔍 **Reviewer** | 单维审查员 | 单维度审查(完整性 / 正确性 / 影响面)——lead 三路并行后合并 |
27
- | 🧪 **Tester** | 测试工程师 | 单元测试、集成测试、边界覆盖、静态验证(构建 / 类型检查 / lint / API 测试) |
28
- | 🔎 **Researcher** | 知识调研员 | 库评估、API 文档、最佳实践调研 |
29
-
30
- ---
31
-
32
- ## 🚀 快速开始
33
-
34
- ### 前置条件
35
-
36
- 1. **安装 OpenCode 桌面版**(如果还没有):
37
-
38
- | 平台 | 安装命令 |
39
- |---|---|
40
- | macOS (Apple Silicon) | `brew install --cask opencode-desktop` |
41
- | macOS (Intel) | `brew install --cask opencode-desktop` |
42
- | Windows | `scoop bucket add extras && scoop install extras/opencode-desktop` |
43
- | Linux | 从 [opencode.ai/download](https://opencode.ai/download) 下载 |
44
-
45
- 或安装 **CLI/TUI** 版本:
46
- ```bash
47
- # 一键脚本(全平台)
48
- curl -fsSL https://opencode.ai/install | bash
49
-
50
- # 或通过 npm
51
- npm install -g opencode-ai
52
- ```
53
-
54
- 2. **Node.js ≥ 18**(用于 npm)
55
-
56
- ### 安装 TeamMode
57
-
58
- **方式 A — 一键安装脚本:**
59
-
60
- macOS / Linux(bash):
61
- ```bash
62
- curl -fsSL https://ghproxy.net/https://raw.githubusercontent.com/Te-River/Opencode-TeamMode/main/scripts/install.sh | bash
63
- ```
64
-
65
- Windows(PowerShell):
66
- ```powershell
67
- irm https://ghproxy.net/https://raw.githubusercontent.com/Te-River/Opencode-TeamMode/main/scripts/install.ps1 | iex
68
- ```
69
-
70
- **方式 B — 手动配置:**
71
-
72
- 在你的 `opencode.jsonc` 中添加插件:
73
-
74
- ```jsonc
75
- {
76
- "$schema": "https://opencode.ai/config.json",
77
- "plugin": [
78
- "@te-river/opencode-team-mode@latest"
79
- ]
80
- }
81
- ```
82
-
83
- OpenCode 启动时会自动安装插件。
84
-
85
- > **提示:** 修改 `opencode.json` 后,**重启 OpenCode Desktop** 使配置生效。
86
-
87
- ---
88
-
89
- ## ⚙️ 配置
90
-
91
- 插件会在 OpenCode 启动时自动注入所有团队 Agent 和命令,**无需手动复制任何 Agent 文件或命令定义**。
92
-
93
- > ⚠️ **模型选择很重要。** 工作流里的每一个判断——分诊、拆解、派单、
94
- > 整合、审查/测试闭环裁决——都经过 **Team Lead**。这个位置上放弱模型,
95
- > 专家再强也救不回整条流水线。如需自定义,还请给你的 `team` agent 钉上你能负担的最强
96
- > 推理模型(配方见下方「自定义」节)。
97
-
98
- ### 全局安装(所有项目生效)
99
-
100
- 要在所有项目中启用 TeamMode,将插件添加到全局配置:
101
-
102
- ```jsonc
103
- // ~/.config/opencode/opencode.jsonc
104
- {
105
- "$schema": "https://opencode.ai/config.json",
106
- "plugin": [
107
- "@te-river/opencode-team-mode@latest"
108
- ]
109
- }
110
- ```
111
-
112
- ---
113
-
114
- ## 📖 使用方法
115
-
116
- ### 斜杠命令
117
-
118
- TeamMode 为 OpenCode 添加了六个斜杠命令,在聊天输入框中输入:
119
-
120
- | 命令 | Agent | 说明 |
121
- |---|---|---|
122
- | `/team-plan <任务>` | Architect | 创建详细的实现计划:架构、文件清单、任务拆解 |
123
- | `/team-implement <任务>` | Implementer | 为功能或任务编写生产代码 |
124
- | `/team-review [范围]` | Reviewer | 审查代码的 Bug、安全问题和质量问题 |
125
- | `/team-test [范围]` | Tester | 生成全面的测试,覆盖边界场景 |
126
- | `/team-research <主题>` | Researcher | 调研库、API 或最佳实践 |
127
- | `/team-run <任务>` | Team Lead | **完整工作流** — 端到端调度所有 Agent |
128
-
129
- #### 示例工作流
130
-
131
- ```bash
132
- # 1. 规划功能
133
- /team-plan 添加基于 OAuth2 和 JWT 的用户认证
134
-
135
- # 2. 审查计划后,开始实现
136
- /team-implement 按计划实现认证模块
137
-
138
- # 3. 审查代码
139
- /team-review src/auth/
140
-
141
- # 4. 编写测试
142
- /team-test src/auth/
143
-
144
- # 或者让 Team Lead 全程调度:
145
- /team-run 添加基于 OAuth2 和 JWT 的用户认证
146
- ```
147
-
148
- ### Agent 选择器
149
-
150
- 你也可以在 OpenCode 桌面版中使用 `@` 直接调用 Agent:
151
-
152
- - `@team` — 调度复杂任务
153
- - `@architect` — 设计系统或模块
154
- - `@implementer` — 编写代码
155
- - `@reviewer` — 审查代码质量
156
- - `@tester` — 编写测试
157
- - `@researcher` — 调研主题
158
-
159
- ### 演示
160
-
161
- 以下是一段会话实录的还原。Team 出厂即默认代理(退出方法见下方配置),
162
- 用户开新会话直接输入:
163
-
164
- > **用户:** 给我们的 Express API 加令牌桶限流——每用户每分钟 100 请求,
165
- > 超限返回 429。不要动 `src/legacy/` 下的任何东西。
166
-
167
- ```text
168
- team 路由:产品行为变更 → implementer → tester → reviewer
169
- (3 次派发 → 触发审批门)
170
-
171
- 调研:已读 README、src/app.ts、src/middleware/*
172
- 阻塞性问题:无 —— 1 条假设列在下方
173
-
174
- 计划
175
- 目标:令牌桶限流,100 请求/分/用户,429 + Retry-After
176
- 范围:src/middleware/rateLimit.ts(新增)、src/app.ts(+3 行)
177
- 流水线:implementer → tester → reviewer(correctness)
178
- 假设:内存桶而非 Redis —— 要改说一声
179
- 边界:src/legacy/** 不动
180
- 批准后开工?
181
-
182
- 用户 批准,开始
183
-
184
- team ▸ @implementer — STATUS: done
185
- CHANGES: src/middleware/rateLimit.ts(新增)· src/app.ts(+3)
186
- HANDOFF: bucket {tokens, lastRefill};refill() 单次原子完成
187
- EVIDENCE: tsc 无错误(输出见上)
188
-
189
- ▸ @tester — STATUS: done · VERDICT: pass(14/14)
190
- FINDINGS: 覆盖突发边界、窗口过期、并发回充;
191
- src/legacy/** 逐字节未变
192
- EVIDENCE: vitest 14 passed
193
-
194
- ▸ @reviewer — STATUS: done · VERDICT: approve(correctness)
195
- FINDINGS: 无 Critical/Major;1 条 Minor(日志噪音)已记录
196
-
197
- team 完成。
198
- 限流器已交付:rateLimit.ts(新增)· app.ts(+3)· 14 测试全绿
199
- 审查:通过 · 假设:仅内存存储 · src/legacy/ 未动
200
- ```
201
-
202
- 用户只输入了任务本身和"批准,开始"。流水线是路由表查表的结果;执行在
203
- 计划获批前一步不动;每次交接都是结构化骨架——零文件仪式。
204
-
205
- ### 桌面版专属特性
206
-
207
- 在 **OpenCode 桌面版** 中,你还能获得额外的 UX 体验:
208
-
209
- - 🎨 **Agent 颜色标识** — 每个 Agent 在聊天 UI 中有独立颜色,便于识别
210
- - 📋 **Agent 选择器** — 点击 Agent 下拉菜单,可视化切换团队 Agent
211
- - 🔀 **并行子任务** — Team Lead 可同时调度多个子 Agent,结果在并行面板中展示
212
- - 📊 **会话历史** — 所有团队交互都保存在桌面版侧边栏,可搜索回溯
213
-
214
- ---
215
-
216
- ## 🧯 上下文治理(tm_* + R6 + R2)—— v1.5.1 起提供
217
-
218
- > ⚠️ 需 `@te-river/opencode-team-mode@1.5.1` 或更新(2026-09-08 发布)。
219
- > 配置里钉 `@latest` 的用户,下次启动自动升级。
220
-
221
- **JIT 层 2 工具(`tm_read` / `tm_grep` / `tm_bash` / `tm_fetch`)。**
222
- 大体积工具输出是上下文成本的主要来源:智能体每走一步都要重发整个窗口。
223
- tm_* 工具先用受治理的管线执行内置能力:超过 `TM_OFFLOAD_THRESHOLD`
224
- token 的结果**不进窗口**——全量写入本地 run 存储,模型只拿一张句柄
225
- “提货单”,附内容感知预览(JSON 键结构 / CSV 表头+形状 / 日志
226
- ERROR×N 统计 / 代码签名清单 / 二进制元信息,硬上限 80 token)。
227
- 确实需要全文时,用 HMAC 签名、限本 run、带有效期的句柄经 `tm_fetch`
228
- 分段取回。`tm_bash` 仅放行只读命令白名单,失败以结构化错误返回。
229
-
230
- **R6 环境变量保护(现已升级为审批门控)。** TeamMode 激活时,模型无法
231
- 静默读取环境变量。env 导出命令(`printenv`、`env`、`Get-ChildItem env:`
232
- 等)与环境文件(`.env`、shell rc 文件)会走 OpenCode **官方确认弹窗**:
233
- 你会在桌面收到一次原生确认,超过 `TM_ASK_TIMEOUT_MIN`(默认 10 分钟)
234
- 无人响应即**自动拒绝**——插件超时只会拒绝,绝不为模型自我放行。通配符
235
- 表达不了的形态(命令里内嵌的 `$VAR` / `${VAR}` / `$env:`、命令替换、
236
- 子 shell/转义写法)以及 `tm_*` 包装通道仍维持**代码级硬拦**(没有弹窗
237
- 可钻)。tm_* 包装工具同样过这套检查(不给包装层留后门)。审计日志只记
238
- 工具名 + 模式类别 + 裁决事件(`ask` / `allowed-once` / `allowed-always` /
239
- `rejected` / `timeout-rejected` / `degraded`)——绝不记录命令文本、路径、
240
- 变量名或值。
241
-
242
- **R2 危险操作(同一个确认弹窗)。** 删除(`rm`/`del`/`Remove-Item`/
243
- `rmdir`)、git 发布(`git push`/`git commit`)、网络(`curl`/`wget`/
244
- `Invoke-WebRequest`/`Invoke-RestMethod`)、包安装与发布(`npm install`/
245
- `npm publish`/`pip install`/`winget`/`choco`)、进程/系统(`taskkill`/
246
- `Stop-Process`/`kill`/`shutdown`/`format`)、权限(`chmod`/`takeown`/
247
- `icacls`)——都不再静默放行,而是弹同一个官方确认框,超时未响应即自动
248
- 拒绝。日常验证栈(`npm test`、`tsc`、`git status`/`diff`)**不在**门控
249
- 之列,团队协作照常无打扰运行。
250
-
251
- > ⚠️ **批准弹窗时请选 once(仅此一次),不要选 always。** 真实宿主实测:
252
- > always 记录的泛化规则远比当次命令宽——对 `Get-ChildItem env:PATH` 选
253
- > always 会记下 `Get-ChildItem *`,此后所有 `Get-ChildItem` 都不再弹窗。
254
- > 只有 once 能让每次危险操作继续单独过人手。
255
-
256
- > 延后是**按会话**生效的:只有运行 TeamMode 注入角色的会话(或已弹过这类
257
- > 确认框的会话)里的 env 读取才会被放行给弹窗;其他会话(如原生
258
- > `build`/`plan`)里守护仍然直接硬拦——那里根本没有弹窗兜底。宿主对复合
259
- > 命令(`a; b`)按段评估、单次弹窗批准整条;任一子段是 env 读取时守护整条
260
- > 拦截。
261
-
262
- > 权限协议已在真实 `opencode serve` 宿主(1.18.29)上经 SSE 事件捕获实测
263
- > 核验;桌面弹窗的渲染本身仍需在真实 Desktop 会话里目视确认一次。非交互
264
- > `opencode run` 下,无人应答的 `ask` 会被立即自动拒绝(没有人类可弹)。
265
-
266
- | 环境变量 | 默认 | 作用 |
267
- |---|---|---|
268
- | `TM_ENV_PROTECT` | `strict` | R6 模式:`strict` / `standard` / `off`(off 同时解除审批计时器) |
269
- | `TM_ASK_TIMEOUT_MIN` | `10` | R6/R2 确认弹窗无人应答后自动拒绝的分钟数;最小 3 分钟(宿主的 `permission.replied` 经事件总线到达插件约延迟 ~120 秒——更小的值会把刚获批的请求误拒) |
270
- | `TM_ENV_PROTECT_EXTRA_DENY` | — | 追加拦截正则(分号分隔;始终硬拦,不走弹窗) |
271
- | `TM_OFFLOAD_THRESHOLD` | `2000` | 卸载阈值(token,chars/4 估算) |
272
- | `TM_PREVIEW_MAX_TOKENS` | `80` | 预览硬上限 |
273
- | `TM_FETCH_MAX_LINES` | `2000` | tm_fetch 单段上限 |
274
- | `TM_BLACKBOARD_DIR` | `.blackboard/` | 卸载载荷存储 |
275
- | `TM_TRAJECTORY_DIR` | `.trajectory/` | 只追加工具调用账本 |
276
- | `TM_BLACKBOARD_TTL` | `7` | 存储保留天数 |
277
- | `TM_BASH_READONLY_ALLOWED` | 内置表 | tm_bash 只读白名单 |
278
- | `TM_PTC_MAX_PROGRAM_CHARS` | `4000` | PTC 程序源码长度上限(字符) |
279
- | `TM_PTC_MAX_CALLS` | `20` | PTC 单次运行桥接调用数上限(1–200) |
280
- | `TM_PTC_MAX_ERRORS` | `3` | PTC 单次运行错误数上限(1–50) |
281
- | `TM_PTC_TIMEOUT_MS` | `60000` | PTC 单次运行墙钟超时(5 秒–10 分钟) |
282
- | `TM_PTC_ENGINE` | `auto` | PTC 引擎:`auto`(worker→inline 降级)/ `worker` / `inline` |
283
-
284
- ---
285
-
286
- ## ⚡ 批量编排(`tm_ptc_run`)—— v1.5.2 起提供
287
-
288
- > 已随 **v1.5.2**(2026-09-10)发布。需 `@te-river/opencode-team-mode@1.5.2` 或更新。
289
-
290
- `tm_ptc_run` 让专家代理编写**一个异步程序**,在单次回合中执行 N 次受治理的
291
- `tm_*` 调用——运行期间零 LLM 往返,仅将聚合摘要返回上下文。设计用于批量
292
- 只读任务:多文件侦察、批量 grep + read 聚合、交叉引用搜索结果。
293
-
294
- ### 工作原理
295
-
296
- 代理使用 `tm.read(args)`、`tm.grep(args)`、`tm.bash(args)`、`tm.fetch(args)`
297
- 编写程序体——参数与四个受治理工具相同。每次调用返回 `{ok:true, data}`(已受
298
- 治理:内联文本或卸载句柄)或 `{ok:false, error:{tool,phase,line?,message}}`。
299
- 程序 `return` 一个值;它会被 JSON 序列化进聚合摘要。
300
-
301
- 包含 `require`、`import`、`process`、`globalThis`、`Deno`、`Bun`、`fs`、`net`
302
- 或 `child_process` 的程序会在执行前被拒绝(静态预扫描,辅助防护)。
303
-
304
- ### 预算(仅收紧)
305
-
306
- 调用方可收紧 `max_calls`、`max_errors` 和 `timeout_ms`——超过 `TM_PTC_*` 上限
307
- 的值会被钳制到上限;低于下限的值会被钳制到下限。触达任一预算即整体停止运行;
308
- 已产出的输出不会丢失。
309
-
310
- ### 引擎(`TM_PTC_ENGINE`)
311
-
312
- | 模式 | 行为 |
313
- |---|---|
314
- | `auto`(默认) | 优先尝试 `worker_threads`;失败时降级为 `node:vm`,摘要标记 `degraded-engine` |
315
- | `worker` | 强制使用 worker 引擎(失败时返回 engine-error) |
316
- | `inline` | 强制使用 `node:vm` 引擎(30 秒编译超时斩杀同步忙等;await 间隙残余已记录) |
317
-
318
- worker 引擎在专用线程中运行程序,`env:{}` 清空 process.env、`resourceLimits`
319
- 限量、硬墙钟 `terminate()`。所有治理(P2 路径范围、P3 白名单、R6、阈值卸载、
320
- TTL)对每次桥接调用生效——PTC 不是绕过层。
321
-
322
- ### 访问权限
323
-
324
- 五个专家代理(`implementer`、`tester`、`architect`、`reviewer`、`researcher`)
325
- 的白名单中包含 `tm_ptc_run`。`team` lead 不包含——它负责编排,不运行批量程序。
326
-
327
- ---
328
-
329
- ## 🏗️ 架构
330
-
331
- ```
332
- opencode-team-mode/
333
- ├── package.json ← npm 包定义
334
- ├── tsconfig.json ← TypeScript 配置
335
- ├── src/
336
- │ ├── index.ts ← 插件入口(server():config + R6 tool.execute.before + 审批门 event 钩子 + tool 段)
337
- │ ├── agents.ts ← Agent 定义(prompts、模式、颜色)
338
- │ ├── commands.ts ← 命令定义(模板、Agent 绑定)
339
- │ ├── blackboard.ts ← 共享黑板 + TTL 自动清理清扫器
340
- │ ├── envprotect.ts ← R6 环境变量读取保护 + R2 确认弹窗模式集(弹窗 vs 硬拦)
341
- │ ├── approval-gate.ts ← 统一审批门:官方弹窗超时自动拒绝(绝不自我放行)
342
- │ ├── tm/ ← JIT 层 2 工具(tm_read / tm_grep / tm_bash / tm_fetch / tm_ptc_run)
343
- │ └── types.ts ← 加载器契约类型定义(1.18.x)
344
- ├── scripts/
345
- │ ├── install.sh ← 一键安装脚本(bash)
346
- │ └── install.ps1 ← 一键安装脚本(PowerShell)
347
- ├── pt07/ ← PT-07 基线任务集(种子化 A/B token 测量)
348
- ├── LICENSE ← Apache 2.0
349
- └── README.md ← 英文文档
350
- README.zh-CN.md ← 中文文档
351
- ```
352
-
353
- ### 工作原理
354
-
355
- 1. OpenCode 桌面版启动,加载 `opencode.json(c)`
356
- 2. 检测到 `plugin` 数组中的 `"@te-river/opencode-team-mode@latest"`,加载 npm 包
357
- 3. 加载器调用插件的 `server(input, options)`,注册 `config` hook;hook 向合并后的配置注入 6 个 Agent 和 6 个命令。同一次调用还会安装 R6 的 `tool.execute.before` 防护、武装 R6/R2 统一审批门(官方确认弹窗 + `TM_ASK_TIMEOUT_MIN` 超时自动拒绝,经 `event` 钩子驱动),并注册受治理的 `tm_*` 工具(见下文“上下文治理”)
358
- 4. 插件的 `id: "team-mode"` 作为插件名显示在桌面版 UI
359
- 5. Agent 和命令立即在桌面版 UI 中可用 —— 无需复制任何文件;同名 Agent 以用户自定义优先(插件绝不覆盖)
360
-
361
- ---
362
-
363
- ## 🗂️ 协作机制:结构化交接优先,文件其次(混合制)
364
-
365
- 子代理之间无法实时互发消息(平台限制),TeamMode 通过**结构化回复骨架**协调它们,
366
- 文件黑板只保留给超大产出:
367
-
368
- - **回复骨架(主通道)**:每个专家的最终回复以
369
- `STATUS: / CHANGES: / FINDINGS: / EVIDENCE: / HANDOFF:` 开头,全文 ≤50 行。
370
- 这个尺寸的产出直接内联传递——零文件 I/O,没有"文件没写上"这种故障面。
371
- Lead 把 `HANDOFF` 原文转贴进下一次派单,并对骨架做机器校验
372
- (缺失 → 带 skeleton 原文重试一次 → 仍违规则降级记入报告)。
373
- - **黑板文件(仅例外)**:完整产出确实超过 ~50 行时(如完整架构设计文档),
374
- 派单点名唯一文件:
375
- `<repo>/.git/opencode-team/<session-key>/<task-slug>/NN-<role>-<topic>.md`
376
- ——位于 `.git/` 内,**绝不污染**工作区和 commit(非 git 工作区回退系统临时目录)。
377
- 写入即冻结:修订 = 新的轮次后缀文件(`…-r2.md`);会话目录层让新对话
378
- 不会撞上尚未清扫的旧黑板。
379
- - **没有 MANIFEST.md**:lead 的状态记忆就是它的 todo list。
380
- - **反馈闭环**:Critical/Major 发现和产品 bug 自动转化为跟踪的修复任务,
381
- 直到交付物收敛(最多 2 轮,之后升级给用户)。
382
-
383
- ### 确定性路由、审批门与自适应评审(v1.4.7)
384
-
385
- - **路由表**:lead 按任务形状查固定流水线行——提问 → 直接回答;纯文档 →
386
- implementer;产品行为变更 → implementer → tester → reviewer;多模块/跨接口
387
- 功能 → architect → implementer → tester → reviewer(s);未知外部技术 →
388
- researcher 前置。流水线有固定下限:产品变更路由到少于 3 次派发即是路由 bug;
389
- 把一个请求拆成多个 <2 派发的子任务以规避审批门 = 协议违规。
390
- - **审批门(按计数触发)**:预计派发 ≥2 → lead 先调研(亲自读仓库;仅未知外部
391
- 技术才派 researcher),呈交 ≤30 行计划,然后**等待你的批准**才执行任何东西。
392
- 0-1 次派发的小任务以 1-2 行通报直接开工。执行中发现需要第 2 次派发 →
393
- 暂停等批准。阻塞性不确定**立即批量问一次**——不猜测、不挤牙膏。
394
- - **自适应评审**:默认 1 个 reviewer 派单(correctness 维度);仅高风险画像
395
- ——鉴权/安全面、跨模块数据契约、≥3 文件的公共 API 变更——才升级为
396
- 3 维并行(完整性 / 正确性 / 影响面)。
397
- - **静态验证**:tester 通过构建、类型检查、静态分析、API/单元测试验证。
398
- 禁止即兴发明浏览器自动化(headless 截图、DOM stub);用户可见前端改动
399
- 以 `UI NOT VERIFIED: <待人工检查项>` 如实收尾,除非项目本身已带真实
400
- 浏览器测试设施。
401
- - **无仪式捷径**:lead 已亲自验证的根因(file:line 证据)直接变成修复规格
402
- 派给 implementer——调查性派单服务于未知,不服务于仪式感。
403
- - **简明纪律**:路由选择是查表;用户可见的计划性文字 ≤5 行。
404
- - **证据标准(保留)**:"完成 / 修复 / 通过"的声明必须附可验证证据——命令
405
- 输出、日志、diff。纯叙述只是进度说明,不是证明。
406
- - **逐字契约(保留)**:需要互通的并行实现代理,其数据契约(端点、字段名、
407
- 类型)逐字贴进每个相关派单——契约错配是集成 bug 之首。
408
- - **文档同步(CHANGELOG + AGENTS.md)**:交付的改动在 CHANGELOG.md 存在时按
409
- Keep a Changelog 风格追加条目;当改动会影响 AGENTS.md 所记录的内容
410
- (构建/测试命令、约定、项目结构、agent 指引)时同步更新它;任一文件缺失
411
- 时提议代建。阅读去重:README 由 lead 亲自阅读(宿主不会注入);
412
- AGENTS.md/CLAUDE.md 若宿主已注入则直接使用上下文中的副本——仅在确实缺失时
413
- 才打开文件;专家不会自己去重读这些文档——约定由 lead 蒸馏进派单。
414
-
415
- ### Triage —— 提问不会变成代码修改
416
-
417
- Team Lead 对每条消息先分类再行动:咨询/提问只得到回答(零文件改动,发现缺陷
418
- 仅**提议**修复并等待你放行);只有明确的行动指令才进入工作流。并且一旦你写明
419
- 了哪些能碰哪些不能碰,**这些边界高于一切规则**——lead 会在每次派发中原样重申。
420
-
421
- ### 清理 —— 只有 TTL 清扫器一条路
422
-
423
- | 责任方 | 时机 |
424
- |---|---|
425
- | 插件代码(进程内清扫器) | 启动时 + 每小时:清除空闲超过 **TTL** 的任务目录 |
426
-
427
- Team Lead 不再删除任务目录 —— 跑完的黑板原地留给你回看审计;回收由纯代码
428
- 完成,从不依赖模型"记得删",崩溃/强杀留下的残骸同样会被清扫。清扫器对活跃
429
- 会话内的过期任务逐个回收,对整个闲置的会话目录一次性收走。TTL 可用
430
- `ttlDays` 调节。
431
-
432
- ### 自定义 TTL
433
-
434
- 默认为 **5 天**。想自定义,在 `opencode.jsonc` 中使用元组形式的插件声明:
435
-
436
- ```jsonc
437
- {
438
- "$schema": "https://opencode.ai/config.json",
439
- "plugin": [
440
- ["@te-river/opencode-team-mode@latest", { "ttlDays": 7 }]
441
- ]
442
- }
443
- ```
444
-
445
- `ttlDays` 接受 `(0, 365]` 内的天数;非法值静默回退到 5 天。
446
-
447
- ### 默认代理
448
-
449
- TeamMode 默认**把 Team 设为你的默认代理**——新会话直接由团队调度者接管。
450
- 占默认槽附带一个排序效应:选择器会把**默认代理钉在第一位**、其余按名称
451
- 字母升序,所以顺序为 **team, build, plan**。(想让 Team 排在 Plan 之下?
452
- 那必须放弃默认槽——见下方退出开关;按服务端的排序规则二者不可兼得。)
453
-
454
- 不想占用默认代理槽(`build` 保持默认,顺序 **build, plan, team**)则退出:
455
-
456
- ```jsonc
457
- {
458
- "plugin": [
459
- ["@te-river/opencode-team-mode@latest", { "defaultAgent": false }]
460
- ]
461
- }
462
- ```
463
-
464
- 用户显式配置的非 `build` 默认代理永远原样保留——插件从不覆写。
465
-
466
- **升级提示**:v1.4.4 曾短暂改为 opt-in(默认不占用);v1.4.5 恢复
467
- Team-as-default 出厂行为。若你在 v1.4.4 期间加过 `{ "defaultAgent": true }`,
468
- 现在可以删掉该选项(或改为 `false` 主动退出)。
469
-
470
- ---
471
-
472
- ## 🔧 自定义
473
-
474
- ### Team Lead 的模型最关键
475
-
476
- Lead 是编排大脑:它给每条消息分类、按路由表查流水线、写每份派单、裁决
477
- reviewer/tester 的发现、合成最终交付。这里的质量问题会**沿流水线放大**——
478
- 平庸的 Lead 拆错任务、给专家的指令含糊、放走劣质产出;没有任何专家能
479
- 救回一份从一开始就派错的工单。
480
-
481
- 所以:自定义模型时**Lead 位上请放你负担得起的最强模型**。其他角色可以用便宜模型——
482
- 它们拿到的指令书精确、阅读范围受限,容错更高。按 agent 钉模型:
483
-
484
- ```jsonc
485
- {
486
- "agent": {
487
- // Team Lead —— 编排值得最好的模型
488
- "team": { "model": "anthropic/claude-opus-4-5" },
489
- // 专家角色 —— 便宜一档通常够用
490
- "implementer": { "model": "anthropic/claude-sonnet-4-6" }
491
- }
492
- }
493
- ```
494
-
495
- (以上模型 ID 仅为示例,换成你服务商实际提供的即可。你自定义的
496
- `agent.team` 永远优先于插件注入的版本。)
497
-
498
- ### 覆盖某个 Agent
499
-
500
- 在 `opencode.json` 中添加同名 Agent —— 你的定义会优先生效:
501
-
502
- ```jsonc
503
- {
504
- "agent": {
505
- "reviewer": {
506
- "model": "anthropic/claude-sonnet-4-6",
507
- "prompt": "你是一个极其严格的审查员。任何 lint 警告都必须打回。"
508
- }
509
- }
510
- }
511
- ```
512
-
513
- ### 添加自己的 Agent
514
-
515
- TeamMode 不阻止你添加更多 Agent,与团队 Agent 并存:
516
-
517
- ```jsonc
518
- {
519
- "agent": {
520
- "devops": {
521
- "mode": "subagent",
522
- "description": "处理 CI/CD、Docker 和部署任务",
523
- "prompt": "你是 DevOps 工程师..."
524
- }
525
- }
526
- }
527
- ```
528
-
529
- ### 禁用某个 Agent
530
-
531
- ```jsonc
532
- {
533
- "agent": {
534
- "researcher": { "disable": true }
535
- }
536
- }
537
- ```
538
-
539
- ---
540
-
541
- ## 📦 发布到 npm
542
-
543
- 如果你想发布自己的 fork:
544
-
545
- ```bash
546
- npm run build # 编译 TypeScript → dist/
547
- npm version patch # 更新版本号
548
- npm publish # 发布到 npm 仓库
549
- ```
550
-
551
- ---
552
-
553
- ## 🤝 贡献
554
-
555
- 欢迎贡献!以下方向特别需要帮助:
556
-
557
- - 🌐 **本地化** — 将 Agent prompt 翻译为其他语言
558
- - 🎨 **更多 Agent 角色** — DevOps、DBA、安全专家、UX 设计师
559
- - 🔧 **更多命令** — `/team-deploy`、`/team-docs`、`/team-refactor`
560
- - 📝 **更好的 Prompt** — 通过 Prompt 工程优化 Agent 行为
561
-
562
- ---
563
-
564
- ## 📄 许可证
565
-
566
- [Apache License 2.0](./LICENSE)
567
-
568
- ---
569
-
570
- ## 🔗 链接
571
-
572
- - [npm 包](https://www.npmjs.com/package/@te-river/opencode-team-mode) — `@te-river/opencode-team-mode`
573
- - [OpenCode 桌面版](https://opencode.ai) — 官网 & 下载
574
- - [OpenCode 文档](https://opencode.ai/docs) — 配置 & 插件文档
575
- - [OpenCode 插件 API](https://opencode.ai/docs/plugins) — 构建你自己的插件
576
- - [OpenCode GitHub](https://github.com/anomalyco/opencode) — OpenCode 源码
1
+ # OpenCode TeamMode
2
+
3
+ **[English](./README.md)** | **[中文](./README.zh-CN.md)**
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@te-river/opencode-team-mode.svg)](https://www.npmjs.com/package/@te-river/opencode-team-mode)
6
+ [![npm downloads](https://img.shields.io/npm/dm/@te-river/opencode-team-mode.svg)](https://www.npmjs.com/package/@te-river/opencode-team-mode)
7
+ [![license](https://img.shields.io/npm/l/@te-river/opencode-team-mode.svg)](./LICENSE)
8
+
9
+ > 🤝 **[OpenCode 桌面版](https://opencode.ai) 多 Agent 团队协作插件**
10
+ >
11
+ > 为你的 OpenCode 桌面版添加一整支 AI 专家团队 —— 架构师、实现者、审查员、测试员、调研员,由 Team Lead 统一调度,通过简单的斜杠命令即可调用。
12
+
13
+ ---
14
+
15
+ ## ✨ TeamMode 是什么?
16
+
17
+ TeamMode 将 OpenCode 桌面版从一个单 Agent 编码助手,升级为**一整个开发团队**。每个 Agent 拥有独立的角色定位、专业领域和行为风格 —— 就像真实的工程团队。
18
+
19
+ 不再是一个 Agent 包揽所有事,你将获得:
20
+
21
+ | Agent | 角色 | 使用场景 |
22
+ |---|---|---|
23
+ | 🎯 **Team Lead** | 调度者 | 需要规划 + 多步执行的复杂任务 |
24
+ | 🏗️ **Architect** | 系统设计师 | 设计文档、模块结构、API 契约 |
25
+ | 💻 **Implementer** | 代码实现者 | 编写生产代码、实现功能 |
26
+ | 🔍 **Reviewer** | 单维审查员 | 单维度审查(完整性 / 正确性 / 影响面)——默认 1 路;仅高风险变更升级为 3 路并行 |
27
+ | 🧪 **Tester** | 测试工程师 | 单元测试、集成测试、边界覆盖、静态验证(构建 / 类型检查 / lint / API 测试) |
28
+ | 🔎 **Researcher** | 知识调研员 | 本地仓库调研优先(代码、配置、已安装依赖、随包文档);联网经用户 MCP 工具或受治理的 `tm_webfetch`——与 Team Lead 并列的两个网络角色之一 |
29
+
30
+ ---
31
+
32
+ ## 🚀 快速开始
33
+
34
+ ### 前置条件
35
+
36
+ 1. **安装 OpenCode 桌面版**(如果还没有):
37
+
38
+ | 平台 | 安装命令 |
39
+ |---|---|
40
+ | macOS (Apple Silicon) | `brew install --cask opencode-desktop` |
41
+ | macOS (Intel) | `brew install --cask opencode-desktop` |
42
+ | Windows | `scoop bucket add extras && scoop install extras/opencode-desktop` |
43
+ | Linux | 从 [opencode.ai/download](https://opencode.ai/download) 下载 |
44
+
45
+ 或安装 **CLI/TUI** 版本:
46
+ ```bash
47
+ # 一键脚本(全平台)
48
+ curl -fsSL https://opencode.ai/install | bash
49
+
50
+ # 或通过 npm
51
+ npm install -g opencode-ai
52
+ ```
53
+
54
+ 2. **Node.js ≥ 18**(用于 npm)
55
+
56
+ ### 安装 TeamMode
57
+
58
+ **方式 A — 一键安装脚本:**
59
+
60
+ macOS / Linux(bash):
61
+ ```bash
62
+ curl -fsSL https://ghproxy.net/https://raw.githubusercontent.com/Te-River/Opencode-TeamMode/main/scripts/install.sh | bash
63
+ ```
64
+
65
+ Windows(PowerShell):
66
+ ```powershell
67
+ irm https://ghproxy.net/https://raw.githubusercontent.com/Te-River/Opencode-TeamMode/main/scripts/install.ps1 | iex
68
+ ```
69
+
70
+ **方式 B — 手动配置:**
71
+
72
+ 在你的 `opencode.jsonc` 中添加插件:
73
+
74
+ ```jsonc
75
+ {
76
+ "$schema": "https://opencode.ai/config.json",
77
+ "plugin": [
78
+ "@te-river/opencode-team-mode@latest"
79
+ ]
80
+ }
81
+ ```
82
+
83
+ OpenCode 启动时会自动安装插件。
84
+
85
+ > **提示:** 修改 `opencode.json` 后,**重启 OpenCode Desktop** 使配置生效。
86
+
87
+ ---
88
+
89
+ ## ⚙️ 配置
90
+
91
+ 插件会在 OpenCode 启动时自动注入所有团队 Agent 和命令,**无需手动复制任何 Agent 文件或命令定义**。
92
+
93
+ > ⚠️ **模型选择很重要。** 工作流里的每一个判断——分诊、拆解、派单、
94
+ > 整合、审查/测试闭环裁决——都经过 **Team Lead**。这个位置上放弱模型,
95
+ > 专家再强也救不回整条流水线。如需自定义,还请给你的 `team` agent 钉上你能负担的最强
96
+ > 推理模型(配方见下方「自定义」节)。
97
+
98
+ ### 全局安装(所有项目生效)
99
+
100
+ 要在所有项目中启用 TeamMode,将插件添加到全局配置:
101
+
102
+ ```jsonc
103
+ // ~/.config/opencode/opencode.jsonc
104
+ {
105
+ "$schema": "https://opencode.ai/config.json",
106
+ "plugin": [
107
+ "@te-river/opencode-team-mode@latest"
108
+ ]
109
+ }
110
+ ```
111
+
112
+ ---
113
+
114
+ ## 📖 使用方法
115
+
116
+ ### 斜杠命令
117
+
118
+ TeamMode 为 OpenCode 添加了六个斜杠命令,在聊天输入框中输入:
119
+
120
+ | 命令 | Agent | 说明 |
121
+ |---|---|---|
122
+ | `/team-plan <任务>` | Architect | 创建详细的实现计划:架构、文件清单、任务拆解 |
123
+ | `/team-implement <任务>` | Implementer | 为功能或任务编写生产代码 |
124
+ | `/team-review [范围]` | Reviewer | 审查代码的 Bug、安全问题和质量问题 |
125
+ | `/team-test [范围]` | Tester | 生成全面的测试,覆盖边界场景 |
126
+ | `/team-research <主题>` | Researcher | 本地仓库调研优先;联网走受治理的 `tm_browser` / `tm_webfetch`(先),再用户 MCP 工具 |
127
+ | `/team-run <任务>` | Team Lead | **完整工作流** — 端到端调度所有 Agent |
128
+
129
+ #### 示例工作流
130
+
131
+ ```bash
132
+ # 1. 规划功能
133
+ /team-plan 添加基于 OAuth2 和 JWT 的用户认证
134
+
135
+ # 2. 审查计划后,开始实现
136
+ /team-implement 按计划实现认证模块
137
+
138
+ # 3. 审查代码
139
+ /team-review src/auth/
140
+
141
+ # 4. 编写测试
142
+ /team-test src/auth/
143
+
144
+ # 或者让 Team Lead 全程调度:
145
+ /team-run 添加基于 OAuth2 和 JWT 的用户认证
146
+ ```
147
+
148
+ ### Agent 选择器
149
+
150
+ 你也可以在 OpenCode 桌面版中使用 `@` 直接调用 Agent:
151
+
152
+ - `@team` — 调度复杂任务
153
+ - `@architect` — 设计系统或模块
154
+ - `@implementer` — 编写代码
155
+ - `@reviewer` — 审查代码质量
156
+ - `@tester` — 编写测试
157
+ - `@researcher` — 调研主题
158
+
159
+ ### 演示
160
+
161
+ 以下是一段会话实录的还原。Team 出厂即默认代理(退出方法见下方配置),
162
+ 用户开新会话直接输入:
163
+
164
+ > **用户:** 给我们的 Express API 加令牌桶限流——每用户每分钟 100 请求,
165
+ > 超限返回 429。不要动 `src/legacy/` 下的任何东西。
166
+
167
+ ```text
168
+ team 路由:产品行为变更 → implementer → tester → reviewer
169
+ (3 次派发 → 触发审批门)
170
+
171
+ 调研:已读 README、src/app.ts、src/middleware/*
172
+ 阻塞性问题:无 —— 1 条假设列在下方
173
+
174
+ 计划
175
+ 目标:令牌桶限流,100 请求/分/用户,429 + Retry-After
176
+ 范围:src/middleware/rateLimit.ts(新增)、src/app.ts(+3 行)
177
+ 流水线:implementer → tester → reviewer(correctness)
178
+ 假设:内存桶而非 Redis —— 要改说一声
179
+ 边界:src/legacy/** 不动
180
+ 批准后开工?
181
+
182
+ 用户 批准,开始
183
+
184
+ team ▸ @implementer — STATUS: done
185
+ CHANGES: src/middleware/rateLimit.ts(新增)· src/app.ts(+3)
186
+ HANDOFF: bucket {tokens, lastRefill};refill() 单次原子完成
187
+ EVIDENCE: tsc 无错误(输出见上)
188
+
189
+ ▸ @tester — STATUS: done · VERDICT: pass(14/14)
190
+ FINDINGS: 覆盖突发边界、窗口过期、并发回充;
191
+ src/legacy/** 逐字节未变
192
+ EVIDENCE: vitest 14 passed
193
+
194
+ ▸ @reviewer — STATUS: done · VERDICT: approve(correctness)
195
+ FINDINGS: 无 Critical/Major;1 条 Minor(日志噪音)已记录
196
+
197
+ team 完成。
198
+ 限流器已交付:rateLimit.ts(新增)· app.ts(+3)· 14 测试全绿
199
+ 审查:通过 · 假设:仅内存存储 · src/legacy/ 未动
200
+ ```
201
+
202
+ 用户只输入了任务本身和"批准,开始"。流水线是路由表查表的结果;执行在
203
+ 计划获批前一步不动;每次交接都是结构化骨架——零文件仪式。
204
+
205
+ ### 桌面版专属特性
206
+
207
+ 在 **OpenCode 桌面版** 中,你还能获得额外的 UX 体验:
208
+
209
+ - 🎨 **Agent 颜色标识** — 每个 Agent 在聊天 UI 中有独立颜色,便于识别
210
+ - 📋 **Agent 选择器** — 点击 Agent 下拉菜单,可视化切换团队 Agent
211
+ - 🔀 **并行子任务** — Team Lead 可同时调度多个子 Agent,结果在并行面板中展示
212
+ - 📊 **会话历史** — 所有团队交互都保存在桌面版侧边栏,可搜索回溯
213
+
214
+ ---
215
+
216
+ ## 🧰 受治理工具与安全
217
+
218
+ TeamMode 新增的每一个工具都跑在同一条治理管线上:超过 `TM_OFFLOAD_THRESHOLD`
219
+ token 的输出绝不进入上下文——全量卸载到 run 存储,只回传内容感知预览 +
220
+ HMAC 签名句柄,agent 确实需要全文时经 `tm_fetch` 分页取回。安全、记忆与
221
+ 联网能力在 v1.5.1–v1.5.6 间陆续交付,历史见 [CHANGELOG.md](./CHANGELOG.md)。
222
+
223
+ | 工具 | 作用 | 角色 |
224
+ |---|---|---|
225
+ | `tm_read` / `tm_grep` / `tm_bash` / `tm_fetch` | 受治理的文件读取 / 正则搜索(宿主索引)/ 只读 shell(白名单)/ 句柄分页取回 | 全部六个 Agent |
226
+ | `tm_memory` | 项目记忆库(Markdown + frontmatter):add / search / list / forget | 全部六个 Agent |
227
+ | `tm_webfetch` | 单个白名单页面的受治理 GET | Lead + Researcher |
228
+ | `tm_browser` | 交互式浏览器会话(有头 CDP):open / navigate / read / screenshot / close | Lead + Researcher |
229
+ | `tm_ptc_run` | 批量编排:一个程序、N 次受治理调用、零 LLM 往返 | 全部六个 Agent |
230
+
231
+ > **固定工具优先级梯子(所有任务):① TeamMode 受治理工具(`tm_*`)→
232
+ > ② 用户 MCP/插件工具 → ③ 模型自行推理(能力缺失按缺口上报,绝不伪装)。**
233
+ > 梯子同时是回退链:受治理工具报错(本机无浏览器、主机被拦)时,Agent
234
+ > 会如实说明并落到下一级,而不是放弃。
235
+
236
+ 所有 Agent 都被要求把每次查询路由到这些工具——先扫描工具面、规划具体
237
+ 调用,再把口语化/缩写/别名称呼展开为规范名、两种写法都查——而不是凭
238
+ 记忆作答或伪装被移除工具的输出。
239
+
240
+ ### 上下文治理:卸载、句柄、预览
241
+
242
+ **JIT 层 2 工具(`tm_read` / `tm_grep` / `tm_bash` / `tm_fetch`)。**
243
+ 大体积工具输出是上下文成本的主要来源:智能体每走一步都要重发整个窗口。
244
+ tm_* 工具先用受治理的管线执行内置能力:超过 `TM_OFFLOAD_THRESHOLD`
245
+ token 的结果**不进窗口**——全量写入本地 run 存储,模型只拿一张句柄
246
+ “提货单”,附内容感知预览(JSON 键结构 / CSV 表头+形状 / 日志
247
+ ERROR×N 统计 / 代码签名清单 / 二进制元信息,硬上限 80 token)。
248
+ 确实需要全文时,用 HMAC 签名、限本 run、带有效期的句柄经 `tm_fetch`
249
+ 分段取回。`tm_bash` 仅放行只读命令白名单,失败以结构化错误返回。
250
+ 所有 Agent 都被要求把每次查询优先路由到这些工具——先扫描自己的工具面、
251
+ 规划具体调用,再把口语化/缩写/别名称呼展开为规范名、两种写法都查——
252
+ 而不是凭记忆作答或伪装被移除工具的输出。
253
+
254
+ ### 项目记忆(tm_memory)
255
+
256
+ **项目记忆(`tm_memory`)——全部 Agent 可用。** 跨会话持久的项目事实
257
+ (构建命令、环境怪癖、架构决策、长期有效的用户约定)以带 frontmatter 的
258
+ Markdown 文件存放在同一个 git 感知存储里
259
+ (`<repo>/.git/opencode-team/memories/<项目slug>/<分类>/`)——人类可直接
260
+ 编辑,绝不进你的工作树。动作:`add` / `search`(确定性关键词评分,取前
261
+ 5)/ `list` / `forget`;单条内容上限 4000 字符——任务状态归 todo list,
262
+ 超长文档归黑板文件。所有 Agent 都被要求:在凭空假设项目约定之前先
263
+ search,踩过坑后把结论 add 给下一次会话。
264
+
265
+ ### 联网访问(tm_browser + tm_webfetch)——仅网络角色
266
+
267
+ 1. **受治理联网工具。** `tm_browser`——交互式浏览器会话,经 CDP 管道协议
268
+ 驱动**你本机的 Chromium 系浏览器**(Windows 优先探测 Edge)有头运行:
269
+ open → navigate → read(页面正文,与 tm_read 同阈值治理)→ screenshot
270
+ (PNG 落 run store,进上下文的只有路径)→ close。隔离临时配置(绝不碰
271
+ 你的真实配置);**域名白名单在网络层逐请求强制**(CDP
272
+ `Fetch.requestPaused`——白名单外主机直接 `BlockedByClient`)。无显示器
273
+ 的 Linux 主机自动转无头;`TM_BROWSER_HEADLESS` 可强制,`TM_BROWSER_PATH`
274
+ 可指定可执行文件。`tm_webfetch`——单个白名单页面的受治理 GET。两者与
275
+ 所有 tm_* 工具走同一套治理(阈值卸载 + 内容感知预览 + `tm_fetch`
276
+ 句柄),网页永远冲不爆上下文。
277
+ 2. **用户 MCP/插件工具。** 用户配置的 MCP 服务器提供的浏览器自动化、搜索、
278
+ 抓取类工具,作为受治理工具覆盖不到时的回退,白名单不干预。
279
+ 3. 其余四个角色(architect / implementer / reviewer / tester)**没有**
280
+ 网络授权——联网问题按缺口上报,绝不伪装结果。内置 webfetch/websearch
281
+ 工具保持移除;远程 `.env` 类 URL 拒绝(R6 红线)。
282
+
283
+ 白名单预置主机(两个联网工具共用):`mobile.moegirl.org.cn`(词条)、
284
+ `search.bilibili.com`、`cn.bing.com`、`www.baidu.com`(搜索 URL 模板);
285
+ 通过 `TM_WEBFETCH_ALLOWED_DOMAINS` 扩展(`"*"` 放开全部主机)。
286
+
287
+ 白名单预置主机(两个联网工具共用):`mobile.moegirl.org.cn`(词条)、
288
+ `search.bilibili.com`、`cn.bing.com`、`www.baidu.com`(搜索 URL 模板);
289
+ 通过 `TM_WEBFETCH_ALLOWED_DOMAINS` 扩展(`"*"` 放开全部主机)。
290
+
291
+ ### 安全:R6 + R2 审批门
292
+
293
+ **R6 环境变量保护(现已升级为审批门控)。** TeamMode 激活时,模型无法
294
+ 静默读取环境变量。env 导出命令(`printenv`、`env`、`Get-ChildItem env:`
295
+ 等)与环境文件(`.env`、shell rc 文件)会走 OpenCode **官方确认弹窗**:
296
+ 你会在桌面收到一次原生确认,超过 `TM_ASK_TIMEOUT_MIN`(默认 10 分钟)
297
+ 无人响应即**自动拒绝**——插件超时只会拒绝,绝不为模型自我放行。通配符
298
+ 表达不了的形态(命令里内嵌的 `$VAR` / `${VAR}` / `$env:`、命令替换、
299
+ 子 shell/转义写法)以及 `tm_*` 包装通道仍维持**代码级硬拦**(没有弹窗
300
+ 可钻)。tm_* 包装工具同样过这套检查(不给包装层留后门)。审计日志只记
301
+ 工具名 + 模式类别 + 裁决事件(`ask` / `allowed-once` / `allowed-always` /
302
+ `rejected` / `timeout-rejected` / `degraded`)——绝不记录命令文本、路径、
303
+ 变量名或值。
304
+
305
+ **R2 危险操作(同一个确认弹窗)。** 删除(`rm`/`del`/`Remove-Item`/
306
+ `rmdir`)、git 发布(`git push`/`git commit`)、网络(`curl`/`wget`/
307
+ `Invoke-WebRequest`/`Invoke-RestMethod`)、包安装与发布(`npm install`/
308
+ `npm publish`/`pip install`/`winget`/`choco`)、进程/系统(`taskkill`/
309
+ `Stop-Process`/`kill`/`shutdown`/`format`)、权限(`chmod`/`takeown`/
310
+ `icacls`)——都不再静默放行,而是弹同一个官方确认框,超时未响应即自动
311
+ 拒绝。日常验证栈(`npm test`、`tsc`、`git status`/`diff`)**不在**门控
312
+ 之列,团队协作照常无打扰运行。
313
+
314
+ > ⚠️ **批准弹窗时请选 once(仅此一次),不要选 always。** 真实宿主实测:
315
+ > always 记录的泛化规则远比当次命令宽——对 `Get-ChildItem env:PATH` 选
316
+ > always 会记下 `Get-ChildItem *`,此后所有 `Get-ChildItem` 都不再弹窗。
317
+ > 只有 once 能让每次危险操作继续单独过人手。
318
+ > (如果确实对 env 弹窗选了 always,TeamMode 会把它收敛为**当前会话**级;
319
+ > 且 env 文件读取(如 `cat .env`)无论如何保持硬拦——它们从无弹窗兜底,
320
+ > 任何 always 都不曾为其授权。)
321
+
322
+ > 延后是**按会话**生效的:只有运行 TeamMode 注入角色的会话(或已弹过这类
323
+ > 确认框的会话)里的 env 读取才会被放行给弹窗;其他会话(如原生
324
+ > `build`/`plan`)里守护仍然直接硬拦——那里根本没有弹窗兜底。同一会话中,
325
+ > 一条路由到非注入角色的用户消息会**撤销**该会话的放行资格(按回合的
326
+ > agent 信号来自 message.updated;宿主传给 tool.execute.before 的入参经实测
327
+ > 不含 agent 字段)。宿主对复合命令(`a; b`)按段评估、单次弹窗批准整条;
328
+ > 任一子段是 env 读取时守护整条拦截。
329
+
330
+ > 权限协议已在真实 `opencode serve` 宿主(1.18.29)上经 SSE 事件捕获实测
331
+ > 核验;桌面弹窗的渲染本身仍需在真实 Desktop 会话里目视确认一次。非交互
332
+ > `opencode run` 下,无人应答的 `ask` 会被立即自动拒绝(没有人类可弹)。
333
+
334
+ ### 仓库卫生与路径语义
335
+
336
+ > **仓库卫生。** 卸载载荷与轨迹账本存储在 `<repo>/.git/opencode-team/` 下
337
+ > (非 git 仓库回退系统临时目录)——绝不污染你的工作树。所有 Agent 都被
338
+ > 要求在汇报完成前**删除自己创建的临时/草稿文件**,一次性工作直接放到系统
339
+ > 临时目录,从源头避免落进仓库。`tm_read` / `tm_grep` 的路径相对**项目根目录**
340
+ > (而非 Agent 的工作目录)。
341
+
342
+ ### 环境变量
343
+
344
+ | 环境变量 | 默认 | 作用 |
345
+ |---|---|---|
346
+ | `TM_ENV_PROTECT` | `strict` | R6 模式:`strict` / `standard` / `off`(off 同时解除审批计时器) |
347
+ | `TM_ASK_TIMEOUT_MIN` | `10` | R6/R2 确认弹窗无人应答后自动拒绝的分钟数;最小 3 分钟(宿主的 `permission.replied` 经事件总线到达插件约延迟 ~120 秒——更小的值会把刚获批的请求误拒) |
348
+ | `TM_ENV_PROTECT_EXTRA_DENY` | — | 追加拦截正则(分号分隔;始终硬拦,不走弹窗) |
349
+ | `TM_OFFLOAD_THRESHOLD` | `2000` | 卸载阈值(token,CJK≈1 token/字、其余 chars/4 估算) |
350
+ | `TM_PREVIEW_MAX_TOKENS` | `80` | 预览硬上限 |
351
+ | `TM_FETCH_MAX_LINES` | `2000` | tm_fetch 单段上限 |
352
+ | `TM_BLACKBOARD_DIR` | `<repo>/.git/opencode-team/blackboard/` | 卸载载荷存储(非 git 仓库回退 tmpdir;显式值支持绝对或项目相对路径) |
353
+ | `TM_TRAJECTORY_DIR` | `<repo>/.git/opencode-team/trajectory/` | 只追加工具调用账本(非 git 仓库回退 tmpdir) |
354
+ | `TM_BLACKBOARD_TTL` | `7` | 存储保留天数 |
355
+ | `TM_BASH_READONLY_ALLOWED` | 内置表 | tm_bash 只读白名单 |
356
+ | `TM_WEBFETCH_ALLOWED_DOMAINS` | `mobile.moegirl.org.cn, search.bilibili.com, cn.bing.com, www.baidu.com` | tm_webfetch/tm_browser 白名单(`"*"` 放开全部主机;显式留空 = 全拒绝) |
357
+ | `TM_BROWSER_PATH` | 自动探测 | tm_browser 可执行文件覆盖(按 Edge/Chrome/Chromium 逐 OS 探测) |
358
+ | `TM_BROWSER_HEADLESS` | `auto` | tm_browser:`1` 无头(服务器/CI) / `0` 有头 / `auto`(仅无显示器的 Linux 自动无头) |
359
+ | `TM_PTC_MAX_PROGRAM_CHARS` | `4000` | PTC 程序源码长度上限(字符) |
360
+ | `TM_PTC_MAX_CALLS` | `20` | PTC 单次运行桥接调用数上限(1–200) |
361
+ | `TM_PTC_MAX_ERRORS` | `3` | PTC 单次运行错误数上限(1–50) |
362
+ | `TM_PTC_TIMEOUT_MS` | `60000` | PTC 单次运行墙钟超时(5 秒–10 分钟) |
363
+ | `TM_PTC_ENGINE` | `auto` | PTC 引擎:`auto`(worker→inline 整体重跑降级)/ `worker` / `inline` |
364
+
365
+ ### 批量编排(tm_ptc_run)
366
+
367
+ `tm_ptc_run` 让专家代理编写**一个异步程序**,在单次回合中执行 N 次受治理的
368
+ `tm_*` 调用——运行期间零 LLM 往返,仅将聚合摘要返回上下文。设计用于批量
369
+ 只读任务:多文件侦察、批量 grep + read 聚合、交叉引用搜索结果。
370
+
371
+ #### 工作原理
372
+
373
+ 代理使用 `tm.read(args)`、`tm.grep(args)`、`tm.bash(args)`、`tm.fetch(args)`
374
+ 编写程序体——参数与四个受治理工具相同。每次调用返回 `{ok:true, data}`(已受
375
+ 治理:内联文本或卸载句柄)或 `{ok:false, error:{tool,phase,line?,message}}`。
376
+ 程序 `return` 一个值;它会被 JSON 序列化进聚合摘要。
377
+
378
+ 包含 `require`、`import`、`process`、`globalThis`、`Deno`、`Bun`、`fs`、`net`
379
+ 或 `child_process` 的程序会在执行前被拒绝(静态预扫描,辅助防护)。
380
+
381
+ #### 预算(仅收紧)
382
+
383
+ 调用方可收紧 `max_calls`、`max_errors` 和 `timeout_ms`——超过 `TM_PTC_*` 上限
384
+ 的值会被钳制到上限;低于下限的值会被钳制到下限。触达任一预算即整体停止运行;
385
+ 已产出的输出不会丢失。
386
+
387
+ #### 引擎(`TM_PTC_ENGINE`)
388
+
389
+ | 模式 | 行为 |
390
+ |---|---|
391
+ | `auto`(默认) | 优先尝试 `worker_threads`;引擎失败时**整体重跑**程序到 `node:vm`,摘要标记 `degraded-engine`(桥接调用均为只读,重跑安全;回退运行在相同墙钟期限内使用全新预算) |
392
+ | `worker` | 强制使用 worker 引擎(失败时返回 engine-error) |
393
+ | `inline` | 强制使用 `node:vm` 引擎(脚本超时可斩杀**首个 await 之前**的同步忙等;await 之后的忙等会不可恢复地阻塞宿主事件循环——生产环境请用 worker/auto) |
394
+
395
+ worker 引擎在专用线程中运行程序,`env:{}` 清空 process.env、`resourceLimits`
396
+ 限量、硬墙钟 `terminate()`。所有治理(P2 路径范围、P3 白名单、R6、阈值卸载、
397
+ TTL)对每次桥接调用生效——PTC 不是绕过层。
398
+
399
+ #### 访问权限
400
+
401
+ **全部六个**代理的白名单中都包含 `tm_ptc_run`(`team` lead 也包含——v1.5.4
402
+ 修订了最初的拒绝裁定)。每次桥接调用仍然运行完整的 tm_* 治理管线(P2 路径
403
+ 域、P3 白名单、R6、阈值卸载 + 句柄、TTL),批量编排只是效率增益,不是治理缺口。
404
+
405
+ ---
406
+
407
+ ## 🏗️ 架构
408
+
409
+ ```
410
+ opencode-team-mode/
411
+ ├── package.json ← npm 包定义
412
+ ├── tsconfig.json ← TypeScript 配置
413
+ ├── src/
414
+ │ ├── index.ts ← 插件入口(server():config + R6 tool.execute.before + 审批门 event 钩子 + tool 段)
415
+ │ ├── agents.ts ← Agent 结构(模式、颜色、温度、白名单矩阵)
416
+ │ ├── prompts/ ← Agent 提示词原文(lead / specialists / shared)——由测试钉死
417
+ │ ├── commands.ts ← 命令定义(模板、Agent 绑定)
418
+ │ ├── blackboard.ts ← 共享黑板 + TTL 自动清理清扫器
419
+ │ ├── envprotect.ts ← R6 门面 → envprotect/(patterns / bash-classify / path-classify / gate-predicates / hook)
420
+ │ ├── approval-gate.ts ← 统一审批门:官方弹窗超时自动拒绝(绝不自我放行)
421
+ │ ├── tm/ ← JIT 层 2 工具:pipelines / result / client-unwrap / shell-bridge / args-schema / tools / guard / preview / store / refs / config / webfetch / memory / browser / ptc/(9 模块)
422
+ │ └── types.ts ← 加载器契约类型定义(1.18.x)
423
+ ├── scripts/
424
+ │ ├── install.sh ← 一键安装脚本(bash)
425
+ │ └── install.ps1 ← 一键安装脚本(PowerShell)
426
+ ├── pt07/ ← PT-07 基线任务集(种子化 A/B token 测量)
427
+ ├── LICENSE ← Apache 2.0
428
+ └── README.md ← 英文文档
429
+ README.zh-CN.md ← 中文文档
430
+ ```
431
+
432
+ ### 工作原理
433
+
434
+ 1. OpenCode 桌面版启动,加载 `opencode.json(c)`
435
+ 2. 检测到 `plugin` 数组中的 `"@te-river/opencode-team-mode@latest"`,加载 npm 包
436
+ 3. 加载器调用插件的 `server(input, options)`,注册 `config` hook;hook 向合并后的配置注入 6 个 Agent 和 6 个命令。同一次调用还会安装 R6 的 `tool.execute.before` 防护、武装 R6/R2 统一审批门(官方确认弹窗 + `TM_ASK_TIMEOUT_MIN` 超时自动拒绝,经 `event` 钩子驱动),并注册受治理的 `tm_*` 工具(见下文“上下文治理”)
437
+ 4. 插件的 `id: "team-mode"` 作为插件名显示在桌面版 UI
438
+ 5. Agent 和命令立即在桌面版 UI 中可用 —— 无需复制任何文件;同名 Agent 以用户自定义优先(插件绝不覆盖)
439
+
440
+ ---
441
+
442
+ ## 🤖 团队如何运作
443
+
444
+ 子代理之间无法实时互发消息(平台限制),TeamMode 通过**结构化回复骨架**协调它们,
445
+ 文件黑板只保留给超大产出:
446
+
447
+ - **回复骨架(主通道)**:每个专家的最终回复以
448
+ `STATUS: / CHANGES: / FINDINGS: / EVIDENCE: / HANDOFF:` 开头,全文 ≤50 行。
449
+ 这个尺寸的产出直接内联传递——零文件 I/O,没有"文件没写上"这种故障面。
450
+ Lead 把 `HANDOFF` 原文转贴进下一次派单,并对骨架做机器校验
451
+ (缺失 → 带 skeleton 原文重试一次 → 仍违规则降级记入报告)。
452
+ - **黑板文件(仅例外)**:完整产出确实超过 ~50 行时(如完整架构设计文档),
453
+ 派单点名唯一文件:
454
+ `<repo>/.git/opencode-team/<session-key>/<task-slug>/NN-<role>-<topic>.md`
455
+ ——位于 `.git/` 内,**绝不污染**工作区和 commit(非 git 工作区回退系统临时目录)。
456
+ 写入即冻结:修订 = 新的轮次后缀文件(`…-r2.md`);会话目录层让新对话
457
+ 不会撞上尚未清扫的旧黑板。
458
+ - **没有 MANIFEST.md**:lead 的状态记忆就是它的 todo list。
459
+ - **反馈闭环**:Critical/Major 发现和产品 bug 自动转化为跟踪的修复任务,
460
+ 直到交付物收敛(最多 2 轮,之后升级给用户)。
461
+
462
+ ### 确定性路由、审批门与自适应评审
463
+
464
+ - **路由表**:lead 按任务形状查固定流水线行——提问 → 直接回答;纯文档 →
465
+ implementer;产品行为变更 → implementer → tester → reviewer;多模块/跨接口
466
+ 功能 → architect → implementer → tester → reviewer(s);未知外部技术 →
467
+ researcher 前置。流水线有固定下限:产品变更路由到少于 3 次派发即是路由 bug;
468
+ 把一个请求拆成多个 <2 派发的子任务以规避审批门 = 协议违规。
469
+ - **审批门(按计数触发)**:预计派发 ≥2 → lead 先调研(亲自读仓库;仅未知外部
470
+ 技术才派 researcher),呈交 ≤30 行计划,然后**等待你的批准**才执行任何东西。
471
+ 0-1 次派发的小任务以 1-2 行通报直接开工。执行中发现需要第 2 次派发 →
472
+ 暂停等批准。阻塞性不确定**立即批量问一次**——不猜测、不挤牙膏。
473
+ - **自适应评审**:默认 1 个 reviewer 派单(correctness 维度);仅高风险画像
474
+ ——鉴权/安全面、跨模块数据契约、≥3 文件的公共 API 变更——才升级为
475
+ 3 维并行(完整性 / 正确性 / 影响面)。
476
+ - **静态验证**:tester 通过构建、类型检查、静态分析、API/单元测试验证。
477
+ 禁止即兴发明浏览器自动化(headless 截图、DOM stub);用户可见前端改动
478
+ 以 `UI NOT VERIFIED: <待人工检查项>` 如实收尾,除非项目本身已带真实
479
+ 浏览器测试设施。
480
+ - **无仪式捷径**:lead 已亲自验证的根因(file:line 证据)直接变成修复规格
481
+ 派给 implementer——调查性派单服务于未知,不服务于仪式感。
482
+ - **简明纪律**:路由选择是查表;用户可见的计划性文字 ≤5 行。
483
+ - **证据标准(保留)**:"完成 / 修复 / 通过"的声明必须附可验证证据——命令
484
+ 输出、日志、diff。纯叙述只是进度说明,不是证明。
485
+ - **逐字契约(保留)**:需要互通的并行实现代理,其数据契约(端点、字段名、
486
+ 类型)逐字贴进每个相关派单——契约错配是集成 bug 之首。
487
+ - **文档同步(CHANGELOG + AGENTS.md)**:交付的改动在 CHANGELOG.md 存在时按
488
+ Keep a Changelog 风格追加条目;当改动会影响 AGENTS.md 所记录的内容
489
+ (构建/测试命令、约定、项目结构、agent 指引)时同步更新它;任一文件缺失
490
+ 时提议代建。阅读去重:README 由 lead 亲自阅读(宿主不会注入);
491
+ AGENTS.md/CLAUDE.md 若宿主已注入则直接使用上下文中的副本——仅在确实缺失时
492
+ 才打开文件;专家不会自己去重读这些文档——约定由 lead 蒸馏进派单。
493
+
494
+ ### Triage —— 提问不会变成代码修改
495
+
496
+ Team Lead 对每条消息先分类再行动:咨询/提问只得到回答(零文件改动,发现缺陷
497
+ 仅**提议**修复并等待你放行);只有明确的行动指令才进入工作流。并且一旦你写明
498
+ 了哪些能碰哪些不能碰,**这些边界高于一切规则**——lead 会在每次派发中原样重申。
499
+
500
+ ### 清理 —— 只有 TTL 清扫器一条路
501
+
502
+ | 责任方 | 时机 |
503
+ |---|---|
504
+ | 插件代码(进程内清扫器) | 启动时 + 每小时:清除空闲超过 **TTL** 的任务目录 |
505
+
506
+ Team Lead 不再删除任务目录 —— 跑完的黑板原地留给你回看审计;回收由纯代码
507
+ 完成,从不依赖模型"记得删",崩溃/强杀留下的残骸同样会被清扫。清扫器对活跃
508
+ 会话内的过期任务逐个回收,对整个闲置的会话目录一次性收走。TTL 可用
509
+ `ttlDays` 调节。
510
+
511
+ ### 自定义 TTL
512
+
513
+ 默认为 **5 天**。想自定义,在 `opencode.jsonc` 中使用元组形式的插件声明:
514
+
515
+ ```jsonc
516
+ {
517
+ "$schema": "https://opencode.ai/config.json",
518
+ "plugin": [
519
+ ["@te-river/opencode-team-mode@latest", { "ttlDays": 7 }]
520
+ ]
521
+ }
522
+ ```
523
+
524
+ `ttlDays` 接受 `(0, 365]` 内的天数;非法值静默回退到 5 天。
525
+
526
+ ### 默认代理
527
+
528
+ TeamMode 默认**把 Team 设为你的默认代理**——新会话直接由团队调度者接管。
529
+ 占默认槽附带一个排序效应:选择器会把**默认代理钉在第一位**、其余按名称
530
+ 字母升序,所以顺序为 **team, build, plan**。(想让 Team 排在 Plan 之下?
531
+ 那必须放弃默认槽——见下方退出开关;按服务端的排序规则二者不可兼得。)
532
+
533
+ 不想占用默认代理槽(`build` 保持默认,顺序 **build, plan, team**)则退出:
534
+
535
+ ```jsonc
536
+ {
537
+ "plugin": [
538
+ ["@te-river/opencode-team-mode@latest", { "defaultAgent": false }]
539
+ ]
540
+ }
541
+ ```
542
+
543
+ 用户显式配置的非 `build` 默认代理永远原样保留——插件从不覆写。
544
+
545
+ **升级提示**:v1.4.4 曾短暂改为 opt-in(默认不占用);v1.4.5 恢复
546
+ Team-as-default 出厂行为。若你在 v1.4.4 期间加过 `{ "defaultAgent": true }`,
547
+ 现在可以删掉该选项(或改为 `false` 主动退出)。
548
+
549
+ ---
550
+
551
+ ## 🔧 自定义
552
+
553
+ ### Team Lead 的模型最关键
554
+
555
+ Lead 是编排大脑:它给每条消息分类、按路由表查流水线、写每份派单、裁决
556
+ reviewer/tester 的发现、合成最终交付。这里的质量问题会**沿流水线放大**——
557
+ 平庸的 Lead 拆错任务、给专家的指令含糊、放走劣质产出;没有任何专家能
558
+ 救回一份从一开始就派错的工单。
559
+
560
+ 所以:自定义模型时**Lead 位上请放你负担得起的最强模型**。其他角色可以用便宜模型——
561
+ 它们拿到的指令书精确、阅读范围受限,容错更高。按 agent 钉模型:
562
+
563
+ ```jsonc
564
+ {
565
+ "agent": {
566
+ // Team Lead —— 编排值得最好的模型
567
+ "team": { "model": "anthropic/claude-opus-4-5" },
568
+ // 专家角色 —— 便宜一档通常够用
569
+ "implementer": { "model": "anthropic/claude-sonnet-4-6" }
570
+ }
571
+ }
572
+ ```
573
+
574
+ (以上模型 ID 仅为示例,换成你服务商实际提供的即可。你自定义的
575
+ `agent.team` 永远优先于插件注入的版本。)
576
+
577
+ ### 覆盖某个 Agent
578
+
579
+ 在 `opencode.json` 中添加同名 Agent —— 你的定义会优先生效:
580
+
581
+ ```jsonc
582
+ {
583
+ "agent": {
584
+ "reviewer": {
585
+ "model": "anthropic/claude-sonnet-4-6",
586
+ "prompt": "你是一个极其严格的审查员。任何 lint 警告都必须打回。"
587
+ }
588
+ }
589
+ }
590
+ ```
591
+
592
+ ### 添加自己的 Agent
593
+
594
+ TeamMode 不阻止你添加更多 Agent,与团队 Agent 并存:
595
+
596
+ ```jsonc
597
+ {
598
+ "agent": {
599
+ "devops": {
600
+ "mode": "subagent",
601
+ "description": "处理 CI/CD、Docker 和部署任务",
602
+ "prompt": "你是 DevOps 工程师..."
603
+ }
604
+ }
605
+ }
606
+ ```
607
+
608
+ ### 禁用某个 Agent
609
+
610
+ ```jsonc
611
+ {
612
+ "agent": {
613
+ "researcher": { "disable": true }
614
+ }
615
+ }
616
+ ```
617
+
618
+ ---
619
+
620
+ ## 📦 发布到 npm
621
+
622
+ 如果你想发布自己的 fork:
623
+
624
+ ```bash
625
+ npm run build # 编译 TypeScript → dist/
626
+ npm version patch # 更新版本号
627
+ npm publish # 发布到 npm 仓库
628
+ ```
629
+
630
+ ---
631
+
632
+ ## 🤝 贡献
633
+
634
+ 欢迎贡献!以下方向特别需要帮助:
635
+
636
+ - 🌐 **本地化** — 将 Agent prompt 翻译为其他语言
637
+ - 🎨 **更多 Agent 角色** — DevOps、DBA、安全专家、UX 设计师
638
+ - 🔧 **更多命令** — `/team-deploy`、`/team-docs`、`/team-refactor`
639
+ - 📝 **更好的 Prompt** — 通过 Prompt 工程优化 Agent 行为
640
+
641
+ ---
642
+
643
+ ## 📄 许可证
644
+
645
+ [Apache License 2.0](./LICENSE)
646
+
647
+ ---
648
+
649
+ ## 🔗 链接
650
+
651
+ - [npm 包](https://www.npmjs.com/package/@te-river/opencode-team-mode) — `@te-river/opencode-team-mode`
652
+ - [OpenCode 桌面版](https://opencode.ai) — 官网 & 下载
653
+ - [OpenCode 文档](https://opencode.ai/docs) — 配置 & 插件文档
654
+ - [OpenCode 插件 API](https://opencode.ai/docs/plugins) — 构建你自己的插件
655
+ - [OpenCode GitHub](https://github.com/anomalyco/opencode) — OpenCode 源码