opencode-swarm-plugin 0.56.0 → 0.57.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. package/README.md +21 -0
  2. package/claude-plugin/.claude-plugin/plugin.json +1 -4
  3. package/claude-plugin/agents/background-worker.md +1 -0
  4. package/claude-plugin/agents/coordinator.md +1 -0
  5. package/claude-plugin/agents/worker.md +1 -0
  6. package/claude-plugin/bin/swarm-mcp-server.ts +47 -8
  7. package/claude-plugin/commands/hive.md +1 -1
  8. package/claude-plugin/commands/swarm.md +5 -1
  9. package/claude-plugin/dist/agent-mail.d.ts +480 -0
  10. package/claude-plugin/dist/agent-mail.d.ts.map +1 -0
  11. package/claude-plugin/dist/anti-patterns.d.ts +257 -0
  12. package/claude-plugin/dist/anti-patterns.d.ts.map +1 -0
  13. package/claude-plugin/dist/bin/swarm.js +373128 -0
  14. package/claude-plugin/dist/cass-tools.d.ts +74 -0
  15. package/claude-plugin/dist/cass-tools.d.ts.map +1 -0
  16. package/claude-plugin/dist/claude-plugin/claude-plugin-assets.d.ts +10 -0
  17. package/claude-plugin/dist/claude-plugin/claude-plugin-assets.d.ts.map +1 -0
  18. package/claude-plugin/dist/compaction-hook.d.ts +178 -0
  19. package/claude-plugin/dist/compaction-hook.d.ts.map +1 -0
  20. package/claude-plugin/dist/compaction-observability.d.ts +173 -0
  21. package/claude-plugin/dist/compaction-observability.d.ts.map +1 -0
  22. package/claude-plugin/dist/compaction-prompt-scoring.d.ts +125 -0
  23. package/claude-plugin/dist/compaction-prompt-scoring.d.ts.map +1 -0
  24. package/claude-plugin/dist/compaction-prompt-scoring.js +139 -0
  25. package/claude-plugin/dist/contributor-tools.d.ts +42 -0
  26. package/claude-plugin/dist/contributor-tools.d.ts.map +1 -0
  27. package/claude-plugin/dist/coordinator-guard.d.ts +79 -0
  28. package/claude-plugin/dist/coordinator-guard.d.ts.map +1 -0
  29. package/claude-plugin/dist/dashboard.d.ts +82 -0
  30. package/claude-plugin/dist/dashboard.d.ts.map +1 -0
  31. package/claude-plugin/dist/decision-trace-integration.d.ts +204 -0
  32. package/claude-plugin/dist/decision-trace-integration.d.ts.map +1 -0
  33. package/claude-plugin/dist/error-enrichment.d.ts +49 -0
  34. package/claude-plugin/dist/error-enrichment.d.ts.map +1 -0
  35. package/claude-plugin/dist/eval-capture.d.ts +494 -0
  36. package/claude-plugin/dist/eval-capture.d.ts.map +1 -0
  37. package/claude-plugin/dist/eval-capture.js +12844 -0
  38. package/claude-plugin/dist/eval-gates.d.ts +84 -0
  39. package/claude-plugin/dist/eval-gates.d.ts.map +1 -0
  40. package/claude-plugin/dist/eval-history.d.ts +117 -0
  41. package/claude-plugin/dist/eval-history.d.ts.map +1 -0
  42. package/claude-plugin/dist/eval-learning.d.ts +216 -0
  43. package/claude-plugin/dist/eval-learning.d.ts.map +1 -0
  44. package/claude-plugin/dist/eval-runner.d.ts +134 -0
  45. package/claude-plugin/dist/eval-runner.d.ts.map +1 -0
  46. package/claude-plugin/dist/examples/plugin-wrapper-template.ts +3341 -0
  47. package/claude-plugin/dist/export-tools.d.ts +76 -0
  48. package/claude-plugin/dist/export-tools.d.ts.map +1 -0
  49. package/claude-plugin/dist/hive.d.ts +949 -0
  50. package/claude-plugin/dist/hive.d.ts.map +1 -0
  51. package/claude-plugin/dist/hive.js +15009 -0
  52. package/claude-plugin/dist/hivemind-tools.d.ts +479 -0
  53. package/claude-plugin/dist/hivemind-tools.d.ts.map +1 -0
  54. package/claude-plugin/dist/hooks/atomic-write.d.ts +21 -0
  55. package/claude-plugin/dist/hooks/atomic-write.d.ts.map +1 -0
  56. package/claude-plugin/dist/hooks/constants.d.ts +28 -0
  57. package/claude-plugin/dist/hooks/constants.d.ts.map +1 -0
  58. package/claude-plugin/dist/hooks/index.d.ts +16 -0
  59. package/claude-plugin/dist/hooks/index.d.ts.map +1 -0
  60. package/claude-plugin/dist/hooks/session-start.d.ts +30 -0
  61. package/claude-plugin/dist/hooks/session-start.d.ts.map +1 -0
  62. package/claude-plugin/dist/hooks/tool-complete.d.ts +54 -0
  63. package/claude-plugin/dist/hooks/tool-complete.d.ts.map +1 -0
  64. package/claude-plugin/dist/index.d.ts +2017 -0
  65. package/claude-plugin/dist/index.d.ts.map +1 -0
  66. package/claude-plugin/dist/index.js +73453 -0
  67. package/claude-plugin/dist/learning.d.ts +700 -0
  68. package/claude-plugin/dist/learning.d.ts.map +1 -0
  69. package/claude-plugin/dist/logger.d.ts +38 -0
  70. package/claude-plugin/dist/logger.d.ts.map +1 -0
  71. package/claude-plugin/dist/mandate-promotion.d.ts +93 -0
  72. package/claude-plugin/dist/mandate-promotion.d.ts.map +1 -0
  73. package/claude-plugin/dist/mandate-storage.d.ts +209 -0
  74. package/claude-plugin/dist/mandate-storage.d.ts.map +1 -0
  75. package/claude-plugin/dist/mandates.d.ts +230 -0
  76. package/claude-plugin/dist/mandates.d.ts.map +1 -0
  77. package/claude-plugin/dist/memory-tools.d.ts +281 -0
  78. package/claude-plugin/dist/memory-tools.d.ts.map +1 -0
  79. package/claude-plugin/dist/memory.d.ts +164 -0
  80. package/claude-plugin/dist/memory.d.ts.map +1 -0
  81. package/claude-plugin/dist/model-selection.d.ts +37 -0
  82. package/claude-plugin/dist/model-selection.d.ts.map +1 -0
  83. package/claude-plugin/dist/observability-health.d.ts +87 -0
  84. package/claude-plugin/dist/observability-health.d.ts.map +1 -0
  85. package/claude-plugin/dist/observability-tools.d.ts +184 -0
  86. package/claude-plugin/dist/observability-tools.d.ts.map +1 -0
  87. package/claude-plugin/dist/output-guardrails.d.ts +125 -0
  88. package/claude-plugin/dist/output-guardrails.d.ts.map +1 -0
  89. package/claude-plugin/dist/pattern-maturity.d.ts +246 -0
  90. package/claude-plugin/dist/pattern-maturity.d.ts.map +1 -0
  91. package/claude-plugin/dist/planning-guardrails.d.ts +183 -0
  92. package/claude-plugin/dist/planning-guardrails.d.ts.map +1 -0
  93. package/claude-plugin/dist/plugin.d.ts +22 -0
  94. package/claude-plugin/dist/plugin.d.ts.map +1 -0
  95. package/claude-plugin/dist/plugin.js +72295 -0
  96. package/claude-plugin/dist/post-compaction-tracker.d.ts +133 -0
  97. package/claude-plugin/dist/post-compaction-tracker.d.ts.map +1 -0
  98. package/claude-plugin/dist/query-tools.d.ts +90 -0
  99. package/claude-plugin/dist/query-tools.d.ts.map +1 -0
  100. package/claude-plugin/dist/rate-limiter.d.ts +218 -0
  101. package/claude-plugin/dist/rate-limiter.d.ts.map +1 -0
  102. package/claude-plugin/dist/regression-detection.d.ts +58 -0
  103. package/claude-plugin/dist/regression-detection.d.ts.map +1 -0
  104. package/claude-plugin/dist/replay-tools.d.ts +28 -0
  105. package/claude-plugin/dist/replay-tools.d.ts.map +1 -0
  106. package/claude-plugin/dist/repo-crawl.d.ts +146 -0
  107. package/claude-plugin/dist/repo-crawl.d.ts.map +1 -0
  108. package/claude-plugin/dist/schemas/cell-events.d.ts +1352 -0
  109. package/claude-plugin/dist/schemas/cell-events.d.ts.map +1 -0
  110. package/claude-plugin/dist/schemas/cell.d.ts +413 -0
  111. package/claude-plugin/dist/schemas/cell.d.ts.map +1 -0
  112. package/claude-plugin/dist/schemas/evaluation.d.ts +161 -0
  113. package/claude-plugin/dist/schemas/evaluation.d.ts.map +1 -0
  114. package/claude-plugin/dist/schemas/index.d.ts +46 -0
  115. package/claude-plugin/dist/schemas/index.d.ts.map +1 -0
  116. package/claude-plugin/dist/schemas/mandate.d.ts +336 -0
  117. package/claude-plugin/dist/schemas/mandate.d.ts.map +1 -0
  118. package/claude-plugin/dist/schemas/swarm-context.d.ts +131 -0
  119. package/claude-plugin/dist/schemas/swarm-context.d.ts.map +1 -0
  120. package/claude-plugin/dist/schemas/task.d.ts +189 -0
  121. package/claude-plugin/dist/schemas/task.d.ts.map +1 -0
  122. package/claude-plugin/dist/schemas/worker-handoff.d.ts +78 -0
  123. package/claude-plugin/dist/schemas/worker-handoff.d.ts.map +1 -0
  124. package/claude-plugin/dist/sessions/agent-discovery.d.ts +59 -0
  125. package/claude-plugin/dist/sessions/agent-discovery.d.ts.map +1 -0
  126. package/claude-plugin/dist/sessions/index.d.ts +10 -0
  127. package/claude-plugin/dist/sessions/index.d.ts.map +1 -0
  128. package/claude-plugin/dist/skills.d.ts +490 -0
  129. package/claude-plugin/dist/skills.d.ts.map +1 -0
  130. package/claude-plugin/dist/storage.d.ts +260 -0
  131. package/claude-plugin/dist/storage.d.ts.map +1 -0
  132. package/claude-plugin/dist/structured.d.ts +206 -0
  133. package/claude-plugin/dist/structured.d.ts.map +1 -0
  134. package/claude-plugin/dist/swarm-adversarial-review.d.ts +104 -0
  135. package/claude-plugin/dist/swarm-adversarial-review.d.ts.map +1 -0
  136. package/claude-plugin/dist/swarm-decompose.d.ts +297 -0
  137. package/claude-plugin/dist/swarm-decompose.d.ts.map +1 -0
  138. package/claude-plugin/dist/swarm-insights.d.ts +390 -0
  139. package/claude-plugin/dist/swarm-insights.d.ts.map +1 -0
  140. package/claude-plugin/dist/swarm-mail.d.ts +274 -0
  141. package/claude-plugin/dist/swarm-mail.d.ts.map +1 -0
  142. package/claude-plugin/dist/swarm-orchestrate.d.ts +924 -0
  143. package/claude-plugin/dist/swarm-orchestrate.d.ts.map +1 -0
  144. package/claude-plugin/dist/swarm-prompts.d.ts +467 -0
  145. package/claude-plugin/dist/swarm-prompts.d.ts.map +1 -0
  146. package/claude-plugin/dist/swarm-prompts.js +45283 -0
  147. package/claude-plugin/dist/swarm-research.d.ts +125 -0
  148. package/claude-plugin/dist/swarm-research.d.ts.map +1 -0
  149. package/claude-plugin/dist/swarm-review.d.ts +214 -0
  150. package/claude-plugin/dist/swarm-review.d.ts.map +1 -0
  151. package/claude-plugin/dist/swarm-signature.d.ts +106 -0
  152. package/claude-plugin/dist/swarm-signature.d.ts.map +1 -0
  153. package/claude-plugin/dist/swarm-strategies.d.ts +113 -0
  154. package/claude-plugin/dist/swarm-strategies.d.ts.map +1 -0
  155. package/claude-plugin/dist/swarm-validation.d.ts +127 -0
  156. package/claude-plugin/dist/swarm-validation.d.ts.map +1 -0
  157. package/claude-plugin/dist/swarm-worktree.d.ts +185 -0
  158. package/claude-plugin/dist/swarm-worktree.d.ts.map +1 -0
  159. package/claude-plugin/dist/swarm.d.ts +590 -0
  160. package/claude-plugin/dist/swarm.d.ts.map +1 -0
  161. package/claude-plugin/dist/tool-availability.d.ts +91 -0
  162. package/claude-plugin/dist/tool-availability.d.ts.map +1 -0
  163. package/claude-plugin/dist/utils/tree-renderer.d.ts +61 -0
  164. package/claude-plugin/dist/utils/tree-renderer.d.ts.map +1 -0
  165. package/claude-plugin/dist/validators/index.d.ts +7 -0
  166. package/claude-plugin/dist/validators/index.d.ts.map +1 -0
  167. package/claude-plugin/dist/validators/schema-validator.d.ts +58 -0
  168. package/claude-plugin/dist/validators/schema-validator.d.ts.map +1 -0
  169. package/claude-plugin/skills/always-on-guidance/SKILL.md +44 -0
  170. package/dist/agent-mail.d.ts +4 -4
  171. package/dist/agent-mail.d.ts.map +1 -1
  172. package/dist/bin/swarm.js +477 -22
  173. package/dist/claude-plugin/claude-plugin-assets.d.ts +10 -0
  174. package/dist/claude-plugin/claude-plugin-assets.d.ts.map +1 -0
  175. package/dist/compaction-hook.d.ts +1 -1
  176. package/dist/compaction-hook.d.ts.map +1 -1
  177. package/dist/index.js +375 -265
  178. package/dist/plugin.js +374 -264
  179. package/dist/skills.d.ts +15 -0
  180. package/dist/skills.d.ts.map +1 -1
  181. package/dist/swarm-mail.d.ts.map +1 -1
  182. package/dist/swarm-prompts.d.ts +4 -2
  183. package/dist/swarm-prompts.d.ts.map +1 -1
  184. package/dist/swarm-prompts.js +84 -7
  185. package/global-skills/swarm-coordination/SKILL.md +21 -20
  186. package/package.json +2 -1
package/dist/plugin.js CHANGED
@@ -26934,6 +26934,7 @@ __export(exports_skills, {
26934
26934
  invalidateSkillsCache: () => invalidateSkillsCache,
26935
26935
  getSkillsContextForSwarm: () => getSkillsContextForSwarm,
26936
26936
  getSkill: () => getSkill,
26937
+ getAlwaysOnGuidanceSkill: () => getAlwaysOnGuidanceSkill,
26937
26938
  findRelevantSkills: () => findRelevantSkills,
26938
26939
  discoverSkills: () => discoverSkills
26939
26940
  });
@@ -26949,6 +26950,44 @@ import {
26949
26950
  } from "path";
26950
26951
  import { fileURLToPath } from "url";
26951
26952
  import { getSwarmMailLibSQL as getSwarmMailLibSQL3, createEvent as createEvent2 } from "swarm-mail";
26953
+ function resolveGuidanceModel(model) {
26954
+ if (!model)
26955
+ return "unknown";
26956
+ const normalized = model.toLowerCase();
26957
+ if (normalized.includes("gpt-5.2")) {
26958
+ return "gpt-5.2-code";
26959
+ }
26960
+ if (normalized.includes("opus-4-5") || normalized.includes("opus 4.5")) {
26961
+ return "opus-4.5";
26962
+ }
26963
+ return "unknown";
26964
+ }
26965
+ function getAlwaysOnGuidanceSkill(options2) {
26966
+ const roleGuidance = ALWAYS_ON_ROLE_GUIDANCE[options2.role];
26967
+ const modelBucket = resolveGuidanceModel(options2.model);
26968
+ let modelGuidance = "";
26969
+ if (modelBucket === "gpt-5.2-code") {
26970
+ modelGuidance = `### Model-Specific Guidance
26971
+ ${GPT_5_2_GUIDANCE}`;
26972
+ } else if (modelBucket === "opus-4.5") {
26973
+ modelGuidance = `### Model-Specific Guidance
26974
+ ${OPUS_4_5_GUIDANCE}`;
26975
+ } else {
26976
+ modelGuidance = `### Model-Specific Guidance
26977
+ ${GPT_5_2_GUIDANCE}
26978
+
26979
+ ${OPUS_4_5_GUIDANCE}`;
26980
+ }
26981
+ return [
26982
+ ALWAYS_ON_GUIDANCE_HEADER,
26983
+ ALWAYS_ON_TOOL_PRIORITY,
26984
+ ALWAYS_ON_RULE_FOLLOWING,
26985
+ roleGuidance,
26986
+ modelGuidance
26987
+ ].join(`
26988
+
26989
+ `);
26990
+ }
26952
26991
  async function emitSkillLoadedEvent(data) {
26953
26992
  try {
26954
26993
  const projectPath = skillsProjectDirectory;
@@ -27348,10 +27387,38 @@ async function findRelevantSkills(taskDescription) {
27348
27387
  }
27349
27388
  return relevant;
27350
27389
  }
27351
- var import_gray_matter, skillsProjectDirectory, skillsCache = null, PROJECT_SKILL_DIRECTORIES, skills_list, skills_use, skills_execute, skills_read, DEFAULT_SKILLS_DIR = ".opencode/skill", skills_create, skills_update, skills_delete, skills_add_script, skills_init, skillsTools;
27390
+ var import_gray_matter, ALWAYS_ON_GUIDANCE_HEADER = "## Always-On Guidance Skill", ALWAYS_ON_TOOL_PRIORITY = `### Tool Priority Order
27391
+ 1. Swarm plugin tools (\`hive_*\`, \`swarm_*\`, \`swarmmail_*\`, \`structured_*\`)
27392
+ 2. \`Read\`/\`Edit\` for file operations
27393
+ 3. \`ast-grep\` for structural search
27394
+ 4. \`Glob\`/\`Grep\` for discovery
27395
+ 5. \`Task\` subagents for exploration
27396
+ 6. \`Bash\` only for system commands
27397
+
27398
+ **Never use Bash for file read/write/edit/search.**`, ALWAYS_ON_RULE_FOLLOWING = `### Rule-Following Guardrails
27399
+ - Follow explicit tool constraints and approval modes
27400
+ - Do not invent tool output or files; ask when unsure
27401
+ - Keep changes scoped to assigned files and requirements`, ALWAYS_ON_ROLE_GUIDANCE, GPT_5_2_GUIDANCE = `#### GPT-5.2-code (Strict)
27402
+ - Follow instructions literally and exactly
27403
+ - Enforce tool priority order; fail closed if a tool is missing
27404
+ - Read before Edit; no speculative changes or output`, OPUS_4_5_GUIDANCE = `#### Opus 4.5 (Concise)
27405
+ - Be concise and deliberate while obeying mandates
27406
+ - Follow tool priorities without shortcuts
27407
+ - Prefer direct answers over speculation`, skillsProjectDirectory, skillsCache = null, PROJECT_SKILL_DIRECTORIES, skills_list, skills_use, skills_execute, skills_read, DEFAULT_SKILLS_DIR = ".opencode/skill", skills_create, skills_update, skills_delete, skills_add_script, skills_init, skillsTools;
27352
27408
  var init_skills = __esm(() => {
27353
27409
  init_dist();
27354
27410
  import_gray_matter = __toESM(require_gray_matter(), 1);
27411
+ ALWAYS_ON_ROLE_GUIDANCE = {
27412
+ coordinator: `### Coordinator Enforcement
27413
+ - Coordinator role: orchestrate, decompose, spawn workers
27414
+ - **Never** edit files or reserve locks directly
27415
+ - Coordinator override: use \`swarmmail_release_all\` only for stale/orphaned reservations (announce in Swarm Mail)
27416
+ - Review work with \`swarm_review\` before accepting`,
27417
+ worker: `### Worker Enforcement
27418
+ - Worker role: implement changes within reserved files
27419
+ - Reserve files before edits and follow TDD (RED → GREEN → REFACTOR)
27420
+ - Complete with \`swarm_complete\`, not \`hive_close\``
27421
+ };
27355
27422
  skillsProjectDirectory = process.cwd();
27356
27423
  PROJECT_SKILL_DIRECTORIES = [
27357
27424
  ".opencode/skill",
@@ -60206,8 +60273,8 @@ import {
60206
60273
  import { join as join4 } from "path";
60207
60274
  import { tmpdir } from "os";
60208
60275
  var AGENT_MAIL_URL = "http://127.0.0.1:8765";
60209
- var DEFAULT_TTL_SECONDS = 3600;
60210
60276
  var MAX_INBOX_LIMIT = 5;
60277
+ var DEFAULT_OPENCODE_MODEL = "openai/gpt-5.2-codex";
60211
60278
  var agentMailProjectDirectory = null;
60212
60279
  function setAgentMailProjectDirectory(directory) {
60213
60280
  agentMailProjectDirectory = directory;
@@ -60626,7 +60693,7 @@ var agentmail_init = tool({
60626
60693
  const agent = await mcpCall("register_agent", {
60627
60694
  project_key: projectPath,
60628
60695
  program: "opencode",
60629
- model: "claude-opus-4",
60696
+ model: DEFAULT_OPENCODE_MODEL,
60630
60697
  name: args.agent_name,
60631
60698
  task_description: args.task_description || ""
60632
60699
  });
@@ -60769,18 +60836,21 @@ var agentmail_reserve = tool({
60769
60836
  description: "Reserve file paths for exclusive editing",
60770
60837
  args: {
60771
60838
  paths: tool.schema.array(tool.schema.string()).describe("File paths or globs to reserve (e.g., src/auth/**)"),
60772
- ttl_seconds: tool.schema.number().optional().describe(`Time to live in seconds (default: ${DEFAULT_TTL_SECONDS})`),
60839
+ ttl_seconds: tool.schema.number().int().positive().describe("Time to live in seconds (required)"),
60773
60840
  exclusive: tool.schema.boolean().optional().describe("Exclusive lock (default: true)"),
60774
60841
  reason: tool.schema.string().optional().describe("Reason for reservation (include bead ID)")
60775
60842
  },
60776
60843
  async execute(args, ctx) {
60777
60844
  const state = requireState(ctx.sessionID);
60778
60845
  await checkRateLimit(state.agentName, "reserve");
60846
+ if (!args.ttl_seconds || args.ttl_seconds <= 0) {
60847
+ throw new AgentMailError("ttl_seconds is required for file reservations", "file_reservation_paths");
60848
+ }
60779
60849
  const result = await mcpCall("file_reservation_paths", {
60780
60850
  project_key: state.projectKey,
60781
60851
  agent_name: state.agentName,
60782
60852
  paths: args.paths,
60783
- ttl_seconds: args.ttl_seconds || DEFAULT_TTL_SECONDS,
60853
+ ttl_seconds: args.ttl_seconds,
60784
60854
  exclusive: args.exclusive ?? true,
60785
60855
  reason: args.reason || ""
60786
60856
  });
@@ -60818,11 +60888,13 @@ var agentmail_release = tool({
60818
60888
  async execute(args, ctx) {
60819
60889
  const state = requireState(ctx.sessionID);
60820
60890
  await checkRateLimit(state.agentName, "release");
60891
+ const shouldUseStoredIds = !args.paths && (!args.reservation_ids || args.reservation_ids.length === 0);
60892
+ const reservationIds = shouldUseStoredIds && state.reservations.length > 0 ? state.reservations : args.reservation_ids;
60821
60893
  const result = await mcpCall("release_file_reservations", {
60822
60894
  project_key: state.projectKey,
60823
60895
  agent_name: state.agentName,
60824
60896
  paths: args.paths,
60825
- file_reservation_ids: args.reservation_ids
60897
+ file_reservation_ids: reservationIds
60826
60898
  });
60827
60899
  state.reservations = [];
60828
60900
  setState(ctx.sessionID, state);
@@ -60935,6 +61007,260 @@ import {
60935
61007
  checkSwarmHealth as checkSwarmHealth2,
60936
61008
  getActiveReservations
60937
61009
  } from "swarm-mail";
61010
+
61011
+ // src/planning-guardrails.ts
61012
+ init_eval_capture();
61013
+ var FILE_MODIFICATION_PATTERNS = [
61014
+ /\bimplement\b/i,
61015
+ /\bcreate\b.*\.(ts|js|tsx|jsx|py|rs|go|java|rb|swift|kt)/i,
61016
+ /\badd\b.*\.(ts|js|tsx|jsx|py|rs|go|java|rb|swift|kt)/i,
61017
+ /\bupdate\b.*\.(ts|js|tsx|jsx|py|rs|go|java|rb|swift|kt)/i,
61018
+ /\bmodify\b/i,
61019
+ /\brefactor\b/i,
61020
+ /\bextract\b/i,
61021
+ /\bmigrate\b/i,
61022
+ /\bconvert\b/i,
61023
+ /\brewrite\b/i,
61024
+ /\bfix\b.*\.(ts|js|tsx|jsx|py|rs|go|java|rb|swift|kt)/i,
61025
+ /\bwrite\b.*\.(ts|js|tsx|jsx|py|rs|go|java|rb|swift|kt)/i,
61026
+ /src\//i,
61027
+ /lib\//i,
61028
+ /packages?\//i,
61029
+ /components?\//i
61030
+ ];
61031
+ var TRACKING_PATTERNS = [
61032
+ /\breview\b/i,
61033
+ /\bcheck\b/i,
61034
+ /\bverify\b/i,
61035
+ /\btest\b.*pass/i,
61036
+ /\brun\b.*test/i,
61037
+ /\bdeploy\b/i,
61038
+ /\bmerge\b/i,
61039
+ /\bpr\b/i,
61040
+ /\bpush\b/i,
61041
+ /\bcommit\b/i
61042
+ ];
61043
+ function analyzeTodoWrite(args) {
61044
+ const todos = args.todos;
61045
+ if (!todos || !Array.isArray(todos) || todos.length < 6) {
61046
+ return {
61047
+ looksLikeParallelWork: false,
61048
+ fileModificationCount: 0,
61049
+ totalCount: todos?.length ?? 0
61050
+ };
61051
+ }
61052
+ let fileModificationCount = 0;
61053
+ for (const todo of todos) {
61054
+ if (typeof todo !== "object" || todo === null)
61055
+ continue;
61056
+ const content = todo.content ?? "";
61057
+ const isFileModification = FILE_MODIFICATION_PATTERNS.some((pattern) => pattern.test(content));
61058
+ const isTracking = TRACKING_PATTERNS.some((pattern) => pattern.test(content));
61059
+ if (isFileModification && !isTracking) {
61060
+ fileModificationCount++;
61061
+ }
61062
+ }
61063
+ const ratio = fileModificationCount / todos.length;
61064
+ const looksLikeParallelWork = ratio >= 0.5 && fileModificationCount >= 4;
61065
+ if (looksLikeParallelWork) {
61066
+ return {
61067
+ looksLikeParallelWork: true,
61068
+ fileModificationCount,
61069
+ totalCount: todos.length,
61070
+ warning: `⚠️ This looks like a multi-file implementation plan (${fileModificationCount}/${todos.length} items are file modifications).
61071
+
61072
+ Consider using swarm instead:
61073
+ swarm_decompose → hive_create_epic → parallel task spawns
61074
+
61075
+ TodoWrite is for tracking progress, not parallelizable implementation work.
61076
+ Swarm workers can complete these ${fileModificationCount} tasks in parallel.
61077
+
61078
+ (Continuing with todowrite - this is just a suggestion)`
61079
+ };
61080
+ }
61081
+ return {
61082
+ looksLikeParallelWork: false,
61083
+ fileModificationCount,
61084
+ totalCount: todos.length
61085
+ };
61086
+ }
61087
+ function shouldAnalyzeTool(toolName) {
61088
+ return toolName === "todowrite" || toolName === "TodoWrite";
61089
+ }
61090
+ var VIOLATION_PATTERNS = {
61091
+ FILE_MODIFICATION_TOOLS: ["edit", "write"],
61092
+ RESERVATION_TOOLS: ["swarmmail_reserve", "agentmail_reserve"],
61093
+ TEST_EXECUTION_PATTERNS: [
61094
+ /\bbun\s+test\b/i,
61095
+ /\bnpm\s+(run\s+)?test/i,
61096
+ /\byarn\s+(run\s+)?test/i,
61097
+ /\bpnpm\s+(run\s+)?test/i,
61098
+ /\bjest\b/i,
61099
+ /\bvitest\b/i,
61100
+ /\bmocha\b/i,
61101
+ /\bava\b/i,
61102
+ /\btape\b/i,
61103
+ /\.test\.(ts|js|tsx|jsx)\b/i,
61104
+ /\.spec\.(ts|js|tsx|jsx)\b/i
61105
+ ]
61106
+ };
61107
+ function detectCoordinatorViolation(params) {
61108
+ const { sessionId, epicId, toolName, toolArgs, agentContext, checkNoSpawn = false } = params;
61109
+ if (agentContext !== "coordinator") {
61110
+ return { isViolation: false };
61111
+ }
61112
+ if (VIOLATION_PATTERNS.FILE_MODIFICATION_TOOLS.includes(toolName)) {
61113
+ const file2 = toolArgs.filePath || "";
61114
+ const payload = { tool: toolName, file: file2 };
61115
+ captureCoordinatorEvent({
61116
+ session_id: sessionId,
61117
+ epic_id: epicId,
61118
+ timestamp: new Date().toISOString(),
61119
+ event_type: "VIOLATION",
61120
+ violation_type: "coordinator_edited_file",
61121
+ payload
61122
+ });
61123
+ return {
61124
+ isViolation: true,
61125
+ violationType: "coordinator_edited_file",
61126
+ message: `⚠️ Coordinator should not edit files directly. Coordinators should spawn workers to implement changes.`,
61127
+ payload
61128
+ };
61129
+ }
61130
+ if (toolName === "bash") {
61131
+ const command = toolArgs.command || "";
61132
+ const isTestCommand = VIOLATION_PATTERNS.TEST_EXECUTION_PATTERNS.some((pattern) => pattern.test(command));
61133
+ if (isTestCommand) {
61134
+ const payload = { tool: toolName, command };
61135
+ captureCoordinatorEvent({
61136
+ session_id: sessionId,
61137
+ epic_id: epicId,
61138
+ timestamp: new Date().toISOString(),
61139
+ event_type: "VIOLATION",
61140
+ violation_type: "coordinator_ran_tests",
61141
+ payload
61142
+ });
61143
+ return {
61144
+ isViolation: true,
61145
+ violationType: "coordinator_ran_tests",
61146
+ message: `⚠️ Coordinator should not run tests directly. Workers run tests as part of their implementation verification.`,
61147
+ payload
61148
+ };
61149
+ }
61150
+ }
61151
+ if (VIOLATION_PATTERNS.RESERVATION_TOOLS.includes(toolName)) {
61152
+ const paths = toolArgs.paths || [];
61153
+ const payload = { tool: toolName, paths };
61154
+ captureCoordinatorEvent({
61155
+ session_id: sessionId,
61156
+ epic_id: epicId,
61157
+ timestamp: new Date().toISOString(),
61158
+ event_type: "VIOLATION",
61159
+ violation_type: "coordinator_reserved_files",
61160
+ payload
61161
+ });
61162
+ return {
61163
+ isViolation: true,
61164
+ violationType: "coordinator_reserved_files",
61165
+ message: `⚠️ Coordinator should not reserve files. Workers reserve files before editing to prevent conflicts.`,
61166
+ payload
61167
+ };
61168
+ }
61169
+ if (toolName === "hive_create_epic" && checkNoSpawn) {
61170
+ const epicTitle = toolArgs.epic_title || "";
61171
+ const subtasks = toolArgs.subtasks || [];
61172
+ const payload = { epic_title: epicTitle, subtask_count: subtasks.length };
61173
+ captureCoordinatorEvent({
61174
+ session_id: sessionId,
61175
+ epic_id: epicId,
61176
+ timestamp: new Date().toISOString(),
61177
+ event_type: "VIOLATION",
61178
+ violation_type: "no_worker_spawned",
61179
+ payload
61180
+ });
61181
+ return {
61182
+ isViolation: true,
61183
+ violationType: "no_worker_spawned",
61184
+ message: `⚠️ Coordinator created decomposition without spawning workers. After hive_create_epic, use swarm_spawn_subtask for each task.`,
61185
+ payload
61186
+ };
61187
+ }
61188
+ if (toolName === "swarm_complete" || toolName === "hive_close") {
61189
+ const payload = { tool: toolName };
61190
+ captureCoordinatorEvent({
61191
+ session_id: sessionId,
61192
+ epic_id: epicId,
61193
+ timestamp: new Date().toISOString(),
61194
+ event_type: "VIOLATION",
61195
+ violation_type: "worker_completed_without_review",
61196
+ payload
61197
+ });
61198
+ return {
61199
+ isViolation: true,
61200
+ violationType: "worker_completed_without_review",
61201
+ message: `⚠️ Coordinator should not complete worker tasks directly. Coordinators should review worker output using swarm_review and swarm_review_feedback.`,
61202
+ payload
61203
+ };
61204
+ }
61205
+ return { isViolation: false };
61206
+ }
61207
+ var coordinatorContexts = new Map;
61208
+ var globalCoordinatorContext = {
61209
+ isCoordinator: false
61210
+ };
61211
+ function setCoordinatorContext(ctx) {
61212
+ const sessionId = ctx.sessionId;
61213
+ if (sessionId) {
61214
+ const existing = coordinatorContexts.get(sessionId) || { isCoordinator: false };
61215
+ coordinatorContexts.set(sessionId, {
61216
+ ...existing,
61217
+ ...ctx,
61218
+ activatedAt: ctx.isCoordinator ? Date.now() : existing.activatedAt
61219
+ });
61220
+ } else {
61221
+ globalCoordinatorContext = {
61222
+ ...globalCoordinatorContext,
61223
+ ...ctx,
61224
+ activatedAt: ctx.isCoordinator ? Date.now() : globalCoordinatorContext.activatedAt
61225
+ };
61226
+ }
61227
+ }
61228
+ function getCoordinatorContext(sessionId) {
61229
+ if (sessionId) {
61230
+ return { ...coordinatorContexts.get(sessionId) || { isCoordinator: false } };
61231
+ }
61232
+ return { ...globalCoordinatorContext };
61233
+ }
61234
+ function clearCoordinatorContext(sessionId) {
61235
+ if (sessionId) {
61236
+ coordinatorContexts.delete(sessionId);
61237
+ } else {
61238
+ globalCoordinatorContext = {
61239
+ isCoordinator: false
61240
+ };
61241
+ }
61242
+ }
61243
+ function isInCoordinatorContext(sessionId) {
61244
+ const ctx = sessionId ? coordinatorContexts.get(sessionId) : globalCoordinatorContext;
61245
+ if (!ctx || !ctx.isCoordinator) {
61246
+ return false;
61247
+ }
61248
+ const COORDINATOR_TIMEOUT_MS = 4 * 60 * 60 * 1000;
61249
+ if (ctx.activatedAt) {
61250
+ const elapsed = Date.now() - ctx.activatedAt;
61251
+ if (elapsed > COORDINATOR_TIMEOUT_MS) {
61252
+ if (sessionId) {
61253
+ coordinatorContexts.delete(sessionId);
61254
+ } else {
61255
+ globalCoordinatorContext = { isCoordinator: false };
61256
+ }
61257
+ return false;
61258
+ }
61259
+ }
61260
+ return true;
61261
+ }
61262
+
61263
+ // src/swarm-mail.ts
60938
61264
  import {
60939
61265
  existsSync as existsSync5,
60940
61266
  mkdirSync as mkdirSync4,
@@ -60982,6 +61308,21 @@ function saveSessionState2(sessionID, state) {
60982
61308
  return false;
60983
61309
  }
60984
61310
  }
61311
+ function hasCoordinatorOverride(sessionID) {
61312
+ return isInCoordinatorContext(sessionID) || isInCoordinatorContext();
61313
+ }
61314
+ function formatCoordinatorOverrideError(params) {
61315
+ return JSON.stringify({
61316
+ error: "Coordinator-only override. Ask the coordinator to use this tool for stale or orphaned reservations.",
61317
+ guard: "coordinator_only",
61318
+ required_context: "coordinator",
61319
+ tool: params.tool,
61320
+ agent_name: params.state.agentName,
61321
+ project_key: params.state.projectKey,
61322
+ session_id: params.sessionID,
61323
+ suggestion: "If reservations are stale, notify the coordinator via swarmmail_send before releasing."
61324
+ }, null, 2);
61325
+ }
60985
61326
  var swarmmail_init = tool({
60986
61327
  description: "Initialize Swarm Mail session. Creates agent identity and registers with the embedded event store.",
60987
61328
  args: {
@@ -61236,6 +61577,13 @@ var swarmmail_release_all = tool({
61236
61577
  if (!state) {
61237
61578
  return JSON.stringify({ error: "Session not initialized. Call swarmmail_init first." }, null, 2);
61238
61579
  }
61580
+ if (!hasCoordinatorOverride(sessionID)) {
61581
+ return formatCoordinatorOverrideError({
61582
+ tool: "swarmmail_release_all",
61583
+ state,
61584
+ sessionID
61585
+ });
61586
+ }
61239
61587
  try {
61240
61588
  const result = await releaseAllSwarmFiles({
61241
61589
  projectPath: state.projectKey,
@@ -61266,6 +61614,13 @@ var swarmmail_release_agent = tool({
61266
61614
  if (!state) {
61267
61615
  return JSON.stringify({ error: "Session not initialized. Call swarmmail_init first." }, null, 2);
61268
61616
  }
61617
+ if (!hasCoordinatorOverride(sessionID)) {
61618
+ return formatCoordinatorOverrideError({
61619
+ tool: "swarmmail_release_agent",
61620
+ state,
61621
+ sessionID
61622
+ });
61623
+ }
61269
61624
  try {
61270
61625
  const result = await releaseSwarmFilesForAgent({
61271
61626
  projectPath: state.projectKey,
@@ -66674,7 +67029,7 @@ var STRATEGY_DECOMPOSITION_PROMPT2 = `You are decomposing a task into paralleliz
66674
67029
 
66675
67030
  {context_section}
66676
67031
 
66677
- {cass_history}
67032
+ {hivemind_history}
66678
67033
 
66679
67034
  {skills_context}
66680
67035
 
@@ -67596,7 +67951,8 @@ var swarm_spawn_subtask = tool({
67596
67951
  files: args2.files,
67597
67952
  shared_context: args2.shared_context,
67598
67953
  project_path: args2.project_path,
67599
- recovery_context: args2.recovery_context
67954
+ recovery_context: args2.recovery_context,
67955
+ model: args2.model
67600
67956
  });
67601
67957
  const { selectWorkerModel: selectWorkerModel2 } = await Promise.resolve().then(() => exports_model_selection);
67602
67958
  const subtask = {
@@ -67857,13 +68213,13 @@ var swarm_evaluation_prompt = tool({
67857
68213
  }
67858
68214
  });
67859
68215
  var swarm_plan_prompt = tool({
67860
- description: "Generate strategy-specific decomposition prompt. Auto-selects strategy or uses provided one. Queries CASS for similar tasks.",
68216
+ description: "Generate strategy-specific decomposition prompt. Auto-selects strategy or uses provided one. Queries Hivemind sessions for similar tasks.",
67861
68217
  args: {
67862
68218
  task: tool.schema.string().min(1).describe("Task description to decompose"),
67863
68219
  strategy: tool.schema.enum(["file-based", "feature-based", "risk-based", "auto"]).optional().describe("Decomposition strategy (default: auto-detect)"),
67864
68220
  context: tool.schema.string().optional().describe("Additional context (codebase info, constraints, etc.)"),
67865
- query_cass: tool.schema.boolean().optional().describe("Query CASS for similar past tasks (default: true)"),
67866
- cass_limit: tool.schema.number().int().min(1).optional().describe("Max CASS results to include (default: 3)"),
68221
+ query_cass: tool.schema.boolean().optional().describe("Query Hivemind sessions for similar past tasks (default: true)"),
68222
+ cass_limit: tool.schema.number().int().min(1).optional().describe("Max Hivemind session results to include (default: 3)"),
67867
68223
  include_skills: tool.schema.boolean().optional().describe("Include available skills in context (default: true)")
67868
68224
  },
67869
68225
  async execute(args2) {
@@ -67911,7 +68267,7 @@ ${insights}` : insights ? `## Additional Context
67911
68267
 
67912
68268
  ${insights}` : `## Additional Context
67913
68269
  (none provided)`;
67914
- const prompt = STRATEGY_DECOMPOSITION_PROMPT2.replace("{task}", args2.task).replace("{strategy_guidelines}", strategyGuidelines).replace("{context_section}", contextSection).replace("{cass_history}", "").replace("{skills_context}", skillsContext || "");
68270
+ const prompt = STRATEGY_DECOMPOSITION_PROMPT2.replace("{task}", args2.task).replace("{strategy_guidelines}", strategyGuidelines).replace("{context_section}", contextSection).replace("{hivemind_history}", "").replace("{skills_context}", skillsContext || "");
67915
68271
  return JSON.stringify({
67916
68272
  prompt,
67917
68273
  strategy: {
@@ -70306,258 +70662,6 @@ function guardrailOutput(toolName, output, config2 = DEFAULT_GUARDRAIL_CONFIG) {
70306
70662
  };
70307
70663
  }
70308
70664
 
70309
- // src/planning-guardrails.ts
70310
- init_eval_capture();
70311
- var FILE_MODIFICATION_PATTERNS = [
70312
- /\bimplement\b/i,
70313
- /\bcreate\b.*\.(ts|js|tsx|jsx|py|rs|go|java|rb|swift|kt)/i,
70314
- /\badd\b.*\.(ts|js|tsx|jsx|py|rs|go|java|rb|swift|kt)/i,
70315
- /\bupdate\b.*\.(ts|js|tsx|jsx|py|rs|go|java|rb|swift|kt)/i,
70316
- /\bmodify\b/i,
70317
- /\brefactor\b/i,
70318
- /\bextract\b/i,
70319
- /\bmigrate\b/i,
70320
- /\bconvert\b/i,
70321
- /\brewrite\b/i,
70322
- /\bfix\b.*\.(ts|js|tsx|jsx|py|rs|go|java|rb|swift|kt)/i,
70323
- /\bwrite\b.*\.(ts|js|tsx|jsx|py|rs|go|java|rb|swift|kt)/i,
70324
- /src\//i,
70325
- /lib\//i,
70326
- /packages?\//i,
70327
- /components?\//i
70328
- ];
70329
- var TRACKING_PATTERNS = [
70330
- /\breview\b/i,
70331
- /\bcheck\b/i,
70332
- /\bverify\b/i,
70333
- /\btest\b.*pass/i,
70334
- /\brun\b.*test/i,
70335
- /\bdeploy\b/i,
70336
- /\bmerge\b/i,
70337
- /\bpr\b/i,
70338
- /\bpush\b/i,
70339
- /\bcommit\b/i
70340
- ];
70341
- function analyzeTodoWrite(args2) {
70342
- const todos = args2.todos;
70343
- if (!todos || !Array.isArray(todos) || todos.length < 6) {
70344
- return {
70345
- looksLikeParallelWork: false,
70346
- fileModificationCount: 0,
70347
- totalCount: todos?.length ?? 0
70348
- };
70349
- }
70350
- let fileModificationCount = 0;
70351
- for (const todo of todos) {
70352
- if (typeof todo !== "object" || todo === null)
70353
- continue;
70354
- const content = todo.content ?? "";
70355
- const isFileModification = FILE_MODIFICATION_PATTERNS.some((pattern2) => pattern2.test(content));
70356
- const isTracking = TRACKING_PATTERNS.some((pattern2) => pattern2.test(content));
70357
- if (isFileModification && !isTracking) {
70358
- fileModificationCount++;
70359
- }
70360
- }
70361
- const ratio = fileModificationCount / todos.length;
70362
- const looksLikeParallelWork = ratio >= 0.5 && fileModificationCount >= 4;
70363
- if (looksLikeParallelWork) {
70364
- return {
70365
- looksLikeParallelWork: true,
70366
- fileModificationCount,
70367
- totalCount: todos.length,
70368
- warning: `⚠️ This looks like a multi-file implementation plan (${fileModificationCount}/${todos.length} items are file modifications).
70369
-
70370
- Consider using swarm instead:
70371
- swarm_decompose → hive_create_epic → parallel task spawns
70372
-
70373
- TodoWrite is for tracking progress, not parallelizable implementation work.
70374
- Swarm workers can complete these ${fileModificationCount} tasks in parallel.
70375
-
70376
- (Continuing with todowrite - this is just a suggestion)`
70377
- };
70378
- }
70379
- return {
70380
- looksLikeParallelWork: false,
70381
- fileModificationCount,
70382
- totalCount: todos.length
70383
- };
70384
- }
70385
- function shouldAnalyzeTool(toolName) {
70386
- return toolName === "todowrite" || toolName === "TodoWrite";
70387
- }
70388
- var VIOLATION_PATTERNS = {
70389
- FILE_MODIFICATION_TOOLS: ["edit", "write"],
70390
- RESERVATION_TOOLS: ["swarmmail_reserve", "agentmail_reserve"],
70391
- TEST_EXECUTION_PATTERNS: [
70392
- /\bbun\s+test\b/i,
70393
- /\bnpm\s+(run\s+)?test/i,
70394
- /\byarn\s+(run\s+)?test/i,
70395
- /\bpnpm\s+(run\s+)?test/i,
70396
- /\bjest\b/i,
70397
- /\bvitest\b/i,
70398
- /\bmocha\b/i,
70399
- /\bava\b/i,
70400
- /\btape\b/i,
70401
- /\.test\.(ts|js|tsx|jsx)\b/i,
70402
- /\.spec\.(ts|js|tsx|jsx)\b/i
70403
- ]
70404
- };
70405
- function detectCoordinatorViolation(params) {
70406
- const { sessionId, epicId, toolName, toolArgs, agentContext, checkNoSpawn = false } = params;
70407
- if (agentContext !== "coordinator") {
70408
- return { isViolation: false };
70409
- }
70410
- if (VIOLATION_PATTERNS.FILE_MODIFICATION_TOOLS.includes(toolName)) {
70411
- const file2 = toolArgs.filePath || "";
70412
- const payload = { tool: toolName, file: file2 };
70413
- captureCoordinatorEvent({
70414
- session_id: sessionId,
70415
- epic_id: epicId,
70416
- timestamp: new Date().toISOString(),
70417
- event_type: "VIOLATION",
70418
- violation_type: "coordinator_edited_file",
70419
- payload
70420
- });
70421
- return {
70422
- isViolation: true,
70423
- violationType: "coordinator_edited_file",
70424
- message: `⚠️ Coordinator should not edit files directly. Coordinators should spawn workers to implement changes.`,
70425
- payload
70426
- };
70427
- }
70428
- if (toolName === "bash") {
70429
- const command = toolArgs.command || "";
70430
- const isTestCommand = VIOLATION_PATTERNS.TEST_EXECUTION_PATTERNS.some((pattern2) => pattern2.test(command));
70431
- if (isTestCommand) {
70432
- const payload = { tool: toolName, command };
70433
- captureCoordinatorEvent({
70434
- session_id: sessionId,
70435
- epic_id: epicId,
70436
- timestamp: new Date().toISOString(),
70437
- event_type: "VIOLATION",
70438
- violation_type: "coordinator_ran_tests",
70439
- payload
70440
- });
70441
- return {
70442
- isViolation: true,
70443
- violationType: "coordinator_ran_tests",
70444
- message: `⚠️ Coordinator should not run tests directly. Workers run tests as part of their implementation verification.`,
70445
- payload
70446
- };
70447
- }
70448
- }
70449
- if (VIOLATION_PATTERNS.RESERVATION_TOOLS.includes(toolName)) {
70450
- const paths = toolArgs.paths || [];
70451
- const payload = { tool: toolName, paths };
70452
- captureCoordinatorEvent({
70453
- session_id: sessionId,
70454
- epic_id: epicId,
70455
- timestamp: new Date().toISOString(),
70456
- event_type: "VIOLATION",
70457
- violation_type: "coordinator_reserved_files",
70458
- payload
70459
- });
70460
- return {
70461
- isViolation: true,
70462
- violationType: "coordinator_reserved_files",
70463
- message: `⚠️ Coordinator should not reserve files. Workers reserve files before editing to prevent conflicts.`,
70464
- payload
70465
- };
70466
- }
70467
- if (toolName === "hive_create_epic" && checkNoSpawn) {
70468
- const epicTitle = toolArgs.epic_title || "";
70469
- const subtasks = toolArgs.subtasks || [];
70470
- const payload = { epic_title: epicTitle, subtask_count: subtasks.length };
70471
- captureCoordinatorEvent({
70472
- session_id: sessionId,
70473
- epic_id: epicId,
70474
- timestamp: new Date().toISOString(),
70475
- event_type: "VIOLATION",
70476
- violation_type: "no_worker_spawned",
70477
- payload
70478
- });
70479
- return {
70480
- isViolation: true,
70481
- violationType: "no_worker_spawned",
70482
- message: `⚠️ Coordinator created decomposition without spawning workers. After hive_create_epic, use swarm_spawn_subtask for each task.`,
70483
- payload
70484
- };
70485
- }
70486
- if (toolName === "swarm_complete" || toolName === "hive_close") {
70487
- const payload = { tool: toolName };
70488
- captureCoordinatorEvent({
70489
- session_id: sessionId,
70490
- epic_id: epicId,
70491
- timestamp: new Date().toISOString(),
70492
- event_type: "VIOLATION",
70493
- violation_type: "worker_completed_without_review",
70494
- payload
70495
- });
70496
- return {
70497
- isViolation: true,
70498
- violationType: "worker_completed_without_review",
70499
- message: `⚠️ Coordinator should not complete worker tasks directly. Coordinators should review worker output using swarm_review and swarm_review_feedback.`,
70500
- payload
70501
- };
70502
- }
70503
- return { isViolation: false };
70504
- }
70505
- var coordinatorContexts = new Map;
70506
- var globalCoordinatorContext = {
70507
- isCoordinator: false
70508
- };
70509
- function setCoordinatorContext(ctx) {
70510
- const sessionId = ctx.sessionId;
70511
- if (sessionId) {
70512
- const existing = coordinatorContexts.get(sessionId) || { isCoordinator: false };
70513
- coordinatorContexts.set(sessionId, {
70514
- ...existing,
70515
- ...ctx,
70516
- activatedAt: ctx.isCoordinator ? Date.now() : existing.activatedAt
70517
- });
70518
- } else {
70519
- globalCoordinatorContext = {
70520
- ...globalCoordinatorContext,
70521
- ...ctx,
70522
- activatedAt: ctx.isCoordinator ? Date.now() : globalCoordinatorContext.activatedAt
70523
- };
70524
- }
70525
- }
70526
- function getCoordinatorContext(sessionId) {
70527
- if (sessionId) {
70528
- return { ...coordinatorContexts.get(sessionId) || { isCoordinator: false } };
70529
- }
70530
- return { ...globalCoordinatorContext };
70531
- }
70532
- function clearCoordinatorContext(sessionId) {
70533
- if (sessionId) {
70534
- coordinatorContexts.delete(sessionId);
70535
- } else {
70536
- globalCoordinatorContext = {
70537
- isCoordinator: false
70538
- };
70539
- }
70540
- }
70541
- function isInCoordinatorContext(sessionId) {
70542
- const ctx = sessionId ? coordinatorContexts.get(sessionId) : globalCoordinatorContext;
70543
- if (!ctx || !ctx.isCoordinator) {
70544
- return false;
70545
- }
70546
- const COORDINATOR_TIMEOUT_MS = 4 * 60 * 60 * 1000;
70547
- if (ctx.activatedAt) {
70548
- const elapsed = Date.now() - ctx.activatedAt;
70549
- if (elapsed > COORDINATOR_TIMEOUT_MS) {
70550
- if (sessionId) {
70551
- coordinatorContexts.delete(sessionId);
70552
- } else {
70553
- globalCoordinatorContext = { isCoordinator: false };
70554
- }
70555
- return false;
70556
- }
70557
- }
70558
- return true;
70559
- }
70560
-
70561
70665
  // src/coordinator-guard.ts
70562
70666
  class CoordinatorGuardError extends Error {
70563
70667
  violationType;
@@ -70809,6 +70913,7 @@ var logger = getLogger();
70809
70913
 
70810
70914
  // src/compaction-hook.ts
70811
70915
  init_eval_capture();
70916
+ init_skills();
70812
70917
  var _logger;
70813
70918
  function getLog() {
70814
70919
  if (!_logger) {
@@ -70830,6 +70935,9 @@ Context was compacted but the swarm is still running. **YOU ARE THE COORDINATOR.
70830
70935
 
70831
70936
  Your role is ORCHESTRATION, not implementation. The resume steps above (if present) tell you exactly what to do first.
70832
70937
 
70938
+ ## \uD83D\uDD27 ALWAYS-ON GUIDANCE
70939
+ ${getAlwaysOnGuidanceSkill({ role: "coordinator" })}
70940
+
70833
70941
  ---
70834
70942
 
70835
70943
  ## \uD83C\uDFAF WHAT GOOD LOOKS LIKE (Behavioral Examples)
@@ -70886,10 +70994,12 @@ You are the **COORDINATOR**. Your job is ORCHESTRATION, not implementation.
70886
70994
  ### What Coordinators Do:
70887
70995
  - ✅ Spawn workers for implementation tasks
70888
70996
  - ✅ Monitor worker progress via \`swarm_status\` and \`swarmmail_inbox\`
70997
+ - ✅ Use \`swarmmail_release_all\` to clear stale/orphaned reservations (coordinator override)
70889
70998
  - ✅ Review completed work with \`swarm_review\`
70890
70999
  - ✅ Unblock dependencies and resolve conflicts
70891
71000
  - ✅ Close the loop when epics complete
70892
71001
 
71002
+
70893
71003
  ### What Coordinators NEVER Do:
70894
71004
  - ❌ **NEVER** edit or write files directly
70895
71005
  - ❌ **NEVER** run tests with \`bash\`