@te-river/opencode-team-mode 1.4.3 → 1.4.4
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 +85 -18
- package/README.zh-CN.md +69 -11
- package/dist/agents.d.ts.map +1 -1
- package/dist/agents.js +28 -7
- package/dist/agents.js.map +1 -1
- package/dist/blackboard.d.ts +18 -5
- package/dist/blackboard.d.ts.map +1 -1
- package/dist/blackboard.js +70 -15
- package/dist/blackboard.js.map +1 -1
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +5 -2
- package/dist/commands.js.map +1 -1
- package/dist/index.d.ts +7 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -169,6 +169,55 @@ You can also invoke agents directly using the `@` mention in OpenCode Desktop:
|
|
|
169
169
|
- `@tester` — Write tests
|
|
170
170
|
- `@researcher` — Research a topic
|
|
171
171
|
|
|
172
|
+
### Demo
|
|
173
|
+
|
|
174
|
+
A session transcript, recreated from how the flow actually looks. The user
|
|
175
|
+
picks `team` in the agent switcher (or enables `defaultAgent`, see
|
|
176
|
+
Configuration), then just types into a fresh chat:
|
|
177
|
+
|
|
178
|
+
> **User:** Add token-bucket rate limiting to our Express API — 100 requests
|
|
179
|
+
> per minute per user, return 429 when exceeded. Don't touch anything under
|
|
180
|
+
> `src/legacy/`.
|
|
181
|
+
|
|
182
|
+
```text
|
|
183
|
+
team Breaking this down: design → implement → review → test.
|
|
184
|
+
Task board: .git/opencode-team/20260831-143012/rate-limiter/ (session folder + board inside .git/, auto-swept after idle TTL)
|
|
185
|
+
|
|
186
|
+
▸ @architect — designing (writes 01-architect-design.md)
|
|
187
|
+
✓ in-memory token bucket, per-user key, 429 + Retry-After
|
|
188
|
+
summary above, full design on the board
|
|
189
|
+
|
|
190
|
+
▸ @implementer — building (Reads: 01; writes 02-implementer-middleware.md)
|
|
191
|
+
✓ src/middleware/rateLimit.ts (new), wired into src/app.ts (+3 lines)
|
|
192
|
+
|
|
193
|
+
▸ @reviewer — auditing the diff (Reads: 01, 02; writes 03-reviewer-findings-r1.md)
|
|
194
|
+
⚠ 1 MAJOR — bucket refill does read-modify-write in two steps;
|
|
195
|
+
races under concurrent requests
|
|
196
|
+
→ converted to a fix task; dispatched to @implementer with the
|
|
197
|
+
finding text (the user was not asked to approve this step)
|
|
198
|
+
|
|
199
|
+
▸ @implementer r2 — fixing the race (Reads: 03-r1 §MAJOR; writes 04-implementer-r2.md)
|
|
200
|
+
✓ refill restructured to single atomic update
|
|
201
|
+
|
|
202
|
+
▸ @reviewer r2 — re-review of fixed scope only
|
|
203
|
+
✓ clean — r1 finding resolved, no regressions
|
|
204
|
+
|
|
205
|
+
▸ @tester — covering limiter + boundaries (writes 05-tester-report.md)
|
|
206
|
+
✓ 14/14 pass — burst edge, window expiry, concurrent refill,
|
|
207
|
+
src/legacy/** byte-identical (user boundary verified in tests)
|
|
208
|
+
|
|
209
|
+
team Done.
|
|
210
|
+
rate limiter shipped: rateLimit.ts (new) · app.ts (+3) · 14 tests green
|
|
211
|
+
review loop: 1 major found → fixed → clean
|
|
212
|
+
assumption: in-memory only — say the word if you want Redis
|
|
213
|
+
src/legacy/ untouched
|
|
214
|
+
task board left in place — TTL sweep will reclaim it
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
The only message the user typed was the first one. The reviewer's finding
|
|
218
|
+
became the implementer's work order without a prompt; every artifact stayed
|
|
219
|
+
out of chat and on the board, read only by the dispatch that needed it.
|
|
220
|
+
|
|
172
221
|
### Desktop-specific features
|
|
173
222
|
|
|
174
223
|
In **OpenCode Desktop**, you get additional UX benefits:
|
|
@@ -214,10 +263,15 @@ opencode-team-mode/
|
|
|
214
263
|
|
|
215
264
|
Sub-agents cannot message each other live (platform limitation), so TeamMode coordinates them through a **file blackboard** with strict ownership:
|
|
216
265
|
|
|
217
|
-
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
266
|
+
- **Session isolation:** every conversation owns ONE timestamped session
|
|
267
|
+
folder, and each multi-agent task gets its own directory inside it:
|
|
268
|
+
`<repo>/.git/opencode-team/<session-key>/<task-slug>/` — inside `.git/`,
|
|
269
|
+
so your working tree and commits are **never polluted**. (Non-git
|
|
270
|
+
workspaces fall back to the OS temp dir.) Since boards now linger until
|
|
271
|
+
the TTL sweep, the session layer keeps a fresh conversation from bumping
|
|
272
|
+
into — or reading stale artifacts from — a not-yet-swept board (timestamps
|
|
273
|
+
are second-granular, so overlap needs two conversations starting in the
|
|
274
|
+
same second).
|
|
221
275
|
- **File ownership:** every artifact is one topic-sized file written by
|
|
222
276
|
exactly one agent (`01-architect-auth-design.md`, `03-reviewer-auth-r1.md`).
|
|
223
277
|
~100 lines max per file — split topics instead of letting files balloon.
|
|
@@ -242,15 +296,18 @@ your go-ahead); only explicit action requests enter the workflow. And whenever
|
|
|
242
296
|
you spell out what may or may not be touched, **those boundaries outrank
|
|
243
297
|
everything else** — the lead restates them in every single dispatch.
|
|
244
298
|
|
|
245
|
-
### Cleanup —
|
|
299
|
+
### Cleanup — the TTL sweeper is the only path
|
|
246
300
|
|
|
247
|
-
|
|
|
248
|
-
|
|
249
|
-
|
|
|
250
|
-
| Safety net | Plugin code (in-process sweeper) | At startup + every hour: removes task directories idle **beyond the TTL** |
|
|
301
|
+
| Who | When |
|
|
302
|
+
|---|---|
|
|
303
|
+
| Plugin code (in-process sweeper) | At startup + every hour: removes task directories idle **beyond the TTL** |
|
|
251
304
|
|
|
252
|
-
The
|
|
253
|
-
|
|
305
|
+
The Team Lead never deletes task directories — finished boards stay
|
|
306
|
+
readable so you can audit how a run went, and reclamation is pure code
|
|
307
|
+
that never relies on the model remembering to do anything (crashes and
|
|
308
|
+
force-kills leave nothing behind either). The sweeper prunes stale task
|
|
309
|
+
dirs individually under a still-live session, and reclaims an entirely
|
|
310
|
+
idle session folder in one pass. Set `ttlDays` to taste.
|
|
254
311
|
|
|
255
312
|
### Configure the TTL
|
|
256
313
|
|
|
@@ -271,21 +328,31 @@ fall back to 5.
|
|
|
271
328
|
|
|
272
329
|
### Default agent
|
|
273
330
|
|
|
274
|
-
TeamMode
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
331
|
+
By default TeamMode **does not** touch the default agent — new chats start
|
|
332
|
+
on the built-in `build` as before. This is a deliberate ordering trade-off:
|
|
333
|
+
the switcher pins the default agent to the **first slot** and sorts
|
|
334
|
+
everything else alphabetically, so "Team pinned as default (first)" and
|
|
335
|
+
"Team shown after Plan" are mutually exclusive. Leaving the default slot
|
|
336
|
+
alone gives you the picker order **build, plan, team**.
|
|
337
|
+
|
|
338
|
+
To promote Team as the default agent anyway (new chats start with the team
|
|
339
|
+
orchestrator, and Team is pinned first — order becomes **team, build,
|
|
340
|
+
plan**):
|
|
278
341
|
|
|
279
342
|
```jsonc
|
|
280
343
|
{
|
|
281
344
|
"plugin": [
|
|
282
|
-
["@te-river/opencode-team-mode@latest", { "defaultAgent":
|
|
345
|
+
["@te-river/opencode-team-mode@latest", { "defaultAgent": true }]
|
|
283
346
|
]
|
|
284
347
|
}
|
|
285
348
|
```
|
|
286
349
|
|
|
287
|
-
An explicitly configured non-`build` `default_agent`
|
|
288
|
-
untouched
|
|
350
|
+
An explicitly configured non-`build` `default_agent` in your own config is
|
|
351
|
+
always respected untouched, even with `defaultAgent: true`.
|
|
352
|
+
|
|
353
|
+
**Upgrade note:** since v1.4.4 the plugin no longer claims the default-agent
|
|
354
|
+
slot by default. If you relied on Team being your default agent before
|
|
355
|
+
(v1.4.2+), add `{ "defaultAgent": true }` to your plugin options.
|
|
289
356
|
|
|
290
357
|
---
|
|
291
358
|
|
package/README.zh-CN.md
CHANGED
|
@@ -169,6 +169,51 @@ TeamMode 为 OpenCode 添加了六个斜杠命令,在聊天输入框中输入
|
|
|
169
169
|
- `@tester` — 编写测试
|
|
170
170
|
- `@researcher` — 调研主题
|
|
171
171
|
|
|
172
|
+
### 演示
|
|
173
|
+
|
|
174
|
+
以下是一段会话实录的还原。用户在代理选择器中选中 `team`(或按下方配置开启
|
|
175
|
+
`defaultAgent`),开新会话直接输入:
|
|
176
|
+
|
|
177
|
+
> **用户:** 给我们的 Express API 加令牌桶限流——每用户每分钟 100 请求,
|
|
178
|
+
> 超限返回 429。不要动 `src/legacy/` 下的任何东西。
|
|
179
|
+
|
|
180
|
+
```text
|
|
181
|
+
team 拆解任务:设计 → 实现 → 审查 → 测试。
|
|
182
|
+
任务黑板:.git/opencode-team/20260831-143012/rate-limiter/(会话目录 + 任务板,都在 .git/ 内,闲置超 TTL 自动清理)
|
|
183
|
+
|
|
184
|
+
▸ @architect — 设计中(写入 01-architect-design.md)
|
|
185
|
+
✓ 内存令牌桶、按用户键控、429 + Retry-After
|
|
186
|
+
聊天里只有摘要,设计全文在黑板上
|
|
187
|
+
|
|
188
|
+
▸ @implementer — 实现中(Reads: 01;写 02-implementer-middleware.md)
|
|
189
|
+
✓ src/middleware/rateLimit.ts(新增),接入 src/app.ts(+3 行)
|
|
190
|
+
|
|
191
|
+
▸ @reviewer — 审查改动(Reads: 01、02;写 03-reviewer-findings-r1.md)
|
|
192
|
+
⚠ 1 个 MAJOR — 桶回充分两步读-改-写,并发下有竞态
|
|
193
|
+
→ 已自动转为修复任务,发现原文随任务书派给 @implementer
|
|
194
|
+
(这一步没有要求用户拍板)
|
|
195
|
+
|
|
196
|
+
▸ @implementer r2 — 修竞态(Reads: 03-r1 §MAJOR;写 04-implementer-r2.md)
|
|
197
|
+
✓ 回充重构为单次原子更新
|
|
198
|
+
|
|
199
|
+
▸ @reviewer r2 — 只复审改动范围
|
|
200
|
+
✓ 通过 — r1 发现已解决,无回归
|
|
201
|
+
|
|
202
|
+
▸ @tester — 覆盖限流器与边界(写 05-tester-report.md)
|
|
203
|
+
✓ 14/14 通过 — 突发边界、窗口过期、并发回充、
|
|
204
|
+
src/legacy/** 逐字节未变(用户边界写进了测试断言)
|
|
205
|
+
|
|
206
|
+
team 完成。
|
|
207
|
+
限流器已交付:rateLimit.ts(新增)· app.ts(+3)· 14 测试全绿
|
|
208
|
+
审查闭环:1 个 major → 已修 → 清零
|
|
209
|
+
假设:仅内存存储——要接 Redis 说一声
|
|
210
|
+
src/legacy/ 未动
|
|
211
|
+
任务黑板留在原地,TTL 到期自动回收
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
用户输入的消息只有第一条。reviewer 的发现直接变成 implementer 的下一张
|
|
215
|
+
工单;每份制品都留在黑板上而不是聊天里,只被需要它的那次派发读取。
|
|
216
|
+
|
|
172
217
|
### 桌面版专属特性
|
|
173
218
|
|
|
174
219
|
在 **OpenCode 桌面版** 中,你还能获得额外的 UX 体验:
|
|
@@ -214,8 +259,11 @@ opencode-team-mode/
|
|
|
214
259
|
|
|
215
260
|
子代理之间无法实时互发消息(平台限制),TeamMode 通过**严格所有权的文件黑板**让它们协作:
|
|
216
261
|
|
|
217
|
-
-
|
|
262
|
+
- **会话隔离:** 每个会话拥有一个时间戳会话目录,多 Agent 任务在其内再各自
|
|
263
|
+
独立建任务目录:`<repo>/.git/opencode-team/<session-key>/<task-slug>/` ——
|
|
218
264
|
位于 `.git/` 内,**绝不污染**你的工作区和 commit(非 git 工作区自动回退到系统临时目录)。
|
|
265
|
+
正因为黑板现在会留到 TTL 清扫才消失,会话层让新对话几乎不可能撞上(或误读到)
|
|
266
|
+
上一场还没被收走的旧黑板 —— 时间戳精确到秒,理论上只有同一秒开跑的两个会话才会重名。
|
|
219
267
|
- **文件所有权**:每个制品是一个"一主题一文件",只由一个 Agent 写
|
|
220
268
|
(`01-architect-auth-design.md`、`03-reviewer-auth-r1.md`)。单文件约 ≤100 行,
|
|
221
269
|
超长就拆主题文件而不是任其膨胀。
|
|
@@ -235,14 +283,16 @@ Team Lead 对每条消息先分类再行动:咨询/提问只得到回答(零
|
|
|
235
283
|
仅**提议**修复并等待你放行);只有明确的行动指令才进入工作流。并且一旦你写明
|
|
236
284
|
了哪些能碰哪些不能碰,**这些边界高于一切规则**——lead 会在每次派发中原样重申。
|
|
237
285
|
|
|
238
|
-
### 清理 ——
|
|
286
|
+
### 清理 —— 只有 TTL 清扫器一条路
|
|
239
287
|
|
|
240
|
-
|
|
|
241
|
-
|
|
242
|
-
|
|
|
243
|
-
| 安全网 | 插件代码(进程内清扫器) | 启动时 + 每小时:清除空闲超过 **TTL** 的任务目录 |
|
|
288
|
+
| 责任方 | 时机 |
|
|
289
|
+
|---|---|
|
|
290
|
+
| 插件代码(进程内清扫器) | 启动时 + 每小时:清除空闲超过 **TTL** 的任务目录 |
|
|
244
291
|
|
|
245
|
-
|
|
292
|
+
Team Lead 不再删除任务目录 —— 跑完的黑板原地留给你回看审计;回收由纯代码
|
|
293
|
+
完成,从不依赖模型"记得删",崩溃/强杀留下的残骸同样会被清扫。清扫器对活跃
|
|
294
|
+
会话内的过期任务逐个回收,对整个闲置的会话目录一次性收走。TTL 可用
|
|
295
|
+
`ttlDays` 调节。
|
|
246
296
|
|
|
247
297
|
### 自定义 TTL
|
|
248
298
|
|
|
@@ -261,18 +311,26 @@ Team Lead 对每条消息先分类再行动:咨询/提问只得到回答(零
|
|
|
261
311
|
|
|
262
312
|
### 默认代理
|
|
263
313
|
|
|
264
|
-
TeamMode
|
|
265
|
-
|
|
314
|
+
TeamMode 默认**不再占用默认代理槽**——新会话仍从内建 `build` 开始。这是刻意的
|
|
315
|
+
排序取舍:选择器会把**默认代理钉在第一位**,其余按名称字母升序,因此
|
|
316
|
+
「Team 排默认(首位)」与「Team 显示在 Plan 之后」不可兼得。不占槽时顺序为
|
|
317
|
+
**build, plan, team**。
|
|
318
|
+
|
|
319
|
+
若希望新会话直接由团队调度者接管(Team 被钉在首位,顺序变为
|
|
320
|
+
**team, build, plan**),开启 `defaultAgent`:
|
|
266
321
|
|
|
267
322
|
```jsonc
|
|
268
323
|
{
|
|
269
324
|
"plugin": [
|
|
270
|
-
["@te-river/opencode-team-mode@latest", { "defaultAgent":
|
|
325
|
+
["@te-river/opencode-team-mode@latest", { "defaultAgent": true }]
|
|
271
326
|
]
|
|
272
327
|
}
|
|
273
328
|
```
|
|
274
329
|
|
|
275
|
-
|
|
330
|
+
即使用户显式配置了非 `build` 默认代理,也永远原样保留(开启与否都不覆写)。
|
|
331
|
+
|
|
332
|
+
**升级提示**:自 v1.4.4 起,插件默认不再占用默认代理槽。此前依赖 Team 作为
|
|
333
|
+
默认代理(v1.4.2+)的用户,请在插件选项中添加 `{ "defaultAgent": true }`。
|
|
276
334
|
|
|
277
335
|
---
|
|
278
336
|
|
package/dist/agents.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAqd7C,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAO9C,CAAA"}
|
package/dist/agents.js
CHANGED
|
@@ -104,8 +104,9 @@ Rules for the list:
|
|
|
104
104
|
4. **Integrate** — collect outputs, resolve conflicts, synthesize; consult
|
|
105
105
|
blackboard files whenever a summary is not enough.
|
|
106
106
|
5. **Verify** — run the feedback loop below before declaring done.
|
|
107
|
-
6. **Report
|
|
108
|
-
|
|
107
|
+
6. **Report** — structured summary with changes, review/test verdict,
|
|
108
|
+
risks. Leave the task directory in place: the plugin's TTL sweeper is
|
|
109
|
+
the only cleanup path (never delete it yourself).
|
|
109
110
|
|
|
110
111
|
## When you may edit directly
|
|
111
112
|
Delegation is the default, not a straitjacket. You MAY make small direct
|
|
@@ -113,11 +114,31 @@ edits: config tweaks, typo/format fixes, doc updates, tiny glue code
|
|
|
113
114
|
(≲ 10 lines). Anything substantive — feature logic, multi-file changes,
|
|
114
115
|
API design — goes to \`implementer\`.
|
|
115
116
|
|
|
117
|
+
Anti-pattern — the lead's own hands (observed in production): while
|
|
118
|
+
building something, you drift into writing file after file yourself until
|
|
119
|
+
the whole deliverable is done inline. Guard rails:
|
|
120
|
+
- If the request meets the medium-or-larger bar (see TodoList rule),
|
|
121
|
+
hand-execution is NOT permitted — every work package on the list gets
|
|
122
|
+
dispatched, including "small" ones you feel like knocking out.
|
|
123
|
+
- Sunk cost is not a reason to continue: caught yourself mid-inline-build
|
|
124
|
+
on a multi-file package? STOP, dispatch the remainder (or the whole
|
|
125
|
+
package for review), and treat what you wrote as input to the specialist,
|
|
126
|
+
not as a fait accompli.
|
|
127
|
+
- A complete feature never arrives in the lead's own diffs. If your final
|
|
128
|
+
report would say "I wrote X, Y, Z" — that is a triage failure, not
|
|
129
|
+
efficiency.
|
|
130
|
+
|
|
116
131
|
## Shared blackboard (file ownership + your dispatch manifest)
|
|
117
132
|
Sub-agents cannot message each other live; the blackboard is their shared
|
|
118
133
|
memory and YOU are the router — you decide who writes what and who reads
|
|
119
134
|
what (root path is appended at the end of this prompt):
|
|
120
|
-
-
|
|
135
|
+
- SESSION ISOLATION: this conversation owns exactly ONE session folder
|
|
136
|
+
\`<root>/<session-key>/\` (compact clock timestamp, created on your first
|
|
137
|
+
board write, reused for every later task here — see the resolved-root
|
|
138
|
+
section). Never touch or reuse a session folder another conversation
|
|
139
|
+
created; boards past their TTL stay on disk until the sweeper runs, and
|
|
140
|
+
the session layer is what keeps a fresh run from bumping into them.
|
|
141
|
+
- One task directory per multi-agent task: \`<root>/<session-key>/<task-slug>/\`.
|
|
121
142
|
- FILE OWNERSHIP — every artifact is one topic-sized file written by
|
|
122
143
|
exactly one agent: \`NN-<role>-<topic>.md\` (e.g.
|
|
123
144
|
\`01-architect-auth-design.md\`, \`03-reviewer-auth-r1.md\`). Keep files
|
|
@@ -147,10 +168,10 @@ what (root path is appended at the end of this prompt):
|
|
|
147
168
|
violation — send it back to write the file itself. Only if its reply
|
|
148
169
|
contains \`BLACKBOARD WRITE FAILED\` may you write the artifact as a
|
|
149
170
|
fallback; note the failure in MANIFEST.md so it is not silently tolerated.
|
|
150
|
-
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
171
|
+
- Do NOT delete the task directory after your report — TTL sweeping owns
|
|
172
|
+
reclamation (see Auto-cleanup in the resolved-root section). Finished
|
|
173
|
+
boards stay readable so the user can audit the run; leftovers from
|
|
174
|
+
crashed sessions sweep the same way.
|
|
154
175
|
|
|
155
176
|
## Feedback loop (mandatory before "done")
|
|
156
177
|
- Triage reviewer findings: **Critical/Major → spawn fix tasks** on the todo
|
package/dist/agents.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,wEAAwE;AACxE,+DAA+D;AAC/D,wEAAwE;AACxE,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;oCAoBO,CAAA;AAEpC,wEAAwE;AACxE,wEAAwE;AACxE,wEAAwE;AACxE,MAAM,QAAQ,GAAgB;IAC5B,IAAI,EAAE,SAAS;IACf,WAAW,EACT,2EAA2E;QAC3E,qEAAqE;QACrE,2EAA2E;QAC3E,2EAA2E;QAC3E,4BAA4B;IAC9B,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":"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"}
|
package/dist/blackboard.d.ts
CHANGED
|
@@ -2,12 +2,17 @@
|
|
|
2
2
|
* Shared blackboard for sub-agent coordination + automatic maintenance.
|
|
3
3
|
*
|
|
4
4
|
* Sub-agents cannot message each other live (platform limitation), so
|
|
5
|
-
* TeamMode uses a file blackboard under
|
|
5
|
+
* TeamMode uses a file blackboard under
|
|
6
|
+
* `<repo>/.git/opencode-team/<session-key>/<task>/`:
|
|
7
|
+
* - <session-key> is a compact timestamp folder, one per conversation —
|
|
8
|
+
* a fresh conversation can never collide with a not-yet-swept board
|
|
9
|
+
* from an earlier one;
|
|
6
10
|
* - each agent writes its full deliverable to a designated file;
|
|
7
11
|
* - the team lead relays summaries + file paths in every dispatch;
|
|
8
|
-
* -
|
|
12
|
+
* - nobody deletes task directories by hand; the sweeper below reclaims
|
|
13
|
+
* them once idle past the TTL (sole cleanup path, by design).
|
|
9
14
|
*
|
|
10
|
-
* This module is the code-level
|
|
15
|
+
* This module is the code-level reclamation path, independent of the model:
|
|
11
16
|
* a sweeper removes task directories whose last activity is older than
|
|
12
17
|
* the TTL, at plugin startup and hourly in-process. Placing the board
|
|
13
18
|
* inside `.git/` guarantees the user's working tree and commits are never
|
|
@@ -31,8 +36,16 @@ export declare function teamRootFor(directory: string): string;
|
|
|
31
36
|
*/
|
|
32
37
|
export declare function resolveTtlMs(options?: Record<string, unknown>): number;
|
|
33
38
|
/**
|
|
34
|
-
* Remove idle
|
|
35
|
-
*
|
|
39
|
+
* Remove idle boards under `root`. Understands both layouts:
|
|
40
|
+
* - session-partitioned `<root>/<session-key>/<task>/`: stale tasks are
|
|
41
|
+
* pruned individually under a live session; an entirely idle session
|
|
42
|
+
* folder goes as a whole;
|
|
43
|
+
* - legacy flat `<root>/<task>/`: unchanged semantics — and if such a dir
|
|
44
|
+
* unexpectedly contains sub-directories, idle ones are pruned by the
|
|
45
|
+
* same rule (harmless hygiene, though counted as task dirs).
|
|
46
|
+
* Returns the number of task directories reclaimed; a wholesale session
|
|
47
|
+
* removal counts its task dirs (min 1, so a ghost empty stale session dir
|
|
48
|
+
* also counts 1). Never throws.
|
|
36
49
|
*/
|
|
37
50
|
export declare function sweepStale(root: string, ttlMs?: number): number;
|
|
38
51
|
/**
|
package/dist/blackboard.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blackboard.d.ts","sourceRoot":"","sources":["../src/blackboard.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"blackboard.d.ts","sourceRoot":"","sources":["../src/blackboard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAMH,kEAAkE;AAClE,eAAO,MAAM,gBAAgB,IAAI,CAAA;AACjC,eAAO,MAAM,cAAc,QAAyC,CAAA;AAQpE,wEAAwE;AACxE,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQzD;AAED,gDAAgD;AAChD,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAIrD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,MAAM,CAM1E;AAuCD;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAiB,GAAG,MAAM,CA6CvE;AAID;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,MAAM,EACjB,KAAK,SAAiB,GACrB,MAAM,CASR"}
|
package/dist/blackboard.js
CHANGED
|
@@ -2,12 +2,17 @@
|
|
|
2
2
|
* Shared blackboard for sub-agent coordination + automatic maintenance.
|
|
3
3
|
*
|
|
4
4
|
* Sub-agents cannot message each other live (platform limitation), so
|
|
5
|
-
* TeamMode uses a file blackboard under
|
|
5
|
+
* TeamMode uses a file blackboard under
|
|
6
|
+
* `<repo>/.git/opencode-team/<session-key>/<task>/`:
|
|
7
|
+
* - <session-key> is a compact timestamp folder, one per conversation —
|
|
8
|
+
* a fresh conversation can never collide with a not-yet-swept board
|
|
9
|
+
* from an earlier one;
|
|
6
10
|
* - each agent writes its full deliverable to a designated file;
|
|
7
11
|
* - the team lead relays summaries + file paths in every dispatch;
|
|
8
|
-
* -
|
|
12
|
+
* - nobody deletes task directories by hand; the sweeper below reclaims
|
|
13
|
+
* them once idle past the TTL (sole cleanup path, by design).
|
|
9
14
|
*
|
|
10
|
-
* This module is the code-level
|
|
15
|
+
* This module is the code-level reclamation path, independent of the model:
|
|
11
16
|
* a sweeper removes task directories whose last activity is older than
|
|
12
17
|
* the TTL, at plugin startup and hourly in-process. Placing the board
|
|
13
18
|
* inside `.git/` guarantees the user's working tree and commits are never
|
|
@@ -57,15 +62,21 @@ export function resolveTtlMs(options = {}) {
|
|
|
57
62
|
}
|
|
58
63
|
return DEFAULT_TTL_MS;
|
|
59
64
|
}
|
|
60
|
-
/**
|
|
61
|
-
|
|
65
|
+
/**
|
|
66
|
+
* Latest mtime within `dir`, looking through up to `levels` sub-directory
|
|
67
|
+
* layers (artifacts live one level below a task dir, so 1 suffices per
|
|
68
|
+
* task and 2 from the session/root level).
|
|
69
|
+
*/
|
|
70
|
+
function lastActivity(dir, levels = 0) {
|
|
62
71
|
try {
|
|
63
72
|
let latest = fs.statSync(dir).mtimeMs;
|
|
64
73
|
for (const entry of fs.readdirSync(dir)) {
|
|
65
74
|
try {
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
75
|
+
const child = path.join(dir, entry);
|
|
76
|
+
const st = fs.statSync(child);
|
|
77
|
+
const seen = st.isDirectory() && levels > 0 ? lastActivity(child, levels - 1) : st.mtimeMs;
|
|
78
|
+
if (seen > latest)
|
|
79
|
+
latest = seen;
|
|
69
80
|
}
|
|
70
81
|
catch {
|
|
71
82
|
/* raced deletion — ignore */
|
|
@@ -78,8 +89,27 @@ function lastActivity(dir) {
|
|
|
78
89
|
}
|
|
79
90
|
}
|
|
80
91
|
/**
|
|
81
|
-
*
|
|
82
|
-
*
|
|
92
|
+
* True when a directory tree shows no activity within the TTL.
|
|
93
|
+
* `levels` must reach down to the artifact files: 1 for a task directory
|
|
94
|
+
* (files sit directly inside), 2 for a session directory (task dirs are
|
|
95
|
+
* one level deeper — depth 1 here would miss in-place rewrites and let a
|
|
96
|
+
* whole live session be reclaimed; regression-pinned by test fixture).
|
|
97
|
+
*/
|
|
98
|
+
function isStale(dir, now, ttlMs, levels) {
|
|
99
|
+
const seen = lastActivity(dir, levels);
|
|
100
|
+
return seen !== 0 && now - seen > ttlMs;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Remove idle boards under `root`. Understands both layouts:
|
|
104
|
+
* - session-partitioned `<root>/<session-key>/<task>/`: stale tasks are
|
|
105
|
+
* pruned individually under a live session; an entirely idle session
|
|
106
|
+
* folder goes as a whole;
|
|
107
|
+
* - legacy flat `<root>/<task>/`: unchanged semantics — and if such a dir
|
|
108
|
+
* unexpectedly contains sub-directories, idle ones are pruned by the
|
|
109
|
+
* same rule (harmless hygiene, though counted as task dirs).
|
|
110
|
+
* Returns the number of task directories reclaimed; a wholesale session
|
|
111
|
+
* removal counts its task dirs (min 1, so a ghost empty stale session dir
|
|
112
|
+
* also counts 1). Never throws.
|
|
83
113
|
*/
|
|
84
114
|
export function sweepStale(root, ttlMs = DEFAULT_TTL_MS) {
|
|
85
115
|
let entries;
|
|
@@ -96,12 +126,37 @@ export function sweepStale(root, ttlMs = DEFAULT_TTL_MS) {
|
|
|
96
126
|
try {
|
|
97
127
|
if (!fs.statSync(dir).isDirectory())
|
|
98
128
|
continue;
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
129
|
+
if (isStale(dir, now, ttlMs, 2)) {
|
|
130
|
+
// Entire tree idle: legacy flat task dir, or a finished session.
|
|
131
|
+
let tasks = 0;
|
|
132
|
+
for (const child of fs.readdirSync(dir)) {
|
|
133
|
+
try {
|
|
134
|
+
if (fs.statSync(path.join(dir, child)).isDirectory())
|
|
135
|
+
tasks++;
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
/* raced — ignore */
|
|
139
|
+
}
|
|
140
|
+
}
|
|
103
141
|
fs.rmSync(dir, { recursive: true, force: true });
|
|
104
|
-
removed
|
|
142
|
+
removed += Math.max(1, tasks);
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
// Live tree: prune per-task dirs (session layout; legacy dirs have
|
|
146
|
+
// no directory children, so this loop is a no-op for them).
|
|
147
|
+
for (const child of fs.readdirSync(dir)) {
|
|
148
|
+
const task = path.join(dir, child);
|
|
149
|
+
try {
|
|
150
|
+
if (!fs.statSync(task).isDirectory())
|
|
151
|
+
continue;
|
|
152
|
+
if (!isStale(task, now, ttlMs, 1))
|
|
153
|
+
continue;
|
|
154
|
+
fs.rmSync(task, { recursive: true, force: true });
|
|
155
|
+
removed++;
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
/* raced — skip this task */
|
|
159
|
+
}
|
|
105
160
|
}
|
|
106
161
|
}
|
|
107
162
|
catch {
|
package/dist/blackboard.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blackboard.js","sourceRoot":"","sources":["../src/blackboard.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"blackboard.js","sourceRoot":"","sources":["../src/blackboard.ts"],"names":[],"mappings":"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"}
|
package/dist/commands.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AA8I/C,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAOlD,CAAA"}
|
package/dist/commands.js
CHANGED
|
@@ -113,7 +113,9 @@ $ARGUMENTS
|
|
|
113
113
|
- Code review → reviewer
|
|
114
114
|
- Testing → tester
|
|
115
115
|
- Research → researcher
|
|
116
|
-
5. Coordinate through the shared blackboard:
|
|
116
|
+
5. Coordinate through the shared blackboard: this conversation owns one
|
|
117
|
+
session folder (<root>/<session-key>/ — compact timestamp, created on
|
|
118
|
+
first board write), one task directory per task inside it; every
|
|
117
119
|
dispatch carries a manifest (Task / Reads: only the files needed /
|
|
118
120
|
Write to: one owned artifact file); artifacts are frozen — revisions are
|
|
119
121
|
new round-suffixed files; keep MANIFEST.md's \`## Current state\` header
|
|
@@ -124,7 +126,8 @@ $ARGUMENTS
|
|
|
124
126
|
escalate).
|
|
125
127
|
7. Collect all outputs, resolve conflicts, synthesize a final result.
|
|
126
128
|
8. Present a structured summary: changes, review/test verdict, remaining
|
|
127
|
-
assumptions and risks.
|
|
129
|
+
assumptions and risks. Leave the task blackboard directory in place —
|
|
130
|
+
the plugin's TTL sweeper reclaims idle boards; never delete it yourself.`,
|
|
128
131
|
};
|
|
129
132
|
/* ------------------------------------------------------------------ */
|
|
130
133
|
/* Export all commands keyed by name */
|
package/dist/commands.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,wEAAwE;AACxE,MAAM,QAAQ,GAAkB;IAC9B,WAAW,EACT,+FAA+F;IACjG,KAAK,EAAE,WAAW;IAClB,QAAQ,EAAE;;;;;;;;;;;;;kDAasC;CACjD,CAAA;AAED,wEAAwE;AACxE,MAAM,aAAa,GAAkB;IACnC,WAAW,EACT,0FAA0F;IAC5F,KAAK,EAAE,aAAa;IACpB,QAAQ,EAAE;;;;;;;;4DAQgD;CAC3D,CAAA;AAED,wEAAwE;AACxE,MAAM,UAAU,GAAkB;IAChC,WAAW,EACT,0EAA0E;IAC5E,KAAK,EAAE,UAAU;IACjB,QAAQ,EAAE;;;;;;;;;;;;;gEAaoD;CAC/D,CAAA;AAED,wEAAwE;AACxE,MAAM,QAAQ,GAAkB;IAC9B,WAAW,EACT,2EAA2E;IAC7E,KAAK,EAAE,QAAQ;IACf,QAAQ,EAAE;;;;;;;;;;;8BAWkB;CAC7B,CAAA;AAED,wEAAwE;AACxE,MAAM,YAAY,GAAkB;IAClC,WAAW,EACT,uEAAuE;IACzE,KAAK,EAAE,YAAY;IACnB,QAAQ,EAAE;;;;;;;;;;;0DAW8C;CACzD,CAAA;AAED,wEAAwE;AACxE,MAAM,OAAO,GAAkB;IAC7B,WAAW,EACT,mGAAmG;IACrG,KAAK,EAAE,MAAM;IACb,QAAQ,EAAE
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,wEAAwE;AACxE,MAAM,QAAQ,GAAkB;IAC9B,WAAW,EACT,+FAA+F;IACjG,KAAK,EAAE,WAAW;IAClB,QAAQ,EAAE;;;;;;;;;;;;;kDAasC;CACjD,CAAA;AAED,wEAAwE;AACxE,MAAM,aAAa,GAAkB;IACnC,WAAW,EACT,0FAA0F;IAC5F,KAAK,EAAE,aAAa;IACpB,QAAQ,EAAE;;;;;;;;4DAQgD;CAC3D,CAAA;AAED,wEAAwE;AACxE,MAAM,UAAU,GAAkB;IAChC,WAAW,EACT,0EAA0E;IAC5E,KAAK,EAAE,UAAU;IACjB,QAAQ,EAAE;;;;;;;;;;;;;gEAaoD;CAC/D,CAAA;AAED,wEAAwE;AACxE,MAAM,QAAQ,GAAkB;IAC9B,WAAW,EACT,2EAA2E;IAC7E,KAAK,EAAE,QAAQ;IACf,QAAQ,EAAE;;;;;;;;;;;8BAWkB;CAC7B,CAAA;AAED,wEAAwE;AACxE,MAAM,YAAY,GAAkB;IAClC,WAAW,EACT,uEAAuE;IACzE,KAAK,EAAE,YAAY;IACnB,QAAQ,EAAE;;;;;;;;;;;0DAW8C;CACzD,CAAA;AAED,wEAAwE;AACxE,MAAM,OAAO,GAAkB;IAC7B,WAAW,EACT,mGAAmG;IACrG,KAAK,EAAE,MAAM;IACb,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4EAgCgE;CAC3E,CAAA;AAED,wEAAwE;AACxE,wEAAwE;AACxE,wEAAwE;AAExE,MAAM,CAAC,MAAM,QAAQ,GAAkC;IACrD,WAAW,EAAE,QAAQ;IACrB,gBAAgB,EAAE,aAAa;IAC/B,aAAa,EAAE,UAAU;IACzB,WAAW,EAAE,QAAQ;IACrB,eAAe,EAAE,YAAY;IAC7B,UAAU,EAAE,OAAO;CACpB,CAAA"}
|
package/dist/index.d.ts
CHANGED
|
@@ -17,8 +17,13 @@
|
|
|
17
17
|
* Options (via the tuple plugin form):
|
|
18
18
|
* "plugin": [["@te-river/opencode-team-mode@latest", { "ttlDays": 7 }]]
|
|
19
19
|
* - `ttlDays` → blackboard auto-cleanup TTL; default 5.
|
|
20
|
-
* - `defaultAgent` → promote Team as the default agent (
|
|
21
|
-
*
|
|
20
|
+
* - `defaultAgent` → promote Team as the default agent (opt-in: set `true`
|
|
21
|
+
* to enable). Trade-off when NOT enabled: new chats
|
|
22
|
+
* start on the built-in `build` agent, but the picker
|
|
23
|
+
* keeps Team in plain alphabetical order — after `plan`
|
|
24
|
+
* (the default agent is pinned first; everything else
|
|
25
|
+
* sorts by name, so "team first" and "team after plan"
|
|
26
|
+
* are mutually exclusive).
|
|
22
27
|
*/
|
|
23
28
|
import type { OpenCodePlugin } from "./types.js";
|
|
24
29
|
declare const plugin: OpenCodePlugin;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAkB,MAAM,YAAY,CAAA;AA2BhE,QAAA,MAAM,MAAM,EAAE,cAyCb,CAAA;AAED,eAAe,MAAM,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -17,8 +17,13 @@
|
|
|
17
17
|
* Options (via the tuple plugin form):
|
|
18
18
|
* "plugin": [["@te-river/opencode-team-mode@latest", { "ttlDays": 7 }]]
|
|
19
19
|
* - `ttlDays` → blackboard auto-cleanup TTL; default 5.
|
|
20
|
-
* - `defaultAgent` → promote Team as the default agent (
|
|
21
|
-
*
|
|
20
|
+
* - `defaultAgent` → promote Team as the default agent (opt-in: set `true`
|
|
21
|
+
* to enable). Trade-off when NOT enabled: new chats
|
|
22
|
+
* start on the built-in `build` agent, but the picker
|
|
23
|
+
* keeps Team in plain alphabetical order — after `plan`
|
|
24
|
+
* (the default agent is pinned first; everything else
|
|
25
|
+
* sorts by name, so "team first" and "team after plan"
|
|
26
|
+
* are mutually exclusive).
|
|
22
27
|
*/
|
|
23
28
|
import { agents } from "./agents.js";
|
|
24
29
|
import { commands } from "./commands.js";
|
|
@@ -30,9 +35,14 @@ function blackboardNote(root, ttlDays) {
|
|
|
30
35
|
"",
|
|
31
36
|
"## Team Blackboard — resolved for this workspace",
|
|
32
37
|
`Root directory: \`${root}\``,
|
|
33
|
-
`-
|
|
34
|
-
|
|
35
|
-
`
|
|
38
|
+
`- Session isolation: on the FIRST board write of this conversation create a session`,
|
|
39
|
+
` folder \`<root>/<session-key>/\` where <session-key> is a compact clock timestamp`,
|
|
40
|
+
` (PowerShell: \`Get-Date -Format yyyyMMdd-HHmmss\`; POSIX: \`date +%Y%m%d-%H%M%S\`).`,
|
|
41
|
+
` Reuse that folder for every later task in the same conversation; never write into`,
|
|
42
|
+
` a session folder created by a different conversation.`,
|
|
43
|
+
`- Create exactly ONE task sub-directory per multi-agent task: \`<root>/<session-key>/<task-slug>/\`.`,
|
|
44
|
+
`- Auto-cleanup: the plugin sweeps task directories idle for more than ${ttlDays} days (at startup and hourly).`,
|
|
45
|
+
` This is the ONLY cleanup path — never delete task or session directories yourself.`,
|
|
36
46
|
].join("\n");
|
|
37
47
|
}
|
|
38
48
|
const plugin = {
|
|
@@ -67,8 +77,8 @@ const plugin = {
|
|
|
67
77
|
continue;
|
|
68
78
|
cfg.command[name] = def;
|
|
69
79
|
}
|
|
70
|
-
// ---------- make Team the default agent (opt-
|
|
71
|
-
const promote = options?.defaultAgent
|
|
80
|
+
// ---------- make Team the default agent (opt-in: defaultAgent:true)
|
|
81
|
+
const promote = options?.defaultAgent === true;
|
|
72
82
|
if (promote && (!cfg.default_agent || cfg.default_agent === "build")) {
|
|
73
83
|
cfg.default_agent = "team";
|
|
74
84
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@te-river/opencode-team-mode",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.4",
|
|
4
4
|
"description": "Team collaboration mode plugin for OpenCode Desktop — injects specialized agents (architect, reviewer, implementer, tester, researcher) and team workflow commands into your OpenCode workspace.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|