opencode-swarm-plugin 0.21.0 → 0.22.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/.beads/issues.jsonl +13 -2
- package/README.md +316 -51
- package/dist/index.js +287 -150
- package/dist/plugin.js +272 -144
- package/docs/semantic-memory-cli-syntax.md +123 -0
- package/docs/swarm-mail-architecture.md +1147 -0
- package/package.json +1 -1
- package/scripts/cleanup-test-memories.ts +346 -0
- package/src/learning.integration.test.ts +19 -4
- package/src/storage.ts +117 -5
- package/src/swarm-orchestrate.ts +392 -239
- package/src/swarm.integration.test.ts +124 -0
- package/vitest.integration.config.ts +6 -0
- package/vitest.integration.setup.ts +48 -0
package/dist/plugin.js
CHANGED
|
@@ -35359,14 +35359,16 @@ var swarm_complete = tool({
|
|
|
35359
35359
|
retry_count: tool.schema.number().optional().describe("Number of retry attempts during task")
|
|
35360
35360
|
},
|
|
35361
35361
|
async execute(args) {
|
|
35362
|
-
const
|
|
35363
|
-
let agentRegistered = false;
|
|
35364
|
-
let registrationWarning = "";
|
|
35362
|
+
const epicId = args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id;
|
|
35365
35363
|
try {
|
|
35366
|
-
const
|
|
35367
|
-
agentRegistered =
|
|
35368
|
-
|
|
35369
|
-
|
|
35364
|
+
const projectKey = args.project_key.replace(/\//g, "-").replace(/\\/g, "-");
|
|
35365
|
+
let agentRegistered = false;
|
|
35366
|
+
let registrationWarning = "";
|
|
35367
|
+
try {
|
|
35368
|
+
const agent = await getAgent(projectKey, args.agent_name, args.project_key);
|
|
35369
|
+
agentRegistered = agent !== null;
|
|
35370
|
+
if (!agentRegistered) {
|
|
35371
|
+
registrationWarning = `⚠️ WARNING: Agent '${args.agent_name}' was NOT registered in swarm-mail for project '${projectKey}'.
|
|
35370
35372
|
|
|
35371
35373
|
This usually means you skipped the MANDATORY swarmmail_init step.
|
|
35372
35374
|
|
|
@@ -35379,150 +35381,176 @@ This usually means you skipped the MANDATORY swarmmail_init step.
|
|
|
35379
35381
|
**Next time:** Run swarmmail_init(project_path="${args.project_key}", task_description="<task>") FIRST, before any other work.
|
|
35380
35382
|
|
|
35381
35383
|
Continuing with completion, but this should be fixed for future subtasks.`;
|
|
35382
|
-
|
|
35384
|
+
console.warn(`[swarm_complete] ${registrationWarning}`);
|
|
35385
|
+
}
|
|
35386
|
+
} catch (error45) {
|
|
35387
|
+
console.warn(`[swarm_complete] Could not verify agent registration:`, error45);
|
|
35388
|
+
registrationWarning = `ℹ️ Could not verify swarm-mail registration (database may not be available). Consider running swarmmail_init next time.`;
|
|
35383
35389
|
}
|
|
35384
|
-
|
|
35385
|
-
|
|
35386
|
-
|
|
35387
|
-
|
|
35388
|
-
|
|
35389
|
-
|
|
35390
|
-
|
|
35391
|
-
|
|
35392
|
-
|
|
35393
|
-
|
|
35394
|
-
|
|
35395
|
-
|
|
35396
|
-
|
|
35397
|
-
|
|
35398
|
-
|
|
35399
|
-
|
|
35400
|
-
|
|
35401
|
-
|
|
35402
|
-
|
|
35403
|
-
|
|
35404
|
-
|
|
35405
|
-
|
|
35406
|
-
|
|
35407
|
-
hint: verificationResult.blockers.length > 0 ? `Fix these issues: ${verificationResult.blockers.map((b, i) => `${i + 1}. ${b}`).join(", ")}. Use skip_verification=true only as last resort.` : "Fix the failing checks and try again. Use skip_verification=true only as last resort.",
|
|
35408
|
-
gate_function: "IDENTIFY → RUN → READ → VERIFY → CLAIM (you are at VERIFY, claim blocked)"
|
|
35409
|
-
}, null, 2);
|
|
35390
|
+
let verificationResult = null;
|
|
35391
|
+
if (!args.skip_verification && args.files_touched?.length) {
|
|
35392
|
+
verificationResult = await runVerificationGate(args.files_touched, args.skip_ubs_scan ?? false);
|
|
35393
|
+
if (!verificationResult.passed) {
|
|
35394
|
+
return JSON.stringify({
|
|
35395
|
+
success: false,
|
|
35396
|
+
error: "Verification Gate FAILED - fix issues before completing",
|
|
35397
|
+
verification: {
|
|
35398
|
+
passed: false,
|
|
35399
|
+
summary: verificationResult.summary,
|
|
35400
|
+
blockers: verificationResult.blockers,
|
|
35401
|
+
steps: verificationResult.steps.map((s) => ({
|
|
35402
|
+
name: s.name,
|
|
35403
|
+
passed: s.passed,
|
|
35404
|
+
skipped: s.skipped,
|
|
35405
|
+
skipReason: s.skipReason,
|
|
35406
|
+
error: s.error?.slice(0, 200)
|
|
35407
|
+
}))
|
|
35408
|
+
},
|
|
35409
|
+
hint: verificationResult.blockers.length > 0 ? `Fix these issues: ${verificationResult.blockers.map((b, i) => `${i + 1}. ${b}`).join(", ")}. Use skip_verification=true only as last resort.` : "Fix the failing checks and try again. Use skip_verification=true only as last resort.",
|
|
35410
|
+
gate_function: "IDENTIFY → RUN → READ → VERIFY → CLAIM (you are at VERIFY, claim blocked)"
|
|
35411
|
+
}, null, 2);
|
|
35412
|
+
}
|
|
35410
35413
|
}
|
|
35411
|
-
|
|
35412
|
-
|
|
35413
|
-
|
|
35414
|
-
|
|
35415
|
-
|
|
35416
|
-
|
|
35417
|
-
|
|
35418
|
-
|
|
35419
|
-
|
|
35420
|
-
|
|
35421
|
-
|
|
35422
|
-
|
|
35423
|
-
|
|
35424
|
-
}
|
|
35414
|
+
let ubsResult = null;
|
|
35415
|
+
if (!args.skip_verification && !verificationResult && args.files_touched?.length && !args.skip_ubs_scan) {
|
|
35416
|
+
ubsResult = await runUbsScan(args.files_touched);
|
|
35417
|
+
if (ubsResult && ubsResult.summary.critical > 0) {
|
|
35418
|
+
return JSON.stringify({
|
|
35419
|
+
success: false,
|
|
35420
|
+
error: `UBS found ${ubsResult.summary.critical} critical bug(s) that must be fixed before completing`,
|
|
35421
|
+
ubs_scan: {
|
|
35422
|
+
critical_count: ubsResult.summary.critical,
|
|
35423
|
+
bugs: ubsResult.bugs.filter((b) => b.severity === "critical")
|
|
35424
|
+
},
|
|
35425
|
+
hint: `Fix these critical bugs: ${ubsResult.bugs.filter((b) => b.severity === "critical").map((b) => `${b.file}:${b.line} - ${b.message}`).slice(0, 3).join("; ")}. Try: Run 'ubs scan ${args.files_touched?.join(" ") || "."} --json' for full report, fix reported issues, or use skip_ubs_scan=true to bypass (not recommended).`
|
|
35426
|
+
}, null, 2);
|
|
35427
|
+
}
|
|
35428
|
+
}
|
|
35429
|
+
let parsedEvaluation;
|
|
35430
|
+
if (args.evaluation) {
|
|
35431
|
+
try {
|
|
35432
|
+
parsedEvaluation = EvaluationSchema.parse(JSON.parse(args.evaluation));
|
|
35433
|
+
} catch (error45) {
|
|
35434
|
+
return JSON.stringify({
|
|
35435
|
+
success: false,
|
|
35436
|
+
error: "Invalid evaluation format",
|
|
35437
|
+
details: error45 instanceof exports_external.ZodError ? error45.issues : String(error45)
|
|
35438
|
+
}, null, 2);
|
|
35439
|
+
}
|
|
35440
|
+
if (!parsedEvaluation.passed) {
|
|
35441
|
+
return JSON.stringify({
|
|
35442
|
+
success: false,
|
|
35443
|
+
error: "Self-evaluation failed",
|
|
35444
|
+
retry_suggestion: parsedEvaluation.retry_suggestion,
|
|
35445
|
+
feedback: parsedEvaluation.overall_feedback
|
|
35446
|
+
}, null, 2);
|
|
35447
|
+
}
|
|
35448
|
+
}
|
|
35449
|
+
const closeResult = await Bun.$`bd close ${args.bead_id} --reason ${args.summary} --json`.quiet().nothrow();
|
|
35450
|
+
if (closeResult.exitCode !== 0) {
|
|
35451
|
+
throw new Error(`Failed to close bead because bd close command failed: ${closeResult.stderr.toString()}. Try: Verify bead exists and is not already closed with 'bd show ${args.bead_id}', check if bead ID is correct with 'beads_query()', or use beads_close tool directly.`);
|
|
35425
35452
|
}
|
|
35426
|
-
}
|
|
35427
|
-
let parsedEvaluation;
|
|
35428
|
-
if (args.evaluation) {
|
|
35429
35453
|
try {
|
|
35430
|
-
|
|
35454
|
+
const epicId3 = args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id;
|
|
35455
|
+
const durationMs2 = args.start_time ? Date.now() - args.start_time : 0;
|
|
35456
|
+
const event = createEvent("subtask_outcome", {
|
|
35457
|
+
project_key: args.project_key,
|
|
35458
|
+
epic_id: epicId3,
|
|
35459
|
+
bead_id: args.bead_id,
|
|
35460
|
+
planned_files: args.planned_files || [],
|
|
35461
|
+
actual_files: args.files_touched || [],
|
|
35462
|
+
duration_ms: durationMs2,
|
|
35463
|
+
error_count: args.error_count || 0,
|
|
35464
|
+
retry_count: args.retry_count || 0,
|
|
35465
|
+
success: true
|
|
35466
|
+
});
|
|
35467
|
+
await appendEvent(event, args.project_key);
|
|
35431
35468
|
} catch (error45) {
|
|
35432
|
-
|
|
35433
|
-
success: false,
|
|
35434
|
-
error: "Invalid evaluation format",
|
|
35435
|
-
details: error45 instanceof exports_external.ZodError ? error45.issues : String(error45)
|
|
35436
|
-
}, null, 2);
|
|
35469
|
+
console.warn("[swarm_complete] Failed to emit SubtaskOutcomeEvent:", error45);
|
|
35437
35470
|
}
|
|
35438
|
-
|
|
35439
|
-
|
|
35440
|
-
|
|
35441
|
-
|
|
35442
|
-
|
|
35443
|
-
|
|
35444
|
-
|
|
35471
|
+
let capturedStrategy;
|
|
35472
|
+
const durationMs = args.start_time ? Date.now() - args.start_time : 0;
|
|
35473
|
+
const memoryInfo = formatMemoryStoreOnSuccess(args.bead_id, args.summary, args.files_touched || [], capturedStrategy);
|
|
35474
|
+
let memoryStored = false;
|
|
35475
|
+
let memoryError;
|
|
35476
|
+
try {
|
|
35477
|
+
const memoryAvailable = await isToolAvailable("semantic-memory");
|
|
35478
|
+
if (memoryAvailable) {
|
|
35479
|
+
const storeResult = await Bun.$`semantic-memory store ${memoryInfo.information} --metadata ${memoryInfo.metadata}`.quiet().nothrow();
|
|
35480
|
+
if (storeResult.exitCode === 0) {
|
|
35481
|
+
memoryStored = true;
|
|
35482
|
+
console.log(`[swarm_complete] Stored learning for ${args.bead_id} in semantic-memory`);
|
|
35483
|
+
} else {
|
|
35484
|
+
memoryError = `semantic-memory store failed: ${storeResult.stderr.toString().slice(0, 200)}`;
|
|
35485
|
+
console.warn(`[swarm_complete] ${memoryError}`);
|
|
35486
|
+
}
|
|
35487
|
+
} else {
|
|
35488
|
+
memoryError = "semantic-memory not available - learning stored in-memory only";
|
|
35489
|
+
warnMissingTool("semantic-memory");
|
|
35490
|
+
}
|
|
35491
|
+
} catch (error45) {
|
|
35492
|
+
memoryError = `Failed to store memory: ${error45 instanceof Error ? error45.message : String(error45)}`;
|
|
35493
|
+
console.warn(`[swarm_complete] ${memoryError}`);
|
|
35494
|
+
}
|
|
35495
|
+
try {
|
|
35496
|
+
await releaseSwarmFiles({
|
|
35497
|
+
projectPath: args.project_key,
|
|
35498
|
+
agentName: args.agent_name
|
|
35499
|
+
});
|
|
35500
|
+
} catch (error45) {
|
|
35501
|
+
console.warn(`[swarm] Failed to release file reservations for ${args.agent_name}:`, error45);
|
|
35445
35502
|
}
|
|
35446
|
-
}
|
|
35447
|
-
const closeResult = await Bun.$`bd close ${args.bead_id} --reason ${args.summary} --json`.quiet().nothrow();
|
|
35448
|
-
if (closeResult.exitCode !== 0) {
|
|
35449
|
-
throw new Error(`Failed to close bead because bd close command failed: ${closeResult.stderr.toString()}. Try: Verify bead exists and is not already closed with 'bd show ${args.bead_id}', check if bead ID is correct with 'beads_query()', or use beads_close tool directly.`);
|
|
35450
|
-
}
|
|
35451
|
-
try {
|
|
35452
35503
|
const epicId2 = args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id;
|
|
35453
|
-
const
|
|
35454
|
-
|
|
35455
|
-
|
|
35456
|
-
|
|
35457
|
-
|
|
35458
|
-
|
|
35459
|
-
|
|
35460
|
-
|
|
35461
|
-
|
|
35462
|
-
|
|
35463
|
-
|
|
35464
|
-
|
|
35465
|
-
await appendEvent(event, args.project_key);
|
|
35466
|
-
} catch (error45) {
|
|
35467
|
-
console.warn("[swarm_complete] Failed to emit SubtaskOutcomeEvent:", error45);
|
|
35468
|
-
}
|
|
35469
|
-
try {
|
|
35470
|
-
await releaseSwarmFiles({
|
|
35504
|
+
const completionBody = [
|
|
35505
|
+
`## Subtask Complete: ${args.bead_id}`,
|
|
35506
|
+
"",
|
|
35507
|
+
`**Summary**: ${args.summary}`,
|
|
35508
|
+
"",
|
|
35509
|
+
parsedEvaluation ? `**Self-Evaluation**: ${parsedEvaluation.passed ? "PASSED" : "FAILED"}` : "",
|
|
35510
|
+
parsedEvaluation?.overall_feedback ? `**Feedback**: ${parsedEvaluation.overall_feedback}` : "",
|
|
35511
|
+
"",
|
|
35512
|
+
`**Memory Capture**: ${memoryStored ? "✓ Stored in semantic-memory" : `✗ ${memoryError || "Failed"}`}`
|
|
35513
|
+
].filter(Boolean).join(`
|
|
35514
|
+
`);
|
|
35515
|
+
await sendSwarmMessage({
|
|
35471
35516
|
projectPath: args.project_key,
|
|
35472
|
-
|
|
35517
|
+
fromAgent: args.agent_name,
|
|
35518
|
+
toAgents: [],
|
|
35519
|
+
subject: `Complete: ${args.bead_id}`,
|
|
35520
|
+
body: completionBody,
|
|
35521
|
+
threadId: epicId2,
|
|
35522
|
+
importance: "normal"
|
|
35473
35523
|
});
|
|
35474
|
-
|
|
35475
|
-
|
|
35476
|
-
|
|
35477
|
-
|
|
35478
|
-
|
|
35479
|
-
|
|
35480
|
-
|
|
35481
|
-
|
|
35482
|
-
|
|
35483
|
-
|
|
35484
|
-
|
|
35485
|
-
|
|
35486
|
-
|
|
35487
|
-
|
|
35488
|
-
|
|
35489
|
-
|
|
35490
|
-
|
|
35491
|
-
|
|
35492
|
-
|
|
35493
|
-
|
|
35494
|
-
|
|
35495
|
-
|
|
35496
|
-
|
|
35497
|
-
|
|
35498
|
-
|
|
35499
|
-
|
|
35500
|
-
|
|
35501
|
-
|
|
35502
|
-
|
|
35503
|
-
|
|
35504
|
-
warning: registrationWarning || undefined
|
|
35505
|
-
},
|
|
35506
|
-
verification_gate: verificationResult ? {
|
|
35507
|
-
passed: true,
|
|
35508
|
-
summary: verificationResult.summary,
|
|
35509
|
-
steps: verificationResult.steps.map((s) => ({
|
|
35510
|
-
name: s.name,
|
|
35511
|
-
passed: s.passed,
|
|
35512
|
-
skipped: s.skipped,
|
|
35513
|
-
skipReason: s.skipReason
|
|
35514
|
-
}))
|
|
35515
|
-
} : args.skip_verification ? { skipped: true, reason: "skip_verification=true" } : { skipped: true, reason: "no files_touched provided" },
|
|
35516
|
-
ubs_scan: ubsResult ? {
|
|
35517
|
-
ran: true,
|
|
35518
|
-
bugs_found: ubsResult.summary.total,
|
|
35519
|
-
summary: ubsResult.summary,
|
|
35520
|
-
warnings: ubsResult.bugs.filter((b) => b.severity !== "critical")
|
|
35521
|
-
} : verificationResult ? { ran: true, included_in_verification_gate: true } : {
|
|
35522
|
-
ran: false,
|
|
35523
|
-
reason: args.skip_ubs_scan ? "skipped" : "no files or ubs unavailable"
|
|
35524
|
-
},
|
|
35525
|
-
learning_prompt: `## Reflection
|
|
35524
|
+
const response = {
|
|
35525
|
+
success: true,
|
|
35526
|
+
bead_id: args.bead_id,
|
|
35527
|
+
closed: true,
|
|
35528
|
+
reservations_released: true,
|
|
35529
|
+
message_sent: true,
|
|
35530
|
+
agent_registration: {
|
|
35531
|
+
verified: agentRegistered,
|
|
35532
|
+
warning: registrationWarning || undefined
|
|
35533
|
+
},
|
|
35534
|
+
verification_gate: verificationResult ? {
|
|
35535
|
+
passed: true,
|
|
35536
|
+
summary: verificationResult.summary,
|
|
35537
|
+
steps: verificationResult.steps.map((s) => ({
|
|
35538
|
+
name: s.name,
|
|
35539
|
+
passed: s.passed,
|
|
35540
|
+
skipped: s.skipped,
|
|
35541
|
+
skipReason: s.skipReason
|
|
35542
|
+
}))
|
|
35543
|
+
} : args.skip_verification ? { skipped: true, reason: "skip_verification=true" } : { skipped: true, reason: "no files_touched provided" },
|
|
35544
|
+
ubs_scan: ubsResult ? {
|
|
35545
|
+
ran: true,
|
|
35546
|
+
bugs_found: ubsResult.summary.total,
|
|
35547
|
+
summary: ubsResult.summary,
|
|
35548
|
+
warnings: ubsResult.bugs.filter((b) => b.severity !== "critical")
|
|
35549
|
+
} : verificationResult ? { ran: true, included_in_verification_gate: true } : {
|
|
35550
|
+
ran: false,
|
|
35551
|
+
reason: args.skip_ubs_scan ? "skipped" : "no files or ubs unavailable"
|
|
35552
|
+
},
|
|
35553
|
+
learning_prompt: `## Reflection
|
|
35526
35554
|
|
|
35527
35555
|
Did you learn anything reusable during this subtask? Consider:
|
|
35528
35556
|
|
|
@@ -35534,9 +35562,81 @@ Did you learn anything reusable during this subtask? Consider:
|
|
|
35534
35562
|
If you discovered something valuable, use \`swarm_learn\` or \`skills_create\` to preserve it as a skill for future swarms.
|
|
35535
35563
|
|
|
35536
35564
|
Files touched: ${args.files_touched?.join(", ") || "none recorded"}`,
|
|
35537
|
-
|
|
35538
|
-
|
|
35539
|
-
|
|
35565
|
+
memory_capture: {
|
|
35566
|
+
attempted: true,
|
|
35567
|
+
stored: memoryStored,
|
|
35568
|
+
error: memoryError,
|
|
35569
|
+
information: memoryInfo.information,
|
|
35570
|
+
metadata: memoryInfo.metadata,
|
|
35571
|
+
note: memoryStored ? "Learning automatically stored in semantic-memory" : `Failed to store: ${memoryError}. Learning lost unless semantic-memory is available.`
|
|
35572
|
+
}
|
|
35573
|
+
};
|
|
35574
|
+
return JSON.stringify(response, null, 2);
|
|
35575
|
+
} catch (error45) {
|
|
35576
|
+
const errorMessage = error45 instanceof Error ? error45.message : String(error45);
|
|
35577
|
+
const errorStack = error45 instanceof Error ? error45.stack : undefined;
|
|
35578
|
+
let failedStep = "unknown";
|
|
35579
|
+
if (errorMessage.includes("verification")) {
|
|
35580
|
+
failedStep = "Verification Gate (UBS/typecheck/tests)";
|
|
35581
|
+
} else if (errorMessage.includes("UBS") || errorMessage.includes("ubs")) {
|
|
35582
|
+
failedStep = "UBS scan";
|
|
35583
|
+
} else if (errorMessage.includes("evaluation")) {
|
|
35584
|
+
failedStep = "Self-evaluation parsing";
|
|
35585
|
+
} else if (errorMessage.includes("bead") || errorMessage.includes("close")) {
|
|
35586
|
+
failedStep = "Bead close";
|
|
35587
|
+
} else if (errorMessage.includes("memory") || errorMessage.includes("semantic")) {
|
|
35588
|
+
failedStep = "Memory storage (non-fatal)";
|
|
35589
|
+
} else if (errorMessage.includes("reservation") || errorMessage.includes("release")) {
|
|
35590
|
+
failedStep = "File reservation release";
|
|
35591
|
+
} else if (errorMessage.includes("message") || errorMessage.includes("mail")) {
|
|
35592
|
+
failedStep = "Swarm mail notification";
|
|
35593
|
+
}
|
|
35594
|
+
const errorBody = [
|
|
35595
|
+
`## ⚠️ SWARM_COMPLETE FAILED`,
|
|
35596
|
+
"",
|
|
35597
|
+
`**Bead**: ${args.bead_id}`,
|
|
35598
|
+
`**Agent**: ${args.agent_name}`,
|
|
35599
|
+
`**Failed Step**: ${failedStep}`,
|
|
35600
|
+
"",
|
|
35601
|
+
`### Error Message`,
|
|
35602
|
+
"```",
|
|
35603
|
+
errorMessage,
|
|
35604
|
+
"```",
|
|
35605
|
+
"",
|
|
35606
|
+
errorStack ? `### Stack Trace
|
|
35607
|
+
\`\`\`
|
|
35608
|
+
${errorStack.slice(0, 1000)}
|
|
35609
|
+
\`\`\`
|
|
35610
|
+
` : "",
|
|
35611
|
+
`### Context`,
|
|
35612
|
+
`- **Summary**: ${args.summary}`,
|
|
35613
|
+
`- **Files touched**: ${args.files_touched?.length ? args.files_touched.join(", ") : "none"}`,
|
|
35614
|
+
`- **Skip UBS**: ${args.skip_ubs_scan ?? false}`,
|
|
35615
|
+
`- **Skip verification**: ${args.skip_verification ?? false}`,
|
|
35616
|
+
"",
|
|
35617
|
+
`### Recovery Actions`,
|
|
35618
|
+
"1. Check error message for specific issue",
|
|
35619
|
+
"2. Review failed step (UBS scan, typecheck, bead close, etc.)",
|
|
35620
|
+
"3. Fix underlying issue or use skip flags if appropriate",
|
|
35621
|
+
"4. Retry swarm_complete after fixing"
|
|
35622
|
+
].filter(Boolean).join(`
|
|
35623
|
+
`);
|
|
35624
|
+
try {
|
|
35625
|
+
await sendSwarmMessage({
|
|
35626
|
+
projectPath: args.project_key,
|
|
35627
|
+
fromAgent: args.agent_name,
|
|
35628
|
+
toAgents: [],
|
|
35629
|
+
subject: `FAILED: swarm_complete for ${args.bead_id}`,
|
|
35630
|
+
body: errorBody,
|
|
35631
|
+
threadId: epicId,
|
|
35632
|
+
importance: "urgent"
|
|
35633
|
+
});
|
|
35634
|
+
} catch (mailError) {
|
|
35635
|
+
console.error(`[swarm_complete] CRITICAL: Failed to notify coordinator of failure for ${args.bead_id}:`, mailError);
|
|
35636
|
+
console.error(`[swarm_complete] Original error:`, error45);
|
|
35637
|
+
}
|
|
35638
|
+
throw error45;
|
|
35639
|
+
}
|
|
35540
35640
|
}
|
|
35541
35641
|
});
|
|
35542
35642
|
var swarm_record_outcome = tool({
|
|
@@ -37347,6 +37447,34 @@ class InMemoryMaturityStorage {
|
|
|
37347
37447
|
}
|
|
37348
37448
|
}
|
|
37349
37449
|
|
|
37450
|
+
// src/storage.ts
|
|
37451
|
+
function getCollectionNames() {
|
|
37452
|
+
const base = {
|
|
37453
|
+
feedback: "swarm-feedback",
|
|
37454
|
+
patterns: "swarm-patterns",
|
|
37455
|
+
maturity: "swarm-maturity"
|
|
37456
|
+
};
|
|
37457
|
+
if (process.env.TEST_MEMORY_COLLECTIONS === "true") {
|
|
37458
|
+
return {
|
|
37459
|
+
feedback: `${base.feedback}-test`,
|
|
37460
|
+
patterns: `${base.patterns}-test`,
|
|
37461
|
+
maturity: `${base.maturity}-test`
|
|
37462
|
+
};
|
|
37463
|
+
}
|
|
37464
|
+
return base;
|
|
37465
|
+
}
|
|
37466
|
+
var DEFAULT_STORAGE_CONFIG = {
|
|
37467
|
+
backend: "semantic-memory",
|
|
37468
|
+
collections: getCollectionNames(),
|
|
37469
|
+
useSemanticSearch: true
|
|
37470
|
+
};
|
|
37471
|
+
var sessionStats = {
|
|
37472
|
+
storesCount: 0,
|
|
37473
|
+
queriesCount: 0,
|
|
37474
|
+
sessionStart: Date.now(),
|
|
37475
|
+
lastAlertCheck: Date.now()
|
|
37476
|
+
};
|
|
37477
|
+
|
|
37350
37478
|
// src/index.ts
|
|
37351
37479
|
init_skills();
|
|
37352
37480
|
var SwarmPlugin = async (input) => {
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Semantic Memory CLI Syntax Reference
|
|
2
|
+
|
|
3
|
+
**CRITICAL: The semantic-memory CLI has specific JSON requirements that will fail silently if violated.**
|
|
4
|
+
|
|
5
|
+
## Working Syntax
|
|
6
|
+
|
|
7
|
+
### Store Memory (via Bash)
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
semantic-memory store \
|
|
11
|
+
--information "Your learning here with full context" \
|
|
12
|
+
--metadata '{"tags": ["tag1", "tag2", "tag3"]}'
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
**Key Rules:**
|
|
16
|
+
|
|
17
|
+
- `--metadata` MUST be valid JSON with single quotes wrapping the object
|
|
18
|
+
- Use `{"tags": [...]}` structure, NOT comma-separated strings
|
|
19
|
+
- Information can be plain text (no quotes needed in bash)
|
|
20
|
+
|
|
21
|
+
### Store Memory (via MCP tool - PREFERRED)
|
|
22
|
+
|
|
23
|
+
The MCP tool `semantic-memory_store` has different syntax:
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
semantic-memory_store(
|
|
27
|
+
information: "Your learning here",
|
|
28
|
+
metadata: "tag1, tag2, tag3" // Comma-separated string, NOT JSON
|
|
29
|
+
)
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Use the MCP tool when available - it handles JSON serialization for you.**
|
|
33
|
+
|
|
34
|
+
## Common Mistakes
|
|
35
|
+
|
|
36
|
+
### ❌ WRONG - Comma-separated string in CLI
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
semantic-memory store \
|
|
40
|
+
--metadata "swarm,edge-case,workaround"
|
|
41
|
+
# Error: Invalid JSON in --metadata
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### ❌ WRONG - Double quotes wrapping JSON
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
semantic-memory store \
|
|
48
|
+
--metadata "{"tags": ["swarm"]}"
|
|
49
|
+
# Error: Shell parsing breaks on nested quotes
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### ❌ WRONG - No tags wrapper
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
semantic-memory store \
|
|
56
|
+
--metadata '["swarm", "edge-case"]'
|
|
57
|
+
# Error: Expected object with "tags" key
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### ✅ CORRECT - JSON object with single quotes
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
semantic-memory store \
|
|
64
|
+
--information "swarm_complete fails when files outside project_key" \
|
|
65
|
+
--metadata '{"tags": ["swarm", "edge-case", "workaround"]}'
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## When to Use Which
|
|
69
|
+
|
|
70
|
+
| Context | Tool | Metadata Format |
|
|
71
|
+
| --------------------------- | ---------------------------------- | ------------------------------------- |
|
|
72
|
+
| **Inside OpenCode session** | `semantic-memory_store()` MCP tool | `"tag1, tag2, tag3"` (string) |
|
|
73
|
+
| **Direct CLI / Bash tool** | `semantic-memory store` command | `'{"tags": ["tag1", "tag2"]}'` (JSON) |
|
|
74
|
+
| **Scripts / automation** | CLI command | JSON object |
|
|
75
|
+
|
|
76
|
+
## Other Commands
|
|
77
|
+
|
|
78
|
+
### Find Memories
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
# CLI
|
|
82
|
+
semantic-memory find --query "search terms" --limit 5
|
|
83
|
+
|
|
84
|
+
# MCP tool (preferred)
|
|
85
|
+
semantic-memory_find(query="search terms", limit=5)
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Validate Memory (reset decay)
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
# CLI
|
|
92
|
+
semantic-memory validate --id "mem-uuid"
|
|
93
|
+
|
|
94
|
+
# MCP tool (preferred)
|
|
95
|
+
semantic-memory_validate(id="mem-uuid")
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### List All
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
# CLI
|
|
102
|
+
semantic-memory list
|
|
103
|
+
|
|
104
|
+
# MCP tool (preferred)
|
|
105
|
+
semantic-memory_list()
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Pro Tips
|
|
109
|
+
|
|
110
|
+
1. **Prefer MCP tools in OpenCode sessions** - they handle serialization
|
|
111
|
+
2. **Use CLI for scripts** - more control, but requires JSON knowledge
|
|
112
|
+
3. **Test metadata syntax** - run `semantic-memory list` to verify storage
|
|
113
|
+
4. **Keep tags focused** - 3-5 tags max, use domain/tech/pattern structure
|
|
114
|
+
5. **Include error messages verbatim** - makes search more effective
|
|
115
|
+
|
|
116
|
+
## Debugging
|
|
117
|
+
|
|
118
|
+
If storage fails:
|
|
119
|
+
|
|
120
|
+
1. Check `--metadata` is valid JSON: `echo '{"tags": ["test"]}' | jq`
|
|
121
|
+
2. Verify single quotes wrap the JSON object
|
|
122
|
+
3. Ensure no shell escaping issues with information text
|
|
123
|
+
4. Try MCP tool instead of CLI if in OpenCode session
|