@hueyexe/opencode-ensemble 0.13.2 → 0.13.3

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,7 +6,7 @@
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-508%20passing-brightgreen.svg)]()
9
+ [![tests](https://img.shields.io/badge/tests-512%20passing-brightgreen.svg)]()
10
10
  [![TypeScript](https://img.shields.io/badge/TypeScript-strict-blue.svg)]()
11
11
  [![OpenCode SDK](https://img.shields.io/badge/deps-OpenCode%20SDK%20only-blue.svg)]()
12
12
  [![license](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
@@ -19,7 +19,7 @@ Plugin built on the public OpenCode SDK. No internal dependencies.
19
19
 
20
20
  ```json
21
21
  {
22
- "plugin": ["@hueyexe/opencode-ensemble@0.13.2"]
22
+ "plugin": ["@hueyexe/opencode-ensemble@0.13.3"]
23
23
  }
24
24
  ```
25
25
 
@@ -140,7 +140,7 @@ Add to your OpenCode config with a pinned version. Project-level or global.
140
140
 
141
141
  ```json
142
142
  {
143
- "plugin": ["@hueyexe/opencode-ensemble@0.13.2"]
143
+ "plugin": ["@hueyexe/opencode-ensemble@0.13.3"]
144
144
  }
145
145
  ```
146
146
 
@@ -148,7 +148,7 @@ Add to your OpenCode config with a pinned version. Project-level or global.
148
148
 
149
149
  ```json
150
150
  {
151
- "plugin": ["@hueyexe/opencode-ensemble@0.13.2"]
151
+ "plugin": ["@hueyexe/opencode-ensemble@0.13.3"]
152
152
  }
153
153
  ```
154
154
 
@@ -410,7 +410,7 @@ Same coordination model (shared tasks, peer messaging, lead coordination) with s
410
410
  ```bash
411
411
  bun install
412
412
  bun run typecheck
413
- bun test # 508 tests
413
+ bun test # 512 tests
414
414
  bun run build
415
415
  ```
416
416
 
package/dist/index.js CHANGED
@@ -1,12 +1,16 @@
1
1
  // @bun
2
2
  var __defProp = Object.defineProperty;
3
+ var __returnValue = (v) => v;
4
+ function __exportSetter(name, newValue) {
5
+ this[name] = __returnValue.bind(null, newValue);
6
+ }
3
7
  var __export = (target, all) => {
4
8
  for (var name in all)
5
9
  __defProp(target, name, {
6
10
  get: all[name],
7
11
  enumerable: true,
8
12
  configurable: true,
9
- set: (newValue) => all[name] = () => newValue
13
+ set: __exportSetter.bind(all, name)
10
14
  });
11
15
  };
12
16
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
@@ -15983,7 +15987,7 @@ function buildLeadSystemPrompt(db, teamId, config2) {
15983
15987
  }
15984
15988
  lines.push(`If user picks "I'll choose per agent", ask for each agent's model individually before each team_spawn call.`, "Pass the chosen model via the model parameter on each team_spawn call.");
15985
15989
  }
15986
- lines.push("", "Spawn teammates ONE AT A TIME. Wait for each tool result before spawning the next.", "This avoids git worktree contention. Once all are spawned, wait for their messages.", "", "Teammates work asynchronously and message you when done.", "Do NOT poll team_status or team_tasks_list repeatedly \u2014 wait for messages.", "After spawning all teammates, tell the user what you've set up and wait.", "When all teammates finish, summarize results and suggest next steps.", "", "MERGE WORKFLOW:", "After a teammate finishes and you shut them down, use team_merge to merge their branch.", "Do NOT tell teammates to commit \u2014 they handle that themselves.", "Do NOT run git merge manually \u2014 use team_merge which squash-merges and unstages for you.", "team_cleanup will safety-net merge any branches you forgot, but prefer explicit team_merge.", "", "Before calling team_cleanup, verify teammates have committed their work.", "team_shutdown will warn you if a teammate has uncommitted changes.", "team_cleanup will block if any worktree has uncommitted changes \u2014 merge or commit first.");
15990
+ lines.push("", "Spawn teammates ONE AT A TIME. Wait for each tool result before spawning the next.", "This avoids git worktree contention. Once all are spawned, wait for their messages.", "Read-only agents (explore, plan) automatically skip worktree creation.", "For other agents that only need to read, pass worktree: false to avoid unnecessary isolation.", "", "Teammates work asynchronously and message you when done.", "Do NOT poll team_status or team_tasks_list repeatedly \u2014 wait for messages.", "After spawning all teammates, tell the user what you've set up and wait.", "When all teammates finish, summarize results and suggest next steps.", "", "MERGE WORKFLOW:", "After a teammate finishes and you shut them down, use team_merge to merge their branch.", "Do NOT tell teammates to commit \u2014 they handle that themselves.", "Do NOT run git merge manually \u2014 use team_merge which squash-merges and unstages for you.", "team_cleanup will safety-net merge any branches you forgot, but prefer explicit team_merge.", "", "Before calling team_cleanup, verify teammates have committed their work.", "team_shutdown will warn you if a teammate has uncommitted changes.", "team_cleanup will block if any worktree has uncommitted changes \u2014 merge or commit first.");
15987
15991
  return lines.join(`
15988
15992
  `);
15989
15993
  }
@@ -17064,7 +17068,8 @@ async function executeTeamSpawn(deps, args, sessionId) {
17064
17068
  const existing = deps.db.query("SELECT name FROM team_member WHERE team_id = ? AND name = ?").get(teamInfo.teamId, args.name);
17065
17069
  if (existing)
17066
17070
  throw new Error(`Teammate "${args.name}" already exists in team "${teamInfo.teamName}"`);
17067
- const useWorktree = args.worktree !== false && !isWorktreeDirectory(deps.directory);
17071
+ const isReadOnly = args.agent === "plan" || args.agent === "explore";
17072
+ const useWorktree = args.worktree !== false && !isReadOnly && !isWorktreeDirectory(deps.directory);
17068
17073
  const usePlanApproval = args.plan_approval === true;
17069
17074
  log(`spawn:start name=${args.name} agent=${args.agent} worktree=${useWorktree}`);
17070
17075
  let worktreeDir = null;
@@ -17104,7 +17109,6 @@ async function executeTeamSpawn(deps, args, sessionId) {
17104
17109
  log(`spawn:workspace:failed name=${args.name} err=${err instanceof Error ? err.message : String(err)}`);
17105
17110
  }
17106
17111
  }
17107
- const isReadOnly = args.agent === "plan" || args.agent === "explore";
17108
17112
  const TEAM_TOOLS = ["team_message", "team_broadcast", "team_tasks_list", "team_tasks_add", "team_tasks_complete", "team_claim"];
17109
17113
  const permission = [];
17110
17114
  if (worktreeDir) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hueyexe/opencode-ensemble",
3
- "version": "0.13.2",
3
+ "version": "0.13.3",
4
4
  "description": "Agent teams for OpenCode — parallel agents with peer-to-peer communication, shared tasks, and coordinated execution",
5
5
  "module": "src/index.ts",
6
6
  "main": "dist/index.js",
@@ -135,6 +135,8 @@ export function buildLeadSystemPrompt(db: Database, teamId: string, config?: Req
135
135
  "",
136
136
  "Spawn teammates ONE AT A TIME. Wait for each tool result before spawning the next.",
137
137
  "This avoids git worktree contention. Once all are spawned, wait for their messages.",
138
+ "Read-only agents (explore, plan) automatically skip worktree creation.",
139
+ "For other agents that only need to read, pass worktree: false to avoid unnecessary isolation.",
138
140
  "",
139
141
  "Teammates work asynchronously and message you when done.",
140
142
  "Do NOT poll team_status or team_tasks_list repeatedly — wait for messages.",
@@ -85,7 +85,8 @@ export async function executeTeamSpawn(
85
85
  .get(teamInfo.teamId, args.name)
86
86
  if (existing) throw new Error(`Teammate "${args.name}" already exists in team "${teamInfo.teamName}"`)
87
87
 
88
- const useWorktree = args.worktree !== false && !isWorktreeDirectory(deps.directory)
88
+ const isReadOnly = args.agent === "plan" || args.agent === "explore"
89
+ const useWorktree = args.worktree !== false && !isReadOnly && !isWorktreeDirectory(deps.directory)
89
90
  const usePlanApproval = args.plan_approval === true
90
91
 
91
92
  log(`spawn:start name=${args.name} agent=${args.agent} worktree=${useWorktree}`)
@@ -143,7 +144,6 @@ export async function executeTeamSpawn(
143
144
  // Permission rules on session.create are the hard gate (server-enforced).
144
145
  // For read-only agents, deny write tools and explicitly allow team tools.
145
146
  // For all agents with worktrees, allowlist the worktree path for edit/bash.
146
- const isReadOnly = args.agent === "plan" || args.agent === "explore"
147
147
  const TEAM_TOOLS = ["team_message", "team_broadcast", "team_tasks_list", "team_tasks_add", "team_tasks_complete", "team_claim"] as const
148
148
  const permission: PermissionRule[] = []
149
149