opencode-swarm-plugin 0.31.7 → 0.33.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 (62) hide show
  1. package/.turbo/turbo-build.log +4 -4
  2. package/.turbo/turbo-test.log +324 -316
  3. package/CHANGELOG.md +394 -0
  4. package/README.md +129 -181
  5. package/bin/swarm.test.ts +31 -0
  6. package/bin/swarm.ts +635 -140
  7. package/dist/compaction-hook.d.ts +1 -1
  8. package/dist/compaction-hook.d.ts.map +1 -1
  9. package/dist/hive.d.ts.map +1 -1
  10. package/dist/index.d.ts +17 -2
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +653 -139
  13. package/dist/memory-tools.d.ts.map +1 -1
  14. package/dist/memory.d.ts +5 -4
  15. package/dist/memory.d.ts.map +1 -1
  16. package/dist/observability-tools.d.ts +116 -0
  17. package/dist/observability-tools.d.ts.map +1 -0
  18. package/dist/plugin.js +648 -136
  19. package/dist/skills.d.ts.map +1 -1
  20. package/dist/swarm-orchestrate.d.ts +29 -5
  21. package/dist/swarm-orchestrate.d.ts.map +1 -1
  22. package/dist/swarm-prompts.d.ts +66 -0
  23. package/dist/swarm-prompts.d.ts.map +1 -1
  24. package/dist/swarm.d.ts +17 -2
  25. package/dist/swarm.d.ts.map +1 -1
  26. package/evals/lib/{data-loader.test.ts → data-loader.evalite-test.ts} +7 -6
  27. package/evals/lib/data-loader.ts +1 -1
  28. package/evals/scorers/{outcome-scorers.test.ts → outcome-scorers.evalite-test.ts} +1 -1
  29. package/examples/plugin-wrapper-template.ts +316 -12
  30. package/global-skills/swarm-coordination/SKILL.md +118 -8
  31. package/package.json +3 -2
  32. package/src/compaction-hook.ts +5 -3
  33. package/src/hive.integration.test.ts +83 -1
  34. package/src/hive.ts +37 -12
  35. package/src/index.ts +25 -1
  36. package/src/mandate-storage.integration.test.ts +601 -0
  37. package/src/memory-tools.ts +6 -4
  38. package/src/memory.integration.test.ts +117 -49
  39. package/src/memory.test.ts +41 -217
  40. package/src/memory.ts +12 -8
  41. package/src/observability-tools.test.ts +346 -0
  42. package/src/observability-tools.ts +594 -0
  43. package/src/repo-crawl.integration.test.ts +441 -0
  44. package/src/skills.integration.test.ts +1192 -0
  45. package/src/skills.test.ts +42 -1
  46. package/src/skills.ts +8 -4
  47. package/src/structured.integration.test.ts +817 -0
  48. package/src/swarm-deferred.integration.test.ts +157 -0
  49. package/src/swarm-deferred.test.ts +38 -0
  50. package/src/swarm-mail.integration.test.ts +15 -19
  51. package/src/swarm-orchestrate.integration.test.ts +282 -0
  52. package/src/swarm-orchestrate.test.ts +123 -0
  53. package/src/swarm-orchestrate.ts +279 -201
  54. package/src/swarm-prompts.test.ts +481 -0
  55. package/src/swarm-prompts.ts +297 -0
  56. package/src/swarm-research.integration.test.ts +544 -0
  57. package/src/swarm-research.test.ts +698 -0
  58. package/src/swarm-research.ts +472 -0
  59. package/src/swarm-review.integration.test.ts +290 -0
  60. package/src/swarm.integration.test.ts +23 -20
  61. package/src/swarm.ts +6 -3
  62. package/src/tool-adapter.integration.test.ts +1221 -0
@@ -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,183 @@ 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
+
695
+ /**
696
+ * Coordinator post-worker checklist - MANDATORY review loop
697
+ *
698
+ * This checklist is returned to coordinators after spawning a worker.
699
+ * It ensures coordinators REVIEW worker output before spawning the next worker.
700
+ */
701
+ export const COORDINATOR_POST_WORKER_CHECKLIST = `
702
+ ## ⚠️ MANDATORY: Post-Worker Review (DO THIS IMMEDIATELY)
703
+
704
+ **A worker just returned. Before doing ANYTHING else, complete this checklist:**
705
+
706
+ ### Step 1: Check Swarm Mail
707
+ \`\`\`
708
+ swarmmail_inbox()
709
+ swarmmail_read_message(message_id=N) // Read any messages from the worker
710
+ \`\`\`
711
+
712
+ ### Step 2: Review the Work
713
+ \`\`\`
714
+ swarm_review(
715
+ project_key="{project_key}",
716
+ epic_id="{epic_id}",
717
+ task_id="{task_id}",
718
+ files_touched=[{files_touched}]
719
+ )
720
+ \`\`\`
721
+
722
+ This generates a review prompt with:
723
+ - Epic context (what we're trying to achieve)
724
+ - Subtask requirements
725
+ - Git diff of changes
726
+ - Dependency status
727
+
728
+ ### Step 3: Evaluate Against Criteria
729
+ - Does the work fulfill the subtask requirements?
730
+ - Does it serve the overall epic goal?
731
+ - Does it enable downstream tasks?
732
+ - Type safety, no obvious bugs?
733
+
734
+ ### Step 4: Send Feedback
735
+ \`\`\`
736
+ swarm_review_feedback(
737
+ project_key="{project_key}",
738
+ task_id="{task_id}",
739
+ worker_id="{worker_id}",
740
+ status="approved", // or "needs_changes"
741
+ summary="<brief summary>",
742
+ issues="[]" // or "[{file, line, issue, suggestion}]"
743
+ )
744
+ \`\`\`
745
+
746
+ ### Step 5: ONLY THEN Continue
747
+ - If approved: Close the cell, spawn next worker
748
+ - If needs_changes: Worker gets feedback, retries (max 3 attempts)
749
+ - If 3 failures: Mark blocked, escalate to human
750
+
751
+ **⚠️ DO NOT spawn the next worker until review is complete.**
752
+ `;
753
+
554
754
  /**
555
755
  * Prompt for self-evaluation before completing a subtask.
556
756
  *
@@ -597,6 +797,30 @@ should describe what needs to be fixed.`;
597
797
  // Helper Functions
598
798
  // ============================================================================
599
799
 
800
+ /**
801
+ * Format the researcher prompt for a documentation research task
802
+ */
803
+ export function formatResearcherPrompt(params: {
804
+ research_id: string;
805
+ epic_id: string;
806
+ tech_stack: string[];
807
+ project_path: string;
808
+ check_upgrades: boolean;
809
+ }): string {
810
+ const techList = params.tech_stack.map((t) => `- ${t}`).join("\n");
811
+
812
+ const upgradesMode = params.check_upgrades
813
+ ? "**UPGRADE COMPARISON MODE**: Fetch docs for BOTH installed AND latest versions. Compare and note breaking changes."
814
+ : "**DEFAULT MODE**: Fetch docs for INSTALLED versions only (from lockfiles).";
815
+
816
+ return RESEARCHER_PROMPT
817
+ .replace(/{research_id}/g, params.research_id)
818
+ .replace(/{epic_id}/g, params.epic_id)
819
+ .replace("{tech_stack}", techList)
820
+ .replace("{project_path}", params.project_path)
821
+ .replace("{check_upgrades}", upgradesMode);
822
+ }
823
+
600
824
  /**
601
825
  * Format the V2 subtask prompt for a specific agent
602
826
  */
@@ -852,6 +1076,15 @@ export const swarm_spawn_subtask = tool({
852
1076
 
853
1077
  const selectedModel = selectWorkerModel(subtask, config);
854
1078
 
1079
+ // Generate post-completion instructions for coordinator
1080
+ const filesJoined = args.files.map(f => `"${f}"`).join(", ");
1081
+ const postCompletionInstructions = COORDINATOR_POST_WORKER_CHECKLIST
1082
+ .replace(/{project_key}/g, args.project_path || "$PWD")
1083
+ .replace(/{epic_id}/g, args.epic_id)
1084
+ .replace(/{task_id}/g, args.bead_id)
1085
+ .replace(/{files_touched}/g, filesJoined)
1086
+ .replace(/{worker_id}/g, "worker"); // Will be filled by actual worker name
1087
+
855
1088
  return JSON.stringify(
856
1089
  {
857
1090
  prompt,
@@ -861,6 +1094,69 @@ export const swarm_spawn_subtask = tool({
861
1094
  project_path: args.project_path,
862
1095
  recovery_context: args.recovery_context,
863
1096
  recommended_model: selectedModel,
1097
+ post_completion_instructions: postCompletionInstructions,
1098
+ },
1099
+ null,
1100
+ 2,
1101
+ );
1102
+ },
1103
+ });
1104
+
1105
+ /**
1106
+ * Prepare a researcher task for spawning with Task tool
1107
+ *
1108
+ * Generates a prompt that tells the researcher to fetch documentation for specific technologies.
1109
+ * Returns JSON that can be directly used with Task tool.
1110
+ */
1111
+ export const swarm_spawn_researcher = tool({
1112
+ description:
1113
+ "Prepare a research task for spawning. Returns prompt for gathering technology documentation. Researcher fetches docs and stores findings in semantic-memory.",
1114
+ args: {
1115
+ research_id: tool.schema.string().describe("Unique ID for this research task"),
1116
+ epic_id: tool.schema.string().describe("Parent epic ID"),
1117
+ tech_stack: tool.schema
1118
+ .array(tool.schema.string())
1119
+ .describe("Explicit list of technologies to research (from coordinator)"),
1120
+ project_path: tool.schema
1121
+ .string()
1122
+ .describe("Absolute project path for swarmmail_init"),
1123
+ check_upgrades: tool.schema
1124
+ .boolean()
1125
+ .optional()
1126
+ .describe("If true, compare installed vs latest versions (default: false)"),
1127
+ },
1128
+ async execute(args) {
1129
+ const prompt = formatResearcherPrompt({
1130
+ research_id: args.research_id,
1131
+ epic_id: args.epic_id,
1132
+ tech_stack: args.tech_stack,
1133
+ project_path: args.project_path,
1134
+ check_upgrades: args.check_upgrades ?? false,
1135
+ });
1136
+
1137
+ return JSON.stringify(
1138
+ {
1139
+ prompt,
1140
+ research_id: args.research_id,
1141
+ epic_id: args.epic_id,
1142
+ tech_stack: args.tech_stack,
1143
+ project_path: args.project_path,
1144
+ check_upgrades: args.check_upgrades ?? false,
1145
+ subagent_type: "swarm/researcher",
1146
+ expected_output: {
1147
+ technologies: [
1148
+ {
1149
+ name: "string",
1150
+ installed_version: "string",
1151
+ latest_version: "string | null",
1152
+ key_patterns: ["string"],
1153
+ gotchas: ["string"],
1154
+ breaking_changes: ["string"],
1155
+ memory_id: "string",
1156
+ },
1157
+ ],
1158
+ summary: "string",
1159
+ },
864
1160
  },
865
1161
  null,
866
1162
  2,
@@ -1056,6 +1352,7 @@ export const swarm_plan_prompt = tool({
1056
1352
  export const promptTools = {
1057
1353
  swarm_subtask_prompt,
1058
1354
  swarm_spawn_subtask,
1355
+ swarm_spawn_researcher,
1059
1356
  swarm_evaluation_prompt,
1060
1357
  swarm_plan_prompt,
1061
1358
  };