opencode-swarm-plugin 0.32.0 → 0.34.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 (55) hide show
  1. package/.hive/issues.jsonl +12 -0
  2. package/.hive/memories.jsonl +255 -1
  3. package/.turbo/turbo-build.log +9 -10
  4. package/.turbo/turbo-test.log +343 -337
  5. package/CHANGELOG.md +358 -0
  6. package/README.md +152 -179
  7. package/bin/swarm.test.ts +303 -1
  8. package/bin/swarm.ts +473 -16
  9. package/dist/compaction-hook.d.ts +1 -1
  10. package/dist/compaction-hook.d.ts.map +1 -1
  11. package/dist/index.d.ts +112 -0
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +12380 -131
  14. package/dist/logger.d.ts +34 -0
  15. package/dist/logger.d.ts.map +1 -0
  16. package/dist/observability-tools.d.ts +116 -0
  17. package/dist/observability-tools.d.ts.map +1 -0
  18. package/dist/plugin.js +12254 -119
  19. package/dist/skills.d.ts.map +1 -1
  20. package/dist/swarm-orchestrate.d.ts +105 -0
  21. package/dist/swarm-orchestrate.d.ts.map +1 -1
  22. package/dist/swarm-prompts.d.ts +113 -2
  23. package/dist/swarm-prompts.d.ts.map +1 -1
  24. package/dist/swarm-research.d.ts +127 -0
  25. package/dist/swarm-research.d.ts.map +1 -0
  26. package/dist/swarm-review.d.ts.map +1 -1
  27. package/dist/swarm.d.ts +73 -1
  28. package/dist/swarm.d.ts.map +1 -1
  29. package/evals/compaction-resumption.eval.ts +289 -0
  30. package/evals/coordinator-behavior.eval.ts +307 -0
  31. package/evals/fixtures/compaction-cases.ts +350 -0
  32. package/evals/scorers/compaction-scorers.ts +305 -0
  33. package/evals/scorers/index.ts +12 -0
  34. package/examples/plugin-wrapper-template.ts +297 -8
  35. package/package.json +6 -2
  36. package/src/compaction-hook.test.ts +617 -1
  37. package/src/compaction-hook.ts +291 -18
  38. package/src/index.ts +54 -1
  39. package/src/logger.test.ts +189 -0
  40. package/src/logger.ts +135 -0
  41. package/src/observability-tools.test.ts +346 -0
  42. package/src/observability-tools.ts +594 -0
  43. package/src/skills.integration.test.ts +137 -1
  44. package/src/skills.test.ts +42 -1
  45. package/src/skills.ts +8 -4
  46. package/src/swarm-orchestrate.test.ts +123 -0
  47. package/src/swarm-orchestrate.ts +183 -0
  48. package/src/swarm-prompts.test.ts +553 -1
  49. package/src/swarm-prompts.ts +406 -4
  50. package/src/swarm-research.integration.test.ts +544 -0
  51. package/src/swarm-research.test.ts +698 -0
  52. package/src/swarm-research.ts +472 -0
  53. package/src/swarm-review.test.ts +177 -0
  54. package/src/swarm-review.ts +12 -47
  55. package/src/swarm.ts +6 -3
@@ -464,6 +464,29 @@ swarm_complete(
464
464
 
465
465
  **DO NOT manually close the cell with hive_close.** Use swarm_complete.
466
466
 
467
+ ## [ON-DEMAND RESEARCH]
468
+
469
+ If you encounter unknown API behavior or version-specific issues:
470
+
471
+ 1. **Check semantic-memory first:**
472
+ \`semantic-memory_find(query="<library> <version> <topic>", limit=3, expand=true)\`
473
+
474
+ 2. **If not found, spawn researcher:**
475
+ \`swarm_spawn_researcher(research_id="{bead_id}-research", epic_id="{epic_id}", tech_stack=["<library>"], project_path="{project_path}")\`
476
+ Then spawn with Task tool: \`Task(subagent_type="swarm/researcher", prompt="<from above>")\`
477
+
478
+ 3. **Wait for research, then continue**
479
+
480
+ **Research triggers:**
481
+ - "I'm not sure how this API works in version X"
482
+ - "This might have breaking changes"
483
+ - "The docs I remember might be outdated"
484
+
485
+ **Don't research:**
486
+ - Standard patterns you're confident about
487
+ - Well-documented, stable APIs
488
+ - Obvious implementations
489
+
467
490
  ## [SWARM MAIL COMMUNICATION]
468
491
 
469
492
  ### Check Inbox Regularly
@@ -551,6 +574,124 @@ Other cell operations:
551
574
 
552
575
  Begin now.`;
553
576
 
577
+ /**
578
+ * Researcher prompt template for documentation discovery
579
+ *
580
+ * Spawned BEFORE decomposition to gather technology documentation.
581
+ * Researchers receive an EXPLICIT list of technologies to research from the coordinator.
582
+ * They dynamically discover WHAT TOOLS are available to fetch docs.
583
+ * Output: condensed summary for shared_context + detailed findings in semantic-memory.
584
+ */
585
+ export const RESEARCHER_PROMPT = `You are a swarm researcher gathering documentation for: **{research_id}**
586
+
587
+ ## [IDENTITY]
588
+ Agent: (assigned at spawn)
589
+ Research Task: {research_id}
590
+ Epic: {epic_id}
591
+
592
+ ## [MISSION]
593
+ Gather comprehensive documentation for the specified technologies to inform task decomposition.
594
+
595
+ **COORDINATOR PROVIDED THESE TECHNOLOGIES TO RESEARCH:**
596
+ {tech_stack}
597
+
598
+ You do NOT discover what to research - the coordinator already decided that.
599
+ You DO discover what TOOLS are available to fetch documentation.
600
+
601
+ ## [OUTPUT MODE]
602
+ {check_upgrades}
603
+
604
+ ## [WORKFLOW]
605
+
606
+ ### Step 1: Initialize (MANDATORY FIRST)
607
+ \`\`\`
608
+ swarmmail_init(project_path="{project_path}", task_description="{research_id}: Documentation research")
609
+ \`\`\`
610
+
611
+ ### Step 2: Discover Available Documentation Tools
612
+ Check what's available for fetching docs:
613
+ - **next-devtools**: \`nextjs_docs\` for Next.js documentation
614
+ - **context7**: Library documentation lookup (\`use context7\` in prompts)
615
+ - **fetch**: General web fetching for official docs sites
616
+ - **pdf-brain**: Internal knowledge base search
617
+
618
+ **Don't assume** - check which tools exist in your environment.
619
+
620
+ ### Step 3: Read Installed Versions
621
+ For each technology in the tech stack:
622
+ 1. Check package.json (or equivalent) for installed version
623
+ 2. Record exact version numbers
624
+ 3. Note any version constraints (^, ~, etc.)
625
+
626
+ ### Step 4: Fetch Documentation
627
+ For EACH technology in the list:
628
+ - Use the most appropriate tool (Next.js → nextjs_docs, libraries → context7, others → fetch)
629
+ - Fetch documentation for the INSTALLED version (not latest, unless --check-upgrades)
630
+ - Focus on: API changes, breaking changes, migration guides, best practices
631
+ - Extract key patterns, gotchas, and compatibility notes
632
+
633
+ **If --check-upgrades mode:**
634
+ - ALSO fetch docs for the LATEST version
635
+ - Compare installed vs latest
636
+ - Note breaking changes, new features, migration complexity
637
+
638
+ ### Step 5: Store Detailed Findings
639
+ For EACH technology, store in semantic-memory:
640
+ \`\`\`
641
+ semantic-memory_store(
642
+ information="<technology-name> <version>: <key patterns, gotchas, API changes, compatibility notes>",
643
+ tags="research, <tech-name>, documentation, {epic_id}"
644
+ )
645
+ \`\`\`
646
+
647
+ **Why store individually?** Future agents can search by technology name.
648
+
649
+ ### Step 6: Broadcast Summary
650
+ Send condensed findings to coordinator:
651
+ \`\`\`
652
+ swarmmail_send(
653
+ to=["coordinator"],
654
+ subject="Research Complete: {research_id}",
655
+ body="<brief summary - see semantic-memory for details>",
656
+ thread_id="{epic_id}"
657
+ )
658
+ \`\`\`
659
+
660
+ ### Step 7: Return Structured Output
661
+ Output JSON with:
662
+ \`\`\`json
663
+ {
664
+ "technologies": [
665
+ {
666
+ "name": "string",
667
+ "installed_version": "string",
668
+ "latest_version": "string | null", // Only if --check-upgrades
669
+ "key_patterns": ["string"],
670
+ "gotchas": ["string"],
671
+ "breaking_changes": ["string"], // Only if --check-upgrades
672
+ "memory_id": "string" // ID of semantic-memory entry
673
+ }
674
+ ],
675
+ "summary": "string" // Condensed summary for shared_context
676
+ }
677
+ \`\`\`
678
+
679
+ ## [CRITICAL REQUIREMENTS]
680
+
681
+ **NON-NEGOTIABLE:**
682
+ 1. Step 1 (swarmmail_init) MUST be first
683
+ 2. Research ONLY the technologies the coordinator specified
684
+ 3. Fetch docs for INSTALLED versions (unless --check-upgrades)
685
+ 4. Store detailed findings in semantic-memory (one per technology)
686
+ 5. Return condensed summary for coordinator (full details in memory)
687
+ 6. Use appropriate doc tools (nextjs_docs for Next.js, context7 for libraries, etc.)
688
+
689
+ **Output goes TWO places:**
690
+ - **semantic-memory**: Detailed findings (searchable by future agents)
691
+ - **Return JSON**: Condensed summary (for coordinator's shared_context)
692
+
693
+ Begin research now.`;
694
+
554
695
  /**
555
696
  * Coordinator post-worker checklist - MANDATORY review loop
556
697
  *
@@ -602,10 +743,32 @@ swarm_review_feedback(
602
743
  )
603
744
  \`\`\`
604
745
 
605
- ### Step 5: ONLY THEN Continue
606
- - If approved: Close the cell, spawn next worker
607
- - If needs_changes: Worker gets feedback, retries (max 3 attempts)
608
- - If 3 failures: Mark blocked, escalate to human
746
+ ### Step 5: Take Action Based on Review
747
+
748
+ **If APPROVED:**
749
+ - Close the cell with hive_close
750
+ - Spawn next worker (if any) using swarm_spawn_subtask
751
+
752
+ **If NEEDS_CHANGES:**
753
+ - Generate retry prompt:
754
+ \`\`\`
755
+ swarm_spawn_retry(
756
+ bead_id="{task_id}",
757
+ epic_id="{epic_id}",
758
+ original_prompt="<original prompt>",
759
+ attempt=<current_attempt>,
760
+ issues="<JSON from swarm_review_feedback>",
761
+ diff="<git diff of previous changes>",
762
+ files=[{files_touched}],
763
+ project_path="{project_key}"
764
+ )
765
+ \`\`\`
766
+ - Spawn new worker with Task() using the retry prompt
767
+ - Increment attempt counter (max 3 attempts)
768
+
769
+ **If 3 FAILURES:**
770
+ - Mark task as blocked: \`hive_update(id="{task_id}", status="blocked")\`
771
+ - Escalate to human - likely an architectural problem, not execution issue
609
772
 
610
773
  **⚠️ DO NOT spawn the next worker until review is complete.**
611
774
  `;
@@ -656,6 +819,30 @@ should describe what needs to be fixed.`;
656
819
  // Helper Functions
657
820
  // ============================================================================
658
821
 
822
+ /**
823
+ * Format the researcher prompt for a documentation research task
824
+ */
825
+ export function formatResearcherPrompt(params: {
826
+ research_id: string;
827
+ epic_id: string;
828
+ tech_stack: string[];
829
+ project_path: string;
830
+ check_upgrades: boolean;
831
+ }): string {
832
+ const techList = params.tech_stack.map((t) => `- ${t}`).join("\n");
833
+
834
+ const upgradesMode = params.check_upgrades
835
+ ? "**UPGRADE COMPARISON MODE**: Fetch docs for BOTH installed AND latest versions. Compare and note breaking changes."
836
+ : "**DEFAULT MODE**: Fetch docs for INSTALLED versions only (from lockfiles).";
837
+
838
+ return RESEARCHER_PROMPT
839
+ .replace(/{research_id}/g, params.research_id)
840
+ .replace(/{epic_id}/g, params.epic_id)
841
+ .replace("{tech_stack}", techList)
842
+ .replace("{project_path}", params.project_path)
843
+ .replace("{check_upgrades}", upgradesMode);
844
+ }
845
+
659
846
  /**
660
847
  * Format the V2 subtask prompt for a specific agent
661
848
  */
@@ -937,6 +1124,219 @@ export const swarm_spawn_subtask = tool({
937
1124
  },
938
1125
  });
939
1126
 
1127
+ /**
1128
+ * Prepare a researcher task for spawning with Task tool
1129
+ *
1130
+ * Generates a prompt that tells the researcher to fetch documentation for specific technologies.
1131
+ * Returns JSON that can be directly used with Task tool.
1132
+ */
1133
+ export const swarm_spawn_researcher = tool({
1134
+ description:
1135
+ "Prepare a research task for spawning. Returns prompt for gathering technology documentation. Researcher fetches docs and stores findings in semantic-memory.",
1136
+ args: {
1137
+ research_id: tool.schema.string().describe("Unique ID for this research task"),
1138
+ epic_id: tool.schema.string().describe("Parent epic ID"),
1139
+ tech_stack: tool.schema
1140
+ .array(tool.schema.string())
1141
+ .describe("Explicit list of technologies to research (from coordinator)"),
1142
+ project_path: tool.schema
1143
+ .string()
1144
+ .describe("Absolute project path for swarmmail_init"),
1145
+ check_upgrades: tool.schema
1146
+ .boolean()
1147
+ .optional()
1148
+ .describe("If true, compare installed vs latest versions (default: false)"),
1149
+ },
1150
+ async execute(args) {
1151
+ const prompt = formatResearcherPrompt({
1152
+ research_id: args.research_id,
1153
+ epic_id: args.epic_id,
1154
+ tech_stack: args.tech_stack,
1155
+ project_path: args.project_path,
1156
+ check_upgrades: args.check_upgrades ?? false,
1157
+ });
1158
+
1159
+ return JSON.stringify(
1160
+ {
1161
+ prompt,
1162
+ research_id: args.research_id,
1163
+ epic_id: args.epic_id,
1164
+ tech_stack: args.tech_stack,
1165
+ project_path: args.project_path,
1166
+ check_upgrades: args.check_upgrades ?? false,
1167
+ subagent_type: "swarm/researcher",
1168
+ expected_output: {
1169
+ technologies: [
1170
+ {
1171
+ name: "string",
1172
+ installed_version: "string",
1173
+ latest_version: "string | null",
1174
+ key_patterns: ["string"],
1175
+ gotchas: ["string"],
1176
+ breaking_changes: ["string"],
1177
+ memory_id: "string",
1178
+ },
1179
+ ],
1180
+ summary: "string",
1181
+ },
1182
+ },
1183
+ null,
1184
+ 2,
1185
+ );
1186
+ },
1187
+ });
1188
+
1189
+ /**
1190
+ * Generate retry prompt for a worker that needs to fix issues from review feedback
1191
+ *
1192
+ * Coordinators use this when swarm_review_feedback returns "needs_changes".
1193
+ * Creates a new worker spawn with context about what went wrong and what to fix.
1194
+ */
1195
+ export const swarm_spawn_retry = tool({
1196
+ description:
1197
+ "Generate retry prompt for a worker that failed review. Includes issues from previous attempt, diff if provided, and standard worker contract.",
1198
+ args: {
1199
+ bead_id: tool.schema.string().describe("Original subtask bead ID"),
1200
+ epic_id: tool.schema.string().describe("Parent epic bead ID"),
1201
+ original_prompt: tool.schema.string().describe("The prompt given to failed worker"),
1202
+ attempt: tool.schema.number().int().min(1).max(3).describe("Current attempt number (1, 2, or 3)"),
1203
+ issues: tool.schema.string().describe("JSON array of ReviewIssue objects from swarm_review_feedback"),
1204
+ diff: tool.schema
1205
+ .string()
1206
+ .optional()
1207
+ .describe("Git diff of previous changes"),
1208
+ files: tool.schema
1209
+ .array(tool.schema.string())
1210
+ .describe("Files to modify (from original subtask)"),
1211
+ project_path: tool.schema
1212
+ .string()
1213
+ .optional()
1214
+ .describe("Absolute project path for swarmmail_init"),
1215
+ },
1216
+ async execute(args) {
1217
+ // Validate attempt number
1218
+ if (args.attempt > 3) {
1219
+ throw new Error(
1220
+ `Retry attempt ${args.attempt} exceeds maximum of 3. After 3 failures, task should be marked blocked.`,
1221
+ );
1222
+ }
1223
+
1224
+ // Parse issues
1225
+ let issuesArray: Array<{
1226
+ file: string;
1227
+ line: number;
1228
+ issue: string;
1229
+ suggestion: string;
1230
+ }> = [];
1231
+ try {
1232
+ issuesArray = JSON.parse(args.issues);
1233
+ } catch (e) {
1234
+ // If issues is not valid JSON, treat as empty array
1235
+ issuesArray = [];
1236
+ }
1237
+
1238
+ // Format issues section
1239
+ const issuesSection = issuesArray.length > 0
1240
+ ? `## ISSUES FROM PREVIOUS ATTEMPT
1241
+
1242
+ The previous attempt had the following issues that need to be fixed:
1243
+
1244
+ ${issuesArray
1245
+ .map(
1246
+ (issue, idx) =>
1247
+ `**${idx + 1}. ${issue.file}:${issue.line}**
1248
+ - **Issue**: ${issue.issue}
1249
+ - **Suggestion**: ${issue.suggestion}`,
1250
+ )
1251
+ .join("\n\n")}
1252
+
1253
+ **Critical**: Fix these issues while preserving any working changes from the previous attempt.`
1254
+ : "";
1255
+
1256
+ // Format diff section
1257
+ const diffSection = args.diff
1258
+ ? `## PREVIOUS ATTEMPT
1259
+
1260
+ Here's what was tried in the previous attempt:
1261
+
1262
+ \`\`\`diff
1263
+ ${args.diff}
1264
+ \`\`\`
1265
+
1266
+ Review this carefully - some changes may be correct and should be preserved.`
1267
+ : "";
1268
+
1269
+ // Build the retry prompt
1270
+ const retryPrompt = `⚠️ **RETRY ATTEMPT ${args.attempt}/3**
1271
+
1272
+ This is a retry of a previously attempted subtask. The coordinator reviewed the previous attempt and found issues that need to be fixed.
1273
+
1274
+ ${issuesSection}
1275
+
1276
+ ${diffSection}
1277
+
1278
+ ## ORIGINAL TASK
1279
+
1280
+ ${args.original_prompt}
1281
+
1282
+ ## YOUR MISSION
1283
+
1284
+ 1. **Understand what went wrong** - Read the issues carefully
1285
+ 2. **Fix the specific problems** - Address each issue listed above
1286
+ 3. **Preserve working code** - Don't throw away correct changes from previous attempt
1287
+ 4. **Follow the standard worker contract** - See below
1288
+
1289
+ ## MANDATORY WORKER CONTRACT
1290
+
1291
+ ### Step 1: Initialize (REQUIRED FIRST)
1292
+ \`\`\`
1293
+ swarmmail_init(project_path="${args.project_path || "$PWD"}", task_description="${args.bead_id}: Retry ${args.attempt}/3")
1294
+ \`\`\`
1295
+
1296
+ ### Step 2: Reserve Files
1297
+ \`\`\`
1298
+ swarmmail_reserve(
1299
+ paths=${JSON.stringify(args.files)},
1300
+ reason="${args.bead_id}: Retry attempt ${args.attempt}",
1301
+ exclusive=true
1302
+ )
1303
+ \`\`\`
1304
+
1305
+ ### Step 3: Fix the Issues
1306
+ - Address each issue listed above
1307
+ - Run tests to verify fixes
1308
+ - Don't introduce new bugs
1309
+
1310
+ ### Step 4: Complete
1311
+ \`\`\`
1312
+ swarm_complete(
1313
+ project_key="${args.project_path || "$PWD"}",
1314
+ agent_name="<your-agent-name>",
1315
+ bead_id="${args.bead_id}",
1316
+ summary="Fixed issues from review: <brief summary>",
1317
+ files_touched=[<files you modified>]
1318
+ )
1319
+ \`\`\`
1320
+
1321
+ **Remember**: This is attempt ${args.attempt} of 3. If this fails review again, there may be an architectural problem that needs human intervention.
1322
+
1323
+ Begin work now.`;
1324
+
1325
+ return JSON.stringify(
1326
+ {
1327
+ prompt: retryPrompt,
1328
+ bead_id: args.bead_id,
1329
+ attempt: args.attempt,
1330
+ max_attempts: 3,
1331
+ files: args.files,
1332
+ issues_count: issuesArray.length,
1333
+ },
1334
+ null,
1335
+ 2,
1336
+ );
1337
+ },
1338
+ });
1339
+
940
1340
  /**
941
1341
  * Generate self-evaluation prompt
942
1342
  */
@@ -1125,6 +1525,8 @@ export const swarm_plan_prompt = tool({
1125
1525
  export const promptTools = {
1126
1526
  swarm_subtask_prompt,
1127
1527
  swarm_spawn_subtask,
1528
+ swarm_spawn_researcher,
1529
+ swarm_spawn_retry,
1128
1530
  swarm_evaluation_prompt,
1129
1531
  swarm_plan_prompt,
1130
1532
  };