opencode-swarm-plugin 0.24.0 → 0.25.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.
@@ -1,9 +1,9 @@
1
1
  $ bun build ./src/index.ts --outdir ./dist --target node --external @electric-sql/pglite --external swarm-mail && bun build ./src/plugin.ts --outfile ./dist/plugin.js --target node --external @electric-sql/pglite --external swarm-mail && tsc
2
- Bundled 196 modules in 42ms
2
+ Bundled 196 modules in 32ms
3
3
 
4
4
  index.js 1.16 MB (entry point)
5
5
 
6
- Bundled 197 modules in 36ms
6
+ Bundled 197 modules in 31ms
7
7
 
8
8
  plugin.js 1.13 MB (entry point)
9
9
 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # opencode-swarm-plugin
2
2
 
3
+ ## 0.25.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`b70ae35`](https://github.com/joelhooks/swarm-tools/commit/b70ae352876515bdfe68511d72bb472c85b7fdfc) Thanks [@joelhooks](https://github.com/joelhooks)! - Add Socratic planning phase and improved worker prompts to swarm setup
8
+
9
+ **SWARM_COMMAND template:**
10
+
11
+ - Added Phase 0: Socratic Planning - asks clarifying questions before decomposing
12
+ - Supports `--fast`, `--auto`, `--confirm-only` flags to skip questions
13
+ - ONE question at a time with concrete options and recommendations
14
+
15
+ **Worker agent template:**
16
+
17
+ - Reinforces the 9-step survival checklist from SUBTASK_PROMPT_V2
18
+ - Explicitly lists all steps with emphasis on non-negotiables
19
+ - Explains WHY skipping steps causes problems (lost work, conflicts, etc.)
20
+
21
+ **Agent path consolidation:**
22
+
23
+ - Now creates nested paths: `~/.config/opencode/agent/swarm/worker.md`
24
+ - Matches `Task(subagent_type="swarm/worker")` format
25
+ - Cleans up legacy flat files (`swarm-worker.md`) on reinstall
26
+
27
+ To get the new prompts, run `swarm setup` and choose "Reinstall everything".
28
+
3
29
  ## 0.24.0
4
30
 
5
31
  ### Minor Changes
package/bin/swarm.ts CHANGED
@@ -883,7 +883,7 @@ const SWARM_COMMAND = `---
883
883
  description: Decompose task into parallel subtasks and coordinate agents
884
884
  ---
885
885
 
886
- You are a swarm coordinator. Decompose the task into beads and spawn parallel agents.
886
+ You are a swarm coordinator. Your job is to clarify the task, decompose it into beads, and spawn parallel agents.
887
887
 
888
888
  ## Task
889
889
 
@@ -891,42 +891,84 @@ $ARGUMENTS
891
891
 
892
892
  ## Workflow
893
893
 
894
- ### 1. Initialize
894
+ ### Phase 0: Socratic Planning (INTERACTIVE - unless --fast)
895
+
896
+ **Before decomposing, clarify the task with the user.**
897
+
898
+ Check for flags in the task:
899
+ - \`--fast\` → Skip questions, use reasonable defaults
900
+ - \`--auto\` → Zero interaction, heuristic decisions
901
+ - \`--confirm-only\` → Show plan, get yes/no only
902
+
903
+ **Default (no flags): Full Socratic Mode**
904
+
905
+ 1. **Analyze task for ambiguity:**
906
+ - Scope unclear? (what's included/excluded)
907
+ - Strategy unclear? (file-based vs feature-based)
908
+ - Dependencies unclear? (what needs to exist first)
909
+ - Success criteria unclear? (how do we know it's done)
910
+
911
+ 2. **If clarification needed, ask ONE question at a time:**
912
+ \`\`\`
913
+ The task "<task>" needs clarification before I can decompose it.
914
+
915
+ **Question:** <specific question>
916
+
917
+ Options:
918
+ a) <option 1> - <tradeoff>
919
+ b) <option 2> - <tradeoff>
920
+ c) <option 3> - <tradeoff>
921
+
922
+ I'd recommend (b) because <reason>. Which approach?
923
+ \`\`\`
924
+
925
+ 3. **Wait for user response before proceeding**
926
+
927
+ 4. **Iterate if needed** (max 2-3 questions)
928
+
929
+ **Rules:**
930
+ - ONE question at a time - don't overwhelm
931
+ - Offer concrete options - not open-ended
932
+ - Lead with recommendation - save cognitive load
933
+ - Wait for answer - don't assume
934
+
935
+ ### Phase 1: Initialize
895
936
  \`swarmmail_init(project_path="$PWD", task_description="Swarm: <task>")\`
896
937
 
897
- ### 2. Knowledge Gathering (MANDATORY)
938
+ ### Phase 2: Knowledge Gathering (MANDATORY)
898
939
 
899
940
  **Before decomposing, query ALL knowledge sources:**
900
941
 
901
942
  \`\`\`
902
943
  semantic-memory_find(query="<task keywords>", limit=5) # Past learnings
903
944
  cass_search(query="<task description>", limit=5) # Similar past tasks
904
- pdf-brain_search(query="<domain concepts>", limit=5) # Design patterns
905
945
  skills_list() # Available skills
906
946
  \`\`\`
907
947
 
908
948
  Synthesize findings into shared_context for workers.
909
949
 
910
- ### 3. Decompose
950
+ ### Phase 3: Decompose
911
951
  \`\`\`
912
952
  swarm_select_strategy(task="<task>")
913
953
  swarm_plan_prompt(task="<task>", context="<synthesized knowledge>")
914
954
  swarm_validate_decomposition(response="<BeadTree JSON>")
915
955
  \`\`\`
916
956
 
917
- ### 4. Create Beads
957
+ ### Phase 4: Create Beads
918
958
  \`beads_create_epic(epic_title="<task>", subtasks=[...])\`
919
959
 
920
- ### 5. Reserve Files
960
+ ### Phase 5: Reserve Files
921
961
  \`swarmmail_reserve(paths=[...], reason="<bead-id>: <desc>")\`
922
962
 
923
- ### 6. Spawn Agents (ALL in single message)
963
+ ### Phase 6: Spawn Agents (ALL in single message)
924
964
  \`\`\`
925
- swarm_spawn_subtask(bead_id, epic_id, subtask_title, files, shared_context)
965
+ swarm_spawn_subtask(bead_id, epic_id, subtask_title, files, shared_context, project_path="$PWD")
926
966
  Task(subagent_type="swarm/worker", prompt="<from above>")
927
967
  \`\`\`
928
968
 
929
- ### 7. Monitor
969
+ **IMPORTANT:** Pass \`project_path\` to \`swarm_spawn_subtask\` so workers can call \`swarmmail_init\`.
970
+
971
+ ### Phase 7: Monitor
930
972
  \`\`\`
931
973
  swarm_status(epic_id, project_key)
932
974
  swarmmail_inbox()
@@ -934,7 +976,7 @@ swarmmail_inbox()
934
976
 
935
977
  Intervene if: blocked >5min, file conflicts, scope creep.
936
978
 
937
- ### 8. Complete
979
+ ### Phase 8: Complete
938
980
  \`\`\`
939
981
  swarm_complete(...)
940
982
  beads_sync()
@@ -949,7 +991,15 @@ beads_sync()
949
991
  | risk-based | Bug fixes, security | fix, bug, security, critical, urgent |
950
992
  | research-based | Investigation, discovery | research, investigate, explore, learn |
951
993
 
952
- Begin with knowledge gathering now.
994
+ ## Flag Reference
995
+
996
+ | Flag | Effect |
997
+ |------|--------|
998
+ | \`--fast\` | Skip Socratic questions, use defaults |
999
+ | \`--auto\` | Zero interaction, heuristic decisions |
1000
+ | \`--confirm-only\` | Show plan, get yes/no only |
1001
+
1002
+ Begin with Phase 0 (Socratic Planning) unless \`--fast\` or \`--auto\` flag is present.
953
1003
  `;
954
1004
 
955
1005
  const getPlannerAgent = (model: string) => `---
@@ -1017,47 +1067,61 @@ description: Executes subtasks in a swarm - fast, focused, cost-effective
1017
1067
  model: ${model}
1018
1068
  ---
1019
1069
 
1020
- You are a swarm worker agent. Execute your assigned subtask efficiently.
1070
+ You are a swarm worker agent. Your prompt contains a **MANDATORY SURVIVAL CHECKLIST** - follow it IN ORDER.
1021
1071
 
1022
- ## Context
1072
+ ## CRITICAL: Read Your Prompt Carefully
1023
1073
 
1024
- Your prompt includes shared_context from the coordinator's knowledge gathering:
1025
- - Relevant patterns from pdf-brain
1026
- - Similar past approaches from CASS
1027
- - Project-specific learnings from semantic-memory
1074
+ Your Task prompt contains detailed instructions including:
1075
+ - 9-step survival checklist (FOLLOW IN ORDER)
1076
+ - File reservations (YOU reserve, not coordinator)
1077
+ - Progress reporting requirements
1078
+ - Completion protocol
1028
1079
 
1029
- **Use this context** - it contains patterns and prior art relevant to your task.
1080
+ **DO NOT skip steps.** The checklist exists because skipping steps causes:
1081
+ - Lost work (no tracking)
1082
+ - Edit conflicts (no reservations)
1083
+ - Wasted time (no semantic memory query)
1084
+ - Silent failures (no progress reports)
1030
1085
 
1031
- ## Workflow
1086
+ ## Step Summary (details in your prompt)
1032
1087
 
1033
- 1. **Read** assigned files to understand current state
1034
- 2. **Check skills** if you need domain guidance: \`skills_use(name="<relevant-skill>")\`
1035
- 3. **Implement** changes following patterns from shared_context
1036
- 4. **Verify** (typecheck, lint if applicable)
1037
- 5. **Complete** with \`swarm_complete\`
1088
+ 1. **swarmmail_init()** - FIRST, before anything else
1089
+ 2. **semantic-memory_find()** - Check past learnings
1090
+ 3. **skills_list() / skills_use()** - Load relevant skills
1091
+ 4. **swarmmail_reserve()** - YOU reserve your files
1092
+ 5. **Do the work** - Read, implement, verify
1093
+ 6. **swarm_progress()** - Report at 25/50/75%
1094
+ 7. **swarm_checkpoint()** - Before risky operations
1095
+ 8. **semantic-memory_store()** - Store learnings
1096
+ 9. **swarm_complete()** - NOT beads_close
1038
1097
 
1039
- ## Rules
1098
+ ## Non-Negotiables
1040
1099
 
1041
- - Focus ONLY on your assigned files
1042
- - Report blockers immediately via Swarm Mail (don't spin)
1043
- - Use beads_update if blocked
1044
- - Call swarm_complete when done - it handles bead closure and file release
1100
+ - **Step 1 is MANDATORY** - swarm_complete fails without init
1101
+ - **Step 2 saves time** - past agents may have solved this
1102
+ - **Step 4 prevents conflicts** - workers reserve, not coordinator
1103
+ - **Step 6 prevents silent failure** - report progress
1104
+ - **Step 9 is the ONLY way to close** - releases reservations, records learning
1045
1105
 
1046
- ## Communication
1106
+ ## When Blocked
1047
1107
 
1048
1108
  \`\`\`
1049
1109
  swarmmail_send(
1050
1110
  to=["coordinator"],
1051
- subject="Progress/Blocker",
1052
- body="...",
1053
- thread_id="<epic_id>"
1111
+ subject="BLOCKED: <bead-id>",
1112
+ body="<what you need>",
1113
+ importance="high"
1054
1114
  )
1115
+ beads_update(id="<bead-id>", status="blocked")
1055
1116
  \`\`\`
1056
1117
 
1057
- ## Learning
1118
+ ## Focus
1058
1119
 
1059
- If you discover a reusable pattern worth preserving:
1060
- \`semantic-memory_store(information="<pattern + why it matters>")\`
1120
+ - Only modify your assigned files
1121
+ - Don't fix other agents' code - coordinate instead
1122
+ - Report scope changes before expanding
1123
+
1124
+ Begin by reading your full prompt and executing Step 1.
1061
1125
  `;
1062
1126
 
1063
1127
  // ============================================================================
@@ -1238,14 +1302,20 @@ async function setup() {
1238
1302
 
1239
1303
  const pluginPath = join(pluginDir, "swarm.ts");
1240
1304
  const commandPath = join(commandDir, "swarm.md");
1241
- const plannerAgentPath = join(agentDir, "swarm-planner.md");
1242
- const workerAgentPath = join(agentDir, "swarm-worker.md");
1305
+ const swarmAgentDir = join(agentDir, "swarm");
1306
+ const plannerAgentPath = join(swarmAgentDir, "planner.md");
1307
+ const workerAgentPath = join(swarmAgentDir, "worker.md");
1308
+ // Legacy flat paths (for detection/cleanup)
1309
+ const legacyPlannerPath = join(agentDir, "swarm-planner.md");
1310
+ const legacyWorkerPath = join(agentDir, "swarm-worker.md");
1243
1311
 
1244
1312
  const existingFiles = [
1245
1313
  pluginPath,
1246
1314
  commandPath,
1247
1315
  plannerAgentPath,
1248
1316
  workerAgentPath,
1317
+ legacyPlannerPath,
1318
+ legacyWorkerPath,
1249
1319
  ].filter((f) => existsSync(f));
1250
1320
 
1251
1321
  if (existingFiles.length > 0) {
@@ -1302,25 +1372,34 @@ async function setup() {
1302
1372
  process.exit(0);
1303
1373
  }
1304
1374
 
1305
- // Update model lines in agent files
1306
- if (existsSync(plannerAgentPath)) {
1307
- const content = readFileSync(plannerAgentPath, "utf-8");
1375
+ // Update model lines in agent files (check both nested and legacy paths)
1376
+ const plannerPaths = [plannerAgentPath, legacyPlannerPath].filter(existsSync);
1377
+ const workerPaths = [workerAgentPath, legacyWorkerPath].filter(existsSync);
1378
+
1379
+ for (const path of plannerPaths) {
1380
+ const content = readFileSync(path, "utf-8");
1308
1381
  const updated = content.replace(
1309
1382
  /^model: .+$/m,
1310
1383
  `model: ${coordinatorModel}`,
1311
1384
  );
1312
- writeFileSync(plannerAgentPath, updated);
1385
+ writeFileSync(path, updated);
1386
+ }
1387
+ if (plannerPaths.length > 0) {
1313
1388
  p.log.success("Planner: " + coordinatorModel);
1314
1389
  }
1315
- if (existsSync(workerAgentPath)) {
1316
- const content = readFileSync(workerAgentPath, "utf-8");
1390
+
1391
+ for (const path of workerPaths) {
1392
+ const content = readFileSync(path, "utf-8");
1317
1393
  const updated = content.replace(
1318
1394
  /^model: .+$/m,
1319
1395
  `model: ${workerModel}`,
1320
1396
  );
1321
- writeFileSync(workerAgentPath, updated);
1397
+ writeFileSync(path, updated);
1398
+ }
1399
+ if (workerPaths.length > 0) {
1322
1400
  p.log.success("Worker: " + workerModel);
1323
1401
  }
1402
+
1324
1403
  p.outro("Models updated! Your customizations are preserved.");
1325
1404
  return;
1326
1405
  }
@@ -1556,7 +1635,7 @@ async function setup() {
1556
1635
 
1557
1636
  // Create directories if needed
1558
1637
  const skillsDir = join(configDir, "skills");
1559
- for (const dir of [pluginDir, commandDir, agentDir, skillsDir]) {
1638
+ for (const dir of [pluginDir, commandDir, agentDir, swarmAgentDir, skillsDir]) {
1560
1639
  if (!existsSync(dir)) {
1561
1640
  mkdirSync(dir, { recursive: true });
1562
1641
  }
@@ -1568,12 +1647,24 @@ async function setup() {
1568
1647
  writeFileSync(commandPath, SWARM_COMMAND);
1569
1648
  p.log.success("Command: " + commandPath);
1570
1649
 
1650
+ // Write nested agent files (swarm/planner.md, swarm/worker.md)
1651
+ // This is the format used by Task(subagent_type="swarm/worker")
1571
1652
  writeFileSync(plannerAgentPath, getPlannerAgent(coordinatorModel as string));
1572
1653
  p.log.success("Planner agent: " + plannerAgentPath);
1573
1654
 
1574
1655
  writeFileSync(workerAgentPath, getWorkerAgent(workerModel as string));
1575
1656
  p.log.success("Worker agent: " + workerAgentPath);
1576
1657
 
1658
+ // Clean up legacy flat agent files if they exist
1659
+ if (existsSync(legacyPlannerPath)) {
1660
+ rmSync(legacyPlannerPath);
1661
+ p.log.message(dim(" Removed legacy: " + legacyPlannerPath));
1662
+ }
1663
+ if (existsSync(legacyWorkerPath)) {
1664
+ rmSync(legacyWorkerPath);
1665
+ p.log.message(dim(" Removed legacy: " + legacyWorkerPath));
1666
+ }
1667
+
1577
1668
  p.log.success("Skills directory: " + skillsDir);
1578
1669
 
1579
1670
  // Show bundled skills info (and optionally sync to global skills dir)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm-plugin",
3
- "version": "0.24.0",
3
+ "version": "0.25.0",
4
4
  "description": "Multi-agent swarm coordination for OpenCode with learning capabilities, beads integration, and Agent Mail",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",