relaybrain 0.2.0 → 0.2.1
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 +434 -291
- package/backend/lib/falkor/demo.js +221 -0
- package/backend/lib/falkor/migrations.js +56 -56
- package/backend/lib/falkor/routes.js +52 -8
- package/backend/lib/localBrowse.js +109 -109
- package/backend/lib/notices.js +7 -0
- package/backend/lib/room.js +152 -12
- package/backend/lib/transcripts/discover.js +109 -10
- package/backend/server.js +62 -7
- package/cli/graph.js +8 -0
- package/cli/relay.js +64 -8
- package/docs/MEMORY-GRAPH.md +57 -12
- package/mission-control/out/404.html +1 -1
- package/mission-control/out/__next.__PAGE__.txt +3 -3
- package/mission-control/out/__next._full.txt +3 -3
- package/mission-control/out/__next._tree.txt +2 -2
- package/mission-control/out/_next/static/chunks/064ntycm-fx5v.js +1 -0
- package/mission-control/out/_next/static/chunks/{25rvg4bnew99f.css → 1-dy52ls2ntb_.css} +1 -1
- package/mission-control/out/_next/static/chunks/31qgr-p-oulpb.js +1 -0
- package/mission-control/out/_not-found/__next._full.txt +1 -1
- package/mission-control/out/_not-found/__next._not-found/__PAGE__.txt +1 -1
- package/mission-control/out/_not-found/__next._tree.txt +1 -1
- package/mission-control/out/_not-found.html +1 -1
- package/mission-control/out/_not-found.txt +1 -1
- package/mission-control/out/index.html +1 -1
- package/mission-control/out/index.txt +3 -3
- package/package.json +76 -76
- package/scripts/falkor-rebuild.js +8 -27
- package/scripts/falkor-seed-demo.js +12 -140
- package/mission-control/out/_next/static/chunks/3_5x4qn1_b4al.js +0 -1
- package/mission-control/out/_next/static/chunks/3o1tiwncjss_k.js +0 -1
- /package/mission-control/out/_next/static/{dglM39XRu0cmneClUkGYd → BuhfCxd0WQE65yIzZJCOM}/_buildManifest.js +0 -0
- /package/mission-control/out/_next/static/{dglM39XRu0cmneClUkGYd → BuhfCxd0WQE65yIzZJCOM}/_clientMiddlewareManifest.js +0 -0
- /package/mission-control/out/_next/static/{dglM39XRu0cmneClUkGYd → BuhfCxd0WQE65yIzZJCOM}/_ssgManifest.js +0 -0
package/README.md
CHANGED
|
@@ -1,291 +1,434 @@
|
|
|
1
|
-
<div align="center">
|
|
2
|
-
|
|
3
|
-

|
|
4
|
-
|
|
5
|
-
### GitHub Desktop for AI agents.
|
|
6
|
-
|
|
7
|
-
*Git coordinates humans committing minutes apart. **Relay coordinates agents editing the same files right now** — file locks, dependency-aware locks, live patch sync, and one shared
|
|
8
|
-
|
|
9
|
-
**Twelve agents on one repo, and none of them blind to the others.**
|
|
10
|
-
|
|
11
|
-
[**Watch the demo**](https://youtu.be/vUea5Qih-nM) · [**
|
|
12
|
-
|
|
13
|
-
<br/>
|
|
14
|
-
|
|
15
|
-
<a href="https://
|
|
16
|
-
<a href="
|
|
17
|
-
<img src="https://img.shields.io/badge/
|
|
18
|
-
<img src="https://img.shields.io/badge/login-not%20required-16a34a?style=for-the-badge" alt="No login">
|
|
19
|
-
|
|
20
|
-
<br/>
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
|
181
|
-
|
|
182
|
-
| `
|
|
183
|
-
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
```bash
|
|
201
|
-
relay
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
|
226
|
-
|
|
227
|
-
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
| | |
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
|
268
|
-
|
|
269
|
-
|
|
|
270
|
-
|
|
|
271
|
-
|
|
|
272
|
-
| [
|
|
273
|
-
|
|
|
274
|
-
|
|
|
275
|
-
|
|
|
276
|
-
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
### GitHub Desktop for AI agents — powered by a FalkorDB Memory Graph.
|
|
6
|
+
|
|
7
|
+
*Git coordinates humans committing minutes apart. **Relay coordinates agents editing the same files right now** — file locks, dependency-aware locks, live patch sync, and one shared **FalkorDB knowledge & memory graph** across every agent and teammate.*
|
|
8
|
+
|
|
9
|
+
**Twelve agents on one repo, and none of them blind to the others.**
|
|
10
|
+
|
|
11
|
+
[**Watch the demo**](https://youtu.be/vUea5Qih-nM) · [**FalkorDB Memory Graph Docs**](./docs/MEMORY-GRAPH.md) · [**Engineering Blog Post**](./docs/BLOG-POST.md) · [**Full Documentation**](https://relay-brain.vercel.app/docs.html)
|
|
12
|
+
|
|
13
|
+
<br/>
|
|
14
|
+
|
|
15
|
+
<a href="https://www.falkordb.com"><img src="https://img.shields.io/badge/memory-FalkorDB%20Property%20Graph-dc2626?style=for-the-badge" alt="FalkorDB memory graph"></a>
|
|
16
|
+
<a href="https://nodejs.org"><img src="https://img.shields.io/badge/node-%E2%89%A520-3c873a?style=for-the-badge&logo=node.js&logoColor=white" alt="Node 20+"></a>
|
|
17
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-2563eb?style=for-the-badge" alt="MIT"></a>
|
|
18
|
+
<img src="https://img.shields.io/badge/login-not%20required-16a34a?style=for-the-badge" alt="No login">
|
|
19
|
+
|
|
20
|
+
<br/>
|
|
21
|
+
|
|
22
|
+
> 🏆 **Built for WeMakeDevs × FalkorDB — *Graph Hacks: Context for AI Agents* (Track 2: Agent Memory & Coordination)**
|
|
23
|
+
>
|
|
24
|
+
> Relay turns multi-agent chaos into a live **FalkorDB property graph** (`relay_<projectId>`) that links every person, agent, session, prompt, edit, lock contention, overlap, and architectural decision — giving agents shared memory *before* they edit and *at the exact moment of conflict*.
|
|
25
|
+
>
|
|
26
|
+
> 👉 **[FalkorDB Memory Graph Architecture & Setup (`docs/MEMORY-GRAPH.md`)](./docs/MEMORY-GRAPH.md)** · **[Engineering Blog Post: From Flat JSON to a FalkorDB Memory Graph (`docs/BLOG-POST.md`)](./docs/BLOG-POST.md)**
|
|
27
|
+
|
|
28
|
+
<br/>
|
|
29
|
+
|
|
30
|
+
**Works with**
|
|
31
|
+
|
|
32
|
+
<p align="center">
|
|
33
|
+
<img src="./support_images/readme/cursor.png" alt="Cursor" height="46" />
|
|
34
|
+
<img src="./support_images/readme/claude.png" alt="Claude Code" height="46" />
|
|
35
|
+
<img src="./support_images/readme/copilot.png" alt="GitHub Copilot" height="46" />
|
|
36
|
+
<br />
|
|
37
|
+
<img src="./support_images/readme/codex.png" alt="Codex" height="46" />
|
|
38
|
+
<img src="./support_images/readme/antigravity.png" alt="Google Antigravity" height="46" />
|
|
39
|
+
</p>
|
|
40
|
+
|
|
41
|
+
</div>
|
|
42
|
+
|
|
43
|
+
## The problem
|
|
44
|
+
|
|
45
|
+
Eighteen months ago you had **one** coding assistant. Today you probably have **three running at once** — Claude in one terminal, Cursor in another, Copilot in the editor. They all write to the same files, and not one of them knows the others exist.
|
|
46
|
+
|
|
47
|
+
Now put **four people** on that repo. That's **twelve agents**, editing the same code, blind to each other. You find out at the merge. Or you don't find out at all.
|
|
48
|
+
|
|
49
|
+
Git solved this for humans — but Git assumes people committing at human speed, minutes apart, one branch each. **Agents write at machine speed, in parallel, in the same directory.** There is no layer for that.
|
|
50
|
+
|
|
51
|
+
## The fix
|
|
52
|
+
|
|
53
|
+
```diff
|
|
54
|
+
- 12 agents · 12 blind writers · flat JSON amnesia · conflicts discovered at merge
|
|
55
|
+
+ 12 agents · 1 lock table · 1 FalkorDB memory graph · conflicts prevented at the edit
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Relay sits under every agent as a **real-time coordination and graph-memory layer**. Pre-tool hooks claim a lock before an agent writes; post-tool hooks release it. And underneath the lock table, a **FalkorDB property graph** continuously connects every agent turn, file edit, prompt, lock contention, and decision so every agent understands *why* code looks the way it does and *what* other agents are doing right now.
|
|
59
|
+
|
|
60
|
+
> **One host, no backend.** One person runs `relay serve` — that machine *is* the server and hosts the room's FalkorDB graph. Teammates connect over a fast tunnel (Cloudflare Quick Tunnel, Tailscale Funnel, custom host URL, or ngrok), straight to that laptop. Nothing lives on infrastructure you do not own.
|
|
61
|
+
|
|
62
|
+
<div align="center">
|
|
63
|
+
|
|
64
|
+

|
|
65
|
+
|
|
66
|
+
**[Watch the full demo on YouTube](https://youtu.be/vUea5Qih-nM)**
|
|
67
|
+
|
|
68
|
+
</div>
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Memory Graph (FalkorDB) — Shared Context for Every Agent
|
|
73
|
+
|
|
74
|
+
Locks stop two agents from overwriting the same file at the same instant. **They don't tell the second agent *why* the file is taken, *which user prompt* caused a recent change, *what architectural decisions* govern the file, or *who on the team* owns that work area.**
|
|
75
|
+
|
|
76
|
+
Relay solves this with **one FalkorDB property graph per project** (`relay_<projectId>`). Every transcript turn, code edit, watcher patch, lock claim, contention block, and decision across all 5 supported agents (**Cursor, Claude Code, Codex, GitHub Copilot, and Google Antigravity**) and every teammate in a room flows into FalkorDB via idempotent, content-addressed `MERGE` batches.
|
|
77
|
+
|
|
78
|
+
### The FalkorDB Graph Schema
|
|
79
|
+
|
|
80
|
+
```mermaid
|
|
81
|
+
flowchart LR
|
|
82
|
+
Person(["Person"]) -->|RUNS| Agent(["Agent"])
|
|
83
|
+
Agent -->|RAN| Session(["Session"])
|
|
84
|
+
Session -->|HAS_TURN| Turn(["Turn"])
|
|
85
|
+
Session -->|MADE| Edit(["Edit"])
|
|
86
|
+
Edit -->|MODIFIED| File(["File"])
|
|
87
|
+
Agent -->|TOUCHED| File
|
|
88
|
+
Session -->|HELD| File
|
|
89
|
+
Edit -->|PROMPTED_BY| Turn
|
|
90
|
+
Edit -->|EXPLAINED_BY| Turn
|
|
91
|
+
Edit -->|SAME_CHANGE| Edit
|
|
92
|
+
Contention(["Contention"]) -->|ON| File
|
|
93
|
+
Contention -->|HELD_BY| Session
|
|
94
|
+
Contention -->|WANTED_BY| Session
|
|
95
|
+
Overlap(["Overlap"]) -->|ON| File
|
|
96
|
+
Overlap -->|BETWEEN| Edit
|
|
97
|
+
Decision(["Decision"]) -->|ABOUT| File
|
|
98
|
+
Decision -->|DURING| Session
|
|
99
|
+
Agent -->|DECIDED| Decision
|
|
100
|
+
File <-->|CO_EDITED| File
|
|
101
|
+
Agent <-->|OVERLAPS_WITH| Agent
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
```text
|
|
105
|
+
Person ──► Agent ──► Session ──► Turn
|
|
106
|
+
└──► MADE ──► Edit ──► MODIFIED ──► File ◄── ON ── Contention ──► HELD_BY ──► Session (its intent)
|
|
107
|
+
└──► PROMPTED_BY ──► the user request behind the change
|
|
108
|
+
File ──► CO_EDITED ──► File (PageRank = coordination hotspots, Label Propagation = functional work areas)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Before vs. Now: Why FalkorDB Replaced Flat JSON
|
|
112
|
+
|
|
113
|
+
| Capability | Before (Flat `memory.json` + JSONL) | Now (FalkorDB Property Graph) |
|
|
114
|
+
|---|---|---|
|
|
115
|
+
| **Storage & retention** | Flat arrays capped at **2,000 events / 400 edits**; older sessions permanently lost on sync | Persistent **per-project multigraph** (`relay_<projectId>`) with in-place migrations and 90-day text pruning (`Meta.lastIngestAt`) — structural history never ages out |
|
|
116
|
+
| **Explaining a file ("Why?")** | 3 separate linear scans across `memory.json`, `decisions.jsonl`, and `collisions.json` with timestamp guessing | **1-hop OpenCypher traversal** (`(File)<-[:MODIFIED]-(Edit)-[:PROMPTED_BY]->(Turn)`) linking 100% of transcript edits to the exact user prompt (skipping filler like *"continue"* / *"yes"*) |
|
|
117
|
+
| **Lock denials at conflict time** | Blind refusal: *"File `src/auth.ts` is locked by Claude Code."* | **Intent-enriched refusal** (0 ms DB wait via FalkorDB-warmed intent cache): quotes the holder's active prompt (`They're working on: "switch the login flow to JWT tokens"`) |
|
|
118
|
+
| **Hotspots & work areas** | Simple edit counters; directory-only grouping | Native **FalkorDB graph algorithms**: `CALL algo.pageRank('File', 'CO_EDITED')` for coordination hotspots and `CALL algo.labelPropagation` for cross-folder functional communities |
|
|
119
|
+
| **Conversational recall** | Substring `.includes()` over capped recent chat array | **RediSearch full-text index** (`CALL db.idx.fulltext.queryNodes('Turn', $q)`) across every agent session and teammate |
|
|
120
|
+
| **Cross-machine room sync** | Disconnected union of teammate arrays | Unified room graph on the host; guests query the host's FalkorDB graph over the room tunnel with **zero local DB setup** |
|
|
121
|
+
|
|
122
|
+
### Context at the Moment of Conflict
|
|
123
|
+
|
|
124
|
+
When an agent's pre-tool hook is denied a lock, Relay enriches the refusal using the holder session's live intent from the graph (cached in-memory so the lock path never blocks on DB I/O):
|
|
125
|
+
|
|
126
|
+
```text
|
|
127
|
+
File `src/auth.ts` is locked by Claude Code:DESK:52b2…. Pick a different task.
|
|
128
|
+
They're working on: "switch the login flow to JWT tokens" (2 min ago).
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Context Before Acting (`relay_session_brief` & `relay_graph_query`)
|
|
132
|
+
|
|
133
|
+
`relay init` wires every agent (`CLAUDE.md`, `AGENTS.md`, `.cursorrules`, `.github/copilot-instructions.md`) to call **`relay_session_brief({ paths })`** before editing unfamiliar files, and exposes **`relay_graph_query`** with 10 named, read-only Cypher queries (`file_story`, `who_to_ask`, `contention_trace`, `search_memory`, `agent_activity`, `hotspots`, `overlaps`, `decision_trace`, `session_brief`, `overview`). Every response returns both the data and the exact Cypher query executed:
|
|
134
|
+
|
|
135
|
+
```cypher
|
|
136
|
+
// 1. file_story — Every change to a file with the user prompt that caused it
|
|
137
|
+
MATCH (f:File {key: $fileKey})<-[:MODIFIED]-(e:Edit)-[:BY]->(a:Agent)
|
|
138
|
+
WHERE NOT (e)-[:SAME_CHANGE]->()
|
|
139
|
+
OPTIONAL MATCH (e)-[p:PROMPTED_BY]->(u:Turn)
|
|
140
|
+
OPTIONAL MATCH (e)-[:EXPLAINED_BY]->(x:Turn)
|
|
141
|
+
OPTIONAL MATCH (s:Session)-[:MADE]->(e)
|
|
142
|
+
RETURN e.ts AS ts, a.label AS agent, a.login AS person, s.title AS session,
|
|
143
|
+
u.text AS prompt, p.via AS via, x.text AS agentSaid, e.added AS added, e.removed AS removed
|
|
144
|
+
ORDER BY ts DESC LIMIT $limit
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
```cypher
|
|
148
|
+
// 2. contention_trace — Who blocked whom on a file, and what both agents were working on
|
|
149
|
+
MATCH (c:Contention)-[:ON]->(f:File)
|
|
150
|
+
WHERE $fileKey IS NULL OR f.key = $fileKey
|
|
151
|
+
OPTIONAL MATCH (c)-[:HELD_BY]->(hs:Session)<-[:RAN]-(ha:Agent)
|
|
152
|
+
OPTIONAL MATCH (c)-[:WANTED_BY]->(ws:Session)<-[:RAN]-(wa:Agent)
|
|
153
|
+
RETURN c.ts AS ts, c.attempts AS attempts, f.path AS file,
|
|
154
|
+
coalesce(ha.label, c.holderLabel) AS holder, coalesce(c.holderIntent, hs.intent) AS holderWasDoing,
|
|
155
|
+
coalesce(wa.label, c.wanterLabel) AS wanter, ws.intent AS wanterWasDoing
|
|
156
|
+
ORDER BY ts DESC LIMIT $limit
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
```cypher
|
|
160
|
+
// 3. hotspots — PageRank & Community Detection over the CO_EDITED projection
|
|
161
|
+
CALL algo.pageRank('File', 'CO_EDITED') YIELD node, score SET node.rank = score;
|
|
162
|
+
CALL algo.labelPropagation({nodeLabels: ['File'], relationshipTypes: ['CO_EDITED']})
|
|
163
|
+
YIELD node, communityId SET node.community = communityId;
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Start the FalkorDB Memory Graph in 3 Commands
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
relay graph up # Starts FalkorDB in Docker (:6379) + FalkorDB Browser (:3010)
|
|
170
|
+
relay graph enable # Saves URL (or pass falkor://user:pass@host:port for FalkorDB Cloud) & hot-enables
|
|
171
|
+
relay serve # Open Mission Control → Memory Graph tab (http://localhost:3001/?tab=graph)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Full guide (Windows/macOS/Linux setup, FalkorDB Cloud, persistence, migrations & troubleshooting): **[docs/MEMORY-GRAPH.md](./docs/MEMORY-GRAPH.md)** · Deep-dive architecture writeup: **[docs/BLOG-POST.md](./docs/BLOG-POST.md)**.
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## The five pillars
|
|
179
|
+
|
|
180
|
+
| | What it does |
|
|
181
|
+
|---|---|
|
|
182
|
+
| **Memory graph (FalkorDB)** | Every person, agent, session, prompt, edit, block, overlap, and decision across machines as one FalkorDB property graph. Agents query it *before* they act (`relay_session_brief`, `relay_graph_query`), and *at the moment of conflict*: a denied lock tells the blocked agent what the holder is working on. |
|
|
183
|
+
| **File locking** | Every agent write goes through a claim/release cycle against a shared lock table (TTL-based, auto-expiring). Destructive overwrites are blocked, not detected after the fact. |
|
|
184
|
+
| **Dependency-graph locking** | Files do not exist independently — one change can affect dozens. Relay parses imports with tree-sitter and asks *"does this change affect files another agent is working on?"*, not just *"is this exact file locked?"* Agents stay parallel; the blast radius stays safe. |
|
|
185
|
+
| **Patch sync across machines** | Your teammate has their own filesystem, environment, and agents. Relay propagates **patches**, not whole-project copies — `relay push` / `relay pull` keep every clone on the same working state. |
|
|
186
|
+
| **Mission Control** | One board for every agent on every machine: interactive **FalkorDB Memory Graph explorer**, live lock table, dependency lock graph, code edits, unified agent chat history, conflicts, presence. |
|
|
187
|
+
|
|
188
|
+
## Quick start
|
|
189
|
+
|
|
190
|
+
**Install** (Node 20+):
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
npm install -g relaybrain # installs the `relay` CLI with Mission Control prebuilt
|
|
194
|
+
relay graph up # optional: FalkorDB memory graph in Docker
|
|
195
|
+
relay graph enable
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
**Host** — the machine everyone else connects to:
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
relay login # GitHub identity (uses the gh CLI)
|
|
202
|
+
relay clone <repo-url> # clone + register workspace + install agent hooks
|
|
203
|
+
relay graph up # start FalkorDB container (optional — or use FalkorDB Cloud)
|
|
204
|
+
relay graph enable # enable the FalkorDB memory graph
|
|
205
|
+
relay serve # API + Mission Control → http://localhost:3001
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Then open Mission Control → **Team → Share** to start a tunnel (Cloudflare Quick Tunnel / Tailscale Funnel / custom URL) and mint the invite link.
|
|
209
|
+
|
|
210
|
+
**Teammate:**
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
relay serve # their own local relay (queries host's FalkorDB graph over the tunnel)
|
|
214
|
+
# join with the host's invite link on the Team tab
|
|
215
|
+
relay pull # take the host's current working state
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Now start agents as usual. Hooks claim and release locks automatically — nobody has to remember a command.
|
|
219
|
+
|
|
220
|
+
<details>
|
|
221
|
+
<summary><strong>Install options</strong></summary>
|
|
222
|
+
|
|
223
|
+
<br/>
|
|
224
|
+
|
|
225
|
+
| Method | Command |
|
|
226
|
+
|--------|---------|
|
|
227
|
+
| npm | `npm install -g relaybrain` |
|
|
228
|
+
| local dev | `npm i`, then `npm link` in this repo |
|
|
229
|
+
| attach an existing repo | `relay add /path/to/repo` |
|
|
230
|
+
| fresh clone | `relay clone <url> [dir]` |
|
|
231
|
+
|
|
232
|
+
Requires **Node.js 20+** and **npm**. No hosted backend, no login server. The memory graph uses FalkorDB (`relay graph up` via Docker, or FalkorDB Cloud); without it, relay fails open and runs on files alone. See [**Dependencies**](#dependencies) below for install commands (`cloudflared`, `gh`, Docker, etc.).
|
|
233
|
+
|
|
234
|
+
</details>
|
|
235
|
+
|
|
236
|
+
## How it works
|
|
237
|
+
|
|
238
|
+
```text
|
|
239
|
+
Cursor ──┐ pre-tool hook: claim
|
|
240
|
+
Claude ──┤ post-tool hook: release ┌──────────────┐
|
|
241
|
+
Copilot ─┼──► lock table ◄── dep graph ──│ relay serve │──► Mission Control (:3001)
|
|
242
|
+
Codex ───┤ ▲ │ (your host) │ ▲
|
|
243
|
+
Antigravity ┘ │ └──────┬───────┘ │
|
|
244
|
+
│ tunnel │ │
|
|
245
|
+
teammate's relay ◄──── patches ─────┼──────────────────┘
|
|
246
|
+
▼
|
|
247
|
+
┌─────────────────┐
|
|
248
|
+
│ FalkorDB │
|
|
249
|
+
│ Memory Graph │
|
|
250
|
+
│ (per-project) │
|
|
251
|
+
└─────────────────┘
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
| Layer | Who runs it | What it guards / powers |
|
|
255
|
+
|-------|-------------|-------------------------|
|
|
256
|
+
| **Memory graph** | FalkorDB (`relay_<projectId>`) | multi-agent provenance (`PROMPTED_BY`), lock intent, PageRank hotspots, `relay_session_brief` |
|
|
257
|
+
| **Claim / release** | pre- and post-tool hooks | exclusive write access to a file |
|
|
258
|
+
| **Dependency graph** | tree-sitter import scan | files *affected by* the edit, not just the edit |
|
|
259
|
+
| **Room** | `relay serve` + tunnel (Cloudflare / Tailscale / custom) | one shared lock table and memory graph across machines |
|
|
260
|
+
| **Patches** | `relay push` / `relay pull` | working-tree state without full copies |
|
|
261
|
+
| **Board** | Mission Control (:3001) | interactive Memory Graph canvas + who holds what, right now |
|
|
262
|
+
|
|
263
|
+
> Locks and the board are separate subsystems — hooks arbitrate straight against the host, while the board and FalkorDB graph are fed asynchronously. `relay doctor` walks that chain and tells you which link is broken.
|
|
264
|
+
|
|
265
|
+
## Commands
|
|
266
|
+
|
|
267
|
+
| Command | Description |
|
|
268
|
+
|---------|-------------|
|
|
269
|
+
| `relay login` / `logout` / `whoami` | GitHub identity (via `gh` CLI, or device flow with `GITHUB_CLIENT_ID`) |
|
|
270
|
+
| `relay clone <url> [dir]` | git clone + register workspace + install agent hooks |
|
|
271
|
+
| `relay add <path>` | Attach an existing local repo |
|
|
272
|
+
| `relay init [path]` | Wire hooks, Relay MCP, and `/relay ask` instructions for all agents |
|
|
273
|
+
| `relay serve` | API + Mission Control on `127.0.0.1:3001` (prebuilt UI) |
|
|
274
|
+
| `relay serve --dev` | Mission Control with hot reload on `:3002` |
|
|
275
|
+
| `relay serve --no-ui` | API + coordinator only |
|
|
276
|
+
| `relay graph up` | Start the local FalkorDB Docker container (`:6379` + Browser UI `:3010`) |
|
|
277
|
+
| `relay graph enable [url]` / `disable` | Enable FalkorDB memory graph (local Docker or `falkor://` Cloud URL) |
|
|
278
|
+
| `relay graph status` / `stats` / `rebuild` | Check FalkorDB health, inspect node/edge counts & migrations, or backfill history |
|
|
279
|
+
| `relay graph seed [id]` | Seed a five-agent demo graph into an isolated `demo_<id>` sandbox |
|
|
280
|
+
| `relay push` | Send your dirty working-tree files to the shared room |
|
|
281
|
+
| `relay pull` | Apply the host's current dirty files onto this clone |
|
|
282
|
+
| `relay status` | Health check (room, role, host, ports) |
|
|
283
|
+
| `relay mcp-url` | Print the MCP config for this room's shared-context endpoint |
|
|
284
|
+
| `relay doctor` | Diagnose Coordinator board, hooks, and FalkorDB graph connectivity |
|
|
285
|
+
|
|
286
|
+
## Mission Control
|
|
287
|
+
|
|
288
|
+
Started by `relay serve` — runs on your own machine, no hosted account.
|
|
289
|
+
|
|
290
|
+
| | URL |
|
|
291
|
+
|---|-----|
|
|
292
|
+
| Dashboard | http://localhost:3001 |
|
|
293
|
+
| Memory Graph Explorer | http://localhost:3001/?tab=graph |
|
|
294
|
+
| API | http://127.0.0.1:3001/api/health |
|
|
295
|
+
|
|
296
|
+
**Collisions prevented counter** (persisted to `~/.relay/data/projects/<id>/collisions.json` and mirrored to `<repo>/.relay/collisions.json`, with full `Contention` nodes and holder intents recorded in FalkorDB).
|
|
297
|
+
|
|
298
|
+
## MCP — shared room & graph context
|
|
299
|
+
|
|
300
|
+
Any MCP client can read the room's context and query the FalkorDB memory graph, **even on a machine with no relay or FalkorDB installed**:
|
|
301
|
+
|
|
302
|
+
```bash
|
|
303
|
+
relay mcp-url # prints a ready-to-paste mcpServers block
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
Coordination tools (`relay_claim_file`, `relay_release_file`, `relay_status`) run against each member's own local relay. The room endpoint is **read-only** for anyone off the host machine.
|
|
307
|
+
|
|
308
|
+
<details>
|
|
309
|
+
<summary><strong>Tools exposed (17 MCP tools)</strong></summary>
|
|
310
|
+
|
|
311
|
+
<br/>
|
|
312
|
+
|
|
313
|
+
| Tool | Purpose |
|
|
314
|
+
|------|---------|
|
|
315
|
+
| `relay_session_brief` | **FalkorDB Memory Graph** brief for files you're about to touch: who's on them now and why, blocks, decisions, prompts behind changes, who to ask, and co-edited community files |
|
|
316
|
+
| `relay_graph_query` | **FalkorDB Memory Graph** named Cypher queries (`file_story`, `who_to_ask`, `contention_trace`, `search_memory`, `agent_activity`, `hotspots`, `overlaps`, `decision_trace`, `session_brief`, `overview`) |
|
|
317
|
+
| `relay_claim_file` | Acquire an exclusive write lock before editing |
|
|
318
|
+
| `relay_release_file` | Release the lock after editing |
|
|
319
|
+
| `relay_status` | View the full lock table |
|
|
320
|
+
| `relay_get_conflicts` | Overlapping edits in the last 5 minutes |
|
|
321
|
+
| `relay_get_recent_changes` | Recent `code_edit` events |
|
|
322
|
+
| `relay_get_chat_history` | Unified agent chat across every room member |
|
|
323
|
+
| `relay_room_brief` | Teammate activity + memory graph brief (for the `/relay ask` agent pseudo-command) |
|
|
324
|
+
| `relay_get_collision_stats` | Lifetime counters for collisions Relay prevented |
|
|
325
|
+
| `relay_report_change` | Push a code-change event |
|
|
326
|
+
| `relay_report_decision` / `relay_get_decisions` | Append / read file-scoped architectural decisions (synced to FalkorDB `Decision` nodes) |
|
|
327
|
+
| `relay_update_task` / `relay_get_active_tasks` | Append / read tasks (synced to FalkorDB `Task` nodes) |
|
|
328
|
+
| `relay_get_project_context` | Full JSON project context |
|
|
329
|
+
| `relay_sync` | Re-read agent transcripts into unified history and trigger FalkorDB ingest |
|
|
330
|
+
|
|
331
|
+
</details>
|
|
332
|
+
|
|
333
|
+
## Hooks
|
|
334
|
+
|
|
335
|
+
`relay clone` / `relay add` / `relay init` install pre-tool (**claim**), post-tool (**release**), pre-read, stop hooks, **Relay MCP** (`relay_session_brief`, `relay_graph_query`, `relay_room_brief`), and the relay-os instruction block into every agent surface:
|
|
336
|
+
|
|
337
|
+
| Agent | Hooks | Instructions | Relay MCP (`relay_session_brief` / `relay_graph_query`) |
|
|
338
|
+
|-------|--------|--------------|--------------------------------|
|
|
339
|
+
| Claude Code | `.claude/settings.json` | `CLAUDE.md` | `.claude/settings.json` → `mcpServers.relay` |
|
|
340
|
+
| Cursor | `.cursor/hooks.json` | `.cursor/rules/relay.mdc`, `AGENTS.md` | `.cursor/mcp.json` |
|
|
341
|
+
| Codex | `.codex/hooks.json` | `AGENTS.md` | `.codex/config.toml` → `[mcp_servers.relay]` |
|
|
342
|
+
| Copilot CLI | `.github/hooks/relay-os.json` | `.github/copilot-instructions.md` | `.github/mcp.json` |
|
|
343
|
+
| Antigravity | `.agents/hooks.json` | `AGENTS.md` | `.agents/mcp_config.json` |
|
|
344
|
+
|
|
345
|
+
Languages parsed for the dependency graph: TypeScript/JavaScript, Python, Go, Rust, Java, C#, C/C++, PHP, Ruby.
|
|
346
|
+
|
|
347
|
+
## Dependencies
|
|
348
|
+
|
|
349
|
+
| | |
|
|
350
|
+
|---|---|
|
|
351
|
+
| **Required** | **Node.js 20+** & `npm` |
|
|
352
|
+
| **Bundled** | `falkordb`, `express`, `cors`, `ws`, `@vscode/tree-sitter-wasm` · `next`, `react` (Mission Control) |
|
|
353
|
+
| **Graph DB** | **FalkorDB** (`relay graph up` via Docker, or [FalkorDB Cloud](https://app.falkordb.cloud)) |
|
|
354
|
+
| **Not needed** | MongoDB, Postgres, a hosted Relay backend, an account |
|
|
355
|
+
| **Optional** | `gh` CLI for `relay login` · `cloudflared` / Tailscale Funnel / ngrok / custom URL for cross-machine rooms |
|
|
356
|
+
|
|
357
|
+
**Env vars:** `RELAY_FALKOR_URL` · `RELAY_FALKOR_TEXT` · `RELAY_FALKOR_TEXT_DAYS` (90) · `RELAY_PORT` (3001) · `RELAY_UI_PORT` (3002) · `RELAY_UI_ORIGIN` · `RELAY_TUNNEL` (`cloudflared`\|`tailscale`\|`ngrok`) · `RELAY_PUBLIC_URL` · `RELAY_PUBLIC_READONLY`
|
|
358
|
+
|
|
359
|
+
### Installing dependencies
|
|
360
|
+
|
|
361
|
+
#### 1. Node.js 20+ & npm *(Required)*
|
|
362
|
+
|
|
363
|
+
- **Windows (`winget`):** `winget install OpenJS.NodeJS.LTS`
|
|
364
|
+
- **macOS (`brew`):** `brew install node@20`
|
|
365
|
+
- **Linux (Ubuntu/Debian):** `curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - && sudo apt-get install -y nodejs`
|
|
366
|
+
|
|
367
|
+
#### 2. Docker Desktop / Docker Engine *(For local FalkorDB memory graph — or use FalkorDB Cloud)*
|
|
368
|
+
|
|
369
|
+
Used to run the local FalkorDB container via `relay graph up` (or skip Docker and connect to [FalkorDB Cloud](https://app.falkordb.cloud) with `relay graph enable falkor://default:PASSWORD@HOST:PORT`).
|
|
370
|
+
|
|
371
|
+
- **Windows (`winget`):** `winget install Docker.DockerDesktop`
|
|
372
|
+
- **macOS (`brew`):** `brew install --cask docker`
|
|
373
|
+
- **Linux:** `curl -fsSL https://get.docker.com | sh`
|
|
374
|
+
|
|
375
|
+
#### 3. GitHub CLI (`gh`) *(Optional — identity & room signaling)*
|
|
376
|
+
|
|
377
|
+
Used by `relay login` to attach your GitHub identity when hosting or joining rooms. After installing, run `gh auth login`.
|
|
378
|
+
|
|
379
|
+
- **Windows (`winget`):** `winget install GitHub.cli`
|
|
380
|
+
- **macOS (`brew`):** `brew install gh`
|
|
381
|
+
- **Linux (Ubuntu/Debian):** `sudo apt-get update && sudo apt-get install -y gh`
|
|
382
|
+
|
|
383
|
+
#### 4. Tunnel Provider for Cross-Machine Rooms *(Optional — room host only)*
|
|
384
|
+
|
|
385
|
+
Only the **room host** needs a tunnel when sharing a session across different networks. Pick any one:
|
|
386
|
+
|
|
387
|
+
- **Cloudflare Quick Tunnels (`cloudflared`) — Recommended** *(zero signup, no account, no rate limits)*:
|
|
388
|
+
- **Windows (`winget`):** `winget install Cloudflare.cloudflared`
|
|
389
|
+
- **macOS (`brew`):** `brew install cloudflared`
|
|
390
|
+
- **Linux:** `curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 -o /usr/local/bin/cloudflared && chmod +x /usr/local/bin/cloudflared`
|
|
391
|
+
- **Tailscale Funnel (`tailscale`):**
|
|
392
|
+
- **Windows (`winget`):** `winget install Tailscale.Tailscale`
|
|
393
|
+
- **macOS (`brew`):** `brew install --cask tailscale`
|
|
394
|
+
- **Linux:** `curl -fsSL https://tailscale.com/install.sh | sh`
|
|
395
|
+
- Expose port: `tailscale funnel 3001`
|
|
396
|
+
- **Custom URL / Cloud VM:**
|
|
397
|
+
- Set `RELAY_PUBLIC_URL=https://your-domain` or paste your public URL directly in Mission Control → **Team → Share**.
|
|
398
|
+
|
|
399
|
+
## Documentation
|
|
400
|
+
|
|
401
|
+
Full documentation lives in [`docs/`](./docs/README.md).
|
|
402
|
+
|
|
403
|
+
| | |
|
|
404
|
+
|---|---|
|
|
405
|
+
| **[Memory graph (FalkorDB)](./docs/MEMORY-GRAPH.md)** | **FalkorDB graph model, Cypher queries, PageRank/CDLP algorithms, migrations & setup** |
|
|
406
|
+
| **[Engineering blog post](./docs/BLOG-POST.md)** | **From flat JSON to a FalkorDB memory graph for AI coding agents** |
|
|
407
|
+
| [Quickstart](./docs/QUICKSTART.md) | Coordinating in about five minutes |
|
|
408
|
+
| [Installation](./docs/INSTALLATION.md) | Requirements, install methods, what gets written where |
|
|
409
|
+
| [Concepts](./docs/CONCEPTS.md) | Workspace, project, agent ID, lock, room, patch |
|
|
410
|
+
| [Rooms and teams](./docs/ROOMS.md) | Hosting, invites, member tokens, joining, leaving |
|
|
411
|
+
| [Architecture](./docs/ARCHITECTURE.md) | Process model, the two planes, one edit end to end |
|
|
412
|
+
| [Locking](./docs/LOCKING.md) | The lock table, TTLs, ownership, dependency-graph soft locks |
|
|
413
|
+
| [Sync and patches](./docs/SYNC.md) | Patch format, Lamport ordering, transform, transcripts |
|
|
414
|
+
| [CLI reference](./docs/CLI.md) | Every command, flag and exit code |
|
|
415
|
+
| [HTTP API reference](./docs/HTTP-API.md) | Every endpoint, with auth rules |
|
|
416
|
+
| [MCP reference](./docs/MCP.md) | The seventeen tools and the read-only room endpoint |
|
|
417
|
+
| [Hooks reference](./docs/HOOKS.md) | The hook contract per agent |
|
|
418
|
+
| [Configuration](./docs/CONFIGURATION.md) | Environment variables, ports, on-disk layout |
|
|
419
|
+
| [Troubleshooting](./docs/TROUBLESHOOTING.md) | `relay doctor` and the known failure modes |
|
|
420
|
+
|
|
421
|
+
## Roadmap
|
|
422
|
+
|
|
423
|
+
- **Git worktree isolation** — every agent in its own workspace off the same repository, free to experiment and test independently, integrated back into main when the work is ready.
|
|
424
|
+
- Richer conflict resolution on top of the existing OT / patch layer and FalkorDB overlap graph.
|
|
425
|
+
|
|
426
|
+
<div align="center">
|
|
427
|
+
|
|
428
|
+
**We used Relay to build Relay.** The problem we were solving was the problem we were having.
|
|
429
|
+
|
|
430
|
+
The next time you build a hackathon project, do not just add more agents. **Just relay.it**
|
|
431
|
+
|
|
432
|
+
<sub>MIT licensed · Powered by FalkorDB · Your machine is the server.</sub>
|
|
433
|
+
|
|
434
|
+
</div>
|