@te-river/opencode-team-mode 1.5.11 → 1.5.12
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 +129 -53
- package/README.zh-CN.md +103 -45
- package/dist/agents.d.ts.map +1 -1
- package/dist/agents.js +17 -11
- package/dist/agents.js.map +1 -1
- package/dist/approval-gate.d.ts +54 -16
- package/dist/approval-gate.d.ts.map +1 -1
- package/dist/approval-gate.js +163 -42
- package/dist/approval-gate.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 +22 -3
- 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 +154 -119
- 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 +40 -11
- package/dist/prompts/specialists.js.map +1 -1
- package/dist/tm/args-schema.d.ts +25 -1
- package/dist/tm/args-schema.d.ts.map +1 -1
- package/dist/tm/args-schema.js +149 -39
- package/dist/tm/args-schema.js.map +1 -1
- package/dist/tm/browser.d.ts +188 -19
- package/dist/tm/browser.d.ts.map +1 -1
- package/dist/tm/browser.js +781 -111
- package/dist/tm/browser.js.map +1 -1
- package/dist/tm/config.d.ts +61 -0
- package/dist/tm/config.d.ts.map +1 -1
- package/dist/tm/config.js +55 -1
- package/dist/tm/config.js.map +1 -1
- package/dist/tm/index.d.ts +5 -3
- package/dist/tm/index.d.ts.map +1 -1
- package/dist/tm/index.js +36 -2
- package/dist/tm/index.js.map +1 -1
- package/dist/tm/memory.d.ts +88 -10
- package/dist/tm/memory.d.ts.map +1 -1
- package/dist/tm/memory.js +881 -99
- package/dist/tm/memory.js.map +1 -1
- package/dist/tm/pipelines.d.ts +26 -3
- package/dist/tm/pipelines.d.ts.map +1 -1
- package/dist/tm/pipelines.js +167 -11
- package/dist/tm/pipelines.js.map +1 -1
- package/dist/tm/ptc/budgets.d.ts +22 -1
- package/dist/tm/ptc/budgets.d.ts.map +1 -1
- package/dist/tm/ptc/budgets.js +87 -8
- package/dist/tm/ptc/budgets.js.map +1 -1
- package/dist/tm/ptc/contract.d.ts +49 -9
- package/dist/tm/ptc/contract.d.ts.map +1 -1
- package/dist/tm/ptc/contract.js +41 -3
- package/dist/tm/ptc/contract.js.map +1 -1
- package/dist/tm/ptc/driver.d.ts +5 -2
- package/dist/tm/ptc/driver.d.ts.map +1 -1
- package/dist/tm/ptc/driver.js +47 -15
- package/dist/tm/ptc/driver.js.map +1 -1
- package/dist/tm/ptc/engines.d.ts +15 -4
- package/dist/tm/ptc/engines.d.ts.map +1 -1
- package/dist/tm/ptc/engines.js +281 -28
- package/dist/tm/ptc/engines.js.map +1 -1
- package/dist/tm/ptc/index.d.ts +4 -4
- package/dist/tm/ptc/index.d.ts.map +1 -1
- package/dist/tm/ptc/index.js +2 -2
- package/dist/tm/ptc/index.js.map +1 -1
- package/dist/tm/ptc/pscan.d.ts +20 -1
- package/dist/tm/ptc/pscan.d.ts.map +1 -1
- package/dist/tm/ptc/pscan.js +328 -14
- package/dist/tm/ptc/pscan.js.map +1 -1
- package/dist/tm/ptc/summary.d.ts.map +1 -1
- package/dist/tm/ptc/summary.js +23 -1
- package/dist/tm/ptc/summary.js.map +1 -1
- package/dist/tm/ptc/tool.d.ts +34 -3
- package/dist/tm/ptc/tool.d.ts.map +1 -1
- package/dist/tm/ptc/tool.js +117 -20
- package/dist/tm/ptc/tool.js.map +1 -1
- package/dist/tm/search.d.ts +83 -14
- package/dist/tm/search.d.ts.map +1 -1
- package/dist/tm/search.js +440 -45
- package/dist/tm/search.js.map +1 -1
- package/dist/tm/shell-bridge.d.ts +14 -1
- package/dist/tm/shell-bridge.d.ts.map +1 -1
- package/dist/tm/shell-bridge.js +57 -10
- package/dist/tm/shell-bridge.js.map +1 -1
- package/dist/tm/webfetch.d.ts +25 -7
- package/dist/tm/webfetch.d.ts.map +1 -1
- package/dist/tm/webfetch.js +88 -14
- package/dist/tm/webfetch.js.map +1 -1
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -44,7 +44,7 @@ TeamMode's answer to each:
|
|
|
44
44
|
|
|
45
45
|
| Pain | TeamMode's answer |
|
|
46
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. |
|
|
47
|
+
| 🔥 **Context flooding** | Every governed tool output over its content-class offload threshold (prose 4000 / data 2000 tokens, CJK-aware) 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
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
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
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. |
|
|
@@ -201,19 +201,22 @@ as a structured skeleton — nothing landed in your repo, nothing was guessed.
|
|
|
201
201
|
## 🧰 Governed tools & security
|
|
202
202
|
|
|
203
203
|
Every tool TeamMode adds runs under ONE governance pipeline: outputs above
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
204
|
+
the offload threshold never enter the context window — the boundary is
|
|
205
|
+
content-class aware (`TM_OFFLOAD_THRESHOLD_TEXT` = 4000 for prose:
|
|
206
|
+
text/log/markdown; `TM_OFFLOAD_THRESHOLD_DATA` = 2000 for json/csv/code/
|
|
207
|
+
binary; an unknown class falls back to the global `TM_OFFLOAD_THRESHOLD`) —
|
|
208
|
+
and oversized results are offloaded to a run store and replaced by a
|
|
209
|
+
content-aware preview plus an HMAC-signed handle that the agent pages
|
|
210
|
+
through with `tm_fetch` when it genuinely needs the payload.
|
|
208
211
|
|
|
209
212
|
| Tool | What it does | Roles |
|
|
210
213
|
|---|---|---|
|
|
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` |
|
|
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 |
|
|
214
|
+
| `tm_read` / `tm_grep` / `tm_bash` / `tm_fetch` | Governed file read / regex search / read-only shell (allowlist) / paged handle retrieval (JSON handles take a `fields` dot-path projection — a deliberately small jq subset like `items[].name`) | all six agents |
|
|
215
|
+
| `tm_memory` | Session + project + global memory store (Markdown + frontmatter): add / search / list / forget / compact | all six agents |
|
|
216
|
+
| `tm_ptc_run` | Batch orchestration: one program, N governed calls, zero LLM round-trips; web roles also get `tm.search` / `tm.webfetch` inside the program | all six agents |
|
|
217
|
+
| `tm_search` | Multi-engine web search with extracted, deduplicated, RRF-fused hit lists | Lead + Researcher |
|
|
215
218
|
| `tm_webfetch` | Single governed GET of an allowlisted page (search pages auto-extracted) | Lead + Researcher |
|
|
216
|
-
| `tm_browser` | Interactive browser session (
|
|
219
|
+
| `tm_browser` | Interactive browser session (**your default browser**): 16 Playwright verbs (snapshot-first `take_snapshot` → uid-addressed `click`/`fill`/`drag`/…) + 5 legacy compat verbs (open/navigate/read/screenshot/close); Playwright engine needs Node ≥ 20, below that (or on any import failure) it auto-degrades to the legacy CDP engine | Lead + Researcher + Tester (UI verification) |
|
|
217
220
|
|
|
218
221
|
> **Fixed tool priority ladder (every task): ① TeamMode governed tools
|
|
219
222
|
> (`tm_*`) → ② user MCP/plugin tools → ③ the model's own reasoning.**
|
|
@@ -228,26 +231,48 @@ its own step id and its own payload, and nothing cross-contaminates
|
|
|
228
231
|
### Context governance: offload, handles, previews
|
|
229
232
|
|
|
230
233
|
Large tool outputs are context cost's main driver — every step re-sends the
|
|
231
|
-
whole window. So results above
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
234
|
+
whole window. So results above the content-class offload boundary (prose →
|
|
235
|
+
`TM_OFFLOAD_THRESHOLD_TEXT`, structured data → `TM_OFFLOAD_THRESHOLD_DATA`,
|
|
236
|
+
unknown → global `TM_OFFLOAD_THRESHOLD`) are written to a local run store
|
|
237
|
+
(`<repo>/.git/opencode-team/`, never your working tree) and replaced by a
|
|
238
|
+
handle with a content-aware preview: JSON keys / CSV header + shape / log
|
|
239
|
+
ERROR×N stats / code signatures / binary metadata, hard-capped at 80 tokens.
|
|
240
|
+
When the agent actually needs the payload, it pages through with `tm_fetch`
|
|
241
|
+
using an HMAC-signed, run-scoped, expiring handle — and on a JSON handle it
|
|
242
|
+
can ask for a `fields` dot-path projection instead (a deliberately small jq
|
|
243
|
+
subset: `items[].name`, `[].stargazers_count`), so a big API dump narrows to
|
|
244
|
+
just the values needed without the raw body ever entering the window.
|
|
245
|
+
`tm_bash` only allows read-only commands (allowlist), and failures come back
|
|
246
|
+
as structured errors instead of raw dumps.
|
|
247
|
+
|
|
248
|
+
### Session + project + global memory (tm_memory)
|
|
241
249
|
|
|
242
250
|
Durable facts — build commands, environment quirks, architecture decisions,
|
|
243
|
-
your conventions — live as human-editable Markdown with frontmatter
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
- **`
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
+
your conventions — live as human-editable Markdown with frontmatter, in
|
|
252
|
+
THREE tiers:
|
|
253
|
+
|
|
254
|
+
- **`session`**: this conversation's transients only — in-process, TTL-swept
|
|
255
|
+
(`TM_MEMORY_SESSION_TTL_MIN`, default 240 min), invisible to other
|
|
256
|
+
sessions; ephemeral unless `TM_MEMORY_SESSION_PERSIST=1` writes them under
|
|
257
|
+
`memories/sessions/<sid>/`.
|
|
258
|
+
- **`project`** (default): `<repo>/.git/opencode-team/memories/…` — per checkout, git-adjacent. Facts about THIS repo: build commands, environment quirks, architecture decisions.
|
|
259
|
+
- **`global`**: `~/.opencode-team/memories/global/` (override `TM_MEMORY_GLOBAL_DIR`) — **follows you across ALL projects**. User-level conventions: preferred package manager, commit style, tooling habits.
|
|
260
|
+
|
|
261
|
+
Actions: `add` / `search` (deterministic keyword scoring) / `list` / `forget` /
|
|
262
|
+
`compact`; 4000 chars per memory. `search` walks ALL tiers with **session >
|
|
263
|
+
project > global precedence** — project entries get a +2 near-tie weight and a
|
|
264
|
+
same-title higher-layer twin shadows the lower one (it never surfaces).
|
|
265
|
+
Near-duplicates never pile up: an `add` that hits an existing entry in the same
|
|
266
|
+
tier and category (dedup key, or title+keywords Jaccard ≥ 0.6) **folds into
|
|
267
|
+
it** — new content wins, keywords union, the old slug moves to `supersedes:`,
|
|
268
|
+
and the answer says 已合并 (that is normal; don't re-add under a variant title).
|
|
269
|
+
When a tier reaches `TM_MEMORY_MAX_ENTRIES` (200 per scope) the add fails on
|
|
270
|
+
purpose: run `compact` first — it dry-runs the merge plan by default, and
|
|
271
|
+
re-running with `apply:true` performs it after copying every original to a
|
|
272
|
+
timestamped `.compact-backup` tree (the rollback path). Entries older than
|
|
273
|
+
`TM_MEMORY_STALE_DAYS` (30) surface tagged `[stale Nd]` in search. Agents
|
|
274
|
+
are prompted to search before assuming conventions and to save hard-won
|
|
275
|
+
facts for the next conversation.
|
|
251
276
|
|
|
252
277
|
### 🌐 Web search that actually works (in China)
|
|
253
278
|
|
|
@@ -258,18 +283,22 @@ sees raw SERP chrome.
|
|
|
258
283
|
|
|
259
284
|
| Engine | Notes |
|
|
260
285
|
|---|---|
|
|
261
|
-
| `
|
|
262
|
-
| `
|
|
263
|
-
| `
|
|
286
|
+
| `auto` (default) | Classifies the query, fans out to 2–3 engines **in parallel**, dedupes by host+path and fuses with weighted RRF (stackoverflow/bing 0.4, others 0.2) into a top-10 list tagged with each hit's source engine(s). Routing: errors / camelCase APIs → `stackoverflow`+`github`+`bing`; dev-ecosystem (releases, frameworks, open source) → `hn`+`github`+`npm`; Chinese / general → `bing`. Pin another default via `TM_SEARCH_DEFAULT_ENGINE` |
|
|
287
|
+
| `bing` | cn.bing.com — the only live CN HTML SERP; multi-word CJK queries get their phrase boundary protected (quoted) so markup shuffle can't split the result list |
|
|
288
|
+
| `stackoverflow` | api.stackexchange.com question search (no key, 300/day/IP) → numbered questions with composite snippets; `auto` tracks the quota and swaps in `bing` once spent |
|
|
289
|
+
| `hn` | Hacker News via Algolia API (no key) → story titles + snippets with direct article URLs |
|
|
264
290
|
| `bilibili` | video search |
|
|
265
291
|
| `moegirl` | MediaWiki search API — entry titles + snippets, structured |
|
|
266
292
|
| `npm` | registry search → name@version + description, structured |
|
|
267
|
-
| `github` | repo search API → stars + description, structured |
|
|
293
|
+
| `github` | repo search API → stars + description, structured; `org:` / `user:` / `stars:` / `language:` qualifiers fold into the query (e.g. `vector db stars:>500 language:rust`) |
|
|
268
294
|
|
|
269
|
-
All
|
|
270
|
-
every one of them sits on the seeded domain allowlist.
|
|
271
|
-
(
|
|
272
|
-
|
|
295
|
+
All seven engines are reachable from mainland China **without API keys**, and
|
|
296
|
+
every one of them sits on the seeded domain allowlist. The previous CN HTML
|
|
297
|
+
SERPs (`sogou` / `so` / `baidu` / `bing-int`) were **removed** — a live
|
|
298
|
+
benchmark (2026-09-14) showed them serving anti-bot shells or 100% empty
|
|
299
|
+
results; they are not even manually selectable. On an empty result,
|
|
300
|
+
the error names the alternative engines instead of leaving the agent stuck.
|
|
301
|
+
Two more channels complete the surface:
|
|
273
302
|
|
|
274
303
|
- `tm_webfetch` — a known URL, one governed GET. Search-engine pages it
|
|
275
304
|
fetches are auto-extracted to hit lists too. JSON endpoints like
|
|
@@ -277,9 +306,28 @@ leaving the agent stuck. Two more channels complete the surface:
|
|
|
277
306
|
- `tm_browser` — JS-rendered pages: **your DEFAULT browser** (Windows
|
|
278
307
|
registry / Linux `xdg-settings`; Chromium-family only — Firefox falls back
|
|
279
308
|
to the Edge/Chrome probe order because CDP is Chromium-proprietary;
|
|
280
|
-
`TM_BROWSER_PATH` overrides), headful
|
|
281
|
-
**domain allowlist enforced at the network layer** per request
|
|
282
|
-
|
|
309
|
+
`TM_BROWSER_PATH` overrides), headful by default, isolated temp profile,
|
|
310
|
+
**domain allowlist enforced at the network layer** per request and per
|
|
311
|
+
redirect hop. The action surface is chrome-devtools-mcp aligned: **16
|
|
312
|
+
Playwright verbs** (`navigate_page` · `take_snapshot` · `click` · `fill` ·
|
|
313
|
+
`hover` · `drag` · `press_key` · `select_page` · `upload_file` · `wait_for`
|
|
314
|
+
· `evaluate_script` · `list_console_messages` · `list_network_requests` ·
|
|
315
|
+
`list_pages` · `take_screenshot` · `handle_dialog`) plus 5 legacy compat
|
|
316
|
+
verbs (`open` / `navigate` / `read` / `screenshot` / `close`).
|
|
317
|
+
Snapshot-first: `take_snapshot` returns the aria snapshot with injected
|
|
318
|
+
`[uid=eN]` tokens, follow-up actions address nodes by uid instead of
|
|
319
|
+
guessed locators; snapshots are hard-capped by
|
|
320
|
+
`TM_BROWSER_SNAPSHOT_MAX_TOKENS` (default 1200).
|
|
321
|
+
**Engine split:** the primary engine is `playwright-core` (an optional
|
|
322
|
+
dependency — needs **Node ≥ 20**; on older Node, or if the import fails,
|
|
323
|
+
the session auto-degrades per instance to the zero-dep `cdp-legacy`
|
|
324
|
+
engine, which keeps the core verbs only; pin either via
|
|
325
|
+
`TM_BROWSER_ENGINE=playwright|cdp-legacy`). No browser download is ever
|
|
326
|
+
involved — Playwright launches YOUR installed browser by path, so
|
|
327
|
+
`npx playwright install` is not part of the user flow (the dependency
|
|
328
|
+
itself resolves at npm install/publish time). Isolated temp profile by
|
|
329
|
+
default: persistent logins only if you explicitly set
|
|
330
|
+
`TM_BROWSER_USER_DATA_DIR`.
|
|
283
331
|
|
|
284
332
|
When a fetch still returns **403 after the real-Chrome headers**, the error
|
|
285
333
|
is a DIRECTIVE: the gate is JS-challenge / TLS-fingerprint based and only a
|
|
@@ -289,16 +337,18 @@ filter known noise: engine-internal wrappers (`so.com/link?`, `ai.so.com`)
|
|
|
289
337
|
and same-name-different-site domains (`maimai.cn` 脉脉 vs the maimai DX
|
|
290
338
|
game) never ride along — extend the hit blacklist with `TM_HIT_BLACKLIST`.
|
|
291
339
|
|
|
292
|
-
Seeded allowlist (
|
|
293
|
-
domains, so every sibling subdomain — baike.baidu.com,
|
|
294
|
-
space.bilibili.com — is covered):
|
|
340
|
+
Seeded allowlist (all three web tools; 23 hosts — baidu/moegirl/bilibili are
|
|
341
|
+
PARENT domains, so every sibling subdomain — baike.baidu.com,
|
|
342
|
+
mzh.moegirl.org.cn, space.bilibili.com — is covered):
|
|
295
343
|
`baidu.com`, `moegirl.org.cn`, `bilibili.com`, `www.sogou.com`, `www.so.com`,
|
|
296
344
|
`cn.bing.com`, `www.bing.com`, `zhihu.com`, `juejin.cn`, `csdn.net`,
|
|
297
345
|
`cnblogs.com`, `gitee.com`, `github.com`, `api.github.com`,
|
|
298
346
|
`raw.githubusercontent.com`, `gist.githubusercontent.com`, `ghproxy.net`
|
|
299
|
-
(mainland mirror for github raw), `stackoverflow.com`, `
|
|
300
|
-
|
|
301
|
-
`
|
|
347
|
+
(mainland mirror for github raw), `stackoverflow.com`, `api.stackexchange.com`
|
|
348
|
+
+ `hn.algolia.com` (the two JSON search engines), `npmjs.org`, `pypi.org`,
|
|
349
|
+
`learn.microsoft.com` — extend via
|
|
350
|
+
`TM_WEBFETCH_ALLOWED_DOMAINS` (`"*"` opens every host; a custom list REPLACES
|
|
351
|
+
the seed, so keep the engine hosts or `tm_search` loses its targets). Architect /
|
|
302
352
|
implementer / reviewer have NO network grant — web questions come back as a
|
|
303
353
|
reported gap, never simulated. The tester carries `tm_browser` ONLY, for
|
|
304
354
|
governed UI verification of the project (local dev servers, preview routes);
|
|
@@ -307,7 +357,7 @@ open web fetching stays with the two network roles.
|
|
|
307
357
|
**Out-of-allowlist targets are a gate, not a wall.** When a fetch / search /
|
|
308
358
|
browser-open points at a host outside the allowlist, the tool hands the URL
|
|
309
359
|
to OpenCode's **official confirmation dialog** — you decide, once per
|
|
310
|
-
target (an unanswered dialog is auto-rejected on the usual
|
|
360
|
+
target (an unanswered dialog is auto-rejected on the usual 1-minute timer,
|
|
311
361
|
and the plugin still never self-allows). Every dialog also fires a
|
|
312
362
|
**system toast notification**, so you know something is waiting even when
|
|
313
363
|
you're not staring at the screen. Env-file URLs and non-http(s) schemes
|
|
@@ -319,11 +369,21 @@ remain hard-rejected with no dialog — R6 red lines are never consentable.
|
|
|
319
369
|
environment variables silently. Env reads (`printenv`, `env`, `Get-ChildItem
|
|
320
370
|
env:`, …) and env files (`.env`, shell rc) route through OpenCode's official
|
|
321
371
|
confirmation dialog; unanswered prompts are **auto-rejected after
|
|
322
|
-
`TM_ASK_TIMEOUT_MIN` (default
|
|
372
|
+
`TM_ASK_TIMEOUT_MIN` (default 1 min)**. Env reads no wildcard can express
|
|
323
373
|
(embedded `$VAR` / `${VAR}` / `$env:` inside another command, command
|
|
324
374
|
substitution) and the `tm_*` wrapper channel stay a **hard block** — no dialog
|
|
325
375
|
to slip through. The audit log records only tool name + pattern category +
|
|
326
|
-
verdict — never command text, paths, variable names or values.
|
|
376
|
+
verdict — never command text, paths, variable names or values. Verdicts now
|
|
377
|
+
also explain a dialog that cannot be answered anymore: a reply that hits an
|
|
378
|
+
**already-closed** dialog (host 404 — the timer already auto-rejected) audits
|
|
379
|
+
as `already-closed` without degrading the gate, a plugin-side bad reply shape
|
|
380
|
+
audits as `rejected-shape-bug`, and a user reply that arrives *after* the
|
|
381
|
+
auto-reject is recorded as `late-<verdict>` for observability only (the
|
|
382
|
+
rejection stands — the plugin still never self-allows). The 1-minute auto-reject
|
|
383
|
+
floor is tunable via `TM_ASK_TIMEOUT_FLOOR_MIN`; the short default is safe
|
|
384
|
+
because a reply that races the timer audits as benign `already-closed` (host
|
|
385
|
+
404 on a closed dialog — no gate degrade), and the observed ~120 s is the
|
|
386
|
+
host-to-plugin event-bus *delivery* lag, not click-resolution latency.
|
|
327
387
|
|
|
328
388
|
**R2 dangerous operations (same dialog).** Delete, git publish, network
|
|
329
389
|
fetch, package install/publish, process/system, privilege changes — none are
|
|
@@ -390,24 +450,36 @@ for overrides, extra agents and disabling roles.
|
|
|
390
450
|
| Env var | Default | Purpose |
|
|
391
451
|
|---|---|---|
|
|
392
452
|
| `TM_ENV_PROTECT` | `strict` | R6 mode: `strict` / `standard` / `off` (off also disarms the approval timer) |
|
|
393
|
-
| `TM_ASK_TIMEOUT_MIN` | `
|
|
453
|
+
| `TM_ASK_TIMEOUT_MIN` | `1` | minutes before an unanswered dialog is auto-rejected (floored at 1 min — safe: a racing reply audits as benign `already-closed`; the host's reply event reaching the plugin ~120 s late is event-bus delivery lag, not a click delay) |
|
|
454
|
+
| `TM_ASK_TIMEOUT_FLOOR_MIN` | `1` | minimum enforced for the ask timeout above |
|
|
394
455
|
| `TM_ENV_PROTECT_EXTRA_DENY` | — | extra block patterns (regex; always hard block, never dialog-governed) |
|
|
395
|
-
| `TM_OFFLOAD_THRESHOLD` | `2000` | offload
|
|
456
|
+
| `TM_OFFLOAD_THRESHOLD` | `2000` | global offload fallback (tokens, CJK-aware estimate) — used when the content class is unknown |
|
|
457
|
+
| `TM_OFFLOAD_THRESHOLD_TEXT` | `4000` | offload boundary for prose (text / log / markdown) |
|
|
458
|
+
| `TM_OFFLOAD_THRESHOLD_DATA` | `2000` | offload boundary for structured payloads (json / csv / code / binary) |
|
|
396
459
|
| `TM_PREVIEW_MAX_TOKENS` | `80` | preview hard cap |
|
|
397
460
|
| `TM_FETCH_MAX_LINES` | `2000` | tm_fetch page cap |
|
|
398
461
|
| `TM_BLACKBOARD_DIR` / `TM_TRAJECTORY_DIR` | `<repo>/.git/opencode-team/…` | offload store / trajectory ledger (tmpdir fallback; explicit = absolute or project-relative) |
|
|
399
462
|
| `TM_BLACKBOARD_TTL` | `7` | store retention (days) |
|
|
400
463
|
| `TM_BASH_READONLY_ALLOWED` | built-in table | tm_bash allowlist |
|
|
401
|
-
| `
|
|
464
|
+
| `TM_SEARCH_DEFAULT_ENGINE` | `auto` | tm_search engine when no `engine` arg is given (`auto` = classify + parallel fan-out + RRF fusion; any table name also pins a manual default) |
|
|
465
|
+
| `TM_WEBFETCH_ALLOWED_DOMAINS` | the 23 seeded hosts | tm_webfetch / tm_search / tm_browser allowlist (`"*"` opens all; empty = deny all; a custom list REPLACES the seed — keep the engine hosts) |
|
|
402
466
|
| `TM_BROWSER_PATH` | auto-detect | tm_browser executable override (default: your DEFAULT browser when Chromium-family, else Edge/Chrome probes) |
|
|
403
467
|
| `TM_BROWSER_HEADLESS` | `auto` | `1` headless (CI) / `0` headful / `auto` (headless only on display-less Linux) |
|
|
404
|
-
| `
|
|
468
|
+
| `TM_BROWSER_ENGINE` | `playwright` | `playwright` (needs Node ≥ 20; any import failure auto-degrades) / `cdp-legacy` (zero-dep CDP pipe, core verbs only) |
|
|
469
|
+
| `TM_BROWSER_SNAPSHOT_MAX_TOKENS` | `1200` | hard cap on `take_snapshot` payloads |
|
|
470
|
+
| `TM_BROWSER_USER_DATA_DIR` | — (isolated temp profile) | explicit persistent profile dir — the ONLY way logins survive between sessions |
|
|
471
|
+
| `TM_MEMORY_GLOBAL_DIR` | `~/.opencode-team/memories/global/` | tm_memory GLOBAL tier store |
|
|
472
|
+
| `TM_MEMORY_SESSION_TTL_MIN` | `240` | session-tier entry TTL (lazy + boot sweep) |
|
|
473
|
+
| `TM_MEMORY_MAX_ENTRIES` | `200` | per-scope entry cap; over it `add` fails on purpose — run `compact` |
|
|
474
|
+
| `TM_MEMORY_STALE_DAYS` | `30` | age after which search hits are tagged `[stale Nd]` (`0` disables) |
|
|
475
|
+
| `TM_MEMORY_SESSION_PERSIST` | — (ephemeral) | `1` also writes session entries under `memories/sessions/<sid>/` |
|
|
405
476
|
| `TM_HIT_BLACKLIST` | `maimai.cn` | extra domains never listed as search hits (comma/semicolon separated; same-name-different-site noise like 脉脉) |
|
|
406
477
|
| `TM_PTC_MAX_PROGRAM_CHARS` | `4000` | PTC program source cap |
|
|
407
478
|
| `TM_PTC_MAX_CALLS` | `20` | PTC per-run bridge-call budget (1–200) |
|
|
408
479
|
| `TM_PTC_MAX_ERRORS` | `3` | PTC per-run error budget (1–50) |
|
|
409
480
|
| `TM_PTC_TIMEOUT_MS` | `60000` | PTC per-run wall-clock timeout (5s–10min) |
|
|
410
481
|
| `TM_PTC_ENGINE` | `auto` | `auto` (worker→inline degrade) / `worker` / `inline` |
|
|
482
|
+
| `TM_PTC_WEB_BRIDGE` | `on` | expose `tm.search` / `tm.webfetch` to PTC programs (`off` removes them from the bridge set) |
|
|
411
483
|
|
|
412
484
|
---
|
|
413
485
|
|
|
@@ -427,6 +499,10 @@ not the rule: a deliverable over ~50 lines goes to ONE named board file under
|
|
|
427
499
|
routing bug.
|
|
428
500
|
- **Approval gate (count-based):** ≥2 dispatches → plan (≤30 lines) → **your
|
|
429
501
|
approval** → execute. Blocking questions are batched and asked immediately.
|
|
502
|
+
- **Concurrent dispatch:** independent dispatches batch into the SAME round
|
|
503
|
+
(parallel implementers with per-file ownership + verbatim contracts,
|
|
504
|
+
3-dimension reviews, split test suites); only the Team Lead dispatches —
|
|
505
|
+
specialists no longer hold `task`, so no sub-agent spawns a sub-agent.
|
|
430
506
|
- **Adaptive review:** one reviewer by default; three parallel dimensions
|
|
431
507
|
only for high-risk profiles (auth/security, cross-module contracts, public APIs).
|
|
432
508
|
- **Static verification:** build / typecheck / lint / tests. Improvised
|
|
@@ -506,7 +582,7 @@ the whole workflow are host-agnostic. On display-less Linux, `tm_browser`
|
|
|
506
582
|
runs headless automatically.
|
|
507
583
|
|
|
508
584
|
**What happens if I don't answer a confirmation dialog?**
|
|
509
|
-
It auto-rejects after `TM_ASK_TIMEOUT_MIN` (default
|
|
585
|
+
It auto-rejects after `TM_ASK_TIMEOUT_MIN` (default 1). The plugin never
|
|
510
586
|
self-approves — the only side it can take is yours or nobody's.
|
|
511
587
|
|
|
512
588
|
---
|
package/README.zh-CN.md
CHANGED
|
@@ -43,9 +43,9 @@ TeamMode 对每一个的回应:
|
|
|
43
43
|
|
|
44
44
|
| 痛点 | TeamMode 的回答 |
|
|
45
45
|
|---|---|
|
|
46
|
-
| 🔥 **上下文爆炸** |
|
|
46
|
+
| 🔥 **上下文爆炸** | 所有受治理工具的输出超过内容分档阈值(散文 4000 / 数据 2000 token,CJK 感知)就卸载到本地 run 存储,换成 80 token 的预览 + HMAC 句柄。agent 需要什么再分页取什么——窗口永远淹不了。 |
|
|
47
47
|
| 🐌 **回合开销** | `tm_ptc_run`:agent 写**一个程序**,单回合内发起 N 次受治理调用。运行期间零 LLM 回合。 |
|
|
48
|
-
| 🕳️ **静默副作用** | R6/R2 审批门禁:环境变量读取和危险操作走 OpenCode 官方确认弹窗,
|
|
48
|
+
| 🕳️ **静默副作用** | R6/R2 审批门禁:环境变量读取和危险操作走 OpenCode 官方确认弹窗,1 分钟没人理自动拒绝。插件从不代替你批准——它只会拒绝。 |
|
|
49
49
|
| 🌫️ **幻觉式调研** | 联网是双角色的授权 + 白名单受治理工具链。抓不到的事实就报告为缺口——绝不编造。 |
|
|
50
50
|
|
|
51
51
|
底下还有流程纪律:确定性路由表、≥2 次派工先出 ≤30 行计划等你批、agent
|
|
@@ -196,18 +196,21 @@ team 完成。rateLimit.ts (new) · app.ts (+3) · 14 测试全绿
|
|
|
196
196
|
|
|
197
197
|
## 🧰 受治理的工具与安全
|
|
198
198
|
|
|
199
|
-
TeamMode
|
|
200
|
-
|
|
199
|
+
TeamMode 加的每个工具都跑在**同一条治理管线**下:超过卸载阈值的输出永不
|
|
200
|
+
进入上下文窗口——阈值按内容分档:散文(text/log/markdown)走
|
|
201
|
+
`TM_OFFLOAD_THRESHOLD_TEXT`(4000),结构化数据(json/csv/code/binary)走
|
|
202
|
+
`TM_OFFLOAD_THRESHOLD_DATA`(2000),内容类别未知时回退全局
|
|
203
|
+
`TM_OFFLOAD_THRESHOLD`。超限输出卸载到 run 存储,换成内容感知预览 +
|
|
201
204
|
HMAC 句柄,agent 真需要 payload 时用 `tm_fetch` 分页取。
|
|
202
205
|
|
|
203
206
|
| 工具 | 功能 | 角色 |
|
|
204
207
|
|---|---|---|
|
|
205
|
-
| `tm_read` / `tm_grep` / `tm_bash` / `tm_fetch` | 受治理的文件读 / 正则搜索 / 只读 shell(白名单)/
|
|
206
|
-
| `tm_memory` | 项目 +
|
|
207
|
-
| `tm_ptc_run` | 批量编排:一个程序、N 次受治理调用、零 LLM
|
|
208
|
-
| `tm_search` |
|
|
208
|
+
| `tm_read` / `tm_grep` / `tm_bash` / `tm_fetch` | 受治理的文件读 / 正则搜索 / 只读 shell(白名单)/ 句柄分页(JSON 句柄支持 `fields` 点路径投影——刻意小的 jq 子集,如 `items[].name`) | 全部六个 agent |
|
|
209
|
+
| `tm_memory` | 会话 + 项目 + 全局三层记忆库(Markdown + frontmatter):add / search / list / forget / compact | 全部六个 agent |
|
|
210
|
+
| `tm_ptc_run` | 批量编排:一个程序、N 次受治理调用、零 LLM 回合;联网角色还能在程序里调 `tm.search` / `tm.webfetch` | 全部六个 agent |
|
|
211
|
+
| `tm_search` | 多引擎网络搜索,返回提取、去重、RRF 融合后的命中列表 | Lead + Researcher |
|
|
209
212
|
| `tm_webfetch` | 白名单页面的单次受治理 GET(搜索页自动提取) | Lead + Researcher |
|
|
210
|
-
| `tm_browser` |
|
|
213
|
+
| `tm_browser` | 交互式浏览器会话(**驱动你的默认浏览器**):16 个 Playwright 动词(快照优先:`take_snapshot` → 按 uid 寻址的 `click`/`fill`/`drag`…)+ 5 个旧版兼容动词(open/navigate/read/screenshot/close);Playwright 引擎需 Node ≥ 20,不满足或导入失败时自动降级到旧版 CDP 引擎 | Lead + Researcher + Tester(仅 UI 验证) |
|
|
211
214
|
|
|
212
215
|
> **固定工具优先级阶梯(每个任务都适用):① TeamMode 受治理工具(`tm_*`)
|
|
213
216
|
> → ② 用户 MCP/插件工具 → ③ 模型自己的推理。** 它同时是回退链:某个受治理
|
|
@@ -221,23 +224,37 @@ HMAC 句柄,agent 真需要 payload 时用 `tm_fetch` 分页取。
|
|
|
221
224
|
### 上下文治理:卸载、句柄、预览
|
|
222
225
|
|
|
223
226
|
大的工具输出是上下文成本的主要来源——每一步都要重发整个窗口。所以超过
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
227
|
+
内容分档阈值的(散文 → `TM_OFFLOAD_THRESHOLD_TEXT`,结构化数据 →
|
|
228
|
+
`TM_OFFLOAD_THRESHOLD_DATA`,未知类别 → 全局 `TM_OFFLOAD_THRESHOLD`)
|
|
229
|
+
结果写进本地 run 存储(`<repo>/.git/opencode-team/`,永不污染工作树),
|
|
230
|
+
换成带内容感知预览的句柄:JSON 键 / CSV 表头+形状 / 日志 ERROR×N 统计 /
|
|
231
|
+
代码签名 / 二进制元数据,硬顶 80 token。agent 真需要 payload 时用
|
|
232
|
+
`tm_fetch`(HMAC 签名、run 域、带过期)分页读;JSON 句柄还可以直接要
|
|
233
|
+
`fields` 点路径投影(刻意小的 jq 子集:`items[].name`、
|
|
234
|
+
`[].stargazers_count`),大 API 转储只留需要的字段、原文从不进窗口。
|
|
235
|
+
`tm_bash` 只放行只读命令(白名单),失败以结构化错误返回,不糊原始转储。
|
|
236
|
+
|
|
237
|
+
### 会话 + 项目 + 全局三层记忆(tm_memory)
|
|
231
238
|
|
|
232
239
|
耐久的事实——构建命令、环境怪癖、架构决策、你的约定——以人可编辑的
|
|
233
|
-
Markdown + frontmatter
|
|
234
|
-
|
|
235
|
-
- **`
|
|
236
|
-
- **`
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
240
|
+
Markdown + frontmatter 存放,共三层:
|
|
241
|
+
|
|
242
|
+
- **`session`**:仅本次会话的瞬时事实——进程内、按 TTL 清扫(`TM_MEMORY_SESSION_TTL_MIN`,默认 240 分钟),对其他会话不可见;除非 `TM_MEMORY_SESSION_PERSIST=1` 才落盘到 `memories/sessions/<sid>/`。
|
|
243
|
+
- **`project`**(默认):`<repo>/.git/opencode-team/memories/…` —— 每 checkout 一份,贴近 git。存放本仓库的事实:构建命令、环境怪癖、架构决策。
|
|
244
|
+
- **`global`**:`~/.opencode-team/memories/global/`(可用 `TM_MEMORY_GLOBAL_DIR` 覆盖)——**跟着你走遍所有项目**。存放用户级约定:偏好的包管理器、提交风格、工具习惯。
|
|
245
|
+
|
|
246
|
+
动作:`add` / `search`(确定性关键词打分)/ `list` / `forget` / `compact`;
|
|
247
|
+
每条记忆上限 4000 字符。`search` 走全部三层,**会话 > 项目 > 全局**优先:
|
|
248
|
+
项目条目获得 +2 的近似同分加权,同名上层条目遮蔽下层(永不浮出)。
|
|
249
|
+
近重复从不堆积:`add` 命中同层同分类的既有条目(去重键,或
|
|
250
|
+
title+keywords 的 Jaccard ≥ 0.6)时**并入既有条目**——新内容胜出、
|
|
251
|
+
keywords 取并集、旧 slug 进 `supersedes:`、答复标注"已合并"(这是正常
|
|
252
|
+
现象,别再换个变体标题重复添加)。某层到达 `TM_MEMORY_MAX_ENTRIES`
|
|
253
|
+
(每作用域 200)时 add 故意失败:先跑 `compact`——默认 dry-run 只报合并
|
|
254
|
+
计划,带 `apply:true` 重跑才执行,执行前所有原件先复制进带时间戳的
|
|
255
|
+
`.compact-backup` 树(回滚路径)。超过 `TM_MEMORY_STALE_DAYS`(30 天)的
|
|
256
|
+
条目在搜索结果里标 `[stale Nd]`。agent 被要求先搜记忆再做项目假设,
|
|
257
|
+
也把来之不易的事实存下来留给下个会话。
|
|
241
258
|
|
|
242
259
|
### 🌐 真正好用的网络搜索(中国可用)
|
|
243
260
|
|
|
@@ -247,17 +264,20 @@ agent 永远看不到原始搜索页的噪音。
|
|
|
247
264
|
|
|
248
265
|
| 引擎 | 说明 |
|
|
249
266
|
|---|---|
|
|
250
|
-
| `
|
|
251
|
-
| `
|
|
252
|
-
| `
|
|
267
|
+
| `auto`(默认) | 给查询分类,**并行**扇出 2–3 个引擎,按 host+path 去重后做加权 RRF 融合(stackoverflow/bing 0.4,其余 0.2),产出标有来源引擎的 top-10 列表。路由:报错/camelCase API → `stackoverflow`+`github`+`bing`;开发生态(发布、框架、开源)→ `hn`+`github`+`npm`;中文/通用 → `bing`。用 `TM_SEARCH_DEFAULT_ENGINE` 钉别的默认 |
|
|
268
|
+
| `bing` | cn.bing.com——唯一活着的中文 HTML SERP;多词 CJK 查询自动保护短语边界(加引号),markup 洗牌拆不散结果列表 |
|
|
269
|
+
| `stackoverflow` | api.stackexchange.com 问题搜索(免 Key,300 次/天/IP)→ 带复合摘要的编号问题列表;`auto` 跟踪配额,耗尽自动换 `bing` 顶上 |
|
|
270
|
+
| `hn` | Hacker News(Algolia API,免 Key)→ 帖子标题 + 摘要与原文链接 |
|
|
253
271
|
| `bilibili` | 视频搜索 |
|
|
254
272
|
| `moegirl` | MediaWiki 搜索 API——词条标题 + 摘要,结构化 |
|
|
255
273
|
| `npm` | registry 搜索 → name@version + 描述,结构化 |
|
|
256
|
-
| `github` | 仓库搜索 API → star 数 +
|
|
274
|
+
| `github` | 仓库搜索 API → star 数 + 描述,结构化;`org:` / `user:` / `stars:` / `language:` 限定符透传折进查询(如 `vector db stars:>500 language:rust`) |
|
|
257
275
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
276
|
+
七个引擎在中国大陆**全部免 Key 可达**,且全部在种子域名白名单内。旧的
|
|
277
|
+
中文 HTML SERP(`sogou` / `so` / `baidu` / `bing-int`)已被**移除**——
|
|
278
|
+
实测定标(2026-09-14)显示它们只返回反爬壳或 100% 空结果,连手动选择
|
|
279
|
+
都不再提供。空结果时错误信息会点名替代引擎,不让 agent 卡死。另两条
|
|
280
|
+
通道补全能力面:
|
|
261
281
|
|
|
262
282
|
- `tm_webfetch` —— 已知 URL,单次受治理 GET。它抓到的搜索引擎页面同样
|
|
263
283
|
自动提取为命中列表。`registry.npmjs.org/<pkg>/latest` 这类 JSON 端点
|
|
@@ -265,9 +285,23 @@ agent 永远看不到原始搜索页的噪音。
|
|
|
265
285
|
- `tm_browser` —— JS 渲染页:**驱动你的默认浏览器**(Windows 读注册表 /
|
|
266
286
|
Linux 读 xdg-settings;仅限 Chromium 系——默认是 Firefox 时回退到
|
|
267
287
|
Edge/Chrome 探测顺序,因为 CDP 是 Chromium 专有协议;`TM_BROWSER_PATH`
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
`
|
|
288
|
+
可强制指定),默认有头运行,隔离临时 profile,**域名白名单在网络层
|
|
289
|
+
逐请求、逐重定向跳强制**。动作面与 chrome-devtools-mcp 对齐:**16 个
|
|
290
|
+
Playwright 动词**(`navigate_page` · `take_snapshot` · `click` · `fill` ·
|
|
291
|
+
`hover` · `drag` · `press_key` · `select_page` · `upload_file` · `wait_for`
|
|
292
|
+
· `evaluate_script` · `list_console_messages` · `list_network_requests` ·
|
|
293
|
+
`list_pages` · `take_screenshot` · `handle_dialog`)+ 5 个旧版兼容动词
|
|
294
|
+
(`open` / `navigate` / `read` / `screenshot` / `close`)。快照优先:
|
|
295
|
+
`take_snapshot` 返回注入了 `[uid=eN]` 标记的 aria 快照,后续动作按 uid
|
|
296
|
+
寻址节点而不是猜定位器;快照受
|
|
297
|
+
`TM_BROWSER_SNAPSHOT_MAX_TOKENS`(默认 1200)硬顶。
|
|
298
|
+
**引擎分工:** 主引擎是 `playwright-core`(optionalDependencies——
|
|
299
|
+
需 **Node ≥ 20**;旧版 Node 或导入失败时,整个插件实例自动降级到零依赖
|
|
300
|
+
`cdp-legacy` 引擎,只保留核心动词;可用 `TM_BROWSER_ENGINE=playwright|cdp-legacy`
|
|
301
|
+
钉死)。从不下载浏览器——Playwright 按路径启动**你自己装的**浏览器,
|
|
302
|
+
`npx playwright install` 不属于用户流程(依赖本体在 npm
|
|
303
|
+
install/发布时解析)。默认隔离临时 profile:登录态想跨会话保留,只有
|
|
304
|
+
显式设置 `TM_BROWSER_USER_DATA_DIR` 这一条路。
|
|
271
305
|
|
|
272
306
|
**伪装浏览器请求头后仍收到 403** 时,错误信息是一条指令:该站点的门槛是
|
|
273
307
|
JS 挑战 / TLS 指纹级别,只有真实浏览器能过——会直接让 agent 调 `tm_browser`
|
|
@@ -276,22 +310,24 @@ JS 挑战 / TLS 指纹级别,只有真实浏览器能过——会直接让 age
|
|
|
276
310
|
(`maimai.cn` 脉脉 ≠ maimai DX 游戏)不会混入命中列表——用
|
|
277
311
|
`TM_HIT_BLACKLIST` 可扩展命中黑名单。
|
|
278
312
|
|
|
279
|
-
|
|
313
|
+
种子白名单(三个联网工具共用,23 个主机;baidu/moegirl/bilibili 用的是父域,
|
|
280
314
|
所有兄弟子域——baike.baidu.com、mzh.moegirl.org.cn、space.bilibili.com——
|
|
281
315
|
一并覆盖):`baidu.com`、`moegirl.org.cn`、`bilibili.com`、`www.sogou.com`、
|
|
282
316
|
`www.so.com`、`cn.bing.com`、`www.bing.com`、`zhihu.com`、`juejin.cn`、
|
|
283
317
|
`csdn.net`、`cnblogs.com`、`gitee.com`、`github.com`、`api.github.com`、
|
|
284
318
|
`raw.githubusercontent.com`、`gist.githubusercontent.com`、`ghproxy.net`
|
|
285
|
-
(github raw 的大陆镜像)、`stackoverflow.com`、`
|
|
319
|
+
(github raw 的大陆镜像)、`stackoverflow.com`、`api.stackexchange.com`
|
|
320
|
+
+ `hn.algolia.com`(两个 JSON 搜索引擎)、`npmjs.org`、`pypi.org`、
|
|
286
321
|
`learn.microsoft.com`——用
|
|
287
|
-
`TM_WEBFETCH_ALLOWED_DOMAINS` 扩展(`"*"`
|
|
322
|
+
`TM_WEBFETCH_ALLOWED_DOMAINS` 扩展(`"*"` 放开全部主机;自定义列表是
|
|
323
|
+
**替换**种子,保留引擎主机否则 `tm_search` 没了目标)。architect /
|
|
288
324
|
implementer / reviewer **没有**联网授权——网络问题会报告为缺口,绝不编造。
|
|
289
325
|
tester 仅持有 `tm_browser`,用于本项目的治理化 UI 验证(本地开发服务器、
|
|
290
326
|
预览路由);开放网络抓取仍归两个联网角色。
|
|
291
327
|
|
|
292
328
|
**白名单外是门,不是墙。** 当抓取 / 搜索 / 浏览器打开的目标主机不在白名单
|
|
293
329
|
内时,工具会把 URL 交给 OpenCode 的**官方确认弹窗**——由你裁决,每次一个
|
|
294
|
-
目标(无人应答照常走
|
|
330
|
+
目标(无人应答照常走 1 分钟自动拒绝,插件依旧绝不代你批准)。每个弹窗
|
|
295
331
|
同时触发一条**系统 toast 通知**,即使你没盯着屏幕也知道有待批准的操作。
|
|
296
332
|
env 文件 URL 和非 http(s) 协议保持硬拦截、无弹窗——R6 红线不可被"同意"。
|
|
297
333
|
|
|
@@ -300,10 +336,17 @@ env 文件 URL 和非 http(s) 协议保持硬拦截、无弹窗——R6 红线
|
|
|
300
336
|
**R6 环境变量保护。** TeamMode 激活时,模型不能悄悄读环境变量。env 读取
|
|
301
337
|
(`printenv`、`env`、`Get-ChildItem env:` 等)和 env 文件(`.env`、shell rc)
|
|
302
338
|
走 OpenCode **官方确认弹窗**;没人应答的弹窗在 `TM_ASK_TIMEOUT_MIN`(默认
|
|
303
|
-
|
|
339
|
+
1 分钟)后**自动拒绝**。通配符表达不了的 env 读取(命令内嵌 `$VAR` /
|
|
304
340
|
`${VAR}` / `$env:`、命令替换)和 `tm_*` 包装通道保持**硬拦截**——没有弹窗
|
|
305
341
|
可钻。审计日志只记录工具名 + 模式类别 + 裁决——绝不记录命令文本、路径、
|
|
306
|
-
|
|
342
|
+
变量名或值。裁决现在还解释"弹窗已无法应答"的情形:应答打到**已关闭**的
|
|
343
|
+
弹窗(宿主 404——计时器早已自动拒绝)记为 `already-closed`、不触发降级;
|
|
344
|
+
插件侧应答形状错误记为 `rejected-shape-bug`;用户在自动拒绝**之后**才到的
|
|
345
|
+
回复记为 `late-<verdict>`(仅可观测——拒绝已成事实,插件依旧绝不代你批准)。
|
|
346
|
+
自动拒绝的地板为 1 分钟,可用 `TM_ASK_TIMEOUT_FLOOR_MIN` 调节。短默认值是安全
|
|
347
|
+
的:抢在计时器之后的应答会良性记为 `already-closed`(宿主对已关闭弹窗返回
|
|
348
|
+
404——不触发门禁降级),实测约 120 秒的滞后是宿主→插件事件总线的**投递**
|
|
349
|
+
延迟,并非点击解析延迟。
|
|
307
350
|
|
|
308
351
|
**R2 危险操作(同一个弹窗)。** 删除、git 发布、网络抓取、包安装/发布、
|
|
309
352
|
进程/系统、提权——统统不允许静默放行。日常验证栈(`npm test`、`tsc`、
|
|
@@ -363,24 +406,36 @@ Team Lead 自己从不删黑板,你可以随时审计任何一次运行。
|
|
|
363
406
|
| 环境变量 | 默认 | 用途 |
|
|
364
407
|
|---|---|---|
|
|
365
408
|
| `TM_ENV_PROTECT` | `strict` | R6 模式:`strict` / `standard` / `off`(off 同时解除审批计时器) |
|
|
366
|
-
| `TM_ASK_TIMEOUT_MIN` | `
|
|
409
|
+
| `TM_ASK_TIMEOUT_MIN` | `1` | 无人应答弹窗自动拒绝前等待的分钟数(地板 1 分钟——安全:抢跑应答良性记为 `already-closed`;宿主应答事件到插件晚约 120 秒是事件总线投递延迟,非点击解析延迟) |
|
|
410
|
+
| `TM_ASK_TIMEOUT_FLOOR_MIN` | `1` | 上述自动拒绝的强制最小时长 |
|
|
367
411
|
| `TM_ENV_PROTECT_EXTRA_DENY` | — | 额外拦截模式(正则;永远硬拦截,不走弹窗) |
|
|
368
|
-
| `TM_OFFLOAD_THRESHOLD` | `2000` |
|
|
412
|
+
| `TM_OFFLOAD_THRESHOLD` | `2000` | 全局卸载兜底阈值(token,CJK 感知估算)——内容类别未知时使用 |
|
|
413
|
+
| `TM_OFFLOAD_THRESHOLD_TEXT` | `4000` | 散文类(text / log / markdown)卸载阈值 |
|
|
414
|
+
| `TM_OFFLOAD_THRESHOLD_DATA` | `2000` | 结构化载荷(json / csv / code / binary)卸载阈值 |
|
|
369
415
|
| `TM_PREVIEW_MAX_TOKENS` | `80` | 预览硬顶 |
|
|
370
416
|
| `TM_FETCH_MAX_LINES` | `2000` | tm_fetch 单页行数上限 |
|
|
371
417
|
| `TM_BLACKBOARD_DIR` / `TM_TRAJECTORY_DIR` | `<repo>/.git/opencode-team/…` | 卸载存储 / 轨迹账本(tmpdir 回退;显式值 = 绝对或项目相对) |
|
|
372
418
|
| `TM_BLACKBOARD_TTL` | `7` | 存储保留天数 |
|
|
373
419
|
| `TM_BASH_READONLY_ALLOWED` | 内置表 | tm_bash 白名单 |
|
|
374
|
-
| `
|
|
420
|
+
| `TM_SEARCH_DEFAULT_ENGINE` | `auto` | tm_search 未显式给 `engine` 时的默认引擎(`auto` = 分类 + 并行扇出 + RRF 融合;也可钉表中任一引擎) |
|
|
421
|
+
| `TM_WEBFETCH_ALLOWED_DOMAINS` | 23 个种子主机 | tm_webfetch / tm_search / tm_browser 白名单(`"*"` 全开;空 = 全拒;自定义值**替换**种子——保留引擎主机) |
|
|
375
422
|
| `TM_BROWSER_PATH` | 自动探测 | tm_browser 可执行文件覆盖(默认用你的默认浏览器——Chromium 系时;否则回退 Edge/Chrome 探测) |
|
|
376
423
|
| `TM_BROWSER_HEADLESS` | `auto` | `1` 无头(CI)/ `0` 有头 / `auto`(仅无显示的 Linux 用无头) |
|
|
377
|
-
| `
|
|
424
|
+
| `TM_BROWSER_ENGINE` | `playwright` | `playwright`(需 Node ≥ 20;导入失败自动降级)/ `cdp-legacy`(零依赖 CDP pipe,仅核心动词) |
|
|
425
|
+
| `TM_BROWSER_SNAPSHOT_MAX_TOKENS` | `1200` | `take_snapshot` 载荷硬顶 |
|
|
426
|
+
| `TM_BROWSER_USER_DATA_DIR` | —(隔离临时 profile) | 显式持久 profile 目录——登录态跨会话保留的唯一途径 |
|
|
427
|
+
| `TM_MEMORY_GLOBAL_DIR` | `~/.opencode-team/memories/global/` | tm_memory GLOBAL 层存储 |
|
|
428
|
+
| `TM_MEMORY_SESSION_TTL_MIN` | `240` | session 层条目 TTL(惰性 + 启动清扫) |
|
|
429
|
+
| `TM_MEMORY_MAX_ENTRIES` | `200` | 每作用域条目上限;超限 add 故意失败——先跑 `compact` |
|
|
430
|
+
| `TM_MEMORY_STALE_DAYS` | `30` | 超过此天数的条目在搜索结果标 `[stale Nd]`(`0` 关闭) |
|
|
431
|
+
| `TM_MEMORY_SESSION_PERSIST` | —(瞬态) | `1` 时 session 条目同时落盘 `memories/sessions/<sid>/` |
|
|
378
432
|
| `TM_HIT_BLACKLIST` | `maimai.cn` | 永不进入搜索命中列表的额外域名(逗号/分号分隔;过滤同名不同站噪音) |
|
|
379
433
|
| `TM_PTC_MAX_PROGRAM_CHARS` | `4000` | PTC 程序源码上限 |
|
|
380
434
|
| `TM_PTC_MAX_CALLS` | `20` | PTC 单次运行桥接调用预算(1–200) |
|
|
381
435
|
| `TM_PTC_MAX_ERRORS` | `3` | PTC 单次运行错误预算(1–50) |
|
|
382
436
|
| `TM_PTC_TIMEOUT_MS` | `60000` | PTC 单次运行墙钟超时(5s–10min) |
|
|
383
437
|
| `TM_PTC_ENGINE` | `auto` | `auto`(worker→inline 降级)/ `worker` / `inline` |
|
|
438
|
+
| `TM_PTC_WEB_BRIDGE` | `on` | 向 PTC 程序暴露 `tm.search` / `tm.webfetch`(`off` 从桥接集移除) |
|
|
384
439
|
|
|
385
440
|
---
|
|
386
441
|
|
|
@@ -398,6 +453,9 @@ Team Lead 自己从不删黑板,你可以随时审计任何一次运行。
|
|
|
398
453
|
路由低于 3 次派工就是路由 bug。
|
|
399
454
|
- **审批门禁(计数式):** ≥2 次派工 → 计划(≤30 行)→ **等你批准** → 执行。
|
|
400
455
|
阻塞性问题立刻批量问,不猜、不挤牙膏。
|
|
456
|
+
- **并发派工:** 互相独立的派工批进**同一轮**并行执行(多 implementer 各带
|
|
457
|
+
文件所有权 + 原文数据契约、三维度评审、分包 tester 同时跑);派工权 Team
|
|
458
|
+
Lead 独有——专家角色已收回 `task`,子代理不再生子代理。
|
|
401
459
|
- **自适应评审:** 默认一名评审;高风险画像(鉴权/安全面、跨模块契约、
|
|
402
460
|
公共 API)才三维度并行。
|
|
403
461
|
- **静态验证:** 构建 / 类型检查 / lint / 测试。禁止临时起意的浏览器自动化;
|
|
@@ -470,7 +528,7 @@ OpenCode 按 spec 字符串缓存插件,从不重新解析 `@latest`(上游
|
|
|
470
528
|
宿主无关。无显示的 Linux 上 `tm_browser` 自动转无头。
|
|
471
529
|
|
|
472
530
|
**确认弹窗我不理会会怎样?**
|
|
473
|
-
`TM_ASK_TIMEOUT_MIN`(默认
|
|
531
|
+
`TM_ASK_TIMEOUT_MIN`(默认 1 分钟)后自动拒绝。插件从不自我批准——它
|
|
474
532
|
能站的队只有"你"或者"没人"。
|
|
475
533
|
|
|
476
534
|
---
|
package/dist/agents.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAmB,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAmB,MAAM,YAAY,CAAA;AAqR9D,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAO9C,CAAA"}
|