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/index.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)}
12948
+ `;
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)}
12924
12955
  `;
12925
- fs.appendFileSync(sessionPath, line, "utf-8");
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";
@@ -40026,7 +40059,7 @@ async function getHiveAdapter(projectKey) {
40026
40059
  if (adapterCache.has(projectKey)) {
40027
40060
  return adapterCache.get(projectKey);
40028
40061
  }
40029
- const swarmMail = await getSwarmMailLibSQL(projectKey);
40062
+ const swarmMail = await getSwarmMailLibSQL2(projectKey);
40030
40063
  const db = await swarmMail.getDatabase();
40031
40064
  const adapter = createHiveAdapter(db, projectKey);
40032
40065
  await adapter.runMigrations();
@@ -40035,6 +40068,9 @@ async function getHiveAdapter(projectKey) {
40035
40068
  return adapter;
40036
40069
  }
40037
40070
  var getBeadsAdapter = getHiveAdapter;
40071
+ function clearHiveAdapterCache() {
40072
+ adapterCache.clear();
40073
+ }
40038
40074
  async function autoMigrateFromJSONL(adapter, projectKey) {
40039
40075
  const jsonlPath = join2(projectKey, ".hive", "issues.jsonl");
40040
40076
  if (!existsSync2(jsonlPath)) {
@@ -40655,7 +40691,7 @@ var hive_sync = tool({
40655
40691
  outputPath: `${projectKey}/.hive/issues.jsonl`
40656
40692
  });
40657
40693
  const flushResult = await withTimeout(flushManager.flush(), TIMEOUT_MS, "flush hive");
40658
- const swarmMail = await getSwarmMailLibSQL(projectKey);
40694
+ const swarmMail = await getSwarmMailLibSQL2(projectKey);
40659
40695
  const db = await swarmMail.getDatabase();
40660
40696
  const hivePath = join2(projectKey, ".hive");
40661
40697
  let memoriesSynced = 0;
@@ -40961,6 +40997,62 @@ var toolCheckers = {
40961
40997
  };
40962
40998
  }
40963
40999
  },
41000
+ hivemind: async () => {
41001
+ const hivemindExists = await commandExists("hivemind");
41002
+ if (hivemindExists) {
41003
+ try {
41004
+ const result = await Bun.$`hivemind stats`.quiet().nothrow();
41005
+ return {
41006
+ available: result.exitCode === 0,
41007
+ checkedAt: new Date().toISOString(),
41008
+ version: "native"
41009
+ };
41010
+ } catch (e) {
41011
+ return {
41012
+ available: false,
41013
+ checkedAt: new Date().toISOString(),
41014
+ error: String(e)
41015
+ };
41016
+ }
41017
+ }
41018
+ const semanticMemoryExists = await commandExists("semantic-memory");
41019
+ if (semanticMemoryExists) {
41020
+ try {
41021
+ const result = await Bun.$`semantic-memory stats`.quiet().nothrow();
41022
+ return {
41023
+ available: result.exitCode === 0,
41024
+ checkedAt: new Date().toISOString(),
41025
+ version: "semantic-memory-backend"
41026
+ };
41027
+ } catch (e) {
41028
+ return {
41029
+ available: false,
41030
+ checkedAt: new Date().toISOString(),
41031
+ error: String(e)
41032
+ };
41033
+ }
41034
+ }
41035
+ try {
41036
+ const proc = Bun.spawn(["bunx", "semantic-memory", "stats"], {
41037
+ stdout: "pipe",
41038
+ stderr: "pipe"
41039
+ });
41040
+ const timeout = setTimeout(() => proc.kill(), BUNX_TIMEOUT_MS);
41041
+ const exitCode = await proc.exited;
41042
+ clearTimeout(timeout);
41043
+ return {
41044
+ available: exitCode === 0,
41045
+ checkedAt: new Date().toISOString(),
41046
+ version: "bunx-semantic-memory"
41047
+ };
41048
+ } catch (e) {
41049
+ return {
41050
+ available: false,
41051
+ checkedAt: new Date().toISOString(),
41052
+ error: String(e)
41053
+ };
41054
+ }
41055
+ },
40964
41056
  ubs: async () => {
40965
41057
  const exists = await commandExists("ubs");
40966
41058
  if (!exists) {
@@ -41043,6 +41135,7 @@ var toolCheckers = {
41043
41135
  var fallbackBehaviors = {
41044
41136
  "semantic-memory": "Learning data stored in-memory only (lost on session end)",
41045
41137
  cass: "Decomposition proceeds without historical context from past sessions",
41138
+ hivemind: "Unified memory unavailable - learnings stored in-memory only, no session history search",
41046
41139
  ubs: "Subtask completion skips bug scanning - manual review recommended",
41047
41140
  hive: "Swarm cannot track issues - task coordination will be less reliable",
41048
41141
  beads: "DEPRECATED: Use hive instead. Swarm cannot track issues - task coordination will be less reliable",
@@ -41075,6 +41168,7 @@ async function checkAllTools() {
41075
41168
  const tools = [
41076
41169
  "semantic-memory",
41077
41170
  "cass",
41171
+ "hivemind",
41078
41172
  "ubs",
41079
41173
  "hive",
41080
41174
  "beads",
@@ -43772,7 +43866,7 @@ Now generate the CellTree for the given task.`;
43772
43866
  ${subagentInstructions}`;
43773
43867
  return JSON.stringify({
43774
43868
  prompt: fullPrompt,
43775
- subagent_type: "swarm/planner",
43869
+ subagent_type: "swarm-planner",
43776
43870
  description: "Task decomposition planning",
43777
43871
  strategy: {
43778
43872
  selected: selectedStrategy,
@@ -45477,7 +45571,7 @@ import {
45477
45571
  getAgent,
45478
45572
  createEvent as createEvent3,
45479
45573
  appendEvent as appendEvent2,
45480
- getSwarmMailLibSQL as getSwarmMailLibSQL3
45574
+ getSwarmMailLibSQL as getSwarmMailLibSQL4
45481
45575
  } from "swarm-mail";
45482
45576
  init_skills();
45483
45577
 
@@ -46508,7 +46602,7 @@ var swarm_init = tool({
46508
46602
  if (!availability.get("ubs")?.status.available) {
46509
46603
  degradedFeatures.push("pre-completion bug scanning");
46510
46604
  }
46511
- if (!availability.get("semantic-memory")?.status.available) {
46605
+ if (!availability.get("hivemind")?.status.available) {
46512
46606
  degradedFeatures.push("persistent learning (using in-memory fallback)");
46513
46607
  }
46514
46608
  const availableSkills = await listSkills();
@@ -46961,7 +47055,7 @@ This will be recorded as a negative learning signal.`;
46961
47055
  let deferredResolved = false;
46962
47056
  let deferredError;
46963
47057
  try {
46964
- const swarmMail = await getSwarmMailLibSQL3(args.project_key);
47058
+ const swarmMail = await getSwarmMailLibSQL4(args.project_key);
46965
47059
  const db = await swarmMail.getDatabase();
46966
47060
  const deferredUrl = `deferred:${args.bead_id}`;
46967
47061
  const checkResult = await db.query(`SELECT url, resolved FROM deferred WHERE url = ? AND resolved = 0`, [deferredUrl]);
@@ -47029,18 +47123,18 @@ This will be recorded as a negative learning signal.`;
47029
47123
  let memoryStored = false;
47030
47124
  let memoryError;
47031
47125
  try {
47032
- const memoryAvailable = await isToolAvailable("semantic-memory");
47126
+ const memoryAvailable = await isToolAvailable("hivemind");
47033
47127
  if (memoryAvailable) {
47034
- const storeResult = await Bun.$`semantic-memory store ${memoryInfo.information} --metadata ${memoryInfo.metadata}`.quiet().nothrow();
47128
+ const storeResult = await Bun.$`hivemind store ${memoryInfo.information} --metadata ${memoryInfo.metadata}`.quiet().nothrow();
47035
47129
  if (storeResult.exitCode === 0) {
47036
47130
  memoryStored = true;
47037
47131
  } else {
47038
- memoryError = `semantic-memory store failed: ${storeResult.stderr.toString().slice(0, 200)}`;
47132
+ memoryError = `hivemind store failed: ${storeResult.stderr.toString().slice(0, 200)}`;
47039
47133
  console.warn(`[swarm_complete] ${memoryError}`);
47040
47134
  }
47041
47135
  } else {
47042
- memoryError = "semantic-memory not available - learning stored in-memory only";
47043
- warnMissingTool("semantic-memory");
47136
+ memoryError = "hivemind not available - learning stored in-memory only";
47137
+ warnMissingTool("hivemind");
47044
47138
  }
47045
47139
  } catch (error45) {
47046
47140
  memoryError = `Failed to store memory: ${error45 instanceof Error ? error45.message : String(error45)}`;
@@ -47063,7 +47157,7 @@ This will be recorded as a negative learning signal.`;
47063
47157
  parsedEvaluation ? `**Self-Evaluation**: ${parsedEvaluation.passed ? "PASSED" : "FAILED"}` : "",
47064
47158
  parsedEvaluation?.overall_feedback ? `**Feedback**: ${parsedEvaluation.overall_feedback}` : "",
47065
47159
  "",
47066
- `**Memory Capture**: ${memoryStored ? "✓ Stored in semantic-memory" : `✗ ${memoryError || "Failed"}`}`
47160
+ `**Memory Capture**: ${memoryStored ? "✓ Stored in hivemind" : `✗ ${memoryError || "Failed"}`}`
47067
47161
  ].filter(Boolean).join(`
47068
47162
  `);
47069
47163
  let messageSent = false;
@@ -47126,7 +47220,7 @@ Files touched: ${args.files_touched?.join(", ") || "none recorded"}`,
47126
47220
  error: memoryError,
47127
47221
  information: memoryInfo.information,
47128
47222
  metadata: memoryInfo.metadata,
47129
- note: memoryStored ? "Learning automatically stored in semantic-memory" : `Failed to store: ${memoryError}. Learning lost unless semantic-memory is available.`
47223
+ note: memoryStored ? "Learning automatically stored in hivemind" : `Failed to store: ${memoryError}. Learning lost unless hivemind is available.`
47130
47224
  },
47131
47225
  contract_validation: contractValidation ? {
47132
47226
  validated: true,
@@ -47438,7 +47532,7 @@ async function runResearchPhase(task, projectPath, options2) {
47438
47532
  research_id: researchId,
47439
47533
  tech,
47440
47534
  prompt,
47441
- subagent_type: "swarm/researcher"
47535
+ subagent_type: "swarm-researcher"
47442
47536
  });
47443
47537
  }
47444
47538
  return {
@@ -47468,7 +47562,7 @@ var swarm_research_phase = tool({
47468
47562
  summaries_collected: Object.keys(result.summaries).length,
47469
47563
  memories_stored: result.memory_ids.length
47470
47564
  },
47471
- usage_hint: "Inject summaries into shared_context for task decomposition. Each technology has documentation in semantic-memory."
47565
+ usage_hint: "Inject summaries into shared_context for task decomposition. Each technology has documentation in hivemind."
47472
47566
  }, null, 2);
47473
47567
  }
47474
47568
  });
@@ -47684,8 +47778,8 @@ var swarm_recover = tool({
47684
47778
  },
47685
47779
  async execute(args) {
47686
47780
  try {
47687
- const { getSwarmMailLibSQL: getSwarmMailLibSQL4 } = await import("swarm-mail");
47688
- const swarmMail = await getSwarmMailLibSQL4(args.project_key);
47781
+ const { getSwarmMailLibSQL: getSwarmMailLibSQL5 } = await import("swarm-mail");
47782
+ const swarmMail = await getSwarmMailLibSQL5(args.project_key);
47689
47783
  const db = await swarmMail.getDatabase();
47690
47784
  const result = await db.query(`SELECT * FROM swarm_contexts
47691
47785
  WHERE epic_id = $1
@@ -47887,7 +47981,7 @@ init_eval_capture();
47887
47981
 
47888
47982
  // src/memory-tools.ts
47889
47983
  init_dist();
47890
- import { getSwarmMailLibSQL as getSwarmMailLibSQL4, createEvent as createEvent4, appendEvent as appendEvent3 } from "swarm-mail";
47984
+ import { getSwarmMailLibSQL as getSwarmMailLibSQL5, createEvent as createEvent4, appendEvent as appendEvent3 } from "swarm-mail";
47891
47985
 
47892
47986
  // ../../node_modules/.bun/effect@3.19.12/node_modules/effect/dist/esm/Function.js
47893
47987
  var isFunction = (input) => typeof input === "function";
@@ -61504,7 +61598,7 @@ async function getMemoryAdapter(projectPath) {
61504
61598
  if (cachedAdapter && cachedProjectPath === path3) {
61505
61599
  return cachedAdapter;
61506
61600
  }
61507
- const swarmMail = await getSwarmMailLibSQL4(path3);
61601
+ const swarmMail = await getSwarmMailLibSQL5(path3);
61508
61602
  const dbAdapter = await swarmMail.getDatabase();
61509
61603
  cachedAdapter = await createMemoryAdapter(dbAdapter);
61510
61604
  cachedProjectPath = path3;
@@ -61890,10 +61984,10 @@ swarmmail_init(project_path="{project_path}", task_description="{bead_id}: {subt
61890
61984
 
61891
61985
  ### Step 2: \uD83E\uDDE0 Query Past Learnings (MANDATORY - BEFORE starting work)
61892
61986
 
61893
- **⚠️ CRITICAL: ALWAYS query semantic memory BEFORE writing ANY code.**
61987
+ **⚠️ CRITICAL: ALWAYS query hivemind BEFORE writing ANY code.**
61894
61988
 
61895
61989
  \`\`\`
61896
- semantic-memory_find(query="<keywords from your task>", limit=5, expand=true)
61990
+ hivemind_find(query="<keywords from your task>", limit=5, expand=true)
61897
61991
  \`\`\`
61898
61992
 
61899
61993
  **Why this is MANDATORY:**
@@ -61912,7 +62006,7 @@ semantic-memory_find(query="<keywords from your task>", limit=5, expand=true)
61912
62006
  - **Performance**: Search "<technology> performance optimization"
61913
62007
 
61914
62008
  **BEFORE you start coding:**
61915
- 1. Run semantic-memory_find with keywords from your task
62009
+ 1. Run hivemind_find with keywords from your task
61916
62010
  2. Read the results with expand=true for full content
61917
62011
  3. Check if any memory solves your problem or warns of pitfalls
61918
62012
  4. Adjust your approach based on past learnings
@@ -62008,7 +62102,7 @@ swarm_checkpoint(
62008
62102
  **If you learned it the hard way, STORE IT so the next agent doesn't have to.**
62009
62103
 
62010
62104
  \`\`\`
62011
- semantic-memory_store(
62105
+ hivemind_store(
62012
62106
  information="<what you learned, WHY it matters, how to apply it>",
62013
62107
  tags="<domain, tech-stack, pattern-type>"
62014
62108
  )
@@ -62065,12 +62159,12 @@ swarm_complete(
62065
62159
 
62066
62160
  If you encounter unknown API behavior or version-specific issues:
62067
62161
 
62068
- 1. **Check semantic-memory first:**
62069
- \`semantic-memory_find(query="<library> <version> <topic>", limit=3, expand=true)\`
62162
+ 1. **Check hivemind first:**
62163
+ \`hivemind_find(query="<library> <version> <topic>", limit=3, expand=true)\`
62070
62164
 
62071
62165
  2. **If not found, spawn researcher:**
62072
62166
  \`swarm_spawn_researcher(research_id="{bead_id}-research", epic_id="{epic_id}", tech_stack=["<library>"], project_path="{project_path}")\`
62073
- Then spawn with Task tool: \`Task(subagent_type="swarm/researcher", prompt="<from above>")\`
62167
+ Then spawn with Task tool: \`Task(subagent_type="swarm-researcher", prompt="<from above>")\`
62074
62168
 
62075
62169
  3. **Wait for research, then continue**
62076
62170
 
@@ -62154,20 +62248,20 @@ Other cell operations:
62154
62248
 
62155
62249
  **NON-NEGOTIABLE:**
62156
62250
  1. Step 1 (swarmmail_init) MUST be first - do it before anything else
62157
- 2. \uD83E\uDDE0 Step 2 (semantic-memory_find) MUST happen BEFORE starting work - query first, code second
62251
+ 2. \uD83E\uDDE0 Step 2 (hivemind_find) MUST happen BEFORE starting work - query first, code second
62158
62252
  3. Step 4 (swarmmail_reserve) - YOU reserve files, not coordinator
62159
62253
  4. Step 6 (swarm_progress) - Report at milestones, don't work silently
62160
- 5. \uD83D\uDCBE Step 8 (semantic-memory_store) - If you learned something hard, STORE IT
62254
+ 5. \uD83D\uDCBE Step 8 (hivemind_store) - If you learned something hard, STORE IT
62161
62255
  6. Step 9 (swarm_complete) - Use this to close, NOT hive_close
62162
62256
 
62163
62257
  **If you skip these steps:**
62164
62258
  - Your work won't be tracked (swarm_complete will fail)
62165
- - \uD83D\uDD04 You'll waste time repeating already-solved problems (no semantic memory query)
62259
+ - \uD83D\uDD04 You'll waste time repeating already-solved problems (no hivemind query)
62166
62260
  - Edit conflicts with other agents (no file reservation)
62167
62261
  - Lost work if you crash (no checkpoints)
62168
62262
  - \uD83D\uDD04 Future agents repeat YOUR mistakes (no learnings stored)
62169
62263
 
62170
- **Memory is the swarm's collective intelligence. Query it. Feed it.**
62264
+ **Hivemind is the swarm's collective intelligence. Query it. Feed it.**
62171
62265
 
62172
62266
  Begin now.`;
62173
62267
  var RESEARCHER_PROMPT = `You are a swarm researcher gathering documentation for: **{research_id}**
@@ -62224,9 +62318,9 @@ For EACH technology in the list:
62224
62318
  - Note breaking changes, new features, migration complexity
62225
62319
 
62226
62320
  ### Step 5: Store Detailed Findings
62227
- For EACH technology, store in semantic-memory:
62321
+ For EACH technology, store in hivemind:
62228
62322
  \`\`\`
62229
- semantic-memory_store(
62323
+ hivemind_store(
62230
62324
  information="<technology-name> <version>: <key patterns, gotchas, API changes, compatibility notes>",
62231
62325
  tags="research, <tech-name>, documentation, {epic_id}"
62232
62326
  )
@@ -62240,7 +62334,7 @@ Send condensed findings to coordinator:
62240
62334
  swarmmail_send(
62241
62335
  to=["coordinator"],
62242
62336
  subject="Research Complete: {research_id}",
62243
- body="<brief summary - see semantic-memory for details>",
62337
+ body="<brief summary - see hivemind for details>",
62244
62338
  thread_id="{epic_id}"
62245
62339
  )
62246
62340
  \`\`\`
@@ -62257,7 +62351,7 @@ Output JSON with:
62257
62351
  "key_patterns": ["string"],
62258
62352
  "gotchas": ["string"],
62259
62353
  "breaking_changes": ["string"], // Only if --check-upgrades
62260
- "memory_id": "string" // ID of semantic-memory entry
62354
+ "memory_id": "string" // ID of hivemind entry
62261
62355
  }
62262
62356
  ],
62263
62357
  "summary": "string" // Condensed summary for shared_context
@@ -62270,12 +62364,12 @@ Output JSON with:
62270
62364
  1. Step 1 (swarmmail_init) MUST be first
62271
62365
  2. Research ONLY the technologies the coordinator specified
62272
62366
  3. Fetch docs for INSTALLED versions (unless --check-upgrades)
62273
- 4. Store detailed findings in semantic-memory (one per technology)
62367
+ 4. Store detailed findings in hivemind (one per technology)
62274
62368
  5. Return condensed summary for coordinator (full details in memory)
62275
62369
  6. Use appropriate doc tools (nextjs_docs for Next.js, context7 for libraries, etc.)
62276
62370
 
62277
62371
  **Output goes TWO places:**
62278
- - **semantic-memory**: Detailed findings (searchable by future agents)
62372
+ - **hivemind**: Detailed findings (searchable by future agents)
62279
62373
  - **Return JSON**: Condensed summary (for coordinator's shared_context)
62280
62374
 
62281
62375
  Begin research now.`;
@@ -62478,7 +62572,7 @@ async function getWorkerInsights(files, domain2) {
62478
62572
  ${learnings.join(`
62479
62573
  `)}
62480
62574
 
62481
- **Check semantic-memory for full details if needed.**`;
62575
+ **Check hivemind for full details if needed.**`;
62482
62576
  }
62483
62577
  const sections = [formattedFileInsights, formattedMemory].filter((s) => s.length > 0);
62484
62578
  if (sections.length === 0) {
@@ -62708,7 +62802,7 @@ var swarm_spawn_subtask = tool({
62708
62802
  }
62709
62803
  });
62710
62804
  var swarm_spawn_researcher = tool({
62711
- description: "Prepare a research task for spawning. Returns prompt for gathering technology documentation. Researcher fetches docs and stores findings in semantic-memory.",
62805
+ description: "Prepare a research task for spawning. Returns prompt for gathering technology documentation. Researcher fetches docs and stores findings in hivemind.",
62712
62806
  args: {
62713
62807
  research_id: tool.schema.string().describe("Unique ID for this research task"),
62714
62808
  epic_id: tool.schema.string().describe("Parent epic ID"),
@@ -62731,7 +62825,7 @@ var swarm_spawn_researcher = tool({
62731
62825
  tech_stack: args2.tech_stack,
62732
62826
  project_path: args2.project_path,
62733
62827
  check_upgrades: args2.check_upgrades ?? false,
62734
- subagent_type: "swarm/researcher",
62828
+ subagent_type: "swarm-researcher",
62735
62829
  expected_output: {
62736
62830
  technologies: [
62737
62831
  {
@@ -63049,11 +63143,6 @@ var TOOL_DEFINITIONS = [
63049
63143
  name: "pdf-brain",
63050
63144
  type: "mcp",
63051
63145
  capabilities: ["knowledge-base-search", "internal-docs"]
63052
- },
63053
- {
63054
- name: "semantic-memory",
63055
- type: "cli",
63056
- capabilities: ["storage", "semantic-search", "persistence"]
63057
63146
  }
63058
63147
  ];
63059
63148
  function stripSemverConstraint(versionStr) {
@@ -64362,13 +64451,302 @@ var mandateTools = {
64362
64451
  mandate_stats
64363
64452
  };
64364
64453
 
64454
+ // src/hivemind-tools.ts
64455
+ init_dist();
64456
+ import {
64457
+ getSwarmMailLibSQL as getSwarmMailLibSQL6,
64458
+ createEvent as createEvent5,
64459
+ SessionIndexer,
64460
+ syncMemories as syncMemories2,
64461
+ toSwarmDb as toSwarmDb2,
64462
+ makeOllamaLive as makeOllamaLive2
64463
+ } from "swarm-mail";
64464
+ import * as os2 from "node:os";
64465
+ import * as path3 from "node:path";
64466
+ import { join as join12 } from "node:path";
64467
+ var cachedAdapter2 = null;
64468
+ var cachedIndexer = null;
64469
+ var cachedProjectPath2 = null;
64470
+ async function getMemoryAdapter2(projectPath) {
64471
+ const path4 = projectPath || process.cwd();
64472
+ if (cachedAdapter2 && cachedProjectPath2 === path4) {
64473
+ return cachedAdapter2;
64474
+ }
64475
+ const swarmMail = await getSwarmMailLibSQL6(path4);
64476
+ const dbAdapter = await swarmMail.getDatabase();
64477
+ cachedAdapter2 = await createMemoryAdapter(dbAdapter);
64478
+ cachedProjectPath2 = path4;
64479
+ return cachedAdapter2;
64480
+ }
64481
+ async function getSessionIndexer(projectPath) {
64482
+ const path4 = projectPath || process.cwd();
64483
+ if (cachedIndexer && cachedProjectPath2 === path4) {
64484
+ return cachedIndexer;
64485
+ }
64486
+ const swarmMail = await getSwarmMailLibSQL6(path4);
64487
+ const dbAdapter = await swarmMail.getDatabase();
64488
+ const db = toSwarmDb2(dbAdapter);
64489
+ const ollamaLayer = makeOllamaLive2({
64490
+ ollamaHost: process.env.OLLAMA_HOST || "http://localhost:11434",
64491
+ ollamaModel: process.env.OLLAMA_MODEL || "mxbai-embed-large"
64492
+ });
64493
+ cachedIndexer = new SessionIndexer(db, ollamaLayer);
64494
+ cachedProjectPath2 = path4;
64495
+ return cachedIndexer;
64496
+ }
64497
+ var getHivemindAdapter = getMemoryAdapter2;
64498
+ async function emitEvent(eventType, data) {
64499
+ try {
64500
+ const projectPath = cachedProjectPath2 || process.cwd();
64501
+ const swarmMail = await getSwarmMailLibSQL6(projectPath);
64502
+ const event = createEvent5(eventType, {
64503
+ project_key: projectPath,
64504
+ ...data
64505
+ });
64506
+ await swarmMail.appendEvent(event);
64507
+ } catch {}
64508
+ }
64509
+ var AGENT_DIRECTORIES = [
64510
+ path3.join(os2.homedir(), ".config", "swarm-tools", "sessions"),
64511
+ path3.join(os2.homedir(), ".opencode"),
64512
+ path3.join(os2.homedir(), "Cursor", "User", "History"),
64513
+ path3.join(os2.homedir(), ".local", "share", "Claude"),
64514
+ path3.join(os2.homedir(), ".aider")
64515
+ ];
64516
+ var hivemind_store = tool({
64517
+ 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.",
64518
+ args: {
64519
+ information: tool.schema.string().describe("The information to store (required)"),
64520
+ collection: tool.schema.string().optional().describe("Collection name (defaults to 'default')"),
64521
+ tags: tool.schema.string().optional().describe("Comma-separated tags (e.g., 'auth,tokens,oauth')"),
64522
+ metadata: tool.schema.string().optional().describe("JSON string with additional metadata"),
64523
+ confidence: tool.schema.number().optional().describe("Confidence level (0.0-1.0) affecting decay rate. Default 0.7"),
64524
+ autoTag: tool.schema.boolean().optional().describe("Auto-generate tags using LLM. Default false"),
64525
+ autoLink: tool.schema.boolean().optional().describe("Auto-link to related memories. Default false"),
64526
+ extractEntities: tool.schema.boolean().optional().describe("Extract entities (people, places, technologies). Default false")
64527
+ },
64528
+ async execute(args2, ctx) {
64529
+ const adapter = await getMemoryAdapter2();
64530
+ const result = await adapter.store(args2);
64531
+ await emitEvent("memory_stored", {
64532
+ memory_id: result.id,
64533
+ content_preview: args2.information.slice(0, 100),
64534
+ tags: args2.tags ? args2.tags.split(",").map((t) => t.trim()) : [],
64535
+ collection: args2.collection || "default"
64536
+ });
64537
+ return JSON.stringify(result, null, 2);
64538
+ }
64539
+ });
64540
+ var hivemind_find = tool({
64541
+ 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).",
64542
+ args: {
64543
+ query: tool.schema.string().describe("Search query (required)"),
64544
+ limit: tool.schema.number().optional().describe("Maximum number of results (default: 10)"),
64545
+ collection: tool.schema.string().optional().describe("Filter by collection (e.g., 'default', 'claude', 'cursor')"),
64546
+ expand: tool.schema.boolean().optional().describe("Return full content instead of truncated preview (default: false)"),
64547
+ fts: tool.schema.boolean().optional().describe("Use full-text search instead of vector search (default: false)")
64548
+ },
64549
+ async execute(args2, ctx) {
64550
+ const startTime = Date.now();
64551
+ const adapter = await getMemoryAdapter2();
64552
+ const result = await adapter.find(args2);
64553
+ const duration3 = Date.now() - startTime;
64554
+ await emitEvent("memory_found", {
64555
+ query: args2.query,
64556
+ result_count: result.results.length,
64557
+ top_score: result.results.length > 0 ? result.results[0].score : undefined,
64558
+ search_duration_ms: duration3,
64559
+ collection_filter: args2.collection
64560
+ });
64561
+ return JSON.stringify(result, null, 2);
64562
+ }
64563
+ });
64564
+ var hivemind_get = tool({
64565
+ description: "Retrieve a specific memory by its ID. Works for both learnings and session memories.",
64566
+ args: {
64567
+ id: tool.schema.string().describe("Memory ID (required)")
64568
+ },
64569
+ async execute(args2, ctx) {
64570
+ const adapter = await getMemoryAdapter2();
64571
+ const memory = await adapter.get(args2);
64572
+ return memory ? JSON.stringify(memory, null, 2) : "Memory not found";
64573
+ }
64574
+ });
64575
+ var hivemind_remove = tool({
64576
+ description: "Delete a memory by ID. Use this to remove outdated or incorrect memories.",
64577
+ args: {
64578
+ id: tool.schema.string().describe("Memory ID (required)")
64579
+ },
64580
+ async execute(args2, ctx) {
64581
+ const adapter = await getMemoryAdapter2();
64582
+ const result = await adapter.remove(args2);
64583
+ if (result.success) {
64584
+ await emitEvent("memory_deleted", {
64585
+ memory_id: args2.id
64586
+ });
64587
+ }
64588
+ return JSON.stringify(result, null, 2);
64589
+ }
64590
+ });
64591
+ var hivemind_validate = tool({
64592
+ 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.",
64593
+ args: {
64594
+ id: tool.schema.string().describe("Memory ID (required)")
64595
+ },
64596
+ async execute(args2, ctx) {
64597
+ const adapter = await getMemoryAdapter2();
64598
+ const result = await adapter.validate(args2);
64599
+ if (result.success) {
64600
+ await emitEvent("memory_validated", {
64601
+ memory_id: args2.id,
64602
+ decay_reset: true
64603
+ });
64604
+ }
64605
+ return JSON.stringify(result, null, 2);
64606
+ }
64607
+ });
64608
+ var hivemind_stats = tool({
64609
+ description: "Get statistics about stored memories, embeddings, and system health. Shows counts by collection (learnings vs sessions) and Ollama availability.",
64610
+ args: {},
64611
+ async execute(args2, ctx) {
64612
+ const adapter = await getMemoryAdapter2();
64613
+ const stats = await adapter.stats();
64614
+ const health = await adapter.checkHealth();
64615
+ let sessionStats = {};
64616
+ try {
64617
+ const indexer = await getSessionIndexer();
64618
+ sessionStats = await exports_Effect.runPromise(indexer.getStats());
64619
+ } catch {}
64620
+ return JSON.stringify({
64621
+ ...stats,
64622
+ healthy: health.ollama,
64623
+ ollama_available: health.ollama,
64624
+ sessions: sessionStats
64625
+ }, null, 2);
64626
+ }
64627
+ });
64628
+ var hivemind_index = tool({
64629
+ 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.",
64630
+ args: {
64631
+ full: tool.schema.boolean().optional().describe("Force full rebuild (default: incremental)")
64632
+ },
64633
+ async execute(args2, ctx) {
64634
+ const startTime = Date.now();
64635
+ try {
64636
+ const indexer = await getSessionIndexer();
64637
+ const allResults = [];
64638
+ for (const dir of AGENT_DIRECTORIES) {
64639
+ try {
64640
+ const options2 = {
64641
+ recursive: true
64642
+ };
64643
+ const results = await exports_Effect.runPromise(indexer.indexDirectory(dir, options2).pipe(exports_Effect.catchAll((error45) => {
64644
+ return exports_Effect.succeed([]);
64645
+ })));
64646
+ allResults.push(...results);
64647
+ } catch {}
64648
+ }
64649
+ const totalIndexed = allResults.reduce((sum2, r) => sum2 + r.indexed, 0);
64650
+ const totalSkipped = allResults.reduce((sum2, r) => sum2 + r.skipped, 0);
64651
+ await emitEvent("sessions_indexed", {
64652
+ sessions_indexed: allResults.length,
64653
+ messages_indexed: totalIndexed,
64654
+ duration_ms: Date.now() - startTime,
64655
+ full_rebuild: args2.full ?? false
64656
+ });
64657
+ return `Indexed ${allResults.length} sessions with ${totalIndexed} chunks (${totalSkipped} skipped) in ${Date.now() - startTime}ms`;
64658
+ } catch (error45) {
64659
+ return JSON.stringify({
64660
+ error: error45 instanceof Error ? error45.message : String(error45)
64661
+ });
64662
+ }
64663
+ }
64664
+ });
64665
+ var hivemind_sync = tool({
64666
+ description: "Sync memories to .hive/memories.jsonl for git-based sharing. Team members can sync their local databases from the JSONL file.",
64667
+ args: {},
64668
+ async execute(args2, ctx) {
64669
+ try {
64670
+ const projectPath = cachedProjectPath2 || process.cwd();
64671
+ const swarmMail = await getSwarmMailLibSQL6(projectPath);
64672
+ const dbAdapter = await swarmMail.getDatabase();
64673
+ const hiveDir = join12(projectPath, ".hive");
64674
+ const result = await syncMemories2(dbAdapter, hiveDir);
64675
+ await emitEvent("memories_synced", {
64676
+ imported: result.imported.created,
64677
+ exported: result.exported
64678
+ });
64679
+ return JSON.stringify({
64680
+ success: true,
64681
+ imported: result.imported.created,
64682
+ exported: result.exported,
64683
+ message: `Synced: imported ${result.imported.created}, exported ${result.exported} memories`
64684
+ }, null, 2);
64685
+ } catch (error45) {
64686
+ return JSON.stringify({
64687
+ success: false,
64688
+ error: error45 instanceof Error ? error45.message : String(error45)
64689
+ });
64690
+ }
64691
+ }
64692
+ });
64693
+ function createDeprecatedAlias(newToolName, oldToolName, tool3) {
64694
+ return {
64695
+ ...tool3,
64696
+ execute: async (args2, ctx) => {
64697
+ console.warn(`[DEPRECATED] ${oldToolName} is deprecated. Use ${newToolName} instead.`);
64698
+ return tool3.execute(args2, ctx);
64699
+ }
64700
+ };
64701
+ }
64702
+ var semantic_memory_store2 = createDeprecatedAlias("hivemind_store", "semantic-memory_store", hivemind_store);
64703
+ var semantic_memory_find2 = createDeprecatedAlias("hivemind_find", "semantic-memory_find", hivemind_find);
64704
+ var semantic_memory_get2 = createDeprecatedAlias("hivemind_get", "semantic-memory_get", hivemind_get);
64705
+ var semantic_memory_remove2 = createDeprecatedAlias("hivemind_remove", "semantic-memory_remove", hivemind_remove);
64706
+ var semantic_memory_validate2 = createDeprecatedAlias("hivemind_validate", "semantic-memory_validate", hivemind_validate);
64707
+ var semantic_memory_list2 = createDeprecatedAlias("hivemind_find", "semantic-memory_list", hivemind_find);
64708
+ var semantic_memory_stats2 = createDeprecatedAlias("hivemind_stats", "semantic-memory_stats", hivemind_stats);
64709
+ var semantic_memory_check2 = createDeprecatedAlias("hivemind_stats", "semantic-memory_check", hivemind_stats);
64710
+ var semantic_memory_upsert2 = createDeprecatedAlias("hivemind_store", "semantic-memory_upsert", hivemind_store);
64711
+ var cass_search = createDeprecatedAlias("hivemind_find", "cass_search", hivemind_find);
64712
+ var cass_view = createDeprecatedAlias("hivemind_get", "cass_view", hivemind_get);
64713
+ var cass_expand = createDeprecatedAlias("hivemind_get", "cass_expand", hivemind_get);
64714
+ var cass_health = createDeprecatedAlias("hivemind_stats", "cass_health", hivemind_stats);
64715
+ var cass_index = createDeprecatedAlias("hivemind_index", "cass_index", hivemind_index);
64716
+ var cass_stats = createDeprecatedAlias("hivemind_stats", "cass_stats", hivemind_stats);
64717
+ var hivemindTools = {
64718
+ hivemind_store,
64719
+ hivemind_find,
64720
+ hivemind_get,
64721
+ hivemind_remove,
64722
+ hivemind_validate,
64723
+ hivemind_stats,
64724
+ hivemind_index,
64725
+ hivemind_sync,
64726
+ "semantic-memory_store": semantic_memory_store2,
64727
+ "semantic-memory_find": semantic_memory_find2,
64728
+ "semantic-memory_get": semantic_memory_get2,
64729
+ "semantic-memory_remove": semantic_memory_remove2,
64730
+ "semantic-memory_validate": semantic_memory_validate2,
64731
+ "semantic-memory_list": semantic_memory_list2,
64732
+ "semantic-memory_stats": semantic_memory_stats2,
64733
+ "semantic-memory_check": semantic_memory_check2,
64734
+ "semantic-memory_upsert": semantic_memory_upsert2,
64735
+ cass_search,
64736
+ cass_view,
64737
+ cass_expand,
64738
+ cass_health,
64739
+ cass_index,
64740
+ cass_stats
64741
+ };
64742
+
64365
64743
  // src/observability-tools.ts
64366
64744
  init_dist();
64367
64745
  import {
64368
64746
  agentActivity,
64369
64747
  checkpointFrequency,
64370
64748
  failedDecompositions,
64371
- getSwarmMailLibSQL as getSwarmMailLibSQL5,
64749
+ getSwarmMailLibSQL as getSwarmMailLibSQL7,
64372
64750
  humanFeedback,
64373
64751
  lockContention,
64374
64752
  messageLatency,
@@ -64433,7 +64811,7 @@ var swarm_analytics = tool({
64433
64811
  async execute(args2) {
64434
64812
  try {
64435
64813
  const projectPath = process.cwd();
64436
- const db = await getSwarmMailLibSQL5(projectPath);
64814
+ const db = await getSwarmMailLibSQL7(projectPath);
64437
64815
  const filters = {
64438
64816
  project_key: projectPath
64439
64817
  };
@@ -64503,7 +64881,7 @@ var swarm_query = tool({
64503
64881
  async execute(args2) {
64504
64882
  try {
64505
64883
  const projectPath = process.cwd();
64506
- const swarmMail = await getSwarmMailLibSQL5(projectPath);
64884
+ const swarmMail = await getSwarmMailLibSQL7(projectPath);
64507
64885
  const db = await swarmMail.getDatabase();
64508
64886
  if (!args2.sql.trim().toLowerCase().startsWith("select")) {
64509
64887
  return JSON.stringify({
@@ -64553,7 +64931,7 @@ var swarm_diagnose = tool({
64553
64931
  async execute(args2) {
64554
64932
  try {
64555
64933
  const projectPath = process.cwd();
64556
- const swarmMail = await getSwarmMailLibSQL5(projectPath);
64934
+ const swarmMail = await getSwarmMailLibSQL7(projectPath);
64557
64935
  const db = await swarmMail.getDatabase();
64558
64936
  const diagnosis = [];
64559
64937
  const include = args2.include || [
@@ -64591,10 +64969,10 @@ var swarm_diagnose = tool({
64591
64969
  }
64592
64970
  if (include.includes("errors")) {
64593
64971
  const errorQuery = `
64594
- SELECT type, json_extract(data, '$.error_count') as error_count
64972
+ SELECT type, json_extract(data, '$.success') as success
64595
64973
  FROM events
64596
64974
  WHERE type = 'subtask_outcome'
64597
- AND json_extract(data, '$.success') = 'false'
64975
+ AND json_extract(data, '$.success') = 0
64598
64976
  ${args2.epic_id ? "AND json_extract(data, '$.epic_id') = ?" : ""}
64599
64977
  ${args2.bead_id ? "AND json_extract(data, '$.bead_id') = ?" : ""}
64600
64978
  LIMIT 10
@@ -64664,13 +65042,13 @@ var swarm_insights = tool({
64664
65042
  });
64665
65043
  }
64666
65044
  const projectPath = process.cwd();
64667
- const swarmMail = await getSwarmMailLibSQL5(projectPath);
65045
+ const swarmMail = await getSwarmMailLibSQL7(projectPath);
64668
65046
  const db = await swarmMail.getDatabase();
64669
65047
  const insights = [];
64670
65048
  if (args2.metrics.includes("success_rate")) {
64671
65049
  const query = `
64672
65050
  SELECT
64673
- SUM(CASE WHEN json_extract(data, '$.success') = 'true' THEN 1 ELSE 0 END) as successes,
65051
+ SUM(CASE WHEN json_extract(data, '$.success') = 1 THEN 1 ELSE 0 END) as successes,
64674
65052
  COUNT(*) as total
64675
65053
  FROM events
64676
65054
  WHERE type = 'subtask_outcome'
@@ -64692,6 +65070,8 @@ var swarm_insights = tool({
64692
65070
  SELECT AVG(CAST(json_extract(data, '$.duration_ms') AS REAL)) as avg_duration
64693
65071
  FROM events
64694
65072
  WHERE type = 'subtask_outcome'
65073
+ AND json_extract(data, '$.success') = 1
65074
+ AND json_extract(data, '$.duration_ms') IS NOT NULL
64695
65075
  ${args2.epic_id ? "AND json_extract(data, '$.epic_id') = ?" : ""}
64696
65076
  `;
64697
65077
  const result = await db.query(query, args2.epic_id ? [args2.epic_id] : []);
@@ -64757,7 +65137,7 @@ function formatCreditLine(user, issueNumber) {
64757
65137
  }
64758
65138
  async function storeContributorMemory(user, issueNumber) {
64759
65139
  try {
64760
- const adapter = await getMemoryAdapter();
65140
+ const adapter = await getHivemindAdapter();
64761
65141
  const twitterPart = user.twitter_username ? ` (@${user.twitter_username} on Twitter)` : "";
64762
65142
  const issuePart = issueNumber ? `. Filed issue #${issueNumber}` : "";
64763
65143
  const bioPart = user.bio ? `. Bio: '${user.bio}'` : "";
@@ -64815,268 +65195,6 @@ var contributorTools = {
64815
65195
  contributor_lookup
64816
65196
  };
64817
65197
 
64818
- // src/cass-tools.ts
64819
- init_dist();
64820
- import { execSync, spawn } from "child_process";
64821
- import { getSwarmMailLibSQL as getSwarmMailLibSQL6, createEvent as createEvent5 } from "swarm-mail";
64822
- function isCassAvailable() {
64823
- try {
64824
- execSync("which cass", { stdio: "ignore" });
64825
- return true;
64826
- } catch {
64827
- return false;
64828
- }
64829
- }
64830
- async function execCass(args2) {
64831
- return new Promise((resolve2, reject) => {
64832
- const proc = spawn("cass", args2, {
64833
- stdio: ["ignore", "pipe", "pipe"]
64834
- });
64835
- let stdout = "";
64836
- let stderr = "";
64837
- proc.stdout.on("data", (data) => {
64838
- stdout += data;
64839
- });
64840
- proc.stderr.on("data", (data) => {
64841
- stderr += data;
64842
- });
64843
- proc.on("close", (code) => {
64844
- if (code === 0) {
64845
- resolve2(stdout);
64846
- } else {
64847
- reject(new Error(stderr || `cass exited with code ${code}`));
64848
- }
64849
- });
64850
- proc.on("error", (err) => {
64851
- if (err.code === "ENOENT") {
64852
- reject(new Error("cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"));
64853
- } else {
64854
- reject(err);
64855
- }
64856
- });
64857
- });
64858
- }
64859
- async function emitEvent(eventType, data) {
64860
- try {
64861
- const projectPath = process.cwd();
64862
- const swarmMail = await getSwarmMailLibSQL6(projectPath);
64863
- const event = createEvent5(eventType, {
64864
- project_key: projectPath,
64865
- ...data
64866
- });
64867
- await swarmMail.appendEvent(event);
64868
- } catch {}
64869
- }
64870
- var cass_search = tool({
64871
- 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.",
64872
- args: {
64873
- query: tool.schema.string().describe("Search query (e.g., 'authentication error Next.js')"),
64874
- agent: tool.schema.string().optional().describe("Filter by agent name (e.g., 'claude', 'cursor')"),
64875
- days: tool.schema.number().optional().describe("Only search sessions from last N days"),
64876
- limit: tool.schema.number().optional().describe("Max results to return (default: 5)"),
64877
- fields: tool.schema.string().optional().describe("Field selection: 'minimal' for compact output (path, line, agent only)")
64878
- },
64879
- async execute(args2) {
64880
- const startTime = Date.now();
64881
- if (!isCassAvailable()) {
64882
- return JSON.stringify({
64883
- error: "cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"
64884
- });
64885
- }
64886
- try {
64887
- const cliArgs = ["search", args2.query];
64888
- if (args2.agent) {
64889
- cliArgs.push("--agent", args2.agent);
64890
- }
64891
- if (args2.days) {
64892
- cliArgs.push("--days", String(args2.days));
64893
- }
64894
- if (args2.limit) {
64895
- cliArgs.push("--limit", String(args2.limit));
64896
- }
64897
- if (args2.fields === "minimal") {
64898
- cliArgs.push("--minimal");
64899
- }
64900
- const output = await execCass(cliArgs);
64901
- const lines = output.trim().split(`
64902
- `).filter((l) => l.trim());
64903
- const resultCount = lines.length;
64904
- await emitEvent("cass_searched", {
64905
- query: args2.query,
64906
- agent_filter: args2.agent,
64907
- days_filter: args2.days,
64908
- result_count: resultCount,
64909
- search_duration_ms: Date.now() - startTime
64910
- });
64911
- return output;
64912
- } catch (error45) {
64913
- return JSON.stringify({
64914
- error: error45 instanceof Error ? error45.message : String(error45)
64915
- });
64916
- }
64917
- }
64918
- });
64919
- var cass_view = tool({
64920
- description: "View a specific conversation/session from search results. Use source_path from cass_search output.",
64921
- args: {
64922
- path: tool.schema.string().describe("Path to session file (from cass_search results)"),
64923
- line: tool.schema.number().optional().describe("Jump to specific line number")
64924
- },
64925
- async execute(args2) {
64926
- if (!isCassAvailable()) {
64927
- return JSON.stringify({
64928
- error: "cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"
64929
- });
64930
- }
64931
- try {
64932
- const cliArgs = ["view", args2.path];
64933
- if (args2.line) {
64934
- cliArgs.push("--line", String(args2.line));
64935
- }
64936
- const output = await execCass(cliArgs);
64937
- let agentType;
64938
- if (args2.path.includes("claude"))
64939
- agentType = "claude";
64940
- else if (args2.path.includes("cursor"))
64941
- agentType = "cursor";
64942
- else if (args2.path.includes("opencode"))
64943
- agentType = "opencode";
64944
- else if (args2.path.includes("codex"))
64945
- agentType = "codex";
64946
- await emitEvent("cass_viewed", {
64947
- session_path: args2.path,
64948
- line_number: args2.line,
64949
- agent_type: agentType
64950
- });
64951
- return output;
64952
- } catch (error45) {
64953
- return JSON.stringify({
64954
- error: error45 instanceof Error ? error45.message : String(error45)
64955
- });
64956
- }
64957
- }
64958
- });
64959
- var cass_expand = tool({
64960
- description: "Expand context around a specific line in a session. Shows messages before/after.",
64961
- args: {
64962
- path: tool.schema.string().describe("Path to session file"),
64963
- line: tool.schema.number().describe("Line number to expand around"),
64964
- context: tool.schema.number().optional().describe("Number of lines before/after to show (default: 5)")
64965
- },
64966
- async execute(args2) {
64967
- if (!isCassAvailable()) {
64968
- return JSON.stringify({
64969
- error: "cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"
64970
- });
64971
- }
64972
- try {
64973
- const cliArgs = ["expand", args2.path, "--line", String(args2.line)];
64974
- if (args2.context) {
64975
- cliArgs.push("--context", String(args2.context));
64976
- }
64977
- const output = await execCass(cliArgs);
64978
- await emitEvent("cass_viewed", {
64979
- session_path: args2.path,
64980
- line_number: args2.line
64981
- });
64982
- return output;
64983
- } catch (error45) {
64984
- return JSON.stringify({
64985
- error: error45 instanceof Error ? error45.message : String(error45)
64986
- });
64987
- }
64988
- }
64989
- });
64990
- var cass_health = tool({
64991
- description: "Check if cass index is healthy. Exit 0 = ready, Exit 1 = needs indexing. Run this before searching.",
64992
- args: {},
64993
- async execute() {
64994
- if (!isCassAvailable()) {
64995
- return JSON.stringify({
64996
- healthy: false,
64997
- error: "cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"
64998
- });
64999
- }
65000
- try {
65001
- await execCass(["health"]);
65002
- return JSON.stringify({ healthy: true, message: "Index is ready" });
65003
- } catch (error45) {
65004
- return JSON.stringify({
65005
- healthy: false,
65006
- message: "Index needs rebuilding. Run cass_index()",
65007
- error: error45 instanceof Error ? error45.message : String(error45)
65008
- });
65009
- }
65010
- }
65011
- });
65012
- var cass_index = tool({
65013
- description: "Build or rebuild the search index. Run this if health check fails or to pick up new sessions.",
65014
- args: {
65015
- full: tool.schema.boolean().optional().describe("Force full rebuild (default: incremental)")
65016
- },
65017
- async execute(args2) {
65018
- const startTime = Date.now();
65019
- if (!isCassAvailable()) {
65020
- return JSON.stringify({
65021
- error: "cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"
65022
- });
65023
- }
65024
- try {
65025
- const cliArgs = ["index"];
65026
- if (args2.full) {
65027
- cliArgs.push("--full");
65028
- }
65029
- const output = await execCass(cliArgs);
65030
- let sessionsIndexed = 0;
65031
- let messagesIndexed = 0;
65032
- const sessionsMatch = output.match(/(\d+)\s*sessions?/i);
65033
- const messagesMatch = output.match(/(\d+)\s*messages?/i);
65034
- if (sessionsMatch)
65035
- sessionsIndexed = parseInt(sessionsMatch[1], 10);
65036
- if (messagesMatch)
65037
- messagesIndexed = parseInt(messagesMatch[1], 10);
65038
- await emitEvent("cass_indexed", {
65039
- sessions_indexed: sessionsIndexed,
65040
- messages_indexed: messagesIndexed,
65041
- duration_ms: Date.now() - startTime,
65042
- full_rebuild: args2.full ?? false
65043
- });
65044
- return output;
65045
- } catch (error45) {
65046
- return JSON.stringify({
65047
- error: error45 instanceof Error ? error45.message : String(error45)
65048
- });
65049
- }
65050
- }
65051
- });
65052
- var cass_stats = tool({
65053
- description: "Show index statistics - how many sessions, messages, agents indexed.",
65054
- args: {},
65055
- async execute() {
65056
- if (!isCassAvailable()) {
65057
- return JSON.stringify({
65058
- error: "cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"
65059
- });
65060
- }
65061
- try {
65062
- const output = await execCass(["stats"]);
65063
- return output;
65064
- } catch (error45) {
65065
- return JSON.stringify({
65066
- error: error45 instanceof Error ? error45.message : String(error45)
65067
- });
65068
- }
65069
- }
65070
- });
65071
- var cassTools = {
65072
- cass_search,
65073
- cass_view,
65074
- cass_expand,
65075
- cass_health,
65076
- cass_index,
65077
- cass_stats
65078
- };
65079
-
65080
65198
  // src/output-guardrails.ts
65081
65199
  var DEFAULT_GUARDRAIL_CONFIG = {
65082
65200
  defaultMaxChars: 32000,
@@ -65420,35 +65538,75 @@ function detectCoordinatorViolation(params) {
65420
65538
  payload
65421
65539
  };
65422
65540
  }
65541
+ if (toolName === "swarm_complete" || toolName === "hive_close") {
65542
+ const payload = { tool: toolName };
65543
+ captureCoordinatorEvent({
65544
+ session_id: sessionId,
65545
+ epic_id: epicId,
65546
+ timestamp: new Date().toISOString(),
65547
+ event_type: "VIOLATION",
65548
+ violation_type: "worker_completed_without_review",
65549
+ payload
65550
+ });
65551
+ return {
65552
+ isViolation: true,
65553
+ violationType: "worker_completed_without_review",
65554
+ message: `⚠️ Coordinator should not complete worker tasks directly. Coordinators should review worker output using swarm_review and swarm_review_feedback.`,
65555
+ payload
65556
+ };
65557
+ }
65423
65558
  return { isViolation: false };
65424
65559
  }
65425
- var coordinatorContext = {
65560
+ var coordinatorContexts = new Map;
65561
+ var globalCoordinatorContext = {
65426
65562
  isCoordinator: false
65427
65563
  };
65428
65564
  function setCoordinatorContext(ctx) {
65429
- coordinatorContext = {
65430
- ...coordinatorContext,
65431
- ...ctx,
65432
- activatedAt: ctx.isCoordinator ? Date.now() : coordinatorContext.activatedAt
65433
- };
65565
+ const sessionId = ctx.sessionId;
65566
+ if (sessionId) {
65567
+ const existing = coordinatorContexts.get(sessionId) || { isCoordinator: false };
65568
+ coordinatorContexts.set(sessionId, {
65569
+ ...existing,
65570
+ ...ctx,
65571
+ activatedAt: ctx.isCoordinator ? Date.now() : existing.activatedAt
65572
+ });
65573
+ } else {
65574
+ globalCoordinatorContext = {
65575
+ ...globalCoordinatorContext,
65576
+ ...ctx,
65577
+ activatedAt: ctx.isCoordinator ? Date.now() : globalCoordinatorContext.activatedAt
65578
+ };
65579
+ }
65434
65580
  }
65435
- function getCoordinatorContext() {
65436
- return { ...coordinatorContext };
65581
+ function getCoordinatorContext(sessionId) {
65582
+ if (sessionId) {
65583
+ return { ...coordinatorContexts.get(sessionId) || { isCoordinator: false } };
65584
+ }
65585
+ return { ...globalCoordinatorContext };
65437
65586
  }
65438
- function clearCoordinatorContext() {
65439
- coordinatorContext = {
65440
- isCoordinator: false
65441
- };
65587
+ function clearCoordinatorContext(sessionId) {
65588
+ if (sessionId) {
65589
+ coordinatorContexts.delete(sessionId);
65590
+ } else {
65591
+ globalCoordinatorContext = {
65592
+ isCoordinator: false
65593
+ };
65594
+ }
65442
65595
  }
65443
- function isInCoordinatorContext() {
65444
- if (!coordinatorContext.isCoordinator) {
65596
+ function isInCoordinatorContext(sessionId) {
65597
+ const ctx = sessionId ? coordinatorContexts.get(sessionId) : globalCoordinatorContext;
65598
+ if (!ctx || !ctx.isCoordinator) {
65445
65599
  return false;
65446
65600
  }
65447
65601
  const COORDINATOR_TIMEOUT_MS = 4 * 60 * 60 * 1000;
65448
- if (coordinatorContext.activatedAt) {
65449
- const elapsed = Date.now() - coordinatorContext.activatedAt;
65602
+ if (ctx.activatedAt) {
65603
+ const elapsed = Date.now() - ctx.activatedAt;
65450
65604
  if (elapsed > COORDINATOR_TIMEOUT_MS) {
65451
- clearCoordinatorContext();
65605
+ if (sessionId) {
65606
+ coordinatorContexts.delete(sessionId);
65607
+ } else {
65608
+ globalCoordinatorContext = { isCoordinator: false };
65609
+ }
65452
65610
  return false;
65453
65611
  }
65454
65612
  }
@@ -65570,9 +65728,9 @@ function getMetricsSummary(metrics) {
65570
65728
  // src/logger.ts
65571
65729
  var import_pino = __toESM(require_pino(), 1);
65572
65730
  import { mkdirSync as mkdirSync5, existsSync as existsSync8 } from "node:fs";
65573
- import { join as join11 } from "node:path";
65574
- import { homedir as homedir3 } from "node:os";
65575
- var DEFAULT_LOG_DIR = join11(homedir3(), ".config", "swarm-tools", "logs");
65731
+ import { join as join13 } from "node:path";
65732
+ import { homedir as homedir4 } from "node:os";
65733
+ var DEFAULT_LOG_DIR = join13(homedir4(), ".config", "swarm-tools", "logs");
65576
65734
  function ensureLogDir(logDir) {
65577
65735
  if (!existsSync8(logDir)) {
65578
65736
  mkdirSync5(logDir, { recursive: true });
@@ -65591,7 +65749,7 @@ function getLogger(logDir = DEFAULT_LOG_DIR) {
65591
65749
  let logger;
65592
65750
  if (process.env.SWARM_LOG_FILE === "1") {
65593
65751
  ensureLogDir(logDir);
65594
- const logPath = join11(logDir, "swarm.log");
65752
+ const logPath = join13(logDir, "swarm.log");
65595
65753
  logger = import_pino.default(baseConfig, import_pino.default.destination({ dest: logPath, sync: false }));
65596
65754
  } else {
65597
65755
  logger = import_pino.default(baseConfig);
@@ -65611,7 +65769,7 @@ function createChildLogger(module, logDir = DEFAULT_LOG_DIR) {
65611
65769
  let childLogger;
65612
65770
  if (process.env.SWARM_LOG_FILE === "1") {
65613
65771
  ensureLogDir(logDir);
65614
- const logPath = join11(logDir, `${module}.log`);
65772
+ const logPath = join13(logDir, `${module}.log`);
65615
65773
  childLogger = import_pino.default(baseConfig, import_pino.default.destination({ dest: logPath, sync: false }));
65616
65774
  } else {
65617
65775
  childLogger = import_pino.default(baseConfig);
@@ -65623,6 +65781,7 @@ function createChildLogger(module, logDir = DEFAULT_LOG_DIR) {
65623
65781
  var logger = getLogger();
65624
65782
 
65625
65783
  // src/compaction-hook.ts
65784
+ init_eval_capture();
65626
65785
  var _logger;
65627
65786
  function getLog() {
65628
65787
  if (!_logger) {
@@ -65649,7 +65808,7 @@ Your role is ORCHESTRATION, not implementation. The resume steps above (if prese
65649
65808
  ## \uD83C\uDFAF WHAT GOOD LOOKS LIKE (Behavioral Examples)
65650
65809
 
65651
65810
  **✅ GOOD Coordinator Behavior:**
65652
- - Spawned researcher for unfamiliar tech → got summary → stored in semantic-memory
65811
+ - Spawned researcher for unfamiliar tech → got summary → stored in hivemind
65653
65812
  - Loaded \`skills_use(name="testing-patterns")\` BEFORE spawning test workers
65654
65813
  - Checked \`swarmmail_inbox()\` every 5-10 minutes → caught blocked worker → unblocked in 2min
65655
65814
  - Delegated planning to swarm/planner subagent → main context stayed clean
@@ -65803,15 +65962,14 @@ swarm_spawn_researcher(
65803
65962
  tech_stack=["TECHNOLOGY"],
65804
65963
  project_path="PROJECT_PATH"
65805
65964
  )
65806
- // Then spawn with Task(subagent_type="swarm/researcher", prompt="...")
65965
+ // Then spawn with Task(subagent_type="swarm-researcher", prompt="...")
65807
65966
  \`\`\`
65808
65967
 
65809
65968
  ### Phase 2: Knowledge Gathering
65810
65969
 
65811
65970
  \`\`\`
65812
- semantic-memory_find(query="TASK_KEYWORDS", limit=5) # Past learnings
65813
- cass_search(query="TASK_DESCRIPTION", limit=5) # Similar past tasks
65814
- skills_list() # Available skills
65971
+ hivemind_find(query="TASK_KEYWORDS", limit=5) # Past learnings
65972
+ skills_list() # Available skills
65815
65973
  \`\`\`
65816
65974
 
65817
65975
  ### Phase 3: Decompose
@@ -65834,7 +65992,7 @@ swarm_validate_decomposition(response="CELLTREE_JSON")
65834
65992
 
65835
65993
  \`\`\`
65836
65994
  swarm_spawn_subtask(bead_id, epic_id, title, files, shared_context, project_path)
65837
- Task(subagent_type="swarm/worker", prompt="GENERATED_PROMPT")
65995
+ Task(subagent_type="swarm-worker", prompt="GENERATED_PROMPT")
65838
65996
  \`\`\`
65839
65997
 
65840
65998
  ### Phase 7: Review Loop (MANDATORY)
@@ -66114,14 +66272,14 @@ function buildDynamicSwarmStateFromScanned(scanned, detected) {
66114
66272
  return parts2.join(`
66115
66273
  `);
66116
66274
  }
66117
- async function detectSwarm() {
66275
+ async function detectSwarm(getHiveAdapterFn, checkSwarmHealthFn, getHiveWorkingDirectoryFn, log3) {
66118
66276
  const reasons = [];
66119
66277
  let highConfidence = false;
66120
66278
  let mediumConfidence = false;
66121
66279
  let lowConfidence = false;
66122
66280
  let state;
66123
66281
  try {
66124
- const projectKey = getHiveWorkingDirectory();
66282
+ const projectKey = getHiveWorkingDirectoryFn();
66125
66283
  state = {
66126
66284
  projectPath: projectKey,
66127
66285
  subtasks: {
@@ -66133,9 +66291,9 @@ async function detectSwarm() {
66133
66291
  };
66134
66292
  const swarmMailStart = Date.now();
66135
66293
  try {
66136
- const health = await checkSwarmHealth3(projectKey);
66294
+ const health = await checkSwarmHealthFn(projectKey);
66137
66295
  const duration3 = Date.now() - swarmMailStart;
66138
- getLog().debug({
66296
+ log3.debug({
66139
66297
  source: "swarm-mail",
66140
66298
  duration_ms: duration3,
66141
66299
  healthy: health.healthy,
@@ -66156,7 +66314,7 @@ async function detectSwarm() {
66156
66314
  }
66157
66315
  }
66158
66316
  } catch (error45) {
66159
- getLog().debug({
66317
+ log3.debug({
66160
66318
  source: "swarm-mail",
66161
66319
  duration_ms: Date.now() - swarmMailStart,
66162
66320
  error: error45 instanceof Error ? error45.message : String(error45)
@@ -66164,7 +66322,7 @@ async function detectSwarm() {
66164
66322
  }
66165
66323
  const hiveStart = Date.now();
66166
66324
  try {
66167
- const adapter = await getHiveAdapter(projectKey);
66325
+ const adapter = await getHiveAdapterFn(projectKey);
66168
66326
  const cells = await adapter.queryCells(projectKey, {});
66169
66327
  const duration3 = Date.now() - hiveStart;
66170
66328
  if (Array.isArray(cells) && cells.length > 0) {
@@ -66191,7 +66349,7 @@ async function detectSwarm() {
66191
66349
  state.subtasks.in_progress = epicSubtasks.filter((c) => c.status === "in_progress").length;
66192
66350
  state.subtasks.open = epicSubtasks.filter((c) => c.status === "open").length;
66193
66351
  state.subtasks.blocked = epicSubtasks.filter((c) => c.status === "blocked").length;
66194
- getLog().debug({
66352
+ log3.debug({
66195
66353
  epic_id: state.epicId,
66196
66354
  epic_title: state.epicTitle,
66197
66355
  subtasks_closed: state.subtasks.closed,
@@ -66211,7 +66369,7 @@ async function detectSwarm() {
66211
66369
  lowConfidence = true;
66212
66370
  reasons.push(`${cells.length} total cells in hive`);
66213
66371
  }
66214
- getLog().debug({
66372
+ log3.debug({
66215
66373
  source: "hive",
66216
66374
  duration_ms: duration3,
66217
66375
  total_cells: cells.length,
@@ -66221,10 +66379,10 @@ async function detectSwarm() {
66221
66379
  recent_updates: recentCells.length
66222
66380
  }, "checked hive cells");
66223
66381
  } else {
66224
- getLog().debug({ source: "hive", duration_ms: duration3, total_cells: 0 }, "hive empty");
66382
+ log3.debug({ source: "hive", duration_ms: duration3, total_cells: 0 }, "hive empty");
66225
66383
  }
66226
66384
  } catch (error45) {
66227
- getLog().debug({
66385
+ log3.debug({
66228
66386
  source: "hive",
66229
66387
  duration_ms: Date.now() - hiveStart,
66230
66388
  error: error45 instanceof Error ? error45.message : String(error45)
@@ -66233,7 +66391,7 @@ async function detectSwarm() {
66233
66391
  } catch (error45) {
66234
66392
  lowConfidence = true;
66235
66393
  reasons.push("Could not detect project, using fallback");
66236
- getLog().debug({
66394
+ log3.debug({
66237
66395
  error: error45 instanceof Error ? error45.message : String(error45)
66238
66396
  }, "project detection failed");
66239
66397
  }
@@ -66253,7 +66411,7 @@ async function detectSwarm() {
66253
66411
  reasons,
66254
66412
  state
66255
66413
  };
66256
- getLog().debug({
66414
+ log3.debug({
66257
66415
  detected: result.detected,
66258
66416
  confidence: result.confidence,
66259
66417
  reason_count: result.reasons.length,
@@ -66262,14 +66420,24 @@ async function detectSwarm() {
66262
66420
  }, "swarm detection complete");
66263
66421
  return result;
66264
66422
  }
66265
- function createCompactionHook(client) {
66423
+ function createCompactionHook(options2) {
66424
+ const isOptions = options2 && typeof options2 === "object" && (("getHiveAdapter" in options2) || ("checkSwarmHealth" in options2) || ("getHiveWorkingDirectory" in options2) || ("client" in options2));
66425
+ const opts = isOptions ? options2 : { client: options2 };
66426
+ const {
66427
+ client,
66428
+ getHiveAdapter: customGetHiveAdapter,
66429
+ checkSwarmHealth: customCheckSwarmHealth,
66430
+ getHiveWorkingDirectory: customGetHiveWorkingDirectory,
66431
+ logger: customLogger
66432
+ } = opts;
66266
66433
  return async (input, output) => {
66267
66434
  const startTime = Date.now();
66435
+ const log3 = customLogger || getLog();
66268
66436
  const metrics = createMetricsCollector({
66269
66437
  session_id: input.sessionID,
66270
66438
  has_sdk_client: !!client
66271
66439
  });
66272
- getLog().info({
66440
+ log3.info({
66273
66441
  session_id: input.sessionID,
66274
66442
  trigger: "session_compaction",
66275
66443
  has_sdk_client: !!client
@@ -66281,7 +66449,7 @@ function createCompactionHook(client) {
66281
66449
  const scannedState = await scanSessionMessages(client, input.sessionID);
66282
66450
  recordPhaseComplete(metrics, "GATHER_SWARM_MAIL" /* GATHER_SWARM_MAIL */);
66283
66451
  recordPhaseStart(metrics, "DETECT" /* DETECT */);
66284
- const detection = await detectSwarm();
66452
+ const detection = await detectSwarm(customGetHiveAdapter || getHiveAdapter, customCheckSwarmHealth || checkSwarmHealth3, customGetHiveWorkingDirectory || getHiveWorkingDirectory, log3);
66285
66453
  let effectiveConfidence = detection.confidence;
66286
66454
  if (scannedState.epicId || scannedState.subtasks.size > 0) {
66287
66455
  if (effectiveConfidence === "none" || effectiveConfidence === "low") {
@@ -66299,6 +66467,18 @@ function createCompactionHook(client) {
66299
66467
  confidence: effectiveConfidence,
66300
66468
  detected: detection.detected || scannedState.epicId !== undefined
66301
66469
  });
66470
+ const epicId = scannedState.epicId || detection.state?.epicId || "unknown";
66471
+ await captureCompactionEvent({
66472
+ session_id: input.sessionID,
66473
+ epic_id: epicId,
66474
+ compaction_type: "detection_complete",
66475
+ payload: {
66476
+ confidence: effectiveConfidence,
66477
+ detected: detection.detected || scannedState.epicId !== undefined,
66478
+ reasons: detection.reasons,
66479
+ context_type: effectiveConfidence === "high" || effectiveConfidence === "medium" ? "full" : "fallback"
66480
+ }
66481
+ });
66302
66482
  recordPhaseStart(metrics, "INJECT" /* INJECT */);
66303
66483
  if (effectiveConfidence === "high" || effectiveConfidence === "medium") {
66304
66484
  const header = `[Swarm detected: ${detection.reasons.join(", ")}]
@@ -66323,7 +66503,18 @@ function createCompactionHook(client) {
66323
66503
  context_length: contextContent.length,
66324
66504
  context_type: "full"
66325
66505
  });
66326
- getLog().info({
66506
+ await captureCompactionEvent({
66507
+ session_id: input.sessionID,
66508
+ epic_id: epicId,
66509
+ compaction_type: "prompt_generated",
66510
+ payload: {
66511
+ prompt_length: contextContent.length,
66512
+ full_prompt: contextContent,
66513
+ context_type: "full",
66514
+ confidence: effectiveConfidence
66515
+ }
66516
+ });
66517
+ log3.info({
66327
66518
  confidence: effectiveConfidence,
66328
66519
  context_length: contextContent.length,
66329
66520
  context_type: "full",
@@ -66343,7 +66534,18 @@ function createCompactionHook(client) {
66343
66534
  context_length: contextContent.length,
66344
66535
  context_type: "fallback"
66345
66536
  });
66346
- getLog().info({
66537
+ await captureCompactionEvent({
66538
+ session_id: input.sessionID,
66539
+ epic_id: epicId,
66540
+ compaction_type: "prompt_generated",
66541
+ payload: {
66542
+ prompt_length: contextContent.length,
66543
+ full_prompt: contextContent,
66544
+ context_type: "fallback",
66545
+ confidence: effectiveConfidence
66546
+ }
66547
+ });
66548
+ log3.info({
66347
66549
  confidence: effectiveConfidence,
66348
66550
  context_length: contextContent.length,
66349
66551
  context_type: "fallback",
@@ -66353,7 +66555,7 @@ function createCompactionHook(client) {
66353
66555
  recordPhaseComplete(metrics, "INJECT" /* INJECT */, {
66354
66556
  context_type: "none"
66355
66557
  });
66356
- getLog().debug({
66558
+ log3.debug({
66357
66559
  confidence: effectiveConfidence,
66358
66560
  context_type: "none"
66359
66561
  }, "no swarm detected, skipping injection");
@@ -66361,7 +66563,7 @@ function createCompactionHook(client) {
66361
66563
  recordPhaseStart(metrics, "COMPLETE" /* COMPLETE */);
66362
66564
  const duration3 = Date.now() - startTime;
66363
66565
  const summary5 = getMetricsSummary(metrics);
66364
- getLog().info({
66566
+ log3.info({
66365
66567
  duration_ms: duration3,
66366
66568
  success: true,
66367
66569
  detected: detection.detected || scannedState.epicId !== undefined,
@@ -66385,7 +66587,7 @@ function createCompactionHook(client) {
66385
66587
  success: false,
66386
66588
  error: error45 instanceof Error ? error45.message : String(error45)
66387
66589
  });
66388
- getLog().error({
66590
+ log3.error({
66389
66591
  duration_ms: duration3,
66390
66592
  success: false,
66391
66593
  error: error45 instanceof Error ? error45.message : String(error45),
@@ -66861,17 +67063,17 @@ init_skills();
66861
67063
 
66862
67064
  // src/eval-history.ts
66863
67065
  import * as fs2 from "node:fs";
66864
- import * as path3 from "node:path";
67066
+ import * as path4 from "node:path";
66865
67067
  var DEFAULT_EVAL_HISTORY_PATH = ".opencode/eval-history.jsonl";
66866
67068
  var VARIANCE_THRESHOLD = 0.1;
66867
67069
  var BOOTSTRAP_THRESHOLD = 10;
66868
67070
  var STABILIZATION_THRESHOLD = 50;
66869
67071
  function getEvalHistoryPath(projectPath) {
66870
- return path3.join(projectPath, DEFAULT_EVAL_HISTORY_PATH);
67072
+ return path4.join(projectPath, DEFAULT_EVAL_HISTORY_PATH);
66871
67073
  }
66872
67074
  function ensureEvalHistoryDir(projectPath) {
66873
67075
  const historyPath = getEvalHistoryPath(projectPath);
66874
- const dir = path3.dirname(historyPath);
67076
+ const dir = path4.dirname(historyPath);
66875
67077
  if (!fs2.existsSync(dir)) {
66876
67078
  fs2.mkdirSync(dir, { recursive: true });
66877
67079
  }
@@ -67248,6 +67450,251 @@ function getSwarmSummary(projection) {
67248
67450
  return parts2.join(`
67249
67451
  `);
67250
67452
  }
67453
+ // src/cass-tools.ts
67454
+ init_dist();
67455
+ import {
67456
+ getDb,
67457
+ makeOllamaLive as makeOllamaLive3,
67458
+ viewSessionLine,
67459
+ SessionIndexer as SessionIndexer2,
67460
+ createEvent as createEvent6,
67461
+ getSwarmMailLibSQL as getSwarmMailLibSQL8
67462
+ } from "swarm-mail";
67463
+ import * as os3 from "node:os";
67464
+ import * as path5 from "node:path";
67465
+ var AGENT_DIRECTORIES2 = [
67466
+ path5.join(os3.homedir(), ".config", "swarm-tools", "sessions"),
67467
+ path5.join(os3.homedir(), ".opencode"),
67468
+ path5.join(os3.homedir(), "Cursor", "User", "History"),
67469
+ path5.join(os3.homedir(), ".local", "share", "Claude"),
67470
+ path5.join(os3.homedir(), ".aider")
67471
+ ];
67472
+ async function getSessionIndexer2() {
67473
+ const db = await getDb();
67474
+ const ollamaLayer = makeOllamaLive3({
67475
+ ollamaHost: process.env.OLLAMA_HOST || "http://localhost:11434",
67476
+ ollamaModel: process.env.OLLAMA_MODEL || "mxbai-embed-large"
67477
+ });
67478
+ return new SessionIndexer2(db, ollamaLayer);
67479
+ }
67480
+ async function emitEvent2(eventType, data) {
67481
+ try {
67482
+ const projectPath = process.cwd();
67483
+ const swarmMail = await getSwarmMailLibSQL8(projectPath);
67484
+ const event = createEvent6(eventType, {
67485
+ project_key: projectPath,
67486
+ ...data
67487
+ });
67488
+ await swarmMail.appendEvent(event);
67489
+ } catch {}
67490
+ }
67491
+ function detectAgentType(filePath) {
67492
+ if (filePath.includes("claude"))
67493
+ return "claude";
67494
+ if (filePath.includes("cursor"))
67495
+ return "cursor";
67496
+ if (filePath.includes("opencode"))
67497
+ return "opencode";
67498
+ if (filePath.includes("swarm-tools"))
67499
+ return "opencode-swarm";
67500
+ if (filePath.includes("codex"))
67501
+ return "codex";
67502
+ if (filePath.includes("aider"))
67503
+ return "aider";
67504
+ return;
67505
+ }
67506
+ var cass_search2 = tool({
67507
+ 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.",
67508
+ args: {
67509
+ query: tool.schema.string().describe("Search query (e.g., 'authentication error Next.js')"),
67510
+ agent: tool.schema.string().optional().describe("Filter by agent name (e.g., 'claude', 'cursor')"),
67511
+ days: tool.schema.number().optional().describe("Only search sessions from last N days"),
67512
+ limit: tool.schema.number().optional().describe("Max results to return (default: 5)"),
67513
+ fields: tool.schema.string().optional().describe("Field selection: 'minimal' for compact output (path, line, agent only)")
67514
+ },
67515
+ async execute(args2) {
67516
+ const startTime = Date.now();
67517
+ try {
67518
+ const indexer = await getSessionIndexer2();
67519
+ const searchOptions = {
67520
+ limit: args2.limit || 5,
67521
+ agent_type: args2.agent,
67522
+ fields: args2.fields === "minimal" ? "minimal" : undefined
67523
+ };
67524
+ const results = await exports_Effect.runPromise(indexer.search(args2.query, searchOptions).pipe(exports_Effect.catchAll((error45) => {
67525
+ console.warn(`Vector search failed, falling back to FTS5: ${error45.message}`);
67526
+ return exports_Effect.succeed([]);
67527
+ })));
67528
+ await emitEvent2("cass_searched", {
67529
+ query: args2.query,
67530
+ agent_filter: args2.agent,
67531
+ days_filter: args2.days,
67532
+ result_count: results.length,
67533
+ search_duration_ms: Date.now() - startTime
67534
+ });
67535
+ if (results.length === 0) {
67536
+ return `No results found. Try:
67537
+ - Broader search terms
67538
+ - Different agent filter
67539
+ - Running cass_index to refresh`;
67540
+ }
67541
+ return results.map((result, idx) => {
67542
+ const metadata = result.memory.metadata;
67543
+ const agentType = metadata?.agent_type || "unknown";
67544
+ const sourcePath = metadata?.source_path || "unknown";
67545
+ const lineNumber = metadata?.message_idx || 0;
67546
+ if (args2.fields === "minimal") {
67547
+ return `${idx + 1}. ${sourcePath}:${lineNumber} (${agentType})`;
67548
+ }
67549
+ return `${idx + 1}. [${agentType}] ${sourcePath}:${lineNumber}
67550
+ Score: ${result.score?.toFixed(3)}
67551
+ ${result.memory.content.slice(0, 200)}...
67552
+ `;
67553
+ }).join(`
67554
+ `);
67555
+ } catch (error45) {
67556
+ return JSON.stringify({
67557
+ error: error45 instanceof Error ? error45.message : String(error45)
67558
+ });
67559
+ }
67560
+ }
67561
+ });
67562
+ var cass_view2 = tool({
67563
+ description: "View a specific conversation/session from search results. Use source_path from cass_search output.",
67564
+ args: {
67565
+ path: tool.schema.string().describe("Path to session file (from cass_search results)"),
67566
+ line: tool.schema.number().optional().describe("Jump to specific line number")
67567
+ },
67568
+ async execute(args2) {
67569
+ try {
67570
+ const opts = {
67571
+ path: args2.path,
67572
+ line: args2.line,
67573
+ context: 3
67574
+ };
67575
+ const output = viewSessionLine(opts);
67576
+ await emitEvent2("cass_viewed", {
67577
+ session_path: args2.path,
67578
+ line_number: args2.line,
67579
+ agent_type: detectAgentType(args2.path)
67580
+ });
67581
+ return output;
67582
+ } catch (error45) {
67583
+ return JSON.stringify({
67584
+ error: error45 instanceof Error ? error45.message : String(error45)
67585
+ });
67586
+ }
67587
+ }
67588
+ });
67589
+ var cass_expand2 = tool({
67590
+ description: "Expand context around a specific line in a session. Shows messages before/after.",
67591
+ args: {
67592
+ path: tool.schema.string().describe("Path to session file"),
67593
+ line: tool.schema.number().describe("Line number to expand around"),
67594
+ context: tool.schema.number().optional().describe("Number of lines before/after to show (default: 5)")
67595
+ },
67596
+ async execute(args2) {
67597
+ try {
67598
+ const opts = {
67599
+ path: args2.path,
67600
+ line: args2.line,
67601
+ context: args2.context || 5
67602
+ };
67603
+ const output = viewSessionLine(opts);
67604
+ await emitEvent2("cass_viewed", {
67605
+ session_path: args2.path,
67606
+ line_number: args2.line
67607
+ });
67608
+ return output;
67609
+ } catch (error45) {
67610
+ return JSON.stringify({
67611
+ error: error45 instanceof Error ? error45.message : String(error45)
67612
+ });
67613
+ }
67614
+ }
67615
+ });
67616
+ var cass_health2 = tool({
67617
+ description: "Check if cass index is healthy. Exit 0 = ready, Exit 1 = needs indexing. Run this before searching.",
67618
+ args: {},
67619
+ async execute() {
67620
+ try {
67621
+ const indexer = await getSessionIndexer2();
67622
+ const health = await exports_Effect.runPromise(indexer.checkHealth());
67623
+ const isHealthy = health.total_indexed > 0 && health.stale_count === 0;
67624
+ return JSON.stringify({
67625
+ healthy: isHealthy,
67626
+ message: isHealthy ? "Index is ready" : "Index needs rebuilding. Run cass_index()",
67627
+ ...health
67628
+ });
67629
+ } catch (error45) {
67630
+ return JSON.stringify({
67631
+ healthy: false,
67632
+ error: error45 instanceof Error ? error45.message : String(error45)
67633
+ });
67634
+ }
67635
+ }
67636
+ });
67637
+ var cass_index2 = tool({
67638
+ description: "Build or rebuild the search index. Run this if health check fails or to pick up new sessions.",
67639
+ args: {
67640
+ full: tool.schema.boolean().optional().describe("Force full rebuild (default: incremental)")
67641
+ },
67642
+ async execute(args2) {
67643
+ const startTime = Date.now();
67644
+ try {
67645
+ const indexer = await getSessionIndexer2();
67646
+ const allResults = [];
67647
+ for (const dir of AGENT_DIRECTORIES2) {
67648
+ try {
67649
+ const options2 = {
67650
+ recursive: true
67651
+ };
67652
+ const results = await exports_Effect.runPromise(indexer.indexDirectory(dir, options2).pipe(exports_Effect.catchAll((error45) => {
67653
+ console.warn(`Skipping ${dir}: ${error45.message}`);
67654
+ return exports_Effect.succeed([]);
67655
+ })));
67656
+ allResults.push(...results);
67657
+ } catch {}
67658
+ }
67659
+ const totalIndexed = allResults.reduce((sum2, r) => sum2 + r.indexed, 0);
67660
+ const totalSkipped = allResults.reduce((sum2, r) => sum2 + r.skipped, 0);
67661
+ await emitEvent2("cass_indexed", {
67662
+ sessions_indexed: allResults.length,
67663
+ messages_indexed: totalIndexed,
67664
+ duration_ms: Date.now() - startTime,
67665
+ full_rebuild: args2.full ?? false
67666
+ });
67667
+ return `Indexed ${allResults.length} sessions with ${totalIndexed} chunks (${totalSkipped} skipped) in ${Date.now() - startTime}ms`;
67668
+ } catch (error45) {
67669
+ return JSON.stringify({
67670
+ error: error45 instanceof Error ? error45.message : String(error45)
67671
+ });
67672
+ }
67673
+ }
67674
+ });
67675
+ var cass_stats2 = tool({
67676
+ description: "Show index statistics - how many sessions, messages, agents indexed.",
67677
+ args: {},
67678
+ async execute() {
67679
+ try {
67680
+ const indexer = await getSessionIndexer2();
67681
+ const stats = await exports_Effect.runPromise(indexer.getStats());
67682
+ return JSON.stringify(stats, null, 2);
67683
+ } catch (error45) {
67684
+ return JSON.stringify({
67685
+ error: error45 instanceof Error ? error45.message : String(error45)
67686
+ });
67687
+ }
67688
+ }
67689
+ });
67690
+ var cassTools = {
67691
+ cass_search: cass_search2,
67692
+ cass_view: cass_view2,
67693
+ cass_expand: cass_expand2,
67694
+ cass_health: cass_health2,
67695
+ cass_index: cass_index2,
67696
+ cass_stats: cass_stats2
67697
+ };
67251
67698
 
67252
67699
  // src/index.ts
67253
67700
  var SwarmPlugin = async (input) => {
@@ -67296,7 +67743,7 @@ var SwarmPlugin = async (input) => {
67296
67743
  ...repoCrawlTools,
67297
67744
  ...skillsTools,
67298
67745
  ...mandateTools,
67299
- ...memoryTools,
67746
+ ...hivemindTools,
67300
67747
  ...observabilityTools,
67301
67748
  ...researchTools,
67302
67749
  ...contributorTools
@@ -67308,16 +67755,30 @@ var SwarmPlugin = async (input) => {
67308
67755
  },
67309
67756
  "tool.execute.before": async (input2, output) => {
67310
67757
  const toolName = input2.tool;
67758
+ const sessionId = input2.sessionID || "unknown";
67311
67759
  if (shouldAnalyzeTool(toolName)) {
67312
67760
  const analysis = analyzeTodoWrite(output.args);
67313
67761
  if (analysis.warning) {
67314
67762
  console.warn(`[swarm-plugin] ${analysis.warning}`);
67315
67763
  }
67316
67764
  }
67317
- if (isInCoordinatorContext()) {
67318
- const ctx = getCoordinatorContext();
67765
+ if (toolName === "hive_create_epic" || toolName === "swarm_decompose") {
67766
+ setCoordinatorContext({
67767
+ isCoordinator: true,
67768
+ sessionId
67769
+ });
67770
+ }
67771
+ const taskArgs = output.args;
67772
+ if (toolName === "task" && taskArgs?.subagent_type?.toLowerCase().includes("swarm")) {
67773
+ setCoordinatorContext({
67774
+ isCoordinator: true,
67775
+ sessionId
67776
+ });
67777
+ }
67778
+ if (isInCoordinatorContext(sessionId)) {
67779
+ const ctx = getCoordinatorContext(sessionId);
67319
67780
  const violation = detectCoordinatorViolation({
67320
- sessionId: input2.sessionID || "unknown",
67781
+ sessionId,
67321
67782
  epicId: ctx.epicId || "unknown",
67322
67783
  toolName,
67323
67784
  toolArgs: output.args,
@@ -67327,12 +67788,6 @@ var SwarmPlugin = async (input) => {
67327
67788
  console.warn(`[swarm-plugin] ${violation.message}`);
67328
67789
  }
67329
67790
  }
67330
- if (toolName === "hive_create_epic" || toolName === "swarm_decompose") {
67331
- setCoordinatorContext({
67332
- isCoordinator: true,
67333
- sessionId: input2.sessionID
67334
- });
67335
- }
67336
67791
  if (toolName === "hive_create_epic" && output.args) {
67337
67792
  const args2 = output.args;
67338
67793
  }
@@ -67379,15 +67834,111 @@ var SwarmPlugin = async (input) => {
67379
67834
  }
67380
67835
  } catch {}
67381
67836
  }
67382
- if (toolName === "hive_close" && output.output && isInCoordinatorContext()) {
67383
- const ctx = getCoordinatorContext();
67837
+ const sessionId = input2.sessionID || "unknown";
67838
+ if (toolName === "hive_close" && output.output && isInCoordinatorContext(sessionId)) {
67839
+ const ctx2 = getCoordinatorContext(sessionId);
67384
67840
  try {
67385
67841
  const result = JSON.parse(output.output);
67386
- if (result.id === ctx.epicId) {
67387
- clearCoordinatorContext();
67842
+ if (result.id === ctx2.epicId) {
67843
+ clearCoordinatorContext(sessionId);
67388
67844
  }
67389
67845
  } catch {}
67390
67846
  }
67847
+ const ctx = getCoordinatorContext();
67848
+ const epicId = ctx.epicId || "unknown";
67849
+ if (toolName === "task") {
67850
+ try {
67851
+ const result = output.output ? JSON.parse(output.output) : {};
67852
+ if (result.researcher_id || result.research_topic || result.tools_used) {
67853
+ const { captureResearcherSpawned: captureResearcherSpawned2 } = await Promise.resolve().then(() => (init_eval_capture(), exports_eval_capture));
67854
+ await captureResearcherSpawned2({
67855
+ session_id: input2.sessionID,
67856
+ epic_id: epicId,
67857
+ researcher_id: result.researcher_id || "unknown",
67858
+ research_topic: result.research_topic || "unknown",
67859
+ tools_used: result.tools_used || []
67860
+ });
67861
+ }
67862
+ } catch (err) {}
67863
+ }
67864
+ if (toolName === "skills_use") {
67865
+ try {
67866
+ const { captureSkillLoaded: captureSkillLoaded2 } = await Promise.resolve().then(() => (init_eval_capture(), exports_eval_capture));
67867
+ const result = output.output ? JSON.parse(output.output) : {};
67868
+ const skillName = result.skill_name || result.name || "unknown";
67869
+ const context4 = result.context;
67870
+ await captureSkillLoaded2({
67871
+ session_id: input2.sessionID,
67872
+ epic_id: epicId,
67873
+ skill_name: skillName,
67874
+ context: context4
67875
+ });
67876
+ } catch (err) {}
67877
+ }
67878
+ if (toolName === "swarmmail_inbox") {
67879
+ try {
67880
+ const { captureInboxChecked: captureInboxChecked2 } = await Promise.resolve().then(() => (init_eval_capture(), exports_eval_capture));
67881
+ const result = output.output ? JSON.parse(output.output) : {};
67882
+ await captureInboxChecked2({
67883
+ session_id: input2.sessionID,
67884
+ epic_id: epicId,
67885
+ message_count: result.message_count || 0,
67886
+ urgent_count: result.urgent_count || 0
67887
+ });
67888
+ } catch (err) {
67889
+ console.warn("[eval-capture] captureInboxChecked failed:", err);
67890
+ }
67891
+ }
67892
+ if (toolName === "hive_update") {
67893
+ try {
67894
+ const result = output.output ? JSON.parse(output.output) : {};
67895
+ const newStatus = result.status;
67896
+ const previousStatus = result.previous_status;
67897
+ if (previousStatus === "blocked" && newStatus !== "blocked") {
67898
+ const { captureBlockerResolved: captureBlockerResolved2 } = await Promise.resolve().then(() => (init_eval_capture(), exports_eval_capture));
67899
+ await captureBlockerResolved2({
67900
+ session_id: input2.sessionID,
67901
+ epic_id: epicId,
67902
+ worker_id: result.worker_id || "unknown",
67903
+ subtask_id: result.id || "unknown",
67904
+ blocker_type: result.blocker_type || "unknown",
67905
+ resolution: result.resolution || "Status changed to " + newStatus
67906
+ });
67907
+ }
67908
+ if (newStatus === "blocked" && previousStatus !== "blocked") {
67909
+ const { captureBlockerDetected: captureBlockerDetected2 } = await Promise.resolve().then(() => (init_eval_capture(), exports_eval_capture));
67910
+ await captureBlockerDetected2({
67911
+ session_id: input2.sessionID,
67912
+ epic_id: epicId,
67913
+ worker_id: result.worker_id || "unknown",
67914
+ subtask_id: result.id || "unknown",
67915
+ blocker_type: result.blocker_type || "unknown",
67916
+ blocker_description: result.blocker_description || result.description || "No description provided"
67917
+ });
67918
+ }
67919
+ } catch (err) {}
67920
+ }
67921
+ if (toolName === "swarmmail_send") {
67922
+ try {
67923
+ const result = output.output ? JSON.parse(output.output) : {};
67924
+ if (result.scope_change || result.original_scope || result.new_scope) {
67925
+ const { captureScopeChangeDecision: captureScopeChangeDecision2 } = await Promise.resolve().then(() => (init_eval_capture(), exports_eval_capture));
67926
+ const threadId = result.thread_id || epicId;
67927
+ await captureScopeChangeDecision2({
67928
+ session_id: input2.sessionID,
67929
+ epic_id: threadId,
67930
+ worker_id: result.worker_id || "unknown",
67931
+ subtask_id: result.subtask_id || "unknown",
67932
+ approved: result.approved ?? false,
67933
+ original_scope: result.original_scope,
67934
+ new_scope: result.new_scope,
67935
+ requested_scope: result.requested_scope,
67936
+ rejection_reason: result.rejection_reason,
67937
+ estimated_time_add: result.estimated_time_add
67938
+ });
67939
+ }
67940
+ } catch (err) {}
67941
+ }
67391
67942
  },
67392
67943
  "experimental.session.compacting": createCompactionHook(client)
67393
67944
  };
@@ -67403,10 +67954,9 @@ var allTools = {
67403
67954
  ...repoCrawlTools,
67404
67955
  ...skillsTools,
67405
67956
  ...mandateTools,
67406
- ...memoryTools,
67957
+ ...hivemindTools,
67407
67958
  ...observabilityTools,
67408
- ...contributorTools,
67409
- ...cassTools
67959
+ ...contributorTools
67410
67960
  };
67411
67961
  export {
67412
67962
  withToolFallback,
@@ -67529,6 +68079,7 @@ export {
67529
68079
  createBeadEvent,
67530
68080
  createAgentMailError,
67531
68081
  clearSessionState,
68082
+ clearHiveAdapterCache,
67532
68083
  checkTool,
67533
68084
  checkGate,
67534
68085
  checkBeadsMigrationNeeded,