@te-river/opencode-team-mode 1.6.2 → 1.7.1
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 +114 -118
- package/README.zh-CN.md +95 -100
- package/dist/agents.d.ts.map +1 -1
- package/dist/agents.js +89 -79
- package/dist/agents.js.map +1 -1
- package/dist/approval-gate.d.ts +8 -9
- package/dist/approval-gate.d.ts.map +1 -1
- package/dist/approval-gate.js +13 -14
- package/dist/approval-gate.js.map +1 -1
- package/dist/capabilities.d.ts +11 -37
- package/dist/capabilities.d.ts.map +1 -1
- package/dist/capabilities.js +11 -141
- package/dist/capabilities.js.map +1 -1
- package/dist/commands.js +1 -1
- package/dist/envprotect/hook.d.ts +12 -31
- package/dist/envprotect/hook.d.ts.map +1 -1
- package/dist/envprotect/hook.js +13 -91
- package/dist/envprotect/hook.js.map +1 -1
- package/dist/envprotect/patterns.d.ts +6 -4
- package/dist/envprotect/patterns.d.ts.map +1 -1
- package/dist/envprotect/patterns.js +6 -4
- package/dist/envprotect/patterns.js.map +1 -1
- package/dist/envprotect.d.ts +1 -1
- package/dist/envprotect.d.ts.map +1 -1
- package/dist/envprotect.js +1 -1
- package/dist/envprotect.js.map +1 -1
- package/dist/host/v2-browser-gate.d.ts +19 -1
- package/dist/host/v2-browser-gate.d.ts.map +1 -1
- package/dist/host/v2-browser-gate.js +47 -6
- package/dist/host/v2-browser-gate.js.map +1 -1
- package/dist/host/v2-capabilities.d.ts +16 -0
- package/dist/host/v2-capabilities.d.ts.map +1 -1
- package/dist/host/v2-capabilities.js +22 -1
- package/dist/host/v2-capabilities.js.map +1 -1
- package/dist/host/v2-default-agent.d.ts +37 -0
- package/dist/host/v2-default-agent.d.ts.map +1 -0
- package/dist/host/v2-default-agent.js +128 -0
- package/dist/host/v2-default-agent.js.map +1 -0
- package/dist/host/v2-events.d.ts +1 -0
- package/dist/host/v2-events.d.ts.map +1 -1
- package/dist/host/v2-events.js +14 -0
- package/dist/host/v2-events.js.map +1 -1
- package/dist/host/v2-guard.d.ts +178 -0
- package/dist/host/v2-guard.d.ts.map +1 -1
- package/dist/host/v2-guard.js +324 -8
- package/dist/host/v2-guard.js.map +1 -1
- package/dist/host/v2-offload.d.ts +1 -1
- package/dist/host/v2-offload.js +2 -2
- package/dist/host/v2-permissions.d.ts +45 -44
- package/dist/host/v2-permissions.d.ts.map +1 -1
- package/dist/host/v2-permissions.js +48 -49
- package/dist/host/v2-permissions.js.map +1 -1
- package/dist/host/v2-probe-chain.d.ts +93 -0
- package/dist/host/v2-probe-chain.d.ts.map +1 -0
- package/dist/host/v2-probe-chain.js +146 -0
- package/dist/host/v2-probe-chain.js.map +1 -0
- package/dist/host/v2-prune.d.ts +157 -0
- package/dist/host/v2-prune.d.ts.map +1 -0
- package/dist/host/v2-prune.js +507 -0
- package/dist/host/v2-prune.js.map +1 -0
- package/dist/host/v2-retry.d.ts +143 -0
- package/dist/host/v2-retry.d.ts.map +1 -0
- package/dist/host/v2-retry.js +315 -0
- package/dist/host/v2-retry.js.map +1 -0
- package/dist/host/v2-scope.d.ts.map +1 -1
- package/dist/host/v2-scope.js +14 -7
- package/dist/host/v2-scope.js.map +1 -1
- package/dist/host/v2-session-client.d.ts +24 -0
- package/dist/host/v2-session-client.d.ts.map +1 -1
- package/dist/host/v2-session-client.js +243 -3
- package/dist/host/v2-session-client.js.map +1 -1
- package/dist/host/v2-session.d.ts +72 -1
- package/dist/host/v2-session.d.ts.map +1 -1
- package/dist/host/v2-session.js +154 -10
- package/dist/host/v2-session.js.map +1 -1
- package/dist/host/v2-tool.d.ts +2 -3
- package/dist/host/v2-tool.d.ts.map +1 -1
- package/dist/host/v2-tool.js +2 -3
- package/dist/host/v2-tool.js.map +1 -1
- package/dist/host/v2-types.d.ts +30 -0
- package/dist/host/v2-types.d.ts.map +1 -1
- package/dist/host/v2-usage.d.ts +50 -0
- package/dist/host/v2-usage.d.ts.map +1 -0
- package/dist/host/v2-usage.js +82 -0
- package/dist/host/v2-usage.js.map +1 -0
- package/dist/host/v2.d.ts +14 -12
- package/dist/host/v2.d.ts.map +1 -1
- package/dist/host/v2.js +430 -73
- package/dist/host/v2.js.map +1 -1
- package/dist/identity.d.ts +27 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +34 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +9 -24
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -27
- package/dist/index.js.map +1 -1
- package/dist/prompts/lead.d.ts +1 -1
- package/dist/prompts/lead.d.ts.map +1 -1
- package/dist/prompts/lead.js +38 -25
- package/dist/prompts/lead.js.map +1 -1
- package/dist/prompts/shared.d.ts +2 -2
- package/dist/prompts/shared.d.ts.map +1 -1
- package/dist/prompts/shared.js +66 -56
- package/dist/prompts/shared.js.map +1 -1
- package/dist/prompts/specialists.d.ts +2 -2
- package/dist/prompts/specialists.d.ts.map +1 -1
- package/dist/prompts/specialists.js +53 -83
- package/dist/prompts/specialists.js.map +1 -1
- package/dist/tm/args-schema.d.ts +7 -32
- package/dist/tm/args-schema.d.ts.map +1 -1
- package/dist/tm/args-schema.js +12 -153
- package/dist/tm/args-schema.js.map +1 -1
- package/dist/tm/board.d.ts +10 -9
- package/dist/tm/board.d.ts.map +1 -1
- package/dist/tm/board.js +11 -10
- package/dist/tm/board.js.map +1 -1
- package/dist/tm/config-files.d.ts +81 -0
- package/dist/tm/config-files.d.ts.map +1 -0
- package/dist/tm/config-files.js +209 -0
- package/dist/tm/config-files.js.map +1 -0
- package/dist/tm/config-layers.d.ts +117 -0
- package/dist/tm/config-layers.d.ts.map +1 -0
- package/dist/tm/config-layers.js +317 -0
- package/dist/tm/config-layers.js.map +1 -0
- package/dist/tm/config.d.ts +10 -101
- package/dist/tm/config.d.ts.map +1 -1
- package/dist/tm/config.js +17 -71
- package/dist/tm/config.js.map +1 -1
- package/dist/tm/dispatch.d.ts +115 -21
- package/dist/tm/dispatch.d.ts.map +1 -1
- package/dist/tm/dispatch.js +424 -67
- package/dist/tm/dispatch.js.map +1 -1
- package/dist/tm/egress.d.ts +19 -7
- package/dist/tm/egress.d.ts.map +1 -1
- package/dist/tm/egress.js +21 -9
- package/dist/tm/egress.js.map +1 -1
- package/dist/tm/index.d.ts +23 -20
- package/dist/tm/index.d.ts.map +1 -1
- package/dist/tm/index.js +117 -116
- package/dist/tm/index.js.map +1 -1
- package/dist/tm/ledger.d.ts +9 -2
- package/dist/tm/ledger.d.ts.map +1 -1
- package/dist/tm/ledger.js +4 -1
- package/dist/tm/ledger.js.map +1 -1
- package/dist/tm/perm-ask.d.ts +3 -3
- package/dist/tm/perm-ask.d.ts.map +1 -1
- package/dist/tm/perm-ask.js +3 -3
- package/dist/tm/perm-ask.js.map +1 -1
- package/dist/tm/pipelines.d.ts +12 -11
- package/dist/tm/pipelines.d.ts.map +1 -1
- package/dist/tm/pipelines.js +40 -207
- package/dist/tm/pipelines.js.map +1 -1
- package/dist/tm/preview.d.ts +1 -1
- package/dist/tm/preview.js +3 -3
- package/dist/tm/preview.js.map +1 -1
- package/dist/tm/refs.d.ts +31 -4
- package/dist/tm/refs.d.ts.map +1 -1
- package/dist/tm/refs.js +48 -4
- package/dist/tm/refs.js.map +1 -1
- package/dist/tm/result.d.ts +1 -1
- package/dist/tm/result.d.ts.map +1 -1
- package/dist/tm/result.js +4 -3
- package/dist/tm/result.js.map +1 -1
- package/dist/tm/search.d.ts +2 -2
- package/dist/tm/search.js +7 -7
- package/dist/tm/search.js.map +1 -1
- package/dist/tm/serp-loop.d.ts +19 -7
- package/dist/tm/serp-loop.d.ts.map +1 -1
- package/dist/tm/serp-loop.js +24 -9
- package/dist/tm/serp-loop.js.map +1 -1
- package/dist/tm/stats.d.ts +12 -27
- package/dist/tm/stats.d.ts.map +1 -1
- package/dist/tm/stats.js +43 -45
- package/dist/tm/stats.js.map +1 -1
- package/dist/tm/store.d.ts +18 -5
- package/dist/tm/store.d.ts.map +1 -1
- package/dist/tm/store.js +39 -9
- package/dist/tm/store.js.map +1 -1
- package/dist/tm/tools.d.ts +7 -5
- package/dist/tm/tools.d.ts.map +1 -1
- package/dist/tm/tools.js +10 -41
- package/dist/tm/tools.js.map +1 -1
- package/dist/tm/webfetch.d.ts +1 -1
- package/dist/tm/webfetch.d.ts.map +1 -1
- package/dist/tm/webfetch.js +38 -23
- package/dist/tm/webfetch.js.map +1 -1
- package/dist/types.d.ts +40 -123
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +7 -21
- package/dist/types.js.map +1 -1
- package/docs/installation-v2.md +133 -33
- package/docs/installation.md +9 -0
- package/docs/research/browser-pane.md +5 -0
- package/docs/v2-port-notes.md +133 -0
- package/package.json +1 -1
- package/scripts/gen-v2-config.mjs +246 -94
- package/scripts/lib/fake-ctx.mjs +67 -0
package/README.zh-CN.md
CHANGED
|
@@ -19,8 +19,7 @@
|
|
|
19
19
|
> **懒人路径:** 把下面这段话粘给任意编码 agent,让它替你装:
|
|
20
20
|
>
|
|
21
21
|
> ```text
|
|
22
|
-
> 安装 OpenCode 插件 @te-river/opencode-team-mode
|
|
23
|
-
> 1.18.x → https://raw.githubusercontent.com/Te-River/Opencode-TeamMode/main/docs/installation.md
|
|
22
|
+
> 安装 OpenCode 插件 @te-river/opencode-team-mode:本包**只支持 OpenCode 2.x**——1.18.x 人格已在 1.7.0 线里整体移除。
|
|
24
23
|
> 2.x → https://raw.githubusercontent.com/Te-River/Opencode-TeamMode/main/docs/installation-v2.md
|
|
25
24
|
> (2.x 的插件不能创建 agent,六个角色和六条 `/team-*` 命令要靠那份指南里的生成步骤落到
|
|
26
25
|
> 配置目录——这一步不是可选的。)然后按该指南里的检查项验证。
|
|
@@ -46,13 +45,13 @@ TeamMode 对每一个的回应:
|
|
|
46
45
|
| 痛点 | TeamMode 的回答 |
|
|
47
46
|
|---|---|
|
|
48
47
|
| 🔥 **上下文爆炸** | 所有受治理工具的输出超过内容分档阈值(散文 4000 / 数据 2000 token,CJK 感知)就卸载到本地 run 存储,换成 80 token 的预览 + HMAC 句柄。agent 需要什么再分页取什么——窗口永远淹不了。 |
|
|
49
|
-
| 🐌 **回合开销** | `
|
|
48
|
+
| 🐌 **回合开销** | 宿主自己的 `execute`(Code Mode):agent 写**一个程序**,单回合内发起 N 次受治理调用。运行期间零 LLM 回合。 |
|
|
50
49
|
| 🕳️ **静默副作用** | R6/R2 审批门禁:环境变量读取和危险操作走 OpenCode 官方确认弹窗,1 分钟没人理自动拒绝。插件从不代替你批准——它只会拒绝。 |
|
|
51
50
|
| 🌫️ **幻觉式调研** | 联网是双角色的授权 + 白名单受治理工具链。抓不到的事实就报告为缺口——绝不编造。 |
|
|
52
51
|
| 🧭 **纯文本墙** | 回复被引导成宿主渲染得最快的形状:逐文件 / 逐用例 / 逐条发现用 markdown 表格,diff 和配置用围栏代码块,浏览器截图只在你明确要求时才内联附上。宿主支持哪些语法是实测出来的、不是照着 CommonMark 猜的,提示词里带着这份实测的否定清单——脚注 `[^1]`、`==高亮==`、单独的 `---` 分隔线和 `$…$` 数学会以字面量形式出现在你面前,所以 agent 被明确告知不要用;而 `mermaid` 图是可以用的,因为这个宿主确实会画。 |
|
|
53
52
|
| 🎯 **目标漂移** | lead 开局必须用你自己的措辞写下 `GOAL:` 和可验证的 `ACCEPTANCE:` 判据,判据没有证据支撑这一轮就不算结束——合法的停止只有两种(卡在你这里,或有证据地证明做不到)。一轮收完但宿主 todolist 上还有未完成项时,`tm_join` 会直接说"目标未达成"并列出条目;目标本身随上下文压缩一起存活,摘要不能悄悄把它换掉。 |
|
|
54
53
|
| 🗣️ **用你没选的语言回话** | 受治理工具回复的是中文,agent 放任自己就会把这份中文原样反射给你。现在每个角色都带一条回复语言规则:**你用的语言优先**;中文句子只在"它本身就是证据"时逐字引用(close 的三种裁决、拒绝语)——把裁决词翻译掉,正是未经核实的结论看起来像核实过的开始。 |
|
|
55
|
-
| ⏱️ **为了"看起来很认真"而烧掉的轮次** | 效率至上写进了 lead 和五个专家:一次宽调用代替三次窄调用、互不依赖的调用并到同一轮、≥3 个探测合成一次 `
|
|
54
|
+
| ⏱️ **为了"看起来很认真"而烧掉的轮次** | 效率至上写进了 lead 和五个专家:一次宽调用代替三次窄调用、互不依赖的调用并到同一轮、≥3 个探测合成一次 `execute`(Code Mode)程序、不许为了"再看它绿一遍"重跑同一个检查。同时把边界写死:效率不能拿去赎回证据规则——一个没验证过的"done"会让你赔上那一轮 **加上** 那个 bug。 |
|
|
56
55
|
|
|
57
56
|
底下还有流程纪律:确定性路由表、≥2 次派工先出 ≤30 行计划等你批、agent
|
|
58
57
|
之间用 `STATUS/CHANGES/FINDINGS/EVIDENCE/HANDOFF` 结构化交接、以及静态
|
|
@@ -71,7 +70,7 @@ TeamMode 对每一个的回应:
|
|
|
71
70
|
| 🏗️ **Architect** | 系统设计 | 设计文档、模块结构、API 契约 |
|
|
72
71
|
| 💻 **Implementer** | 写代码 | 做功能、写生产代码 |
|
|
73
72
|
| 🔍 **Reviewer** | 维度审计 | 默认单维度评审;高风险变更才三维度并行 |
|
|
74
|
-
| 🧪 **Tester** | 测试工程师 | 带真边界条件的测试;静态验证(构建 / 类型检查 / lint
|
|
73
|
+
| 🧪 **Tester** | 测试工程师 | 带真边界条件的测试;静态验证(构建 / 类型检查 / lint);经宿主原生 `browser_*` 工具的治理化 UI 验证 |
|
|
75
74
|
| 🔎 **Researcher** | 找资料 | 本地仓库优先,然后才是网络——两个联网角色之一(另一个是 Lead) |
|
|
76
75
|
|
|
77
76
|
开箱即用时 **Team 就是你的默认 agent**——新会话直接进编排者(可在
|
|
@@ -86,8 +85,7 @@ TeamMode 对每一个的回应:
|
|
|
86
85
|
把这段话粘给任意编码 agent——它会改配置、提醒你重启、并完成验证:
|
|
87
86
|
|
|
88
87
|
```text
|
|
89
|
-
安装 OpenCode 插件 @te-river/opencode-team-mode
|
|
90
|
-
1.18.x → https://raw.githubusercontent.com/Te-River/Opencode-TeamMode/main/docs/installation.md
|
|
88
|
+
安装 OpenCode 插件 @te-river/opencode-team-mode:本包**只支持 OpenCode 2.x**——1.18.x 人格已在 1.7.0 线里整体移除。
|
|
91
89
|
2.x → https://raw.githubusercontent.com/Te-River/Opencode-TeamMode/main/docs/installation-v2.md
|
|
92
90
|
(2.x 的插件不能创建 agent,六个角色和六条 `/team-*` 命令要靠那份指南里的生成步骤落到配置
|
|
93
91
|
目录——这一步不是可选的。)按该指南里的检查项验证。
|
|
@@ -261,50 +259,48 @@ HMAC 句柄,agent 真需要 payload 时用 `tm_fetch` 分页取。
|
|
|
261
259
|
|
|
262
260
|
| 工具 | 功能 | 角色 |
|
|
263
261
|
|---|---|---|
|
|
264
|
-
| `
|
|
262
|
+
| `tm_fetch` | 句柄分页:取回被卸载的结果(JSON 句柄支持 `fields` 点路径投影——刻意小的 jq 子集,如 `items[].name`) | 全部六个 agent |
|
|
265
263
|
| `tm_memory` | 会话 + 项目 + 全局三层记忆库(Markdown + frontmatter):add / search / list / forget / compact | 全部六个 agent |
|
|
266
264
|
| `tm_board_write` | **黑板的写入侧**:只在 `<board-root>/<session-key>/<task-slug>/NN-<role>-<topic>[-rN].md` 放下一个**新**的 Markdown 文件,文件名由工具自己决定——修订是一个带 `-rN` 的新文件,绝不覆写;回复只给路径和字节数,绝不回传正文。它存在的理由是:落黑板原本需要一个文件工具,而 `architect` / `researcher` 一个都没有(没有 `write`、没有 `edit`、连用来给会话目录打时间戳的 `bash` 都没有),于是这两类角色的超长交付每次都以 `BLACKBOARD WRITE FAILED` + 整篇文档内联回来收场——本项目最看重的那个回复形态,恰恰在最需要的角色身上无法执行。范围是强制的:路径段做规整、目标用 realpath 对齐黑板根(符号链接的任务目录直接拒写)、文件名永远以 `.md` 结尾(所以造不出 `.env`/rc 文件)、正文受 `TM_BOARD_MAX_CHARS` 与会话文件数上限约束 | 全部六个 agent |
|
|
267
|
-
| `tm_ptc_run` | 批量编排:一个程序、N 次受治理调用、零 LLM 回合;联网角色还能在程序里调 `tm.search` / `tm.webfetch` | 全部六个 agent |
|
|
268
265
|
| `tm_search` | 多引擎网络搜索,返回提取、去重、RRF 融合后的命中列表 | Lead + Researcher |
|
|
269
266
|
| `tm_webfetch` | 白名单页面的单次受治理 GET(搜索页自动提取)。重定向逐跳手动过检,被拒时会把**整条链**报出来(`跳转链: a → b(停在第 2 跳)`)——以前只会报最后一个主机,一个在白名单内的短链跳到站外时,读起来像"这个站点抓不到",于是 agent 又回去重试它刚眼睁睁失败的入口 URL。429/503 若带 delta-seconds 的 `Retry-After` 会一并报出(HTTP-date 形式刻意不折算成倒计时),所以"待会儿再来"不会被当成"这里没东西"。读页面时还会优先要 Markdown(`Accept: text/markdown,…`)——实测 `learn.microsoft.com`:60 778 B 的 HTML 变成 11 449 B 的 Markdown,其余站点两种请求返回同一份文档,所以在不支待的地方这个偏好是零成本的 | Lead + Researcher |
|
|
270
|
-
| `tm_ledger` | **领队的任务清单**(`add` / `doing` / `done` / `blocked` / `list`),存在宿主自己的 `ctx.storage` 里、按会话分开——OpenCode 2.x 不给插件 `todowrite`,LEDGER 规则从此有了落点。同一个要求重复提出只算一条;编号撞上两条会拒绝并把两条都列出来;`blocked`
|
|
271
|
-
| `tm_join` | **子代理回收**——插件侧的派发器已经没有了(`tm_dispatch` 被移除:插件创建的子会话,用户既打不开也停不掉)。派活统一走宿主自己的 `task` / `task { background: true }`,`tm_join` 是它的读端:不带参数=状态快照,`waitMs`=有界等待,`cancel:true` 取消跑飞的子任务,`tm_join { ids: ["ses_…"] }` 则把某个子代理的**整篇**回复经卸载管线取回(句柄 + ≤80 token 预览),而不是几千 token 直接压进上下文。插件重启后它还会从宿主会话树重建登记,遗留的子代理被"接管"而不是丢失。**2.x 上它还会登记宿主自己的 `subagent` 工具派出去的子会话**(凭据就是那句确认里的 `metadata.sessionID`),所以用户明明在屏幕上看着子代理跑、`tm_join` 却说"没有待收集的派发"
|
|
272
|
-
| `
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
>
|
|
277
|
-
>
|
|
278
|
-
> 接管,`tm_ptc_run` 由宿主的 `execute`(Code Mode)接管——同一件工作,少给模型一个
|
|
279
|
-
> 要挑的工具。治理没有跟着消失:超大的原生结果照样被 `tool.execute.after` 卸载
|
|
267
|
+
| `tm_ledger` | **领队的任务清单**(`add` / `doing` / `done` / `blocked` / `list`),存在宿主自己的 `ctx.storage` 里、按会话分开——OpenCode 2.x 不给插件 `todowrite`,LEDGER 规则从此有了落点。同一个要求重复提出只算一条;编号撞上两条会拒绝并把两条都列出来;`blocked` 带上卡住的原因;写不进存储就报失败,不会说成「已记录」 | 仅领队 |
|
|
268
|
+
| `tm_join` | **子代理回收**——插件侧的派发器已经没有了(`tm_dispatch` 被移除:插件创建的子会话,用户既打不开也停不掉)。派活统一走宿主自己的 `task` / `task { background: true }`,`tm_join` 是它的读端:不带参数=状态快照,`waitMs`=有界等待,`cancel:true` 取消跑飞的子任务,`tm_join { ids: ["ses_…"] }` 则把某个子代理的**整篇**回复经卸载管线取回(句柄 + ≤80 token 预览),而不是几千 token 直接压进上下文。插件重启后它还会从宿主会话树重建登记,遗留的子代理被"接管"而不是丢失。**2.x 上它还会登记宿主自己的 `subagent` 工具派出去的子会话**(凭据就是那句确认里的 `metadata.sessionID`),所以用户明明在屏幕上看着子代理跑、`tm_join` 却说"没有待收集的派发"这种事不会再发生;这类行同时说清自己的正文是从哪儿到的(宿主的注入消息),以及它是靠事件结算的还是靠推断结算的。**停掉一个也是真调用**:`cancel: true` 走宿主自己的 `POST /api/session/{id}/interrupt`(`tm_join { ids: ["ses_…"], cancel: true }` 停指定的那一个,不带 `ids` 就停所有还在跑的)。宿主给这个端点写下的契约是"活动执行被中断返回 interrupted=true,空闲时是 no-op 返回 false",所以回话刻意分成**五种裁决**:已由宿主中断 / 空闲未中断(它当时没在跑——是我们的登记行过时了,不是失败)/ 未确认(调用成功了但宿主没回布尔)/ 无中断缝 / 被宿主拒绝(带上宿主自己的原因),既在回复里计数,也写进轨迹(`stop_tried` / `stop_confirmed` / `stop_refused` / `stop_unknown`,可用 `tm_stats` 读回)。五个不同的事实不会被压成一句"已取消";`resume` 也刻意从不发送,因为"中断后继续消化排队的引导输入"和"取消"正好相反。*(这项能力目前只在 `main` 上:已发布的 1.6.1 在 2.x 上仍然回一句"宿主无 abort 接口,未取消"。)* | 仅 Lead |
|
|
269
|
+
| `tm_stats` | **插件把自己的 trajectory 读回来**:卸载挡在上下文之外的 token(扣掉确实回来的预览)、派发重叠省下的秒数(串行代价减去子代理实际占用的墙钟)、治理计数(被拦子资源、shell 超时夹顶、缓存命中、脱敏次数)——外加**宿主能力矩阵**(每个宿主接口标 `已验证/存在未用/待观察/缺失/需人眼`)。只读本插件自己写的文件;OpenCode 升级后第一个跑它。`{ recent: 20 }` 追加一份逐条调用清单——每次卸载结果的句柄和落盘路径都在里面,这就是"看看刚才那个工具到底返回了什么"的办法(宿主不给插件工具卡片留展开位) | 全角色 |
|
|
270
|
+
|
|
271
|
+
> **v1(1.18.x)人格已在 1.7.0 线里整体移除。** 包只导出 `{id, setup}`,所以
|
|
272
|
+
> `tm_read` / `tm_grep` / `tm_bash` / `tm_ptc_run` / `tm_pty` 一并消失——这些活现在由
|
|
273
|
+
> 宿主自己的 `read` / `grep` / `glob` / `shell` 和它的 `execute`(Code Mode)承担。
|
|
274
|
+
> 治理没有跟着消失:超大的原生结果照样被 `tool.execute.after` 卸载
|
|
280
275
|
> (实测:`shell` 的 12,902 token 变成 78 token 的预览),地址红线和 R6 的按命令分类
|
|
281
|
-
> 都跑在宿主的 `permission.evaluate`
|
|
276
|
+
> 都跑在宿主的 `permission.evaluate` 上。`tm_ledger` 是领队的清单,落在宿主不给插件
|
|
277
|
+
> `todowrite` 的地方。
|
|
282
278
|
> **我们改的一切都不会溢到 Team 之外。** v2 的每个钩子对宿主上所有会话都会触发,所以工具面
|
|
283
279
|
> 裁剪、0.2 温度、黑板注记、原生结果卸载、R6 与地址红线的收紧、强制后台派发,全都会先问一句
|
|
284
280
|
> "这是我们六个角色吗"——`build`、`plan` 和你自己的 agent 保持刚装好时的原样。宿主没告诉我们会话
|
|
285
281
|
> 归属的调用同样不碰,并且会计数(`tm_stats` 里是 `作用域:我们 · 他人 · 未判定`)。
|
|
286
|
-
>
|
|
287
|
-
> 里面点名的是 `read` / `grep` / `shell`
|
|
288
|
-
> 上面这张表描述的是 v1(1.18.x)的工具面,那一份仍然十三个都在。
|
|
282
|
+
> 安装器写出的六个角色提示词,
|
|
283
|
+
> 里面点名的是 `read` / `grep` / `shell` 而不是这些已移除的别名。
|
|
289
284
|
|
|
290
285
|
> **在 OpenCode 2.x 上,交互式浏览交给宿主,治理仍在我们手里。** 桌面端侧边栏挂的是**服务端自己的**浏览器
|
|
291
286
|
> 服务——插件没法把自己的页面注册进去(取证:`docs/research/browser-pane.md`)。所以三个有联网授权的角色
|
|
292
|
-
> (领队 / researcher / tester
|
|
293
|
-
>
|
|
287
|
+
> (领队 / researcher / tester)用宿主的 `browser_*` 工具——自建 `tm_browser` 已在 1.7.0 移除,
|
|
288
|
+
> 宿主目录是唯一的浏览器;没有原生浏览器目录的宿主(CLI / standalone)从此没有浏览器可用,
|
|
289
|
+
> agent 如实报告这个缺口,绝不模拟。交出去的是浏览器,不是治理:活体观测里 `browser_*` **不触发**
|
|
294
290
|
> `permission.evaluate`,所以门禁改挂在 `tool.execute.before` 上——判定每次 navigate/open 的 URL、每次
|
|
295
291
|
> `browser_preview` 的路径,以及写在 `execute` 程序里的浏览器 URL;不合规则就拒绝,而宿主若把已拒绝的调用
|
|
296
292
|
> 照样跑了,就把页面换成同一段拒绝语,越权内容不会进上下文、store 或轨迹。宿主已发出的请求我们撤回不了,
|
|
297
293
|
> 这照实说,不谎称拦住过;`tm_stats` 把两个数分开给(拒绝 N 次 / 被放过去 M 次)。卸载规则在此有一条例外:
|
|
298
294
|
> `browser_snapshot` 是**寻址表**不是文档,所以它是**截断**(每行 `[ref=…]` 都留、丢静态文字,预算
|
|
299
|
-
> `TM_NATIVE_SNAPSHOT_MAX_TOKENS` 默认 1 200
|
|
295
|
+
> `TM_NATIVE_SNAPSHOT_MAX_TOKENS` 默认 1 200)而不是换成句柄。261 个 ref 的页面实测:
|
|
300
296
|
> 从头截断只剩 118 个 ref,这种方式 261 个全留,11 326 token 里只占 1 044。
|
|
301
297
|
|
|
302
298
|
> **固定工具优先级阶梯(每个任务都适用):① 用户自己的 MCP/插件工具
|
|
303
299
|
> → ② TeamMode 受治理工具(`tm_*`) → ③ 模型自己的推理。** 它同时是回退链:某个受治理
|
|
304
300
|
> 工具报错(这台机器没浏览器、主机被拦),agent 会说明情况降到下一级,
|
|
305
301
|
> 而不是躺平;第 ③ 级里缺失的能力只能如实报"缺口",绝不编造。
|
|
306
|
-
> 一个会当场说明的例外:**网络**这一路仍是 `tm_search` / `tm_webfetch`
|
|
307
|
-
>
|
|
302
|
+
> 一个会当场说明的例外:**网络**这一路仍是 `tm_search` / `tm_webfetch`
|
|
303
|
+
> 优先,因为只有这条线带着域名白名单、逐次确认窗和 R6 红线,
|
|
308
304
|
> 换用户的抓取工具去看同一个页面,等于把这三样治理一起绕掉。
|
|
309
305
|
|
|
310
306
|
> **宿主 UI 看不到的一部分。** OpenCode 只给"它自己内置的工具"渲染可展开的
|
|
@@ -349,7 +345,7 @@ HMAC 句柄,agent 真需要 payload 时用 `tm_fetch` 分页取。
|
|
|
349
345
|
`tm_fetch`(HMAC 签名、run 域、带过期)分页读;JSON 句柄还可以直接要
|
|
350
346
|
`fields` 点路径投影(刻意小的 jq 子集:`items[].name`、
|
|
351
347
|
`[].stargazers_count`),大 API 转储只留需要的字段、原文从不进窗口。
|
|
352
|
-
`
|
|
348
|
+
宿主的 `shell` 在它自己的权限规则下跑只读探针,失败以结构化错误返回,不糊原始转储。
|
|
353
349
|
|
|
354
350
|
### 会话 + 项目 + 全局三层记忆(tm_memory)
|
|
355
351
|
|
|
@@ -399,39 +395,22 @@ agent 永远看不到原始搜索页的噪音。
|
|
|
399
395
|
- `tm_webfetch` —— 已知 URL,单次受治理 GET。它抓到的搜索引擎页面同样
|
|
400
396
|
自动提取为命中列表。`registry.npmjs.org/<pkg>/latest` 这类 JSON 端点
|
|
401
397
|
原样透传。
|
|
402
|
-
- `
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
`
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
`TM_BROWSER_SNAPSHOT_MAX_TOKENS`(默认 1200)硬顶。
|
|
415
|
-
**引擎分工:** 主引擎是 `playwright-core`(optionalDependencies——
|
|
416
|
-
需 **Node ≥ 20**;旧版 Node 或导入失败时,整个插件实例自动降级到零依赖
|
|
417
|
-
`cdp-legacy` 引擎,只保留核心动词;可用 `TM_BROWSER_ENGINE=playwright|cdp-legacy`
|
|
418
|
-
钉死)。从不下载浏览器——Playwright 按路径启动**你自己装的**浏览器,
|
|
419
|
-
`npx playwright install` 不属于用户流程(依赖本体在 npm
|
|
420
|
-
install/发布时解析)。默认隔离临时 profile:登录态想跨会话保留,只有
|
|
421
|
-
显式设置 `TM_BROWSER_USER_DATA_DIR` 这一条路。默认没有 cookie 是设计:agent 开的是
|
|
422
|
-
全新 profile,这也是风控站点(比如百度)给你的窗口放行、却给它弹验证墙的原因。
|
|
423
|
-
想让它带登录态:把该变量指到一个**专用目录**,首次人工登录一次。浏览器**自己**
|
|
424
|
-
弹出的站点权限气泡("……想要访问此设备上的其他应用和服务")在启动时就被**自动拒绝**:那个模态框不是
|
|
425
|
-
我们的确认通道、也没有任何超时,在无人看管的机器上会把页面永久挂住。我们从不
|
|
426
|
-
自动"允许"任何权限——真需要该权限的页面会在那项功能上明显失败,而不是在一个
|
|
427
|
-
没人看见的弹窗上悄悄卡死。agent 忘关的窗口现在会被**说出来**,而不只是等回收:
|
|
428
|
-
`open` 在自己的回复里写明收尾义务(带上真实的空闲秒数),回复契约要求 EVIDENCE
|
|
429
|
-
给出工具自己的关闭裁决,`tm_join` 会在子代理已结算却还占着窗口时告诉 lead
|
|
430
|
-
「⚠ N 个浏览器还开着」——不会只有你一个人发现它还在。
|
|
398
|
+
- **交互式浏览交给宿主自己的 `browser_*` 工具**(`browser_tabs_open` ·
|
|
399
|
+
`browser_navigate` · `browser_snapshot` · `browser_click` · `browser_evaluate`
|
|
400
|
+
…)。自建 `tm_browser` 已在 **1.7.0 移除**(破坏性变更):桌面端侧边栏挂的是
|
|
401
|
+
**服务端自己的**浏览器服务,插件没法把自己的页面注册进去(取证:
|
|
402
|
+
`docs/research/browser-pane.md`)。原生目录由 `src/host/v2-browser-gate.ts` 在
|
|
403
|
+
`execute.before` 上把关——每次 navigate/open 的 URL、每次 `browser_preview` 的路径、
|
|
404
|
+
以及写在 `execute` 程序里的浏览器 URL,都按地址红线和环境文件规则分类;宿主若把已拒绝的
|
|
405
|
+
调用照样跑了,就把页面换成同一段拒绝语,越权内容不会进上下文、store 或轨迹。
|
|
406
|
+
调用约定与已删除的工具不同:`evaluate` 的参数是 `{tabID, script}`,`script` 是**表达式**
|
|
407
|
+
(不是函数源文本),返回对象要自己 `JSON.stringify` 成标量;快照的可寻址记号形如
|
|
408
|
+
`@e8 [link]`。**已知代价,已接受:** 没有原生浏览器目录的宿主(CLI / standalone)
|
|
409
|
+
从此没有浏览器可用——agent 如实报告这个缺口,绝不模拟。
|
|
431
410
|
|
|
432
411
|
**伪装浏览器请求头后仍收到 403** 时,错误信息是一条指令:该站点的门槛是
|
|
433
|
-
JS 挑战 / TLS 指纹级别,只有真实浏览器能过——会直接让 agent
|
|
434
|
-
|
|
412
|
+
JS 挑战 / TLS 指纹级别,只有真实浏览器能过——会直接让 agent 用宿主原生
|
|
413
|
+
`browser_navigate` 打开该 URL(再用 `browser_snapshot` 读)。搜索结果提取同时过滤已知
|
|
435
414
|
噪音:引擎自身包装链接(`so.com/link?`、`ai.so.com`)和同名不同站的域名
|
|
436
415
|
(`maimai.cn` 脉脉 ≠ maimai DX 游戏)不会混入命中列表——用
|
|
437
416
|
`TM_HIT_BLACKLIST` 可扩展命中黑名单。
|
|
@@ -448,7 +427,7 @@ JS 挑战 / TLS 指纹级别,只有真实浏览器能过——会直接让 age
|
|
|
448
427
|
`TM_WEBFETCH_ALLOWED_DOMAINS` 扩展(`"*"` 放开全部主机;自定义列表是
|
|
449
428
|
**替换**种子,保留引擎主机否则 `tm_search` 没了目标)。architect /
|
|
450
429
|
implementer / reviewer **没有**联网授权——网络问题会报告为缺口,绝不编造。
|
|
451
|
-
tester
|
|
430
|
+
tester 仅持有宿主原生 `browser_*` 工具,用于本项目的治理化 UI 验证(本地开发服务器、
|
|
452
431
|
预览路由);开放网络抓取仍归两个联网角色。
|
|
453
432
|
|
|
454
433
|
**白名单外是门,不是墙。** 当抓取 / 搜索 / 浏览器打开的目标主机不在白名单
|
|
@@ -459,6 +438,10 @@ env 文件 URL 和非 http(s) 协议保持硬拦截、无弹窗——R6 红线
|
|
|
459
438
|
|
|
460
439
|
### 安全:R6 + R2 审批门禁
|
|
461
440
|
|
|
441
|
+
**在 OpenCode 2.x 上,R6 默认开启。** Team 角色用原生 `read` 读 `.env` 会被直接拒——没有同意路径;读环境变量的 shell 命令
|
|
442
|
+
走宿主自己的权限提示(2.x 上插件弹不出对话框,所以 shell 面是宿主的 `ask`,env-FILE 面是硬 `deny`)。
|
|
443
|
+
关闭方式:插件选项 `envProtect: false`,或 `TM_ENV_PROTECT=off`。
|
|
444
|
+
|
|
462
445
|
**R6 环境变量保护。** TeamMode 激活时,模型不能悄悄读环境变量。env 读取
|
|
463
446
|
(`printenv`、`env`、`Get-ChildItem env:` 等)和 env 文件(`.env`、shell rc)
|
|
464
447
|
走 OpenCode **官方确认弹窗**;没人应答的弹窗在 `TM_ASK_TIMEOUT_MIN`(默认
|
|
@@ -523,12 +506,17 @@ Team Lead 自己从不删黑板,你可以随时审计任何一次运行。
|
|
|
523
506
|
|
|
524
507
|
```jsonc
|
|
525
508
|
{
|
|
526
|
-
"
|
|
527
|
-
|
|
509
|
+
"plugins": [
|
|
510
|
+
{ "package": "@te-river/opencode-team-mode@latest", "options": { "defaultAgent": false } }
|
|
528
511
|
]
|
|
529
512
|
}
|
|
530
513
|
```
|
|
531
514
|
|
|
515
|
+
注意形状:2.x 的插件条目要么是字符串,要么是带 `package` 与 `options` 的**对象**。1.x 那种
|
|
516
|
+
`["@te-river/opencode-team-mode@latest", { … }]` 元组会被直接拒(`path=$.plugins.1 kind=invalid`,
|
|
517
|
+
2026-10-06 实测)。选项确实能传进来——用对象形状时 `{ "ttlDays": 7 }` 的 boot 行读出
|
|
518
|
+
`board_ttl_days=7`,这是实测不是文档承诺。
|
|
519
|
+
|
|
532
520
|
你自己定义的同名 agent 永远优先;插件从不覆盖用户定义。覆盖、加人、停用
|
|
533
521
|
见[自定义](#-自定义)。
|
|
534
522
|
|
|
@@ -537,9 +525,9 @@ Team Lead 自己从不删黑板,你可以随时审计任何一次运行。
|
|
|
537
525
|
| 环境变量 | 默认 | 用途 |
|
|
538
526
|
|---|---|---|
|
|
539
527
|
| `TM_ENV_PROTECT` | `strict` | R6 模式:`strict` / `standard` / `off`(off 同时解除审批计时器)
|
|
540
|
-
| `TM_R6_FINE_ASK` |
|
|
528
|
+
| `TM_R6_FINE_ASK` | 按命令行判定 | 命令行由宿主的 `permission.evaluate` 钩子逐次判定,所以普通 `git status` 什么都不问、导出环境变量照样问。`off` 退回"每条 shell 命令都问"——宿主不提供该钩子时也会自动走这条路,而且启动日志会说是哪一个原因造成的 |
|
|
541
529
|
| `TM_V2_CODEMODE` | catalog(`direct` 需显式开启)——**仅 v2** | 我们的工具怎么送到模型面前。OpenCode 2.x 用 `options.codemode` 决定可见性。我们曾默认发 `codemode:false` 并宣称"以真实定义交付"——**一次 2.0.16 桌面端活体会话把它推翻了**:发了那个标志之后,十个 `tm_*` 仍然只出现在宿主的 Code Mode 目录里(原文:"They cannot be called directly…"),模型可直接调用的是那九个原生工具。所以默认什么都不发,`direct` 留给可能认它的构建做实验。能核对的只有关停记录里的 `tools_in_request`(`tm_stats` 渲染成"请求内实际可见=…"),不是我们发出的标志 |
|
|
542
|
-
| `TM_PRIVATE_SPACE` |
|
|
530
|
+
| `TM_PRIVATE_SPACE` | `deny` | 私网(回环、RFC1918、ULA、CGNAT、`.localhost`)经我们工具时的行为:`allow` 放开整段,`deny` 拒绝。默认 `deny`,因为 2.x 插件弹不出窗子——"等用户批准"在一台给不出确认框的宿主上不是闸门,是让 agent 干等。所以拒绝语会印出两条操作者自己走得通的出口(`TM_PRIVATE_SPACE=allow`,或把这一台主机名写进 `TM_WEBFETCH_ALLOWED_DOMAINS`)。元数据 / 链路本地 / 保留段不在这个开关管辖内:任何设置都拒,也没有批准路径 |
|
|
543
531
|
| `TM_V2_BROWSER_GATE` | 开——**仅 v2** | 对宿主 `browser_*` 目录的门禁(`execute.before` 判 URL 与 `browser_preview` 路径,也扫 `execute` 程序里出现的浏览器 URL)。`off` 恢复宿主无治理的浏览;启动行与 `tm_stats` 会说清当前是哪种 |
|
|
544
532
|
| `TM_NATIVE_SNAPSHOT_MAX_TOKENS` | 1200——**仅 v2** | 原生 `browser_snapshot` / `browser_find` 在上下文里保留的预算。带 ref 的行优先占位,静态文字先被删;超过 `预算 × 4` 时回复会说明有多少 ref 行没装下,kept + dropped 恒等于总行数 |
|
|
545
533
|
| `TM_NATIVE_REPORT_MAX_TOKENS` | 1600——**仅 v2** | 报告形原生结果(带 Markdown 表格的那种:经 Code Mode 回来的 `tm_stats`、`tm_join` 汇总)在上下文里保留的预算。表格行和小标题优先占位,被删的是表格之间的散文——缺一行的表格就不是表格;全文仍在句柄里 |
|
|
@@ -557,20 +545,26 @@ Team Lead 自己从不删黑板,你可以随时审计任何一次运行。
|
|
|
557
545
|
| `TM_BLACKBOARD_TTL` | `7` | 存储保留天数 |
|
|
558
546
|
| `TM_BOARD_MAX_CHARS` | `200000` | tm_board_write:单个黑板文件的字符上限——超了就拒写并提示拆 topic,而不是把交付物截断 |
|
|
559
547
|
| `TM_BOARD_MAX_FILES` | `200` | tm_board_write:一个会话目录允许的 markdown 文件数;回收只由 TTL 清扫负责,所以拒绝文案会点出 `ttlDays` |
|
|
560
|
-
| `TM_BASH_READONLY_ALLOWED` | 内置表 | tm_bash 白名单 |
|
|
561
548
|
| `TM_SEARCH_DEFAULT_ENGINE` | `auto` | tm_search 未显式给 `engine` 时的默认引擎(`auto` = 分类 + 并行扇出 + RRF 融合;也可钉表中任一引擎) |
|
|
562
549
|
| `TM_SEARCH_WEIGHTS` | 未设 | 按引擎覆盖融合权重,如 `bing=0.3,hn=0.25`;未列出的沿用内置表 |
|
|
563
550
|
| `TM_SEARCH_RELEVANCE_FLOOR` | `0.35` | 与查询词零重叠的命中只保留该比例的权重(压垃圾,不删引擎) |
|
|
564
551
|
| `TM_SEARCH_MAX_HITS` | `10` | 每引擎腿与融合列表保留的命中数 |
|
|
565
552
|
| `TM_SEARCH_DISABLED_ENGINES` | 未设 | 从引擎表与所有 `auto` 路由中移除的引擎(`sogou,baidu` 写法) |
|
|
566
|
-
| `
|
|
567
|
-
| `TM_BROWSER_IDLE_MS` | `180000` | 无人触碰的浏览器会话超过该毫秒数自动关闭并提示用户(0 关闭该回收)——没人负责的窗口是打扰用户的 bug |
|
|
568
|
-
| `TM_BROWSER_ASK_EVAL` | `on` | `evaluate_script` 在**你的**浏览器里跑任意 JS——这是域白名单管不住的唯一动词(白名单限制我们去哪儿导航,管不了已加载的页面交回什么)。每个浏览器会话走一次官方确认窗;没有 ask 桥就拒绝。`off` 恢复旧行为;结果脱敏(JWT/bearer/cookie/api-key 形状)不可关闭 |
|
|
569
|
-
| `TM_WEB_CACHE_TTL_SEC` | `300` | 受治理抓取在同一 URL 上可复用多久(0 = 关)。tm_webfetch / tm_search / PTC 桥共用一份缓存;条目以哈希命名(带令牌的查询串不落盘),且只在**静态白名单**放行的那一跳读写——弹窗授权仍是逐请求的,复用命中会标注 缓存命中 |
|
|
570
|
-
| `TM_BROWSER_IMAGE_MAX_BYTES` | `400000` | `take_screenshot { image:true }` 内联给模型的 JPEG 上限;超过则只回路径并说明原因 |
|
|
553
|
+
| `TM_WEB_CACHE_TTL_SEC` | `300` | 受治理抓取在同一 URL 上可复用多久(0 = 关)。tm_webfetch / tm_search 共用一份缓存;条目以哈希命名(带令牌的查询串不落盘),且只在**静态白名单**放行的那一跳读写——弹窗授权仍是逐请求的,复用命中会标注 缓存命中 |
|
|
571
554
|
| `TM_BASH_TIMEOUT_PROBE_MS` | `60000` | 对只读探针命令(P3 白名单内)强制夹顶模型自设的 `timeout`(0 关闭) |
|
|
555
|
+
| `TM_PRUNE` | `on` | `off` 完全关闭上下文裁剪(已结算的消息正文留在请求里) |
|
|
556
|
+
| `TM_PRUNE_AT_PERCENT` | `70` | 请求达到模型窗口的这个比例就开始裁;从 `limit.context` 推导,不是写死的 token 数。**钳制在 40–95**——低于 40 会被静默抬到 40,所以按 5 复现其实测的是 40 |
|
|
557
|
+
| `TM_PRUNE_KEEP_TAIL_PERCENT` | `40` | 尾部逐字保留的窗口比例;最新一条永远保留 |
|
|
558
|
+
| `TM_RETRY` | `on` | `off` 关闭错峰重试(不再注入等待秒数、不再有冷却期) |
|
|
559
|
+
| `TM_RETRY_BASE_MS` | `5000` | 配额/限流错误后的首次退避;每连续一次错误翻倍 |
|
|
560
|
+
| `TM_RETRY_MAX_MS` | `60000` | 退避上限 |
|
|
561
|
+
| `TM_RETRY_JITTER` | `0.3` | 等待时间的 ± 抖动比例,避免并行会话同时重发 |
|
|
562
|
+
| `TM_RETRY_BREAK_AFTER` | `5` | 连续多少次错误后进入冷却 |
|
|
563
|
+
| `TM_RETRY_COOLDOWN_MS` | `60000` | 熔断后拒绝新子代理派发的时长 |
|
|
564
|
+
| `TM_SPLIT_ADVICE` | `on` | `off` 关闭拆分提示(提示词纪律仍在) |
|
|
565
|
+
| `TM_SPLIT_BRIEF_TOKENS` | `4000` | 派发 brief 超过这个体积,下一次请求会收到拆分提示。**钳制 ≥200**——低于 200 会被静默抬高,所以按 50 复现其实测的是 200 |
|
|
566
|
+
| `TM_SPLIT_MAX_CRITERIA` | `3` | 提示词自己的规则:验收标准超过这个条数就该拆 |
|
|
572
567
|
| `TM_BASH_TIMEOUT_MAX_MS` | `0` | 其它 bash 命令的可选全局上限——默认关闭,真实构建保留它要的超时 |
|
|
573
|
-
| `TM_PTY_MAX` | `4` | 本插件同时最多保持多少个 `tm_pty` 终端会话 |
|
|
574
568
|
| `TM_JOIN_MAX_WAIT_MS` | `60000` | `tm_join { waitMs }` 的上限。过去是 300 000,于是有了一次"连续两次各等 5 分钟、期间 lead 什么都没做"的实测——等待不是并行,所以默认改成"看一眼就去干活"。上一次没等到任何结算时,第二次等待被截到 10 秒并附替代动作 |
|
|
575
569
|
| `TM_STORE_RECLAIM` | `on` | 启动时回收“升级留下的遗产”:超过 TTL 没动静的分片,以及临时目录回退点上分片之前的 `blackboard/` + `trajectory/`(一台真实机器上实测滞留 503 MB 过期 run,而搬家后没有任何清扫器指向那里)。只删超过 TTL 的条目——新鲜的 run 一定留着,因为升级前起来的会话可能还在往里写。设 `off` 就完全不碰磁盘(测试执行器会设它) |
|
|
576
570
|
| `TM_TASK_OFFLOAD` | `on` | 把宿主的后台子代理压在 token 预算内:`task { background: true }` 完成时宿主会把子代理全文注入你的会话,这里把超限的正文换成预览 + 取回指针(`tm_join { ids: [...] }`)。**只碰**同时满足三条的 part:`synthetic === true`、正文精确匹配宿主自己的 `<task id=… state="completed">` 信封、且超过文本卸载阈值;任一不满足就原样放过。不往磁盘复制任何东西——全文本来就写在子会话里。`off` 恢复宿主原样注入。**OpenCode 2.x 上这一半不适用**:v2 不会把注入后的消息在落盘前交给插件,而我们刻意不改写发出的消息(对那一层形状猜错就是静默删证据,v1 的 `experimental.chat.messages.transform` 就是因此一直没实现)。v2 的补偿是契约而不是改写:超限交付写进黑板文件、回复里带路径,领队读摘要、用 `tm_join` 取全文 |
|
|
@@ -580,24 +574,13 @@ Team Lead 自己从不删黑板,你可以随时审计任何一次运行。
|
|
|
580
574
|
| `TM_COMPACTION_AUTOCONTINUE` | `on` | 设 `off` 则压缩后不让宿主静默续跑,先由人复核状态 |
|
|
581
575
|
| `TM_SHELL_NO_COLOR` | `on` | 经 `shell.env` 给每个子 shell 注入 `NO_COLOR`/`TERM=dumb`(ANSI 进度条纯属上下文税)。绝不覆盖宿主已设的值 |
|
|
582
576
|
| `TM_SHELL_ENV` | — | 显式 `KEY=VALUE;KEY2=VALUE2` 透传进子 shell——刻意用白名单,避免这个钩子变成父环境泄露通道 |
|
|
583
|
-
| `TM_WEBFETCH_ALLOWED_DOMAINS` |
|
|
584
|
-
| `TM_BROWSER_PATH` | 自动探测 | tm_browser 可执行文件覆盖(默认用你的默认浏览器——Chromium 系时;否则回退 Edge/Chrome 探测) |
|
|
585
|
-
| `TM_BROWSER_HEADLESS` | `auto` | `1` 无头(CI)/ `0` 有头 / `auto`(仅无显示的 Linux 用无头) |
|
|
586
|
-
| `TM_BROWSER_ENGINE` | `playwright` | `playwright`(需 Node ≥ 20;导入失败自动降级)/ `cdp-legacy`(零依赖 CDP pipe,仅核心动词) |
|
|
587
|
-
| `TM_BROWSER_SNAPSHOT_MAX_TOKENS` | `1200` | `take_snapshot` 载荷硬顶 |
|
|
588
|
-
| `TM_BROWSER_USER_DATA_DIR` | —(隔离临时 profile) | 显式持久 profile 目录——登录态跨会话保留的唯一途径,两个引擎(playwright 与 cdp-legacy)都支持。请用**专用空目录**(如 `D:\tm-browser-profile`),首次人工登录一次;指向浏览器自己的数据目录(`…\Microsoft\Edge\User Data`、`google-chrome`、Firefox `Profiles`)会在启动前被拒绝——那等于让 agent 以你的身份上网,而进程归强杀式回收器管 |
|
|
577
|
+
| `TM_WEBFETCH_ALLOWED_DOMAINS` | `"*"` | tm_webfetch / tm_search 白名单(`"*"` 全开;空 = 全拒;自定义值**替换**种子——保留引擎主机)。`"*"` **不覆盖私网**:回环 / RFC1918 / CGNAT / `.localhost` 仍然每次都要弹确认窗;不可路由段(169.254.0.0/16 元数据端点、0.0.0.0/8、组播、保留段,以及这些地址的 IPv4-mapped 与 DNS64 写法)是不可被任何配置打开的硬红线 |
|
|
589
578
|
| `TM_MEMORY_GLOBAL_DIR` | `~/.opencode-team/memories/global/` | tm_memory GLOBAL 层存储 |
|
|
590
579
|
| `TM_MEMORY_SESSION_TTL_MIN` | `240` | session 层条目 TTL(惰性 + 启动清扫) |
|
|
591
580
|
| `TM_MEMORY_MAX_ENTRIES` | `200` | 每作用域条目上限;超限 add 故意失败——先跑 `compact` |
|
|
592
581
|
| `TM_MEMORY_STALE_DAYS` | `30` | 超过此天数的条目在搜索结果标 `[stale Nd]`(`0` 关闭) |
|
|
593
582
|
| `TM_MEMORY_SESSION_PERSIST` | —(瞬态) | `1` 时 session 条目同时落盘 `memories/sessions/<sid>/` |
|
|
594
583
|
| `TM_HIT_BLACKLIST` | `maimai.cn` | 永不进入搜索命中列表的额外域名(逗号/分号分隔;过滤同名不同站噪音) |
|
|
595
|
-
| `TM_PTC_MAX_PROGRAM_CHARS` | `4000` | PTC 程序源码上限 |
|
|
596
|
-
| `TM_PTC_MAX_CALLS` | `20` | PTC 单次运行桥接调用预算(1–200) |
|
|
597
|
-
| `TM_PTC_MAX_ERRORS` | `3` | PTC 单次运行错误预算(1–50) |
|
|
598
|
-
| `TM_PTC_TIMEOUT_MS` | `60000` | PTC 单次运行墙钟超时(5s–10min) |
|
|
599
|
-
| `TM_PTC_ENGINE` | `auto` | `auto`(worker→inline 降级)/ `worker` / `inline` |
|
|
600
|
-
| `TM_PTC_WEB_BRIDGE` | `on` | 向 PTC 程序暴露 `tm.search` / `tm.webfetch`(`off` 从桥接集移除) |
|
|
601
584
|
|
|
602
585
|
---
|
|
603
586
|
|
|
@@ -657,14 +640,25 @@ Team Lead 自己从不删黑板,你可以随时审计任何一次运行。
|
|
|
657
640
|
|
|
658
641
|
**停用一个:** `"researcher": { "disable": true }`。
|
|
659
642
|
|
|
660
|
-
**黑板保留期**
|
|
643
|
+
**黑板保留期** 用插件条目的 `options`:
|
|
644
|
+
|
|
645
|
+
```jsonc
|
|
646
|
+
{
|
|
647
|
+
"plugins": [
|
|
648
|
+
{ "package": "@te-river/opencode-team-mode@latest", "options": { "ttlDays": 7 } }
|
|
649
|
+
]
|
|
650
|
+
}
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
有效区间 (0, 365],非法值回退 5。2026-10-06 实测:这样写时 `ttlDays: 9` 的 boot 行读出
|
|
654
|
+
`board_ttl_days=9`。(1.x 的元组形状在 2.x 会被拒:`path=$.plugins.1 kind=invalid`。)
|
|
661
655
|
|
|
662
656
|
---
|
|
663
657
|
|
|
664
658
|
## ❓ FAQ
|
|
665
659
|
|
|
666
660
|
**会不会很烧 token?**
|
|
667
|
-
恰恰相反,省 token 就是设计目标。卸载 + 80 token 预览 +
|
|
661
|
+
恰恰相反,省 token 就是设计目标。卸载 + 80 token 预览 + 宿主 Code Mode 的 `execute` 的存在
|
|
668
662
|
理由就是:五 agent 流水线要是裸接一个上下文窗口,那才叫烧 token。治理本身
|
|
669
663
|
就是省 token 的机制。
|
|
670
664
|
|
|
@@ -687,7 +681,8 @@ OpenCode 按 spec 字符串缓存插件,从不重新解析 `@latest`(上游
|
|
|
687
681
|
|
|
688
682
|
**CLI(TUI)能用吗,还是只有桌面版?**
|
|
689
683
|
都能。桌面版多了彩色 agent 选择器和并行面板;受治理工具和整个工作流与
|
|
690
|
-
|
|
684
|
+
宿主无关。交互式浏览是宿主自己的 `browser_*` 目录,所以没有原生浏览器的
|
|
685
|
+
宿主(CLI / standalone)就没有浏览器可用——agent 如实报告这个缺口,绝不模拟。
|
|
691
686
|
|
|
692
687
|
**确认弹窗我不理会会怎样?**
|
|
693
688
|
`TM_ASK_TIMEOUT_MIN`(默认 1 分钟)后自动拒绝。插件从不自我批准——它
|
|
@@ -697,10 +692,9 @@ OpenCode 按 spec 字符串缓存插件,从不重新解析 `@latest`(上游
|
|
|
697
692
|
|
|
698
693
|
## 🗑️ 卸载
|
|
699
694
|
|
|
700
|
-
1. 从配置文件的 `"
|
|
701
|
-
的安装器也写在那里;如果你是在 2.x 上装的,还要删掉生成的
|
|
695
|
+
1. 从配置文件的 `"plugins"` 数组里移除该条目;如果你是在 2.x 上装的,还要删掉生成的
|
|
702
696
|
`~/.config/opencode/agents/*.md` 与 `commands/team-*.md`,以及你不再需要的
|
|
703
|
-
`default_agent: "
|
|
697
|
+
`default_agent: "Team"`。
|
|
704
698
|
2. 想回收磁盘就删缓存目录(见[安装](#-现在读一遍以后省一小时)里的表格)。
|
|
705
699
|
3. 重启 OpenCode。agent、命令、工具全部消失;`<repo>/.git/opencode-team/`
|
|
706
700
|
下的存储(全局记忆在 `~/.opencode-team/`)都是普通文件,随时可删。
|
|
@@ -714,26 +708,27 @@ OpenCode 按 spec 字符串缓存插件,从不重新解析 `@latest`(上游
|
|
|
714
708
|
```
|
|
715
709
|
opencode-team-mode/
|
|
716
710
|
├── src/
|
|
717
|
-
│ ├── index.ts ← 插件入口(
|
|
711
|
+
│ ├── index.ts ← 插件入口({id, setup}——仅 v2)
|
|
718
712
|
│ ├── agents.ts ← Agent 结构(mode、颜色、温度、白名单矩阵)
|
|
719
713
|
│ ├── prompts/ ← Agent 提示词(lead / specialists / shared)——测试钉死
|
|
720
714
|
│ ├── commands.ts ← 斜杠命令定义
|
|
721
715
|
│ ├── blackboard.ts ← 共享黑板 + TTL 清扫
|
|
722
716
|
│ ├── envprotect.ts ← R6 门面(patterns / 分类器 / 门禁谓词 / hook)
|
|
723
|
-
│ ├──
|
|
717
|
+
│ ├── identity.ts ← Agent 名身份(大小写不敏感的 lead 判定)
|
|
724
718
|
│ ├── tm/ ← 受治理工具:pipelines / store / preview / guard / refs /
|
|
725
|
-
│ │ webfetch / search / memory / browser / shell-bridge /
|
|
726
|
-
│
|
|
727
|
-
|
|
719
|
+
│ │ webfetch / search / memory / browser / shell-bridge / board / ledger
|
|
720
|
+
│ ├── host/ ← v2 人格(setup / guard / offload / session / events / …)
|
|
721
|
+
│ └── types.ts ← 加载器契约类型
|
|
722
|
+
├── docs/installation.md ← 历史 1.18.x 指南(已不再支持)
|
|
728
723
|
├── docs/installation-v2.md ← 2.x 安装指南(角色以生成的配置文件形式落地)
|
|
729
724
|
├── scripts/ ← 一行安装脚本(bash / PowerShell)
|
|
730
725
|
├── pt07/ ← PT-07 基线套件(种子化 A/B token 测量)
|
|
731
726
|
└── README.*.md ← 你在这里(有两个版本)
|
|
732
727
|
```
|
|
733
728
|
|
|
734
|
-
加载器只调一次 `
|
|
735
|
-
|
|
736
|
-
|
|
729
|
+
加载器只调一次 `setup(ctx)`:注册 `tm_*` 工具、在 `permission.evaluate` 上装
|
|
730
|
+
R6/地址守卫、在 `tool.execute.after` 上挂 JIT 卸载、并发布黑板注记。用户自定义的
|
|
731
|
+
同名 agent 永远赢——插件从不覆盖。
|
|
737
732
|
|
|
738
733
|
---
|
|
739
734
|
|
|
@@ -754,8 +749,8 @@ opencode-team-mode/
|
|
|
754
749
|
## 🔗 链接
|
|
755
750
|
|
|
756
751
|
- [npm 包](https://www.npmjs.com/package/@te-river/opencode-team-mode) — `@te-river/opencode-team-mode`
|
|
757
|
-
- [
|
|
758
|
-
- [
|
|
752
|
+
- [安装指南(**OpenCode 2.x**)](./docs/installation-v2.md) — 受支持的装法:2.x 插件不能创建 agent,六个角色和六条命令要生成到配置目录
|
|
753
|
+
- [安装指南(1.18.x)](./docs/installation.md) — **仅历史**:1.18.x 人格已在 1.7.0 线里移除,本页只作参考,不是可用的安装路径
|
|
759
754
|
- [OpenCode Desktop](https://opencode.ai) — 官网与下载
|
|
760
755
|
- [OpenCode 文档](https://opencode.ai/docs) — 配置与插件文档
|
|
761
756
|
- [OpenCode 插件 API](https://opencode.ai/docs/plugins) — 开发你自己的插件
|
package/dist/agents.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAqI9D;;;;wCAIwC;AACxC,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,eAAe,EAAE,UAAU,EAAE,OAAO,GAAG,IAAI,CAGhG;AA6KD,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAW9C,CAAA"}
|