opencode-swarm-plugin 0.45.0 → 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/plugin.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,
@@ -39801,6 +39853,20 @@ var hive_create = tool({
39801
39853
  parent_id: validated.parent_id
39802
39854
  });
39803
39855
  await adapter.markDirty(projectKey, cell.id);
39856
+ try {
39857
+ const event = createEvent("cell_created", {
39858
+ project_key: projectKey,
39859
+ cell_id: cell.id,
39860
+ title: validated.title,
39861
+ description: validated.description,
39862
+ issue_type: validated.type || "task",
39863
+ priority: validated.priority ?? 2,
39864
+ parent_id: validated.parent_id
39865
+ });
39866
+ await appendEvent(event, projectKey);
39867
+ } catch (error45) {
39868
+ console.warn("[hive_create] Failed to emit cell_created event:", error45);
39869
+ }
39804
39870
  const formatted = formatCellForOutput(cell);
39805
39871
  return JSON.stringify(formatted, null, 2);
39806
39872
  } catch (error45) {
@@ -39860,6 +39926,19 @@ var hive_create_epic = tool({
39860
39926
  subtasks: created.slice(1).map((c) => formatCellForOutput(c))
39861
39927
  };
39862
39928
  const effectiveProjectKey = args.project_key || projectKey;
39929
+ try {
39930
+ const epicCreatedEvent = createEvent("epic_created", {
39931
+ project_key: effectiveProjectKey,
39932
+ epic_id: epic.id,
39933
+ title: validated.epic_title,
39934
+ description: validated.epic_description,
39935
+ subtask_count: validated.subtasks.length,
39936
+ subtask_ids: created.slice(1).map((c) => c.id)
39937
+ });
39938
+ await appendEvent(epicCreatedEvent, effectiveProjectKey);
39939
+ } catch (error45) {
39940
+ console.warn("[hive_create_epic] Failed to emit epic_created event:", error45);
39941
+ }
39863
39942
  try {
39864
39943
  const event = createEvent("decomposition_generated", {
39865
39944
  project_key: effectiveProjectKey,
@@ -40024,6 +40103,23 @@ var hive_update = tool({
40024
40103
  cell = existingCell;
40025
40104
  }
40026
40105
  await adapter.markDirty(projectKey, cellId);
40106
+ try {
40107
+ const fieldsChanged = [];
40108
+ if (validated.status)
40109
+ fieldsChanged.push("status");
40110
+ if (validated.description !== undefined)
40111
+ fieldsChanged.push("description");
40112
+ if (validated.priority !== undefined)
40113
+ fieldsChanged.push("priority");
40114
+ const event = createEvent("cell_updated", {
40115
+ project_key: projectKey,
40116
+ cell_id: cellId,
40117
+ fields_changed: fieldsChanged
40118
+ });
40119
+ await appendEvent(event, projectKey);
40120
+ } catch (error45) {
40121
+ console.warn("[hive_update] Failed to emit cell_updated event:", error45);
40122
+ }
40027
40123
  const formatted = formatCellForOutput(cell);
40028
40124
  return JSON.stringify(formatted, null, 2);
40029
40125
  } catch (error45) {
@@ -40140,6 +40236,16 @@ var hive_close = tool({
40140
40236
  console.warn("[hive_close] Failed to emit SwarmCompletedEvent:", error45);
40141
40237
  }
40142
40238
  }
40239
+ try {
40240
+ const event = createEvent("cell_closed", {
40241
+ project_key: projectKey,
40242
+ cell_id: cellId,
40243
+ reason: validated.reason
40244
+ });
40245
+ await appendEvent(event, projectKey);
40246
+ } catch (error45) {
40247
+ console.warn("[hive_close] Failed to emit cell_closed event:", error45);
40248
+ }
40143
40249
  return `Closed ${cell.id}: ${validated.reason}`;
40144
40250
  } catch (error45) {
40145
40251
  const message = error45 instanceof Error ? error45.message : String(error45);
@@ -40165,6 +40271,17 @@ var hive_start = tool({
40165
40271
  const cellId = await resolvePartialId(adapter, projectKey, args.id) || args.id;
40166
40272
  const cell = await adapter.changeCellStatus(projectKey, cellId, "in_progress");
40167
40273
  await adapter.markDirty(projectKey, cellId);
40274
+ try {
40275
+ const event = createEvent("cell_status_changed", {
40276
+ project_key: projectKey,
40277
+ cell_id: cellId,
40278
+ old_status: "open",
40279
+ new_status: "in_progress"
40280
+ });
40281
+ await appendEvent(event, projectKey);
40282
+ } catch (error45) {
40283
+ console.warn("[hive_start] Failed to emit cell_status_changed event:", error45);
40284
+ }
40168
40285
  return `Started: ${cell.id}`;
40169
40286
  } catch (error45) {
40170
40287
  const message = error45 instanceof Error ? error45.message : String(error45);
@@ -40353,11 +40470,25 @@ var hive_sync = tool({
40353
40470
  }
40354
40471
  const remoteCheckResult = await runGitCommand(["remote"]);
40355
40472
  const hasRemote = remoteCheckResult.stdout.trim() !== "";
40473
+ let pushSuccess = false;
40356
40474
  if (hasRemote) {
40357
40475
  const pushResult = await withTimeout(runGitCommand(["push"]), TIMEOUT_MS, "git push");
40358
40476
  if (pushResult.exitCode !== 0) {
40359
40477
  throw new HiveError(`Failed to push: ${pushResult.stderr}`, "git push", pushResult.exitCode);
40360
40478
  }
40479
+ pushSuccess = true;
40480
+ }
40481
+ try {
40482
+ const event = createEvent("hive_synced", {
40483
+ project_key: projectKey,
40484
+ cells_synced: flushResult.cellsExported,
40485
+ push_success: pushSuccess
40486
+ });
40487
+ await appendEvent(event, projectKey);
40488
+ } catch (error45) {
40489
+ console.warn("[hive_sync] Failed to emit hive_synced event:", error45);
40490
+ }
40491
+ if (hasRemote) {
40361
40492
  return "Hive synced and pushed successfully";
40362
40493
  } else {
40363
40494
  return "Hive synced successfully (no remote configured)";
@@ -44943,9 +45074,9 @@ import {
44943
45074
  releaseSwarmFiles as releaseSwarmFiles2,
44944
45075
  sendSwarmMessage as sendSwarmMessage3,
44945
45076
  getAgent,
44946
- createEvent as createEvent2,
45077
+ createEvent as createEvent3,
44947
45078
  appendEvent as appendEvent2,
44948
- getSwarmMailLibSQL as getSwarmMailLibSQL2
45079
+ getSwarmMailLibSQL as getSwarmMailLibSQL3
44949
45080
  } from "swarm-mail";
44950
45081
  init_skills();
44951
45082
 
@@ -45448,9 +45579,9 @@ var swarm_review = tool({
45448
45579
  downstream_tasks: downstreamTasks.length > 0 ? downstreamTasks : undefined
45449
45580
  });
45450
45581
  try {
45451
- const { createEvent: createEvent2, appendEvent: appendEvent2 } = await import("swarm-mail");
45582
+ const { createEvent: createEvent3, appendEvent: appendEvent2 } = await import("swarm-mail");
45452
45583
  const attempt = getReviewStatus(args.task_id).attempt_count || 1;
45453
- const reviewStartedEvent = createEvent2("review_started", {
45584
+ const reviewStartedEvent = createEvent3("review_started", {
45454
45585
  project_key: args.project_key,
45455
45586
  epic_id: args.epic_id,
45456
45587
  bead_id: args.task_id,
@@ -45539,9 +45670,9 @@ var swarm_review_feedback = tool({
45539
45670
  console.warn("[swarm_review_feedback] Failed to trace review_decision:", error45);
45540
45671
  }
45541
45672
  try {
45542
- const { createEvent: createEvent2, appendEvent: appendEvent2 } = await import("swarm-mail");
45673
+ const { createEvent: createEvent3, appendEvent: appendEvent2 } = await import("swarm-mail");
45543
45674
  const attempt = getReviewStatus(args.task_id).attempt_count || 1;
45544
- const reviewCompletedEvent = createEvent2("review_completed", {
45675
+ const reviewCompletedEvent = createEvent3("review_completed", {
45545
45676
  project_key: args.project_key,
45546
45677
  epic_id: epicId,
45547
45678
  bead_id: args.task_id,
@@ -45610,9 +45741,9 @@ You may now complete the task with \`swarm_complete\`.`,
45610
45741
  console.warn("[swarm_review_feedback] Failed to trace review_decision:", error45);
45611
45742
  }
45612
45743
  try {
45613
- const { createEvent: createEvent2, appendEvent: appendEvent2 } = await import("swarm-mail");
45744
+ const { createEvent: createEvent3, appendEvent: appendEvent2 } = await import("swarm-mail");
45614
45745
  const status = remaining <= 0 ? "blocked" : "needs_changes";
45615
- const reviewCompletedEvent = createEvent2("review_completed", {
45746
+ const reviewCompletedEvent = createEvent3("review_completed", {
45616
45747
  project_key: args.project_key,
45617
45748
  epic_id: epicId,
45618
45749
  bead_id: args.task_id,
@@ -46168,7 +46299,7 @@ var swarm_progress = tool({
46168
46299
  }
46169
46300
  };
46170
46301
  const checkpointData = JSON.stringify(checkpoint);
46171
- const checkpointEvent = createEvent2("swarm_checkpointed", {
46302
+ const checkpointEvent = createEvent3("swarm_checkpointed", {
46172
46303
  project_key: args.project_key,
46173
46304
  ...checkpoint,
46174
46305
  checkpoint_size_bytes: Buffer.byteLength(checkpointData, "utf8"),
@@ -46176,7 +46307,7 @@ var swarm_progress = tool({
46176
46307
  });
46177
46308
  await appendEvent2(checkpointEvent, args.project_key);
46178
46309
  const checkpointId = `ckpt-${Date.now()}-${args.bead_id}`;
46179
- const createdEvent = createEvent2("checkpoint_created", {
46310
+ const createdEvent = createEvent3("checkpoint_created", {
46180
46311
  project_key: args.project_key,
46181
46312
  epic_id: epicId,
46182
46313
  bead_id: args.bead_id,
@@ -46429,7 +46560,7 @@ This will be recorded as a negative learning signal.`;
46429
46560
  let deferredResolved = false;
46430
46561
  let deferredError;
46431
46562
  try {
46432
- const swarmMail = await getSwarmMailLibSQL2(args.project_key);
46563
+ const swarmMail = await getSwarmMailLibSQL3(args.project_key);
46433
46564
  const db = await swarmMail.getDatabase();
46434
46565
  const deferredUrl = `deferred:${args.bead_id}`;
46435
46566
  const checkResult = await db.query(`SELECT url, resolved FROM deferred WHERE url = ? AND resolved = 0`, [deferredUrl]);
@@ -46458,16 +46589,16 @@ This will be recorded as a negative learning signal.`;
46458
46589
  syncError = error45 instanceof Error ? error45.message : String(error45);
46459
46590
  console.warn(`[swarm_complete] Auto-sync failed (non-fatal): ${syncError}`);
46460
46591
  }
46592
+ const completionDurationMs = args.start_time ? Date.now() - args.start_time : 0;
46593
+ const eventEpicId = cell.parent_id || (args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id);
46461
46594
  try {
46462
- const durationMs2 = args.start_time ? Date.now() - args.start_time : 0;
46463
- const eventEpicId = cell.parent_id || (args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id);
46464
- const event = createEvent2("subtask_outcome", {
46595
+ const event = createEvent3("subtask_outcome", {
46465
46596
  project_key: args.project_key,
46466
46597
  epic_id: eventEpicId,
46467
46598
  bead_id: args.bead_id,
46468
46599
  planned_files: args.planned_files || [],
46469
46600
  actual_files: args.files_touched || [],
46470
- duration_ms: durationMs2,
46601
+ duration_ms: completionDurationMs,
46471
46602
  error_count: args.error_count || 0,
46472
46603
  retry_count: args.retry_count || 0,
46473
46604
  success: true,
@@ -46478,8 +46609,21 @@ This will be recorded as a negative learning signal.`;
46478
46609
  } catch (error45) {
46479
46610
  console.warn("[swarm_complete] Failed to emit SubtaskOutcomeEvent:", error45);
46480
46611
  }
46612
+ try {
46613
+ const workerCompletedEvent = createEvent3("worker_completed", {
46614
+ project_key: args.project_key,
46615
+ epic_id: eventEpicId,
46616
+ bead_id: args.bead_id,
46617
+ worker_agent: args.agent_name,
46618
+ success: true,
46619
+ duration_ms: completionDurationMs,
46620
+ files_touched: args.files_touched || []
46621
+ });
46622
+ await appendEvent2(workerCompletedEvent, args.project_key);
46623
+ } catch (error45) {
46624
+ console.warn("[swarm_complete] Failed to emit worker_completed event:", error45);
46625
+ }
46481
46626
  let capturedStrategy;
46482
- const durationMs = args.start_time ? Date.now() - args.start_time : 0;
46483
46627
  const memoryInfo = formatMemoryStoreOnSuccess(args.bead_id, args.summary, args.files_touched || [], capturedStrategy);
46484
46628
  let memoryStored = false;
46485
46629
  let memoryError;
@@ -46596,7 +46740,7 @@ Files touched: ${args.files_touched?.join(", ") || "none recorded"}`,
46596
46740
  };
46597
46741
  try {
46598
46742
  const { captureSubtaskOutcome: captureSubtaskOutcome2 } = await Promise.resolve().then(() => (init_eval_capture(), exports_eval_capture));
46599
- const durationMs2 = args.start_time ? Date.now() - args.start_time : 0;
46743
+ const durationMs = args.start_time ? Date.now() - args.start_time : 0;
46600
46744
  const evalEpicId = cell.parent_id || epicId2;
46601
46745
  captureSubtaskOutcome2({
46602
46746
  epicId: evalEpicId,
@@ -46605,7 +46749,7 @@ Files touched: ${args.files_touched?.join(", ") || "none recorded"}`,
46605
46749
  title: cell.title,
46606
46750
  plannedFiles: args.planned_files || [],
46607
46751
  actualFiles: args.files_touched || [],
46608
- durationMs: durationMs2,
46752
+ durationMs,
46609
46753
  errorCount: args.error_count || 0,
46610
46754
  retryCount: args.retry_count || 0,
46611
46755
  success: true
@@ -46614,7 +46758,7 @@ Files touched: ${args.files_touched?.join(", ") || "none recorded"}`,
46614
46758
  console.warn("[swarm_complete] Failed to capture subtask outcome:", error45);
46615
46759
  }
46616
46760
  try {
46617
- const durationMs2 = args.start_time ? Date.now() - args.start_time : 0;
46761
+ const durationMs = args.start_time ? Date.now() - args.start_time : 0;
46618
46762
  captureCoordinatorEvent({
46619
46763
  session_id: _ctx.sessionID || "unknown",
46620
46764
  epic_id: epicId2,
@@ -46623,7 +46767,7 @@ Files touched: ${args.files_touched?.join(", ") || "none recorded"}`,
46623
46767
  outcome_type: "subtask_success",
46624
46768
  payload: {
46625
46769
  bead_id: args.bead_id,
46626
- duration_ms: durationMs2,
46770
+ duration_ms: durationMs,
46627
46771
  files_touched: args.files_touched || [],
46628
46772
  verification_passed: verificationResult?.passed ?? false,
46629
46773
  verification_skipped: args.skip_verification ?? false
@@ -47097,7 +47241,7 @@ var swarm_checkpoint = tool({
47097
47241
  }
47098
47242
  };
47099
47243
  const checkpointData = JSON.stringify(checkpoint);
47100
- const event = createEvent2("swarm_checkpointed", {
47244
+ const event = createEvent3("swarm_checkpointed", {
47101
47245
  project_key: args.project_key,
47102
47246
  epic_id: args.epic_id,
47103
47247
  bead_id: args.bead_id,
@@ -47139,8 +47283,8 @@ var swarm_recover = tool({
47139
47283
  },
47140
47284
  async execute(args) {
47141
47285
  try {
47142
- const { getSwarmMailLibSQL: getSwarmMailLibSQL3 } = await import("swarm-mail");
47143
- const swarmMail = await getSwarmMailLibSQL3(args.project_key);
47286
+ const { getSwarmMailLibSQL: getSwarmMailLibSQL4 } = await import("swarm-mail");
47287
+ const swarmMail = await getSwarmMailLibSQL4(args.project_key);
47144
47288
  const db = await swarmMail.getDatabase();
47145
47289
  const result = await db.query(`SELECT * FROM swarm_contexts
47146
47290
  WHERE epic_id = $1
@@ -47167,7 +47311,7 @@ var swarm_recover = tool({
47167
47311
  created_at: row.created_at,
47168
47312
  updated_at: row.updated_at
47169
47313
  };
47170
- const event = createEvent2("swarm_recovered", {
47314
+ const event = createEvent3("swarm_recovered", {
47171
47315
  project_key: args.project_key,
47172
47316
  epic_id: args.epic_id,
47173
47317
  bead_id: context.bead_id,
@@ -47342,7 +47486,7 @@ init_eval_capture();
47342
47486
 
47343
47487
  // src/memory-tools.ts
47344
47488
  init_dist();
47345
- import { getSwarmMailLibSQL as getSwarmMailLibSQL3 } from "swarm-mail";
47489
+ import { getSwarmMailLibSQL as getSwarmMailLibSQL4, createEvent as createEvent4, appendEvent as appendEvent3 } from "swarm-mail";
47346
47490
 
47347
47491
  // ../../node_modules/.bun/effect@3.19.12/node_modules/effect/dist/esm/Function.js
47348
47492
  var isFunction = (input) => typeof input === "function";
@@ -60959,7 +61103,7 @@ async function getMemoryAdapter(projectPath) {
60959
61103
  if (cachedAdapter && cachedProjectPath === path3) {
60960
61104
  return cachedAdapter;
60961
61105
  }
60962
- const swarmMail = await getSwarmMailLibSQL3(path3);
61106
+ const swarmMail = await getSwarmMailLibSQL4(path3);
60963
61107
  const dbAdapter = await swarmMail.getDatabase();
60964
61108
  cachedAdapter = await createMemoryAdapter(dbAdapter);
60965
61109
  cachedProjectPath = path3;
@@ -60980,6 +61124,21 @@ var semantic_memory_store = tool({
60980
61124
  async execute(args2, ctx) {
60981
61125
  const adapter = await getMemoryAdapter();
60982
61126
  const result = await adapter.store(args2);
61127
+ try {
61128
+ const projectKey = cachedProjectPath || process.cwd();
61129
+ const tags = args2.tags ? args2.tags.split(",").map((t) => t.trim()) : [];
61130
+ const event = createEvent4("memory_stored", {
61131
+ project_key: projectKey,
61132
+ memory_id: result.id,
61133
+ content_preview: args2.information.slice(0, 100),
61134
+ tags,
61135
+ auto_tagged: args2.autoTag,
61136
+ collection: args2.collection
61137
+ });
61138
+ await appendEvent3(event, projectKey);
61139
+ } catch (error45) {
61140
+ console.warn("[semantic_memory_store] Failed to emit memory_stored event:", error45);
61141
+ }
60983
61142
  return JSON.stringify(result, null, 2);
60984
61143
  }
60985
61144
  });
@@ -60993,8 +61152,25 @@ var semantic_memory_find = tool({
60993
61152
  fts: tool.schema.boolean().optional().describe("Use full-text search instead of vector search (default: false)")
60994
61153
  },
60995
61154
  async execute(args2, ctx) {
61155
+ const startTime = Date.now();
60996
61156
  const adapter = await getMemoryAdapter();
60997
61157
  const result = await adapter.find(args2);
61158
+ const duration3 = Date.now() - startTime;
61159
+ try {
61160
+ const projectKey = cachedProjectPath || process.cwd();
61161
+ const topScore = result.results.length > 0 ? result.results[0].score : undefined;
61162
+ const event = createEvent4("memory_found", {
61163
+ project_key: projectKey,
61164
+ query: args2.query,
61165
+ result_count: result.results.length,
61166
+ top_score: topScore,
61167
+ search_duration_ms: duration3,
61168
+ used_fts: args2.fts
61169
+ });
61170
+ await appendEvent3(event, projectKey);
61171
+ } catch (error45) {
61172
+ console.warn("[semantic_memory_find] Failed to emit memory_found event:", error45);
61173
+ }
60998
61174
  return JSON.stringify(result, null, 2);
60999
61175
  }
61000
61176
  });
@@ -61017,6 +61193,18 @@ var semantic_memory_remove = tool({
61017
61193
  async execute(args2, ctx) {
61018
61194
  const adapter = await getMemoryAdapter();
61019
61195
  const result = await adapter.remove(args2);
61196
+ if (result.success) {
61197
+ try {
61198
+ const projectKey = cachedProjectPath || process.cwd();
61199
+ const event = createEvent4("memory_deleted", {
61200
+ project_key: projectKey,
61201
+ memory_id: args2.id
61202
+ });
61203
+ await appendEvent3(event, projectKey);
61204
+ } catch (error45) {
61205
+ console.warn("[semantic_memory_remove] Failed to emit memory_deleted event:", error45);
61206
+ }
61207
+ }
61020
61208
  return JSON.stringify(result, null, 2);
61021
61209
  }
61022
61210
  });
@@ -61028,6 +61216,19 @@ var semantic_memory_validate = tool({
61028
61216
  async execute(args2, ctx) {
61029
61217
  const adapter = await getMemoryAdapter();
61030
61218
  const result = await adapter.validate(args2);
61219
+ if (result.success) {
61220
+ try {
61221
+ const projectKey = cachedProjectPath || process.cwd();
61222
+ const event = createEvent4("memory_validated", {
61223
+ project_key: projectKey,
61224
+ memory_id: args2.id,
61225
+ decay_reset: true
61226
+ });
61227
+ await appendEvent3(event, projectKey);
61228
+ } catch (error45) {
61229
+ console.warn("[semantic_memory_validate] Failed to emit memory_validated event:", error45);
61230
+ }
61231
+ }
61031
61232
  return JSON.stringify(result, null, 2);
61032
61233
  }
61033
61234
  });
@@ -61075,6 +61276,18 @@ var semantic_memory_upsert = tool({
61075
61276
  async execute(args2, ctx) {
61076
61277
  const adapter = await getMemoryAdapter();
61077
61278
  const result = await adapter.upsert(args2);
61279
+ try {
61280
+ const projectKey = cachedProjectPath || process.cwd();
61281
+ const event = createEvent4("memory_updated", {
61282
+ project_key: projectKey,
61283
+ memory_id: result.memoryId || "unknown",
61284
+ operation: result.operation,
61285
+ reason: result.reason
61286
+ });
61287
+ await appendEvent3(event, projectKey);
61288
+ } catch (error45) {
61289
+ console.warn("[semantic_memory_upsert] Failed to emit memory_updated event:", error45);
61290
+ }
61078
61291
  return JSON.stringify(result, null, 2);
61079
61292
  }
61080
61293
  });
@@ -62060,9 +62273,9 @@ var swarm_spawn_subtask = tool({
62060
62273
  }
62061
62274
  if (args2.project_path) {
62062
62275
  try {
62063
- const { createEvent: createEvent3, appendEvent: appendEvent3 } = await import("swarm-mail");
62276
+ const { createEvent: createEvent5, appendEvent: appendEvent4 } = await import("swarm-mail");
62064
62277
  const spawnOrder = 0;
62065
- const workerSpawnedEvent = createEvent3("worker_spawned", {
62278
+ const workerSpawnedEvent = createEvent5("worker_spawned", {
62066
62279
  project_key: args2.project_path,
62067
62280
  epic_id: args2.epic_id,
62068
62281
  bead_id: args2.bead_id,
@@ -62072,7 +62285,7 @@ var swarm_spawn_subtask = tool({
62072
62285
  spawn_order: spawnOrder,
62073
62286
  is_parallel: false
62074
62287
  });
62075
- await appendEvent3(workerSpawnedEvent, args2.project_path);
62288
+ await appendEvent4(workerSpawnedEvent, args2.project_path);
62076
62289
  } catch (error45) {
62077
62290
  console.warn("[swarm_spawn_subtask] Failed to emit WorkerSpawnedEvent:", error45);
62078
62291
  }
@@ -63704,7 +63917,7 @@ import {
63704
63917
  agentActivity,
63705
63918
  checkpointFrequency,
63706
63919
  failedDecompositions,
63707
- getSwarmMailLibSQL as getSwarmMailLibSQL4,
63920
+ getSwarmMailLibSQL as getSwarmMailLibSQL5,
63708
63921
  humanFeedback,
63709
63922
  lockContention,
63710
63923
  messageLatency,
@@ -63769,7 +63982,7 @@ var swarm_analytics = tool({
63769
63982
  async execute(args2) {
63770
63983
  try {
63771
63984
  const projectPath = process.cwd();
63772
- const db = await getSwarmMailLibSQL4(projectPath);
63985
+ const db = await getSwarmMailLibSQL5(projectPath);
63773
63986
  const filters = {
63774
63987
  project_key: projectPath
63775
63988
  };
@@ -63839,7 +64052,7 @@ var swarm_query = tool({
63839
64052
  async execute(args2) {
63840
64053
  try {
63841
64054
  const projectPath = process.cwd();
63842
- const swarmMail = await getSwarmMailLibSQL4(projectPath);
64055
+ const swarmMail = await getSwarmMailLibSQL5(projectPath);
63843
64056
  const db = await swarmMail.getDatabase();
63844
64057
  if (!args2.sql.trim().toLowerCase().startsWith("select")) {
63845
64058
  return JSON.stringify({
@@ -63889,7 +64102,7 @@ var swarm_diagnose = tool({
63889
64102
  async execute(args2) {
63890
64103
  try {
63891
64104
  const projectPath = process.cwd();
63892
- const swarmMail = await getSwarmMailLibSQL4(projectPath);
64105
+ const swarmMail = await getSwarmMailLibSQL5(projectPath);
63893
64106
  const db = await swarmMail.getDatabase();
63894
64107
  const diagnosis = [];
63895
64108
  const include = args2.include || [
@@ -64000,7 +64213,7 @@ var swarm_insights = tool({
64000
64213
  });
64001
64214
  }
64002
64215
  const projectPath = process.cwd();
64003
- const swarmMail = await getSwarmMailLibSQL4(projectPath);
64216
+ const swarmMail = await getSwarmMailLibSQL5(projectPath);
64004
64217
  const db = await swarmMail.getDatabase();
64005
64218
  const insights = [];
64006
64219
  if (args2.metrics.includes("success_rate")) {
@@ -64556,6 +64769,268 @@ var contributorTools = {
64556
64769
  contributor_lookup
64557
64770
  };
64558
64771
 
64772
+ // src/cass-tools.ts
64773
+ init_dist();
64774
+ import { execSync, spawn } from "child_process";
64775
+ import { getSwarmMailLibSQL as getSwarmMailLibSQL6, createEvent as createEvent5 } from "swarm-mail";
64776
+ function isCassAvailable() {
64777
+ try {
64778
+ execSync("which cass", { stdio: "ignore" });
64779
+ return true;
64780
+ } catch {
64781
+ return false;
64782
+ }
64783
+ }
64784
+ async function execCass(args2) {
64785
+ return new Promise((resolve2, reject) => {
64786
+ const proc = spawn("cass", args2, {
64787
+ stdio: ["ignore", "pipe", "pipe"]
64788
+ });
64789
+ let stdout = "";
64790
+ let stderr = "";
64791
+ proc.stdout.on("data", (data) => {
64792
+ stdout += data;
64793
+ });
64794
+ proc.stderr.on("data", (data) => {
64795
+ stderr += data;
64796
+ });
64797
+ proc.on("close", (code) => {
64798
+ if (code === 0) {
64799
+ resolve2(stdout);
64800
+ } else {
64801
+ reject(new Error(stderr || `cass exited with code ${code}`));
64802
+ }
64803
+ });
64804
+ proc.on("error", (err) => {
64805
+ if (err.code === "ENOENT") {
64806
+ reject(new Error("cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"));
64807
+ } else {
64808
+ reject(err);
64809
+ }
64810
+ });
64811
+ });
64812
+ }
64813
+ async function emitEvent(eventType, data) {
64814
+ try {
64815
+ const projectPath = process.cwd();
64816
+ const swarmMail = await getSwarmMailLibSQL6(projectPath);
64817
+ const event = createEvent5(eventType, {
64818
+ project_key: projectPath,
64819
+ ...data
64820
+ });
64821
+ await swarmMail.appendEvent(event);
64822
+ } catch {}
64823
+ }
64824
+ var cass_search = tool({
64825
+ 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.",
64826
+ args: {
64827
+ query: tool.schema.string().describe("Search query (e.g., 'authentication error Next.js')"),
64828
+ agent: tool.schema.string().optional().describe("Filter by agent name (e.g., 'claude', 'cursor')"),
64829
+ days: tool.schema.number().optional().describe("Only search sessions from last N days"),
64830
+ limit: tool.schema.number().optional().describe("Max results to return (default: 5)"),
64831
+ fields: tool.schema.string().optional().describe("Field selection: 'minimal' for compact output (path, line, agent only)")
64832
+ },
64833
+ async execute(args2) {
64834
+ const startTime = Date.now();
64835
+ if (!isCassAvailable()) {
64836
+ return JSON.stringify({
64837
+ error: "cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"
64838
+ });
64839
+ }
64840
+ try {
64841
+ const cliArgs = ["search", args2.query];
64842
+ if (args2.agent) {
64843
+ cliArgs.push("--agent", args2.agent);
64844
+ }
64845
+ if (args2.days) {
64846
+ cliArgs.push("--days", String(args2.days));
64847
+ }
64848
+ if (args2.limit) {
64849
+ cliArgs.push("--limit", String(args2.limit));
64850
+ }
64851
+ if (args2.fields === "minimal") {
64852
+ cliArgs.push("--minimal");
64853
+ }
64854
+ const output = await execCass(cliArgs);
64855
+ const lines = output.trim().split(`
64856
+ `).filter((l) => l.trim());
64857
+ const resultCount = lines.length;
64858
+ await emitEvent("cass_searched", {
64859
+ query: args2.query,
64860
+ agent_filter: args2.agent,
64861
+ days_filter: args2.days,
64862
+ result_count: resultCount,
64863
+ search_duration_ms: Date.now() - startTime
64864
+ });
64865
+ return output;
64866
+ } catch (error45) {
64867
+ return JSON.stringify({
64868
+ error: error45 instanceof Error ? error45.message : String(error45)
64869
+ });
64870
+ }
64871
+ }
64872
+ });
64873
+ var cass_view = tool({
64874
+ description: "View a specific conversation/session from search results. Use source_path from cass_search output.",
64875
+ args: {
64876
+ path: tool.schema.string().describe("Path to session file (from cass_search results)"),
64877
+ line: tool.schema.number().optional().describe("Jump to specific line number")
64878
+ },
64879
+ async execute(args2) {
64880
+ if (!isCassAvailable()) {
64881
+ return JSON.stringify({
64882
+ error: "cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"
64883
+ });
64884
+ }
64885
+ try {
64886
+ const cliArgs = ["view", args2.path];
64887
+ if (args2.line) {
64888
+ cliArgs.push("--line", String(args2.line));
64889
+ }
64890
+ const output = await execCass(cliArgs);
64891
+ let agentType;
64892
+ if (args2.path.includes("claude"))
64893
+ agentType = "claude";
64894
+ else if (args2.path.includes("cursor"))
64895
+ agentType = "cursor";
64896
+ else if (args2.path.includes("opencode"))
64897
+ agentType = "opencode";
64898
+ else if (args2.path.includes("codex"))
64899
+ agentType = "codex";
64900
+ await emitEvent("cass_viewed", {
64901
+ session_path: args2.path,
64902
+ line_number: args2.line,
64903
+ agent_type: agentType
64904
+ });
64905
+ return output;
64906
+ } catch (error45) {
64907
+ return JSON.stringify({
64908
+ error: error45 instanceof Error ? error45.message : String(error45)
64909
+ });
64910
+ }
64911
+ }
64912
+ });
64913
+ var cass_expand = tool({
64914
+ description: "Expand context around a specific line in a session. Shows messages before/after.",
64915
+ args: {
64916
+ path: tool.schema.string().describe("Path to session file"),
64917
+ line: tool.schema.number().describe("Line number to expand around"),
64918
+ context: tool.schema.number().optional().describe("Number of lines before/after to show (default: 5)")
64919
+ },
64920
+ async execute(args2) {
64921
+ if (!isCassAvailable()) {
64922
+ return JSON.stringify({
64923
+ error: "cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"
64924
+ });
64925
+ }
64926
+ try {
64927
+ const cliArgs = ["expand", args2.path, "--line", String(args2.line)];
64928
+ if (args2.context) {
64929
+ cliArgs.push("--context", String(args2.context));
64930
+ }
64931
+ const output = await execCass(cliArgs);
64932
+ await emitEvent("cass_viewed", {
64933
+ session_path: args2.path,
64934
+ line_number: args2.line
64935
+ });
64936
+ return output;
64937
+ } catch (error45) {
64938
+ return JSON.stringify({
64939
+ error: error45 instanceof Error ? error45.message : String(error45)
64940
+ });
64941
+ }
64942
+ }
64943
+ });
64944
+ var cass_health = tool({
64945
+ description: "Check if cass index is healthy. Exit 0 = ready, Exit 1 = needs indexing. Run this before searching.",
64946
+ args: {},
64947
+ async execute() {
64948
+ if (!isCassAvailable()) {
64949
+ return JSON.stringify({
64950
+ healthy: false,
64951
+ error: "cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"
64952
+ });
64953
+ }
64954
+ try {
64955
+ await execCass(["health"]);
64956
+ return JSON.stringify({ healthy: true, message: "Index is ready" });
64957
+ } catch (error45) {
64958
+ return JSON.stringify({
64959
+ healthy: false,
64960
+ message: "Index needs rebuilding. Run cass_index()",
64961
+ error: error45 instanceof Error ? error45.message : String(error45)
64962
+ });
64963
+ }
64964
+ }
64965
+ });
64966
+ var cass_index = tool({
64967
+ description: "Build or rebuild the search index. Run this if health check fails or to pick up new sessions.",
64968
+ args: {
64969
+ full: tool.schema.boolean().optional().describe("Force full rebuild (default: incremental)")
64970
+ },
64971
+ async execute(args2) {
64972
+ const startTime = Date.now();
64973
+ if (!isCassAvailable()) {
64974
+ return JSON.stringify({
64975
+ error: "cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"
64976
+ });
64977
+ }
64978
+ try {
64979
+ const cliArgs = ["index"];
64980
+ if (args2.full) {
64981
+ cliArgs.push("--full");
64982
+ }
64983
+ const output = await execCass(cliArgs);
64984
+ let sessionsIndexed = 0;
64985
+ let messagesIndexed = 0;
64986
+ const sessionsMatch = output.match(/(\d+)\s*sessions?/i);
64987
+ const messagesMatch = output.match(/(\d+)\s*messages?/i);
64988
+ if (sessionsMatch)
64989
+ sessionsIndexed = parseInt(sessionsMatch[1], 10);
64990
+ if (messagesMatch)
64991
+ messagesIndexed = parseInt(messagesMatch[1], 10);
64992
+ await emitEvent("cass_indexed", {
64993
+ sessions_indexed: sessionsIndexed,
64994
+ messages_indexed: messagesIndexed,
64995
+ duration_ms: Date.now() - startTime,
64996
+ full_rebuild: args2.full ?? false
64997
+ });
64998
+ return output;
64999
+ } catch (error45) {
65000
+ return JSON.stringify({
65001
+ error: error45 instanceof Error ? error45.message : String(error45)
65002
+ });
65003
+ }
65004
+ }
65005
+ });
65006
+ var cass_stats = tool({
65007
+ description: "Show index statistics - how many sessions, messages, agents indexed.",
65008
+ args: {},
65009
+ async execute() {
65010
+ if (!isCassAvailable()) {
65011
+ return JSON.stringify({
65012
+ error: "cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"
65013
+ });
65014
+ }
65015
+ try {
65016
+ const output = await execCass(["stats"]);
65017
+ return output;
65018
+ } catch (error45) {
65019
+ return JSON.stringify({
65020
+ error: error45 instanceof Error ? error45.message : String(error45)
65021
+ });
65022
+ }
65023
+ }
65024
+ });
65025
+ var cassTools = {
65026
+ cass_search,
65027
+ cass_view,
65028
+ cass_expand,
65029
+ cass_health,
65030
+ cass_index,
65031
+ cass_stats
65032
+ };
65033
+
64559
65034
  // src/output-guardrails.ts
64560
65035
  var DEFAULT_GUARDRAIL_CONFIG = {
64561
65036
  defaultMaxChars: 32000,
@@ -66150,7 +66625,8 @@ var allTools = {
66150
66625
  ...mandateTools,
66151
66626
  ...memoryTools,
66152
66627
  ...observabilityTools,
66153
- ...contributorTools
66628
+ ...contributorTools,
66629
+ ...cassTools
66154
66630
  };
66155
66631
 
66156
66632
  // src/plugin.ts