@weaveprotocol/cli 0.1.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 +156 -0
- package/dist/weave.mjs +11528 -0
- package/package.json +39 -0
package/README.md
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# weave — the protocol from a terminal
|
|
2
|
+
|
|
3
|
+
One program, three jobs:
|
|
4
|
+
|
|
5
|
+
- **Manage your spaces** — every command the Node API has, as `weave spaces …` and `weave records …`
|
|
6
|
+
- **Run an always-on node** — `weave run` keeps every space syncing, serves sockets browsers dial into, and is a relay too
|
|
7
|
+
- **Connect an agent** — `weave connect <code>`, then Claude Code, Claude Desktop or Cursor starts `weave mcp` by itself
|
|
8
|
+
|
|
9
|
+
It uses the same data folder layout a browser does. Point `--home` at the folder
|
|
10
|
+
you picked in Chrome and the CLI, the daemon and the browser all share one
|
|
11
|
+
account.
|
|
12
|
+
|
|
13
|
+
## Quick start
|
|
14
|
+
|
|
15
|
+
In this repo, `npm run dev` (at the root) already runs a node with a throwaway
|
|
16
|
+
identity, and `npm run weave -- <command>` talks to it — no setup.
|
|
17
|
+
|
|
18
|
+
To make the dev node *your* account's node — so it serves every list you make
|
|
19
|
+
in the browser, with nothing to hand it — give it your account password once:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
rm -rf .weave-dev # drop the throwaway identity
|
|
23
|
+
WEAVE_RECOVERY_CODE='XXXX-…' npm run weave -- init --existing --passphrase --name Me
|
|
24
|
+
npm run dev
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
To have `weave` everywhere:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm install -g @weaveprotocol/cli # or run it without installing: npx @weaveprotocol/cli <command>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
From this repo: `cd cli && npm install && npm run bundle && npm link`, or a
|
|
34
|
+
binary with no Node at all: `bun build.ts --native`.
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
weave init --name Leif --passphrase # prints your recovery code once
|
|
38
|
+
export WEAVE_PASSPHRASE='…' # so later commands don't ask
|
|
39
|
+
|
|
40
|
+
weave spaces create --name Groceries --visibility private --roles team
|
|
41
|
+
weave records put --space <id> --collection app.todo.item --body '{"text":"milk","completed":false,"order":1}'
|
|
42
|
+
weave records list --space <id>
|
|
43
|
+
weave spaces invite --space <id> # a secret: it carries the space key and the write key
|
|
44
|
+
weave spaces invite --space <id> --view-only # they can read it, not change it
|
|
45
|
+
weave spaces join --invite 'https://…#invite=…'
|
|
46
|
+
weave run # stay up and serve; --create makes an account on first start
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Every data command is an action from `NODE_ACTIONS`: `weave records put` runs
|
|
50
|
+
`records_put`, and its flags are that action's input fields. `weave actions`
|
|
51
|
+
prints them all with their schemas. `--json '{…}'` passes an input whole.
|
|
52
|
+
|
|
53
|
+
## Unlocking
|
|
54
|
+
|
|
55
|
+
Secrets never go on the command line, where `ps` shows them:
|
|
56
|
+
|
|
57
|
+
| | |
|
|
58
|
+
|---|---|
|
|
59
|
+
| `WEAVE_RECOVERY_CODE` or `--code-file FILE` | the account's recovery code |
|
|
60
|
+
| `WEAVE_PASSPHRASE` or `--passphrase-file FILE` | a passphrase added with `init --passphrase` |
|
|
61
|
+
| neither | you are asked, without echo |
|
|
62
|
+
|
|
63
|
+
Nothing ever writes the seed in the clear: the account file holds only wrapped
|
|
64
|
+
copies, exactly as in a browser folder.
|
|
65
|
+
|
|
66
|
+
## The always-on node
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
weave run --port 8787
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
- `ws://host:8787/peer?space=<id>` — the protocol's WebSocket transport. Browsers
|
|
73
|
+
reach it with `network: { nodes: ['wss://host/peer'] }` (the example app reads
|
|
74
|
+
`VITE_WEAVE_NODES`). No relay, no TURN.
|
|
75
|
+
- `ws://host:8787?room=<id>` — the signaling relay, so one process bootstraps a space.
|
|
76
|
+
- `GET /health` — `{"ok":true}`, nothing more
|
|
77
|
+
|
|
78
|
+
It listens on this machine only (`127.0.0.1`). On a server, put it behind
|
|
79
|
+
whatever terminates TLS — browsers need `wss://` anyway — or pass
|
|
80
|
+
`--host 0.0.0.0` to listen on every interface.
|
|
81
|
+
|
|
82
|
+
It opens every space the account holds and notices new ones within five
|
|
83
|
+
seconds, whoever added them: `weave spaces join` in another terminal, a browser
|
|
84
|
+
pointed at the same folder, a pairing. It validates everything with the same
|
|
85
|
+
gates as any peer. It is an **anchor, not a host** — uptime, no authority.
|
|
86
|
+
|
|
87
|
+
For a server, `bun build.ts` makes single-file binaries for this machine,
|
|
88
|
+
`linux-x64` and `linux-arm64`; `weave-node.service` is a systemd unit.
|
|
89
|
+
|
|
90
|
+
## Agents
|
|
91
|
+
|
|
92
|
+
In an app, choose **Connect an agent** in the account menu. It shows one
|
|
93
|
+
command:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
npx @weaveprotocol/cli connect wv_… # in this repo: npm run weave -- connect wv_…
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
It makes a key for this computer's agent (it never leaves `~/.weave/agent/`),
|
|
100
|
+
finds the app through the relay, and waits while you allow it at your account
|
|
101
|
+
home, which signs an agent's note for your whole account, for as long as you
|
|
102
|
+
chose. Then it adds `weave` to Claude Code (`claude mcp add`), Claude Desktop
|
|
103
|
+
and Cursor, where it finds them. `--no-configure` prints the config instead,
|
|
104
|
+
`--name` changes what you see ("Agent on leifs-macbook"), and `--relay` adds
|
|
105
|
+
one the app uses (`$WEAVE_RELAYS` sets the defaults).
|
|
106
|
+
|
|
107
|
+
From then on the agent starts `weave mcp` itself. It's a node of its own: it
|
|
108
|
+
follows your account's list of spaces, meets your other devices over WebRTC,
|
|
109
|
+
and keeps working with every tab closed. What it writes shows "via agent". It
|
|
110
|
+
isn't offered what needs a person (making, joining or leaving spaces, invites,
|
|
111
|
+
roles, defining collections): it proposes apps with `apps_propose`, and you add
|
|
112
|
+
them. `weave disconnect` forgets it on this computer; disconnecting it in your
|
|
113
|
+
account home stops its note working everywhere.
|
|
114
|
+
|
|
115
|
+
`weave mcp --account` serves the unlocked account instead, as you:
|
|
116
|
+
|
|
117
|
+
```json
|
|
118
|
+
{ "mcpServers": { "weave": { "command": "weave", "args": ["mcp", "--account"], "env": { "WEAVE_PASSPHRASE": "…" } } } }
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
It works offline against the folder; with `weave run` on the same folder,
|
|
122
|
+
whatever the agent writes is synced within seconds.
|
|
123
|
+
|
|
124
|
+
## Who gets served
|
|
125
|
+
|
|
126
|
+
Every peer first proves the DID it gives is its own: the node sends a random
|
|
127
|
+
challenge, and the client signs it with the key that DID names. So nobody can
|
|
128
|
+
connect under someone else's name and knock them off the node.
|
|
129
|
+
|
|
130
|
+
For a **private** space, the client also proves it may read before anything
|
|
131
|
+
moves: it signs the same challenge with the space's read key, which comes from
|
|
132
|
+
the space key. The node checks that against the
|
|
133
|
+
public read key the space names, so it needs no secret of the space's to do it.
|
|
134
|
+
The node then signs the client's challenge with its own key, so the client
|
|
135
|
+
knows the welcome comes from the node that sent the challenge. A stranger who
|
|
136
|
+
knows the space id gets a challenge and a closed socket, never the ciphertext —
|
|
137
|
+
the same answer as for a space the node does not hold, so a web page cannot ask
|
|
138
|
+
your node which spaces you have.
|
|
139
|
+
A **public** space is served to anyone, as its data is public anyway.
|
|
140
|
+
|
|
141
|
+
Writing is checked separately, record by record: its author must hold a role in
|
|
142
|
+
the space, as of the access history the record says it saw, and the node
|
|
143
|
+
refuses any that doesn't, as every peer does. Roles and members are kept in the
|
|
144
|
+
clear, so a node holding no key of a private space still judges its writes.
|
|
145
|
+
|
|
146
|
+
## Your node follows your account
|
|
147
|
+
|
|
148
|
+
Run the node as *your* account (`weave init --existing` with your recovery code)
|
|
149
|
+
and it follows the account registry: every space you create or join, on any
|
|
150
|
+
device, is served by the node within moments — no invites to hand it. Leaving a
|
|
151
|
+
space anywhere leaves it everywhere.
|
|
152
|
+
|
|
153
|
+
## Not yet
|
|
154
|
+
|
|
155
|
+
- **WebRTC on the node.** Browsers reach it over WebSocket. `node-datachannel`
|
|
156
|
+
plugs into the same transport seam if measurement says it is needed.
|