@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.
- package/README.md +732 -634
- package/README.zh-CN.md +655 -576
- package/dist/agents.d.ts +6 -1
- package/dist/agents.d.ts.map +1 -1
- package/dist/agents.js +103 -522
- package/dist/agents.js.map +1 -1
- package/dist/approval-gate.d.ts +16 -0
- package/dist/approval-gate.d.ts.map +1 -1
- package/dist/approval-gate.js +8 -1
- package/dist/approval-gate.js.map +1 -1
- package/dist/blackboard.d.ts.map +1 -1
- package/dist/blackboard.js +3 -2
- package/dist/blackboard.js.map +1 -1
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +7 -6
- package/dist/commands.js.map +1 -1
- package/dist/envprotect/bash-classify.d.ts +42 -0
- package/dist/envprotect/bash-classify.d.ts.map +1 -0
- package/dist/envprotect/bash-classify.js +221 -0
- package/dist/envprotect/bash-classify.js.map +1 -0
- package/dist/envprotect/gate-predicates.d.ts +57 -0
- package/dist/envprotect/gate-predicates.d.ts.map +1 -0
- package/dist/envprotect/gate-predicates.js +174 -0
- package/dist/envprotect/gate-predicates.js.map +1 -0
- package/dist/envprotect/hook.d.ts +45 -0
- package/dist/envprotect/hook.d.ts.map +1 -0
- package/dist/envprotect/hook.js +158 -0
- package/dist/envprotect/hook.js.map +1 -0
- package/dist/envprotect/path-classify.d.ts +16 -0
- package/dist/envprotect/path-classify.d.ts.map +1 -0
- package/dist/envprotect/path-classify.js +72 -0
- package/dist/envprotect/path-classify.js.map +1 -0
- package/dist/envprotect/patterns.d.ts +77 -0
- package/dist/envprotect/patterns.d.ts.map +1 -0
- package/dist/envprotect/patterns.js +182 -0
- package/dist/envprotect/patterns.js.map +1 -0
- package/dist/envprotect.d.ts +19 -217
- package/dist/envprotect.d.ts.map +1 -1
- package/dist/envprotect.js +18 -803
- package/dist/envprotect.js.map +1 -1
- package/dist/fs-safe.d.ts +16 -0
- package/dist/fs-safe.d.ts.map +1 -0
- package/dist/fs-safe.js +56 -0
- package/dist/fs-safe.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -6
- package/dist/index.js.map +1 -1
- package/dist/prompts/lead.d.ts +7 -0
- package/dist/prompts/lead.d.ts.map +1 -0
- package/dist/prompts/lead.js +230 -0
- package/dist/prompts/lead.js.map +1 -0
- package/dist/prompts/shared.d.ts +8 -0
- package/dist/prompts/shared.d.ts.map +1 -0
- package/dist/prompts/shared.js +118 -0
- package/dist/prompts/shared.js.map +1 -0
- package/dist/prompts/specialists.d.ts +12 -0
- package/dist/prompts/specialists.d.ts.map +1 -0
- package/dist/prompts/specialists.js +218 -0
- package/dist/prompts/specialists.js.map +1 -0
- package/dist/shell-text.d.ts +14 -0
- package/dist/shell-text.d.ts.map +1 -0
- package/dist/shell-text.js +16 -0
- package/dist/shell-text.js.map +1 -0
- package/dist/tm/args-schema.d.ts +36 -0
- package/dist/tm/args-schema.d.ts.map +1 -0
- package/dist/tm/args-schema.js +191 -0
- package/dist/tm/args-schema.js.map +1 -0
- package/dist/tm/browser.d.ts +52 -0
- package/dist/tm/browser.d.ts.map +1 -0
- package/dist/tm/browser.js +361 -0
- package/dist/tm/browser.js.map +1 -0
- package/dist/tm/client-unwrap.d.ts +38 -0
- package/dist/tm/client-unwrap.d.ts.map +1 -0
- package/dist/tm/client-unwrap.js +113 -0
- package/dist/tm/client-unwrap.js.map +1 -0
- package/dist/tm/config.d.ts +46 -18
- package/dist/tm/config.d.ts.map +1 -1
- package/dist/tm/config.js +60 -17
- package/dist/tm/config.js.map +1 -1
- package/dist/tm/guard.d.ts.map +1 -1
- package/dist/tm/guard.js +4 -7
- package/dist/tm/guard.js.map +1 -1
- package/dist/tm/index.d.ts +15 -5
- package/dist/tm/index.d.ts.map +1 -1
- package/dist/tm/index.js +95 -19
- package/dist/tm/index.js.map +1 -1
- package/dist/tm/memory.d.ts +82 -0
- package/dist/tm/memory.d.ts.map +1 -0
- package/dist/tm/memory.js +350 -0
- package/dist/tm/memory.js.map +1 -0
- package/dist/tm/pipelines.d.ts +58 -0
- package/dist/tm/pipelines.d.ts.map +1 -0
- package/dist/tm/pipelines.js +301 -0
- package/dist/tm/pipelines.js.map +1 -0
- package/dist/tm/preview.d.ts +6 -1
- package/dist/tm/preview.d.ts.map +1 -1
- package/dist/tm/preview.js +31 -8
- package/dist/tm/preview.js.map +1 -1
- package/dist/tm/ptc/budgets.d.ts +38 -0
- package/dist/tm/ptc/budgets.d.ts.map +1 -0
- package/dist/tm/ptc/budgets.js +59 -0
- package/dist/tm/ptc/budgets.js.map +1 -0
- package/dist/tm/ptc/contract.d.ts +131 -0
- package/dist/tm/ptc/contract.d.ts.map +1 -0
- package/dist/tm/ptc/contract.js +47 -0
- package/dist/tm/ptc/contract.js.map +1 -0
- package/dist/tm/ptc/driver.d.ts +37 -0
- package/dist/tm/ptc/driver.d.ts.map +1 -0
- package/dist/tm/ptc/driver.js +181 -0
- package/dist/tm/ptc/driver.js.map +1 -0
- package/dist/tm/ptc/engines.d.ts +32 -0
- package/dist/tm/ptc/engines.d.ts.map +1 -0
- package/dist/tm/ptc/engines.js +201 -0
- package/dist/tm/ptc/engines.js.map +1 -0
- package/dist/tm/ptc/gate.d.ts +28 -0
- package/dist/tm/ptc/gate.d.ts.map +1 -0
- package/dist/tm/ptc/gate.js +127 -0
- package/dist/tm/ptc/gate.js.map +1 -0
- package/dist/tm/ptc/index.d.ts +19 -0
- package/dist/tm/ptc/index.d.ts.map +1 -0
- package/dist/tm/ptc/index.js +15 -0
- package/dist/tm/ptc/index.js.map +1 -0
- package/dist/tm/ptc/pscan.d.ts +11 -0
- package/dist/tm/ptc/pscan.d.ts.map +1 -0
- package/dist/tm/ptc/pscan.js +27 -0
- package/dist/tm/ptc/pscan.js.map +1 -0
- package/dist/tm/ptc/summary.d.ts +17 -0
- package/dist/tm/ptc/summary.d.ts.map +1 -0
- package/dist/tm/ptc/summary.js +107 -0
- package/dist/tm/ptc/summary.js.map +1 -0
- package/dist/tm/ptc/tool.d.ts +35 -0
- package/dist/tm/ptc/tool.d.ts.map +1 -0
- package/dist/tm/ptc/tool.js +135 -0
- package/dist/tm/ptc/tool.js.map +1 -0
- package/dist/tm/ptc.d.ts +45 -26
- package/dist/tm/ptc.d.ts.map +1 -1
- package/dist/tm/ptc.js +71 -45
- package/dist/tm/ptc.js.map +1 -1
- package/dist/tm/result.d.ts +34 -0
- package/dist/tm/result.d.ts.map +1 -0
- package/dist/tm/result.js +87 -0
- package/dist/tm/result.js.map +1 -0
- package/dist/tm/shell-bridge.d.ts +22 -0
- package/dist/tm/shell-bridge.d.ts.map +1 -0
- package/dist/tm/shell-bridge.js +70 -0
- package/dist/tm/shell-bridge.js.map +1 -0
- package/dist/tm/store.d.ts.map +1 -1
- package/dist/tm/store.js +2 -1
- package/dist/tm/store.js.map +1 -1
- package/dist/tm/tools.d.ts +13 -71
- package/dist/tm/tools.d.ts.map +1 -1
- package/dist/tm/tools.js +23 -656
- package/dist/tm/tools.js.map +1 -1
- package/dist/tm/webfetch.d.ts +94 -0
- package/dist/tm/webfetch.d.ts.map +1 -0
- package/dist/tm/webfetch.js +225 -0
- package/dist/tm/webfetch.js.map +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,634 +1,732 @@
|
|
|
1
|
-
# OpenCode TeamMode
|
|
2
|
-
|
|
3
|
-
**[English](./README.md)** | **[中文](./README.zh-CN.md)**
|
|
4
|
-
|
|
5
|
-
[](https://www.npmjs.com/package/@te-river/opencode-team-mode)
|
|
6
|
-
[](https://www.npmjs.com/package/@te-river/opencode-team-mode)
|
|
7
|
-
[](./LICENSE)
|
|
8
|
-
|
|
9
|
-
> 🤝 **Multi-agent team collaboration plugin for [OpenCode Desktop](https://opencode.ai)**
|
|
10
|
-
>
|
|
11
|
-
> Adds a complete team of specialized AI agents — Architect, Implementer, Reviewer, Tester, Researcher — orchestrated by a Team Lead, all accessible via simple slash commands.
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
## ✨ What is TeamMode?
|
|
16
|
-
|
|
17
|
-
TeamMode transforms OpenCode Desktop from a single-agent coding assistant into a **full development team**. Each agent has a distinct role, expertise, and personality — just like a real engineering team.
|
|
18
|
-
|
|
19
|
-
Instead of one agent trying to do everything, you get:
|
|
20
|
-
|
|
21
|
-
| Agent | Role | When to use |
|
|
22
|
-
|---|---|---|
|
|
23
|
-
| 🎯 **Team Lead** | Orchestrator | Complex tasks that need planning + multi-step execution |
|
|
24
|
-
| 🏗️ **Architect** | System designer | Design docs, module structure, API contracts |
|
|
25
|
-
| 💻 **Implementer** | Code writer | Building features, writing production code |
|
|
26
|
-
| 🔍 **Reviewer** | Dimension-focused auditor | Single-dimension review (completeness / correctness / impact) —
|
|
27
|
-
| 🧪 **Tester** | Test engineer | Unit tests, integration tests, edge-case coverage, static verification (build / typecheck / lint / API tests) |
|
|
28
|
-
| 🔎 **Researcher** | Knowledge finder |
|
|
29
|
-
|
|
30
|
-
---
|
|
31
|
-
|
|
32
|
-
## 🚀 Quick Start
|
|
33
|
-
|
|
34
|
-
### Prerequisites
|
|
35
|
-
|
|
36
|
-
1. **Install OpenCode Desktop** (if you haven't already):
|
|
37
|
-
|
|
38
|
-
| Platform | Install command |
|
|
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 | Download from [opencode.ai/download](https://opencode.ai/download) |
|
|
44
|
-
|
|
45
|
-
Or install the **CLI/TUI** version:
|
|
46
|
-
```bash
|
|
47
|
-
# one-line script (all platforms)
|
|
48
|
-
curl -fsSL https://opencode.ai/install | bash
|
|
49
|
-
|
|
50
|
-
# or via npm
|
|
51
|
-
npm install -g opencode-ai
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
2. **Node.js ≥ 18** (for npm)
|
|
55
|
-
|
|
56
|
-
### Install TeamMode
|
|
57
|
-
|
|
58
|
-
**Option A — One-line installer:**
|
|
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
|
-
**Option B — Manual config:**
|
|
71
|
-
|
|
72
|
-
Add the plugin to your `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 will automatically install the plugin on startup.
|
|
84
|
-
|
|
85
|
-
> **Tip:** After modifying `opencode.json`, **restart OpenCode Desktop** for changes to take effect.
|
|
86
|
-
|
|
87
|
-
---
|
|
88
|
-
|
|
89
|
-
## ⚙️ Configuration
|
|
90
|
-
|
|
91
|
-
The plugin automatically injects all team agents and commands when OpenCode starts. **No need to manually copy agent files or command definitions.**
|
|
92
|
-
|
|
93
|
-
> ⚠️ **Model choice matters.** Every judgment in the workflow — triage,
|
|
94
|
-
> decomposition, dispatch briefs, synthesis, review-loop verdicts — flows
|
|
95
|
-
> through the **Team Lead**. A weak model in that seat degrades the whole
|
|
96
|
-
> pipeline no matter how strong the specialists are. Pin your best
|
|
97
|
-
> reasoning model to the `team` agent (recipe in
|
|
98
|
-
> [Customization](#customization) below).
|
|
99
|
-
|
|
100
|
-
### Global install (all projects)
|
|
101
|
-
|
|
102
|
-
To enable TeamMode in every project, add the plugin to your global config:
|
|
103
|
-
|
|
104
|
-
```jsonc
|
|
105
|
-
// ~/.config/opencode/opencode.jsonc
|
|
106
|
-
{
|
|
107
|
-
"$schema": "https://opencode.ai/config.json",
|
|
108
|
-
"plugin": [
|
|
109
|
-
"@te-river/opencode-team-mode@latest"
|
|
110
|
-
]
|
|
111
|
-
}
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
---
|
|
115
|
-
|
|
116
|
-
## 📖 Usage
|
|
117
|
-
|
|
118
|
-
### Slash Commands
|
|
119
|
-
|
|
120
|
-
TeamMode adds six slash commands to OpenCode. Type them in the chat input:
|
|
121
|
-
|
|
122
|
-
| Command | Agent | Description |
|
|
123
|
-
|---|---|---|
|
|
124
|
-
| `/team-plan <task>` | Architect | Create a detailed implementation plan with architecture, file manifest, and task breakdown |
|
|
125
|
-
| `/team-implement <task>` | Implementer | Write production code for a feature or task |
|
|
126
|
-
| `/team-review [scope]` | Reviewer | Audit code for bugs, security issues, and quality problems |
|
|
127
|
-
| `/team-test [scope]` | Tester | Generate comprehensive tests with edge-case coverage |
|
|
128
|
-
| `/team-research <topic>` | Researcher | Investigate
|
|
129
|
-
| `/team-run <task>` | Team Lead | **Full workflow** — orchestrates all agents end-to-end |
|
|
130
|
-
|
|
131
|
-
#### Example workflow
|
|
132
|
-
|
|
133
|
-
```
|
|
134
|
-
# 1. Plan the feature
|
|
135
|
-
/team-plan Add user authentication with OAuth2 and JWT tokens
|
|
136
|
-
|
|
137
|
-
# 2. Review the plan, then implement
|
|
138
|
-
/team-implement Implement the auth module as planned
|
|
139
|
-
|
|
140
|
-
# 3. Review the code
|
|
141
|
-
/team-review src/auth/
|
|
142
|
-
|
|
143
|
-
# 4. Write tests
|
|
144
|
-
/team-test src/auth/
|
|
145
|
-
|
|
146
|
-
# Or let the team lead handle everything:
|
|
147
|
-
/team-run Add user authentication with OAuth2 and JWT tokens
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
### Agent Picker
|
|
151
|
-
|
|
152
|
-
You can also invoke agents directly using the `@` mention in OpenCode Desktop:
|
|
153
|
-
|
|
154
|
-
- `@team` — Orchestrate a complex task
|
|
155
|
-
- `@architect` — Design a system or module
|
|
156
|
-
- `@implementer` — Write code
|
|
157
|
-
- `@reviewer` — Review code quality
|
|
158
|
-
- `@tester` — Write tests
|
|
159
|
-
- `@researcher` — Research a topic
|
|
160
|
-
|
|
161
|
-
### Demo
|
|
162
|
-
|
|
163
|
-
A session transcript, recreated from how the flow actually looks. Team is the
|
|
164
|
-
default agent out of the box (see Configuration to opt out), so the user just
|
|
165
|
-
types into a fresh chat:
|
|
166
|
-
|
|
167
|
-
> **User:** Add token-bucket rate limiting to our Express API — 100 requests
|
|
168
|
-
> per minute per user, return 429 when exceeded. Don't touch anything under
|
|
169
|
-
> `src/legacy/`.
|
|
170
|
-
|
|
171
|
-
```text
|
|
172
|
-
team Route: product behavior change → implementer → tester → reviewer
|
|
173
|
-
(3 dispatches → approval gate applies)
|
|
174
|
-
|
|
175
|
-
Research: read README, src/app.ts, src/middleware/*
|
|
176
|
-
Blocking questions: none — 1 assumption listed below
|
|
177
|
-
|
|
178
|
-
PLAN
|
|
179
|
-
Goal: token-bucket limiter, 100 req/min/user, 429 + Retry-After
|
|
180
|
-
Scope: src/middleware/rateLimit.ts (new), src/app.ts (+3 lines)
|
|
181
|
-
Pipeline: implementer → tester → reviewer (correctness)
|
|
182
|
-
Assumption: in-memory bucket, not Redis — say the word to change
|
|
183
|
-
Boundary: src/legacy/** untouched
|
|
184
|
-
Approve to proceed?
|
|
185
|
-
|
|
186
|
-
user approved, go
|
|
187
|
-
|
|
188
|
-
team ▸ @implementer — STATUS: done
|
|
189
|
-
CHANGES: src/middleware/rateLimit.ts (new) · src/app.ts (+3)
|
|
190
|
-
HANDOFF: bucket {tokens, lastRefill}; refill() is a single atomic pass
|
|
191
|
-
EVIDENCE: tsc clean (output above)
|
|
192
|
-
|
|
193
|
-
▸ @tester — STATUS: done · VERDICT: pass (14/14)
|
|
194
|
-
FINDINGS: burst edge, window expiry, concurrent refill covered;
|
|
195
|
-
src/legacy/** byte-identical
|
|
196
|
-
EVIDENCE: vitest 14 passed
|
|
197
|
-
|
|
198
|
-
▸ @reviewer — STATUS: done · VERDICT: approve (correctness)
|
|
199
|
-
FINDINGS: no Critical/Major; 1 Minor (log line noise) noted
|
|
200
|
-
|
|
201
|
-
team Done.
|
|
202
|
-
rate limiter shipped: rateLimit.ts (new) · app.ts (+3) · 14 tests green
|
|
203
|
-
review: approve · assumption: in-memory only · src/legacy/ untouched
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
The only message the user typed was the task and "approved, go". The
|
|
207
|
-
pipeline was a routing-table lookup, execution waited for plan approval,
|
|
208
|
-
and every handoff traveled as a structured skeleton — no file ceremony.
|
|
209
|
-
|
|
210
|
-
### Desktop-specific features
|
|
211
|
-
|
|
212
|
-
In **OpenCode Desktop**, you get additional UX benefits:
|
|
213
|
-
|
|
214
|
-
- 🎨 **Color-coded agents** — Each agent has a distinct color in the chat UI for easy identification.
|
|
215
|
-
- 📋 **Agent picker** — Click the agent dropdown to switch between team agents visually.
|
|
216
|
-
- 🔀 **Parallel sub-tasks** — The Team Lead can dispatch multiple sub-agents simultaneously, with results shown in parallel panels.
|
|
217
|
-
- 📊 **Session history** — All team interactions are saved and searchable in the Desktop session sidebar.
|
|
218
|
-
|
|
219
|
-
---
|
|
220
|
-
|
|
221
|
-
##
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
**
|
|
239
|
-
|
|
240
|
-
(
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
`
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
###
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
The
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
`
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
###
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
```
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
```
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
1
|
+
# OpenCode TeamMode
|
|
2
|
+
|
|
3
|
+
**[English](./README.md)** | **[中文](./README.zh-CN.md)**
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@te-river/opencode-team-mode)
|
|
6
|
+
[](https://www.npmjs.com/package/@te-river/opencode-team-mode)
|
|
7
|
+
[](./LICENSE)
|
|
8
|
+
|
|
9
|
+
> 🤝 **Multi-agent team collaboration plugin for [OpenCode Desktop](https://opencode.ai)**
|
|
10
|
+
>
|
|
11
|
+
> Adds a complete team of specialized AI agents — Architect, Implementer, Reviewer, Tester, Researcher — orchestrated by a Team Lead, all accessible via simple slash commands.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## ✨ What is TeamMode?
|
|
16
|
+
|
|
17
|
+
TeamMode transforms OpenCode Desktop from a single-agent coding assistant into a **full development team**. Each agent has a distinct role, expertise, and personality — just like a real engineering team.
|
|
18
|
+
|
|
19
|
+
Instead of one agent trying to do everything, you get:
|
|
20
|
+
|
|
21
|
+
| Agent | Role | When to use |
|
|
22
|
+
|---|---|---|
|
|
23
|
+
| 🎯 **Team Lead** | Orchestrator | Complex tasks that need planning + multi-step execution |
|
|
24
|
+
| 🏗️ **Architect** | System designer | Design docs, module structure, API contracts |
|
|
25
|
+
| 💻 **Implementer** | Code writer | Building features, writing production code |
|
|
26
|
+
| 🔍 **Reviewer** | Dimension-focused auditor | Single-dimension review (completeness / correctness / impact) — ONE reviewer by default; 3 in parallel only for high-risk changes |
|
|
27
|
+
| 🧪 **Tester** | Test engineer | Unit tests, integration tests, edge-case coverage, static verification (build / typecheck / lint / API tests) |
|
|
28
|
+
| 🔎 **Researcher** | Knowledge finder | Local-repo investigation first (code, configs, installed packages, shipped docs); web lookups via user MCP tools or the governed `tm_webfetch` — one of the two network roles (with the Team Lead) |
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## 🚀 Quick Start
|
|
33
|
+
|
|
34
|
+
### Prerequisites
|
|
35
|
+
|
|
36
|
+
1. **Install OpenCode Desktop** (if you haven't already):
|
|
37
|
+
|
|
38
|
+
| Platform | Install command |
|
|
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 | Download from [opencode.ai/download](https://opencode.ai/download) |
|
|
44
|
+
|
|
45
|
+
Or install the **CLI/TUI** version:
|
|
46
|
+
```bash
|
|
47
|
+
# one-line script (all platforms)
|
|
48
|
+
curl -fsSL https://opencode.ai/install | bash
|
|
49
|
+
|
|
50
|
+
# or via npm
|
|
51
|
+
npm install -g opencode-ai
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
2. **Node.js ≥ 18** (for npm)
|
|
55
|
+
|
|
56
|
+
### Install TeamMode
|
|
57
|
+
|
|
58
|
+
**Option A — One-line installer:**
|
|
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
|
+
**Option B — Manual config:**
|
|
71
|
+
|
|
72
|
+
Add the plugin to your `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 will automatically install the plugin on startup.
|
|
84
|
+
|
|
85
|
+
> **Tip:** After modifying `opencode.json`, **restart OpenCode Desktop** for changes to take effect.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## ⚙️ Configuration
|
|
90
|
+
|
|
91
|
+
The plugin automatically injects all team agents and commands when OpenCode starts. **No need to manually copy agent files or command definitions.**
|
|
92
|
+
|
|
93
|
+
> ⚠️ **Model choice matters.** Every judgment in the workflow — triage,
|
|
94
|
+
> decomposition, dispatch briefs, synthesis, review-loop verdicts — flows
|
|
95
|
+
> through the **Team Lead**. A weak model in that seat degrades the whole
|
|
96
|
+
> pipeline no matter how strong the specialists are. Pin your best
|
|
97
|
+
> reasoning model to the `team` agent (recipe in
|
|
98
|
+
> [Customization](#customization) below).
|
|
99
|
+
|
|
100
|
+
### Global install (all projects)
|
|
101
|
+
|
|
102
|
+
To enable TeamMode in every project, add the plugin to your global config:
|
|
103
|
+
|
|
104
|
+
```jsonc
|
|
105
|
+
// ~/.config/opencode/opencode.jsonc
|
|
106
|
+
{
|
|
107
|
+
"$schema": "https://opencode.ai/config.json",
|
|
108
|
+
"plugin": [
|
|
109
|
+
"@te-river/opencode-team-mode@latest"
|
|
110
|
+
]
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## 📖 Usage
|
|
117
|
+
|
|
118
|
+
### Slash Commands
|
|
119
|
+
|
|
120
|
+
TeamMode adds six slash commands to OpenCode. Type them in the chat input:
|
|
121
|
+
|
|
122
|
+
| Command | Agent | Description |
|
|
123
|
+
|---|---|---|
|
|
124
|
+
| `/team-plan <task>` | Architect | Create a detailed implementation plan with architecture, file manifest, and task breakdown |
|
|
125
|
+
| `/team-implement <task>` | Implementer | Write production code for a feature or task |
|
|
126
|
+
| `/team-review [scope]` | Reviewer | Audit code for bugs, security issues, and quality problems |
|
|
127
|
+
| `/team-test [scope]` | Tester | Generate comprehensive tests with edge-case coverage |
|
|
128
|
+
| `/team-research <topic>` | Researcher | Investigate the local repository first; web lookups via the governed `tm_browser` / `tm_webfetch`, then user MCP tools |
|
|
129
|
+
| `/team-run <task>` | Team Lead | **Full workflow** — orchestrates all agents end-to-end |
|
|
130
|
+
|
|
131
|
+
#### Example workflow
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
# 1. Plan the feature
|
|
135
|
+
/team-plan Add user authentication with OAuth2 and JWT tokens
|
|
136
|
+
|
|
137
|
+
# 2. Review the plan, then implement
|
|
138
|
+
/team-implement Implement the auth module as planned
|
|
139
|
+
|
|
140
|
+
# 3. Review the code
|
|
141
|
+
/team-review src/auth/
|
|
142
|
+
|
|
143
|
+
# 4. Write tests
|
|
144
|
+
/team-test src/auth/
|
|
145
|
+
|
|
146
|
+
# Or let the team lead handle everything:
|
|
147
|
+
/team-run Add user authentication with OAuth2 and JWT tokens
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Agent Picker
|
|
151
|
+
|
|
152
|
+
You can also invoke agents directly using the `@` mention in OpenCode Desktop:
|
|
153
|
+
|
|
154
|
+
- `@team` — Orchestrate a complex task
|
|
155
|
+
- `@architect` — Design a system or module
|
|
156
|
+
- `@implementer` — Write code
|
|
157
|
+
- `@reviewer` — Review code quality
|
|
158
|
+
- `@tester` — Write tests
|
|
159
|
+
- `@researcher` — Research a topic
|
|
160
|
+
|
|
161
|
+
### Demo
|
|
162
|
+
|
|
163
|
+
A session transcript, recreated from how the flow actually looks. Team is the
|
|
164
|
+
default agent out of the box (see Configuration to opt out), so the user just
|
|
165
|
+
types into a fresh chat:
|
|
166
|
+
|
|
167
|
+
> **User:** Add token-bucket rate limiting to our Express API — 100 requests
|
|
168
|
+
> per minute per user, return 429 when exceeded. Don't touch anything under
|
|
169
|
+
> `src/legacy/`.
|
|
170
|
+
|
|
171
|
+
```text
|
|
172
|
+
team Route: product behavior change → implementer → tester → reviewer
|
|
173
|
+
(3 dispatches → approval gate applies)
|
|
174
|
+
|
|
175
|
+
Research: read README, src/app.ts, src/middleware/*
|
|
176
|
+
Blocking questions: none — 1 assumption listed below
|
|
177
|
+
|
|
178
|
+
PLAN
|
|
179
|
+
Goal: token-bucket limiter, 100 req/min/user, 429 + Retry-After
|
|
180
|
+
Scope: src/middleware/rateLimit.ts (new), src/app.ts (+3 lines)
|
|
181
|
+
Pipeline: implementer → tester → reviewer (correctness)
|
|
182
|
+
Assumption: in-memory bucket, not Redis — say the word to change
|
|
183
|
+
Boundary: src/legacy/** untouched
|
|
184
|
+
Approve to proceed?
|
|
185
|
+
|
|
186
|
+
user approved, go
|
|
187
|
+
|
|
188
|
+
team ▸ @implementer — STATUS: done
|
|
189
|
+
CHANGES: src/middleware/rateLimit.ts (new) · src/app.ts (+3)
|
|
190
|
+
HANDOFF: bucket {tokens, lastRefill}; refill() is a single atomic pass
|
|
191
|
+
EVIDENCE: tsc clean (output above)
|
|
192
|
+
|
|
193
|
+
▸ @tester — STATUS: done · VERDICT: pass (14/14)
|
|
194
|
+
FINDINGS: burst edge, window expiry, concurrent refill covered;
|
|
195
|
+
src/legacy/** byte-identical
|
|
196
|
+
EVIDENCE: vitest 14 passed
|
|
197
|
+
|
|
198
|
+
▸ @reviewer — STATUS: done · VERDICT: approve (correctness)
|
|
199
|
+
FINDINGS: no Critical/Major; 1 Minor (log line noise) noted
|
|
200
|
+
|
|
201
|
+
team Done.
|
|
202
|
+
rate limiter shipped: rateLimit.ts (new) · app.ts (+3) · 14 tests green
|
|
203
|
+
review: approve · assumption: in-memory only · src/legacy/ untouched
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
The only message the user typed was the task and "approved, go". The
|
|
207
|
+
pipeline was a routing-table lookup, execution waited for plan approval,
|
|
208
|
+
and every handoff traveled as a structured skeleton — no file ceremony.
|
|
209
|
+
|
|
210
|
+
### Desktop-specific features
|
|
211
|
+
|
|
212
|
+
In **OpenCode Desktop**, you get additional UX benefits:
|
|
213
|
+
|
|
214
|
+
- 🎨 **Color-coded agents** — Each agent has a distinct color in the chat UI for easy identification.
|
|
215
|
+
- 📋 **Agent picker** — Click the agent dropdown to switch between team agents visually.
|
|
216
|
+
- 🔀 **Parallel sub-tasks** — The Team Lead can dispatch multiple sub-agents simultaneously, with results shown in parallel panels.
|
|
217
|
+
- 📊 **Session history** — All team interactions are saved and searchable in the Desktop session sidebar.
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## 🧰 Governed tools & security
|
|
222
|
+
|
|
223
|
+
Every tool TeamMode adds runs under ONE governance pipeline: outputs above
|
|
224
|
+
`TM_OFFLOAD_THRESHOLD` tokens never enter the context window — they are
|
|
225
|
+
offloaded to a run store and replaced by a content-aware preview plus an
|
|
226
|
+
HMAC-signed handle that the agent pages through with `tm_fetch` when it
|
|
227
|
+
genuinely needs the payload. Security, memory and web access shipped
|
|
228
|
+
across v1.5.1–v1.5.6; see [CHANGELOG.md](./CHANGELOG.md) for the history.
|
|
229
|
+
|
|
230
|
+
| Tool | What it does | Roles |
|
|
231
|
+
|---|---|---|
|
|
232
|
+
| `tm_read` / `tm_grep` / `tm_bash` / `tm_fetch` | Governed file read / regex search (host index) / read-only shell (allowlist) / paged handle retrieval | all six agents |
|
|
233
|
+
| `tm_memory` | Project memory store (Markdown + frontmatter): add / search / list / forget | all six agents |
|
|
234
|
+
| `tm_webfetch` | Single governed GET of an allowlisted web page | Lead + Researcher |
|
|
235
|
+
| `tm_browser` | Interactive browser session (headful CDP): open / navigate / read / screenshot / close | Lead + Researcher |
|
|
236
|
+
| `tm_ptc_run` | Batch orchestration: one program, N governed calls, zero LLM round-trips | all six agents |
|
|
237
|
+
|
|
238
|
+
> **Fixed tool priority ladder (every task): ① TeamMode governed tools
|
|
239
|
+
> (`tm_*`) → ② user MCP/plugin tools → ③ the model's own reasoning
|
|
240
|
+
> (a missing capability is reported as a gap, never fabricated).** The
|
|
241
|
+
> ladder is also a fallback chain: when a governed tool errors (no browser
|
|
242
|
+
> on this host, blocked host), the agent says so and drops to the next
|
|
243
|
+
> rung instead of giving up.
|
|
244
|
+
|
|
245
|
+
Agents are prompted to route every lookup through these tools — scan the
|
|
246
|
+
tool surface, plan the concrete call, expand colloquial or abbreviated
|
|
247
|
+
terms to canonical forms and search both spellings — instead of answering
|
|
248
|
+
from memory or simulating removed tools.
|
|
249
|
+
|
|
250
|
+
### Context governance: offload, handles, previews
|
|
251
|
+
|
|
252
|
+
**JIT layer-2 tools (`tm_read` / `tm_grep` / `tm_bash` / `tm_fetch`).**
|
|
253
|
+
Large tool outputs are context cost's main driver: every step re-sends the
|
|
254
|
+
whole window. The tm_* tools run the built-in capability under governance
|
|
255
|
+
first: results above `TM_OFFLOAD_THRESHOLD` tokens never enter the window —
|
|
256
|
+
they are written to a local run store and replaced by a handle with a
|
|
257
|
+
content-aware preview (JSON keys / CSV header+shape / log ERROR×N stats /
|
|
258
|
+
code signatures / binary metadata, hard-capped at 80 tokens). When the agent
|
|
259
|
+
actually needs the payload it pages through it with `tm_fetch`, using an
|
|
260
|
+
HMAC-signed, run-scoped, expiring handle. `tm_bash` only allows read-only
|
|
261
|
+
commands (allowlist), and failures come back as structured errors instead of
|
|
262
|
+
raw dumps. Agents are prompted to route every lookup through these tools —
|
|
263
|
+
scan the tool surface, plan the concrete call, expand colloquial or
|
|
264
|
+
abbreviated terms to canonical forms and search both spellings — instead of
|
|
265
|
+
answering from memory or simulating removed tools.
|
|
266
|
+
|
|
267
|
+
### Project memory (tm_memory)
|
|
268
|
+
|
|
269
|
+
**Project memory (`tm_memory`) — all agents.** Durable project facts
|
|
270
|
+
(build commands, environment quirks, architecture decisions, user
|
|
271
|
+
conventions that outlive one conversation) live as Markdown files with
|
|
272
|
+
frontmatter under the same git-aware store
|
|
273
|
+
(`<repo>/.git/opencode-team/memories/<project-slug>/<category>/`) —
|
|
274
|
+
human-editable, never in your working tree. `add` / `search`
|
|
275
|
+
(deterministic keyword scoring, top 5) / `list` / `forget`; content is
|
|
276
|
+
capped at 4000 chars per memory — task state belongs to the todo list,
|
|
277
|
+
oversized docs to board files. Agents are prompted to search before
|
|
278
|
+
assuming project conventions and to save hard-won facts for the next
|
|
279
|
+
conversation.
|
|
280
|
+
|
|
281
|
+
### Web access (tm_browser + tm_webfetch) — network roles only
|
|
282
|
+
|
|
283
|
+
1. **Governed web tools.** `tm_browser` — an interactive browser session
|
|
284
|
+
driving **your own Chromium-family browser** (Edge probed first on
|
|
285
|
+
Windows) headful via the CDP pipe protocol: open → navigate → read
|
|
286
|
+
(page text, threshold-governed like tm_read) → screenshot (PNG saved
|
|
287
|
+
to the run store, only the path enters context) → close. Isolated
|
|
288
|
+
temp profile (never your real one); the **domain allowlist is enforced
|
|
289
|
+
at the network layer** per request (CDP `Fetch.requestPaused` —
|
|
290
|
+
non-allowlisted hosts get `BlockedByClient`). Display-less Linux
|
|
291
|
+
hosts run headless automatically; `TM_BROWSER_HEADLESS` forces either
|
|
292
|
+
way, `TM_BROWSER_PATH` points at a specific executable. `tm_webfetch`
|
|
293
|
+
— a single governed GET of an allowlisted page. Both ride the same
|
|
294
|
+
governance as every tm_* tool (threshold offload + content-aware
|
|
295
|
+
preview + `tm_fetch` handle), so a web page can never flood the
|
|
296
|
+
context.
|
|
297
|
+
2. **User MCP/plugin tools.** Browser automation, search or fetch tools
|
|
298
|
+
from user-configured MCP servers are the fallback for what the
|
|
299
|
+
governed tools cannot do — the whitelist never touches them.
|
|
300
|
+
3. The other four agents (architect / implementer / reviewer / tester)
|
|
301
|
+
have NO network grant — web questions are reported as a gap, never
|
|
302
|
+
simulated. The built-in webfetch/websearch tools stay removed; remote
|
|
303
|
+
`.env`-style URLs are refused (R6 red line).
|
|
304
|
+
|
|
305
|
+
Seeded allowlist hosts (both web tools): `mobile.moegirl.org.cn` (wiki
|
|
306
|
+
term), `search.bilibili.com`, `cn.bing.com`, `www.baidu.com` (search URL
|
|
307
|
+
templates); extend via `TM_WEBFETCH_ALLOWED_DOMAINS` (`"*"` opens every
|
|
308
|
+
host).
|
|
309
|
+
|
|
310
|
+
Seeded allowlist hosts (both web tools): `mobile.moegirl.org.cn` (wiki
|
|
311
|
+
term), `search.bilibili.com`, `cn.bing.com`, `www.baidu.com` (search URL
|
|
312
|
+
templates); extend via `TM_WEBFETCH_ALLOWED_DOMAINS` (`"*"` opens every
|
|
313
|
+
host).
|
|
314
|
+
|
|
315
|
+
### Security: R6 + R2 approval gate
|
|
316
|
+
|
|
317
|
+
**R6 environment protection (now an approval gate).** With TeamMode active,
|
|
318
|
+
the model cannot read environment variables silently. Env-var reads
|
|
319
|
+
(`printenv`, `env`, `Get-ChildItem env:`, …) and env files (`.env`, shell rc
|
|
320
|
+
files) route through OpenCode's **official confirmation dialog**: you get a
|
|
321
|
+
native prompt to approve or deny, and an unanswered prompt is **auto-rejected
|
|
322
|
+
after `TM_ASK_TIMEOUT_MIN` (default 10 min)** — the plugin only ever rejects
|
|
323
|
+
on timeout, never approves on the model's behalf. Env reads that no wildcard
|
|
324
|
+
can express (embedded `$VAR` / `${VAR}` / `$env:` inside another command,
|
|
325
|
+
command substitution, subshell/escaped forms) and the `tm_*` wrapper channel
|
|
326
|
+
stay a **hard block** (no dialog to slip through). tm_* wrappers route through
|
|
327
|
+
the same checks (no backdoor via the wrappers). Audit lines record only tool
|
|
328
|
+
name + pattern category + the verdict (`ask` / `allowed-once` /
|
|
329
|
+
`allowed-always` / `rejected` / `timeout-rejected` / `degraded`) — never
|
|
330
|
+
command text, paths, variable names or values.
|
|
331
|
+
|
|
332
|
+
**R2 dangerous operations (same dialog).** Delete (`rm`/`del`/`Remove-Item`/
|
|
333
|
+
`rmdir`), git publishing (`git push`/`git commit`), network fetch (`curl`/
|
|
334
|
+
`wget`/`Invoke-WebRequest`/`Invoke-RestMethod`), package installs/publishes
|
|
335
|
+
(`npm install`/`npm publish`/`pip install`/`winget`/`choco`), process/system
|
|
336
|
+
(`taskkill`/`Stop-Process`/`kill`/`shutdown`/`format`) and privilege changes
|
|
337
|
+
(`chmod`/`takeown`/`icacls`) — none are silently allowed. They pop the same
|
|
338
|
+
official dialog and are auto-rejected if you don't answer within the timeout.
|
|
339
|
+
The normal verification stack (`npm test`, `tsc`, `git status`/`diff`) is NOT
|
|
340
|
+
gated, so day-to-day team work runs without interruption.
|
|
341
|
+
|
|
342
|
+
> ⚠️ **When you approve a dialog, pick "once" — not "always".** Verified on
|
|
343
|
+
> the live host, "always" records a far broader rule than the command you
|
|
344
|
+
> saw: approving `Get-ChildItem env:PATH` with "always" stores `Get-ChildItem
|
|
345
|
+
> *`, so every later `Get-ChildItem` runs with no dialog at all. Only the
|
|
346
|
+
> once-verdict keeps each gated operation individually human-checked.
|
|
347
|
+
> (If you do pick "always" on an env dialog, TeamMode scopes it to the
|
|
348
|
+
> current session — and env-FILE reads such as `cat .env` stay hard-blocked
|
|
349
|
+
> regardless: no dialog ever backs them, so no "always" can consent to them.)
|
|
350
|
+
|
|
351
|
+
> Deferral is per-session: env reads only route to the dialog in sessions
|
|
352
|
+
> running TeamMode's injected agents (or after such a session has shown one
|
|
353
|
+
> of these dialogs). In any other session (e.g. a stock `build`/`plan` chat)
|
|
354
|
+
> TeamMode's guard keeps hard-blocking env reads, since no dialog would back
|
|
355
|
+
> them there. Within one session, a user prompt routed to a non-injected
|
|
356
|
+
> agent REVOKES that eligibility (the per-turn agent signal rides
|
|
357
|
+
> `message.updated`; the verified host passes NO agent to
|
|
358
|
+
> `tool.execute.before`). Compound commands (`a; b`) are evaluated per segment by the
|
|
359
|
+
> host and approved through one dialog; the guard blocks them outright
|
|
360
|
+
> whenever any segment is an env read.
|
|
361
|
+
|
|
362
|
+
> The permission protocol was verified against a live `opencode serve` host
|
|
363
|
+
> (1.18.29) via SSE event capture; the Desktop dialog rendering itself is the
|
|
364
|
+
> one leg that still needs eyeballing in a real Desktop session. Headless
|
|
365
|
+
> `opencode run` auto-rejects an unanswered `ask` immediately (there is no
|
|
366
|
+
> human to prompt).
|
|
367
|
+
|
|
368
|
+
### Repo hygiene & path semantics
|
|
369
|
+
|
|
370
|
+
> **Repo hygiene.** The offload/trajectory stores live under
|
|
371
|
+
> `<repo>/.git/opencode-team/` (or the OS temp dir outside a git repo) —
|
|
372
|
+
> never your working tree. Every agent is instructed to delete scratch /
|
|
373
|
+
> temporary files it created before reporting done, and to keep throwaway
|
|
374
|
+
> work in the OS temp dir so nothing lands in the repo at all. `tm_read` /
|
|
375
|
+
> `tm_grep` paths are relative to the **project root** (not the agent's
|
|
376
|
+
> working directory).
|
|
377
|
+
|
|
378
|
+
### Environment variables
|
|
379
|
+
|
|
380
|
+
| Env var | Default | Purpose |
|
|
381
|
+
|---|---|---|
|
|
382
|
+
| `TM_ENV_PROTECT` | `strict` | R6 mode: `strict` / `standard` / `off` (off also disarms the approval timer) |
|
|
383
|
+
| `TM_ASK_TIMEOUT_MIN` | `10` | minutes before an unanswered R6/R2 confirmation dialog is auto-rejected; minimum 3 minutes (the host's `permission.replied` reaches the plugin ~120 s late on the event bus — shorter values would auto-reject a just-approved request) |
|
|
384
|
+
| `TM_ENV_PROTECT_EXTRA_DENY` | — | extra block patterns (regex list; always a hard block, never dialog-governed) |
|
|
385
|
+
| `TM_OFFLOAD_THRESHOLD` | `2000` | offload threshold (tokens, CJK-aware estimate) |
|
|
386
|
+
| `TM_PREVIEW_MAX_TOKENS` | `80` | preview hard cap |
|
|
387
|
+
| `TM_FETCH_MAX_LINES` | `2000` | tm_fetch page cap |
|
|
388
|
+
| `TM_BLACKBOARD_DIR` | `<repo>/.git/opencode-team/blackboard/` | offloaded payload store (tmpdir fallback outside a git repo; explicit value = absolute or project-relative) |
|
|
389
|
+
| `TM_TRAJECTORY_DIR` | `<repo>/.git/opencode-team/trajectory/` | append-only tool-call ledger (tmpdir fallback outside a git repo) |
|
|
390
|
+
| `TM_BLACKBOARD_TTL` | `7` | store retention (days) |
|
|
391
|
+
| `TM_BASH_READONLY_ALLOWED` | built-in table | tm_bash allowlist |
|
|
392
|
+
| `TM_WEBFETCH_ALLOWED_DOMAINS` | `mobile.moegirl.org.cn, search.bilibili.com, cn.bing.com, www.baidu.com` | tm_webfetch/tm_browser allowlist (`"*"` opens every host; explicit empty = deny all) |
|
|
393
|
+
| `TM_BROWSER_PATH` | auto-detect | tm_browser executable override (Edge/Chrome/Chromium probed per OS) |
|
|
394
|
+
| `TM_BROWSER_HEADLESS` | `auto` | tm_browser: `1` headless (servers/CI) / `0` headful / `auto` (headless only on display-less Linux) |
|
|
395
|
+
| `TM_PTC_MAX_PROGRAM_CHARS` | `4000` | PTC program source length cap (chars) |
|
|
396
|
+
| `TM_PTC_MAX_CALLS` | `20` | PTC per-run bridge-call budget (1–200) |
|
|
397
|
+
| `TM_PTC_MAX_ERRORS` | `3` | PTC per-run error budget (1–50) |
|
|
398
|
+
| `TM_PTC_TIMEOUT_MS` | `60000` | PTC per-run wall-clock timeout (5s–10min) |
|
|
399
|
+
| `TM_PTC_ENGINE` | `auto` | PTC engine: `auto` (worker→inline degrade) / `worker` / `inline` |
|
|
400
|
+
|
|
401
|
+
### Batch orchestration (tm_ptc_run)
|
|
402
|
+
|
|
403
|
+
`tm_ptc_run` lets a specialist agent write **one async program** that makes N
|
|
404
|
+
governed `tm_*` calls in a single turn — zero LLM round-trips during the run,
|
|
405
|
+
only an aggregation summary returns to context. It is designed for batch
|
|
406
|
+
read-only tasks: multi-file reconnaissance, bulk grep + read aggregation,
|
|
407
|
+
cross-referencing search results.
|
|
408
|
+
|
|
409
|
+
#### How it works
|
|
410
|
+
|
|
411
|
+
The agent writes a program body using `tm.read(args)`, `tm.grep(args)`,
|
|
412
|
+
`tm.bash(args)`, `tm.fetch(args)` — same args as the four governed tools.
|
|
413
|
+
Each call returns `{ok:true, data}` (governed: inline text or an offload
|
|
414
|
+
handle) or `{ok:false, error:{tool,phase,line?,message}}`. The program
|
|
415
|
+
`return`s a value; it is JSON-serialized into the aggregation summary.
|
|
416
|
+
|
|
417
|
+
Programs containing `require`, `import`, `process`, `globalThis`, `Deno`,
|
|
418
|
+
`Bun`, `fs`, `net`, or `child_process` are rejected before execution (static
|
|
419
|
+
pre-scan, auxiliary guard).
|
|
420
|
+
|
|
421
|
+
#### Budgets (tighten-only)
|
|
422
|
+
|
|
423
|
+
The caller may tighten `max_calls`, `max_errors`, and `timeout_ms` — values
|
|
424
|
+
above the `TM_PTC_*` ceilings are clamped down; values below the floor are
|
|
425
|
+
clamped up. Hitting any budget stops the whole run; produced output is NOT
|
|
426
|
+
lost.
|
|
427
|
+
|
|
428
|
+
#### Engine (`TM_PTC_ENGINE`)
|
|
429
|
+
|
|
430
|
+
| Mode | Behavior |
|
|
431
|
+
|---|---|
|
|
432
|
+
| `auto` (default) | Tries `worker_threads` first; on engine failure it re-runs the WHOLE program on `node:vm` with a `degraded-engine` mark in the summary (bridged calls are read-only, so a re-run is safe; the fallback starts with fresh budgets under the same wall-clock deadline) |
|
|
433
|
+
| `worker` | Forces the worker engine (engine-error on failure) |
|
|
434
|
+
| `inline` | Forces the `node:vm` engine (script timeout kills pre-await synchronous busy-loops; a busy loop after the first `await` blocks the host event loop irrecoverably — prefer worker/auto) |
|
|
435
|
+
|
|
436
|
+
The worker engine runs the program in a dedicated thread with `env:{}`
|
|
437
|
+
(process.env emptied), `resourceLimits`, and hard wall-clock `terminate()`.
|
|
438
|
+
All governance (P2 path scope, P3 allowlist, R6, threshold offload, TTL)
|
|
439
|
+
applies to every bridged call — PTC is not a bypass layer.
|
|
440
|
+
|
|
441
|
+
#### Access
|
|
442
|
+
|
|
443
|
+
`tm_ptc_run` is in the whitelist of **all six** agents (the `team` lead
|
|
444
|
+
included — v1.5.4 revised the original deny ruling). Every bridged call
|
|
445
|
+
still runs the full governed tm_* pipeline (P2 path scope, P3 allowlist, R6,
|
|
446
|
+
threshold offload + handles, TTL), so batch orchestration is a convenience
|
|
447
|
+
gain, not a governance gap.
|
|
448
|
+
|
|
449
|
+
---
|
|
450
|
+
|
|
451
|
+
## 🏗️ Architecture
|
|
452
|
+
|
|
453
|
+
```
|
|
454
|
+
opencode-team-mode/
|
|
455
|
+
├── package.json ← npm package definition
|
|
456
|
+
├── tsconfig.json ← TypeScript config
|
|
457
|
+
├── src/
|
|
458
|
+
│ ├── index.ts ← Plugin entry (server(): config + R6 tool.execute.before + approval-gate event + tool segment)
|
|
459
|
+
│ ├── agents.ts ← Agent structure (modes, colors, temperatures, whitelist matrix)
|
|
460
|
+
│ ├── prompts/ ← The agent prompt strings (lead / specialists / shared) — pinned by tests
|
|
461
|
+
│ ├── commands.ts ← Command definitions (templates, agent bindings)
|
|
462
|
+
│ ├── blackboard.ts ← Shared blackboard + TTL auto-cleanup sweeper
|
|
463
|
+
│ ├── envprotect.ts ← R6 facade → envprotect/ (patterns / bash-classify / path-classify / gate-predicates / hook)
|
|
464
|
+
│ ├── approval-gate.ts ← Unified approval gate: host-dialog timeout auto-reject (never self-allows)
|
|
465
|
+
│ ├── tm/ ← JIT layer-2 tools: pipelines / result / client-unwrap / shell-bridge / args-schema / tools / guard / preview / store / refs / config / webfetch / memory / browser / ptc/ (9 modules)
|
|
466
|
+
│ └── types.ts ← Loader-contract type definitions (1.18.x)
|
|
467
|
+
├── scripts/
|
|
468
|
+
│ ├── install.sh ← One-click installer (bash)
|
|
469
|
+
│ └── install.ps1 ← One-click installer (PowerShell)
|
|
470
|
+
├── pt07/ ← PT-07 baseline suite (seeded A/B token measurement)
|
|
471
|
+
├── LICENSE ← Apache 2.0
|
|
472
|
+
├── README.md ← English documentation
|
|
473
|
+
└── README.zh-CN.md ← Chinese documentation
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
### How it works
|
|
477
|
+
|
|
478
|
+
1. OpenCode Desktop starts and loads `opencode.json(c)`.
|
|
479
|
+
2. It sees `"@te-river/opencode-team-mode@latest"` in the `plugin` array and loads the npm package.
|
|
480
|
+
3. The loader calls the plugin's `server(input, options)`, which registers a `config` hook; the hook injects 6 agents and 6 commands into the merged config. The same call installs the R6 `tool.execute.before` guard, arms the unified R6/R2 approval gate (official dialog + `TM_ASK_TIMEOUT_MIN` auto-reject, wired through an `event` hook), and registers the governed `tm_*` tools (see [Governed tools & security](#-governed-tools--security) below).
|
|
481
|
+
4. The plugin's `id: "team-mode"` is displayed as the plugin name in the Desktop UI.
|
|
482
|
+
5. Agents and commands are immediately available in the Desktop UI — no file copying needed. User-defined agents with the same name always win (the plugin never clobbers them).
|
|
483
|
+
|
|
484
|
+
---
|
|
485
|
+
|
|
486
|
+
## 🤖 How the team works
|
|
487
|
+
|
|
488
|
+
Sub-agents cannot message each other live (platform limitation), so TeamMode
|
|
489
|
+
coordinates them through a **structured reply skeleton**, with a file
|
|
490
|
+
blackboard reserved for oversized output:
|
|
491
|
+
|
|
492
|
+
- **Reply skeleton (primary channel):** every specialist's final reply starts
|
|
493
|
+
with `STATUS: / CHANGES: / FINDINGS: / EVIDENCE: / HANDOFF:` and stays ≤50
|
|
494
|
+
lines. Deliverables at that size travel inline — zero file I/O, nothing to
|
|
495
|
+
fall out of sync. The lead relays `HANDOFF` verbatim into the next
|
|
496
|
+
dispatch and machine-checks the skeleton (missing → one retry with it
|
|
497
|
+
inline, then downgrade and note the violation).
|
|
498
|
+
- **Board files (exception only):** when a full deliverable exceeds ~50 lines
|
|
499
|
+
(e.g. a complete architecture doc), the dispatch names ONE file:
|
|
500
|
+
`<repo>/.git/opencode-team/<session-key>/<task-slug>/NN-<role>-<topic>.md`
|
|
501
|
+
— inside `.git/`, so your working tree and commits are **never polluted**
|
|
502
|
+
(non-git workspaces fall back to the OS temp dir). Writes are frozen: a
|
|
503
|
+
revision is a new round-suffixed file (`…-r2.md`); session folders keep a
|
|
504
|
+
fresh conversation from touching a not-yet-swept board.
|
|
505
|
+
- **No MANIFEST.md:** the lead's state memory is its todo list.
|
|
506
|
+
- **Feedback loop:** Critical/Major findings and product bugs automatically
|
|
507
|
+
become tracked fix tasks until the deliverable converges (max 2 loops,
|
|
508
|
+
then escalate to you).
|
|
509
|
+
|
|
510
|
+
### Deterministic routing, approval gate & adaptive review
|
|
511
|
+
|
|
512
|
+
- **Routing table:** the lead picks a fixed pipeline row by task shape —
|
|
513
|
+
question → direct answer; docs-only → implementer; product behavior
|
|
514
|
+
change → implementer → tester → reviewer; multi-module feature →
|
|
515
|
+
architect → implementer → tester → reviewer(s); unknown external tech →
|
|
516
|
+
researcher first. Pipelines have fixed minimums: a product change routed
|
|
517
|
+
below 3 dispatches is a routing bug, and splitting one request into
|
|
518
|
+
sub-2-dispatch pieces to dodge the gate is a protocol violation.
|
|
519
|
+
- **Approval gate (count-based):** ≥2 planned dispatches → the lead
|
|
520
|
+
researches (reading the repo itself; a researcher dispatch only for
|
|
521
|
+
unknown external tech), presents a ≤30-line plan, and **waits for your
|
|
522
|
+
approval** before executing anything. 0-1 dispatches run with a 1-2 line
|
|
523
|
+
notice. A task that grows a second dispatch mid-run pauses for approval.
|
|
524
|
+
Blocking uncertainties are batched and asked immediately — never guessed,
|
|
525
|
+
never drip-fed.
|
|
526
|
+
- **Adaptive review:** default is ONE reviewer dispatch (correctness);
|
|
527
|
+
three parallel dimensions (completeness / correctness / impact) only for
|
|
528
|
+
high-risk profiles — auth/security surface, cross-module data contracts,
|
|
529
|
+
public APIs across ≥3 files.
|
|
530
|
+
- **Static verification:** testers verify via build, typecheck, static
|
|
531
|
+
analysis, and API/unit tests. Improvised browser automation (headless
|
|
532
|
+
screenshots, DOM stubs) is banned; user-visible frontend changes end with
|
|
533
|
+
`UI NOT VERIFIED: <what needs manual checking>` unless the project
|
|
534
|
+
already ships real browser-test tooling.
|
|
535
|
+
- **No-ceremony fast path:** a root cause the lead has already verified
|
|
536
|
+
(file:line evidence) goes straight to the implementer as a fix spec —
|
|
537
|
+
investigation dispatches serve unknowns, not ritual.
|
|
538
|
+
- **Brevity discipline:** route selection is a table lookup; user-visible
|
|
539
|
+
planning text stays ≤5 lines.
|
|
540
|
+
- **Evidence standard (kept):** "done / fixed / passed" claims need
|
|
541
|
+
verifiable evidence — command output, logs, diffs. Narratives are
|
|
542
|
+
progress notes, not proof.
|
|
543
|
+
- **Verbatim contracts (kept):** parallel implementers that must
|
|
544
|
+
interoperate get the exact data contract (endpoints, field names, types)
|
|
545
|
+
pasted verbatim into every affected dispatch.
|
|
546
|
+
- **Docs sync (CHANGELOG + AGENTS.md):** delivered changes append a
|
|
547
|
+
CHANGELOG.md entry when one exists, and update AGENTS.md when the change
|
|
548
|
+
alters what it records (build/test commands, conventions, structure,
|
|
549
|
+
agent instructions); either file is offered for creation when missing.
|
|
550
|
+
Reading is deduplicated: the lead reads the README itself (the host does
|
|
551
|
+
not inject it), uses the host-injected AGENTS.md/CLAUDE.md copy already
|
|
552
|
+
in context and opens those files only when genuinely absent — and
|
|
553
|
+
specialists never re-open these docs, since conventions arrive
|
|
554
|
+
distilled inside their dispatches.
|
|
555
|
+
|
|
556
|
+
### Triage — questions don't become code edits
|
|
557
|
+
|
|
558
|
+
The Team Lead classifies every incoming message before acting: a question or
|
|
559
|
+
consult gets an answer (zero file changes, fixes merely proposed and awaiting
|
|
560
|
+
your go-ahead); only explicit action requests enter the workflow. And whenever
|
|
561
|
+
you spell out what may or may not be touched, **those boundaries outrank
|
|
562
|
+
everything else** — the lead restates them in every single dispatch.
|
|
563
|
+
|
|
564
|
+
### Cleanup — the TTL sweeper is the only path
|
|
565
|
+
|
|
566
|
+
| Who | When |
|
|
567
|
+
|---|---|
|
|
568
|
+
| Plugin code (in-process sweeper) | At startup + every hour: removes task directories idle **beyond the TTL** |
|
|
569
|
+
|
|
570
|
+
The Team Lead never deletes task directories — finished boards stay
|
|
571
|
+
readable so you can audit how a run went, and reclamation is pure code
|
|
572
|
+
that never relies on the model remembering to do anything (crashes and
|
|
573
|
+
force-kills leave nothing behind either). The sweeper prunes stale task
|
|
574
|
+
dirs individually under a still-live session, and reclaims an entirely
|
|
575
|
+
idle session folder in one pass. Set `ttlDays` to taste.
|
|
576
|
+
|
|
577
|
+
### Configure the TTL
|
|
578
|
+
|
|
579
|
+
Default is **5 days**. To choose your own, use the tuple plugin form in
|
|
580
|
+
`opencode.jsonc`:
|
|
581
|
+
|
|
582
|
+
```jsonc
|
|
583
|
+
{
|
|
584
|
+
"$schema": "https://opencode.ai/config.json",
|
|
585
|
+
"plugin": [
|
|
586
|
+
["@te-river/opencode-team-mode@latest", { "ttlDays": 7 }]
|
|
587
|
+
]
|
|
588
|
+
}
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
`ttlDays` accepts any number of days in `(0, 365]`; invalid values silently
|
|
592
|
+
fall back to 5.
|
|
593
|
+
|
|
594
|
+
### Default agent
|
|
595
|
+
|
|
596
|
+
By default TeamMode **makes Team your default agent** — new chats open
|
|
597
|
+
directly in the team orchestrator. One side effect comes with the default
|
|
598
|
+
slot: the switcher pins the default agent to the **first position** and
|
|
599
|
+
sorts everything else alphabetically, so the picker order is
|
|
600
|
+
**team, build, plan**. (Want Team below Plan instead? That requires
|
|
601
|
+
giving up the default slot — see the opt-out below; the two are
|
|
602
|
+
mutually exclusive by the server's sort.)
|
|
603
|
+
|
|
604
|
+
To opt out (`build` stays the default, picker order **build, plan,
|
|
605
|
+
team**):
|
|
606
|
+
|
|
607
|
+
```jsonc
|
|
608
|
+
{
|
|
609
|
+
"plugin": [
|
|
610
|
+
["@te-river/opencode-team-mode@latest", { "defaultAgent": false }]
|
|
611
|
+
]
|
|
612
|
+
}
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
An explicitly configured non-`build` `default_agent` in your own config is
|
|
616
|
+
always respected untouched — the plugin never clobbers it.
|
|
617
|
+
|
|
618
|
+
**Upgrade note:** v1.4.4 briefly made this promotion opt-in; v1.4.5 restores
|
|
619
|
+
Team-as-default as the shipped behavior. If you pinned `{ "defaultAgent":
|
|
620
|
+
true }` during v1.4.4, you can drop that option (or switch it to `false` to
|
|
621
|
+
opt out).
|
|
622
|
+
|
|
623
|
+
---
|
|
624
|
+
|
|
625
|
+
## 🔧 Customization
|
|
626
|
+
|
|
627
|
+
### The Team Lead's model matters most
|
|
628
|
+
|
|
629
|
+
The Lead is the orchestrating brain: it classifies every message, cuts the
|
|
630
|
+
work into packages, writes each dispatch manifest, judges reviewer/tester
|
|
631
|
+
findings, and synthesizes the final deliverable. Quality failures there
|
|
632
|
+
**multiply down the pipeline** — a mediocre Lead mis-decomposes, briefs the
|
|
633
|
+
experts vaguely, and waves weak work through; no specialist can rescue an
|
|
634
|
+
assignment it was never correctly given.
|
|
635
|
+
|
|
636
|
+
So run the strongest model you can afford **in the Lead seat**. The other
|
|
637
|
+
roles tolerate cheaper models — they work from tight briefs with scoped
|
|
638
|
+
reading. Pin models per agent:
|
|
639
|
+
|
|
640
|
+
```jsonc
|
|
641
|
+
{
|
|
642
|
+
"agent": {
|
|
643
|
+
// Team Lead — orchestration earns your best model
|
|
644
|
+
"team": { "model": "anthropic/claude-opus-4-5" },
|
|
645
|
+
// specialists — cheaper models are usually fine
|
|
646
|
+
"implementer": { "model": "anthropic/claude-sonnet-4-6" }
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
(Model IDs above are placeholders — use whatever your provider exposes.
|
|
652
|
+
Your own `agent.team` definition always takes precedence over the plugin's.)
|
|
653
|
+
|
|
654
|
+
### Override an agent
|
|
655
|
+
|
|
656
|
+
Add an agent with the same name in your `opencode.json` — your definition takes precedence:
|
|
657
|
+
|
|
658
|
+
```jsonc
|
|
659
|
+
{
|
|
660
|
+
"agent": {
|
|
661
|
+
"reviewer": {
|
|
662
|
+
"model": "anthropic/claude-sonnet-4-6",
|
|
663
|
+
"prompt": "You are an extremely strict reviewer. Reject anything with a lint warning."
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
### Add your own agents
|
|
670
|
+
|
|
671
|
+
TeamMode does not prevent you from adding more agents. Define them alongside the team:
|
|
672
|
+
|
|
673
|
+
```jsonc
|
|
674
|
+
{
|
|
675
|
+
"agent": {
|
|
676
|
+
"devops": {
|
|
677
|
+
"mode": "subagent",
|
|
678
|
+
"description": "Handles CI/CD, Docker, and deployment tasks.",
|
|
679
|
+
"prompt": "You are the DevOps engineer..."
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
### Disable an agent
|
|
686
|
+
|
|
687
|
+
```jsonc
|
|
688
|
+
{
|
|
689
|
+
"agent": {
|
|
690
|
+
"researcher": { "disable": true }
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
---
|
|
696
|
+
|
|
697
|
+
## 📦 Publishing to npm
|
|
698
|
+
|
|
699
|
+
If you want to publish your own fork:
|
|
700
|
+
|
|
701
|
+
```bash
|
|
702
|
+
npm run build # compile TypeScript → dist/
|
|
703
|
+
npm version patch # bump version
|
|
704
|
+
npm publish # publish to npm registry
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
---
|
|
708
|
+
|
|
709
|
+
## 🤝 Contributing
|
|
710
|
+
|
|
711
|
+
Contributions are welcome! Areas where we need help:
|
|
712
|
+
|
|
713
|
+
- 🌐 **Localization** — Translate agent prompts to other languages
|
|
714
|
+
- 🎨 **More agent roles** — DevOps, DBA, Security Specialist, UX Designer
|
|
715
|
+
- 🔧 **Additional commands** — `/team-deploy`, `/team-docs`, `/team-refactor`
|
|
716
|
+
- 📝 **Better prompts** — Improve agent behavior through prompt engineering
|
|
717
|
+
|
|
718
|
+
---
|
|
719
|
+
|
|
720
|
+
## 📄 License
|
|
721
|
+
|
|
722
|
+
[Apache License 2.0](./LICENSE)
|
|
723
|
+
|
|
724
|
+
---
|
|
725
|
+
|
|
726
|
+
## 🔗 Links
|
|
727
|
+
|
|
728
|
+
- [npm Package](https://www.npmjs.com/package/@te-river/opencode-team-mode) — `@te-river/opencode-team-mode` on npm
|
|
729
|
+
- [OpenCode Desktop](https://opencode.ai) — Official website & download
|
|
730
|
+
- [OpenCode Docs](https://opencode.ai/docs) — Configuration & plugin documentation
|
|
731
|
+
- [OpenCode Plugin API](https://opencode.ai/docs/plugins) — Build your own plugins
|
|
732
|
+
- [OpenCode GitHub](https://github.com/anomalyco/opencode) — Source code for OpenCode itself
|