@hueyexe/opencode-ensemble 0.17.0 → 0.20.0

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 CHANGED
@@ -6,24 +6,24 @@
6
6
 
7
7
  [![npm version](https://img.shields.io/npm/v/@hueyexe/opencode-ensemble.svg)](https://www.npmjs.com/package/@hueyexe/opencode-ensemble)
8
8
  [![npm downloads](https://img.shields.io/npm/dm/@hueyexe/opencode-ensemble.svg)](https://www.npmjs.com/package/@hueyexe/opencode-ensemble)
9
- [![tests](https://img.shields.io/badge/tests-666%20passing-brightgreen.svg)]()
9
+ [![CI](https://github.com/hueyexe/opencode-ensemble/actions/workflows/ci.yml/badge.svg)](https://github.com/hueyexe/opencode-ensemble/actions/workflows/ci.yml)
10
10
  [![TypeScript](https://img.shields.io/badge/TypeScript-strict-blue.svg)]()
11
- [![OpenCode SDK](https://img.shields.io/badge/deps-OpenCode%20SDK%20only-blue.svg)]()
11
+ [![deps](https://img.shields.io/badge/deps-runtime%3A%20OpenCode%20SDKs-blue.svg)]()
12
12
  [![license](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
13
13
 
14
14
  Run parallel AI agents in OpenCode. Each agent gets its own session, context window, and task. They coordinate through messaging and a shared task board.
15
15
 
16
- Plugin built on the public OpenCode SDK. No internal dependencies.
16
+ Built on the public OpenCode SDKs — no OpenCode internals. Runtime dependencies are the three OpenCode SDK packages (`@opencode-ai/sdk`, `@opencode-ai/plugin`, `@opencode/plugin`). The bundled TUI companion additionally uses SolidJS and OpenTUI, provided by the OpenCode host and declared as peer dependencies.
17
17
 
18
18
  ## Quick Start
19
19
 
20
- ```json
21
- {
22
- "plugin": ["@hueyexe/opencode-ensemble@0.16.0"]
23
- }
20
+ Install the plugin and you're done:
21
+
22
+ ```sh
23
+ opencode plugin add @hueyexe/opencode-ensemble@0.18.0
24
24
  ```
25
25
 
26
- Add to your `opencode.json`, restart OpenCode, and ask it to do something that benefits from parallel work. The agent handles the rest. See [Install](#install) for full setup including worktree permissions.
26
+ Then restart OpenCode and ask it to do something that benefits from parallel work. The agent handles the rest. See [Install](#install) for worktree permissions and other options.
27
27
 
28
28
  ## What actually happens
29
29
 
@@ -40,10 +40,10 @@ The lead agent:
40
40
  2. Adds independent tasks first and records the generated task IDs.
41
41
  3. Adds dependent QA and review tasks with `depends_on` using real returned IDs.
42
42
  4. Spawns a small team with explicit roles:
43
- - scout: explore agent, worktree disabled, model openai/gpt-5.3-codex-spark
44
- - api-dev: build agent, own worktree, model anthropic/claude-opus-4-7, plan_approval: true
45
- - qa: build agent, own worktree, model anthropic/claude-sonnet-4-6
46
- - reviewer: explore agent, worktree disabled, model openai/gpt-5.3-codex-spark
43
+ - scout: explore agent, worktree disabled, model openai/gpt-5-mini (example)
44
+ - api-dev: build agent, own worktree, model anthropic/claude-opus-4-7 (example), plan_approval: true
45
+ - qa: build agent, own worktree, model anthropic/claude-opus-4-7 (example)
46
+ - reviewer: explore agent, worktree disabled, model openai/gpt-5-mini (example)
47
47
  ```
48
48
 
49
49
  The lead uses the task board to make sequencing visible. Record the returned task IDs before creating dependent tasks:
@@ -79,7 +79,7 @@ team_spawn({
79
79
  name: "scout",
80
80
  agent: "explore",
81
81
  worktree: false,
82
- model: "openai/gpt-5.3-codex-spark",
82
+ model: "openai/gpt-5-mini",
83
83
  claim_task: "task_abc123",
84
84
  prompt: "Trace the checkout webhook flow. Report the files, data model, existing tests, and the smallest safe implementation plan. Do not edit files.",
85
85
  })
@@ -177,21 +177,31 @@ The plugin uses SQLite via the host's runtime adapter:
177
177
 
178
178
  ### 1. Add the plugin
179
179
 
180
- Add to your OpenCode config with a pinned version. Project-level or global.
180
+ The simplest install is the CLI (npm registry or Git package specifiers both work):
181
+
182
+ ```sh
183
+ opencode plugin add @hueyexe/opencode-ensemble@0.18.0
184
+ ```
185
+
186
+ This installs globally and writes the config entry for you. To update later: `opencode plugin update @hueyexe/opencode-ensemble`.
187
+
188
+ **Manual config** — add to your OpenCode config with a pinned version. Project-level or global.
181
189
 
182
190
  **Project-level** (`opencode.json` in your project root):
183
191
 
184
- ```json
192
+ ```jsonc
185
193
  {
186
- "plugin": ["@hueyexe/opencode-ensemble@0.16.0"]
194
+ // OpenCode v2:
195
+ "plugins": ["@hueyexe/opencode-ensemble@0.18.0"]
187
196
  }
188
197
  ```
189
198
 
190
- **Global** (`~/.config/opencode/opencode.json`):
199
+ **Global** (`~/.config/opencode/opencode.json`): same entry.
191
200
 
192
- ```json
201
+ ```jsonc
193
202
  {
194
- "plugin": ["@hueyexe/opencode-ensemble@0.16.0"]
203
+ // OpenCode v1:
204
+ "plugin": ["@hueyexe/opencode-ensemble@0.18.0"]
195
205
  }
196
206
  ```
197
207
 
@@ -211,7 +221,19 @@ Then restart OpenCode.
211
221
 
212
222
  Teammates work in git worktrees outside your project directory. Without this permission, OpenCode will prompt you to approve every file operation in a teammate's worktree.
213
223
 
214
- Add to your OpenCode config (`~/.config/opencode/opencode.json`):
224
+ Add to your OpenCode config (`~/.config/opencode/opencode.json`).
225
+
226
+ OpenCode v2 (`permissions` array):
227
+
228
+ ```jsonc
229
+ {
230
+ "permissions": [
231
+ { "action": "external_directory", "resource": "~/.local/share/opencode/worktree/**", "effect": "allow" }
232
+ ]
233
+ }
234
+ ```
235
+
236
+ OpenCode v1 (`permission` map):
215
237
 
216
238
  ```json
217
239
  {
@@ -227,15 +249,15 @@ This is required. Without it, you'll see "Permission required — Access externa
227
249
 
228
250
  ### Local development
229
251
 
230
- To test a local build, point your plugin config at the built output:
252
+ Configure the worktree as a local plugin (v2 loads the source entry; v1 uses the `server()` export from the same file):
231
253
 
232
- ```json
254
+ ```jsonc
233
255
  {
234
- "plugin": ["/path/to/opencode-ensemble/dist/index.js"]
256
+ "plugins": [{ "package": "/path/to/opencode-ensemble" }]
235
257
  }
236
258
  ```
237
259
 
238
- Build with `bun run build`, then restart OpenCode to pick up changes.
260
+ No build step needed for local testing — but run `bun run typecheck && bun test && bun run build` before committing. Restart OpenCode (or wait for hot-reload) to pick up changes.
239
261
 
240
262
  ## Tools
241
263
 
@@ -251,7 +273,7 @@ Build with `bun run build`, then restart OpenCode to pick up changes.
251
273
  | `team_merge` | Merge a shutdown teammate's branch into working directory (unstaged). Blocks if you have local changes to overlapping files. |
252
274
  | `team_cleanup` | Remove the current team when done. Safety-net merges forgotten branches. With `purge`, previews archived-team deletion and returns exact approval labels plus a confirmation token. |
253
275
  | `team_status` | See all members, their status, and a task summary. |
254
- | `team_view` | Switch the TUI to a teammate's session. |
276
+ | `team_view` | Resolve a teammate's session; pass `navigate: true` to switch the TUI to it (opt-in — only when the user explicitly asks). |
255
277
 
256
278
  Archived-team purge is intentionally two-step. First call `team_cleanup` with `purge` to get a preview, exact approval and denial option labels, and `confirm_token`; no data is deleted. Stale archived worktree/workspace references and stale Ensemble-owned branches are counted in the preview and cleaned during confirmed purge. Arbitrary non-Ensemble branches still block purge for safety. The lead must then use the question tool with those exact options. Only after the user selects the exact approval option should it call `team_cleanup` again with the same `purge`, `confirm_purge: true`, and the preview token.
257
279
 
@@ -274,17 +296,15 @@ Archived-team purge is intentionally two-step. First call `team_cleanup` with `p
274
296
 
275
297
  ## What you see in the TUI
276
298
 
277
- The plugin works within OpenCode's existing TUI. For deeper visibility, open the [dashboard](#dashboard) at `http://localhost:4747`.
299
+ The plugin works within OpenCode's existing UI on every client (terminal, desktop, web): tools, approvals, messages, and the [dashboard](#dashboard) at `http://localhost:4747` all live server-side.
278
300
 
279
301
  What you get:
280
302
 
281
- - **Toast notifications** when teammates spawn, finish, error, shut down, or get rate-limited
282
- - **Working progress toasts** showing who's still active after every status change (e.g. "Working: alice, bob (2/3)")
283
- - **Rich tool titles** in the sidebar (e.g. "Spawned alice (build)", "Message -> bob", "Task board (3 tasks)")
284
- - **Session switching** via `team_view` to see any teammate's full chat log
285
- - **Status checks** via `team_status` for a snapshot of the whole team
286
-
287
- Teammate messages arrive in the lead's session as `[Team message from alice]: ...` blocks. They look like user messages because that's how `promptAsync` delivery works. Content is clearly labeled with the sender's name.
303
+ - **Team state in context** — the lead's system prompt carries member statuses and task counts, so it stays aware across turns including after compaction.
304
+ - **Teammate messages** arriving in the lead's session as labeled blocks with the sender's name.
305
+ - **Rich tool titles** in the sidebar (e.g. "Spawned alice (build)", "Message -> bob", "Task board (3 tasks)").
306
+ - **Status checks** via `team_status` for a snapshot of the whole team.
307
+ - **Terminal extras** (terminal only): a sidebar widget with live member status and task counts via the bundled `./tui` companion, loaded automatically with the plugin. `team_view` reports the teammate session by default; ask for it and `navigate: true` switches the TUI there (ctrl+p to return).
288
308
 
289
309
  ## Architecture
290
310
 
@@ -436,7 +456,9 @@ STALL_THRESHOLD_MS=0
436
456
 
437
457
  ## Known limitations
438
458
 
439
- - **Teammate messages may switch the lead's agent mode.** When a teammate sends a message back to the lead via `promptAsync`, OpenCode starts a new prompt loop that can switch the lead from plan/explore mode into build mode. This is a server-level behavior that the plugin cannot override. The lead's mode will restore when you send your next message.
459
+ - **Teammate messages may switch the lead's agent mode (v1).** When a teammate sends a message back to the lead, OpenCode can start the next prompt loop in build mode even if the lead was in plan/explore mode. Tracked upstream; the lead's mode restores when you send your next message. On v2, pass an explicit `model` on `team_spawn` so teammates never inherit the server default.
460
+ - **Session switching is opt-in (v2).** `team_view` reports the teammate's session ID by default; it switches the user's client only when asked for with `navigate: true` — agents never hijack the client unprompted. The live sidebar (terminal only) shows member status on every client's dashboard at `http://localhost:4747`.
461
+ - **Per-session shell env is unavailable (v2).** The v2 shell hook carries no session ID, so `ENSEMBLE_*` variables are not injected into teammate shells. Team identity travels in prompts and tool calls instead.
440
462
 
441
463
  ## How this differs from Claude Code agent teams
442
464
 
@@ -455,7 +477,7 @@ Same coordination model (shared tasks, peer messaging, lead coordination) with s
455
477
  ```bash
456
478
  bun install
457
479
  bun run typecheck
458
- bun test # 623 tests
480
+ bun test # 835 tests
459
481
  bun run build
460
482
  ```
461
483