opencode-swarm 6.21.1 → 6.21.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/dist/cli/index.js CHANGED
@@ -29784,7 +29784,7 @@ function createSwarmTool(opts) {
29784
29784
  args: opts.args,
29785
29785
  execute: async (args, ctx) => {
29786
29786
  const directory = ctx?.directory ?? process.cwd();
29787
- return opts.execute(args, directory);
29787
+ return opts.execute(args, directory, ctx);
29788
29788
  }
29789
29789
  });
29790
29790
  }
@@ -35666,7 +35666,7 @@ var HELP_TEXT = [
35666
35666
 
35667
35667
  // src/cli/index.ts
35668
35668
  var CONFIG_DIR = path14.join(process.env.XDG_CONFIG_HOME || path14.join(os2.homedir(), ".config"), "opencode");
35669
- var OPENCODE_CONFIG_PATH = path14.join(CONFIG_DIR, "config.json");
35669
+ var OPENCODE_CONFIG_PATH = path14.join(CONFIG_DIR, "opencode.json");
35670
35670
  var PLUGIN_CONFIG_PATH = path14.join(CONFIG_DIR, "opencode-swarm.json");
35671
35671
  var PROMPTS_DIR = path14.join(CONFIG_DIR, "opencode-swarm");
35672
35672
  function ensureDir(dir) {
@@ -35692,9 +35692,16 @@ async function install() {
35692
35692
  `);
35693
35693
  ensureDir(CONFIG_DIR);
35694
35694
  ensureDir(PROMPTS_DIR);
35695
+ const LEGACY_CONFIG_PATH = path14.join(CONFIG_DIR, "config.json");
35695
35696
  let opencodeConfig = loadJson(OPENCODE_CONFIG_PATH);
35696
35697
  if (!opencodeConfig) {
35697
- opencodeConfig = {};
35698
+ const legacyConfig = loadJson(LEGACY_CONFIG_PATH);
35699
+ if (legacyConfig) {
35700
+ console.log("\u26A0 Migrating existing config from config.json to opencode.json...");
35701
+ opencodeConfig = legacyConfig;
35702
+ } else {
35703
+ opencodeConfig = {};
35704
+ }
35698
35705
  }
35699
35706
  if (!opencodeConfig.plugin) {
35700
35707
  opencodeConfig.plugin = [];
package/dist/index.js CHANGED
@@ -30346,7 +30346,7 @@ function createSwarmTool(opts) {
30346
30346
  args: opts.args,
30347
30347
  execute: async (args2, ctx) => {
30348
30348
  const directory = ctx?.directory ?? process.cwd();
30349
- return opts.execute(args2, directory);
30349
+ return opts.execute(args2, directory, ctx);
30350
30350
  }
30351
30351
  });
30352
30352
  }
@@ -38317,7 +38317,8 @@ var KNOWN_SWARM_PREFIXES = [
38317
38317
  "custom",
38318
38318
  "team",
38319
38319
  "project",
38320
- "swarm"
38320
+ "swarm",
38321
+ "synthetic"
38321
38322
  ];
38322
38323
  var SEPARATORS = ["_", "-", " "];
38323
38324
  function stripKnownSwarmPrefix(agentName) {
@@ -47268,15 +47269,23 @@ function createDelegationGateHook(config3) {
47268
47269
  session.qaSkipCount = 0;
47269
47270
  session.qaSkipTaskIds = [];
47270
47271
  }
47271
- if (hasReviewer && session.currentTaskId) {
47272
- try {
47273
- advanceTaskState(session, session.currentTaskId, "reviewer_run");
47274
- } catch {}
47272
+ if (hasReviewer && session.taskWorkflowStates) {
47273
+ for (const [taskId, state] of session.taskWorkflowStates) {
47274
+ if (state === "coder_delegated" || state === "pre_check_passed") {
47275
+ try {
47276
+ advanceTaskState(session, taskId, "reviewer_run");
47277
+ } catch {}
47278
+ }
47279
+ }
47275
47280
  }
47276
- if (hasReviewer && hasTestEngineer && session.currentTaskId) {
47277
- try {
47278
- advanceTaskState(session, session.currentTaskId, "tests_run");
47279
- } catch {}
47281
+ if (hasReviewer && hasTestEngineer && session.taskWorkflowStates) {
47282
+ for (const [taskId, state] of session.taskWorkflowStates) {
47283
+ if (state === "reviewer_run") {
47284
+ try {
47285
+ advanceTaskState(session, taskId, "tests_run");
47286
+ } catch {}
47287
+ }
47288
+ }
47280
47289
  }
47281
47290
  }
47282
47291
  }
@@ -47586,7 +47595,9 @@ function createDelegationTrackerHook(config3, guardrailsEnabled = true) {
47586
47595
  if (!isArchitect && guardrailsEnabled) {
47587
47596
  beginInvocation(input.sessionID, agentName);
47588
47597
  }
47589
- if (config3.hooks?.delegation_tracker === true && previousAgent && previousAgent !== agentName) {
47598
+ const delegationTrackerEnabled = config3.hooks?.delegation_tracker === true;
47599
+ const delegationGateEnabled = config3.hooks?.delegation_gate !== false;
47600
+ if ((delegationTrackerEnabled || delegationGateEnabled) && previousAgent && previousAgent !== agentName) {
47590
47601
  const entry = {
47591
47602
  from: previousAgent,
47592
47603
  to: agentName,
@@ -47597,7 +47608,9 @@ function createDelegationTrackerHook(config3, guardrailsEnabled = true) {
47597
47608
  }
47598
47609
  const chain = swarmState.delegationChains.get(input.sessionID);
47599
47610
  chain?.push(entry);
47600
- swarmState.pendingEvents++;
47611
+ if (delegationTrackerEnabled) {
47612
+ swarmState.pendingEvents++;
47613
+ }
47601
47614
  }
47602
47615
  };
47603
47616
  }
@@ -53438,13 +53451,13 @@ var phase_complete = createSwarmTool({
53438
53451
  summary: tool.schema.string().optional().describe("Optional summary of what was accomplished in this phase"),
53439
53452
  sessionID: tool.schema.string().optional().describe("Session ID for tracking state (auto-provided by plugin context)")
53440
53453
  },
53441
- execute: async (args2, directory) => {
53454
+ execute: async (args2, directory, ctx) => {
53442
53455
  let phaseCompleteArgs;
53443
53456
  try {
53444
53457
  phaseCompleteArgs = {
53445
53458
  phase: Number(args2.phase),
53446
53459
  summary: args2.summary !== undefined ? String(args2.summary) : undefined,
53447
- sessionID: args2.sessionID !== undefined ? String(args2.sessionID) : undefined
53460
+ sessionID: ctx?.sessionID ?? (args2.sessionID !== undefined ? String(args2.sessionID) : undefined)
53448
53461
  };
53449
53462
  } catch {
53450
53463
  return JSON.stringify({
@@ -59463,9 +59476,15 @@ function checkReviewerGate(taskId) {
59463
59476
  return { blocked: false, reason: "" };
59464
59477
  }
59465
59478
  }
59479
+ const stateEntries = [];
59480
+ for (const [sessionId, session] of swarmState.agentSessions) {
59481
+ const state = getTaskState(session, taskId);
59482
+ stateEntries.push(`${sessionId}: ${state}`);
59483
+ }
59484
+ const currentStateStr = stateEntries.length > 0 ? stateEntries.join(", ") : "no active sessions";
59466
59485
  return {
59467
59486
  blocked: true,
59468
- reason: `Task ${taskId} has not passed QA gates (state machine requires tests_run or complete, current state indicates gates not yet passed). Call mega_reviewer and mega_test_engineer before marking task as completed.`
59487
+ reason: `Task ${taskId} has not passed QA gates. Current state: [${currentStateStr}]. Required state: tests_run or complete. Do not write directly to plan files \u2014 use update_task_status after running mega_reviewer and mega_test_engineer.`
59469
59488
  };
59470
59489
  } catch {
59471
59490
  return { blocked: false, reason: "" };
@@ -59488,6 +59507,16 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
59488
59507
  errors: [taskIdError]
59489
59508
  };
59490
59509
  }
59510
+ if (args2.status === "in_progress") {
59511
+ for (const [_sessionId, session] of swarmState.agentSessions) {
59512
+ const currentState = getTaskState(session, args2.task_id);
59513
+ if (currentState === "idle") {
59514
+ try {
59515
+ advanceTaskState(session, args2.task_id, "coder_delegated");
59516
+ } catch {}
59517
+ }
59518
+ }
59519
+ }
59491
59520
  if (args2.status === "completed") {
59492
59521
  const reviewerCheck = checkReviewerGate(args2.task_id);
59493
59522
  if (reviewerCheck.blocked) {
@@ -1,4 +1,4 @@
1
- import { tool } from '@opencode-ai/plugin';
1
+ import { type ToolContext, tool } from '@opencode-ai/plugin';
2
2
  /**
3
3
  * Options for creating a swarm tool.
4
4
  * The args type is inferred from what you pass to the tool() call.
@@ -6,10 +6,10 @@ import { tool } from '@opencode-ai/plugin';
6
6
  export interface SwarmToolOptions<Args extends Record<string, unknown>> {
7
7
  description: string;
8
8
  args: Args;
9
- execute: (args: Args, directory: string) => Promise<string>;
9
+ execute: (args: Args, directory: string, ctx?: ToolContext) => Promise<string>;
10
10
  }
11
11
  /**
12
12
  * Creates a swarm tool with automatic working directory injection.
13
- * Wraps the @opencode-ai/plugin/tool factory to always inject `directory` into tool execute callbacks.
13
+ * Wraps the @opencode-ai/plugin/tool factory to always inject `directory` and `ctx` into tool execute callbacks.
14
14
  */
15
15
  export declare function createSwarmTool<Args extends Record<string, unknown>>(opts: SwarmToolOptions<Args>): ReturnType<typeof tool>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "6.21.1",
3
+ "version": "6.21.3",
4
4
  "description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",