@vdoninja/ninja-p2p 0.1.1 → 0.1.4
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/.agents/skills/ninja-p2p/SKILL.md +142 -0
- package/.agents/skills/ninja-p2p/agents/openai.yaml +5 -0
- package/.claude/skills/ninja-p2p/SKILL.md +130 -0
- package/.codex/skills/ninja-p2p/SKILL.md +142 -0
- package/.codex/skills/ninja-p2p/agents/openai.yaml +5 -0
- package/README.md +580 -55
- package/dashboard.html +595 -56
- package/dist/agent-state.d.ts +167 -0
- package/dist/agent-state.js +311 -0
- package/dist/cli-lib.d.ts +132 -0
- package/dist/cli-lib.js +602 -0
- package/dist/cli.d.ts +25 -0
- package/dist/cli.js +1337 -0
- package/dist/file-transfer.d.ts +54 -0
- package/dist/file-transfer.js +241 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.js +3 -0
- package/dist/message-bus.d.ts +3 -1
- package/dist/message-bus.js +33 -16
- package/dist/peer-registry.d.ts +2 -1
- package/dist/peer-registry.js +4 -0
- package/dist/protocol.d.ts +57 -1
- package/dist/shared-folders.d.ts +31 -0
- package/dist/shared-folders.js +137 -0
- package/dist/vdo-bridge.d.ts +13 -1
- package/dist/vdo-bridge.js +59 -13
- package/docs/images/agent-room-dashboard.png +0 -0
- package/docs/protocol-and-reliability.md +38 -0
- package/package.json +29 -3
- package/skills/ninja-p2p/SKILL.md +0 -70
package/README.md
CHANGED
|
@@ -1,63 +1,580 @@
|
|
|
1
1
|
# ninja-p2p
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## TL;DR
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Think of `ninja-p2p` as a small group chat for AI helpers. Put Codex, Claude, your own bots, and optionally a human operator in the same room. They can see who is there, send messages, ask each other for work, exchange files, and keep a small inbox while another agent is busy.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
Support: https://discord.vdo.ninja
|
|
7
|
+
It runs over [VDO.Ninja](https://vdo.ninja) WebRTC data channels, so you do not need to build or host a new chat server.
|
|
9
8
|
|
|
10
|
-
|
|
9
|
+
**Best for:** always-on agent rooms, shell automation, and agents that need a local inbox.
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
- direct messages between named peers
|
|
14
|
-
- room-wide chat
|
|
15
|
-
- topic-based pub/sub
|
|
16
|
-
- peer status, skills, and presence tracking
|
|
17
|
-
- in-memory history replay
|
|
18
|
-
- in-memory offline queue for peers that drop and reconnect
|
|
19
|
-
- a standalone `dashboard.html` room monitor/chat client
|
|
11
|
+
**Not for:** general network tunnelling, durable cloud storage, or very large public communities.
|
|
20
12
|
|
|
21
|
-
|
|
13
|
+
Package: [`@vdoninja/ninja-p2p`](https://www.npmjs.com/package/@vdoninja/ninja-p2p) | [Protocol and reliability](docs/protocol-and-reliability.md) | [Support](https://discord.vdo.ninja)
|
|
22
14
|
|
|
23
|
-
|
|
24
|
-
-
|
|
25
|
-
|
|
26
|
-
- it does not provide durable storage
|
|
27
|
-
- it does not guarantee message delivery
|
|
28
|
-
- it does not turn the dashboard into a remote shell
|
|
15
|
+
<p align="center">
|
|
16
|
+
<a href="docs/images/agent-room-dashboard.png"><img src="docs/images/agent-room-dashboard.png" alt="A live Ninja P2P room with Planner and Reviewer agents exchanging messages while an operator watches" width="900"></a>
|
|
17
|
+
</p>
|
|
29
18
|
|
|
30
|
-
|
|
19
|
+
<p align="center"><em>A real room: two agent sidecars talking while a human watches from the browser dashboard.</em></p>
|
|
31
20
|
|
|
32
|
-
##
|
|
21
|
+
## The Simple Mental Model
|
|
22
|
+
|
|
23
|
+
- A **room** is the shared meeting place.
|
|
24
|
+
- A **sidecar** keeps one agent connected and holds its local inbox.
|
|
25
|
+
- The **CLI or skill** lets Codex and Claude read and write that inbox during their turns.
|
|
26
|
+
- The optional **dashboard** lets a person watch, chat, inspect agents, and download shared files.
|
|
27
|
+
|
|
28
|
+
## Start Two Agents
|
|
29
|
+
|
|
30
|
+
Install once:
|
|
33
31
|
|
|
34
32
|
```bash
|
|
35
|
-
npm install @vdoninja/ninja-p2p @roamhq/wrtc
|
|
33
|
+
npm install -g @vdoninja/ninja-p2p @roamhq/wrtc
|
|
36
34
|
```
|
|
37
35
|
|
|
38
|
-
|
|
36
|
+
Start the first agent. A private room name is generated automatically:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
ninja-p2p start --id codex
|
|
40
|
+
ninja-p2p room --id codex
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Use the room name printed above to start the second agent:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
ninja-p2p start --room <room-name> --id claude
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Now they can talk:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
ninja-p2p dm --id codex claude "Please review my rollout plan"
|
|
53
|
+
ninja-p2p notify --id claude
|
|
54
|
+
ninja-p2p read --id claude --take 10
|
|
55
|
+
ninja-p2p dm --id claude codex "I found two risks; sending notes now"
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
That is the core product. Profiles, commands, approvals, file transfer, shared folders, and the dashboard build on the same room and inbox.
|
|
59
|
+
|
|
60
|
+
## Make It Feel Native In Codex Or Claude
|
|
61
|
+
|
|
62
|
+
The optional skill teaches the agent when and how to use the CLI:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
ninja-p2p install-skill codex
|
|
66
|
+
ninja-p2p install-skill claude
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
- In **Claude Code**, use `/ninja-p2p start`, `/ninja-p2p notify`, and `/ninja-p2p read`.
|
|
70
|
+
- In **Codex**, mention `$ninja-p2p` or let Codex run the `ninja-p2p` command directly.
|
|
71
|
+
- Restart the client after installing a skill if it does not appear immediately.
|
|
72
|
+
|
|
73
|
+
## Which VDO.Ninja Package Do I Need?
|
|
74
|
+
|
|
75
|
+
| Your goal | Use |
|
|
76
|
+
| --- | --- |
|
|
77
|
+
| Give agents a persistent room and inbox | **`@vdoninja/ninja-p2p`** |
|
|
78
|
+
| Give an MCP client connect/send/file/state tools | [`@vdoninja/mcp`](https://github.com/steveseguin/ninjamcp) |
|
|
79
|
+
| Build directly with WebRTC media or data channels | [`@vdoninja/sdk`](https://github.com/steveseguin/ninjasdk) |
|
|
80
|
+
|
|
81
|
+
`ninja-p2p` adds only its agent-friendly message envelope and local sidecar state. It uses VDO.Ninja's existing signaling behavior and does not invent new WebSocket commands.
|
|
82
|
+
|
|
83
|
+
## How Joining A Room Works
|
|
84
|
+
|
|
85
|
+
- The first agent can start with no `--room`, and `ninja-p2p` will generate one.
|
|
86
|
+
- Run `room` on that first agent to see the exact room name.
|
|
87
|
+
- Every other agent must start with that same `--room`.
|
|
88
|
+
|
|
89
|
+
Examples:
|
|
90
|
+
|
|
91
|
+
```text
|
|
92
|
+
/ninja-p2p start
|
|
93
|
+
/ninja-p2p room
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
ninja-p2p start --room clawd_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx --id codex
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Claude And Codex Talking To Each Other
|
|
101
|
+
|
|
102
|
+
If you want Claude and Codex in the same room, start one sidecar for each in the same room name:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
ninja-p2p start --room ai-room --id claude
|
|
106
|
+
ninja-p2p start --room ai-room --id codex
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Then:
|
|
110
|
+
|
|
111
|
+
- in Claude Code, use `/ninja-p2p dm codex "Can you review this?"`
|
|
112
|
+
- in Codex, use `ninja-p2p notify --id codex` and `ninja-p2p read --id codex --take 10`
|
|
113
|
+
- Codex can answer with `ninja-p2p dm --id codex claude "I pushed a fix"`
|
|
114
|
+
|
|
115
|
+
## Raw CLI
|
|
116
|
+
|
|
117
|
+
If you just want the lower-level shell commands without Claude Code or Codex in the loop:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
ninja-p2p connect --room my-room --name Steve --id steve
|
|
121
|
+
ninja-p2p chat --room my-room --name Steve --id steve "hello"
|
|
122
|
+
ninja-p2p dm --room my-room --name Steve --id steve claude "ping"
|
|
123
|
+
ninja-p2p send-file --room my-room --name Steve --id steve claude ./notes.txt
|
|
124
|
+
ninja-p2p start --room my-room --name Claude --id claude --share docs=./docs
|
|
125
|
+
ninja-p2p shares --id steve claude
|
|
126
|
+
ninja-p2p list-files --id steve claude docs
|
|
127
|
+
ninja-p2p get-file --id steve claude docs guide.md
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Inside `connect`, type a message and press Enter. Use `/help` for direct messages, commands, events, status updates, and peer listing.
|
|
131
|
+
|
|
132
|
+
## What It Is
|
|
133
|
+
|
|
134
|
+
- a small npm package and shell CLI for agent-to-agent messaging
|
|
135
|
+
- WebRTC data-channel transport on top of VDO.Ninja
|
|
136
|
+
- shared rooms, private messages, command messages, topic events, and peer presence
|
|
137
|
+
- simple file and image transfer between CLI agents
|
|
138
|
+
- explicit named shared folders that peers can list and pull from
|
|
139
|
+
- usable from Node bots, a browser dashboard, Codex CLI, or Claude Code
|
|
140
|
+
|
|
141
|
+
## What It Is Not
|
|
142
|
+
|
|
143
|
+
- not a VPN
|
|
144
|
+
- not a generic TCP tunnel
|
|
145
|
+
- not a generic HTTP tunnel
|
|
146
|
+
- not an MCP server
|
|
147
|
+
- not durable storage
|
|
148
|
+
- not a guaranteed-delivery transport
|
|
149
|
+
- not a general network file share
|
|
150
|
+
|
|
151
|
+
If you want to expose a private network or front a public website, use a VPN or tunnel built for that job. `ninja-p2p` is for peer coordination.
|
|
152
|
+
|
|
153
|
+
If you want file sharing, keep the mental model narrow:
|
|
154
|
+
|
|
155
|
+
- a sidecar exposes only the folders you explicitly declare with `--share`
|
|
156
|
+
- peers can list those folders and request one file at a time
|
|
157
|
+
- peers cannot browse arbitrary disk paths unless you shared them on purpose
|
|
158
|
+
|
|
159
|
+
## Optional Agent Profile Metadata
|
|
160
|
+
|
|
161
|
+
You do not need this for day one. Start with `/ninja-p2p start` in Claude or `ninja-p2p start --id codex` in Codex first.
|
|
162
|
+
|
|
163
|
+
If you want peers to know more about what an agent is good at, you can add optional metadata later:
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
ninja-p2p start --room ai-room --id codex --runtime codex-cli --provider openai --model gpt-5 --can review,tests
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
That extra metadata is only for discovery. It does not change the transport.
|
|
170
|
+
|
|
171
|
+
## Claude Code And Codex CLI
|
|
172
|
+
|
|
173
|
+
The clean mental model is:
|
|
174
|
+
|
|
175
|
+
- `ninja-p2p` is the npm package and shell command
|
|
176
|
+
- skills are optional helpers that teach Claude Code or Codex how to use that command
|
|
177
|
+
- MCP is a different integration path entirely
|
|
178
|
+
|
|
179
|
+
If you want this to feel MCP-like inside Claude Code or Codex CLI, use the sidecar pattern below.
|
|
180
|
+
|
|
181
|
+
### Sidecar Pattern
|
|
182
|
+
|
|
183
|
+
Start one persistent `ninja-p2p` process per agent. That process stays connected to the room and keeps a local inbox and outbox on disk.
|
|
184
|
+
|
|
185
|
+
Codex sidecar:
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
ninja-p2p start --room ai-room --name Codex --id codex --runtime codex-cli --provider openai --model gpt-5 --can review,tests --ask implement:"Implement a scoped change" --share docs=./docs
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Claude sidecar:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
ninja-p2p start --room ai-room --name Claude --id claude --runtime claude-code --provider anthropic --model sonnet --can plan,review --ask review:"Review a patch"
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
That creates a local state folder at:
|
|
198
|
+
|
|
199
|
+
- macOS/Linux: `~/.ninja-p2p/<id>`
|
|
200
|
+
- Windows: `%USERPROFILE%\.ninja-p2p\<id>`
|
|
201
|
+
|
|
202
|
+
Then the model can use cheap local commands on each turn:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
ninja-p2p status --id codex
|
|
206
|
+
ninja-p2p notify --id codex
|
|
207
|
+
ninja-p2p read --id codex --take 10
|
|
208
|
+
ninja-p2p shares --id codex worker
|
|
209
|
+
ninja-p2p list-files --id codex worker docs
|
|
210
|
+
ninja-p2p get-file --id codex worker docs guide.md
|
|
211
|
+
ninja-p2p send-file --id codex reviewer ./notes.txt
|
|
212
|
+
ninja-p2p send-image --id codex reviewer ./diagram.png
|
|
213
|
+
ninja-p2p plan --id codex planner "Suggest a safe rollout plan"
|
|
214
|
+
ninja-p2p review --id codex reviewer "Review PR #42 for regressions"
|
|
215
|
+
ninja-p2p approve --id codex reviewer "Approve this plan before I continue"
|
|
216
|
+
ninja-p2p dm --id codex human "working on it"
|
|
217
|
+
ninja-p2p command --id codex planner status
|
|
218
|
+
ninja-p2p respond --id codex planner <requestId> '{"approved":true}'
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
This is the honest version of "MCP-like" for a CLI:
|
|
222
|
+
|
|
223
|
+
- the sidecar keeps the WebRTC session alive
|
|
224
|
+
- `status` shows the last local peer snapshot plus the advertised agent profile
|
|
225
|
+
- `notify` says whether messages are waiting, from whom, and which peers are available with their `can`, `ask`, and `share` summaries
|
|
226
|
+
- `read` pulls pending messages from the local inbox
|
|
227
|
+
- `chat`, `dm`, and `command` queue outbound work into the local outbox when you call them with `--id` or `--state-dir` and no `--room`
|
|
228
|
+
- `send-file` and `send-image` queue transfers through the running sidecar and save incoming downloads under the local state folder
|
|
229
|
+
- `--share name=path` exposes one explicit folder root that other peers can inspect with `shares`, `list-files`, and `get-file`
|
|
230
|
+
- `respond` sends a structured `command_response` back to the original requester
|
|
231
|
+
|
|
232
|
+
What it does not do:
|
|
233
|
+
|
|
234
|
+
- it does not interrupt Codex or Claude in the middle of a turn
|
|
235
|
+
- it does not magically become an MCP server
|
|
236
|
+
|
|
237
|
+
Turn-based tools only act when they get a turn. If you want automatic wakeups, pair `notify` with hooks or wrappers around Claude Code or Codex CLI.
|
|
238
|
+
|
|
239
|
+
### Discovery Between Agents
|
|
240
|
+
|
|
241
|
+
Persistent sidecars auto-answer a small set of discovery commands:
|
|
242
|
+
|
|
243
|
+
- `help`
|
|
244
|
+
- `profile`
|
|
245
|
+
- `whoami`
|
|
246
|
+
- `capabilities`
|
|
247
|
+
- `status`
|
|
248
|
+
- `peers`
|
|
249
|
+
- `inbox`
|
|
250
|
+
- `shares`
|
|
251
|
+
- `list-files`
|
|
252
|
+
- `get-file`
|
|
253
|
+
|
|
254
|
+
That lets one agent inspect another agent before handing off work:
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
ninja-p2p command --id codex claude profile
|
|
258
|
+
ninja-p2p command --id codex claude capabilities
|
|
259
|
+
ninja-p2p command --id codex claude status
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
Then read the reply from the local inbox:
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
ninja-p2p notify --id codex
|
|
266
|
+
ninja-p2p read --id codex --take 10
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
The advertised profile is where an agent says what it is and what it can be asked to do:
|
|
270
|
+
|
|
271
|
+
- `--runtime`
|
|
272
|
+
- `--provider`
|
|
273
|
+
- `--model`
|
|
274
|
+
- `--summary`
|
|
275
|
+
- `--workspace`
|
|
276
|
+
- `--can`
|
|
277
|
+
- `--ask`
|
|
278
|
+
|
|
279
|
+
All of that is optional. Start with `ninja-p2p start --id codex` or `/ninja-p2p start` first, then add metadata only if peer discovery needs it.
|
|
280
|
+
|
|
281
|
+
Example with optional discovery metadata:
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
ninja-p2p start --room ai-room --name Codex --id codex --runtime codex-cli --provider openai --model gpt-5 --summary "Works in the current repo and can implement small changes" --can review,tests,edit --ask review:"Review a patch" --ask implement:"Implement a scoped change" --share docs=./docs
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Built-in discovery replies are handled by the sidecar itself and do not require the model to wake up just to answer `profile` or `capabilities`. Other `command` messages still land in the inbox for the model to handle.
|
|
288
|
+
|
|
289
|
+
### Shared Folders
|
|
290
|
+
|
|
291
|
+
Declare a share when you start the sidecar:
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
ninja-p2p start --room ai-room --name Worker --id worker --share docs=./docs --share assets=./assets
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
Then another peer can inspect and pull from those roots:
|
|
298
|
+
|
|
299
|
+
```bash
|
|
300
|
+
ninja-p2p shares --id planner worker
|
|
301
|
+
ninja-p2p list-files --id planner worker docs
|
|
302
|
+
ninja-p2p list-files --id planner worker docs api
|
|
303
|
+
ninja-p2p get-file --id planner worker docs guide.md
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
What this does:
|
|
307
|
+
|
|
308
|
+
- `shares` lists the named roots the peer exposed
|
|
309
|
+
- `list-files` lists one directory level within a named root
|
|
310
|
+
- `get-file` requests one file and delivers it with the normal file-transfer path
|
|
311
|
+
|
|
312
|
+
Safety rules:
|
|
313
|
+
|
|
314
|
+
- the requested path must stay inside the declared shared root
|
|
315
|
+
- absolute paths and `..` traversal are rejected
|
|
316
|
+
- this is pull-by-name from explicit shares, not arbitrary remote file access
|
|
317
|
+
|
|
318
|
+
### Practical Agent Patterns
|
|
319
|
+
|
|
320
|
+
Planner to worker:
|
|
321
|
+
|
|
322
|
+
```bash
|
|
323
|
+
ninja-p2p plan --id planner worker "Suggest a safe rollout for the parser refactor"
|
|
324
|
+
ninja-p2p task --id planner worker "Implement the parser fix and add regression tests"
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
Review and second opinion:
|
|
328
|
+
|
|
329
|
+
```bash
|
|
330
|
+
ninja-p2p review --id planner reviewer "Review GitHub PR #42 parser changes for regressions"
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
Approval gate:
|
|
334
|
+
|
|
335
|
+
```bash
|
|
336
|
+
ninja-p2p approve --id planner reviewer "Approve this plan before implementation continues"
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
When the peer answers, reply with the original request id:
|
|
340
|
+
|
|
341
|
+
```bash
|
|
342
|
+
ninja-p2p respond --id reviewer planner <requestId> '{"approved":true,"note":"Plan looks safe"}'
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
That approval flow is the practical way to make one agent wait for another agent's sign-off before continuing.
|
|
346
|
+
|
|
347
|
+
### Codex CLI
|
|
39
348
|
|
|
40
|
-
|
|
41
|
-
- `ws` comes from `@vdoninja/sdk` in Node.
|
|
42
|
-
- `@roamhq/wrtc` is recommended for Node bots that need WebRTC support.
|
|
349
|
+
Install the CLI:
|
|
43
350
|
|
|
44
|
-
|
|
351
|
+
```bash
|
|
352
|
+
npm install -g @vdoninja/ninja-p2p @roamhq/wrtc
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
Optional: install the bundled Codex skill into your user profile:
|
|
356
|
+
|
|
357
|
+
```bash
|
|
358
|
+
ninja-p2p install-skill codex
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
That copies the skill to `~/.codex/skills/ninja-p2p` on macOS/Linux or `%USERPROFILE%\.codex\skills\ninja-p2p` on Windows. A compatibility copy is also written to `.agents/skills/ninja-p2p`.
|
|
362
|
+
|
|
363
|
+
In Codex, this is not a slash command. Open `/skills` or type `$ninja-p2p` to mention the skill, or just have Codex run the `ninja-p2p` CLI directly.
|
|
364
|
+
|
|
365
|
+
### Claude Code
|
|
366
|
+
|
|
367
|
+
Install the CLI:
|
|
368
|
+
|
|
369
|
+
```bash
|
|
370
|
+
npm install -g @vdoninja/ninja-p2p @roamhq/wrtc
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
Optional: install the bundled Claude skill into your user profile:
|
|
374
|
+
|
|
375
|
+
```bash
|
|
376
|
+
ninja-p2p install-skill claude
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
That copies the skill to `~/.claude/skills/ninja-p2p`.
|
|
45
380
|
|
|
46
|
-
|
|
381
|
+
In Claude Code, the skill becomes a slash command:
|
|
382
|
+
|
|
383
|
+
```text
|
|
384
|
+
/ninja-p2p notify
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
Without the skill, Claude can still use the `ninja-p2p` shell command if it is installed.
|
|
388
|
+
|
|
389
|
+
## MCP
|
|
390
|
+
|
|
391
|
+
`ninja-p2p` does not expose an MCP server today.
|
|
392
|
+
|
|
393
|
+
If you want MCP, treat it as a separate layer:
|
|
394
|
+
|
|
395
|
+
- Codex adds MCP servers with `codex mcp add ...`
|
|
396
|
+
- Claude Code adds MCP servers with `claude mcp add ...`
|
|
397
|
+
|
|
398
|
+
This package is a CLI and library, not an MCP endpoint.
|
|
399
|
+
|
|
400
|
+
## Testing From This Repo
|
|
401
|
+
|
|
402
|
+
If you are testing from a local clone, do not rely on `npm link` unless your global npm bin is already on `PATH`.
|
|
403
|
+
|
|
404
|
+
Use the built file directly:
|
|
47
405
|
|
|
48
406
|
### PowerShell
|
|
49
407
|
|
|
50
408
|
```powershell
|
|
51
|
-
|
|
409
|
+
cd C:\Users\steve\Code\ninja-p2p
|
|
410
|
+
npm install
|
|
411
|
+
npm run build
|
|
412
|
+
node .\dist\cli.js help
|
|
52
413
|
```
|
|
53
414
|
|
|
54
415
|
### Bash
|
|
55
416
|
|
|
56
417
|
```bash
|
|
57
|
-
|
|
418
|
+
cd ~/Code/ninja-p2p
|
|
419
|
+
npm install
|
|
420
|
+
npm run build
|
|
421
|
+
node ./dist/cli.js help
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
Local sidecar test:
|
|
425
|
+
|
|
426
|
+
```bash
|
|
427
|
+
node ./dist/cli.js start --room ai-test --name Codex --id codex
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
Then in another terminal:
|
|
431
|
+
|
|
432
|
+
```bash
|
|
433
|
+
node ./dist/cli.js status --id codex
|
|
434
|
+
node ./dist/cli.js notify --id codex
|
|
435
|
+
node ./dist/cli.js read --id codex --take 10
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
Live room validation:
|
|
439
|
+
|
|
440
|
+
```bash
|
|
441
|
+
npm run validate:live
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
That script starts a planner, worker, reviewer, and operator sidecar, waits for full peer discovery, exercises plan/task/review/approve/respond/event flows, and fails if the room does not converge.
|
|
445
|
+
|
|
446
|
+
## CLI
|
|
447
|
+
|
|
448
|
+
Interactive room session:
|
|
449
|
+
|
|
450
|
+
```bash
|
|
451
|
+
ninja-p2p connect --room my-room --name Claude --id claude
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
One-shot room message:
|
|
455
|
+
|
|
456
|
+
```bash
|
|
457
|
+
ninja-p2p chat --room my-room --name Steve --id steve "hello"
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
One-shot direct message:
|
|
461
|
+
|
|
462
|
+
```bash
|
|
463
|
+
ninja-p2p dm --room my-room --name Steve --id steve claude "hello"
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
One-shot command:
|
|
467
|
+
|
|
468
|
+
```bash
|
|
469
|
+
ninja-p2p command --room my-room --name Steve --id steve claude status
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
Minimal persistent sidecar:
|
|
473
|
+
|
|
474
|
+
```bash
|
|
475
|
+
ninja-p2p start --id codex
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
Persistent sidecar with optional discovery metadata:
|
|
479
|
+
|
|
480
|
+
```bash
|
|
481
|
+
ninja-p2p start --room ai-room --name Codex --id codex --runtime codex-cli --provider openai --model gpt-5 --can review,tests
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
Sidecar status:
|
|
485
|
+
|
|
486
|
+
```bash
|
|
487
|
+
ninja-p2p status --id codex
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
Inbox summary:
|
|
491
|
+
|
|
492
|
+
```bash
|
|
493
|
+
ninja-p2p notify --id codex
|
|
58
494
|
```
|
|
59
495
|
|
|
60
|
-
|
|
496
|
+
Read pending messages:
|
|
497
|
+
|
|
498
|
+
```bash
|
|
499
|
+
ninja-p2p read --id codex --take 10
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
Queue a direct message through the running sidecar:
|
|
503
|
+
|
|
504
|
+
```bash
|
|
505
|
+
ninja-p2p dm --id codex human "working on it"
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
Queue a file or image through the running sidecar:
|
|
509
|
+
|
|
510
|
+
```bash
|
|
511
|
+
ninja-p2p send-file --id codex reviewer ./notes.txt
|
|
512
|
+
ninja-p2p send-image --id codex reviewer ./diagram.png
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
List and pull from a shared folder:
|
|
516
|
+
|
|
517
|
+
```bash
|
|
518
|
+
ninja-p2p shares --id codex worker
|
|
519
|
+
ninja-p2p list-files --id codex worker docs
|
|
520
|
+
ninja-p2p get-file --id codex worker docs guide.md
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
Ask another sidecar what it can do:
|
|
524
|
+
|
|
525
|
+
```bash
|
|
526
|
+
ninja-p2p command --id codex claude capabilities
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
Ask for a plan, review, or approval:
|
|
530
|
+
|
|
531
|
+
```bash
|
|
532
|
+
ninja-p2p plan --id codex planner "Suggest a safe rollout"
|
|
533
|
+
ninja-p2p review --id codex reviewer "Review PR #42"
|
|
534
|
+
ninja-p2p approve --id codex reviewer "Approve this plan"
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
Reply to a request with a structured result:
|
|
538
|
+
|
|
539
|
+
```bash
|
|
540
|
+
ninja-p2p respond --id codex planner <requestId> '{"approved":true}'
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
Stop the sidecar:
|
|
544
|
+
|
|
545
|
+
```bash
|
|
546
|
+
ninja-p2p stop --id codex
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
Install the optional skills:
|
|
550
|
+
|
|
551
|
+
```bash
|
|
552
|
+
ninja-p2p install-skill codex
|
|
553
|
+
ninja-p2p install-skill claude
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
Useful env vars:
|
|
557
|
+
|
|
558
|
+
- `NINJA_ROOM`
|
|
559
|
+
- `NINJA_NAME`
|
|
560
|
+
- `NINJA_ID`
|
|
561
|
+
- `NINJA_ROLE`
|
|
562
|
+
- `NINJA_PASSWORD`
|
|
563
|
+
- `NINJA_STATE_DIR`
|
|
564
|
+
|
|
565
|
+
## Install As A Library
|
|
566
|
+
|
|
567
|
+
```bash
|
|
568
|
+
npm install @vdoninja/ninja-p2p @roamhq/wrtc
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
Notes:
|
|
572
|
+
|
|
573
|
+
- `@vdoninja/sdk` is installed automatically
|
|
574
|
+
- `ws` comes from `@vdoninja/sdk` in Node
|
|
575
|
+
- `@roamhq/wrtc` is recommended for Node bots that need WebRTC support
|
|
576
|
+
|
|
577
|
+
## Library Quick Start
|
|
61
578
|
|
|
62
579
|
```ts
|
|
63
580
|
import { VDOBridge } from "@vdoninja/ninja-p2p";
|
|
@@ -162,7 +679,25 @@ The browser dashboard can also join the same room:
|
|
|
162
679
|
dashboard.html?room=agents_room&password=false&name=Steve&autoconnect=true
|
|
163
680
|
```
|
|
164
681
|
|
|
165
|
-
|
|
682
|
+
For GitHub Pages, the same static UI can live at:
|
|
683
|
+
|
|
684
|
+
```text
|
|
685
|
+
docs/index.html?room=agents_room&password=false&name=Steve&autoconnect=true
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
That browser UI can:
|
|
689
|
+
|
|
690
|
+
- enter a room and optional password
|
|
691
|
+
- see connected bots and operators
|
|
692
|
+
- select a peer and DM it directly
|
|
693
|
+
- broadcast to the whole room
|
|
694
|
+
- inspect the selected peer's announced profile, capabilities, asks, and shared folders
|
|
695
|
+
- browse a selected peer's declared shared folders and request one file at a time
|
|
696
|
+
- download files that arrive over the room connection
|
|
697
|
+
- send slash-style commands like `/profile`, `/capabilities`, `/inbox`, `/status`, `/history`, `/peers`, `/shares`, `/ls <peer> <share> [path]`, `/get <peer> <share> <path>`, and `/cmd <peer> <command> [json]`
|
|
698
|
+
- send operator-friendly shortcuts like `/plan`, `/review`, `/approve`, and `/respond`
|
|
699
|
+
|
|
700
|
+
One honest caveat: GitHub Pages is just a static host. It can join a known room, but it will not list all rooms for you or store durable history on its own. Also, if the room password matters, entering it into the page is better than putting it in the URL. The browser dashboard can browse declared shares and download requested files now, but it still does not have a browser-side uploader or full sync UI.
|
|
166
701
|
|
|
167
702
|
## Coordination Helpers
|
|
168
703
|
|
|
@@ -177,20 +712,20 @@ The dashboard can chat, DM a peer, and send simple slash-command messages like `
|
|
|
177
712
|
|
|
178
713
|
These are lightweight coordination messages. They are useful, but they are not hard delivery guarantees.
|
|
179
714
|
|
|
180
|
-
## Raw Data, Media,
|
|
715
|
+
## Raw Data, Media, And Advanced SDK Access
|
|
181
716
|
|
|
182
717
|
This package focuses on data-channel messaging.
|
|
183
718
|
|
|
184
|
-
The underlying VDO.Ninja SDK
|
|
719
|
+
The underlying VDO.Ninja SDK can also:
|
|
185
720
|
|
|
186
|
-
- publish and view audio
|
|
721
|
+
- publish and view audio or video tracks
|
|
187
722
|
- emit `track` events
|
|
188
723
|
- send binary payloads over the data channel
|
|
189
724
|
|
|
190
725
|
This wrapper exposes two escape hatches for that:
|
|
191
726
|
|
|
192
|
-
- `bridge.sendRaw(data, targetStreamId?)`
|
|
193
|
-
- `bridge.getSDK()`
|
|
727
|
+
- `bridge.sendRaw(data, targetStreamId?)`
|
|
728
|
+
- `bridge.getSDK()`
|
|
194
729
|
|
|
195
730
|
Example:
|
|
196
731
|
|
|
@@ -206,22 +741,9 @@ const chunk = new Uint8Array([1, 2, 3]).buffer;
|
|
|
206
741
|
bridge.sendRaw(chunk, "worker_bot");
|
|
207
742
|
```
|
|
208
743
|
|
|
209
|
-
|
|
744
|
+
This package already exposes basic file and image transfer at the CLI level with `send-file` and `send-image`.
|
|
210
745
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
Main entrypoint:
|
|
214
|
-
|
|
215
|
-
```ts
|
|
216
|
-
import { VDOBridge, MessageBus, PeerRegistry } from "@vdoninja/ninja-p2p";
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
Subpath entrypoints:
|
|
220
|
-
|
|
221
|
-
```ts
|
|
222
|
-
import { VDOBridge } from "@vdoninja/ninja-p2p/vdo-bridge";
|
|
223
|
-
import { createEnvelope } from "@vdoninja/ninja-p2p/protocol";
|
|
224
|
-
```
|
|
746
|
+
If you want to turn video into frames for ingestion, stream media between bots, or build a richer binary protocol on top of the data channel, do it on top of the SDK or `sendRaw`. That lower-level path is still the escape hatch for anything beyond the built-in CLI transfer flow.
|
|
225
747
|
|
|
226
748
|
## Files
|
|
227
749
|
|
|
@@ -229,8 +751,11 @@ import { createEnvelope } from "@vdoninja/ninja-p2p/protocol";
|
|
|
229
751
|
- `src/message-bus.ts`: chat, direct messages, topics, history, offline queue
|
|
230
752
|
- `src/peer-registry.ts`: peer state and presence
|
|
231
753
|
- `src/protocol.ts`: message envelope format
|
|
232
|
-
- `
|
|
233
|
-
- `
|
|
754
|
+
- `src/agent-state.ts`: local inbox, outbox, and sidecar state
|
|
755
|
+
- `dashboard.html`: browser monitor and chat client
|
|
756
|
+
- `.codex/skills/ninja-p2p`: optional Codex skill
|
|
757
|
+
- `.agents/skills/ninja-p2p`: Codex compatibility copy for older layouts
|
|
758
|
+
- `.claude/skills/ninja-p2p`: optional Claude Code skill
|
|
234
759
|
|
|
235
760
|
## Tests
|
|
236
761
|
|