opencode-swarm-plugin 0.45.1 → 0.45.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/index.js CHANGED
@@ -26904,6 +26904,34 @@ import {
26904
26904
  sep
26905
26905
  } from "path";
26906
26906
  import { fileURLToPath } from "url";
26907
+ import { getSwarmMailLibSQL as getSwarmMailLibSQL2, createEvent as createEvent2 } from "swarm-mail";
26908
+ async function emitSkillLoadedEvent(data) {
26909
+ try {
26910
+ const projectPath = skillsProjectDirectory;
26911
+ const swarmMail = await getSwarmMailLibSQL2(projectPath);
26912
+ const event = createEvent2("skill_loaded", {
26913
+ project_key: projectPath,
26914
+ skill_name: data.skill_name,
26915
+ skill_source: data.skill_source,
26916
+ context_provided: data.context_provided,
26917
+ content_length: data.content_length
26918
+ });
26919
+ await swarmMail.appendEvent(event);
26920
+ } catch {}
26921
+ }
26922
+ async function emitSkillCreatedEvent(data) {
26923
+ try {
26924
+ const projectPath = skillsProjectDirectory;
26925
+ const swarmMail = await getSwarmMailLibSQL2(projectPath);
26926
+ const event = createEvent2("skill_created", {
26927
+ project_key: projectPath,
26928
+ skill_name: data.skill_name,
26929
+ skill_scope: data.skill_scope,
26930
+ description: data.description
26931
+ });
26932
+ await swarmMail.appendEvent(event);
26933
+ } catch {}
26934
+ }
26907
26935
  function setSkillsProjectDirectory(dir) {
26908
26936
  skillsProjectDirectory = dir;
26909
26937
  skillsCache = null;
@@ -27339,6 +27367,18 @@ If the skill has scripts, you can run them with skills_execute.`,
27339
27367
  const names = available.map((s) => s.name).join(", ");
27340
27368
  return `Skill '${args.name}' not found. Available skills: ${names || "none"}`;
27341
27369
  }
27370
+ let skillSource = "project";
27371
+ if (skill.path.includes(".config/opencode/skills") || skill.path.includes(".claude/skills")) {
27372
+ skillSource = "global";
27373
+ } else if (skill.path.includes("global-skills")) {
27374
+ skillSource = "bundled";
27375
+ }
27376
+ await emitSkillLoadedEvent({
27377
+ skill_name: skill.metadata.name,
27378
+ skill_source: skillSource,
27379
+ context_provided: true,
27380
+ content_length: skill.body.length
27381
+ });
27342
27382
  const includeScripts = args.include_scripts !== false;
27343
27383
  let output = `# Skill: ${skill.metadata.name}
27344
27384
 
@@ -27507,6 +27547,12 @@ Good skills have:
27507
27547
  const content = generateSkillContent(args.name, args.description, args.body, { tags: args.tags, tools: args.tools });
27508
27548
  await writeFile(skillPath, content, "utf-8");
27509
27549
  invalidateSkillsCache();
27550
+ const skillScope = args.directory === "global" || args.directory === "global-claude" ? "global" : "project";
27551
+ await emitSkillCreatedEvent({
27552
+ skill_name: args.name,
27553
+ skill_scope: skillScope,
27554
+ description: args.description
27555
+ });
27510
27556
  const response = {
27511
27557
  success: true,
27512
27558
  skill: args.name,
@@ -27742,6 +27788,12 @@ echo "Project directory: $1"
27742
27788
  createdFiles.push("references/guide.md");
27743
27789
  }
27744
27790
  invalidateSkillsCache();
27791
+ const skillScope = args.directory === "global" ? "global" : "project";
27792
+ await emitSkillCreatedEvent({
27793
+ skill_name: args.name,
27794
+ skill_scope: skillScope,
27795
+ description: args.description || "[TODO: Complete description]"
27796
+ });
27745
27797
  return JSON.stringify({
27746
27798
  success: true,
27747
27799
  skill: args.name,
@@ -40045,6 +40097,20 @@ var hive_create = tool({
40045
40097
  parent_id: validated.parent_id
40046
40098
  });
40047
40099
  await adapter.markDirty(projectKey, cell.id);
40100
+ try {
40101
+ const event = createEvent("cell_created", {
40102
+ project_key: projectKey,
40103
+ cell_id: cell.id,
40104
+ title: validated.title,
40105
+ description: validated.description,
40106
+ issue_type: validated.type || "task",
40107
+ priority: validated.priority ?? 2,
40108
+ parent_id: validated.parent_id
40109
+ });
40110
+ await appendEvent(event, projectKey);
40111
+ } catch (error45) {
40112
+ console.warn("[hive_create] Failed to emit cell_created event:", error45);
40113
+ }
40048
40114
  const formatted = formatCellForOutput(cell);
40049
40115
  return JSON.stringify(formatted, null, 2);
40050
40116
  } catch (error45) {
@@ -40104,6 +40170,19 @@ var hive_create_epic = tool({
40104
40170
  subtasks: created.slice(1).map((c) => formatCellForOutput(c))
40105
40171
  };
40106
40172
  const effectiveProjectKey = args.project_key || projectKey;
40173
+ try {
40174
+ const epicCreatedEvent = createEvent("epic_created", {
40175
+ project_key: effectiveProjectKey,
40176
+ epic_id: epic.id,
40177
+ title: validated.epic_title,
40178
+ description: validated.epic_description,
40179
+ subtask_count: validated.subtasks.length,
40180
+ subtask_ids: created.slice(1).map((c) => c.id)
40181
+ });
40182
+ await appendEvent(epicCreatedEvent, effectiveProjectKey);
40183
+ } catch (error45) {
40184
+ console.warn("[hive_create_epic] Failed to emit epic_created event:", error45);
40185
+ }
40107
40186
  try {
40108
40187
  const event = createEvent("decomposition_generated", {
40109
40188
  project_key: effectiveProjectKey,
@@ -40268,6 +40347,23 @@ var hive_update = tool({
40268
40347
  cell = existingCell;
40269
40348
  }
40270
40349
  await adapter.markDirty(projectKey, cellId);
40350
+ try {
40351
+ const fieldsChanged = [];
40352
+ if (validated.status)
40353
+ fieldsChanged.push("status");
40354
+ if (validated.description !== undefined)
40355
+ fieldsChanged.push("description");
40356
+ if (validated.priority !== undefined)
40357
+ fieldsChanged.push("priority");
40358
+ const event = createEvent("cell_updated", {
40359
+ project_key: projectKey,
40360
+ cell_id: cellId,
40361
+ fields_changed: fieldsChanged
40362
+ });
40363
+ await appendEvent(event, projectKey);
40364
+ } catch (error45) {
40365
+ console.warn("[hive_update] Failed to emit cell_updated event:", error45);
40366
+ }
40271
40367
  const formatted = formatCellForOutput(cell);
40272
40368
  return JSON.stringify(formatted, null, 2);
40273
40369
  } catch (error45) {
@@ -40384,6 +40480,16 @@ var hive_close = tool({
40384
40480
  console.warn("[hive_close] Failed to emit SwarmCompletedEvent:", error45);
40385
40481
  }
40386
40482
  }
40483
+ try {
40484
+ const event = createEvent("cell_closed", {
40485
+ project_key: projectKey,
40486
+ cell_id: cellId,
40487
+ reason: validated.reason
40488
+ });
40489
+ await appendEvent(event, projectKey);
40490
+ } catch (error45) {
40491
+ console.warn("[hive_close] Failed to emit cell_closed event:", error45);
40492
+ }
40387
40493
  return `Closed ${cell.id}: ${validated.reason}`;
40388
40494
  } catch (error45) {
40389
40495
  const message = error45 instanceof Error ? error45.message : String(error45);
@@ -40409,6 +40515,17 @@ var hive_start = tool({
40409
40515
  const cellId = await resolvePartialId(adapter, projectKey, args.id) || args.id;
40410
40516
  const cell = await adapter.changeCellStatus(projectKey, cellId, "in_progress");
40411
40517
  await adapter.markDirty(projectKey, cellId);
40518
+ try {
40519
+ const event = createEvent("cell_status_changed", {
40520
+ project_key: projectKey,
40521
+ cell_id: cellId,
40522
+ old_status: "open",
40523
+ new_status: "in_progress"
40524
+ });
40525
+ await appendEvent(event, projectKey);
40526
+ } catch (error45) {
40527
+ console.warn("[hive_start] Failed to emit cell_status_changed event:", error45);
40528
+ }
40412
40529
  return `Started: ${cell.id}`;
40413
40530
  } catch (error45) {
40414
40531
  const message = error45 instanceof Error ? error45.message : String(error45);
@@ -40597,11 +40714,25 @@ var hive_sync = tool({
40597
40714
  }
40598
40715
  const remoteCheckResult = await runGitCommand(["remote"]);
40599
40716
  const hasRemote = remoteCheckResult.stdout.trim() !== "";
40717
+ let pushSuccess = false;
40600
40718
  if (hasRemote) {
40601
40719
  const pushResult = await withTimeout(runGitCommand(["push"]), TIMEOUT_MS, "git push");
40602
40720
  if (pushResult.exitCode !== 0) {
40603
40721
  throw new HiveError(`Failed to push: ${pushResult.stderr}`, "git push", pushResult.exitCode);
40604
40722
  }
40723
+ pushSuccess = true;
40724
+ }
40725
+ try {
40726
+ const event = createEvent("hive_synced", {
40727
+ project_key: projectKey,
40728
+ cells_synced: flushResult.cellsExported,
40729
+ push_success: pushSuccess
40730
+ });
40731
+ await appendEvent(event, projectKey);
40732
+ } catch (error45) {
40733
+ console.warn("[hive_sync] Failed to emit hive_synced event:", error45);
40734
+ }
40735
+ if (hasRemote) {
40605
40736
  return "Hive synced and pushed successfully";
40606
40737
  } else {
40607
40738
  return "Hive synced successfully (no remote configured)";
@@ -45344,9 +45475,9 @@ import {
45344
45475
  releaseSwarmFiles as releaseSwarmFiles2,
45345
45476
  sendSwarmMessage as sendSwarmMessage3,
45346
45477
  getAgent,
45347
- createEvent as createEvent2,
45478
+ createEvent as createEvent3,
45348
45479
  appendEvent as appendEvent2,
45349
- getSwarmMailLibSQL as getSwarmMailLibSQL2
45480
+ getSwarmMailLibSQL as getSwarmMailLibSQL3
45350
45481
  } from "swarm-mail";
45351
45482
  init_skills();
45352
45483
 
@@ -45849,9 +45980,9 @@ var swarm_review = tool({
45849
45980
  downstream_tasks: downstreamTasks.length > 0 ? downstreamTasks : undefined
45850
45981
  });
45851
45982
  try {
45852
- const { createEvent: createEvent2, appendEvent: appendEvent2 } = await import("swarm-mail");
45983
+ const { createEvent: createEvent3, appendEvent: appendEvent2 } = await import("swarm-mail");
45853
45984
  const attempt = getReviewStatus(args.task_id).attempt_count || 1;
45854
- const reviewStartedEvent = createEvent2("review_started", {
45985
+ const reviewStartedEvent = createEvent3("review_started", {
45855
45986
  project_key: args.project_key,
45856
45987
  epic_id: args.epic_id,
45857
45988
  bead_id: args.task_id,
@@ -45940,9 +46071,9 @@ var swarm_review_feedback = tool({
45940
46071
  console.warn("[swarm_review_feedback] Failed to trace review_decision:", error45);
45941
46072
  }
45942
46073
  try {
45943
- const { createEvent: createEvent2, appendEvent: appendEvent2 } = await import("swarm-mail");
46074
+ const { createEvent: createEvent3, appendEvent: appendEvent2 } = await import("swarm-mail");
45944
46075
  const attempt = getReviewStatus(args.task_id).attempt_count || 1;
45945
- const reviewCompletedEvent = createEvent2("review_completed", {
46076
+ const reviewCompletedEvent = createEvent3("review_completed", {
45946
46077
  project_key: args.project_key,
45947
46078
  epic_id: epicId,
45948
46079
  bead_id: args.task_id,
@@ -46011,9 +46142,9 @@ You may now complete the task with \`swarm_complete\`.`,
46011
46142
  console.warn("[swarm_review_feedback] Failed to trace review_decision:", error45);
46012
46143
  }
46013
46144
  try {
46014
- const { createEvent: createEvent2, appendEvent: appendEvent2 } = await import("swarm-mail");
46145
+ const { createEvent: createEvent3, appendEvent: appendEvent2 } = await import("swarm-mail");
46015
46146
  const status = remaining <= 0 ? "blocked" : "needs_changes";
46016
- const reviewCompletedEvent = createEvent2("review_completed", {
46147
+ const reviewCompletedEvent = createEvent3("review_completed", {
46017
46148
  project_key: args.project_key,
46018
46149
  epic_id: epicId,
46019
46150
  bead_id: args.task_id,
@@ -46569,7 +46700,7 @@ var swarm_progress = tool({
46569
46700
  }
46570
46701
  };
46571
46702
  const checkpointData = JSON.stringify(checkpoint);
46572
- const checkpointEvent = createEvent2("swarm_checkpointed", {
46703
+ const checkpointEvent = createEvent3("swarm_checkpointed", {
46573
46704
  project_key: args.project_key,
46574
46705
  ...checkpoint,
46575
46706
  checkpoint_size_bytes: Buffer.byteLength(checkpointData, "utf8"),
@@ -46577,7 +46708,7 @@ var swarm_progress = tool({
46577
46708
  });
46578
46709
  await appendEvent2(checkpointEvent, args.project_key);
46579
46710
  const checkpointId = `ckpt-${Date.now()}-${args.bead_id}`;
46580
- const createdEvent = createEvent2("checkpoint_created", {
46711
+ const createdEvent = createEvent3("checkpoint_created", {
46581
46712
  project_key: args.project_key,
46582
46713
  epic_id: epicId,
46583
46714
  bead_id: args.bead_id,
@@ -46830,7 +46961,7 @@ This will be recorded as a negative learning signal.`;
46830
46961
  let deferredResolved = false;
46831
46962
  let deferredError;
46832
46963
  try {
46833
- const swarmMail = await getSwarmMailLibSQL2(args.project_key);
46964
+ const swarmMail = await getSwarmMailLibSQL3(args.project_key);
46834
46965
  const db = await swarmMail.getDatabase();
46835
46966
  const deferredUrl = `deferred:${args.bead_id}`;
46836
46967
  const checkResult = await db.query(`SELECT url, resolved FROM deferred WHERE url = ? AND resolved = 0`, [deferredUrl]);
@@ -46859,16 +46990,16 @@ This will be recorded as a negative learning signal.`;
46859
46990
  syncError = error45 instanceof Error ? error45.message : String(error45);
46860
46991
  console.warn(`[swarm_complete] Auto-sync failed (non-fatal): ${syncError}`);
46861
46992
  }
46993
+ const completionDurationMs = args.start_time ? Date.now() - args.start_time : 0;
46994
+ const eventEpicId = cell.parent_id || (args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id);
46862
46995
  try {
46863
- const durationMs2 = args.start_time ? Date.now() - args.start_time : 0;
46864
- const eventEpicId = cell.parent_id || (args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id);
46865
- const event = createEvent2("subtask_outcome", {
46996
+ const event = createEvent3("subtask_outcome", {
46866
46997
  project_key: args.project_key,
46867
46998
  epic_id: eventEpicId,
46868
46999
  bead_id: args.bead_id,
46869
47000
  planned_files: args.planned_files || [],
46870
47001
  actual_files: args.files_touched || [],
46871
- duration_ms: durationMs2,
47002
+ duration_ms: completionDurationMs,
46872
47003
  error_count: args.error_count || 0,
46873
47004
  retry_count: args.retry_count || 0,
46874
47005
  success: true,
@@ -46879,8 +47010,21 @@ This will be recorded as a negative learning signal.`;
46879
47010
  } catch (error45) {
46880
47011
  console.warn("[swarm_complete] Failed to emit SubtaskOutcomeEvent:", error45);
46881
47012
  }
47013
+ try {
47014
+ const workerCompletedEvent = createEvent3("worker_completed", {
47015
+ project_key: args.project_key,
47016
+ epic_id: eventEpicId,
47017
+ bead_id: args.bead_id,
47018
+ worker_agent: args.agent_name,
47019
+ success: true,
47020
+ duration_ms: completionDurationMs,
47021
+ files_touched: args.files_touched || []
47022
+ });
47023
+ await appendEvent2(workerCompletedEvent, args.project_key);
47024
+ } catch (error45) {
47025
+ console.warn("[swarm_complete] Failed to emit worker_completed event:", error45);
47026
+ }
46882
47027
  let capturedStrategy;
46883
- const durationMs = args.start_time ? Date.now() - args.start_time : 0;
46884
47028
  const memoryInfo = formatMemoryStoreOnSuccess(args.bead_id, args.summary, args.files_touched || [], capturedStrategy);
46885
47029
  let memoryStored = false;
46886
47030
  let memoryError;
@@ -46997,7 +47141,7 @@ Files touched: ${args.files_touched?.join(", ") || "none recorded"}`,
46997
47141
  };
46998
47142
  try {
46999
47143
  const { captureSubtaskOutcome: captureSubtaskOutcome2 } = await Promise.resolve().then(() => (init_eval_capture(), exports_eval_capture));
47000
- const durationMs2 = args.start_time ? Date.now() - args.start_time : 0;
47144
+ const durationMs = args.start_time ? Date.now() - args.start_time : 0;
47001
47145
  const evalEpicId = cell.parent_id || epicId2;
47002
47146
  captureSubtaskOutcome2({
47003
47147
  epicId: evalEpicId,
@@ -47006,7 +47150,7 @@ Files touched: ${args.files_touched?.join(", ") || "none recorded"}`,
47006
47150
  title: cell.title,
47007
47151
  plannedFiles: args.planned_files || [],
47008
47152
  actualFiles: args.files_touched || [],
47009
- durationMs: durationMs2,
47153
+ durationMs,
47010
47154
  errorCount: args.error_count || 0,
47011
47155
  retryCount: args.retry_count || 0,
47012
47156
  success: true
@@ -47015,7 +47159,7 @@ Files touched: ${args.files_touched?.join(", ") || "none recorded"}`,
47015
47159
  console.warn("[swarm_complete] Failed to capture subtask outcome:", error45);
47016
47160
  }
47017
47161
  try {
47018
- const durationMs2 = args.start_time ? Date.now() - args.start_time : 0;
47162
+ const durationMs = args.start_time ? Date.now() - args.start_time : 0;
47019
47163
  captureCoordinatorEvent({
47020
47164
  session_id: _ctx.sessionID || "unknown",
47021
47165
  epic_id: epicId2,
@@ -47024,7 +47168,7 @@ Files touched: ${args.files_touched?.join(", ") || "none recorded"}`,
47024
47168
  outcome_type: "subtask_success",
47025
47169
  payload: {
47026
47170
  bead_id: args.bead_id,
47027
- duration_ms: durationMs2,
47171
+ duration_ms: durationMs,
47028
47172
  files_touched: args.files_touched || [],
47029
47173
  verification_passed: verificationResult?.passed ?? false,
47030
47174
  verification_skipped: args.skip_verification ?? false
@@ -47498,7 +47642,7 @@ var swarm_checkpoint = tool({
47498
47642
  }
47499
47643
  };
47500
47644
  const checkpointData = JSON.stringify(checkpoint);
47501
- const event = createEvent2("swarm_checkpointed", {
47645
+ const event = createEvent3("swarm_checkpointed", {
47502
47646
  project_key: args.project_key,
47503
47647
  epic_id: args.epic_id,
47504
47648
  bead_id: args.bead_id,
@@ -47540,8 +47684,8 @@ var swarm_recover = tool({
47540
47684
  },
47541
47685
  async execute(args) {
47542
47686
  try {
47543
- const { getSwarmMailLibSQL: getSwarmMailLibSQL3 } = await import("swarm-mail");
47544
- const swarmMail = await getSwarmMailLibSQL3(args.project_key);
47687
+ const { getSwarmMailLibSQL: getSwarmMailLibSQL4 } = await import("swarm-mail");
47688
+ const swarmMail = await getSwarmMailLibSQL4(args.project_key);
47545
47689
  const db = await swarmMail.getDatabase();
47546
47690
  const result = await db.query(`SELECT * FROM swarm_contexts
47547
47691
  WHERE epic_id = $1
@@ -47568,7 +47712,7 @@ var swarm_recover = tool({
47568
47712
  created_at: row.created_at,
47569
47713
  updated_at: row.updated_at
47570
47714
  };
47571
- const event = createEvent2("swarm_recovered", {
47715
+ const event = createEvent3("swarm_recovered", {
47572
47716
  project_key: args.project_key,
47573
47717
  epic_id: args.epic_id,
47574
47718
  bead_id: context.bead_id,
@@ -47743,7 +47887,7 @@ init_eval_capture();
47743
47887
 
47744
47888
  // src/memory-tools.ts
47745
47889
  init_dist();
47746
- import { getSwarmMailLibSQL as getSwarmMailLibSQL3 } from "swarm-mail";
47890
+ import { getSwarmMailLibSQL as getSwarmMailLibSQL4, createEvent as createEvent4, appendEvent as appendEvent3 } from "swarm-mail";
47747
47891
 
47748
47892
  // ../../node_modules/.bun/effect@3.19.12/node_modules/effect/dist/esm/Function.js
47749
47893
  var isFunction = (input) => typeof input === "function";
@@ -61360,7 +61504,7 @@ async function getMemoryAdapter(projectPath) {
61360
61504
  if (cachedAdapter && cachedProjectPath === path3) {
61361
61505
  return cachedAdapter;
61362
61506
  }
61363
- const swarmMail = await getSwarmMailLibSQL3(path3);
61507
+ const swarmMail = await getSwarmMailLibSQL4(path3);
61364
61508
  const dbAdapter = await swarmMail.getDatabase();
61365
61509
  cachedAdapter = await createMemoryAdapter(dbAdapter);
61366
61510
  cachedProjectPath = path3;
@@ -61385,6 +61529,21 @@ var semantic_memory_store = tool({
61385
61529
  async execute(args2, ctx) {
61386
61530
  const adapter = await getMemoryAdapter();
61387
61531
  const result = await adapter.store(args2);
61532
+ try {
61533
+ const projectKey = cachedProjectPath || process.cwd();
61534
+ const tags = args2.tags ? args2.tags.split(",").map((t) => t.trim()) : [];
61535
+ const event = createEvent4("memory_stored", {
61536
+ project_key: projectKey,
61537
+ memory_id: result.id,
61538
+ content_preview: args2.information.slice(0, 100),
61539
+ tags,
61540
+ auto_tagged: args2.autoTag,
61541
+ collection: args2.collection
61542
+ });
61543
+ await appendEvent3(event, projectKey);
61544
+ } catch (error45) {
61545
+ console.warn("[semantic_memory_store] Failed to emit memory_stored event:", error45);
61546
+ }
61388
61547
  return JSON.stringify(result, null, 2);
61389
61548
  }
61390
61549
  });
@@ -61398,8 +61557,25 @@ var semantic_memory_find = tool({
61398
61557
  fts: tool.schema.boolean().optional().describe("Use full-text search instead of vector search (default: false)")
61399
61558
  },
61400
61559
  async execute(args2, ctx) {
61560
+ const startTime = Date.now();
61401
61561
  const adapter = await getMemoryAdapter();
61402
61562
  const result = await adapter.find(args2);
61563
+ const duration3 = Date.now() - startTime;
61564
+ try {
61565
+ const projectKey = cachedProjectPath || process.cwd();
61566
+ const topScore = result.results.length > 0 ? result.results[0].score : undefined;
61567
+ const event = createEvent4("memory_found", {
61568
+ project_key: projectKey,
61569
+ query: args2.query,
61570
+ result_count: result.results.length,
61571
+ top_score: topScore,
61572
+ search_duration_ms: duration3,
61573
+ used_fts: args2.fts
61574
+ });
61575
+ await appendEvent3(event, projectKey);
61576
+ } catch (error45) {
61577
+ console.warn("[semantic_memory_find] Failed to emit memory_found event:", error45);
61578
+ }
61403
61579
  return JSON.stringify(result, null, 2);
61404
61580
  }
61405
61581
  });
@@ -61422,6 +61598,18 @@ var semantic_memory_remove = tool({
61422
61598
  async execute(args2, ctx) {
61423
61599
  const adapter = await getMemoryAdapter();
61424
61600
  const result = await adapter.remove(args2);
61601
+ if (result.success) {
61602
+ try {
61603
+ const projectKey = cachedProjectPath || process.cwd();
61604
+ const event = createEvent4("memory_deleted", {
61605
+ project_key: projectKey,
61606
+ memory_id: args2.id
61607
+ });
61608
+ await appendEvent3(event, projectKey);
61609
+ } catch (error45) {
61610
+ console.warn("[semantic_memory_remove] Failed to emit memory_deleted event:", error45);
61611
+ }
61612
+ }
61425
61613
  return JSON.stringify(result, null, 2);
61426
61614
  }
61427
61615
  });
@@ -61433,6 +61621,19 @@ var semantic_memory_validate = tool({
61433
61621
  async execute(args2, ctx) {
61434
61622
  const adapter = await getMemoryAdapter();
61435
61623
  const result = await adapter.validate(args2);
61624
+ if (result.success) {
61625
+ try {
61626
+ const projectKey = cachedProjectPath || process.cwd();
61627
+ const event = createEvent4("memory_validated", {
61628
+ project_key: projectKey,
61629
+ memory_id: args2.id,
61630
+ decay_reset: true
61631
+ });
61632
+ await appendEvent3(event, projectKey);
61633
+ } catch (error45) {
61634
+ console.warn("[semantic_memory_validate] Failed to emit memory_validated event:", error45);
61635
+ }
61636
+ }
61436
61637
  return JSON.stringify(result, null, 2);
61437
61638
  }
61438
61639
  });
@@ -61480,6 +61681,18 @@ var semantic_memory_upsert = tool({
61480
61681
  async execute(args2, ctx) {
61481
61682
  const adapter = await getMemoryAdapter();
61482
61683
  const result = await adapter.upsert(args2);
61684
+ try {
61685
+ const projectKey = cachedProjectPath || process.cwd();
61686
+ const event = createEvent4("memory_updated", {
61687
+ project_key: projectKey,
61688
+ memory_id: result.memoryId || "unknown",
61689
+ operation: result.operation,
61690
+ reason: result.reason
61691
+ });
61692
+ await appendEvent3(event, projectKey);
61693
+ } catch (error45) {
61694
+ console.warn("[semantic_memory_upsert] Failed to emit memory_updated event:", error45);
61695
+ }
61483
61696
  return JSON.stringify(result, null, 2);
61484
61697
  }
61485
61698
  });
@@ -62465,9 +62678,9 @@ var swarm_spawn_subtask = tool({
62465
62678
  }
62466
62679
  if (args2.project_path) {
62467
62680
  try {
62468
- const { createEvent: createEvent3, appendEvent: appendEvent3 } = await import("swarm-mail");
62681
+ const { createEvent: createEvent5, appendEvent: appendEvent4 } = await import("swarm-mail");
62469
62682
  const spawnOrder = 0;
62470
- const workerSpawnedEvent = createEvent3("worker_spawned", {
62683
+ const workerSpawnedEvent = createEvent5("worker_spawned", {
62471
62684
  project_key: args2.project_path,
62472
62685
  epic_id: args2.epic_id,
62473
62686
  bead_id: args2.bead_id,
@@ -62477,7 +62690,7 @@ var swarm_spawn_subtask = tool({
62477
62690
  spawn_order: spawnOrder,
62478
62691
  is_parallel: false
62479
62692
  });
62480
- await appendEvent3(workerSpawnedEvent, args2.project_path);
62693
+ await appendEvent4(workerSpawnedEvent, args2.project_path);
62481
62694
  } catch (error45) {
62482
62695
  console.warn("[swarm_spawn_subtask] Failed to emit WorkerSpawnedEvent:", error45);
62483
62696
  }
@@ -64155,7 +64368,7 @@ import {
64155
64368
  agentActivity,
64156
64369
  checkpointFrequency,
64157
64370
  failedDecompositions,
64158
- getSwarmMailLibSQL as getSwarmMailLibSQL4,
64371
+ getSwarmMailLibSQL as getSwarmMailLibSQL5,
64159
64372
  humanFeedback,
64160
64373
  lockContention,
64161
64374
  messageLatency,
@@ -64220,7 +64433,7 @@ var swarm_analytics = tool({
64220
64433
  async execute(args2) {
64221
64434
  try {
64222
64435
  const projectPath = process.cwd();
64223
- const db = await getSwarmMailLibSQL4(projectPath);
64436
+ const db = await getSwarmMailLibSQL5(projectPath);
64224
64437
  const filters = {
64225
64438
  project_key: projectPath
64226
64439
  };
@@ -64290,7 +64503,7 @@ var swarm_query = tool({
64290
64503
  async execute(args2) {
64291
64504
  try {
64292
64505
  const projectPath = process.cwd();
64293
- const swarmMail = await getSwarmMailLibSQL4(projectPath);
64506
+ const swarmMail = await getSwarmMailLibSQL5(projectPath);
64294
64507
  const db = await swarmMail.getDatabase();
64295
64508
  if (!args2.sql.trim().toLowerCase().startsWith("select")) {
64296
64509
  return JSON.stringify({
@@ -64340,7 +64553,7 @@ var swarm_diagnose = tool({
64340
64553
  async execute(args2) {
64341
64554
  try {
64342
64555
  const projectPath = process.cwd();
64343
- const swarmMail = await getSwarmMailLibSQL4(projectPath);
64556
+ const swarmMail = await getSwarmMailLibSQL5(projectPath);
64344
64557
  const db = await swarmMail.getDatabase();
64345
64558
  const diagnosis = [];
64346
64559
  const include = args2.include || [
@@ -64451,7 +64664,7 @@ var swarm_insights = tool({
64451
64664
  });
64452
64665
  }
64453
64666
  const projectPath = process.cwd();
64454
- const swarmMail = await getSwarmMailLibSQL4(projectPath);
64667
+ const swarmMail = await getSwarmMailLibSQL5(projectPath);
64455
64668
  const db = await swarmMail.getDatabase();
64456
64669
  const insights = [];
64457
64670
  if (args2.metrics.includes("success_rate")) {
@@ -65007,6 +65220,268 @@ var contributorTools = {
65007
65220
  contributor_lookup
65008
65221
  };
65009
65222
 
65223
+ // src/cass-tools.ts
65224
+ init_dist();
65225
+ import { execSync, spawn } from "child_process";
65226
+ import { getSwarmMailLibSQL as getSwarmMailLibSQL6, createEvent as createEvent5 } from "swarm-mail";
65227
+ function isCassAvailable() {
65228
+ try {
65229
+ execSync("which cass", { stdio: "ignore" });
65230
+ return true;
65231
+ } catch {
65232
+ return false;
65233
+ }
65234
+ }
65235
+ async function execCass(args2) {
65236
+ return new Promise((resolve2, reject) => {
65237
+ const proc = spawn("cass", args2, {
65238
+ stdio: ["ignore", "pipe", "pipe"]
65239
+ });
65240
+ let stdout = "";
65241
+ let stderr = "";
65242
+ proc.stdout.on("data", (data) => {
65243
+ stdout += data;
65244
+ });
65245
+ proc.stderr.on("data", (data) => {
65246
+ stderr += data;
65247
+ });
65248
+ proc.on("close", (code) => {
65249
+ if (code === 0) {
65250
+ resolve2(stdout);
65251
+ } else {
65252
+ reject(new Error(stderr || `cass exited with code ${code}`));
65253
+ }
65254
+ });
65255
+ proc.on("error", (err) => {
65256
+ if (err.code === "ENOENT") {
65257
+ reject(new Error("cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"));
65258
+ } else {
65259
+ reject(err);
65260
+ }
65261
+ });
65262
+ });
65263
+ }
65264
+ async function emitEvent(eventType, data) {
65265
+ try {
65266
+ const projectPath = process.cwd();
65267
+ const swarmMail = await getSwarmMailLibSQL6(projectPath);
65268
+ const event = createEvent5(eventType, {
65269
+ project_key: projectPath,
65270
+ ...data
65271
+ });
65272
+ await swarmMail.appendEvent(event);
65273
+ } catch {}
65274
+ }
65275
+ var cass_search = tool({
65276
+ description: "Search across all AI coding agent histories (Claude, Codex, Cursor, Gemini, Aider, ChatGPT, Cline, OpenCode). Query BEFORE solving problems from scratch - another agent may have already solved it.",
65277
+ args: {
65278
+ query: tool.schema.string().describe("Search query (e.g., 'authentication error Next.js')"),
65279
+ agent: tool.schema.string().optional().describe("Filter by agent name (e.g., 'claude', 'cursor')"),
65280
+ days: tool.schema.number().optional().describe("Only search sessions from last N days"),
65281
+ limit: tool.schema.number().optional().describe("Max results to return (default: 5)"),
65282
+ fields: tool.schema.string().optional().describe("Field selection: 'minimal' for compact output (path, line, agent only)")
65283
+ },
65284
+ async execute(args2) {
65285
+ const startTime = Date.now();
65286
+ if (!isCassAvailable()) {
65287
+ return JSON.stringify({
65288
+ error: "cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"
65289
+ });
65290
+ }
65291
+ try {
65292
+ const cliArgs = ["search", args2.query];
65293
+ if (args2.agent) {
65294
+ cliArgs.push("--agent", args2.agent);
65295
+ }
65296
+ if (args2.days) {
65297
+ cliArgs.push("--days", String(args2.days));
65298
+ }
65299
+ if (args2.limit) {
65300
+ cliArgs.push("--limit", String(args2.limit));
65301
+ }
65302
+ if (args2.fields === "minimal") {
65303
+ cliArgs.push("--minimal");
65304
+ }
65305
+ const output = await execCass(cliArgs);
65306
+ const lines = output.trim().split(`
65307
+ `).filter((l) => l.trim());
65308
+ const resultCount = lines.length;
65309
+ await emitEvent("cass_searched", {
65310
+ query: args2.query,
65311
+ agent_filter: args2.agent,
65312
+ days_filter: args2.days,
65313
+ result_count: resultCount,
65314
+ search_duration_ms: Date.now() - startTime
65315
+ });
65316
+ return output;
65317
+ } catch (error45) {
65318
+ return JSON.stringify({
65319
+ error: error45 instanceof Error ? error45.message : String(error45)
65320
+ });
65321
+ }
65322
+ }
65323
+ });
65324
+ var cass_view = tool({
65325
+ description: "View a specific conversation/session from search results. Use source_path from cass_search output.",
65326
+ args: {
65327
+ path: tool.schema.string().describe("Path to session file (from cass_search results)"),
65328
+ line: tool.schema.number().optional().describe("Jump to specific line number")
65329
+ },
65330
+ async execute(args2) {
65331
+ if (!isCassAvailable()) {
65332
+ return JSON.stringify({
65333
+ error: "cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"
65334
+ });
65335
+ }
65336
+ try {
65337
+ const cliArgs = ["view", args2.path];
65338
+ if (args2.line) {
65339
+ cliArgs.push("--line", String(args2.line));
65340
+ }
65341
+ const output = await execCass(cliArgs);
65342
+ let agentType;
65343
+ if (args2.path.includes("claude"))
65344
+ agentType = "claude";
65345
+ else if (args2.path.includes("cursor"))
65346
+ agentType = "cursor";
65347
+ else if (args2.path.includes("opencode"))
65348
+ agentType = "opencode";
65349
+ else if (args2.path.includes("codex"))
65350
+ agentType = "codex";
65351
+ await emitEvent("cass_viewed", {
65352
+ session_path: args2.path,
65353
+ line_number: args2.line,
65354
+ agent_type: agentType
65355
+ });
65356
+ return output;
65357
+ } catch (error45) {
65358
+ return JSON.stringify({
65359
+ error: error45 instanceof Error ? error45.message : String(error45)
65360
+ });
65361
+ }
65362
+ }
65363
+ });
65364
+ var cass_expand = tool({
65365
+ description: "Expand context around a specific line in a session. Shows messages before/after.",
65366
+ args: {
65367
+ path: tool.schema.string().describe("Path to session file"),
65368
+ line: tool.schema.number().describe("Line number to expand around"),
65369
+ context: tool.schema.number().optional().describe("Number of lines before/after to show (default: 5)")
65370
+ },
65371
+ async execute(args2) {
65372
+ if (!isCassAvailable()) {
65373
+ return JSON.stringify({
65374
+ error: "cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"
65375
+ });
65376
+ }
65377
+ try {
65378
+ const cliArgs = ["expand", args2.path, "--line", String(args2.line)];
65379
+ if (args2.context) {
65380
+ cliArgs.push("--context", String(args2.context));
65381
+ }
65382
+ const output = await execCass(cliArgs);
65383
+ await emitEvent("cass_viewed", {
65384
+ session_path: args2.path,
65385
+ line_number: args2.line
65386
+ });
65387
+ return output;
65388
+ } catch (error45) {
65389
+ return JSON.stringify({
65390
+ error: error45 instanceof Error ? error45.message : String(error45)
65391
+ });
65392
+ }
65393
+ }
65394
+ });
65395
+ var cass_health = tool({
65396
+ description: "Check if cass index is healthy. Exit 0 = ready, Exit 1 = needs indexing. Run this before searching.",
65397
+ args: {},
65398
+ async execute() {
65399
+ if (!isCassAvailable()) {
65400
+ return JSON.stringify({
65401
+ healthy: false,
65402
+ error: "cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"
65403
+ });
65404
+ }
65405
+ try {
65406
+ await execCass(["health"]);
65407
+ return JSON.stringify({ healthy: true, message: "Index is ready" });
65408
+ } catch (error45) {
65409
+ return JSON.stringify({
65410
+ healthy: false,
65411
+ message: "Index needs rebuilding. Run cass_index()",
65412
+ error: error45 instanceof Error ? error45.message : String(error45)
65413
+ });
65414
+ }
65415
+ }
65416
+ });
65417
+ var cass_index = tool({
65418
+ description: "Build or rebuild the search index. Run this if health check fails or to pick up new sessions.",
65419
+ args: {
65420
+ full: tool.schema.boolean().optional().describe("Force full rebuild (default: incremental)")
65421
+ },
65422
+ async execute(args2) {
65423
+ const startTime = Date.now();
65424
+ if (!isCassAvailable()) {
65425
+ return JSON.stringify({
65426
+ error: "cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"
65427
+ });
65428
+ }
65429
+ try {
65430
+ const cliArgs = ["index"];
65431
+ if (args2.full) {
65432
+ cliArgs.push("--full");
65433
+ }
65434
+ const output = await execCass(cliArgs);
65435
+ let sessionsIndexed = 0;
65436
+ let messagesIndexed = 0;
65437
+ const sessionsMatch = output.match(/(\d+)\s*sessions?/i);
65438
+ const messagesMatch = output.match(/(\d+)\s*messages?/i);
65439
+ if (sessionsMatch)
65440
+ sessionsIndexed = parseInt(sessionsMatch[1], 10);
65441
+ if (messagesMatch)
65442
+ messagesIndexed = parseInt(messagesMatch[1], 10);
65443
+ await emitEvent("cass_indexed", {
65444
+ sessions_indexed: sessionsIndexed,
65445
+ messages_indexed: messagesIndexed,
65446
+ duration_ms: Date.now() - startTime,
65447
+ full_rebuild: args2.full ?? false
65448
+ });
65449
+ return output;
65450
+ } catch (error45) {
65451
+ return JSON.stringify({
65452
+ error: error45 instanceof Error ? error45.message : String(error45)
65453
+ });
65454
+ }
65455
+ }
65456
+ });
65457
+ var cass_stats = tool({
65458
+ description: "Show index statistics - how many sessions, messages, agents indexed.",
65459
+ args: {},
65460
+ async execute() {
65461
+ if (!isCassAvailable()) {
65462
+ return JSON.stringify({
65463
+ error: "cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"
65464
+ });
65465
+ }
65466
+ try {
65467
+ const output = await execCass(["stats"]);
65468
+ return output;
65469
+ } catch (error45) {
65470
+ return JSON.stringify({
65471
+ error: error45 instanceof Error ? error45.message : String(error45)
65472
+ });
65473
+ }
65474
+ }
65475
+ });
65476
+ var cassTools = {
65477
+ cass_search,
65478
+ cass_view,
65479
+ cass_expand,
65480
+ cass_health,
65481
+ cass_index,
65482
+ cass_stats
65483
+ };
65484
+
65010
65485
  // src/output-guardrails.ts
65011
65486
  var DEFAULT_GUARDRAIL_CONFIG = {
65012
65487
  defaultMaxChars: 32000,
@@ -67190,7 +67665,8 @@ var allTools = {
67190
67665
  ...mandateTools,
67191
67666
  ...memoryTools,
67192
67667
  ...observabilityTools,
67193
- ...contributorTools
67668
+ ...contributorTools,
67669
+ ...cassTools
67194
67670
  };
67195
67671
  export {
67196
67672
  withToolFallback,
@@ -67317,6 +67793,7 @@ export {
67317
67793
  checkGate,
67318
67794
  checkBeadsMigrationNeeded,
67319
67795
  checkAllTools,
67796
+ cassTools,
67320
67797
  calculateVariance,
67321
67798
  beads_update,
67322
67799
  beads_sync,