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/dist/index.js CHANGED
@@ -35523,14 +35523,16 @@ var swarm_complete = tool({
35523
35523
  retry_count: tool.schema.number().optional().describe("Number of retry attempts during task")
35524
35524
  },
35525
35525
  async execute(args) {
35526
- const projectKey = args.project_key.replace(/\//g, "-").replace(/\\/g, "-");
35527
- let agentRegistered = false;
35528
- let registrationWarning = "";
35526
+ const epicId = args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id;
35529
35527
  try {
35530
- const agent = await getAgent(projectKey, args.agent_name, args.project_key);
35531
- agentRegistered = agent !== null;
35532
- if (!agentRegistered) {
35533
- registrationWarning = `⚠️ WARNING: Agent '${args.agent_name}' was NOT registered in swarm-mail for project '${projectKey}'.
35528
+ const projectKey = args.project_key.replace(/\//g, "-").replace(/\\/g, "-");
35529
+ let agentRegistered = false;
35530
+ let registrationWarning = "";
35531
+ try {
35532
+ const agent = await getAgent(projectKey, args.agent_name, args.project_key);
35533
+ agentRegistered = agent !== null;
35534
+ if (!agentRegistered) {
35535
+ registrationWarning = `⚠️ WARNING: Agent '${args.agent_name}' was NOT registered in swarm-mail for project '${projectKey}'.
35534
35536
 
35535
35537
  This usually means you skipped the MANDATORY swarmmail_init step.
35536
35538
 
@@ -35543,150 +35545,176 @@ This usually means you skipped the MANDATORY swarmmail_init step.
35543
35545
  **Next time:** Run swarmmail_init(project_path="${args.project_key}", task_description="<task>") FIRST, before any other work.
35544
35546
 
35545
35547
  Continuing with completion, but this should be fixed for future subtasks.`;
35546
- console.warn(`[swarm_complete] ${registrationWarning}`);
35548
+ console.warn(`[swarm_complete] ${registrationWarning}`);
35549
+ }
35550
+ } catch (error45) {
35551
+ console.warn(`[swarm_complete] Could not verify agent registration:`, error45);
35552
+ registrationWarning = `ℹ️ Could not verify swarm-mail registration (database may not be available). Consider running swarmmail_init next time.`;
35547
35553
  }
35548
- } catch (error45) {
35549
- console.warn(`[swarm_complete] Could not verify agent registration:`, error45);
35550
- registrationWarning = `ℹ️ Could not verify swarm-mail registration (database may not be available). Consider running swarmmail_init next time.`;
35551
- }
35552
- let verificationResult = null;
35553
- if (!args.skip_verification && args.files_touched?.length) {
35554
- verificationResult = await runVerificationGate(args.files_touched, args.skip_ubs_scan ?? false);
35555
- if (!verificationResult.passed) {
35556
- return JSON.stringify({
35557
- success: false,
35558
- error: "Verification Gate FAILED - fix issues before completing",
35559
- verification: {
35560
- passed: false,
35561
- summary: verificationResult.summary,
35562
- blockers: verificationResult.blockers,
35563
- steps: verificationResult.steps.map((s) => ({
35564
- name: s.name,
35565
- passed: s.passed,
35566
- skipped: s.skipped,
35567
- skipReason: s.skipReason,
35568
- error: s.error?.slice(0, 200)
35569
- }))
35570
- },
35571
- 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.",
35572
- gate_function: "IDENTIFY → RUN → READ → VERIFY → CLAIM (you are at VERIFY, claim blocked)"
35573
- }, null, 2);
35554
+ let verificationResult = null;
35555
+ if (!args.skip_verification && args.files_touched?.length) {
35556
+ verificationResult = await runVerificationGate(args.files_touched, args.skip_ubs_scan ?? false);
35557
+ if (!verificationResult.passed) {
35558
+ return JSON.stringify({
35559
+ success: false,
35560
+ error: "Verification Gate FAILED - fix issues before completing",
35561
+ verification: {
35562
+ passed: false,
35563
+ summary: verificationResult.summary,
35564
+ blockers: verificationResult.blockers,
35565
+ steps: verificationResult.steps.map((s) => ({
35566
+ name: s.name,
35567
+ passed: s.passed,
35568
+ skipped: s.skipped,
35569
+ skipReason: s.skipReason,
35570
+ error: s.error?.slice(0, 200)
35571
+ }))
35572
+ },
35573
+ 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.",
35574
+ gate_function: "IDENTIFY → RUN → READ → VERIFY → CLAIM (you are at VERIFY, claim blocked)"
35575
+ }, null, 2);
35576
+ }
35574
35577
  }
35575
- }
35576
- let ubsResult = null;
35577
- if (!args.skip_verification && !verificationResult && args.files_touched?.length && !args.skip_ubs_scan) {
35578
- ubsResult = await runUbsScan(args.files_touched);
35579
- if (ubsResult && ubsResult.summary.critical > 0) {
35580
- return JSON.stringify({
35581
- success: false,
35582
- error: `UBS found ${ubsResult.summary.critical} critical bug(s) that must be fixed before completing`,
35583
- ubs_scan: {
35584
- critical_count: ubsResult.summary.critical,
35585
- bugs: ubsResult.bugs.filter((b) => b.severity === "critical")
35586
- },
35587
- 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).`
35588
- }, null, 2);
35578
+ let ubsResult = null;
35579
+ if (!args.skip_verification && !verificationResult && args.files_touched?.length && !args.skip_ubs_scan) {
35580
+ ubsResult = await runUbsScan(args.files_touched);
35581
+ if (ubsResult && ubsResult.summary.critical > 0) {
35582
+ return JSON.stringify({
35583
+ success: false,
35584
+ error: `UBS found ${ubsResult.summary.critical} critical bug(s) that must be fixed before completing`,
35585
+ ubs_scan: {
35586
+ critical_count: ubsResult.summary.critical,
35587
+ bugs: ubsResult.bugs.filter((b) => b.severity === "critical")
35588
+ },
35589
+ 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).`
35590
+ }, null, 2);
35591
+ }
35592
+ }
35593
+ let parsedEvaluation;
35594
+ if (args.evaluation) {
35595
+ try {
35596
+ parsedEvaluation = EvaluationSchema.parse(JSON.parse(args.evaluation));
35597
+ } catch (error45) {
35598
+ return JSON.stringify({
35599
+ success: false,
35600
+ error: "Invalid evaluation format",
35601
+ details: error45 instanceof exports_external.ZodError ? error45.issues : String(error45)
35602
+ }, null, 2);
35603
+ }
35604
+ if (!parsedEvaluation.passed) {
35605
+ return JSON.stringify({
35606
+ success: false,
35607
+ error: "Self-evaluation failed",
35608
+ retry_suggestion: parsedEvaluation.retry_suggestion,
35609
+ feedback: parsedEvaluation.overall_feedback
35610
+ }, null, 2);
35611
+ }
35612
+ }
35613
+ const closeResult = await Bun.$`bd close ${args.bead_id} --reason ${args.summary} --json`.quiet().nothrow();
35614
+ if (closeResult.exitCode !== 0) {
35615
+ 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.`);
35589
35616
  }
35590
- }
35591
- let parsedEvaluation;
35592
- if (args.evaluation) {
35593
35617
  try {
35594
- parsedEvaluation = EvaluationSchema.parse(JSON.parse(args.evaluation));
35618
+ const epicId3 = args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id;
35619
+ const durationMs2 = args.start_time ? Date.now() - args.start_time : 0;
35620
+ const event = createEvent("subtask_outcome", {
35621
+ project_key: args.project_key,
35622
+ epic_id: epicId3,
35623
+ bead_id: args.bead_id,
35624
+ planned_files: args.planned_files || [],
35625
+ actual_files: args.files_touched || [],
35626
+ duration_ms: durationMs2,
35627
+ error_count: args.error_count || 0,
35628
+ retry_count: args.retry_count || 0,
35629
+ success: true
35630
+ });
35631
+ await appendEvent(event, args.project_key);
35595
35632
  } catch (error45) {
35596
- return JSON.stringify({
35597
- success: false,
35598
- error: "Invalid evaluation format",
35599
- details: error45 instanceof exports_external.ZodError ? error45.issues : String(error45)
35600
- }, null, 2);
35633
+ console.warn("[swarm_complete] Failed to emit SubtaskOutcomeEvent:", error45);
35601
35634
  }
35602
- if (!parsedEvaluation.passed) {
35603
- return JSON.stringify({
35604
- success: false,
35605
- error: "Self-evaluation failed",
35606
- retry_suggestion: parsedEvaluation.retry_suggestion,
35607
- feedback: parsedEvaluation.overall_feedback
35608
- }, null, 2);
35635
+ let capturedStrategy;
35636
+ const durationMs = args.start_time ? Date.now() - args.start_time : 0;
35637
+ const memoryInfo = formatMemoryStoreOnSuccess(args.bead_id, args.summary, args.files_touched || [], capturedStrategy);
35638
+ let memoryStored = false;
35639
+ let memoryError;
35640
+ try {
35641
+ const memoryAvailable = await isToolAvailable("semantic-memory");
35642
+ if (memoryAvailable) {
35643
+ const storeResult = await Bun.$`semantic-memory store ${memoryInfo.information} --metadata ${memoryInfo.metadata}`.quiet().nothrow();
35644
+ if (storeResult.exitCode === 0) {
35645
+ memoryStored = true;
35646
+ console.log(`[swarm_complete] Stored learning for ${args.bead_id} in semantic-memory`);
35647
+ } else {
35648
+ memoryError = `semantic-memory store failed: ${storeResult.stderr.toString().slice(0, 200)}`;
35649
+ console.warn(`[swarm_complete] ${memoryError}`);
35650
+ }
35651
+ } else {
35652
+ memoryError = "semantic-memory not available - learning stored in-memory only";
35653
+ warnMissingTool("semantic-memory");
35654
+ }
35655
+ } catch (error45) {
35656
+ memoryError = `Failed to store memory: ${error45 instanceof Error ? error45.message : String(error45)}`;
35657
+ console.warn(`[swarm_complete] ${memoryError}`);
35658
+ }
35659
+ try {
35660
+ await releaseSwarmFiles({
35661
+ projectPath: args.project_key,
35662
+ agentName: args.agent_name
35663
+ });
35664
+ } catch (error45) {
35665
+ console.warn(`[swarm] Failed to release file reservations for ${args.agent_name}:`, error45);
35609
35666
  }
35610
- }
35611
- const closeResult = await Bun.$`bd close ${args.bead_id} --reason ${args.summary} --json`.quiet().nothrow();
35612
- if (closeResult.exitCode !== 0) {
35613
- 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.`);
35614
- }
35615
- try {
35616
35667
  const epicId2 = args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id;
35617
- const durationMs = args.start_time ? Date.now() - args.start_time : 0;
35618
- const event = createEvent("subtask_outcome", {
35619
- project_key: args.project_key,
35620
- epic_id: epicId2,
35621
- bead_id: args.bead_id,
35622
- planned_files: args.planned_files || [],
35623
- actual_files: args.files_touched || [],
35624
- duration_ms: durationMs,
35625
- error_count: args.error_count || 0,
35626
- retry_count: args.retry_count || 0,
35627
- success: true
35628
- });
35629
- await appendEvent(event, args.project_key);
35630
- } catch (error45) {
35631
- console.warn("[swarm_complete] Failed to emit SubtaskOutcomeEvent:", error45);
35632
- }
35633
- try {
35634
- await releaseSwarmFiles({
35668
+ const completionBody = [
35669
+ `## Subtask Complete: ${args.bead_id}`,
35670
+ "",
35671
+ `**Summary**: ${args.summary}`,
35672
+ "",
35673
+ parsedEvaluation ? `**Self-Evaluation**: ${parsedEvaluation.passed ? "PASSED" : "FAILED"}` : "",
35674
+ parsedEvaluation?.overall_feedback ? `**Feedback**: ${parsedEvaluation.overall_feedback}` : "",
35675
+ "",
35676
+ `**Memory Capture**: ${memoryStored ? "✓ Stored in semantic-memory" : `✗ ${memoryError || "Failed"}`}`
35677
+ ].filter(Boolean).join(`
35678
+ `);
35679
+ await sendSwarmMessage({
35635
35680
  projectPath: args.project_key,
35636
- agentName: args.agent_name
35681
+ fromAgent: args.agent_name,
35682
+ toAgents: [],
35683
+ subject: `Complete: ${args.bead_id}`,
35684
+ body: completionBody,
35685
+ threadId: epicId2,
35686
+ importance: "normal"
35637
35687
  });
35638
- } catch (error45) {
35639
- console.warn(`[swarm] Failed to release file reservations for ${args.agent_name}:`, error45);
35640
- }
35641
- const epicId = args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id;
35642
- const completionBody = [
35643
- `## Subtask Complete: ${args.bead_id}`,
35644
- "",
35645
- `**Summary**: ${args.summary}`,
35646
- "",
35647
- parsedEvaluation ? `**Self-Evaluation**: ${parsedEvaluation.passed ? "PASSED" : "FAILED"}` : "",
35648
- parsedEvaluation?.overall_feedback ? `**Feedback**: ${parsedEvaluation.overall_feedback}` : ""
35649
- ].filter(Boolean).join(`
35650
- `);
35651
- await sendSwarmMessage({
35652
- projectPath: args.project_key,
35653
- fromAgent: args.agent_name,
35654
- toAgents: [],
35655
- subject: `Complete: ${args.bead_id}`,
35656
- body: completionBody,
35657
- threadId: epicId,
35658
- importance: "normal"
35659
- });
35660
- const response = {
35661
- success: true,
35662
- bead_id: args.bead_id,
35663
- closed: true,
35664
- reservations_released: true,
35665
- message_sent: true,
35666
- agent_registration: {
35667
- verified: agentRegistered,
35668
- warning: registrationWarning || undefined
35669
- },
35670
- verification_gate: verificationResult ? {
35671
- passed: true,
35672
- summary: verificationResult.summary,
35673
- steps: verificationResult.steps.map((s) => ({
35674
- name: s.name,
35675
- passed: s.passed,
35676
- skipped: s.skipped,
35677
- skipReason: s.skipReason
35678
- }))
35679
- } : args.skip_verification ? { skipped: true, reason: "skip_verification=true" } : { skipped: true, reason: "no files_touched provided" },
35680
- ubs_scan: ubsResult ? {
35681
- ran: true,
35682
- bugs_found: ubsResult.summary.total,
35683
- summary: ubsResult.summary,
35684
- warnings: ubsResult.bugs.filter((b) => b.severity !== "critical")
35685
- } : verificationResult ? { ran: true, included_in_verification_gate: true } : {
35686
- ran: false,
35687
- reason: args.skip_ubs_scan ? "skipped" : "no files or ubs unavailable"
35688
- },
35689
- learning_prompt: `## Reflection
35688
+ const response = {
35689
+ success: true,
35690
+ bead_id: args.bead_id,
35691
+ closed: true,
35692
+ reservations_released: true,
35693
+ message_sent: true,
35694
+ agent_registration: {
35695
+ verified: agentRegistered,
35696
+ warning: registrationWarning || undefined
35697
+ },
35698
+ verification_gate: verificationResult ? {
35699
+ passed: true,
35700
+ summary: verificationResult.summary,
35701
+ steps: verificationResult.steps.map((s) => ({
35702
+ name: s.name,
35703
+ passed: s.passed,
35704
+ skipped: s.skipped,
35705
+ skipReason: s.skipReason
35706
+ }))
35707
+ } : args.skip_verification ? { skipped: true, reason: "skip_verification=true" } : { skipped: true, reason: "no files_touched provided" },
35708
+ ubs_scan: ubsResult ? {
35709
+ ran: true,
35710
+ bugs_found: ubsResult.summary.total,
35711
+ summary: ubsResult.summary,
35712
+ warnings: ubsResult.bugs.filter((b) => b.severity !== "critical")
35713
+ } : verificationResult ? { ran: true, included_in_verification_gate: true } : {
35714
+ ran: false,
35715
+ reason: args.skip_ubs_scan ? "skipped" : "no files or ubs unavailable"
35716
+ },
35717
+ learning_prompt: `## Reflection
35690
35718
 
35691
35719
  Did you learn anything reusable during this subtask? Consider:
35692
35720
 
@@ -35698,9 +35726,81 @@ Did you learn anything reusable during this subtask? Consider:
35698
35726
  If you discovered something valuable, use \`swarm_learn\` or \`skills_create\` to preserve it as a skill for future swarms.
35699
35727
 
35700
35728
  Files touched: ${args.files_touched?.join(", ") || "none recorded"}`,
35701
- memory_store: formatMemoryStoreOnSuccess(args.bead_id, args.summary, args.files_touched || [])
35702
- };
35703
- return JSON.stringify(response, null, 2);
35729
+ memory_capture: {
35730
+ attempted: true,
35731
+ stored: memoryStored,
35732
+ error: memoryError,
35733
+ information: memoryInfo.information,
35734
+ metadata: memoryInfo.metadata,
35735
+ note: memoryStored ? "Learning automatically stored in semantic-memory" : `Failed to store: ${memoryError}. Learning lost unless semantic-memory is available.`
35736
+ }
35737
+ };
35738
+ return JSON.stringify(response, null, 2);
35739
+ } catch (error45) {
35740
+ const errorMessage = error45 instanceof Error ? error45.message : String(error45);
35741
+ const errorStack = error45 instanceof Error ? error45.stack : undefined;
35742
+ let failedStep = "unknown";
35743
+ if (errorMessage.includes("verification")) {
35744
+ failedStep = "Verification Gate (UBS/typecheck/tests)";
35745
+ } else if (errorMessage.includes("UBS") || errorMessage.includes("ubs")) {
35746
+ failedStep = "UBS scan";
35747
+ } else if (errorMessage.includes("evaluation")) {
35748
+ failedStep = "Self-evaluation parsing";
35749
+ } else if (errorMessage.includes("bead") || errorMessage.includes("close")) {
35750
+ failedStep = "Bead close";
35751
+ } else if (errorMessage.includes("memory") || errorMessage.includes("semantic")) {
35752
+ failedStep = "Memory storage (non-fatal)";
35753
+ } else if (errorMessage.includes("reservation") || errorMessage.includes("release")) {
35754
+ failedStep = "File reservation release";
35755
+ } else if (errorMessage.includes("message") || errorMessage.includes("mail")) {
35756
+ failedStep = "Swarm mail notification";
35757
+ }
35758
+ const errorBody = [
35759
+ `## ⚠️ SWARM_COMPLETE FAILED`,
35760
+ "",
35761
+ `**Bead**: ${args.bead_id}`,
35762
+ `**Agent**: ${args.agent_name}`,
35763
+ `**Failed Step**: ${failedStep}`,
35764
+ "",
35765
+ `### Error Message`,
35766
+ "```",
35767
+ errorMessage,
35768
+ "```",
35769
+ "",
35770
+ errorStack ? `### Stack Trace
35771
+ \`\`\`
35772
+ ${errorStack.slice(0, 1000)}
35773
+ \`\`\`
35774
+ ` : "",
35775
+ `### Context`,
35776
+ `- **Summary**: ${args.summary}`,
35777
+ `- **Files touched**: ${args.files_touched?.length ? args.files_touched.join(", ") : "none"}`,
35778
+ `- **Skip UBS**: ${args.skip_ubs_scan ?? false}`,
35779
+ `- **Skip verification**: ${args.skip_verification ?? false}`,
35780
+ "",
35781
+ `### Recovery Actions`,
35782
+ "1. Check error message for specific issue",
35783
+ "2. Review failed step (UBS scan, typecheck, bead close, etc.)",
35784
+ "3. Fix underlying issue or use skip flags if appropriate",
35785
+ "4. Retry swarm_complete after fixing"
35786
+ ].filter(Boolean).join(`
35787
+ `);
35788
+ try {
35789
+ await sendSwarmMessage({
35790
+ projectPath: args.project_key,
35791
+ fromAgent: args.agent_name,
35792
+ toAgents: [],
35793
+ subject: `FAILED: swarm_complete for ${args.bead_id}`,
35794
+ body: errorBody,
35795
+ threadId: epicId,
35796
+ importance: "urgent"
35797
+ });
35798
+ } catch (mailError) {
35799
+ console.error(`[swarm_complete] CRITICAL: Failed to notify coordinator of failure for ${args.bead_id}:`, mailError);
35800
+ console.error(`[swarm_complete] Original error:`, error45);
35801
+ }
35802
+ throw error45;
35803
+ }
35704
35804
  }
35705
35805
  });
35706
35806
  var swarm_record_outcome = tool({
@@ -37603,20 +37703,47 @@ async function execSemanticMemory2(args) {
37603
37703
  };
37604
37704
  }
37605
37705
  }
37606
- var DEFAULT_STORAGE_CONFIG = {
37607
- backend: "semantic-memory",
37608
- collections: {
37706
+ function getCollectionNames() {
37707
+ const base = {
37609
37708
  feedback: "swarm-feedback",
37610
37709
  patterns: "swarm-patterns",
37611
37710
  maturity: "swarm-maturity"
37612
- },
37711
+ };
37712
+ if (process.env.TEST_MEMORY_COLLECTIONS === "true") {
37713
+ return {
37714
+ feedback: `${base.feedback}-test`,
37715
+ patterns: `${base.patterns}-test`,
37716
+ maturity: `${base.maturity}-test`
37717
+ };
37718
+ }
37719
+ return base;
37720
+ }
37721
+ var DEFAULT_STORAGE_CONFIG = {
37722
+ backend: "semantic-memory",
37723
+ collections: getCollectionNames(),
37613
37724
  useSemanticSearch: true
37614
37725
  };
37615
-
37726
+ var sessionStats = {
37727
+ storesCount: 0,
37728
+ queriesCount: 0,
37729
+ sessionStart: Date.now(),
37730
+ lastAlertCheck: Date.now()
37731
+ };
37616
37732
  class SemanticMemoryStorage {
37617
37733
  config;
37618
37734
  constructor(config2 = {}) {
37619
37735
  this.config = { ...DEFAULT_STORAGE_CONFIG, ...config2 };
37736
+ console.log(`[storage] SemanticMemoryStorage initialized with collections:`, this.config.collections);
37737
+ }
37738
+ async checkLowUsageAlert() {
37739
+ const TEN_MINUTES = 10 * 60 * 1000;
37740
+ const now = Date.now();
37741
+ const sessionDuration = now - sessionStats.sessionStart;
37742
+ const timeSinceLastAlert = now - sessionStats.lastAlertCheck;
37743
+ if (sessionDuration >= TEN_MINUTES && sessionStats.storesCount < 1 && timeSinceLastAlert >= TEN_MINUTES) {
37744
+ console.warn(`[storage] LOW USAGE ALERT: ${sessionStats.storesCount} stores after ${Math.floor(sessionDuration / 60000)} minutes`);
37745
+ sessionStats.lastAlertCheck = now;
37746
+ }
37620
37747
  }
37621
37748
  async store(collection, data, metadata) {
37622
37749
  const content = typeof data === "string" ? data : JSON.stringify(data);
@@ -37624,7 +37751,13 @@ class SemanticMemoryStorage {
37624
37751
  if (metadata) {
37625
37752
  args.push("--metadata", JSON.stringify(metadata));
37626
37753
  }
37627
- await execSemanticMemory2(args);
37754
+ console.log(`[storage] store() -> collection="${collection}"`);
37755
+ sessionStats.storesCount++;
37756
+ const result = await execSemanticMemory2(args);
37757
+ if (result.exitCode !== 0) {
37758
+ console.warn(`[storage] semantic-memory store() failed with exit code ${result.exitCode}: ${result.stderr.toString().trim()}`);
37759
+ }
37760
+ await this.checkLowUsageAlert();
37628
37761
  }
37629
37762
  async find(collection, query, limit = 10, useFts = false) {
37630
37763
  const args = [
@@ -37639,6 +37772,8 @@ class SemanticMemoryStorage {
37639
37772
  if (useFts) {
37640
37773
  args.push("--fts");
37641
37774
  }
37775
+ console.log(`[storage] find() -> collection="${collection}", query="${query.slice(0, 50)}${query.length > 50 ? "..." : ""}", limit=${limit}, fts=${useFts}`);
37776
+ sessionStats.queriesCount++;
37642
37777
  const result = await execSemanticMemory2(args);
37643
37778
  if (result.exitCode !== 0) {
37644
37779
  console.warn(`[storage] semantic-memory find() failed with exit code ${result.exitCode}: ${result.stderr.toString().trim()}`);
@@ -37664,6 +37799,8 @@ class SemanticMemoryStorage {
37664
37799
  }
37665
37800
  }
37666
37801
  async list(collection) {
37802
+ console.log(`[storage] list() -> collection="${collection}"`);
37803
+ sessionStats.queriesCount++;
37667
37804
  const result = await execSemanticMemory2([
37668
37805
  "list",
37669
37806
  "--collection",