@nervur-org/dock 0.3.0 → 0.4.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/GETTING_STARTED.md +22 -12
- package/{beings/GLOSSARY.md → GLOSSARY.md} +3 -3
- package/NOTICE +1 -1
- package/README.md +20 -16
- package/{beings/WORLDS.md → WORLDS.md} +6 -4
- package/api/route.ts +3 -3
- package/beings/avatar.ts +2 -2
- package/beings/carry.ts +2 -2
- package/beings/clock.ts +2 -2
- package/beings/courier.ts +2 -2
- package/beings/desk.ts +2 -2
- package/beings/doorbell.ts +2 -2
- package/beings/envoy.ts +2 -2
- package/beings/join.ts +2 -2
- package/beings/link.ts +5 -5
- package/beings/look.ts +1 -1
- package/beings/porter.ts +2 -2
- package/beings/presence.ts +1 -1
- package/beings/setup.ts +3 -3
- package/beings/side.ts +2 -2
- package/beings/user.ts +2 -2
- package/beings/way.ts +1 -1
- package/cli/client.ts +6 -6
- package/cli/daemon.ts +7 -7
- package/cli/estate/{quo.service → nervur.service} +12 -12
- package/cli/estate/org.nervur.plist +44 -0
- package/cli/estate.ts +6 -6
- package/cli/{quo.ts → nervur.ts} +43 -37
- package/cli/pilot.ts +3 -3
- package/cli/stand.ts +3 -3
- package/dist/api/route.d.ts +2 -2
- package/dist/api/route.js +2 -2
- package/dist/beings/avatar.d.ts +1 -1
- package/dist/beings/avatar.js +1 -1
- package/dist/beings/carry.d.ts +2 -2
- package/dist/beings/carry.js +1 -1
- package/dist/beings/clock.d.ts +2 -2
- package/dist/beings/clock.js +1 -1
- package/dist/beings/courier.d.ts +2 -2
- package/dist/beings/courier.js +1 -1
- package/dist/beings/desk.d.ts +3 -3
- package/dist/beings/desk.js +1 -1
- package/dist/beings/doorbell.d.ts +3 -3
- package/dist/beings/doorbell.js +1 -1
- package/dist/beings/envoy.d.ts +2 -2
- package/dist/beings/envoy.js +1 -1
- package/dist/beings/join.d.ts +2 -2
- package/dist/beings/link.d.ts +2 -2
- package/dist/beings/link.js +3 -3
- package/dist/beings/look.d.ts +1 -1
- package/dist/beings/porter.d.ts +2 -2
- package/dist/beings/porter.js +1 -1
- package/dist/beings/presence.d.ts +1 -1
- package/dist/beings/setup.d.ts +1 -1
- package/dist/beings/side.d.ts +1 -1
- package/dist/beings/side.js +1 -1
- package/dist/beings/user.d.ts +3 -3
- package/dist/beings/user.js +1 -1
- package/dist/beings/way.d.ts +1 -1
- package/dist/cli/client.js +4 -4
- package/dist/cli/daemon.d.ts +1 -1
- package/dist/cli/daemon.js +6 -6
- package/dist/cli/estate/{quo.service → nervur.service} +12 -12
- package/dist/cli/estate/org.nervur.plist +44 -0
- package/dist/cli/estate.js +6 -6
- package/dist/cli/{quo.js → nervur.js} +43 -37
- package/dist/cli/stand.d.ts +2 -2
- package/dist/dock/agents.d.ts +1 -1
- package/dist/dock/agents.js +1 -1
- package/dist/dock/apns.js +1 -1
- package/dist/dock/console.d.ts +1 -1
- package/dist/dock/dialers.d.ts +2 -2
- package/dist/dock/dialers.js +2 -2
- package/dist/dock/faculty.d.ts +2 -2
- package/dist/dock/faculty.js +1 -1
- package/dist/dock/grants.d.ts +1 -1
- package/dist/dock/grants.js +1 -1
- package/dist/dock/http2.js +1 -1
- package/dist/dock/index.d.ts +1 -1
- package/dist/dock/index.js +1 -1
- package/dist/dock/local.d.ts +2 -2
- package/dist/dock/location.d.ts +1 -1
- package/dist/dock/notifications.d.ts +1 -1
- package/dist/dock/notifications.js +1 -1
- package/dist/dock/push.d.ts +1 -1
- package/dist/dock/push.js +3 -3
- package/dist/dock/service.js +1 -1
- package/dist/dock/timer.d.ts +1 -1
- package/dist/harbor/browser.d.ts +2 -2
- package/dist/harbor/browser.js +4 -4
- package/dist/harbor/capacitor.d.ts +1 -1
- package/dist/harbor/capacitor.js +1 -1
- package/dist/harbor/disk.d.ts +4 -4
- package/dist/harbor/disk.js +5 -5
- package/dist/harbor/edge/edge.d.ts +2 -2
- package/dist/harbor/edge/edge.js +5 -5
- package/dist/harbor/edge/exercise.js +8 -8
- package/dist/harbor/edge/given.d.ts +1 -1
- package/dist/harbor/edge/platform.d.ts +1 -1
- package/dist/harbor/edge/storage.d.ts +1 -1
- package/dist/harbor/edge/storage.js +2 -2
- package/dist/harbor/edge/worker.js +2 -2
- package/dist/harbor/files.d.ts +1 -1
- package/dist/harbor/files.js +2 -2
- package/dist/harbor/http.d.ts +2 -2
- package/dist/harbor/http.js +1 -1
- package/dist/harbor/idb.d.ts +1 -1
- package/dist/harbor/idb.js +0 -0
- package/dist/harbor/quo.js +1 -1
- package/dist/harbor/seal.js +1 -1
- package/dist/harbor/sealed.d.ts +1 -1
- package/dist/harbor/sealed.js +4 -4
- package/dist/harbor/tauri.d.ts +1 -1
- package/dist/harbor/tauri.js +1 -1
- package/dist/harbor/ward.d.ts +1 -1
- package/dist/human/app.d.ts +2 -2
- package/dist/human/door.js +4 -4
- package/dist/human/guest.js +1 -1
- package/dist/human/html.d.ts +1 -1
- package/dist/human/html.js +1 -1
- package/dist/human/local.d.ts +1 -1
- package/dist/human/mark.js +2 -2
- package/dist/human/move.d.ts +2 -2
- package/dist/human/move.js +1 -1
- package/dist/human/screen.d.ts +1 -1
- package/dist/human/screen.js +3 -3
- package/dist/human/tab.bundle.txt +32 -32
- package/dist/human/tab.js +7 -7
- package/dist/human/tree.d.ts +1 -1
- package/dist/human/wake.d.ts +2 -2
- package/dist/human/wake.js +1 -1
- package/dist/human/web.d.ts +1 -1
- package/dist/human/web.js +4 -4
- package/dist/human/worker.bundle.txt +27 -27
- package/dist/human/worker.js +4 -4
- package/dist/human/worlds.d.ts +2 -2
- package/dist/human/worlds.js +4 -4
- package/dist/mcp/agent.d.ts +1 -1
- package/dist/mcp/allow.d.ts +1 -1
- package/dist/mcp/allow.js +2 -2
- package/dist/mcp/oauth.js +1 -1
- package/dist/mcp/runner.d.ts +1 -1
- package/dist/mcp/server.d.ts +2 -2
- package/dist/mcp/server.js +2 -2
- package/dock/agents.ts +2 -2
- package/dock/apns.ts +1 -1
- package/dock/console.ts +1 -1
- package/dock/dialers.ts +3 -3
- package/dock/faculty.ts +2 -2
- package/dock/grants.ts +2 -2
- package/dock/http2.ts +1 -1
- package/dock/index.ts +3 -3
- package/dock/local.ts +1 -1
- package/dock/location.ts +1 -1
- package/dock/notifications.ts +2 -2
- package/dock/push.ts +4 -4
- package/dock/service.ts +1 -1
- package/dock/timer.ts +1 -1
- package/harbor/browser.ts +5 -5
- package/harbor/capacitor.ts +2 -2
- package/harbor/disk.ts +8 -8
- package/harbor/edge/edge.ts +7 -7
- package/harbor/edge/exercise.ts +11 -11
- package/harbor/edge/given.ts +1 -1
- package/harbor/edge/platform.d.ts +1 -1
- package/harbor/edge/storage.ts +2 -2
- package/harbor/edge/worker.ts +2 -2
- package/harbor/edge/wrangler.toml +3 -3
- package/harbor/files.ts +2 -2
- package/harbor/http.ts +2 -2
- package/harbor/idb.ts +0 -0
- package/harbor/quo.ts +1 -1
- package/harbor/resolve.ts +1 -1
- package/harbor/seal.ts +1 -1
- package/harbor/sealed.ts +5 -5
- package/harbor/tauri.ts +2 -2
- package/harbor/ward.ts +1 -1
- package/human/app.ts +2 -2
- package/human/apps.ts +1 -1
- package/human/door.ts +4 -4
- package/human/guest.ts +2 -2
- package/human/html.ts +2 -2
- package/human/local.ts +1 -1
- package/human/mark.ts +2 -2
- package/human/move.ts +3 -3
- package/human/screen.ts +5 -5
- package/human/tab.bundle.txt +32 -32
- package/human/tab.ts +10 -10
- package/human/tree.ts +1 -1
- package/human/wake.ts +3 -3
- package/human/web.ts +5 -5
- package/human/worker.bundle.txt +27 -27
- package/human/worker.ts +6 -6
- package/human/worlds.ts +5 -5
- package/mcp/agent.ts +1 -1
- package/mcp/allow.ts +5 -5
- package/mcp/oauth.ts +1 -1
- package/mcp/runner.ts +1 -1
- package/mcp/server.ts +3 -3
- package/package.json +15 -7
- package/{api/quo-api.md → quo-api.md} +1 -1
- package/{beings/quo-dock.md → quo-dock.md} +74 -71
- package/{harbor/quo-harbor.md → quo-harbor.md} +54 -30
- package/{human/quo-human.md → quo-human.md} +7 -7
- package/{mcp/quo-mcp.md → quo-mcp.md} +10 -10
- package/cli/estate/systems.quo.plist +0 -44
- package/cli/quo-dock.md +0 -1942
- package/dist/cli/estate/systems.quo.plist +0 -44
- package/dock/quo-app-bells.md +0 -280
- package/dock/quo-dock.md +0 -1942
- /package/dist/cli/{quo.d.ts → nervur.d.ts} +0 -0
- /package/{beings/quo-app-bells.md → quo-app-bells.md} +0 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
This is the trunk of the dock: what every estate on Quo needs and nobody writes
|
|
4
4
|
twice. `quo/SPEC.md` is the protocol and knows nothing of this folder, and
|
|
5
|
-
`papers/quo-kit.md` is what the library under `packages/
|
|
5
|
+
`papers/quo-kit.md` is what the library under `packages/nervur/src` chose; the
|
|
6
6
|
five documents under `packages/dock/` are the truth of their folders in the
|
|
7
7
|
same way, and where any of them disagrees with `quo/SPEC.md`, the spec wins
|
|
8
8
|
and the document is rewritten. Nothing
|
|
@@ -16,11 +16,11 @@ does not run. `papers/GLOSSARY.md` holds every word of both.
|
|
|
16
16
|
|
|
17
17
|
Three layers, one repository, and the words for them:
|
|
18
18
|
|
|
19
|
-
| layer | folder
|
|
20
|
-
| --------- |
|
|
21
|
-
| Quo | `packages/
|
|
22
|
-
| the dock | `packages/dock/`
|
|
23
|
-
| an estate | the owner's own
|
|
19
|
+
| layer | folder | package | published |
|
|
20
|
+
| --------- | ------------------ | ------------------ | --------------- |
|
|
21
|
+
| Quo | `packages/nervur/` | `nervur` | yes, Apache 2.0 |
|
|
22
|
+
| the dock | `packages/dock/` | `@nervur-org/dock` | yes, Apache 2.0 |
|
|
23
|
+
| an estate | the owner's own | none | never |
|
|
24
24
|
|
|
25
25
|
**An estate is all of one owner's harbors.** The droplet, the edge and the
|
|
26
26
|
Mac, with the desk, the user being and the avatars living across them: that
|
|
@@ -32,7 +32,7 @@ taken here, exactly as owning anyone else's would be. What makes them one
|
|
|
32
32
|
estate is who holds those standings, not a key any two of them share. A second
|
|
33
33
|
domain is a second estate. An adopter's company is an estate in their own
|
|
34
34
|
repository, and it looks exactly like ours. An estate folder is one folder
|
|
35
|
-
per harbor, each the
|
|
35
|
+
per harbor, each the harbor directory that device runs minus what it mints,
|
|
36
36
|
its class bodies, its routes, its agents, its dial list, plus that device's
|
|
37
37
|
unit; a package file that depends on the dock and nothing else; secrets by
|
|
38
38
|
reference; and one document. Nothing else may be needed to run it, and the
|
|
@@ -41,7 +41,7 @@ one install of the dock, boots. If it does not, the missing piece belongs
|
|
|
41
41
|
in the dock.
|
|
42
42
|
|
|
43
43
|
**The dock is what a harbor is fitted with to receive people and models**:
|
|
44
|
-
the daemon and the `
|
|
44
|
+
the daemon and the `nervur` command, the front desk, the user being and the
|
|
45
45
|
avatar, the harbors on real terrains, the model sides and the screen, the
|
|
46
46
|
credential exchange, and the faculties of the dock ward, one being per
|
|
47
47
|
thing a box can do. It is general by two rules, under
|
|
@@ -60,7 +60,7 @@ The five documents of the dock, and the folders each answers for:
|
|
|
60
60
|
|
|
61
61
|
Five documents and seven folders, because the trunk answers for three: the
|
|
62
62
|
beings every side shares, the dock ward that holds a box's faculties, and
|
|
63
|
-
the daemon and the `
|
|
63
|
+
the daemon and the `nervur` command that stand a device up. Each document
|
|
64
64
|
decides only its own folders, and names another side's word only to say
|
|
65
65
|
where the boundary runs: the human document decides no transport, the model
|
|
66
66
|
document decides no screen, the harbor document decides nothing about what
|
|
@@ -70,17 +70,17 @@ a being is. Anything two sides need is decided here.
|
|
|
70
70
|
|
|
71
71
|
An adopter alone with this paper stands a box and puts a phone in a world
|
|
72
72
|
in six commands. The dock installs from npm and brings the library with
|
|
73
|
-
it; `
|
|
73
|
+
it; `nervur` is its one command, run as `npx nervur` in the folder it was
|
|
74
74
|
installed in, and every command takes `--dir` for the harbor folder, or
|
|
75
|
-
reads `
|
|
75
|
+
reads `NERVUR_DIR`, or takes `~/.nervur`.
|
|
76
76
|
|
|
77
77
|
```bash
|
|
78
78
|
npm install @nervur-org/dock
|
|
79
|
-
npx
|
|
80
|
-
npx
|
|
79
|
+
npx nervur init --dir ~/.nervur --ward acme --user razvan --domain acme.com --default --show
|
|
80
|
+
npx nervur serve --dir ~/.nervur --http 8787
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
-
`init` mints the ward `acme` at `~/.
|
|
83
|
+
`init` mints the ward `acme` at `~/.nervur/wards/acme/`, boots razvan's user
|
|
84
84
|
being, her doorbell and the desk in it, marks it the default ward, the one
|
|
85
85
|
a caller means when naming none, shows it at the web route, and writes
|
|
86
86
|
`routes.json`: the four routes `mcp.`, `web.`, `quo.` and `api.` under the
|
|
@@ -105,8 +105,8 @@ it hosts, and one of them is `dock`, the box's own, which it boots and no
|
|
|
105
105
|
init made. From a second terminal:
|
|
106
106
|
|
|
107
107
|
```bash
|
|
108
|
-
npx
|
|
109
|
-
npx
|
|
108
|
+
npx nervur invite --dir ~/.nervur '{"being":"razvan","id":"phone"}'
|
|
109
|
+
npx nervur census --dir ~/.nervur
|
|
110
110
|
```
|
|
111
111
|
|
|
112
112
|
The invite's answer is the invitation, `ward`, `heir` and `secret`, and
|
|
@@ -120,9 +120,9 @@ her `asks`, the seven of the owner, `boot`, `public`, `invite`, `knock`,
|
|
|
120
120
|
same daemon; `--ward` names it on any command, and naming none means the
|
|
121
121
|
default.
|
|
122
122
|
|
|
123
|
-
The root reaches into a being of her own ward with `
|
|
123
|
+
The root reaches into a being of her own ward with `nervur ask <being>
|
|
124
124
|
[method] [json]`; with no method the answer is the being's describe. A
|
|
125
|
-
being is booted from the classes the box holds, `
|
|
125
|
+
being is booted from the classes the box holds, `nervur boot
|
|
126
126
|
'{"key":"clock","class":"Clock"}'`, and the classes are the dock's own,
|
|
127
127
|
`User`, `Desk`, `Clock`, `Courier`, `Avatar`, `Presence` and the
|
|
128
128
|
faculties, plus what `classes/index.ts` beside the wards exports by name,
|
|
@@ -130,14 +130,14 @@ empty as init leaves it: a class nobody holds answers `no such class, or
|
|
|
130
130
|
key taken`, as a key already booted does.
|
|
131
131
|
|
|
132
132
|
Everything the box does on its own is a row on a faculty of the dock ward,
|
|
133
|
-
placed by the root with `
|
|
133
|
+
placed by the root with `nervur ask --ward dock`, kept in her cells and back
|
|
134
134
|
at every boot; the daemon reads no recipe. Two rows every estate meets:
|
|
135
135
|
|
|
136
136
|
```bash
|
|
137
|
-
npx
|
|
138
|
-
npx
|
|
139
|
-
npx
|
|
140
|
-
npx
|
|
137
|
+
npx nervur ask --dir ~/.nervur --ward dock dialers keep '{"url":"http://127.0.0.1:8788/quo"}'
|
|
138
|
+
npx nervur ask --dir ~/.nervur --ward dock agents keep '{"id":"bot","ward":"acme","url":"http://127.0.0.1:1234/v1","model":"qwen"}'
|
|
139
|
+
npx nervur ask --dir ~/.nervur --ward dock agents list
|
|
140
|
+
npx nervur ask --dir ~/.nervur --ward dock agents drop '{"id":"bot"}'
|
|
141
141
|
```
|
|
142
142
|
|
|
143
143
|
A dialer row is a socket this box holds to that quo route from now and
|
|
@@ -156,10 +156,10 @@ B knocks for B's user being with the invitation A answered, the three
|
|
|
156
156
|
fields without the `link`:
|
|
157
157
|
|
|
158
158
|
```bash
|
|
159
|
-
npx
|
|
160
|
-
npx
|
|
161
|
-
npx
|
|
162
|
-
npx
|
|
159
|
+
npx nervur reach --dir B <pk of A> http://127.0.0.1:8787/quo
|
|
160
|
+
npx nervur invite --dir A '{"being":"<pk of A>","id":"b"}'
|
|
161
|
+
npx nervur knock --dir B '{"being":"razvan","id":"a","invitation":{"ward":"…","heir":"…","secret":"…"}}'
|
|
162
|
+
npx nervur census --dir B --via a
|
|
163
163
|
```
|
|
164
164
|
|
|
165
165
|
The knock answers `taken`, the standing's name, and A's describe for an
|
|
@@ -174,10 +174,10 @@ script, `stand.ts`, under "What a device stands up".
|
|
|
174
174
|
**On the edge** the harbor is one Durable Object and the worker is the
|
|
175
175
|
dock's, reached by name from a two-line `worker.ts`; there is no process
|
|
176
176
|
of your own and no socket, so the root is whoever holds the platform
|
|
177
|
-
secret `
|
|
178
|
-
other secret, `
|
|
179
|
-
the object's storage. `wrangler dev --var
|
|
180
|
-
|
|
177
|
+
secret `NERVUR_ROOT`, and the root's asks arrive as one POST under it. The
|
|
178
|
+
other secret, `NERVUR_SEED_KEY`, thirty-two bytes as hex, seals the seeds in
|
|
179
|
+
the object's storage. `wrangler dev --var NERVUR_SEED_KEY:… --var
|
|
180
|
+
NERVUR_ROOT:…` runs the same worker on a Mac's loopback.
|
|
181
181
|
|
|
182
182
|
```ts
|
|
183
183
|
export { Quo } from '@nervur-org/dock/harbor/edge/worker';
|
|
@@ -200,8 +200,8 @@ new_sqlite_classes = ["Quo"]
|
|
|
200
200
|
```
|
|
201
201
|
|
|
202
202
|
```bash
|
|
203
|
-
npx wrangler secret put
|
|
204
|
-
npx wrangler secret put
|
|
203
|
+
npx wrangler secret put NERVUR_SEED_KEY
|
|
204
|
+
npx wrangler secret put NERVUR_ROOT
|
|
205
205
|
npx wrangler deploy
|
|
206
206
|
```
|
|
207
207
|
|
|
@@ -223,7 +223,7 @@ curl -s -X POST $R -H "$H" -H 'content-type: application/json' -d '{"method":"in
|
|
|
223
223
|
|
|
224
224
|
The invite answers the three fields and no link, since the edge composes
|
|
225
225
|
none. The first thing a root on the edge does is that invite on the
|
|
226
|
-
ward's own pk: a box reaches the edge with `
|
|
226
|
+
ward's own pk: a box reaches the edge with `nervur reach <pk>
|
|
227
227
|
<origin>/h/main/quo`, knocks with the three fields, and from then on
|
|
228
228
|
pilots it with `--via`, as any ward, and the secret is not used again.
|
|
229
229
|
|
|
@@ -296,7 +296,7 @@ that every arrival is named and judged.
|
|
|
296
296
|
are two sides of one avatar class.
|
|
297
297
|
- **Front desk.** A being strangers and fresh clients meet first. It holds
|
|
298
298
|
a standing to the ward's own being and to every being it made, and can
|
|
299
|
-
ask one for a device invitation. It is the being `
|
|
299
|
+
ask one for a device invitation. It is the being `nervur init` marks public
|
|
300
300
|
in a fresh ward, and nothing more: a ward has one public being of any
|
|
301
301
|
class, an estate's front in place of the desk, a board or a corpus in a
|
|
302
302
|
ward of its own, and the mark is the owner's to move. Public is not a
|
|
@@ -435,7 +435,7 @@ acme.com, or a family's domain: the dialable part of an estate
|
|
|
435
435
|
quo. the harbor's socket door: the rendezvous for every dialer
|
|
436
436
|
mcp. the model side over HTTP, a credential exchange in front
|
|
437
437
|
api. a describe as plain JSON: the public being for a stranger, the avatar under a bearer
|
|
438
|
-
|
|
438
|
+
nervur serve: one process, one harbor, the ask pointer
|
|
439
439
|
unix socket owner asks, local only, never behind the proxy
|
|
440
440
|
localhost ports the routes above
|
|
441
441
|
ward main the estate's home: its org being, the desk, the bell, its envoys, its members, its avatars
|
|
@@ -443,13 +443,13 @@ acme.com, or a family's domain: the dialable part of an estate
|
|
|
443
443
|
ward <world> any other world the estate runs: a corpus, a board, with a public being of its own
|
|
444
444
|
|
|
445
445
|
mac
|
|
446
|
-
|
|
446
|
+
nervur serve (laptop, dialer, holds a socket to quo.)
|
|
447
447
|
unix socket owner asks, local only
|
|
448
448
|
ward main the device's own: the human's local beings and the avatars of local sides
|
|
449
449
|
a local agent
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
450
|
+
nervur side -> an avatar over stdio occupant
|
|
451
|
+
nervur pilot -> the ask pointer over the sock owner, here
|
|
452
|
+
nervur pilot --via droplet -> a standing at the droplet's ward, sealed owner, there
|
|
453
453
|
the editor -> being classes on disk developer
|
|
454
454
|
|
|
455
455
|
iphone, or a tab
|
|
@@ -599,7 +599,7 @@ other ward on the box comes to hold a standing at one through `lend`, the
|
|
|
599
599
|
seventh member of the ground. The faculties below are the ones the dock
|
|
600
600
|
ships, and they are examples of the shape and not a list: `lend` reaches
|
|
601
601
|
any being of the dock ward by her key, so an estate boots a faculty of its
|
|
602
|
-
own there, `
|
|
602
|
+
own there, `nervur boot --ward dock`, of a class in its own `classes/` that
|
|
603
603
|
extends `Faculty`, holding whatever its terrain allows, and lends it the
|
|
604
604
|
same way.
|
|
605
605
|
|
|
@@ -817,7 +817,7 @@ Three things that shape are: a token names its bell, the address of the
|
|
|
817
817
|
service that holds the keys of the app that minted it, set by that app's
|
|
818
818
|
shell from its build the way `sandbox` is, so a box rings the service the
|
|
819
819
|
token names and rings a phone running an app it never shipped, while the
|
|
820
|
-
service the root kept on the push faculty, `
|
|
820
|
+
service the root kept on the push faculty, `nervur ask --ward dock push keep
|
|
821
821
|
'{"service":"https://bell.example"}'`, is a world's default for a token
|
|
822
822
|
that names none and never an address in this package, since whose service it is
|
|
823
823
|
belongs to an estate; who may ring it is the token itself, because a device
|
|
@@ -829,7 +829,7 @@ while Node's fetch is undici, which speaks none, so a box whose fetch
|
|
|
829
829
|
speaks it rings Apple with `dock/apns.ts` and a Node box rings the same
|
|
830
830
|
thing with `dock/http2.ts`, which is that ring over `node:http2` and is
|
|
831
831
|
named by the Node terrain alone. A Node box is a bell when it is handed
|
|
832
|
-
Apple's key, `
|
|
832
|
+
Apple's key, `NERVUR_APNS_KEY` and the three beside it, and every box handed
|
|
833
833
|
none routes to the service instead. Web Push is the world's own key and
|
|
834
834
|
names no service.
|
|
835
835
|
|
|
@@ -1111,7 +1111,7 @@ because nothing runs in a hand at night and a faculty that promised a wake
|
|
|
1111
1111
|
nothing would fire is worse than a name the box does not hold.
|
|
1112
1112
|
|
|
1113
1113
|
The root places what the device always does from a shell, once,
|
|
1114
|
-
`
|
|
1114
|
+
`nervur ask clock keep '{"id":"sweep","ask":"corpus.sweep","cron":"0 3 * * *"}'`,
|
|
1115
1115
|
one line per schedule, and the estate's paper holds those lines, so the
|
|
1116
1116
|
paper still describes the whole device. A schedule that will not read is
|
|
1117
1117
|
refused in the answer to that line, where it was written, and is never kept
|
|
@@ -1233,7 +1233,7 @@ a gate that reads notes is fed without a line of code.
|
|
|
1233
1233
|
a kind of ward: its agents boot there, its door answers for it when a
|
|
1234
1234
|
caller names no ward, and a command with no `--ward` is on it, and that is
|
|
1235
1235
|
all. A harbor hosting one ward has it as the default with nothing said; a
|
|
1236
|
-
harbor hosting several marks one, `
|
|
1236
|
+
harbor hosting several marks one, `nervur init --default` or `nervur default
|
|
1237
1237
|
<ward>`, a mark kept in that ward's own folder so it moves with the ward,
|
|
1238
1238
|
and with none marked is refused at boot, by the names it hosts, rather
|
|
1239
1239
|
than coming up on a guess. No name is a default, and the dock ward, which
|
|
@@ -1377,7 +1377,7 @@ is no password anywhere in the dock, because login is a knock. Every way in
|
|
|
1377
1377
|
ends the same way:
|
|
1378
1378
|
|
|
1379
1379
|
1. Somebody who may invite mints an invitation for the client identity.
|
|
1380
|
-
The root does, on the box, with `
|
|
1380
|
+
The root does, on the box, with `nervur invite` on the user being, and
|
|
1381
1381
|
sends it as a link or a line; a device of hers that may mint does it
|
|
1382
1382
|
from where it stands, on her `device` ask, so only a human's first
|
|
1383
1383
|
device ever has to come from the box. On the device, a side that reached the
|
|
@@ -1422,7 +1422,7 @@ asks for the words it wants, and she writes only those it holds itself, so
|
|
|
1422
1422
|
a chain of devices never gains a power along the way. The
|
|
1423
1423
|
notes are written when the occupant is minted; to change one, remove the
|
|
1424
1424
|
occupant and mint again, because reconnect mints nothing. A device the
|
|
1425
|
-
root mints on her directly, with `
|
|
1425
|
+
root mints on her directly, with `nervur invite`, carries no note: the id the
|
|
1426
1426
|
root chose is its client identity, and it reaches and may wake, since the
|
|
1427
1427
|
root owns everything she holds and chose to mint it. `mint` is never
|
|
1428
1428
|
implied, not even there, because it admits somebody else rather than
|
|
@@ -1453,7 +1453,7 @@ answers 401 at the next session and forgets the grant.
|
|
|
1453
1453
|
|
|
1454
1454
|
## The daemon and the CLI
|
|
1455
1455
|
|
|
1456
|
-
One command, `
|
|
1456
|
+
One command, `nervur`, under `packages/dock/cli/`. It imports the four library exports
|
|
1457
1457
|
and nothing else, holds no class body, and never speaks to a ward except
|
|
1458
1458
|
through the ask pointer or an avatar, the two doors everyone has. The
|
|
1459
1459
|
daemon's folder holds the process and its two sockets, and nothing under
|
|
@@ -1470,19 +1470,19 @@ rule: what it is made of is the daemon's socket, so it stands in `cli/`, and
|
|
|
1470
1470
|
`mcp/` holds the model side it is handed to.
|
|
1471
1471
|
|
|
1472
1472
|
```
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1473
|
+
nervur init [--dir D] [--ward W] [--user U] [--class C] [--default] [--show] [--domain DOM] mint a seed, boot a ward over a disk store, write both; C is the class of its home being, User unless said, an org's for an org's ward; --default marks it the default ward; --show shows it at the web route; --domain writes the four routes under DOM
|
|
1474
|
+
nervur default <ward> mark one ward the default, the one a caller means when naming none; a harbor with one ward needs no mark
|
|
1475
|
+
nervur show|hide <ward> show a ward at the web route, listed at its root and its public being's page painted for a stranger; hidden at init
|
|
1476
|
+
nervur domain <domain> write routes.json by the convention, mcp., web., quo. and api. under the domain, over https
|
|
1477
|
+
nervur serve [--dir D] the daemon: harbor from disk, the unix socket, the routes' listeners, the agents, a socket held to every route the dialers faculty keeps
|
|
1478
|
+
nervur pilot [--dir D] [--via S] the owner pilot over stdio: the ward's describe as tools; as the root, or via a standing at another ward
|
|
1479
|
+
nervur side [--dir D] --as NAME an avatar over stdio for a local client; NAME is the client identity
|
|
1480
|
+
nervur run [--dir D] --as NAME --url URL --model NAME a human at a terminal talking to a model through an avatar; a line in, the final text out
|
|
1481
|
+
nervur census [--dir D] print the census once and exit
|
|
1482
|
+
nervur boot|public|invite|knock|remove|unboot six of the seven owner asks from a shell, for scripts and for agents under cron; --via S sends them to another ward
|
|
1483
|
+
nervur ask <being> [method] [json] the seventh: the root reaching into a being of its own ward, as the device
|
|
1484
|
+
nervur reach <pk> <url> a hint for the harbor's directory: that world's ward lives at that quo. route
|
|
1485
|
+
nervur estate <dir> --domain D an estate folder of the shape every estate has: a droplet's harbor directory, its unit and Caddyfile, a Mac's launchd agent and dial list, a package on this dock
|
|
1486
1486
|
```
|
|
1487
1487
|
|
|
1488
1488
|
**The owner does two things, and the ward says both.** Six of the seven make
|
|
@@ -1498,7 +1498,7 @@ an ask only the daemon's own code could reach, which is an ask nobody can
|
|
|
1498
1498
|
make.
|
|
1499
1499
|
|
|
1500
1500
|
It is the ward's ask and not the socket's, so nothing on this dock holds a
|
|
1501
|
-
being's answer and judges it again. `
|
|
1501
|
+
being's answer and judges it again. `nervur ask` and the socket's `being` line
|
|
1502
1502
|
forward it; the api route asks it with no being named for a stranger,
|
|
1503
1503
|
which is the public being asked as nobody; and a being of the tab's own
|
|
1504
1504
|
ward is a subject over it, since the tab holds that ward's pointer and is
|
|
@@ -1506,7 +1506,7 @@ its root. Each of those
|
|
|
1506
1506
|
was once a hand-written door with an asker of its own making, an allowance
|
|
1507
1507
|
copied from the spec and a save written after it, and there is one now.
|
|
1508
1508
|
|
|
1509
|
-
**One process owns the harbor.** `
|
|
1509
|
+
**One process owns the harbor.** `nervur serve` is the only process that ever
|
|
1510
1510
|
holds the seed, the partition and the ask pointer, on every device, the Mac
|
|
1511
1511
|
included. Two processes over one partition are two wards with one pk, and
|
|
1512
1512
|
they diverge silently. `init` is the one exception: it creates with no
|
|
@@ -1541,7 +1541,7 @@ routes. The socket is the root. Owning a droplet from elsewhere is a
|
|
|
1541
1541
|
standing: the root there invites an owner on the ward's own pk, the root
|
|
1542
1542
|
here knocks for the user being with it, and she takes the droplet's ward
|
|
1543
1543
|
under a name, `droplet`. Owning is one of the human's standings, so she
|
|
1544
|
-
holds it as she holds acme. From then on `
|
|
1544
|
+
holds it as she holds acme. From then on `nervur pilot --via droplet`, and the
|
|
1545
1545
|
bare owner asks with `--via droplet`, are sealed asks at the droplet's door,
|
|
1546
1546
|
counted, rotated, removable: the daemon here asks on her standing
|
|
1547
1547
|
in-process, as it drives an avatar for a side, and saves. The answers are
|
|
@@ -1681,7 +1681,7 @@ class on it is written from this block and nothing else:
|
|
|
1681
1681
|
|
|
1682
1682
|
```ts
|
|
1683
1683
|
import { Envoy, owner, occupant, type Delivery, type Wake } from '@nervur-org/dock';
|
|
1684
|
-
import type { Asker, JsonObject } from '
|
|
1684
|
+
import type { Asker, JsonObject } from 'nervur';
|
|
1685
1685
|
|
|
1686
1686
|
export class Booking extends Envoy {
|
|
1687
1687
|
// cells and asks are statics, as on every being. Spread the base's asks,
|
|
@@ -1857,10 +1857,13 @@ Two rules keep them general:
|
|
|
1857
1857
|
2. Every interface has one suite, run against every implementation. A new
|
|
1858
1858
|
implementation is accepted when the shared suite passes untouched.
|
|
1859
1859
|
|
|
1860
|
-
Harbor core, reach and store are the library's
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1860
|
+
Harbor core, reach and store are the library's and are written under
|
|
1861
|
+
`packages/nervur/src`, because a harbor is a word of the protocol and not a
|
|
1862
|
+
convention of ours. Only one of the three is the protocol's own: the reach,
|
|
1863
|
+
whose two kinds and whose frames `quo/SPEC.md` pins, because two harbors meet
|
|
1864
|
+
on them. A core and a store are this kit's way of paying what the spec asks a
|
|
1865
|
+
harbor for, and `papers/quo-harbor.md` decides them. What is the dock's of the
|
|
1866
|
+
three is each terrain's store, loader, lease and listener, which is a device's
|
|
1864
1867
|
business and no ward's. The other six pieces are dock conventions and are
|
|
1865
1868
|
decided here.
|
|
1866
1869
|
|
|
@@ -1893,7 +1896,7 @@ never against a reader we imagine.
|
|
|
1893
1896
|
ward, which never moves. Nothing that migrates carries a credential.
|
|
1894
1897
|
10. Nothing outside a package reaches inside it. `packages/dock/` imports
|
|
1895
1898
|
the library by its four exports and never a path under
|
|
1896
|
-
`packages/
|
|
1899
|
+
`packages/nervur/src`; an estate and an app import the two packages by
|
|
1897
1900
|
their exported names, the root and the subpaths the export map offers,
|
|
1898
1901
|
and never a file that is not one. A folder of a package reaches its
|
|
1899
1902
|
sibling folders by relative path, which is inside and not a breach.
|
|
@@ -1933,7 +1936,7 @@ Two rules hold:
|
|
|
1933
1936
|
The second is how a harbor on any terrain is accepted, untouched, and not
|
|
1934
1937
|
before. Neither binds an adopter; they bind this bench.
|
|
1935
1938
|
- **One language, TypeScript, until 1.0.0.** A second kit is a second thing to
|
|
1936
|
-
keep in step with every change, and the shelf under `packages/
|
|
1939
|
+
keep in step with every change, and the shelf under `packages/nervur/protocol/`
|
|
1937
1940
|
are the hand that will be extended when the time comes.
|
|
1938
1941
|
|
|
1939
1942
|
## Glossary
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
# Transports
|
|
2
2
|
|
|
3
3
|
This is how a harbor lives on a real device and how two of them meet over a real
|
|
4
|
-
network. It implements the harbor of `quo/SPEC.md` on every terrain and
|
|
5
|
-
|
|
4
|
+
network. It implements the harbor of `quo/SPEC.md` on every terrain and adds
|
|
5
|
+
nothing a ward or a far harbor can observe: what is written here that the
|
|
6
|
+
protocol does not say is a device's own half, a store, a lease, a loader, a
|
|
7
|
+
core and a dialer's patience, and a second kit that answers the same bytes owes
|
|
8
|
+
none of it. A harbor boots wards, keeps what they are made of, carries
|
|
6
9
|
bytes to one pk, returns what came back or nothing, never reads them, and
|
|
7
10
|
answers nothing only where it knows nothing was sent. This document names no
|
|
8
11
|
being and no side; it knows seeds, partitions, code, sockets and disks.
|
|
@@ -109,7 +112,7 @@ apps share that is the argument for the secret store.
|
|
|
109
112
|
Wrapped is what is built, and it is one piece, `seal.ts`: AES-GCM under a
|
|
110
113
|
32-byte key, a fresh nonce each time, nonce and ciphertext together as hex,
|
|
111
114
|
on WebCrypto so it runs wherever a store does. The key is the one secret a
|
|
112
|
-
harbor reads from its terrain's secret store, named `
|
|
115
|
+
harbor reads from its terrain's secret store, named `NERVUR_SEED_KEY` on every
|
|
113
116
|
terrain: a platform secret on the edge, the environment of a daemon on a
|
|
114
117
|
device, handed to it from the Keychain by the app that spawned it. A
|
|
115
118
|
droplet gives no key and its folder stays plain under its file modes. A
|
|
@@ -253,7 +256,7 @@ with the owner's word for a world's.
|
|
|
253
256
|
|
|
254
257
|
There are two harbor cores, and every device runs one of them:
|
|
255
258
|
|
|
256
|
-
- **The node daemon**, `
|
|
259
|
+
- **The node daemon**, `nervur serve`. A disk or keychain store, a unix socket
|
|
257
260
|
for the owner, listeners on localhost for the routes. Droplet, Mac, Linux
|
|
258
261
|
box: wherever a home runs.
|
|
259
262
|
- **The browser harbor.** A dialer inside a webview or a tab, an IndexedDB
|
|
@@ -297,10 +300,26 @@ Two kinds of harbor exist in the world, and every pair reduces to them:
|
|
|
297
300
|
| browser tab | no | yes | while open | itself |
|
|
298
301
|
|
|
299
302
|
A ward on a dialer is reached only if its harbor dialed first and something
|
|
300
|
-
holds that line open. A
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
303
|
+
holds that line open. A dialer holds one socket to a URL, announces the pks
|
|
304
|
+
this harbor holds when the line opens and again whenever they change, and
|
|
305
|
+
dials again with a wait that backs off to a ceiling when the line drops; how
|
|
306
|
+
far it backs off is this harbor's, and the wait goes back to the shortest one
|
|
307
|
+
where the far side announced and was taken, not where the line merely opened,
|
|
308
|
+
or a listener that opens and then refuses is dialed at one short wait for
|
|
309
|
+
good. A harbor may dial several listeners, and a pk nobody here knows is
|
|
310
|
+
tried down that list in order.
|
|
311
|
+
|
|
312
|
+
A device that comes back from sleep tells its dialer so, `wake`: whatever
|
|
313
|
+
line it holds, open or still opening, is put down and a new one is dialed
|
|
314
|
+
now, the frozen wait called off. Nothing can tell a line the system closed
|
|
315
|
+
under a sleeping device from a live one, and asking would cost a round trip
|
|
316
|
+
the four words do not have; an announce written into a dead line sits in the
|
|
317
|
+
send buffer and errors only when TCP gives up, minutes later, and for all of
|
|
318
|
+
it every ask to a pk bound behind that line hears `late`. Dialing costs one
|
|
319
|
+
handshake when the line was fine, and an ask made meanwhile waits on the new
|
|
320
|
+
socket. A line put down this way closes when the system gets round to it and
|
|
321
|
+
dials nothing: only the line the dialer still holds dials again. A phone's
|
|
322
|
+
ask must survive a push wake-up, and a tab is a
|
|
304
323
|
device, and one seed never lives in two tabs.
|
|
305
324
|
|
|
306
325
|
## Transport by necessity
|
|
@@ -333,7 +352,7 @@ rotation, and nothing else.
|
|
|
333
352
|
## Reach, directory, rendezvous
|
|
334
353
|
|
|
335
354
|
A harbor needs two reach kinds and nothing more, which is what
|
|
336
|
-
`quo/SPEC.md` says and what `packages/
|
|
355
|
+
`quo/SPEC.md` says and what `packages/nervur/src/harbor/reach.ts` is:
|
|
337
356
|
|
|
338
357
|
- **request**: a URL. Send bytes, get bytes. Listener to listener.
|
|
339
358
|
- **socket**: a held connection, opened by whichever side can dial, used in
|
|
@@ -386,8 +405,10 @@ negotiated: in the text frame a socket announces itself with, and as the
|
|
|
386
405
|
header `quo-suite` on a request. It is never on an ask, so an ask is bytes
|
|
387
406
|
with nothing in front of them, and a harbor still knows before it carries
|
|
388
407
|
anything whether the far side can open what it would send. A side meeting a
|
|
389
|
-
suite it does not know closes the line; a request door answers
|
|
390
|
-
delivered.
|
|
408
|
+
suite it does not know closes the line with code 4001; a request door answers
|
|
409
|
+
nothing delivered. A dialer refused that way waits out its ceiling before
|
|
410
|
+
asking again, because a suite does not become speakable by asking sooner.
|
|
411
|
+
`quo/SPEC.md` owns the number and says why it exists.
|
|
391
412
|
|
|
392
413
|
The **directory** is the map from pk to reach. The memory harbor stubs it with
|
|
393
414
|
linked peers. A real one is a table the harbor fills however it likes, and the
|
|
@@ -400,7 +421,7 @@ rebinds it.
|
|
|
400
421
|
## The quo. route, as built
|
|
401
422
|
|
|
402
423
|
The reach interface and its two implementations are the library's,
|
|
403
|
-
`packages/
|
|
424
|
+
`packages/nervur/src/harbor/reach.ts`, and pass its reach suite here: the request
|
|
404
425
|
and a socket to a daemon in `packages/dock/test/wire.test.ts`, the request
|
|
405
426
|
through the worker inside the edge. The route is one file on every terrain,
|
|
406
427
|
`packages/dock/harbor/quo.ts`, `Request` in and `Response` out, mounted by
|
|
@@ -425,7 +446,7 @@ socket a WebSocket at <url>, held by the dialer, used both ways
|
|
|
425
446
|
reply frame [1][id 4][bytes]
|
|
426
447
|
none frame [2][id 4] nothing was delivered
|
|
427
448
|
directory pk -> reach, filled three ways: a socket a dialer holds, bound once proven
|
|
428
|
-
and unbound at close; a hint from a link, `
|
|
449
|
+
and unbound at close; a hint from a link, `nervur reach <pk> <url>`, kept in
|
|
429
450
|
<dir>/reach.json; and the harbor's own doors, always first
|
|
430
451
|
```
|
|
431
452
|
|
|
@@ -434,7 +455,7 @@ door or to a socket this harbor holds for that pk, and never onward by
|
|
|
434
455
|
request. So a third harbor with a hint that a phone's pk is at acme's
|
|
435
456
|
`quo.` sends there, and acme forwards down the socket the phone holds.
|
|
436
457
|
A row on the dock ward's `dialers` faculty makes a daemon a dialer, placed
|
|
437
|
-
once by the root, `
|
|
458
|
+
once by the root, `nervur ask --ward dock dialers keep '{"url":"https://quo.acme.com"}'`,
|
|
438
459
|
kept in her cells and dialed again at every boot: it holds one socket per
|
|
439
460
|
URL, announces its wards on open, binds the listener's pks, and reconnects
|
|
440
461
|
with backoff from a second to thirty when the line drops. `drop` closes
|
|
@@ -454,11 +475,13 @@ root as `/quo/`, with the trailing slash, which the door takes.
|
|
|
454
475
|
|
|
455
476
|
## The two cores, as built
|
|
456
477
|
|
|
457
|
-
The harbor core is the library's, `packages/
|
|
458
|
-
the dialer, `packages/
|
|
459
|
-
|
|
478
|
+
The harbor core is the library's, `packages/nervur/src/harbor/core.ts`, and so is
|
|
479
|
+
the dialer, `packages/nervur/src/harbor/dial.ts`. Neither is a word of the
|
|
480
|
+
protocol: `quo/SPEC.md` says what a harbor owes a ward and what a reach owes
|
|
481
|
+
a far harbor, and a core and a dialer are how this kit pays both on every
|
|
482
|
+
terrain. Every harbor here extends the core and hands it three things: a
|
|
460
483
|
**store**, the library's interface, with `files.ts` on a disk, plain as three
|
|
461
|
-
files per ward or sealed as one blob when the daemon holds `
|
|
484
|
+
files per ward or sealed as one blob when the daemon holds `NERVUR_SEED_KEY`,
|
|
462
485
|
and `idb.ts` in a tab, each passing the library's store suite, the files
|
|
463
486
|
store in both forms; a **loader**, the code half, a
|
|
464
487
|
module from a folder on a daemon and the bundle in a tab; and a **lease**, a pid
|
|
@@ -523,7 +546,7 @@ is the harbor. The platform runs one instance of it at a time, which is
|
|
|
523
546
|
the lease and the single writer every ward needs. Its storage is the
|
|
524
547
|
store, `storage.ts`: one row per ward, seed, partition and record, with the
|
|
525
548
|
seed sealed by `seal.ts` under a key from the platform's secrets,
|
|
526
|
-
`
|
|
549
|
+
`NERVUR_SEED_KEY`, so the storage holds ciphertext and the secret store holds
|
|
527
550
|
the one key, as the table above says. The deployed worker is the code, the
|
|
528
551
|
built-in beings and whatever it hands in. It is a listener and never a
|
|
529
552
|
dialer: reached by request at `<origin>/h/<name>/quo`, holding the sockets
|
|
@@ -531,7 +554,7 @@ dialers open to it on the platform's own socket pair, the rendezvous for
|
|
|
531
554
|
them, awake per request and kept awake by a held socket.
|
|
532
555
|
|
|
533
556
|
Its owner door is a route, not a socket, because the platform has no local
|
|
534
|
-
process: the root is whoever holds `
|
|
557
|
+
process: the root is whoever holds `NERVUR_ROOT`, a platform secret, and the
|
|
535
558
|
root's asks arrive as one POST at `<origin>/h/<name>/root` under it, the
|
|
536
559
|
first of them `{ init: { ward, user } }`, the root's setup. That is the
|
|
537
560
|
device's own rule on this terrain, as file permissions are on a disk. The
|
|
@@ -626,8 +649,9 @@ this harbor, the dock's shell over it, and the link the platform hands the
|
|
|
626
649
|
app, as the launch URL and then on every link opened while it runs.
|
|
627
650
|
|
|
628
651
|
The harbor on a phone is the browser harbor, `browser.ts`, over that
|
|
629
|
-
store: the browser harbor takes a name,
|
|
630
|
-
under
|
|
652
|
+
store: the browser harbor takes a name, `nervur` unless one is given, which
|
|
653
|
+
is an IndexedDB database under the web lock `nervur:<name>`, or a store
|
|
654
|
+
handed in, whose lease is the process that
|
|
631
655
|
holds it, since an app has one harbor and nothing else can open its
|
|
632
656
|
files. `nativeHarbor` in `capacitor.ts` is that harbor booted and armed:
|
|
633
657
|
the App plugin's foreground event tells it `wake`, which tells every
|
|
@@ -735,7 +759,7 @@ desk, so a desk is reached while the app is open and drains what it
|
|
|
735
759
|
missed when it opens. The one
|
|
736
760
|
window the desk app has is a surface over the DOM like the tab's, and the
|
|
737
761
|
screen runs in it: nothing of the desk app is a daemon, spawns one or
|
|
738
|
-
attaches to one. A person who wants a home on a Mac runs `
|
|
762
|
+
attaches to one. A person who wants a home on a Mac runs `nervur serve` on it
|
|
739
763
|
as an operator, and that is a home like any other and no concern of the
|
|
740
764
|
app's.
|
|
741
765
|
|
|
@@ -760,8 +784,8 @@ heir dies at the first knock, and whoever opens it first is bound.
|
|
|
760
784
|
|
|
761
785
|
```
|
|
762
786
|
device
|
|
763
|
-
|
|
764
|
-
|
|
787
|
+
nervur serve one process, one harbor, the ask pointer
|
|
788
|
+
nervur.sock owner asks; local only; never behind a proxy
|
|
765
789
|
side.sock local sides; local only; never behind a proxy
|
|
766
790
|
127.0.0.1:8787 the HTTP door, loopback only; routes mount by path
|
|
767
791
|
/health the wards it hosts, by name and pk, and the saves refused; harbor/http.ts
|
|
@@ -786,8 +810,8 @@ the edge, in a browser's own service worker, on Deno and on Bun, and the
|
|
|
786
810
|
terrain is the door and never the side.
|
|
787
811
|
|
|
788
812
|
The daemon listens on loopback only, and only when asked, with `--http PORT`
|
|
789
|
-
or `
|
|
790
|
-
does. `
|
|
813
|
+
or `NERVUR_HTTP`. The proxy faces the world and terminates TLS; the daemon never
|
|
814
|
+
does. `nervur estate` writes a systemd unit that runs the daemon as one user
|
|
791
815
|
forever, a launchd agent that does the same on a Mac, and a Caddyfile that
|
|
792
816
|
maps the hostnames onto the one port by path, from the templates in
|
|
793
817
|
`packages/dock/cli/estate/`.
|
|
@@ -804,7 +828,7 @@ There is no `cli.` route.
|
|
|
804
828
|
**Where the addresses come from, per terrain.** One convention holds
|
|
805
829
|
everywhere: the four routes are `mcp.`, `web.`, `quo.` and `api.` under one
|
|
806
830
|
domain, over https, and nobody types a hostname four times. On a droplet
|
|
807
|
-
the domain is said once, `
|
|
831
|
+
the domain is said once, `nervur init --domain acme.com` or `nervur domain
|
|
808
832
|
acme.com`, and `<dir>/routes.json` is written by the convention; an estate
|
|
809
833
|
whose names break it edits that file, and it is the one file that stands
|
|
810
834
|
beside the wards by right, since a ward knows its pk and never its
|
|
@@ -824,10 +848,10 @@ A harbor here is accepted when it passes the library's conformance suite
|
|
|
824
848
|
untouched, and by nothing else. Three do: the disk harbor over the wire
|
|
825
849
|
under both reaches, the browser harbor through a daemon, and the edge harbor
|
|
826
850
|
inside the platform's runtime. Every store passes the library's store suite,
|
|
827
|
-
`packages/
|
|
851
|
+
`packages/nervur/src/conformance/store.ts`: files in
|
|
828
852
|
`packages/dock/test/store.test.ts`, IndexedDB and the edge's storage inside
|
|
829
853
|
their terrains behind `deep:dock`. Every reach passes the library's reach
|
|
830
|
-
suite, `packages/
|
|
854
|
+
suite, `packages/nervur/src/conformance/reach.ts`. The store, the reach and the
|
|
831
855
|
core are the library's, and every harbor here is one of them over its own
|
|
832
856
|
terrain.
|
|
833
857
|
|
|
@@ -131,7 +131,7 @@ running there, from her cells, and painted by the same painter.
|
|
|
131
131
|
on every device and no class carries a layout. A kind an estate wants and
|
|
132
132
|
the grammar lacks is asked for here, and never written around.
|
|
133
133
|
- **The painter emits the kit and nothing else.** Every node paints as a
|
|
134
|
-
piece of `papers/
|
|
134
|
+
piece of `papers/nervur-ui.md`'s catalogue, a `stack` as `.nv-stack`, a
|
|
135
135
|
`list` as `.nv-list` of `.nv-item`, a `person` as `.nv-person` with an
|
|
136
136
|
`.nv-avatar`, a title as `.nv-t-title`, a form as the kit's fieldset and
|
|
137
137
|
fields and one `.nv-button`, an answer as `.nv-answer` with the word it
|
|
@@ -326,7 +326,7 @@ Read with the trunk's "Carrying" and "The look", which this applies.
|
|
|
326
326
|
- **Worlds have addresses, and so do the beings one holds.** `web./<ward>`
|
|
327
327
|
is that world's page, `web./` lists the worlds shown, and a hostname per
|
|
328
328
|
world is one proxy line, the estate's choice. Shown is the ward's own
|
|
329
|
-
mark, `
|
|
329
|
+
mark, `nervur show` and `nervur hide`, hidden at `init`: a hidden ward is not
|
|
330
330
|
listed and a stranger at its page meets the plain door, while a link
|
|
331
331
|
still knocks with its invitation and the desk still answers a proof, so
|
|
332
332
|
an estate shows its face and leaves every home hidden. `quo.` stays one per harbor,
|
|
@@ -339,24 +339,24 @@ Read with the trunk's "Carrying" and "The look", which this applies.
|
|
|
339
339
|
device paints as nothing, since an address adds no right. Every section
|
|
340
340
|
on the world's page says where its own page is.
|
|
341
341
|
- **A link is the page with the invitation in the fragment**, under the one
|
|
342
|
-
reserved key `
|
|
343
|
-
`ward` alone: `web.acme.com/shop#
|
|
342
|
+
reserved key `nervur`, the invitation compact as `ward.heir.secret` or
|
|
343
|
+
`ward` alone: `web.acme.com/shop#nervur=...`. The fragment never leaves the
|
|
344
344
|
browser, where a query string would reach the server, its logs and every
|
|
345
345
|
referer. The tab reads it, strips it from the address bar before anything
|
|
346
346
|
else runs, and joins. A page's own routing keeps the query, the path and
|
|
347
|
-
the rest of the fragment; only `
|
|
347
|
+
the rest of the fragment; only `nervur` is taken. `beings/link.ts`.
|
|
348
348
|
- **An answer that is an invitation paints as the link it is.** The only
|
|
349
349
|
thing to do with one is to open it, and a being does not know where her
|
|
350
350
|
page lives while the side does: the side builds the link on the world's
|
|
351
351
|
page address, which is why the grammar carries no URL and this is not a
|
|
352
352
|
node. It is how devices beget devices on a page: a human asks her user
|
|
353
353
|
being's `device` for the next one and gets back a link to send, the same
|
|
354
|
-
link `
|
|
354
|
+
link `nervur invite` prints on the box. A side with an `admit` shows a guest
|
|
355
355
|
the door instead, and that is the door alone.
|
|
356
356
|
- **An invitation is self-addressing.** It names its ward by pk, so the
|
|
357
357
|
path of the page it was opened on is a hint for humans and nothing more:
|
|
358
358
|
the tab joins in the local ward of the ward the invitation names, and
|
|
359
|
-
the address follows. `web./#
|
|
359
|
+
the address follows. `web./#nervur=...` is a complete way in for anyone
|
|
360
360
|
holding an invitation to any ward the harbor hosts, and every ward has a
|
|
361
361
|
page, whether or not anyone is at its door, so that a link into one has
|
|
362
362
|
somewhere to land; a ward with no public being says it admits by
|