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/.beads/issues.jsonl +146 -2
- package/README.md +65 -12
- package/bun.lock +23 -0
- package/dist/index.js +9695 -0
- package/dist/plugin.js +9693 -0
- package/examples/commands/swarm.md +50 -0
- package/package.json +2 -3
- package/src/agent-mail.ts +134 -0
- package/src/index.ts +2 -0
- package/src/rate-limiter.integration.test.ts +466 -0
- package/src/rate-limiter.ts +656 -0
- package/src/swarm.integration.test.ts +115 -0
- package/src/swarm.ts +276 -0
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
|
-
##
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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=="],
|