opencode-swarm-plugin 0.3.0 → 0.5.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.
package/README.md CHANGED
@@ -94,6 +94,38 @@ bd --version
94
94
  | `agentmail_search` | Search messages (FTS5 syntax) |
95
95
  | `agentmail_health` | Check if Agent Mail server is running |
96
96
 
97
+ ## Rate Limiting
98
+
99
+ Client-side, per-agent rate limits prevent abuse and ensure fair resource usage across agents. Uses Redis as primary store (`localhost:6379`) with automatic SQLite fallback (`~/.config/opencode/rate-limits.db`).
100
+
101
+ ### Default Limits
102
+
103
+ | Endpoint | Per Minute | Per Hour |
104
+ | ------------------ | ---------- | -------- |
105
+ | `send` | 20 | 200 |
106
+ | `reserve` | 10 | 100 |
107
+ | `release` | 10 | 100 |
108
+ | `ack` | 20 | 200 |
109
+ | `inbox` | 60 | 600 |
110
+ | `read_message` | 60 | 600 |
111
+ | `summarize_thread` | 30 | 300 |
112
+ | `search` | 30 | 300 |
113
+
114
+ ### Configuration
115
+
116
+ | Environment Variable | Description |
117
+ | ----------------------------------------- | --------------------------------------------------------------------------- |
118
+ | `OPENCODE_RATE_LIMIT_REDIS_URL` | Redis connection URL (default: `redis://localhost:6379`) |
119
+ | `OPENCODE_RATE_LIMIT_SQLITE_PATH` | SQLite database path (default: `~/.config/opencode/rate-limits.db`) |
120
+ | `OPENCODE_RATE_LIMIT_{ENDPOINT}_PER_MIN` | Per-minute limit for endpoint (e.g., `OPENCODE_RATE_LIMIT_SEND_PER_MIN=30`) |
121
+ | `OPENCODE_RATE_LIMIT_{ENDPOINT}_PER_HOUR` | Per-hour limit for endpoint (e.g., `OPENCODE_RATE_LIMIT_SEND_PER_HOUR=300`) |
122
+
123
+ ### Troubleshooting
124
+
125
+ - **Rate limit exceeded errors** - Adjust limits via environment variables for your workload
126
+ - **Redis unavailable** - Automatic SQLite fallback with warning logged; no action needed
127
+ - **SQLite cleanup** - Expired entries cleaned automatically on init
128
+
97
129
  ### Swarm Tools
98
130
 
99
131
  | Tool | Description |
@@ -105,7 +137,9 @@ bd --version
105
137
  | `swarm_progress` | Report progress on a subtask |
106
138
  | `swarm_complete` | Mark subtask complete with UBS bug scan, release reservations |
107
139
  | `swarm_record_outcome` | Record outcome for implicit feedback (duration, errors, retries) |
108
- | `swarm_subtask_prompt` | Generate prompt for spawned subtask agent |
140
+ | `swarm_subtask_prompt` | Generate prompt for spawned subtask agent (V1 - includes coordination) |
141
+ | `swarm_spawn_subtask` | Generate V2 prompt with Agent Mail/beads instructions for subagents |
142
+ | `swarm_complete_subtask` | Handle subtask completion: close bead, create issue beads |
109
143
  | `swarm_evaluation_prompt` | Generate self-evaluation prompt |
110
144
 
111
145
  ### Structured Output Tools
@@ -395,24 +429,43 @@ The plugin enforces these limits regardless of input:
395
429
  - Thread summaries use LLM mode for concise output
396
430
  - File reservations auto-track for cleanup
397
431
 
398
- ## Integration with /swarm Command
432
+ ## Custom Commands
433
+
434
+ This plugin provides tools that work with OpenCode's [custom commands](https://opencode.ai/docs/commands). Create a `/swarm` command to orchestrate multi-agent work.
399
435
 
400
- This plugin provides the primitives used by OpenCode's `/swarm` command:
436
+ ### Setup /swarm Command
437
+
438
+ Copy the example command to your OpenCode config:
439
+
440
+ ```bash
441
+ cp examples/commands/swarm.md ~/.config/opencode/command/
442
+ ```
443
+
444
+ ### Usage
401
445
 
402
446
  ```
403
447
  /swarm "Add user authentication with OAuth providers"
404
448
  ```
405
449
 
406
- The `/swarm` command uses this plugin to:
450
+ ### How It Works
451
+
452
+ 1. **Decompose** - `swarm_decompose` breaks task into subtasks with file assignments
453
+ 2. **Create beads** - `beads_create_epic` creates epic + subtasks atomically
454
+ 3. **Spawn agents** - `swarm_spawn_subtask` generates prompts WITH Agent Mail/beads instructions
455
+ 4. **Parallel work** - Subagents use Agent Mail to communicate, beads to track progress
456
+ 5. **Coordination** - Agents report progress, ask questions, announce blockers via Agent Mail
457
+ 6. **Completion** - Agents use `swarm_complete` when done
458
+ 7. **Cleanup** - `beads_sync` pushes to git
459
+
460
+ ### Subagent Capabilities
461
+
462
+ Spawned subagents have **full access** to all plugin tools:
463
+
464
+ - **Agent Mail** - `agentmail_send`, `agentmail_inbox`, `agentmail_reserve`, etc.
465
+ - **Beads** - `beads_update`, `beads_create`, `swarm_complete`
466
+ - All standard OpenCode tools
407
467
 
408
- 1. **Decompose** - Break task into subtasks using `TaskDecompositionSchema`
409
- 2. **Create beads** - Use `beads_create_epic` for atomic issue creation
410
- 3. **Initialize agents** - Each agent calls `agentmail_init`
411
- 4. **Reserve files** - Prevent conflicts with `agentmail_reserve`
412
- 5. **Coordinate** - Agents communicate via `agentmail_send`
413
- 6. **Track status** - Use `SwarmStatusSchema` for progress
414
- 7. **Evaluate** - Validate work with `EvaluationSchema`
415
- 8. **Cleanup** - Release reservations and sync beads
468
+ The prompts tell agents to actively communicate and coordinate.
416
469
 
417
470
  ## Error Handling
418
471
 
package/bun.lock CHANGED
@@ -6,6 +6,7 @@
6
6
  "name": "opencode-swarm-plugin",
7
7
  "dependencies": {
8
8
  "@opencode-ai/plugin": "^1.0.134",
9
+ "ioredis": "^5.4.1",
9
10
  "zod": "4.1.8",
10
11
  },
11
12
  "devDependencies": {
@@ -71,6 +72,8 @@
71
72
 
72
73
  "@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="],
73
74
 
75
+ "@ioredis/commands": ["@ioredis/commands@1.4.0", "", {}, "sha512-aFT2yemJJo+TZCmieA7qnYGQooOS7QfNmYrzGtsYd3g9j5iDP8AimYYAesf79ohjbLG12XxC4nG5DyEnC88AsQ=="],
76
+
74
77
  "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
75
78
 
76
79
  "@opencode-ai/plugin": ["@opencode-ai/plugin@1.0.134", "", { "dependencies": { "@opencode-ai/sdk": "1.0.134", "zod": "4.1.8" } }, "sha512-W5305/s7nVOtM4ha+qZ3iafY2h52D4zvPSylzq/ge0VVxowB/Ge1Tu+3mMUcwnoEcOOwGok7267SP9+4ulaK2w=="],
@@ -153,6 +156,12 @@
153
156
 
154
157
  "chai": ["chai@6.2.1", "", {}, "sha512-p4Z49OGG5W/WBCPSS/dH3jQ73kD6tiMmUM+bckNK6Jr5JHMG3k9bg/BvKR8lKmtVBKmOiuVaV2ws8s9oSbwysg=="],
155
158
 
159
+ "cluster-key-slot": ["cluster-key-slot@1.1.2", "", {}, "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA=="],
160
+
161
+ "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
162
+
163
+ "denque": ["denque@2.1.0", "", {}, "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw=="],
164
+
156
165
  "es-module-lexer": ["es-module-lexer@1.7.0", "", {}, "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA=="],
157
166
 
158
167
  "esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="],
@@ -165,8 +174,16 @@
165
174
 
166
175
  "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
167
176
 
177
+ "ioredis": ["ioredis@5.8.2", "", { "dependencies": { "@ioredis/commands": "1.4.0", "cluster-key-slot": "^1.1.0", "debug": "^4.3.4", "denque": "^2.1.0", "lodash.defaults": "^4.2.0", "lodash.isarguments": "^3.1.0", "redis-errors": "^1.2.0", "redis-parser": "^3.0.0", "standard-as-callback": "^2.1.0" } }, "sha512-C6uC+kleiIMmjViJINWk80sOQw5lEzse1ZmvD+S/s8p8CWapftSaC+kocGTx6xrbrJ4WmYQGC08ffHLr6ToR6Q=="],
178
+
179
+ "lodash.defaults": ["lodash.defaults@4.2.0", "", {}, "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ=="],
180
+
181
+ "lodash.isarguments": ["lodash.isarguments@3.1.0", "", {}, "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg=="],
182
+
168
183
  "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
169
184
 
185
+ "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
186
+
170
187
  "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
171
188
 
172
189
  "obug": ["obug@2.1.1", "", {}, "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ=="],
@@ -179,6 +196,10 @@
179
196
 
180
197
  "postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
181
198
 
199
+ "redis-errors": ["redis-errors@1.2.0", "", {}, "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w=="],
200
+
201
+ "redis-parser": ["redis-parser@3.0.0", "", { "dependencies": { "redis-errors": "^1.0.0" } }, "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A=="],
202
+
182
203
  "rollup": ["rollup@4.53.3", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.53.3", "@rollup/rollup-android-arm64": "4.53.3", "@rollup/rollup-darwin-arm64": "4.53.3", "@rollup/rollup-darwin-x64": "4.53.3", "@rollup/rollup-freebsd-arm64": "4.53.3", "@rollup/rollup-freebsd-x64": "4.53.3", "@rollup/rollup-linux-arm-gnueabihf": "4.53.3", "@rollup/rollup-linux-arm-musleabihf": "4.53.3", "@rollup/rollup-linux-arm64-gnu": "4.53.3", "@rollup/rollup-linux-arm64-musl": "4.53.3", "@rollup/rollup-linux-loong64-gnu": "4.53.3", "@rollup/rollup-linux-ppc64-gnu": "4.53.3", "@rollup/rollup-linux-riscv64-gnu": "4.53.3", "@rollup/rollup-linux-riscv64-musl": "4.53.3", "@rollup/rollup-linux-s390x-gnu": "4.53.3", "@rollup/rollup-linux-x64-gnu": "4.53.3", "@rollup/rollup-linux-x64-musl": "4.53.3", "@rollup/rollup-openharmony-arm64": "4.53.3", "@rollup/rollup-win32-arm64-msvc": "4.53.3", "@rollup/rollup-win32-ia32-msvc": "4.53.3", "@rollup/rollup-win32-x64-gnu": "4.53.3", "@rollup/rollup-win32-x64-msvc": "4.53.3", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA=="],
183
204
 
184
205
  "siginfo": ["siginfo@2.0.0", "", {}, "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g=="],
@@ -187,6 +208,8 @@
187
208
 
188
209
  "stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="],
189
210
 
211
+ "standard-as-callback": ["standard-as-callback@2.1.0", "", {}, "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A=="],
212
+
190
213
  "std-env": ["std-env@3.10.0", "", {}, "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg=="],
191
214
 
192
215
  "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="],