opencode-swarm-plugin 0.36.0 → 0.36.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/.hive/issues.jsonl +4 -4
  2. package/.hive/memories.jsonl +274 -1
  3. package/.turbo/turbo-build.log +4 -4
  4. package/.turbo/turbo-test.log +307 -307
  5. package/CHANGELOG.md +71 -0
  6. package/bin/swarm.ts +234 -179
  7. package/dist/compaction-hook.d.ts +54 -4
  8. package/dist/compaction-hook.d.ts.map +1 -1
  9. package/dist/eval-capture.d.ts +122 -17
  10. package/dist/eval-capture.d.ts.map +1 -1
  11. package/dist/index.d.ts +1 -7
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +1278 -619
  14. package/dist/planning-guardrails.d.ts +121 -0
  15. package/dist/planning-guardrails.d.ts.map +1 -1
  16. package/dist/plugin.d.ts +9 -9
  17. package/dist/plugin.d.ts.map +1 -1
  18. package/dist/plugin.js +1283 -329
  19. package/dist/schemas/task.d.ts +0 -1
  20. package/dist/schemas/task.d.ts.map +1 -1
  21. package/dist/swarm-decompose.d.ts +0 -8
  22. package/dist/swarm-decompose.d.ts.map +1 -1
  23. package/dist/swarm-orchestrate.d.ts.map +1 -1
  24. package/dist/swarm-prompts.d.ts +0 -4
  25. package/dist/swarm-prompts.d.ts.map +1 -1
  26. package/dist/swarm-review.d.ts.map +1 -1
  27. package/dist/swarm.d.ts +0 -6
  28. package/dist/swarm.d.ts.map +1 -1
  29. package/evals/README.md +38 -0
  30. package/evals/coordinator-session.eval.ts +154 -0
  31. package/evals/fixtures/coordinator-sessions.ts +328 -0
  32. package/evals/lib/data-loader.ts +69 -0
  33. package/evals/scorers/coordinator-discipline.evalite-test.ts +536 -0
  34. package/evals/scorers/coordinator-discipline.ts +315 -0
  35. package/evals/scorers/index.ts +12 -0
  36. package/examples/plugin-wrapper-template.ts +303 -4
  37. package/package.json +2 -2
  38. package/src/compaction-hook.test.ts +8 -1
  39. package/src/compaction-hook.ts +31 -21
  40. package/src/eval-capture.test.ts +390 -0
  41. package/src/eval-capture.ts +163 -4
  42. package/src/index.ts +68 -1
  43. package/src/planning-guardrails.test.ts +387 -2
  44. package/src/planning-guardrails.ts +289 -0
  45. package/src/plugin.ts +10 -10
  46. package/src/swarm-decompose.ts +20 -0
  47. package/src/swarm-orchestrate.ts +44 -0
  48. package/src/swarm-prompts.ts +20 -0
  49. package/src/swarm-review.ts +41 -0
package/dist/index.js CHANGED
@@ -26027,7 +26027,7 @@ var require_parse = __commonJS((exports, module) => {
26027
26027
 
26028
26028
  // ../../node_modules/.bun/gray-matter@4.0.3/node_modules/gray-matter/index.js
26029
26029
  var require_gray_matter = __commonJS((exports, module) => {
26030
- var fs = __require("fs");
26030
+ var fs2 = __require("fs");
26031
26031
  var sections = require_section_matter();
26032
26032
  var defaults = require_defaults();
26033
26033
  var stringify = require_stringify();
@@ -26114,7 +26114,7 @@ var require_gray_matter = __commonJS((exports, module) => {
26114
26114
  return stringify(file2, data, options2);
26115
26115
  };
26116
26116
  matter.read = function(filepath, options2) {
26117
- const str2 = fs.readFileSync(filepath, "utf8");
26117
+ const str2 = fs2.readFileSync(filepath, "utf8");
26118
26118
  const file2 = matter(str2, options2);
26119
26119
  file2.path = filepath;
26120
26120
  return file2;
@@ -26166,9 +26166,9 @@ __export(exports_skills, {
26166
26166
  });
26167
26167
  import { readdir, readFile, stat, mkdir, writeFile, rm } from "fs/promises";
26168
26168
  import {
26169
- join as join5,
26169
+ join as join6,
26170
26170
  basename,
26171
- dirname as dirname2,
26171
+ dirname as dirname3,
26172
26172
  resolve,
26173
26173
  relative,
26174
26174
  isAbsolute,
@@ -26214,19 +26214,19 @@ function validateSkillMetadata(raw, filePath) {
26214
26214
  }
26215
26215
  function getGlobalSkillsDir() {
26216
26216
  const home = process.env.HOME || process.env.USERPROFILE || "~";
26217
- return join5(home, ".config", "opencode", "skills");
26217
+ return join6(home, ".config", "opencode", "skills");
26218
26218
  }
26219
26219
  function getClaudeGlobalSkillsDir() {
26220
26220
  const home = process.env.HOME || process.env.USERPROFILE || "~";
26221
- return join5(home, ".claude", "skills");
26221
+ return join6(home, ".claude", "skills");
26222
26222
  }
26223
26223
  function getPackageSkillsDir() {
26224
26224
  try {
26225
26225
  const currentFilePath = fileURLToPath(import.meta.url);
26226
- return join5(dirname2(currentFilePath), "..", "global-skills");
26226
+ return join6(dirname3(currentFilePath), "..", "global-skills");
26227
26227
  } catch {
26228
26228
  const currentDir = decodeURIComponent(new URL(".", import.meta.url).pathname);
26229
- return join5(currentDir, "..", "global-skills");
26229
+ return join6(currentDir, "..", "global-skills");
26230
26230
  }
26231
26231
  }
26232
26232
  async function findSkillFiles(baseDir) {
@@ -26235,7 +26235,7 @@ async function findSkillFiles(baseDir) {
26235
26235
  const entries = await readdir(baseDir, { withFileTypes: true });
26236
26236
  for (const entry of entries) {
26237
26237
  if (entry.isDirectory()) {
26238
- const skillPath = join5(baseDir, entry.name, "SKILL.md");
26238
+ const skillPath = join6(baseDir, entry.name, "SKILL.md");
26239
26239
  try {
26240
26240
  const s = await stat(skillPath);
26241
26241
  if (s.isFile()) {
@@ -26249,7 +26249,7 @@ async function findSkillFiles(baseDir) {
26249
26249
  }
26250
26250
  async function findSkillScripts(skillDir) {
26251
26251
  const scripts = [];
26252
- const scriptsDir = join5(skillDir, "scripts");
26252
+ const scriptsDir = join6(skillDir, "scripts");
26253
26253
  try {
26254
26254
  const entries = await readdir(scriptsDir, { withFileTypes: true });
26255
26255
  for (const entry of entries) {
@@ -26264,7 +26264,7 @@ async function loadSkill(skillPath) {
26264
26264
  const content = await readFile(skillPath, "utf-8");
26265
26265
  const { metadata: rawMetadata, body } = parseFrontmatter(content);
26266
26266
  const metadata = validateSkillMetadata(rawMetadata, skillPath);
26267
- const directory = dirname2(skillPath);
26267
+ const directory = dirname3(skillPath);
26268
26268
  const scripts = await findSkillScripts(directory);
26269
26269
  return {
26270
26270
  metadata,
@@ -26297,7 +26297,7 @@ async function discoverSkills(projectDir) {
26297
26297
  }
26298
26298
  }
26299
26299
  for (const relPath of PROJECT_SKILL_DIRECTORIES) {
26300
- await loadSkillsFromDir(join5(dir, relPath));
26300
+ await loadSkillsFromDir(join6(dir, relPath));
26301
26301
  }
26302
26302
  await loadSkillsFromDir(getGlobalSkillsDir());
26303
26303
  await loadSkillsFromDir(getClaudeGlobalSkillsDir());
@@ -26656,7 +26656,7 @@ Scripts run in the skill's directory with the project directory as an argument.`
26656
26656
  if (!skill.scripts.includes(args.script)) {
26657
26657
  return `Script '${args.script}' not found in skill '${args.skill}'. Available: ${skill.scripts.join(", ") || "none"}`;
26658
26658
  }
26659
- const scriptPath = join5(skill.directory, "scripts", args.script);
26659
+ const scriptPath = join6(skill.directory, "scripts", args.script);
26660
26660
  const scriptArgs = args.args || [];
26661
26661
  try {
26662
26662
  const TIMEOUT_MS = 60000;
@@ -26765,14 +26765,14 @@ Good skills have:
26765
26765
  const csoWarnings = validateCSOCompliance(args.name, args.description);
26766
26766
  let skillDir;
26767
26767
  if (args.directory === "global") {
26768
- skillDir = join5(getGlobalSkillsDir(), args.name);
26768
+ skillDir = join6(getGlobalSkillsDir(), args.name);
26769
26769
  } else if (args.directory === "global-claude") {
26770
- skillDir = join5(getClaudeGlobalSkillsDir(), args.name);
26770
+ skillDir = join6(getClaudeGlobalSkillsDir(), args.name);
26771
26771
  } else {
26772
26772
  const baseDir = args.directory || DEFAULT_SKILLS_DIR;
26773
- skillDir = join5(skillsProjectDirectory, baseDir, args.name);
26773
+ skillDir = join6(skillsProjectDirectory, baseDir, args.name);
26774
26774
  }
26775
- const skillPath = join5(skillDir, "SKILL.md");
26775
+ const skillPath = join6(skillDir, "SKILL.md");
26776
26776
  try {
26777
26777
  await mkdir(skillDir, { recursive: true });
26778
26778
  const content = generateSkillContent(args.name, args.description, args.body, { tags: args.tags, tools: args.tools });
@@ -26923,8 +26923,8 @@ executed with skills_execute. Use for:
26923
26923
  if (isAbsolute(args.script_name) || args.script_name.includes("..") || args.script_name.includes("/") || args.script_name.includes("\\") || basename(args.script_name) !== args.script_name) {
26924
26924
  return "Invalid script name. Use simple filenames without paths.";
26925
26925
  }
26926
- const scriptsDir = join5(skill.directory, "scripts");
26927
- const scriptPath = join5(scriptsDir, args.script_name);
26926
+ const scriptsDir = join6(skill.directory, "scripts");
26927
+ const scriptPath = join6(scriptsDir, args.script_name);
26928
26928
  try {
26929
26929
  await mkdir(scriptsDir, { recursive: true });
26930
26930
  await writeFile(scriptPath, args.content, {
@@ -26973,20 +26973,20 @@ Perfect for learning to create effective skills.`,
26973
26973
  }
26974
26974
  let skillDir;
26975
26975
  if (args.directory === "global") {
26976
- skillDir = join5(getGlobalSkillsDir(), args.name);
26976
+ skillDir = join6(getGlobalSkillsDir(), args.name);
26977
26977
  } else {
26978
26978
  const baseDir = args.directory || DEFAULT_SKILLS_DIR;
26979
- skillDir = join5(skillsProjectDirectory, baseDir, args.name);
26979
+ skillDir = join6(skillsProjectDirectory, baseDir, args.name);
26980
26980
  }
26981
26981
  const createdFiles = [];
26982
26982
  try {
26983
26983
  await mkdir(skillDir, { recursive: true });
26984
- const skillPath = join5(skillDir, "SKILL.md");
26984
+ const skillPath = join6(skillDir, "SKILL.md");
26985
26985
  const skillContent = generateSkillTemplate(args.name, args.description);
26986
26986
  await writeFile(skillPath, skillContent, "utf-8");
26987
26987
  createdFiles.push("SKILL.md");
26988
26988
  if (args.include_example_script !== false) {
26989
- const scriptsDir = join5(skillDir, "scripts");
26989
+ const scriptsDir = join6(skillDir, "scripts");
26990
26990
  await mkdir(scriptsDir, { recursive: true });
26991
26991
  const exampleScript = `#!/usr/bin/env bash
26992
26992
  # Example helper script for ${args.name}
@@ -27000,15 +27000,15 @@ echo "Project directory: $1"
27000
27000
 
27001
27001
  # TODO: Add actual script logic
27002
27002
  `;
27003
- const scriptPath = join5(scriptsDir, "example.sh");
27003
+ const scriptPath = join6(scriptsDir, "example.sh");
27004
27004
  await writeFile(scriptPath, exampleScript, { mode: 493 });
27005
27005
  createdFiles.push("scripts/example.sh");
27006
27006
  }
27007
27007
  if (args.include_reference !== false) {
27008
- const refsDir = join5(skillDir, "references");
27008
+ const refsDir = join6(skillDir, "references");
27009
27009
  await mkdir(refsDir, { recursive: true });
27010
27010
  const refContent = generateReferenceTemplate(args.name);
27011
- const refPath = join5(refsDir, "guide.md");
27011
+ const refPath = join6(refsDir, "guide.md");
27012
27012
  await writeFile(refPath, refContent, "utf-8");
27013
27013
  createdFiles.push("references/guide.md");
27014
27014
  }
@@ -27153,17 +27153,17 @@ var require_visit = __commonJS((exports) => {
27153
27153
  visit.BREAK = BREAK;
27154
27154
  visit.SKIP = SKIP;
27155
27155
  visit.REMOVE = REMOVE;
27156
- function visit_(key, node, visitor, path2) {
27157
- const ctrl = callVisitor(key, node, visitor, path2);
27156
+ function visit_(key, node, visitor, path3) {
27157
+ const ctrl = callVisitor(key, node, visitor, path3);
27158
27158
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
27159
- replaceNode(key, path2, ctrl);
27160
- return visit_(key, ctrl, visitor, path2);
27159
+ replaceNode(key, path3, ctrl);
27160
+ return visit_(key, ctrl, visitor, path3);
27161
27161
  }
27162
27162
  if (typeof ctrl !== "symbol") {
27163
27163
  if (identity.isCollection(node)) {
27164
- path2 = Object.freeze(path2.concat(node));
27164
+ path3 = Object.freeze(path3.concat(node));
27165
27165
  for (let i = 0;i < node.items.length; ++i) {
27166
- const ci = visit_(i, node.items[i], visitor, path2);
27166
+ const ci = visit_(i, node.items[i], visitor, path3);
27167
27167
  if (typeof ci === "number")
27168
27168
  i = ci - 1;
27169
27169
  else if (ci === BREAK)
@@ -27174,13 +27174,13 @@ var require_visit = __commonJS((exports) => {
27174
27174
  }
27175
27175
  }
27176
27176
  } else if (identity.isPair(node)) {
27177
- path2 = Object.freeze(path2.concat(node));
27178
- const ck = visit_("key", node.key, visitor, path2);
27177
+ path3 = Object.freeze(path3.concat(node));
27178
+ const ck = visit_("key", node.key, visitor, path3);
27179
27179
  if (ck === BREAK)
27180
27180
  return BREAK;
27181
27181
  else if (ck === REMOVE)
27182
27182
  node.key = null;
27183
- const cv = visit_("value", node.value, visitor, path2);
27183
+ const cv = visit_("value", node.value, visitor, path3);
27184
27184
  if (cv === BREAK)
27185
27185
  return BREAK;
27186
27186
  else if (cv === REMOVE)
@@ -27201,17 +27201,17 @@ var require_visit = __commonJS((exports) => {
27201
27201
  visitAsync.BREAK = BREAK;
27202
27202
  visitAsync.SKIP = SKIP;
27203
27203
  visitAsync.REMOVE = REMOVE;
27204
- async function visitAsync_(key, node, visitor, path2) {
27205
- const ctrl = await callVisitor(key, node, visitor, path2);
27204
+ async function visitAsync_(key, node, visitor, path3) {
27205
+ const ctrl = await callVisitor(key, node, visitor, path3);
27206
27206
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
27207
- replaceNode(key, path2, ctrl);
27208
- return visitAsync_(key, ctrl, visitor, path2);
27207
+ replaceNode(key, path3, ctrl);
27208
+ return visitAsync_(key, ctrl, visitor, path3);
27209
27209
  }
27210
27210
  if (typeof ctrl !== "symbol") {
27211
27211
  if (identity.isCollection(node)) {
27212
- path2 = Object.freeze(path2.concat(node));
27212
+ path3 = Object.freeze(path3.concat(node));
27213
27213
  for (let i = 0;i < node.items.length; ++i) {
27214
- const ci = await visitAsync_(i, node.items[i], visitor, path2);
27214
+ const ci = await visitAsync_(i, node.items[i], visitor, path3);
27215
27215
  if (typeof ci === "number")
27216
27216
  i = ci - 1;
27217
27217
  else if (ci === BREAK)
@@ -27222,13 +27222,13 @@ var require_visit = __commonJS((exports) => {
27222
27222
  }
27223
27223
  }
27224
27224
  } else if (identity.isPair(node)) {
27225
- path2 = Object.freeze(path2.concat(node));
27226
- const ck = await visitAsync_("key", node.key, visitor, path2);
27225
+ path3 = Object.freeze(path3.concat(node));
27226
+ const ck = await visitAsync_("key", node.key, visitor, path3);
27227
27227
  if (ck === BREAK)
27228
27228
  return BREAK;
27229
27229
  else if (ck === REMOVE)
27230
27230
  node.key = null;
27231
- const cv = await visitAsync_("value", node.value, visitor, path2);
27231
+ const cv = await visitAsync_("value", node.value, visitor, path3);
27232
27232
  if (cv === BREAK)
27233
27233
  return BREAK;
27234
27234
  else if (cv === REMOVE)
@@ -27255,23 +27255,23 @@ var require_visit = __commonJS((exports) => {
27255
27255
  }
27256
27256
  return visitor;
27257
27257
  }
27258
- function callVisitor(key, node, visitor, path2) {
27258
+ function callVisitor(key, node, visitor, path3) {
27259
27259
  if (typeof visitor === "function")
27260
- return visitor(key, node, path2);
27260
+ return visitor(key, node, path3);
27261
27261
  if (identity.isMap(node))
27262
- return visitor.Map?.(key, node, path2);
27262
+ return visitor.Map?.(key, node, path3);
27263
27263
  if (identity.isSeq(node))
27264
- return visitor.Seq?.(key, node, path2);
27264
+ return visitor.Seq?.(key, node, path3);
27265
27265
  if (identity.isPair(node))
27266
- return visitor.Pair?.(key, node, path2);
27266
+ return visitor.Pair?.(key, node, path3);
27267
27267
  if (identity.isScalar(node))
27268
- return visitor.Scalar?.(key, node, path2);
27268
+ return visitor.Scalar?.(key, node, path3);
27269
27269
  if (identity.isAlias(node))
27270
- return visitor.Alias?.(key, node, path2);
27270
+ return visitor.Alias?.(key, node, path3);
27271
27271
  return;
27272
27272
  }
27273
- function replaceNode(key, path2, node) {
27274
- const parent = path2[path2.length - 1];
27273
+ function replaceNode(key, path3, node) {
27274
+ const parent = path3[path3.length - 1];
27275
27275
  if (identity.isCollection(parent)) {
27276
27276
  parent.items[key] = node;
27277
27277
  } else if (identity.isPair(parent)) {
@@ -27828,10 +27828,10 @@ var require_Collection = __commonJS((exports) => {
27828
27828
  var createNode = require_createNode();
27829
27829
  var identity = require_identity();
27830
27830
  var Node = require_Node();
27831
- function collectionFromPath(schema, path2, value) {
27831
+ function collectionFromPath(schema, path3, value) {
27832
27832
  let v = value;
27833
- for (let i = path2.length - 1;i >= 0; --i) {
27834
- const k = path2[i];
27833
+ for (let i = path3.length - 1;i >= 0; --i) {
27834
+ const k = path3[i];
27835
27835
  if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
27836
27836
  const a = [];
27837
27837
  a[k] = v;
@@ -27850,7 +27850,7 @@ var require_Collection = __commonJS((exports) => {
27850
27850
  sourceObjects: new Map
27851
27851
  });
27852
27852
  }
27853
- var isEmptyPath = (path2) => path2 == null || typeof path2 === "object" && !!path2[Symbol.iterator]().next().done;
27853
+ var isEmptyPath = (path3) => path3 == null || typeof path3 === "object" && !!path3[Symbol.iterator]().next().done;
27854
27854
 
27855
27855
  class Collection extends Node.NodeBase {
27856
27856
  constructor(type, schema) {
@@ -27871,11 +27871,11 @@ var require_Collection = __commonJS((exports) => {
27871
27871
  copy.range = this.range.slice();
27872
27872
  return copy;
27873
27873
  }
27874
- addIn(path2, value) {
27875
- if (isEmptyPath(path2))
27874
+ addIn(path3, value) {
27875
+ if (isEmptyPath(path3))
27876
27876
  this.add(value);
27877
27877
  else {
27878
- const [key, ...rest] = path2;
27878
+ const [key, ...rest] = path3;
27879
27879
  const node = this.get(key, true);
27880
27880
  if (identity.isCollection(node))
27881
27881
  node.addIn(rest, value);
@@ -27885,8 +27885,8 @@ var require_Collection = __commonJS((exports) => {
27885
27885
  throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
27886
27886
  }
27887
27887
  }
27888
- deleteIn(path2) {
27889
- const [key, ...rest] = path2;
27888
+ deleteIn(path3) {
27889
+ const [key, ...rest] = path3;
27890
27890
  if (rest.length === 0)
27891
27891
  return this.delete(key);
27892
27892
  const node = this.get(key, true);
@@ -27895,8 +27895,8 @@ var require_Collection = __commonJS((exports) => {
27895
27895
  else
27896
27896
  throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
27897
27897
  }
27898
- getIn(path2, keepScalar) {
27899
- const [key, ...rest] = path2;
27898
+ getIn(path3, keepScalar) {
27899
+ const [key, ...rest] = path3;
27900
27900
  const node = this.get(key, true);
27901
27901
  if (rest.length === 0)
27902
27902
  return !keepScalar && identity.isScalar(node) ? node.value : node;
@@ -27911,15 +27911,15 @@ var require_Collection = __commonJS((exports) => {
27911
27911
  return n == null || allowScalar && identity.isScalar(n) && n.value == null && !n.commentBefore && !n.comment && !n.tag;
27912
27912
  });
27913
27913
  }
27914
- hasIn(path2) {
27915
- const [key, ...rest] = path2;
27914
+ hasIn(path3) {
27915
+ const [key, ...rest] = path3;
27916
27916
  if (rest.length === 0)
27917
27917
  return this.has(key);
27918
27918
  const node = this.get(key, true);
27919
27919
  return identity.isCollection(node) ? node.hasIn(rest) : false;
27920
27920
  }
27921
- setIn(path2, value) {
27922
- const [key, ...rest] = path2;
27921
+ setIn(path3, value) {
27922
+ const [key, ...rest] = path3;
27923
27923
  if (rest.length === 0) {
27924
27924
  this.set(key, value);
27925
27925
  } else {
@@ -30301,9 +30301,9 @@ var require_Document = __commonJS((exports) => {
30301
30301
  if (assertCollection(this.contents))
30302
30302
  this.contents.add(value);
30303
30303
  }
30304
- addIn(path2, value) {
30304
+ addIn(path3, value) {
30305
30305
  if (assertCollection(this.contents))
30306
- this.contents.addIn(path2, value);
30306
+ this.contents.addIn(path3, value);
30307
30307
  }
30308
30308
  createAlias(node, name) {
30309
30309
  if (!node.anchor) {
@@ -30352,30 +30352,30 @@ var require_Document = __commonJS((exports) => {
30352
30352
  delete(key) {
30353
30353
  return assertCollection(this.contents) ? this.contents.delete(key) : false;
30354
30354
  }
30355
- deleteIn(path2) {
30356
- if (Collection.isEmptyPath(path2)) {
30355
+ deleteIn(path3) {
30356
+ if (Collection.isEmptyPath(path3)) {
30357
30357
  if (this.contents == null)
30358
30358
  return false;
30359
30359
  this.contents = null;
30360
30360
  return true;
30361
30361
  }
30362
- return assertCollection(this.contents) ? this.contents.deleteIn(path2) : false;
30362
+ return assertCollection(this.contents) ? this.contents.deleteIn(path3) : false;
30363
30363
  }
30364
30364
  get(key, keepScalar) {
30365
30365
  return identity.isCollection(this.contents) ? this.contents.get(key, keepScalar) : undefined;
30366
30366
  }
30367
- getIn(path2, keepScalar) {
30368
- if (Collection.isEmptyPath(path2))
30367
+ getIn(path3, keepScalar) {
30368
+ if (Collection.isEmptyPath(path3))
30369
30369
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
30370
- return identity.isCollection(this.contents) ? this.contents.getIn(path2, keepScalar) : undefined;
30370
+ return identity.isCollection(this.contents) ? this.contents.getIn(path3, keepScalar) : undefined;
30371
30371
  }
30372
30372
  has(key) {
30373
30373
  return identity.isCollection(this.contents) ? this.contents.has(key) : false;
30374
30374
  }
30375
- hasIn(path2) {
30376
- if (Collection.isEmptyPath(path2))
30375
+ hasIn(path3) {
30376
+ if (Collection.isEmptyPath(path3))
30377
30377
  return this.contents !== undefined;
30378
- return identity.isCollection(this.contents) ? this.contents.hasIn(path2) : false;
30378
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path3) : false;
30379
30379
  }
30380
30380
  set(key, value) {
30381
30381
  if (this.contents == null) {
@@ -30384,13 +30384,13 @@ var require_Document = __commonJS((exports) => {
30384
30384
  this.contents.set(key, value);
30385
30385
  }
30386
30386
  }
30387
- setIn(path2, value) {
30388
- if (Collection.isEmptyPath(path2)) {
30387
+ setIn(path3, value) {
30388
+ if (Collection.isEmptyPath(path3)) {
30389
30389
  this.contents = value;
30390
30390
  } else if (this.contents == null) {
30391
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path2), value);
30391
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path3), value);
30392
30392
  } else if (assertCollection(this.contents)) {
30393
- this.contents.setIn(path2, value);
30393
+ this.contents.setIn(path3, value);
30394
30394
  }
30395
30395
  }
30396
30396
  setSchema(version2, options2 = {}) {
@@ -32279,9 +32279,9 @@ var require_cst_visit = __commonJS((exports) => {
32279
32279
  visit.BREAK = BREAK;
32280
32280
  visit.SKIP = SKIP;
32281
32281
  visit.REMOVE = REMOVE;
32282
- visit.itemAtPath = (cst, path2) => {
32282
+ visit.itemAtPath = (cst, path3) => {
32283
32283
  let item = cst;
32284
- for (const [field, index] of path2) {
32284
+ for (const [field, index] of path3) {
32285
32285
  const tok = item?.[field];
32286
32286
  if (tok && "items" in tok) {
32287
32287
  item = tok.items[index];
@@ -32290,23 +32290,23 @@ var require_cst_visit = __commonJS((exports) => {
32290
32290
  }
32291
32291
  return item;
32292
32292
  };
32293
- visit.parentCollection = (cst, path2) => {
32294
- const parent = visit.itemAtPath(cst, path2.slice(0, -1));
32295
- const field = path2[path2.length - 1][0];
32293
+ visit.parentCollection = (cst, path3) => {
32294
+ const parent = visit.itemAtPath(cst, path3.slice(0, -1));
32295
+ const field = path3[path3.length - 1][0];
32296
32296
  const coll = parent?.[field];
32297
32297
  if (coll && "items" in coll)
32298
32298
  return coll;
32299
32299
  throw new Error("Parent collection not found");
32300
32300
  };
32301
- function _visit(path2, item, visitor) {
32302
- let ctrl = visitor(item, path2);
32301
+ function _visit(path3, item, visitor) {
32302
+ let ctrl = visitor(item, path3);
32303
32303
  if (typeof ctrl === "symbol")
32304
32304
  return ctrl;
32305
32305
  for (const field of ["key", "value"]) {
32306
32306
  const token = item[field];
32307
32307
  if (token && "items" in token) {
32308
32308
  for (let i = 0;i < token.items.length; ++i) {
32309
- const ci = _visit(Object.freeze(path2.concat([[field, i]])), token.items[i], visitor);
32309
+ const ci = _visit(Object.freeze(path3.concat([[field, i]])), token.items[i], visitor);
32310
32310
  if (typeof ci === "number")
32311
32311
  i = ci - 1;
32312
32312
  else if (ci === BREAK)
@@ -32317,10 +32317,10 @@ var require_cst_visit = __commonJS((exports) => {
32317
32317
  }
32318
32318
  }
32319
32319
  if (typeof ctrl === "function" && field === "key")
32320
- ctrl = ctrl(item, path2);
32320
+ ctrl = ctrl(item, path3);
32321
32321
  }
32322
32322
  }
32323
- return typeof ctrl === "function" ? ctrl(item, path2) : ctrl;
32323
+ return typeof ctrl === "function" ? ctrl(item, path3) : ctrl;
32324
32324
  }
32325
32325
  exports.visit = visit;
32326
32326
  });
@@ -33589,14 +33589,14 @@ var require_parser2 = __commonJS((exports) => {
33589
33589
  case "scalar":
33590
33590
  case "single-quoted-scalar":
33591
33591
  case "double-quoted-scalar": {
33592
- const fs = this.flowScalar(this.type);
33592
+ const fs2 = this.flowScalar(this.type);
33593
33593
  if (atNextItem || it.value) {
33594
- map2.items.push({ start, key: fs, sep: [] });
33594
+ map2.items.push({ start, key: fs2, sep: [] });
33595
33595
  this.onKeyLine = true;
33596
33596
  } else if (it.sep) {
33597
- this.stack.push(fs);
33597
+ this.stack.push(fs2);
33598
33598
  } else {
33599
- Object.assign(it, { key: fs, sep: [] });
33599
+ Object.assign(it, { key: fs2, sep: [] });
33600
33600
  this.onKeyLine = true;
33601
33601
  }
33602
33602
  return;
@@ -33724,13 +33724,13 @@ var require_parser2 = __commonJS((exports) => {
33724
33724
  case "scalar":
33725
33725
  case "single-quoted-scalar":
33726
33726
  case "double-quoted-scalar": {
33727
- const fs = this.flowScalar(this.type);
33727
+ const fs2 = this.flowScalar(this.type);
33728
33728
  if (!it || it.value)
33729
- fc.items.push({ start: [], key: fs, sep: [] });
33729
+ fc.items.push({ start: [], key: fs2, sep: [] });
33730
33730
  else if (it.sep)
33731
- this.stack.push(fs);
33731
+ this.stack.push(fs2);
33732
33732
  else
33733
- Object.assign(it, { key: fs, sep: [] });
33733
+ Object.assign(it, { key: fs2, sep: [] });
33734
33734
  return;
33735
33735
  }
33736
33736
  case "flow-map-end":
@@ -34237,8 +34237,8 @@ var require_req = __commonJS((exports, module) => {
34237
34237
  if (req.originalUrl) {
34238
34238
  _req.url = req.originalUrl;
34239
34239
  } else {
34240
- const path2 = req.path;
34241
- _req.url = typeof path2 === "string" ? path2 : req.url ? req.url.path || req.url : undefined;
34240
+ const path3 = req.path;
34241
+ _req.url = typeof path3 === "string" ? path3 : req.url ? req.url.path || req.url : undefined;
34242
34242
  }
34243
34243
  if (req.query) {
34244
34244
  _req.query = req.query;
@@ -34394,14 +34394,14 @@ var require_redact = __commonJS((exports, module) => {
34394
34394
  }
34395
34395
  return obj;
34396
34396
  }
34397
- function parsePath(path2) {
34397
+ function parsePath(path3) {
34398
34398
  const parts2 = [];
34399
34399
  let current = "";
34400
34400
  let inBrackets = false;
34401
34401
  let inQuotes = false;
34402
34402
  let quoteChar = "";
34403
- for (let i = 0;i < path2.length; i++) {
34404
- const char = path2[i];
34403
+ for (let i = 0;i < path3.length; i++) {
34404
+ const char = path3[i];
34405
34405
  if (!inBrackets && char === ".") {
34406
34406
  if (current) {
34407
34407
  parts2.push(current);
@@ -34532,10 +34532,10 @@ var require_redact = __commonJS((exports, module) => {
34532
34532
  return current;
34533
34533
  }
34534
34534
  function redactPaths(obj, paths, censor, remove7 = false) {
34535
- for (const path2 of paths) {
34536
- const parts2 = parsePath(path2);
34535
+ for (const path3 of paths) {
34536
+ const parts2 = parsePath(path3);
34537
34537
  if (parts2.includes("*")) {
34538
- redactWildcardPath(obj, parts2, censor, path2, remove7);
34538
+ redactWildcardPath(obj, parts2, censor, path3, remove7);
34539
34539
  } else {
34540
34540
  if (remove7) {
34541
34541
  removeKey(obj, parts2);
@@ -34622,8 +34622,8 @@ var require_redact = __commonJS((exports, module) => {
34622
34622
  }
34623
34623
  } else {
34624
34624
  if (afterWildcard.includes("*")) {
34625
- const wrappedCensor = typeof censor === "function" ? (value, path2) => {
34626
- const fullPath = [...pathArray.slice(0, pathLength), ...path2];
34625
+ const wrappedCensor = typeof censor === "function" ? (value, path3) => {
34626
+ const fullPath = [...pathArray.slice(0, pathLength), ...path3];
34627
34627
  return censor(value, fullPath);
34628
34628
  } : censor;
34629
34629
  redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove7);
@@ -34660,8 +34660,8 @@ var require_redact = __commonJS((exports, module) => {
34660
34660
  return null;
34661
34661
  }
34662
34662
  const pathStructure = new Map;
34663
- for (const path2 of pathsToClone) {
34664
- const parts2 = parsePath(path2);
34663
+ for (const path3 of pathsToClone) {
34664
+ const parts2 = parsePath(path3);
34665
34665
  let current = pathStructure;
34666
34666
  for (let i = 0;i < parts2.length; i++) {
34667
34667
  const part = parts2[i];
@@ -34713,24 +34713,24 @@ var require_redact = __commonJS((exports, module) => {
34713
34713
  }
34714
34714
  return cloneSelectively(obj, pathStructure);
34715
34715
  }
34716
- function validatePath(path2) {
34717
- if (typeof path2 !== "string") {
34716
+ function validatePath(path3) {
34717
+ if (typeof path3 !== "string") {
34718
34718
  throw new Error("Paths must be (non-empty) strings");
34719
34719
  }
34720
- if (path2 === "") {
34720
+ if (path3 === "") {
34721
34721
  throw new Error("Invalid redaction path ()");
34722
34722
  }
34723
- if (path2.includes("..")) {
34724
- throw new Error(`Invalid redaction path (${path2})`);
34723
+ if (path3.includes("..")) {
34724
+ throw new Error(`Invalid redaction path (${path3})`);
34725
34725
  }
34726
- if (path2.includes(",")) {
34727
- throw new Error(`Invalid redaction path (${path2})`);
34726
+ if (path3.includes(",")) {
34727
+ throw new Error(`Invalid redaction path (${path3})`);
34728
34728
  }
34729
34729
  let bracketCount = 0;
34730
34730
  let inQuotes = false;
34731
34731
  let quoteChar = "";
34732
- for (let i = 0;i < path2.length; i++) {
34733
- const char = path2[i];
34732
+ for (let i = 0;i < path3.length; i++) {
34733
+ const char = path3[i];
34734
34734
  if ((char === '"' || char === "'") && bracketCount > 0) {
34735
34735
  if (!inQuotes) {
34736
34736
  inQuotes = true;
@@ -34744,20 +34744,20 @@ var require_redact = __commonJS((exports, module) => {
34744
34744
  } else if (char === "]" && !inQuotes) {
34745
34745
  bracketCount--;
34746
34746
  if (bracketCount < 0) {
34747
- throw new Error(`Invalid redaction path (${path2})`);
34747
+ throw new Error(`Invalid redaction path (${path3})`);
34748
34748
  }
34749
34749
  }
34750
34750
  }
34751
34751
  if (bracketCount !== 0) {
34752
- throw new Error(`Invalid redaction path (${path2})`);
34752
+ throw new Error(`Invalid redaction path (${path3})`);
34753
34753
  }
34754
34754
  }
34755
34755
  function validatePaths(paths) {
34756
34756
  if (!Array.isArray(paths)) {
34757
34757
  throw new TypeError("paths must be an array");
34758
34758
  }
34759
- for (const path2 of paths) {
34760
- validatePath(path2);
34759
+ for (const path3 of paths) {
34760
+ validatePath(path3);
34761
34761
  }
34762
34762
  }
34763
34763
  function slowRedact(options2 = {}) {
@@ -34919,8 +34919,8 @@ var require_redaction = __commonJS((exports, module) => {
34919
34919
  if (shape[k] === null) {
34920
34920
  o[k] = (value) => topCensor(value, [k]);
34921
34921
  } else {
34922
- const wrappedCensor = typeof censor === "function" ? (value, path2) => {
34923
- return censor(value, [k, ...path2]);
34922
+ const wrappedCensor = typeof censor === "function" ? (value, path3) => {
34923
+ return censor(value, [k, ...path3]);
34924
34924
  } : censor;
34925
34925
  o[k] = Redact({
34926
34926
  paths: shape[k],
@@ -35128,10 +35128,10 @@ var require_atomic_sleep = __commonJS((exports, module) => {
35128
35128
 
35129
35129
  // ../../node_modules/.bun/sonic-boom@4.2.0/node_modules/sonic-boom/index.js
35130
35130
  var require_sonic_boom = __commonJS((exports, module) => {
35131
- var fs = __require("fs");
35131
+ var fs2 = __require("fs");
35132
35132
  var EventEmitter = __require("events");
35133
35133
  var inherits = __require("util").inherits;
35134
- var path2 = __require("path");
35134
+ var path3 = __require("path");
35135
35135
  var sleep5 = require_atomic_sleep();
35136
35136
  var assert2 = __require("assert");
35137
35137
  var BUSY_WRITE_TIMEOUT = 100;
@@ -35186,21 +35186,21 @@ var require_sonic_boom = __commonJS((exports, module) => {
35186
35186
  if (sonic.sync) {
35187
35187
  try {
35188
35188
  if (sonic.mkdir)
35189
- fs.mkdirSync(path2.dirname(file2), { recursive: true });
35190
- const fd = fs.openSync(file2, flags, mode);
35189
+ fs2.mkdirSync(path3.dirname(file2), { recursive: true });
35190
+ const fd = fs2.openSync(file2, flags, mode);
35191
35191
  fileOpened(null, fd);
35192
35192
  } catch (err) {
35193
35193
  fileOpened(err);
35194
35194
  throw err;
35195
35195
  }
35196
35196
  } else if (sonic.mkdir) {
35197
- fs.mkdir(path2.dirname(file2), { recursive: true }, (err) => {
35197
+ fs2.mkdir(path3.dirname(file2), { recursive: true }, (err) => {
35198
35198
  if (err)
35199
35199
  return fileOpened(err);
35200
- fs.open(file2, flags, mode, fileOpened);
35200
+ fs2.open(file2, flags, mode, fileOpened);
35201
35201
  });
35202
35202
  } else {
35203
- fs.open(file2, flags, mode, fileOpened);
35203
+ fs2.open(file2, flags, mode, fileOpened);
35204
35204
  }
35205
35205
  }
35206
35206
  function SonicBoom(opts) {
@@ -35241,16 +35241,16 @@ var require_sonic_boom = __commonJS((exports, module) => {
35241
35241
  this.flush = flushBuffer;
35242
35242
  this.flushSync = flushBufferSync;
35243
35243
  this._actualWrite = actualWriteBuffer;
35244
- fsWriteSync = () => fs.writeSync(this.fd, this._writingBuf);
35245
- fsWrite = () => fs.write(this.fd, this._writingBuf, this.release);
35244
+ fsWriteSync = () => fs2.writeSync(this.fd, this._writingBuf);
35245
+ fsWrite = () => fs2.write(this.fd, this._writingBuf, this.release);
35246
35246
  } else if (contentMode === undefined || contentMode === kContentModeUtf8) {
35247
35247
  this._writingBuf = "";
35248
35248
  this.write = write;
35249
35249
  this.flush = flush;
35250
35250
  this.flushSync = flushSync;
35251
35251
  this._actualWrite = actualWrite;
35252
- fsWriteSync = () => fs.writeSync(this.fd, this._writingBuf, "utf8");
35253
- fsWrite = () => fs.write(this.fd, this._writingBuf, "utf8", this.release);
35252
+ fsWriteSync = () => fs2.writeSync(this.fd, this._writingBuf, "utf8");
35253
+ fsWrite = () => fs2.write(this.fd, this._writingBuf, "utf8", this.release);
35254
35254
  } else {
35255
35255
  throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
35256
35256
  }
@@ -35306,7 +35306,7 @@ var require_sonic_boom = __commonJS((exports, module) => {
35306
35306
  }
35307
35307
  }
35308
35308
  if (this._fsync) {
35309
- fs.fsyncSync(this.fd);
35309
+ fs2.fsyncSync(this.fd);
35310
35310
  }
35311
35311
  const len = this._len;
35312
35312
  if (this._reopening) {
@@ -35419,7 +35419,7 @@ var require_sonic_boom = __commonJS((exports, module) => {
35419
35419
  const onDrain = () => {
35420
35420
  if (!this._fsync) {
35421
35421
  try {
35422
- fs.fsync(this.fd, (err) => {
35422
+ fs2.fsync(this.fd, (err) => {
35423
35423
  this._flushPending = false;
35424
35424
  cb(err);
35425
35425
  });
@@ -35521,7 +35521,7 @@ var require_sonic_boom = __commonJS((exports, module) => {
35521
35521
  const fd = this.fd;
35522
35522
  this.once("ready", () => {
35523
35523
  if (fd !== this.fd) {
35524
- fs.close(fd, (err) => {
35524
+ fs2.close(fd, (err) => {
35525
35525
  if (err) {
35526
35526
  return this.emit("error", err);
35527
35527
  }
@@ -35570,7 +35570,7 @@ var require_sonic_boom = __commonJS((exports, module) => {
35570
35570
  buf = this._bufs[0];
35571
35571
  }
35572
35572
  try {
35573
- const n = fs.writeSync(this.fd, buf, "utf8");
35573
+ const n = fs2.writeSync(this.fd, buf, "utf8");
35574
35574
  const releasedBufObj = releaseWritingBuf(buf, this._len, n);
35575
35575
  buf = releasedBufObj.writingBuf;
35576
35576
  this._len = releasedBufObj.len;
@@ -35586,7 +35586,7 @@ var require_sonic_boom = __commonJS((exports, module) => {
35586
35586
  }
35587
35587
  }
35588
35588
  try {
35589
- fs.fsyncSync(this.fd);
35589
+ fs2.fsyncSync(this.fd);
35590
35590
  } catch {}
35591
35591
  }
35592
35592
  function flushBufferSync() {
@@ -35606,7 +35606,7 @@ var require_sonic_boom = __commonJS((exports, module) => {
35606
35606
  buf = mergeBuf(this._bufs[0], this._lens[0]);
35607
35607
  }
35608
35608
  try {
35609
- const n = fs.writeSync(this.fd, buf);
35609
+ const n = fs2.writeSync(this.fd, buf);
35610
35610
  buf = buf.subarray(n);
35611
35611
  this._len = Math.max(this._len - n, 0);
35612
35612
  if (buf.length <= 0) {
@@ -35634,13 +35634,13 @@ var require_sonic_boom = __commonJS((exports, module) => {
35634
35634
  this._writingBuf = this._writingBuf || this._bufs.shift() || "";
35635
35635
  if (this.sync) {
35636
35636
  try {
35637
- const written = fs.writeSync(this.fd, this._writingBuf, "utf8");
35637
+ const written = fs2.writeSync(this.fd, this._writingBuf, "utf8");
35638
35638
  release(null, written);
35639
35639
  } catch (err) {
35640
35640
  release(err);
35641
35641
  }
35642
35642
  } else {
35643
- fs.write(this.fd, this._writingBuf, "utf8", release);
35643
+ fs2.write(this.fd, this._writingBuf, "utf8", release);
35644
35644
  }
35645
35645
  }
35646
35646
  function actualWriteBuffer() {
@@ -35649,7 +35649,7 @@ var require_sonic_boom = __commonJS((exports, module) => {
35649
35649
  this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
35650
35650
  if (this.sync) {
35651
35651
  try {
35652
- const written = fs.writeSync(this.fd, this._writingBuf);
35652
+ const written = fs2.writeSync(this.fd, this._writingBuf);
35653
35653
  release(null, written);
35654
35654
  } catch (err) {
35655
35655
  release(err);
@@ -35658,7 +35658,7 @@ var require_sonic_boom = __commonJS((exports, module) => {
35658
35658
  if (kCopyBuffer) {
35659
35659
  this._writingBuf = Buffer.from(this._writingBuf);
35660
35660
  }
35661
- fs.write(this.fd, this._writingBuf, release);
35661
+ fs2.write(this.fd, this._writingBuf, release);
35662
35662
  }
35663
35663
  }
35664
35664
  function actualClose(sonic) {
@@ -35674,11 +35674,11 @@ var require_sonic_boom = __commonJS((exports, module) => {
35674
35674
  sonic._lens = [];
35675
35675
  assert2(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
35676
35676
  try {
35677
- fs.fsync(sonic.fd, closeWrapped);
35677
+ fs2.fsync(sonic.fd, closeWrapped);
35678
35678
  } catch {}
35679
35679
  function closeWrapped() {
35680
35680
  if (sonic.fd !== 1 && sonic.fd !== 2) {
35681
- fs.close(sonic.fd, done7);
35681
+ fs2.close(sonic.fd, done7);
35682
35682
  } else {
35683
35683
  done7();
35684
35684
  }
@@ -35924,7 +35924,7 @@ var require_thread_stream = __commonJS((exports, module) => {
35924
35924
  var { version: version2 } = require_package();
35925
35925
  var { EventEmitter } = __require("events");
35926
35926
  var { Worker } = __require("worker_threads");
35927
- var { join: join10 } = __require("path");
35927
+ var { join: join11 } = __require("path");
35928
35928
  var { pathToFileURL } = __require("url");
35929
35929
  var { wait } = require_wait();
35930
35930
  var {
@@ -35960,7 +35960,7 @@ var require_thread_stream = __commonJS((exports, module) => {
35960
35960
  function createWorker(stream, opts) {
35961
35961
  const { filename, workerData } = opts;
35962
35962
  const bundlerOverrides = "__bundlerPathsOverrides" in globalThis ? globalThis.__bundlerPathsOverrides : {};
35963
- const toExecute = bundlerOverrides["thread-stream-worker"] || join10(__dirname, "lib", "worker.js");
35963
+ const toExecute = bundlerOverrides["thread-stream-worker"] || join11(__dirname, "lib", "worker.js");
35964
35964
  const worker = new Worker(toExecute, {
35965
35965
  ...opts.workerOpts,
35966
35966
  trackUnmanagedFds: false,
@@ -36344,7 +36344,7 @@ var require_transport = __commonJS((exports, module) => {
36344
36344
  var __dirname = "/Users/joel/Code/joelhooks/opencode-swarm-plugin/node_modules/.bun/pino@9.14.0/node_modules/pino/lib";
36345
36345
  var { createRequire: createRequire2 } = __require("module");
36346
36346
  var getCallers = require_caller();
36347
- var { join: join10, isAbsolute: isAbsolute2, sep: sep3 } = __require("node:path");
36347
+ var { join: join11, isAbsolute: isAbsolute2, sep: sep3 } = __require("node:path");
36348
36348
  var sleep5 = require_atomic_sleep();
36349
36349
  var onExit4 = require_on_exit_leak_free();
36350
36350
  var ThreadStream = require_thread_stream();
@@ -36407,7 +36407,7 @@ var require_transport = __commonJS((exports, module) => {
36407
36407
  throw new Error("only one of target or targets can be specified");
36408
36408
  }
36409
36409
  if (targets) {
36410
- target = bundlerOverrides["pino-worker"] || join10(__dirname, "worker.js");
36410
+ target = bundlerOverrides["pino-worker"] || join11(__dirname, "worker.js");
36411
36411
  options2.targets = targets.filter((dest) => dest.target).map((dest) => {
36412
36412
  return {
36413
36413
  ...dest,
@@ -36424,7 +36424,7 @@ var require_transport = __commonJS((exports, module) => {
36424
36424
  });
36425
36425
  });
36426
36426
  } else if (pipeline) {
36427
- target = bundlerOverrides["pino-worker"] || join10(__dirname, "worker.js");
36427
+ target = bundlerOverrides["pino-worker"] || join11(__dirname, "worker.js");
36428
36428
  options2.pipelines = [pipeline.map((dest) => {
36429
36429
  return {
36430
36430
  ...dest,
@@ -36446,7 +36446,7 @@ var require_transport = __commonJS((exports, module) => {
36446
36446
  return origin;
36447
36447
  }
36448
36448
  if (origin === "pino/file") {
36449
- return join10(__dirname, "..", "file.js");
36449
+ return join11(__dirname, "..", "file.js");
36450
36450
  }
36451
36451
  let fixTarget2;
36452
36452
  for (const filePath of callers) {
@@ -37384,7 +37384,7 @@ var require_safe_stable_stringify = __commonJS((exports, module) => {
37384
37384
  return circularValue;
37385
37385
  }
37386
37386
  let res = "";
37387
- let join10 = ",";
37387
+ let join11 = ",";
37388
37388
  const originalIndentation = indentation;
37389
37389
  if (Array.isArray(value)) {
37390
37390
  if (value.length === 0) {
@@ -37398,7 +37398,7 @@ var require_safe_stable_stringify = __commonJS((exports, module) => {
37398
37398
  indentation += spacer;
37399
37399
  res += `
37400
37400
  ${indentation}`;
37401
- join10 = `,
37401
+ join11 = `,
37402
37402
  ${indentation}`;
37403
37403
  }
37404
37404
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
@@ -37406,13 +37406,13 @@ ${indentation}`;
37406
37406
  for (;i < maximumValuesToStringify - 1; i++) {
37407
37407
  const tmp2 = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
37408
37408
  res += tmp2 !== undefined ? tmp2 : "null";
37409
- res += join10;
37409
+ res += join11;
37410
37410
  }
37411
37411
  const tmp = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
37412
37412
  res += tmp !== undefined ? tmp : "null";
37413
37413
  if (value.length - 1 > maximumBreadth) {
37414
37414
  const removedKeys = value.length - maximumBreadth - 1;
37415
- res += `${join10}"... ${getItemCount(removedKeys)} not stringified"`;
37415
+ res += `${join11}"... ${getItemCount(removedKeys)} not stringified"`;
37416
37416
  }
37417
37417
  if (spacer !== "") {
37418
37418
  res += `
@@ -37433,7 +37433,7 @@ ${originalIndentation}`;
37433
37433
  let separator = "";
37434
37434
  if (spacer !== "") {
37435
37435
  indentation += spacer;
37436
- join10 = `,
37436
+ join11 = `,
37437
37437
  ${indentation}`;
37438
37438
  whitespace = " ";
37439
37439
  }
@@ -37447,13 +37447,13 @@ ${indentation}`;
37447
37447
  const tmp = stringifyFnReplacer(key2, value, stack, replacer, spacer, indentation);
37448
37448
  if (tmp !== undefined) {
37449
37449
  res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
37450
- separator = join10;
37450
+ separator = join11;
37451
37451
  }
37452
37452
  }
37453
37453
  if (keyLength > maximumBreadth) {
37454
37454
  const removedKeys = keyLength - maximumBreadth;
37455
37455
  res += `${separator}"...":${whitespace}"${getItemCount(removedKeys)} not stringified"`;
37456
- separator = join10;
37456
+ separator = join11;
37457
37457
  }
37458
37458
  if (spacer !== "" && separator.length > 1) {
37459
37459
  res = `
@@ -37493,7 +37493,7 @@ ${originalIndentation}`;
37493
37493
  }
37494
37494
  const originalIndentation = indentation;
37495
37495
  let res = "";
37496
- let join10 = ",";
37496
+ let join11 = ",";
37497
37497
  if (Array.isArray(value)) {
37498
37498
  if (value.length === 0) {
37499
37499
  return "[]";
@@ -37506,7 +37506,7 @@ ${originalIndentation}`;
37506
37506
  indentation += spacer;
37507
37507
  res += `
37508
37508
  ${indentation}`;
37509
- join10 = `,
37509
+ join11 = `,
37510
37510
  ${indentation}`;
37511
37511
  }
37512
37512
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
@@ -37514,13 +37514,13 @@ ${indentation}`;
37514
37514
  for (;i < maximumValuesToStringify - 1; i++) {
37515
37515
  const tmp2 = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
37516
37516
  res += tmp2 !== undefined ? tmp2 : "null";
37517
- res += join10;
37517
+ res += join11;
37518
37518
  }
37519
37519
  const tmp = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
37520
37520
  res += tmp !== undefined ? tmp : "null";
37521
37521
  if (value.length - 1 > maximumBreadth) {
37522
37522
  const removedKeys = value.length - maximumBreadth - 1;
37523
- res += `${join10}"... ${getItemCount(removedKeys)} not stringified"`;
37523
+ res += `${join11}"... ${getItemCount(removedKeys)} not stringified"`;
37524
37524
  }
37525
37525
  if (spacer !== "") {
37526
37526
  res += `
@@ -37533,7 +37533,7 @@ ${originalIndentation}`;
37533
37533
  let whitespace = "";
37534
37534
  if (spacer !== "") {
37535
37535
  indentation += spacer;
37536
- join10 = `,
37536
+ join11 = `,
37537
37537
  ${indentation}`;
37538
37538
  whitespace = " ";
37539
37539
  }
@@ -37542,7 +37542,7 @@ ${indentation}`;
37542
37542
  const tmp = stringifyArrayReplacer(key2, value[key2], stack, replacer, spacer, indentation);
37543
37543
  if (tmp !== undefined) {
37544
37544
  res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
37545
- separator = join10;
37545
+ separator = join11;
37546
37546
  }
37547
37547
  }
37548
37548
  if (spacer !== "" && separator.length > 1) {
@@ -37599,20 +37599,20 @@ ${originalIndentation}`;
37599
37599
  indentation += spacer;
37600
37600
  let res2 = `
37601
37601
  ${indentation}`;
37602
- const join11 = `,
37602
+ const join12 = `,
37603
37603
  ${indentation}`;
37604
37604
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
37605
37605
  let i = 0;
37606
37606
  for (;i < maximumValuesToStringify - 1; i++) {
37607
37607
  const tmp2 = stringifyIndent(String(i), value[i], stack, spacer, indentation);
37608
37608
  res2 += tmp2 !== undefined ? tmp2 : "null";
37609
- res2 += join11;
37609
+ res2 += join12;
37610
37610
  }
37611
37611
  const tmp = stringifyIndent(String(i), value[i], stack, spacer, indentation);
37612
37612
  res2 += tmp !== undefined ? tmp : "null";
37613
37613
  if (value.length - 1 > maximumBreadth) {
37614
37614
  const removedKeys = value.length - maximumBreadth - 1;
37615
- res2 += `${join11}"... ${getItemCount(removedKeys)} not stringified"`;
37615
+ res2 += `${join12}"... ${getItemCount(removedKeys)} not stringified"`;
37616
37616
  }
37617
37617
  res2 += `
37618
37618
  ${originalIndentation}`;
@@ -37628,16 +37628,16 @@ ${originalIndentation}`;
37628
37628
  return '"[Object]"';
37629
37629
  }
37630
37630
  indentation += spacer;
37631
- const join10 = `,
37631
+ const join11 = `,
37632
37632
  ${indentation}`;
37633
37633
  let res = "";
37634
37634
  let separator = "";
37635
37635
  let maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
37636
37636
  if (isTypedArrayWithEntries(value)) {
37637
- res += stringifyTypedArray(value, join10, maximumBreadth);
37637
+ res += stringifyTypedArray(value, join11, maximumBreadth);
37638
37638
  keys3 = keys3.slice(value.length);
37639
37639
  maximumPropertiesToStringify -= value.length;
37640
- separator = join10;
37640
+ separator = join11;
37641
37641
  }
37642
37642
  if (deterministic) {
37643
37643
  keys3 = sort2(keys3, comparator);
@@ -37648,13 +37648,13 @@ ${indentation}`;
37648
37648
  const tmp = stringifyIndent(key2, value[key2], stack, spacer, indentation);
37649
37649
  if (tmp !== undefined) {
37650
37650
  res += `${separator}${strEscape(key2)}: ${tmp}`;
37651
- separator = join10;
37651
+ separator = join11;
37652
37652
  }
37653
37653
  }
37654
37654
  if (keyLength > maximumBreadth) {
37655
37655
  const removedKeys = keyLength - maximumBreadth;
37656
37656
  res += `${separator}"...": "${getItemCount(removedKeys)} not stringified"`;
37657
- separator = join10;
37657
+ separator = join11;
37658
37658
  }
37659
37659
  if (separator !== "") {
37660
37660
  res = `
@@ -37966,7 +37966,7 @@ var require_multistream = __commonJS((exports, module) => {
37966
37966
 
37967
37967
  // ../../node_modules/.bun/pino@9.14.0/node_modules/pino/pino.js
37968
37968
  var require_pino = __commonJS((exports, module) => {
37969
- var os = __require("node:os");
37969
+ var os2 = __require("node:os");
37970
37970
  var stdSerializers = require_pino_std_serializers();
37971
37971
  var caller = require_caller();
37972
37972
  var redaction = require_redaction();
@@ -38013,7 +38013,7 @@ var require_pino = __commonJS((exports, module) => {
38013
38013
  } = symbols;
38014
38014
  var { epochTime, nullTime } = time3;
38015
38015
  var { pid } = process;
38016
- var hostname3 = os.hostname();
38016
+ var hostname3 = os2.hostname();
38017
38017
  var defaultErrorSerializer = stdSerializers.err;
38018
38018
  var defaultOptions = {
38019
38019
  level: "info",
@@ -38393,7 +38393,6 @@ var TaskDecompositionSchema = exports_external.object({
38393
38393
  });
38394
38394
  var DecomposeArgsSchema = exports_external.object({
38395
38395
  task: exports_external.string().min(1),
38396
- max_subtasks: exports_external.number().int().min(1).default(5),
38397
38396
  context: exports_external.string().optional()
38398
38397
  });
38399
38398
  var SpawnedAgentSchema = exports_external.object({
@@ -41847,6 +41846,122 @@ init_swarm_strategies();
41847
41846
  init_dist();
41848
41847
  init_zod();
41849
41848
  init_swarm_strategies();
41849
+
41850
+ // src/eval-capture.ts
41851
+ init_zod();
41852
+ import * as fs from "node:fs";
41853
+ import * as os from "node:os";
41854
+ import * as path from "node:path";
41855
+ var SubtaskOutcomeSchema = exports_external.object({
41856
+ bead_id: exports_external.string(),
41857
+ title: exports_external.string(),
41858
+ planned_files: exports_external.array(exports_external.string()),
41859
+ actual_files: exports_external.array(exports_external.string()),
41860
+ duration_ms: exports_external.number().int().min(0),
41861
+ error_count: exports_external.number().int().min(0),
41862
+ retry_count: exports_external.number().int().min(0),
41863
+ success: exports_external.boolean(),
41864
+ failure_mode: exports_external.string().optional()
41865
+ });
41866
+ var EvalRecordSchema = exports_external.object({
41867
+ id: exports_external.string(),
41868
+ timestamp: exports_external.string(),
41869
+ project_path: exports_external.string(),
41870
+ task: exports_external.string(),
41871
+ context: exports_external.string().optional(),
41872
+ strategy: exports_external.enum(["file-based", "feature-based", "risk-based", "auto"]),
41873
+ subtask_count: exports_external.number().int().min(1),
41874
+ epic_title: exports_external.string(),
41875
+ epic_description: exports_external.string().optional(),
41876
+ subtasks: exports_external.array(exports_external.object({
41877
+ title: exports_external.string(),
41878
+ description: exports_external.string().optional(),
41879
+ files: exports_external.array(exports_external.string()),
41880
+ dependencies: exports_external.array(exports_external.number()).optional(),
41881
+ estimated_complexity: exports_external.number().int().min(1).max(5).optional()
41882
+ })),
41883
+ outcomes: exports_external.array(SubtaskOutcomeSchema).optional(),
41884
+ overall_success: exports_external.boolean().optional(),
41885
+ total_duration_ms: exports_external.number().int().min(0).optional(),
41886
+ total_errors: exports_external.number().int().min(0).optional(),
41887
+ human_accepted: exports_external.boolean().optional(),
41888
+ human_modified: exports_external.boolean().optional(),
41889
+ human_notes: exports_external.string().optional(),
41890
+ file_overlap_count: exports_external.number().int().min(0).optional(),
41891
+ scope_accuracy: exports_external.number().min(0).max(2).optional(),
41892
+ time_balance_ratio: exports_external.number().min(1).optional()
41893
+ });
41894
+ var CoordinatorEventSchema = exports_external.discriminatedUnion("event_type", [
41895
+ exports_external.object({
41896
+ session_id: exports_external.string(),
41897
+ epic_id: exports_external.string(),
41898
+ timestamp: exports_external.string(),
41899
+ event_type: exports_external.literal("DECISION"),
41900
+ decision_type: exports_external.enum([
41901
+ "strategy_selected",
41902
+ "worker_spawned",
41903
+ "review_completed",
41904
+ "decomposition_complete"
41905
+ ]),
41906
+ payload: exports_external.any()
41907
+ }),
41908
+ exports_external.object({
41909
+ session_id: exports_external.string(),
41910
+ epic_id: exports_external.string(),
41911
+ timestamp: exports_external.string(),
41912
+ event_type: exports_external.literal("VIOLATION"),
41913
+ violation_type: exports_external.enum([
41914
+ "coordinator_edited_file",
41915
+ "coordinator_ran_tests",
41916
+ "coordinator_reserved_files",
41917
+ "no_worker_spawned"
41918
+ ]),
41919
+ payload: exports_external.any()
41920
+ }),
41921
+ exports_external.object({
41922
+ session_id: exports_external.string(),
41923
+ epic_id: exports_external.string(),
41924
+ timestamp: exports_external.string(),
41925
+ event_type: exports_external.literal("OUTCOME"),
41926
+ outcome_type: exports_external.enum([
41927
+ "subtask_success",
41928
+ "subtask_retry",
41929
+ "subtask_failed",
41930
+ "epic_complete"
41931
+ ]),
41932
+ payload: exports_external.any()
41933
+ })
41934
+ ]);
41935
+ var CoordinatorSessionSchema = exports_external.object({
41936
+ session_id: exports_external.string(),
41937
+ epic_id: exports_external.string(),
41938
+ start_time: exports_external.string(),
41939
+ end_time: exports_external.string().optional(),
41940
+ events: exports_external.array(CoordinatorEventSchema)
41941
+ });
41942
+ var inProgressRecords = new Map;
41943
+ function getSessionDir() {
41944
+ return path.join(os.homedir(), ".config", "swarm-tools", "sessions");
41945
+ }
41946
+ function getSessionPath(sessionId) {
41947
+ return path.join(getSessionDir(), `${sessionId}.jsonl`);
41948
+ }
41949
+ function ensureSessionDir() {
41950
+ const sessionDir = getSessionDir();
41951
+ if (!fs.existsSync(sessionDir)) {
41952
+ fs.mkdirSync(sessionDir, { recursive: true });
41953
+ }
41954
+ }
41955
+ function captureCoordinatorEvent(event) {
41956
+ CoordinatorEventSchema.parse(event);
41957
+ ensureSessionDir();
41958
+ const sessionPath = getSessionPath(event.session_id);
41959
+ const line = `${JSON.stringify(event)}
41960
+ `;
41961
+ fs.appendFileSync(sessionPath, line, "utf-8");
41962
+ }
41963
+
41964
+ // src/swarm-decompose.ts
41850
41965
  var DECOMPOSITION_PROMPT = `You are decomposing a task into parallelizable subtasks for a swarm of agents.
41851
41966
 
41852
41967
  ## Task
@@ -42107,7 +42222,6 @@ var swarm_decompose = tool({
42107
42222
  description: "Generate decomposition prompt for breaking task into parallelizable subtasks. Optionally queries CASS for similar past tasks.",
42108
42223
  args: {
42109
42224
  task: tool.schema.string().min(1).describe("Task description to decompose"),
42110
- max_subtasks: tool.schema.number().int().min(1).optional().describe("Suggested max subtasks (optional - LLM decides if not specified)"),
42111
42225
  context: tool.schema.string().optional().describe("Additional context (codebase info, constraints, etc.)"),
42112
42226
  query_cass: tool.schema.boolean().optional().describe("Query CASS for similar past tasks (default: true)"),
42113
42227
  cass_limit: tool.schema.number().int().min(1).optional().describe("Max CASS results to include (default: 3)")
@@ -42142,7 +42256,7 @@ var swarm_decompose = tool({
42142
42256
  const contextSection = fullContext ? `## Additional Context
42143
42257
  ${fullContext}` : `## Additional Context
42144
42258
  (none provided)`;
42145
- const prompt = DECOMPOSITION_PROMPT.replace("{task}", args.task).replace("{max_subtasks}", (args.max_subtasks ?? 5).toString()).replace("{context_section}", contextSection);
42259
+ const prompt = DECOMPOSITION_PROMPT.replace("{task}", args.task).replace("{context_section}", contextSection);
42146
42260
  return JSON.stringify({
42147
42261
  prompt,
42148
42262
  expected_schema: "CellTree",
@@ -42238,7 +42352,6 @@ var swarm_delegate_planning = tool({
42238
42352
  args: {
42239
42353
  task: tool.schema.string().min(1).describe("The task to decompose"),
42240
42354
  context: tool.schema.string().optional().describe("Additional context to include"),
42241
- max_subtasks: tool.schema.number().int().min(1).optional().describe("Suggested max subtasks (optional - LLM decides if not specified)"),
42242
42355
  strategy: tool.schema.enum(["auto", "file-based", "feature-based", "risk-based"]).optional().default("auto").describe("Decomposition strategy (default: auto-detect)"),
42243
42356
  query_cass: tool.schema.boolean().optional().default(true).describe("Query CASS for similar past tasks (default: true)")
42244
42357
  },
@@ -42256,6 +42369,22 @@ var swarm_delegate_planning = tool({
42256
42369
  selectedStrategy = selection.strategy;
42257
42370
  strategyReasoning = selection.reasoning;
42258
42371
  }
42372
+ try {
42373
+ captureCoordinatorEvent({
42374
+ session_id: process.env.OPENCODE_SESSION_ID || "unknown",
42375
+ epic_id: "planning",
42376
+ timestamp: new Date().toISOString(),
42377
+ event_type: "DECISION",
42378
+ decision_type: "strategy_selected",
42379
+ payload: {
42380
+ strategy: selectedStrategy,
42381
+ reasoning: strategyReasoning,
42382
+ task_preview: args.task.slice(0, 100)
42383
+ }
42384
+ });
42385
+ } catch (error45) {
42386
+ console.warn("[swarm_delegate_planning] Failed to capture strategy_selected:", error45);
42387
+ }
42259
42388
  let cassContext = "";
42260
42389
  let cassResultInfo;
42261
42390
  if (args.query_cass !== false) {
@@ -42301,7 +42430,7 @@ var swarm_delegate_planning = tool({
42301
42430
  const contextSection = args.context ? `## Additional Context
42302
42431
  ${args.context}` : `## Additional Context
42303
42432
  (none provided)`;
42304
- const planningPrompt = STRATEGY_DECOMPOSITION_PROMPT.replace("{task}", args.task).replace("{strategy_guidelines}", strategyGuidelines).replace("{context_section}", contextSection).replace("{cass_history}", cassContext || "").replace("{skills_context}", skillsContext || "").replace("{max_subtasks}", (args.max_subtasks ?? 5).toString());
42433
+ const planningPrompt = STRATEGY_DECOMPOSITION_PROMPT.replace("{task}", args.task).replace("{strategy_guidelines}", strategyGuidelines).replace("{context_section}", contextSection).replace("{cass_history}", cassContext || "").replace("{skills_context}", skillsContext || "");
42305
42434
  const subagentInstructions = `
42306
42435
  ## CRITICAL: Output Format
42307
42436
 
@@ -43408,11 +43537,11 @@ var qmarksTestNoExtDot = ([$0]) => {
43408
43537
  return (f) => f.length === len && f !== "." && f !== "..";
43409
43538
  };
43410
43539
  var defaultPlatform = typeof process === "object" && process ? typeof process.env === "object" && process.env && process.env.__MINIMATCH_TESTING_PLATFORM__ || process.platform : "posix";
43411
- var path = {
43540
+ var path2 = {
43412
43541
  win32: { sep: "\\" },
43413
43542
  posix: { sep: "/" }
43414
43543
  };
43415
- var sep2 = defaultPlatform === "win32" ? path.win32.sep : path.posix.sep;
43544
+ var sep2 = defaultPlatform === "win32" ? path2.win32.sep : path2.posix.sep;
43416
43545
  minimatch.sep = sep2;
43417
43546
  var GLOBSTAR = Symbol("globstar **");
43418
43547
  minimatch.GLOBSTAR = GLOBSTAR;
@@ -44057,12 +44186,12 @@ init_skills();
44057
44186
  // src/swarm-worktree.ts
44058
44187
  init_dist();
44059
44188
  init_zod();
44060
- import { join as join6 } from "node:path";
44061
- import { existsSync as existsSync5 } from "node:fs";
44189
+ import { join as join7 } from "node:path";
44190
+ import { existsSync as existsSync6 } from "node:fs";
44062
44191
  var WORKTREE_DIR = ".swarm/worktrees";
44063
44192
  function getWorktreePath(projectPath, taskId) {
44064
44193
  const safeTaskId = taskId.replace(/[^a-zA-Z0-9.-]/g, "_");
44065
- return join6(projectPath, WORKTREE_DIR, safeTaskId);
44194
+ return join7(projectPath, WORKTREE_DIR, safeTaskId);
44066
44195
  }
44067
44196
  function parseTaskIdFromPath(worktreePath) {
44068
44197
  const parts = worktreePath.split("/");
@@ -44072,18 +44201,18 @@ function parseTaskIdFromPath(worktreePath) {
44072
44201
  }
44073
44202
  return null;
44074
44203
  }
44075
- async function isGitRepo(path2) {
44076
- const result = await Bun.$`git -C ${path2} rev-parse --git-dir`.quiet().nothrow();
44204
+ async function isGitRepo(path3) {
44205
+ const result = await Bun.$`git -C ${path3} rev-parse --git-dir`.quiet().nothrow();
44077
44206
  return result.exitCode === 0;
44078
44207
  }
44079
- async function hasUncommittedChanges(path2) {
44080
- const result = await Bun.$`git -C ${path2} status --porcelain`.quiet().nothrow();
44208
+ async function hasUncommittedChanges(path3) {
44209
+ const result = await Bun.$`git -C ${path3} status --porcelain`.quiet().nothrow();
44081
44210
  if (result.exitCode !== 0)
44082
44211
  return true;
44083
44212
  return result.stdout.toString().trim().length > 0;
44084
44213
  }
44085
- async function getCurrentCommit(path2) {
44086
- const result = await Bun.$`git -C ${path2} rev-parse HEAD`.quiet().nothrow();
44214
+ async function getCurrentCommit(path3) {
44215
+ const result = await Bun.$`git -C ${path3} rev-parse HEAD`.quiet().nothrow();
44087
44216
  if (result.exitCode !== 0)
44088
44217
  return null;
44089
44218
  return result.stdout.toString().trim();
@@ -44096,7 +44225,7 @@ async function getWorktreeCommits(worktreePath, startCommit) {
44096
44225
  `).filter((c) => c.length > 0);
44097
44226
  }
44098
44227
  async function ensureWorktreeDir(projectPath) {
44099
- const worktreeDir = join6(projectPath, WORKTREE_DIR);
44228
+ const worktreeDir = join7(projectPath, WORKTREE_DIR);
44100
44229
  await Bun.$`mkdir -p ${worktreeDir}`.quiet().nothrow();
44101
44230
  }
44102
44231
  var swarm_worktree_create = tool({
@@ -44115,7 +44244,7 @@ var swarm_worktree_create = tool({
44115
44244
  return JSON.stringify(result2, null, 2);
44116
44245
  }
44117
44246
  const worktreePath = getWorktreePath(args.project_path, args.task_id);
44118
- const exists = existsSync5(worktreePath);
44247
+ const exists = existsSync6(worktreePath);
44119
44248
  if (exists) {
44120
44249
  const result2 = {
44121
44250
  success: false,
@@ -44151,7 +44280,7 @@ var swarm_worktree_merge = tool({
44151
44280
  },
44152
44281
  async execute(args) {
44153
44282
  const worktreePath = getWorktreePath(args.project_path, args.task_id);
44154
- const exists = existsSync5(worktreePath);
44283
+ const exists = existsSync6(worktreePath);
44155
44284
  if (!exists) {
44156
44285
  const result2 = {
44157
44286
  success: false,
@@ -44233,7 +44362,7 @@ var swarm_worktree_cleanup = tool({
44233
44362
  return JSON.stringify(result3, null, 2);
44234
44363
  }
44235
44364
  const output = listResult.stdout.toString();
44236
- const worktreeDir = join6(args.project_path, WORKTREE_DIR);
44365
+ const worktreeDir = join7(args.project_path, WORKTREE_DIR);
44237
44366
  const worktrees = output.split(`
44238
44367
 
44239
44368
  `).filter((block) => block.includes(worktreeDir)).map((block) => {
@@ -44261,7 +44390,7 @@ var swarm_worktree_cleanup = tool({
44261
44390
  return JSON.stringify(result2, null, 2);
44262
44391
  }
44263
44392
  const worktreePath = getWorktreePath(args.project_path, args.task_id);
44264
- const exists = existsSync5(worktreePath);
44393
+ const exists = existsSync6(worktreePath);
44265
44394
  if (!exists) {
44266
44395
  const result2 = {
44267
44396
  success: true,
@@ -44298,7 +44427,7 @@ var swarm_worktree_list = tool({
44298
44427
  }, null, 2);
44299
44428
  }
44300
44429
  const output = listResult.stdout.toString();
44301
- const worktreeDir = join6(args.project_path, WORKTREE_DIR);
44430
+ const worktreeDir = join7(args.project_path, WORKTREE_DIR);
44302
44431
  const worktrees = [];
44303
44432
  const blocks = output.split(`
44304
44433
 
@@ -44308,12 +44437,12 @@ var swarm_worktree_list = tool({
44308
44437
  const commitMatch = block.match(/^HEAD ([a-f0-9]+)$/m);
44309
44438
  const branchMatch = block.match(/^branch (.+)$/m);
44310
44439
  if (pathMatch && pathMatch[1].includes(worktreeDir)) {
44311
- const path2 = pathMatch[1];
44312
- const taskId = parseTaskIdFromPath(path2);
44440
+ const path3 = pathMatch[1];
44441
+ const taskId = parseTaskIdFromPath(path3);
44313
44442
  if (taskId) {
44314
44443
  worktrees.push({
44315
44444
  task_id: taskId,
44316
- path: path2,
44445
+ path: path3,
44317
44446
  commit: commitMatch ? commitMatch[1] : "unknown",
44318
44447
  branch: branchMatch ? branchMatch[1] : undefined
44319
44448
  });
@@ -44597,6 +44726,22 @@ var swarm_review_feedback = tool({
44597
44726
  const epicId = args.task_id.includes(".") ? args.task_id.split(".")[0] : args.task_id;
44598
44727
  if (args.status === "approved") {
44599
44728
  markReviewApproved(args.task_id);
44729
+ try {
44730
+ captureCoordinatorEvent({
44731
+ session_id: process.env.OPENCODE_SESSION_ID || "unknown",
44732
+ epic_id: epicId,
44733
+ timestamp: new Date().toISOString(),
44734
+ event_type: "DECISION",
44735
+ decision_type: "review_completed",
44736
+ payload: {
44737
+ task_id: args.task_id,
44738
+ status: "approved",
44739
+ retry_count: 0
44740
+ }
44741
+ });
44742
+ } catch (error45) {
44743
+ console.warn("[swarm_review_feedback] Failed to capture review_completed:", error45);
44744
+ }
44600
44745
  await sendSwarmMessage2({
44601
44746
  projectPath: args.project_key,
44602
44747
  fromAgent: "coordinator",
@@ -44619,6 +44764,24 @@ You may now complete the task with \`swarm_complete\`.`,
44619
44764
  }
44620
44765
  const attemptNumber = incrementAttempt(args.task_id);
44621
44766
  const remaining = MAX_REVIEW_ATTEMPTS - attemptNumber;
44767
+ try {
44768
+ captureCoordinatorEvent({
44769
+ session_id: process.env.OPENCODE_SESSION_ID || "unknown",
44770
+ epic_id: epicId,
44771
+ timestamp: new Date().toISOString(),
44772
+ event_type: "DECISION",
44773
+ decision_type: "review_completed",
44774
+ payload: {
44775
+ task_id: args.task_id,
44776
+ status: "needs_changes",
44777
+ retry_count: attemptNumber,
44778
+ remaining_attempts: remaining,
44779
+ issues_count: parsedIssues.length
44780
+ }
44781
+ });
44782
+ } catch (error45) {
44783
+ console.warn("[swarm_review_feedback] Failed to capture review_completed:", error45);
44784
+ }
44622
44785
  if (remaining <= 0) {
44623
44786
  const adapter = await getHiveAdapterSafe(args.project_key);
44624
44787
  if (adapter) {
@@ -45574,6 +45737,25 @@ Files touched: ${args.files_touched?.join(", ") || "none recorded"}`,
45574
45737
  reason: "No files_owned contract found (non-epic subtask or decomposition event missing)"
45575
45738
  }
45576
45739
  };
45740
+ try {
45741
+ const durationMs2 = args.start_time ? Date.now() - args.start_time : 0;
45742
+ captureCoordinatorEvent({
45743
+ session_id: process.env.OPENCODE_SESSION_ID || "unknown",
45744
+ epic_id: epicId2,
45745
+ timestamp: new Date().toISOString(),
45746
+ event_type: "OUTCOME",
45747
+ outcome_type: "subtask_success",
45748
+ payload: {
45749
+ bead_id: args.bead_id,
45750
+ duration_ms: durationMs2,
45751
+ files_touched: args.files_touched || [],
45752
+ verification_passed: verificationResult?.passed ?? false,
45753
+ verification_skipped: args.skip_verification ?? false
45754
+ }
45755
+ });
45756
+ } catch (error45) {
45757
+ console.warn("[swarm_complete] Failed to capture subtask_success:", error45);
45758
+ }
45577
45759
  return JSON.stringify(response, null, 2);
45578
45760
  } catch (error45) {
45579
45761
  const errorMessage = error45 instanceof Error ? error45.message : String(error45);
@@ -45637,6 +45819,24 @@ ${errorStack.slice(0, 1000)}
45637
45819
  console.error(`[swarm_complete] CRITICAL: Failed to notify coordinator of failure for ${args.bead_id}:`, mailError);
45638
45820
  console.error(`[swarm_complete] Original error:`, error45);
45639
45821
  }
45822
+ try {
45823
+ const durationMs = args.start_time ? Date.now() - args.start_time : 0;
45824
+ captureCoordinatorEvent({
45825
+ session_id: process.env.OPENCODE_SESSION_ID || "unknown",
45826
+ epic_id: epicId,
45827
+ timestamp: new Date().toISOString(),
45828
+ event_type: "OUTCOME",
45829
+ outcome_type: "subtask_failed",
45830
+ payload: {
45831
+ bead_id: args.bead_id,
45832
+ duration_ms: durationMs,
45833
+ failed_step: failedStep,
45834
+ error_message: errorMessage.slice(0, 500)
45835
+ }
45836
+ });
45837
+ } catch (captureError) {
45838
+ console.warn("[swarm_complete] Failed to capture subtask_failed:", captureError);
45839
+ }
45640
45840
  return JSON.stringify({
45641
45841
  success: false,
45642
45842
  error: `swarm_complete failed: ${errorMessage}`,
@@ -46149,7 +46349,7 @@ ${args.files_context.map((f) => `- \`${f}\``).join(`
46149
46349
  *Learned from swarm execution on ${new Date().toISOString().split("T")[0]}*`;
46150
46350
  const { getSkill: getSkill2, invalidateSkillsCache: invalidateSkillsCache2 } = await Promise.resolve().then(() => (init_skills(), exports_skills));
46151
46351
  const { mkdir: mkdir2, writeFile: writeFile2 } = await import("node:fs/promises");
46152
- const { join: join7 } = await import("node:path");
46352
+ const { join: join8 } = await import("node:path");
46153
46353
  const existing = await getSkill2(args.skill_name);
46154
46354
  if (existing) {
46155
46355
  return JSON.stringify({
@@ -46160,8 +46360,8 @@ ${args.files_context.map((f) => `- \`${f}\``).join(`
46160
46360
  suggestion: "Use skills_update to add to existing skill, or choose a different name"
46161
46361
  }, null, 2);
46162
46362
  }
46163
- const skillDir = join7(process.cwd(), ".opencode", "skills", args.skill_name);
46164
- const skillPath = join7(skillDir, "SKILL.md");
46363
+ const skillDir = join8(process.cwd(), ".opencode", "skills", args.skill_name);
46364
+ const skillPath = join8(skillDir, "SKILL.md");
46165
46365
  const frontmatter = [
46166
46366
  "---",
46167
46367
  `name: ${args.skill_name}`,
@@ -47048,6 +47248,22 @@ var swarm_spawn_subtask = tool({
47048
47248
  const selectedModel = selectWorkerModel2(subtask, config2);
47049
47249
  const filesJoined = args.files.map((f) => `"${f}"`).join(", ");
47050
47250
  const postCompletionInstructions = COORDINATOR_POST_WORKER_CHECKLIST.replace(/{project_key}/g, args.project_path || "$PWD").replace(/{epic_id}/g, args.epic_id).replace(/{task_id}/g, args.bead_id).replace(/{files_touched}/g, filesJoined).replace(/{worker_id}/g, "worker");
47251
+ try {
47252
+ captureCoordinatorEvent({
47253
+ session_id: process.env.OPENCODE_SESSION_ID || "unknown",
47254
+ epic_id: args.epic_id,
47255
+ timestamp: new Date().toISOString(),
47256
+ event_type: "DECISION",
47257
+ decision_type: "worker_spawned",
47258
+ payload: {
47259
+ bead_id: args.bead_id,
47260
+ files: args.files,
47261
+ worker_model: selectedModel
47262
+ }
47263
+ });
47264
+ } catch (error45) {
47265
+ console.warn("[swarm_spawn_subtask] Failed to capture worker_spawned:", error45);
47266
+ }
47051
47267
  return JSON.stringify({
47052
47268
  prompt,
47053
47269
  bead_id: args.bead_id,
@@ -47243,7 +47459,6 @@ var swarm_plan_prompt = tool({
47243
47459
  args: {
47244
47460
  task: tool.schema.string().min(1).describe("Task description to decompose"),
47245
47461
  strategy: tool.schema.enum(["file-based", "feature-based", "risk-based", "auto"]).optional().describe("Decomposition strategy (default: auto-detect)"),
47246
- max_subtasks: tool.schema.number().int().min(1).optional().describe("Suggested max subtasks (optional - LLM decides if not specified)"),
47247
47462
  context: tool.schema.string().optional().describe("Additional context (codebase info, constraints, etc.)"),
47248
47463
  query_cass: tool.schema.boolean().optional().describe("Query CASS for similar past tasks (default: true)"),
47249
47464
  cass_limit: tool.schema.number().int().min(1).optional().describe("Max CASS results to include (default: 3)"),
@@ -47288,7 +47503,7 @@ var swarm_plan_prompt = tool({
47288
47503
  const contextSection = args.context ? `## Additional Context
47289
47504
  ${args.context}` : `## Additional Context
47290
47505
  (none provided)`;
47291
- const prompt = STRATEGY_DECOMPOSITION_PROMPT2.replace("{task}", args.task).replace("{strategy_guidelines}", strategyGuidelines).replace("{context_section}", contextSection).replace("{cass_history}", "").replace("{skills_context}", skillsContext || "").replace("{max_subtasks}", (args.max_subtasks ?? 5).toString());
47506
+ const prompt = STRATEGY_DECOMPOSITION_PROMPT2.replace("{task}", args.task).replace("{strategy_guidelines}", strategyGuidelines).replace("{context_section}", contextSection).replace("{cass_history}", "").replace("{skills_context}", skillsContext || "");
47292
47507
  return JSON.stringify({
47293
47508
  prompt,
47294
47509
  strategy: {
@@ -47326,9 +47541,9 @@ var promptTools = {
47326
47541
  };
47327
47542
  // src/swarm-research.ts
47328
47543
  init_dist();
47329
- import { existsSync as existsSync6 } from "node:fs";
47544
+ import { existsSync as existsSync7 } from "node:fs";
47330
47545
  import { readFile as readFile2 } from "node:fs/promises";
47331
- import { join as join7 } from "node:path";
47546
+ import { join as join8 } from "node:path";
47332
47547
 
47333
47548
  // ../../node_modules/.bun/yaml@2.8.2/node_modules/yaml/dist/index.js
47334
47549
  var composer = require_composer();
@@ -47511,21 +47726,21 @@ async function parsePackageJson(packageJsonPath, packages) {
47511
47726
  }
47512
47727
  }
47513
47728
  async function getInstalledVersions(projectPath, packages, checkUpgrades = false) {
47514
- const npmLock = join7(projectPath, "package-lock.json");
47729
+ const npmLock = join8(projectPath, "package-lock.json");
47515
47730
  let versions2 = [];
47516
- if (existsSync6(npmLock)) {
47731
+ if (existsSync7(npmLock)) {
47517
47732
  versions2 = await parseNpmLockfile(npmLock, packages);
47518
47733
  } else {
47519
- const pnpmLock = join7(projectPath, "pnpm-lock.yaml");
47520
- if (existsSync6(pnpmLock)) {
47734
+ const pnpmLock = join8(projectPath, "pnpm-lock.yaml");
47735
+ if (existsSync7(pnpmLock)) {
47521
47736
  versions2 = await parsePnpmLockfile(pnpmLock, packages);
47522
47737
  } else {
47523
- const yarnLock = join7(projectPath, "yarn.lock");
47524
- if (existsSync6(yarnLock)) {
47738
+ const yarnLock = join8(projectPath, "yarn.lock");
47739
+ if (existsSync7(yarnLock)) {
47525
47740
  versions2 = await parseYarnLockfile(yarnLock, packages);
47526
47741
  } else {
47527
- const packageJson = join7(projectPath, "package.json");
47528
- if (existsSync6(packageJson)) {
47742
+ const packageJson = join8(projectPath, "package.json");
47743
+ if (existsSync7(packageJson)) {
47529
47744
  versions2 = await parsePackageJson(packageJson, packages);
47530
47745
  }
47531
47746
  }
@@ -49743,7 +49958,7 @@ var dedupeWith = /* @__PURE__ */ dual(2, (self, isEquivalent) => {
49743
49958
  return [];
49744
49959
  });
49745
49960
  var dedupe = (self) => dedupeWith(self, equivalence());
49746
- var join8 = /* @__PURE__ */ dual(2, (self, sep3) => fromIterable(self).join(sep3));
49961
+ var join9 = /* @__PURE__ */ dual(2, (self, sep3) => fromIterable(self).join(sep3));
49747
49962
 
49748
49963
  // ../../node_modules/.bun/effect@3.19.12/node_modules/effect/dist/esm/Number.js
49749
49964
  var Order = number5;
@@ -54284,67 +54499,67 @@ var Or = (self, that) => {
54284
54499
  });
54285
54500
  return error45;
54286
54501
  };
54287
- var InvalidData = (path2, message, options2 = {
54502
+ var InvalidData = (path3, message, options2 = {
54288
54503
  pathDelim: "."
54289
54504
  }) => {
54290
54505
  const error45 = Object.create(proto2);
54291
54506
  error45._op = OP_INVALID_DATA;
54292
- error45.path = path2;
54507
+ error45.path = path3;
54293
54508
  error45.message = message;
54294
54509
  Object.defineProperty(error45, "toString", {
54295
54510
  enumerable: false,
54296
54511
  value() {
54297
- const path3 = pipe2(this.path, join8(options2.pathDelim));
54298
- return `(Invalid data at ${path3}: "${this.message}")`;
54512
+ const path4 = pipe2(this.path, join9(options2.pathDelim));
54513
+ return `(Invalid data at ${path4}: "${this.message}")`;
54299
54514
  }
54300
54515
  });
54301
54516
  return error45;
54302
54517
  };
54303
- var MissingData = (path2, message, options2 = {
54518
+ var MissingData = (path3, message, options2 = {
54304
54519
  pathDelim: "."
54305
54520
  }) => {
54306
54521
  const error45 = Object.create(proto2);
54307
54522
  error45._op = OP_MISSING_DATA;
54308
- error45.path = path2;
54523
+ error45.path = path3;
54309
54524
  error45.message = message;
54310
54525
  Object.defineProperty(error45, "toString", {
54311
54526
  enumerable: false,
54312
54527
  value() {
54313
- const path3 = pipe2(this.path, join8(options2.pathDelim));
54314
- return `(Missing data at ${path3}: "${this.message}")`;
54528
+ const path4 = pipe2(this.path, join9(options2.pathDelim));
54529
+ return `(Missing data at ${path4}: "${this.message}")`;
54315
54530
  }
54316
54531
  });
54317
54532
  return error45;
54318
54533
  };
54319
- var SourceUnavailable = (path2, message, cause, options2 = {
54534
+ var SourceUnavailable = (path3, message, cause, options2 = {
54320
54535
  pathDelim: "."
54321
54536
  }) => {
54322
54537
  const error45 = Object.create(proto2);
54323
54538
  error45._op = OP_SOURCE_UNAVAILABLE;
54324
- error45.path = path2;
54539
+ error45.path = path3;
54325
54540
  error45.message = message;
54326
54541
  error45.cause = cause;
54327
54542
  Object.defineProperty(error45, "toString", {
54328
54543
  enumerable: false,
54329
54544
  value() {
54330
- const path3 = pipe2(this.path, join8(options2.pathDelim));
54331
- return `(Source unavailable at ${path3}: "${this.message}")`;
54545
+ const path4 = pipe2(this.path, join9(options2.pathDelim));
54546
+ return `(Source unavailable at ${path4}: "${this.message}")`;
54332
54547
  }
54333
54548
  });
54334
54549
  return error45;
54335
54550
  };
54336
- var Unsupported = (path2, message, options2 = {
54551
+ var Unsupported = (path3, message, options2 = {
54337
54552
  pathDelim: "."
54338
54553
  }) => {
54339
54554
  const error45 = Object.create(proto2);
54340
54555
  error45._op = OP_UNSUPPORTED;
54341
- error45.path = path2;
54556
+ error45.path = path3;
54342
54557
  error45.message = message;
54343
54558
  Object.defineProperty(error45, "toString", {
54344
54559
  enumerable: false,
54345
54560
  value() {
54346
- const path3 = pipe2(this.path, join8(options2.pathDelim));
54347
- return `(Unsupported operation at ${path3}: "${this.message}")`;
54561
+ const path4 = pipe2(this.path, join9(options2.pathDelim));
54562
+ return `(Unsupported operation at ${path4}: "${this.message}")`;
54348
54563
  }
54349
54564
  });
54350
54565
  return error45;
@@ -54376,9 +54591,9 @@ var prefixed = /* @__PURE__ */ dual(2, (self, prefix) => {
54376
54591
  var empty19 = {
54377
54592
  _tag: "Empty"
54378
54593
  };
54379
- var patch5 = /* @__PURE__ */ dual(2, (path2, patch6) => {
54594
+ var patch5 = /* @__PURE__ */ dual(2, (path3, patch6) => {
54380
54595
  let input = of3(patch6);
54381
- let output = path2;
54596
+ let output = path3;
54382
54597
  while (isCons(input)) {
54383
54598
  const patch7 = input.head;
54384
54599
  switch (patch7._tag) {
@@ -54445,7 +54660,7 @@ var make21 = (options2) => ({
54445
54660
  var makeFlat = (options2) => ({
54446
54661
  [FlatConfigProviderTypeId]: FlatConfigProviderTypeId,
54447
54662
  patch: options2.patch,
54448
- load: (path2, config2, split = true) => options2.load(path2, config2, split),
54663
+ load: (path3, config2, split = true) => options2.load(path3, config2, split),
54449
54664
  enumerateChildren: options2.enumerateChildren
54450
54665
  });
54451
54666
  var fromFlat = (flat) => make21({
@@ -54463,29 +54678,29 @@ var fromEnv = (options2) => {
54463
54678
  pathDelim: "_",
54464
54679
  seqDelim: ","
54465
54680
  }, options2);
54466
- const makePathString = (path2) => pipe2(path2, join8(pathDelim));
54681
+ const makePathString = (path3) => pipe2(path3, join9(pathDelim));
54467
54682
  const unmakePathString = (pathString) => pathString.split(pathDelim);
54468
54683
  const getEnv = () => typeof process !== "undefined" && ("env" in process) && typeof process.env === "object" ? process.env : {};
54469
- const load = (path2, primitive, split = true) => {
54470
- const pathString = makePathString(path2);
54684
+ const load = (path3, primitive, split = true) => {
54685
+ const pathString = makePathString(path3);
54471
54686
  const current = getEnv();
54472
54687
  const valueOpt = pathString in current ? some2(current[pathString]) : none2();
54473
- return pipe2(valueOpt, mapError(() => MissingData(path2, `Expected ${pathString} to exist in the process context`)), flatMap7((value) => parsePrimitive(value, path2, primitive, seqDelim, split)));
54688
+ return pipe2(valueOpt, mapError(() => MissingData(path3, `Expected ${pathString} to exist in the process context`)), flatMap7((value) => parsePrimitive(value, path3, primitive, seqDelim, split)));
54474
54689
  };
54475
- const enumerateChildren = (path2) => sync(() => {
54690
+ const enumerateChildren = (path3) => sync(() => {
54476
54691
  const current = getEnv();
54477
54692
  const keys3 = Object.keys(current);
54478
54693
  const keyPaths = keys3.map((value) => unmakePathString(value.toUpperCase()));
54479
54694
  const filteredKeyPaths = keyPaths.filter((keyPath) => {
54480
- for (let i = 0;i < path2.length; i++) {
54481
- const pathComponent = pipe2(path2, unsafeGet(i));
54695
+ for (let i = 0;i < path3.length; i++) {
54696
+ const pathComponent = pipe2(path3, unsafeGet(i));
54482
54697
  const currentElement = keyPath[i];
54483
54698
  if (currentElement === undefined || pathComponent !== currentElement) {
54484
54699
  return false;
54485
54700
  }
54486
54701
  }
54487
54702
  return true;
54488
- }).flatMap((keyPath) => keyPath.slice(path2.length, path2.length + 1));
54703
+ }).flatMap((keyPath) => keyPath.slice(path3.length, path3.length + 1));
54489
54704
  return fromIterable5(filteredKeyPaths);
54490
54705
  });
54491
54706
  return fromFlat(makeFlat({
@@ -54501,17 +54716,17 @@ var extend2 = (leftDef, rightDef, left3, right3) => {
54501
54716
  const rightExtension = concat(right3, rightPad);
54502
54717
  return [leftExtension, rightExtension];
54503
54718
  };
54504
- var appendConfigPath = (path2, config2) => {
54719
+ var appendConfigPath = (path3, config2) => {
54505
54720
  let op = config2;
54506
54721
  if (op._tag === "Nested") {
54507
- const out = path2.slice();
54722
+ const out = path3.slice();
54508
54723
  while (op._tag === "Nested") {
54509
54724
  out.push(op.name);
54510
54725
  op = op.config;
54511
54726
  }
54512
54727
  return out;
54513
54728
  }
54514
- return path2;
54729
+ return path3;
54515
54730
  };
54516
54731
  var fromFlatLoop = (flat, prefix, config2, split) => {
54517
54732
  const op = config2;
@@ -54587,8 +54802,8 @@ var fromFlatLoop = (flat, prefix, config2, split) => {
54587
54802
  return fail2(right3.left);
54588
54803
  }
54589
54804
  if (isRight2(left3) && isRight2(right3)) {
54590
- const path2 = pipe2(prefix, join8("."));
54591
- const fail3 = fromFlatLoopFail(prefix, path2);
54805
+ const path3 = pipe2(prefix, join9("."));
54806
+ const fail3 = fromFlatLoopFail(prefix, path3);
54592
54807
  const [lefts, rights] = extend2(fail3, fail3, pipe2(left3.right, map3(right2)), pipe2(right3.right, map3(right2)));
54593
54808
  return pipe2(lefts, zip(rights), forEachSequential(([left4, right4]) => pipe2(zip2(left4, right4), map9(([left5, right5]) => op.zip(left5, right5)))));
54594
54809
  }
@@ -54597,19 +54812,19 @@ var fromFlatLoop = (flat, prefix, config2, split) => {
54597
54812
  }
54598
54813
  }
54599
54814
  };
54600
- var fromFlatLoopFail = (prefix, path2) => (index) => left2(MissingData(prefix, `The element at index ${index} in a sequence at path "${path2}" was missing`));
54815
+ var fromFlatLoopFail = (prefix, path3) => (index) => left2(MissingData(prefix, `The element at index ${index} in a sequence at path "${path3}" was missing`));
54601
54816
  var splitPathString = (text, delim) => {
54602
54817
  const split = text.split(new RegExp(`\\s*${escape2(delim)}\\s*`));
54603
54818
  return split;
54604
54819
  };
54605
- var parsePrimitive = (text, path2, primitive, delimiter, split) => {
54820
+ var parsePrimitive = (text, path3, primitive, delimiter, split) => {
54606
54821
  if (!split) {
54607
54822
  return pipe2(primitive.parse(text), mapBoth({
54608
- onFailure: prefixed(path2),
54823
+ onFailure: prefixed(path3),
54609
54824
  onSuccess: of
54610
54825
  }));
54611
54826
  }
54612
- return pipe2(splitPathString(text, delimiter), forEachSequential((char) => primitive.parse(char.trim())), mapError(prefixed(path2)));
54827
+ return pipe2(splitPathString(text, delimiter), forEachSequential((char) => primitive.parse(char.trim())), mapError(prefixed(path3)));
54613
54828
  };
54614
54829
  var transpose = (array4) => {
54615
54830
  return Object.keys(array4[0]).map((column) => array4.map((row) => row[column]));
@@ -56761,11 +56976,11 @@ var interruptAllAs = /* @__PURE__ */ dual(2, /* @__PURE__ */ fnUntraced(function
56761
56976
  }
56762
56977
  }));
56763
56978
  var interruptAsFork = /* @__PURE__ */ dual(2, (self, fiberId2) => self.interruptAsFork(fiberId2));
56764
- var join9 = (self) => zipLeft(flatten4(self.await), self.inheritAll);
56979
+ var join10 = (self) => zipLeft(flatten4(self.await), self.inheritAll);
56765
56980
  var _never2 = {
56766
56981
  ...CommitPrototype,
56767
56982
  commit() {
56768
- return join9(this);
56983
+ return join10(this);
56769
56984
  },
56770
56985
  ...fiberProto,
56771
56986
  id: () => none4,
@@ -58012,7 +58227,7 @@ class FiberRuntime extends Class2 {
58012
58227
  this.refreshRefCache();
58013
58228
  }
58014
58229
  commit() {
58015
- return join9(this);
58230
+ return join10(this);
58016
58231
  }
58017
58232
  id() {
58018
58233
  return this._fiberId;
@@ -59027,7 +59242,7 @@ var forEachConcurrentDiscard = (self, f, batching, processAll, n) => uninterrupt
59027
59242
  next();
59028
59243
  }
59029
59244
  }));
59030
- return asVoid(onExit(flatten4(restore(join9(processingFiber))), exitMatch({
59245
+ return asVoid(onExit(flatten4(restore(join10(processingFiber))), exitMatch({
59031
59246
  onFailure: (cause2) => {
59032
59247
  onInterruptSignal();
59033
59248
  const target2 = residual.length + 1;
@@ -59349,7 +59564,7 @@ var fiberAll = (fibers) => {
59349
59564
  const _fiberAll = {
59350
59565
  ...CommitPrototype2,
59351
59566
  commit() {
59352
- return join9(this);
59567
+ return join10(this);
59353
59568
  },
59354
59569
  [FiberTypeId]: fiberVariance2,
59355
59570
  id: () => fromIterable(fibers).reduce((id, fiber) => combine3(id, fiber.id()), none4),
@@ -59402,14 +59617,14 @@ var raceWith = /* @__PURE__ */ dual(3, (self, other, options2) => raceFibersWith
59402
59617
  }
59403
59618
  })
59404
59619
  }));
59405
- var disconnect = (self) => uninterruptibleMask((restore) => fiberIdWith((fiberId2) => flatMap7(forkDaemon(restore(self)), (fiber) => pipe2(restore(join9(fiber)), onInterrupt(() => pipe2(fiber, interruptAsFork(fiberId2)))))));
59620
+ var disconnect = (self) => uninterruptibleMask((restore) => fiberIdWith((fiberId2) => flatMap7(forkDaemon(restore(self)), (fiber) => pipe2(restore(join10(fiber)), onInterrupt(() => pipe2(fiber, interruptAsFork(fiberId2)))))));
59406
59621
  var race = /* @__PURE__ */ dual(2, (self, that) => fiberIdWith((parentFiberId) => raceWith(self, that, {
59407
59622
  onSelfDone: (exit2, right3) => exitMatchEffect(exit2, {
59408
- onFailure: (cause2) => pipe2(join9(right3), mapErrorCause((cause22) => parallel(cause2, cause22))),
59623
+ onFailure: (cause2) => pipe2(join10(right3), mapErrorCause((cause22) => parallel(cause2, cause22))),
59409
59624
  onSuccess: (value) => pipe2(right3, interruptAsFiber(parentFiberId), as(value))
59410
59625
  }),
59411
59626
  onOtherDone: (exit2, left3) => exitMatchEffect(exit2, {
59412
- onFailure: (cause2) => pipe2(join9(left3), mapErrorCause((cause22) => parallel(cause22, cause2))),
59627
+ onFailure: (cause2) => pipe2(join10(left3), mapErrorCause((cause22) => parallel(cause22, cause2))),
59413
59628
  onSuccess: (value) => pipe2(left3, interruptAsFiber(parentFiberId), as(value))
59414
59629
  })
59415
59630
  })));
@@ -60563,8 +60778,8 @@ var forkIn = /* @__PURE__ */ dual(2, (self, scope2) => withFiberRuntime((parent,
60563
60778
  return succeed(fiber);
60564
60779
  }));
60565
60780
  var forkScoped = (self) => scopeWith((scope2) => forkIn(self, scope2));
60566
- var fromFiber = (fiber) => join9(fiber);
60567
- var fromFiberEffect = (fiber) => suspend(() => flatMap7(fiber, join9));
60781
+ var fromFiber = (fiber) => join10(fiber);
60782
+ var fromFiberEffect = (fiber) => suspend(() => flatMap7(fiber, join10));
60568
60783
  var memoKeySymbol = /* @__PURE__ */ Symbol.for("effect/Effect/memoizeFunction.key");
60569
60784
 
60570
60785
  class Key {
@@ -62310,14 +62525,14 @@ async function createMemoryAdapter(db) {
62310
62525
  var cachedAdapter = null;
62311
62526
  var cachedProjectPath = null;
62312
62527
  async function getMemoryAdapter(projectPath) {
62313
- const path2 = projectPath || process.cwd();
62314
- if (cachedAdapter && cachedProjectPath === path2) {
62528
+ const path3 = projectPath || process.cwd();
62529
+ if (cachedAdapter && cachedProjectPath === path3) {
62315
62530
  return cachedAdapter;
62316
62531
  }
62317
- const swarmMail = await getSwarmMailLibSQL3(path2);
62532
+ const swarmMail = await getSwarmMailLibSQL3(path3);
62318
62533
  const dbAdapter = await swarmMail.getDatabase();
62319
62534
  cachedAdapter = await createMemoryAdapter(dbAdapter);
62320
- cachedProjectPath = path2;
62535
+ cachedProjectPath = path3;
62321
62536
  return cachedAdapter;
62322
62537
  }
62323
62538
  function resetMemoryCache() {
@@ -63033,6 +63248,752 @@ Swarm workers can complete these ${fileModificationCount} tasks in parallel.
63033
63248
  function shouldAnalyzeTool(toolName) {
63034
63249
  return toolName === "todowrite" || toolName === "TodoWrite";
63035
63250
  }
63251
+ var VIOLATION_PATTERNS = {
63252
+ FILE_MODIFICATION_TOOLS: ["edit", "write"],
63253
+ RESERVATION_TOOLS: ["swarmmail_reserve", "agentmail_reserve"],
63254
+ TEST_EXECUTION_PATTERNS: [
63255
+ /\bbun\s+test\b/i,
63256
+ /\bnpm\s+(run\s+)?test/i,
63257
+ /\byarn\s+(run\s+)?test/i,
63258
+ /\bpnpm\s+(run\s+)?test/i,
63259
+ /\bjest\b/i,
63260
+ /\bvitest\b/i,
63261
+ /\bmocha\b/i,
63262
+ /\bava\b/i,
63263
+ /\btape\b/i,
63264
+ /\.test\.(ts|js|tsx|jsx)\b/i,
63265
+ /\.spec\.(ts|js|tsx|jsx)\b/i
63266
+ ]
63267
+ };
63268
+ function detectCoordinatorViolation(params) {
63269
+ const { sessionId, epicId, toolName, toolArgs, agentContext, checkNoSpawn = false } = params;
63270
+ if (agentContext !== "coordinator") {
63271
+ return { isViolation: false };
63272
+ }
63273
+ if (VIOLATION_PATTERNS.FILE_MODIFICATION_TOOLS.includes(toolName)) {
63274
+ const file2 = toolArgs.filePath || "";
63275
+ const payload = { tool: toolName, file: file2 };
63276
+ captureCoordinatorEvent({
63277
+ session_id: sessionId,
63278
+ epic_id: epicId,
63279
+ timestamp: new Date().toISOString(),
63280
+ event_type: "VIOLATION",
63281
+ violation_type: "coordinator_edited_file",
63282
+ payload
63283
+ });
63284
+ return {
63285
+ isViolation: true,
63286
+ violationType: "coordinator_edited_file",
63287
+ message: `⚠️ Coordinator should not edit files directly. Coordinators should spawn workers to implement changes.`,
63288
+ payload
63289
+ };
63290
+ }
63291
+ if (toolName === "bash") {
63292
+ const command = toolArgs.command || "";
63293
+ const isTestCommand = VIOLATION_PATTERNS.TEST_EXECUTION_PATTERNS.some((pattern) => pattern.test(command));
63294
+ if (isTestCommand) {
63295
+ const payload = { tool: toolName, command };
63296
+ captureCoordinatorEvent({
63297
+ session_id: sessionId,
63298
+ epic_id: epicId,
63299
+ timestamp: new Date().toISOString(),
63300
+ event_type: "VIOLATION",
63301
+ violation_type: "coordinator_ran_tests",
63302
+ payload
63303
+ });
63304
+ return {
63305
+ isViolation: true,
63306
+ violationType: "coordinator_ran_tests",
63307
+ message: `⚠️ Coordinator should not run tests directly. Workers run tests as part of their implementation verification.`,
63308
+ payload
63309
+ };
63310
+ }
63311
+ }
63312
+ if (VIOLATION_PATTERNS.RESERVATION_TOOLS.includes(toolName)) {
63313
+ const paths = toolArgs.paths || [];
63314
+ const payload = { tool: toolName, paths };
63315
+ captureCoordinatorEvent({
63316
+ session_id: sessionId,
63317
+ epic_id: epicId,
63318
+ timestamp: new Date().toISOString(),
63319
+ event_type: "VIOLATION",
63320
+ violation_type: "coordinator_reserved_files",
63321
+ payload
63322
+ });
63323
+ return {
63324
+ isViolation: true,
63325
+ violationType: "coordinator_reserved_files",
63326
+ message: `⚠️ Coordinator should not reserve files. Workers reserve files before editing to prevent conflicts.`,
63327
+ payload
63328
+ };
63329
+ }
63330
+ if (toolName === "hive_create_epic" && checkNoSpawn) {
63331
+ const epicTitle = toolArgs.epic_title || "";
63332
+ const subtasks = toolArgs.subtasks || [];
63333
+ const payload = { epic_title: epicTitle, subtask_count: subtasks.length };
63334
+ captureCoordinatorEvent({
63335
+ session_id: sessionId,
63336
+ epic_id: epicId,
63337
+ timestamp: new Date().toISOString(),
63338
+ event_type: "VIOLATION",
63339
+ violation_type: "no_worker_spawned",
63340
+ payload
63341
+ });
63342
+ return {
63343
+ isViolation: true,
63344
+ violationType: "no_worker_spawned",
63345
+ message: `⚠️ Coordinator created decomposition without spawning workers. After hive_create_epic, use swarm_spawn_subtask for each task.`,
63346
+ payload
63347
+ };
63348
+ }
63349
+ return { isViolation: false };
63350
+ }
63351
+ var coordinatorContext = {
63352
+ isCoordinator: false
63353
+ };
63354
+ function setCoordinatorContext(ctx) {
63355
+ coordinatorContext = {
63356
+ ...coordinatorContext,
63357
+ ...ctx,
63358
+ activatedAt: ctx.isCoordinator ? Date.now() : coordinatorContext.activatedAt
63359
+ };
63360
+ }
63361
+ function getCoordinatorContext() {
63362
+ return { ...coordinatorContext };
63363
+ }
63364
+ function clearCoordinatorContext() {
63365
+ coordinatorContext = {
63366
+ isCoordinator: false
63367
+ };
63368
+ }
63369
+ function isInCoordinatorContext() {
63370
+ if (!coordinatorContext.isCoordinator) {
63371
+ return false;
63372
+ }
63373
+ const COORDINATOR_TIMEOUT_MS = 4 * 60 * 60 * 1000;
63374
+ if (coordinatorContext.activatedAt) {
63375
+ const elapsed = Date.now() - coordinatorContext.activatedAt;
63376
+ if (elapsed > COORDINATOR_TIMEOUT_MS) {
63377
+ clearCoordinatorContext();
63378
+ return false;
63379
+ }
63380
+ }
63381
+ return true;
63382
+ }
63383
+
63384
+ // src/compaction-hook.ts
63385
+ import { checkSwarmHealth as checkSwarmHealth3 } from "swarm-mail";
63386
+
63387
+ // src/logger.ts
63388
+ var import_pino = __toESM(require_pino(), 1);
63389
+ import { mkdirSync as mkdirSync5, existsSync as existsSync8 } from "node:fs";
63390
+ import { join as join11 } from "node:path";
63391
+ import { homedir as homedir3 } from "node:os";
63392
+ var DEFAULT_LOG_DIR = join11(homedir3(), ".config", "swarm-tools", "logs");
63393
+ function ensureLogDir(logDir) {
63394
+ if (!existsSync8(logDir)) {
63395
+ mkdirSync5(logDir, { recursive: true });
63396
+ }
63397
+ }
63398
+ function createTransport(filename, logDir) {
63399
+ const isPretty = process.env.SWARM_LOG_PRETTY === "1";
63400
+ if (isPretty) {
63401
+ return {
63402
+ target: "pino-pretty",
63403
+ options: {
63404
+ colorize: true,
63405
+ translateTime: "HH:MM:ss",
63406
+ ignore: "pid,hostname"
63407
+ }
63408
+ };
63409
+ }
63410
+ return {
63411
+ target: "pino-roll",
63412
+ options: {
63413
+ file: join11(logDir, filename),
63414
+ frequency: "daily",
63415
+ extension: "log",
63416
+ limit: { count: 14 },
63417
+ mkdir: true
63418
+ }
63419
+ };
63420
+ }
63421
+ var loggerCache = new Map;
63422
+ function getLogger(logDir = DEFAULT_LOG_DIR) {
63423
+ const cacheKey = `swarm:${logDir}`;
63424
+ if (loggerCache.has(cacheKey)) {
63425
+ return loggerCache.get(cacheKey);
63426
+ }
63427
+ ensureLogDir(logDir);
63428
+ const logger = import_pino.default({
63429
+ level: process.env.LOG_LEVEL || "info",
63430
+ timestamp: import_pino.default.stdTimeFunctions.isoTime
63431
+ }, import_pino.default.transport(createTransport("swarm", logDir)));
63432
+ loggerCache.set(cacheKey, logger);
63433
+ return logger;
63434
+ }
63435
+ function createChildLogger(module, logDir = DEFAULT_LOG_DIR) {
63436
+ const cacheKey = `${module}:${logDir}`;
63437
+ if (loggerCache.has(cacheKey)) {
63438
+ return loggerCache.get(cacheKey);
63439
+ }
63440
+ ensureLogDir(logDir);
63441
+ const childLogger = import_pino.default({
63442
+ level: process.env.LOG_LEVEL || "info",
63443
+ timestamp: import_pino.default.stdTimeFunctions.isoTime
63444
+ }, import_pino.default.transport(createTransport(module, logDir)));
63445
+ const logger = childLogger.child({ module });
63446
+ loggerCache.set(cacheKey, logger);
63447
+ return logger;
63448
+ }
63449
+ var logger = getLogger();
63450
+
63451
+ // src/compaction-hook.ts
63452
+ var _logger;
63453
+ function getLog() {
63454
+ if (!_logger) {
63455
+ _logger = createChildLogger("compaction");
63456
+ }
63457
+ return _logger;
63458
+ }
63459
+ var SWARM_COMPACTION_CONTEXT = `## \uD83D\uDC1D SWARM ACTIVE - You Are The COORDINATOR
63460
+
63461
+ Context was compacted but the swarm is still running. You are the **COORDINATOR**.
63462
+
63463
+ ### ⛔ NEVER DO THESE (Coordinator Anti-Patterns)
63464
+
63465
+ **CRITICAL: Coordinators NEVER do implementation work. ALWAYS spawn workers.**
63466
+
63467
+ - ❌ **NEVER** use \`edit\` or \`write\` tools - SPAWN A WORKER
63468
+ - ❌ **NEVER** run tests with \`bash\` - SPAWN A WORKER
63469
+ - ❌ **NEVER** implement features yourself - SPAWN A WORKER
63470
+ - ❌ **NEVER** "just do it myself to save time" - NO. SPAWN A WORKER.
63471
+ - ❌ **NEVER** reserve files with \`swarmmail_reserve\` - Workers reserve files
63472
+
63473
+ **If you catch yourself about to edit a file, STOP. Use \`swarm_spawn_subtask\` instead.**
63474
+
63475
+ ### ✅ ALWAYS DO THESE (Coordinator Checklist)
63476
+
63477
+ On resume, execute this checklist IN ORDER:
63478
+
63479
+ 1. \`swarm_status(epic_id="<epic>", project_key="<path>")\` - Get current state
63480
+ 2. \`swarmmail_inbox(limit=5)\` - Check for agent messages
63481
+ 3. For completed work: \`swarm_review\` → \`swarm_review_feedback\`
63482
+ 4. For open subtasks: \`swarm_spawn_subtask\` (NOT "do it yourself")
63483
+ 5. For blocked work: Investigate, unblock, reassign
63484
+
63485
+ ### Preserve in Summary
63486
+
63487
+ Extract from session context:
63488
+
63489
+ 1. **Epic & Subtasks** - IDs, titles, status, file assignments
63490
+ 2. **What's Running** - Which agents are active, what they're working on
63491
+ 3. **What's Blocked** - Blockers and what's needed to unblock
63492
+ 4. **What's Done** - Completed work and any follow-ups needed
63493
+ 5. **What's Next** - Pending subtasks ready to spawn
63494
+
63495
+ ### Summary Format
63496
+
63497
+ \`\`\`
63498
+ ## \uD83D\uDC1D Swarm State
63499
+
63500
+ **Epic:** <cell-xxx> - <title>
63501
+ **Project:** <path>
63502
+ **Progress:** X/Y subtasks complete
63503
+
63504
+ **Active:**
63505
+ - <cell-xxx>: <title> [in_progress] → <agent> working on <files>
63506
+
63507
+ **Blocked:**
63508
+ - <cell-xxx>: <title> - BLOCKED: <reason>
63509
+
63510
+ **Completed:**
63511
+ - <cell-xxx>: <title> ✓
63512
+
63513
+ **Ready to Spawn:**
63514
+ - <cell-xxx>: <title> (files: <...>)
63515
+ \`\`\`
63516
+
63517
+ ### Your Role
63518
+
63519
+ - **Spawn aggressively** - If a subtask is ready and unblocked, spawn an agent
63520
+ - **Monitor actively** - Check status, read messages, respond to blockers
63521
+ - **Review work** - Use \`swarm_review\` and \`swarm_review_feedback\` for completed work
63522
+ - **Close the loop** - When all subtasks done, verify and close the epic
63523
+
63524
+ **You are the COORDINATOR. You orchestrate. You do NOT implement. Spawn workers.**
63525
+ `;
63526
+ var SWARM_DETECTION_FALLBACK = `## \uD83D\uDC1D Swarm Detection - Check Your Context
63527
+
63528
+ **IMPORTANT:** Before summarizing, check if this session involves an active swarm.
63529
+
63530
+ Look for ANY of these patterns in the conversation:
63531
+
63532
+ ### Tool Calls (definite swarm sign)
63533
+ - \`swarm_decompose\`, \`swarm_spawn_subtask\`, \`swarm_status\`, \`swarm_complete\`
63534
+ - \`swarmmail_init\`, \`swarmmail_reserve\`, \`swarmmail_send\`
63535
+ - \`hive_create_epic\`, \`hive_start\`, \`hive_close\`
63536
+
63537
+ ### IDs and Names
63538
+ - Cell IDs: \`bd-xxx\`, \`bd-xxx.N\` (subtask format)
63539
+ - Agent names: BlueLake, RedMountain, GreenValley, etc.
63540
+ - Epic references: "epic", "subtask", "parent"
63541
+
63542
+ ### Coordination Language
63543
+ - "spawn", "worker", "coordinator"
63544
+ - "reserve", "reservation", "files"
63545
+ - "blocked", "unblock", "dependency"
63546
+ - "progress", "complete", "in_progress"
63547
+
63548
+ ### If You Find Swarm Evidence
63549
+
63550
+ Include this in your summary:
63551
+ 1. Epic ID and title
63552
+ 2. Project path
63553
+ 3. Subtask status (running/blocked/done/pending)
63554
+ 4. Any blockers or issues
63555
+ 5. What should happen next
63556
+
63557
+ **Then tell the resumed session:**
63558
+ "This is an active swarm. Check swarm_status and swarmmail_inbox immediately."
63559
+ `;
63560
+ function buildDynamicSwarmState(state) {
63561
+ const parts2 = [];
63562
+ parts2.push(`## \uD83D\uDC1D Current Swarm State
63563
+ `);
63564
+ if (state.epicId && state.epicTitle) {
63565
+ parts2.push(`**Epic:** ${state.epicId} - ${state.epicTitle}`);
63566
+ const totalSubtasks = state.subtasks.closed + state.subtasks.in_progress + state.subtasks.open + state.subtasks.blocked;
63567
+ if (totalSubtasks > 0) {
63568
+ parts2.push(`**Subtasks:**`);
63569
+ if (state.subtasks.closed > 0)
63570
+ parts2.push(` - ${state.subtasks.closed} closed`);
63571
+ if (state.subtasks.in_progress > 0)
63572
+ parts2.push(` - ${state.subtasks.in_progress} in_progress`);
63573
+ if (state.subtasks.open > 0)
63574
+ parts2.push(` - ${state.subtasks.open} open`);
63575
+ if (state.subtasks.blocked > 0)
63576
+ parts2.push(` - ${state.subtasks.blocked} blocked`);
63577
+ }
63578
+ }
63579
+ parts2.push(`**Project:** ${state.projectPath}`);
63580
+ if (state.epicId) {
63581
+ parts2.push(`
63582
+ ## \uD83C\uDFAF YOU ARE THE COORDINATOR`);
63583
+ parts2.push(``);
63584
+ parts2.push(`**Primary role:** Orchestrate workers, review their output, unblock dependencies.`);
63585
+ parts2.push(`**Spawn workers** for implementation tasks - don't do them yourself.`);
63586
+ parts2.push(``);
63587
+ parts2.push(`**RESUME STEPS:**`);
63588
+ parts2.push(`1. Check swarm status: \`swarm_status(epic_id="${state.epicId}", project_key="${state.projectPath}")\``);
63589
+ parts2.push(`2. Check inbox for worker messages: \`swarmmail_inbox(limit=5)\``);
63590
+ parts2.push(`3. For in_progress subtasks: Review worker results with \`swarm_review\``);
63591
+ parts2.push(`4. For open subtasks: Spawn workers with \`swarm_spawn_subtask\``);
63592
+ parts2.push(`5. For blocked subtasks: Investigate and unblock`);
63593
+ }
63594
+ return parts2.join(`
63595
+ `);
63596
+ }
63597
+ async function scanSessionMessages(client, sessionID, limit = 100) {
63598
+ const state = {
63599
+ subtasks: new Map
63600
+ };
63601
+ if (!client) {
63602
+ return state;
63603
+ }
63604
+ try {
63605
+ const sdkClient = client;
63606
+ const response = await sdkClient.session.messages({
63607
+ path: { id: sessionID },
63608
+ query: { limit }
63609
+ });
63610
+ const messages = response.data || [];
63611
+ for (const message of messages) {
63612
+ for (const part of message.parts) {
63613
+ if (part.type !== "tool" || part.state.status !== "completed") {
63614
+ continue;
63615
+ }
63616
+ const { tool: tool3, state: toolState } = part;
63617
+ const { input, output, time: time3 } = toolState;
63618
+ state.lastAction = {
63619
+ tool: tool3,
63620
+ args: input,
63621
+ timestamp: time3.end
63622
+ };
63623
+ switch (tool3) {
63624
+ case "hive_create_epic": {
63625
+ try {
63626
+ const parsed = JSON.parse(output);
63627
+ if (parsed.epic?.id) {
63628
+ state.epicId = parsed.epic.id;
63629
+ }
63630
+ if (input.epic_title && typeof input.epic_title === "string") {
63631
+ state.epicTitle = input.epic_title;
63632
+ }
63633
+ } catch {}
63634
+ break;
63635
+ }
63636
+ case "swarmmail_init": {
63637
+ try {
63638
+ const parsed = JSON.parse(output);
63639
+ if (parsed.agent_name) {
63640
+ state.agentName = parsed.agent_name;
63641
+ }
63642
+ if (parsed.project_key) {
63643
+ state.projectPath = parsed.project_key;
63644
+ }
63645
+ } catch {}
63646
+ break;
63647
+ }
63648
+ case "swarm_spawn_subtask": {
63649
+ const beadId = input.bead_id;
63650
+ const epicId = input.epic_id;
63651
+ const title = input.subtask_title;
63652
+ const files = input.files;
63653
+ if (beadId && title) {
63654
+ let worker;
63655
+ try {
63656
+ const parsed = JSON.parse(output);
63657
+ worker = parsed.worker;
63658
+ } catch {}
63659
+ state.subtasks.set(beadId, {
63660
+ title,
63661
+ status: "spawned",
63662
+ worker,
63663
+ files
63664
+ });
63665
+ if (epicId && !state.epicId) {
63666
+ state.epicId = epicId;
63667
+ }
63668
+ }
63669
+ break;
63670
+ }
63671
+ case "swarm_complete": {
63672
+ const beadId = input.bead_id;
63673
+ if (beadId && state.subtasks.has(beadId)) {
63674
+ const existing = state.subtasks.get(beadId);
63675
+ state.subtasks.set(beadId, {
63676
+ ...existing,
63677
+ status: "completed"
63678
+ });
63679
+ }
63680
+ break;
63681
+ }
63682
+ case "swarm_status": {
63683
+ const epicId = input.epic_id;
63684
+ if (epicId && !state.epicId) {
63685
+ state.epicId = epicId;
63686
+ }
63687
+ const projectKey = input.project_key;
63688
+ if (projectKey && !state.projectPath) {
63689
+ state.projectPath = projectKey;
63690
+ }
63691
+ break;
63692
+ }
63693
+ }
63694
+ }
63695
+ }
63696
+ } catch (error45) {
63697
+ getLog().debug({
63698
+ error: error45 instanceof Error ? error45.message : String(error45)
63699
+ }, "SDK message scanning failed");
63700
+ }
63701
+ return state;
63702
+ }
63703
+ function buildDynamicSwarmStateFromScanned(scanned, detected) {
63704
+ const parts2 = [];
63705
+ parts2.push(`## \uD83D\uDC1D Current Swarm State
63706
+ `);
63707
+ const epicId = scanned.epicId || detected.epicId;
63708
+ const epicTitle = scanned.epicTitle || detected.epicTitle;
63709
+ const projectPath = scanned.projectPath || detected.projectPath;
63710
+ if (epicId) {
63711
+ parts2.push(`**Epic:** ${epicId}${epicTitle ? ` - ${epicTitle}` : ""}`);
63712
+ }
63713
+ if (scanned.agentName) {
63714
+ parts2.push(`**Coordinator:** ${scanned.agentName}`);
63715
+ }
63716
+ parts2.push(`**Project:** ${projectPath}`);
63717
+ if (scanned.subtasks.size > 0) {
63718
+ parts2.push(`
63719
+ **Subtasks:**`);
63720
+ for (const [id, subtask] of scanned.subtasks) {
63721
+ const status = subtask.status === "completed" ? "✓" : `[${subtask.status}]`;
63722
+ const worker = subtask.worker ? ` → ${subtask.worker}` : "";
63723
+ const files = subtask.files?.length ? ` (${subtask.files.join(", ")})` : "";
63724
+ parts2.push(` - ${id}: ${subtask.title} ${status}${worker}${files}`);
63725
+ }
63726
+ } else if (detected.subtasks) {
63727
+ const total = detected.subtasks.closed + detected.subtasks.in_progress + detected.subtasks.open + detected.subtasks.blocked;
63728
+ if (total > 0) {
63729
+ parts2.push(`**Subtasks:**`);
63730
+ if (detected.subtasks.closed > 0)
63731
+ parts2.push(` - ${detected.subtasks.closed} closed`);
63732
+ if (detected.subtasks.in_progress > 0)
63733
+ parts2.push(` - ${detected.subtasks.in_progress} in_progress`);
63734
+ if (detected.subtasks.open > 0)
63735
+ parts2.push(` - ${detected.subtasks.open} open`);
63736
+ if (detected.subtasks.blocked > 0)
63737
+ parts2.push(` - ${detected.subtasks.blocked} blocked`);
63738
+ }
63739
+ }
63740
+ if (scanned.lastAction) {
63741
+ parts2.push(`
63742
+ **Last Action:** \`${scanned.lastAction.tool}\``);
63743
+ }
63744
+ if (epicId) {
63745
+ parts2.push(`
63746
+ ## \uD83C\uDFAF YOU ARE THE COORDINATOR`);
63747
+ parts2.push(``);
63748
+ parts2.push(`**Primary role:** Orchestrate workers, review their output, unblock dependencies.`);
63749
+ parts2.push(`**Spawn workers** for implementation tasks - don't do them yourself.`);
63750
+ parts2.push(``);
63751
+ parts2.push(`**RESUME STEPS:**`);
63752
+ parts2.push(`1. Check swarm status: \`swarm_status(epic_id="${epicId}", project_key="${projectPath}")\``);
63753
+ parts2.push(`2. Check inbox for worker messages: \`swarmmail_inbox(limit=5)\``);
63754
+ parts2.push(`3. For in_progress subtasks: Review worker results with \`swarm_review\``);
63755
+ parts2.push(`4. For open subtasks: Spawn workers with \`swarm_spawn_subtask\``);
63756
+ parts2.push(`5. For blocked subtasks: Investigate and unblock`);
63757
+ }
63758
+ return parts2.join(`
63759
+ `);
63760
+ }
63761
+ async function detectSwarm() {
63762
+ const reasons = [];
63763
+ let highConfidence = false;
63764
+ let mediumConfidence = false;
63765
+ let lowConfidence = false;
63766
+ let state;
63767
+ try {
63768
+ const projectKey = getHiveWorkingDirectory();
63769
+ state = {
63770
+ projectPath: projectKey,
63771
+ subtasks: {
63772
+ closed: 0,
63773
+ in_progress: 0,
63774
+ open: 0,
63775
+ blocked: 0
63776
+ }
63777
+ };
63778
+ const swarmMailStart = Date.now();
63779
+ try {
63780
+ const health = await checkSwarmHealth3(projectKey);
63781
+ const duration3 = Date.now() - swarmMailStart;
63782
+ getLog().debug({
63783
+ source: "swarm-mail",
63784
+ duration_ms: duration3,
63785
+ healthy: health.healthy,
63786
+ stats: health.stats
63787
+ }, "checked swarm-mail health");
63788
+ if (health.healthy && health.stats) {
63789
+ if (health.stats.reservations > 0) {
63790
+ highConfidence = true;
63791
+ reasons.push(`${health.stats.reservations} active file reservations`);
63792
+ }
63793
+ if (health.stats.agents > 0) {
63794
+ mediumConfidence = true;
63795
+ reasons.push(`${health.stats.agents} registered agents`);
63796
+ }
63797
+ if (health.stats.messages > 0) {
63798
+ lowConfidence = true;
63799
+ reasons.push(`${health.stats.messages} swarm messages`);
63800
+ }
63801
+ }
63802
+ } catch (error45) {
63803
+ getLog().debug({
63804
+ source: "swarm-mail",
63805
+ duration_ms: Date.now() - swarmMailStart,
63806
+ error: error45 instanceof Error ? error45.message : String(error45)
63807
+ }, "swarm-mail check failed");
63808
+ }
63809
+ const hiveStart = Date.now();
63810
+ try {
63811
+ const adapter = await getHiveAdapter(projectKey);
63812
+ const cells = await adapter.queryCells(projectKey, {});
63813
+ const duration3 = Date.now() - hiveStart;
63814
+ if (Array.isArray(cells) && cells.length > 0) {
63815
+ const inProgress = cells.filter((c) => c.status === "in_progress");
63816
+ if (inProgress.length > 0) {
63817
+ highConfidence = true;
63818
+ reasons.push(`${inProgress.length} cells in_progress`);
63819
+ }
63820
+ const subtasks = cells.filter((c) => c.status === "open" && c.parent_id);
63821
+ if (subtasks.length > 0) {
63822
+ mediumConfidence = true;
63823
+ reasons.push(`${subtasks.length} open subtasks`);
63824
+ }
63825
+ const openEpics = cells.filter((c) => c.type === "epic" && c.status !== "closed");
63826
+ if (openEpics.length > 0) {
63827
+ mediumConfidence = true;
63828
+ reasons.push(`${openEpics.length} unclosed epics`);
63829
+ const inProgressEpic = openEpics.find((c) => c.status === "in_progress");
63830
+ if (inProgressEpic && state) {
63831
+ state.epicId = inProgressEpic.id;
63832
+ state.epicTitle = inProgressEpic.title;
63833
+ const epicSubtasks = cells.filter((c) => c.parent_id === inProgressEpic.id);
63834
+ state.subtasks.closed = epicSubtasks.filter((c) => c.status === "closed").length;
63835
+ state.subtasks.in_progress = epicSubtasks.filter((c) => c.status === "in_progress").length;
63836
+ state.subtasks.open = epicSubtasks.filter((c) => c.status === "open").length;
63837
+ state.subtasks.blocked = epicSubtasks.filter((c) => c.status === "blocked").length;
63838
+ getLog().debug({
63839
+ epic_id: state.epicId,
63840
+ epic_title: state.epicTitle,
63841
+ subtasks_closed: state.subtasks.closed,
63842
+ subtasks_in_progress: state.subtasks.in_progress,
63843
+ subtasks_open: state.subtasks.open,
63844
+ subtasks_blocked: state.subtasks.blocked
63845
+ }, "captured epic state for context");
63846
+ }
63847
+ }
63848
+ const oneHourAgo = Date.now() - 60 * 60 * 1000;
63849
+ const recentCells = cells.filter((c) => c.updated_at > oneHourAgo);
63850
+ if (recentCells.length > 0) {
63851
+ mediumConfidence = true;
63852
+ reasons.push(`${recentCells.length} cells updated in last hour`);
63853
+ }
63854
+ if (cells.length > 0) {
63855
+ lowConfidence = true;
63856
+ reasons.push(`${cells.length} total cells in hive`);
63857
+ }
63858
+ getLog().debug({
63859
+ source: "hive",
63860
+ duration_ms: duration3,
63861
+ total_cells: cells.length,
63862
+ in_progress: inProgress.length,
63863
+ open_subtasks: subtasks.length,
63864
+ open_epics: openEpics.length,
63865
+ recent_updates: recentCells.length
63866
+ }, "checked hive cells");
63867
+ } else {
63868
+ getLog().debug({ source: "hive", duration_ms: duration3, total_cells: 0 }, "hive empty");
63869
+ }
63870
+ } catch (error45) {
63871
+ getLog().debug({
63872
+ source: "hive",
63873
+ duration_ms: Date.now() - hiveStart,
63874
+ error: error45 instanceof Error ? error45.message : String(error45)
63875
+ }, "hive check failed");
63876
+ }
63877
+ } catch (error45) {
63878
+ lowConfidence = true;
63879
+ reasons.push("Could not detect project, using fallback");
63880
+ getLog().debug({
63881
+ error: error45 instanceof Error ? error45.message : String(error45)
63882
+ }, "project detection failed");
63883
+ }
63884
+ let confidence;
63885
+ if (highConfidence) {
63886
+ confidence = "high";
63887
+ } else if (mediumConfidence) {
63888
+ confidence = "medium";
63889
+ } else if (lowConfidence) {
63890
+ confidence = "low";
63891
+ } else {
63892
+ confidence = "none";
63893
+ }
63894
+ const result = {
63895
+ detected: confidence !== "none",
63896
+ confidence,
63897
+ reasons,
63898
+ state
63899
+ };
63900
+ getLog().debug({
63901
+ detected: result.detected,
63902
+ confidence: result.confidence,
63903
+ reason_count: result.reasons.length,
63904
+ reasons: result.reasons,
63905
+ has_state: !!result.state
63906
+ }, "swarm detection complete");
63907
+ return result;
63908
+ }
63909
+ function createCompactionHook(client) {
63910
+ return async (input, output) => {
63911
+ const startTime = Date.now();
63912
+ getLog().info({
63913
+ session_id: input.sessionID,
63914
+ trigger: "session_compaction",
63915
+ has_sdk_client: !!client
63916
+ }, "compaction started");
63917
+ try {
63918
+ const scannedState = await scanSessionMessages(client, input.sessionID);
63919
+ const detection = await detectSwarm();
63920
+ let effectiveConfidence = detection.confidence;
63921
+ if (scannedState.epicId || scannedState.subtasks.size > 0) {
63922
+ if (effectiveConfidence === "none" || effectiveConfidence === "low") {
63923
+ effectiveConfidence = "medium";
63924
+ detection.reasons.push("swarm tool calls found in session");
63925
+ }
63926
+ if (scannedState.subtasks.size > 0) {
63927
+ effectiveConfidence = "high";
63928
+ detection.reasons.push(`${scannedState.subtasks.size} subtasks spawned`);
63929
+ }
63930
+ }
63931
+ if (effectiveConfidence === "high" || effectiveConfidence === "medium") {
63932
+ const header = `[Swarm detected: ${detection.reasons.join(", ")}]
63933
+
63934
+ `;
63935
+ let dynamicState = "";
63936
+ if (scannedState.epicId || scannedState.subtasks.size > 0) {
63937
+ dynamicState = buildDynamicSwarmStateFromScanned(scannedState, detection.state || {
63938
+ projectPath: scannedState.projectPath || process.cwd(),
63939
+ subtasks: { closed: 0, in_progress: 0, open: 0, blocked: 0 }
63940
+ }) + `
63941
+
63942
+ `;
63943
+ } else if (detection.state && detection.state.epicId) {
63944
+ dynamicState = buildDynamicSwarmState(detection.state) + `
63945
+
63946
+ `;
63947
+ }
63948
+ const contextContent = header + dynamicState + SWARM_COMPACTION_CONTEXT;
63949
+ output.context.push(contextContent);
63950
+ getLog().info({
63951
+ confidence: effectiveConfidence,
63952
+ context_length: contextContent.length,
63953
+ context_type: "full",
63954
+ reasons: detection.reasons,
63955
+ has_dynamic_state: !!dynamicState,
63956
+ epic_id: scannedState.epicId || detection.state?.epicId,
63957
+ scanned_subtasks: scannedState.subtasks.size,
63958
+ scanned_agent: scannedState.agentName
63959
+ }, "injected swarm context");
63960
+ } else if (effectiveConfidence === "low") {
63961
+ const header = `[Possible swarm: ${detection.reasons.join(", ")}]
63962
+
63963
+ `;
63964
+ const contextContent = header + SWARM_DETECTION_FALLBACK;
63965
+ output.context.push(contextContent);
63966
+ getLog().info({
63967
+ confidence: effectiveConfidence,
63968
+ context_length: contextContent.length,
63969
+ context_type: "fallback",
63970
+ reasons: detection.reasons
63971
+ }, "injected swarm context");
63972
+ } else {
63973
+ getLog().debug({
63974
+ confidence: effectiveConfidence,
63975
+ context_type: "none"
63976
+ }, "no swarm detected, skipping injection");
63977
+ }
63978
+ const duration3 = Date.now() - startTime;
63979
+ getLog().info({
63980
+ duration_ms: duration3,
63981
+ success: true,
63982
+ detected: detection.detected || scannedState.epicId !== undefined,
63983
+ confidence: effectiveConfidence,
63984
+ context_injected: output.context.length > 0
63985
+ }, "compaction complete");
63986
+ } catch (error45) {
63987
+ const duration3 = Date.now() - startTime;
63988
+ getLog().error({
63989
+ duration_ms: duration3,
63990
+ success: false,
63991
+ error: error45 instanceof Error ? error45.message : String(error45),
63992
+ stack: error45 instanceof Error ? error45.stack : undefined
63993
+ }, "compaction failed");
63994
+ }
63995
+ };
63996
+ }
63036
63997
  // src/storage.ts
63037
63998
  init_learning();
63038
63999
 
@@ -63497,353 +64458,8 @@ async function resetStorage() {
63497
64458
 
63498
64459
  // src/index.ts
63499
64460
  init_skills();
63500
-
63501
- // src/compaction-hook.ts
63502
- import { checkSwarmHealth as checkSwarmHealth3 } from "swarm-mail";
63503
-
63504
- // src/logger.ts
63505
- var import_pino = __toESM(require_pino(), 1);
63506
- import { mkdirSync as mkdirSync4, existsSync as existsSync7 } from "node:fs";
63507
- import { join as join10 } from "node:path";
63508
- import { homedir as homedir2 } from "node:os";
63509
- var DEFAULT_LOG_DIR = join10(homedir2(), ".config", "swarm-tools", "logs");
63510
- function ensureLogDir(logDir) {
63511
- if (!existsSync7(logDir)) {
63512
- mkdirSync4(logDir, { recursive: true });
63513
- }
63514
- }
63515
- function createTransport(filename, logDir) {
63516
- const isPretty = process.env.SWARM_LOG_PRETTY === "1";
63517
- if (isPretty) {
63518
- return {
63519
- target: "pino-pretty",
63520
- options: {
63521
- colorize: true,
63522
- translateTime: "HH:MM:ss",
63523
- ignore: "pid,hostname"
63524
- }
63525
- };
63526
- }
63527
- return {
63528
- target: "pino-roll",
63529
- options: {
63530
- file: join10(logDir, filename),
63531
- frequency: "daily",
63532
- extension: "log",
63533
- limit: { count: 14 },
63534
- mkdir: true
63535
- }
63536
- };
63537
- }
63538
- var loggerCache = new Map;
63539
- function getLogger(logDir = DEFAULT_LOG_DIR) {
63540
- const cacheKey = `swarm:${logDir}`;
63541
- if (loggerCache.has(cacheKey)) {
63542
- return loggerCache.get(cacheKey);
63543
- }
63544
- ensureLogDir(logDir);
63545
- const logger = import_pino.default({
63546
- level: process.env.LOG_LEVEL || "info",
63547
- timestamp: import_pino.default.stdTimeFunctions.isoTime
63548
- }, import_pino.default.transport(createTransport("swarm", logDir)));
63549
- loggerCache.set(cacheKey, logger);
63550
- return logger;
63551
- }
63552
- function createChildLogger(module, logDir = DEFAULT_LOG_DIR) {
63553
- const cacheKey = `${module}:${logDir}`;
63554
- if (loggerCache.has(cacheKey)) {
63555
- return loggerCache.get(cacheKey);
63556
- }
63557
- ensureLogDir(logDir);
63558
- const childLogger = import_pino.default({
63559
- level: process.env.LOG_LEVEL || "info",
63560
- timestamp: import_pino.default.stdTimeFunctions.isoTime
63561
- }, import_pino.default.transport(createTransport(module, logDir)));
63562
- const logger = childLogger.child({ module });
63563
- loggerCache.set(cacheKey, logger);
63564
- return logger;
63565
- }
63566
- var logger = getLogger();
63567
-
63568
- // src/compaction-hook.ts
63569
- var _logger;
63570
- function getLog() {
63571
- if (!_logger) {
63572
- _logger = createChildLogger("compaction");
63573
- }
63574
- return _logger;
63575
- }
63576
- var SWARM_COMPACTION_CONTEXT = `## \uD83D\uDC1D SWARM ACTIVE - Keep Cooking
63577
-
63578
- You are the **COORDINATOR** of an active swarm. Context was compacted but the swarm is still running.
63579
-
63580
- **YOUR JOB:** Keep orchestrating. Spawn agents. Monitor progress. Unblock work. Ship it.
63581
-
63582
- ### Preserve in Summary
63583
-
63584
- Extract from session context:
63585
-
63586
- 1. **Epic & Subtasks** - IDs, titles, status, file assignments
63587
- 2. **What's Running** - Which agents are active, what they're working on
63588
- 3. **What's Blocked** - Blockers and what's needed to unblock
63589
- 4. **What's Done** - Completed work and any follow-ups needed
63590
- 5. **What's Next** - Pending subtasks ready to spawn
63591
-
63592
- ### Summary Format
63593
-
63594
- \`\`\`
63595
- ## \uD83D\uDC1D Swarm State
63596
-
63597
- **Epic:** <bd-xxx> - <title>
63598
- **Project:** <path>
63599
- **Progress:** X/Y subtasks complete
63600
-
63601
- **Active:**
63602
- - <bd-xxx>: <title> [in_progress] → <agent> working on <files>
63603
-
63604
- **Blocked:**
63605
- - <bd-xxx>: <title> - BLOCKED: <reason>
63606
-
63607
- **Completed:**
63608
- - <bd-xxx>: <title> ✓
63609
-
63610
- **Ready to Spawn:**
63611
- - <bd-xxx>: <title> (files: <...>)
63612
- \`\`\`
63613
-
63614
- ### On Resume - IMMEDIATELY
63615
-
63616
- 1. \`swarm_status(epic_id="<epic>", project_key="<path>")\` - Get current state
63617
- 2. \`swarmmail_inbox(limit=5)\` - Check for agent messages
63618
- 3. \`swarm_review(project_key, epic_id, task_id, files_touched)\` - Review any completed work
63619
- 4. \`swarm_review_feedback(project_key, task_id, worker_id, status, issues)\` - Approve or request changes
63620
- 5. **Spawn ready subtasks** - Don't wait, fire them off
63621
- 6. **Unblock blocked work** - Resolve dependencies, reassign if needed
63622
- 7. **Collect completed work** - Close done subtasks, verify quality
63623
-
63624
- ### Keep the Swarm Cooking
63625
-
63626
- - **Spawn aggressively** - If a subtask is ready and unblocked, spawn an agent
63627
- - **Monitor actively** - Check status, read messages, respond to blockers
63628
- - **Close the loop** - When all subtasks done, verify and close the epic
63629
- - **Don't stop** - The swarm runs until the epic is closed
63630
-
63631
- **You are not waiting for instructions. You are the coordinator. Coordinate.**
63632
- `;
63633
- var SWARM_DETECTION_FALLBACK = `## \uD83D\uDC1D Swarm Detection - Check Your Context
63634
-
63635
- **IMPORTANT:** Before summarizing, check if this session involves an active swarm.
63636
-
63637
- Look for ANY of these patterns in the conversation:
63638
-
63639
- ### Tool Calls (definite swarm sign)
63640
- - \`swarm_decompose\`, \`swarm_spawn_subtask\`, \`swarm_status\`, \`swarm_complete\`
63641
- - \`swarmmail_init\`, \`swarmmail_reserve\`, \`swarmmail_send\`
63642
- - \`hive_create_epic\`, \`hive_start\`, \`hive_close\`
63643
-
63644
- ### IDs and Names
63645
- - Cell IDs: \`bd-xxx\`, \`bd-xxx.N\` (subtask format)
63646
- - Agent names: BlueLake, RedMountain, GreenValley, etc.
63647
- - Epic references: "epic", "subtask", "parent"
63648
-
63649
- ### Coordination Language
63650
- - "spawn", "worker", "coordinator"
63651
- - "reserve", "reservation", "files"
63652
- - "blocked", "unblock", "dependency"
63653
- - "progress", "complete", "in_progress"
63654
-
63655
- ### If You Find Swarm Evidence
63656
-
63657
- Include this in your summary:
63658
- 1. Epic ID and title
63659
- 2. Project path
63660
- 3. Subtask status (running/blocked/done/pending)
63661
- 4. Any blockers or issues
63662
- 5. What should happen next
63663
-
63664
- **Then tell the resumed session:**
63665
- "This is an active swarm. Check swarm_status and swarmmail_inbox immediately."
63666
- `;
63667
- async function detectSwarm() {
63668
- const reasons = [];
63669
- let highConfidence = false;
63670
- let mediumConfidence = false;
63671
- let lowConfidence = false;
63672
- try {
63673
- const projectKey = getHiveWorkingDirectory();
63674
- const swarmMailStart = Date.now();
63675
- try {
63676
- const health = await checkSwarmHealth3(projectKey);
63677
- const duration3 = Date.now() - swarmMailStart;
63678
- getLog().debug({
63679
- source: "swarm-mail",
63680
- duration_ms: duration3,
63681
- healthy: health.healthy,
63682
- stats: health.stats
63683
- }, "checked swarm-mail health");
63684
- if (health.healthy && health.stats) {
63685
- if (health.stats.reservations > 0) {
63686
- highConfidence = true;
63687
- reasons.push(`${health.stats.reservations} active file reservations`);
63688
- }
63689
- if (health.stats.agents > 0) {
63690
- mediumConfidence = true;
63691
- reasons.push(`${health.stats.agents} registered agents`);
63692
- }
63693
- if (health.stats.messages > 0) {
63694
- lowConfidence = true;
63695
- reasons.push(`${health.stats.messages} swarm messages`);
63696
- }
63697
- }
63698
- } catch (error45) {
63699
- getLog().debug({
63700
- source: "swarm-mail",
63701
- duration_ms: Date.now() - swarmMailStart,
63702
- error: error45 instanceof Error ? error45.message : String(error45)
63703
- }, "swarm-mail check failed");
63704
- }
63705
- const hiveStart = Date.now();
63706
- try {
63707
- const adapter = await getHiveAdapter(projectKey);
63708
- const cells = await adapter.queryCells(projectKey, {});
63709
- const duration3 = Date.now() - hiveStart;
63710
- if (Array.isArray(cells) && cells.length > 0) {
63711
- const inProgress = cells.filter((c) => c.status === "in_progress");
63712
- if (inProgress.length > 0) {
63713
- highConfidence = true;
63714
- reasons.push(`${inProgress.length} cells in_progress`);
63715
- }
63716
- const subtasks = cells.filter((c) => c.status === "open" && c.parent_id);
63717
- if (subtasks.length > 0) {
63718
- mediumConfidence = true;
63719
- reasons.push(`${subtasks.length} open subtasks`);
63720
- }
63721
- const openEpics = cells.filter((c) => c.type === "epic" && c.status !== "closed");
63722
- if (openEpics.length > 0) {
63723
- mediumConfidence = true;
63724
- reasons.push(`${openEpics.length} unclosed epics`);
63725
- }
63726
- const oneHourAgo = Date.now() - 60 * 60 * 1000;
63727
- const recentCells = cells.filter((c) => c.updated_at > oneHourAgo);
63728
- if (recentCells.length > 0) {
63729
- mediumConfidence = true;
63730
- reasons.push(`${recentCells.length} cells updated in last hour`);
63731
- }
63732
- if (cells.length > 0) {
63733
- lowConfidence = true;
63734
- reasons.push(`${cells.length} total cells in hive`);
63735
- }
63736
- getLog().debug({
63737
- source: "hive",
63738
- duration_ms: duration3,
63739
- total_cells: cells.length,
63740
- in_progress: inProgress.length,
63741
- open_subtasks: subtasks.length,
63742
- open_epics: openEpics.length,
63743
- recent_updates: recentCells.length
63744
- }, "checked hive cells");
63745
- } else {
63746
- getLog().debug({ source: "hive", duration_ms: duration3, total_cells: 0 }, "hive empty");
63747
- }
63748
- } catch (error45) {
63749
- getLog().debug({
63750
- source: "hive",
63751
- duration_ms: Date.now() - hiveStart,
63752
- error: error45 instanceof Error ? error45.message : String(error45)
63753
- }, "hive check failed");
63754
- }
63755
- } catch (error45) {
63756
- lowConfidence = true;
63757
- reasons.push("Could not detect project, using fallback");
63758
- getLog().debug({
63759
- error: error45 instanceof Error ? error45.message : String(error45)
63760
- }, "project detection failed");
63761
- }
63762
- let confidence;
63763
- if (highConfidence) {
63764
- confidence = "high";
63765
- } else if (mediumConfidence) {
63766
- confidence = "medium";
63767
- } else if (lowConfidence) {
63768
- confidence = "low";
63769
- } else {
63770
- confidence = "none";
63771
- }
63772
- const result = {
63773
- detected: confidence !== "none",
63774
- confidence,
63775
- reasons
63776
- };
63777
- getLog().debug({
63778
- detected: result.detected,
63779
- confidence: result.confidence,
63780
- reason_count: result.reasons.length,
63781
- reasons: result.reasons
63782
- }, "swarm detection complete");
63783
- return result;
63784
- }
63785
- function createCompactionHook() {
63786
- return async (input, output) => {
63787
- const startTime = Date.now();
63788
- getLog().info({
63789
- session_id: input.sessionID,
63790
- trigger: "session_compaction"
63791
- }, "compaction started");
63792
- try {
63793
- const detection = await detectSwarm();
63794
- if (detection.confidence === "high" || detection.confidence === "medium") {
63795
- const header = `[Swarm detected: ${detection.reasons.join(", ")}]
63796
-
63797
- `;
63798
- const contextContent = header + SWARM_COMPACTION_CONTEXT;
63799
- output.context.push(contextContent);
63800
- getLog().info({
63801
- confidence: detection.confidence,
63802
- context_length: contextContent.length,
63803
- context_type: "full",
63804
- reasons: detection.reasons
63805
- }, "injected swarm context");
63806
- } else if (detection.confidence === "low") {
63807
- const header = `[Possible swarm: ${detection.reasons.join(", ")}]
63808
-
63809
- `;
63810
- const contextContent = header + SWARM_DETECTION_FALLBACK;
63811
- output.context.push(contextContent);
63812
- getLog().info({
63813
- confidence: detection.confidence,
63814
- context_length: contextContent.length,
63815
- context_type: "fallback",
63816
- reasons: detection.reasons
63817
- }, "injected swarm context");
63818
- } else {
63819
- getLog().debug({
63820
- confidence: detection.confidence,
63821
- context_type: "none"
63822
- }, "no swarm detected, skipping injection");
63823
- }
63824
- const duration3 = Date.now() - startTime;
63825
- getLog().info({
63826
- duration_ms: duration3,
63827
- success: true,
63828
- detected: detection.detected,
63829
- confidence: detection.confidence,
63830
- context_injected: output.context.length > 0
63831
- }, "compaction complete");
63832
- } catch (error45) {
63833
- const duration3 = Date.now() - startTime;
63834
- getLog().error({
63835
- duration_ms: duration3,
63836
- success: false,
63837
- error: error45 instanceof Error ? error45.message : String(error45),
63838
- stack: error45 instanceof Error ? error45.stack : undefined
63839
- }, "compaction failed");
63840
- }
63841
- };
63842
- }
63843
-
63844
- // src/index.ts
63845
64461
  var SwarmPlugin = async (input) => {
63846
- const { $, directory } = input;
64462
+ const { $, directory, client } = input;
63847
64463
  setHiveWorkingDirectory(directory);
63848
64464
  setSkillsProjectDirectory(directory);
63849
64465
  setAgentMailProjectDirectory(directory);
@@ -63905,6 +64521,28 @@ var SwarmPlugin = async (input) => {
63905
64521
  console.warn(`[swarm-plugin] ${analysis.warning}`);
63906
64522
  }
63907
64523
  }
64524
+ if (isInCoordinatorContext()) {
64525
+ const ctx = getCoordinatorContext();
64526
+ const violation = detectCoordinatorViolation({
64527
+ sessionId: ctx.sessionId || "unknown",
64528
+ epicId: ctx.epicId || "unknown",
64529
+ toolName,
64530
+ toolArgs: output.args,
64531
+ agentContext: "coordinator"
64532
+ });
64533
+ if (violation.isViolation) {
64534
+ console.warn(`[swarm-plugin] ${violation.message}`);
64535
+ }
64536
+ }
64537
+ if (toolName === "hive_create_epic" || toolName === "swarm_decompose") {
64538
+ setCoordinatorContext({
64539
+ isCoordinator: true,
64540
+ sessionId: input2.sessionID
64541
+ });
64542
+ }
64543
+ if (toolName === "hive_create_epic" && output.args) {
64544
+ const args2 = output.args;
64545
+ }
63908
64546
  },
63909
64547
  "tool.execute.after": async (input2, output) => {
63910
64548
  const toolName = input2.tool;
@@ -63936,7 +64574,29 @@ var SwarmPlugin = async (input) => {
63936
64574
  if (toolName === "swarm_complete" && activeAgentMailState) {
63937
64575
  await releaseReservations();
63938
64576
  }
63939
- }
64577
+ if (toolName === "hive_create_epic" && output.output) {
64578
+ try {
64579
+ const result = JSON.parse(output.output);
64580
+ if (result.epic?.id) {
64581
+ setCoordinatorContext({
64582
+ isCoordinator: true,
64583
+ epicId: result.epic.id,
64584
+ sessionId: input2.sessionID
64585
+ });
64586
+ }
64587
+ } catch {}
64588
+ }
64589
+ if (toolName === "hive_close" && output.output && isInCoordinatorContext()) {
64590
+ const ctx = getCoordinatorContext();
64591
+ try {
64592
+ const result = JSON.parse(output.output);
64593
+ if (result.id === ctx.epicId) {
64594
+ clearCoordinatorContext();
64595
+ }
64596
+ } catch {}
64597
+ }
64598
+ },
64599
+ "experimental.session.compacting": createCompactionHook(client)
63940
64600
  };
63941
64601
  };
63942
64602
  var src_default = SwarmPlugin;
@@ -64084,7 +64744,6 @@ export {
64084
64744
  SwarmStatusSchema,
64085
64745
  SwarmSpawnResultSchema,
64086
64746
  SwarmRecoverySchema,
64087
- SwarmPlugin,
64088
64747
  SwarmEvaluationResultSchema,
64089
64748
  SwarmError,
64090
64749
  SwarmDirectivesSchema,