opencode-swarm-plugin 0.45.7 → 0.46.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.
Files changed (47) hide show
  1. package/bin/cass.characterization.test.ts +400 -379
  2. package/bin/eval-gate.test.ts +23 -0
  3. package/bin/eval-gate.ts +21 -0
  4. package/bin/swarm.ts +141 -45
  5. package/dist/bin/swarm.js +1715 -1415
  6. package/dist/cass-tools.d.ts +1 -2
  7. package/dist/cass-tools.d.ts.map +1 -1
  8. package/dist/compaction-hook.d.ts +50 -6
  9. package/dist/compaction-hook.d.ts.map +1 -1
  10. package/dist/dashboard.d.ts +5 -6
  11. package/dist/dashboard.d.ts.map +1 -1
  12. package/dist/eval-capture.d.ts +20 -10
  13. package/dist/eval-capture.d.ts.map +1 -1
  14. package/dist/eval-capture.js +54 -21
  15. package/dist/eval-learning.d.ts +5 -5
  16. package/dist/eval-learning.d.ts.map +1 -1
  17. package/dist/hive.d.ts +7 -0
  18. package/dist/hive.d.ts.map +1 -1
  19. package/dist/hive.js +61 -24
  20. package/dist/hivemind-tools.d.ts +479 -0
  21. package/dist/hivemind-tools.d.ts.map +1 -0
  22. package/dist/index.d.ts +31 -98
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +1018 -467
  25. package/dist/observability-health.d.ts +87 -0
  26. package/dist/observability-health.d.ts.map +1 -0
  27. package/dist/observability-tools.d.ts +5 -1
  28. package/dist/observability-tools.d.ts.map +1 -1
  29. package/dist/planning-guardrails.d.ts +24 -5
  30. package/dist/planning-guardrails.d.ts.map +1 -1
  31. package/dist/plugin.js +1006 -475
  32. package/dist/query-tools.d.ts +23 -5
  33. package/dist/query-tools.d.ts.map +1 -1
  34. package/dist/regression-detection.d.ts +58 -0
  35. package/dist/regression-detection.d.ts.map +1 -0
  36. package/dist/swarm-orchestrate.d.ts +3 -3
  37. package/dist/swarm-orchestrate.d.ts.map +1 -1
  38. package/dist/swarm-prompts.d.ts +4 -4
  39. package/dist/swarm-prompts.d.ts.map +1 -1
  40. package/dist/swarm-prompts.js +165 -74
  41. package/dist/swarm-research.d.ts +0 -2
  42. package/dist/swarm-research.d.ts.map +1 -1
  43. package/dist/tool-availability.d.ts +1 -1
  44. package/dist/tool-availability.d.ts.map +1 -1
  45. package/examples/commands/swarm.md +7 -7
  46. package/global-skills/swarm-coordination/SKILL.md +6 -6
  47. package/package.json +6 -3
package/dist/plugin.js CHANGED
@@ -12726,6 +12726,7 @@ __export(exports_eval_capture, {
12726
12726
  import * as fs from "node:fs";
12727
12727
  import * as os from "node:os";
12728
12728
  import * as path from "node:path";
12729
+ import { getSwarmMailLibSQL } from "swarm-mail";
12729
12730
  function getEvalDataPath(projectPath) {
12730
12731
  return path.join(projectPath, DEFAULT_EVAL_DATA_PATH);
12731
12732
  }
@@ -12905,7 +12906,7 @@ function getEvalDataStats(projectPath) {
12905
12906
  };
12906
12907
  }
12907
12908
  function getSessionDir() {
12908
- return path.join(os.homedir(), ".config", "swarm-tools", "sessions");
12909
+ return process.env.SWARM_SESSIONS_DIR || path.join(os.homedir(), ".config", "swarm-tools", "sessions");
12909
12910
  }
12910
12911
  function getSessionPath(sessionId) {
12911
12912
  return path.join(getSessionDir(), `${sessionId}.jsonl`);
@@ -12916,15 +12917,46 @@ function ensureSessionDir() {
12916
12917
  fs.mkdirSync(sessionDir, { recursive: true });
12917
12918
  }
12918
12919
  }
12919
- function captureCoordinatorEvent(event) {
12920
+ async function captureCoordinatorEvent(event) {
12920
12921
  CoordinatorEventSchema.parse(event);
12921
- ensureSessionDir();
12922
- const sessionPath = getSessionPath(event.session_id);
12923
- const line = `${JSON.stringify(event)}
12922
+ try {
12923
+ const projectPath = process.cwd();
12924
+ const swarmMail = await getSwarmMailLibSQL(projectPath);
12925
+ const eventType = `coordinator_${event.event_type.toLowerCase()}`;
12926
+ const eventData = {
12927
+ type: eventType,
12928
+ project_key: projectPath,
12929
+ timestamp: new Date(event.timestamp).getTime(),
12930
+ session_id: event.session_id,
12931
+ epic_id: event.epic_id,
12932
+ event_type: event.event_type,
12933
+ payload: event.payload
12934
+ };
12935
+ if (event.event_type === "DECISION") {
12936
+ eventData.decision_type = event.decision_type;
12937
+ } else if (event.event_type === "VIOLATION") {
12938
+ eventData.violation_type = event.violation_type;
12939
+ } else if (event.event_type === "OUTCOME") {
12940
+ eventData.outcome_type = event.outcome_type;
12941
+ } else if (event.event_type === "COMPACTION") {
12942
+ eventData.compaction_type = event.compaction_type;
12943
+ }
12944
+ await swarmMail.appendEvent(eventData);
12945
+ ensureSessionDir();
12946
+ const sessionPath = getSessionPath(event.session_id);
12947
+ const line = `${JSON.stringify(event)}
12924
12948
  `;
12925
- fs.appendFileSync(sessionPath, line, "utf-8");
12949
+ fs.appendFileSync(sessionPath, line, "utf-8");
12950
+ } catch (error45) {
12951
+ console.warn("Failed to append event to libSQL, using JSONL fallback:", error45);
12952
+ ensureSessionDir();
12953
+ const sessionPath = getSessionPath(event.session_id);
12954
+ const line = `${JSON.stringify(event)}
12955
+ `;
12956
+ fs.appendFileSync(sessionPath, line, "utf-8");
12957
+ }
12926
12958
  }
12927
- function captureCompactionEvent(params) {
12959
+ async function captureCompactionEvent(params) {
12928
12960
  const event = {
12929
12961
  session_id: params.session_id,
12930
12962
  epic_id: params.epic_id,
@@ -12933,9 +12965,9 @@ function captureCompactionEvent(params) {
12933
12965
  compaction_type: params.compaction_type,
12934
12966
  payload: params.payload
12935
12967
  };
12936
- captureCoordinatorEvent(event);
12968
+ await captureCoordinatorEvent(event);
12937
12969
  }
12938
- function captureResearcherSpawned(params) {
12970
+ async function captureResearcherSpawned(params) {
12939
12971
  const event = {
12940
12972
  session_id: params.session_id,
12941
12973
  epic_id: params.epic_id,
@@ -12948,9 +12980,9 @@ function captureResearcherSpawned(params) {
12948
12980
  tools_used: params.tools_used || []
12949
12981
  }
12950
12982
  };
12951
- captureCoordinatorEvent(event);
12983
+ await captureCoordinatorEvent(event);
12952
12984
  }
12953
- function captureSkillLoaded(params) {
12985
+ async function captureSkillLoaded(params) {
12954
12986
  const event = {
12955
12987
  session_id: params.session_id,
12956
12988
  epic_id: params.epic_id,
@@ -12962,9 +12994,9 @@ function captureSkillLoaded(params) {
12962
12994
  context: params.context
12963
12995
  }
12964
12996
  };
12965
- captureCoordinatorEvent(event);
12997
+ await captureCoordinatorEvent(event);
12966
12998
  }
12967
- function captureInboxChecked(params) {
12999
+ async function captureInboxChecked(params) {
12968
13000
  const event = {
12969
13001
  session_id: params.session_id,
12970
13002
  epic_id: params.epic_id,
@@ -12976,9 +13008,9 @@ function captureInboxChecked(params) {
12976
13008
  urgent_count: params.urgent_count
12977
13009
  }
12978
13010
  };
12979
- captureCoordinatorEvent(event);
13011
+ await captureCoordinatorEvent(event);
12980
13012
  }
12981
- function captureBlockerResolved(params) {
13013
+ async function captureBlockerResolved(params) {
12982
13014
  const event = {
12983
13015
  session_id: params.session_id,
12984
13016
  epic_id: params.epic_id,
@@ -12992,9 +13024,9 @@ function captureBlockerResolved(params) {
12992
13024
  resolution: params.resolution
12993
13025
  }
12994
13026
  };
12995
- captureCoordinatorEvent(event);
13027
+ await captureCoordinatorEvent(event);
12996
13028
  }
12997
- function captureScopeChangeDecision(params) {
13029
+ async function captureScopeChangeDecision(params) {
12998
13030
  const event = {
12999
13031
  session_id: params.session_id,
13000
13032
  epic_id: params.epic_id,
@@ -13014,9 +13046,9 @@ function captureScopeChangeDecision(params) {
13014
13046
  rejection_reason: params.rejection_reason
13015
13047
  }
13016
13048
  };
13017
- captureCoordinatorEvent(event);
13049
+ await captureCoordinatorEvent(event);
13018
13050
  }
13019
- function captureBlockerDetected(params) {
13051
+ async function captureBlockerDetected(params) {
13020
13052
  const event = {
13021
13053
  session_id: params.session_id,
13022
13054
  epic_id: params.epic_id,
@@ -13031,7 +13063,7 @@ function captureBlockerDetected(params) {
13031
13063
  reported_at: new Date().toISOString()
13032
13064
  }
13033
13065
  };
13034
- captureCoordinatorEvent(event);
13066
+ await captureCoordinatorEvent(event);
13035
13067
  }
13036
13068
  function readSessionEvents(sessionId) {
13037
13069
  const sessionPath = getSessionPath(sessionId);
@@ -13134,7 +13166,8 @@ var init_eval_capture = __esm(() => {
13134
13166
  "coordinator_edited_file",
13135
13167
  "coordinator_ran_tests",
13136
13168
  "coordinator_reserved_files",
13137
- "no_worker_spawned"
13169
+ "no_worker_spawned",
13170
+ "worker_completed_without_review"
13138
13171
  ]),
13139
13172
  payload: exports_external.any()
13140
13173
  }),
@@ -26904,11 +26937,11 @@ import {
26904
26937
  sep
26905
26938
  } from "path";
26906
26939
  import { fileURLToPath } from "url";
26907
- import { getSwarmMailLibSQL as getSwarmMailLibSQL2, createEvent as createEvent2 } from "swarm-mail";
26940
+ import { getSwarmMailLibSQL as getSwarmMailLibSQL3, createEvent as createEvent2 } from "swarm-mail";
26908
26941
  async function emitSkillLoadedEvent(data) {
26909
26942
  try {
26910
26943
  const projectPath = skillsProjectDirectory;
26911
- const swarmMail = await getSwarmMailLibSQL2(projectPath);
26944
+ const swarmMail = await getSwarmMailLibSQL3(projectPath);
26912
26945
  const event = createEvent2("skill_loaded", {
26913
26946
  project_key: projectPath,
26914
26947
  skill_name: data.skill_name,
@@ -26922,7 +26955,7 @@ async function emitSkillLoadedEvent(data) {
26922
26955
  async function emitSkillCreatedEvent(data) {
26923
26956
  try {
26924
26957
  const projectPath = skillsProjectDirectory;
26925
- const swarmMail = await getSwarmMailLibSQL2(projectPath);
26958
+ const swarmMail = await getSwarmMailLibSQL3(projectPath);
26926
26959
  const event = createEvent2("skill_created", {
26927
26960
  project_key: projectPath,
26928
26961
  skill_name: data.skill_name,
@@ -35190,8 +35223,8 @@ var require_req = __commonJS((exports, module) => {
35190
35223
  if (req.originalUrl) {
35191
35224
  _req.url = req.originalUrl;
35192
35225
  } else {
35193
- const path3 = req.path;
35194
- _req.url = typeof path3 === "string" ? path3 : req.url ? req.url.path || req.url : undefined;
35226
+ const path4 = req.path;
35227
+ _req.url = typeof path4 === "string" ? path4 : req.url ? req.url.path || req.url : undefined;
35195
35228
  }
35196
35229
  if (req.query) {
35197
35230
  _req.query = req.query;
@@ -35347,14 +35380,14 @@ var require_redact = __commonJS((exports, module) => {
35347
35380
  }
35348
35381
  return obj;
35349
35382
  }
35350
- function parsePath(path3) {
35383
+ function parsePath(path4) {
35351
35384
  const parts2 = [];
35352
35385
  let current = "";
35353
35386
  let inBrackets = false;
35354
35387
  let inQuotes = false;
35355
35388
  let quoteChar = "";
35356
- for (let i = 0;i < path3.length; i++) {
35357
- const char = path3[i];
35389
+ for (let i = 0;i < path4.length; i++) {
35390
+ const char = path4[i];
35358
35391
  if (!inBrackets && char === ".") {
35359
35392
  if (current) {
35360
35393
  parts2.push(current);
@@ -35485,10 +35518,10 @@ var require_redact = __commonJS((exports, module) => {
35485
35518
  return current;
35486
35519
  }
35487
35520
  function redactPaths(obj, paths, censor, remove7 = false) {
35488
- for (const path3 of paths) {
35489
- const parts2 = parsePath(path3);
35521
+ for (const path4 of paths) {
35522
+ const parts2 = parsePath(path4);
35490
35523
  if (parts2.includes("*")) {
35491
- redactWildcardPath(obj, parts2, censor, path3, remove7);
35524
+ redactWildcardPath(obj, parts2, censor, path4, remove7);
35492
35525
  } else {
35493
35526
  if (remove7) {
35494
35527
  removeKey(obj, parts2);
@@ -35575,8 +35608,8 @@ var require_redact = __commonJS((exports, module) => {
35575
35608
  }
35576
35609
  } else {
35577
35610
  if (afterWildcard.includes("*")) {
35578
- const wrappedCensor = typeof censor === "function" ? (value, path3) => {
35579
- const fullPath = [...pathArray.slice(0, pathLength), ...path3];
35611
+ const wrappedCensor = typeof censor === "function" ? (value, path4) => {
35612
+ const fullPath = [...pathArray.slice(0, pathLength), ...path4];
35580
35613
  return censor(value, fullPath);
35581
35614
  } : censor;
35582
35615
  redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove7);
@@ -35613,8 +35646,8 @@ var require_redact = __commonJS((exports, module) => {
35613
35646
  return null;
35614
35647
  }
35615
35648
  const pathStructure = new Map;
35616
- for (const path3 of pathsToClone) {
35617
- const parts2 = parsePath(path3);
35649
+ for (const path4 of pathsToClone) {
35650
+ const parts2 = parsePath(path4);
35618
35651
  let current = pathStructure;
35619
35652
  for (let i = 0;i < parts2.length; i++) {
35620
35653
  const part = parts2[i];
@@ -35666,24 +35699,24 @@ var require_redact = __commonJS((exports, module) => {
35666
35699
  }
35667
35700
  return cloneSelectively(obj, pathStructure);
35668
35701
  }
35669
- function validatePath(path3) {
35670
- if (typeof path3 !== "string") {
35702
+ function validatePath(path4) {
35703
+ if (typeof path4 !== "string") {
35671
35704
  throw new Error("Paths must be (non-empty) strings");
35672
35705
  }
35673
- if (path3 === "") {
35706
+ if (path4 === "") {
35674
35707
  throw new Error("Invalid redaction path ()");
35675
35708
  }
35676
- if (path3.includes("..")) {
35677
- throw new Error(`Invalid redaction path (${path3})`);
35709
+ if (path4.includes("..")) {
35710
+ throw new Error(`Invalid redaction path (${path4})`);
35678
35711
  }
35679
- if (path3.includes(",")) {
35680
- throw new Error(`Invalid redaction path (${path3})`);
35712
+ if (path4.includes(",")) {
35713
+ throw new Error(`Invalid redaction path (${path4})`);
35681
35714
  }
35682
35715
  let bracketCount = 0;
35683
35716
  let inQuotes = false;
35684
35717
  let quoteChar = "";
35685
- for (let i = 0;i < path3.length; i++) {
35686
- const char = path3[i];
35718
+ for (let i = 0;i < path4.length; i++) {
35719
+ const char = path4[i];
35687
35720
  if ((char === '"' || char === "'") && bracketCount > 0) {
35688
35721
  if (!inQuotes) {
35689
35722
  inQuotes = true;
@@ -35697,20 +35730,20 @@ var require_redact = __commonJS((exports, module) => {
35697
35730
  } else if (char === "]" && !inQuotes) {
35698
35731
  bracketCount--;
35699
35732
  if (bracketCount < 0) {
35700
- throw new Error(`Invalid redaction path (${path3})`);
35733
+ throw new Error(`Invalid redaction path (${path4})`);
35701
35734
  }
35702
35735
  }
35703
35736
  }
35704
35737
  if (bracketCount !== 0) {
35705
- throw new Error(`Invalid redaction path (${path3})`);
35738
+ throw new Error(`Invalid redaction path (${path4})`);
35706
35739
  }
35707
35740
  }
35708
35741
  function validatePaths(paths) {
35709
35742
  if (!Array.isArray(paths)) {
35710
35743
  throw new TypeError("paths must be an array");
35711
35744
  }
35712
- for (const path3 of paths) {
35713
- validatePath(path3);
35745
+ for (const path4 of paths) {
35746
+ validatePath(path4);
35714
35747
  }
35715
35748
  }
35716
35749
  function slowRedact(options2 = {}) {
@@ -35872,8 +35905,8 @@ var require_redaction = __commonJS((exports, module) => {
35872
35905
  if (shape[k] === null) {
35873
35906
  o[k] = (value) => topCensor(value, [k]);
35874
35907
  } else {
35875
- const wrappedCensor = typeof censor === "function" ? (value, path3) => {
35876
- return censor(value, [k, ...path3]);
35908
+ const wrappedCensor = typeof censor === "function" ? (value, path4) => {
35909
+ return censor(value, [k, ...path4]);
35877
35910
  } : censor;
35878
35911
  o[k] = Redact({
35879
35912
  paths: shape[k],
@@ -36084,7 +36117,7 @@ var require_sonic_boom = __commonJS((exports, module) => {
36084
36117
  var fs2 = __require("fs");
36085
36118
  var EventEmitter = __require("events");
36086
36119
  var inherits = __require("util").inherits;
36087
- var path3 = __require("path");
36120
+ var path4 = __require("path");
36088
36121
  var sleep5 = require_atomic_sleep();
36089
36122
  var assert2 = __require("assert");
36090
36123
  var BUSY_WRITE_TIMEOUT = 100;
@@ -36139,7 +36172,7 @@ var require_sonic_boom = __commonJS((exports, module) => {
36139
36172
  if (sonic.sync) {
36140
36173
  try {
36141
36174
  if (sonic.mkdir)
36142
- fs2.mkdirSync(path3.dirname(file2), { recursive: true });
36175
+ fs2.mkdirSync(path4.dirname(file2), { recursive: true });
36143
36176
  const fd = fs2.openSync(file2, flags, mode);
36144
36177
  fileOpened(null, fd);
36145
36178
  } catch (err) {
@@ -36147,7 +36180,7 @@ var require_sonic_boom = __commonJS((exports, module) => {
36147
36180
  throw err;
36148
36181
  }
36149
36182
  } else if (sonic.mkdir) {
36150
- fs2.mkdir(path3.dirname(file2), { recursive: true }, (err) => {
36183
+ fs2.mkdir(path4.dirname(file2), { recursive: true }, (err) => {
36151
36184
  if (err)
36152
36185
  return fileOpened(err);
36153
36186
  fs2.open(file2, flags, mode, fileOpened);
@@ -36877,7 +36910,7 @@ var require_thread_stream = __commonJS((exports, module) => {
36877
36910
  var { version: version2 } = require_package();
36878
36911
  var { EventEmitter } = __require("events");
36879
36912
  var { Worker } = __require("worker_threads");
36880
- var { join: join11 } = __require("path");
36913
+ var { join: join13 } = __require("path");
36881
36914
  var { pathToFileURL } = __require("url");
36882
36915
  var { wait } = require_wait();
36883
36916
  var {
@@ -36913,7 +36946,7 @@ var require_thread_stream = __commonJS((exports, module) => {
36913
36946
  function createWorker(stream, opts) {
36914
36947
  const { filename, workerData } = opts;
36915
36948
  const bundlerOverrides = "__bundlerPathsOverrides" in globalThis ? globalThis.__bundlerPathsOverrides : {};
36916
- const toExecute = bundlerOverrides["thread-stream-worker"] || join11(__dirname, "lib", "worker.js");
36949
+ const toExecute = bundlerOverrides["thread-stream-worker"] || join13(__dirname, "lib", "worker.js");
36917
36950
  const worker = new Worker(toExecute, {
36918
36951
  ...opts.workerOpts,
36919
36952
  trackUnmanagedFds: false,
@@ -37297,7 +37330,7 @@ var require_transport = __commonJS((exports, module) => {
37297
37330
  var __dirname = "/home/runner/work/swarm-tools/swarm-tools/node_modules/.bun/pino@9.14.0/node_modules/pino/lib";
37298
37331
  var { createRequire: createRequire2 } = __require("module");
37299
37332
  var getCallers = require_caller();
37300
- var { join: join11, isAbsolute: isAbsolute2, sep: sep3 } = __require("node:path");
37333
+ var { join: join13, isAbsolute: isAbsolute2, sep: sep3 } = __require("node:path");
37301
37334
  var sleep5 = require_atomic_sleep();
37302
37335
  var onExit4 = require_on_exit_leak_free();
37303
37336
  var ThreadStream = require_thread_stream();
@@ -37360,7 +37393,7 @@ var require_transport = __commonJS((exports, module) => {
37360
37393
  throw new Error("only one of target or targets can be specified");
37361
37394
  }
37362
37395
  if (targets) {
37363
- target = bundlerOverrides["pino-worker"] || join11(__dirname, "worker.js");
37396
+ target = bundlerOverrides["pino-worker"] || join13(__dirname, "worker.js");
37364
37397
  options2.targets = targets.filter((dest) => dest.target).map((dest) => {
37365
37398
  return {
37366
37399
  ...dest,
@@ -37377,7 +37410,7 @@ var require_transport = __commonJS((exports, module) => {
37377
37410
  });
37378
37411
  });
37379
37412
  } else if (pipeline) {
37380
- target = bundlerOverrides["pino-worker"] || join11(__dirname, "worker.js");
37413
+ target = bundlerOverrides["pino-worker"] || join13(__dirname, "worker.js");
37381
37414
  options2.pipelines = [pipeline.map((dest) => {
37382
37415
  return {
37383
37416
  ...dest,
@@ -37399,7 +37432,7 @@ var require_transport = __commonJS((exports, module) => {
37399
37432
  return origin;
37400
37433
  }
37401
37434
  if (origin === "pino/file") {
37402
- return join11(__dirname, "..", "file.js");
37435
+ return join13(__dirname, "..", "file.js");
37403
37436
  }
37404
37437
  let fixTarget2;
37405
37438
  for (const filePath of callers) {
@@ -38337,7 +38370,7 @@ var require_safe_stable_stringify = __commonJS((exports, module) => {
38337
38370
  return circularValue;
38338
38371
  }
38339
38372
  let res = "";
38340
- let join11 = ",";
38373
+ let join13 = ",";
38341
38374
  const originalIndentation = indentation;
38342
38375
  if (Array.isArray(value)) {
38343
38376
  if (value.length === 0) {
@@ -38351,7 +38384,7 @@ var require_safe_stable_stringify = __commonJS((exports, module) => {
38351
38384
  indentation += spacer;
38352
38385
  res += `
38353
38386
  ${indentation}`;
38354
- join11 = `,
38387
+ join13 = `,
38355
38388
  ${indentation}`;
38356
38389
  }
38357
38390
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
@@ -38359,13 +38392,13 @@ ${indentation}`;
38359
38392
  for (;i < maximumValuesToStringify - 1; i++) {
38360
38393
  const tmp2 = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
38361
38394
  res += tmp2 !== undefined ? tmp2 : "null";
38362
- res += join11;
38395
+ res += join13;
38363
38396
  }
38364
38397
  const tmp = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
38365
38398
  res += tmp !== undefined ? tmp : "null";
38366
38399
  if (value.length - 1 > maximumBreadth) {
38367
38400
  const removedKeys = value.length - maximumBreadth - 1;
38368
- res += `${join11}"... ${getItemCount(removedKeys)} not stringified"`;
38401
+ res += `${join13}"... ${getItemCount(removedKeys)} not stringified"`;
38369
38402
  }
38370
38403
  if (spacer !== "") {
38371
38404
  res += `
@@ -38386,7 +38419,7 @@ ${originalIndentation}`;
38386
38419
  let separator = "";
38387
38420
  if (spacer !== "") {
38388
38421
  indentation += spacer;
38389
- join11 = `,
38422
+ join13 = `,
38390
38423
  ${indentation}`;
38391
38424
  whitespace = " ";
38392
38425
  }
@@ -38400,13 +38433,13 @@ ${indentation}`;
38400
38433
  const tmp = stringifyFnReplacer(key2, value, stack, replacer, spacer, indentation);
38401
38434
  if (tmp !== undefined) {
38402
38435
  res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
38403
- separator = join11;
38436
+ separator = join13;
38404
38437
  }
38405
38438
  }
38406
38439
  if (keyLength > maximumBreadth) {
38407
38440
  const removedKeys = keyLength - maximumBreadth;
38408
38441
  res += `${separator}"...":${whitespace}"${getItemCount(removedKeys)} not stringified"`;
38409
- separator = join11;
38442
+ separator = join13;
38410
38443
  }
38411
38444
  if (spacer !== "" && separator.length > 1) {
38412
38445
  res = `
@@ -38446,7 +38479,7 @@ ${originalIndentation}`;
38446
38479
  }
38447
38480
  const originalIndentation = indentation;
38448
38481
  let res = "";
38449
- let join11 = ",";
38482
+ let join13 = ",";
38450
38483
  if (Array.isArray(value)) {
38451
38484
  if (value.length === 0) {
38452
38485
  return "[]";
@@ -38459,7 +38492,7 @@ ${originalIndentation}`;
38459
38492
  indentation += spacer;
38460
38493
  res += `
38461
38494
  ${indentation}`;
38462
- join11 = `,
38495
+ join13 = `,
38463
38496
  ${indentation}`;
38464
38497
  }
38465
38498
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
@@ -38467,13 +38500,13 @@ ${indentation}`;
38467
38500
  for (;i < maximumValuesToStringify - 1; i++) {
38468
38501
  const tmp2 = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
38469
38502
  res += tmp2 !== undefined ? tmp2 : "null";
38470
- res += join11;
38503
+ res += join13;
38471
38504
  }
38472
38505
  const tmp = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
38473
38506
  res += tmp !== undefined ? tmp : "null";
38474
38507
  if (value.length - 1 > maximumBreadth) {
38475
38508
  const removedKeys = value.length - maximumBreadth - 1;
38476
- res += `${join11}"... ${getItemCount(removedKeys)} not stringified"`;
38509
+ res += `${join13}"... ${getItemCount(removedKeys)} not stringified"`;
38477
38510
  }
38478
38511
  if (spacer !== "") {
38479
38512
  res += `
@@ -38486,7 +38519,7 @@ ${originalIndentation}`;
38486
38519
  let whitespace = "";
38487
38520
  if (spacer !== "") {
38488
38521
  indentation += spacer;
38489
- join11 = `,
38522
+ join13 = `,
38490
38523
  ${indentation}`;
38491
38524
  whitespace = " ";
38492
38525
  }
@@ -38495,7 +38528,7 @@ ${indentation}`;
38495
38528
  const tmp = stringifyArrayReplacer(key2, value[key2], stack, replacer, spacer, indentation);
38496
38529
  if (tmp !== undefined) {
38497
38530
  res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
38498
- separator = join11;
38531
+ separator = join13;
38499
38532
  }
38500
38533
  }
38501
38534
  if (spacer !== "" && separator.length > 1) {
@@ -38552,20 +38585,20 @@ ${originalIndentation}`;
38552
38585
  indentation += spacer;
38553
38586
  let res2 = `
38554
38587
  ${indentation}`;
38555
- const join12 = `,
38588
+ const join14 = `,
38556
38589
  ${indentation}`;
38557
38590
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
38558
38591
  let i = 0;
38559
38592
  for (;i < maximumValuesToStringify - 1; i++) {
38560
38593
  const tmp2 = stringifyIndent(String(i), value[i], stack, spacer, indentation);
38561
38594
  res2 += tmp2 !== undefined ? tmp2 : "null";
38562
- res2 += join12;
38595
+ res2 += join14;
38563
38596
  }
38564
38597
  const tmp = stringifyIndent(String(i), value[i], stack, spacer, indentation);
38565
38598
  res2 += tmp !== undefined ? tmp : "null";
38566
38599
  if (value.length - 1 > maximumBreadth) {
38567
38600
  const removedKeys = value.length - maximumBreadth - 1;
38568
- res2 += `${join12}"... ${getItemCount(removedKeys)} not stringified"`;
38601
+ res2 += `${join14}"... ${getItemCount(removedKeys)} not stringified"`;
38569
38602
  }
38570
38603
  res2 += `
38571
38604
  ${originalIndentation}`;
@@ -38581,16 +38614,16 @@ ${originalIndentation}`;
38581
38614
  return '"[Object]"';
38582
38615
  }
38583
38616
  indentation += spacer;
38584
- const join11 = `,
38617
+ const join13 = `,
38585
38618
  ${indentation}`;
38586
38619
  let res = "";
38587
38620
  let separator = "";
38588
38621
  let maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
38589
38622
  if (isTypedArrayWithEntries(value)) {
38590
- res += stringifyTypedArray(value, join11, maximumBreadth);
38623
+ res += stringifyTypedArray(value, join13, maximumBreadth);
38591
38624
  keys3 = keys3.slice(value.length);
38592
38625
  maximumPropertiesToStringify -= value.length;
38593
- separator = join11;
38626
+ separator = join13;
38594
38627
  }
38595
38628
  if (deterministic) {
38596
38629
  keys3 = sort2(keys3, comparator);
@@ -38601,13 +38634,13 @@ ${indentation}`;
38601
38634
  const tmp = stringifyIndent(key2, value[key2], stack, spacer, indentation);
38602
38635
  if (tmp !== undefined) {
38603
38636
  res += `${separator}${strEscape(key2)}: ${tmp}`;
38604
- separator = join11;
38637
+ separator = join13;
38605
38638
  }
38606
38639
  }
38607
38640
  if (keyLength > maximumBreadth) {
38608
38641
  const removedKeys = keyLength - maximumBreadth;
38609
38642
  res += `${separator}"...": "${getItemCount(removedKeys)} not stringified"`;
38610
- separator = join11;
38643
+ separator = join13;
38611
38644
  }
38612
38645
  if (separator !== "") {
38613
38646
  res = `
@@ -38919,7 +38952,7 @@ var require_multistream = __commonJS((exports, module) => {
38919
38952
 
38920
38953
  // ../../node_modules/.bun/pino@9.14.0/node_modules/pino/pino.js
38921
38954
  var require_pino = __commonJS((exports, module) => {
38922
- var os2 = __require("node:os");
38955
+ var os3 = __require("node:os");
38923
38956
  var stdSerializers = require_pino_std_serializers();
38924
38957
  var caller = require_caller();
38925
38958
  var redaction = require_redaction();
@@ -38966,7 +38999,7 @@ var require_pino = __commonJS((exports, module) => {
38966
38999
  } = symbols;
38967
39000
  var { epochTime, nullTime } = time3;
38968
39001
  var { pid } = process;
38969
- var hostname3 = os2.hostname();
39002
+ var hostname3 = os3.hostname();
38970
39003
  var defaultErrorSerializer = stdSerializers.err;
38971
39004
  var defaultOptions = {
38972
39005
  level: "info",
@@ -39132,7 +39165,7 @@ import {
39132
39165
  FlushManager,
39133
39166
  importFromJSONL,
39134
39167
  syncMemories,
39135
- getSwarmMailLibSQL,
39168
+ getSwarmMailLibSQL as getSwarmMailLibSQL2,
39136
39169
  resolvePartialId,
39137
39170
  findCellsByPartialId
39138
39171
  } from "swarm-mail";
@@ -39783,7 +39816,7 @@ async function getHiveAdapter(projectKey) {
39783
39816
  if (adapterCache.has(projectKey)) {
39784
39817
  return adapterCache.get(projectKey);
39785
39818
  }
39786
- const swarmMail = await getSwarmMailLibSQL(projectKey);
39819
+ const swarmMail = await getSwarmMailLibSQL2(projectKey);
39787
39820
  const db = await swarmMail.getDatabase();
39788
39821
  const adapter = createHiveAdapter(db, projectKey);
39789
39822
  await adapter.runMigrations();
@@ -40411,7 +40444,7 @@ var hive_sync = tool({
40411
40444
  outputPath: `${projectKey}/.hive/issues.jsonl`
40412
40445
  });
40413
40446
  const flushResult = await withTimeout(flushManager.flush(), TIMEOUT_MS, "flush hive");
40414
- const swarmMail = await getSwarmMailLibSQL(projectKey);
40447
+ const swarmMail = await getSwarmMailLibSQL2(projectKey);
40415
40448
  const db = await swarmMail.getDatabase();
40416
40449
  const hivePath = join2(projectKey, ".hive");
40417
40450
  let memoriesSynced = 0;
@@ -40706,6 +40739,62 @@ var toolCheckers = {
40706
40739
  };
40707
40740
  }
40708
40741
  },
40742
+ hivemind: async () => {
40743
+ const hivemindExists = await commandExists("hivemind");
40744
+ if (hivemindExists) {
40745
+ try {
40746
+ const result = await Bun.$`hivemind stats`.quiet().nothrow();
40747
+ return {
40748
+ available: result.exitCode === 0,
40749
+ checkedAt: new Date().toISOString(),
40750
+ version: "native"
40751
+ };
40752
+ } catch (e) {
40753
+ return {
40754
+ available: false,
40755
+ checkedAt: new Date().toISOString(),
40756
+ error: String(e)
40757
+ };
40758
+ }
40759
+ }
40760
+ const semanticMemoryExists = await commandExists("semantic-memory");
40761
+ if (semanticMemoryExists) {
40762
+ try {
40763
+ const result = await Bun.$`semantic-memory stats`.quiet().nothrow();
40764
+ return {
40765
+ available: result.exitCode === 0,
40766
+ checkedAt: new Date().toISOString(),
40767
+ version: "semantic-memory-backend"
40768
+ };
40769
+ } catch (e) {
40770
+ return {
40771
+ available: false,
40772
+ checkedAt: new Date().toISOString(),
40773
+ error: String(e)
40774
+ };
40775
+ }
40776
+ }
40777
+ try {
40778
+ const proc = Bun.spawn(["bunx", "semantic-memory", "stats"], {
40779
+ stdout: "pipe",
40780
+ stderr: "pipe"
40781
+ });
40782
+ const timeout = setTimeout(() => proc.kill(), BUNX_TIMEOUT_MS);
40783
+ const exitCode = await proc.exited;
40784
+ clearTimeout(timeout);
40785
+ return {
40786
+ available: exitCode === 0,
40787
+ checkedAt: new Date().toISOString(),
40788
+ version: "bunx-semantic-memory"
40789
+ };
40790
+ } catch (e) {
40791
+ return {
40792
+ available: false,
40793
+ checkedAt: new Date().toISOString(),
40794
+ error: String(e)
40795
+ };
40796
+ }
40797
+ },
40709
40798
  ubs: async () => {
40710
40799
  const exists = await commandExists("ubs");
40711
40800
  if (!exists) {
@@ -40788,6 +40877,7 @@ var toolCheckers = {
40788
40877
  var fallbackBehaviors = {
40789
40878
  "semantic-memory": "Learning data stored in-memory only (lost on session end)",
40790
40879
  cass: "Decomposition proceeds without historical context from past sessions",
40880
+ hivemind: "Unified memory unavailable - learnings stored in-memory only, no session history search",
40791
40881
  ubs: "Subtask completion skips bug scanning - manual review recommended",
40792
40882
  hive: "Swarm cannot track issues - task coordination will be less reliable",
40793
40883
  beads: "DEPRECATED: Use hive instead. Swarm cannot track issues - task coordination will be less reliable",
@@ -40820,6 +40910,7 @@ async function checkAllTools() {
40820
40910
  const tools = [
40821
40911
  "semantic-memory",
40822
40912
  "cass",
40913
+ "hivemind",
40823
40914
  "ubs",
40824
40915
  "hive",
40825
40916
  "beads",
@@ -43390,7 +43481,7 @@ Now generate the CellTree for the given task.`;
43390
43481
  ${subagentInstructions}`;
43391
43482
  return JSON.stringify({
43392
43483
  prompt: fullPrompt,
43393
- subagent_type: "swarm/planner",
43484
+ subagent_type: "swarm-planner",
43394
43485
  description: "Task decomposition planning",
43395
43486
  strategy: {
43396
43487
  selected: selectedStrategy,
@@ -45076,7 +45167,7 @@ import {
45076
45167
  getAgent,
45077
45168
  createEvent as createEvent3,
45078
45169
  appendEvent as appendEvent2,
45079
- getSwarmMailLibSQL as getSwarmMailLibSQL3
45170
+ getSwarmMailLibSQL as getSwarmMailLibSQL4
45080
45171
  } from "swarm-mail";
45081
45172
  init_skills();
45082
45173
 
@@ -46107,7 +46198,7 @@ var swarm_init = tool({
46107
46198
  if (!availability.get("ubs")?.status.available) {
46108
46199
  degradedFeatures.push("pre-completion bug scanning");
46109
46200
  }
46110
- if (!availability.get("semantic-memory")?.status.available) {
46201
+ if (!availability.get("hivemind")?.status.available) {
46111
46202
  degradedFeatures.push("persistent learning (using in-memory fallback)");
46112
46203
  }
46113
46204
  const availableSkills = await listSkills();
@@ -46560,7 +46651,7 @@ This will be recorded as a negative learning signal.`;
46560
46651
  let deferredResolved = false;
46561
46652
  let deferredError;
46562
46653
  try {
46563
- const swarmMail = await getSwarmMailLibSQL3(args.project_key);
46654
+ const swarmMail = await getSwarmMailLibSQL4(args.project_key);
46564
46655
  const db = await swarmMail.getDatabase();
46565
46656
  const deferredUrl = `deferred:${args.bead_id}`;
46566
46657
  const checkResult = await db.query(`SELECT url, resolved FROM deferred WHERE url = ? AND resolved = 0`, [deferredUrl]);
@@ -46628,18 +46719,18 @@ This will be recorded as a negative learning signal.`;
46628
46719
  let memoryStored = false;
46629
46720
  let memoryError;
46630
46721
  try {
46631
- const memoryAvailable = await isToolAvailable("semantic-memory");
46722
+ const memoryAvailable = await isToolAvailable("hivemind");
46632
46723
  if (memoryAvailable) {
46633
- const storeResult = await Bun.$`semantic-memory store ${memoryInfo.information} --metadata ${memoryInfo.metadata}`.quiet().nothrow();
46724
+ const storeResult = await Bun.$`hivemind store ${memoryInfo.information} --metadata ${memoryInfo.metadata}`.quiet().nothrow();
46634
46725
  if (storeResult.exitCode === 0) {
46635
46726
  memoryStored = true;
46636
46727
  } else {
46637
- memoryError = `semantic-memory store failed: ${storeResult.stderr.toString().slice(0, 200)}`;
46728
+ memoryError = `hivemind store failed: ${storeResult.stderr.toString().slice(0, 200)}`;
46638
46729
  console.warn(`[swarm_complete] ${memoryError}`);
46639
46730
  }
46640
46731
  } else {
46641
- memoryError = "semantic-memory not available - learning stored in-memory only";
46642
- warnMissingTool("semantic-memory");
46732
+ memoryError = "hivemind not available - learning stored in-memory only";
46733
+ warnMissingTool("hivemind");
46643
46734
  }
46644
46735
  } catch (error45) {
46645
46736
  memoryError = `Failed to store memory: ${error45 instanceof Error ? error45.message : String(error45)}`;
@@ -46662,7 +46753,7 @@ This will be recorded as a negative learning signal.`;
46662
46753
  parsedEvaluation ? `**Self-Evaluation**: ${parsedEvaluation.passed ? "PASSED" : "FAILED"}` : "",
46663
46754
  parsedEvaluation?.overall_feedback ? `**Feedback**: ${parsedEvaluation.overall_feedback}` : "",
46664
46755
  "",
46665
- `**Memory Capture**: ${memoryStored ? "✓ Stored in semantic-memory" : `✗ ${memoryError || "Failed"}`}`
46756
+ `**Memory Capture**: ${memoryStored ? "✓ Stored in hivemind" : `✗ ${memoryError || "Failed"}`}`
46666
46757
  ].filter(Boolean).join(`
46667
46758
  `);
46668
46759
  let messageSent = false;
@@ -46725,7 +46816,7 @@ Files touched: ${args.files_touched?.join(", ") || "none recorded"}`,
46725
46816
  error: memoryError,
46726
46817
  information: memoryInfo.information,
46727
46818
  metadata: memoryInfo.metadata,
46728
- note: memoryStored ? "Learning automatically stored in semantic-memory" : `Failed to store: ${memoryError}. Learning lost unless semantic-memory is available.`
46819
+ note: memoryStored ? "Learning automatically stored in hivemind" : `Failed to store: ${memoryError}. Learning lost unless hivemind is available.`
46729
46820
  },
46730
46821
  contract_validation: contractValidation ? {
46731
46822
  validated: true,
@@ -47037,7 +47128,7 @@ async function runResearchPhase(task, projectPath, options2) {
47037
47128
  research_id: researchId,
47038
47129
  tech,
47039
47130
  prompt,
47040
- subagent_type: "swarm/researcher"
47131
+ subagent_type: "swarm-researcher"
47041
47132
  });
47042
47133
  }
47043
47134
  return {
@@ -47067,7 +47158,7 @@ var swarm_research_phase = tool({
47067
47158
  summaries_collected: Object.keys(result.summaries).length,
47068
47159
  memories_stored: result.memory_ids.length
47069
47160
  },
47070
- usage_hint: "Inject summaries into shared_context for task decomposition. Each technology has documentation in semantic-memory."
47161
+ usage_hint: "Inject summaries into shared_context for task decomposition. Each technology has documentation in hivemind."
47071
47162
  }, null, 2);
47072
47163
  }
47073
47164
  });
@@ -47283,8 +47374,8 @@ var swarm_recover = tool({
47283
47374
  },
47284
47375
  async execute(args) {
47285
47376
  try {
47286
- const { getSwarmMailLibSQL: getSwarmMailLibSQL4 } = await import("swarm-mail");
47287
- const swarmMail = await getSwarmMailLibSQL4(args.project_key);
47377
+ const { getSwarmMailLibSQL: getSwarmMailLibSQL5 } = await import("swarm-mail");
47378
+ const swarmMail = await getSwarmMailLibSQL5(args.project_key);
47288
47379
  const db = await swarmMail.getDatabase();
47289
47380
  const result = await db.query(`SELECT * FROM swarm_contexts
47290
47381
  WHERE epic_id = $1
@@ -47486,7 +47577,7 @@ init_eval_capture();
47486
47577
 
47487
47578
  // src/memory-tools.ts
47488
47579
  init_dist();
47489
- import { getSwarmMailLibSQL as getSwarmMailLibSQL4, createEvent as createEvent4, appendEvent as appendEvent3 } from "swarm-mail";
47580
+ import { getSwarmMailLibSQL as getSwarmMailLibSQL5, createEvent as createEvent4, appendEvent as appendEvent3 } from "swarm-mail";
47490
47581
 
47491
47582
  // ../../node_modules/.bun/effect@3.19.12/node_modules/effect/dist/esm/Function.js
47492
47583
  var isFunction = (input) => typeof input === "function";
@@ -61103,7 +61194,7 @@ async function getMemoryAdapter(projectPath) {
61103
61194
  if (cachedAdapter && cachedProjectPath === path3) {
61104
61195
  return cachedAdapter;
61105
61196
  }
61106
- const swarmMail = await getSwarmMailLibSQL4(path3);
61197
+ const swarmMail = await getSwarmMailLibSQL5(path3);
61107
61198
  const dbAdapter = await swarmMail.getDatabase();
61108
61199
  cachedAdapter = await createMemoryAdapter(dbAdapter);
61109
61200
  cachedProjectPath = path3;
@@ -61291,17 +61382,6 @@ var semantic_memory_upsert = tool({
61291
61382
  return JSON.stringify(result, null, 2);
61292
61383
  }
61293
61384
  });
61294
- var memoryTools = {
61295
- "semantic-memory_store": semantic_memory_store,
61296
- "semantic-memory_find": semantic_memory_find,
61297
- "semantic-memory_get": semantic_memory_get,
61298
- "semantic-memory_remove": semantic_memory_remove,
61299
- "semantic-memory_validate": semantic_memory_validate,
61300
- "semantic-memory_list": semantic_memory_list,
61301
- "semantic-memory_stats": semantic_memory_stats,
61302
- "semantic-memory_check": semantic_memory_check,
61303
- "semantic-memory_upsert": semantic_memory_upsert
61304
- };
61305
61385
 
61306
61386
  // src/swarm-prompts.ts
61307
61387
  var STRATEGY_DECOMPOSITION_PROMPT2 = `You are decomposing a task into parallelizable subtasks for a swarm of agents.
@@ -61485,10 +61565,10 @@ swarmmail_init(project_path="{project_path}", task_description="{bead_id}: {subt
61485
61565
 
61486
61566
  ### Step 2: \uD83E\uDDE0 Query Past Learnings (MANDATORY - BEFORE starting work)
61487
61567
 
61488
- **⚠️ CRITICAL: ALWAYS query semantic memory BEFORE writing ANY code.**
61568
+ **⚠️ CRITICAL: ALWAYS query hivemind BEFORE writing ANY code.**
61489
61569
 
61490
61570
  \`\`\`
61491
- semantic-memory_find(query="<keywords from your task>", limit=5, expand=true)
61571
+ hivemind_find(query="<keywords from your task>", limit=5, expand=true)
61492
61572
  \`\`\`
61493
61573
 
61494
61574
  **Why this is MANDATORY:**
@@ -61507,7 +61587,7 @@ semantic-memory_find(query="<keywords from your task>", limit=5, expand=true)
61507
61587
  - **Performance**: Search "<technology> performance optimization"
61508
61588
 
61509
61589
  **BEFORE you start coding:**
61510
- 1. Run semantic-memory_find with keywords from your task
61590
+ 1. Run hivemind_find with keywords from your task
61511
61591
  2. Read the results with expand=true for full content
61512
61592
  3. Check if any memory solves your problem or warns of pitfalls
61513
61593
  4. Adjust your approach based on past learnings
@@ -61603,7 +61683,7 @@ swarm_checkpoint(
61603
61683
  **If you learned it the hard way, STORE IT so the next agent doesn't have to.**
61604
61684
 
61605
61685
  \`\`\`
61606
- semantic-memory_store(
61686
+ hivemind_store(
61607
61687
  information="<what you learned, WHY it matters, how to apply it>",
61608
61688
  tags="<domain, tech-stack, pattern-type>"
61609
61689
  )
@@ -61660,12 +61740,12 @@ swarm_complete(
61660
61740
 
61661
61741
  If you encounter unknown API behavior or version-specific issues:
61662
61742
 
61663
- 1. **Check semantic-memory first:**
61664
- \`semantic-memory_find(query="<library> <version> <topic>", limit=3, expand=true)\`
61743
+ 1. **Check hivemind first:**
61744
+ \`hivemind_find(query="<library> <version> <topic>", limit=3, expand=true)\`
61665
61745
 
61666
61746
  2. **If not found, spawn researcher:**
61667
61747
  \`swarm_spawn_researcher(research_id="{bead_id}-research", epic_id="{epic_id}", tech_stack=["<library>"], project_path="{project_path}")\`
61668
- Then spawn with Task tool: \`Task(subagent_type="swarm/researcher", prompt="<from above>")\`
61748
+ Then spawn with Task tool: \`Task(subagent_type="swarm-researcher", prompt="<from above>")\`
61669
61749
 
61670
61750
  3. **Wait for research, then continue**
61671
61751
 
@@ -61749,20 +61829,20 @@ Other cell operations:
61749
61829
 
61750
61830
  **NON-NEGOTIABLE:**
61751
61831
  1. Step 1 (swarmmail_init) MUST be first - do it before anything else
61752
- 2. \uD83E\uDDE0 Step 2 (semantic-memory_find) MUST happen BEFORE starting work - query first, code second
61832
+ 2. \uD83E\uDDE0 Step 2 (hivemind_find) MUST happen BEFORE starting work - query first, code second
61753
61833
  3. Step 4 (swarmmail_reserve) - YOU reserve files, not coordinator
61754
61834
  4. Step 6 (swarm_progress) - Report at milestones, don't work silently
61755
- 5. \uD83D\uDCBE Step 8 (semantic-memory_store) - If you learned something hard, STORE IT
61835
+ 5. \uD83D\uDCBE Step 8 (hivemind_store) - If you learned something hard, STORE IT
61756
61836
  6. Step 9 (swarm_complete) - Use this to close, NOT hive_close
61757
61837
 
61758
61838
  **If you skip these steps:**
61759
61839
  - Your work won't be tracked (swarm_complete will fail)
61760
- - \uD83D\uDD04 You'll waste time repeating already-solved problems (no semantic memory query)
61840
+ - \uD83D\uDD04 You'll waste time repeating already-solved problems (no hivemind query)
61761
61841
  - Edit conflicts with other agents (no file reservation)
61762
61842
  - Lost work if you crash (no checkpoints)
61763
61843
  - \uD83D\uDD04 Future agents repeat YOUR mistakes (no learnings stored)
61764
61844
 
61765
- **Memory is the swarm's collective intelligence. Query it. Feed it.**
61845
+ **Hivemind is the swarm's collective intelligence. Query it. Feed it.**
61766
61846
 
61767
61847
  Begin now.`;
61768
61848
  var RESEARCHER_PROMPT = `You are a swarm researcher gathering documentation for: **{research_id}**
@@ -61819,9 +61899,9 @@ For EACH technology in the list:
61819
61899
  - Note breaking changes, new features, migration complexity
61820
61900
 
61821
61901
  ### Step 5: Store Detailed Findings
61822
- For EACH technology, store in semantic-memory:
61902
+ For EACH technology, store in hivemind:
61823
61903
  \`\`\`
61824
- semantic-memory_store(
61904
+ hivemind_store(
61825
61905
  information="<technology-name> <version>: <key patterns, gotchas, API changes, compatibility notes>",
61826
61906
  tags="research, <tech-name>, documentation, {epic_id}"
61827
61907
  )
@@ -61835,7 +61915,7 @@ Send condensed findings to coordinator:
61835
61915
  swarmmail_send(
61836
61916
  to=["coordinator"],
61837
61917
  subject="Research Complete: {research_id}",
61838
- body="<brief summary - see semantic-memory for details>",
61918
+ body="<brief summary - see hivemind for details>",
61839
61919
  thread_id="{epic_id}"
61840
61920
  )
61841
61921
  \`\`\`
@@ -61852,7 +61932,7 @@ Output JSON with:
61852
61932
  "key_patterns": ["string"],
61853
61933
  "gotchas": ["string"],
61854
61934
  "breaking_changes": ["string"], // Only if --check-upgrades
61855
- "memory_id": "string" // ID of semantic-memory entry
61935
+ "memory_id": "string" // ID of hivemind entry
61856
61936
  }
61857
61937
  ],
61858
61938
  "summary": "string" // Condensed summary for shared_context
@@ -61865,12 +61945,12 @@ Output JSON with:
61865
61945
  1. Step 1 (swarmmail_init) MUST be first
61866
61946
  2. Research ONLY the technologies the coordinator specified
61867
61947
  3. Fetch docs for INSTALLED versions (unless --check-upgrades)
61868
- 4. Store detailed findings in semantic-memory (one per technology)
61948
+ 4. Store detailed findings in hivemind (one per technology)
61869
61949
  5. Return condensed summary for coordinator (full details in memory)
61870
61950
  6. Use appropriate doc tools (nextjs_docs for Next.js, context7 for libraries, etc.)
61871
61951
 
61872
61952
  **Output goes TWO places:**
61873
- - **semantic-memory**: Detailed findings (searchable by future agents)
61953
+ - **hivemind**: Detailed findings (searchable by future agents)
61874
61954
  - **Return JSON**: Condensed summary (for coordinator's shared_context)
61875
61955
 
61876
61956
  Begin research now.`;
@@ -62073,7 +62153,7 @@ async function getWorkerInsights(files, domain2) {
62073
62153
  ${learnings.join(`
62074
62154
  `)}
62075
62155
 
62076
- **Check semantic-memory for full details if needed.**`;
62156
+ **Check hivemind for full details if needed.**`;
62077
62157
  }
62078
62158
  const sections = [formattedFileInsights, formattedMemory].filter((s) => s.length > 0);
62079
62159
  if (sections.length === 0) {
@@ -62303,7 +62383,7 @@ var swarm_spawn_subtask = tool({
62303
62383
  }
62304
62384
  });
62305
62385
  var swarm_spawn_researcher = tool({
62306
- description: "Prepare a research task for spawning. Returns prompt for gathering technology documentation. Researcher fetches docs and stores findings in semantic-memory.",
62386
+ description: "Prepare a research task for spawning. Returns prompt for gathering technology documentation. Researcher fetches docs and stores findings in hivemind.",
62307
62387
  args: {
62308
62388
  research_id: tool.schema.string().describe("Unique ID for this research task"),
62309
62389
  epic_id: tool.schema.string().describe("Parent epic ID"),
@@ -62326,7 +62406,7 @@ var swarm_spawn_researcher = tool({
62326
62406
  tech_stack: args2.tech_stack,
62327
62407
  project_path: args2.project_path,
62328
62408
  check_upgrades: args2.check_upgrades ?? false,
62329
- subagent_type: "swarm/researcher",
62409
+ subagent_type: "swarm-researcher",
62330
62410
  expected_output: {
62331
62411
  technologies: [
62332
62412
  {
@@ -62644,11 +62724,6 @@ var TOOL_DEFINITIONS = [
62644
62724
  name: "pdf-brain",
62645
62725
  type: "mcp",
62646
62726
  capabilities: ["knowledge-base-search", "internal-docs"]
62647
- },
62648
- {
62649
- name: "semantic-memory",
62650
- type: "cli",
62651
- capabilities: ["storage", "semantic-search", "persistence"]
62652
62727
  }
62653
62728
  ];
62654
62729
  function stripSemverConstraint(versionStr) {
@@ -63911,13 +63986,302 @@ var mandateTools = {
63911
63986
  mandate_stats
63912
63987
  };
63913
63988
 
63989
+ // src/hivemind-tools.ts
63990
+ init_dist();
63991
+ import {
63992
+ getSwarmMailLibSQL as getSwarmMailLibSQL6,
63993
+ createEvent as createEvent5,
63994
+ SessionIndexer,
63995
+ syncMemories as syncMemories2,
63996
+ toSwarmDb as toSwarmDb2,
63997
+ makeOllamaLive as makeOllamaLive2
63998
+ } from "swarm-mail";
63999
+ import * as os2 from "node:os";
64000
+ import * as path3 from "node:path";
64001
+ import { join as join12 } from "node:path";
64002
+ var cachedAdapter2 = null;
64003
+ var cachedIndexer = null;
64004
+ var cachedProjectPath2 = null;
64005
+ async function getMemoryAdapter2(projectPath) {
64006
+ const path4 = projectPath || process.cwd();
64007
+ if (cachedAdapter2 && cachedProjectPath2 === path4) {
64008
+ return cachedAdapter2;
64009
+ }
64010
+ const swarmMail = await getSwarmMailLibSQL6(path4);
64011
+ const dbAdapter = await swarmMail.getDatabase();
64012
+ cachedAdapter2 = await createMemoryAdapter(dbAdapter);
64013
+ cachedProjectPath2 = path4;
64014
+ return cachedAdapter2;
64015
+ }
64016
+ async function getSessionIndexer(projectPath) {
64017
+ const path4 = projectPath || process.cwd();
64018
+ if (cachedIndexer && cachedProjectPath2 === path4) {
64019
+ return cachedIndexer;
64020
+ }
64021
+ const swarmMail = await getSwarmMailLibSQL6(path4);
64022
+ const dbAdapter = await swarmMail.getDatabase();
64023
+ const db = toSwarmDb2(dbAdapter);
64024
+ const ollamaLayer = makeOllamaLive2({
64025
+ ollamaHost: process.env.OLLAMA_HOST || "http://localhost:11434",
64026
+ ollamaModel: process.env.OLLAMA_MODEL || "mxbai-embed-large"
64027
+ });
64028
+ cachedIndexer = new SessionIndexer(db, ollamaLayer);
64029
+ cachedProjectPath2 = path4;
64030
+ return cachedIndexer;
64031
+ }
64032
+ var getHivemindAdapter = getMemoryAdapter2;
64033
+ async function emitEvent(eventType, data) {
64034
+ try {
64035
+ const projectPath = cachedProjectPath2 || process.cwd();
64036
+ const swarmMail = await getSwarmMailLibSQL6(projectPath);
64037
+ const event = createEvent5(eventType, {
64038
+ project_key: projectPath,
64039
+ ...data
64040
+ });
64041
+ await swarmMail.appendEvent(event);
64042
+ } catch {}
64043
+ }
64044
+ var AGENT_DIRECTORIES = [
64045
+ path3.join(os2.homedir(), ".config", "swarm-tools", "sessions"),
64046
+ path3.join(os2.homedir(), ".opencode"),
64047
+ path3.join(os2.homedir(), "Cursor", "User", "History"),
64048
+ path3.join(os2.homedir(), ".local", "share", "Claude"),
64049
+ path3.join(os2.homedir(), ".aider")
64050
+ ];
64051
+ var hivemind_store = tool({
64052
+ description: "Store a memory (learning, decision, pattern) with semantic embedding. Memories are searchable by semantic similarity and organized into collections. Use collection='default' for manual learnings.",
64053
+ args: {
64054
+ information: tool.schema.string().describe("The information to store (required)"),
64055
+ collection: tool.schema.string().optional().describe("Collection name (defaults to 'default')"),
64056
+ tags: tool.schema.string().optional().describe("Comma-separated tags (e.g., 'auth,tokens,oauth')"),
64057
+ metadata: tool.schema.string().optional().describe("JSON string with additional metadata"),
64058
+ confidence: tool.schema.number().optional().describe("Confidence level (0.0-1.0) affecting decay rate. Default 0.7"),
64059
+ autoTag: tool.schema.boolean().optional().describe("Auto-generate tags using LLM. Default false"),
64060
+ autoLink: tool.schema.boolean().optional().describe("Auto-link to related memories. Default false"),
64061
+ extractEntities: tool.schema.boolean().optional().describe("Extract entities (people, places, technologies). Default false")
64062
+ },
64063
+ async execute(args2, ctx) {
64064
+ const adapter = await getMemoryAdapter2();
64065
+ const result = await adapter.store(args2);
64066
+ await emitEvent("memory_stored", {
64067
+ memory_id: result.id,
64068
+ content_preview: args2.information.slice(0, 100),
64069
+ tags: args2.tags ? args2.tags.split(",").map((t) => t.trim()) : [],
64070
+ collection: args2.collection || "default"
64071
+ });
64072
+ return JSON.stringify(result, null, 2);
64073
+ }
64074
+ });
64075
+ var hivemind_find = tool({
64076
+ description: "Search all memories (manual learnings + AI session history) by semantic similarity or full-text search. Filter by collection to search specific sources (e.g., collection='claude' for Claude sessions, collection='default' for learnings).",
64077
+ args: {
64078
+ query: tool.schema.string().describe("Search query (required)"),
64079
+ limit: tool.schema.number().optional().describe("Maximum number of results (default: 10)"),
64080
+ collection: tool.schema.string().optional().describe("Filter by collection (e.g., 'default', 'claude', 'cursor')"),
64081
+ expand: tool.schema.boolean().optional().describe("Return full content instead of truncated preview (default: false)"),
64082
+ fts: tool.schema.boolean().optional().describe("Use full-text search instead of vector search (default: false)")
64083
+ },
64084
+ async execute(args2, ctx) {
64085
+ const startTime = Date.now();
64086
+ const adapter = await getMemoryAdapter2();
64087
+ const result = await adapter.find(args2);
64088
+ const duration3 = Date.now() - startTime;
64089
+ await emitEvent("memory_found", {
64090
+ query: args2.query,
64091
+ result_count: result.results.length,
64092
+ top_score: result.results.length > 0 ? result.results[0].score : undefined,
64093
+ search_duration_ms: duration3,
64094
+ collection_filter: args2.collection
64095
+ });
64096
+ return JSON.stringify(result, null, 2);
64097
+ }
64098
+ });
64099
+ var hivemind_get = tool({
64100
+ description: "Retrieve a specific memory by its ID. Works for both learnings and session memories.",
64101
+ args: {
64102
+ id: tool.schema.string().describe("Memory ID (required)")
64103
+ },
64104
+ async execute(args2, ctx) {
64105
+ const adapter = await getMemoryAdapter2();
64106
+ const memory = await adapter.get(args2);
64107
+ return memory ? JSON.stringify(memory, null, 2) : "Memory not found";
64108
+ }
64109
+ });
64110
+ var hivemind_remove = tool({
64111
+ description: "Delete a memory by ID. Use this to remove outdated or incorrect memories.",
64112
+ args: {
64113
+ id: tool.schema.string().describe("Memory ID (required)")
64114
+ },
64115
+ async execute(args2, ctx) {
64116
+ const adapter = await getMemoryAdapter2();
64117
+ const result = await adapter.remove(args2);
64118
+ if (result.success) {
64119
+ await emitEvent("memory_deleted", {
64120
+ memory_id: args2.id
64121
+ });
64122
+ }
64123
+ return JSON.stringify(result, null, 2);
64124
+ }
64125
+ });
64126
+ var hivemind_validate = tool({
64127
+ description: "Validate that a memory is still accurate and reset its decay timer (90-day half-life). Use when you confirm a memory is correct.",
64128
+ args: {
64129
+ id: tool.schema.string().describe("Memory ID (required)")
64130
+ },
64131
+ async execute(args2, ctx) {
64132
+ const adapter = await getMemoryAdapter2();
64133
+ const result = await adapter.validate(args2);
64134
+ if (result.success) {
64135
+ await emitEvent("memory_validated", {
64136
+ memory_id: args2.id,
64137
+ decay_reset: true
64138
+ });
64139
+ }
64140
+ return JSON.stringify(result, null, 2);
64141
+ }
64142
+ });
64143
+ var hivemind_stats = tool({
64144
+ description: "Get statistics about stored memories, embeddings, and system health. Shows counts by collection (learnings vs sessions) and Ollama availability.",
64145
+ args: {},
64146
+ async execute(args2, ctx) {
64147
+ const adapter = await getMemoryAdapter2();
64148
+ const stats = await adapter.stats();
64149
+ const health = await adapter.checkHealth();
64150
+ let sessionStats = {};
64151
+ try {
64152
+ const indexer = await getSessionIndexer();
64153
+ sessionStats = await exports_Effect.runPromise(indexer.getStats());
64154
+ } catch {}
64155
+ return JSON.stringify({
64156
+ ...stats,
64157
+ healthy: health.ollama,
64158
+ ollama_available: health.ollama,
64159
+ sessions: sessionStats
64160
+ }, null, 2);
64161
+ }
64162
+ });
64163
+ var hivemind_index = tool({
64164
+ description: "Index AI coding agent session directories (Claude, Cursor, OpenCode, etc.) for searchable history. Run this to pick up new sessions or rebuild the index.",
64165
+ args: {
64166
+ full: tool.schema.boolean().optional().describe("Force full rebuild (default: incremental)")
64167
+ },
64168
+ async execute(args2, ctx) {
64169
+ const startTime = Date.now();
64170
+ try {
64171
+ const indexer = await getSessionIndexer();
64172
+ const allResults = [];
64173
+ for (const dir of AGENT_DIRECTORIES) {
64174
+ try {
64175
+ const options2 = {
64176
+ recursive: true
64177
+ };
64178
+ const results = await exports_Effect.runPromise(indexer.indexDirectory(dir, options2).pipe(exports_Effect.catchAll((error45) => {
64179
+ return exports_Effect.succeed([]);
64180
+ })));
64181
+ allResults.push(...results);
64182
+ } catch {}
64183
+ }
64184
+ const totalIndexed = allResults.reduce((sum2, r) => sum2 + r.indexed, 0);
64185
+ const totalSkipped = allResults.reduce((sum2, r) => sum2 + r.skipped, 0);
64186
+ await emitEvent("sessions_indexed", {
64187
+ sessions_indexed: allResults.length,
64188
+ messages_indexed: totalIndexed,
64189
+ duration_ms: Date.now() - startTime,
64190
+ full_rebuild: args2.full ?? false
64191
+ });
64192
+ return `Indexed ${allResults.length} sessions with ${totalIndexed} chunks (${totalSkipped} skipped) in ${Date.now() - startTime}ms`;
64193
+ } catch (error45) {
64194
+ return JSON.stringify({
64195
+ error: error45 instanceof Error ? error45.message : String(error45)
64196
+ });
64197
+ }
64198
+ }
64199
+ });
64200
+ var hivemind_sync = tool({
64201
+ description: "Sync memories to .hive/memories.jsonl for git-based sharing. Team members can sync their local databases from the JSONL file.",
64202
+ args: {},
64203
+ async execute(args2, ctx) {
64204
+ try {
64205
+ const projectPath = cachedProjectPath2 || process.cwd();
64206
+ const swarmMail = await getSwarmMailLibSQL6(projectPath);
64207
+ const dbAdapter = await swarmMail.getDatabase();
64208
+ const hiveDir = join12(projectPath, ".hive");
64209
+ const result = await syncMemories2(dbAdapter, hiveDir);
64210
+ await emitEvent("memories_synced", {
64211
+ imported: result.imported.created,
64212
+ exported: result.exported
64213
+ });
64214
+ return JSON.stringify({
64215
+ success: true,
64216
+ imported: result.imported.created,
64217
+ exported: result.exported,
64218
+ message: `Synced: imported ${result.imported.created}, exported ${result.exported} memories`
64219
+ }, null, 2);
64220
+ } catch (error45) {
64221
+ return JSON.stringify({
64222
+ success: false,
64223
+ error: error45 instanceof Error ? error45.message : String(error45)
64224
+ });
64225
+ }
64226
+ }
64227
+ });
64228
+ function createDeprecatedAlias(newToolName, oldToolName, tool3) {
64229
+ return {
64230
+ ...tool3,
64231
+ execute: async (args2, ctx) => {
64232
+ console.warn(`[DEPRECATED] ${oldToolName} is deprecated. Use ${newToolName} instead.`);
64233
+ return tool3.execute(args2, ctx);
64234
+ }
64235
+ };
64236
+ }
64237
+ var semantic_memory_store2 = createDeprecatedAlias("hivemind_store", "semantic-memory_store", hivemind_store);
64238
+ var semantic_memory_find2 = createDeprecatedAlias("hivemind_find", "semantic-memory_find", hivemind_find);
64239
+ var semantic_memory_get2 = createDeprecatedAlias("hivemind_get", "semantic-memory_get", hivemind_get);
64240
+ var semantic_memory_remove2 = createDeprecatedAlias("hivemind_remove", "semantic-memory_remove", hivemind_remove);
64241
+ var semantic_memory_validate2 = createDeprecatedAlias("hivemind_validate", "semantic-memory_validate", hivemind_validate);
64242
+ var semantic_memory_list2 = createDeprecatedAlias("hivemind_find", "semantic-memory_list", hivemind_find);
64243
+ var semantic_memory_stats2 = createDeprecatedAlias("hivemind_stats", "semantic-memory_stats", hivemind_stats);
64244
+ var semantic_memory_check2 = createDeprecatedAlias("hivemind_stats", "semantic-memory_check", hivemind_stats);
64245
+ var semantic_memory_upsert2 = createDeprecatedAlias("hivemind_store", "semantic-memory_upsert", hivemind_store);
64246
+ var cass_search = createDeprecatedAlias("hivemind_find", "cass_search", hivemind_find);
64247
+ var cass_view = createDeprecatedAlias("hivemind_get", "cass_view", hivemind_get);
64248
+ var cass_expand = createDeprecatedAlias("hivemind_get", "cass_expand", hivemind_get);
64249
+ var cass_health = createDeprecatedAlias("hivemind_stats", "cass_health", hivemind_stats);
64250
+ var cass_index = createDeprecatedAlias("hivemind_index", "cass_index", hivemind_index);
64251
+ var cass_stats = createDeprecatedAlias("hivemind_stats", "cass_stats", hivemind_stats);
64252
+ var hivemindTools = {
64253
+ hivemind_store,
64254
+ hivemind_find,
64255
+ hivemind_get,
64256
+ hivemind_remove,
64257
+ hivemind_validate,
64258
+ hivemind_stats,
64259
+ hivemind_index,
64260
+ hivemind_sync,
64261
+ "semantic-memory_store": semantic_memory_store2,
64262
+ "semantic-memory_find": semantic_memory_find2,
64263
+ "semantic-memory_get": semantic_memory_get2,
64264
+ "semantic-memory_remove": semantic_memory_remove2,
64265
+ "semantic-memory_validate": semantic_memory_validate2,
64266
+ "semantic-memory_list": semantic_memory_list2,
64267
+ "semantic-memory_stats": semantic_memory_stats2,
64268
+ "semantic-memory_check": semantic_memory_check2,
64269
+ "semantic-memory_upsert": semantic_memory_upsert2,
64270
+ cass_search,
64271
+ cass_view,
64272
+ cass_expand,
64273
+ cass_health,
64274
+ cass_index,
64275
+ cass_stats
64276
+ };
64277
+
63914
64278
  // src/observability-tools.ts
63915
64279
  init_dist();
63916
64280
  import {
63917
64281
  agentActivity,
63918
64282
  checkpointFrequency,
63919
64283
  failedDecompositions,
63920
- getSwarmMailLibSQL as getSwarmMailLibSQL5,
64284
+ getSwarmMailLibSQL as getSwarmMailLibSQL7,
63921
64285
  humanFeedback,
63922
64286
  lockContention,
63923
64287
  messageLatency,
@@ -63982,7 +64346,7 @@ var swarm_analytics = tool({
63982
64346
  async execute(args2) {
63983
64347
  try {
63984
64348
  const projectPath = process.cwd();
63985
- const db = await getSwarmMailLibSQL5(projectPath);
64349
+ const db = await getSwarmMailLibSQL7(projectPath);
63986
64350
  const filters = {
63987
64351
  project_key: projectPath
63988
64352
  };
@@ -64052,7 +64416,7 @@ var swarm_query = tool({
64052
64416
  async execute(args2) {
64053
64417
  try {
64054
64418
  const projectPath = process.cwd();
64055
- const swarmMail = await getSwarmMailLibSQL5(projectPath);
64419
+ const swarmMail = await getSwarmMailLibSQL7(projectPath);
64056
64420
  const db = await swarmMail.getDatabase();
64057
64421
  if (!args2.sql.trim().toLowerCase().startsWith("select")) {
64058
64422
  return JSON.stringify({
@@ -64102,7 +64466,7 @@ var swarm_diagnose = tool({
64102
64466
  async execute(args2) {
64103
64467
  try {
64104
64468
  const projectPath = process.cwd();
64105
- const swarmMail = await getSwarmMailLibSQL5(projectPath);
64469
+ const swarmMail = await getSwarmMailLibSQL7(projectPath);
64106
64470
  const db = await swarmMail.getDatabase();
64107
64471
  const diagnosis = [];
64108
64472
  const include = args2.include || [
@@ -64140,10 +64504,10 @@ var swarm_diagnose = tool({
64140
64504
  }
64141
64505
  if (include.includes("errors")) {
64142
64506
  const errorQuery = `
64143
- SELECT type, json_extract(data, '$.error_count') as error_count
64507
+ SELECT type, json_extract(data, '$.success') as success
64144
64508
  FROM events
64145
64509
  WHERE type = 'subtask_outcome'
64146
- AND json_extract(data, '$.success') = 'false'
64510
+ AND json_extract(data, '$.success') = 0
64147
64511
  ${args2.epic_id ? "AND json_extract(data, '$.epic_id') = ?" : ""}
64148
64512
  ${args2.bead_id ? "AND json_extract(data, '$.bead_id') = ?" : ""}
64149
64513
  LIMIT 10
@@ -64213,13 +64577,13 @@ var swarm_insights = tool({
64213
64577
  });
64214
64578
  }
64215
64579
  const projectPath = process.cwd();
64216
- const swarmMail = await getSwarmMailLibSQL5(projectPath);
64580
+ const swarmMail = await getSwarmMailLibSQL7(projectPath);
64217
64581
  const db = await swarmMail.getDatabase();
64218
64582
  const insights = [];
64219
64583
  if (args2.metrics.includes("success_rate")) {
64220
64584
  const query = `
64221
64585
  SELECT
64222
- SUM(CASE WHEN json_extract(data, '$.success') = 'true' THEN 1 ELSE 0 END) as successes,
64586
+ SUM(CASE WHEN json_extract(data, '$.success') = 1 THEN 1 ELSE 0 END) as successes,
64223
64587
  COUNT(*) as total
64224
64588
  FROM events
64225
64589
  WHERE type = 'subtask_outcome'
@@ -64241,6 +64605,8 @@ var swarm_insights = tool({
64241
64605
  SELECT AVG(CAST(json_extract(data, '$.duration_ms') AS REAL)) as avg_duration
64242
64606
  FROM events
64243
64607
  WHERE type = 'subtask_outcome'
64608
+ AND json_extract(data, '$.success') = 1
64609
+ AND json_extract(data, '$.duration_ms') IS NOT NULL
64244
64610
  ${args2.epic_id ? "AND json_extract(data, '$.epic_id') = ?" : ""}
64245
64611
  `;
64246
64612
  const result = await db.query(query, args2.epic_id ? [args2.epic_id] : []);
@@ -64306,7 +64672,7 @@ function formatCreditLine(user, issueNumber) {
64306
64672
  }
64307
64673
  async function storeContributorMemory(user, issueNumber) {
64308
64674
  try {
64309
- const adapter = await getMemoryAdapter();
64675
+ const adapter = await getHivemindAdapter();
64310
64676
  const twitterPart = user.twitter_username ? ` (@${user.twitter_username} on Twitter)` : "";
64311
64677
  const issuePart = issueNumber ? `. Filed issue #${issueNumber}` : "";
64312
64678
  const bioPart = user.bio ? `. Bio: '${user.bio}'` : "";
@@ -64364,268 +64730,6 @@ var contributorTools = {
64364
64730
  contributor_lookup
64365
64731
  };
64366
64732
 
64367
- // src/cass-tools.ts
64368
- init_dist();
64369
- import { execSync, spawn } from "child_process";
64370
- import { getSwarmMailLibSQL as getSwarmMailLibSQL6, createEvent as createEvent5 } from "swarm-mail";
64371
- function isCassAvailable() {
64372
- try {
64373
- execSync("which cass", { stdio: "ignore" });
64374
- return true;
64375
- } catch {
64376
- return false;
64377
- }
64378
- }
64379
- async function execCass(args2) {
64380
- return new Promise((resolve2, reject) => {
64381
- const proc = spawn("cass", args2, {
64382
- stdio: ["ignore", "pipe", "pipe"]
64383
- });
64384
- let stdout = "";
64385
- let stderr = "";
64386
- proc.stdout.on("data", (data) => {
64387
- stdout += data;
64388
- });
64389
- proc.stderr.on("data", (data) => {
64390
- stderr += data;
64391
- });
64392
- proc.on("close", (code) => {
64393
- if (code === 0) {
64394
- resolve2(stdout);
64395
- } else {
64396
- reject(new Error(stderr || `cass exited with code ${code}`));
64397
- }
64398
- });
64399
- proc.on("error", (err) => {
64400
- if (err.code === "ENOENT") {
64401
- reject(new Error("cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"));
64402
- } else {
64403
- reject(err);
64404
- }
64405
- });
64406
- });
64407
- }
64408
- async function emitEvent(eventType, data) {
64409
- try {
64410
- const projectPath = process.cwd();
64411
- const swarmMail = await getSwarmMailLibSQL6(projectPath);
64412
- const event = createEvent5(eventType, {
64413
- project_key: projectPath,
64414
- ...data
64415
- });
64416
- await swarmMail.appendEvent(event);
64417
- } catch {}
64418
- }
64419
- var cass_search = tool({
64420
- 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.",
64421
- args: {
64422
- query: tool.schema.string().describe("Search query (e.g., 'authentication error Next.js')"),
64423
- agent: tool.schema.string().optional().describe("Filter by agent name (e.g., 'claude', 'cursor')"),
64424
- days: tool.schema.number().optional().describe("Only search sessions from last N days"),
64425
- limit: tool.schema.number().optional().describe("Max results to return (default: 5)"),
64426
- fields: tool.schema.string().optional().describe("Field selection: 'minimal' for compact output (path, line, agent only)")
64427
- },
64428
- async execute(args2) {
64429
- const startTime = Date.now();
64430
- if (!isCassAvailable()) {
64431
- return JSON.stringify({
64432
- error: "cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"
64433
- });
64434
- }
64435
- try {
64436
- const cliArgs = ["search", args2.query];
64437
- if (args2.agent) {
64438
- cliArgs.push("--agent", args2.agent);
64439
- }
64440
- if (args2.days) {
64441
- cliArgs.push("--days", String(args2.days));
64442
- }
64443
- if (args2.limit) {
64444
- cliArgs.push("--limit", String(args2.limit));
64445
- }
64446
- if (args2.fields === "minimal") {
64447
- cliArgs.push("--minimal");
64448
- }
64449
- const output = await execCass(cliArgs);
64450
- const lines = output.trim().split(`
64451
- `).filter((l) => l.trim());
64452
- const resultCount = lines.length;
64453
- await emitEvent("cass_searched", {
64454
- query: args2.query,
64455
- agent_filter: args2.agent,
64456
- days_filter: args2.days,
64457
- result_count: resultCount,
64458
- search_duration_ms: Date.now() - startTime
64459
- });
64460
- return output;
64461
- } catch (error45) {
64462
- return JSON.stringify({
64463
- error: error45 instanceof Error ? error45.message : String(error45)
64464
- });
64465
- }
64466
- }
64467
- });
64468
- var cass_view = tool({
64469
- description: "View a specific conversation/session from search results. Use source_path from cass_search output.",
64470
- args: {
64471
- path: tool.schema.string().describe("Path to session file (from cass_search results)"),
64472
- line: tool.schema.number().optional().describe("Jump to specific line number")
64473
- },
64474
- async execute(args2) {
64475
- if (!isCassAvailable()) {
64476
- return JSON.stringify({
64477
- error: "cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"
64478
- });
64479
- }
64480
- try {
64481
- const cliArgs = ["view", args2.path];
64482
- if (args2.line) {
64483
- cliArgs.push("--line", String(args2.line));
64484
- }
64485
- const output = await execCass(cliArgs);
64486
- let agentType;
64487
- if (args2.path.includes("claude"))
64488
- agentType = "claude";
64489
- else if (args2.path.includes("cursor"))
64490
- agentType = "cursor";
64491
- else if (args2.path.includes("opencode"))
64492
- agentType = "opencode";
64493
- else if (args2.path.includes("codex"))
64494
- agentType = "codex";
64495
- await emitEvent("cass_viewed", {
64496
- session_path: args2.path,
64497
- line_number: args2.line,
64498
- agent_type: agentType
64499
- });
64500
- return output;
64501
- } catch (error45) {
64502
- return JSON.stringify({
64503
- error: error45 instanceof Error ? error45.message : String(error45)
64504
- });
64505
- }
64506
- }
64507
- });
64508
- var cass_expand = tool({
64509
- description: "Expand context around a specific line in a session. Shows messages before/after.",
64510
- args: {
64511
- path: tool.schema.string().describe("Path to session file"),
64512
- line: tool.schema.number().describe("Line number to expand around"),
64513
- context: tool.schema.number().optional().describe("Number of lines before/after to show (default: 5)")
64514
- },
64515
- async execute(args2) {
64516
- if (!isCassAvailable()) {
64517
- return JSON.stringify({
64518
- error: "cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"
64519
- });
64520
- }
64521
- try {
64522
- const cliArgs = ["expand", args2.path, "--line", String(args2.line)];
64523
- if (args2.context) {
64524
- cliArgs.push("--context", String(args2.context));
64525
- }
64526
- const output = await execCass(cliArgs);
64527
- await emitEvent("cass_viewed", {
64528
- session_path: args2.path,
64529
- line_number: args2.line
64530
- });
64531
- return output;
64532
- } catch (error45) {
64533
- return JSON.stringify({
64534
- error: error45 instanceof Error ? error45.message : String(error45)
64535
- });
64536
- }
64537
- }
64538
- });
64539
- var cass_health = tool({
64540
- description: "Check if cass index is healthy. Exit 0 = ready, Exit 1 = needs indexing. Run this before searching.",
64541
- args: {},
64542
- async execute() {
64543
- if (!isCassAvailable()) {
64544
- return JSON.stringify({
64545
- healthy: false,
64546
- error: "cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"
64547
- });
64548
- }
64549
- try {
64550
- await execCass(["health"]);
64551
- return JSON.stringify({ healthy: true, message: "Index is ready" });
64552
- } catch (error45) {
64553
- return JSON.stringify({
64554
- healthy: false,
64555
- message: "Index needs rebuilding. Run cass_index()",
64556
- error: error45 instanceof Error ? error45.message : String(error45)
64557
- });
64558
- }
64559
- }
64560
- });
64561
- var cass_index = tool({
64562
- description: "Build or rebuild the search index. Run this if health check fails or to pick up new sessions.",
64563
- args: {
64564
- full: tool.schema.boolean().optional().describe("Force full rebuild (default: incremental)")
64565
- },
64566
- async execute(args2) {
64567
- const startTime = Date.now();
64568
- if (!isCassAvailable()) {
64569
- return JSON.stringify({
64570
- error: "cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"
64571
- });
64572
- }
64573
- try {
64574
- const cliArgs = ["index"];
64575
- if (args2.full) {
64576
- cliArgs.push("--full");
64577
- }
64578
- const output = await execCass(cliArgs);
64579
- let sessionsIndexed = 0;
64580
- let messagesIndexed = 0;
64581
- const sessionsMatch = output.match(/(\d+)\s*sessions?/i);
64582
- const messagesMatch = output.match(/(\d+)\s*messages?/i);
64583
- if (sessionsMatch)
64584
- sessionsIndexed = parseInt(sessionsMatch[1], 10);
64585
- if (messagesMatch)
64586
- messagesIndexed = parseInt(messagesMatch[1], 10);
64587
- await emitEvent("cass_indexed", {
64588
- sessions_indexed: sessionsIndexed,
64589
- messages_indexed: messagesIndexed,
64590
- duration_ms: Date.now() - startTime,
64591
- full_rebuild: args2.full ?? false
64592
- });
64593
- return output;
64594
- } catch (error45) {
64595
- return JSON.stringify({
64596
- error: error45 instanceof Error ? error45.message : String(error45)
64597
- });
64598
- }
64599
- }
64600
- });
64601
- var cass_stats = tool({
64602
- description: "Show index statistics - how many sessions, messages, agents indexed.",
64603
- args: {},
64604
- async execute() {
64605
- if (!isCassAvailable()) {
64606
- return JSON.stringify({
64607
- error: "cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"
64608
- });
64609
- }
64610
- try {
64611
- const output = await execCass(["stats"]);
64612
- return output;
64613
- } catch (error45) {
64614
- return JSON.stringify({
64615
- error: error45 instanceof Error ? error45.message : String(error45)
64616
- });
64617
- }
64618
- }
64619
- });
64620
- var cassTools = {
64621
- cass_search,
64622
- cass_view,
64623
- cass_expand,
64624
- cass_health,
64625
- cass_index,
64626
- cass_stats
64627
- };
64628
-
64629
64733
  // src/output-guardrails.ts
64630
64734
  var DEFAULT_GUARDRAIL_CONFIG = {
64631
64735
  defaultMaxChars: 32000,
@@ -64961,35 +65065,75 @@ function detectCoordinatorViolation(params) {
64961
65065
  payload
64962
65066
  };
64963
65067
  }
65068
+ if (toolName === "swarm_complete" || toolName === "hive_close") {
65069
+ const payload = { tool: toolName };
65070
+ captureCoordinatorEvent({
65071
+ session_id: sessionId,
65072
+ epic_id: epicId,
65073
+ timestamp: new Date().toISOString(),
65074
+ event_type: "VIOLATION",
65075
+ violation_type: "worker_completed_without_review",
65076
+ payload
65077
+ });
65078
+ return {
65079
+ isViolation: true,
65080
+ violationType: "worker_completed_without_review",
65081
+ message: `⚠️ Coordinator should not complete worker tasks directly. Coordinators should review worker output using swarm_review and swarm_review_feedback.`,
65082
+ payload
65083
+ };
65084
+ }
64964
65085
  return { isViolation: false };
64965
65086
  }
64966
- var coordinatorContext = {
65087
+ var coordinatorContexts = new Map;
65088
+ var globalCoordinatorContext = {
64967
65089
  isCoordinator: false
64968
65090
  };
64969
65091
  function setCoordinatorContext(ctx) {
64970
- coordinatorContext = {
64971
- ...coordinatorContext,
64972
- ...ctx,
64973
- activatedAt: ctx.isCoordinator ? Date.now() : coordinatorContext.activatedAt
64974
- };
65092
+ const sessionId = ctx.sessionId;
65093
+ if (sessionId) {
65094
+ const existing = coordinatorContexts.get(sessionId) || { isCoordinator: false };
65095
+ coordinatorContexts.set(sessionId, {
65096
+ ...existing,
65097
+ ...ctx,
65098
+ activatedAt: ctx.isCoordinator ? Date.now() : existing.activatedAt
65099
+ });
65100
+ } else {
65101
+ globalCoordinatorContext = {
65102
+ ...globalCoordinatorContext,
65103
+ ...ctx,
65104
+ activatedAt: ctx.isCoordinator ? Date.now() : globalCoordinatorContext.activatedAt
65105
+ };
65106
+ }
64975
65107
  }
64976
- function getCoordinatorContext() {
64977
- return { ...coordinatorContext };
65108
+ function getCoordinatorContext(sessionId) {
65109
+ if (sessionId) {
65110
+ return { ...coordinatorContexts.get(sessionId) || { isCoordinator: false } };
65111
+ }
65112
+ return { ...globalCoordinatorContext };
64978
65113
  }
64979
- function clearCoordinatorContext() {
64980
- coordinatorContext = {
64981
- isCoordinator: false
64982
- };
65114
+ function clearCoordinatorContext(sessionId) {
65115
+ if (sessionId) {
65116
+ coordinatorContexts.delete(sessionId);
65117
+ } else {
65118
+ globalCoordinatorContext = {
65119
+ isCoordinator: false
65120
+ };
65121
+ }
64983
65122
  }
64984
- function isInCoordinatorContext() {
64985
- if (!coordinatorContext.isCoordinator) {
65123
+ function isInCoordinatorContext(sessionId) {
65124
+ const ctx = sessionId ? coordinatorContexts.get(sessionId) : globalCoordinatorContext;
65125
+ if (!ctx || !ctx.isCoordinator) {
64986
65126
  return false;
64987
65127
  }
64988
65128
  const COORDINATOR_TIMEOUT_MS = 4 * 60 * 60 * 1000;
64989
- if (coordinatorContext.activatedAt) {
64990
- const elapsed = Date.now() - coordinatorContext.activatedAt;
65129
+ if (ctx.activatedAt) {
65130
+ const elapsed = Date.now() - ctx.activatedAt;
64991
65131
  if (elapsed > COORDINATOR_TIMEOUT_MS) {
64992
- clearCoordinatorContext();
65132
+ if (sessionId) {
65133
+ coordinatorContexts.delete(sessionId);
65134
+ } else {
65135
+ globalCoordinatorContext = { isCoordinator: false };
65136
+ }
64993
65137
  return false;
64994
65138
  }
64995
65139
  }
@@ -65095,9 +65239,9 @@ function getMetricsSummary(metrics) {
65095
65239
  // src/logger.ts
65096
65240
  var import_pino = __toESM(require_pino(), 1);
65097
65241
  import { mkdirSync as mkdirSync5, existsSync as existsSync8 } from "node:fs";
65098
- import { join as join11 } from "node:path";
65099
- import { homedir as homedir3 } from "node:os";
65100
- var DEFAULT_LOG_DIR = join11(homedir3(), ".config", "swarm-tools", "logs");
65242
+ import { join as join13 } from "node:path";
65243
+ import { homedir as homedir4 } from "node:os";
65244
+ var DEFAULT_LOG_DIR = join13(homedir4(), ".config", "swarm-tools", "logs");
65101
65245
  function ensureLogDir(logDir) {
65102
65246
  if (!existsSync8(logDir)) {
65103
65247
  mkdirSync5(logDir, { recursive: true });
@@ -65116,7 +65260,7 @@ function getLogger(logDir = DEFAULT_LOG_DIR) {
65116
65260
  let logger;
65117
65261
  if (process.env.SWARM_LOG_FILE === "1") {
65118
65262
  ensureLogDir(logDir);
65119
- const logPath = join11(logDir, "swarm.log");
65263
+ const logPath = join13(logDir, "swarm.log");
65120
65264
  logger = import_pino.default(baseConfig, import_pino.default.destination({ dest: logPath, sync: false }));
65121
65265
  } else {
65122
65266
  logger = import_pino.default(baseConfig);
@@ -65136,7 +65280,7 @@ function createChildLogger(module, logDir = DEFAULT_LOG_DIR) {
65136
65280
  let childLogger;
65137
65281
  if (process.env.SWARM_LOG_FILE === "1") {
65138
65282
  ensureLogDir(logDir);
65139
- const logPath = join11(logDir, `${module}.log`);
65283
+ const logPath = join13(logDir, `${module}.log`);
65140
65284
  childLogger = import_pino.default(baseConfig, import_pino.default.destination({ dest: logPath, sync: false }));
65141
65285
  } else {
65142
65286
  childLogger = import_pino.default(baseConfig);
@@ -65148,6 +65292,7 @@ function createChildLogger(module, logDir = DEFAULT_LOG_DIR) {
65148
65292
  var logger = getLogger();
65149
65293
 
65150
65294
  // src/compaction-hook.ts
65295
+ init_eval_capture();
65151
65296
  var _logger;
65152
65297
  function getLog() {
65153
65298
  if (!_logger) {
@@ -65174,7 +65319,7 @@ Your role is ORCHESTRATION, not implementation. The resume steps above (if prese
65174
65319
  ## \uD83C\uDFAF WHAT GOOD LOOKS LIKE (Behavioral Examples)
65175
65320
 
65176
65321
  **✅ GOOD Coordinator Behavior:**
65177
- - Spawned researcher for unfamiliar tech → got summary → stored in semantic-memory
65322
+ - Spawned researcher for unfamiliar tech → got summary → stored in hivemind
65178
65323
  - Loaded \`skills_use(name="testing-patterns")\` BEFORE spawning test workers
65179
65324
  - Checked \`swarmmail_inbox()\` every 5-10 minutes → caught blocked worker → unblocked in 2min
65180
65325
  - Delegated planning to swarm/planner subagent → main context stayed clean
@@ -65328,15 +65473,14 @@ swarm_spawn_researcher(
65328
65473
  tech_stack=["TECHNOLOGY"],
65329
65474
  project_path="PROJECT_PATH"
65330
65475
  )
65331
- // Then spawn with Task(subagent_type="swarm/researcher", prompt="...")
65476
+ // Then spawn with Task(subagent_type="swarm-researcher", prompt="...")
65332
65477
  \`\`\`
65333
65478
 
65334
65479
  ### Phase 2: Knowledge Gathering
65335
65480
 
65336
65481
  \`\`\`
65337
- semantic-memory_find(query="TASK_KEYWORDS", limit=5) # Past learnings
65338
- cass_search(query="TASK_DESCRIPTION", limit=5) # Similar past tasks
65339
- skills_list() # Available skills
65482
+ hivemind_find(query="TASK_KEYWORDS", limit=5) # Past learnings
65483
+ skills_list() # Available skills
65340
65484
  \`\`\`
65341
65485
 
65342
65486
  ### Phase 3: Decompose
@@ -65359,7 +65503,7 @@ swarm_validate_decomposition(response="CELLTREE_JSON")
65359
65503
 
65360
65504
  \`\`\`
65361
65505
  swarm_spawn_subtask(bead_id, epic_id, title, files, shared_context, project_path)
65362
- Task(subagent_type="swarm/worker", prompt="GENERATED_PROMPT")
65506
+ Task(subagent_type="swarm-worker", prompt="GENERATED_PROMPT")
65363
65507
  \`\`\`
65364
65508
 
65365
65509
  ### Phase 7: Review Loop (MANDATORY)
@@ -65639,14 +65783,14 @@ function buildDynamicSwarmStateFromScanned(scanned, detected) {
65639
65783
  return parts2.join(`
65640
65784
  `);
65641
65785
  }
65642
- async function detectSwarm() {
65786
+ async function detectSwarm(getHiveAdapterFn, checkSwarmHealthFn, getHiveWorkingDirectoryFn, log3) {
65643
65787
  const reasons = [];
65644
65788
  let highConfidence = false;
65645
65789
  let mediumConfidence = false;
65646
65790
  let lowConfidence = false;
65647
65791
  let state;
65648
65792
  try {
65649
- const projectKey = getHiveWorkingDirectory();
65793
+ const projectKey = getHiveWorkingDirectoryFn();
65650
65794
  state = {
65651
65795
  projectPath: projectKey,
65652
65796
  subtasks: {
@@ -65658,9 +65802,9 @@ async function detectSwarm() {
65658
65802
  };
65659
65803
  const swarmMailStart = Date.now();
65660
65804
  try {
65661
- const health = await checkSwarmHealth3(projectKey);
65805
+ const health = await checkSwarmHealthFn(projectKey);
65662
65806
  const duration3 = Date.now() - swarmMailStart;
65663
- getLog().debug({
65807
+ log3.debug({
65664
65808
  source: "swarm-mail",
65665
65809
  duration_ms: duration3,
65666
65810
  healthy: health.healthy,
@@ -65681,7 +65825,7 @@ async function detectSwarm() {
65681
65825
  }
65682
65826
  }
65683
65827
  } catch (error45) {
65684
- getLog().debug({
65828
+ log3.debug({
65685
65829
  source: "swarm-mail",
65686
65830
  duration_ms: Date.now() - swarmMailStart,
65687
65831
  error: error45 instanceof Error ? error45.message : String(error45)
@@ -65689,7 +65833,7 @@ async function detectSwarm() {
65689
65833
  }
65690
65834
  const hiveStart = Date.now();
65691
65835
  try {
65692
- const adapter = await getHiveAdapter(projectKey);
65836
+ const adapter = await getHiveAdapterFn(projectKey);
65693
65837
  const cells = await adapter.queryCells(projectKey, {});
65694
65838
  const duration3 = Date.now() - hiveStart;
65695
65839
  if (Array.isArray(cells) && cells.length > 0) {
@@ -65716,7 +65860,7 @@ async function detectSwarm() {
65716
65860
  state.subtasks.in_progress = epicSubtasks.filter((c) => c.status === "in_progress").length;
65717
65861
  state.subtasks.open = epicSubtasks.filter((c) => c.status === "open").length;
65718
65862
  state.subtasks.blocked = epicSubtasks.filter((c) => c.status === "blocked").length;
65719
- getLog().debug({
65863
+ log3.debug({
65720
65864
  epic_id: state.epicId,
65721
65865
  epic_title: state.epicTitle,
65722
65866
  subtasks_closed: state.subtasks.closed,
@@ -65736,7 +65880,7 @@ async function detectSwarm() {
65736
65880
  lowConfidence = true;
65737
65881
  reasons.push(`${cells.length} total cells in hive`);
65738
65882
  }
65739
- getLog().debug({
65883
+ log3.debug({
65740
65884
  source: "hive",
65741
65885
  duration_ms: duration3,
65742
65886
  total_cells: cells.length,
@@ -65746,10 +65890,10 @@ async function detectSwarm() {
65746
65890
  recent_updates: recentCells.length
65747
65891
  }, "checked hive cells");
65748
65892
  } else {
65749
- getLog().debug({ source: "hive", duration_ms: duration3, total_cells: 0 }, "hive empty");
65893
+ log3.debug({ source: "hive", duration_ms: duration3, total_cells: 0 }, "hive empty");
65750
65894
  }
65751
65895
  } catch (error45) {
65752
- getLog().debug({
65896
+ log3.debug({
65753
65897
  source: "hive",
65754
65898
  duration_ms: Date.now() - hiveStart,
65755
65899
  error: error45 instanceof Error ? error45.message : String(error45)
@@ -65758,7 +65902,7 @@ async function detectSwarm() {
65758
65902
  } catch (error45) {
65759
65903
  lowConfidence = true;
65760
65904
  reasons.push("Could not detect project, using fallback");
65761
- getLog().debug({
65905
+ log3.debug({
65762
65906
  error: error45 instanceof Error ? error45.message : String(error45)
65763
65907
  }, "project detection failed");
65764
65908
  }
@@ -65778,7 +65922,7 @@ async function detectSwarm() {
65778
65922
  reasons,
65779
65923
  state
65780
65924
  };
65781
- getLog().debug({
65925
+ log3.debug({
65782
65926
  detected: result.detected,
65783
65927
  confidence: result.confidence,
65784
65928
  reason_count: result.reasons.length,
@@ -65787,14 +65931,24 @@ async function detectSwarm() {
65787
65931
  }, "swarm detection complete");
65788
65932
  return result;
65789
65933
  }
65790
- function createCompactionHook(client) {
65934
+ function createCompactionHook(options2) {
65935
+ const isOptions = options2 && typeof options2 === "object" && (("getHiveAdapter" in options2) || ("checkSwarmHealth" in options2) || ("getHiveWorkingDirectory" in options2) || ("client" in options2));
65936
+ const opts = isOptions ? options2 : { client: options2 };
65937
+ const {
65938
+ client,
65939
+ getHiveAdapter: customGetHiveAdapter,
65940
+ checkSwarmHealth: customCheckSwarmHealth,
65941
+ getHiveWorkingDirectory: customGetHiveWorkingDirectory,
65942
+ logger: customLogger
65943
+ } = opts;
65791
65944
  return async (input, output) => {
65792
65945
  const startTime = Date.now();
65946
+ const log3 = customLogger || getLog();
65793
65947
  const metrics = createMetricsCollector({
65794
65948
  session_id: input.sessionID,
65795
65949
  has_sdk_client: !!client
65796
65950
  });
65797
- getLog().info({
65951
+ log3.info({
65798
65952
  session_id: input.sessionID,
65799
65953
  trigger: "session_compaction",
65800
65954
  has_sdk_client: !!client
@@ -65806,7 +65960,7 @@ function createCompactionHook(client) {
65806
65960
  const scannedState = await scanSessionMessages(client, input.sessionID);
65807
65961
  recordPhaseComplete(metrics, "GATHER_SWARM_MAIL" /* GATHER_SWARM_MAIL */);
65808
65962
  recordPhaseStart(metrics, "DETECT" /* DETECT */);
65809
- const detection = await detectSwarm();
65963
+ const detection = await detectSwarm(customGetHiveAdapter || getHiveAdapter, customCheckSwarmHealth || checkSwarmHealth3, customGetHiveWorkingDirectory || getHiveWorkingDirectory, log3);
65810
65964
  let effectiveConfidence = detection.confidence;
65811
65965
  if (scannedState.epicId || scannedState.subtasks.size > 0) {
65812
65966
  if (effectiveConfidence === "none" || effectiveConfidence === "low") {
@@ -65824,6 +65978,18 @@ function createCompactionHook(client) {
65824
65978
  confidence: effectiveConfidence,
65825
65979
  detected: detection.detected || scannedState.epicId !== undefined
65826
65980
  });
65981
+ const epicId = scannedState.epicId || detection.state?.epicId || "unknown";
65982
+ await captureCompactionEvent({
65983
+ session_id: input.sessionID,
65984
+ epic_id: epicId,
65985
+ compaction_type: "detection_complete",
65986
+ payload: {
65987
+ confidence: effectiveConfidence,
65988
+ detected: detection.detected || scannedState.epicId !== undefined,
65989
+ reasons: detection.reasons,
65990
+ context_type: effectiveConfidence === "high" || effectiveConfidence === "medium" ? "full" : "fallback"
65991
+ }
65992
+ });
65827
65993
  recordPhaseStart(metrics, "INJECT" /* INJECT */);
65828
65994
  if (effectiveConfidence === "high" || effectiveConfidence === "medium") {
65829
65995
  const header = `[Swarm detected: ${detection.reasons.join(", ")}]
@@ -65848,7 +66014,18 @@ function createCompactionHook(client) {
65848
66014
  context_length: contextContent.length,
65849
66015
  context_type: "full"
65850
66016
  });
65851
- getLog().info({
66017
+ await captureCompactionEvent({
66018
+ session_id: input.sessionID,
66019
+ epic_id: epicId,
66020
+ compaction_type: "prompt_generated",
66021
+ payload: {
66022
+ prompt_length: contextContent.length,
66023
+ full_prompt: contextContent,
66024
+ context_type: "full",
66025
+ confidence: effectiveConfidence
66026
+ }
66027
+ });
66028
+ log3.info({
65852
66029
  confidence: effectiveConfidence,
65853
66030
  context_length: contextContent.length,
65854
66031
  context_type: "full",
@@ -65868,7 +66045,18 @@ function createCompactionHook(client) {
65868
66045
  context_length: contextContent.length,
65869
66046
  context_type: "fallback"
65870
66047
  });
65871
- getLog().info({
66048
+ await captureCompactionEvent({
66049
+ session_id: input.sessionID,
66050
+ epic_id: epicId,
66051
+ compaction_type: "prompt_generated",
66052
+ payload: {
66053
+ prompt_length: contextContent.length,
66054
+ full_prompt: contextContent,
66055
+ context_type: "fallback",
66056
+ confidence: effectiveConfidence
66057
+ }
66058
+ });
66059
+ log3.info({
65872
66060
  confidence: effectiveConfidence,
65873
66061
  context_length: contextContent.length,
65874
66062
  context_type: "fallback",
@@ -65878,7 +66066,7 @@ function createCompactionHook(client) {
65878
66066
  recordPhaseComplete(metrics, "INJECT" /* INJECT */, {
65879
66067
  context_type: "none"
65880
66068
  });
65881
- getLog().debug({
66069
+ log3.debug({
65882
66070
  confidence: effectiveConfidence,
65883
66071
  context_type: "none"
65884
66072
  }, "no swarm detected, skipping injection");
@@ -65886,7 +66074,7 @@ function createCompactionHook(client) {
65886
66074
  recordPhaseStart(metrics, "COMPLETE" /* COMPLETE */);
65887
66075
  const duration3 = Date.now() - startTime;
65888
66076
  const summary5 = getMetricsSummary(metrics);
65889
- getLog().info({
66077
+ log3.info({
65890
66078
  duration_ms: duration3,
65891
66079
  success: true,
65892
66080
  detected: detection.detected || scannedState.epicId !== undefined,
@@ -65910,7 +66098,7 @@ function createCompactionHook(client) {
65910
66098
  success: false,
65911
66099
  error: error45 instanceof Error ? error45.message : String(error45)
65912
66100
  });
65913
- getLog().error({
66101
+ log3.error({
65914
66102
  duration_ms: duration3,
65915
66103
  success: false,
65916
66104
  error: error45 instanceof Error ? error45.message : String(error45),
@@ -66055,6 +66243,246 @@ var sessionStats = {
66055
66243
  // src/index.ts
66056
66244
  init_skills();
66057
66245
  init_swarm_validation();
66246
+
66247
+ // src/cass-tools.ts
66248
+ init_dist();
66249
+ import {
66250
+ getDb,
66251
+ makeOllamaLive as makeOllamaLive3,
66252
+ viewSessionLine,
66253
+ SessionIndexer as SessionIndexer2,
66254
+ createEvent as createEvent6,
66255
+ getSwarmMailLibSQL as getSwarmMailLibSQL8
66256
+ } from "swarm-mail";
66257
+ import * as os3 from "node:os";
66258
+ import * as path4 from "node:path";
66259
+ var AGENT_DIRECTORIES2 = [
66260
+ path4.join(os3.homedir(), ".config", "swarm-tools", "sessions"),
66261
+ path4.join(os3.homedir(), ".opencode"),
66262
+ path4.join(os3.homedir(), "Cursor", "User", "History"),
66263
+ path4.join(os3.homedir(), ".local", "share", "Claude"),
66264
+ path4.join(os3.homedir(), ".aider")
66265
+ ];
66266
+ async function getSessionIndexer2() {
66267
+ const db = await getDb();
66268
+ const ollamaLayer = makeOllamaLive3({
66269
+ ollamaHost: process.env.OLLAMA_HOST || "http://localhost:11434",
66270
+ ollamaModel: process.env.OLLAMA_MODEL || "mxbai-embed-large"
66271
+ });
66272
+ return new SessionIndexer2(db, ollamaLayer);
66273
+ }
66274
+ async function emitEvent2(eventType, data) {
66275
+ try {
66276
+ const projectPath = process.cwd();
66277
+ const swarmMail = await getSwarmMailLibSQL8(projectPath);
66278
+ const event = createEvent6(eventType, {
66279
+ project_key: projectPath,
66280
+ ...data
66281
+ });
66282
+ await swarmMail.appendEvent(event);
66283
+ } catch {}
66284
+ }
66285
+ function detectAgentType(filePath) {
66286
+ if (filePath.includes("claude"))
66287
+ return "claude";
66288
+ if (filePath.includes("cursor"))
66289
+ return "cursor";
66290
+ if (filePath.includes("opencode"))
66291
+ return "opencode";
66292
+ if (filePath.includes("swarm-tools"))
66293
+ return "opencode-swarm";
66294
+ if (filePath.includes("codex"))
66295
+ return "codex";
66296
+ if (filePath.includes("aider"))
66297
+ return "aider";
66298
+ return;
66299
+ }
66300
+ var cass_search2 = tool({
66301
+ 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.",
66302
+ args: {
66303
+ query: tool.schema.string().describe("Search query (e.g., 'authentication error Next.js')"),
66304
+ agent: tool.schema.string().optional().describe("Filter by agent name (e.g., 'claude', 'cursor')"),
66305
+ days: tool.schema.number().optional().describe("Only search sessions from last N days"),
66306
+ limit: tool.schema.number().optional().describe("Max results to return (default: 5)"),
66307
+ fields: tool.schema.string().optional().describe("Field selection: 'minimal' for compact output (path, line, agent only)")
66308
+ },
66309
+ async execute(args2) {
66310
+ const startTime = Date.now();
66311
+ try {
66312
+ const indexer = await getSessionIndexer2();
66313
+ const searchOptions = {
66314
+ limit: args2.limit || 5,
66315
+ agent_type: args2.agent,
66316
+ fields: args2.fields === "minimal" ? "minimal" : undefined
66317
+ };
66318
+ const results = await exports_Effect.runPromise(indexer.search(args2.query, searchOptions).pipe(exports_Effect.catchAll((error45) => {
66319
+ console.warn(`Vector search failed, falling back to FTS5: ${error45.message}`);
66320
+ return exports_Effect.succeed([]);
66321
+ })));
66322
+ await emitEvent2("cass_searched", {
66323
+ query: args2.query,
66324
+ agent_filter: args2.agent,
66325
+ days_filter: args2.days,
66326
+ result_count: results.length,
66327
+ search_duration_ms: Date.now() - startTime
66328
+ });
66329
+ if (results.length === 0) {
66330
+ return `No results found. Try:
66331
+ - Broader search terms
66332
+ - Different agent filter
66333
+ - Running cass_index to refresh`;
66334
+ }
66335
+ return results.map((result, idx) => {
66336
+ const metadata = result.memory.metadata;
66337
+ const agentType = metadata?.agent_type || "unknown";
66338
+ const sourcePath = metadata?.source_path || "unknown";
66339
+ const lineNumber = metadata?.message_idx || 0;
66340
+ if (args2.fields === "minimal") {
66341
+ return `${idx + 1}. ${sourcePath}:${lineNumber} (${agentType})`;
66342
+ }
66343
+ return `${idx + 1}. [${agentType}] ${sourcePath}:${lineNumber}
66344
+ Score: ${result.score?.toFixed(3)}
66345
+ ${result.memory.content.slice(0, 200)}...
66346
+ `;
66347
+ }).join(`
66348
+ `);
66349
+ } catch (error45) {
66350
+ return JSON.stringify({
66351
+ error: error45 instanceof Error ? error45.message : String(error45)
66352
+ });
66353
+ }
66354
+ }
66355
+ });
66356
+ var cass_view2 = tool({
66357
+ description: "View a specific conversation/session from search results. Use source_path from cass_search output.",
66358
+ args: {
66359
+ path: tool.schema.string().describe("Path to session file (from cass_search results)"),
66360
+ line: tool.schema.number().optional().describe("Jump to specific line number")
66361
+ },
66362
+ async execute(args2) {
66363
+ try {
66364
+ const opts = {
66365
+ path: args2.path,
66366
+ line: args2.line,
66367
+ context: 3
66368
+ };
66369
+ const output = viewSessionLine(opts);
66370
+ await emitEvent2("cass_viewed", {
66371
+ session_path: args2.path,
66372
+ line_number: args2.line,
66373
+ agent_type: detectAgentType(args2.path)
66374
+ });
66375
+ return output;
66376
+ } catch (error45) {
66377
+ return JSON.stringify({
66378
+ error: error45 instanceof Error ? error45.message : String(error45)
66379
+ });
66380
+ }
66381
+ }
66382
+ });
66383
+ var cass_expand2 = tool({
66384
+ description: "Expand context around a specific line in a session. Shows messages before/after.",
66385
+ args: {
66386
+ path: tool.schema.string().describe("Path to session file"),
66387
+ line: tool.schema.number().describe("Line number to expand around"),
66388
+ context: tool.schema.number().optional().describe("Number of lines before/after to show (default: 5)")
66389
+ },
66390
+ async execute(args2) {
66391
+ try {
66392
+ const opts = {
66393
+ path: args2.path,
66394
+ line: args2.line,
66395
+ context: args2.context || 5
66396
+ };
66397
+ const output = viewSessionLine(opts);
66398
+ await emitEvent2("cass_viewed", {
66399
+ session_path: args2.path,
66400
+ line_number: args2.line
66401
+ });
66402
+ return output;
66403
+ } catch (error45) {
66404
+ return JSON.stringify({
66405
+ error: error45 instanceof Error ? error45.message : String(error45)
66406
+ });
66407
+ }
66408
+ }
66409
+ });
66410
+ var cass_health2 = tool({
66411
+ description: "Check if cass index is healthy. Exit 0 = ready, Exit 1 = needs indexing. Run this before searching.",
66412
+ args: {},
66413
+ async execute() {
66414
+ try {
66415
+ const indexer = await getSessionIndexer2();
66416
+ const health = await exports_Effect.runPromise(indexer.checkHealth());
66417
+ const isHealthy = health.total_indexed > 0 && health.stale_count === 0;
66418
+ return JSON.stringify({
66419
+ healthy: isHealthy,
66420
+ message: isHealthy ? "Index is ready" : "Index needs rebuilding. Run cass_index()",
66421
+ ...health
66422
+ });
66423
+ } catch (error45) {
66424
+ return JSON.stringify({
66425
+ healthy: false,
66426
+ error: error45 instanceof Error ? error45.message : String(error45)
66427
+ });
66428
+ }
66429
+ }
66430
+ });
66431
+ var cass_index2 = tool({
66432
+ description: "Build or rebuild the search index. Run this if health check fails or to pick up new sessions.",
66433
+ args: {
66434
+ full: tool.schema.boolean().optional().describe("Force full rebuild (default: incremental)")
66435
+ },
66436
+ async execute(args2) {
66437
+ const startTime = Date.now();
66438
+ try {
66439
+ const indexer = await getSessionIndexer2();
66440
+ const allResults = [];
66441
+ for (const dir of AGENT_DIRECTORIES2) {
66442
+ try {
66443
+ const options2 = {
66444
+ recursive: true
66445
+ };
66446
+ const results = await exports_Effect.runPromise(indexer.indexDirectory(dir, options2).pipe(exports_Effect.catchAll((error45) => {
66447
+ console.warn(`Skipping ${dir}: ${error45.message}`);
66448
+ return exports_Effect.succeed([]);
66449
+ })));
66450
+ allResults.push(...results);
66451
+ } catch {}
66452
+ }
66453
+ const totalIndexed = allResults.reduce((sum2, r) => sum2 + r.indexed, 0);
66454
+ const totalSkipped = allResults.reduce((sum2, r) => sum2 + r.skipped, 0);
66455
+ await emitEvent2("cass_indexed", {
66456
+ sessions_indexed: allResults.length,
66457
+ messages_indexed: totalIndexed,
66458
+ duration_ms: Date.now() - startTime,
66459
+ full_rebuild: args2.full ?? false
66460
+ });
66461
+ return `Indexed ${allResults.length} sessions with ${totalIndexed} chunks (${totalSkipped} skipped) in ${Date.now() - startTime}ms`;
66462
+ } catch (error45) {
66463
+ return JSON.stringify({
66464
+ error: error45 instanceof Error ? error45.message : String(error45)
66465
+ });
66466
+ }
66467
+ }
66468
+ });
66469
+ var cass_stats2 = tool({
66470
+ description: "Show index statistics - how many sessions, messages, agents indexed.",
66471
+ args: {},
66472
+ async execute() {
66473
+ try {
66474
+ const indexer = await getSessionIndexer2();
66475
+ const stats = await exports_Effect.runPromise(indexer.getStats());
66476
+ return JSON.stringify(stats, null, 2);
66477
+ } catch (error45) {
66478
+ return JSON.stringify({
66479
+ error: error45 instanceof Error ? error45.message : String(error45)
66480
+ });
66481
+ }
66482
+ }
66483
+ });
66484
+
66485
+ // src/index.ts
66058
66486
  var SwarmPlugin = async (input) => {
66059
66487
  const { $, directory, client } = input;
66060
66488
  setHiveWorkingDirectory(directory);
@@ -66101,7 +66529,7 @@ var SwarmPlugin = async (input) => {
66101
66529
  ...repoCrawlTools,
66102
66530
  ...skillsTools,
66103
66531
  ...mandateTools,
66104
- ...memoryTools,
66532
+ ...hivemindTools,
66105
66533
  ...observabilityTools,
66106
66534
  ...researchTools,
66107
66535
  ...contributorTools
@@ -66113,16 +66541,30 @@ var SwarmPlugin = async (input) => {
66113
66541
  },
66114
66542
  "tool.execute.before": async (input2, output) => {
66115
66543
  const toolName = input2.tool;
66544
+ const sessionId = input2.sessionID || "unknown";
66116
66545
  if (shouldAnalyzeTool(toolName)) {
66117
66546
  const analysis = analyzeTodoWrite(output.args);
66118
66547
  if (analysis.warning) {
66119
66548
  console.warn(`[swarm-plugin] ${analysis.warning}`);
66120
66549
  }
66121
66550
  }
66122
- if (isInCoordinatorContext()) {
66123
- const ctx = getCoordinatorContext();
66551
+ if (toolName === "hive_create_epic" || toolName === "swarm_decompose") {
66552
+ setCoordinatorContext({
66553
+ isCoordinator: true,
66554
+ sessionId
66555
+ });
66556
+ }
66557
+ const taskArgs = output.args;
66558
+ if (toolName === "task" && taskArgs?.subagent_type?.toLowerCase().includes("swarm")) {
66559
+ setCoordinatorContext({
66560
+ isCoordinator: true,
66561
+ sessionId
66562
+ });
66563
+ }
66564
+ if (isInCoordinatorContext(sessionId)) {
66565
+ const ctx = getCoordinatorContext(sessionId);
66124
66566
  const violation = detectCoordinatorViolation({
66125
- sessionId: input2.sessionID || "unknown",
66567
+ sessionId,
66126
66568
  epicId: ctx.epicId || "unknown",
66127
66569
  toolName,
66128
66570
  toolArgs: output.args,
@@ -66132,12 +66574,6 @@ var SwarmPlugin = async (input) => {
66132
66574
  console.warn(`[swarm-plugin] ${violation.message}`);
66133
66575
  }
66134
66576
  }
66135
- if (toolName === "hive_create_epic" || toolName === "swarm_decompose") {
66136
- setCoordinatorContext({
66137
- isCoordinator: true,
66138
- sessionId: input2.sessionID
66139
- });
66140
- }
66141
66577
  if (toolName === "hive_create_epic" && output.args) {
66142
66578
  const args2 = output.args;
66143
66579
  }
@@ -66184,15 +66620,111 @@ var SwarmPlugin = async (input) => {
66184
66620
  }
66185
66621
  } catch {}
66186
66622
  }
66187
- if (toolName === "hive_close" && output.output && isInCoordinatorContext()) {
66188
- const ctx = getCoordinatorContext();
66623
+ const sessionId = input2.sessionID || "unknown";
66624
+ if (toolName === "hive_close" && output.output && isInCoordinatorContext(sessionId)) {
66625
+ const ctx2 = getCoordinatorContext(sessionId);
66189
66626
  try {
66190
66627
  const result = JSON.parse(output.output);
66191
- if (result.id === ctx.epicId) {
66192
- clearCoordinatorContext();
66628
+ if (result.id === ctx2.epicId) {
66629
+ clearCoordinatorContext(sessionId);
66193
66630
  }
66194
66631
  } catch {}
66195
66632
  }
66633
+ const ctx = getCoordinatorContext();
66634
+ const epicId = ctx.epicId || "unknown";
66635
+ if (toolName === "task") {
66636
+ try {
66637
+ const result = output.output ? JSON.parse(output.output) : {};
66638
+ if (result.researcher_id || result.research_topic || result.tools_used) {
66639
+ const { captureResearcherSpawned: captureResearcherSpawned2 } = await Promise.resolve().then(() => (init_eval_capture(), exports_eval_capture));
66640
+ await captureResearcherSpawned2({
66641
+ session_id: input2.sessionID,
66642
+ epic_id: epicId,
66643
+ researcher_id: result.researcher_id || "unknown",
66644
+ research_topic: result.research_topic || "unknown",
66645
+ tools_used: result.tools_used || []
66646
+ });
66647
+ }
66648
+ } catch (err) {}
66649
+ }
66650
+ if (toolName === "skills_use") {
66651
+ try {
66652
+ const { captureSkillLoaded: captureSkillLoaded2 } = await Promise.resolve().then(() => (init_eval_capture(), exports_eval_capture));
66653
+ const result = output.output ? JSON.parse(output.output) : {};
66654
+ const skillName = result.skill_name || result.name || "unknown";
66655
+ const context4 = result.context;
66656
+ await captureSkillLoaded2({
66657
+ session_id: input2.sessionID,
66658
+ epic_id: epicId,
66659
+ skill_name: skillName,
66660
+ context: context4
66661
+ });
66662
+ } catch (err) {}
66663
+ }
66664
+ if (toolName === "swarmmail_inbox") {
66665
+ try {
66666
+ const { captureInboxChecked: captureInboxChecked2 } = await Promise.resolve().then(() => (init_eval_capture(), exports_eval_capture));
66667
+ const result = output.output ? JSON.parse(output.output) : {};
66668
+ await captureInboxChecked2({
66669
+ session_id: input2.sessionID,
66670
+ epic_id: epicId,
66671
+ message_count: result.message_count || 0,
66672
+ urgent_count: result.urgent_count || 0
66673
+ });
66674
+ } catch (err) {
66675
+ console.warn("[eval-capture] captureInboxChecked failed:", err);
66676
+ }
66677
+ }
66678
+ if (toolName === "hive_update") {
66679
+ try {
66680
+ const result = output.output ? JSON.parse(output.output) : {};
66681
+ const newStatus = result.status;
66682
+ const previousStatus = result.previous_status;
66683
+ if (previousStatus === "blocked" && newStatus !== "blocked") {
66684
+ const { captureBlockerResolved: captureBlockerResolved2 } = await Promise.resolve().then(() => (init_eval_capture(), exports_eval_capture));
66685
+ await captureBlockerResolved2({
66686
+ session_id: input2.sessionID,
66687
+ epic_id: epicId,
66688
+ worker_id: result.worker_id || "unknown",
66689
+ subtask_id: result.id || "unknown",
66690
+ blocker_type: result.blocker_type || "unknown",
66691
+ resolution: result.resolution || "Status changed to " + newStatus
66692
+ });
66693
+ }
66694
+ if (newStatus === "blocked" && previousStatus !== "blocked") {
66695
+ const { captureBlockerDetected: captureBlockerDetected2 } = await Promise.resolve().then(() => (init_eval_capture(), exports_eval_capture));
66696
+ await captureBlockerDetected2({
66697
+ session_id: input2.sessionID,
66698
+ epic_id: epicId,
66699
+ worker_id: result.worker_id || "unknown",
66700
+ subtask_id: result.id || "unknown",
66701
+ blocker_type: result.blocker_type || "unknown",
66702
+ blocker_description: result.blocker_description || result.description || "No description provided"
66703
+ });
66704
+ }
66705
+ } catch (err) {}
66706
+ }
66707
+ if (toolName === "swarmmail_send") {
66708
+ try {
66709
+ const result = output.output ? JSON.parse(output.output) : {};
66710
+ if (result.scope_change || result.original_scope || result.new_scope) {
66711
+ const { captureScopeChangeDecision: captureScopeChangeDecision2 } = await Promise.resolve().then(() => (init_eval_capture(), exports_eval_capture));
66712
+ const threadId = result.thread_id || epicId;
66713
+ await captureScopeChangeDecision2({
66714
+ session_id: input2.sessionID,
66715
+ epic_id: threadId,
66716
+ worker_id: result.worker_id || "unknown",
66717
+ subtask_id: result.subtask_id || "unknown",
66718
+ approved: result.approved ?? false,
66719
+ original_scope: result.original_scope,
66720
+ new_scope: result.new_scope,
66721
+ requested_scope: result.requested_scope,
66722
+ rejection_reason: result.rejection_reason,
66723
+ estimated_time_add: result.estimated_time_add
66724
+ });
66725
+ }
66726
+ } catch (err) {}
66727
+ }
66196
66728
  },
66197
66729
  "experimental.session.compacting": createCompactionHook(client)
66198
66730
  };
@@ -66208,10 +66740,9 @@ var allTools = {
66208
66740
  ...repoCrawlTools,
66209
66741
  ...skillsTools,
66210
66742
  ...mandateTools,
66211
- ...memoryTools,
66743
+ ...hivemindTools,
66212
66744
  ...observabilityTools,
66213
- ...contributorTools,
66214
- ...cassTools
66745
+ ...contributorTools
66215
66746
  };
66216
66747
 
66217
66748
  // src/plugin.ts