opencode-swarm-plugin 0.23.5 → 0.24.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/.turbo/turbo-build.log +4 -4
- package/CHANGELOG.md +34 -0
- package/README.md +155 -3
- package/bin/swarm.ts +497 -187
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +668 -91
- package/dist/plugin.js +596 -91
- package/dist/schemas/bead-events.d.ts +698 -0
- package/dist/schemas/bead-events.d.ts.map +1 -0
- package/dist/schemas/index.d.ts +1 -0
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/skills.d.ts.map +1 -1
- package/dist/swarm-decompose.d.ts +74 -0
- package/dist/swarm-decompose.d.ts.map +1 -1
- package/dist/swarm-orchestrate.d.ts.map +1 -1
- package/dist/swarm-prompts.d.ts +1 -1
- package/dist/swarm-prompts.d.ts.map +1 -1
- package/dist/swarm.d.ts +27 -0
- package/dist/swarm.d.ts.map +1 -1
- package/docs/testing/context-recovery-test.md +470 -0
- package/examples/commands/swarm.md +92 -20
- package/global-skills/swarm-coordination/SKILL.md +380 -10
- package/package.json +2 -2
- package/src/schemas/bead-events.test.ts +341 -0
- package/src/schemas/bead-events.ts +583 -0
- package/src/schemas/index.ts +51 -0
- package/src/skills.ts +10 -3
- package/src/swarm-decompose.ts +337 -0
- package/src/swarm-orchestrate.ts +72 -55
- package/src/swarm-prompts.ts +144 -42
- package/src/swarm.integration.test.ts +581 -31
|
@@ -63,6 +63,86 @@ Swarm Mail is embedded (no external server needed) and provides:
|
|
|
63
63
|
|
|
64
64
|
**Heuristic:** If you can describe the task in one sentence without "and", don't swarm.
|
|
65
65
|
|
|
66
|
+
## Worker Survival Checklist (MANDATORY)
|
|
67
|
+
|
|
68
|
+
Every swarm worker MUST follow these 9 steps. No exceptions.
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
// 1. INITIALIZE - Register with Swarm Mail
|
|
72
|
+
swarmmail_init({
|
|
73
|
+
project_path: "/abs/path/to/project",
|
|
74
|
+
task_description: "bead-id: Task description"
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// 2. QUERY LEARNINGS - Check what past agents learned
|
|
78
|
+
semantic_memory_find({
|
|
79
|
+
query: "task keywords domain",
|
|
80
|
+
limit: 5
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// 3. LOAD SKILLS - Get domain expertise
|
|
84
|
+
skills_list();
|
|
85
|
+
skills_use({ name: "relevant-skill" });
|
|
86
|
+
|
|
87
|
+
// 4. RESERVE FILES - Claim exclusive ownership
|
|
88
|
+
swarmmail_reserve({
|
|
89
|
+
paths: ["src/assigned/**"],
|
|
90
|
+
reason: "bead-id: What I'm working on",
|
|
91
|
+
ttl_seconds: 3600
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// 5. DO WORK
|
|
95
|
+
// ... implement changes ...
|
|
96
|
+
|
|
97
|
+
// 6. REPORT PROGRESS - Every 30min or at milestones
|
|
98
|
+
swarm_progress({
|
|
99
|
+
project_key: "/abs/path/to/project",
|
|
100
|
+
agent_name: "WorkerName",
|
|
101
|
+
bead_id: "bd-123.4",
|
|
102
|
+
status: "in_progress",
|
|
103
|
+
message: "Auth service 80% complete, testing remaining",
|
|
104
|
+
progress_percent: 80
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// 7. CHECKPOINT - Before risky operations
|
|
108
|
+
swarm_checkpoint({
|
|
109
|
+
bead_id: "bd-123.4",
|
|
110
|
+
checkpoint_name: "pre-refactor",
|
|
111
|
+
reason: "About to refactor auth flow"
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// 8. STORE LEARNINGS - Capture what you discovered
|
|
115
|
+
semantic_memory_store({
|
|
116
|
+
information: "OAuth refresh tokens need 5min buffer...",
|
|
117
|
+
metadata: "auth, oauth, tokens"
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// 9. COMPLETE - Auto-releases, runs UBS, records outcome
|
|
121
|
+
swarm_complete({
|
|
122
|
+
project_key: "/abs/path/to/project",
|
|
123
|
+
agent_name: "WorkerName",
|
|
124
|
+
bead_id: "bd-123.4",
|
|
125
|
+
summary: "Auth service implemented with JWT",
|
|
126
|
+
files_touched: ["src/auth/service.ts", "src/auth/schema.ts"]
|
|
127
|
+
});
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Why These Steps Matter:**
|
|
131
|
+
|
|
132
|
+
| Step | Purpose | Consequence of Skipping |
|
|
133
|
+
|------|---------|-------------------------|
|
|
134
|
+
| 1. Init | Register identity, enable coordination | Can't send messages, reservations fail |
|
|
135
|
+
| 2. Query | Learn from past mistakes | Repeat solved problems, waste time |
|
|
136
|
+
| 3. Skills | Load domain expertise | Miss known patterns, lower quality |
|
|
137
|
+
| 4. Reserve | Prevent edit conflicts | Merge conflicts, lost work |
|
|
138
|
+
| 5. Work | Actually do the task | N/A |
|
|
139
|
+
| 6. Progress | Keep coordinator informed | Coordinator assumes stuck, may reassign |
|
|
140
|
+
| 7. Checkpoint | Safe rollback point | Can't recover from failures |
|
|
141
|
+
| 8. Store | Help future agents | Same bugs recur, no learning |
|
|
142
|
+
| 9. Complete | Clean release, learning signal | Reservations leak, no outcome tracking |
|
|
143
|
+
|
|
144
|
+
**If your subtask prompt doesn't include these steps, something is wrong with the coordinator.**
|
|
145
|
+
|
|
66
146
|
## Task Clarity Check (BEFORE Decomposing)
|
|
67
147
|
|
|
68
148
|
**Before decomposing, ask: Is this task clear enough to parallelize?**
|
|
@@ -112,6 +192,86 @@ I'd recommend (a) because [reason]. Which approach?
|
|
|
112
192
|
|
|
113
193
|
## Coordinator Workflow
|
|
114
194
|
|
|
195
|
+
### Phase 0: Socratic Planning (NEW - INTERACTIVE)
|
|
196
|
+
|
|
197
|
+
**Before decomposing, engage with the user to clarify the task.**
|
|
198
|
+
|
|
199
|
+
Swarm supports three interaction modes:
|
|
200
|
+
|
|
201
|
+
| Mode | Flag | Behavior |
|
|
202
|
+
|------|------|----------|
|
|
203
|
+
| **Full Socratic** | (default) | Ask questions, offer recommendations, collaborative planning |
|
|
204
|
+
| **Fast** | `--fast` | Skip questions, proceed with reasonable defaults |
|
|
205
|
+
| **Auto** | `--auto` | Minimal interaction, use heuristics for all decisions |
|
|
206
|
+
| **Confirm Only** | `--confirm-only` | Show plan, get yes/no, no discussion |
|
|
207
|
+
|
|
208
|
+
**Default Flow (Full Socratic):**
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
// 1. Analyze task for clarity
|
|
212
|
+
const signals = analyzeTaskClarity(task);
|
|
213
|
+
|
|
214
|
+
if (signals.needsClarification) {
|
|
215
|
+
// 2. Ask ONE question at a time
|
|
216
|
+
const question = generateClarifyingQuestion(signals);
|
|
217
|
+
|
|
218
|
+
// 3. Offer 2-3 concrete options
|
|
219
|
+
const options = generateOptions(signals);
|
|
220
|
+
|
|
221
|
+
// 4. Lead with recommendation
|
|
222
|
+
const recommendation = selectRecommendation(options);
|
|
223
|
+
|
|
224
|
+
// 5. Present to user
|
|
225
|
+
console.log(`
|
|
226
|
+
The task "${task}" needs clarification before I can decompose it.
|
|
227
|
+
|
|
228
|
+
**Question:** ${question}
|
|
229
|
+
|
|
230
|
+
Options:
|
|
231
|
+
a) ${options[0].description} - ${options[0].tradeoff}
|
|
232
|
+
b) ${options[1].description} - ${options[1].tradeoff}
|
|
233
|
+
c) ${options[2].description} - ${options[2].tradeoff}
|
|
234
|
+
|
|
235
|
+
I'd recommend (${recommendation.letter}) because ${recommendation.reason}. Which approach?
|
|
236
|
+
`);
|
|
237
|
+
|
|
238
|
+
// 6. Wait for answer, iterate if needed
|
|
239
|
+
const answer = await getUserResponse();
|
|
240
|
+
|
|
241
|
+
// 7. Ask next question if needed (ONE at a time)
|
|
242
|
+
if (needsMoreClarification(answer)) {
|
|
243
|
+
// Repeat with next question
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// 8. Proceed to decomposition once clear
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
**Fast Mode (`--fast`):**
|
|
251
|
+
|
|
252
|
+
- Skip all questions
|
|
253
|
+
- Use reasonable defaults based on task type
|
|
254
|
+
- Proceed directly to decomposition
|
|
255
|
+
|
|
256
|
+
**Auto Mode (`--auto`):**
|
|
257
|
+
|
|
258
|
+
- Zero interaction
|
|
259
|
+
- Heuristic-based decisions for all choices
|
|
260
|
+
- Use for batch processing or CI
|
|
261
|
+
|
|
262
|
+
**Confirm Only (`--confirm-only`):**
|
|
263
|
+
|
|
264
|
+
- Generate plan silently
|
|
265
|
+
- Show final BeadTree
|
|
266
|
+
- Get yes/no only
|
|
267
|
+
|
|
268
|
+
**Rules for Socratic Mode:**
|
|
269
|
+
|
|
270
|
+
- **ONE question at a time** - don't overwhelm
|
|
271
|
+
- **Offer concrete options** - not open-ended
|
|
272
|
+
- **Lead with recommendation** - save user cognitive load
|
|
273
|
+
- **Wait for answer** - don't proceed with assumptions
|
|
274
|
+
|
|
115
275
|
### Phase 1: Initialize Swarm Mail (FIRST)
|
|
116
276
|
|
|
117
277
|
```typescript
|
|
@@ -212,23 +372,54 @@ await beads_create_epic({
|
|
|
212
372
|
- **Scales to long swarms** - coordinator can manage 10+ workers without exhaustion
|
|
213
373
|
- **Faster coordination** - less context = faster responses when monitoring workers
|
|
214
374
|
|
|
215
|
-
### Phase 4:
|
|
375
|
+
### Phase 4: File Ownership (CRITICAL RULE)
|
|
376
|
+
|
|
377
|
+
**⚠️ COORDINATORS NEVER RESERVE FILES**
|
|
378
|
+
|
|
379
|
+
This is a hard rule. Here's why:
|
|
216
380
|
|
|
217
381
|
```typescript
|
|
218
|
-
//
|
|
219
|
-
|
|
382
|
+
// ❌ WRONG - Coordinator reserving files
|
|
383
|
+
swarmmail_reserve({
|
|
220
384
|
paths: ["src/auth/**"],
|
|
221
|
-
reason: "bd-123: Auth service implementation"
|
|
222
|
-
|
|
223
|
-
|
|
385
|
+
reason: "bd-123: Auth service implementation"
|
|
386
|
+
});
|
|
387
|
+
// Then spawns worker... who owns the files?
|
|
388
|
+
|
|
389
|
+
// ✅ CORRECT - Worker reserves their own files
|
|
390
|
+
// Coordinator includes file list in worker prompt
|
|
391
|
+
const prompt = swarm_spawn_subtask({
|
|
392
|
+
bead_id: "bd-123.4",
|
|
393
|
+
files: ["src/auth/**"], // Files listed here
|
|
394
|
+
// ...
|
|
224
395
|
});
|
|
396
|
+
|
|
397
|
+
// Worker receives prompt with file list
|
|
398
|
+
// Worker calls swarmmail_reserve themselves
|
|
225
399
|
```
|
|
226
400
|
|
|
227
|
-
**
|
|
401
|
+
**Why This Pattern:**
|
|
402
|
+
|
|
403
|
+
| Coordinator Reserves | Worker Reserves |
|
|
404
|
+
|---------------------|-----------------|
|
|
405
|
+
| Ownership confusion | Clear ownership |
|
|
406
|
+
| Who releases? | Worker releases via `swarm_complete` |
|
|
407
|
+
| Coordinator must track | Worker manages lifecycle |
|
|
408
|
+
| Deadlock risk | Clean handoff |
|
|
409
|
+
|
|
410
|
+
**Coordinator Responsibilities:**
|
|
411
|
+
|
|
412
|
+
1. **Plan** which files each worker needs (no overlap)
|
|
413
|
+
2. **Include** file list in worker prompt
|
|
414
|
+
3. **Mediate** conflicts if workers request different files
|
|
415
|
+
4. **Never** call `swarmmail_reserve` themselves
|
|
228
416
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
417
|
+
**Worker Responsibilities:**
|
|
418
|
+
|
|
419
|
+
1. **Read** assigned files from prompt
|
|
420
|
+
2. **Reserve** those files (step 4 of survival checklist)
|
|
421
|
+
3. **Work** exclusively on reserved files
|
|
422
|
+
4. **Release** via `swarm_complete` (automatic)
|
|
232
423
|
|
|
233
424
|
### Phase 5: Spawn Workers
|
|
234
425
|
|
|
@@ -286,6 +477,185 @@ await swarmmail_release(); // Release any remaining reservations
|
|
|
286
477
|
await beads_sync();
|
|
287
478
|
```
|
|
288
479
|
|
|
480
|
+
## Context Survival Patterns (CRITICAL)
|
|
481
|
+
|
|
482
|
+
Long-running swarms exhaust context windows. These patterns keep you alive.
|
|
483
|
+
|
|
484
|
+
### Pattern 1: Query Memory Before Starting
|
|
485
|
+
|
|
486
|
+
**Problem:** Repeating solved problems wastes tokens on rediscovery.
|
|
487
|
+
|
|
488
|
+
**Solution:** Query semantic memory FIRST.
|
|
489
|
+
|
|
490
|
+
```typescript
|
|
491
|
+
// At swarm start (coordinator)
|
|
492
|
+
const learnings = await semantic_memory_find({
|
|
493
|
+
query: "auth oauth tokens",
|
|
494
|
+
limit: 5
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
// Include in shared_context for workers
|
|
498
|
+
const shared_context = `
|
|
499
|
+
## Past Learnings
|
|
500
|
+
${learnings.map(l => `- ${l.information}`).join('\n')}
|
|
501
|
+
`;
|
|
502
|
+
|
|
503
|
+
// At worker start (survival checklist step 2)
|
|
504
|
+
const relevantLearnings = await semantic_memory_find({
|
|
505
|
+
query: "task-specific keywords",
|
|
506
|
+
limit: 3
|
|
507
|
+
});
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
**Why:** 5 learnings (~2k tokens) prevent rediscovering solutions (~20k tokens of trial-and-error).
|
|
511
|
+
|
|
512
|
+
### Pattern 2: Checkpoint Before Risky Operations
|
|
513
|
+
|
|
514
|
+
**Problem:** Failed experiments consume context without producing value.
|
|
515
|
+
|
|
516
|
+
**Solution:** Checkpoint before risky changes.
|
|
517
|
+
|
|
518
|
+
```typescript
|
|
519
|
+
// Before refactoring
|
|
520
|
+
await swarm_checkpoint({
|
|
521
|
+
bead_id: "bd-123.4",
|
|
522
|
+
checkpoint_name: "pre-refactor",
|
|
523
|
+
reason: "About to change auth flow structure"
|
|
524
|
+
});
|
|
525
|
+
|
|
526
|
+
// Try risky change...
|
|
527
|
+
|
|
528
|
+
// If it fails, restore and try different approach
|
|
529
|
+
await swarm_restore_checkpoint({
|
|
530
|
+
bead_id: "bd-123.4",
|
|
531
|
+
checkpoint_name: "pre-refactor"
|
|
532
|
+
});
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
**When to Checkpoint:**
|
|
536
|
+
|
|
537
|
+
| Operation | Risk | Checkpoint? |
|
|
538
|
+
|-----------|------|-------------|
|
|
539
|
+
| Add new file | Low | No |
|
|
540
|
+
| Refactor across files | High | Yes |
|
|
541
|
+
| Change API contract | High | Yes |
|
|
542
|
+
| Update dependencies | Medium | Yes |
|
|
543
|
+
| Fix typo | Low | No |
|
|
544
|
+
| Rewrite algorithm | High | Yes |
|
|
545
|
+
|
|
546
|
+
### Pattern 3: Store Learnings Immediately
|
|
547
|
+
|
|
548
|
+
**Problem:** Discoveries get lost in context churn.
|
|
549
|
+
|
|
550
|
+
**Solution:** Store learnings as soon as you discover them.
|
|
551
|
+
|
|
552
|
+
```typescript
|
|
553
|
+
// ❌ WRONG - Wait until end
|
|
554
|
+
// ... debug for 30 minutes ...
|
|
555
|
+
// ... find root cause ...
|
|
556
|
+
// ... keep working ...
|
|
557
|
+
// ... forget to store learning ...
|
|
558
|
+
|
|
559
|
+
// ✅ CORRECT - Store immediately when discovered
|
|
560
|
+
// ... debug for 30 minutes ...
|
|
561
|
+
// ... find root cause ...
|
|
562
|
+
await semantic_memory_store({
|
|
563
|
+
information: "OAuth refresh tokens need 5min buffer to avoid race conditions. Without buffer, token refresh can fail mid-request if expiry happens between check and use.",
|
|
564
|
+
metadata: "auth, oauth, tokens, race-conditions"
|
|
565
|
+
});
|
|
566
|
+
// ... continue working with peace of mind ...
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
**Trigger:** Store a learning whenever you say "Aha!" or "That's why!".
|
|
570
|
+
|
|
571
|
+
### Pattern 4: Progress Reports Trigger Auto-Checkpoints
|
|
572
|
+
|
|
573
|
+
**Problem:** Workers forget to checkpoint manually.
|
|
574
|
+
|
|
575
|
+
**Solution:** `swarm_progress` auto-checkpoints at milestones.
|
|
576
|
+
|
|
577
|
+
```typescript
|
|
578
|
+
// Report progress at 25%, 50%, 75%
|
|
579
|
+
await swarm_progress({
|
|
580
|
+
project_key: "/abs/path",
|
|
581
|
+
agent_name: "WorkerName",
|
|
582
|
+
bead_id: "bd-123.4",
|
|
583
|
+
status: "in_progress",
|
|
584
|
+
progress_percent: 50, // Auto-checkpoint triggered
|
|
585
|
+
message: "Auth service half complete"
|
|
586
|
+
});
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
**Auto-checkpoint thresholds:** 25%, 50%, 75%, 100% (completion).
|
|
590
|
+
|
|
591
|
+
### Pattern 5: Delegate Heavy Research to Subagents
|
|
592
|
+
|
|
593
|
+
**Problem:** Reading 10+ files or doing deep CASS searches pollutes main thread.
|
|
594
|
+
|
|
595
|
+
**Solution:** Subagent researches, returns summary only.
|
|
596
|
+
|
|
597
|
+
```typescript
|
|
598
|
+
// ❌ WRONG - Coordinator reads files inline
|
|
599
|
+
const file1 = await read("src/a.ts"); // 500 lines
|
|
600
|
+
const file2 = await read("src/b.ts"); // 600 lines
|
|
601
|
+
const file3 = await read("src/c.ts"); // 400 lines
|
|
602
|
+
// ... context now +1500 lines ...
|
|
603
|
+
|
|
604
|
+
// ✅ CORRECT - Subagent reads, summarizes
|
|
605
|
+
const summary = await Task({
|
|
606
|
+
subagent_type: "explore",
|
|
607
|
+
prompt: "Read src/a.ts, src/b.ts, src/c.ts. Summarize the auth flow in 3 bullet points."
|
|
608
|
+
});
|
|
609
|
+
// ... context +3 bullets, subagent context disposed ...
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
**When to Delegate:**
|
|
613
|
+
|
|
614
|
+
- Reading >3 files
|
|
615
|
+
- Multiple CASS searches
|
|
616
|
+
- Deep file tree exploration
|
|
617
|
+
- Analyzing large logs
|
|
618
|
+
|
|
619
|
+
### Pattern 6: Use Summaries Over Raw Data
|
|
620
|
+
|
|
621
|
+
**Problem:** Full inboxes, file contents, search results exhaust tokens.
|
|
622
|
+
|
|
623
|
+
**Solution:** Summaries and previews only.
|
|
624
|
+
|
|
625
|
+
```typescript
|
|
626
|
+
// ❌ WRONG - Fetch all message bodies
|
|
627
|
+
const inbox = await swarmmail_inbox({ include_bodies: true });
|
|
628
|
+
|
|
629
|
+
// ✅ CORRECT - Headers only, read specific messages
|
|
630
|
+
const inbox = await swarmmail_inbox({ limit: 5 }); // Headers only
|
|
631
|
+
if (inbox.urgent.length > 0) {
|
|
632
|
+
const msg = await swarmmail_read_message({ message_id: inbox.urgent[0].id });
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
// ✅ BETTER - Summarize threads
|
|
636
|
+
const summary = await swarmmail_summarize_thread({ thread_id: "bd-123" });
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
**Token Budget:**
|
|
640
|
+
|
|
641
|
+
| Approach | Tokens |
|
|
642
|
+
|----------|--------|
|
|
643
|
+
| 10 full messages | ~5k |
|
|
644
|
+
| 10 message headers | ~500 |
|
|
645
|
+
| Thread summary | ~200 |
|
|
646
|
+
|
|
647
|
+
### Context Survival Checklist
|
|
648
|
+
|
|
649
|
+
- [ ] Query semantic memory at start
|
|
650
|
+
- [ ] Checkpoint before risky operations
|
|
651
|
+
- [ ] Store learnings immediately when discovered
|
|
652
|
+
- [ ] Use `swarm_progress` for auto-checkpoints
|
|
653
|
+
- [ ] Delegate heavy research to subagents
|
|
654
|
+
- [ ] Use summaries over raw data
|
|
655
|
+
- [ ] Monitor token usage (stay under 150k)
|
|
656
|
+
|
|
657
|
+
**If you're past 150k tokens, you've already lost. These patterns keep you alive.**
|
|
658
|
+
|
|
289
659
|
## Decomposition Strategies
|
|
290
660
|
|
|
291
661
|
Four strategies, auto-selected by task keywords:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.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",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"@opencode-ai/plugin": "^1.0.134",
|
|
34
34
|
"gray-matter": "^4.0.3",
|
|
35
35
|
"ioredis": "^5.4.1",
|
|
36
|
-
"swarm-mail": "0.1.
|
|
36
|
+
"swarm-mail": "0.1.3",
|
|
37
37
|
"zod": "4.1.8"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|