opencode-swarm-plugin 0.57.6 → 0.59.0
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/bin/swarm.ts +350 -8
- package/claude-plugin/.claude-plugin/plugin.json +1 -1
- package/claude-plugin/README.md +187 -0
- package/claude-plugin/agents/worker.md +1 -0
- package/claude-plugin/dist/index.js +467 -178
- package/claude-plugin/hooks/hooks.json +67 -0
- package/claude-plugin/skills/release/SKILL.md +101 -0
- package/claude-plugin/skills/swarm-cli/SKILL.md +82 -0
- package/dist/bin/swarm.js +1200 -328
- package/dist/decision-trace-integration.d.ts +18 -0
- package/dist/decision-trace-integration.d.ts.map +1 -1
- package/dist/hive.d.ts.map +1 -1
- package/dist/hive.js +34 -8
- package/dist/index.js +447 -181
- package/dist/marketplace/index.js +467 -178
- package/dist/plugin.js +447 -181
- package/dist/query-tools.d.ts +4 -4
- package/dist/query-tools.d.ts.map +1 -1
- package/dist/rate-limiter.d.ts +2 -0
- package/dist/rate-limiter.d.ts.map +1 -1
- package/dist/skills.d.ts.map +1 -1
- package/dist/storage.d.ts.map +1 -1
- package/dist/swarm-decompose.d.ts.map +1 -1
- package/dist/swarm-orchestrate.d.ts.map +1 -1
- package/dist/swarm-prompts.d.ts +1 -1
- package/dist/swarm-prompts.d.ts.map +1 -1
- package/dist/swarm-prompts.js +395 -124
- package/dist/tool-availability.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/swarm-prompts.js
CHANGED
|
@@ -17875,13 +17875,13 @@ Scripts run in the skill's directory with the project directory as an argument.`
|
|
|
17875
17875
|
}
|
|
17876
17876
|
const scriptPath = join3(skill.directory, "scripts", args.script);
|
|
17877
17877
|
const scriptArgs = args.args || [];
|
|
17878
|
+
const TIMEOUT_MS = 60000;
|
|
17879
|
+
const proc = Bun.spawn([scriptPath, skillsProjectDirectory, ...scriptArgs], {
|
|
17880
|
+
cwd: skill.directory,
|
|
17881
|
+
stdout: "pipe",
|
|
17882
|
+
stderr: "pipe"
|
|
17883
|
+
});
|
|
17878
17884
|
try {
|
|
17879
|
-
const TIMEOUT_MS = 60000;
|
|
17880
|
-
const proc = Bun.spawn([scriptPath, skillsProjectDirectory, ...scriptArgs], {
|
|
17881
|
-
cwd: skill.directory,
|
|
17882
|
-
stdout: "pipe",
|
|
17883
|
-
stderr: "pipe"
|
|
17884
|
-
});
|
|
17885
17885
|
const timeoutPromise = new Promise((resolve2) => {
|
|
17886
17886
|
setTimeout(() => resolve2({ timedOut: true }), TIMEOUT_MS);
|
|
17887
17887
|
});
|
|
@@ -17895,7 +17895,6 @@ Scripts run in the skill's directory with the project directory as an argument.`
|
|
|
17895
17895
|
})();
|
|
17896
17896
|
const result = await Promise.race([resultPromise, timeoutPromise]);
|
|
17897
17897
|
if (result.timedOut) {
|
|
17898
|
-
proc.kill();
|
|
17899
17898
|
return `Script timed out after ${TIMEOUT_MS / 1000} seconds.`;
|
|
17900
17899
|
}
|
|
17901
17900
|
const output = result.stdout + result.stderr;
|
|
@@ -17907,6 +17906,8 @@ ${output}`;
|
|
|
17907
17906
|
}
|
|
17908
17907
|
} catch (error45) {
|
|
17909
17908
|
return `Failed to execute script: ${error45 instanceof Error ? error45.message : String(error45)}`;
|
|
17909
|
+
} finally {
|
|
17910
|
+
proc.kill();
|
|
17910
17911
|
}
|
|
17911
17912
|
}
|
|
17912
17913
|
});
|
|
@@ -18284,6 +18285,237 @@ echo "Project directory: $1"
|
|
|
18284
18285
|
};
|
|
18285
18286
|
});
|
|
18286
18287
|
|
|
18288
|
+
// src/decision-trace-integration.ts
|
|
18289
|
+
var exports_decision_trace_integration = {};
|
|
18290
|
+
__export(exports_decision_trace_integration, {
|
|
18291
|
+
traceWorkerSpawn: () => traceWorkerSpawn,
|
|
18292
|
+
traceStrategySelection: () => traceStrategySelection,
|
|
18293
|
+
traceScopeChange: () => traceScopeChange,
|
|
18294
|
+
traceReviewDecision: () => traceReviewDecision,
|
|
18295
|
+
traceFileSelection: () => traceFileSelection,
|
|
18296
|
+
linkOutcomeToDecisionTrace: () => linkOutcomeToDecisionTrace,
|
|
18297
|
+
getEpicDecisionTraces: () => getEpicDecisionTraces,
|
|
18298
|
+
getDecisionTracesByType: () => getDecisionTracesByType,
|
|
18299
|
+
extractMemoryIds: () => extractMemoryIds
|
|
18300
|
+
});
|
|
18301
|
+
import {
|
|
18302
|
+
createDecisionTrace,
|
|
18303
|
+
createEntityLink
|
|
18304
|
+
} from "swarm-mail";
|
|
18305
|
+
import { createLibSQLAdapter } from "swarm-mail";
|
|
18306
|
+
import { getDatabasePath } from "swarm-mail";
|
|
18307
|
+
async function getTraceDb(projectPath) {
|
|
18308
|
+
const dbPath = getDatabasePath(projectPath);
|
|
18309
|
+
return createLibSQLAdapter({ url: `file:${dbPath}` });
|
|
18310
|
+
}
|
|
18311
|
+
function extractMemoryIds(precedentCited) {
|
|
18312
|
+
if (!precedentCited) {
|
|
18313
|
+
return [];
|
|
18314
|
+
}
|
|
18315
|
+
if (precedentCited.memoryIds && Array.isArray(precedentCited.memoryIds)) {
|
|
18316
|
+
return precedentCited.memoryIds;
|
|
18317
|
+
}
|
|
18318
|
+
if (precedentCited.memoryId) {
|
|
18319
|
+
return [precedentCited.memoryId];
|
|
18320
|
+
}
|
|
18321
|
+
return [];
|
|
18322
|
+
}
|
|
18323
|
+
async function traceStrategySelection(input) {
|
|
18324
|
+
try {
|
|
18325
|
+
const db = await getTraceDb(input.projectKey);
|
|
18326
|
+
const trace = await createDecisionTrace(db, {
|
|
18327
|
+
decision_type: "strategy_selection",
|
|
18328
|
+
epic_id: input.epicId,
|
|
18329
|
+
bead_id: input.beadId,
|
|
18330
|
+
agent_name: input.agentName,
|
|
18331
|
+
project_key: input.projectKey,
|
|
18332
|
+
decision: {
|
|
18333
|
+
strategy: input.strategy,
|
|
18334
|
+
confidence: input.confidence,
|
|
18335
|
+
task_preview: input.taskPreview
|
|
18336
|
+
},
|
|
18337
|
+
rationale: input.reasoning,
|
|
18338
|
+
inputs_gathered: input.inputsGathered,
|
|
18339
|
+
alternatives: input.alternatives,
|
|
18340
|
+
precedent_cited: input.precedentCited
|
|
18341
|
+
});
|
|
18342
|
+
const memoryIds = extractMemoryIds(input.precedentCited);
|
|
18343
|
+
for (const memoryId of memoryIds) {
|
|
18344
|
+
await createEntityLink(db, {
|
|
18345
|
+
source_decision_id: trace.id,
|
|
18346
|
+
target_entity_type: "memory",
|
|
18347
|
+
target_entity_id: memoryId,
|
|
18348
|
+
link_type: "cites_precedent",
|
|
18349
|
+
strength: input.precedentCited?.similarity ?? 1,
|
|
18350
|
+
context: "Cited as precedent for strategy selection"
|
|
18351
|
+
});
|
|
18352
|
+
}
|
|
18353
|
+
await db.close?.();
|
|
18354
|
+
return trace.id;
|
|
18355
|
+
} catch (error45) {
|
|
18356
|
+
console.warn("[decision-trace] Failed to trace strategy_selection:", error45);
|
|
18357
|
+
return "";
|
|
18358
|
+
}
|
|
18359
|
+
}
|
|
18360
|
+
async function traceWorkerSpawn(input) {
|
|
18361
|
+
try {
|
|
18362
|
+
const db = await getTraceDb(input.projectKey);
|
|
18363
|
+
const trace = await createDecisionTrace(db, {
|
|
18364
|
+
decision_type: "worker_spawn",
|
|
18365
|
+
epic_id: input.epicId,
|
|
18366
|
+
bead_id: input.beadId,
|
|
18367
|
+
agent_name: input.agentName,
|
|
18368
|
+
project_key: input.projectKey,
|
|
18369
|
+
decision: {
|
|
18370
|
+
worker: input.workerName || "worker",
|
|
18371
|
+
subtask_title: input.subtaskTitle,
|
|
18372
|
+
files: input.files,
|
|
18373
|
+
model: input.model,
|
|
18374
|
+
spawn_order: input.spawnOrder,
|
|
18375
|
+
is_parallel: input.isParallel
|
|
18376
|
+
},
|
|
18377
|
+
rationale: input.rationale || `Spawning worker for: ${input.subtaskTitle}`
|
|
18378
|
+
});
|
|
18379
|
+
for (const file2 of input.files) {
|
|
18380
|
+
await createEntityLink(db, {
|
|
18381
|
+
source_decision_id: trace.id,
|
|
18382
|
+
target_entity_type: "file",
|
|
18383
|
+
target_entity_id: file2,
|
|
18384
|
+
link_type: "assigns_file",
|
|
18385
|
+
strength: 1,
|
|
18386
|
+
context: `File assigned to worker ${input.workerName || "worker"}`
|
|
18387
|
+
});
|
|
18388
|
+
}
|
|
18389
|
+
await db.close?.();
|
|
18390
|
+
return trace.id;
|
|
18391
|
+
} catch (error45) {
|
|
18392
|
+
console.warn("[decision-trace] Failed to trace worker_spawn:", error45);
|
|
18393
|
+
return "";
|
|
18394
|
+
}
|
|
18395
|
+
}
|
|
18396
|
+
async function traceReviewDecision(input) {
|
|
18397
|
+
try {
|
|
18398
|
+
const db = await getTraceDb(input.projectKey);
|
|
18399
|
+
const trace = await createDecisionTrace(db, {
|
|
18400
|
+
decision_type: "review_decision",
|
|
18401
|
+
epic_id: input.epicId,
|
|
18402
|
+
bead_id: input.beadId,
|
|
18403
|
+
agent_name: input.agentName,
|
|
18404
|
+
project_key: input.projectKey,
|
|
18405
|
+
decision: {
|
|
18406
|
+
status: input.status,
|
|
18407
|
+
worker_id: input.workerId,
|
|
18408
|
+
issues_count: input.issues?.length || 0,
|
|
18409
|
+
attempt_number: input.attemptNumber,
|
|
18410
|
+
remaining_attempts: input.remainingAttempts
|
|
18411
|
+
},
|
|
18412
|
+
rationale: input.rationale || input.summary || `Review ${input.status}`,
|
|
18413
|
+
inputs_gathered: input.issues ? [{ source: "code_review", issues: input.issues }] : undefined
|
|
18414
|
+
});
|
|
18415
|
+
await createEntityLink(db, {
|
|
18416
|
+
source_decision_id: trace.id,
|
|
18417
|
+
target_entity_type: "agent",
|
|
18418
|
+
target_entity_id: input.workerId,
|
|
18419
|
+
link_type: "reviewed_work_by",
|
|
18420
|
+
strength: 1,
|
|
18421
|
+
context: `Review ${input.status} for ${input.workerId}`
|
|
18422
|
+
});
|
|
18423
|
+
await db.close?.();
|
|
18424
|
+
return trace.id;
|
|
18425
|
+
} catch (error45) {
|
|
18426
|
+
console.warn("[decision-trace] Failed to trace review_decision:", error45);
|
|
18427
|
+
return "";
|
|
18428
|
+
}
|
|
18429
|
+
}
|
|
18430
|
+
async function traceFileSelection(input) {
|
|
18431
|
+
try {
|
|
18432
|
+
const db = await getTraceDb(input.projectKey);
|
|
18433
|
+
const trace = await createDecisionTrace(db, {
|
|
18434
|
+
decision_type: "file_selection",
|
|
18435
|
+
epic_id: input.epicId,
|
|
18436
|
+
bead_id: input.beadId,
|
|
18437
|
+
agent_name: input.agentName,
|
|
18438
|
+
project_key: input.projectKey,
|
|
18439
|
+
decision: {
|
|
18440
|
+
files_selected: input.filesSelected,
|
|
18441
|
+
files_owned: input.filesOwned,
|
|
18442
|
+
scope_expanded: input.scopeExpanded
|
|
18443
|
+
},
|
|
18444
|
+
rationale: input.rationale || `Selected ${input.filesSelected.length} files`
|
|
18445
|
+
});
|
|
18446
|
+
await db.close?.();
|
|
18447
|
+
return trace.id;
|
|
18448
|
+
} catch (error45) {
|
|
18449
|
+
console.warn("[decision-trace] Failed to trace file_selection:", error45);
|
|
18450
|
+
return "";
|
|
18451
|
+
}
|
|
18452
|
+
}
|
|
18453
|
+
async function traceScopeChange(input) {
|
|
18454
|
+
try {
|
|
18455
|
+
const db = await getTraceDb(input.projectKey);
|
|
18456
|
+
const trace = await createDecisionTrace(db, {
|
|
18457
|
+
decision_type: "scope_change",
|
|
18458
|
+
epic_id: input.epicId,
|
|
18459
|
+
bead_id: input.beadId,
|
|
18460
|
+
agent_name: input.agentName,
|
|
18461
|
+
project_key: input.projectKey,
|
|
18462
|
+
decision: {
|
|
18463
|
+
files_added: input.filesAdded || [],
|
|
18464
|
+
files_removed: input.filesRemoved || [],
|
|
18465
|
+
coordinator_approved: input.coordinatorApproved
|
|
18466
|
+
},
|
|
18467
|
+
rationale: input.reason
|
|
18468
|
+
});
|
|
18469
|
+
await db.close?.();
|
|
18470
|
+
return trace.id;
|
|
18471
|
+
} catch (error45) {
|
|
18472
|
+
console.warn("[decision-trace] Failed to trace scope_change:", error45);
|
|
18473
|
+
return "";
|
|
18474
|
+
}
|
|
18475
|
+
}
|
|
18476
|
+
async function getEpicDecisionTraces(projectKey, epicId) {
|
|
18477
|
+
try {
|
|
18478
|
+
const { getDecisionTracesByEpic } = await import("swarm-mail");
|
|
18479
|
+
const db = await getTraceDb(projectKey);
|
|
18480
|
+
const traces = await getDecisionTracesByEpic(db, epicId);
|
|
18481
|
+
await db.close?.();
|
|
18482
|
+
return traces;
|
|
18483
|
+
} catch (error45) {
|
|
18484
|
+
console.warn("[decision-trace] Failed to query epic traces:", error45);
|
|
18485
|
+
return [];
|
|
18486
|
+
}
|
|
18487
|
+
}
|
|
18488
|
+
async function getDecisionTracesByType(projectKey, decisionType) {
|
|
18489
|
+
try {
|
|
18490
|
+
const { getDecisionTracesByType: queryByType } = await import("swarm-mail");
|
|
18491
|
+
const db = await getTraceDb(projectKey);
|
|
18492
|
+
const traces = await queryByType(db, decisionType);
|
|
18493
|
+
await db.close?.();
|
|
18494
|
+
return traces;
|
|
18495
|
+
} catch (error45) {
|
|
18496
|
+
console.warn("[decision-trace] Failed to query traces by type:", error45);
|
|
18497
|
+
return [];
|
|
18498
|
+
}
|
|
18499
|
+
}
|
|
18500
|
+
async function linkOutcomeToDecisionTrace(input) {
|
|
18501
|
+
try {
|
|
18502
|
+
const { findDecisionTraceByBead, linkOutcomeToTrace } = await import("swarm-mail");
|
|
18503
|
+
const db = await getTraceDb(input.projectKey);
|
|
18504
|
+
const trace = await findDecisionTraceByBead(db, input.beadId);
|
|
18505
|
+
if (!trace) {
|
|
18506
|
+
await db.close?.();
|
|
18507
|
+
return false;
|
|
18508
|
+
}
|
|
18509
|
+
await linkOutcomeToTrace(db, trace.id, input.outcomeEventId);
|
|
18510
|
+
await db.close?.();
|
|
18511
|
+
return true;
|
|
18512
|
+
} catch (error45) {
|
|
18513
|
+
console.warn("[decision-trace] Failed to link outcome to trace:", error45);
|
|
18514
|
+
return false;
|
|
18515
|
+
}
|
|
18516
|
+
}
|
|
18517
|
+
var init_decision_trace_integration = () => {};
|
|
18518
|
+
|
|
18287
18519
|
// src/anti-patterns.ts
|
|
18288
18520
|
var exports_anti_patterns = {};
|
|
18289
18521
|
__export(exports_anti_patterns, {
|
|
@@ -18809,9 +19041,11 @@ async function execSemanticMemory(args) {
|
|
|
18809
19041
|
stderr: "pipe"
|
|
18810
19042
|
});
|
|
18811
19043
|
try {
|
|
19044
|
+
const TIMEOUT_MS = 30000;
|
|
19045
|
+
const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error("Process timed out after 30s")), TIMEOUT_MS));
|
|
18812
19046
|
const stdout = Buffer.from(await new Response(proc.stdout).arrayBuffer());
|
|
18813
19047
|
const stderr = Buffer.from(await new Response(proc.stderr).arrayBuffer());
|
|
18814
|
-
const exitCode = await proc.exited;
|
|
19048
|
+
const exitCode = await Promise.race([proc.exited, timeoutPromise]);
|
|
18815
19049
|
return { exitCode, stdout, stderr };
|
|
18816
19050
|
} finally {
|
|
18817
19051
|
proc.kill();
|
|
@@ -39785,13 +40019,17 @@ var toolCheckers = {
|
|
|
39785
40019
|
stderr: "pipe"
|
|
39786
40020
|
});
|
|
39787
40021
|
const timeout = setTimeout(() => proc.kill(), BUNX_TIMEOUT_MS);
|
|
39788
|
-
|
|
39789
|
-
|
|
39790
|
-
|
|
39791
|
-
|
|
39792
|
-
|
|
39793
|
-
|
|
39794
|
-
|
|
40022
|
+
try {
|
|
40023
|
+
const exitCode = await proc.exited;
|
|
40024
|
+
return {
|
|
40025
|
+
available: exitCode === 0,
|
|
40026
|
+
checkedAt: new Date().toISOString(),
|
|
40027
|
+
version: "bunx"
|
|
40028
|
+
};
|
|
40029
|
+
} finally {
|
|
40030
|
+
clearTimeout(timeout);
|
|
40031
|
+
proc.kill();
|
|
40032
|
+
}
|
|
39795
40033
|
} catch (e) {
|
|
39796
40034
|
return {
|
|
39797
40035
|
available: false,
|
|
@@ -39864,13 +40102,17 @@ var toolCheckers = {
|
|
|
39864
40102
|
stderr: "pipe"
|
|
39865
40103
|
});
|
|
39866
40104
|
const timeout = setTimeout(() => proc.kill(), BUNX_TIMEOUT_MS);
|
|
39867
|
-
|
|
39868
|
-
|
|
39869
|
-
|
|
39870
|
-
|
|
39871
|
-
|
|
39872
|
-
|
|
39873
|
-
|
|
40105
|
+
try {
|
|
40106
|
+
const exitCode = await proc.exited;
|
|
40107
|
+
return {
|
|
40108
|
+
available: exitCode === 0,
|
|
40109
|
+
checkedAt: new Date().toISOString(),
|
|
40110
|
+
version: "bunx-semantic-memory"
|
|
40111
|
+
};
|
|
40112
|
+
} finally {
|
|
40113
|
+
clearTimeout(timeout);
|
|
40114
|
+
proc.kill();
|
|
40115
|
+
}
|
|
39874
40116
|
} catch (e) {
|
|
39875
40117
|
return {
|
|
39876
40118
|
available: false,
|
|
@@ -40034,12 +40276,16 @@ async function runGitCommand(args) {
|
|
|
40034
40276
|
stdout: "pipe",
|
|
40035
40277
|
stderr: "pipe"
|
|
40036
40278
|
});
|
|
40037
|
-
|
|
40038
|
-
|
|
40039
|
-
|
|
40040
|
-
|
|
40041
|
-
|
|
40042
|
-
|
|
40279
|
+
try {
|
|
40280
|
+
const [stdout, stderr] = await Promise.all([
|
|
40281
|
+
new Response(proc.stdout).text(),
|
|
40282
|
+
new Response(proc.stderr).text()
|
|
40283
|
+
]);
|
|
40284
|
+
const exitCode = await proc.exited;
|
|
40285
|
+
return { exitCode, stdout, stderr };
|
|
40286
|
+
} finally {
|
|
40287
|
+
proc.kill();
|
|
40288
|
+
}
|
|
40043
40289
|
}
|
|
40044
40290
|
|
|
40045
40291
|
class HiveError extends Error {
|
|
@@ -40196,9 +40442,9 @@ var hive_create = tool({
|
|
|
40196
40442
|
}
|
|
40197
40443
|
});
|
|
40198
40444
|
var hive_create_epic = tool({
|
|
40199
|
-
description: "Create epic with subtasks
|
|
40445
|
+
description: "Create epic with subtasks atomically. REQUIRED: epic_title, subtasks (array with {title, files?}). Use after swarm_validate_decomposition confirms your decomposition is valid. Each subtask should list files it will modify to enable parallel work without conflicts.",
|
|
40200
40446
|
args: {
|
|
40201
|
-
epic_title: tool.schema.string().describe("Epic title"),
|
|
40447
|
+
epic_title: tool.schema.string().describe("Epic title (e.g., 'Implement user auth')"),
|
|
40202
40448
|
epic_description: tool.schema.string().optional().describe("Epic description"),
|
|
40203
40449
|
epic_id: tool.schema.string().optional().describe("Custom ID for the epic (e.g., 'phase-0')"),
|
|
40204
40450
|
subtasks: tool.schema.array(tool.schema.object({
|
|
@@ -40217,6 +40463,28 @@ var hive_create_epic = tool({
|
|
|
40217
40463
|
}).optional().describe("Recovery context from checkpoint compaction")
|
|
40218
40464
|
},
|
|
40219
40465
|
async execute(args, ctx) {
|
|
40466
|
+
const missing = [];
|
|
40467
|
+
if (!args.epic_title)
|
|
40468
|
+
missing.push("epic_title");
|
|
40469
|
+
if (!args.subtasks || args.subtasks.length === 0)
|
|
40470
|
+
missing.push("subtasks (array of subtask objects)");
|
|
40471
|
+
if (missing.length > 0) {
|
|
40472
|
+
return JSON.stringify({
|
|
40473
|
+
success: false,
|
|
40474
|
+
error: `Missing required parameters: ${missing.join(", ")}`,
|
|
40475
|
+
hint: "hive_create_epic creates an epic with subtasks atomically.",
|
|
40476
|
+
example: {
|
|
40477
|
+
epic_title: "Implement user authentication",
|
|
40478
|
+
epic_description: "Add login, logout, and session management",
|
|
40479
|
+
subtasks: [
|
|
40480
|
+
{ title: "Create auth service", files: ["src/auth/service.ts"] },
|
|
40481
|
+
{ title: "Add login endpoint", files: ["src/api/login.ts"] },
|
|
40482
|
+
{ title: "Add session middleware", files: ["src/middleware/session.ts"] }
|
|
40483
|
+
]
|
|
40484
|
+
},
|
|
40485
|
+
tip: "Each subtask should have a title and optionally files it will modify. This helps with file reservation and parallel execution."
|
|
40486
|
+
}, null, 2);
|
|
40487
|
+
}
|
|
40220
40488
|
const validated = EpicCreateArgsSchema.parse(args);
|
|
40221
40489
|
const projectKey = getHiveWorkingDirectory();
|
|
40222
40490
|
const adapter = await getHiveAdapter(projectKey);
|
|
@@ -41270,90 +41538,7 @@ init_dist();
|
|
|
41270
41538
|
init_zod();
|
|
41271
41539
|
import { sendSwarmMessage } from "swarm-mail";
|
|
41272
41540
|
init_eval_capture();
|
|
41273
|
-
|
|
41274
|
-
// src/decision-trace-integration.ts
|
|
41275
|
-
import {
|
|
41276
|
-
createDecisionTrace,
|
|
41277
|
-
createEntityLink
|
|
41278
|
-
} from "swarm-mail";
|
|
41279
|
-
import { createLibSQLAdapter } from "swarm-mail";
|
|
41280
|
-
import { getDatabasePath } from "swarm-mail";
|
|
41281
|
-
async function getTraceDb(projectPath) {
|
|
41282
|
-
const dbPath = getDatabasePath(projectPath);
|
|
41283
|
-
return createLibSQLAdapter({ url: `file:${dbPath}` });
|
|
41284
|
-
}
|
|
41285
|
-
async function traceWorkerSpawn(input) {
|
|
41286
|
-
try {
|
|
41287
|
-
const db = await getTraceDb(input.projectKey);
|
|
41288
|
-
const trace = await createDecisionTrace(db, {
|
|
41289
|
-
decision_type: "worker_spawn",
|
|
41290
|
-
epic_id: input.epicId,
|
|
41291
|
-
bead_id: input.beadId,
|
|
41292
|
-
agent_name: input.agentName,
|
|
41293
|
-
project_key: input.projectKey,
|
|
41294
|
-
decision: {
|
|
41295
|
-
worker: input.workerName || "worker",
|
|
41296
|
-
subtask_title: input.subtaskTitle,
|
|
41297
|
-
files: input.files,
|
|
41298
|
-
model: input.model,
|
|
41299
|
-
spawn_order: input.spawnOrder,
|
|
41300
|
-
is_parallel: input.isParallel
|
|
41301
|
-
},
|
|
41302
|
-
rationale: input.rationale || `Spawning worker for: ${input.subtaskTitle}`
|
|
41303
|
-
});
|
|
41304
|
-
for (const file2 of input.files) {
|
|
41305
|
-
await createEntityLink(db, {
|
|
41306
|
-
source_decision_id: trace.id,
|
|
41307
|
-
target_entity_type: "file",
|
|
41308
|
-
target_entity_id: file2,
|
|
41309
|
-
link_type: "assigns_file",
|
|
41310
|
-
strength: 1,
|
|
41311
|
-
context: `File assigned to worker ${input.workerName || "worker"}`
|
|
41312
|
-
});
|
|
41313
|
-
}
|
|
41314
|
-
await db.close?.();
|
|
41315
|
-
return trace.id;
|
|
41316
|
-
} catch (error45) {
|
|
41317
|
-
console.warn("[decision-trace] Failed to trace worker_spawn:", error45);
|
|
41318
|
-
return "";
|
|
41319
|
-
}
|
|
41320
|
-
}
|
|
41321
|
-
async function traceReviewDecision(input) {
|
|
41322
|
-
try {
|
|
41323
|
-
const db = await getTraceDb(input.projectKey);
|
|
41324
|
-
const trace = await createDecisionTrace(db, {
|
|
41325
|
-
decision_type: "review_decision",
|
|
41326
|
-
epic_id: input.epicId,
|
|
41327
|
-
bead_id: input.beadId,
|
|
41328
|
-
agent_name: input.agentName,
|
|
41329
|
-
project_key: input.projectKey,
|
|
41330
|
-
decision: {
|
|
41331
|
-
status: input.status,
|
|
41332
|
-
worker_id: input.workerId,
|
|
41333
|
-
issues_count: input.issues?.length || 0,
|
|
41334
|
-
attempt_number: input.attemptNumber,
|
|
41335
|
-
remaining_attempts: input.remainingAttempts
|
|
41336
|
-
},
|
|
41337
|
-
rationale: input.rationale || input.summary || `Review ${input.status}`,
|
|
41338
|
-
inputs_gathered: input.issues ? [{ source: "code_review", issues: input.issues }] : undefined
|
|
41339
|
-
});
|
|
41340
|
-
await createEntityLink(db, {
|
|
41341
|
-
source_decision_id: trace.id,
|
|
41342
|
-
target_entity_type: "agent",
|
|
41343
|
-
target_entity_id: input.workerId,
|
|
41344
|
-
link_type: "reviewed_work_by",
|
|
41345
|
-
strength: 1,
|
|
41346
|
-
context: `Review ${input.status} for ${input.workerId}`
|
|
41347
|
-
});
|
|
41348
|
-
await db.close?.();
|
|
41349
|
-
return trace.id;
|
|
41350
|
-
} catch (error45) {
|
|
41351
|
-
console.warn("[decision-trace] Failed to trace review_decision:", error45);
|
|
41352
|
-
return "";
|
|
41353
|
-
}
|
|
41354
|
-
}
|
|
41355
|
-
|
|
41356
|
-
// src/swarm-review.ts
|
|
41541
|
+
init_decision_trace_integration();
|
|
41357
41542
|
var ReviewIssueSchema = exports_external.object({
|
|
41358
41543
|
file: exports_external.string(),
|
|
41359
41544
|
line: exports_external.number().optional(),
|
|
@@ -42207,17 +42392,41 @@ var swarm_status = tool({
|
|
|
42207
42392
|
}
|
|
42208
42393
|
});
|
|
42209
42394
|
var swarm_progress = tool({
|
|
42210
|
-
description: "Report progress on a subtask to coordinator",
|
|
42395
|
+
description: "Report progress on a subtask to coordinator. REQUIRED: project_key, agent_name, bead_id, status. Call periodically (every 25% or when blocked) to keep coordinator informed. Use status='blocked' with message explaining the blocker if you're stuck.",
|
|
42211
42396
|
args: {
|
|
42212
|
-
project_key: tool.schema.string().describe("Project path"),
|
|
42213
|
-
agent_name: tool.schema.string().describe("Your
|
|
42214
|
-
bead_id: tool.schema.string().describe("
|
|
42397
|
+
project_key: tool.schema.string().describe("Project path (e.g., '/Users/name/project')"),
|
|
42398
|
+
agent_name: tool.schema.string().describe("Your agent name from swarmmail_init"),
|
|
42399
|
+
bead_id: tool.schema.string().describe("Task ID from your spawn prompt or hive cell"),
|
|
42215
42400
|
status: tool.schema.enum(["in_progress", "blocked", "completed", "failed"]).describe("Current status"),
|
|
42216
42401
|
message: tool.schema.string().optional().describe("Progress message or blockers"),
|
|
42217
42402
|
progress_percent: tool.schema.number().min(0).max(100).optional().describe("Completion percentage"),
|
|
42218
42403
|
files_touched: tool.schema.array(tool.schema.string()).optional().describe("Files modified so far")
|
|
42219
42404
|
},
|
|
42220
42405
|
async execute(args) {
|
|
42406
|
+
const missing = [];
|
|
42407
|
+
if (!args.bead_id)
|
|
42408
|
+
missing.push("bead_id");
|
|
42409
|
+
if (!args.project_key)
|
|
42410
|
+
missing.push("project_key");
|
|
42411
|
+
if (!args.agent_name)
|
|
42412
|
+
missing.push("agent_name");
|
|
42413
|
+
if (!args.status)
|
|
42414
|
+
missing.push("status");
|
|
42415
|
+
if (missing.length > 0) {
|
|
42416
|
+
return JSON.stringify({
|
|
42417
|
+
success: false,
|
|
42418
|
+
error: `Missing required parameters: ${missing.join(", ")}`,
|
|
42419
|
+
hint: "swarm_progress reports task progress to the coordinator.",
|
|
42420
|
+
example: {
|
|
42421
|
+
project_key: "/path/to/project",
|
|
42422
|
+
agent_name: "your-agent-name",
|
|
42423
|
+
bead_id: "your-task-id from spawn",
|
|
42424
|
+
status: "in_progress",
|
|
42425
|
+
progress_percent: 50,
|
|
42426
|
+
message: "Completed X, working on Y"
|
|
42427
|
+
}
|
|
42428
|
+
}, null, 2);
|
|
42429
|
+
}
|
|
42221
42430
|
const progress = {
|
|
42222
42431
|
bead_id: args.bead_id,
|
|
42223
42432
|
agent_name: args.agent_name,
|
|
@@ -42343,12 +42552,12 @@ ${args.files_affected.map((f) => `- \`${f}\``).join(`
|
|
|
42343
42552
|
}
|
|
42344
42553
|
});
|
|
42345
42554
|
var swarm_complete = tool({
|
|
42346
|
-
description: "Mark subtask complete with Verification Gate. Runs typecheck
|
|
42555
|
+
description: "Mark subtask complete with Verification Gate. REQUIRED: project_key, agent_name, bead_id (from your task assignment), summary, start_time (Date.now() from when you started). Before calling: 1) hivemind_store your learnings, 2) list files_touched for verification. Runs typecheck/tests before finalizing.",
|
|
42347
42556
|
args: {
|
|
42348
|
-
project_key: tool.schema.string().describe("Project path"),
|
|
42349
|
-
agent_name: tool.schema.string().describe("Your
|
|
42350
|
-
bead_id: tool.schema.string().describe("
|
|
42351
|
-
summary: tool.schema.string().describe("
|
|
42557
|
+
project_key: tool.schema.string().describe("Project path (e.g., '/Users/name/project')"),
|
|
42558
|
+
agent_name: tool.schema.string().describe("Your agent name from swarmmail_init"),
|
|
42559
|
+
bead_id: tool.schema.string().describe("Task ID from your spawn prompt or hive cell"),
|
|
42560
|
+
summary: tool.schema.string().describe("What you accomplished (1-3 sentences)"),
|
|
42352
42561
|
evaluation: tool.schema.string().optional().describe("Self-evaluation JSON (Evaluation schema)"),
|
|
42353
42562
|
files_touched: tool.schema.array(tool.schema.string()).optional().describe("Files modified - will be verified (typecheck, tests)"),
|
|
42354
42563
|
skip_verification: tool.schema.boolean().optional().describe("Skip ALL verification (typecheck, tests). Use sparingly! (default: false)"),
|
|
@@ -42359,6 +42568,33 @@ var swarm_complete = tool({
|
|
|
42359
42568
|
skip_review: tool.schema.boolean().optional().describe("Skip review gate check (default: false). Use only for tasks that don't require coordinator review.")
|
|
42360
42569
|
},
|
|
42361
42570
|
async execute(args, _ctx) {
|
|
42571
|
+
const missing = [];
|
|
42572
|
+
if (!args.bead_id)
|
|
42573
|
+
missing.push("bead_id");
|
|
42574
|
+
if (!args.project_key)
|
|
42575
|
+
missing.push("project_key");
|
|
42576
|
+
if (!args.agent_name)
|
|
42577
|
+
missing.push("agent_name");
|
|
42578
|
+
if (!args.summary)
|
|
42579
|
+
missing.push("summary");
|
|
42580
|
+
if (args.start_time === undefined)
|
|
42581
|
+
missing.push("start_time");
|
|
42582
|
+
if (missing.length > 0) {
|
|
42583
|
+
return JSON.stringify({
|
|
42584
|
+
success: false,
|
|
42585
|
+
error: `Missing required parameters: ${missing.join(", ")}`,
|
|
42586
|
+
hint: "swarm_complete marks a subtask as done. All parameters are required.",
|
|
42587
|
+
example: {
|
|
42588
|
+
project_key: "/path/to/project",
|
|
42589
|
+
agent_name: "your-agent-name",
|
|
42590
|
+
bead_id: "epic-id.subtask-num OR cell-id from hive",
|
|
42591
|
+
summary: "Brief description of what you completed",
|
|
42592
|
+
start_time: Date.now(),
|
|
42593
|
+
files_touched: ["src/file1.ts", "src/file2.ts"]
|
|
42594
|
+
},
|
|
42595
|
+
tip: "The bead_id comes from swarm_spawn_subtask or hive_create. Check your task assignment for the correct ID."
|
|
42596
|
+
}, null, 2);
|
|
42597
|
+
}
|
|
42362
42598
|
const epicId = args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id;
|
|
42363
42599
|
if (!args.skip_review) {
|
|
42364
42600
|
const reviewStatusResult = getReviewStatus(args.bead_id);
|
|
@@ -42559,6 +42795,7 @@ This will be recorded as a negative learning signal.`;
|
|
|
42559
42795
|
}
|
|
42560
42796
|
const completionDurationMs = Date.now() - args.start_time;
|
|
42561
42797
|
const eventEpicId = cell.parent_id || (args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id);
|
|
42798
|
+
let outcomeEventId;
|
|
42562
42799
|
try {
|
|
42563
42800
|
const event = createEvent3("subtask_outcome", {
|
|
42564
42801
|
project_key: args.project_key,
|
|
@@ -42573,10 +42810,23 @@ This will be recorded as a negative learning signal.`;
|
|
|
42573
42810
|
scope_violation: contractValidation ? !contractValidation.valid : undefined,
|
|
42574
42811
|
violation_files: contractValidation?.violations
|
|
42575
42812
|
});
|
|
42576
|
-
await appendEvent2(event, args.project_key);
|
|
42813
|
+
const savedEvent = await appendEvent2(event, args.project_key);
|
|
42814
|
+
outcomeEventId = savedEvent.id;
|
|
42577
42815
|
} catch (error45) {
|
|
42578
42816
|
console.warn("[swarm_complete] Failed to emit SubtaskOutcomeEvent:", error45);
|
|
42579
42817
|
}
|
|
42818
|
+
if (outcomeEventId) {
|
|
42819
|
+
try {
|
|
42820
|
+
const { linkOutcomeToDecisionTrace: linkOutcomeToDecisionTrace2 } = await Promise.resolve().then(() => (init_decision_trace_integration(), exports_decision_trace_integration));
|
|
42821
|
+
await linkOutcomeToDecisionTrace2({
|
|
42822
|
+
projectKey: args.project_key,
|
|
42823
|
+
beadId: args.bead_id,
|
|
42824
|
+
outcomeEventId
|
|
42825
|
+
});
|
|
42826
|
+
} catch (error45) {
|
|
42827
|
+
console.warn("[swarm_complete] Failed to link outcome to decision trace:", error45);
|
|
42828
|
+
}
|
|
42829
|
+
}
|
|
42580
42830
|
try {
|
|
42581
42831
|
const workerCompletedEvent = createEvent3("worker_completed", {
|
|
42582
42832
|
project_key: args.project_key,
|
|
@@ -43538,6 +43788,7 @@ ${skillBody}`, "utf-8");
|
|
|
43538
43788
|
// src/swarm-prompts.ts
|
|
43539
43789
|
init_eval_capture();
|
|
43540
43790
|
init_memory_tools();
|
|
43791
|
+
init_decision_trace_integration();
|
|
43541
43792
|
var DECOMPOSITION_PROMPT = `You are decomposing a task into parallelizable subtasks for a swarm of agents.
|
|
43542
43793
|
|
|
43543
43794
|
## Task
|
|
@@ -43746,6 +43997,26 @@ Before writing code:
|
|
|
43746
43997
|
Begin work on your subtask now.`;
|
|
43747
43998
|
var SUBTASK_PROMPT_V2 = `You are a swarm agent working on: **{subtask_title}**
|
|
43748
43999
|
|
|
44000
|
+
╔═══════════════════════════════════════════════════════════════════════════════╗
|
|
44001
|
+
║ ║
|
|
44002
|
+
║ \uD83D\uDED1 STOP - READ THIS FIRST - BEFORE ANY EDIT OR WRITE \uD83D\uDED1 ║
|
|
44003
|
+
║ ║
|
|
44004
|
+
║ You MUST do these 3 things BEFORE your first Edit/Write call: ║
|
|
44005
|
+
║ ║
|
|
44006
|
+
║ 1️⃣ hivemind_find(query="<your task keywords>", limit=5, expand=true) ║
|
|
44007
|
+
║ → Check if past agents already solved this ║
|
|
44008
|
+
║ → Find gotchas, patterns, warnings ║
|
|
44009
|
+
║ ║
|
|
44010
|
+
║ 2️⃣ skills_list() then skills_use(name="<relevant>") ║
|
|
44011
|
+
║ → testing-patterns, swarm-coordination, system-design ║
|
|
44012
|
+
║ ║
|
|
44013
|
+
║ 3️⃣ swarmmail_send(to=["coordinator"], ...) when blocked ║
|
|
44014
|
+
║ → Don't spin >5min - ASK FOR HELP ║
|
|
44015
|
+
║ ║
|
|
44016
|
+
║ SKIPPING THESE = wasted time repeating solved problems ║
|
|
44017
|
+
║ ║
|
|
44018
|
+
╚═══════════════════════════════════════════════════════════════════════════════╝
|
|
44019
|
+
|
|
43749
44020
|
## [IDENTITY]
|
|
43750
44021
|
Agent: (assigned at spawn)
|
|
43751
44022
|
Cell: {bead_id}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-availability.d.ts","sourceRoot":"","sources":["../src/tool-availability.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAUH,MAAM,MAAM,QAAQ,GAChB,iBAAiB,GACjB,MAAM,GACN,UAAU,GACV,MAAM,GACN,OAAO,GACP,YAAY,GACZ,YAAY,CAAC;AAEjB,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,UAAU,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;
|
|
1
|
+
{"version":3,"file":"tool-availability.d.ts","sourceRoot":"","sources":["../src/tool-availability.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAUH,MAAM,MAAM,QAAQ,GAChB,iBAAiB,GACjB,MAAM,GACN,UAAU,GACV,MAAM,GACN,OAAO,GACP,YAAY,GACZ,YAAY,CAAC;AAEjB,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,UAAU,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AA6RD;;;;;GAKG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,CAWnE;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAGtE;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,QAAQ,GACb,OAAO,CAAC,gBAAgB,CAAC,CAO3B;AAED;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAC5C,GAAG,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAChC,CA0BA;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,CAQpD;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAO/D;AAED;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CAAC,CAAC,EACtC,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACxB,QAAQ,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAC7B,OAAO,CAAC,CAAC,CAAC,CASZ;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,CAAC,EACrC,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACvB,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CASxB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAGrC;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,YAAY,EAAE,GAAG,CAAC,QAAQ,EAAE,gBAAgB,CAAC,GAC5C,MAAM,CAWR"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.59.0",
|
|
4
4
|
"description": "Multi-agent swarm coordination for OpenCode with learning capabilities, beads integration, and Agent Mail",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"minimatch": "^10.1.1",
|
|
71
71
|
"pino": "^9.6.0",
|
|
72
72
|
"pino-roll": "^1.3.0",
|
|
73
|
-
"swarm-mail": "1.10.
|
|
73
|
+
"swarm-mail": "1.10.3",
|
|
74
74
|
"yaml": "^2.8.2",
|
|
75
75
|
"zod": "4.1.8"
|
|
76
76
|
},
|