opencode-swarm-plugin 0.12.30 → 0.13.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 +204 -10
- package/.opencode/skills/tdd/SKILL.md +182 -0
- package/README.md +165 -17
- package/bin/swarm.ts +120 -31
- package/bun.lock +23 -0
- package/dist/index.js +4020 -438
- package/dist/pglite.data +0 -0
- package/dist/pglite.wasm +0 -0
- package/dist/plugin.js +4008 -514
- package/examples/commands/swarm.md +114 -19
- package/examples/skills/beads-workflow/SKILL.md +75 -28
- package/examples/skills/swarm-coordination/SKILL.md +92 -1
- package/global-skills/testing-patterns/SKILL.md +430 -0
- package/global-skills/testing-patterns/references/dependency-breaking-catalog.md +586 -0
- package/package.json +11 -5
- package/src/index.ts +44 -5
- package/src/streams/agent-mail.test.ts +777 -0
- package/src/streams/agent-mail.ts +535 -0
- package/src/streams/debug.test.ts +500 -0
- package/src/streams/debug.ts +629 -0
- package/src/streams/effect/ask.integration.test.ts +314 -0
- package/src/streams/effect/ask.ts +202 -0
- package/src/streams/effect/cursor.integration.test.ts +418 -0
- package/src/streams/effect/cursor.ts +288 -0
- package/src/streams/effect/deferred.test.ts +357 -0
- package/src/streams/effect/deferred.ts +445 -0
- package/src/streams/effect/index.ts +17 -0
- package/src/streams/effect/layers.ts +73 -0
- package/src/streams/effect/lock.test.ts +385 -0
- package/src/streams/effect/lock.ts +399 -0
- package/src/streams/effect/mailbox.test.ts +260 -0
- package/src/streams/effect/mailbox.ts +318 -0
- package/src/streams/events.test.ts +628 -0
- package/src/streams/events.ts +214 -0
- package/src/streams/index.test.ts +229 -0
- package/src/streams/index.ts +492 -0
- package/src/streams/migrations.test.ts +355 -0
- package/src/streams/migrations.ts +269 -0
- package/src/streams/projections.test.ts +611 -0
- package/src/streams/projections.ts +302 -0
- package/src/streams/store.integration.test.ts +548 -0
- package/src/streams/store.ts +546 -0
- package/src/streams/swarm-mail.ts +552 -0
- package/src/swarm-mail.integration.test.ts +970 -0
- package/src/swarm-mail.ts +739 -0
- package/src/swarm.ts +84 -59
- package/src/tool-availability.ts +35 -2
- package/global-skills/mcp-tool-authoring/SKILL.md +0 -695
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tdd
|
|
3
|
+
description: "Test-Driven Development workflow with RED-GREEN-REFACTOR, lore from Kent Beck, Michael Feathers, and Ousterhout's counterpoint"
|
|
4
|
+
tags:
|
|
5
|
+
- testing
|
|
6
|
+
- workflow
|
|
7
|
+
- methodology
|
|
8
|
+
- tdd
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Test-Driven Development (TDD)
|
|
12
|
+
|
|
13
|
+
## The Rhythm: RED-GREEN-REFACTOR
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
1. RED - Write failing test first (define expected behavior)
|
|
17
|
+
2. GREEN - Minimal implementation to pass (don't over-engineer)
|
|
18
|
+
3. REFACTOR - Clean up, remove duplication, run tests again
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Why TDD Works (The Lore)
|
|
22
|
+
|
|
23
|
+
### Kent Beck (Test-Driven Development by Example)
|
|
24
|
+
|
|
25
|
+
> "The act of writing a unit test is more an act of design than verification."
|
|
26
|
+
|
|
27
|
+
- Tests become executable documentation of intent
|
|
28
|
+
- "Fake it til you make it" - start with hardcoded values, generalize
|
|
29
|
+
- Small steps reduce debugging time
|
|
30
|
+
- Confidence to refactor comes from test coverage
|
|
31
|
+
|
|
32
|
+
### Michael Feathers (Working Effectively with Legacy Code)
|
|
33
|
+
|
|
34
|
+
> "The most powerful feature-addition technique I know of is test-driven development."
|
|
35
|
+
|
|
36
|
+
- TDD works in both OO and procedural code
|
|
37
|
+
- Writing tests first forces you to think about interfaces
|
|
38
|
+
- Tests are the safety net that enables aggressive refactoring
|
|
39
|
+
- Legacy code = code without tests
|
|
40
|
+
|
|
41
|
+
### Martin Fowler (Refactoring)
|
|
42
|
+
|
|
43
|
+
> "Kent Beck baked this habit of writing the test first into a technique called Test-Driven Development."
|
|
44
|
+
|
|
45
|
+
- TDD relies on short cycles
|
|
46
|
+
- Tests enable refactoring
|
|
47
|
+
- Refactoring becomes safe - tests catch regressions instantly
|
|
48
|
+
|
|
49
|
+
## The Counterpoint: Know When to Break the Rule
|
|
50
|
+
|
|
51
|
+
### John Ousterhout (A Philosophy of Software Design)
|
|
52
|
+
|
|
53
|
+
> "The problem with test-driven development is that it focuses attention on getting specific features working, rather than finding the best design."
|
|
54
|
+
|
|
55
|
+
**When TDD can hurt:**
|
|
56
|
+
|
|
57
|
+
- Can lead to tactical programming (feature-focused, not design-focused)
|
|
58
|
+
- May produce code that's easy to test but hard to understand
|
|
59
|
+
- Risk of over-testing implementation details
|
|
60
|
+
|
|
61
|
+
**The balance:**
|
|
62
|
+
|
|
63
|
+
- For exploratory/architectural work, design first, then add tests
|
|
64
|
+
- Don't let tests drive you into a corner
|
|
65
|
+
- Step back periodically to evaluate overall design
|
|
66
|
+
|
|
67
|
+
## When to Use TDD
|
|
68
|
+
|
|
69
|
+
✅ **Use TDD for:**
|
|
70
|
+
|
|
71
|
+
- New features with clear requirements
|
|
72
|
+
- Bug fixes (write test that reproduces bug first)
|
|
73
|
+
- Refactoring existing code (add characterization tests first)
|
|
74
|
+
- API design (tests reveal ergonomics)
|
|
75
|
+
- Any code that will be maintained long-term
|
|
76
|
+
|
|
77
|
+
❌ **Skip TDD for:**
|
|
78
|
+
|
|
79
|
+
- Exploratory spikes (but add tests after if keeping the code)
|
|
80
|
+
- Emergency hotfixes (but add tests immediately after)
|
|
81
|
+
- Pure UI/styling changes
|
|
82
|
+
- One-off scripts
|
|
83
|
+
- Throwaway prototypes
|
|
84
|
+
|
|
85
|
+
## The TDD Workflow
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# 1. Write test, watch it fail
|
|
89
|
+
bun test src/thing.test.ts # RED - test fails
|
|
90
|
+
|
|
91
|
+
# 2. Implement minimal code to pass
|
|
92
|
+
bun test src/thing.test.ts # GREEN - test passes
|
|
93
|
+
|
|
94
|
+
# 3. Refactor, tests still pass
|
|
95
|
+
bun test src/thing.test.ts # GREEN - still passing
|
|
96
|
+
|
|
97
|
+
# 4. Repeat for next behavior
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## TDD Patterns
|
|
101
|
+
|
|
102
|
+
### Start with the Assertion
|
|
103
|
+
|
|
104
|
+
Write the assertion first, then work backwards:
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
// Start here
|
|
108
|
+
expect(result).toBe(42);
|
|
109
|
+
|
|
110
|
+
// Then figure out what 'result' is
|
|
111
|
+
const result = calculate(input);
|
|
112
|
+
|
|
113
|
+
// Then figure out what 'input' is
|
|
114
|
+
const input = { value: 21 };
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Triangulation
|
|
118
|
+
|
|
119
|
+
Use multiple examples to drive generalization:
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
it("doubles 2", () => expect(double(2)).toBe(4));
|
|
123
|
+
it("doubles 3", () => expect(double(3)).toBe(6));
|
|
124
|
+
// Now you MUST implement the general solution
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Obvious Implementation
|
|
128
|
+
|
|
129
|
+
When the solution is obvious, just write it:
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
function add(a: number, b: number): number {
|
|
133
|
+
return a + b; // Don't fake this
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Fake It Til You Make It
|
|
138
|
+
|
|
139
|
+
When unsure, start with hardcoded values:
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
// First pass
|
|
143
|
+
function fibonacci(n: number): number {
|
|
144
|
+
return 1; // Passes for n=1
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Add test for n=2, then generalize
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Testing Pyramid
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
/\
|
|
154
|
+
/ \ E2E (few)
|
|
155
|
+
/----\
|
|
156
|
+
/ \ Integration (some)
|
|
157
|
+
/--------\
|
|
158
|
+
/ \ Unit (many)
|
|
159
|
+
--------------
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
- **Unit tests**: Fast, isolated, test one thing
|
|
163
|
+
- **Integration tests**: Test component interactions
|
|
164
|
+
- **E2E tests**: Test full user flows (expensive, use sparingly)
|
|
165
|
+
|
|
166
|
+
## Common TDD Mistakes
|
|
167
|
+
|
|
168
|
+
1. **Writing too many tests at once** - One failing test at a time
|
|
169
|
+
2. **Testing implementation, not behavior** - Test what, not how
|
|
170
|
+
3. **Skipping the refactor step** - Technical debt accumulates
|
|
171
|
+
4. **Over-mocking** - Don't mock what you don't own
|
|
172
|
+
5. **Testing private methods** - Test through public interface
|
|
173
|
+
|
|
174
|
+
## Integration with Beads
|
|
175
|
+
|
|
176
|
+
When working on a bead:
|
|
177
|
+
|
|
178
|
+
1. Start bead: `beads_start(id="bd-123")`
|
|
179
|
+
2. Write failing test for the requirement
|
|
180
|
+
3. Implement to pass
|
|
181
|
+
4. Refactor
|
|
182
|
+
5. Close bead: `beads_close(id="bd-123", reason="Done: tests passing")`
|
package/README.md
CHANGED
|
@@ -36,11 +36,11 @@ The setup wizard handles everything:
|
|
|
36
36
|
◆ OpenCode
|
|
37
37
|
◆ Beads
|
|
38
38
|
◆ Go
|
|
39
|
-
▲
|
|
39
|
+
▲ Swarm Mail (optional)
|
|
40
40
|
▲ Redis (optional)
|
|
41
41
|
│
|
|
42
42
|
◆ Install optional dependencies?
|
|
43
|
-
│ ◻
|
|
43
|
+
│ ◻ Swarm Mail - Multi-agent coordination
|
|
44
44
|
│ ◻ Redis - Rate limiting
|
|
45
45
|
│
|
|
46
46
|
◇ Setting up OpenCode integration...
|
|
@@ -271,16 +271,16 @@ What NOT to do...
|
|
|
271
271
|
|
|
272
272
|
## Dependencies
|
|
273
273
|
|
|
274
|
-
| Dependency | Purpose
|
|
275
|
-
| ------------------------------------------------------------------------------------------------------ |
|
|
276
|
-
| [OpenCode](https://opencode.ai) | Plugin host
|
|
277
|
-
| [Beads](https://github.com/steveyegge/beads) | Git-backed issue tracking
|
|
278
|
-
| [Go](https://go.dev) | Required for
|
|
279
|
-
| [MCP Agent Mail](https://github.com/Dicklesworthstone/mcp_agent_mail)
|
|
280
|
-
| [CASS (Coding Agent Session Search)](https://github.com/Dicklesworthstone/coding_agent_session_search) | Historical context from past sessions
|
|
281
|
-
| [UBS (Ultimate Bug Scanner)](https://github.com/Dicklesworthstone/ultimate_bug_scanner) | Pre-completion bug scanning using AI-powered static analysis
|
|
282
|
-
| [semantic-memory](https://github.com/joelhooks/semantic-memory) | Learning persistence
|
|
283
|
-
| [Redis](https://redis.io) | Rate limiting (SQLite fallback available)
|
|
274
|
+
| Dependency | Purpose | Required |
|
|
275
|
+
| ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | -------- |
|
|
276
|
+
| [OpenCode](https://opencode.ai) | Plugin host | Yes |
|
|
277
|
+
| [Beads](https://github.com/steveyegge/beads) | Git-backed issue tracking | Yes |
|
|
278
|
+
| [Go](https://go.dev) | Required for Swarm Mail | No |
|
|
279
|
+
| [MCP Agent Mail](https://github.com/Dicklesworthstone/mcp_agent_mail) ⭐ | **The original** - Multi-agent coordination, file reservations. Swarm Mail is built on these patterns. | No |
|
|
280
|
+
| [CASS (Coding Agent Session Search)](https://github.com/Dicklesworthstone/coding_agent_session_search) | Historical context from past sessions | No |
|
|
281
|
+
| [UBS (Ultimate Bug Scanner)](https://github.com/Dicklesworthstone/ultimate_bug_scanner) | Pre-completion bug scanning using AI-powered static analysis | No |
|
|
282
|
+
| [semantic-memory](https://github.com/joelhooks/semantic-memory) | Learning persistence | No |
|
|
283
|
+
| [Redis](https://redis.io) | Rate limiting (SQLite fallback available) | No |
|
|
284
284
|
|
|
285
285
|
All dependencies are checked and can be installed via `swarm setup`.
|
|
286
286
|
|
|
@@ -298,12 +298,14 @@ curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/ultimate_bug_sca
|
|
|
298
298
|
curl -fsSL https://raw.githubusercontent.com/Dicklesworthstone/coding_agent_session_search/main/install.sh | bash -s -- --easy-mode
|
|
299
299
|
```
|
|
300
300
|
|
|
301
|
-
**MCP Agent Mail** -
|
|
301
|
+
**MCP Agent Mail** ⭐ - The original multi-agent coordination system. Swarm Mail's embedded implementation is inspired by and compatible with MCP Agent Mail's protocol:
|
|
302
302
|
|
|
303
303
|
```bash
|
|
304
304
|
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/mcp_agent_mail/main/scripts/install.sh" | bash -s -- --yes
|
|
305
305
|
```
|
|
306
306
|
|
|
307
|
+
> **Note:** The embedded Swarm Mail (PGLite in-process) is now the primary option and works out of the box with no external dependencies. MCP Agent Mail (external Go server) is still supported for advanced use cases requiring a separate server process.
|
|
308
|
+
|
|
307
309
|
## Tools Reference
|
|
308
310
|
|
|
309
311
|
### Swarm
|
|
@@ -315,7 +317,7 @@ curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/mcp_agent_mail/m
|
|
|
315
317
|
| `swarm_plan_prompt` | Generate strategy-specific planning prompt with CASS history |
|
|
316
318
|
| `swarm_decompose` | Generate decomposition prompt |
|
|
317
319
|
| `swarm_validate_decomposition` | Validate response, detect file conflicts |
|
|
318
|
-
| `swarm_spawn_subtask` | Generate worker agent prompt with
|
|
320
|
+
| `swarm_spawn_subtask` | Generate worker agent prompt with Swarm Mail/beads instructions |
|
|
319
321
|
| `swarm_status` | Get swarm progress by epic ID |
|
|
320
322
|
| `swarm_progress` | Report subtask progress to coordinator |
|
|
321
323
|
| `swarm_complete` | Complete subtask - runs UBS (Ultimate Bug Scanner), releases reservations |
|
|
@@ -333,9 +335,22 @@ curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/mcp_agent_mail/m
|
|
|
333
335
|
| `beads_start` | Mark bead as in-progress |
|
|
334
336
|
| `beads_ready` | Get next unblocked bead |
|
|
335
337
|
| `beads_sync` | Sync to git and push |
|
|
336
|
-
| `beads_link_thread` | Link bead to
|
|
338
|
+
| `beads_link_thread` | Link bead to Swarm Mail thread |
|
|
339
|
+
|
|
340
|
+
### Swarm Mail (Embedded - Primary)
|
|
341
|
+
|
|
342
|
+
| Tool | Description |
|
|
343
|
+
| ------------------------ | --------------------------------------------- |
|
|
344
|
+
| `swarmmail_init` | Initialize session, register agent |
|
|
345
|
+
| `swarmmail_send` | Send message to agents |
|
|
346
|
+
| `swarmmail_inbox` | Fetch inbox (max 5, no bodies - context safe) |
|
|
347
|
+
| `swarmmail_read_message` | Fetch single message body by ID |
|
|
348
|
+
| `swarmmail_reserve` | Reserve file paths for exclusive editing |
|
|
349
|
+
| `swarmmail_release` | Release file reservations |
|
|
350
|
+
| `swarmmail_ack` | Acknowledge message |
|
|
351
|
+
| `swarmmail_health` | Check embedded database health |
|
|
337
352
|
|
|
338
|
-
### Agent Mail
|
|
353
|
+
### Agent Mail (Legacy MCP - Optional)
|
|
339
354
|
|
|
340
355
|
| Tool | Description |
|
|
341
356
|
| ---------------------------- | ---------------------------------------------- |
|
|
@@ -348,7 +363,140 @@ curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/mcp_agent_mail/m
|
|
|
348
363
|
| `agentmail_release` | Release file reservations |
|
|
349
364
|
| `agentmail_ack` | Acknowledge message |
|
|
350
365
|
| `agentmail_search` | Search messages by keyword |
|
|
351
|
-
| `agentmail_health` | Check if Agent Mail server is running
|
|
366
|
+
| `agentmail_health` | Check if MCP Agent Mail server is running |
|
|
367
|
+
|
|
368
|
+
## Event-Sourced Architecture (Embedded)
|
|
369
|
+
|
|
370
|
+
> **🙏 Built on the shoulders of giants**
|
|
371
|
+
>
|
|
372
|
+
> The Swarm Mail system is deeply inspired by and builds upon [**MCP Agent Mail**](https://github.com/Dicklesworthstone/mcp_agent_mail) by [@Dicklesworthstone](https://github.com/Dicklesworthstone). The original MCP Agent Mail pioneered multi-agent coordination patterns including file reservations, thread-based messaging, and agent registration - concepts that form the foundation of this embedded implementation.
|
|
373
|
+
>
|
|
374
|
+
> If you need a production-ready, battle-tested solution with a full Go server, **use MCP Agent Mail directly**. This embedded version is an experimental alternative that trades the external server for in-process PGLite, optimized for single-machine development workflows.
|
|
375
|
+
>
|
|
376
|
+
> **Key contributions from MCP Agent Mail:**
|
|
377
|
+
>
|
|
378
|
+
> - File reservation protocol with conflict detection
|
|
379
|
+
> - Agent registration and heartbeat patterns
|
|
380
|
+
> - Thread-based message organization
|
|
381
|
+
> - Importance levels and acknowledgment tracking
|
|
382
|
+
>
|
|
383
|
+
> Thank you to the MCP Agent Mail team for open-sourcing such a well-designed system.
|
|
384
|
+
|
|
385
|
+
The plugin includes an embedded event-sourced Swarm Mail implementation as an alternative to the external MCP server. This provides the same multi-agent coordination capabilities without requiring a separate server process.
|
|
386
|
+
|
|
387
|
+
### Architecture Comparison
|
|
388
|
+
|
|
389
|
+
**MCP-based (external):**
|
|
390
|
+
|
|
391
|
+
```
|
|
392
|
+
plugin tools → HTTP → MCP Server (Go process) → SQLite
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
**Event-sourced (embedded):**
|
|
396
|
+
|
|
397
|
+
```
|
|
398
|
+
plugin tools → streams/agent-mail.ts → streams/store.ts → PGLite (in-process)
|
|
399
|
+
↓
|
|
400
|
+
streams/projections.ts
|
|
401
|
+
↓
|
|
402
|
+
Materialized views (agents, messages, reservations)
|
|
403
|
+
↓
|
|
404
|
+
Fast reads
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
### Architecture Flow
|
|
408
|
+
|
|
409
|
+
```
|
|
410
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
411
|
+
│ Plugin Tools Layer │
|
|
412
|
+
│ (agentmail_init, agentmail_send, agentmail_reserve, etc.) │
|
|
413
|
+
└──────────────────────────────┬──────────────────────────────────┘
|
|
414
|
+
│
|
|
415
|
+
▼
|
|
416
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
417
|
+
│ streams/agent-mail.ts │
|
|
418
|
+
│ (High-level API wrapper) │
|
|
419
|
+
└──────────────────────────────┬──────────────────────────────────┘
|
|
420
|
+
│
|
|
421
|
+
▼
|
|
422
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
423
|
+
│ streams/events.ts │
|
|
424
|
+
│ 11 event types: agent_registered, message_sent, │
|
|
425
|
+
│ file_reserved, message_read, message_acked, etc. │
|
|
426
|
+
└──────────────────────────────┬──────────────────────────────────┘
|
|
427
|
+
│
|
|
428
|
+
▼
|
|
429
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
430
|
+
│ streams/store.ts │
|
|
431
|
+
│ Append-only event log (PGLite storage) │
|
|
432
|
+
│ appendEvent() • readEvents() • replayEvents() │
|
|
433
|
+
└──────────────────────────────┬──────────────────────────────────┘
|
|
434
|
+
│
|
|
435
|
+
▼
|
|
436
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
437
|
+
│ streams/projections.ts │
|
|
438
|
+
│ Build materialized views from events │
|
|
439
|
+
│ getAgents() • getInbox() • getActiveReservations() │
|
|
440
|
+
│ checkConflicts() • threadStats() │
|
|
441
|
+
└─────────────────────────────┬────────────────────────────────────┘
|
|
442
|
+
│
|
|
443
|
+
▼
|
|
444
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
445
|
+
│ Materialized Tables (Derived State) │
|
|
446
|
+
│ agents • messages • reservations • message_reads │
|
|
447
|
+
│ (Rebuilt by replaying event log) │
|
|
448
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
### Module Descriptions
|
|
452
|
+
|
|
453
|
+
| Module | Responsibility |
|
|
454
|
+
| -------------------------- | -------------------------------------------------------------------------------------------------- |
|
|
455
|
+
| **streams/events.ts** | Zod schemas for 11 event types (agent_registered, message_sent, file_reserved, task_progress, etc) |
|
|
456
|
+
| **streams/store.ts** | Append-only event log with PGLite backend (appendEvent, readEvents, replayEvents) |
|
|
457
|
+
| **streams/projections.ts** | Materialize views from events (getAgents, getInbox, checkConflicts, threadStats) |
|
|
458
|
+
| **streams/agent-mail.ts** | High-level API matching MCP interface (initAgent, sendAgentMessage, reserveAgentFiles) |
|
|
459
|
+
| **streams/debug.ts** | Debugging utilities (debugEvents, debugAgent, debugMessage, inspectState) |
|
|
460
|
+
|
|
461
|
+
### Key Benefits
|
|
462
|
+
|
|
463
|
+
- **No external dependencies** - Runs in-process with PGLite (Postgres compiled to WASM)
|
|
464
|
+
- **Full audit trail** - Every state change is an immutable event
|
|
465
|
+
- **Crash recovery** - Rebuild state by replaying events from log
|
|
466
|
+
- **Time-travel debugging** - Replay events up to any point in time
|
|
467
|
+
- **Testability** - 127 tests passing across streams module
|
|
468
|
+
- **Durable Streams protocol** - Inspired by Electric SQL's event sourcing patterns
|
|
469
|
+
|
|
470
|
+
### Event Types
|
|
471
|
+
|
|
472
|
+
The system emits 11 event types tracked in `streams/events.ts`:
|
|
473
|
+
|
|
474
|
+
| Event | Triggered By |
|
|
475
|
+
| ------------------ | ------------------------------------- |
|
|
476
|
+
| `agent_registered` | Agent initialization |
|
|
477
|
+
| `message_sent` | Sending inter-agent message |
|
|
478
|
+
| `file_reserved` | Reserving files for exclusive editing |
|
|
479
|
+
| `file_released` | Releasing file reservations |
|
|
480
|
+
| `message_read` | Reading a message |
|
|
481
|
+
| `message_acked` | Acknowledging a message |
|
|
482
|
+
| `task_started` | Starting work on a bead |
|
|
483
|
+
| `task_progress` | Reporting progress update |
|
|
484
|
+
| `task_completed` | Completing a bead |
|
|
485
|
+
| `task_blocked` | Marking a task as blocked |
|
|
486
|
+
| `agent_active` | Agent heartbeat/keep-alive |
|
|
487
|
+
|
|
488
|
+
### Materialized Views
|
|
489
|
+
|
|
490
|
+
Projections build these derived tables from the event log:
|
|
491
|
+
|
|
492
|
+
| View | Contains |
|
|
493
|
+
| --------------- | ------------------------------------------------------ |
|
|
494
|
+
| `agents` | Registered agents with metadata and last activity |
|
|
495
|
+
| `messages` | All inter-agent messages with thread/importance |
|
|
496
|
+
| `reservations` | Active file reservations with TTL and exclusivity flag |
|
|
497
|
+
| `message_reads` | Read receipts for message tracking |
|
|
498
|
+
|
|
499
|
+
State is always derived - delete the tables and replay events to rebuild.
|
|
352
500
|
|
|
353
501
|
### Structured Output
|
|
354
502
|
|
package/bin/swarm.ts
CHANGED
|
@@ -497,23 +497,65 @@ $ARGUMENTS
|
|
|
497
497
|
|
|
498
498
|
## Workflow
|
|
499
499
|
|
|
500
|
-
1.
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
500
|
+
### 1. Initialize
|
|
501
|
+
\`agentmail_init(project_path="$PWD", task_description="Swarm: <task>")\`
|
|
502
|
+
|
|
503
|
+
### 2. Knowledge Gathering (MANDATORY)
|
|
504
|
+
|
|
505
|
+
**Before decomposing, query ALL knowledge sources:**
|
|
506
|
+
|
|
507
|
+
\`\`\`
|
|
508
|
+
semantic-memory_find(query="<task keywords>", limit=5) # Past learnings
|
|
509
|
+
cass_search(query="<task description>", limit=5) # Similar past tasks
|
|
510
|
+
pdf-brain_search(query="<domain concepts>", limit=5) # Design patterns
|
|
511
|
+
skills_list() # Available skills
|
|
512
|
+
\`\`\`
|
|
513
|
+
|
|
514
|
+
Synthesize findings into shared_context for workers.
|
|
515
|
+
|
|
516
|
+
### 3. Decompose
|
|
517
|
+
\`\`\`
|
|
518
|
+
swarm_select_strategy(task="<task>")
|
|
519
|
+
swarm_plan_prompt(task="<task>", context="<synthesized knowledge>")
|
|
520
|
+
swarm_validate_decomposition(response="<BeadTree JSON>")
|
|
521
|
+
\`\`\`
|
|
522
|
+
|
|
523
|
+
### 4. Create Beads
|
|
524
|
+
\`beads_create_epic(epic_title="<task>", subtasks=[...])\`
|
|
525
|
+
|
|
526
|
+
### 5. Reserve Files
|
|
527
|
+
\`agentmail_reserve(paths=[...], reason="<bead-id>: <desc>")\`
|
|
528
|
+
|
|
529
|
+
### 6. Spawn Agents (ALL in single message)
|
|
530
|
+
\`\`\`
|
|
531
|
+
swarm_spawn_subtask(bead_id, epic_id, subtask_title, files, shared_context)
|
|
532
|
+
Task(subagent_type="swarm/worker", prompt="<from above>")
|
|
533
|
+
\`\`\`
|
|
534
|
+
|
|
535
|
+
### 7. Monitor
|
|
536
|
+
\`\`\`
|
|
537
|
+
swarm_status(epic_id, project_key)
|
|
538
|
+
agentmail_inbox()
|
|
539
|
+
\`\`\`
|
|
540
|
+
|
|
541
|
+
Intervene if: blocked >5min, file conflicts, scope creep.
|
|
542
|
+
|
|
543
|
+
### 8. Complete
|
|
544
|
+
\`\`\`
|
|
545
|
+
swarm_complete(...)
|
|
546
|
+
beads_sync()
|
|
547
|
+
\`\`\`
|
|
548
|
+
|
|
549
|
+
## Strategy Reference
|
|
550
|
+
|
|
551
|
+
| Strategy | Best For | Keywords |
|
|
552
|
+
| -------------- | ------------------------ | -------------------------------------- |
|
|
553
|
+
| file-based | Refactoring, migrations | refactor, migrate, rename, update all |
|
|
554
|
+
| feature-based | New features | add, implement, build, create, feature |
|
|
555
|
+
| risk-based | Bug fixes, security | fix, bug, security, critical, urgent |
|
|
556
|
+
| research-based | Investigation, discovery | research, investigate, explore, learn |
|
|
557
|
+
|
|
558
|
+
Begin with knowledge gathering now.
|
|
517
559
|
`;
|
|
518
560
|
|
|
519
561
|
const getPlannerAgent = (model: string) => `---
|
|
@@ -526,12 +568,30 @@ You are a swarm planner. Decompose tasks into optimal parallel subtasks.
|
|
|
526
568
|
|
|
527
569
|
## Workflow
|
|
528
570
|
|
|
529
|
-
1.
|
|
530
|
-
2. Call \`swarm_plan_prompt\` to get strategy-specific guidance
|
|
531
|
-
3. Create a BeadTree following the guidelines
|
|
532
|
-
4. Return ONLY valid JSON - no markdown, no explanation
|
|
571
|
+
### 1. Knowledge Gathering (MANDATORY)
|
|
533
572
|
|
|
534
|
-
|
|
573
|
+
**Before decomposing, query ALL knowledge sources:**
|
|
574
|
+
|
|
575
|
+
\`\`\`
|
|
576
|
+
semantic-memory_find(query="<task keywords>", limit=5) # Past learnings
|
|
577
|
+
cass_search(query="<task description>", limit=5) # Similar past tasks
|
|
578
|
+
pdf-brain_search(query="<domain concepts>", limit=5) # Design patterns
|
|
579
|
+
skills_list() # Available skills
|
|
580
|
+
\`\`\`
|
|
581
|
+
|
|
582
|
+
Synthesize findings - note relevant patterns, past approaches, and skills to recommend.
|
|
583
|
+
|
|
584
|
+
### 2. Strategy Selection
|
|
585
|
+
|
|
586
|
+
\`swarm_select_strategy(task="<task>")\`
|
|
587
|
+
|
|
588
|
+
### 3. Generate Plan
|
|
589
|
+
|
|
590
|
+
\`swarm_plan_prompt(task="<task>", context="<synthesized knowledge>")\`
|
|
591
|
+
|
|
592
|
+
### 4. Output BeadTree
|
|
593
|
+
|
|
594
|
+
Return ONLY valid JSON - no markdown, no explanation:
|
|
535
595
|
|
|
536
596
|
\`\`\`json
|
|
537
597
|
{
|
|
@@ -539,7 +599,7 @@ You are a swarm planner. Decompose tasks into optimal parallel subtasks.
|
|
|
539
599
|
"subtasks": [
|
|
540
600
|
{
|
|
541
601
|
"title": "...",
|
|
542
|
-
"description": "
|
|
602
|
+
"description": "Include relevant context from knowledge gathering",
|
|
543
603
|
"files": ["src/..."],
|
|
544
604
|
"dependencies": [],
|
|
545
605
|
"estimated_complexity": 2
|
|
@@ -554,6 +614,7 @@ You are a swarm planner. Decompose tasks into optimal parallel subtasks.
|
|
|
554
614
|
- No file overlap between subtasks
|
|
555
615
|
- Include tests with the code they test
|
|
556
616
|
- Order by dependency (if B needs A, A comes first)
|
|
617
|
+
- Pass synthesized knowledge to workers via subtask descriptions
|
|
557
618
|
`;
|
|
558
619
|
|
|
559
620
|
const getWorkerAgent = (model: string) => `---
|
|
@@ -564,17 +625,45 @@ model: ${model}
|
|
|
564
625
|
|
|
565
626
|
You are a swarm worker agent. Execute your assigned subtask efficiently.
|
|
566
627
|
|
|
628
|
+
## Context
|
|
629
|
+
|
|
630
|
+
Your prompt includes shared_context from the coordinator's knowledge gathering:
|
|
631
|
+
- Relevant patterns from pdf-brain
|
|
632
|
+
- Similar past approaches from CASS
|
|
633
|
+
- Project-specific learnings from semantic-memory
|
|
634
|
+
|
|
635
|
+
**Use this context** - it contains patterns and prior art relevant to your task.
|
|
636
|
+
|
|
637
|
+
## Workflow
|
|
638
|
+
|
|
639
|
+
1. **Read** assigned files to understand current state
|
|
640
|
+
2. **Check skills** if you need domain guidance: \`skills_use(name="<relevant-skill>")\`
|
|
641
|
+
3. **Implement** changes following patterns from shared_context
|
|
642
|
+
4. **Verify** (typecheck, lint if applicable)
|
|
643
|
+
5. **Complete** with \`swarm_complete\`
|
|
644
|
+
|
|
567
645
|
## Rules
|
|
646
|
+
|
|
568
647
|
- Focus ONLY on your assigned files
|
|
569
|
-
- Report
|
|
570
|
-
- Use beads_update
|
|
571
|
-
- Call swarm_complete when done
|
|
648
|
+
- Report blockers immediately via Agent Mail (don't spin)
|
|
649
|
+
- Use beads_update if blocked
|
|
650
|
+
- Call swarm_complete when done - it handles bead closure and file release
|
|
572
651
|
|
|
573
|
-
##
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
652
|
+
## Communication
|
|
653
|
+
|
|
654
|
+
\`\`\`
|
|
655
|
+
agentmail_send(
|
|
656
|
+
to=["coordinator"],
|
|
657
|
+
subject="Progress/Blocker",
|
|
658
|
+
body="...",
|
|
659
|
+
thread_id="<epic_id>"
|
|
660
|
+
)
|
|
661
|
+
\`\`\`
|
|
662
|
+
|
|
663
|
+
## Learning
|
|
664
|
+
|
|
665
|
+
If you discover a reusable pattern worth preserving:
|
|
666
|
+
\`semantic-memory_store(information="<pattern + why it matters>")\`
|
|
578
667
|
`;
|
|
579
668
|
|
|
580
669
|
// ============================================================================
|