@te-river/opencode-team-mode 1.6.0 → 1.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/README.md +80 -15
  2. package/README.zh-CN.md +67 -18
  3. package/dist/host/note.d.ts +7 -0
  4. package/dist/host/note.d.ts.map +1 -0
  5. package/dist/host/note.js +31 -0
  6. package/dist/host/note.js.map +1 -0
  7. package/dist/host/v1.d.ts +14 -0
  8. package/dist/host/v1.d.ts.map +1 -0
  9. package/dist/host/v1.js +340 -0
  10. package/dist/host/v1.js.map +1 -0
  11. package/dist/host/v2-browser-gate.d.ts +45 -0
  12. package/dist/host/v2-browser-gate.d.ts.map +1 -0
  13. package/dist/host/v2-browser-gate.js +319 -0
  14. package/dist/host/v2-browser-gate.js.map +1 -0
  15. package/dist/host/v2-capabilities.d.ts +78 -0
  16. package/dist/host/v2-capabilities.d.ts.map +1 -0
  17. package/dist/host/v2-capabilities.js +173 -0
  18. package/dist/host/v2-capabilities.js.map +1 -0
  19. package/dist/host/v2-client.d.ts +53 -0
  20. package/dist/host/v2-client.d.ts.map +1 -0
  21. package/dist/host/v2-client.js +193 -0
  22. package/dist/host/v2-client.js.map +1 -0
  23. package/dist/host/v2-events.d.ts +56 -0
  24. package/dist/host/v2-events.d.ts.map +1 -0
  25. package/dist/host/v2-events.js +158 -0
  26. package/dist/host/v2-events.js.map +1 -0
  27. package/dist/host/v2-guard.d.ts +101 -0
  28. package/dist/host/v2-guard.d.ts.map +1 -0
  29. package/dist/host/v2-guard.js +199 -0
  30. package/dist/host/v2-guard.js.map +1 -0
  31. package/dist/host/v2-offload.d.ts +148 -0
  32. package/dist/host/v2-offload.d.ts.map +1 -0
  33. package/dist/host/v2-offload.js +288 -0
  34. package/dist/host/v2-offload.js.map +1 -0
  35. package/dist/host/v2-permissions.d.ts +123 -0
  36. package/dist/host/v2-permissions.d.ts.map +1 -0
  37. package/dist/host/v2-permissions.js +190 -0
  38. package/dist/host/v2-permissions.js.map +1 -0
  39. package/dist/host/v2-probe.d.ts +85 -0
  40. package/dist/host/v2-probe.d.ts.map +1 -0
  41. package/dist/host/v2-probe.js +268 -0
  42. package/dist/host/v2-probe.js.map +1 -0
  43. package/dist/host/v2-scope.d.ts +51 -0
  44. package/dist/host/v2-scope.d.ts.map +1 -0
  45. package/dist/host/v2-scope.js +58 -0
  46. package/dist/host/v2-scope.js.map +1 -0
  47. package/dist/host/v2-session-client.d.ts +105 -0
  48. package/dist/host/v2-session-client.d.ts.map +1 -0
  49. package/dist/host/v2-session-client.js +390 -0
  50. package/dist/host/v2-session-client.js.map +1 -0
  51. package/dist/host/v2-session.d.ts +85 -0
  52. package/dist/host/v2-session.d.ts.map +1 -0
  53. package/dist/host/v2-session.js +171 -0
  54. package/dist/host/v2-session.js.map +1 -0
  55. package/dist/host/v2-subagent.d.ts +157 -0
  56. package/dist/host/v2-subagent.d.ts.map +1 -0
  57. package/dist/host/v2-subagent.js +286 -0
  58. package/dist/host/v2-subagent.js.map +1 -0
  59. package/dist/host/v2-tool.d.ts +67 -0
  60. package/dist/host/v2-tool.d.ts.map +1 -0
  61. package/dist/host/v2-tool.js +209 -0
  62. package/dist/host/v2-tool.js.map +1 -0
  63. package/dist/host/v2-transcript.d.ts +73 -0
  64. package/dist/host/v2-transcript.d.ts.map +1 -0
  65. package/dist/host/v2-transcript.js +151 -0
  66. package/dist/host/v2-transcript.js.map +1 -0
  67. package/dist/host/v2-types.d.ts +229 -0
  68. package/dist/host/v2-types.d.ts.map +1 -0
  69. package/dist/host/v2-types.js +17 -0
  70. package/dist/host/v2-types.js.map +1 -0
  71. package/dist/host/v2.d.ts +42 -0
  72. package/dist/host/v2.d.ts.map +1 -0
  73. package/dist/host/v2.js +853 -0
  74. package/dist/host/v2.js.map +1 -0
  75. package/dist/index.d.ts +23 -17
  76. package/dist/index.d.ts.map +1 -1
  77. package/dist/index.js +29 -366
  78. package/dist/index.js.map +1 -1
  79. package/dist/prompts/lead.d.ts +1 -1
  80. package/dist/prompts/lead.d.ts.map +1 -1
  81. package/dist/prompts/lead.js +456 -426
  82. package/dist/prompts/lead.js.map +1 -1
  83. package/dist/prompts/shared.d.ts +2 -2
  84. package/dist/prompts/shared.d.ts.map +1 -1
  85. package/dist/prompts/shared.js +38 -11
  86. package/dist/prompts/shared.js.map +1 -1
  87. package/dist/prompts/specialists.d.ts +2 -2
  88. package/dist/prompts/specialists.d.ts.map +1 -1
  89. package/dist/prompts/specialists.js +7 -6
  90. package/dist/prompts/specialists.js.map +1 -1
  91. package/dist/task-offload.d.ts +16 -0
  92. package/dist/task-offload.d.ts.map +1 -1
  93. package/dist/task-offload.js +51 -0
  94. package/dist/task-offload.js.map +1 -1
  95. package/dist/tm/browser.d.ts.map +1 -1
  96. package/dist/tm/browser.js +41 -10
  97. package/dist/tm/browser.js.map +1 -1
  98. package/dist/tm/dispatch.d.ts +86 -1
  99. package/dist/tm/dispatch.d.ts.map +1 -1
  100. package/dist/tm/dispatch.js +360 -39
  101. package/dist/tm/dispatch.js.map +1 -1
  102. package/dist/tm/dupe-guard.d.ts +16 -3
  103. package/dist/tm/dupe-guard.d.ts.map +1 -1
  104. package/dist/tm/dupe-guard.js +27 -7
  105. package/dist/tm/dupe-guard.js.map +1 -1
  106. package/dist/tm/index.d.ts +40 -1
  107. package/dist/tm/index.d.ts.map +1 -1
  108. package/dist/tm/index.js +40 -11
  109. package/dist/tm/index.js.map +1 -1
  110. package/dist/tm/ledger.d.ts +114 -0
  111. package/dist/tm/ledger.d.ts.map +1 -0
  112. package/dist/tm/ledger.js +308 -0
  113. package/dist/tm/ledger.js.map +1 -0
  114. package/dist/tm/perm-ask.d.ts +1 -3
  115. package/dist/tm/perm-ask.d.ts.map +1 -1
  116. package/dist/tm/perm-ask.js +10 -1
  117. package/dist/tm/perm-ask.js.map +1 -1
  118. package/dist/tm/preview.d.ts +55 -0
  119. package/dist/tm/preview.d.ts.map +1 -1
  120. package/dist/tm/preview.js +225 -0
  121. package/dist/tm/preview.js.map +1 -1
  122. package/dist/tm/search.d.ts.map +1 -1
  123. package/dist/tm/search.js +40 -10
  124. package/dist/tm/search.js.map +1 -1
  125. package/dist/tm/serp-loop.d.ts +45 -0
  126. package/dist/tm/serp-loop.d.ts.map +1 -0
  127. package/dist/tm/serp-loop.js +80 -0
  128. package/dist/tm/serp-loop.js.map +1 -0
  129. package/dist/tm/stats.d.ts +29 -0
  130. package/dist/tm/stats.d.ts.map +1 -1
  131. package/dist/tm/stats.js +278 -4
  132. package/dist/tm/stats.js.map +1 -1
  133. package/dist/tm/webfetch.d.ts +4 -0
  134. package/dist/tm/webfetch.d.ts.map +1 -1
  135. package/dist/tm/webfetch.js +75 -8
  136. package/dist/tm/webfetch.js.map +1 -1
  137. package/docs/installation-v2.md +445 -0
  138. package/docs/installation.md +12 -0
  139. package/docs/research/agent-data-exchange.md +117 -0
  140. package/docs/research/browser-pane.md +89 -0
  141. package/docs/research/host-http-api.md +132 -0
  142. package/docs/research/host-subagent-injection.md +187 -0
  143. package/docs/research/plugin-loader-contract.md +261 -0
  144. package/docs/research/v2-builtin-tools.md +447 -0
  145. package/docs/v2-port-notes.md +413 -0
  146. package/index.js +7 -0
  147. package/package.json +64 -61
  148. package/scripts/gen-v2-config.mjs +304 -0
  149. package/scripts/lib/config-surgery.cjs +239 -0
  150. package/scripts/lib/fake-ctx.mjs +169 -0
@@ -0,0 +1,445 @@
1
+ # TeamMode on OpenCode 2.x — Installation / 安装指南(v2 专用)
2
+
3
+ > **Read this page instead of `installation.md` if your host is OpenCode 2.x.**
4
+ > The two generations are not variants of one install: a 2.x plugin **cannot create
5
+ > an agent**, so the six Team roles and the six `/team-*` commands reach the host as
6
+ > **config files** this package generates, and several v1 mechanisms have no v2
7
+ > equivalent at all. `installation.md` describes the 1.18.x path and stays correct
8
+ > there.
9
+ >
10
+ > 如果你的宿主是 OpenCode 2.x,请看本页而不是 `installation.md`:2.x 的插件**不能创建
11
+ > agent**,六个角色和六条 `/team-*` 命令是以**配置文件**的形式由本包生成出去的;v1 的几处
12
+ > 机制在 v2 上根本没有对应物。`installation.md` 讲的是 1.18.x,那份仍然是对的。
13
+
14
+ Find out which one you are on / 先确认你在哪一代:
15
+
16
+ ```bash
17
+ opencode --version # 1.18.x → installation.md ; 2.x → this page
18
+ ```
19
+
20
+ ---
21
+
22
+ ## Part A — English
23
+
24
+ ### One command, or the steps below
25
+
26
+ `scripts/install.sh` / `scripts\install.ps1` now detect the host major version and run
27
+ all three steps of this page on 2.x (plugin entry → generate roles and commands →
28
+ `default_agent` last, with a read-back from disk). Two things are said rather than
29
+ implied:
30
+
31
+ - the version probe also asks the **desktop app** (`resources/opencode-cli.version`,
32
+ then the bundled `opencode-cli.exe --version`), because the desktop install does not
33
+ put `opencode` on `PATH` — on such a machine a PATH-only probe answers "not found"
34
+ while 2.0.16 is running;
35
+ - this v2 branch **has been exercised end to end on a live 2.0.18 host** with `HOME` and
36
+ `USERPROFILE` redirected (both front-ends): exactly one `loading plugin` line for Team, no load
37
+ failure, `v2-boot tools_registered:9`, a foreign plugin entry left intact in each config file,
38
+ and the legacy `.json` still strict-parseable afterwards. Running it — not reading it — found
39
+ and fixed two defects: `ours()` did not recognise a working-tree path spelling (so the next run
40
+ would have added a SECOND entry, the double load this function exists to prevent), and
41
+ PowerShell's `Copy-Item <src>\* <dst>` threw mid-copy when the destination did not exist yet,
42
+ leaving a half-copied package. The manual steps below are still the documented fallback: if the
43
+ installer's v2 branch misbehaves on YOUR host, follow them and report which step said what.
44
+
45
+ ### What is different on 2.x (read this before the steps)
46
+
47
+ | | OpenCode 1.18.x | OpenCode 2.x |
48
+ |---|---|---|
49
+ | The six roles | injected by the plugin at boot | `~/.config/opencode/agents/*.md`, written by the generator below — a plugin cannot add an agent |
50
+ | The six `/team-*` commands | injected by the plugin | `~/.config/opencode/commands/*.md`, same generator |
51
+ | Default agent | filled only if the user left it alone | **Team is the default on every boot** (the API has no getter), plus `default_agent: "team"` in config, which is the checkable one. Opt out with `"team-mode": { "defaultAgent": false }` |
52
+ | Non-blocking commands | `tm_pty`, on the host's own terminal sessions | **not registered at all** — the v2 plugin context has no pty domain, so the tool could only ever report its own missing seam. Run a slow step as its own `shell` call (one per call, each with its own `timeout`) and tee the output to a log you can read back |
53
+ | File access | `tm_read` / `tm_grep` / `tm_bash` | the host's own `read` / `grep` / `glob` / `shell` — **governed anyway**: oversized results are offloaded through `tool.execute.after`, and out-of-project paths go through the host's own `external_directory` permission (a dialog, where v1 had a hard refusal) |
54
+ | Batch calls | `tm_ptc_run` | the host's own `execute` (Code Mode) |
55
+ | Interactive browsing | `tm_browser` (our own playwright/CDP browser) | **the host's own `browser_*` tools first** — they are the only browser the desktop renders in its side panel (`docs/research/browser-pane.md`). `tm_browser` stays registered as the fallback for a host with no desktop browser (CLI / standalone), and the host catalog is policed by `src/host/v2-browser-gate.ts` (URL / address red line / env-file path at `execute.before`, with a leak-detected fallback that replaces the page with the refusal). Snapshots are capped, not offloaded, so every `[ref=…]` the next click needs stays in context |
56
+ | Sub-agent settlement | the host `event` hook | `ctx.event.subscribe()` — zero-dependency async iterable, filtered by event-type name (`src/host/v2-events.ts`). Without it `tm_join` cannot tell a settled child from a running one; `tm_stats` reports what the feed forwarded and which type names went unrecognised (names only, never payloads) |
57
+ | The task ledger | the host's `todowrite` | **`tm_ledger`**, stored in the host's `ctx.storage` (v2 has no `todowrite`) |
58
+ | Asking the user | the host's official per-request dialog | **a plugin cannot open a dialog on v2.** Governed calls that would have asked instead **fail closed** with a refusal that says why. The dialogs you do see are raised by the host itself (permission rules, out-of-project access) |
59
+ | Web access | a 22-host allowlist + the confirm dialog | **the domain gate is off** (`TM_WEBFETCH_ALLOWED_DOMAINS` defaults to `"*"`): a 2.x plugin cannot raise a dialog, so "approve to proceed" was an instruction to wait for a window that never opens. Address classes are still policed — cloud-metadata / link-local / reserved ranges are refused under every setting, and private space (loopback, RFC1918, CGNAT, `.localhost`) is refused too, but the refusal now names both exits instead of promising a click: `TM_PRIVATE_SPACE=allow` (opens the class) or that one hostname in `TM_WEBFETCH_ALLOWED_DOMAINS` (opens exactly it) |
60
+ | Sub-agents | needs `OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=true` | native; the plugin forces `background: true` on every `subagent` call, so **do not set that env var for 2.x** (it is a v1 workaround and changes nothing here) |
61
+ | Effect on your other modes | the plugin's hooks are global | **none.** Every hook checks the session's owner first, so `build`, `plan` and any agent you installed yourself stay exactly as a fresh OpenCode leaves them — no tool is deleted from their requests, no temperature is set, nothing is offloaded, no permission is tightened, no dispatch is converted to background |
62
+
63
+ ### Prerequisite
64
+
65
+ OpenCode 2.x (desktop or CLI) and Node.js on PATH (the plugin runs on the host's own
66
+ runtime; Node 20+ additionally enables the Playwright browser engine).
67
+
68
+ ### Step 1 — Install the plugin
69
+
70
+ The key is **`plugins`** (plural), and one line in it is the whole plugin install: the
71
+ host resolves the entry and **installs the package itself at startup**. There is nothing
72
+ to `npm install` first, no plugin cache to purge, and `opencode plugin add` is not a
73
+ prerequisite — it is a convenience that writes this same key (into `opencode.json`, which
74
+ is why you may see the entry appear there).
75
+
76
+ ```jsonc
77
+ // ~/.config/opencode/opencode.jsonc
78
+ { "plugins": ["@te-river/opencode-team-mode@latest"] }
79
+ ```
80
+
81
+ Two facts about that file, both measured on 2.0.16 / 2.0.18 and both easy to get wrong
82
+ from 1.18.x habits (`docs/research/plugin-loader-contract.md` has the host's own code):
83
+
84
+ - `opencode.json` and `opencode.jsonc` are **both parsed and merged**. The 1.18.x rule
85
+ "jsonc overrides json" is false on 2.x, and acting on it — copying the old file forward
86
+ — puts the same plugin in both, which **loads it twice** (two personalities, the same
87
+ tools and hooks bound twice) with no warning.
88
+ - The host's dedupe matches only an **identical string**. `@te-river/…@latest` in one file
89
+ and `./vendor/team-mode` in the other is two entries, not one plugin.
90
+
91
+ A **local directory** is the other legal spelling, and the one a development tree needs:
92
+
93
+ ```jsonc
94
+ { "plugins": ["./vendor/team-mode"] } // relative to this file, or an absolute dir
95
+ ```
96
+
97
+ The directory **must contain a root `index.js`**. The host resolves a directory as
98
+ `<dir>/index` and nothing else — a `package.json#exports` map is honoured for an installed
99
+ package but not for a path — and a directory whose entrypoint does not resolve is skipped
100
+ **silently**: no error, no log line, no plugin. This package ships that `index.js` for
101
+ exactly that reason.
102
+
103
+ `opencode plugin add` cannot do this: it refuses a path with "Plugin target must be an npm
104
+ registry package or Git package specifier".
105
+
106
+ #### Doing this as an agent, on someone's machine
107
+
108
+ The installers (`scripts/install.sh`, `scripts/install.ps1`) encode the same procedure; if
109
+ you are an agent working for a user who prefers not to run them, follow these steps and do
110
+ not skip the last one. Never claim an install without the arrival check — a config write
111
+ returning cleanly is not evidence the plugin loaded.
112
+
113
+ 1. Read both `~/.config/opencode/opencode.jsonc` and `opencode.json`. Count how many
114
+ entries anywhere in them name this package (`opencode-team-mode`, case and hyphens
115
+ vary). More than one → the plugin is loading twice; fix that before anything else.
116
+ 2. Write **one** entry, into the file that already holds the user's other keys (prefer the
117
+ `.jsonc`, since that is where previous installers wrote). Keep every entry that is not
118
+ ours, keep the comments, and leave no comma dangling before `]` — the host tolerates it,
119
+ the next hand edit may not.
120
+ 3. Generate the roles and commands (Step 2). A plugin cannot create an agent on 2.x, so
121
+ without these twelve files Team does not exist however well the plugin loaded.
122
+ 4. Set `default_agent: "team"` **last** (Step 3) — a default naming agents that are not on
123
+ disk makes the host fall back to `build` silently.
124
+ 5. Verify, in this order, and report what you actually saw:
125
+ - `opencode-cli … run --standalone --print-logs` (or restart the desktop and read the
126
+ log) → exactly **one** line `msg="loading plugin" id=<our entry>
127
+ entrypoint=file:///…/index.js`, and **no** `failed to load plugin` naming us.
128
+ - a new Team session → `tm_stats`, section `启动与人格`: `tools_registered: 9`, and the
129
+ `作用域` line. The role check is the visibility line, not a
130
+ missing-names field (the boot row's `agents_missing` is gone): it distinguishes 已装而看不见 —
131
+ `agents_editor_unseen` with `agents_resolved_in_request` non-empty, because the host really
132
+ resolved those ids in a request — from 本进程无法区分, since `ctx.agent.transform` is a
133
+ snapshot from BEFORE the config directory merges. "Step 3 has not run" shows up at the host
134
+ (`--agent team` does not resolve), never as a row in this table.
135
+ - If the log shows nothing at all about our id, the entry is under a key the host does
136
+ not read (`plugin`, singular) or the directory has no root `index.js`. Both failures
137
+ are silent by design; the absence of an error is not a success signal.
138
+ 6. Say which of the two spellings you left installed, and whether the package came from
139
+ npm or from a local path — the Extensions panel cannot tell them apart (a loader file
140
+ named `team-mode.js` and a directory whose plugin id is `team-mode` print identically).
141
+
142
+ ### Step 2 — Generate the six roles and the six commands
143
+
144
+ This is the step 2.x exists for and the v1 installer never needed. Run the generator
145
+ that ships **inside the installed package** — never copy the markdown by hand, or the
146
+ prompts drift away from what the plugin injects on v1:
147
+
148
+ ```bash
149
+ # the installed copy of this package (global config's node_modules):
150
+ node ~/.config/opencode/node_modules/@te-river/opencode-team-mode/scripts/gen-v2-config.mjs
151
+
152
+ # preview without writing:
153
+ node …/scripts/gen-v2-config.mjs --print
154
+ # write somewhere else (a project's .opencode/, a temp dir for a check):
155
+ node …/scripts/gen-v2-config.mjs --dir ~/.config/opencode
156
+ ```
157
+
158
+ Expected output: `共 12 个文件(角色 6 + 命令 6)`. It is idempotent — re-running writes
159
+ nothing and prints `已是最新`. A file it did not generate (no marker) is **refused**, not
160
+ overwritten, so your own `agents/team.md` survives; `--force` overrides that.
161
+
162
+ On Windows the installed path is
163
+ `%USERPROFILE%\.config\opencode\node_modules\@te-river\opencode-team-mode\scripts\gen-v2-config.mjs`.
164
+
165
+ The generated `agents/<role>.md` carries the role's `description` / `mode` / `color` /
166
+ permission triples in frontmatter and the **v2 variant** of the prompt in the body: the
167
+ generator rewrites every sentence that named a retired tool, and it **fails the run** if a
168
+ rewrite rule stops matching the source. That is deliberate — a v2 model told to call
169
+ `tm_read` costs the round the mandate exists to save.
170
+
171
+ ### Step 3 — Make Team the default, in config
172
+
173
+ The plugin also calls `default("team")` on every boot, but a 2.x plugin cannot read the
174
+ value back, so the config key is the one you can verify:
175
+
176
+ ```jsonc
177
+ { "default_agent": "team" }
178
+ ```
179
+
180
+ **Order matters:** set it only after Step 2 wrote the role files. A default naming a
181
+ missing agent makes the host fall back to `build` **silently** — you would see Team
182
+ working in a new session and nothing explaining why it stopped. Note also that
183
+ `default_agent` does not change the agent already stored on an existing conversation;
184
+ it applies to new sessions.
185
+
186
+ ### Step 4 — Restart and verify
187
+
188
+ ```bash
189
+ opencode reload # or just restart the desktop app
190
+ ```
191
+
192
+ Four checks, in this order:
193
+
194
+ 1. `opencode agents` (or the picker) lists `team`, `architect`, `implementer`,
195
+ `reviewer`, `tester`, `researcher`.
196
+ 2. A new session starts as Team. Ask: `tm_stats` — the reply has a
197
+ **启动与人格** section showing the v2 boot line: which tools were registered, whether
198
+ `tool.execute.after` / `permission.evaluate` / `session.context` attached, the probe's
199
+ counts, and `storage_probe` (the `ctx.storage` round-trip that `tm_ledger` depends on).
200
+ 3. **JIT actually governs the host's tools**: ask Team to run a command that prints a lot
201
+ (e.g. `dir /s` / `ls -R` on a large tree). The tool result should come back as a short
202
+ preview with an offload handle, not the whole dump. If it comes back verbatim, the
203
+ offload layer is not attached — `tm_stats` says so.
204
+ 4. `tm_ledger { action:"add", text:"smoke test" }` answers with an id and
205
+ `已写入 ctx.storage`. That is the v2 ledger being live.
206
+
207
+ ### Updating / 更新
208
+
209
+ ```bash
210
+ opencode plugin update @te-river/opencode-team-mode # or plugin add …@latest again
211
+ node ~/.config/opencode/node_modules/@te-river/opencode-team-mode/scripts/gen-v2-config.mjs
212
+ opencode reload
213
+ ```
214
+
215
+ The second command is not optional after an upgrade: the role files carry the prompts, and
216
+ a new release may have changed them. Re-running is cheap — unchanged files are skipped.
217
+
218
+ ### Uninstalling
219
+
220
+ 1. Remove the plugin entry (`opencode plugin remove @te-river/opencode-team-mode`).
221
+ 2. Delete the generated files: `~/.config/opencode/agents/{team,architect,implementer,reviewer,tester,researcher}.md`
222
+ and `~/.config/opencode/commands/team-*.md`. Only files carrying our marker were written
223
+ by the generator — anything else you wrote yourself is yours.
224
+ 3. Remove `"default_agent": "team"` if you set it.
225
+ 4. The plugin's own data lives under `<repo>/.git/opencode-team/` (git workspaces) or the
226
+ OS temp dir; deleting it costs nothing — the TTL sweeper does the same over time.
227
+
228
+ ### Troubleshooting
229
+
230
+ | Symptom | Cause and move |
231
+ |---|---|
232
+ | Roles are not in the picker | Step 2 never ran, or ran against a different `--dir`. `ls ~/.config/opencode/agents` |
233
+ | The default silently became `build` | `default_agent` names an agent that does not exist — re-run Step 2, then Step 3 |
234
+ | A hand-written `agents/team.md` was not updated | By design: the generator refuses files it did not create. Move yours aside, or pass `--force` |
235
+ | `/team-plan` etc. run but not as the specialist | 2.x documents `mode: subagent` as "runs only in a child session"; if a command selecting a specialist does not behave, the fix is `mode: "all"` in the role definition (report it — this is the one item in this flow still unverified on a live host) |
236
+ | `tm_webfetch` on an odd site says it refused **without asking anyone** | Expected on 2.x: a plugin cannot raise a dialog. Use a source that works, or let the host's own permission rule allow it; the address red line (metadata / private) has no consent path at all, on either generation |
237
+ | `task`/`subagent` seems to block the lead | On 2.x the plugin forces `background: true`; if you also set the old `OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS`, unset it — it is a v1 flag and only confuses the picture |
238
+ | A tool's output arrives un-offloaded | `TM_NATIVE_OFFLOAD=off` (or a missing `tool.execute.after` seam on an older 2.x build) — `tm_stats` names which |
239
+ | The plugin behaves oddly — two dialogs, doubled hooks, tools registered twice | It is loaded twice. `opencode.json` and `opencode.jsonc` are merged, and the host's dedupe matches only an identical string, so the same package under two spellings (or in both files) is two personalities. Count the Team entries across BOTH files; `msg="loading plugin"` appearing twice for one id is the proof |
240
+ | You wrote the entry and the host says nothing at all about it | Two silent causes, both by design: the key is singular `plugin` (2.x reads `plugins`), or a directory entry without a root `index.js`. The loader resolves a directory as `<dir>/index` only and drops it with no message when that fails — absence of an error is not a success signal here |
241
+ | A background sub-agent's reply is huge | The child is registered, collectable AND readable: `tm_join` lists it (marked 宿主 subagent 派发), reads its report back through `ctx.session.context`, and credits the seam it came from (`正文来源=ctx.session.context`) — so the reply arrives through the same JIT pipeline as everything else (offload + ≤80-token preview + `tm_fetch` handle when it is oversized). What v2 still never gives a plugin is the injected message BEFORE the host persists it, so we can read a report but cannot rewrite the injection — which is why a >~50-line DELIVERABLE still belongs on the blackboard file with its path in the reply |
242
+ | You want OUR browser visible in the side panel | Not possible — the panel attaches to the server's own browser service (`docs/research/browser-pane.md`). What IS reachable is a still frame: hand the screenshot to the host's `browser_preview { path }`, which renders a server-local png/html/md/pdf into that panel. Not yet confirmed in a real GUI session |
243
+ | You need to know what the host actually exposes | `TM_V2_PROBE=<path>.jsonl` records tool and action **names and counts only** — never a command, path, URL or value — and `tm_stats` renders the capability matrix |
244
+
245
+ ---
246
+
247
+ ## Part B — 中文
248
+
249
+ ### 一条命令,或者按下面的步骤来
250
+
251
+ `scripts/install.sh` / `scripts\install.ps1` 现在会探测宿主主版本,并在 2.x 上把本页的三步全做完(插件条目 → 生成角色与命令 → 最后写 `default_agent`,并从磁盘读回校验)。两件事直说而不含糊:
252
+
253
+ - 版本探测也会去问**桌面端**(`resources/opencode-cli.version`,再试自带的 `opencode-cli.exe --version`),因为桌面安装不把 `opencode` 放进 `PATH`——在这种机器上,只探 PATH 会得到"没找到",而 2.0.16 正在跑;
254
+ - 这条 v2 分支**已经在活体 2.0.18 宿主上端到端跑过**(两个前端都跑了,`HOME` 与 `USERPROFILE` 重定向):Team 只有**一条** `loading plugin`、零加载失败、`v2-boot tools_registered:9`、每个配置文件里别人家的条目原样保留、旧的 `.json` 之后仍能被严格 `JSON.parse`。是"跑"而不是"读"抓出并修好了两个缺陷:`ours()` 认不出工作树路径的写法(下一次运行就会加出**第二条**条目——恰好是这个函数存在的理由),以及 PowerShell 的 `Copy-Item <src>\* <dst>` 在目标目录尚不存在时会中途抛错,留下半份包。下面的手动步骤仍是文档化的退路:安装脚本在你那台宿主上表现不对,就按手动步骤做,并回报是哪一步说了什么。
255
+
256
+ ### 2.x 上到底哪里不一样(先看这张表再动手)
257
+
258
+ | | OpenCode 1.18.x | OpenCode 2.x |
259
+ |---|---|---|
260
+ | 六个角色 | 插件启动时注入 | `~/.config/opencode/agents/*.md`,由下面的生成器写出——插件没有"造 agent"的接口 |
261
+ | 六条 `/team-*` 命令 | 插件注入 | 同一个生成器写 `commands/*.md` |
262
+ | 默认 agent | 只在用户没动过时补位 | **每次启动都把 Team 设成默认**(v2 没有读取接口),再加配置里的 `default_agent: "team"`(这一条才是你核对得动的)。退出方式:`"team-mode": { "defaultAgent": false }` |
263
+ | 读文件 / 搜代码 / 跑命令 | `tm_read` / `tm_grep` / `tm_bash` | 宿主的 `read` / `grep` / `glob` / `shell`,**治理照旧**:超大结果照样在 `tool.execute.after` 被卸载成预览 + 句柄,跨出项目的路径走宿主自己的 `external_directory` 权限(v1 是硬拒,v2 是弹窗) |
264
+ | 批量调用 | `tm_ptc_run` | 宿主自己的 `execute`(Code Mode) |
265
+ | 入口文件(v2 主机的硬要求) | — | 宿主把插件**目录**解析成 `<目录>/index.js`;只写 `package.json#exports` 的目录会被**静默忽略**(连错误都没有)。本包根目录的 `index.js` 就是为这条存在的——`plugins: ["./vendor/team-mode"]` 这类官方写法能加载,靠的是它 |
266
+ | 交互式浏览 | `tm_browser`(我们自己起的 playwright/CDP 浏览器) | **优先宿主的 `browser_*`**——只有它是桌面端侧边栏里那个浏览器(`docs/research/browser-pane.md`)。`tm_browser` 保留为"宿主没接桌面浏览器时"的退路(CLI / standalone);原生目录由 `src/host/v2-browser-gate.ts` 管(`execute.before` 上判 URL / 地址红线 / 环境文件路径,并且有"漏过去就把页面换成拒绝语"的兜底)。快照是**截断**而不是卸载,所以下一次点击要的 `[ref=…]` 都留在上下文里 |
267
+ | 子代理结算检测 | 宿主的 `event` 钩子 | `ctx.event.subscribe()`——零依赖的 async iterable,按事件类型名过滤(`src/host/v2-events.ts`)。没有它 `tm_join` 分不清「已结算」和「仍在跑」;`tm_stats` 会给出转发了多少、哪些类型名没认出来(只记名字,绝不记负载) |
268
+ | 任务清单 | 宿主 `todowrite` | **`tm_ledger`**,存在宿主的 `ctx.storage` 里(v2 不给插件 `todowrite`) |
269
+ | 征求用户同意 | 宿主官方逐次弹窗 | **插件在 v2 弹不出对话框。** 原本该问的受治理调用一律**直接拒绝**,并说明是"没人可问"而不是"问了被拒"。你看到的弹窗都来自宿主自己(权限规则、越出项目目录) |
270
+ | 联网 | 22 个域名白名单 + 确认弹窗 | **域名门禁关掉**(`TM_WEBFETCH_ALLOWED_DOMAINS` 默认 `"*"`):2.x 插件弹不出确认框,"批准后放行"等于让 agent 去等一个永远不会出现的窗口。地址类别照管——元数据 / 链路本地 / 保留网段在任何设置下都拒;私网(回环、RFC1918、CGNAT、`.localhost`)也拒,但拒绝语现在给出两条出口而不是承诺点击:`TM_PRIVATE_SPACE=allow`(放开整段),或把那一台主机名写进 `TM_WEBFETCH_ALLOWED_DOMAINS`(只放开它自己) |
271
+ | 非阻塞命令 | `tm_pty`(跑在宿主终端会话上)| **完全不注册**——v2 插件上下文没有 pty 域,这个工具只能报自己缺缝。慢步骤请一条一个 `shell` 调用(各自带 `timeout`),并把输出 tee 到日志好回读 |
272
+ | 子代理 | 需要 `OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=true` | 原生能力;插件对每次 `subagent` 强制 `background: true`,所以 **2.x 不要去设那个环境变量**(那是 v1 的补丁,在这里什么也不改变,只会让人误判) |
273
+ | 对你其它模式的影响 | 插件钩子是全局的 | **没有影响。** 每个钩子都先看会话归属,所以 `build`、`plan` 和你自己装的 agent 都保持刚装好 OpenCode 时的样子——不会从它们的请求里删工具、不会设温度、不会卸载结果、不会收紧权限、也不会把它们的派发改成后台 |
274
+
275
+ ### 前置条件
276
+
277
+ OpenCode 2.x(桌面版或 CLI),以及 PATH 上可用的 Node.js(插件跑在宿主的运行时里;
278
+ Node 20+ 还会额外启用 Playwright 浏览器引擎)。
279
+
280
+ ### 第 1 步 — 安装插件
281
+
282
+ 键名是 **`plugins`(复数)**,而且里面一行就是完整的插件安装:宿主会在**启动时自己解析并安装**
283
+ 这个条目指向的包。不需要先 `npm install`,没有缓存要清,`opencode plugin add` 也不是前置条件
284
+ ——它只是顺手帮你写了这同一个键(写进 `opencode.json`,所以你会看到条目出现在那儿)。
285
+
286
+ ```jsonc
287
+ // ~/.config/opencode/opencode.jsonc
288
+ { "plugins": ["@te-river/opencode-team-mode@latest"] }
289
+ ```
290
+
291
+ 关于这个文件有两件事是实测出来的(2.0.16 / 2.0.18),而且用 1.18.x 的直觉一定会搞错,
292
+ 宿主的原始代码见 `docs/research/plugin-loader-contract.md`:
293
+
294
+ - `opencode.json` 与 `opencode.jsonc` 是**两份都读、合并生效**。1.18.x 那句"`.jsonc` 覆盖
295
+ `.json`"在 2.x 上不成立;照它做(把旧文件向前复制一份)就等于把同一个插件写进两个文件,
296
+ 于是**加载两次**(两套人格、同样的工具和钩子绑两遍),而且没有任何警告。
297
+ - 宿主自己的去重只认**完全相同的字符串**。一个文件里写 `@te-river/…@latest`、另一个里写
298
+ `./vendor/team-mode`,是两个条目,不是一个插件。
299
+
300
+ **本地目录**是另一种合法写法,开发时必须要用它:
301
+
302
+ ```jsonc
303
+ { "plugins": ["./vendor/team-mode"] } // 相对本文件,或者绝对路径的目录
304
+ ```
305
+
306
+ 这个目录**必须有根 `index.js`**。宿主解析目录只试 `<dir>/index`,别的不试 ——
307
+ `package.json#exports` 只对已安装的包生效,对路径不生效 —— 而解析不出入口的目录会被
308
+ **静默跳过**:没有报错、没有日志、也没有插件。本包发布时带上那个 `index.js` 就是为了这件事。
309
+
310
+ `opencode plugin add` 干不了这件事:给它路径会被拒绝
311
+ ("Plugin target must be an npm registry package or Git package specifier")。
312
+
313
+ #### 由 Agent 代用户在机器上执行
314
+
315
+ 两个安装脚本(`scripts/install.sh`、`scripts/install.ps1`)走的就是下面这套;如果你是被派来
316
+ 装机器的 Agent 而用户不想跑脚本,就按顺序做完,**尤其不要跳过最后一步**——配置写成功了不等于
317
+ 插件加载了,没有到达性检查就没有资格说"装好了"。
318
+
319
+ 1. 同时读 `~/.config/opencode/opencode.jsonc` 和 `opencode.json`,数一下两个文件里指向本包的
320
+ 条目一共有几条(`opencode-team-mode`,大小写和连字符都可能不一样)。多于一条 → 插件正在
321
+ 被加载两次,先修这件事再谈其他。
322
+ 2. 只写**一条**条目,写进已经装着用户其他配置的那个文件(优先 `.jsonc`,因为以前的安装器
323
+ 就写在那里)。别人家的条目一条都不许动,注释保留,`)`/`]` 前不要留悬挂逗号——宿主容忍它,
324
+ 下一个手工编辑的人未必容忍。
325
+ 3. 生成角色与命令(第 2 步)。2.x 上插件不能创建 agent,所以这十二个文件不在,Team 就不存在,
326
+ 插件加载得再好也没用。
327
+ 4. 最后一步才写 `default_agent: "team"`(第 3 步)——默认值指向不存在的 agent 会让宿主
328
+ 静默退回 `build`。
329
+ 5. 验证,按顺序,并且把你真正看到的说出来:
330
+ - `opencode-cli … run --standalone --print-logs`(或重启桌面端后读日志)→
331
+ **恰好一条** `msg="loading plugin" id=<我们的条目> entrypoint=file:///…/index.js`,
332
+ 并且**没有**指名我们的 `failed to load plugin`。
333
+ - 新建一个 Team 会话 → `tm_stats` 的 `启动与人格`:`tools_registered: 9`,以及 `作用域`
334
+ 那一行。角色这一项看的是可见性行,不再是缺名字段(boot 行的 `agents_missing` 已经去掉):它区分"已装而看不见"——`agents_editor_unseen` 有值,且 `agents_resolved_in_request` 也有值,说明宿主在真实请求里解析过这些 id——和"本进程无法区分",因为 `ctx.agent.transform` 拿到的是配置目录合并**之前**的角色集。"第 3 步没做"要到宿主那边才看得见(`--agent team` 解析不到),不会在这张表里变成一行结论。
335
+ - 日志里关于我们的 id 一个字都没有 → 条目写在了宿主不读的键下(单数 `plugin`),或者那个
336
+ 目录没有根 `index.js`。这两种失败都是设计上静默的,所以"没报错"不是成功信号。
337
+ 6. 明确说清你留下的是哪种写法、包来自 npm 还是本地路径 —— 扩展面板分不出来:一个叫
338
+ `team-mode.js` 的 loader 文件,和一个插件 id 恰好是 `team-mode` 的目录条目,显示出来一模一样。
339
+
340
+ ### 第 2 步 — 生成六个角色和六条命令
341
+
342
+ 这一步就是 2.x 存在、而 v1 安装脚本从不需要的那件事。请运行**已安装包里**自带的那个生成器
343
+ ——不要手抄 markdown,否则 v1 注入的提示词和 v2 配置文件里的会悄悄分叉:
344
+
345
+ ```bash
346
+ node ~/.config/opencode/node_modules/@te-river/opencode-team-mode/scripts/gen-v2-config.mjs
347
+
348
+ # 只预览不写盘:
349
+ node …/scripts/gen-v2-config.mjs --print
350
+ # 写到别处(某个项目的 .opencode/,或者先写到临时目录做检查):
351
+ node …/scripts/gen-v2-config.mjs --dir ~/.config/opencode
352
+ ```
353
+
354
+ 期望输出 `共 12 个文件(角色 6 + 命令 6)`。它是幂等的:再跑一次什么都不写,只报
355
+ `已是最新`。不是它生成的文件(没有标记)会被**拒绝覆盖**,所以你自己手写的
356
+ `agents/team.md` 安全;要强行覆盖才用 `--force`。
357
+
358
+ Windows 上的路径是
359
+ `%USERPROFILE%\.config\opencode\node_modules\@te-river\opencode-team-mode\scripts\gen-v2-config.mjs`。
360
+
361
+ 生成的 `agents/<角色>.md` 里,frontmatter 放 `description` / `mode` / `color` 和权限三元组,
362
+ 正文是提示词的 **v2 变体**:所有点名了已退役工具的句子都会被改写,而且**只要某条改写规则
363
+ 在源文里找不到,生成就会失败**。这是刻意的——告诉一个 v2 模型"用 `tm_read`",代价就是那条
364
+ 规则本来要省下的那一轮。
365
+
366
+ ### 第 3 步 — 在配置里把 Team 设为默认
367
+
368
+ 插件每次启动也会调 `default("team")`,但 v2 插件读不回这个值,所以能核对的是配置键:
369
+
370
+ ```jsonc
371
+ { "default_agent": "team" }
372
+ ```
373
+
374
+ **顺序不能颠倒**:必须在第 2 步已经把角色文件写出去之后再设。默认值指向一个不存在的 agent
375
+ 时,宿主会**静默回落到 `build`**——你会看到新会话不是 Team,而现场没有任何解释。另外
376
+ `default_agent` 不会改动已经存在的会话所用过的 agent,它只作用于新会话。
377
+
378
+ ### 第 4 步 — 重启并核对
379
+
380
+ ```bash
381
+ opencode reload # 或者直接重启桌面端
382
+ ```
383
+
384
+ 按顺序做四项核对:
385
+
386
+ 1. `opencode agents`(或选择器里)能看到 `team`、`architect`、`implementer`、`reviewer`、
387
+ `tester`、`researcher`。
388
+ 2. 新会话默认是 Team。在里面跑 `tm_stats` —— 回复里应有**启动与人格**一段,展示 v2 的启动
389
+ 快照:注册了哪些工具、`tool.execute.after` / `permission.evaluate` / `session.context`
390
+ 有没有挂上、探针计到的东西,以及 `storage_probe`(`tm_ledger` 依赖的那次
391
+ `ctx.storage` 写读回环)。
392
+ 3. **JIT 真的在治理宿主工具**:让 Team 跑一条输出很多的命令(大目录树的 `ls -R` /
393
+ `dir /s`)。结果应该以"短预览 + 卸载句柄"回来,而不是整坨灌进上下文。若原样回来了,
394
+ 说明卸载层没挂上——`tm_stats` 会直说。
395
+ 4. `tm_ledger { action:"add", text:"冒烟测试" }` 应该回你一个编号,并写明
396
+ `已写入 ctx.storage`。这就是 v2 清单活着的样子。
397
+
398
+ ### 更新
399
+
400
+ ```bash
401
+ opencode plugin update @te-river/opencode-team-mode # 或者再跑一次 plugin add …@latest
402
+ node ~/.config/opencode/node_modules/@te-river/opencode-team-mode/scripts/gen-v2-config.mjs
403
+ opencode reload
404
+ ```
405
+
406
+ 第二条命令在升级之后不是可选项:角色文件里装的是提示词,新版本可能改过。重跑很便宜——没变
407
+ 的文件会被跳过。
408
+
409
+ ### 卸载
410
+
411
+ 1. 去掉插件条目(`opencode plugin remove @te-river/opencode-team-mode`)。
412
+ 2. 删掉生成的文件:`~/.config/opencode/agents/{team,architect,implementer,reviewer,tester,researcher}.md`
413
+ 和 `~/.config/opencode/commands/team-*.md`。只有带我们标记的文件是生成器写的,你自己写的
414
+ 东西它从不碰。
415
+ 3. 如果设过 `"default_agent": "team"`,一并删掉。
416
+ 4. 插件自己的数据在 `<repo>/.git/opencode-team/`(git 工作区)或系统临时目录下;删掉没有代价
417
+ ——TTL 清理器本来就会定期做同样的事。
418
+
419
+ ### 故障排查
420
+
421
+ | 现象 | 原因与处置 |
422
+ |---|---|
423
+ | 选择器里没有那六个角色 | 第 2 步没跑,或者 `--dir` 指到了别处。`ls ~/.config/opencode/agents` |
424
+ | 默认 agent 悄悄变成 `build` | `default_agent` 指向了一个不存在的角色——重跑第 2 步,再做第 3 步 |
425
+ | 手写的 `agents/team.md` 没被更新 | 这是设计:生成器拒绝覆盖不是它生成的文件。把你的文件挪开,或显式加 `--force` |
426
+ | `/team-plan` 能跑但不是以那个专家身份跑 | 2.x 把 `mode: subagent` 文档化为"只在子会话里运行"。如果选定专家的命令行为不对,改法是角色定义里用 `mode: "all"`(请回报——这是本流程里唯一还没在活体宿主上验证过的一项) |
427
+ | `tm_webfetch` 说它"没问任何人就直接拒绝" | v2 的预期行为:插件弹不出对话框。换一个不需要这次访问的源,或让宿主自己的权限规则放行;地址红线(元数据 / 私网)在两代宿主上都没有授权路径 |
428
+ | `subagent` 好像把领队挡住了 | v2 上插件会强制 `background: true`;如果你顺手设了老的 `OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS`,请取消它——那是 v1 的开关,在这里只会误导判断 |
429
+ | 某个工具的输出没被卸载 | `TM_NATIVE_OFFLOAD=off`(或者那个 2.x 构建没有 `tool.execute.after` 缝)——`tm_stats` 会告诉你是哪一种 |
430
+ | 插件行为怪:两次弹窗、钩子重复、工具像注册了两遍 | 它被加载了两次。`opencode.json` 与 `opencode.jsonc` 是合并读取的,而宿主去重只认完全相同的字符串,所以同一个包换两种写法(或者同时躺在两个文件里)就是两套人格。把两个文件里指向 Team 的条目一起数一遍;`msg="loading plugin"` 对同一个 id 出现两条就是证据 |
431
+ | 写了条目,但宿主日志里关于它一个字都没有 | 两个"设计上静默"的原因:键名写成了单数 `plugin`(2.x 读 `plugins`),或者目录条目缺根 `index.js`。宿主解析目录只试 `<dir>/index`,试不出来就直接丢掉、不留任何消息 —— 在这里"没报错"不是成功信号 |
432
+ | 后台子代理的回复太长 | 子会话现在会被登记、可被收集(`tm_join` 会列出它,行上标着「宿主 subagent 派发」),但它的**正文**仍然是宿主的注入消息,v2 不会在落盘前把这条消息交给插件;我们也不改写发出的消息(猜错那一层的形状等于静默删证据)。所以超限交付走黑板文件:正文进文件、回复里带路径,领队读那个文件 |
433
+ | `tm_join` 说"没有匹配的派发",可孩子明明跑完了 | 活体在 2.0.16 上复现过:领队用的是**宿主的** `subagent{background:true}`,插件不创建子会话所以登记里没有它,而收养/按 id 认领原本走 `client.session.children` / `client.session.get`——v2 的插件上下文里根本没有 client。所以回复是通过宿主自己的完成注入到达领队的,不是通过我们的收集通道。这条待补的桥是 `ctx.session.get` 做父子校验(事件流已经能给出候选 sessionID) |
434
+ | 想在侧边栏看到我们 `tm_browser` 的页面 | 做不到(面板挂的是服务端自己的浏览器服务;见 `docs/research/browser-pane.md`)。能看到的是**静帧**:让 agent 把截图交给宿主的 `browser_preview { path }`,它会把服务端本地文件(png/html/md/pdf/mermaid)渲染进面板——这条尚未在你的 GUI 里验证过 |
435
+ | 想知道宿主到底给了什么 | `TM_V2_PROBE=<路径>.jsonl` 只记工具名与权限动作名**以及计数**,绝不记命令行、路径、URL 或环境变量值;`tm_stats` 会把能力矩阵渲染出来 |
436
+
437
+ ### v2 专属的开关
438
+
439
+ | 变量 / 配置 | 默认 | 作用 |
440
+ |---|---|---|
441
+ | `TM_WEBFETCH_ALLOWED_DOMAINS` | `*`(**仅 v2**) | 域名门禁默认关掉,只留地址红线;显式给了值就以它为准(v1 仍是 24 个种子域名) |
442
+ | `TM_NATIVE_OFFLOAD` | on | 用 `tool.execute.after` 治理宿主原生工具的结果;off 就退回宿主原样 |
443
+ | `TM_R6_FINE_ASK` | on(v2) | 由按命令分类器决定哪条 shell 要问;`off` 回到"每条 shell 都问",宿主没有 `permission.hook` 时也自动回到这一档 |
444
+ | `TM_V2_PROBE` | 未设 | 把宿主真实工具面/动作名记成 JSONL(只有名字和计数) |
445
+ | `"team-mode": { "defaultAgent": false }` | 不设置 = Team 永远默认 | 退出默认位抢占(只影响插件的每次启动行为,配置里的 `default_agent` 请自己改回来) |
@@ -1,5 +1,17 @@
1
1
  # TeamMode Installation Guide / 安装指南
2
2
 
3
+ > **This page is the OpenCode 1.18.x path.** On OpenCode 2.x a plugin cannot create an
4
+ > agent, so the six roles and the six `/team-*` commands have to be generated into
5
+ > `~/.config/opencode/agents/` and `commands/` — that flow is its own page:
6
+ > **[installation-v2.md](./installation-v2.md)**. Check `opencode --version` first;
7
+ > following the wrong one leaves Team half-installed (the plugin loads, the roles do not
8
+ > exist).
9
+ >
10
+ > **本页是 1.18.x 的装法。** OpenCode 2.x 上插件不能创建 agent,六个角色和六条 `/team-*`
11
+ > 命令必须生成到 `~/.config/opencode/agents/` 与 `commands/`——那一套单独写在
12
+ > **[installation-v2.md](./installation-v2.md)**。先跑 `opencode --version` 再选:走错页面会
13
+ > 留下"插件加载了、角色不存在"的半安装状态。
14
+
3
15
  > **For LLM agents:** your user asked you to install `@te-river/opencode-team-mode`. This document is the complete, self-contained procedure. Read it fully, then execute. Do not improvise package names or config locations — everything you need is here.
4
16
  >
5
17
  > **面向 LLM 智能体:** 用户要求你安装 `@te-river/opencode-team-mode`。本文档是完整、自包含的安装规程。通读后再执行。不要 improvised 包名或配置路径——所需信息全在这里。