opencode-swarm 7.29.1 → 7.29.2

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
@@ -34,7 +34,7 @@ var package_default;
34
34
  var init_package = __esm(() => {
35
35
  package_default = {
36
36
  name: "opencode-swarm",
37
- version: "7.29.1",
37
+ version: "7.29.2",
38
38
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
39
39
  main: "dist/index.js",
40
40
  types: "dist/index.d.ts",
package/dist/index.js CHANGED
@@ -48,7 +48,7 @@ var package_default;
48
48
  var init_package = __esm(() => {
49
49
  package_default = {
50
50
  name: "opencode-swarm",
51
- version: "7.29.1",
51
+ version: "7.29.2",
52
52
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
53
53
  main: "dist/index.js",
54
54
  types: "dist/index.d.ts",
@@ -39003,7 +39003,46 @@ async function buildParallelExecutionGuidance(directory, sessionID, session) {
39003
39003
  if (eligible.length === 0) {
39004
39004
  return `[PARALLEL EXECUTION PROFILE] parallelization_enabled=true max_concurrent_tasks=${maxConcurrent}; no dependency-ready pending tasks are available for a new coder slot. Continue the current task/gate.`;
39005
39005
  }
39006
- return `[PARALLEL EXECUTION PROFILE] parallelization_enabled=true max_concurrent_tasks=${maxConcurrent}; ${occupied.size} slot(s) occupied. Eligible now: ${eligible.join(", ")}. [NEXT] dispatch up to ${availableSlots} eligible coder task(s) before waiting; preserve ONE task per coder call and call declare_scope for each task.`;
39006
+ return `[PARALLEL EXECUTION PROFILE] parallelization_enabled=true max_concurrent_tasks=${maxConcurrent}; ${occupied.size} slot(s) occupied. Eligible now: ${eligible.join(", ")}. [NEXT] dispatch up to ${availableSlots} eligible coder task(s) before waiting; for each dispatched task, call update_task_status(in_progress), call declare_scope, then send the coder Task. Preserve ONE atomic task per coder Task call.`;
39007
+ }
39008
+ async function buildPlanContinuationGuidance(directory) {
39009
+ if (!directory)
39010
+ return null;
39011
+ const plan = await loadPlanJsonOnly(directory);
39012
+ const currentTaskId = getPlanContinuationTaskId(plan);
39013
+ if (!currentTaskId)
39014
+ return null;
39015
+ const sanitizedTaskId = sanitizeGuidanceValue(currentTaskId, 32);
39016
+ return `[NEXT] Continue plan task ${sanitizedTaskId}: if it is not already in progress, call update_task_status with task_id="${sanitizedTaskId}" and status="in_progress"; ` + `then call declare_scope for the task files and dispatch coder Task call(s) according to the execution profile. ` + `Preserve ONE atomic task per coder Task call; when parallel execution is enabled, use available coder slots instead of forcing a single coder.`;
39017
+ }
39018
+ function sanitizeGuidanceValue(value, maxLength) {
39019
+ return value.replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\[ \]/g, "()").replace(/\[/g, "(").replace(/\]/g, ")").replace(/[\r\n]/g, " ").slice(0, maxLength);
39020
+ }
39021
+ function getPlanContinuationTaskId(plan) {
39022
+ if (!plan)
39023
+ return;
39024
+ const currentPhase = plan.current_phase ?? 1;
39025
+ const phase = plan.phases.find((p) => p.id === currentPhase);
39026
+ if (!phase)
39027
+ return;
39028
+ const sortedTasks = [...phase.tasks].sort((a, b) => comparePlanTaskIds(a.id, b.id));
39029
+ const inProgress = sortedTasks.find((task) => task.status === "in_progress");
39030
+ if (inProgress)
39031
+ return inProgress.id;
39032
+ const incomplete = sortedTasks.find((task) => task.status !== "completed" && task.status !== "closed");
39033
+ return incomplete?.id;
39034
+ }
39035
+ function comparePlanTaskIds(a, b) {
39036
+ const partsA = a.split(".").map((part) => Number.parseInt(part, 10));
39037
+ const partsB = b.split(".").map((part) => Number.parseInt(part, 10));
39038
+ const maxLength = Math.max(partsA.length, partsB.length);
39039
+ for (let i2 = 0;i2 < maxLength; i2++) {
39040
+ const numA = partsA[i2] ?? 0;
39041
+ const numB = partsB[i2] ?? 0;
39042
+ if (numA !== numB)
39043
+ return numA - numB;
39044
+ }
39045
+ return 0;
39007
39046
  }
39008
39047
  function isParallelGuidancePhaseComplete(phase) {
39009
39048
  return phase.status === "complete" || phase.status === "completed" || phase.status === "closed";
@@ -39581,6 +39620,7 @@ ${trimComment}${after}`;
39581
39620
  const deliberationSession = ensureAgentSession(deliberationSessionID);
39582
39621
  const lastGate = deliberationSession.lastGateOutcome;
39583
39622
  const parallelGuidance = await buildParallelExecutionGuidance(directory, deliberationSessionID, deliberationSession);
39623
+ const planContinuationGuidance = parallelGuidance === null ? await buildPlanContinuationGuidance(directory) : null;
39584
39624
  const taskAwaitingCompletion = await findTaskAwaitingCompletion(directory, deliberationSession);
39585
39625
  let guidance;
39586
39626
  if (taskAwaitingCompletion) {
@@ -39588,12 +39628,12 @@ ${trimComment}${after}`;
39588
39628
  [NEXT] Print the task completion checklist, then call update_task_status with task_id="${taskAwaitingCompletion}" and status="completed" before declare_scope or starting another task.`;
39589
39629
  } else if (lastGate?.taskId) {
39590
39630
  const gateResult = lastGate.passed ? "PASSED" : "FAILED";
39591
- const sanitizedGate = lastGate.gate.replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\[ \]/g, "()").replace(/\[/g, "(").replace(/\]/g, ")").replace(/[\r\n]/g, " ").slice(0, 64);
39592
- const sanitizedTaskId = lastGate.taskId.replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\[/g, "(").replace(/\]/g, ")").replace(/[\r\n]/g, " ").slice(0, 32);
39631
+ const sanitizedGate = sanitizeGuidanceValue(lastGate.gate, 64);
39632
+ const sanitizedTaskId = sanitizeGuidanceValue(lastGate.taskId, 32);
39593
39633
  guidance = `[Last gate: ${sanitizedGate} ${gateResult} for task ${sanitizedTaskId}]
39594
39634
  ${parallelGuidance ?? "[NEXT] Execute the next gate for the current task."}`;
39595
39635
  } else {
39596
- guidance = parallelGuidance ?? "[NEXT] Begin the first plan task and run gates sequentially.";
39636
+ guidance = parallelGuidance ?? planContinuationGuidance ?? "[NEXT] Begin the first plan task and run gates sequentially.";
39597
39637
  }
39598
39638
  const systemMsgIdx = messages.findIndex((m) => m && m.info?.role === "system");
39599
39639
  const insertIdx = systemMsgIdx >= 0 ? systemMsgIdx + 1 : 0;
@@ -76418,6 +76458,7 @@ If .swarm/plan.md exists:
76418
76458
  - Update context.md Swarm field to "{{SWARM_ID}}"
76419
76459
  - Inform user: "Resuming project from [other] swarm. Cleared stale context. Ready to continue."
76420
76460
  - Resume at current task
76461
+ Resume execution rule: after identifying the current task, do not restart broad discovery. Move into EXECUTE: call \`update_task_status\` if the task is not already in progress, call \`declare_scope\` for the task files, then dispatch coder Task call(s) according to \`execution_profile\`. Preserve ONE atomic task per coder Task call; parallel profiles may dispatch up to the available coder slots.
76421
76462
  If .swarm/plan.md does not exist → New project, proceed to MODE: CLARIFY
76422
76463
  If new project: Run \`complexity_hotspots\` tool (90 days) to generate a risk map. Note modules with recommendation "security_review" or "full_gates" in context.md for stricter QA gates during Phase 5. Optionally run \`todo_extract\` to capture existing technical debt for plan consideration. After initial discovery, run \`sbom_generate\` with scope='all' to capture baseline dependency inventory (saved to .swarm/evidence/sbom/).
76423
76464
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "7.29.1",
3
+ "version": "7.29.2",
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",