@hueyexe/opencode-ensemble 0.5.0 → 0.6.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
@@ -1,21 +1,21 @@
1
1
  # OpenCode Ensemble
2
2
 
3
- Run a team of parallel AI agents in OpenCode. Each agent gets its own session, context window, and task. They coordinate through messaging and a shared task board.
3
+ 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.
4
4
 
5
- Built as a plugin on the public OpenCode SDK. Zero internal dependencies.
5
+ Plugin built on the public OpenCode SDK. No internal dependencies.
6
6
 
7
7
  ## What actually happens
8
8
 
9
- You ask the agent to do something complex. The agent decides it needs help, creates a team, and spawns teammates. Each teammate gets its own OpenCode session with a fresh context window and a specific task.
9
+ You ask the agent to do something complex. It creates a team, spawns teammates, and they work in parallel. Each teammate runs in its own OpenCode session with a fresh context window.
10
10
 
11
- Here's a real interaction:
11
+ A real interaction:
12
12
 
13
13
  ```
14
14
  You: "Add input validation to all API endpoints and write tests for each one."
15
15
 
16
16
  The lead agent:
17
17
  1. Creates a team called "validation"
18
- 2. Adds tasks to the shared board: one per endpoint
18
+ 2. Adds tasks to the shared board, one per endpoint
19
19
  3. Spawns 3 teammates:
20
20
  - alice: validate user endpoints (POST /users, PUT /users/:id)
21
21
  - bob: validate order endpoints (POST /orders, PUT /orders/:id)
@@ -23,7 +23,7 @@ The lead agent:
23
23
  4. carol's tasks depend on alice and bob finishing first
24
24
  ```
25
25
 
26
- From here, things happen in parallel. Alice and bob work simultaneously in their own sessions. You see toast notifications as they make progress:
26
+ Alice and bob work simultaneously. You see toast notifications as they progress:
27
27
 
28
28
  ```
29
29
  [toast] Teammate alice spawned (build)
@@ -31,18 +31,18 @@ From here, things happen in parallel. Alice and bob work simultaneously in their
31
31
  [toast] Teammate carol spawned (build)
32
32
  ```
33
33
 
34
- The teammates talk to each other and to the lead:
34
+ Teammates talk to each other and to the lead:
35
35
 
36
36
  ```
37
37
  alice -> lead: "User validation done. Added zod schemas to POST /users and PUT /users/:id."
38
- bob -> lead: "Order validation done. Found an edge case in PUT /orders/:id — negative quantities were allowed."
38
+ bob -> lead: "Order validation done. Found an edge case in PUT /orders/:id, negative quantities were allowed."
39
39
  bob -> alice: "Did you handle email format validation? I want to match the pattern for order contact emails."
40
- alice -> bob: "Yes, using z.string().email() — see src/validators/user.ts line 12."
40
+ alice -> bob: "Yes, using z.string().email(). See src/validators/user.ts line 12."
41
41
  ```
42
42
 
43
- When alice and bob finish, carol's blocked tasks unblock automatically. Carol starts writing tests using the actual validation schemas alice and bob created.
43
+ When alice and bob finish, carol's blocked tasks unblock automatically. Carol starts writing tests using the validation schemas they created.
44
44
 
45
- The lead keeps you updated throughout. You can check on things at any time:
45
+ Check on things at any time:
46
46
 
47
47
  ```
48
48
  You: "How's the team doing?"
@@ -56,7 +56,7 @@ Lead calls team_status:
56
56
  Tasks: 5 total (3 completed, 1 in_progress, 1 pending)
57
57
  ```
58
58
 
59
- Want to see what carol is actually doing? The lead can switch your view to her session:
59
+ Want to see what carol is doing? The lead can switch your view to her session:
60
60
 
61
61
  ```
62
62
  You: "Show me what carol is working on."
@@ -79,9 +79,9 @@ Lead: "All validation and tests are complete. 5 endpoints validated,
79
79
 
80
80
  ## Install
81
81
 
82
- Add the plugin to your OpenCode config. This can be project-level or global.
82
+ Add the plugin to your OpenCode config. Project-level or global.
83
83
 
84
- **Project-level** — `opencode.json` in your project root:
84
+ **Project-level** (`opencode.json` in your project root):
85
85
 
86
86
  ```json
87
87
  {
@@ -89,7 +89,7 @@ Add the plugin to your OpenCode config. This can be project-level or global.
89
89
  }
90
90
  ```
91
91
 
92
- **Global** — `~/.config/opencode/opencode.json`:
92
+ **Global** (`~/.config/opencode/opencode.json`):
93
93
 
94
94
  ```json
95
95
  {
@@ -97,7 +97,7 @@ Add the plugin to your OpenCode config. This can be project-level or global.
97
97
  }
98
98
  ```
99
99
 
100
- That's it. OpenCode auto-installs npm plugins at startup (cached in `~/.cache/opencode/node_modules/`). No `npm install` or `bun add` needed.
100
+ OpenCode auto-installs npm plugins at startup (cached in `~/.cache/opencode/node_modules/`). No `npm install` needed.
101
101
 
102
102
  ### Local development
103
103
 
@@ -115,15 +115,15 @@ export { default } from "/path/to/opencode-ensemble/src/index.ts"
115
115
 
116
116
  ## Tools
117
117
 
118
- 13 tools total. The lead has all of them. Teammates get 6 (messaging + tasks).
118
+ 13 tools. The lead has all of them. Teammates get 6 (messaging + tasks).
119
119
 
120
120
  **Team lifecycle** (lead only)
121
121
 
122
122
  | Tool | What it does |
123
123
  |------|-------------|
124
124
  | `team_create` | Create a team. Caller becomes the lead. |
125
- | `team_spawn` | Start a new teammate with a task. |
126
- | `team_shutdown` | Ask a teammate to stop. |
125
+ | `team_spawn` | Start a new teammate with a task. Supports `plan_approval` mode. |
126
+ | `team_shutdown` | Ask a teammate to stop. Supports `force` flag for immediate abort. |
127
127
  | `team_cleanup` | Remove the team when done. |
128
128
  | `team_status` | See all members, their status, and a task summary. |
129
129
  | `team_view` | Switch the TUI to a teammate's session. |
@@ -132,7 +132,7 @@ export { default } from "/path/to/opencode-ensemble/src/index.ts"
132
132
 
133
133
  | Tool | What it does |
134
134
  |------|-------------|
135
- | `team_message` | Send a direct message to a teammate or the lead. |
135
+ | `team_message` | Send a direct message to a teammate or the lead. Also handles plan approval/rejection. |
136
136
  | `team_broadcast` | Message everyone on the team. |
137
137
  | `team_results` | Retrieve full message content (messages to lead are truncated on delivery). |
138
138
 
@@ -147,28 +147,31 @@ export { default } from "/path/to/opencode-ensemble/src/index.ts"
147
147
 
148
148
  ## What you see in the TUI
149
149
 
150
- The plugin works within OpenCode's existing TUI. There's no custom team panel (that requires core TUI changes, which are [in progress upstream](https://github.com/sst/opencode)).
150
+ The plugin works within OpenCode's existing TUI. No custom team panel (that requires core TUI changes, which are [in progress upstream](https://github.com/sst/opencode)).
151
151
 
152
- What you do get:
152
+ What you get:
153
153
 
154
154
  - **Toast notifications** when teammates spawn, finish, error, shut down, or get rate-limited
155
155
  - **Working progress toasts** showing who's still active after every status change (e.g. "Working: alice, bob (2/3)")
156
156
  - **Rich tool titles** in the sidebar (e.g. "Spawned alice (build)", "Message -> bob", "Task board (3 tasks)")
157
157
  - **Session switching** via `team_view` to see any teammate's full chat log
158
- - **Status checks** via `team_status` for a snapshot of the whole team (also fires a toast)
158
+ - **Status checks** via `team_status` for a snapshot of the whole team
159
159
 
160
- Teammate messages arrive in the lead's session as `[Team message from alice]: ...` blocks. They look like user messages in the TUI because that's how `promptAsync` delivery works. The content is clearly labeled with the sender's name.
160
+ 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.
161
161
 
162
162
  ## Architecture
163
163
 
164
164
  - **SQLite** (`bun:sqlite`, WAL mode) for teams, members, tasks, and messages
165
165
  - **promptAsync** for message delivery: injects a message and starts the prompt loop in one call
166
- - **Git worktree isolation**: each teammate gets their own worktree by default, so multiple agents can edit files without conflicts. The lead merges branches after cleanup. Opt out with `worktree: false` for read-only agents.
166
+ - **Git worktree isolation**: each teammate gets their own worktree by default, so multiple agents can edit files without conflicts. Opt out with `worktree: false` for read-only agents.
167
+ - **System prompt injection**: the lead's system prompt includes team state (member statuses, task counts) on every LLM call. Teammates get a short role reminder.
168
+ - **Compaction safety**: team context is preserved when OpenCode compacts long conversations
169
+ - **Shell environment**: teammate shells get `ENSEMBLE_TEAM`, `ENSEMBLE_MEMBER`, `ENSEMBLE_ROLE`, and `ENSEMBLE_BRANCH` variables
167
170
  - **Sub-agent isolation**: teammates' sub-agents can't use team tools (parent chain tracking, max depth 10)
168
171
  - **Crash recovery**: stale busy members marked as errored on restart, orphaned sessions aborted, orphaned worktrees cleaned up, undelivered messages redelivered
169
172
  - **Spawn rollback**: if the initial prompt fails, the member, session, and worktree are all cleaned up
170
173
  - **Timeout watchdog**: teammates stuck busy beyond the TTL are automatically timed out and aborted
171
- - **Shutdown resilience**: abort failures handled gracefully, busy-after-shutdown triggers re-abort
174
+ - **Graceful shutdown**: busy teammates receive a shutdown message and finish their current work. Use `force: true` to abort immediately.
172
175
  - **Rate limiting**: token bucket (configurable via `OPENCODE_ENSEMBLE_RATE_LIMIT`, default 10 tokens/sec)
173
176
 
174
177
  ## Configuration
@@ -187,34 +190,38 @@ OPENCODE_ENSEMBLE_TIMEOUT=3600000
187
190
  OPENCODE_ENSEMBLE_TIMEOUT=0
188
191
  ```
189
192
 
190
- ### Best practices
193
+ ## Best practices
191
194
 
192
- - Start with 2-4 teammates for most tasks. More agents means more coordination overhead.
193
- - Give each teammate 3-5 specific, self-contained tasks. Vague prompts produce vague results.
194
- - Start with research before implementation — spawn an explore agent first to understand the codebase, then spawn build agents with that context.
195
- - Use `worktree: false` for read-only agents (research, review, code analysis). They don't need file isolation.
196
- - Use `plan_approval: true` for risky changes — the teammate sends a plan first, you review and approve before they write any code.
197
- - Let the lead coordinate. Don't micromanage teammates — they message you when done or when they're blocked.
198
- - After spawning, tell the user what you've set up and wait for results. Don't poll `team_status` in a loop.
195
+ - Start with 2-3 teammates. More agents means more coordination overhead.
196
+ - Give each teammate specific, self-contained tasks. Vague prompts produce vague results.
197
+ - Spawn an explore agent first to understand the codebase, then spawn build agents with that context.
198
+ - Use `worktree: false` for read-only agents (research, review, code analysis).
199
+ - Use `plan_approval: true` for risky changes. The teammate sends a plan first, you review and approve before they write any code.
200
+ - Don't micromanage. Teammates message you when done or when they're blocked.
201
+ - Don't poll `team_status` in a loop. Wait for messages.
199
202
 
200
- ### How this differs from Claude Code agent teams
203
+ ## Known limitations
201
204
 
202
- Claude Code has built-in agent teams. This plugin takes the same coordination model (shared tasks, peer messaging, lead coordination) and adds:
205
+ - **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.
203
206
 
204
- - **Git worktree isolation by default** — each teammate gets their own branch, no merge conflicts between parallel agents
205
- - **System prompt injection** — the lead's system prompt is updated with team state (member statuses, task progress) so it stays aware across turns
206
- - **Compaction safety** — team context is preserved when sessions get long and OpenCode compacts the conversation
207
- - **Team-aware shell environment** — teammate shells get `ENSEMBLE_TEAM`, `ENSEMBLE_MEMBER`, `ENSEMBLE_ROLE`, and `ENSEMBLE_BRANCH` variables
208
- - **Graceful shutdown** — teammates finish their current work before stopping, with a force flag for emergencies
209
- - **Plan approval mode** — review teammate plans before they write code, useful for risky or unfamiliar changes
210
- - **Works today as a plugin** — no waiting for upstream features, install and go
207
+ ## How this differs from Claude Code agent teams
208
+
209
+ Same coordination model (shared tasks, peer messaging, lead coordination) with some additions:
210
+
211
+ - **Git worktree isolation by default**: each teammate gets their own branch, no merge conflicts between parallel agents
212
+ - **System prompt injection**: the lead's system prompt is updated with team state so it stays aware across turns
213
+ - **Compaction safety**: team context is preserved when sessions get long
214
+ - **Team-aware shell environment**: `ENSEMBLE_TEAM`, `ENSEMBLE_MEMBER`, `ENSEMBLE_ROLE`, `ENSEMBLE_BRANCH`
215
+ - **Graceful shutdown**: teammates finish current work before stopping, with a force flag for emergencies
216
+ - **Plan approval mode**: review teammate plans before they write code
217
+ - **Works today as a plugin**: install and go, no upstream changes needed
211
218
 
212
219
  ## Development
213
220
 
214
221
  ```bash
215
222
  bun install
216
223
  bun run typecheck
217
- bun test # 144 tests
224
+ bun test # 286 tests
218
225
  bun run build
219
226
  ```
220
227