opencode-swarm-plugin 0.56.1 → 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 (182) hide show
  1. package/README.md +21 -0
  2. package/claude-plugin/agents/background-worker.md +1 -0
  3. package/claude-plugin/agents/coordinator.md +1 -0
  4. package/claude-plugin/agents/worker.md +1 -0
  5. package/claude-plugin/bin/swarm-mcp-server.ts +47 -8
  6. package/claude-plugin/dist/agent-mail.d.ts +480 -0
  7. package/claude-plugin/dist/agent-mail.d.ts.map +1 -0
  8. package/claude-plugin/dist/anti-patterns.d.ts +257 -0
  9. package/claude-plugin/dist/anti-patterns.d.ts.map +1 -0
  10. package/claude-plugin/dist/bin/swarm.js +373128 -0
  11. package/claude-plugin/dist/cass-tools.d.ts +74 -0
  12. package/claude-plugin/dist/cass-tools.d.ts.map +1 -0
  13. package/claude-plugin/dist/claude-plugin/claude-plugin-assets.d.ts +10 -0
  14. package/claude-plugin/dist/claude-plugin/claude-plugin-assets.d.ts.map +1 -0
  15. package/claude-plugin/dist/compaction-hook.d.ts +178 -0
  16. package/claude-plugin/dist/compaction-hook.d.ts.map +1 -0
  17. package/claude-plugin/dist/compaction-observability.d.ts +173 -0
  18. package/claude-plugin/dist/compaction-observability.d.ts.map +1 -0
  19. package/claude-plugin/dist/compaction-prompt-scoring.d.ts +125 -0
  20. package/claude-plugin/dist/compaction-prompt-scoring.d.ts.map +1 -0
  21. package/claude-plugin/dist/compaction-prompt-scoring.js +139 -0
  22. package/claude-plugin/dist/contributor-tools.d.ts +42 -0
  23. package/claude-plugin/dist/contributor-tools.d.ts.map +1 -0
  24. package/claude-plugin/dist/coordinator-guard.d.ts +79 -0
  25. package/claude-plugin/dist/coordinator-guard.d.ts.map +1 -0
  26. package/claude-plugin/dist/dashboard.d.ts +82 -0
  27. package/claude-plugin/dist/dashboard.d.ts.map +1 -0
  28. package/claude-plugin/dist/decision-trace-integration.d.ts +204 -0
  29. package/claude-plugin/dist/decision-trace-integration.d.ts.map +1 -0
  30. package/claude-plugin/dist/error-enrichment.d.ts +49 -0
  31. package/claude-plugin/dist/error-enrichment.d.ts.map +1 -0
  32. package/claude-plugin/dist/eval-capture.d.ts +494 -0
  33. package/claude-plugin/dist/eval-capture.d.ts.map +1 -0
  34. package/claude-plugin/dist/eval-capture.js +12844 -0
  35. package/claude-plugin/dist/eval-gates.d.ts +84 -0
  36. package/claude-plugin/dist/eval-gates.d.ts.map +1 -0
  37. package/claude-plugin/dist/eval-history.d.ts +117 -0
  38. package/claude-plugin/dist/eval-history.d.ts.map +1 -0
  39. package/claude-plugin/dist/eval-learning.d.ts +216 -0
  40. package/claude-plugin/dist/eval-learning.d.ts.map +1 -0
  41. package/claude-plugin/dist/eval-runner.d.ts +134 -0
  42. package/claude-plugin/dist/eval-runner.d.ts.map +1 -0
  43. package/claude-plugin/dist/examples/plugin-wrapper-template.ts +3341 -0
  44. package/claude-plugin/dist/export-tools.d.ts +76 -0
  45. package/claude-plugin/dist/export-tools.d.ts.map +1 -0
  46. package/claude-plugin/dist/hive.d.ts +949 -0
  47. package/claude-plugin/dist/hive.d.ts.map +1 -0
  48. package/claude-plugin/dist/hive.js +15009 -0
  49. package/claude-plugin/dist/hivemind-tools.d.ts +479 -0
  50. package/claude-plugin/dist/hivemind-tools.d.ts.map +1 -0
  51. package/claude-plugin/dist/hooks/atomic-write.d.ts +21 -0
  52. package/claude-plugin/dist/hooks/atomic-write.d.ts.map +1 -0
  53. package/claude-plugin/dist/hooks/constants.d.ts +28 -0
  54. package/claude-plugin/dist/hooks/constants.d.ts.map +1 -0
  55. package/claude-plugin/dist/hooks/index.d.ts +16 -0
  56. package/claude-plugin/dist/hooks/index.d.ts.map +1 -0
  57. package/claude-plugin/dist/hooks/session-start.d.ts +30 -0
  58. package/claude-plugin/dist/hooks/session-start.d.ts.map +1 -0
  59. package/claude-plugin/dist/hooks/tool-complete.d.ts +54 -0
  60. package/claude-plugin/dist/hooks/tool-complete.d.ts.map +1 -0
  61. package/claude-plugin/dist/index.d.ts +2017 -0
  62. package/claude-plugin/dist/index.d.ts.map +1 -0
  63. package/claude-plugin/dist/index.js +73453 -0
  64. package/claude-plugin/dist/learning.d.ts +700 -0
  65. package/claude-plugin/dist/learning.d.ts.map +1 -0
  66. package/claude-plugin/dist/logger.d.ts +38 -0
  67. package/claude-plugin/dist/logger.d.ts.map +1 -0
  68. package/claude-plugin/dist/mandate-promotion.d.ts +93 -0
  69. package/claude-plugin/dist/mandate-promotion.d.ts.map +1 -0
  70. package/claude-plugin/dist/mandate-storage.d.ts +209 -0
  71. package/claude-plugin/dist/mandate-storage.d.ts.map +1 -0
  72. package/claude-plugin/dist/mandates.d.ts +230 -0
  73. package/claude-plugin/dist/mandates.d.ts.map +1 -0
  74. package/claude-plugin/dist/memory-tools.d.ts +281 -0
  75. package/claude-plugin/dist/memory-tools.d.ts.map +1 -0
  76. package/claude-plugin/dist/memory.d.ts +164 -0
  77. package/claude-plugin/dist/memory.d.ts.map +1 -0
  78. package/claude-plugin/dist/model-selection.d.ts +37 -0
  79. package/claude-plugin/dist/model-selection.d.ts.map +1 -0
  80. package/claude-plugin/dist/observability-health.d.ts +87 -0
  81. package/claude-plugin/dist/observability-health.d.ts.map +1 -0
  82. package/claude-plugin/dist/observability-tools.d.ts +184 -0
  83. package/claude-plugin/dist/observability-tools.d.ts.map +1 -0
  84. package/claude-plugin/dist/output-guardrails.d.ts +125 -0
  85. package/claude-plugin/dist/output-guardrails.d.ts.map +1 -0
  86. package/claude-plugin/dist/pattern-maturity.d.ts +246 -0
  87. package/claude-plugin/dist/pattern-maturity.d.ts.map +1 -0
  88. package/claude-plugin/dist/planning-guardrails.d.ts +183 -0
  89. package/claude-plugin/dist/planning-guardrails.d.ts.map +1 -0
  90. package/claude-plugin/dist/plugin.d.ts +22 -0
  91. package/claude-plugin/dist/plugin.d.ts.map +1 -0
  92. package/claude-plugin/dist/plugin.js +72295 -0
  93. package/claude-plugin/dist/post-compaction-tracker.d.ts +133 -0
  94. package/claude-plugin/dist/post-compaction-tracker.d.ts.map +1 -0
  95. package/claude-plugin/dist/query-tools.d.ts +90 -0
  96. package/claude-plugin/dist/query-tools.d.ts.map +1 -0
  97. package/claude-plugin/dist/rate-limiter.d.ts +218 -0
  98. package/claude-plugin/dist/rate-limiter.d.ts.map +1 -0
  99. package/claude-plugin/dist/regression-detection.d.ts +58 -0
  100. package/claude-plugin/dist/regression-detection.d.ts.map +1 -0
  101. package/claude-plugin/dist/replay-tools.d.ts +28 -0
  102. package/claude-plugin/dist/replay-tools.d.ts.map +1 -0
  103. package/claude-plugin/dist/repo-crawl.d.ts +146 -0
  104. package/claude-plugin/dist/repo-crawl.d.ts.map +1 -0
  105. package/claude-plugin/dist/schemas/cell-events.d.ts +1352 -0
  106. package/claude-plugin/dist/schemas/cell-events.d.ts.map +1 -0
  107. package/claude-plugin/dist/schemas/cell.d.ts +413 -0
  108. package/claude-plugin/dist/schemas/cell.d.ts.map +1 -0
  109. package/claude-plugin/dist/schemas/evaluation.d.ts +161 -0
  110. package/claude-plugin/dist/schemas/evaluation.d.ts.map +1 -0
  111. package/claude-plugin/dist/schemas/index.d.ts +46 -0
  112. package/claude-plugin/dist/schemas/index.d.ts.map +1 -0
  113. package/claude-plugin/dist/schemas/mandate.d.ts +336 -0
  114. package/claude-plugin/dist/schemas/mandate.d.ts.map +1 -0
  115. package/claude-plugin/dist/schemas/swarm-context.d.ts +131 -0
  116. package/claude-plugin/dist/schemas/swarm-context.d.ts.map +1 -0
  117. package/claude-plugin/dist/schemas/task.d.ts +189 -0
  118. package/claude-plugin/dist/schemas/task.d.ts.map +1 -0
  119. package/claude-plugin/dist/schemas/worker-handoff.d.ts +78 -0
  120. package/claude-plugin/dist/schemas/worker-handoff.d.ts.map +1 -0
  121. package/claude-plugin/dist/sessions/agent-discovery.d.ts +59 -0
  122. package/claude-plugin/dist/sessions/agent-discovery.d.ts.map +1 -0
  123. package/claude-plugin/dist/sessions/index.d.ts +10 -0
  124. package/claude-plugin/dist/sessions/index.d.ts.map +1 -0
  125. package/claude-plugin/dist/skills.d.ts +490 -0
  126. package/claude-plugin/dist/skills.d.ts.map +1 -0
  127. package/claude-plugin/dist/storage.d.ts +260 -0
  128. package/claude-plugin/dist/storage.d.ts.map +1 -0
  129. package/claude-plugin/dist/structured.d.ts +206 -0
  130. package/claude-plugin/dist/structured.d.ts.map +1 -0
  131. package/claude-plugin/dist/swarm-adversarial-review.d.ts +104 -0
  132. package/claude-plugin/dist/swarm-adversarial-review.d.ts.map +1 -0
  133. package/claude-plugin/dist/swarm-decompose.d.ts +297 -0
  134. package/claude-plugin/dist/swarm-decompose.d.ts.map +1 -0
  135. package/claude-plugin/dist/swarm-insights.d.ts +390 -0
  136. package/claude-plugin/dist/swarm-insights.d.ts.map +1 -0
  137. package/claude-plugin/dist/swarm-mail.d.ts +274 -0
  138. package/claude-plugin/dist/swarm-mail.d.ts.map +1 -0
  139. package/claude-plugin/dist/swarm-orchestrate.d.ts +924 -0
  140. package/claude-plugin/dist/swarm-orchestrate.d.ts.map +1 -0
  141. package/claude-plugin/dist/swarm-prompts.d.ts +467 -0
  142. package/claude-plugin/dist/swarm-prompts.d.ts.map +1 -0
  143. package/claude-plugin/dist/swarm-prompts.js +45283 -0
  144. package/claude-plugin/dist/swarm-research.d.ts +125 -0
  145. package/claude-plugin/dist/swarm-research.d.ts.map +1 -0
  146. package/claude-plugin/dist/swarm-review.d.ts +214 -0
  147. package/claude-plugin/dist/swarm-review.d.ts.map +1 -0
  148. package/claude-plugin/dist/swarm-signature.d.ts +106 -0
  149. package/claude-plugin/dist/swarm-signature.d.ts.map +1 -0
  150. package/claude-plugin/dist/swarm-strategies.d.ts +113 -0
  151. package/claude-plugin/dist/swarm-strategies.d.ts.map +1 -0
  152. package/claude-plugin/dist/swarm-validation.d.ts +127 -0
  153. package/claude-plugin/dist/swarm-validation.d.ts.map +1 -0
  154. package/claude-plugin/dist/swarm-worktree.d.ts +185 -0
  155. package/claude-plugin/dist/swarm-worktree.d.ts.map +1 -0
  156. package/claude-plugin/dist/swarm.d.ts +590 -0
  157. package/claude-plugin/dist/swarm.d.ts.map +1 -0
  158. package/claude-plugin/dist/tool-availability.d.ts +91 -0
  159. package/claude-plugin/dist/tool-availability.d.ts.map +1 -0
  160. package/claude-plugin/dist/utils/tree-renderer.d.ts +61 -0
  161. package/claude-plugin/dist/utils/tree-renderer.d.ts.map +1 -0
  162. package/claude-plugin/dist/validators/index.d.ts +7 -0
  163. package/claude-plugin/dist/validators/index.d.ts.map +1 -0
  164. package/claude-plugin/dist/validators/schema-validator.d.ts +58 -0
  165. package/claude-plugin/dist/validators/schema-validator.d.ts.map +1 -0
  166. package/claude-plugin/skills/always-on-guidance/SKILL.md +44 -0
  167. package/dist/agent-mail.d.ts +4 -4
  168. package/dist/agent-mail.d.ts.map +1 -1
  169. package/dist/bin/swarm.js +467 -12
  170. package/dist/claude-plugin/claude-plugin-assets.d.ts +10 -0
  171. package/dist/claude-plugin/claude-plugin-assets.d.ts.map +1 -0
  172. package/dist/compaction-hook.d.ts +1 -1
  173. package/dist/compaction-hook.d.ts.map +1 -1
  174. package/dist/index.js +370 -260
  175. package/dist/plugin.js +369 -259
  176. package/dist/skills.d.ts +15 -0
  177. package/dist/skills.d.ts.map +1 -1
  178. package/dist/swarm-mail.d.ts.map +1 -1
  179. package/dist/swarm-prompts.d.ts +3 -1
  180. package/dist/swarm-prompts.d.ts.map +1 -1
  181. package/dist/swarm-prompts.js +79 -2
  182. package/package.json +2 -1
package/dist/index.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",
@@ -60505,8 +60572,8 @@ import {
60505
60572
  import { join as join4 } from "path";
60506
60573
  import { tmpdir } from "os";
60507
60574
  var AGENT_MAIL_URL = "http://127.0.0.1:8765";
60508
- var DEFAULT_TTL_SECONDS = 3600;
60509
60575
  var MAX_INBOX_LIMIT = 5;
60576
+ var DEFAULT_OPENCODE_MODEL = "openai/gpt-5.2-codex";
60510
60577
  var agentMailProjectDirectory = null;
60511
60578
  function setAgentMailProjectDirectory(directory) {
60512
60579
  agentMailProjectDirectory = directory;
@@ -60916,7 +60983,7 @@ async function reRegisterAgent(projectKey, agentName, taskDescription) {
60916
60983
  await mcpCall("register_agent", {
60917
60984
  project_key: projectKey,
60918
60985
  program: "opencode",
60919
- model: "claude-opus-4",
60986
+ model: DEFAULT_OPENCODE_MODEL,
60920
60987
  name: agentName,
60921
60988
  task_description: taskDescription || "Re-registered after server restart"
60922
60989
  });
@@ -61005,7 +61072,7 @@ var agentmail_init = tool({
61005
61072
  const agent = await mcpCall("register_agent", {
61006
61073
  project_key: projectPath,
61007
61074
  program: "opencode",
61008
- model: "claude-opus-4",
61075
+ model: DEFAULT_OPENCODE_MODEL,
61009
61076
  name: args.agent_name,
61010
61077
  task_description: args.task_description || ""
61011
61078
  });
@@ -61148,18 +61215,21 @@ var agentmail_reserve = tool({
61148
61215
  description: "Reserve file paths for exclusive editing",
61149
61216
  args: {
61150
61217
  paths: tool.schema.array(tool.schema.string()).describe("File paths or globs to reserve (e.g., src/auth/**)"),
61151
- ttl_seconds: tool.schema.number().optional().describe(`Time to live in seconds (default: ${DEFAULT_TTL_SECONDS})`),
61218
+ ttl_seconds: tool.schema.number().int().positive().describe("Time to live in seconds (required)"),
61152
61219
  exclusive: tool.schema.boolean().optional().describe("Exclusive lock (default: true)"),
61153
61220
  reason: tool.schema.string().optional().describe("Reason for reservation (include bead ID)")
61154
61221
  },
61155
61222
  async execute(args, ctx) {
61156
61223
  const state = requireState(ctx.sessionID);
61157
61224
  await checkRateLimit(state.agentName, "reserve");
61225
+ if (!args.ttl_seconds || args.ttl_seconds <= 0) {
61226
+ throw new AgentMailError("ttl_seconds is required for file reservations", "file_reservation_paths");
61227
+ }
61158
61228
  const result = await mcpCall("file_reservation_paths", {
61159
61229
  project_key: state.projectKey,
61160
61230
  agent_name: state.agentName,
61161
61231
  paths: args.paths,
61162
- ttl_seconds: args.ttl_seconds || DEFAULT_TTL_SECONDS,
61232
+ ttl_seconds: args.ttl_seconds,
61163
61233
  exclusive: args.exclusive ?? true,
61164
61234
  reason: args.reason || ""
61165
61235
  });
@@ -61197,11 +61267,13 @@ var agentmail_release = tool({
61197
61267
  async execute(args, ctx) {
61198
61268
  const state = requireState(ctx.sessionID);
61199
61269
  await checkRateLimit(state.agentName, "release");
61270
+ const shouldUseStoredIds = !args.paths && (!args.reservation_ids || args.reservation_ids.length === 0);
61271
+ const reservationIds = shouldUseStoredIds && state.reservations.length > 0 ? state.reservations : args.reservation_ids;
61200
61272
  const result = await mcpCall("release_file_reservations", {
61201
61273
  project_key: state.projectKey,
61202
61274
  agent_name: state.agentName,
61203
61275
  paths: args.paths,
61204
- file_reservation_ids: args.reservation_ids
61276
+ file_reservation_ids: reservationIds
61205
61277
  });
61206
61278
  state.reservations = [];
61207
61279
  setState(ctx.sessionID, state);
@@ -61327,6 +61399,260 @@ import {
61327
61399
  checkSwarmHealth as checkSwarmHealth2,
61328
61400
  getActiveReservations
61329
61401
  } from "swarm-mail";
61402
+
61403
+ // src/planning-guardrails.ts
61404
+ init_eval_capture();
61405
+ var FILE_MODIFICATION_PATTERNS = [
61406
+ /\bimplement\b/i,
61407
+ /\bcreate\b.*\.(ts|js|tsx|jsx|py|rs|go|java|rb|swift|kt)/i,
61408
+ /\badd\b.*\.(ts|js|tsx|jsx|py|rs|go|java|rb|swift|kt)/i,
61409
+ /\bupdate\b.*\.(ts|js|tsx|jsx|py|rs|go|java|rb|swift|kt)/i,
61410
+ /\bmodify\b/i,
61411
+ /\brefactor\b/i,
61412
+ /\bextract\b/i,
61413
+ /\bmigrate\b/i,
61414
+ /\bconvert\b/i,
61415
+ /\brewrite\b/i,
61416
+ /\bfix\b.*\.(ts|js|tsx|jsx|py|rs|go|java|rb|swift|kt)/i,
61417
+ /\bwrite\b.*\.(ts|js|tsx|jsx|py|rs|go|java|rb|swift|kt)/i,
61418
+ /src\//i,
61419
+ /lib\//i,
61420
+ /packages?\//i,
61421
+ /components?\//i
61422
+ ];
61423
+ var TRACKING_PATTERNS = [
61424
+ /\breview\b/i,
61425
+ /\bcheck\b/i,
61426
+ /\bverify\b/i,
61427
+ /\btest\b.*pass/i,
61428
+ /\brun\b.*test/i,
61429
+ /\bdeploy\b/i,
61430
+ /\bmerge\b/i,
61431
+ /\bpr\b/i,
61432
+ /\bpush\b/i,
61433
+ /\bcommit\b/i
61434
+ ];
61435
+ function analyzeTodoWrite(args) {
61436
+ const todos = args.todos;
61437
+ if (!todos || !Array.isArray(todos) || todos.length < 6) {
61438
+ return {
61439
+ looksLikeParallelWork: false,
61440
+ fileModificationCount: 0,
61441
+ totalCount: todos?.length ?? 0
61442
+ };
61443
+ }
61444
+ let fileModificationCount = 0;
61445
+ for (const todo of todos) {
61446
+ if (typeof todo !== "object" || todo === null)
61447
+ continue;
61448
+ const content = todo.content ?? "";
61449
+ const isFileModification = FILE_MODIFICATION_PATTERNS.some((pattern) => pattern.test(content));
61450
+ const isTracking = TRACKING_PATTERNS.some((pattern) => pattern.test(content));
61451
+ if (isFileModification && !isTracking) {
61452
+ fileModificationCount++;
61453
+ }
61454
+ }
61455
+ const ratio = fileModificationCount / todos.length;
61456
+ const looksLikeParallelWork = ratio >= 0.5 && fileModificationCount >= 4;
61457
+ if (looksLikeParallelWork) {
61458
+ return {
61459
+ looksLikeParallelWork: true,
61460
+ fileModificationCount,
61461
+ totalCount: todos.length,
61462
+ warning: `⚠️ This looks like a multi-file implementation plan (${fileModificationCount}/${todos.length} items are file modifications).
61463
+
61464
+ Consider using swarm instead:
61465
+ swarm_decompose → hive_create_epic → parallel task spawns
61466
+
61467
+ TodoWrite is for tracking progress, not parallelizable implementation work.
61468
+ Swarm workers can complete these ${fileModificationCount} tasks in parallel.
61469
+
61470
+ (Continuing with todowrite - this is just a suggestion)`
61471
+ };
61472
+ }
61473
+ return {
61474
+ looksLikeParallelWork: false,
61475
+ fileModificationCount,
61476
+ totalCount: todos.length
61477
+ };
61478
+ }
61479
+ function shouldAnalyzeTool(toolName) {
61480
+ return toolName === "todowrite" || toolName === "TodoWrite";
61481
+ }
61482
+ var VIOLATION_PATTERNS = {
61483
+ FILE_MODIFICATION_TOOLS: ["edit", "write"],
61484
+ RESERVATION_TOOLS: ["swarmmail_reserve", "agentmail_reserve"],
61485
+ TEST_EXECUTION_PATTERNS: [
61486
+ /\bbun\s+test\b/i,
61487
+ /\bnpm\s+(run\s+)?test/i,
61488
+ /\byarn\s+(run\s+)?test/i,
61489
+ /\bpnpm\s+(run\s+)?test/i,
61490
+ /\bjest\b/i,
61491
+ /\bvitest\b/i,
61492
+ /\bmocha\b/i,
61493
+ /\bava\b/i,
61494
+ /\btape\b/i,
61495
+ /\.test\.(ts|js|tsx|jsx)\b/i,
61496
+ /\.spec\.(ts|js|tsx|jsx)\b/i
61497
+ ]
61498
+ };
61499
+ function detectCoordinatorViolation(params) {
61500
+ const { sessionId, epicId, toolName, toolArgs, agentContext, checkNoSpawn = false } = params;
61501
+ if (agentContext !== "coordinator") {
61502
+ return { isViolation: false };
61503
+ }
61504
+ if (VIOLATION_PATTERNS.FILE_MODIFICATION_TOOLS.includes(toolName)) {
61505
+ const file2 = toolArgs.filePath || "";
61506
+ const payload = { tool: toolName, file: file2 };
61507
+ captureCoordinatorEvent({
61508
+ session_id: sessionId,
61509
+ epic_id: epicId,
61510
+ timestamp: new Date().toISOString(),
61511
+ event_type: "VIOLATION",
61512
+ violation_type: "coordinator_edited_file",
61513
+ payload
61514
+ });
61515
+ return {
61516
+ isViolation: true,
61517
+ violationType: "coordinator_edited_file",
61518
+ message: `⚠️ Coordinator should not edit files directly. Coordinators should spawn workers to implement changes.`,
61519
+ payload
61520
+ };
61521
+ }
61522
+ if (toolName === "bash") {
61523
+ const command = toolArgs.command || "";
61524
+ const isTestCommand = VIOLATION_PATTERNS.TEST_EXECUTION_PATTERNS.some((pattern) => pattern.test(command));
61525
+ if (isTestCommand) {
61526
+ const payload = { tool: toolName, command };
61527
+ captureCoordinatorEvent({
61528
+ session_id: sessionId,
61529
+ epic_id: epicId,
61530
+ timestamp: new Date().toISOString(),
61531
+ event_type: "VIOLATION",
61532
+ violation_type: "coordinator_ran_tests",
61533
+ payload
61534
+ });
61535
+ return {
61536
+ isViolation: true,
61537
+ violationType: "coordinator_ran_tests",
61538
+ message: `⚠️ Coordinator should not run tests directly. Workers run tests as part of their implementation verification.`,
61539
+ payload
61540
+ };
61541
+ }
61542
+ }
61543
+ if (VIOLATION_PATTERNS.RESERVATION_TOOLS.includes(toolName)) {
61544
+ const paths = toolArgs.paths || [];
61545
+ const payload = { tool: toolName, paths };
61546
+ captureCoordinatorEvent({
61547
+ session_id: sessionId,
61548
+ epic_id: epicId,
61549
+ timestamp: new Date().toISOString(),
61550
+ event_type: "VIOLATION",
61551
+ violation_type: "coordinator_reserved_files",
61552
+ payload
61553
+ });
61554
+ return {
61555
+ isViolation: true,
61556
+ violationType: "coordinator_reserved_files",
61557
+ message: `⚠️ Coordinator should not reserve files. Workers reserve files before editing to prevent conflicts.`,
61558
+ payload
61559
+ };
61560
+ }
61561
+ if (toolName === "hive_create_epic" && checkNoSpawn) {
61562
+ const epicTitle = toolArgs.epic_title || "";
61563
+ const subtasks = toolArgs.subtasks || [];
61564
+ const payload = { epic_title: epicTitle, subtask_count: subtasks.length };
61565
+ captureCoordinatorEvent({
61566
+ session_id: sessionId,
61567
+ epic_id: epicId,
61568
+ timestamp: new Date().toISOString(),
61569
+ event_type: "VIOLATION",
61570
+ violation_type: "no_worker_spawned",
61571
+ payload
61572
+ });
61573
+ return {
61574
+ isViolation: true,
61575
+ violationType: "no_worker_spawned",
61576
+ message: `⚠️ Coordinator created decomposition without spawning workers. After hive_create_epic, use swarm_spawn_subtask for each task.`,
61577
+ payload
61578
+ };
61579
+ }
61580
+ if (toolName === "swarm_complete" || toolName === "hive_close") {
61581
+ const payload = { tool: toolName };
61582
+ captureCoordinatorEvent({
61583
+ session_id: sessionId,
61584
+ epic_id: epicId,
61585
+ timestamp: new Date().toISOString(),
61586
+ event_type: "VIOLATION",
61587
+ violation_type: "worker_completed_without_review",
61588
+ payload
61589
+ });
61590
+ return {
61591
+ isViolation: true,
61592
+ violationType: "worker_completed_without_review",
61593
+ message: `⚠️ Coordinator should not complete worker tasks directly. Coordinators should review worker output using swarm_review and swarm_review_feedback.`,
61594
+ payload
61595
+ };
61596
+ }
61597
+ return { isViolation: false };
61598
+ }
61599
+ var coordinatorContexts = new Map;
61600
+ var globalCoordinatorContext = {
61601
+ isCoordinator: false
61602
+ };
61603
+ function setCoordinatorContext(ctx) {
61604
+ const sessionId = ctx.sessionId;
61605
+ if (sessionId) {
61606
+ const existing = coordinatorContexts.get(sessionId) || { isCoordinator: false };
61607
+ coordinatorContexts.set(sessionId, {
61608
+ ...existing,
61609
+ ...ctx,
61610
+ activatedAt: ctx.isCoordinator ? Date.now() : existing.activatedAt
61611
+ });
61612
+ } else {
61613
+ globalCoordinatorContext = {
61614
+ ...globalCoordinatorContext,
61615
+ ...ctx,
61616
+ activatedAt: ctx.isCoordinator ? Date.now() : globalCoordinatorContext.activatedAt
61617
+ };
61618
+ }
61619
+ }
61620
+ function getCoordinatorContext(sessionId) {
61621
+ if (sessionId) {
61622
+ return { ...coordinatorContexts.get(sessionId) || { isCoordinator: false } };
61623
+ }
61624
+ return { ...globalCoordinatorContext };
61625
+ }
61626
+ function clearCoordinatorContext(sessionId) {
61627
+ if (sessionId) {
61628
+ coordinatorContexts.delete(sessionId);
61629
+ } else {
61630
+ globalCoordinatorContext = {
61631
+ isCoordinator: false
61632
+ };
61633
+ }
61634
+ }
61635
+ function isInCoordinatorContext(sessionId) {
61636
+ const ctx = sessionId ? coordinatorContexts.get(sessionId) : globalCoordinatorContext;
61637
+ if (!ctx || !ctx.isCoordinator) {
61638
+ return false;
61639
+ }
61640
+ const COORDINATOR_TIMEOUT_MS = 4 * 60 * 60 * 1000;
61641
+ if (ctx.activatedAt) {
61642
+ const elapsed = Date.now() - ctx.activatedAt;
61643
+ if (elapsed > COORDINATOR_TIMEOUT_MS) {
61644
+ if (sessionId) {
61645
+ coordinatorContexts.delete(sessionId);
61646
+ } else {
61647
+ globalCoordinatorContext = { isCoordinator: false };
61648
+ }
61649
+ return false;
61650
+ }
61651
+ }
61652
+ return true;
61653
+ }
61654
+
61655
+ // src/swarm-mail.ts
61330
61656
  import {
61331
61657
  existsSync as existsSync5,
61332
61658
  mkdirSync as mkdirSync4,
@@ -61382,6 +61708,21 @@ function clearSessionState(sessionID) {
61382
61708
  }
61383
61709
  } catch {}
61384
61710
  }
61711
+ function hasCoordinatorOverride(sessionID) {
61712
+ return isInCoordinatorContext(sessionID) || isInCoordinatorContext();
61713
+ }
61714
+ function formatCoordinatorOverrideError(params) {
61715
+ return JSON.stringify({
61716
+ error: "Coordinator-only override. Ask the coordinator to use this tool for stale or orphaned reservations.",
61717
+ guard: "coordinator_only",
61718
+ required_context: "coordinator",
61719
+ tool: params.tool,
61720
+ agent_name: params.state.agentName,
61721
+ project_key: params.state.projectKey,
61722
+ session_id: params.sessionID,
61723
+ suggestion: "If reservations are stale, notify the coordinator via swarmmail_send before releasing."
61724
+ }, null, 2);
61725
+ }
61385
61726
  var swarmmail_init = tool({
61386
61727
  description: "Initialize Swarm Mail session. Creates agent identity and registers with the embedded event store.",
61387
61728
  args: {
@@ -61636,6 +61977,13 @@ var swarmmail_release_all = tool({
61636
61977
  if (!state) {
61637
61978
  return JSON.stringify({ error: "Session not initialized. Call swarmmail_init first." }, null, 2);
61638
61979
  }
61980
+ if (!hasCoordinatorOverride(sessionID)) {
61981
+ return formatCoordinatorOverrideError({
61982
+ tool: "swarmmail_release_all",
61983
+ state,
61984
+ sessionID
61985
+ });
61986
+ }
61639
61987
  try {
61640
61988
  const result = await releaseAllSwarmFiles({
61641
61989
  projectPath: state.projectKey,
@@ -61666,6 +62014,13 @@ var swarmmail_release_agent = tool({
61666
62014
  if (!state) {
61667
62015
  return JSON.stringify({ error: "Session not initialized. Call swarmmail_init first." }, null, 2);
61668
62016
  }
62017
+ if (!hasCoordinatorOverride(sessionID)) {
62018
+ return formatCoordinatorOverrideError({
62019
+ tool: "swarmmail_release_agent",
62020
+ state,
62021
+ sessionID
62022
+ });
62023
+ }
61669
62024
  try {
61670
62025
  const result = await releaseSwarmFilesForAgent({
61671
62026
  projectPath: state.projectKey,
@@ -68015,7 +68370,8 @@ var swarm_spawn_subtask = tool({
68015
68370
  files: args2.files,
68016
68371
  shared_context: args2.shared_context,
68017
68372
  project_path: args2.project_path,
68018
- recovery_context: args2.recovery_context
68373
+ recovery_context: args2.recovery_context,
68374
+ model: args2.model
68019
68375
  });
68020
68376
  const { selectWorkerModel: selectWorkerModel2 } = await Promise.resolve().then(() => exports_model_selection);
68021
68377
  const subtask = {
@@ -70779,258 +71135,6 @@ function createMetrics(result, toolName) {
70779
71135
  };
70780
71136
  }
70781
71137
 
70782
- // src/planning-guardrails.ts
70783
- init_eval_capture();
70784
- var FILE_MODIFICATION_PATTERNS = [
70785
- /\bimplement\b/i,
70786
- /\bcreate\b.*\.(ts|js|tsx|jsx|py|rs|go|java|rb|swift|kt)/i,
70787
- /\badd\b.*\.(ts|js|tsx|jsx|py|rs|go|java|rb|swift|kt)/i,
70788
- /\bupdate\b.*\.(ts|js|tsx|jsx|py|rs|go|java|rb|swift|kt)/i,
70789
- /\bmodify\b/i,
70790
- /\brefactor\b/i,
70791
- /\bextract\b/i,
70792
- /\bmigrate\b/i,
70793
- /\bconvert\b/i,
70794
- /\brewrite\b/i,
70795
- /\bfix\b.*\.(ts|js|tsx|jsx|py|rs|go|java|rb|swift|kt)/i,
70796
- /\bwrite\b.*\.(ts|js|tsx|jsx|py|rs|go|java|rb|swift|kt)/i,
70797
- /src\//i,
70798
- /lib\//i,
70799
- /packages?\//i,
70800
- /components?\//i
70801
- ];
70802
- var TRACKING_PATTERNS = [
70803
- /\breview\b/i,
70804
- /\bcheck\b/i,
70805
- /\bverify\b/i,
70806
- /\btest\b.*pass/i,
70807
- /\brun\b.*test/i,
70808
- /\bdeploy\b/i,
70809
- /\bmerge\b/i,
70810
- /\bpr\b/i,
70811
- /\bpush\b/i,
70812
- /\bcommit\b/i
70813
- ];
70814
- function analyzeTodoWrite(args2) {
70815
- const todos = args2.todos;
70816
- if (!todos || !Array.isArray(todos) || todos.length < 6) {
70817
- return {
70818
- looksLikeParallelWork: false,
70819
- fileModificationCount: 0,
70820
- totalCount: todos?.length ?? 0
70821
- };
70822
- }
70823
- let fileModificationCount = 0;
70824
- for (const todo of todos) {
70825
- if (typeof todo !== "object" || todo === null)
70826
- continue;
70827
- const content = todo.content ?? "";
70828
- const isFileModification = FILE_MODIFICATION_PATTERNS.some((pattern2) => pattern2.test(content));
70829
- const isTracking = TRACKING_PATTERNS.some((pattern2) => pattern2.test(content));
70830
- if (isFileModification && !isTracking) {
70831
- fileModificationCount++;
70832
- }
70833
- }
70834
- const ratio = fileModificationCount / todos.length;
70835
- const looksLikeParallelWork = ratio >= 0.5 && fileModificationCount >= 4;
70836
- if (looksLikeParallelWork) {
70837
- return {
70838
- looksLikeParallelWork: true,
70839
- fileModificationCount,
70840
- totalCount: todos.length,
70841
- warning: `⚠️ This looks like a multi-file implementation plan (${fileModificationCount}/${todos.length} items are file modifications).
70842
-
70843
- Consider using swarm instead:
70844
- swarm_decompose → hive_create_epic → parallel task spawns
70845
-
70846
- TodoWrite is for tracking progress, not parallelizable implementation work.
70847
- Swarm workers can complete these ${fileModificationCount} tasks in parallel.
70848
-
70849
- (Continuing with todowrite - this is just a suggestion)`
70850
- };
70851
- }
70852
- return {
70853
- looksLikeParallelWork: false,
70854
- fileModificationCount,
70855
- totalCount: todos.length
70856
- };
70857
- }
70858
- function shouldAnalyzeTool(toolName) {
70859
- return toolName === "todowrite" || toolName === "TodoWrite";
70860
- }
70861
- var VIOLATION_PATTERNS = {
70862
- FILE_MODIFICATION_TOOLS: ["edit", "write"],
70863
- RESERVATION_TOOLS: ["swarmmail_reserve", "agentmail_reserve"],
70864
- TEST_EXECUTION_PATTERNS: [
70865
- /\bbun\s+test\b/i,
70866
- /\bnpm\s+(run\s+)?test/i,
70867
- /\byarn\s+(run\s+)?test/i,
70868
- /\bpnpm\s+(run\s+)?test/i,
70869
- /\bjest\b/i,
70870
- /\bvitest\b/i,
70871
- /\bmocha\b/i,
70872
- /\bava\b/i,
70873
- /\btape\b/i,
70874
- /\.test\.(ts|js|tsx|jsx)\b/i,
70875
- /\.spec\.(ts|js|tsx|jsx)\b/i
70876
- ]
70877
- };
70878
- function detectCoordinatorViolation(params) {
70879
- const { sessionId, epicId, toolName, toolArgs, agentContext, checkNoSpawn = false } = params;
70880
- if (agentContext !== "coordinator") {
70881
- return { isViolation: false };
70882
- }
70883
- if (VIOLATION_PATTERNS.FILE_MODIFICATION_TOOLS.includes(toolName)) {
70884
- const file2 = toolArgs.filePath || "";
70885
- const payload = { tool: toolName, file: file2 };
70886
- captureCoordinatorEvent({
70887
- session_id: sessionId,
70888
- epic_id: epicId,
70889
- timestamp: new Date().toISOString(),
70890
- event_type: "VIOLATION",
70891
- violation_type: "coordinator_edited_file",
70892
- payload
70893
- });
70894
- return {
70895
- isViolation: true,
70896
- violationType: "coordinator_edited_file",
70897
- message: `⚠️ Coordinator should not edit files directly. Coordinators should spawn workers to implement changes.`,
70898
- payload
70899
- };
70900
- }
70901
- if (toolName === "bash") {
70902
- const command = toolArgs.command || "";
70903
- const isTestCommand = VIOLATION_PATTERNS.TEST_EXECUTION_PATTERNS.some((pattern2) => pattern2.test(command));
70904
- if (isTestCommand) {
70905
- const payload = { tool: toolName, command };
70906
- captureCoordinatorEvent({
70907
- session_id: sessionId,
70908
- epic_id: epicId,
70909
- timestamp: new Date().toISOString(),
70910
- event_type: "VIOLATION",
70911
- violation_type: "coordinator_ran_tests",
70912
- payload
70913
- });
70914
- return {
70915
- isViolation: true,
70916
- violationType: "coordinator_ran_tests",
70917
- message: `⚠️ Coordinator should not run tests directly. Workers run tests as part of their implementation verification.`,
70918
- payload
70919
- };
70920
- }
70921
- }
70922
- if (VIOLATION_PATTERNS.RESERVATION_TOOLS.includes(toolName)) {
70923
- const paths = toolArgs.paths || [];
70924
- const payload = { tool: toolName, paths };
70925
- captureCoordinatorEvent({
70926
- session_id: sessionId,
70927
- epic_id: epicId,
70928
- timestamp: new Date().toISOString(),
70929
- event_type: "VIOLATION",
70930
- violation_type: "coordinator_reserved_files",
70931
- payload
70932
- });
70933
- return {
70934
- isViolation: true,
70935
- violationType: "coordinator_reserved_files",
70936
- message: `⚠️ Coordinator should not reserve files. Workers reserve files before editing to prevent conflicts.`,
70937
- payload
70938
- };
70939
- }
70940
- if (toolName === "hive_create_epic" && checkNoSpawn) {
70941
- const epicTitle = toolArgs.epic_title || "";
70942
- const subtasks = toolArgs.subtasks || [];
70943
- const payload = { epic_title: epicTitle, subtask_count: subtasks.length };
70944
- captureCoordinatorEvent({
70945
- session_id: sessionId,
70946
- epic_id: epicId,
70947
- timestamp: new Date().toISOString(),
70948
- event_type: "VIOLATION",
70949
- violation_type: "no_worker_spawned",
70950
- payload
70951
- });
70952
- return {
70953
- isViolation: true,
70954
- violationType: "no_worker_spawned",
70955
- message: `⚠️ Coordinator created decomposition without spawning workers. After hive_create_epic, use swarm_spawn_subtask for each task.`,
70956
- payload
70957
- };
70958
- }
70959
- if (toolName === "swarm_complete" || toolName === "hive_close") {
70960
- const payload = { tool: toolName };
70961
- captureCoordinatorEvent({
70962
- session_id: sessionId,
70963
- epic_id: epicId,
70964
- timestamp: new Date().toISOString(),
70965
- event_type: "VIOLATION",
70966
- violation_type: "worker_completed_without_review",
70967
- payload
70968
- });
70969
- return {
70970
- isViolation: true,
70971
- violationType: "worker_completed_without_review",
70972
- message: `⚠️ Coordinator should not complete worker tasks directly. Coordinators should review worker output using swarm_review and swarm_review_feedback.`,
70973
- payload
70974
- };
70975
- }
70976
- return { isViolation: false };
70977
- }
70978
- var coordinatorContexts = new Map;
70979
- var globalCoordinatorContext = {
70980
- isCoordinator: false
70981
- };
70982
- function setCoordinatorContext(ctx) {
70983
- const sessionId = ctx.sessionId;
70984
- if (sessionId) {
70985
- const existing = coordinatorContexts.get(sessionId) || { isCoordinator: false };
70986
- coordinatorContexts.set(sessionId, {
70987
- ...existing,
70988
- ...ctx,
70989
- activatedAt: ctx.isCoordinator ? Date.now() : existing.activatedAt
70990
- });
70991
- } else {
70992
- globalCoordinatorContext = {
70993
- ...globalCoordinatorContext,
70994
- ...ctx,
70995
- activatedAt: ctx.isCoordinator ? Date.now() : globalCoordinatorContext.activatedAt
70996
- };
70997
- }
70998
- }
70999
- function getCoordinatorContext(sessionId) {
71000
- if (sessionId) {
71001
- return { ...coordinatorContexts.get(sessionId) || { isCoordinator: false } };
71002
- }
71003
- return { ...globalCoordinatorContext };
71004
- }
71005
- function clearCoordinatorContext(sessionId) {
71006
- if (sessionId) {
71007
- coordinatorContexts.delete(sessionId);
71008
- } else {
71009
- globalCoordinatorContext = {
71010
- isCoordinator: false
71011
- };
71012
- }
71013
- }
71014
- function isInCoordinatorContext(sessionId) {
71015
- const ctx = sessionId ? coordinatorContexts.get(sessionId) : globalCoordinatorContext;
71016
- if (!ctx || !ctx.isCoordinator) {
71017
- return false;
71018
- }
71019
- const COORDINATOR_TIMEOUT_MS = 4 * 60 * 60 * 1000;
71020
- if (ctx.activatedAt) {
71021
- const elapsed = Date.now() - ctx.activatedAt;
71022
- if (elapsed > COORDINATOR_TIMEOUT_MS) {
71023
- if (sessionId) {
71024
- coordinatorContexts.delete(sessionId);
71025
- } else {
71026
- globalCoordinatorContext = { isCoordinator: false };
71027
- }
71028
- return false;
71029
- }
71030
- }
71031
- return true;
71032
- }
71033
-
71034
71138
  // src/coordinator-guard.ts
71035
71139
  class CoordinatorGuardError extends Error {
71036
71140
  violationType;
@@ -71298,6 +71402,7 @@ var logger = getLogger();
71298
71402
 
71299
71403
  // src/compaction-hook.ts
71300
71404
  init_eval_capture();
71405
+ init_skills();
71301
71406
  var _logger;
71302
71407
  function getLog() {
71303
71408
  if (!_logger) {
@@ -71319,6 +71424,9 @@ Context was compacted but the swarm is still running. **YOU ARE THE COORDINATOR.
71319
71424
 
71320
71425
  Your role is ORCHESTRATION, not implementation. The resume steps above (if present) tell you exactly what to do first.
71321
71426
 
71427
+ ## \uD83D\uDD27 ALWAYS-ON GUIDANCE
71428
+ ${getAlwaysOnGuidanceSkill({ role: "coordinator" })}
71429
+
71322
71430
  ---
71323
71431
 
71324
71432
  ## \uD83C\uDFAF WHAT GOOD LOOKS LIKE (Behavioral Examples)
@@ -71375,10 +71483,12 @@ You are the **COORDINATOR**. Your job is ORCHESTRATION, not implementation.
71375
71483
  ### What Coordinators Do:
71376
71484
  - ✅ Spawn workers for implementation tasks
71377
71485
  - ✅ Monitor worker progress via \`swarm_status\` and \`swarmmail_inbox\`
71486
+ - ✅ Use \`swarmmail_release_all\` to clear stale/orphaned reservations (coordinator override)
71378
71487
  - ✅ Review completed work with \`swarm_review\`
71379
71488
  - ✅ Unblock dependencies and resolve conflicts
71380
71489
  - ✅ Close the loop when epics complete
71381
71490
 
71491
+
71382
71492
  ### What Coordinators NEVER Do:
71383
71493
  - ❌ **NEVER** edit or write files directly
71384
71494
  - ❌ **NEVER** run tests with \`bash\`