@mandible-ai/mandible 0.2.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.
Files changed (187) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +391 -0
  3. package/dist/examples/code-pipeline/index.d.ts +3 -0
  4. package/dist/examples/code-pipeline/index.d.ts.map +1 -0
  5. package/dist/examples/code-pipeline/index.js +239 -0
  6. package/dist/examples/code-pipeline/index.js.map +1 -0
  7. package/dist/examples/code-pipeline/with-providers.d.ts +3 -0
  8. package/dist/examples/code-pipeline/with-providers.d.ts.map +1 -0
  9. package/dist/examples/code-pipeline/with-providers.js +246 -0
  10. package/dist/examples/code-pipeline/with-providers.js.map +1 -0
  11. package/dist/examples/docker-pipeline/index.d.ts +3 -0
  12. package/dist/examples/docker-pipeline/index.d.ts.map +1 -0
  13. package/dist/examples/docker-pipeline/index.js +235 -0
  14. package/dist/examples/docker-pipeline/index.js.map +1 -0
  15. package/dist/examples/github-colony/mandible.config.d.ts +11 -0
  16. package/dist/examples/github-colony/mandible.config.d.ts.map +1 -0
  17. package/dist/examples/github-colony/mandible.config.js +63 -0
  18. package/dist/examples/github-colony/mandible.config.js.map +1 -0
  19. package/dist/examples/remote-pipeline/index.d.ts +3 -0
  20. package/dist/examples/remote-pipeline/index.d.ts.map +1 -0
  21. package/dist/examples/remote-pipeline/index.js +154 -0
  22. package/dist/examples/remote-pipeline/index.js.map +1 -0
  23. package/dist/examples/repo-maintenance/fixer.d.ts +80 -0
  24. package/dist/examples/repo-maintenance/fixer.d.ts.map +1 -0
  25. package/dist/examples/repo-maintenance/fixer.js +217 -0
  26. package/dist/examples/repo-maintenance/fixer.js.map +1 -0
  27. package/dist/examples/repo-maintenance/mandible.config.d.ts +11 -0
  28. package/dist/examples/repo-maintenance/mandible.config.d.ts.map +1 -0
  29. package/dist/examples/repo-maintenance/mandible.config.js +34 -0
  30. package/dist/examples/repo-maintenance/mandible.config.js.map +1 -0
  31. package/dist/examples/repo-maintenance/scout.d.ts +39 -0
  32. package/dist/examples/repo-maintenance/scout.d.ts.map +1 -0
  33. package/dist/examples/repo-maintenance/scout.js +163 -0
  34. package/dist/examples/repo-maintenance/scout.js.map +1 -0
  35. package/dist/examples/repo-maintenance/seed.d.ts +3 -0
  36. package/dist/examples/repo-maintenance/seed.d.ts.map +1 -0
  37. package/dist/examples/repo-maintenance/seed.js +169 -0
  38. package/dist/examples/repo-maintenance/seed.js.map +1 -0
  39. package/dist/src/cli/index.d.ts +3 -0
  40. package/dist/src/cli/index.d.ts.map +1 -0
  41. package/dist/src/cli/index.js +116 -0
  42. package/dist/src/cli/index.js.map +1 -0
  43. package/dist/src/cli/server.d.ts +15 -0
  44. package/dist/src/cli/server.d.ts.map +1 -0
  45. package/dist/src/cli/server.js +204 -0
  46. package/dist/src/cli/server.js.map +1 -0
  47. package/dist/src/cloud/client.d.ts +30 -0
  48. package/dist/src/cloud/client.d.ts.map +1 -0
  49. package/dist/src/cloud/client.js +124 -0
  50. package/dist/src/cloud/client.js.map +1 -0
  51. package/dist/src/cloud/index.d.ts +5 -0
  52. package/dist/src/cloud/index.d.ts.map +1 -0
  53. package/dist/src/cloud/index.js +3 -0
  54. package/dist/src/cloud/index.js.map +1 -0
  55. package/dist/src/cloud/types.d.ts +104 -0
  56. package/dist/src/cloud/types.d.ts.map +1 -0
  57. package/dist/src/cloud/types.js +9 -0
  58. package/dist/src/cloud/types.js.map +1 -0
  59. package/dist/src/core/attestation.d.ts +63 -0
  60. package/dist/src/core/attestation.d.ts.map +1 -0
  61. package/dist/src/core/attestation.js +331 -0
  62. package/dist/src/core/attestation.js.map +1 -0
  63. package/dist/src/core/events.d.ts +22 -0
  64. package/dist/src/core/events.d.ts.map +1 -0
  65. package/dist/src/core/events.js +45 -0
  66. package/dist/src/core/events.js.map +1 -0
  67. package/dist/src/core/index.d.ts +8 -0
  68. package/dist/src/core/index.d.ts.map +1 -0
  69. package/dist/src/core/index.js +7 -0
  70. package/dist/src/core/index.js.map +1 -0
  71. package/dist/src/core/runtime.d.ts +57 -0
  72. package/dist/src/core/runtime.d.ts.map +1 -0
  73. package/dist/src/core/runtime.js +564 -0
  74. package/dist/src/core/runtime.js.map +1 -0
  75. package/dist/src/core/signal.d.ts +33 -0
  76. package/dist/src/core/signal.d.ts.map +1 -0
  77. package/dist/src/core/signal.js +127 -0
  78. package/dist/src/core/signal.js.map +1 -0
  79. package/dist/src/core/types.d.ts +395 -0
  80. package/dist/src/core/types.d.ts.map +1 -0
  81. package/dist/src/core/types.js +19 -0
  82. package/dist/src/core/types.js.map +1 -0
  83. package/dist/src/core/validation.d.ts +10 -0
  84. package/dist/src/core/validation.d.ts.map +1 -0
  85. package/dist/src/core/validation.js +40 -0
  86. package/dist/src/core/validation.js.map +1 -0
  87. package/dist/src/dsl/builder.d.ts +63 -0
  88. package/dist/src/dsl/builder.d.ts.map +1 -0
  89. package/dist/src/dsl/builder.js +159 -0
  90. package/dist/src/dsl/builder.js.map +1 -0
  91. package/dist/src/dsl/index.d.ts +2 -0
  92. package/dist/src/dsl/index.d.ts.map +1 -0
  93. package/dist/src/dsl/index.js +2 -0
  94. package/dist/src/dsl/index.js.map +1 -0
  95. package/dist/src/environments/dolt/adapter.d.ts +45 -0
  96. package/dist/src/environments/dolt/adapter.d.ts.map +1 -0
  97. package/dist/src/environments/dolt/adapter.js +128 -0
  98. package/dist/src/environments/dolt/adapter.js.map +1 -0
  99. package/dist/src/environments/dolt/index.d.ts +2 -0
  100. package/dist/src/environments/dolt/index.d.ts.map +1 -0
  101. package/dist/src/environments/dolt/index.js +2 -0
  102. package/dist/src/environments/dolt/index.js.map +1 -0
  103. package/dist/src/environments/filesystem/adapter.d.ts +33 -0
  104. package/dist/src/environments/filesystem/adapter.d.ts.map +1 -0
  105. package/dist/src/environments/filesystem/adapter.js +296 -0
  106. package/dist/src/environments/filesystem/adapter.js.map +1 -0
  107. package/dist/src/environments/filesystem/index.d.ts +2 -0
  108. package/dist/src/environments/filesystem/index.d.ts.map +1 -0
  109. package/dist/src/environments/filesystem/index.js +2 -0
  110. package/dist/src/environments/filesystem/index.js.map +1 -0
  111. package/dist/src/environments/github/adapter.d.ts +47 -0
  112. package/dist/src/environments/github/adapter.d.ts.map +1 -0
  113. package/dist/src/environments/github/adapter.js +324 -0
  114. package/dist/src/environments/github/adapter.js.map +1 -0
  115. package/dist/src/environments/github/client.d.ts +48 -0
  116. package/dist/src/environments/github/client.d.ts.map +1 -0
  117. package/dist/src/environments/github/client.js +151 -0
  118. package/dist/src/environments/github/client.js.map +1 -0
  119. package/dist/src/environments/github/index.d.ts +5 -0
  120. package/dist/src/environments/github/index.d.ts.map +1 -0
  121. package/dist/src/environments/github/index.js +5 -0
  122. package/dist/src/environments/github/index.js.map +1 -0
  123. package/dist/src/environments/github/mapper.d.ts +66 -0
  124. package/dist/src/environments/github/mapper.d.ts.map +1 -0
  125. package/dist/src/environments/github/mapper.js +240 -0
  126. package/dist/src/environments/github/mapper.js.map +1 -0
  127. package/dist/src/environments/github/types.d.ts +71 -0
  128. package/dist/src/environments/github/types.d.ts.map +1 -0
  129. package/dist/src/environments/github/types.js +4 -0
  130. package/dist/src/environments/github/types.js.map +1 -0
  131. package/dist/src/environments/remote/adapter.d.ts +61 -0
  132. package/dist/src/environments/remote/adapter.d.ts.map +1 -0
  133. package/dist/src/environments/remote/adapter.js +392 -0
  134. package/dist/src/environments/remote/adapter.js.map +1 -0
  135. package/dist/src/environments/remote/index.d.ts +5 -0
  136. package/dist/src/environments/remote/index.d.ts.map +1 -0
  137. package/dist/src/environments/remote/index.js +3 -0
  138. package/dist/src/environments/remote/index.js.map +1 -0
  139. package/dist/src/environments/remote/protocol.d.ts +124 -0
  140. package/dist/src/environments/remote/protocol.d.ts.map +1 -0
  141. package/dist/src/environments/remote/protocol.js +24 -0
  142. package/dist/src/environments/remote/protocol.js.map +1 -0
  143. package/dist/src/index.d.ts +25 -0
  144. package/dist/src/index.d.ts.map +1 -0
  145. package/dist/src/index.js +31 -0
  146. package/dist/src/index.js.map +1 -0
  147. package/dist/src/patterns/bridge.d.ts +32 -0
  148. package/dist/src/patterns/bridge.d.ts.map +1 -0
  149. package/dist/src/patterns/bridge.js +163 -0
  150. package/dist/src/patterns/bridge.js.map +1 -0
  151. package/dist/src/patterns/index.d.ts +5 -0
  152. package/dist/src/patterns/index.d.ts.map +1 -0
  153. package/dist/src/patterns/index.js +3 -0
  154. package/dist/src/patterns/index.js.map +1 -0
  155. package/dist/src/patterns/sentinel.d.ts +69 -0
  156. package/dist/src/patterns/sentinel.d.ts.map +1 -0
  157. package/dist/src/patterns/sentinel.js +184 -0
  158. package/dist/src/patterns/sentinel.js.map +1 -0
  159. package/dist/src/providers/agent.d.ts +23 -0
  160. package/dist/src/providers/agent.d.ts.map +1 -0
  161. package/dist/src/providers/agent.js +184 -0
  162. package/dist/src/providers/agent.js.map +1 -0
  163. package/dist/src/providers/bash.d.ts +13 -0
  164. package/dist/src/providers/bash.d.ts.map +1 -0
  165. package/dist/src/providers/bash.js +91 -0
  166. package/dist/src/providers/bash.js.map +1 -0
  167. package/dist/src/providers/claude-code.d.ts +23 -0
  168. package/dist/src/providers/claude-code.d.ts.map +1 -0
  169. package/dist/src/providers/claude-code.js +184 -0
  170. package/dist/src/providers/claude-code.js.map +1 -0
  171. package/dist/src/providers/context.d.ts +12 -0
  172. package/dist/src/providers/context.d.ts.map +1 -0
  173. package/dist/src/providers/context.js +160 -0
  174. package/dist/src/providers/context.js.map +1 -0
  175. package/dist/src/providers/index.d.ts +6 -0
  176. package/dist/src/providers/index.d.ts.map +1 -0
  177. package/dist/src/providers/index.js +7 -0
  178. package/dist/src/providers/index.js.map +1 -0
  179. package/dist/src/providers/structured-output.d.ts +7 -0
  180. package/dist/src/providers/structured-output.d.ts.map +1 -0
  181. package/dist/src/providers/structured-output.js +316 -0
  182. package/dist/src/providers/structured-output.js.map +1 -0
  183. package/dist/src/providers/types.d.ts +239 -0
  184. package/dist/src/providers/types.d.ts.map +1 -0
  185. package/dist/src/providers/types.js +19 -0
  186. package/dist/src/providers/types.js.map +1 -0
  187. package/package.json +129 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Mandible
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,391 @@
1
+ # Mandible
2
+
3
+ ![CI](https://github.com/mandible-ai/mandible/actions/workflows/ci.yml/badge.svg)
4
+ ![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)
5
+ ![Node](https://img.shields.io/badge/Node-%3E%3D20-brightgreen.svg)
6
+
7
+ A universal stigmergy framework for autonomous agent coordination.
8
+
9
+ Instead of wiring agents together with message passing, Mandible agents coordinate by depositing and sensing **signals** in a shared **environment** — the same way ant colonies self-organize through pheromone trails. No orchestrator. No message routing. Complex behavior emerges from simple rules.
10
+
11
+ [mandible.dev](https://mandible.dev)
12
+
13
+ ## Why stigmergy over message passing?
14
+
15
+ Most multi-agent frameworks coordinate agents through direct messaging. This reimplements distributed systems problems — service discovery, routing, consensus, backpressure — but for LLMs.
16
+
17
+ Stigmergy sidesteps all of that. The environment carries the state. Agents are stateless reactive workers. You never need to answer "who should I tell about this?" — you just modify the environment, and whoever cares will notice.
18
+
19
+ **What you get:**
20
+
21
+ - **Observability for free** — the environment *is* the log. `ls` the signals directory and see the full system state.
22
+ - **Fault tolerance** — an agent dies, the signal remains, another agent picks it up. No lost messages.
23
+ - **Zero coupling** — add or remove colony types without touching any existing colony's configuration.
24
+ - **Natural load balancing** — spin up more instances of any colony type. They self-organize around available work.
25
+ - **Provenance built in** — every signal is signed by the colony that produced it. Bridges attest transfers. Trust is verifiable.
26
+
27
+ ## Quick start
28
+
29
+ ```bash
30
+ npm install mandible
31
+ ```
32
+
33
+ ```typescript
34
+ import { colony, createRuntime, FilesystemEnvironment, withClaudeCode } from 'mandible';
35
+
36
+ const env = new FilesystemEnvironment({ root: './.mandible/signals' });
37
+
38
+ const shaper = colony('shaper')
39
+ .in(env)
40
+ .sense('task:ready', { unclaimed: true })
41
+ .do(withClaudeCode({
42
+ systemPrompt: 'You are a code shaper. Given a task, write the implementation.',
43
+ allowedTools: ['Read', 'Write', 'Bash'],
44
+ }))
45
+ .concurrency(2)
46
+ .claim('lease', 30_000)
47
+ .build();
48
+
49
+ const critic = colony('critic')
50
+ .in(env)
51
+ .sense('task:shaped', { unclaimed: true })
52
+ .do(withClaudeCode({
53
+ systemPrompt: 'You are a code critic. Review the implementation for correctness and style.',
54
+ allowedTools: ['Read'],
55
+ }))
56
+ .claim('exclusive')
57
+ .build();
58
+
59
+ // Start them — they self-organize from here
60
+ const shaperRuntime = createRuntime(shaper);
61
+ const criticRuntime = createRuntime(critic);
62
+ await shaperRuntime.start();
63
+ await criticRuntime.start();
64
+ ```
65
+
66
+ No colony references any other colony. They coordinate entirely through signals in the environment.
67
+
68
+ ### Run with the dashboard
69
+
70
+ The fastest way to see colonies in action is the CLI:
71
+
72
+ ```bash
73
+ mandible dev examples/repo-maintenance/mandible.config.ts
74
+ ```
75
+
76
+ This starts all colonies and opens the live dashboard at `localhost:4040`. See the [Dashboard](#dashboard) section for details.
77
+
78
+ A ready-made demo is available:
79
+
80
+ ```bash
81
+ npm run demo:repo-maintenance
82
+ ```
83
+
84
+ ## Dashboard
85
+
86
+ `mandible dev <config>` runs your colonies and opens a live dashboard in the browser.
87
+
88
+ - Real-time signal flow — watch signals appear, get claimed, and cascade through colonies
89
+ - Colony status cards — running state, concurrency, claim counts, heartbeat health
90
+ - WebSocket streaming — updates push instantly, no polling
91
+
92
+ ```bash
93
+ mandible dev mandible.config.ts # default: localhost:4040
94
+ mandible dev mandible.config.ts --port 8080 # custom port
95
+ mandible dev mandible.config.ts --no-open # skip auto-opening browser
96
+ ```
97
+
98
+ *Dashboard GIF coming soon*
99
+
100
+ ## Architecture
101
+
102
+ ![Mandible architecture](docs/mandible-architecture.png)
103
+
104
+ ## Core concepts
105
+
106
+ Every concept maps to a biological analogy:
107
+
108
+ | Mandible | Biology | Description |
109
+ |----------|---------|-------------|
110
+ | **Signal** | Pheromone | A typed marker deposited in the environment with a payload, concentration, and TTL. |
111
+ | **Environment** | Substrate | The shared medium agents read from and write to. Filesystem, GitHub, Remote, Dolt. |
112
+ | **Colony** | Ant caste | A group of identical agents with shared sensors, rules, and claim strategy. |
113
+ | **Sensor** | Antennae | How a colony perceives signals. A query pattern like `task:ready` or `review:*`. |
114
+ | **Rule** | Instinct | A stimulus→response mapping: "when I sense X, do Y and deposit Z." |
115
+ | **Concentration** | Pheromone strength | Signal priority (1.0 → 0.0). Agents prioritize stronger signals. |
116
+ | **Decay** | Evaporation | Signals weaken over time, preventing stale work from accumulating. |
117
+ | **Colony Identity** | Colony scent | Ed25519 keypair. Every signal is signed by the colony that produced it. |
118
+ | **Attestation** | Trail markers | Bridges sign transfers, creating a verifiable chain of custody across environments. |
119
+ | **Sentinel** | Guard ant | Monitors an environment for signals that fail provenance verification. |
120
+
121
+ ## The stigmergy loop
122
+
123
+ Every colony runtime executes the same loop:
124
+
125
+ ```
126
+ sense → match rules → claim → execute action → deposit → (others sense)
127
+ ```
128
+
129
+ 1. **Sense** — poll or watch the environment for signals matching the colony's sensor queries.
130
+ 2. **Match** — evaluate rules against sensed signals, ordered by priority.
131
+ 3. **Claim** — attempt to claim the signal (prevents duplicate work across concurrent agents).
132
+ 4. **Act** — execute the matched rule's action (LLM call, shell command, custom function).
133
+ 5. **Deposit** — leave new signed signals in the environment as output.
134
+
135
+ Other colonies sense those deposited signals and the cycle continues. Complex workflows emerge from simple local rules.
136
+
137
+ ## Colony DSL
138
+
139
+ ```typescript
140
+ colony('name')
141
+ .in(env) // which environment
142
+ .sense('type:pattern', { unclaimed: true }) // what to watch for
143
+ .when(signal => signal.payload.priority > 0) // optional guard
144
+ .do(withClaudeCode({ allowedTools: ['Read', 'Write'] })) // action provider
145
+ .concurrency(3) // max parallel agents
146
+ .claim('lease', 30_000) // claim strategy
147
+ .poll(2000) // sensor poll interval (ms)
148
+ .heartbeat(10_000) // periodic alive signals
149
+ .autoWithdraw() // auto-remove processed signals
150
+ .timeout(60_000) // action timeout
151
+ .retry(3, 1000) // retry with backoff
152
+ .build();
153
+ ```
154
+
155
+ **Claim strategies:**
156
+
157
+ | Strategy | Behavior |
158
+ |----------|----------|
159
+ | `exclusive` | Strict claim-before-work. Only one agent processes each signal. |
160
+ | `lease` | Claim with TTL. Auto-releases if the agent dies or times out. |
161
+ | `optimistic` | Let multiple agents start, reconcile after. |
162
+ | `none` | No claiming. Multiple agents may process the same signal. |
163
+
164
+ ## Action providers
165
+
166
+ Action providers wrap external capabilities into a standard interface for colony rules.
167
+
168
+ | Provider | Use case | Backed by |
169
+ |----------|----------|-----------|
170
+ | `withClaudeCode` | Coding agents, complex reasoning | Claude Code SDK (live) |
171
+ | `withStructuredOutput` | Classification, review, decisions | Anthropic, OpenAI, Vercel AI SDK |
172
+ | `withBash` | Build commands, test runners, linters | Shell execution |
173
+
174
+ `withClaudeCode` is fully wired to the Claude Code SDK — colonies spawn real agent sessions that read files, write code, and run commands. It supports **AWS Bedrock routing** via the `bedrock` config option for enterprise deployments.
175
+
176
+ The provider assembles context by walking signal lineage (`caused_by` chains), giving the agent full awareness of the work pipeline state.
177
+
178
+ ## Signal types
179
+
180
+ Signal types use a `domain:state` convention and support glob patterns for sensing:
181
+
182
+ ```typescript
183
+ 'task:ready' // exact match
184
+ 'task:*' // any task signal
185
+ '*:ready' // anything in the ready state
186
+ 'review:*' // any review signal
187
+ ```
188
+
189
+ ## Trust and attestation
190
+
191
+ Mandible provides cryptographic provenance for signals using `@noble/ed25519`:
192
+
193
+ - **Colony signing** — each colony generates an Ed25519 keypair and signs every signal it deposits. Signatures cover the semantic content (type, payload, lineage) but not mutable state (concentration, timestamps).
194
+ - **Bridge attestation** — when a signal crosses environments via a bridge, the bridge appends a signed attestation. Each attestation signs over the previous, creating a linked chain of custody.
195
+ - **Trust levels** — signals are classified as `verified` (valid signature + chain), `attested` (bridge chain valid, origin unsigned), `unverified` (no provenance), or `rejected` (verification failed).
196
+ - **Sentinel colonies** — monitor an environment for trust violations and deposit report signals that other colonies can react to.
197
+
198
+ ## Environment adapters
199
+
200
+ Any shared substrate that supports observe/deposit/withdraw/claim/watch can be a Mandible environment.
201
+
202
+ ### Filesystem (implemented)
203
+
204
+ Signals are JSON files. Claims use atomic file operations. History lives in a `withdrawn/` directory.
205
+
206
+ ```typescript
207
+ import { FilesystemEnvironment } from 'mandible';
208
+
209
+ const env = new FilesystemEnvironment({
210
+ root: './.mandible/signals',
211
+ name: 'local',
212
+ });
213
+ ```
214
+
215
+ ### GitHub (implemented)
216
+
217
+ Issues, pull requests, comments, and labels mapped as signals. Colonies can sense repository activity and deposit responses.
218
+
219
+ ```typescript
220
+ import { GitHubEnvironment } from 'mandible';
221
+
222
+ const env = new GitHubEnvironment({
223
+ owner: 'mandible-ai',
224
+ repo: 'mandible',
225
+ token: process.env.GITHUB_TOKEN,
226
+ });
227
+ ```
228
+
229
+ ### Remote (implemented)
230
+
231
+ WebSocket-based environment for distributed deployments. Multiple machines share a single signal namespace over the network.
232
+
233
+ ```typescript
234
+ import { RemoteEnvironment } from 'mandible';
235
+
236
+ const env = new RemoteEnvironment({
237
+ url: 'ws://coordinator:4041',
238
+ apiKey: process.env.MANDIBLE_API_KEY,
239
+ project: 'my-project',
240
+ name: 'distributed',
241
+ });
242
+ ```
243
+
244
+ ### Dolt (stubbed)
245
+
246
+ [Dolt](https://www.dolthub.com/) is a SQL database with Git-like versioning. Signals become rows, branching enables parallel work, and `dolt_history` provides queryable time travel for the full signal history.
247
+
248
+ ### Writing your own
249
+
250
+ Implement the `Environment` interface:
251
+
252
+ ```typescript
253
+ interface Environment {
254
+ name: string;
255
+ observe(query: SignalQuery): Promise<Signal[]>;
256
+ deposit(signal): Promise<Signal>;
257
+ withdraw(signalId: string): Promise<void>;
258
+ claim(signalId: string, claimant: string, leaseDuration?: number): Promise<boolean>;
259
+ release(signalId: string): Promise<void>;
260
+ watch(query: SignalQuery, callback: (signal: Signal) => void): Subscription;
261
+ history(query: SignalQuery): Promise<Signal[]>;
262
+ decay(): Promise<DecayResult>;
263
+ snapshot(): Promise<Signal[]>;
264
+ }
265
+ ```
266
+
267
+ ## Patterns
268
+
269
+ Reusable coordination patterns built on top of the core primitives.
270
+
271
+ ### SignalBridge
272
+
273
+ Cross-environment signal mirroring with attestation chains. Bridges watch for signals in one environment and mirror them to another, appending a signed attestation to preserve provenance across boundaries.
274
+
275
+ ```typescript
276
+ import { createBridge } from 'mandible';
277
+
278
+ const bridge = createBridge({
279
+ name: 'local-to-github',
280
+ identity: bridgeIdentity,
281
+ source: localEnv,
282
+ target: githubEnv,
283
+ signalTypes: ['fix:proposed'],
284
+ });
285
+ await bridge.start();
286
+ ```
287
+
288
+ ### Sentinel
289
+
290
+ Trust monitoring colony that watches an environment for signals with invalid or missing provenance. When violations are detected, the sentinel deposits `trust:violation` report signals that other colonies can react to.
291
+
292
+ ```typescript
293
+ import { createSentinel } from 'mandible';
294
+
295
+ const sentinel = createSentinel({
296
+ name: 'trust-guard',
297
+ environment: env,
298
+ policy: { name: 'strict', defaultTrust: 'unverified', minimumTrust: 'verified' },
299
+ });
300
+ await sentinel.start();
301
+ ```
302
+
303
+ ## Project structure
304
+
305
+ ```
306
+ src/
307
+ cli/
308
+ index.ts CLI entry point — `mandible dev`
309
+ server.ts Dashboard HTTP + WebSocket server
310
+ dashboard.html Live dashboard UI
311
+ cloud/
312
+ index.ts Cloud client for hosted observability
313
+ core/
314
+ types.ts Core type system (Signal, Environment, Colony, Trust)
315
+ signal.ts Signal creation, matching, decay, priority sorting
316
+ runtime.ts Colony runtime — the stigmergy loop engine
317
+ attestation.ts Ed25519 signing & verification (@noble/ed25519)
318
+ dsl/
319
+ builder.ts Fluent colony definition DSL
320
+ environments/
321
+ filesystem/ Filesystem adapter (JSON files + atomic claims)
322
+ github/ GitHub adapter (issues, PRs, comments, labels as signals)
323
+ remote/ Remote adapter (WebSocket-based distributed environments)
324
+ dolt/ Dolt adapter (stub)
325
+ providers/
326
+ claude-code.ts withClaudeCode — Claude Code SDK (live)
327
+ structured-output.ts withStructuredOutput — multi-model
328
+ bash.ts withBash — shell commands
329
+ context.ts Context assembly from signal lineage
330
+ patterns/
331
+ bridge.ts SignalBridge — cross-environment mirroring with attestation
332
+ sentinel.ts Sentinel — trust monitoring and violation reporting
333
+
334
+ tests/
335
+ core/ Signal, runtime, attestation tests
336
+ environments/ Filesystem, GitHub, remote adapter tests
337
+ providers/ Agent, structured output, bash provider tests
338
+ colonies/ Integration tests for colony workflows
339
+
340
+ examples/
341
+ code-pipeline/ Shaper → Critic → Keeper pipeline demo
342
+ repo-maintenance/ Scout + Fixer repo maintenance demo
343
+ ```
344
+
345
+ ## Examples
346
+
347
+ ### Code pipeline
348
+
349
+ The included demo seeds 5 coding tasks into a filesystem environment. Three colonies self-organize to process them:
350
+
351
+ - **Shaper** (concurrency: 2) — picks up `task:ready` signals, produces `task:shaped` signals
352
+ - **Critic** (concurrency: 2) — reviews shaped artifacts, deposits `review:approved` or `review:rejected`
353
+ - **Keeper** (concurrency: 1) — commits approved work, deposits `task:complete`
354
+
355
+ No orchestrator. No message broker. No routing logic. The colonies discover work through the environment and coordinate through signals.
356
+
357
+ ```bash
358
+ npm run demo
359
+ ```
360
+
361
+ ### Repo maintenance
362
+
363
+ Scout + Fixer colony pair that maintain a repository. Run it against any repo:
364
+
365
+ - **Scout** — scans the repository for issues, deposits `issue:detected` signals (one per finding, categorized by severity)
366
+ - **Fixer** — claims `issue:detected` signals, applies fixes, deposits `fix:proposed` or `fix:failed`
367
+
368
+ ```bash
369
+ npm run demo:repo-maintenance
370
+ ```
371
+
372
+ Both colonies are wired to real Claude agents via `withClaudeCode`. The dashboard shows signal flow in real time.
373
+
374
+ ## Roadmap
375
+
376
+ - [x] `mandible dev` CLI + live dashboard
377
+ - [x] `withClaudeCode` wired to Claude Code SDK
378
+ - [x] Test suite (371 tests, 95%+ coverage)
379
+ - [x] GitHub environment adapter
380
+ - [x] Remote environment adapter
381
+ - [ ] `create-mandible` starter template
382
+ - [ ] Dashboard GIF + landing page
383
+ - [ ] Dolt full implementation
384
+ - [ ] CloudEvents bridge adapter
385
+ - [ ] Colony scaler
386
+ - [ ] Trust enforcement
387
+ - [ ] Hosted observability platform
388
+
389
+ ## License
390
+
391
+ MIT
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env tsx
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../examples/code-pipeline/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,239 @@
1
+ #!/usr/bin/env tsx
2
+ // ============================================================
3
+ // Code Pipeline Demo — Stigmergy in Action
4
+ // ============================================================
5
+ // Three colonies coordinate through a shared filesystem:
6
+ //
7
+ // 1. SHAPER — watches for task:ready signals, "writes code",
8
+ // deposits artifact:shaped signals
9
+ //
10
+ // 2. CRITIC — watches for artifact:shaped signals, "reviews code",
11
+ // deposits review:approved or review:changes-needed signals
12
+ //
13
+ // 3. KEEPER — watches for review:approved signals,
14
+ // "merges" the artifact and deposits artifact:merged signals
15
+ //
16
+ // No colony knows about any other colony.
17
+ // They only interact through signals in the environment.
18
+ //
19
+ // To run:
20
+ // npx tsx examples/code-pipeline/index.ts
21
+ //
22
+ // Then watch the signals/ directory to see stigmergy happen:
23
+ // watch -n 0.5 'ls -la /tmp/stigmergy-demo/signals/'
24
+ // ============================================================
25
+ import { resolve } from 'node:path';
26
+ import { rm, mkdir } from 'node:fs/promises';
27
+ import { FilesystemEnvironment } from '../../src/environments/filesystem/index.js';
28
+ import { colony } from '../../src/dsl/index.js';
29
+ import { createRuntime } from '../../src/core/runtime.js';
30
+ // ----------------------------------------------------------
31
+ // Environment setup
32
+ // ----------------------------------------------------------
33
+ const ENV_ROOT = resolve('/tmp/stigmergy-demo');
34
+ async function setup() {
35
+ // Clean slate
36
+ await rm(ENV_ROOT, { recursive: true, force: true });
37
+ await mkdir(ENV_ROOT, { recursive: true });
38
+ console.log(`\n🌿 Environment root: ${ENV_ROOT}`);
39
+ console.log(` Watch signals: watch -n 0.5 'ls /tmp/stigmergy-demo/signals/'\n`);
40
+ }
41
+ // ----------------------------------------------------------
42
+ // Simulated work functions (replace with real LLM calls)
43
+ // ----------------------------------------------------------
44
+ async function simulateShaping(task) {
45
+ const duration = 500 + Math.random() * 1500;
46
+ await sleep(duration);
47
+ return {
48
+ code: `function ${task.name}() { /* shaped by colony */ return true; }`,
49
+ linesChanged: Math.floor(Math.random() * 100) + 10,
50
+ task: task.name,
51
+ };
52
+ }
53
+ async function simulateReview(artifact) {
54
+ const duration = 300 + Math.random() * 1000;
55
+ await sleep(duration);
56
+ // 80% approval rate
57
+ const approved = Math.random() > 0.2;
58
+ return {
59
+ approved,
60
+ feedback: approved
61
+ ? `Code for "${artifact.task}" looks good. Clean implementation.`
62
+ : `Code for "${artifact.task}" needs work: missing error handling.`,
63
+ };
64
+ }
65
+ async function simulateMerge(artifact) {
66
+ const duration = 200 + Math.random() * 500;
67
+ await sleep(duration);
68
+ return {
69
+ merged: true,
70
+ task: artifact.task,
71
+ commitHash: Math.random().toString(36).slice(2, 10),
72
+ };
73
+ }
74
+ // ----------------------------------------------------------
75
+ // Colony definitions
76
+ // ----------------------------------------------------------
77
+ function defineColonies(env) {
78
+ // ── SHAPER COLONY ──────────────────────────────────────
79
+ const shaperDef = colony('shaper')
80
+ .in(env)
81
+ .sense('task:ready', { unclaimed: true, minConcentration: 0.1 })
82
+ .do('shape-code', async (signal, ctx) => {
83
+ ctx.log(`Picking up task: ${signal.payload.name}`);
84
+ const artifact = await simulateShaping(signal.payload);
85
+ // Deposit the shaped artifact — this is the pheromone trail
86
+ await ctx.deposit('artifact:shaped', artifact, {
87
+ causedBy: [signal.id],
88
+ tags: ['needs-review'],
89
+ });
90
+ // Withdraw the task signal — it's been handled
91
+ await ctx.withdraw(signal.id);
92
+ ctx.log(`Shaped "${signal.payload.name}" (${artifact.linesChanged} lines)`);
93
+ })
94
+ .concurrency(2)
95
+ .claim('lease', 30_000)
96
+ .poll(1000)
97
+ .build();
98
+ // ── CRITIC COLONY ──────────────────────────────────────
99
+ const criticDef = colony('critic')
100
+ .in(env)
101
+ .sense('artifact:shaped', { unclaimed: true, minConcentration: 0.1 })
102
+ .do('review-code', async (signal, ctx) => {
103
+ ctx.log(`Reviewing artifact for task: ${signal.payload.task}`);
104
+ const review = await simulateReview(signal.payload);
105
+ if (review.approved) {
106
+ await ctx.deposit('review:approved', {
107
+ artifact: signal.payload,
108
+ feedback: review.feedback,
109
+ }, {
110
+ causedBy: [signal.id],
111
+ tags: ['ready-to-merge'],
112
+ });
113
+ ctx.log(`✓ Approved: ${review.feedback}`);
114
+ }
115
+ else {
116
+ await ctx.deposit('review:changes-needed', {
117
+ artifact: signal.payload,
118
+ feedback: review.feedback,
119
+ }, {
120
+ causedBy: [signal.id],
121
+ tags: ['needs-rework'],
122
+ ttl: 60_000, // expires after 1 minute if nobody picks it up
123
+ });
124
+ ctx.log(`✗ Changes needed: ${review.feedback}`);
125
+ }
126
+ // Withdraw the shaped artifact signal
127
+ await ctx.withdraw(signal.id);
128
+ })
129
+ .concurrency(2)
130
+ .claim('lease', 30_000)
131
+ .poll(1000)
132
+ .build();
133
+ // ── KEEPER COLONY ──────────────────────────────────────
134
+ const keeperDef = colony('keeper')
135
+ .in(env)
136
+ .sense('review:approved', { unclaimed: true, minConcentration: 0.1 })
137
+ .do('merge-artifact', async (signal, ctx) => {
138
+ const artifact = signal.payload.artifact ?? {};
139
+ ctx.log(`Merging approved artifact: ${artifact.task}`);
140
+ const result = await simulateMerge(artifact);
141
+ await ctx.deposit('artifact:merged', result, {
142
+ causedBy: [signal.id],
143
+ tags: ['complete'],
144
+ });
145
+ await ctx.withdraw(signal.id);
146
+ ctx.log(`Merged → commit ${result.commitHash}`);
147
+ })
148
+ .concurrency(1) // single keeper for serialized merges
149
+ .claim('exclusive')
150
+ .poll(1000)
151
+ .build();
152
+ return { shaperDef, criticDef, keeperDef };
153
+ }
154
+ // ----------------------------------------------------------
155
+ // Orchestration (just seeds tasks — no coordination logic!)
156
+ // ----------------------------------------------------------
157
+ async function seedTasks(env) {
158
+ const tasks = [
159
+ { name: 'auth-middleware', priority: 'high', description: 'Add JWT authentication' },
160
+ { name: 'rate-limiter', priority: 'medium', description: 'Implement API rate limiting' },
161
+ { name: 'health-check', priority: 'low', description: 'Add /health endpoint' },
162
+ { name: 'error-handler', priority: 'high', description: 'Global error handling middleware' },
163
+ { name: 'request-logger', priority: 'medium', description: 'Structured request logging' },
164
+ ];
165
+ console.log('📋 Seeding tasks into environment...\n');
166
+ for (const task of tasks) {
167
+ const signal = await env.deposit({
168
+ type: 'task:ready',
169
+ payload: task,
170
+ meta: { deposited_by: 'orchestrator', tags: [task.priority] },
171
+ });
172
+ console.log(` → task:ready "${task.name}" (${signal.id})`);
173
+ }
174
+ console.log('\n' + '─'.repeat(60));
175
+ console.log(' Colonies are now self-organizing. No further coordination.');
176
+ console.log('─'.repeat(60) + '\n');
177
+ }
178
+ // ----------------------------------------------------------
179
+ // Main
180
+ // ----------------------------------------------------------
181
+ async function main() {
182
+ await setup();
183
+ const env = new FilesystemEnvironment({ root: ENV_ROOT, name: 'code-pipeline' });
184
+ const { shaperDef, criticDef, keeperDef } = defineColonies(env);
185
+ // Create runtimes
186
+ const shaperRuntime = createRuntime(shaperDef, { rate: 0.005, interval: 10_000 });
187
+ const criticRuntime = createRuntime(criticDef, { rate: 0.005, interval: 10_000 });
188
+ const keeperRuntime = createRuntime(keeperDef, { rate: 0.005, interval: 10_000 });
189
+ // Wire up observability
190
+ for (const [name, rt] of [['shaper', shaperRuntime], ['critic', criticRuntime], ['keeper', keeperRuntime]]) {
191
+ rt.on('action:completed', (signal) => {
192
+ // Just for demo visibility
193
+ });
194
+ rt.on('signal:claim_failed', (signal) => {
195
+ console.log(` ⚡ Claim conflict in ${name}: ${signal.type}`);
196
+ });
197
+ }
198
+ // Start all colonies
199
+ console.log('🚀 Starting colonies...\n');
200
+ await Promise.all([
201
+ shaperRuntime.start(),
202
+ criticRuntime.start(),
203
+ keeperRuntime.start(),
204
+ ]);
205
+ // Seed tasks into the environment
206
+ await sleep(500);
207
+ await seedTasks(env);
208
+ // Let the colonies work for 20 seconds
209
+ await sleep(20_000);
210
+ // Print final state
211
+ console.log('\n' + '═'.repeat(60));
212
+ console.log(' FINAL STATE');
213
+ console.log('═'.repeat(60));
214
+ const snapshot = await env.snapshot();
215
+ const history = await env.history({ includeWithdrawn: true });
216
+ console.log(`\n Active signals: ${snapshot.length}`);
217
+ console.log(` Total signals processed: ${history.length}`);
218
+ console.log(`\n Active signals:`);
219
+ for (const s of snapshot) {
220
+ console.log(` [${s.type}] ${s.payload.task ?? s.payload.name ?? '?'} (conc: ${s.meta.concentration.toFixed(2)})`);
221
+ }
222
+ console.log(`\n Colony stats:`);
223
+ console.log(` Shaper: ${shaperRuntime.stats.signalsProcessed} processed, ${shaperRuntime.stats.signalsDeposited} deposited, ${shaperRuntime.stats.claimConflicts} conflicts`);
224
+ console.log(` Critic: ${criticRuntime.stats.signalsProcessed} processed, ${criticRuntime.stats.signalsDeposited} deposited, ${criticRuntime.stats.claimConflicts} conflicts`);
225
+ console.log(` Keeper: ${keeperRuntime.stats.signalsProcessed} processed, ${keeperRuntime.stats.signalsDeposited} deposited, ${keeperRuntime.stats.claimConflicts} conflicts`);
226
+ // Graceful shutdown
227
+ console.log('\n🛑 Stopping colonies...');
228
+ await Promise.all([
229
+ shaperRuntime.stop(),
230
+ criticRuntime.stop(),
231
+ keeperRuntime.stop(),
232
+ ]);
233
+ console.log('✅ Done.\n');
234
+ }
235
+ function sleep(ms) {
236
+ return new Promise(resolve => setTimeout(resolve, ms));
237
+ }
238
+ main().catch(console.error);
239
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../examples/code-pipeline/index.ts"],"names":[],"mappings":"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"}