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 +1 -1
- package/dist/index.js +46 -5
- package/package.json +1 -1
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.
|
|
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.
|
|
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;
|
|
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, "<").replace(/>/g, ">").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
|
|
39592
|
-
const sanitizedTaskId = lastGate.taskId
|
|
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.
|
|
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",
|