@te-river/opencode-team-mode 1.5.6 → 1.5.8
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 +354 -528
- package/README.zh-CN.md +346 -480
- package/dist/agents.d.ts.map +1 -1
- package/dist/agents.js +44 -26
- package/dist/agents.js.map +1 -1
- package/dist/approval-gate.d.ts +5 -0
- package/dist/approval-gate.d.ts.map +1 -1
- package/dist/approval-gate.js +29 -0
- package/dist/approval-gate.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +27 -0
- 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 +7 -4
- package/dist/prompts/lead.js.map +1 -1
- package/dist/prompts/shared.d.ts +1 -1
- package/dist/prompts/shared.d.ts.map +1 -1
- package/dist/prompts/shared.js +15 -13
- 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 +31 -5
- package/dist/prompts/specialists.js.map +1 -1
- package/dist/tm/args-schema.d.ts +6 -0
- package/dist/tm/args-schema.d.ts.map +1 -1
- package/dist/tm/args-schema.js +23 -1
- package/dist/tm/args-schema.js.map +1 -1
- package/dist/tm/browser.d.ts.map +1 -1
- package/dist/tm/browser.js +35 -6
- package/dist/tm/browser.js.map +1 -1
- package/dist/tm/config.d.ts +16 -5
- package/dist/tm/config.d.ts.map +1 -1
- package/dist/tm/config.js +23 -6
- package/dist/tm/config.js.map +1 -1
- package/dist/tm/index.d.ts +11 -4
- package/dist/tm/index.d.ts.map +1 -1
- package/dist/tm/index.js +20 -6
- package/dist/tm/index.js.map +1 -1
- package/dist/tm/memory.d.ts +8 -2
- package/dist/tm/memory.d.ts.map +1 -1
- package/dist/tm/memory.js +31 -21
- package/dist/tm/memory.js.map +1 -1
- package/dist/tm/perm-ask.d.ts +37 -0
- package/dist/tm/perm-ask.d.ts.map +1 -0
- package/dist/tm/perm-ask.js +41 -0
- package/dist/tm/perm-ask.js.map +1 -0
- package/dist/tm/pipelines.d.ts.map +1 -1
- package/dist/tm/pipelines.js +7 -0
- package/dist/tm/pipelines.js.map +1 -1
- package/dist/tm/preview.d.ts.map +1 -1
- package/dist/tm/preview.js +32 -5
- package/dist/tm/preview.js.map +1 -1
- package/dist/tm/ptc/gate.d.ts.map +1 -1
- package/dist/tm/ptc/gate.js +4 -1
- package/dist/tm/ptc/gate.js.map +1 -1
- package/dist/tm/ptc/summary.d.ts.map +1 -1
- package/dist/tm/ptc/summary.js +5 -0
- package/dist/tm/ptc/summary.js.map +1 -1
- package/dist/tm/ptc/tool.d.ts.map +1 -1
- package/dist/tm/ptc/tool.js +2 -1
- package/dist/tm/ptc/tool.js.map +1 -1
- package/dist/tm/search.d.ts +58 -0
- package/dist/tm/search.d.ts.map +1 -0
- package/dist/tm/search.js +253 -0
- package/dist/tm/search.js.map +1 -0
- package/dist/tm/shell-bridge.d.ts +1 -1
- package/dist/tm/shell-bridge.d.ts.map +1 -1
- package/dist/tm/shell-bridge.js +52 -6
- package/dist/tm/shell-bridge.js.map +1 -1
- package/dist/tm/tools.js +1 -1
- package/dist/tm/webfetch.d.ts +36 -8
- package/dist/tm/webfetch.d.ts.map +1 -1
- package/dist/tm/webfetch.js +144 -23
- package/dist/tm/webfetch.js.map +1 -1
- package/docs/installation.md +219 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -6,68 +6,108 @@
|
|
|
6
6
|
[](https://www.npmjs.com/package/@te-river/opencode-team-mode)
|
|
7
7
|
[](./LICENSE)
|
|
8
8
|
|
|
9
|
-
> 🤝 **
|
|
9
|
+
> 🤝 **Your OpenCode just hired a team.**
|
|
10
10
|
>
|
|
11
|
-
>
|
|
11
|
+
> Six specialized agents — a Lead, an Architect, an Implementer, a Reviewer, a Tester and a Researcher — with governed tools, structured handoffs, and a plan-first approval gate. One plugin, zero config files to copy.
|
|
12
|
+
|
|
13
|
+
> 💡 **Best for medium-to-large projects.** The governance layer (approval gate, context offload, tool allowlists) is an asset once a codebase has real surface area — and mostly overhead on tiny scripts and one-off questions. Use it where the work is.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## TL;DR — skip the docs
|
|
18
|
+
|
|
19
|
+
> **The lazy path:** paste this to any coding agent and let it do the work:
|
|
20
|
+
>
|
|
21
|
+
> ```text
|
|
22
|
+
> Install the OpenCode plugin @te-river/opencode-team-mode following
|
|
23
|
+
> https://raw.githubusercontent.com/Te-River/Opencode-TeamMode/main/docs/installation.md
|
|
24
|
+
> Then verify the install using the checks in that guide.
|
|
25
|
+
> ```
|
|
26
|
+
>
|
|
27
|
+
> **The one command to remember afterwards:** `/team-run <task>` — the Team Lead
|
|
28
|
+
> plans it, shows you the plan, waits for your approval, then runs the whole team.
|
|
29
|
+
|
|
30
|
+
Everything else below is detail. When you're ready for it, here's the map:
|
|
31
|
+
|
|
32
|
+
**[Why](#-why-teammode) · [The team](#-the-team) · [Install](#-install) · [Usage](#-usage) · [Tools & security](#-governed-tools--security) · [Search](#-web-search-that-actually-works-in-china) · [Config](#️-configuration) · [How it works](#-how-the-team-works) · [FAQ](#-faq) · [Uninstall](#-uninstall)**
|
|
12
33
|
|
|
13
34
|
---
|
|
14
35
|
|
|
15
|
-
##
|
|
36
|
+
## 🤔 Why TeamMode?
|
|
16
37
|
|
|
17
|
-
|
|
38
|
+
Because a single agent doing everything is how you get: a context window stuffed
|
|
39
|
+
with 5000-line file dumps, twenty round-trips to `bash` for what one script could
|
|
40
|
+
do, sub-agents that silently read `.env`, and web "research" that is really just
|
|
41
|
+
the model's imagination.
|
|
18
42
|
|
|
19
|
-
|
|
43
|
+
TeamMode's answer to each:
|
|
44
|
+
|
|
45
|
+
| Pain | TeamMode's answer |
|
|
46
|
+
|---|---|
|
|
47
|
+
| 🔥 **Context flooding** | Every governed tool output over 2000 tokens is offloaded to a local run store and replaced by an 80-token preview + an HMAC handle. The agent pages through what it needs — the window never drowns. |
|
|
48
|
+
| 🐌 **Round-trip overhead** | `tm_ptc_run`: the agent writes ONE program that makes N governed calls in a single turn. Zero LLM round-trips during the run. |
|
|
49
|
+
| 🕳️ **Silent side effects** | R6/R2 approval gate: env-var reads and dangerous ops route through OpenCode's official confirmation dialog, auto-rejected after 10 unanswered minutes. The plugin never approves on its own — it only ever rejects. |
|
|
50
|
+
| 🌫️ **Hallucinated research** | Web access is a two-role grant with an allowlisted, governed tool chain. A fact that couldn't be fetched is reported as a gap — never fabricated. |
|
|
51
|
+
|
|
52
|
+
And the workflow discipline underneath: deterministic routing, a ≤30-line plan
|
|
53
|
+
you approve before ≥2 dispatches execute, structured `STATUS/CHANGES/FINDINGS/
|
|
54
|
+
EVIDENCE/HANDOFF` replies between agents, and static verification (build /
|
|
55
|
+
typecheck / tests) instead of vibes.
|
|
56
|
+
|
|
57
|
+
That discipline is also why the recommendation is **medium-to-large
|
|
58
|
+
projects**: on a two-file script the team simply has less to govern.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## 👥 The team
|
|
20
63
|
|
|
21
64
|
| Agent | Role | When to use |
|
|
22
65
|
|---|---|---|
|
|
23
|
-
| 🎯 **Team Lead** | Orchestrator | Complex tasks that need planning + multi-step execution |
|
|
66
|
+
| 🎯 **Team Lead** (`@team`) | Orchestrator | Complex tasks that need planning + multi-step execution |
|
|
24
67
|
| 🏗️ **Architect** | System designer | Design docs, module structure, API contracts |
|
|
25
68
|
| 💻 **Implementer** | Code writer | Building features, writing production code |
|
|
26
|
-
| 🔍 **Reviewer** | Dimension-focused auditor | Single-dimension review
|
|
27
|
-
| 🧪 **Tester** | Test engineer |
|
|
28
|
-
| 🔎 **Researcher** | Knowledge finder | Local
|
|
29
|
-
|
|
30
|
-
---
|
|
69
|
+
| 🔍 **Reviewer** | Dimension-focused auditor | Single-dimension review by default; 3 in parallel only for high-risk changes |
|
|
70
|
+
| 🧪 **Tester** | Test engineer | Tests with real edge cases; static verification (build / typecheck / lint); governed UI verification via `tm_browser` |
|
|
71
|
+
| 🔎 **Researcher** | Knowledge finder | Local repo first, then the web — one of the two network roles (with the Lead) |
|
|
31
72
|
|
|
32
|
-
|
|
73
|
+
Out of the box, **Team is your default agent** — new chats open straight into the
|
|
74
|
+
orchestrator (opt-out in [Configuration](#-configuration)).
|
|
33
75
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
1. **Install OpenCode Desktop** (if you haven't already):
|
|
76
|
+
---
|
|
37
77
|
|
|
38
|
-
|
|
39
|
-
|---|---|
|
|
40
|
-
| macOS (Apple Silicon) | `brew install --cask opencode-desktop` |
|
|
41
|
-
| macOS (Intel) | `brew install --cask opencode-desktop` |
|
|
42
|
-
| Windows | `scoop bucket add extras && scoop install extras/opencode-desktop` |
|
|
43
|
-
| Linux | Download from [opencode.ai/download](https://opencode.ai/download) |
|
|
78
|
+
## 📦 Install
|
|
44
79
|
|
|
45
|
-
|
|
46
|
-
```bash
|
|
47
|
-
# one-line script (all platforms)
|
|
48
|
-
curl -fsSL https://opencode.ai/install | bash
|
|
80
|
+
### Option 1 — Let your agent do it (recommended)
|
|
49
81
|
|
|
50
|
-
|
|
51
|
-
npm install -g opencode-ai
|
|
52
|
-
```
|
|
82
|
+
Copy this into any coding agent — it will edit your config, restart-remind you, and verify:
|
|
53
83
|
|
|
54
|
-
|
|
84
|
+
```text
|
|
85
|
+
Install the OpenCode plugin @te-river/opencode-team-mode following
|
|
86
|
+
https://raw.githubusercontent.com/Te-River/Opencode-TeamMode/main/docs/installation.md
|
|
87
|
+
(If that URL is unreachable — common on mainland-China networks — retry with
|
|
88
|
+
the mirror prefix: https://ghproxy.net/ + the same path.)
|
|
89
|
+
Then verify the install using the checks in that guide.
|
|
90
|
+
```
|
|
55
91
|
|
|
56
|
-
|
|
92
|
+
(The guide is the complete manual procedure — config file locations, plugin
|
|
93
|
+
entry, restart, verification, update and uninstall. Your agent reads it and
|
|
94
|
+
executes it faithfully; there is nothing else it needs.)
|
|
57
95
|
|
|
58
|
-
|
|
96
|
+
### Option 2 — One-line script
|
|
59
97
|
|
|
60
98
|
macOS / Linux (bash):
|
|
99
|
+
|
|
61
100
|
```bash
|
|
62
101
|
curl -fsSL https://ghproxy.net/https://raw.githubusercontent.com/Te-River/Opencode-TeamMode/main/scripts/install.sh | bash
|
|
63
102
|
```
|
|
64
103
|
|
|
65
104
|
Windows (PowerShell):
|
|
105
|
+
|
|
66
106
|
```powershell
|
|
67
107
|
irm https://ghproxy.net/https://raw.githubusercontent.com/Te-River/Opencode-TeamMode/main/scripts/install.ps1 | iex
|
|
68
108
|
```
|
|
69
109
|
|
|
70
|
-
|
|
110
|
+
### Option 3 — Manual
|
|
71
111
|
|
|
72
112
|
Add the plugin to your `opencode.jsonc`:
|
|
73
113
|
|
|
@@ -80,101 +120,54 @@ Add the plugin to your `opencode.jsonc`:
|
|
|
80
120
|
}
|
|
81
121
|
```
|
|
82
122
|
|
|
83
|
-
OpenCode
|
|
84
|
-
|
|
85
|
-
> **Tip:** After modifying `opencode.json`, **restart OpenCode Desktop** for changes to take effect.
|
|
86
|
-
|
|
87
|
-
---
|
|
123
|
+
OpenCode installs the plugin on next startup.
|
|
88
124
|
|
|
89
|
-
|
|
125
|
+
### ⚠️ Read this once, save yourself an hour later
|
|
90
126
|
|
|
91
|
-
|
|
127
|
+
- **Restart to activate.** After touching `opencode.json`, fully quit and restart OpenCode (Desktop: quit from tray, not just the window).
|
|
128
|
+
- **Plugin updates: re-run the installer.** It is idempotent — a re-run re-patches the config (no-op when present), purges the stale plugin cache, and re-resolves any npm-installed copy. This exists because OpenCode caches plugins by spec string and does NOT re-resolve `@latest` when a new version publishes (upstream limitation). Manual recipe, if you prefer:
|
|
92
129
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
> reasoning model to the `team` agent (recipe in
|
|
98
|
-
> [Customization](#customization) below).
|
|
130
|
+
| OS | Cache location |
|
|
131
|
+
|---|---|
|
|
132
|
+
| macOS / Linux | `rm -rf ~/.cache/opencode/packages/@te_river+opencode-team-mode@latest` |
|
|
133
|
+
| Windows | `Remove-Item -Recurse -Force "$env:LOCALAPPDATA\opencode\cache\packages\@te_river+opencode-team-mode@latest"` |
|
|
99
134
|
|
|
100
|
-
|
|
135
|
+
If you also npm-installed the plugin into `~/.config/opencode`, its package-lock pins the version — run `npm install @te-river/opencode-team-mode@latest` there too. Full recipe (including an agent-driven update prompt): [installation guide, Updating](./docs/installation.md).
|
|
136
|
+
- **Prerequisites:** [OpenCode](https://opencode.ai) (Desktop or CLI) and Node ≥ 18.
|
|
101
137
|
|
|
102
|
-
|
|
138
|
+
### Verify
|
|
103
139
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
{
|
|
107
|
-
"$schema": "https://opencode.ai/config.json",
|
|
108
|
-
"plugin": [
|
|
109
|
-
"@te-river/opencode-team-mode@latest"
|
|
110
|
-
]
|
|
111
|
-
}
|
|
112
|
-
```
|
|
140
|
+
Restart, open the agent picker, and look for **team, architect, implementer,
|
|
141
|
+
reviewer, tester, researcher**. That's it — the team is hired.
|
|
113
142
|
|
|
114
143
|
---
|
|
115
144
|
|
|
116
145
|
## 📖 Usage
|
|
117
146
|
|
|
118
|
-
### Slash
|
|
119
|
-
|
|
120
|
-
TeamMode adds six slash commands to OpenCode. Type them in the chat input:
|
|
147
|
+
### Slash commands
|
|
121
148
|
|
|
122
149
|
| Command | Agent | Description |
|
|
123
150
|
|---|---|---|
|
|
124
|
-
| `/team-plan <task>` | Architect |
|
|
125
|
-
| `/team-implement <task>` | Implementer |
|
|
126
|
-
| `/team-review [scope]` | Reviewer | Audit
|
|
127
|
-
| `/team-test [scope]` | Tester |
|
|
128
|
-
| `/team-research <topic>` | Researcher |
|
|
129
|
-
| `/team-run <task>` | Team Lead | **
|
|
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
|
-
```
|
|
151
|
+
| `/team-plan <task>` | Architect | Implementation plan with architecture, file manifest, task breakdown |
|
|
152
|
+
| `/team-implement <task>` | Implementer | Production code for a feature or task |
|
|
153
|
+
| `/team-review [scope]` | Reviewer | Audit for bugs, security issues, quality problems |
|
|
154
|
+
| `/team-test [scope]` | Tester | Comprehensive tests with edge-case coverage |
|
|
155
|
+
| `/team-research <topic>` | Researcher | Local repo first; web via the governed tools |
|
|
156
|
+
| `/team-run <task>` | Team Lead | **The full workflow** — plan → approval → orchestration → verification |
|
|
149
157
|
|
|
150
|
-
|
|
158
|
+
Or `@`-mention agents directly: `@team`, `@architect`, `@implementer`,
|
|
159
|
+
`@reviewer`, `@tester`, `@researcher`.
|
|
151
160
|
|
|
152
|
-
|
|
161
|
+
### What a run feels like
|
|
153
162
|
|
|
154
|
-
|
|
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
|
|
163
|
+
Team is the default agent out of the box, so you just type into a fresh chat:
|
|
160
164
|
|
|
161
|
-
|
|
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/`.
|
|
165
|
+
> **You:** Add token-bucket rate limiting to our Express API — 100 requests per minute per user, return 429 when exceeded. Don't touch anything under `src/legacy/`.
|
|
170
166
|
|
|
171
167
|
```text
|
|
172
168
|
team Route: product behavior change → implementer → tester → reviewer
|
|
173
169
|
(3 dispatches → approval gate applies)
|
|
174
170
|
|
|
175
|
-
Research: read README, src/app.ts, src/middleware/*
|
|
176
|
-
Blocking questions: none — 1 assumption listed below
|
|
177
|
-
|
|
178
171
|
PLAN
|
|
179
172
|
Goal: token-bucket limiter, 100 req/min/user, 429 + Retry-After
|
|
180
173
|
Scope: src/middleware/rateLimit.ts (new), src/app.ts (+3 lines)
|
|
@@ -183,38 +176,25 @@ team Route: product behavior change → implementer → tester → reviewer
|
|
|
183
176
|
Boundary: src/legacy/** untouched
|
|
184
177
|
Approve to proceed?
|
|
185
178
|
|
|
186
|
-
|
|
179
|
+
you approved, go
|
|
187
180
|
|
|
188
181
|
team ▸ @implementer — STATUS: done
|
|
189
182
|
CHANGES: src/middleware/rateLimit.ts (new) · src/app.ts (+3)
|
|
190
|
-
|
|
191
|
-
EVIDENCE: tsc clean (output above)
|
|
183
|
+
EVIDENCE: tsc clean
|
|
192
184
|
|
|
193
185
|
▸ @tester — STATUS: done · VERDICT: pass (14/14)
|
|
194
186
|
FINDINGS: burst edge, window expiry, concurrent refill covered;
|
|
195
187
|
src/legacy/** byte-identical
|
|
196
|
-
EVIDENCE: vitest 14 passed
|
|
197
188
|
|
|
198
189
|
▸ @reviewer — STATUS: done · VERDICT: approve (correctness)
|
|
199
|
-
FINDINGS: no Critical/Major; 1 Minor (log line noise) noted
|
|
200
190
|
|
|
201
|
-
team Done.
|
|
202
|
-
rate limiter shipped: rateLimit.ts (new) · app.ts (+3) · 14 tests green
|
|
191
|
+
team Done. rateLimit.ts (new) · app.ts (+3) · 14 tests green
|
|
203
192
|
review: approve · assumption: in-memory only · src/legacy/ untouched
|
|
204
193
|
```
|
|
205
194
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
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.
|
|
195
|
+
You typed the task and four words. The plan was a routing-table lookup,
|
|
196
|
+
execution waited for your approval, and every handoff between agents traveled
|
|
197
|
+
as a structured skeleton — nothing landed in your repo, nothing was guessed.
|
|
218
198
|
|
|
219
199
|
---
|
|
220
200
|
|
|
@@ -224,385 +204,159 @@ Every tool TeamMode adds runs under ONE governance pipeline: outputs above
|
|
|
224
204
|
`TM_OFFLOAD_THRESHOLD` tokens never enter the context window — they are
|
|
225
205
|
offloaded to a run store and replaced by a content-aware preview plus an
|
|
226
206
|
HMAC-signed handle that the agent pages through with `tm_fetch` when it
|
|
227
|
-
genuinely needs the payload.
|
|
228
|
-
across v1.5.1–v1.5.6; see [CHANGELOG.md](./CHANGELOG.md) for the history.
|
|
207
|
+
genuinely needs the payload.
|
|
229
208
|
|
|
230
209
|
| Tool | What it does | Roles |
|
|
231
210
|
|---|---|---|
|
|
232
|
-
| `tm_read` / `tm_grep` / `tm_bash` / `tm_fetch` | Governed file read / regex search
|
|
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 |
|
|
211
|
+
| `tm_read` / `tm_grep` / `tm_bash` / `tm_fetch` | Governed file read / regex search / read-only shell (allowlist) / paged handle retrieval | all six agents |
|
|
212
|
+
| `tm_memory` | Project + global memory store (Markdown + frontmatter): add / search / list / forget | all six agents |
|
|
236
213
|
| `tm_ptc_run` | Batch orchestration: one program, N governed calls, zero LLM round-trips | all six agents |
|
|
214
|
+
| `tm_search` | Multi-engine web search with extracted, deduplicated hit lists | Lead + Researcher |
|
|
215
|
+
| `tm_webfetch` | Single governed GET of an allowlisted page (search pages auto-extracted) | Lead + Researcher |
|
|
216
|
+
| `tm_browser` | Interactive browser session (headful CDP): open / navigate / read / screenshot / close | Lead + Researcher + Tester (UI verification) |
|
|
237
217
|
|
|
238
218
|
> **Fixed tool priority ladder (every task): ① TeamMode governed tools
|
|
239
|
-
> (`tm_*`) → ② user MCP/plugin tools → ③ the model's own reasoning
|
|
240
|
-
>
|
|
241
|
-
>
|
|
242
|
-
> on this host, blocked host), the agent says so and drops to the next
|
|
243
|
-
> rung instead of giving up.
|
|
219
|
+
> (`tm_*`) → ② user MCP/plugin tools → ③ the model's own reasoning.**
|
|
220
|
+
> It doubles as the fallback chain: when a governed tool errors (no browser
|
|
221
|
+
> on this host, blocked host), the agent says so and drops to the next rung.
|
|
244
222
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
223
|
+
All governed tools are **parallel-safe**: the host may run a batch of
|
|
224
|
+
`tm_search` / `tm_webfetch` / `tm_fetch` calls concurrently — each call gets
|
|
225
|
+
its own step id and its own payload, and nothing cross-contaminates
|
|
226
|
+
(proven by the parallel test suite).
|
|
249
227
|
|
|
250
228
|
### Context governance: offload, handles, previews
|
|
251
229
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
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)
|
|
230
|
+
Large tool outputs are context cost's main driver — every step re-sends the
|
|
231
|
+
whole window. So results above `TM_OFFLOAD_THRESHOLD` tokens are written to a
|
|
232
|
+
local run store (`<repo>/.git/opencode-team/`, never your working tree) and
|
|
233
|
+
replaced by a handle with a content-aware preview: JSON keys / CSV header +
|
|
234
|
+
shape / log ERROR×N stats / code signatures / binary metadata, hard-capped at
|
|
235
|
+
80 tokens. When the agent actually needs the payload, it pages through with
|
|
236
|
+
`tm_fetch` using an HMAC-signed, run-scoped, expiring handle. `tm_bash` only
|
|
237
|
+
allows read-only commands (allowlist), and failures come back as structured
|
|
238
|
+
errors instead of raw dumps.
|
|
402
239
|
|
|
403
|
-
|
|
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.
|
|
240
|
+
### Project + global memory (tm_memory)
|
|
408
241
|
|
|
409
|
-
|
|
242
|
+
Durable facts — build commands, environment quirks, architecture decisions,
|
|
243
|
+
your conventions — live as human-editable Markdown with frontmatter:
|
|
410
244
|
|
|
411
|
-
|
|
412
|
-
|
|
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.
|
|
245
|
+
- **`project`** (default): `<repo>/.git/opencode-team/memories/…` — per checkout, git-adjacent.
|
|
246
|
+
- **`global`**: `~/.opencode-team/memories/global/` (override `TM_MEMORY_GLOBAL_DIR`) — **follows you across ALL projects**.
|
|
416
247
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
248
|
+
Actions: `add` / `search` (deterministic keyword scoring) / `list` / `forget`;
|
|
249
|
+
4000 chars per memory. Agents are prompted to search before assuming
|
|
250
|
+
conventions and to save hard-won facts for the next conversation.
|
|
420
251
|
|
|
421
|
-
|
|
252
|
+
### 🌐 Web search that actually works (in China)
|
|
422
253
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
254
|
+
`tm_search` is the open-ended-lookup front: **one call, one query, clean
|
|
255
|
+
results**. The engine URL is built for you, fetched through the governed
|
|
256
|
+
pipeline, and collapsed into a numbered title+URL hit list — the agent never
|
|
257
|
+
sees raw SERP chrome.
|
|
427
258
|
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
| Mode | Behavior |
|
|
259
|
+
| Engine | Notes |
|
|
431
260
|
|---|---|
|
|
432
|
-
| `
|
|
433
|
-
| `
|
|
434
|
-
| `
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
261
|
+
| `bing` (default) | cn.bing.com; `bing-int` forces international results (`ensearch=1`) |
|
|
262
|
+
| `sogou` / `so` (360) | CN-native engines, good for CJK content |
|
|
263
|
+
| `baidu` | flakiest (anti-bot) but sometimes the only CN-specific index; failures name alternatives |
|
|
264
|
+
| `bilibili` | video search |
|
|
265
|
+
| `moegirl` | MediaWiki search API — entry titles + snippets, structured |
|
|
266
|
+
| `npm` | registry search → name@version + description, structured |
|
|
267
|
+
| `github` | repo search API → stars + description, structured |
|
|
268
|
+
|
|
269
|
+
All nine engines are reachable from mainland China **without API keys**, and
|
|
270
|
+
every one of them sits on the seeded domain allowlist. On an empty result
|
|
271
|
+
(an anti-bot shell), the error names the alternative engines instead of
|
|
272
|
+
leaving the agent stuck. Two more channels complete the surface:
|
|
273
|
+
|
|
274
|
+
- `tm_webfetch` — a known URL, one governed GET. Search-engine pages it
|
|
275
|
+
fetches are auto-extracted to hit lists too. JSON endpoints like
|
|
276
|
+
`registry.npmjs.org/<pkg>/latest` pass through untouched.
|
|
277
|
+
- `tm_browser` — JS-rendered pages: your own Chromium-family browser, headful
|
|
278
|
+
via CDP pipe, isolated temp profile, **domain allowlist enforced at the
|
|
279
|
+
network layer** per request (`Fetch.requestPaused` → non-allowlisted hosts
|
|
280
|
+
get `BlockedByClient`).
|
|
281
|
+
|
|
282
|
+
Seeded allowlist (both tools): `mobile.moegirl.org.cn`, `search.bilibili.com`,
|
|
283
|
+
`cn.bing.com`, `www.bing.com`, `www.baidu.com`, `www.sogou.com`, `www.so.com`,
|
|
284
|
+
`registry.npmjs.org`, `api.github.com`, `raw.githubusercontent.com`,
|
|
285
|
+
`ghproxy.net` (mainland mirror for github raw) — extend via
|
|
286
|
+
`TM_WEBFETCH_ALLOWED_DOMAINS` (`"*"` opens every host). Architect /
|
|
287
|
+
implementer / reviewer have NO network grant — web questions come back as a
|
|
288
|
+
reported gap, never simulated. The tester carries `tm_browser` ONLY, for
|
|
289
|
+
governed UI verification of the project (local dev servers, preview routes);
|
|
290
|
+
open web fetching stays with the two network roles.
|
|
291
|
+
|
|
292
|
+
**Out-of-allowlist targets are a gate, not a wall.** When a fetch / search /
|
|
293
|
+
browser-open points at a host outside the allowlist, the tool hands the URL
|
|
294
|
+
to OpenCode's **official confirmation dialog** — you decide, once per
|
|
295
|
+
target (an unanswered dialog is auto-rejected on the usual 10-minute timer,
|
|
296
|
+
and the plugin still never self-allows). Every dialog also fires a
|
|
297
|
+
**system toast notification**, so you know something is waiting even when
|
|
298
|
+
you're not staring at the screen. Env-file URLs and non-http(s) schemes
|
|
299
|
+
remain hard-rejected with no dialog — R6 red lines are never consentable.
|
|
300
|
+
|
|
301
|
+
### Security: the R6 + R2 approval gate
|
|
302
|
+
|
|
303
|
+
**R6 environment protection.** With TeamMode active, the model cannot read
|
|
304
|
+
environment variables silently. Env reads (`printenv`, `env`, `Get-ChildItem
|
|
305
|
+
env:`, …) and env files (`.env`, shell rc) route through OpenCode's official
|
|
306
|
+
confirmation dialog; unanswered prompts are **auto-rejected after
|
|
307
|
+
`TM_ASK_TIMEOUT_MIN` (default 10 min)**. Env reads no wildcard can express
|
|
308
|
+
(embedded `$VAR` / `${VAR}` / `$env:` inside another command, command
|
|
309
|
+
substitution) and the `tm_*` wrapper channel stay a **hard block** — no dialog
|
|
310
|
+
to slip through. The audit log records only tool name + pattern category +
|
|
311
|
+
verdict — never command text, paths, variable names or values.
|
|
312
|
+
|
|
313
|
+
**R2 dangerous operations (same dialog).** Delete, git publish, network
|
|
314
|
+
fetch, package install/publish, process/system, privilege changes — none are
|
|
315
|
+
silently allowed. The normal verification stack (`npm test`, `tsc`,
|
|
316
|
+
`git status`) is NOT gated, so day-to-day work runs uninterrupted.
|
|
440
317
|
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
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
|
|
318
|
+
> ⚠️ **When you approve a dialog, pick "once" — not "always".** Verified on
|
|
319
|
+
> the live host, "always" records a far broader rule than the command you
|
|
320
|
+
> saw: approving `Get-ChildItem env:PATH` with "always" stores `Get-ChildItem
|
|
321
|
+
> *`, so every later `Get-ChildItem` runs with no dialog at all.
|
|
452
322
|
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
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
|
-
```
|
|
323
|
+
> Deferral to the dialog is per-session: env reads only route to the dialog
|
|
324
|
+
> in sessions running TeamMode's injected agents. In any other session the
|
|
325
|
+
> guard keeps hard-blocking env reads. `headless opencode run` auto-rejects
|
|
326
|
+
> unanswered `ask`s immediately (there is no human to prompt).
|
|
475
327
|
|
|
476
|
-
###
|
|
328
|
+
### Repo hygiene
|
|
477
329
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
330
|
+
The offload/trajectory/memory stores live under `<repo>/.git/opencode-team/`
|
|
331
|
+
(or the OS temp dir outside a git repo) — **never your working tree**. Every
|
|
332
|
+
agent is instructed to delete scratch files before reporting done and to keep
|
|
333
|
+
throwaway work in the OS temp dir. A TTL sweeper reclaims old task dirs at
|
|
334
|
+
startup + hourly; the Team Lead never deletes boards itself, so you can audit
|
|
335
|
+
any run.
|
|
483
336
|
|
|
484
337
|
---
|
|
485
338
|
|
|
486
|
-
##
|
|
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.
|
|
339
|
+
## ⚙️ Configuration
|
|
576
340
|
|
|
577
|
-
|
|
341
|
+
The plugin injects everything at startup — no agent files to copy.
|
|
578
342
|
|
|
579
|
-
|
|
580
|
-
|
|
343
|
+
> **Model choice matters.** Every judgment — triage, decomposition, dispatch
|
|
344
|
+
> briefs, synthesis, review verdicts — flows through the Team Lead. A weak
|
|
345
|
+
> model in that seat degrades the whole pipeline no matter how strong the
|
|
346
|
+
> specialists are. Pin your best reasoning model to `team`:
|
|
581
347
|
|
|
582
348
|
```jsonc
|
|
583
349
|
{
|
|
584
|
-
"
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
350
|
+
"agent": {
|
|
351
|
+
"team": { "model": "anthropic/claude-opus-4-5" }, // Lead earns your best model
|
|
352
|
+
"implementer": { "model": "anthropic/claude-sonnet-4-6" } // specialists tolerate cheaper
|
|
353
|
+
}
|
|
588
354
|
}
|
|
589
355
|
```
|
|
590
356
|
|
|
591
|
-
|
|
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.)
|
|
357
|
+
**Global install** — put the plugin entry in `~/.config/opencode/opencode.jsonc` and every project gets the team.
|
|
603
358
|
|
|
604
|
-
|
|
605
|
-
team**):
|
|
359
|
+
**Keep Team off the default slot:**
|
|
606
360
|
|
|
607
361
|
```jsonc
|
|
608
362
|
{
|
|
@@ -612,48 +366,64 @@ team**):
|
|
|
612
366
|
}
|
|
613
367
|
```
|
|
614
368
|
|
|
615
|
-
|
|
616
|
-
|
|
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
|
|
369
|
+
Your own agents named `team` / `architect` / … always take precedence; the
|
|
370
|
+
plugin never clobbers user definitions. See [Customization](#-customization)
|
|
371
|
+
for overrides, extra agents and disabling roles.
|
|
626
372
|
|
|
627
|
-
###
|
|
373
|
+
### Environment variables
|
|
628
374
|
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
375
|
+
| Env var | Default | Purpose |
|
|
376
|
+
|---|---|---|
|
|
377
|
+
| `TM_ENV_PROTECT` | `strict` | R6 mode: `strict` / `standard` / `off` (off also disarms the approval timer) |
|
|
378
|
+
| `TM_ASK_TIMEOUT_MIN` | `10` | minutes before an unanswered dialog is auto-rejected (hard floor 3 — the host's reply event reaches the plugin ~120 s late) |
|
|
379
|
+
| `TM_ENV_PROTECT_EXTRA_DENY` | — | extra block patterns (regex; always hard block, never dialog-governed) |
|
|
380
|
+
| `TM_OFFLOAD_THRESHOLD` | `2000` | offload threshold (tokens, CJK-aware estimate) |
|
|
381
|
+
| `TM_PREVIEW_MAX_TOKENS` | `80` | preview hard cap |
|
|
382
|
+
| `TM_FETCH_MAX_LINES` | `2000` | tm_fetch page cap |
|
|
383
|
+
| `TM_BLACKBOARD_DIR` / `TM_TRAJECTORY_DIR` | `<repo>/.git/opencode-team/…` | offload store / trajectory ledger (tmpdir fallback; explicit = absolute or project-relative) |
|
|
384
|
+
| `TM_BLACKBOARD_TTL` | `7` | store retention (days) |
|
|
385
|
+
| `TM_BASH_READONLY_ALLOWED` | built-in table | tm_bash allowlist |
|
|
386
|
+
| `TM_WEBFETCH_ALLOWED_DOMAINS` | the eleven seeded hosts | tm_webfetch / tm_search / tm_browser allowlist (`"*"` opens all; empty = deny all) |
|
|
387
|
+
| `TM_BROWSER_PATH` | auto-detect | tm_browser executable override (Edge/Chrome/Chromium per OS) |
|
|
388
|
+
| `TM_BROWSER_HEADLESS` | `auto` | `1` headless (CI) / `0` headful / `auto` (headless only on display-less Linux) |
|
|
389
|
+
| `TM_MEMORY_GLOBAL_DIR` | `~/.opencode-team/memories/global/` | tm_memory GLOBAL scope store |
|
|
390
|
+
| `TM_PTC_MAX_PROGRAM_CHARS` | `4000` | PTC program source cap |
|
|
391
|
+
| `TM_PTC_MAX_CALLS` | `20` | PTC per-run bridge-call budget (1–200) |
|
|
392
|
+
| `TM_PTC_MAX_ERRORS` | `3` | PTC per-run error budget (1–50) |
|
|
393
|
+
| `TM_PTC_TIMEOUT_MS` | `60000` | PTC per-run wall-clock timeout (5s–10min) |
|
|
394
|
+
| `TM_PTC_ENGINE` | `auto` | `auto` (worker→inline degrade) / `worker` / `inline` |
|
|
635
395
|
|
|
636
|
-
|
|
637
|
-
roles tolerate cheaper models — they work from tight briefs with scoped
|
|
638
|
-
reading. Pin models per agent:
|
|
396
|
+
---
|
|
639
397
|
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
398
|
+
## 🏗️ How the team works
|
|
399
|
+
|
|
400
|
+
Sub-agents can't message each other live (platform limitation), so TeamMode
|
|
401
|
+
coordinates them through a **structured reply skeleton** — every specialist
|
|
402
|
+
reply is `STATUS: / CHANGES: / FINDINGS: / EVIDENCE: / HANDOFF:`, ≤50 lines,
|
|
403
|
+
relayed verbatim by the Lead into the next dispatch. Files are the exception,
|
|
404
|
+
not the rule: a deliverable over ~50 lines goes to ONE named board file under
|
|
405
|
+
`<repo>/.git/opencode-team/` (round-suffixed, working tree untouched).
|
|
406
|
+
|
|
407
|
+
- **Routing table:** question → direct answer; docs-only → implementer;
|
|
408
|
+
product change → implementer → tester → reviewer; multi-module →
|
|
409
|
+
architect → implementer → tester → reviewer(s); unknown tech → researcher
|
|
410
|
+
first. Fixed minimums — a product change routed below 3 dispatches is a
|
|
411
|
+
routing bug.
|
|
412
|
+
- **Approval gate (count-based):** ≥2 dispatches → plan (≤30 lines) → **your
|
|
413
|
+
approval** → execute. Blocking questions are batched and asked immediately.
|
|
414
|
+
- **Adaptive review:** one reviewer by default; three parallel dimensions
|
|
415
|
+
only for high-risk profiles (auth/security, cross-module contracts, public APIs).
|
|
416
|
+
- **Static verification:** build / typecheck / lint / tests. Improvised
|
|
417
|
+
browser automation is banned; unverified UI work ends with
|
|
418
|
+
`UI NOT VERIFIED: <what to check>`.
|
|
419
|
+
- **Evidence standard:** "done / fixed / passed" claims need verifiable
|
|
420
|
+
evidence — output, logs, diffs.
|
|
650
421
|
|
|
651
|
-
|
|
652
|
-
Your own `agent.team` definition always takes precedence over the plugin's.)
|
|
422
|
+
---
|
|
653
423
|
|
|
654
|
-
|
|
424
|
+
## 🔧 Customization
|
|
655
425
|
|
|
656
|
-
|
|
426
|
+
**Override an agent** — same name in your config wins:
|
|
657
427
|
|
|
658
428
|
```jsonc
|
|
659
429
|
{
|
|
@@ -666,9 +436,7 @@ Add an agent with the same name in your `opencode.json` — your definition take
|
|
|
666
436
|
}
|
|
667
437
|
```
|
|
668
438
|
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
TeamMode does not prevent you from adding more agents. Define them alongside the team:
|
|
439
|
+
**Add your own agents** alongside the team:
|
|
672
440
|
|
|
673
441
|
```jsonc
|
|
674
442
|
{
|
|
@@ -682,38 +450,96 @@ TeamMode does not prevent you from adding more agents. Define them alongside the
|
|
|
682
450
|
}
|
|
683
451
|
```
|
|
684
452
|
|
|
685
|
-
|
|
453
|
+
**Disable one:** `"researcher": { "disable": true }`.
|
|
686
454
|
|
|
687
|
-
|
|
688
|
-
{
|
|
689
|
-
"agent": {
|
|
690
|
-
"researcher": { "disable": true }
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
|
-
```
|
|
455
|
+
**Board retention** via the tuple form: `["@te-river/opencode-team-mode@latest", { "ttlDays": 7 }]` (valid range (0, 365], invalid values fall back to 5).
|
|
694
456
|
|
|
695
457
|
---
|
|
696
458
|
|
|
697
|
-
##
|
|
459
|
+
## ❓ FAQ
|
|
460
|
+
|
|
461
|
+
**Will this eat my tokens?**
|
|
462
|
+
The opposite is the point. Offload + 80-token previews + PTC batch programs
|
|
463
|
+
exist because a five-agent pipeline naively bolted onto one context window
|
|
464
|
+
*would* eat your tokens. The governance is the token-saver.
|
|
465
|
+
|
|
466
|
+
**Is the web access safe?**
|
|
467
|
+
It's the most guarded surface in the plugin: two full web roles plus a
|
|
468
|
+
browser-only tester grant, a domain
|
|
469
|
+
allowlist with dialog-gated escapes (you approve any out-of-allowlist
|
|
470
|
+
target in OpenCode's official dialog, with a toast notification), redirects
|
|
471
|
+
re-checked per hop, network-layer enforcement in the browser, env-file URL
|
|
472
|
+
refusal, and every payload rides the same offload governance. No allowlisted
|
|
473
|
+
page can bounce the fetch off-site.
|
|
474
|
+
|
|
475
|
+
**Why doesn't the plugin auto-update?**
|
|
476
|
+
OpenCode caches plugins by spec string and never re-resolves `@latest`
|
|
477
|
+
(upstream limitation, not ours). **Re-run the installer — that IS the
|
|
478
|
+
update** (it purges the cache and re-resolves npm copies); or delete the
|
|
479
|
+
cache dir by hand. Recipe above and in the
|
|
480
|
+
[installation guide](./docs/installation.md).
|
|
481
|
+
|
|
482
|
+
**Can agents run tools in parallel?**
|
|
483
|
+
Yes — and they're *engineered* for it: parallel `tm_search` / `tm_webfetch` /
|
|
484
|
+
`tm_fetch` calls get distinct step ids and isolated payloads. A regression
|
|
485
|
+
here fails the test suite before it ever reaches you.
|
|
486
|
+
|
|
487
|
+
**Does it work in the CLI (TUI), or only Desktop?**
|
|
488
|
+
Both. Desktop adds the color-coded picker and panels; the governed tools and
|
|
489
|
+
the whole workflow are host-agnostic. On display-less Linux, `tm_browser`
|
|
490
|
+
runs headless automatically.
|
|
491
|
+
|
|
492
|
+
**What happens if I don't answer a confirmation dialog?**
|
|
493
|
+
It auto-rejects after `TM_ASK_TIMEOUT_MIN` (default 10). The plugin never
|
|
494
|
+
self-approves — the only side it can take is yours or nobody's.
|
|
698
495
|
|
|
699
|
-
|
|
496
|
+
---
|
|
700
497
|
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
498
|
+
## 🗑️ Uninstall
|
|
499
|
+
|
|
500
|
+
1. Remove the entry from the `"plugin"` array in your config file.
|
|
501
|
+
2. Delete the cache dir (table in [Install](#-read-this-once-save-yourself-an-hour-later)) if you want the disk space back.
|
|
502
|
+
3. Restart OpenCode. The agents, commands and tools are gone; the stores under `<repo>/.git/opencode-team/` (and `~/.opencode-team/` for global memories) are plain files you can delete whenever.
|
|
503
|
+
|
|
504
|
+
No DLLs were harmed. Nothing was written to your working tree.
|
|
505
|
+
|
|
506
|
+
---
|
|
507
|
+
|
|
508
|
+
## 🏛️ Architecture (for the curious)
|
|
509
|
+
|
|
510
|
+
```
|
|
511
|
+
opencode-team-mode/
|
|
512
|
+
├── src/
|
|
513
|
+
│ ├── index.ts ← Plugin entry (config + R6 guard + approval gate + tool segment)
|
|
514
|
+
│ ├── agents.ts ← Agent structure (modes, colors, temperatures, whitelist matrix)
|
|
515
|
+
│ ├── prompts/ ← Agent prompts (lead / specialists / shared) — pinned by tests
|
|
516
|
+
│ ├── commands.ts ← Slash command definitions
|
|
517
|
+
│ ├── blackboard.ts ← Shared blackboard + TTL sweeper
|
|
518
|
+
│ ├── envprotect.ts ← R6 facade (patterns / classifiers / gate predicates / hook)
|
|
519
|
+
│ ├── approval-gate.ts ← Unified approval gate (dialog timeout auto-reject)
|
|
520
|
+
│ ├── tm/ ← Governed tools: pipelines / store / preview / guard / refs /
|
|
521
|
+
│ │ webfetch / search / memory / browser / shell-bridge / ptc/ (9 modules)
|
|
522
|
+
│ └── types.ts ← Loader-contract types (1.18.x)
|
|
523
|
+
├── docs/installation.md ← The agent-consumable install guide
|
|
524
|
+
├── scripts/ ← One-line installers (bash / PowerShell)
|
|
525
|
+
├── pt07/ ← PT-07 baseline suite (seeded A/B token measurement)
|
|
526
|
+
└── README.*.md ← You are here (twice)
|
|
705
527
|
```
|
|
706
528
|
|
|
529
|
+
The loader calls `server(input, options)` once: the `config` hook injects the
|
|
530
|
+
six agents and six commands, the same call installs the R6
|
|
531
|
+
`tool.execute.before` guard, arms the approval gate through an `event` hook,
|
|
532
|
+
and registers the `tm_*` tools. User-defined agents with the same name always
|
|
533
|
+
win — the plugin never clobbers.
|
|
534
|
+
|
|
707
535
|
---
|
|
708
536
|
|
|
709
537
|
## 🤝 Contributing
|
|
710
538
|
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
- 🔧 **Additional commands** — `/team-deploy`, `/team-docs`, `/team-refactor`
|
|
716
|
-
- 📝 **Better prompts** — Improve agent behavior through prompt engineering
|
|
539
|
+
Issues and PRs welcome. Especially wanted: localization of agent prompts,
|
|
540
|
+
more agent roles, more command templates, and real-world reports of the
|
|
541
|
+
search engines' behavior (they rearrange their markup; the extractor filters
|
|
542
|
+
are intentionally loose but not psychic).
|
|
717
543
|
|
|
718
544
|
---
|
|
719
545
|
|
|
@@ -725,8 +551,8 @@ Contributions are welcome! Areas where we need help:
|
|
|
725
551
|
|
|
726
552
|
## 🔗 Links
|
|
727
553
|
|
|
728
|
-
- [npm Package](https://www.npmjs.com/package/@te-river/opencode-team-mode) — `@te-river/opencode-team-mode`
|
|
554
|
+
- [npm Package](https://www.npmjs.com/package/@te-river/opencode-team-mode) — `@te-river/opencode-team-mode`
|
|
555
|
+
- [Installation guide](./docs/installation.md) — the complete manual / agent-consumable procedure
|
|
729
556
|
- [OpenCode Desktop](https://opencode.ai) — Official website & download
|
|
730
557
|
- [OpenCode Docs](https://opencode.ai/docs) — Configuration & plugin documentation
|
|
731
558
|
- [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
|