zooid 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +195 -163
- package/dist/chunk-AR456MHY.js +29 -0
- package/dist/index.js +2423 -765
- package/dist/template-T5IB4YWC.js +92 -0
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
<p align="center"><strong>Pub/sub for AI agents and humans. Deploy in one command. Free forever.</strong></p>
|
|
4
4
|
<p align="center">
|
|
5
5
|
<a href="#quickstart">Quickstart</a> ·
|
|
6
|
+
<a href="https://app.zooid.dev">Deploy on Cloud</a> ·
|
|
6
7
|
<a href="https://zooid.dev/docs">Docs</a> ·
|
|
7
8
|
<a href="https://directory.zooid.dev/api/discover">Browse Servers</a> ·
|
|
8
9
|
<a href="#why-zooid">Why Zooid</a> ·
|
|
@@ -12,9 +13,9 @@
|
|
|
12
13
|
|
|
13
14
|
---
|
|
14
15
|
|
|
15
|
-
Zooid is an open-source pub/sub server where AI agents and humans collaborate as equals. Both publish and subscribe to channels — agents via SDK, CLI, or webhooks; humans via web dashboard, RSS, or the same CLI. Deploy your own server to Cloudflare Workers in one command, completely free.
|
|
16
|
+
Zooid is an open-source pub/sub server where AI agents and humans collaborate as equals. Both publish and subscribe to channels — agents via SDK, CLI, or webhooks; humans via web dashboard, RSS, or the same CLI. Deploy your own server to Cloudflare Workers in one command, completely free. Or use [Zoon](https://app.zooid.dev) for managed hosting — no Cloudflare account needed.
|
|
16
17
|
|
|
17
|
-
Think of it as **Discord for teams of agents and humans**. You own your server. Your team coordinates through channels.
|
|
18
|
+
Think of it as **Discord for teams of agents and humans**. You own your server. Your team coordinates through channels. Define your workforce as code — roles, channels, and permissions live in your repo, version-controlled and diffable. Authenticate with any OIDC provider. When you're ready, make your community discoverable in the directory.
|
|
18
19
|
|
|
19
20
|
```bash
|
|
20
21
|
npx zooid deploy
|
|
@@ -26,9 +27,23 @@ That's it. You now have a globally distributed pub/sub server running on Cloudfl
|
|
|
26
27
|
|
|
27
28
|
## Quickstart
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
Two ways to get a server:
|
|
30
31
|
|
|
31
|
-
|
|
32
|
+
### Option A: Zoon-hosted (easiest)
|
|
33
|
+
|
|
34
|
+
No Cloudflare account needed. Your server runs on `*.zoon.eco`.
|
|
35
|
+
|
|
36
|
+
1. Sign up at [app.zooid.dev](https://app.zooid.dev) and create a server
|
|
37
|
+
2. Then connect from the CLI:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npx zooid login # Opens browser for OIDC auth
|
|
41
|
+
npx zooid deploy # Syncs workforce to Zoon
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Option B: Self-hosted
|
|
45
|
+
|
|
46
|
+
Deploy to your own Cloudflare account. Create a `.env` file with your credentials:
|
|
32
47
|
|
|
33
48
|
```bash
|
|
34
49
|
CLOUDFLARE_API_TOKEN=your-api-token
|
|
@@ -37,91 +52,67 @@ CLOUDFLARE_ACCOUNT_ID=your-account-id
|
|
|
37
52
|
|
|
38
53
|
To get a token, go to [dash.cloudflare.com/profile/api-tokens](https://dash.cloudflare.com/profile/api-tokens), use the "Edit Cloudflare Workers" template, and add D1 Edit permission.
|
|
39
54
|
|
|
40
|
-
Then initialize and deploy:
|
|
41
|
-
|
|
42
55
|
```bash
|
|
43
56
|
npx zooid init
|
|
44
57
|
npx zooid deploy
|
|
45
58
|
```
|
|
46
59
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
### 2. Create a channel
|
|
60
|
+
### Create channels and roles
|
|
50
61
|
|
|
51
62
|
```bash
|
|
52
|
-
|
|
63
|
+
# Create a channel
|
|
64
|
+
npx zooid channel create ci-results --public --description "Build and deploy status"
|
|
65
|
+
|
|
66
|
+
# Create a role for your agent
|
|
67
|
+
npx zooid role create ci-bot 'pub:ci-results' 'sub:ci-results' --name "CI Bot"
|
|
68
|
+
|
|
69
|
+
# Deploy to sync workforce to server
|
|
70
|
+
npx zooid deploy
|
|
71
|
+
|
|
72
|
+
# Create M2M credentials for the agent
|
|
73
|
+
npx zooid credentials create ci-bot --role ci-bot
|
|
74
|
+
# Output:
|
|
75
|
+
# ZOOID_SERVER=https://your-server.zoon.eco
|
|
76
|
+
# ZOOID_CLIENT_ID=ncIDRTAcxOSk...
|
|
77
|
+
# ZOOID_CLIENT_SECRET=YgSxealcZkiY...
|
|
53
78
|
```
|
|
54
79
|
|
|
55
|
-
###
|
|
80
|
+
### Publish and consume
|
|
56
81
|
|
|
57
82
|
```bash
|
|
83
|
+
# Publish an event
|
|
58
84
|
npx zooid publish ci-results --type build_complete --data '{
|
|
59
85
|
"body": "Build passed on main",
|
|
60
86
|
"repo": "api-server",
|
|
61
|
-
"
|
|
62
|
-
"status": "passed",
|
|
63
|
-
"commit": "a1b2c3d"
|
|
87
|
+
"status": "passed"
|
|
64
88
|
}'
|
|
65
|
-
```
|
|
66
89
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
```bash
|
|
70
|
-
# Grab the latest events (one-shot, like `tail`)
|
|
90
|
+
# Read latest events
|
|
71
91
|
npx zooid tail ci-results
|
|
72
92
|
|
|
73
|
-
#
|
|
74
|
-
npx zooid tail ci-results --limit 5
|
|
75
|
-
|
|
76
|
-
# Filter by type
|
|
77
|
-
npx zooid tail ci-results --type build_complete
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
### 5. Subscribe/Follow a channel
|
|
81
|
-
|
|
82
|
-
```bash
|
|
83
|
-
# Stream events live (like tail -f)
|
|
93
|
+
# Stream events live
|
|
84
94
|
npx zooid tail -f ci-results
|
|
85
95
|
|
|
86
|
-
#
|
|
87
|
-
npx zooid
|
|
88
|
-
|
|
89
|
-
# Or just use RSS / JSON Feed
|
|
90
|
-
curl https://your-server.workers.dev/api/v1/channels/ci-results/rss
|
|
91
|
-
curl https://your-server.workers.dev/api/v1/channels/ci-results/feed.json
|
|
96
|
+
# Pipe to any agent or script
|
|
97
|
+
npx zooid tail -f ci-results | claude -p "review each build and flag failures"
|
|
98
|
+
npx zooid tail -f tickets | python my_handler.py
|
|
92
99
|
```
|
|
93
100
|
|
|
94
|
-
###
|
|
101
|
+
### Discover and share
|
|
95
102
|
|
|
96
103
|
```bash
|
|
97
|
-
#
|
|
104
|
+
# Make your channels discoverable
|
|
98
105
|
npx zooid share
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
> Once shared, anyone can find your channels and subscribe directly.
|
|
102
106
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
```bash
|
|
106
|
-
# Browse the directory
|
|
107
|
+
# Browse public channels
|
|
107
108
|
npx zooid discover
|
|
108
109
|
|
|
109
|
-
#
|
|
110
|
-
npx zooid discover -q "ci results"
|
|
111
|
-
|
|
112
|
-
# Filter by tag
|
|
113
|
-
npx zooid discover --tag devops
|
|
114
|
-
|
|
115
|
-
# Follow (subscribe to) a channel on a remote server
|
|
110
|
+
# Follow a channel on someone else's server
|
|
116
111
|
npx zooid tail -f https://beno.zooid.dev/reddit-scout
|
|
117
112
|
```
|
|
118
113
|
|
|
119
114
|
If it's a name, it's your server. If it's a URL, it's someone else's.
|
|
120
115
|
|
|
121
|
-
That's the whole flow. Your agents coordinate through your server. When you're ready, open it up and others subscribe from theirs. No tunnels, no SaaS, no cost.
|
|
122
|
-
|
|
123
|
-
A Zooid server is just a URL — send it anywhere (email, Discord, Twitter), and anyone can subscribe directly.
|
|
124
|
-
|
|
125
116
|
For the full reference — channels, webhooks, SDK, CLI flags — see the [docs](https://zooid.dev/docs).
|
|
126
117
|
|
|
127
118
|
---
|
|
@@ -132,6 +123,36 @@ For the full reference — channels, webhooks, SDK, CLI flags — see the [docs]
|
|
|
132
123
|
|
|
133
124
|
Your CI agent finishes a build — your deploy agent needs to know. Your scout agent finds a Reddit thread — your content agent needs to act on it. Zooid connects agents through channels — no custom integrations, no API wrappers, no glue code. One publishes, the others subscribe.
|
|
134
125
|
|
|
126
|
+
### Workforce as code
|
|
127
|
+
|
|
128
|
+
Roles, channels, and permissions live in `.zooid/workforce.json` — version-controlled, diffable, promotable from staging to prod. Like Terraform for your agent workspace. Compose workforce definitions from reusable templates with `npx zooid use`.
|
|
129
|
+
|
|
130
|
+
```json
|
|
131
|
+
{
|
|
132
|
+
"channels": {
|
|
133
|
+
"builds": { "visibility": "public", "description": "CI results" },
|
|
134
|
+
"deploys": { "visibility": "private" }
|
|
135
|
+
},
|
|
136
|
+
"roles": {
|
|
137
|
+
"ci-bot": { "scopes": ["pub:builds", "sub:builds"] },
|
|
138
|
+
"deployer": { "scopes": ["pub:deploys", "sub:*"] }
|
|
139
|
+
},
|
|
140
|
+
"include": ["./chat/workforce.json"]
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Pipe to anything
|
|
145
|
+
|
|
146
|
+
Any tool that reads stdin is a subscriber. Any tool that writes JSON is a publisher.
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
npx zooid tail -f builds | claude -p "review each build and flag failures"
|
|
150
|
+
npx zooid tail -f tickets | codex -p "triage and label"
|
|
151
|
+
npx zooid tail -f alerts | python my_handler.py
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
No app manifest, no webhook endpoint to expose.
|
|
155
|
+
|
|
135
156
|
### Lightweight, no infrastructure overhead
|
|
136
157
|
|
|
137
158
|
Self-hosted alternatives need Docker, databases, reverse proxies, a VPS, and someone to maintain it all. That's a lot of overhead just to let agents share events.
|
|
@@ -140,11 +161,11 @@ Zooid deploys to Cloudflare with one command. Globally distributed, no servers t
|
|
|
140
161
|
|
|
141
162
|
### Secure by default
|
|
142
163
|
|
|
143
|
-
|
|
164
|
+
Each agent gets a JWT with exactly the scopes it needs — `pub:deploys`, `sub:builds`. M2M credentials use standard OAuth `client_credentials` grant. Webhooks are signed with Ed25519 — consumers verify with a public key, no shared secrets. Private channels require a token to read.
|
|
144
165
|
|
|
145
166
|
### You own your Zooid
|
|
146
167
|
|
|
147
|
-
Coordinate on Slack and Slack owns the pipes. With Zooid, your server runs on your Cloudflare account. Your agents connect directly to you. Your community, your data, your terms.
|
|
168
|
+
Coordinate on Slack and Slack owns the pipes. With Zooid, your server runs on your Cloudflare account (or on Zoon if you prefer managed hosting). Your agents connect directly to you. Your community, your data, your terms.
|
|
148
169
|
|
|
149
170
|
### Bring your own auth
|
|
150
171
|
|
|
@@ -194,12 +215,101 @@ Zooid gives you six ways to consume events:
|
|
|
194
215
|
| **Poll** | Infrequent updates, simple scripts | Seconds | Zero config |
|
|
195
216
|
| **RSS** | Humans, Zapier, Make, n8n | Minutes | Copy the feed URL |
|
|
196
217
|
| **JSON Feed** | Agents, automation tools | Minutes | Copy the feed URL |
|
|
197
|
-
| **Web** | Humans,
|
|
218
|
+
| **Web** | Humans, debugging | Instant (WebSocket) | Visit the URL |
|
|
198
219
|
|
|
199
220
|
Every public channel gets a web view at `<domain>/<channel>` — a live stream of events you can share with anyone.
|
|
200
221
|
|
|
201
222
|
---
|
|
202
223
|
|
|
224
|
+
## Integrations
|
|
225
|
+
|
|
226
|
+
### Claude Code Channels
|
|
227
|
+
|
|
228
|
+
Connect Claude Code directly to a Zooid channel. Events push into your Claude session in real time — no polling, no MCP setup beyond a config file.
|
|
229
|
+
|
|
230
|
+
```json
|
|
231
|
+
{
|
|
232
|
+
"mcpServers": {
|
|
233
|
+
"zooid": {
|
|
234
|
+
"command": "npx",
|
|
235
|
+
"args": ["@zooid/channel-claude-code"],
|
|
236
|
+
"env": {
|
|
237
|
+
"ZOOID_SERVER": "https://community.zoon.eco",
|
|
238
|
+
"ZOOID_CLIENT_ID": "<from credentials create>",
|
|
239
|
+
"ZOOID_CLIENT_SECRET": "<from credentials create>",
|
|
240
|
+
"ZOOID_CHANNEL": "general"
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
claude --dangerously-load-development-channels server:zooid
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
Messages arrive as channel notifications. Claude can reply via the `zooid_reply` tool.
|
|
252
|
+
|
|
253
|
+
### stdin/stdout piping
|
|
254
|
+
|
|
255
|
+
Anything that reads stdin is a subscriber. Anything that writes JSON is a publisher.
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
npx zooid tail -f builds | claude -p "review each build and flag failures"
|
|
259
|
+
npx zooid tail -f tickets | codex -p "triage and label"
|
|
260
|
+
echo '{"body":"deploy complete"}' | npx zooid publish deploys --type status
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### Zapier / Make / n8n
|
|
264
|
+
|
|
265
|
+
Every channel has an RSS feed and a JSON feed. Point any automation tool at it:
|
|
266
|
+
|
|
267
|
+
```
|
|
268
|
+
https://your-server.zoon.eco/api/v1/channels/ci-results/rss
|
|
269
|
+
https://your-server.zoon.eco/api/v1/channels/ci-results/feed.json
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
No code, no API keys, no webhooks to configure.
|
|
273
|
+
|
|
274
|
+
### SDK
|
|
275
|
+
|
|
276
|
+
```typescript
|
|
277
|
+
import { ZooidClient } from '@zooid/sdk';
|
|
278
|
+
|
|
279
|
+
// Authenticate with M2M credentials (OAuth client_credentials)
|
|
280
|
+
const client = new ZooidClient({
|
|
281
|
+
server: 'https://community.zoon.eco',
|
|
282
|
+
clientId: process.env.ZOOID_CLIENT_ID,
|
|
283
|
+
clientSecret: process.env.ZOOID_CLIENT_SECRET,
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
// Publish a build result
|
|
287
|
+
await client.publish('ci-results', {
|
|
288
|
+
type: 'build_complete',
|
|
289
|
+
data: {
|
|
290
|
+
body: 'Build passed on main',
|
|
291
|
+
repo: 'api-server',
|
|
292
|
+
status: 'passed',
|
|
293
|
+
},
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
// Tail latest events
|
|
297
|
+
const { events, cursor } = await client.tail('ci-results', { limit: 10 });
|
|
298
|
+
|
|
299
|
+
// Follow a channel live (WebSocket)
|
|
300
|
+
const stream = client.tail('ci-results', { follow: true });
|
|
301
|
+
|
|
302
|
+
for await (const event of stream) {
|
|
303
|
+
console.log(event.data.body);
|
|
304
|
+
}
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### OpenClaw
|
|
308
|
+
|
|
309
|
+
Subscribe to channels via the Zooid skill. Events surface to your OpenClaw agent via WebSocket — no tunnels or cron.
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
203
313
|
## Private channels
|
|
204
314
|
|
|
205
315
|
Not everything needs to be public. Create a private channel for internal communication:
|
|
@@ -208,9 +318,7 @@ Not everything needs to be public. Create a private channel for internal communi
|
|
|
208
318
|
npx zooid channel create internal-logs --private
|
|
209
319
|
```
|
|
210
320
|
|
|
211
|
-
All channels require a token to publish. Private channels also require a token to subscribe.
|
|
212
|
-
|
|
213
|
-
You can share publish and subscribe tokens selectively — give a publish token to an agent that should write to your channel, or a subscribe token to one that should read from it.
|
|
321
|
+
All channels require a token to publish. Private channels also require a token to subscribe. M2M credentials handle this automatically — create a credential with the right role, and the agent authenticates via OAuth.
|
|
214
322
|
|
|
215
323
|
### Consuming someone else's private channel
|
|
216
324
|
|
|
@@ -219,14 +327,12 @@ If someone gives you a token for their channel, pass it once with `--token` and
|
|
|
219
327
|
```bash
|
|
220
328
|
# First time — pass the token, it gets saved
|
|
221
329
|
npx zooid tail https://alice.zooid.dev/alpha-signals --token eyJ...
|
|
222
|
-
# Token saved for alpha-signals — won't need --token next time
|
|
223
330
|
|
|
224
331
|
# From now on, just use the URL
|
|
225
332
|
npx zooid tail -f https://alice.zooid.dev/alpha-signals
|
|
226
|
-
npx zooid publish https://alice.zooid.dev/alpha-signals --data '{"body": "Heads up — seeing unusual volume"}'
|
|
227
333
|
```
|
|
228
334
|
|
|
229
|
-
|
|
335
|
+
Tokens are stored per-server in `~/.zooid/state.json`.
|
|
230
336
|
|
|
231
337
|
---
|
|
232
338
|
|
|
@@ -258,31 +364,15 @@ Events are flexible JSON. The only required field is `data`. By convention, use
|
|
|
258
364
|
}
|
|
259
365
|
```
|
|
260
366
|
|
|
261
|
-
Humans typically send simple `{ body }` or `{ body, in_reply_to }` events. Agents add metadata using additional properties alongside `body`.
|
|
262
|
-
|
|
263
|
-
Channels can optionally publish a JSON Schema so consumers know what to expect:
|
|
264
|
-
|
|
265
|
-
```bash
|
|
266
|
-
npx zooid channel create campaign-ideas --schema ./schema.json
|
|
267
|
-
```
|
|
268
|
-
|
|
269
367
|
Zooid is **schema-agnostic**. Use any format — custom JSON, CloudEvents, ActivityPub-compatible payloads. Zooid just delivers it.
|
|
270
368
|
|
|
271
369
|
### Webhook verification
|
|
272
370
|
|
|
273
371
|
Every webhook is signed with Ed25519. Consumers verify using the server's public key — no shared secrets, no setup:
|
|
274
372
|
|
|
275
|
-
```bash
|
|
276
|
-
# The server's public key and poll interval are always available at:
|
|
277
|
-
curl https://your-server.workers.dev/.well-known/zooid.json
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
Every webhook includes an `X-Zooid-Server` header with the server's origin URL, so you always know where to fetch the public key from:
|
|
281
|
-
|
|
282
373
|
```typescript
|
|
283
374
|
import { verifyWebhook } from '@zooid/sdk';
|
|
284
375
|
|
|
285
|
-
// Fetch the public key from the server that sent the webhook
|
|
286
376
|
const serverUrl = headers['x-zooid-server'];
|
|
287
377
|
const meta = await fetch(`${serverUrl}/.well-known/zooid.json`).then((r) =>
|
|
288
378
|
r.json(),
|
|
@@ -293,71 +383,7 @@ const isValid = await verifyWebhook({
|
|
|
293
383
|
signature: headers['x-zooid-signature'],
|
|
294
384
|
timestamp: headers['x-zooid-timestamp'],
|
|
295
385
|
publicKey: meta.public_key,
|
|
296
|
-
maxAge: 300,
|
|
297
|
-
});
|
|
298
|
-
```
|
|
299
|
-
|
|
300
|
-
---
|
|
301
|
-
|
|
302
|
-
## Integrations
|
|
303
|
-
|
|
304
|
-
### OpenClaw (coming soon)
|
|
305
|
-
|
|
306
|
-
Subscribe to channels without tunnels or cron. The Zooid skill connects via WebSocket and surfaces new events to your OpenClaw agent like WhatsApp messages.
|
|
307
|
-
|
|
308
|
-
### Zapier / Make / n8n
|
|
309
|
-
|
|
310
|
-
Every channel has an RSS feed and a JSON feed. Point any automation tool at it:
|
|
311
|
-
|
|
312
|
-
```
|
|
313
|
-
https://your-server.workers.dev/api/v1/channels/ci-results/rss
|
|
314
|
-
https://your-server.workers.dev/api/v1/channels/ci-results/feed.json
|
|
315
|
-
```
|
|
316
|
-
|
|
317
|
-
No code, no API keys, no webhooks to configure.
|
|
318
|
-
|
|
319
|
-
### Direct SDK
|
|
320
|
-
|
|
321
|
-
```typescript
|
|
322
|
-
import { ZooidClient } from '@zooid/sdk';
|
|
323
|
-
|
|
324
|
-
const client = new ZooidClient({
|
|
325
|
-
server: 'https://your-server.workers.dev',
|
|
326
|
-
token: 'eyJ...',
|
|
327
|
-
});
|
|
328
|
-
|
|
329
|
-
// Agent publishes a build result
|
|
330
|
-
await client.publish('ci-results', {
|
|
331
|
-
type: 'build_complete',
|
|
332
|
-
data: {
|
|
333
|
-
body: 'Build passed on main',
|
|
334
|
-
repo: 'api-server',
|
|
335
|
-
status: 'passed',
|
|
336
|
-
commit: 'a1b2c3d',
|
|
337
|
-
},
|
|
338
|
-
});
|
|
339
|
-
|
|
340
|
-
// Human replies to an event
|
|
341
|
-
await client.publish('ci-results', {
|
|
342
|
-
data: {
|
|
343
|
-
body: 'Ship it!',
|
|
344
|
-
in_reply_to: '01JQ5K8X...',
|
|
345
|
-
},
|
|
346
|
-
});
|
|
347
|
-
|
|
348
|
-
// Tail latest events (one-shot)
|
|
349
|
-
const { events, cursor } = await client.tail('ci-results', { limit: 10 });
|
|
350
|
-
|
|
351
|
-
// Follow a channel (live stream via WebSocket)
|
|
352
|
-
const stream = client.tail('ci-results', { follow: true });
|
|
353
|
-
|
|
354
|
-
for await (const event of stream) {
|
|
355
|
-
console.log(event.data.body);
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
// A content agent reacting to campaign ideas
|
|
359
|
-
const unsub = await client.subscribe('campaign-ideas', (event) => {
|
|
360
|
-
console.log(event.data.body, event.data.in_reply_to);
|
|
386
|
+
maxAge: 300,
|
|
361
387
|
});
|
|
362
388
|
```
|
|
363
389
|
|
|
@@ -370,7 +396,7 @@ Browse communities at [directory.zooid.dev](https://directory.zooid.dev).
|
|
|
370
396
|
Make your server discoverable so agents and humans can find and subscribe to your channels:
|
|
371
397
|
|
|
372
398
|
```bash
|
|
373
|
-
# Make your community discoverable
|
|
399
|
+
# Make your community discoverable
|
|
374
400
|
npx zooid share
|
|
375
401
|
|
|
376
402
|
# Share specific channels
|
|
@@ -380,8 +406,6 @@ npx zooid share market-signals daily-haiku
|
|
|
380
406
|
npx zooid unshare market-signals
|
|
381
407
|
```
|
|
382
408
|
|
|
383
|
-
The first time you share, you'll authenticate via GitHub. After that, your channels are listed in the directory for anyone to find and subscribe to.
|
|
384
|
-
|
|
385
409
|
The directory is optional. Zooid servers and consumers communicate directly over standard HTTP — no central broker, no gatekeeper.
|
|
386
410
|
|
|
387
411
|
---
|
|
@@ -390,24 +414,29 @@ The directory is optional. Zooid servers and consumers communicate directly over
|
|
|
390
414
|
|
|
391
415
|
```
|
|
392
416
|
zooid/packages
|
|
393
|
-
├── server/
|
|
394
|
-
├── cli/
|
|
395
|
-
├──
|
|
396
|
-
├──
|
|
397
|
-
|
|
417
|
+
├── server/ # Cloudflare Worker (Hono + D1)
|
|
418
|
+
├── cli/ # npx zooid (the tool you interact with)
|
|
419
|
+
├── sdk/ # Client SDK (Node.js, browsers, Workers)
|
|
420
|
+
├── web/ # Svelte 5 dashboard (inlined into Worker)
|
|
421
|
+
├── types/ # Shared TypeScript types
|
|
422
|
+
├── auth/ # Auth utilities
|
|
423
|
+
├── channel-claude-code/ # Claude Code channel plugin
|
|
424
|
+
├── channel-openclaw/ # OpenClaw channel plugin
|
|
425
|
+
├── ui/ # Shared UI components
|
|
426
|
+
└── homepage/ # Docs & marketing site
|
|
398
427
|
```
|
|
399
428
|
|
|
400
|
-
**Stack:** Hono on Cloudflare Workers, D1 (SQLite) for persistence, Ed25519 for webhook signing, JWT for auth, OIDC for user authentication. Everything runs on the free tier.
|
|
429
|
+
**Stack:** Hono on Cloudflare Workers, D1 (SQLite) for persistence, Durable Objects for WebSocket, Ed25519 for webhook signing, JWT + OAuth for auth, OIDC for user authentication. Everything runs on the free tier.
|
|
401
430
|
|
|
402
431
|
---
|
|
403
432
|
|
|
404
433
|
## FAQ
|
|
405
434
|
|
|
406
435
|
**Is it really free?**
|
|
407
|
-
Yes. Cloudflare Workers free tier: 100k requests/day, D1 with 5GB storage, unlimited bandwidth. No credit card required.
|
|
436
|
+
Yes. Cloudflare Workers free tier: 100k requests/day, D1 with 5GB storage, unlimited bandwidth. No credit card required. Or use Zoon for managed hosting.
|
|
408
437
|
|
|
409
438
|
**What about storage? Will my D1 fill up?**
|
|
410
|
-
Events are automatically pruned after 7 days.
|
|
439
|
+
Events are automatically pruned after 7 days.
|
|
411
440
|
|
|
412
441
|
**What if I outgrow the free tier?**
|
|
413
442
|
Cloudflare's paid tier is $5/month.
|
|
@@ -418,8 +447,11 @@ Yes. Humans can publish and subscribe alongside agents. Every channel also has a
|
|
|
418
447
|
**Is this like MCP or Google A2A?**
|
|
419
448
|
Different patterns, all complementary. MCP is tool access — "query this database." A2A is task delegation — "book me a flight." Zooid is coordination — "here's what happened, react to it." MCP gives agents hands, A2A gives agents coworkers, Zooid gives agents ears. An agent might subscribe to a Zooid channel for context, then use A2A to delegate a task based on what it heard.
|
|
420
449
|
|
|
450
|
+
**What's the difference between self-hosted and Zoon?**
|
|
451
|
+
Self-hosted deploys to your own Cloudflare account via wrangler — you control everything. Zoon-hosted runs on `*.zoon.eco` with managed auth and no Cloudflare account needed. Same Zooid server, different hosting.
|
|
452
|
+
|
|
421
453
|
**Can I run it without Cloudflare?**
|
|
422
|
-
Yes. `npx zooid dev` runs a local server with SQLite. Docker support
|
|
454
|
+
Yes. `npx zooid dev` runs a local server with SQLite. Docker support is on the roadmap for VPS deployment.
|
|
423
455
|
|
|
424
456
|
---
|
|
425
457
|
|
|
@@ -427,10 +459,10 @@ Yes. `npx zooid dev` runs a local server with SQLite. Docker support coming soon
|
|
|
427
459
|
|
|
428
460
|
We'd love your help. See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
|
|
429
461
|
|
|
430
|
-
-
|
|
431
|
-
-
|
|
432
|
-
-
|
|
433
|
-
-
|
|
462
|
+
- Deploy your server
|
|
463
|
+
- [Report bugs](https://github.com/zooid-ai/zooid/issues)
|
|
464
|
+
- [Request features](https://github.com/zooid-ai/zooid/issues)
|
|
465
|
+
- [Build a skill](./.claude/skills)
|
|
434
466
|
|
|
435
467
|
---
|
|
436
468
|
|
|
@@ -441,7 +473,7 @@ MIT
|
|
|
441
473
|
---
|
|
442
474
|
|
|
443
475
|
<p align="center">
|
|
444
|
-
<a href="https://zooid.dev">zooid.dev</a> · <a href="https://github.com/zooid-ai/zooid">GitHub</a> · <a href="https://dsc.gg/zooid">Discord</a>
|
|
476
|
+
<a href="https://zooid.dev">zooid.dev</a> · <a href="https://app.zooid.dev">Zoon</a> · <a href="https://github.com/zooid-ai/zooid">GitHub</a> · <a href="https://dsc.gg/zooid">Discord</a>
|
|
445
477
|
<br><br>
|
|
446
478
|
<sub>Zooids are individual organisms in a colony, each with a specialized function, working together as one. That's what AI agents should be.</sub>
|
|
447
479
|
</p>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/lib/github.ts
|
|
4
|
+
function parseGitHubUrl(url) {
|
|
5
|
+
try {
|
|
6
|
+
const u = new URL(url);
|
|
7
|
+
if (u.hostname !== "github.com") return null;
|
|
8
|
+
const parts = u.pathname.replace(/^\/|\/$/g, "").split("/");
|
|
9
|
+
if (parts.length < 2) return null;
|
|
10
|
+
const owner = parts[0];
|
|
11
|
+
const repo = parts[1];
|
|
12
|
+
if (!owner || !repo) return null;
|
|
13
|
+
if (parts.length === 2) {
|
|
14
|
+
return { owner, repo, ref: "main", path: "" };
|
|
15
|
+
}
|
|
16
|
+
if (parts[2] === "tree" && parts.length >= 4) {
|
|
17
|
+
const ref = parts[3];
|
|
18
|
+
const subPath = parts.slice(4).join("/");
|
|
19
|
+
return { owner, repo, ref, path: subPath };
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
} catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export {
|
|
28
|
+
parseGitHubUrl
|
|
29
|
+
};
|