opencode-swarm-plugin 0.45.1 → 0.45.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/plugin.js CHANGED
@@ -26904,6 +26904,34 @@ import {
26904
26904
  sep
26905
26905
  } from "path";
26906
26906
  import { fileURLToPath } from "url";
26907
+ import { getSwarmMailLibSQL as getSwarmMailLibSQL2, createEvent as createEvent2 } from "swarm-mail";
26908
+ async function emitSkillLoadedEvent(data) {
26909
+ try {
26910
+ const projectPath = skillsProjectDirectory;
26911
+ const swarmMail = await getSwarmMailLibSQL2(projectPath);
26912
+ const event = createEvent2("skill_loaded", {
26913
+ project_key: projectPath,
26914
+ skill_name: data.skill_name,
26915
+ skill_source: data.skill_source,
26916
+ context_provided: data.context_provided,
26917
+ content_length: data.content_length
26918
+ });
26919
+ await swarmMail.appendEvent(event);
26920
+ } catch {}
26921
+ }
26922
+ async function emitSkillCreatedEvent(data) {
26923
+ try {
26924
+ const projectPath = skillsProjectDirectory;
26925
+ const swarmMail = await getSwarmMailLibSQL2(projectPath);
26926
+ const event = createEvent2("skill_created", {
26927
+ project_key: projectPath,
26928
+ skill_name: data.skill_name,
26929
+ skill_scope: data.skill_scope,
26930
+ description: data.description
26931
+ });
26932
+ await swarmMail.appendEvent(event);
26933
+ } catch {}
26934
+ }
26907
26935
  function setSkillsProjectDirectory(dir) {
26908
26936
  skillsProjectDirectory = dir;
26909
26937
  skillsCache = null;
@@ -27339,6 +27367,18 @@ If the skill has scripts, you can run them with skills_execute.`,
27339
27367
  const names = available.map((s) => s.name).join(", ");
27340
27368
  return `Skill '${args.name}' not found. Available skills: ${names || "none"}`;
27341
27369
  }
27370
+ let skillSource = "project";
27371
+ if (skill.path.includes(".config/opencode/skills") || skill.path.includes(".claude/skills")) {
27372
+ skillSource = "global";
27373
+ } else if (skill.path.includes("global-skills")) {
27374
+ skillSource = "bundled";
27375
+ }
27376
+ await emitSkillLoadedEvent({
27377
+ skill_name: skill.metadata.name,
27378
+ skill_source: skillSource,
27379
+ context_provided: true,
27380
+ content_length: skill.body.length
27381
+ });
27342
27382
  const includeScripts = args.include_scripts !== false;
27343
27383
  let output = `# Skill: ${skill.metadata.name}
27344
27384
 
@@ -27507,6 +27547,12 @@ Good skills have:
27507
27547
  const content = generateSkillContent(args.name, args.description, args.body, { tags: args.tags, tools: args.tools });
27508
27548
  await writeFile(skillPath, content, "utf-8");
27509
27549
  invalidateSkillsCache();
27550
+ const skillScope = args.directory === "global" || args.directory === "global-claude" ? "global" : "project";
27551
+ await emitSkillCreatedEvent({
27552
+ skill_name: args.name,
27553
+ skill_scope: skillScope,
27554
+ description: args.description
27555
+ });
27510
27556
  const response = {
27511
27557
  success: true,
27512
27558
  skill: args.name,
@@ -27742,6 +27788,12 @@ echo "Project directory: $1"
27742
27788
  createdFiles.push("references/guide.md");
27743
27789
  }
27744
27790
  invalidateSkillsCache();
27791
+ const skillScope = args.directory === "global" ? "global" : "project";
27792
+ await emitSkillCreatedEvent({
27793
+ skill_name: args.name,
27794
+ skill_scope: skillScope,
27795
+ description: args.description || "[TODO: Complete description]"
27796
+ });
27745
27797
  return JSON.stringify({
27746
27798
  success: true,
27747
27799
  skill: args.name,
@@ -35138,8 +35190,8 @@ var require_req = __commonJS((exports, module) => {
35138
35190
  if (req.originalUrl) {
35139
35191
  _req.url = req.originalUrl;
35140
35192
  } else {
35141
- const path5 = req.path;
35142
- _req.url = typeof path5 === "string" ? path5 : req.url ? req.url.path || req.url : undefined;
35193
+ const path3 = req.path;
35194
+ _req.url = typeof path3 === "string" ? path3 : req.url ? req.url.path || req.url : undefined;
35143
35195
  }
35144
35196
  if (req.query) {
35145
35197
  _req.query = req.query;
@@ -35295,14 +35347,14 @@ var require_redact = __commonJS((exports, module) => {
35295
35347
  }
35296
35348
  return obj;
35297
35349
  }
35298
- function parsePath(path5) {
35350
+ function parsePath(path3) {
35299
35351
  const parts2 = [];
35300
35352
  let current = "";
35301
35353
  let inBrackets = false;
35302
35354
  let inQuotes = false;
35303
35355
  let quoteChar = "";
35304
- for (let i = 0;i < path5.length; i++) {
35305
- const char = path5[i];
35356
+ for (let i = 0;i < path3.length; i++) {
35357
+ const char = path3[i];
35306
35358
  if (!inBrackets && char === ".") {
35307
35359
  if (current) {
35308
35360
  parts2.push(current);
@@ -35433,10 +35485,10 @@ var require_redact = __commonJS((exports, module) => {
35433
35485
  return current;
35434
35486
  }
35435
35487
  function redactPaths(obj, paths, censor, remove7 = false) {
35436
- for (const path5 of paths) {
35437
- const parts2 = parsePath(path5);
35488
+ for (const path3 of paths) {
35489
+ const parts2 = parsePath(path3);
35438
35490
  if (parts2.includes("*")) {
35439
- redactWildcardPath(obj, parts2, censor, path5, remove7);
35491
+ redactWildcardPath(obj, parts2, censor, path3, remove7);
35440
35492
  } else {
35441
35493
  if (remove7) {
35442
35494
  removeKey(obj, parts2);
@@ -35523,8 +35575,8 @@ var require_redact = __commonJS((exports, module) => {
35523
35575
  }
35524
35576
  } else {
35525
35577
  if (afterWildcard.includes("*")) {
35526
- const wrappedCensor = typeof censor === "function" ? (value, path5) => {
35527
- const fullPath = [...pathArray.slice(0, pathLength), ...path5];
35578
+ const wrappedCensor = typeof censor === "function" ? (value, path3) => {
35579
+ const fullPath = [...pathArray.slice(0, pathLength), ...path3];
35528
35580
  return censor(value, fullPath);
35529
35581
  } : censor;
35530
35582
  redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove7);
@@ -35561,8 +35613,8 @@ var require_redact = __commonJS((exports, module) => {
35561
35613
  return null;
35562
35614
  }
35563
35615
  const pathStructure = new Map;
35564
- for (const path5 of pathsToClone) {
35565
- const parts2 = parsePath(path5);
35616
+ for (const path3 of pathsToClone) {
35617
+ const parts2 = parsePath(path3);
35566
35618
  let current = pathStructure;
35567
35619
  for (let i = 0;i < parts2.length; i++) {
35568
35620
  const part = parts2[i];
@@ -35614,24 +35666,24 @@ var require_redact = __commonJS((exports, module) => {
35614
35666
  }
35615
35667
  return cloneSelectively(obj, pathStructure);
35616
35668
  }
35617
- function validatePath(path5) {
35618
- if (typeof path5 !== "string") {
35669
+ function validatePath(path3) {
35670
+ if (typeof path3 !== "string") {
35619
35671
  throw new Error("Paths must be (non-empty) strings");
35620
35672
  }
35621
- if (path5 === "") {
35673
+ if (path3 === "") {
35622
35674
  throw new Error("Invalid redaction path ()");
35623
35675
  }
35624
- if (path5.includes("..")) {
35625
- throw new Error(`Invalid redaction path (${path5})`);
35676
+ if (path3.includes("..")) {
35677
+ throw new Error(`Invalid redaction path (${path3})`);
35626
35678
  }
35627
- if (path5.includes(",")) {
35628
- throw new Error(`Invalid redaction path (${path5})`);
35679
+ if (path3.includes(",")) {
35680
+ throw new Error(`Invalid redaction path (${path3})`);
35629
35681
  }
35630
35682
  let bracketCount = 0;
35631
35683
  let inQuotes = false;
35632
35684
  let quoteChar = "";
35633
- for (let i = 0;i < path5.length; i++) {
35634
- const char = path5[i];
35685
+ for (let i = 0;i < path3.length; i++) {
35686
+ const char = path3[i];
35635
35687
  if ((char === '"' || char === "'") && bracketCount > 0) {
35636
35688
  if (!inQuotes) {
35637
35689
  inQuotes = true;
@@ -35645,20 +35697,20 @@ var require_redact = __commonJS((exports, module) => {
35645
35697
  } else if (char === "]" && !inQuotes) {
35646
35698
  bracketCount--;
35647
35699
  if (bracketCount < 0) {
35648
- throw new Error(`Invalid redaction path (${path5})`);
35700
+ throw new Error(`Invalid redaction path (${path3})`);
35649
35701
  }
35650
35702
  }
35651
35703
  }
35652
35704
  if (bracketCount !== 0) {
35653
- throw new Error(`Invalid redaction path (${path5})`);
35705
+ throw new Error(`Invalid redaction path (${path3})`);
35654
35706
  }
35655
35707
  }
35656
35708
  function validatePaths(paths) {
35657
35709
  if (!Array.isArray(paths)) {
35658
35710
  throw new TypeError("paths must be an array");
35659
35711
  }
35660
- for (const path5 of paths) {
35661
- validatePath(path5);
35712
+ for (const path3 of paths) {
35713
+ validatePath(path3);
35662
35714
  }
35663
35715
  }
35664
35716
  function slowRedact(options2 = {}) {
@@ -35820,8 +35872,8 @@ var require_redaction = __commonJS((exports, module) => {
35820
35872
  if (shape[k] === null) {
35821
35873
  o[k] = (value) => topCensor(value, [k]);
35822
35874
  } else {
35823
- const wrappedCensor = typeof censor === "function" ? (value, path5) => {
35824
- return censor(value, [k, ...path5]);
35875
+ const wrappedCensor = typeof censor === "function" ? (value, path3) => {
35876
+ return censor(value, [k, ...path3]);
35825
35877
  } : censor;
35826
35878
  o[k] = Redact({
35827
35879
  paths: shape[k],
@@ -36029,10 +36081,10 @@ var require_atomic_sleep = __commonJS((exports, module) => {
36029
36081
 
36030
36082
  // ../../node_modules/.bun/sonic-boom@4.2.0/node_modules/sonic-boom/index.js
36031
36083
  var require_sonic_boom = __commonJS((exports, module) => {
36032
- var fs4 = __require("fs");
36084
+ var fs2 = __require("fs");
36033
36085
  var EventEmitter = __require("events");
36034
36086
  var inherits = __require("util").inherits;
36035
- var path5 = __require("path");
36087
+ var path3 = __require("path");
36036
36088
  var sleep5 = require_atomic_sleep();
36037
36089
  var assert2 = __require("assert");
36038
36090
  var BUSY_WRITE_TIMEOUT = 100;
@@ -36087,21 +36139,21 @@ var require_sonic_boom = __commonJS((exports, module) => {
36087
36139
  if (sonic.sync) {
36088
36140
  try {
36089
36141
  if (sonic.mkdir)
36090
- fs4.mkdirSync(path5.dirname(file2), { recursive: true });
36091
- const fd = fs4.openSync(file2, flags, mode);
36142
+ fs2.mkdirSync(path3.dirname(file2), { recursive: true });
36143
+ const fd = fs2.openSync(file2, flags, mode);
36092
36144
  fileOpened(null, fd);
36093
36145
  } catch (err) {
36094
36146
  fileOpened(err);
36095
36147
  throw err;
36096
36148
  }
36097
36149
  } else if (sonic.mkdir) {
36098
- fs4.mkdir(path5.dirname(file2), { recursive: true }, (err) => {
36150
+ fs2.mkdir(path3.dirname(file2), { recursive: true }, (err) => {
36099
36151
  if (err)
36100
36152
  return fileOpened(err);
36101
- fs4.open(file2, flags, mode, fileOpened);
36153
+ fs2.open(file2, flags, mode, fileOpened);
36102
36154
  });
36103
36155
  } else {
36104
- fs4.open(file2, flags, mode, fileOpened);
36156
+ fs2.open(file2, flags, mode, fileOpened);
36105
36157
  }
36106
36158
  }
36107
36159
  function SonicBoom(opts) {
@@ -36142,16 +36194,16 @@ var require_sonic_boom = __commonJS((exports, module) => {
36142
36194
  this.flush = flushBuffer;
36143
36195
  this.flushSync = flushBufferSync;
36144
36196
  this._actualWrite = actualWriteBuffer;
36145
- fsWriteSync = () => fs4.writeSync(this.fd, this._writingBuf);
36146
- fsWrite = () => fs4.write(this.fd, this._writingBuf, this.release);
36197
+ fsWriteSync = () => fs2.writeSync(this.fd, this._writingBuf);
36198
+ fsWrite = () => fs2.write(this.fd, this._writingBuf, this.release);
36147
36199
  } else if (contentMode === undefined || contentMode === kContentModeUtf8) {
36148
36200
  this._writingBuf = "";
36149
36201
  this.write = write;
36150
36202
  this.flush = flush;
36151
36203
  this.flushSync = flushSync;
36152
36204
  this._actualWrite = actualWrite;
36153
- fsWriteSync = () => fs4.writeSync(this.fd, this._writingBuf, "utf8");
36154
- fsWrite = () => fs4.write(this.fd, this._writingBuf, "utf8", this.release);
36205
+ fsWriteSync = () => fs2.writeSync(this.fd, this._writingBuf, "utf8");
36206
+ fsWrite = () => fs2.write(this.fd, this._writingBuf, "utf8", this.release);
36155
36207
  } else {
36156
36208
  throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
36157
36209
  }
@@ -36207,7 +36259,7 @@ var require_sonic_boom = __commonJS((exports, module) => {
36207
36259
  }
36208
36260
  }
36209
36261
  if (this._fsync) {
36210
- fs4.fsyncSync(this.fd);
36262
+ fs2.fsyncSync(this.fd);
36211
36263
  }
36212
36264
  const len = this._len;
36213
36265
  if (this._reopening) {
@@ -36320,7 +36372,7 @@ var require_sonic_boom = __commonJS((exports, module) => {
36320
36372
  const onDrain = () => {
36321
36373
  if (!this._fsync) {
36322
36374
  try {
36323
- fs4.fsync(this.fd, (err) => {
36375
+ fs2.fsync(this.fd, (err) => {
36324
36376
  this._flushPending = false;
36325
36377
  cb(err);
36326
36378
  });
@@ -36422,7 +36474,7 @@ var require_sonic_boom = __commonJS((exports, module) => {
36422
36474
  const fd = this.fd;
36423
36475
  this.once("ready", () => {
36424
36476
  if (fd !== this.fd) {
36425
- fs4.close(fd, (err) => {
36477
+ fs2.close(fd, (err) => {
36426
36478
  if (err) {
36427
36479
  return this.emit("error", err);
36428
36480
  }
@@ -36471,7 +36523,7 @@ var require_sonic_boom = __commonJS((exports, module) => {
36471
36523
  buf = this._bufs[0];
36472
36524
  }
36473
36525
  try {
36474
- const n = fs4.writeSync(this.fd, buf, "utf8");
36526
+ const n = fs2.writeSync(this.fd, buf, "utf8");
36475
36527
  const releasedBufObj = releaseWritingBuf(buf, this._len, n);
36476
36528
  buf = releasedBufObj.writingBuf;
36477
36529
  this._len = releasedBufObj.len;
@@ -36487,7 +36539,7 @@ var require_sonic_boom = __commonJS((exports, module) => {
36487
36539
  }
36488
36540
  }
36489
36541
  try {
36490
- fs4.fsyncSync(this.fd);
36542
+ fs2.fsyncSync(this.fd);
36491
36543
  } catch {}
36492
36544
  }
36493
36545
  function flushBufferSync() {
@@ -36507,7 +36559,7 @@ var require_sonic_boom = __commonJS((exports, module) => {
36507
36559
  buf = mergeBuf(this._bufs[0], this._lens[0]);
36508
36560
  }
36509
36561
  try {
36510
- const n = fs4.writeSync(this.fd, buf);
36562
+ const n = fs2.writeSync(this.fd, buf);
36511
36563
  buf = buf.subarray(n);
36512
36564
  this._len = Math.max(this._len - n, 0);
36513
36565
  if (buf.length <= 0) {
@@ -36535,13 +36587,13 @@ var require_sonic_boom = __commonJS((exports, module) => {
36535
36587
  this._writingBuf = this._writingBuf || this._bufs.shift() || "";
36536
36588
  if (this.sync) {
36537
36589
  try {
36538
- const written = fs4.writeSync(this.fd, this._writingBuf, "utf8");
36590
+ const written = fs2.writeSync(this.fd, this._writingBuf, "utf8");
36539
36591
  release(null, written);
36540
36592
  } catch (err) {
36541
36593
  release(err);
36542
36594
  }
36543
36595
  } else {
36544
- fs4.write(this.fd, this._writingBuf, "utf8", release);
36596
+ fs2.write(this.fd, this._writingBuf, "utf8", release);
36545
36597
  }
36546
36598
  }
36547
36599
  function actualWriteBuffer() {
@@ -36550,7 +36602,7 @@ var require_sonic_boom = __commonJS((exports, module) => {
36550
36602
  this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
36551
36603
  if (this.sync) {
36552
36604
  try {
36553
- const written = fs4.writeSync(this.fd, this._writingBuf);
36605
+ const written = fs2.writeSync(this.fd, this._writingBuf);
36554
36606
  release(null, written);
36555
36607
  } catch (err) {
36556
36608
  release(err);
@@ -36559,7 +36611,7 @@ var require_sonic_boom = __commonJS((exports, module) => {
36559
36611
  if (kCopyBuffer) {
36560
36612
  this._writingBuf = Buffer.from(this._writingBuf);
36561
36613
  }
36562
- fs4.write(this.fd, this._writingBuf, release);
36614
+ fs2.write(this.fd, this._writingBuf, release);
36563
36615
  }
36564
36616
  }
36565
36617
  function actualClose(sonic) {
@@ -36575,11 +36627,11 @@ var require_sonic_boom = __commonJS((exports, module) => {
36575
36627
  sonic._lens = [];
36576
36628
  assert2(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
36577
36629
  try {
36578
- fs4.fsync(sonic.fd, closeWrapped);
36630
+ fs2.fsync(sonic.fd, closeWrapped);
36579
36631
  } catch {}
36580
36632
  function closeWrapped() {
36581
36633
  if (sonic.fd !== 1 && sonic.fd !== 2) {
36582
- fs4.close(sonic.fd, done7);
36634
+ fs2.close(sonic.fd, done7);
36583
36635
  } else {
36584
36636
  done7();
36585
36637
  }
@@ -36825,7 +36877,7 @@ var require_thread_stream = __commonJS((exports, module) => {
36825
36877
  var { version: version2 } = require_package();
36826
36878
  var { EventEmitter } = __require("events");
36827
36879
  var { Worker } = __require("worker_threads");
36828
- var { join: join12 } = __require("path");
36880
+ var { join: join11 } = __require("path");
36829
36881
  var { pathToFileURL } = __require("url");
36830
36882
  var { wait } = require_wait();
36831
36883
  var {
@@ -36861,7 +36913,7 @@ var require_thread_stream = __commonJS((exports, module) => {
36861
36913
  function createWorker(stream, opts) {
36862
36914
  const { filename, workerData } = opts;
36863
36915
  const bundlerOverrides = "__bundlerPathsOverrides" in globalThis ? globalThis.__bundlerPathsOverrides : {};
36864
- const toExecute = bundlerOverrides["thread-stream-worker"] || join12(__dirname, "lib", "worker.js");
36916
+ const toExecute = bundlerOverrides["thread-stream-worker"] || join11(__dirname, "lib", "worker.js");
36865
36917
  const worker = new Worker(toExecute, {
36866
36918
  ...opts.workerOpts,
36867
36919
  trackUnmanagedFds: false,
@@ -37245,7 +37297,7 @@ var require_transport = __commonJS((exports, module) => {
37245
37297
  var __dirname = "/home/runner/work/swarm-tools/swarm-tools/node_modules/.bun/pino@9.14.0/node_modules/pino/lib";
37246
37298
  var { createRequire: createRequire2 } = __require("module");
37247
37299
  var getCallers = require_caller();
37248
- var { join: join12, isAbsolute: isAbsolute2, sep: sep3 } = __require("node:path");
37300
+ var { join: join11, isAbsolute: isAbsolute2, sep: sep3 } = __require("node:path");
37249
37301
  var sleep5 = require_atomic_sleep();
37250
37302
  var onExit4 = require_on_exit_leak_free();
37251
37303
  var ThreadStream = require_thread_stream();
@@ -37308,7 +37360,7 @@ var require_transport = __commonJS((exports, module) => {
37308
37360
  throw new Error("only one of target or targets can be specified");
37309
37361
  }
37310
37362
  if (targets) {
37311
- target = bundlerOverrides["pino-worker"] || join12(__dirname, "worker.js");
37363
+ target = bundlerOverrides["pino-worker"] || join11(__dirname, "worker.js");
37312
37364
  options2.targets = targets.filter((dest) => dest.target).map((dest) => {
37313
37365
  return {
37314
37366
  ...dest,
@@ -37325,7 +37377,7 @@ var require_transport = __commonJS((exports, module) => {
37325
37377
  });
37326
37378
  });
37327
37379
  } else if (pipeline) {
37328
- target = bundlerOverrides["pino-worker"] || join12(__dirname, "worker.js");
37380
+ target = bundlerOverrides["pino-worker"] || join11(__dirname, "worker.js");
37329
37381
  options2.pipelines = [pipeline.map((dest) => {
37330
37382
  return {
37331
37383
  ...dest,
@@ -37347,7 +37399,7 @@ var require_transport = __commonJS((exports, module) => {
37347
37399
  return origin;
37348
37400
  }
37349
37401
  if (origin === "pino/file") {
37350
- return join12(__dirname, "..", "file.js");
37402
+ return join11(__dirname, "..", "file.js");
37351
37403
  }
37352
37404
  let fixTarget2;
37353
37405
  for (const filePath of callers) {
@@ -38285,7 +38337,7 @@ var require_safe_stable_stringify = __commonJS((exports, module) => {
38285
38337
  return circularValue;
38286
38338
  }
38287
38339
  let res = "";
38288
- let join12 = ",";
38340
+ let join11 = ",";
38289
38341
  const originalIndentation = indentation;
38290
38342
  if (Array.isArray(value)) {
38291
38343
  if (value.length === 0) {
@@ -38299,7 +38351,7 @@ var require_safe_stable_stringify = __commonJS((exports, module) => {
38299
38351
  indentation += spacer;
38300
38352
  res += `
38301
38353
  ${indentation}`;
38302
- join12 = `,
38354
+ join11 = `,
38303
38355
  ${indentation}`;
38304
38356
  }
38305
38357
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
@@ -38307,13 +38359,13 @@ ${indentation}`;
38307
38359
  for (;i < maximumValuesToStringify - 1; i++) {
38308
38360
  const tmp2 = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
38309
38361
  res += tmp2 !== undefined ? tmp2 : "null";
38310
- res += join12;
38362
+ res += join11;
38311
38363
  }
38312
38364
  const tmp = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
38313
38365
  res += tmp !== undefined ? tmp : "null";
38314
38366
  if (value.length - 1 > maximumBreadth) {
38315
38367
  const removedKeys = value.length - maximumBreadth - 1;
38316
- res += `${join12}"... ${getItemCount(removedKeys)} not stringified"`;
38368
+ res += `${join11}"... ${getItemCount(removedKeys)} not stringified"`;
38317
38369
  }
38318
38370
  if (spacer !== "") {
38319
38371
  res += `
@@ -38334,7 +38386,7 @@ ${originalIndentation}`;
38334
38386
  let separator = "";
38335
38387
  if (spacer !== "") {
38336
38388
  indentation += spacer;
38337
- join12 = `,
38389
+ join11 = `,
38338
38390
  ${indentation}`;
38339
38391
  whitespace = " ";
38340
38392
  }
@@ -38348,13 +38400,13 @@ ${indentation}`;
38348
38400
  const tmp = stringifyFnReplacer(key2, value, stack, replacer, spacer, indentation);
38349
38401
  if (tmp !== undefined) {
38350
38402
  res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
38351
- separator = join12;
38403
+ separator = join11;
38352
38404
  }
38353
38405
  }
38354
38406
  if (keyLength > maximumBreadth) {
38355
38407
  const removedKeys = keyLength - maximumBreadth;
38356
38408
  res += `${separator}"...":${whitespace}"${getItemCount(removedKeys)} not stringified"`;
38357
- separator = join12;
38409
+ separator = join11;
38358
38410
  }
38359
38411
  if (spacer !== "" && separator.length > 1) {
38360
38412
  res = `
@@ -38394,7 +38446,7 @@ ${originalIndentation}`;
38394
38446
  }
38395
38447
  const originalIndentation = indentation;
38396
38448
  let res = "";
38397
- let join12 = ",";
38449
+ let join11 = ",";
38398
38450
  if (Array.isArray(value)) {
38399
38451
  if (value.length === 0) {
38400
38452
  return "[]";
@@ -38407,7 +38459,7 @@ ${originalIndentation}`;
38407
38459
  indentation += spacer;
38408
38460
  res += `
38409
38461
  ${indentation}`;
38410
- join12 = `,
38462
+ join11 = `,
38411
38463
  ${indentation}`;
38412
38464
  }
38413
38465
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
@@ -38415,13 +38467,13 @@ ${indentation}`;
38415
38467
  for (;i < maximumValuesToStringify - 1; i++) {
38416
38468
  const tmp2 = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
38417
38469
  res += tmp2 !== undefined ? tmp2 : "null";
38418
- res += join12;
38470
+ res += join11;
38419
38471
  }
38420
38472
  const tmp = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
38421
38473
  res += tmp !== undefined ? tmp : "null";
38422
38474
  if (value.length - 1 > maximumBreadth) {
38423
38475
  const removedKeys = value.length - maximumBreadth - 1;
38424
- res += `${join12}"... ${getItemCount(removedKeys)} not stringified"`;
38476
+ res += `${join11}"... ${getItemCount(removedKeys)} not stringified"`;
38425
38477
  }
38426
38478
  if (spacer !== "") {
38427
38479
  res += `
@@ -38434,7 +38486,7 @@ ${originalIndentation}`;
38434
38486
  let whitespace = "";
38435
38487
  if (spacer !== "") {
38436
38488
  indentation += spacer;
38437
- join12 = `,
38489
+ join11 = `,
38438
38490
  ${indentation}`;
38439
38491
  whitespace = " ";
38440
38492
  }
@@ -38443,7 +38495,7 @@ ${indentation}`;
38443
38495
  const tmp = stringifyArrayReplacer(key2, value[key2], stack, replacer, spacer, indentation);
38444
38496
  if (tmp !== undefined) {
38445
38497
  res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
38446
- separator = join12;
38498
+ separator = join11;
38447
38499
  }
38448
38500
  }
38449
38501
  if (spacer !== "" && separator.length > 1) {
@@ -38500,20 +38552,20 @@ ${originalIndentation}`;
38500
38552
  indentation += spacer;
38501
38553
  let res2 = `
38502
38554
  ${indentation}`;
38503
- const join13 = `,
38555
+ const join12 = `,
38504
38556
  ${indentation}`;
38505
38557
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
38506
38558
  let i = 0;
38507
38559
  for (;i < maximumValuesToStringify - 1; i++) {
38508
38560
  const tmp2 = stringifyIndent(String(i), value[i], stack, spacer, indentation);
38509
38561
  res2 += tmp2 !== undefined ? tmp2 : "null";
38510
- res2 += join13;
38562
+ res2 += join12;
38511
38563
  }
38512
38564
  const tmp = stringifyIndent(String(i), value[i], stack, spacer, indentation);
38513
38565
  res2 += tmp !== undefined ? tmp : "null";
38514
38566
  if (value.length - 1 > maximumBreadth) {
38515
38567
  const removedKeys = value.length - maximumBreadth - 1;
38516
- res2 += `${join13}"... ${getItemCount(removedKeys)} not stringified"`;
38568
+ res2 += `${join12}"... ${getItemCount(removedKeys)} not stringified"`;
38517
38569
  }
38518
38570
  res2 += `
38519
38571
  ${originalIndentation}`;
@@ -38529,16 +38581,16 @@ ${originalIndentation}`;
38529
38581
  return '"[Object]"';
38530
38582
  }
38531
38583
  indentation += spacer;
38532
- const join12 = `,
38584
+ const join11 = `,
38533
38585
  ${indentation}`;
38534
38586
  let res = "";
38535
38587
  let separator = "";
38536
38588
  let maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
38537
38589
  if (isTypedArrayWithEntries(value)) {
38538
- res += stringifyTypedArray(value, join12, maximumBreadth);
38590
+ res += stringifyTypedArray(value, join11, maximumBreadth);
38539
38591
  keys3 = keys3.slice(value.length);
38540
38592
  maximumPropertiesToStringify -= value.length;
38541
- separator = join12;
38593
+ separator = join11;
38542
38594
  }
38543
38595
  if (deterministic) {
38544
38596
  keys3 = sort2(keys3, comparator);
@@ -38549,13 +38601,13 @@ ${indentation}`;
38549
38601
  const tmp = stringifyIndent(key2, value[key2], stack, spacer, indentation);
38550
38602
  if (tmp !== undefined) {
38551
38603
  res += `${separator}${strEscape(key2)}: ${tmp}`;
38552
- separator = join12;
38604
+ separator = join11;
38553
38605
  }
38554
38606
  }
38555
38607
  if (keyLength > maximumBreadth) {
38556
38608
  const removedKeys = keyLength - maximumBreadth;
38557
38609
  res += `${separator}"...": "${getItemCount(removedKeys)} not stringified"`;
38558
- separator = join12;
38610
+ separator = join11;
38559
38611
  }
38560
38612
  if (separator !== "") {
38561
38613
  res = `
@@ -39801,6 +39853,20 @@ var hive_create = tool({
39801
39853
  parent_id: validated.parent_id
39802
39854
  });
39803
39855
  await adapter.markDirty(projectKey, cell.id);
39856
+ try {
39857
+ const event = createEvent("cell_created", {
39858
+ project_key: projectKey,
39859
+ cell_id: cell.id,
39860
+ title: validated.title,
39861
+ description: validated.description,
39862
+ issue_type: validated.type || "task",
39863
+ priority: validated.priority ?? 2,
39864
+ parent_id: validated.parent_id
39865
+ });
39866
+ await appendEvent(event, projectKey);
39867
+ } catch (error45) {
39868
+ console.warn("[hive_create] Failed to emit cell_created event:", error45);
39869
+ }
39804
39870
  const formatted = formatCellForOutput(cell);
39805
39871
  return JSON.stringify(formatted, null, 2);
39806
39872
  } catch (error45) {
@@ -39860,6 +39926,19 @@ var hive_create_epic = tool({
39860
39926
  subtasks: created.slice(1).map((c) => formatCellForOutput(c))
39861
39927
  };
39862
39928
  const effectiveProjectKey = args.project_key || projectKey;
39929
+ try {
39930
+ const epicCreatedEvent = createEvent("epic_created", {
39931
+ project_key: effectiveProjectKey,
39932
+ epic_id: epic.id,
39933
+ title: validated.epic_title,
39934
+ description: validated.epic_description,
39935
+ subtask_count: validated.subtasks.length,
39936
+ subtask_ids: created.slice(1).map((c) => c.id)
39937
+ });
39938
+ await appendEvent(epicCreatedEvent, effectiveProjectKey);
39939
+ } catch (error45) {
39940
+ console.warn("[hive_create_epic] Failed to emit epic_created event:", error45);
39941
+ }
39863
39942
  try {
39864
39943
  const event = createEvent("decomposition_generated", {
39865
39944
  project_key: effectiveProjectKey,
@@ -40024,6 +40103,23 @@ var hive_update = tool({
40024
40103
  cell = existingCell;
40025
40104
  }
40026
40105
  await adapter.markDirty(projectKey, cellId);
40106
+ try {
40107
+ const fieldsChanged = [];
40108
+ if (validated.status)
40109
+ fieldsChanged.push("status");
40110
+ if (validated.description !== undefined)
40111
+ fieldsChanged.push("description");
40112
+ if (validated.priority !== undefined)
40113
+ fieldsChanged.push("priority");
40114
+ const event = createEvent("cell_updated", {
40115
+ project_key: projectKey,
40116
+ cell_id: cellId,
40117
+ fields_changed: fieldsChanged
40118
+ });
40119
+ await appendEvent(event, projectKey);
40120
+ } catch (error45) {
40121
+ console.warn("[hive_update] Failed to emit cell_updated event:", error45);
40122
+ }
40027
40123
  const formatted = formatCellForOutput(cell);
40028
40124
  return JSON.stringify(formatted, null, 2);
40029
40125
  } catch (error45) {
@@ -40140,6 +40236,16 @@ var hive_close = tool({
40140
40236
  console.warn("[hive_close] Failed to emit SwarmCompletedEvent:", error45);
40141
40237
  }
40142
40238
  }
40239
+ try {
40240
+ const event = createEvent("cell_closed", {
40241
+ project_key: projectKey,
40242
+ cell_id: cellId,
40243
+ reason: validated.reason
40244
+ });
40245
+ await appendEvent(event, projectKey);
40246
+ } catch (error45) {
40247
+ console.warn("[hive_close] Failed to emit cell_closed event:", error45);
40248
+ }
40143
40249
  return `Closed ${cell.id}: ${validated.reason}`;
40144
40250
  } catch (error45) {
40145
40251
  const message = error45 instanceof Error ? error45.message : String(error45);
@@ -40165,6 +40271,17 @@ var hive_start = tool({
40165
40271
  const cellId = await resolvePartialId(adapter, projectKey, args.id) || args.id;
40166
40272
  const cell = await adapter.changeCellStatus(projectKey, cellId, "in_progress");
40167
40273
  await adapter.markDirty(projectKey, cellId);
40274
+ try {
40275
+ const event = createEvent("cell_status_changed", {
40276
+ project_key: projectKey,
40277
+ cell_id: cellId,
40278
+ old_status: "open",
40279
+ new_status: "in_progress"
40280
+ });
40281
+ await appendEvent(event, projectKey);
40282
+ } catch (error45) {
40283
+ console.warn("[hive_start] Failed to emit cell_status_changed event:", error45);
40284
+ }
40168
40285
  return `Started: ${cell.id}`;
40169
40286
  } catch (error45) {
40170
40287
  const message = error45 instanceof Error ? error45.message : String(error45);
@@ -40353,11 +40470,25 @@ var hive_sync = tool({
40353
40470
  }
40354
40471
  const remoteCheckResult = await runGitCommand(["remote"]);
40355
40472
  const hasRemote = remoteCheckResult.stdout.trim() !== "";
40473
+ let pushSuccess = false;
40356
40474
  if (hasRemote) {
40357
40475
  const pushResult = await withTimeout(runGitCommand(["push"]), TIMEOUT_MS, "git push");
40358
40476
  if (pushResult.exitCode !== 0) {
40359
40477
  throw new HiveError(`Failed to push: ${pushResult.stderr}`, "git push", pushResult.exitCode);
40360
40478
  }
40479
+ pushSuccess = true;
40480
+ }
40481
+ try {
40482
+ const event = createEvent("hive_synced", {
40483
+ project_key: projectKey,
40484
+ cells_synced: flushResult.cellsExported,
40485
+ push_success: pushSuccess
40486
+ });
40487
+ await appendEvent(event, projectKey);
40488
+ } catch (error45) {
40489
+ console.warn("[hive_sync] Failed to emit hive_synced event:", error45);
40490
+ }
40491
+ if (hasRemote) {
40361
40492
  return "Hive synced and pushed successfully";
40362
40493
  } else {
40363
40494
  return "Hive synced successfully (no remote configured)";
@@ -44943,9 +45074,9 @@ import {
44943
45074
  releaseSwarmFiles as releaseSwarmFiles2,
44944
45075
  sendSwarmMessage as sendSwarmMessage3,
44945
45076
  getAgent,
44946
- createEvent as createEvent2,
45077
+ createEvent as createEvent3,
44947
45078
  appendEvent as appendEvent2,
44948
- getSwarmMailLibSQL as getSwarmMailLibSQL2
45079
+ getSwarmMailLibSQL as getSwarmMailLibSQL3
44949
45080
  } from "swarm-mail";
44950
45081
  init_skills();
44951
45082
 
@@ -45448,9 +45579,9 @@ var swarm_review = tool({
45448
45579
  downstream_tasks: downstreamTasks.length > 0 ? downstreamTasks : undefined
45449
45580
  });
45450
45581
  try {
45451
- const { createEvent: createEvent2, appendEvent: appendEvent2 } = await import("swarm-mail");
45582
+ const { createEvent: createEvent3, appendEvent: appendEvent2 } = await import("swarm-mail");
45452
45583
  const attempt = getReviewStatus(args.task_id).attempt_count || 1;
45453
- const reviewStartedEvent = createEvent2("review_started", {
45584
+ const reviewStartedEvent = createEvent3("review_started", {
45454
45585
  project_key: args.project_key,
45455
45586
  epic_id: args.epic_id,
45456
45587
  bead_id: args.task_id,
@@ -45539,9 +45670,9 @@ var swarm_review_feedback = tool({
45539
45670
  console.warn("[swarm_review_feedback] Failed to trace review_decision:", error45);
45540
45671
  }
45541
45672
  try {
45542
- const { createEvent: createEvent2, appendEvent: appendEvent2 } = await import("swarm-mail");
45673
+ const { createEvent: createEvent3, appendEvent: appendEvent2 } = await import("swarm-mail");
45543
45674
  const attempt = getReviewStatus(args.task_id).attempt_count || 1;
45544
- const reviewCompletedEvent = createEvent2("review_completed", {
45675
+ const reviewCompletedEvent = createEvent3("review_completed", {
45545
45676
  project_key: args.project_key,
45546
45677
  epic_id: epicId,
45547
45678
  bead_id: args.task_id,
@@ -45610,9 +45741,9 @@ You may now complete the task with \`swarm_complete\`.`,
45610
45741
  console.warn("[swarm_review_feedback] Failed to trace review_decision:", error45);
45611
45742
  }
45612
45743
  try {
45613
- const { createEvent: createEvent2, appendEvent: appendEvent2 } = await import("swarm-mail");
45744
+ const { createEvent: createEvent3, appendEvent: appendEvent2 } = await import("swarm-mail");
45614
45745
  const status = remaining <= 0 ? "blocked" : "needs_changes";
45615
- const reviewCompletedEvent = createEvent2("review_completed", {
45746
+ const reviewCompletedEvent = createEvent3("review_completed", {
45616
45747
  project_key: args.project_key,
45617
45748
  epic_id: epicId,
45618
45749
  bead_id: args.task_id,
@@ -46168,7 +46299,7 @@ var swarm_progress = tool({
46168
46299
  }
46169
46300
  };
46170
46301
  const checkpointData = JSON.stringify(checkpoint);
46171
- const checkpointEvent = createEvent2("swarm_checkpointed", {
46302
+ const checkpointEvent = createEvent3("swarm_checkpointed", {
46172
46303
  project_key: args.project_key,
46173
46304
  ...checkpoint,
46174
46305
  checkpoint_size_bytes: Buffer.byteLength(checkpointData, "utf8"),
@@ -46176,7 +46307,7 @@ var swarm_progress = tool({
46176
46307
  });
46177
46308
  await appendEvent2(checkpointEvent, args.project_key);
46178
46309
  const checkpointId = `ckpt-${Date.now()}-${args.bead_id}`;
46179
- const createdEvent = createEvent2("checkpoint_created", {
46310
+ const createdEvent = createEvent3("checkpoint_created", {
46180
46311
  project_key: args.project_key,
46181
46312
  epic_id: epicId,
46182
46313
  bead_id: args.bead_id,
@@ -46429,7 +46560,7 @@ This will be recorded as a negative learning signal.`;
46429
46560
  let deferredResolved = false;
46430
46561
  let deferredError;
46431
46562
  try {
46432
- const swarmMail = await getSwarmMailLibSQL2(args.project_key);
46563
+ const swarmMail = await getSwarmMailLibSQL3(args.project_key);
46433
46564
  const db = await swarmMail.getDatabase();
46434
46565
  const deferredUrl = `deferred:${args.bead_id}`;
46435
46566
  const checkResult = await db.query(`SELECT url, resolved FROM deferred WHERE url = ? AND resolved = 0`, [deferredUrl]);
@@ -46458,16 +46589,16 @@ This will be recorded as a negative learning signal.`;
46458
46589
  syncError = error45 instanceof Error ? error45.message : String(error45);
46459
46590
  console.warn(`[swarm_complete] Auto-sync failed (non-fatal): ${syncError}`);
46460
46591
  }
46592
+ const completionDurationMs = args.start_time ? Date.now() - args.start_time : 0;
46593
+ const eventEpicId = cell.parent_id || (args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id);
46461
46594
  try {
46462
- const durationMs2 = args.start_time ? Date.now() - args.start_time : 0;
46463
- const eventEpicId = cell.parent_id || (args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id);
46464
- const event = createEvent2("subtask_outcome", {
46595
+ const event = createEvent3("subtask_outcome", {
46465
46596
  project_key: args.project_key,
46466
46597
  epic_id: eventEpicId,
46467
46598
  bead_id: args.bead_id,
46468
46599
  planned_files: args.planned_files || [],
46469
46600
  actual_files: args.files_touched || [],
46470
- duration_ms: durationMs2,
46601
+ duration_ms: completionDurationMs,
46471
46602
  error_count: args.error_count || 0,
46472
46603
  retry_count: args.retry_count || 0,
46473
46604
  success: true,
@@ -46478,8 +46609,21 @@ This will be recorded as a negative learning signal.`;
46478
46609
  } catch (error45) {
46479
46610
  console.warn("[swarm_complete] Failed to emit SubtaskOutcomeEvent:", error45);
46480
46611
  }
46612
+ try {
46613
+ const workerCompletedEvent = createEvent3("worker_completed", {
46614
+ project_key: args.project_key,
46615
+ epic_id: eventEpicId,
46616
+ bead_id: args.bead_id,
46617
+ worker_agent: args.agent_name,
46618
+ success: true,
46619
+ duration_ms: completionDurationMs,
46620
+ files_touched: args.files_touched || []
46621
+ });
46622
+ await appendEvent2(workerCompletedEvent, args.project_key);
46623
+ } catch (error45) {
46624
+ console.warn("[swarm_complete] Failed to emit worker_completed event:", error45);
46625
+ }
46481
46626
  let capturedStrategy;
46482
- const durationMs = args.start_time ? Date.now() - args.start_time : 0;
46483
46627
  const memoryInfo = formatMemoryStoreOnSuccess(args.bead_id, args.summary, args.files_touched || [], capturedStrategy);
46484
46628
  let memoryStored = false;
46485
46629
  let memoryError;
@@ -46596,7 +46740,7 @@ Files touched: ${args.files_touched?.join(", ") || "none recorded"}`,
46596
46740
  };
46597
46741
  try {
46598
46742
  const { captureSubtaskOutcome: captureSubtaskOutcome2 } = await Promise.resolve().then(() => (init_eval_capture(), exports_eval_capture));
46599
- const durationMs2 = args.start_time ? Date.now() - args.start_time : 0;
46743
+ const durationMs = args.start_time ? Date.now() - args.start_time : 0;
46600
46744
  const evalEpicId = cell.parent_id || epicId2;
46601
46745
  captureSubtaskOutcome2({
46602
46746
  epicId: evalEpicId,
@@ -46605,7 +46749,7 @@ Files touched: ${args.files_touched?.join(", ") || "none recorded"}`,
46605
46749
  title: cell.title,
46606
46750
  plannedFiles: args.planned_files || [],
46607
46751
  actualFiles: args.files_touched || [],
46608
- durationMs: durationMs2,
46752
+ durationMs,
46609
46753
  errorCount: args.error_count || 0,
46610
46754
  retryCount: args.retry_count || 0,
46611
46755
  success: true
@@ -46614,7 +46758,7 @@ Files touched: ${args.files_touched?.join(", ") || "none recorded"}`,
46614
46758
  console.warn("[swarm_complete] Failed to capture subtask outcome:", error45);
46615
46759
  }
46616
46760
  try {
46617
- const durationMs2 = args.start_time ? Date.now() - args.start_time : 0;
46761
+ const durationMs = args.start_time ? Date.now() - args.start_time : 0;
46618
46762
  captureCoordinatorEvent({
46619
46763
  session_id: _ctx.sessionID || "unknown",
46620
46764
  epic_id: epicId2,
@@ -46623,7 +46767,7 @@ Files touched: ${args.files_touched?.join(", ") || "none recorded"}`,
46623
46767
  outcome_type: "subtask_success",
46624
46768
  payload: {
46625
46769
  bead_id: args.bead_id,
46626
- duration_ms: durationMs2,
46770
+ duration_ms: durationMs,
46627
46771
  files_touched: args.files_touched || [],
46628
46772
  verification_passed: verificationResult?.passed ?? false,
46629
46773
  verification_skipped: args.skip_verification ?? false
@@ -47097,7 +47241,7 @@ var swarm_checkpoint = tool({
47097
47241
  }
47098
47242
  };
47099
47243
  const checkpointData = JSON.stringify(checkpoint);
47100
- const event = createEvent2("swarm_checkpointed", {
47244
+ const event = createEvent3("swarm_checkpointed", {
47101
47245
  project_key: args.project_key,
47102
47246
  epic_id: args.epic_id,
47103
47247
  bead_id: args.bead_id,
@@ -47139,8 +47283,8 @@ var swarm_recover = tool({
47139
47283
  },
47140
47284
  async execute(args) {
47141
47285
  try {
47142
- const { getSwarmMailLibSQL: getSwarmMailLibSQL3 } = await import("swarm-mail");
47143
- const swarmMail = await getSwarmMailLibSQL3(args.project_key);
47286
+ const { getSwarmMailLibSQL: getSwarmMailLibSQL4 } = await import("swarm-mail");
47287
+ const swarmMail = await getSwarmMailLibSQL4(args.project_key);
47144
47288
  const db = await swarmMail.getDatabase();
47145
47289
  const result = await db.query(`SELECT * FROM swarm_contexts
47146
47290
  WHERE epic_id = $1
@@ -47167,7 +47311,7 @@ var swarm_recover = tool({
47167
47311
  created_at: row.created_at,
47168
47312
  updated_at: row.updated_at
47169
47313
  };
47170
- const event = createEvent2("swarm_recovered", {
47314
+ const event = createEvent3("swarm_recovered", {
47171
47315
  project_key: args.project_key,
47172
47316
  epic_id: args.epic_id,
47173
47317
  bead_id: context.bead_id,
@@ -47342,7 +47486,7 @@ init_eval_capture();
47342
47486
 
47343
47487
  // src/memory-tools.ts
47344
47488
  init_dist();
47345
- import { getSwarmMailLibSQL as getSwarmMailLibSQL3 } from "swarm-mail";
47489
+ import { getSwarmMailLibSQL as getSwarmMailLibSQL4, createEvent as createEvent4, appendEvent as appendEvent3 } from "swarm-mail";
47346
47490
 
47347
47491
  // ../../node_modules/.bun/effect@3.19.12/node_modules/effect/dist/esm/Function.js
47348
47492
  var isFunction = (input) => typeof input === "function";
@@ -60959,7 +61103,7 @@ async function getMemoryAdapter(projectPath) {
60959
61103
  if (cachedAdapter && cachedProjectPath === path3) {
60960
61104
  return cachedAdapter;
60961
61105
  }
60962
- const swarmMail = await getSwarmMailLibSQL3(path3);
61106
+ const swarmMail = await getSwarmMailLibSQL4(path3);
60963
61107
  const dbAdapter = await swarmMail.getDatabase();
60964
61108
  cachedAdapter = await createMemoryAdapter(dbAdapter);
60965
61109
  cachedProjectPath = path3;
@@ -60980,6 +61124,21 @@ var semantic_memory_store = tool({
60980
61124
  async execute(args2, ctx) {
60981
61125
  const adapter = await getMemoryAdapter();
60982
61126
  const result = await adapter.store(args2);
61127
+ try {
61128
+ const projectKey = cachedProjectPath || process.cwd();
61129
+ const tags = args2.tags ? args2.tags.split(",").map((t) => t.trim()) : [];
61130
+ const event = createEvent4("memory_stored", {
61131
+ project_key: projectKey,
61132
+ memory_id: result.id,
61133
+ content_preview: args2.information.slice(0, 100),
61134
+ tags,
61135
+ auto_tagged: args2.autoTag,
61136
+ collection: args2.collection
61137
+ });
61138
+ await appendEvent3(event, projectKey);
61139
+ } catch (error45) {
61140
+ console.warn("[semantic_memory_store] Failed to emit memory_stored event:", error45);
61141
+ }
60983
61142
  return JSON.stringify(result, null, 2);
60984
61143
  }
60985
61144
  });
@@ -60993,8 +61152,25 @@ var semantic_memory_find = tool({
60993
61152
  fts: tool.schema.boolean().optional().describe("Use full-text search instead of vector search (default: false)")
60994
61153
  },
60995
61154
  async execute(args2, ctx) {
61155
+ const startTime = Date.now();
60996
61156
  const adapter = await getMemoryAdapter();
60997
61157
  const result = await adapter.find(args2);
61158
+ const duration3 = Date.now() - startTime;
61159
+ try {
61160
+ const projectKey = cachedProjectPath || process.cwd();
61161
+ const topScore = result.results.length > 0 ? result.results[0].score : undefined;
61162
+ const event = createEvent4("memory_found", {
61163
+ project_key: projectKey,
61164
+ query: args2.query,
61165
+ result_count: result.results.length,
61166
+ top_score: topScore,
61167
+ search_duration_ms: duration3,
61168
+ used_fts: args2.fts
61169
+ });
61170
+ await appendEvent3(event, projectKey);
61171
+ } catch (error45) {
61172
+ console.warn("[semantic_memory_find] Failed to emit memory_found event:", error45);
61173
+ }
60998
61174
  return JSON.stringify(result, null, 2);
60999
61175
  }
61000
61176
  });
@@ -61017,6 +61193,18 @@ var semantic_memory_remove = tool({
61017
61193
  async execute(args2, ctx) {
61018
61194
  const adapter = await getMemoryAdapter();
61019
61195
  const result = await adapter.remove(args2);
61196
+ if (result.success) {
61197
+ try {
61198
+ const projectKey = cachedProjectPath || process.cwd();
61199
+ const event = createEvent4("memory_deleted", {
61200
+ project_key: projectKey,
61201
+ memory_id: args2.id
61202
+ });
61203
+ await appendEvent3(event, projectKey);
61204
+ } catch (error45) {
61205
+ console.warn("[semantic_memory_remove] Failed to emit memory_deleted event:", error45);
61206
+ }
61207
+ }
61020
61208
  return JSON.stringify(result, null, 2);
61021
61209
  }
61022
61210
  });
@@ -61028,6 +61216,19 @@ var semantic_memory_validate = tool({
61028
61216
  async execute(args2, ctx) {
61029
61217
  const adapter = await getMemoryAdapter();
61030
61218
  const result = await adapter.validate(args2);
61219
+ if (result.success) {
61220
+ try {
61221
+ const projectKey = cachedProjectPath || process.cwd();
61222
+ const event = createEvent4("memory_validated", {
61223
+ project_key: projectKey,
61224
+ memory_id: args2.id,
61225
+ decay_reset: true
61226
+ });
61227
+ await appendEvent3(event, projectKey);
61228
+ } catch (error45) {
61229
+ console.warn("[semantic_memory_validate] Failed to emit memory_validated event:", error45);
61230
+ }
61231
+ }
61031
61232
  return JSON.stringify(result, null, 2);
61032
61233
  }
61033
61234
  });
@@ -61075,6 +61276,18 @@ var semantic_memory_upsert = tool({
61075
61276
  async execute(args2, ctx) {
61076
61277
  const adapter = await getMemoryAdapter();
61077
61278
  const result = await adapter.upsert(args2);
61279
+ try {
61280
+ const projectKey = cachedProjectPath || process.cwd();
61281
+ const event = createEvent4("memory_updated", {
61282
+ project_key: projectKey,
61283
+ memory_id: result.memoryId || "unknown",
61284
+ operation: result.operation,
61285
+ reason: result.reason
61286
+ });
61287
+ await appendEvent3(event, projectKey);
61288
+ } catch (error45) {
61289
+ console.warn("[semantic_memory_upsert] Failed to emit memory_updated event:", error45);
61290
+ }
61078
61291
  return JSON.stringify(result, null, 2);
61079
61292
  }
61080
61293
  });
@@ -62060,9 +62273,9 @@ var swarm_spawn_subtask = tool({
62060
62273
  }
62061
62274
  if (args2.project_path) {
62062
62275
  try {
62063
- const { createEvent: createEvent3, appendEvent: appendEvent3 } = await import("swarm-mail");
62276
+ const { createEvent: createEvent5, appendEvent: appendEvent4 } = await import("swarm-mail");
62064
62277
  const spawnOrder = 0;
62065
- const workerSpawnedEvent = createEvent3("worker_spawned", {
62278
+ const workerSpawnedEvent = createEvent5("worker_spawned", {
62066
62279
  project_key: args2.project_path,
62067
62280
  epic_id: args2.epic_id,
62068
62281
  bead_id: args2.bead_id,
@@ -62072,7 +62285,7 @@ var swarm_spawn_subtask = tool({
62072
62285
  spawn_order: spawnOrder,
62073
62286
  is_parallel: false
62074
62287
  });
62075
- await appendEvent3(workerSpawnedEvent, args2.project_path);
62288
+ await appendEvent4(workerSpawnedEvent, args2.project_path);
62076
62289
  } catch (error45) {
62077
62290
  console.warn("[swarm_spawn_subtask] Failed to emit WorkerSpawnedEvent:", error45);
62078
62291
  }
@@ -63704,7 +63917,7 @@ import {
63704
63917
  agentActivity,
63705
63918
  checkpointFrequency,
63706
63919
  failedDecompositions,
63707
- getSwarmMailLibSQL as getSwarmMailLibSQL4,
63920
+ getSwarmMailLibSQL as getSwarmMailLibSQL5,
63708
63921
  humanFeedback,
63709
63922
  lockContention,
63710
63923
  messageLatency,
@@ -63769,7 +63982,7 @@ var swarm_analytics = tool({
63769
63982
  async execute(args2) {
63770
63983
  try {
63771
63984
  const projectPath = process.cwd();
63772
- const db = await getSwarmMailLibSQL4(projectPath);
63985
+ const db = await getSwarmMailLibSQL5(projectPath);
63773
63986
  const filters = {
63774
63987
  project_key: projectPath
63775
63988
  };
@@ -63839,7 +64052,7 @@ var swarm_query = tool({
63839
64052
  async execute(args2) {
63840
64053
  try {
63841
64054
  const projectPath = process.cwd();
63842
- const swarmMail = await getSwarmMailLibSQL4(projectPath);
64055
+ const swarmMail = await getSwarmMailLibSQL5(projectPath);
63843
64056
  const db = await swarmMail.getDatabase();
63844
64057
  if (!args2.sql.trim().toLowerCase().startsWith("select")) {
63845
64058
  return JSON.stringify({
@@ -63889,7 +64102,7 @@ var swarm_diagnose = tool({
63889
64102
  async execute(args2) {
63890
64103
  try {
63891
64104
  const projectPath = process.cwd();
63892
- const swarmMail = await getSwarmMailLibSQL4(projectPath);
64105
+ const swarmMail = await getSwarmMailLibSQL5(projectPath);
63893
64106
  const db = await swarmMail.getDatabase();
63894
64107
  const diagnosis = [];
63895
64108
  const include = args2.include || [
@@ -64000,7 +64213,7 @@ var swarm_insights = tool({
64000
64213
  });
64001
64214
  }
64002
64215
  const projectPath = process.cwd();
64003
- const swarmMail = await getSwarmMailLibSQL4(projectPath);
64216
+ const swarmMail = await getSwarmMailLibSQL5(projectPath);
64004
64217
  const db = await swarmMail.getDatabase();
64005
64218
  const insights = [];
64006
64219
  if (args2.metrics.includes("success_rate")) {
@@ -64060,411 +64273,6 @@ var observabilityTools = {
64060
64273
  swarm_insights
64061
64274
  };
64062
64275
 
64063
- // src/eval-runner.ts
64064
- init_dist();
64065
- import { runEvalite } from "evalite/runner";
64066
- import { createInMemoryStorage } from "evalite/in-memory-storage";
64067
- import fs3 from "node:fs/promises";
64068
- import path4 from "node:path";
64069
-
64070
- // src/eval-history.ts
64071
- import * as fs2 from "node:fs";
64072
- import * as path3 from "node:path";
64073
- var DEFAULT_EVAL_HISTORY_PATH = ".opencode/eval-history.jsonl";
64074
- var VARIANCE_THRESHOLD = 0.1;
64075
- var BOOTSTRAP_THRESHOLD = 10;
64076
- var STABILIZATION_THRESHOLD = 50;
64077
- function getEvalHistoryPath(projectPath) {
64078
- return path3.join(projectPath, DEFAULT_EVAL_HISTORY_PATH);
64079
- }
64080
- function ensureEvalHistoryDir(projectPath) {
64081
- const historyPath = getEvalHistoryPath(projectPath);
64082
- const dir = path3.dirname(historyPath);
64083
- if (!fs2.existsSync(dir)) {
64084
- fs2.mkdirSync(dir, { recursive: true });
64085
- }
64086
- }
64087
- function recordEvalRun(projectPath, run) {
64088
- ensureEvalHistoryDir(projectPath);
64089
- const historyPath = getEvalHistoryPath(projectPath);
64090
- const line = `${JSON.stringify(run)}
64091
- `;
64092
- fs2.appendFileSync(historyPath, line, "utf-8");
64093
- }
64094
- function readAllRecords(projectPath) {
64095
- const historyPath = getEvalHistoryPath(projectPath);
64096
- if (!fs2.existsSync(historyPath)) {
64097
- return [];
64098
- }
64099
- const content = fs2.readFileSync(historyPath, "utf-8");
64100
- const lines = content.trim().split(`
64101
- `).filter(Boolean);
64102
- return lines.map((line) => JSON.parse(line));
64103
- }
64104
- function getScoreHistory(projectPath, evalName) {
64105
- return readAllRecords(projectPath).filter((run) => run.eval_name === evalName);
64106
- }
64107
- function calculateVariance(scores) {
64108
- if (scores.length <= 1) {
64109
- return 0;
64110
- }
64111
- const mean = scores.reduce((sum2, score) => sum2 + score, 0) / scores.length;
64112
- const variance5 = scores.reduce((sum2, score) => {
64113
- const deviation = score - mean;
64114
- return sum2 + deviation * deviation;
64115
- }, 0) / scores.length;
64116
- return variance5;
64117
- }
64118
- function getPhase(projectPath, evalName) {
64119
- const history = getScoreHistory(projectPath, evalName);
64120
- if (history.length < BOOTSTRAP_THRESHOLD) {
64121
- return "bootstrap";
64122
- }
64123
- if (history.length <= STABILIZATION_THRESHOLD) {
64124
- return "stabilization";
64125
- }
64126
- const scores = history.map((run) => run.score);
64127
- const variance5 = calculateVariance(scores);
64128
- if (variance5 < VARIANCE_THRESHOLD) {
64129
- return "production";
64130
- }
64131
- return "stabilization";
64132
- }
64133
-
64134
- // src/eval-gates.ts
64135
- var DEFAULT_THRESHOLDS = {
64136
- stabilization: 0.1,
64137
- production: 0.05
64138
- };
64139
- function calculateBaseline(history, currentScore) {
64140
- if (history.length === 0) {
64141
- return currentScore;
64142
- }
64143
- return history.reduce((sum2, run) => sum2 + run.score, 0) / history.length;
64144
- }
64145
- function calculateRegression(baseline, currentScore) {
64146
- if (baseline === 0) {
64147
- return 0;
64148
- }
64149
- return (baseline - currentScore) / baseline;
64150
- }
64151
- function formatRegressionMessage(regressionPercent, baseline, currentScore) {
64152
- return `${(regressionPercent * 100).toFixed(1)}% regression (baseline: ${baseline.toFixed(2)}, current: ${currentScore.toFixed(2)})`;
64153
- }
64154
- function checkGate(projectPath, evalName, currentScore, config2) {
64155
- const thresholds = {
64156
- stabilization: config2?.stabilizationThreshold ?? DEFAULT_THRESHOLDS.stabilization,
64157
- production: config2?.productionThreshold ?? DEFAULT_THRESHOLDS.production
64158
- };
64159
- const phase = getPhase(projectPath, evalName);
64160
- const history = getScoreHistory(projectPath, evalName);
64161
- if (phase === "bootstrap") {
64162
- return {
64163
- passed: true,
64164
- phase: "bootstrap",
64165
- message: `Bootstrap phase (${history.length}/10 runs) - collecting data`,
64166
- currentScore
64167
- };
64168
- }
64169
- const baseline = calculateBaseline(history, currentScore);
64170
- const regressionPercent = calculateRegression(baseline, currentScore);
64171
- const regressionMsg = formatRegressionMessage(regressionPercent, baseline, currentScore);
64172
- if (phase === "stabilization") {
64173
- if (regressionPercent > thresholds.stabilization) {
64174
- return {
64175
- passed: true,
64176
- phase: "stabilization",
64177
- message: `Stabilization phase: ${regressionMsg} - exceeds ${(thresholds.stabilization * 100).toFixed(0)}% threshold but still passing`,
64178
- baseline,
64179
- currentScore,
64180
- regressionPercent
64181
- };
64182
- }
64183
- if (history.length > 50) {
64184
- const scores = history.map((run) => run.score);
64185
- const variance5 = calculateVariance(scores);
64186
- return {
64187
- passed: true,
64188
- phase: "stabilization",
64189
- message: `Stabilization phase: ${regressionMsg} - acceptable. High variance (${variance5.toFixed(3)}) prevents production phase.`,
64190
- baseline,
64191
- currentScore,
64192
- regressionPercent
64193
- };
64194
- }
64195
- return {
64196
- passed: true,
64197
- phase: "stabilization",
64198
- message: `Stabilization phase: ${regressionMsg} - acceptable`,
64199
- baseline,
64200
- currentScore,
64201
- regressionPercent
64202
- };
64203
- }
64204
- if (regressionPercent > thresholds.production) {
64205
- return {
64206
- passed: false,
64207
- phase: "production",
64208
- message: `Production phase FAIL: ${regressionMsg} - exceeds ${(thresholds.production * 100).toFixed(0)}% threshold`,
64209
- baseline,
64210
- currentScore,
64211
- regressionPercent
64212
- };
64213
- }
64214
- return {
64215
- passed: true,
64216
- phase: "production",
64217
- message: `Production phase: ${regressionMsg} - acceptable`,
64218
- baseline,
64219
- currentScore,
64220
- regressionPercent
64221
- };
64222
- }
64223
-
64224
- // src/eval-learning.ts
64225
- var DEFAULT_EVAL_LEARNING_CONFIG = {
64226
- dropThreshold: 0.15,
64227
- windowSize: 5
64228
- };
64229
- function calculateRollingAverage(history, windowSize = 5) {
64230
- if (history.length === 0) {
64231
- return 0;
64232
- }
64233
- const recentRuns = history.slice(-windowSize);
64234
- const sum2 = recentRuns.reduce((acc, run) => acc + run.score, 0);
64235
- return sum2 / recentRuns.length;
64236
- }
64237
- function isSignificantDrop(currentScore, baseline, threshold = 0.15) {
64238
- if (baseline === 0) {
64239
- return false;
64240
- }
64241
- const drop3 = (baseline - currentScore) / baseline;
64242
- return drop3 >= threshold;
64243
- }
64244
- function formatFailureContext(evalName, currentScore, baseline, scorerContext) {
64245
- const dropPercentage = baseline > 0 ? (baseline - currentScore) / baseline * 100 : 0;
64246
- const lines = [
64247
- `Eval "${evalName}" regression detected:`,
64248
- `- Current score: ${currentScore.toFixed(2)}`,
64249
- `- Baseline (rolling avg): ${baseline.toFixed(2)}`,
64250
- `- Drop: ${dropPercentage.toFixed(1)}%`
64251
- ];
64252
- if (scorerContext) {
64253
- lines.push("", "Scorer context:", scorerContext);
64254
- }
64255
- lines.push("", "Action: Review recent changes that may have caused regression.", "Query this memory when generating future prompts for this eval.");
64256
- return lines.join(`
64257
- `);
64258
- }
64259
- async function learnFromEvalFailure(evalName, currentScore, history, memoryAdapter, options2) {
64260
- const config2 = options2?.config ?? DEFAULT_EVAL_LEARNING_CONFIG;
64261
- const baseline = calculateRollingAverage(history, config2.windowSize);
64262
- const dropPercentage = baseline > 0 ? (baseline - currentScore) / baseline : 0;
64263
- const significant = isSignificantDrop(currentScore, baseline, config2.dropThreshold);
64264
- const result = {
64265
- triggered: significant,
64266
- baseline,
64267
- current: currentScore,
64268
- drop_percentage: dropPercentage
64269
- };
64270
- if (significant) {
64271
- const information = formatFailureContext(evalName, currentScore, baseline, options2?.scorerContext);
64272
- const tags = ["eval-failure", evalName, "regression"].join(",");
64273
- const metadata = JSON.stringify({
64274
- eval_name: evalName,
64275
- baseline_score: baseline,
64276
- current_score: currentScore,
64277
- drop_percentage: dropPercentage,
64278
- timestamp: new Date().toISOString()
64279
- });
64280
- const storeResult = await memoryAdapter.store({
64281
- information,
64282
- tags,
64283
- metadata
64284
- });
64285
- if (storeResult.id) {
64286
- result.memory_id = storeResult.id;
64287
- }
64288
- }
64289
- return result;
64290
- }
64291
-
64292
- // src/eval-runner.ts
64293
- async function runEvals(options2 = {}) {
64294
- const {
64295
- cwd = process.cwd(),
64296
- suiteFilter,
64297
- scoreThreshold,
64298
- outputPath: userOutputPath
64299
- } = options2;
64300
- try {
64301
- const projectRoot = cwd.endsWith("src") ? path4.dirname(cwd) : cwd;
64302
- const evalsDir = path4.join(projectRoot, "evals");
64303
- let evalPath;
64304
- if (suiteFilter) {
64305
- try {
64306
- const files = await fs3.readdir(evalsDir);
64307
- const matchingFiles = files.filter((f) => f.toLowerCase().includes(suiteFilter.toLowerCase()));
64308
- if (matchingFiles.length === 0) {
64309
- return {
64310
- success: true,
64311
- totalSuites: 0,
64312
- totalEvals: 0,
64313
- averageScore: 0,
64314
- suites: []
64315
- };
64316
- }
64317
- evalPath = path4.join(evalsDir, matchingFiles[0]);
64318
- } catch (err) {
64319
- return {
64320
- success: false,
64321
- totalSuites: 0,
64322
- totalEvals: 0,
64323
- averageScore: 0,
64324
- suites: [],
64325
- error: `Failed to read evals directory: ${err instanceof Error ? err.message : String(err)}`
64326
- };
64327
- }
64328
- } else {
64329
- evalPath = evalsDir;
64330
- }
64331
- const outputPath = userOutputPath || path4.join(projectRoot, `.evalite-results-${Date.now()}.json`);
64332
- const isTemporaryOutput = !userOutputPath;
64333
- const storage = createInMemoryStorage();
64334
- await runEvalite({
64335
- path: evalPath,
64336
- cwd: projectRoot,
64337
- mode: "run-once-and-exit",
64338
- scoreThreshold,
64339
- outputPath,
64340
- hideTable: true,
64341
- storage,
64342
- disableServer: true
64343
- });
64344
- let outputJson;
64345
- try {
64346
- outputJson = await fs3.readFile(outputPath, "utf-8");
64347
- } catch (err) {
64348
- return {
64349
- success: false,
64350
- totalSuites: 0,
64351
- totalEvals: 0,
64352
- averageScore: 0,
64353
- suites: [],
64354
- error: `No results file generated: ${err instanceof Error ? err.message : String(err)}`
64355
- };
64356
- }
64357
- const output = JSON.parse(outputJson);
64358
- if (isTemporaryOutput) {
64359
- await fs3.unlink(outputPath).catch(() => {});
64360
- }
64361
- const suites = output.evals.map((evalItem) => ({
64362
- name: evalItem.name,
64363
- filepath: evalItem.filepath,
64364
- status: evalItem.status,
64365
- duration: evalItem.duration,
64366
- averageScore: evalItem.averageScore,
64367
- evalCount: evalItem.results.length,
64368
- evals: evalItem.results.map((r) => ({
64369
- input: r.input,
64370
- output: r.output,
64371
- expected: r.expected,
64372
- scores: r.scores.map((s) => ({
64373
- name: s.name,
64374
- score: s.score,
64375
- description: s.description
64376
- }))
64377
- }))
64378
- }));
64379
- for (const suite of suites) {
64380
- const history = getScoreHistory(projectRoot, suite.name);
64381
- recordEvalRun(projectRoot, {
64382
- timestamp: new Date().toISOString(),
64383
- eval_name: suite.name,
64384
- score: suite.averageScore,
64385
- run_count: history.length + 1
64386
- });
64387
- }
64388
- const gateResults = [];
64389
- for (const suite of suites) {
64390
- const history = getScoreHistory(projectRoot, suite.name);
64391
- const gate = checkGate(projectRoot, suite.name, suite.averageScore);
64392
- gateResults.push({ suite: suite.name, ...gate });
64393
- if (!gate.passed) {
64394
- try {
64395
- const memoryAdapter = await getMemoryAdapter();
64396
- await learnFromEvalFailure(suite.name, suite.averageScore, history, memoryAdapter);
64397
- } catch (e) {
64398
- console.warn(`Failed to store learning for ${suite.name}:`, e);
64399
- }
64400
- }
64401
- }
64402
- const totalEvals = suites.reduce((sum2, s) => sum2 + s.evalCount, 0);
64403
- const averageScore = suites.length > 0 ? suites.reduce((sum2, s) => sum2 + s.averageScore, 0) / suites.length : 0;
64404
- const thresholdPassed = scoreThreshold === undefined || averageScore * 100 >= scoreThreshold;
64405
- return {
64406
- success: thresholdPassed,
64407
- totalSuites: suites.length,
64408
- totalEvals,
64409
- averageScore,
64410
- suites,
64411
- gateResults
64412
- };
64413
- } catch (error45) {
64414
- return {
64415
- success: false,
64416
- totalSuites: 0,
64417
- totalEvals: 0,
64418
- averageScore: 0,
64419
- suites: [],
64420
- error: error45 instanceof Error ? error45.message : String(error45)
64421
- };
64422
- }
64423
- }
64424
- var eval_run = tool({
64425
- description: `Run evalite evals programmatically and get structured results with scores.
64426
-
64427
- Use this to:
64428
- - Run all evals in evals/ directory
64429
- - Filter by specific eval suite (e.g., "coordinator", "compaction")
64430
- - Enforce score thresholds for quality gates
64431
- - Get per-suite and per-eval scores
64432
-
64433
- Returns structured JSON with:
64434
- - success: boolean (true if all tests passed threshold)
64435
- - totalSuites: number of eval suites run
64436
- - totalEvals: number of individual test cases
64437
- - averageScore: 0-1 score across all suites
64438
- - suites: array of suite results with scores
64439
-
64440
- Example usage:
64441
- - Run all evals: eval_run()
64442
- - Run coordinator evals: eval_run({ suiteFilter: "coordinator" })
64443
- - Enforce 80% threshold: eval_run({ scoreThreshold: 80 })`,
64444
- args: {
64445
- suiteFilter: tool.schema.string().optional().describe('Optional filter to run specific eval suite (e.g., "coordinator", "compaction"). Matches against eval file paths using substring matching.'),
64446
- scoreThreshold: tool.schema.number().optional().describe("Optional minimum average score threshold (0-100). If average score falls below this, result.success will be false. Useful for CI quality gates."),
64447
- includeDetailedResults: tool.schema.boolean().optional().describe("Include individual eval results with input/output/scores in response. Set to false (default) for summary only to save token usage.")
64448
- },
64449
- execute: async (args2) => {
64450
- const result = await runEvals({
64451
- cwd: process.cwd(),
64452
- suiteFilter: args2.suiteFilter,
64453
- scoreThreshold: args2.scoreThreshold
64454
- });
64455
- const includeDetails = args2.includeDetailedResults === true;
64456
- if (!includeDetails) {
64457
- for (const suite of result.suites) {
64458
- delete suite.evals;
64459
- }
64460
- }
64461
- return JSON.stringify(result, null, 2);
64462
- }
64463
- });
64464
- var evalTools = {
64465
- eval_run
64466
- };
64467
-
64468
64276
  // src/contributor-tools.ts
64469
64277
  init_dist();
64470
64278
  init_zod();
@@ -64556,6 +64364,268 @@ var contributorTools = {
64556
64364
  contributor_lookup
64557
64365
  };
64558
64366
 
64367
+ // src/cass-tools.ts
64368
+ init_dist();
64369
+ import { execSync, spawn } from "child_process";
64370
+ import { getSwarmMailLibSQL as getSwarmMailLibSQL6, createEvent as createEvent5 } from "swarm-mail";
64371
+ function isCassAvailable() {
64372
+ try {
64373
+ execSync("which cass", { stdio: "ignore" });
64374
+ return true;
64375
+ } catch {
64376
+ return false;
64377
+ }
64378
+ }
64379
+ async function execCass(args2) {
64380
+ return new Promise((resolve2, reject) => {
64381
+ const proc = spawn("cass", args2, {
64382
+ stdio: ["ignore", "pipe", "pipe"]
64383
+ });
64384
+ let stdout = "";
64385
+ let stderr = "";
64386
+ proc.stdout.on("data", (data) => {
64387
+ stdout += data;
64388
+ });
64389
+ proc.stderr.on("data", (data) => {
64390
+ stderr += data;
64391
+ });
64392
+ proc.on("close", (code) => {
64393
+ if (code === 0) {
64394
+ resolve2(stdout);
64395
+ } else {
64396
+ reject(new Error(stderr || `cass exited with code ${code}`));
64397
+ }
64398
+ });
64399
+ proc.on("error", (err) => {
64400
+ if (err.code === "ENOENT") {
64401
+ reject(new Error("cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"));
64402
+ } else {
64403
+ reject(err);
64404
+ }
64405
+ });
64406
+ });
64407
+ }
64408
+ async function emitEvent(eventType, data) {
64409
+ try {
64410
+ const projectPath = process.cwd();
64411
+ const swarmMail = await getSwarmMailLibSQL6(projectPath);
64412
+ const event = createEvent5(eventType, {
64413
+ project_key: projectPath,
64414
+ ...data
64415
+ });
64416
+ await swarmMail.appendEvent(event);
64417
+ } catch {}
64418
+ }
64419
+ var cass_search = tool({
64420
+ description: "Search across all AI coding agent histories (Claude, Codex, Cursor, Gemini, Aider, ChatGPT, Cline, OpenCode). Query BEFORE solving problems from scratch - another agent may have already solved it.",
64421
+ args: {
64422
+ query: tool.schema.string().describe("Search query (e.g., 'authentication error Next.js')"),
64423
+ agent: tool.schema.string().optional().describe("Filter by agent name (e.g., 'claude', 'cursor')"),
64424
+ days: tool.schema.number().optional().describe("Only search sessions from last N days"),
64425
+ limit: tool.schema.number().optional().describe("Max results to return (default: 5)"),
64426
+ fields: tool.schema.string().optional().describe("Field selection: 'minimal' for compact output (path, line, agent only)")
64427
+ },
64428
+ async execute(args2) {
64429
+ const startTime = Date.now();
64430
+ if (!isCassAvailable()) {
64431
+ return JSON.stringify({
64432
+ error: "cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"
64433
+ });
64434
+ }
64435
+ try {
64436
+ const cliArgs = ["search", args2.query];
64437
+ if (args2.agent) {
64438
+ cliArgs.push("--agent", args2.agent);
64439
+ }
64440
+ if (args2.days) {
64441
+ cliArgs.push("--days", String(args2.days));
64442
+ }
64443
+ if (args2.limit) {
64444
+ cliArgs.push("--limit", String(args2.limit));
64445
+ }
64446
+ if (args2.fields === "minimal") {
64447
+ cliArgs.push("--minimal");
64448
+ }
64449
+ const output = await execCass(cliArgs);
64450
+ const lines = output.trim().split(`
64451
+ `).filter((l) => l.trim());
64452
+ const resultCount = lines.length;
64453
+ await emitEvent("cass_searched", {
64454
+ query: args2.query,
64455
+ agent_filter: args2.agent,
64456
+ days_filter: args2.days,
64457
+ result_count: resultCount,
64458
+ search_duration_ms: Date.now() - startTime
64459
+ });
64460
+ return output;
64461
+ } catch (error45) {
64462
+ return JSON.stringify({
64463
+ error: error45 instanceof Error ? error45.message : String(error45)
64464
+ });
64465
+ }
64466
+ }
64467
+ });
64468
+ var cass_view = tool({
64469
+ description: "View a specific conversation/session from search results. Use source_path from cass_search output.",
64470
+ args: {
64471
+ path: tool.schema.string().describe("Path to session file (from cass_search results)"),
64472
+ line: tool.schema.number().optional().describe("Jump to specific line number")
64473
+ },
64474
+ async execute(args2) {
64475
+ if (!isCassAvailable()) {
64476
+ return JSON.stringify({
64477
+ error: "cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"
64478
+ });
64479
+ }
64480
+ try {
64481
+ const cliArgs = ["view", args2.path];
64482
+ if (args2.line) {
64483
+ cliArgs.push("--line", String(args2.line));
64484
+ }
64485
+ const output = await execCass(cliArgs);
64486
+ let agentType;
64487
+ if (args2.path.includes("claude"))
64488
+ agentType = "claude";
64489
+ else if (args2.path.includes("cursor"))
64490
+ agentType = "cursor";
64491
+ else if (args2.path.includes("opencode"))
64492
+ agentType = "opencode";
64493
+ else if (args2.path.includes("codex"))
64494
+ agentType = "codex";
64495
+ await emitEvent("cass_viewed", {
64496
+ session_path: args2.path,
64497
+ line_number: args2.line,
64498
+ agent_type: agentType
64499
+ });
64500
+ return output;
64501
+ } catch (error45) {
64502
+ return JSON.stringify({
64503
+ error: error45 instanceof Error ? error45.message : String(error45)
64504
+ });
64505
+ }
64506
+ }
64507
+ });
64508
+ var cass_expand = tool({
64509
+ description: "Expand context around a specific line in a session. Shows messages before/after.",
64510
+ args: {
64511
+ path: tool.schema.string().describe("Path to session file"),
64512
+ line: tool.schema.number().describe("Line number to expand around"),
64513
+ context: tool.schema.number().optional().describe("Number of lines before/after to show (default: 5)")
64514
+ },
64515
+ async execute(args2) {
64516
+ if (!isCassAvailable()) {
64517
+ return JSON.stringify({
64518
+ error: "cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"
64519
+ });
64520
+ }
64521
+ try {
64522
+ const cliArgs = ["expand", args2.path, "--line", String(args2.line)];
64523
+ if (args2.context) {
64524
+ cliArgs.push("--context", String(args2.context));
64525
+ }
64526
+ const output = await execCass(cliArgs);
64527
+ await emitEvent("cass_viewed", {
64528
+ session_path: args2.path,
64529
+ line_number: args2.line
64530
+ });
64531
+ return output;
64532
+ } catch (error45) {
64533
+ return JSON.stringify({
64534
+ error: error45 instanceof Error ? error45.message : String(error45)
64535
+ });
64536
+ }
64537
+ }
64538
+ });
64539
+ var cass_health = tool({
64540
+ description: "Check if cass index is healthy. Exit 0 = ready, Exit 1 = needs indexing. Run this before searching.",
64541
+ args: {},
64542
+ async execute() {
64543
+ if (!isCassAvailable()) {
64544
+ return JSON.stringify({
64545
+ healthy: false,
64546
+ error: "cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"
64547
+ });
64548
+ }
64549
+ try {
64550
+ await execCass(["health"]);
64551
+ return JSON.stringify({ healthy: true, message: "Index is ready" });
64552
+ } catch (error45) {
64553
+ return JSON.stringify({
64554
+ healthy: false,
64555
+ message: "Index needs rebuilding. Run cass_index()",
64556
+ error: error45 instanceof Error ? error45.message : String(error45)
64557
+ });
64558
+ }
64559
+ }
64560
+ });
64561
+ var cass_index = tool({
64562
+ description: "Build or rebuild the search index. Run this if health check fails or to pick up new sessions.",
64563
+ args: {
64564
+ full: tool.schema.boolean().optional().describe("Force full rebuild (default: incremental)")
64565
+ },
64566
+ async execute(args2) {
64567
+ const startTime = Date.now();
64568
+ if (!isCassAvailable()) {
64569
+ return JSON.stringify({
64570
+ error: "cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"
64571
+ });
64572
+ }
64573
+ try {
64574
+ const cliArgs = ["index"];
64575
+ if (args2.full) {
64576
+ cliArgs.push("--full");
64577
+ }
64578
+ const output = await execCass(cliArgs);
64579
+ let sessionsIndexed = 0;
64580
+ let messagesIndexed = 0;
64581
+ const sessionsMatch = output.match(/(\d+)\s*sessions?/i);
64582
+ const messagesMatch = output.match(/(\d+)\s*messages?/i);
64583
+ if (sessionsMatch)
64584
+ sessionsIndexed = parseInt(sessionsMatch[1], 10);
64585
+ if (messagesMatch)
64586
+ messagesIndexed = parseInt(messagesMatch[1], 10);
64587
+ await emitEvent("cass_indexed", {
64588
+ sessions_indexed: sessionsIndexed,
64589
+ messages_indexed: messagesIndexed,
64590
+ duration_ms: Date.now() - startTime,
64591
+ full_rebuild: args2.full ?? false
64592
+ });
64593
+ return output;
64594
+ } catch (error45) {
64595
+ return JSON.stringify({
64596
+ error: error45 instanceof Error ? error45.message : String(error45)
64597
+ });
64598
+ }
64599
+ }
64600
+ });
64601
+ var cass_stats = tool({
64602
+ description: "Show index statistics - how many sessions, messages, agents indexed.",
64603
+ args: {},
64604
+ async execute() {
64605
+ if (!isCassAvailable()) {
64606
+ return JSON.stringify({
64607
+ error: "cass CLI not found. Install from: https://github.com/Dicklesworthstone/coding_agent_session_search"
64608
+ });
64609
+ }
64610
+ try {
64611
+ const output = await execCass(["stats"]);
64612
+ return output;
64613
+ } catch (error45) {
64614
+ return JSON.stringify({
64615
+ error: error45 instanceof Error ? error45.message : String(error45)
64616
+ });
64617
+ }
64618
+ }
64619
+ });
64620
+ var cassTools = {
64621
+ cass_search,
64622
+ cass_view,
64623
+ cass_expand,
64624
+ cass_health,
64625
+ cass_index,
64626
+ cass_stats
64627
+ };
64628
+
64559
64629
  // src/output-guardrails.ts
64560
64630
  var DEFAULT_GUARDRAIL_CONFIG = {
64561
64631
  defaultMaxChars: 32000,
@@ -65024,13 +65094,13 @@ function getMetricsSummary(metrics) {
65024
65094
 
65025
65095
  // src/logger.ts
65026
65096
  var import_pino = __toESM(require_pino(), 1);
65027
- import { mkdirSync as mkdirSync6, existsSync as existsSync9 } from "node:fs";
65028
- import { join as join12 } from "node:path";
65097
+ import { mkdirSync as mkdirSync5, existsSync as existsSync8 } from "node:fs";
65098
+ import { join as join11 } from "node:path";
65029
65099
  import { homedir as homedir3 } from "node:os";
65030
- var DEFAULT_LOG_DIR = join12(homedir3(), ".config", "swarm-tools", "logs");
65100
+ var DEFAULT_LOG_DIR = join11(homedir3(), ".config", "swarm-tools", "logs");
65031
65101
  function ensureLogDir(logDir) {
65032
- if (!existsSync9(logDir)) {
65033
- mkdirSync6(logDir, { recursive: true });
65102
+ if (!existsSync8(logDir)) {
65103
+ mkdirSync5(logDir, { recursive: true });
65034
65104
  }
65035
65105
  }
65036
65106
  function createTransport(filename, logDir) {
@@ -65048,7 +65118,7 @@ function createTransport(filename, logDir) {
65048
65118
  return {
65049
65119
  target: "pino-roll",
65050
65120
  options: {
65051
- file: join12(logDir, filename),
65121
+ file: join11(logDir, filename),
65052
65122
  frequency: "daily",
65053
65123
  extension: "log",
65054
65124
  limit: { count: 14 },
@@ -66043,7 +66113,6 @@ var SwarmPlugin = async (input) => {
66043
66113
  ...memoryTools,
66044
66114
  ...observabilityTools,
66045
66115
  ...researchTools,
66046
- ...evalTools,
66047
66116
  ...contributorTools
66048
66117
  },
66049
66118
  event: async ({ event }) => {
@@ -66150,7 +66219,8 @@ var allTools = {
66150
66219
  ...mandateTools,
66151
66220
  ...memoryTools,
66152
66221
  ...observabilityTools,
66153
- ...contributorTools
66222
+ ...contributorTools,
66223
+ ...cassTools
66154
66224
  };
66155
66225
 
66156
66226
  // src/plugin.ts