opencode-swarm-plugin 0.35.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 (52) 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 +133 -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 +747 -34
  37. package/package.json +2 -2
  38. package/src/compaction-hook.test.ts +234 -281
  39. package/src/compaction-hook.ts +221 -63
  40. package/src/eval-capture.test.ts +390 -0
  41. package/src/eval-capture.ts +168 -10
  42. package/src/index.ts +89 -2
  43. package/src/learning.integration.test.ts +0 -2
  44. package/src/planning-guardrails.test.ts +387 -2
  45. package/src/planning-guardrails.ts +289 -0
  46. package/src/plugin.ts +10 -10
  47. package/src/schemas/task.ts +0 -1
  48. package/src/swarm-decompose.ts +21 -8
  49. package/src/swarm-orchestrate.ts +44 -0
  50. package/src/swarm-prompts.ts +20 -0
  51. package/src/swarm-review.ts +41 -0
  52. package/src/swarm.integration.test.ts +0 -40
package/dist/plugin.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",
@@ -38378,7 +38378,6 @@ var TaskDecompositionSchema = exports_external.object({
38378
38378
  });
38379
38379
  var DecomposeArgsSchema = exports_external.object({
38380
38380
  task: exports_external.string().min(1),
38381
- max_subtasks: exports_external.number().int().min(1).default(5),
38382
38381
  context: exports_external.string().optional()
38383
38382
  });
38384
38383
  var SpawnedAgentSchema = exports_external.object({
@@ -41465,6 +41464,122 @@ init_swarm_strategies();
41465
41464
  init_dist();
41466
41465
  init_zod();
41467
41466
  init_swarm_strategies();
41467
+
41468
+ // src/eval-capture.ts
41469
+ init_zod();
41470
+ import * as fs from "node:fs";
41471
+ import * as os from "node:os";
41472
+ import * as path from "node:path";
41473
+ var SubtaskOutcomeSchema = exports_external.object({
41474
+ bead_id: exports_external.string(),
41475
+ title: exports_external.string(),
41476
+ planned_files: exports_external.array(exports_external.string()),
41477
+ actual_files: exports_external.array(exports_external.string()),
41478
+ duration_ms: exports_external.number().int().min(0),
41479
+ error_count: exports_external.number().int().min(0),
41480
+ retry_count: exports_external.number().int().min(0),
41481
+ success: exports_external.boolean(),
41482
+ failure_mode: exports_external.string().optional()
41483
+ });
41484
+ var EvalRecordSchema = exports_external.object({
41485
+ id: exports_external.string(),
41486
+ timestamp: exports_external.string(),
41487
+ project_path: exports_external.string(),
41488
+ task: exports_external.string(),
41489
+ context: exports_external.string().optional(),
41490
+ strategy: exports_external.enum(["file-based", "feature-based", "risk-based", "auto"]),
41491
+ subtask_count: exports_external.number().int().min(1),
41492
+ epic_title: exports_external.string(),
41493
+ epic_description: exports_external.string().optional(),
41494
+ subtasks: exports_external.array(exports_external.object({
41495
+ title: exports_external.string(),
41496
+ description: exports_external.string().optional(),
41497
+ files: exports_external.array(exports_external.string()),
41498
+ dependencies: exports_external.array(exports_external.number()).optional(),
41499
+ estimated_complexity: exports_external.number().int().min(1).max(5).optional()
41500
+ })),
41501
+ outcomes: exports_external.array(SubtaskOutcomeSchema).optional(),
41502
+ overall_success: exports_external.boolean().optional(),
41503
+ total_duration_ms: exports_external.number().int().min(0).optional(),
41504
+ total_errors: exports_external.number().int().min(0).optional(),
41505
+ human_accepted: exports_external.boolean().optional(),
41506
+ human_modified: exports_external.boolean().optional(),
41507
+ human_notes: exports_external.string().optional(),
41508
+ file_overlap_count: exports_external.number().int().min(0).optional(),
41509
+ scope_accuracy: exports_external.number().min(0).max(2).optional(),
41510
+ time_balance_ratio: exports_external.number().min(1).optional()
41511
+ });
41512
+ var CoordinatorEventSchema = exports_external.discriminatedUnion("event_type", [
41513
+ exports_external.object({
41514
+ session_id: exports_external.string(),
41515
+ epic_id: exports_external.string(),
41516
+ timestamp: exports_external.string(),
41517
+ event_type: exports_external.literal("DECISION"),
41518
+ decision_type: exports_external.enum([
41519
+ "strategy_selected",
41520
+ "worker_spawned",
41521
+ "review_completed",
41522
+ "decomposition_complete"
41523
+ ]),
41524
+ payload: exports_external.any()
41525
+ }),
41526
+ exports_external.object({
41527
+ session_id: exports_external.string(),
41528
+ epic_id: exports_external.string(),
41529
+ timestamp: exports_external.string(),
41530
+ event_type: exports_external.literal("VIOLATION"),
41531
+ violation_type: exports_external.enum([
41532
+ "coordinator_edited_file",
41533
+ "coordinator_ran_tests",
41534
+ "coordinator_reserved_files",
41535
+ "no_worker_spawned"
41536
+ ]),
41537
+ payload: exports_external.any()
41538
+ }),
41539
+ exports_external.object({
41540
+ session_id: exports_external.string(),
41541
+ epic_id: exports_external.string(),
41542
+ timestamp: exports_external.string(),
41543
+ event_type: exports_external.literal("OUTCOME"),
41544
+ outcome_type: exports_external.enum([
41545
+ "subtask_success",
41546
+ "subtask_retry",
41547
+ "subtask_failed",
41548
+ "epic_complete"
41549
+ ]),
41550
+ payload: exports_external.any()
41551
+ })
41552
+ ]);
41553
+ var CoordinatorSessionSchema = exports_external.object({
41554
+ session_id: exports_external.string(),
41555
+ epic_id: exports_external.string(),
41556
+ start_time: exports_external.string(),
41557
+ end_time: exports_external.string().optional(),
41558
+ events: exports_external.array(CoordinatorEventSchema)
41559
+ });
41560
+ var inProgressRecords = new Map;
41561
+ function getSessionDir() {
41562
+ return path.join(os.homedir(), ".config", "swarm-tools", "sessions");
41563
+ }
41564
+ function getSessionPath(sessionId) {
41565
+ return path.join(getSessionDir(), `${sessionId}.jsonl`);
41566
+ }
41567
+ function ensureSessionDir() {
41568
+ const sessionDir = getSessionDir();
41569
+ if (!fs.existsSync(sessionDir)) {
41570
+ fs.mkdirSync(sessionDir, { recursive: true });
41571
+ }
41572
+ }
41573
+ function captureCoordinatorEvent(event) {
41574
+ CoordinatorEventSchema.parse(event);
41575
+ ensureSessionDir();
41576
+ const sessionPath = getSessionPath(event.session_id);
41577
+ const line = `${JSON.stringify(event)}
41578
+ `;
41579
+ fs.appendFileSync(sessionPath, line, "utf-8");
41580
+ }
41581
+
41582
+ // src/swarm-decompose.ts
41468
41583
  var DECOMPOSITION_PROMPT = `You are decomposing a task into parallelizable subtasks for a swarm of agents.
41469
41584
 
41470
41585
  ## Task
@@ -41725,7 +41840,6 @@ var swarm_decompose = tool({
41725
41840
  description: "Generate decomposition prompt for breaking task into parallelizable subtasks. Optionally queries CASS for similar past tasks.",
41726
41841
  args: {
41727
41842
  task: tool.schema.string().min(1).describe("Task description to decompose"),
41728
- max_subtasks: tool.schema.number().int().min(1).optional().describe("Suggested max subtasks (optional - LLM decides if not specified)"),
41729
41843
  context: tool.schema.string().optional().describe("Additional context (codebase info, constraints, etc.)"),
41730
41844
  query_cass: tool.schema.boolean().optional().describe("Query CASS for similar past tasks (default: true)"),
41731
41845
  cass_limit: tool.schema.number().int().min(1).optional().describe("Max CASS results to include (default: 3)")
@@ -41760,7 +41874,7 @@ var swarm_decompose = tool({
41760
41874
  const contextSection = fullContext ? `## Additional Context
41761
41875
  ${fullContext}` : `## Additional Context
41762
41876
  (none provided)`;
41763
- const prompt = DECOMPOSITION_PROMPT.replace("{task}", args.task).replace("{max_subtasks}", (args.max_subtasks ?? 5).toString()).replace("{context_section}", contextSection);
41877
+ const prompt = DECOMPOSITION_PROMPT.replace("{task}", args.task).replace("{context_section}", contextSection);
41764
41878
  return JSON.stringify({
41765
41879
  prompt,
41766
41880
  expected_schema: "CellTree",
@@ -41856,7 +41970,6 @@ var swarm_delegate_planning = tool({
41856
41970
  args: {
41857
41971
  task: tool.schema.string().min(1).describe("The task to decompose"),
41858
41972
  context: tool.schema.string().optional().describe("Additional context to include"),
41859
- max_subtasks: tool.schema.number().int().min(1).optional().describe("Suggested max subtasks (optional - LLM decides if not specified)"),
41860
41973
  strategy: tool.schema.enum(["auto", "file-based", "feature-based", "risk-based"]).optional().default("auto").describe("Decomposition strategy (default: auto-detect)"),
41861
41974
  query_cass: tool.schema.boolean().optional().default(true).describe("Query CASS for similar past tasks (default: true)")
41862
41975
  },
@@ -41874,6 +41987,22 @@ var swarm_delegate_planning = tool({
41874
41987
  selectedStrategy = selection.strategy;
41875
41988
  strategyReasoning = selection.reasoning;
41876
41989
  }
41990
+ try {
41991
+ captureCoordinatorEvent({
41992
+ session_id: process.env.OPENCODE_SESSION_ID || "unknown",
41993
+ epic_id: "planning",
41994
+ timestamp: new Date().toISOString(),
41995
+ event_type: "DECISION",
41996
+ decision_type: "strategy_selected",
41997
+ payload: {
41998
+ strategy: selectedStrategy,
41999
+ reasoning: strategyReasoning,
42000
+ task_preview: args.task.slice(0, 100)
42001
+ }
42002
+ });
42003
+ } catch (error45) {
42004
+ console.warn("[swarm_delegate_planning] Failed to capture strategy_selected:", error45);
42005
+ }
41877
42006
  let cassContext = "";
41878
42007
  let cassResultInfo;
41879
42008
  if (args.query_cass !== false) {
@@ -41919,7 +42048,7 @@ var swarm_delegate_planning = tool({
41919
42048
  const contextSection = args.context ? `## Additional Context
41920
42049
  ${args.context}` : `## Additional Context
41921
42050
  (none provided)`;
41922
- 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());
42051
+ 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 || "");
41923
42052
  const subagentInstructions = `
41924
42053
  ## CRITICAL: Output Format
41925
42054
 
@@ -43007,11 +43136,11 @@ var qmarksTestNoExtDot = ([$0]) => {
43007
43136
  return (f) => f.length === len && f !== "." && f !== "..";
43008
43137
  };
43009
43138
  var defaultPlatform = typeof process === "object" && process ? typeof process.env === "object" && process.env && process.env.__MINIMATCH_TESTING_PLATFORM__ || process.platform : "posix";
43010
- var path = {
43139
+ var path2 = {
43011
43140
  win32: { sep: "\\" },
43012
43141
  posix: { sep: "/" }
43013
43142
  };
43014
- var sep2 = defaultPlatform === "win32" ? path.win32.sep : path.posix.sep;
43143
+ var sep2 = defaultPlatform === "win32" ? path2.win32.sep : path2.posix.sep;
43015
43144
  minimatch.sep = sep2;
43016
43145
  var GLOBSTAR = Symbol("globstar **");
43017
43146
  minimatch.GLOBSTAR = GLOBSTAR;
@@ -43656,12 +43785,12 @@ init_skills();
43656
43785
  // src/swarm-worktree.ts
43657
43786
  init_dist();
43658
43787
  init_zod();
43659
- import { join as join6 } from "node:path";
43660
- import { existsSync as existsSync5 } from "node:fs";
43788
+ import { join as join7 } from "node:path";
43789
+ import { existsSync as existsSync6 } from "node:fs";
43661
43790
  var WORKTREE_DIR = ".swarm/worktrees";
43662
43791
  function getWorktreePath(projectPath, taskId) {
43663
43792
  const safeTaskId = taskId.replace(/[^a-zA-Z0-9.-]/g, "_");
43664
- return join6(projectPath, WORKTREE_DIR, safeTaskId);
43793
+ return join7(projectPath, WORKTREE_DIR, safeTaskId);
43665
43794
  }
43666
43795
  function parseTaskIdFromPath(worktreePath) {
43667
43796
  const parts = worktreePath.split("/");
@@ -43671,18 +43800,18 @@ function parseTaskIdFromPath(worktreePath) {
43671
43800
  }
43672
43801
  return null;
43673
43802
  }
43674
- async function isGitRepo(path2) {
43675
- const result = await Bun.$`git -C ${path2} rev-parse --git-dir`.quiet().nothrow();
43803
+ async function isGitRepo(path3) {
43804
+ const result = await Bun.$`git -C ${path3} rev-parse --git-dir`.quiet().nothrow();
43676
43805
  return result.exitCode === 0;
43677
43806
  }
43678
- async function hasUncommittedChanges(path2) {
43679
- const result = await Bun.$`git -C ${path2} status --porcelain`.quiet().nothrow();
43807
+ async function hasUncommittedChanges(path3) {
43808
+ const result = await Bun.$`git -C ${path3} status --porcelain`.quiet().nothrow();
43680
43809
  if (result.exitCode !== 0)
43681
43810
  return true;
43682
43811
  return result.stdout.toString().trim().length > 0;
43683
43812
  }
43684
- async function getCurrentCommit(path2) {
43685
- const result = await Bun.$`git -C ${path2} rev-parse HEAD`.quiet().nothrow();
43813
+ async function getCurrentCommit(path3) {
43814
+ const result = await Bun.$`git -C ${path3} rev-parse HEAD`.quiet().nothrow();
43686
43815
  if (result.exitCode !== 0)
43687
43816
  return null;
43688
43817
  return result.stdout.toString().trim();
@@ -43695,7 +43824,7 @@ async function getWorktreeCommits(worktreePath, startCommit) {
43695
43824
  `).filter((c) => c.length > 0);
43696
43825
  }
43697
43826
  async function ensureWorktreeDir(projectPath) {
43698
- const worktreeDir = join6(projectPath, WORKTREE_DIR);
43827
+ const worktreeDir = join7(projectPath, WORKTREE_DIR);
43699
43828
  await Bun.$`mkdir -p ${worktreeDir}`.quiet().nothrow();
43700
43829
  }
43701
43830
  var swarm_worktree_create = tool({
@@ -43714,7 +43843,7 @@ var swarm_worktree_create = tool({
43714
43843
  return JSON.stringify(result2, null, 2);
43715
43844
  }
43716
43845
  const worktreePath = getWorktreePath(args.project_path, args.task_id);
43717
- const exists = existsSync5(worktreePath);
43846
+ const exists = existsSync6(worktreePath);
43718
43847
  if (exists) {
43719
43848
  const result2 = {
43720
43849
  success: false,
@@ -43750,7 +43879,7 @@ var swarm_worktree_merge = tool({
43750
43879
  },
43751
43880
  async execute(args) {
43752
43881
  const worktreePath = getWorktreePath(args.project_path, args.task_id);
43753
- const exists = existsSync5(worktreePath);
43882
+ const exists = existsSync6(worktreePath);
43754
43883
  if (!exists) {
43755
43884
  const result2 = {
43756
43885
  success: false,
@@ -43832,7 +43961,7 @@ var swarm_worktree_cleanup = tool({
43832
43961
  return JSON.stringify(result3, null, 2);
43833
43962
  }
43834
43963
  const output = listResult.stdout.toString();
43835
- const worktreeDir = join6(args.project_path, WORKTREE_DIR);
43964
+ const worktreeDir = join7(args.project_path, WORKTREE_DIR);
43836
43965
  const worktrees = output.split(`
43837
43966
 
43838
43967
  `).filter((block) => block.includes(worktreeDir)).map((block) => {
@@ -43860,7 +43989,7 @@ var swarm_worktree_cleanup = tool({
43860
43989
  return JSON.stringify(result2, null, 2);
43861
43990
  }
43862
43991
  const worktreePath = getWorktreePath(args.project_path, args.task_id);
43863
- const exists = existsSync5(worktreePath);
43992
+ const exists = existsSync6(worktreePath);
43864
43993
  if (!exists) {
43865
43994
  const result2 = {
43866
43995
  success: true,
@@ -43897,7 +44026,7 @@ var swarm_worktree_list = tool({
43897
44026
  }, null, 2);
43898
44027
  }
43899
44028
  const output = listResult.stdout.toString();
43900
- const worktreeDir = join6(args.project_path, WORKTREE_DIR);
44029
+ const worktreeDir = join7(args.project_path, WORKTREE_DIR);
43901
44030
  const worktrees = [];
43902
44031
  const blocks = output.split(`
43903
44032
 
@@ -43907,12 +44036,12 @@ var swarm_worktree_list = tool({
43907
44036
  const commitMatch = block.match(/^HEAD ([a-f0-9]+)$/m);
43908
44037
  const branchMatch = block.match(/^branch (.+)$/m);
43909
44038
  if (pathMatch && pathMatch[1].includes(worktreeDir)) {
43910
- const path2 = pathMatch[1];
43911
- const taskId = parseTaskIdFromPath(path2);
44039
+ const path3 = pathMatch[1];
44040
+ const taskId = parseTaskIdFromPath(path3);
43912
44041
  if (taskId) {
43913
44042
  worktrees.push({
43914
44043
  task_id: taskId,
43915
- path: path2,
44044
+ path: path3,
43916
44045
  commit: commitMatch ? commitMatch[1] : "unknown",
43917
44046
  branch: branchMatch ? branchMatch[1] : undefined
43918
44047
  });
@@ -44196,6 +44325,22 @@ var swarm_review_feedback = tool({
44196
44325
  const epicId = args.task_id.includes(".") ? args.task_id.split(".")[0] : args.task_id;
44197
44326
  if (args.status === "approved") {
44198
44327
  markReviewApproved(args.task_id);
44328
+ try {
44329
+ captureCoordinatorEvent({
44330
+ session_id: process.env.OPENCODE_SESSION_ID || "unknown",
44331
+ epic_id: epicId,
44332
+ timestamp: new Date().toISOString(),
44333
+ event_type: "DECISION",
44334
+ decision_type: "review_completed",
44335
+ payload: {
44336
+ task_id: args.task_id,
44337
+ status: "approved",
44338
+ retry_count: 0
44339
+ }
44340
+ });
44341
+ } catch (error45) {
44342
+ console.warn("[swarm_review_feedback] Failed to capture review_completed:", error45);
44343
+ }
44199
44344
  await sendSwarmMessage2({
44200
44345
  projectPath: args.project_key,
44201
44346
  fromAgent: "coordinator",
@@ -44218,6 +44363,24 @@ You may now complete the task with \`swarm_complete\`.`,
44218
44363
  }
44219
44364
  const attemptNumber = incrementAttempt(args.task_id);
44220
44365
  const remaining = MAX_REVIEW_ATTEMPTS - attemptNumber;
44366
+ try {
44367
+ captureCoordinatorEvent({
44368
+ session_id: process.env.OPENCODE_SESSION_ID || "unknown",
44369
+ epic_id: epicId,
44370
+ timestamp: new Date().toISOString(),
44371
+ event_type: "DECISION",
44372
+ decision_type: "review_completed",
44373
+ payload: {
44374
+ task_id: args.task_id,
44375
+ status: "needs_changes",
44376
+ retry_count: attemptNumber,
44377
+ remaining_attempts: remaining,
44378
+ issues_count: parsedIssues.length
44379
+ }
44380
+ });
44381
+ } catch (error45) {
44382
+ console.warn("[swarm_review_feedback] Failed to capture review_completed:", error45);
44383
+ }
44221
44384
  if (remaining <= 0) {
44222
44385
  const adapter = await getHiveAdapterSafe(args.project_key);
44223
44386
  if (adapter) {
@@ -45173,6 +45336,25 @@ Files touched: ${args.files_touched?.join(", ") || "none recorded"}`,
45173
45336
  reason: "No files_owned contract found (non-epic subtask or decomposition event missing)"
45174
45337
  }
45175
45338
  };
45339
+ try {
45340
+ const durationMs2 = args.start_time ? Date.now() - args.start_time : 0;
45341
+ captureCoordinatorEvent({
45342
+ session_id: process.env.OPENCODE_SESSION_ID || "unknown",
45343
+ epic_id: epicId2,
45344
+ timestamp: new Date().toISOString(),
45345
+ event_type: "OUTCOME",
45346
+ outcome_type: "subtask_success",
45347
+ payload: {
45348
+ bead_id: args.bead_id,
45349
+ duration_ms: durationMs2,
45350
+ files_touched: args.files_touched || [],
45351
+ verification_passed: verificationResult?.passed ?? false,
45352
+ verification_skipped: args.skip_verification ?? false
45353
+ }
45354
+ });
45355
+ } catch (error45) {
45356
+ console.warn("[swarm_complete] Failed to capture subtask_success:", error45);
45357
+ }
45176
45358
  return JSON.stringify(response, null, 2);
45177
45359
  } catch (error45) {
45178
45360
  const errorMessage = error45 instanceof Error ? error45.message : String(error45);
@@ -45236,6 +45418,24 @@ ${errorStack.slice(0, 1000)}
45236
45418
  console.error(`[swarm_complete] CRITICAL: Failed to notify coordinator of failure for ${args.bead_id}:`, mailError);
45237
45419
  console.error(`[swarm_complete] Original error:`, error45);
45238
45420
  }
45421
+ try {
45422
+ const durationMs = args.start_time ? Date.now() - args.start_time : 0;
45423
+ captureCoordinatorEvent({
45424
+ session_id: process.env.OPENCODE_SESSION_ID || "unknown",
45425
+ epic_id: epicId,
45426
+ timestamp: new Date().toISOString(),
45427
+ event_type: "OUTCOME",
45428
+ outcome_type: "subtask_failed",
45429
+ payload: {
45430
+ bead_id: args.bead_id,
45431
+ duration_ms: durationMs,
45432
+ failed_step: failedStep,
45433
+ error_message: errorMessage.slice(0, 500)
45434
+ }
45435
+ });
45436
+ } catch (captureError) {
45437
+ console.warn("[swarm_complete] Failed to capture subtask_failed:", captureError);
45438
+ }
45239
45439
  return JSON.stringify({
45240
45440
  success: false,
45241
45441
  error: `swarm_complete failed: ${errorMessage}`,
@@ -45748,7 +45948,7 @@ ${args.files_context.map((f) => `- \`${f}\``).join(`
45748
45948
  *Learned from swarm execution on ${new Date().toISOString().split("T")[0]}*`;
45749
45949
  const { getSkill: getSkill2, invalidateSkillsCache: invalidateSkillsCache2 } = await Promise.resolve().then(() => (init_skills(), exports_skills));
45750
45950
  const { mkdir: mkdir2, writeFile: writeFile2 } = await import("node:fs/promises");
45751
- const { join: join7 } = await import("node:path");
45951
+ const { join: join8 } = await import("node:path");
45752
45952
  const existing = await getSkill2(args.skill_name);
45753
45953
  if (existing) {
45754
45954
  return JSON.stringify({
@@ -45759,8 +45959,8 @@ ${args.files_context.map((f) => `- \`${f}\``).join(`
45759
45959
  suggestion: "Use skills_update to add to existing skill, or choose a different name"
45760
45960
  }, null, 2);
45761
45961
  }
45762
- const skillDir = join7(process.cwd(), ".opencode", "skills", args.skill_name);
45763
- const skillPath = join7(skillDir, "SKILL.md");
45962
+ const skillDir = join8(process.cwd(), ".opencode", "skills", args.skill_name);
45963
+ const skillPath = join8(skillDir, "SKILL.md");
45764
45964
  const frontmatter = [
45765
45965
  "---",
45766
45966
  `name: ${args.skill_name}`,
@@ -46647,6 +46847,22 @@ var swarm_spawn_subtask = tool({
46647
46847
  const selectedModel = selectWorkerModel2(subtask, config2);
46648
46848
  const filesJoined = args.files.map((f) => `"${f}"`).join(", ");
46649
46849
  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");
46850
+ try {
46851
+ captureCoordinatorEvent({
46852
+ session_id: process.env.OPENCODE_SESSION_ID || "unknown",
46853
+ epic_id: args.epic_id,
46854
+ timestamp: new Date().toISOString(),
46855
+ event_type: "DECISION",
46856
+ decision_type: "worker_spawned",
46857
+ payload: {
46858
+ bead_id: args.bead_id,
46859
+ files: args.files,
46860
+ worker_model: selectedModel
46861
+ }
46862
+ });
46863
+ } catch (error45) {
46864
+ console.warn("[swarm_spawn_subtask] Failed to capture worker_spawned:", error45);
46865
+ }
46650
46866
  return JSON.stringify({
46651
46867
  prompt,
46652
46868
  bead_id: args.bead_id,
@@ -46842,7 +47058,6 @@ var swarm_plan_prompt = tool({
46842
47058
  args: {
46843
47059
  task: tool.schema.string().min(1).describe("Task description to decompose"),
46844
47060
  strategy: tool.schema.enum(["file-based", "feature-based", "risk-based", "auto"]).optional().describe("Decomposition strategy (default: auto-detect)"),
46845
- max_subtasks: tool.schema.number().int().min(1).optional().describe("Suggested max subtasks (optional - LLM decides if not specified)"),
46846
47061
  context: tool.schema.string().optional().describe("Additional context (codebase info, constraints, etc.)"),
46847
47062
  query_cass: tool.schema.boolean().optional().describe("Query CASS for similar past tasks (default: true)"),
46848
47063
  cass_limit: tool.schema.number().int().min(1).optional().describe("Max CASS results to include (default: 3)"),
@@ -46887,7 +47102,7 @@ var swarm_plan_prompt = tool({
46887
47102
  const contextSection = args.context ? `## Additional Context
46888
47103
  ${args.context}` : `## Additional Context
46889
47104
  (none provided)`;
46890
- 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());
47105
+ const prompt = STRATEGY_DECOMPOSITION_PROMPT2.replace("{task}", args.task).replace("{strategy_guidelines}", strategyGuidelines).replace("{context_section}", contextSection).replace("{cass_history}", "").replace("{skills_context}", skillsContext || "");
46891
47106
  return JSON.stringify({
46892
47107
  prompt,
46893
47108
  strategy: {
@@ -46925,9 +47140,9 @@ var promptTools = {
46925
47140
  };
46926
47141
  // src/swarm-research.ts
46927
47142
  init_dist();
46928
- import { existsSync as existsSync6 } from "node:fs";
47143
+ import { existsSync as existsSync7 } from "node:fs";
46929
47144
  import { readFile as readFile2 } from "node:fs/promises";
46930
- import { join as join7 } from "node:path";
47145
+ import { join as join8 } from "node:path";
46931
47146
 
46932
47147
  // ../../node_modules/.bun/yaml@2.8.2/node_modules/yaml/dist/index.js
46933
47148
  var composer = require_composer();
@@ -47110,21 +47325,21 @@ async function parsePackageJson(packageJsonPath, packages) {
47110
47325
  }
47111
47326
  }
47112
47327
  async function getInstalledVersions(projectPath, packages, checkUpgrades = false) {
47113
- const npmLock = join7(projectPath, "package-lock.json");
47328
+ const npmLock = join8(projectPath, "package-lock.json");
47114
47329
  let versions2 = [];
47115
- if (existsSync6(npmLock)) {
47330
+ if (existsSync7(npmLock)) {
47116
47331
  versions2 = await parseNpmLockfile(npmLock, packages);
47117
47332
  } else {
47118
- const pnpmLock = join7(projectPath, "pnpm-lock.yaml");
47119
- if (existsSync6(pnpmLock)) {
47333
+ const pnpmLock = join8(projectPath, "pnpm-lock.yaml");
47334
+ if (existsSync7(pnpmLock)) {
47120
47335
  versions2 = await parsePnpmLockfile(pnpmLock, packages);
47121
47336
  } else {
47122
- const yarnLock = join7(projectPath, "yarn.lock");
47123
- if (existsSync6(yarnLock)) {
47337
+ const yarnLock = join8(projectPath, "yarn.lock");
47338
+ if (existsSync7(yarnLock)) {
47124
47339
  versions2 = await parseYarnLockfile(yarnLock, packages);
47125
47340
  } else {
47126
- const packageJson = join7(projectPath, "package.json");
47127
- if (existsSync6(packageJson)) {
47341
+ const packageJson = join8(projectPath, "package.json");
47342
+ if (existsSync7(packageJson)) {
47128
47343
  versions2 = await parsePackageJson(packageJson, packages);
47129
47344
  }
47130
47345
  }
@@ -49296,7 +49511,7 @@ var dedupeWith = /* @__PURE__ */ dual(2, (self, isEquivalent) => {
49296
49511
  return [];
49297
49512
  });
49298
49513
  var dedupe = (self) => dedupeWith(self, equivalence());
49299
- var join8 = /* @__PURE__ */ dual(2, (self, sep3) => fromIterable(self).join(sep3));
49514
+ var join9 = /* @__PURE__ */ dual(2, (self, sep3) => fromIterable(self).join(sep3));
49300
49515
 
49301
49516
  // ../../node_modules/.bun/effect@3.19.12/node_modules/effect/dist/esm/Number.js
49302
49517
  var Order = number5;
@@ -53837,67 +54052,67 @@ var Or = (self, that) => {
53837
54052
  });
53838
54053
  return error45;
53839
54054
  };
53840
- var InvalidData = (path2, message, options2 = {
54055
+ var InvalidData = (path3, message, options2 = {
53841
54056
  pathDelim: "."
53842
54057
  }) => {
53843
54058
  const error45 = Object.create(proto2);
53844
54059
  error45._op = OP_INVALID_DATA;
53845
- error45.path = path2;
54060
+ error45.path = path3;
53846
54061
  error45.message = message;
53847
54062
  Object.defineProperty(error45, "toString", {
53848
54063
  enumerable: false,
53849
54064
  value() {
53850
- const path3 = pipe2(this.path, join8(options2.pathDelim));
53851
- return `(Invalid data at ${path3}: "${this.message}")`;
54065
+ const path4 = pipe2(this.path, join9(options2.pathDelim));
54066
+ return `(Invalid data at ${path4}: "${this.message}")`;
53852
54067
  }
53853
54068
  });
53854
54069
  return error45;
53855
54070
  };
53856
- var MissingData = (path2, message, options2 = {
54071
+ var MissingData = (path3, message, options2 = {
53857
54072
  pathDelim: "."
53858
54073
  }) => {
53859
54074
  const error45 = Object.create(proto2);
53860
54075
  error45._op = OP_MISSING_DATA;
53861
- error45.path = path2;
54076
+ error45.path = path3;
53862
54077
  error45.message = message;
53863
54078
  Object.defineProperty(error45, "toString", {
53864
54079
  enumerable: false,
53865
54080
  value() {
53866
- const path3 = pipe2(this.path, join8(options2.pathDelim));
53867
- return `(Missing data at ${path3}: "${this.message}")`;
54081
+ const path4 = pipe2(this.path, join9(options2.pathDelim));
54082
+ return `(Missing data at ${path4}: "${this.message}")`;
53868
54083
  }
53869
54084
  });
53870
54085
  return error45;
53871
54086
  };
53872
- var SourceUnavailable = (path2, message, cause, options2 = {
54087
+ var SourceUnavailable = (path3, message, cause, options2 = {
53873
54088
  pathDelim: "."
53874
54089
  }) => {
53875
54090
  const error45 = Object.create(proto2);
53876
54091
  error45._op = OP_SOURCE_UNAVAILABLE;
53877
- error45.path = path2;
54092
+ error45.path = path3;
53878
54093
  error45.message = message;
53879
54094
  error45.cause = cause;
53880
54095
  Object.defineProperty(error45, "toString", {
53881
54096
  enumerable: false,
53882
54097
  value() {
53883
- const path3 = pipe2(this.path, join8(options2.pathDelim));
53884
- return `(Source unavailable at ${path3}: "${this.message}")`;
54098
+ const path4 = pipe2(this.path, join9(options2.pathDelim));
54099
+ return `(Source unavailable at ${path4}: "${this.message}")`;
53885
54100
  }
53886
54101
  });
53887
54102
  return error45;
53888
54103
  };
53889
- var Unsupported = (path2, message, options2 = {
54104
+ var Unsupported = (path3, message, options2 = {
53890
54105
  pathDelim: "."
53891
54106
  }) => {
53892
54107
  const error45 = Object.create(proto2);
53893
54108
  error45._op = OP_UNSUPPORTED;
53894
- error45.path = path2;
54109
+ error45.path = path3;
53895
54110
  error45.message = message;
53896
54111
  Object.defineProperty(error45, "toString", {
53897
54112
  enumerable: false,
53898
54113
  value() {
53899
- const path3 = pipe2(this.path, join8(options2.pathDelim));
53900
- return `(Unsupported operation at ${path3}: "${this.message}")`;
54114
+ const path4 = pipe2(this.path, join9(options2.pathDelim));
54115
+ return `(Unsupported operation at ${path4}: "${this.message}")`;
53901
54116
  }
53902
54117
  });
53903
54118
  return error45;
@@ -53929,9 +54144,9 @@ var prefixed = /* @__PURE__ */ dual(2, (self, prefix) => {
53929
54144
  var empty19 = {
53930
54145
  _tag: "Empty"
53931
54146
  };
53932
- var patch5 = /* @__PURE__ */ dual(2, (path2, patch6) => {
54147
+ var patch5 = /* @__PURE__ */ dual(2, (path3, patch6) => {
53933
54148
  let input = of3(patch6);
53934
- let output = path2;
54149
+ let output = path3;
53935
54150
  while (isCons(input)) {
53936
54151
  const patch7 = input.head;
53937
54152
  switch (patch7._tag) {
@@ -53998,7 +54213,7 @@ var make21 = (options2) => ({
53998
54213
  var makeFlat = (options2) => ({
53999
54214
  [FlatConfigProviderTypeId]: FlatConfigProviderTypeId,
54000
54215
  patch: options2.patch,
54001
- load: (path2, config2, split = true) => options2.load(path2, config2, split),
54216
+ load: (path3, config2, split = true) => options2.load(path3, config2, split),
54002
54217
  enumerateChildren: options2.enumerateChildren
54003
54218
  });
54004
54219
  var fromFlat = (flat) => make21({
@@ -54016,29 +54231,29 @@ var fromEnv = (options2) => {
54016
54231
  pathDelim: "_",
54017
54232
  seqDelim: ","
54018
54233
  }, options2);
54019
- const makePathString = (path2) => pipe2(path2, join8(pathDelim));
54234
+ const makePathString = (path3) => pipe2(path3, join9(pathDelim));
54020
54235
  const unmakePathString = (pathString) => pathString.split(pathDelim);
54021
54236
  const getEnv = () => typeof process !== "undefined" && ("env" in process) && typeof process.env === "object" ? process.env : {};
54022
- const load = (path2, primitive, split = true) => {
54023
- const pathString = makePathString(path2);
54237
+ const load = (path3, primitive, split = true) => {
54238
+ const pathString = makePathString(path3);
54024
54239
  const current = getEnv();
54025
54240
  const valueOpt = pathString in current ? some2(current[pathString]) : none2();
54026
- return pipe2(valueOpt, mapError(() => MissingData(path2, `Expected ${pathString} to exist in the process context`)), flatMap7((value) => parsePrimitive(value, path2, primitive, seqDelim, split)));
54241
+ return pipe2(valueOpt, mapError(() => MissingData(path3, `Expected ${pathString} to exist in the process context`)), flatMap7((value) => parsePrimitive(value, path3, primitive, seqDelim, split)));
54027
54242
  };
54028
- const enumerateChildren = (path2) => sync(() => {
54243
+ const enumerateChildren = (path3) => sync(() => {
54029
54244
  const current = getEnv();
54030
54245
  const keys3 = Object.keys(current);
54031
54246
  const keyPaths = keys3.map((value) => unmakePathString(value.toUpperCase()));
54032
54247
  const filteredKeyPaths = keyPaths.filter((keyPath) => {
54033
- for (let i = 0;i < path2.length; i++) {
54034
- const pathComponent = pipe2(path2, unsafeGet(i));
54248
+ for (let i = 0;i < path3.length; i++) {
54249
+ const pathComponent = pipe2(path3, unsafeGet(i));
54035
54250
  const currentElement = keyPath[i];
54036
54251
  if (currentElement === undefined || pathComponent !== currentElement) {
54037
54252
  return false;
54038
54253
  }
54039
54254
  }
54040
54255
  return true;
54041
- }).flatMap((keyPath) => keyPath.slice(path2.length, path2.length + 1));
54256
+ }).flatMap((keyPath) => keyPath.slice(path3.length, path3.length + 1));
54042
54257
  return fromIterable5(filteredKeyPaths);
54043
54258
  });
54044
54259
  return fromFlat(makeFlat({
@@ -54054,17 +54269,17 @@ var extend2 = (leftDef, rightDef, left3, right3) => {
54054
54269
  const rightExtension = concat(right3, rightPad);
54055
54270
  return [leftExtension, rightExtension];
54056
54271
  };
54057
- var appendConfigPath = (path2, config2) => {
54272
+ var appendConfigPath = (path3, config2) => {
54058
54273
  let op = config2;
54059
54274
  if (op._tag === "Nested") {
54060
- const out = path2.slice();
54275
+ const out = path3.slice();
54061
54276
  while (op._tag === "Nested") {
54062
54277
  out.push(op.name);
54063
54278
  op = op.config;
54064
54279
  }
54065
54280
  return out;
54066
54281
  }
54067
- return path2;
54282
+ return path3;
54068
54283
  };
54069
54284
  var fromFlatLoop = (flat, prefix, config2, split) => {
54070
54285
  const op = config2;
@@ -54140,8 +54355,8 @@ var fromFlatLoop = (flat, prefix, config2, split) => {
54140
54355
  return fail2(right3.left);
54141
54356
  }
54142
54357
  if (isRight2(left3) && isRight2(right3)) {
54143
- const path2 = pipe2(prefix, join8("."));
54144
- const fail3 = fromFlatLoopFail(prefix, path2);
54358
+ const path3 = pipe2(prefix, join9("."));
54359
+ const fail3 = fromFlatLoopFail(prefix, path3);
54145
54360
  const [lefts, rights] = extend2(fail3, fail3, pipe2(left3.right, map3(right2)), pipe2(right3.right, map3(right2)));
54146
54361
  return pipe2(lefts, zip(rights), forEachSequential(([left4, right4]) => pipe2(zip2(left4, right4), map9(([left5, right5]) => op.zip(left5, right5)))));
54147
54362
  }
@@ -54150,19 +54365,19 @@ var fromFlatLoop = (flat, prefix, config2, split) => {
54150
54365
  }
54151
54366
  }
54152
54367
  };
54153
- var fromFlatLoopFail = (prefix, path2) => (index) => left2(MissingData(prefix, `The element at index ${index} in a sequence at path "${path2}" was missing`));
54368
+ var fromFlatLoopFail = (prefix, path3) => (index) => left2(MissingData(prefix, `The element at index ${index} in a sequence at path "${path3}" was missing`));
54154
54369
  var splitPathString = (text, delim) => {
54155
54370
  const split = text.split(new RegExp(`\\s*${escape2(delim)}\\s*`));
54156
54371
  return split;
54157
54372
  };
54158
- var parsePrimitive = (text, path2, primitive, delimiter, split) => {
54373
+ var parsePrimitive = (text, path3, primitive, delimiter, split) => {
54159
54374
  if (!split) {
54160
54375
  return pipe2(primitive.parse(text), mapBoth({
54161
- onFailure: prefixed(path2),
54376
+ onFailure: prefixed(path3),
54162
54377
  onSuccess: of
54163
54378
  }));
54164
54379
  }
54165
- return pipe2(splitPathString(text, delimiter), forEachSequential((char) => primitive.parse(char.trim())), mapError(prefixed(path2)));
54380
+ return pipe2(splitPathString(text, delimiter), forEachSequential((char) => primitive.parse(char.trim())), mapError(prefixed(path3)));
54166
54381
  };
54167
54382
  var transpose = (array4) => {
54168
54383
  return Object.keys(array4[0]).map((column) => array4.map((row) => row[column]));
@@ -56314,11 +56529,11 @@ var interruptAllAs = /* @__PURE__ */ dual(2, /* @__PURE__ */ fnUntraced(function
56314
56529
  }
56315
56530
  }));
56316
56531
  var interruptAsFork = /* @__PURE__ */ dual(2, (self, fiberId2) => self.interruptAsFork(fiberId2));
56317
- var join9 = (self) => zipLeft(flatten4(self.await), self.inheritAll);
56532
+ var join10 = (self) => zipLeft(flatten4(self.await), self.inheritAll);
56318
56533
  var _never2 = {
56319
56534
  ...CommitPrototype,
56320
56535
  commit() {
56321
- return join9(this);
56536
+ return join10(this);
56322
56537
  },
56323
56538
  ...fiberProto,
56324
56539
  id: () => none4,
@@ -57565,7 +57780,7 @@ class FiberRuntime extends Class2 {
57565
57780
  this.refreshRefCache();
57566
57781
  }
57567
57782
  commit() {
57568
- return join9(this);
57783
+ return join10(this);
57569
57784
  }
57570
57785
  id() {
57571
57786
  return this._fiberId;
@@ -58580,7 +58795,7 @@ var forEachConcurrentDiscard = (self, f, batching, processAll, n) => uninterrupt
58580
58795
  next();
58581
58796
  }
58582
58797
  }));
58583
- return asVoid(onExit(flatten4(restore(join9(processingFiber))), exitMatch({
58798
+ return asVoid(onExit(flatten4(restore(join10(processingFiber))), exitMatch({
58584
58799
  onFailure: (cause2) => {
58585
58800
  onInterruptSignal();
58586
58801
  const target2 = residual.length + 1;
@@ -58902,7 +59117,7 @@ var fiberAll = (fibers) => {
58902
59117
  const _fiberAll = {
58903
59118
  ...CommitPrototype2,
58904
59119
  commit() {
58905
- return join9(this);
59120
+ return join10(this);
58906
59121
  },
58907
59122
  [FiberTypeId]: fiberVariance2,
58908
59123
  id: () => fromIterable(fibers).reduce((id, fiber) => combine3(id, fiber.id()), none4),
@@ -58955,14 +59170,14 @@ var raceWith = /* @__PURE__ */ dual(3, (self, other, options2) => raceFibersWith
58955
59170
  }
58956
59171
  })
58957
59172
  }));
58958
- var disconnect = (self) => uninterruptibleMask((restore) => fiberIdWith((fiberId2) => flatMap7(forkDaemon(restore(self)), (fiber) => pipe2(restore(join9(fiber)), onInterrupt(() => pipe2(fiber, interruptAsFork(fiberId2)))))));
59173
+ var disconnect = (self) => uninterruptibleMask((restore) => fiberIdWith((fiberId2) => flatMap7(forkDaemon(restore(self)), (fiber) => pipe2(restore(join10(fiber)), onInterrupt(() => pipe2(fiber, interruptAsFork(fiberId2)))))));
58959
59174
  var race = /* @__PURE__ */ dual(2, (self, that) => fiberIdWith((parentFiberId) => raceWith(self, that, {
58960
59175
  onSelfDone: (exit2, right3) => exitMatchEffect(exit2, {
58961
- onFailure: (cause2) => pipe2(join9(right3), mapErrorCause((cause22) => parallel(cause2, cause22))),
59176
+ onFailure: (cause2) => pipe2(join10(right3), mapErrorCause((cause22) => parallel(cause2, cause22))),
58962
59177
  onSuccess: (value) => pipe2(right3, interruptAsFiber(parentFiberId), as(value))
58963
59178
  }),
58964
59179
  onOtherDone: (exit2, left3) => exitMatchEffect(exit2, {
58965
- onFailure: (cause2) => pipe2(join9(left3), mapErrorCause((cause22) => parallel(cause22, cause2))),
59180
+ onFailure: (cause2) => pipe2(join10(left3), mapErrorCause((cause22) => parallel(cause22, cause2))),
58966
59181
  onSuccess: (value) => pipe2(left3, interruptAsFiber(parentFiberId), as(value))
58967
59182
  })
58968
59183
  })));
@@ -60116,8 +60331,8 @@ var forkIn = /* @__PURE__ */ dual(2, (self, scope2) => withFiberRuntime((parent,
60116
60331
  return succeed(fiber);
60117
60332
  }));
60118
60333
  var forkScoped = (self) => scopeWith((scope2) => forkIn(self, scope2));
60119
- var fromFiber = (fiber) => join9(fiber);
60120
- var fromFiberEffect = (fiber) => suspend(() => flatMap7(fiber, join9));
60334
+ var fromFiber = (fiber) => join10(fiber);
60335
+ var fromFiberEffect = (fiber) => suspend(() => flatMap7(fiber, join10));
60121
60336
  var memoKeySymbol = /* @__PURE__ */ Symbol.for("effect/Effect/memoizeFunction.key");
60122
60337
 
60123
60338
  class Key {
@@ -61863,14 +62078,14 @@ async function createMemoryAdapter(db) {
61863
62078
  var cachedAdapter = null;
61864
62079
  var cachedProjectPath = null;
61865
62080
  async function getMemoryAdapter(projectPath) {
61866
- const path2 = projectPath || process.cwd();
61867
- if (cachedAdapter && cachedProjectPath === path2) {
62081
+ const path3 = projectPath || process.cwd();
62082
+ if (cachedAdapter && cachedProjectPath === path3) {
61868
62083
  return cachedAdapter;
61869
62084
  }
61870
- const swarmMail = await getSwarmMailLibSQL3(path2);
62085
+ const swarmMail = await getSwarmMailLibSQL3(path3);
61871
62086
  const dbAdapter = await swarmMail.getDatabase();
61872
62087
  cachedAdapter = await createMemoryAdapter(dbAdapter);
61873
- cachedProjectPath = path2;
62088
+ cachedProjectPath = path3;
61874
62089
  return cachedAdapter;
61875
62090
  }
61876
62091
  var semantic_memory_store = tool({
@@ -62574,6 +62789,752 @@ Swarm workers can complete these ${fileModificationCount} tasks in parallel.
62574
62789
  function shouldAnalyzeTool(toolName) {
62575
62790
  return toolName === "todowrite" || toolName === "TodoWrite";
62576
62791
  }
62792
+ var VIOLATION_PATTERNS = {
62793
+ FILE_MODIFICATION_TOOLS: ["edit", "write"],
62794
+ RESERVATION_TOOLS: ["swarmmail_reserve", "agentmail_reserve"],
62795
+ TEST_EXECUTION_PATTERNS: [
62796
+ /\bbun\s+test\b/i,
62797
+ /\bnpm\s+(run\s+)?test/i,
62798
+ /\byarn\s+(run\s+)?test/i,
62799
+ /\bpnpm\s+(run\s+)?test/i,
62800
+ /\bjest\b/i,
62801
+ /\bvitest\b/i,
62802
+ /\bmocha\b/i,
62803
+ /\bava\b/i,
62804
+ /\btape\b/i,
62805
+ /\.test\.(ts|js|tsx|jsx)\b/i,
62806
+ /\.spec\.(ts|js|tsx|jsx)\b/i
62807
+ ]
62808
+ };
62809
+ function detectCoordinatorViolation(params) {
62810
+ const { sessionId, epicId, toolName, toolArgs, agentContext, checkNoSpawn = false } = params;
62811
+ if (agentContext !== "coordinator") {
62812
+ return { isViolation: false };
62813
+ }
62814
+ if (VIOLATION_PATTERNS.FILE_MODIFICATION_TOOLS.includes(toolName)) {
62815
+ const file2 = toolArgs.filePath || "";
62816
+ const payload = { tool: toolName, file: file2 };
62817
+ captureCoordinatorEvent({
62818
+ session_id: sessionId,
62819
+ epic_id: epicId,
62820
+ timestamp: new Date().toISOString(),
62821
+ event_type: "VIOLATION",
62822
+ violation_type: "coordinator_edited_file",
62823
+ payload
62824
+ });
62825
+ return {
62826
+ isViolation: true,
62827
+ violationType: "coordinator_edited_file",
62828
+ message: `⚠️ Coordinator should not edit files directly. Coordinators should spawn workers to implement changes.`,
62829
+ payload
62830
+ };
62831
+ }
62832
+ if (toolName === "bash") {
62833
+ const command = toolArgs.command || "";
62834
+ const isTestCommand = VIOLATION_PATTERNS.TEST_EXECUTION_PATTERNS.some((pattern) => pattern.test(command));
62835
+ if (isTestCommand) {
62836
+ const payload = { tool: toolName, command };
62837
+ captureCoordinatorEvent({
62838
+ session_id: sessionId,
62839
+ epic_id: epicId,
62840
+ timestamp: new Date().toISOString(),
62841
+ event_type: "VIOLATION",
62842
+ violation_type: "coordinator_ran_tests",
62843
+ payload
62844
+ });
62845
+ return {
62846
+ isViolation: true,
62847
+ violationType: "coordinator_ran_tests",
62848
+ message: `⚠️ Coordinator should not run tests directly. Workers run tests as part of their implementation verification.`,
62849
+ payload
62850
+ };
62851
+ }
62852
+ }
62853
+ if (VIOLATION_PATTERNS.RESERVATION_TOOLS.includes(toolName)) {
62854
+ const paths = toolArgs.paths || [];
62855
+ const payload = { tool: toolName, paths };
62856
+ captureCoordinatorEvent({
62857
+ session_id: sessionId,
62858
+ epic_id: epicId,
62859
+ timestamp: new Date().toISOString(),
62860
+ event_type: "VIOLATION",
62861
+ violation_type: "coordinator_reserved_files",
62862
+ payload
62863
+ });
62864
+ return {
62865
+ isViolation: true,
62866
+ violationType: "coordinator_reserved_files",
62867
+ message: `⚠️ Coordinator should not reserve files. Workers reserve files before editing to prevent conflicts.`,
62868
+ payload
62869
+ };
62870
+ }
62871
+ if (toolName === "hive_create_epic" && checkNoSpawn) {
62872
+ const epicTitle = toolArgs.epic_title || "";
62873
+ const subtasks = toolArgs.subtasks || [];
62874
+ const payload = { epic_title: epicTitle, subtask_count: subtasks.length };
62875
+ captureCoordinatorEvent({
62876
+ session_id: sessionId,
62877
+ epic_id: epicId,
62878
+ timestamp: new Date().toISOString(),
62879
+ event_type: "VIOLATION",
62880
+ violation_type: "no_worker_spawned",
62881
+ payload
62882
+ });
62883
+ return {
62884
+ isViolation: true,
62885
+ violationType: "no_worker_spawned",
62886
+ message: `⚠️ Coordinator created decomposition without spawning workers. After hive_create_epic, use swarm_spawn_subtask for each task.`,
62887
+ payload
62888
+ };
62889
+ }
62890
+ return { isViolation: false };
62891
+ }
62892
+ var coordinatorContext = {
62893
+ isCoordinator: false
62894
+ };
62895
+ function setCoordinatorContext(ctx) {
62896
+ coordinatorContext = {
62897
+ ...coordinatorContext,
62898
+ ...ctx,
62899
+ activatedAt: ctx.isCoordinator ? Date.now() : coordinatorContext.activatedAt
62900
+ };
62901
+ }
62902
+ function getCoordinatorContext() {
62903
+ return { ...coordinatorContext };
62904
+ }
62905
+ function clearCoordinatorContext() {
62906
+ coordinatorContext = {
62907
+ isCoordinator: false
62908
+ };
62909
+ }
62910
+ function isInCoordinatorContext() {
62911
+ if (!coordinatorContext.isCoordinator) {
62912
+ return false;
62913
+ }
62914
+ const COORDINATOR_TIMEOUT_MS = 4 * 60 * 60 * 1000;
62915
+ if (coordinatorContext.activatedAt) {
62916
+ const elapsed = Date.now() - coordinatorContext.activatedAt;
62917
+ if (elapsed > COORDINATOR_TIMEOUT_MS) {
62918
+ clearCoordinatorContext();
62919
+ return false;
62920
+ }
62921
+ }
62922
+ return true;
62923
+ }
62924
+
62925
+ // src/compaction-hook.ts
62926
+ import { checkSwarmHealth as checkSwarmHealth3 } from "swarm-mail";
62927
+
62928
+ // src/logger.ts
62929
+ var import_pino = __toESM(require_pino(), 1);
62930
+ import { mkdirSync as mkdirSync5, existsSync as existsSync8 } from "node:fs";
62931
+ import { join as join11 } from "node:path";
62932
+ import { homedir as homedir3 } from "node:os";
62933
+ var DEFAULT_LOG_DIR = join11(homedir3(), ".config", "swarm-tools", "logs");
62934
+ function ensureLogDir(logDir) {
62935
+ if (!existsSync8(logDir)) {
62936
+ mkdirSync5(logDir, { recursive: true });
62937
+ }
62938
+ }
62939
+ function createTransport(filename, logDir) {
62940
+ const isPretty = process.env.SWARM_LOG_PRETTY === "1";
62941
+ if (isPretty) {
62942
+ return {
62943
+ target: "pino-pretty",
62944
+ options: {
62945
+ colorize: true,
62946
+ translateTime: "HH:MM:ss",
62947
+ ignore: "pid,hostname"
62948
+ }
62949
+ };
62950
+ }
62951
+ return {
62952
+ target: "pino-roll",
62953
+ options: {
62954
+ file: join11(logDir, filename),
62955
+ frequency: "daily",
62956
+ extension: "log",
62957
+ limit: { count: 14 },
62958
+ mkdir: true
62959
+ }
62960
+ };
62961
+ }
62962
+ var loggerCache = new Map;
62963
+ function getLogger(logDir = DEFAULT_LOG_DIR) {
62964
+ const cacheKey = `swarm:${logDir}`;
62965
+ if (loggerCache.has(cacheKey)) {
62966
+ return loggerCache.get(cacheKey);
62967
+ }
62968
+ ensureLogDir(logDir);
62969
+ const logger = import_pino.default({
62970
+ level: process.env.LOG_LEVEL || "info",
62971
+ timestamp: import_pino.default.stdTimeFunctions.isoTime
62972
+ }, import_pino.default.transport(createTransport("swarm", logDir)));
62973
+ loggerCache.set(cacheKey, logger);
62974
+ return logger;
62975
+ }
62976
+ function createChildLogger(module, logDir = DEFAULT_LOG_DIR) {
62977
+ const cacheKey = `${module}:${logDir}`;
62978
+ if (loggerCache.has(cacheKey)) {
62979
+ return loggerCache.get(cacheKey);
62980
+ }
62981
+ ensureLogDir(logDir);
62982
+ const childLogger = import_pino.default({
62983
+ level: process.env.LOG_LEVEL || "info",
62984
+ timestamp: import_pino.default.stdTimeFunctions.isoTime
62985
+ }, import_pino.default.transport(createTransport(module, logDir)));
62986
+ const logger = childLogger.child({ module });
62987
+ loggerCache.set(cacheKey, logger);
62988
+ return logger;
62989
+ }
62990
+ var logger = getLogger();
62991
+
62992
+ // src/compaction-hook.ts
62993
+ var _logger;
62994
+ function getLog() {
62995
+ if (!_logger) {
62996
+ _logger = createChildLogger("compaction");
62997
+ }
62998
+ return _logger;
62999
+ }
63000
+ var SWARM_COMPACTION_CONTEXT = `## \uD83D\uDC1D SWARM ACTIVE - You Are The COORDINATOR
63001
+
63002
+ Context was compacted but the swarm is still running. You are the **COORDINATOR**.
63003
+
63004
+ ### ⛔ NEVER DO THESE (Coordinator Anti-Patterns)
63005
+
63006
+ **CRITICAL: Coordinators NEVER do implementation work. ALWAYS spawn workers.**
63007
+
63008
+ - ❌ **NEVER** use \`edit\` or \`write\` tools - SPAWN A WORKER
63009
+ - ❌ **NEVER** run tests with \`bash\` - SPAWN A WORKER
63010
+ - ❌ **NEVER** implement features yourself - SPAWN A WORKER
63011
+ - ❌ **NEVER** "just do it myself to save time" - NO. SPAWN A WORKER.
63012
+ - ❌ **NEVER** reserve files with \`swarmmail_reserve\` - Workers reserve files
63013
+
63014
+ **If you catch yourself about to edit a file, STOP. Use \`swarm_spawn_subtask\` instead.**
63015
+
63016
+ ### ✅ ALWAYS DO THESE (Coordinator Checklist)
63017
+
63018
+ On resume, execute this checklist IN ORDER:
63019
+
63020
+ 1. \`swarm_status(epic_id="<epic>", project_key="<path>")\` - Get current state
63021
+ 2. \`swarmmail_inbox(limit=5)\` - Check for agent messages
63022
+ 3. For completed work: \`swarm_review\` → \`swarm_review_feedback\`
63023
+ 4. For open subtasks: \`swarm_spawn_subtask\` (NOT "do it yourself")
63024
+ 5. For blocked work: Investigate, unblock, reassign
63025
+
63026
+ ### Preserve in Summary
63027
+
63028
+ Extract from session context:
63029
+
63030
+ 1. **Epic & Subtasks** - IDs, titles, status, file assignments
63031
+ 2. **What's Running** - Which agents are active, what they're working on
63032
+ 3. **What's Blocked** - Blockers and what's needed to unblock
63033
+ 4. **What's Done** - Completed work and any follow-ups needed
63034
+ 5. **What's Next** - Pending subtasks ready to spawn
63035
+
63036
+ ### Summary Format
63037
+
63038
+ \`\`\`
63039
+ ## \uD83D\uDC1D Swarm State
63040
+
63041
+ **Epic:** <cell-xxx> - <title>
63042
+ **Project:** <path>
63043
+ **Progress:** X/Y subtasks complete
63044
+
63045
+ **Active:**
63046
+ - <cell-xxx>: <title> [in_progress] → <agent> working on <files>
63047
+
63048
+ **Blocked:**
63049
+ - <cell-xxx>: <title> - BLOCKED: <reason>
63050
+
63051
+ **Completed:**
63052
+ - <cell-xxx>: <title> ✓
63053
+
63054
+ **Ready to Spawn:**
63055
+ - <cell-xxx>: <title> (files: <...>)
63056
+ \`\`\`
63057
+
63058
+ ### Your Role
63059
+
63060
+ - **Spawn aggressively** - If a subtask is ready and unblocked, spawn an agent
63061
+ - **Monitor actively** - Check status, read messages, respond to blockers
63062
+ - **Review work** - Use \`swarm_review\` and \`swarm_review_feedback\` for completed work
63063
+ - **Close the loop** - When all subtasks done, verify and close the epic
63064
+
63065
+ **You are the COORDINATOR. You orchestrate. You do NOT implement. Spawn workers.**
63066
+ `;
63067
+ var SWARM_DETECTION_FALLBACK = `## \uD83D\uDC1D Swarm Detection - Check Your Context
63068
+
63069
+ **IMPORTANT:** Before summarizing, check if this session involves an active swarm.
63070
+
63071
+ Look for ANY of these patterns in the conversation:
63072
+
63073
+ ### Tool Calls (definite swarm sign)
63074
+ - \`swarm_decompose\`, \`swarm_spawn_subtask\`, \`swarm_status\`, \`swarm_complete\`
63075
+ - \`swarmmail_init\`, \`swarmmail_reserve\`, \`swarmmail_send\`
63076
+ - \`hive_create_epic\`, \`hive_start\`, \`hive_close\`
63077
+
63078
+ ### IDs and Names
63079
+ - Cell IDs: \`bd-xxx\`, \`bd-xxx.N\` (subtask format)
63080
+ - Agent names: BlueLake, RedMountain, GreenValley, etc.
63081
+ - Epic references: "epic", "subtask", "parent"
63082
+
63083
+ ### Coordination Language
63084
+ - "spawn", "worker", "coordinator"
63085
+ - "reserve", "reservation", "files"
63086
+ - "blocked", "unblock", "dependency"
63087
+ - "progress", "complete", "in_progress"
63088
+
63089
+ ### If You Find Swarm Evidence
63090
+
63091
+ Include this in your summary:
63092
+ 1. Epic ID and title
63093
+ 2. Project path
63094
+ 3. Subtask status (running/blocked/done/pending)
63095
+ 4. Any blockers or issues
63096
+ 5. What should happen next
63097
+
63098
+ **Then tell the resumed session:**
63099
+ "This is an active swarm. Check swarm_status and swarmmail_inbox immediately."
63100
+ `;
63101
+ function buildDynamicSwarmState(state) {
63102
+ const parts2 = [];
63103
+ parts2.push(`## \uD83D\uDC1D Current Swarm State
63104
+ `);
63105
+ if (state.epicId && state.epicTitle) {
63106
+ parts2.push(`**Epic:** ${state.epicId} - ${state.epicTitle}`);
63107
+ const totalSubtasks = state.subtasks.closed + state.subtasks.in_progress + state.subtasks.open + state.subtasks.blocked;
63108
+ if (totalSubtasks > 0) {
63109
+ parts2.push(`**Subtasks:**`);
63110
+ if (state.subtasks.closed > 0)
63111
+ parts2.push(` - ${state.subtasks.closed} closed`);
63112
+ if (state.subtasks.in_progress > 0)
63113
+ parts2.push(` - ${state.subtasks.in_progress} in_progress`);
63114
+ if (state.subtasks.open > 0)
63115
+ parts2.push(` - ${state.subtasks.open} open`);
63116
+ if (state.subtasks.blocked > 0)
63117
+ parts2.push(` - ${state.subtasks.blocked} blocked`);
63118
+ }
63119
+ }
63120
+ parts2.push(`**Project:** ${state.projectPath}`);
63121
+ if (state.epicId) {
63122
+ parts2.push(`
63123
+ ## \uD83C\uDFAF YOU ARE THE COORDINATOR`);
63124
+ parts2.push(``);
63125
+ parts2.push(`**Primary role:** Orchestrate workers, review their output, unblock dependencies.`);
63126
+ parts2.push(`**Spawn workers** for implementation tasks - don't do them yourself.`);
63127
+ parts2.push(``);
63128
+ parts2.push(`**RESUME STEPS:**`);
63129
+ parts2.push(`1. Check swarm status: \`swarm_status(epic_id="${state.epicId}", project_key="${state.projectPath}")\``);
63130
+ parts2.push(`2. Check inbox for worker messages: \`swarmmail_inbox(limit=5)\``);
63131
+ parts2.push(`3. For in_progress subtasks: Review worker results with \`swarm_review\``);
63132
+ parts2.push(`4. For open subtasks: Spawn workers with \`swarm_spawn_subtask\``);
63133
+ parts2.push(`5. For blocked subtasks: Investigate and unblock`);
63134
+ }
63135
+ return parts2.join(`
63136
+ `);
63137
+ }
63138
+ async function scanSessionMessages(client, sessionID, limit = 100) {
63139
+ const state = {
63140
+ subtasks: new Map
63141
+ };
63142
+ if (!client) {
63143
+ return state;
63144
+ }
63145
+ try {
63146
+ const sdkClient = client;
63147
+ const response = await sdkClient.session.messages({
63148
+ path: { id: sessionID },
63149
+ query: { limit }
63150
+ });
63151
+ const messages = response.data || [];
63152
+ for (const message of messages) {
63153
+ for (const part of message.parts) {
63154
+ if (part.type !== "tool" || part.state.status !== "completed") {
63155
+ continue;
63156
+ }
63157
+ const { tool: tool3, state: toolState } = part;
63158
+ const { input, output, time: time3 } = toolState;
63159
+ state.lastAction = {
63160
+ tool: tool3,
63161
+ args: input,
63162
+ timestamp: time3.end
63163
+ };
63164
+ switch (tool3) {
63165
+ case "hive_create_epic": {
63166
+ try {
63167
+ const parsed = JSON.parse(output);
63168
+ if (parsed.epic?.id) {
63169
+ state.epicId = parsed.epic.id;
63170
+ }
63171
+ if (input.epic_title && typeof input.epic_title === "string") {
63172
+ state.epicTitle = input.epic_title;
63173
+ }
63174
+ } catch {}
63175
+ break;
63176
+ }
63177
+ case "swarmmail_init": {
63178
+ try {
63179
+ const parsed = JSON.parse(output);
63180
+ if (parsed.agent_name) {
63181
+ state.agentName = parsed.agent_name;
63182
+ }
63183
+ if (parsed.project_key) {
63184
+ state.projectPath = parsed.project_key;
63185
+ }
63186
+ } catch {}
63187
+ break;
63188
+ }
63189
+ case "swarm_spawn_subtask": {
63190
+ const beadId = input.bead_id;
63191
+ const epicId = input.epic_id;
63192
+ const title = input.subtask_title;
63193
+ const files = input.files;
63194
+ if (beadId && title) {
63195
+ let worker;
63196
+ try {
63197
+ const parsed = JSON.parse(output);
63198
+ worker = parsed.worker;
63199
+ } catch {}
63200
+ state.subtasks.set(beadId, {
63201
+ title,
63202
+ status: "spawned",
63203
+ worker,
63204
+ files
63205
+ });
63206
+ if (epicId && !state.epicId) {
63207
+ state.epicId = epicId;
63208
+ }
63209
+ }
63210
+ break;
63211
+ }
63212
+ case "swarm_complete": {
63213
+ const beadId = input.bead_id;
63214
+ if (beadId && state.subtasks.has(beadId)) {
63215
+ const existing = state.subtasks.get(beadId);
63216
+ state.subtasks.set(beadId, {
63217
+ ...existing,
63218
+ status: "completed"
63219
+ });
63220
+ }
63221
+ break;
63222
+ }
63223
+ case "swarm_status": {
63224
+ const epicId = input.epic_id;
63225
+ if (epicId && !state.epicId) {
63226
+ state.epicId = epicId;
63227
+ }
63228
+ const projectKey = input.project_key;
63229
+ if (projectKey && !state.projectPath) {
63230
+ state.projectPath = projectKey;
63231
+ }
63232
+ break;
63233
+ }
63234
+ }
63235
+ }
63236
+ }
63237
+ } catch (error45) {
63238
+ getLog().debug({
63239
+ error: error45 instanceof Error ? error45.message : String(error45)
63240
+ }, "SDK message scanning failed");
63241
+ }
63242
+ return state;
63243
+ }
63244
+ function buildDynamicSwarmStateFromScanned(scanned, detected) {
63245
+ const parts2 = [];
63246
+ parts2.push(`## \uD83D\uDC1D Current Swarm State
63247
+ `);
63248
+ const epicId = scanned.epicId || detected.epicId;
63249
+ const epicTitle = scanned.epicTitle || detected.epicTitle;
63250
+ const projectPath = scanned.projectPath || detected.projectPath;
63251
+ if (epicId) {
63252
+ parts2.push(`**Epic:** ${epicId}${epicTitle ? ` - ${epicTitle}` : ""}`);
63253
+ }
63254
+ if (scanned.agentName) {
63255
+ parts2.push(`**Coordinator:** ${scanned.agentName}`);
63256
+ }
63257
+ parts2.push(`**Project:** ${projectPath}`);
63258
+ if (scanned.subtasks.size > 0) {
63259
+ parts2.push(`
63260
+ **Subtasks:**`);
63261
+ for (const [id, subtask] of scanned.subtasks) {
63262
+ const status = subtask.status === "completed" ? "✓" : `[${subtask.status}]`;
63263
+ const worker = subtask.worker ? ` → ${subtask.worker}` : "";
63264
+ const files = subtask.files?.length ? ` (${subtask.files.join(", ")})` : "";
63265
+ parts2.push(` - ${id}: ${subtask.title} ${status}${worker}${files}`);
63266
+ }
63267
+ } else if (detected.subtasks) {
63268
+ const total = detected.subtasks.closed + detected.subtasks.in_progress + detected.subtasks.open + detected.subtasks.blocked;
63269
+ if (total > 0) {
63270
+ parts2.push(`**Subtasks:**`);
63271
+ if (detected.subtasks.closed > 0)
63272
+ parts2.push(` - ${detected.subtasks.closed} closed`);
63273
+ if (detected.subtasks.in_progress > 0)
63274
+ parts2.push(` - ${detected.subtasks.in_progress} in_progress`);
63275
+ if (detected.subtasks.open > 0)
63276
+ parts2.push(` - ${detected.subtasks.open} open`);
63277
+ if (detected.subtasks.blocked > 0)
63278
+ parts2.push(` - ${detected.subtasks.blocked} blocked`);
63279
+ }
63280
+ }
63281
+ if (scanned.lastAction) {
63282
+ parts2.push(`
63283
+ **Last Action:** \`${scanned.lastAction.tool}\``);
63284
+ }
63285
+ if (epicId) {
63286
+ parts2.push(`
63287
+ ## \uD83C\uDFAF YOU ARE THE COORDINATOR`);
63288
+ parts2.push(``);
63289
+ parts2.push(`**Primary role:** Orchestrate workers, review their output, unblock dependencies.`);
63290
+ parts2.push(`**Spawn workers** for implementation tasks - don't do them yourself.`);
63291
+ parts2.push(``);
63292
+ parts2.push(`**RESUME STEPS:**`);
63293
+ parts2.push(`1. Check swarm status: \`swarm_status(epic_id="${epicId}", project_key="${projectPath}")\``);
63294
+ parts2.push(`2. Check inbox for worker messages: \`swarmmail_inbox(limit=5)\``);
63295
+ parts2.push(`3. For in_progress subtasks: Review worker results with \`swarm_review\``);
63296
+ parts2.push(`4. For open subtasks: Spawn workers with \`swarm_spawn_subtask\``);
63297
+ parts2.push(`5. For blocked subtasks: Investigate and unblock`);
63298
+ }
63299
+ return parts2.join(`
63300
+ `);
63301
+ }
63302
+ async function detectSwarm() {
63303
+ const reasons = [];
63304
+ let highConfidence = false;
63305
+ let mediumConfidence = false;
63306
+ let lowConfidence = false;
63307
+ let state;
63308
+ try {
63309
+ const projectKey = getHiveWorkingDirectory();
63310
+ state = {
63311
+ projectPath: projectKey,
63312
+ subtasks: {
63313
+ closed: 0,
63314
+ in_progress: 0,
63315
+ open: 0,
63316
+ blocked: 0
63317
+ }
63318
+ };
63319
+ const swarmMailStart = Date.now();
63320
+ try {
63321
+ const health = await checkSwarmHealth3(projectKey);
63322
+ const duration3 = Date.now() - swarmMailStart;
63323
+ getLog().debug({
63324
+ source: "swarm-mail",
63325
+ duration_ms: duration3,
63326
+ healthy: health.healthy,
63327
+ stats: health.stats
63328
+ }, "checked swarm-mail health");
63329
+ if (health.healthy && health.stats) {
63330
+ if (health.stats.reservations > 0) {
63331
+ highConfidence = true;
63332
+ reasons.push(`${health.stats.reservations} active file reservations`);
63333
+ }
63334
+ if (health.stats.agents > 0) {
63335
+ mediumConfidence = true;
63336
+ reasons.push(`${health.stats.agents} registered agents`);
63337
+ }
63338
+ if (health.stats.messages > 0) {
63339
+ lowConfidence = true;
63340
+ reasons.push(`${health.stats.messages} swarm messages`);
63341
+ }
63342
+ }
63343
+ } catch (error45) {
63344
+ getLog().debug({
63345
+ source: "swarm-mail",
63346
+ duration_ms: Date.now() - swarmMailStart,
63347
+ error: error45 instanceof Error ? error45.message : String(error45)
63348
+ }, "swarm-mail check failed");
63349
+ }
63350
+ const hiveStart = Date.now();
63351
+ try {
63352
+ const adapter = await getHiveAdapter(projectKey);
63353
+ const cells = await adapter.queryCells(projectKey, {});
63354
+ const duration3 = Date.now() - hiveStart;
63355
+ if (Array.isArray(cells) && cells.length > 0) {
63356
+ const inProgress = cells.filter((c) => c.status === "in_progress");
63357
+ if (inProgress.length > 0) {
63358
+ highConfidence = true;
63359
+ reasons.push(`${inProgress.length} cells in_progress`);
63360
+ }
63361
+ const subtasks = cells.filter((c) => c.status === "open" && c.parent_id);
63362
+ if (subtasks.length > 0) {
63363
+ mediumConfidence = true;
63364
+ reasons.push(`${subtasks.length} open subtasks`);
63365
+ }
63366
+ const openEpics = cells.filter((c) => c.type === "epic" && c.status !== "closed");
63367
+ if (openEpics.length > 0) {
63368
+ mediumConfidence = true;
63369
+ reasons.push(`${openEpics.length} unclosed epics`);
63370
+ const inProgressEpic = openEpics.find((c) => c.status === "in_progress");
63371
+ if (inProgressEpic && state) {
63372
+ state.epicId = inProgressEpic.id;
63373
+ state.epicTitle = inProgressEpic.title;
63374
+ const epicSubtasks = cells.filter((c) => c.parent_id === inProgressEpic.id);
63375
+ state.subtasks.closed = epicSubtasks.filter((c) => c.status === "closed").length;
63376
+ state.subtasks.in_progress = epicSubtasks.filter((c) => c.status === "in_progress").length;
63377
+ state.subtasks.open = epicSubtasks.filter((c) => c.status === "open").length;
63378
+ state.subtasks.blocked = epicSubtasks.filter((c) => c.status === "blocked").length;
63379
+ getLog().debug({
63380
+ epic_id: state.epicId,
63381
+ epic_title: state.epicTitle,
63382
+ subtasks_closed: state.subtasks.closed,
63383
+ subtasks_in_progress: state.subtasks.in_progress,
63384
+ subtasks_open: state.subtasks.open,
63385
+ subtasks_blocked: state.subtasks.blocked
63386
+ }, "captured epic state for context");
63387
+ }
63388
+ }
63389
+ const oneHourAgo = Date.now() - 60 * 60 * 1000;
63390
+ const recentCells = cells.filter((c) => c.updated_at > oneHourAgo);
63391
+ if (recentCells.length > 0) {
63392
+ mediumConfidence = true;
63393
+ reasons.push(`${recentCells.length} cells updated in last hour`);
63394
+ }
63395
+ if (cells.length > 0) {
63396
+ lowConfidence = true;
63397
+ reasons.push(`${cells.length} total cells in hive`);
63398
+ }
63399
+ getLog().debug({
63400
+ source: "hive",
63401
+ duration_ms: duration3,
63402
+ total_cells: cells.length,
63403
+ in_progress: inProgress.length,
63404
+ open_subtasks: subtasks.length,
63405
+ open_epics: openEpics.length,
63406
+ recent_updates: recentCells.length
63407
+ }, "checked hive cells");
63408
+ } else {
63409
+ getLog().debug({ source: "hive", duration_ms: duration3, total_cells: 0 }, "hive empty");
63410
+ }
63411
+ } catch (error45) {
63412
+ getLog().debug({
63413
+ source: "hive",
63414
+ duration_ms: Date.now() - hiveStart,
63415
+ error: error45 instanceof Error ? error45.message : String(error45)
63416
+ }, "hive check failed");
63417
+ }
63418
+ } catch (error45) {
63419
+ lowConfidence = true;
63420
+ reasons.push("Could not detect project, using fallback");
63421
+ getLog().debug({
63422
+ error: error45 instanceof Error ? error45.message : String(error45)
63423
+ }, "project detection failed");
63424
+ }
63425
+ let confidence;
63426
+ if (highConfidence) {
63427
+ confidence = "high";
63428
+ } else if (mediumConfidence) {
63429
+ confidence = "medium";
63430
+ } else if (lowConfidence) {
63431
+ confidence = "low";
63432
+ } else {
63433
+ confidence = "none";
63434
+ }
63435
+ const result = {
63436
+ detected: confidence !== "none",
63437
+ confidence,
63438
+ reasons,
63439
+ state
63440
+ };
63441
+ getLog().debug({
63442
+ detected: result.detected,
63443
+ confidence: result.confidence,
63444
+ reason_count: result.reasons.length,
63445
+ reasons: result.reasons,
63446
+ has_state: !!result.state
63447
+ }, "swarm detection complete");
63448
+ return result;
63449
+ }
63450
+ function createCompactionHook(client) {
63451
+ return async (input, output) => {
63452
+ const startTime = Date.now();
63453
+ getLog().info({
63454
+ session_id: input.sessionID,
63455
+ trigger: "session_compaction",
63456
+ has_sdk_client: !!client
63457
+ }, "compaction started");
63458
+ try {
63459
+ const scannedState = await scanSessionMessages(client, input.sessionID);
63460
+ const detection = await detectSwarm();
63461
+ let effectiveConfidence = detection.confidence;
63462
+ if (scannedState.epicId || scannedState.subtasks.size > 0) {
63463
+ if (effectiveConfidence === "none" || effectiveConfidence === "low") {
63464
+ effectiveConfidence = "medium";
63465
+ detection.reasons.push("swarm tool calls found in session");
63466
+ }
63467
+ if (scannedState.subtasks.size > 0) {
63468
+ effectiveConfidence = "high";
63469
+ detection.reasons.push(`${scannedState.subtasks.size} subtasks spawned`);
63470
+ }
63471
+ }
63472
+ if (effectiveConfidence === "high" || effectiveConfidence === "medium") {
63473
+ const header = `[Swarm detected: ${detection.reasons.join(", ")}]
63474
+
63475
+ `;
63476
+ let dynamicState = "";
63477
+ if (scannedState.epicId || scannedState.subtasks.size > 0) {
63478
+ dynamicState = buildDynamicSwarmStateFromScanned(scannedState, detection.state || {
63479
+ projectPath: scannedState.projectPath || process.cwd(),
63480
+ subtasks: { closed: 0, in_progress: 0, open: 0, blocked: 0 }
63481
+ }) + `
63482
+
63483
+ `;
63484
+ } else if (detection.state && detection.state.epicId) {
63485
+ dynamicState = buildDynamicSwarmState(detection.state) + `
63486
+
63487
+ `;
63488
+ }
63489
+ const contextContent = header + dynamicState + SWARM_COMPACTION_CONTEXT;
63490
+ output.context.push(contextContent);
63491
+ getLog().info({
63492
+ confidence: effectiveConfidence,
63493
+ context_length: contextContent.length,
63494
+ context_type: "full",
63495
+ reasons: detection.reasons,
63496
+ has_dynamic_state: !!dynamicState,
63497
+ epic_id: scannedState.epicId || detection.state?.epicId,
63498
+ scanned_subtasks: scannedState.subtasks.size,
63499
+ scanned_agent: scannedState.agentName
63500
+ }, "injected swarm context");
63501
+ } else if (effectiveConfidence === "low") {
63502
+ const header = `[Possible swarm: ${detection.reasons.join(", ")}]
63503
+
63504
+ `;
63505
+ const contextContent = header + SWARM_DETECTION_FALLBACK;
63506
+ output.context.push(contextContent);
63507
+ getLog().info({
63508
+ confidence: effectiveConfidence,
63509
+ context_length: contextContent.length,
63510
+ context_type: "fallback",
63511
+ reasons: detection.reasons
63512
+ }, "injected swarm context");
63513
+ } else {
63514
+ getLog().debug({
63515
+ confidence: effectiveConfidence,
63516
+ context_type: "none"
63517
+ }, "no swarm detected, skipping injection");
63518
+ }
63519
+ const duration3 = Date.now() - startTime;
63520
+ getLog().info({
63521
+ duration_ms: duration3,
63522
+ success: true,
63523
+ detected: detection.detected || scannedState.epicId !== undefined,
63524
+ confidence: effectiveConfidence,
63525
+ context_injected: output.context.length > 0
63526
+ }, "compaction complete");
63527
+ } catch (error45) {
63528
+ const duration3 = Date.now() - startTime;
63529
+ getLog().error({
63530
+ duration_ms: duration3,
63531
+ success: false,
63532
+ error: error45 instanceof Error ? error45.message : String(error45),
63533
+ stack: error45 instanceof Error ? error45.stack : undefined
63534
+ }, "compaction failed");
63535
+ }
63536
+ };
63537
+ }
62577
63538
  // src/storage.ts
62578
63539
  init_learning();
62579
63540
 
@@ -62709,63 +63670,8 @@ var sessionStats = {
62709
63670
 
62710
63671
  // src/index.ts
62711
63672
  init_skills();
62712
-
62713
- // src/compaction-hook.ts
62714
- import { checkSwarmHealth as checkSwarmHealth3 } from "swarm-mail";
62715
-
62716
- // src/logger.ts
62717
- var import_pino = __toESM(require_pino(), 1);
62718
- import { mkdirSync as mkdirSync4, existsSync as existsSync7 } from "node:fs";
62719
- import { join as join10 } from "node:path";
62720
- import { homedir as homedir2 } from "node:os";
62721
- var DEFAULT_LOG_DIR = join10(homedir2(), ".config", "swarm-tools", "logs");
62722
- function ensureLogDir(logDir) {
62723
- if (!existsSync7(logDir)) {
62724
- mkdirSync4(logDir, { recursive: true });
62725
- }
62726
- }
62727
- function createTransport(filename, logDir) {
62728
- const isPretty = process.env.SWARM_LOG_PRETTY === "1";
62729
- if (isPretty) {
62730
- return {
62731
- target: "pino-pretty",
62732
- options: {
62733
- colorize: true,
62734
- translateTime: "HH:MM:ss",
62735
- ignore: "pid,hostname"
62736
- }
62737
- };
62738
- }
62739
- return {
62740
- target: "pino-roll",
62741
- options: {
62742
- file: join10(logDir, filename),
62743
- frequency: "daily",
62744
- extension: "log",
62745
- limit: { count: 14 },
62746
- mkdir: true
62747
- }
62748
- };
62749
- }
62750
- var loggerCache = new Map;
62751
- function getLogger(logDir = DEFAULT_LOG_DIR) {
62752
- const cacheKey = `swarm:${logDir}`;
62753
- if (loggerCache.has(cacheKey)) {
62754
- return loggerCache.get(cacheKey);
62755
- }
62756
- ensureLogDir(logDir);
62757
- const logger = import_pino.default({
62758
- level: process.env.LOG_LEVEL || "info",
62759
- timestamp: import_pino.default.stdTimeFunctions.isoTime
62760
- }, import_pino.default.transport(createTransport("swarm", logDir)));
62761
- loggerCache.set(cacheKey, logger);
62762
- return logger;
62763
- }
62764
- var logger = getLogger();
62765
-
62766
- // src/index.ts
62767
63673
  var SwarmPlugin = async (input) => {
62768
- const { $, directory } = input;
63674
+ const { $, directory, client } = input;
62769
63675
  setHiveWorkingDirectory(directory);
62770
63676
  setSkillsProjectDirectory(directory);
62771
63677
  setAgentMailProjectDirectory(directory);
@@ -62827,6 +63733,28 @@ var SwarmPlugin = async (input) => {
62827
63733
  console.warn(`[swarm-plugin] ${analysis.warning}`);
62828
63734
  }
62829
63735
  }
63736
+ if (isInCoordinatorContext()) {
63737
+ const ctx = getCoordinatorContext();
63738
+ const violation = detectCoordinatorViolation({
63739
+ sessionId: ctx.sessionId || "unknown",
63740
+ epicId: ctx.epicId || "unknown",
63741
+ toolName,
63742
+ toolArgs: output.args,
63743
+ agentContext: "coordinator"
63744
+ });
63745
+ if (violation.isViolation) {
63746
+ console.warn(`[swarm-plugin] ${violation.message}`);
63747
+ }
63748
+ }
63749
+ if (toolName === "hive_create_epic" || toolName === "swarm_decompose") {
63750
+ setCoordinatorContext({
63751
+ isCoordinator: true,
63752
+ sessionId: input2.sessionID
63753
+ });
63754
+ }
63755
+ if (toolName === "hive_create_epic" && output.args) {
63756
+ const args2 = output.args;
63757
+ }
62830
63758
  },
62831
63759
  "tool.execute.after": async (input2, output) => {
62832
63760
  const toolName = input2.tool;
@@ -62858,9 +63786,32 @@ var SwarmPlugin = async (input) => {
62858
63786
  if (toolName === "swarm_complete" && activeAgentMailState) {
62859
63787
  await releaseReservations();
62860
63788
  }
62861
- }
63789
+ if (toolName === "hive_create_epic" && output.output) {
63790
+ try {
63791
+ const result = JSON.parse(output.output);
63792
+ if (result.epic?.id) {
63793
+ setCoordinatorContext({
63794
+ isCoordinator: true,
63795
+ epicId: result.epic.id,
63796
+ sessionId: input2.sessionID
63797
+ });
63798
+ }
63799
+ } catch {}
63800
+ }
63801
+ if (toolName === "hive_close" && output.output && isInCoordinatorContext()) {
63802
+ const ctx = getCoordinatorContext();
63803
+ try {
63804
+ const result = JSON.parse(output.output);
63805
+ if (result.id === ctx.epicId) {
63806
+ clearCoordinatorContext();
63807
+ }
63808
+ } catch {}
63809
+ }
63810
+ },
63811
+ "experimental.session.compacting": createCompactionHook(client)
62862
63812
  };
62863
63813
  };
63814
+ var src_default = SwarmPlugin;
62864
63815
  var allTools = {
62865
63816
  ...hiveTools,
62866
63817
  ...swarmMailTools,
@@ -62873,6 +63824,9 @@ var allTools = {
62873
63824
  ...mandateTools,
62874
63825
  ...memoryTools
62875
63826
  };
63827
+
63828
+ // src/plugin.ts
63829
+ var plugin_default = src_default;
62876
63830
  export {
62877
- SwarmPlugin
63831
+ plugin_default as default
62878
63832
  };