opencode-swarm 6.23.0 → 6.23.1

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/index.js CHANGED
@@ -48788,10 +48788,8 @@ function createDelegationGateHook(config3) {
48788
48788
  break;
48789
48789
  }
48790
48790
  }
48791
- if (lastCoderIndex === -1) {
48792
- return;
48793
- }
48794
- const afterCoder = delegationChain.slice(lastCoderIndex);
48791
+ const searchStart = lastCoderIndex === -1 ? 0 : lastCoderIndex;
48792
+ const afterCoder = delegationChain.slice(searchStart);
48795
48793
  for (const delegation of afterCoder) {
48796
48794
  const target = stripKnownSwarmPrefix(delegation.to);
48797
48795
  if (target === "reviewer")
@@ -48799,7 +48797,7 @@ function createDelegationGateHook(config3) {
48799
48797
  if (target === "test_engineer")
48800
48798
  hasTestEngineer = true;
48801
48799
  }
48802
- if (hasReviewer && hasTestEngineer) {
48800
+ if (lastCoderIndex !== -1 && hasReviewer && hasTestEngineer) {
48803
48801
  session.qaSkipCount = 0;
48804
48802
  session.qaSkipTaskIds = [];
48805
48803
  }
@@ -60954,6 +60952,7 @@ var todo_extract = createSwarmTool({
60954
60952
  });
60955
60953
  // src/tools/update-task-status.ts
60956
60954
  init_tool();
60955
+ init_schema();
60957
60956
  init_manager2();
60958
60957
  import * as fs35 from "fs";
60959
60958
  import * as path47 from "path";
@@ -61003,10 +61002,6 @@ function checkReviewerGate(taskId, workingDirectory) {
61003
61002
  const state = getTaskState(session, taskId);
61004
61003
  stateEntries.push(`${sessionId}: ${state}`);
61005
61004
  }
61006
- const allIdle = stateEntries.length > 0 && stateEntries.every((e) => e.endsWith(": idle"));
61007
- if (allIdle) {
61008
- return { blocked: false, reason: "" };
61009
- }
61010
61005
  try {
61011
61006
  const resolvedDir = workingDirectory ?? process.cwd();
61012
61007
  const planPath = path47.join(resolvedDir, ".swarm", "plan.json");
@@ -61029,6 +61024,49 @@ function checkReviewerGate(taskId, workingDirectory) {
61029
61024
  return { blocked: false, reason: "" };
61030
61025
  }
61031
61026
  }
61027
+ function recoverTaskStateFromDelegations(taskId) {
61028
+ let hasReviewer = false;
61029
+ let hasTestEngineer = false;
61030
+ for (const [, chain] of swarmState.delegationChains) {
61031
+ for (const delegation of chain) {
61032
+ const target = stripKnownSwarmPrefix(delegation.to);
61033
+ if (target === "reviewer")
61034
+ hasReviewer = true;
61035
+ if (target === "test_engineer")
61036
+ hasTestEngineer = true;
61037
+ }
61038
+ }
61039
+ if (!hasReviewer && !hasTestEngineer)
61040
+ return;
61041
+ for (const [, session] of swarmState.agentSessions) {
61042
+ if (!(session.taskWorkflowStates instanceof Map))
61043
+ continue;
61044
+ const currentState = getTaskState(session, taskId);
61045
+ if (currentState === "tests_run" || currentState === "complete")
61046
+ continue;
61047
+ if (hasReviewer && currentState === "idle") {
61048
+ try {
61049
+ advanceTaskState(session, taskId, "coder_delegated");
61050
+ } catch {}
61051
+ }
61052
+ if (hasReviewer) {
61053
+ const stateNow = getTaskState(session, taskId);
61054
+ if (stateNow === "coder_delegated" || stateNow === "pre_check_passed") {
61055
+ try {
61056
+ advanceTaskState(session, taskId, "reviewer_run");
61057
+ } catch {}
61058
+ }
61059
+ }
61060
+ if (hasTestEngineer) {
61061
+ const stateNow = getTaskState(session, taskId);
61062
+ if (stateNow === "reviewer_run") {
61063
+ try {
61064
+ advanceTaskState(session, taskId, "tests_run");
61065
+ } catch {}
61066
+ }
61067
+ }
61068
+ }
61069
+ }
61032
61070
  async function executeUpdateTaskStatus(args2, fallbackDir) {
61033
61071
  const statusError = validateStatus(args2.status);
61034
61072
  if (statusError) {
@@ -61112,6 +61150,7 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
61112
61150
  directory = fallbackDir ?? process.cwd();
61113
61151
  }
61114
61152
  if (args2.status === "completed") {
61153
+ recoverTaskStateFromDelegations(args2.task_id);
61115
61154
  const reviewerCheck = checkReviewerGate(args2.task_id, directory);
61116
61155
  if (reviewerCheck.blocked) {
61117
61156
  return {
@@ -50,6 +50,17 @@ export interface ReviewerGateResult {
50
50
  * @returns ReviewerGateResult indicating whether the gate is blocked
51
51
  */
52
52
  export declare function checkReviewerGate(taskId: string, workingDirectory?: string): ReviewerGateResult;
53
+ /**
54
+ * Recovery mechanism: reconcile task state with delegation history.
55
+ * When reviewer/test_engineer delegations occurred but the state machine
56
+ * was not advanced (e.g., toolAfter didn't fire, subagent_type missing,
57
+ * cross-session gaps, or pure verification tasks without coder delegation),
58
+ * this function walks all delegation chains and advances the task state
59
+ * so that checkReviewerGate can make an accurate decision.
60
+ *
61
+ * @param taskId - The task ID to recover state for
62
+ */
63
+ export declare function recoverTaskStateFromDelegations(taskId: string): void;
53
64
  /**
54
65
  * Execute the update_task_status tool.
55
66
  * Validates the task_id and status, then updates the task status in the plan.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "6.23.0",
3
+ "version": "6.23.1",
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",