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/index.js CHANGED
@@ -26904,6 +26904,34 @@ import {
26904
26904
  sep
26905
26905
  } from "path";
26906
26906
  import { fileURLToPath } from "url";
26907
+ import { getSwarmMailLibSQL as getSwarmMailLibSQL2, createEvent as createEvent2 } from "swarm-mail";
26908
+ async function emitSkillLoadedEvent(data) {
26909
+ try {
26910
+ const projectPath = skillsProjectDirectory;
26911
+ const swarmMail = await getSwarmMailLibSQL2(projectPath);
26912
+ const event = createEvent2("skill_loaded", {
26913
+ project_key: projectPath,
26914
+ skill_name: data.skill_name,
26915
+ skill_source: data.skill_source,
26916
+ context_provided: data.context_provided,
26917
+ content_length: data.content_length
26918
+ });
26919
+ await swarmMail.appendEvent(event);
26920
+ } catch {}
26921
+ }
26922
+ async function emitSkillCreatedEvent(data) {
26923
+ try {
26924
+ const projectPath = skillsProjectDirectory;
26925
+ const swarmMail = await getSwarmMailLibSQL2(projectPath);
26926
+ const event = createEvent2("skill_created", {
26927
+ project_key: projectPath,
26928
+ skill_name: data.skill_name,
26929
+ skill_scope: data.skill_scope,
26930
+ description: data.description
26931
+ });
26932
+ await swarmMail.appendEvent(event);
26933
+ } catch {}
26934
+ }
26907
26935
  function setSkillsProjectDirectory(dir) {
26908
26936
  skillsProjectDirectory = dir;
26909
26937
  skillsCache = null;
@@ -27339,6 +27367,18 @@ If the skill has scripts, you can run them with skills_execute.`,
27339
27367
  const names = available.map((s) => s.name).join(", ");
27340
27368
  return `Skill '${args.name}' not found. Available skills: ${names || "none"}`;
27341
27369
  }
27370
+ let skillSource = "project";
27371
+ if (skill.path.includes(".config/opencode/skills") || skill.path.includes(".claude/skills")) {
27372
+ skillSource = "global";
27373
+ } else if (skill.path.includes("global-skills")) {
27374
+ skillSource = "bundled";
27375
+ }
27376
+ await emitSkillLoadedEvent({
27377
+ skill_name: skill.metadata.name,
27378
+ skill_source: skillSource,
27379
+ context_provided: true,
27380
+ content_length: skill.body.length
27381
+ });
27342
27382
  const includeScripts = args.include_scripts !== false;
27343
27383
  let output = `# Skill: ${skill.metadata.name}
27344
27384
 
@@ -27507,6 +27547,12 @@ Good skills have:
27507
27547
  const content = generateSkillContent(args.name, args.description, args.body, { tags: args.tags, tools: args.tools });
27508
27548
  await writeFile(skillPath, content, "utf-8");
27509
27549
  invalidateSkillsCache();
27550
+ const skillScope = args.directory === "global" || args.directory === "global-claude" ? "global" : "project";
27551
+ await emitSkillCreatedEvent({
27552
+ skill_name: args.name,
27553
+ skill_scope: skillScope,
27554
+ description: args.description
27555
+ });
27510
27556
  const response = {
27511
27557
  success: true,
27512
27558
  skill: args.name,
@@ -27742,6 +27788,12 @@ echo "Project directory: $1"
27742
27788
  createdFiles.push("references/guide.md");
27743
27789
  }
27744
27790
  invalidateSkillsCache();
27791
+ const skillScope = args.directory === "global" ? "global" : "project";
27792
+ await emitSkillCreatedEvent({
27793
+ skill_name: args.name,
27794
+ skill_scope: skillScope,
27795
+ description: args.description || "[TODO: Complete description]"
27796
+ });
27745
27797
  return JSON.stringify({
27746
27798
  success: true,
27747
27799
  skill: args.name,
@@ -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 = `
@@ -40045,6 +40097,20 @@ var hive_create = tool({
40045
40097
  parent_id: validated.parent_id
40046
40098
  });
40047
40099
  await adapter.markDirty(projectKey, cell.id);
40100
+ try {
40101
+ const event = createEvent("cell_created", {
40102
+ project_key: projectKey,
40103
+ cell_id: cell.id,
40104
+ title: validated.title,
40105
+ description: validated.description,
40106
+ issue_type: validated.type || "task",
40107
+ priority: validated.priority ?? 2,
40108
+ parent_id: validated.parent_id
40109
+ });
40110
+ await appendEvent(event, projectKey);
40111
+ } catch (error45) {
40112
+ console.warn("[hive_create] Failed to emit cell_created event:", error45);
40113
+ }
40048
40114
  const formatted = formatCellForOutput(cell);
40049
40115
  return JSON.stringify(formatted, null, 2);
40050
40116
  } catch (error45) {
@@ -40104,6 +40170,19 @@ var hive_create_epic = tool({
40104
40170
  subtasks: created.slice(1).map((c) => formatCellForOutput(c))
40105
40171
  };
40106
40172
  const effectiveProjectKey = args.project_key || projectKey;
40173
+ try {
40174
+ const epicCreatedEvent = createEvent("epic_created", {
40175
+ project_key: effectiveProjectKey,
40176
+ epic_id: epic.id,
40177
+ title: validated.epic_title,
40178
+ description: validated.epic_description,
40179
+ subtask_count: validated.subtasks.length,
40180
+ subtask_ids: created.slice(1).map((c) => c.id)
40181
+ });
40182
+ await appendEvent(epicCreatedEvent, effectiveProjectKey);
40183
+ } catch (error45) {
40184
+ console.warn("[hive_create_epic] Failed to emit epic_created event:", error45);
40185
+ }
40107
40186
  try {
40108
40187
  const event = createEvent("decomposition_generated", {
40109
40188
  project_key: effectiveProjectKey,
@@ -40268,6 +40347,23 @@ var hive_update = tool({
40268
40347
  cell = existingCell;
40269
40348
  }
40270
40349
  await adapter.markDirty(projectKey, cellId);
40350
+ try {
40351
+ const fieldsChanged = [];
40352
+ if (validated.status)
40353
+ fieldsChanged.push("status");
40354
+ if (validated.description !== undefined)
40355
+ fieldsChanged.push("description");
40356
+ if (validated.priority !== undefined)
40357
+ fieldsChanged.push("priority");
40358
+ const event = createEvent("cell_updated", {
40359
+ project_key: projectKey,
40360
+ cell_id: cellId,
40361
+ fields_changed: fieldsChanged
40362
+ });
40363
+ await appendEvent(event, projectKey);
40364
+ } catch (error45) {
40365
+ console.warn("[hive_update] Failed to emit cell_updated event:", error45);
40366
+ }
40271
40367
  const formatted = formatCellForOutput(cell);
40272
40368
  return JSON.stringify(formatted, null, 2);
40273
40369
  } catch (error45) {
@@ -40384,6 +40480,16 @@ var hive_close = tool({
40384
40480
  console.warn("[hive_close] Failed to emit SwarmCompletedEvent:", error45);
40385
40481
  }
40386
40482
  }
40483
+ try {
40484
+ const event = createEvent("cell_closed", {
40485
+ project_key: projectKey,
40486
+ cell_id: cellId,
40487
+ reason: validated.reason
40488
+ });
40489
+ await appendEvent(event, projectKey);
40490
+ } catch (error45) {
40491
+ console.warn("[hive_close] Failed to emit cell_closed event:", error45);
40492
+ }
40387
40493
  return `Closed ${cell.id}: ${validated.reason}`;
40388
40494
  } catch (error45) {
40389
40495
  const message = error45 instanceof Error ? error45.message : String(error45);
@@ -40409,6 +40515,17 @@ var hive_start = tool({
40409
40515
  const cellId = await resolvePartialId(adapter, projectKey, args.id) || args.id;
40410
40516
  const cell = await adapter.changeCellStatus(projectKey, cellId, "in_progress");
40411
40517
  await adapter.markDirty(projectKey, cellId);
40518
+ try {
40519
+ const event = createEvent("cell_status_changed", {
40520
+ project_key: projectKey,
40521
+ cell_id: cellId,
40522
+ old_status: "open",
40523
+ new_status: "in_progress"
40524
+ });
40525
+ await appendEvent(event, projectKey);
40526
+ } catch (error45) {
40527
+ console.warn("[hive_start] Failed to emit cell_status_changed event:", error45);
40528
+ }
40412
40529
  return `Started: ${cell.id}`;
40413
40530
  } catch (error45) {
40414
40531
  const message = error45 instanceof Error ? error45.message : String(error45);
@@ -40597,11 +40714,25 @@ var hive_sync = tool({
40597
40714
  }
40598
40715
  const remoteCheckResult = await runGitCommand(["remote"]);
40599
40716
  const hasRemote = remoteCheckResult.stdout.trim() !== "";
40717
+ let pushSuccess = false;
40600
40718
  if (hasRemote) {
40601
40719
  const pushResult = await withTimeout(runGitCommand(["push"]), TIMEOUT_MS, "git push");
40602
40720
  if (pushResult.exitCode !== 0) {
40603
40721
  throw new HiveError(`Failed to push: ${pushResult.stderr}`, "git push", pushResult.exitCode);
40604
40722
  }
40723
+ pushSuccess = true;
40724
+ }
40725
+ try {
40726
+ const event = createEvent("hive_synced", {
40727
+ project_key: projectKey,
40728
+ cells_synced: flushResult.cellsExported,
40729
+ push_success: pushSuccess
40730
+ });
40731
+ await appendEvent(event, projectKey);
40732
+ } catch (error45) {
40733
+ console.warn("[hive_sync] Failed to emit hive_synced event:", error45);
40734
+ }
40735
+ if (hasRemote) {
40605
40736
  return "Hive synced and pushed successfully";
40606
40737
  } else {
40607
40738
  return "Hive synced successfully (no remote configured)";
@@ -45344,9 +45475,9 @@ import {
45344
45475
  releaseSwarmFiles as releaseSwarmFiles2,
45345
45476
  sendSwarmMessage as sendSwarmMessage3,
45346
45477
  getAgent,
45347
- createEvent as createEvent2,
45478
+ createEvent as createEvent3,
45348
45479
  appendEvent as appendEvent2,
45349
- getSwarmMailLibSQL as getSwarmMailLibSQL2
45480
+ getSwarmMailLibSQL as getSwarmMailLibSQL3
45350
45481
  } from "swarm-mail";
45351
45482
  init_skills();
45352
45483
 
@@ -45849,9 +45980,9 @@ var swarm_review = tool({
45849
45980
  downstream_tasks: downstreamTasks.length > 0 ? downstreamTasks : undefined
45850
45981
  });
45851
45982
  try {
45852
- const { createEvent: createEvent2, appendEvent: appendEvent2 } = await import("swarm-mail");
45983
+ const { createEvent: createEvent3, appendEvent: appendEvent2 } = await import("swarm-mail");
45853
45984
  const attempt = getReviewStatus(args.task_id).attempt_count || 1;
45854
- const reviewStartedEvent = createEvent2("review_started", {
45985
+ const reviewStartedEvent = createEvent3("review_started", {
45855
45986
  project_key: args.project_key,
45856
45987
  epic_id: args.epic_id,
45857
45988
  bead_id: args.task_id,
@@ -45940,9 +46071,9 @@ var swarm_review_feedback = tool({
45940
46071
  console.warn("[swarm_review_feedback] Failed to trace review_decision:", error45);
45941
46072
  }
45942
46073
  try {
45943
- const { createEvent: createEvent2, appendEvent: appendEvent2 } = await import("swarm-mail");
46074
+ const { createEvent: createEvent3, appendEvent: appendEvent2 } = await import("swarm-mail");
45944
46075
  const attempt = getReviewStatus(args.task_id).attempt_count || 1;
45945
- const reviewCompletedEvent = createEvent2("review_completed", {
46076
+ const reviewCompletedEvent = createEvent3("review_completed", {
45946
46077
  project_key: args.project_key,
45947
46078
  epic_id: epicId,
45948
46079
  bead_id: args.task_id,
@@ -46011,9 +46142,9 @@ You may now complete the task with \`swarm_complete\`.`,
46011
46142
  console.warn("[swarm_review_feedback] Failed to trace review_decision:", error45);
46012
46143
  }
46013
46144
  try {
46014
- const { createEvent: createEvent2, appendEvent: appendEvent2 } = await import("swarm-mail");
46145
+ const { createEvent: createEvent3, appendEvent: appendEvent2 } = await import("swarm-mail");
46015
46146
  const status = remaining <= 0 ? "blocked" : "needs_changes";
46016
- const reviewCompletedEvent = createEvent2("review_completed", {
46147
+ const reviewCompletedEvent = createEvent3("review_completed", {
46017
46148
  project_key: args.project_key,
46018
46149
  epic_id: epicId,
46019
46150
  bead_id: args.task_id,
@@ -46569,7 +46700,7 @@ var swarm_progress = tool({
46569
46700
  }
46570
46701
  };
46571
46702
  const checkpointData = JSON.stringify(checkpoint);
46572
- const checkpointEvent = createEvent2("swarm_checkpointed", {
46703
+ const checkpointEvent = createEvent3("swarm_checkpointed", {
46573
46704
  project_key: args.project_key,
46574
46705
  ...checkpoint,
46575
46706
  checkpoint_size_bytes: Buffer.byteLength(checkpointData, "utf8"),
@@ -46577,7 +46708,7 @@ var swarm_progress = tool({
46577
46708
  });
46578
46709
  await appendEvent2(checkpointEvent, args.project_key);
46579
46710
  const checkpointId = `ckpt-${Date.now()}-${args.bead_id}`;
46580
- const createdEvent = createEvent2("checkpoint_created", {
46711
+ const createdEvent = createEvent3("checkpoint_created", {
46581
46712
  project_key: args.project_key,
46582
46713
  epic_id: epicId,
46583
46714
  bead_id: args.bead_id,
@@ -46830,7 +46961,7 @@ This will be recorded as a negative learning signal.`;
46830
46961
  let deferredResolved = false;
46831
46962
  let deferredError;
46832
46963
  try {
46833
- const swarmMail = await getSwarmMailLibSQL2(args.project_key);
46964
+ const swarmMail = await getSwarmMailLibSQL3(args.project_key);
46834
46965
  const db = await swarmMail.getDatabase();
46835
46966
  const deferredUrl = `deferred:${args.bead_id}`;
46836
46967
  const checkResult = await db.query(`SELECT url, resolved FROM deferred WHERE url = ? AND resolved = 0`, [deferredUrl]);
@@ -46859,16 +46990,16 @@ This will be recorded as a negative learning signal.`;
46859
46990
  syncError = error45 instanceof Error ? error45.message : String(error45);
46860
46991
  console.warn(`[swarm_complete] Auto-sync failed (non-fatal): ${syncError}`);
46861
46992
  }
46993
+ const completionDurationMs = args.start_time ? Date.now() - args.start_time : 0;
46994
+ const eventEpicId = cell.parent_id || (args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id);
46862
46995
  try {
46863
- const durationMs2 = args.start_time ? Date.now() - args.start_time : 0;
46864
- const eventEpicId = cell.parent_id || (args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id);
46865
- const event = createEvent2("subtask_outcome", {
46996
+ const event = createEvent3("subtask_outcome", {
46866
46997
  project_key: args.project_key,
46867
46998
  epic_id: eventEpicId,
46868
46999
  bead_id: args.bead_id,
46869
47000
  planned_files: args.planned_files || [],
46870
47001
  actual_files: args.files_touched || [],
46871
- duration_ms: durationMs2,
47002
+ duration_ms: completionDurationMs,
46872
47003
  error_count: args.error_count || 0,
46873
47004
  retry_count: args.retry_count || 0,
46874
47005
  success: true,
@@ -46879,8 +47010,21 @@ This will be recorded as a negative learning signal.`;
46879
47010
  } catch (error45) {
46880
47011
  console.warn("[swarm_complete] Failed to emit SubtaskOutcomeEvent:", error45);
46881
47012
  }
47013
+ try {
47014
+ const workerCompletedEvent = createEvent3("worker_completed", {
47015
+ project_key: args.project_key,
47016
+ epic_id: eventEpicId,
47017
+ bead_id: args.bead_id,
47018
+ worker_agent: args.agent_name,
47019
+ success: true,
47020
+ duration_ms: completionDurationMs,
47021
+ files_touched: args.files_touched || []
47022
+ });
47023
+ await appendEvent2(workerCompletedEvent, args.project_key);
47024
+ } catch (error45) {
47025
+ console.warn("[swarm_complete] Failed to emit worker_completed event:", error45);
47026
+ }
46882
47027
  let capturedStrategy;
46883
- const durationMs = args.start_time ? Date.now() - args.start_time : 0;
46884
47028
  const memoryInfo = formatMemoryStoreOnSuccess(args.bead_id, args.summary, args.files_touched || [], capturedStrategy);
46885
47029
  let memoryStored = false;
46886
47030
  let memoryError;
@@ -46997,7 +47141,7 @@ Files touched: ${args.files_touched?.join(", ") || "none recorded"}`,
46997
47141
  };
46998
47142
  try {
46999
47143
  const { captureSubtaskOutcome: captureSubtaskOutcome2 } = await Promise.resolve().then(() => (init_eval_capture(), exports_eval_capture));
47000
- const durationMs2 = args.start_time ? Date.now() - args.start_time : 0;
47144
+ const durationMs = args.start_time ? Date.now() - args.start_time : 0;
47001
47145
  const evalEpicId = cell.parent_id || epicId2;
47002
47146
  captureSubtaskOutcome2({
47003
47147
  epicId: evalEpicId,
@@ -47006,7 +47150,7 @@ Files touched: ${args.files_touched?.join(", ") || "none recorded"}`,
47006
47150
  title: cell.title,
47007
47151
  plannedFiles: args.planned_files || [],
47008
47152
  actualFiles: args.files_touched || [],
47009
- durationMs: durationMs2,
47153
+ durationMs,
47010
47154
  errorCount: args.error_count || 0,
47011
47155
  retryCount: args.retry_count || 0,
47012
47156
  success: true
@@ -47015,7 +47159,7 @@ Files touched: ${args.files_touched?.join(", ") || "none recorded"}`,
47015
47159
  console.warn("[swarm_complete] Failed to capture subtask outcome:", error45);
47016
47160
  }
47017
47161
  try {
47018
- const durationMs2 = args.start_time ? Date.now() - args.start_time : 0;
47162
+ const durationMs = args.start_time ? Date.now() - args.start_time : 0;
47019
47163
  captureCoordinatorEvent({
47020
47164
  session_id: _ctx.sessionID || "unknown",
47021
47165
  epic_id: epicId2,
@@ -47024,7 +47168,7 @@ Files touched: ${args.files_touched?.join(", ") || "none recorded"}`,
47024
47168
  outcome_type: "subtask_success",
47025
47169
  payload: {
47026
47170
  bead_id: args.bead_id,
47027
- duration_ms: durationMs2,
47171
+ duration_ms: durationMs,
47028
47172
  files_touched: args.files_touched || [],
47029
47173
  verification_passed: verificationResult?.passed ?? false,
47030
47174
  verification_skipped: args.skip_verification ?? false
@@ -47498,7 +47642,7 @@ var swarm_checkpoint = tool({
47498
47642
  }
47499
47643
  };
47500
47644
  const checkpointData = JSON.stringify(checkpoint);
47501
- const event = createEvent2("swarm_checkpointed", {
47645
+ const event = createEvent3("swarm_checkpointed", {
47502
47646
  project_key: args.project_key,
47503
47647
  epic_id: args.epic_id,
47504
47648
  bead_id: args.bead_id,
@@ -47540,8 +47684,8 @@ var swarm_recover = tool({
47540
47684
  },
47541
47685
  async execute(args) {
47542
47686
  try {
47543
- const { getSwarmMailLibSQL: getSwarmMailLibSQL3 } = await import("swarm-mail");
47544
- const swarmMail = await getSwarmMailLibSQL3(args.project_key);
47687
+ const { getSwarmMailLibSQL: getSwarmMailLibSQL4 } = await import("swarm-mail");
47688
+ const swarmMail = await getSwarmMailLibSQL4(args.project_key);
47545
47689
  const db = await swarmMail.getDatabase();
47546
47690
  const result = await db.query(`SELECT * FROM swarm_contexts
47547
47691
  WHERE epic_id = $1
@@ -47568,7 +47712,7 @@ var swarm_recover = tool({
47568
47712
  created_at: row.created_at,
47569
47713
  updated_at: row.updated_at
47570
47714
  };
47571
- const event = createEvent2("swarm_recovered", {
47715
+ const event = createEvent3("swarm_recovered", {
47572
47716
  project_key: args.project_key,
47573
47717
  epic_id: args.epic_id,
47574
47718
  bead_id: context.bead_id,
@@ -47743,7 +47887,7 @@ init_eval_capture();
47743
47887
 
47744
47888
  // src/memory-tools.ts
47745
47889
  init_dist();
47746
- import { getSwarmMailLibSQL as getSwarmMailLibSQL3 } from "swarm-mail";
47890
+ import { getSwarmMailLibSQL as getSwarmMailLibSQL4, createEvent as createEvent4, appendEvent as appendEvent3 } from "swarm-mail";
47747
47891
 
47748
47892
  // ../../node_modules/.bun/effect@3.19.12/node_modules/effect/dist/esm/Function.js
47749
47893
  var isFunction = (input) => typeof input === "function";
@@ -61360,7 +61504,7 @@ async function getMemoryAdapter(projectPath) {
61360
61504
  if (cachedAdapter && cachedProjectPath === path3) {
61361
61505
  return cachedAdapter;
61362
61506
  }
61363
- const swarmMail = await getSwarmMailLibSQL3(path3);
61507
+ const swarmMail = await getSwarmMailLibSQL4(path3);
61364
61508
  const dbAdapter = await swarmMail.getDatabase();
61365
61509
  cachedAdapter = await createMemoryAdapter(dbAdapter);
61366
61510
  cachedProjectPath = path3;
@@ -61385,6 +61529,21 @@ var semantic_memory_store = tool({
61385
61529
  async execute(args2, ctx) {
61386
61530
  const adapter = await getMemoryAdapter();
61387
61531
  const result = await adapter.store(args2);
61532
+ try {
61533
+ const projectKey = cachedProjectPath || process.cwd();
61534
+ const tags = args2.tags ? args2.tags.split(",").map((t) => t.trim()) : [];
61535
+ const event = createEvent4("memory_stored", {
61536
+ project_key: projectKey,
61537
+ memory_id: result.id,
61538
+ content_preview: args2.information.slice(0, 100),
61539
+ tags,
61540
+ auto_tagged: args2.autoTag,
61541
+ collection: args2.collection
61542
+ });
61543
+ await appendEvent3(event, projectKey);
61544
+ } catch (error45) {
61545
+ console.warn("[semantic_memory_store] Failed to emit memory_stored event:", error45);
61546
+ }
61388
61547
  return JSON.stringify(result, null, 2);
61389
61548
  }
61390
61549
  });
@@ -61398,8 +61557,25 @@ var semantic_memory_find = tool({
61398
61557
  fts: tool.schema.boolean().optional().describe("Use full-text search instead of vector search (default: false)")
61399
61558
  },
61400
61559
  async execute(args2, ctx) {
61560
+ const startTime = Date.now();
61401
61561
  const adapter = await getMemoryAdapter();
61402
61562
  const result = await adapter.find(args2);
61563
+ const duration3 = Date.now() - startTime;
61564
+ try {
61565
+ const projectKey = cachedProjectPath || process.cwd();
61566
+ const topScore = result.results.length > 0 ? result.results[0].score : undefined;
61567
+ const event = createEvent4("memory_found", {
61568
+ project_key: projectKey,
61569
+ query: args2.query,
61570
+ result_count: result.results.length,
61571
+ top_score: topScore,
61572
+ search_duration_ms: duration3,
61573
+ used_fts: args2.fts
61574
+ });
61575
+ await appendEvent3(event, projectKey);
61576
+ } catch (error45) {
61577
+ console.warn("[semantic_memory_find] Failed to emit memory_found event:", error45);
61578
+ }
61403
61579
  return JSON.stringify(result, null, 2);
61404
61580
  }
61405
61581
  });
@@ -61422,6 +61598,18 @@ var semantic_memory_remove = tool({
61422
61598
  async execute(args2, ctx) {
61423
61599
  const adapter = await getMemoryAdapter();
61424
61600
  const result = await adapter.remove(args2);
61601
+ if (result.success) {
61602
+ try {
61603
+ const projectKey = cachedProjectPath || process.cwd();
61604
+ const event = createEvent4("memory_deleted", {
61605
+ project_key: projectKey,
61606
+ memory_id: args2.id
61607
+ });
61608
+ await appendEvent3(event, projectKey);
61609
+ } catch (error45) {
61610
+ console.warn("[semantic_memory_remove] Failed to emit memory_deleted event:", error45);
61611
+ }
61612
+ }
61425
61613
  return JSON.stringify(result, null, 2);
61426
61614
  }
61427
61615
  });
@@ -61433,6 +61621,19 @@ var semantic_memory_validate = tool({
61433
61621
  async execute(args2, ctx) {
61434
61622
  const adapter = await getMemoryAdapter();
61435
61623
  const result = await adapter.validate(args2);
61624
+ if (result.success) {
61625
+ try {
61626
+ const projectKey = cachedProjectPath || process.cwd();
61627
+ const event = createEvent4("memory_validated", {
61628
+ project_key: projectKey,
61629
+ memory_id: args2.id,
61630
+ decay_reset: true
61631
+ });
61632
+ await appendEvent3(event, projectKey);
61633
+ } catch (error45) {
61634
+ console.warn("[semantic_memory_validate] Failed to emit memory_validated event:", error45);
61635
+ }
61636
+ }
61436
61637
  return JSON.stringify(result, null, 2);
61437
61638
  }
61438
61639
  });
@@ -61480,6 +61681,18 @@ var semantic_memory_upsert = tool({
61480
61681
  async execute(args2, ctx) {
61481
61682
  const adapter = await getMemoryAdapter();
61482
61683
  const result = await adapter.upsert(args2);
61684
+ try {
61685
+ const projectKey = cachedProjectPath || process.cwd();
61686
+ const event = createEvent4("memory_updated", {
61687
+ project_key: projectKey,
61688
+ memory_id: result.memoryId || "unknown",
61689
+ operation: result.operation,
61690
+ reason: result.reason
61691
+ });
61692
+ await appendEvent3(event, projectKey);
61693
+ } catch (error45) {
61694
+ console.warn("[semantic_memory_upsert] Failed to emit memory_updated event:", error45);
61695
+ }
61483
61696
  return JSON.stringify(result, null, 2);
61484
61697
  }
61485
61698
  });
@@ -62465,9 +62678,9 @@ var swarm_spawn_subtask = tool({
62465
62678
  }
62466
62679
  if (args2.project_path) {
62467
62680
  try {
62468
- const { createEvent: createEvent3, appendEvent: appendEvent3 } = await import("swarm-mail");
62681
+ const { createEvent: createEvent5, appendEvent: appendEvent4 } = await import("swarm-mail");
62469
62682
  const spawnOrder = 0;
62470
- const workerSpawnedEvent = createEvent3("worker_spawned", {
62683
+ const workerSpawnedEvent = createEvent5("worker_spawned", {
62471
62684
  project_key: args2.project_path,
62472
62685
  epic_id: args2.epic_id,
62473
62686
  bead_id: args2.bead_id,
@@ -62477,7 +62690,7 @@ var swarm_spawn_subtask = tool({
62477
62690
  spawn_order: spawnOrder,
62478
62691
  is_parallel: false
62479
62692
  });
62480
- await appendEvent3(workerSpawnedEvent, args2.project_path);
62693
+ await appendEvent4(workerSpawnedEvent, args2.project_path);
62481
62694
  } catch (error45) {
62482
62695
  console.warn("[swarm_spawn_subtask] Failed to emit WorkerSpawnedEvent:", error45);
62483
62696
  }
@@ -64155,7 +64368,7 @@ import {
64155
64368
  agentActivity,
64156
64369
  checkpointFrequency,
64157
64370
  failedDecompositions,
64158
- getSwarmMailLibSQL as getSwarmMailLibSQL4,
64371
+ getSwarmMailLibSQL as getSwarmMailLibSQL5,
64159
64372
  humanFeedback,
64160
64373
  lockContention,
64161
64374
  messageLatency,
@@ -64220,7 +64433,7 @@ var swarm_analytics = tool({
64220
64433
  async execute(args2) {
64221
64434
  try {
64222
64435
  const projectPath = process.cwd();
64223
- const db = await getSwarmMailLibSQL4(projectPath);
64436
+ const db = await getSwarmMailLibSQL5(projectPath);
64224
64437
  const filters = {
64225
64438
  project_key: projectPath
64226
64439
  };
@@ -64290,7 +64503,7 @@ var swarm_query = tool({
64290
64503
  async execute(args2) {
64291
64504
  try {
64292
64505
  const projectPath = process.cwd();
64293
- const swarmMail = await getSwarmMailLibSQL4(projectPath);
64506
+ const swarmMail = await getSwarmMailLibSQL5(projectPath);
64294
64507
  const db = await swarmMail.getDatabase();
64295
64508
  if (!args2.sql.trim().toLowerCase().startsWith("select")) {
64296
64509
  return JSON.stringify({
@@ -64340,7 +64553,7 @@ var swarm_diagnose = tool({
64340
64553
  async execute(args2) {
64341
64554
  try {
64342
64555
  const projectPath = process.cwd();
64343
- const swarmMail = await getSwarmMailLibSQL4(projectPath);
64556
+ const swarmMail = await getSwarmMailLibSQL5(projectPath);
64344
64557
  const db = await swarmMail.getDatabase();
64345
64558
  const diagnosis = [];
64346
64559
  const include = args2.include || [
@@ -64451,7 +64664,7 @@ var swarm_insights = tool({
64451
64664
  });
64452
64665
  }
64453
64666
  const projectPath = process.cwd();
64454
- const swarmMail = await getSwarmMailLibSQL4(projectPath);
64667
+ const swarmMail = await getSwarmMailLibSQL5(projectPath);
64455
64668
  const db = await swarmMail.getDatabase();
64456
64669
  const insights = [];
64457
64670
  if (args2.metrics.includes("success_rate")) {
@@ -64511,411 +64724,6 @@ var observabilityTools = {
64511
64724
  swarm_insights
64512
64725
  };
64513
64726
 
64514
- // src/eval-runner.ts
64515
- init_dist();
64516
- import { runEvalite } from "evalite/runner";
64517
- import { createInMemoryStorage } from "evalite/in-memory-storage";
64518
- import fs3 from "node:fs/promises";
64519
- import path4 from "node:path";
64520
-
64521
- // src/eval-history.ts
64522
- import * as fs2 from "node:fs";
64523
- import * as path3 from "node:path";
64524
- var DEFAULT_EVAL_HISTORY_PATH = ".opencode/eval-history.jsonl";
64525
- var VARIANCE_THRESHOLD = 0.1;
64526
- var BOOTSTRAP_THRESHOLD = 10;
64527
- var STABILIZATION_THRESHOLD = 50;
64528
- function getEvalHistoryPath(projectPath) {
64529
- return path3.join(projectPath, DEFAULT_EVAL_HISTORY_PATH);
64530
- }
64531
- function ensureEvalHistoryDir(projectPath) {
64532
- const historyPath = getEvalHistoryPath(projectPath);
64533
- const dir = path3.dirname(historyPath);
64534
- if (!fs2.existsSync(dir)) {
64535
- fs2.mkdirSync(dir, { recursive: true });
64536
- }
64537
- }
64538
- function recordEvalRun(projectPath, run) {
64539
- ensureEvalHistoryDir(projectPath);
64540
- const historyPath = getEvalHistoryPath(projectPath);
64541
- const line = `${JSON.stringify(run)}
64542
- `;
64543
- fs2.appendFileSync(historyPath, line, "utf-8");
64544
- }
64545
- function readAllRecords(projectPath) {
64546
- const historyPath = getEvalHistoryPath(projectPath);
64547
- if (!fs2.existsSync(historyPath)) {
64548
- return [];
64549
- }
64550
- const content = fs2.readFileSync(historyPath, "utf-8");
64551
- const lines = content.trim().split(`
64552
- `).filter(Boolean);
64553
- return lines.map((line) => JSON.parse(line));
64554
- }
64555
- function getScoreHistory(projectPath, evalName) {
64556
- return readAllRecords(projectPath).filter((run) => run.eval_name === evalName);
64557
- }
64558
- function calculateVariance(scores) {
64559
- if (scores.length <= 1) {
64560
- return 0;
64561
- }
64562
- const mean = scores.reduce((sum2, score) => sum2 + score, 0) / scores.length;
64563
- const variance5 = scores.reduce((sum2, score) => {
64564
- const deviation = score - mean;
64565
- return sum2 + deviation * deviation;
64566
- }, 0) / scores.length;
64567
- return variance5;
64568
- }
64569
- function getPhase(projectPath, evalName) {
64570
- const history = getScoreHistory(projectPath, evalName);
64571
- if (history.length < BOOTSTRAP_THRESHOLD) {
64572
- return "bootstrap";
64573
- }
64574
- if (history.length <= STABILIZATION_THRESHOLD) {
64575
- return "stabilization";
64576
- }
64577
- const scores = history.map((run) => run.score);
64578
- const variance5 = calculateVariance(scores);
64579
- if (variance5 < VARIANCE_THRESHOLD) {
64580
- return "production";
64581
- }
64582
- return "stabilization";
64583
- }
64584
-
64585
- // src/eval-gates.ts
64586
- var DEFAULT_THRESHOLDS = {
64587
- stabilization: 0.1,
64588
- production: 0.05
64589
- };
64590
- function calculateBaseline(history, currentScore) {
64591
- if (history.length === 0) {
64592
- return currentScore;
64593
- }
64594
- return history.reduce((sum2, run) => sum2 + run.score, 0) / history.length;
64595
- }
64596
- function calculateRegression(baseline, currentScore) {
64597
- if (baseline === 0) {
64598
- return 0;
64599
- }
64600
- return (baseline - currentScore) / baseline;
64601
- }
64602
- function formatRegressionMessage(regressionPercent, baseline, currentScore) {
64603
- return `${(regressionPercent * 100).toFixed(1)}% regression (baseline: ${baseline.toFixed(2)}, current: ${currentScore.toFixed(2)})`;
64604
- }
64605
- function checkGate(projectPath, evalName, currentScore, config2) {
64606
- const thresholds = {
64607
- stabilization: config2?.stabilizationThreshold ?? DEFAULT_THRESHOLDS.stabilization,
64608
- production: config2?.productionThreshold ?? DEFAULT_THRESHOLDS.production
64609
- };
64610
- const phase = getPhase(projectPath, evalName);
64611
- const history = getScoreHistory(projectPath, evalName);
64612
- if (phase === "bootstrap") {
64613
- return {
64614
- passed: true,
64615
- phase: "bootstrap",
64616
- message: `Bootstrap phase (${history.length}/10 runs) - collecting data`,
64617
- currentScore
64618
- };
64619
- }
64620
- const baseline = calculateBaseline(history, currentScore);
64621
- const regressionPercent = calculateRegression(baseline, currentScore);
64622
- const regressionMsg = formatRegressionMessage(regressionPercent, baseline, currentScore);
64623
- if (phase === "stabilization") {
64624
- if (regressionPercent > thresholds.stabilization) {
64625
- return {
64626
- passed: true,
64627
- phase: "stabilization",
64628
- message: `Stabilization phase: ${regressionMsg} - exceeds ${(thresholds.stabilization * 100).toFixed(0)}% threshold but still passing`,
64629
- baseline,
64630
- currentScore,
64631
- regressionPercent
64632
- };
64633
- }
64634
- if (history.length > 50) {
64635
- const scores = history.map((run) => run.score);
64636
- const variance5 = calculateVariance(scores);
64637
- return {
64638
- passed: true,
64639
- phase: "stabilization",
64640
- message: `Stabilization phase: ${regressionMsg} - acceptable. High variance (${variance5.toFixed(3)}) prevents production phase.`,
64641
- baseline,
64642
- currentScore,
64643
- regressionPercent
64644
- };
64645
- }
64646
- return {
64647
- passed: true,
64648
- phase: "stabilization",
64649
- message: `Stabilization phase: ${regressionMsg} - acceptable`,
64650
- baseline,
64651
- currentScore,
64652
- regressionPercent
64653
- };
64654
- }
64655
- if (regressionPercent > thresholds.production) {
64656
- return {
64657
- passed: false,
64658
- phase: "production",
64659
- message: `Production phase FAIL: ${regressionMsg} - exceeds ${(thresholds.production * 100).toFixed(0)}% threshold`,
64660
- baseline,
64661
- currentScore,
64662
- regressionPercent
64663
- };
64664
- }
64665
- return {
64666
- passed: true,
64667
- phase: "production",
64668
- message: `Production phase: ${regressionMsg} - acceptable`,
64669
- baseline,
64670
- currentScore,
64671
- regressionPercent
64672
- };
64673
- }
64674
-
64675
- // src/eval-learning.ts
64676
- var DEFAULT_EVAL_LEARNING_CONFIG = {
64677
- dropThreshold: 0.15,
64678
- windowSize: 5
64679
- };
64680
- function calculateRollingAverage(history, windowSize = 5) {
64681
- if (history.length === 0) {
64682
- return 0;
64683
- }
64684
- const recentRuns = history.slice(-windowSize);
64685
- const sum2 = recentRuns.reduce((acc, run) => acc + run.score, 0);
64686
- return sum2 / recentRuns.length;
64687
- }
64688
- function isSignificantDrop(currentScore, baseline, threshold = 0.15) {
64689
- if (baseline === 0) {
64690
- return false;
64691
- }
64692
- const drop3 = (baseline - currentScore) / baseline;
64693
- return drop3 >= threshold;
64694
- }
64695
- function formatFailureContext(evalName, currentScore, baseline, scorerContext) {
64696
- const dropPercentage = baseline > 0 ? (baseline - currentScore) / baseline * 100 : 0;
64697
- const lines = [
64698
- `Eval "${evalName}" regression detected:`,
64699
- `- Current score: ${currentScore.toFixed(2)}`,
64700
- `- Baseline (rolling avg): ${baseline.toFixed(2)}`,
64701
- `- Drop: ${dropPercentage.toFixed(1)}%`
64702
- ];
64703
- if (scorerContext) {
64704
- lines.push("", "Scorer context:", scorerContext);
64705
- }
64706
- lines.push("", "Action: Review recent changes that may have caused regression.", "Query this memory when generating future prompts for this eval.");
64707
- return lines.join(`
64708
- `);
64709
- }
64710
- async function learnFromEvalFailure(evalName, currentScore, history, memoryAdapter, options2) {
64711
- const config2 = options2?.config ?? DEFAULT_EVAL_LEARNING_CONFIG;
64712
- const baseline = calculateRollingAverage(history, config2.windowSize);
64713
- const dropPercentage = baseline > 0 ? (baseline - currentScore) / baseline : 0;
64714
- const significant = isSignificantDrop(currentScore, baseline, config2.dropThreshold);
64715
- const result = {
64716
- triggered: significant,
64717
- baseline,
64718
- current: currentScore,
64719
- drop_percentage: dropPercentage
64720
- };
64721
- if (significant) {
64722
- const information = formatFailureContext(evalName, currentScore, baseline, options2?.scorerContext);
64723
- const tags = ["eval-failure", evalName, "regression"].join(",");
64724
- const metadata = JSON.stringify({
64725
- eval_name: evalName,
64726
- baseline_score: baseline,
64727
- current_score: currentScore,
64728
- drop_percentage: dropPercentage,
64729
- timestamp: new Date().toISOString()
64730
- });
64731
- const storeResult = await memoryAdapter.store({
64732
- information,
64733
- tags,
64734
- metadata
64735
- });
64736
- if (storeResult.id) {
64737
- result.memory_id = storeResult.id;
64738
- }
64739
- }
64740
- return result;
64741
- }
64742
-
64743
- // src/eval-runner.ts
64744
- async function runEvals(options2 = {}) {
64745
- const {
64746
- cwd = process.cwd(),
64747
- suiteFilter,
64748
- scoreThreshold,
64749
- outputPath: userOutputPath
64750
- } = options2;
64751
- try {
64752
- const projectRoot = cwd.endsWith("src") ? path4.dirname(cwd) : cwd;
64753
- const evalsDir = path4.join(projectRoot, "evals");
64754
- let evalPath;
64755
- if (suiteFilter) {
64756
- try {
64757
- const files = await fs3.readdir(evalsDir);
64758
- const matchingFiles = files.filter((f) => f.toLowerCase().includes(suiteFilter.toLowerCase()));
64759
- if (matchingFiles.length === 0) {
64760
- return {
64761
- success: true,
64762
- totalSuites: 0,
64763
- totalEvals: 0,
64764
- averageScore: 0,
64765
- suites: []
64766
- };
64767
- }
64768
- evalPath = path4.join(evalsDir, matchingFiles[0]);
64769
- } catch (err) {
64770
- return {
64771
- success: false,
64772
- totalSuites: 0,
64773
- totalEvals: 0,
64774
- averageScore: 0,
64775
- suites: [],
64776
- error: `Failed to read evals directory: ${err instanceof Error ? err.message : String(err)}`
64777
- };
64778
- }
64779
- } else {
64780
- evalPath = evalsDir;
64781
- }
64782
- const outputPath = userOutputPath || path4.join(projectRoot, `.evalite-results-${Date.now()}.json`);
64783
- const isTemporaryOutput = !userOutputPath;
64784
- const storage = createInMemoryStorage();
64785
- await runEvalite({
64786
- path: evalPath,
64787
- cwd: projectRoot,
64788
- mode: "run-once-and-exit",
64789
- scoreThreshold,
64790
- outputPath,
64791
- hideTable: true,
64792
- storage,
64793
- disableServer: true
64794
- });
64795
- let outputJson;
64796
- try {
64797
- outputJson = await fs3.readFile(outputPath, "utf-8");
64798
- } catch (err) {
64799
- return {
64800
- success: false,
64801
- totalSuites: 0,
64802
- totalEvals: 0,
64803
- averageScore: 0,
64804
- suites: [],
64805
- error: `No results file generated: ${err instanceof Error ? err.message : String(err)}`
64806
- };
64807
- }
64808
- const output = JSON.parse(outputJson);
64809
- if (isTemporaryOutput) {
64810
- await fs3.unlink(outputPath).catch(() => {});
64811
- }
64812
- const suites = output.evals.map((evalItem) => ({
64813
- name: evalItem.name,
64814
- filepath: evalItem.filepath,
64815
- status: evalItem.status,
64816
- duration: evalItem.duration,
64817
- averageScore: evalItem.averageScore,
64818
- evalCount: evalItem.results.length,
64819
- evals: evalItem.results.map((r) => ({
64820
- input: r.input,
64821
- output: r.output,
64822
- expected: r.expected,
64823
- scores: r.scores.map((s) => ({
64824
- name: s.name,
64825
- score: s.score,
64826
- description: s.description
64827
- }))
64828
- }))
64829
- }));
64830
- for (const suite of suites) {
64831
- const history = getScoreHistory(projectRoot, suite.name);
64832
- recordEvalRun(projectRoot, {
64833
- timestamp: new Date().toISOString(),
64834
- eval_name: suite.name,
64835
- score: suite.averageScore,
64836
- run_count: history.length + 1
64837
- });
64838
- }
64839
- const gateResults = [];
64840
- for (const suite of suites) {
64841
- const history = getScoreHistory(projectRoot, suite.name);
64842
- const gate = checkGate(projectRoot, suite.name, suite.averageScore);
64843
- gateResults.push({ suite: suite.name, ...gate });
64844
- if (!gate.passed) {
64845
- try {
64846
- const memoryAdapter = await getMemoryAdapter();
64847
- await learnFromEvalFailure(suite.name, suite.averageScore, history, memoryAdapter);
64848
- } catch (e) {
64849
- console.warn(`Failed to store learning for ${suite.name}:`, e);
64850
- }
64851
- }
64852
- }
64853
- const totalEvals = suites.reduce((sum2, s) => sum2 + s.evalCount, 0);
64854
- const averageScore = suites.length > 0 ? suites.reduce((sum2, s) => sum2 + s.averageScore, 0) / suites.length : 0;
64855
- const thresholdPassed = scoreThreshold === undefined || averageScore * 100 >= scoreThreshold;
64856
- return {
64857
- success: thresholdPassed,
64858
- totalSuites: suites.length,
64859
- totalEvals,
64860
- averageScore,
64861
- suites,
64862
- gateResults
64863
- };
64864
- } catch (error45) {
64865
- return {
64866
- success: false,
64867
- totalSuites: 0,
64868
- totalEvals: 0,
64869
- averageScore: 0,
64870
- suites: [],
64871
- error: error45 instanceof Error ? error45.message : String(error45)
64872
- };
64873
- }
64874
- }
64875
- var eval_run = tool({
64876
- description: `Run evalite evals programmatically and get structured results with scores.
64877
-
64878
- Use this to:
64879
- - Run all evals in evals/ directory
64880
- - Filter by specific eval suite (e.g., "coordinator", "compaction")
64881
- - Enforce score thresholds for quality gates
64882
- - Get per-suite and per-eval scores
64883
-
64884
- Returns structured JSON with:
64885
- - success: boolean (true if all tests passed threshold)
64886
- - totalSuites: number of eval suites run
64887
- - totalEvals: number of individual test cases
64888
- - averageScore: 0-1 score across all suites
64889
- - suites: array of suite results with scores
64890
-
64891
- Example usage:
64892
- - Run all evals: eval_run()
64893
- - Run coordinator evals: eval_run({ suiteFilter: "coordinator" })
64894
- - Enforce 80% threshold: eval_run({ scoreThreshold: 80 })`,
64895
- args: {
64896
- 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.'),
64897
- 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."),
64898
- 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.")
64899
- },
64900
- execute: async (args2) => {
64901
- const result = await runEvals({
64902
- cwd: process.cwd(),
64903
- suiteFilter: args2.suiteFilter,
64904
- scoreThreshold: args2.scoreThreshold
64905
- });
64906
- const includeDetails = args2.includeDetailedResults === true;
64907
- if (!includeDetails) {
64908
- for (const suite of result.suites) {
64909
- delete suite.evals;
64910
- }
64911
- }
64912
- return JSON.stringify(result, null, 2);
64913
- }
64914
- });
64915
- var evalTools = {
64916
- eval_run
64917
- };
64918
-
64919
64727
  // src/contributor-tools.ts
64920
64728
  init_dist();
64921
64729
  init_zod();
@@ -65007,6 +64815,268 @@ var contributorTools = {
65007
64815
  contributor_lookup
65008
64816
  };
65009
64817
 
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
+
65010
65080
  // src/output-guardrails.ts
65011
65081
  var DEFAULT_GUARDRAIL_CONFIG = {
65012
65082
  defaultMaxChars: 32000,
@@ -65499,13 +65569,13 @@ function getMetricsSummary(metrics) {
65499
65569
 
65500
65570
  // src/logger.ts
65501
65571
  var import_pino = __toESM(require_pino(), 1);
65502
- import { mkdirSync as mkdirSync6, existsSync as existsSync9 } from "node:fs";
65503
- import { join as join12 } from "node:path";
65572
+ import { mkdirSync as mkdirSync5, existsSync as existsSync8 } from "node:fs";
65573
+ import { join as join11 } from "node:path";
65504
65574
  import { homedir as homedir3 } from "node:os";
65505
- var DEFAULT_LOG_DIR = join12(homedir3(), ".config", "swarm-tools", "logs");
65575
+ var DEFAULT_LOG_DIR = join11(homedir3(), ".config", "swarm-tools", "logs");
65506
65576
  function ensureLogDir(logDir) {
65507
- if (!existsSync9(logDir)) {
65508
- mkdirSync6(logDir, { recursive: true });
65577
+ if (!existsSync8(logDir)) {
65578
+ mkdirSync5(logDir, { recursive: true });
65509
65579
  }
65510
65580
  }
65511
65581
  function createTransport(filename, logDir) {
@@ -65523,7 +65593,7 @@ function createTransport(filename, logDir) {
65523
65593
  return {
65524
65594
  target: "pino-roll",
65525
65595
  options: {
65526
- file: join12(logDir, filename),
65596
+ file: join11(logDir, filename),
65527
65597
  frequency: "daily",
65528
65598
  extension: "log",
65529
65599
  limit: { count: 14 },
@@ -66797,6 +66867,161 @@ async function resetStorage() {
66797
66867
 
66798
66868
  // src/index.ts
66799
66869
  init_skills();
66870
+
66871
+ // src/eval-history.ts
66872
+ import * as fs2 from "node:fs";
66873
+ import * as path3 from "node:path";
66874
+ var DEFAULT_EVAL_HISTORY_PATH = ".opencode/eval-history.jsonl";
66875
+ var VARIANCE_THRESHOLD = 0.1;
66876
+ var BOOTSTRAP_THRESHOLD = 10;
66877
+ var STABILIZATION_THRESHOLD = 50;
66878
+ function getEvalHistoryPath(projectPath) {
66879
+ return path3.join(projectPath, DEFAULT_EVAL_HISTORY_PATH);
66880
+ }
66881
+ function ensureEvalHistoryDir(projectPath) {
66882
+ const historyPath = getEvalHistoryPath(projectPath);
66883
+ const dir = path3.dirname(historyPath);
66884
+ if (!fs2.existsSync(dir)) {
66885
+ fs2.mkdirSync(dir, { recursive: true });
66886
+ }
66887
+ }
66888
+ function recordEvalRun(projectPath, run) {
66889
+ ensureEvalHistoryDir(projectPath);
66890
+ const historyPath = getEvalHistoryPath(projectPath);
66891
+ const line = `${JSON.stringify(run)}
66892
+ `;
66893
+ fs2.appendFileSync(historyPath, line, "utf-8");
66894
+ }
66895
+ function readAllRecords(projectPath) {
66896
+ const historyPath = getEvalHistoryPath(projectPath);
66897
+ if (!fs2.existsSync(historyPath)) {
66898
+ return [];
66899
+ }
66900
+ const content = fs2.readFileSync(historyPath, "utf-8");
66901
+ const lines = content.trim().split(`
66902
+ `).filter(Boolean);
66903
+ return lines.map((line) => JSON.parse(line));
66904
+ }
66905
+ function getScoreHistory(projectPath, evalName) {
66906
+ return readAllRecords(projectPath).filter((run) => run.eval_name === evalName);
66907
+ }
66908
+ function calculateVariance(scores) {
66909
+ if (scores.length <= 1) {
66910
+ return 0;
66911
+ }
66912
+ const mean = scores.reduce((sum2, score) => sum2 + score, 0) / scores.length;
66913
+ const variance5 = scores.reduce((sum2, score) => {
66914
+ const deviation = score - mean;
66915
+ return sum2 + deviation * deviation;
66916
+ }, 0) / scores.length;
66917
+ return variance5;
66918
+ }
66919
+ function getPhase(projectPath, evalName) {
66920
+ const history = getScoreHistory(projectPath, evalName);
66921
+ if (history.length < BOOTSTRAP_THRESHOLD) {
66922
+ return "bootstrap";
66923
+ }
66924
+ if (history.length <= STABILIZATION_THRESHOLD) {
66925
+ return "stabilization";
66926
+ }
66927
+ const scores = history.map((run) => run.score);
66928
+ const variance5 = calculateVariance(scores);
66929
+ if (variance5 < VARIANCE_THRESHOLD) {
66930
+ return "production";
66931
+ }
66932
+ return "stabilization";
66933
+ }
66934
+ // src/eval-gates.ts
66935
+ var DEFAULT_THRESHOLDS = {
66936
+ stabilization: 0.1,
66937
+ production: 0.05
66938
+ };
66939
+ function calculateBaseline(history, currentScore) {
66940
+ if (history.length === 0) {
66941
+ return currentScore;
66942
+ }
66943
+ return history.reduce((sum2, run) => sum2 + run.score, 0) / history.length;
66944
+ }
66945
+ function calculateRegression(baseline, currentScore) {
66946
+ if (baseline === 0) {
66947
+ return 0;
66948
+ }
66949
+ return (baseline - currentScore) / baseline;
66950
+ }
66951
+ function formatRegressionMessage(regressionPercent, baseline, currentScore) {
66952
+ return `${(regressionPercent * 100).toFixed(1)}% regression (baseline: ${baseline.toFixed(2)}, current: ${currentScore.toFixed(2)})`;
66953
+ }
66954
+ function checkGate(projectPath, evalName, currentScore, config2) {
66955
+ const thresholds = {
66956
+ stabilization: config2?.stabilizationThreshold ?? DEFAULT_THRESHOLDS.stabilization,
66957
+ production: config2?.productionThreshold ?? DEFAULT_THRESHOLDS.production
66958
+ };
66959
+ const phase = getPhase(projectPath, evalName);
66960
+ const history = getScoreHistory(projectPath, evalName);
66961
+ if (phase === "bootstrap") {
66962
+ return {
66963
+ passed: true,
66964
+ phase: "bootstrap",
66965
+ message: `Bootstrap phase (${history.length}/10 runs) - collecting data`,
66966
+ currentScore
66967
+ };
66968
+ }
66969
+ const baseline = calculateBaseline(history, currentScore);
66970
+ const regressionPercent = calculateRegression(baseline, currentScore);
66971
+ const regressionMsg = formatRegressionMessage(regressionPercent, baseline, currentScore);
66972
+ if (phase === "stabilization") {
66973
+ if (regressionPercent > thresholds.stabilization) {
66974
+ return {
66975
+ passed: true,
66976
+ phase: "stabilization",
66977
+ message: `Stabilization phase: ${regressionMsg} - exceeds ${(thresholds.stabilization * 100).toFixed(0)}% threshold but still passing`,
66978
+ baseline,
66979
+ currentScore,
66980
+ regressionPercent
66981
+ };
66982
+ }
66983
+ if (history.length > 50) {
66984
+ const scores = history.map((run) => run.score);
66985
+ const variance5 = calculateVariance(scores);
66986
+ return {
66987
+ passed: true,
66988
+ phase: "stabilization",
66989
+ message: `Stabilization phase: ${regressionMsg} - acceptable. High variance (${variance5.toFixed(3)}) prevents production phase.`,
66990
+ baseline,
66991
+ currentScore,
66992
+ regressionPercent
66993
+ };
66994
+ }
66995
+ return {
66996
+ passed: true,
66997
+ phase: "stabilization",
66998
+ message: `Stabilization phase: ${regressionMsg} - acceptable`,
66999
+ baseline,
67000
+ currentScore,
67001
+ regressionPercent
67002
+ };
67003
+ }
67004
+ if (regressionPercent > thresholds.production) {
67005
+ return {
67006
+ passed: false,
67007
+ phase: "production",
67008
+ message: `Production phase FAIL: ${regressionMsg} - exceeds ${(thresholds.production * 100).toFixed(0)}% threshold`,
67009
+ baseline,
67010
+ currentScore,
67011
+ regressionPercent
67012
+ };
67013
+ }
67014
+ return {
67015
+ passed: true,
67016
+ phase: "production",
67017
+ message: `Production phase: ${regressionMsg} - acceptable`,
67018
+ baseline,
67019
+ currentScore,
67020
+ regressionPercent
67021
+ };
67022
+ }
67023
+
67024
+ // src/index.ts
66800
67025
  init_swarm_validation();
66801
67026
 
66802
67027
  // src/swarm-signature.ts
@@ -67083,7 +67308,6 @@ var SwarmPlugin = async (input) => {
67083
67308
  ...memoryTools,
67084
67309
  ...observabilityTools,
67085
67310
  ...researchTools,
67086
- ...evalTools,
67087
67311
  ...contributorTools
67088
67312
  },
67089
67313
  event: async ({ event }) => {
@@ -67190,7 +67414,8 @@ var allTools = {
67190
67414
  ...mandateTools,
67191
67415
  ...memoryTools,
67192
67416
  ...observabilityTools,
67193
- ...contributorTools
67417
+ ...contributorTools,
67418
+ ...cassTools
67194
67419
  };
67195
67420
  export {
67196
67421
  withToolFallback,
@@ -67317,6 +67542,7 @@ export {
67317
67542
  checkGate,
67318
67543
  checkBeadsMigrationNeeded,
67319
67544
  checkAllTools,
67545
+ cassTools,
67320
67546
  calculateVariance,
67321
67547
  beads_update,
67322
67548
  beads_sync,